以下是为了对付CRC检查 自己测试的所有的方法 写成了笔记
规避CRC检查 1:
将调用函数地址 写到别的地址 而不是在函数头进行Hook
这样游戏调用 会调到自己的函数 在自己的函数里 再调用游戏的函数
因为游戏不会再这里检查CRC的 这里又不是代码段
游戏调用 ->MyHUD_Frame ->Engine::g_pClient->HUD_Frame
经过测试发现 并不可以 原因如下
游戏会检查 地址是否在 代码段地址范围之内 不在则游戏掉线 如果你把地址写在代码段 再Jmp到自己的函数 也行不通 这里正好有CRC检查
检查游戏的调用 检查范围 也没发现什么头绪 所以这个方法PASS
规避CRC检查 2:
在检测区 下访问断点 ----断点没来 因为游戏不会检查 是NGS在检查CRC
规避CRC检查 3:
对 NGS进行Hook Radprocessmemory 发现并没有调用 应该是走sysenter 但是当初调用门 没学好..忘了
然后在网上找了一段资料 恶补了一下X64 最后可以Hook了 但是发现 扫描的地址 并没有在游戏范围之内???
那他怎么知道游戏地址被改的?? 分析通讯 然后剥离??? 都被VM 且垃圾代码很多 对于我来说太难了
复制游戏内存到自身进程然后再比对? 测试发现并没有 Pass
检查本地文件 再对游戏的地址 进行比对? 我对client.dll本地文件改写了一处代码 发现还是被检测 Pass
是不是更改内存权限的问题? 发现改了代码再改回权限 也不行 单独改权限 是可以的 那么就不是这里的问题 Pass
没头绪 然后就放弃了
规避CRC检查 4:
上驱动 但是又不能Hook Radprocessmemory 搜索资料 发现可以用VT来监视 但是自己对VT的认识为0
然后到看雪 和GitHub搜资料 勉强找了几分VT源码 但都是单线程 最终找了份多线程的代码 改了改(其实还是复制粘贴) 显然还是没明白原理 管它呢 先拿来用用 EPT 来下 执行异常 (好像是这样吧 ..)
if (pEpt_Attribute->Execute)
{
//DbgBreakPoint();
// Execute Access
for (int i = 0;i < g_nEptHookCount;i++)
{
if ((ULONG64)g_EptHookItems[i].pHookedVA == uGuestRIP)
{
if (!g_EptHookItems[i].bDisabled)
{
//KdPrint(("From 0x%p to 0x%p.\n", uGuestRIP, g_EptHookItems[i].pJmpVA));
Vmx_VmWrite(GUEST_RIP, (ULONG64)g_EptHookItems[i].pJmpVA);
}
g_EptHookItems[i].nHitCount++;
}
if (g_EptHookItems[i].pPte == pPte)
{
g_EptRewatch[uCPUID] = SetRewathInfo(pPte, g_EptHookItems[i].pOldPte, (PVOID64)Guest_PA.QuadPart);
}
}
}
上游戏 exe测试 Hook了一个地址 发现确实可以 没有非法 然后赶紧全部写成这样的Hook方式
实际测试发现 并没有Hook成功???? 经过排除 发现并不能对自身进程Hook 需要在写个外部进程 en.....那就继续写呗
实现方式 DLL给注入发送事件通讯 让注入器Hook 就可以了
if (Anti_CheckVT())
{
if (!g_Validate.DLLInit())
return;
LPSTR lpBuff = g_Validate.GetBuff();
*(PDWORD)lpBuff = 1;
// Hook 初始化
TAG_ANTI_DATA_DLL_INFO Data;
Data.dwPid = GetCurrentProcessId();
Data.dwNewAddress = (DWORD)HUD_Frame;
Data.dwOldAddress = (DWORD)Engine::g_pClient->HUD_Frame;
RtlCopyMemory((PVOID)((DWORD)lpBuff + 4), &Data, sizeof(TAG_ANTI_DATA_DLL_INFO));
//Hook CL_IsThirdPerson
Data.dwNewAddress = (DWORD)CL_IsThirdPerson;
Data.dwOldAddress = (DWORD)Engine::g_pClient->CL_IsThirdPerson;
RtlCopyMemory((PVOID)((DWORD)lpBuff + 4 + (sizeof(TAG_ANTI_DATA_DLL_INFO) * 1)), &Data, sizeof(TAG_ANTI_DATA_DLL_INFO));
//Hook HUD_PostRunCmd
Data.dwNewAddress = (DWORD)HUD_PostRunCmd;
Data.dwOldAddress = (DWORD)Engine::g_pClient->HUD_PostRunCmd;
RtlCopyMemory((PVOID)((DWORD)lpBuff + 4 + (sizeof(TAG_ANTI_DATA_DLL_INFO) * 2)), &Data, sizeof(TAG_ANTI_DATA_DLL_INFO));
//HUD_Redraw
Data.dwNewAddress = (DWORD)HUD_Redraw;
Data.dwOldAddress = (DWORD)Engine::g_pClient->HUD_Redraw;
RtlCopyMemory((PVOID)((DWORD)lpBuff + 4 + (sizeof(TAG_ANTI_DATA_DLL_INFO) * 3)), &Data, sizeof(TAG_ANTI_DATA_DLL_INFO));
//Hook CL_CreateMove
Data.dwNewAddress = (DWORD)CL_CreateMove;
Data.dwOldAddress = (DWORD)Engine::g_pClient->CL_CreateMove;
RtlCopyMemory((PVOID)((DWORD)lpBuff + 4 + (sizeof(TAG_ANTI_DATA_DLL_INFO) * 4)), &Data, sizeof(TAG_ANTI_DATA_DLL_INFO));
//Hook V_CalcRefdef
Data.dwNewAddress = (DWORD)V_CalcRefdef;
Data.dwOldAddress = (DWORD)Engine::g_pClient->V_CalcRefdef;
RtlCopyMemory((PVOID)((DWORD)lpBuff + 4 + (sizeof(TAG_ANTI_DATA_DLL_INFO) * 5)), &Data, sizeof(TAG_ANTI_DATA_DLL_INFO));
//Hook HUD_Key_Event
Data.dwNewAddress = (DWORD)HUD_Key_Event;
Data.dwOldAddress = (DWORD)Engine::g_pClient->HUD_Key_Event;
RtlCopyMemory((PVOID)((DWORD)lpBuff + 4 + (sizeof(TAG_ANTI_DATA_DLL_INFO) * 6)), &Data, sizeof(TAG_ANTI_DATA_DLL_INFO));
//Hook HUD_AddEntity
Data.dwNewAddress = (DWORD)HUD_AddEntity;
Data.dwOldAddress = (DWORD)Engine::g_pClient->HUD_AddEntity;
RtlCopyMemory((PVOID)((DWORD)lpBuff + 4 + (sizeof(TAG_ANTI_DATA_DLL_INFO) * 7)), &Data, sizeof(TAG_ANTI_DATA_DLL_INFO));
//
//Hook HUD_PlayerMove
Data.dwNewAddress = (DWORD)HUD_PlayerMove;
Data.dwOldAddress = (DWORD)Engine::g_pClient->HUD_PlayerMove;
RtlCopyMemory((PVOID)((DWORD)lpBuff + 4 + (sizeof(TAG_ANTI_DATA_DLL_INFO) * 8)), &Data, sizeof(TAG_ANTI_DATA_DLL_INFO));
//Hook 骨骼
/*Data.dwNewAddress = (DWORD)StudioDrawPoints;
Data.dwOldAddress = (DWORD)Engine::g_pStudio->StudioDrawPoints;
RtlCopyMemory((PVOID)((DWORD)lpBuff + 4 + (sizeof(TAG_ANTI_DATA_DLL_INFO) * 9)), &Data, sizeof(TAG_ANTI_DATA_DLL_INFO));*/
取骨骼
//Data.dwNewAddress = (DWORD)StudioEntityLight;
//Data.dwOldAddress = (DWORD)Engine::g_pStudio->StudioEntityLight;
//RtlCopyMemory((PVOID)((DWORD)lpBuff + 4 + (sizeof(TAG_ANTI_DATA_DLL_INFO) * 9)), &Data, sizeof(TAG_ANTI_DATA_DLL_INFO));
}
SetEvent(g_Validate.GetEventExe());
//-------------------------------------------------等待中----------------------------------
while (true)
{
WaitForSingleObject(g_Validate.GetEventDll(), INFINITE);
MessageBox(0, "提交完毕", 0, 0);
break;
}
EXE
void Validate::StartExe()
{
if (!hEvent)
{
hEvent = OpenEventA(EVENT_ALL_ACCESS, false, "Global\\TEXT");
}
//Hook的数量
DWORD dwSize = *(PDWORD)lpBuff;
for (int i = 0; i < dwSize; i++)
{
PTAG_ANTI_DATA_DLL_INFO pHookData = (PTAG_ANTI_DATA_DLL_INFO)(lpBuff + 4 + (sizeof(TAG_ANTI_DATA_DLL_INFO)*i));
DWORD dwOldAddes = pHookData->dwOldAddress;
DWORD dwNewAddes = pHookData->dwNewAddress;
DWORD dwPid = pHookData->dwPid;
if (AntiProtecPassCRC(dwPid, dwOldAddes, dwNewAddes) == -1)
{
//失败了 改写错误码
*(PDWORD)lpBuff = 0x0;
//通知DLL
SetEvent(hEvent);
return;
}
}
//hook 完成
*(PDWORD)lpBuff = 0x1;
SetEvent(hEvent);
return;
}
测试开始 上游戏 开始游戏 30秒直接蓝屏了?? 心态蹦了 太累了躺床上想想原因吧