Что нового

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

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 711
Хочу предложить свой способ привязать программу к определенному компьютеру, т.е. программа будет работать только на этом компьютере. Для запуска нижеприведенных примеров необходима библиотека 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 319
Yashied
В Вашей замечательной UDF WinAPIEx.au3 версия 2.8 в функции _WinAPI_UniqueHardwareID() пропущена r (_WinAPI_UniqueHardwaeID)

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

Yashied

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

:smile:
 
Автор
Yashied

Yashied

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

CreatoR

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

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

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 711
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 711
Это не сложно, но хитрый юзер может оставить себе копию установщика.

ЗАПУСКАТЬ ТОЛЬКО СКОМПИЛИРОВАННЫЙ (.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 711
Bloodrinker сказал(а):
...скачал твой скрипт, откомпилил в папке с моей "myprog.exe", запустил твой скрипт, выбрал папку. exe-шник в конце удаляется, это хорошо, сейчас протестируюна другом ПК что получилось и отпишусь...

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

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 472
Репутация
2 401
Можно ещё компилировать скрипт на стороне клиента, и предварительно вшить в него (в скрипт :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
Репутация
964
Kalisnik
Получается, что если нет интернета, то и программой пользоваться не получится?! :smile:
 
Автор
Yashied

Yashied

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

: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
Репутация
964
Kalisnik [?]
А теперь представьте возможные потери (материальные или моральные) от "нелегального" использования Вашей программы, когда каждый второй, а то и первый, будет использовать ее без Вашего ведома...
У вас на ПК лицензионный Windows?! ;D
А вы о масштабах думаете! Дай бог, если скажут спасибо!
Я полагаю, что когда у вас будет как минимум пользователей 3000, можно будет задуматься о коммерческой составляющей, поверьте.
Нет, конечно же, я не против защиты, было бы что защищать! :smile:
 
Верх