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



         

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


Однако ситуация, рассмотренная выше, достаточно идеализирована, и в реальных программах передача одних лишь непосредственных значений встречается редко. Давайте же теперь, освоившись с быстрыми вызовами, дизассемблируем более трудный пример:

#if defined(__BORLANDC__) || defined (_MSC_VER)

__fastcall

#endif

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

{

#if defined(__WATCOMC__)

#pragma aux MyFunc parm [EAX] [EBX] [ECX];

#endif

return a+b[0]+c;

}

main()

{

int a=2;

printf("%x\n",MyFunc(strlen("1"),&a,strlen("333")));

}

Листинг 74 Трудный пример с fastcall

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

main         proc near           ; CODE XREF: start+AFp

var_4        = dword      ptr -4

push   ebp

mov    ebp, esp

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

push   ecx

push   esi

; Сохраняем регистры в стеке

mov    [ebp+var_4], 2

; Присваиваем локальной переменной var_4 типа int

значение 2.

; Тип определяется на основе того, что переменная занимает 4 байта

; (подробнее см. "Идентификация локальных стековых переменных")

push   offset a333  ; const      char *

; Передаем функции strlen указатель на строку "333".

; Аргументы функции MyFunc как и положено передаются справа налево

call   _strlen

add    esp, 4

push   eax

; Здесь – либо мы сохраняем возвращенное функцией значение в стеке,

; либо передаем его следующей функции.

lea    esi, [ebp+var_4]

; В ESI заносим указатель на локальную переменную var_4

push   offset a1    ; const      char *

; Передаем функции strlen указатель на строку "1"

call   _strlen

add    esp, 4

mov    cl, al

; Возвращенное значение копируется в регистр CL, а ниже инициализируется EDX.

; Поскольку, ECX:EDX

используются для передачи аргументов fastcall-функциям,

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

; Можно предположить, что через CL




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