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

📄 disasm.cpp

📁 十分经典的开源反编译工具
💻 CPP
📖 第 1 页 / 共 5 页
字号:
  cbyte=ibuff[0];
  if(tabtype==TABLE_EXT)
    cbyte=ibuff[1];
  if(tabtype==TABLE_EXT2)
    cbyte=ibuff[2];
  if((tabtype==TABLE_EXT2)&&(options.processor==PROC_Z80))
    cbyte=ibuff[3];
  while(itable[tablenum].table!=NULL)  // search tables
  { righttable=true;
	 if((itable[tablenum].type!=tabtype)||(itable[tablenum].minlim>cbyte)||
		(itable[tablenum].maxlim<cbyte)) righttable=false;
	 if(((tabtype==TABLE_EXT)||(tabtype==TABLE_EXT2))&&(ibuff[0]!=itable[tablenum].extnum))
		righttable=false;
	 if((tabtype==TABLE_EXT2)&&(ibuff[1]!=itable[tablenum].extnum2))
		righttable=false;
	 if(righttable)
	 { insttab=itable[tablenum].table;      // need to search this now
		instnum=0;
		mbyte=cbyte;
		fupbyte=false;
		if(itable[tablenum].divisor)
        mbyte=(byte)(mbyte/itable[tablenum].divisor);
		if(itable[tablenum].mask)
        mbyte=mbyte&itable[tablenum].mask;
		else      // follow up byte encodings (KNI,AMD3DNOW)
		{ fupbyte=true;
		  flgs=insttab[instnum].flags;
		  a1=insttab[instnum].arg1;
		  a2=insttab[instnum].arg2;
		  a3=insttab[instnum].arg3;
#ifdef __BORLANDC__
#pragma warn -sig
#endif
		  length=1+arglength(a1,mcode[1+itable[tablenum].modrmpos],mcode[2+itable[tablenum].modrmpos],flgs,true)
					+arglength(a2,mcode[1+itable[tablenum].modrmpos],mcode[2+itable[tablenum].modrmpos],flgs,true)
					+arglength(a3,mcode[1+itable[tablenum].modrmpos],mcode[2+itable[tablenum].modrmpos],flgs,true)
					+itable[tablenum].modrmpos;
#ifdef __BORLANDC__
#pragma warn +sig
#endif
		  // addition for table extensions where inst is part of modrm byte
		  if(((tabtype==TABLE_EXT)||(tabtype==TABLE_EXT2))&&(length==1))
          length++;
		  mbyte=ibuff[length];
		}
		while((insttab[instnum].name!=NULL)||(insttab[instnum].instbyte)||(insttab[instnum].processor))
		{ if((omode32)&&(insttab[instnum].flags&FLAGS_OMODE16));
		  else if((!omode32)&&(insttab[instnum].flags&FLAGS_OMODE32));
		  else if((insttab[instnum].instbyte==mbyte)&&(insttab[instnum].processor&options.processor))
		  { // found it
			 if(insttab[instnum].name==NULL)
			 { if(tabtype==TABLE_MAIN)
              return decodeinst(ibuff,mcode,loc,TABLE_EXT,omode32,5);
				else
              return decodeinst(ibuff,mcode,loc,TABLE_EXT2,omode32,5);
			 }
			 else
			 { // interpret flags,etc
				flgs=insttab[instnum].flags;
				if((flgs&FLAGS_OPERPREFIX)&&(depth<5))
				{ newdsm=decodeinst(ibuff+1,mcode+1,loc+1,tabtype,!omode32,depth+1);
				  if(newdsm==NULL)
                return NULL;
				  newdsm->addr.offs--;
				  newdsm->length++;
				  newdsm->modrm++;
				  newdsm->data--;
				  return newdsm;
				}
				if((flgs&FLAGS_ADDRPREFIX)&&(depth<5))
				{ options.mode32=!options.mode32;
				  options.mode16=!options.mode16;
				  newdsm=decodeinst(ibuff+1,mcode+1,loc+1,tabtype,omode32,depth+1);
				  options.mode32=!options.mode32;
				  options.mode16=!options.mode16;
				  if(newdsm==NULL)
                return NULL;
				  newdsm->addr.offs--;
				  newdsm->length++;
				  newdsm->modrm++;
				  newdsm->data--;
				  newdsm->flags=newdsm->flags|FLAGS_ADDRPREFIX;
				  return newdsm;
				}
				if((flgs&FLAGS_SEGPREFIX)&&(depth<5))
				{ newdsm=decodeinst(ibuff+1,mcode+1,loc+1,tabtype,omode32,depth+1);
				  if(newdsm==NULL)
                return NULL;
				  newdsm->addr.offs--;
				  newdsm->length++;
				  newdsm->modrm++;
				  newdsm->data--;
				  newdsm->flags=newdsm->flags|FLAGS_SEGPREFIX;
				  return newdsm;
				}
				if((flgs&FLAGS_PREFIX)&&(depth<5))
				{ newdsm=decodeinst(ibuff+1,mcode+1,loc+1,tabtype,omode32,depth+1);
				  if(newdsm==NULL)
                return NULL;
				  newdsm->addr.offs--;
				  newdsm->length++;
				  newdsm->modrm++;
				  newdsm->data--;
				  newdsm->flags=newdsm->flags|FLAGS_PREFIX;
				  return newdsm;
				}
				newdsm=new dsmitem;
            initnewdsm(newdsm,loc,dsmcode);
				newdsm->tptr=(void *)&insttab[instnum];
				newdsm->modrm=(byte)(1+itable[tablenum].modrmpos);
				newdsm->data=mcode;
				newdsm->mode32=omode32;
				if(flgs&FLAGS_16BIT)
              newdsm->mode32=false;
				if(flgs&FLAGS_32BIT)
              newdsm->mode32=true;
				newdsm->flags=flgs;
				a1=insttab[instnum].arg1;
				a2=insttab[instnum].arg2;
				a3=insttab[instnum].arg3;
#ifdef __BORLANDC__
#pragma warn -sig
#endif
				length=1+arglength(a1,mcode[1+itable[tablenum].modrmpos],mcode[2+itable[tablenum].modrmpos],flgs,newdsm->mode32)
					+arglength(a2,mcode[1+itable[tablenum].modrmpos],mcode[2+itable[tablenum].modrmpos],flgs,newdsm->mode32)
					+arglength(a3,mcode[1+itable[tablenum].modrmpos],mcode[2+itable[tablenum].modrmpos],flgs,newdsm->mode32)
					+itable[tablenum].modrmpos;
#ifdef __BORLANDC__
#pragma warn +sig
#endif
				// addition for table extensions where inst is part of modrm byte
				if(((tabtype==TABLE_EXT)||(tabtype==TABLE_EXT2))&&((length==1)||(options.processor==PROC_Z80)))
				  length++;
				if(options.processor==PROC_Z80)
				{ if(tabtype==TABLE_EXT2)
                length++;
				  if(flgs&FLAGS_INDEXREG)
                length++;
				}
				if(fupbyte)
              length++;
				newdsm->length=length;
				if(!checkvalid(newdsm))
				{ delete newdsm;
				  return NULL;
				}
				if(flgs&(FLAGS_JMP|FLAGS_CALL|FLAGS_CJMP))
				{ switch(a1)
				  { case ARG_RELIMM:
						j=loc;
						dta=mcode+length;
						if(options.mode32)
						{ dta-=4;
						  j+=((dword *)dta)[0]+length;
						}
						else
						{ dta-=2;
						  j+=(word)(((word *)dta)[0]+length);
						}
						scheduler.addtask(dis_code,priority_definitecode,j,NULL);
						xrefs.addxref(j,newdsm->addr);
						break;
					 case ARG_RELIMM8:
						j=loc;
						dta=mcode+length-1;
						if(options.mode32)
						{ if(dta[0]&0x80)
							 j+=(dword)(dta[0]+0xffffff00+length);
						  else
							 j+=(dword)(dta[0]+length);
						}
						else
						{ if(dta[0]&0x80)
							 j+=(word)(dta[0]+0xff00+length);
						  else
							 j+=(word)(dta[0]+length);
						}
						scheduler.addtask(dis_code,priority_definitecode,j,NULL);
						xrefs.addxref(j,newdsm->addr);
						break;
					 case ARG_FADDR:
						dta=mcode+length;
						if(options.mode32)
						{ dta-=6;
						  j.assign(((word *)(&dta[4]))[0],((dword *)(&dta[0]))[0]);
						}
						else
						{ dta-=4;
						  j.assign(((word *)(&dta[2]))[0],((word *)(&dta[0]))[0]);
						}
						scheduler.addtask(dis_code,priority_definitecode,j,NULL);
						xrefs.addxref(j,newdsm->addr);
						break;
					 case ARG_MODRM:
					 case ARG_MODRM_FPTR:
						if(options.mode32)
						{ if((newdsm->data[0]==0xff)&&(newdsm->data[1]==0x25)&&(tabtype==TABLE_EXT))
						  { j.assign(loc.segm,((dword *)(&newdsm->data[2]))[0]);
							 if(import.isname(j))
							 { imp=import.nextiterator();
								impname[0]='_';
								impname[GNAME_MAXLEN]=0;
								lstrcpyn(&impname[1],imp->name,GNAME_MAXLEN-2);
								//if(!name.isname(segm,offs))
								scheduler.addtask(namecurloc,priority_nameloc,loc,impname);
							 }
						  }
						}
						scheduler.addtask(dis_jumptable,priority_definitecode,loc,NULL);
						break;
					 default:
						break;
				  }
				}
				switch(a1)
				{ case ARG_IMM32:
					 if(reloc.isreloc(loc+length-4))
					 {	newdsm->override=over_dsoffset;
						dta=mcode+length-4;
						j.assign(options.dseg,((dword *)(&dta[0]))[0]);
						xrefs.addxref(j,newdsm->addr);
					 }
					 break;
				  case ARG_IMM:
					 if(options.mode32)
					 { if(reloc.isreloc(loc+length-4))
						{ newdsm->override=over_dsoffset;
						  dta=mcode+length-4;
						  j.assign(options.dseg,((dword *)(&dta[0]))[0]);
						  xrefs.addxref(j,newdsm->addr);
						}
					 }
					 break;
              case ARG_MEMLOC:
                if(options.mode32)
                { newdsm->override=over_dsoffset;
						dta=mcode+length-4;
						j.assign(options.dseg,((dword *)(&dta[0]))[0]);
                  xrefs.addxref(j,newdsm->addr);
                }
                break;
	 			  case ARG_MMXMODRM:
	 			  case ARG_XMMMODRM:
	 			  case ARG_MODRM_S:
	 			  case ARG_MODRMM512:
	 			  case ARG_MODRMQ:
	 			  case ARG_MODRM_SREAL:
	 			  case ARG_MODRM_PTR:
	 			  case ARG_MODRM_WORD:
	 			  case ARG_MODRM_SINT:
	 			  case ARG_MODRM_EREAL:
		 		  case ARG_MODRM_DREAL:
	 			  case ARG_MODRM_WINT:
	 			  case ARG_MODRM_LINT:
	 			  case ARG_MODRM_BCD:
	 			  case ARG_MODRM_FPTR:
	 			  case ARG_MODRM:
                if(options.mode32)
                	if((newdsm->data[newdsm->modrm]&0xc7)==5) // straight disp32
                	{ dta=mcode+newdsm->modrm+1;
						  j.assign(options.dseg,((dword *)(&dta[0]))[0]);
                    xrefs.addxref(j,newdsm->addr);
                	}
                break;
				  default:
					 break;
				}
				switch(a2)
				{ case ARG_IMM32:
					 if(reloc.isreloc(loc+length-4))
					 {	newdsm->override=over_dsoffset;
						dta=mcode+length-4;
						j.assign(options.dseg,((dword *)(&dta[0]))[0]);
						xrefs.addxref(j,newdsm->addr);
					 }
					 break;
				  case ARG_IMM:
					 if(options.mode32)
					 { if(reloc.isreloc(loc+length-4))
						{ newdsm->override=over_dsoffset;
						  dta=mcode+length-4;
						  j.assign(options.dseg,((dword *)(&dta[0]))[0]);
						  xrefs.addxref(j,newdsm->addr);
						}
					 }
					 break;
              case ARG_MEMLOC:
                if(options.mode32)
                { newdsm->override=over_dsoffset;
						dta=mcode+length-4;
						j.assign(options.dseg,((dword *)(&dta[0]))[0]);
                  xrefs.addxref(j,newdsm->addr);
                }
                break;
	 			  case ARG_MMXMODRM:
	 			  case ARG_XMMMODRM:
	 			  case ARG_MODRM_S:
	 			  case ARG_MODRMM512:
	 			  case ARG_MODRMQ:
	 			  case ARG_MODRM_SREAL:
	 			  case ARG_MODRM_PTR:
	 			  case ARG_MODRM_WORD:
	 			  case ARG_MODRM_SINT:
	 			  case ARG_MODRM_EREAL:
		 		  case ARG_MODRM_DREAL:
	 			  case ARG_MODRM_WINT:
	 			  case ARG_MODRM_LINT:
	 			  case ARG_MODRM_BCD:
	 			  case ARG_MODRM_FPTR:
	 			  case ARG_MODRM:
                if(options.mode32)
                	if((newdsm->data[newdsm->modrm]&0xc7)==5) // straight disp32
                	{ dta=mcode+newdsm->modrm+1;
						  j.assign(options.dseg,((dword *)(&dta[0]))[0]);
                    xrefs.addxref(j,newdsm->addr);
                	}
                break;
				  default:
					 break;
				}
				return newdsm;
			 }
		  }
		  instnum++;
		}
	 }
	 tablenum++;
  }
  return NULL;
}

