📄 disasm.cpp
字号:
* - disassembles a string at location loc. *
* - also names the location using the string. *
* - Unicode Pascal style *
************************************************************************/
void disasm::disdataupstring(lptr loc)
{ // unicode pascal style string.
dsegitem *dblock;
dsmitem *newdsm;
word tlen;
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;
maxlen-=1;
actuallen=0;
tlen=((word *)(dblock->data+(loc-dblock->addr)))[0];
while(tlen)
{ actuallen++;
tlen--;
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[4];
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-1)*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;
}
/************************************************************************
* disdatadosstring *
* - disassembles a string at location loc. *
* - also names the location using the string. *
* - DOS style *
************************************************************************/
void disasm::disdatadosstring(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[2];
newdsm->length=(word)actuallen; // string length
newdsm->data=dblock->data+(loc-dblock->addr);
if(checkvalid(newdsm))
{ callit[0]='s';
callit[1]='_';
callit[GNAME_MAXLEN]=0;
if(actuallen>GNAME_MAXLEN-2)
lstrcpyn(callit+2,(char *)newdsm->data,GNAME_MAXLEN-3);
else
lstrcpyn(callit+2,(char *)newdsm->data,actuallen);
cleanstring(callit);
addto(newdsm);
name.addname(newdsm->addr,callit);
//check if need to update window.
dio.updatewindowifinrange(loc);
}
else
delete newdsm;
}
/************************************************************************
* disdatageneralstring *
* - disassembles a string at location loc. *
* - also names the location using the string. *
* - general string is defined as printable characters *
************************************************************************/
void disasm::disdatageneralstring(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(isprint((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[2];
newdsm->length=(word)actuallen; // string length
newdsm->data=dblock->data+(loc-dblock->addr);
if(checkvalid(newdsm))
{ callit[0]='s';
callit[1]='_';
callit[GNAME_MAXLEN]=0;
if(actuallen>GNAME_MAXLEN-2)
lstrcpyn(callit+2,(char *)newdsm->data,GNAME_MAXLEN-3);
else
lstrcpyn(callit+2,(char *)newdsm->data,actuallen);
cleanstring(callit);
addto(newdsm);
name.addname(newdsm->addr,callit);
//check if need to update window.
dio.updatewindowifinrange(loc);
}
else
delete newdsm;
}
/************************************************************************
* disdatapstring *
* - disassembles a string at location loc. *
* - also names the location using the string. *
* - Pascal style *
************************************************************************/
void disasm::disdatapstring(lptr loc)
{ dsegitem *dblock;
dsmitem *newdsm;
byte tlen;
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;
tlen=(dblock->data+(loc-dblock->addr))[0];
while(tlen)
{ actuallen++;
tlen--;
maxlen--;
if(!maxlen)
return;
}
actuallen++;
if(actuallen>0xffff)
return; // tooo big
newdsm=new dsmitem;
initnewdsm(newdsm,loc,dsmcode);
newdsm->tptr=&asmstr[1];
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+1,GNAME_MAXLEN-3);
}
else
{ callit[actuallen+2]=0;
lstrcpyn(callit+2,(char *)newdsm->data+1,actuallen);
}
cleanstring(callit);
addto(newdsm);
name.addname(newdsm->addr,callit);
//check if need to update window.
dio.updatewindowifinrange(loc);
}
else
delete newdsm;
}
/************************************************************************
* disdata *
* - disassembles a dataitem, the common parts of the routines which *
* disassemble particular types (words,dwords, etc) *
************************************************************************/
void disasm::disdata(lptr loc,asminstdata *asmwd,byte len,byteoverride overr)
{ dsegitem *dblock;
dsmitem *newdsm;
dblock=dta.findseg(loc);
if(dblock==NULL)
return;
newdsm=new dsmitem;
initnewdsm(newdsm,loc,dsmcode);
newdsm->tptr=asmwd;
newdsm->length=len;
newdsm->data=dblock->data+(loc-dblock->addr);
newdsm->override=overr;
if(checkvalid(newdsm))
{ addto(newdsm);
//check if need to update window.
dio.updatewindowifinrange(loc);
}
else
delete newdsm;
}
/************************************************************************
* disdataword *
* - disassembles a word at location loc. *
************************************************************************/
void disasm::disdataword(lptr loc)
{ disdata(loc,&asmword[0],2,over_null);
}
/************************************************************************
* disdatadword *
* - disassembles a dword at location loc. *
************************************************************************/
void disasm::disdatadword(lptr loc)
{ disdata(loc,&asmdword[0],4,over_null);
}
/************************************************************************
* disdatasingle *
* - disassembles a single (float) at location loc. *
************************************************************************/
void disasm::disdatasingle(lptr loc)
{ disdata(loc,&asm_fp[0],4,over_null);
}
/************************************************************************
* disdatadouble *
* - disassembles a double (float) at location loc. *
************************************************************************/
void disasm::disdatadouble(lptr loc)
{ disdata(loc,&asm_fp[1],8,over_null);
}
/************************************************************************
* disdatalongdouble *
* - disassembles a long double at location loc. *
************************************************************************/
void disasm::disdatalongdouble(lptr loc)
{ disdata(loc,&asm_fp[2],10,over_null);
}
/************************************************************************
* disdatadsoffword *
* - disassembles an offset data item stored at a location *
* - short for disdatadword and changing it to an offset,ie dword offset *
************************************************************************/
void disasm::disdatadsoffword(lptr loc)
{ disdata(loc,&asmdword[0],4,over_dsoffset);
}
/************************************************************************
* addcomment *
* - called to add an auto comment to the disassembly, where the auto *
* comment will be edittable by the user. this is used in resource *
* analysis. *
************************************************************************/
void disasm::addcomment(lptr loc,char *comment)
{ char *nm;
nm=new char[strlen(comment)+1];
strcpy(nm,comment);
disautocomment(loc,dsmcomment,(unsigned char *)nm);
}
/************************************************************************
* disname_or_ordinal *
* - part of the resource item analysis, this looks for either an *
* ordinal number, or a name, and disassembles the data adding auto *
* comments too. *
************************************************************************/
int disasm::disname_or_ordinal(lptr loc,bool comment_ctrl)
{ dsegitem *dblock;
dword maxlen,idnum;
dblock=dta.findseg(loc);
if(dblock==NULL)
return 0;
maxlen=dblock->size-(loc-dblock->addr);
if(maxlen<2)
return 0;
idnum=((word *)(dblock->data+(loc-dblock->addr)))[0];
if(idnum==0xffff) // ordinal follows
{ disdataword(loc);
idnum=((word *)(dblock->data+(loc-dblock->addr)))[1];
disdataword(loc+2);
// ctrl class -> add description for class
if(comment_ctrl)
{ switch(idnum)
{ case 0x0080:
addcomment(loc+2,"[Button]");
break;
case 0x0081:
addcomment(loc+2,"[Edit]");
break;
case 0x0082:
addcomment(loc+2,"[Static]");
break;
case 0x0083:
addcomment(loc+2,"[List Box]");
break;
case 0x0084:
addcomment(loc+2,"[Scroll Bar]");
break;
case 0x0085:
addcomment(loc+2,"[Combo Box]");
break;
default:
break;
}
}
return 4;
}
disdataucstring(loc);
return getlength(loc);
}
/************************************************************************
* disdialog *
* - disassembles a dialog resource, by which I mean that data items are *
* disassembled to dwords, strings, etc, and the whole lot is *
* commented with what the fields are *
* - at the moment basename is unused, for future refinement ? *
************************************************************************/
#ifdef __BORLANDC__
#pragma warn -par
#endif
void disasm::disdialog(lptr loc,char *basename)
{ lptr cloc;
int ilen,numctrls;
dsmitem *findit;
bool exd;
dsegitem *dblock;
dword maxlen,idnum,hdrstyle;
// ho hum, things are never simple
// - after adding the dialog format i found that some dialogs were just completely
// different - the so called dialogex dialogs, and after much hunting around i found
// some details on microsofts site (wow). so then i hacked the code up to do it....
// dialog header
exd=false;
dblock=dta.findseg(loc);
if(dblock==NULL)
return;
maxlen=dblock->size-(loc-dblock->addr);
if(maxlen<4)
return;
idnum=((dword *)(dblock->data+(loc-dblock->addr)))[0];
if(idnum==0xffff0001)
exd=true; // whoah, dialogex found
/* basic struct is as follows:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -