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

使用CreateRemoteThread注入线程导致目标进程崩溃的问题排查

CreateRemoteThread无DLL注入崩溃问题分析与解决

1. 是否可以实现“无DLL的DLL注入”?

可以,这种技术叫做代码注入,无需依赖DLL文件,直接将待执行的机器码写入目标进程的内存空间,再通过CreateRemoteThread执行这段代码。核心是把本地的函数逻辑转换成可在目标进程中运行的机器码,而非直接引用本地函数地址。

2. 崩溃的根本原因

你的代码存在两个致命错误:

  • 线程函数地址无效:CreateRemoteThread传入的HackThread是本地进程(injector.exe)中的函数地址,目标进程(game.exe)的虚拟地址空间与本地完全独立,这个地址在目标进程中要么是未分配的内存,要么是无关数据,执行时直接触发内存访问错误导致崩溃。
  • 逻辑混淆:数据与代码的位置错误:你向目标进程分配的内存中写入的是player变量的地址(0x00791000),而非要执行的线程函数代码。目标进程执行这段数据时,会把它当作机器码解析,必然引发崩溃。

修复方案

步骤1:提取线程函数的机器码

要让目标进程执行HackThread的逻辑,需要先将该函数的机器码提取出来。可以通过__declspec(naked)定义线程函数,避免编译器插入额外的序言/尾声代码,便于精准提取机器码。

步骤2:正确注入机器码与参数

  • 向目标进程分配可执行内存,写入提取的机器码
  • 传递正确的线程参数(目标进程中player变量的真实地址,需从game.exe的输出中获取或通过内存扫描得到)

修改后的injector.cpp示例

#include <windows.h>
#include <iostream>
#include <cstring>

const WCHAR* TARGET_PROCESS_NAME = L"game.exe";
const DWORD MEMORY_ALLOCATION_SIZE = 1 << 12;

// 裸函数,便于提取机器码,手动处理栈帧
__declspec(naked) DWORD WINAPI HackThread() {
    __asm {
        mov eax, [esp+4]    // 获取线程参数(player的地址)
        mov dword ptr [eax], 0x64  // 设置*player = 100
        xor eax, eax        // 返回0
        ret 4               // 清理参数栈
    }
}

// 补充getProcessId函数实现
DWORD getProcessId(const WCHAR* processName) {
    PROCESSENTRY32 pe32;
    pe32.dwSize = sizeof(PROCESSENTRY32);
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnapshot == INVALID_HANDLE_VALUE) return 0;

    if (!Process32First(hSnapshot, &pe32)) {
        CloseHandle(hSnapshot);
        return 0;
    }

    do {
        if (!wcscmp(pe32.szExeFile, processName)) {
            CloseHandle(hSnapshot);
            return pe32.th32ProcessID;
        }
    } while (Process32Next(hSnapshot, &pe32));

    CloseHandle(hSnapshot);
    return 0;
}

int main() {
    auto pid = getProcessId(TARGET_PROCESS_NAME);
    if (pid == 0) {
        std::cerr << "Error: Unable to find process " << TARGET_PROCESS_NAME << std::endl;
        return 1;
    }

    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    if (hProcess == NULL) {
        std::cerr << "Error: Unable to open process. Error code: " << GetLastError() << std::endl;
        return 1;
    }

    // 分配可执行内存用于存放注入的机器码
    LPVOID remoteCode = VirtualAllocEx(hProcess, nullptr, MEMORY_ALLOCATION_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    if (remoteCode == nullptr) {
        std::cerr << "Error: Unable to allocate code memory in remote process. Error code: " << GetLastError() << std::endl;
        CloseHandle(hProcess);
        return 1;
    }

    // 提取HackThread的机器码(实际需通过反汇编确定准确长度)
    const unsigned char* codeStart = reinterpret_cast<const unsigned char*>(&HackThread);
    size_t codeLength = 10; // 示例长度,需根据反汇编结果调整

    // 将机器码写入目标进程
    if (!WriteProcessMemory(hProcess, remoteCode, codeStart, codeLength, NULL)) {
        std::cerr << "Error: Unable to write code to remote process. Error code: " << GetLastError() << std::endl;
        VirtualFreeEx(hProcess, remoteCode, MEMORY_ALLOCATION_SIZE, MEM_RELEASE);
        CloseHandle(hProcess);
        return 1;
    }

    // 替换为game.exe输出的player真实地址
    LPVOID playerAddr = reinterpret_cast<LPVOID>(0x00791000);

    // 创建远程线程执行注入的代码
    HANDLE hThread = CreateRemoteThread(hProcess, nullptr, 0, (LPTHREAD_START_ROUTINE)remoteCode, playerAddr, NULL, nullptr);
    if (hThread == NULL) {
        std::cerr << "Error: Unable to create remote thread. Error code: " << GetLastError() << std::endl;
        VirtualFreeEx(hProcess, remoteCode, MEMORY_ALLOCATION_SIZE, MEM_RELEASE);
        CloseHandle(hProcess);
        return 1;
    }

    WaitForSingleObject(hThread, INFINITE);

    // 清理资源
    VirtualFreeEx(hProcess, remoteCode, MEMORY_ALLOCATION_SIZE, MEM_RELEASE);
    CloseHandle(hThread);
    CloseHandle(hProcess);

    return 0;
}

关键注意事项

  • 机器码长度:实际使用时需通过反汇编工具(如x64dbg、IDA)查看HackThread的机器码长度,避免写入不完整或多余字节。
  • 地址随机性:game.exe中的player地址可能因ASLR机制每次运行变化,建议通过内存扫描动态获取,而非硬编码地址。
  • 权限要求:确保injector.exe以管理员权限运行,避免因权限不足导致操作失败。

内容的提问来源于stack exchange,提问作者Tu Le Anh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 12:57:03