📄 dedeclassemulator.pas
字号:
ClearRegister(Str2TRegister(sDestReg));
end;
rtCall : sReference:=sREF_POSSIBLE_VIRT_METH+' '+sCN+'.OFFS_'+s;
rtDynCall : sReference:=sREF_POSSIBLE_DYN_METH+' '+sCN+'.OFFS_'+s;
End;
bReference:=True;
end;
end;
function ByteToBin(b : Byte) : String;
begin
Result:='';
while b<>0 do
begin
if b mod 2 = 0 then Result:='0'+Result
else Result:='1'+Result;
b:=b div 2;
end;
while length(Result)<8 do Result:='0'+Result;
end;
function BinToByte(s : String) : Byte;
const power2_dta : array [0..7] of Byte = (1,2,4,8,16,32,64,128);
var i : Integer;
Begin
Result:=0;
For i:=Length(s) downto 1 Do
Result:=Result+(Integer(s[i]='1'))*power2_dta[8-i];
End;
function Decode_REG_mask(s:String) : Integer; overload;
var cs : Byte;
begin
cs:=BinToByte(s);
case cs of
0: Result:=ORD(rgEAX);
1: Result:=ORD(rgECX);
2: Result:=ORD(rgEDX);
3: Result:=ORD(rgEBX);
4: Result:=ORD(rgESP);
5: Result:=ORD(rgEBP);
6: Result:=ORD(rgESI);
7: Result:=ORD(rgEDI)
else Result:=-1;
end;
end;
function Decode_REG_mask(cs:Byte; bExtended : Boolean) : Integer; overload;
begin
if bExtended
Then case cs of
0: Result:=ORD(rgEAX);
1: Result:=ORD(rgECX);
2: Result:=ORD(rgEDX);
3: Result:=ORD(rgEBX);
4: Result:=ORD(rgESP);
5: Result:=ORD(rgEBP);
6: Result:=ORD(rgESI);
7: Result:=ORD(rgEDI)
else Result:=-1;
end
else Case cs of
// This shit acctually returns which 32bit
// register will be affected. The real decoding
// should return Al,CL,DL,BL,AH,CH,DX,BH
0: Result:=ORD(rgEAX);
1: Result:=ORD(rgECX);
2: Result:=ORD(rgEDX);
3: Result:=ORD(rgEBX);
4: Result:=ORD(rgEAX);
5: Result:=ORD(rgECX);
6: Result:=ORD(rgEDX);
7: Result:=ORD(rgEBX)
else Result:=-1;
end;
end;
/////////////////////////////////////////////////////////////////////////////
// supported masks so far:
//
// '11 reg1 reg2'
// 'mod reg r/m'
// '11 111 reg'
/////////////////////////////////////////////////////////////////////////////
Procedure DecodeOperandInfo(b : Byte; sMask : String; w : Byte; var i1,i2,i3 : Integer);
var bExtended : Boolean;
// bitmask : String;
begin
// bitmask:=ByteToBin(b);
bExtended:=w=1;
if sMask='11 reg1 reg2' then
begin
i1:=(B and $C0) shr 6;
i2:=Decode_REG_mask((B and $38) shr 3, bExtended);
i3:=Decode_REG_mask(B and $07, bExtended);
end;
if sMask='mod reg r/m' then
begin
i3:=(B and $C0) shr 6;
i2:=(B and $38) shr 3;
i1:=Decode_REG_mask(B and $07, bExtended);
end;
if sMask='11 111 reg' then
begin
i1:=(B and $C0) shr 6;
i2:=(B and $38) shr 3;
i3:=Decode_REG_mask(B and $07, bExtended);
end;
end;
procedure CL_Reg_to_Reg(sInstruction : String);
var i1,i2,i3 : Integer;
begin
///////////////////////////////
// "register1 to register2" //
// "register2 to register1" //
///////////////////////////////
DecodeOperandInfo(ORD(sInstruction[2]),'11 reg1 reg2',ORD(sInstruction[1]) mod 2, i1,i2,i3);
if i1=3 {i1 = 11} then
begin
if (ORD(sInstruction[1]) and $02) = 0 then ClearRegister(TRegister(i3));
if (ORD(sInstruction[1]) and $01) = 0 then ClearRegister(TRegister(i2));
end;
end;
procedure CL_Mod_Reg_RM(sInstruction : String);
var i1,i2,i3 : Integer;
begin
///////////////////////////
// "memory to register" //
///////////////////////////
DecodeOperandInfo(ORD(sInstruction[2]),'mod reg r/m',ORD(sInstruction[1]) mod 2, i1,i2,i3);
if i1<>3 {not register, register selector} then ClearRegister(TRegister(i2));
end;
procedure CL_Reg_to_Reg_0F(sInstruction : String);
var i1,i2,i3 : Integer;
begin
///////////////////////////////
// "register1 to register2" //
// "register2 to register1" //
///////////////////////////////
DecodeOperandInfo(ORD(sInstruction[2]),'11 reg1 reg2',1, i1,i2,i3);
if i1=3 {i1 = 11} then
begin
if (ORD(sInstruction[1]) and $02) = 0 then ClearRegister(TRegister(i3));
if (ORD(sInstruction[1]) and $01) = 0 then ClearRegister(TRegister(i2));
end;
end;
procedure CL_Mod_Reg_RM_0F(sInstruction : String);
var i1,i2,i3 : Integer;
begin
///////////////////////////
// "memory to register" //
///////////////////////////
DecodeOperandInfo(ORD(sInstruction[2]),'mod reg r/m',1, i1,i2,i3);
if i1<>3 {not register, register selector} then ClearRegister(TRegister(i2));
end;
procedure CL_Imm_to_A;
begin
////////////////////////////////////
// "immediate to AL, AX, or EAX" //
////////////////////////////////////
ClearRegister(rgEAX);
end;
Function Min(X,Y : Integer) : Integer;
Begin
If X<Y Then Result:=X Else Result:=Y;
End;
{*******************************************************************************
********************************************************************************
******
****** Pseudo Emulator of class operations and reference finder
******
********************************************************************************
********************************************************************************
}
// Instruction is a string containing the OPCODES
// size is the size in bytes of instruction
// sIns and sOp are the ASM Instruction and Operands representing the instruction
//
Procedure EmulateInstruction(Instruction : String; size : Integer; sIns, sOp : String);
var //RegIdx : TRegister;
i1,i2,i3,ii1,ii2,ii3,_i1,_i2,_i3 : Integer;
InstructionOF : String;
begin
bReference:=False;
//////////////////////////////////////////////////////////////////////////////
// THE x86 INSTRUCTION SET GROUPED BY OPCODES //
//////////////////////////////////////////////////////////////////////////////
// //
// Include only instructions that affect registers eax ... edi because //
// those registers are included in class emulation. Also includes //
// (FF : 10 010 reg) and (FF : 01 010 reg) call [reg+offs] instructions //
// that are handles to search DOI method references. //
// The (8B : 11 reg1 reg2) mov reg1, reg2 instruction is emulated in //
// DeDeDisAsm.ControlRef() function and EmulateInstruction() is not called //
// if that function returns any reference. Also note that this function //
// can return reference for CMP and LEA(??) instructions! //
//////////////////////////////////////////////////////////////////////////////
// This is called I1 to be known
DecodeOperandInfo(ORD(Instruction[2]),'11 reg1 reg2',1, i1,i2,i3);
DecodeOperandInfo(ORD(Instruction[3]),'11 reg1 reg2',1, ii1,ii2,ii3);
InstructionOF:=Copy(Instruction,1,Length(Instruction)-1);
Case ORD(Instruction[1]) of
$00,{add reg2, reg1}
$01 {add reg2, reg1}
: case I1 of
3 : {add reg2, reg1} CL_Reg_to_Reg(Instruction)
end;
$02,{add reg1, reg2}
$03 {add reg1, reg2}
: case I1 of
3 : {add reg2, reg1} CL_Reg_to_Reg(Instruction)
else {add reg, memory}
if (i2=7) {i2 = 111}
and (i1=2) {i1 = 10}
{add reg32, imm_32bit_data}
then OffsInfReference(TRegister(i3), sOp)
else CL_Mod_Reg_RM(Instruction);
end;
$04,{add reg8, imm_data}
$05 {add reg8, imm_data}
: CL_Imm_to_A;
$08,{or reg2, reg1}
$09 {or reg2, reg1}
: case I1 of
3 : {or reg2, reg1} CL_Reg_to_Reg(Instruction)
end;
$0A,{or reg1, reg2}
$0B {or reg1, reg2}
: case I1 of
3 : {or reg2, reg1} CL_Reg_to_Reg(Instruction)
else {or reg, memory} CL_Mod_Reg_RM(Instruction);
end;
$0C,{or reg8, imm_data}
$0D {or reg8, imm_data}
: CL_Imm_to_A;
$0F : case ORD(Instruction[2]) of
$00 : if (II1=3) then
case II2 of
0 : {sltd reg} ClearRegister(TRegister(II3));
1 : { str reg} ClearRegister(TRegister(II3));
end;
$01 : if (II1=3) then
case II2 of
3 : {smsw reg} ClearRegister(TRegister(II3));
end;
$02 : case II1 of
3 : {lar reg1, reg2 } CL_Reg_to_Reg_0F(InstructionOF)
else {lar reg, memory} CL_Mod_Reg_RM_0F(InstructionOF);
end;
$40..$4F
: case II1 of
3 : {cmov__ reg1, reg2 } CL_Reg_to_Reg_0F(InstructionOF)
else {cmov__ reg, memory} CL_Mod_Reg_RM_0F(InstructionOF);
end;
$90..$9F
: if (II1=3 {11}) and (II2=0 {000})
then {set__ reg} ClearRegister(TRegister(II3));
$A2 : begin
{cpuid}
ClearRegister(rgEAX);
ClearRegister(rgECX);
ClearRegister(rgEDX);
ClearRegister(rgEBX);
end;
$A4, {shld reg1, reg2, imm_data }
$A5 {shld reg1, reg2, cl }
: if II1 = 3 then
begin
ClearRegister(TRegister(II2));
ClearRegister(TRegister(II3));
end;
$AB : case II1 of
3 : {bts reg1, reg2 } CL_Reg_to_Reg_0F(InstructionOF)
else {bts reg, memory} CL_Mod_Reg_RM_0F(InstructionOF);
end;
$AC, {shrd reg1, reg2, imm_data }
$AD {shrd reg1, reg2, cl }
: if II1 = 3 then
begin
ClearRegister(TRegister(II2));
ClearRegister(TRegister(II3));
end;
$AF : case II1 of
3 : {imul reg1, reg2 } CL_Reg_to_Reg_0F(InstructionOF)
else {imul reg, memory} CL_Mod_Reg_RM_0F(InstructionOF);
end;
$B0,
$B1 : case II1 of
3 : {cmpxchg reg1, reg2}
begin
DecodeOperandInfo(ORD(Instruction[3]),'11 reg1 reg2',ORD(Instruction[2]) mod 2, _i1,_i2,_i3);
ClearRegister(TRegister(_i2));
ClearRegister(TRegister(_i3));
end;
else {cmpxchg reg1, memory}
begin
DecodeOperandInfo(ORD(Instruction[3]),'mod reg r/m',ORD(Instruction[2]) mod 2, _i1,_i2,_i3);
ClearRegister(TRegister(_i2));
end
end;
$B3 : case II1 of
3 : {btr reg1, reg2 } CL_Reg_to_Reg_0F(InstructionOF)
else {btr reg, memory} CL_Mod_Reg_RM_0F(InstructionOF);
end;
$B6,
$B7 : case II1 of
3 : {movzx reg1, reg2 } CL_Reg_to_Reg_0F(InstructionOF)
else {movzx reg, memory} CL_Mod_Reg_RM_0F(InstructionOF);
end;
$BB : case II1 of
3 : {btc reg1, reg2 } CL_Reg_to_Reg_0F(InstructionOF)
else {btc reg, memory} CL_Mod_Reg_RM_0F(InstructionOF);
end;
$BC : case II1 of
3 : {bsf reg1, reg2 } CL_Reg_to_Reg_0F(InstructionOF)
else {bsf reg, memory} CL_Mod_Reg_RM_0F(InstructionOF);
end;
$BD : case II1 of
3 : {bsr reg1, reg2 } CL_Reg_to_Reg_0F(InstructionOF)
else {bsr reg, memory} CL_Mod_Reg_RM_0F(InstructionOF);
end;
$BE,
$BF : case II1 of
3 : {movsx reg1, reg2 } CL_Reg_to_Reg_0F(InstructionOF)
else {movsx reg, memory} CL_Mod_Reg_RM_0F(InstructionOF);
end;
$C0,
$C1 : begin
DecodeOperandInfo(ORD(Instruction[2]),'11 reg1 reg2', ORD(Instruction[2]) mod 2, _i1,_i2,_i3);
if _i1=3 then begin
{xadd reg1, reg2 }
ClearRegister(TRegister(_i2));
ClearRegister(TRegister(_i3))
end;
end;
$C8..$CF
: begin
{bswap}
DecodeOperandInfo(ORD(Instruction[2]),'11 111 reg', 1 , _i1,_i2,_i3);
ClearRegister(TRegister(_i3));
end;
end; // 0F subfunctions
$10,{adc reg2, reg1}
$11 {adc reg2, reg1}
: case I1 of
3 : {adc reg2, reg1} CL_Reg_to_Reg(Instruction);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -