总在用户态调试 C# 程序,终还是搭了一个内核态环境
一:背景
一直在用 WinDbg 调试用户态程序,并没有用它调试过 内核态
,毕竟不是做驱动开发,也没有在分析 dump 中需要接触用内核态的需求,但未知的事情总觉得很酷,加上最近在看 《深入解析 Windows 操作系统》 一书,书中有不少案例需要深入到 内核态
,所以这篇准备整理一下如何用 WinDbg 调试 C# 内核态吧。
操作环境:
- Windbg Preview
- 宿主机:Windows 10
- 虚拟机:Windows 10
二:搭建内核态调试
1. 基本原理
操作系统的引导程序 BootMgr
和 WinLoad
内置了调试模式,支持以 COM 接口互通,所以我们需要先添加一种可供调试的启动项,供引导程序 BootMgr
启动时弹框让我们选择。
2. 配置调试启动项
大家可以在 https://msdn.itellyou.cn/
下载一个完整版的 Window10 ISO 包,这里就不细说了,启动虚拟机进入 Windows10 ,以管理员模式打开 CMD
窗口,执行如下 四条命令 来编辑 bcd (Boot Configuration Data)
。
bcdedit /dbgsettings serial baudrate:115200 debugport:1
bcdedit /copy {current} /d WinDbg
bcdedit /displayorder {current} {ID}
bcdedit /debug {ID} ON
注意一下,这里的 {ID}
是 CMD 上生成的 GUID,这是你的启动项唯一键,别名是 WinDbg
, 在我的界面上大概是这个样子:
3. 配置 COM 接口
这里有几个步骤要注意了,大致如下:
1) 把打印机
选项移除了,因为它占用了 COM1 接口。
2) 新增一个 串行端口
。
3)在 使用命名管道
中填入 \\.\pipe\com_1
, 同时勾选 轮询时主动放弃CPU
。
设置完之后点击确定,完整截图如下:
4. 配置 Windbg Preview
我们把 WinDbg 打开,选择 Attach to kernel
选项,然后选择 COM
模式,设置 Baud Rate = 115200
,然后是 Port=\\.\pipe\com_1
,配置完之后点击 OK, 完整截图如下:
如果一切正常的话,Windbg 应该是如下输出,等待COM连接状态。
Microsoft (R) Windows Debugger Version 10.0.25136.1001 AMD64
Copyright (c) Microsoft Corporation. All rights reserved.
Waiting for pipe \\.\pipe\com_1
Waiting to reconnect...
5. 启动虚拟机
这些都配置完之后,我们重新启动虚拟机,在 BootMgr 阶段会出现两个引导项,其中一个就是在 小项2
时配置的,我们选择它就好了,完整截图如下:
稍等片刻后 WinDbg 会显示连接成功,在进入初始化时会 int 3 中断, 如果你真的到了这一步,那恭喜你!!!
Microsoft (R) Windows Debugger Version 10.0.25136.1001 AMD64
Copyright (c) Microsoft Corporation. All rights reserved.
Waiting for pipe \\.\pipe\com_1
Waiting to reconnect...
Connected to Windows 10 10240 x64 target at (Thu Sep 1 23:23:35.235 2022 (UTC + 8:00)), ptr64 TRUE
Kernel Debugger connection established. (Initial Breakpoint requested)
************* Path validation summary **************
Response Time (ms) Location
Deferred srv*c:\mysymbols_fix*https://msdl.microsoft.com/download/symbols
Error D:\net5\ConsoleApp1\Debug
Deferred srv*c:\mysymbols*https://msdl.microsoft.com/download/symbols
Symbol search path is: srv*c:\mysymbols_fix*https://msdl.microsoft.com/download/symbols;D:\net5\ConsoleApp1\Debug;srv*c:\mysymbols*https://msdl.microsoft.com/download/symbols
Executable search path is:
Windows 10 Kernel Version 10240 MP (1 procs) Free x64
Edition build lab: 10240.17394.amd64fre.th1_st1.170427-1347
Machine Name:
Kernel base = 0xfffff802`a3c7b000 PsLoadedModuleList = 0xfffff802`a3fa0070
System Uptime: 0 days 0:00:00.092
nt!DebugService2+0x5:
fffff802`a3dcfca5 cc int 3
因为是初始化中断,接下来在 WinDbg 命令面板中先用 g
执行,让操作系统继续跑下去,稍等片刻就会进入到 Windows 10 的操作界面。
6. netcore 测试
前段时间写了一篇文章,聊到了 ReadFile
从用户态切到内核态的过程,还画了一张图。
现在可以调试 内核态
那何不试试看呢??? 哈哈,说干就干,先上一段测试代码。
static void Main(string[] args)
{
var i = 0;
File.WriteAllText(@"C:\1.txt", "hello world!");
while (true)
{
var str = File.ReadAllText(@"C:\1.txt");
Console.WriteLine($"{i++}, content={str.Length}");
Thread.Sleep(1000);
}
Console.ReadLine();
}
为了方便观察用户态栈,我在虚拟机中的 Windows10 系统上安装一个 WinDbg10
,目的就是拦截 ntdll!NtReadFile
函数时输出 用户态栈
。
bp ntdll!NtReadFile "k 10;gc"
可以看到每次只要程序输出一次,windbg10 都能成功拦截,接下来在宿主机的 WinDbg Preview 中先输入 .reload
重新加载下符号,目的就是方便看到用户态上的 ntdll.dll
函数名,但不一定好使,碰碰运气吧,接下来输入 nt!NtReadFile
观察内核态栈。
bp nt!NtReadFile
从新老Windbg截图中,可以清晰的看到,这个的 Child-SP
线程栈终于对接上了,也就验证了图上所说:ntdll!NtReadFile (用户态网关) -> nt!KiSystemServiceCopyEnd(内核态调度中心) -> nt!NtReadFile (内核态处理函数)
。
好了,本篇就先说这么多,希望对大家有帮助,也是对自己的一个总结。
总在用户态调试 C# 程序,终还是搭了一个内核态环境的更多相关文章
- linux 用户态和内核态以及进程上下文、中断上下文 内核空间用户空间理解
1.特权级 Intel x86架构的cpu一共有0-4四个特权级,0级最高,3级最低,ARM架构也有不同的特权级,硬件上在执行每条指令时都会对指令所具有的特权级做相应的检查.硬件已经提 ...
- linux 用户态 内核态
http://blog.chinaunix.net/uid-1829236-id-3182279.html 究竟什么是用户态,什么是内核态,这两个基本概念以前一直理解得不是很清楚,根本原因个人觉得是在 ...
- 在ubuntu下真机调试android程序出现设备没有访问权限
今天把android的开发环境从windows平台切换到了ubuntu上. java jdk android-adt android-ndk都下好,环境变量都配好之后, 在调试程序的时候,出现设备没有 ...
- Linux 用户态和内核态
1.特权级特权级用来管理和控制程序执行.如Intel x86架构的CPU,有0~3四个特权级,0级最高,3级最低.硬件在执行每条指令时都会检查指令具有的特权级.硬件提供了特权级使用机制,对操作系统来说 ...
- Linux内核态、用户态简介与IntelCPU特权级别--Ring0-3
一.现代操作系统的权限分离: 现代操作系统一般都至少分为内核态和用户态.一般应用程序通常运行于用户态,而当应用程序调用系统调用时候会执行内核代码,此时会处于内核态.一般的,应用程序是不能随便进入内核态 ...
- 2.2.1 用户态、内核态的形成 -《zobolの操作系统学习札记》
内核态的出现,让计算机系统的权力向操作系统高度集中了. 操作系统分出内核态和用户态,就是为了进行不同等级的权限管理, 从而更好的适应多用户多任务并发的工作环境. 用户态和内核态的来源 在早期的单进程单 ...
- Linux内核态抢占机制分析
http://blog.sina.com.cn/s/blog_502c8cc401012pxj.html [摘要]本文首先介绍非抢占式内核(Non-Preemptive Kernel)和可抢占式内核( ...
- Linux内核态抢占机制分析(转)
Linux内核态抢占机制分析 http://blog.sina.com.cn/s/blog_502c8cc401012pxj.html 摘 要]本文首先介绍非抢占式内核(Non-Preemptive ...
- Linux内核态抢占机制分析【转】
转自:http://blog.csdn.net/yiyeguzhou100/article/details/53097665 目录(?)[-] 1非抢占式和可抢占式内核的区别 21 用户态抢占User ...
随机推荐
- TypeScript(4)接口
介绍 TypeScript 的核心原则之一是对值所具有的结构进行类型检查.我们使用接口(Interfaces)来定义对象的类型.接口是对象的状态(属性)和行为(方法)的抽象(描述) 接口初探 声明接口 ...
- SpringCloud Alibaba整合Sentinel
SpringCloud Alibaba整合Sentinel Sentinel 控制台 1. 概述 Sentinel 提供一个轻量级的开源控制台,它提供机器发现以及健康情况管理.监控(单机和集群),规则 ...
- 全新升级的AOP框架Dora.Interception[6]: 实现任意的拦截器注册方式
Dora.Interception提供了两种拦截器注册方式,一种是利用标注在目标类型.属性和方法上的InterceptorAttribute特性,另一种采用基于目标方法或者属性的调用表达式.通过提供的 ...
- VScode中配置Java环境
vscode 中配置Java环境 转载说明:本篇文档原作者[@火星动力猿],文档出处来自哔哩哔哩-[教程]VScode中配置Java运行环境 转载请在开头或显眼位置标注转载信息. 1.下载VScode ...
- 禁用Chrome自动更新
删除下Update目录 C:\Program Files (x86)\Google\Chrome\
- 【ASP.NET Core】选项模式的相关接口
在 .NET 中,配置与选项模式其实有联系的(这些功能现在不仅限于 ASP.NET Core,而是作为平台扩展来提供,在其他.NET 项目中都能用).配置一般从多个来源(上一篇水文中的例子,记得否?) ...
- CF1593D2 Half of Same
题目大意: 给定一个包含 \(n\)(\(n\) 是偶数)个整数的数列 \(a_1,a_2,\ldots,a_n\). 考虑一个可能的正整数 \(k\),在每次操作中,你可以选定一个 \(i\),并将 ...
- 论文解读(MaskGAE)《MaskGAE: Masked Graph Modeling Meets Graph Autoencoders》
论文信息 论文标题:MaskGAE: Masked Graph Modeling Meets Graph Autoencoders论文作者:Jintang Li, Ruofan Wu, Wangbin ...
- Linux中安装JDK详细步骤
一.下载Linux版本的JDK 进入官网下载对应的JDK,下载之前需要先登录 官网地址 -> https://www.oracle.com/ 登录成功后,找到对应的下载位置 根据自己电脑下载对应 ...
- 自定义注解_格式&本质和自定义注解_属性定义
自定义注解: 格式: public @interface 注解名称{} 本质:注解本质上就是一个接口,该接口默认继承Annotation接口 public interface MyAnno exten ...