首页
社区
课程
招聘
我也来理解虚拟机
2008-2-29 13:23 19252

我也来理解虚拟机

2008-2-29 13:23
19252
 现在的技术更新换代真是快哦,好多壳都还没有脱成功,就出现VM了.本来还不打算接触VM的, 但是被某某鄙视不动手的懒人,所以今天就动手给他瞧瞧.不过话说回来,我确实有点懒,因为我把大部分时间都花在泡MM,游戏,跟发呆上(我经常发呆冥想自己中了大奖,有个美女跟我搭讪什么的),做今天这样的事情完全是凭心血来潮.
 
看了些讨论虚拟机的帖子,“每个虚拟机都有自己的CONTEXT”,“会在伪指令中修改EIP”
我纳闷了好久,按我目前的理解,我就知道有一个SetThreadContext可以修改CONTEXT结构,但是用OD打开VM过的程序,楞是没看到呀??

入口参数:
00401166 > $  68 514E4000   push    00404E51                        //压入PCODE首地址
0040116B   .- E9 4F3A0000   jmp     00404BBF

VM初始化:
00404BBF    9C              pushfd                                    //压入32位的EFLAGS
00404BC0    60              pushad                                   //压入eax,ecx,edx,ebx,esp,ebp,esi,edi
00404BC1    68 00000000     push    0                                //我把他看作压入一个DWORD变量
00404BC6    8B7424 28       mov     esi, dword ptr [esp+28]          //[esp+28]=00404E51            
00404BCA    BF 00404000     mov     edi, 00404000                    //edi=CONTEXT结构
00404BCF    FC              cld
00404BD0    89F3            mov     ebx, esi
00404BD2    033424          add     esi, dword ptr [esp]            

00000000(变量) |
edi            |
esi            | ⌒
ebp            | 堆
esp            | 栈
ebx            | ↓
edx            |
ecx            |
eax            |
flags          |
00404e51       |

mov     edi, 00404000
对比了一些帖子,我也敢说00404000指向CONTEXT结构,刚开始的时候我觉得这个地址就是VMP区段的开头,没什么特别的。
CTRL+G到00404000看看:
00404000    F5                cmc
00404001    808B 1C99DCE8 E2  or      byte ptr [ebx+E8DC991C], 0E2
00404008    94                xchg    eax, esp
00404009    3386 C61FD899     xor     eax, dword ptr [esi+99D81FC6]
0040400F    8136 24CFFA5B     xor     dword ptr [esi], 5BFACF24
00404015    7E 68             jle     short 0040407F
00404017    48                dec     eax
00404018    2B8C14 DDA08B9B   sub     ecx, dword ptr [esp+edx+9B8BA0DD]
0040401F    6E                outs    dx, byte ptr es:[edi]
00404020    F605 6B6A8A6E 80  test    byte ptr [6E8A6A6B], 80
00404027    3246 52           xor     al, byte ptr [esi+52]
0040402A    4D                dec     ebp
0040402B    55                push    ebp
0040402C    55                push    ebp
0040402D    1D 94803BB9       sbb     eax, B93B8094
00404032    5D                pop     ebp
00404033    F693 7570A7FE     not     byte ptr [ebx+FEA77075]
00404039    F5                cmc
0040403A    04 4E             add     al, 4E
0040403C    2130              and     dword ptr [eax], esi
0040403E    8C2459            mov     word ptr [ecx+ebx*2], fs
00404041    0F23C1            mov     dr0, ecx                          //这里看起来想一个伪指令的开始呢
00404044    E9 8C0B0000       jmp     00404BD5

那么00404000--00404041之间的就是CONTEXT结构,才41h大小呀??远远比一个完整的CONTEXT结构要小很多呢!!
现在按我的理解这个CONTEXT结构指向的是一个内存地址,不是真实的寄存器。既然是内存的一块,要么是作者定义的一个对象,要么是申请的一块内存,
这里更象前者。那这样看来,论坛里讨论虚拟机帖子里给出的那些CONTEXT结构中的EAX,EDX,EIP,EFLAGS都不是真实的寄存器,只是一个变量,一个符号而已!?

