Obscufator

    • Offizieller Beitrag

    Ich muss SEuBo zustimmen. Eine absolute Sicherheit gibt es nicht und die wird man mit AutoIt auch nicht erreichen können.
    Man kann es den Skript-Kiddies nur schwerer machen (obfuscaten).

    Dafür habe ich meinen Random-Obfuscator mal noch etwas erweitert (jetzt auch mit Random-Funktionsnamen):

    Spoiler anzeigen
    [autoit]


    #include <Array.au3>
    #include <GUIConstantsEx.au3>
    #include <StaticConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Global $sTitle = 'Random-Obfuscator v2.0'
    Global $sObfuscator = StringRegExpReplace(@AutoItExe, '(.+\\).+', '$1') & 'SciTE\Obfuscator\Obfuscator.exe' ; Pfad zum Original-Obfuscator
    Global $hGui = GUICreate($sTitle & ' (C) by Oscar (http://www.autoit.de)', 640, 240)
    GUISetBKColor(0xAAAAAA)

    [/autoit] [autoit][/autoit] [autoit]

    GUICtrlCreateGroup('Source', 10, 10, 300, 110)
    GUICtrlSetFont(-1, 14, 400, 0, 'Arial')
    GUICtrlCreateLabel('Filename:', 20, 50, 70, 25)
    GUICtrlSetFont(-1, 9, 400, 0, 'Arial')
    $hSourceFilename = GUICtrlCreateLabel('', 90, 50, 200, 25)
    GUICtrlSetFont(-1, 9, 400, 0, 'Arial')
    GUICtrlCreateLabel('Lines:', 20, 70, 70, 25)
    GUICtrlSetFont(-1, 9, 400, 0, 'Arial')
    $hSourceLines = GUICtrlCreateLabel('0', 90, 70, 200, 25)
    GUICtrlSetFont(-1, 9, 400, 0, 'Arial')
    GUICtrlCreateLabel('Filesize:', 20, 90, 70, 25)
    GUICtrlSetFont(-1, 9, 400, 0, 'Arial')
    $hSourceFilesize = GUICtrlCreateLabel('0 Bytes', 90, 90, 200, 25)
    GUICtrlSetFont(-1, 9, 400, 0, 'Arial')
    GUICtrlCreateGroup('', -99, -99, 1, 1)

    [/autoit] [autoit][/autoit] [autoit]

    GUICtrlCreateGroup('Destination', 330, 10, 300, 110)
    GUICtrlSetFont(-1, 14, 400, 0, 'Arial')
    GUICtrlCreateLabel('Filename:', 340, 50, 70, 25)
    GUICtrlSetFont(-1, 9, 400, 0, 'Arial')
    $hDestFilename = GUICtrlCreateLabel('', 410, 50, 200, 25)
    GUICtrlSetFont(-1, 9, 400, 0, 'Arial')
    GUICtrlCreateLabel('Lines:', 340, 70, 70, 25)
    GUICtrlSetFont(-1, 9, 400, 0, 'Arial')
    $hDestLines = GUICtrlCreateLabel('0', 410, 70, 200, 25)
    GUICtrlSetFont(-1, 9, 400, 0, 'Arial')
    GUICtrlCreateLabel('Filesize:', 340, 90, 70, 25)
    GUICtrlSetFont(-1, 9, 400, 0, 'Arial')
    $hDestFilesize = GUICtrlCreateLabel('0 Bytes', 410, 90, 200, 25)
    GUICtrlSetFont(-1, 9, 400, 0, 'Arial')
    GUICtrlCreateGroup('', -99, -99, 1, 1)

    [/autoit] [autoit][/autoit] [autoit]

    $hProgressPercent = GUICtrlCreateLabel('0%', 295, 130, 60, 18, $SS_CENTER)
    GUICtrlSetFont(-1, 9, 400, 0, 'Arial')
    $hProgress = GUICtrlCreateProgress(10, 150, 620, 16)

    [/autoit] [autoit][/autoit] [autoit]

    $hStatusLine = GUICtrlCreateLabel(' Select Script . . .', -2, 222, 644, 18, $SS_SUNKEN)
    GUICtrlSetBKColor(-1, 0xdddddd)
    GUICtrlSetFont(-1, 9, 400, 0, 'Arial')
    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    $sScriptSource = FileOpenDialog('Select Script', @ScriptDir, 'AutoIt-Script (*.au3)', 3, '', $hGui)
    If @error Then _End()
    GUICtrlSetData($hSourceFilename, StringRegExpReplace($sScriptSource, '.+\\(.+)', '$1'))
    $sSource = FileRead($sScriptSource)
    GUICtrlSetData($hSourceFilesize, _StringAddThousandsSep(FileGetSize($sScriptSource), '.', ',') & ' Bytes')
    StringReplace($sSource, @CR, '')
    GUICtrlSetData($hSourceLines, @extended)

    [/autoit] [autoit][/autoit] [autoit]

    $sSource = StringReplace($sSource, '#AutoIt3Wrapper_Run_Obfuscator', '; #AutoIt3Wrapper_Run_Obfuscator')
    $sSource = StringReplace($sSource, '#Obfuscator_Parameters', '; #Obfuscator_Parameters')
    $sSource = StringRegExpReplace($sSource, '((\x22|\x27).*(\x22|\x27))|(;\V*)|(?s)((#cs|#comments-start).+?(#ce|#comments-end)\V*)', '$1')
    $sSource = StringRegExpReplace($sSource, '(\r\n)\s+', '$1')

    [/autoit] [autoit][/autoit] [autoit]

    GUICtrlSetData($hStatusLine, ' Create Dictionaries . . .')
    $oDictVars = ObjCreate('Scripting.Dictionary') ; Variablen-Ersetz-Wörterbuch anlegen
    If Not IsObj($oDictVars) Then _End('Cannot create 1st Scripting.Dictionary!')
    $oDictVars.CompareMode = 1 ; Textmode (Case-insensitive) einschalten

    [/autoit] [autoit][/autoit] [autoit]

    $oDictFuncs = ObjCreate('Scripting.Dictionary') ; Funktionen-Ersetz-Wörterbuch anlegen
    If Not IsObj($oDictFuncs) Then _End('Cannot create 2nd Scripting.Dictionary!')
    $oDictFuncs.CompareMode = 1 ; Textmode (Case-insensitive) einschalten

    [/autoit] [autoit][/autoit] [autoit]

    $oDictHelpV = ObjCreate('Scripting.Dictionary') ; Hilfs-Wörterbuch für Zufallsvariablen anlegen
    If Not IsObj($oDictHelpV) Then _End('Cannot create 3rd Scripting.Dictionary!')
    $oDictHelpV.CompareMode = 1 ; Textmode (Case-insensitive) einschalten

    [/autoit] [autoit][/autoit] [autoit]

    $oDictHelpF = ObjCreate('Scripting.Dictionary') ; Hilfs-Wörterbuch für Zufallsfunktionen anlegen
    If Not IsObj($oDictHelpF) Then _End('Cannot create 4th Scripting.Dictionary!')
    $oDictHelpF.CompareMode = 1 ; Textmode (Case-insensitive) einschalten

    [/autoit] [autoit][/autoit] [autoit]

    _Exception($sSource) ; Ausnahmen ins Wörterbuch eintragen

    [/autoit] [autoit][/autoit] [autoit]

    GUICtrlSetData($hStatusLine, ' Obfuscate Variables . . .')
    $sTmp = StringRegExpReplace($sSource, '(?:\x22|\x27)(.+?)(?:\x22|\x27)', '')
    $aVars = StringRegExp($sTmp, '(?i)\$\w+', 3)
    If IsArray($aVars) Then
    $aVars = _ArrayUnique($aVars)
    _ArraySort($aVars, 1)
    For $i = 1 To $aVars[0]
    If Not $oDictVars.Exists($aVars[$i]) Then $oDictVars.Add($aVars[$i], _RandomVar())
    $sSource = StringReplace($sSource, $aVars[$i], $oDictVars.Item($aVars[$i]))
    $iPercent = Int(50 / $aVars[0] * $i)
    GUICtrlSetData($hProgress, $iPercent)
    GUICtrlSetData($hProgressPercent, $iPercent & '%')
    Next
    EndIf
    GUICtrlSetData($hStatusLine, ' Obfuscate Funktions . . .')
    $aFuncs = StringRegExp($sTmp, '(?i)Func (\w+)', 3)
    If IsArray($aFuncs) Then
    $aFuncs = _ArrayUnique($aFuncs)
    _ArraySort($aFuncs, 1)
    For $i = 1 To $aFuncs[0]
    If Not $oDictFuncs.Exists($aFuncs[$i]) Then $oDictFuncs.Add($aFuncs[$i], _RandomFunc())
    $sSource = StringReplace($sSource, $aFuncs[$i], $oDictFuncs.Item($aFuncs[$i]))
    $iPercent = Int(50 / $aFuncs[0] * $i) + 50
    GUICtrlSetData($hProgress, $iPercent)
    GUICtrlSetData($hProgressPercent, $iPercent & '%')
    Next
    EndIf
    GUICtrlSetData($hProgress, 100)
    GUICtrlSetData($hProgressPercent, '100%')

    [/autoit] [autoit][/autoit] [autoit]

    StringReplace($sSource, @CR, '')
    GUICtrlSetData($hDestLines, @extended)

    [/autoit] [autoit][/autoit] [autoit]

    GUICtrlSetData($hStatusLine, ' Save random obfuscated Script . . .')
    $sDestFile = StringRegExpReplace($sScriptSource, '(.+)(\..+)', '$1_rnd$2')
    GUICtrlSetData($hDestFilename, StringRegExpReplace($sDestFile, '.+\\(.+)', '$1'))
    $hFile = FileOpen($sDestFile, 2)
    If $hFile <> -1 Then
    FileWrite($hFile, $sSource)
    FileClose($hFile)
    EndIf
    GUICtrlSetData($hDestFilesize, _StringAddThousandsSep(FileGetSize($sDestFile), '.', ',') & ' Bytes')

    [/autoit] [autoit][/autoit] [autoit]

    GUICtrlSetData($hStatusLine, ' Run Original-Obfuscator . . . Please wait!')
    RunWait('"' & $sObfuscator & '" "' & $sDestFile & '" /cs 1 /cn 1 /cf 1 /cv 1', @ScriptDir, @SW_HIDE) ; Kopie vom Original-Obfuscator bearbeiten lassen
    $sDestFile = StringRegExpReplace($sScriptSource, '(.+)(\..+)', '$1_rnd_obfuscated$2')
    GUICtrlSetData($hStatusLine, ' Ready.')

    [/autoit] [autoit][/autoit] [autoit]

    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

    [/autoit] [autoit][/autoit] [autoit]

    Func _End($msg = '')
    If $msg <> '' Then MsgBox(262144+16, 'Error', $msg)
    Exit
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _Exception($sScript)
    Local $aException
    $aException = StringRegExp($sScript, '(?i)IsDeclared\h*\((.*?)\)', 3) ; Die IsDeclared-Variablen in ein Array holen
    If IsArray($aException) Then
    For $i = 0 To UBound($aException)-1
    If StringLeft($aException[$i], 1) <> '$' Then $aException[$i] = Execute('"$" &' & $aException[$i])
    $oDictVars.Add($aException[$i], $aException[$i]) ; Die IsDeclared-Variablen mit ihrem richtigen Namen ins Wörterbuch eintragen (werden dann nicht umgewandelt)
    Next
    EndIf
    $aException = StringRegExp($sScript, '(?i)Assign\h*\((.*?),', 3) ; Die Assign-Variablen in ein Array holen
    If IsArray($aException) Then
    For $i = 0 To UBound($aException)-1
    If StringLeft($aException[$i], 1) <> '$' Then $aException[$i] = Execute('"$" &' & $aException[$i])
    $oDictVars.Add($aException[$i], $aException[$i]) ; Die Assign-Variablen mit ihrem richtigen Namen ins Wörterbuch eintragen (werden dann nicht umgewandelt)
    Next
    EndIf
    _GetIncludeConsts($oDictVars, StringRegExpReplace(@AutoItExe, '(.+\\).+', '$1') & 'Include')
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _RandomVar()
    Local $sVar
    Do
    $sVar = '$' & Chr(Random(65, 90, 1))
    For $i = 0 To 7
    $sVar &= Chr(Random(48, 57, 1))
    Next
    Until Not $oDictHelpV.Exists($sVar)
    $oDictHelpV.Add($sVar, $sVar)
    Return $sVar
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _RandomFunc()
    Local $sFunc
    Do
    $sFunc = Chr(Random(65, 90, 1))
    For $i = 0 To 8
    $sFunc &= Chr(Random(48, 57, 1))
    Next
    Until Not $oDictHelpF.Exists($sFunc)
    $oDictHelpF.Add($sFunc, $sFunc)
    Return $sFunc
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _GetIncludeConsts(ByRef $oDict, $sPath)
    Local $aIncludeFiles, $sFile, $aConstants
    $aIncludeFiles = _MyFileListToArray($sPath, '*.au3') ; alle Standard-Include-Dateinamen einlesen
    If Not IsArray($aIncludeFiles) Then _End('ERROR! Include-Files not found!')
    For $sInclude In $aIncludeFiles ; alle Include-Dateien durchgehen
    $sFile = FileRead($sPath & '\' & $sInclude) ; Include-Datei einlesen
    $aConstants = StringRegExp($sFile, '(?s)(?:Global|Global Const) (\$.+?)(?:\;|\,|\h)', 3) ; alle Konstanten aus der Include-Datei holen
    If IsArray($aConstants) Then ; wenn welche gefunden wurden, dann...
    For $sConstant In $aConstants ; der Reihe nach durchgehen
    If Not $oDict.Exists($sConstant) Then $oDict.Add($sConstant, $sConstant) ; wenn nicht im Dictionary vorhanden, diesem hinzufügen
    Next
    EndIf
    Next
    EndFunc ;==>_GetIncludeFuncsAndConsts

    [/autoit] [autoit][/autoit] [autoit]

    Func _MyFileListToArray($sPath, $sFilter)
    Local $sFileList = '', $hSearch, $sFile
    If StringRight($sPath, 1) <> '\' Then $sPath &= '\'
    $hSearch = FileFindFirstFile($sPath & $sFilter)
    If @error Then Return
    Do
    $sFile = FileFindNextFile($hSearch)
    If @extended Then ContinueLoop
    $sFileList &= $sFile & '|'
    Until @error
    FileClose($hSearch)
    If $sFileList = '' Then Return
    Return StringSplit(StringTrimRight($sFileList, 1), '|', 2)
    EndFunc ;==>_MyFileListToArray

    [/autoit] [autoit][/autoit] [autoit]

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _StringAddThousandsSep
    ; Description ...: Returns the original numbered string with the Thousands delimiter inserted.
    ; Syntax.........: _StringAddThousandsSep($sString[, $sThousands = -1[, $sDecimal = -1]])
    ; Parameters ....: $sString - The string to be converted.
    ; $sThousands - Optional: The Thousands delimiter
    ; $sDecimal - Optional: The decimal delimiter
    ; Return values .: Success - The string with Thousands delimiter added.
    ; Author ........: SmOke_N (orignal _StringAddComma
    ; Modified.......: Valik (complete re-write, new function name)
    ; Remarks .......:
    ; Related .......:
    ; Link ..........;
    ; Example .......; Yes
    ; ===============================================================================================================================
    Func _StringAddThousandsSep($sString, $sThousands = -1, $sDecimal = -1)
    Local $sResult = "" ; Force string
    Local $rKey = "HKCU\Control Panel\International"
    If $sDecimal = -1 Then $sDecimal = RegRead($rKey, "sDecimal")
    If $sThousands = -1 Then $sThousands = RegRead($rKey, "sThousand")
    Local $aNumber = StringRegExp($sString, "(\D?\d+)\D?(\d*)", 1) ; This one works for negatives.
    If UBound($aNumber) = 2 Then
    Local $sLeft = $aNumber[0]
    While StringLen($sLeft)
    $sResult = $sThousands & StringRight($sLeft, 3) & $sResult
    $sLeft = StringTrimRight($sLeft, 3)
    WEnd
    $sResult = StringTrimLeft($sResult, StringLen($sThousands)) ; Strip leading thousands separator
    If $aNumber[1] <> "" Then $sResult &= $sDecimal & $aNumber[1]
    EndIf
    Return $sResult
    EndFunc ;==>_StringAddThousandsSep

    [/autoit]

    Aber auch der verhindert nicht, dass man entsprechende Informationen (zum hacken der HiScoreListe) aus dem Quelltext auslesen kann (genügend Geduld vorausgesetzt).

  • Aber auch der verhindert nicht, dass man entsprechende Informationen (zum hacken der HiScoreListe) aus dem Quelltext auslesen kann (genügend Geduld vorausgesetzt).

    Und selbst wenn er das würde, gäbe es immer noch genügend andere Methoden des Reverse Engineering, die zum Erfolg führen (können). Als Beispiel sei da nur mal das mitsniffen von Packeten, wie schon von Prog@ndy erwähnt, genannt.

    Mal ganz abgesehen davon, dass der Source für deinen Obfuscator offen zugänglich ist, und es damit jedem, der den Thread hier gelesen hat, möglich ist, die einzelnen Schritte des Verschleierns nachzuvollziehen und ein entsprechendes Programm zu schreiben, um diese Maßnahmen rückgängig zu machen.

    Eine absolute Sicherheit wird man m.E. nach nicht nur nicht mit AutoIt nicht erreichen können, sondern auch mit allen anderen Sprachen.
    Spätestens wenn ein Disassembler ins Spiel kommt, sind sie nämlich alle nur noch Assemblercode. Man bedenke, dass sogar Windows bei jedem Release innerhalb kürzester Zeit geknackt wird. Und ich finde, dass die Jungs bei WinzigWeich schon ganz fähige Programmierer sind. Es gibt ja auch genügend Hardwarebasierte Angriffsmöglichkeiten - da hilft Softwareschutz dann garnicht mehr.

    Ich weiß, das Thema gabs schon zu Genüge. Ich wollt es nur nochmal erwähnen.

    • Offizieller Beitrag

    Mal ganz abgesehen davon, dass der Source für deinen Obfuscator offen zugänglich ist, und es damit jedem, der den Thread hier gelesen hat, möglich ist, die einzelnen Schritte des Verschleierns nachzuvollziehen und ein entsprechendes Programm zu schreiben, um diese Maßnahmen rückgängig zu machen.

    Wie gesagt, beim Rest stimme ich Dir zu, aber das hier stimmt nicht, denn meine Random-Massnahmen kann man nicht rückgängig machen.
    Du kannst den Variablen und Funktionen vielleicht andere Namen geben, aber die ursprünglichen Namen sind futsch. Die lassen sich aus den Zufallswerten nicht wiederherstellen.

  • Hallo Oscar,

    Zitat

    Du kannst den Variablen und Funktionen vielleicht andere Namen geben, aber die ursprünglichen Namen sind futsch. Die lassen sich aus den Zufallswerten nicht wiederherstellen.

    Ja, so meinte ich das auch nicht. Mit "Maßnahmen rückgängig machen" meinte ich eher das umkehren der restlichen Schutzmechanismen.
    Ein Beispiel: Der Obfuscator den ich mal geschrieben hatte (Der mit StringEncrypt arbeitet(e)), hatte folgenden Aufbau:

    1. Includes ins Script einbinden
    2. Strings durch ... Chr(...) & Chr(...) & Chr(...) ... ersetzen.
    3. Funktionsnamen random ersetzen
    4. Variablennamen random ersetzen (außer Konstanten)
    5. Chr(...)-Gebilde, Funktionsaufrufe, If-Anweisungen werden in _StringEncrypt & Execute umgewandelt
    6. Zahlen werden durch _StringReverse & BinarytoString ( bin mir da garnich mehr so sicher :D) ersetzt
    7. Der Obfus verschiebt bestimmte Scriptteile
    8. Kommentare und #Region/#EndRegion werden entfernt.

    Bis auf die Punkte 3, 4 & 8 lässt sich alles rückgängig machen (mit entsprechendem Aufwand)

  • :D

    Ihr denkt das echt, oder?

    Es gibt nen bot auf elitepvpers ; geproggt mit AutoIt, und der ist zu 100 % Obfuscated und sicher !!!

    Das gibt es, der typ heist low ??? in skype ;)


    Und ich verwette 5 € drauf, dass er nicht lesbar ist (habe ihn selber decompiled)

  • Alles klar.

    Danke für eure Meinung und Hilfe.
    Inzwischen bin ich ganz zuversichtlich, dass wir den Code recht sicher bekommen, da man durch kombination verschiedener, hier nicht genannter Methoden zu einem Code kommt, der nur mit SEHR viel Zeitaufwand gekanckt werden kann.

    mfg Ubuntu

  • Ja alles ist möglich, aber man muss bei einem Störfaktor ansetzen.
    Und darüber zu dikutieren wie man den Code schützen kann ist Mist, da das doch jeder hier lesen kann und gegenmassnahmen ergreifen kann :pinch:

    Also wer was weiss soll mir ne pm schicken und das hat auch schon jemand getan.

    mfg Ubuntu

  • Könnte man nicht den MD5-Hash der orginalen, kompilierten Version auf dem Server speichern und immer an den Server den MD5-Hash der benutzten Datei übermitteln? Dann müsste man diese nur vergleichen.

  • Das wäre auch ein Ansatz.
    Sollte man vielleicht mal ernsthaft drüber nachdenken ...

    mfg Ubuntu