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 


Cannot disable AA script
Goto page 1, 2  Next
 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General Gamehacking
View previous topic :: View next topic  
Author Message
Sarge411
Newbie cheater
Reputation: 0

Joined: 21 Apr 2018
Posts: 21

PostPosted: Wed Apr 25, 2018 2:30 pm    Post subject: Cannot disable AA script Reply with quote

This is a followup on this topic

forum[dot]cheatengine[dot]org[slash]viewtopic[dot]php?p=5738370

I've written a script that should set the player's health to 0 upon enabling and back to its original value upon re-enabling:

Code:

{ Game   : Duke3dw.exe
  Version:
  Date   : 2018-04-25
  Author : Sarge411

  This script does blah blah blah
}

[ENABLE]

aobscanmodule(INJECT,Duke3dw.exe,0F BF 54 91 0A) // should be unique
alloc(newmem,$1000)


alloc(healthValue, 4)
alloc(healthAddress, 4)
registersymbol(healthValue)
registersymbol(healthAddress)
healthValue:
  dd 0
healthAddress:
  dd 0

label(code)
label(return)

newmem:
  // Duke dies
  pushfd
  push eax
  push ebx
  mov eax, 0
  mov ebx, 0
  lea eax, [ecx+edx*4+0A]
  // Save health address
  mov [healthAddress], eax
  mov bx, [eax]
  mov [healthValue], bx
  mov ebx, 0
  mov [eax], bx
  pop ebx
  pop eax
  popfd

code:
  movsx edx,word ptr [ecx+edx*4+0A]
  jmp return

INJECT:
  jmp newmem
return:
registersymbol(INJECT)

[DISABLE]
  // Duke lives
  // pushfd
  // push eax
  // push ebx
  // mov eax, 0
  // mov ebx, 0
  // mov bx, [healthValue]
  // mov eax, [healthAddress]
  // mov [eax], bx
  // pop ebx
  // pop eax
  // popfd

INJECT:
  db 0F BF 54 91 0A

unregistersymbol(INJECT)
dealloc(newmem)

unregistersymbol(healthValue)
dealloc(healthValue)

unregistersymbol(healthAddress)
dealloc(healthAddress)

{
// ORIGINAL CODE - INJECTION POINT: "Duke3dw.exe"+4C65C

"Duke3dw.exe"+4C62D: 0F BF 83 E6 02 00 00        -  movsx eax,word ptr [ebx+000002E6]
"Duke3dw.exe"+4C634: B9 D4 70 D0 00              -  mov ecx,Duke3dw.exe+9070D4
"Duke3dw.exe"+4C639: 8D 14 80                    -  lea edx,[eax+eax*4]
"Duke3dw.exe"+4C63C: 8D 14 50                    -  lea edx,[eax+edx*2]
"Duke3dw.exe"+4C63F: 66 8B 83 F6 02 00 00        -  mov ax,[ebx+000002F6]
"Duke3dw.exe"+4C646: 66 C1 F8 08                 -  sar ax,08
"Duke3dw.exe"+4C64A: 66 29 44 91 0A              -  sub [ecx+edx*4+0A],ax
"Duke3dw.exe"+4C64F: 0F BF 83 E6 02 00 00        -  movsx eax,word ptr [ebx+000002E6]
"Duke3dw.exe"+4C656: 8D 14 80                    -  lea edx,[eax+eax*4]
"Duke3dw.exe"+4C659: 8D 14 50                    -  lea edx,[eax+edx*2]
// ---------- INJECTING HERE ----------
"Duke3dw.exe"+4C65C: 0F BF 54 91 0A              -  movsx edx,word ptr [ecx+edx*4+0A]
// ---------- DONE INJECTING  ----------
"Duke3dw.exe"+4C661: 0F BF 83 96 02 00 00        -  movsx eax,word ptr [ebx+00000296]
"Duke3dw.exe"+4C668: 89 D6                       -  mov esi,edx
"Duke3dw.exe"+4C66A: 29 C6                       -  sub esi,eax
"Duke3dw.exe"+4C66C: 79 7A                       -  jns Duke3dw.exe+4C6E8
"Duke3dw.exe"+4C66E: 66 C7 83 F6 02 00 00 00 00  -  mov word ptr [ebx+000002F6],0000
"Duke3dw.exe"+4C677: 66 83 BB 36 03 00 00 00     -  cmp word ptr [ebx+00000336],00
"Duke3dw.exe"+4C67F: 7E 49                       -  jle Duke3dw.exe+4C6CA
"Duke3dw.exe"+4C681: E8 5A 7A 02 00              -  call Duke3dw.exe+740E0
"Duke3dw.exe"+4C686: BF 1E 00 00 00              -  mov edi,0000001E
"Duke3dw.exe"+4C68B: 99                          -  cdq
}


The script works as expected when enabled (health set to 0, player dies) but remains enabled when any of the instructions passed the DISABLE label are un-commented.

Why doesn't CE execute that code? (when the script gets activated and stuck the player remains dead even though the character becomes playable if health is restored from CE).
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 138

Joined: 06 Jul 2014
Posts: 4275

PostPosted: Wed Apr 25, 2018 2:57 pm    Post subject: Reply with quote

Sarge411 wrote:
...and back to its original value upon re-enabling

Did you mean disabling?

Sarge411 wrote:
Why doesn't CE execute that code?

CE doesn't execute any of that code (enable or disable section). CE writes that code to the target's memory which the target might execute eventually.

CE can execute Lua code in an AA script.
Code:
[DISABLE]
{$lua}
writeSmallInteger('[healthAddress]', readSmallInteger('healthValue'))
{$asm}
//...
{$lua} blocks are executed before pretty much everything else in the script, so the dealloc / unregistersymbol statements won't affect it.


Since the code in the enable section is presumably executed multiple times by the target, [healthValue] will likely be 0 when the disable section is executed. One way to fix this is to see if [healthValue] is nonzero and, if so, don't assign to it again.

You should also probably check if [healthValue] is nonzero in the disable section, but that would only be a problem if the target never executed the code in the enable section.

_________________
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
Sarge411
Newbie cheater
Reputation: 0

Joined: 21 Apr 2018
Posts: 21

PostPosted: Wed Apr 25, 2018 4:55 pm    Post subject: Reply with quote

ParkourPenguin wrote:

Did you mean disabling?


Yes.

ParkourPenguin wrote:

CE doesn't execute any of that code (enable or disable section). CE writes that code to the target's memory which the target might execute eventually.


But this means that everything following the DISABLE label is not executed, including deallocations. It's strange that when commenting the instructions after DISABLE the script can be started and stopped.

ParkourPenguin wrote:

CE can execute Lua code in an AA script.
Code:
[DISABLE]
{$lua}
writeSmallInteger('[healthAddress]', readSmallInteger('healthValue'))
{$asm}
//...
{$lua} blocks are executed before pretty much everything else in the script, so the dealloc / unregistersymbol statements won't affect it.


So, if the lua script executes before the instructions after ENABLE doesn't this leave the healthValue and healthAddress variables uninitialized?

I'm not sure how to check their values when running the script. I managed to follow execution and see the valid address and health value loaded into the registers but was not able to follow the changes in memory. How can you check variable values during debugging? I used the memory viewer but it changes on every instruction making it difficult to track a variable's value.

ParkourPenguin wrote:

Since the code in the enable section is presumably executed multiple times by the target, [healthValue] will likely be 0 when the disable section is executed. One way to fix this is to see if [healthValue] is nonzero and, if so, don't assign to it again.

You should also probably check if [healthValue] is nonzero in the disable section, but that would only be a problem if the target never executed the code in the enable section.


Trying it now.
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 138

Joined: 06 Jul 2014
Posts: 4275

PostPosted: Wed Apr 25, 2018 5:56 pm    Post subject: Reply with quote

Sarge411 wrote:
It's strange that when commenting the instructions after DISABLE the script can be started and stopped.

You didn't specify what address the code in the disable section is being written to. That's a syntax error, and when CE tries to disable the script, it fails.

Sarge411 wrote:
So, if the lua script executes before the instructions after ENABLE doesn't this leave the healthValue and healthAddress variables uninitialized?

That's more or less what I was referring to in the last sentence of my previous post. The enable section initializes the values to 0, and the code should assign a nonzero value the first time it is run. If it wasn't assigned a nonzero value, the disable section as I wrote it would unconditionally assign 0 (the initial value) to the address. This probably won't happen if the code is run often enough (e.g. once every frame), and it isn't as big of a problem as what happens if the target runs it more than once (you should fix that first).

Sarge411 wrote:
I'm not sure how to check their values when running the script.

Use a cmp followed by a conditional instruction (i.e. jcc / cmovcc).

_________________
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
Sarge411
Newbie cheater
Reputation: 0

Joined: 21 Apr 2018
Posts: 21

PostPosted: Thu Apr 26, 2018 3:13 am    Post subject: Reply with quote

ParkourPenguin wrote:

You didn't specify what address the code in the disable section is being written to. That's a syntax error, and when CE tries to disable the script, it fails.


But isn't the value of the healthAddress and healthValue known at this point? Or should the syntax be pointing to somewhere in memory like:

Code:

[DISABLE]
00D071AB:
 <code that writes to healthValue (which is static) after reading from healthAddress>


ParkourPenguin wrote:

That's more or less what I was referring to in the last sentence of my previous post. The enable section initializes the values to 0, and the code should assign a nonzero value the first time it is run. If it wasn't assigned a nonzero value, the disable section as I wrote it would unconditionally assign 0 (the initial value) to the address. This probably won't happen if the code is run often enough (e.g. once every frame), and it isn't as big of a problem as what happens if the target runs it more than once (you should fix that first).


So, the lua script runs first when the script is enabled and initializes the values and this happens even on subsequent runs (say the player has an initial life value, runs the script, stops it, takes some damage and then reruns the script, the lua will then rerun and update the healthValue with the current value of the player, no?)

ParkourPenguin wrote:
I'm not sure how to check their values when running the script.
Use a cmp followed by a conditional instruction (i.e. jcc / cmovcc).


I rewrote the code to check if the values have been set:

Code:

{ Game   : Duke3dw.exe
  Version:
  Date   : 2018-04-25
  Author : Sarge411

  This script does blah blah blah
}

[ENABLE]

aobscanmodule(INJECT,Duke3dw.exe,0F BF 54 91 0A) // should be unique
alloc(newmem,$1000)

registersymbol(healthValue)
registersymbol(healthAddress)
alloc(healthValue, 4)
alloc(healthAddress, 4)

healthValue:
  dd 0
healthAddress:
  dd 0

label(code)
label(return)
label(initialized)
label(uninitialized)

newmem:
  // Duke dies
  pushfd
  push eax
  push ebx
  push ecx

  mov eax, 0
  mov ebx, 0
  mov ecx, 0

  // Check if health address and value has been set
  mov eax, [healthValue]
  cmp eax, 0
  je uninitialized
  inc ecx
  mov eax, [healthAddress]
  cmp eax, 0
  je uninitialized
  inc ecx
  cmp ecx, 2
  je initialized

uninitialized:
  mov eax, 0
  lea eax, [ecx+edx*4+0A]
  // Save health address
  mov [healthAddress], eax
  mov bx, [eax]
  mov [healthValue], bx
  mov ebx, 0
  mov [eax], bx

initialized:
  pop ecx
  pop ebx
  pop eax
  popfd

code:
  movsx edx,word ptr [ecx+edx*4+0A]
  jmp return

INJECT:
  jmp newmem
return:
registersymbol(INJECT)

[DISABLE]
  // Duke lives
  //pushfd
  //push eax
  //push ebx
  //mov eax, 0
  //mov ebx, 0
  //mov bx, [healthValue]
  //mov eax, [healthAddress]
  //mov [eax], bx
  //pop ebx
  //pop eax
  //popfd

INJECT:
  db 0F BF 54 91 0A

unregistersymbol(INJECT)
dealloc(newmem)

unregistersymbol(healthValue)
dealloc(healthValue)

unregistersymbol(healthAddress)
dealloc(healthAddress)

{
// ORIGINAL CODE - INJECTION POINT: "Duke3dw.exe"+4C65C

"Duke3dw.exe"+4C62D: 0F BF 83 E6 02 00 00        -  movsx eax,word ptr [ebx+000002E6]
"Duke3dw.exe"+4C634: B9 D4 70 D0 00              -  mov ecx,Duke3dw.exe+9070D4
"Duke3dw.exe"+4C639: 8D 14 80                    -  lea edx,[eax+eax*4]
"Duke3dw.exe"+4C63C: 8D 14 50                    -  lea edx,[eax+edx*2]
"Duke3dw.exe"+4C63F: 66 8B 83 F6 02 00 00        -  mov ax,[ebx+000002F6]
"Duke3dw.exe"+4C646: 66 C1 F8 08                 -  sar ax,08
"Duke3dw.exe"+4C64A: 66 29 44 91 0A              -  sub [ecx+edx*4+0A],ax
"Duke3dw.exe"+4C64F: 0F BF 83 E6 02 00 00        -  movsx eax,word ptr [ebx+000002E6]
"Duke3dw.exe"+4C656: 8D 14 80                    -  lea edx,[eax+eax*4]
"Duke3dw.exe"+4C659: 8D 14 50                    -  lea edx,[eax+edx*2]
// ---------- INJECTING HERE ----------
"Duke3dw.exe"+4C65C: 0F BF 54 91 0A              -  movsx edx,word ptr [ecx+edx*4+0A]
// ---------- DONE INJECTING  ----------
"Duke3dw.exe"+4C661: 0F BF 83 96 02 00 00        -  movsx eax,word ptr [ebx+00000296]
"Duke3dw.exe"+4C668: 89 D6                       -  mov esi,edx
"Duke3dw.exe"+4C66A: 29 C6                       -  sub esi,eax
"Duke3dw.exe"+4C66C: 79 7A                       -  jns Duke3dw.exe+4C6E8
"Duke3dw.exe"+4C66E: 66 C7 83 F6 02 00 00 00 00  -  mov word ptr [ebx+000002F6],0000
"Duke3dw.exe"+4C677: 66 83 BB 36 03 00 00 00     -  cmp word ptr [ebx+00000336],00
"Duke3dw.exe"+4C67F: 7E 49                       -  jle Duke3dw.exe+4C6CA
"Duke3dw.exe"+4C681: E8 5A 7A 02 00              -  call Duke3dw.exe+740E0
"Duke3dw.exe"+4C686: BF 1E 00 00 00              -  mov edi,0000001E
"Duke3dw.exe"+4C68B: 99                          -  cdq
}


But now the game exits when enabling the cheat.
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 138

Joined: 06 Jul 2014
Posts: 4275

PostPosted: Thu Apr 26, 2018 9:53 am    Post subject: Reply with quote

Sarge411 wrote:
But isn't the value of the healthAddress and healthValue known at this point? Or should the syntax be pointing to somewhere in memory like:

Code:

[DISABLE]
00D071AB:
 <code that writes to healthValue (which is static) after reading from healthAddress>
That's irrelevant. Read over my previous posts again: CE doesn't execute that code. CE writes that code to the target's memory. In the disable section, you didn't specify any address to write that code to. That is a syntax error.

If you did write it to some address, the target would still execute it on its own terms (maybe not at all). I guess you could call code to run using createthread and deallocate the memory for the code injection in the code injection itself, but that's far more complicated than simply using Lua.

Sarge411 wrote:
So, the lua script runs first when the script is enabled and initializes the values and this happens even on subsequent runs (say the player has an initial life value, runs the script, stops it, takes some damage and then reruns the script, the lua will then rerun and update the healthValue with the current value of the player, no?)
  • The Lua script is in the disable section. It will be run when the script is disabled, not enabled.
  • The initial values stored at healthValue and healthAddress are defined by you to be 0 (via the pseudoinstruction "dd 0").
  • The Lua script will run when the script is disabled. Beyond that, I don't know what you mean by "subsequent runs."
  • Your code injection is what assigns the new value to healthValue; not the Lua script.
Also, I just noticed healthAddress also wouldn't have a valid address if the target never ran your code injection. When the Lua script goes to write something to the address, it wouldn't change anything and therefore wouldn't be a problem (writeSmallInteger doesn't generate an error).
Sarge411 wrote:
I rewrote the code to check if the values have been set:
Code:
...

But now the game exits when enabling the cheat.
It's crashing.

At this point, it really seems like you just copied and pasted everything from somewhere hoping it would work. If you didn't, then you're writing nonsensical code still in the vain hope it works, which isn't much better. You don't know what you're doing regardless.

Try learning by doing something easier and smaller in scope: finish the CE tutorial, follow along with videos on YouTube, download other cheat tables and learn from them, etc.

_________________
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
Sarge411
Newbie cheater
Reputation: 0

Joined: 21 Apr 2018
Posts: 21

PostPosted: Thu Apr 26, 2018 3:05 pm    Post subject: Reply with quote

ParkourPenguin wrote:

That's irrelevant. Read over my previous posts again: CE doesn't execute that code. CE writes that code to the target's memory. In the disable section, you didn't specify any address to write that code to. That is a syntax error.


I'm not sure if my understanding of code injection is correct. Is this what CE does (in a scenario where an instruction "frequently" accessing a static address is picked as an injection point):

1. Allocate memory in the running process
2. Replace accessing instruction with a jmp to the newly allocated instruction
3. Execute code after ENABLE (provided that execution reaches injection point (the now jmp instruction))
4. Execute original code that was in place of the jmp
5. jmp back to the instruction immediately after the jmp

Is this correct at all?

Now as far as my understanding goes, CE places the code after the DISABLE label to an address in memory defined after DISABLE. This is a working snippet that freezes a counter:

Code:

define(address,"Duke3dw.exe"+522A2)
define(bytes,48 66 89 83 32 03 00 00)

[DISABLE]

address:
  db bytes
  // dec eax
  // mov [ebx+00000332],ax


Does the code write those bytes to the address upon disabling the script?

Code:

If you did write it to some address, the target would still execute it on its own terms (maybe not at all). I guess you could call code to run using createthread and deallocate the memory for the code injection in the code injection itself, but that's far more complicated than simply using Lua.


I still have to look at how CE manages threads (among many other things).

ParkourPenguin wrote:

  • The Lua script is in the disable section. It will be run when the script is disabled, not enabled.
  • The initial values stored at healthValue and healthAddress are defined by you to be 0 (via the pseudoinstruction "dd 0").
  • The Lua script will run when the script is disabled. Beyond that, I don't know what you mean by "subsequent runs."
  • Your code injection is what assigns the new value to healthValue; not the Lua script.
Also, I just noticed healthAddress also wouldn't have a valid address if the target never ran your code injection. When the Lua script goes to write something to the address, it wouldn't change anything and therefore wouldn't be a problem (writeSmallInteger doesn't generate an error).


Ok, I think it's clearer now. The idea is that when the lua script gets executed there will always be valid values stored in both healthAddress and healthValue (since the script must first be enabled before being disabled?).

ParkourPenguin wrote:

At this point, it really seems like you just copied and pasted everything from somewhere hoping it would work. If you didn't, then you're writing nonsensical code still in the vain hope it works, which isn't much better. You don't know what you're doing regardless.


I'm struggling with it on my own. I have an asm file in visual studio and am trying to replicate something that works there in CE.

ParkourPenguin wrote:

Try learning by doing something easier and smaller in scope: finish the CE tutorial, follow along with videos on YouTube, download other cheat tables and learn from them, etc.


I've been through the x86 tutorial. Looking over lua.
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 138

Joined: 06 Jul 2014
Posts: 4275

PostPosted: Thu Apr 26, 2018 3:55 pm    Post subject: Reply with quote

Sarge411 wrote:
I'm not sure if my understanding of code injection is correct. Is this what CE does (in a scenario where an instruction "frequently" accessing a static address is picked as an injection point):

1. Allocate memory in the running process
2. Replace accessing instruction with a jmp to the newly allocated instruction
3. Execute code after ENABLE (provided that execution reaches injection point (the now jmp instruction))
4. Execute original code that was in place of the jmp
5. jmp back to the instruction immediately after the jmp
  1. Yes, that is what the alloc statement does.
  2. Yes, that is done by "INJECT:" / "jmp newmem"
  3. No. Cheat Engine is not executing any of that code. It is only writing that code into the allocated memory so the game can execute it when the game wants to.
  4. No. (same reasoning as 3)
  5. That jmp instruction does exist.

Cheat Engine is not executing that code. Cheat Engine writes that code into the game's memory. The game will execute that code when the game was suppose to execute the original instruction(s). I don't know how else to word this so that you understand.

I also believe you're using the term "static address" incorrectly, but that's another discussion. In short, if it's green in the memory view, it's static; if it's black, it's not.
Sarge411 wrote:
Now as far as my understanding goes, CE places the code after the DISABLE label to an address in memory defined after DISABLE.
Everything CE automatically generates in the disable section of a script reverts everything done in the enable section. This involves deallocating memory, unregistering symbols, and restoring the original code that was overwritten by a jmp.
Sarge411 wrote:
I still have to look at how CE manages threads (among many other things).
CE doesn't really manage anything. createthread simply creates a thread in the target process that starts at the specified address.
Sarge411 wrote:
The idea is that when the lua script gets executed there will always be valid values stored in both healthAddress and healthValue (since the script must first be enabled before being disabled?).
The script does have to be enabled before it can be disabled, but that doesn't mean healthAddress and healthValue have nonzero values. Again, Cheat Engine does not execute the code in the enable section. The code in the enable section is only executed by the game when the game was suppose to execute the original instruction(s). By the time you disable the script, the game might have already executed the code, or it might not have. So the values stored in healthAddress and healthValue might be valid or they might still be 0.
_________________
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
Sarge411
Newbie cheater
Reputation: 0

Joined: 21 Apr 2018
Posts: 21

PostPosted: Fri Apr 27, 2018 3:25 pm    Post subject: Reply with quote

ParkourPenguin wrote:
  1. Yes, that is what the alloc statement does.
  2. Yes, that is done by "INJECT:" / "jmp newmem"
  3. No. Cheat Engine is not executing any of that code. It is only writing that code into the allocated memory so the game can execute it when the game wants to.
  4. No. (same reasoning as 3)
  5. That jmp instruction does exist.

Cheat Engine is not executing that code. Cheat Engine writes that code into the game's memory. The game will execute that code when the game was suppose to execute the original instruction(s). I don't know how else to word this so that you understand.


Ok, that's clear.

I've reworked the code as you suggested earlier (by using lua to save the health value):

Code:

[ENABLE]

