第三章——静态分析技术-IDA的简单操作

 
  •     注释:按“:”输入的注释只会在该处出现,按“;”的注释会在所有的交叉参考处出现
 
  •     字符串搜索View->Open Subviews->String,此处字符串可与交叉引用结合使用
 
  •     按ESC退后,Ctrl+Enter前进
 
  •     重命名:N
 
  •     标签的使用:菜单项Jump->Mark position 打开标记位置,可以进行标记,当分析到后门按Ctrl+M可以查看标记的点
 
  •     代码和数据的转换:如果发现一段十六进制是一段指令,我们要做的需要将光标移至第一个字节,使用快捷键"C",即可,
                                  按“P”可以定义为某段代码定位为子程序,并列出参数调用
                                  按“U”可以将数据重新以16进制显示
                                  按“D”数据类型会在db,dw,dd直接转换
                                  数据类型转换可以通过“Options->Setup->data types”设置更多数据类型
 
  •     我们确定一串十六进制是字符串,可以通过快捷键“A”显示,当然按"A"默认是C语言字符串,也可以选择“Options->ASCII string style”设置完其他格式字符串

  

 
  • 当遇到数据为数组时,选择快捷键“ * ”来进行数组排列调整

    

 
  • Flirt快速识别与鉴定技术
            FLIRT技术的目的是为了每个可标识的库函数创建一个“签名”使IDA在分析时候能标识它
            如果IDA支持程序的编译器,但是FLIRT没有自动识别出来,就可以强制使用其编译器特征文件,例如:
            这里用一个Delphi5编写的程序演示,Delphi5的签名文件d5vcl.sig储存在IDASIG目录中,运行IDA,打开Delphi5.exe,我们发现

   

       我们看到这两个call没有被FLIRT识别到,这时就必须强行使用Delphi5的签名文件d5vcl.sig 

    

    

 
  • IDC脚本
            IDA可识别的脚本有两种,一种是IDC一种是python脚本。 这里举出两个例子来简要认识IDC脚本
             第一个,用IDC脚本读取导入表,以及用python脚本读取导入表(脚本代码在附件中)
   

     

          第二个,利用IDC分析加密代码
              实例程序中有两个关键call
    
          第一个call是对第二个call的解密过程,这段利用了SMC(自己修改自己的代码)技术,阅读这段代码后发现,解密过程较为简单,异或加密的过程
          加载IDC脚本解密。之后可以利用"Shift+F2"来对代码进行解密,输入关键解密操作——decrypt(0x00401060,0x15,0x1);
    
    回到源程序发现
    
 
 
python脚本
 1 #coding=utf-8
 2 
 3 def GetImportSeg():
 4     ea=FirstSeg()
 5     next=ea
 6     count=0
 7 
 8     while next != BADADDR:  #判断是否为".idata"段
 9         next=NextSeg(next)
10         name=SegName(next)
11         if name[0:6]=='.idata':
12             break
13     return next
14 
15 def main():
16     BytePtr=SegStart(GetImportSeg()) #确定idata段VA
17     EndImports=SegEnd(BytePtr)
18     print('
 Parsing import table...') 
19     while  BytePtr<EndImports:
20         if LineA(BytePtr,1):
21             print( '__'+LineA(BytePtr,1)+'__')
22         if Name(BytePtr): 
23             print(Name(BytePtr)+'
')  #显示当前地址的函数名
24         BytePtr=NextAddr(BytePtr)
25     print('Import table parsing complete
')
26 
27 if __name__=='__main__':
28     main()

 1 //Imports.idc 列出当前程序的输入函数
 2 //(c)  www.PEDIY.com 2000-2008
 3 
 4 #include <idc.idc>
 5 
 6 static GetImportSeg()
 7 {
 8     auto ea, next, name;
 9     ea = FirstSeg();
10     next = ea;
11     while ( (next = NextSeg(next)) != -1) {
12         name = SegName(next);
13         if ( substr( name, 0, 6 ) == ".idata" ) break;
14    }
15    return next;
16 }
17 
18 static main()
19 {
20     auto BytePtr, EndImports;
21     BytePtr = SegStart( GetImportSeg() );
22     EndImports = SegEnd( BytePtr );
23     Message(" 
" + "Parsing Import Table...
");
24     while ( BytePtr < EndImports ) {
25         if (LineA(BytePtr, 1) != "") Message("
" + "____" + LineA(BytePtr,1) + "____" + "
");
26         if (Name(BytePtr)!= "") Message(Name(BytePtr) + "
");
27         BytePtr = NextAddr(BytePtr);
28     }
29     Message("
" + "Import Table Parsing Complete
");
30 }
IDC导入表
 1 #include <idc.idc>
 2 static decrypt(from, size, key ) { 
 3    auto i, x; 
 4    for ( i=0; i < size; i=i+1 ) { 
 5       x = Byte(from); 
 6       x = (x^key); 
 7       PatchByte(from,x); 
 8       from = from + 1;
 9    } 
10  Message("
" + "Decrypt Complete
");
11 } 
IDC解密代码
原文地址:https://www.cnblogs.com/Tempt/p/10004690.html