Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


[VB.NET] Search for array of bytes, & return Address

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming
View previous topic :: View next topic  
Author Message
DTeCH
Newbie cheater
Reputation: 0

Joined: 19 Jul 2013
Posts: 23
Location: Cayman Islands

PostPosted: Tue Oct 08, 2013 6:53 am    Post subject: [VB.NET] Search for array of bytes, & return Address Reply with quote

Hey guys Smile


I have been trying alot of different projects found online, but have not managed to get a workable project built.

All of the online projects tend to be done with the core reason for making it being an overwhelming one sided assumption that all users will use pointers, or some type of base address which is not correct to think. Not all programs can be targeted with base pointers.

In my case, the locations change every time the game is loaded, so I require the need to scan for the location first... THEN continue from there.

I have tried BlackMagic-1.1, & it seems to allow the locating of addresses, & it does so rather quickly (suprisingly fast! Very Happy), however, I am not familiar whith what functions are usually used to complete my desired goals.

I have found that with BlackMagic1.1, you pass a string value with a hex string (with spaces - like "00 B8 00 00 F1 86 29 C7...") along with a mask string (like: "?x??xxxx") to the FindPattern function like this (With just a multiline textbox, & a button on a new project form):

Code:
Imports System.Collections.Generic
imports System.Diagnostics
imports System.Text
Imports Magic

Public Class Form1

    Private Const find_PATTERN As String = "54 68 69 73 49 73 54 65 73 74 41 00 00 00 00" ' ThisIsTestA
    Private Const find_MASK As String = "xxxxxxxxxxx????"
    Private WithEvents Timer1 As System.Timers.Timer
   
    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
      Dim ThisIsTestB_Bytes() As Byte = {&H54, &H68, &H69, &H73, &H49, &H73, &H54, &H65, &H73, &H74, &H42, &H00, &H00, &H00, &H00} 'ThisIsTestB in Bytes
        Dim dwCodeLoc As UInt32
        Dim bmGame As BlackMagic = New BlackMagic()
        If (bmGame.OpenProcessAndThread(SProcess.GetProcessFromProcessName("plugin-container"))) Then 'Firefox
         TextBox1.Text = bmGame.GetModuleFilePath() & vbCrLf

         Dim dt As DateTime = DateTime.Now
         dwCodeLoc = bmGame.FindPattern(find_PATTERN, find_MASK)
         
         Dim dwCodeLocStr As String = "&H" & dwCodeLoc '<==== &H & the UInt number, or should it be &H & the HEX version of the UInt number "&H" & Hex(dwCodeLoc), or even just Hex Hex(dwCodeLoc), or UInt version with no &H???
         
         ' I've experimented with different ways of reading from that location (address)
         TextBox1.Text += bmGame.ReadASCIIString(dwCodeLocStr, 15) & vbCrLf
         Dim tmpByte() As Byte = MemMod.ReadMemory(dwCodeLocStr, 15)
         TextBox1.Text += Encoding.ASCII.GetString(tmpByte) & vbCrLf
         TextBox1.Text += bmGame.ReadBytes(dwCodeLocStr, 15) & vbCrLf ' Encoding.ASCII.GetString(MemMod.ReadMemory(dwCodeLoc, "e_rare_rubber_duck_ticket".Length)) & vbCrLf
         
         TextBox1.Text += "Pattern found in " & DateTime.Now.Subtract(dt).TotalMilliseconds & "ms" & vbCrLf
         
         TextBox1.Text += "Code location: " & dwCodeLocStr & vbCrLf
         TextBox1.Text += "find_PATTERN: " & bmGame.ReadUInt(dwCodeLocStr + &H16) & vbCrLf
         TextBox1.Text += "CURMGR_OFFSET: " & bmGame.ReadUInt(dwCodeLocStr + &H1C) & vbCrLf
         
         TextBox1.Text += Encoding.ASCII.GetString(tmpByte) & vbCrLf
         
         ' I've experimented with different ways of writing to that location (address)
         bmGame.WriteASCIIString(dwCodeLoc, "ThisIsTestB")
         'bmGame.WriteBytes(dwCodeLoc, ThisIsTestB_Bytes, 15) ', RubberDucks)
         'MemMod.WriteMemory(dwCodeLocStr, "ThisIsTestB" + vbNullChar, True)
         'MemMod.WriteMemory(dwCodeLocStr, ThisIsTestB_Bytes)
         dwCodeLoc = 0
         
         ' Check to see if ThisIsTestA is till at the first detected location
         dwCodeLoc = bmGame.FindPattern(find_PATTERN, find_MASK) 'Finds ThisIsTestA at the same location as before even though I attempted to overwrite it with ThisIsTestB string already.
         TextBox1.Text += dwCodeLocStr & vbCrLf
         TextBox1.Text += Encoding.ASCII.GetString(MemMod.ReadMemory(dwCodeLocStr, 15)) & vbCrLf
         TextBox1.Text += bmGame.ReadASCIIString(dwCodeLocStr, 15) & vbCrLf
         TextBox1.Text += Encoding.ASCII.GetString(MemMod.ReadMemory(dwCodeLoc, "ThisIsTestB".Length)) & vbCrLf
      Else
         TextBox1.Text = "Game could not be opened for read/write." & vbCrLf
      End If
      TextBox1.Text += "Test Done."
    End Sub
   
   
    Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        Timer1 = New System.Timers.Timer
        Timer1.Enabled = True
        Timer1.Interval = 1000
        Timer1.Start() ' = True
        GC.Collect()
    End Sub

    Private Sub Timer1_Elapsed(sender As Object, e As System.Timers.ElapsedEventArgs) Handles Timer1.Elapsed
        If MemMod.UpdateProcessHandlePublic() Then ' Check if the game is running
            picBrowser1.Image = ImageList1.Images.Item(1)
            picBrowser1.Invalidate()
            picBrowser1.Refresh()
        Else
            picBrowser1.Image = ImageList1.Images.Item(0)
            picBrowser1.Invalidate()
            picBrowser1.Refresh()
        End If
    End Sub
   
