首页
社区
课程
招聘
[原创]用麒麟框架深入分析实模式二进制文件
发表于: 2020-9-6 02:36 12228

[原创]用麒麟框架深入分析实模式二进制文件

2020-9-6 02:36
12228

分析一个实模式二进制文件,比如 DOS 可执行文件或者 MBR 代码从来不是一个简单的任务。目前最好的办法是先用 Bochs, QEMU 或者 Dosbox 模拟运行,然后再使用 gdb, debug.exe 或者 IDA Pro来远程调试。但是这都是在没有麒麟框架(Qiling Framework)的情况下。现在我们想骄傲的宣布,麒麟框架正式支持 16bit 二进制的模拟运行,并且与之伴随的还有麒麟框架多维度分析二进制文件的能力。

本文在介绍实模式模拟实现细节的同时也会作为一篇教程来介绍麒麟框架的使用。

本文同样也发表于我的博客

麒麟框架基于 Unicorn 引擎,所以在介绍麒麟之前,我想先介绍一下 Unicorn 引擎。Unicorn 是一个以 QEMU 部分代码为基础实现的一个纯粹的 CPU 模拟器。与 QEMU 相比,Unicorn 有很多亮眼的特点:

但是正如之前所说,Unicorn是一个纯粹的CPU模拟器,它不知道自己上层运行的操作系统是什么,所以这里就有了麒麟框架。

有时候,我自己都不知道怎么解释麒麟到底是什么。 ---- Lau Kaijern,麒麟的作者

确实,很难用一句话来定义麒麟。为了更全面的描述麒麟,我想从麒麟四个核心功能来说明:模拟、分析、调试、扩展。

麒麟最基础的功能就是模拟,但是和 Unicorn 的模拟有所不同。刚才提到过,Unicorn 是一个 CPU 模拟器,而麒麟实际上是一个操作系统模拟器。下面是一个简单的图来说明一个原生应用和一个模拟应用的联系。

通常来说,原生应用在一个特定的操作系统环境上运行,这个操作系统会提供各种各样的 API,而操作系统运行在一个 CPU 之上。对于一个用麒麟模拟的应用,架构是非常相似的:Unicorn 扮演了 CPU 模拟器的角色,麒麟来完成操作系统的任务执行目标二进制文件。为了实现这些,麒麟分为了三层。

接下来用 DOS 和 HI.COM作为例子来讲解这三层是如何相互配合来模拟操作系统的。

对于 arch 层,我们可以假设 CPU 是 8086,它设置起来比较简单,只需要设置好寄存器即可。

COM 文件就只是一个内存镜像,没有任何文件头。因此 loader 层的实现极其简单:分配足够的内存,把整个文件写入到内存,设置好 PC 和栈即可。

对于 os 层,麒麟要做的事情就是尽可能多的实现中断。下面是 HI.COM 的源代码:

当 Unicorn 执行到 INT 21 的时候,它并不知道这个中断的具体含义,因此它会调用我们在 os 层中定义的 hook 函数,下面就是 os 层相应的实现:

这就是麒麟为了模拟 COM 执行文件所有的工作。其实还是蛮简单的,不是吗?

实际上,为了模拟一个 16bit 二进制文件,我大多数的工作都是合理的实现中断。比如 Petya 是一个 MBR 病毒,它大量的使用了 BIOS 提供的 INT 10 图像服务。在现代终端上一个对应的实现是 curses 所以我花了很多时间来把过去的图像中断翻译成了 curses 的调用。以 INT10, 0 为例子。

英文有句名言是 "Simple is better"。现在,相比以前的屏幕,终端已经变得越来越复杂了,结果实现一个简单的屏幕反而变得更难了,因为有太多的 corner cases。

有心的读者可能已经注意到了,我们这里的模拟其实和真正的 DOS 系统行为并不完全一样。没错,麒麟的模拟就是这样的。完美和快速的模拟从来不是麒麟的首要目标。麒麟关注的是为用户在二进制分析时提供最大的便利。我马上会谈到这一点。

顺带一提,麒麟从设计之初就是平台独立的。这意味着用户可以在 Windows 上运行一个 Linux ELF,在 Mac OS 上运行一个 Windows exe。然而对于 QEMU 来说这是不可能的,因为它需要把系统调用转发到主机上。

麒麟远远不止是一个模拟器。它同样提供了大量的API。

让我们以 fs_mapper 为例(因为我刚重构过 XD):

目标二进制文件 x86_fetch_urandom 的源代码为:

这个二进制文件就简单的从 Linux 系统下的伪随机字节流 /dev/urandom 获取一个字节。然而,如果使用了 ql.add_fs_mapper("/dev/urandom", Fake_urandom()) 我们就可以劫持这次读取过程并且返回一个固定的字节。