aobscanmodule(INJECT,Duke3dw.exe,66 29 44 91 0A) // should be unique
alloc(newmem,$1000)

label(code)
label(return)

newmem:
 {$lua}
 healthAddress = hex_value
 healthValue = readInteger(healthAddress)
 writeInteger(healthAddress, 0)
 {$asm}

code:
  sub [ecx+edx*4+0A],ax
  jmp return

INJECT:
  jmp newmem
return:
registersymbol(INJECT)

[DISABLE]
  {$lua}
  writeInteger(healthAddress, healthValue)
  {$asm}

INJECT:
  db 66 29 44 91 0A

unregistersymbol(INJECT)
dealloc(newmem)


but now am getting:

Code:


Error in line

healthAddress = hex_value

This instruction cannot be compiled.



ParkourPenguin wrote:

Everything CE automatically generates in the disable section of a script reverts everything done in the enable section. This involves deallocating memory, unregistering symbols, and restoring the original code that was overwritten by a jmp.
CE doesn't really manage anything. createthread simply creates a thread in the target process that starts at the specified address.
The script does have to be enabled before it can be disabled, but that doesn't mean healthAddress and healthValue have nonzero values. Again, Cheat Engine does not execute the code in the enable section. The code in the enable section is only executed by the game when the game was suppose to execute the original instruction(s). By the time you disable the script, the game might have already executed the code, or it might not have. So the values stored in healthAddress and healthValue might be valid or they might still be 0.


W.r.t. to the inline lua code in the AA, how are variables treated? Does their scope extend to the entire AA script or is only valid within the lua...asm tags?

For example, if healthValue is set by lua after the script is enabled will the same value be used when it's disabled?
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 138

Joined: 06 Jul 2014
Posts: 4275

PostPosted: Fri Apr 27, 2018 4:26 pm    Post subject: Reply with quote

Sarge411 wrote:
I've reworked the code as you suggested earlier (by using lua to save the health value)

I never suggested that, and that would not work. As I have said, CE executes the Lua code, not the game.

If you're curious, that particular error is because you put spaces before the {$lua} and {$asm} lines.

Also, since you changed the injection point, you shouldn't execute the sub instruction after writing 0 to the address.

Sarge411 wrote:
W.r.t. to the inline lua code in the AA, how are variables treated? Does their scope extend to the entire AA script or is only valid within the lua...asm tags?

For example, if healthValue is set by lua after the script is enabled will the same value be used when it's disabled?

The {$lua} block just executes Lua code. It also does something else, but it's not relevant in this case. Look at a Lua tutorial if you want to learn how Lua works, and look at celua.txt for functions CE provides.

_________________
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
Sarge411
Newbie cheater
Reputation: 0

Joined: 21 Apr 2018
Posts: 21

PostPosted: Sat Apr 28, 2018 1:32 pm    Post subject: Reply with quote

ParkourPenguin wrote:

I never suggested that, and that would not work. As I have said, CE executes the Lua code, not the game.

If you're curious, that particular error is because you put spaces before the {$lua} and {$asm} lines.


Indentation fixed that error.

ParkourPenguin wrote:

Also, since you changed the injection point, you shouldn't execute the sub instruction after writing 0 to the address.


I now only save the value from healthAddress in healthValue and write 0 to healthAddress when the script is enabled (lua after ENABLE label is executed) and write back the value from healthValue to healthAddress.

Code:

[ENABLE]

aobscanmodule(INJECT,Duke3dw.exe,66 8B 42 2A 66 89 85 96 02 00 00) // should be unique
alloc(newmem,$1000)

label(code)
label(return)

newmem:
{$lua}
print("Alive 1")
healthAddress = hexval
healthValue = readInteger(healthAddress)
writeInteger(healthAddress, 0)
print("Alive 2")
{$asm}

code:
  mov ax,[edx+2A]
  mov [ebp+00000296],ax
  jmp return

INJECT:
  jmp newmem
  nop
  nop
  nop
  nop
  nop
  nop
return:
registersymbol(INJECT)

[DISABLE]
{$lua}
print("Dead 1")
writeInteger(healthAddress, healthValue)
print("Dead 2")
{$asm}

INJECT:
  db 66 8B 42 2A 66 89 85 96 02 00 00

unregistersymbol(INJECT)
dealloc(newmem)


The code runs (character dies) but the cross doesn't appear as if the cheat is enabled/disabled. When I run it from the editor it gives the following error:

Code:

Error while scanning for AOB's: INJECT

Error


Even though that instruction is still present in memory.

Is it correct that lua scripts are executed before any asm code and are not written to the process' memory? The asm code now handles the injection jmps and nothing more (I think (hope)).

