Sna1lGo

网络游戏逆向分析-9-自动更新基址

网络游戏逆向分析-9-自动更新基址

基址在每次更新之后都会修改,这个比较麻烦,不然每次都得重新找,非常消耗体力和时间。

 

自动更新基址原理

搜索游戏进程的内存,然后把硬编码依次和内存里面数据进行匹配,匹配到了之后就返回地址,地址附近就是基址了,通过加减来得到基址。

这里要扯到一些关于硬编码和机器指令的问题了,从整个计算机来看实际上要跑的东西在CPU上,只能识别0和1,但是为了后面的多种多样功能,通过对0和1的组合来实现了机器指令,CPU可以直接通过这个0和1的指令来进行不同的操作,这个指令就叫做机器指令也可以说是硬编码(也就是硬件上的编码)根据CPU的不同而不同,而我们常用的汇编指令,是唯一一个可以和机器指令一一对应的东西,因为如果直接用机器指令对于开发来说非常非常麻烦。所以我们常用的是汇编语言,而我们通过一些Ollydbg,xdbg这些东西,都是通过CPU里用的机器指令翻译成的汇编指令,这个流程的工具叫做反汇编引擎,比如说:

 

 

这个ollydbg里面的1是内存地址,2是机器码的内容,3是汇编指令的内容。实际上运行的是内存地址里面存放的机器码,只不过这个调试器帮我们翻译成了汇编指令,然后我们修改汇编指令的时候也帮我们修改了机器码这样子。

自动更新基址思路

所以这里我们可以参考机器码,我们把整个内存的机器码读出来,然后通过机器码比对得到对应的有关地址的机器码指令,然后转成字符串,读取得到基址。

开始

这里我们随便用一段东西把:

 

 

需要注意的是,这里的机器码尽量多弄一下,这样来达到机器码是唯一的别的地方不能会重复。

逻辑都在代码里面了:

#include"UpdateAddr.h"

BOOL ByteToChar(BYTE* ByteArray, char* CharArray, int ByteLen)
{
//ByteArray是字节数组
//CharArray是字符数组
//ByteLen 是字节数组长度
for (int i = 0; i < ByteLen; i++)
{
wsprintfA(&CharArray[i * 2], "%02X", ByteArray[i]);
}


return TRUE;
}
BOOL CmpMachineStr(char* TempReadMachineCodeStr,char* MachineCodeStr, int MachineCodeStrLen)
{
// TempReadMachineCodeStr 读取的机器码字符串
// MachineCodeStr 特征机器码字符串
//MachineCodeStrLen特征机器码字符串长度
for (int i = 0; i < MachineCodeStrLen; i++)
{
if (TempReadMachineCodeStr[i] != MachineCodeStr[i])
return FALSE;
}
return TRUE;
}
BOOL ScanProcess(HANDLE HandleProcess, DWORD BeginAddr, DWORD EndAddr, char* MachineCodeStr, int MachineCodeStrLen)
{
//HandleProcess是进程的句柄,BeginAddr是起始内存地址,EndAddr是结束内存地址,MachineCode是机器码的字符串表达形式
//MachineCodeLen是机器码字符串长度。
int Flag = 0;

//每次读取0x1000个机器码的内容进行比较。
BYTE TempReadMachineCode[0x1000] = { 0 };
for (DWORD TempBeginAddr = BeginAddr; TempBeginAddr < EndAddr - 0x1000; TempBeginAddr += (0x1000 - MachineCodeStrLen))
{
//将机器码缓冲区用0填充
memset(TempReadMachineCode, 0x0, 0x1000);
//读0x1000个机器码到byte缓冲数组里。
BOOL RetReadProcessMemory = ReadProcessMemory(HandleProcess,(LPVOID)TempBeginAddr,TempReadMachineCode, 0x1000, NULL);
if (RetReadProcessMemory == 0)
continue;

//把byte字节数组转换成字符串
char TempReadMachineCodeStr[0x2001]={ 0 };
ByteToChar(TempReadMachineCode, TempReadMachineCodeStr, 0x1000);

//开始比较
for (int

分类:

技术点:

相关文章: