Что нового

_UniqueHardwaeIDv1() - Генерация уникального ID компьютера

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Функция генерит уникальный идентификатор компьютера (по железу) с учетом заданных параметров ($UHID_... флаги).

$UHID_MB (0x00)
При генерации ID используется информация о материнской плате. Этот флаг используется по умолчанию независимо от того, задан он или нет.

$UHID_BIOS (0x01)
При генерации ID используется информация из BIOS.

$UHID_CPU (0x02)
При генерации ID используется информация о процессоре(ах). Заметно снижает скорость выполнения функции.

$UHID_HDD (0x04)
При генерации ID используется информация об установленных жестких дисках. Любое изменение в конфигурации дисков приведет к изменению ID, возвращаемого этой функцией. Учитываются только несъемные диски с интерфейсами ATA или SATA.

Самый оптимальный вариант - $UHID_MB + $UHID_BIOS.

Последовательность опроса:

Motherboard (IdentifyingNumber + Name + SKUNumber + UUID + Vendor + Version)
+
BIOS (IdentificationCode + Manufacturer + Name + SerialNumber + SMBIOSMajorVersion + SMBIOSMinorVersion)
+
Processors (CPU1 (Architecture + Family + Level + Manufacturer + Name + ProcessorId + Revision + Version) + CPU2 (...) + ...)
+
HDDs (HDD1 (SerialNumber) + HDD2 (...) + ...)

Код:
#Include  <Crypt.au3>
#Include  <WinAPI.au3>

Global Const $UHID_MB = 0x00
Global Const $UHID_BIOS = 0x01
Global Const $UHID_CPU = 0x02
Global Const $UHID_HDD = 0x04

ConsoleWrite(_UniqueHardwaeIDv1() & @CR)
ConsoleWrite(_UniqueHardwaeIDv1(BitOR($UHID_MB, $UHID_BIOS)) & @CR)
;ConsoleWrite(_UniqueHardwaeIDv1(BitOR($UHID_MB, $UHID_BIOS, $UHID_CPU)) & @CR)
;ConsoleWrite(_UniqueHardwaeIDv1(BitOR($UHID_MB, $UHID_BIOS, $UHID_CPU, $UHID_HDD)) & @CR)

Func _UniqueHardwaeIDv1($iFlags = 0)

	Local $oService = ObjGet('winmgmts:\\.\root\cimv2')

	If Not IsObj($oService) Then
		Return SetError(1, 0, '')
	EndIf

	Local $tSPQ, $tSDD, $oItems, $hFile, $Hash, $Ret, $Str, $Hw = '', $Result = 0

	$oItems = $oService.ExecQuery('SELECT * FROM Win32_ComputerSystemProduct')
	If Not IsObj($oItems) Then
		Return SetError(2, 0, '')
	EndIf
	For $Property In $oItems
		$Hw &= $Property.IdentifyingNumber
		$Hw &= $Property.Name
		$Hw &= $Property.SKUNumber
		$Hw &= $Property.UUID
		$Hw &= $Property.Vendor
		$Hw &= $Property.Version
	Next
	$Hw = StringStripWS($Hw, 8)
	If Not $Hw Then
		Return SetError(3, 0, '')
	EndIf
	If BitAND($iFlags, 0x01) Then
		$oItems = $oService.ExecQuery('SELECT * FROM Win32_BIOS')
		If Not IsObj($oItems) Then
			Return SetError(2, 0, '')
		EndIf
		$Str = ''
		For $Property In $oItems
			$Str &= $Property.IdentificationCode
			$Str &= $Property.Manufacturer
			$Str &= $Property.Name
			$Str &= $Property.SerialNumber
			$Str &= $Property.SMBIOSMajorVersion
			$Str &= $Property.SMBIOSMinorVersion
