构建核心注入代码

构建核心注入代码

1.INJECT.h

#pragma once

typedef unsigned int (WINAPI* _LoadLibrary)(wchar_t* dllName); //指向LoadLibrary的函数指针
typedef struct _REMOTE_DATA
{
wchar_t dllName[0xff]; //dll路径
_LoadLibrary f_LoadLibrary;
}* PREMOTE_DATA;

class INJECT
{
public:
BOOL StartProcess(
const wchar_t* GameExe,
const wchar_t* GamePath,
wchar_t* GameCmds,
PROCESS_INFORMATION* LPinfo
);

void* ImageLoad(const wchar_t* filename);
void UnloadImage(void* _data);
DWORD GetEntryPoint(const wchar_t* filename);

public:
//分配远程空间内存
BOOL CreateRemoteData(HANDLE hProcess, const wchar_t* dllName);
void CodeRemoteData(PREMOTE_DATA _data, const wchar_t* dllName); //编码远程参数
};


2.INJECT.cpp

#include "pch.h"
#include "INJECT.h"
#include <fstream>

void _stdcall INJECTCode()
{
unsigned address = 0xCCCCCCCC; //创建一个指针指向LoadLibrary的dll,此处的0xCCCCCCC只是一个象征,被编译后的字节码会再次进行替换
PREMOTE_DATA p = (PREMOTE_DATA)address;
p->f_LoadLibrary(p->dllName);
}

BOOL INJECT::StartProcess(const wchar_t* GameExe, const wchar_t* GamePath, wchar_t* GameCmds, PROCESS_INFORMATION* LPinfo)
{
STARTUPINFO si{}; //获取进程信息的结构体
si.cb = sizeof(si); //必须要 no why

return CreateProcess( //固定格式
GameExe,
GameCmds,
NULL, NULL, TRUE,
CREATE_SUSPENDED,
NULL,
GamePath,
&si,
LPinfo
);
}

void INJECT::UnloadImage(void* _data)
{
delete[] _data;
}

DWORD INJECT::GetEntryPoint(const wchar_t* filename)
{
void* image = ImageLoad(filename);

IMAGE_DOS_HEADER* dosHeader = (IMAGE_DOS_HEADER*)image;
unsigned PEAddress = dosHeader->e_lfanew + unsigned(image);

IMAGE_NT_HEADERS* ntHeader = (IMAGE_NT_HEADERS*)PEAddress;
DWORD dEntryPoint = ntHeader->OptionalHeader.AddressOfEntryPoint;

UnloadImage(image);
return dEntryPoint;
}

BOOL INJECT::CreateRemoteData(HANDLE hProcess, const wchar_t* dllName)
{
LPVOID adrRemote = VirtualAllocEx(hProcess, 0, 0x3000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
//写入远程代码
SIZE_T lwt;
LPVOID adrRemoteData = LPVOID((unsigned)adrRemote + 0x2000);
_REMOTE_DATA remoteData{};
CodeRemoteData(&remoteData, dllName);
WriteProcessMemory(hProcess, adrRemoteData, &remoteData, sizeof(remoteData), &lwt);

//修正远程代码
char _code[0x200];
memcpy(_code, INJECTCode, sizeof(_code));
for (int i = 0; i < 0x100; i++) //
{
unsigned* pcode = (unsigned*)(&_code[i]);
if (pcode[0] == 0xCCCCCCCC)
{
pcode[0] = (unsigned)adrRemoteData;
break;
}
}

WriteProcessMemory(hProcess, adrRemote, _code, 0x200, &lwt);
DWORD dwThreadId;
HANDLE remoteHd1 = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)adrRemote, NULL, 0, &dwThreadId);
WaitForSingleObject(remoteHd1, INFINITE);
return 0;
}

void INJECT::CodeRemoteData(PREMOTE_DATA _data, const wchar_t* dllName)
{
short length{};
for (length = 0; dllName[length]; length++);

HMODULE hKernel = LoadLibrary(_T("kernel32.dll"));
_data->f_LoadLibrary = (_LoadLibrary)GetProcAddress(hKernel, "LoadLibraryW");
memcpy(_data->dllName, dllName, (length + 1) * 2); //wchar_t 2字节
/*CString wTxt;
wTxt.Format(L"%X", _data->f_LoadLibrary);
AfxMessageBox(wTxt);*/
}

void* INJECT::ImageLoad(const wchar_t* filename)
{
std::ifstream streamReader(filename, std::ios::binary);
streamReader.seekg(0, std::ios::end); //游标移到文件结尾
unsigned filesize = streamReader.tellg(); //获取游标当前位置 - 文件开始位置,此处为文件大小
char* _data = new char[filesize]; //分配内存
streamReader.seekg(0, std::ios::beg); //跳转回开始
streamReader.read(_data, filesize); //读取文件
streamReader.close();
return _data;
}