windows环境下隐蔽调试器的设计与实现
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
电子科技大学
UNIVERSITY OF ELECTRONIC SCIENCE AND TECHNOLOGY OF CHINA
硕士学位论文
MASTER DISSERTATION
论文题目: windows环境下隐蔽调试器的设计与实现
学科专业:计算机应用技术
指导教师:
作者姓名:
班学号: 200620603016
分类号密级
UDC1注
学位论文
windows环境下隐蔽调试器的设计与实现
(题名和副题名)
2009年月日
注1:注明《国际十进分类法UDC》的类号。
独创性声明
本人声明所呈交的学位论文是本人在导师指导下进行的研究工作及取得的研究成果。
据我所知,除了文中特别加以标注和致谢的地方外,论文中不包含其他人已经发表或撰写过的研究成果,也不包含为获得电子科技大学或其它教育机构的学位或证书而使用过的材料。
与我一同工作的同志对本研究所做的任何贡献均已在论文中作了明确的说明并表示谢意。
签名:日期:年月日
关于论文使用授权的说明
本学位论文作者完全了解电子科技大学有关保留、使用学位论文的规定,有权保留并向国家有关部门或机构送交论文的复印件和磁盘,允许论文被查阅和借阅。
本人授权电子科技大学可以将学位论文的全部或部分内容编入有关数据库进行检索,可以采用影印、缩印或扫描等复制手段保存、汇编学位论文。
(保密的学位论文在解密后应遵守此规定)
签名:导师签名:
日期:年月日
摘要
摘要
在安全事件中,恶意代码造成的经济损失占有最大的比例。
恶意代码的检测技术总是滞后于新恶意代码的出现。
一方面是人们很难区别正常代码和恶意代码;另一方面,很多信息系统缺少必要的保护措施。
因此,人们常常被恶意代码欺骗,而无意地执行恶意代码。
可见恶意代码被引入系统并执行是不可避免的,监控、分析或检测二进制程序是否为恶意程序已经成为现阶段的研究热点。
恶意代码为了防止被分析,都有很强的自保护功能,现在主要的调试器很难对恶意代码进行分析。
同时,软件保护技术的发展使大量的反调试工具出现,既有针对源代码的反调试工具,又有针对二进制程序的反调试工具。
在反调试工具中,加壳工具功能比较突出,它综合使用多种技术对抗代码分析调试,而且加壳工具使用非常简单,越来越多的恶意代码使用加壳技术保护自己。
本文在分析了很多反调试技术后,包括检测断点技术、检测调试器技术和自动修改代码技术等,设计并实现了一种隐蔽性强的调试器。
该隐蔽调试器利用windows分页管理机制,巧妙地对目标进程设置断点以获取控制,很好地实现了隐蔽调试的特性。
为获得对目标进程的控制权,本调试器利用了windows系统中进程的地址空间分为用户空间和系统空间,代码执行之前系统会进行权限检查的特点,通过修改了目标进程内存页面属性,使目标进程执行时出现异常,从而获得目标进程的控制权。
为增强隐蔽性,本调试器还采用了多种设计技术,包括:通过向目标进程插入shellcode控制目标进程、不产生在windows系统中的注册信息等等。
在功能使用性方面,本隐蔽调试器为系统增加了一些新的系统调用,以方便实现调试功能设置和用户交互。
实验和测试证明,本文提出的调试方法可以作为现行调试技术的一种有效的补充。
关键词:调试器,反调试,恶意代码,进程
I
ABSTRACT
ABSTRACT
The economic loss which the malicious code creates holds the maximum proportion in the security incident. At present, the detection technology of malicious code could not meet the expectations of network security for a great diversity of malicious code. It is very difficult to distinguish the normal code and the malicious code, and many information systems lack the essential protective measures. Analyzing of the malicious code in detail is meaningful in resisting the attack of malicious code and also a hot research spot.
The malicious code has the inner self protection function to prevent to be analyzed. Most debuggers are very difficult to analyze the malicious code. Software protection technique now receives broad attention from all fields both at home and abroad, and there are a lot of Anti debug softwares witch are used for an application code protection from reverse engineering. Packers are created to protect an executable from analysis. They are used legitimately by commercial applications to prevent information disclosure, tampering and piracy. Unfortunately, malcodes also use packers for the same reasons but for a malicious purpose.
Due to a large number of packed malcode, researchers and malcode analysts started to develop the skills to unpack samples for analysis. There are many anti-debug techniques, for example, software breakpoint detection, code checksum calculation and encryption and compression. The debugger is designed and completed witch uses the windows paging management mechanism to debug malcodes. The debugger doesn't register the debugger in the windows system, and Controls the behavior of the object process by the shellcode. The debugger communicates with the user by adding some new system calls. The debugger is different from the other debuggers.
The results of experiment showed that the method offered here is a supplement for traditional debugging techniques.
Keywords: debugger, anti-debug, malicious code, process
II
目录
第1章绪论 (1)
1.1研究背景 (1)
1.2研究内容 (1)
1.3本文组织结构 (2)
第2章调试技术研究分析 (3)
2.1调试的基本概念 (3)
2.2调试器的结构 (5)
2.2.1 调试器基础 (5)
2.2.2 调试器调试模型 (6)
2.3主流调试器比较 (11)
第3章反调试技术研究分析 (13)
3.1反调试技术简介 (13)
3.1.1 检测断点 (13)
3.1.2 计算校验和 (13)
3.1.3 检测调试器 (13)
3.1.4 自修改代码 (14)
3.1.5 覆盖调试程序信息 (14)
3.1.6 解除调试器线程 (15)
3.1.7 加密解密 (15)
3.2反调试工具 (15)
3.2.1 AntiDebugLIB (15)
3.2.2 Themida (16)
3.2.3 加壳工具 (16)
第4章隐蔽调试器设计基础 (20)
4.1调试器的CPU支持 (20)
4.1.1 CPU基础 (20)
4.1.2 中断和异常 (22)
III
4.1.3 断点和单步执行 (23)
4.2调试器的操作系统支持 (24)
4.2.1 windows概述 (24)
4.2.2 windows页面机制 (25)
4.2.3 windows异常处理 (28)
4.2.4 Hook技术 (29)
第5章隐蔽调试器系统地位及总体设计 (32)
5.1隐蔽调试器与其它子系统关系 (32)
5.2隐蔽调试器的系统框架 (33)
5.2.1 隐蔽调试器框架 (33)
5.2.2 Trais和CSXE关系 (34)
5.2.3 隐蔽调试器工作流程 (35)
5.3隐蔽调试器的通信协议 (35)
第6章隐蔽调试引擎各模块详细设计 (39)
6.1页面异常处理(PFH)模块详细设计 (39)
6.2断点处理模块详细设计 (42)
6.3断点表模块详细设计 (43)
6.4通信模块详细设计 (46)
第7章实验和测试 (51)
7.1概述 (51)
7.2实验环境 (51)
7.3测试程序 (51)
7.3.1 调试器界面程序 (51)
7.3.2 目标程序 (54)
7.4功能测试 (56)
7.5总结和展望 (59)
致谢 (60)
参考文献 (61)
攻硕期间取得的研究成果............................................................... 错误!未定义书签。
IV
图录
图 2-1 进程内调试模型 (7)
图2-2 进程外调试模型 (8)
图2-3 混合调试模型图 (9)
图2-4 双机内核调试模型 (10)
图2-5 单机内核调试模型 (10)
图4-1 常用寄存器图 (21)
表4-1 处理器工作方式与CR0的关系 (21)
图4-2 windows简明结构图 (24)
图4-3 windows虚拟地址空间布局 (26)
图4-4 页面地址转换 (26)
图4-5 页表索引结构 (28)
图4-6 IDT表 (28)
表4-2 异常和中断的优先级表 (29)
图4-7 DLL文件替换法 (30)
图5-1 恶意代码动态分析平台总体框架 (32)
图5-2 隐蔽调试器框架 (33)
图5-3 隐蔽调试引擎Trais框架 (34)
图5-4 隐蔽调试器工作流程 (35)
图5-5 隐蔽调试器和目标进程的关系 (36)
图5-6 隐蔽调试器通信流程 (36)
图6-1 异常处理程序的堆栈图 (39)
图6-2 页面异常错误代码结构 (40)
图6-3 目标进程中页面和断点关系图 (40)
图6-4 PFH模块的流程图 (41)
图6-5 设置断点流程图 (42)
图6-6 查找断点流程图 (43)
图6-7 断点表插入流程图 (44)
图6-8 断点表删除流程图 (45)
图6-9 目标程序调试功能初始化图 (50)
V
图6-10 回调函数流程图 (50)
图7-1 界面程序流程图 (52)
图7-2 目标进程执行shellcode时堆栈分布图 (54)
图7-3 中间调用API图 (54)
图7-4 themida基本界面图 (55)
图7-5 themida加壳选项图 (55)
图7-6 隐蔽调试器界面图 (56)
图7-7 隐蔽调试器用户命令菜单图 (56)
图7-8 隐蔽调试器设置断点图 (57)
图7-9 隐蔽调试器查看断点图 (57)
图7-10 OD调试notepad (58)
图7-11 隐蔽调试器调试notepad (58)
VI
第1章绪论
第1章绪论
1.1 研究背景
在安全事件[1]中,恶意代码(Malicious Code)造成的经济损失占有最大的比例。
恶意代码主要包括计算机病毒(Virus)、蠕虫(Worm)、木马程序(Trojan Horse)、后门程序(Backdoor)、间谍软件(Spyware)、逻辑炸弹(Logic Bomb)等等。
恶意代码感染就是通过用户执行该恶意代码或已经感染恶意代码的可执行代码,从而使得恶意代码得以执行,进而将自身或者是自身的变体植入其他可执行程序。
被执行的恶意代码在完成自身传播的同时,若满足一定的条件,并具有足够的权限时,就发作并进行破坏活动,造成信息丢失或者泄密等严重后果。
恶意代码的检测技术总是滞后于新的恶意代码的出现。
一方面是人们很难区别正常代码和恶意代码;另一方面,很多信息系统缺少必要的保护措施。
因此,人们常常被恶意代码欺骗,而无意地执行恶意代码。
所以,恶意代码被引入系统并执行是不可避免的。
恶意代码为了防止被分析,都有很强的自保护功能[2],现在主要的调试器很难对恶意代码进行分析。
同时,软件保护技术的发展使大量的反调试工具出现,既有针对源代码的反调试工具,又有针对二进制程序的反调试工具。
在反调试工具中,加壳工具[3]功能比较突出,它综合使用多种技术对抗代码分析调试,而且加壳工具使用非常简单,越来越多的恶意代码使用加壳技术保护自己。
因此,监控、分析或检测二进制程序是否为恶意程序已经成为现阶段的研究热点。
目前比较流行的二进制程序分析工具[3]或调试器[4]常见的有:OllyDbg、IDA、SoftICE,注册表检测器RegMon和文件监视器FileMon,以及最近出现的DynamoRIO平台和Dyninst平台等等。
但是这些工具需要相互配合使用,而且目前恶意代码的不断进化,抗分析能力越来越强,迫切需要具有高效、可靠的恶意代码与安全漏洞动态分析平台。
1.2 研究内容
本论文是国家242项目恶意代码动态分析平台研究内容的一部分,主要研究内容是分析目前主要的反调试技术和深入理解windows进程的管理机制,设计出一种隐蔽性很强的调试方法。
本文简述了软件调试[5]的一般概念,论述了软件调试的一般原理和调试器的结构,以及CPU对调试的支持(包括硬件断点,中断和异常,
1
电子科技大学硕士学位论文
保护模式等)。
本文充分研究了windows分页管理机制和进程管理机制,设计了一种隐蔽性很强的调试机制和断点机制,以保证对恶意代码进行有效地动态分析。
1.3 本文组织结构
本文首先介绍了项目的研究背景,然后概述了软件调试的一般原理和调试器结构,并介绍了目前主要使用的调试器,接下来分析目前主要的反调试技术。
最后,介绍隐蔽调试器的设计原理和总体设计,以及隐蔽调试器各个模块的详细设计。
具体章节内容安排如下:
第1章为项目相关背景,研究内容的介绍。
第2章概述了软件调试的一般原理和调试器结构,并介绍了目前主要使用的调试器。
第3章分析目前主要的反调试技术。
第4章简述了隐蔽调试器的设计原理,包括CPU基础、软件调试的支持和windows操作系统分页管理机制和进程管理机制。
第5章介绍了隐蔽调试器与恶意代码动态分析平台的关系,以及隐蔽调试器的总体设计,并详细介绍了隐蔽调试器通信协议的设计。
第6章介绍了隐蔽调试器的各个模块详细设计,每个模块的流程图,以及关键数据结构。
第7章对隐蔽调试器进行测试,验证本调试器的功能、性能。
最后,对隐蔽调试器进行总结,并就未来进行展望。
2
第2章调试技术研究分析
第2章调试技术研究分析
2.1 调试的基本概念
软件调试是软件开发和维护中非常频繁的一项任务,几乎在软件生命周期的每个阶段,都有很多这样那样的问题需要进行调试。
软件调试泛指重现软件故障,定位故障根源,并最终解决软件问题的过程。
软件调试的另一种解释就是使用调试工具求解各种软件问题的过程,例如跟踪软件的执行过程,探索软件本身工作原理等。
软件调试的基本过程[7]:
(1)重现故障,通常是在用于调试的系统上重复导致故障的步骤,使要解决的问
题出现在被调试的系统中。
(2)定位根源,即综合利用各种调试工具,使用各种调试手段寻找导致软件故障
的根源。
通常测试人员报告和描述的是软件故障的外在症状,例如界面或执行结果中所表现的异常;或者与软件需求和功能规约不符的地方。
而这些表面的缺欠总是一个或多个内在因素所导致的,这些内因要么是代码的行为错误,要么是不行为的错误。
(3)设计解决方案,即根据寻找到的故障根源,资源情况,紧迫程度等设计解决
方案。
(4)验证方案,在目标环境中测试方案的有效性。
如果问题已经解决,那么就可
以关闭问题。
如果没有解决,则回到第三步调整和修改解决方案。
软件调试过程中,定位根源是非常困难,也是最关键的步骤,它是软件调试过程中的核心和灵魂。
如果没有找到故障根源,那么解决方案便是无从下手。
软件调试的基本特征[9]:
(1)难度大[8],如果把定位软件错误看作是一种特别的搜索问题,那么它通常是一
个很复杂的搜索问题。
为了探寻问题的根源,很多时候必须深入到被调试模块或系统的底层,研究内部的数据结构和代码。
与顶层不同,底层的数据大多是以原始形态存在的,理解和分析的难度比顶层大。
因为要在一个较大的问题域内定位错误,所以要求调试者必须有丰富的知识,熟习问题域内的各个软硬件模块,以及他们之间的协作方式。
每个软件调试任务都有很多特殊性,或者说很难找到两个调试任务是一样的。
软件的大型化,层次的增多,
3
电子科技大学硕士学位论文
多核和多处理器系统的普及都在增加软件的调试难度。
(2)完成时间难以估计,对一个软件错误,到底需要多久才能定位到它的根源并
解决这个问题是一个很难回答的问题。
这是因为软件调试问题的问题域比较大,调试过程中包含的随机性和不确定性很多,调试人员对问题及相关模块和系统的熟悉程度,对调试技术的熟练程度也会加入很多不确定性。
在现实中,很多软件难题经常成为整个项目的瓶颈,是项目团队中所有人关注的焦点。
接收调试任务的工程师除了要面对技术上的难题外,还要承受很多其他方面的压力。
(3)关联性广泛[10],软件调试与计算机系统的硬件核心(CPU)和软件核心(操
作系统)都有着很紧密的耦合关系,与编译器也息息相关。
因此,软件调试具有广泛的关联性。
软件调试的广泛关联性增加了理解软件调试过程的难度,同时也导致软件调试技术难以在短时间内迅速发展和升级。
开发一种新的调试手段,通常需要硬件、操作系统和工具软件的支持,使软件调试技术滞后于其他技术。
软件调试方法[6]包括交互式调试、静态分析和动态检查三种。
交互式软件调试工具包括GDB,Windbg等,是大多数程序员最常用的调试方法。
因为开发者对自己的程序非常熟悉,所以可以通过调试器来手工的找到错误。
但是,由于程序在调试器环境中运行非常缓慢,而且程序员必须手工地检查程序的执行情况,所以,这种方法非常的耗时,而且需要大量的人工参与,因此也要求程序员有丰富的经验。
更为重要的是,它很难重现一个软件错误,因为错误常常会在执行数小时甚至数天后发生,或者需要某一个特殊的用户输入组合才会发生,或者与时间相关的事件导致错误发生,所以在这些情况下,交互式调试器只能提供非常有限的帮助。
静态检查技术是对程序执行静态检查,主要通过定义泛化的故障模式、挖掘潜在编程规则、分析代码编写的不一致行为,以及对历史故障模型的学习等手段来实现对软件系统中潜在故障的检测。
由于故障静态检测方法无法获取软件动态运行信息,因而,对于降低故障误报率方面仍存在较大局限性。
动态监控技术主要在程序的运行过程中,检查程序执行是否违反了一些语义规则。
可以分为两类:程序员参与的监控和自动监控。
程序员参与的监控主要包括断言(assert)和数据结构一致性检查。
数据结构一致性表示一个数据结构的状态在整个程序执行期间需要满足的性质,当然,对数据结构修改时可能会违反这种性质,但最终修改完成后会达到一致。
而传统的一致性检查需要遍历整个数据结构,
4
第2章调试技术研究分析
然后确定是否满足一致性,这种方法的主要问题就是检查开销非常大,因此不能在程序中插入大量检查,否则会显著影响程序的运行效率。
大多数动态监控技术都使用了自动监控工具。
2.2 调试器的结构
随着计算机技术的发展,调试器已成为软件开发的重要工具。
由于调试器和硬件紧密相关,和操作系统结合紧密,其开发设计因而比较复杂和困难。
现代操作系统和硬件提供了越来越强和越来越多的功能和设备来支持查错和意外处理,加之高级编程语言的飞速发展,就要求跟踪调试器能更加有效的利用操作系统接口和硬件功能,向用户提供高效,便利和功能强大的开发调试差错能力。
跟踪调试器是软件开发人员在开发过程中定位,去除软件错误的工具。
2.2.1 调试器基础
调试器可以中断程序的执行以检查代码,计算和编辑程序中的变量,查看寄存器,以及查看应用程序所占用的内存空间等。
建立和终止调试会话
调试器在调试一个程序前,必须先与其建立起调试和被调试的关系,即建立调试会话。
对于用户态调试,建立调试会话的方式通常有两种,一种在调试器中启动被调试程序,另一种在被调试程序加载后,将调试器附加到被调试程序。
对于内核态调试,建立调试会话的过程就是调试引擎被加载到操作系统中,通常是在系统启动时完成。
终止调试会话的方式有很多种,可以直接退出调试器,此时通常被调试程序也会终止;或者将被调试程序分离,让调试器继续运行;被调试程序也可以直接退出。
断点和观察点[11]
断点是一个信号,它通知调试器,在某个特定点上暂时将程序执行挂起。
当执行在某个断点处挂起时,我们称程序处于中断模式。
进入中断模式并不会终止或结束程序的执行。
执行可以在任何时候继续。
断点提供了一种强大的工具,使调试者能够在需要的时间和位置挂起执行。
与逐条指令地检查代码不同的是,可以让程序一直执行,直到遇到断点,然后开始调试。
这大大地加快了调试过程。
没有这个功能,调试大的程序几乎是不可能的。
5
电子科技大学硕士学位论文
观察点是一种特殊的断点,它区别于断点的地方在于,它不是一个可中断的指令代码地址,而是一个内存地址,当指定地址的内存被访问时会引起中断异常。
中断异常的处理类似于断点。
单步[11]
当程序处于被调试模式,且碰到断点停止执行时,单步执行使程序向前执行一条指令后停止,并等待调试器的进一步命令。
它分为两种:机器码级单步执行和源代码级单步执行。
前者使程序向前执行一条机器指令,后者则向前执行到下一行源代码所对应的机器指令处,一行源代码可以由一条或很多条机器指令构成,因此源码级单步更加复杂,它需要确定源码与机器码的对应关系。
程序状态信息[11][12]
程序状态信息包括寄存器内容,内存内容,调用堆栈上的函数名,程序创建的线程等。
程序的调试信息中有些需要符号文件支持。
默认情况下,符号文件中包含了所有的结构、函数,以及对应的源代码信息。
微软提供的Windows符号文件去掉了源代码信息、函数参数定义和一些内部数据结构的定义。
符号文件(PDB文件)除了包含符号外,还负责把符号和该符号所处的二进制地址联系起来。
比如有一个全局变量叫做gBuffer,PDB文件不仅仅记录了gBuffer的类型,还能让调试器找到保存gBuffer的内存地址。
当在调试器中试图读取某一个内存地址的时候,调试器会尝试在对应的PDB文件中配对,看这个内存地址是否有符号对应。
如果能够找到,调试器就可以把对应的符号显示出来,极大程度上方便了开发人员的观察。
内存是软件工作的舞台,软件的代码必须先被读入到内存后才能被CPU执行。
除了少数分配在寄存器中的局部变量外,软件的大多数变量都是保存在内存中,因此观察和操作被调试程序的内存对调试器来说非常重要。
2.2.2 调试器调试模型
调试器调试模型[12]根据与目标进程关系可分为进程内调试模型、进程外调试模型和混合调试模型。
进程内调试模型
进程内调试模型是指调试器与被调试程序工作在同一个进程的地址空间中。
如图2-1进程内调试模型。
6
第2章 调试技术研究分析
7
调试器
被调试程序
进
程
空
间
图 2-1 进程内调试模型
因为与被调试程序在同一个空间中,所以进程内模式有如下优势:
(1)
可以直接访问被调试程序的代码和数据,速度快,实现也简单。
(2) 调试器可以复用被调试程序的某些资源和数据结构,从总体上看可以节约资
源。
(3) 在调试器代码和被调试程序代码之间可以方便地跳转或互相调用。
进程内模型的不足如下:
(1) 调试器的存在和工作可能影响被调试程序的行为。
(2) 调试器的代码和数据容易遭到破坏。
(3) 因为在同一进程内,所以不利于独立控制被调试程序。
例如,挂起进程时,调试器线程也会被挂起。
在某些简单的计算机系统中,要么没有操作系统,要么操作系统是DOS 这样的单任务操作系统,这些操作系统中的调试器通常是和被调试程序工作在同一个空间中。
DOS 下的DEBUG 调试器也属于这种情况。
调试时,DEBUG 需要先运行并将自己加载到内存中,然后再将被调试程序加载到内存中。
某些嵌入式系统的调试器使用的也是类似的方法。
尽管在这样简单系统中不存在严格意义上的进程,但是从地址空间的角度来看,仍然可以将这些调试器所使用的模型称为进程内模型。
在windows 这样的操作系统中,完全使用进程内模型的调试器是不存在的。
因为当操作系统发送调试事件时会先将被调试进程挂起,所以,如果调试器在同一个进程内,那么调试器的代码也会被挂起,根本无法接收和处理调试事件了。
进程外调试模型
进程外调试模型是指调试器和被调试程序分别工作在各自的进程空间。
如图2-2进程外调试模型。
在进程外模型中,调试器和被调试器分别在各自的进程空间
电子科技大学硕士学位论文
中工作,调试器借助系统的API和调试子系统与被调试程序进行通信。
图2-2 进程外调试模型
进程外模型具有如下优势:
(1)调试器进程使用自己的进程空间来工作,不占用被调试程序的地址空间,也
不会直接访问它的数据和代码,因此减少对被调试程序的影响。
(2)被调试程序很难触及到调试器的代码和数据,因此调试器的代码和数据也不
容易被调试程序所破坏。
(3)控制被调试程序时不会影响调试器进程。
进程外模型也有一下不足:
(1)两者在不同的地址空间中,调试器无法直接访问被调试程序的代码和数据,
必须借助操作系统的API间接读取。
(2)调试事件是通过操作系统调试子系统的转发而送给调试器的,调试器处理后
再把处理结果返回给调试子系统。
这个过程通常要经历核心态和用户态的多次转换所以速度比较慢。
(3)调试器和被调试程序之间很难进行代码共享和函数调用。
在windows系统中可以使用进程外模型实现对普通应用程序的调试。
混合调试模型
混合调试模型是将进程内调试模型和进程外调试模型放在一个调试方案中混合使用。
如图2-3混合调试模型图,除了有一个专门的调试器进程外,在被调试程序的进程内也存在一部分调试器代码,通常是一个线程。
调试进程和被调试进程内的调试代码互相配合共同完成调试任务。
通常将位于被调试进程中的那部分称为调试器左端,而独立的调试器进程称为调试器右端。
8。