- 论坛徽章:
- 11
|
&pid了解一下栈的布局? 我不了解我能写出那些代码吗?
anchor不是必须的? 你看明白它的作用以及为什么需 ...
OwnWaterloo 发表于 2010-01-30 15:57 ![]()
恩, 经检验, 有道理,
0x0040135e <begin_hack+0>: push %ebp
0x0040135f <begin_hack+1>: mov %esp,%ebp
0x00401361 <begin_hack+3>: sub $0x18,%esp --- 注意这一句
0x00401364 <begin_hack+6>: call 0x40133c <hack>
0x00401369 <begin_hack+11>: lea -0x4(%ebp),%eax
0x0040136c <begin_hack+14>: add $0x8,%eax
0x0040136f <begin_hack+17>: lea -0x4(%ebp),%edx
0x00401372 <begin_hack+20>: sub $0x4,%edx
0x00401375 <begin_hack+23>: mov (%edx),%edx
0x00401377 <begin_hack+25>: mov %edx,(%eax)
0x00401379 <begin_hack+27>: leave
0x0040137a <begin_hack+28>: ret
所以, 在gcc下是这样的
return addr
ebp
int a
int b
...
padding
...
return addr
ebp
int c
int d
所以以下代码能够正常退出
- 1 #include <stdio.h>
- 2
- 3
- 4 void hack(){
- 5 fprintf(stderr, "hack\n");
- 6 }
- 7
- 8 void begin_hack(){
- 9 int addr;
- 10
- 11 hack();
- 12
- 13 [color=Red] *(&addr + 2) = *(&addr - 1);[/color] // 如果没有padding, 那么这里将会破坏 f 函数中压栈的 ebp, 肯定会crash
- 14 }
- 15
- 16 void f()
- 17 {
- 18 int i = *(&i + 2);
- 19 *(&i + 2) = (int)((int *) begin_hack);
- 20 }
- 21
- 22 void test()
- 23 {
- 24 int i = 0;
- 25
- 26 f();
- 27
- 28 fprintf(stderr, "returned\n");
- 29 }
- 30
- 31 int main(int a, char** b)
- 32 {
- 33 test();
- 34 return 0;
- 35 }
- 36
- ~
复制代码 |
|