首页
论坛
专栏
课程

[原创]使用IDA开发壳程序、自动化分析程序

5天前 1805

[原创]使用IDA开发壳程序、自动化分析程序

5天前
1805
(本篇主要内容为介绍IDAT的使用和一些编好的简便工具)

1 初衷:
是的,没有看错标题,
通常人们用IDA破解程序,
我选择用IDA开发程序,

事情是这样的,
编写保护壳/自动化静态分析的最开始,
通常需要 编写程序来分析PE、ELF结构/符号/引用/偏移量/指令信息,作为基础数据。
在指令集和文件格式众多的情况下,如果手动编码来做,相当耗费精力。

这部分功能,可以选择一些现有类库来完成,比如LIEF类库等。
实际上LIEF等类库功能还是有限,并不能满足开发者丰富的需求。

这里作者突然想到了宇宙最强静态分析工具IDA,
想办法导出它丰富的数据库内容,
作为开发保护壳/自动化分析的前提。


2 目录:

(1)如何导出IDA的分析结果

(2)介绍IDAT的使用

(3)一键生成IDAT命令

(4)编写IDAPY脚本

(5)一键批量调用IDAT


3 正文:

(1)如何导出IDA的分析结果

众所周知IDA分析可执行程序的最开始,会生成一个同名的idb文件,

在图形界面中看到的各种区段符号偏移信息,都存储在idb中,

IDA提供了python脚本接口来访问这些数据,

而IDA是一个GUI程序,不方便通过代码带执行IDAPY,

实际上IDA目录下还有一个命令行版本的IDAT,

可以将PY脚本传递给idat运行,接着脚本访问数据库内容,SAVE为文本。





(2) 介绍IDAT的使用

这个是IDAT使用的官网介绍, https://www.hex-rays.com/products/ida/support/idadoc/417.shtml

实际非常坑,脚本传参失败,也看不到日志,最开始用命令很难写规范。


这里给出一个实例格式参考:

>>>    idat.exe -A -L"日志.txt" -S"脚本.py 脚本参数" 目标二进制文件

>>>    idat.exe -A -L"log\libape__getallfunc.txt" -S"script\getallfunc.py output\libape__getallfunc.json" input\libape.so


(3) 一键生成IDAT命令

自己写命令,还是很麻烦,干脆写一个小程序,一键生成idat.exe命令

import sys,os

class IDAT:
    # ·作用:拼接出IDAT.EXE使用的的命令字符串
    # ·参数1:父级目录
    # ·参数2:二进制文件名
    # ·参数3:脚本文件名
    # ·参数4:输出文件名
    # .参数5:日志文件名
    # ·返回值:str cmd
    # ·使用前提:
    # 根目录下存在IDA_Pro_v7.0_Portable、intput、output、script、log文件夹
    # 并且so文件存在于intput下,脚本文件存在于script文件夹下,idat完整程序在IDA_Pro_v7.0_Portable下
    # 举例:root_path libape.so getallfunc.py libape__getallfunc.json libape__getallfunc.txt
    @staticmethod
    def get(root,bin,script,result,log):
        根目录 = root
        IDA可执行文件名 = 根目录 + "\\IDA_Pro_v7.0_Portable\\idat.exe"
        二进制文件名 = 根目录 + "\\input\\"  + bin
        脚本文件名   = 根目录 + "\\script\\" + script
        结果文件名   = 根目录 + "\\output\\" + result
        日志文件名   = 根目录 + "\\log\\" + log
        p1 = IDA可执行文件名
        p2 = " -A"
        p3 = " -L" + "\"" + 日志文件名 + "\""
        p4 = " -S" + "\"" + 脚本文件名
        p5 = " " + 结果文件名 + "\""
        p6 = " " + 二进制文件名
        cmd = p1 + p2 + p3 + p4 + p5 + p6
        return cmd

    # ·作用:通过命令行传参调用get
    # ·参数1:sys.argv
    # ·返回值:str cmd
    @staticmethod
    def exe(sys_argv):
        if (6 != len(sys.argv)):
            print("6 !=sys.argv.count(),fail.")
            return ""
        else:
            root = sys.argv[1]
            bin = sys.argv[2]
            script = sys.argv[3]
            result = sys.argv[4]
            log = sys.argv[5]
            return IDAT.get(root, bin, script, result,log)

if(__name__=="__main__"):
    # 输入为:C:\Users\HAHA\Desktop\haha libape.so getallfunc.py libape__getallfunc.json libape__getallfunc.txt
    cmd = IDAT.exe(sys.argv)
    print(cmd)

