- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我一直在尝试使用 strcpy
、sprint
、gets
等故意易受攻击的 c 程序。这些程序在运行时都按预期运行在 Linux 上,但我的 OS X 机器上发生了一些奇怪的事情。这是我写的程序:
#include <stdio.h>
int main(int argc, char **argv) {
char buffer[64];
strcpy(buffer, argv[1]);
printf("buffer: %s\n", buffer);
return 0;
}
我是这样运行的:
(gdb) run test
Starting program: /Users/****/test2 test
buffer: test
[Inferior 1 (process 5290) exited normally]
(gdb) run `python -c 'print "A"*64'`
Starting program: /Users/****/test2 `python -c 'print "A"*64'`
buffer: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
[Inferior 1 (process 5291) exited normally]
(gdb) run `python -c 'print "A"*70'`
Starting program: /Users/****/test2 `python -c 'print "A"*70'`
buffer: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
[Inferior 1 (process 5294) exited normally]
(gdb) run `python -c 'print "A"*80'`
Starting program: /Users/****/test2 `python -c 'print "A"*80'`
buffer: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
[Inferior 1 (process 5297) exited normally]
(gdb) run `python -c 'print "A"*100'`
Starting program: /Users/****/test2 `python -c 'print "A"*100'`
buffer: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Program received signal SIGABRT, Aborted.
0x00007fff8eef3866 in ?? ()
(gdb)
首先,我预计 80 个字节足以使其崩溃。其次,我希望看到 0x4141414141414141
而不是 0x00007fff8eef3866
因为我只是试图用一堆 A 覆盖一些内存。其他数据来自哪里?另外,为什么程序会得到SIGABRT?为什么没有段错误?
程序集如下:
.section __TEXT,__text,regular,pure_instructions
.globl _main
.align 4, 0x90
_main: ## @main
.cfi_startproc
## BB#0:
pushq %rbp
Ltmp2:
.cfi_def_cfa_offset 16
Ltmp3:
.cfi_offset %rbp, -16
movq %rsp, %rbp
Ltmp4:
.cfi_def_cfa_register %rbp
subq $112, %rsp
movq ___stack_chk_guard@GOTPCREL(%rip), %rax
movq (%rax), %rax
movq %rax, -8(%rbp)
leaq -96(%rbp), %rax
movl $0, -12(%rbp)
movl %edi, -16(%rbp)
movq %rsi, -24(%rbp)
movq -24(%rbp), %rsi
movq 8(%rsi), %rsi
movq %rax, %rdi
callq _strcpy
leaq L_.str(%rip), %rdi
leaq -96(%rbp), %rsi
movq %rax, -104(%rbp) ## 8-byte Spill
movb $0, %al
callq _printf
movq ___stack_chk_guard@GOTPCREL(%rip), %rsi
movq (%rsi), %rsi
movq -8(%rbp), %rdi
cmpq %rdi, %rsi
movl %eax, -108(%rbp) ## 4-byte Spill
jne LBB0_2
## BB#1: ## %SP_return
movl $0, %eax
addq $112, %rsp
popq %rbp
ret
LBB0_2: ## %CallStackCheckFailBlk
callq ___stack_chk_fail
.cfi_endproc
.section __TEXT,__cstring,cstring_literals
L_.str: ## @.str
.asciz "buffer: %s\n"
.subsections_via_symbols
[更新]
实际上,似乎没有任何寄存器被覆盖,但看起来它们应该被覆盖:
启动程序:/Users/henrypitcairn/test2 python -c 'print "A"*128'
Breakpoint 1, 0x0000000100000ed4 in main ()
(gdb) c
Continuing.
buffer: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Program received signal SIGABRT, Aborted.
0x00007fff8eef3866 in ?? ()
(gdb) info registers
rax 0x0 0
rbx 0x7fff77921310 140735199449872
rcx 0x7fff5fbff9f8 140734799804920
rdx 0x0 0
rsi 0x6 6
rdi 0xc07 3079
rbp 0x7fff5fbffa20 0x7fff5fbffa20
rsp 0x7fff5fbff9f8 0x7fff5fbff9f8
r8 0x0 0
r9 0x0 0
r10 0x8000000 134217728
r11 0x206 518
r12 0x0 0
r13 0x0 0
r14 0x6 6
r15 0x0 0
rip 0x7fff8eef3866 0x7fff8eef3866
eflags 0x206 [ PF IF ]
cs 0x7 7
ss *value not available*
ds *value not available*
es *value not available*
fs 0x0 0
gs 0x30000 196608
(gdb) disas main
Dump of assembler code for function main:
0x0000000100000ed0 <+0>: push %rbp
0x0000000100000ed1 <+1>: mov %rsp,%rbp
0x0000000100000ed4 <+4>: sub $0x70,%rsp
0x0000000100000ed8 <+8>: mov 0x131(%rip),%rax # 0x100001010
0x0000000100000edf <+15>: mov (%rax),%rax
0x0000000100000ee2 <+18>: mov %rax,-0x8(%rbp)
0x0000000100000ee6 <+22>: lea -0x60(%rbp),%rax
0x0000000100000eea <+26>: movl $0x0,-0xc(%rbp)
0x0000000100000ef1 <+33>: mov %edi,-0x10(%rbp)
0x0000000100000ef4 <+36>: mov %rsi,-0x18(%rbp)
0x0000000100000ef8 <+40>: mov -0x18(%rbp),%rsi
0x0000000100000efc <+44>: mov 0x8(%rsi),%rsi
0x0000000100000f00 <+48>: mov %rax,%rdi
0x0000000100000f03 <+51>: callq 0x100000f54
0x0000000100000f08 <+56>: lea 0x7b(%rip),%rdi # 0x100000f8a
0x0000000100000f0f <+63>: lea -0x60(%rbp),%rsi
0x0000000100000f13 <+67>: mov %rax,-0x68(%rbp)
0x0000000100000f17 <+71>: mov $0x0,%al
0x0000000100000f19 <+73>: callq 0x100000f4e
0x0000000100000f1e <+78>: mov 0xeb(%rip),%rsi # 0x100001010
0x0000000100000f25 <+85>: mov (%rsi),%rsi
0x0000000100000f28 <+88>: mov -0x8(%rbp),%rdi
0x0000000100000f2c <+92>: cmp %rdi,%rsi
0x0000000100000f2f <+95>: mov %eax,-0x6c(%rbp)
0x0000000100000f32 <+98>: jne 0x100000f43 <main+115>
0x0000000100000f38 <+104>: mov $0x0,%eax
0x0000000100000f3d <+109>: add $0x70,%rsp
0x0000000100000f41 <+113>: pop %rbp
0x0000000100000f42 <+114>: retq
0x0000000100000f43 <+115>: callq 0x100000f48
End of assembler dump.
(gdb)
最佳答案
从您的汇编代码中您可以看到编译器添加了一个 stack_chk_guard,为了获得更多“易于操作”的程序,请尝试使用 -fno-stack-protector
进行编译(假设它是 gcc)。更多选项(也在 llvm 中)是 here .
它还表明编译器在堆栈上为局部变量保存了 112 个字节,其中包括 4 个字节和 8 个字节的寄存器溢出 - 所以其余 100 个字节可能是缓冲区 + 一些用于保护的填充,这可以解释为什么你看到它在 100 以上失败。
你实际上并没有在那里完成整个帧,你可能超出了溢出的寄存器,这解释了为什么它们在你之前的运行中似乎已经被“改变”,也可能为什么你得到的是 SIGABORT 而不是 seg错误以及返回地址正常的原因 - 你没有覆盖返回地址,你覆盖了一些寄存器(导致天知道是什么)
关于c - 故意易受攻击的测试程序未按预期运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21498765/
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 3 年前。 Improve
我目前正在从事类似bash的项目。但是,我需要使用数千个测试来测试该项目,而这些测试无法手动检查。这就是为什么我想自动执行测试。 我的程序使用fgets()来获取用户输入。我知道如何直接向程序发送参数
我想在 Android 中编写一个原生应用程序进行测试表面抛物线。是否有任何简单的程序显示如何创建Surfaceflinger 上的表面、寄存器缓冲区和后置缓冲区。 最佳答案 frameworks/b
有一个对象依赖于计时来正常运行。不幸的是,计时持续时间本身太长,无法实时对其进行实际测试,并且由于对象的性质,缩短持续时间违背了测试的目的。 测试此类对象的最佳方法是什么?理想情况下,会有一些可以使用
我首先要说的是,我是一名几乎没有 C++ 经验的大学生。你听对了多少次?我正在使用 libnodave 库中的测试程序 testISO_TCP(简化版)。该程序在连接到 seimens 300 PLC
我正在尝试构建一个非常简单的libodbc++程序。最近,我们注意到了一个奇怪的内存泄漏,我们认为这是由于ODBC++和IDS驱动程序之间的某个地方引起的-我正在编写一个测试来证明这一点。 我使用以下
我对 JavaScript 还很陌生,我有一点疑问。 我创建了这个 JSFiddle:https://jsfiddle.net/AndreaNobili/1up938xf/ 我只定义了执行简单求和(无
我用三个类文件在 IntelliJ 中创建了一个 maven 项目: package mavenKris; import org.apache.hadoop.io.Text; import org.a
我下载了包含 freeglut 的“非官方 OpenGL 软件 SDK”,但我似乎无法让它工作。我在 Windows 上。我在 Visual Studio 2010 或 MinGW g++ 上都没有成
我正在尝试使用 std::async 在 C++ 中调用异步函数按照这个官方cplusplus.com示例代码。 不幸的是,编译失败了。运行时 mingw32-make ,我收到以下错误: main.
我是一名优秀的程序员,十分优秀!