I've picked the injection point an instruction that executes often regardless if the player is dead or alive (but should injection points in the context of running lua scripts matter? as, per my understanding, lua is independent of AA functionality-wise. Why can't ):

Code:

Alive
--------------------------------------------
0044DD05 - 66 83 3C 85 DE70D000 00 - cmp word ptr [eax*4+00D070DE],00
00452A96 - 66 83 7B 2A 00 - cmp word ptr [ebx+2A],00
0044C64A - 66 29 44 91 0A  - sub [ecx+edx*4+0A],ax
0044C65C - 0FBF 54 91 0A  - movsx edx,word ptr [ecx+edx*4+0A]
00452AC2 - 66 8B 42 2A  - mov ax,[edx+2A] // <== Instruction picked as injection point
00452D22 - 66 83 79 2A 00 - cmp word ptr [ecx+2A],00
004601A3 - 66 83 3C 95 DE70D000 00 - cmp word ptr [edx*4+00D070DE],00
0043207F - 66 83 3C 95 DE70D000 00 - cmp word ptr [edx*4+00D070DE],00
0043671B - 0FBF 50 2A  - movsx edx,word ptr [eax+2A]
00431DBA - 66 83 7E 2A 00 - cmp word ptr [esi+2A],00
00438793 - 66 83 3C 85 DE70D000 00 - cmp word ptr [eax*4+00D070DE],00
0042A50E - 66 83 7E 2A 00 - cmp word ptr [esi+2A],00


Code:

Dead
--------------------------------------------
0044DD05 - 66 83 3C 85 DE70D000 00 - cmp word ptr [eax*4+00D070DE],00
00452A96 - 66 83 7B 2A 00 - cmp word ptr [ebx+2A],00
00452AAF - 66 C7 40 2A 0000 - mov word ptr [eax+2A],0000
00452AC2 - 66 8B 42 2A  - mov ax,[edx+2A]    // <== Instruction picked as injection point
00452D22 - 66 83 79 2A 00 - cmp word ptr [ecx+2A],00
004601A3 - 66 83 3C 95 DE70D000 00 - cmp word ptr [edx*4+00D070DE],00
0043207F - 66 83 3C 95 DE70D000 00 - cmp word ptr [edx*4+00D070DE],00
0043671B - 0FBF 50 2A  - movsx edx,word ptr [eax+2A]
00431DBA - 66 83 7E 2A 00 - cmp word ptr [esi+2A],00
00438793 - 66 83 3C 85 DE70D000 00 - cmp word ptr [eax*4+00D070DE],00



Quote:

The {$lua} block just executes Lua code. It also does something else, but it's not relevant in this case. Look at a Lua tutorial if you want to learn how Lua works, and look at celua.txt for functions CE provides.


I'm looking at it and working on a thread workflow:

1. Start thread when cheat is enabled
2. Always read key values
3. Stop thread on given key
4. If other keys are pressed updated character coordinates
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 138

Joined: 06 Jul 2014
Posts: 4275

PostPosted: Sat Apr 28, 2018 2:58 pm    Post subject: Reply with quote

Sarge411 wrote:
Is it correct that lua scripts are executed before any asm code and are not written to the process' memory?

Yes, that is correct.

Sarge411 wrote:
but should injection points in the context of running lua scripts matter?

No, it doesn't matter. None of the Lua code in that AA script depends on the injection point. You don't even need to use code injection in the first place if you already have the address.

_________________
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
Sarge411
Newbie cheater
Reputation: 0

Joined: 21 Apr 2018
Posts: 21

PostPosted: Sun Apr 29, 2018 3:14 pm    Post subject: Reply with quote

ParkourPenguin wrote:
Yes, that is correct


I wrote this lua script:

Code:


