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);
}