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

📄 disasm.cpp

📁 十分经典的开源反编译工具
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	 case ARG_MODRM:
		rm=(byte)((modrmbyte&0xc0)>>6);
		switch(rm)
		{ case 0:
			 if(options.mode32)
			 { if((modrmbyte&0x07)==5)
				  return 5; // disp32
				if((modrmbyte&0x07)==4)
				{ if((sibbyte&0x07)==5)
					 return 6;
				  return 2; //sib byte - need to check if r=5 also.
				}
			 }
			 else
            if((modrmbyte&0x07)==6)
              return 3;
			 break;
		  case 1:
			 if(options.mode32)
			 { if((modrmbyte&0x07)==4)
				{ return 3; //sib byte
				}
			 }
			 return 2; // disp8
		  case 2:
			 if(options.mode32)
			 { if((modrmbyte&0x07)==4)
				  return 6; //sib byte
				return 5; // disp32
			 }
			 else
            return 3; // disp16
		  case 3:
			 return 1;
		}
		return 1;
	 default:
		break;
  }
  return 0;
}

/************************************************************************
* compare function                                                      *
* - the compare function for the list of disassembled instructions.     *
* - the disassembled instructions are kept in order using location, and *
*   type where type indicates instruction, comment, segheader line, etc *
*   as these are kept in the database of disassembled instructions. The *
*   window that the user sees into the disassembly is simply a view of  *
*   this database with one line per record.                             *
************************************************************************/
int disasm::compare(dsmitem *i,dsmitem *j)
{ if(i->addr==j->addr)
  { if(i->type==j->type)
		return 0;
	 else if(i->type>j->type)
		return 1;
	 return -1;
  }
  if(i->addr>j->addr)
	 return 1;
  return -1;
}

/************************************************************************
* deletion function                                                     *
* - in deleting the database we delete any comments that may be         *
*   attached, overrides the standard list item delete function          *
************************************************************************/
//deletion function for list
void disasm::delfunc(dsmitem *i)
{ // bugfix by Mark Ogden - added dsmnameloc
  if((i->type!=dsmcode)&&(i->type!=dsmnameloc))
	 if(i->tptr!=NULL)
      delete i->tptr;
  delete i;
}

/************************************************************************
* undefineline                                                          *
* - this simply deletes any code item in the disassembly database, for  *
*   the users current line in the database/window                       *
************************************************************************/
void disasm::undefineline(void)
{ dsmitem *tblock;
  lptr outhere;
  tblock=dio.findcurrentline();
  if(tblock==NULL)
    return;
  outhere=tblock->addr;
  tblock=nextiter_code(tblock);
  if(tblock!=NULL)
  { if(outhere==tblock->addr)
	 {	delfrom(tblock);
      dio.updatewindow();
    }
  }
}

/************************************************************************
* undefinelines                                                         *
* - undefines the next 10 lines of code, or until a non-disassembled    *
*   item is found                                                       *
************************************************************************/
void disasm::undefinelines(void)
{ dsmitem *tblock;
  lptr outhere;
  int i;
  tblock=dio.findcurrentline();
  if(tblock==NULL)
    return;
  outhere=tblock->addr;
  for(i=0;i<10;i++)
  { tblock=nextiter_code(tblock);
	 if(tblock!=NULL)
	 { if(outhere==tblock->addr)
		{ outhere+=tblock->length;
		  delfrom(tblock);
		  tblock=nextiterator();
		}
		else
        break;
	 }
  }
  dio.updatewindow();
}

/************************************************************************
* undefinelines_long                                                    *
* - here we continue undefining any code items in the database from the *
*   users line until we come to a location which is not code, or some   *
*   other kind of item in the database, like a comment, name, or xref   *
************************************************************************/
void disasm::undefinelines_long(void)
{ dsmitem *tblock;
  lptr outhere;
  tblock=dio.findcurrentline();
  if(tblock==NULL)
    return;
  outhere=tblock->addr;
  tblock=nextiter_code(tblock);
  while(tblock!=NULL)
  { if(!tblock->length)
      break;
    if(outhere==tblock->addr)
	 { outhere+=tblock->length;
	   delfrom(tblock);
	   tblock=nextiterator();
	 }
	 else
      break;
  }
  dio.updatewindow();
}

