1

我很难在进程的内存中搜索一个值(以及值模式)。这个进程是一个“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)

4

0 回答 0