local function initCam()
 
  writeBytes(ZWExitMapAddr, getNops(#ZWExitMapOrigCode))
 
  writeBytes(CamRotWAddr, getNops(#CamWOrigCode))
 
  writeBytes(ZWAddr, getNops(#ZWOrigCode))
  writeBytes(YWAddr, getNops(#YWOrigCode))
  writeBytes(XWAddr, getNops(#XWOrigCode))
  writeBytes(CamUpDnWAddr, getNops(#CamUpDnOrigCode))
 
  print("before read health")
  healthVal = readSmallInteger(healthAddr)
  print("after read")

  print("health addr " .. string.format("%x", healthAddr))
  print("value at address " .. healthVal)

  writeSmallInteger(healthAddr, 0)

  XVal = readInteger(XAddr)
  YVal = readInteger(YAddr)
  ZVal = readInteger(ZAddr)
end

local camThread = createThread(function(startThread)
    initCam()
end)


but get

Code:

attempt to call a nil value (global 'readSmallInteger')


Why isn't 'readSmallInteger' defined? I looked at similar threads and the problem was always a typo in the function's name (the health is stored as short in the least significant bytes at healthAddress)

Also, when I use 'readInteger' instead, the value of healthValue remains 0 as it was initialized prior to starting the thread:

Code:


healthAddr = hex
healthVal  = 0

XAddr      = hex
YAddr      = hex
ZAddr      = hex

XVal       = 0
YVal       = 0
ZVal       = 0


and not updated.

Is it because initCam() executes in a separate thread and can only read globals from the main thread?

Similarly, CE complained about isKeyPressed. I'm using CE 6.6 x86 build.

Here is the full script (base64):

aHR0cHM6Ly9wYXN0ZS51YnVudHUuY29tL3Avc1I2d1lZM3lwUC8=
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 138

Joined: 06 Jul 2014
Posts: 4275

PostPosted: Sun Apr 29, 2018 4:04 pm    Post subject: Reply with quote

Several Lua functions were added in CE 6.7. Update to the latest version (or implement the function(s) yourself).

Sarge411 wrote:
Also, when I use 'readInteger' instead, the value of healthValue remains 0 as it was initialized prior to starting the thread

If the value of the player's health is 0 before the thread is created, it will read 0 from that address and assign 0 to the global healthVal.

_________________
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
Sarge411
Newbie cheater
Reputation: 0

Joined: 21 Apr 2018
Posts: 21

PostPosted: Sun May 06, 2018 1:33 pm    Post subject: Reply with quote

ParkourPenguin wrote:
Several Lua functions were added in CE 6.7. Update to the latest version (or implement the function(s) yourself).


I fixed this by adding functions from CE 6.7 but was quite a PITA.

ParkourPenguin wrote:

If the value of the player's health is 0 before the thread is created, it will read 0 from that address and assign 0 to the global healthVal.


I'm almost done but it seems that I hit another bump that's related to concurrency. Does lua in CE have any form of syncing primitives? I looked at celua.txt but couldn't find any.

The code is (base64):

Code:

c2xlZXBUaW1lICAgICAgICAgPSAxNTANCg0KbG9jYWwgY2FtVGhyZWFkID0gY3JlYdipshitVGhyZWFkKGZ1bmN0aW9uKHN0YXJ0VGhyZWFkKQ0KDQogICAgd2hpbGUgdHJ1ZSBkbw0KDQogICAgICAgIGlmIChpc0tleVByZXNzZWQoVktfTlVNUEFEMCkgYW5kIGNhbUlzU3RhcnRlZCA9PSBmYWxzZSkgdGhlbg0KICAgICAgICAgICBpbml0Q2FtKCkNCiAgICAgICAgICAgY2FtSXNTdGFydGVkID0gdHJ1ZQ0KICAgICAgICAgICBzbGVlcChzbGVlcFRpbWUgKQ0KICAgICAgICBlbmQNCg0KICAgICAgICBpZiAoaXNLZXlQcmVzc2VkKFZLX05VTVBBRDApIGFuZCBjYW1Jc1N0YXJ0ZWQgPT0gdHJ1ZSkgdGhlbg0KICAgICAgICAgICByZXN0b3JlQ29kZSgpDQogICAgICAgICAgIGNhbUlzU3RhcnRlZCA9IGZhbHNlDQogICAgICAgICAgIHNsZWVwKHNsZWVwVGltZSkNCiAgICAgICAgZW5kDQoNCiAgICAgICAgaWYgKGNhbUlzU3RhcnRlZCkgdGhlbg0KDQogICAgICAgICAgIGlmIChpc0tleVByZXNzZWQoVktfTlVNUEFEOCkpIHRoZW4NCiAgICAgICAgICAgICAgbW92ZUZXKE1PRElGSUVSKQ0KICAgICAgICAgICBlbmQNCg0KICAgICAgICBlbmQNCiAgICAgICAgc2xlZXAoc2xlZXBUaW1lKQ0KICAgIGVuZCANCmVuZCk=


where initCam() and restoreCode() are external to the thread's body/function and are defined globally. Sometimes the cheat works, sometimes it doesn't. It seems as if the initCam() function does not execute entirely. Same goes for restoreCode().

If the newly created thread runs a while loop, what happens to the main thread? Can it be that if CE doesn't read fast enough from memory before it writes to it, an original value is overwritten? E.g. if the health is read but the read doesn't finish before write is called and 0 (the initial value of healthVal) gets written to memory instead?
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> General Gamehacking All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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