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); }
发表评论: