反汇编问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了反汇编问题相关的知识,希望对你有一定的参考价值。

mov eax,dword ptr【esp+8】
mov ebx,dword ptr【esp+10h】
mov ecx,dword ptr【esp+14h】
mov edx,dword ptr【esp+18h】
这四个到底哪个是第一个参数,哪个是第二个参数,哪个是第三个,第四个参数,原因

【esp+8】有可能是第一个参数,也可能是第二个参数,也有可能不是参数。确定【esp+8】是第一个参数还是第二个参数,取决于第一个mov 指令之前是否有push指令。
由于你给的信息不完整,所以这有几种可能。
===================================================================
首先你应该明白,0+4=4,4+4=8,8+4=0ch,0ch+4=10h,10h+4=14h,14h+4=18h
其次,你应该明白堆栈向低地址增长
===================================================================
第一种:假设第一个mov之前有一个push指令
——————+
push的数值 <-当前esp所指向的地方
——————+
esp+4 <-这里是函数的返回地址
——————+
esp+8 <-这里是第一个参数
——————+
esp+0ch <-这里是第二个参数
——————+
esp+10h <-这里是第三个参数
——————+
esp+14h <-这里是第四个参数
——————+
esp+18h <-这里是第五个参数
——————+
=============================================================
第二种情况,第一个mov之前如果没有push
——————+
esp <-当前esp所指向的地方,即函数的返回地址
——————+
esp+4 <-这里是第一个参数
——————+
esp+8 <-这里是第二个参数
——————+
esp+0ch <-这里是第三个参数
——————+
esp+10h <-这里是第四个参数
——————+
esp+14h <-这里是第五个参数
——————+
esp+18h <-这里是第六个参数
——————+
=================================================================
更多的可能,如果第一个mov指令之前有两个push 的话,很显然,【esp+8】就不是参数,而是返回地址,如果mov之前有更多push,就是依次类推,要取到参数esp加的值就会越大
参考技术A 你应该从原理上来理解,高级语言有两种入栈形式,从左至右,从右至左。

带注释的可执行文件反汇编

【中文标题】带注释的可执行文件反汇编【英文标题】:Annotated disassembly of executable 【发布时间】:2014-08-05 13:45:48 【问题描述】:

将 C 程序编译为目标文件时,很容易让 Microsoft 编译器使用 cl /Fa 为您提供带注释的反汇编(带有函数和变量的名称、源代码行号等)。

我试图从最终链接的可执行文件中获得类似的东西(假设程序是使用适当的调试信息编译的),这似乎更棘手; dumpbinobjdump 似乎只提供无注释的反汇编。

获得这个的最好方法是什么?

【问题讨论】:

【参考方案1】:

如果你有使用 debuginfo 编译的程序,windbg 应该提供带有行号的函数的反汇编

使用调试信息编译的示例代码和使用 /Fa 生成的程序集文件

C:\codesnips\comparesrc\debug>cl /Zi /Fa comparesrc.cpp /link /Debug

comparesrc.cpp

/out:comparesrc.exe
/debug
/Debug
comparesrc.obj

以上编译的源码

C:\codesnips\comparesrc\debug>type comparesrc.cpp
#include <stdio.h>  // standard include file
int main (void)
 // this line will become prolog
    printf("hello my dear source compare\n");  // see str in .data section
    puts("c");  // will put a char* with line break to console
    puts("om");
    puts("pare");
    int a,b,c,d;
    a = 2; b =3 ; c = 4;
    d = a+b-c;    // 2+3 -4 = 1
    printf("%d\n",d);  // should print 1
    d = (a*b)/c;  // 2*3 /4 = 6 /4  numerator = 1
    printf("%d\n",d);  // should printf 1
    d = (a*b)%c;   // 2 * 3 % 4 denominator = 2
    printf("%d\n",d);  // should print 2
    return 0;   // lets generate a cod file and see the assembly
   // this line will get converted to epilog

/Fa 开关创建的汇编文件

C:\codesnips\comparesrc\debug>type comparesrc.asm
; Listing generated by Microsoft (R) Optimizing Compiler Version 16.00.30319.01


        TITLE   C:\codesnips\comparesrc\debug\comparesrc.cpp
        .686P
        .XMM
        include listing.inc
        .model  flat

INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES

CONST   SEGMENT
$SG3850 DB      'hello my dear source compare', 0aH, 00H
        ORG $+2
$SG3851 DB      'c', 00H
        ORG $+2
$SG3852 DB      'om', 00H
        ORG $+1
$SG3853 DB      'pare', 00H
        ORG $+3
$SG3858 DB      '%d', 0aH, 00H
$SG3859 DB      '%d', 0aH, 00H
$SG3860 DB      '%d', 0aH, 00H
CONST   ENDS
PUBLIC  _main
EXTRN   _puts:PROC
EXTRN   _printf:PROC
; Function compile flags: /Odtp
_TEXT   SEGMENT
_c$ = -16                                               ; size = 4
_d$ = -12                                               ; size = 4
_b$ = -8                                                ; size = 4
_a$ = -4                                                ; size = 4
_main   PROC
; File c:\codesnips\comparesrc\debug\comparesrc.cpp
; Line 3
        push    ebp
        mov     ebp, esp
        sub     esp, 16                                 ; 00000010H
; Line 4
        push    OFFSET $SG3850
        call    _printf
        add     esp, 4
; Line 5
        push    OFFSET $SG3851
        call    _puts
        add     esp, 4
; Line 6
        push    OFFSET $SG3852
        call    _puts
        add     esp, 4
; Line 7
        push    OFFSET $SG3853
        call    _puts
        add     esp, 4
; Line 9
        mov     DWORD PTR _a$[ebp], 2
        mov     DWORD PTR _b$[ebp], 3
        mov     DWORD PTR _c$[ebp], 4
; Line 10
        mov     eax, DWORD PTR _a$[ebp]
        add     eax, DWORD PTR _b$[ebp]
        sub     eax, DWORD PTR _c$[ebp]
        mov     DWORD PTR _d$[ebp], eax
; Line 11
        mov     ecx, DWORD PTR _d$[ebp]
        push    ecx
        push    OFFSET $SG3858
        call    _printf
        add     esp, 8
; Line 12
        mov     eax, DWORD PTR _a$[ebp]
        imul    eax, DWORD PTR _b$[ebp]
        cdq
        idiv    DWORD PTR _c$[ebp]
        mov     DWORD PTR _d$[ebp], eax
; Line 13
        mov     edx, DWORD PTR _d$[ebp]
        push    edx
        push    OFFSET $SG3859
        call    _printf
        add     esp, 8
; Line 14
        mov     eax, DWORD PTR _a$[ebp]
        imul    eax, DWORD PTR _b$[ebp]
        cdq
        idiv    DWORD PTR _c$[ebp]
        mov     DWORD PTR _d$[ebp], edx
; Line 15
        mov     eax, DWORD PTR _d$[ebp]
        push    eax
        push    OFFSET $SG3860
        call    _printf
        add     esp, 8
; Line 16
        xor     eax, eax
; Line 17
        mov     esp, ebp
        pop     ebp
        ret     0
_main   ENDP
_TEXT   ENDS
END

最后使用 cdb(windbg 的控制台版本)反汇编完整的 main 函数

cdb -c ".lines;g main;uf @eip;q;"比较rc.exe

