Создайте тот же идентификатор аппаратного обеспечения компьютера. (CHID), например, computerhardwareids.exe из Windows SDK

ВСТУПЛЕНИЕ

Эта ветка должна стать завершающей главой для этот первый поток от 2014 года и этот второй от 2017 года.

Короче говоря, вам просто нужно знать, что Microsoft Windows SDK включает в себя программу под названием computerhardwareids.exe, которая, как следует из ее названия, генерирует (несколько) аппаратных идентификаторов для компьютера, и я хотел бы воспроизвести алгоритм CHID, используя .NET для создания тех же идентификаторов, что и эта программа.

Список CHIDS, которые эта программа может генерировать в Windows 10, которую я использую, указан как здесь:

  1. HardwareID-0 Производитель + Семейство + Название продукта + Номер SKU + Производитель BIOS + версия BIOS + основная версия BIOS + дополнительная версия BIOS
  2. HardwareID-1 Производитель + Семейство + Название продукта + Производитель BIOS + Версия BIOS + основная версия BIOS + дополнительная версия BIOS
  3. HardwareID-2 Производитель + Название продукта + Производитель BIOS + Версия BIOS + Основная версия BIOS + Дополнительная версия BIOS
  4. HardwareID-3 Производитель + Семейство + Название продукта + Номер SKU + Производитель базовой платы + Продукт базовой платы
  5. HardwareID-4 Производитель + семейство + название продукта + номер SKU
  6. HardwareID-5 Производитель + семейство + название продукта
  7. HardwareID-6 Производитель + Номер SKU + Производитель базовой платы + Продукт базовой платы
  8. HardwareID-7 Производитель + номер SKU
  9. HardwareID-8 Производитель + Название продукта + Производитель базовой платы + Продукт базовой платы
  10. HardwareID-9 Производитель + название продукта
  11. HardwareID-10 Производитель + Семейство + Производитель базовой платы + Продукт базовой платы
  12. HardwareID-11 Производитель + семейство
  13. HardwareID-12 Производитель + Тип корпуса
  14. HardwareID-13 Производитель + Производитель базовой платы + Продукт базовой платы
  15. HardwareID-14 Производитель

ПРОБЛЕМА

Мне удалось воспроизвести все идентификаторы оборудования, кроме: 0, 1, 2 и 12.

Я обнаружил, что эти четыре проблемных идентификатора имеют общее то, что они единственные, которые содержат числовые значения для добавления к строке, с помощью которой генерируется UUID. См. таблицу по этой ссылке или прочтите этот список:

  • Имя | Длина | Тип

  • Основная версия системного BIOS | БАЙТ | Варьируется

  • Второстепенная версия системного BIOS | БАЙТ | Варьируется

  • Тип корпуса | БАЙТ | Варьируется

Я думаю, что это явный признак того, что я не знаю, как обращаться с этими числовыми значениями при построении строки, с помощью которой генерируется UUID.

ВОПРОС

Я не знаю, в каком классе WMI найти значение Тип корпуса, но это не имеет значения, потому что я действительно не забочусь о репликации значения HardwareID-12/Тип корпуса, но я хотел бы иметь возможность реплицировать HardwareID-0, HardwareID-1 и HardwareID-2

Я уже знаю, из какого класса WMI получить основную и дополнительную версию BIOS для HardwareID-0, HardwareID-1 и HardwareID-2, но проблема в том, что когда я добавляю эти значения BIOS к строке, с помощью которой создается UUID, я получаю совершенно другое UUID из того, что генерирует computerhardwareids.exe.

Мои вопросы:

  • Что мне нужно сделать, чтобы воспроизвести точно такой же сгенерированный UUID для HardwareID-0, HardwareID-1 и HardwareID-2?.

  • Может быть, мне нужно обрабатывать эти числовые значения особым образом, применяя какой-то формат, который я не знаю, при добавлении их к строке, с которой генерируется UUID?

Обратите внимание, что у меня НЕТ опыта реверс-инжиниринга.

КОД