接下来我也来到了VM指令解释器:
VM指令解释器:
00404BD5    8A0E            mov     cl, byte ptr [esi]
00404BD7    00D9            add     cl, bl
00404BD9    FEC1            inc     cl
00404BDB    F6D1            not     cl
00404BDD    80E9 47         sub     cl, 47                          //对esi做一系列变换
00404BE0    C0C1 07         rol     cl, 7
00404BE3    46              inc     esi                             //esi++
00404BE4    80F1 C5         xor     cl, 0C5
00404BE7    80E9 CD         sub     cl, 0CD
00404BEA    C0C1 05         rol     cl, 5
00404BED    00CB            add     bl, cl
00404BEF    0FB6C1          movzx   eax, cl                        //eax在这里作为指针
00404BF2    8D1485 48424000 lea     edx, dword ptr [eax*4+404248]  //00404248就是那张大的表的起始地址
00404BF9    FF22            jmp     dword ptr [edx]                //jmp VM_Op_Code

ESI指向PCODE,地址位于VMP区段,这些PCODE是怎么来的呢?有没有什么规律?我现在也不清楚,但是对比了一下程序,我至少知道了它不是从原始程序中来的,
是作者自己安排的。原来的代码还好好的在那躺着呢!(刚开始的时候我认为虚拟机是把原始代指令化后保存在文件中,执行的时候再把这些指令还原,并跑到“虚拟机”中执行指令)
----“上面就是VM的主循环.”

~!·#¥%¥%
前面突然停电了,来电后我用VMP再一次VM了程序,原来的就被覆盖掉了,真不好意思,下面的是新的程序,所以地址跟某些代码有些变化,但大致结构还是差不多的。VMP我还不大会用,每次加的程序运行总会弹出个非法对话框。
接下来这段代码执行了很多次了,就是把堆栈顶端的数据弹到[EDI+EAX*4]这个地址中去。今天我突然觉得这段代码应该是设置CONTEXT结构的,原来我以为这里也是一个伪指令。
00404076    AC              lods    byte ptr [esi]
00404077    00D8            add     al, bl
00404079    34 F9           xor     al, 0F9
0040407B    2C 70           sub     al, 70
0040407D    C0C0 05         rol     al, 5
00404080    2C 0C           sub     al, 0C
00404082    C0C0 06         rol     al, 6
00404085    00C3            add     bl, al
00404087    8F0487          pop     dword ptr [edi+eax*4]
0040408A  ^ E9 87FFFFFF     jmp     00404016
EDI指向CONTEXT结构的呢,eax做为指针。代码把0,edi,esi,ebp---eflags弹到了CONTEXT结构这个地址,这样就设置了一个CONTEXT结构。例如把EAX弹到了XXXX这个地址,就可以把这个地址看成是EAX,应该是这样吧。

接下来应该是执行伪指令了吧????我见大虾们都给它们起了一个很好听的名字.
004045B5    58              pop     eax                              
004045B6  ^ E9 5BFAFFFF     jmp     00404016
把这里命名为p_popeax怎么样???
004042E3    AC              lods    byte ptr [esi]
004042E4    00D8            add     al, bl
004042E6    34 F9           xor     al, 0F9
004042E8    2C 70           sub     al, 70
004042EA    C0C0 05         rol     al, 5
004042ED    2C 0C           sub     al, 0C
004042EF    C0C0 06         rol     al, 6
004042F2    00C3            add     bl, al
004042F4    FF3487          push    dword ptr [edi+eax*4]
004042F7  ^ E9 1AFDFFFF     jmp     00404016

00404228    AD              lods    dword ptr [esi]
00404229    01D8            add     eax, ebx
0040422B    05 972C1742     add     eax, 42172C97
00404230    35 C476D6BE     xor     eax, BED676C4
00404235    05 43E5412D     add     eax, 2D41E543
0040423A    C1C0 10         rol     eax, 10
0040423D    01C3            add     ebx, eax
0040423F    50              push    eax
00404240  ^ E9 D1FDFFFF     jmp     00404016

跟到这里就懒的跟下去拉。。。。如果说上面的都是伪指令,却没有看到修改EIP的,我只看到了VM解释器里的inc esi(有些是lods byte ptr [esi]).
意思是说我只看到程序在跑自己的PCODE,跑完了就到原始的程序接着跑,当然我可没有跟到原始程序,我心疼我的F7跟F8。

