1.3.1 CE内存搜索工具
CE(Cheat Engine)是一个流行的内存修改和调试工具,它也包含了内存搜索功能。使用CE的内存搜索工具,您可以在运行中的进程中搜索特定的内存值,并对其进行修改。
■以下是使用CE进行内存搜索的一般步骤:
●启动CE:双击Cheat Engine可执行文件以启动CE。
●选择进程:在CE的主界面中,点击左上角的计算机图标按钮,选择您想要搜索的进程。这将使CE与该进程建立连接,以便进行内存搜索和修改。
●打开内存搜索器:在CE的菜单栏中,选择"Edit"(编辑)菜单,然后选择"Scan for values"(搜索值)选项,或使用快捷键Ctrl + F。
●设置搜索条件:在内存搜索器对话框中,您可以设置搜索条件:
1.选择要搜索的数据类型(例如整数、浮点数、字符串等)。
2.输入要搜索的具体数值或数值范围。
3.选择搜索方式(例如精确搜索、模糊搜索、增加/减少值等)。
●开始搜索:点击"First scan"(首次搜索)按钮开始搜索。CE将在选择的进程的内存空间中查找符合搜索条件的内存地址。
●分析搜索结果:CE将显示搜索结果列表,其中包含符合搜索条件的内存地址和对应的值。您可以在这些结果中查找您感兴趣的值。
●进行进一步的搜索和筛选:如果搜索结果很多,您可以在结果列表中继续进行进一步的搜索和筛选,以缩小范围。例如,您可以根据新的条件再次搜索,或在已有结果中过滤掉不符合要求的值。
●修改内存值:选择您要修改的内存地址,在CE的主界面中进行相应的修改操作。请注意,修改内存值可能会对进程的行为产生影响,请谨慎操作。
CE内存搜索工具自带一个通关游戏教程Tutorial.exe,我们只需要按照教程操作一遍,基本就可以熟悉CE工具的使用方法了。接下来我们举例说明。
第一步:运行Tutorial.exe,如图1-37所示。
图1-37 CE内存搜索工具使用游戏教程
第二步:运行CE5.6汉化版,程序界面如图1-38所示。点击左上角“open”按钮,显示当前进程列表。
图1-38 使用CE打开进程
第三步:点击训练进程Tutorial.exe界面下一步,进入步骤2(精确值扫描),左下角的初始健康值为100,点击“打我”按钮,健康值变为95,如图1-39所示。
图1-39 精确值扫描训练
第四步:在CE窗口,数据栏输入要查找的内存数据“95”,搜索类型设置为“精确值”(这里可以根据实际情况选择某个大于或小于的搜索类型),值类型设置为“4 Bytes”(这里可以根据实际需要选择字符串或其他数据类型)。左侧的“HEX”选表示搜索十六进制数,可以自动转换。下方的搜索设置栏中可以设置搜索方式,默认为快速搜索(以4个字节为单位搜索),深度搜索表示以字节为单位搜索,速度较慢。设置好以后,点击“新的搜索”按钮,左侧地址栏窗口会显示所有的搜索结果,如图1-40所示。我们会发现,有很多内存地址处的值都是95,如果要确定哪一个为正确的地址,则需要再次搜索。
图1-40 第一次搜索
第五步:再次点击训练进程Tutorial.exe界面“打我”按钮,健康值此时变为90。然后我们在CE搜索值一栏输入搜索值“90”,点击再次搜索。此时左侧地址栏只剩下一个地址,此地址就应该是正确的内存地址了。如果还是出现多个地址,则可以同样的方法继续搜索。或者点击“打我”,减少健康值,观察哪个地址处的值发生变化,与训练进程中的健康值相同。
第六步:点击地址栏下方的“查看内存”按钮,或者鼠标双击地址,将地址添加到下方窗口列表。选中地址后点击鼠标右键,选择“改变记录”>“值”,弹出对话框窗口,如图1-41所示。将该地址处的值改为1000。此时再次点击训练进程Tutorial.exe界面“打我”按钮,健康值此时变为1000。
图1-41 修改内存地址处的值
这一步完成后,就可以点击训练进程“下一步”,进入下一关。So easy! 剩下的关卡不再演示了,交给读者自己完成了。
练习
请读者完成CE训练进程剩下的关卡。
1.3.2 DTDebug调试器
■DtDebug调试器的使用方法
DTDebug.exe是供程序员使用的R3应用程序调试工具软件,可以在编程达人官网www.bcdaren.com或者www.dtdebug.com学习论坛下载。
DtDebug调试器的使用方法参见编程达人官网工具软件视频教程,本节仅作简单介绍。
●软件安装
图1-42 设置UDD和插件路径
下载后无需安装,直接双击打开DTDebug.exe程序,点击菜单键:Options->Appearance->Directorics,找到安装文件夹DTDebug下的udd文件夹,设置UDD path为udd路径;找到plugin文件夹,将Plugin path路径设为plugin文件夹路径,如图1-42:
配置好环境后,我们用DTDEBUG打开一个程序,打开的方式有两种,一种是进入点击菜单键:File--> open,选择相应的程序,一种是将程序直接拖进DTDEBUG窗口中,DTDEBUG一共四个界面,左上角是汇编语言反汇编窗口,程序执行到哪一步都可以在这个窗口看到,右上角是寄存器窗口,左下角内存窗口,右下角是堆栈窗口。如图1-43所示。
双击DTDebug.exe,打开界面如图1-44所示。
图1-43 DTDEBUG窗口界面
图1-44 DtDebug初始界面
图1-44是软件的原始界面,没有任何记录。那该怎么把将要被调试的程序打开哪?
有四种方法:
1、在如图1-44程序窗口中找到File -> Open ->找到调试程序;
2、直接将要被调试的程序拖拽到如图1-44程序窗口中。
3、关闭如图1-44窗口,把将要被调试的程序拖到DtDebug图标上。
4、在如图1-44程序窗口中找到File -> Attach ->找到将要被调试的程序(正在运行的软件)。
以IPMGS.exe为例,介绍DTDebug界面,如图1-45、图1-46所示。
图1-45 示例程序
图1-46 DtDebug加载示例程序后的界面
图1-46中标注的4个窗口,分别为汇编窗口、寄存器窗口、内存窗口、堆栈窗口。
■汇编窗口
简单介绍汇编窗口,汇编窗口由内存、特征码、汇编、标注区(从左向右)这四块组成。
一个程序运行以后,处理器会一行行的执行它的代码,如图1-46处理器会沿着汇编窗口从上往下一行行执行代码,直至结束。跟着操作时肯定会有如下疑问,首先没有看到被调试的程序运行,其次汇编窗口并没有从上往下一行行执行代码。接下来解答一下,DTDebug软件是可以中断当前运行的程序的,如图1-46黄色区域中写着Paused 表示当前程序是被中断的,其次接着看图1-46汇编窗口中有黑色区域表示当前被调试的程序被中断在这块内存区域。该块区域是被调试程序的入口点。【文中讲到的中断指:处理器运行到该段程序时,让该程序停止运行了】。 那怎么让程序一行行往下执行呢?看图1-46中有一个三角符号
,按下程序将会一行行往下执行,此时被调试的程序就会运行起来。
接下来介绍寄存器窗口。
■寄存器窗口
简单介绍寄存器窗口,寄存器窗口由EAX、ECX、EDX、EBX、ESP、EBP、ESI、EDI这8个通用寄存器,还有EIP寄存器、EFLAGS寄存器及它们相对应存储的数值。
EIP、EFLAGS寄存器与8个通用寄存器的区别在于,以EAX寄存器为例,EAX寄存器可以任意读写数据,而EIP寄存器,它的作用是存放当前代码段即将被执行的下一条指令的地址,不可以随意读写,如图1-44寄存器窗口所示,EIP当前存储的值为:004185B7,看汇编窗口黑色区域和EIP存储的值是一样的。EFLAGS是标志寄存器,状态标志位记录算术逻辑运算的结果,控制标志位控制计算机的运行,系统标志位记录系统信息。
寄存器窗口简单介绍完了,调试器的简单使用方法我们将在具体的实验中再详细讲述。
【注】读者也可以使用ollydbg调试器,具体的使用方法与DTDebug调试器完全相同。DTDebug.exe调试器是ollydbg调试器的一个改版。
1.3.3 x64dbg调试器
在上一小节中我们介绍了三环32位调试器DTDebug的使用方法。接下来我们介绍另一个开源的三环64位调试器x64dbg。
x64dbg是一款开源的Windows x64和x86调试器,用于逆向工程、漏洞研究和软件调试等领域。它提供了强大的调试功能和用户友好的图形界面,可以帮助分析人员理解和修改二进制程序的执行过程。
■以下是x64dbg调试器的一些主要特点和功能:
●调试功能: x64dbg支持程序的单步执行、断点设置、寄存器和内存的查看和修改,以及调试事件的监视和处理。它可以帮助分析人员跟踪程序的执行流程、观察变量的值,并进行动态调试和分析。
●图形化界面: x64dbg提供了直观且用户友好的图形用户界面,包括可视化的寄存器和内存查看、代码和数据窗口以及调试器控制面板。这使得调试过程更加方便和可视化。
●插件支持: x64dbg支持插件扩展,允许用户编写自定义插件来增强调试功能和添加新的特性。用户可以使用C++或插件开发框架(如x64dbg Plugin SDK)来开发自己的插件。
●反汇编和分析: x64dbg内置了Capstone引擎,可以将机器码反汇编为可读的汇编代码,帮助分析人员理解程序的执行逻辑。它还提供了IDA Pro和Hopper等第三方反汇编工具的集成支持。
●脚本支持: x64dbg内置了Python脚本引擎,允许用户编写脚本来自动化调试任务和执行自定义分析。用户可以使用Python脚本来编写断点脚本、自定义命令和插件。
●多重数据表示: x64dbg支持多种数据表示,包括十六进制、十进制、ASCII、UNICODE等,方便分析人员查看和修改不同类型的数据。
x64dbg是一款功能强大且灵活的调试器,适用于各种逆向工程和软件调试任务。它的开源性质使其能够不断演进和受到社区的支持,提供了丰富的功能和可定制性。
如果我们熟悉了DTDebug调试器的使用方法,使用x64dbg将是一件非常简单的事情。打开x64dbg调试器,界面如图1-47所示。可以在“文件“菜单选择打开或附加当前活动的进程,或者直接将程序拖入窗口内。x64dbg调试器的窗口布局和DTDebug调试器也几乎是一样的,这里不再赘述。在后续的实验中,我们再详细讲述具体的使用方法。
图1-47 使用x64dbg调试器打开进程
1.3.4 Windbg调试器
Windbg是一款由微软提供的强大的调试器工具,主要用于Windows操作系统和应用程序的调试和分析。它提供了许多高级调试功能和命令,使开发人员和调试人员能够深入分析应用程序的内部工作和问题。
■以下是Windbg调试器的一些主要功能和特点:
●内核级调试:Windbg可以用于调试Windows操作系统的内核模式和用户模式。它可以连接到正在运行的操作系统内核,以诊断和解决各种系统级问题,例如驱动程序崩溃、蓝屏错误等。
●用户模式调试:Windbg可以用于调试应用程序的用户模式。它可以加载可执行文件或动态链接库,并允许用户设置断点、追踪代码执行、查看变量和内存内容等。
●符号文件支持:Windbg可以与符号文件(.pdb文件)一起使用,以提供更详细的调试信息。符号文件包含了应用程序或操作系统的函数、变量和调试信息,可以帮助开发人员更好地理解代码和问题。
●调试扩展:Windbg支持调试扩展,这些扩展可以为调试器提供额外的功能和命令。例如,可以使用扩展来分析内存转储文件、查看线程堆栈跟踪、分析性能问题等。
●调试脚本:Windbg支持使用JavaScript脚本进行自动化调试和分析。开发人员可以编写脚本来执行自定义的调试操作,自动化执行复杂的调试任务。
●远程调试:Windbg可以通过网络连接到远程计算机进行调试。这对于调试在远程计算机上运行的应用程序或操作系统非常有用,可以通过网络收集调试信息和诊断问题。
Windbg是一个强大而灵活的调试器工具,适用于各种调试场景和需求。它广泛应用于Windows驱动程序开发、应用程序调试、漏洞分析、恶意代码分析等领域。然而,使用Windbg需要一定的学习和熟练掌握,因为它提供了丰富的功能和复杂的命令集。
由于本书仅涉及用户模式调试,因此这里仅限对用户模式调试的介绍。
Windows调试工具(Debugging Tools for Windows)由调试器、工具以及软件包中调试器的相关文档组成。这个工具包可以作为Windows SDK或者WDK的一部分安装。可以从编程达人官网直接下载Windbg调试器,或者在微软的MSDN网站下载Windows SDK。工具包中包括四个调试器:Cdb.exe、Ntsd.exe、Kd.exe和WinDbg.exe。我们仅介绍WinDbg用户模式调试的一些简单使用方法。
■WinDbg简介
在Visual Studio中调试时,大部分的功能是借助菜单或按钮实现,而Windbg调试器是建立在命令之上。
用户输入一个命令,调试器用文本描述命令执行的结果给出响应。
在GUI模式下,一些结果用专门的窗口进行显示,比如局部变量、栈、线程等。
正是因为这种调试模式,所以Windbg调试器学习的门槛就要相对高一些,得记这些命令。
■Windbg调试器的使用
Windbg分32位和64位版本,32位程序应使用32位Windbg调试,64位程序应64位Windbg调试。我们以notepad记事本为例进行演示。
●加载符号
打开Windbg调试器,点击菜单“File->Symbol File path…”,输入符号保存路径:
SRV*c:\mysymbol* Symbol information
命令行窗口输入命令:.reload 重新载入符号。
●调试步骤
方法1:File->Open Executable(打开一个.exe可执行文件)->在Windbg窗口执行g(Go);出现如下错误:
ERROR: Symbol file could not be found. Defaulted to export symbols for ntdll.dll -
ntdll!LdrInitShimEngineDynamic+0x35c:
以Viusal Studio为例,一般发布给客户的程序,我们采用Release模式编译程序,而Release模式与Debug模式,有个很大的区别:Release模式编译出来的程序默认是不带PDB相关信息的,而Debug模式则有。
没有设置符号信息的路径,所以找不到符号。这里所说的符号信息就指上述PDB文件,并且在默认Release模式编译出来的程序,会带有一个同名的PDB文件。你也可以通过配置Visual Studio的配置项来决定是否产生PDB文件:
项目属性->链接->Debugging->生成debug信息(Generate Debug Info)。
方法2:先运行一个.exe->File->attach to a process。
按下快捷键Ctrl+Break断下,F5运行。
■Windbg支持三类命令:
●内部命令:这些命令内建于调试器之中,操作被调试的目标。
• g 运行
• t 单步步入
• p 单步步过
• r 查看和修改寄存器
●元命令:这些命令以(.)开头,操作调试进程自身,不直接操作被调试的目标。
• .reload 重新载入符号
• .reboot 重启目标机器
• .restart 重启调试器
• .logfile 显示信息
●扩展命令:这些命令以(!)开头,为调试器提供了很多功能。
!mona是一款由Corelan Team开发的Windbg调试器扩展,用于辅助漏洞开发和渗透测试。它提供了一系列有用的命令和功能,用于自动化和简化常见的漏洞开发任务。
以下是一些!mona常用命令和功能的示例:
!mona config:显示和配置!mona的一些全局设置,如堆栈溢出检测选项、模块选项等。
!mona modules:列出目标进程加载的所有模块,包括基址、大小、模块路径等信息。
!mona find:用于在目标进程的内存中查找特定的字符串、指令、模式等。可以用于寻找可利用的漏洞。
!mona pattern_create:生成指定长度的模式字符串,用于寻找漏洞的偏移量。
!mona pattern_offset:在模式字符串中查找特定的偏移量,用于确定漏洞的溢出点。
!mona seh:用于查找目标进程中的SEH(Structured Exception Handling)链,用于发现和利用SEH溢出漏洞。
!mona jmp:用于生成各种类型的跳转指令,用于利用栈溢出漏洞。
!mona compare:用于比较两个模块的不同之处,用于发现功能和代码的漏洞。
!mona bytearray:生成指定长度的随机字节,用于测试缓冲区溢出漏洞。
所有扩展命令均在外部DLL中实现。 默认情况下,调试器加载一组预定义的扩展DLL,但是通过使用.load命令可以从Debugger目录或其他目录中加载更多DLL。
【说明】Windbg是大小写不敏感的,所以在输入命令时,大小写都可以。
■常用调试命令:
1. x:以通配符的方式检查一个模块内的符号地址 。
例如:x nt!Psp* (显示内核里所有以Psp开头的内核符号) 。
2. lm:显示所有已加载的模块列表 。
3. dd:显示一个地址起始的32位整数值(默认显示32个整数,每行4个,共8行) 。
例如: dd 1014db0 L1 (L1表示只显示一个整数) 。
4. du:显示UNICODE形式的字符串 。
5. .formats <数字> :以各种进制显示这个数字 。
6. !process 0 0:打印系统中所有进程(只在内核调试下有效)。
!process <EPROCESS> : 显示一个进程的关键信息 。
7. !dd:显示物理地址(只在内核调试下有效)。
8. 使用Windbg在内核调试下调试用户进程。
!process 0 0 列出所有进程 。
.process /p <EPROCESS> 切换到应用进程的地址空间 。
.reload /f /user 重新加载此进程用户空间的符号信息 。
.process /i /p <EPROCESS> 以入侵且禁止缓存映射地址的方式重新切换地址空间 。
bp <xxx> 下应用层断点 。
9. bl:查看已设置的断点列表 。
10. bc:取消一个断点 。
11. ba:设定一个内存访问断点 。
例如:ba w1 0042201c
ba r2 0042201c
12. r:显示寄存器的值 。
13. u:反汇编,例如: u 401500 L9 反汇编当前地址以后的9条指令 。
14. ub:向前反汇编,例如: ub 4014f9 L2 反汇编当前地址之前的两条指令 。
15. k:显示栈回溯 。
16. kp:显示栈回溯并且显示每个函数被调用时的参数信息 。
17. g:继续执行程序 。
18. dt:显示类型结构命令 。
例如在内核调试下:
dt _EPROCESS <某进程的EPROCESS首地址>
19. 在内核调试下显示一个进程的PEB信息 。
.process <EPROCESS> 先切换到某个进程的上下文 。
dt _PEB <PEB地址> 显示进程的环境块信息 。
20. ln [address]:显示指定地址的类型信息,或临近address的符号的类型信息,address为可选.。
21. ~* kp:显示所有线程的栈回溯 。
22. ~*:显示所有线程(同时也显示出线程的启动函数的地址) 。
23. dt ntdll!*create*:显示一个模块内的所有结构体类型名 。
24. !handle:查看句柄(表) 。
25. uf <function address> :反汇编函数 。
26. !peb [address] :显示一个进程的进程块信息 。
27. !object 查看内核对象,格式如下:
Usage: !object [-p] | [[<Path>] | [<Address>] | [0 <TypeName>]]
28. t:单步跟入
tc: 单步跟入直到一个call为止。
Tct:单步跟入直到一个call或ret为止。
tt: 单步步入直到一个ret为止。
29. p:单步步过. pc: 单步步过直到一个call为止. pct: 单步步过直到一个call或ret为止。
Pt:单步步过直到一个ret为止。
29. bu kernel32!BaseProcessStart :设置一个延迟的以后再落实的断点 。
【 注】上面这个命令常用来对还没有加载的模块内的函数设置断点。
■调试技巧
在开始调试之前,有几个要点,记住以下几个点对于调试事半功倍
• 直接按回车可以执行上一条命令。
• 使用分分号作为分隔符,可以在同一行输入多条命令。
• 按上下方向键可以浏览和选择以前输入过的命令。
• 当命令提示符显示为BUSY时,即使命令编辑框可以输入命令,但是这个命令也不会被马上执行,要等WinDBG恢复到空闲状态才能执行。
• 使用Ctrl+Break 来终止一个长时间未完成的命令。如果使用KD或则CDB,那么用Ctrl+C。
• 选择菜单->Edit_>Write Window Text to File可以把之前敲过的所有命令记录到文件 。