#include "Windows.h"
#include "tlhelp32.h"
#include "String.h"
#include "Shlwapi.h"
#include "iostream"
using namespace std;
HANDLE hProcess;
LPVOID lp_address;
LPVOID lp_ret_value_address;
DWORD lp_ret_jmp;
DWORD lp_to_jmp;
template <typename T>
T Read(LPVOID Address)
{
T Data;
ReadProcessMemory(hProcess, (LPVOID)Address, &Data, sizeof(T), nullptr);
return Data;
}
uintptr_t FindPattern(uintptr_t start, uintptr_t length, const unsigned char* pattern, const char* mask)
{
size_t pos = 0;
auto maskLength = strlen(mask) - 1;
auto startAdress = start;
for (auto it = startAdress; it < startAdress + length; ++it)
{
if (Read<unsigned char>(LPVOID(it)) == pattern[pos] || mask[pos] == '?')
{
if (mask[pos + 1] == ' ')
return it - maskLength;
pos++;
}
else pos = 0;
}
return 0;
}
//特征码寻址
uintptr_t FindPattern(HMODULE hModule, const unsigned char* pattern, const char* mask)
{
IMAGE_DOS_HEADER DOSHeader = Read<IMAGE_DOS_HEADER>(hModule);
IMAGE_NT_HEADERS NTHeaders = Read<IMAGE_NT_HEADERS>(LPVOID(uintptr_t(hModule) + DOSHeader.e_lfanew));
return FindPattern(
reinterpret_cast<uintptr_t>(hModule) + NTHeaders.OptionalHeader.BaseOfCode,
reinterpret_cast<uintptr_t>(hModule) + NTHeaders.OptionalHeader.SizeOfCode, pattern, mask);
}
HMODULE GetProcessModuleHandleByName(DWORD pid, LPCSTR ModuleName)
{
MODULEENTRY32 ModuleInfo;
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);
if (!hSnapshot)
{
return 0;
}
ZeroMemory(&ModuleInfo, sizeof(MODULEENTRY32));
ModuleInfo.dwSize = sizeof(MODULEENTRY32);
if (!Module32First(hSnapshot, &ModuleInfo))
{
return 0;
}
do
{
if (!lstrcmpi(ModuleInfo.szModule, ModuleName))
{
CloseHandle(hSnapshot);
return ModuleInfo.hModule;
}
} while (Module32Next(hSnapshot, &ModuleInfo));
CloseHandle(hSnapshot);
return 0;
}
DWORD GetProcessIDByName(const char* pName)
{
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (INVALID_HANDLE_VALUE == hSnapshot) {
return NULL;
}
PROCESSENTRY32 pe = { sizeof(pe) };
for (BOOL ret = Process32First(hSnapshot, &pe); ret; ret = Process32Next(hSnapshot, &pe)) {
if (strcmp(pe.szExeFile, pName) == 0) {
CloseHandle(hSnapshot);
return pe.th32ProcessID;
}
//printf("%-6d %sn", pe.th32ProcessID, pe.szExeFile);
}
CloseHandle(hSnapshot);
return 0;
}
//内联汇编被写入
inline __declspec(naked) void ret_hook()
{
__asm
{
mov edi,edi
push ebp
mov ebp,esp
mov edx, edi
}
}
int main()
{
SetConsoleTitleA("[Pass CRC ~《终结者2:审判日》 1.123311.297055 ] ");
DWORD OldProtect = NULL;
int Pid = GetProcessIDByName("zjz.exe");
hProcess = INVALID_HANDLE_VALUE;
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, Pid);//游戏进程句柄
cout << "进程ID:" << Pid << endl << endl << "进程句柄:" << hProcess << endl << endl;
lp_address = VirtualAllocEx(hProcess, NULL, 128, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
//cout << "分配的写入hook的地址:" << lp_address << hex << endl;
//bcryptPrimitives.dll+24AFF - CC - int 3
HMODULE hbcryptPrimitives = GetProcessModuleHandleByName(Pid, "bcryptPrimitives.dll");
//这边自己搞检测地址
lp_ret_jmp = (DWORD)hbcryptPrimitives + 0x24B05;
lp_to_jmp = (DWORD)hbcryptPrimitives + 0x24B00;
//cout << "跳回的地址计算:" << lp_ret_jmp << endl;
/*写ret hook*/
if (WriteProcessMemory(hProcess, lp_address, ret_hook, 50, NULL) != 0) {
//cout << "写入成功!" << endl;
BYTE jmp_e9 = { 0xe9 };
WriteProcessMemory(hProcess, (LPVOID)((DWORD)lp_address + 0x7), (LPVOID)&jmp_e9, 1, NULL);
int jmp_ret = (int)lp_ret_jmp - ((DWORD)lp_address + 0x7) - 5;
WriteProcessMemory(hProcess, (LPVOID)((DWORD)lp_address + 0x8), (LPVOID)&jmp_ret, 4, NULL);
/*to hook*/
BYTE jmp_to_e9 = { 0xe9 };
WriteProcessMemory(hProcess, (LPVOID)lp_to_jmp, (LPVOID)&jmp_to_e9, 1, NULL);
int jmp_to_hook = (int)lp_address - lp_to_jmp - 5;
WriteProcessMemory(hProcess, (LPVOID)(lp_to_jmp + 0x1), (LPVOID)&jmp_to_hook, 4, NULL);
}
/*ret jmp*/
cout << "CRC检测已经成功过掉!请尽情开启功能玩耍!" << endl << endl;
cout << "微信i-xiaodi 游戏逆向信息安全-xd团队" << endl << endl;
cout << "网易云课堂搜索 “游戏逆向的故事” ,关注我们!了解更多内部视频产品!" << endl;
getchar();
return 0;
}
有同学问的特征码寻址,大致调用方法如下:
//uintptr_t Fnd = FindPattern(hModule, (const unsigned char*)"x8BxFFx55x8BxECx81xECxC4x00x00x00xA1",
//"xxxxxxxxxxxx");
关键字:“FindPattern”,外网有很多大佬写,不同的方式都可以,大家可以自己封装,上面代码为我自己封装的,可能会出现一些问题在所难免。
原文链接: https://www.cnblogs.com/Rehacker/p/12370454.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/193660
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!