;			$Str &= $Property.Version
		Next
		$Str = StringStripWS($Str, 8)
		If $Str Then
			$Result += 0x01
			$Hw &= $Str
		EndIf
	EndIf
	If BitAND($iFlags, 0x02) Then
		$oItems = $oService.ExecQuery('SELECT * FROM Win32_Processor')
		If Not IsObj($oItems) Then
			Return SetError(2, 0, '')
		EndIf
		$Str = ''
		For $Property In $oItems
			$Str &= $Property.Architecture
			$Str &= $Property.Family
			$Str &= $Property.Level
			$Str &= $Property.Manufacturer
			$Str &= $Property.Name
			$Str &= $Property.ProcessorId
			$Str &= $Property.Revision
			$Str &= $Property.Version
		Next
		$Str = StringStripWS($Str, 8)
		If $Str Then
			$Result += 0x02
			$Hw &= $Str
		EndIf
	EndIf
	If BitAND($iFlags, 0x04) Then
		$oItems = $oService.ExecQuery('SELECT * FROM Win32_PhysicalMedia')
		If Not IsObj($oItems) Then
			Return SetError(2, 0, '')
		EndIf
		$Str = ''
		$tSPQ = DllStructCreate('dword;dword;byte[4]')
		$tSDD = DllStructCreate('ulong;ulong;byte;byte;byte;byte;ulong;ulong;ulong;ulong;dword;ulong;byte[512]')
		For $Property In $oItems
			$hFile = _WinAPI_CreateFile($Property.Tag, 2, 0, 0)
			If Not $hFile Then
				ContinueLoop
			EndIf
			$Ret = DllCall('kernel32.dll', 'int', 'DeviceIoControl', 'ptr', $hFile, 'dword', 0x002D1400, 'ptr', DllStructGetPtr($tSPQ), 'dword', DllStructGetSize($tSPQ), 'ptr', DllStructGetPtr($tSDD), 'dword', DllStructGetSize($tSDD), 'dword*', 0, 'ptr', 0)
			If (Not @error) And ($Ret[0]) And (Not DllStructGetData($tSDD, 5)) Then
				Switch DllStructGetData($tSDD, 11)
					Case 0x03, 0x0B ; ATA, SATA
						$Str &= $Property.SerialNumber
				EndSwitch
			EndIf
			_WinAPI_CloseHandle($hFile)
		Next
		$Str = StringStripWS($Str, 8)
		If $Str Then
			$Result += 0x04
			$Hw &= $Str
		EndIf
	EndIf
	$Hash = _Crypt_HashData($Hw, $CALG_MD5)
	If @error Then
		Return SetError(4, 0, '')
	EndIf
	$Hash = StringTrimLeft($Hash, 2)
	Return SetError(0, $Result, '{' & StringMid($Hash, 1, 8) & '-' & StringMid($Hash, 9, 4) & '-' & StringMid($Hash, 13, 4) & '-' & StringMid($Hash, 17, 4) & '-' & StringMid($Hash, 21, 12) & '}')
EndFunc   ;==>_UniqueHardwaeIDv1
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Re: _UniqueHardwaeID() - Получение

Yashied
У меня на одном компьютере стоят 2 Win XP. Оба варианта функций показывают одинаковые значения. А на другом стоят Win XP и Win 7. Здесь функция _UniqueHardwaeID() выдает одинаковые варианты, а _UniqueHardwaeID(BitOR($UHID_MB, $UHID_BIOS)) - разные.
Классная функция получилась. Спасибо!
 
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Re: _UniqueHardwaeID() - Получение

madmasles сказал(а):
У меня на одном компьютере стоят 2 Win XP. Оба варианта функций показывают одинаковые значения. А на другом стоят Win XP и Win 7. Здесь функция _UniqueHardwaeID() выдает одинаковые варианты, а _UniqueHardwaeID(BitOR($UHID_MB, $UHID_BIOS)) - разные.
Классная функция получилась. Спасибо!

Покажи мне пожалуйста результаты сдедующего примера из XP и 7.

Код:
#Include  <Crypt.au3>
#Include  <WinAPI.au3>

Global Const $UHID_MB = 0x00
Global Const $UHID_BIOS = 0x01
Global Const $UHID_CPU = 0x02
Global Const $UHID_HDD = 0x04

;ConsoleWrite(_UniqueHardwaeID() & @CR)
ConsoleWrite(_UniqueHardwaeID(BitOR($UHID_MB, $UHID_BIOS)) & @CR)
;ConsoleWrite(_UniqueHardwaeID(BitOR($UHID_MB, $UHID_BIOS, $UHID_CPU)) & @CR)
;ConsoleWrite(_UniqueHardwaeID(BitOR($UHID_MB, $UHID_BIOS, $UHID_CPU, $UHID_HDD)) & @CR)

Func _UniqueHardwaeID($iFlags = 0)

	Local $oService = ObjGet('winmgmts:\\.\root\cimv2')

	If Not IsObj($oService) Then
		Return SetError(1, 0, '')
	EndIf

	Local $tSPQ, $tSDD, $oItems, $hFile, $Hash, $Ret, $Str, $Hw = '', $Result = 0

	$oItems = $oService.ExecQuery('SELECT * FROM Win32_ComputerSystemProduct')
	If Not IsObj($oItems) Then
		Return SetError(2, 0, '')
	EndIf
	For $Property In $oItems
ConsoleWrite($Property.IdentifyingNumber & @CR)
ConsoleWrite($Property.Name & @CR)
ConsoleWrite($Property.SKUNumber & @CR)
ConsoleWrite($Property.UUID & @CR)
ConsoleWrite($Property.Vendor & @CR)
ConsoleWrite($Property.Version & @CR)
ConsoleWrite('--------------------' & @CR)
		$Hw &= $Property.IdentifyingNumber
		$Hw &= $Property.Name
		$Hw &= $Property.SKUNumber
		$Hw &= $Property.UUID
		$Hw &= $Property.Vendor
		$Hw &= $Property.Version
	Next
	$Hw = StringStripWS($Hw, 8)
	If Not $Hw Then
		Return SetError(3, 0, '')
	EndIf
	If BitAND($iFlags, 0x01) Then
		$oItems = $oService.ExecQuery('SELECT * FROM Win32_BIOS')
		If Not IsObj($oItems) Then
			Return SetError(2, 0, '')
		EndIf
		$Str = ''
		For $Property In $oItems
ConsoleWrite($Property.IdentificationCode & @CR)
ConsoleWrite($Property.Manufacturer & @CR)
ConsoleWrite($Property.Name & @CR)
ConsoleWrite($Property.SerialNumber & @CR)
ConsoleWrite($Property.SMBIOSMajorVersion & @CR)
ConsoleWrite($Property.SMBIOSMinorVersion & @CR)
ConsoleWrite($Property.Version & @CR)
ConsoleWrite('--------------------' & @CR)
			$Str &= $Property.IdentificationCode
			$Str &= $Property.Manufacturer
			$Str &= $Property.Name
			$Str &= $Property.SerialNumber
			$Str &= $Property.SMBIOSMajorVersion
			$Str &= $Property.SMBIOSMinorVersion
			$Str &= $Property.Version
		Next
		$Str = StringStripWS($Str, 8)
		If $Str Then
			$Result += 0x01
			$Hw &= $Str
		EndIf
	EndIf
	If BitAND($iFlags, 0x02) Then
		$oItems = $oService.ExecQuery('SELECT * FROM Win32_Processor')
		If Not IsObj($oItems) Then
			Return SetError(2, 0, '')
		EndIf
		$Str = ''
		For $Property In $oItems
			$Str &= $Property.Architecture
			$Str &= $Property.Family
			$Str &= $Property.Level
			$Str &= $Property.Manufacturer
			$Str &= $Property.Name
			$Str &= $Property.ProcessorId
			$Str &= $Property.Revision
			$Str &= $Property.Version
		Next
		$Str = StringStripWS($Str, 8)
		If $Str Then
			$Result += 0x02
			$Hw &= $Str
		EndIf
	EndIf
	If BitAND($iFlags, 0x04) Then
		$oItems = $oService.ExecQuery('SELECT * FROM Win32_PhysicalMedia')
		If Not IsObj($oItems) Then
			Return SetError(2, 0, '')
		EndIf
		$Str = ''
		$tSPQ = DllStructCreate('dword;dword;byte[4]')
		$tSDD = DllStructCreate('ulong;ulong;byte;byte;byte;byte;ulong;ulong;ulong;ulong;dword;ulong;byte[512]')
		For $Property In $oItems
			$hFile = _WinAPI_CreateFile($Property.Tag, 2, 0, 0)
			If Not $hFile Then
				ContinueLoop
			EndIf
			$Ret = DllCall('kernel32.dll', 'int', 'DeviceIoControl', 'ptr', $hFile, 'dword', 0x002D1400, 'ptr', DllStructGetPtr($tSPQ), 'dword', DllStructGetSize($tSPQ), 'ptr', DllStructGetPtr($tSDD), 'dword', DllStructGetSize($tSDD), 'dword*', 0, 'ptr', 0)
			If (Not @error) And ($Ret[0]) And (Not DllStructGetData($tSDD, 5)) Then
				Switch DllStructGetData($tSDD, 11)
					Case 0x03, 0x0B ; ATA, SATA
						$Str &= $Property.SerialNumber
				EndSwitch
			EndIf
			_WinAPI_CloseHandle($hFile)
		Next
		$Str = StringStripWS($Str, 8)
		If $Str Then
			$Result += 0x04
			$Hw &= $Str
		EndIf
	EndIf
	$Hash = _Crypt_HashData($Hw, $CALG_MD5)
	If @error Then
		Return SetError(4, 0, '')
	EndIf
	$Hash = StringTrimLeft($Hash, 2)
	Return SetError(0, $Result, '{' & StringMid($Hash, 1, 8) & '-' & StringMid($Hash, 9, 4) & '-' & StringMid($Hash, 13, 4) & '-' & StringMid($Hash, 17, 4) & '-' & StringMid($Hash, 21, 12) & '}')
EndFunc   ;==>_UniqueHardwaeID

Добавлено:

Хотя ладно, сам разобрался, см. првый пост.
 

Yuri

AutoIT Гуру
Сообщения
737
Репутация
282
Re: _UniqueHardwaeID() - Генерация уникального ID компьютера

Спасибо. Все работает. Пригодится.
Win XP Pro SP3 чистая (не сборка)
{7FE593D4-5873-4130-49EC-C5C9881319B7}
{06390B63-D3EA-B156-8B85-88CA504DF37B}
>Exit code: 0 Time: 0.516

{7FE593D4-5873-4130-49EC-C5C9881319B7}
{06390B63-D3EA-B156-8B85-88CA504DF37B}
{F47AC66D-7851-F9CD-EBF1-BD329E7F5963}
{C0AF95F0-B58C-611D-32B3-78A145B76813}
>Exit code: 0 Time: 2.556
 
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Re: _UniqueHardwaeID() - Генерация уникального ID компьютера

Смысл в том, что на одном и томже компьютере ID должен быть одинаковый, независимо от того, какая OS установлена. Сейчас у меня генерятся ID одинаковые на XP и 7.
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Re: _UniqueHardwaeID() - Генерация уникального ID компьютера

Yashied [?]
результаты сдедующего примера из XP и 7.
У меня различается только $Property.Version
WIN_7 & X86 SECCSD - 20080714
WIN_XP & X86 K-Syst - 20080714
 
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Re: _UniqueHardwaeID() - Генерация уникального ID компьютера

$Property.Version для "SELECT * FROM Win32_BIOS" ?
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Re: _UniqueHardwaeID() - Генерация уникального ID компьютера

Yashied
Извините, сразу не написал. Да, для SELECT * FROM Win32_BIOS.
 
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Re: _UniqueHardwaeID() - Генерация уникального ID компьютера

ОК. Я ее уже убрал из кода. Спасибо.



Добавлено:
Сообщение автоматически объединено:

Переименовал функцию в _UniqueHardwaeIDv1(). Почему? Потому, что любое изменение в этой функции связанное со сбором информации приведет к изменению результирующего ID. В этом случае функция должна уже именоваться как _UniqueHardwaeIDv2() и т.д. (для совместимости).
 
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Я включил эту функцию в WinAPIEx.au3.

_WinAPI_UniqueHardwareID()
 

svigelf

Знающий
Сообщения
61
Репутация
17
есть вопрос? можно ли какимто образом сменить ID перечисленных устройств? (если можно, то сложно ли ето)

при обновлении Bios - ID меняется?
 

Luke

Знающий
Сообщения
64
Репутация
14
Возникли такие вопросы:
1 На разных виртуальных машинах VMware на одном физическом компе возвращаемый ID будет одинаковый ?
2 На скопированной вирт машине VMware запущеной на другом физическом компе ID будет другой ?
Вообщем можно ли привязать софт к вирт. машине, кто нибудь проверял? (у меня нет такой возможности)

Просьба добавить в параметры UniqueHardwaeID() MAC адрес сетевой карты.
 

Belfigor

Модератор
Локальный модератор
Сообщения
3,608
Репутация
941
Люк, решил таки свой софт продавать?
51.gif
 

Luke

Знающий
Сообщения
64
Репутация
14
Пока пытаюсь придумать какую нибудь защиту :-\.
OffTopic:
Mожет подскажешь криптор-пакер шифрующий оверлей exe-ка?
 

Belfigor

Модератор
Локальный модератор
Сообщения
3,608
Репутация
941
Luke сказал(а):
Пока пытаюсь придумать какую нибудь защиту :-\.
OffTopic:
Mожет подскажешь криптор-пакер шифрующий оверлей exe-ка?
Лучшая защита - перенос части действий с клиента на сервер. То есть ты распространяешь программу клиент которая лишь шлет серверу полученные данные, а сервер уже говорит программе что делать.
 

Luke

Знающий
Сообщения
64
Репутация
14
Вариант хороший, но требует сервера 24/7 онлайн. Кроме того всё равно нужна надёжная идентификация клиента (логин-пароль могут выложить в паблик, подсмотреть и т.п.). Тот же клиент EVE пересылает кучу инфы о железе на сервер.
 

Bloodrinker

<Блуждающий...>
Сообщения
228
Репутация
19
да какие пароли? можно и без них сделать опираясь на серийник и прогу- клиент, привязанную к компу, соотв-но.
клиент пройдется по железу или еще там по чему, вышлет данные на сервер например, вы сгенерите серийник и выдадите ему, а клиент в это время сам сгенерит такой-же серийник, сверит его с полученным с сервера и начнет работу с сервером.
ну как-то так..... почти... я правда знаю как это можно обойти, но сложновато....
привязка к железу самый оптимальный вариант для средненькой проги, правда я и это знаю как обойти можно, но для начала надо будет узнать, что она к железу привязывается)))))))) а ни к чему другому)
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
Bloodrinker [?]
вышлет данные на сервер например, вы сгенерите серийник и выдадите ему, а клиент в это время сам сгенерит такой-же серийник
Зачем в таком случае, высылать куда-то данные? ;)
 
Верх