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

📄 disasm.cpp

📁 十分经典的开源反编译工具
💻 CPP
📖 第 1 页 / 共 5 页
字号:
  struct dialogboxheader
  { unsigned long style,extendedstyle;
    unsigned short numberofitems;
    unsigned short x,y;
    unsigned short cx,cy;
  };*/
  if(exd)
  { addcomment(loc,"Signature+Version");
    disdatadword(loc);
    addcomment(loc+4,"HelpID");
    disdatadword(loc+4);
    loc=loc+8;
  }
  if(exd)
    addcomment(loc,"Extended Style");
  else
    addcomment(loc,"Style");
  disdatadword(loc);
  if(exd)
    addcomment(loc+4,"Style");
  else
    addcomment(loc+4,"Extended Style");
  disdatadword(loc+4);
  addcomment(loc+8,"Number of Items");
  disdataword(loc+8);
  addcomment(loc+10,"x");
  disdataword(loc+10);
  addcomment(loc+12,"y");
  disdataword(loc+12);
  addcomment(loc+14,"cx");
  disdataword(loc+14);
  addcomment(loc+16,"cy");
  disdataword(loc+16);
  cloc=loc+18;
  addcomment(cloc,"Menu name/ordinal");
  ilen=disname_or_ordinal(cloc,false);
  cloc+=ilen;
  addcomment(cloc,"Class name/ordinal");
  ilen=disname_or_ordinal(cloc,false);
  cloc+=ilen;
  addcomment(cloc,"Caption");
  disdataucstring(cloc);
  cloc+=getlength(cloc);
  findit=dsmfindaddrtype(loc+4*(exd?1:0),dsmcode);
  hdrstyle=0;
  if(findit!=NULL)
  { if((findit->addr==loc+4*(exd?1:0))&&(findit->type==dsmcode))
      hdrstyle=((dword *)findit->data)[0];
  }
  // i noticed a reference to DS_SHELLFONT on msdn, but what is that ????????
  if (hdrstyle&DS_SETFONT)  // if ds_setfont then 2 more items...in theory
  { addcomment(cloc,"font pointsize");
    disdataword(cloc);
    cloc+=2;
    if(exd) // more options with exd
    { addcomment(cloc,"weight");
      disdataword(cloc);
      cloc+=2;
      addcomment(cloc,"italic");
      //disdatabyte(cloc);
      cloc+=1;
      addcomment(cloc,"charset");
      //disdatabyte(cloc);
      cloc+=1;
    }
    addcomment(cloc,"font");
    disdataucstring(cloc);
    cloc+=getlength(cloc);
  }
  // now do controls
  findit=dsmfindaddrtype(loc+8,dsmcode);
  numctrls=0;
  if(findit!=NULL)
  { if((findit->addr==loc+8)&&(findit->type==dsmcode))
      numctrls=((word *)findit->data)[0];
  }
  /*struct ctrlheader
  { unsigned long style,extendedstyle;
    unsigned short x,y;
    unsigned short cx,cy;
    unsigned short wid;
  };*/
  while(numctrls)
  { if(cloc.offs&0x03)
      cloc.offs=(cloc.offs|0x03)+1;
    if(exd)
    { addcomment(cloc,"HelpID");
      disdatadword(cloc);
      cloc+=4;
    }
    if(exd)
      addcomment(cloc,"Extended Style");
    else
      addcomment(cloc,"Style");
    disdatadword(cloc);
    if(exd)
      addcomment(cloc+4,"Style");
    else
      addcomment(cloc+4,"Extended Style");
    disdatadword(cloc+4);
    addcomment(cloc+8,"x");
    disdataword(cloc+8);
    addcomment(cloc+10,"y");
    disdataword(cloc+10);
    addcomment(cloc+12,"cx");
    disdataword(cloc+12);
    addcomment(cloc+14,"cy");
    disdataword(cloc+14);
    addcomment(cloc+16,"wid");
    disdataword(cloc+16);
    cloc+=18;
    if(exd)
      if(cloc.offs&0x03)
        cloc.offs=(cloc.offs|0x03)+1;
    addcomment(cloc,"Class id");
    ilen=disname_or_ordinal(cloc,true);
    cloc+=ilen;
    addcomment(cloc,"Text");
    ilen=disname_or_ordinal(cloc,false);
    cloc+=ilen;
    addcomment(cloc,"Extra Stuff");
    disdataword(cloc);
    findit=dsmfindaddrtype(cloc,dsmcode);
    if(findit!=NULL)
    { if((findit->addr==cloc)&&(findit->type==dsmcode))
        cloc+=((word *)findit->data)[0];
    }
    cloc+=2;
    numctrls--;
  }
}
#ifdef __BORLANDC__
#pragma warn +par
#endif

