直接修改栈的实例

栈溢出与动态库符号解析
本文通过一个具体的C语言程序示例介绍了如何利用栈溢出来修改内存内容,并解释了32位x86架构下动态链接库中函数调用的工作原理。深入探讨了通过修改栈内容来实现特定函数调用的技术细节。
1 [bobo]$catgotover.c
2 #include<stdio.h>
3 #include<string.h>
4
5 intevil_code(char*s)
6 {
7 printf("hi,Iamhere!\n");
8 return0;
9 }
10
11 intmain(intargc,char*argv[])
12 {
13 longaddr=*(long*)((long)strlen+2);
14
15 *(long*)addr=(long)evil_code;
16
17 intlen=strlen(argv[0]);
18
19 printf("len=[%d]\n",len);
20
21 return0;
22 }
23
24 [bobo]$gccgotover.c-ogotover
25 [bobo]$./gotover
26 hi,Iamhere!
27 len=[0]

看了这篇帖子,理解了上面这段程序,直接修改栈内容。

详细内容可以参考 , 还有一篇alert7写的动态库符号解析过程
大概是这样的:
对于32位的x86,调用动态库中的函数,比如 printf(); 调用的其实是plt中的一小段代码,这一小段代码如:
address + 0: jmp *0xXXXXXXXX
address + 6 : push 一个常数
jmp 0xYYYYYYYY
第一次调用printf时地址0xXXXXXXXX中的值就是address + 6, 也就是第一次jmp会跳到 address + 6的地方,然后下一个jmp进行如号解析,然后在0xXXXXXXXX中写入真实的printf函数的地址,之后再调用printf时就会直接跳到printf函数去了。
我前面那个代码就是在0xXXXXXXXX中放入evil_code()函数的地址,address + 0: jmp *0xXXXXXXXX 这条指令占用6个字节,前面两个是操作码,后面就是地址,所以有代码中" + 2"

跑了帖子中更能清晰理解栈结构的例子,结果如下:

[S@fedora-1 test]$ cat test1.c
#include

int gi = 1;

f(char *fmt, int *p, int v)
{
int i;

for(i = 0; i < 8; i++) {
printf("%d %p %p\n", i, &i + i, *(&i+i));
}
printf("p = %p v = %d\n", p, v);
return;

for(i = 0; i < 256; i++) {
printf("addr = %p value = %d\n", &gi, gi);
}
}

main()
{
f("fmt", &gi, gi);
}
[S@fedora-1 test]$ ./a.out
0 0xbf8daf24 (nil)
1 0xbf8daf28 0xbf8daf48
2 0xbf8daf2c 0x8048469
3 0xbf8daf30 0x804855d
4 0xbf8daf34 0x80496d4
5 0xbf8daf38 0x1
6 0xbf8daf3c 0x80484a9
7 0xbf8daf40 0xa7add0
p = 0x80496d4 v = 1

程序中的局部数组溢出使用,就能改变栈,结果不可预料。打印出荒唐的信息。

摘自:http://bbs.chinaunix.net/viewthread.php?tid=1652842&extra=page%3D1%26amp;filter%3Ddigest&page=6

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值