ListDLLs & Handle 学习笔记(8.11):谁注入了 DLL?谁占着文件不放?一篇教你全搞定

ListDLLs & Handle 学习笔记(8.11):谁注入了 DLL?谁占着文件不放?一篇教你全搞定

  • [ListDLLs & Handle 学习笔记(8.11):谁注入了 DLL?谁占着文件不放?一篇教你全搞定](#ListDLLs & Handle 学习笔记(8.11):谁注入了 DLL?谁占着文件不放?一篇教你全搞定)
    • [1. DLL、句柄,这俩为什么这么关键?](#1. DLL、句柄,这俩为什么这么关键?)
    • [2. ListDLLs:快速枚举进程加载的 DLL](#2. ListDLLs:快速枚举进程加载的 DLL)
    • [3. Handle:谁在锁文件?谁阻止你删/弹/改?](#3. Handle:谁在锁文件?谁阻止你删/弹/改?)
      • 它主要做三件大事:
      • [3.1 基本体检式用法:直接列句柄](#3.1 基本体检式用法:直接列句柄)
      • [3.2 经典诊断:哪个进程锁住了某个文件?](#3.2 经典诊断:哪个进程锁住了某个文件?)
      • [3.3 暴力解决方案:关闭句柄](#3.3 暴力解决方案:关闭句柄)
    • [4. ListDLLs vs Handle:什么时候用谁?](#4. ListDLLs vs Handle:什么时候用谁?)
    • [5. 典型实战剧本(你可以直接照抄)](#5. 典型实战剧本(你可以直接照抄))
      • [剧本 A:客户机器总弹广告。怀疑浏览器被注入插件](#剧本 A:客户机器总弹广告。怀疑浏览器被注入插件)
      • [剧本 B:Windows 服务器上某个 .log 无法轮转,影响磁盘,业务喊救命](#剧本 B:Windows 服务器上某个 .log 无法轮转,影响磁盘,业务喊救命)
      • [剧本 C:怀疑内核级 Rootkit 或奇怪驱动](#剧本 C:怀疑内核级 Rootkit 或奇怪驱动)
    • [6. 风险 & 注意事项](#6. 风险 & 注意事项)
    • [7. 总结](#7. 总结)

ListDLLs & Handle 学习笔记(8.11):谁注入了 DLL?谁占着文件不放?一篇教你全搞定

适用读者:

  • 运维 / 桌面支持:客户说"删不掉,说文件正被占用",你总不能一直说"重启一下"。
  • 安全 / 取证:怀疑有恶意 DLL 注入、内存驻留模块、幽灵驱动在搞事情。
  • 开发 / 测试:想确认目标进程到底加载了哪些模块、有没有把测试版 DLL 误带进生产。
  • 游戏 / 反外挂 / 反Hook:想知道谁把奇怪的 DLL 注入到我们进程里。

这一篇我们把 Sysinternals 里两个常用但经常被忽略的狠角色拉上台:

  • ListDLLs:列出进程加载的 DLL、模块路径、内存基址等
  • Handle :枚举系统中所有打开的句柄(文件句柄、注册表句柄、同步对象、Section 对象等),并支持按目标名搜索,甚至强制关闭句柄

说人话:

  • ListDLLs → "这个进程吃了哪些动态库?"
  • Handle → "是谁卡着这个资源不放?"

1. DLL、句柄,这俩为什么这么关键?

DLL:模块注入的真相

任何一个用户态进程都不是"它自己一个 EXE 在跑"------它通常还会加载几十上百个 DLL:系统库(如 kernel32.dll)、第三方库(如显卡驱动注入的 overlay)、安全/杀软的 hook DLL、甚至是恶意软件植入的假冒模块。

很多行为劫持、键盘记录、API hook 都是通过"把我这段 DLL 注入到你的进程里"来完成的。

如果你能看到"谁被塞了什么 DLL",你就能定位一大批可疑行为。

这正是 ListDLLs 做的第一件事。


句柄:资源被占用的真相

Windows 里一切资源几乎都"包成了句柄"(Handle):

  • 一个打开的文件 = 一个句柄
  • 正在占用的 COM 端口 = 一个句柄
  • 某个仍在持有的服务管道、注册表键、同步互斥体,全是句柄

当你遇到这些经典抱怨:

  • "这个 .log 删不了,说正在被占用"
  • "这个 U 盘弹不出去"
  • "这个驱动程序卸载不了,说目标正在使用中"

问题往往是:哪个进程还在握着这个资源对应的句柄?

Handle 工具就能告诉你------并且还能(在你足够清楚后果时)强制掰开它的手指。


2. ListDLLs:快速枚举进程加载的 DLL

基本能力

  • 列出指定进程(或系统中所有进程)所加载的 DLL / 映射模块
  • 显示模块的内存基址、大小、路径
  • 支持过滤某个特定 DLL,看它被注入到了哪些进程里

这种信息能直接用于:

  • 查内存劫持("怎么我的浏览器里有个奇怪的 overlayhook.dll?")
  • 双开/外挂检测
  • 兼容性排查("客户机器上到底加载的是我们发布的 release.dll 还是他们自己魔改的测试 DLL?")

常见用法示例

1)列出某个进程加载的 DLL
cmd 复制代码
listdlls notepad.exe

含义:枚举 notepad.exe 进程中所有已加载模块。

也可以用 PID(更精确):

cmd 复制代码
listdlls -p 4321

输出里通常会包含:

  • 模块名
  • 基址 (Base)
  • 大小 (Size)
  • 模块完整路径(非常关键,用来判断是否被劫持到奇怪目录)
2)查某个 DLL 被谁加载了
cmd 复制代码
listdlls yourhook.dll

含义:告诉你"哪些进程加载了名为 yourhook.dll 的模块"。

这个用法在安全分析场景非常炸裂,比如你怀疑有键鼠劫持 DLL、广告注入 DLL、甚至外挂模块 ------ 直接反查所有进程谁吃了它。

3)导出信息用于比对

运维/排障时可以把输出重定向到文件留档:

cmd 复制代码
listdlls chrome.exe > chrome_modules.txt

之后可和"健康机器"的对比结果做 diff,就能肉眼看出异常模块。


3. Handle:谁在锁文件?谁阻止你删/弹/改?

Handle 是 Sysinternals 里最常实用主义的武器之一。

它主要做三件大事:

  1. 枚举全系统的句柄

    • 哪个进程持有哪些句柄(文件句柄、注册表句柄、Section、Mutant、Pipe...)
  2. 按关键字搜索

    • "给我查所有句柄里包含 report.xlsx 的那一个,告诉我是哪个进程占着"
    • 典型用于"删不掉/改不了/弹不出"的排障
  3. 可选地关闭句柄

    • 是的,暴力手段
    • 这就像用手把某进程从文件上掰开
    • 但注意:可能导致进程崩溃、数据损坏,必须谨慎

3.1 基本体检式用法:直接列句柄

cmd 复制代码
handle

不带参数直接执行 = 列出全系统句柄(会很多)。

输出字段通常包含:

  • PID
  • 进程名
  • 句柄值
  • 句柄类型(File、Key、Mutant、Section...)
  • 目标路径(如文件全路径、注册表键路径等)

这个列表平时太大,所以我们几乎总是结合搜索。


3.2 经典诊断:哪个进程锁住了某个文件?

比如你删不掉 D:\logs\app.log,系统说"正在被使用"。

直接搜:

cmd 复制代码
handle app.log

or 更精确:

cmd 复制代码
handle "D:\logs\app.log"

输出大概会长这样(示例结构):

text 复制代码
notepad.exe       pid: 4820   38C: File  (RW-)   D:\logs\app.log

翻译一下:

  • 进程名 notepad.exe(PID 4820)还在占用 app.log
  • 句柄号是 38C

所以你就知道:是谁锁了它。这比"重启电脑再试"高到不知道哪里去了。

同理,这个技巧可以用在:

  • 网络驱动器无法弹出
  • U 盘"此设备正在使用中"
  • 注册表项无法删除(是哪个安全代理还占着)
  • 某软件说"请关闭所有 Office 应用后继续安装",但你根本没开 Word

3.3 暴力解决方案:关闭句柄

警告先说前面:
强行关别人的句柄可能会让那个进程直接炸死,甚至蓝屏(尤其是系统/驱动关键句柄)。

只有在你确认目标进程可以被终止、或数据不再重要的情况下用它。

步骤是两步式:

第一步,定位句柄(获取 PID 和句柄值):

cmd 复制代码
handle "D:\logs\app.log"

假设输出告诉你:

notepad.exe PID 4820,句柄号 38C

第二步,执行关闭(需要管理员):

cmd 复制代码
handle -p 4820 -c 38C
  • -p 指定目标进程的 PID
  • -c 指定要关闭的句柄值

Handle 会询问你是否确认关闭,除非你还加了 /y 等自动确认参数(不同版本语法有细微差别,核心思想一致:指定 PID + 句柄值 → 关闭)。

什么时候会这么用?

  • 发布/升级脚本里批量替换日志文件、DLL 文件,而老版本进程没正常释放资源
  • 应急情况下被锁的驱动/日志/临时文件必须立刻释放
  • 清理"幽灵占用"的共享文件句柄以解锁共享目录

再强调一遍:
关闭句柄 = 手术刀,不是日常保养。


4. ListDLLs vs Handle:什么时候用谁?

可以把这俩工具想成"进程做了什么"的两个观察角度。

需求场景 用哪个
我想知道这个进程里都加载了哪些 DLL? ListDLLs
我怀疑某个进程内被注入了恶意 DLL / hook DLL ListDLLs
我想知道是谁还在持有这个文件 / 注册表键 / 命名管道 Handle
我想直接把这个资源从进程手里抢回来 Handle (带 -c)
我怀疑是某个第三方插件导致崩溃 先用 ListDLLs 确认是否加载了这类插件,再结合 Dump/Procmon 等分析
我遇到"文件无法删除"/"设备正被使用" Handle

实际排障时,这两个工具经常和 ProcmonLiveKd 联动使用:

  • Procmon:看"行为历史"(谁什么时候访问了什么)
  • Handle:看"现在谁在占用它"
  • LiveKd:看"内核底层现场是怎样的"
  • ListDLLs:看"进程里到底混进了哪些模块"

这是完整的三维视角:时间线(Procmon)、现场占用(Handle)、进程注入面(ListDLLs)、内核现场(LiveKd)。


5. 典型实战剧本(你可以直接照抄)

剧本 A:客户机器总弹广告。怀疑浏览器被注入插件

  1. 远程上机 / 要求客户运行:

    cmd 复制代码
    listdlls chrome.exe > chrome_dlls.txt
  2. 你对比正常环境的 chrome_dlls.txt

    • 如果看到陌生的 DLL,尤其是来自奇怪路径(比如用户临时目录、AppData 里形如随机字符串的路径),基本可以锁定它。
  3. 后续就可以结合 taskkill、启动项排查、注册表 Run 项排查,甚至配合安全团队封堵。


剧本 B:Windows 服务器上某个 .log 无法轮转,影响磁盘,业务喊救命

  1. 在服务器上执行:

    cmd 复制代码
    handle "D:\prod\app\run.log"
  2. 得到结果例如:

    text 复制代码
    java.exe  pid: 9124   2A0: File  D:\prod\app\run.log
  3. 如果你准备重启这个 Java 服务,先优雅 stop;

    如果 stop 不掉、但磁盘要爆了,可以:

    cmd 复制代码
    handle -p 9124 -c 2A0

    然后立刻做日志切分和清理(⚠ 之后建议重启对应服务,恢复干净状态)


剧本 C:怀疑内核级 Rootkit 或奇怪驱动

  1. 先用 LiveKd 抓一个 dump / 或直接开交互调试(我们在上一篇详讲)
  2. 再用 ListDLLs / Handle 确认高权限进程里加载了哪些模块、还占了哪些对象
  3. 三者信息交叉起来,可以定位可疑驱动 or 用户态 Loader

6. 风险 & 注意事项

  • Handle 关闭句柄 = 破坏性手段

    你是在强制把资源从进程嘴里扣出来。生产上请先走停服务/回收进程,只有在"已经坏了""必须释放资源"时用它兜底。

  • ListDLLs 看到的模块路径非常敏感

    这些路径能暴露三方插件、内网私有模块、甚至商业反作弊/反篡改组件。别随手把输出贴到公网工单或论坛。

  • 管理员权限很关键

    要想枚举别的进程的 DLL 或句柄,往往需要管理员(或者 SYSTEM)级访问权限。标准用户看到的信息是有限的。

  • 杀软可能拦截

    某些安全产品会把 Handle / ListDLLs 归类为"高权限诊断工具",可能会弹框或阻止。企业环境要和安全团队打个招呼。


7. 总结

这篇的重点可以压成四句话背走👇

  1. ListDLLs 解决"进程里现在都注入/加载了哪些 DLL 模块?"

    • 定位异常插件、外挂、Hook、兼容性污染。
  2. Handle 解决"谁锁着这个资源不让我动?"

    • 快速找出无法删除/无法弹出/无法卸载的罪魁进程。
  3. Handle 还能 ------ 在你充分理解风险后 ------ 强制关闭那个句柄,等于手动解锁资源。

  4. 它们和 Procmon、LiveKd、DebugView 形成了生产排障的"武器库四件套":

    • Procmon 看行为历史
    • DebugView 听调试输出
    • LiveKd 看内核现场
    • ListDLLs / Handle 看模块注入 & 句柄占用

下一步我们会把这些工具和前面章节的 VMMap / DebugView / LiveKd 串起来,给出一套"现场 → 采证 → 复盘"的应急响应流程模板,让你在碰到线上的 CPU 飙高、资源锁死、劫持注入、疑似木马、服务卡死事件时,能跑一套标准动作,而不是手忙脚乱地猜。

相关推荐
阿标的博客2 小时前
Electron学习(三):进程间通信
学习·electron
风车带走过往2 小时前
Windows10 使用 dynv6 + ddns-go 实现 IPv6 固定域名远程访问指南
网络
蒙奇D索大2 小时前
【算法】回溯算法精讲:从深度优先搜索到剪枝优化
经验分享·笔记·算法·深度优先·剪枝·改行学it
爱奥尼欧3 小时前
【Linux笔记】网络部分——NAT-代理-网络穿透
linux·网络·笔记
njxiejing3 小时前
基于Packet Tracer的路由器的基本配置(地址、密码,远程登录)
网络·智能路由器
一个平凡而乐于分享的小比特3 小时前
UCOS-III笔记(七)
笔记·ucosiii
HalvmånEver3 小时前
Linux:基础开发工具(三)
linux·运维·服务器·开发语言·学习·gcc/g++
阿巴~阿巴~3 小时前
UDP服务端绑定INADDR_ANY后,客户端该用什么IP访问?
服务器·网络·udp协议·网络测试·udp套接字编程·inaddr_any
MARIN_shen4 小时前
PCB之电源完整性之电源网络的PDN仿真CST---08
网络·单片机·硬件工程·pcb工艺