IDA F5 增强插件,还我源代码(一)

公众号: 奋飞安全
• 阅读 1726

一、目标

许多年以后,面对IDA的F5,奋飞将会想起,老李老板甩给他一本80x86汇编的那个遥远的下午。

IDA F5 增强插件,还我源代码(一)

那时的App的名字还叫exe、com。Asm程序员最后的荣光,就是面对黑洞洞的屏幕敲下DEBUG的那个不眠之夜。

后来App改名叫pe、elf了。IDA F5一下就是C程序员的狂欢,Asm程序员只能黯淡落幕了。默默的抱起小李老板新买的《C语言程序设计》。

IDA F5 增强插件,还我源代码(一)

时代的车轮呼啸而过,瑞士的同行给我们上了一课,ollvm一下,你妈都认不出来你了。

IDA F5 增强插件,还我源代码(一)

ollvm纪元都已经10年了,现在的混淆只有更狠,没有最狠。

谁来还我源代码?还得是 IDA F5 ,当年横空出世的时候喊人家小甜甜,现在遇上ollvm了,就喊人家牛夫人了。牛夫人也有变身的时候。

二、步骤

IDA 7.x+

是的,我知道你在用 7.5。

git clone https://gitlab.com/eshard/d810.git

把d810文件夹和D810.py文件一起放到 C:\fenfei\IDAPro7_5\plugins 目录下面。

然后作者强烈建议安装 z3

pip3 install z3-solver 

打开心爱的IDA,载入样本 blog_instruction_obfuscation_sub1.bin, 然后 File->Script File... 选中 D810.py 跑一下,最后 Ctrl-Shift-D ,神器出现了。

IDA F5 增强插件,还我源代码(一)

Current file loaded 中选择配置文件 default_instruction_only.json

然后点击 ”Start“ 按钮,再 F5一下, 见证奇迹的时刻来了。

IDA F5 增强插件,还我源代码(一)

虽然看上去还不是很帅,但是起码他妈应该能认出他来了。

小窍门

为啥有的小伙伴即使都配置好了D810,但是F5之后还是没有变化?

那是因为IDA F5有缓存,你之前已经F5过了,再来一次不会走D810插件,还会走原来的缓存。

那怎么删除这个F5的缓存呢? 这个,我也不知道。

但是飞哥找到了一个等效的方法。

  • 用keypatch插件把目标函数的任意一行代码修改成nop
  • undo last patching 还原刚才的修改

这下再F5就会重新生成,走D810的增强结果了。

完美收工……

IDA Microcode介绍

李老板: 奋飞呀,你就这么结束也太水了吧。这种文章我都不好意思 转发,严重影响我大佬的人设。

奋飞:老板说的有道理,使用开源工具,不读他的源码是对作者的不尊重。

我们先来聊聊 IDA Microcode, 他是一种中间语言,从反汇编出来的汇编代码到F5生成漂亮的C代码,中间要经过多次的Microcode转换。

举个例子,生米煮成熟饭(说你呢,别想歪了),在萌新看来,就是大米 biu~~ 一下就成米饭了。但是立志成为老鸟的小伙伴就要分析一下了, 大米加水后会膨胀,成熟度1度的时候,大米刚刚有点发白,成熟度2度的时候,大米表皮变软,成熟度n度的时候,才是香喷喷的米饭。

如果我们在成熟度2度的时候,给锅里加点葡萄干,那么最后出来的米饭会不会更帅?

Microcode把 ASM -> C 的过程分成了多个成熟度,每个成熟度提供api给你hook,你可以自己加点料。这样最后出来的C代码就更可口了。

这次的新朋友是 https://github.com/gaasedelen/lucid

IDA F5 增强插件,还我源代码(一)

明明白白的查看各个成熟度的微码,方便你夹私货。

D810分析

Microcode聊完了,我们再聊聊D810小甜甜的原理。

D810主要做了两步,一步是指令替换

  • (x + y) - 2 * (x & y)
  • (x + y) - 2 * (y & x)
  • (x - 2 * (x & y)) + y
  • (~x | ~y) | (x ^ y)
  • ((2 * (x | x)) - (x ^ x))

混淆后的代码里面有大量这种模式的代码,只要用点小学数学知识,我们就能换算出

  • (x + y) - 2 * (x & y) == x ^ y
  • (~x | ~y) | (x ^ y) == ~(x & y)

然后把对应的代码替换掉不就行了?

在 d810/ast.py 中用 AstNode 对象来表示一个算式

比如 x+y 用 AstNode表示就是

# x+y
AstNode(m_add,
             AstLeaf("x_0"),
             AstLeaf("x_1"))

# (x + y) - 2 * (x & y)
AstNode(m_sub,
              AstNode(m_add,
                          AstLeaf("x_0"),
                          AstLeaf("x_1")),
                      AstNode(m_mul,
                              AstConstant("2", 2),
                              AstNode(m_and,
                                      AstLeaf("x_0"),
                                      AstLeaf("x_1"))))

这样抽象出来之后,你从 d810/optimizers/instructions/pattern_matching 下面就可以翻到一堆指令替换的代码了。

