DebugPort 调用过程
有图示的用DEBUG调试程序过程示例

用DEBUG调试程序示例例如:编程实现两个字类型的数相加,把和存在存储单元中,并且用debug查看程序的运行结果,检查程序运行结果的正确性。
参考源程序如下:DATA SEGMENTNUM1 DW 1234HNUM2 DW 5678HSUM DW ?DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATASTART: MOV AX,DATAMOV DS,AXMOV AX,NUM1ADD AX,NUM2MOV SUM,AXMOV AH,4CHINT 21HCODE ENDSEND START假设把源程序命名为jiafa.asm,输入源程序后,完成汇编、连接的过程,则生成了可执行文件jiafa.exe。
运行此可执行文件时在屏幕上无显示结果。
在debug下调试程序的步骤示例如下:一、进入debug,同时把被调试程序调入内存。
回车后即进入了debug程序,结果如下图所示:注意:被调试的是可执行文件,而且文件必须写全名,不能只写主文件名。
二、用u命令反汇编(输入u后回车),以便查找需要设置断点的地址。
三、设置断点运行断点可以设置在程序中的任意一条指令的首地址处,但为了能够查看到程序的运行结果,一般把断点设置在主程序运行完并且程序退出之前,例如程序的最后两条指令是MOV AH, 4CHINT 21H则把断点设置在MOV AH, 4CH处,(如果程序较长,一次反汇编没有找到上述指令,再次输入u命令后回车,直到显示上述指令为止,),对于本例,显示如下图所示的结果。
如上图示例中的指令mov ah,4ch的偏移地址是0000F,指令int 21h(debug下默认为16进制,不显示h)的偏移地址是0011,则用G命令设置断点运行时输入g0F(g是debug下的程序运行命令,后面的数字0F是刚才选定的断点地址)回车后结果如下图:为了能够查看你的程序在内存单元中存放的数据,必须设置断点运行不能只用G命令,并且断点必须是你程序中的某条指令,一般设置在MOV AH, 4CH处。
实验一 利用 DEBUG 调试汇编语言程序段

实验名称实验一利用 DEBUG 调试汇编语言程序段一、实验目的1.熟悉 DEBUG 有关命令的使用方法;2.利用 DEBUG 掌握有关指令的功能;3.利用 DEBUG 运行简单的程序段。
二、实验要求1.仔细阅读有关 DEBUG 命令的内容,对有关命令,要求事先准备好使用的例子;三、实验环境DOS 操作系统四、实验内容1.进入和退出 DEBUG 程序;1)开始—运行点确定进入DOS命令窗口图1进入DOS命令窗口2)在命令窗口中输入 dubug 进入 debug 程序图2进入 debug 程序3)进入 debug 窗口后,输入 q 命令退出 debug图3退出 debug2.学会 DEBUG 中的1)D 命令(显示内存数据 D 段地址:偏移地址)例 1:-D100 ;显示 DS 段, 0100 开始的 128 个字节内容-D ;默认段寄存器为 DS,当前偏移地址(刚进入 debug 程序偏移地址为 0100H)图4默认显示 DS 段内容-D DS:100 ;显示 DS 段, 0100H 开始的 128 个字节内容图5显示 DS 段内容-D CS:200 ;显示 CS 段, 0200H 开始的 128 个字节内容图6显示 CS 段内容-D 200:100 ;显示 DS 段, 0200:0100H 开始的 128 个字节内容图7显示 DS段0200:0100H内容-D 200 ;显示 DS 段, 0200H开始的128个字节内容图8显示 DS段0200H开始的内容-D 100 L 10 ;显示 DS 段, 100H 开始的 100H 个字节内容图9显示 DS段100H开始的100H字节内容2)E 命令(修改指定内存)例 1:-E100 41 42 43 44 48 47 46 45-D 100,L08结果:073F:0100 41 42 43 44 48 47 46 45-e 100 修改内存内容-d 100,L08 查看刚才修改的内存内容图10 修改和查看DS段100H开始的80H字节内容例 2: -E 100073F:0100 41. 42 : 42 是操作员键入此命令是将原 100 号内存内容 41 修改为 42,用 D 命令可察看。
debug 的使用

Debug是一种程序调试工具,主要用于帮助程序员检查和修复程序中的错误。
以下是如何使用Debug的基本步骤:
设置断点:断点是一种标记,告诉Debug从标记的地方开始查看。
在要设置断点的代码行上单击鼠标左键即可。
运行程序:在代码区域右击,选择Debug执行。
单步执行:点击Step Into(F7)这个箭头,或者直接按F7,以一行一行地操纵代码,从而判断程序的执行流程是否与预期一致。
查看变量值:在执行过程中,可以查看变量的当前值,以了解程序状态。
删除或禁用断点:选择要删除的断点,单击鼠标左键即可。
如果是多个断点,可以每一个再点击一次。
也可以一次性全部删除。
以上是使用Debug的基本步骤,但请注意,具体使用方式可能会根据Debug的具体版本和配置有所不同。
实验一熟悉使用调试工具软件DEBUG

实验一熟悉使用调试工具软件DEBUG引言调试是软件开发过程中不可或缺的一部分。
通过调试工具软件DEBUG,我们可以查找和修复程序中的错误、检查变量的值、跟踪代码的执行路径等等。
本实验旨在帮助学生熟悉DEBUG的基本功能和使用方法。
一、实验目标1.熟悉DEBUG软件的界面和基本功能;2.学会使用DEBUG软件进行程序的调试和跟踪;3.掌握DEBUG软件中的断点设置和单步执行等功能。
二、实验环境1. 操作系统:Windows 10;2.调试工具软件:DEBUG。
三、实验步骤[DEBUG软件界面截图](1)Registers窗口显示寄存器的内容,包括通用寄存器、段寄存器等;(2)Disassembly窗口显示汇编指令的内容;(3)Dump窗口显示内存中的内容;(1)r:显示寄存器的内容;(2)u:显示当前汇编指令的地址和指令;(3)d:显示内存中的内容。
通过执行这些指令,我们可以查看和了解程序的运行状态和内存存储的内容。
(1)g:运行程序;(2)t:执行一条指令,并显示执行结果;(3)p:执行一行汇编代码,并显示执行结果。
通过执行这些指令,我们可以跟踪程序的执行路径和变量的值。
6. 在Disassembly窗口中,双击一条汇编指令可以设置断点。
设置断点后,程序执行到断点处会自动停止。
在调试过程中,我们可以查看断点前后的变量值,检查程序是否按照预期执行。
(1)bp:查看断点列表;(2)bl:清除断点列表中的断点;(3)bd:删除一个断点。
通过执行这些指令,我们可以管理和控制断点,实现更精细的调试过程。
8. 在DEBUG软件界面中,点击工具栏上的“跟踪”按钮,可以选中“Trace over”、“Trace into”和“Animate”等选项。
这些选项分别表示在执行过程中是否显示详细过程、是否跳过函数调用、是否动画演示执行过程等。
通过选择不同的选项,我们可以根据需要自定义调试过程。
四、实验总结通过本次实验,我们了解了DEBUG软件的基本功能和使用方法。
DEBUG的使用方法

