【原创】Themida 2260 虚拟机 FISH 初探(一)

标 题: 【原创】Themida 2260 虚拟机 FISH 初探(一)
作 者: xiaohang
时 间: 2016-03-03,00:39:37
链 接: http://bbs.pediy.com/showthread.php?t=208207

引用:

标 题: 【原创】Themida 2260 虚拟机 FISH 初探 (二)
作 者: xiaohang
时 间: 2016-03-03,14:35:18
链 接: http://bbs.pediy.com/showthread.php?t=208217

这篇文章摘自一年前我的工作笔记,早就想放上来的,由于我懒,一直懒得整理编辑,老婆出差,闲着也是闲着,所以下定决心整理了一下,发出来抛砖引玉
以下是正文

Themida 2260 VM FISH 初探

by xiaohang99

前言:
著名的反虚拟机插件Oreans UnVirtualizer 已经升级到1.8 ,完全支持了对Themida 2.2.6.0 的FISH 虚拟机生成代码的还原 。
下面摘录自Oreans UnVirtualizer 的更新信息:

引用:

[v1.8]
- FISH BLACK variant avaible
- Fixed deofuscation order (GenV6)
- New deofucation scheme for FISH machine
- New smart code tracer for FISH machines
- Stack sort for FISH commands
- Improved management of memory (faster deofuscation)
- Added movzx reg32, [esp+eax+memoffset] on CISC machines
- Added a message prompt when the opcode buffer is not enough
- Added LEAVE instruction for FISH machines
- Added support for CALLs to VM section in FISH machines
- CHECK_PROTECTION macro disabled, now it must be restored by hand
- Fixed QWORD incorrect names for some opcodes
- Fixed a problem when deofuscating RISC machines

我尝试着通过对Oreans UnVirtualizer (以下称之为OU)的逆向,来学习Themida的FISH VM结构,有所心得,整理笔记,以成此文。
一下的内容是对VM FISH White 进行的分析,其他颜色的虚拟机可能部分适用,毕竟原理还是一样的。

VM FISH虚拟机的结构
VM FISH 虚拟机在我看来有些类似之前的CISC和RISC的组合,包含了两种指令集的特色,以增加逆向的难度。VM FISH white的结构大概可以分6个部分,他们分别是引导区域、VM入口、Handler表、Handler代码、VM context以及 OP code存储区。
引导区域
这个比较简单,引导区调用自程序代码段,主要任务是PUSH两个立即数,第一个是要使用的OP code 所保存的偏移量,第二个是第一个调用的handler序号。

注意堆栈是先进后出的,所以在栈顶的是handler的序号。

VM入口
和之前的CSIC类似,完成几个标准动作
1、首先是保存当前寄存器
2、计算VM context的偏移量
3、检测虚拟机的线程安全
4、保存参数如ImageBase和OP code 偏移
5、计算handler表的偏移
6、检测handler表是否已初始化,否则进行初始化
7、通过引导区给出的第一个handler序号,跳转到相应的handler开始VM的运行



这部分其实和CSIC比较起来没什么变化,所以初看起来就是CSIC,但是真正的变化在进入handler运行之后。

Handler表
这部分也没什么特别好说的,保存的是每个handler的偏移量,在VM入口中被初始化后就是绝对地址了。寻址方式就是一个数组,handler id 乘以4 加上handler表的基地址,就是相应handler 的指针了。

Handler 代码区
Handler 表往上看就是Handler代码区,handler表中每个指针都指向这一段区域的handler开始的位置。

VM context
Handler代码段往上看就是VM context了,保存了所有虚拟机运行过程中的数据,很类似CISC的VM context,只是这里要大很多,每个handler在读写context的时候都会有变化,不会有固定的类似CISC中专门的地方用来模拟eax的情况出现。

OP code存储区
这个就不解释了,保护时生成的OP code 就保存在这里。

VM FISH的Handler

Handler是VM Fish中的关键,可以说是VM Fish的核心,他的功能包括读取参数,处理Opcode,保存运算结果,对运算结果再加密,等等……
所以,理清Handler的工作原理,可以说基本上就弄明白了VM FISH的工作原理了。下面我们重点来探讨一下VM FISH中的Handler。

VM FISH的Handler类型

任何东西都是可以分门别类的,在程序的世界里尤其如此,当然,这也是最耗时,最磨人的工作。有幸的是,由于有了对OU的逆向,我不需要自己对所有的Handler分类了,我唯一要做的是理解这些分类的意义,并给他们命个自己,包括看客们能明白的名称而已。
0类 pop&push

引用:

loc_1003ED83: ; jumptable 1003ED7C case 0
mov ecx, [ebp+arg_0_pTheMidaFishOpcode]
push ecx
mov edx, [ebp+arg_4_pOVopIAT]
push edx
mov ecx, [ebp+var_4]
call j_Make_pop
jmp loc_1003EF53

由于虚拟机中对pop和push的使用最平凡,所以OU对其分类摆在了第一位。而具体处理pop还是push,是由handler读取OPCode中的参数决定。

1类 type1

引用:

loc_1003ED98: ; jumptable 1003ED7C case 1
mov eax, [ebp+arg_0_pTheMidaFishOpcode]
push eax
mov ecx, [ebp+arg_4_pOVopIAT]
push ecx
mov ecx, [ebp+var_4]
call j__make_handle_type1_function
jmp loc_1003EF53

这个类型从功能上比较难辨别,它里面其实包含很多种操作,具体执行哪个是由handler读取Opcode中的subhandle(subhandle的概念以后的章节会说明)决定的,但是有一个规律是可以抓住的,这些操作都是单一参数的汇编操作,如inc,dec,neg等等

2类 type2

引用:

loc_1003EDAD: ; jumptable 1003ED7C case 2
mov edx, [ebp+arg_0_pTheMidaFishOpcode]
push edx
mov eax, [ebp+arg_4_pOVopIAT]
push eax
mov ecx, [ebp+var_4]
call j__make_handle_type2_function
jmp loc_1003EF53

这个类型从和上面的类型有很大的相似之处,就是包含多种操作,具体执行看Opcode中的subhandle,但是区别就在于它处理的都是带两个操作数的汇编操作,如sub,add等

3类xchg

引用:

loc_1003EDC2: ; jumptable 1003ED7C case 4
mov ecx, [ebp+arg_0_pTheMidaFishOpcode]
push ecx
mov edx, [ebp+arg_4_pOVopIAT]
push edx
mov ecx, [ebp+var_4]
call j_make_xchg
jmp loc_1003EF53

这个比较好理解,就是单一模拟xchg这个汇编指令,至少我暂时没看出他有其他的什么功能。

4类流程控制
这个类型OU中分了好几个类型,那我就放在一起讲了,就是负责控制程序的流程的,当然就是模拟各种汇编中的jmp call ret jnz jz 等等的指令,功能也比较一目了然的。

5类 ESP控制
VM本质上是和宿主程序共用堆栈的,所以ESP的控制很重要,他必须要模拟宿主程序进入call和返回时候所有ESP操作,否则会出现堆栈异常甚至溢出。

6类中断操作类

引用:

loc_1003EE94: ; jumptable 1003ED7C case 31
mov eax, [ebp+arg_0_pTheMidaFishOpcode]
push eax
mov ecx, [ebp+arg_4_pOVopIAT]
push ecx
mov ecx, [ebp+var_4]
call j_Handler_type_1F ; clc cld cli cmc stc std sti
jmp loc_1003EF53

程序中模拟clc cld cli等中断错作类的指令。

7类串操作类

引用:

loc_1003EED3: ; jumptable 1003ED7C cases 14-28
mov eax, [ebp+arg_0_pTheMidaFishOpcode]
push eax
mov ecx, [ebp+arg_4_pOVopIAT]
push ecx
mov ecx, [ebp+var_4]
call j_make_str_fun
jmp short loc_1003EF53

模拟lods scas cmps等串操作类的指令

8类 popfd&pushfd
模拟popfd和pushfd的操作

9类 VM FISH中的自有操作
这些指令的存在不是为了模拟某种汇编指令,而是VM FISH为了自身运行而创造出来的,比如初始化,加密等等
最典型的就是初始化,再每次进入VM后,一般第一条OPCODE指令就是初始化指令,指向一个初始化handler的序号,以下是经过整理的一个典型初始化handler(注意是经过整理,源代码有很多混淆)

引用:

// FISH Virtual Handler 0000 00422A0F
00422A17 MOV DWORD PTR [EBP+0x53],0x0
00422A25 MOV DWORD PTR [EBP+0xa7],0x0
00422A33 MOV DWORD PTR [EBP+0x89],0x0
00422A41 MOV DWORD PTR [EBP+0x14],0x0
00422A4F MOV DWORD PTR [EBP+0x8f],0x0
00422A5D MOV WORD PTR [EBP+0xa0],0x0
00422A6A MOV BYTE PTR [EBP+0x57],0x0
00422A75 MOV DWORD PTR [EBP+0x68],0x0
00422A88 MOV ESI,DWORD PTR [EBP+0x8]
00422A8A ADD ESI,0x0
00422A90 MOV DI,WORD PTR [ESI]
00422A93 SHL EDI,0x2
00422A9E MOV ESI,DWORD PTR [EBP+0x4f]
00422AA0 ADD ESI,EDI
00422AA2 MOV EDX,DWORD PTR [ESI]
00422AAB ADD DWORD PTR [EBP+0x8],0x2
00422AB1 JMP EDX

可以看到handler做的就是把所有的我称之为加密寄存器清零,(加密寄存器我以后再讲),然后读取OPCODE中的第二个handle序号,跳转到下一个handler去。

VM FISH中的handler是如何处理OPcode的

虚拟机被创造出来的目的就是以Opcode来替代原来PC中的指令,并加入混淆欺骗等等,以增加逆向的难度,这里我们就以VM处理Opcode为引,探索一下Themida Fish VM 是如何处理Opcode的,从而对Fish VM有个概念上的了解,并且其中还将详细的解说subhandle和加密寄存器的作用以及他们的运作机制。
这里,我就举handler中比较复杂的type2类型handler处理一段Opcode为例子,进行详细说明:
(未完待续……)

后面的内容看反馈再整理发布。
求版主发exetools的邀请码以资鼓励,给邀请码就越有动力整理发布嘛

另外,欢迎转载,但转载请说明出处哦,还有就是大家有兴趣一起研究新版本的themida动物园的,可以联系我,邮箱:[email protected] ,共同探讨,一起进步

下篇已经发布: 【原创】Themida 2260 虚拟机 FISH 初探(二)

*转载请注明来自看雪论坛@PEdiy.com

时间: 2024-08-27 13:49:00

【原创】Themida 2260 虚拟机 FISH 初探(一)的相关文章

实现原创指令集的虚拟机

上两篇文章我介绍了我最近设计的一套指令集及其对应的虚拟机架构,这篇文章就来介绍虚拟机的实现过程. 虚拟机其实很简单,需要做的只是用一种指令去模拟另一种指令的功能. 为了运行速度,当然希望用尽量低级的方法去模拟,所以应该用汇编编写,但为了效率,我先用的C语言写出整体逻辑,后期再考虑汇编. 虚拟机原理 LVM虚拟机运行的流程是这样: 初始化:虚拟机内存和寄存器值. 链接:指定虚拟机要运行的代码. 可以看到虚拟机的功能就是循环处理指令. 我按照运行流程,简单介绍一下代码,首先是虚拟机的数据结构: 一台

脱壳基础知识入门

现在加解密发展己形成2个分支了,一个就是传统的算法,另一个就是加密壳.越来越多的软件采用了密码学相关算法,现在要做出一个软件注册机己不象前几年那 么容易,这就要求解密者必须要有一定的数学功底和密码学知识,而这些在短时间内是不容易掌握的.除了密码学的应用,越来越多的软件加壳了,因此要求解密者 必须掌握一些脱壳技术,这就使得壳成了解密必须迈过的一个门槛.壳发展到今天,强度越来越高了,将许多人挡在门外,使得大家望壳兴叹.另外,论坛现在两极 分化比较严重,高手讨论的脱壳技术新手看不懂,很多人想学脱壳,但

Secure CRT 如何连接虚拟机里面的CentOS系统 当主机没有网的时候 作者原创 欢迎转载

当家里没有网络的时候: 1.第一步:首先保证主机所有的网卡都没有分享连接给VM8这一块网卡 如图:这个设置就保证了无线网络连接这块网卡没有分享给VM8这一块网卡 第二步:启用VM8这一块网卡,右键enable 第三步:查看VM8这块网卡的IP地址 网关地址 DNS服务器地址 ip地址是:192.168.6.1 第四步:虚拟机里面的设置记得选择VM8(NAT)这个选项 第五步:修改虚拟机里面的CentOS的IP地址,记得和VM8这块网卡的IP地址在一个网段上,我们这里设置为192.168.6.10

Secure CRT 如何连接虚拟机里面的CentOS系统 当主机使用有线网的时候 作者原创 欢迎转载

1.虚拟机的网卡配置如下图所示: 2.在CentOS 5.8的命令行界面:输入如下指令 然后准备修改里面的网关地址和自己的IP地址 3.同时查看自己的IP地址和网关 4.在第二步里面修改,网关地址应该和本机的网关地址是一样的,IP地址应该和本机的IPV4地址在同一个网段上,都是192.168.0.X,虚拟机里面的CentOS系统的网关地址和主机的gateway地址设置的应该是一样的 5.修改完毕之后,虚拟机里面按ESC键,然后输入":"(冒号不用输入),回车,最后输入"wq!

Secure CRT 如何连接虚拟机里面的CentOS系统——当主机使用无线网的时候 作者原创 欢迎转载

第一步:设置自己的无线网,并且分享给VM8这个虚拟网卡 第二步:查看VM8网卡的IP地址,如图是192.168.137.1 第三步:设置虚拟机的配置:选择VM8网卡并且是NAT的 第四步:设置虚拟机里面的CentOS系统的IP地址: 命令:vi /etc/sysconfig/network-scripts/ifcfg-eth0 ip地址和第二步里面的192.168.137.1在同一个网段就行,网关就是VM8网卡的ip地址:192.168.137.1,其他的设置不变 这个是更改DNS地址的命令:

【原创】宿主机远程登录虚拟机(windows server 2003系统)

转载请注明,谢谢合作 1.虚拟机网络设置为  “桥接模式”如图 2.系统装好并登陆后 右键点击我的电脑,点击属性,然后在弹出来的选择框中勾选远程桌面-->启用这台计算机的远程桌面 然后点添加-->高级-->立即查找-->选择第一个Administrator -->确定-->确定,确定. 3.运行cmd ,输入  ipconfig  回车,出现下图,得到IP地址 4.从宿主机远程到这个 IP即可,如图,输入帐号 administrator  密码

初探KVM-第一个虚拟机

一.准备环境 主板是否支持虚拟化技术: egrep '(vmx|svm)' --color=always /proc/cpuinfo 检查kvm是否加载: # lsmod |grep kvm 配置文件: /etc/libvirt/libvirtd.conf 管理方式 1) 安装vnc用GUI工具(Virtual Machine Manager)管理: Virtual Machine Manager 由 Red Hat 使用 Python 语言开发,用于控制虚拟机的生命周期,包括配给.虚拟网络管理

虚拟机下Linux系统Hadoop单机/伪分布式配置:Hadoop2.5.2+Ubuntu14.04(半原创)

系统: Ubuntu 14.04 64bit Hadoop版本: Hadoop 2.5.2 (stable) JDK版本: JDK 1.6 虚拟机及Ubuntu安装 1. 下载并安装 VMware workstation 11 下载地址:https://my.vmware.com/web/vmware/info/slug/desktop_end_user_computing/vmware_workstation/11_0?wd=%20VMware%20workstation%2011%20&is

【原创】如何设置Virtual Box虚拟机CentOS7为静态IP地址

如何设置Virtual Box虚拟机CentOS7为静态IP地址 最近要搭建一个Kubernetes集群,需要设置虚拟机为静态IP地址不变.翻了一些资料,参差不齐,有些也比较过时了.自己实测总结了一下,整理如下,供有需要的同学参考. 1.虚拟机设置,"网卡1"选择"桥接网卡"  2.ip addr查看虚拟机网卡地址 3.修改网卡配置文件 /etc/sysconfig/network-scripts/ifcfg-enp0s3 此处我虚拟机网卡是enp0s3,其它虚拟机