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 


Help with Unstable Auto Assembly Script

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

Joined: 22 Nov 2023
Posts: 5

PostPosted: Tue Nov 28, 2023 4:57 pm    Post subject: Help with Unstable Auto Assembly Script Reply with quote

Hi, I'm having trouble with this script for Laika Aged Through Blood, tested on the previous version (1.0.3) and latest version (released today 2023-11-28, looks like 1.0.13, steam build number: 21306022). This Auto Assembly script initializes and updates pointers to a construct which holds current ammo and another construct which holds max ammo. It activates when the player fires their weapon. Most of the time it works perfectly fine, but it occasionally won't load and other times crashes the game when activated (on firing the weapon). It's odd because when it starts crashing, it crashes consistently. Then after a while it will stop crashing. Can anyone identify any issues that may be causing this?

Code:


//Initialization script:

{$lua}
LaunchMonoDataCollector()
{$asm}

[ENABLE]

  globalalloc(activeWeapon,4)
  activeWeapon:
  dd #0

{$lua}

getAddressList().getMemoryRecordByDescription('asmGetBaseWeapon').Active=true

{$asm}

[DISABLE]

{$lua}

getAddressList().getMemoryRecordByDescription('asmGetBaseWeapon').Active=false

{$asm}

//-----------------------Different script----------------------//

//Script - asmGetBaseWeapon:

[ENABLE]

aobscanregion(Ammo_Dec_AOB,WeaponData:Shoot+8f4,WeaponData:Shoot+10f4,FF CA 89 50 20) // Not sure about this range for scanning. I borrowed this from ColonelRVH who made a trainer for v1.0.2. I don't know if there's a methodology for finding the best scan range, but this one seems to work, at least most of the time. This may be why the script doesn't load sometimes, but as I understand it this should not crash the game if it fails.

alloc(newmem,$1000)

label(code)
label(return)

alloc(baseWeapon,8) // will hold the pointer for the construct which has current ammo
alloc(baseWeaponData,8) // will hold the pointer for the construct which has max ammo

registersymbol(baseWeapon)
registersymbol(baseWeaponData)

newmem:
  mov [baseWeapon],rax // Copy pointer for the construct which holds current ammo for use in cheat table/another script.
  mov r10,[rax+10] -- This is the pointer for the construct with holds max ammo. I picked a register at random to store this, so this may be an issue. I'm not sure how to figure out which registers are available to use. However, the script had issues before I added this line so it is likely not the main culprit.
  mov [baseWeaponData],r10 // Move the copied pointer to a symbol for use in cheat table/another script.
  mov [activeWeapon],#1 // The game has different constructs for the crossbow, so we need to keep track of which weapon is equipped. This doesn't work great because it only updates when firing the weapon. Haven't yet found anything else I can use. This is initialized using globalalloc in the initialization script. This also is likely not the issue as the crashes occurred before I added this.
  jmp code

// original code, unchanged.
code:
  dec edx // decrease ammo
  mov [rax+20],edx // copy new ammo amount to ammo pointer
  jmp return

Ammo_Dec_AOB:
  jmp newmem
return:
registersymbol(Ammo_Dec_AOB)

[DISABLE]

Ammo_Dec_AOB:
  db FF CA 89 50 20

unregistersymbol(Ammo_Dec_AOB)
unregistersymbol(baseWeapon)
unregistersymbol(baseWeaponData)
dealloc(newmem)
dealloc(baseWeapon)
dealloc(baseWeaponData)



Also, if anyone knows how to skip all the crap they show before the main menu, please let me know. It's like 30 seconds worth of intro videos/messages. It's driving me nuts.
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 152

Joined: 06 Jul 2014
Posts: 4717

PostPosted: Tue Nov 28, 2023 7:04 pm    Post subject: Reply with quote

No need for `baseWeaponData`. You're already copying rax- just use that and add another offset.

You're not accounting for RIP-relative addressing. There's no guarantee `newmem` is close enough to the injection point (this may crash the game), and likewise for `activeWeapon` and `newmem` (at least CE will complain in that case).
Use the AOBScan template. If you don't know what something in the template does, don't remove it.

Don't overwrite general purpose registers as you see fit. At least push / pop them.

Why two different scripts?

_________________
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
sklskl
How do I cheat?
Reputation: 0

Joined: 22 Nov 2023
Posts: 5

PostPosted: Tue Nov 28, 2023 7:53 pm    Post subject: Reply with quote

Quote:

No need for `baseWeaponData`. You're already copying rax- just use that and add another offset.


Ah, okay. I don't know why that didn't occur to me.

Quote:

You're not accounting for RIP-relative addressing. There's no guarantee `newmem` is close enough to the injection point (this may crash the game), and likewise for `activeWeapon` and `newmem` (at least CE will complain in that case).
Use the AOBScan template. If you don't know what something in the template does, don't just remove it.


I am aware it is good practice to allocate the memory close to the injection point, but I wasn't aware it could crash the game. If that's the problem, that would explain why the crashes are intermittent. I'll give that a shot.

Quote:

Don't just overwrite general purpose registers as you see fit. At least push / pop them.


I know it is a bad idea, I just wasn't sure how to go about avoiding it. I wasn't even sure what to Google. I am very new to assembly. Push/Pop sounds like the right answer, but I guess it's a moot point since it looks like I don't need `baseWeaponData`.

Quote:

Why two different scripts?


If I understand your question correctly, you're asking why I am initializing `activeWeapon` outside of the asmGetBaseWeapon script. I have several scripts that need to be able to either read or write to `activeWeapon` and they all need to know for sure that it exists (or they won't assemble). The game sometimes uses a different structure (requiring a different injection point) depending on the weapon you have equipped, so each one has its own methodology and script. This makes it necessary to keep track of which weapon/structure is active at a given time. I tried several approaches and this is the one that worked. I also wanted flexibility to turn on and off different operations to help me diagnose where a crash is coming from. Not sure if that answers your question.

Thanks ParkourPenguin!
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 152

Joined: 06 Jul 2014
Posts: 4717

PostPosted: Tue Nov 28, 2023 8:59 pm    Post subject: Reply with quote

sklskl wrote:
I know it is a bad idea, I just wasn't sure how to go about avoiding it. I wasn't even sure what to Google. I am very new to assembly. Push/Pop sounds like the right answer, but I guess it's a moot point since it looks like I don't need `baseWeaponData`.
In general, code injections should try to disturb the game as little as possible.
If this is the original code:
Code:
mov ecx,[rbx+10]
Before this instruction is executed, you obviously don't want to set rbx to 0 and leave it like that because that would crash the game. Use push/pop if it's necessary to use rbx.
Code:
push rbx
mov rbx,whatever
...
pop rbx

mov ecx,[rbx+10]

Modifying ecx is fine since the game overwrites it. No need for push/pop.
Code:
//push rcx
mov rcx,whatever
...
//pop rcx

mov ecx,[rbx+10]
(note that push/pop temporarily modifies rsp)

sklskl wrote:
I have several scripts that need to be able to either read or write to `activeWeapon` and they all need to know for sure that it exists (or they won't assemble).
One alternative is to put `globalalloc(activeWeapon,4)` in all of those scripts. `globalAlloc` allocates some memory and associates it with a symbol only once. It never gets deallocated, nor will it allocate more memory for that same symbol. It gets allocated once and reused from that point on. CE will complain if you use a different amount of memory (e.g. say 4 bytes in one script and 8 bytes in another).
_________________
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
sklskl
How do I cheat?
Reputation: 0

Joined: 22 Nov 2023
Posts: 5

PostPosted: Wed Nov 29, 2023 10:17 pm    Post subject: Reply with quote

Thanks again @ParkourPenguin!

Quote:

One alternative is to put `globalalloc(activeWeapon,4)` in all of those scripts. `globalAlloc` allocates some memory and associates it with a symbol only once. It never gets deallocated, nor will it allocate more memory for that same symbol. It gets allocated once and reused from that point on. CE will complain if you use a different amount of memory (e.g. say 4 bytes in one script and 8 bytes in another).


Awesome, this is good to know.

Using your advice I cleaned up the scripts and have had no crashes since.

One thing that I'm still wondering, is there a methodology for determining the scan area for an AOB scan? Let's say I have the following injection point using the 'Full injection' template:

Code:

{
// ORIGINAL CODE - INJECTION POINT: WeaponArm:SwitchWeapon+400
WeaponArm:SwitchWeapon+3d2: 48 89 45 90                    - mov [rbp-70],rax
WeaponArm:SwitchWeapon+3d6: 49 BA 48 91 7E 51 3C 02 00 00  - mov r10,0000023C517E9148
//..
// ---------- INJECTING HERE ----------
WeaponArm:SwitchWeapon+400: 48 63 51 3C                    - movsxd  rdx,dword ptr [rcx+3C]
// ---------- DONE INJECTING  ----------
//..
WeaponArm:SwitchWeapon+426: 49 BB E0 04 26 16 3D 02 00 00  - mov r11,WeaponArm:EquipWeapon
WeaponArm:SwitchWeapon+430: 41 FF D3                       - call r11
}


Is there some way to determine a good starting and ending point for the scan? The starting point of the injection template is:

3d2 (hex) = 978 (dec)
and the ending point is
430 (hex) = 1072 (dec)

I subtracted/added a few hundred rounded (bytes?) on either side and got:

2BC (hex) = 700 (dec)
514 (hex) = 1300 (dec)

which results in:

Code:

aobscanregion(WeaponSwitch_AOB,WeaponArm:SwitchWeapon+2BC,WeaponArm:SwitchWeapon+514,48 63 51 3C 48 8B C8)


Is this an acceptable way to do it? Is there a better way?
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 152

Joined: 06 Jul 2014
Posts: 4717

PostPosted: Wed Nov 29, 2023 10:56 pm    Post subject: Reply with quote

Not really. I don't know why the original author is restricting it that much to begin with. The main reason for aobscanregion is to speed up the scan drastically. Changing the size of the scan region by a few thousand bytes wouldn't noticeably change the speed of the scan. I'd put the starting location at +0 and the ending location at +2000 or something- CE can scan through a couple pages of memory pretty much instantly.

Maybe there's more than one result in that same region. Do an aobscan in CE's main window for that pattern (search all memory, not just writable) and see what comes up. If it's just one result, there's no need to think about the start/end region that much. If there's multiple and they're both in the same function, try to separate them as best you can. e.g. maybe only check the second half of the function or something. Worst case, you can use a {$lua} block to get all the aobscan results in that region and manually pick the first, second, third, etc. results.

_________________
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