IDC资源自动添加注释
功能:分析资源段数据并自动添加注释,寻找代码段中的资源号并添加注释,改进中,fx_ffx@163.com
//-------------------------------------------------------------------
#include <idc.idc>
#include <uni2gb.idc>
static FindAllSeg() { // find all seg
auto next;
auto name;
auto lasttype;
lasttype="";
next = FirstSeg();
do{
name = SegName(next);
Message("Seg=%s\n",name);
if(GetSegType(next)==1) AnalyseCodeSeg(next);
//if(GetSegType(next)==5) GetRsrc(next,1,lasttype);
} while ( (next=NextSeg(next)) != -1 );
}
static AnalyseCodeSeg(seg)
{
auto nStartAddr; //起始地址=0x401000
auto nResult; //找到的地址
auto bFound;
auto nOperand; //当前地址的第1个operand
auto nOperandType; //当前operand类型,5为Immediate
auto ea1;
auto ea2;
ea1=SegStart(seg);
Message("Segstart=%08X\n",ea1);
ea2=SegEnd(seg);
Message("SegsEnd=%08X\n",ea2);
nStartAddr=ea1;
do //扫描IDB的CODE段
{
//bFound=Comments(nStartAddr);
bFound=CommentEx(nStartAddr,0);
if(bFound=="uID")
{
Message("text:%08X ",nStartAddr);
Message("Comments=%s\n",bFound);
}
nStartAddr=NextNotTail(nStartAddr); //更新地址
}while((nStartAddr<ea2)&&(nResult!=BADADDR)); //在DATA段前结束
}
static FindRsrcSeg() { //
auto next;
auto name;
next = FirstSeg();
do{
name = SegName(next);
if(GetSegType(next)==5) return next;
} while ( (next=NextSeg(next)) != -1 );
return 0;
}
static GetRsrc(seg,level,lasttype){
auto ea;
auto type,id;
auto i,t;
auto sz,s1;
auto addrinname,addrinid;
s1="";
for(i=1;i<level;i++)
s1=s1+" ";
MakeDword(seg);
MakeComm(seg,form("Characteristics=%X",Dword(seg)));
MakeDword(seg+4);
MakeComm(seg+4,form("TimeDataStamp=%X",Dword(seg+4)));
MakeWord(seg+8);
MakeComm(seg+8,form("MajorVersion=%X",Word(seg+8)));
MakeWord(seg+10);
MakeComm(seg+10,form("MinorVersion=%X",Word(seg+10)));
MakeWord(seg+12);
MakeComm(seg+12,form("NumberOfNameedEntries=%ld",Word(seg+12)));
MakeWord(seg+14);
MakeComm(seg+14,form("NumberOfIdEntries=%ld",Word(seg+14)));
addrinname=seg+16;
if(Word(seg+12)>0)
{
if(Word(seg+12)>1)
Message(s1+form("NOfNm=%d\n",Word(seg+12)));
for(i=0;i<Word(seg+12);i++)
{
sz=GetResourceType(addrinname+i*8,level);
MakeDword(addrinname+i*8);
MakeComm(addrinname+i*8,sz);
Message(form("(%d) %s\n",i+1,sz));
ea=FindRsrcSeg()+Dword(addrinname+i*8+4)&0x7fffffff;
MakeDword(addrinname+i*8+4);
MakeComm(addrinname+i*8+4,atoa(ea));
id=lasttype+"\n"+sz;
if(Dword(addrinname+i*8+4)&0x80000000)
GetRsrc(ea,level+1,id);
else
GetRsrcData(ea,id);
}
}
addrinid=addrinname+8*Word(seg+12);
if(Word(seg+14)>0)
{
if(Word(seg+14)>1)
Message(s1+form("NOfId=%d\n",Word(seg+14)));
for(i=0;i<Word(seg+14);i++)
{
sz=GetResourceType(addrinid+i*8,level);
MakeDword(addrinid+i*8);
MakeComm(addrinid+i*8,sz);
Message(s1+form("(%d) %s \n",i+1,sz));
ea=FindRsrcSeg()+Dword(addrinid+i*8+4)&0x7fffffff;
MakeDword(addrinid+i*8+4);
MakeComm(addrinid+i*8+4,atoa(ea));
//Message(s1+atoa(ea)+"\n");
id=lasttype+"\n"+sz;
if(Dword(addrinid+i*8+4)&0x80000000)
GetRsrc(ea,level+1,id);
else
GetRsrcData(ea,id);
}
}
}
static GetRsrcData(seg,lasttype){
auto ea;
auto i,t,size;
auto a1,a2;
auto id;
auto sz,s1;
auto addrinname,addrinid;
auto cm;
auto controlnum;
s1=" ";
MakeDword(seg);
MakeComm(seg,form("OffsetToData=%08X",Dword(seg)+0x400000));
Message(s1+form("OffsetToData=%08X\n",Dword(seg)+0x400000));
MakeComm(Dword(seg)+0x400000,form("::%s",lasttype));
MakeDword(seg+4);
MakeComm(seg+4,form("Size=%d",Dword(seg+4)));
Message(s1+form("Size=%d\n",Dword(seg+4)));
MakeDword(seg+8);
MakeComm(seg+8,form("CodePage=%X",Dword(seg+8)));
MakeDword(seg+12);
MakeComm(seg+12,form("Reserved=%X",Dword(seg+12)));
MakeByte(Dword(seg)+0x400000);
if(strstr(lasttype,"menu")!=-1)
{
a1=strstr(lasttype,"ID=");
a2=strstr(lasttype,"CodePage");
id=atol(substr(lasttype,a1+3,a2));
GetMenuData(seg);
}
if(strstr(lasttype,"dialog")!=-1)
{
a1=strstr(lasttype,"ID=");
a2=strstr(lasttype,"CodePage");
id=atol(substr(lasttype,a1+3,a2));
GetDialogData(seg,id);
}
if(strstr(lasttype,"string table")!=-1)
{
a1=strstr(lasttype,"ID=");
a2=strstr(lasttype,"CodePage");
id=atol(substr(lasttype,a1+3,a2));
GetStringData(seg,id);
}
}
static MakeStringComm(stringid,szComment){
auto nStartAddr; //起始地址=0x401000
auto nResult; //找到的地址
auto bFound;
auto nOperand; //当前地址的第1个operand
auto nOperandType; //当前operand类型,5为Immediate
nStartAddr=0x401000;
do //扫描IDB的CODE段
{
nResult=FindBinary(nStartAddr,SEARCH_NEXT|SEARCH_DOWN,"68"); //
//用"6A"再做一遍
if(nResult!=BADADDR)
{
nOperandType=GetOpType(nResult,0); //测试operand类型
if(nOperandType==5) //Immediate
{
nOperand=GetOperandValue(nResult,0);
if(nOperand==stringid) //匹配?
{
Message(form("\nFound at %X",nResult));
if(strstr(CommentEx(nResult,0),"uID")!=-1)
MakeComm(nResult,szComment); //注释
}
}
}
nStartAddr=NextAddr(nResult); //更新地址
}while((nStartAddr<0x48D000)&&(nResult!=BADADDR)); //在DATA段前结束
}
static GetStringData(seg,id)
{
auto ea;
auto i,t,size;
auto sz;
id=(id-1)*16;
t=0;
do{
ea=Dword(seg)+0x400000+t;
size=Word(ea);
MakeWord(ea);
MakeComm(ea,form("%s\nL:%d\nstringid=%d","String",size,id));
sz="";
if(size>0)
{
for(i=0;i<size;i++){
sz=sz+form("%s",uni2gb(Word(ea+2+i*2)));
MakeWord(ea+2+i*2);
MakeComm(ea+2+i*2,form("%s",uni2gb(Word(ea+2+i*2))));
}
MakeStringComm(id,sz);
}
Message(form(" stringid=%d ",id)+sz+"\n");
t=t+2+2*size;
id=id+1;
}while(t<Dword(seg+4));
}
static GetMenuData(seg)
{
auto ea;
auto t,cm;
t=0;
ea=Dword(seg)+0x400000;
MakeWord(ea);
MakeComm(ea,form("wVersion=0"));
t=t+2;
MakeWord(ea+t);
MakeComm(ea+t,form("cbHeaderSize=0"));
t=t+2;
do
{
MakeWord(ea+t);
MakeComm(ea+t,form("fItemFlags=%04X",Word(ea+t)));
cm=0;
if(!(Word(ea+t)&0x0010))
{
t=t+2;
MakeWord(ea+t);
MakeComm(ea+t,form("wMenuID=%d",Word(ea+t)));
}
t=t+2;
if(Word(ea+t)!=0)
{
do
{
MakeComm(ea+t,form("%s",uni2gb(Word(ea+t))));
Message(form("%s",uni2gb(Word(ea+t))));
t=t+2;
}while(Word(ea+t)!=0);
MakeComm(ea+t,form("str_Eof"));
Message(form("\n"));
}
t=t+2;
}while(t<Dword(seg+4));
}
static GetDialogData(seg,dialogid)
{
auto ea;
auto controlnum,i;
//Message("Dialog=%d\n",dialogid);
//ea=Dword(seg)+SegStart(GetSegByName(".text"));
ea=Dword(seg)+0x400000;
MakeUnknown(ea,4,1);
MakeDword(ea);
if(Dword(ea)==0xffff0001)
{
ea=ea+4;
MakeUnknown(ea,4,1);
MakeDword(ea);
ea=ea+4;
MakeUnknown(ea,4,1);
MakeDword(ea);
}
ea=ea+4;
MakeUnknown(ea,4,1);
MakeDword(ea);
MakeComm(ea,form("lExtendedStyle=",Dword(ea)));
ea=ea+4;
MakeWord(ea);
MakeComm(ea,form("Control num=%d",Word(ea)));
controlnum=Word(ea);
ea=ea+2;
MakeWord(ea);
MakeComm(ea,form("x=%d",Word(ea)));
ea=ea+2;
MakeWord(ea);
MakeComm(ea,form("y=%d",Word(ea)));
ea=ea+2;
MakeWord(ea);
MakeComm(ea,form("cx=%d",Word(ea)));
ea=ea+2;
MakeWord(ea);
MakeComm(ea,form("cy=%d",Word(ea)));
ea=ea+2;
MakeWord(ea);
if(Word(ea)!=0)
{
if(Word(ea)==0xffff)
{
ea=ea+2;
MakeWord(ea);
MakeComm(ea,form("menuname=%d",Word(ea)));
}
else
{
do{
MakeWord(ea);
MakeComm(ea,form("%s",uni2gb(Word(ea))));
ea=ea+2;
}while(Word(ea)!=0);
}
}
ea=ea+2;
MakeWord(ea);
if(Word(ea)!=0)
{
if(Word(ea)==0xffff)
{
ea=ea+2;
MakeWord(ea);
MakeComm(ea,form("classname=%d",Word(ea)));
}
else
{
do{
MakeWord(ea);
MakeComm(ea,form("%s",uni2gb(Word(ea))));
ea=ea+2;
}while(Word(ea)!=0);
}
}
//
do{
MakeWord(ea);
MakeComm(ea,form("%s",uni2gb(Word(ea))));
Message(form("%s",uni2gb(Word(ea))));
ea=ea+2;
}while(Word(ea)!=0);
Message("\n");
MakeWord(ea);
MakeComm(ea,form("str_Eof"));
ea=ea+2;
MakeWord(ea);
MakeComm(ea,form("wPointSize=%d",Word(ea)));
// Message(form("wPointSize=%d\n",Word(ea)));
ea=ea+2;
if(Dword(ea)==0x1000000)
ea=ea+4;
// Message(form("szFontName=%x\n",Word(ea)));
do{
MakeWord(ea);
MakeComm(ea,form("%s",uni2gb(Word(ea))));
// Message(form("%s",uni2gb(Word(ea))));
ea=ea+2;
}while(Word(ea)!=0);
Message("\n");
MakeWord(ea);
MakeComm(ea,form("str_Eof\n"));
ea=ea+2;
for(i=0;i<controlnum;i++)
{
if(ea%4!=0)
{
MakeWord(ea);
MakeComm(ea,"padding");
ea=((ea/4)+1)*4;
}
MakeUnknown(ea,4,1);
MakeDword(ea);
MakeComm(ea,form("[ lStyle=%x",Dword(ea)));
ea=ea+4;
MakeUnknown(ea,4,1);
MakeDword(ea);
MakeComm(ea,form("lExtendedStyle=%x",Dword(ea)));
if(Dword(ea)==0||Dword(ea)==0x20000||Dword(ea)==1)
{
if(Dword(ea-4)==0)
{
ea=ea+4;
MakeUnknown(ea,4,1);
MakeDword(ea);
MakeComm(ea,form("lExtendedStyle=%x",Dword(ea)));
}
}
ea=ea+4;
MakeWord(ea);//x
MakeComm(ea,form("x=%d",Word(ea)));
ea=ea+2;
MakeWord(ea);//y
MakeComm(ea,form("y=%d",Word(ea)));
ea=ea+2;
MakeWord(ea);//cx
MakeComm(ea,form("cx=%d",Word(ea)));
ea=ea+2;
MakeWord(ea);//cy
MakeComm(ea,form("cy=%d",Word(ea)));
ea=ea+2;
MakeWord(ea);//wid
MakeComm(ea,form("wId=%d",Word(ea)));
Message(form("wId=%x ",Word(ea)));
ea=ea+2;
if(Word(ea)==0)
ea=ea+2;
if(Word(ea)==0xffff)
{
MakeWord(ea);
MakeComm(ea,form("FFFF"));
ea=ea+2;
if(Word(ea)==0xffff)
{
MakeComm(ea,form("FFFF"));
ea=ea+2;
}
MakeWord(ea);
//MakeComm(ea,form("classid=%d\n",Word(ea)));
if(Word(ea)==0x80)
{MakeComm(ea,"BUTTON");Message("BUTTON ");}
if(Word(ea)==0x81)
{MakeComm(ea,"EDIT");Message("EDIT ");}
if(Word(ea)==0x82)
{MakeComm(ea,"STATIC");Message("STATIC ");}
if(Word(ea)==0x83)
{MakeComm(ea,"LISTBOX");Message("LISTBOX ");}
if(Word(ea)==0x84)
{MakeComm(ea,"SCROLLBAR");Message("SCROLLBAR ");}
if(Word(ea)==0x85)
{MakeComm(ea,"COMBOBOX");Message("COMBOBOX ");}
ea=ea+2;
}
else
ea=FindStrEndAddr(ea);
if(Word(ea)==0xffff)
{
MakeWord(ea);
MakeComm(ea,form("FFFF"));
ea=ea+2;
if(Word(ea)==0xffff)
{
MakeComm(ea,form("FFFF"));
ea=ea+2;
}
MakeWord(ea);
MakeComm(ea,form("text ordinal=%d",Word(ea)));
ea=ea+2;
}
else
{
Message(GetStr(ea));
ea=FindStrEndAddr(ea);
Message("\n");
}
MakeWord(ea);
MakeComm(ea,form("nExtraStuff=%d\n",Word(ea)));
ea=ea+2;
}
}
static FindStrEndAddr(ea)
{
do{
ea=ea+2;
}while(Word(ea)!=0);
ea=ea+2;
MakeWord(ea);
MakeComm(ea,form("str_Eof"));
return ea;//end addr
}
static GetStr(ea)
{
auto text,caption;
caption="";
do{
MakeWord(ea);
text=form("%s",uni2gb(Word(ea)));
MakeComm(ea,text);
caption=caption+text;
ea=ea+2;
}while(Word(ea)!=0);
return caption;
}
static GetSegType(seg)
{
auto name;
name=SegName(seg);
if ( substr(name,0,5) == ".text" ) return 1;
if ( substr(name,0,5) == ".idat" ) return 2;
if ( substr(name,0,5) == ".rdat" ) return 3;
if ( substr(name,0,5) == ".data" ) return 4;
if ( substr(name,0,5) == ".rsrc" ) return 5;
return 0;
}
//-------------------------------------------------------------------
static GetResourceType(seg,level) {
auto type;
auto t;
t=Dword(seg);
if(level==1){
if(t==1)type="cursor ";
if(t==2)type="bitmap ";
if(t==3)type="icon ";
if(t==4)type="menu ";
if(t==5)type="dialog ";
if(t==6)type="string table ";
if(t==7)type="font directory ";
if(t==8)type="font ";
if(t==9)type="accelerators ";
if(t==10)type="unformatted resource ";
if(t==11)type="message talbe ";
if(t==12)type="group cursor ";
if(t==14)type="group icon ";
if(t==16)type="version information ";
return type;
}
if(level==2){
return (form("ID=%d",t));
}
if(level==3){
return (form("CodePage=%d",t));
}
return 0; // couldn't determine rsc type
}
//-------------------------------------------------------------------
static main(void) {
auto ea;
auto type,id;
Message("Searching for resources...\n");
FindAllSeg();
Message("Done.\n");
//writeuni2gbdata();
}