(4) 编写IDAPY脚本

idapy脚本的写法,这里举一个简单例子,遍历IDA分析出的BIN所有函数信息,并保存为JSON,

宇宙最强神器IDA,简单粗暴。。

# coding=UTF-8
import sys
import idc
import idaapi
import idautils

def save_json(path,content):
    with open(path, 'w+') as f:
        json.dump(fp=f, obj=content)
        return

def get_all_func():
    num = 0
    content = []
    for func in idautils.Functions():
        seg_perm = idc.get_segm_attr(func,SEGATTR_PERM)         # 段属性
        if(5 !=seg_perm):
            continue
        seg_name = idc.get_segm_name(func)                      # 段名
        if(".plt" == seg_name):
            continue
        
        func_name = idc.get_func_name(func)                     # 函数名
        func_flags = hex(idc.get_func_attr(func,FUNCATTR_FLAGS))# 函数信息
        func_head = hex(idc.get_func_attr(func,FUNCATTR_START)) # 函数头
        func_end = hex(idc.get_func_attr(func,FUNCATTR_END))    # 函数尾

        l = []
        l.append(num)
        l.append(seg_name)
        l.append(seg_perm)
        l.append(func_name)
        l.append(func_flags)
        l.append(func_head)
        l.append(func_end)
        content.append(l)
        
        num += 1
        #print(l)
    return content
        
# 程序入口
idaapi.autoWait()

path = idc.ARGV[1]
content = get_all_func()
save_json(path,content)
print("haha")

idc.Exit(0)

这里给出一个我整理的IDAPY最常用的API.


(5)一键批量调用IDAT

实际上,

我们可能有很多可执行程序,

有很多脚本模块(比如获取符号的,获取交叉引用的......),

所以挨个手动调用IDAT还是很麻烦,这里干脆再写个一键调用。


大致做法:

把可执行文件、IDAPY脚本文件、IDAPY日志、IDAPY输出都放在固定的目录下,然后

for i in 脚本列表:
    for k in 可执行列表:
        json = idat.(i,k);save(json)

完整工程代码参考:

https://github.com/acbocai/run_idat


调用效果




4 更多常用功能脚本编写中......

   





[公告]安全服务和外包项目请将项目需求发到看雪企服平台:https://qifu.kanxue.com

最后于 5天前 被爱吃菠菜编辑 ,原因:
上传的附件:
最新回复 (17)
xiaofu 8 5天前
2
0
学习了
Editor 5天前
3
0
感谢分享哦~
jgs 5天前
4
0
学习了,谢谢楼主分享
5
0
很早就想这么做了~而且ida官方也是推荐命令行的方式去做batch,他们最开始的搞批量上传常见云sig就是headless下批量运行ida多进程实现的,每个进程差不多能吃满一个核心。
有时候确实有批量分析N+库文件生成idb的需要,但姑且还是偷懒了
nqxcwl 5天前
6
0
感谢楼主~
Zkeleven 5天前
8
0
大佬txl
mb_ldtiaylu 5天前
9
0
请问ida有供c++调用的接口吗?有点不习惯python的类型
10
0
月落之汀 很早就想这么做了~而且ida官方也是推荐命令行的方式去做batch,他们最开始的搞批量上传常见云sig就是headless下批量运行ida多进程实现的,每个进程差不多能吃满一个核心。 有时候确实有批 ...
可以修改下我的代码,最后执行命令的部分改为多进程。
11
0
只有idc脚本和py脚本,都是动态类型的。
最后于 5天前 被爱吃菠菜编辑 ,原因:
xiaohang 3 4天前
12
0
其实写python脚步夜没那么麻烦,不过这个思路还是满有意思的,可以用ida的分析结果来自动抽取指令进行加密处理,但是可执行程序再生成呢?LIEF可是方便的多了?
13
0
初衷主要是发现IDA像是个静态信息数据库,按需提取就行,
写壳写自动逆向工具,最初的静态信息收集信息阶段动作,全部都省略了。
14
0
@xiaohang  我觉得IDA应该信息更全面一些,尤其还有各种内存访问交叉引用的统计,免费的就是不如花钱的
最后于 4天前 被爱吃菠菜编辑 ,原因:
15
0
很好的思路,赞一个。
最后于 3天前 被天水姜伯约编辑 ,原因:
kakasasa 3天前
16
0
mark
我要学 1天前
17
0
厉害了我的IDA
theRX 1天前
18
0
感谢分享
游客
登录 | 注册 方可回帖
返回