0x0804834d
0x08048350
0x08048353
0x08048354
0x08048356
0x08048357
0x0804835c
0x08048361
0x08048362
0x08048363
0x08048366
End of assembler dump.
(gdb) disassemble f
Dump of assembler code for function f:
0x08048344
0x08048345
0x08048347
0x08048348
End of assembler dump.
补充知识:
1)lea
mov是将数据从源操作传到目的操作数中
lea是将源操作数的地址传到目的操作数中
一个是数据,一个是地址
lea指令只有一个周期,某些编译器会使用lea来优化加法等操作
mov eax,[00400000]
传的是地址400000这个地址里的值,假设400000这个地址中的值是100,那么eax寄存器中的值就为100
lea eax,[00400000]
那么eax寄存器中的值就是400000
2) push src:
esp <- esp - 4
[esp] <- src
3) pop dest:
dest <- [esp]
esp <- esp + 4
4) leave:
mov esp, ebp
pop ebp
5) call src:
push eip
eip <- src;
6) ret:
pop eip
-------------------------
http://blog.chinaunix.net/u/26166/showart.php?id=198375 (zz)
栈从接近0xC0000000处开始并向下生长,代码从0x8000000处开始,而堆则如前所述扩展。
#include
void attack(){
int attack=1;
printf("hi,attacked!\n");
}
void yaya(){
int yaya=1;
printf("hi,yaya is my wife\n");
}
void foo(){
int ret=1;
*(&ret +2)=(int)attack;
}
void main(){
int i=5;
i=(int)yaya;
foo();
- gcc att.c -o att -g
- gdb ./ret
- list foo,as follow:
6 }
7 void yaya(){
8 int yaya=1;
9 printf("hi,yaya is my wife\n");
10 }
11 void foo(){
12 int ret=1;
13 *(&ret +2)=(int)attack;
14 }
15 void main(){
(gdb)
16 int i=5;
17 i=(int)yaya;
18 foo();
19
20 }(gdb)
- break 14
- run
(gdb) r
Starting program: /home/zswan/infect/stack/att
Reading symbols from shared object read from target memory...done.
Loaded system supplied DSO at 0x7b0000
Breakpoint 1, foo () at ret.c:14
14 }
(gdb) print &ret
$1 = (int *) 0xbfc11678
(gdb) print (&ret+2)
$2 = (int *) 0xbfc11680
(gdb) print /x *(&ret+2)
$3 = 0x8048384=============>这里便是调用函数的返回地址
(gdb)
Dump of assembler code for function attack
0x08048385
0x08048387
0x0804838a
0x08048391
0x08048398
0x0804839d
0x0804839e
End of assembler dump.
0x080483cf
0x080483d0
0x080483d2
0x080483d5
0x080483dc
0x080483e3
0x080483e8
0x080483e9
End of assembler dump.
0x080483b3
0x080483b4
0x080483b6
0x080483b9
0x080483c0
0x080483c3
0x080483c6
0x080483cb
0x080483cd
0x080483ce
End of assembler dump.
(gdb) 如果程序正常执行的话,返回后应该跑到正常返回地址,但是由于前面地址改成了attack的地址了,当main调用call后,堆栈的情况从高到低应该是:/返回地址/esp/变量i/返回地址0x080483e8。当执行foo的时候堆栈情况应该是:/返回地址0x08048384/esp/局部变量ret。foo完后,一系列出栈动作,这时候要注意,由于没有返回到正常的主函数中,所以主函数的局部变量i还没有弹出来。只是在出栈的时候把地址弹出返回到attack函数,那么在attack的时候堆栈如何呢?