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

记一次 .NET某医疗器械清洗系统 卡死分析

一:背景

1. 讲故事

前段时间协助训练营里的一位朋友分析了一个程序卡死的问题,回过头来看这个案例比较经典,这篇稍微整理一下供后来者少踩坑吧。

二:WinDbg 分析

1. 为什么会卡死

因为是窗体程序,理所当然就是看主线程此时正在做什么? 可以用 ~0s ; k 看一下便知。


0:000> k# ChildEBP RetAddr      
00 00aff168 75e3bb0a     win32u!NtUserPeekMessage+0xc
01 00aff168 75e3ba7e     USER32!_PeekMessage+0x2a
02 00aff1a4 6a5d711c     USER32!PeekMessageW+0x16e
03 00aff1f0 6a5841a6     System_Windows_Forms_ni+0x23711c
...
17 00afffbc 00000000     ntdll!_RtlUserThreadStart+0x1b

从线程栈来看,当前的方法卡在 win32u!NtUserPeekMessage 上, 熟悉 Windows 窗体消息的朋友都知道这是提取 消息队列 的常规逻辑,这个方法的下一步就是通过 Wow64SystemServiceCall 进入到 Windows内核态,可以用 u 命令验证一下。


0:000> ub win32u!NtUserPeekMessage+0xc
761d1010 b801100000      mov     eax,1001h
761d1015 ba10631d76      mov     edx,offset win32u!Wow64SystemServiceCall (761d6310)
761d101a ffd2            call    edx

朋友也给我截了图,确实出现了卡死,那接下来的问题就是看下当前线程在 内核态 到底在做什么?

2. 真的卡在内核态吗

幸好朋友可以在卡死的机器上安装 windbg,让朋友在卡死的时候使用 Attch to kernel 的方式观察内核态,截图如下:

附加成功后,可以用 !process 0 f xxxx.exe 看到主线程的线程栈。


lkd> !process 0 f xxxx.exe
PROCESS ffffab8ebea75080SessionId: 1  Cid: 0f78    Peb: 009f1000  ParentCid: 1134...THREAD ffffab8ecad14540  Cid 0f78.38f8  Teb: 00000000009f3000 Win32Thread: ffffab8ecd5dabc0 WAIT: (WrUserRequest) UserMode Non-Alertableffffab8ecb31bcc0  QueueObjectIRP List:ffffab8ecad82b20: (0006,0478) Flags: 00060000  Mdl: 00000000Not impersonatingDeviceMap                 ffffd400aa7eed50Owning Process            ffffab8ebea75080       Image:         xxxx.exeAttached Process          N/A            Image:         N/AWait Start TickCount      1117311        Ticks: 9265 (0:00:02:24.765)Context Switch Count      60628          IdealProcessor: 2  NoStackSwapUserTime                  00:00:10.796KernelTime                00:00:06.593Win32 Start Address 0x00000000006e16aaStack Init ffffa88b5b18fb90 Current ffffa88b5b18e780Base ffffa88b5b190000 Limit ffffa88b5b189000 Call 0000000000000000Priority 10 BasePriority 8 PriorityDecrement 0 IoPriority 2 PagePriority 5Child-SP          RetAddr               Call Siteffffa88b`5b18e7c0 fffff806`6627e370     nt!KiSwapContext+0x76ffffa88b`5b18e900 fffff806`6627d89f     nt!KiSwapThread+0x500ffffa88b`5b18e9b0 fffff806`6627d143     nt!KiCommitThreadWait+0x14fffffa88b`5b18ea50 fffff806`6628679b     nt!KeWaitForSingleObject+0x233ffffa88b`5b18eb40 ffffa9d4`bdd32b12     nt!KeWaitForMultipleObjects+0x45bffffa88b`5b18ec50 ffffa9d4`bdd352d9     win32kfull!xxxRealSleepThread+0x362ffffa88b`5b18ed70 ffffa9d4`bdd33f8a     win32kfull!xxxInterSendMsgEx+0xdd9ffffa88b`5b18eee0 ffffa9d4`bdd37870     win32kfull!xxxSendTransformableMessageTimeout+0x3eaffffa88b`5b18f030 ffffa9d4`bdf1e088     win32kfull!xxxSendMessage+0x2cffffa88b`5b18f090 ffffa9d4`bdf1e0e9     win32kfull!xxxCompositedTraverse+0x40ffffa88b`5b18f0e0 ffffa9d4`bdf1e0e9     win32kfull!xxxCompositedTraverse+0xa1ffffa88b`5b18f130 ffffa9d4`bdf1e0e9     win32kfull!xxxCompositedTraverse+0xa1ffffa88b`5b18f180 ffffa9d4`bdf1e0e9     win32kfull!xxxCompositedTraverse+0xa1ffffa88b`5b18f1d0 ffffa9d4`bdf1e2a7     win32kfull!xxxCompositedTraverse+0xa1ffffa88b`5b18f220 ffffa9d4`bde5a013     win32kfull!xxxCompositedPaint+0x37ffffa88b`5b18f2b0 ffffa9d4`bdd2e438     win32kfull!xxxInternalDoPaint+0x12bce3ffffa88b`5b18f300 ffffa9d4`bdd2e03a     win32kfull!xxxInternalDoPaint+0x108ffffa88b`5b18f350 ffffa9d4`bdd30f1c     win32kfull!xxxDoPaint+0x52ffffa88b`5b18f3b0 ffffa9d4`bdd2ff08     win32kfull!xxxRealInternalGetMessage+0xfacffffa88b`5b18f880 ffffa9d4`be1871ce     win32kfull!NtUserPeekMessage+0x158ffffa88b`5b18f940 fffff806`6640d8f5     win32k!NtUserPeekMessage+0x2affffa88b`5b18f990 00007ffe`1816ff74     nt!KiSystemServiceCopyEnd+0x25 (TrapFrame @ ffffa88b`5b18fa00)00000000`0077e558 00000000`00000000     0x00007ffe`1816ff74

如果线程信息很少的话,可以用 .process 将此进程作为当前上下文,然后加载用户符号,输出如下:


lkd> .process ffffab8ebea75080
Implicit process is now ffffab8e`bea75080
lkd> .reload
Connected to Windows 10 19041 x64 target at (Tue Mar 21 13:21:21.213 2023 (UTC + 8:00)), ptr64 TRUE
Loading Kernel Symbols
...............................................................
................................................................
................................................................
.................
Loading User Symbols
PEB is paged out (Peb.Ldr = 00000000`009f1018).  Type ".hh dbgerr001" for details
Loading unloaded module list

从刚才的线程栈上看,很明显有一个 win32kfull!xxxSendMessage+0x2c 方法,熟悉 SendMessage 的朋友都知道这个是用来向某个窗体发消息的,那到底是哪一个窗体呢?

3. 到底给哪个窗体发消息

要想获取发送窗体的句柄,需要提取 win32kfull!xxxSendMessage 方法的第一个参数,在 x64 的调用协定下,它是用 rcx 传递的,需要分析下汇编代码,如果 rcx 没有放到栈里,那就无法提取了。

为了少点麻烦,建议让朋友看下 32bit 的操作系统上是否也有这个问题?结果反馈说也存在,使用 !thread xxx 切到目标线程,使用 kb 提取第一个参数地址上的值,即:00010598,截图如下:

丢了一个 sdbgext 插件让朋友看下窗体句柄信息,发现是个 64bit 的,其实除了它还可以用 Spy++ 观察窗体句柄,重点就是找到这个神秘窗体 是由哪个进程下的线程创建的,当把句柄号丢进去后还真给找到了,有点黑暗中寻找到了曙光。截图如下:

从 Spy++ 看当前窗体是由进程号:000016E0下的线程号0000109C 创建的,经过比对,这个线程就是本进程的某个线程号。

分析到这里其实就很明朗了,是因为这个线程 0000109C 创建了一个用户控件,导致内核态 在某种情况下给它发消息,接下来就是寻找到底是什么控件创建的。

4. 罪魁祸首

关于非主线程创建用户控件导致的卡死,我感觉都已经说破嘴皮了,还是有非常多的人犯这个毛病,无语哈,解决办法就是用 bp 去拦截 System.Windows.Forms.Application+MarshalingControl..ctor 方法,具体方案可参考我的文章:【一个超经典 WinForm 卡死问题的再反思】

接下来就是朋友的苦苦调试,终于给找到了,截图如下:

 