Это код, который я использую, написанный на VB.NET. В его текущем состоянии я считаю его рабочим решением, которое реплицирует (или должно реплицировать) те же идентификаторы оборудования компьютера, что и программа computerhardwareids.exe, за исключением идентификаторов оборудования 0, 1, 2 и 12 по причинам, которые я объяснил.

  1. Перечисление типа идентификатора компьютерного оборудования

     ' https://docs.microsoft.com/en-us/windows-hardware/drivers/install/specifying-hardware-ids-for-a-computer
     Public Enum ComputerHardwareIdMicrosoftType
    
         ''' <summary>
         ''' HardwareID-0
         ''' <para></para>
         ''' Manufacturer + Family + Product Name + SKU Number + BIOS Vendor + BIOS Version + BIOS Major Release + BIOS Minor Release
         ''' </summary>
         HardwareID_0 = 0
    
         ''' <summary>
         ''' HardwareID-1
         ''' <para></para>
         ''' Manufacturer + Family + Product Name + BIOS Vendor + BIOS Version + BIOS Major Release + BIOS Minor Release
         ''' </summary>
         HardwareID_1 = 1
    
         ''' <summary>
         ''' HardwareID-2
         ''' <para></para>
         ''' Manufacturer + Product Name + BIOS Vendor + BIOS Version + BIOS Major Release + BIOS Minor Release
         ''' </summary>
         HardwareID_2 = 2
    
         ''' <summary>
         ''' HardwareID-3
         ''' <para></para>
         ''' Manufacturer + Family + Product Name + SKU Number + Baseboard Manufacturer + Baseboard Product
         ''' </summary>
         HardwareID_3 = 3
    
         ''' <summary>
         ''' HardwareID-4
         ''' <para></para>
         ''' Manufacturer + Family + Product Name + SKU Number
         ''' </summary>
         HardwareID_4 = 4
    
         ''' <summary>
         ''' HardwareID-5
         ''' <para></para>
         ''' Manufacturer + Family + Product Name
         ''' </summary>
         HardwareID_5 = 5
    
         ''' <summary>
         ''' HardwareID-6
         ''' <para></para>
         ''' Manufacturer + SKU Number + Baseboard Manufacturer + Baseboard Product
         ''' </summary>
         HardwareID_6 = 6
    
         ''' <summary>
         ''' HardwareID-7
         ''' <para></para>
         ''' Manufacturer + SKU Number
         ''' </summary>
         HardwareID_7 = 7
    
         ''' <summary>
         ''' HardwareID-8
         ''' <para></para>
         ''' Manufacturer + Product Name + Baseboard Manufacturer + Baseboard Product
         ''' </summary>
         HardwareID_8 = 8
    
         ''' <summary>
         ''' HardwareID-9
         ''' <para></para>
         ''' Manufacturer + Product Name
         ''' </summary>
         HardwareID_9 = 9
    
         ''' <summary>
         ''' HardwareID-10
         ''' <para></para>
         ''' Manufacturer + Family + Baseboard Manufacturer + Baseboard Product
         ''' </summary>
         HardwareID_10 = 10
    
         ''' <summary>
         ''' HardwareID-11
         ''' <para></para>
         ''' Manufacturer + Family
         ''' </summary>
         HardwareID_11 = 11
    
         ''' <summary>
         ''' HardwareID-12
         ''' <para></para>
         ''' Manufacturer + Enclosure Type
         ''' </summary>
         HardwareID_12 = 12
    
         ''' <summary>
         ''' HardwareID-13
         ''' <para></para>
         ''' Manufacturer + Baseboard Manufacturer + Baseboard Product
         ''' </summary>
         HardwareID_13 = 13
    
         ''' <summary>
         ''' HardwareID-14
         ''' <para></para>
         ''' Manufacturer
         ''' </summary>
         HardwareID_14 = 14
    
     End Enum
    
  2. Метод генерации идентификатора аппаратного обеспечения компьютера:

     Public Shared Function GetComputerHardwareIdFromMicrosoftHwIdType(hwidType As ComputerHardwareIdMicrosoftType) As Guid
    
         Select Case hwidType
             Case Is < 0, Is > 14
                 Throw New InvalidEnumArgumentException(argumentName:=NameOf(hwidType), invalidValue:=hwidType, enumClass:=GetType(ComputerHardwareIdMicrosoftType))
    
         '' *************************************************************
         '' HARDWARE TYPE ID. 0, 1 AND 2 ARE NOT GIVING THE CORRECT GUID.
         '' *************************************************************
             Case 0, 1, 2, 12
                 Throw New NotImplementedException("This hardware id type is not implemented.")
         End Select
    
         ' Namespace used by 'computerhardwareids.exe' program included in the Windows SDK.
         ' https://stackoverflow.com/questions/25190906/get-hardware-ids-like-microsoft-does/43619888#43619888
         ' https://blogs.gnome.org/hughsie/2017/04/25/reverse-engineering-computerhardwareids-exe-with-winedbg/
         Dim namespaceUUID As Guid = Guid.Parse("70ffd812-4c7f-4c7d-0000-000000000000")
    
         ' Win32_ComputerSystem fields
         Dim manufacturer, family, productName, skuNumber As String
    
         ' Win32_BaseBoard fields
         Dim baseBoardManufacturer, baseBoardProduct As String
    
         ' Win32_BIOS fields
         Dim biosVendor, biosVersion, biosMajorRelease, biosMinorRelease As String
    
         ' Retrieve computer info.
         Using mos As New Management.ManagementObjectSearcher()
    
             ' Win32_ComputerSystem
             mos.Query.QueryString = "select Manufacturer,Model,SystemFamily,SystemSKUNumber from Win32_ComputerSystem"
             Using systemInfo As Management.ManagementObject = mos.Get(0)
                 manufacturer = CStr(systemInfo.Properties("Manufacturer").Value).Trim()
                 productName = CStr(systemInfo.Properties("Model").Value).Trim()
                 family = CStr(systemInfo.Properties("SystemFamily").Value).Trim()
                 skuNumber = CStr(systemInfo.Properties("SystemSKUNumber").Value).Trim()
             End Using
    
             ' Win32_BaseBoard
             mos.Query.QueryString = "select Manufacturer,Product from Win32_BaseBoard"
             Using baseBoardInfo As Management.ManagementObject = mos.Get(0)
                 baseBoardManufacturer = CStr(baseBoardInfo.Properties("Manufacturer").Value).Trim()
                 baseBoardProduct = CStr(baseBoardInfo.Properties("Product").Value).Trim()
             End Using
    
             ' Win32_BIOS
             mos.Query.QueryString = "select Manufacturer,SMBIOSBIOSVersion,SystemBiosMajorVersion,SystemBiosMinorVersion from Win32_BIOS"
             Using biosInfo As Management.ManagementObject = mos.Get(0)
                 biosVendor = CStr(biosInfo.Properties("Manufacturer").Value).Trim()
                 biosVersion = CStr(biosInfo.Properties("SMBIOSBIOSVersion").Value).Trim()
                 biosMajorRelease = CStr(biosInfo.Properties("SystemBiosMajorVersion").Value).Trim()
                 biosMinorRelease = CStr(biosInfo.Properties("SystemBiosMinorVersion").Value).Trim()
             End Using
    
         End Using
    
     #If DEBUG Then
         ' Console.WriteLine($"{NameOf(manufacturer)}          = {manufacturer}")
         ' Console.WriteLine($"{NameOf(productName)}           = {productName}")
         ' Console.WriteLine($"{NameOf(family)}                = {family}")
         ' Console.WriteLine($"{NameOf(skuNumber)}             = {skuNumber}")
         ' Console.WriteLine($"{NameOf(baseBoardManufacturer)} = {baseBoardManufacturer}")
         ' Console.WriteLine($"{NameOf(baseBoardProduct)}      = {baseBoardProduct}")
         ' Console.WriteLine($"{NameOf(biosVendor)}            = {biosVendor}")
         ' Console.WriteLine($"{NameOf(biosVersion)}           = {biosVersion}")
         ' Console.WriteLine($"{NameOf(biosMajorRelease)}      = {biosMajorRelease}")
         ' Console.WriteLine($"{NameOf(biosMinorRelease)}      = {biosMinorRelease}")
     #End If
    
         Dim stringToHash As String = String.Empty
    
         Select Case hwidType
    
             Case ComputerHardwareIdMicrosoftType.HardwareID_0
                 stringToHash = $"{manufacturer}&{family}&{productName}&{skuNumber}&{biosVendor}&{biosVersion}&{biosMajorRelease}&{biosMinorRelease}"
    
             Case ComputerHardwareIdMicrosoftType.HardwareID_1
                 stringToHash = $"{manufacturer}&{family}&{productName}&{biosVendor}&{biosVersion}&{biosMajorRelease}&{biosMinorRelease}"
    
             Case ComputerHardwareIdMicrosoftType.HardwareID_2
                 stringToHash = $"{manufacturer}&{productName}&{biosVendor}&{biosVersion}&{biosMajorRelease}&{biosMinorRelease}"
    
             Case ComputerHardwareIdMicrosoftType.HardwareID_3
                 stringToHash = $"{manufacturer}&{family}&{productName}&{skuNumber}&{baseBoardManufacturer}&{baseBoardProduct}"
    
             Case ComputerHardwareIdMicrosoftType.HardwareID_4
                 stringToHash = $"{manufacturer}&{family}&{productName}&{skuNumber}"
    
             Case ComputerHardwareIdMicrosoftType.HardwareID_5
                 stringToHash = $"{manufacturer}&{family}&{productName}"
    
             Case ComputerHardwareIdMicrosoftType.HardwareID_6
                 stringToHash = $"{manufacturer}&{skuNumber}&{baseBoardManufacturer}&{baseBoardProduct}"
    
             Case ComputerHardwareIdMicrosoftType.HardwareID_7
                 stringToHash = $"{manufacturer}&{skuNumber}"
    
             Case ComputerHardwareIdMicrosoftType.HardwareID_8
                 stringToHash = $"{manufacturer}&{productName}&{baseBoardManufacturer}&{baseBoardProduct}"
    
             Case ComputerHardwareIdMicrosoftType.HardwareID_9
                 stringToHash = $"{manufacturer}&{productName}"
    
             Case ComputerHardwareIdMicrosoftType.HardwareID_10
                 stringToHash = $"{manufacturer}&{family}&{baseBoardManufacturer}&{baseBoardProduct}"
    
             Case ComputerHardwareIdMicrosoftType.HardwareID_11
                 stringToHash = $"{manufacturer}&{family}"
    
             Case ComputerHardwareIdMicrosoftType.HardwareID_13
                 stringToHash = $"{manufacturer}&{baseBoardManufacturer}&{baseBoardProduct}"
    
             Case ComputerHardwareIdMicrosoftType.HardwareID_14
                 stringToHash = manufacturer
    
         End Select
    
         ' Creates a name-based UUID using the algorithm from RFC 4122 §4.3.
         ' https://stackoverflow.com/questions/61267254/generating-uuid-based-on-strings
         Dim generateGuidDelegate As Func(Of Guid, String, Guid) =
             Function(namespaceId As Guid, name As String) As Guid
    
                 ' Converts a GUID (expressed as a byte array) to/from network order (MSB-first).
                 Dim swapByteOrderDelegate As New Action(Of Byte())(
                     Sub(ByVal guid() As Byte)
                         Dim temp As Byte = guid(0)
                         guid(0) = guid(3)
                         guid(3) = temp
    
                         temp = guid(1)
                         guid(1) = guid(2)
                         guid(2) = temp
    
                         temp = guid(4)
                         guid(4) = guid(5)
                         guid(5) = temp
    
                         temp = guid(6)
                         guid(6) = guid(7)
                         guid(7) = temp
                     End Sub)
    
                 ' Convert the name to a sequence of octets (as defined by the standard or conventions of its namespace) (step 3).
                 Dim nameBytes() As Byte = Encoding.Unicode.GetBytes(name)
    
                 ' Convert the namespace UUID to network order (step 3).
                 Dim namespaceBytes() As Byte = namespaceId.ToByteArray()
                 swapByteOrderDelegate.Invoke(namespaceBytes)
    
                 ' Compute the hash of the name space ID concatenated with the name (step 4).
                 Dim hash As Byte()
                 Using algorithm As HashAlgorithm = SHA1.Create()
                     algorithm.TransformBlock(namespaceBytes, 0, namespaceBytes.Length, Nothing, 0)
                     algorithm.TransformFinalBlock(nameBytes, 0, nameBytes.Length)
                     hash = algorithm.Hash
                 End Using
    
                 ' Most bytes from the hash are copied straight to the bytes of the new GUID (steps 5-7, 9, 11-12).
                 Dim newGuid(15) As Byte
                 Array.Copy(hash, 0, newGuid, 0, 16)
    
                 ' Set the four most significant bits (bits 12 through 15) of the time_hi_and_version field
                 ' to the appropriate 4-bit version number from Section 4.1.3 (step 8).
                 newGuid(6) = CByte((newGuid(6) And &HF) Or (5 << 4))
    
                 ' Set the two most significant bits (bits 6 and 7) of the clock_seq_hi_and_reserved
                 ' to zero and one, respectively (step 10).
                 newGuid(8) = CByte((newGuid(8) And &H3F) Or &H80)
    
                 ' Convert the resulting UUID to local byte order (step 13).
                 swapByteOrderDelegate.Invoke(newGuid)
                 Return New Guid(newGuid)
             End Function
    
         Return generateGuidDelegate.Invoke(namespaceUUID, stringToHash)
    
     End Function
    
  3. Пример использования:

     'Console.WriteLine($"{{{GetComputerHardwareIdFromMicrosoftHwIdType(0)}}}    <- Manufacturer + Family + ProductName + SKUNumber + BIOS Vendor + BIOS Version + BIOS Major Release + BIOS Minor Release")
     'Console.WriteLine($"{{{GetComputerHardwareIdFromMicrosoftHwIdType(1)}}}    <- Manufacturer + Family + ProductName + BIOS Vendor + BIOS Version + BIOS Major Release + BIOS Minor Release")
     'Console.WriteLine($"{{{GetComputerHardwareIdFromMicrosoftHwIdType(2)}}}    <- Manufacturer + ProductName + BIOS Vendor + BIOS Version + BIOS Major Release + BIOS Minor Release")
     Console.WriteLine($"{{{GetComputerHardwareIdFromMicrosoftHwIdType(3)}}}    <- Manufacturer + Family + ProductName + SKUNumber + Baseboard Manufacturer + Baseboard Product")
     Console.WriteLine($"{{{GetComputerHardwareIdFromMicrosoftHwIdType(4)}}}    <- Manufacturer + Family + ProductName + SKUNumber")
     Console.WriteLine($"{{{GetComputerHardwareIdFromMicrosoftHwIdType(5)}}}    <- Manufacturer + Family + ProductName")
     Console.WriteLine($"{{{GetComputerHardwareIdFromMicrosoftHwIdType(6)}}}    <- Manufacturer + SKUNumber + Baseboard Manufacturer + Baseboard Product")
     Console.WriteLine($"{{{GetComputerHardwareIdFromMicrosoftHwIdType(7)}}}    <- Manufacturer + SKUNumber")
     Console.WriteLine($"{{{GetComputerHardwareIdFromMicrosoftHwIdType(8)}}}    <- Manufacturer + ProductName + Baseboard Manufacturer + Baseboard Product")
     Console.WriteLine($"{{{GetComputerHardwareIdFromMicrosoftHwIdType(9)}}}    <- Manufacturer + ProductName")
     Console.WriteLine($"{{{GetComputerHardwareIdFromMicrosoftHwIdType(10)}}}    <- Manufacturer + Family + Baseboard Manufacturer + Baseboard Product")
     Console.WriteLine($"{{{GetComputerHardwareIdFromMicrosoftHwIdType(11)}}}    <- Manufacturer + Family")
     Console.WriteLine($"{{{GetComputerHardwareIdFromMicrosoftHwIdType(13)}}}    <- Manufacturer + Baseboard Manufacturer + Baseboard Product")
     Console.WriteLine($"{{{GetComputerHardwareIdFromMicrosoftHwIdType(14)}}}    <- Manufacturer")
    
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
44
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Путем проб и ошибок, пробуя возможные форматы, я обнаружил, что числовые значения (типа byte) должны быть преобразованы в шестнадцатеричные числа и они должны быть в нижнем регистре.

Итак, единственные изменения, которые мне нужно внести в исходный код, который я опубликовал в основном посте, и для репликации Hardware-Id 0, 1, 2, это:

biosMajorRelease = CByte(biosInfo.Properties("SystemBiosMajorVersion").Value).ToString("X2").ToLower()
biosMinorRelease = CByte(biosInfo.Properties("SystemBiosMinorVersion").Value).ToString("X2").ToLower()

Это и, конечно же, удалить строку Нереализованное исключение.

Теперь код работает, чтобы получить все идентификаторы оборудования, кроме HardwareId-12, потому что я не знаю, в каком классе WMI найти значение типа корпуса, которое, кстати, тоже является байтовым типом.

Но на самом деле это не имеет значения. У меня есть 13 работающих CHIDS из 14, и я считаю, что это очень хорошая оценка, чтобы наконец сказать, что это полное управляемое решение для воспроизведения того, что делает computerhardwareids.exe, хотя я не тестировал его на своем ПК.

Другие вопросы по теме