I have a code which I have translated the majority of for use in vb.net.
It requires: 3 Labels, 3 Text Boxes, and 1 Button (named command1)
It also has no errors in the errors list, so hopefully it should be an easy fix for the
average/experienced coder.
CODE: (full)
The errors received when running he application are:
LINE: hProcess = OpenProcess(PROCESS_READ_WRITE_QUERY, False, pid)
LINE: Call GetSystemInfo(si)
Then the application closes.
What is supposed to do is:
Command1 (Button1) Clicked: Open the calulator, look for the string in backspace,
and change it to VB-O-Matic.
Help is appreciated, Thanks. :wave:
It requires: 3 Labels, 3 Text Boxes, and 1 Button (named command1)
It also has no errors in the errors list, so hopefully it should be an easy fix for the
average/experienced coder.
CODE: (full)
Code:
Public Class Form1
Structure OSVERSIONINFO
Public dwOSVersionInfoSize As Long
Public dwMajorVersion As Long
Public dwMinorVersion As Long
Public dwBuildNumber As Long
Public dwPlatformId As Long
Public szCSDVersion As String
End Structure
Structure MEMORY_BASIC_INFORMATION ' 28 bytes
Public BaseAddress As Long
Public AllocationBase As Long
Public AllocationProtect As Long
Public RegionSize As Long
Public State As Long
Public Protect As Long
Public lType As Long
End Structure
Structure SYSTEM_INFO ' 36 Bytes
Public dwOemID As Long
Public dwPageSize As Long
Public lpMinimumApplicationAddress As Long
Public lpMaximumApplicationAddress As Long
Public dwActiveProcessorMask As Long
Public dwNumberOrfProcessors As Long
Public dwProcessorType As Long
Public dwAllocationGranularity As Long
Public wProcessorLevel As Integer
Public wProcessorRevision As Integer
End Structure
Private Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" (ByVal LpVersionInformation As OSVERSIONINFO) As Long
Private Declare Function VirtualQueryEx& Lib "kernel32" (ByVal hProcess As Long, ByVal lpAddress As Long, ByVal lpBuffer As MEMORY_BASIC_INFORMATION, ByVal dwLength As Long)
Private Declare Sub GetSystemInfo Lib "kernel32" (ByVal lpSystemInfo As SYSTEM_INFO)
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal blnheritHandle As Long, ByVal dwAppProcessId As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, ByVal lpBaseAddress As Long, ByRef lpBuffer As String, ByVal nSize As Long, ByVal lpNumberOfBytesWritten As Long) As Long
Private Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Long, ByVal lpBaseAddress As Long, ByRef lpBuffer As String, ByVal nSize As Long, ByVal lpNumberOfBytesWritten As Long) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As Long, ByRef lpdwProcessId As Long) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
Private Declare Function GetParent Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function GetWindow Lib "user32" (ByVal hWnd As Long, ByVal wCmd As Long) As Long
Const GW_HWNDNEXT = 2
Private Declare Function InvalidateRect Lib "user32" (ByVal hWnd As Long, ByVal lpRect As Long, ByVal bErase As Long) As Long
Const PROCESS_VM_READ = (&H10)
Const PROCESS_VM_WRITE = (&H20)
Const PROCESS_VM_OPERATION = (&H8)
Const PROCESS_QUERY_INFORMATION = (&H400)
Const PROCESS_READ_WRITE_QUERY = PROCESS_VM_READ + PROCESS_VM_WRITE + PROCESS_VM_OPERATION + PROCESS_QUERY_INFORMATION
Const MEM_PRIVATE& = &H20000
Const MEM_COMMIT& = &H1000
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Try
Me.Text = "Memory Scanner"
Label1.Text = "Start application:"
Label2.Text = "String to find:"
Label3.Text = "Replace with:"
TextBox1.Text = "Calc.exe"
TextBox2.Text = "Backspace"
TextBox3.Text = "VB-O-Matic"
Command1.Text = "&Launch It!"
Catch ex As Exception
MsgBox(ErrorToString, ex.ToString)
End Try
End Sub
Private Sub B1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Command1.Click
Try
Dim pid As Long, hProcess As Long, hWin As Long
Dim lpMem As Long, ret As Long, lLenMBI As Long
Dim lWritten As Long, CalcAddress As Long, lPos As Long
Dim sBuffer As String
Dim sSearchString As String, sReplaceString As String
Dim si As SYSTEM_INFO
Dim mbi As MEMORY_BASIC_INFORMATION
sSearchString = TextBox2.Text
sReplaceString = TextBox3.Text & Chr(0)
pid = Shell(TextBox1.Text) 'launch application (calc.exe in this sample)
hWin = InstanceToWnd(pid) 'get handle of launched window - only to repaint it after changes
'Open process with required access
hProcess = OpenProcess(PROCESS_READ_WRITE_QUERY, False, pid)
lLenMBI = Len(mbi)
'Determine applications memory addresses range
Call GetSystemInfo(si)
lpMem = si.lpMinimumApplicationAddress
'Scan memory
Do While lpMem < si.lpMaximumApplicationAddress
mbi.RegionSize = 0
ret = VirtualQueryEx(hProcess, lpMem, mbi, lLenMBI)
If ret = lLenMBI Then
If ((mbi.lType = MEM_PRIVATE) And (mbi.State = MEM_COMMIT)) Then ' this block is In use by this process
If mbi.RegionSize > 0 Then
sBuffer = mbi.RegionSize
'Read region into string
ReadProcessMemory(hProcess, mbi.BaseAddress, sBuffer, mbi.RegionSize, lWritten)
'Check if region contain search string
lPos = InStr(1, sBuffer, sSearchString, vbTextCompare)
If lPos Then
CalcAddress = mbi.BaseAddress + lPos
Me.Show()
ret = MsgBox("Search string was found at address " & CalcAddress & "." & vbCrLf & "Do you want to replace it?", vbInformation + vbYesNo, "VB-O-Matic")
If ret = vbYes Then
'Replace string in virtual memory
Call WriteProcessMemory(hProcess, CalcAddress - 1, sReplaceString, Len(sReplaceString), lWritten)
'Redraw window
InvalidateRect(hWin, 0, 1)
End If
Exit Do
End If
End If
End If
'Increase base address for next searching cicle. Last address may overhead max Long value (Windows use 2GB memory, which is near max long value), so add Error checking
lpMem = mbi.BaseAddress + mbi.RegionSize
Else
Exit Do
End If
Loop
Catch ex As Exception
MsgBox(ErrorToString, ex.ToString)
End Try
End Sub
Private Function InstanceToWnd(ByVal target_pid As Long) As Long
Try
Dim test_hwnd As Long
Dim test_pid As Long
Dim test_thread_id As Long
test_hwnd = FindWindow(0&, 0&)
Do While test_hwnd <> 0
If GetParent(test_hwnd) = 0 Then
test_thread_id = GetWindowThreadProcessId(test_hwnd, test_pid)
If test_pid = target_pid Then
InstanceToWnd = test_hwnd
Exit Do
End If
End If
test_hwnd = GetWindow(test_hwnd, GW_HWNDNEXT)
Loop
Catch ex As Exception
MsgBox(ErrorToString, ex.ToString)
End Try
End Function
End Class
LINE: hProcess = OpenProcess(PROCESS_READ_WRITE_QUERY, False, pid)
Code:
Managed Debugging Assistant 'PInvokeStackImbalance' has detected a problem in 'C:\Documents and Settings\User X\My Documents\Visual Studio 2010\Projects\Memory Scanner\Memory Scanner\bin\Debug\Memory Scanner.vshost.exe'.
Additional Information: A call to PInvoke function 'Memory Scanner!Memory_Scanner.Form1::OpenProcess' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.
Code:
An unhandled exception of type 'System.AccessViolationException' occurred in Memory Scanner.exe
Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
What is supposed to do is:
Command1 (Button1) Clicked: Open the calulator, look for the string in backspace,
and change it to VB-O-Matic.
Help is appreciated, Thanks. :wave: