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

记一次 .NET某收银软件 非托管泄露分析

一:背景

1. 讲故事

在我的分析之旅中,遇到过很多程序的故障和杀毒软件扯上了关系,有杀毒软件导致的程序卡死,有杀毒软件导致的程序崩溃,这一篇又出现了一个杀毒软件导致的程序非托管内存泄露,真的是分析多了什么鬼都能撞上。

前几天有位朋友找到过,我他们的程序内存在慢慢的泄露,最后程序会出现崩溃,不知道是什么导致的,让我帮忙看一下怎么回事,简单分析后发现是非托管泄露,让朋友开启了ust并在内存超出预期时抓了一个dump下来,接下来就是分析了。

二:WinDbg 分析

1. 到底是哪里的泄露

相信一直追这个系统的朋友应该知道怎么判断,很简单, 看下 MEM_COMMITHEAP 指标即可,使用 !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某收银软件 非托管泄露分析

一&#xff1a;背景 1. 讲故事 在我的分析之旅中&#xff0c;遇到过很多程序的故障和杀毒软件扯上了关系&#xff0c;有杀毒软件导致的程序卡死&#xff0c;有杀毒软件导致的程序崩溃&#xff0c;这一篇又出现了一个杀毒软件导致的程序非托管内存泄露&#xff0c;真的是分析多…...

C++力扣题目131--分割回文串

131. 分割回文串 给你一个字符串 s&#xff0c;请你将 s 分割成一些子串&#xff0c;使每个子串都是 回文串 。返回 s 所有可能的分割方案。 回文串 是正着读和反着读都一样的字符串。 示例 1&#xff1a; 输入&#xff1a;s "aab" 输出&#xff1a;[["a&qu…...

vue脚手架

● vue是单⻚⾯应⽤程序 ● 什么是路由 ○ 后端路由 ■ 对于普通的⽹站&#xff0c;所有的超链接都是URL地址&#xff0c;所有的URL地址都对应服务器上对应的资源 ○ 前端路由 ■ 对于单⻚⾯应⽤程序来说&#xff0c;主要通过URL中的hash ( # 号) 来实现不同⻚⾯之间的切换…...

Monorepo-uniapp 构建分享

Monorepo uniapp 构建灵感&#xff1a;刚好要做一个项目&#xff0c;于是想到升级一下之前自己写的一个vue3tspiniauno的模版框架&#xff0c;其实那个框架也不错&#xff1b;只是感觉还差点东西&#xff0c;我已经用那个小框架写了两三个项目&#xff1b;轻巧实用。为什么选…...

django后台登录:Forbidden (403) CSRF verification failed. Request aborted.

如果您在尝试登录Django后台时遇到了CSRF验证失败的错误&#xff0c;这通常意味着您的浏览器未能提交正确的CSRF令牌&#xff0c;或者Django后端未能验证该令牌。遵循以下步骤来解决这个问题&#xff1a; 清除浏览器Cookies和缓存&#xff1a; 有时候&#xff0c;浏览器的Cooki…...

【Python数据可视化】matplotlib之绘制常用图形:折线图、柱状图(条形图)、饼图和直方图

文章传送门 Python 数据可视化matplotlib之绘制常用图形&#xff1a;折线图、柱状图&#xff08;条形图&#xff09;、饼图和直方图matplotlib之设置坐标&#xff1a;添加坐标轴名字、设置坐标范围、设置主次刻度、坐标轴文字旋转并标出坐标值matplotlib之增加图形内容&#x…...

Python从入门到精通秘籍五

Python速成,每日持续更新,知识点超详细,涵盖所有Python重难点知识及其对应代码,利用碎片化时间,实现Python从入门到精通的飞跃!!! 一、Python的函数基本定义语法 当定义一个函数时,我们使用关键字def,后跟函数名称和一对圆括号。在圆括号内,可以指定任意数量的参数…...

MySQL 基于 GTID 主从复制

GTID 定义 GTID 是 MySQL 事务标识&#xff0c;为每一个提交的事务都生成一个标识&#xff0c;并且是全局唯一的&#xff0c;这个特性是从 MySQL5.6 引进的。 组成 GTID 是由 UUID TID&#xff0c;UUID 是MySQL的唯一标识&#xff0c;每个MySQL实例之间都是不同的。TID是代表…...

Linux操作系统基础

