 |
Cheat Engine The Official Site of Cheat Engine
|
| View previous topic :: View next topic |
| Author |
Message |
Lost_Warrior How do I cheat?
Reputation: 0
Joined: 07 Aug 2021 Posts: 3
|
Posted: Sat Aug 07, 2021 8:37 pm Post subject: Finding "opposite" of a number using AA |
|
|
Hello, I have searched for an answer to a problem I have with no avail and this may need to be under the lua section but I'm not sure..
Basically I have an address whose value changes every time the game is launched and to get the result i am looking for I need the address to be the "opposite" number per se.
Example: lets say the value of the address is (2bytes): 35792 and I need it to become a value of: 29743 (which is 65535-35792). But when the game restarts the value is now 56781 and needs to become 8754 (65535-56781). When disabled the script would also return the original value of the address.
I assume I would need something similar to this but not sure how to complete it and make it work. It may not even be remotely close but hopefully it can help
| Code: |
[ENABLE]
AOBSCAN(arraystart,4D 50 30 5F 54 41 54 54 4F 4F 5F 46 4D 5F 55 4E 4C 4F 43 4B 53 5F 31 37)
RegisterSymbol(StartAddress)
label(StartAddress)
arraystart-10:
StartAddress:
//probably need some form of alloc for functions?
OriginalValue:
readmem(Starting Address)
label(OriginalValue)
NewValue:
sub FFFF,OriginalValue //this would be 65535-35792 for example
label(NewValue)
mov StartAddress,NewValue
[DISABLE]
mov StartAddress,OriginalValue
|
|
|
| Back to top |
|
 |
TheyCallMeTim13 Wiki Contributor
Reputation: 51
Joined: 24 Feb 2017 Posts: 976 Location: Pluto
|
|
| Back to top |
|
 |
ParkourPenguin I post too much
Reputation: 152
Joined: 06 Jul 2014 Posts: 4706
|
Posted: Sat Aug 07, 2021 11:16 pm Post subject: |
|
|
That isn't remotely close to how AA scripts work.
If you're doing an aobscan for data and not code, I'd recommend you use Lua AOBScan to specify alignment and permissions. In fact you may as well do everything in Lua. Use AA and you'd need to allocate memory and create a thread in the game. That's ridiculous when CE can do the same thing by simply reading and writing a value.
Something like this (untested):
| Code: | {$lua}
if syntaxcheck then return end
local symbolname = 'StartAddress'
[ENABLE]
if getAddressSafe(symbolname) then
unregisterSymbol(symbolname)
end
local result = assert(AOBScan('4D 50 30 5F 54 41 54 54 4F 4F 5F 46 4D 5F 55 4E 4C 4F 43 4B 53 5F 31 37', '+W-C', fsmAligned, '2'))
local addr = getAddress(result[0])
result.destroy()
registerSymbol(symbolname, addr, true)
addr = addr - 0x10
writeSmallInteger(addr, readSmallInteger(addr) ~ 0xFFFF)
[DISABLE]
local addr = getAddress(symbolname) - 0x10
unregisterSymbol(symbolname)
writeSmallInteger(addr, readSmallInteger(addr) ~ 0xFFFF)
|
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
| Back to top |
|
 |
Lost_Warrior How do I cheat?
Reputation: 0
Joined: 07 Aug 2021 Posts: 3
|
Posted: Sun Aug 08, 2021 12:17 am Post subject: |
|
|
| ParkourPenguin wrote: | That isn't remotely close to how AA scripts work.
If you're doing an aobscan for data and not code, I'd recommend you use Lua AOBScan to specify alignment and permissions. In fact you may as well do everything in Lua. Use AA and you'd need to allocate memory and create a thread in the game. That's ridiculous when CE can do the same thing by simply reading and writing a value.
Something like this (untested):
| Code: | {$lua}
if syntaxcheck then return end
local symbolname = 'StartAddress'
[ENABLE]
if getAddressSafe(symbolname) then
unregisterSymbol(symbolname)
end
local result = assert(AOBScan('4D 50 30 5F 54 41 54 54 4F 4F 5F 46 4D 5F 55 4E 4C 4F 43 4B 53 5F 31 37', '+W-C', fsmAligned, '2'))
local addr = getAddress(result[0])
result.destroy()
registerSymbol(symbolname, addr, true)
addr = addr - 0x10
writeSmallInteger(addr, readSmallInteger(addr) ~ 0xFFFF)
[DISABLE]
local addr = getAddress(symbolname) - 0x10
unregisterSymbol(symbolname)
writeSmallInteger(addr, readSmallInteger(addr) ~ 0xFFFF)
|
|
This does exactly what I've been trying to do and Thank you.
I know what i wrote down was sloppy but it was meant to be a general guideline of what I wanted to happen. Writing it out helped me to think about it more and go back because I think i was over complicating it in my head.
When I went back to figure it out I had this but couldn't get past the sub part as it would just say Error sub ffff+16, ffff+8. I don't even know if it would work in the end once i figured out everything as this is probably the most I've done with AA by myself.
If possible could you break down what you wrote so that I may learn more about what is happening to at least learn something? and tell me if my original idea below would even work in the end once it is compiled correctly?
| Code: |
[ENABLE]
AOBSCAN(arraystart,4D 50 30 5F 54 41 54 54 4F 4F 5F 46 4D 5F 55 4E 4C 4F 43 4B 53 5F 31 37)
RegisterSymbol(StartAddress)
label(StartAddress)
arraystart-10:
StartAddress:
registersymbol(NewMem)
label(NewMem)
NewMem:
alloc(NewMem,2048):
NewMem+8:
readmem(StartAddress,2)
NewMem+16:
dd FFFF
NewMem+24:
sub NewMem+16,NewMem+8
StartAddress:
readmem(Newmem+24,2)
[DISABLE]
StartAddress:
readmem(NewMem+8,2)
|
[/code]
|
|
| Back to top |
|
 |
ParkourPenguin I post too much
Reputation: 152
Joined: 06 Jul 2014 Posts: 4706
|
Posted: Sun Aug 08, 2021 12:59 am Post subject: |
|
|
A {$lua} block returns a string that gets substituted back into the AA script. If you're just using a Lua block for its side effects (as is the case here), then you don't need to return anything and it won't affect anything. In the case of this script, there is no actual AA code: as far as the auto assembler is concerned, the script is blank:
AA scripts can go through a "dry-run" that checks the syntax of the script. This happens before executing the script among other times. Since {$lua} blocks can affect the AA script, they need to be run during this syntax check. If the {$lua} block is only used for its side effects, it's usually fine to skip executing it during this syntax check. CE sets a local variable "syntaxcheck" to true when doing a syntax check so you can check this.
[ENABLE] and [DISABLE] are like preprocessor directives. Everything above [ENABLE] is always included, everything between [ENABLE] and [DISABLE] is included only when the script is enabled, and everything after [DISABLE] is included only when the script is disabled.
Those Lua functions are documented in celua.txt. AOBScan will return nil if there are no results (hence the assert), the results it gives are a stringlist IIRC (index starts at 0 and the object should be destroyed), and registerSymbol can give an error if the symbol is already registered (unlike AA registersymbol).
Beyond that it's just standard Lua 5.3 code.
The biggest thing you're not understanding about AA is that instructions like sub or xor aren't executed by CE. They're assembled into machine code (array of bytes) and written into the game. Those instructions don't get executed on their own: usually one of the game's threads is expected to eventually execute them.
In this case, you'd need to make your own thread:
| Code: | [ENABLE]
AOBSCAN(arraystart,4D 50 30 5F 54 41 54 54 4F 4F 5F 46 4D 5F 55 4E 4C 4F 43 4B 53 5F 31 37)
alloc(newmem,4096)
createthread(newmem)
newmem:
mov rax,arraystart
not word ptr[rax-10]
mov rcx,newmem
xor edx,edx
mov r8d,8000
jmp kernel32.VirtualFree
[DISABLE]
|
Allocating a page of memory and creating a thread just to execute a single not instruction is ridiculous.
The last 4 instructions are a tail call to VirtualFree. If CE tries to deallocate memory while the script is running (e.g. call dealloc under [DISABLE]), the thread might try to execute unmapped memory and crash the process. This surely isn't a problem in this case since the thread should end almost immediately, but it's good to know in general.
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
| Back to top |
|
 |
