代码之家  ›  专栏  ›  技术社区  ›  Stoica Nicusor

VB.NET ReadProcessMemory字符串

  •  0
  • Stoica Nicusor  · 技术社区  · 11 年前

    所以我有以下代码

    Imports System.Diagnostics
    Imports System.IO
    Imports System.Runtime.InteropServices    
    Public Class Form1    
        <StructLayout(LayoutKind.Sequential)> _
        Structure OSVERSIONINFO
            Dim dwOSVersionInfoSize As Integer
            Dim dwMajorVersion As Integer
            Dim dwMinorVersion As Integer
            Dim dwBuildNumber As Integer
            Dim dwPlatformId As Integer
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=128), VBFixedString(128)> Dim szCSDVersion As String
        End Structure
        <StructLayout(LayoutKind.Sequential)> _
        Structure MEMORY_BASIC_INFORMATION
            Dim BaseAddress As Integer
            Dim AllocationBase As Integer
            Dim AllocationProtect As Integer
            Dim RegionSize As Integer
            Dim State As Integer
            Dim Protect As Integer
            Dim lType As Integer
        End Structure    
        <StructLayout(LayoutKind.Sequential)> _
        Structure SYSTEM_INFO ' 36 Bytes
            Dim dwOemID As Integer
            Dim dwPageSize As Integer
            Dim lpMinimumApplicationAddress As Integer
            Dim lpMaximumApplicationAddress As Integer
            Dim dwActiveProcessorMask As Integer
            Dim dwNumberOrfProcessors As Integer
            Dim dwProcessorType As Integer
            Dim dwAllocationGranularity As Integer
            Dim wProcessorLevel As Short
            Dim wProcessorRevision As Short
        End Structure
        Private Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" (ByRef LpVersionInformation As OSVERSIONINFO) As Integer
        Private Declare Function VirtualQueryEx Lib "kernel32.dll" (ByVal hProcess As IntPtr, ByVal lpAddress As UInteger, ByRef lpBuffer As MEMORY_BASIC_INFORMATION, ByVal dwLength As Integer) As Integer
        Private Declare Sub GetSystemInfo Lib "kernel32" (ByRef lpSystemInfo As SYSTEM_INFO)
        Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Integer, ByVal blnheritHandle As Integer, ByVal dwAppProcessId As Integer) As Integer
        Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Integer) As Integer
        Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Integer, ByRef lpBaseAddress As Integer, ByRef lpBuffer As Long, ByVal nSize As Integer, ByRef lpNumberOfBytesWritten As Integer) As Integer
        Private Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Integer, ByRef lpBaseAddress As Integer, ByRef lpBuffer As String, ByVal nSize As Integer, ByRef lpNumberOfBytesWritten As Integer) As Integer
        Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As Integer, ByRef lpdwProcessId As Integer) As Integer
        Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As Integer, ByVal lpWindowName As Integer) As Integer
        Private Declare Function GetParent Lib "user32" (ByVal hWnd As Integer) As Integer
        Private Declare Function GetWindow Lib "user32" (ByVal hWnd As Integer, ByVal wCmd As Integer) As Integer
        Private Const PROCESS_VM_READ = (&H10)
        Private Const PROCESS_VM_OPERATION = (&H8)
        Private Const PROCESS_QUERY_INFORMATION = (&H400)
        Public Const PROCESS_READ_WRITE_QUERY = PROCESS_VM_READ + PROCESS_VM_OPERATION + PROCESS_QUERY_INFORMATION
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click    
            Dim pid As Integer, hProcess As Integer
            Dim lpMem As Integer, ret As DialogResult, lLenMBI As Integer
            Dim lWritten As Integer
            Dim sBuffer As String
            Dim sSearchString As String = "", sReplaceString As String = ""
            Dim si As SYSTEM_INFO
            Dim mbi As MEMORY_BASIC_INFORMATION
            For Each p As Process In Process.GetProcesses
                If p.ProcessName = "notepad" Then
                    pid = p.Id
                End If
            Next
            hProcess = OpenProcess(PROCESS_READ_WRITE_QUERY, False, pid)
            lLenMBI = Len(mbi)
            'Determine applications memory addresses range
            GetSystemInfo(si)
            lpMem = si.lpMinimumApplicationAddress
             Do While lpMem < si.lpMaximumApplicationAddress
                mbi.RegionSize = 0
                ret = VirtualQueryEx(hProcess, lpMem, mbi, lLenMBI)
                If ret = lLenMBI Then
                    If ((mbi.lType = &H20000) And (mbi.State = &H1000)) Then
                        If mbi.RegionSize > 0 Then
                            Dim stringinmemory As Long
                            sBuffer = mbi.RegionSize
                            ReadProcessMemory(hProcess, mbi.BaseAddress, stringinmemory, mbi.RegionSize, lWritten)
                            Debug.WriteLine(sBuffer)
                        End If
                    End If
                    lpMem = mbi.BaseAddress + mbi.RegionSize
                Else
                    Exit Do
                End If
            Loop
            CloseHandle(hProcess)
        End Sub
    End Class
    

    它应该读取所有记事本内存(一步一步地)。我运行它时没有错误,但它会返回

        4096
        4096
        4096
        8192
        90112
        4096
        344064
        131072
        8192
        45056
        172032
        4096
        155648
        4096
    
    

    这段代码在VB6中运行良好,但我将其转换为VB.NET。 我做错了什么?你能帮帮我吗? 提前感谢。 尼库

    1 回复  |  直到 11 年前
        1
  •  1
  •   Chris Dunaway    11 年前

    您正在打印的值 sBuffer 这是一个整数,它解释了你所看到的结果。此外,sBuffer不包含从内存中读取的数据。我想你的 lpBuffer 参数(以及字符串内存)不应该是Long,而是Byte数组。类似于:

    Const PROCESS_WM_READ As Integer = &H10
    
    <DllImport("kernel32.dll")> _
    Public Shared Function OpenProcess(dwDesiredAccess As Integer, bInheritHandle As Boolean, dwProcessId As Integer) As IntPtr
    End Function
    
    <DllImport("kernel32.dll")> _
    Public Shared Function ReadProcessMemory(hProcess As Integer, lpBaseAddress As Integer, lpBuffer As Byte(), dwSize As Integer, ByRef lpNumberOfBytesRead As Integer) As Boolean
    End Function
    
    Public Shared Sub Main()
        Dim notepadProcess As Process = Process.GetProcessesByName("notepad")(0)
        Dim processHandle As IntPtr = OpenProcess(PROCESS_WM_READ, False, notepadProcess.Id)
    
        Dim bytesRead As Integer = 0
        Dim buffer As Byte() = New Byte(23) {}
    
        'The address in this line is hard-coded.  Use whatever is appropriate for your situation.
        ReadProcessMemory(CInt(processHandle), &H36B9D0, buffer, buffer.Length, bytesRead)
    
        Console.WriteLine(Encoding.Unicode.GetString(buffer))
        Console.ReadLine()
    End Sub