C++ 特征码搜索
2022-07-02
编译环境:Unicode字符集
编译代码:
#include <stdio.h>
#include <windows.h>
#include <iostream>
#include <string.h>
#include <cstdlib>
#include <Tlhelp32.h>
#include <string>
using namespace std;
//参数分别为:进程句柄、特征码、偏移、读取长度、开始扫描位地置、扫描结束位置
uintptr_t hanshu_dizhi; //记录特征码对应的地址
uintptr_t ScanAddress(HANDLE process, char *markCode, int nOffset, unsigned long dwReadLen = 4, uintptr_t StartAddr = 0x400000, uintptr_t EndAddr = 0x7FFFFFFF, int InstructionLen = 0)
{
//************处理特征码,转化成字节*****************
if (strlen(markCode) % 2 != 0) return 0;
//特征码长度
int len = strlen(markCode) / 2; //获取代码的字节数
//将特征码转换成byte型 保存在m_code 中
BYTE *m_code = new BYTE[len];
for (int i = 0; i < len; i++)
{
//定义可容纳单个字符的一种基本数据类型。
char c[] = { markCode[i * 2], markCode[i * 2 + 1], '\0' };
//将参数nptr字符串根据参数base来转换成长整型数
m_code[i] = (BYTE)::strtol(c, NULL, 16);
}
//每次读取游戏内存数目的大小
const DWORD pageSize = 4096;
// 查找特征码 /
//每页读取4096个字节
BYTE *page = new BYTE[pageSize];
uintptr_t tmpAddr = StartAddr;
//定义和特征码一样长度的标识
int compare_one = 0;
while (tmpAddr <= EndAddr)
{
::ReadProcessMemory(process, (LPCVOID)tmpAddr, page, pageSize, 0); //读取0x400000的内存数据,保存在page,长度为pageSize
//在该页中查找特征码
for (int i = 0; i < pageSize; i++)
{
if (m_code[0] == page[i])//有一个字节与特征码的第一个字节相同,则搜索
{
for (int j = 0; j<len - 1; j++)
{
if (m_code[j + 1] == page[i + j + 1])//比较每一个字节的大小,不相同则退出
{
compare_one++;
}
else
{
compare_one = 0;
break;
}//如果下个对比的字节不相等,则退出,减少资源被利用
}
if ((compare_one + 1) == len)
{
// 找到特征码处理
//赋值时要给初始值,避免冲突
uintptr_t dwAddr = tmpAddr + i + nOffset;
uintptr_t ullRet = 0;
::ReadProcessMemory(process, (void*)dwAddr, &ullRet, dwReadLen, 0);
//cout<<dwAddr<<endl;
//这里的dwAddr已经对应的是搜索到的地址
//地址输出的也是10进制 需要转化为16进制
hanshu_dizhi = dwAddr;//记录地址
if (InstructionLen)
{
ullRet += dwAddr + dwReadLen;
}
return ullRet;
}
}
}
tmpAddr = tmpAddr + pageSize - len;//下一页搜索要在前一页最后长度len 开始查找,避免两页交接中间有特征码搜索不出来
}
return 0;
}
//10到16 用法在下面
/*
int ret = 10;
string result = tentosixteen(ret);
cout << result << endl;
*/
int quzheng(unsigned int tendoc)
{
int qian = tendoc / 16;
return qian;
}
string huanzhi(int numtype)
{
string us = std::to_string(numtype);
if (us == "0")
{
string result = "0";
return result;
}
else if (us == "1")
{
string result = "1";
return result;
}
else if (us == "2")
{
string result = "2";
return result;
}
else if (us == "3")
{
string result = "3";
return result;
}
else if (us == "4")
{
string result = "4";
return result;
}
else if (us == "5")
{
string result = "5";
return result;
}
else if (us == "6")
{
string result = "6";
return result;
}
else if (us == "7")
{
string result = "7";
return result;
}
else if (us == "8")
{
string result = "8";
return result;
}
else if (us == "9")
{
string result = "9";
return result;
}
else if (us == "10")
{
string result = "A";
return result;
}
else if (us == "11")
{
string result = "B";
return result;
}
else if (us == "12")
{
string result = "C";
return result;
}
else if (us == "13")
{
string result = "D";
return result;
}
else if (us == "14")
{
string result = "E";
return result;
}
else if (us == "15")
{
string result = "F";
return result;
}
else if (us == "16")
{
string result = "10";
return result;
}
}
string daoxu(string sixteendoc)
{
int length = strlen(sixteendoc.c_str());
int i = 0;
string ret;
string result;
while (i < length || i == length)
{
ret = sixteendoc.substr(length - i, 1);
result = result + ret;
//cout << ret << endl;
i = i + 1;
}
return result;
}
string tentosixteen(unsigned int tendoc)
{
//int tendoc = 426;
int zhengshu = quzheng(tendoc);
string sixteendoc = "";
while (true)
{
if (zhengshu > 16)
{
int cha = tendoc - zhengshu * 16;
tendoc = zhengshu;
//cout << cha << endl;
string result = huanzhi(cha);
sixteendoc = sixteendoc + result;
zhengshu = quzheng(tendoc);
}
else if (zhengshu == 16)
{
int cha = tendoc - zhengshu * 16;
tendoc = zhengshu;
//cout << cha << endl;
string result = huanzhi(cha);
sixteendoc = sixteendoc + result;
zhengshu = quzheng(tendoc);
}
else
{
int cha = tendoc - zhengshu * 16;
tendoc = zhengshu;
//cout << cha << endl;
//cout << zhengshu << endl;//最后一个整数也是差值
string result1 = huanzhi(cha);
string result2 = huanzhi(zhengshu);
sixteendoc = sixteendoc + result1 + result2;
break;
}
}
string oversixdoc = daoxu(sixteendoc);//这个时候sixteendoc是反着的所以倒序倒为正了
//cout << "oversixdoc:" << oversixdoc << endl;
int length = strlen(oversixdoc.c_str());
string tianchong;
//cout <<"length:" << length << endl;
int i = 8 - length;
while (true)
{
if (i > 0)
{
tianchong = tianchong + "0";
}
else
{
break;
}
i = i - 1;
}
//cout << "tianchong" << tianchong << endl;
string result = tianchong + oversixdoc;
//string result = tianchong + oversixdoc;
return result;
}
//16到10 用法在下面
/*
string typesixteen = "ABCDEFAB";
unsigned int result = sixteentoten(typesixteen);
cout << "结果:" << result << endl;
*/
int beishu(int length)
{
int ji = 1;
int length1 = 7 - length;
int i = 0;
while (true)
{
if (i < length1)
{
ji = ji * 16;
}
else
{
break;
}
i = i + 1;
}
//cout << "ji : " << ji << endl;
return ji;
}
int callback(string ret, int i)
{
unsigned int callback = 1;
//cout << "i:" << i << "ret" << ret << endl;
//cout << "beishu : " << beilv << endl;
if (ret == "0")
{
int beilv = beishu(i);
callback = beilv * 0;
}
else if (ret == "1")
{
int beilv = beishu(i);
callback = beilv * 1;
}
else if (ret == "2")
{
int beilv = beishu(i);
callback = beilv * 2;
}
else if (ret == "3")
{
int beilv = beishu(i);
callback = beilv * 3;
}
else if (ret == "4")
{
int beilv = beishu(i);
callback = beilv * 4;
}
else if (ret == "5")
{
int beilv = beishu(i);
callback = beilv * 5;
}
else if (ret == "6")
{
int beilv = beishu(i);
callback = beilv * 6;
}
else if (ret == "7")
{
int beilv = beishu(i);
callback = beilv * 7;
}
else if (ret == "8")
{
int beilv = beishu(i);
callback = beilv * 8;
}
else if (ret == "9")
{
int beilv = beishu(i);
callback = beilv * 9;
}
else if (ret == "A" || ret == "a")
{
int beilv = beishu(i);
callback = beilv * 10;
}
else if (ret == "B" || ret == "b")
{
int beilv = beishu(i);
callback = beilv * 11;
}
else if (ret == "C" || ret == "c")
{
int beilv = beishu(i);
callback = beilv * 12;
}
else if (ret == "D" || ret == "d")
{
int beilv = beishu(i);
callback = beilv * 13;
}
else if (ret == "E" || ret == "e")
{
int beilv = beishu(i);
callback = beilv * 14;
}
else if (ret == "F" || ret == "f")
{
int beilv = beishu(i);
callback = beilv * 15;
}
return callback;
}
int sixteentoten(string ten)
{
int length = strlen(ten.c_str());
int i = 0;
int answer = 0;
int reback;
string ret;
while (true)
{
if (i < length)
{
ret = ten.substr(i, 1);//获取到了每一个位数上的具体值
reback = callback(ret, i);
answer = answer + reback;
}
else
{
break;
}
i = i + 1;
}
string result = "1";
return answer;
}
/*Char*转TCHAR*/
LPWSTR ConvertCharToLPWSTR(const char* szString)
{
int dwLen = strlen(szString) + 1;
int nwLen = MultiByteToWideChar(CP_ACP, 0, szString, dwLen, NULL, 0);//算出合适的长度
LPWSTR lpszPath = new WCHAR[dwLen];
MultiByteToWideChar(CP_ACP, 0, szString, dwLen, lpszPath, nwLen);
return lpszPath;
}
/*string转LPCWSTR*/
LPCWSTR stringToLPCWSTR(std::string orig)
{
size_t origsize = orig.length() + 1;
const size_t newsize = 100;
size_t convertedChars = 0;
wchar_t *wcstring = (wchar_t *)malloc(sizeof(wchar_t)*(orig.length() - 1));
mbstowcs_s(&convertedChars, wcstring, origsize, orig.c_str(), _TRUNCATE);
return wcstring;
}
int main()
{
cout << "请输入窗口标题:";
string title;
cin >> title;
cout << "请输入特征码(如果不行可以试试切换大小写):";
string special;
cin >> special;
char * specialcode = const_cast<char*>(special.c_str());
cout << "请输入偏移量,如果没有请输入0:";
int move;
cin >> move;
HWND hWnd;
LPCWSTR newititle = ConvertCharToLPWSTR(title.c_str());
hWnd = FindWindow(NULL, newititle);//根据窗口标题获取窗口句柄
DWORD PID;
GetWindowThreadProcessId(hWnd, &PID);//存入PID
HANDLE hprocess;
hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);//获取进程
ScanAddress(hprocess, specialcode, 0);//"获取地址值为多少" 如果输出的地址不对,可以试试特征码的大写和小写的替换
//cout << hanshu_dizhi << endl;//输出地址(10进制)
unsigned int num = hanshu_dizhi;
num = num + move;//相对内存地址偏移量(10进制)
string oversixdoc = tentosixteen(num);//这里已经转换为了16进制的地址
cout << "地址为:" << oversixdoc << endl;//输出地址(10进制)
while (true);
}
发表评论: