记一次 .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快速上手 创建文献资料库创建文献分组导入文献手动输入文件导入在线搜索 修改文献信息去重文献删除…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...
站群服务器的应用场景都有哪些?
站群服务器主要是为了多个网站的托管和管理所设计的,可以通过集中管理和高效资源的分配,来支持多个独立的网站同时运行,让每一个网站都可以分配到独立的IP地址,避免出现IP关联的风险,用户还可以通过控制面板进行管理功…...

软件工程 期末复习
瀑布模型:计划 螺旋模型:风险低 原型模型: 用户反馈 喷泉模型:代码复用 高内聚 低耦合:模块内部功能紧密 模块之间依赖程度小 高内聚:指的是一个模块内部的功能应该紧密相关。换句话说,一个模块应当只实现单一的功能…...
xmind转换为markdown
文章目录 解锁思维导图新姿势:将XMind转为结构化Markdown 一、认识Xmind结构二、核心转换流程详解1.解压XMind文件(ZIP处理)2.解析JSON数据结构3:递归转换树形结构4:Markdown层级生成逻辑 三、完整代码 解锁思维导图新…...