Microsoft (R) Windows Debugger Version 6.12.0002.633 X86    
CommandLine: comparesrc.exe    
0:000> cdb: Reading initial command '.lines;g main;uf @eip;q;'    
Line number information will be loaded
comparesrc!main [c:\codesnips\comparesrc\debug\comparesrc.cpp @ 3]:
    3 00401010 55              push    ebp
    3 00401011 8bec            mov     ebp,esp
    3 00401013 83ec10          sub     esp,10h
    4 00401016 685c8c4100      push    offset comparesrc!__xt_z+0x120 (00418c5c)

    4 0040101b e81b020000      call    comparesrc!printf (0040123b)
    4 00401020 83c404          add     esp,4
    5 00401023 687c8c4100      push    offset comparesrc!__xt_z+0x140 (00418c7c)

    5 00401028 e8bf000000      call    comparesrc!puts (004010ec)
    5 0040102d 83c404          add     esp,4
    6 00401030 68808c4100      push    offset comparesrc!__xt_z+0x144 (00418c80)

    6 00401035 e8b2000000      call    comparesrc!puts (004010ec)
    6 0040103a 83c404          add     esp,4
    7 0040103d 68848c4100      push    offset comparesrc!__xt_z+0x148 (00418c84)

    7 00401042 e8a5000000      call    comparesrc!puts (004010ec)
    7 00401047 83c404          add     esp,4
    9 0040104a c745fc02000000  mov     dword ptr [ebp-4],2
    9 00401051 c745f803000000  mov     dword ptr [ebp-8],3
    9 00401058 c745f004000000  mov     dword ptr [ebp-10h],4
   10 0040105f 8b45fc          mov     eax,dword ptr [ebp-4]
   10 00401062 0345f8          add     eax,dword ptr [ebp-8]
   10 00401065 2b45f0          sub     eax,dword ptr [ebp-10h]
   10 00401068 8945f4          mov     dword ptr [ebp-0Ch],eax
   11 0040106b 8b4df4          mov     ecx,dword ptr [ebp-0Ch]
   11 0040106e 51              push    ecx
   11 0040106f 688c8c4100      push    offset comparesrc!__xt_z+0x150 (00418c8c)

   11 00401074 e8c2010000      call    comparesrc!printf (0040123b)
   11 00401079 83c408          add     esp,8
   12 0040107c 8b45fc          mov     eax,dword ptr [ebp-4]
   12 0040107f 0faf45f8        imul    eax,dword ptr [ebp-8]
   12 00401083 99              cdq
   12 00401084 f77df0          idiv    eax,dword ptr [ebp-10h]
   12 00401087 8945f4          mov     dword ptr [ebp-0Ch],eax
   13 0040108a 8b55f4          mov     edx,dword ptr [ebp-0Ch]
   13 0040108d 52              push    edx
   13 0040108e 68908c4100      push    offset comparesrc!__xt_z+0x154 (00418c90)

   13 00401093 e8a3010000      call    comparesrc!printf (0040123b)
   13 00401098 83c408          add     esp,8
   14 0040109b 8b45fc          mov     eax,dword ptr [ebp-4]
   14 0040109e 0faf45f8        imul    eax,dword ptr [ebp-8]
   14 004010a2 99              cdq
   14 004010a3 f77df0          idiv    eax,dword ptr [ebp-10h]
   14 004010a6 8955f4          mov     dword ptr [ebp-0Ch],edx
   15 004010a9 8b45f4          mov     eax,dword ptr [ebp-0Ch]
   15 004010ac 50              push    eax
   15 004010ad 68948c4100      push    offset comparesrc!__xt_z+0x158 (00418c94)

   15 004010b2 e884010000      call    comparesrc!printf (0040123b)
   15 004010b7 83c408          add     esp,8
   16 004010ba 33c0            xor     eax,eax
   17 004010bc 8be5            mov     esp,ebp
   17 004010be 5d              pop     ebp
   17 004010bf c3              ret

【讨论】:

【参考方案2】:

你可以使用

Windbg -z <any image> 

对该图像执行反汇编或任何检查(也可与 cdb \ kd 一起使用)。 您无需实际运行程序即可查看源代码行、符号、类型。

这对于查看 DLL 很有用,但当您想要查看为其他体系结构或无法在您的机器上运行的设备驱动程序编译的代码时非常必要。

例如

cdb -z ntoskrnl.exe

将让您检查 Windows 内核的代码。

这比故障转储更强大,因为您不仅可以看到分页的代码 - 您还可以看到 所有 .exe 中的代码

【讨论】:

以上是关于反汇编问题的主要内容,如果未能解决你的问题,请参考以下文章

什么是反汇编?

反编译和反汇编有啥区别?

反汇编工具objdump的使用以及反汇编文件的解读

C++反汇编与逆向分析技术揭秘的目录

IDA反汇编工具的使用详解

汇编数据段地址问题 看我的源代码,从反汇编的代码中可以看到段地址DS应该为075A 但是D命令查看的结果不是