Это вызов указателя функции, хранящегося в структуре.
В этой первой строке указатель хранится по адресу DS:xxxxxxxx
. Квадратные скобки указывают разыменование адреса, очень похоже на *
в C. Значение из памяти собирается использоваться в качестве указателя; он помещается в регистр ecx
.
MOV ECX,DWORD PTR DS:[xxxxxxxx] ; xxxxxxxx is an address
Вторая строка разыменовывает указатель, полученный выше. Это значение из ecx
теперь используется как адрес, на который разыменовывается. Значение, найденное в памяти, является еще одним указателем. Этот второй указатель помещается в регистр edx
.
MOV EDX,DWORD PTR DS:[ECX]
Третья строка снова разыменовывает память; на этот раз доступ происходит по адресу смещение от указателя, полученного выше на 0x116 байтов. Это не делится поровну на четыре, поэтому указатель на эту функцию, похоже, не из таблицы C ++. Полученное из памяти значение в этот раз сохраняется в регистре eax
.
MOV EAX,DWORD PTR DS:[EDX+116]
Наконец, выполняется функция, на которую указывает eax
. Это просто вызывает функцию через указатель на функцию. Кажется, что функция принимает нулевые аргументы, но у меня есть вопрос о пересмотре моего ответа: есть ли PUSH
инструкция, предшествующая этому фрагменту? Это были бы аргументы функции. Знаки вопроса указывают на то, что эта функция может возвращать значение, которое мы не можем определить по нашему мнению.
CALL EAX
В целом, фрагмент кода выглядит как вызов функции расширения из библиотеки подключаемых модулей к OllyDbg. ABI OllyDbg определяет различные struct
, которые содержат некоторые указатели на функции. Существуют также массивы указателей на функции, но двойное косвенное обращение к указателю edx
(также смещение не выровнено по даже кратному) заставляет меня думать, что это struct
, а не массив указателей на функции или vtable класса C ++.
Другими словами, xxxxxxxx
- это указатель на указатель на struct
, содержащий указатель на функцию.
В исходном файле OllyDbg PlugIn.h есть некоторые подходящие определения struct
. Вот пример:
typedef struct t_sorted { // Descriptor of sorted table
char name[MAX_PATH]; // Name of table, as appears in error
int n; // Actual number of entries
int nmax; // Maximal number of entries
int selected; // Index of selected entry or -1
ulong seladdr; // Base address of selected entry
int itemsize; // Size of single entry
ulong version; // Unique version of table
void *data; // Entries, sorted by address
SORTFUNC *sortfunc; // Function which sorts data or NULL
DESTFUNC *destfunc; // Destructor function or NULL
int sort; // Sorting criterium (column)
int sorted; // Whether indexes are sorted
int *index; // Indexes, sorted by criterium
int suppresserr; // Suppress multiple overflow errors
} t_sorted;
Эти примеры могут быть NULL
, а ваш фрагмент asm не проверяет указатель NULL
в указателе функции. Следовательно, оно должно быть DRAWFUNC
из t_table
или SPECFUNC
из t_dump
.
Вы можете создать небольшой проект, который включает файл заголовка и использует printf()
и offsetof()
, чтобы определить, имеет ли какой-либо из них смещение 0x116.
В противном случае я представляю, что внутренности OllyDbg написаны в том же стиле. Таким образом, вероятно, существуют частные struct
определения (не опубликованные в файле Plugin.h), используемые для различных целей в OllyDbg.
Я хотел бы добавить, я думаю, это позор, что исходники OllyDbg не доступны. У меня сложилось впечатление, что статически связанный дизассемблер находится под какой-то лицензией GPL, но мне не повезло получить исходные коды для OllyDbg.