DEBUG的使用方法1.设置断点:断点是在代码中设置的一个位置,程序在运行到这个位置时会暂停执行。
可以在关键的代码行上设置断点,以便在程序运行到这些位置时进行观察和调试。
在DEBUG工具中,我们可以在代码行上单击左侧的空白区域来设置断点。
2.执行步进:步进是一种按步执行程序的方法,可以逐行或逐过程执行代码。
通过逐行执行代码,可以观察每一行代码的执行情况,以便找出程序中的错误。
可以使用DEBUG工具提供的步进功能,一次执行一行代码或一个过程。
3.观察变量:在程序运行过程中,可以观察和监视变量的值,以便了解程序的状态。
可以使用DEBUG工具来查看变量的值,并在程序执行过程中跟踪变量的变化。
这对于发现变量值的改变和问题的根源非常有帮助。
4.输出调试信息:在调试过程中,可以通过在代码中插入输出语句来输出调试信息。
可以使用DEBUG工具提供的输出窗口或控制台来查看这些调试信息。
输出调试信息有助于了解程序的执行流程,找到错误发生的原因。
5.检查堆栈:堆栈是保存程序执行状态的一种数据结构,可以在DEBUG工具中查看和跟踪堆栈的状态。
堆栈信息可以告诉我们程序的执行路径,以及代码是如何调用和返回的。
通过检查堆栈,我们可以找到错误发生的上下文和调用链。
6.使用断言:断言是一种在代码中插入的条件,用于检查程序执行过程中的假设和要求。
可以使用DEBUG工具中的断言功能,在关键的代码位置插入断言条件。
当断言条件不满足时,程序会执行中断操作,从而帮助我们快速定位错误。
7.进行追踪:追踪是一种记录程序执行过程的方法,可以在DEBUG工具中查看程序的执行轨迹。
追踪记录了程序的每一步操作,包括函数调用、条件语句的执行和变量的修改等。
通过追踪,我们可以逐步了解程序的执行情况,并找到错误所在。
8.使用条件断点:条件断点是一种在特定条件下触发断点的方法。
可以在DEBUG工具中设置条件断点,当满足特定条件时,程序会在断点处暂停执行。
条件断点可以帮助我们找出特定情况下的错误,提高调试的效率。
debug调试程序的使用 实验原理

debug调试程序的使用实验原理Debug调试程序是一种在软件开发过程中用于定位和修复程序错误的工具。
它可以帮助开发人员在程序运行时检测和诊断错误,并提供相应的信息以便于修复错误。
在本文中,我们将探讨Debug调试程序的使用方法以及其背后的原理。
Debug调试程序的使用Debug调试程序是由软件开发工具提供的一种功能,例如集成开发环境(IDE)或命令行调试器。
它允许开发人员以步骤方式执行程序,观察每一步的结果,并在每一步之间检查程序状态和变量的值。
以下是Debug调试程序的使用步骤:1.设置断点:断点是程序执行暂停的标记。
通过在代码中设置断点,开发人员可以指示调试器在该处暂停执行。
一般来说,可以在IDE 中点击代码行号或使用调试命令设置断点。
2.启动调试器:在设置断点后,可以启动调试器来执行程序。
调试器将会在达到断点处暂停执行,并等待进一步的调试命令。
3.逐步执行:一旦程序暂停在一个断点上,开发人员可以使用调试命令逐步执行代码。
常用的调试命令包括执行下一步、进入函数、跳出函数、继续执行等。
4.观察变量:在每个代码步骤中,开发人员可以查看变量的值以及程序状态。
这对于发现错误、理解代码逻辑以及验证程序逻辑非常有用。
5.修改变量值:在调试过程中,开发人员可以修改变量的值,以便验证不同的情况和修复错误。
这可以通过在调试器的变量窗口中直接修改变量值,或者在调试命令中使用特定的语法进行。
6.检查函数调用栈:函数调用栈是程序中函数调用的历史记录。
调试器允许开发人员检查调用栈,找到导致错误的函数调用路径。
7.调试复杂数据结构:在调试过程中,开发人员可能需要检查复杂的数据结构,例如数组、链表、对象等。
调试器通常提供了可视化工具和命令来帮助开发人员检查和修改这些数据结构。
8.寻找内存错误:调试器还可以帮助开发人员寻找内存错误,例如空指针解引用、内存泄漏等。
通过检查内存地址、跟踪内存分配和释放等功能,开发人员可以更容易地识别和修复这些问题。
windbg双机调试的配置方法(1394版)

