Created
July 20, 2020 14:21
-
-
Save fiddyschmitt/b534d9206d753a5d65d0d8fb056103aa to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Region ;**** Directives created by AutoIt3Wrapper_GUI **** | |
#AutoIt3Wrapper_Change2CUI=y | |
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** | |
#include <WinAPI.au3> | |
;~ #include <WinAPIInternals.au3> | |
#include <Array.au3> | |
Main() | |
Func Main() | |
Local $processOrPid | |
Local $mutantName | |
If $CmdLine[0] = 2 Then | |
$processOrPid = $CmdLine[1] ;eg. notepad.exe or 20123 | |
$mutantName = $CmdLine[2] ;\Sessions\1\BaseNamedObjects\SessionImmersiveColorMutex | |
Else | |
ConsoleWrite("Invalid arguments. Please provide two arguments: [process name|pid] mutexName" & @CRLF & "Example: " & @CRLF & @ScriptName & " notepad.exe \Sessions\1\BaseNamedObjects\SessionImmersiveColorMutex") | |
Exit | |
EndIf | |
Local $processList = [] | |
If IsNumber($processOrPid) Then | |
$processList[0] = Number($processOrPid) | |
Else | |
$processList = ProcessList($processOrPid) | |
EndIf | |
Local $pidList = [] | |
For $i = 1 To $processList[0][0] | |
_ArrayAdd($pidList, $processList[$i][1]) | |
Next | |
_ArrayDelete($pidList, 0) | |
;~ _ArrayDisplay($pidList) | |
$mutants = _getHandles($pidList, "Mutant", $mutantName) | |
If IsArray($mutants) Then | |
;~ _ArrayDisplay($mutants) | |
For $iIndex = 0 To UBound($mutants) - 1 | |
$pid = $mutants[$iIndex][0] | |
$mutantHandle = $mutants[$iIndex][4] | |
$mutantName = $mutants[$iIndex][9] | |
ConsoleWrite("Closing Mutant Handle " & $mutantHandle & " in Process ID " & $pid & " for Mutant " & $mutantName & @CRLF) | |
_ReleaseMutex($mutantHandle, $pid) | |
Next | |
Else | |
ConsoleWrite("No mutants found." & @CRLF) | |
EndIf | |
EndFunc ;==>Main | |
Func _NtQueryObject($h, $i) | |
$tag_OBJECT_TYPE = _ ; TYPE / NAME Doesnt matter... I just want the unicodestring. | |
"ushort Length;" & _ | |
"ushort MaximumLength;" & _ | |
"ptr Name;" & _ | |
"byte[512]" | |
Local $ObjType = DllStructCreate($tag_OBJECT_TYPE) | |
DllCall("ntdll.dll", "int", "NtQueryObject", "hwnd", $h, "int", $i, "ptr", DllStructGetPtr($ObjType, 1), "int", DllStructGetSize($ObjType), "int*", 0) | |
Local $aGLE = DllCall("Kernel32.dll", "int", "GetLastError") | |
If $aGLE[0] > 0 Then SetError($aGLE[0]) | |
$buffer = DllStructCreate("wchar[256]", DllStructGetData($ObjType, "Name")) | |
Return DllStructGetData($buffer, 1) | |
EndFunc ;==>_NtQueryObject | |
Func _getHandleType($hMutex) | |
$ret = _NtQueryObject($hMutex, 2) | |
If @error Then SetError(@error) | |
If $ret == 0 Then Return "Unknown?" | |
Return $ret | |
EndFunc ;==>_getHandleType | |
Func _getHandleName($hMutex) | |
$ret = _NtQueryObject($hMutex, 1) | |
If @error Then SetError(@error) | |
If $ret == 0 Then Return "No Name?" | |
Return $ret | |
EndFunc ;==>_getHandleName | |
Func _getHandles($pidList, $sObjectType = Default, $sObjectName = Default) | |
$tag_SYSTEM_HANDLE_INFO = _ | |
"USHORT UniqueProcessId;" & _ ; | |
"USHORT CreatorBackTraceIndex;" & _ ; | |
"ubyte ObjectTypeIndex;" & _ ; | |
"ubyte HandleAttributes;" & _ ; | |
"USHORT HandleValue;" & _ ; | |
"ptr Object;" & _ ; | |
"ptr GrantedAccess" ; | |
Local $Mem = DllStructCreate("byte[" & 40000000 & "]") | |
Local $ret = DllCall("ntdll.dll", "int", "ZwQuerySystemInformation", "int", 16, "ptr", DllStructGetPtr($Mem), "int", DllStructGetSize($Mem), "int*", 0) | |
Local $SysHnd = DllStructCreate($tag_SYSTEM_HANDLE_INFO, $ret[2] + 4) | |
Local $dw = DllStructCreate("dword", $ret[2]) | |
Local $Count = DllStructGetData($dw, 1) | |
Local $SysHnd_ptr = $ret[2] + 4 | |
Local $SysHnd_Size = DllStructGetSize($SysHnd) | |
Local $buffer, $i = 0, $lastthread, $m = 0, $NextEntryDelta, $k, $temp, $space, $l | |
Local $avArray[1000000][10] | |
Local $types[100] | |
While 1 | |
;~ ConsoleWrite($m & "/" & $Count & @CRLF) | |
If $m = $Count Then | |
ExitLoop | |
EndIf | |
$avArray[$i][0] = DllStructGetData($SysHnd, "UniqueProcessId") | |
If _ArraySearch($pidList, $avArray[$i][0]) == -1 Then | |
$m += 1 | |
$SysHnd = DllStructCreate($tag_SYSTEM_HANDLE_INFO, $SysHnd_ptr + $SysHnd_Size * $m) | |
ContinueLoop | |
EndIf | |
;~ ConsoleWrite("Processing PID handles") | |
$avArray[$i][1] = DllStructGetData($SysHnd, "CreatorBackTraceIndex") | |
$avArray[$i][2] = DllStructGetData($SysHnd, "ObjectTypeIndex") | |
$avArray[$i][3] = DllStructGetData($SysHnd, "HandleAttributes") | |
$avArray[$i][4] = Ptr(DllStructGetData($SysHnd, "HandleValue")) | |
$avArray[$i][5] = DllStructGetData($SysHnd, "Object") | |
$avArray[$i][6] = DllStructGetData($SysHnd, "GrantedAccess") | |
$hProcSource = _WinAPI_OpenProcess(0x1f0fff, 0, $avArray[$i][0]) | |
$hProcDest = _WinAPI_OpenProcess(0x1f0fff, 0, @AutoItPID) | |
$ret = DllCall("kernel32.dll", "int", "DuplicateHandle", "hwnd", $hProcSource, "hwnd", $avArray[$i][4], "hwnd", $hProcDest, "hwnd*", 0, "int", 0, "int", 0, "int", $DUPLICATE_SAME_ACCESS) | |
$avArray[$i][7] = $ret[4] | |
$avArray[$i][7] = $ret[4] | |
If $types[$avArray[$i][2]] == "" Then | |
$avArray[$i][8] = _getHandleType($ret[4]) | |
$types[$avArray[$i][2]] = $avArray[$i][8] | |
Else | |
$avArray[$i][8] = $types[$avArray[$i][2]] | |
EndIf | |
;Filter by ObjectType | |
If $sObjectType <> Default And $avArray[$i][8] <> $sObjectType Then | |
$m += 1 | |
$SysHnd = DllStructCreate($tag_SYSTEM_HANDLE_INFO, $SysHnd_ptr + $SysHnd_Size * $m) | |
ContinueLoop | |
EndIf | |
;Get the object name | |
$avArray[$i][9] = _getHandleName($ret[4]) | |
If Not $avArray[$i][9] Then $avArray[$i][9] = "" | |
;~ ConsoleWrite($i & " " & $avArray[$i][9] & @CRLF) | |
If $sObjectName <> Default And $avArray[$i][9] <> $sObjectName Then | |
$m += 1 | |
$SysHnd = DllStructCreate($tag_SYSTEM_HANDLE_INFO, $SysHnd_ptr + $SysHnd_Size * $m) | |
ContinueLoop | |
EndIf | |
_WinAPI_CloseHandle($hProcSource) | |
_WinAPI_CloseHandle($hProcDest) | |
$i += 1 | |
$m += 1 | |
$SysHnd = DllStructCreate($tag_SYSTEM_HANDLE_INFO, $SysHnd_ptr + $SysHnd_Size * $m) | |
ContinueLoop | |
WEnd | |
If ($i == 0) Then | |
$avArray = 0 | |
Else | |
ReDim $avArray[$i][10] | |
EndIf | |
Return $avArray | |
EndFunc ;==>_getHandles | |
Func _ReleaseMutex($hMutex, $iPID = @AutoItPID) | |
$test = _DuplicateHandle($iPID, $hMutex, @AutoItPID, True) | |
If @error Then Return SetError(@error, 0, 0) | |
Return 1 | |
EndFunc ;==>_ReleaseMutex | |
;=============================================================================== | |
; | |
; Description: Duplicates a Handle from or for another process | |
; Parameter(s): $dwSourcePid - Pid from Source Process | |
; $hSourceHandle - The Handle to duplicate | |
; $dwTargetPid - Optional, Pid from Target Procces - Defaults to current process | |
; $fCloseSource - Optional, Close the source handle - Defaults to False | |
; Requirement(s): 3.2.4.9 | |
; Return Value(s): On Success - Duplicated Handle | |
; On Failure - 0 and sets error to | |
; @error to: 1 - Api OpenProcess Failed | |
; 2 - Api DuplicateHandle Falied | |
; Author(s): Florian 'Piccaso' Fida | |
; Note(s): | |
; | |
;=============================================================================== | |
Func _DuplicateHandle($dwSourcePid, $hSourceHandle, $dwTargetPid = @AutoItPID, $fCloseSource = False) | |
Local $hTargetHandle, $hPrSource, $hPrTarget, $dwOptions | |
$hPrSource = __dh_OpenProcess($dwSourcePid) | |
$hPrTarget = __dh_OpenProcess($dwTargetPid) | |
If $hPrSource = 0 Or $hPrTarget = 0 Then | |
_CloseHandle($hPrSource) | |
_CloseHandle($hPrTarget) | |
Return SetError(1, 0, 0) | |
EndIf | |
; DUPLICATE_CLOSE_SOURCE = 0x00000001 | |
; DUPLICATE_SAME_ACCESS = 0x00000002 | |
If $fCloseSource <> False Then | |
$dwOptions = 0x01 + 0x02 | |
Else | |
$dwOptions = 0x02 | |
EndIf | |
$hTargetHandle = DllCall("kernel32.dll", "int", "DuplicateHandle", "ptr", $hPrSource, "ptr", $hSourceHandle, "ptr", $hPrTarget, "long_ptr", 0, "dword", 0, "int", 1, "dword", $dwOptions) | |
Local $aGLE = DllCall("Kernel32.dll", "int", "GetLastError") | |
If $aGLE[0] > 0 Then Return SetError($aGLE[0], 0, 0) | |
Return $hTargetHandle[4] | |
EndFunc ;==>_DuplicateHandle | |
Func __dh_OpenProcess($dwProcessId) | |
; PROCESS_DUP_HANDLE = 0x40 | |
Local $hPr = DllCall("kernel32.dll", "ptr", "OpenProcess", "dword", 0x40, "int", 0, "dword", $dwProcessId) | |
If @error Then Return SetError(1, 0, 0) | |
Return $hPr[0] | |
EndFunc ;==>__dh_OpenProcess | |
Func _CloseHandle($hAny) | |
If $hAny = 0 Then Return SetError(1, 0, 0) | |
Local $fch = DllCall("kernel32.dll", "int", "CloseHandle", "ptr", $hAny) | |
If @error Then Return SetError(1, 0, 0) | |
Return $fch[0] | |
EndFunc ;==>_CloseHandle |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment