Сводная таблица функций
??? #Верстальщику ChangeTable
функции возвращающие значение ячейки виртуальной памяти
имя функции краткое описание long Byte(long ea) возвращает содержимое ячейки виртуальной памяти, расположенной по адресу ea long Word(long ea) возвращает содержимое ячеек виртуальной памяти, расположенных по адресам ea и ea+1, располагая их в младшем и старшем байте машинного слова соответственно. long Dword(long ea) возвращает содержимое ячеек виртуальной памяти, расположенных по адресам ea, ea+1, ea+2 и ea+3, располагая их в младших и старших байтах младшего и старшего слова соответственно
функции модифицирующие значение ячейки виртуальной памяти
имя функции краткое описание void PatchByte(long ea,long value) записывает в ячейку виртуальной памяти, расположенную по адресу ea, значение value void PatchWord(long ea,long value) записывает в ячейки виртуальной памяти, расположенные по адресам ea и ea+1, младший и старший байт значения value соответственно void PatchDword(long ea,long value) записывает в ячейки виртуальной памяти, расположенные по адресам ea, ea+1, ea+2 и ea+3 младшие и старшие байты младшего и старшего слова соответственно
функции трассирующие адреса виртуальной памяти
имя функции краткое описание long NextAddr(long ea) возвращает следующий линейный адрес, если он существует, в противном случае - ошибку long PrevAddr(long ea) возвращает предыдущий линейный адрес, если он существует, в противном случае – ошибку
функции поиска
имя функции краткое описание long FindBinary(long ea,long flag,char str)
функции, манипулирующие с флагами
имя функции краткое описание long GetFlags (long ea) возращает значение флагов виртуальной памяти long SetFlags(long ea, long flags) задает новые значения флагов виртуальной памяти long Byte (long ea)
Функция возвращает значение байта виртуальной памяти, расположенного по
39
адресу
ea. Если указанный адрес не существует, функция возвращает 0хFF, сигнализируя об ошибке, такое же значение возвратится и в том случае если ячейка имеет не инициализированное значение.
Поэтому, до вызова функции Byte следует убедиться, что ячейка действительно существует и имеет определенное значение. Проверить это можно, проанализировав младший бит поля атрибутов, определенный в файле <
idc.idc> константой
FF_INV, - если он не равен нулю, то все о’кей: if (FF_INV & GetFlags(ea))) value=Byte(ea); else // ячейка не существует или имеет неиницилизированное значение
В файле <
idc.idc> определены два макроса
hasValue(F) и
isLoaded(ea), выполняющие такие проверки. Макрос hasValue(F) ожидает флаг виртуальной памяти, а isLoaded(ea)
линейный адрес ячейки, т.е.: if(hasValue(GetFlags(ea))) value=Byte(ea); else //ячейка не существует или имеет неиницилизированное значение if(isLoaded(ea)) value=Byte(ea); else //ячейка не существует или имеет неиницилизированное значение
Альтернативой функции Byte служит вызов GetFlags с последующей маскировкой старших 24-бит, содержащих поле атрибутов. Маской может служить определенная в файле <
idc.idc> константа
MS_VAL или непосредственное значение – 0xFF. Это может выглядеть так: value = (MS_VAL & GetFlags(ea)).
Для увеличения производительности скрипта можно использовать макрос
byteValue(F), определенный в файле
, передавая ему значение флагов, ранее полученное для выполнения проверки существования ячейки:”F=GetFlags(ea); if
(hasValue(F)) value=byteValue(F);” – это позволяет избавиться от вызова функции
Byte, экономя тем самым некоторое количество процессорного времени.
Замечание:
если читаемые ячейки заведомо существуют и гарантированно содержат
инициализированные значения, в дополнительных проверках никакой необходимости нет и
использование макроса byteValue будет ничуть не быстрее вызова функции Byte
Пример использования:
0:00010000 db 48h ; H
0:00010001 db 65h ; e
0:00010002 db 6Ch ; l
0:00010003 db 6Ch ; l
0:00010004 db 6Fh ; o
0:00010005 db 2Ch ; ,
0:00010006 db 20h ;
0:00010007 db 49h ; I
0:00010008 db 44h ; D
0:00010009 db 41h ; A
0:0001000A db 20h ;
0:0001000B db 50h ; P
0:0001000C db 72h ; r
0:0001000D db 6Fh ; o
0:0001000E db 21h ; !
0:0001000F db 20h ;
0:00010010 db 0Dh ;
0:00010011 db 0Ah ; a) исходные данные – требуется вывести на консоль содержимое отображаемых
40
ячеек памяти auto a;
Message(“>”); for (a=0x10000;a<0x10011;a++)
Message("%c",Byte(a));
Message("\n"); b) последовательный вызов Byte для каждой ячейки
> Hello, IDA Pro! c) результат
Другие примеры использования функции Byte можно найти в главе «Первые шаги с
IDA Pro» и в файле “memcpy.idc”, входящим в комплект поставки IDA.
??? #Верстальщику – change table аргумент пояснения ea линейный адрес ячейки виртуальной памяти
=return пояснения
== содержимое байта ячейки виртуальной памяти return
==0xFF ошибка
Родственные функции: Word, Dword
Интерактивный аналог: нет long Word (long ea)
Функция возвращает значение слова (одно слово равно двум байтам) виртуальной памяти, расположенного по адресу ea. При попытке чтения байта, расположенного по несуществующему адресу, равно как и имеющего неопределенное значение, функция возвращает значение 0xFF, сигнализируя об ошибке. Наглядно продемонстрировать работу функции позволяет следующий пример:
0:00010000 db 48h ; H
0:00010001 db 65h ; e
0:00010002 db 6Ch ; l
0:00010003 db 6Ch ; l
0:00010004 db 6Fh ; o
0:00010005 db 2Ch ; ,
0:00010006 db 20h ;
0:00010007 db 49h ; I
0:00010008 db 44h ; D
0:00010009 db 41h ; A
0:0001000A db 20h ;
0:0001000B db 50h ; P
0:0001000C db 72h ; r
0:0001000D db 6Fh ; o
0:0001000E db 21h ; !
0:0001000F db 20h ;
0:00010010 db 0Dh ;
0:00010011 db 0Ah ;
Message(“>%X\n”, Word (0x10000));
41
>6548
Message(“>%X\n”, Word (0x0));
>FFFF
Message(“>%X\n”, Word (0x10011));
>FF0A
Message(“>%X\n”, Word (0xFFFF));
>48FF
В первом случае существуют оба адреса (т.е. 0x10000 и 0x10001) и функция отрабатывает успешно; во втором – ни существует ни одного из них – ни 0x0, ни 0x1, в результате чего возвращается 0xFFFF.
Но попытка прочитать слово, расположенное по адресу 0x10011, приводит к тому, что в младшем байте
возвращается значение соответствующей ячейки, а в старшем –
0xFF! Аналогично и в последнем примере – несуществующий младший байт дает 0xFF, в то время как старший читается успешно.
Поэтому, до вызова функции Word следует убедиться, что обе ячейка действительно существуют и имеют определенные значение. Проверить это можно, проанализировав младший бит поля атрибутов каждой из ячеек – если он не равен нулю, то все о’кей. О том как это сделать подробно рассказано в описании функции Byte.
??? #верстальщику – change table аргумент пояснения ea линейный адрес ячейки виртуальной памяти
==return пояснения
== содержимое слова виртуальной памяти return
==FF?? | ==??FF ошибка
Родственные функции: Byte, Dword.
Интерактивный аналог:
нет long Dword (long ea)
Функция возвращает значение двойного слова виртуальной памяти по указанному адресу.
В остальном она полностью аналогична функции Word.
??? #верстальщику – change table аргумент пояснение ea линейный адрес ячейки виртуальной памяти
==return Пояснения содержимое двойного слова виртуальной памяти return
==(FF) ошибка
Родственные функции: Byte, Word
Интерактивный аналог:
нет 42
void PatchByte (long ea, long value)
Функция модифицирует содержимое байта виртуальной памяти, расположенного по линейному адресу
ea, на значение
value.
По замыслу разработчика предназначалась для
падченья программы (например, замене 7x на EB, т.е. инструкций условного перехода на безусловный переход – операция часто сопутствующая снятию защит), чем и объясняется ее название. Однако, она нашла применение в решении широкого круга различных задач, в частности копировании фрагментов виртуальной памяти.
Функция не позволяет модифицировать не существующие ячейки памяти и не сигнализирует об ошибках записи, поэтому, перед ее вызовом рекомендуется проверить передаваемый ей линейный адрес на существование вызовом GetFlags (подробнее об этом рассказывается в описании функции Byte).
Пример ее использования можно найти в файле “memcpy.idc”, поставляемом вместе с IDA.
??? #верстальщику – change table аргумент пояснение ea линейный адрес ячейки виртуальной памяти value Записываемое значение (байт)
Родственные функции: PatchWord, PatchDword
Интекративный аналог: «
EDIT\Patch program\Change byte» void PatchWord (long ea,long value)
Функция модифицирует содержимое слова виртуальной памяти, расположенного по адресу
ea на значение
value. В остальном аналогичена PatchByte (см. описание
PathByte).
??? #верстальщику – change table аргумент пояснения ea линейный адрес ячейки виртуальной памяти value Записывамое значение (слово)
Родственные функции: PatchByte, PatchDword
Интерактивный аналог: «
EDIT\ Patch program\Change word» void PatchDword (long ea,long value)
Функция модифицирует
содержимое двойного слова виртуальной памяти, расположенного по адресу
ea на значение
value. В остальном аналогична PatchByte (см. описание PatchByte)
??? #верстальщику – change table аргумент пояснения
43
ea линейный адрес ячейки виртуальной памяти value Записывамое значение (слово)
Родственные функции: PatchByte, PatchWord
Интерактивный аналог: нет long NextAddr (long ea)
Функция возвращает следующий существующий виртуальный адрес, и BADADDR в том случае, если такого адреса не существует. Вызов NextAddr (BADADDR) равносилен
NextAddr (0x0).
Пример использования:
0:00010000 db 48h ; H
0:00010001 db 65h ; e
0:00010002 db 6Ch ; l
0:00010003 db 6Ch ; l
0:00010004 db 6Fh ; o
0:00010005 db 2Ch ; ,
0:00010006 db 20h ;
0:00010007 db 49h ; I
0:00010008 db 44h ; D
0:00010009 db 41h ; A
0:0001000A db 20h ;
0:0001000B db 50h ; P
0:0001000C db 72h ; r
0:0001000D db 6Fh ; o
0:0001000E db 21h ; !
0:0001000F db 20h ;
0:00010010 db 0Dh ;
0:00010011 db 0Ah ; a) исходные данные – требуется получить список адресов виртуальной памяти auto a; a=0; while(1)
{ a=NextAddr(a); if (a==BADADDR) break;
Message(">%x\n",a);
} b) трассировка адресов последовательными вызовами функции NextAddr
>10000
>10001
>10002
>10003
>10004
>10005
>10006
>10007
>10008
>10009
>1000a
44
>1000b
>1000c
>1000d
>1000e
>1000f
>10010
>10011 с) результат – получение перечня существующих адресов виртуальной памяти
??? #верстальщику – change table аргумент пояснения ea линейный адрес ячейки виртуальной памяти
=return пояснения
!=BADADDR следующий за ea адрес виртуальной памяти return
==BADADDR ошибка
Родственные функции: PrevAddr
Интерактивный аналог: нет long PrevAddr (long ea)
Функция возвращает предшествующий ea существующий виртуальный адрес, и
BADADDR в том случае, если такого адреса не существует.
Пример использования:
0:00010000 db 48h ; H
0:00010001 db 65h ; e
0:00010002 db 6Ch ; l
0:00010003 db 6Ch ; l
0:00010004 db 6Fh ; o
0:00010005 db 2Ch ; ,
0:00010006 db 20h ;
0:00010007 db 49h ; I
0:00010008 db 44h ; D
0:00010009 db 41h ; A
0:0001000A db 20h ;
0:0001000B db 50h ; P
0:0001000C db 72h ; r
0:0001000D db 6Fh ; o
0:0001000E db 21h ; !
0:0001000F db 20h ;
0:00010010 db 0Dh ;
0:00010011 db 0Ah ; a) исходные данные – требуется получить список адресов виртуальной памяти auto a; a=BADADDR; while(1)
{ a=PrevAddr(a); if (a==BADADDR) break;
Message(">%X\n",a);
45
} b) трассировка адресов последовательными вызовами функции PrevAddr
>10011
>10010
>1000F
>1000E
>1000D
>1000C
>1000B
>1000A
>10009
>10008
>10007
>10006
>10005
>10004
>10003
>10002
>10001
>10000 с) результат – получение перечня существующих адресов виртуальной памяти
??? #верстальщику – change table аргумент пояснение ea линейный адрес ячейки виртуальной памяти
=return пояснения
!=BADADDR предшествующий ea адрес виртуальной памяти return
==BADADDR ошибка
Родственные функции: NextAddr
Интерактивный аналог: нет long GetFlags(long ea)
Функция возвращает значение флагов виртуальной памяти, ассоциированных с виртуальным адресом ea. Если указанного виртуального адреса не существует, функция возвращает ноль.
О назначении каждого бита флагов рассказано при описании связанных с ним функций.
??? #верстальщику – change table аргумент пояснения ea линейный адрес ячейки виртуальной памяти
=return Пояснения
!=0 значение флагов return
==0 ошибка
Родственные функции: SetFlags
Интерактивный аналог: нет
46
void SetFlags(long ea)
Функция задает новое значение флагов виртуальной памяти, ассоциированных с виртуальным адресом ea. Допустимо модифицировать флаги лишь существующей ячейки виртуальной памяти.
Внимание: настоятельно рекомендуется по возможности избегать
непосредственной модификации флагов – допущенная ошибка может привести к
зависанию дизассемблера!
??? #верстальщику – change table аргумент пояснения ea линейный адрес ячейки виртуальной памяти
Родственные функции: GetFlags
Интерактивный аналог: нет long FindBinary(long ea,long flag,char str)
Функция ищет заданную подстроку в виртуальной памяти и в случае успешного поиска возвращает ее линейный адрес, иначе возвращает значение BADADDR, сигнализируя об ошибке.
В зависимости от флага направления поиск может идти как вперед (от младших адресов к старшим), так и назад (от старших адресов к младшим), регистр символов может как различаться, так и нет.
Аргумент ea задает линейный адрес начала поиска и не обязательно должен существовать.
Аргумент str задает подстроку поиска, выраженную в шестнадцатеричных кодах символов (точнее – в системе исчисления, установленной системой исчисления по умолчанию), разделенных между собой пробелами. Суффикс “h”, равно как и префикс “x” при этом указывать не нужно.
Аргумент flag задает направление поиска и определяет чувствительность к регистру символов: если его младший бит установлен поиск идет от младших адресов к старшим и, соответственно, наоборот; если первый справа бит (считая от нуля) установлен
– прописные и строчечные буквы различаются и, соответственно, наоборот.
Пример использования: seg000:0000 db 48h ; H seg000:0001 db 65h ; e seg000:0002 db 6Ch ; l seg000:0003 db 6Ch ; l seg000:0004 db 6Fh ; o seg000:0005 db 2Ch ; , seg000:0006 db 20h ; seg000:0007 db 49h ; I seg000:0008 db 44h ; D seg000:0009 db 41h ; A seg000:000A db 20h ; seg000:000B db 50h ; P seg000:000C db 72h ; r seg000:000D db 6Fh ; o seg000:000E db 21h ; ! seg000:000F db 0 ;
47
Message(">%s\n",atoa(FindBinary( SegByName("seg000"),1,"49 44 41")));
??? #верстальщику – change table аргумент пояснения ea линейный адрес начала поиска
=flag пояснения бит
#
0 поиск от старших адресов к младшим
0 1 поиск от младших адресов к старшим
0 не различать регистр символов flag
1 1 различать регистр символов
=return Пояснения
!=BADADDR линейный адрес найденной подстроки return
==BADADDR ошибка
Родственные функции:
нет Интерактивный аналог: “Search\Text”,
СЕГМЕНТЫ И СЕЛЕКТОРЫ
#Definition
Сегментом называется непрерывная область памяти, адресуемая относительно базового адреса сегмента.
Каждый сегмент характеризуется базовым адресом сегмента, адресом начала
сегмента и адресом конца сегмента.
Базовый адрес сегмента обычно выражается в параграфах, адреса начала и конца
- в байтах.
Адрес начала сегмента задает наименьший адрес, принадлежащей сегменту; адрес конца сегмента – адрес, на единицу больше превышающий наибольший адрес, принадлежащий сегменту.
Никакой линейный адрес не может принадлежать более чем одному сегменту одновременно – т.е. сегменты не могут пересекаться.
В дальнейшем, если не оговорено обратное, адрес начала сегмента обозначается
“startea”, адрес конца сегмента – “endea”, а базовый адрес – “BASE”.
Смещение первого байта в сегменте обозначается “startoffset” и связано с адресом начала и базовым адресом следующим соотношением: startoffset = startea – BASE * 0x10
Формула 1 Смещение первого байта в сегменте
Смещения в сегменте измеряются целыми неотрицательными числами, следовательно, приравняв startoffset к нулю, получаем: startea
≥ (BASE* 0x10).
Сегментный адрес [BASE:offset] связан с линейным адресом следующим соотношением:
48
ea = BASE * 0x10 + offset
Формула 2 Перевод сегментного адреса в линейный Подавляющее большинство функций IDA работают не с сегментными, а с линейными адресами. Пользователь же, напротив, видит на экране дизассемблера в основном сегментные адреса, а линейные от его взора скрыты.
Для облегчения преобразования сегментных адресов в линейные предусмотрен специальный макрос
MK_FP(long BASE, long offset), возвращающий значение
BASE*0x10+offset, а так же оператор «квадратные скобки» - “[BASE, offset]” аналогичного назначения.
Линейные адреса начала и конца сегмента представляют собой 32-битовые значения, ограничивающие максимальный размер сегмента четырьмя гигабайтами.
Базовый адрес представляет собой 16-битовое значение, ограничивающее адресуемую память одним мегабайтом, которого в ряде случаев оказывается недостаточно.