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

在C++中动态执行用户Shellcode遇阻,求问题排查

分析你的Shellcode执行失败问题

我来帮你拆解代码里的几个关键问题,这些都是导致执行异常的核心原因:

1. Shellcode本身不完整,缺少返回指令

你定义的shellcode是"\xB8\x04\x00\x00\x00",对应的汇编指令是:

mov eax, 0x4

这段代码执行完毕后,CPU没有收到返回指令(ret),会继续执行后续的垃圾内存数据,必然触发访问异常。你需要在shellcode末尾加上\xC3(对应ret指令),让函数指针调用后能正确返回。

2. 自定义段的属性设置问题(MSVC特定)

你用#pragma section(".shell",read,execute)创建的段,存在两个潜在问题:

  • MSVC的段属性设置中,只指定read+execute的段可能会被链接器的默认规则调整,导致实际权限不符合预期;
  • 全局数组放到自定义段时,链接器可能会和其他段合并,破坏你设置的可执行属性。

更稳妥的写法是明确加上write属性(即使你不需要修改shellcode,也能避免链接器的特殊处理),或者直接用动态内存分配的方式控制权限,这比自定义段更可靠。

3. 函数指针转换的不规范写法(虽非直接崩溃原因,但需注意)

你把数组地址转换成函数指针的写法((int(*)())&code),这里&code是数组的指针(unsigned char (*)[...]类型),直接转换会触发类型转换警告。更规范的写法是取数组首元素地址,或者利用数组名退化为指针的特性:

// 两种等价的规范写法
shell = reinterpret_cast<int(*)()>(&code[0]);
// 或者
shell = reinterpret_cast<int(*)()>(code);

修复后的示例代码

这里提供两种修复方案,按需选择:

方案1:修复自定义段写法

#pragma section(".shell", read, write, execute)
__declspec(allocate(".shell")) unsigned char code[] = "\xB8\x04\x00\x00\x00\xC3"; // 新增ret指令\xC3

int(*shell)();

int main() {
    shell = reinterpret_cast<int(*)()>(code);
    int a = shell(); // a的值会是4,可正常返回
    return 0;
}

方案2:用VirtualAlloc动态分配可执行内存(更推荐,灵活性更高)

这种方式完全手动控制内存权限,不受编译器段设置的影响:

#include <windows.h>

int main() {
    unsigned char code[] = "\xB8\x04\x00\x00\x00\xC3";
    // 分配可读写执行的内存页
    void* exec_mem = VirtualAlloc(nullptr, sizeof(code), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    if (!exec_mem) {
        // 处理内存分配失败的情况
        return 1;
    }
    // 复制shellcode到可执行内存
    memcpy(exec_mem, code, sizeof(code));
    // 转换为函数指针并执行
    int(*shell)() = reinterpret_cast<int(*)()>(exec_mem);
    int a = shell();
    // 释放内存
    VirtualFree(exec_mem, 0, MEM_RELEASE);
    return 0;
}

额外注意事项

  • 架构匹配:你的shellcode是32位x86指令,要确保项目编译为32位程序;如果是64位项目,需要编写对应的64位shellcode。
  • DEP影响:上述两种方案都是在可执行内存中执行代码,不会被数据执行保护(DEP)拦截,无需额外关闭DEP。
  • 编译器选项:如果启用了/GS(缓冲区安全检查),不会影响上述代码的执行,但要注意其他内存操作的安全性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:25:08