能力值:
( LV12,RANK:760 )
|
-
-
2 楼
设置断点需要遍历全部线程,每个线程都要设置一次。
|
能力值:
( LV8,RANK:130 )
|
-
-
3 楼
其实如果某个或者多个函数被处理了,遍历所有的线程也不会触发异常! 其实drx可以有全局的硬件断点,不需要遍历所有线程!
|
能力值:
( LV13,RANK:388 )
|
-
-
4 楼
异常时eip是0x004465D0
ExceptionInfo->ContextRecord->Eip += 0x004467E2;
这里+= 完了就是0x004465D0+0x004467E2了
改成=吧
+=是offset
|
能力值:
( LV13,RANK:388 )
|
-
-
5 楼
这个问题我是这么考虑的
我改了 导入表 所以dll是加载的时候就加载进去了
这样的话,新起的线程都会有DLL_THREAD_ATTACH消息,这时候再set一下,理论上所有线程都会设置好
你说的是dr7的g0位吧,这个全局有效不知道是什么意思,不过好像不是对所有线程都有效的意思
|
能力值:
( LV2,RANK:10 )
|
-
-
6 楼
那就是说我这样子直接注入DLL是不能设置DRX硬件断点成功的吗?
还需要修改导入表吗?具体是指修改导入表哪个地方呢?
DRX全局硬件又是如何设置呢?
|
能力值:
( LV2,RANK:10 )
|
-
-
7 楼
异常时eip是0x004465D0
ExceptionInfo->ContextRecord->Eip += 0x004467E2; 这里+= 完了就是0x004465D0+0x004467E2了
改成=吧 +=是offset
这个地方不是关键问题,现在关键的问题是,我设置的DRX硬件断点无论如何都没有成功断下来
多谢bitt和liuqiangni以及cvcvxk几位大哥的解答,但小弟的问题还没弄明白!
能再具体一点吗,或者有其他资料可以指一条路吗
|
能力值:
( LV2,RANK:10 )
|
-
-
8 楼
要open thread
才能操作线程
|
能力值:
( LV9,RANK:330 )
|
-
-
9 楼
硬件断点线程相关,每个线程都需要设置.
dll注入中设置硬件断点,当前的线程是你执行dll注入的线程,并非程序主线程,或者执行
ctx.Dr0 = 0x004465D0;
的线程.
|
能力值:
( LV2,RANK:10 )
|
-
-
10 楼
总算碰到了把这个思路公布出来的了;硬断内存补丁是躲避内存扫描的一项利器。
要特别注意的地方是线程的上下文,时刻要清楚的知道当前所运行的线程是哪一个。
SetThreadContext:
Do not try to set the context for a running thread; the results are unpredictable.
这是CSDN 上的对SetThreadContext 解释。
尤其是对自身的上下文进行设置,这很可能使得自身线程崩溃或者得不到想要的结果
历遍所有线程,SuspendThread,然后SetThreadContext ,再 ResumeThread ,同时排除自身线程。
至于全局硬断起不起作用,你想一下如果起作用会有什么后果就知道了,所以不用指望
|
能力值:
( LV2,RANK:10 )
|
-
-
11 楼
说错了,不是CSDN,是MSDN。其实关于Win32API 最权威的资料就是MSDN Library,楼主多看看
|
能力值:
( LV2,RANK:10 )
|
-
-
12 楼
历遍所有线程,SuspendThread,然后SetThreadContext ,再 ResumeThread ,同时排除自身线程。
那DLL注入的方式不就不可以实现了吗
|
能力值:
( LV2,RANK:10 )
|
-
-
13 楼
你的方法是对的!
因为我在2年前我就已经做过VEH向量型异常处理机制,所以我想告想讲2点你为什么不能实现VEH,不能实现硬件断点。
一 注入本身有问题,因为远程进程注入是对进程创建一条新的执行线程,所以你这个DLL是新的线程,不是游戏里面的主线程,GetCurrentThread(),取到的是自身的线程,不是主线程,所以你对自己的线程下断硬件断点根本就没有反应是正常的,你还没有理解什么是线程环境!请查看MSND,最好百度一下。
解决方法两种:
1 取消远程注入DLL方式采用消息钩子注入,消息钩子注入注入游戏主线程里面。
2 远程注入也可以,要遍历所有游戏进程所有线程,对每个线程下硬件断点,OD的硬件断点是这么实现的。
二 操作进程要openprocess 那操作线程也是要openthread,一样原理的,为什么TP人家要HOOK两个地方,一个是ntopenprocess,防止读写内存,一个ntopenthread,防止操作线程,例如暂停线程,结束线程,还有控制线程结构环境
下面附送上一段delphi 代码
rtlAddVectoredExceptionHandler(2311,@VectoredHandler);//安装向量异常处理机制
hThread:=OpenThread(THREAD_SUSPEND_RESUME or THREAD_SET_CONTEXT,false, GetCurrentThreadId());
SuspendThread( hThread );
ctx.ContextFlags :=CONTEXT_DEBUG_REGISTERS ; // 这里要设置线程标志为
BPadress:=strtoint('$'+Edit2.Text);
ctx.Dr0 :=BPadress;
ctx.Dr7 :=$401;
SetThreadContext(hThread ,ctx);
ResumeThread(hThread);
|
能力值:
( LV2,RANK:10 )
|
-
-
14 楼
你的方法在思路上没错,但是需要一个技巧避开SetThreadContext的限制:
修改你的 SetHwBreakpoint ,这样来设置Context : 先注册一个SEH,然后引发一个能修正的异常,在SEH里面处理异常的时候设置 Context , 接着让代码继续在异常指令之后执行,这时候Context 就应设置好了
引发异常的时候,你要注意不要重复处理(VEH 和 SEH 之中),或者你把设置Context 的代码也放在VEH 之中,就不用SEH了
|
能力值:
( LV12,RANK:760 )
|
-
-
15 楼
SetThreadContext需要权限对才行。事情太多可能,最大的可能是注入的姿势不对,当前线程不是程序的线程。
|
能力值:
( LV2,RANK:10 )
|
-
-
16 楼
SetThreadContext需要权限对才行。事情太多可能,最大的可能是注入的姿势不对,当前线程不是程序的线程。
我是注入到我要设置硬件断点的目标程序中
比如我要在A中设置硬件断点达到通过VEH来实现HOOK处理,那么我是通过B(DLL)注入到A的,这样的流程,可行吗,还需要什么权限,能不能说更具体一些
在此谢谢各位大哥的真诚回复
|
能力值:
( LV2,RANK:10 )
|
-
-
17 楼
我也是Delphier
我也想用Delphi写的DLL下硬件断点,可惜太多都是C语言的...
求完整代码,
|
能力值:
( LV2,RANK:10 )
|
-
-
18 楼
::SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)KeyboardProc, theApp.m_hInstance, 0);也就是说我用这种全局的键盘钩子进行注入是存在问题的是吗,要采用消息钩子才可以对吧,知道的大哥请解答一下,谢谢
|
能力值:
( LV2,RANK:10 )
|
-
-
19 楼
//函数名:debugProc
//参数 :debuger结构体,使用前必须初始化
//返回值:-
//作用 :设置断点
DWORD WINAPI debugProc(LPVOID lpParameter )
{
if(debuger1.caozuo==1)
{
RefreshThreadList(GetCurrentProcessId());
for(int i=0;i<100;i++)
{
if(lst[i]==0)
{
break;
}
if(lst[i]!=GetCurrentThreadId())
{
HANDLE thd=OpenThread(THREAD_ALL_ACCESS,true,lst[i]);
SuspendThread(thd);
CONTEXT con;
con.ContextFlags=CONTEXT_CONTROL|CONTEXT_DEBUG_REGISTERS;
GetThreadContext(thd,&con);
if(debuger1.dr==0)
{
con.Dr0=debuger1.addr;
con.Dr7=con.Dr7|0x3;
}
if(debuger1.dr==1)
{
con.Dr1=debuger1.addr;
con.Dr7=con.Dr7|0xc;
}
if(debuger1.dr==2)
{
con.Dr2=debuger1.addr;
con.Dr7=con.Dr7|0x30;
}
if(debuger1.dr==3)
{
con.Dr3=debuger1.addr;
con.Dr7=con.Dr7|0xc0;
}
con.ContextFlags= CONTEXT_CONTROL|CONTEXT_DEBUG_REGISTERS;
SetThreadContext(thd,&con);
ResumeThread(thd);
}
}
}else
{
RefreshThreadList(GetCurrentProcessId());
for(int i=0;i<100;i++)
{
if(lst[i]==0)
{
break;
}
if(lst[i]!=GetCurrentThreadId())
{
HANDLE thd=OpenThread(THREAD_ALL_ACCESS,true,lst[i]);
SuspendThread(thd);
CONTEXT con;
con.ContextFlags=CONTEXT_CONTROL|CONTEXT_DEBUG_REGISTERS;
GetThreadContext(thd,&con);
if(debuger1.dr==0)
{
con.Dr0=debuger1.addr;
con.Dr7=con.Dr7&~0x3;
}
if(debuger1.dr==1)
{
con.Dr1=debuger1.addr;
con.Dr7=con.Dr7&~0xc;
}
if(debuger1.dr==2)
{
con.Dr2=debuger1.addr;
con.Dr7=con.Dr7&~0x30;
}
if(debuger1.dr==3)
{
con.Dr3=debuger1.addr;
con.Dr7=con.Dr7&~0xc0;
}
con.ContextFlags= CONTEXT_CONTROL|CONTEXT_DEBUG_REGISTERS;
SetThreadContext(thd,&con);
ResumeThread(thd);
}
}
}
|
能力值:
( LV2,RANK:10 )
|
-
-
20 楼
呃,还有一个是线程
CreateThread(NULL,255,(LPTHREAD_START_ROUTINE)debugProc,NULL,0,NULL);
以及设置VEH
if(pExceptionInfo->ExceptionRecord->ExceptionAddress==(PVOID)0x005B9680)//address
{
pExceptionInfo->ContextRecord->Eip=(DWORD)TouMingWudi; //设置eip
return EXCEPTION_CONTINUE_EXECUTION;
}
|
能力值:
( LV2,RANK:10 )
|
-
-
21 楼
我HOOK INT 01 这样下硬件断点可以成功.
__asm
{
PUSH EAX
MOV EAX, 断点一
MOV DR0, EAX
MOV EAX, 断点二
MOV DR1, EAX
MOV EAX, DR7
OR EAX, 0x270F
MOV DR7, EAX
POP EAX
}
可是为什么我取消断点 :
__asm
{
PUSH EAX
MOV EAX, 0
MOV DR0, EAX
MOV DR1, EAX
MOV EAX, DR7
AND EAX, 0xFFFFFFF0
MOV DR7, EAX
POP EAX
}
这样取消断点不行呢...希望大牛指点.
比如我重新设硬断断点也不行.
__asm
{
PUSH EAX
MOV EAX, 新断点一
MOV DR0, EAX
MOV EAX, 新断点二
MOV DR1, EAX
MOV EAX, DR7
OR EAX, 0x270F
MOV DR7, EAX
POP EAX
}
望各位大牛指点...解惑.
难道必须用NtSetContextThread 和异常来设置硬件断点么?
|
|
|