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 


What is the best way to compare 18 bytes in auto assembler?

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

Joined: 25 Aug 2024
Posts: 3

PostPosted: Sun Aug 25, 2024 9:25 am    Post subject: What is the best way to compare 18 bytes in auto assembler? Reply with quote

Hi! I'm hacking a really ancient game, in which I was unable to find a stable pointer to the character object, rather a huge static array with object pointers on the same map (scene?). So I found a stable 18-bytes AOB signature, that (if subsctracted c8b offset) will point to entity start (which I need).

The plan: on calling a spell function go to ebx adress and see if it is indeed points to the main character object, using my stable signature (+ cb8), get 18 bytes from there, compare them and if it is indeed the character object, do not substract the spell counter. But I was unable to do so in pure lua, despite trying I couldn't transfer any information to ($asm), via flag, symbol or otherwise.

So I would like to know how to best do it using auto assembler only. To clarify further, I'll attach a snippet of my code in lua, which could be used to better understand the issue.



lua.png
 Description:
 Filesize:  45.22 KB
 Viewed:  1975 Time(s)

lua.png


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

Joined: 06 Jul 2014
Posts: 4718

PostPosted: Sun Aug 25, 2024 1:42 pm    Post subject: Reply with quote

{$lua} is for preprocessing- substituting a string that will then be interpreted by the auto assembler.
Code:
{$lua}
return 'define(foo,1234)'
{$asm}

// same as writing:
define(foo,1234)

You might be looking for {$luacode}
https://forum.cheatengine.org/viewtopic.php?t=618134

But you really shouldn't be using {$luacode} unless you need to interact with CE itself from the target process. That involves synchronous IPC which is relatively expensive compared to just staying in the game's process.
If you don't like assembly, try {$ccode} instead:
Code:
alloc(pattern,32)
newmem:
  push rax
{$ccode ptr=rbx output=rax}
extern int memcmp(const void *p1, const void *p2, unsigned long long size);
extern unsigned char pattern;
output = memcmp((unsigned char *)ptr + 1976, &pattern, 18);
{$asm}
  test eax,eax
  ...
  pop rax
  // original code here
  jmp return

pattern:
  db 43 6F 6E 65 00 00 00 00 44 50 4C 41 59 45 52 33 38 BD

But if it's just comparing a few bytes in memory against a static pattern, that's easy enough to do in pure assembly
Code:
newmem:
  push rax
  mov rax,00000000656E6F43
  cmp [rbx+7B8],rax
  jne ...
  mov rax,33524559414C5044
  cmp [rbx+7C0],rax
  jne ...
  mov eax,BD38
  cmp word ptr[rbx+7C8],ax
  jne ...
  ...
  pop rax
  // original code here
  jmp return


Edit: If the game is 32-bit, the code is different. No 64-bit registers (e.g. use eax instead of rax), memcmp size parameter is unsigned long, and you have to compare 4 bytes at a time for the pure assembly version (but you can directly compare an immediate against a 32-bit memory location)

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

Joined: 25 Aug 2024
Posts: 3

PostPosted: Mon Aug 26, 2024 4:32 am    Post subject: Reply with quote

Many thanks! I tinkered with assembler code for a while, using your code for a reference, and got working solution:
Code:

push rcx
mov rcx, 00000000656E6F4E
cmp [rbx+7B8], rcx
jne originalcode
mov rcx, 33524559414C5044
cmp [rbx+7C0], rcx
jne originalcode
mov ecx, BD38
cmp word ptr[rbx+7C8], cx
jne originalcode

jmp exit

originalcode:
and [rsi+08],ax

exit:
pop rcx
test r13d,r13d
jmp returnhere


I also checked out C code, and I understand it well enough, but I'm unsure how you initialize
Code:
 alloc(pattern,32)

with the actual pattern, that later got itself compared in C block. Should you do it manually in assembly (move chunk in eax, move to adress of allocated memory, update offset and repeat), or is there some other more elegant way?

I had no idea that $lua is not done at injection, but rather on pre-procession, so I was really confused yesterday. Hopefully, by injecting more code on C I'll make higher-level languages to make all of heavy lifting, and leave $asm for control flow only (jmp, je, call etc)
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 152

Joined: 06 Jul 2014
Posts: 4718

PostPosted: Mon Aug 26, 2024 11:12 am    Post subject: Reply with quote

Crockball wrote:
I'm unsure how you initialize
Code:
alloc(pattern,32)
with the actual pattern, that later got itself compared in C block.
This pair of lines at the bottom:
Code:
pattern:
  db 43 6F 6E 65 00 00 00 00 44 50 4C 41 59 45 52 33 38 BD
`db` writes bytes into memory
_________________
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
Csimbi
I post too much
Reputation: 97

Joined: 14 Jul 2007
Posts: 3337

PostPosted: Mon Aug 26, 2024 3:07 pm    Post subject: Reply with quote

I'd try using AOB scan? (scan for the 18 bytes in the memory where the other 18 bytes are)
You can make luacall in ASM Very Happy
Back to top
View user's profile Send private message
Crockball
How do I cheat?
Reputation: 0

Joined: 25 Aug 2024
Posts: 3

PostPosted: Tue Aug 27, 2024 8:46 am    Post subject: Reply with quote

Quote:
`db` writes bytes into memory

thanks again, I didn't realize that db was an instruction, I took it for hexadecimal number DB.

Quote:
I'd try using AOB scan? (scan for the 18 bytes in the memory where the other 18 bytes are)


My previous solution (that I've decided to abandon) was:
aobscan as initialise to find pointer to player object in a static array, thus updating symbols, declared in lua, which then passed to auto assembler and make checks on 2 shared function. However due to my unableness to understand why and where static array was updated (and reshuffled), I couldn't find suitable places to inject updateSymbols() function. From what I understand, the game updated static array on save, on load, every few days and every few locations, but each of these cases were not a 100% update situation, so I missed quite a few updates and pointer to character entity (ultimate goal) was lost.

And if you are meaning that I should call aobscan each time I cast the spell, I decided to drop this idea either, because each lua aobscan will freeze the game for about 1 to 1.5 second, and it is possible to cast 10 spells each combat. I have a rather modest setup (ryzen 5 1600), so I've decided that this preformance is unsatisfactory.

or if you mean that I should aobscan to find my signatrue, the issue was not about finding it, but rather putting it to where alloc() has happened.
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