首页
社区
课程
招聘
[分享]从注册表查询USB插拔记录
发表于: 2024-1-14 00:32 9982

[分享]从注册表查询USB插拔记录

2024-1-14 00:32
9982

前言

感谢看雪论坛,和感谢论坛上每位无私奉献大神让我在这里学习到很多知识。也感谢看雪论坛能让我可以在这里分享自已的小工具。有位朋友问USB外接设备记录实现原理,当时本想单独抽源代码出来,但在抽取过程中,发现引用了很多单元,比如注册表读写单元是自已实现的,而这个单元又引用了很多其他的单元,如字符串处理(前辈实现),抽了20分钟都没有抽出来,很麻烦,所以在这里发一下大致原理。




正文


重点:注册表有一些键值,平时我们看不到,要模拟系统用户才能读取出来。用“Windows 可视化管理”的“进程页”选中“winlogon.exe”,右键-->创建进程-->以此为父进程创建。会弹出一个输入窗口,在进程路径中输入 C:\Windows\regedit.exe 点确定就可以打开注册表。


 这时就可以查询到像下面这些不能查询的键值了。

 


  比如注册表中每个USB设备的properties \{83da6326-97a6-4088-9453-a1923f573b29}子键下,只有系统用户可以读取它们。



  安装时间: 指定安装USB设备的日期/时间。仅在以管理员身份运行时才能读取此属性。此属性存储在Properties \ {83da6326-97a6-4088-9453-a1923f573b29}子项下,属性号为0064。


  首次安装时间: 指定首次安装USB设备的时间。仅在以管理员身份运行时才能读取此属性。该属性存储在Properties \ {83da6326-97a6-4088-9453-a1923f573b29}子项下,属性号为0065。


  连接时间: 指定上次插入USB设备的时间。仅在以管理员身份运行时才能读取此属性。此属性仅在Windows 10/8上可用。此属性存储在Properties \ {83da6326-97a6-4088-9453-a1923f573b29}子项下,属性号为0066。


  断开时间: 指定上次拔出USB设备的时间。此属性仅在Windows 10/8上可用。仅在以管理员身份运行时才能读取此属性。此属性存储在Properties \ {83da6326-97a6-4088-9453-a1923f573b29}子项下,属性号为0067。



相关代码如下:


type
  TMyUSBDeviceInfo = record  // 自定义结构,这些从注册表读入的
    USBDI_RegKeyPath : array [0..255] of AnsiChar;
    USBDI_ContainerID : array [0..38] of AnsiChar; 
    USBDI_ClassGUID : array [0..38] of AnsiChar;
    USBDI_DeviceType, USBDI_DeviceVolumeName : array [0..38] of AnsiChar;  //设备类型
    USBDI_DeviceSerialNumber : array [0..67] of AnsiChar;   // 设备序列号
    USBDI_DeviceMfg : array [0..67] of AnsiChar;  //制造商
    USBDI_FriendlyName : array [0..127] of AnsiChar;  //设备名称
    USBDI_LocationInformation  : array [0..63] of AnsiChar; // 位置 Port_#0001.Hub_#0001
    USBDI_SetupDateTime, USBDI_ConnectTime, USBDI_LastUesrDateTime : TDateTime;
  end;
  TMyUSBDeviceInfoArray = array of TMyUSBDeviceInfo;



function MySetThreadTokenOnProcess(const dwPID : DWORD; const Thread : PHANDLE; const bSetThreadToken : Boolean; var StrErrorInfo : String) : Boolean;
var
  process_handle: THandle;
  token_handle: THandle;
  dup_token_handle: THandle;
  token_attributes: SECURITY_ATTRIBUTES;
begin
  Result:=False;
  StrErrorInfo:='';
  if not bSetThreadToken then
  begin
  Result:=windows.SetThreadToken(Thread, //指向函数向其分配模拟令牌的线程的句柄的指针。
                            // 如果 Thread 为 NULL,则该函数会将模拟令牌分配给调用线程。
                 0); // 如果 Token 为 NULL,该函数将导致线程停止使用模拟令牌。
  Exit;
  end;
 
  process_handle := MyOpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, dwPID, True);
  if (process_handle = 0) then
  begin
    StrErrorInfo:='OpenProcess 失败:' + MyGetErrorToText;
    Exit;
  end;
  // 打开与进程关联的访问令牌。
  if (not OpenProcessToken(
    process_handle,  // 打开其访问令牌的进程的句柄。该进程必须具有 PROCESS_QUERY_INFORMATION 访问权限。
    TOKEN_DUPLICATE, // 指定一个访问掩码,该掩码指定对访问令牌的请求访问类型。这些请求的访问类型与令牌的自由访问控制列表(DACL) 进行比较,以确定哪些访问被授予或拒绝。
    token_handle)) then  // 指向句柄的指针,该句柄在函数返回时标识新打开的访问令牌。
  begin
    windows.CloseHandle(process_handle);
    StrErrorInfo:='OpenProcessToken 失败: ' + MyGetErrorToText;
    Exit;
  end;
  windows.CloseHandle(process_handle);
  token_attributes.nLength := sizeof(SECURITY_ATTRIBUTES);
  token_attributes.lpSecurityDescriptor := nil;
  token_attributes.bInheritHandle := FALSE;
   // 创建一个复制现有令牌的新访问令牌。此函数可以创建主令牌或模拟令牌。
  if (not DuplicateTokenEx(
    token_handle,  // 使用 TOKEN_DUPLICATE 访问打开的访问令牌的句柄。
    TOKEN_IMPERSONATE, // 指定新令牌的请求访问权限。
                      //DuplicateTokenEx函数将请求的访问权限与现有令牌的自主访问控制列表(DACL) 进行比较,以确定授予或拒绝哪些权限。
                      //要请求与现有令牌相同的访问权限,请指定零。要请求对调用者有效的所有访问权限,请指定 MAXIMUM_ALLOWED。
    @token_attributes, // 指向 SECURITY_ATTRIBUTES结构的指针,该结构指定新令牌的安全描述符并确定子进程是否可以继承令牌。
                       //如果lpTokenAttributes为NULL,则令牌获取默认安全描述符,并且无法继承句柄。
                       //如果安全描述符包含系统访问控制列表(SACL),则令牌将获得 ACCESS_SYSTEM_SECURITY 访问权限,即使它没有在dwDesiredAccess中请求。
                       //要在新令牌的安全描述符中设置所有者,调用者的进程令牌必须具有SE_RESTORE_NAME权限集。
    SecurityImpersonation,  // 从 SECURITY_IMPERSONATION_LEVEL 枚举中指定一个值,该值指示新令牌的模拟级别。
                            // 安全模拟    服务器进程可以在其本地系统上模拟客户端的安全上下文。服务器无法在远程系统上模拟客户端。
    TokenImpersonation,    //表示模拟令牌。
    dup_token_handle)    //指向接收新标记的HANDLE变量的指针。
    ) then
  begin
    windows.CloseHandle(token_handle);
    StrErrorInfo:='DuplicateTokenEx 失败:' + MyGetErrorToText;
    Exit;
  end;
  windows.CloseHandle(token_handle);
  if windows.SetThreadToken(Thread, //指向函数向其分配模拟令牌的线程的句柄的指针。
                            // 如果 Thread 为 NULL,则该函数会将模拟令牌分配给调用线程。
                    dup_token_handle  // 要分配给线程的模拟令牌的句柄。 此句柄必须已使用 TOKEN_IMPERSONATE 访问权限打开。
                                      // 如果 Token 为 NULL,该函数将导致线程停止使用模拟令牌。
                    ) then
  begin
  Result:=True;
  end
  else
  begin
  StrErrorInfo:='SetThreadToken 失败:' + MyGetErrorToText;
  end;
  windows.CloseHandle(dup_token_handle);
end;


// 自己简单封装的 RegOpenKeyEx
function MyRegOpenKeyEx(const RootKey : HKEY; const lpSubKey : PChar; const KEYsamDesired : REGSAM; const isKEY_WOW64_64KEY : Boolean; var phkResult : HKEY) : Boolean;
var
  samDesired : REGSAM;
begin
  samDesired:=KEYsamDesired;
  if isKEY_WOW64_64KEY and G_IsWin64 then
  begin
  samDesired:=samDesired or KEY_WOW64_64KEY;  // 注意,这里是禁止重定向
  end;
  Result:= ERROR_SUCCESS = RegOpenKeyEx(RootKey, lpSubKey, 0, samDesired, phkResult);
end;


// 自己简单封装的 RegEnumKeyEx
function MyRegEnumKeyNameToList(const phkResult: HKEY; var KeyNamesList: TStringList) : Boolean;
var
  I : Integer;
  dwDataSize, dwLen : DWORD;
  status : DWORD;
  buffer : array [0..255] of AnsiChar;  //255 个字符
begin
  Result:=False;
  if not Assigned(KeyNamesList) then exit;
  dwLen:=Length(buffer);
  I:=0;
  repeat
    ZeroMemory(@buffer[0], dwLen);
    dwDataSize:=dwLen;
    status:=RegEnumKeyEx(phkResult, // 一个已打开项的句柄,或者指定一个标准项名
                         I, // 欲获取的子项的索引。第一个子项的索引编号为零
                         buffer, //用于装载指定索引处项名的一个缓冲区
                         dwDataSize, // 指定一个变量,用于装载lpName缓冲区的实际长度(包括空字符)。一旦返回,它会设为实际装载到lpName缓冲区的字符数量
                         nil, //未用,设为零
                         nil, //项使用的类名。可以为vbNullString
                         nil, // 用于装载lpClass缓冲区长度的一个变量。一旦返回,它会设为实际装载到缓冲区的字符数量
                         nil); // 枚举子项上一次修改的时间
    if ERROR_SUCCESS = status then  //枚举子健
    begin
    KeyNamesList.Add(buffer);
    Inc(I);
    end;
  until status <> ERROR_SUCCESS; // 返回值, 零(ERROR_SUCCESS)表示成功。其他任何值都代表一个错误代码
  Result:=I > 0;
end;

// 取出注册表中二进制(数组长度为8)的值转换为时间
function MyRegGetPropertiesDateTime(const RootKey : HKEY; const lpSubKey : PChar; const isKEY_WOW64_64KEY : Boolean; var DTTime : TDateTime) : Boolean;
var
  //RegValue :PChar;
  samDesired : REGSAM;
  phkResult : HKEY;
  AData: TMyArrayOfBytes;
  dwOutBufSize : DWORD;
  //iValue64 : Int64;
begin
  Result:=False;
  DTTime:=0;
  samDesired:=KEY_READ or KEY_QUERY_VALUE;
  if isKEY_WOW64_64KEY and G_IsWin64 then
  begin
  samDesired:=samDesired or KEY_WOW64_64KEY;  // 注意,这里是禁止重定向
  end;

  if ERROR_SUCCESS = RegOpenKeyEx(RootKey, lpSubKey, 0, samDesired, phkResult) then
  begin
    if MyRegQueryBinaryValueEx(phkResult, '', AData, dwOutBufSize) then
    begin
    DTTime:=MyRegBinaryValueToDateTime(AData, 0, dwOutBufSize);
    Result:=True;
    SetLength(AData, 0);
    end
    else
    begin
    Result:=MyRegGetKeyLastWriteTime(phkResult, DTTime);
    end;
  RegCloseKey(phkResult);
  end;

end;

// 读取注册表USB设备信息到 TMyUSBDeviceInfoArray
function MyGetUSBDeviceUserInfo(var MyUSBDeviceInfo : TMyUSBDeviceInfoArray) : Boolean;
var
  I, J, iLen, iTtemCount : Integer;
phkResult, phkResult2, phkResult3, hkKeyLastUesrDateTime : HKEY;
  KeyNamesList1, KeyNamesList2, KeyNamesList3: TStringList;
  StrKeyName, StrKey_WPDBUSENUM : PAnsiChar;
  StrFriendlyName, StrClassGUID, StrSerialNumber, StrLastUesrDateTime, StrMfg, StrVolumeName,
    StrSetupDateTime, StrConnectTime, StrKeyName2, StrKeyName3, StrProperties, StrContainerID, StrService, StrErrorInfo : string;
  DTLastWriteTime, DTConnectTime, DTSetupDateTime : TDateTime;
begin
  Result:=False;
  KeyNamesList1:=TStringList.Create;
  KeyNamesList2:=TStringList.Create;
  KeyNamesList3:=TStringList.Create;
  // 接入过的 USB 设备都保存在这里
  iLen:=0; // 数组长度
  iTtemCount:=0;
  StrKeyName:='SYSTEM\CurrentControlSet\Enum\USB\';
  if MyRegOpenKeyEx(HKEY_LOCAL_MACHINE, StrKeyName, KEY_READ or KEY_QUERY_VALUE, True, phkResult) then
  begin
    if MyRegEnumKeyNameToList(phkResult, KeyNamesList1) then
    begin
      for I:=0 to KeyNamesList1.Count-1 do
      begin
      StrKeyName2:=StrKeyName + KeyNamesList1[I];
        if MyRegOpenKeyEx(HKEY_LOCAL_MACHINE, PAnsiChar(StrKeyName2), KEY_READ or KEY_QUERY_VALUE, True, phkResult2) then
        begin
        KeyNamesList2.Clear;
          if MyRegEnumKeyNameToList(phkResult2, KeyNamesList2) then
          begin
            for J:=0 to KeyNamesList2.Count-1 do
            begin
            StrKeyName3:= StrKeyName2 + '\' + KeyNamesList2[J];
              if MyRegOpenKeyEx(HKEY_LOCAL_MACHINE, PAnsiChar(StrKeyName3), KEY_READ or KEY_QUERY_VALUE, True, phkResult3) then
              begin
                if MyRegQueryStringValueEx(phkResult3, 'Service', StrService) and (SameText(StrService, 'USBSTOR')) then
                begin
                  if MyRegQueryStringValueEx(phkResult3, 'ContainerID', StrContainerID) then  // 通过这里来定位
                  begin
                  MyRegQueryStringValueEx(phkResult3, 'LocationInformation', StrMfg);
                  Inc(iLen);// 数组长度
                  SetLength(MyUSBDeviceInfo, iLen);
                    with MyUSBDeviceInfo[iLen - 1] do
                    begin
                    StringCbCopyA(@USBDI_RegKeyPath[0], SizeOf(USBDI_RegKeyPath), PAnsiChar(StrKeyName3));
                    StringCbCopyA(@USBDI_ContainerID[0], SizeOf(USBDI_ContainerID), PAnsiChar(StrContainerID));
                    StringCbCopyA(@USBDI_LocationInformation[0], SizeOf(USBDI_LocationInformation), PAnsiChar(StrMfg));
                    end;
                  end;
                end;
              RegCloseKey(phkResult3);
              end;
            end;
          end;
        RegCloseKey(phkResult2);
        end;
      end;
    end;
  RegCloseKey(phkResult);
  end;
                
  if (iLen > 0) and MyRegOpenKeyEx(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Enum\USBSTOR', KEY_READ or KEY_QUERY_VALUE, True, phkResult) then
  begin
    if MyRegEnumKeyNameToList(phkResult, KeyNamesList1) then
    begin
      if MySetThreadTokenOnProcess(MyGetProcessPIDByNameEx('winlogon.exe', 3), nil, True, StrErrorInfo) then
      begin
        for I:=0 to KeyNamesList1.Count -1 do
        begin
        StrKeyName:=PAnsiChar('SYSTEM\CurrentControlSet\Enum\USBSTOR' + '\' + KeyNamesList1[I]);
          if MyRegOpenKeyEx(HKEY_LOCAL_MACHINE, StrKeyName, KEY_READ or KEY_QUERY_VALUE, True, phkResult2) then
          begin
          KeyNamesList2.Clear;
            if MyRegEnumKeyNameToList(phkResult2, KeyNamesList2) then
            begin
            StrSerialNumber:=KeyNamesList2[0];
            StrKeyName2:=StrKeyName + '\' + StrSerialNumber;
            StrConnectTime:='';
            StrLastUesrDateTime:='';
            StrSetupDateTime:='';
              if MyRegOpenKeyEx(HKEY_LOCAL_MACHINE, PAnsiChar(StrKeyName2), KEY_READ or KEY_QUERY_VALUE, True, phkResult3) then
              begin
                if MyRegQueryStringValueEx(phkResult3, 'ContainerID', StrContainerID) then
                begin
                  for J:=Low(MyUSBDeviceInfo) to High(MyUSBDeviceInfo) do
                  begin
                    if SameText(StrContainerID, MyUSBDeviceInfo[J].USBDI_ContainerID)  then
                    begin    
                    StrProperties:=MyUSBDeviceInfo[J].USBDI_RegKeyPath + '\Properties\{83da6326-97a6-4088-9453-a1923f573b29}\';
                      // 首次安装时间: 仅在以管理员身份运行时才能读取此属性。
                      // 该属性存储在Properties \ {83da6326-97a6-4088-9453-a1923f573b29}子项下,属性号为0065。
                      if MyRegGetPropertiesDateTime(HKEY_LOCAL_MACHINE, PAnsiChar(StrProperties + '0065'), True, DTSetupDateTime) then
                      begin
                      end
                      //安装时间
                      else if MyRegGetPropertiesDateTime(HKEY_LOCAL_MACHINE, PAnsiChar(StrProperties + '0064'), True, DTSetupDateTime) then
                      begin
                      end;
                      // 所有时间戳均采用标准 Windows 64 位 (FILETIME) 格式。
                      // 最近插入时间   上一次到达日期
                      MyRegGetPropertiesDateTime(HKEY_LOCAL_MACHINE, PAnsiChar(StrProperties + '0066'), True, DTConnectTime);
                      // 最近拔出时间 断开时间    上一次删除日期
                      MyRegGetPropertiesDateTime(HKEY_LOCAL_MACHINE, PAnsiChar(StrProperties + '0067'), True, DTLastWriteTime);
                      // HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\STORAGE\Volume\**
                      MyRegQueryStringValueEx(phkResult3, 'FriendlyName', StrFriendlyName);
                      MyRegQueryStringValueEx(phkResult3, 'ClassGUID', StrClassGUID);
                      StrClassGUID:=MyGetUSBDeviceClassGUIDToStr(StrClassGUID);
                      StrKey_WPDBUSENUM:=PAnsiChar('SYSTEM\CurrentControlSet\Enum\SWD\WPDBUSENUM\_??_USBSTOR#' + KeyNamesList1[I]  + '#' + StrSerialNumber + '#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}');
                      if MyRegOpenKeyEx(HKEY_LOCAL_MACHINE, StrKey_WPDBUSENUM, KEY_READ or KEY_QUERY_VALUE, True, hkKeyLastUesrDateTime) then
                      begin
                      MyRegQueryStringValueEx(hkKeyLastUesrDateTime, 'Mfg', StrMfg);
                      MyRegQueryStringValueEx(hkKeyLastUesrDateTime, 'FriendlyName', StrVolumeName);
                      RegCloseKey(hkKeyLastUesrDateTime);
                      end
                      else
                      begin
                      StrMfg:='';
                      StrVolumeName:='';
                      end;
                      with MyUSBDeviceInfo[J] do
                      begin
                      StringCbCopyA(@USBDI_FriendlyName[0], SizeOf(USBDI_FriendlyName), PAnsiChar(StrFriendlyName));
                      StringCbCopyA(@USBDI_DeviceType[0], SizeOf(USBDI_DeviceType), PAnsiChar(StrClassGUID));  //设备类型
                      StrSerialNumber:=MyGetUSBSerialNumberOnRegKey(StrSerialNumber);
                      StringCbCopyA(@USBDI_DeviceSerialNumber[0], SizeOf(USBDI_DeviceSerialNumber), PAnsiChar(StrSerialNumber));   // 设备序列号
                      StringCbCopyA(@USBDI_DeviceMfg[0], SizeOf(USBDI_DeviceMfg), PAnsiChar(StrMfg));   // 制造商
                      StringCbCopyA(@USBDI_DeviceVolumeName[0], SizeOf(USBDI_DeviceVolumeName), PAnsiChar(StrVolumeName));  // 卷标
                      USBDI_SetupDateTime:=DTSetupDateTime; // 安装时间
                      USBDI_ConnectTime:=DTConnectTime;  // 最近插入时间 连接时间
                      USBDI_LastUesrDateTime:=DTLastWriteTime; // 最近拔出时间 最后一次使用时间  断开时间
                      end;
                    Inc(iTtemCount);
                    Break;
                    end;
                  end;
                end;
              RegCloseKey(phkResult3);
              end;
            end;
          RegCloseKey(phkResult2);
          end;
        end;
      MySetThreadTokenOnProcess(0, nil, False, StrErrorInfo);
      end
      else
      begin
      MyAddDebugInfo('Err Reg Token:' + StrErrorInfo);
      end;
    end;
  KeyNamesList1.Free;
  KeyNamesList2.Free;
  KeyNamesList3.Free;
  RegCloseKey(phkResult);
  end;
  Result:=iTtemCount > 0;
end;


// 查询 USB 插拔记录
procedure TWindowsVisualManage_MainForm.PopupMenu_other2_USBSTORClick(
  Sender: TObject);
var
  cListItem : TListItem;
  cListColumn : TListColumn;
  MyUSBDeviceInfo : TMyUSBDeviceInfoArray;
  I : Integer;
begin
  MyPopupMenu_other2_AsClick(Sender);  // 当初考虑把所有查询功能都共用一个"ListView"控件,以节省不必要的开销。
  cListColumn:=ListView_VCLShareQuery.Columns.Add;
  cListColumn.Caption:='设备名称';
  cListColumn.Width:=250;
  cListColumn:=ListView_VCLShareQuery.Columns.Add;
  cListColumn.Caption:='设备类型';
  cListColumn.Width:=68;
  cListColumn:=ListView_VCLShareQuery.Columns.Add;
  cListColumn.Caption:='设备位置';
  cListColumn.Width:=132;
  cListColumn:=ListView_VCLShareQuery.Columns.Add;
  cListColumn.Caption:='设备序列号';
  cListColumn.Width:=158;
  cListColumn:=ListView_VCLShareQuery.Columns.Add;
  cListColumn.Caption:='制造商';
  cListColumn.Width:=82;
  cListColumn:=ListView_VCLShareQuery.Columns.Add;
  cListColumn.Caption:='卷标';
  cListColumn.Width:=82;
  cListColumn:=ListView_VCLShareQuery.Columns.Add;
  cListColumn.Caption:='首次插入时间';
  cListColumn.Width:=126;
  cListColumn:=ListView_VCLShareQuery.Columns.Add;
  cListColumn.Caption:='最近插入时间'; // 连接时间
  cListColumn.Width:=126;
  cListColumn:=ListView_VCLShareQuery.Columns.Add;
  cListColumn.Caption:='最近拔出时间'; // 断开时间
  cListColumn.Width:=126;
  if MyGetUSBDeviceUserInfo(MyUSBDeviceInfo) then
  begin
    for I:=Low(MyUSBDeviceInfo) to High(MyUSBDeviceInfo) do
    begin
      with MyUSBDeviceInfo[I] do
      begin
      cListItem:=ListView_VCLShareQuery.Items.Add;
      cListItem.Caption:=USBDI_FriendlyName; //设备名称
      cListItem.SubItems.Add(USBDI_DeviceType); //设备类型
      cListItem.SubItems.Add(USBDI_LocationInformation); // 位置
      cListItem.SubItems.Add(USBDI_DeviceSerialNumber); //设备序列号
      cListItem.SubItems.Add(USBDI_DeviceMfg);  //制造商
      cListItem.SubItems.Add(USBDI_DeviceVolumeName); // 卷标
      cListItem.SubItems.Add(FormatDateTime('yyyy/mm/dd hh:mm:ss', USBDI_SetupDateTime)); // 安装时间
      cListItem.SubItems.Add(FormatDateTime('yyyy/mm/dd hh:mm:ss', USBDI_ConnectTime)); // 连接时间
      cListItem.SubItems.Add(FormatDateTime('yyyy/mm/dd hh:mm:ss', USBDI_LastUesrDateTime)); // 最后一次使用时间  断开时间
      end;
    end;
  StatusBar1.Panels.Items[4].Text:='USB外接设备记录:' + IntToStr(ListView_VCLShareQuery.Items.Count);
  end;
end;





[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2024-5-9 15:02 被kagayaki编辑 ,原因:
收藏
免费 4
支持
分享
最新回复 (12)
雪    币: 4112
活跃值: (5812)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
2
感谢楼主的解答
2024-1-14 15:59
0
雪    币: 1276
活跃值: (5139)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
badboyl 感谢楼主的解答
不用
2024-1-14 20:44
0
雪    币: 3004
活跃值: (30861)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
感谢分享
2024-1-14 23:09
1
雪    币: 4803
活跃值: (3802)
能力值: ( LV12,RANK:230 )
在线值:
发帖
回帖
粉丝
5


USBDriveLog

https://www.nirsoft.net/utils/usb_drive_log.html

http://www.linux-usb.org/usb.ids



USBDriveLog是第三方工具,将Win10、Win11内置USB日志以更人性化的方式展示出来。该工具可查看U盘插入时间、拔出时间、容量、文件系统类型等等,还有许多可用作U盘指纹的数据。一般关心这几列数据:


Serial Number   // U盘序列号

Plug Time       // U盘插入时间

Unplug Time     // U盘拔出时间

Capacity        // U盘容量(大小)

File System     // U盘文件系统类型


涉及USB设备取证场景时,USBDriveLog是一种选择。该工具只有一个EXE,无需安装,便携。为了显示Vendor Name、Product Name,需要额外下载usb.ids,与EXE置于同一目录。


缺省在线查看USB日志,但可以离线查看USB日志,只要找得着日志,比如这种位置:


X:\Windows\System32\winevt\Logs\Microsoft-Windows-Partition%4Diagnostic.evtx

X:\Windows\System32\winevt\Logs\Microsoft-Windows-Storsvc%4Diagnostic.evtx


若日志位于C盘,需要管理员权限访问这两个文件,离线查看时无所谓。具体操作如下:


File->Choose Data Source (F7)->Load from->External Folder


☆ 参考资源


[1] USBDriveLog

    https://www.nirsoft.net/utils/usb_drive_log.html

    http://www.linux-usb.org/usb.ids


[2] USB storage forensics in Win10 #1 - Events - [2019-08-03]

    https://www.senturean.com/posts/19_08_03_usb_storage_forensics_1/


[3] Get-WinEvent

    https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.diagnostics/get-winevent


    Creating Get-WinEvent queries with FilterHashtable

    https://learn.microsoft.com/en-us/powershell/scripting/samples/creating-get-winevent-queries-with-filterhashtable


[4] Consuming Events (Windows Event Log)

    https://learn.microsoft.com/en-us/windows/win32/wes/consuming-events


[5] wevtutil

    https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/wevtutil


最后于 2024-1-15 09:18 被scz编辑 ,原因: 补充参考资源
2024-1-15 09:16
0
雪    币: 1276
活跃值: (5139)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
6
scz 参USBDriveLoghttps://www.nirsoft.net/utils/usb_drive_log.htmlhttp://www.linux-usb.org/usb.idsUSBDrive ...
谢谢
2024-1-16 19:51
0
雪    币: 1276
活跃值: (5139)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
7
秋狝 感谢分享
谢谢
2024-1-20 14:46
0
雪    币: 7063
活跃值: (2958)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
学习了 
2024-3-12 18:07
0
雪    币: 1276
活跃值: (5139)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
9
shuyangzjg 学习了
共同进步
2024-3-13 18:12
0
雪    币: 4055
活跃值: (4792)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
学到了
2024-3-13 19:03
0
雪    币: 1276
活跃值: (5139)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
11
青眼白龙 学到了[em_67]
谢谢
2024-3-14 15:04
0
雪    币: 4224
活跃值: (788)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
学到了,对工作帮助很大~
2024-6-22 11:43
0
雪    币: 1276
活跃值: (5139)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
13
yuanyouran 学到了,对工作帮助很大~[em_63]
2024-6-22 13:17
0
游客
登录 | 注册 方可回帖
返回
//