C/C++实现简易特征码扫描器
扫描特征码基地址
#include <stdio.h> #include <stdlib.h> #include <windows.h>union Base
4];
{
DWORD address;
BYTE data[
}; /*****************************************************************/
/ 函数说明:根据特征码扫描基址
/* 参数一:process 要查找的进程
/* 参数二:markCode 特征码字符串,不能有空格
/* 参数三:特征码离基址的距离,默认距离:1
/* 参数四:findMode 扫描方式,找到特征码后,默认为:1
/* 0:往上找基址(特征码在基址下面)
/* 1:往下找基址(特征码在基址上面)
/* 参数五:offset 保存基址距离进程的偏移,默认为:不保存
/********************************************************************/
DWORD ScanAddress(HANDLE process, char *markCode, DWORD distinct = 1, DWORD findMode = 1, LPDWORD offset = NULL)
{
//起始地址
const DWORD beginAddr = 0x00400000;
//结束地址
const DWORD endAddr = 0x7FFFFFFF;
//每次读取游戏内存数目的大小
const DWORD pageSize = 4096;</span><span style="color: #808080;">////////////////////////</span><span style="color: #008000;">处理特征码</span><span style="color: #808080;">/////////////////////</span> <span style="color: #008000;">//</span><span style="color: #008000;">特征码长度不能为单数 </span> <span style="color: #0000ff;">if</span> (strlen(markCode) % <span style="color: #800080;">2</span> != <span style="color: #800080;">0</span>) <span style="color: #0000ff;">return</span> <span style="color: #800080;">0</span><span style="color: #000000;">; </span><span style="color: #008000;">//</span><span style="color: #008000;">特征码长度 </span> <span style="color: #0000ff;">int</span> len = strlen(markCode) / <span style="color: #800080;">2</span><span style="color: #000000;">; </span><span style="color: #008000;">//</span><span style="color: #008000;">将特征码转换成byte型 </span> BYTE *m_code = <span style="color: #0000ff;">new</span><span style="color: #000000;"> BYTE[len]; </span><span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = <span style="color: #800080;">0</span>; i < len; i++<span style="color: #000000;">){ </span><span style="color: #0000ff;">char</span> c[] = { markCode[i * <span style="color: #800080;">2</span>], markCode[i * <span style="color: #800080;">2</span> + <span style="color: #800080;">1</span>], <span style="color: #800000;">'</span><span style="color: #800000;">\0</span><span style="color: #800000;">'</span><span style="color: #000000;"> }; </span>*m_code = (BYTE)::strtol(c, NULL, <span style="color: #800080;">16</span><span style="color: #000000;">); } </span><span style="color: #808080;">////////////////////////</span><span style="color: #008000;">/查找特征码</span><span style="color: #808080;">/////////////////////</span> BOOL _break =<span style="color: #000000;"> FALSE; </span><span style="color: #008000;">//</span><span style="color: #008000;">用来保存在第几页中的第几个找到的特征码 </span> <span style="color: #0000ff;">int</span> curPage = <span style="color: #800080;">0</span><span style="color: #000000;">; </span><span style="color: #0000ff;">int</span> curIndex = <span style="color: #800080;">0</span><span style="color: #000000;">; Base </span><span style="color: #0000ff;">base</span><span style="color: #000000;">; </span><span style="color: #008000;">//</span><span style="color: #008000;">每页读取4096个字节 </span>
BYTE page[pageSize];
DWORD tmpAddr = beginAddr;
while (tmpAddr <= endAddr - len)
{
::ReadProcessMemory(process, (LPCVOID)tmpAddr, &page, pageSize, 0);</span><span style="color: #008000;">//</span><span style="color: #008000;">在该页中查找特征码 </span> <span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = <span style="color: #800080;">0</span>; i < pageSize; i++<span style="color: #000000;">) { </span><span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> j = <span style="color: #800080;">0</span>; j < len; j++<span style="color: #000000;">) { </span><span style="color: #008000;">//</span><span style="color: #008000;">只要有一个与特征码对应不上则退出循环 </span> <span style="color: #0000ff;">if</span> (m_code[j] != page[i + j])<span style="color: #0000ff;">break</span><span style="color: #000000;">; </span><span style="color: #008000;">//</span><span style="color: #008000;">找到退出所有循环 </span> <span style="color: #0000ff;">if</span> (j == len - <span style="color: #800080;">1</span><span style="color: #000000;">){ _break </span>=<span style="color: #000000;"> TRUE; </span><span style="color: #0000ff;">if</span> (!<span style="color: #000000;">findMode) { curIndex </span>=<span style="color: #000000;"> i; </span><span style="color: #0000ff;">base</span>.data[<span style="color: #800080;">0</span>] = page[curIndex - distinct - <span style="color: #800080;">4</span><span style="color: #000000;">]; </span><span style="color: #0000ff;">base</span>.data[<span style="color: #800080;">1</span>] = page[curIndex - distinct - <span style="color: #800080;">3</span><span style="color: #000000;">]; </span><span style="color: #0000ff;">base</span>.data[<span style="color: #800080;">2</span>] = page[curIndex - distinct - <span style="color: #800080;">2</span><span style="color: #000000;">]; </span><span style="color: #0000ff;">base</span>.data[<span style="color: #800080;">3</span>] = page[curIndex - distinct - <span style="color: #800080;">1</span><span style="color: #000000;">]; } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> { curIndex </span>= i +<span style="color: #000000;"> j; </span><span style="color: #0000ff;">base</span>.data[<span style="color: #800080;">0</span>] = page[curIndex + distinct + <span style="color: #800080;">1</span><span style="color: #000000;">]; </span><span style="color: #0000ff;">base</span>.data[<span style="color: #800080;">1</span>] = page[curIndex + distinct + <span style="color: #800080;">2</span><span style="color: #000000;">]; </span><span style="color: #0000ff;">base</span>.data[<span style="color: #800080;">2</span>] = page[curIndex + distinct + <span style="color: #800080;">3</span><span style="color: #000000;">]; </span><span style="color: #0000ff;">base</span>.data[<span style="color: #800080;">3</span>] = page[curIndex + distinct + <span style="color: #800080;">4</span><span style="color: #000000;">]; } </span><span style="color: #0000ff;">break</span><span style="color: #000000;">; } } </span><span style="color: #0000ff;">if</span> (_break) <span style="color: #0000ff;">break</span><span style="color: #000000;">; } </span><span style="color: #0000ff;">if</span> (_break) <span style="color: #0000ff;">break</span><span style="color: #000000;">; curPage</span>++<span style="color: #000000;">; tmpAddr </span>+=<span style="color: #000000;"> pageSize; } </span><span style="color: #0000ff;">if</span> (offset !=<span style="color: #000000;"> NULL) { </span>*offset = curPage * pageSize + curIndex +<span style="color: #000000;"> beginAddr; } </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">base</span><span style="color: #000000;">.address;
}
int main(int argc, char* argv[])
{
//查找游戏窗口
HWND hGame = ::FindWindow(“DxFirst“, NULL);
if (hGame == NULL) return FALSE;DWORD processId; HANDLE process; </span><span style="color: #008000;">//</span><span style="color: #008000;"> 得到PID</span> ::GetWindowThreadProcessId(hGame, &<span style="color: #000000;">processId); process </span>= ::OpenProcess(PROCESS_ALL_ACCESS, <span style="color: #0000ff;">false</span><span style="color: #000000;">, processId); </span><span style="color: #008000;">//</span><span style="color: #008000;"> 基址在特征码下面</span> DWORD addr = ScanAddress(process, <span style="color: #800000;">"</span><span style="color: #800000;">83C404C3CCCCA1</span><span style="color: #800000;">"</span><span style="color: #000000;">); printf(</span><span style="color: #800000;">"</span><span style="color: #800000;">人物基址:%X\n</span><span style="color: #800000;">"</span><span style="color: #000000;">, addr); </span><span style="color: #008000;">//</span><span style="color: #008000;">基址在特征码上面 </span> addr = ScanAddress(process, <span style="color: #800000;">"</span><span style="color: #800000;">C3CCCCCCCCCCCCCCCCCCCC8B442404A3ECA72001</span><span style="color: #800000;">"</span>, <span style="color: #800080;">3</span>, <span style="color: #800080;">0</span><span style="color: #000000;">); printf(</span><span style="color: #800000;">"</span><span style="color: #800000;">人物基址:%X\n</span><span style="color: #800000;">"</span><span style="color: #000000;">, addr); ::CloseHandle(process); </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">0</span><span style="color: #000000;">;
}
扫描关键CALL
#include <stdio.h> #include <stdlib.h> #include <windows.h>union Base
4];
{
DWORD address;
BYTE data[
}; /********************************************************************/
/ 函数说明:根据特征码扫描call地址
/* 参数一:process 要查找的进程
/* 参数二:markCode 特征码字符串,不能有空格
/* 参数三:特征码离基址的距离,默认距离:1
/* 参数四:findMode 扫描方式,找到特征码后,默认为:1
/* 0:往上找基址
/* 1:往下找基址
/***********************************************************************/
DWORD ScanCall(HANDLE process, char *markCode,
DWORD distinct = 1, DWORD findMode = 1)
{
DWORD offset;
DWORD call = ScanAddress(process, markCode, distinct, findMode, &offset);
call += offset;
if (findMode) call = call + 5 + distinct;
else call = call - distinct;
return call;
} int main(int argc, char* argv[])
{
DWORD call = ScanCall(process, “5557535152C6400801E8“);
printf(“call基址:%X\n“, call);::CloseHandle(process); </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">0</span><span style="color: #000000;">;
}