2015-05-05 5 views
2

У меня есть три фрагмента кода ассемблера, и я должен определить правильное соглашение о вызове (CDECL, STDCALL, FASTCALL) для каждого фрагмента. Чтобы идентифицировать соглашение о вызовах, я искал очиститель стека, который является либо вызывающим, либо вызываемым. Но что, если я не могу найти код очистки, который, как я полагаю, выглядит как «добавить esp, 8». Я ошибаюсь в своем подходе. Должен ли я искать другие характеристики конференц-связи? Ниже приведены фрагменты кода.Как идентифицировать вызывающие соглашения в коде сборки

Фрагмент 1

push ebp 
mov ebp , esp 
sub esp , 0x8 
mov [ ebp-0x4 ] , eax 
mov [ ebp-0x8 ] , edx 
mov eax , [ ebp-0x8 ] 
mov edx , [ ebp-0x4 ] 
add edx , eax 
mov eax , ecx 
add eax , edx 
leave 
ret 

Фрагмент 2

push ebp 
mov ebp , esp 
mov eax , [ ebp+0xC] 
mov edx , [ ebp+0x8 ] 
add edx , eax 
mov eax , [ ebp+0x10 ] 
add eax , edx 
pop ebp 
ret 0xC 

Фрагмент 3

push ebp 
mov ebp , esp 
mov eax , [ ebp+0xC] 
mov edx , [ ebp+0x8 ] 
add edx , eax 
mov eax , [ ebp+0x10 ] 
add eax , edx 
pop ebp 
ret 
+0

WTB выделения для ассемблере на StackOverflow :( –

+0

'добавить особ ...' это не единственный способ, [RET работает] (HTTP://переполнение стека.com/questions/1396909/ret-retn-retf-how-to-use-them) – Diego

+0

поэтому в случае 'ret' обратный адрес выставляется из стека и помещается в' eip'. Так что до звонящего, чтобы очистить стек, не так ли? – Dennis1818

ответ

2

Первый фрагмент азЬсаЙ вызовы , поскольку процедура использует регистры (EAX, EDX) без присвоения значения к нему - это означает, что вызывающий абонент использовал регистры для передачи аргументов - как в линии

mov [ ebp-0x4 ] , eax 

второго фрагмента STDCALL соглашения о вызове, поскольку процедура чистила стек параметров

ret 0xC 

третьего фрагмента Cdecl соглашения о вызове, поскольку процедура заняла параметры из стек, но она не очищается стек от параметров

ret 

быстрые метки для каждого из них будет:

азЬсаИ: регистры использования вызывающего абонента для передачи первых двух аргументов.

stdcall: вызывающий должен очистить стопку.

cdecl: вызывающий должен очистить стек.

для получения дополнительной информации см вики

http://en.wikipedia.org/wiki/X86_calling_conventions

+0

Спасибо, ты мне очень помог. – Dennis1818

0

Поскольку обратный адрес находится в пути, типичный метод вызываемого абонента очистки является ret X инструкция (где X - количество байт аргументов удалять). Таким образом, ваш второй пример - очистка вызываемого абонента, т.е. stdcall.

Чтобы обнаружить fastcall, вам просто нужно найти регистры, которые используются без инициализации. Вы можете увидеть это в своем первом фрагменте: ни eax, ни edx не были инициализированы. Так вот fastcall.

Что остается должен быть cdecl, но, конечно, вы можете увидеть, что он обращается к аргументам выше обратного адреса, с помощью ebp+0x8 и ebp+0xC, и он не удаляет их.

+0

спасибо, очень ясно. Я был настолько сосредоточен на добавлении инструкции и забыл обо всем остальном. – Dennis1818