masvil Posted October 20, 2016 Posted October 20, 2016 (edited) WHAT This script restarts an executable (the AutoIT script itself called "cantstopme.exe", in this case) if any attempt of closure is done. WHY If you want to preserve critical admin task from potential stop attempts. HOW Pure AutoIT method. No batch file(s) are created. It clones itself and creates a self-protecting triangle in this way: - protector1.exe takes care of cantstopme.exe and protector2.exe - protector2.exe takes care of protector1.exe Its goal is to be unstoppable because thanks to auto-restart tecnique no process-trees exist, so conventional process managers can't kill. Furthermore there are no apparent relationships between involved processes. Executables cannot run more than once, so everything stay stable. CPU effort is very low. You can show an administrator alert message, same like I did in the script. INSTRUCTIONS You can change $Protector1Dir, $Protector1Name, $Protector2Dir, $Protector2Name as you want. You can replace the example loop code in "Your script here" section. Compile and run it. The only way to stop persistent generated 3 processes will be pressing CTRL+ALT+E or restarting your PC. If latter then you should manually delete Protectors to clean. SORRY Because almost no comments in the code. Anyway it's short and simple, and I'm here to explain if needed. SO Please test, comment, rate, enhance. Try to kill it! Do you think it is really bullet-proof? I hope someone can create an UDF (I'm not enough skilled to do it). If you like the topic there is one related by @guinness. expandcollapse popup#NoTrayIcon If @Compiled = 0 Then MsgBox(1, '"You cant stop it" AutoIT script by MasviL', "You should run it compiled!") Exit EndIf Local $Protector1Dir = @AppDataDir & "\protector1 dir" Local $Protector1Name = "protector1.exe" Local $Protector2Dir = @AppDataDir & "\protector2 dir" Local $Protector2Name = "protector2.exe" Persistent() ; =============================================== ; Your script here While 1 Sleep(1000) WEnd ; =============================================== Func Persistent() If @ScriptDir <> $Protector1Dir And @ScriptDir <> $Protector2Dir Then If $CmdLine[0] = 0 Then Local $aArray = ProcessList(@ScriptName) For $i = 1 To $aArray[0][0] If $aArray[$i][1] = @AutoItPID Then ContinueLoop $Path = _ProcessGetLocation($aArray[$i][1]) If StringInStr($Path, @ScriptDir) Then Exit EndIf Next FileCopy(@ScriptFullPath, $Protector1Dir & "\" & $Protector1Name, 9) Run($Protector1Dir & "\" & $Protector1Name & ' "' & @ScriptDir & '" ' & @ScriptName & " restart", $Protector1Dir) EndIf If $CmdLine[0] = 1 Then Run(@ScriptFullPath & " 1 2", @ScriptDir) Exit EndIf HotKeySet("^!e", "CloseAll") If FileExists(@ScriptDir & "\stop") Then FileDelete(@ScriptDir & "\stop") ; maybe useless MsgBox(0, '"You cant stop it" AutoIT script by MasviL', 'The only way to stop this script process "' & @ScriptName & '" will be pressing CTRL+ALT+E or restarting your PC.') EndIf If @ScriptDir = $Protector1Dir Then OnAutoItExitRegister("Terminate") ; Maybe useless If $CmdLine[0] = 0 Then Exit If $CmdLine[0] > 1 Then $ExeDir = $CmdLine[1] $ExeName = $CmdLine[2] EndIf If $CmdLine[0] = 3 Then Run(@ScriptFullPath & ' "' & $ExeDir & '" ' & $ExeName, @ScriptDir) Exit EndIf While 1 Sleep(500) If FileExists($ExeDir & "\stop") Then Exit WinKill("AutoIt Error") ; just in case $ExeRunning = 0 Local $aArray = ProcessList($ExeName) For $i = 1 To $aArray[0][0] $Path = _ProcessGetLocation($aArray[$i][1]) If StringInStr($Path, $ExeDir) Then $ExeRunning = 1 EndIf Next If $ExeRunning = 0 Then FileCopy(@ScriptFullPath, $ExeDir & "\" & $ExeName, 9) Run($ExeDir & "\" & $ExeName & " restart", @ScriptDir) EndIf $Protector2Running = 0 Local $aArray = ProcessList($Protector2Name) For $i = 1 To $aArray[0][0] $Path = _ProcessGetLocation($aArray[$i][1]) If StringInStr($Path, $Protector2Dir) Then $Protector2Running = 1 EndIf Next If $Protector2Running = 0 Then FileCopy(@ScriptFullPath, $Protector2Dir & "\" & $Protector2Name, 9) Run($Protector2Dir & "\" & $Protector2Name & ' "' & $ExeDir & '" ' & $ExeName & " restart", @ScriptDir) EndIf WEnd EndIf If @ScriptDir = $Protector2Dir Then OnAutoItExitRegister("Terminate") ; Maybe useless If $CmdLine[0] = 0 Then Exit If $CmdLine[0] > 1 Then $ExeDir = $CmdLine[1] $ExeName = $CmdLine[2] EndIf If $CmdLine[0] = 3 Then Run(@ScriptFullPath & ' "' & $ExeDir & '" ' & $ExeName, @ScriptDir) Exit EndIf While 1 Sleep(500) If FileExists($ExeDir & "\stop") Then Exit WinKill("AutoIt Error") ; just in case $Protector1Running = 0 Local $aArray = ProcessList($Protector1Name) For $i = 1 To $aArray[0][0] $Path = _ProcessGetLocation($aArray[$i][1]) If StringInStr($Path, $Protector1Dir) Then $Protector1Running = 1 EndIf Next If $Protector1Running = 0 Then FileCopy(@ScriptFullPath, $Protector1Dir & "\" & $Protector1Name, 9) Run($Protector1Dir & "\" & $Protector1Name & ' "' & $ExeDir & '" ' & $ExeName & " restart", @ScriptDir) EndIf WEnd EndIf EndFunc ;==>Persistent Func Terminate() Exit EndFunc ;==>Terminate Func CloseAll() $Stop = FileOpen(@ScriptDir & "\stop", 1) FileClose($Stop) Local $aArray = ProcessList($Protector1Name) For $i = 1 To $aArray[0][0] $Path = _ProcessGetLocation($aArray[$i][1]) If StringInStr($Path, $Protector1Dir) Then ProcessWaitClose($aArray[$i][1]) EndIf Next Local $aArray = ProcessList($Protector2Name) For $i = 1 To $aArray[0][0] $Path = _ProcessGetLocation($aArray[$i][1]) If StringInStr($Path, $Protector2Dir) Then ProcessWaitClose($aArray[$i][1]) EndIf Next FileDelete(@ScriptDir & "\stop") DirRemove($Protector1Dir, 1) DirRemove($Protector2Dir, 1) MsgBox(262144, '"You cant stop it" AutoIT script by MasviL', 'Done! You got rid of it.') Exit EndFunc ;==>CloseAll Func _ProcessGetLocation($iPID) Local $aProc = DllCall('kernel32.dll', 'hwnd', 'OpenProcess', 'int', BitOR(0x0400, 0x0010), 'int', 0, 'int', $iPID) If $aProc[0] = 0 Then Return SetError(1, 0, '') Local $vStruct = DllStructCreate('int[1024]') DllCall('psapi.dll', 'int', 'EnumProcessModules', 'hwnd', $aProc[0], 'ptr', DllStructGetPtr($vStruct), 'int', DllStructGetSize($vStruct), 'int_ptr', 0) Local $aReturn = DllCall('psapi.dll', 'int', 'GetModuleFileNameEx', 'hwnd', $aProc[0], 'int', DllStructGetData($vStruct, 1), 'str', '', 'int', 2048) If StringLen($aReturn[3]) = 0 Then Return SetError(2, 0, '') Return $aReturn[3] EndFunc ;==>_ProcessGetLocation cantstopme.au3 Edited October 21, 2016 by masvil Improvement coffeeturtle 1
legend Posted October 21, 2016 Posted October 21, 2016 nice, but you could just suspend protect1 and protect2 and then close the real script, and afterwards protect1 and protect2 but what is the purpose of a persistence process? masvil 1
MattHiggs Posted October 21, 2016 Posted October 21, 2016 11 hours ago, legend said: nice, but you could just suspend protect1 and protect2 and then close the real script, and afterwards protect1 and protect2 but what is the purpose of a persistence process? I agree with legend. If this script is meant to be used in a live environment where end users are going to potentially try to stop the execution of the script, then you might want to include "Opt("TrayAutoPause", 0)" at the beginning so that clicking the toolbar icon does not pause the execution of the scripts, so that the vulnerability described by legend cannot take place masvil 1
masvil Posted October 21, 2016 Author Posted October 21, 2016 (edited) You're right, script updated. I added "#NoTrayIcon" instead of " Opt("TrayAutoPause", 0)", so the trick stay more hidden. Edited October 21, 2016 by masvil
legend Posted October 21, 2016 Posted October 21, 2016 took me less than 5 seconds to close it you can't really prevent me from suspending the process. and even if you did I could remove the permissions of the running procceses, or i could use the SYSTEM account to close it. If your serious about preventing the user from from closing the process you run the script as the SYSTEM account, and then you set the process to be critical, but then again, it would begin to look suspicious, and i wouldn't see the purpose in doing that.
masvil Posted October 21, 2016 Author Posted October 21, 2016 (edited) 7 minutes ago, legend said: took me less than 5 seconds to close it you can't really prevent me from suspending the process. If you don't know how the script works (let's pretend it) how can you know which process(es) to suspend? There is no process-tree. Edited October 21, 2016 by masvil
legend Posted October 21, 2016 Posted October 21, 2016 yes, but i'm not gonna do that, since it can be used for bad minds. if you want to hide the tray icon, use #notrayicon in top of your script
masvil Posted October 21, 2016 Author Posted October 21, 2016 3 minutes ago, legend said: yes, but i'm not gonna do that, since it can be used for bad minds. Do you think I should delete the post? Quote if you want to hide the tray icon, use #notrayicon in top of your script Done.
legend Posted October 21, 2016 Posted October 21, 2016 No I think it's ok, but that's not up to me to decide. masvil 1
MattHiggs Posted October 21, 2016 Posted October 21, 2016 (edited) What I would do is, instead of having other processes keep the main process open, maybe you should just make a single service that does this. There are quite a few udfs available to create services with autoit. This way, the user needs to have admin rights in order to even access the service snap-in console, and wouldn't have permissions to change its state. Plus, the cool thing about services is that you can customize their permissions, and make it so that nobody has rights to change it. Edited October 21, 2016 by MattHiggs masvil 1
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now