Описание функций встроенного языка
Скачать 2.86 Mb.
|
Функция возвращает селектор перемещаемого элемента, заданного линейным адресом. Пример использования: C0000000 ; Segment type: Pure code C0000000 LCOD segment para public 'CODE' use32 C0000000 assume cs:LCOD C0000000 ;org 0C0000000h C0000000 assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing C0000000 Service_Table_0 dd offset unkserv_0 ; DATA XREF: LCOD:C0000040 Message("0x%X, 0x%X \n", GetNextFixupEA(0), GetFixupTgtSel(GetNextFixupEA(0) ) ); 0xC0000000, 0x2 301 Операнд Пояснения ea Линейный адрес Завершение Пояснения !=BADADDR Селектор перемещаемого элемента Return ==BADADDR Ошибка long GetFixupTgtOff(long ea); Функция возвращает смещение перемещаемого элемента, заданного линейным адресом. Пример использования: C0000000 ; Segment type: Pure code C0000000 LCOD segment para public 'CODE' use32 C0000000 assume cs:LCOD C0000000 ;org 0C0000000h C0000000 assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing C0000000 Service_Table_0 dd offset unkserv_0 ; DATA XREF: LCOD:C0000040 Message("0x%X, 0x%X \n", GetNextFixupEA(0), GetFixupTgtOff(GetNextFixupEA(0) ) ); 0xC0000000, 0xC0003514 Операнд Пояснения ea Линейный адрес Завершение Пояснения !=BADADDR Смещение перемещаемого элемента Return ==BADADDR Ошибка long GetFixupTgtDispl(long ea); Функция возвращает displacement перемещаемого элемента, заданного линейным адресом. В настоящее время на платформе Intel практически не используется и подробнее описана в факультативном приложении к книге «Использование IDA на не-Intel платформах» Операнд Пояснения ea Линейный адрес Завершение Пояснения !=BADADDR Displacement перемещаемого элемента Return ==BADADDR Ошибка void SetFixup(long ea,long type,long targetsel,long targetoff,long displ); 302 Функция позволяет управлять перемещаемым элементом. Практически никогда не используется, так как IDA сама разбирается в большинстве существующих форматов файлов и правильно задает значение перемещаемых элементов. Однако, может быть полена при написании своего загрузчика файла. Тогда необходимо для каждого перемещаемого элемента вызвать эту функцию, указав его линейный адрес. Обратите внимание, не адрес начала манипулирующей с ним инструкции. Тип перемещаемого элемента может принимать одно из следующих значений: FIXUP_MASK 0xF FIXUP_BYTE FIXUP_OFF8 FIXUP_OFF8 0 Восьми битное смещение FIXUP_OFF16 1 16-битное смещение FIXUP_SEG16 2 16-битный сегмент (селектор) FIXUP_PTR32 3 32-битный длинный указатель (16-бит база; 16-бит селектор) FIXUP_OFF32 4 32-битное смещение FIXUP_PTR48 5 48-битный указатель (16-бит база; 32-бит смещение). FIXUP_HI8 6 Старшие 8 бит 16-битного смещения FIXUP_HI16 7 Старшие 16 бит 32-битного смещения FIXUP_LOW8 8 Младшие 8 бит 16-битного смещения FIXUP_LOW16 9 Младшие 16бит 32-битного смещения FIXUP_REL 0x10 fixup is relative to the linear address specified in the 3d parameter to set_fixup() FIXUP_SELFRE L 0x0 elf-relative? - disallows the kernel to convert operands in the first pass- this fixup is used during output This type of fixups is not used anymore. Anyway you can use it for commenting purpose in the loader modules FIXUP_EXTDEF 0x20 target is a location (otherwise - segment) FIXUP_UNUSED 0x40 fixup is ignored by IDA disallows the kernel to convert operands- this fixup is not used during output FIXUP_CREATE D 0x80 fixup was not present in the input file Следующие два аргумента задают селектор (сегмент) и смещение объекта, на который ссылается перемещаемый элемент. Например: seg000:0000 start proc near seg000:0000 mov ax, seg dseg seg000:0003 mov ds, ax seg000:0005 assume ds:dseg seg000:0005 mov ah, 9 seg000:0007 mov dx, 0Ch seg000:000A int 21h ; DOS - PRINT STRING seg000:000A ; DS:DX -> string terminated by "$" seg000:000C mov ax, seg dseg seg000:000F mov ds, ax seg000:0011 mov ah, 9 303 seg000:0013 mov dx, 0Ch seg000:0016 int 21h ; DOS - PRINT STRING seg000:0016 ; DS:DX -> string terminated by "$" seg000:0018 mov ah, 4Ch seg000:001A int 21h ; DOS - 2+ - QUIT WITH EXIT CODE (EXIT) seg000:001A start endp ; AL = exit code seg000:001A seg000:001A seg000 ends seg000:001A dseg:000C ; ----------------------------------------------------- ---------------------- dseg:000C dseg:000C ; Segment type: Pure data dseg:000C dseg segment para public 'DATA' use16 dseg:000C assume cs:dseg dseg:000C ;org 0Ch dseg:000C aHelloSailor db 'Hello,Sailor!',0Dh,0Ah,'$' dseg:000C dseg ends В приведенном выше коде перемещаемый элемент был создан вызовом: SetFixup(0x10001, FIXUP_SEG16, 0, 0x1001, 0); Операнд Пояснения ea Линейный адрес Type Тип перемещаемого элемента sel Селектор off Смещение Displ Displacement void DelFixup(long ea); Функция удаляет перемещаемый элемент. Операнд Пояснения ea Линейный адрес АНАЛИЗ Имя функции Назначение long FindText (long ea,long flag,long y,long x,char str); Ищет фрагмент дизассемблируемого текста Прочие функции Имя функции Назначение Void DeleteAll Удаляет все элементы и связанные с ними элементы. 304 Long AnalyseArea (long sEA,long eEA Дизассемблирует выбранный регион void AutoMark (long ea,long queuetype); Управляет автоанализом void AutoMark2 (long start,long end,long queuetype) Управляет автоанализов void DeleteAll (); Невероятно “полезная” функция, удаляющая всю информацию о дизассемблируемой программе - сегменты, метки, комментарии, словом все флаги и связанные с ними объекты. Как вариант частичного отката результата использования этой функции – немедленный аварийный выход из IDA без сохранения последних изменений. Пример использования: seg000:0000 ; seg000:0000 ; File Name : F:\IDAF\IDA\test.exe seg000:0000 ; Format : MS-DOS executable (EXE) seg000:0000 ; Base Address: 1000h Range: 10000h-132EAh Loaded length: 32EAh seg000:0000 ; Entry Point : 1000:22C0 seg000:0000 seg000:0000 seg000:0000 ; --------------------------------------------------------- seg000:0000 seg000:0000 ; Segment type: Pure code seg000:0000 seg000 segment byte public 'CODE' use16 seg000:0000 assume cs:seg000 seg000:0000 assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing seg000:0000 seg000:0000;_______ S U B R O U T I N E _______________________________ seg000:0000 seg000:0000 seg000:0000 MyFunct proc near ; CODE XREF: sub_0_22DD+1Ep seg000:0000 push ax ; My Comment seg000:0001 push bx seg000:0002 push cx seg000:0003 push dx seg000:0004 seg000:0004 MyLabel: seg000:0004 mov ax, 3D02h seg000:0007 mov dx, 206h seg000:000A int 21h DeleteAll (); 0:00010000 db 50h ; P 0:00010001 db 53h ; S 0:00010002 db 51h ; Q 0:00010003 db 52h ; R 305 0:00010004 db 0B8h ; + 0:00010005 db 2 ; 0:00010006 db 3Dh ; = 0:00010007 db 0BAh ; ¦ 0:00010008 db 6 ; 0:00010009 db 2 ; 0:0001000A db 0CDh ; - long AnalyseArea (long sEA,long eEA); Полный анализ выбранной области. Весь код будет дизассемблирован независимо от того, были обнаружены на него ссылки или нет. Сравните: seg000:0100 start db 0BBh ; + seg000:0101 db 5 ; seg000:0102 db 1 ; seg000:0103 db 0FFh ; seg000:0104 db 0E3h ; у seg000:0105 db 0B4h ; ¦ seg000:0106 db 6 ; seg000:0107 db 0B2h ; _ seg000:0108 db 7 ; seg000:0109 db 0CDh ; - seg000:010A db 21h ; ! seg000:010B db 0C3h ; + seg000:010B seg000 ends MakeCode(0x10100); seg000:0100 start: seg000:0100 mov bx, 105h seg000:0103 jmp bx seg000:0103 ; ------------------------------------ seg000:0105 db 0B4h ; ¦ seg000:0106 db 6 ; seg000:0107 db 0B2h ; _ seg000:0108 db 7 ; seg000:0109 db 0CDh ; - seg000:010A db 21h ; ! seg000:010B db 0C3h ; + seg000:010B seg000 ends AnalyseArea(0x10100,0x10B); seg000:0100 start: seg000:0100 mov bx, 105h seg000:0103 jmp bx seg000:0105 ; ------------------------------------- seg000:0105 mov ah, 6 seg000:0107 mov dl, 7 seg000:0109 int 21h seg000:010B retn seg000:010B seg000 ends 306 Аналогично авто анализу функция может выполняться в фоновом режиме. Поэтому, в скриптах эта функция используется совместно с Wait(). К сожалению никаких других, более развитых средств синхронизации не предусмотрено. Задаваемые границы анализируемой области не обязательно должны существовать в природе. В крайнем случае, будет проанализирован регион от наименьшего до наибольшего существующих адресов. AnalyseArea(0,0x30000) успешно выполнится, даже если наименьшим из существующих окажется адрес '0x10000'. 'AnalyseArea(0,BADADDR-1);' выполнится успешно и для удобства может быть определено как макрос 'AnalyseAll' и размещено в файле 'ida.idc' При нормальном завершении функция возвращает '1' и '0' если анализ был прерван пользователем по нажатию 'Ctrl-Break'. Операнд пояснения sEA линейный адрес начала анализируемой области eEA линейный адрес конца анализируемой области Return ==return пояснения ==1 Анализ был успешно завершен ==0 Анализ был прерван, нажатием Ctrl-Break void AutoMark (long ea,long queuetype); void AutoMark2 (long start,long end,long queuetype); Функции, позволяющие непосредственно управлять автоанализом. Пользователь может явно указать, как будет трактоваться тот или иной регион. Допустим, нам известно, что в приведенном ниже примере по адресу 0xE расположены данные, а не код. Однако IDA не может «догадаться» до этого и дизассемблирует код не так, как мы этого ожидаем. Разумеется, можно прибегнуть к ручному анализу, но это будет слишком утомительно. Гораздо проще использовать следующие команды: seg000:0004 unk_0_4 db 0B8h seg000:0005 db 2 seg000:0006 db 3Dh seg000:0007 db 0BAh seg000:0008 db 0 seg000:0009 db 32h seg000:000A db 0CDh seg000:000B db 21h seg000:000C db 73h seg000:000D db 9 seg000:000E db 0B4h seg000:000F db 3Ch AutoMark(0x1000E,AU_UNK); MakeCode(0x10004); seg000:0004 loc_0_4: seg000:0004 mov ax, 3D02h seg000:0007 mov dx, 3200h seg000:000A int 21h seg000:000C jnb near ptr unk_0_1 seg000:000C ; -------------------------------------- 307 seg000:000E db 0B4h ; ¦ seg000:000F db 3Ch ; < Как видно, «MakeCode» дошла до адреса 0xE и остановилась. Это очень удобный способ ограничить диапазон ее действия (конечного адреса MakeCode не имеет). Кроме этого с помощью AutoMark можно создавать функции, применять библиотеки сигнатур и так далее. Действие определяется выбором параметра queuetype. Для него определены следующие константы: определение действите AU_UNK не исследовать указанную область AU_CODE преобразовать указанную область в код AU_PROC создать функцию по указанному адресу AU_USED реанализ AU_LIBF применить сигнатуру FLIRT AU_FINAL свернуть все неисследованные области Для одного и того же адреса допустимо задавать более одного указания. IDA помещает все запросы в очередь, поэтому «затирания» не происходит. После анализа запросы удаляются из очереди, поэтому при реанализе следует их задать повторно. AutoMark отличается от AutoMark2 тем, что последняя позволяет явно указать область действия запроса, тогда как первая определяет ее автоматически. Обращаться с этой функцией следует осторожно. Если тип запроса не будет соответствовать определенным константам, то IDA выдаст сообщение об ошибке и аварийно выйдет в операционную систему без сохранения результата работы. Операнд пояснения ‘ea’ линейный адрес queuetype Тип запроса (смотри таблицу выше) long FindText (long ea,long flag,long y,long x,char str); Эта очень полезная и мощная функция для глобального поиска подстроки во всем дизассемблируемом тексте. Сюда входят не только строковые выражения, но и символьное представление инструкций, имен, комментариев, меток и перекрестных ссылок. Словом, равносильно тому, как если бы мы вывели результат работы в дизассемблера в LST файл - отчета и искали бы в нем требуют подстроку. Заметим, что чаще все же так и поступают потому что то FindText работает достаточно медленно и не поддерживает символы-джокеры, как, например hiew. Очень часто критерии поиска настолько сложны, что не могут быть реализованы через ‘FindText’. Поэтому приходится прибегать к созданию хитрых скриптов для весьма изощренного поиска. Однако, в ряде случаев ‘FindText’ все же хватает для повседневых задач и легче использовать несколько вызовов этой функции с разными параметрами, чем прибегать к нештатным средствам. Младший бит флага задает направление поиска. Если он установлен, то поиск будет идти от младших адресов к старшим и наоборот. Первый, считая от нуля, бит флагов указывает на чувствительность функции к регистру. Если он установлен, то заглавные и строчечные символы будут различаться. Координаты ‘x’ и ‘y’ применимы только к многострочным комментариям (ExtLinA\ExtLinB) в остальных жу случаях они игнорируются и могут быть равны нулю. ‘srt’ задает подстроку поиска. 308 seg000:005A 88 04 mov [si], al seg000:005C 46 inc si seg000:005D E2 E7 loop loc_0_46 seg000:005F BE EC 01 mov si, 1ECh seg000:0062 E8 78 00 call sub_0_DD Message("%x \n", FindText(0x1005A,1,0,0,"loop") ); 1005D В случае ошибки поиска функция возвращает константу BADADDR. Операнд пояснения ea Линейный адрес flag ==flag Направление поиска 1 Поиск «вперед» 0 Поиск «назад» Return ==return Пояснения !=BADADDR Линейный адрес найденного текстового вхождения ==BADADDR Ошибка char Demangle(char name, long disable_mask) Функция «размангляет» переданное ей имя name в соответствии с заданными настойками disable_mask (см. таблицу ). Если функция не может разманглить имя, она возвращает пустую строку. IDA Pro поддерживает спецификации Watcom, Microsoft и Borlad. Перечни символов используемых для замангления имен содержатся в поле “MangleChars” конфигурационного файла <ida.cfg> MangleChars = "$:?([.)]" // watcom "@$%?" // microsoft "@$%"; // borland Пример использования: Message(“>%s\n”,Demangle(“??1streambuf@@UAE@XZ”, MNG_DEFNONE)); a) вызов функции Demangle для «размангления» имени “??1streambuf@@UAE@XZ” >public: virtual __thiscall streambuf::streambuf(void) b) результат флаг # пояснения MNG_NOPTRTYPE 0x00000001 не показывать ни far, ни near, ни huge модификаторы MNG_DEFNEAR 0x00000000 не показывать near модификатор MNG_DEFFAR 0x00000002 не показывать far модификатор MNG_DEFHUGE 0x00000004 не показывать huge модификатор MNG_DEFNONE 0x00000006 показывать модификаторы near, far, huge (если установлен MNG_NOPTRTYPE. модификаторы не 309 будут отображаться) MNG_NODEFINIT 0x00000008 не показывать ничего, кроме главного имени MNG_NOUNDERSCORE 0x00000010 не показывать символы прочерка MNG_NOTYPE 0x00000020 не выполнять преобразование типов передаваемых параметров и базового класса MNG_NORETTYPE 0x00000040 не показывать тип значения, возвращаемого функцией MNG_NOBASEDT 0x00000080 не показывать базовый тип MNG_NOCALLC 0x00000100 нигде не преобразовывать типы MNG_NOSCTYP 0x00000400 не показывать ключевые слова public, private, protect MNG_NOTHROW 0x00000800 не показывать описатель throw MNG_NOSTVIR 0x00001000 не показывать ключевые слова static и virtual MNG_NOECSU 0x00002000 не показывать ключевые слова class, struct, union, enum MNG_NOCSVOL 0x00004000 не показывать ключевые слова const и volatile MNG_NOCLOSUR 0x00008000 не показывать ключевого слова __closure MNG_SHORT_S 0x00010000 заменять signed int на sint MNG_SHORT_U 0x00020000 заменять unsigned int на uint MNG_ZPT_SPACE 0x00040000 не показывать пробелы после запятых MNG_IGN_ANYWAY 0x00080000 игнорировать суффикс _nn в конце имен MNG_IGN_JMP 0x00100000 игнорировать префикс j_ в начале имен MNG_MOVE_JMP 0x00200000 переносить префикс j_ и в замангленные имена Это две предварительно определенные сокращенные и полные формы записи. Для просмотра и модификации активируйте пункт меню (Options\ Demangled names...) ??? #верстальщику – change table аргумент пояснения name замангленное имя disable_m ask маска (смотри таблицу ???) =return пояснения !=”” размангленное имя return ==”” ошибка ВЗАИМОДЕЙСТВИЕ С ПОЛЬЗОВАТЕЛЕМ ALMA MATER Изначально IDA проектировалась, как интерактивная среда, то есть тесно взаимодействующая с пользователем. Однако, для скриптов большинство интерфейсных функций не доступно. Нельзя, например, сконструировать диалог или создать свой пункт меню. В распоряжении пользователя оказывается набор функций, обеспечивающий примитивный ввод – вывод. То есть простейшие диалоговое окна запроса параметров и вывода результатов своей деятельности на экран. 310 Впрочем, этого в большинстве случаев оказывается достаточно, потому что большинство скриптов предназначено для работы в автономном режиме. Но иногда все же требуется узнать позицию курсора на экране, или наоборот, перевести его на определенное место, что бы привлечь внимание пользователя, сообщить о результатах своей работы и так далее. Вот для этого и существует набор специальных функций, ютящихся под одной крышей, только потому, что они попали под критерий «взаимодействие с пользователем». В отличие от всех, описанных выше, они не относятся к какому-то определенному объекту и не понятно какой частью архитектуры IDA они являются. Но… они есть, и следовательно, будут тщательно рассмотрены о описаны. Для облегчения понимания введем некоторую дополнительную классификацию, хотя она, конечно, будет весьма условна. Итак, одна группа функций взаимодействует с курсором на экране. Что есть курсор с точки зрения IDA? Это указатель текущей строки, которая связана с некоторым объектом, точнее с линейным адресом его начала. То есть при работе с курсором IDA не рассматривает его экранные координаты, а только линейный адрес памяти, на который этот курсор указывает. Часто бывает так, что несколько строк расположены по одному и тому же линейному адресу. Например: .text:00401020 .text:00401020 ; _______________ S U B R O U T I N E _______________________________________ .text:00401020 .text:00401020 ; Attributes: library function bp-based frame .text:00401020 .text:00401020 public start .text:00401020 start proc near .text:00401020 .text:00401020 var_20 = dword ptr -20h .text:00401020 var_1C = dword ptr -1Ch .text:00401020 var_18 = dword ptr -18h .text:00401020 var_14 = dword ptr -14h .text:00401020 var_4 = dword ptr -4 .text:00401020 .text:00401020 push ebp Все эти стоки совершенно идентичны с точки зрения IDA, поэтому в которой бы из них не находился курсор, при попытке определить его положение, всегда вернется адрес 0х401020, что в общем-то неудивительно. Но вот далеко не однозначно, на какую строку переместится курсор при попытке изменить его положение. Оказывается, что на первую в которой присутствует инструкция или команда. Впрочем, это относится к тем тонкостям реализации, сохранность которых в последующих версиях не гарантируется. Но, с другой стороны, скорее всего не будет изменяться, поскольку это решение выглядит достаточно логичным. Другая группа функций работает с выделением, то есть отмеченным блоком на экране. Собственно это наиболее популярный способ передачи скрипту входных данных для работы, а точнее диапазона адресов. Этим заведуют всего две функции, - SelStart и SelEnd. К сожалению, выделение программно доступно «Только на чтение» и выделить регион самостоятельно скрипт не может. Теперь перейдем к функциям, управляющим экранным вводом – выводом. Ввод данных обеспечивает едва ли не десяток специализированных функций, создающих диалоговые окна и проверяющие корректность ввода пользователя. 311 Однако, в силу больших условностей и множества оговорок, лучше пользоваться только низкоуровневыми функциями, обеспечивающих ввод строкового или длинного целого значений и проверять их корректность самостоятельно. Вывод данных в основном направляется в окно сообщений, и за редким исключением в всплывающие диалоговое окна. Все необходимые функции подробнее будут описаны ниже. |