除了设备文件,fs_mapper 还可以模拟一个完整的磁盘。下面是模拟 Petya 的代码:

0x80 是实模式下磁盘的索引。对于 Linux 和 Windows,这个值可以是 /dev/sda 或者 \\.\PHYSICALDRIVE0QlDisk 是一个类,可以把一个文件模拟成磁盘,比如磁头、柱面和扇区的支持等等。之所以要模拟一个侧畔,是因为 Petya 使用了 BIOS 提供的 INT 13 磁盘服务来直接读写硬盘。为了实现这些中断,把一个文件映射成模拟环境下的磁盘是有必要的。

另一个例子是系统调用劫持。下面是文档里的一个例子。

因为麒麟自己就是整个 OS 环境,所以把系统调用暴露给用户是非常简单就可以实现的。

快照可以让用户保存或者恢复一个程序执行的上下文,包括 CPU 寄存器,内存内容甚至是文件描述符。配合部分执行的API,快照可以让用户完全控制一个程序,随意的测试一个程序内的任何一段代码。下面是分析 Petya 的例子:

在上面的代码中,我们首先准备好了堆栈,然后保存了一次快照。之后我们把解密的 key 写入到函数参数然后直接调用了验证函数。如果结果表明 key 是错误的,那么我们直接恢复之前保存的快照然后再次尝试。

限于篇幅,我无法在这里介绍麒麟所有的功能。如果有兴趣可以参考麒麟的文档。总而言之,正是这些强大的 API 让麒麟成为了一个真正的动态打桩分析框架,让麒麟区别于其他的模拟器。

我们知道,QEMU 是支持 gdb 远程调试的,那么麒麟怎么能不支持这么好的 feature 呢?

在写下这篇文章的时候,麒麟的调试功能仍然在紧张开发中,但是 16bit 调试已经完成了。简单的增加一行 ql.debugger=True 然后连接 gdb 到 127.0.0.1:9999 即可,下面是一张截图。

目前,麒麟正在把一些逻辑解耦成为单独的扩展。其中我们最近的一个工作是 IDA 插件,下面是相应的截图:

哦,等一下,我知道大家都是命令行高手,这样的插件真的有意义吗?

当然,正是有了 IDA 插件,至少你不需要再买一份 IDA Linux 授权,因为你可以在 Windows/Mac OS 上运行 Linux ELF,不是吗?

在麒麟的 qiling/extensions directory 目录下还有很多有意思的插件,有兴趣可以查看相应的 REAME 或者文档。

麒麟框架是一个非常有野心的框架。我们的终极目标是写出一个像瑞士军刀一样的分析框架,解除各种限制,比如因为平台或者系统不同导致的壁垒,为广大的逆向工程师们提供最好的体验。没有什么能阻止我们进一步的二进制分析!

然而,麒麟框架现在仍然不完美。欢迎大家给我们一个 star 以示鼓励并且加入到我们的开发中来!我们期待合并你的第一个 PR!

项目地址为:https://github.com/qilingframework/qiling

 

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2020-9-6 11:51 被澪同学编辑 ,原因:
收藏
免费 9
支持
分享
打赏 + 1.00雪花
打赏次数 1 雪花 + 1.00
 
赞赏  Editor   +1.00 2020/09/07 精品文章~
最新回复 (33)
雪    币: 47147
活跃值: (20460)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
2
现在编辑把内容放上来
2020-9-6 07:01
0
雪    币: 516
活跃值: (474)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
3
kanxue 现在编辑把内容放上来
多谢,已经编辑好了。
2020-9-6 11:31
0
雪    币: 4883
活跃值: (18890)
能力值: ( LV13,RANK:317 )
在线值:
发帖
回帖
粉丝
4

关注下~

最后于 2020-9-7 00:07 被0x指纹编辑 ,原因:
2020-9-7 00:06
0
雪    币: 2466
活跃值: (4561)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
期待~~
2020-9-7 00:39
0
雪    币: 2335
活跃值: (1319)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
6
很强!
2020-9-7 09:43
0
雪    币: 2325
活跃值: (4908)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7

#include <iostream>

#include <windows.h>


int main()

{

MessageBoxW(0, L"asfasdfa", L"adfasf", 0);

}


我用vs2017编译这个运行都异常··· 2010可以, 但是2010用printf 也异常
2020-9-7 14:25
0
雪    币: 2325
活跃值: (4908)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8

