⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dsasm_functions.cpp

📁 Pvdasm.v1.04b反汇编程序的源代码.供研究反汇编技术的朋友参考
💻 CPP
📖 第 1 页 / 共 2 页
字号:
   
/*
     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 + -