 |
Cheat Engine The Official Site of Cheat Engine
|
| View previous topic :: View next topic |
| Author |
Message |
HenryEx Expert Cheater
Reputation: 2
Joined: 18 Dec 2011 Posts: 100
|
Posted: Fri Jan 13, 2012 7:21 am Post subject: [AA] Checking bit arrays / Loading & Saving Data |
|
|
So i'm working on a table with a big single script that has several optional functions. I'm currently allocating a byte "flag" for every function and let the code check whether the value is zero or not.
Since CE can actually read/display single bits, i want to try my hand at a bit array for these On/Off switches, but i'm not sure how i can actually check the value of a certain bit conveniently and quickly. Do i shift the register left and right to isolate the bit? Or do i AND with the value to expect?
Currently i'm doing:
cmp byte ptr [FlagAddress],00
je _BackToCode
Is there anything as simple as that?
Also, another question. I'm not sure if this can be done in Auto Assembler. You can assign scripts to hotkeys, right? I want to save certain values in memory (coordinates, ca. 50 bytes) to an address i have allocated myself by pressing a hotkey. Then i want to load these coordinates from the allocated space back into the game memory with another hotkey.
How would i go about doing this? It seems that, with AA scripts, i always have to rely on the game to execute the code i write.
|
|
| Back to top |
|
 |
Dark Byte Site Admin
Reputation: 474
Joined: 09 May 2003 Posts: 25930 Location: The netherlands
|
Posted: Fri Jan 13, 2012 1:39 pm Post subject: |
|
|
you could use the "test" command instead of cmp to set the eflags
the ZF flag gets set if (result1 AND result2)== 0
meaning, it gets set if the flag was NOT present in the value
e.g:
| Code: |
test [FlagAddress],8 //check if bit 3 is set
jnz theflagisset
|
as for assigning hotkeys to scripts there are multiple ways
first method is making the script into a cheat table entry ([enable]/[disable] section) and then add a hotkey to the entry that toggles it
another method is to write a lua function that when called calls autoassemble(yourscript)
and then use createHotkey("functionname", hotkey1, hotkey2, hotkey3...) to register the hotkey which will execute your lua function when pressed
---
For your problem though you will either need an AA script injected in a active part of the game where you check with GetKeystate if the keys are pressed and then do your stuff, or use a LUA script triggered by a hotkey that reads the memory and writes it to the game
_________________
Tools give you results. Knowledge gives you control.
Like my help? Join me on Patreon so i can keep helping |
|
| Back to top |
|
 |
HenryEx Expert Cheater
Reputation: 2
Joined: 18 Dec 2011 Posts: 100
|
Posted: Sat Jan 14, 2012 3:01 pm Post subject: |
|
|
Thanks, "test" works pretty good and it's short to boot!
Now here's a marginally more complex situation, where i need to check the status of two flags and then decide where to go. There's options for one flag, the other flag, or both at once. Things suddenly got a lot more complicated, since i can't just check if test returns zero.
This is how i solved the problem for now:
| Code: | push eax // Back up register
mov al,byte ptr [bArray1+1] // Load boolean flags
and al,3 // Check only the two flags we want
cmp al,3 // Check both
je _Both // Jump if true
cmp al,2 // Check second flag
je _Second // Jump if true
cmp al,1 // Check first flag
je _First // Jump if true |
(the code for no flag comes right afterwards)
This is not only huge, but also uses a register. That tripped me up good, because some original game code in that function modified the stack pointer before i could pop eax again to get it back in every case. Took me a while to find out that was the reason the program crashed.
Is there a way to make this simpler or shorter and not use a register?
|
|
| Back to top |
|
 |
Dark Byte Site Admin
Reputation: 474
Joined: 09 May 2003 Posts: 25930 Location: The netherlands
|
Posted: Sat Jan 14, 2012 9:40 pm Post subject: |
|
|
I think you can use "test" here as well so it doesn't modify any register except the eflags, but will be about as long, but probably easier to read
| Code: |
test byte ptr [bArray1+1],3 //will 'AND' the byte with the value 3. Z flag will be 0 if both bits are set to 1
jnz _Both
test byte ptr [bArray1+1],2
jnz _Second
test byte ptr [bArray1+1],1
jnz _First
_Neither:
...
|
Also, using registers should not be a problem as long as you do a restore of the registers before you even consider executing the original code
based on your original code:
| Code: |
push eax // Back up register
mov al,byte ptr [bArray1+1] // Load boolean flags
and al,3 // Check only the two flags we want
cmp al,3 // Check both
je _Both // Jump if true
cmp al,2 // Check second flag
je _Second // Jump if true
cmp al,1 // Check first flag
je _First // Jump if true
_neither:
pop eax
...
_Both:
pop eax
//yourcode for _Both
_Second:
pop eax
//your code for _Second
_First:
pop eax
//your code for _First
|
Note: If the original code is a intruction that's based on the eflags state, also push the eflags registers(Conditional jumps, conditional sets, etc...), even with the 'test' method
_________________
Tools give you results. Knowledge gives you control.
Like my help? Join me on Patreon so i can keep helping |
|
| Back to top |
|
 |
HenryEx Expert Cheater
Reputation: 2
Joined: 18 Dec 2011 Posts: 100
|
Posted: Sat Jan 14, 2012 9:54 pm Post subject: |
|
|
Thanks for the tip about saving flags.
Also, correct me if i'm wrong, but "test" is basically a logical AND that doesn't save the result, right? So if i AND 1 and 3...
| Code: |
0 0 0 1 flags (only 1)
0 0 1 1 check (for both)
--------
0 0 0 1 result |
... the result is not zero (so ZF=0) even if not both of the flags are set.
So the first jump would trigger any time one of the flags or both are set.
That was the problem that led me to the cmp stuff. I'm not sure how test sets flags, though.
|
|
| Back to top |
|
 |
Dark Byte Site Admin
Reputation: 474
Joined: 09 May 2003 Posts: 25930 Location: The netherlands
|
Posted: Sat Jan 14, 2012 10:28 pm Post subject: |
|
|
Ah yes, you're right
I think the only solution is to use registers then(or compare against all byte combinations that have one or both of the bits set...)
Not really a problem as long as you keep track of the registers you use (you don't have to use al, you can use any other register as well)
_________________
Tools give you results. Knowledge gives you control.
Like my help? Join me on Patreon so i can keep helping |
|
| Back to top |
|
 |
HenryEx Expert Cheater
Reputation: 2
Joined: 18 Dec 2011 Posts: 100
|
Posted: Sat Jan 14, 2012 10:57 pm Post subject: |
|
|
It now occurs to me that i could still use test if i reorder the checks like so:
| Code: |
test byte ptr [bArray1+1],1 // check for 1st flag only
jnz _First
test byte ptr [bArray1+1],2 // check for 2nd flag only
jnz _Second
test byte ptr [bArray1+1],3 // check for any of the two
jnz _Both
_Neither:
... |
Since the first two cases are checked beforehand, the only possible outcome for the check against 3 is that both flags are set.
No register stuff! Though i guess i can't check for both if i don't check for the single cases before that...
|
|
| Back to top |
|
 |
Dark Byte Site Admin
Reputation: 474
Joined: 09 May 2003 Posts: 25930 Location: The netherlands
|
Posted: Sat Jan 14, 2012 11:00 pm Post subject: |
|
|
Hmm, this won't work
if bArray1+1 has both flags set it will jump to _first as well
_________________
Tools give you results. Knowledge gives you control.
Like my help? Join me on Patreon so i can keep helping |
|
| 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
|
|