/************************************************************************
* arglength                                                             *
* - a function which returns the increase in length of an instruction   *
*   due to its argtype, used by the decodeinst engine in calculating    *
*   the instruction length                                              *
************************************************************************/
byte disasm::arglength(argtype a,byte modrmbyte,byte sibbyte,dword flgs,bool omode32)
{ byte rm;
  switch(a)
  { case ARG_IMM:
		if(flgs&FLAGS_8BIT)
        return 1;
		if(!omode32)
        return 2;
		else
        return 4;
	 case ARG_NONEBYTE:
		return 1;
	 case ARG_RELIMM:
	 case ARG_MEMLOC:
		if(options.mode16)
        return 2;
		else
        return 4;
	 case ARG_RELIMM8:
	 case ARG_SIMM8:
	 case ARG_IMM8:
	 case ARG_IMM8_IND:
		return 1;
	 case ARG_IMM32:
		return 4;
	 case ARG_IMM16_A:
	 case ARG_IMM16:
	 case ARG_MEMLOC16:
		return 2;
	 case ARG_FADDR:
		if(options.mode16)
        return 4;
		else
        return 6;
	 case ARG_MODREG:
	 case ARG_MMXMODRM:
	 case ARG_XMMMODRM:
	 case ARG_MODRM8:
	 case ARG_MODRM16:
	 case ARG_MODRM_S:
	 case ARG_MODRMM512:
	 case ARG_MODRMQ:
	 case ARG_MODRM_SREAL:
	 case ARG_MODRM_PTR:
	 case ARG_MODRM_WORD:
	 case ARG_MODRM_SINT:
	 case ARG_MODRM_EREAL:
	 case ARG_MODRM_DREAL:
	 case ARG_MODRM_WINT:
	 case ARG_MODRM_LINT:
	 case ARG_MODRM_BCD:
	 case ARG_MODRM_FPTR:

⌨️ 快捷键说明

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