 |
Cheat Engine The Official Site of Cheat Engine
|
| View previous topic :: View next topic |
| Author |
Message |
Studio80 Advanced Cheater
Reputation: 2
Joined: 12 Sep 2012 Posts: 83
|
Posted: Thu Sep 13, 2012 8:58 pm Post subject: [VB.NET HELP] Problem with reading a pointer integer. |
|
|
Hello guys. I'm having a problem with reading a pointer integer from the Cheat Engine tutorial (step 6). I have scanned everything etc. So the pointer is:
| Code: | | "Tutorial-i386.exe"+00290380 Offset 0: 0 |
My template:
| Code: | 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 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
End Module |
Now when I use the following code it ALWAYS returns a 0:
| Code: | Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Me.TextBox1.Text = ReadPointerInteger("Tutorial-i386", &H290380, &H0).ToString()
End Sub |
If I use a dynamic adress from the search results like:
| Code: | Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Me.TextBox1.Text = ReadPointerInteger("Tutorial-i386", &H6E938)
End Sub |
Than it works, but when I add the base adress like in the first example it returns a zero. Can some one please tell me what I'm doing wrong?
|
|
| Back to top |
|
 |
Pingo Grandmaster Cheater
Reputation: 8
Joined: 12 Jul 2007 Posts: 571
|
Posted: Sat Sep 15, 2012 11:30 am Post subject: |
|
|
&H290380 isnt the address, its the offset.
"Tutorial-i386.exe"+00290380 is the address.
Tutorial-i386.exe = BaseAddress and then add the offset.
_________________
|
|
| Back to top |
|
 |
Studio80 Advanced Cheater
Reputation: 2
Joined: 12 Sep 2012 Posts: 83
|
Posted: Sat Sep 15, 2012 2:23 pm Post subject: |
|
|
It should be like this:
| Code: | | ReadPointerInteger(Game name, &HPointer,&HOffset).ToString() |
So I write down:
| Code: | | ReadPointerInteger("Tutorial-i386", &H0,&H290380).ToString() |
In the source there is an example:
| Code: | | Me.Text = ReadPointerInteger("gta_sa", &HB71A38,&H540).ToString() |
It still returns a 0.
| Description: |
|
| Filesize: |
1.71 KB |
| Viewed: |
21030 Time(s) |
![1zvvn60[1].gif](files/1zvvn60_1__652.gif)
|
|
|
| Back to top |
|
 |
Pingo Grandmaster Cheater
Reputation: 8
Joined: 12 Jul 2007 Posts: 571
|
Posted: Sat Sep 15, 2012 3:36 pm Post subject: |
|
|
Here is 3 functions i just made for you to test.
| Code: | Public Declare Function ReadProcessMemory Lib "kernel32" Alias "ReadProcessMemory" (ByVal hProcess As IntPtr, ByVal lpBaseAddress As Integer, ByVal buffer As Byte(), ByVal size As Integer, ByVal lpNumberOfBytesRead As Integer) As Boolean
Public Declare Function WriteProcessMemory Lib "kernel32" Alias "WriteProcessMemory" (ByVal hProcess As IntPtr, ByVal lpBaseAddress As Integer, ByVal buffer As Byte(), ByVal size As Integer, ByVal lpNumberOfBytesWritten As Integer) As Boolean |
| Code: | Private Function GetAddress(ByVal Proc As Process, ByVal Address_Offsets As String) As Integer
Dim tmp As String() = Address_Offsets.Split(" ")
Dim _Addy As Integer = -1
''''''Gets the base address'''''''
If (tmp(0).IndexOf("+", StringComparison.Ordinal) = -1) Then
_Addy = Integer.Parse(tmp(0), System.Globalization.NumberStyles.HexNumber)
Else
Dim BS As String() = tmp(0).Split("+")
For Each M As ProcessModule In Proc.Modules
If (M.ModuleName.ToLower = BS(0).ToLower) Then
_Addy = M.BaseAddress.ToInt32 + Integer.Parse(BS(1), System.Globalization.NumberStyles.HexNumber)
End If
Next
End If
''''''''''''''''''''''''''''''''''
If _Addy = -1 Then
Return -1
End If
If (tmp.Length = 1) Then
Return _Addy
End If
''''''Gets the pointer''''''''''''
Dim buff As Byte() = New Byte(3) {}
ReadProcessMemory(Proc.Handle, _Addy, buff, 4, 0)
_Addy = BitConverter.ToInt32(buff, 0)
For i As Integer = 1 To tmp.Length - 1
Dim Off As Integer = Integer.Parse(tmp(i), System.Globalization.NumberStyles.HexNumber)
ReadProcessMemory(Proc.Handle, _Addy + Off, buff, 4, 0)
_Addy = If(i <> (tmp.Length - 1), BitConverter.ToInt32(buff, 0), _Addy + Off)
Next i
''''''''''''''''''''''''''''''''''
Return _Addy
End Function |
| Code: | Public Function Read(ByVal EXENAME As String, ByVal Address_Offsets As String, ByVal MemType As Object) As Object
If (Address_Offsets <> String.Empty) Then
Dim Proc As Process() = Process.GetProcessesByName(EXENAME)
If Proc.Length = 0 Then
Return -1
End If
Dim buff As Byte()
Select Case Array.IndexOf(Of Object)(New Object() {GetType(Byte), GetType(Integer), GetType(UInt32), GetType(Single), GetType(Double)}, MemType)
Case 0
buff = New Byte(1) {}
ReadProcessMemory(Proc(0).Handle, GetAddress(Proc(0), Address_Offsets), buff, 1, 0)
Return buff(0)
Case 1
buff = New Byte(3) {}
ReadProcessMemory(Proc(0).Handle, GetAddress(Proc(0), Address_Offsets), buff, 4, 0)
Return BitConverter.ToInt32(buff, 0)
Case 2
buff = New Byte(3) {}
ReadProcessMemory(Proc(0).Handle, GetAddress(Proc(0), Address_Offsets), buff, 4, 0)
Return BitConverter.ToUInt32(buff, 0)
Case 3
buff = New Byte(3) {}
ReadProcessMemory(Proc(0).Handle, GetAddress(Proc(0), Address_Offsets), buff, 4, 0)
Return BitConverter.ToSingle(buff, 0)
Case 4
buff = New Byte(7) {}
ReadProcessMemory(Proc(0).Handle, GetAddress(Proc(0), Address_Offsets), buff, 8, 0)
Return BitConverter.ToDouble(buff, 0)
Case -1
Return -1
End Select
End If
Return -1
End Function |
| Code: | Private Sub Write(ByVal EXENAME As String, ByVal Address_Offsets As String, ByVal _Hack As Object, ByVal MemType As Object)
If (Address_Offsets <> String.Empty And _Hack <> Nothing) Then
Dim Proc As Process() = Process.GetProcessesByName(EXENAME)
If Proc.Length = 0 Then
Return
End If
Dim buff As Byte() = Nothing
Select Case Array.IndexOf(Of Object)(New Object() {GetType(Byte), GetType(Integer), GetType(UInt32), GetType(Single), GetType(Double)}, MemType)
Case 0
buff = BitConverter.GetBytes(Byte.Parse(_Hack))
Exit Select
Case 1
buff = BitConverter.GetBytes(Integer.Parse(_Hack))
Exit Select
Case 2
buff = BitConverter.GetBytes(UInt32.Parse(_Hack))
Exit Select
Case 3
buff = BitConverter.GetBytes(Single.Parse(_Hack))
Exit Select
Case 4
buff = BitConverter.GetBytes(Double.Parse(_Hack))
Exit Select
End Select
If Not buff Is Nothing Then
WriteProcessMemory(Proc(0).Handle, GetAddress(Proc(0), Address_Offsets), buff, buff.Length, 0)
End If
End If
End Sub |
Usage is with this pointer and the dll pointer you're asking about in the other thread.
| Code: | Write("ProcessNameHere", "mono.dll+11EE684 F0 F4 14 10", &H64, GetType(Integer))
Me.Text = Read("ProcessNameHere", "mono.dll+11EE684 F0 F4 14 10", GetType(Integer)) |
| Code: | Write("Tutorial-i386", "Tutorial-i386.exe+290380 0", &H64, GetType(Integer))
Me.Text = Read("Tutorial-i386", "Tutorial-i386.exe+290380 0", GetType(Integer)) |
The pointer offsets are seperated by a single space, just how i have it in the example.
The functions are big but they do multiple things.
Example the GetAddress loops all the modules aswell as getting the pointer.
The read/write functions use different value types aswell.
Remember it uses the process name, not the windows title like your other reader.
_________________
|
|
| Back to top |
|
 |
Studio80 Advanced Cheater
Reputation: 2
Joined: 12 Sep 2012 Posts: 83
|
Posted: Sat Sep 15, 2012 5:15 pm Post subject: |
|
|
| Holy crap, it works with the DLL file! THANK YOU SO MUCH! You don;t wanna know how many time I have spend to get this to work! THANK YOU!
|
|
| Back to top |
|
 |
Pingo Grandmaster Cheater
Reputation: 8
Joined: 12 Jul 2007 Posts: 571
|
Posted: Sun Sep 16, 2012 3:39 am Post subject: |
|
|
I have a memory class i made that you can have. It never gets used cause when i do make a trainer, its in C#.
2Shared Link
You dont need to define the process name everytime you read/write.
Just do it once as the app loads. Dont worry if the game process isnt active, a timer in the mem class keeps it alive.
| Code: | Dim Mem As ProcMem = New ProcMem
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Mem.GetProcess("ProcessNameHere")
End Sub |
If writing a value, its in string format sorry. I forgot to change it over.
So like this on a button
| Code: | Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Mem.Write("mono.dll+11EE684 F0 F4 14 10", "64", GetType(Integer))
End Sub |
Some features
Read/Write
Byte
Integer
UInt32
Single
Double
Ascii String
Unicode String
AobScanning with wildcards
Patch Memory
Injection with Allocate and Deallocate
Accessed- Get addresses that access an instruction
Integrity checks
Hotkeys
Heres an example of a aobscan with wildcards and nopping the instruction.
Im gonna use solitaire on win7 which has codeshifting
Instructions were after
| Code: | 002210B0 - FF 40 08 - inc [eax+08]
002210B3 - E8 37DFFFFF - call 0021EFEF
002210B8 - 8B 46 2C - mov eax,[esi+2C]
|
| Code: | Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim AobResult As Integer = Mem.AobScan("solitaire.exe+0", &HF00000, "FF 40 08 E8 ?? ?? ?? ?? 8B 46 2C")
Mem.Patch(AobResult, "90 90 90", "FF 40 08")
End Sub |
One click nops it, another puts it back to default.
You dont need to seperate the bytes with a space, i only did it in the example, works both ways.
| Code: | Dim AobResult As Integer = Mem.AobScan("solitaire.exe+0", &HF00000, "FF4008E8????????8B462C")
Mem.Patch(AobResult, "909090", "FF4008") |
Or which is harder to read but works the same..
| Code: | | Mem.Patch(Mem.AobScan("solitaire.exe+0", &HF00000, "FF4008E8????????8B462C"), "909090", "FF4008") |
"solitaire.exe+0" is the base where you would like the scan to start.
You can use &H400000 or whatever if the game doesnt codeshift.
I find this usefull when scanning within modules and the game has multiple results.
mono.dll+0 could be the base.
Just have a mess and see how things go. You'l work it out.
_________________
|
|
| Back to top |
|
 |
Studio80 Advanced Cheater
Reputation: 2
Joined: 12 Sep 2012 Posts: 83
|
Posted: Sun Sep 16, 2012 9:05 pm Post subject: |
|
|
About the first template you have posted. Sometimes when I use it it doesn't use the codes and hotkeys I have coded. When I close the game I get an error.
Using the following code:
At some part the trainer doesn't work and then when I close the game I get this error. I have made one option for two pointers:
| Code: | Private Sub Timer4_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer4.Tick
Write("TinyTroopers", "TinyTroopers.exe+00838DA8 2f8 24 18 10 10", 1120403456, GetType(Integer)) 'P1 Health
Write("TinyTroopers", "TinyTroopers.exe+00838DA8 2f8 24 18 10 40", 1120403456, GetType(Integer)) 'P2 Health
End Sub |
Error: Win32Exception was Unhandled
| Code: | Private Function GetAddress(ByVal Proc As Process, ByVal Address_Offsets As String) As Integer
Dim tmp As String() = Address_Offsets.Split(" ")
Dim _Addy As Integer = -1
''''''Gets the base address'''''''
If (tmp(0).IndexOf("+", StringComparison.Ordinal) = -1) Then
_Addy = Integer.Parse(tmp(0), System.Globalization.NumberStyles.HexNumber)
Else
Dim BS As String() = tmp(0).Split("+")
>>>>>> For Each M As ProcessModule In Proc.Modules<<<<<<< THAT LINE GIVES ME THE ERROR
If (M.ModuleName.ToLower = BS(0).ToLower) Then
_Addy = M.BaseAddress.ToInt32 + Integer.Parse(BS(1), System.Globalization.NumberStyles.HexNumber)
End If
Next
End If |
If I run the build exe, it crashes at some part and gives me the following exception error:
| Code: | at System.Diagnostics.NtProcessManager.GetModuleInfos(Int32 processId, Boolean firstModuleOnly)
at System.Diagnostics.ProcessManager.GetModuleInfos(Int32 processId)
at System.Diagnostics.Process.get_Modules()
at WindowsApplication1.Form1.GetAddress(Process Proc, String Address_Offsets)
at WindowsApplication1.Form1.Write(String EXENAME, String Address_Offsets, Object _Hack, Object MemType)
at WindowsApplication1.Form1.Timer4_Tick(Object sender, EventArgs e)
at System.Windows.Forms.Timer.OnTick(EventArgs e)
at System.Windows.Forms.Timer.TimerNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) |
|
|
| Back to top |
|
 |
Pingo Grandmaster Cheater
Reputation: 8
Joined: 12 Jul 2007 Posts: 571
|
Posted: Mon Sep 17, 2012 1:33 am Post subject: |
|
|
It might be because of the process exiting. No idea, i tend to get alot of errors with vb.
In the read function under
| Code: | If Proc.Length = 0 Then
Return -1
End If |
Add this so it looks like
| Code: | If Proc.Length = 0 Then
Return -1
End If
If Proc.Length <> 0 Then
If Proc(0).HasExited Then
Return -1
End If
End If |
In the write function, make it look like
| Code: | If Proc.Length = 0 Then
Return
End If
If Proc.Length <> 0 Then
If Proc(0).HasExited Then
Return
End If
End If |
The memory class handles this already.
_________________
|
|
| Back to top |
|
 |
Studio80 Advanced Cheater
Reputation: 2
Joined: 12 Sep 2012 Posts: 83
|
Posted: Mon Sep 17, 2012 9:07 pm Post subject: |
|
|
Haha just tried it, in some cases it game me a Blue Screen of Death. MS products at their best.
I think I have to read some tutorials about ASM programming, this VB and C stuff always fail for me so I guess programming in ASM will be much better. Thanks for your help anyways
|
|
| Back to top |
|
 |
Banrukai How do I cheat?
Reputation: 0
Joined: 26 Sep 2012 Posts: 4
|
Posted: Thu Sep 27, 2012 7:06 am Post subject: |
|
|
Hey Pingo,
How hard would it to make similar code structure like this, but for Reading and Sending packets to a game client?
Also, your write function wasn't working for me at first, but I figured out how to make it work. But there still seems to be a problem, it seems to be writing a few extra bytes when writing to an address. For example, I was writing to certain address and it was adding 00 to the address above it which causes the application i'm trying to modify, to crash.
If you know how to fix that, it would be awesome. I'm gonna continue to look at it and maybe figure it out like I did to make the write function work.
|
|
| Back to top |
|
 |
Studio80 Advanced Cheater
Reputation: 2
Joined: 12 Sep 2012 Posts: 83
|
Posted: Wed Jan 16, 2013 5:46 pm Post subject: |
|
|
Hello it has been a longtime, this script is pretty good I have modified it a little bit (hotkeys etc). I have found an another problem. When I try to perform a code injection (I'm just taking the jmp to cave as an example):
Original:
| Code: | 00551921 89 81 C8 00 00 00 MOV DWORD PTR DS:[ECX+C8],EAX
[b]00551927 - C2 0400 RET 0004[/b]
|
Cave:
| Code: | 00551921 - E9 95 F9 AB FF JMP 000112BB
00551926 90 NOP |
Which should be written in the template like:
| Code: | Write("game-pc", "00551921", &HE9, GetType(Integer))
Write("game-pc", "00551922", &H95, GetType(Integer))
Write("game-pc", "00551923", &HF9, GetType(Integer))
Write("game-pc", "00551924", &HAB, GetType(Integer))
Write("game-pc", "00551925", &HFF, GetType(Integer))
Write("game-pc", "00551926", &H90, GetType(Integer)) |
Now the problem is when I use the function to activate this code this trainer templates changes two extra bytes:
00551921 - E9 95 F9 AB FF - jmp 000112BB
00551926 - 90 - nop
00551927 - 00 00 - add [eax],al
00551929 - 00 CC - add ah,cl
It changes the line at 00551927, which isn't normal because I have nopped enough bytes (00551926). Any idea on how to solve this?
|
|
| Back to top |
|
 |
Pingo Grandmaster Cheater
Reputation: 8
Joined: 12 Jul 2007 Posts: 571
|
Posted: Thu Jan 17, 2013 7:04 am Post subject: |
|
|
Probably because you're using an Integer instead of Byte... GetType(Byte)
Just a guess from a quick glance.
Why not use the memory class the way its supposed to be used.
| Code: | | Patch(&H551921, "E995F9ABFF90", "8981C8000000") |
_________________
|
|
| Back to top |
|
 |
Studio80 Advanced Cheater
Reputation: 2
Joined: 12 Sep 2012 Posts: 83
|
Posted: Mon Feb 11, 2013 12:43 pm Post subject: |
|
|
Thank you it worked! There is a bug in your file, when you run an option and the game isn't running you'll get an error:
| Code: | Private Function wBytes(ByVal _A As Integer, ByVal _B As Byte()) As Boolean
Return IIf(ProcActive, WriteProcessMemory(Proc(0).Handle, _A, _B, _B.Length, 0), False)
End Function |
Error: IndexOutOfRangeException was unhandled.
Any idea on how to solve this? And again thank you.
|
|
| Back to top |
|
 |
Studio80 Advanced Cheater
Reputation: 2
Joined: 12 Sep 2012 Posts: 83
|
Posted: Sun Dec 13, 2015 9:13 pm Post subject: |
|
|
I'm having problem with the Aobscan function. I'm trying it with Solitaire just like in your example with the same code. When I run the game and the trainer and push the button I get the following error
Arithmetic operation resulted in an overflow.
#Region "Pointers/Module"
Return (M.BaseAddress.ToInt32 + Integer.Parse(tmp(1), NumberStyles.HexNumber))
The Callstack gets stuck on:
> VBTRN.exe!WindowsApplication1.ProcMem._Module(String _Address = "solitaire.exe+0") Line 350 Basic
Could you help me out? It's driving me crazy.
|
|
| Back to top |
|
 |
Zanzer I post too much
Reputation: 126
Joined: 09 Jun 2013 Posts: 3278
|
Posted: Sun Dec 13, 2015 9:49 pm Post subject: |
|
|
Probably because you're running Windows 64-bit and your code is treating everything as 32-bit integers.
Use ToInt64 and Long instead. Or better yet, IntPtr.
|
|
| Back to top |
|
 |
|
|
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
|
|