?? dsasm_functions.cpp
字號:
#include "Disasm.h"
// x86 Registers
char *regs[3][9] = {
{ "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh" }, // 8Bit
{ "ax", "cx", "dx", "bx", "sp", "bp", "si", "di" }, // 16Bit
{ "eax","ecx","edx","ebx","esp","ebp","esi","edi" } // 32bit
//{ "eeax","eecx","eedx","eebx","eesp","eebp","eesi",eedi"
};
// x86 Data Size
const char *regSize[10] = { "Qword","Dword","Word","Byte","Fword","TByte","(28)Byte","(108)Byte","DQword", "(512)Byte" }; // Registers Size of addressing
// x86 Segments
const char *segs[8] = { "ES","CS","SS","DS","FS","GS","SEG?","SEG?"}; // Segments
// x86 SIB
const char *Scale[5] = { "-","+","*2+","*4+","*8+" }; // Scale in SIB
// 16Bit Addressing
const char *addr16[8] = { "BX+SI","BX+DI","BP+SI","BP+DI","SI","DI","BX","BP" }; // 16bit addressing
// x86 Instructions
const char *Instructions[8] = { "add" , "or" , "adc" , "sbb" , "and" , "sub" , "xor" , "cmp" }; // Basic Repetive Assembly
const char *ArtimaticInstructions[8] = { "rol" , "ror" , "rcl" , "rcr" , "shl" , "shr" , "sal" , "sar" }; // Bitwise Repetive Assembly
const char *InstructionsSet2[8] = { "test", "test", "not" , "neg" , "mul" , "imul" , "div" , "idiv" }; // Arithmatic Repetive Assembly (test is Twice -> long repetive set)
const char *InstructionsSet3[8] = { "inc" , "dec" , "???" , "???" , "???" , "???" , "???" , "???" }; // Arithmatic Repetive Assebly (Opcode 0xFE)
const char *InstructionsSet4[8] = { "inc" , "dec" , "call","call far", "jmp" , "jmp far", "push", "???" }; // Arithmatic Repetive Assebly (Opcode 0xFE)
// FPU instructions
const char *FpuRegs[8] = { "st(0)", "st(1)", "st(2)", "st(3)" , "st(4)" , "st(5)" , "st(6)" , "st(7)" }; // FPU Registers
const char *FpuInstructions[8] = { "fadd" , "fmul" , "fcom" , "fcomp" , "fsub" , "fsubr" , "fdiv" , "fdivr" }; // Unsigned fpu instructions
const char *FpuInstructionsSigned[8] = { "fiadd", "fimul", "ficom", "ficomp", "fisub" , "fisubr", "fidiv" , "fidivr" }; // Signed fpu instructions
const char *FpuInstructionsSet2[8] = { "fld" , "???" , "fst" , "fstp" , "fldenv", "fldcw" , "fstenv", "fstcw" }; // set2 of Unsigned fpu instructions
const char *FpuInstructionsSet2Signed[8] = { "fild" , "???" , "fist" , "fistp" , "???" , "fld" , "???" , "fstp" }; // set2 of Signed fpu instructions
const char *FpuInstructionsSet3[8] = { "fld" , "???" , "fst" , "fstp" , "frstor", "???" , "fsave" , "fstsw" }; // set3 of Unsigned fpu instructions
const char *FpuInstructionsSet2Signed_EX[8] = { "fild" , "???" , "fist" , "fistp" , "fbld" , "fild" , "fbstp" , "fistp" }; // set2 of Signed fpu instructions With Extended 2 instructions
// MMX, 3DNow! Registers
const char *Regs3DNow [8] = { "mm0" , "mm1" , "mm2" , "mm3" , "mm4" , "mm5" , "mm6" , "mm7" }; // 3DNow! Registers
const char *MMXRegs [8] = { "xmm0" , "xmm1" , "xmm2" , "xmm3" , "xmm4" , "xmm5" , "xmm6" , "xmm7" }; // MMX Registers
// MMX, 3DNow! (+extended), SSE , SSE2 Instructions
const char *NewSet [8] = { "sldt" , "str" , "lldt" , "ltr" , "verr" , "verw" , "???" , "???" }; // New Set1
const char *NewSet2 [8] = { "sgdt" , "sidt" , "lgdt" , "lidt" , "smsw" , "???" , "lmsw" , "invlpg" }; // New Set2
const char *NewSet3 [8] = { "prefetchnta", "prefetcht0", "prefetcht1", "prefetcht2", "???" , "???" , "???" , "???" }; // New Set3
const char *NewSet4 [8] = { "movaps" , "movaps" , "cvtpi2ps" , "???" , "cvttps2pi" , "cvtps2pi", "ucomiss" , "comiss" }; // New Set4
const char *NewSet5 [16] = { "cmovo" , "cmovno" , "cmovb" , "cmovnb" , "cmove" , "cmovne" , "cmovbe" , "cmova" , "cmovs" , "cmovns" , "cmovpe" , "cmovpo" , "cmovl" , "cmovge" , "cmovle", "cmovg" }; // New Set5
const char *NewSet6 [16] = { "???" , "sqrtps" , "rsqrtps" , "rcpps" , "andps" , "andnps" , "orps" , "xorps" , "addps" , "mulps" , "???" , "???" , "subps" , "minps" , "divps" , "maxps" }; // New Set6
const char *NewSet6Ex [16] = { "???" , "sqrtss" , "rsqrtss" , "rcpss" , "andps" , "andnps" , "orps" , "xorps" , "addss" , "mulss" , "???" , "???" , "subss" , "minss" , "divss" , "maxss" }; // New Set6 Extended (Prefix 0xF3)
const char *NewSet7 [16] = { "punpcklbw" , "punpcklwd" , "punpckldq" , "packsswb" , "pcmpgtb" , "pcmpgtw" , "pcmpgtd" , "packuswb", "punpckhbw", "punpckhwd", "punpckhdq" , "packssdw", "???" , "???" , "movd" , "movq" }; // New Set7
const char *NewSet8 [8] = { "pshufw" , "???" , "???" , "???" , "pcmpeqb" , "pcmpeqw" , "pcmpeqd" , "emms" }; // New Set8
const char *NewSet9 [16] = { "seto" , "setno" , "setb" , "setnb" , "sete" , "setne" , "setbe" , "seta" , "sets" , "setns" , "setpe" , "setpo" , "setl" , "setge" , "setle" , "setg" }; // New Set9
const char *NewSet10 [16] = { "push fs" , "pop fs" , "cpuid" , "bt" , "shld" , "shld" , "???" , "???" , "push gs" , "pop gs" , "rsm" , "bts" , "shrd" , "shrd" , "fxsave", "imul" }; // New Set10
const char *NewSet10Ex [8] = { "fxsave" , "fxrstor" , "ldmxcsr" , "stmxcsr" , "???" , "???" , "???" , "???" }; // New Set10 Extended (Opcode 0xAE)
const char *NewSet11 [16] = { "cmpxchg" , "cmpxchg" , "lss" , "btr" , "lfs" , "lgs" , "movzx" , "movzx" , "???" , "???" , "???" , "btc" , "bsf" , "bsr" , "movsx" , "movsx" }; // New Set11
const char *NewSet12 [8] = { "cmpeqps" , "cmpltps" , "cmpleps" , "cmpunordps", "cmpneqps" , "cmpnltps", "cmpnleps", "cmpordps" }; // New Set12
const char *NewSet12Ex [8] = { "cmpeqss" , "cmpltss" , "cmpless" , "cmpunordss", "cmpneqss" , "cmpnltss", "cmpnless", "cmpordss" }; // New Set12 Extended (Prefix 0xF3)
const char *NewSet13 [16] = { "???" , "psrlw" , "psrld" , "psrlq" , "???" , "pmullw" , "???" , "pmovmskb", "psubusb" , "psubusw" , "pminub" , "pand" , "paddusb" , "paddusw", "pmaxub", "pandn" }; // New Set13
const char *NewSet14 [16] = { "pavgb" , "psraw" , "psrad" , "pavgw" , "pmulhuw" , "pmulhw" , "???" , "movntq" , "psubsb" , "psubsw" , "pminsw" , "por" , "paddsb" , "paddsw" , "pmaxsw", "pxor" }; // New Set14
const char *NewSet15 [16] = { "???" , "psllw" , "pslld" , "psllq" , "???" , "pmaddwd" , "psadbw" , "maskmovq", "psubb" , "psubw" , "psubd" , "???" , "paddb" , "paddw" , "paddd" , "???" }; // New Set15
// Debug/Control/Test Registers
const char *DebugRegs [8] = { "dr0" , "dr1" , "dr2" , "dr3" , "dr4" , "dr5" , "dr6" , "dr7" }; // Debug Registers
const char *ControlRegs[8] = { "cr0" , "cr1" , "cr2" , "cr3" , "cr4" , "cr5" , "cr6" , "cr7" }; // Control Registers
//const char *TestRegs [8] = { "tr0" , "tr1" , "tr2" , "tr3" , "tr4" , "tr5" , "tr6" , "tr7" }; // Test Registers
// =============================================//
// Decoding Functions //
// =============================================//
void Mod_11_RM(BYTE d, BYTE w,char **Opcode,DISASSEMBLY **Disasm,char instruction[],bool PrefixReg,BYTE Op,DWORD **index)
{
/*
Function Mod_11_RM Checks whatever we have
Both bit d (direction) and bit w (full/partial size).
There are 4 states:
00 - d=0 / w=0 ; direction -> (ie: DH->DL), partial size (AL,DH,BL..)
01 - d=0 / w=1 ; direction -> (ie: EDX->EAX), partial size (EAX,EBP,EDI..)
10 - d=1 / w=0 ; direction <- (ie: DH<-DL), partial size (AL,DH,BL..)
11 - d=1 / w=1 ; direction <- (ie: EDX<-EAX), partial size (EAX,EBP,EDI..)
Also deals with harder opcodes which have diffrent
Addresing type.
*/
DWORD dwMem=0,dwOp=0;
int RM,IndexAdd=1,m_OpcodeSize=2,Pos; // Register(s) Pointer
WORD wMem=0,wOp=0;
BYTE reg1=0,reg2=0,m_Opcode=0,REG;
BYTE FOpcode;
char assembly[50]="",temp[128]="",m_Bytes[128]="";
Pos=(*(*index)); // Current Position
m_Opcode = (BYTE)(*(*Opcode+Pos+1));// Decode registers from second byte
// Strip Used Instructions / Used Segment
REG=(BYTE)(*(*Opcode+Pos+1));
REG>>=3;
REG&=0x07;
// Check Opcode range
if((Op>=0x80 && Op<=0x83) || Op==0xC7 || Op==0x69)
{
switch(Op) // Find Current Opcode
{
// Diffrent Opcodes ahs different Modes
case 0x80: case 0x82: case 0x83:// 1 byte
{
RM=REG8;
if(Op==0x83 && PrefixReg==0) // full size reg
RM=REG32;
if(PrefixReg==1)
RM=REG16;
reg1=(m_Opcode&7); // Get Destination Register
SwapWord((BYTE*)(*Opcode+Pos+1),&wOp,&wMem);
FOpcode=wOp&0x00FF;
if(FOpcode>0x7F) // check for signed numbers!!
{
FOpcode = 0x100-FOpcode; // -XX
wsprintf(temp,"%s%02X",Scale[0],FOpcode); // '-' aritmathic
}
else
wsprintf(temp,"%02X",FOpcode);
// Read Opcodes: Opcode - imm8
wsprintf(m_Bytes,"%02X%04X",Op,wOp);
m_OpcodeSize=3;
(*(*index))+=2; // Prepare to read next Instruction
}
break;
case 0x81: case 0xC7: case 0x69: // 2 (WORD)/4 (DWORD) bytes
{
// 0x66 is being Used
if(PrefixReg==1) // READ WORD
{
RM=REG16;
reg1=(m_Opcode&0x07); // Get Destination Register
SwapWord((BYTE*)(*Opcode+Pos+2),&wOp,&wMem);
SwapDword((BYTE*)(*Opcode+Pos),&dwOp,&dwMem);
// Read imm16
wsprintf(temp,"%04X",wMem);
// Read Opcodes: Opcode - imm16
wsprintf(m_Bytes,"%08X",dwOp);
m_OpcodeSize=4; // Instruction Size
(*(*index))+=3;
}
else // READ DWORD
{
RM=REG32;
reg1=(m_Opcode&0x07); // Get Destination Register
SwapDword((BYTE*)(*Opcode+Pos+2),&dwOp,&dwMem);
SwapWord((BYTE*)(*Opcode+Pos),&wOp,&wMem);
// Read Dword Data number (imm32)
wsprintf(temp,"%08X",dwMem);
// Read Opcodes: Opcode - imm32
wsprintf(m_Bytes,"%04X %08X",wOp,dwOp);
m_OpcodeSize=6; // Instruction Size
(*(*index))+=5;
}
}
break;
}
if(Op==0xC7)
{
/*
Instruction rule: Mem,Imm -> 1100011woo000mmm,imm
Code Block: 1100011
w = Reg Size
oo - Mod
000 - Must be!
mmm - Reg/Mem
imm - Immidiant (麼弳)
*/
if(((m_Opcode&0x38)>>3)!=0) // check 000
lstrcat((*Disasm)->Remarks,"Invalid Instruction");
wsprintf(assembly,"%s %s, %s","mov",regs[RM][reg1],temp);
}
else{
// Build assembly
if(Op==0x69)
{
reg2=((m_Opcode&0x038)>>3);
wsprintf(assembly,"imul %s, %s, %s",regs[RM][reg2],regs[RM][reg1],temp);
}
else
wsprintf(assembly,"%s %s, %s",Instructions[REG],regs[RM][reg1],temp);
}
lstrcat((*Disasm)->Assembly,assembly);
(*Disasm)->OpcodeSize=m_OpcodeSize;
lstrcat((*Disasm)->Opcode,m_Bytes);
return; // RET
}
else{ // Check Other Set of Opcodes
// Special Types usnig Segments
if(Op==0x8C || Op==0x8E)
{
RM=REG16;
reg1=(m_Opcode&0x07);
SwapWord((BYTE*)(*Opcode+Pos),&wOp,&wMem);
wsprintf(m_Bytes,"%04X",wOp);
if(REG<=5) // SEG IS KNOWN
{
if(d==0) // (->) Direction
{
wsprintf(assembly,"%s %s, %s",instruction,regs[RM][reg1],segs[REG]);
}
else // (<-) Direction
{
wsprintf(assembly,"%s %s, %s",instruction,segs[REG],regs[RM][reg1]);
}
}
else // UNKNOWN SEG (NOT IN RANGE 0-5)
{
if(d==0) // (->) Direction
{
wsprintf(assembly,"%s %s, SEG ??",instruction,regs[RM][reg1]);
}
else //(<-) Direction
{
wsprintf(assembly,"%s SEG ??,%s",instruction,regs[RM][reg1]);
}
// Put warning
lstrcat((*Disasm)->Remarks,"Unknown Segment Used,");
}
// Add data to the Struct
(*Disasm)->OpcodeSize=2; // Instruction Size
lstrcat((*Disasm)->Assembly,assembly);
lstrcat((*Disasm)->Opcode,m_Bytes);
// Segment Modification Opcode ( MOV <SEG>, <REG>)
if(Op==0x8E)
lstrcat((*Disasm)->Remarks,"Segment Is Being Modified!");
(*(*index))++;
return;
}
if(Op==0xC6)
{
RM=REG8;
if(m_Opcode>=0xC0 && m_Opcode<=0xC7)
{
reg1=(m_Opcode&0x07); // Get Destination Register
SwapWord((BYTE*)(*Opcode+Pos+1),&wOp,&wMem);
// Read imm16
wsprintf(temp,"%02X",*((BYTE*)(*Opcode+Pos+2)));
wsprintf(m_Bytes,"C6 %04X",wOp);
// Read Opcodes: Opcode - imm16
m_OpcodeSize=3; // Instruction Size
(*(*index))+=2;
wsprintf(assembly,"%s %s, %s","mov",regs[RM][reg1],temp);
}
else
{
SwapWord((BYTE*)(*Opcode+Pos+1),&wOp,&wMem);
wsprintf(m_Bytes,"C6 %04X",wOp);
m_OpcodeSize=3;
(*(*index))+=2;
lstrcpy(assembly,"???");
}
lstrcat((*Disasm)->Assembly,assembly);
(*Disasm)->OpcodeSize=m_OpcodeSize;
lstrcat((*Disasm)->Opcode,m_Bytes);
return;
}
// Mixed Instructions
if(Op==0xC0 || Op==0xC1)
{
// Check register Size
if(w==0)
RM=REG8;
else
{
if(PrefixReg==1)
RM=REG16;
else
RM=REG32;
}
reg1=(m_Opcode&7); // Get Destination Register
SwapWord((BYTE*)(*Opcode+Pos+1),&wOp,&wMem);
wsprintf(temp,"%02X",wOp&0x00FF);
// Read Opcodes: Opcode - imm8
wsprintf(m_Bytes,"%02X%04X",Op,wOp);
m_OpcodeSize=3;
(*(*index))+=2; // Prepare to read next Instruction
// Build assembly
wsprintf(assembly,"%s %s, %s",ArtimaticInstructions[REG],regs[RM][reg1],temp);
lstrcat((*Disasm)->Assembly,assembly);
(*Disasm)->OpcodeSize=m_OpcodeSize;
lstrcat((*Disasm)->Opcode,m_Bytes);
return; // exit the function
}
// XCHG Register
if(Op>=0x91 && Op<=0x97)
{
m_Opcode=(*(*Opcode+Pos)); // 1 byte Opcode
m_Opcode+=0x30; // Add 0x30 in order to get values of EAX-EDI (trick)
IndexAdd=0; // Dont Add to the index counter.
m_OpcodeSize=1; // 1 byte opcode
}
// (->) / reg8
if(d==0 && w==0)
{
RM=REG8;
reg1=(m_Opcode&0x07);
reg2=(m_Opcode&0x38)>>3;
}
// (->) / reg32
if(d==0 && w==1)
{
RM=REG32;
if(PrefixReg==1)
RM=REG16; // (->) / reg16 (RegPerfix is being used)
reg1=(m_Opcode&0x07);
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -