前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[系统安全] 五十六.恶意软件分析 (8)IDA Python基础用法及CFG控制流图提取详解[下]

[系统安全] 五十六.恶意软件分析 (8)IDA Python基础用法及CFG控制流图提取详解[下]

作者头像
Eastmount
发布2024-05-17 14:27:05
1510
发布2024-05-17 14:27:05
举报

“2024年4月28日是Eastmount的安全星球 —— 『网络攻防和AI安全之家』正式创建和运营的日子,该星球目前主营业务为 安全零基础答疑、安全技术分享、AI安全技术分享、AI安全论文交流、威胁情报每日推送、网络攻防技术总结、系统安全技术实战、面试求职、安全考研考博、简历修改及润色、学术交流及答疑、人脉触达、认知提升等。下面是星球的新人券,欢迎新老博友和朋友加入,一起分享更多安全知识,比较良心的星球,非常适合初学者和换安全专业的读者学习。 ”

该系列文章将系统整理和深入学习系统安全、逆向分析和恶意代码检测,文章会更加聚焦,更加系统,更加深入,也是作者的慢慢成长史。漫漫长征路,偏向虎山行。享受过程,一起奋斗~

前文介绍了IDA Python配置过程和基础用法。这篇文章将尝试利用IDA Python提取恶意软件的控制流图(CFG),再为后续的恶意软件家族分类或溯源提供帮助。由于作者是初学者,因此会遇到很多问题,欢迎各位大佬和读者指导,同时感谢李师弟的指导和交流。基础性基础,且看且珍惜。

文章目录:

  • 一.测试样本生成
  • 二.IDA手动提取CFG
    • 1.IDA概述
    • 2.IDA手动保存CFG
  • 三.IDA Python提取CFG
    • 1.函数提取
    • 2.样本提取
  • 四.CFG提取问题
  • 五.总结

作者的github资源:

  • 逆向分析:
    • https://github.com/eastmountyxz/ SystemSecurity-ReverseAnalysis
  • 网络安全:
    • https://github.com/eastmountyxz/ NetworkSecuritySelf-study

声明:本人坚决反对利用教学方法进行犯罪的行为,一切犯罪行为必将受到严惩,绿色网络需要我们共同维护,更推荐大家了解它们背后的原理,更好地进行防护。(参考文献见后)


一.测试样本生成

首先,我们编写一段C语言程序并生成对应的可执行文件。如下图所示:

该程序逻辑比较简单,包含一个条件语句、一个循环语句和一个函数调用。

代码语言:javascript
复制
#include <stdio.h>

int sub_num(int a, int b) {
    int s;
    s = a + b;
    printf("函数运算结果: %d\n",s);
    return s;
}

int main() {
    int i,m,n;
    int result=0;

    scanf("%d %d",&m,&n);
    printf("输入的数字为:%d %d",m,n);

    //条件语句
    if (m>10) {
        printf("数字大于10\n");
    }
    else {
        printf("数字小于等于10\n");
    }

    //循环语句
    for (i=0; i<=10; i++) {
        result += i;
        i++;
    }
    printf("1 + 2 + ... + 10 = %d\n",result);
    
    //函数
    result = result + sub_num(m,n);
    printf("最终输出结果: %d\n",result);
    return 0;
}

输出结果如下图所示:

编译生成的中间文件如下所示:


二.IDA手动提取CFG

接着介绍IDA Python配置过程,并讲解如何实现IDA手动提取控制流图(CFG)。

1.IDA概述

IDA Pro(Interactive Disassembler Professional)简称“IDA”,是Hex-Rays公司出品的一款交互式反汇编工具,是目前最棒的一个静态反编译软件,为众多0day世界的成员和ShellCode安全分析人士不可缺少的利器。IDA Pro具有强大的功能,但操作较为复杂,需要储备很多知识,同时,它具有交互式、可编程、可扩展、多处理器等特点,可以通过Windows或Linux、MacOS平台来分析程序, 被公认为最好的逆向工程利器之一。

第一步,打开IDA Pro32软件选择一个exe文件载入,它将是我们要进行分析的程序,所分析的程序时上面撰写的C语言代码。

  • 在“Load a new file”窗口中选择装载PE文件,包括text(代码块)、data(数据块)、rsrc(资源块)、idata(输入表)和edata(输出表)等,也可以载入二进制文件。

IDA反汇编包括两个阶段,首先将程序的代码和数据分开,分别标记函数并分析参数调用、跳转、指令关系等;接着如果IDA能识别文件的编译类型,就装载对应的编译器特征文件,给各函数赋名。同时,IDA会创建一个数据库,其组件分别保存在“.id0”、“.id1”、“.nam”和“.til”的文件里。

第二步,在弹出确认窗口中选择“Don’t show this message again”选项,在“Check for Hex-Rays product updates”中点击“OK”。运行结果如下图所示,接着可以开始我们的逆向分析。

第三步,选择“_main_0”函数查看程序的控制流图,下图可以看到代码及部分注释。

第四步,按下F5能够查看对应的源代码,另一个自定义函数为,可以查看其加分操作。

  • v3 = sub_401005(v7, v6);

第五步,可以在Graph View和Text View中切换。

最后,关闭IDA Pro并保存数据库文件,下次载入时,可以直接加载数据库文件,获取之前分析的状态。


2.IDA手动保存CFG

函数调用图 在菜单栏中点击“view–>graphs–>Function calls”,查看函数调用图。

显示结果如下图所示:

  • 为啥显示这么复杂呢?
  • 如何提取关键函数的调用关系呢?

函数流程图 在菜单栏中点击“view–>graphs–>flowt chart”,查看函数流程图,其显示效果与IDA自带的反汇编流程视图相似。

在WinGraph中点击“file–>save as”,将调用关系另存为GDL(graph discription language)文本为test01.gdl。

保存的文件结果显示如下:


三.IDA Python提取CFG

该部分感谢李师弟的帮助,通过IDA Python批量提取样本的CFG,并生成gdl文件。整个工作目录如下所示:

代码语言:javascript
复制
- get_cfg.py
- get_cfg_main.py
- get_sample_cfg.py
- sample
  - test01.exe

1.函数提取

首先定义主函数,通过主函数调用IDA软件和样本的路径,并构建analyse_module函数分析样本的CFG。关键代码如下所示:

代码语言:javascript
复制
# coding: utf-8
# By:Eastmount & LJC 2024-05-10
import os

#完整路径跨目录调用
IDA_PATH = r"C:\Software\IDAPro7.5\ida.exe"
IDA64_PATH = r"C:\Software\IDAPro7.5\ida64.exe"
analyser = r"D:\test_cfg\get_cfg.py"

#命令行脚本批量获取样本cfg
def analyse_module(sample_list, sample_name):
    ida_exe = IDA_PATH
    for i in range(len(sample_list)):
        sample = sample_list[i]
        name = sample_name[i]
        cmd = " ".join([ida_exe, f"-c -A -S" + '"' + analyser + ' ' + name + '"',  sample])
        print(cmd)
        os.system(cmd)

    return True

if __name__ == '__main__':
    #批量样本地址
    file_path = r'D:\test_cfg\sample'
    sample_name = os.listdir(file_path)
    sample_list = []
    for i in range(len(sample_name)):
        sample = file_path + '\\' + sample_name[i]
        print(sample)
        sample_list.append(sample)

    analyse_module(sample_list, sample_name)
    print("over!!!")

接着调用get_cfg.py文件分别提取函数CFG信息,关键代码如下所示:

  • get_func_name
  • idaapi.get_func
  • idc.get_func_attr
  • gen_flow_graph
代码语言:javascript
复制
#coding: utf-8
# By:Eastmount & LJC 2024-05-10
import idaapi
import ida_gdl
import idautils
import idc

def main():

    functions = idautils.Functions()
    
    for func_ea in functions:
        func_name = idc.get_func_name(func_ea)
        func = idaapi.get_func(func_ea)
        start_ea = idc.get_func_attr(func_ea, FUNCATTR_START)
        end_ea = idc.get_func_attr(func_ea, FUNCATTR_END)
        gdl_file_name = "CFG_{}.gdl".format(func_name)
        flowchart = idc.gen_flow_graph(gdl_file_name, "cfg", start_ea, end_ea, CHART_GEN_GDL)
        if flowchart:
            print("CFG for function {} has been saved as {}".format(func_name, gdl_file_name))
        else:
            print("Failed to save CFG for function {}".format(func_name))

if __name__ == "__main__":
    idaapi.auto_wait()
    main()
    idc.qexit(0)

运行结果如下图所示:

该程序成功提取了各函数的CFG并生成gdl文件,然后部分函数是系统自带(未被使用)也被提取。


2.样本提取

接着调用get_sample_cfg.py文件分别提取样本的CFG信息,核心思想是捕获最大地址和最小地址之间的内容,关键代码如下所示:

代码语言:javascript
复制
#coding: utf-8
# By:Eastmount & LJC 2024-05-10
import idautils
import ida_gdl
import idaapi
import idc
import time

#根据样本最小地址和最大地址生成整个样本的cfg
def main(name):
    start_ea = ida_ida.inf_get_min_ea()
    end_ea = ida_ida.inf_get_max_ea()
    print(start_ea)
    print(end_ea)
    filename = '{}_cfg.gdl'.format(name)
    flowchart = idc.gen_flow_graph(filename, "cfg", start_ea, end_ea, CHART_GEN_GDL)
    print(flowchart)
    time.sleep(5)

if __name__ == "__main__":
    idaapi.auto_wait()
    main(idc.ARGV[1])
    idc.qexit(0)

运行结果如下图所示:

并且生成和保存两个文件,文件内容如下所示。

  • test01.exe.idb
  • test01.exe_cfg.gdl

至此,成功利用IDA Python提取样本的CFG。


四.CFG提取问题

然后当前代码存在几个问题:

  • 提取了很多不关键的函数或系统函数,如何提取关键函数呢?
  • 是否能利用angr工具实现呢?
  • 如何将gdl文件转换为特征向量供模型学习呢?
  • 如何利用工具显示gdl文件(easy-graph转换成图)

如下图所示,IDA Python提取并生成的gdl文件远远大于导出的文件,并且包含大量系统函数,这些冗余信息会干扰实验分析。

  • test01.exe.idb
  • test01.exe_cfg.gdl(929KB):本文Python代码提取
  • test01.gdl(3.92KB):IDA手工导出

手工导出gdl文件。


五.总结

写到这里,这篇文章就介绍完毕,希望对您有所帮助。

  • 一.测试样本生成
  • 二.IDA手动提取CFG 1.IDA概述 2.IDA手动保存CFG
  • 三.IDA Python提取CFG 1.函数提取 2.样本提取
  • 四.CFG提取问题
  • 五.总结

『网络攻防和AI安全之家』目前收到了很多博友、朋友和老师的支持和点赞,尤其是一些看了我文章多年的老粉,购买来感谢,真的很感动,类目。未来,我将分享更多高质量文章,更多安全干货,真心帮助到大家。虽然起步晚,但贵在坚持,像十多年如一日的博客分享那样,脚踏实地,只争朝夕。继续加油,再次感谢!

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-05-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 娜璋AI安全之家 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一.测试样本生成
  • 二.IDA手动提取CFG
    • 1.IDA概述
      • 2.IDA手动保存CFG
      • 三.IDA Python提取CFG
        • 1.函数提取
          • 2.样本提取
          • 四.CFG提取问题
          • 五.总结
          相关产品与服务
          高级威胁追溯系统
          腾讯高级威胁追溯系统(Advanced Threat Tracking System,ATTS)由腾讯安全团队构建的高级威胁追溯平台,旨在帮助用户通过该平台进行线索研判,攻击定性和关联分析,追溯威胁源头,有效预测威胁的发生并及时预警。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档