首页
社区
课程
招聘
[原创]分析强壳的虚拟机原理
发表于: 2019-5-18 14:22 8808

[原创]分析强壳的虚拟机原理

Buu 活跃值
1
2019-5-18 14:22
8808

    本人是逆向界的一枚小学生,喜欢唱,跳,搜字符串,以及回收站,这个分析是好早前分析的了,如有不对的地方,还请各位大佬海涵

执行完以后这里在判断下栈够不够,够就继续循环取中间码,如果不够就在扩充,因为有可能执行被VM后的代码导致开始开辟0x200的栈不够,所以需要判断,如果不够就在开,然后把寄存器环境在从新拷贝

然后第二次可以看到把中间码3D拿出来,然后esi+1,然后跳过去

然后用EDI+2C,根据上面分析的可以看到EDI+2C是原本的EBP,然后将原本的EBP压入栈顶

然后在跳回来,取出中间码0x59,继续在跳走执行

然后取出刚刚压进去原来的EBP给EAX,然后把原来程序用的EBP-4,然后把eax MOV进去,然后就完成了push  ebp的操作

然后在回来,这次拿出0x65

然后我们跳过来,在取中间码2C给EAX,然后把刚开始压入栈顶的EBP弹到虚拟机用的寄存器环境里的EBP

然后在回来,拿出9A

继续JMP过来,可以看到把栈顶又抬了0x4的大小

然后在回来,这次拿出中间码0x27

然后跳过来后把原来程序用的EBP给虚拟机的寄存器环境里+0X10的位置,因为刚才push了,然后EBP-4了,也就是说现在EBP是原来程序用的栈的栈顶, 然后这块虚拟机用的寄存器环境的栈顶也得移动栈针,也得-4,所以把他原来的拿过来赋值,

然后在跳回去,在拿出3D

跳过来拿出0x10给EAX,然后把EDI+10在压入栈顶,EDI+10就是上一步赋值过来的,这里看的迷糊的看最开始的分析,EDI+0X10就是真实程序用的ESP

继续跳回去,还是拿出3D,3D是压寄存器操作

继续执行,拿出2C,还是上面的操作,把EBP压入栈顶

然后拿出0xB5

JMP过去,因为刚才把EBP和ESP都压人栈顶了,这个时候访问栈顶,把ESP给EBP,完成mov EBP,ESP的操作,然后也把标志寄存器更新了一下

然后在跳回去,拿出0x65

JMP过来,拿出中间码0x65,根据上面的分析,0x65就是把当前栈顶的值更新到虚拟寄存器环境中

然后在跳回来,拿出9A,根据上面分析的,9A是抬栈

然后在回来,拿出中间码0x27

根据上面分析,0x27是把程序用的EBP给虚拟的ESP

在跳回去,拿出操作数0x9D,开始压栈

跳过来以后,可以看到在拿出操作数,压入当前的栈顶

然后在跳回去,拿出操作数CD

然后跳过来,从栈顶拿出刚压的,然后程序用的EBP抬4个字节,然后把字符串压进去,这个时候才完成了把一个字符串地址压入程序用的栈的操作

在跳回去,拿出操作数0x9A,因为刚才压到栈顶的字符串没用了,要弹走

在回来(执行完抬栈了),然后在回来看到又是一个抬栈,因为上面mov ebp,esp的时候,抬的时候只抬了一个,这个时候再把另外一个抬走

然后再回来,拿出操作数0x27,更新虚拟寄存器环境里的esp

这个时候在压栈

我们跟过来看下,可以看到压入printf的地址了

跳回来看到又是压栈

跳过来给可以看到给栈顶压了一个1

然后在跳回来,拿出操作数0x9D,继续压

调过来看到又压入0xFFFFFFFF

跳回来又看到压栈

这里又压了一个0xFFFFFFFF

跳回来这次拿到0x31

JMP过来,可以看到ADD esp,0x10,把栈顶刚压入的4个参数弹走,然后从新把printf的地址压进去,现在栈顶只有一个printf的地址

