Описание функций встроенного языка
Скачать 2.86 Mb.
|
Ivanov ",0x66); SetHashLong(a," Cheputilo ",0x77); SetHashLong(a," Alushta ",0x67); DeleteArray(a); 368 Операнд Пояснения id Идентификатор массива idx Индекс массива (строковой!) value Присваиваемое значение типа «длинное целое» ==return Пояснения ==1 Успешное завершение Return ==0 Ошибка success SetHashString(long id,char idx,char value); Функция присваивает значение элементу ассоциативного массива. Ассоциативные массивы выгодно отличаются от остальных тем, что могут индексироваться строковыми значениями! В остальном же с ними могут использоваться те же подходы, что и для разряженных массивов. Однако, в отличие от разреженных массивов один и тот же индекс не может содержать числовое и строковое значение одновременно. Пример использования: auto a; DeleteArray(GetArrayId("MyArray")); a=CreateArray("MyArray"); SetHashLong(a," Ivanov ",”Patron”); SetHashLong(a," Cheputilo ",”Mouse”); SetHashLong(a," Alushta ",”Metro Station”); DeleteArray(a); Операнд Пояснения id Идентификатор массива idx Индекс массива (строковой!) value Присваиваемое значение типа «строка» ==return Пояснения ==1 Успешное завершение Return ==0 Ошибка long GetHashLong(long id,char idx); Функция возвращает значение элемента ассоциативного массива типа «длинное целое» Как уже говорилось выше один и тот же элемент не может содержать значения «строка» и «длинное целое» одновременно. Поэтому возникает возможность присвоить значение одного типа, а попытаться прочитать другого. Эта операция завершиться корректно и типы будут автоматически преобразованы. При этом функция GetHaskLong всегда возвращает четыре первые байта, сколько бы строка ни занимала на самом деле. Если она была короче, - то остаток будет представлять собой мусор и содержать непредсказуемые значения. Например: auto a; DeleteArray(GetArrayId("MyArray")); 369 a=CreateArray("MyArray"); SetHashString(a,"Ivanov","Patron"); Message("%s \n", GetHashLong(a,"Ivanov")'>GetHashLong(a,"Ivanov") ); DeleteArray(a); Patr Необходимо помнить, что IDA учитывает регистр индексов. Так “Ivanov” и “ivanov” это два разных индекса и при попытке прочитать присвоенное значение функция возвратит ноль. Например: auto a; DeleteArray(GetArrayId("MyArray")); a=CreateArray("MyArray"); SetHashLong(a," I vanov",0х66); Message("%x \n", GetHashLong(a," i vanov") ); DeleteArray(a); 0 Возникает неоднозначность, – то ли действительно возникла ошибка, то ли такое значение имеет элемент? В остальном же никаких проблем с использованием этой функции не возникает. Например: auto a; DeleteArray(GetArrayId("MyArray")); a=CreateArray("MyArray"); SetHashLong(a,"Ivanov",0х66); Message("%x \n", GetHashLong(a,"Ivanov") ); DeleteArray(a); 0x66 Операнд Пояснения id Идентификатор массива idx Индекс массива (строковой!) ==return Пояснения !=0 Значение элемента массива Ошибка Return ==0 Значение элемента массива char GetHashString(long id,char idx); Функция возвращает значение элемента ассоциативного массива типа «строка» 370 Как уже говорилось выше один и тот же элемент не может содержать значения «строка» и «длинное целое» одновременно. Поэтому возникает возможность присвоить значение одного типа, а попытаться прочитать другого. Эта операция завершиться корректно и типы будут автоматически преобразованы. При этом функция GetHashString возвращает четыре первые байта, если ни один из них не является нулем, в противном случае весь отрезок до первого нуля. Например: auto a; DeleteArray(GetArrayId("MyArray")); a=CreateArray("MyArray"); SetHashLong(a,"Ivanov",0x66776677); Message("%s \n", GetHashString(a,"Ivanov")); DeleteArray(a); Wfwf Необходимо помнить, что IDA учитывает регистр индексов. Так “Ivanov” и “ivanov” это два разных индекса и при попытке прочитать присвоенное значение функция возвратит пустую строку. Например: auto a; DeleteArray(GetArrayId("MyArray")); a=CreateArray("MyArray"); SetHashString(a," I vanov",0х66); Message("%s \n", GetHashLong(a," i vanov") ); DeleteArray(a); Возникает неоднозначность, – то ли действительно возникла ошибка, то ли такое значение имеет элемент? В остальном же никаких проблем с использованием этой функции не возникает. Например: auto a; DeleteArray(GetArrayId("MyArray")); a=CreateArray("MyArray"); SetHashString(a,"Ivanov",”Patron”); Message("%s \n", GetHashLong(a,"Ivanov") ); DeleteArray(a); Patron Операнд Пояснения id Идентификатор массива idx Индекс массива (строковой!) ==return Пояснения Return !=”” Значение элемента массива 371 Ошибка ==”” Значение элемента массива success DelHashElement(long id,char idx); Функция удаляет один элемент ассоциативного массива. Поскольку один и тот же элемент не может содержать значения «строка» и «длинное целое» одновременно, отпадает необходимость указывать теги (смотри описание функции DelArrayElement для разряженных массивов) Необходимо помнить, что IDA учитывает регистр индексов. Так “Ivanov” и “ivanov” это два разных индекса и представляют собой два разных элемента. В остальном же функция ничем не отличается от аналогичной, использующийся для удаления элементов разряженных массивов. Например: auto a; DeleteArray(GetArrayId("MyArray")); a=CreateArray("MyArray"); SetHashString(a,"Ivanov",”Patron”); Message("%s \n", DelHashElement(a,"Ivanov") ); DeleteArray(a); 1 Операнд Пояснения id Идентификатор массива idx Индекс массива (строковой!) ==return Пояснения ==1 Операция выполнена успешно Return ==0 Ошибка char GetFirstHashKey(long id); Функция возвращает индекс первого элемента ассоциативного массива. Поскольку ассоциативные массивы индексируются строковыми значениями, то привычные для нас способы обращения к элементам не подходят. Что бы понять принципы функционирования этой (и некоторых других) функций, необходимо познакомиться с техническими деталями архитектуры ассоциативных массивов. Индексы ассоциативных массивов хранятся в списке, упорядоченном в алфавитной последовательности, не зависимо от порядка добавления в него новых элементов, что и доказывает следующий пример: auto a; DeleteArray(GetArrayId("MyArray")); a=CreateArray("MyArray"); SetHashLong(a,"Ivanov",0x66); SetHashLong(a,"Cheputilo",0x77); SetHashLong(a,"Alushta",0x67); Message("%s \n", 372 GetFirstHashKey(a) ); DeleteArray(a); Alushta Операнд Пояснения id Идентификатор массива ==return Пояснения !=”” Индекс первого элемента массива Return ==”” Ошибка char GetLastHashKey(long id); Функция возвращает индекс последнего элемента ассоциативного массива. Поскольку ассоциативные массивы индексируются строковыми значениями, то привычные для нас способы обращения к элементам не подходят. Что бы понять принципы функционирования этой (и некоторых других) функций, необходимо познакомиться с техническими деталями архитектуры ассоциативных массивов. Индексы ассоциативных массивов хранятся в списке, упорядоченном в алфавитной последовательности, не зависимо от порядка добавления в него новых элементов, что и доказывает следующий пример: auto a; DeleteArray(GetArrayId("MyArray")); a=CreateArray("MyArray"); SetHashLong(a,"Ivanov",0x66); SetHashLong(a,"Cheputilo",0x77); SetHashLong(a,"Alushta",0x67); Message("%s \n", GetLastHashKey(a) ); DeleteArray(a); Ivanov Операнд Пояснения id Идентификатор массива ==return Пояснения !=”” Индекс последнего элемента массива Return ==”” Ошибка char GetNextHashKey(long id,char idx); Функция возвращает индекс следующего элемента ассоциативного массива. Поскольку ассоциативные массивы индексируются строковыми значениями, то привычные для нас способы обращения к элементам не подходят. Что бы понять принципы функционирования этой (и некоторых других) функций, необходимо познакомиться с техническими деталями архитектуры ассоциативных массивов. Индексы ассоциативных массивов хранятся в списке, упорядоченном в алфавитной последовательности, не зависимо от порядка добавления в него новых элементов, и 373 функция GetNextHashKey последовательно возвращает элементы ассоциативного массива один за другим. Передаваемый ей текущий индекс не обязательно должен существовать в природе – функция просматривает список всех элементов и возвращает следующий в алфавитном порядке за ним. Это дает возможность отказаться от вызовов GetFirstHashKey, поскольку GetNextHashKey(,””) будет его полным эквивалентом. Например: auto a,b; b=""; DeleteArray(GetArrayId("MyArray")); a=CreateArray("MyArray"); SetHashLong(a,"Ivanov",0x66); SetHashLong(a,"Cheputilo",0x77); SetHashLong(a,"Alushta",0x67); for(;;){ b=GetNextHashKey(a,b); if (b=="") break; Message("%s \n",b);} DeleteArray(a); Alushta Cheputilo Ivanov Операнд Пояснения id Идентификатор массива idx Индекс массива (строковой!) ==return Пояснения !=”” Очередной индекс массива Return ==”” Ошибка char GetPrevHashKey(long id,char idx); Функция возвращает индекс предыдущего элемента ассоциативного массива. Поскольку ассоциативные массивы индексируются строковыми значениями, то привычные для нас способы обращения к элементам не подходят. Что бы понять принципы функционирования этой (и некоторых других) функций, необходимо познакомиться с техническими деталями архитектуры ассоциативных массивов. Индексы ассоциативных массивов хранятся в списке, упорядоченном в алфавитной последовательности, не зависимо от порядка добавления в него новых элементов, и функция GetPrevHashKey последовательно возвращает элементы ассоциативного массива один за другим. Передаваемый ей текущий индекс не обязательно должен существовать в природе – функция просматривает список всех элементов и возвращает предшествующий в алфавитном порядке за ним. Это дает возможность отказаться от вызовов GetLastHashKey, поскольку GetNextHashKey(,-1) будет его полным эквивалентом. Например: auto a,b; b=-1; 374 DeleteArray(GetArrayId("MyArray")); a=CreateArray("MyArray"); SetHashLong(a,"Ivanov",0x66); SetHashLong(a,"Cheputilo",0x77); SetHashLong(a,"Alushta",0x67); for(;;){ b=GetPrevHashKey(a,b); if (b=="") break; Message("%s \n",b);} DeleteArray(a); Ivanov Cheputilo Alushta Операнд Пояснения Id Идентификатор массива idx Индекс массива (строковой!) ==return Пояснения !=”” Очередной индекс массива Return ==”” Ошибка ОПЕРАЦИИ С ГЛОБАЛЬНЫМИ НАСТРОЙКАМИ МЕТОДЫ Функция Назначение long GetLongPrm (long offset) Возвращает длинный целый параметр long GetShortPrm(long offset); Возвращает короткий целый параметр long GetCharPrm (long offset) Возвращает байтовый параметр success SetLongPrm (long offset,long value); Задает длинный целый параметр success SetShortPrm(long offset,long value); Задает короткий целый параметр success SetCharPrm (long offset,long value); Задает байтовый параметр success SetPrcsr (char processor); Задет тип процессора для дизассемблирования long Batch (long batch); Устанавливает или снимает пакетный режим работы char GetIdaDirectory () Возвращает путь к директории, в которой расположена IDA 375 char GetInputFile () Возвращает имя дизассемблируемого файла long GetLongPrm (long offset); long GetShortPrm(long offset); long GetCharPrm (long offset); success SetLongPrm (long offset,long value); success SetShortPrm(long offset,long value); success SetCharPrm (long offset,long value); IDA предоставляет возможность не только чтения глобальных установок из скриптов, но даже их модификации. Для этого служат целых шесть приведенных выше функций. Это может показаться излишне сложным, но на самом деле все они сводятся к простому чтению \ записи непрерывного фрагмента памяти, в котором IDA и хранит свои настройки. Три функции чтения GetLongPrm, GetShortPrm, GetCharPrm отличаются только возвращаемым значением. Первая возвращает длинное целое, вторая короткое целое и последняя строку. В каком-то смысле все они взаимозаменяемы. Т.е. можно использовать GetLongPrm для чтения короткого целого, если потом «врачую» маскировать старшие биты возращенного значения. Обратите внимание, что GetCharPrm возвращает не строку, оканчивающуюся нулем, а только один байт. Чтение же всей строки целиком приходится осуществлять пошагово в цикле байт за байтом. Или можно воспользоваться GetLongPrm, читая строку по четыре байта за раз (это удобнее да и быстрее). ‘offset’ это смещение внутри структуры, в которой IDA и хранит настойки. Ниже это будет подробно описано. А пока обратим внимание на то, что IDA не запрещает передавать функции произвольное смещение внутри структуры. Это часто становится источником неочевидных ошибок. Обычно такое происходит, когда используются фиксированные смещения элементов структуры, вместо определенных IDA значений. Ввиду того, что в следующих версиях эта структура, скорее всего, не останется без изменений, то необходимо использовать только определения IDA, иначе за работоспособность скрипта трудно будет поручиться. НАСТОЙКИ IDA Первые три байта хранят в себе слово ‘IDA’. Хотя это и не сообщается в документации, но нетрудно убедится, что это именно так и есть. Message("%s%s\n", GetShortPrm(0), GetCharPrm(2) ); IDA INF_VERSION Содержит, переменную типа Short хранящую версию базы IDA. Например: Message("%x \n", 376 GetShortPrm(INF_VERSION) ); 22 INF_PROCNAME Хранит восьмисимвольное имя выбранного типа процессора дизассемблируемого текста. Для процессоров серии 80x86 предусмотрены следующие соответствия: Intel 8086 8086 Intel 80286 real 80286r Intel 80286 protected 80286p Intel 80386 real 80386r Intel 80386 protected 80386p Intel 80486 real 80486r Intel 80486 protected 80486p Intel Pentium real with MMX 80586r Intel Pentium protected with MMX 80586p Intel Pentium Pro (P6) with MMX 80686p Intel Pentium II p262 AMD K6-2 with 3DNow! K62p3 Intel Pentium III p3ntel Наиболее разумным (и быстрым) способом извлечения этого поля, вероятно, окажется чтение его с помощью GetLongPrm как показано ниже: Message("%s%s \n", GetLongPrm(INF_PROCNAME), GetLongPrm(INF_PROCNAME+4) ); p3ntel ПРИМЕЧАНИЕ: Это поле может только считываться. Все попытки его модификации посредством SetXXXPrm будут проигнорированы. INF_LFLAGS Это однобайтовое поле хранит флаги, определяемые по умолчанию в IDP модуле для конкретной модели процессора, которые могут принимать следующие значения: LFLG_PC_FPP (0x1) Декодировать инструкции с плавающей запятой для арифметического сопроцессора. LFLG_PC_FLAT (0x2) Плоская модель памяти 377 Обратите внимание, что изменение последнего параметра может повлечь за собой непредсказуемую работу дизассемблера и привести к неверному анализу исследуемого файла! Пример использования: auto a; a=GetCharPrm(INF_LFLAGS); Message(“%x \n”,a); if (a & LFLG_PC_FPP) Message ("Decode FPP \n"); if (a & LFLG_PC_FLAT) Message ("FLAT MODEL \n"); 1 Decode FPP INF_DEMNAMES Однобайтовое поле, определяющие каким образом IDA будет «заманглять» имена. Безболезненно может как считываться, так и модифицироваться. DEMNAM_CMNT (0); Отображать замангленные имена как комментарии. Например: SetCharPrm(INF_DEMNAMES,DEMNAFM_CMNT); .text:00403E79 ?sputc@streambuf@@QAEHH@Z proc near ; streambuf::sputc(int) DEMNAM_NAME (1) Заманглять в имена. Например: SetCharPrm(INF_DEMNAMES,DEMNAFM_NAME); .text:00403E79 public: int __thiscall streambuf::sputc(int) proc near DEMNAM_NONE (2) Не заманглять и представлять имена как есть. SetCharPrm(INF_DEMNAMES,DEMNAFM_NONE); .text:00403E79 ?sputc@streambuf@@QAEHH@Z proc near При установке нового значения IDA автоматически начнет реанализ и внесет все изменения в дизассемблируемый текст. 378 INF_FILETYPE Это поле содержит короткое целое, хранящее тип дизассемблируемого файла. Видимо не используется IDA, поскольку может безболезненно модифицироваться произвольными значениями, что не нарушает работоспособности. Так же следует учитывать, что в версии 3.84 функция возвращает неверные значения. Дело в том, что IDC.IDC не был изменен, тогда как были расширены типы файлов, начиная с середины таблицы, от чего все типы «посыпались». MS-DOS exe файл стал определятся как программный файл PalmPilot, что хотя и не нарушало работоспособности IDA, но не позволяло определить тип текущего файла. В IDC.IDC содержится ссылка на файл ‘core.hpp’. На самом деле это опечатка и нужно смотреть ‘ida.hpp’, входящий в IDA SDK. Там мы обнаружим прелюбопытную структуру, описывающую типы поддерживаемых файлов. Сравнив ее с IDC.IDC можно обнаружить различие, которое показано ниже: f_EXE_old, FT_EXE_OLD f_COM_old, FT_COM_OLD f_BIN, FT_BIN f_DRV, FT_DRV f_WIN, FT_WIN f_HEX, FT_HEX f_MEX, FT_MEX f_LX, FT_LX f_LE, FT_LE f_NLM, FT_NLM f_COFF, FT_COFF f_PE, FT_PE f_OMF, FT_USER f_SREC, FT_OMF f_ZIP, FT_SREC f_OMFLIB, FT_ZIP f_AR, FT_OMFLIB f_LOADER, FT_AR f_ELF, FT_LOADER f_W32RUN, FT_ELF f_AOUT, FT_W32RUN f_PRC, FT_AOUT FT_PRC FT_EXE FT_COM FT_AIXAR Что бы функция возвращала правильный результат, необходимо исключить тип FT_USER и перенумеровать остаток списка. Расшифровка всех значений приведена ниже: FT_EXE_OLD MS DOS EXE файл FT_COM_OLD MS DOS COM файл FT_BIN Двоичный файл (дамп ROM например) 379 FT_DRV MS DOS драйвер (drv или sys) FT_WIN New Executable (NE) FT_HEX Intel Hex Object File FT_MEX MOS Technology Hex Object File FT_LX Linear Executable (LX) FT_LE Linear Executable (LE) FT_NLM Netware Loadable Module (NLM) FT_COFF Common Object File Format (COFF) FT_PE Portable Executable (PE) FT_USER Файл, загруженный посредством загрузчика IDP FT_OMF Object Module Format FT_SREC R-records FT_ZIP ZIP file (никогда не бывает загружен в базу IDA) FT_OMFLIB Библиотека OMF Модулей FT_AR ar library FT_LOADER Файл загружен посредством LOADER DLL FT_ELF Executable and Linkable Format (ELF) FT_W32RUN Watcom DOS32 Extender (W32RUN) FT_AOUT Linux a.out (AOUT) FT_PRC PalmPilot программный файл FT_EXE MS DOS EXE File FT_COM MS DOS COM File FT_AIXAR AIX ar library Пример использования: Message("%d \n", |