; Author: Luigi ; Source: https://www.autoitscript.com/forum/topic/194419-protect-a-single-exe/?do=edit #include-once #include #include #include #include #include #include #include Opt("GUIOnEventMode", 1) Opt("GUIEventOptions", 1) Opt("MustDeclareVars", 1) Opt("WinWaitDelay", 0) #cs Detect Logon: https://www.autoitscript.com/forum/topic/173834-is-there-a-function-or-api-call-to-detect-system-is-at-logon-screen/ https://www.autoitscript.com/forum/topic/162012-detect-fast-user-switch-and-session-lockunlock/ @TODO How keep/maitain $hGui2 over $HANDLE #ce HotKeySet("^{PAUSE}", "Quit") _DebugSetup("MONITOR", True, 4, "monitor.log", True) Global $aUsers[3][2] = [ _ ["cascao", "cascao123"], _ ["cebolinha", "cebolinha123"], _ ["monica", "monica123"] _ ] Global $hGui1, $iInputUser, $iInputPass, $iButtonTryLogin, $iLabel, $mid, $len = 180 Global $hGui2 Global $EXE = "teste.exe" Global $PID = 0 Global $HANDLE = 0 Global $LIST Global $WIN Global $USER = 0 Global $STATUS = 0 Global $aDim[4] Global $USER_NAME = "" Global $iStart, $iDelay = 500 AdlibRegister("EvalUser", 100) While Sleep($iDelay) $iStart = _Timer_Init() Monitor() $iDelay = _Timer_Diff($iStart) $iDelay = $iDelay < 400 ? 400 : $iDelay * 2 WEnd Func EvalUser() If $USER And Not ($USER_NAME = @UserName) Then $USER_NAME = @UserName Logout() EndIf EndFunc ;==>EvalUser Func Monitor() $LIST = __Process() Switch $LIST[0][0] Case 0 $PID = Run($EXE) $HANDLE = GetHandleFromPID($PID) While Not $HANDLE And Sleep(50) $HANDLE = GetHandleFromPID($PID) WEnd $WIN = WinGetPos($HANDLE) Case 1 $PID = $LIST[1][1] While Not $HANDLE And Sleep(50) $HANDLE = GetHandleFromPID($PID) WEnd $WIN = WinGetPos($HANDLE) Case Else For $ii = $LIST[0][0] To 2 Step -1 While Not ProcessClose($LIST[$ii][1]) And Sleep(50) WEnd Next EndSwitch __GuiEval() EndFunc ;==>Monitor Func __GuiEval() $STATUS = __Status() If $USER Then Else If BitOR($STATUS, $WIN_STATE_ENABLED) Then WinSetState($HANDLE, "", @SW_DISABLE) If BitOR($STATUS, $WIN_STATE_VISIBLE) Then WinSetState($HANDLE, "", @SW_HIDE) If $hGui1 Then Else Gui1_Show() EndIf EndIf EndFunc ;==>__GuiEval Func __Status() Local $STATUS = WinGetState($HANDLE) ;~ ConsoleWrite("$status[" & $STATUS & "] $HANDLE[" & $HANDLE & "]" & @LF) ;~ If BitAND($STATUS, 1) Then ConsoleWrite("[ 1] $WIN_STATE_EXISTS" & @LF) ;~ If BitAND($STATUS, 2) Then ConsoleWrite("[ 2] $WIN_STATE_VISIBLE" & @LF) ;~ If BitAND($STATUS, 4) Then ConsoleWrite("[ 4] $WIN_STATE_ENABLED" & @LF) ;~ If BitAND($STATUS, 8) Then ConsoleWrite("[ 8] $WIN_STATE_ACTIVE" & @LF) ;~ If BitAND($STATUS, 16) Then ConsoleWrite("[16] $WIN_STATE_MINIMIZED" & @LF) ;~ If BitAND($STATUS, 32) Then ConsoleWrite("[32] $WIN_STATE_MAXIMIZED" & @LF) EndFunc ;==>__Status Func __Process() Local $arr[1][4] = [[0]] Local $aProcess = ProcessList($EXE) Local $oWMI = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & @ComputerName & "\root\cimv2") If IsObj($oWMI) Then Local $colProcs = $oWMI.ExecQuery("SELECT * FROM win32_process") If IsObj($colProcs) Then For $oProc In $colProcs For $ii = 1 To $aProcess[0][0] If $aProcess[$ii][1] = $oProc.ProcessId Then _ArrayAdd2D($arr, $aProcess[$ii][0], $aProcess[$ii][1], $oProc.ExecutablePath, __StringToDate($oProc.CreationDate)) ExitLoop EndIf Next Next EndIf EndIf _ArraySort($arr, 0, 1, 0, 3) Return $arr EndFunc ;==>__Process Func __StringToDate($in) Return StringLeft($in, 4) & StringMid($in, 5, 2) & StringMid($in, 7, 2) & StringMid($in, 9, 2) & StringMid($in, 11, 2) & StringMid($in, 13, 2) EndFunc ;==>__StringToDate Func _ArrayAdd2D(ByRef $aInput, $mOpt1 = Default, $mOpt2 = Default, $mOpt3 = Default, $mOpt4 = Default, $mOpt5 = Default, $mOpt6 = Default, $mOpt7 = Default, $mOpt8 = Default, $mOpt9 = Default, $mOpt10 = Default) $aInput[0][0] = UBound($aInput, 1) ReDim $aInput[$aInput[0][0] + 1][UBound($aInput, 2)] Local $iCol = @NumParams - 1 < UBound($aInput, 2) ? @NumParams - 1 : UBound($aInput, 2) For $ii = 1 To $iCol $aInput[$aInput[0][0]][$ii - 1] = Execute("$mOpt" & $ii) Next Return $aInput[0][0] EndFunc ;==>_ArrayAdd2D Func GetHandleFromPID($ipid) Local $aList = WinList() For $ii = 1 To UBound($aList) - 1 If (WinGetProcess($aList[$ii][1]) == $ipid) And (BitAND(WinGetState($aList[$ii][1]), 2)) Then Return $aList[$ii][1] Next Return 0 EndFunc ;==>GetHandleFromPID Func Quit() AdlibUnRegister("EvalUser") WinSetState($HANDLE, "", @SW_ENABLE) WinSetState($HANDLE, "", @SW_SHOW) Exit EndFunc ;==>Quit Func TryLogin() __GuiLock() Local $_user = GUICtrlRead($iInputUser) Local $_pass = GUICtrlRead($iInputPass) GUICtrlSetData($iInputPass, "") If Not $_user Then Return __GuiUnlock(1, "empty user") If Not $_pass Then Return __GuiUnlock(1, "empty pass") Local $iSearch = _ArraySearch($aUsers, $_user, 1) If @error Then Return __GuiUnlock(1, "unknow user") If Not ($_pass == $aUsers[$iSearch][1]) Then Return __GuiUnlock(1, "wrong pass") $USER = $iSearch _DebugOut("Login $USER[" & $USER & "][" & $aUsers[$USER][0] & "]") $USER_NAME = @UserName GUIDelete($hGui1) Gui2_Show() EndFunc ;==>TryLogin Func __GuiLock() GUICtrlSetState($iInputUser, $GUI_DISABLE) GUICtrlSetState($iInputPass, $GUI_DISABLE) GUICtrlSetState($iButtonTryLogin, $GUI_DISABLE) EndFunc ;==>__GuiLock Func __GuiUnlock($iCode = 0, $msg = "") Switch $iCode Case 1 GUICtrlSetState($iInputUser, $GUI_ENABLE) GUICtrlSetState($iInputPass, $GUI_ENABLE) GUICtrlSetState($iButtonTryLogin, $GUI_ENABLE) GUICtrlSetState($iInputUser, $GUI_FOCUS) If $msg Then GUICtrlSetData($iLabel, $msg) Case 2 GUICtrlSetState($iInputUser, $GUI_ENABLE) GUICtrlSetState($iInputPass, $GUI_ENABLE) GUICtrlSetState($iButtonTryLogin, $GUI_ENABLE) EndSwitch _DebugOut("Unlock.code[" & $iCode & "]" & ($msg ? " msg[" & $msg & "]" : "") & ($USER ? " USER[" & $USER & "]" : "")) EndFunc ;==>__GuiUnlock Func Logout() GUIRegisterMsg($WM_WINDOWPOSCHANGED, "") _DebugOut("Logout $USER[" & $USER & "][" & $aUsers[$USER][0] & "]") WinSetState($HANDLE, "", @SW_HIDE) WinSetState($HANDLE, "", @SW_DISABLE) GUIDelete($hGui2) $USER = 0 $USER_NAME = "" Gui1_Show() EndFunc ;==>Logout Func Gui1_Show() $hGui1 = GUICreate("MONITOR", $WIN[2], $WIN[3], $WIN[0], $WIN[1], $WS_POPUP) $mid = ($WIN[2] - $len) / 2 $iInputUser = GUICtrlCreateInput("monica", $mid, 80, $len, 26) $iInputPass = GUICtrlCreateInput("monica123", $mid, 120, $len, 26, $ES_PASSWORD) $iButtonTryLogin = GUICtrlCreateButton("Login", $mid + $len / 2, 160, $len / 2, 26) GUICtrlSetOnEvent($iButtonTryLogin, "TryLogin") $iLabel = GUICtrlCreateLabel("", $mid, 200, $len, 200) GUISetState(@SW_SHOW, $hGui1) EndFunc ;==>Gui1_Show Func Gui2_Show() $hGui2 = GUICreate("MONITOR", $WIN[2] - 4, 1, $WIN[0] - 6, $WIN[1], $WS_THICKFRAME) GUISetOnEvent($GUI_EVENT_CLOSE, "Logout", $hGui2) WinSetState($HANDLE, "", @SW_ENABLE) WinSetState($HANDLE, "", @SW_SHOW) WinMove($HANDLE, "", $WIN[0], $WIN[1], $WIN[2], $WIN[3]) WinActivate($HANDLE) GUIRegisterMsg($WM_WINDOWPOSCHANGED, "WM_WINDOWPOSCHANGED") GUISetState(@SW_SHOW, $hGui2) EndFunc ;==>Gui2_Show Func WM_WINDOWPOSCHANGED($hWnd, $msg, $wParam, $lParam) ;~ ConsoleWrite("$hWnd[" & $hWnd & "] $hGui2[" & $hGui2 & "] $Msg[" & $msg & "] $wParam[" & $wParam & "] $lParam[" & $lParam & "]" & @LF) If $hGui2 Then Local $aRet = DllStructCreate("Int[6]", $lParam) $aDim[0] = DllStructGetData($aRet, 1, 3) $aDim[1] = DllStructGetData($aRet, 1, 4) $aDim[2] = DllStructGetData($aRet, 1, 5) $aDim[3] = DllStructGetData($aRet, 1, 6) WinMove($HANDLE, "", $aDim[0] + 6, $aDim[1], $aDim[2] - 12, $WIN[3]) WinSetTitle($hGui2, "", "[" & _ArrayToString($aDim, ",") & "] Delay[" & $iDelay & "]") EndIf Return $GUI_RUNDEFMSG EndFunc ;==>WM_WINDOWPOSCHANGED