|
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
Sinthetix How do I cheat? Reputation: 0
Joined: 17 Feb 2024 Posts: 4
|
Posted: Sat Feb 17, 2024 3:08 pm Post subject: Find what instructions are acessing a range of addresses |
|
|
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 |
|
|
ParkourPenguin I post too much Reputation: 140
Joined: 06 Jul 2014 Posts: 4307
|
Posted: Sat Feb 17, 2024 4:29 pm Post subject: |
|
|
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 |
|
|
Sinthetix How do I cheat? Reputation: 0
Joined: 17 Feb 2024 Posts: 4
|
Posted: Sun Feb 18, 2024 7:18 pm Post subject: |
|
|
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
or this
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 |
|
|
ParkourPenguin I post too much Reputation: 140
Joined: 06 Jul 2014 Posts: 4307
|
Posted: Sun Feb 18, 2024 8:42 pm Post subject: |
|
|
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 |
|
|
Dark Byte Site Admin Reputation: 458
Joined: 09 May 2003 Posts: 25300 Location: The netherlands
|
Posted: Mon Feb 19, 2024 3:55 am Post subject: |
|
|
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 |
|
|
Sinthetix How do I cheat? Reputation: 0
Joined: 17 Feb 2024 Posts: 4
|
Posted: Mon Feb 19, 2024 11:05 am Post subject: |
|
|
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 |
|
|
ParkourPenguin I post too much Reputation: 140
Joined: 06 Jul 2014 Posts: 4307
|
Posted: Mon Feb 19, 2024 1:41 pm Post subject: |
|
|
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 |
|
|
Sinthetix How do I cheat? Reputation: 0
Joined: 17 Feb 2024 Posts: 4
|
Posted: Mon Feb 19, 2024 2:23 pm Post subject: |
|
|
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 |
|
|
ParkourPenguin I post too much Reputation: 140
Joined: 06 Jul 2014 Posts: 4307
|
Posted: Mon Feb 19, 2024 2:48 pm Post subject: |
|
|
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 |
|
|
|
|
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
|
|