2020-9-7 14:25
0
雪    币: 26205
活跃值: (63302)
能力值: (RANK:135 )
在线值:
发帖
回帖
粉丝
9
关注点赞收藏,三连走起
2020-9-7 15:18
0
雪    币: 2345
活跃值: (3064)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
10
https://blog.lazym.io/2020/09/05/Dive-deeper-Analyze-real-mode-binaries-like-a-Pro-with-Qiling-Framework/
这是你英文博客?
2020-9-7 15:25
0
雪    币: 516
活跃值: (474)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
11
boursonjane https://blog.lazym.io/2020/09/05/Dive-deeper-Analyze-real-mode-binaries-like-a-Pro-with-Qiling-Frame ...
嗯对,在关于页面里可以看到有互相引用的。
2020-9-7 17:38
0
雪    币: 516
活跃值: (474)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
12
值得怀疑
很可能是没有Windows的DLL,可以看一下我们的README,如果要跑Windows的exe需要先collect一波。
2020-9-7 17:41
0
雪    币: 516
活跃值: (474)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
13
另外欢迎来Github提一个issue :)
2020-9-7 17:42
0
雪    币: 18
活跃值: (1059)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
14
澪同学 另外欢迎来Github提一个issue :)
特别想用C++造福一下广大同行。
2020-9-7 18:18
0
雪    币: 516
活跃值: (474)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
15
猪会被杀掉 特别想用C++造福一下广大同行。
具体来说是?
2020-9-7 18:41
0
雪    币: 2325
活跃值: (4908)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
澪同学 很可能是没有Windows的DLL,可以看一下我们的README,如果要跑Windows的exe需要先collect一波。
我说的问题你没遇到吗? 用vs2017 或2019 编译个exe运行不了有异常
2020-9-7 19:33
0
雪    币: 2325
活跃值: (4908)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
澪同学 很可能是没有Windows的DLL,可以看一下我们的README,如果要跑Windows的exe需要先collect一波。
我运行了那个bat 把那些dll放过来了
2020-9-7 21:05
0
雪    币: 516
活跃值: (474)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
18
值得怀疑 我说的问题你没遇到吗? 用vs2017 或2019 编译个exe运行不了有异常
把完整的log发一下,最好可以到Github提一个完整的issue。另外gdi32这块目前还是WIP。
2020-9-7 22:29
0
雪    币: 783
活跃值: (1121)
能力值: ( LV5,RANK:78 )
在线值:
发帖
回帖
粉丝
19
年初就有关注.... 但是苦于 不知道怎么对界面化的程序进行完整模拟....
2020-9-8 01:11
0
雪    币: 2296
活跃值: (6668)
能力值: ( LV7,RANK:102 )
在线值:
发帖
回帖
粉丝
20
程序快照功能赞一个
2020-9-8 09:07
0
雪    币: 14872
活跃值: (6093)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
这个时候还有模拟dos操作系统的?浪费精力。完全可以去掉这部分,把工作重点转移到模拟windows、安卓上来。
2020-9-8 09:21
0
雪    币: 1535
活跃值: (695)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
tDasm 这个时候还有模拟dos操作系统的?浪费精力。完全可以去掉这部分,把工作重点转移到模拟windows、安卓上来。
1. 如果你不想看,麻烦直接关掉这个页面。
2. 没有什么“浪费精力”这一说,只要喜欢,做什么都可以。
3. talk is cheap, show me the code。自己一篇帖子都没发过,就别在别人帖子下面说别人不行了。
ps: 最讨厌一天天什么都不研究,只喜欢在别人文章下面指手画脚的人了呢  
2020-9-8 09:46
0
雪    币: 14872
活跃值: (6093)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
开花的水管 1. 如果你不想看,麻烦直接关掉这个页面。 2. 没有什么“浪费精力”这一说,只要喜欢,做什么都可以。 3. talk is cheap, show me the code。自己一篇帖子都没发过, ...

你有什么资格说这话?我就要说,你能怎么的?你怎么知道别人没研究?一看就知道你是个不学无术的。
狗咬耗子多管闲事!

最后于 2020-9-8 09:59 被tDasm编辑 ,原因:
2020-9-8 09:55
0
雪    币: 1535
活跃值: (695)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
感谢楼主分享,点赞、收藏、关注三连支持了
2020-9-8 09:59
0
雪    币: 516
活跃值: (474)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
25
bambooqj 年初就有关注.... 但是苦于 不知道怎么对界面化的程序进行完整模拟....
感谢关注。这个功能我们正在尝试实现,问题主要是Windows是个黑箱,想要完美模拟手工实现比较困难,已经制定两条技术路线在做尝试了。
2020-9-8 12:31
0
游客
登录 | 注册 方可回帖
返回
//