gpt4 book ai didi

c# - 如何获取之前连接的 USB 设备的时间戳?

转载 作者:可可西里 更新时间:2023-11-01 09:32:38 24 4
gpt4 key购买 nike

我正在尝试获取一个旧的 PowerShell 脚本来显示以前连接的 USB 设备的时间。在阅读了一些取证之后blogs喜欢this , 我找到了 this script来自 this blog . (杰森·沃克的剧本。)

遗憾的是,它不显示任何时间戳 或有关设备的任何其他有用的详细信息。所以我希望 there should be a way to get that too .只有我看不出如何合并它。

Function Get-USBHistory { 
[CmdletBinding()]
Param
(
[parameter(ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)]
[alias("CN","Computer")]
[String[]]$ComputerName=$Env:COMPUTERNAME,
[Switch]$Ping
)

Begin {
$TempErrorAction = $ErrorActionPreference
$ErrorActionPreference = "Stop"
$Hive = "LocalMachine"
$Key = "SYSTEM\CurrentControlSet\Enum\USBSTOR"
}

Process
{
$USBDevices = @()
$ComputerCounter = 0

ForEach($Computer in $ComputerName)
{
$USBSTORSubKeys1 = @()
$ChildSubkeys = @()
$ChildSubkeys1 = @()

$ComputerCounter++
$Computer = $Computer.Trim().ToUpper()
Write-Progress -Activity "Collecting USB history" -Status "Retrieving USB history from $Computer" -PercentComplete (($ComputerCounter/($ComputerName.Count)*100))


If($Ping)
{
If(-not (Test-Connection -ComputerName $Computer -Count 1 -Quiet))
{
Write-Warning "Ping failed on $Computer"
Continue
}
}#end if ping

Try
{
$Reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($Hive,$Computer)
$USBSTORKey = $Reg.OpenSubKey($Key)
$USBSTORSubKeys1 = $USBSTORKey.GetSubKeyNames()
}#end try
Catch
{
Write-Warning "There was an error connecting to the registry on $Computer or USBSTOR key not found. Ensure the remote registry service is running on the remote machine."
}#end catch

ForEach($SubKey1 in $USBSTORSubKeys1)
{
$ErrorActionPreference = "Continue"
$Key2 = "SYSTEM\CurrentControlSet\Enum\USBSTOR\$SubKey1"
$RegSubKey2 = $Reg.OpenSubKey($Key2)
$SubkeyName2 = $RegSubKey2.GetSubKeyNames()

$ChildSubkeys += "$Key2\$SubKeyName2"
$RegSubKey2.Close()
}#end foreach SubKey1

ForEach($Child in $ChildSubkeys)
{

If($Child -match " ")
{
$BabySubkey = $null
$ChildSubkey1 = ($Child.split(" "))[0]

$SplitChildSubkey1 = $ChildSubkey1.split("\")

0..4 | Foreach{ [String]$BabySubkey += ($SplitChildSubkey1[$_]) + "\"}

$ChildSubkeys1 += $BabySubkey + ($Child.split(" ")[-1])
$ChildSubkeys1 += $ChildSubkey1

}
Else
{
$ChildSubkeys1 += $Child
}
$ChildSubKeys1.count
}#end foreach ChildSubkeys

ForEach($ChildSubkey1 in $ChildSubkeys1)
{
$USBKey = $Reg.OpenSubKey($ChildSubkey1)
$USBDevice = $USBKey.GetValue('FriendlyName')
If($USBDevice)
{
$USBDevices += New-Object -TypeName PSObject -Property @{
USBDevice = $USBDevice
Computer = $Computer
Serial = $ChildSubkey1.Split("\")[-1]
}
}
$USBKey.Close()
}#end foreach ChildSubKey2

$USBSTORKey.Close()
#Display results
$USBDevices | Select Computer,USBDevice,Serial
}#end foreach computer

}#end process

End
{
#Set error action preference back to original setting
$ErrorActionPreference = $TempErrorAction
}

}#end function

C# 代码:

using System;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using Microsoft.Win32.SafeHandles;
class Program
{
static void Main(string[] args)
{
string usbStor = @"SYSTEM\ControlSet001\Enum\USBSTOR";
using (var keyUsbStor = Registry.LocalMachine.OpenSubKey(usbStor))
{
var usbDevices = from className in keyUsbStor.GetSubKeyNames()
let keyUsbClass = keyUsbStor.OpenSubKey(className)
from instanceName in keyUsbClass.GetSubKeyNames()
let keyUsbInstance = new RegistryKeyEx(keyUsbClass.OpenSubKey(instanceName))
select new
{
UsbName = keyUsbInstance.Key.GetValue("FriendlyName"),
ConnectTime = keyUsbInstance.LastWriteTime
};
foreach (var usbDevice in usbDevices.OrderBy(x => x.ConnectTime))
{
Console.WriteLine("({0}) -- '{1}'", usbDevice.ConnectTime, usbDevice.UsbName);
}
}
}
}
/// <summary>
/// Wraps a RegistryKey object and corresponding last write time.
/// </summary>
/// <remarks>
/// .NET doesn't expose the last write time for a registry key
/// in the RegistryKey class, so P/Invoke is required.
/// </remarks>
public class RegistryKeyEx
{
#region P/Invoke Declarations
// This declaration is intended to be used for the last write time only. int is used
// instead of more convenient types so that dummy values of 0 reduce verbosity.
[DllImport("advapi32.dll", EntryPoint = "RegQueryInfoKey", CallingConvention = CallingConvention.Winapi, SetLastError = true)]
extern private static int RegQueryInfoKey(
SafeRegistryHandle hkey,
int lpClass,
int lpcbClass,
int lpReserved,
int lpcSubKeys,
int lpcbMaxSubKeyLen,
int lpcbMaxClassLen,
int lpcValues,
int lpcbMaxValueNameLen,
int lpcbMaxValueLen,
int lpcbSecurityDescriptor,
IntPtr lpftLastWriteTime);
#endregion
#region Public Poperties
/// <summary>
/// Gets the registry key owned by the info object.
/// </summary>
public RegistryKey Key { get; private set; }
/// <summary>
/// Gets the last write time for the corresponding registry key.
/// </summary>
public DateTime LastWriteTime { get; private set; }
#endregion
/// <summary>
/// Creates and initializes a new RegistryKeyInfo object from the provided RegistryKey object.
/// </summary>
/// <param name="key">RegistryKey component providing a handle to the key.</param>
public RegistryKeyEx(RegistryKey key)
{
Key = key;
SetLastWriteTime();
}
/// <summary>
/// Creates and initializes a new RegistryKeyInfo object from a registry key path string.
/// </summary>
/// <param name="parent">Parent key for the key being loaded.</param>
/// <param name="keyName">Path to the registry key.</param>
public RegistryKeyEx(RegistryKey parent, string keyName)
: this(parent.OpenSubKey(keyName))
{ }
/// <summary>
/// Queries the currently set registry key through P/Invoke for the last write time.
/// </summary>
private void SetLastWriteTime()
{
Debug.Assert(Key != null, "RegistryKey component must be initialized");
GCHandle pin = new GCHandle();
long lastWriteTime = 0;
try
{
pin = GCHandle.Alloc(lastWriteTime, GCHandleType.Pinned);
if (RegQueryInfoKey(Key.Handle, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, pin.AddrOfPinnedObject()) == 0)
{
LastWriteTime = DateTime.FromFileTime((long)pin.Target);
}
else
{
LastWriteTime = DateTime.MinValue;
}
}
finally
{
if (pin.IsAllocated)
{
pin.Free();
}
}
}
}

(抱歉,我无法正确突出显示 PSH 代码。)

我如何使用它来改进脚本?


更新时间:2017-11-06

按照@iRon 的建议,我尝试直接访问注册表路径:HKLM\SYSTEM\CurrentControlSet\Enum\USBSTOR\<drive>\Propertie‌​s ,使用 RegEdit,但随后出现权限错误,这很奇怪,因为我的用户帐户是 Admin。 (这是在Win8.1上)

enter image description here

我发现的其他一些选项是:

  1. 使用 Windows 内置 Event Viewer并制作自定义 View 。但是,这需要您已经启用事件日志。
  2. 同样使用 logparser使用 CMD 批处理 script如图herehere . (需要启用事件日志。)
  3. 按照说明进行取证 here ,他们在其中检查各种注册表项和日志文件:...\Windows\inf\setupapi.dev.log获取第一个连接日期,但如何获取最后一个连接更不清楚。 (应该是通过对比\NTUSER\<username>\Software\Microsoft\Windows\Explorer\MountPoints2数据,但是我没找到。)
  4. 另外,“Windows Registry Forensics: Advanced Digital Forensic Analysis of the Windows Registry”一书从第 95 页开始还提供了一些针对 (3) 的额外提示。

一种可能有用的 PS 单行代码是:

Get-WinEvent -LogName Microsoft-Windows-DriverFrameworks-UserMode/Operational | where {$_.Id -eq "2003" -or $_.Id -eq "2102"} | Format-Table –Property TimeCreated, Id, Message -AutoSize -Wrap

这给出了带有消息内容的事件(2003 年、2102 年)的时间戳,可以进一步解析。

TimeCreated           Id Message                                                                                                                                                                                                                  
----------- -- -------
2017-11-09 13:37:04 2102 Forwarded a finished Pnp or Power operation (27, 2) to the lower driver for device
SWD\WPDBUSENUM\_??_USBSTOR#DISK&VEN_KINGSTON&PROD_DATATRAVELER_G2&REV_PMAP#YYYYY&0#{XXXXX} with status 0x0.
2017-11-09 13:37:04 2102 Forwarded a finished Pnp or Power operation (27, 23) to the lower driver for device
SWD\WPDBUSENUM\_??_USBSTOR#DISK&VEN_KINGSTON&PROD_DATATRAVELER_G2&REV_PMAP#YYYYY&0#{XXXXX} with status 0x0.
2017-11-09 13:34:38 2003 The UMDF Host Process ({XXXXX}) has been asked to load drivers for device
SWD\WPDBUSENUM\_??_USBSTOR#DISK&VEN_KINGSTON&PROD_DATATRAVELER_G2&REV_PMAP#YYYYY&0#{XXXXX}.
2017-11-06 15:18:41 2102 Forwarded a finished Pnp or Power operation (27, 2) to the lower driver for device SWD\WPDBUSENUM\{XXXXX}#0000000000007E00 with status 0x0.
2017-11-06 15:18:41 2102 Forwarded a finished Pnp or Power operation (27, 23) to the lower driver for device SWD\WPDBUSENUM\{XXXXX}#0000000000007E00 with status 0x0.
2017-11-06 15:18:13 2003 The UMDF Host Process ({XXXXX}) has been asked to load drivers for device SWD\WPDBUSENUM\{XXXXX}#0000000000007E00.

最佳答案

这还不完整,但应该让你开始吧?

$code = @"
using System;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using Microsoft.Win32.SafeHandles;

/// <summary>
/// Wraps a RegistryKey object and corresponding last write time.
/// </summary>
/// <remarks>
/// .NET doesn't expose the last write time for a registry key
/// in the RegistryKey class, so P/Invoke is required.
/// </remarks>
public class RegistryKeyEx
{
#region P/Invoke Declarations
// This declaration is intended to be used for the last write time only. int is used
// instead of more convenient types so that dummy values of 0 reduce verbosity.
[DllImport("advapi32.dll", EntryPoint = "RegQueryInfoKey", CallingConvention = CallingConvention.Winapi, SetLastError = true)]
extern private static int RegQueryInfoKey(
SafeRegistryHandle hkey,
int lpClass,
int lpcbClass,
int lpReserved,
int lpcSubKeys,
int lpcbMaxSubKeyLen,
int lpcbMaxClassLen,
int lpcValues,
int lpcbMaxValueNameLen,
int lpcbMaxValueLen,
int lpcbSecurityDescriptor,
IntPtr lpftLastWriteTime);
#endregion
#region Public Poperties
/// <summary>
/// Gets the registry key owned by the info object.
/// </summary>
public RegistryKey Key { get; private set; }
/// <summary>
/// Gets the last write time for the corresponding registry key.
/// </summary>
public DateTime LastWriteTime { get; private set; }
#endregion
/// <summary>
/// Creates and initializes a new RegistryKeyInfo object from the provided RegistryKey object.
/// </summary>
/// <param name="key">RegistryKey component providing a handle to the key.</param>
public RegistryKeyEx(RegistryKey key)
{
Key = key;
SetLastWriteTime();
}
/// <summary>
/// Creates and initializes a new RegistryKeyInfo object from a registry key path string.
/// </summary>
/// <param name="parent">Parent key for the key being loaded.</param>
/// <param name="keyName">Path to the registry key.</param>
public RegistryKeyEx(RegistryKey parent, string keyName)
: this(parent.OpenSubKey(keyName))
{ }
/// <summary>
/// Queries the currently set registry key through P/Invoke for the last write time.
/// </summary>
private void SetLastWriteTime()
{
Debug.Assert(Key != null, "RegistryKey component must be initialized");
GCHandle pin = new GCHandle();
long lastWriteTime = 0;
try
{
pin = GCHandle.Alloc(lastWriteTime, GCHandleType.Pinned);
if (RegQueryInfoKey(Key.Handle, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, pin.AddrOfPinnedObject()) == 0)
{
LastWriteTime = DateTime.FromFileTime((long)pin.Target);
}
else
{
LastWriteTime = DateTime.MinValue;
}
}
finally
{
if (pin.IsAllocated)
{
pin.Free();
}
}
}
}
"@

$type = Add-Type -TypeDefinition $code -Language CSharp

$devices = Get-Item HKLM:\SYSTEM\ControlSet001\Enum\USBSTOR\*

$result = foreach($device in $devices) {
Write-Verbose -Verbose "New device: $($device.PSPath)"

Write-Verbose -Verbose "GetClass"
foreach($classname in $device.GetSubKeyNames()) {
$class = $device.OpenSubKey($class)

if($class -eq $null) {
Write-Verbose -Verbose "Class is null"
continue
}

Write-Verbose -Verbose "GetInstance"
foreach($instancename in $class.GetSubKeyNames()) {
$instance = $class.OpenSubKey($instancename)

if($instance -eq $null) {
Write-Verbose -Verbose "Instance is null"
continue
}

Write-Verbose -Verbose "RegistryKeyEx"
$keyEx = New-Object RegistryKeyEx $instance

[pscustomobject]@{
FriendlyName = $keyEx.key.GetValue('FriendlyName')
DevicePath = $device.PSPath
LastWriteTime = $keyEx.LastWriteTime
}
}
}
}

编辑:(通过 not2qubit)

此脚本是内联 C# sharp。当前版本提供以下输出:

VERBOSE: New device: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Enum\USBSTOR\Disk&Ven_Kingston&Prod_DataTraveler_G2&Rev_PMAP
VERBOSE: GetClass
VERBOSE: GetInstance
VERBOSE: RegistryKeyEx
VERBOSE: New device: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Enum\USBSTOR\Disk&Ven_WD&Prod_My_Passport_0730&Rev_1015
VERBOSE: GetClass
VERBOSE: Class is null
VERBOSE: New device: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Enum\USBSTOR\Other&Ven_WD&Prod_SES_Device&Rev_1015
VERBOSE: GetClass
VERBOSE: GetInstance
VERBOSE: RegistryKeyEx

因此缺少时间戳...

编辑:

除非您查看 $result 变量。

PS C:\> $result

FriendlyName DevicePath LastWriteTime
------------ ---------- -------------
Corsair Survivor 3.0 USB Device Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Enum\USBSTOR\Disk&Ven_Corsair&Prod_Survivor_3.0&Rev_1.00 2017-11-05 21:08:25

PS C:\> get-date

November 11, 2017 17:02:09

这为您提供了此人在您的 C# 代码示例中所拥有的内容。我不能说这些信息是否足够准确以满足您的需求。

关于c# - 如何获取之前连接的 USB 设备的时间戳?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44251091/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com