Script kurzzeitig schützen

  • Hallo zusammen und Frohes Neues,
    ich hab ein Script, dass vor dem Schließen geschützt werden soll. Egal ob durch den Taskmanger, über die CMD, oder durch das Herunterfahren des PCs. Das Script läuft in einer Endlosschleife und zwischendrin gibt es einen Bereich, in dem einige Daten nur in den Variablen des programms gespeichert sind. In diesem bereich sollte es nicht geschlossen werden können, sondern erst wieder wenn alle daten wieder in anderen dateien gesichert sind. Es sollte zuminset eine Nachfrage kommen, ob es wirklich beendet werden soll.
    Ich hoffe, ihr versteht, was ich meine.

    Schonmal Danke im Vorraus.

    3 Mal editiert, zuletzt von jjj (4. Januar 2014 um 18:55)

  • Danke, aber das Problem mit dieser Funktion ist, dass der geschützte Teil von Anfang bis Ende durchlaufen soll. Mit OnAutoItExitRegister startet man doch nur eine registrierte Funktion, oder irre ich mir da? Oder kann man da reinschreiben, dass das Script fortgesetzt werden soll?

  • Schwer vorstellbar...
    Das grenzt ja schon für eine Bastelanleitung für Viren :D

    Zudem werden alle Variablen Global behandelt die außerhalb einer Funktion (Egal mit welchem Schlüsselwort [Local|Global|Const|Dim]) deklariert werden.

  • Ich kann versichern, dass das kein Virus ist
    Und danke, ich habs jetzt so gelöst, dass der Aktuelle schritt in einer Variablen steht und die Funktion bei OnAutoItExitRegister das dann zu Ende führt.
    Ist aber nicht gerade schön.

    Einmal editiert, zuletzt von jjj (2. Januar 2014 um 14:38)

  • Um ein Prozess-Beenden durch den Taskmanager zu verhindern, müsstest du entweder:

    a) NtTerminateProcess Hooken (Prozess-Status kannste mit ZwQueryProcessInformation in der ProcessBreakOnTerminationClass prüfen.)
    b) Deinem AutoIt process mit dem API Call RtlSetProcessIsCritical eine Critical-Flag zuweißen.
    c) Deinem AutoIt process mit dem API Call NtSetInformationProcess eine Critical-Flag zuweißen.
    d) Andere Native Methoden anwenden, das geht mit AutoIt aber nicht, da wird C/C++/ASM benötigt...

    Viel Erfolg.

  • Kannte ich zwar auch noch nicht, sieht aber nützlich aus:

    RtlSetProcessIsCritical
    [autoit]


    #include <Security.au3>
    #include <WinAPI.au3>

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

    #RequireAdmin

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

    ;Debug-Privlegien holen...
    Local $hToken = _Security__OpenProcessToken(_WinAPI_GetCurrentProcess(), $TOKEN_ALL_ACCESS)
    _Security__SetPrivilege($hToken, $SE_DEBUG_NAME, True)
    _WinAPI_CloseHandle($hToken)

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

    ;Escape-Funktion registrieren
    HotKeySet("{ESC}", "_Escape")

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

    ;Critical-Flag auf <TRUE> setzen
    _WinAPI_SetProcessIsCritical(True)

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

    ;Hauptschleife
    While True
    Sleep(20)
    WEnd

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

    Func _Escape()
    ;Critical-Flag auf <FALSE> setzen
    MsgBox(0, "", _WinAPI_SetProcessIsCritical(False))
    Exit
    EndFunc

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

    Func _WinAPI_SetProcessIsCritical($bState)
    $avReturn = DllCall("ntdll.dll", "int:cdecl", "RtlSetProcessIsCritical", "boolean", $bState, "ptr", Null, "boolean", False)
    Return $avReturn[0]
    EndFunc

    [/autoit]

    Aber Vorsicht!!!
    Wenn man probiert, den Prozess nun zu beenden (egal ob per pkill, Exit vom TrayIcon oder per Exit aus dem Skript heraus)... Naja, wer sich die Überraschung verderben möchte, soll in den Spoiler schauen. :D
    Trotzdem ein Tipp: Vorher alles Speichern. ^^

    Spoiler anzeigen


    Bluescreen! :party:

    Gruß

  • chesstiger :

    Das ist aber nur bei der Verwendung der RtlSetProcessIsCritical-API.
    Da versucht wird sogar im Admin-mode den Prozess zu schützen. --> BSOD bei Kill.
    Wenn du die CriticalFlag mit der NtSetInformationProcess-API zuweist gibts nur ne Usermode Protection, also bei einem Nichtadmin kommt bei einem versuchten Prozesskill diese Meldung:

    [Blockierte Grafik: http://s14.directupload.net/images/140101/ohw27fgh.png]


    Bei einem Administrator beendet sich nach einem Prozesskill die Anwendung normal, ohne BSOD.
    Kannste ja mal probieren zu scripten ^^


    Edit:
    Ich habs mal Mit NtSetInformationProcess probiert, aber iwie klappt es nicht, der Prozess kann normal gekillt werden...
    Der DllCall muss falsch sein...? :huh:

    [autoit]

    #include <WinApi.au3>
    #include <Security.au3>
    #RequireAdmin

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

    ;Get Debug Privileges
    Local $DebugToken = _Security__OpenThreadToken(_WinAPI_GetCurrentProcess(),$TOKEN_ALL_ACCESS)
    _Security__SetPrivilege($DebugToken,$SE_DEBUG_NAME,True)
    _WinAPI_CloseHandle($DebugToken)

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

    Func _NtSetInformationProcess_ProtectProcess()
    ConsoleWrite('Protecting Process...' & @LF)
    $StateReturn = DllCall("ntdll.dll","int", "NtSetInformationProcess","handle",_WinAPI_OpenProcess(512,False,ProcessExists(@ScriptName)),"int",29,"ptr*",1,"long",4)
    Return $StateReturn
    EndFunc

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

    _NtSetInformationProcess_ProtectProcess()

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

    While True

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

    Sleep(20)

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

    WEnd

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

    Einmal editiert, zuletzt von Madara (1. Januar 2014 um 21:49)

  • Danke für die ganzen Antworten, werde das gleicht mal einbauen.

    Ich hab das Scripte von chesstiger mal getestet, aber da kommt immer eine Fehlermeldung in Z. 29: $avReturn = DllCall("ntdll.dll", "int:cdecl", "RtlSetProcessIsCritical", "boolean", $bState, "ptr", Null^ ERROR
    Missing separator character after keyword.
    Weiß jeman, warum, bzw. wie man das beheben kann?

    3 Mal editiert, zuletzt von jjj (2. Januar 2014 um 14:38)

  • Ja. So:

    [autoit]

    #include <Security.au3>
    #include <WinAPI.au3>

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

    #RequireAdmin

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

    ;Debug-Privlegien holen...
    Local $hToken = _Security__OpenProcessToken(_WinAPI_GetCurrentProcess(), $TOKEN_ALL_ACCESS)
    _Security__SetPrivilege($hToken, $SE_DEBUG_NAME, True)
    _WinAPI_CloseHandle($hToken)

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

    ;Escape-Funktion registrieren
    HotKeySet("{ESC}", "_Escape")

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

    ;Critical-Flag auf <TRUE> setzen
    _WinAPI_SetProcessIsCritical(True)

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

    ;Hauptschleife
    While True
    Sleep(20)
    WEnd

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

    Func _Escape()
    ;Critical-Flag auf <FALSE> setzen
    MsgBox(0, "", _WinAPI_SetProcessIsCritical(False))
    Exit
    EndFunc

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

    Func _WinAPI_SetProcessIsCritical($bState)
    $avReturn = DllCall("ntdll.dll", "int:cdecl", "RtlSetProcessIsCritical", "boolean", $bState, "ptr", 'none', "boolean", False)
    Return $avReturn[0]
    EndFunc

    [/autoit]
  • Danke,
    Problem fast gelöst. Es wäre gut, wenn nicht gleich der ganze PC abkratzen würde, wenn man des Progamm versucht zu beenden. So ist es dann ja auch geschlossen, und die Daten sind Weg.
    Geht es nicht irgendwie, dass einfach nur eine MsgBox kommt, von wegen "Kann nicht beendet werden" und dann läuft alles normal weiter?

  • Hatte ich versucht, ging aber nicht. Hab dann wahrscheinlich die " vergessen , oder so.

    Trotzdem sollte da eine MsgBox kommen, das Problem ist, dass iich als Admin angemeldet bin.

  • Und wie geht das?


    Du injectest ASM in die Zielfunktion, um einen JMP am Anfang zu platzieren. Dieser JMP springt beim Funktionsaufruf zur Hook-Prozedur.
    Die Hook-Prozedur callt die orginale API, bekommt das Ergebnis, manipuliert es, schickt die manipulierten Daten zurück zur API und diese zurück zur Anwendung (Hier: taskmgr.exe)
    Ließ mal hier nach.