Hello everybody,
I'm having a hard time searching for a value (and furthermore, values pattern) in a process' memory.
This process is a "VBoxHeadless" process (like a normal VM process, but without GUI to be able to be run remotely if needed). It is created by Andy, the Android emulator.
I can get an handle from the process, but when using VirtualQueryEx, the only thing I get is an array of the good length but containing only '00000000000' values.
I've tried different ways to access this information, but the result is the same.
Any idea?
I'm having a hard time searching for a value (and furthermore, values pattern) in a process' memory.
This process is a "VBoxHeadless" process (like a normal VM process, but without GUI to be able to be run remotely if needed). It is created by Andy, the Android emulator.
I can get an handle from the process, but when using VirtualQueryEx, the only thing I get is an array of the good length but containing only '00000000000' values.
I've tried different ways to access this information, but the result is the same.
Any idea?
Code:
#RequireAdmin
#include <WinAPI.au3>
#Include <Constants.au3>
#Include <Array.au3>
; Relevant string used to identify the right VM process.
Local Const $RELEVANT_STRING = "heroes"
Func findProcess($name)
setprivilege("sedebugprivilege", 1)
; Multiple process have the same name, we need to find the good process first, using the $RELEVANT_STRING
Dim $pids = ProcessList($name)
Dim $process
For $i = 1 To UBound($pids) - 1
$process = _WinAPI_OpenProcess (0x1F0FFF, 1, $pids[$i][1])
If (UBound(searchProcessMemory($process, $RELEVANT_STRING, 1)) > 1) Then
; Get the hwnd.
Return $process
EndIf
Next
EndFunc
Func searchProcessMemory($procHwnd, $SearchValue, $dType = 1)
;GetSystemInfo
Dim $systemInfo = _WinAPI_GetSystemInfo()
$lpMinimumApplicationAddress = $systemInfo[2]
$lpMaximumApplicationAddress = $systemInfo[3]
$systemInfo=""
$i = $lpMinimumApplicationAddress
While $i < $lpMaximumApplicationAddress
Local $mbi[7] ; MEMORY_BASIC_INFORMATION Structure
If @Error Then SetError(@Error + 1)
Dim $v_Buffer = _VirtualQueryEx($i, $procHwnd) ; Returns an array of a valid length full of 0
If Not @Error Then
For $j = 0 to 6
$mbi[$j] = StringStripWS($v_Buffer[$j], 3)
Next
Else
SetError(6)
EndIf
Local $Output
Select
Case $dType = 1
$SearchV = Hex(StringToBinary($SearchValue, 2));;unicode string hex to search for
;In this particular case we know what we looking for, so we will narrow down the field to speed up the search
If $mbi[4] = 4096 And $mbi[5] = 4 And $mbi[6] = 16777216 Then ;a.k.a MEM_COMMIT + PAGE_READWRITE + MEM_IMAGE
Local $pBuffer = DllStructCreate("byte["&$mbi[3]&"]")
DllCall("Kernel32.dll", 'int', 'ReadProcessMemory', 'int', $procHwnd, 'int', $mbi[0], 'ptr', DllStructGetPtr($pBuffer), 'int', DllStructGetSize($pBuffer), 'int', '')
$oc = 1
While 1
$x = StringInStr(DllStructGetData($pBuffer, 1), $SearchV, 0, $oc)
If @Error Then SetError(@Error + 1)
If Mod($x, 2) Then ;if aligned at byte (and obviously <> 0)
$Address = ($x - 3) / 2 + $i
$Output &= Hex($Address) & @CR & $SearchValue & @CR
$oc +=1
Else
ExitLoop
EndIf
WEnd
EndIf
$pBuffer = ""
Case $dType = 2
Case $dType = 3
EndSelect
$i += $mbi[3]
WEnd
$retArray = StringSplit($Output, @CRLF)
Return $retArray
EndFunc
Func setprivilege($PRIVILEGE, $BENABLE)
Const $MY_TOKEN_ADJUST_PRIVILEGES = 32
Const $MY_TOKEN_QUERY = 8
Const $MY_SE_PRIVILEGE_ENABLED = 2
Local $HTOKEN, $SP_AUXRET, $SP_RET, $HCURRPROCESS, $NTOKENS, $NTOKENINDEX, $PRIV
$NTOKENS = 1
$LUID = DllStructCreate("dword;int")
If IsArray($PRIVILEGE) Then $NTOKENS = UBound($PRIVILEGE)
$TOKEN_PRIVILEGES = DllStructCreate("dword;dword[" & (3 * $NTOKENS) & "]")
$NEWTOKEN_PRIVILEGES = DllStructCreate("dword;dword[" & (3 * $NTOKENS) & "]")
$HCURRPROCESS = DllCall("kernel32.dll", "hwnd", "GetCurrentProcess")
$SP_AUXRET = DllCall("advapi32.dll", "int", "OpenProcessToken", "hwnd", $HCURRPROCESS[0], "int", BitOR($MY_TOKEN_ADJUST_PRIVILEGES, $MY_TOKEN_QUERY), "int*", 0)
If $SP_AUXRET[0] Then
$HTOKEN = $SP_AUXRET[3]
DllStructSetData($TOKEN_PRIVILEGES, 1, 1)
$NTOKENINDEX = 1
While $NTOKENINDEX <= $NTOKENS
If IsArray($PRIVILEGE) Then
$PRIV = $PRIVILEGE[$NTOKENINDEX - 1]
Else
$PRIV = $PRIVILEGE
EndIf
$RET = DllCall("advapi32.dll", "int", "LookupPrivilegeValue", "str", "", "str", $PRIV, "ptr", DllStructGetPtr($LUID))
If $RET[0] Then
If $BENABLE Then
DllStructSetData($TOKEN_PRIVILEGES, 2, $MY_SE_PRIVILEGE_ENABLED, (3 * $NTOKENINDEX))
Else
DllStructSetData($TOKEN_PRIVILEGES, 2, 0, (3 * $NTOKENINDEX))
EndIf
DllStructSetData($TOKEN_PRIVILEGES, 2, DllStructGetData($LUID, 1), (3 * ($NTOKENINDEX - 1)) + 1)
DllStructSetData($TOKEN_PRIVILEGES, 2, DllStructGetData($LUID, 2), (3 * ($NTOKENINDEX - 1)) + 2)
DllStructSetData($LUID, 1, 0)
DllStructSetData($LUID, 2, 0)
EndIf
$NTOKENINDEX += 1
WEnd
$RET = DllCall("advapi32.dll", "int", "AdjustTokenPrivileges", "hwnd", $HTOKEN, "int", 0, "ptr", DllStructGetPtr($TOKEN_PRIVILEGES), "int", DllStructGetSize($NEWTOKEN_PRIVILEGES), "ptr", DllStructGetPtr($NEWTOKEN_PRIVILEGES), "int*", 0)
$F = DllCall("kernel32.dll", "int", "GetLastError")
EndIf
$NEWTOKEN_PRIVILEGES = 0
$TOKEN_PRIVILEGES = 0
$LUID = 0
If $SP_AUXRET[0] = 0 Then Return 0
$SP_AUXRET = DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $HTOKEN)
If Not $RET[0] And Not $SP_AUXRET[0] Then Return 0
Return $RET[0]
EndFunc ;==>SETPRIVILEGE
Func _WinAPI_GetSystemInfo($iInformation=-1)
If $iInformation<>-1 And ($iInformation<1 Or $iInformation>10) Then Return SetError(1,0,-1)
Local $aRet,$stSystemInfo=DllStructCreate("ushort;short;dword;ptr;ptr;ulong_ptr;dword;dword;dword;short;short")
; If we are running in 32-bit mode on a 64-bit OS, we need to call a different API function
If Not @AutoItX64 And @OSArch<>"X86" Then
$aRet=DllCall("kernel32.dll","none","GetNativeSystemInfo","ptr",DllStructGetPtr($stSystemInfo))
Else
$aRet=DllCall("kernel32.dll","none","GetSystemInfo","ptr",DllStructGetPtr($stSystemInfo))
EndIf
If @error Or Not IsArray($aRet) Then Return SetError(2,0,-1)
If $iInformation<>-1 Then
If $iInformation==1 Then Return DllStructGetData($stSystemInfo,1)
Return DllStructGetData($stSystemInfo,$iInformation+1)
EndIf
Local $aSysInfo[10]
$aSysInfo[0]=DllStructGetData($stSystemInfo,1)
For $i=1 To 9
$aSysInfo[$i]=DllStructGetData($stSystemInfo,$i+2)
Next
#cs
; Full feature display:
MsgBox(64,"System Info", _
"Processor Architecture:"&$aSysInfo[0]&@CRLF& _
"Page Size:"&$aSysInfo[1]&@CRLF& _
"Minimum Application Address:"&$aSysInfo[2]&@CRLF& _
"Maximum Application Address:"&$aSysInfo[3]&@CRLF& _
"Active Processor Mask:"&Hex($aSysInfo[4])&@CRLF& _
"Number of Processors:"&$aSysInfo[5]&@CRLF& _
"Processor Type:"&$aSysInfo[6]&@CRLF& _
"Allocation Granularity:"&$aSysInfo[7]&@CRLF& _
"Processor Level:"&Hex($aSysInfo[8])&@CRLF& _
"Processor Revision:"&Hex($aSysInfo[9]))
#ce
Return $aSysInfo
EndFunc
Func _VirtualQueryEx($iv_Address, $ah_Handle)
;If Not IsArray($ah_Handle) Then
; SetError(1)
; Return 0
;EndIf
Local $av_Data[7], $i
Local $v_Buffer = DllStructCreate('dword;dword;dword;dword;dword;dword;dword')
If @Error Then
SetError(@Error + 1)
Return 0
EndIf
DllCall('Kernel32.dll', 'int', 'VirtualQueryEx', 'int', $ah_Handle, 'int', $iv_Address, 'ptr', DllStructGetPtr($v_Buffer), 'int', DllStructGetSize($v_Buffer))
If Not @Error Then
For $i = 0 to 6
$av_Data[$i] = Hex(DllStructGetData($v_Buffer, ($i + 1)))
Next
Return $av_Data
Else
SetError(6)
Return 0
EndIf
EndFunc
Dim $t = findProcess("VBoxHeadless.exe")
MsgBox(0, "TEST", $t)