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

如何将任意EXE转为可注入其他进程的字节并执行

进程注入:将EXE转换为可执行十六进制字节的正确方法

我需要把一个EXE文件转换为十六进制字节,注入到其他进程内存中执行,功能类似直接注入计算器的进程注入方案,但要支持任意EXE。之前尝试过十六进制编辑器复制内容、在线转换工具、C指令等方法都没成功,下面是我写的Go代码和注入用的C代码片段:

我的Go转换代码

file, err := ioutil.ReadFile("...\\helper.exe")
if err != nil {
}
//fmt.Print(file)
f, err := os.Create("...\\fileInByte.txt")
if err != nil {
}
defer f.Close()
_, err = f.Write([]byte(file))
file2, err2 := ioutil.ReadFile("...\\fileInByte.txt")
if err2 != nil {
}
fmt.Print(file2)

我的C++注入代码片段

std::ifstream input("...\\fileInByte.txt", std::ios::binary);
std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(input), {});
unsigned char* my_payload;
my_payload = &buffer[0];
unsigned int my_payload_len = sizeof(my_payload);
...
...
...

// allocate memory buffer for remote process
rb = VirtualAllocEx(ph, NULL, my_payload_len, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
// write payload to memory buffer
if(!WriteProcessMemory(ph, rb, my_payload, my_payload_len, NULL))

问题分析

  1. Go代码逻辑错误:你只是把EXE的二进制内容直接写入文本文件,没有转换成十六进制字符串。二进制中的不可打印字符会在文本文件中丢失或乱码,导致后续读取无法还原正确数据。
  2. C++代码长度计算错误:sizeof(my_payload)获取的是指针的内存大小(通常4/8字节),不是实际payload的长度,应该用buffer.size()。
  3. 核心认知误区:普通EXE是PE格式文件,直接注入内存后无法直接执行——PE需要加载器处理重定位、导入表等逻辑。你参考的计算器注入方案用的是shellcode(精简的可执行指令),不是完整EXE。

正确实现方案

方案1:直接二进制注入(高效无转换)

跳过十六进制转换步骤,直接读取EXE二进制内容注入,避免转换开销:

#include <fstream>
#include <vector>

// 读取EXE二进制内容
std::ifstream input("helper.exe", std::ios::binary);
std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(input), {});
input.close();

// 正确获取payload信息
unsigned char* my_payload = buffer.data();
unsigned int my_payload_len = buffer.size();

// 后续注入逻辑保持原代码
// rb = VirtualAllocEx(ph, NULL, my_payload_len, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
// if(!WriteProcessMemory(ph, rb, my_payload, my_payload_len, NULL))

方案2:EXE转十六进制字符串再还原(按需使用)

如果必须用十六进制文本中转,修正Go和C++代码:

修正后的Go转换代码

package main

import (
	"encoding/hex"
	"io/ioutil"
)

func main() {
	// 读取EXE二进制
	fileBytes, err := ioutil.ReadFile("helper.exe")
	if err != nil {
		panic(err)
	}

	// 二进制转十六进制字符串
	hexContent := hex.EncodeToString(fileBytes)

	// 写入文本文件
	err = ioutil.WriteFile("fileInHex.txt", []byte(hexContent), 0644)
	if err != nil {
		panic(err)
	}
}

修正后的C++解码注入代码

#include <fstream>
#include <vector>
#include <string>
#include <cstdlib>

// 十六进制字符串转二进制字节数组
std::vector<unsigned char> hexToBytes(const std::string& hexStr) {
	std::vector<unsigned char> bytes;
	for (size_t i = 0; i < hexStr.length(); i += 2) {
		std::string byteStr = hexStr.substr(i, 2);
		unsigned char byte = static_cast<unsigned char>(strtol(byteStr.c_str(), nullptr, 16));
		bytes.push_back(byte);
	}
	return bytes;
}

int main() {
	// 读取十六进制文本
	std::ifstream input("fileInHex.txt");
	std::string hexStr((std::istreambuf_iterator<char>(input)), std::istreambuf_iterator<char>());
	input.close();

	// 还原为二进制
	std::vector<unsigned char> buffer = hexToBytes(hexStr);
	unsigned char* my_payload = buffer.data();
	unsigned int my_payload_len = buffer.size();

	// 后续注入逻辑
	// ...
	return 0;
}

关键补充:完整EXE注入的必要步骤

如果要注入完整EXE并执行,必须实现反射式PE加载:

  1. 在目标进程内存中解析PE文件头
  2. 处理PE重定位表
  3. 解析并加载导入的DLL和函数
  4. 跳转到PE入口点执行

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 15:10:28