免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12345下一页
最近访问板块 发新帖
查看: 13436 | 回复: 42

这个最基础的注入为什么会出错啊? [复制链接]

论坛徽章:
0
发表于 2009-12-14 18:18 |显示全部楼层
模仿着内核版的一个精华帖,写了一个最基础的练习题,不知道为什么会重复输出两次,然后segment fault

#include <stdio.h>

void attack() {
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;printf("hi,attacked!\n");
}


void foo() {
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;int c_foo;
&nbsp;&nbsp;&nbsp;&nbsp;int main_eip = (int) *(&c_foo + 3);
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;*(&c_foo + 3) = (int)attack;
&nbsp;&nbsp;&nbsp;&nbsp;*(&c_foo + 4) = main_eip;
&nbsp;&nbsp;&nbsp;&nbsp;
}

void main()
{
&nbsp;&nbsp;int local;
&nbsp;&nbsp;foo();
&nbsp;&nbsp;printf("I am retrun!\n");
&nbsp;
}

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
发表于 2009-12-14 18:53 |显示全部楼层
呵呵,还是建议用汇编写

论坛徽章:
0
发表于 2009-12-14 19:43 |显示全部楼层
int main_eip = (int) *(&c_foo + 2);   
    *(&c_foo + 2) = (int)attack;
    *(&c_foo + 3) = main_eip;
Solaris下面这样是可以的,我猜你想要这样的结果吧

论坛徽章:
0
发表于 2009-12-14 20:02 |显示全部楼层
用gdb逐步跟踪了,地址计算方面没有错误,不过很有意思的是在foo()中int main_eip的位置是在int  c_foo之前的。然后正常的进入attack(),返回main(),执行printf(),之后就出问题了,进入了一个好像是什么in_start()之类的函数,连续的next之后,就莫名其妙的回到了foo()中...

论坛徽章:
0
发表于 2009-12-14 22:11 |显示全部楼层
原帖由 iLRainyday 于 2009-12-14 18:18 发表
模仿着内核版的一个精华帖,写了一个最基础的练习题,不知道为什么会重复输出两次,然后segment fault

#include

void attack() {
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;& ...


汗,你把那篇东西找出来对一对,连抄都抄错

还是要理解才好呀。

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
发表于 2009-12-14 22:29 |显示全部楼层
画个图,来理解进栈出栈,就可以加深理解。这里的原理并不复杂,更不高深,用汇编再对着图,很快就可以写出预计的结果。

论坛徽章:
0
发表于 2009-12-14 22:53 |显示全部楼层
汗,你把那篇东西找出来对一对,连抄都抄错

还是要理解才好呀。


我没有照抄啦~~  按自己理解来计算,就是返回到main()之后出错了,call foo之后是一个add $xxx, %esp,我发现每次我返回到这里的时候,%esp的值总是和正确的值差了4个字节,估计就是这个原因造成连续输出两句“hi,attacked!” 按照mik老大的意思,由attack()来处理返回,可是返回的时候还是%esp的问题

论坛徽章:
0
发表于 2009-12-14 23:03 |显示全部楼层
你想:main() --> foo() ---->  attack() ---> main()     是吧?

如果要在 foo() 里设的话就要:

foo() 的返回值置为 attack()

attack() 的返回值置为 main()

[ 本帖最后由 mik 于 2009-12-15 00:23 编辑 ]

论坛徽章:
0
发表于 2009-12-14 23:25 |显示全部楼层
我画了个图,mik老大看看我哪里理解错了
cu.jpg

论坛徽章:
0
发表于 2009-12-14 23:51 |显示全部楼层
原帖由 iLRainyday 于 2009-12-14 23:25 发表
我画了个图,mik老大看看我哪里理解错了



由于在函数里:

push ebp                    <----- 建栈
mov ebp, esp
...
...
mov esp, ebp
pop ebp                        <----- 销栈
ret

------------------------------------

所以,在执行 attack() 时,也需要遵循这个原则

因此,还要为 attack() 函数留了一个 [ebp] 值

----------------------------
ret_value                                    <--------------------- main() 地址
----------------------------
ebp
---------------------------
ret_value                                     <-------------------  attack() 地址
---------------------------
ebp
---------------------------
main_eip
---------------------------
c_foo
----------------------------

[ 本帖最后由 mik 于 2009-12-15 00:21 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP