本帖最后由 乔延臣 于 2014-12-23 10:12 编辑
引用:http://grapeel.com/?p=251 问题描述: 如何批量获取PE文件的汇编代码.asm以及.asm文件中的函数标志位? 如下图所示,最右边的R、F、L等就是函数的标志位,其中L表示Library Function,这些函数都是从系统库中调用的,在分析时一般情况下是不需要分析的,只要根据函数名字了解了这个函数的功能就够了,所以需要根据标志位把这些函数区分出来。 解决方案: 借鉴自: 批量模式:http://bbs.pediy.com/showthread.php?t=147777 函数信息:http://blog.csdn.net/whatday/article/details/8630354 由于没有深入研究IDA,所以只能借鉴别人的工作,在别人工作基础上修改运用。 在IDA的根目录下有个idc目录,是存储以idc语言编写插件的一个目录,目录下的ida.idc是IDA启动时调用的一个插件,当批量模式idaw.exe执行时也会调用。 首先在该目录下新建一个idc文件,可以以export_func_flag.idc命名,具体代码如下: #include <idc.idc>
static export_func_flag()
{
auto addr,path,file,imagebase;
file = fopen(GetInputFilePath(),"rb");
if (0 == file)
{
Warning("open INPUTFILE failed!");
return;
}
if (0 != fseek(file,0x3c,0))
{
Warning("seek e_lfanew failed!");
fclose(file);
return;
}
imagebase = readlong(file,0);
if (0 != fseek(file,imagebase + 0x34,0))
{
Warning("seek imagebase failed!");
fclose(file);
return;
}
imagebase = readlong(file,0);
fclose(file);
path = GetInputFilePath()+".lu";
if (BADADDR == path)
{
Warning("AskFile failed!");
return;
}
file = fopen(path,"w");
if (0 == file)
{
Warning("fopen failed!");
return;
}
addr = MinEA();
auto x, y;
if ("" != GetFunctionName(addr))
{
fprintf(file,"%s",GetFunctionName(addr));
x = GetFunctionFlags(addr);
if (x & FUNC_LIB)
fprintf(file, "\t0");
else
fprintf(file, "\t1");
fprintf(file, "\n");
}
for(addr = NextFunction(addr);BADADDR != addr;addr = NextFunction(addr))
{
fprintf(file,"%s",GetFunctionName(addr));
x = GetFunctionFlags(addr);
if (x & FUNC_LIB)
fprintf(file, "\t0");
else
fprintf(file, "\t1");
fprintf(file, "\n");
}
fclose(file);
Message("output functions' names finished!");
} 之后,在ida.idc的#include <idc.idc>下添加上#include <export_func_flag.idc>,并在main函数中加入两行代码,如下所示: static main(void)
{
//
// This function is executed when IDA is started.
//
// Add statements to fine-tune your IDA here.
//
// Instantiate the breakpoints singleton object
Breakpoints = BreakpointManager();
//AddHotkey("Alt-9","CamelLu");
Wait();
export_func_flag();
// uncomment this line to remove full paths in the debugger process options:
// SetCharPrm(INF_LFLAGS, LFLG_DBG_NOPATH|GetCharPrm(INF_LFLAGS));
} 记住,一定要加上Wait();这行代码,否则在未逆向完全时就输出,得到的信息不完整。 之后,需要再在这个目录中新建一个批量模式脚本,命名为myanalysis.idc,代码如下: #include <idc.idc>
static main()
{
// turn on coagulation of data in the final pass of analysis
SetShortPrm(INF_AF2, GetShortPrm(INF_AF2) | AF2_DODATA);
Message("Waiting for the end of the auto analysis...\n");
Wait();
Message("\n\n------ Creating the output file.... --------\n");
auto file = GetInputFilePath() + ".asm";
WriteTxt(file, 0, BADADDR); // create the assembler file
Message("All done, exiting...\n");
Exit(0); // exit to OS, error code 0 - success
} 批量模式的命令行为: idaw -A -c -Smyanalysis.idc pe.exe 这样就会得到idb文件、asm文件以及lu文件,其中lu文件为函数信息文件。 0表示是Library Function,1表示是正常文件。 当然这是IDA根据sig目录下的指纹识别的,若是没有相关的库,那也就识别不出是否是Library Function了。
|