对,就是这么一句 Intptr handle =this.Handle 代码,内核句柄的获取让它在这个线程上生根了。

三:总结

就是这么一句代码,来来回回兜了好几圈,花费了朋友个把星期,终于给解决了,也算是一个好结果吧,这个案例需要实时观察程序的内核态用户态,看 dump 效果不大,造成了这么多时间的浪费。

相信这个案例也让公司老板对他 刮目相看

  

相关文章:

记一次 .NET某医疗器械清洗系统 卡死分析

一:背景 1. 讲故事 前段时间协助训练营里的一位朋友分析了一个程序卡死的问题,回过头来看这个案例比较经典,这篇稍微整理一下供后来者少踩坑吧。 二:WinDbg 分析 1. 为什么会卡死 因为是窗体程序,理所当然就是看主…...

C# 基于Rijndael对文件进行加解密

介绍: Rijndael 是一种对称加密算法,也是 AES(Advanced Encryption Standard)的前身。它用于数据的加密和解密,并提供了安全且高效的加密功能。 在.NET Framework 中,Rijndael 类是一个实现了 Rijndael 算法…...

Elasticsearchr入门

首先在官网下载elasticsearch8.9版本&#xff0c;以及8.9版本的kibana。 解压&#xff0c;点击es8.9bin目录下的elasticsearch.bat文件启动es 如图所示即为成功。 启动之后打开idea&#xff0c;添加依赖 <dependency><groupId>com.fasterxml.jackson.core</g…...

【ARM】imx6ul移植kernel记录,恩智浦github提供的最新kernel(2023年7月31)

❤️作者主页:凉开水白菜 ❤️作者简介:共同学习,互相监督,热于分享,多加讨论,一起进步! ❤️专栏目录: ❤️专栏资料: ❤️点赞 👍 收藏 ⭐再看,养成习惯 订阅的粉丝可通过PC端文末加我微信,可对文章的内容进行一对一答疑! 文章目录 一、简介二、源码下载三、官方…...

eeglab(自用)

目录 1.加载、显示数据 2.绘制脑电头皮图 3.绘制通道光谱图 4.预处理工具 5.ICA去除伪迹 5. 提取数据epoch 1.加载、显示数据 观察事件值(Event values)&#xff1a;该数据集中包含2400个事件&#xff0c;每个事件指定了EEG.event结构的字段Type(类型)、position(位置)和…...

Dockerfile构建Tomcat镜像(源码)

Dockerfile构建Tomcat镜像 目录 Dockerfile构建Tomcat镜像 1、建立工作目录 2、编写Dockerfile文件 3、构建镜像 4、测试容器 5、浏览器访问测试&#xff1a; 1、建立工作目录 [roothuyang1 ~]# mkdir tomcat[roothuyang1 ~]# cd tomcat/[roothuyang1 tomcat]# lsapach…...

Frida Error: getPackageInfoNoCheck(): has more than one overload的解决方法

使用frida绕过证书的时候执行代码&#xff1a; frida -U -f de.robv.android.xposed.installer --codeshare akabe1/frida-multiple-unpinning --no-pause遇到这样的错误 Error: getPackageInfoNoCheck(): has more than one overload, use .overload() to choose from: 网上查…...

flutter开发实战-RawKeyboardListener监听键盘事件及keycode。

flutter开发实战-RawKeyboardListener监听键盘事件及keycode。 最近开发过程中遇到外设备的按钮点击触发相应的操作&#xff0c;需要监听对应的keycode来开启游戏或者相关操作。 这里用到了RawKeyboardListener 一、RawKeyboardListener是什么&#xff1f; RawKeyboardListe…...

Temu、希音们全托管引争议,跨境电商应变“工贸一体化”

自7月27日Shopee宣布正式上线全托管模式起&#xff0c;全托管似乎突然又进入了爆发期。 在7月31日至8月1日举行的2023第八届深圳国际跨境电商贸易博览会上&#xff0c;全托管成为SHEIN、Wish、Lazada等平台力推的运营模式。进入8月&#xff0c;跨境圈突然涌现大批传言称&#…...

某科技公司提前批测试岗

文章目录 题目 今天给大家带来一家提前批测试岗的真题&#xff0c;目前已经发offer 题目 1.自我介绍 2.登录页面测试用例设计 3.如何模拟多用户登录 可以使用Jmeter,loadRunner性能测试工具来模拟大量用户登录操作去观察一些参数变化 4.有使用过Jmeter,loadRunner做过性能压…...

一次redis缓存不均衡优化经验

背景 高并发接口&#xff0c;引入redis作为缓存之后&#xff0c;运行一段时间发现redis各个节点在高峰时段的访问量严重不均衡&#xff0c;有的节点访问量7000次/s&#xff0c;有的节点访问量500次/s 此种现象虽然暂时不影响系统使用&#xff0c;但是始终是个安全隐患&#x…...

npm发布包

1.npm 登录 在控制台输入命令 npm login 按提示输入用户名&#xff0c;密码&#xff0c;邮箱后登录 如果出现如下提示 需要将淘宝镜像源切换为npm源&#xff0c;删除或注释以下内容就行 2.发布 进入准备发布的代码的根目录下&#xff0c;输入命令 npm publish 3.删除已发…...

Qt5.13引入QtWebApp的模块后报错: error C2440: “reinterpret_cast”: 无法从“int”转换为“quintptr”

1、开发环境 Win10-64 qt5.13 msvc2015-64bit-release 2、报错 新建一个demo工程。 引入QtWebApp的httpserver、logging、templateengine三个模块后。 直接运行&#xff0c;&#xff0c;此时报错如下&#xff1a; E:\Qt5.13.1\install\5.13.1\msvc2015_64\include\QtCore…...

软件为什么要进行性能压力测试?

软件为什么要进行性能压力测试&#xff1f;随着软件应用的不断增多和复杂度的提高&#xff0c;软件的性能对用户体验和业务成功至关重要。性能问题可能导致软件运行缓慢、崩溃或无响应&#xff0c;给用户带来不便甚至损失。为了确保软件能够在高负载和压力下正常运行&#xff0…...

阻塞队列BlockingQueue详解

一、阻塞队列介绍 1、队列 队列入队从队首开始添加&#xff0c;直至队尾&#xff1b;出队从队首出队&#xff0c;直至队尾&#xff0c;所以入队和出队的顺序是一样的 Queue接口 add(E) &#xff1a;在指定队列容量条件下添加元素&#xff0c;若成功返回true&#xff0c;若当前…...

pygame贪吃蛇游戏

pygame贪吃蛇游戏 贪吃蛇游戏通过enter键启动&#xff0c;贪吃蛇通过WSAD进行上下左右移动&#xff0c;每次在游戏区域中随机生成一个食物&#xff0c;每次吃完食物后&#xff0c;蛇变长并且获得积分&#xff1b;按空格键暂停。 贪吃蛇 import random, sys, time, pygame from …...

Mac系统下使用远程桌面连接Windows系统

一、远程桌面工具 Microsoft Remote Desktop 二、下载地址 https://go.microsoft.com/fwlink/?linkid868963 三、下载并安装 四、添加远程PC PC name:云服务器IP。 User account: 添加系统用户 PC name&#xff1a;远程桌面 IP 地址User account&#xff1a;可以选择是…...

使用 OpenCV 和深度学习对黑白图像进行着色

在本文中,我们将创建一个程序将黑白图像(即灰度图像)转换为彩色图像。我们将为此程序使用 Caffe 着色模型。您应该熟悉基本的 OpenCV 功能和用法,例如读取图像或如何使用 dnn 模块加载预训练模型等。现在让我们讨论实现该程序所遵循的过程。 给定一张灰度照片作为输入,本文…...

从价值的角度看,为何 POSE 通证值得长期看好

PoseSwap 是 Nautilus Chain 上的首个 DEX&#xff0c;基于 Nautilus Chain 也让其成为了首个以模块化构建的 Layer3 架构的 DEX。该 DEX 本身能够以 Dapp 层&#xff08;Rollup&#xff09;的形态&#xff0c;与其他应用层并行化运行。...

pytorch的CrossEntropyLoss交叉熵损失函数默认reduction是平均值

pytorch中使用nn.CrossEntropyLoss()创建出来的交叉熵损失函数计算损失默认是求平均值的&#xff0c;即多个样本输入后获取的是一个均值标量&#xff0c;而不是样本大小的向量。 net nn.Linear(4, 2) loss nn.CrossEntropyLoss() X torch.rand(10, 4) y torch.ones(10, dt…...

GitHub Desktop汉化终极指南:3步快速完成中文界面配置

GitHub Desktop汉化终极指南&#xff1a;3步快速完成中文界面配置 【免费下载链接】GitHubDesktop2Chinese GithubDesktop语言本地化(汉化)工具 【GitHub桌面客户端中文汉化】 项目地址: https://gitcode.com/gh_mirrors/gi/GitHubDesktop2Chinese 还在为GitHub Desktop…...

Mac Mouse Fix:如何让你的普通鼠标在macOS上超越苹果触控板

Mac Mouse Fix&#xff1a;如何让你的普通鼠标在macOS上超越苹果触控板 【免费下载链接】mac-mouse-fix Mac Mouse Fix - Make Your $10 Mouse Better Than an Apple Trackpad! 项目地址: https://gitcode.com/GitHub_Trending/ma/mac-mouse-fix 你是否曾经为macOS对第三…...

突破性插件本地化方案:Obsidian-i18n全攻略

突破性插件本地化方案&#xff1a;Obsidian-i18n全攻略 【免费下载链接】obsidian-i18n 项目地址: https://gitcode.com/gh_mirrors/ob/obsidian-i18n 在全球化的今天&#xff0c;Obsidian作为一款强大的知识管理工具&#xff0c;其丰富的插件生态极大地扩展了功能边界…...

C++ 模板参数推导机制剖析

C 模板参数推导机制剖析 C的模板参数推导是泛型编程的核心机制之一&#xff0c;它允许编译器在调用模板函数或类时自动推断类型参数&#xff0c;从而减少冗余代码并提升开发效率。理解这一机制不仅能帮助开发者编写更灵活的代码&#xff0c;还能避免因类型推导错误导致的编译问…...

实战指南:RegRipper3.0 Windows注册表深度取证分析完整方案

实战指南&#xff1a;RegRipper3.0 Windows注册表深度取证分析完整方案 【免费下载链接】RegRipper3.0 RegRipper3.0 项目地址: https://gitcode.com/gh_mirrors/re/RegRipper3.0 RegRipper3.0 是一个专业的 Windows 注册表分析工具&#xff0c;专为数字取证和事件响应设…...

从底层源码深入分析Bean的实例化

在技术领域&#xff0c;我们常常被那些闪耀的、可见的成果所吸引。今天&#xff0c;这个焦点无疑是大语言模型技术。它们的流畅对话、惊人的创造力&#xff0c;让我们得以一窥未来的轮廓。然而&#xff0c;作为在企业一线构建、部署和维护复杂系统的实践者&#xff0c;我们深知…...

新手福音:在快马平台用openclaw启动项目迈出机器人开发第一步

作为一名刚接触机器人开发的新手&#xff0c;第一次听说openclaw启动项目时&#xff0c;我完全不知道从何入手。机械爪控制、PWM信号、硬件通信这些术语听起来就让人头大。好在发现了InsCode(快马)平台&#xff0c;它帮我用最直观的方式理解了整个流程。 项目框架搭建 平台提供…...

百度网盘下载加速终极指南:3分钟学会高速下载技巧

百度网盘下载加速终极指南&#xff1a;3分钟学会高速下载技巧 【免费下载链接】baidu-wangpan-parse 获取百度网盘分享文件的下载地址 项目地址: https://gitcode.com/gh_mirrors/ba/baidu-wangpan-parse 还在为百度网盘的龟速下载而烦恼吗&#xff1f;每次下载大文件都…...

文档格式高效破解:NCMDump实现加密文件自由掌控全指南

文档格式高效破解&#xff1a;NCMDump实现加密文件自由掌控全指南 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 在数字化办公时代&#xff0c;你是否曾因收到的加密文档无法跨平台打开而错失重要信息&#xff1f;是否经历过花费数…...

ComfyUI-Manager下载加速技术全解析:3种方案实现8倍效率提升的低难度指南

ComfyUI-Manager下载加速技术全解析&#xff1a;3种方案实现8倍效率提升的低难度指南 【免费下载链接】ComfyUI-Manager ComfyUI-Manager is an extension designed to enhance the usability of ComfyUI. It offers management functions to install, remove, disable, and en…...