我很难在进程的内存中搜索一个值(以及值模式)。这个进程是一个“VBoxHeadless”进程(就像一个普通的 VM 进程,但没有 GUI 可以在需要时远程运行)。它由 Android 模拟器 Andy 创建。
我可以从这个过程中得到一个句柄,但是当使用 VirtualQueryEx 时,我唯一得到的是一个长度合适但只包含“00000000000”值的数组。
我尝试了不同的方法来访问这些信息,但结果是一样的。
任何想法?
#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)