上一个内容:36.远程注入到入口点注入
以 36.远程注入到入口点注入 它的代码为基础进行修改
效果图:
CWndINJ.cpp文件中修改的函数OnNMDblclkList1
void CWndINJ::OnNMDblclkList1(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
// TODO: 在此添加控件通知处理程序代码
*pResult = 0;
int index = pNMItemActivate->iItem;
if (index < 0)return;
CString GamePath = ExeLst.GetItemText(index, 2);
CString GameExe = ExeLst.GetItemText(index, 1);
CString GameCmds = ExeLst.GetItemText(index, 3);
CString GameDlls = ExeLst.GetItemText(index, 4);
// 用来指定创建时进程的主窗口的窗口工作站、桌面、标准句柄和外观。
// STARTUPINFO si{};
// si.cb = sizeof(si);
PROCESS_INFORMATION prinfo{};
m_INJCET.StartProcess(GameExe, GamePath, GameCmds.GetBuffer(), &prinfo);
PROCESS_INFORMATION odinfo{};
//F:\其它\OllyDbg\Ollydbg.exe - p 4760
CString dbgExe, dbgPath, dbgCmds;
dbgExe = L"F:\\其它\\OllyDbg\\Ollydbg.exe";
dbgPath = L"F:\\其它\\OllyDbg\\";
dbgCmds.Format(L"%s -p %d", dbgExe, prinfo.dwProcessId);
m_INJCET.StartProcess(dbgExe, dbgPath, dbgCmds.GetBuffer(), &odinfo, false);
//STARTUPINFO si{};
//si.cb = sizeof(si);
//CreateProcess(dbgExe,
// dbgExe.GetBuffer(),
// NULL, NULL,
// false,
// // 新进程的主线程处于挂起状态创建,在调用 ResumeThread 函数之前不会运行。
// 0,
// NULL,
// dbgPath,
// &si,
// &odinfo
//);
m_INJCET.CreateRemoteData(prinfo.hProcess, GameExe, L"F:\\代码存放地\\c\\GAMEHACKER2\\Release\\Dlls.dll");
ResumeThread(prinfo.hThread);
//ResumeThread(odinfo.hThread);
//m_INJCET.CodeRemoteData(&_data);
/**
CreateProcess(GameExe,
GameCmds.GetBuffer(),
NULL,NULL,
FALSE,
// 新进程的主线程处于挂起状态创建,在调用 ResumeThread 函数之前不会运行。
CREATE_SUSPENDED,
NULL,
GamePath,
&si,
&prinfo
);
*/
/** 方式一调用api
CStringA GameExeA;
GameExeA = GameExe;
PLOADED_IMAGE image = ImageLoad(GameExeA, NULL);
DWORD dEntryPoint = image->FileHeader->OptionalHeader.AddressOfEntryPoint;
CString wTxt;
wTxt.Format(L"%X", dEntryPoint);
AfxMessageBox(wTxt);
ImageUnload(image)
*/
/** 方式二(要在32位环境下运行)
void* image = _imageload(GameExe.GetBuffer());
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;
CString wTxt;
wTxt.Format(L"%X", dEntryPoint);
AfxMessageBox(wTxt);
_unloadimage(image);
*/
//LPVOID adrRemote = VirtualAllocEx(prinfo.hProcess, 0, 0x3000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
//SIZE_T lwt;
//WriteProcessMemory(prinfo.hProcess, adrRemote, INJECTCode, 0x200, &lwt);
//CString wTxt;
//wTxt.Format(L"%X", adrRemote);
//AfxMessageBox(wTxt);
// 让游戏继续运行
//m_INJCET.CreateRemoteData(prinfo.hProcess, GameDlls.GetBuffer());
}
INJCET.cpp文件中修改的函数 StartProcess、CreateRemoteData
#include "pch.h"
#include "INJCET.h"
#include <fstream>
void _stdcall INJECTCode() {
unsigned address = 0xCCCCCCCC;
PREMOTE_DATA p = (PREMOTE_DATA)address;
p->f_LoadLibrary(p->dllName);
unsigned dEntry = p->EntryPoint;
char* entryCode = (char*)p->EntryPoint;
entryCode[0] = p->oldCode[0];
entryCode[1] = p->oldCode[1];
entryCode[2] = p->oldCode[2];
entryCode[3] = p->oldCode[3];
entryCode[4] = p->oldCode[4];
_asm {
mov eax, dEntry
jmp eax
}
}
DWORD _stdcall RemoteThreadProce(PREMOTE_DATA p) {
unsigned base = p->f_GetModuleHandleA(0);
DWORD dRet;
p->EntryPoint += base;
p->f_VirtualProtect((LPVOID)p->EntryPoint, 0x1000, PAGE_EXECUTE_READWRITE, &dRet);
char* entryCode = (char*)p->EntryPoint;
p->oldCode[0] = entryCode[0];
p->oldCode[1] = entryCode[1];
p->oldCode[2] = entryCode[2];
p->oldCode[3] = entryCode[3];
p->oldCode[4] = entryCode[4];
int* entryDis = (int*)(p->EntryPoint + 1);
*entryCode = 0xE9;
int Distance = p->HOOKFunction - p->EntryPoint - 5;
entryDis[0] = Distance;
return 1;
}
BOOL INJCET::StartProcess(const wchar_t* GameExe, const wchar_t* GamePath, wchar_t* GameCmds, PROCESS_INFORMATION* LPinfo, bool Pause)
{
// 用来指定创建时进程的主窗口的窗口工作站、桌面、标准句柄和外观。
STARTUPINFO si{};
si.cb = sizeof(si);
DWORD s = 0;
if (Pause)s = CREATE_SUSPENDED;
CreateProcess(GameExe,
GameCmds,
NULL, NULL,
false,
// 新进程的主线程处于挂起状态创建,在调用 ResumeThread 函数之前不会运行。
s,
NULL,
GamePath,
&si,
LPinfo
);
return TRUE;
}
void* INJCET::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;
}
void INJCET::UnloadImage(void* _data) {
delete[] _data;
}
DWORD INJCET::GetEntryPoint(const wchar_t* filename)
{
// 方式二(要在32位环境下运行根据游戏版本选择运行32还是64位的程序)
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;
CString wTxt;
wTxt.Format(L"%X", dEntryPoint);
AfxMessageBox(wTxt);
UnloadImage(image);
return dEntryPoint;
}
BOOL INJCET::CreateRemoteData(HANDLE hProcess, const wchar_t* GameExe, const wchar_t* dllName)
{
LPVOID adrRemote = VirtualAllocEx(hProcess, 0, 0x3000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
SIZE_T lwt;
LPVOID adrRemoteData = (LPVOID)((unsigned)adrRemote + 0x2000);
LPVOID adrRemoteProc= (LPVOID)((unsigned)adrRemote + 0x500);
_REMOTE_DATA remoteData{};
remoteData.EntryPoint = GetEntryPoint(GameExe);
CodeRemoteData(&remoteData, dllName);
remoteData.HOOKFunction = (unsigned)adrRemote;
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);
WriteProcessMemory(hProcess, adrRemoteProc, RemoteThreadProce, 0x200, &lwt);
CString wTxt;
wTxt.Format(L"%X", adrRemote);
AfxMessageBox(wTxt);
DWORD dwThreadId = 0;
HANDLE remotehdl = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)adrRemoteProc, adrRemoteData, 0, &dwThreadId);
WaitForSingleObject(remotehdl, INFINITE);
//DWORD dwThreadId = 0;
//HANDLE remoteHdl = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)adrRemote, NULL, 0, &dwThreadId);
//WaitForSingleObject(remoteHdl, INFINITE);
return TRUE;
}
void INJCET::CodeRemoteData(PREMOTE_DATA _data, const wchar_t* dllName)
{
short lenth;
// 求长度
for (lenth = 0; dllName[lenth]; lenth++);
HMODULE hKernel = LoadLibrary(_T("kernel32.dll"));
//_data->f_LoadLibrary = (_LoadLibrary)GetProcAddress(hKernel, "LoadLibraryW");
_data->f_LoadLibrary = (_LoadLibrary)GetProcAddress(hKernel, "LoadLibraryW");
_data->f_GetModuleHandleA = (_GetModuleHandleA)GetProcAddress(hKernel, "GetModuleHandleA");
_data->f_VirtualProtect = (_VirtualProtect)GetProcAddress(hKernel, "VirtualProtect");
//LoadLibraryW
// wchar两字节拷贝是一字节所以长度要成2
memcpy(_data->dllName, dllName, (lenth + 1) * 2);
/*CString wTxt;
wTxt.Format(L"%X", _data->f_LoadLibrary);
AfxMessageBox(wTxt);*/
}