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



         

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


; функции передается именно char, а не int.

; Попутно отметим глупость компилятора – стоило ли передавать аргументы через

; регистры, чтобы тут же заслать их в локальные переменные!

; Ведь обращение к памяти сжирает всю выгоду от быстрого вызова!

; Такой "быстрый" вызов быстрым даже язык не поворачивается назвать.

movsx  eax, [ebp+var_4]

; В EAX загружается первый слева аргумент, переданный через CL, типа char

; со знаковым расширением до двойного слова. Значит, это signed char

; (т.е. char по умолчанию для Microsoft Visual C++)

add    eax, [ebp+var_8]

; Складываем EAX со вторым слева аргументом

add    eax, [ebp+arg_0]

; Складываем результат предыдущего сложения с третьим слева аргументом,

; переданным через стек…

add    eax, [ebp+arg_4]

; …и все это складываем с четвертым аргументом, так же переданным через стек.

mov    esp, ebp

pop    ebp

; Закрываем кадр стека

retn   8

; Чистим за собой стек, как и положено по fastcall

соглашению

MyFunc       endp

Листинг 71

А теперь сравним это с результатом компиляции Borland C++:

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

_main        proc near           ; DATA XREF: DATA:00407044o

argc         = dword      ptr  8

argv         = dword      ptr  0Ch

envp          = dword      ptr  10h

push   ebp

mov    ebp, esp

push   4

; Передаем аргумент через стек. Скосив глаза вниз, мы обнаруживаем явную

; инициализацию регистров ECX, EDX, AL. Для четвертого аргумента регистров

; не хватило и его пришлось передавать через стек. Значит, четвертый слева

; аргумент функции – 0x4

mov    ecx, 3

mov    edx, 2

mov    al,  1

; Этот код не может быть ничем иным, как передачей аргументов через регистры

call   MyFunc

push   eax

push   offset unk_407074 ; format

call   _printf

add    esp, 8

xor    eax, eax

pop    ebp

retn

_main        endp




Содержание  Назад  Вперед