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

📄 disasm.cpp

📁 实现了屏幕截取
💻 CPP
📖 第 1 页 / 共 4 页
字号:
			if (pfixup==NULL) 
				pfixup=cmd+2;
			da->fixupsize+=4;
			if (addr==0)
				da->zeroconst=1;
			seg=SEG_DS;
			Memadr(seg,"",addr,dsize);
		}
	}
	// Next possibility: 32-bit address with SIB byte.
	else if ((c & 0x07)==0x04) 
	{         // SIB addresation
		sib=cmd[2]; hassib=1;
		*s='\0';
		if (c==0x04 && (sib & 0x07)==0x05)
		{
			dispsize=4;                      // Immediate address without base
			if (size<7)
				da->error=DAE_CROSS;           // Disp32 outside the memory block
			else 
			{
				da->adrconst=addr=*(ulong *)(cmd+3);
				if (pfixup==NULL) 
					pfixup=cmd+3;
				da->fixupsize+=4;
				if (addr==0) 
					da->zeroconst=1;
				if ((sib & 0x38)!=0x20) 
				{      // Index register present
					da->indexed=1;
					if (type==MRJ)
						da->jmptable=addr; };
					seg=SEG_DS;
			}
		}
		else
		{                             // Base and, eventually, displacement
			if ((c & 0xC0)==0x40)
			{          // 8-bit displacement
				dispsize=1;
				if (size<4) 
					da->error=DAE_CROSS;
				else
				{
					da->adrconst=addr=(signed char)cmd[3];
					if (addr==0) da->zeroconst=1;
				}
			}
			else if ((c & 0xC0)==0x80) 
			{     // 32-bit displacement
				dispsize=4;
				if (size<7)
					da->error=DAE_CROSS;         // Disp32 outside the memory block
				else
				{
					da->adrconst=addr=*(ulong *)(cmd+3);
					if (pfixup==NULL)
						pfixup=cmd+3;
					da->fixupsize+=4;
					if (addr==0)
						da->zeroconst=1;
					// Most compilers use address of type [index*4+displacement] to
					// address jump table (switch). But, for completeness, I allow all
					// cases which include index with scale 1 or 4, base or both.
					if (type==MRJ)
						da->jmptable=addr;
				}
			}
			da->indexed=1;
			j=sib & 0x07;
			if (mode>=DISASM_FILE)
			{
				strcpy(s,regname[2][j]);
				seg=addr32[j].defseg;

				da->addrreg1 = j;//
			}
		}
		if ((sib & 0x38)!=0x20) 
		{          // Scaled index present
			if ((sib & 0xC0)==0x40) 
				da->indexed=2;
			else if ((sib & 0xC0)==0x80)
				da->indexed=4;
			else if ((sib & 0xC0)==0xC0)
				da->indexed=8;
			else
				da->indexed=1;
		};
		if (mode>=DISASM_FILE && da->error==DAE_NOERR) 
		{
			if ((sib & 0x38)!=0x20)
			{        // Scaled index present
				if (*s!='\0') 
					strcat(s,"+");
				strcat(s,addr32[(sib>>3) & 0x07].descr);
				da->regsscale = 1;
				da->addrreg2 = (sib>>3) & 0x07;//第2个寄存器偏移
				if ((sib & 0xC0)==0x40) 
				{
					da->jmptable=0;              // Hardly a switch!
					strcat(s,"*2");
					da->regsscale = 2;
				}
				else if ((sib & 0xC0)==0x80)
				{
					strcat(s,"*4");
					da->regsscale = 4;
				}
				else if ((sib & 0xC0)==0xC0) 
				{
					da->jmptable=0;              // Hardly a switch!
					strcat(s,"*8");
					da->regsscale = 8;
				}
			}
			Memadr(seg,s,addr,dsize);
		};
	}
	// Last possibility: 32-bit address without SIB byte.
	// 最后一个可能: 32位地址
	else
	{                               // No SIB
		if ((c & 0xC0)==0x40)
		{
			dispsize=1;
			if (size<3)
				da->error=DAE_CROSS; // Disp8 outside the memory block
			else 
			{
				da->adrconst=addr=(signed char)cmd[2];
				if (addr==0) 
					da->zeroconst=1;
			}
		}
		else if ((c & 0xC0)==0x80)
		{
			dispsize=4;
			if (size<6)
				da->error=DAE_CROSS;           // Disp32 outside the memory block
			else 
			{
				da->adrconst=addr=*(ulong *)(cmd+2);
				if (pfixup==NULL) 
					pfixup=cmd+2;
				da->fixupsize+=4;
				if (addr==0) 
					da->zeroconst=1;
				if (type==MRJ) 
					da->jmptable=addr;
			}
		}
		da->indexed=1;
		if (mode>=DISASM_FILE && da->error==DAE_NOERR) 
		{
			seg=addr32[c & 0x07].defseg;
			da->addrreg1 = (c & 0x07);
			Memadr(seg,addr32[c & 0x07].descr,addr,dsize);
		}
	}
}

// Disassemble implicit source of string operations and, if available, dump
// address and contents.
//static void DecodeSO(void)
static int DecodeSO(void)
{
	if (mode<DISASM_FILE)
		return -1;        // No need to decode
	if (datasize==1) 
		da->memtype=DEC_BYTE;
	else if (datasize==2)
		da->memtype=DEC_WORD;
	else if (datasize==4)
		da->memtype=DEC_DWORD;
	da->indexed=1;
	Memadr(SEG_DS,regname[addrsize==2?1:2][REG_ESI],0L,datasize);

	da->reg[stoperand] = REG_ESI;
	return REG_ESI;
}

// Disassemble implicit destination of string operations and, if available,
// dump address and contents. Destination always uses segment ES, and this
// setting cannot be overridden.
//static void DecodeDE(void) 
static int DecodeDE(void) 
{
	int seg;
	if (mode<DISASM_FILE) 
		return -1;        // No need to decode
	if (datasize==1)
		da->memtype=DEC_BYTE;
	else if (datasize==2)
		da->memtype=DEC_WORD;
	else if (datasize==4)
		da->memtype=DEC_DWORD;
	da->indexed=1;
	seg = segprefix; 
	segprefix=SEG_ES;     // Fake Memadr by changing segment prefix
	Memadr(SEG_DS,regname[addrsize==2?1:2][REG_EDI],0L,datasize);
	segprefix=seg;                       // Restore segment prefix

	da->reg[stoperand] = REG_EDI;
	return REG_EDI;
};

// Decode XLAT operand and, if available, dump address and contents.
static void DecodeXL(void)
{
  if (mode<DISASM_FILE)
	  return;        // No need to decode
  da->memtype=DEC_BYTE;
  da->indexed=1;
  Memadr(SEG_DS,(addrsize==2?"BX+AL":"EBX+AL"),0L,1);
};

// Decode immediate operand of size constsize. If sxt is non-zero, byte operand
// should be sign-extended to sxt bytes. If type of immediate constant assumes
// this, small negative operands may be displayed as signed negative numbers.
// Note that in most cases immediate operands are not shown in comment window.
static void DecodeIM(int constsize,int sxt,int type) 
{
  int i;
  signed long data;
  ulong l;
  char name[TEXTLEN],comment[TEXTLEN] = {0};
  immsize+=constsize;                    // Allows several immediate operands
  if (mode<DISASM_DATA)
	  return;

  //sprintf_s(da->vm_name,"%s_IMM%02d",da->vm_name,constsize*8);
  sprintf_s(da->vm_name,"%s_IMM32",da->vm_name);//IMM只有32位
  da->optype[stoperand] = Imm;

  l=1+hasrm+hassib+dispsize+(immsize-constsize);
  data=0;
  if (size<l+constsize)
    da->error=DAE_CROSS;
  else if (constsize==1) 
  {
    if (sxt==0) 
		data=(uchar)cmd[l];
    else 
		data=(signed char)cmd[l];
    if (type==IMS && ((data & 0xE0)!=0 || data==0)) 
	{
      da->warnings|=DAW_SHIFT;
      da->cmdtype|=C_RARE;
    }
  }
  else if (constsize==2) 
  {
    if (sxt==0) 
		data=*(ushort *)(cmd+l);
    else 
		data=*(short *)(cmd+l);
  }
  else 
  {
    data=*(long *)(cmd+l);
    if (pfixup==NULL)
		pfixup=cmd+l;
    da->fixupsize+=4;
  }
  if (sxt==2)
	  data&=0x0000FFFF;
  if (data==0 && da->error==0)
	  da->zeroconst=1;
  // Command ENTER, as an exception from Intel's rules, has two immediate
  // constants. As the second constant is rarely used, I exclude it from
  // search if the first constant is non-zero (which is usually the case).
  if (da->immconst==0)
    da->immconst=data;
  if (mode>=DISASM_FILE && da->error==DAE_NOERR) 
  {
    if (mode>=DISASM_CODE && type!=IMU)
      i=Decodeaddress(data,name,TEXTLEN-nresult-24,comment);
    else 
	{
      i=0; comment[0]='\0'; 
	}
    if (i!=0 && symbolic!=0)
	{
      strcpy(da->result+nresult,name); nresult+=i;
	}
    else if (type==IMU || type==IMS || type==IM2 || data>=0 || data<NEGLIMIT)
      nresult+=sprintf(da->result+nresult,"%lX",data);
    else
      nresult+=sprintf(da->result+nresult,"-%lX",-data);
    if (addcomment && comment[0]!='\0')
		strcpy(da->comment,comment);
  }
}

