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


Идентификация аргументов функций - часть 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




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



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