【问题标题】:Recognizing passed parameters in a CALL instruction using Ollydbg使用 Ollydbg 识别 CALL 指令中传递的参数
【发布时间】:2014-08-17 04:02:01
【问题描述】:

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

【问题讨论】:

    标签: ollydbg


    【解决方案1】:

    调用约定在任何编译器上都是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 /analyze 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;
    }
    

    以及main的相关反汇编

    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
    

    【讨论】:

    • 这是一个很好的答案!
    猜你喜欢
    • 1970-01-01
    • 2014-11-27
    • 1970-01-01
    • 2012-12-15
    • 2014-07-14
    • 1970-01-01
    • 1970-01-01
    • 2021-03-27
    • 2017-07-02
    相关资源
    最近更新 更多