End Class


...with this module added for the MemMod functions:

Code:
Option Strict On

Imports System.Runtime.InteropServices
Imports System.Text

Module MemMod
    <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
    Public TargetProcess As String = "plugin-container" 'Firefox
    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

    Public Function UpdateProcessHandlePublic() 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

    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



One of the configuration was able to return a string of crap though, but right now I can't remeber how it was that produced results. I assumed that the address format was wrong, & caused the crap to be returned instead, but as I said, I do not remember the configuration that did it.

I commented out all the above except MemMod module (used for my Game process checks by the timer), & removed the references to BlackMagic... replacing it with ManagedWinapi.dll from GitHub, & tested another function:

Code:

Imports System.Collections.Generic
imports System.Diagnostics
imports System.Text

Public Class Form1

    Private Const find_PATTERN As String = "54 68 69 73 49 73 54 65 73 74 41 00 00 00 00" ' ThisIsTestA
    Private Const find_MASK As String = "xxxxxxxxxxx????"
    Private WithEvents Timer1 As System.Timers.Timer



    Private Shared Function GetMemoryAddressOfString(searchedBytes As Byte(), p As Process) As Integer
        'List<int> addrList = new List<int>();
        Dim addr As Integer = 0
        Dim speed As Integer = 1024 * 64
        Dim j As Integer = &H400000
        While j < &H7FFFFFFF
            Dim mem As ManagedWinapi.ProcessMemoryChunk = New ManagedWinapi.ProcessMemoryChunk(p, j, speed + searchedBytes.Length)

            Dim bigMem As Byte() = mem.Read()

            For k As Integer = 0 To bigMem.Length - searchedBytes.Length - 1
                Dim found As Boolean = True
                For l As Integer = 0 To searchedBytes.Length - 1
                    If bigMem(k + l) <> searchedBytes(l) Then
                        found = False
                        Exit For
                    End If
                Next
                If found Then
                    addr = k + j
                    Exit For
                End If
            Next
            If addr <> 0 Then
                'addrList.Add(addr);
                'addr = 0;
                Exit While
            End If
            j += speed
        End While
        'return addrList;
        Return addr
    End Function


    Private Sub Timer1_Elapsed(sender As Object, e As System.Timers.ElapsedEventArgs) Handles Timer1.Elapsed
        If MemMod.UpdateProcessHandlePublic() Then ' Check if the game is running
            picBrowser1.Image = ImageList1.Images.Item(1)
            picBrowser1.Invalidate()
            picBrowser1.Refresh()
        Else
            picBrowser1.Image = ImageList1.Images.Item(0)
            picBrowser1.Invalidate()
            picBrowser1.Refresh()
        End If
    End Sub

    Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        Timer1 = New System.Timers.Timer
        Timer1.Enabled = True
        Timer1.Interval = 1000
        Timer1.Start() ' = True
        GC.Collect()
    End Sub

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        Dim tmpByte() As Byte = Encoding.ASCII.GetBytes("ThisIsTestA")
        Dim p As Process() = Process.GetProcessesByName("plugin-container")
        TextBox1.Text = GetMemoryAddressOfString(tmpByte, p(0))
    End Sub

End Class




Just like the other tests, all I seem to get in return is either "T", or "MZ?"... except for the one time I got a string of crap in return.


Can anyone check the code, see where I might have went wrong? I used BmlackMagic's test project as a template, & that's why you see:

Code:
         TextBox1.Text += "find_PATTERN: " & bmGame.ReadUInt(dwCodeLocStr + &H16) & vbCrLf
         TextBox1.Text += "CURMGR_OFFSET: " & bmGame.ReadUInt(dwCodeLocStr + &H1C) & vbCrLf


&H16, & &H1C must be something specific to the WoW game (I don't play that crap Razz), & seems to be the set offset for whatever the test project was targeting, or something like that.

Can someone with experience, & familiar with reading process memory with VS.NET show me what the obvious errors I've overlooked are? Smile

ps: I know the Address/Location is probably the most obvious place to look, & I have tried different ways of setting it. Could just be that I just haven't set it to the right combination of settings yet to see results the way I expect. Razz


Thanks guys.


UPDATE:

The following is what I have so far, & it works for most of what I need in my .NET trainers (Except autoassembler functionality Razz)


Imports:
Code:
Imports System.Collections.Generic
Imports System.Diagnostics
Imports System.Text
Imports ManagedWinapi '<===== From GitHub (ManagedWinapi.dll)
Imports System.ComponentModel


Form:
Code:
Public Class Form1
    Private WithEvents Timer1 As System.Timers.Timer
    Private WithEvents bgWorker As New BackgroundWorker
   
    Private Shared Function GetAddressOfString(searchedBytes As Byte(), p As Process, start As UInt32) As Integer
        Dim addr As Integer = 0
        Dim speed As Integer = 1024 * 64
        Dim j As UInt32 = start '&H400000
        While j < &H7FFFFFFF
            Dim mem As ManagedWinapi.ProcessMemoryChunk = New ManagedWinapi.ProcessMemoryChunk(p, j, speed + searchedBytes.Length)

            Dim bigMem As Byte() = mem.Read()

            For k As Integer = 0 To bigMem.Length - searchedBytes.Length - 1
                Dim found As Boolean = True
                For l As Integer = 0 To searchedBytes.Length - 1
                    If bigMem(k + l) <> searchedBytes(l) Then
                        found = False
                        Exit For
                    End If
                Next
                If found Then
                    addr = k + j
                    Exit For
                End If
            Next
            If addr <> 0 Then
                Exit While
            End If
            j += speed
        End While
        Return addr
    End Function

    Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        bgWorker.WorkerReportsProgress = True
    End Sub

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
      Button1.Text = "Working..."
      Button1.Enabled = False
      bgWorker.RunWorkerAsync()
    End Sub

    Private Sub bgWorker_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles bgWorker.DoWork
        Dim tmpByte() As Byte = Encoding.ASCII.GetBytes("Hi... I'm a test string. :)")
        Dim p As Process() = Process.GetProcessesByName("plugin-container")
        Dim tmpLastAddr As String = "&H400000"
        Dim tmpAddressStr As String = ""
        WorkMessage = Nothing
        bgWorker.ReportProgress(0)

        Do Until tmpAddressStr = "&H0"
            tmpAddressStr = "&H" & Hex(GetAddressOfString(tmpByte, p(0), tmpLastAddr))
            If tmpAddressStr = "&H0" Then
                WorkMessage = "Test Done."
                bgWorker.ReportProgress(0)
                Exit Sub
            Else
                WorkMessage = tmpAddressStr & vbCrLf
                bgWorker.ReportProgress(0)
                Application.DoEvents()
                MemMod.WriteMemory(tmpAddressStr, "Hi... I'm a test string too! :)" + vbNullChar, False)
                tmpLastAddr = tmpAddressStr
            End If
        Loop
        WorkMessage = "Test Done."
        bgWorker.ReportProgress(0)
        WorkMessage = "EnableButton"
        bgWorker.ReportProgress(0)
    End Sub

    Private Sub bgWorker_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles bgWorker.ProgressChanged
      If WorkMessage = "EnableButton" then
         WorkMessage = ""
         Button1.Text = "Cheat Active"
         Button1.Enabled = True
        Else
      If WorkMessage = Nothing Then
            TextBox1.Text = ""
        Else
            TextBox1.Text += WorkMessage
        End If
        Application.DoEvents()
        End If
    End Sub
End Class



Module:
Code:
Option Strict On

Imports System.Runtime.InteropServices
Imports System.Text

Module MemMod
    Public WorkMessage As String = Nothing
    <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
    Public TargetProcess As String = "plugin-container"
    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

    Public Function UpdateProcessHandlePublic() 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

    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



It's not as fast as BlackMagic-1.1, but it does the job! Very Happy

ps: Put together with bits of code from across the net. Will add credits when I remember where I got all the bits from. Smile

_________________
Hitler... When all else fails, you'll be in the right state of mind. Jesus Saves.
Back to top
View user's profile Send private message AIM Address Yahoo Messenger
Bruj£
How do I cheat?
Reputation: 0

Joined: 24 Sep 2015
Posts: 9

PostPosted: Sat Sep 26, 2015 9:14 am    Post subject: Reply with quote

Old thread but nice tutorial and work.. Thanks.
don't work for 64bit!
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites