1.IDA反編譯生成c代碼時,有時會出現sp-analysis failed錯誤。這一般是由于IDA分析某個外部函數call時出現了堆棧指針調整錯誤。可以先設置菜單option->General->Disassembly選中stack pointer.然后逐行看看哪些調用前后堆棧出現了偏差。
2.IDA可以通過定義struct/enum來增強生成C代碼的可讀性。但有時候在分析一個程序時定義的結構在另一個文件中也可能有用。這時怎樣處理呢。答案是先導出,再導入。
結構體的導出可參見http://bbs.pediy.com/showthread.php?t=99931
導入比較簡單,通過“菜單Load file/Parse C header file”直接導入頭文件。導入成功后,在Structures里就可以insert,然后Add standard structure中去查找了。導入之后在local types可見,而后全選右鍵同步即可。
結構體導出的代碼保存在這里,便于查閱。
#include "idc.idc"
static Save2HStart(ofile)


{
writestr(ofile,"/***************************************************************************************\n");
writestr(ofile,"本程序用來導出結構體.并且暫時支持BYTE,WORD,DWORD和結構體。其他的類型被轉換成BYTE數組.\n");
writestr(ofile,"如需支持其他的數據類型請自己在函數Save2HAddItem內加入.\n");
writestr(ofile," Author GUANRI\n");
writestr(ofile," 2009年11月8日\n");
writestr(ofile,"****************************************************************************************/\n");
writestr(ofile,"#include \"stdafx.h\"\n");
writestr(ofile,"#include \"windows.h\"\n");
writestr(ofile,"#ifndef _WRITE_BY_GRUANRI_\n");
writestr(ofile,"#define _WRITE_BY_GRUANRI_\n");
}
static Save2HEnd(ofile)


{
writestr(ofile,"#endif");
}
static Save2HAddItem(ofile,id,add)


{
auto type,itemsize,MemName;
type = GetMemberFlag(id,add) & DT_TYPE;
if ( type == FF_BYTE )

{
type = "BYTE";
itemsize=GetMemberSize(id,add);
}
else if ( type == FF_WORD )

{
type = "WORD";
itemsize=GetMemberSize(id,add)/2;
}
else if ( type == FF_DWRD )

{
type = "DWORD";
itemsize=GetMemberSize(id,add)/4;
}
else if ( type == FF_DWRD )

{
type = "DWORD";
itemsize=GetMemberSize(id,add)/4;
}
else if ( type == FF_STRU )

{
type = GetStrucName(GetMemberStrId(id,add));
itemsize=GetMemberSize(id,add)/GetStrucSize(GetMemberStrId(id,add));
}
else

{
type = "BYTE";
itemsize=GetMemberSize(id,add);
}
MemName=GetMemberName(id,add);
if(MemName=="")

{
return;
}
writestr(ofile," "+type+" "+MemName);
if(itemsize!=1)

{
writestr(ofile,"["+ltoa(itemsize,10)+"];\n");
}
else

{
writestr(ofile,";\n");
}
}
static Save2HAddItems(ofile,id)


{
auto add,MemName;
for ( add= 0;(add!=GetStrucSize(id))&&(add!=-1);add=GetStrucNextOff(id,add) )

{
MemName=GetMemberName(id,add);

if (strstr(MemName,"::")==-1)

{
Save2HAddItem(ofile,id,add);
}
else

{
return;
}

}
}
static Save2HStruct(ofile,id)


{
auto structname;
structname=GetStrucName(id);
writestr(ofile,"/***************************************************************************************\n");
writestr(ofile,"結構體名稱:"+GetStrucName(id)+"\n");
writestr(ofile,"固定 注釋:"+GetStrucComment(id,0)+"\n");
writestr(ofile,"重復 注釋:"+GetStrucComment(id,1)+"\n");
writestr(ofile,"結構體大小:"+ltoa(GetStrucSize(id),10)+"\n");
writestr(ofile,"成員 個數:"+ltoa(GetMemberQty(id),10)+"\n");
writestr(ofile,"****************************************************************************************/\n");
writestr(ofile,"typedef struct \n");
writestr(ofile," {\n");
Save2HAddItems(ofile,id);
writestr(ofile," }"+structname+",*p"+structname+";\n");
}
static main()


{
auto file,filename,idx,id,structname;
filename=AskFile(1,"*.h","保存頭文件名");
if(filename==0)

{
Warning("請輸入一個文件名,謝謝!!!!!!");
return;
}
file=fopen(filename,"w+");
Message("寫入中"+filename+"\n");
Save2HStart(file);

for ( idx=GetFirstStrucIdx(); idx != -1; idx=GetNextStrucIdx(idx) )

{
id=GetStrucId(idx);
structname=GetStrucName(id);

if(strstr(structname,"::")==-1) //這個是過濾結構名帶::的

{
Save2HStruct(file,id);
Message("結構名: "+structname+"\n");
}
}
Save2HEnd(file);
fclose(file);
}