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 


How does having multiple AOB scans in the same code work?

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General Discussions
View previous topic :: View next topic  
Author Message
TDWL
Newbie cheater
Reputation: 0

Joined: 28 Jan 2020
Posts: 10

PostPosted: Sat Feb 08, 2020 11:01 pm    Post subject: How does having multiple AOB scans in the same code work? Reply with quote

So, I'm trying to make a NO DAMAGE script for a game but the code that deals with damage is shared between the player and all enemies, and I couldn't find team numbers to distinguish between the two so I made another script which searches for the player's health address (I did this through the instruction that displays the player's health which is unique to him) and stores it in a symbol (called playerAddress) which I can use in my cheat script to compare with the current address and in case its an enemy it should run the original code.

The problem with this is that I first need to run the playerAddress code, wait a few seconds until it finds the address and then I can start running my cheat.

What I'd like to do is run the AOB scan for playerAddress in the same code as my cheat. However, I'm not sure how to do this or if it is even possible.

My current scripts are as follows:

- Code that searches for player address
Code:

[ENABLE]

aobscan(healthAddress,8B 82 E8 00 00 00 89 45 F4 F2)
alloc(newmem,2048)
label(code)
label(return)
registersymbol(healthAddress)

alloc(playerAddress,4)
registersymbol(playerAddress)

newmem:
  mov [playerAddress],edx

code:
  mov eax,[edx+000000E8]
  jmp return

healthAddress:
  jmp newmem
  nop
return:



[DISABLE]

healthAddress:
  db 8B 82 E8 00 00 00

unregistersymbol(healthAddress)
unregistersymbol(playerAddress)
dealloc(newmem)
dealloc(playerAddress)
{
// ORIGINAL CODE - INJECTION POINT: 0D8B6AD6

0D8B6AB3: B8 E0 30 0B 0D     -  mov eax,0D0B30E0
0D8B6AB8: FF D0              -  call eax
0D8B6ABA: 89 6C 24 FC        -  mov [esp-04],ebp
0D8B6ABE: F2 0F 11 62 08     -  movsd [edx+08],xmm4
0D8B6AC3: 83 EC 08           -  sub esp,08
0D8B6AC6: 50                 -  push eax
0D8B6AC7: E8 24 4E 30 01     -  call 0EBBB8F0
0D8B6ACC: 89 6C 24 FC        -  mov [esp-04],ebp
0D8B6AD0: 83 C4 0C           -  add esp,0C
0D8B6AD3: 8B 55 08           -  mov edx,[ebp+08]
// ---------- INJECTING HERE ----------
0D8B6AD6: 8B 82 E8 00 00 00  -  mov eax,[edx+000000E8]
// ---------- DONE INJECTING  ----------
0D8B6ADC: 89 45 F4           -  mov [ebp-0C],eax
0D8B6ADF: F2 0F 2A D8        -  cvtsi2sd xmm3,eax
0D8B6AE3: F2 0F 11 5D A8     -  movsd [ebp-58],xmm3
0D8B6AE8: 8B 8D 5C FE FF FF  -  mov ecx,[ebp-000001A4]
0D8B6AEE: 8B 81 88 00 00 00  -  mov eax,[ecx+00000088]
0D8B6AF4: 89 85 50 FE FF FF  -  mov [ebp-000001B0],eax
0D8B6AFA: 85 C0              -  test eax,eax
0D8B6AFC: 75 0E              -  jne 0D8B6B0C
0D8B6AFE: 83 EC 0C           -  sub esp,0C
0D8B6B01: B8 E0 30 0B 0D     -  mov eax,0D0B30E0
}


- Code for no damage
Code:

[ENABLE]

aobscan(NoDMG,8B EC 81 EC B4 00 00 00 8B 45 08 8B 88 E8)
alloc(newmem,$1000)

label(code)
label(return)

newmem:
  mov ebp,esp // part of original code
  push ecx
  push ebx
  mov ebx,[ebp+8]
  mov ecx,[playerAddress] // why does cmp [playerAddress],ebx does not work?
  cmp ecx,ebx
  jne code
  pop ebx
  pop ecx
  mov [ebp+08],157F71A0-E8 // ENEMY ADDRESS

  sub esp,000000B4 // part of original code

  jmp return


code:
  pop ebx
  pop ecx
  sub esp,000000B4
  jmp return

NoDMG:
  jmp newmem
  nop 3
return:
registersymbol(NoDMG)

[DISABLE]

NoDMG:
  db 8B EC 81 EC B4 00 00 00

unregistersymbol(NoDMG)
dealloc(newmem)

{
// ORIGINAL CODE - INJECTION POINT: 0D06C4F1

0D06C4E7: C3                 -  ret
0D06C4E8: 90                 -  nop
0D06C4E9: 90                 -  nop
0D06C4EA: 90                 -  nop
0D06C4EB: 90                 -  nop
0D06C4EC: 90                 -  nop
0D06C4ED: 90                 -  nop
0D06C4EE: 90                 -  nop
0D06C4EF: 90                 -  nop
0D06C4F0: 55                 -  push ebp
// ---------- INJECTING HERE ----------
0D06C4F1: 8B EC              -  mov ebp,esp
0D06C4F3: 81 EC B4 00 00 00  -  sub esp,000000B4
// ---------- DONE INJECTING  ----------
0D06C4F9: 8B 45 08           -  mov eax,[ebp+08]
0D06C4FC: 8B 88 E8 00 00 00  -  mov ecx,[eax+000000E8]
0D06C502: 89 4D FC           -  mov [ebp-04],ecx
0D06C505: 33 D2              -  xor edx,edx
0D06C507: 89 55 F8           -  mov [ebp-08],edx
0D06C50A: 3B D1              -  cmp edx,ecx
0D06C50C: 0F 8C 0B 00 00 00  -  jl 0D06C51D
0D06C512: 8B 45 00           -  mov eax,[ebp+00]
0D06C515: 81 C4 B4 00 00 00  -  add esp,000000B4
0D06C51B: 5D                 -  pop ebp
}


Clarification: The static address that I commented as //ENEMY ADDRESS should be the current address of the enemy that is attacking me, but that will be solved if I learn how to do what I'm asking here. For now it's just the address of one enemy I found manually which works for testing.

But what I'd like to do is something like this:
Code:

[ENABLE]

aobscan(NoDMG,8B EC 81 EC B4 00 00 00 8B 45 08 8B 88 E8)
aobscan(healthAddress,8B 82 E8 00 00 00 89 45 F4 F2)
alloc(newmem,$1000)

registersymbol(NoDMG)

alloc(playerAddress,4)
registersymbol(playerHealth)

label(code)
label(return)

newmem:
  mov ebp,esp // part of original code
  push ecx
  push ebx
  mov ebx,[ebp+8]
  mov ecx,[playerAddress] // why does cmp [playerAddress],ebx does not work?
  cmp ecx,ebx
  jne code
  pop ebx
  pop ecx
  mov [ebp+08],157F71A0-E8 // ENEMY ADDRESS

  sub esp,000000B4 // part of original code

  jmp return


code:
  pop ebx
  pop ecx
  sub esp,000000B4
  jmp return

NoDMG:
  jmp newmem
  nop 3
return:


[DISABLE]

NoDMG:
  db 8B EC 81 EC B4 00 00 00

unregistersymbol(NoDMG)
unregistersymbol(playerHealth)
dealloc(newmem)
dealloc(playerHealth)

And somehow give playerHealth the correct address (I think if it's in the same script it could also be a label instead of a symbol??). But I have no idea how I'd do this.
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 152

Joined: 06 Jul 2014
Posts: 4696

PostPosted: Sun Feb 09, 2020 12:11 am    Post subject: Reply with quote

You misunderstand how an injection copy works (i.e. the method you're using to get the player's address).

An injection copy is a code injection that copies an address you don't know about into an area of memory you do know about. It works by modifying the game's code. The address won't magically appear on its own when the AA script is done- the game has to actually run that injected code in order for the address to be copied. Waiting for the game to do this is an inconvenience that's intrinsic to the injection copy method. Combining the two scripts into one wouldn't do much besides organize the AA code differently.

TDWL wrote:
why does cmp [playerAddress],ebx does not work?
You probably tried to assemble that when the playerAddress symbol wasn't defined.
Combining the two scripts into one would actually prevent this from happening, but the resulting script would be hard to maintain. I'd leave the two as separate scripts, make the "no damage" script a child of the injection copy script (click and drag the rows), and set the injection copy script to hide children when disabled (somewhere in the right click menu) when it's time to release the table.

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

Joined: 28 Jan 2020
Posts: 10

PostPosted: Sun Feb 09, 2020 12:58 am    Post subject: Reply with quote

From what I undertood the injection code replaces the instruction in the address given with a jump that goes into a place in memory that is "free" (which would be the allocated newmem). And there it runs the code I wrote and then jumps back to the previous address.
I know the code I wrote won't do anything, but I thought maybe there was a way to trigger the the instruction which has the health address whenever the NoDMG script was triggered. And then I could save that address in playerAddress.
But I don't really see how that would work and it may not make any sense at all.
If that's not possible though I have a bigger problem. As I mentioned, for now all the damage that should be applied to me was being redirected into a random enemy whose address I searched for manually. That's far from ideal though, so my idea was to use an instruction that runs every time I'm hit and which contains the address of the attacker, and that way redirect the damage automatically to any enemy that attacks me. But doing this in separate scripts seems like it would not work or at least fail often (because if the enemy address takes longer than the NoDMG script to run then it would probably carsh). How would you tackle this type of script? Maybe there's a far easier solution that I'm not seeing.


Quote:

You probably tried to assemble that when the playerAddress symbol wasn't defined.

So assuming the symbol is defined that instruction should work?
Also, I don't understand why I have to put the symbols between brackets. Is playerAddress actually a random address which has as its value my health address? Because I thought it was the address in itself.

Anyways, thanks for answering again so quickly Smile
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 152

Joined: 06 Jul 2014
Posts: 4696

PostPosted: Sun Feb 09, 2020 11:18 am    Post subject: Reply with quote

TDWL wrote:
And there it runs the code I wrote and then jumps back to the previous address.
Yes. It's not run when the AA script is run, but when the game eventually decides to run the code at the injection point.

TDWL wrote:
I thought maybe there was a way to trigger the the instruction which has the health address whenever the NoDMG script was triggered.
Not really.
You could call something that would execute that injection copy, but if you could do that, you'd also have a more direct way to get the player's address, making the whole injection copy redundant.

TDWL wrote:
How would you tackle this type of script? Maybe there's a far easier solution that I'm not seeing.
Look around and hope you get lucky. Perhaps there's something in the stack you could use. Find an enemy's address, set a breakpoint at the code that damages you, have the enemy damage you, and look through the stack for that address.

TDWL wrote:
Is playerAddress actually a random address which has as its value my health address?
That's mostly correct. The line "alloc(playerAddress,4)" allocates 4 bytes of memory somewhere and defines the symbol "playerAddress" to be the address of the first byte. So "playerAddress" is some random address in memory CE allocated, but "[playerAddress]" is the value stored at that address.
Instructions like "cmp [playerAddress],ebx" would be assembled as "cmp [017C1000],ebx". I believe this is the reason that instruction couldn't be assembled. If the first script isn't run, playerAddress is never allocated or defined, and CE doesn't know what "playerAddress" means when it tries to assemble that instruction.
This is also why the game has to run that injection copy to assign a meaningful value to playerAddress. The instruction "mov [playerAddress],edx" moves edx into some random address CE allocated: e.g. "mov [017C1000],edx". It's only after that instruction is executed by the game that playerAddress has some meaningful value. Before, it'll just contain the default value of newly allocated memory: i.e. 0.
So what you said is mostly correct. playerAddress is some random address, but it won't initially have as its value your health address. Only after the game runs the code injection that assigns it will it contain your health 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
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> General Discussions 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