我试图确定最近保存了哪个 Windows 10 64 位 Shell Bag,但由于我有 5000 个 Bags,因此 powershell 中的“最大包”参数毫无用处,并且注册表中的 BagMRU 键是一棵非常深的树(它标识了几十个“最后的包”)。
我正在使用 HKCU\SOFTWARE\Classes\Local Settings\Software\Microsoft\Windows\Shell\Bags 下的键
是否有一个 powershell 脚本可以识别最后保存的单个包?
答案1
您只能获取密钥最后一次被修改时的时间戳。使用RegQueryInfoKeyA
功能:
[out, optional] lpftLastWriteTime
指向接收上次写入时间的 FILETIME 结构的指针。此参数可以为 NULL。
该函数设置 FILETIME 结构的成员来指示上次修改键或其任何值条目的时间。
Add-Type @'
using Microsoft.Win32.SafeHandles;
using System;
using System.Runtime.InteropServices;
public class API
{
[DllImport("Advapi32.dll", SetLastError=true)]
[return: MarshalAs(UnmanagedType.Error)]
public static extern int RegQueryInfoKeyA(
SafeRegistryHandle hkey,
uint p2,uint p3,uint p4,uint p5,uint p6,
uint p7,uint p8,uint p9,uint p10,uint p11,
ref long lpftLastWriteTime
);
}
'@
$KeyPath = 'HKCU:\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\Bags'
Get-ChildItem $KeyPath | ForEach-Object -Process{
[long]$lwt = 0
[API]::RegQueryInfoKeyA(
$_.Handle,0,0,0,0,0,0,0,0,0,0,[ref]$lwt
) | out-null
[PSCustomObject]@{
'KeyName' = $_.PSChildName
'LastMod' = [DateTime]::FromFileTime($lwt)
}
} | sort LastMod -Descending
输出:
KeyName LastMod
------- -------
295 3/8/2023 03:19:13 AM
294 3/8/2023 03:16:28 AM
293 3/8/2023 03:16:18 AM
292 3/8/2023 03:15:25 AM
291 3/8/2023 03:14:28 AM
166 3/8/2023 03:14:23 AM
290 3/6/2023 02:47:23 AM
289 3/6/2023 02:29:46 AM
288 3/6/2023 02:29:03 AM
...
答案2
这不是一个直接的答案,但确实是一个答案。
有一位名叫 Eric Zimmerman 的出色程序员,他制作了两种类似的工具。
ShellBags Explorer 和 SbeCmd(此工具的命令行版本)。
SbeCmd 应该能够导出您正在寻找的数据,您可以将其读入 powershell。
他的代码是用 .net 编写的,因此如果您弄清楚他正在做的“魔术”,Powershell 将能够访问相同的功能。我自己建议联系他以找出秘密,因为他看起来是个很酷的人。
你可以找到他的工具这里如果你联系他,他可能会直接给你这个问题的答案(通过代码)而不是我的解决方案(通过使用他的工具)。
答案3
好吧,使用 ProcMon 我有一个强力答案。 以下是程序:
- 启动 Procmon
- 关闭事件捕获
- 清除屏幕
- 设置一个过滤器以仅查看来自 Explorer 的事件,并添加路径包含“bags”的过滤器
- 开启事件捕获
- 关闭浏览器窗口以保存您想要的包
- 关闭偶数捕获
- 查看结果列表,找到您正在寻找的包类型(钥匙)
- 注意该密钥的父编号
当然,这只是一次性的。为了更常规/自动地找到最后一个包,必须编写某种脚本。