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

如何从C++源代码中获取可执行字节码用于内存注入

从C++源代码直接生成可内存注入字节码的实现方案

你需要的可注入字节码本质是位置无关代码(PIC, Position-Independent Code),不需要依赖PE加载器处理重定位、导入表就能直接在目标进程内存中运行的原生指令序列,具体实现步骤如下:

1 编写符合Shellcode规范的C++代码

代码必须满足无外部依赖、位置无关的核心要求,需遵循以下规则:

  • 不可直接调用系统API,需自行通过PEB遍历获取目标API地址,或将用到的API地址作为参数传入shellcode逻辑
  • 禁止使用全局变量、静态变量,所有数据都在栈上分配,或用相对偏移读取内嵌的常量数据
  • 不可调用C++标准库、CRT函数,避免引入外部依赖
  • 统一使用__stdcall调用约定,自行控制栈平衡,避免编译器生成冗余指令

示例代码框架:

// 自行声明需要用到的结构体、函数指针类型,不依赖外部头文件
typedef NTSTATUS(WINAPI* PFN_NtAllocateVirtualMemory)(
    HANDLE ProcessHandle,
    PVOID* BaseAddress,
    ULONG ZeroBits,
    PULONG RegionSize,
    ULONG AllocationType,
    ULONG Protect
);

// Shellcode入口函数,所有逻辑都写在此处,不要调用外部未定义的函数
VOID ShellcodeMain() {
    // 业务逻辑实现,例如遍历PEB获取NtAllocateVirtualMemory地址、分配内存等
    // 所有字符串都以栈数组形式定义,例如:CHAR kernel32Name[] = {'k','e','r','n','e','l','3','2','.','d','l','l',0};
}

2 调整编译配置

以MSVC编译器为例,需调整以下编译选项:

  • 开启/O1或/Os优化,最小化代码体积
  • 开启/Gy函数级链接选项,方便后续提取代码段
  • 关闭/GS缓冲区安全检查,去除多余的安全检查指令
  • 关闭/RTC运行时错误检查,避免生成CRT检查代码
  • 编译架构和待注入的目标进程架构完全一致,x86进程只能注入x86架构的字节码,x64同理

3 提取编译后的字节码

有两种常用提取方式可选择:

方式1:用dumpbin工具提取

编译生成obj目标文件后,使用VS自带的dumpbin工具查看.text段内容:
dumpbin /ALL your_source.obj
找到ShellcodeMain函数对应的.text段字节序列,直接拷贝转换为unsigned char数组即可。

方式2:添加边界标记直接读取

在代码中新增空函数标记shellcode的结束边界,运行时直接读取两个函数地址之间的内存即可拿到字节码:

// 放在ShellcodeMain之后的空函数,作为结束边界
VOID ShellcodeEnd() {}

// 运行时直接提取字节码
SIZE_T shellcodeSize = (SIZE_T)ShellcodeEnd - (SIZE_T)ShellcodeMain;
unsigned char* shellcodeBuffer = (unsigned char*)ShellcodeMain;

注意事项

  • 注入字节码前,需要将目标进程中存放shellcode的内存页权限修改为PAGE_EXECUTE_READWRITE,否则会触发内存访问异常
  • 如果shellcode中存在硬编码地址,需要自行处理重定位逻辑,或者全程使用相对偏移访问数据和指令

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 23:45:00