Набор статей и руководств по дизассемблеру IDA

         

Расширение IDC


Предположим, что Вы хотите расширить встроенный script engine IDC за счет собственных функций (ну мало ли чего может захотеться вполне достигшему половой зрелости программисту - mp3 там послушать, пивка попить и проч.). И сильно меня огорчал все время тот факт, что нет ну совершенно никакого документированного способа добавить ну хоть одну свою функцию в IDC script engine к уже реализованным где-то в бездонных глубинах ida.wll. Однако после пристального изучения файла заголовков expr.hpp можно обнаружить нечто интересное, а именно:

typedef struct { /* Element of functions table */ const char *name; /* Name of function */ error_t (*fp)(value_t *argv,value_t *res); /* Pointer to the Function */ const char *args; /* Type of arguments. Terminated with 0 */ /* VT_WILD means a function with arbitrary number of arguments. Actual number of arguments will be passed in res->num */ } extfun_t;

typedef struct { int qnty; /* Quantity of functions */ extfun_t *f; /* Functions table */ error_t (*startup)(void); error_t (*shutdown)(void); } ffuncset_t;

/*-------------------------------------------------------------------------*/

// Array of built-in IDA functions

extern ffuncset_t Funcs; /* external functions */

И все бы хорошо, только жить да радоваться - но Вы забыли, кто автор этой гениальной программы. Символ Funcs НЕ ЭКСПОРТИРУЕТСЯ из ida.wll (горячий привет Ильфаку. Кстати, ты также забыл экспортировать такие мелочи как qmakefile, doFloat, DoDouble. Не иначе как очередное (какое уже по счету ? Я примерно после третьего десятка сбился со счету) проявление неповторимой заботы о пользователях своего продукта, умиляет аж до кровавых слез). В общем, способ данный будет работать только для версии 4.15 Standard Edition (впрочем, для всех других версий нужно будет поправить всего одно значение - инициализацию ida415_Funcs

в файле idc_ext.cpp. Итак, используем старую недобрую технику расширения таблицы функций, позаимствованную из Linux - можно с легкостью как заменить любую из уже имеющихся функций, так и добавить любое количество собственных функций. Что меня неприятно поразило - то, что массив функций Funcs->f не отсортирован, и при выполнении любой встроенной IDC функции каждый раз происходит линейный поиск. Видимо, Кнута в наше время читать считается плохим тоном и за это расстреливают гнилыми помидорами с логотипом "Compatible with products from Microsoft".


Но и это еще не все. Дело в том, что если Вы захотите слегка расширить таблицу функций например из метода инициализации pluginа, то Вы поимеете неприятности. Дело в том, что каждый plugin загружается два раза. В первый раз просто вызывается метод init - если plugin решает, что он может быть полезным в данных условиях, данный метод должен вернуть PLUGIN_OK. После этого plugin в любом случае ВЫГРУЖАЕТСЯ. Логика - железобетонная. После чего списком грузятся все pluginы, к-рые изъявили желание работать, и второй раз их метод init

уже не вызывается. Занавес. В общем, работает мой plugin, реализующий пример расширения IDC script engine примерно так - Вы должны явно руками запустить его хотя бы один раз. После чего Вы можете использовать в своих IDC скриптах две новых встроенных функции с примерно следующими прототипами:

void rp1(char arg); void rp2(long, long);

написанных на C++ и реализуемых функциями RP_IDC_Ext & RP_IDC_Ext2

соответственно. Ничего сногсшибательно полезного они не делают (хотя и могли бы :-) - в общем, если интересно, см. исходник моего pluginа в файле idc_ext.cpp.


Содержание раздела