|
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
grease How do I cheat? Reputation: 0
Joined: 25 Mar 2023 Posts: 6
|
Posted: Sat Mar 25, 2023 7:29 pm Post subject: Assembly syntax question |
|
|
Hello friends! I'm new to using Cheat Engine and having a blast, but I can't quite figure out the assembly syntax for tutorial step 9. I keep getting this error when I try to compile a script to solve the challenge. The issue is from trying to mess with the floating point registers. Can someone maybe take a look at my script and let me know if you see me doing anything wrong?[/img]
Description: |
|
Filesize: |
5.96 KB |
Viewed: |
6631 Time(s) |
|
Description: |
|
Filesize: |
32.31 KB |
Viewed: |
6631 Time(s) |
|
|
|
Back to top |
|
|
ParkourPenguin I post too much Reputation: 147
Joined: 06 Jul 2014 Posts: 4518
|
Posted: Sat Mar 25, 2023 7:55 pm Post subject: |
|
|
memory-to-memory moves generally can't happen. Use a register as an intermediary.
If you're just moving data, `mov` w/ general purpose registers works fine. If you're doing any floating point arithmetic, use SSE instructions and registers (e.g. `movss`, `xmm0`).
`teamEnemyValue` is label that's undefined. Place it after a well-defined address.
`jmp returnhere` / `popfq` are placed after `"Tutorial-x86_64.exe"+2F25D`, not `newmem`. This will overwrite code after the injection point that you didn't intend to overwrite.
`popfq` isn't doing any good after the jump to the return label.
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
|
grease How do I cheat? Reputation: 0
Joined: 25 Mar 2023 Posts: 6
|
Posted: Sun Mar 26, 2023 11:38 am Post subject: |
|
|
Thanks for responding! I've seen your replies in other threads, thanks for being a resource. I am new to code injections and I'm having a lot of issues figuring out whats happening when I click execute.
`teamEnemyValue` is label that's undefined. Place it after a well-defined address.
What do you mean by this? I can see in the error message that it's getting shoved all the way to the top address ([fffffffffffffff]), but why? I was under the impression the function label(fooBar) would handle this mapping process. Does the order I place the labels in the script affect what memory address they're mapped to?
`jmp returnhere` / `popfq` are placed after `"Tutorial-x86_64.exe"+2F25D`, not `newmem`. This will overwrite code after the injection point that you didn't intend to overwrite.
This sounds like something really important I have yet to figure out. So from my understanding, we enter the script at the address label ""Tutorial-x86_64.exe"+2F25D`. After allocating some memory, we jump into this "memory cave" we created using the newmem label and start executing our fucker code. after that gets executed, we jump back to where the code should have executed to begin with (originalcode). My question is, how does the code get unintentionally overwritten? I see alot of people posting algorithms to do like one-hit-kills or something to solve the challenge, but haven't yet seen any explanation about the wrapper code that handles the injection itself. Does that make sense?
|
|
Back to top |
|
|
ParkourPenguin I post too much Reputation: 147
Joined: 06 Jul 2014 Posts: 4518
|
Posted: Sun Mar 26, 2023 12:45 pm Post subject: |
|
|
`label(fooBar)` simply tells CE there should be a symbol named "fooBar" that gets defined somewhere in the script. It declares the label exists: it doesn't define an address for it.
In order to define an address for a label, you have to place it in the script somewhere with a semicolon after it. i.e. `fooBar:`
The address it gets assigned is based on where it appears in the script.
Code: | label(example)
00401234:
example: | 00401234 is an address. Putting a semicolon after it tells CE that stuff after it should use that address. In this case, it defines the label `example` to be the address 00401234.
A slightly more complicated example:
Code: | alloc(newmem,4096)
label(myValue)
newmem:
mov eax,[rcx+08] // takes up 3 bytes
add eax,[myValue] // takes up 6 bytes
ret // takes up 1 byte
myValue:
dd 0 | Unlike `label`, `alloc` does define an address for the symbol. If `newmem` gets the address 02CA0000, then writing `newmem:` is like writing `02CA0000:`.
The instructions that come after that get written sequentially to the specified address. i.e.:
02CA0000 - mov eax,[rcx+08]
02CA0003 - add eax,[myValue]
02CA0009 - ret
The line `myValue:` now defines the symbol to be the address 02CA000A (1 after `ret`), and the `dd` writes the 4-byte integer 0 to that address (i.e. 02CA000A).
Use a template in the AA window and look at the code it generates.
This is a stripped-down version:
Code: | alloc(newmem,2048,"Tutorial-x86_64.exe"+2B4BC)
label(returnhere)
newmem:
sub [rbx+000007F8],eax
jmp returnhere
"Tutorial-x86_64.exe"+2B4BC:
jmp newmem
nop
returnhere:
/* Original code:
Tutorial-x86_64.exe+2B4AF - B9 05000000 - mov ecx,00000005 { 5 }
Tutorial-x86_64.exe+2B4B4 - E8 5747FEFF - call Tutorial-x86_64.exe+FC10
Tutorial-x86_64.exe+2B4B9 - 83 C0 01 - add eax,01 { 1 }
// Injecting here
Tutorial-x86_64.exe+2B4BC - 29 83 F8070000 - sub [rbx+000007F8],eax
// Done injecting
Tutorial-x86_64.exe+2B4C2 - 48 8D 4D F8 - lea rcx,[rbp-08]
Tutorial-x86_64.exe+2B4C6 - E8 45DAFDFF - call Tutorial-x86_64.exe+8F10
Tutorial-x86_64.exe+2B4CB - 8B 8B F8070000 - mov ecx,[rbx+000007F8]
*/ | `alloc` allocates memory. Ignore the label for now.
`newmem` is the memory you allocated. You're free to write whatever you want here. In this case, it just executes the original code and jumps to the return label.
`"Tutorial-x86_64.exe"+2B4BC` is the injection point. This address is the game's code. You have to be careful about what you modify here.
At the injection point, it must jump to your code (newmem) and then define a place for your code to jump back to (returnhere). The nop instruction is for padding: the original code takes up 6 bytes, but the `jmp` instruction only takes up 5 bytes. The single `nop` accounts for the missing byte so that the `returnhere` label gets defined to be the address of the next instruction (i.e. Tutorial-x86_64.exe+2B4C2).
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
|
grease How do I cheat? Reputation: 0
Joined: 25 Mar 2023 Posts: 6
|
Posted: Mon Mar 27, 2023 9:32 am Post subject: |
|
|
I'm understanding! Cool, so when programming in assembly, you have to pay attention to the amount of space your instructions themselves are filling. Especially at the injection point, where you have to make sure that the injection script itself doesn't alter the amount of memory the original instruction filled. In this case we can tell that the orignial instruction filled 6 bytes, because 2B4C2 - 2B4BC = 6
It helped alot!
EDIT: So I've had a couple hours to fuck around and try to fix it based off what you told me, and I'm still running into issues defining the address for TeamEnemyValue. I tried to place the label in a location that would be well definied in reference to newmem and got the same error I was getting before. I tried to experiment based on what I now know about how this script compiles by trying to define a location for the data in reference to newmem using arithmetic. This also did not work, for the same reason. It seems to me it does not like it when I try to leave a address to be defined at compile time, so trying to use newmem as a base raises errors. But I see other people format their code like this as well. Do you think I'm still making programming errors, or do you think there may be some issues with my settings?
Description: |
Tring to place label in a location that would be well defined in reference to newmem |
|
Filesize: |
21.22 KB |
Viewed: |
6546 Time(s) |
|
Description: |
Error from trying to place label in a location that would be well defined in reference to newmem |
|
Filesize: |
5.22 KB |
Viewed: |
6546 Time(s) |
|
Description: |
Tried to fix by defining data location through arithmetic |
|
Filesize: |
35.49 KB |
Viewed: |
6546 Time(s) |
|
Description: |
Error from trying to define a location through arithmetic |
|
Filesize: |
5.78 KB |
Viewed: |
6546 Time(s) |
|
|
|
Back to top |
|
|
ParkourPenguin I post too much Reputation: 147
Joined: 06 Jul 2014 Posts: 4518
|
Posted: Mon Mar 27, 2023 11:57 am Post subject: |
|
|
Instructions like `mov [rdx],[whatever]` tries to access 2 memory locations in the same instruction. As I've said before, this generally can't happen. You need to use a register as an intermediary. I'd suggest xmm0 since the game is already using it.
Code: | ...
newmem:
cmp [rbx+14],1
je code
movss xmm0,[TeamEnemyValue]
code:
movss [rbx+08],xmm0
jmp return
TeamEnemyValue:
dd (float)0
... |
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
|
grease How do I cheat? Reputation: 0
Joined: 25 Mar 2023 Posts: 6
|
Posted: Mon Mar 27, 2023 12:33 pm Post subject: |
|
|
Thank you based penguin. I was mistakenly equating registers and memory addresses. I am now a graduate of Cheat Engine Tutorial x86_64 academy
|
|
Back to top |
|
|
m0rc0m How do I cheat? Reputation: 0
Joined: 29 May 2023 Posts: 8 Location: sysadmin
|
Posted: Wed May 31, 2023 12:46 pm Post subject: |
|
|
You can't do memory to memory instructions
_________________
The end may justify the means as long as there is something that justifies the end. |
|
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
|
|