Skip to content

Instantly share code, notes, and snippets.

@fiddyschmitt
Created July 20, 2020 14:21
Show Gist options
  • Save fiddyschmitt/b534d9206d753a5d65d0d8fb056103aa to your computer and use it in GitHub Desktop.
Save fiddyschmitt/b534d9206d753a5d65d0d8fb056103aa to your computer and use it in GitHub Desktop.
#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