Help With Memory Editor Class - Using Pointers And offsets

Posts 1–11 of 11 · Page 1 of 1
Help With Memory Editor Class - Using Pointers And offsets
Hello Guys.
I have been trying to use this memory editor class, but I can't seem to get it to work:
Code:
'VB.NET Module
'Author : Cless
'How to use Read/Write Pointer
'Example Read
'       Me.Text = ReadPointerInteger(Game exe name, &HPointer,&HOffset).ToString()
'
'       Me.Text = ReadPointerInteger("gta_sa", &HB71A38,&H540).ToString()
'       Or
'       Me.Text = ReadPointerInteger("gta_sa", &HB71A38,&H540,&H544).ToString()
'Example Write
'       WritePointerInteger(Game exe name,&HPointer,Value,&HOffset)
'
'       WritePointerInteger("gta_sa",&HB71A38,1000,&H540)
'       Or
'       WritePointerInteger("gta_sa",&HB71A38,1000,&H540, &H544)

Module Trainer
    Private Declare Function ReadMemoryByte Lib "kernel32" Alias "ReadProcessMemory" (ByVal Handle As Integer, ByVal Address As Integer, ByRef Value As Byte, Optional ByVal Size As Integer = 2, Optional ByRef Bytes As Integer = 0) As Byte
    Private Declare Function ReadMemoryInteger Lib "kernel32" Alias "ReadProcessMemory" (ByVal Handle As Integer, ByVal Address As Integer, ByRef Value As Integer, Optional ByVal Size As Integer = 4, Optional ByRef Bytes As Integer = 0) As Integer
    Private Declare Function ReadMemoryFloat Lib "kernel32" Alias "ReadProcessMemory" (ByVal Handle As Integer, ByVal Address As Integer, ByRef Value As Single, Optional ByVal Size As Integer = 4, Optional ByRef Bytes As Integer = 0) As Single
    Private Declare Function ReadMemoryDouble Lib "kernel32" Alias "ReadProcessMemory" (ByVal Handle As Integer, ByVal Address As Integer, ByRef Value As Double, Optional ByVal Size As Integer = 8, Optional ByRef Bytes As Integer = 0) As Double

    Private Declare Function WriteMemoryByte Lib "kernel32" Alias "WriteProcessMemory" (ByVal Handle As Integer, ByVal Address As Integer, ByRef Value As Byte, Optional ByVal Size As Integer = 2, Optional ByRef Bytes As Integer = 0) As Byte
    Private Declare Function WriteMemoryInteger Lib "kernel32" Alias "WriteProcessMemory" (ByVal Handle As Integer, ByVal Address As Integer, ByRef Value As Integer, Optional ByVal Size As Integer = 4, Optional ByRef Bytes As Integer = 0) As Integer
    Private Declare Function WriteMemoryFloat Lib "kernel32" Alias "WriteProcessMemory" (ByVal Handle As Integer, ByVal Address As Integer, ByRef Value As Single, Optional ByVal Size As Integer = 2, Optional ByRef Bytes As Integer = 0) As Single
    Private Declare Function WriteMemoryDouble Lib "kernel32" Alias "WriteProcessMemory" (ByVal Handle As Integer, ByVal Address As Integer, ByRef Value As Double, Optional ByVal Size As Integer = 2, Optional ByRef Bytes As Integer = 0) As Double

    Public Function ReadByte(ByVal EXENAME As String, ByVal Address As Integer) As Byte
        Dim Value As Byte
        If Process.GetProcessesByName(EXENAME).Length <> 0 Then
            Dim Handle As Integer = Process.GetProcessesByName(EXENAME)(0).Handle
            If Handle <> 0 Then
                ReadMemoryByte(Handle, Address, Value)
            End If
        End If
        Return Value
    End Function

    Public Function ReadInteger(ByVal EXENAME As String, ByVal Address As Integer) As Integer
        Dim Value As Integer
        If Process.GetProcessesByName(EXENAME).Length <> 0 Then
            Dim Handle As Integer = Process.GetProcessesByName(EXENAME)(0).Handle
            If Handle <> 0 Then
                ReadMemoryInteger(Handle, Address, Value)
            End If
        End If
        Return Value
    End Function

    Public Function ReadFloat(ByVal EXENAME As String, ByVal Address As Integer) As Single
        Dim Value As Single
        If Process.GetProcessesByName(EXENAME).Length <> 0 Then
            Dim Handle As Integer = Process.GetProcessesByName(EXENAME)(0).Handle
            If Handle <> 0 Then
                ReadMemoryFloat(Handle, Address, Value)
            End If
        End If
        Return Value
    End Function

    Public Function ReadDouble(ByVal EXENAME As String, ByVal Address As Integer) As Double
        Dim Value As Double
        If Process.GetProcessesByName(EXENAME).Length <> 0 Then
            Dim Handle As Integer = Process.GetProcessesByName(EXENAME)(0).Handle
            If Handle <> 0 Then
                ReadMemoryByte(Handle, Address, Value)
            End If
        End If
        Return Value
    End Function

    Public Function ReadPointerByte(ByVal EXENAME As String, ByVal Pointer As Integer, ByVal ParamArray Offset As Integer()) As Byte
        Dim Value As Byte
        If Process.GetProcessesByName(EXENAME).Length <> 0 Then
            Dim Handle As Integer = Process.GetProcessesByName(EXENAME)(0).Handle
            If Handle <> 0 Then
                For Each I As Integer In Offset
                    ReadMemoryInteger(Handle, Pointer, Pointer)
                    Pointer += I
                Next
                ReadMemoryByte(Handle, Pointer, Value)
            End If
        Else
            MsgBox("can't find process")
        End If
        Return Value
    End Function

    Public Function ReadPointerInteger(ByVal EXENAME As String, ByVal Pointer As Integer, ByVal ParamArray Offset As Integer()) As Integer
        Dim Value As Integer
        If Process.GetProcessesByName(EXENAME).Length <> 0 Then
            Dim Handle As Integer = Process.GetProcessesByName(EXENAME)(0).Handle
            If Handle <> 0 Then
                For Each I As Integer In Offset
                    ReadMemoryInteger(Handle, Pointer, Pointer)
                    Pointer += I
                Next
                ReadMemoryInteger(Handle, Pointer, Value)
            End If
        End If
        Return Value
    End Function

    Public Function ReadPointerFloat(ByVal EXENAME As String, ByVal Pointer As Integer, ByVal ParamArray Offset As Integer()) As Single
        Dim Value As Single
        If Process.GetProcessesByName(EXENAME).Length <> 0 Then
            Dim Handle As Integer = Process.GetProcessesByName(EXENAME)(0).Handle
            If Handle <> 0 Then
                For Each I As Integer In Offset
                    ReadMemoryInteger(Handle, Pointer, Pointer)
                    Pointer += I
                Next
                ReadMemoryFloat(Handle, Pointer, Value)
            End If
        End If
        Return Value
    End Function

    Public Function ReadPointerDouble(ByVal EXENAME As String, ByVal Pointer As Integer, ByVal ParamArray Offset As Integer()) As Double
        Dim Value As Double
        If Process.GetProcessesByName(EXENAME).Length <> 0 Then
            Dim Handle As Integer = Process.GetProcessesByName(EXENAME)(0).Handle
            If Handle <> 0 Then
                For Each I As Integer In Offset
                    ReadMemoryInteger(Handle, Pointer, Pointer)
                    Pointer += I
                Next
                ReadMemoryDouble(Handle, Pointer, Value)
            End If
        End If
        Return Value
    End Function

    Public Sub WriteByte(ByVal EXENAME As String, ByVal Address As Integer, ByVal Value As Byte)
        If Process.GetProcessesByName(EXENAME).Length <> 0 Then
            Dim Handle As Integer = Process.GetProcessesByName(EXENAME)(0).Handle
            If Handle <> 0 Then
                WriteMemoryByte(Handle, Address, Value)
            End If
        End If
    End Sub

    Public Sub WriteInteger(ByVal EXENAME As String, ByVal Address As Integer, ByVal Value As Integer)
        If Process.GetProcessesByName(EXENAME).Length <> 0 Then
            Dim Handle As Integer = Process.GetProcessesByName(EXENAME)(0).Handle
            If Handle <> 0 Then
                WriteMemoryInteger(Handle, Address, Value)
            End If
        End If
    End Sub

    Public Sub WriteFloat(ByVal EXENAME As String, ByVal Address As Integer, ByVal Value As Single)
        If Process.GetProcessesByName(EXENAME).Length <> 0 Then
            Dim Handle As Integer = Process.GetProcessesByName(EXENAME)(0).Handle
            If Handle <> 0 Then
                WriteMemoryFloat(Handle, Address, Value)
            End If
        End If
    End Sub

    Public Sub WriteDouble(ByVal EXENAME As String, ByVal Address As Integer, ByVal Value As Double)
        If Process.GetProcessesByName(EXENAME).Length <> 0 Then
            Dim Handle As Integer = Process.GetProcessesByName(EXENAME)(0).Handle
            If Handle <> 0 Then
                WriteMemoryDouble(Handle, Address, Value)
            End If
        End If
    End Sub

    Public Sub WritePointerByte(ByVal EXENAME As String, ByVal Pointer As Integer, ByVal Value As Byte, ByVal ParamArray Offset As Integer())
        If Process.GetProcessesByName(EXENAME).Length <> 0 Then
            Dim Handle As Integer = Process.GetProcessesByName(EXENAME)(0).Handle
            If Handle <> 0 Then
                For Each I As Integer In Offset
                    ReadMemoryInteger(Handle, Pointer, Pointer)
                    Pointer += I
                Next
                WriteMemoryByte(Handle, Pointer, Value)
            End If
        End If
    End Sub

    Public Sub WritePointerInteger(ByVal EXENAME As String, ByVal Pointer As Integer, ByVal Value As Integer, ByVal ParamArray Offset As Integer())
        If Process.GetProcessesByName(EXENAME).Length <> 0 Then
            Dim Handle As Integer = Process.GetProcessesByName(EXENAME)(0).Handle
            If Handle <> 0 Then
                For Each I As Integer In Offset
                    ReadMemoryInteger(Handle, Pointer, Pointer)
                    Pointer += I
                Next
                WriteMemoryInteger(Handle, Pointer, Value)
            End If
        End If
    End Sub

    Public Sub WritePointerFloat(ByVal EXENAME As String, ByVal Pointer As Integer, ByVal Value As Single, ByVal ParamArray Offset As Integer())
        If Process.GetProcessesByName(EXENAME).Length <> 0 Then
            Dim Handle As Integer = Process.GetProcessesByName(EXENAME)(0).Handle
            If Handle <> 0 Then
                For Each I As Integer In Offset
                    ReadMemoryInteger(Handle, Pointer, Pointer)
                    Pointer += I
                Next
                WriteMemoryFloat(Handle, Pointer, Value)
            End If
        End If
    End Sub

    Public Sub WritePointerDouble(ByVal EXENAME As String, ByVal Pointer As Integer, ByVal Value As Double, ByVal ParamArray Offset As Integer())
        If Process.GetProcessesByName(EXENAME).Length <> 0 Then
            Dim Handle As Integer = Process.GetProcessesByName(EXENAME)(0).Handle
            If Handle <> 0 Then
                For Each I As Integer In Offset
                    ReadMemoryInteger(Handle, Pointer, Pointer)
                    Pointer += I
                Next
                WriteMemoryDouble(Handle, Pointer, Value)
            End If
        End If
    End Sub
End Module
I have found my pointer with cheat engine, and it is a valid pointer, when i restart the game it shows the current value of what I want.
see attachment below - it shows the pointer information.

When I try to get the value of it:
Code:
TextBox1.Text = ReadPointerInteger("PurblePlace", &H101D60, {&H74, &H10, &H8}).ToString()
It returns: 0, but the value is 1 and it always returns zero.
In cheat engine it shows the current value(pointer). Am I using the wrong addresses? the wrong offsets or what?
The name should be correct: "PurblePlace" - it is the default game on windows 7.
Quote Originally Posted by zassadgh2 View Post
.
It's because your 3rd offset is simply added, and should not dereferenced after added.


[xxxx + yy]
vs.
xxxx + yy


The top offset in your picture should simply be added to the last addr found -- do not dereference this as a pointer.

That "ReadPointerInteger" function is dereferencing them all.
For Each I As Integer In Offset
ReadMemoryInteger(Handle, Pointer, Pointer)
Pointer += I
Next
ReadMemoryInteger(Handle, Pointer, Value) '<--dereference the last one!

Easiest solution would be to pass in all but the last offset: manually add the last offset to the function's return value.

edit: You also passed in the offset list backwards!
Thank you for your quick and very good response:
I am very new to memory editing but here is what I have tried:
TextBox1.Text = ReadPointerInteger(AppAIONComboBo*****lectedItem.To String, &H101D60, {&H8, &H10}).ToString() --> retruns 0
TextBox1.Text = ReadPointerInteger(AppAIONComboBo*****lectedItem.To String, &H101D60, {&H8, &H10, &H74}).ToString() --> retruns 0
TextBox1.Text = ReadPointerInteger(AppAIONComboBo*****lectedItem.To String, &H101D60, {&H10, &H74}).ToString() --> retruns 0

No combination of that retruns anything but 0 and it should return 1.
Please give me a little code example of how you mean I should call it, thank you.
is this the correct address: &H101D60 - see picture.
because I said to "Add the last offset to the function's return value. -- you didn't do that...you just used 1 less offset :/

TextBox1.Text = ReadPointerInteger(AppAIONComboBo*****lectedItem.To String, &H101D60, {&H8, &H10}).ToString() --> retruns 0
Code:
Dim finalAddr As Integer = ReadPointerInteger(AppAIONComboBo*****lectedItem.To String, &H101D60, {&H8, &H10})
finalAddr += 74 '' IS THIS CE CRAP IN HEX OR BASE10 ??  74 vs &H74 :| It matters for these two also   ^^   ^^  .

TextBox1.Text = finalAddr.ToString("x") ' <-- (x) will print it in hex, instead of base10.

yes. well CE said it was mainModuleBase + someSmallOffset --> Each time you restart the game that *may* change, but if it's not, you can leave it hardcoded for now I guess.

 
rant

edit: why did you change "theGameName" to "AppAIONComboBo*****lectedItem.To String" ....you should change one thing at a time. We're trying to fix the pointer error, not change everythin else in the code too.
Because I did not add the last offset was because of the examples returned all 0, and adding the last number would not do any difference if all retruned 0.
Your code returns 116 (base-10).
cheat engine(4 bytes - integer) says it should show 2 - and so does the game.
What could be the cause of that?
maybe the offsets are in base10 from CE ......use 8,10 instead of &H8,&H10

?

I'm not 100% sure. set breakpoints and check return values. Debugging time...we can't just make random permutations of the code and figure out which one works : p


and no!
Code:
Dim finalAddr As Integer = ReadPointerInteger(AppAIONComboBo*****lectedItem.To String, &H101D60, {8, 10})
finalAddr += 74 '' IS THIS CE CRAP IN HEX OR BASE10 ??  74 vs &H74 :| It matters for these two also   ^^   ^^  .

TextBox1.Text = finalAddr.ToString("x") ' <-- (x) will print it in hex, instead of base10.

should show

"0962D974" according to Your picture. Where did you get '2' :/
&H and without - does not change the outcome of the integer 116
I am still worried that my pointer is wrong or something or I am not using the class correctly

I appreciate your help very much:
"According to your picture it should add the first offset ( 8 ) before dereferencing : )"
so how should offset collection then look like?
heh, it's because of how the

Code:
    Public Function ReadPointerInteger(ByVal EXENAME As String, ByVal Pointer As Integer, ByVal ParamArray Offset As Integer()) As Integer
        Dim Value As Integer
        If Process.GetProcessesByName(EXENAME).Length <> 0 Then
            Dim Handle As Integer = Process.GetProcessesByName(EXENAME)(0).Handle
            If Handle <> 0 Then
                For Each I As Integer In Offset
                    ReadMemoryInteger(Handle, Pointer, Pointer)
                    Pointer += I
                Next
                ReadMemoryInteger(Handle, Pointer, Value)
            End If
        End If
        Return Value
    End Function
function was made.

For Each I As Integer In Offset
ReadMemoryInteger(Handle, Pointer, Pointer)
Pointer += I
Next
For each offset
->Read (pointer)
->add offset

So the first thing is does is dereference the addr u passed into the function.

According to your picture it should add the first offset ( 8 ) before dereferencing : )


edit: ---------------------
you pass to the function "00101D60"

and according to the IMAGE, you should first add ( 8 - the first offset), THEN dereference it.

Your ReadPointerInteger dereferences it first.

You see the problem?
idk man : )

edit: well originally it was 8, 10, 74


I told you add the last one, 74, but not dereference that new value. so 74 is out.

Now I just told u the 8 has to be added before calling the ReadPtrInt function because of how the function is set up.

That only leaves 10. 1 item isn't a "collection"

I'm not going to analyze the rest of your (someone else's fugly) code to see if that'll cause more bugs.

You should write your own memory reading library...start small at reading integers and bytes and work your way up to "reading an addr" (ie. pointers).

Code:
Dim finalAddr As Integer = ReadPointerInteger(AppAIONComboBo*****lectedItem.To String, &H101D60 + 8, {10})
finalAddr += 74 

TextBox1.Text = finalAddr.ToString("x") ' <-- (x) will print it in hex, instead of base10.
MAYBE. These functions are horrible looking...I'm not going to debug for you. Ask a specific question, else I'm done.
Posts 1–11 of 11 · Page 1 of 1

Post a Reply

Similar Threads

Tags for this Thread

None

Need help?