How to read pointer+offset from other process (like Cheat Engine)?

Just starting out? Need help? Post your questions and find answers here.
rotacak
User
User
Posts: 77
Joined: Tue Feb 14, 2006 2:00 pm

How to read pointer+offset from other process (like Cheat Engine)?

Post by rotacak »

Hello,
I have this working code for reading health value from another game (memory address is 0EECD3C0):

Code: Select all

HWND = FindWindowEx_(0, 0, "SDL_app", 0)
GetWindowThreadProcessId_(HWND, @pid)
hProcess = OpenProcess_(#PROCESS_ALL_ACCESS, #False, pid)

aaa:
	res = ReadProcessMemory_(hProcess, $0EECD3C0, @mem, 4, 0)
	If res > 0
		Debug PeekI(@mem)
	EndIf
	
	Delay(50)
Goto aaa

CloseHandle_(hProcess)
But memory address is everytime different, when I run the game. That is reason why I found pointer/base (885d64) + offset (110) with Cheat Engine. But how to use it in this code? Anyone knows?
User avatar
Mijikai
Addict
Addict
Posts: 1517
Joined: Sun Sep 11, 2016 2:17 pm

Re: How to read pointer+offset from other process (like Cheat Engine)?

Post by Mijikai »

First you need to get the base address of the game also known as ImageBase or ModuleHandle.
For this you need to enumerate the moduleentry list and locate your module.

https://docs.microsoft.com/en-us/window ... 32snapshot:

Code: Select all

CreateToolhelp32Snapshot_(#TH32CS_SNAPMODULE32,ProcessId)
;...
Once you know the base address get the first address like this:

Code: Select all

ReadProcessMemory_(Handle,ImageBase + RVA ($885D64),Buffer,Bytes,#Null)
Then you add the next offset to the result to finally read the health value:

Code: Select all

ReadProcessMemory_(Handle,Address + HealthOffset ($110),Buffer,Bytes,#Null)
rotacak
User
User
Posts: 77
Joined: Tue Feb 14, 2006 2:00 pm

Re: How to read pointer+offset from other process (like Cheat Engine)?

Post by rotacak »

This will read the "Address" variable?:

Code: Select all

ReadProcessMemory_(Handle,ImageBase + RVA ($885D64),Buffer,Bytes,#Null)
If yes, how much Bytes I should read?
User avatar
Mijikai
Addict
Addict
Posts: 1517
Joined: Sun Sep 11, 2016 2:17 pm

Re: How to read pointer+offset from other process (like Cheat Engine)?

Post by Mijikai »

The address will be always be the size of an integer.
On a x86 game it will be 4 on a x64 game it will be 8.

Health is somewhere located in memory but since the PC normally loads the game into a different
place in memory every it runs all addresses will change.
To get health we must trace it back through a pointer chain until we find a static offset.
The first static offset or RelativeVirtualAddress is always an offset to the ModuleHandle (ImageBase).
So to get to health we must walk all the way through the pointer chain.
The first address we read will be ImageBase + RVA.
The resulting address will be next position in the pointer chain.
Now we repeat this until we are at the last offset.
The last offset will point to health so we dont need to read a address we read health (depending on how it is stored).
User avatar
NicTheQuick
Addict
Addict
Posts: 1504
Joined: Sun Jun 22, 2003 7:43 pm
Location: Germany, Saarbrücken
Contact:

Re: How to read pointer+offset from other process (like Cheat Engine)?

Post by NicTheQuick »

Just for your information: The reason for different memory locations on every start of a process is address space layout randomization. It is integrated in Windows since Vista. Besides other attacks It is also used against Cheat Engines. :P
The english grammar is freeware, you can use it freely - But it's not Open Source, i.e. you can not change it or publish it in altered way.
BarryG
Addict
Addict
Posts: 4127
Joined: Thu Apr 18, 2019 8:17 am

Re: How to read pointer+offset from other process (like Cheat Engine)?

Post by BarryG »

Hmm, I use Cheat Engine on Quake 2 and the memory addresses are always the same.
User avatar
Mijikai
Addict
Addict
Posts: 1517
Joined: Sun Sep 11, 2016 2:17 pm

Re: How to read pointer+offset from other process (like Cheat Engine)?

Post by Mijikai »

BarryG wrote: Fri Sep 03, 2021 10:48 am Hmm, I use Cheat Engine on Quake 2 and the memory addresses are always the same.
Either ASLR is disabled or Quake 2 does some black magic with sections which is possible.

Anyway i somehow doubt it so my Question is:

Code: Select all

Procedure.i Really(ProcessId.i);<- pid of quake 2
  Protected hproc.i
  Protected result.i
  Protected signature.i
  hproc = OpenProcess_(#PROCESS_ALL_ACCESS,#False,ProcessId)
  If hproc
    If ReadProcessMemory_(hproc,$400000,@signature,2,#Null)
      result = Bool(signature = $5A4D)  
    EndIf
    CloseHandle_(hproc)
  EndIf
  ProcedureReturn result
EndProcedure

;Debug Really()
firace
Addict
Addict
Posts: 946
Joined: Wed Nov 09, 2011 8:58 am

Re: How to read pointer+offset from other process (like Cheat Engine)?

Post by firace »

BarryG wrote: Fri Sep 03, 2021 10:48 am Hmm, I use Cheat Engine on Quake 2 and the memory addresses are always the same.
You’re probably talking about relative (not absolute) addresses ? Otherwise it would be very surprising.
BarryG
Addict
Addict
Posts: 4127
Joined: Thu Apr 18, 2019 8:17 am

Re: How to read pointer+offset from other process (like Cheat Engine)?

Post by BarryG »

Mijikai wrote: Fri Sep 03, 2021 12:13 pmEither ASLR is disabled or Quake 2 does some black magic with sections which is possible.
I wouldn't have a clue. Your code returns 1 for me when I give it Q2's PID.

I've been using Cheat Engine (and even PureBasic) with Q2 for years now, and the memory addresses of common items (health, etc) have never changed, even when I switched from Win XP to Win 7 to Win 10. I've even got them hard-coded into my app. I can record a short vid if you like?
User avatar
Mijikai
Addict
Addict
Posts: 1517
Joined: Sun Sep 11, 2016 2:17 pm

Re: How to read pointer+offset from other process (like Cheat Engine)?

Post by Mijikai »

I belive you, if it returns 1 then its mapped to the default image base which is nice.
I know that this is possible even on a system with ASLR enabled.
BarryG
Addict
Addict
Posts: 4127
Joined: Thu Apr 18, 2019 8:17 am

Re: How to read pointer+offset from other process (like Cheat Engine)?

Post by BarryG »

I know you believe me, but I wanted to make a short video anyway. Also, I googled ASLR and found out what it was. It was disabled, but even after enabling and rebooting Win 10, it still works with Quake 2. Here's my test code, and my video link. As you can see, I can read the player's Health level with PureBasic, no matter how often I restart the game. So it's a non-changing memory address for it ($AF05E2). Same goes for ammo and other items.

Code: Select all

exe$="C:\Quake2\Quake2.exe"
hProcess=RunProgram(exe$,"+map q2dm1",GetPathPart(exe$),#PB_Program_Open)

pid=ProgramID(hProcess)
ProcessHandle=OpenProcess_(#PROCESS_ALL_ACCESS,0,pid)

While ProgramRunning(hProcess)
  ReadProcessMemory_(Processhandle,$AF05E2,@Health.w,2,0)
  Debug Health ; Always matches the game.
  Delay(250)
Wend
The video proof -> https://i.imgur.com/u5xai4D.mp4

Note that Imgur "optimized" the video upload, so make it full-screen to read it better.
User avatar
Mijikai
Addict
Addict
Posts: 1517
Joined: Sun Sep 11, 2016 2:17 pm

Re: How to read pointer+offset from other process (like Cheat Engine)?

Post by Mijikai »

Nice 8)
Now i want to write a hack again its been some time.
rotacak
User
User
Posts: 77
Joined: Tue Feb 14, 2006 2:00 pm

Re: How to read pointer+offset from other process (like Cheat Engine)?

Post by rotacak »

Hmm, I have somewhere something wrong:

Code: Select all

Procedure GetBaseAddressPID(dwpid)
  Protected hSnapshot.l, me32.MODULEENTRY32, hMod.l
  hSnapshot = CreateToolhelp32Snapshot_(#TH32CS_SNAPMODULE, dwPID)
  If hSnapshot <> #INVALID_HANDLE_VALUE 
    me32\dwSize = SizeOf(MODULEENTRY32)
    hMod = Module32First_(hSnapshot, me32) 
    If hMod
      ProcedureReturn me32\modBaseAddr
    EndIf
    CloseHandle_(hSnapshot)
  EndIf
EndProcedure

;Get ProcessID
HWND = FindWindow_(0, "Barony") : If Not HWND : Debug "err: fw" : EndIf
GetWindowThreadProcessId_(HWND, @pid)
hProcess = OpenProcess_(#PROCESS_ALL_ACCESS, #False, pid)
ImageBase = GetBaseAddressPID(pid)
res_a = ReadProcessMemory_(hProcess, ImageBase + $00a55d64, @memadr, 4, 0)

If res_a > 0
  Address = PeekI(@memadr)
Else
  Debug "err: res_a"
EndIf

Debug ImageBase
Debug ImageBase + $885D64
Debug Address
Debug Address + $110

End
aaa:
  res = ReadProcessMemory_(hProcess, Address + $110, @memscore, 4, 0)
  If res > 0
    Debug PeekI(@memscore)
  Else
    Debug "err: res"
  EndIf
  
  Delay(50)
Goto aaa
CloseHandle_(hProcess)
Result of debug is:
err: res_a
7602176
16538980
0
272

Where can be error?

There is the value from Cheat Engine:
Image
User avatar
Mijikai
Addict
Addict
Posts: 1517
Joined: Sun Sep 11, 2016 2:17 pm

Re: How to read pointer+offset from other process (like Cheat Engine)?

Post by Mijikai »

It looks alright but from the screenshot i see that the offset +110 will not reveal health but the address that holds health.
Sow you need to read the resulting address once more to get the actual health.
rotacak
User
User
Posts: 77
Joined: Tue Feb 14, 2006 2:00 pm

Re: How to read pointer+offset from other process (like Cheat Engine)?

Post by rotacak »

But it will fail on the ReadProcessMemory_(hProcess, ImageBase + $00a55d64, @memadr, 4, 0). It will end before I can try to read address+offset.
Post Reply