public void UsbStor() { var r = new USBSTOR(); // var reg = new RegistryHive(@"D:\SynologyDrive\Registry\NTUSER_RecentAppsERZ.DAT"); var reg = new RegistryHive(@"C:\temp\SYSTEM"); reg.ParseHive(); var key = reg.GetKey(@"ControlSet001\Enum\USBSTOR"); Check.That(key).IsNotNull(); Check.That(r.Values.Count).IsEqualTo(0); r.ProcessValues(key); Check.That(r.Values.Count).IsEqualTo(4); var ff = (RegistryPlugin.USBSTOR.ValuesOut)r.Values[0]; Check.That(ff.DiskId).IsNotEmpty(); Check.That(ff.DiskId).Contains("Timestamp"); Debug.WriteLine(ff.DiskId); foreach (var rValue in r.Values) { Debug.WriteLine(rValue); } }
///////////////////////////////////////////////////// // // // EnumerateUSBDevices() // // // ///////////////////////////////////////////////////// //Description: Uses .NET registry objects to dig in // the infamous USBSTOR key for past and // present USB devices. //Returns: true if successful // NOTE: // techniques used in this function are from // "Windows Forensic Analysis" by Harlan Carvey // ///////////////////////////////////////////////////// public static bool EnumerateUSBDevices(ref StringBuilder usbdata) { RegistryKey USBSTOR; string current = ""; //loop through 10 currentcontrolsets //sample structure: // HKLM\System\CurrentControlSet003\Enum\USBSTOR\ // \Disk&Ven_ChipsBnk&Prod_Flash_Disk&Rev_2.00 --> USB DRIVE // \3852u395823 --> Instance ID // \ag3490t24t940 // \Disk&Ven_SanDisk&Prod_Cruzer_Slide&Rev_4.05 --> USB DRIVE // .... // for (int i = 0; i < 10; i++) { current = "00" + i.ToString(); //001,002,003,etc USBSTOR = Registry.LocalMachine.OpenSubKey("System\\ControlSet" + current + "\\Enum\\USBSTOR"); //if the key doesnt exist, we must continue b/c control set numbering isn't contiguous if (USBSTOR == null) { continue; } string[] DeviceClassIds = USBSTOR.GetSubKeyNames(); //loop through all usb device class IDs beneath USBSTOR... //get a list of subkeys which are named by instance IDs foreach (string deviceName in DeviceClassIds) { //lots of info you can get from device name: //Disk&Ven_###&Prod_###&Rev_### -- we want the ### string[] driveInfo = deviceName.Split(new char[] { '&' }); string vendor = driveInfo[1].Replace("Ven_", "").Replace("_", " "); string product = driveInfo[2].Replace("Prod_", "").Replace("_", " "); string revision = driveInfo[3].Replace("Rev_", "").Replace("_", " "); string serial = ""; ArrayList insertionDates = new ArrayList(); //get list of instances string[] instances = USBSTOR.OpenSubKey(deviceName).GetSubKeyNames(); int count = 0; //each unique instance represents a time the device was plugged in //so collect information on each instance foreach (string instanceId in instances) { //if the second character in the instanceId is '&', then we //know the id is made up by windows and manuf did not give one if (instanceId[1] == '&') { serial = "None"; } else { serial = instanceId; } string friendlyName = "[none]"; object friendlyNameValueObj = USBSTOR.OpenSubKey(deviceName + "\\" + instanceId).GetValue("FriendlyName"); if (friendlyNameValueObj != null) { friendlyName = (string)friendlyNameValueObj.ToString(); } //see ntddstor.h - these are GUIDs for disk and volume device interfaces.. string key1 = "SYSTEM\\CurrentControlSet\\Control\\DeviceClasses\\{53f56307-b6bf-11d0-94f2-00a0c91efb8b}"; string key2 = "SYSTEM\\CurrentControlSet\\Control\\DeviceClasses\\{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}"; RegistryKey diskGuid = Registry.LocalMachine.OpenSubKey(key1); RegistryKey volDevGuid = Registry.LocalMachine.OpenSubKey(key2); string[] DeviceClasses1 = diskGuid.GetSubKeyNames(); string[] DeviceClasses2 = volDevGuid.GetSubKeyNames(); //merge two sets of device classes into one string[] allDeviceClasses = new string[DeviceClasses1.Length + DeviceClasses2.Length]; DeviceClasses1.CopyTo(allDeviceClasses, 0); DeviceClasses2.CopyTo(allDeviceClasses, DeviceClasses1.Length); IntPtr lastInsertionDatePtr = (IntPtr)0; IntPtr keyHandle = (IntPtr)0; IntPtr hKey = (IntPtr)0; System.Runtime.InteropServices.ComTypes.FILETIME lastInsertionDate = new System.Runtime.InteropServices.ComTypes.FILETIME(); //get last write date/time foreach (string devclass in allDeviceClasses) { if (devclass.Contains(instanceId)) { //open the registry key using unmanaged API call if (Win32Helper.RegOpenKeyExW(hKey, key1 + "\\" + devclass, 0, 0x00020019, ref keyHandle) == 0 && keyHandle != (IntPtr)(-1)) { //pass 0 to all the vars we dont care about- we only want last write time Win32Helper.RegQueryInfoKeyW(keyHandle, null, (IntPtr)0, (IntPtr)0, (IntPtr)0, (IntPtr)0, (IntPtr)0, (IntPtr)0, (IntPtr)0, (IntPtr)0, (IntPtr)0, lastInsertionDatePtr); Marshal.PtrToStructure(lastInsertionDatePtr, lastInsertionDate); insertionDates.Add(lastInsertionDate.ToString()); } } } //print out summary info on first iteration of instances of this usb drive if (count == 0) { usbdata.AppendLine(" Found USB Device '" + friendlyName + "'"); usbdata.AppendLine(" Serial Num : " + serial); usbdata.AppendLine(" Vendor : " + vendor); usbdata.AppendLine(" Product : " + product); usbdata.AppendLine(" Revision : " + revision); usbdata.AppendLine(" Instances : " + instances.Length); } usbdata.AppendLine(" Date: " + lastInsertionDate.dwHighDateTime.ToString() + "/" + lastInsertionDate.dwLowDateTime.ToString()); count++; } //add how many other insertion dates there were string[] dts = (string[])insertionDates.ToArray(typeof(string)); usbdata.AppendLine(" InsertionDates : " + string.Join(",", dts)); } } return(true); }