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

📄 disasm.cpp

📁 反汇编工具borg2.27源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/************************************************************************
*                disasm.cpp                                             *
* This is a fairly big class, even having split off the disio class.    *
* The class is the class responsible for maintaining the main           *
* disassembly structures of Borg, and for performing the disassembly    *
* analysis. The class has some very old code in it, and hasn't          *
* undergone much improvement for some time, so parts could do with      *
* rewriting.                                                            *
************************************************************************/

#include <windows.h>
#include <stdio.h>

#include "disasm.h"
#include "dasm.h"
#include "xref.h"
#include "data.h"
#include "gname.h"
#include "schedule.h"
#include "relocs.h"
#include "debug.h"

/************************************************************************
* constructor function                                                  *
* - resets a few class globals                                          *
************************************************************************/
disasm::disasm()
{ lastdis=NULL;
  itables=0;
  jtables=0;
  irefs=0;
}

/************************************************************************
* destructor function is currently null                                 *
************************************************************************/
disasm::~disasm()
{
}

/************************************************************************
* initnewdsm                                                            *
* - this is some common code i pulled out and put into a function on    *
*   its own. when a new disassembly item is created it initialises some *
*   of the stucture.                                                    *
************************************************************************/
void disasm::initnewdsm(dsmitem *newdsm,lptr loc,dsmitemtype typ)
{ newdsm->addr=loc;
  newdsm->type=typ;
  newdsm->override=over_null;
  newdsm->modrm=0;
  newdsm->mode32=options.mode32;
  newdsm->flags=0;
  newdsm->displayflags=0;
}

/************************************************************************
* dissettable                                                           *
* - this function sets up the processor table. It should be called once *
*   when the processor has been selected and before disassembly begins  *
************************************************************************/
void disasm::dissettable(void)
{ int i=0;
  while((procnames[i].num!=0)&&(procnames[i].num!=options.processor))
    i++;
  itable=procnames[i].tab;
}

/************************************************************************
* nextiter_code                                                         *
* - a basic building block piece of code which skips to the next        *
*   code/data item in the disassembly (identified by having a length),  *
*   or returns null if it gets to the end                               *
************************************************************************/
dsmitem *disasm::nextiter_code(dsmitem *tblock)
{ if(tblock!=NULL)
  { while(!tblock->length)
    { tblock=nextiterator();
      if(tblock==NULL)
        break;
    }
  }
  return tblock;
}

/************************************************************************
* dsmitem_contains_loc                                                  *
* - a basic building block piece of code which returns true if the      *
*   dsmitem straddles loc                                               *
* - added in v2.22                                                      *
************************************************************************/
bool disasm::dsmitem_contains_loc(dsmitem *d,lptr loc)
{ if((d->addr<loc)&&(d->addr+d->length>loc))
    return true;
  return false;
}

/************************************************************************
* dsmfindaddrtype                                                       *
* - a basic building block piece of code which returns a dsmitem        *
*   pointer using the list class find to find it by loc and type        *
* - added in v2.22                                                      *
************************************************************************/
dsmitem *disasm::dsmfindaddrtype(lptr loc,dsmitemtype typ)
{ dsmitem fnd;
  fnd.addr=loc;
  fnd.type=typ;
  return find(&fnd);
}

/************************************************************************
* oktoname                                                              *
* - this checks that we arent trying to name a location which is in the *
*   middle of an instruction and returns true if it is ok to assign a   *
*   name here                                                           *
************************************************************************/
bool disasm::oktoname(lptr loc)
{ dsmitem *checker;
  // check table for the given address
  checker=dsmfindaddrtype(loc,dsmcode);
  // NULL returned - must be ok.
  if(checker==NULL)
    return true;
  // check bounds.
  if(dsmitem_contains_loc(checker,loc))
	 return false;
  return true;
}