windbg双机调试的配置方法(1394版)学习各种外挂制作技术,马上去百度搜索"魔鬼作坊"点击第一个站进入、快速成为做挂达人。
昨天在Berry的指导下开始了双机调试之旅(两台笔记本)准备的材料:两台都有1394的机器,我这里用的是笔记本,一根1394线(1394线有3种,4对4,4对6,6对6,一般笔记本都是4口的,所以我买了一根4对4的线,市场价大概30元吧,也许还有更便宜的)下面,被调试机称target,调试机称Host。
target机配置:2000-2003的配置:在boot.ini里面加一行:multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP1394"/noexecute =optin/fastdetect/debug/debugport=1394/channel=20红颜色的是关键,前面的根据各人的电脑自己配置,网上配置虚拟机调试的教程很多,不多说了,注意我这里最后的channel是20,然后禁用1394(2000必须禁用,xp以上不需要,系统会在进debug后自己禁用),重启,选这个选项进系统host机配置:安装windbg(最好是用微软的安装包安装,不是copy),然后把1394线拔了(这里我搞了半个小时,最后快放弃了才成功的关键点,也许是我的host机器太老了,1394设备太烂,插了线就不认),然后打开windbg,按Ctrl+K,选择1394,填入20(这里的20是上面的channel),然后确定,这时候windbg会自动安装一个虚拟的1394的驱动,然后会wait to connect,这时候插上线,就可以调试了。
以后可以在windbg的快捷方式里面填上启动选项-k1394:channel=20,symlink=instance这样可以快速启动1394调试1394的调试速度很快,双机调试确实很爽,呵呵注意,vista以上的启动选项比较复杂,不能通过改boot.ini来配置在上篇的中我们介绍了API编程的基础知识和一些比较“酷”的API调用,这期我们将配合专题介绍关于注册表编程的API函数及其应用实例,使读者朋友何能够将前面学到的注册表知识推广到VB编程中,继续向VB高手迈进(路漫漫……)。
idea 如何debug请求的调用过程

