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

📄 disasm.cpp

📁 实现了屏幕截取
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	int i;
	if (mode<DISASM_DATA)
		return;

	index&=0x07;
	if (index>=6) 
		softerror=DAE_BADSEG;  // Undefined segment register

	sprintf_s(da->vm_name,"%s_%s",da->vm_name,segname[index]);
	da->optype[stoperand] = Seg;

	if (mode>=DISASM_FILE) 
	{
		da->segreg = index;
		i=sprintf(da->result+nresult,"%s",segname[index]);
		if (lowercase)
			strlwr(da->result+nresult);
		nresult+=i;
	}
}

// Decode control register addressed in R part of ModRM byte. Operands of
// this type are extremely rare. Contents of control registers are accessible
// only from privilege level 0, so I cannot dump them here.
static void DecodeCR(int index)
{
  hasrm=1;
  if (mode>=DISASM_FILE)
  {
    index=(index>>3) & 0x07;
    nresult+=sprintf(da->result+nresult,"%s",crname[index]);
    if (lowercase)
		strlwr(da->result+nresult);
  }
}

// Decode debug register addressed in R part of ModRM byte. Operands of
// this type are extremely rare. I can dump only those debug registers
// available in CONTEXT structure.
static void DecodeDR(int index) 
{
  int i;
  hasrm=1;
  if (mode>=DISASM_FILE) 
  {
    index=(index>>3) & 0x07;
    i=sprintf(da->result+nresult,"%s",drname[index]);
    if (lowercase)
		strlwr(da->result+nresult);
    nresult+=i;
  }
}

// Skips 3DNow! operands and extracts command suffix. Returns suffix or -1 if
// suffix lies outside the memory block. This subroutine assumes that cmd still
// points to the beginning of 3DNow! command (i.e. to the sequence of two bytes
// 0F, 0F).
static int Get3dnowsuffix(void)
{
  int c,sib;
  ulong offset;
  if (size<3) 
	  return -1;               // Suffix outside the memory block
  offset=3;
  c=cmd[2] & 0xC7;                     // Leave only Mod and M fields
  // Register in ModM - general-purpose, MMX or 3DNow!
  if ((c & 0xC0)==0xC0)
    ;
  // 16-bit addressing mode, SIB byte is never used here.
  else if (addrsize==2)
  {
    if (c==0x06)                       // Special case of immediate address
      offset+=2;
    else if ((c & 0xC0)==0x40)         // 8-bit signed displacement
      offset++;
    else if ((c & 0xC0)==0x80)         // 16-bit unsigned displacement
      offset+=2;
  }
  // Immediate 32-bit address.
  else if (c==0x05)                    // Special case of immediate address
    offset+=4;
  // 32-bit address with SIB byte.
  else if ((c & 0x07)==0x04)
  {         // SIB addresation
    if (size<4) 
		return -1;             // Suffix outside the memory block
    sib=cmd[3]; 
	offset++;
    if (c==0x04 && (sib & 0x07)==0x05)
      offset+=4;                       // Immediate address without base
    else if ((c & 0xC0)==0x40)         // 8-bit displacement
      offset+=1;
    else if ((c & 0xC0)==0x80)         // 32-bit dislacement
      offset+=4;
  }
  // 32-bit address without SIB byte
  else if ((c & 0xC0)==0x40)
    offset+=1;
  else if ((c & 0xC0)==0x80)
    offset+=4;
  if (offset>=size) 
	  return -1;         // Suffix outside the memory block
  return cmd[offset];
}

// Function checks whether 80x86 flags meet condition set in the command.
// Returns 1 if condition is met, 0 if not and -1 in case of error (which is
// not possible).
int Checkcondition(int code,ulong flags)
{
  ulong cond,temp;
  switch (code & 0x0E) 
  {
    case 0:                            // If overflow
      cond=flags & 0x0800;
	  break;
    case 2:                            // If below
      cond=flags & 0x0001;
	  break;
    case 4:                            // If equal
      cond=flags & 0x0040;
	  break;
    case 6:                            // If below or equal
      cond=flags & 0x0041; 
	  break;
    case 8:                            // If sign
      cond=flags & 0x0080; 
	  break;
    case 10:                           // If parity
      cond=flags & 0x0004;
	  break;
    case 12:                           // If less
      temp=flags & 0x0880;
      cond=(temp==0x0800 || temp==0x0080); 
	  break;
    case 14:                           // If less or equal
      temp=flags & 0x0880;
      cond=(temp==0x0800 || temp==0x0080 || (flags & 0x0040)!=0);
	  break;
    default:
		return -1;                // Internal error, not possible!
  }
  if ((code & 0x01)==0)
	  return (cond!=0);
  else
	  return (cond==0);               // Invert condition
}


