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


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


MSG msg;

 

// Устанавливаем таймер, передавая ему адрес процедуры TimerProc

SetTimer(0,0,1000,TimerProc);

 

// Цикл выборки сообщений. Когда надоест – жмем Ctrl-Break и прерываем его

while (GetMessage(&msg, (HWND) NULL, 0, 0))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

}

 

Листинг 66 Пример, демонстрирующий тот случай, когда требуется точно отличать PASCAL от stdcall

 

Откомпилируем этот пример так: "cl pascal.callback.c USER32.lib" и посмотрим, что из этого получилось:

 

main         proc near           ; CODE XREF: start+AFp

; На сей раз IDA не определила прототип функции. Ну и ладно...

 

Msg          = MSG ptr -20h

; IDA

распознала одну локальную переменную и даже восстановила ее тип, что радует

 

push   ebp

mov    ebp, esp

sub    esp, 20h

 

push   offset TimerProc ; lpTimerFunc

; Передаем указатель на функцию TimerProc

 

push   1000         ; uElapse

; Передаем время задержки таймера

 

push   0            ; nIDEvent

; В консольных приложениях аргумент nIDEvent

всегда игнорируется

 

push   0            ; hWnd

; Окон нет, передаем NULL

 

call   ds:SetTimer

; Win32 API

функции вызываются по соглашению stdcall

– это дает возможность,

; зная их прототип,(а он описан в SDK) восстановить тип и назначение аргументов

; в данном случае исходный текст выглядел так:

; SetTimer(NULL, BULL, 1000, TimerProc);

 

loc_401051:                       ; CODE XREF: main+42j

push   0            ; wMsgFilterMax

; NULL – нет

фильтра

 

push   0            ; wMsgFilterMin

; NULL – нет

фильтра

 

push   0            ; hWnd

; NULL

– нет окон в консольном приложении

 

lea    eax, [ebp+Msg]

; Получаем указатель на локальную переменную msg

-

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

; функции GetMessageA

 

push   eax          ; lpMsg

; Передаем указатель на msg

 

call   ds:GetMessageA




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