VB.NET ReadProcessMemory 字符串

VB.NET ReadProcessMemory string

所以我有以下代码

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

而且它应该读取所​​有记事本内存(像一步一步)。当我 运行 它时我没有得到任何错误,但是它 returns


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

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

您正在打印 sBuffer 的值,它是一个整数,可以解释您看到的结果。此外,sBuffer 不包含从内存中读取的数据。我认为您的 lpBuffer 参数(以及 stringinmemory )不应该是 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