کد:
Imports System.Diagnostics
Imports System.IO
Imports System.Runtime.InteropServices
Public Class Form1
' REQUIRED CONSTS
Private Const PROCESS_QUERY_INFORMATION As Integer = 1024
Private Const MEM_COMMIT As Integer = 4096
Private Const PAGE_READWRITE As Integer = 4
Private Const PROCESS_WM_READ As Integer = 16
' REQUIRED METHODS
Public Declare Function OpenProcess Lib "kernel32.dll" (ByVal dwDesiredAccess As Integer, ByVal bInheritHandle As Boolean, ByVal dwProcessId As Integer) As IntPtr
Public Declare Function ReadProcessMemory Lib "kernel32.dll" (ByVal hProcess As Integer, ByVal lpBaseAddress As Integer, ByVal lpBuffer() As Byte, ByVal dwSize As Integer, ByRef lpNumberOfBytesRead As Integer) As Boolean
Private Declare Sub GetSystemInfo Lib "kernel32.dll" (ByRef lpSystemInfo As SYSTEM_INFO)
Private Declare Function VirtualQueryEx Lib "kernel32.dll" (ByVal hProcess As IntPtr, ByVal lpAddress As IntPtr, ByRef lpBuffer As MEMORY_BASIC_INFORMATION, ByVal dwLength As UInteger) As Integer
' REQUIRED STRUCTS
Public Structure MEMORY_BASIC_INFORMATION
Public BaseAddress As Integer
Public AllocationBase As Integer
Public AllocationProtect As Integer
Public RegionSize As Integer
Public State As Integer
Public Protect As Integer
Public lType As Integer
End Structure
Public Structure SYSTEM_INFO
Public processorArchitecture As System.UInt16
Private reserved As System.UInt16
Public pageSize As UInteger
Public minimumApplicationAddress As IntPtr
Public maximumApplicationAddress As IntPtr
Public activeProcessorMask As IntPtr
Public numberOfProcessors As UInteger
Public processorType As UInteger
Public allocationGranularity As UInteger
Public processorLevel As System.UInt16
Public processorRevision As System.UInt16
End Structure
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
' getting minimum & maximum address
Dim sys_info As SYSTEM_INFO
GetSystemInfo(sys_info)
Dim proc_min_address As IntPtr = sys_info.minimumApplicationAddress
Dim proc_max_address As IntPtr = sys_info.maximumApplicationAddress
' saving the values as long ints so I won't have to do a lot of casts later
Dim proc_min_address_l As Long = CType(proc_min_address, Long)
Dim proc_max_address_l As Long = CType(proc_max_address, Long)
' notepad better be runnin'
Dim process As Process = Process.GetProcessesByName("ETABS")(0)
' opening the process with desired access level
Dim processHandle As IntPtr = OpenProcess((PROCESS_QUERY_INFORMATION Or PROCESS_WM_READ), False, process.Id)
Dim sw As StreamWriter = New StreamWriter("dump.txt")
' this will store any information we get from VirtualQueryEx()
Dim mem_basic_info As MEMORY_BASIC_INFORMATION = New MEMORY_BASIC_INFORMATION
Dim bytesRead As Integer = 0
' number of bytes read with ReadProcessMemory
While (proc_min_address_l < proc_max_address_l)
' 28 = sizeof(MEMORY_BASIC_INFORMATION)
VirtualQueryEx(processHandle, proc_min_address, mem_basic_info, 28)
' if this memory chunk is accessible
If ((mem_basic_info.Protect = PAGE_READWRITE) AndAlso (mem_basic_info.State = MEM_COMMIT)) Then
Dim buffer() As Byte = New Byte((mem_basic_info.RegionSize) - 1) {}
' read everything in the buffer above
ReadProcessMemory(CType(processHandle, Integer), mem_basic_info.BaseAddress, buffer, mem_basic_info.RegionSize, bytesRead)
' then output this in the file
Dim i As Integer = 0
Do While (i < mem_basic_info.RegionSize)
'sw.WriteLine("0x{0} : {1}", (mem_basic_info.BaseAddress + i).ToString("X"), CType(buffer(i), Char))
sw.WriteLine("0x{0} : {1}", (mem_basic_info.BaseAddress + i).ToString("X"), Microsoft.VisualBasic.AscW(buffer(i)))
i = (i + 1)
Loop
End If
' move to the next memory chunk
proc_min_address_l = (proc_min_address_l + mem_basic_info.RegionSize)
proc_min_address = New IntPtr(proc_min_address_l)
End While
sw.Close()
Console.ReadLine()
End Sub
End Class