直接上我写KingDom Rush外挂的代码,一开始想法是直接在内存中定位到关键汇编代码,直接在内存中改写就可以了。
发现基址和定位的关键汇编地址没有任何联系,可能是随机分配的缘故吧。不过还是纪录一下这种方法
#include<iostream>
#include<windows.h>
#include<TlHelp32.h>
#include<stdio.h>
using namespace std;
bool changeAsm(HANDLE mproc, DWORD pid);
int main()
{
HWND phandle = FindWindow("UnityWndClass","Kingdom Rush");//获取游戏句柄
if (!phandle)
{
MessageBox(NULL, "句柄打开失败!", "Warning!!!", MB_OK);
cout << "没有找到KingDom Rush游戏,请打开!" << endl;
return 0;
}
DWORD pid;
GetWindowThreadProcessId(phandle, &pid);//获取游戏进程id
if (!pid)
{
cout << "获取id失败!" << endl;
return 0;
}
HANDLE mProc = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
if (mProc == NULL)
{
MessageBox(NULL, "请先打开游戏", "warning!", MB_OK);
return 0;
}
changeAsm(mProc, pid);
system("pause");
return 0;
}
//简单更改sub为add
bool changeAsm(HANDLE mproc, DWORD pid)
{
DWORD addressOfChange;//这个因为会变,所有遍历内存中的模块
HANDLE phSnapshot;
MODULEENTRY32 me32;//存放快照信息的结构体
phSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,pid);//创建进程快照
if (phSnapshot == INVALID_HANDLE_VALUE)
{
cout << "遍历失败!" << endl;
return false;
}
//使用之前先设置大小
me32.dwSize = sizeof(MODULEENTRY32);
if (!Module32First(phSnapshot, &me32))
{
cout << "失败!" << endl;
return false;
}
do
{
printf("\n\n MODULE NAME: %s",
me32.szModule);
printf("\n executable = %s",
me32.szExePath);
printf("\n process ID = 0x%08X",
me32.th32ProcessID);
printf("\n ref count (g) = 0x%04X",
me32.GlblcntUsage);
printf("\n ref count (p) = 0x%04X",
me32.ProccntUsage);
printf("\n base address = 0x%08X",
(DWORD)me32.modBaseAddr);
printf("\n base size = %d",
me32.modBaseSize);
if (me32.th32ProcessID == pid)
{
addressOfChange = (DWORD)me32.modBaseAddr;
break;
}
} while (Module32Next(phSnapshot, &me32));
BYTE oldByte;
DWORD dwNum = 0;
if (!ReadProcessMemory(mproc, &addressOfChange, &oldByte, 1, &dwNum))
{
cout << "|读取失败!" << endl;
}
printf("0x%08x\n",addressOfChange);
printf("0x%08x\n", oldByte);
return true;
}
关于进程快照 CreateToolhelp32Snapshot
CreateToolhelp32Snapshot函数为指定的进程、进程使用的堆[HEAP]、模块[MODULE]、线程[THREAD])建立一个快照[snapshot]。
HANDLE WINAPI CreateToolhelp32Snapshot( DWORD dwFlags, //用来指定“快照”中需要返回的对象,可以是TH32CS_SNAPPROCESS等 DWORD th32ProcessID //一个进程ID号,用来指定要获取哪一个进程的快照,当获取系统进程列表或获取当前进程快照时可以设为0 );具体参照API