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


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


push   offset unk_420004

call   printf_

 

add    esp, 8

xor    eax, eax

pop    edi

pop    esi

pop    ebx

retn

main_        endp

 

 

MyFunc       proc near           ; CODE XREF: main_+21p

; Функция не принимает через стек ни одного аргумента

 

push   4

call   __CHK

 

and    eax, 0FFh

; Обнуление старших двадцати четырех бит вкупе с обращением к регистру

; до его инициализации наводит на мысль, что через EAX

передается тип char

; какой это аргумент мы сказать не можем, увы...

 

add    esi, eax

; Регистр ESI не был инициализирован нашей функцией, следовательно, через

; него передается аргумент типа int. Можно предположить, что это – второй

; слева аргумент в прототипе функции, т.к. (если ничто не препятствует),

; регистры в вызывающей функции инициализируются согласно их порядку

; перечисления в прототипе, считая справа, а выражения вычисляются

; слева направо.

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

; все-таки приятно, если удается его восстановить

 

lea    eax, [esi+edi]

; Опаньки, выдерем Тигре хвост с корнем! Вы думаете, что в EAX

загружается

; указатель? А ESI и EDI переданные функции – так же указатели? EAX

с его

; типом char становится очень похожим на индекс...

; Увы! Компилятор WATCOM слишком хитер и при анализе программ,

; скомпилированных с его помощью, очень легко впасть в грубые ошибки.

; Да, EAX это указатель, в том смысле, что LEA

используется для вычисления

; суммы ESI и EDI, но обращения к памяти по этому указателю не происходит

; ни в вызывающей, ни в вызываемой функции. Следовательно, аргументы функции

; не указатели, а константы!

 

add    eax, ebx

; Аналогично – EDX содержит в себе аргумент, переданный функции.

; Итак, прототип функции должен быть выглядеть так:

; MyFunc(char a, int b, int c, int d)

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

 

retn

MyFunc       endp

Листинг 73

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


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