Idea 是一个广泛使用的 Java 集成开发环境(IDE),在编写和调试Java 程序时非常方便和高效。
在进行后端开发时,我们经常需要通过浏览器或者客户端发送请求到后端服务,但是当出现问题时,我们就需要通过调试来排查问题,定位具体出错的地方。
下面介绍如何使用Idea 来 debug 请求的调用过程。
一、设置断点1. 打开你的项目,并找到发送请求的地方。
这可以是一个Controller 或者一个 Service 层的方法。
2. 在你想要为调试的代码行上点击鼠标右键,然后选择“Toggle Breakpoint” 选项将该行标记为断点。
3. 如果你想对请求的处理流程全面进行调试,你也可以在整个方法的第一行或最后一行设置断点。
二、配置调试环境1. 确保你的项目已经被成功编译,并且没有编译错误。
如果有编译错误,在 debug 时可能会导致意想不到的问题。
2. 点击菜单栏中的“Run” -> “Edit Configurations”,然后在弹出的窗口中选择“+” 号,选择“Application”。
3. 在“M本人n class” 一栏中选择你要调试的主类。
如果你是在Spring Boot 项目中进行调试,那么就选择启动类(通常是以SpringBootApplication 注解的类)。
三、启动 Debug 模式1. 点击菜单栏中的“Run” -> “Debug” 或者直接按下快捷键Shift + F9 来启动 Debug 模式。
2. 访问你要调试的接口位置区域或者触发发送请求的行为。
四、在调试过程中查看变量和调用栈1. 当程序执行到断点时,会自动暂停,并且 Idea 会自动切换到Debug 调试窗口。
2. 在 Debug 调试窗口中,你可以看到当前的断点所在的代码行。
3. 在左侧的变量窗口中,你可以查看当前作用域内的变量的值,这对于排查问题非常有帮助。
4. 在下方的调用栈窗口中,你可以查看当前方法的调用栈,以及每个方法的参数和返回值,帮助你分析代码执行流程。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
DebugPort调用过程学习各种外挂制作技术,马上去百度搜索"魔鬼作坊"点击第一个站进入、快速成为做挂达人。
1一个程序被ring3调试器调试时,有很多的调试特征可以检测,本论坛也有专门的帖子详细论述,但有个非常根本的标志ring3也是可以检测的比较少人提及,那就是_EPROCESS.DebugPort。
DebugPort对于ring3调试器来说非常重要,没有它正常的ring3调试是无法进行的。
当然要检测这个标志的前提是程序能够读取ring0内存,在XP 以上的系统有个非常简单的方法就是使用ZwSystemDebugControl的SysDbgReadVirtualMemory方法,我们也可以mapphysicalmemory来操作。
检测DebugPort之前首先要得到进程的eprocess地址,这可以通过ZwQuerySystemInformation的SystemHandleInformation方法得到,也可以直接搜索ring0内存的eprocess结构。
对于ring3直接检测DebugPort,我们可以通过禁止该进程访问ring0内存来对付,但是目标一旦使用驱动来检测,那么就非常麻烦了。
下面介绍一种隐藏_EPROCESS.DebugPort的方法,这种方法的基本思路是,将一个正常被调试进程的DebugPort置零后,修正所有受影响的函数,使我们的调试器能够正常进行。
这些函数如下:PspCreateProcess、MmCreatePeb进程创建,设置DebugPortDbgkCreateThread发送线程或者进程创建的调试信息KiDispatchException、DbgkForwardException和DbgkpQueueMessage发送异常调试信息PspExitThread、DbgkExitThread和DbgkExitProcess发送线程退出、进程退出的调试信息DbgkMapViewOfSection和DbgkUnMapViewOfSection发送映像装载卸载调试信息DbgkpSetProcessDebugObject和DbgkpMarkProcessPeb当调试器附加进程时设置DebugPort这类函数非常多的,如果都HOOK处理的话,那太恐怖了,这里使用一个非常简单的办法:偷龙转凤。
我们看系统访问DebugPort的代码都是这样的(XP)8b89bc000000mov ecx,dword ptr[ecx+0BCh]//0BCh就是DebugPort的偏移我们可以把DebugPort转移到_EPROCESS的另外一个地方,比如我使用+0x070CreateTime,它是纪录进程创建时间的,进程创建之后,在进程退出前系统不会对它进行任何修改,而且我们修改后对系统或进程没有任何影响。
这样我们可以把上面的代码改成这样8b8970000000mov ecx,dword ptr[ecx+070h]//指向CreateTime,实际的DebugPort已经被移到这里只需要修改一个字节,非常简单。
当然这种方法最麻烦的地方就是定位引用到DebugPort的函数(本人仅仅针对不同的XP系统制作特征码都累到吐血),这些函数都是不导出的,如果是特定系统,最简单的方法就是WinDbg->uf***直接找地址硬编码,只需要几分钟时间。
BOOLEAN InitHackAddress()2{3_SEH_TRY4{5g_KernelBase=GetKernelBaseAndSize(&g_KernelSize);6g_HackPspCreateProcess= SearchHackPspCreateProcess(&g_NopPspCreateProcess.Address);7g_HackKiDispatchException=SearchKiDispatchException(g_KernelBase,g_KernelSize);8g_HackDbgkpQueueMessage= SearchDbgkpQueueMessage(g_KernelBase,g_KernelSize);9g_HackDbgkCreateThread= SearchDbgkCreateThread(g_KernelBase,g_KernelSize);10SearchDbgkNotifyRoutine(g_KernelBase,g_KernelSize);11g_HackPspExitThread=SearchPspExitThread();12g_HackMmCreatePeb=SearchMmCreatePeb(g_HackPspCreateProcess); 13SearchDbgkpSetProcessDebugObject(g_KernelBase,g_KernelSize);14if(g_HackDbgkpSetProcessDebugObject[3])15g_HackDbgkpMarkProcessPeb= SearchDbgkpMarkProcessPeb(g_HackDbgkpSetProcessDebugObject[3]);1617if(g_NopPspCreateProcess.Address!=0){18RtlFillMemory(g_NopPspCreateProcess.NopCode,sizeof(g_NopPspCreateProcess. NopCode),0x90);19g_NopPspCreateProcess.Size=9;20RtlCopyMemory(g_NopPspCreateProcess.OrigCode,(PVOID)g_NopPspCreateProce ss.Address,g_NopPspCreateProcess.Size);21}22if(g_NopDbgkForwardException.Address!=0){23RtlFillMemory(g_NopDbgkForwardException.NopCode,sizeof(g_NopDbgkForwardE xception.NopCode),0x90);24RtlCopyMemory(g_NopDbgkForwardException.OrigCode,(PVOID)g_NopDbgkForwa rdException.Address,g_NopDbgkForwardException.Size);25}26if(g_NopDbgkExitThread.Address!=0){27RtlFillMemory(g_NopDbgkExitThread.NopCode,sizeof(g_NopDbgkExitThread.NopC ode),0x90);28RtlCopyMemory(g_NopDbgkExitThread.OrigCode,(PVOID)g_NopDbgkExitThread.A ddress,g_NopDbgkExitThread.Size);29}30if(g_NopDbgkExitProcess.Address!=0){31RtlFillMemory(g_NopDbgkExitProcess.NopCode,sizeof(g_NopDbgkExitProcess.Nop Code),0x90);32RtlCopyMemory(g_NopDbgkExitProcess.OrigCode,(PVOID)g_NopDbgkExitProcess. Address,g_NopDbgkExitProcess.Size);33}34if(g_NopDbgkMapViewOfSection.Address!=0){35RtlFillMemory(g_NopDbgkMapViewOfSection.NopCode,sizeof(g_NopDbgkMapView OfSection.NopCode),0x90);36RtlCopyMemory(g_NopDbgkMapViewOfSection.OrigCode,(PVOID)g_NopDbgkMapV iewOfSection.Address,g_NopDbgkMapViewOfSection.Size);37}38if(g_NopDbgkUnMapViewOfSection.Address!=0){39RtlFillMemory(g_NopDbgkUnMapViewOfSection.NopCode,sizeof(g_NopDbgkUnMa pViewOfSection.NopCode),0x90);40RtlCopyMemory(g_NopDbgkUnMapViewOfSection.OrigCode,(PVOID)g_NopDbgkUn MapViewOfSection.Address,g_NopDbgkUnMapViewOfSection.Size);41}424344}45_SEH_HANDLER46{47DbgPrint("InitHackAddress Exception!\n");48}49return(g_HackPspCreateProcess!=0&&50g_HackKiDispatchException!=0&&51g_HackDbgkForwardException!=0&&52g_HackDbgkpQueueMessage!=0&&53g_NopPspCreateProcess.Address!=0&&54g_NopDbgkForwardException.Address!=0&&55g_HackDbgkCreateThread!=0&&56g_HackDbgkExitThread!=0&&57g_NopDbgkExitThread.Address!=0&&58g_HackDbgkExitProcess!=0&&59g_NopDbgkExitProcess.Address!=0&&60g_HackDbgkMapViewOfSection!=0&&61g_NopDbgkMapViewOfSection.Address!=0&&62g_HackDbgkUnMapViewOfSection!=0&&63g_NopDbgkUnMapViewOfSection.Address!=0&&64g_HackPspExitThread!=0&&65g_HackMmCreatePeb!=0&&66g_HackDbgkpSetProcessDebugObject[0]!=0&&67g_HackDbgkpSetProcessDebugObject[1]!=0&&68g_HackDbgkpSetProcessDebugObject[2]!=0&&69g_HackDbgkpSetProcessDebugObject[3]!=0&&70g_HackDbgkpMarkProcessPeb!=0);71}//修改已经运行进程的DebugPort位置72BOOLEAN ChangeProcessDebugPort(BOOLEAN Hide)73{74ULONG eProcess=(ULONG)PsInitialSystemProcess;75PLIST_ENTRY pListHead,pListWalk;76ULONG DebugObject;77if(!g_bIsAddressStartup){78return FALSE;79}80pListHead=(PLIST_ENTRY)(eProcess+ACTIVE_LINKS_OFFSET);81pListWalk=pListHead;82_SEH_TRY83{84do{85if(pListWalk==NULL||eProcess==0)86break;87eProcess=((ULONG)pListWalk-ACTIVE_LINKS_OFFSET);88if(Hide){89DebugObject=*(ULONG*)(eProcess+DEBUG_PORT_OFFSET); 90*(ULONG*)(eProcess+CREATE_TIME_OFFSET)=DebugObject; 91*(ULONG*)(eProcess+DEBUG_PORT_OFFSET)=0;92}else{93DebugObject=*(ULONG*)(eProcess+CREATE_TIME_OFFSET); 94*(ULONG*)(eProcess+DEBUG_PORT_OFFSET)=DebugObject; 95}96pListWalk=pListWalk->Flink;97}while(pListWalk!=pListHead);98}99_SEH_HANDLER100{101DbgPrint("ChangeProcessDebugPortexception!\n");102}103104return TRUE;105}106代码:107BOOLEANModifyDebugFunction()108{109if(!g_bIsAddressStartup){110returnFALSE;111}112__asm{113cli114mov eax,cr0115and eax,not10000h116mov cr0,eax117}118*(ULONG*)g_HackPspCreateProcess=CREATE_TIME_OFFSET;119*(ULONG*)g_HackKiDispatchException=CREATE_TIME_OFFSET;120*(ULONG*)g_HackDbgkForwardException=CREATE_TIME_OFFSET;121*(ULONG*)g_HackDbgkpQueueMessage=CREATE_TIME_OFFSET;122*(ULONG*)g_HackDbgkCreateThread=CREATE_TIME_OFFSET;123*(ULONG*)g_HackDbgkExitThread=CREATE_TIME_OFFSET;124*(ULONG*)g_HackDbgkExitProcess=CREATE_TIME_OFFSET;125*(ULONG*)g_HackDbgkMapViewOfSection=CREATE_TIME_OFFSET;126*(ULONG*)g_HackDbgkUnMapViewOfSection=CREATE_TIME_OFFSET;127*(ULONG*)g_HackPspExitThread=CREATE_TIME_OFFSET;128*(ULONG*)g_HackDbgkpMarkProcessPeb=CREATE_TIME_OFFSET;129*(ULONG*)g_HackMmCreatePeb=CREATE_TIME_OFFSET;130*(ULONG*)g_HackDbgkpSetProcessDebugObject[0]= CREATE_TIME_OFFSET;131*(ULONG*)g_HackDbgkpSetProcessDebugObject[1]= CREATE_TIME_OFFSET;132*(ULONG*)g_HackDbgkpSetProcessDebugObject[2]= CREATE_TIME_OFFSET;133*(ULONG*)g_HackDbgkpSetProcessDebugObject[3]= CREATE_TIME_OFFSET;134135RtlCopyMemory((PVOID)g_NopPspCreateProcess.Address,g_NopPspCreateProces s.NopCode,g_NopPspCreateProcess.Size);136RtlCopyMemory((PVOID)g_NopDbgkForwardException.Address,g_NopDbgkForward Exception.NopCode,g_NopDbgkForwardException.Size);137RtlCopyMemory((PVOID)g_NopDbgkExitThread.Address,g_NopDbgkExitThread.No pCode,g_NopDbgkExitThread.Size);138RtlCopyMemory((PVOID)g_NopDbgkExitProcess.Address,g_NopDbgkExitProcess.N opCode,g_NopDbgkExitProcess.Size);139RtlCopyMemory((PVOID)g_NopDbgkMapViewOfSection.Address,g_NopDbgkMapVi ewOfSection.NopCode,g_NopDbgkMapViewOfSection.Size);140RtlCopyMemory((PVOID)g_NopDbgkUnMapViewOfSection.Address,g_NopDbgkUn MapViewOfSection.NopCode,g_NopDbgkUnMapViewOfSection.Size);141__asm{142mov eax,cr0143or eax,10000h144mov cr0,eax145sti146}147return TRUE;148}149BOOLEAN WriteBackDebugFunction()150{151if(!g_bIsAddressStartup){152return FALSE;153}154__asm{155cli156mov eax,cr0157and eax,not10000h158mov cr0,eax159}160*(ULONG*)g_HackPspCreateProcess=DEBUG_PORT_OFFSET;161*(ULONG*)g_HackKiDispatchException=DEBUG_PORT_OFFSET;162*(ULONG*)g_HackDbgkForwardException=DEBUG_PORT_OFFSET;163*(ULONG*)g_HackDbgkpQueueMessage=DEBUG_PORT_OFFSET;164*(ULONG*)g_HackDbgkCreateThread=DEBUG_PORT_OFFSET;165*(ULONG*)g_HackDbgkExitThread=DEBUG_PORT_OFFSET;166*(ULONG*)g_HackDbgkExitProcess=DEBUG_PORT_OFFSET;167*(ULONG*)g_HackDbgkMapViewOfSection=DEBUG_PORT_OFFSET;168*(ULONG*)g_HackDbgkUnMapViewOfSection=DEBUG_PORT_OFFSET;169*(ULONG*)g_HackPspExitThread=DEBUG_PORT_OFFSET;170*(ULONG*)g_HackDbgkpMarkProcessPeb=DEBUG_PORT_OFFSET;171*(ULONG*)g_HackMmCreatePeb=DEBUG_PORT_OFFSET;172*(ULONG*)g_HackDbgkpSetProcessDebugObject[0]= DEBUG_PORT_OFFSET;173*(ULONG*)g_HackDbgkpSetProcessDebugObject[1]= DEBUG_PORT_OFFSET;174*(ULONG*)g_HackDbgkpSetProcessDebugObject[2]= DEBUG_PORT_OFFSET;175*(ULONG*)g_HackDbgkpSetProcessDebugObject[3]= DEBUG_PORT_OFFSET;176RtlCopyMemory((PVOID)g_NopPspCreateProcess.Address,g_NopPspCreateProces s.OrigCode,g_NopPspCreateProcess.Size);177RtlCopyMemory((PVOID)g_NopDbgkForwardException.Address,g_NopDbgkForward Exception.OrigCode,g_NopDbgkForwardException.Size);178RtlCopyMemory((PVOID)g_NopDbgkExitThread.Address,g_NopDbgkExitThread.Ori gCode,g_NopDbgkExitThread.Size);179RtlCopyMemory((PVOID)g_NopDbgkExitProcess.Address,g_NopDbgkExitProcess.O rigCode,g_NopDbgkExitProcess.Size);180RtlCopyMemory((PVOID)g_NopDbgkMapViewOfSection.Address,g_NopDbgkMapVi ewOfSection.OrigCode,g_NopDbgkMapViewOfSection.Size);181RtlCopyMemory((PVOID)g_NopDbgkUnMapViewOfSection.Address,g_NopDbgkUn MapViewOfSection.OrigCode,g_NopDbgkUnMapViewOfSection.Size);182__asm{183mov eax,cr0184or eax,10000h185mov cr0,eax186sti187}188return TRUE;189}我想再嗦一下,上面代码大家看到很多函数有个NOPCode,这个实际上是对付线程PS_C ROSS_THREAD_FLAGS_HIDEFROMDBG的,NOP掉相关地方后,就算线程被设置为T hreadHideFromDebugger也无法阻挡调试器接收调试信息。