Reading/Writing Process Memory (VB.NET 2005)

Post here about scripting and programming for HaloPC (audio, network, ai, etc.)
Post Reply
ugly-nerd





Posts: 23
Joined: Sat May 21, 2005 6:51 am

Reading/Writing Process Memory (VB.NET 2005)

Post by ugly-nerd »

Download Link:
http://rapidshare.de/files/25558056/Nam ... o.rar.html

In this tutorial I used Warcraft III as an example.

Code: Select all

    Public Sub WriteName()
        'Try

        'Catch ex As Exception

        'End Try

        'That means it will try to do the function, if it cant and gets an error it will do whats below of 'Catch ex As Exception'
        'In our case, we want to message box the exception.
        Try
            'We declare Address as an integer (or number(s)), and vBuffer as Long.
            'A Long is for longer integers. Integers can only store a maximum number. Longs can store much more.
            Dim Address As Integer, vBuffer As Long
            'We declare enc as an ASCIIEncoding. We use this to translate vBuffer into characters (or readable letters).
            Dim enc As New System.Text.ASCIIEncoding
            'Now we retreive the process for Warcraft III. (war3.exe)
            Dim myProcesses As Process() = Process.GetProcessesByName("war3")
            'If Warcraft III isnt running, then the length of it would be 0.
            If myProcesses.Length = 0 Then
                'So if it is 0 (or isnt running), we need to let the user know that isnt running.
                'We do this by making the label "Status" say that Warcraft III isnt running.
                Status.Text = "Warcraft III is not running."
                'Then, we dont want to keep going or we will get an arithmatic overflow, so we have to exit the sub.
                Exit Sub
            End If
            'Now since Warcraft III is running, we need to make sure we can access the process.
            'We use processHandle and open the process of Warcaft III for reading and writing.
            Dim processHandle As IntPtr = OpenProcess(PROCESS_ALL_ACCESS, 0, myProcesses(0).Id)
            'If we cant access the process, then processHandle will equal IntPtr.Zero (0)
            If processHandle = IntPtr.Zero Then
                'Now if we cant access the process, we need to let the user know. We do this by changing the status label's text.
                Status.Text = "Failed to open Warcraft III process."
                Exit Sub
            End If
            'Since we know that we can always find "3RAW 0" (ROC) or "PX3W 0" (TFT) at an offset that ends with HEX 2D4 or DEC 724.
            'We need to start reading at HEX 2D4 or DEC 724.
            'If we dont read either of those values, we need to increase the Address by DEC 65536 or HEX 10000.
            'We keep doing this (looping) until we reach one of those values, and then the code tells us to 'Exit Do' which means we will exit the loop, now that we have our value.
            Address = 724
            'Do

            'Loop

            'That does the functions inbetween it until the user uses Exit Do.

            Do
                'We are going to use ReadProcessMemory(process, offet (or where we can find those values, vBuffer (returns what it has read), Length to read, Byte Written)
                'We use processHandle (war3.exe), the Address starts at HEX 2D4 or DEC 724 and increases by DEC 65536 or HEX 10000 until it reads the correct value, we are reading 4 bytes since 3RAW 0 and PX3W 0 converted to a 4 byte integer is DEC 1463898675 or DEC 1462982736.
                ReadProcessMemory(processHandle, Address, vBuffer, 4, 0)
                'Now that we have ReadProcessMemory at the certain Address, we need to make sure its the right Address.
                'We do this by checking if vBuffer is equal to 3RAW 0 or PX3W 0 in a 4 byte integer.
                If vBuffer = 1463898675 Then
                    'If it is 3RAW 0 then we need to change our icon to ROC icon.
                    Me.Icon = My.Resources.ROC
                    'And the system tray icon..
                    NotifyIcon.Icon = My.Resources.ROC
                    'Now we need to subtract HEX 20 or DEC 32 from the address, because thats how far back our name location starts.
                    'So HEX 2D4 or DEC 724 - HEX 20 or DEC 32 is where our name location is located.
                    Address -= 32
                    'Now we dont want to keep reading memory until we reach the end (which will give you the arithmatic overflow)
                    'So we Exit the loop with Exit Do.
                    Exit Do
                ElseIf vBuffer = 1462982736 Then
                    'If vBuffer isnt 3RAW 0, we still have a chance of the user using TFT, so we check if it is PX3W 0.
                    'If it is... Then we need to change our icon to TFT.
                    Me.Icon = My.Resources.TFT
                    NotifyIcon.Icon = My.Resources.TFT
                    'And subtract HEX 20 ir DEC 32 from the Address, that way we get our name location (offset).
                    Address -= 32
                    'We dont want to keep looping, so we Exit the loop with Exit Do.
                    Exit Do
                Else
                    'If we still dont have the right address (or offset) then we need to add HEX 10000 or DEC 65536 to it until we finally get the right Address.
                    Address += 65536
                    'If we never get the right address, then the user is probully not logged into Battle.net, or he changed the value of 3RAW 0 or P3XW 0.
                End If
            Loop
            'Now that we have our name offset, we need to write the new name at the offset.
            'We do this by taking each letter of the new name textbox and adding it at the Address of the name.
            'Since we are only writing 1 byte, that means we will have to add 1 to the Address each time, so we arent overwriting our last byte at the same exact offset.
            'We do this by starting at 0 (i), and looping until i = the number of characters in the new name textbox - 1.
            'We start at 0 because we dont want to add 1 to the name address right off the bat, or else you would have the old character of your last name, at the very front of your new name.
            'We subtrasct 1 from the new name textbox because we dont need to write a blank offset to the end of the address. Thats why we have the 'For i As Integer = Len(newName.Text)'
            For i As Integer = 0 To Len(NewName.Text) - 1
                'This will write the new name at the address.
                'Asc converts the String (which is the new name, newname.text textbox) to an integer.
                'Mid(Str As String, Start As Integer, Length As Integer) will return the one letter from the String inputted.
                WriteProcessMemory(processHandle, Address + i, Asc(Mid(NewName.Text, i + 1, 1)), 1, 0)
            Next
            'Now we need to null the left over bytes. The number of left over bytes is equal to 14 - the number of characters in the new name textbox.
            'So we start our loop where we left off (above) and we do it until we reach 14.
            For i As Integer = Len(NewName.Text) To 14
                'We add i to the Address (that way we are writing at the right address (or offset).
                'We are writing 0 (null), the length of it is 1, and the number of bytes written is 0.
                WriteProcessMemory(processHandle, Address + i, 0, 1, 0)
            Next
            'Since we have gotten this far, we have done all those functions successfully.
            'So we change the CurrentName textbox to the new name.
            CurrentName.Text = NewName.Text
            'And we let the user know that Warcraft III is still running.
            Status.Text = "Warcraft III is running."
            'So we dont get any errors when playing Warcraft III, we need to close the process from our reading and writing.
            CloseHandle(processHandle)
        Catch ex As Exception
            'If we ever happen to get an error, we will catch the error as an exception, then let the user know by making the status label's text equal to the error. (exception.message)
            Status.Text = ex.Message
            'Then we need to exit the sub so we dont get any more errors.
            Exit Sub
        End Try
    End Sub

    Public Sub GetName()
        'From here too where I put END, is where its the same as above.
        Try
            Dim Address As Integer, vBuffer As Long
            Dim enc As New System.Text.ASCIIEncoding
            Dim myProcesses As Process() = Process.GetProcessesByName("war3")
            If myProcesses.Length = 0 Then
                Status.Text = "Warcraft III is not running."
                Exit Sub
            End If
            Dim processHandle As IntPtr = OpenProcess(PROCESS_ALL_ACCESS, 0, myProcesses(0).Id)
            If processHandle = IntPtr.Zero Then
                Status.Text = "Failed to open Warcraft III process."
                Exit Sub
            End If
            Address = 724
            Do
                ReadProcessMemory(processHandle, Address, vBuffer, 4, 0)
                If vBuffer = 1463898675 Then
                    Me.Icon = My.Resources.ROC
                    NotifyIcon.Icon = My.Resources.ROC
                    Address -= 32
                    Exit Do
                ElseIf vBuffer = 1462982736 Then
                    Me.Icon = My.Resources.TFT
                    NotifyIcon.Icon = My.Resources.TFT
                    Address -= 32
                    Exit Do
                Else
                    Address += 65536
                End If
            Loop
            'END
            'Below this is what has changed from WriteName.
            'We declare ret as a Byte Array. We declare it as an array by putting () after Byte.
            Dim ret As Byte() = Nothing
            'We make sure that the CurrentName textbox is nothing. That way when we are converting the integer to a string, we arent &='ing onto the textbox.
            CurrentName.Text = ""
            'We are now going to start our loop, increase the Address by 1 each time, and read the process memory.
            For i As Integer = 0 To 15
                'Read the memory.
                ReadProcessMemory(processHandle, Address + i, vBuffer, 1, 0)
                'Now we need to take vBuffer and get the bytes from it.
                ret = BitConverter.GetBytes(vBuffer)
                'Then convert ret to a readable string.
                'Then we add the new string to the Current Name textbox.
                CurrentName.Text &= System.Text.Encoding.ASCII.GetString(ret).Replace("RAW", "")
            Next
            'Then we close the process so warcraft III doesnt get any errors.
            CloseHandle(processHandle)
            'Then we need to let the user know that Warcraft III is running fine.
            Status.Text = "Warcraft III is running."
        Catch ex As Exception
            'If we happen to get any errors, we will set the status label's text to the exceptions (error) (ex.message).
            Status.Text = ex.Message
            'Then we need to exit the sub so we dont get any more errors.
            Exit Sub
        End Try
    End Sub
Zenaku213





Posts: 185
Joined: Thu Jun 02, 2005 12:09 pm
Location: In your walls.

Post by Zenaku213 »

Very nice tutorial, this is somewhat similar to Locke's memory hacks.
CLuis wrote:Being goth is a disease.
All those losers in gym must have it then.
Patrickssj6




Pi Collaborator

Posts: 5426
Joined: Sat Jul 24, 2004 12:12 pm
Location: I'm a Paranoid
Contact:

Post by Patrickssj6 »

I had the code for VB6 from BB.I will look through it.Very nice :D
...left for good
Post Reply