您好,欢迎来到沃锋问答-赞臣社区旗下知识互动平台! [
请登录
]
|
[
免费注册
]
沃锋问答-赞臣社区旗下知识互动平台
问答首页
问答动态
问题库
问答专家
知识专题
站内公告
全部分类
>
电脑网络
windows64怎样查找DR0寄存器下内核硬件断点
电脑网络
取nmlgb
|
浏览1137次
收藏
|
2020/01/18 15:02
满意回答
检举
|
2020/01/18 15:31
只是VC++不支持64位的内联汇编(我隐约记得VC++2019也支持了,今天没环境),其它编译器,如gcc,intel C,C++builder的64位都支持的但要注意的是但是,DRx的访问是需要一定权限的。比如你用MOV操作的话,你需要在实地址模式,系统管理模式(smm)或者在保护模式(CPL设0).如果权限不够,将会在访问DRx的时候尝产生#GP(general-protection)异常
评论(0)
加载中...
whoami1978
书生
|
采纳率100%
|
回答于 2020/01/18 15:31
其他回答(1)
上善若
一,中断和异常概述:中断和异常是导致处理器转向正常控制流之外代码的两种操作系统条件。中断是一个异步事件(可以在任何时候发生),并且与处理器当前正在执行的任务毫无关系。中断主要由I/O设备、处理器时钟,或者定时器产生的。异常是一个同步事件,它是一个特殊指令执行的结果,与当前处理器正在执行的任务有关。二,IDT(中断描述符表)系统为每一种中断或者异常提供一个陷阱处理器,当中断或者异常发生时,当前指令的执行就会转到特定的陷阱处理器中,此陷阱处理器完成中断或异常的处理工作。由于中断或异常的类型很多,系统为了方便管理,把各种陷阱处理器放入到一张表中(数组),然后中断和异常发生时,cpu就根据中断或者异常的类型,转入到表中某项去执行中断或异常的处理工作。此表,我们称之为IDT(中断描述符表)。由于中断或异常发生时,转到IDT表项的工作是CPU负责完成的,所以系统中每个CPU都对应一张IDT表,而且每个CPU的IDT表内容都相同。IDT的定义如下:typedef struct _IDTR{USHORT limit; //范围ULONG base; //IDT表项起始地址}IDTR,*PIDTR;typedef struct _IDTENTRY{ unsignedshort LowOffset; unsignedshort selector; unsignedchar retention:5; unsignedchar zero1:3; unsignedchar gate_type:1; unsignedchar zero2:1; unsignedchar interrupt_gate_size:1; unsignedchar zero3:1; unsignedchar zero4:1; unsignedchar DPL:2; unsignedchar P:1; unsignedshort HiOffset;} IDTENTRY,*PIDTENTRY;执行陷阱处理器之前,要把该异常发生时的现场保存下来,方便我们后续指令继续执行。陷阱帧定义:typedef struct_X86_KTRAP_FRAME { ULONGDbgEbp; ULONGDbgEip; ULONGDbgArgMark; ULONGDbgArgPointer; ULONG TempSegCs; ULONGTempEsp; ULONGDr0; ULONGDr1; ULONGDr2; ULONGDr3; ULONGDr6; ULONGDr7; ULONGSegGs; ULONGSegEs; ULONGSegDs; ULONGEdx; ULONGEcx; ULONGEax; ULONGPreviousPreviousMode; ULONGExceptionList; ULONGSegFs; ULONGEdi; ULONGEsi; ULONGEbx; ULONGEbp; ULONGErrCode; ULONGEip; ULONGSegCs; ULONGEFlags; ULONGHardwareEsp; // WARNING - segSS:espare only here for stacks ULONGHardwareSegSs; // that involve aring transition. ULONGV86Es; // these will bepresent for all transitions from ULONGV86Ds; // V86 mode ULONGV86Fs; ULONGV86Gs;} X86_KTRAP_FRAME,*PX86_KTRAP_FRAME;获取所有kpcr代码:typedef KAFFINITY(*KESETAFFINITYTHREAD)(__inout PKTHREAD Thread,__in KAFFINITY Affinity);#defineMAX_PROCESSORCOUNT 0x40ULONGgkv_KiProcessorBlock[MAX_PROCESSORCOUNT];BOOLEAN PsGetKiProcessorBlock(){ULONG Index,Affinity,CurrentAffinity;ULONG fnpKeSetAffinityThread;ULONG kPrcb;UNICODE_STRING usFuncName;RtlInitUnicodeString(&usFuncName,L"KeSetAffinityThread");fnpKeSetAffinityThread =(ULONG)MmGetSystemRoutineAddress(&usFuncNam);if (fnpKeSetAffinityThread==0){ return FALSE;}Affinity = KeQueryActiveProcessors(); //KeQueryActiveProcessors获取处理器相关的位图(这里的位图可以理解为个数,比如返回1代表一个处理器,返回3表示两个处理器,返回7表示三个处理器,依此类推。也就是说从有多少个处理器,那么Affinity的值就会从低位到高位依此填充多少位)CurrentAffinity = 1;Index = 0;while(Affinity){ //下面只是个简单的算法,使当前线程运行到不同的处理器上 Affinity &= ~CurrentAffinity;((KESETAFFINITYTHREAD)fnpKeSetAffinityThread)(PsGetCurrentThread(),(KAFFINITY)CurrentAffinity); CurrentAffinity <<= 1; __asm{ push eaxmov eax,fs:[0x20] mov kPrcb,eax pop eax } //得到我们要的东西 gkv_KiProcessorBlock[Index] =kPrcb;Index++;}return TRUE;}硬件断点是cpu直接支持的,通过对DR0~DR7寄存器的相关设置,就可以达到监控某地址的执行或者读写情况。内核层中的硬件断点,是可以直接设置DR0~DR7寄存器。用户层中的硬件断点,是不可以直接设置DR0~DR7寄存器。Windows为我们提供了两个API,可以去帮我我们设置硬件断点。BOOL GetThreadContext(HANDLE hThread,LPCONTEXT lpContext);BOOL SetThreadContext(HANDLE hThread,CONST CONTEXT* lpContext);以上两个api可以获取和设置一个线程的上下文。以前说过,设置硬件断点是通过改写DR0---DR7寄存器进行的。设置和获取线程上下文最终是通过KeContextToKframes和KeContextFromKframes实现的。KeContextFromKframes内部是通过内核栈上面保存的一个_KTRAP_FRAME结构来获取相关的线程上下文内容。其中获取调试寄存器的内容后,通过KiUpdateDr7此函数更新一些东西。线程对象的0x3偏移位置是DebugActive成员,这个成员,是记录哪些调试寄存器是被设置了。KeContextToKframes内部是通过设置内核栈上面保存的一个_KTRAP_FRAME结构来更新线程上下文的。其中并没有对我们的调试寄存器进行直接的设置工作。这里虽然没有直接的相关设置工作,那么它肯定是在某个地方进行了设置,不然的话,用户层是没办法实现硬件断点的。首先用户层调用api的原理是:xxx----进入内核----KiFastCallEntry-----xxx对应的内核函数-----KiFastCallEntry-----退出内核(KiServiceExit)-----返回xxx设置硬件断点的工作如下:在NtSetContextThread内部更新了目标线程内核栈上的陷阱帧。然后当目标线程切换进内核并退出时,目标线程会把它内核栈上的陷阱帧更新到对应的DR0---DR7调试寄存器中,这样就达到了设置硬件断点的目的。Windows为了区分用户模式硬件断点和内核模式硬件的,它的设计思路如下:当是内核模式硬件断点的时候,可以直接设置调试寄存器。当是用户模式硬件断点的时候,因为具体的设置工作是要在内核中进行的,而如果直接在KeContextToKframes中进行设置调试寄存器的工作的话,那是就等于是设置内核模式的调试寄存器了。所以windows选择在目标线程退出内核的那一刻时,进行设置,那么退出内核后,硬件断点就生效了。总结:1,反硬件断点,我们可以通过对某线程的DebugActive成员进行判断,如果存在值的话,那么就是存在硬件断点。2,可以通过对目标线程内核栈上的陷阱帧进行获取和设置工作,也可以达到反硬件断点与检测的目的。NtGetContextThread(HANDLEThreadHandle, PCONTEXT Context)NtSetContextThread(HANDLEThreadHandle, PCONTEXT Context)PsGetContextThread(PETHREADThread, PCONTEXT Context,KPROCESSORMODE AccessMode)PsSetContextThread(PETHREADThread, PCONTEXT Context,KPROCESSORMODE AccessMode)
评论(0)
回答于 2020/01/18 15:40
加载中...
相关已解决
4个回答
用qq登陆注册王者荣耀时,qq好友来自会收到提示吗?
1个回答
CPUi5-13400f显卡华硕4070主板华硕B760MKD来自5这个配置合适吗?
4个回答
这电脑怎么样,怎么升级
1个回答
pcb喷印机字来自符问题点是什么?
1个回答
一登录,就出现身份与密码不符,我也不知道是啥问题
1个回答
什么是C++
1个回答
如何不被设计?
1个回答
华硕B150M-ETSERIES
1个回答
怎么优酷视频来自下载的都不是MP4了
1个回答
进制转换c++代码小美刚刚学习了十六进制,她觉得很速安肉得群会互板烧形有趣,想到是不是还有更大的进制
0
人关注该问题
>>
>>
+1
加载中...