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



         

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


; предпочтений: EAX, EDX, ECX

можно сделать вывод, что в EAX

передается первый

; слева аргумент функции, а два остальных в EDX

и ECX

соответственно.

; Обратите внимание и на то, что Borland C++, в отличие от Microsoft Visual C++

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

; значение всех функций, "выдергивая" их справа налево, и только

; потом переходит к переменным и константам.

; И в этом есть свой здравый смысл – функции

; изменяют значение многих регистров общего назначения и, до тех пор пока не

; будет вызвана последняя функция, нельзя приступать к передаче аргументов

; через регистры.

push   eax

push   offset asc_407074 ; format

call   _printf

add    esp, 8

xor    eax, eax

; Возвращаем нулевое значение

pop    ecx

pop    ebp

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

retn

_main        endp

MyFunc       proc near           ; CODE XREF: _main+26p

push   ebp

mov    ebp, esp

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

movsx  eax, al

; Расширяем EAX до знакового двойного слова

mov    edx, [edx]

; Загружаем в EDX содержимое ячейки памяти, на которую указывает указатель EDX

add    eax, edx

; Складываем первый аргумент функции с переменной типа int, переданной

; вторым аргументом по ссылке

add    ecx, eax

; Складываем третий аргумент типа int

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

mov    eax, ecx

; Помещаем результат обратно в EAX

; Глупый компилятор, не проще ли было переставить местами аргументы предыдущей

; команды?

pop    ebp

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

retn

MyFunc       endp

Листинг 76

А теперь рассмотрим результат компиляции того же примера компилятором WATCOM C, у которого всегда есть чему поучиться:

main_        proc near           ; CODE XREF: __CMain+40p

var_C        = dword      ptr -0Ch

; Локальная переменная

push   18h

call   __CHK

; Проверка стека на переполнение

push   ebx

push   ecx




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