📄 dsasm_functions.cpp
字号:
/*
8888888b. 888 888 d8b
888 Y88b 888 888 Y8P
888 888 888 888
888 d88P 888d888 .d88b. Y88b d88P 888 .d88b. 888 888 888
8888888P" 888P" d88""88b Y88b d88P 888 d8P Y8b 888 888 888
888 888 888 888 Y88o88P 888 88888888 888 888 888
888 888 Y88..88P Y888P 888 Y8b. Y88b 888 d88P
888 888 "Y88P" Y8P 888 "Y8888 "Y8888888P"
Dissasembler Engine Core
~~~~~~~~~~~~~~~~~~~~~~~~
Written by Bengaly (R) 2003-2005.
As a part of the Proview (a.k.a PVDasm).
Permission is granted to make and distribute verbatim copies of this
Program provided the copyright notice and this permission notice are
Preserved on all copies.
File: Dsasm_Functions.cpp (main)
Disassembler Core Version: 1.04b
*/
#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]);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -