|
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
beyondoptics How do I cheat? Reputation: 0
Joined: 12 Jan 2022 Posts: 4
|
Posted: Thu Jan 13, 2022 12:34 am Post subject: What "calls" a Call? Breakpoints skipped? Logic or |
|
|
I have been trying to understand why and it's bothering me because I am taking an assembly course and yet I've got no explanation to how this happens.
I would appreciate some thoughts or help on understanding it.
Thanks in advance <3
Description: |
|
Filesize: |
173.99 KB |
Viewed: |
1201 Time(s) |
|
|
|
Back to top |
|
|
ParkourPenguin I post too much Reputation: 138
Joined: 06 Jul 2014 Posts: 4275
|
Posted: Thu Jan 13, 2022 2:50 am Post subject: |
|
|
I have no idea what you're asking. Are you confused why one breakpoint might trigger when another nearby doesn't?
Take this C code for example:
Code: | unsigned collatz(unsigned n) {
if (n % 2 == 0) {
return n / 2;
} else {
return 3*n+1;
}
} | If the argument is even, divide it by 2; else, multiply it by 3 and add 1.
This code will compile to this assembly:
Code: | collatz:
test dil, 1
jne .L2
mov eax, edi
shr eax
ret
.L2:
lea eax, [rdi+1+rdi*2]
ret
| If you set a breakpoint on the lea instruction, it won't trigger if the argument is even, because the processor took the first branch by falling through the jne instruction.
Similarly, when the argument is odd, the jne instruction will jump to the lea instruction. Instructions between them (i.e. mov / shr / ret) won't get executed, and any breakpoints on them won't trigger.
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
|
beyondoptics How do I cheat? Reputation: 0
Joined: 12 Jan 2022 Posts: 4
|
Posted: Thu Jan 13, 2022 11:24 am Post subject: |
|
|
Code: | collatz:
collatz:
test dil, 1
jne .L2
mov eax, edi
shr eax
ret
.L2:
lea eax, [rdi+1+rdi*2]
ret
|
Exactly! If I set a breakpoint on "test dil,1" it would trigger regardless of whether the number is even or odd right?
But based on the code that I showed in my first post, the first call should've been triggered even when I perform Action 1, or Action 2. Because there isn't any conditional jumps pointing to the calls.
So what bothers me, after looking at your code. It would make sense that when an argument is odd, the jne will jump to the lea instruction. But on the memory view of Cheat Engine, lea would have a "conditional jump marker" above the address.
In my code, there aren't any conditional jumps at all pointing to the calls. But it just confused me how an "odd number" triggers the first call and an "even number" could trigger the second call. When both of em should triggered by the "odd/even number" due to not having a conditional jump as the number would simply go through their instructions right?
Hahaha, am I over complicating this?
|
|
Back to top |
|
|
ParkourPenguin I post too much Reputation: 138
Joined: 06 Jul 2014 Posts: 4275
|
Posted: Thu Jan 13, 2022 1:39 pm Post subject: |
|
|
beyondoptics wrote: | Because there isn't any conditional jumps pointing to the calls. | You don't know that.
Jumps can come from very far away- certainly far enough to not be on the same screen as the location it's jumping to. CE has a "dissect code" tool that can analyze code and find some of these jumps; however, it won't find them all. Indirect jumps (e.g. jump table) won't be analyzed by CE.
For example, in your picture, the code at +255A3 is an unconditional jump to somewhere else. Something else surely jumps to the next instruction at +255A8.
I've also seen a game where it would overwrite the return address of a call to get it to return somewhere else other than the call site. I highly doubt this is the case here- it's extremely rare (outside of obfuscation) since it's a terrible thing to do.
If you're really confused, you can go to the start of the function and look at what happens from there, but you really need to know how to read assembly do to that.
I'm still confused by your picture. It looks like you have breakpoints on two call instructions (the ones highlighted in yellow). I don't know what the two big red/green square brackets to the right of the code are. I don't know what action 1 or 2 are referring to. I don't know what "the breakpoint in RED" means since both breakpoints are in the green square bracket.
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
|
beyondoptics How do I cheat? Reputation: 0
Joined: 12 Jan 2022 Posts: 4
|
Posted: Thu Jan 13, 2022 5:14 pm Post subject: |
|
|
I realized that my picture above is quite confusing. Sorry about that.
Lets say Action 1, is jumping while wearing a small hat. It will trigger all the lines marked with the red. Which would be :
+25A9C
+25AA1
+25AA3
Action 2, would be jumping while wearing a big hat. It will trigger all the lines marked in green. Which would be all the lines from : +25AA8 to +25AC1.
I just have no idea why both Action 1 and Action 2 doesn't trigger the call at +25A9C. Only Action 1.
And how come only Action 2 triggers a breakpoint at +25AA8.
Also, will a jmp trigger a breakpoint? Because +25A97 doesn't trigger one a t all. So I am assuming that it isn't executed at all. And the code only starts at +25A9C.
Description: |
|
Filesize: |
173.99 KB |
Viewed: |
1117 Time(s) |
|
|
|
Back to top |
|
|
ParkourPenguin I post too much Reputation: 138
Joined: 06 Jul 2014 Posts: 4275
|
Posted: Thu Jan 13, 2022 8:37 pm Post subject: |
|
|
Breakpoints trigger when the CPU tries to execute an instruction.
Action 1 triggers the breakpoint at +25A9C because it tried to execute that instruction. It won't trigger the breakpoint at +25AA8 because Action 1 jumps away before it reaches that instruction. Specifically, the jmp instruction at +25AA3 will cause the CPU running Action 1 to start executing code at +26EDE - the destination where the jmp instruction is jumping to.
For example:
Code: | code:
nop
jmp L1
int 3 // this instruction will never be executed- the jmp jumps over this instruction
L1:
ret |
Action 2 triggers the breakpoint at +25AA8 because it tried to execute that instruction. Action 2 won't trigger the breakpoint at +25A9C because it never tried to execute that instruction.
I don't know where Action 1 or Action 2 were before they started executing those instructions. My first guess is there's a couple jcc (conditional jump) instructions that jump to +25A9C for Action1 and +25AA8 for Action 2. If you use CE's "dissect code" feature, it should find those.
If the "dissect code" feature doesn't find anything, it's probably an indirect jump, such as a jump table. This is common in switch statements. e.g. this C code:
Code: | #include <stdio.h>
unsigned number;
void foo()
{
switch (number % 8) {
case 0:
puts("zero");
break;
case 1:
puts("one");
break;
case 2:
puts("two");
break;
case 3:
puts("three");
break;
case 4:
puts("four");
break;
case 5:
puts("five");
break;
case 6:
puts("six");
break;
case 7:
puts("seven");
break;
}
}
| Could be assembled like this (CE AA script):
Code: | [ENABLE]
globalalloc(foo,4096)
createthread(foo)
label(puts)
label(number)
registersymbol(number)
{$lua}
if syntaxcheck then return end
getDissectCode().clear()
createTimer(100, function()
getDissectCode().dissect(getAddress'foo', 4096)
end)
{$asm}
// code
foo:
mov eax, [number]
mov rcx, L4
and eax, 7
jmp [rcx+rax*8]
L3:
mov rdi, LC7
jmp puts
L10:
mov rdi, LC1
jmp puts
L9:
mov rdi, LC2
jmp puts
L8:
mov rdi, LC3
jmp puts
L7:
mov rdi, LC4
jmp puts
L6:
mov rdi, LC5
jmp puts
L5:
mov rdi, LC6
jmp puts
L2:
mov rdi, LC0
jmp puts
puts:
// print string literal
// stub: this does nothing
nop
ret
align 8 CC
// data
L4:
dq L2
dq L10
dq L9
dq L8
dq L7
dq L6
dq L5
dq L3
number:
resd 1
LC0:
db 'zero', 0
LC1:
db 'one', 0
LC2:
db 'two', 0
LC3:
db 'three', 0
LC4:
db 'four', 0
LC5:
db 'five', 0
LC6:
db 'six', 0
LC7:
db 'seven', 0
[DISABLE] | The LC* labels are the string literals, the L* labels are what gcc decided to output (not sure why it's in that odd order, but ok), and the puts function is just a stub in this code.
The important part is the instruction `jmp [rcx+rax*8]`- this is an indirect jump to some address in the jump table (label L4). CE's dissect code feature won't see it.
Start the CE tutorial (64-bit), attach to it, and enable/disable the script. Go to the address "foo" in the disassembler and set a breakpoint near the start (e.g. `mov rcx, L4`). Enable the script and step over instructions to watch what happens. Add a memory record with address "number" and change it if you want.
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
|
beyondoptics How do I cheat? Reputation: 0
Joined: 12 Jan 2022 Posts: 4
|
Posted: Thu Jan 13, 2022 9:53 pm Post subject: |
|
|
Oh I finally understand now! Thanks so much for your time with explaining all these. It really opened my eyes alot. <3
|
|
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
|
|