这个cm 是前天晚上八两兄发给我的, 外壳检测是vmp, 但是 text段的虚拟机
试了几次都没有用插件找到 ,插件不能用,于是就当做一般的虚拟机来分析了
,首先跟踪一下代码
以下是跟踪记录的一小部分,可以参考附件中的trace.asm:
-------------
044B351 ...
044B35B retn 0x38 ;这里是dispatcher 的出口
044917D ...
0449188 jmp 00449BD0
0449BD0 ...
0449BD8 jmp 0044B8AB
044B8AB ...
044B8AC jpe 00449DF7
0449DF7 ...
0449E08 jmp 0044A752
044A752 ... ;dispatcher 的入口
044A764 jns 0044A122
044A122 ...
044A167 jmp 00449139
0449139 ...
044917A retn 0x54 ;这里也是出口
0449C2D ...
0449C56 call 0044B214
044B214 ...
044B229 jmp 0044A752
044A752 ... ;dispatcher 的入口
044A764 jns 0044A122
-------------
虚拟机的运行 就是一个由dispatcher 到 handler 的循环 ,
入口和出口都是不断重复的,所以不难分析出来
变形的代码出口无所谓几种 , 一种是 retn xxx , 另一种是 call eax
写一个脚本再跟踪一下它的vm
-------------
mov vmEntry,0044A755
mov dispatcher,0044AC99
mov dispatcher2,0044917A
bc
bp vmEntry
bp dispatcher
bp dispatcher2
mov file,"c:\\out.txt"
wrt file,"--------"
var vip
loop:
run
ifeq eip,vmEntry
mov vip,esi
else
mov top,[ebp]
sub top,4
ifeq top,ebp
wrta file, "maybe vPushEsp up"
endif
endif
ifeq eip,dispatcher
eval "{vip}--{ecx}"
wrta file,$RESULT
endif
ifeq eip,dispatcher2
eval "{vip}--{ecx}"
wrta file,$RESULT
endif
jmp loop
-------------
结果很长 , 就帖一部分吧,参考附件中的 out.txt
-------------
4B41EE--44917D
4B41EF--449C2D
4B41F0--449E60
4B41F1--449E60
4B41F2--449014 ;vjmp
4A3AD0--449C2D
4A3AD1--44BE95
4A3AD6--44917D
4A3AD7--449C2
-------------
中间用空行分开了,很明显这是一个 vjmp,至此程序注册的流程也出来了
-------------
4E1168--4E1D66
495BFB--495CD2
4B3FCD--4B41F2
4A3AD0--4A3ED7
-------------
由于没有分析 handler , 不好分析vm代码, 但是基于栈的虚拟机
,要实现结点的计算,有一个 handler 是肯定要用的, 大家猜一下 ^_*
后面的分析就不用细讲了,无所谓试验几个结点 ,没啥含量
不能补丁虚拟码了, 这次使用另一种补丁的方法:
-------------
<00449014>
call 004EB900
nop
nop
<004EB900>
pushfd
cmp esi, 0x4B41F3
jnz short @func
mov dword ptr [ebp], 0x4D12B7
@func:
popfd
mov esi, dword ptr [ebp]
retn
-------------
试验一下:
爆破程序主要代码如下,参考loader.exe:
-------------
void test2(){
BYTE patch1[0x0007] = { 0xe8, 0xe7, 0x28, 0x0a, 0x00, 0x90, 0x90 };
BYTE patch2[0x0015] = { 0x9c, 0x81, 0xfe, 0xf3, 0x41, 0x4b, 0x00, 0x75, 0x07, 0xc7, 0x45, 0x00, 0xb7, 0x12, 0x4d, 0x00, 0x9d, 0x8b, 0x75, 0x00, 0xc3 };
Loader l = Loader("209 CRECKME 0.vmp.exe");
l.run();
l.tilWindow("CRECKME STEP0");
l.patch(0x00449014,(LPVOID)patch1,0x7);
l.patch(0x004EB900,(LPVOID)patch2,0X15);
return;
}
-------------
写在最后:
前几天天气太执, 有点小郁闷 , 实在没啥心情研究技术 , 本来不想写vm的东西了
,和八两聊天的时候 ,提到有另一种不需要补丁虚拟码的方法 (毕竟依赖插件不好) ,这个就算是补充吧
附件下载: 某vm的破解.7z
下午还要写c# , 帖子写得比较粗, 见谅
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!