C/C++实现简易特征码扫描器

扫描特征码基地址

#include <stdio.h>  
#include <stdlib.h>  
#include <windows.h> 

union Base
{
DWORD address;
BYTE data[4];
};

/*****************************************************************/
/
函数说明:根据特征码扫描基址
/* 参数一: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 &lt; 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 &lt; 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 &lt; 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, &amp;<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
{
DWORD address;
BYTE data[4];
};

/********************************************************************/
/
函数说明:根据特征码扫描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;">;

}