Фундаментальные основы хакерства


Идентификация аргументов функций - часть 19


#include <string.h>

 

// Внимание! Microsoft Visual C++ уже не поддерживает тип вызова PASCAL

// вместо этого используйте аналогичный ему тип вызова WINAPI, определенный в файле

// <windows.h>.

#if defined(_MSC_VER)

#include <windows.h>

// включать windows.h только если мы компилируется Microsoft Visual C++

// для остальных компиляторов более эффективное решение – использование ключевого

// слова PASACAL, если они, конечно, его поддерживают. (Borland

поддерживает)

#endif

 

 

// Подобный примем программирования может и делает листинг менее читабельным,

// но зато позволяет компилировать его не только одним компилятором!

#if defined(_MSC_VER)

WINAPI

#else

__pascal

#endif

 

MyFunc(int a, int b, char *c)

{

return a+b+strlen(c);

}

 

main()

{

printf("%x\n",MyFunc(0x666,0x777,"Hello,World!"));

}

Листинг 64 Демонстрация вызова PASCAL

 

Результат компиляции Borland C++ должен выглядеть так:

 

; int __cdecl main(int argc,const char **argv,const char *envp)

_main        proc near           ; DATA XREF: DATA:00407044o

 

push   ebp

mov    ebp, esp

 

push   666h         ; int

push   777h         ; int

push   offset aHelloWorld ; s

; Передаем функции аргументы. Заглянув в исходный текст, мы заметим, что

; аргументы передаются слева направо. Однако если исходных текстов нет,

; установить этот факт невозможно! К счастью, подлинный прототип функции

; не важен.

 

call   MyFunc

; Функция не вычищает за собой стек! Если это не результат оптимизации –

; ее тип вызова либо PASCAL, либо stdcall. Ввиду того, что PASACAL уже вышел

; из употребления, будем считать, что имеем дело с stdcall

 

push   eax

push   offset unk_407074 ; format

call   _printf

add    esp, 8

 

xor    eax, eax

pop    ebp

retn

_main        endp

 

; int __cdecl MyFunc(const char   *s,int,int)

; Ага! IDA вновь дала неправильный результат! Тип вызова явно не cdecl!




- Начало -  - Назад -  - Вперед -



Книжный магазин