3leven (07-05-2013),Geometrical (09-18-2012),hoschi111 (08-04-2012),Jorndel (06-04-2012),Larity2056 (06-04-2012),Lovroman (07-05-2013),norgor21 (08-10-2012),src36 (06-16-2013),TheMaskedOne (07-10-2013),Vamphilim (07-15-2015),xFrozzed (07-22-2012)
Someone originally asked me about how to write a float to memory and when he gave me his code, I immediately facepalmed since the decleration for WriteProcessMemory and ReadProcessMemory were completely wrong. I know it's not his fault because he probably copied from somewhere but here's my take on it.
It supports ANY 'primitive' value type, the most common one you guys will be using is probably: Integer, Single (Float) and String (string is not a primitive type but it's still supported). You can also read Byte() too (byte array), make sure to indicate how many bytes you want to read though.
Here's a full list if you're interested: Boolean, Byte, SByte, Int16 (Short), UInt16 (UShort), Int32 (Integer), UInt32 (UInteger), Int64 (Long), UInt64 (ULong), IntPtr, UIntPtr, Char, Double, and Single (Float).
Here's the code:
How do I use the code?Code:Option Strict On Imports System.Runtime.InteropServices Imports System.Text Module MemoryModule <DllImport("kernel32.dll")> _ Private Function OpenProcess(ByVal dwDesiredAccess As UInteger, <MarshalAs(UnmanagedType.Bool)> ByVal bInheritHandle As Boolean, ByVal dwProcessId As Integer) As IntPtr End Function <DllImport("kernel32.dll", SetLastError:=True)> _ Private Function WriteProcessMemory(ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, ByVal lpBuffer As Byte(), ByVal nSize As IntPtr, <Out()> ByRef lpNumberOfBytesWritten As IntPtr) As Boolean End Function <DllImport("kernel32.dll", SetLastError:=True)> _ Private Function ReadProcessMemory(ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, <Out()> ByVal lpBuffer() As Byte, ByVal dwSize As IntPtr, ByRef lpNumberOfBytesRead As IntPtr) As Boolean End Function <DllImport("kernel32.dll", SetLastError:=True)> Private Function CloseHandle(ByVal hObject As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean End Function Private Const PROCESS_VM_WRITE As UInteger = &H20 Private Const PROCESS_VM_READ As UInteger = &H10 Private Const PROCESS_VM_OPERATION As UInteger = &H8 Private Const TargetProcess As String = "iw5sp" Private ProcessHandle As IntPtr = IntPtr.Zero Private LastKnownPID As Integer = -1 Public Function ReadMemory(Of T)(ByVal address As Integer) As T Return ReadMemory(Of T)(address, 0, False) End Function Public Function ReadMemory(ByVal address As Integer, ByVal length As Integer) As Byte() Return ReadMemory(Of Byte())(address, length, False) End Function Private Function ProcessIDExists(ByVal pID As Integer) As Boolean For Each p As Process In Process.GetProcessesByName(TargetProcess) If p.ID = pID Then Return True Next Return False End Function Private Function UpdateProcessHandle() As Boolean If LastKnownPID = -1 OrElse Not ProcessIDExists(LastKnownPID) Then If ProcessHandle <> IntPtr.Zero Then CloseHandle(ProcessHandle) Dim p() As Process = Process.GetProcessesByName(TargetProcess) If p.Length = 0 Then Return False LastKnownPID = p(0).Id ProcessHandle = OpenProcess(PROCESS_VM_READ Or PROCESS_VM_WRITE Or PROCESS_VM_OPERATION, False, p(0).Id) If ProcessHandle = IntPtr.Zero Then Return False End If Return True End Function Public Function ReadMemory(Of T)(ByVal address As Integer, ByVal length As Integer, ByVal unicodeString As Boolean) As T Dim buffer() As Byte If GetType(T) Is GetType(String) Then If unicodeString Then buffer = New Byte(length * 2 - 1) {} Else buffer = New Byte(length - 1) {} ElseIf GetType(T) Is GetType(Byte()) Then buffer = New Byte(length - 1) {} Else buffer = New Byte(Marshal.SizeOf(GetType(T)) - 1) {} End If If Not UpdateProcessHandle() Then Return Nothing Dim success As Boolean = ReadProcessMemory(ProcessHandle, New IntPtr(address), buffer, New IntPtr(buffer.Length), IntPtr.Zero) If Not success Then Return Nothing If GetType(T) Is GetType(Byte()) Then Return CType(CType(buffer, Object), T) If GetType(T) Is GetType(String) Then If unicodeString Then Return CType(CType(Encoding.Unicode.GetString(buffer), Object), T) Return CType(CType(Encoding.ASCII.GetString(buffer), Object), T) End If Dim gcHandle As GCHandle = gcHandle.Alloc(buffer, GCHandleType.Pinned) Dim returnObject As T returnObject = CType(Marshal.PtrToStructure(gcHandle.AddrOfPinnedObject, GetType(T)), T) gcHandle.Free() Return returnObject End Function Private Function GetObjectBytes(ByVal value As Object) As Byte() If value.GetType() Is GetType(Byte()) Then Return CType(value, Byte()) Dim buffer(Marshal.SizeOf(value) - 1) As Byte Dim ptr As IntPtr = Marshal.AllocHGlobal(buffer.Length) Marshal.StructureToPtr(value, ptr, True) Marshal.Copy(ptr, buffer, 0, buffer.Length) Marshal.FreeHGlobal(ptr) Return buffer End Function Public Function WriteMemory(ByVal address As Integer, ByVal value As Object) As Boolean Return WriteMemory(address, value, False) End Function Public Function WriteMemory(ByVal address As Integer, ByVal value As Object, ByVal unicode As Boolean) As Boolean If Not UpdateProcessHandle() Then Return False Dim buffer() As Byte If TypeOf value Is String Then If unicode Then buffer = Encoding.Unicode.GetBytes(value.ToString()) Else buffer = Encoding.ASCII.GetBytes(value.ToString()) Else buffer = GetObjectBytes(value) End If Dim result As Boolean = WriteProcessMemory(ProcessHandle, New IntPtr(address), buffer, New IntPtr(buffer.Length), IntPtr.Zero) Return result End Function End Module
Right-click on your project and Add a new module. Then copy and paste the code from the box into the screen. If you want to use this module on another process, replace "iw5sp" with whatever you want next to 'TargetProcess'.
I've created a few functions for you guys. To check if a process is running, use the UpdateProcessHandle() function. For example (in a timer):
Now, here's how to read/write memory using this module:Code:Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick If UpdateProcessHandle() Then ' Check if the game is running ' Do stuff here, like writing/reading memory or telling a user in a Label the game is open. End If End Sub
Dim myIntValue As Integer = ReadMemory(Of Integer)(&H12345678) ' Reads the value from 0x12345678 as an Integer
Dim myFloatValue As Single = ReadMemory(Of Single)(&H12345678) ' Reads the value from 0x12345678 as a Single (remember that Single is the same as Float)
Dim myASCIIStringValue As String = ReadMemory(Of String)(&H12345678, 10, False) ' Reads 10 characters at 0x12345678 as a ASCII String
Dim myUnicodeStringValue As String = ReadMemory(Of String)(&H12345678, 10, True) ' Reads 10 characters at 0x12345678 as a Unicode String
Dim myByteData() As Byte = ReadMemory(&H12345678, 12) ' Reads 12 bytes from 0x12345678
WriteMemory(&H12345678, 10I) ' Writes 10 as an Integer to 0x12345678, take note of the I at the end (it's optional but you can put it there just incase)
WriteMemory(&H12345678, 0.5F) ' Writes 0.5 as a Single to 0x12345678, take note of the F at the end! (you MUST do this or it will assume it's a Double!)
WriteMemory(&H12345678, "Hello World", False) ' Writes Hello World as an ASCII string to 0x12345678
WriteMemory(&H12345678, "Hello World", True) ' Writes Hello World as a Unicode string to 0x12345678
WriteMemory(&H12345678, New Byte() { &H90, &H90, &H90, &H90 }) ' Writes '0x90, 0x90, 0x90, 0x90' as a byte array to 0x12345678
How do I write a number into memory if I'm going to get it from a text box?
It is extremely important that you let VB.NET know what type you want to write into memory otherwise it may assume and you might get some nasty results, here's how you can do it:
However, if you are 100% sure that whatever inside a box is a number and not letters you can do this:Code:Dim valueToWrite As Integer If Integer.TryParse(TextBox1.Text, valueToWrite) Then ' Try to convert the text into an Integer WriteMemory(&H12345678, valueToWrite) End If Dim floatValueToWrite As Single If Single.TryParse(TextBox2.Text, valueToWrite) Then ' Try convert the text into a Single WriteMemory(&H12345678, floatValueToWrite) End If
What's the difference between a ASCII and Unicode string?Code:WriteMemory(&H12345678, CInt(TextBox1.Text)) ' Writes the value inside a TextBox as a Integer WriteMemory(&H12345678, CSng(TextBox2.Text)) ' Writes the value inside a TextBox as a Single
Unicode strings use 2 bytes for every letter it uses and ASCII only uses 1 byte for every letter. If you find a string in memory with Cheat Engine with the Unicode box unticked then it's a ASCII string. If the Unicode box is ticked then it's a Unicode string.
Last edited by master131; 07-09-2013 at 10:00 PM.
Donate:
BTC: 1GEny3y5tsYfw8E8A45upK6PKVAEcUDNv9
Handy Tools/Hacks:
Extreme Injector v3.7.3
A powerful and advanced injector in a simple GUI.
Can scramble DLLs on injection making them harder to detect and even make detected hacks work again!
Minion Since: 13th January 2011
Moderator Since: 6th May 2011
Global Moderator Since: 29th April 2012
Super User/Unknown Since: 23rd July 2013
'Game Hacking' Team Since: 30th July 2013
--My Art--
[Roxas - Pixel Art, WIP]
[Natsu - Drawn]
[Natsu - Coloured]
All drawings are coloured using Photoshop.
--Gifts--
[Kyle]
3leven (07-05-2013),Geometrical (09-18-2012),hoschi111 (08-04-2012),Jorndel (06-04-2012),Larity2056 (06-04-2012),Lovroman (07-05-2013),norgor21 (08-10-2012),src36 (06-16-2013),TheMaskedOne (07-10-2013),Vamphilim (07-15-2015),xFrozzed (07-22-2012)
Nice work Master
Thats for that awesome source.
Everything works fine, except reading the adresse as string.
as example:
Returns an error here:Code:Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim mystring As String = ReadMemory(Of String)(&H1D07CBC, 231, False) End Sub
=> MissingMethodExceptionCode:Public Function ReadMemory(Of T)(ByVal address As Integer, ByVal length As Integer, ByVal unicodeString As Boolean) As T Dim buffer() As Byte If GetType(T) Is GetType(String) Then If unicodeString Then buffer = New Byte(length * 2 - 1) {} Else buffer = New Byte(length - 1) {} ElseIf GetType(T) Is GetType(Byte()) Then buffer = New Byte(length - 1) {} Else buffer = New Byte(Marshal.SizeOf(GetType(T)) - 1) {} End If If Not UpdateProcessHandle() Then Return Nothing Dim success As Boolean = ReadProcessMemory(ProcessHandle, New IntPtr(address), buffer, New IntPtr(buffer.Length), IntPtr.Zero) If Not success Then Return Nothing If GetType(T) Is GetType(Byte()) Then Return CType(CType(buffer, Object), T) Dim gcHandle As GCHandle = gcHandle.Alloc(buffer, GCHandleType.Pinned) Dim returnObject As T returnObject = CType(Marshal.PtrToStructure(gcHandle.AddrOfPinnedObject, GetType(T)), T) gcHandle.Free() Return returnObject End Function
I'm thankful for any solution.
Btw, a bad solution is returning a bytearray which will be enocoded as string with an external function.
Last edited by hoschi111; 08-04-2012 at 04:58 PM. Reason: Grammar Nazi
Hello, i have a question, how to use pointers with "ReadMemory()"?
Also, i am getting the => MissingMethodException too.
Thanks in advance.
Last edited by norgor21; 08-10-2012 at 05:27 AM.
People where saying that strings weren't working, I've fixed it now. Also, if strings still have some of the old text at the end, please make sure to add vbNullChar at the end of the string.
Example:
WriteMemory(&H12345678, "Hello World" + vbNullChar, False)
Last edited by master131; 07-10-2013 at 07:43 PM.
Donate:
BTC: 1GEny3y5tsYfw8E8A45upK6PKVAEcUDNv9
Handy Tools/Hacks:
Extreme Injector v3.7.3
A powerful and advanced injector in a simple GUI.
Can scramble DLLs on injection making them harder to detect and even make detected hacks work again!
Minion Since: 13th January 2011
Moderator Since: 6th May 2011
Global Moderator Since: 29th April 2012
Super User/Unknown Since: 23rd July 2013
'Game Hacking' Team Since: 30th July 2013
--My Art--
[Roxas - Pixel Art, WIP]
[Natsu - Drawn]
[Natsu - Coloured]
All drawings are coloured using Photoshop.
--Gifts--
[Kyle]
TheMaskedOne (08-12-2013)