1 | -g 产生调试信息 |
objdump
1 | objdump -D -M intel file.bin | grep main.: -A20 |
Mac OS X 上 objdump
二进制文件实际上可能是指向llvm的 objdump 的链接,具有不同的命令行选项和行为。比如在我的Mac上’/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/objdump’
所以例子的 -M intel 无效
1 | -d |
国际惯例,先来感受 hello world
1 | // hello.c |
gcc -g -c hello.c
生成hello.o
1 | ➜ hello objdump --source --x86-asm-syntax=intel hello.o |
下面开始 通过一个例子函数调用
add.c
1 | // add.c |
gcc -g -c add.c
得到add.o
objdump --source --x86-asm-syntax=intel add.o
得到反汇编Intel 格式
1 | add.o: file format Mach-O 64-bit x86-64 |
objdump --source add.o
得到AT&T格式
1 | add.o: file format Mach-O 64-bit x86-64 |
Mac电脑,就以AT&T为例了
热身准备
操作码 | 操作数 | 功能 |
---|---|---|
mov | A, B | 把B的值赋给A |
and | A, B | 把A的值与B的值相加,结果赋给A |
push | A | 把A的值存储在栈中 |
pop | A | 从栈中读取值,并将其赋给A |
call | A | 调用函数 |
ret | 无 | 将返回到函数的调用源 |
字节序
大端法:最高有效位在最前面
小端法:最低有效位在最前面
内存地址是一致的,不同的是从高还是低位开始‘装入’
下面举例,一个int(32位)类型变量,位于地址0x100处,十六进制值为0x01234567.地址范围0x100~0x·03的字节顺序依赖于机器的类型:
0x100 | 0x101 | 0x102 | 0x103 | |
---|---|---|---|---|
大端法 | 01 | 23 | 45 | 67 |
小端法 | 67 | 45 | 23 | 01 |
通常
Intel机使用小端模式
ARM 可以按照大端法或小端法,一旦选定了也就固定下来了。我们熟知的移动操作系统Android和iOS运行小端模式
程序运行时,会在内存上申请栈空间。存储顺序为LIFO。对栈进行读写的内存地址是由esp进行管理的。push和pop指令运行后,esp的值会自动进行更新
Hopper
ida64
参考资料
https://wiki.cdot.senecacollege.ca/wiki/X86_64_Register_and_Instruction_Quick_Start