samuri25404 Grandmaster Cheater
Reputation: 7
Joined: 04 May 2007 Posts: 955 Location: Why do you care?
|
Posted: Sat Oct 27, 2007 7:16 am Post subject: [CE] Assemblerunit.pas |
|
|
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:
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:
But wait, the assemblerunit.pas has it for only
Am I missing something somewhere?
Edit:
After poking around a little more, I figured out that the last byte is the parameters.
changes the bytes to
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
to
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
to
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
to have something like
and maybe
to have
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!
|
|