/************************************************************************
* checkvalid                                                            *
* - this is called when adding an instruction disassembly to the list   *
* - it checks that an instruction isnt being added which would overlap  *
*   with instructions already in the database                           *
* - it will delete any names and xrefs or comments which get in the way *
************************************************************************/
bool disasm::checkvalid(dsmitem *newdsm)
{ dsmitem *lstdsm,*deldsm;
  lstdsm=dsmfindaddrtype(newdsm->addr,dsmnull);
  if(lstdsm==NULL)
    return true;
  // go through the disassembly items nearby and check for any overlaps.
  do
  { if(lstdsm->length)
	 { if(newdsm->addr.between(lstdsm->addr,lstdsm->addr+lstdsm->length-1))
		  return false;
      if(lstdsm->addr.between(newdsm->addr,newdsm->addr+newdsm->length-1))
		  return false;
	 }
	 if(lstdsm->addr>=(newdsm->addr+newdsm->length))
      break;
	 lstdsm=nextiterator();
  } while(lstdsm!=NULL);
  deldsm=dsmfindaddrtype(newdsm->addr,dsmnull);
  // now go through them again, and this time delete any names/xrefs which get
  // in the way.
  do
  { if((!deldsm->length)&&(deldsm->addr.segm==newdsm->addr.segm))
	 { if(dsmitem_contains_loc(newdsm,deldsm->addr))
      { switch(deldsm->type)
		  { case dsmnameloc:
#ifdef DEBUG
				DebugMessage("Deleting Name : %s",deldsm->tptr);
#endif
				name.delname(deldsm->addr);
				break;
			 case dsmxref:
#ifdef DEBUG
				DebugMessage("Deleting Xref at : %04lx:%04lx",deldsm->addr.segm,deldsm->addr.offs);
#endif
				break;
			 default:
				break;
		  }
		  delfrom(deldsm);
		  deldsm=dsmfindaddrtype(newdsm->addr,dsmnull);
		  if(deldsm==NULL)
          return true;
		}
	 }
	 if(newdsm->addr+newdsm->length<=deldsm->addr)
      break;
	 deldsm=nextiterator();
  } while(lstdsm!=NULL);
  return true;
}

/************************************************************************
* setcodeoverride                                                       *
* - sets a particular override for a given location                     *
* - this subfunction was created in v211 as it was duplicated code in   *
*   several functions                                                   *
************************************************************************/
void disasm::setcodeoverride(lptr loc,byteoverride typ)
{ dsmitem *findit;
  findit=dsmfindaddrtype(loc,dsmcode);
  if(findit!=NULL)
  { if((findit->addr==loc)&&(findit->type==dsmcode))
	 {	findit->override=typ;
		dio.updatewindowifinrange(loc);
	 }
  }
}

/************************************************************************
* disargnegate                                                          *
* - as well as an override I added some displayflags for a disassembly  *
*   item. There is a negation item which allows immediates to be        *
*   negated when displayed, and this function sets or resets the flag   *
************************************************************************/
void disasm::disargnegate(lptr loc)
{ dsmitem *findit;
  findit=dsmfindaddrtype(loc,dsmcode);
  if(findit!=NULL)
  { if((findit->addr==loc)&&(findit->type==dsmcode))
	 {	findit->displayflags=(byte)(findit->displayflags^DISPFLAG_NEGATE);
		dio.updatewindowifinrange(loc);
	 }
  }
}

/************************************************************************
* disargoverdec                                                         *
* - sets the decimal override for a disassembly item, given the         *
*   location                                                            *
************************************************************************/
void disasm::disargoverdec(lptr loc)
{ setcodeoverride(loc,over_decimal);
}

/************************************************************************
* disargoversingle                                                      *
* - sets the single (float) override for a disassembly item, given the  *
*   location                                                            *
************************************************************************/
void disasm::disargoversingle(lptr loc)
{ setcodeoverride(loc,over_single);
}

/************************************************************************
* disargoverhex                                                         *
* - sets the hex (null) override for a disassembly item, given the      *
*   location                                                            *
************************************************************************/
void disasm::disargoverhex(lptr loc)
{ setcodeoverride(loc,over_null);
}

/************************************************************************
* disargoverchar                                                        *
* - sets the character override for a disassembly item, given the       *
*   location                                                            *
************************************************************************/
void disasm::disargoverchar(lptr loc)
{ setcodeoverride(loc,over_char);
}