目前我对虚拟机的理解就到这里了,也不知道对不对。
前些天我问了一个外星人:
“我觉得VM过的程序只是多了一个VMP区段,把这个区段删掉,再修复PE头里的section,sizeofimage,不就可以了吗?”
“还要修复VM!”
“什么是修复VM呀?”
“就是还原成80X86指令!”
听到这样的答复我立即跑了,太深奥了嘛~!
今天我又拿程序出来对比了下,发现除了多出这个VMP区段以外,还有有一处不一样:

原始程序的:
00401166 >/$  E8 1EFFFFFF   call    00401089
0040116B  |.  6A 00         push    0                                ; /ExitCode = 0
0040116D  \.  E8 5A000000   call    <jmp.&kernel32.ExitProcess>      ; \ExitProcess
00401172   $- FF25 48204000 jmp     dword ptr [<&user32.BeginPaint>] ;  user32.BeginPaint

VM过的:
00401166 > $  68 514E4000   push    00404E51                        //压入PCODE首地址
0040116B   .- E9 4F3A0000   jmp     00404BBF

我这里只有一处不一样,我不知道VM过的程序是否有多处,我把原始程序的二进制代码替换掉VM过的,保存后不要VMP区段也可以运行。难道这样就是修复VM??
如果是的话那可就麻烦大了,如何得知原来的代码是什么呢,CTRL+B搜索不到,疑惑中。。。。。

总结一下今天的理解:
①:VM里有自己的context结构,按我的理解我没有把这个结构与真实的context结构联系起来
②:pcode是作者自己定义的,目前我还没有发现这些pcode跟伪指令有什么联系
③:程序在跑自己的pcode,似乎什么都没有做!
                                                                                                      2008-2-29 下午 1:32:06
                                                                                                                      小娃崽

