Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


Finding "opposite" of a number using AA

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine
View previous topic :: View next topic  
Author Message
Lost_Warrior
How do I cheat?
Reputation: 0

Joined: 07 Aug 2021
Posts: 3

PostPosted: Sat Aug 07, 2021 8:37 pm    Post subject: Finding "opposite" of a number using AA Reply with quote

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
View user's profile Send private message
TheyCallMeTim13
Wiki Contributor
Reputation: 51

Joined: 24 Feb 2017
Posts: 976
Location: Pluto

PostPosted: Sat Aug 07, 2021 8:56 pm    Post subject: Reply with quote

You could just use SUB, but XOR sounds more like what you want.
Code:
xor ax,FFFF


https://www.felixcloutier.com/x86/xor

_________________
Back to top
View user's profile Send private message Visit poster's website
ParkourPenguin
I post too much
Reputation: 152

Joined: 06 Jul 2014
Posts: 4706

PostPosted: Sat Aug 07, 2021 11:16 pm    Post subject: Reply with quote

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
View user's profile Send private message
Lost_Warrior
How do I cheat?
Reputation: 0

Joined: 07 Aug 2021
Posts: 3

PostPosted: Sun Aug 08, 2021 12:17 am    Post subject: Reply with quote

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
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 152

Joined: 06 Jul 2014
Posts: 4706

PostPosted: Sun Aug 08, 2021 12:59 am    Post subject: Reply with quote

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:
Code:
[ENABLE]
[DISABLE]

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
View user's profile Send private message
Lost_Warrior
How do I cheat?
Reputation: 0

Joined: 07 Aug 2021
Posts: 3

PostPosted: Sun Aug 08, 2021 12:23 pm    Post subject: Reply with quote

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:
Code:
[ENABLE]
[DISABLE]

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
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 152

Joined: 06 Jul 2014
Posts: 4706

PostPosted: Sun Aug 08, 2021 7:51 pm    Post subject: Reply with quote

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
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites