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

📄 dsasm_functions.cpp

📁 自己写的一个调试器模型的源码, 有单步功能和反汇编引擎.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    char menemonic[128]="",tempMeme[128]="",Addr[15]="",temp[128]="";
	char instr[50]="";
	

    // Get used Register
	// Get target register, example:
	// 1. add byte ptr [ecx], -> al <-
	// 2. add -> al <- ,byte ptr [ecx]
    REG=(BYTE)(*(*Opcode+pos+1)); 
	REG>>=3;
	REG&=0x07;

    //Displacement MOD (none|BYTE/WORD|DWORD)
	Extension=(BYTE)(*(*Opcode+pos+1))>>6;
	/*
	    There are 3 types of Displacement to RegMem
	    00 -> [00] 000 000 ; no byte extention ([RegMem])
	    40->  [01] 000 000 ; 1 byte extenton ([RegMem+XX])
	    80 -> [10] 000 000 ; 4 bytes extention ([RegMem+XXXXXXXX])
	*/

    //===================//
    // Bitwise OverRides //
    //===================//
	// Arpl, Bound, Test, Xchg menemonics are special cases! when alone.
	// so we need to set specific static bits for d/w
    // We specify Size of Data corresponding to each mnemonic.

	switch((BYTE)(*(*Opcode+pos)))
	{
      case 0x20:            { PrefixReg=0;                                        }     break; // Force Byte Size Regardless Operands.
      case 0x39: case 0x3B:                     strcpy(RSize,regSize[1]);               break; // DWORD
      case 0x63:            { Bit_d=0; Bit_w=1; strcpy(RSize,regSize[1]); }             break; // DWORD
	  case 0x62:            { RM=REG32; bound=1; Bit_d=1; Bit_w=0; strcpy(RSize,regSize[0]); }    break; // QWORD
      case 0x69:            { Bit_d=0; Bit_w=1; strcpy(RSize,regSize[1]);         }     break; // DWORD
      case 0x6B:            { Bit_d=0; Bit_w=1; strcpy(RSize,regSize[1]);         }     break; // DWORD
      case 0x84: case 0x86: { Bit_d=0; Bit_w=0; }                                       break; // BYTE
      case 0x85: case 0x87: { Bit_d=0; Bit_w=1; strcpy(RSize,regSize[1]); }             break; // DWORD
      case 0x80: case 0x82: case 0xC6: case 0xF6:{ Bit_d=0;Bit_w=0; strcpy(RSize,regSize[3]); } break; // BYTE
      case 0x81: case 0x83: case 0xC7: case 0xF7: case 0x89:{ Bit_d=0;Bit_w=1; strcpy(RSize,regSize[1]); } break;	
      case 0x8B: strcpy(RSize,regSize[1]);                                              break; // DWORD
      case 0x8C: case 0x8E: { strcpy(RSize,regSize[2]); }                               break; // WORD
      case 0x8D: case 0x8F: { Bit_d=1; Bit_w=1; strcpy(RSize,regSize[1]); }             break; // POP/LEA
      case 0xC0:            { Bit_d=1; Bit_w=0;}                                        break; // BYTE
      case 0xC1:            { Bit_d=1; Bit_w=1; strcpy(RSize,regSize[1]); }             break; // MIX
      case 0xC4: case 0xC5: { RM=REG32; Bit_d=1; Bit_w=0; strcpy(RSize,regSize[4]); }             break; // LES/LDS
      case 0xD0: case 0xD2: { Bit_d=0; Bit_w=0; strcpy(RSize,regSize[3]); }             break; // MIX
      case 0xD1: case 0xD3: { Bit_d=0; Bit_w=1; strcpy(RSize,regSize[1]); }             break; // MIXED
      case 0xD8:            { UsesFPU=1; Bit_d=0; Bit_w=1; strcpy(RSize,regSize[1]); }  break; // FPU
      case 0xD9:{ 
                  UsesFPU=1; Bit_d=0; Bit_w=0; 
                  switch(REG)
                  {
                    case 0: case 2: case 3:strcpy(RSize,regSize[1]); break; // DWORD (REAL4)
                    case 4: case 6: strcpy(RSize,regSize[6]);        break; // 28Bytes                                       
                    case 5: case 7: strcpy(RSize,regSize[2]);        break; // WORD (REAL2)
                  }
                  
                }
                break; // FPU

      case 0xDA: { UsesFPU=1; Bit_d=0; Bit_w=1; strcpy(RSize,regSize[1]); }                                         break; // FPU
      case 0xDB: { UsesFPU=1; Bit_d=0; Bit_w=0; if(REG<4) strcpy(RSize,regSize[1]); else strcpy(RSize,regSize[5]);} break; // FPU
      case 0xDC: { UsesFPU=1; Bit_d=0; Bit_w=0; strcpy(RSize,regSize[0]); }                                         break; // FPU
      case 0xDD: { 
                   UsesFPU=1; Bit_d=0; Bit_w=0;
                   switch(REG)
                   {
                      case 0: case 1: case 2: case 3: strcpy(RSize,regSize[0]); break; // QWORD
                      case 4: case 5: case 6: strcpy(RSize,regSize[7]);         break; // (108)Byte
                      case 7: strcpy(RSize,regSize[2]);                         break; // WORD
                   }
                 }
                 break; // FPU

      case 0xDE: { UsesFPU=1; Bit_d=0; Bit_w=0; strcpy(RSize,regSize[2]); }     break; // WORD
      case 0xDF: {
                   UsesFPU=1; Bit_d=0; Bit_w=0;
                   switch(REG)
                   {
                       case 0: case 1: case 2: case 3: strcpy(RSize,regSize[2]); break; // WORD
                       case 4: case 6: strcpy(RSize,regSize[5]);                 break; // TByte
                       case 5: case 7: strcpy(RSize,regSize[0]);                 break; // QWord
                   }
                 }
                 break;
      case 0xFE: { Bit_d=0; Bit_w=0; strcpy(RSize,regSize[3]); }                 break; // BYTE
      case 0xFF: { 
                   Bit_d=0; Bit_w=0; 
                   if(REG==3 || REG==5) // FAR JMP/CALL
                       strcpy(RSize,regSize[4]); // FWORD
                   else
                       strcpy(RSize,regSize[1]);
                 }
                 break; // DWORD

    }

	// check for bit register size : 16bit/32bit
	if(Bit_w==1)
	{
	   RM=REG32; // 32bit registers set       

	   //if(/*!bound/&& Op==0x62*/)// Special Case
		strcpy(RSize,regSize[1]); // dword ptr   
           
	}

	// check for prefix 0x66 OverRide (change default size)
	if(PrefixReg==1)
	{
        if(!UsesFPU) // FPU DataSize doesn't Change, others are, on prefix 0x66.
        { 
		   if(lstrcmp(RSize,"Byte")!=0) // doesn't affect byte mode
		   {
			   RM=REG16; // 16bit registers
			   strcpy(RSize,regSize[2]); // word ptr
			   if(Op==0x62 || Op==0xC4 || Op==0xC5) // Special Case, 66 Prefix doesn't affect Memory Size.
				   strcpy(RSize,regSize[1]);
		   }
        }
	}
	
    // SCALE INDEX BASE :
	SIB=(BYTE)(*(*Opcode+pos+1))&0x07; // Get SIB extension
	/*
	   Exmaple:
	   --------
       
       format of sib is:
       ss iii bbb.
       where ss is 2 upper bits for scale
       and they represent power (exponent) of 2 for
       scale index multipyer.
       iii is 3 middle bits for index.
       bbb is 3 low bits for base.

       *SIB == 4
	   *NO SIB != 4

       0x04 -> 00 000 [100] <- SIB
	   0x0C -> 00 001 [100] <- SIB
	   0x64 -> 01 100 [100] <- SIB
	   0x60 -> 01 100 [000] <- NO SIB
	   0xB5 -> 10 110 [101] <- NO SIB
	   0x76 -> 01 110 [110] <- NO SIB

       Extract SS II BB information (3rd byte)
       =======================================
       0x81,0xAC,0x20

       0x20 =  00 100 000
       
       Scale: 00 = *1 (not shown)
       100 - ESP = not Shown, Cannot be an Index register
       000 - EAX = shown

       if MOD 10/01 is being used, get displacement data after 
       the SIB.
	*/


    // ===================================================//
    //             AddrPrefix is being used!               //
    // ===================================================//

	if(PrefixAddr==1) // Prefix 0x67 is set, Change Segments/Addressing Modes to 16 bits
	{		
        FOpcode=((BYTE)(*(*Opcode+pos+1))&0x0F); // Get addressing Mode (8 types of mode)
		reg1=((BYTE)(*(*Opcode+pos+1))&0x38)>>3;

        // Check if we decode POP instruction, which had few valid instruction.
        if(Op==0x8F && reg1!=0)
            lstrcat((*Disasm)->Remarks,"Invalid Instruction");
        
        // Choose Mode + Segment
		switch(FOpcode)
		{
		  case 0x00: case 0x08: wsprintf(Addr,"%s",addr16[0]); /*SEG=SEG_DS;*/ break; // Mode 0:[BX+SI]
		  case 0x01: case 0x09: wsprintf(Addr,"%s",addr16[1]); /*SEG=SEG_DS;*/ break; // Mode 1:[BX+DI]
		  case 0x02: case 0x0A: wsprintf(Addr,"%s",addr16[2]); SEG=SEG_SS; break; // Mode 2:[BP+SI]
		  case 0x03: case 0x0B: wsprintf(Addr,"%s",addr16[3]); SEG=SEG_SS; break; // Mode 3:[BP+DI]
		  case 0x04: case 0x0C: wsprintf(Addr,"%s",addr16[4]); /*SEG=SEG_DS;*/ break; // Mode 4:[SI]
		  case 0x05: case 0x0D: wsprintf(Addr,"%s",addr16[5]); /*SEG=SEG_DS;*/ break; // Mode 5:[DI]
		  case 0x06: case 0x0E: // Mode 6: [BP+XX/XXXX] | [XX]
		  {
				  if(Extension==0) // 0x00-0x3F only! has special [XXXX]
				  {
					  /*SEG=SEG_DS;*/
                      SwapWord((BYTE*)(*Opcode+pos+2),&wOp,&wMem);
					  wsprintf(Addr,"%04X",wMem);
					  (*(*index))+=2; // read 2 bytes
				  }
				  else{ // 0x50-0xBF has [BP+]

					  SEG=SEG_SS; // SS Segment
					  wsprintf(Addr,"%s",addr16[7]);
				  }
		  }
		  break;
          
		  case 0x07: case 0x0F: wsprintf(Addr,"%s",addr16[6]); /*SEG=SEG_DS;*/ break; // Mode 7: [BX]
		}

		// Choose used extension 
		// And Decode properly the menemonic
		switch(Extension)
		{
			case 0: // No extension of bytes to RegMem (except mode 6)
			{
				wsprintf(tempMeme,"%s ptr %s:[%s]",RSize,segs[SEG],Addr);
				SwapDword((BYTE*)(*Opcode+pos),&dwOp,&dwMem);
				SwapWord((BYTE*)(*Opcode+pos),&wOp,&wMem);

                if(((wOp&0x00FF)&0x0F)==0x06) // 0x00-0x3F with mode 6 only!
				{	                    
					wsprintf(menemonic,"%08X",dwOp);
					(*Disasm)->OpcodeSize=4;
					lstrcat((*Disasm)->Opcode,menemonic);
				}
				else{ // other modes                    
					wsprintf(menemonic,"%04X",wOp);
					(*Disasm)->OpcodeSize=2;
					lstrcat((*Disasm)->Opcode,menemonic);
				}
			}
			break;

			case 1: // 1 Byte Extension to regMem
			{
                SwapWord((BYTE*)(*Opcode+pos+1),&wOp,&wMem);
				FOpcode=wOp&0x00FF;
				
				if(FOpcode>0x7F) // check for signed numbers
				{
					wsprintf(Aritmathic,"%s",Scale[0]); // '-' Signed Numbers
					FOpcode = 0x100-FOpcode; // -XX
				}
				wsprintf(menemonic,"%02X%04X",Op,wOp);
				lstrcat((*Disasm)->Opcode,menemonic);
				wsprintf(tempMeme,"%s ptr %s:[%s%s%02X]",RSize,segs[SEG],Addr,Aritmathic,FOpcode);
				++(*(*index)); // 1 byte read
				(*Disasm)->OpcodeSize=3;
			}
			break;
			
			case 2: // 2 Bytes Extension to RegMem
			{
                SwapDword((BYTE*)(*Opcode+pos),&dwOp,&dwMem);
                SwapWord((BYTE*)(*Opcode+pos+2),&wOp,&wMem);
				wsprintf(menemonic,"%08X",dwOp);
				(*Disasm)->OpcodeSize=4;
				lstrcat((*Disasm)->Opcode,menemonic);
				wsprintf(tempMeme,"%s ptr %s:[%s%s%04X]",RSize,segs[SEG],Addr,Aritmathic,wMem);
				(*(*index))+=2; // we read 2 bytes
			}
			break;
		}

		// Switch Direction Mode.
		// And Build Menemonic from that direction
		switch(Bit_d)
		{
			case 0: // (->)
			{
				// Check for More Menemonics Addons
				switch(Op)// Check for all Cases
				{
                    case 0x6B:
                    {
                        // We check Extension because there is a diff
						// Reading position of bytes depend on the extension
						// 1 = read byte, 3rd position
						// 2 = read dword, 6th position
						
						if(Extension==1) // read 1 byte at 3rd position
						{
                            SwapWord((BYTE*)(*Opcode+pos+2),&wOp,&wMem);
							FOpcode=wOp&0x00FF;
							wsprintf(temp,"%02X",FOpcode);
							lstrcat((*Disasm)->Opcode,temp);
						}
						else{ 
                            if(Extension==2) //read byte at 7th position (dword read before)
                            {   
                                SwapWord((BYTE*)(*Opcode+pos+3),&wOp,&wMem);
                                FOpcode=wOp&0x00FF;
                                wsprintf(temp,"%02X",FOpcode);
                                lstrcat((*Disasm)->Opcode,temp);
                            }
                            else
                            { // Extension==0
                                SwapWord((BYTE*)(*Opcode+pos+1),&wOp,&wMem);
                                FOpcode=wOp&0x00FF;
                                wsprintf(temp,"%02X",FOpcode);
                                lstrcat((*Disasm)->Opcode,temp);
                            }
						}
                        
						if(FOpcode>0x7F) // check for signed numbers!!
                        {
                            FOpcode = 0x100-FOpcode; // -XX (Signed)
                            wsprintf(Aritmathic,"%s",Scale[0]); // '-' aritmathic (Signed)                            
                        }
                        else                    
                            strcpy(Aritmathic,"");
						
					    strcpy(instruction,"imul");
						wsprintf(temp,"%s %s,%s,%s%02X",instruction,regs[RM][reg2],tempMeme,Aritmathic,FOpcode);

						(*(*index))++;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -