我刚开始学习逆向工程(自学)。我知道装配达到一些可以理解的程度。拆解C代码后弹出的基本指令对我来说几乎是可以理解的(比如每条指令的含义)。从一开始,有人可能会觉得这些都是愚蠢的问题,并且可以提出一些关于倒车基础知识的好电子书,这样我就可以停止询问noob问题了。那么,查询是: - 这是一个简单的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”存储在哪里? 此外,如果有人可以建议我一些良好的读数,以学习从基础知识的逆转。提前谢谢。
答案 0 :(得分:0)
printf
在堆栈上等待其参数。字符串存储在内存中的地址为$0x403064
。所以你可以看到指令
movl $0x403064,(%esp)
将此地址复制到堆栈上(请注意esp
周围的大括号。)
老实说,这不是通常的做法。但是你的程序非常简单,因此编译器会做一些微优化。这有助于跳过一些机器指令。通常,会使用某种lea
和push
指令的组合将地址复制到堆栈中,然后在调用之后(在我们这里的cdecl
调用约定中)将它复制到堆栈中通常使用add
指令来纠正esp
之后。
编辑:
使用gdb调试sessien后,我使用命令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)