记一次 .NET某收银软件 非托管泄露分析
一:背景
1. 讲故事
在我的分析之旅中,遇到过很多程序的故障和杀毒软件扯上了关系,有杀毒软件导致的程序卡死,有杀毒软件导致的程序崩溃,这一篇又出现了一个杀毒软件导致的程序非托管内存泄露,真的是分析多了什么鬼都能撞上。
前几天有位朋友找到过,我他们的程序内存在慢慢的泄露,最后程序会出现崩溃,不知道是什么导致的,让我帮忙看一下怎么回事,简单分析后发现是非托管泄露,让朋友开启了ust并在内存超出预期时抓了一个dump下来,接下来就是分析了。
二:WinDbg 分析
1. 到底是哪里的泄露
相信一直追这个系统的朋友应该知道怎么判断,很简单, 看下 MEM_COMMIT 和 HEAP 指标即可,使用 !address -summary 命令输出如下:
0:000> !address -summary--- Usage Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal
Heap 678 93bd0000 ( 2.308 GB) 65.39% 57.71%
<unknown> 2610 3005d000 ( 768.363 MB) 21.26% 18.76%
Free 515 1e133000 ( 481.199 MB) 11.75%
Image 1526 118f8000 ( 280.969 MB) 7.77% 6.86%
Other 19 804e000 ( 128.305 MB) 3.55% 3.13%
Stack 390 4900000 ( 73.000 MB) 2.02% 1.78%
TEB 73 49000 ( 292.000 kB) 0.01% 0.01%
PEB 1 1000 ( 4.000 kB) 0.00% 0.00%--- State Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal
MEM_COMMIT 4477 c51f9000 ( 3.080 GB) 87.25% 77.00%
MEM_FREE 515 1e133000 ( 481.199 MB) 11.75%
MEM_RESERVE 820 1ccc4000 ( 460.766 MB) 12.75% 11.25%--- Largest Region by Usage ----------- Base Address -------- Region Size ----------
Heap 38be0000 fd0000 ( 15.812 MB)
<unknown> cc6000 7fd9000 ( 127.848 MB)
Free f7590000 88bf000 ( 136.746 MB)
Image 5ab2c000 e41000 ( 14.254 MB)
Other 8cee000 7fb0000 ( 127.688 MB)
Stack 14610000 fd000 (1012.000 kB)
TEB ffe51000 1000 ( 4.000 kB)
PEB fffde000 1000 ( 4.000 kB)
从卦中看,3G的提交内存,Heap 吃了 2.3G,也就表明是 NTHEAP 的泄露,这是一块非托管内存区域,一般都是 C/C++ 语言用 malloc 或者 new 分配的内存,接下来深挖下 NTHEAP 即可,使用 !heap -s 命令。
0:000> !heap -s
SEGMENT HEAP ERROR: failed to initialize the extention
NtGlobalFlag enables following debugging aids for new heaps:stack back traces
LFH Key : 0x7c31b93c
Termination on corruption : DISABLEDHeap Flags Reserv Commit Virt Free List UCR Virt Lock Fast (k) (k) (k) (k) length blocks cont. heap
-----------------------------------------------------------------------------
00200000 08000002 178304 138172 178304 42165 1747 56 0 34 LFHExternal fragmentation 30 % (1747 free blocks)
006c0000 08001002 1088 224 1088 18 8 2 0 0 LFH
00590000 08041002 256 4 256 2 1 1 0 0
006a0000 08001002 3136 1184 3136 153 82 3 0 0 LFHExternal fragmentation 12 % (82 free blocks)
00570000 08001002 1088 224 1088 18 8 2 0 0 LFH
...
15710000 08001002 2185152 2179432 2185152 442 1323 139 0 0 LFH
...
从卦中信息看, 15710000 吃了2.18G,也就表明它是吃内存的主力,这里简单说一下,00200000 是默认的进程堆,除了这个之外都是用非托管代码调用 Win32API 的 HeapCreate 方法创建出来的,接下来就得看下是什么代码创建的。
2. 到底是谁创建的
要想知道是谁创建的,一定要在注册表中开启 ust 选项,大家可以了解下 gflags.exe 工具,参考如下:
PS C:\Users\Administrator\Desktop> gflags /i Example_17_1_7.exe +ust
Current Registry Settings for Example_17_1_7.exe executable are: 00001000ust - Create user mode stack trace database
开启之后 win32api 的 HeapAlloc 方法的内部中会到注册表中看一下是否有 ust 值,如果有就会记录分配的调用栈,这样就知道是谁创建的,抓取dump后可以用windbg的 !gflag 命令看下是否开启成功,参考输出如下:
0:000> !gflag
Current NtGlobalFlag contents: 0x00001000ust - Create user mode stack trace database
接下来对 Heap=15710000 进行一个 block 分组,看下是否有一些有价值的信息。
0:000> !heap -stat -h 15710000heap @ 15710000
group-by: TOTSIZE max-display: 20size #blocks total ( %) (percent of total busy bytes)2cb dea4 - 26dd40c (9.58)2d7 c778 - 23675c8 (8.72)d0 26d64 - 1f8e140 (7.78)7c5 2c50 - 1584990 (5.30)cb 14449 - 10125e3 (3.96)83c 16c2 - bb6578 (2.89)cf9 bc4 - 98a1a4 (2.35)1f51 3da - 789dfa (1.86)...
从卦中数据看没有哪个size占用的特别高,接下来就依次从高往低看,发现都是和 prthook 有关,参考输出如下:
0:000> !heap -flt s 2cb_HEAP @ 15710000HEAP_ENTRY Size Prev Flags UserPtr UserSize - state1571f948 005d 0000 [00] 1571f960 002cb - (busy)15649d70 005d 005d [00] 15649d88 002cb - (busy)...3ec4b900 005d 005d [00] 3ec4b918 002cb - (busy)3ec4bbe8 005d 005d [00] 3ec4bc00 002cb - (busy)3ec4bed0 005d 005d [00] 3ec4bee8 002cb - (busy)3ec4c1b8 005d 005d [00] 3ec4c1d0 002cb - (busy)...0:000> !heap -flt s 2d7HEAP_ENTRY Size Prev Flags UserPtr UserSize - state15665550 005e 0000 [00] 15665568 002d7 - (busy)1566b930 005e 005e [00] 1566b948 002d7 - (busy)1566df98 005e 005e [00] 1566dfb0 002d7 - (busy)1566e288 005e 005e [00] 1566e2a0 002d7 - (busy)...39e3acc8 0061 0061 [00] 39e3ace0 002d7 - (busy)39e3c508 0061 0061 [00] 39e3c520 002d7 - (busy)39e3c810 0061 0061 [00] 39e3c828 002d7 - (busy)39e3cb18 0061 0061 [00] 39e3cb30 002d7 - (busy)39e3ce20 0061 0061 [00] 39e3ce38 002d7 - (busy)0:000> !heap -p -a 3ec4c1b8address 3ec4c1b8 found in_HEAP @ 15710000HEAP_ENTRY Size Prev Flags UserPtr UserSize - state3ec4c1b8 005d 0000 [00] 3ec4c1d0 002cb - (busy)771dd969 ntdll!RtlAllocateHeap+0x00000274153e7439 prthook!MyShowWindow+0x0001d1f9153e543c prthook!MyShowWindow+0x0001b1fc153476ab prthook+0x000276ab0:000> !heap -p -a 39e3ce20address 39e3ce20 found in_HEAP @ 15710000HEAP_ENTRY Size Prev Flags UserPtr UserSize - state39e3ce20 0061 0000 [00] 39e3ce38 002d7 - (busy)771dd969 ntdll!RtlAllocateHeap+0x00000274153e7439 prthook!MyShowWindow+0x0001d1f9153e543c prthook!MyShowWindow+0x0001b1fc153476ab prthook+0x000276ab
3. prthook 到底为何方神圣
从前一节的卦中数据看,貌似 prthook 在不断的弹框,在弹框中用 ntdll!RtlAllocateHeap 分配了非托管内存,那 prthook 到底是个啥呢?可以用 lmvm 看下。
0:000> lmvm prthook
Browse full module list
start end module name
15320000 155dc000 prthook (export symbols) prthook.dllLoaded symbol image file: prthook.dllImage path: C:\Windows\SysWOW64\prthook.dllImage name: prthook.dllBrowse all global symbols functions dataTimestamp: Thu Jun 22 17:16:53 2017 (594B8B05)CheckSum: 001F4972ImageSize: 002BC000File version: 16.17.6.22Product version: 16.17.6.22File flags: 0 (Mask 3F)File OS: 40004 NT Win32File type: 2.0 DllFile date: 00000000.00000000Translations: 0804.04b0Information from resource tables:CompanyName: Beijing VRV Software Co.,LtdProductName: edpInternalName: prthookOriginalFilename: prthook.dll_DBProductVersion: 16, 17, 6, 22FileVersion: 16, 17, 6, 22FileDescription: prthook_DBLegalCopyright: Copyright (C) 2016 Beijing VRV Software Co.,LtdComments: 中英文版
从卦中数据看,prthook.dll 所属公司为 Beijing VRV Software Co.,Ltd,无语的是把这个第三方的dll放在Windows的系统目录 C:\Windows\SysWOW64 下,容易让人觉得有点 鸠占鹊巢,接下来查一下百度,发现是 北信源 的,截图如下:

有了这些信息,告诉朋友让客户把这个安全软件卸载掉就可以了。
三:总结
程序的故障如果不是我们的代码造成的,你想通过排查代码找出问题是不可能的事情,追过这个系列的朋友应该深有体会,常见的外在因素有:
- 杀毒软件
- 电磁辐射
- 显卡问题
相关文章:
记一次 .NET某收银软件 非托管泄露分析
一:背景 1. 讲故事 在我的分析之旅中,遇到过很多程序的故障和杀毒软件扯上了关系,有杀毒软件导致的程序卡死,有杀毒软件导致的程序崩溃,这一篇又出现了一个杀毒软件导致的程序非托管内存泄露,真的是分析多…...
C++力扣题目131--分割回文串
131. 分割回文串 给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。 回文串 是正着读和反着读都一样的字符串。 示例 1: 输入:s "aab" 输出:[["a&qu…...
vue脚手架
● vue是单⻚⾯应⽤程序 ● 什么是路由 ○ 后端路由 ■ 对于普通的⽹站,所有的超链接都是URL地址,所有的URL地址都对应服务器上对应的资源 ○ 前端路由 ■ 对于单⻚⾯应⽤程序来说,主要通过URL中的hash ( # 号) 来实现不同⻚⾯之间的切换…...
Monorepo-uniapp 构建分享
Monorepo uniapp 构建灵感:刚好要做一个项目,于是想到升级一下之前自己写的一个vue3tspiniauno的模版框架,其实那个框架也不错;只是感觉还差点东西,我已经用那个小框架写了两三个项目;轻巧实用。为什么选…...
django后台登录:Forbidden (403) CSRF verification failed. Request aborted.
如果您在尝试登录Django后台时遇到了CSRF验证失败的错误,这通常意味着您的浏览器未能提交正确的CSRF令牌,或者Django后端未能验证该令牌。遵循以下步骤来解决这个问题: 清除浏览器Cookies和缓存: 有时候,浏览器的Cooki…...
【Python数据可视化】matplotlib之绘制常用图形:折线图、柱状图(条形图)、饼图和直方图
文章传送门 Python 数据可视化matplotlib之绘制常用图形:折线图、柱状图(条形图)、饼图和直方图matplotlib之设置坐标:添加坐标轴名字、设置坐标范围、设置主次刻度、坐标轴文字旋转并标出坐标值matplotlib之增加图形内容&#x…...
Python从入门到精通秘籍五
Python速成,每日持续更新,知识点超详细,涵盖所有Python重难点知识及其对应代码,利用碎片化时间,实现Python从入门到精通的飞跃!!! 一、Python的函数基本定义语法 当定义一个函数时,我们使用关键字def,后跟函数名称和一对圆括号。在圆括号内,可以指定任意数量的参数…...
MySQL 基于 GTID 主从复制
GTID 定义 GTID 是 MySQL 事务标识,为每一个提交的事务都生成一个标识,并且是全局唯一的,这个特性是从 MySQL5.6 引进的。 组成 GTID 是由 UUID TID,UUID 是MySQL的唯一标识,每个MySQL实例之间都是不同的。TID是代表…...
Linux操作系统基础
目录 计算机存储结构 冯.诺依曼结构 操作系统 在前几期我们学写了linux中常见的一些指令,本期我们将正式进行linux操作系统的学习。 计算机存储结构 要学习linux操作系统,我们就得先进行计算机存储结构的学习,要进行计算机存储结构的学…...
docker 批量更改镜像标签
docker 批量更改镜像标签 批量更改镜像标签批量删除镜像 批量更改镜像标签 docker images | grep "registry.aliyuncs.com\/google_containers" | sed s/registry.aliyuncs.com\/google_containers/registry.k8s.io/ | awk {print "docker tag "$3" …...
js 校验 大于等于0小于等于100
如果你想要在JavaScript中校验一个数值是否在0到100之间(包括0和100),你可以使用以下的函数: function validateRange(value) {return value > 0 && value < 100; }你可以使用这个函数来检查一个值是否在指定的范围…...
前端面试题-webpack
1.webpack是什么? 模块打包工具,用于将前端资源,如JavaScript、css、图片等打包成可以在浏览器运行的静态资源。可以将多个模块打包成一个或多个bundle。 主要功能: 模块化:可以将多个模块打包成一个或多个bundle&…...
What is `WebMvcConfigurer` does?
WebMvcConfigurer 用于自定义和扩展SpringMVC的功能配置。 比如:可以配置如视图解析器、静态资源处理、消息转换器、拦截器等MVC相关的组件。 实现 WebMvcConfigurer 接口,并使用 Configuration 注解标记,使其成为一个配置类 Configuration …...
安全强化学习笔记
这里写自定义目录标题 参考资料 Safe Reinforcement Learning环境算法CPO 2017 ICMLPCPO 2019 ICLRFOCOPS 2020 NIPSCRPO 2021 ICMLCUP 2022 NIPS TRPO 如何看懂TRPO里所有的数学推导细节? - 小小何先生的回答 - 知乎 参考资料 Safe Reinforcement Learning 安全/约束强化学…...
POI-tl 知识整理:整理1 -> 利用模板向word中写入数据
1 文本传值 Testpublic void testText() throws Exception {XWPFTemplate template XWPFTemplate.compile("D:\\Idea-projects\\POI_word\\templates.docx");Map<String, Object> map new HashMap<>();map.put("title", "Hi, girl"…...
PDF结构详解
文章目录 介绍前言高保真的文件什么是PDF?PDF的一些优点版本摘要谁在使用PDF?有用的免费软件谁应该阅读 构建一个简单PDF文件基本PDF语法File StructureDocument ContentPage Content 构建简单PDF文件头目录,交叉引用表和文件尾主要对象图形内…...
Three.js 镜面反射Reflector 为MeshStandardMaterial增加Reflector能力
效果效果官方案例 区别:官方的案例更像一个镜子 没有纹理等属性 也没有透明度修改 根据源码进行修改为 MeshStandardMaterial实现反射 使用案例 createReflector() {const plane this.helper.create.plane(2, 2);this.helper.add(plane.mesh);plane.mesh.rotat…...
UE4使用技巧
打开蓝图编辑器时不是打开一个新窗口,而是作为主窗口 适用于全部的打开新窗口的操作 蓝图编译时自动保存 开始游戏后立即捕获鼠标...
行为型设计模式—职责链模式
职责链模式:从名字可以拆分为 职责 和 链。即能为请求创建一条由多个处理器组成的链路,每个处理器各自负责自己的职责,相互之间没有耦合,完成自己任务后请求对象即传递到链路的下一个处理器进行处理。 如果在写好的执行函数里加上…...
EndNote快速上手
前言:用EndNote主要就是为了方便管理文章引用的文献,所以本篇就是针对EndNote在文章中引用文献需要的技巧,然后本文用的是EndNoteX9。 EndNote快速上手 创建文献资料库创建文献分组导入文献手动输入文件导入在线搜索 修改文献信息去重文献删除…...
【Java学习笔记】Arrays类
Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...
uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...
NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...
均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
计算机基础知识解析:从应用到架构的全面拆解
目录 前言 1、 计算机的应用领域:无处不在的数字助手 2、 计算机的进化史:从算盘到量子计算 3、计算机的分类:不止 “台式机和笔记本” 4、计算机的组件:硬件与软件的协同 4.1 硬件:五大核心部件 4.2 软件&#…...
从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践
作者:吴岐诗,杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言:融合数据湖与数仓的创新之路 在数字金融时代,数据已成为金融机构的核心竞争力。杭银消费金…...
