Что нового

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

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 711
Функция генерит уникальный идентификатор компьютера (по железу) с учетом заданных параметров ($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 319
Re: _UniqueHardwaeID() - Получение

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

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 711
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 711
Re: _UniqueHardwaeID() - Генерация уникального ID компьютера

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

madmasles

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

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

Yashied

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

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

madmasles

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

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

Yashied

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

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



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

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

Yashied

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

_WinAPI_UniqueHardwareID()
 

svigelf

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

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

Luke

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

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

Belfigor

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

Luke

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

Belfigor

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

Luke

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

Bloodrinker

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

Garrett

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