总在用户态调试 C# 程序,终还是搭了一个内核态环境

一:背景

一直在用 WinDbg 调试用户态程序,并没有用它调试过 内核态,毕竟不是做驱动开发,也没有在分析 dump 中需要接触用内核态的需求,但未知的事情总觉得很酷,加上最近在看 《深入解析 Windows 操作系统》 一书,书中有不少案例需要深入到 内核态 ,所以这篇准备整理一下如何用 WinDbg 调试 C# 内核态吧。

操作环境:

  • Windbg Preview

  • 宿主机:Windows 10

  • 虚拟机:Windows 10

二:搭建内核态调试

1. 基本原理

操作系统的引导程序 BootMgrWinLoad 内置了调试模式,支持以 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, 在我的界面上大概是这个样子:

f77ac1946477acde26718b9f58db9305.png

3. 配置 COM 接口

这里有几个步骤要注意了,大致如下:

1) 把打印机选项移除了,因为它占用了 COM1 接口。

2) 新增一个 串行端口

3)在 使用命名管道 中填入 \\.\pipe\com_1, 同时勾选 轮询时主动放弃CPU

设置完之后点击确定,完整截图如下:

09280b109c57f89452620a948b71cd04.png

4. 配置 Windbg Preview

我们把 WinDbg 打开,选择 Attach to kernel 选项,然后选择 COM 模式,设置 Baud Rate = 115200 ,然后是 Port=\\.\pipe\com_1 ,配置完之后点击 OK, 完整截图如下:

07d57a797c6ad1a67d763a3c5dcd9c4d.png

如果一切正常的话,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 时配置的,我们选择它就好了,完整截图如下:

b7ad629fea1e6c58b5b85604d83bd52c.png

稍等片刻后 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 从用户态切到内核态的过程,还画了一张图。

0eb9b658a6a905d50ab9dd83fc2a51b9.png

现在可以调试 内核态 那何不试试看呢???哈哈,说干就干,先上一段测试代码。

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"

e0ca070f780a257e3c8612c55ea6bab4.png

可以看到每次只要程序输出一次,windbg10 都能成功拦截,接下来在宿主机的 WinDbg Preview 中先输入 .reload 重新加载下符号,目的就是方便看到用户态上的 ntdll.dll 函数名,但不一定好使,碰碰运气吧,接下来输入 nt!NtReadFile 观察内核态栈。

bp nt!NtReadFile

a579cbb4bdf2c924e7d65ef73cd2c0ac.png

从新老Windbg截图中,可以清晰的看到,这个的 Child-SP 线程栈终于对接上了,也就验证了图上所说:ntdll!NtReadFile (用户态网关) -> nt!KiSystemServiceCopyEnd(内核态调度中心) -> nt!NtReadFile (内核态处理函数)

好了,本篇就先说这么多,希望对大家有帮助,也是对自己的一个总结。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/283123.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

bat kafka启动_windows下搭建Kafka,并通过命令窗口收发消息

参考网址:前提条件:windows环境需要安装jdk2.由于Kafka依赖于zookeeper,所以也需要下载zookeeper,可以通过官网下载http://zookeeper.apache.org/3.安装zookeeper将压缩包解压后,到bin目录下,启动zkServer.bat即可注意…

异常处理、socke基于TCP协议编程

一、异常处理 1、错误和异常 1.程序中难免出现错误,而错误分成两种 (1)语法错误(这种错误过不了Python解释器的语法检测,必须在程序执行前改正) #语法错误示范一 if#语法错误示范二 def test:pass#语法错误…

windows下apache报错The requested operation has failed解决方法

2019独角兽企业重金招聘Python工程师标准>>> Apache报错The requested operation has failed,基本上是因为端口被占用。解决方法如下: 第一步,运行cmd,cd 定位到Apache安装目录的bin目录下,输入httpd.exe -…

stm32 usmart使用

我直接用正点原子给的,步骤如下 先添加三个.c进工程,添加两个头文件的编译路径 #include "usart.h"#include "usmart.h" main函数里添加如下 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2 uart_init(960…

Istio 1.15 发布,支持 arm64 架构处理器

Istio 是基于容器的云原生技术栈的三大核心技术之一,另外两个是 Kubernetes 和 Knative。其中 Kubernetes 和 Knative 早已支持了 arm64 架构,甚至连 Istio 的数据平面 Envoy 早在 1.16 版本 [1] 就已支持 arm64 架构(2020 年 10 月&#xff…

TP框架表单验证 【包含ajax方法】

之前的表单验证都是用js写的,这里也可以使用tp框架的验证。但是两者比较而言还是js验证比较好,因为tp框架验证会运行后台代码,这样运行速度和效率就会下降。  自动验证是ThinkPHP模型层提供的一种数据验证方法,可以在使用create创…

Spring 入门学习二之IOC

今天来学习Spring ioc .一、spring jar 包导入 在 spring 官网下载开发包 spring-framework-4.2.4.RELEASE,然后导入需要的 jar 包到项目 /lib/ 目录下。  二、代码开发 新建一个 src/cn/sxt/bean/Hello.java文件 package cn.sxt.bean;/*** Created by kaiyiwang o…

java 物理内存_聊聊Java中的内存

JVM的内存先放一张JVM的内存划分图,总体上可以分为堆和非堆(粗略划分,基于java8)那么一个Java进程最大占用的物理内存为:Max Memory eden survivor old String Constant Pool Code cache compressed class space Metaspace Thread st…

.Net CoreRabbitMQ基本使用

队列模式https://www.rabbitmq.com/getstarted.html对以上几种模式进行简要分类,可以分成如下三类(RPC暂不考虑)简单队列模式,单发单收,一对一模式Worker模式,单发多收(一个消息一个接收者,多个消息多个接收者)&#x…

Linux包系列的知识(附:Ubuntu16.04升级到18.04的案例)

Linux基础:https://www.cnblogs.com/dunitian/p/4822808.html#linux 之前看到朋友还动不动 apt-get update upgrade,就很纳闷,后来发现原来他只是知道这个更新命令却不知其意,所以每次安装个包就把所有apt-get的常用清除更新命令打…

java获取tomcat目录结构_Tomcat目录结构详解

Tomcat目录结构图如下:bin目录存放一些可执行的二进制文件,.sh结尾的为linux下执行命令,.bat结尾的为windows下执行命令。catalina.sh:真正启动tomcat文件,可以在里面设置jvm参数。startup.sh:启动tomcat(需…

智慧农业物联网云平台方案

2019独角兽企业重金招聘Python工程师标准>>> 多比智慧农业物联网云平台解决方案结合了最先进的物联网、云计算、传感器、自动控制等, 在浏览器或手机客户端实时显示大棚、大田、温室等温度、湿度、PH值、光强度、CO2,或作为自动控制的参变量参与到自动控…

使用JDBC获取Oracle连接时报错

The Network Adapter could not establish the connection 网络适配器不能创建连接 作为初学者的来说,这个问题让我找了好多次,每次重新开启电脑时就可以正常获取连接,过了一会儿,自己不知道做了什么就会又报错,…

.Net CoreRabbitMQ消息转发可靠机制(上)

前言生产者发送消息到了队列,队列推送数据给了消费者,这里存在一些问题需要思考下生产者如何确保消息一定投递到了队列中RabbitMQ 丢失了消息(下文暂不涉及这块)队列如何确保消费者收到了消息呢生产者可靠发送执行流程当生产者将消息发送出去后&#xff…

一个java文件中可包含多个main方法

java中的main方法是java应用程序的入口,java程序在运行时,首先调用执行main方法。但并不是说java中只能有一个main方法,不同类中都可以包含main方法。当JVM进行编译时,会提示选择其中一个main方法作为编译的入口。 转载于:https:/…

【SRM-05 B】无题?

Description 有一个拥有n个城市的国家。这个国家由n-1条边连接起来。有一天国家发生叛乱。叛军已占领了一些城市。如果叛军占领的城市中,存在两个城市之间有边直接相连,则称这种情况是坏的。现在并不知道叛军占领了那些城市,问有多少种情况是…

分享一些 Java 后端的个人干货

学习 Java 也有了不少时间,入 Java 后台的坑也有了一段时日。这段时间里,听过许多前辈的经验与分享,也看过许多大佬的文章和作品。找了个时间整理和总结了一下我个人到目前为止一路以来的听到看到或者自己感悟到的干货。 这篇文章可能更多的是…

.NET MAUI实战 Routing

1.详情本章继续分享.NET MAUI中的路由,这个概念依旧是在Prism里存在过的概念。如果使用过Prism框架的小伙伴使用该机制上手速度是非常快的。接下来一起来看看什么是路由。.NET 多平台应用 UI (.NET MAUI) Shell 包含基于 URI 的导航体验,该体验使用路由导…

分享Web应用运行的细节问题:预编译提高网站性能、跟踪用户习惯和解决线程同步...

在这个文章里,我将分享一下在iOpenWorks.com这个网站试运行中碰到的若干问题和解决方案,这些问题包含了:(1)如何通过ASP.NET MVC预编译提高性能;(2)如何知道网站在运行中&#xff0c…

mondrain配置mysql_mondrian 4.7 源码部署(示例代码)

mondrian是一个开源的数据分析工程, 网上有关mondrian3.X的源码部署比较多, 有关4.X的部署较少. 目前官方推荐使用的时mondrian3.7的修订版, 可以再github上下载到最近更新维护的mondrian-master, 下载下来后基本上只需要按部就班的使用maven build一下就可以正常使用了, 如有问…