Что нового

Привязка скрипта к одному компьютеру (железу)

Yashied

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

Шаг 1

Вставляем в свой скрипт следующий код и компилируем его с именем MyProg.exe.

Код:
#Include <WinAPIEx.au3>

If Not _ValidateScript() Then
	MsgBox(16, ':-(', 'The program has not been installed on this computer.')
	Exit
EndIf

MsgBox(0, ':-)', 'OK')

Func _ValidateScript()

	Local $sID = _WinAPI_UniqueHardwareID(BitOR($UHID_MB, $UHID_BIOS))

	If Not $sID Then
		Return 0
	EndIf

	Local $hFile = _WinAPI_CreateFile(@ScriptFullPath, 2, 2)

	If Not $hFile Then
		Return 0
	EndIf

	Local $tData = DllStructCreate($tagGUID), $pData = DllStructGetPtr($tData)
	Local $sData, $iByte, $Result = 0

	Do
		If Not _WinAPI_SetFilePointer($hFile, -16, 2) Then
			ExitLoop
		EndIf
		If (Not _WinAPI_ReadFile($hFile, $pData, 16, $iByte)) Or ($iByte <> 16) Then
			ExitLoop
		EndIf
		$sData = _WinAPI_StringFromGUID($pData)
		If (Not $sData) Or ($sData <> $sID) Then
			ExitLoop
		EndIf
		$Result = 1
	Until 1
	_WinAPI_CloseHandle($hFile)
	Return $Result
EndFunc   ;==>_ValidateScript

Если запустить этот скрипт, то он не пройдет проверку и завершит свою работу.

Шаг 2

Запустим следующий скрипт (теоретически это должен делать установщик вашей программы).

Код:
#Include <WinAPIEx.au3>

If Not _InjectUniqueID('MyProg.exe', _WinAPI_UniqueHardwareID(BitOR($UHID_MB, $UHID_BIOS))) Then
	Switch @error
		Case 2
			MsgBox(16, 'Error', 'MyProg.exe already patched.')
		Case Else
			MsgBox(16, 'Error', 'Unable to patch file.')
	EndSwitch
EndIf

Func _InjectUniqueID($sFile, $sID)

	Local $tData = _WinAPI_GUIDFromString($sID)

	If Not IsDllStruct($tData) Then
		Return 0
	EndIf

	Local $hFile = _WinAPI_CreateFile($sFile, 2, 6)

	If Not $hFile Then
		Return 0
	EndIf

	Local $tSign = DllStructCreate('dword'), $pSign = DllStructGetPtr($tSign)
	Local $iByte, $Error = 1

	Do
		If Not _WinAPI_SetFilePointer($hFile, -20, 2) Then
			ExitLoop
		EndIf
		If (Not _WinAPI_ReadFile($hFile, $pSign, 4, $iByte)) Or ($iByte <> 4) Then
			ExitLoop
		EndIf
		If DllStructGetData($tSign, 1) = 0x0144ADDA Then
			$Error = 2
			ExitLoop
		EndIf
		If Not _WinAPI_SetFilePointer($hFile, 0, 2) Then
			ExitLoop
		EndIf
		DllStructSetData($tSign, 1, 0x0144ADDA)
		If (Not _WinAPI_WriteFile($hFile, $pSign, 4, $iByte)) Or ($iByte <> 4) Then
			ExitLoop
		EndIf
		If (Not _WinAPI_WriteFile($hFile, DllStructGetPtr($tData), 16, $iByte)) Or ($iByte <> 16) Then
			ExitLoop
		EndIf
		$Error = 0
	Until 1
	_WinAPI_CloseHandle($hFile)
	Return SetError($Error, 0, Number($Error = 0))
EndFunc   ;==>_InjectUniqueID

Теперь ваша программа (MyProg.exe) успешно запустится и выведет сообщение "OK". И самое главное, файл MyProg.exe будет работать ТОЛЬКО на том компьютере, на котором мы вызвали функцию _InjectUniqueID().

:smile:
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Yashied
В Вашей замечательной UDF WinAPIEx.au3 версия 2.8 в функции _WinAPI_UniqueHardwareID() пропущена r (_WinAPI_UniqueHardwaeID)

Проверил на 2-х компьютерах - работает как надо. Патч еще можно, наверное, сделать самоудаляющимся.
Спасибо огромное! Отличный способ защиты.
 
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Я ее уже поправил немногим позже, как выложил v2.8. Нужно скачать еще раз.

:smile:
 
Автор
Yashied

Yashied

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

Согласен, не установщик, а именно патч.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Yashied
Хороший пример. По сути, это можно использовать скажем, для предотвращения распространения частей дистрибутива нашей программы без исходного установщика. Типа обязательство установки :smile:

P.S
WinAPIEx.au3 всё же не нативная библиотека, многие новички не поймут почему скрипт не работает. Лучше добавь на неё ссылку и упоминание о необходимости её подключать отдельно.
 
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
CreatoR

OK.



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

Опишу принцип защиты. Берется защищаемый .exe файл и дописывается в конец 4 байта (сигнатура) + 16 байт (GUID). Вот и все. Программе остается только открыть саму себя и прочитать с конца 16 байт данных. Затем сравнить эти данные с ID, полученным с помощью функции _WinAPI_UniqueHardwareID(). Если не совпадает, то...
 

Bloodrinker

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

PS: Понимаю, фантазия у меня удивительная и я хочу слишком многого, но как сказать... Мало ли... Вдруг, возможно это реализовать... Например будет полезно тем, кто пишет программки на AutoIt и продает, а вышесказанным можно предотвратить её дальшейшее нелегальное путешествие по сети интернет (хотя бы частично :smile:)
 
Автор
Yashied

Yashied

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

ЗАПУСКАТЬ ТОЛЬКО СКОМПИЛИРОВАННЫЙ (.EXE) ФАЙЛ!!!

Код:
#Include <File.au3>
#Include <WinAPIEx.au3>

$Dir = FileSelectFolder('Select folder to install MyProg.exe.', '', 0, @ScriptDir)
If Not $Dir Then
	Exit
EndIf

If FileInstall('MyProg.exe', $Dir & '\MyProg.exe', 1) Then
	_InjectUniqueID($Dir & '\MyProg.exe', _WinAPI_UniqueHardwareID(BitOR($UHID_MB, $UHID_BIOS)))
	_ScriptDestroy()
EndIf

Func _InjectUniqueID($sFile, $sID)

	Local $tData = _WinAPI_GUIDFromString($sID)

	If Not IsDllStruct($tData) Then
		Return 0
	EndIf

	Local $hFile = _WinAPI_CreateFile($sFile, 2, 6)

	If Not $hFile Then
		Return 0
	EndIf

	Local $tSign = DllStructCreate('dword'), $pSign = DllStructGetPtr($tSign)
	Local $iByte, $Error = 1

	Do
		If Not _WinAPI_SetFilePointer($hFile, -20, 2) Then
			ExitLoop
		EndIf
		If (Not _WinAPI_ReadFile($hFile, $pSign, 4, $iByte)) Or ($iByte <> 4) Then
			ExitLoop
		EndIf
		If DllStructGetData($tSign, 1) = 0x0144ADDA Then
			$Error = 2
			ExitLoop
		EndIf
		If Not _WinAPI_SetFilePointer($hFile, 0, 2) Then
			ExitLoop
		EndIf
		DllStructSetData($tSign, 1, 0x0144ADDA)
		If (Not _WinAPI_WriteFile($hFile, $pSign, 4, $iByte)) Or ($iByte <> 4) Then
			ExitLoop
		EndIf
		If (Not _WinAPI_WriteFile($hFile, DllStructGetPtr($tData), 16, $iByte)) Or ($iByte <> 16) Then
			ExitLoop
		EndIf
		$Error = 0
	Until 1
	_WinAPI_CloseHandle($hFile)
	Return SetError($Error, 0, Number($Error = 0))
EndFunc   ;==>_InjectUniqueID

#Include <File.au3>

Func _ScriptDestroy()
    $sTemp = _TempFile(@TempDir, '~', '.bat')
    $sPath = FileGetShortName(@ScriptFullPath)
    $hFile = FileOpen($sTemp, 2)
    FileWriteLine($hFile, '@echo off')
    FileWriteLine($hFile, ':loop')
    FileWriteLine($hFile, 'del ' & $sPath)
    FileWriteLine($hFile, 'if exist ' & $sPath & ' goto loop')
    FileWriteLine($hFile, 'del ' & $sTemp)
    FileClose($hFile)
    Run($sTemp, '', @SW_HIDE)
EndFunc   ;==>_ScriptDestroy
 

Bloodrinker

<Блуждающий...>
Сообщения
228
Репутация
19
Yashied сказал(а):
ЗАПУСКАТЬ ТОЛЬКО СКОМПИЛИРОВАННЫЙ (.EXE) ФАЙЛ!!!

А что страшного будет если запустить скрипт? o_O Я ничего такого страшного не нашел... ;D
Да, ты прав, можно сделать копию, и надо с этим как-то тоже справиться... но это отходит от темы...


скачал твой скрипт, откомпилил в папке с моей "myprog.exe", запустил твой скрипт, выбрал папку. exe-шник в конце удаляется, это хорошо, сейчас протестируюна другом ПК что получилось и отпишусь...



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

я точно все правильно сделал? почему он запускается на другом ПК? Я что-то неправильно сделал, это однозначно)
 
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Bloodrinker сказал(а):
...скачал твой скрипт, откомпилил в папке с моей "myprog.exe", запустил твой скрипт, выбрал папку. exe-шник в конце удаляется, это хорошо, сейчас протестируюна другом ПК что получилось и отпишусь...

я точно все правильно сделал? почему он запускается на другом ПК?