然后回来,拿出中间码0xC0

跳过来,然后把printf的地址给eax,然后在拿出中间码给edx



     因为一直对强壳里面所谓的虚拟机感兴趣,但是反调试,反虚拟机等很烦人,所以当时找了个demo,只有虚拟机,没有其他乱七八糟的东西,当然这个虚拟机可能跟其他强壳比起来弱爆了,但是原理大致相通,也有可能现在的虚拟机都不这样玩了,但是作为学习来说还是能学到比较多的思路的,当时对壳还是比较感兴趣的,但是这个分析完以后,emmmmmmm


废话不多说,开搞,我们先运行程序,可以看到就是输出两段字符串,程序很简单,第二个输出字符串的函数是被VM了(虚拟机执行的函数我暂时称为被VM的代码),所以我们对第二个函数分析就行了


因为是控制台程序,所以我们直接定位到main函数,可以看到,框出的地方就是VM的代码了


还犹豫什么,F7进去盘他



这里进去看到压了一个参数,我们内存窗口看看


我们发现压入的是字符串,好了,今天的分析就到这了,我们下次再见,我还要去拯救苇名


好了,我们看下到底压了个什么鬼进去了


好家伙,这都是什么鬼,没字符串我还逆个屁啊



我们继续走,可以看到这里就是主要代码了,可以看到这里首先保存了一堆寄存器,紧接着两次开辟栈空间,我们上面说了,既然是虚拟机,那么寄存器环境和栈环境什么的,都要模拟出来,这里第一次抬0x200的大小是构造一个栈空间,第二次抬0x40是构造寄存器环境


往下走,可以看到给esi赋值了,就是刚才我们不知道什么鬼的那些东西,我们暂且把这些称为中间码,毕竟他也要面子的嘛



这里我画一个图,助于理解,第一次抬了0x200后把栈顶给了edi,那么说明虚拟机的栈是用edi来访问的,寄存器环境是用esp来访问的



继续走,我们看到拿出了第一个中间码,然后跳了




可以看到这里是在取开始压入的寄存器的值,然后给虚拟机的寄存器环境赋值



那么我们先记录下
EDI:VMContext栈底 寄存器环境
    +0       EFLAGS
    +4       EDX
    +10     ESP
    +18     ESI
    +1C    EBX
    +20     EAX
    +24     EDI
    +28     ECX
    +2C    EBP
    +0       EFLAGS
    +4       EDX
    +10     ESP
    +18     ESI
    +1C    EBX
    +20     EAX
    +24     EDI
    +28     ECX
    +2C    EBP

中间码
 F6 初始化寄存器环境

执行完以后这里在判断下栈够不够,够就继续循环取中间码,如果不够就在扩充,因为有可能执行被VM后的代码导致开始开辟0x200的栈不够,所以需要判断,如果不够就在开,然后把寄存器环境在从新拷贝



然后第二次可以看到把中间码3D拿出来,然后esi+1,然后跳过去



跳过来以后拿出了中间码0x2C给EAX



然后用EDI+2C,根据上面分析的可以看到EDI+2C是原本的EBP,然后将原本的EBP压入栈顶



然后在跳回来,取出中间码0x59,继续在跳走执行



然后取出刚刚压进去原来的EBP给EAX,然后把原来程序用的EBP-4,然后把eax MOV进去,然后就完成了push  ebp的操作



好家伙,折腾这么大一圈就完成了一个push ebp


我们都知道,函数进来得保存栈的环境,给当前函数开辟新的栈空间和栈底等,那么push ebp完了以后就该是 mov ebp,esp了,我们接着看这虚拟机的骚操作


然后在回来,这次拿出0x65



然后我们跳过来,在取中间码2C给EAX,然后把刚开始压入栈顶的EBP弹到虚拟机用的寄存器环境里的EBP



还是画个图,不然容易乱