/************************************************************************
* disargoveroffsetdseg                                                  *
* - sets the dseg override for a disassembly item, given the location   *
* - NB at present it does not affect xrefs, to be done.......           *
************************************************************************/
void disasm::disargoveroffsetdseg(lptr loc)
{ dsmitem *findit;
  lptr j;
  findit=dsmfindaddrtype(loc,dsmcode);
  if(findit!=NULL)
  { if((findit->addr==loc)&&(findit->type==dsmcode))
	 {	findit->override=over_dsoffset;
		dio.updatewindowifinrange(loc);
		if((options.mode32)&&(findit->length>=4))
		{ j.assign(options.dseg,((dword *)(&findit->data[findit->length-4]))[0]);
		  xrefs.addxref(j,loc);
		}
	 }
  }
}

/************************************************************************
* disdatastring                                                         *
* - disassembles a string at location loc.                              *
* - also names the location using the string.                           *
* - C style                                                             *
************************************************************************/
void disasm::disdatastring(lptr loc)
{ dsegitem *dblock;
  dsmitem *newdsm;
  dword maxlen,actuallen;
  char callit[GNAME_MAXLEN+1];
  dblock=dta.findseg(loc);
  if(dblock==NULL)
    return;
  maxlen=dblock->size-(loc-dblock->addr);
  if(maxlen<2)
    return;
  actuallen=0;
  while((dblock->data+(loc-dblock->addr)+actuallen)[0])
  { actuallen++;
	 maxlen--;
	 if(!maxlen)
      return;
  }
  actuallen++;
  if(actuallen>0xffff)
    return; // tooo big
  newdsm=new dsmitem;
  initnewdsm(newdsm,loc,dsmcode);
  newdsm->tptr=&asmstr[0];
  newdsm->length=(word)actuallen;              // string length
  newdsm->data=dblock->data+(loc-dblock->addr);
  if(checkvalid(newdsm))
  { callit[0]='s';
	 callit[1]='_';
	 if(actuallen>GNAME_MAXLEN-2)
	 { callit[GNAME_MAXLEN]=0;
		lstrcpyn(callit+2,(char *)newdsm->data,GNAME_MAXLEN-3);
	 }
	 else lstrcpy(callit+2,(char *)newdsm->data);
	 cleanstring(callit);
	 addto(newdsm);
	 name.addname(newdsm->addr,callit);
	 //check if need to update window.
	 dio.updatewindowifinrange(loc);
  }
  else
	 delete newdsm;
}

/************************************************************************
* disdataucstring                                                       *
* - disassembles a string at location loc.                              *
* - also names the location using the string.                           *
* - unicode C style                                                     *
************************************************************************/
void disasm::disdataucstring(lptr loc)
{ // unicode c-style string.
  dsegitem *dblock;
  dsmitem *newdsm;
  dword maxlen,actuallen;
  unsigned int i;
  char callit[GNAME_MAXLEN+1];
  dblock=dta.findseg(loc);
  if(dblock==NULL)
    return;
  maxlen=dblock->size-(loc-dblock->addr);
  if(maxlen<2)
    return;
  actuallen=0;
  while((dblock->data+(loc-dblock->addr)+actuallen)[0])
  { actuallen++;
	 maxlen--;
	 if(!maxlen)
      return;
	 actuallen++;
	 maxlen--;
	 if(!maxlen)
      return;
  }
  actuallen+=2;
  if(actuallen>0xffff)
    return; // tooo big
  newdsm=new dsmitem;
  initnewdsm(newdsm,loc,dsmcode);
  newdsm->tptr=&asmstr[3];
  newdsm->length=(word)actuallen;              // string length
  newdsm->data=dblock->data+(loc-dblock->addr);
  if(checkvalid(newdsm))
  { callit[0]='s';
	 callit[1]='_';
	 i=2;
	 while(i<GNAME_MAXLEN-1)
	 { callit[i]=newdsm->data[(i-2)*2];
		i++;
		if(i*2>actuallen)
        break;
	 }
	 callit[i]=0;
	 cleanstring(callit);
	 addto(newdsm);
	 name.addname(newdsm->addr,callit);
	 //check if need to update window.
	 dio.updatewindowifinrange(loc);
  }
  else
	 delete newdsm;
}

/************************************************************************
* disdataupstring                                                       *

⌨️ 快捷键说明

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