BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / soft-design / #3526同步于 2006/2/16
该镜像源已超过 30 天没有更新,可能在源站已被删除。
SoftDesign机器人发帖

关于溢出与反溢出

zzm7000
2006/2/16镜像同步12 回复
看“Smashing The Stack For Fun And Profit”里面example3.c void fun(int a, int b,int c) { char buffer1[5]; char buffer2[10]; int *ret; ret = buffer1 + 12; (*ret) += 8; } void main(){ int x; x=0; fun(1,2,3); x=1; printf("%d\n",x); } 作者的目的是修改stack上的返回地址,所以ret = buffer1 + 12;我不知道他的gcc版本,他用的gdb的版本号是GDB 4.15,此时stack的图如下 buffer2 buffer1 sfp ret a b c <------ [ 12bytes ][ 8bytes ][ 4bytes ][ 4bytes][ ][ ][ ] top of bottom of stack stack 所以要达到作者的效果buffer2应该挨着buffer1,buffer1挨着sfp(ebp)。 这是我用GCC: (GNU) 3.4.3编译后的反汇编结果 .file "example3.c" .text .globl fun .type fun, @function fun: pushl %ebp movl %esp, %ebp subl $56, %esp --问题就在这里,要达到作者效果,这里应该是subl $20, %esp 才对吧 leal -24(%ebp), %eax addl $12, %eax movl %eax, -44(%ebp) movl -44(%ebp), %edx movl -44(%ebp), %eax movl (%eax), %eax addl $8, %eax movl %eax, (%edx) leave ret .size fun, .-fun .section .rodata .LC0: .string "%d\n" .text .globl main .type main, @function main: pushl %ebp movl %esp, %ebp subl $8, %esp andl $-16, %esp movl $0, %eax addl $15, %eax addl $15, %eax shrl $4, %eax sall $4, %eax subl %eax, %esp movl $0, -4(%ebp) subl $4, %esp pushl $3 pushl $2 pushl $1 call fun addl $16, %esp movl $1, -4(%ebp) subl $8, %esp pushl -4(%ebp) pushl $.LC0 call pritnf addl $16, %esp leave ret 我试改了buffer1,2的大小,没有什么规律,好像为本地变量预留的空间是随机的。用vc时也发现过这个问题,它减esp的数值远大于局部变量的大小。 我认为这就是一种反溢出的简单手段,至少不能通过buffer的地址推测返回地址。buffer1,buffer2可能是随机分布在56bytes的空间中。 我在想应该可以用内嵌汇编取得函数的返回地址。 不知道对不对,谁讲讲,谢啦。
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
zzm7000机器人#1 · 2006/2/16
貌似该发到 信息安全版去。。。。
flyingkisser机器人#2 · 2006/2/16
nasm的语法看起来很不习惯,我研究过win32下的溢出,VC给局部变量留下的空间是固定的,即是局部变量的总大小,当然是双字对齐的。另外,测试溢出点的时候,对于栈溢出二分法是个不错的方法, 一个程序的溢出点,在同一个平台下,多半是固定的。你说的这种反溢出的简单手段在win32下是行不通的,unix我研究不多,不敢妄下结论。
zzm7000机器人#3 · 2006/2/16
我没太明白,比如这个 void fun(int a, int b) { int d=a; int e=b; } void main() { fun(1,2); } 我用的vs。net 2003 void fun(int a, int b) { 00411A40 push ebp 00411A41 mov ebp,esp 00411A43 sub esp,0D8h ----这里不是有216字节吗?四字对齐也只需要8字节啊?我没懂 00411A49 push ebx 00411A4A push esi 00411A4B push edi 00411A4C lea edi,[ebp-0D8h] 00411A52 mov ecx,36h ------ 54 54*4=216 00411A57 mov eax,0CCCCCCCCh ------初始化?为什么初始0CCCCCCCCh 00411A5C rep stos dword ptr [edi] int d=a; 00411A5E mov eax,dword ptr [a] 00411A61 mov dword ptr [d],eax int e=b; 00411A64 mov eax,dword ptr [b] 00411A67 mov dword ptr [e],eax } 00411A6A pop edi 00411A6B pop esi 00411A6C pop ebx 00411A6D mov esp,ebp 00411A6F pop ebp 00411A70 ret 大牛再给我讲讲呵
zzm7000机器人#4 · 2006/2/16
上面写错了 是四字节对齐 就是说从上面来看,VC给局部变量留下的空间不是局部变量的总大小啊?
zzm7000机器人#5 · 2006/2/16
cl version Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86 Copyright (C) Microsoft Corporation 1984-2002.
flyingkisser机器人#6 · 2006/2/16
把你编译好的程序发上来看看,release版的, 我当年在vc6.0下试过,确实是一个int或一个char,就留下一个双字。 另外,你编译出来的是.net程序吗?.net的PE文件格式有所变化,变化还不小,没太研究过了。
zzm7000机器人#7 · 2006/2/16
【 在 zzm7000 的大作中提到: 】 : 看“Smashing The Stack For Fun And Profit”里面example3.c : void fun(int a, int b,int c) : { : ................... 附件(21.5KB) test.exe
zzm7000机器人#8 · 2006/2/16
我建得是win32 console
atian25机器人#9 · 2006/2/16
老猫是这方面的牛人