当前位置: 首页 > news >正文

聊一聊 .NET高级调试 内核模式堆泄露

一:背景

1. 讲故事

前几天有位朋友找到我,说他的机器内存在不断的上涨,但在任务管理器中查不出是哪个进程吃的内存,特别奇怪,截图如下:

在我的分析旅程中都是用户态模式的内存泄漏,像上图中的异常征兆已经明确告诉你了,不是用户态程序吃的内存,那就是内核态程序吃的,比如:

  • 某些驱动程序
  • 操作系统

从概率上来说一般都是某些第三方程序内存泄露导致的,这一篇我们就来聊一聊这种问题该如何解决。

二:内核模式堆泄露分析

1. 驱动程序是如何分配内存的

相信有很多朋友都知道,用户态的程序是直接或者间接的调用 VirtualAlloc 方法来向操作系统要内存,包括 C# 的 GC 堆也是一样,它的方法签名如下:


LPVOID VirtualAlloc([in, optional] LPVOID lpAddress,[in]           SIZE_T dwSize,[in]           DWORD  flAllocationType,[in]           DWORD  flProtect
);

那内核中的驱动程序是如何向操作系统要内存的呢?一般都是调用 ExAllocatePool2 方法来要内存的,签名如下:


DECLSPEC_RESTRICT PVOID ExAllocatePool2(POOL_FLAGS Flags,SIZE_T     NumberOfBytes,ULONG      Tag
);

上面有两个参数要详细解释一下:

  • Flags 参数

一般用的多的就是 POOL_FLAG_NON_PAGEDPOOL_FLAG_PAGED 两种,前者表示分配的内存是需要永久驻留内存,不可以交换到硬盘的。后者分配的内存是可以交换到硬盘的。

  • Tag 参数

这个参数的本意就是方便日后洞察内存泄露的,它强行让一块内存和这个 Tag(4byte的ascii 字符串) 做了强绑定,到时候通过这个 tag 就知道是谁分配的内存。

2. 制造内核模式堆泄露

为了能够让驱动程序泄露,可以使用微软提供的 NotMyFault 工具,这个工具利用 myfault.sys 驱动不断的向操作系统分配内存。官方网址为:https://learn.microsoft.com/zh-cn/sysinternals/downloads/notmyfault

打开 myfault 工具然后输入 40M/s 的泄露,并分配在非换页池中,同时配置下内核态转储dump, 代码和截图参考如下:


ExAllocatePool2(POOL_FLAG_NON_PAGED,40*1024*1024,"Leak");

在泄露的过程中,通过 Process Explorer 很明显的发现提交了 6.7G 的内存,其中有 4.9G 是在 NonPaged 中,即通过上图中的 POOL_FLAG_NON_PAGED 标记分配的,截图如下:

接下来在 MyFault 上切换到 Crash 选项卡,强行让操作系统蓝屏来生成 dump 文件。

3. dump 分析

拿到dump后,先通过 !vm 观察下操作系统级的虚拟内存的分布情况。


3: kd> !vm
...
Physical Memory:          2069421 (    8277684 Kb)
Available Pages:           445015 (    1780060 Kb)
ResAvail Pages:            707292 (    2829168 Kb)
Locked IO Pages:                0 (          0 Kb)
Free System PTEs:      4295052431 (17180209724 Kb)
...
Modified Pages:             11479 (      45916 Kb)
Modified PF Pages:          11479 (      45916 Kb)
Modified No Write Pages:        0 (          0 Kb)
NonPagedPool Usage:       1219892 (    4879568 Kb)
NonPagedPoolNx Usage:       24512 (      98048 Kb)
NonPagedPool Max:      4294967296 (17179869184 Kb)
PagedPool Usage:            32907 (     131628 Kb)
PagedPool Maximum:     4294967296 (17179869184 Kb)
...
NonPagedPool Commit:      1246469 (    4985876 Kb)
...
Sum System Commit:        1409562 (    5638248 Kb)
Total Private:             279673 (    1118692 Kb)********** Sum of individual system commit + Process commit exceeds overall commit by 1952 Kb ? ********
Committed pages:          1688747 (    6754988 Kb)
Commit limit:             4166573 (   16666292 Kb)

从卦中的 NonPagedPool Usage 指标可以看到,当前的 非换页池 占用了 4.8G 内存,总计 121w 的内存页。