//bughoho
int stoperand = 0;
ulong Disasm(char *src,ulong srcsize,ulong srcip,t_disasm *disasm,int disasmmode) 
{
  int i,j,isprefix,is3dnow,repeated,operand,mnemosize,arg = 0;
  ulong u,code;
  int lockprefix;                      // Non-zero if lock prefix present
  int repprefix;                       // REPxxx prefix or 0
  int cxsize;
  char name[TEXTLEN],*pname;
  const t_cmddata *pd,*pdan;
  // Prepare disassembler variables and initialize structure disasm.
  //初始化结构和变量
  datasize=addrsize=4;                 // 32-bit code and data segments only!
  segprefix=SEG_UNDEF;
  hasrm=hassib=0; dispsize=immsize=0;
  lockprefix=0; repprefix=0;
  ndump=0; nresult=0;
  cmd=src; size=srcsize; pfixup=NULL;
  softerror=0; is3dnow=0;
  da=disasm;
  da->ip=srcip;
  da->comment[0]='\0';
  da->cmdtype=C_BAD; da->nprefix=0;
  da->memtype=DEC_UNKNOWN; da->indexed=0;
  da->jmpconst=0; da->jmptable=0;
  da->adrconst=0; da->immconst=0;
  da->zeroconst=0;
  da->fixupoffset=0; da->fixupsize=0;
  da->warnings=0;
  da->error=DAE_NOERR;
  mode=disasmmode;                     // No need to use register contents

  da->optype[0] = da->optype[1] = da->optype[2] = -1;
  da->reg[0] = da->reg[1] = da->reg[2] = -1;
  da->segreg = -1;
  da->addrreg1 = da->addrreg2 = -1;
  da->regsscale = 1;
  memset(da->hexcode,0,TEXTLEN);
  da->codelen = 0;
  da->highbit[0] = da->highbit[1] = da->highbit[2] = false;
  // Correct 80x86 command may theoretically contain up to 4 prefixes belonging
  // to different prefix groups. This limits maximal possible size of the
  // command to MAXCMDSIZE=16 bytes. In order to maintain this limit, if
  // Disasm() detects second prefix from the same group, it flushes first
  // prefix in the sequence as a pseudocommand.
  u=0; repeated=0;
  while (size>0)
  {
	  isprefix=1;                        // Assume that there is some prefix
	  switch (*cmd)
	  {
	  case 0x26:
		  if (segprefix==SEG_UNDEF)
			  segprefix=SEG_ES;
		  else repeated=1;
		  break;
	  case 0x2E: 
		  if (segprefix==SEG_UNDEF)
			  segprefix=SEG_CS;
		  else repeated=1; 
		  break;
	  case 0x36:
		  if (segprefix==SEG_UNDEF)
			  segprefix=SEG_SS;
		  else repeated=1;
		  break;
	  case 0x3E: 
		  if (segprefix==SEG_UNDEF) 
			  segprefix=SEG_DS;
		  else repeated=1;
		  break;
	  case 0x64:
		  if (segprefix==SEG_UNDEF) 
			  segprefix=SEG_FS;
		  else repeated=1; 
		  break;
	  case 0x65: 
		  if (segprefix==SEG_UNDEF)
			  segprefix=SEG_GS;
		  else repeated=1;
		  break;
	  case 0x66:
		  if (datasize==4) 
			  datasize=2;
		  else repeated=1; 
		  break;
	  case 0x67: 
		  if (addrsize==4) 
			  addrsize=2;
		  else repeated=1;
		  break;
	  case 0xF0: 
		  if (lockprefix==0)
			  lockprefix=0xF0;
		  else repeated=1; 
		  break;
	  case 0xF2:
		  if (repprefix==0) 
			  repprefix=0xF2;
		  else repeated=1;
		  break;
	  case 0xF3: 
		  if (repprefix==0) 
			  repprefix=0xF3;
		  else repeated=1;
		  break;
	  default: 
		  isprefix=0;
		  break;
	  }
	  if (isprefix==0 || repeated!=0)
		  break;                           // No more prefixes or duplicated prefix
	  if (mode>=DISASM_FILE)
	  {
		  ndump+=sprintf(da->dump+ndump,"%02X:",*cmd);
		  da->hexcode[da->codelen++] = *cmd;
	  }
	  da->nprefix++;
	  cmd++; srcip++; size--; u++; 
  }
  //bughoho
  da->segment = segprefix;//得到段寄存器
  // We do have repeated prefix. Flush first prefix from the sequence.
  if (repeated)
  {
	  if (mode>=DISASM_FILE) 
	  {
		  da->dump[3]='\0';                // Leave only first dumped prefix
		  da->nprefix=1;
		  switch (cmd[-(long)u])//cmd++ 且 u++;这里是得到cmd[0]
		  {
		  case 0x26: pname=(char *)(segname[SEG_ES]); 
			  break;
		  case 0x2E: pname=(char *)(segname[SEG_CS]);
			  break;
		  case 0x36: pname=(char *)(segname[SEG_SS]);
			  break;
		  case 0x3E: pname=(char *)(segname[SEG_DS]);
			  break;
		  case 0x64: pname=(char *)(segname[SEG_FS]);
			  break;
		  case 0x65: pname=(char *)(segname[SEG_GS]); 
			  break;
		  case 0x66: pname="DATASIZE";
			  break;
		  case 0x67: pname="ADDRSIZE";
			  break;
		  case 0xF0: pname="LOCK";
			  break;
		  case 0xF2: pname="REPNE";
			  break;
		  case 0xF3: pname="REPE";
			  break;
		  default: pname="?";
			  break; 
		  }
		  nresult+=sprintf(da->result+nresult,"PREFIX %s:",pname);
		  if (lowercase)
			  strlwr(da->result);
		  if (extraprefix==0) 
			  strcpy(da->comment,"Superfluous prefix");
	  }
	  da->warnings |= DAW_PREFIX;
	  if (lockprefix)
		  da->warnings |= DAW_LOCK;
	  da->cmdtype=C_RARE;
	  return 1;                          // Any prefix is 1 byte long
  }
  // If lock prefix available, display it and forget, because it has no
  // influence on decoding of rest of the command.
  if (lockprefix!=0) 
  {
	  if (mode>=DISASM_FILE) 
		  nresult+=sprintf(da->result+nresult,"LOCK ");
	  da->warnings |= DAW_LOCK;
  }
  // Fetch (if available) first 3 bytes of the command, add repeat prefix and
  // find command in the command table.
  //取得命令的头三个字节
  code=0;
  if (size>0) 
	  *(((char *)&code)+0)=cmd[0];
  if (size>1)
	  *(((char *)&code)+1)=cmd[1];
  if (size>2) 
	  *(((char *)&code)+2)=cmd[2];
  if (repprefix!=0)                    // RER/REPE/REPNE is considered to be
	  code=(code<<8) | repprefix;        // part of command.
  if (decodevxd && (code & 0xFFFF)==0x20CD)
	  pd=&vxdcmd;                        // Decode VxD call (Win95/98)
  else
  {
	  for (pd=cmddata; pd->mask!=0; pd++) //从指令表中搜索
	  {
		  if (((code^pd->code) & pd->mask)!=0)
			  continue;
		  if (mode>=DISASM_FILE && shortstringcmds &&								//如果是反汇编模式,并且Use short form of string commands
			  (pd->arg1==MSO || pd->arg1==MDE || pd->arg2==MSO || pd->arg2==MDE))     //如果寄存器是ESI或EDI
			  continue;                      // Search short form of string command
		  break;
	  }
  }
  if ( (pd->type & C_TYPEMASK) == C_NOW) //如果是3DNow指令
  {
	  // 3DNow! commands require additional search.
	  is3dnow=1;
	  j=Get3dnowsuffix();
	  if (j<0)
		  da->error=DAE_CROSS;
	  else 
	  {
		  for( ; pd->mask!=0; pd++)
		  {
			  if (((code^pd->code) & pd->mask)!=0)
				  continue;
			  if (((uchar *)&(pd->code))[2]==j) 
				  break;
		  }
	  }
  }

  //bughoho 
  da->is3dnow = is3dnow;//是否是3DNow!指令

  if (pd->mask==0)    //命令未找到
  {                   // Command not found
	  da->cmdtype=C_BAD;
	  if (size<2) 
		  da->error=DAE_CROSS;
	  else 
		  da->error=DAE_BADCMD; 
  }
  else//命令经过认证
  {                               // Command recognized, decode it
	  da->cmdtype=pd->type;//命令类型(附加信息)
	  cxsize=datasize;                 // Default size of ECX used as counter //ECX记数器的默认长度
	  if (segprefix==SEG_FS || segprefix==SEG_GS || lockprefix!=0)
		  da->cmdtype|=C_RARE;             // These prefixes are rare //出现很少的命令
	  if (pd->bits==PR)//特权指令
		  da->warnings|=DAW_PRIV;          // Privileged command (ring 0)
	  else if (pd->bits==WP)//IO命令
		  da->warnings|=DAW_IO;            // I/O command
	  // Win32 programs usually try to keep stack dword-aligned, so INC ESP
	  // (44) and DEC ESP (4C) usually don't appear in real code. Also check for
	  // ADD ESP,imm and SUB ESP,imm (81,C4,imm32; 83,C4,imm8; 81,EC,imm32;
	  // 83,EC,imm8).
	  //WIN32程序通常会保持栈的四字节对齐,所以inc esp,dec esp一般不会出现在平常的代码中,
	  //同样检测add esp,imm 和 sub esp,imm.
	  if (	cmd[0]==0x44 || cmd[0]==0x4C ||
		  (size>=3 && (cmd[0]==0x81 || cmd[0]==0x83) &&
		  (cmd[1]==0xC4 || cmd[1]==0xEC) && (cmd[2] & 0x03)!=0) )
	  {
		  da->warnings|=DAW_STACK;//栈警告
		  da->cmdtype|=C_RARE;	  //不常出现的指令
	  }
	  // Warn also on MOV SEG,... (8E...). Win32 works in flat mode.
	  //警告 mov seg,xxx 操作,因为Win32工作在平坦模式
	  if (cmd[0]==0x8E)
		  da->warnings|=DAW_SEGMENT;
	  // If opcode is 2-byte, adjust command.
	  //如果操作码是2字节的则调整命令
	  if (pd->len==2) 
	  {
		  if (size==0)
			  da->error=DAE_CROSS;
		  else 
		  {
			  if (mode>=DISASM_FILE)
			  {
				  ndump+=sprintf(da->dump+ndump,"%02X",*cmd);
				  da->hexcode[da->codelen++] = *cmd;
			  }
			  cmd++; 
			  srcip++;
			  size--;
		  }
	  }
	  if (size==0) 
		  da->error=DAE_CROSS;
	  // Some commands either feature non-standard data size or have bit which
	  // allowes to select data size.
	  //一些命令的数据长度不是标准的,可以改变长度大小
	  if ((pd->bits & WW)!=0 && (*cmd & WW)==0)
		  datasize=1;                      // Bit W in command set to 0
	  else if ((pd->bits & W3)!=0 && (*cmd & W3)==0)
		  datasize=1;                      // Another position of bit W
	  else if ((pd->bits & FF)!=0)
		  datasize=2;                      // Forced word (2-byte) size
	  // Some commands either have mnemonics which depend on data size (8/16 bits
	  // or 32 bits, like CWD/CDQ), or have several different mnemonics (like
	  // JNZ/JNE). First case is marked by either '&' (mnemonic depends on
	  // operand size) or '$' (depends on address size). In the second case,
	  // there is no special marker and disassembler selects main mnemonic.
	  if (mode>=DISASM_FILE) 
	  {
		  if (pd->name[0]=='&')
			  mnemosize=datasize;
		  else if (pd->name[0]=='$')
			  mnemosize=addrsize;
		  else mnemosize=0;
		  if (mnemosize!=0)
		  {
			  for (i=0,j=1; pd->name[j]!='\0'; j++) 
			  {

⌨️ 快捷键说明

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