0

我刚刚开始学习逆向工程(自学)。我知道组装到一些可以理解的程度。反汇编 C 代码后弹出的基本指令对我来说几乎是可以理解的(比如每条指令的含义)。既然开始了,有人可能会觉得这些问题很愚蠢,请推荐一些关于倒车基础知识的好电子书,这样我就可以停止问菜鸟问题了。好吧,查询是:- 这是一个简单的 C 代码

#include<stdio.h>
int main(void)
{
    printf("hello world");
}

然后是main的反汇编代码。

0x004013b0 <+0>:     push   %ebp                         //saves ebp to stack
0x004013b1 <+1>:     mov    %esp,%ebp                    //saves esp onto ebp
0x004013b3 <+3>:     and    $0xfffffff0,%esp             //alignong the stack
0x004013b6 <+6>:     sub    $0x10,%esp                   //creating 16 bytes on stack
0x004013b9 <+9>:     call   0x401980 <__main>            //main call
0x004013be <+14>:    movl   $0x403064,(%esp)             ?? what is it exactly doing??
0x004013c5 <+21>:    call   0x401bf0 <printf>            //print call
0x004013ca <+26>:    leave
0x004013cb <+27>:    ret

在这里我无法理解它在做什么(尽管 0x403064 中的内容似乎被复制到 esp 的堆栈中)- movl $0x403064,(%esp)

在这个汇编代码中,我需要知道“hello world”存储在哪里?另外,如果有人可以建议我一些好的阅读材料,以便从基础学习逆向。提前致谢。

4

1 回答 1

0

printf在这种情况下,它在堆栈上等待其参数。您的字符串存储在内存中的地址是$0x403064. 所以你可以看到说明

movl   $0x403064,(%esp)

将此地址复制到堆栈上(请注意 周围的大括号esp)。

老实说,这不是通常的方式。但是您的程序非常简单,因此编译器会进行一些微优化。这有助于跳过一些机器指令。通常,人们会使用某种指令的组合将地址复制到堆栈,然后在调用之后(在我们这里的lea调用约定中)通常使用指令来纠正之后的情况。pushcdecladdesp

编辑:

在使用 gdb 进行调试之后,我使用命令x/sb 0x403064在内存中显示字符串。

GNU gdb (GDB) 7.5
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-mingw32".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from d:\temp\C++11\test.exe...(no debugging symbols found)...don
e.
(gdb) start
Temporary breakpoint 1 at 0x4013b3
Starting program: d:\temp\C++11\test.exe
[New Thread 5348.0x16f4]

Temporary breakpoint 1, 0x004013b3 in main ()
(gdb) disassemble $eip
Dump of assembler code for function main:
   0x004013b0 <+0>:     push   %ebp
   0x004013b1 <+1>:     mov    %esp,%ebp
=> 0x004013b3 <+3>:     and    $0xfffffff0,%esp
   0x004013b6 <+6>:     sub    $0x10,%esp
   0x004013b9 <+9>:     call   0x401990 <__main>
   0x004013be <+14>:    movl   $0x403064,(%esp)
   0x004013c5 <+21>:    call   0x401c10 <printf>
   0x004013ca <+26>:    mov    $0x0,%eax
   0x004013cf <+31>:    leave
   0x004013d0 <+32>:    ret
   0x004013d1 <+33>:    nop
   0x004013d2 <+34>:    nop
   0x004013d3 <+35>:    nop
   0x004013d4 <+36>:    add    %al,(%eax)
   0x004013d6 <+38>:    add    %al,(%eax)
   0x004013d8 <+40>:    add    %al,(%eax)
   0x004013da <+42>:    add    %al,(%eax)
   0x004013dc <+44>:    add    %al,(%eax)
   0x004013de <+46>:    add    %al,(%eax)
End of assembler dump.
(gdb) x/sb 0x403064
0x403064 <_Jv_RegisterClasses+4206692>: "hello world"
(gdb) x/12xb 0x403064
0x403064 <_Jv_RegisterClasses+4206692>: 0x68    0x65    0x6c    0x6c    0x6f
0x20    0x77    0x6f
0x40306c <_Jv_RegisterClasses+4206700>: 0x72    0x6c    0x64    0x00
(gdb)
于 2012-11-07T05:57:47.807 回答