接下来就是要深挖下 非换页池 ,看看到底都是什么 Tag 分配的,可以使用 !poolused 2 命令。


3: kd> !poolused 2
....Sorting by NonPaged Pool ConsumedNonPaged                  PagedTag     Allocs         Used     Allocs         UsedLeak       119   4991221760          0            0	UNKNOWN pooltag 'Leak', please update pooltag.txtConT       238     14499840          0            0	UNKNOWN pooltag 'ConT', please update pooltag.txtKETR     16410      8117664          0            0	UNKNOWN pooltag 'KETR', please update pooltag.txtEtwB       196      7565568          2       131072	Etw Buffer , Binary: nt!etw2872         6      5660864          0            0	UNKNOWN pooltag '2872', please update pooltag.txt287R      1026      4183040          0            0	UNKNOWN pooltag '287R', please update pooltag.txtFile      9734      3877408          0            0	File objects Thre      1257      3217920          0            0	Thread objects , Binary: nt!psEtwR     12141      2672640          0            0	Etw KM RegEntry , Binary: nt!etw
...

从卦中数据看,有一个神秘的 Tag=Leak 的内存分配,它分配了 119 次,总大小 4.99G。 哈哈,其实就是刚才通过 MyFault 做的 40M/s 的内存分配。

接下来的问题是:这个 Leak 是哪一个驱动程序所为呢?最简单的办法就是在各个驱动的内存空间中做内存搜索,看看谁里面有 Leak 的asc硬编码,对吧,有了这个思路,先用 lm 看看里面都有哪些 sys 。


3: kd> lm
start             end                 module name
ffffc25c`891b0000 ffffc25c`89480000   win32kbase   (deferred)             
ffffc25c`8a190000 ffffc25c`8a545000   win32kfull   (deferred)     
...                  
fffff807`22600000 fffff807`23646000   nt         (pdb symbols) 
fffff807`23c00000 fffff807`23d16000   clipsp     (deferred)             
fffff807`47f30000 fffff807`47f4b000   monitor    (deferred)             
fffff807`47f50000 fffff807`47f59000   myfault    (deferred)             
...          Unloaded modules:
fffff807`3c6e0000 fffff807`3c6ec000   360Sensor64.sys
fffff807`31550000 fffff807`31560000   dump_storport.sys
fffff807`315a0000 fffff807`315d3000   dump_storahci.sys
fffff807`31000000 fffff807`3101e000   dump_dumpfve.sys
fffff807`26b80000 fffff807`26bac000   luafv.sys
fffff807`26b20000 fffff807`26b30000   dump_storport.sys
fffff807`26b70000 fffff807`26ba3000   dump_storahci.sys
fffff807`26bd0000 fffff807`26bee000   dump_dumpfve.sys
fffff807`28130000 fffff807`2814c000   dam.sys 
fffff807`24200000 fffff807`2420a000   360elam64.sys
fffff807`25230000 fffff807`25241000   hwpolicy.sys

接下来就是写脚本在每个 sys 的 start ~ end 区间做 s 搜索,这个脚本我就不放了,非常简单,最终就在 myfault.sys 中成功找到了 Leak 硬编码,参考如下:


3: kd> lmvm myfault
Browse full module list
start             end                 module name
fffff807`47f50000 fffff807`47f59000   myfault    (deferred)             Image path: \??\C:\Windows\system32\drivers\myfault.sysImage name: myfault.sysBrowse all global symbols  functions  dataTimestamp:        Fri Sep 30 00:17:31 2022 (6335C51B)CheckSum:         00010CEDImageSize:        00009000Translations:     0000.04b0 0000.04e4 0409.04b0 0409.04e4Information from resource tables:3: kd> ? fffff807`47f59000 - fffff807`47f50000
Evaluate expression: 36864 = 00000000`000090003: kd> s -a fffff807`47f50000 L?0x9000  "Leak"
fffff807`47f51559  4c 65 61 6b 0f 42 c1 41-8d 49 fd 8b d0 ff 15 0c  Leak.B.A.I......
fffff807`47f515c7  4c 65 61 6b 0f 42 c1 33-c9 8b d0 ff 15 a0 1a 00  Leak.B.3........

三: 总结

在过往的dump分析中都是用户态程序的泄露,内核态模式堆的的泄露还是第一次分析,不是朋友提供的这次机会,真的就没缘分啦!在这次dump分析过程中,也让大家看到了 windbg 是多么的强大!

相关文章:

聊一聊 .NET高级调试 内核模式堆泄露

一:背景 1. 讲故事 前几天有位朋友找到我,说他的机器内存在不断的上涨,但在任务管理器中查不出是哪个进程吃的内存,特别奇怪,截图如下: 在我的分析旅程中都是用户态模式的内存泄漏,像上图中的…...

海外代理IP在游戏中有什么作用?

随着科技的飞速发展,手机和电脑等电子产品已成为互联网连接万物的重要工具,深度融入我们的日常生活,我们借助互联网完成工作、休闲和购物等任务,以求提升生活质量。 不仅如此,网络游戏也是人们心中最爱,它…...

高防ip适合防御网站和游戏类的攻击吗?

​  作为站长,要学会并承受得住网站外来攻击的压力,尤其是所属为 DDoS 攻击高发行业的网站类业务及游戏行业,是很容易被竞争对手或者一些伪黑客爱好者盯上的。 加上,有些站长并没有提前了解,就盲目进军了这两个行业&…...

HTML5和JS实现明媚月色效果

HTML5和JS实现明媚月色效果 先给出效果图&#xff1a; 源码如下&#xff1a; <!DOCTYPE html> <html> <head><title>明媚月光效果</title><style>body {margin: 0;overflow: hidden;background-color: #000; /* 添加一个深色背景以便看到…...

Django5+DRF序列化

概述 本教程将介绍如何创建一个简单的粘贴板代码高亮 Web API。在此过程中&#xff0c;它将介绍构成 REST 框架的各种组件&#xff0c;让你全面了解所有组件是如何组合在一起的。 本教程相当深入&#xff0c;因此在开始学习之前&#xff0c;你可能需要先吃一块饼干&#xff0…...

什么是编译程序和解释程序

一、编译程序 1、编译器接收源代码作为输入&#xff0c;它会一次性地将整个源代码程序转换成目标代码&#xff08;通常是机器语言或汇编语言&#xff09;&#xff0c;这个过程包括词法分析、语法分析、语义分析、优化以及最终的目标代码生成。2、编译后的目标代码是一个独立的…...

文档审阅批注的合并和对比

#创作灵感# 最近在改论文&#xff0c;Feedback返回的时候&#xff0c;把之前的批注都删了&#xff0c;这就增加了工作量&#xff0c;看起来不方便&#xff0c;所以就需要将删掉的批注全部复原。 那在原来的文档重新在修改一遍&#xff0c;工作量还是很大的&#xff0c;所以这里…...

广义零样本学习综述的笔记

1 Title A Review of Generalized Zero-Shot Learning Methods&#xff08;Farhad Pourpanah; Moloud Abdar; Yuxuan Luo; Xinlei Zhou; Ran Wang; Chee Peng Lim&#xff09;【IEEE Transactions on Pattern Analysis and Machine Intelligence 2022】 2 conclusion Generali…...

java每日一题——输出9x9乘法表(答案及编程思路)

前言&#xff1a; 打好基础&#xff0c;daydayup! 题目&#xff1a;输出下图9x9乘法表 编程思路&#xff1a;java只能输出行&#xff0c;不能输出列&#xff0c;所以考虑好每一行输出的内容即可 public class demo {public static void main(String[] args) {for (int i 1; i…...

Android 车联网——基础简介(一)

传统的车载功能单一,无太多娱乐性,而随着智能化时代的发展,车载系统也被赋予了在系统中预装 Android 应用的能力,基于Android平台的车载信息娱乐系统 —— Android AutoMotive 应运而生。 一、AutoMotive简介 Android Automotive OS 车载操作系统,是一个基本 Android 平台…...

自动驾驶货车编队行驶系统功能规范

货车编队行驶功能规范 Truck Platooning Functional Specification 目录 1 概述... 7 1.1 目的... 7 1.2 范围... 7 1.3 术语及缩写... 7 1.4 参考法规标准... 8 2 功能规范... 9 2.1 功能描述... 9 2.1.1 功能用途…...

javafx

JavaFX JavaFX简介 JavaFX是一个用于创建富客户端应用程序的图形用户界面&#xff08;GUI&#xff09;框架。它是Java平台的一部分&#xff0c;从Java 8开始成为Java的标准库。 JavaFX提供了丰富的图形和多媒体功能&#xff0c;使开发人员能够创建具有吸引力和交互性的应用程…...