[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界

收藏
点赞7
打赏
分享
最新回复 (35)
雪    币: 8188
活跃值: (4243)
能力值: ( LV15,RANK:2459 )
在线值:
发帖
回帖
粉丝
ccfer 16 2008-2-29 13:27
2
0
看来有些人需要被多多BS才行
雪    币: 6073
活跃值: (2236)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
forgot 26 2008-2-29 15:54
3
0
替鄙视楼主的人再鄙视一次
雪    币: 1946
活跃值: (238)
能力值: (RANK:330 )
在线值:
发帖
回帖
粉丝
Bughoho 8 2008-2-29 16:40
4
0
我听见脚步声
雪    币: 2134
活跃值: (14)
能力值: (RANK:170 )
在线值:
发帖
回帖
粉丝
Aker 4 2008-2-29 21:28
6
0
有总结就有提高,多多学习
雪    币: 383
活跃值: (41)
能力值: ( LV12,RANK:530 )
在线值:
发帖
回帖
粉丝
小娃崽 13 2008-3-1 16:46
7
0
      
             (替换)                           |-保存CONTEXT结构
原始指令---------->jmp VM--------| 执行PCODE相映的伪指令代码
   |                                           | 恢复CONTEXT结构
   |                                           |-返回原始程序 
   |(修改后)
   |
 PCODE

我打算这样寻找原始指令,context,PCODE,伪指令这四者之间的联系!
我发现我真是太聪明了^_^
雪    币: 6073
活跃值: (2236)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
forgot 26 2008-3-1 18:03
8
0
可惜你找不到
雪    币: 254
活跃值: (126)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
heXer 3 2008-3-1 19:25
9
0
自己找不到不等于别人也找不到
雪    币: 6073
活跃值: (2236)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
forgot 26 2008-3-1 19:35
10
0
PCODE,伪指令被列为2者了
雪    币: 494
活跃值: (629)
能力值: ( LV9,RANK:1210 )
在线值:
发帖
回帖
粉丝
softworm 30 2008-3-1 20:02
11
0
① VM的context与Win32的CONTEXT结构没有关系,但意思相似
② VM指令集是作者自己定义的, pcode==pseduo code==伪码==VM的机器码
③ 程序(VM解释引擎)在跑原x86指令转换的对应pcode,什么都做了

没有看明白楼主打算怎样还原x86指令?
雪    币: 1946
活跃值: (238)
能力值: (RANK:330 )
在线值:
发帖
回帖
粉丝
Bughoho 8 2008-3-1 20:25
12
0
VM+变形不知道楼主想打算怎么还原
雪    币: 398
活跃值: (343)
能力值: (RANK:650 )
在线值:
发帖
回帖
粉丝
shoooo 16 2008-3-1 20:26
13
0
看不见你的笑我怎么睡的着
雪    币: 1946
活跃值: (238)
能力值: (RANK:330 )
在线值:
发帖
回帖
粉丝
Bughoho 8 2008-3-1 20:33
14
0
你那么爱他 为什么不把他留下
雪    币: 213
活跃值: (96)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
云重 1 2008-3-1 20:46
15
0
有些人总觉得自己聪明,受不了啊。实际写的都是人家研究2分钟就看明白东西。
雪    币: 1379
活跃值: (708)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
hmilywen 2008-3-2 13:08
16
0
此贴强人太多,留名~
雪    币: 210
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
breezer 2008-3-2 15:11
17
0
Shoooo 龙猫
雪    币: 383
活跃值: (41)
能力值: ( LV12,RANK:530 )
在线值:
发帖
回帖
粉丝
小娃崽 13 2008-3-2 16:39
18
0
③ 程序(VM解释引擎)在跑原x86指令转换的对应pcode,什么都做了

00404077    00D8            add     al, bl
00404079    34 F9           xor     al, 0F9
0040407B    2C 70           sub     al, 70
0040407D    C0C0 05         rol     al, 5
00404080    2C 0C           sub     al, 0C
00404082    C0C0 06         rol     al, 6
00404085    00C3            add     bl, al
00404087    8F0487          pop     dword ptr [edi+eax*4]
0040408A  ^ E9 87FFFFFF     jmp     00404016

我现在觉得这里也是一个伪指令,把堆栈的数据弹到context,我给它起了个名字VM_SaveContext.rn   rn表示一个寄存器,具体是哪个,跟pcode有关

被VM了的程序,原始指令几乎被肢解到PCDOE里了,不是简单的stolen
再由VM拼装还原....
我现在才开始对VM有点感觉了~!
具体怎么还原vm,我还没找到感觉,那位大虾知道的偷偷告诉我

接下来我打算去看wangdell大虾的文章
雪    币: 6073
活跃值: (2236)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
forgot 26 2008-3-2 16:56
19
0
再由VM拼装还原....
这句错了
雪    币: 255
活跃值: (207)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
peaceclub 6 2008-3-2 17:18
20
0
如果是拼装还原的话,就不要虚拟机了。
虚拟机的概念就是有自己的指令体系

cpu - vm -  *  - vm - vmcode

可以有若干套vm嵌套的.

其实,理解起来很容易,把虚拟机当成vb的pcode也就差不多了
雪    币: 2314
活跃值: (129)
能力值: (RANK:410 )
在线值:
发帖
回帖
粉丝
shellwolf 10 2008-3-2 17:31
21
0
个人理解,分析vm有两种方法,一种是跟到里面去,直接攻城(这你要有时间和精力,这恐怕正是vmprotect公司所希望的).另一种是打外围,农村包围城市.
我觉得第二种更容易些.把vm当成一个黑盒子,用工具分析和记录其行为,猜测内部代码.比如做了哪些reg操作,做了那些文件操作,是否有访问网络,也可以从系统api开始,因为毕竟它还没有模拟api.进入api时,它要先从vm中出来.
雪    币: 332
活跃值: (1663)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
sungy 1 2008-3-2 23:29
22
0
如果说需要修改的代码在VM中,或者注册保护代码被VM了,那怎么分析程序,修改程序呢?
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
zhucheba 2008-3-3 09:43
23
0
看来有些人需要被多多BS才行
雪    币: 1844
活跃值: (35)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
yingyue 2008-3-3 13:03
24
0
楼主应该错了,不是在VM中重生,是在VM中YD
雪    币: 1844
活跃值: (35)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
yingyue 2008-3-3 13:03
25
0
发多了一贴
游客
登录 | 注册 方可回帖
返回