第二十九篇:USER MODE DLL开发过程中的调试技巧心得分享

2024-08-29 17:08

本文主要是介绍第二十九篇:USER MODE DLL开发过程中的调试技巧心得分享,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

最近由于项目需要,被老板安排开发一个WINDOWS USER MODE DLL, 即WINDOWS用户模式下的动态链接库。


写代码,实现具体的功能这类初等工作,对于大多数软件开发工程师来讲,只是时间与工作量上的问题,具体的WINDOWS DLL的知识点,本人参考了Jeffrey Richter的《WINDOWS核心编程》中的DLL几章,不再熬述。


这里谈一下关于USER MODE DLL在调试过程中所涉及到的一些知识点,以及它们彼此之间的关系:

1. DebugBreak / int 3;

2. OutputDebugString

3. bcdedit /debug (on/off)

4. Windbg user/kernel mode debug

5. IsDebuggerPresent() 函数返回值

6. DebugView.exe

7. EPROCESS.debugport

8. PEB.beingdebugged


1. DebugBreak / __asm int 3; 起到中断到调试器的功能。

在DLL初步编码完成,第一次上系统跑的时候,可以在DllMain中尝试加入它们,以确定DLL是否被服务或者EXE正确调用。

当然,也可以在其它阶段的函数中调用,不过,笔者在该断点HIT之时,通过.reload /f命令,正确加载了调试符号,就可以通过动态设置、取消断点的方式来继续进一步的调试。


2. OutputDebugString & DebugView.exe & Windbg user/kernel mode & IsDebuggerPresent

以及EPROCESS.debugport & PED.beingdebugged

这些个因素有他们之间的彼此关联。

首先,必须的一步,在Win7,8,8.1上使用DebugView.exe必须在注册表中加入:

HKLM/SYSTEM/CurrentControlSet/Control/Session Manager

Debug Print Filter (Key)

DWORD(type),DEFAULT (name)0xF(value)

其次,OutputDebugSting函数本质上是通过异常机制工作的(raise exception), 具体的理论方面的内容请参考张银奎《software debugging》, chapter 10.

这里只谈本人的一点实践经验。

第一,在目标进程没有被Windbg Attach的时候,即目标进程不处于被调试状态,在这种状态下,目标程序的EPROCESS.debugport == NULL, PEB.beingdebugged == FALSE.

IsDebuggerPresent()函数的判断依据实则为PEB.beingdebugged, 在没有被windbg attach时,返回为FALSE。


如果在你的代码中,有下面的代码段,OutputDebugString输出"Debugger not Present"到DebugView.exe中.

if(IsDebuggerPresent()){
OutputDebugString(TEXT("Debugger Present\n"));
}else{
OutputDebugString(TEXT("Debugger not Present\n"));
}

但是,当有windbg attach到目标进程,该目标进程进入到被调试状态,以上代码则输出“Debugger Present”到Windbg的Command窗口。

值得注意的是,IsDebuggerPresent()只与windbg attach有关,与系统是否处于kernel debug无关。

进一步讲,当目标进程被windbg attach后,上述进程处于user mode debug状态,进入user mode debug状态,则影响了EPROCESS.debugport与PEC.beingdebugged.

而通过设置NET双机调试,利用DebugBreak/int 3; 将DLL中断到windbg, 该行为并不影响以上两个变量,因为,此时目标进程处于kernel mode debug,从而IsDebuggerPresent返回为FALSE。


3. bcdedit /debug on/off & DebugBreak/int 3;

bcdedit /debug on的状态下, DebugBreak/int 3;会中断到调试器,如果此时系统没有双机联调,或者进程没有被attach, 具体表现则是系统一直pending.

bcdedit /debug off的状态下,DebugBreak/int 3;产生异常, 但由于该异常并未中断到调试器,该异常得不到正确处理,系统最终将该进程结束。


4. bcdedit /debug on/off & Windbg user/kernel mode & DebugBreak/int 3;

最后,来讲一讲他们之间的关系。

DebugBreak/int 3;作为一种异常,总归要有东西去处理。

假设, 被调试机器(target),既通过NET连接到了调试主机(host,此时bcdedit /debug on), 又在本地通过WINDBG ATTACH到了目标进程。

在这种情况下,DebugBreak/int 3;首先被本地WINDBG处理, 既中断到本地的WINDBG。

如果目标进程未被WINDBG ATTACH,则该异常中断到主机的WINDBG。

但是,如果此时也没有远程(NET)HOST WINDBG连接,则造成一个无东西处理的内核异常,则出现上面所说的,系统PENDING。


而在bcdedit /debug off并且既没有远程也没有本地WINDBG,则这是无东西处理的用户异常,最终,系统将该进程终止掉了。



后记:

EPROCESS的成员DebugPort是一个数据结构,作为调试子系统与调试器交互的一种通道(手段)。

其主要的数据成员包括一个EVENT用来信号通知,一个MUTEX用来同步链表操作,以及LIST_ENTRY用来排列调试事件。


DebugBreak的内核函数为DbgBreakPoint.


写代码是正面交战,敌人在明处,花时间与功夫,一点点地编码调试总归能够完成任务。

调试则正好相反,调试环境的搭建,调试关键知识的掌握,以及躲在暗处的BUG,从经验与系统知识上来讲,需要更加扎实的功底。


前阵子翻过一下张银奎的《software debugging》, 1000多页的内容,让人看了后面,忘了前面。

纠其原因,就是看书的方法不当,以软件开发的的思维习惯与软件开发的经验去看这本书,只能是花了时间功夫多,收获甚少。

但在开发这个DLL项目过程当中,实实在在地将一些调试方面的知识应用在实际当中,有了问题查找资料,然后再实践,之后,通过《software debugging》这本书,confirm遇到的这些调试知识点,调试技巧,达到举一反三,融会贯通的效果,将调试的基本观念用在软件开发的过程当中,才是实实在在的积小流,积跬步的过程。

这篇关于第二十九篇:USER MODE DLL开发过程中的调试技巧心得分享的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1118456

相关文章

python设置环境变量路径实现过程

《python设置环境变量路径实现过程》本文介绍设置Python路径的多种方法:临时设置(Windows用`set`,Linux/macOS用`export`)、永久设置(系统属性或shell配置文件... 目录设置python路径的方法临时设置环境变量(适用于当前会话)永久设置环境变量(Windows系统

python运用requests模拟浏览器发送请求过程

《python运用requests模拟浏览器发送请求过程》模拟浏览器请求可选用requests处理静态内容,selenium应对动态页面,playwright支持高级自动化,设置代理和超时参数,根据需... 目录使用requests库模拟浏览器请求使用selenium自动化浏览器操作使用playwright

Mysql中设计数据表的过程解析

《Mysql中设计数据表的过程解析》数据库约束通过NOTNULL、UNIQUE、DEFAULT、主键和外键等规则保障数据完整性,自动校验数据,减少人工错误,提升数据一致性和业务逻辑严谨性,本文介绍My... 目录1.引言2.NOT NULL——制定某列不可以存储NULL值2.UNIQUE——保证某一列的每一

解密SQL查询语句执行的过程

《解密SQL查询语句执行的过程》文章讲解了SQL语句的执行流程,涵盖解析、优化、执行三个核心阶段,并介绍执行计划查看方法EXPLAIN,同时提出性能优化技巧如合理使用索引、避免SELECT*、JOIN... 目录1. SQL语句的基本结构2. SQL语句的执行过程3. SQL语句的执行计划4. 常见的性能优

PyQt5 GUI 开发的基础知识

《PyQt5GUI开发的基础知识》Qt是一个跨平台的C++图形用户界面开发框架,支持GUI和非GUI程序开发,本文介绍了使用PyQt5进行界面开发的基础知识,包括创建简单窗口、常用控件、窗口属性设... 目录简介第一个PyQt程序最常用的三个功能模块控件QPushButton(按钮)控件QLable(纯文本

电脑提示d3dx11_43.dll缺失怎么办? DLL文件丢失的多种修复教程

《电脑提示d3dx11_43.dll缺失怎么办?DLL文件丢失的多种修复教程》在使用电脑玩游戏或运行某些图形处理软件时,有时会遇到系统提示“d3dx11_43.dll缺失”的错误,下面我们就来分享超... 在计算机使用过程中,我们可能会遇到一些错误提示,其中之一就是缺失某个dll文件。其中,d3dx11_4

OpenCV在Java中的完整集成指南分享

《OpenCV在Java中的完整集成指南分享》本文详解了在Java中集成OpenCV的方法,涵盖jar包导入、dll配置、JNI路径设置及跨平台兼容性处理,提供了图像处理、特征检测、实时视频分析等应用... 目录1. OpenCV简介与应用领域1.1 OpenCV的诞生与发展1.2 OpenCV的应用领域2

linux下shell脚本启动jar包实现过程

《linux下shell脚本启动jar包实现过程》确保APP_NAME和LOG_FILE位于目录内,首次启动前需手动创建log文件夹,否则报错,此为个人经验,供参考,欢迎支持脚本之家... 目录linux下shell脚本启动jar包样例1样例2总结linux下shell脚本启动jar包样例1#!/bin

游戏闪退弹窗提示找不到storm.dll文件怎么办? Stormdll文件损坏修复技巧

《游戏闪退弹窗提示找不到storm.dll文件怎么办?Stormdll文件损坏修复技巧》DLL文件丢失或损坏会导致软件无法正常运行,例如我们在电脑上运行软件或游戏时会得到以下提示:storm.dll... 很多玩家在打开游戏时,突然弹出“找不到storm.dll文件”的提示框,随后游戏直接闪退,这通常是由于

java内存泄漏排查过程及解决

《java内存泄漏排查过程及解决》公司某服务内存持续增长,疑似内存泄漏,未触发OOM,排查方法包括检查JVM配置、分析GC执行状态、导出堆内存快照并用IDEAProfiler工具定位大对象及代码... 目录内存泄漏内存问题排查1.查看JVM内存配置2.分析gc是否正常执行3.导出 dump 各种工具分析4.