D810做的第二步,是流程重组,类似我们之前 http://91fans.com.cn/post/disollvmone/ 分析的那样,找到 主分发器和真实块,然后重组正确的流程。

这一步的实现在 d810/optimizers/flow 里面

动手吧

说那那么多,我们来动手给d810再加点料。

刚才分析的 obfucated_full_example 还不是很帅,

 while ( ((v3 | 0xFFFFFFFA) & ~(((v3 - 5) | v3 ^ 0xFFFFFFFA) & (v3 ^ (v3 - 5) ^ 5)) & 0x80000000) == 0 )

这行代码看上去应该也是可以优化的

在 \d810_logs\pattern_guess.log 的日志里面,他有提示我们 (~((x_0 - 5)) | (x_0 ^ 5)) 这一步是可以优化的。

小学数学登场

(~((x_0 - 5)) | (x_0 ^ 5)) == 1

飞哥,我小学数学是体育老师教的,你会不会骗我?

说好的信任呢? 来吧, 介绍一位新朋友 https://github.com/quarkslab/arybo

专治小学数学不服

IDA F5 增强插件,还我源代码(一)

那就开始写代码吧

class FFRule0(PatternMatchingRule):
    PATTERN = AstNode(m_or,
                      AstNode(m_bnot,
                              AstNode(m_sub,
                                      AstLeaf('x_0'),
                                      AstConstant('5', 5))),
                      AstNode(m_xor,
                              AstLeaf('x_0'),
                              AstConstant('5', 5)))

    REPLACEMENT_PATTERN = AstNode(m_mov, AstConstant("val_1"))

    def check_candidate(self, candidate):
        candidate.add_constant_leaf("val_1", 1, candidate.size)
        return True

然后配置上我们新的规则

IDA F5 增强插件,还我源代码(一)

再看看增强plus的结果:

IDA F5 增强插件,还我源代码(一)

欧耶,漂亮多了。

三、总结

小学数学很重要。

一般情况下作者推荐用 default_instruction_only.json ,等你搞明白了,可以自己搭配配置,小孩子才做选择,成年人全都要。是不行的,所有配置都加上慢的一比不说,还会增加崩溃的几率。

没有一劳永逸直接F5就出来漂亮源码的办法,IDA的F5已经做了很多的工作,攻防总是在不断升级的,武器是战争的重要因素,但不是决定因素,决定的因素是人不是物。

参考链接:

https://eshard.com/posts/d810_blog_post_1/

D810:为 IDA Pro 创建一个可扩展的反混淆插件

IDA F5 增强插件,还我源代码(一)

如果把出类拔萃定义为成功,那么大多数人注定无所建树;如果把比昨天进步一点点当成目标,那么我们每天都有机会宣布自己获得了一次小胜利

TIP: 本文的目的只有一个就是学习更多的逆向技巧和思路,如果有人利用本文技术去进行非法商业获取利益带来的法律责任都是操作者自己承担,和本文以及作者没关系,本文涉及到的代码项目可以去 奋飞的朋友们 知识星球自取,欢迎加入知识星球一起学习探讨技术。有问题可以加我wx: fenfei331 讨论下。

关注微信公众号:奋飞安全,最新技术干货实时推送

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
借你一双慧眼, Frida Native Trace
一、目标李老板:奋飞呀,最近没怎么更新呀?奋飞:最近的KPI定的合不合理你心里没点AC数?我现在内卷到周三就开始写周报了,不然被新来的就给卷失业了。遥想在古典PC互联网时代,咱也是OD、IDA玩的很溜的。一日饮酒乐甚,突发奇想,IDA识别出所有函数,然后导出来给OD,给这些函数下断点,触发之后先打日志,再自动取消断点。这样程序运行的流程不就出来了?实
不能Hook的人生不值得 jsHook和模拟执行
一、目标李老板:奋飞呀,上次分析的那个App光能Debug还不够呀,网页中的js也用不了Frida,我还想Hook它的函数,咋搞呀?再有App可以RPC去执行签名,这个js我如何去利用呀?总不能代码都改成js去做请求吧?奋飞:老板呀,你一下提这么多要求,不是明摆着要我们加班吗?这次加班费可得加倍。二、步骤最简单易行的jsHookcon
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Unity IL2CPP 游戏分析入门
一、目标很多时候App加密本身并不难,难得是他用了一套新玩意,天生自带加密光环。例如PC时代的VB,直接ida的话,汇编代码能把你看懵。但是要是搞明白了他的玩法,VBDecompiler一上,那妥妥的就是源码。Unity和Flu
Stella981 Stella981
2年前
Android蓝牙连接汽车OBD设备
//设备连接public class BluetoothConnect implements Runnable {    private static final UUID CONNECT_UUID  UUID.fromString("0000110100001000800000805F9B34FB");
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
公众号:  奋飞安全
公众号: 奋飞安全
Lv1
奋飞,国家高级信息系统项目管理师,独立安全研究员。 http://91fans.com.cn/
文章
59
粉丝
4
获赞
44