好友
阅读权限20
听众
最后登录1970-1-1
|
本帖最后由 blbljj008 于 2023-6-28 22:12 编辑
不做gif动画演示了,只分享代码和原理
第一步:硬件断点的实现源码硬件执行断点源码
//添加一个按钮启动硬件执行断点
void CPAGE00::OnBnClickedButton72()
{
//添加VEH异常处理
AddVectoredExceptionHandler(1, (PVECTORED_EXCEPTION_HANDLER)VehExceptionFilter);
//设置硬件执行断点
SetBreakPointHook();
}
//发生硬件访问断点时候的异常处理过程,我不是程序猿,copy的代码,这部分网上的资料较多,可以自己查阅。
LONG NTAPI VehExceptionFilter(PEXCEPTION_POINTERS ExceptionInfo)
{
//判断当前异常码是否为硬件断点异常
if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP)
{
//判断发生异常的地址是否和hook的地址一致
if ((DWORD)ExceptionInfo->ExceptionRecord->ExceptionAddress == 0x0050B723)
{
//读取或者设置异常位置的信息,可以做一些事情
//异常处理完成 让程序继续执行
return EXCEPTION_CONTINUE_EXECUTION;
}
}
return EXCEPTION_CONTINUE_SEARCH;
}
//设置硬件执行断点在判断所属的函数位置
void SetBreakPointHook()
{
//遍历线程 通过openthread获取到线程环境后设置硬件断点
HANDLE hTool32 = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (hTool32 != INVALID_HANDLE_VALUE)
{
//线程环境结构体
THREADENTRY32 thread_entry32;
thread_entry32.dwSize = sizeof(THREADENTRY32);
HANDLE hHookThread = NULL;
//遍历线程
if (Thread32First(hTool32, &thread_entry32))
{
do
{
//如果线程父进程ID为当前进程ID
if (thread_entry32.th32OwnerProcessID == GetCurrentProcessId())
{
hHookThread = OpenThread(THREAD_SET_CONTEXT | THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION, FALSE, thread_entry32.th32ThreadID);
//暂停线程
SuspendThread(hHookThread);
//设置硬件断点在判断所属的函数位置
CONTEXT thread_context = { CONTEXT_DEBUG_REGISTERS };
thread_context.Dr0 = 0x0050B723;
thread_context.Dr7 = 0x405;
SetThreadContext(hHookThread, &thread_context);
//恢复线程
ResumeThread(hHookThread);
CloseHandle(hHookThread);
}
} while (Thread32Next(hTool32, &thread_entry32));
}
CloseHandle(hTool32);
}
}
第二步:介绍控制所有坦克的代码以及代码修改
当你控制坦克的时候,就会判断坦克的所属,是自己的可以控制,不是自己的就不可以控制,实现这个功能的就是0050B6F0子函数,下面解析它的代码。
0050B6F0 mov eax,dword ptr ds:[0xA8B238]
0050B6F5 test eax,eax
0050B6F7 jnz short gamemd.0050B716
0050B6F9 mov al,byte ptr ds:[ecx+0x1EC]
0050B6FF test al,al
0050B701 jnz short gamemd.0050B710
0050B703 mov al,byte ptr ds:[ecx+0x1ED]
0050B709 test al,al
0050B70B jnz short gamemd.0050B710
0050B70D xor eax,eax
0050B70F retn
0050B710 mov eax,0x1
0050B715 retn
0050B716 mov edx,dword ptr ds:[0xA83D4C] 读取本机所属
0050B71C xor eax,eax
0050B71E cmp ecx,edx 比较所选的坦克是否是本机的坦克
0050B720 sete al 返回al 0=不是本机 1=是本机的坦克
0050B723 retn
我以前的方式是直接修改代码,比较直接暴力。
0050B6F0 mov eax,1
0050B6F5 retn
第三步:利用硬件断点开挂控制所有坦克
在判断所属函数返回的位置下硬件断点,每到执行到此处的时候就断下,通过异常处理函数就可以改变eax返回值达到改写返回值的目的,这样是不改变原游戏代码的。
0050B723 retn
那么重写上上面的异常处理函数
//发生硬件访问断点时候的异常处理过程
LONG NTAPI VehExceptionFilter(PEXCEPTION_POINTERS ExceptionInfo)
{
//判断当前异常码是否为硬件断点异常
if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP)
{
//判断发生异常的地址是否和hook的地址一致
if ((DWORD)ExceptionInfo->ExceptionRecord->ExceptionAddress == 0x0050B723)
{
//修改判断所属函数的返回值,实现控制所有坦克
ExceptionInfo->ContextRecord->Eax = 1;
//异常处理完成 让程序继续执行
return EXCEPTION_CONTINUE_EXECUTION;
}
}
return EXCEPTION_CONTINUE_SEARCH;
} |
免费评分
-
查看全部评分
|
发帖前要善用【论坛搜索】功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。 |
|
|
|
|