 |
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
alihlko Newbie cheater
Reputation: 0
Joined: 14 Apr 2023 Posts: 10 Location: earth
|
Posted: Thu Aug 24, 2023 11:59 am Post subject: Comperation issue in Cheat Engine... |
|
|
well so it's been weeks and i'm trying to make a CMP on (Assassins creed BH)
i've found the size and speed of players but i need a comparation here.. i've already tried different comparation types and tried to compare 1/2/3enemy with my player with no luck (yes it works but after restarting the mession it isn't) the reaon behind that is because every time i restart the game and have a disec comparasion i see different values its just like a random world of values..
my question is.. is there any stable way to find or make a stable and static offset comparation..?
the think that confuses me is that some modders on ferless forums made that comparasion possible somehow (i don't understand how).. and it's like below:
newmem:
movss xmm0,[eax+68]
code:
cmp eax,[pEntity]
jne short @f
movss xmm0,[fSpeed]
@@:
jmp return
Speed:
jmp newmem
return:
like why they compare a structure base with eax?
and what is inside [pEntity] is a structure of player coordinates or what?
a lot of questions around !!
something that is related to [pEntity] that i don't understand:
newmem:
{$try}
push ebx
mov ebx,eax
sub ebx,0x10
cmp ebx,[pEntity]
pop ebx
jne code
// freeroam routines... x32: 4-byte ptrs & e?x registers...
cmp byte ptr [bFreeRoam],1
jne code
push ebx
push edx
mov ebx,[pEntity]
mov [pStructCrdBase],ebx
// updated coordinates...
call updateCrd
mov ebx,[pStructCrdBase]
movaps xmm0,[ebx+40]
pop edx
pop ebx
jmp code
{$except}
inc [nCrash2]
code:
push ecx
movaps [eax+30],xmm0
jmp return
any help is appericiated..
|
|
Back to top |
|
 |
ParkourPenguin I post too much
Reputation: 152
Joined: 06 Jul 2014 Posts: 4703
|
Posted: Thu Aug 24, 2023 12:04 pm Post subject: |
|
|
alihlko wrote: | like why they compare a structure base with eax?
and what is inside [pEntity] is a structure of player coordinates or what? | There's probably another code injection that initializes `pEntity`. Look at a parent script.
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
 |
alihlko Newbie cheater
Reputation: 0
Joined: 14 Apr 2023 Posts: 10 Location: earth
|
Posted: Thu Aug 24, 2023 1:26 pm Post subject: |
|
|
ParkourPenguin wrote: | alihlko wrote: | like why they compare a structure base with eax?
and what is inside [pEntity] is a structure of player coordinates or what? | There's probably another code injection that initializes `pEntity`. Look at a parent script. |
i think it's this one can you please make things clear my purpose is to learn and i'm pretty noob with codes like that. i'm trying to use this method as comparation cuz sometimes the regular way is not giving a good results and sometime "like my case here" it soesn't even work mybe a bad game coding idk this is the full code (EXTRACTED FROM FEARLESS ACBH TABLE) that collects data from somewhere in the memory.. is it a structure that works with all comparations or what is the case? thank you
[ENABLE]
// structname: +10 .. +8
// +8: Entity ..+5C: World ..+688:NotoritieManager
// +8: Entity ..+5C: World ..+20 .. +80:NotoritieManager
// +8: Entity ..+5C: World ..+20 .. +74 .. +15C:NotoritieManager
// +10: CharacterAI ..+C: StatechartDesc
// ..+20: CharacterAI
// ..+58 .. +0: PlayerDataItem
// ..+58 .. +C: InventoryDataItem .. +10 .. +0~xx: (resp items): InventoryRechargeableContainer
// 0~ money
// +10 +58 +8: SharedDataItem
// +78 +30 +40: CSrvPlayerHealth
// +78 +30 +14: C+78CLPlayerDeath ~ CLNPCDeath
// +78 +30 +28: CSrvGroupMember
// +10 .. +4C .. +18 .. +178 (StatechartState) .. +1C: CSrvPlayerHealth
// +14: PhysicWorkspace
// +18: Human
// +24: EventListener
// +28: BhvAssassin
// +68: CharacterAI
// +78: CharacterAI
aobscanmodule(BhvAssassin,$process,8B D0 8B 01 23 C2 0F 84 65)
registersymbol(BhvAssassin)
alloc(newmem,$100,$process)
globalalloc(pBhvAssassin,4,$process)
globalalloc(pEntity,4,$process)
globalalloc(pHealth,4,$process)
globalalloc(pInventory,4,$process)
globalalloc(pSharedData,4,$process)
globalalloc(pNotoriety,4,$process)
globalalloc(bGodmode,1,$process)
globalalloc(bInvisible,1,$process)
bGodmode:
db 0
bInvisible:
db 0
globalalloc(nCrash1,4,$process)
globalalloc(nCrash2,4,$process)
globalalloc(nCrash3,4,$process)
nCrash1:
dd (int)0
nCrash2:
dd (int)0
nCrash3:
dd (int)0
// 'Player Coordinates' script
// x64 pointers are 8-bytes long
globalalloc(pStructCrdBase,4,$process)
globalalloc(pStructCrdOffset,4,$process)
// ptrs for Tools...
globalalloc(pCheckTools,4,$process)
globalalloc(pCheckIcons,4,$process)
globalalloc(pCheckViewP,4,$process)
pCheckIcons:
dd 0x0
pCheckViewP:
dd 0x0
// Time Of Day...
globalalloc(pTimeOfDay,4,$process)
// Accomplishments...
globalalloc(pAccomplishm,4,$process)
globalalloc(pAccomplVFT,4,$process)
// Cheats...
globalalloc(pCheatMgr,4,$process)
globalalloc(pMissionMgr,4,$process)
// see [Maintenance scripts ~ 'special' scripts] (x3)..
globalalloc(bInverseXY,1,$process)
bInverseXY:
db 0
label(code)
label(code2)
label(return)
newmem:
{$try}
mov edx,eax
mov eax,[ecx]
and eax,edx
code:
push ebx
test eax,eax
je code2
mov [pBhvAssassin],eax
// dis-enable invisible...
mov bl,[bInvisible]
mov byte ptr [eax+1C],bl
// get entity...
mov ebx,[eax+8]
mov [pEntity],ebx
// get health...
mov ebx,[eax+78]
test ebx,ebx
je code2
mov ebx,[ebx+30]
mov ebx,[ebx+40]
mov [pHealth],ebx
// get notoriety...
mov ebx,[eax+8]
mov ebx,[ebx+5C] // World
mov ebx,[ebx+688]
mov [pNotoriety],ebx
// get inventory...
mov ebx,[eax+10]
mov ebx,[ebx+58]
mov ebx,[ebx+C]
mov ebx,[ebx+10]
mov [pInventory],ebx
// get sharedData...
mov ebx,[eax+10]
mov ebx,[ebx+58]
mov ebx,[ebx+8]
test ebx,ebx
je code2
mov [pSharedData],ebx
// dis-enable godmode...
mov byte ptr [ebx+18],0x80
cmp [bGodmode],1
jne code2
mov byte ptr [ebx+18],0x81
jmp code2
{$except}
inc [nCrash1]
code2:
pop ebx
jmp return
BhvAssassin:
jmp newmem
db 90
return:
[DISABLE]
BhvAssassin:
db 8B D0 8B 01 23 C2
unregistersymbol(BhvAssassin)
dealloc(newmem)
{
// ORIGINAL CODE - INJECTION POINT: "ACBSP.exe"+C264A9
"ACBSP.exe"+C2648D: 8B 41 08 - mov eax,[ecx+08]
"ACBSP.exe"+C26490: C1 F8 1F - sar eax,1F
"ACBSP.exe"+C26493: 85 01 - test [ecx],eax
"ACBSP.exe"+C26495: 75 07 - jne ACBSP.exe+C2649E
"ACBSP.exe"+C26497: 8B CE - mov ecx,esi
"ACBSP.exe"+C26499: E8 12 F1 FF FF - call ACBSP.exe+C255B0
"ACBSP.exe"+C2649E: 8B 4E 18 - mov ecx,[esi+18]
"ACBSP.exe"+C264A1: 8B 41 08 - mov eax,[ecx+08]
"ACBSP.exe"+C264A4: C1 F8 1F - sar eax,1F
// ---------- INJECTING HERE ----------
"ACBSP.exe"+C264A7: 8B D0 - mov edx,eax
"ACBSP.exe"+C264A9: 8B 01 - mov eax,[ecx]
"ACBSP.exe"+C264AB: 23 C2 - and eax,edx
// ---------- DONE INJECTING ----------
"ACBSP.exe"+C264AD: 0F 84 65 02 00 00 - je ACBSP.exe+C26718
"ACBSP.exe"+C264B3: 0F B6 88 94 08 00 00 - movzx ecx,byte ptr [eax+00000894]
"ACBSP.exe"+C264BA: 8A 90 95 08 00 00 - mov dl,[eax+00000895]
"ACBSP.exe"+C264C0: 88 4D D4 - mov [ebp-2C],cl
"ACBSP.exe"+C264C3: 0F B6 88 96 08 00 00 - movzx ecx,byte ptr [eax+00000896]
"ACBSP.exe"+C264CA: 88 55 D5 - mov [ebp-2B],dl
"ACBSP.exe"+C264CD: 8B 90 98 08 00 00 - mov edx,[eax+00000898]
"ACBSP.exe"+C264D3: 88 4D D6 - mov [ebp-2A],cl
"ACBSP.exe"+C264D6: 8B 88 9C 08 00 00 - mov ecx,[eax+0000089C]
"ACBSP.exe"+C264DC: 89 55 D8 - mov [ebp-28],edx
"ACBSP.exe"+C264DF: 8B 90 A0 08 00 00 - mov edx,[eax+000008A0]
}
|
|
Back to top |
|
 |
ParkourPenguin I post too much
Reputation: 152
Joined: 06 Jul 2014 Posts: 4703
|
Posted: Thu Aug 24, 2023 1:52 pm Post subject: |
|
|
There's no easy way to explain this.
Data is typically organized into structures. These structures can contain pointers to other structures. Analyzing these structures is a part of reverse engineering.
The author probably found important values and started from there. You could try to do a pointer scan to find the parent structures, but that would likely give a ton of false positives. It's more reliable to backtrace an access to a value to learn the exact path a game is taking. This process requires knowledge of assembly and can't be explained in a single short forum post.
Do this process of backtracing for several values, and you'll eventually make a tree of sorts where one important structure (i.e. the one being dismantled in the second script you posted) branches off to several other structures (e.g. `pEntity`).
After you have that information, you can use it in other scripts such as the first script you posted.
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
 |
alihlko Newbie cheater
Reputation: 0
Joined: 14 Apr 2023 Posts: 10 Location: earth
|
Posted: Thu Aug 24, 2023 2:23 pm Post subject: |
|
|
ParkourPenguin wrote: | There's no easy way to explain this.
Data is typically organized into structures. These structures can contain pointers to other structures. Analyzing these structures is a part of reverse engineering.
The author probably found important values and started from there. You could try to do a pointer scan to find the parent structures, but that would likely give a ton of false positives. It's more reliable to backtrace an access to a value to learn the exact path a game is taking. This process requires knowledge of assembly and can't be explained in a single short forum post.
Do this process of backtracing for several values, and you'll eventually make a tree of sorts where one important structure (i.e. the one being dismantled in the second script you posted) branches off to several other structures (e.g. `pEntity`).
After you have that information, you can use it in other scripts such as the first script you posted. |
uh looks like its exactly what i thought! well i have some assembly knowledge but the question here is WHY "cmp eax,[pEntity]" gives a good/right comparation? i mean i found that [eax+08] is starting from our player's health but why comparing random player stracture values to player speed works? i mean does comparing structures like cmp eax,ecx is even possible? what is it comparing exactly?
if you ask me i would compare a value inside the pEntity structure with the same value but in shared structure.. like this one :
cmp eax+06,[pEntitty]+06
doesn't it make more sense?
i don't know if you got my question...
it's just hurting me that i don't have enough knowledge
EDIT:
wait.. maybe it's comparing two similar assembly part structures to determine how they differ. and as of [pEntity] has our players health (not shared structure) then it compares some part of our structure with the shared one so it does something like
cmp "sharedStructure","ourHealthIncludedStructure"
je "jump if health value is equal"
and so on..
am i wrong ?
|
|
Back to top |
|
 |
ParkourPenguin I post too much
Reputation: 152
Joined: 06 Jul 2014 Posts: 4703
|
Posted: Thu Aug 24, 2023 3:30 pm Post subject: |
|
|
Quote: | the question here is WHY "cmp eax,[pEntity]" gives a good/right comparation? ...but why comparing random player stracture values to player speed works? | That instruction is comparing neither random player structure values nor player speed. It's comparing pointers.
A pointer is a value type that stores the address of something else. `eax` and `[pEntity]` are addresses.
Initially, `[pEntity]` is 0. After the game executes the code in the second script you posted, it gets initialized to a certain address: `mov ebx,[eax+8]` / `mov [pEntity],ebx`. I'm guessing this certain address is the player structure.
In the first script you posted, the comparison compares `eax`, the address the game is using in the original code, against `[pEntity]`, the address the first code injection stored. If they're the same thing, it means the original code is accessing the player's structure. If it's different, then it's accessing something else (or `[pEntity]` hasn't been initialized yet).
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
 |
alihlko Newbie cheater
Reputation: 0
Joined: 14 Apr 2023 Posts: 10 Location: earth
|
Posted: Thu Aug 24, 2023 4:25 pm Post subject: |
|
|
ParkourPenguin wrote: | Quote: | the question here is WHY "cmp eax,[pEntity]" gives a good/right comparation? ...but why comparing random player stracture values to player speed works? | That instruction is comparing neither random player structure values nor player speed. It's comparing pointers.
A pointer is a value type that stores the address of something else. `eax` and `[pEntity]` are addresses.
Initially, `[pEntity]` is 0. After the game executes the code in the second script you posted, it gets initialized to a certain address: `mov ebx,[eax+8]` / `mov [pEntity],ebx`. I'm guessing this certain address is the player structure.
In the first script you posted, the comparison compares `eax`, the address the game is using in the original code, against `[pEntity]`, the address the first code injection stored. If they're the same thing, it means the original code is accessing the player's structure. If it's different, then it's accessing something else (or `[pEntity]` hasn't been initialized yet). |
this one cleared everything thanks alot..
|
|
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
|
|