然后在回来,拿出9A



继续JMP过来,可以看到把栈顶又抬了0x4的大小




然后在回来,这次拿出中间码0x27




[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2019-5-19 18:41 被Buu编辑 ,原因:
上传的附件:
收藏
免费 5
支持
分享
最新回复 (21)
雪    币: 650
活跃值: (4217)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
写的不错!
2019-5-18 14:56
0
雪    币: 2496
活跃值: (221)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
学习.
2019-5-18 14:59
0
雪    币: 283
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
写的不错~
2019-5-18 19:24
0
雪    币: 7
活跃值: (283)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
5
表情包不错
2019-5-18 20:35
0
雪    币: 764
活跃值: (999)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
6
学习一下
2019-5-18 22:53
0
雪    币: 764
活跃值: (999)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
7
lz能放一下程序吗
2019-5-18 23:05
0
雪    币: 4057
活跃值: (312)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
8
我找找吧,找到了就放上来
2019-5-19 12:27
0
雪    币: 452
活跃值: (6128)
能力值: ( LV12,RANK:580 )
在线值:
发帖
回帖
粉丝
9
给力嗷
2019-5-19 16:25
0
雪    币: 4057
活跃值: (312)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
10
xuanzee lz能放一下程序吗
程序我放上来了,不知道是论坛的BUG还是我自己的问题。。我点引用好像不行。。
2019-5-19 18:42
1
雪    币: 4057
活跃值: (312)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
11
又好了,这特么的。。。。
2019-5-19 18:43
0
雪    币: 8764
活跃值: (5240)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
12
楼主有才。
2019-5-19 21:07
0
雪    币: 2466
活跃值: (4561)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
楼主666
2019-5-19 21:14
0
雪    币: 576
活跃值: (1163)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
14
表情包不错
2019-5-20 09:51
0
雪    币: 12502
活跃值: (3058)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
15
没那么容易的,他的字节码,不一定一次取几个字节。比如正走比如倒走,比如一次四个字节比如一次一个字节。想用这种方式去还原虚拟机,不是好办法。因为字节码并不是可靠的,而且新版本没有你的“dispatcher”,是靠寄存器连接的,每一段代码,并不知道下一段在哪里。
2019-5-20 10:18
0
雪    币: 4065
活跃值: (3457)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
16
表情包不错+1
2019-5-20 11:00
0
雪    币: 4057
活跃值: (312)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
17
白菜大哥 没那么容易的,他的字节码,不一定一次取几个字节。比如正走比如倒走,比如一次四个字节比如一次一个字节。想用这种方式去还原虚拟机,不是好办法。因为字节码并不是可靠的,而且新版本没有你的“dispatche ...
是的,基于这个可以延伸很多方法,新版本咋玩的我也不知道,我这里只是说下基础,最简单的玩法,所以狗命要紧,后面的不玩了,太菜了,等以后哪天想作死了在研究吧
最后于 2019-5-20 11:01 被Buu编辑 ,原因:
2019-5-20 11:01
0
雪    币: 713
活跃值: (91)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
活捉逗逼一个。
2019-5-24 00:23
0
雪    币: 2375
活跃值: (433)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
白菜大哥 没那么容易的,他的字节码,不一定一次取几个字节。比如正走比如倒走,比如一次四个字节比如一次一个字节。想用这种方式去还原虚拟机,不是好办法。因为字节码并不是可靠的,而且新版本没有你的“dispatche ...
楼主分析的是什么壳,vmp么?
2019-6-14 17:08
0
雪    币: 8447
活跃值: (5041)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
20
表情包收走了[em_13]
最后于 2019-6-14 18:19 被v0id_编辑 ,原因:
2019-6-14 18:17
0
雪    币: 218
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
21
向大佬递茶
2019-6-17 12:16
0
雪    币: 1129
活跃值: (2761)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
22
感谢分享
2019-12-3 09:41
0
游客
登录 | 注册 方可回帖
返回
//