/************************************************************************
* undefineblock                                                         *
* - a block undefine using a selected block of code, we simply undefine *
*   any code items found between the start and end points of the block  *
************************************************************************/
void disasm::undefineblock(lptr ufrom,lptr uto)
{ dsmitem *tblock;
  lptr outhere;
  tblock=dsmfindaddrtype(ufrom,dsmcode);
  if(tblock==NULL)
    return;
  outhere=tblock->addr;
  while(tblock!=NULL)
  { if(tblock->addr>uto)
      break;
    if((tblock->type==dsmcode)&&(tblock->addr>=ufrom))
	   delfrom(tblock);
	 tblock=nextiterator();
  }
  dio.updatewindow();
}

/************************************************************************
* discomment                                                            *
* - this adds a comment to the disassembly database. It is used to add  *
*   different types of comments (like segheaders and user entered       *
*   comments)                                                           *
************************************************************************/
void disasm::discomment(lptr loc,dsmitemtype typ,byte *comment)
{ dsmitem *newdsm;
  newdsm=new dsmitem;
  initnewdsm(newdsm,loc,typ);
  newdsm->tptr=(void *)comment;
  newdsm->length=0;
  newdsm->data=comment;
  addto(newdsm);
  dio.updatewindowifinrange(loc);
}

/************************************************************************
* disautocomment                                                        *
* - this is a second function to add a comment to the disassembly       *
*   database, but only if there is no comment already there. This is    *
*   used to add disassembler autocomments. This is currently only used  *
*   in resource disassembly, but could easily be used to add standard   *
*   comments for particular instructions or for API calls, or for DOS   *
*   INTs.                                                               *
************************************************************************/
void disasm::disautocomment(lptr loc,dsmitemtype typ,byte *comment)
{ dsmitem *newdsm,*fdsm;
  fdsm=dsmfindaddrtype(loc,typ);
  if(fdsm!=NULL)
    if((fdsm->addr==loc)&&(fdsm->type==typ))
    { delete comment;
      return;
    }
  newdsm=new dsmitem;
  initnewdsm(newdsm,loc,typ);
  newdsm->tptr=(void *)comment;
  newdsm->length=0;
  newdsm->data=comment;
  addto(newdsm);
  dio.updatewindowifinrange(loc);
}

/************************************************************************
* delcomment                                                            *
* - this is used to delete comments from the database. Typically it is  *
*   called when the user enters a comment for a location. We delete the *
*   old one and then add the new one later.                             *
************************************************************************/
void disasm::delcomment(lptr loc,dsmitemtype typ)
{ dsmitem *fdsm;
  fdsm=dsmfindaddrtype(loc,typ);
  if(fdsm!=NULL)
	 if((fdsm->addr==loc)&&(fdsm->type==typ))
	 { delfrom(fdsm);
      dio.updatewindowifinrange(loc);
	 }
}