Lost_Warrior How do I cheat?
Reputation: 0
Joined: 07 Aug 2021 Posts: 3
|
Posted: Sun Aug 08, 2021 12:23 pm Post subject: |
|
|
| ParkourPenguin wrote: | A {$lua} block returns a string that gets substituted back into the AA script. If you're just using a Lua block for its side effects (as is the case here), then you don't need to return anything and it won't affect anything. In the case of this script, there is no actual AA code: as far as the auto assembler is concerned, the script is blank:
AA scripts can go through a "dry-run" that checks the syntax of the script. This happens before executing the script among other times. Since {$lua} blocks can affect the AA script, they need to be run during this syntax check. If the {$lua} block is only used for its side effects, it's usually fine to skip executing it during this syntax check. CE sets a local variable "syntaxcheck" to true when doing a syntax check so you can check this.
[ENABLE] and [DISABLE] are like preprocessor directives. Everything above [ENABLE] is always included, everything between [ENABLE] and [DISABLE] is included only when the script is enabled, and everything after [DISABLE] is included only when the script is disabled.
Those Lua functions are documented in celua.txt. AOBScan will return nil if there are no results (hence the assert), the results it gives are a stringlist IIRC (index starts at 0 and the object should be destroyed), and registerSymbol can give an error if the symbol is already registered (unlike AA registersymbol).
Beyond that it's just standard Lua 5.3 code.
The biggest thing you're not understanding about AA is that instructions like sub or xor aren't executed by CE. They're assembled into machine code (array of bytes) and written into the game. Those instructions don't get executed on their own: usually one of the game's threads is expected to eventually execute them.
In this case, you'd need to make your own thread:
| Code: | [ENABLE]
AOBSCAN(arraystart,4D 50 30 5F 54 41 54 54 4F 4F 5F 46 4D 5F 55 4E 4C 4F 43 4B 53 5F 31 37)
alloc(newmem,4096)
createthread(newmem)
newmem:
mov rax,arraystart
not word ptr[rax-10]
mov rcx,newmem
xor edx,edx
mov r8d,8000
jmp kernel32.VirtualFree
[DISABLE]
|
Allocating a page of memory and creating a thread just to execute a single not instruction is ridiculous.
The last 4 instructions are a tail call to VirtualFree. If CE tries to deallocate memory while the script is running (e.g. call dealloc under [DISABLE]), the thread might try to execute unmapped memory and crash the process. This surely isn't a problem in this case since the thread should end almost immediately, but it's good to know in general. |
Interesting. After seeing the normal AA version compared to the lua version I can understand the lua version much better than just the A version.
I also find it strange there isn't an easier way to do math using AA and when looking at the wiki it said you can use symbols with the sub command but maybe I misunderstood something.
This tells me to go and learn more lua to not ask another stupid question and thank you again.
|
|
| Back to top |
|
 |
ParkourPenguin I post too much
Reputation: 152
Joined: 06 Jul 2014 Posts: 4706
|
Posted: Sun Aug 08, 2021 7:51 pm Post subject: |
|
|
It's not a stupid question. Everyone starts somewhere.
The AA just isn't used for that kind of thing. It's not really a scripting language in the same way Lua is. AA code is mainly used to change the game's code and that's it. Automating stuff like changing values in special ways is best done by Lua.
_________________
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
|
|