gpt4 book ai didi

c++ - c++是否存在缓冲区溢出helloworld?

转载 作者:太空狗 更新时间:2023-10-29 23:42:45 25 4
gpt4 key购买 nike

我尝试了 this question 提供的代码, 但它不起作用。

如何设计溢出来包裹我的脑袋?

更新:

    .file   "hw.cpp"
.section .rdata,"dr"
LC0:
.ascii "Oh shit really bad~!\15\12\0"
.text
.align 2
.globl __Z3badv
.def __Z3badv; .scl 2; .type 32; .endef
__Z3badv:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
movl $LC0, (%esp)
call _printf
leave
ret
.section .rdata,"dr"
LC1:
.ascii "WOW\0"
.text
.align 2
.globl __Z3foov
.def __Z3foov; .scl 2; .type 32; .endef
__Z3foov:
pushl %ebp
movl %esp, %ebp
subl $4, %esp
movl LC1, %eax
movl %eax, -4(%ebp)
movl $__Z3badv, 4(%ebp)
leave
ret
.def ___main; .scl 2; .type 32; .endef
.align 2
.globl _main
.def _main; .scl 2; .type 32; .endef
_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
movl %eax, -4(%ebp)
movl -4(%ebp), %eax
call __alloca
call ___main
call __Z3foov
movl $0, %eax
leave
ret
.def _printf; .scl 2; .type 32; .endef

最佳答案

将另一个问题中的示例编译为汇编会有所帮助,这样您就可以了解给定编译器和处理器的堆栈布局方式。示例中的 +8 可能不是您环境的正确数字。您需要确定的是返回地址存储在堆栈中相对于存储在堆栈中的数组的位置。

顺便说一句,这个例子对我有用。我在 Win XP 上用 Cygwin,gcc 版本 4.3.4 编译。当我说它“有效”时,我的意思是它在 bad() 函数中运行代码,即使该函数从未被代码调用。

$ gcc -Wall -Wextra buffer-overflow.c && ./a.exe
Oh shit really bad~!
Segmentation fault (core dumped)

该代码实际上不是缓冲区溢出的示例,它是当缓冲区溢出被利用时可能发生的坏事的示例。

我不是很擅长 x86 汇编,但这是我对这个漏洞利用工作原理的解释。

$ gcc -S buffer-overflow.c && cat buffer-overflow.s
_foo:
pushl %ebp ;2
movl %esp, %ebp ;3
subl $16, %esp ;4
movl LC1, %eax ;5
movl %eax, -4(%ebp) ;6
leal -4(%ebp), %eax ;7
leal 8(%eax), %edx ;8
movl $_bad, %eax ;9
movl %eax, (%edx) ;10
leave
ret

_main:
...
call _foo ;1
...

main 调用 foo (1) 时,call 指令将 main 中的地址压入堆栈,一旦调用foo 完成。压入堆栈涉及递减 ESP 并在其中存储一个值。

一旦在 foo 中,旧的基指针值也被压入堆栈 (2)。这将在 foo 返回时恢复。堆栈指针被保存为该堆栈帧 (3) 的基指针。堆栈指针递减 16 (4),这会在此堆栈帧上为局部变量创建空间。

文字“WOW\0”的地址被复制到栈上的局部变量overme中(5,6)——这对我来说很奇怪,不应该是复制4个字符吗到堆栈上分配的空间?无论如何,WOW(或指向它的指针)被复制的地方是当前基指针下方 4 个字节。所以堆栈包含这个值,然后是旧的基指针,然后是返回地址。

overme 的地址被放入 EAX (7) 并在该地址 (8) 之外的 8 个字节处创建一个整数指针。 bad 函数的地址被放入 EAX (9),然后该地址存储在整数指针 (10) 指向的内存中。

堆栈看起来像这样:

     // 4 bytes on each row
ESP: (unused)
: (unused)
: (unused)
: &"WOW\0"
: old EBP from main
: return PC, overwritten with &bad

当您使用优化进行编译时,所有有趣的东西都会被优化为“无用代码”(确实如此)。

$ gcc -S -O2 buffer-overflow.c && cat buffer-overflow.s
_foo:
pushl %ebp
movl %esp, %ebp
popl %ebp
ret

关于c++ - c++是否存在缓冲区溢出helloworld?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2533261/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com