diff --git a/src/LetterSwap.au3 b/src/LetterSwap.au3 index 2f9aaf5..fb2e6cc 100644 --- a/src/LetterSwap.au3 +++ b/src/LetterSwap.au3 @@ -1,36 +1,34 @@ #NoTrayIcon #Region ;**** Directives created by AutoIt3Wrapper_GUI **** -#AutoIt3Wrapper_Outfile_type=a3x #AutoIt3Wrapper_Icon=LetterSwap.ico -#AutoIt3Wrapper_Outfile=d:\__Proect\LetterSwapAu3\LetterSwap.a3x -#AutoIt3Wrapper_UseX64=n +#AutoIt3Wrapper_Outfile=..\bin\x86\LetterSwap.exe +#AutoIt3Wrapper_Outfile_x64=..\bin\x64\LetterSwap.exe +#AutoIt3Wrapper_Compile_Both=y #AutoIt3Wrapper_Res_Comment=LetterSwap.exe #AutoIt3Wrapper_Res_Description=LetterSwap.exe -#AutoIt3Wrapper_Res_Fileversion=2019.2.10.3 +#AutoIt3Wrapper_Res_Fileversion=2019.2.10.5 #AutoIt3Wrapper_Res_Fileversion_AutoIncrement=y -#AutoIt3Wrapper_Res_ProductVersion=2018.10.9 +#AutoIt3Wrapper_Res_ProductVersion=2019.2.10 #AutoIt3Wrapper_Res_LegalCopyright=(c)Nikzzzz -#AutoIt3Wrapper_Run_After=%scitedir%\CheckSum\CheckSumPe.exe /c "%out%" -#AutoIt3Wrapper_Run_After=%scitedir%\CheckSum\signtool.exe sign /f "%scitedir%\CheckSum\Sert\Sert.pfx" "%out%" -#AutoIt3Wrapper_Run_After=%scitedir%\CheckSum\CheckSumPe.exe /c "%outx64%" -#AutoIt3Wrapper_Run_After=%scitedir%\CheckSum\signtool.exe sign /f "%scitedir%\CheckSum\Sert\Sert.pfx" "%outx64%" +#AutoIt3Wrapper_Res_Language=1033 #AutoIt3Wrapper_Run_Au3Stripper=y -#Au3Stripper_Parameters=/pe /sf /sv +#Au3Stripper_Parameters=/so #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** + #include -#include -#include +#include ".\Reg.au3" +#include ".\SecurityEx.au3" Opt('MustDeclareVars', 1) Opt('TrayIconHide', 1) Opt('ExpandEnvStrings', 1) -Global $sAboot = " (c)Nikzzzz 10.02.2019" +Global $sAbout = " (c)Nikzzzz 10.02.2019" Global $sHelp = @ScriptName & " [/HideLetter|/MountAll] [/Auto|/Manual|WinDir] [/Save] [/BootDrive NewLetter:[\TagFile]] [/SetLetter NewLetter:\TagFile] [/RestartExplorer] [/log [LogFile|con:]] [/IgnoreLetter Letters] [/Swap Drive: Drive:] [/wait 10]" & @CRLF If $CmdLine[0] = 0 Then - MsgBox(4096, @ScriptName & $sAboot, $sHelp) + MsgBox(4096, @ScriptName & $sAbout, $sHelp) Exit EndIf Global $sHostKey = "HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices" @@ -90,7 +88,7 @@ While $i <= $CmdLine[0] If Number($CmdLine[$i]) >= 0 Then $iWait0 = Number($CmdLine[$i]) * 10 EndIf Case "/?", "/help" - MsgBox(4096, @ScriptName & $sAboot, $sHelp) + MsgBox(4096, @ScriptName & $sAbout, $sHelp) Exit Case "/RestartExplorer" $sRestartExplorer = True diff --git a/src/Reg.au3 b/src/Reg.au3 new file mode 100644 index 0000000..f637e44 --- /dev/null +++ b/src/Reg.au3 @@ -0,0 +1,330 @@ +#include-once +#include +#include ".\SecurityEx.au3" + +; #INDEX# ======================================================================================================================================= +; Title .........: Reg +; AutoIt Version : 3.2.10++ +; Language ......: English +; Description ...: Perform operations with registry files +; =============================================================================================================================================== + +; #CURRENT# ===================================================================================================================================== +;_RegLoadHive +;_RegRestoreHive +;_RegSaveHive +;_RegUnloadHive +; =============================================================================================================================================== + +; #INTERNAL_USE_ONLY#============================================================================================================================ +;RegCloseKey +;RegConnectRegistry +;RegCreateKeyEx +;RegOpenKeyEx +;Split_sRootKey +; =============================================================================================================================================== + +Global Const $KEY_READ = 0x20019 +Global Const $KEY_WRITE = 0x20006 + +; #FUNCTION# ==================================================================================================================================== +; Name...........: _RegLoadHive +; Description ...: Loads a file as a registry hive +; Syntax.........: _RegLoadHive($sFile, $sKey) +; Parameters ....: $sFile - Full path to the file to be loaded +; $sKey - Registry key to load the file to +; Must start with HKEY_LOCAL_MACHINE or HKEY_USERS +; Requirement(s).: None +; Return values .: Success - 1 +; Failure - 0 +; Sets @error +; Author ........: engine +; Modified.......: +; Remarks .......: It is possible to access remote registries by using $sRootKey in the form "\\computername\keyname" +; If a remote computer is specified than $sFile is relative to that computer +; You can only load registry hives to a subkey immediately below HKEY_LOCAL_MACHINE or HKEY_USERS +; Related .......: +; Link ..........; +; Examples ......; _RegLoadHive("C:\Documents and Settings\Guest\ntuser.dat", "HKU\TempHive") +; _RegLoadHive("C:\Documents and Settings\Guest\ntuser.dat", "HKLM\TempHive") +; _RegLoadHive("C:\Documents and Settings\Administrator\ntuser.dat", "\\computername\HKU\S-1-5-21-domain-500") +; _RegLoadHive("C:\Documents and Settings\Guest\ntuser.dat", "\\computername\HKEY_USERS\S-1-5-21-domain-501") +; =============================================================================================================================================== + +Func _RegLoadHive($sFile, $sKey) + Local $avArray = Split_sRootKey($sKey) + Local $hKey = RegConnectRegistry($avArray[0], $avArray[1]) + Local $avCurr[2][2] = [[$SE_RESTORE_NAME, $SE_PRIVILEGE_ENABLED], [$SE_BACKUP_NAME, $SE_PRIVILEGE_ENABLED]] + Local $avPrev = _SetPrivilege($avCurr) + Local $avRLH = DllCall("Advapi32.dll", "long", "RegLoadKey", "hwnd", $hKey, "str", $avArray[2], "str", $sFile) + _SetPrivilege($avPrev) + RegCloseKey($hKey) + Return SetError( $avRLH[0], 0, Number($avRLH[0] = 0) ) +EndFunc ;==> _RegLoadHive + +; #FUNCTION# ==================================================================================================================================== +; Name...........: _RegRestoreHive +; Description ...: Reads the registry information in a specified file and copies it over the specified key +; Syntax.........: _RegRestoreHive($sFile, $sKey) +; Parameters ....: $sFile - The name of the file with the registry information +; $sKey - Registry key +; Requirement(s).: None +; Return values .: Success - 1 +; Failure - 0 +; Sets @error +; Author ........: engine +; Modified.......: +; Remarks .......: It is possible to access remote registries by using $sKey in the form "\\computername\keyname" +; If a remote computer is specified than $sFile is relative to that computer +; Related .......: +; Link ..........; +; Example .......; _RegRestoreHive("HKCU.dat", "\\" & @ComputerName & "\HKCU") +; =============================================================================================================================================== + +Func _RegRestoreHive($sFile, $sKey) + Local Const $REG_FORCE_RESTORE = 0x00000008 + Local $avArray = Split_sRootKey($sKey) + Local $hRoot = RegConnectRegistry($avArray[0], $avArray[1]) + Local $hKey = RegCreateKeyEx( $hRoot, $avArray[2], BitOR($KEY_READ, $KEY_WRITE) ) + RegCloseKey($hRoot) + Local $avCurr[2][2] = [[$SE_RESTORE_NAME, $SE_PRIVILEGE_ENABLED], [$SE_BACKUP_NAME, $SE_PRIVILEGE_ENABLED]] + Local $avPrev = _SetPrivilege($avCurr) + Local $avRRK = DllCall("Advapi32.dll", "long", "RegRestoreKey", "hwnd", $hKey, "str", $sFile, "dword", $REG_FORCE_RESTORE) + _SetPrivilege($avPrev) + RegCloseKey($hKey) + Return SetError( $avRRK[0], 0, Number($avRRK[0] = 0) ) +EndFunc ;==> _RegRestoreHive + +; #FUNCTION# ==================================================================================================================================== +; Name...........: _RegSaveHive +; Description ...: Saves the specified key and all of its subkeys and values to a new file, in the standard format +; Syntax.........: _RegSaveHive($sFile, $sKey) +; Parameters ....: $sFile - The name of the file in which the specified key and subkeys are to be saved +; $sKey - Registry key +; Requirement(s).: None +; Return values .: Success - 1 +; Failure - 0 +; Sets @error +; Author ........: engine +; Modified.......: +; Remarks .......: It is possible to access remote registries by using $sKey in the form "\\computername\keyname" +; Related .......: +; Link ..........; +; Example .......; _RegSaveHive("HKCU.dat", "\\" & @ComputerName & "\HKCU") +; =============================================================================================================================================== + +Func _RegSaveHive($sFile, $sKey) + Local $avArray = Split_sRootKey($sKey) + Local $hRoot = RegConnectRegistry($avArray[0], $avArray[1]) + Local $hKey = RegOpenKeyEx($hRoot, $avArray[2], $KEY_READ) + RegCloseKey($hRoot) + Local $avCurr[2] = [$SE_BACKUP_NAME, $SE_PRIVILEGE_ENABLED] + Local $avPrev = _SetPrivilege($avCurr) + Local $avRSK = DllCall("Advapi32.dll", "long", "RegSaveKey", "hwnd", $hKey, "str", $sFile, "ptr", 0) + _SetPrivilege($avPrev) + RegCloseKey($hKey) + Return SetError( $avRSK[0], 0, Number($avRSK[0] = 0) ) +EndFunc ;==> _RegSaveHive + +; #FUNCTION# ==================================================================================================================================== +; Name...........: _RegUnloadHive +; Description ...: Unloads a registry hive +; Syntax.........: _RegUnloadHive($sKey) +; Parameters ....: $sKey - Registry key to unload the hive from +; Requirement(s).: None +; Return values .: Success - 1 +; Failure - 0 +; Sets @error +; Author ........: engine +; Modified.......: +; Remarks .......: It is possible to access remote registries by using $sKey in the form "\\computername\keyname" +; Related .......: +; Link ..........; +; Examples ......; _RegUnloadHive("HKU\TempHive") +; _RegUnloadHive("HKLM\TempHive") +; _RegUnloadHive("\\computername\HKU\S-1-5-21-domain-500") +; _RegUnloadHive("\\computername\HKEY_USERS\S-1-5-21-domain-501") +; =============================================================================================================================================== + +Func _RegUnloadHive($sKey) + Local $avArray = Split_sRootKey($sKey) + Local $hKey = RegConnectRegistry($avArray[0], $avArray[1]) + Local $avCurr[2][2] = [[$SE_RESTORE_NAME, $SE_PRIVILEGE_ENABLED], [$SE_BACKUP_NAME, $SE_PRIVILEGE_ENABLED]] + Local $avPrev = _SetPrivilege($avCurr) + Local $avRUH = DllCall("Advapi32.dll", "long", "RegUnLoadKey", "hwnd", $hKey, "str", $avArray[2]) + _SetPrivilege($avPrev) + RegCloseKey($hKey) + Return SetError( $avRUH[0], 0, Number($avRUH[0] = 0) ) +EndFunc ;==> _RegUnloadHive + +; #INTERNAL_USE_ONLY#============================================================================================================================ +; Name...........: RegCloseKey +; Description ...: Closes a handle to the specified registry key +; Syntax.........: RegCloseKey($hKey) +; Parameters ....: $hKey - Registry key handle to close +; Requirement(s).: None +; Return values .: Success - 1 +; Failure - 0 +; Sets @error +; Author ........: engine +; Modified.......: +; Remarks .......: For internal use only +; Related .......: +; Link ..........; +; Example .......; +; =============================================================================================================================================== + +Func RegCloseKey($hKey) + Local $avRCK = DllCall("Advapi32.dll", "long", "RegCloseKey", "hwnd", $hKey) + Return SetError( $avRCK[0], 0, Number($avRCK[0] = 0) ) +EndFunc ;==> RegCloseKey + +; #INTERNAL_USE_ONLY#============================================================================================================================ +; Name...........: RegConnectRegistry +; Description ...: Establishes a connection to a predefined registry key on another computer +; Syntax.........: RegConnectRegistry($sComputer, $hKey) +; Parameters ....: $sComputer - Computer name in the form '\\computername' +; $hKey - Predefined registry key handle +; Requirement(s).: Service 'RemoteRegistry' running on the target computer +; When the target computer is the local computer, the 'RemoteRegistry' service isn't required +; Return values .: Success - Registry key handle +; Failure - 0 +; Sets @error +; Author ........: engine +; Modified.......: +; Remarks .......: For internal use only +; Related .......: +; Link ..........; +; Example .......; +; =============================================================================================================================================== + +Func RegConnectRegistry($sComputer, $hKey) + Local $avRCR = DllCall( "Advapi32.dll", "long", "RegConnectRegistry", _ + "str", $sComputer, _ + "hwnd", $hKey, _ + "hwnd*", 0 ) + Return SetError($avRCR[0], 0, $avRCR[3]) +EndFunc ;==> RegConnectRegistry + +; #INTERNAL_USE_ONLY#============================================================================================================================ +; Name...........: RegCreateKeyEx +; Description ...: Creates the specified registry key +; Syntax.........: RegCreateKeyEx($kKey, $sSubKey, $iAccess) +; Parameters ....: $hKey - Predefined registry key handle +; $sSubKey - The name of the registry subkey to be created +; $iAccess - A mask that specifies the desired access rights to the key +; Requirement(s).: None +; Return values .: Success - Registry key handle +; Failure - 0 +; Sets @error +; Author ........: engine +; Modified.......: +; Remarks .......: For internal use only +; Related .......: +; Link ..........; +; Example .......; +; =============================================================================================================================================== + +Func RegCreateKeyEx($kKey, $sSubKey, $iAccess) + Local Const $REG_OPTION_NON_VOLATILE = 0x00000000 + Local $avRCKE = DllCall( "Advapi32.dll", "long", "RegCreateKeyEx", _ + "hwnd", $kKey, _ + "str", $sSubKey, _ + "dword", 0, _ + "ptr", 0, _ + "dword", $REG_OPTION_NON_VOLATILE, _ + "dword", $iAccess, _ + "ptr", 0, _ + "hwnd*", 0, _ + "ptr", 0 ) + Return SetError($avRCKE[0], 0, $avRCKE[8]) +EndFunc ;==> RegCreateKeyEx + +; #INTERNAL_USE_ONLY#============================================================================================================================ +; Name...........: RegOpenKeyEx +; Description ...: Opens the specified registry key +; Syntax.........: RegOpenKeyEx($hKey, $sSubKey, $iAccess) +; Parameters ....: $hKey - Predefined registry key handle +; $sSubKey - The name of the registry subkey to be opened +; $iAccess - A mask that specifies the desired access rights to the key +; Requirement(s).: None +; Return values .: Success - Registry key handle +; Failure - 0 +; Sets @error +; Author ........: engine +; Modified.......: +; Remarks .......: For internal use only +; Related .......: +; Link ..........; +; Example .......; +; =============================================================================================================================================== + +Func RegOpenKeyEx($hKey, $sSubKey, $iAccess) + Local $avROKE = DllCall( "Advapi32.dll", "long", "RegOpenKeyEx", _ + "hwnd", $hKey, _ + "str", $sSubKey, _ + "dword", 0, _ + "dword", $iAccess, _ + "hwnd*", 0 ) + Return SetError($avROKE[0], 0, $avROKE[5]) +EndFunc ;==> RegOpenKeyEx + +; #INTERNAL_USE_ONLY#============================================================================================================================ +; Name...........: Split_sRootKey +; Description ...: Splits $sRootKey between computer name, predefined registry key handle and subkey +; Syntax.........: Split_sRootKey($sRootKey) +; Parameters ....: $sRootKey - Reg function main key +; Requirement(s).: None +; Return values .: Returns an array where: +; $array[0] = \\computername +; $array[1] = Predefined registry key handle +; $array[2] = Subkey +; Author ........: engine +; Modified.......: +; Remarks .......: For internal use only +; Related .......: +; Link ..........; +; Example .......; +; =============================================================================================================================================== + +Func Split_sRootKey($sRootKey) + Local Const $HKEY_CLASSES_ROOT = 0x80000000 + Local Const $HKEY_CURRENT_USER = 0x80000001 + Local Const $HKEY_LOCAL_MACHINE = 0x80000002 + Local Const $HKEY_USERS = 0x80000003 + Local Const $HKEY_CURRENT_CONFIG = 0x80000005 + Local $avHKEY[5][3] = [["HKCR", "HKEY_CLASSES_ROOT", $HKEY_CLASSES_ROOT], _ + ["HKCU", "HKEY_CURRENT_USER", $HKEY_CURRENT_USER], _ + ["HKLM", "HKEY_LOCAL_MACHINE", $HKEY_LOCAL_MACHINE], _ + ["HKU", "HKEY_USERS", $HKEY_USERS], _ + ["HKCC", "HKEY_CURRENT_CONFIG", $HKEY_CURRENT_CONFIG]] + Local $avArray[3] + If StringInStr($sRootKey, "\\") = 1 Then + Local $asComputer = StringRegExp($sRootKey, "\\\\[^\\]*\\", 1) + If Not @error Then + $avArray[0] = StringTrimRight($asComputer[0], 1) + $sRootKey = StringReplace($sRootKey, $asComputer[0], "", 1) + EndIf + EndIf + If StringInStr($sRootKey, "\") = 1 Or StringInStr($sRootKey, "\", 0, -1) = StringLen($sRootKey) Or StringInStr($sRootKey, "\\") Then + $avArray[0] = "" + Return $avArray + Else + Local $asSplit = StringSplit($sRootKey, "\") + For $i = 0 To UBound($avHKEY) - 1 + If $asSplit[1] = $avHKEY[$i][0] Or $asSplit[1] = $avHKEY[$i][1] Then + $avArray[1] = $avHKEY[$i][2] + ExitLoop + EndIf + Next + If $avArray[1] = "" Then + $avArray[0] = "" + Return $avArray + EndIf + For $i = 2 To $asSplit[0] - 1 + $avArray[2] &= $asSplit[$i] & "\" + Next + If $asSplit[0] > 1 Then $avArray[2] &= $asSplit[ $asSplit[0] ] + EndIf + Return $avArray +EndFunc ;==> Split_sRootKey diff --git a/src/SecurityEx.au3 b/src/SecurityEx.au3 new file mode 100644 index 0000000..526dc58 --- /dev/null +++ b/src/SecurityEx.au3 @@ -0,0 +1,92 @@ +#include-once + +; #FUNCTION# ==================================================================================================================================== +; Name...........: _SetPrivilege +; Description ...: Enables or disables special privileges as required by some DllCalls +; Syntax.........: _SetPrivilege($avPrivilege) +; Parameters ....: $avPrivilege - An array of privileges and respective attributes +; $SE_PRIVILEGE_ENABLED - The function enables the privilege +; $SE_PRIVILEGE_REMOVED - The privilege is removed from the list of privileges in the token +; 0 - The function disables the privilege +; Requirement(s).: None +; Return values .: Success - An array of modified privileges and their respective previous attribute state +; Failure - An empty array +; Sets @error +; Author ........: engine +; Modified.......: +; Remarks .......: +; Related .......: +; Link ..........; +; Example .......; +; =============================================================================================================================================== + +Func _SetPrivilege($avPrivilege) + Local $iDim = UBound($avPrivilege, 0), $avPrevState[1][2] + If Not ( $iDim <= 2 And UBound($avPrivilege, $iDim) = 2 ) Then Return SetError(1300, 0, $avPrevState) + If $iDim = 1 Then + Local $avTemp[1][2] + $avTemp[0][0] = $avPrivilege[0] + $avTemp[0][1] = $avPrivilege[1] + $avPrivilege = $avTemp + $avTemp = 0 + EndIf + Local $k, $tagTP = "dword", $iTokens = UBound($avPrivilege, 1) + Do + $k += 1 + $tagTP &= ";dword;long;dword" + Until $k = $iTokens + Local $tCurrState, $tPrevState, $pPrevState, $tLUID, $hAdvapi32, $hKernel32, $ahGCP, $avOPT, $aiGLE + $tCurrState = DLLStructCreate($tagTP) + $tPrevState = DllStructCreate($tagTP) + $pPrevState = DllStructGetPtr($tPrevState) + $tLUID = DllStructCreate("dword;long") + DLLStructSetData($tCurrState, 1, $iTokens) + $hAdvapi32 = DllOpen("Advapi32.dll") + For $i = 0 To $iTokens - 1 + DllCall( $hAdvapi32, "int", "LookupPrivilegeValue", _ + "str", "", _ + "str", $avPrivilege[$i][0], _ + "ptr", DllStructGetPtr($tLUID) ) + DLLStructSetData( $tCurrState, 3 * $i + 2, DllStructGetData($tLUID, 1) ) + DLLStructSetData( $tCurrState, 3 * $i + 3, DllStructGetData($tLUID, 2) ) + DLLStructSetData( $tCurrState, 3 * $i + 4, $avPrivilege[$i][1] ) + Next + $hKernel32 = DllOpen("Kernel32.dll") + $ahGCP = DllCall($hKernel32, "hwnd", "GetCurrentProcess") + $avOPT = DllCall( $hAdvapi32, "int", "OpenProcessToken", _ + "hwnd", $ahGCP[0], _ + "dword", BitOR($TOKEN_ADJUST_PRIVILEGES, $TOKEN_QUERY), _ + "hwnd*", 0 ) + DllCall( $hAdvapi32, "int", "AdjustTokenPrivileges", _ + "hwnd", $avOPT[3], _ + "int", False, _ + "ptr", DllStructGetPtr($tCurrState), _ + "dword", DllStructGetSize($tCurrState), _ + "ptr", $pPrevState, _ + "dword*", 0 ) + $aiGLE = DllCall($hKernel32, "dword", "GetLastError") + DllCall($hKernel32, "int", "CloseHandle", "hwnd", $avOPT[3]) + DllClose($hKernel32) + Local $iCount = DllStructGetData($tPrevState, 1) + If $iCount > 0 Then + Local $pLUID, $avLPN, $tName, $avPrevState[$iCount][2] + For $i = 0 To $iCount - 1 + $pLUID = $pPrevState + 12 * $i + 4 + $avLPN = DllCall( $hAdvapi32, "int", "LookupPrivilegeName", _ + "str", "", _ + "ptr", $pLUID, _ + "ptr", 0, _ + "dword*", 0 ) + $tName = DllStructCreate("char[" & $avLPN[4] & "]") + DllCall( $hAdvapi32, "int", "LookupPrivilegeName", _ + "str", "", _ + "ptr", $pLUID, _ + "ptr", DllStructGetPtr($tName), _ + "dword*", DllStructGetSize($tName) ) + $avPrevState[$i][0] = DllStructGetData($tName, 1) + $avPrevState[$i][1] = DllStructGetData($tPrevState, 3 * $i + 4) + Next + EndIf + DllClose($hAdvapi32) + Return SetError($aiGLE[0], 0, $avPrevState) +EndFunc ;==> _SetPrivilege