使用Ollydbg识别CALL指令中的传递参数

时间:2014-06-26 10:31:41

标签: ollydbg

汇编中使用的调用约定因编译器而异。问题是: ollydbg2.01如何帮助我识别从调用者传递给被调用者的参数以及从被调用者返回给调用者的值以获得CALL指令。 我正在处理的程序集是由Microsoft Visual C ++编译的。

1 个答案:

答案 0 :(得分:2)

任何编译器的调用约定都是not dependent

通过default microsoft visual studio使用__cdecl(用户必须清理堆栈)

您可以强制它使用__stdcall(被称为函数负责清理堆栈)

您也可以使用__declspec (naked)(任意清理)

进行编译

Afaik x64仅限FASTCALL(不适用其他调用约定)

您可以通过查看程序集来识别调用约定

如果你观察

call xxxx
add esp,XXXXX 
it most likely is __cdecl

如果你观察

call xxxx
inside the call 
leave 
retn XXX then it is likely to be __stdcall

等等

您可能需要通过观察反汇编来识别特定构造,并使用调用约定来对其进行核心化

调用约定也可以任意混合,因此您可能需要单独确定每个函数调用

用cl / Zi / nologo / W4编译/分析xxx.cpp / link / RELEASE

#include <stdio.h>
char *domain = "i am calling me" , *formatstr = "%s %s\n";
void __cdecl cdecprint (char *king) {
    printf(formatstr,domain,king);
}
void __stdcall stdprint (char *king) {
    printf(formatstr,domain,king);
}
void __fastcall fastprint (char *king) {
    printf(formatstr,domain,king);
}
__declspec(naked) void arbitprint (char *king) {
    (void)king; //unreferenced warning 
    __asm    {
        lea eax, [esp+4]
        push [eax]
        push domain
            push formatstr
            call printf
            add esp,0Ch
            retn
    }
}
int main (void) {
    cdecprint("cdecinking");
    stdprint("stdking");
    fastprint("fastking");
    arbitprint("arbitking");
    return 0x1337;
}

和主要的相关反汇编

004010A0 callme.main PUSH    EBP                     ; {
004010A1             MOV     EBP, ESP
004010A3             PUSH    callme.004121A4     ; cdecprint("cdecinking");
004010A8             CALL    callme.cdecprint
004010AD             ADD     ESP, 4  <---------- ; call above is likely __cdecl
004010B0             PUSH    callme.004121B0     ; stdprint("stdking");
004010B5             CALL    callme.stdprint  <--; no cleanup likely __stdcall
004010BA             MOV     ECX, callme.004121B8; fastprint("fastking"); 
004010BF             CALL    callme.fastprint <--; __stdcall ? No __fastcall 
004010C4             PUSH    callme.004121C4     ; arbitprint("arbitking");
004010C9             CALL    callme.arbitprint   ;
004010CE             ADD     ESP, 4  <---------  ; __cdecl? No __declspec (naked)
004010D1             MOV     EAX, 1337           ; return 0x1337;
004010D6             POP     EBP                 ; }
004010D7             RETN

<强> __ CDECL

00401000 callme.cdecprint  PUSH    EBP
00401001                   MOV     EBP, ESP
00401003                   MOV     EAX, DWORD PTR SS:[EBP+8]
00401006                   PUSH    EAX
00401007                   MOV     ECX, DWORD PTR DS:[domain]
0040100D                   PUSH    ECX
0040100E                   MOV     EDX, DWORD PTR DS:[formatstr]
00401014                   PUSH    EDX
00401015                   CALL    callme.printf
0040101A                   ADD     ESP, 0C
0040101D                   POP     EBP
0040101E                   RETN

<强> __ STDCALL

00401020 callme.stdprint   PUSH    EBP
00401021                   MOV     EBP, ESP
00401023                   MOV     EAX, DWORD PTR SS:[EBP+8]
00401026                   PUSH    EAX
00401027                   MOV     ECX, DWORD PTR DS:[domain]
0040102D                   PUSH    ECX
0040102E                   MOV     EDX, DWORD PTR DS:[formatstr]
00401034                   PUSH    EDX
00401035                   CALL    callme.printf
0040103A                   ADD     ESP, 0C
0040103D                   POP     EBP
0040103E                   RETN    4

<强> __ FASTCALL

00401050 callme.fastprint  PUSH    EBP     
00401051                   MOV     EBP, ESP
00401053                   PUSH    ECX
00401054                   MOV     DWORD PTR SS:[EBP-4], ECX
00401057                   MOV     EAX, DWORD PTR SS:[EBP-4]
0040105A                   PUSH    EAX
0040105B                   MOV     ECX, DWORD PTR DS:[domain]
00401061                   PUSH    ECX
00401062                   MOV     EDX, DWORD PTR DS:[formatstr]
00401068                   PUSH    EDX
00401069                   CALL    callme.printf
0040106E                   ADD     ESP, 0C
00401071                   MOV     ESP, EBP
00401073                   POP     EBP
00401074                   RETN

__ declspec(裸体)

00401080 callme.arbitprint LEA     EAX, DWORD PTR SS:[ESP+4]
00401084                   PUSH    DWORD PTR DS:[EAX]
00401086                   PUSH    DWORD PTR DS:[domain]
0040108C                   PUSH    DWORD PTR DS:[formatstr]
00401092                   CALL    callme.printf
00401097                   ADD     ESP, 0C
0040109A                   RETN

除了上面的4之外,还有一些专门的调用约定 和过时的调用约定

__clrcall is for managed 
__vectorcall is for using streaming instructions (sse 2 .....)
__thiscall used mostly oop and com methods
__pascal etc obsolete