Windows 内存分配与远程线程注入笔记

一、内存分配

1. VirtualAlloc(当前进程)

// 申请内存,返回起始地址
LPVOID addr = VirtualAlloc(NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE);
if (addr == NULL)
{
    VirtualFree(addr, 0x1000, MEM_DECOMMIT);
}

2. VirtualAllocEx(其他进程)

常用于申请其他进程的内存空间。

HANDLE hProcess = GetCurrentProcess();
LPVOID addr = VirtualAllocEx(hProcess, NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE);
if (addr == NULL)
{
    VirtualFreeEx(hProcess, addr, 0x1000, MEM_DECOMMIT);
}

3. HeapAlloc(堆内存)

HANDLE hProcess = GetProcessHeap();
LPVOID addr = HeapAlloc(hProcess, HEAP_ZERO_MEMORY, 0x1000);
if (addr == NULL)
{
    HeapFree(hProcess, HEAP_NO_SERIALIZE, addr);
}

4. GlobalAlloc(堆内存)

PSECURITY_DESCRIPTOR hProcess = GlobalAlloc(GMEM_FIXED, 0x1000);
if (hProcess == NULL)
{
    GlobalFree(hProcess);
}

二、进程与线程相关

1. CreateThread(创建线程)

DWORD WINAPI fun1()
{
    MessageBox(0, L"Hello", L"Thread", MB_OK);
    return 0;
}

int main()
{
    HANDLE hThread = CreateThread(NULL, NULL, fun1, NULL, NULL, NULL);
    if (hThread == NULL)
    {
        CloseHandle(hThread);
    }
    WaitForSingleObject(hThread, INFINITE);
    return 0;
}

创建一个线程,执行 fun1 功能,弹出消息框。

2. CreateRemoteThread(远程线程)

可在其他进程中创建线程并执行。

HANDLE hProcess = GetCurrentProcess();
HANDLE hThread = CreateRemoteThread(hProcess, NULL, NULL, fun1, NULL, NULL, NULL);
if (hThread == NULL)
{
    CloseHandle(hThread);
}
WaitForSingleObject(hThread, INFINITE);

三、远程注入 DLL 弹出消息框

注入器代码(injector.cpp)

#include <stdio.h>
#include <windows.h>

int main()
{
    wchar_t dllPath[] = L"E:\\Mycode\\test\\Debug\\test.dll";

    // 检查 DLL 文件是否存在
    if (GetFileAttributesW(dllPath) == INVALID_FILE_ATTRIBUTES)
    {
        printf("DLL 文件不存在: %ws\n", dllPath);
        return 0;
    }

    // 查找目标窗口
    HWND WinProcess = FindWindowA(NULL, "[ LordPE Deluxe ] by yoda");
    if (WinProcess == NULL)
    {
        printf("查找窗口失败");
        exit(0);
    }

    // 获取进程 ID
    DWORD Pid = 0;
    GetWindowThreadProcessId(WinProcess, &Pid);
    if (Pid == 0)
    {
        printf("获取pid失败");
        exit(0);
    }

    // 打开目标进程
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, Pid);
    if (hProcess == NULL)
    {
        printf("获取进程权限失败");
        exit(0);
    }

    // 获取 LoadLibraryW 函数地址
    LPVOID loadLibraryAddr = GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "LoadLibraryW");
    if (loadLibraryAddr == NULL)
    {
        printf("获取 LoadLibraryW 地址失败\n");
        CloseHandle(hProcess);
        exit(0);
    }

    // 在目标进程中分配内存
    LPVOID addr = VirtualAllocEx(hProcess, NULL, 0x1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    if (addr == NULL)
    {
        printf("申请内存失败");
        CloseHandle(hProcess);
        exit(0);
    }

    // 将 DLL 路径写入目标进程
    SIZE_T bytesWritten = 0;
    SIZE_T pathSize = (wcslen(dllPath) + 1) * sizeof(wchar_t);
    if (WriteProcessMemory(hProcess, addr, dllPath, pathSize, &bytesWritten) == 0)
    {
        printf("进程写入失败");
        VirtualFreeEx(hProcess, addr, 0, MEM_RELEASE);
        CloseHandle(hProcess);
        exit(0);
    }

    // 创建远程线程,加载 DLL
    HANDLE hTread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)loadLibraryAddr, addr, 0, NULL);
    if (hTread == NULL)
    {
        printf("远程执行失败");
        VirtualFreeEx(hProcess, addr, 0, MEM_RELEASE);
        CloseHandle(hProcess);
        exit(0);
    }

    // 等待线程执行完毕
    WaitForSingleObject(hTread, INFINITE);

    // 清理资源
    CloseHandle(hTread);
    VirtualFreeEx(hProcess, addr, 0, MEM_RELEASE);
    CloseHandle(hProcess);

    system("pause");
    return 0;
}

DLL 代码(test.dll)

// dllmain.cpp
#include "pch.h"
#include <windows.h>

BOOL APIENTRY DllMain(HMODULE hModule,
                      DWORD  ul_reason_for_call,
                      LPVOID lpReserved)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        MessageBoxW(NULL, L"Hello from injected DLL!", L"Thread", MB_OK);
        break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

效果展示