В твоей "myprog.exe" должна присутствовать проверка на соответствие ID, см. "Шаг 1" в первом посте.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Можно ещё компилировать скрипт на стороне клиента, и предварительно вшить в него (в скрипт :smile: ) привязку к системе (проверка на идентификатор железа).
 

Kalisnik

Эволюция
Сообщения
295
Репутация
63
Как вариант, бороться с копированием можно уже давно испытанным способом - через интернет-активацию. :smile: Установочный файл при запуске на ПК требует интернет-подключения. При его наличии, сканит ID оборудования и вместе со своим идентификационным номером программы отправляет эти ID на сервер, где копия регистрируется и делается привязка этой копии к высланным ID оборудования. После чего c сервера отсылается "Key" для установки программы. Таким образом копирование ни чего не даст, поскольку запустить зарегистрированный на сервере файл можно будет только с того компьютера, на который программа была установлена в первый раз. А в случае повреждения Windows и т.д., переустановить имеющуюся копию на ПК, чей ID храниться на сервере, будет делом пары-тройки минут. Мне это дело так представляется. :smile:
 

Bloodrinker

<Блуждающий...>
Сообщения
228
Репутация
19
Kalisnik сказал(а):
Как вариант, бороться с копированием можно уже давно испытанным способом - через интернет-активацию. :smile: Установочный файл при запуске на ПК требует интернет-подключения. При его наличии, сканит ID оборудования и вместе со своим идентификационным номером программы отправляет эти ID на сервер, где копия регистрируется и делается привязка этой копии к высланным ID оборудования. После чего c сервера отсылается "Key" для установки программы. Таким образом копирование ни чего не даст, поскольку запустить зарегистрированный на сервере файл можно будет только с того компьютера, на который программа была установлена в первый раз. А в случае повреждения Windows и т.д., переустановить имеющуюся копию на ПК, чей ID храниться на сервере, будет делом пары-тройки минут. Мне это дело так представляется. :smile:

это правильнее всего, но с AutoIt это будет довольно сложно организовать. А вот что делать на сервее я вообще без понятия, или есть готовые варианты?
 

Kalisnik

Эволюция
Сообщения
295
Репутация
63
Bloodrinker
Я тоже не знаю как это все организовать... :laugh: - я свои мысли описал неосторожно. Но одним AutoIt в этом случае явно не обойтись. Нужны знания языков веб-программирования, уметь работать с базами данных и т.д.... в общем со стороны не знающего выглядит довольно угрожающе (у меня это смотрится именно так :smile:) :wacko:

П\с: Хотя для этих целей думаю можно использовать и бесплатный хост - так что были бы только знания. :smile:
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
Kalisnik
Получается, что если нет интернета, то и программой пользоваться не получится?! :smile:
 
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Это глядишь, мы так скоро дойдем до активации программы через интернет или по телефону.

:smile:
 

Bloodrinker

<Блуждающий...>
Сообщения
228
Репутация
19
Garrett сказал(а):
Kalisnik
Получается, что если нет интернета, то и программой пользоваться не получится?! :smile:

при первом запуске-да, смотря как сделать, можно при каждом запуске обращаться к серверу, а множно только единожды.
 

Kalisnik

Эволюция
Сообщения
295
Репутация
63
Garrett сказал(а):
Kalisnik
Получается, что если нет интернета, то и программой пользоваться не получится?! :smile:
По данным Википедии, на 2010 год в России проживает 141,9 млн. человек. Из них около 50 млн. человек являются пользователями интернета по данным с сайта www.telecomru.ru. Минус точки общественного доступа, учебные заведения, организации и т.п., то остается примерно 40 млн. человек имеющих доступ к сети интернет. Почти треть всего населения России. :smile: На вскидку, количество домашних ПК без доступа к интернет, не превышает одной трети от всех ПК в России, а то и 1/4 (это не факт, это на вскидку). ;) А ведь можно выйти в интернет всего лишь подключив мобильный телефон к ПК. ))) А теперь представьте возможные потери (материальные или моральные) от "нелегального" использования Вашей программы, когда каждый второй, а то и первый, будет использовать ее без Вашего ведома... :shok:

Bloodrinker [?]
при первом запуске-да, смотря как сделать, можно при каждом запуске обращаться к серверу, а множно только единожды.
Лучше всего при установке (первом запуске) программы, в противном случае это будет жестоко :smile:


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

Yashied сказал(а):
Это глядишь, мы так скоро дойдем до активации программы через интернет или по телефону.

:smile:
Кстати... мысль! ;D
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
Kalisnik [?]
А теперь представьте возможные потери (материальные или моральные) от "нелегального" использования Вашей программы, когда каждый второй, а то и первый, будет использовать ее без Вашего ведома...
У вас на ПК лицензионный Windows?! ;D
А вы о масштабах думаете! Дай бог, если скажут спасибо!
Я полагаю, что когда у вас будет как минимум пользователей 3000, можно будет задуматься о коммерческой составляющей, поверьте.
Нет, конечно же, я не против защиты, было бы что защищать! :smile:
 
Верх