程序运行都要用到堆栈,由编译器自动分配、释放 ,用来存放函数的参数值、局部变量、返回值等。Intel指令用到的寄存器有ESP(RSP)、EBP(RBP);Arm指令是用R11(FP)、R13(SP)、或X29(FP)、X31(SP)。反汇编就是利用这些寄存器的值,画出程序的堆栈图。逆向时,画堆栈图是基本技能,掌握并不难。
源程序:
#include <stdio.h>
void max(int * a, int * b)
{
if (*a < *b)
*a = *b;
}
int main()
{
int a = 5, b = 6;
max(&a, &b);
printf("a, b max %d\n", a);
return 0;
}
反编译:
Dump of assembler code for function main:
0x0000555555555198 <+0>: endbr64
0x000055555555519c <+4>: push %rbp
0x000055555555519d <+5>: mov %rsp,%rbp
0x00005555555551a0 <+8>: sub $0x10,%rsp
0x00005555555551a4 <+12>: mov %fs:0x28,%rax
0x00005555555551ad <+21>: mov %rax,-0x8(%rbp)
0x00005555555551b1 <+25>: xor %eax,%eax
0x00005555555551b3 <+27>: movl $0x5,-0x10(%rbp)
0x00005555555551ba <+34>: movl $0x6,-0xc(%rbp)
0x00005555555551c1 <+41>: lea -0xc(%rbp),%rdx
0x00005555555551c5 <+45>: lea -0x10(%rbp),%rax
0x00005555555551c9 <+49>: mov %rdx,%rsi
0x00005555555551cc <+52>: mov %rax,%rdi
0x00005555555551cf <+55>: callq 0x555555555169 <max>
0x00005555555551d4 <+60>: mov -0x10(%rbp),%eax
0x00005555555551d7 <+63>: mov %eax,%esi
0x00005555555551d9 <+65>: lea 0xe24(%rip),%rdi # 0x555555556004
0x00005555555551e0 <+72>: mov $0x0,%eax
0x00005555555551e5 <+77>: callq 0x555555555070 <printf@plt>
0x00005555555551ea <+82>: mov $0x0,%eax
0x00005555555551ef <+87>: mov -0x8(%rbp),%rcx
0x00005555555551f3 <+91>: xor %fs:0x28,%rcx
0x00005555555551fc <+100>: je 0x555555555203 <main+107>
0x00005555555551fe <+102>: callq 0x555555555060 <__stack_chk_fail@plt>
0x0000555555555203 <+107>: leaveq
0x0000555555555204 <+108>: retq
End of assembler dump.
Dump of assembler code for function max:
0x0000555555555169 <+0>: endbr64
0x000055555555516d <+4>: push %rbp
0x000055555555516e <+5>: mov %rsp,%rbp
0x0000555555555171 <+8>: mov %rdi,-0x8(%rbp)
0x0000555555555175 <+12>: mov %rsi,-0x10(%rbp)
0x0000555555555179 <+16>: mov -0x8(%rbp),%rax
0x000055555555517d <+20>: mov (%rax),%edx
0x000055555555517f <+22>: mov -0x10(%rbp),%rax
0x0000555555555183 <+26>: mov (%rax),%eax
0x0000555555555185 <+28>: cmp %eax,%edx
0x0000555555555187 <+30>: jge 0x555555555195 <max+44>
0x0000555555555189 <+32>: mov -0x10(%rbp),%rax
0x000055555555518d <+36>: mov (%rax),%edx
0x000055555555518f <+38>: mov -0x8(%rbp),%rax
0x0000555555555193 <+42>: mov %edx,(%rax)
0x0000555555555195 <+44>: nop
0x0000555555555196 <+45>: pop %rbp
0x0000555555555197 <+46>: retq
End of assembler dump.