📄 data.cpp
字号:
* - returns a bool value indicating whether the loc is outside a *
* segment. Used a lot to determine if we have moved outside a data *
* area. If two segments have the same segm value and are contiguous *
* then it will return false, not true *
************************************************************************/
bool dataseg::beyondseg(lptr loc)
{ dsegitem *findd;
resetiterator();
findd=nextiterator();
while(findd!=NULL)
{ if(insegloc(findd,loc))
return false;
findd=nextiterator();
}
return true;
}
/************************************************************************
* nextseg *
* - this function takes a loc, and returns the next segment first loc *
* or a segm=0 if its not found *
* mainly used in output and display routines *
************************************************************************/
void dataseg::nextseg(lptr *loc)
{ dsegitem *findd;
resetiterator();
findd=nextiterator();
while(findd!=NULL)
{ if(insegloc(findd,*loc))
{ findd=nextiterator();
if(findd==NULL)
loc->segm=0;
else
(*loc)=findd->addr;
return;
}
findd=nextiterator();
}
loc->segm=0;
}
/************************************************************************
* lastseg *
* - this function takes a loc, and returns the last segment last loc *
* or a segm=0 if its not found *
* mainly used in output and display routines *
************************************************************************/
void dataseg::lastseg(lptr *loc)
{ dsegitem *findd,*prevd;
resetiterator();
findd=nextiterator();
prevd=NULL;
while(findd!=NULL)
{ if(insegloc(findd,*loc))
{ if(prevd==NULL)
loc->segm=0;
else
(*loc)=prevd->addr+prevd->size-1;
return;
}
prevd=findd;
findd=nextiterator();
}
loc->segm=0;
}
/************************************************************************
* possibleentrycode *
* - this just scans a whole segment for possible routine entrycode, as *
* defined by options, and adds scheduler items for proper analysis by *
* disasm. currently all specific to the 80x86 processor *
************************************************************************/
void dataseg::possibleentrycode(lptr loc)
{ dsegitem t1,*findd;
dword length;
if(options.processor==PROC_Z80)
return;
t1.addr=loc;
findd=find(&t1);
if(findd==NULL)
return;
length=findd->size;
loc.offs=findd->addr.offs;
if(options.codedetect&CD_AGGRESSIVE)
scheduler.addtask(seek_code,priority_aggressivesearch,loc,NULL);
while(length)
{ if((options.codedetect&CD_PUSHBP)&&(length>3))
{ if(findd->data[loc-findd->addr]==0x55) // push bp
{ // two encodings of mov bp,sp
if((findd->data[(loc-findd->addr)+1]==0x8b)&&(findd->data[(loc-findd->addr)+2]==0xec))
scheduler.addtask(dis_code,priority_possiblecode,loc,NULL);
if((findd->data[(loc-findd->addr)+1]==0x89)&&(findd->data[(loc-findd->addr)+2]==0xe5))
scheduler.addtask(dis_code,priority_possiblecode,loc,NULL);
}
}
if((options.codedetect&CD_EAXFROMESP)&&(length>4))
{ if(findd->data[loc-findd->addr]==0x55) // push bp
{ if((findd->data[(loc-findd->addr)+1]==0x8b)&&(findd->data[(loc-findd->addr)+2]==0x44)&&(findd->data[(loc-findd->addr)+3]==0x24)) // mov ax,[sp+xx]
scheduler.addtask(dis_code,priority_possiblecode,loc,NULL);
}
}
if((options.codedetect&CD_MOVEAX)&&(length>3))
{ if((findd->data[(loc-findd->addr)]==0x8b)&&(findd->data[(loc-findd->addr)+1]==0x44)&&(findd->data[(loc-findd->addr)+2]==0x24)) // mov ax,[sp+xx]
scheduler.addtask(dis_code,priority_possiblecode,loc,NULL);
}
if((options.codedetect&CD_ENTER)&&(length>4))
{ if(findd->data[loc-findd->addr]==0xc8) // enter
{ if(findd->data[(loc-findd->addr)+3]==0x00) // enter xx,00
scheduler.addtask(dis_code,priority_possiblecode,loc,NULL);
}
}
if((options.codedetect&CD_MOVBX)&&(length>2)) // mov bx,sp
{ if((findd->data[loc-findd->addr]==0x8b)&&(findd->data[(loc-findd->addr)+1]==0xdc))
scheduler.addtask(dis_code,priority_possiblecode,loc,NULL);
}
loc.offs++;
length--;
}
}
/************************************************************************
* segheader *
* - here we add the segment header as a comment, to the disassembly *
* disasm adds the comment, we assemble the information here. *
************************************************************************/
void dataseg::segheader(lptr loc)
{ byte *tmpc,tmp2[30];
dsegitem t1,*findd;
dword t;
t1.addr=loc;
findd=find(&t1);
if(findd==NULL)
return;
tmpc=new byte[80];
strcpy((char *)tmpc,"-----------------------------------------------------------------------");
dsm.discomment(loc,dsmsegheader,tmpc);
tmpc=new byte[80];
t=loc.segm;
wsprintf((char *)tmpc,"Segment : %02lxh",t);
wsprintf((char *)tmp2," Offset : %02lxh",loc.offs);
strcat((char *)tmpc,(char *)tmp2);
wsprintf((char *)tmp2," Size : %02lxh",findd->size);
strcat((char *)tmpc,(char *)tmp2);
dsm.discomment(loc,(dsmitemtype)(dsmsegheader+1),tmpc);
tmpc=new byte[80];
switch(findd->typ)
{ case code16:
strcpy((char *)tmpc,"16-bit Code");
break;
case code32:
strcpy((char *)tmpc,"32-bit Code");
break;
case data16:
strcpy((char *)tmpc,"16-bit Data");
break;
case data32:
strcpy((char *)tmpc,"32-bit Data");
break;
case uninitdata:
strcpy((char *)tmpc,"Uninit Data");
break;
case debugdata:
strcpy((char *)tmpc,"Debug Data");
break;
case resourcedata:
strcpy((char *)tmpc,"Resource Data ");
break;
default:
strcpy((char *)tmpc,"Unknown");
break;
}
if(findd->name!=NULL)
{ strcat((char *)tmpc," : ");
strncat((char *)tmpc,findd->name,60);
}
dsm.discomment(loc,(dsmitemtype)(dsmsegheader+2),tmpc);
tmpc=new byte[80];
strcpy((char *)tmpc,"-----------------------------------------------------------------------");
dsm.discomment(loc,(dsmitemtype)(dsmsegheader+3),tmpc);
}
/************************************************************************
* write_item *
* - writes a dataseg item to the savefile specified *
* uses the current item, and moves the iterator on *
* saving in borg is single pass and so stringlengths are saved before *
* strings, etc. we use a similar structure item for the save *
* (dsegitem - dsegitemsave). As the data item is a pointer it is *
* converted into an offset for saving. *
************************************************************************/
bool dataseg::write_item(savefile *sf,byte *filebuff)
{ dword nlen;
dsegitemsave structsave;
dsegitem *currseg;
currseg=nextiterator();
structsave.addr=currseg->addr;
structsave.size=currseg->size;
structsave.fileoffset=currseg->data-filebuff;
structsave.typ=currseg->typ;
if(currseg->name!=NULL)
structsave.name=true;
else
structsave.name=false;
if(!sf->swrite(&structsave,sizeof(dsegitemsave)))
return false;
if(structsave.name)
{ nlen=strlen(currseg->name)+1;
if(!sf->swrite(&nlen,sizeof(dword)))
return false;
if(!sf->swrite(currseg->name,nlen))
return false;
}
return true;
}
/************************************************************************
* read_item *
* - reads a dataseg item from the savefile specified *
* Note that addseg is not used here, since we have all the *
* information and just need to reconstruct the dsegitem. Hence we *
* also need to recalculate total_data_size in here. Also, for uninit *
* data segments we add a false data area. *
************************************************************************/
bool dataseg::read_item(savefile *sf,byte *filebuff)
{ dword num,nlen;
dsegitemsave structsave;
dsegitem *currseg;
currseg=new dsegitem;
if(!sf->sread(&structsave,sizeof(dsegitemsave),&num))
return false;
currseg->addr=structsave.addr;
currseg->size=structsave.size;
currseg->data=structsave.fileoffset+filebuff;
currseg->typ=structsave.typ;
// total_data_size increased
total_data_size+=currseg->size;
if(structsave.name)
{ if(!sf->sread(&nlen,sizeof(dword),&num))
return false;
currseg->name=new char[nlen];
if(!sf->sread(currseg->name,nlen,&num))
return false;
}
else currseg->name=NULL;
// uninitdata - add false data area
if(currseg->typ==uninitdata)
{ currseg->data=new byte[currseg->size];
for(nlen=0;nlen<currseg->size;nlen++)
(currseg->data)[nlen]=0;
}
addto(currseg);
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -