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 


Find what instructions are acessing a range of addresses

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine
View previous topic :: View next topic  
Author Message
Sinthetix
How do I cheat?
Reputation: 0

Joined: 17 Feb 2024
Posts: 4

PostPosted: Sat Feb 17, 2024 3:08 pm    Post subject: Find what instructions are acessing a range of addresses Reply with quote

How are you doing.

I will first describe the case:
So let's say I found the base pointer of the player in memory. In memory it has a range for example of 4096 bytes.
Next, let's suppose I found the player's health at baseAddress + offset. But when I check what instructions access baseAddres and healthAddress I get some shared instructions as usually happens.
So I spent some time to check what other addresses from the same range are modified in memory and found at baseAddress+BB8 an address which is accessed by only one instruction.
So I could then create a pointer from there..

Now the question, is it possible somehow to check what instructions access a range of addresses at once or in a loop, then checking if that instructions are shared or not?
This will save a lot of time.
It would be useful to have a feature to check what instructions are accessing a range of addresses and then leave only instruction which access only an address from the range omitting the shared ones.
Of course not all 4096 bytes at ones but in a loop starting from the first address and preceding to the next, incrementing by a step of (4,8 bytes). Once an instruction is accessing an address from outside the range it can be excluded from the results
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 140

Joined: 06 Jul 2014
Posts: 4307

PostPosted: Sat Feb 17, 2024 4:29 pm    Post subject: Reply with quote

Break-on-write / break-on-access breakpoints are typically hardware breakpoints. There's only 4 available, meaning you can only watch at max 32 bytes (in 64-bit mode; 16 in 32-bit mode) at a time. You could try them sequentially- set 4 breakpoints, play in the game for a bit, and if nothing comes up, move on to the next 32 bytes. Lua can automate this.

CE does have page exception breakpoints that will trigger every time a page gets accessed / written to; however, that could slow the game down considerably and only works at page granularity (i.e. 4096 bytes at a time).

_________________
I don't know where I'm going, but I'll figure it out when I get there.
Back to top
View user's profile Send private message
Sinthetix
How do I cheat?
Reputation: 0

Joined: 17 Feb 2024
Posts: 4

PostPosted: Sun Feb 18, 2024 7:18 pm    Post subject: Reply with quote

Thanks for reply.

So I have some progress in lua, I loop though a range of bytes, get addresses one by one,
using this function:
Code:
debug_setBreakpoint(addr, 1, bptAccess, bpmInt3, function()

to get what instructions access an address, storing instructions in a table and then I need to loop through each instruction and check what other addresses they access, and here comes the problems. It seems that I don't have the calculated address when a breakpoint is triggered as how CE calculates it.

Is it possible to get the calculated address [rbx+offset] from the following function when a breakpoint is triggered?

Code:
debug_setBreakpoint(inject, 1, bptExecute, function()
  print(string.format("RBX: %x", RBX))
  print(string.format("Lval: %x", LEFT_CALCULATED_ADDR)) --??
  print(string.format("Lval: %x", RIGHT_CALCULATED_ADDR)) --??
  debug_removeBreakpoint(inject)
  debug_continueFromBreakpoint(co_run)
  return 0
end)


What other information except register values can I get from lua?
Because I need the exact information as how CE calculates it when we do "find out what addresses this code access" or "check if found opcodes access other addresses"

If we have this instruction
Code:
mov rax,[rbx+CD]


or this
Code:
mov [rbx+CD],rax


then CE will calculate value of rbx+CD at each access and compare them.
Is it possible to obtain the same info in lua somehow?
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 140

Joined: 06 Jul 2014
Posts: 4307

PostPosted: Sun Feb 18, 2024 8:42 pm    Post subject: Reply with quote

That's a bit of a messy problem.

The first problem is that hardware breakpoints- i.e. bptAccess / bptWrite- trigger after the instruction has been executed. This means you need to get the address of the previous instruction. The Lua function `getPreviousOpcode` makes a good guess, but you can do your own heuristics if you want.

The second problem is figuring out what addresses an instruction accesses, as you said. Unfortunately, there is no easy API to do this for you- you have to do this yourself.

Most (but not all) instructions use square brackets to denote a memory access, so you can disassemble the address of the instruction and parse the string to get the accessed address. The only exceptions I can think of off the top of my head are instructions that access the stack implicitly (i.e. ret, push, pop) and string instructions (e.g. rep movsb - these can be especially weird when debugging).

The "simple" way of disassembling an address is to use `disassemble` / `splitDisassembledString`, but you might be better off creating your own disassembler object w/ `createDisassembler` and use the `disassemble` and `LastDisassembleData` fields. See celua.txt in the main CE directory for information.

Parsing it is up to you. There's no API to help you here AFAIK.

Note that bptExecute breakpoints trigger before the instruction has executed (in contrast to bptAccess / bptWrite that trigger after). This means you don't have to worry about instructions that write to the same register they're using to address memory (e.g. `mov rdx,[rdx+C]`).

_________________
I don't know where I'm going, but I'll figure it out when I get there.
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 458

Joined: 09 May 2003
Posts: 25300
Location: The netherlands

PostPosted: Mon Feb 19, 2024 3:55 am    Post subject: Reply with quote

dbvm find what accesses can also record what accesses a whole page
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.

Like my help? Join me on Patreon so i can keep helping
Back to top
View user's profile Send private message MSN Messenger
Sinthetix
How do I cheat?
Reputation: 0

Joined: 17 Feb 2024
Posts: 4

PostPosted: Mon Feb 19, 2024 11:05 am    Post subject: Reply with quote

Theoretically it's easier than I thought to do that. But I need to test everything.

So I was already using getPreviousOpcode(RIP)
yes, that's important to have the address of the instruction which actually change the memory and not one after it, although the next instruction will be important later...

Next, I've tested and I actually can evaluate the address expression between [...] with this function: GetAddress("RAX+10")
that means I can use as you said this function disassemble(RIP) or this one: extra, opcode, bytes, address = splitDisassembledString(disassemble(RIP))
to extract the opcodes, then with a regular expression to find and extract the left and/or right expressions apart: mov RBX, [RAX+10].

Of course as you mentioned before it's hard to analyze all cases when an address is changed through some different instructions, but checking only something like mov or movaps should be enough to find a non shared instruction..

Next when an instruction execution breakpoint is triggered, in RIP register you have the address of the next instruction, that means you can remove the current breakpoint and set another to the next instruction.
When next one is triggered, I can evaluate the earlier saved address expression [RAX+10] and check if it matches the needed address.

Thanks for the help, I should give it a try
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 140

Joined: 06 Jul 2014
Posts: 4307

PostPosted: Mon Feb 19, 2024 1:41 pm    Post subject: Reply with quote

Sinthetix wrote:
Next when an instruction execution breakpoint is triggered, in RIP register you have the address of the next instruction, that means you can remove the current breakpoint and set another to the next instruction.
When next one is triggered, I can evaluate the earlier saved address expression [RAX+10] and check if it matches the needed address.
What? Why evaluate it after the instruction has executed? Just do it when the first breakpoint triggers. If you let the first instruction execute, you'll run into the problems I talked about previously regarding instructions that modify the register they're using to address a memory location (e.g. `mov rdx,[rdx+C]`). It's important to evaluate the expression immediately before such an instruction executes- not after.
_________________
I don't know where I'm going, but I'll figure it out when I get there.
Back to top
View user's profile Send private message
Sinthetix
How do I cheat?
Reputation: 0

Joined: 17 Feb 2024
Posts: 4

PostPosted: Mon Feb 19, 2024 2:23 pm    Post subject: Reply with quote

Yes, you are right, I figured this out already, I don't need a breakpoint on the next instruction,
I was keeping this idea when I thought about extracting the address from a single register after an eventual lea instruction, if no expression evaluation would have been possible...

Anyway It seems that it works as expected, I'm using this pattern to extract the expression if the instruction has an address expression in it:
Code:
local pat = ".*%[(.*)%].*"
then converting expression to uppercase.

The only problem now is that after the scripts completes the Memory Viewer window becomes broken.
I cannot scroll addresses anymore, well it scrolls but it shows wired info, closing/reopening doesn't help either, the main script loop is running in a separate thread to not block the main one. Should investigate more...
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 140

Joined: 06 Jul 2014
Posts: 4307

PostPosted: Mon Feb 19, 2024 2:48 pm    Post subject: Reply with quote

Sinthetix wrote:
the main script loop is running in a separate thread
Don't access the GUI from a separate thread.

I'm pretty sure the `disassemble` function uses the default disassembler. celua.txt:
Quote:
getDefaultDisassembler() - Returns the default disassembler object used by a lot of ce's disassembler routines (Only use this from the main thread)


You should be doing everything asynchronously. It's not like setBreakpiont blocks. Why use a separate thread?

If you need to do this in a separate thread, use `createDisassembler`

_________________
I don't know where I'm going, but I'll figure it out when I get there.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine 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