/************************************************************************
* disstringtable                                                        *
* - disassembles a string table, by which I mean that the strings are   *
*   disassembled into strings and the locations are named according to  *
*   the strings id numbers (I chose this in preference to naming by     *
*   string because they are a resource, and so the locations will not   *
*   be referenced, but if the program wants to use them then it will    *
*   use the id numbers, and make an API call to get hold of them).      *
************************************************************************/
void disasm::disstringtable(lptr loc,char *basename)
{ int i;
  lptr cloc;
  char callit[40];
  dword idnum;
  int ipt;
  dsmitem *lastdsm;
  ipt=0;
  idnum=0;
  if(basename!=NULL)
  { while((basename[ipt])&&(basename[ipt]!=':'))
      ipt++;
    if(basename[ipt]==':')
    { ipt++;
      while(basename[ipt])
      { if(basename[ipt]>='a')
          idnum=idnum*16+basename[ipt]-'a'+10;
        else
          idnum=idnum*16+basename[ipt]-'0';
        ipt++;
        if(basename[ipt]=='h')
          break;
      }
    }
  }
  cloc=loc;
  for(i=0;i<16;i++)  // 16 strings in a stringtable, of type unicode_pascal.
  { disdataupstring(cloc);
    if(idnum)
    { wsprintf(callit,"String_ID_%lx",(idnum-1)*16+i);
      name.addname(cloc,callit);
    }
    lastdsm=dsmfindaddrtype(cloc,dsmcode);
    if(lastdsm==NULL)
      break;
    if((lastdsm->type!=dsmcode)||(lastdsm->addr!=cloc))
      break;
    cloc+=lastdsm->length;
  }
}

/************************************************************************
* codeseek                                                              *
* - this is the aggressive code search if it is chosen as an option. It *
*   has a low priority, and so appears near the end of the queue. It    *
*   hunts for possible code to disassemble in the code segments (added  *
*   as a task during file load for each code segment). When it finds an *
*   undisassembled byte it tries to disassemble from that point, and    *
*   drops into the background again until disassembly has been done     *
* - note that if it doesnt find anything in a short time it exits and   *
*   puts a continuation request in to the scheduler, this ensures that  *
*   userrequests are answered quickly                                   *
************************************************************************/
void disasm::codeseek(lptr loc)
{ bool doneblock;
  dsegitem *dblock;
  dsmitem *tblock;
  int dcount,ilength;
  // check if already done.
  dblock=dta.findseg(loc);      // find segment item.
  dcount=0;
  if(dblock==NULL)
    return;
  do{
    doneblock=false;
    ilength=1;
    dsmfindaddrtype(loc,dsmnull);
    tblock=nextiterator();
    tblock=nextiter_code(tblock);
    if(tblock!=NULL)
	 { if((tblock->addr.segm==loc.segm)&&(dsmitem_contains_loc(tblock,loc)))
		  doneblock=true;
      while(tblock->addr==loc)
	   { if(tblock->length)
          ilength=tblock->length;
    	  if(tblock->type!=dsmcomment)
	     { doneblock=true;
	 	    break;
        }
		  tblock=nextiterator();
		  if(tblock==NULL)
          break;
      }
    }
    if(doneblock)
    { loc+=ilength;
      dcount++;
      if(loc>=(dblock->addr+dblock->size))
        return;
      if(dcount>1000)
      {	// dont forget the main thread!
        scheduler.addtask(seek_code,priority_continuation,loc,NULL);
        return;
      }
    }
  } while (doneblock);
  // decode it.
  scheduler.addtask(seek_code,priority_aggressivesearch,loc+1,NULL);
  scheduler.addtask(dis_code,priority_possiblecode,loc,NULL);
}

/************************************************************************
* disexportblock                                                        *
* - this disassembles a block of code, from an export address, but only *
*   if the export address is in a code segment                          *
************************************************************************/
void disasm::disexportblock(lptr loc)
{  dsegitem *dblock;
   dblock=dta.findseg(loc);
   if(dblock==NULL)
     return;
   if(dblock->typ==code32)
   	disblock(loc);
}

