【原创】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序号。
名称:  1.png
查看次数: 1
文件大小:  2.9 KB
注意堆栈是先进后出的,所以在栈顶的是handler的序号。


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

图片名称:	2.png
查看次数:	1
文件大小:	15.9 KB
文件 ID :	103437
点击图片以查看大图

图片名称:	3.png
查看次数:	0
文件大小:	20.0 KB
文件 ID :	103438
名称:  4.png
查看次数: 1
文件大小:  6.0 KB
这部分其实和CSIC比较起来没什么变化,所以初看起来就是CSIC,但是真正的变化在进入handler运行之后。

Handler
这部分也没什么特别好说的,保存的是每个handler的偏移量,在VM入口中被初始化后就是绝对地址了。寻址方式就是一个数组,handler id 乘以加上handler表的基地址,就是相应handler 的指针了。
名称:  5.png
查看次数: 0
文件大小:  3.2 KB

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


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

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

VM FISHHandler

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


VM FISHHandler类型

任何东西都是可以分门别类的,在程序的世界里尤其如此,当然,这也是最耗时,最磨人的工作。有幸的是,由于有了对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


由于虚拟机中对poppush的使用最平凡,所以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中的subhandlesubhandle的概念以后的章节会说明)决定的,但是有一个规律是可以抓住的,这些操作都是单一参数的汇编操作,如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

3xchg

引用:
 
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
模拟popfdpushfd的操作

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动物园的,可以联系我,邮箱:xiaohang99@gmail.com ,共同探讨,一起进步


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

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

原文地址:https://www.cnblogs.com/Reverser/p/5240501.html