VB.NET ReadProcessMemory字符串

时间:2015-01-28 09:57:08

标签: vb.net readprocessmemory

所以我有以下代码

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。 我究竟做错了什么 ?你能帮我吗 ? 提前致谢。 NICU

1 个答案:

答案 0 :(得分:1)

您正在打印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