/************************************************************************
* interpretmod                                                          *
* - this is used by the jumptable detection routines in order to        *
*   examine a modrm/sib encoding for information                        *
* - it returns information about offsets and indexes and the registers  *
*   in use, and any multiplier                                          *
************************************************************************/
bool disasm::interpretmod(byte *data,dword *toffs,byte *indexreg,byte *indexreg2,byte *indexamount,int *numjumps)
{ byte rm,modrm,sib;
  rm=(byte)((data[0]&0xc0)>>6);
  modrm=(byte)(data[0]&0x07);
  switch(rm)
  { case 0:
		if(options.mode32)
		{ if(modrm==5)   // disp32 only.
		  { *toffs=((dword *)(&data[1]))[0];
			 *numjumps=1;
		  }
		  else if(modrm==4)        // case 4=sib
		  { sib=data[1];
			 if((sib&0x07)==5)
            *toffs=((dword *)(&data[2]))[0];  // disp32
			 else
            return false; // no disp
			 if(((sib>>3)&0x07)==4)
            *numjumps=1;  // no scaled index reg
			 else
			 { *indexreg=(byte)((sib>>3)&0x07);
				switch(sib>>6)
				{ case 0:
					 *indexamount=1;
					 break;
				  case 1:
					 *indexamount=2;
					 break;
				  case 2:
					 *indexamount=4;
					 break;
				  case 3:
					 *indexamount=8;
					 break;
				}
			 }
		  }
		  else
          return false; // no disp
		}
		else // 16-bit mode
		{ if(modrm==6) // disp16 only
		  { *toffs=((word *)(&data[1]))[0];
			 *numjumps=1;
		  }
		  else
          return false; // no disp
		}
		break;
	 case 1:
		return false; // all disp8 offsets - don't follow
	 case 2:
		if(options.mode32)
		{ if(modrm==4)        // case 4=sib
		  { sib=data[1];
			 *toffs=((dword *)(&data[2]))[0];
			 *indexreg2=(byte)(sib&0x07);
			 if(((sib>>3)&0x07)==4); // no scaled index reg
			 else
			 { *indexreg=(byte)((sib>>3)&0x07);
				switch(sib>>6)
				{ case 0:
					 *indexamount=1;
					 break;
				  case 1:
					 *indexamount=2;
					 break;
				  case 2:
					 *indexamount=4;
					 break;
				  case 3:
					 *indexamount=8;
					 break;
				}
			 }
		  }
		  else
		  { *toffs=((dword *)(&data[1]))[0];
			 *indexreg2=(byte)(data[0]&0x07);
		  }
		}
		else // 16bit mode
		{ *toffs=((word *)(&data[1]))[0];
		  *indexreg=(byte)(data[0]&0x07); // NB double index reg eg bx+si
		}
		break;
	 case 3:
		// case 3 - no jump table offset present. indirect jump.
		return false;
  }
  return true;
}

/************************************************************************
* disjumptable                                                          *
* - this was written some ago as a quick hack for decoding jump tables  *
* - it tries to obtain information on the table itself, and looks for   *
*   an indication of the number of items in the table by examining      *
*   prior instructions, although it is quite unintelligent in some      *
*   ways.                                                               *
* - it also looks for indextables which are used in complex jumptables  *
*   to decode an initial case number for the jumptable.                 *
* - although good for some compilers the output from some modern        *
*   compilers does not fare well in the analysis.                       *
************************************************************************/
void disasm::disjumptable(lptr loc)
{ dsmitem *investigate;
  dsegitem *dblock,*idblock;
  byte *data;
  byte pbyte;       // prefix byte
  lptr t,it,index,xr;
  int numjumps,inumjumps;
  int i;
  byte indexreg,indexamount,indexreg2;
  byte iindexreg,iindexamount,iindexreg2;
  char tablename[20],tablenum[10];
  bool itable;
  pbyte=0;
  numjumps=0;
  indexreg=0;
  indexreg2=0;
  indexamount=0;
  inumjumps=0;
  iindexreg=0;
  iindexreg2=0;
  iindexamount=0;
  investigate=dsmfindaddrtype(loc,dsmcode);
  if(investigate==NULL)
    return;
  // check that inst is still there/ correct type of jump
  // adjust for any segment overrides added since
  if((loc-investigate->addr)<4)
    loc.offs=investigate->addr.offs;
  if((investigate->addr!=loc)||(investigate->type!=dsmcode))
	 return;
  if(DSMITEM_ARG1(investigate)!=ARG_MODRM)
	 return;
  if(!(investigate->flags&(FLAGS_JMP|FLAGS_CALL|FLAGS_CJMP)))
    return;
  data=investigate->data+investigate->modrm;
  if(!interpretmod(data,&t.offs,&indexreg,&indexreg2,&indexamount,&numjumps))
    return;
  // find target - jump table, need to use default ds:/ check for cs: override
  if(investigate->flags&FLAGS_SEGPR

⌨️ 快捷键说明

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