Что нового

Защита исходного кода программы

Sergey2210

Осваивающий
Сообщения
263
Репутация
31
Версия AutoIt:3.

Собрал функцию для защиты кода программы,минус в том что исходный код скомпилированной программы нужно сохранить в файл,и если узнают про этот файл то ему можно поставить расширение EXE и программа вновь заработает,я понимаю что полностью защитить программу не возможно,но эта функция защитит от таких программ как Restorator,ResourceBuilder и так далее,вопрос в том как не создавать этот файл если это возможно,если нет то как при создании файла с исходным кодом дописать в него любую строку и чтоб при выполнении функции она не читала её а пропускала,это для того чтоб если поставят расширение EXE файлу с исходным кодом программы то при запуске вылетала системная ошибка с текстом приложение не является образом win32

Код:
$Result = _sCheckChange_Script('uninstall.lnk')
If @error Then
	Exit
EndIf	 

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

$Form = GUICreate("Form1", 400, 300)

GUISetState()

While 1
	$nMsg = GUIGetMsg()
	Switch $nMsg
		Case $GUI_EVENT_CLOSE
			Exit
	EndSwitch
WEnd

Func _sCheckChange_Script($__Temp_File)
	
    If Not FileExists($__Temp_File) Then
	    $__sOpen_Script = FileOpen(@ScriptName,0)
	    $__sConsider_Interiors = FileRead($__sOpen_Script)
	    $__sWrite_temp = FileWrite($__Temp_File,$__sConsider_Interiors)
	Else
	    If FileExists($__Temp_File) Then
			
		    $__sOpen_Temp = FileOpen($__Temp_File,0)
		    $__sConsider_Temp = FileRead($__sOpen_Temp)
			
		    $__sOpen_Script_Temp = FileOpen(@ScriptName,0)
	        $__sConsider_Interiors_Temp = FileRead($__sOpen_Script_Temp)
			
		    If $__sConsider_Interiors_Temp = $__sConsider_Temp Then
			    Sleep(0)
		    Else
				SetError(-1,0,0)
		    EndIf
	    EndIf	
	EndIf

EndFunc
 

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Тема "FAQ по использованию ресурсов в AutoIt" навела меня на очень интерестное размышление,после того как я попробывал сделать,решил обратится к вам,защитить как говорят ни когда не получится,но теперь у злоумышлеников будет много работы + их терпение,хотя может ошибаюсь,у меня получился вот такой скриптик.

Код:
Load(Module(0), 6032)

Func Module($sModule)
	Local $aresult = DllCall("kernel32.dll", "handle", "GetModuleHandleW", "wstr", $sModule)
	If @error Then Return SetError(@error, @extended, 0)
	Return $aresult[0]
EndFunc 
Func Load($hInstance, $hResource)
	Local $Ret = DllCall('kernel32.dll', 'ptr', 'LoadResource', 'ptr', $hInstance, 'ptr', $hResource)
	If (@error) Or (Not $Ret[0]) Then
		Return SetError(1, 0, 0)
	EndIf
	Return $Ret[0]
EndFunc


Сома программа добавлена в User-defined ресурс,вот сам пример программы:
Exam.exe

Есть ещё один способ,он не то чтобы защитит,но тем кто хочет достать изходник понадобится терпение,так выглядет скрипт после обработки и работает

Код:
#include <GUIConstantsEx.au3>

$hForm = Execute(BinaryToString("0x47554943726561746528224578616D706C65222C3330302C32303029"))
Execute(BinaryToString("0x47554953657453746174652829"))
Execute(BinaryToString("0x57696E5365745469746C65282468466F726D2C22222C2248656C6C6F2229")) ; Изменить заголовок окна

While 1
	$sMsg = Execute(BinaryToString("0x4755494765744D73672829"))
	Switch Execute(BinaryToString("0x24734D7367"))
		Case Execute(BinaryToString("0x244755495F4556454E545F434C4F5345"))
			Exit
	EndSwitch
WEnd


А вот функцию собрал,чтоб автоматически всё делала,проблема в том что некоторые стандартные функции автоита не хотят работать в таком виде,ни где не должно быть пробелов например GUICreate("Title",300,200),так же не работает та функция в которой в значениях используется & @CR; @LF; @CRLF,можно как нибудь по другому сделать чтобы всё работало,но при декомпиляции злоумышленник видел что-то подобное приведённое выше?
 

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Помогите составить правильный шаблон для перевода скрипта в вид приведёный выше,нужно чтобы если в строке имеется @CR @LF @CRLF то он пропускал эту строку,всё что нужно перевести находится в файле который записан так:

FileWrite
FileWriteLine
IniDelete
IniRead
IniWrite
IniWriteSection
GUICreate
GUICtrlCreateButton
GUIctrlCreateCombo
GUICtrlCreateDate

Вот функция на быструю руку,я сделал её через сравнивание строк

Код:
CoderScrypt("AutoIt v3 Script (4).au3",@ScriptDir & "\au3CodeIt.apf")


Func CoderScrypt($sAu3File,$sFuncNoCoder)
	
	Global $sResult
	Global $Au3TempCode

	$sAu3Open = FileOpen($sAu3File)
	$sNoCoder = FileOpen($sFuncNoCoder)
	$sReadNoCoder = FileRead($sNoCoder)
	$sName = StringTrimRight($sAu3File,4)
	
	While 1
	    $sAu3Read = FileReadLine($sAu3Open)
        If @error = -1 Then ExitLoop
		If StringRegExp (" ", $sAu3Read) = 0 Then
			$sSplit = StringSplit($sAu3Read," ")
			For $i = 1 To $sSplit[0] Step 1
				$FileSplit = StringSplit($sReadNoCoder,@CRLF,1)
				For $v = 1 To $FileSplit[0] Step 1
				    If StringInStr($sSplit[$i],$FileSplit[$v]) = 1 Then	
					    $Au3TempCode &= 'Execute(BinaryToString("' & StringToBinary($sSplit[$i]) & '"))' & " ;"
				    EndIf	
			    Next
			    If StringInStr($sSplit[$i],'') = 0 Then
					$Au3TempCode &= $sSplit[$i] & " "
			    EndIf		
			Next
		EndIf	
		$Au3TempCode &= @CRLF
    WEnd
	
	FileClose($sAu3Open)
	FileClose($sNoCoder)
	
	FileWrite($sName & "_Binofuscator.au3",$Au3TempCode)
	
	Return $sResult

EndFunc


Файл au3CodeIt.apf это и есть то откуда функция берёт строку для сравнения

Всё,я понял,всё хорошо работает,единственно например в кнопке её название должно стоять не "Открыть файл" а "Открытьфайл", просто функция выдёргивает каждое слово из строки с помощью StringSplit,так как слова разделены пробелами то в функция например MsgBox(0,"","Это пример") будет разделятся так MsgBox(0,"","Это и на ещё одно отдельное слово пример") как это обойти,вот пример рабочего скрипта:

Код:
#Include <GUIConstantsEx.au3> 
#Include <GUIMenu.au3> 
#Include <WindowsConstants.au3> 

$hForm = Execute(BinaryToString("0x47554943726561746528274D79475549272C3430302C34303029")) ;GUICreate('MyGUI',400,400) 
$Button = Execute(BinaryToString("0x4755494374726C437265617465427574746F6E28274F7074696F6E73272C32302C32302C3134302C343029")) ;GUICtrlCreateButton('Options',20,20,140,40) 
$Dummy = Execute(BinaryToString("0x4755494374726C43726561746544756D6D792829")) ;GUICtrlCreateDummy() 

Dim $Menu[4] 

$Menu[0] = Execute(BinaryToString("0x4755494374726C437265617465436F6E746578744D656E75282444756D6D7929")) ;GUICtrlCreateContextMenu($Dummy) 
$Menu[1] = Execute(BinaryToString("0x4755494374726C4372656174654D656E754974656D28274F7074696F6E31272C244D656E755B305D29")) ;GUICtrlCreateMenuItem('Option1',$Menu[0]) 
$Menu[2] = Execute(BinaryToString("0x4755494374726C4372656174654D656E754974656D28274F7074696F6E32272C244D656E755B305D29")) ;GUICtrlCreateMenuItem('Option2',$Menu[0]) 
$Menu[3] = Execute(BinaryToString("0x4755494374726C4372656174654D656E754974656D28274F7074696F6E33272C244D656E755B305D29")) ;GUICtrlCreateMenuItem('Option3',$Menu[0]) 
$Menu[0] = Execute(BinaryToString("0x4755494374726C47657448616E646C6528244D656E755B305D29")) ;GUICtrlGetHandle($Menu[0]) 

Execute(BinaryToString("0x47554953657453746174652829")) ;GUISetState() 

While 1 
    Switch Execute(BinaryToString("0x4755494765744D73672829")) ;GUIGetMsg() 
        Case $GUI_EVENT_CLOSE 
            ExitLoop 
        Case $Button 
            _GUICtrlMenu_TrackPopupMenu($Menu[0],$hForm) 
        Case $Menu[1] 
            Execute(BinaryToString("0x4D7367426F7828302C22222C224F7074696F6E312229")) ;MsgBox(0,"","Option1") 
        Case $Menu[2] 
            Execute(BinaryToString("0x4D7367426F7828302C22222C224F7074696F6E322229")) ;MsgBox(0,"","Option2") 
        Case $Menu[3] 
            Execute(BinaryToString("0x4D7367426F7828302C22222C224F7074696F6E332229")) ;MsgBox(0,"","Option3") 
    EndSwitch 
WEnd
 

iamOmg

Новичок
Сообщения
97
Репутация
2
Viktor1703
Не совсем понял что делает этот скрипт??
Код:
Load(Module(0), 6032)

Func Module($sModule)
    Local $aresult = DllCall("kernel32.dll", "handle", "GetModuleHandleW", "wstr", $sModule)
    If @error Then Return SetError(@error, @extended, 0)
    Return $aresult[0]
EndFunc 
Func Load($hInstance, $hResource)
    Local $Ret = DllCall('kernel32.dll', 'ptr', 'LoadResource', 'ptr', $hInstance, 'ptr', $hResource)
    If (@error) Or (Not $Ret[0]) Then
        Return SetError(1, 0, 0)
    EndIf
    Return $Ret[0]
EndFunc

И ещё, злоумышленнику не составит труда написать скрипт который все эти строки обратно переведет и подставит в нужное место))
 

Ganibal95

GreenBytes
Сообщения
877
Репутация
240
Viktor1703
От такой защиты производительность программы только потеряешь.
Smoke.gif
 

iamOmg

Новичок
Сообщения
97
Репутация
2
Ganibal95
Эту защиту можно быстро снять)) каждую строчку выполнить и вывести в текстовой файл и получиться чистый исходник))
 

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Мой ответ был Июнь 27, 2011, тогда я мало чего знал, смотрите хотя бы дату оставленного сообщения и делайте выводы, этот пример вообще использовать не нужно, это так сказать были мои давние размышления выраженные в этом сообщении.

И на счет защиты - я сам знаю что её нет и не будет, можно даже не получая исходник на руки, кардинально изменить работу программы достаточно просто знать ASM.
 

iamOmg

Новичок
Сообщения
97
Репутация
2
Интересно в будущем разработчики Autoit придумают что-нибудь по поводу защиты исходного кода, или мы так и будем изобретать сами....
 

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Я же написал что защиты нет и не будет, без разницы на чём вы пишите программу, хоть на Delphi хоть на C/C++ хоть на AutoIt, тот кому нужно достать информацию с вашего exe либо изменить его работу, либо просто напросто крякнуть (если ваш софт требует ключ), достаточно просто иметь под рукой нужный инструмент и знать ASM.
 
Верх