// Decode VxD service name (always 4-byte).
static void DecodeVX(void) 
{
  ulong l,data;
  immsize+=4;                          // Allows several immediate operands
  if (mode<DISASM_DATA) 
	  return;
  l=1+hasrm+hassib+dispsize+(immsize-4);
  if (size<l+4) 
  {
    da->error=DAE_CROSS;
    return;
  }
  data=*(long *)(cmd+l);
  if (data==0 && da->error==0)
	  da->zeroconst=1;
  if (da->immconst==0)
    da->immconst=data;
  if (mode>=DISASM_FILE && da->error==DAE_NOERR)
  {
    if ((data & 0x00008000)!=0 && memicmp("VxDCall",da->result,7)==0)
      memcpy(da->result,lowercase?"vxdjump":"VxDJump",7);
    nresult+=sprintf(da->result+nresult,"%lX",data);
  }
}

// Decode implicit constant 1 (used in shift commands). This operand is so
// insignificant that it is never shown in comment window.
static void DecodeC1(void)
{
  if (mode<DISASM_DATA)
	  return;
  da->immconst=1;
  if (mode>=DISASM_FILE) 
	  nresult+=sprintf(da->result+nresult,"1");
}

// Decode immediate absolute data address. This operand is used in 8080-
// compatible commands which allow to move data from memory to accumulator and
// back. Note that bytes ModRM and SIB never appear in commands with IA operand.
static void DecodeIA(void) 
{
  ulong addr;
  if (size<1+addrsize) 
  {
    da->error=DAE_CROSS; 
	return; 
  };
  dispsize=addrsize;
  if (mode<DISASM_DATA) 
	  return;
  if (datasize==1) 
	  da->memtype=DEC_BYTE;
  else if (datasize==2)
	  da->memtype=DEC_WORD;
  else if (datasize==4)
	  da->memtype=DEC_DWORD;
  if (addrsize==2)
    addr=*(ushort *)(cmd+1);
  else
  {
    addr=*(ulong *)(cmd+1);
    if (pfixup==NULL) 
		pfixup=cmd+1;
    da->fixupsize+=4; 
  }
  da->adrconst=addr;
  if (addr==0)
	  da->zeroconst=1;
  if (mode>=DISASM_FILE)
  {
    Memadr(SEG_DS,"",addr,datasize);
  }
}

// Decodes jump relative to nextip of size offsize.
static void DecodeRJ(ulong offsize,ulong nextip)
{
	sprintf_s(da->vm_name,"%s_IMM%02d",da->vm_name,4*8);//不管长跳短跳都认为是32位地址
	da->optype[stoperand] = Imm;
	int i;
	ulong addr;
	char s[TEXTLEN];
	if (size<offsize+1) 
	{
		da->error=DAE_CROSS; 
		return; 
	}
	dispsize=offsize;                    // Interpret offset as displacement
	if (mode<DISASM_DATA)
		return;
	if (offsize==1)//短跳转
	{
		addr=(signed char)cmd[1]+nextip;
	}
	else if (offsize==2)
		addr=*(signed short *)(cmd+1)+nextip;
	else
		addr=*(ulong *)(cmd+1)+nextip;
	if (datasize==2)
		addr&=0xFFFF;
	da->jmpconst=addr;
	if (addr==0) 
		da->zeroconst=1;
	if (mode>=DISASM_FILE)
	{
		if (offsize==1) 
			nresult+=sprintf(da->result+nresult, "%s ",(lowercase==0?"SHORT":"short"));
		if (mode>=DISASM_CODE)
			i=Decodeaddress(addr,s,TEXTLEN,da->comment);
		else
			i=0;
		if (symbolic==0 || i==0)
			nresult+=sprintf(da->result+nresult,"%08lX",addr);
		else
			nresult+=sprintf(da->result+nresult,"%.*s",TEXTLEN-nresult-25,s);
		if (symbolic==0 && i!=0 && da->comment[0]=='\0')
			strcpy(da->comment,s);
	}
}

// Decode immediate absolute far jump address. In flat model, such addresses
// are not used (mostly because selector is specified directly in the command),
// so I neither decode as symbol nor comment it. To allow search for selector
// by value, I interprete it as an immediate constant.
static void DecodeJF(void)
{
	ulong addr,seg;
	if (size<1+addrsize+2)
	{
		da->error=DAE_CROSS;
		return;
	}
	dispsize=addrsize; immsize=2;        // Non-trivial but allowed interpretation
	if (mode<DISASM_DATA)
		return;
	if (addrsize==2) 
	{
		addr=*(ushort *)(cmd+1);
		seg=*(ushort *)(cmd+3);
	}
	else
	{
		addr=*(ulong *)(cmd+1);
		seg=*(ushort *)(cmd+5);
	}
	da->jmpconst=addr;
	da->immconst=seg;
	if (addr==0 || seg==0)
		da->zeroconst=1;
	if (mode>=DISASM_FILE)
	{
		nresult+=sprintf(da->result+nresult,"%s %04X:%08X",(lowercase==0?"FAR":"far"),seg,addr);
	}
}

// Decode segment register. In flat model, operands of this type are seldom.
static void DecodeSG(int index) 
{

⌨️ 快捷键说明

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