本帖最后由 tk86935367 于 2012-5-9 19:04 编辑
这个是比赛的一个crackme,偶对反虚拟机比较感兴趣,所以就来测试这个程序。
至于反反虚拟机,大概就是两个方式了,一种是不让程序监测是否在虚拟机中运行,另一种就是监测后不允许它有上面动作,这篇就是这个道理。
crackme下载地址: http://files.cnblogs.com/tk091/crackme2.7z
很习惯的,首先查壳,ASPack 2.12 -> Alexey Solodovnikov,很简单,一个esp定律就搞定,dump后再说。 dump后的文件下载: http://files.cnblogs.com/tk091/dump.rar 运行后发现这个程序是反虚拟机的,反虚拟机的方式有很多,比如,通过特权指令来检测、利用IDT基址检测、利用LDT和GDT的检测方法、基于STR(Store Task Register)的检测方法、通过注册表检测虚拟机(是否安装了tools工具等)、基于时间差的检测方式(通过RDTSC)、利用虚拟硬件指纹检测(对MAC地址检查等)等。
通过分析发现,这个crackme是通过特权指令来检测虚拟机的,有两种方式去除,一种是不让它检测,一种是检测后什么都不干(默认会显示提示并两秒后自动退出)。 我们用IDA来看看程序大致的流程,其中有一部分是:
瞬间就看到了dwMilliseconds,毫秒嘛,那么就是检测到虚拟机后的动作了,我们让它跳过这个,也就是不处理这段程序。 进入main函数的起始: 找到关键跳:
1 0040CACF |. /75 2C jnz short 0040CAFD
2 0040CAD1 |. |8D8D 0CFBFFFF lea ecx, dword ptr [ebp-4F4]
3 0040CAD7 |. |51 push ecx
4 0040CAD8 |. |68 C80D4200 push 00420DC8 ; ASCII "%s",LF
5 0040CADD |. |E8 024EFFFF call 004018E4
6 0040CAE2 |. |83C4 08 add esp, 8
7 0040CAE5 |. |8BF4 mov esi, esp
8 0040CAE7 |. |68 D0070000 push 7D0 ; /Timeout = 2000. ms
9 0040CAEC |. |FF15 F4624200 call dword ptr [<&kernel32.Sleep>] ; \Sleep
10 0040CAF2 |. |3BF4 cmp esi, esp
11 0040CAF4 |. |E8 134AFFFF call 0040150C
12 0040CAF9 |. |33C0 xor eax, eax
13 0040CAFB |. |EB 79 jmp short 0040CB76 ; 检测到虚拟机,跳转到程序退出的地方
上面的第一行就是关键跳,即是跳转到正常的代码,直接修改为jmp,然后保存即可。这样,程序执行到这里的时候就会直接跳过。 下面是去掉反虚拟机后的程序: http://files.cnblogs.com/tk091/Anti-Anti-virtual.rar 下面是完整的反虚拟机的汇编代码: 1 00401400 > \55 push ebp
2 00401401 . 8BEC mov ebp, esp
3 00401403 . 6A FF push -1
4 00401405 . 68 68004200 push 00420068
5 0040140A . 68 E4204000 push 004020E4 ; SE 处理程序安装
6 0040140F . 64:A1 0000000> mov eax, dword ptr fs:[0
7 00401415 . 50 push eax
8 00401416 . 64:8925 00000> mov dword ptr fs:[0], esp
9 0040141D . 83C4 B4 add esp, -4C
10 00401420 . 53 push ebx
11 00401421 . 56 push esi
12 00401422 . 57 push edi
13 00401423 . 8965 E8 mov dword ptr [ebp-18], esp
14 00401426 . 8D7D A4 lea edi, dword ptr [ebp-5C]
15 00401429 . B9 11000000 mov ecx, 11
16 0040142E . B8 CCCCCCCC mov eax, CCCCCCCC
17 00401433 . F3:AB rep stos dword ptr es:[edi]
18 00401435 . C645 E4 01 mov byte ptr [ebp-1C], 1
19 00401439 . C745 FC 00000> mov dword ptr [ebp-4], 0
20 00401440 . 52 push edx
21 00401441 . 51 push ecx
22 00401442 . 53 push ebx
23 00401443 . B8 68584D56 mov eax, 564D5868
24 00401448 . BB 00000000 mov ebx, 0
25 0040144D . B9 0A000000 mov ecx, 0A
26 00401452 . BA 58560000 mov edx, 5658
27 00401457 . ED in eax, dx
28 00401458 . 81FB 68584D56 cmp ebx, 564D5868
29 0040145E . 0F9445 E4 sete byte ptr [ebp-1C]
30 00401462 . 5B pop ebx
31 00401463 . 59 pop ecx
32 00401464 . 5A pop edx
33 00401465 . C745 FC FFFFF> mov dword ptr [ebp-4], -1
34 0040146C . EB 14 jmp short 00401482
35 0040146E . B8 01000000 mov eax, 1
36 00401473 . C3 retn
至于后面的分析,就难了,我加了些注释,希望能够继续分析
1 0040CAFD BA 01000000 mov edx, 1 2 0040CB02 |. 85D2 |test edx, edx
3 0040CB04 |. 74 6E |je short 0040CB74 ; 跳到 结束
4 0040CB06 |. 8D85 5CFBFFFF |lea eax, dword ptr [ebp-4A4]
5 0040CB0C |. 50 |push eax ; 0012FADC please input password:
6 0040CB0D |. 68 74004200 |push 00420074 ; ASCII "%s "
7 0040CB12 |. E8 CD4DFFFF |call 004018E4
8 0040CB17 |. 83C4 08 |add esp, 8 ; 恢复堆栈
9 0040CB1A |. 8D8D FCFBFFFF |lea ecx, dword ptr [ebp-404]
10 0040CB20 |. 51 |push ecx ; 输入scanf
11 0040CB21 |. 68 6C0D4200 |push 00420D6C ; ASCII "%s"
12 0040CB26 |. E8 894DFFFF |call 004018B4 ; 输入的信息保存在堆栈中
13 0040CB2B |. 83C4 08 |add esp, 8
14 0040CB2E |. 8D95 FCFBFFFF |lea edx, dword ptr [ebp-404]
15 0040CB34 |. 52 |push edx
16 0040CB35 |. E8 CB44FFFF |call 00401005 ; 可能的关键call
17 0040CB3A |. 83C4 04 |add esp, 4
18 0040CB3D |. 8945 FC |mov dword ptr [ebp-4], eax ; 这两句相当于test eax,eax
19 0040CB40 837D FC 00 cmp dword ptr [ebp-4], 0
20 0040CB44 75 16 jnz short 0040CB5C ; 进行判断
21 0040CB46 |. 8D85 C4FBFFFF |lea eax, dword ptr [ebp-43C]
22 0040CB4C |. 50 |push eax
23 0040CB4D |. 68 C80D4200 |push 00420DC8 ; ASCII "%s",LF
24 0040CB52 |. E8 8D4DFFFF |call 004018E4 ; 调用printf函数
25 0040CB57 |. 83C4 08 |add esp, 8
26 0040CB5A |. EB 16 |jmp short 0040CB72
27 0040CB5C |> 8D8D 90FBFFFF |lea ecx, dword ptr [ebp-470] ; 这里是正确信息保存的位置
28 0040CB62 |. 51 |push ecx
29 0040CB63 |. 68 C80D4200 |push 00420DC8 ; ASCII "%s",LF
30 0040CB68 |. E8 774DFFFF |call 004018E4
31 0040CB6D |. 83C4 08 |add esp, 8
32 0040CB70 |. EB 02 |jmp short 0040CB74 ; 结果正确,跳出循环
33 0040CB72 |>^ EB 89 \jmp short 0040CAFD ; 重新开始判断算法分析始终是个大难题。
程序的分析就大致这样吧。 勿在浮沙筑高台,还是回去好好学基础吧。 -----2012-5-2-22:10---------继续分析---------- 通过52的几个大牛的帮助 (http://www.cnblogs.com/tk091/archive/2012/04/27/2473170.html
|