/************************************************************************
* disblock                                                              *
* - disassembles a block from the starting point loc, calling           *
*   decodeinst for each instruction.                                    *
* - we dont just keep going in here, but only disassemble a few         *
*   instructions then ask for a continuation and quit back to the       *
*   scheduler for userrequests to be processed. If Borg seems to slow   *
*   on your machine when you scroll around and it is still analysing    *
*   then try dropping the number of instructions to disassemble and     *
*   window updates should occur more often.                             *
* - If Borg cannot disassemble for whatever reason, or if a ret or jmp  *
*   type instruction is reached then we finish.                         *
************************************************************************/
void disasm::disblock(lptr loc)
{ byte ibuff[20];                     // ibuff is the disassembly buffer - m/c is moved here
												  // for disassembly - no checking of eof is then needed
												  // until after the code is identified.
  dsegitem *dblock;
  int i,disasmcount;
  bool doneblock;
  dsmitem *tblock;
  dword aaddr;
  byte *mcode;
  asminstdata *codefound;

  dblock=dta.findseg(loc);      // find segment item.
  disasmcount=0;
  if(dblock==NULL)
    return;
  if(dblock->typ==uninitdata)
    return;
  if(loc>=dblock->addr+dblock->size)
    return;
  doneblock=false;
  while(!doneblock)
  { // don't spend too long in here
	 disasmcount++;
	 if(disasmcount>50)
	 { scheduler.addtask(dis_code,priority_continuation,loc,NULL);
		return;
	 }
	 memset(ibuff,0,20);
	 // check if already done.
	 dsmfindaddrtype(loc,dsmnull);
	 tblock=nextiterator();
    tblock=nextiter_code(tblock);
	 if(tblock!=NULL)
	 {	if((tblock->addr.segm==loc.segm)&&(dsmitem_contains_loc(tblock,loc)))
		  doneblock=true;
	 	while(tblock->addr==loc)
		{ if(tblock->type!=dsmcomment)
		  { doneblock=true;
			 break;
		  }
		  tblock=nextiterator();
		  if(tblock==NULL)
          break;
		}
	 }
	 // decode it.
	 if(doneblock)
      break;
	 aaddr=loc-dblock->addr;
	 mcode=dblock->data+aaddr;
	 i=0;
	 while((i<15)&&(aaddr<dblock->size))
	 { ibuff[i]=mcode[i];
		i++;
		aaddr++;
	 }
	 tblock=decodeinst(ibuff,mcode,loc,TABLE_MAIN,options.mode32,0);
	 if(tblock!=NULL)
    { if(!checkvalid(tblock))
	   { delete tblock;
	     tblock=NULL;
	   }
    }
	 if(tblock!=NULL)
	 {	addto(tblock);
		//check if need to update window.
		dio.updatewindowifinrange(loc);
      loc.offs+=tblock->length;
		if((loc-dblock->addr)>dblock->size)
		{ doneblock=true;
		  delfrom(tblock);
		}
	 }
	 else
      doneblock=true;
	 if(doneblock)
      break;
	 // check if end (jmp,ret,etc)
	 codefound=(asminstdata *)tblock->tptr;
	 if((codefound->flags&FLAGS_JMP)||(codefound->flags&FLAGS_RET))
		doneblock=true;
  }
}

/************************************************************************
* decodeinst                                                            *
* - disassembles one instruction                                        *
* - in some ways this is the single most important function in Borg. It *
*   disassembles an instruction adding a disassembled item to the       *
*   database. It uses the options we have set, and the processor tables *
*   identified.                                                         *
* - If some kind of call or conditional jump is reached then Borg       *
*   just adds another disassembly task to the scheduler to look at      *
*   later, and then carries on.                                         *
* - Note that this function is recursive, for handling some complex     *
*   x86 overrides, note that the recursion depth is limited but Borg    *
*   should handle complex prefix byte sequences and 'double sequences'  *
* - The majority of the code here is some of the oldest code in Borg,   *
*   and probably some of the most complex.                              *
* - xreffing and windowupdates are performed from here                  *
************************************************************************/
dsmitem *disasm::decodeinst(byte *ibuff,byte *mcode,lptr loc,byte tabtype,bool omode32,int depth)
{ int tablenum=0;             // asmtable table number
  int instnum;                // instruction num in table
  asminstdata *insttab;
  dsmitem *newdsm;
  dword flgs;  					// inst flags
  argtype a1,a2,a3;           // inst args
  lptr j;                     // jump/call target
  byte *dta;
  byte length;
  gnameitem *imp;
  char impname[GNAME_MAXLEN+1];
  bool righttable;
  byte cbyte,mbyte;
  bool fupbyte;

⌨️ 快捷键说明

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