目录 计算机存储结构 冯.诺依曼结构 操作系统 在前几期我们学写了linux中常见的一些指令&#xff0c;本期我们将正式进行linux操作系统的学习。 计算机存储结构 要学习linux操作系统&#xff0c;我们就得先进行计算机存储结构的学习&#xff0c;要进行计算机存储结构的学…...

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之间&#xff08;包括0和100&#xff09;&#xff0c;你可以使用以下的函数&#xff1a; function validateRange(value) {return value > 0 && value < 100; }你可以使用这个函数来检查一个值是否在指定的范围…...

前端面试题-webpack

1.webpack是什么&#xff1f; 模块打包工具&#xff0c;用于将前端资源&#xff0c;如JavaScript、css、图片等打包成可以在浏览器运行的静态资源。可以将多个模块打包成一个或多个bundle。 主要功能&#xff1a; 模块化&#xff1a;可以将多个模块打包成一个或多个bundle&…...

What is `WebMvcConfigurer` does?

WebMvcConfigurer 用于自定义和扩展SpringMVC的功能配置。 比如&#xff1a;可以配置如视图解析器、静态资源处理、消息转换器、拦截器等MVC相关的组件。 实现 WebMvcConfigurer 接口&#xff0c;并使用 Configuration 注解标记&#xff0c;使其成为一个配置类 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&#xff1f;PDF的一些优点版本摘要谁在使用PDF&#xff1f;有用的免费软件谁应该阅读 构建一个简单PDF文件基本PDF语法File StructureDocument ContentPage Content 构建简单PDF文件头目录&#xff0c;交叉引用表和文件尾主要对象图形内…...

Three.js 镜面反射Reflector 为MeshStandardMaterial增加Reflector能力

效果效果官方案例 区别&#xff1a;官方的案例更像一个镜子 没有纹理等属性 也没有透明度修改 根据源码进行修改为 MeshStandardMaterial实现反射 使用案例 createReflector() {const plane this.helper.create.plane(2, 2);this.helper.add(plane.mesh);plane.mesh.rotat…...

UE4使用技巧

打开蓝图编辑器时不是打开一个新窗口&#xff0c;而是作为主窗口 适用于全部的打开新窗口的操作 蓝图编译时自动保存 开始游戏后立即捕获鼠标...

行为型设计模式—职责链模式

职责链模式&#xff1a;从名字可以拆分为 职责 和 链。即能为请求创建一条由多个处理器组成的链路&#xff0c;每个处理器各自负责自己的职责&#xff0c;相互之间没有耦合&#xff0c;完成自己任务后请求对象即传递到链路的下一个处理器进行处理。 如果在写好的执行函数里加上…...

EndNote快速上手

前言&#xff1a;用EndNote主要就是为了方便管理文章引用的文献&#xff0c;所以本篇就是针对EndNote在文章中引用文献需要的技巧&#xff0c;然后本文用的是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

智慧工地管理云平台系统&#xff0c;智慧工地全套源码&#xff0c;java版智慧工地源码&#xff0c;支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求&#xff0c;提供“平台网络终端”的整体解决方案&#xff0c;提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

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

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

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

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》

在注意力分散、内容高度同质化的时代&#xff0c;情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现&#xff0c;消费者对内容的“有感”程度&#xff0c;正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中&#xff0…...

是否存在路径(FIFOBB算法)

题目描述 一个具有 n 个顶点e条边的无向图&#xff0c;该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序&#xff0c;确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数&#xff0c;分别表示n 和 e 的值&#xff08;1…...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;使用DevEco Studio作为开发工具&#xff0c;采用Java语言实现&#xff0c;包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

站群服务器的应用场景都有哪些?

站群服务器主要是为了多个网站的托管和管理所设计的&#xff0c;可以通过集中管理和高效资源的分配&#xff0c;来支持多个独立的网站同时运行&#xff0c;让每一个网站都可以分配到独立的IP地址&#xff0c;避免出现IP关联的风险&#xff0c;用户还可以通过控制面板进行管理功…...

软件工程 期末复习

瀑布模型&#xff1a;计划 螺旋模型&#xff1a;风险低 原型模型: 用户反馈 喷泉模型:代码复用 高内聚 低耦合&#xff1a;模块内部功能紧密 模块之间依赖程度小 高内聚&#xff1a;指的是一个模块内部的功能应该紧密相关。换句话说&#xff0c;一个模块应当只实现单一的功能…...

xmind转换为markdown

文章目录 解锁思维导图新姿势&#xff1a;将XMind转为结构化Markdown 一、认识Xmind结构二、核心转换流程详解1.解压XMind文件&#xff08;ZIP处理&#xff09;2.解析JSON数据结构3&#xff1a;递归转换树形结构4&#xff1a;Markdown层级生成逻辑 三、完整代码 解锁思维导图新…...