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



         

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


передается крайний левый аргумент типа char

mov    edx, esi

; В ESI содержится указатель на var_4, следовательно, второй аргумент функции,

; типа int, заносимый в EDX, передается по ссылке.

call   MyFunc

; Предварительный прототип функции выглядит так:

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

; Откуда взялся аргумент с? А помните, выше в стек был затолкнут EAX

и

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

; убедится в этом окончательно, требуется посмотреть сколько байт со стека

; снимает вызываемая функция

; Обратите так же внимание и на то, что значения, возвращенные функцией strlen,

; не заносилось в локальные переменные, а передавались непосредственно MyFunc.

; Это наводит на мысль, что исходный код программы выглядел так:

; MyFunc(strlen("1"),&var_4,strlen("333"));

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

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

; во-первых, судя по коду вызываемой функции компилятор работает без

; оптимизации, а во-вторых, если значения, возвращенные функциями strlen,

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

; их в локальную переменную – большая глупость, только затуманивающая суть

; программы. Тем более, что исследователю важно не восстановить подлинный

; исходный код, а понять его алгоритм.

push   eax

push   offset asc_406038 ; "%x\n"

call   _printf

add    esp, 8

pop    esi

mov    esp, ebp

pop    ebp

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

retn

main         endp

MyFunc       proc near           ; CODE XREF: main+2Ep

var_8        = dword      ptr -8

var_4        = byte ptr -4

arg_0        = dword      ptr  8

; Функция принимает один аргумент – значит, это и есть тот EAX, занесенный в стек

push   ebp

mov    ebp, esp

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

sub    esp, 8

; Резервируем восемь байт под локальные переменные




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