玩转贝启科技BQ3588C开源鸿蒙系统开发板 —— 编译构建及此过程中的踩坑填坑(3)

接前一篇文章&#xff1a;玩转贝启科技BQ3588C开源鸿蒙系统开发板 —— 编译构建及此过程中的踩坑填坑&#xff08;2&#xff09; 上一篇文章结束时在等待提示的各依赖包下载安装后的编译结果&#xff0c;但是很遗憾&#xff0c;编译并没有最终完成&#xff0c;既未成功也没有失…...

SQL ORDER BY 关键字

ORDER BY 关键字用于对结果集进行排序。 SQL ORDER BY 关键字 ORDER BY 关键字用于对结果集按照一个列或者多个列进行排序。 ORDER BY 关键字默认按照升序对记录进行排序。如果需要按照降序对记录进行排序&#xff0c;您可以使用 DESC 关键字。 SQL ORDER BY 语法 SELECT …...

多线程-生产者消费者模型

一、基本信息 1、场景介绍&#xff1a;厨师和吃货的例子&#xff0c;吃货吃桌子上的面条&#xff0c;吃完让厨师做&#xff0c;厨师做完面条放桌子上&#xff0c;让吃货吃&#xff0c;厨师如果发现桌子上有面条&#xff0c;就不做&#xff0c;吃货发现桌子上没有面条就不吃。 …...

解压命令之一 gzip

文章目录 解压命令之一 gzip更多信息 解压命令之一 gzip gzip用于对后缀为gz文件进行解压&#xff1a; $ gzip -d data.gz这个命令将解压examplefile.gz&#xff0c;并且在当前目录下生成一个名为data的解压后的文件。 但特别需要留意的是&#xff0c;这个操作会删除源文件&…...

力扣:438. 找到字符串中所有字母异位词 题解

Problem: 438. 找到字符串中所有字母异位词 438. 找到字符串中所有字母异位词 预备知识解题思路复杂度Code其它细节推荐博客或题目博客题目滑动窗口哈希表 预备知识 此题用到了双指针算法中的滑动窗口思想&#xff0c;以及哈希表的运用。c中是unordered_map。如果对此不了解的u…...

QT 高DPI解决方案

一、根据DPI实现动态调整控件大小&#xff08;三种方式&#xff09; 1、QT支持高DPI&#xff08;针对整个进程中所有的UI&#xff09; // main函数中 QApplication::setAttribute(Qt::AA_EnableHighDpiScaling)tips&#xff1a;&#xff08;1&#xff09;如果不想全局设置&am…...

SLB、DMZ、Nginx、Ingress、Gateway、Kibana和Grafana

SLB、DMZ、Nginx、Ingress、Gateway、Kibana和Grafana虽然有一些相似之处&#xff0c;但是它们的功能和适用场景还是有所不同。 SLB主要用于将大流量的请求分配到多个服务器上进行处理&#xff0c;从而提高系统的可伸缩性和可靠性。它适用于需要处理大流量的应用&#xff0c;如…...

【已解决】Invalid bound statement (not found)

报错讯息 org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.casey.mapper.SysRoleMapper.getUserRoleCode at org.apache.ibatis.binding.MapperMethod S q l C o m m a n d . < i n i t > ( M a p p e r M e t h o d . j a v a :…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上&#xff0c;开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识&#xff0c;在 vs 2017 平台上&#xff0c;进行 ASP.NET 应用程序和简易网站的开发&#xff1b;初步熟悉开发一…...

Java 8 Stream API 入门到实践详解

一、告别 for 循环&#xff01; 传统痛点&#xff1a; Java 8 之前&#xff0c;集合操作离不开冗长的 for 循环和匿名类。例如&#xff0c;过滤列表中的偶数&#xff1a; List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

DBAPI如何优雅的获取单条数据

API如何优雅的获取单条数据 案例一 对于查询类API&#xff0c;查询的是单条数据&#xff0c;比如根据主键ID查询用户信息&#xff0c;sql如下&#xff1a; select id, name, age from user where id #{id}API默认返回的数据格式是多条的&#xff0c;如下&#xff1a; {&qu…...

聊一聊接口测试的意义有哪些?

目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开&#xff0c;首…...

Mac下Android Studio扫描根目录卡死问题记录

环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中&#xff0c;提示一个依赖外部头文件的cpp源文件需要同步&#xff0c;点…...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行&#xff01; sudo su - 1. CentOS 系统&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...