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 


[CE] Assemblerunit.pas

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming
View previous topic :: View next topic  
Author Message
samuri25404
Grandmaster Cheater
Reputation: 7

Joined: 04 May 2007
Posts: 955
Location: Why do you care?

PostPosted: Sat Oct 27, 2007 7:16 am    Post subject: [CE] Assemblerunit.pas Reply with quote

I've been poking around in here, and with my limited knowledge of Pascal (damned Computer Science I, at least C++ is next year though!), I can pretty much understand the lines, but I'm not sure at all how CE decides which bytes go to which opcodes.

For example:

I picked a random opcode out of the list; that opcode had two parameters, 16 bit registers. So I have this opcode:

Code:

cmovl ax,bx


I loaded up Minesweeper (just so I don't have to mess anything important up), and found an address, then changed it to my opcode.

The bytes change to:

Code:

66 0F 4C C3


But wait, the assemblerunit.pas has it for only

Code:

66 0F 4C


Am I missing something somewhere?

Edit:

After poking around a little more, I figured out that the last byte is the parameters.

Code:

cmovl dx,cx


changes the bytes to

Code:

66 0F 4C D1


I'm still not quite sure on how it does it though.

If anyone could enlighten me, I would be very appreciative. Otherwise, I'll keep poking around.

Edit:

I found out what the second part of the byte is:

Code:

  if (reg='EAX') or (reg='AX') or (reg='AL') or (reg='MM0') or (reg='XMM0') or (reg='ST(0)') or (reg='ST') or (reg='ES') or (reg='CR0') or (reg='DR0') then result:=0;
  if (reg='ECX') or (reg='CX') or (reg='CL') or (reg='MM1') or (reg='XMM1') or (reg='ST(1)') or (reg='CS') or (reg='CR1') or (reg='DR1') then result:=1;
  if (reg='EDX') or (reg='DX') or (reg='DL') or (reg='MM2') or (reg='XMM2') or (reg='ST(2)') or (reg='SS') or (reg='CR2') or (reg='DR2') then result:=2;
  if (reg='EBX') or (reg='BX') or (reg='BL') or (reg='MM3') or (reg='XMM3') or (reg='ST(3)') or (reg='DS') or (reg='CR3') or (reg='DR3') then result:=3;
  if (reg='ESP') or (reg='SP') or (reg='AH') or (reg='MM4') or (reg='XMM4') or (reg='ST(4)') or (reg='FS') or (reg='CR4') or (reg='DR4') then result:=4;
  if (reg='EBP') or (reg='BP') or (reg='CH') or (reg='MM5') or (reg='XMM5') or (reg='ST(5)') or (reg='GS') or (reg='CR5') or (reg='DR5') then result:=5;
  if (reg='ESI') or (reg='SI') or (reg='DH') or (reg='MM6') or (reg='XMM6') or (reg='ST(6)') or (reg='HS') or (reg='CR6') or (reg='DR6') then result:=6;
  if (reg='EDI') or (reg='DI') or (reg='BH') or (reg='MM7') or (reg='XMM7') or (reg='ST(7)') or (reg='IS') or (reg='CR7') or (reg='DR7') then result:=7;


Still looking for the first part though.

Edit:

Scratch the last edit, I have no idea:

Code:

cmovl ax,ax - OPCODEBYTES + C0

cmovl bx,ax - OPCODEBYTES + D8

cmovl cx,ax - OPCODEBYTES + C8

cmovl dx,ax - OPCODEBYTES + D0


Had my theory before been true, then the last half of the byte should have been constant, right? But it was a 0 at some times, and an 8 at other times.

As I stated before, I only have a limited ammount of knowledge in Pascal (I'm a C guy at heart--and I mean C#, not actual C).

Edit:

I've given up analyzing the code--it's starting to look like jibberish, and my eyes are starting to hurt from the white bg of notepad (I reinstalled Windows recently, and I haven't installed Delphi yet).

Anyways, here's the results of changing the registers:

Code:

ax,ax - C0
ax,cx - C1
ax,dx - C2
ax,bx - C3

cx,ax - C8
cx,cx - C9
cx,dx - CA
cx,bx - CB

dx,ax - D0
dx,cx - D1
dx,dx - D2
dx,bx - D3

bx,ax - D8
bx,cx - D9
bx,dx - DA
bx,bx - DB


I'm not quite sure where this is going to get me, but if anyone could help me out, as I stated before, I would be very appreciative.

Edit:

After toying around with a couple other opcodes, I found that the last byte stays constant as long as the parameters stay the same.

I even found that changing for example

Code:

ax,bx


to

Code:

eax,ebx


produces the same last byte, but only changes the opcode's bytes (I saw that there were many opcodes of a certain thing in the code--there's like 8 "cmp" commands, for example.)

However, I'm not sure if he (and if I should, in my program--that's what this is all for) dynamically generates this all, or has a permutation, because there is a little set:

Code:

  if (reg='EAX') or (reg='AX') or (reg='AL') or (reg='MM0') or (reg='XMM0') or (reg='ST(0)') or (reg='ST') or (reg='ES') or (reg='CR0') or (reg='DR0') then result:=0;
  if (reg='ECX') or (reg='CX') or (reg='CL') or (reg='MM1') or (reg='XMM1') or (reg='ST(1)') or (reg='CS') or (reg='CR1') or (reg='DR1') then result:=1;
  if (reg='EDX') or (reg='DX') or (reg='DL') or (reg='MM2') or (reg='XMM2') or (reg='ST(2)') or (reg='SS') or (reg='CR2') or (reg='DR2') then result:=2;
  if (reg='EBX') or (reg='BX') or (reg='BL') or (reg='MM3') or (reg='XMM3') or (reg='ST(3)') or (reg='DS') or (reg='CR3') or (reg='DR3') then result:=3;
  if (reg='ESP') or (reg='SP') or (reg='AH') or (reg='MM4') or (reg='XMM4') or (reg='ST(4)') or (reg='FS') or (reg='CR4') or (reg='DR4') then result:=4;
  if (reg='EBP') or (reg='BP') or (reg='CH') or (reg='MM5') or (reg='XMM5') or (reg='ST(5)') or (reg='GS') or (reg='CR5') or (reg='DR5') then result:=5;
  if (reg='ESI') or (reg='SI') or (reg='DH') or (reg='MM6') or (reg='XMM6') or (reg='ST(6)') or (reg='HS') or (reg='CR6') or (reg='DR6') then result:=6;
  if (reg='EDI') or (reg='DI') or (reg='BH') or (reg='MM7') or (reg='XMM7') or (reg='ST(7)') or (reg='IS') or (reg='CR7') or (reg='DR7') then result:=7;


That I posted before, and that explains the fact that changing

Code:

ax,bx


to

Code:

eax,ebx


doesn't change the last byte.

But my question is:

Does DB dynamically generate the last byte based on the parameters, or does he have all the permutations listed out?

Like, that he might have

Code:

1-1


to have something like

Code:

ax,ax


and maybe

Code:

2-1


to have

Code:

ebx,eax


based on the first couple of bytes of the opcode.

(Like the fact that eax,ebx changes the first bytes of an opcode, but does nothing to the last one)

Edit:

YES!

I've figured out where the missing bytes are:

Code:

ax,ax - C0
ax,cx - C1
ax,dx - C2
ax,bx - C3
ax,sp - C4
ax,bp - C5
ax,si - C6
ax,di - C7

cx,ax - C8
cx,cx - C9
cx,dx - CA
cx,bx - CB
cx,sp - CC
cx,bp - CD
cx,si - CE
cx,di - CF

:
:
:


Etc,

I'm gonna go ahead and guess that DB generates these dynamically--and if not, he really should--no one needs to do all that crap, even if it does make it easier to read.

A big whopping thanks to all of you!
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 programming 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