I keep seeing posts like "You can't do hacks in VB.Net noob, learn c++". While it's true that having your code rely on CLR sets some boundaries(for instance you can't inject managed code into unmanaged processes), .Net is just as capable of calling windows API as any other language runtime. And guess what? Accessing a processes memory is Windows API stuff.
Alright, let's start. At this point I'm going to assume you already know what is a memory address and how to find one.
If not, take this tutorial about memory addresses first, and then come back here.
It's a simple c++ console application with a static variable which you can increase or decrease by typing in +/- and pressing enter. The variable will not increase after 10. We are going to use VB.Net to set that value to 100.
First you want to find the memory address of the variable. It's generally good practice to find it yourself, but in case you feel you already handle that part well enough, I'm going to save you some time by telling you that it is...
[SPOILER]
0x0419004
[/SPOILER]
Create a new Windows Forms project and add 2 buttons to your form: "Read Memory" and "Write Memory".
Now add a new Module to your project and call it Memory.vb.
Copy this code in the Module:
Code:
Imports System.Runtime.InteropServices
Module Memory
<DllImport("kernel32.dll")> _
Public Function ReadProcessMemory(ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, <[In](), Out()> ByVal buffer As Byte(), ByVal size As UInt32, ByRef lpNumberOfBytesRead As IntPtr) As Int32
End Function
<DllImport("kernel32.dll")> _
Public Function WriteProcessMemory(ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, <[In](), Out()> ByVal buffer As Byte(), ByVal size As UInt32, ByRef lpNumberOfBytesWritten As IntPtr) As Int32
End Function
Public Function WriteInt32(ByVal P As Process, ByVal memAdr As Int32, ByVal value As Integer) As Boolean
Return WriteBytes(P, memAdr, BitConverter.GetBytes(value), 4)
End Function
Public Function ReadInt32(ByVal P As Process, ByVal memAdr As Int32) As Integer
Return BitConverter.ToInt32(ReadBytes(P, memAdr, 4), 0)
End Function
Private Function ReadBytes(ByVal P As Process, ByVal memAdr As Long, ByVal bytesToRead As UInteger) As Byte()
Dim ptrBytesRead As IntPtr
Dim buffer As Byte() = New Byte(bytesToRead - 1) {}
ReadProcessMemory(P.Handle, New IntPtr(memAdr), buffer, bytesToRead, ptrBytesRead)
Return buffer
End Function
Private Function WriteBytes(ByVal P As Process, ByVal memAdr As Long, ByVal bytes As Byte(), ByVal length As UInteger) As Boolean
Dim bytesWritten As IntPtr
Dim result As Integer = WriteProcessMemory(P.Handle, New IntPtr(memAdr), bytes, length, bytesWritten)
Return result <> 0
End Function
End Module
Now you have the API calls and simple wrapper functions declared.
Copy this code in the first("read memory") button's click event handler:
Code:
Dim p As Process = Nothing
If Process.GetProcessesByName("HackMe").Count > 0 Then
p = Process.GetProcessesByName("HackMe")(0)
Else
MessageBox.Show("HackMe not open!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning)
Exit Sub
End If
Dim Adr As Int32 = &H419004
Try
Dim Variable As Int32 = Memory.ReadInt32(p, &H419004)
MessageBox.Show("Variable: " & Variable.ToString, "Memory Read Successful", MessageBoxButtons.OK) Catch ex As Exception
MessageBox.Show("Reading memory failed: " & vbCrLf & ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning)
End Try
First we looked for the process by name("HackMe"). If found, we tried to read from our memory address and display the result.
Now for the final part, writing memory and accomplishing our goal. Copy this code to the second buttons("write memory") click event handler:
Code:
Dim p As Process = Nothing
If Process.GetProcessesByName("HackMe").Count > 0 Then
p = Process.GetProcessesByName("HackMe")(0)
Else
MessageBox.Show("HackMe not open!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning)
Exit Sub
End If
Dim Adr As Int32 = &H419004
Try
If WriteInt32(p, Adr, 100) Then
MessageBox.Show("Variable set to 100.", "Memory Write Successful", MessageBoxButtons.OK)
Else
MessageBox.Show("Writing memory failed!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning)
End If
Catch ex As Exception
MessageBox.Show("Writing memory failed: " & vbCrLf & ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning)
End Try
Compile and run. Try the buttons...
...and hit Enter in HackMe to see if it worked:
Hassan's Edit: Outside links are not allowed and are removed.