首页
社区
课程
招聘
[原创]SVMP 第二弹 寻找加解密代码.
发表于: 2014-10-19 11:16 11044

[原创]SVMP 第二弹 寻找加解密代码.

2014-10-19 11:16
11044
我又来打扰各位前辈了, 小弟上次发帖希望各位前辈能对我个人写的SVMP给予指点不足。
但下载量极小,让小弟我鼻子酸酸的,无奈自己无法提供物质上的奖品来激励各位前辈对本小弟写的SVMP进行攻破还原。

由于本人所写的SVMP还在开发测试阶段,所以该SVMP 不带任何花指令 以及 Anti, 并且SVMP的编译器也不会给原始代码生成花指令, 所以编译加密后的代码虽然是中间代码, 但绝对是原原本本的原始代码,这一层不会给分析者加大分析难度。

派遣函数暴漏十分明显, hook后可以记录所有handler;   

本身使用SVMP加密后的PE也不带任何花指令 以及 Anti.

SVMP是从渺小慢慢扩展的, 每一次小更新我都会发上来给前辈们分析, 基于只一套机制,希望热爱分析虚拟机的前辈也能从中慢慢提高, 并给于SVMP的不足给于指点,我们相互学习,相互探讨。

SVMP更新内容:
1. 修改所有跳转指令的绝对地址计算方式
2. 增加虚拟CPU内存中随机化的功能 [目前只给8个通用寄存器附加该功能]
3. 修改虚拟机栈的处理方式 [为了配合开启了地址空间随机化的PE文件]
4. 支持对开启了空间地址随机化的PE文件进行加密



附加说明:  [如果附加运行有崩溃信息, 希望前辈们提出]
1. 请输入一个4字节的16进制数 例如:
输入>>03020100   [表示输入的是 0x03020100]

为了便于观察输入输出, 请按照上面的方式进行输入.

输出第一行为加密后的数据.
输出最后一行为解密后的数据.

最后祝大家周末愉快.

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

上传的附件:
收藏
免费 0
支持
分享
最新回复 (19)
雪    币: 6
活跃值: (1151)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
开源不是更好,不然没人关注你这个玩意儿
2014-10-19 14:38
0
雪    币: 1844
活跃值: (35)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
3
刚追了一下,眼睛开始流泪了 (所以很久都不碰这些东西了) ,珍惜生命,远离解密 。。。。。再反追一下估计可以还原的 。。。暂时如下

输入 12345678   , 结果是  4f d1 89 57

           4BB7A3F0 - D49A9B6D = 771D0883
           771D0883 + 88E2F7E5 = 68

           4BB7A3F0 - D49A9B6D = 771D0883
           771D0883 + 88E2F7EF = 72

            4BB7A3F0 - D49A9B6D = 771D0883
            771D0883 + 88E2F842 = C5

            4BB7A3F0 - D49A9B6D = 771D0883
            771D0883 + 88E2F858 = DB

上面的 68  72  C5  DB  再经下面的最后解码的出  4f  d1  89 57  

00415F99      mov     al, byte ptr ss:[ebp-0xF8]
00415F9F      or        al, byte ptr ss:[ebp-0x104]
00415FA5      mov     cl, byte ptr ss:[ebp-0xF8]
00415FAB      and      cl, byte ptr ss:[ebp-0x104]
00415FB1      add      al, cl
00415FB3      mov     byte ptr ss:[ebp-0xF8], al
2014-10-19 21:28
0
雪    币: 1844
活跃值: (35)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
4
嗯,刚才在跟了一下,可以还原了,但要跟你原来一样代码估计不行 。。

但弄懂后,就懒得写代码了 。。。当我吹牛吧
2014-10-19 22:26
0
雪    币: 51
活跃值: (30)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
5
您好, 您得第一回答我没看明白, 您可以解释一下吗? 然后就是您随后贴出来的代码是您还原得出的代码,还是您自己写的公式套出来的代码了? 根据我看到您回答的内容, 暂时是不正确的,也许是我没看懂您最上面的回答。

2014-10-19 22:59
0
雪    币: 1844
活跃值: (35)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
6
嗯,不算完全逆向,有一部分是从代码里面猜测的,但可以写个跟你一模一样的出来,出来结果跟你的一样
毕竟时间比较短,全部看的完,那是骗人的

还有,我上面给出的额结果是正确的,我从各个不同的输入都得到更你一样的答案
今晚太夜了,眼睛不舒服,明早回去有空模拟一个出来 。。呵呵
2014-10-19 23:28
0
雪    币: 51
活跃值: (30)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
7
您好,眼睛不舒服就早点休息吧, 明个有空我们再来讨论, 我目前大概知道您已经走到哪一步了,您应该是到了生成KEY,加密那一步了。 但那只是2个函数的调用过程, 我特意留下没有使用SVMP虚拟化的, 因为总得留下线索,其实在更前面的位置,就已经有了这两个函数的线索。但是了,这两个函数的里面的代码是经过SVMP虚拟化了的,关键是看您能不能还原出实现代码,当然完全一模一样也没有必要, 您只要还原出大概的,或者是相同的功能, 给出几个指令handler也算是可以了。

然后就是您应该也看了这两个函数之后的一个过程,是被SVMP虚拟机保护了的, 然后才到printf. 您应该更具堆栈得知加密后的数据再一次经过了处理, 然后您还给出了代码, 但是那段代码是错误的,
但或许您指的 [ebp-0xf8] [ebp-0x104] 是您自己写出来的代码, 没有给出具体输入输出所以我也没有办法写代码验证您的答案, 至于最上面的 + -表达式, 我是真的一点都没有看明白, 还请您给于指点一下。

早点休息吧, 晚安。
2014-10-19 23:41
0
雪    币: 1844
活跃值: (35)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
8
+ - 只是我从 OD 里最开始截取结果的方式,可以忽略,打个譬如,如果你这个是注册机制的话,我已经可以写出
注册机了 。。。。。。,真要睡了,8.。。。。。
2014-10-19 23:51
0
雪    币: 51
活跃值: (30)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
9
恩,这个要写注册机很简单的,一个简单的列子:
[>>00000000] == [3d fd 3b ff]
[>>01010101] == [3c fc 3c 00]

根据上面的过程, 在加上第一结果跟第二结果做一次比较, 就可以出注册机了。

所以, 结果是不重要的, 关键是代码的还原程度, 因为如果我把过程换成另外的领域,比如一个线程的启动过程,初始化代码, 那么就没有这些输出参考了, 只能还原出原始代码, 才能算是解密。

今天确实晚了, 悲剧, 明天还要上班, 8.
2014-10-20 00:05
0
雪    币: 1844
活跃值: (35)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
10
上面加法产生在下面的代码处,昨天是正向追踪的,也发现里面的结构啊什么的,但实在怕麻烦,没有分析下去了,但是没能搞清楚,毕竟繁杂了,这和 vmp 不同,那东西搞了很久,很多东西都给时间磨平了 。。。。。 并且还是当年热情高涨的时候  

00406960       > mov     ecx, dword ptr ss:[ebp-0x3C4]
00406966       .  sub      ecx, dword ptr ss:[ebp-0x3C8]
0040696C       .  mov     edx, dword ptr ss:[ebp-0x14A0]
00406972       .  add      ecx, dword ptr ds:[edx]                    昨天贴的那个记录就是从这,用脚本上记录下来的
00406974       .  mov     dword ptr ss:[ebp-0x374], ecx

随手写了个,还不保证有错误,试了一下感觉ok  .... 分析真是累人的活
楼主这坑挖的深啊,强大,哪里学的 。。。。。。难道是 。。山东济。。。

刚才测试了一下,貌似有很小部分得出结果不一致 (等我修改一下)
2014-10-20 15:42
0
雪    币: 51
活跃值: (30)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
11
原来你是在这里记录的, 这里是从虚拟CPU里面取出一个数据或是转换一个数据时做的操作, 你发出来的这几行代码是一个虚拟CPU数据的加密解密过程, 这些代码在全局里面都会包含, 就这个位置往下走才是handler。
输入的加密解决绝不是这里, 这里只是一个虚拟CPU原子操作地点, 一条指令不见得会来一次。
原始代码在PE文件里面肯定是没有了的, 写注册机不需要逆向都可以, 你只要从00 到 ff 依次输入观察加密后的数据 就可以很简单的实现注册机了。

我们不看结果,只看对原始代码还原的程度。

另外您写的这个注册机, 只是针对了我这一个KEY, 我不需要修改生成KEY 跟加密解密的代码,只需要修改初始化子KEY的代码, 您的注册机就会失效。

您想一下, 我这里使用的是32字节的子KEY, 您需要写多少注册机才能应付所有的输入输出?
您目前并不是通过源代码来写出注册机,完全是靠猜测的,因为您应该是还没有解决创建KEY那一块代码。

关于第一层函数源代码我发出来, 有助于您分析,该函数内部所有的call 均使用Function代替原始函数名:

VOID __declspec(naked)Function(VOID){

        __asm push ebp;
        __asm mov ebp, esp;
        __asm sub esp, 0x428;

        __asm push eax;
        __asm push ebx;
        __asm push ecx;
        __asm push edx;
        __asm push esi;
        __asm push edi;
       
        // 需要加密的代码段  这里我简单的生成子KEY 非常简单的代码[您可以依据这里分析虚拟机]
        SYS_PROTECT_BEGIN('f', 'o', 'r', 'c', 'o', 'd', 'e', 0, 0);
        __asm xor ecx, ecx;
        __asm jmp __for_key_cmp;
__for_key_start:
        __asm add ecx, 0x1;
__for_key_cmp:
        __asm cmp ecx, 32;
        __asm je __for_key_end;
        __asm lea eax, dp[ebp - 0x20];
        __asm mov bp[eax + ecx], cl;
        __asm jmp __for_key_start;
__for_key_end:
        SYS_PROTECT_END();
       
        // 生成key
        __asm push 32;
        __asm lea edx, dp[ebp - 0x20];        // 子KEY
        __asm push edx;
        __asm lea edx, dp[ebp - 0x428];        // 生成的EKY
        __asm push edx;
        __asm call dp[Function];                // 生成KEY的函数 [该函数内部使用SVMP加密]
        __asm add esp, 0xc;

        // 加密
        __asm push 4;
        __asm mov edx, dp[ebp + 0x8];                // 加密的字节 也就是 0x12345678 您输入的
        __asm push edx;
        __asm lea edx, dp[ebp - 0x428];                // KEY
        __asm push edx;
        __asm call dp[Function];                // 加密函数 [该函数内部使用SVMP加密]
        __asm add esp, 0xc;

        // 需要加密的代码段
        SYS_PROTECT_BEGIN('a', 'd', 'd', 'c', 'o', 'd', 'e', 0, 0);
        // 额外加
        __asm mov al, 0xef;
        __asm mov ecx, dp[ebp + 0x8];
        __asm add bp[ecx + 0x0], al;
        __asm mov al, 0x17;
        __asm add bp[ecx + 0x1], al;
        __asm mov al, 0x0c;
        __asm add bp[ecx + 0x2], al;
        __asm mov al, 0x74;
        __asm add bp[ecx + 0x3], al;
        SYS_PROTECT_END();

        __asm mov edx, dp[ebp + 0x8];
        __asm movzx edx, bp[edx + 0x0];
        __asm push edx;
        __asm mov edx, dp[ebp + 0x8];
        __asm movzx edx, bp[edx + 0x1];
        __asm push edx;
        __asm mov edx, dp[ebp + 0x8];
        __asm movzx edx, bp[edx + 0x2];
        __asm push edx;
        __asm mov edx, dp[ebp + 0x8];
        __asm movzx edx, bp[edx + 0x3];
        __asm push edx;
        __asm lea edx, dp[g_Msg];
        __asm push edx;
        __asm call dp[printf];
        __asm add esp, 0x14;

        // 生成key
        __asm push 32;
        __asm lea edx, dp[ebp - 0x20];
        __asm push edx;
        __asm lea edx, dp[ebp - 0x428];
        __asm push edx;
        __asm call dp[Function];
        __asm add esp, 0xc;

        // 需要加密的代码段
        SYS_PROTECT_BEGIN('s', 'u', 'b', 'c', 'o', 'd', 'e', 0, 0);
        // 额外减
        __asm mov al, 0xef;
        __asm mov ecx, dp[ebp + 0x8];
        __asm sub bp[ecx + 0x0], al;
        __asm mov al, 0x17;
        __asm sub bp[ecx + 0x1], al;
        __asm mov al, 0x0c;
        __asm sub bp[ecx + 0x2], al;
        __asm mov al, 0x74;
        __asm sub bp[ecx + 0x3], al;
        SYS_PROTECT_END();

        // 解密
        __asm push 4;
        __asm mov edx, dp[ebp + 0x8];
        __asm push edx;
        __asm lea edx, dp[ebp - 0x428];
        __asm push edx;
        __asm call dp[Function];
        __asm add esp, 0xc;

        __asm mov edx, dp[ebp + 0x8];
        __asm movzx edx, bp[edx + 0x3];
        __asm push edx;
        __asm mov edx, dp[ebp + 0x8];
        __asm movzx edx, bp[edx + 0x2];
        __asm push edx;
        __asm mov edx, dp[ebp + 0x8];
        __asm movzx edx, bp[edx + 0x1];
        __asm push edx;
        __asm mov edx, dp[ebp + 0x8];
        __asm movzx edx, bp[edx + 0x0];
        __asm push edx;
        __asm lea edx, dp[g_Msg];
        __asm push edx;
        __asm call dp[printf];
        __asm add esp, 0x14;

        __asm pop edi;
        __asm pop esi;
        __asm pop edx;
        __asm pop ecx;
        __asm pop ebx;
        __asm pop eax;

        __asm add esp, 0x428;
        __asm pop ebp;
        __asm ret;
}

期待您把创建KEY的注册机也写出来,希望您从还原原始代码下手。
2014-10-20 16:27
0
雪    币: 1844
活跃值: (35)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
12
嗯,的却是从代码入手 。。。但这活有点大了,你的写的不错,足够复杂了 。。。。。
2014-10-20 16:38
0
雪    币: 51
活跃值: (30)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
13
00F51E1F   push        esp
00F51E20   push        ebp
00F51E21   push        eax
00F51E22   push        ebx
00F51E23   push        ecx
00F51E24   push        edx
00F51E25   push        esi
00F51E26   push        edi
00F51E27   pushfd
00F51E28   sub         esp,0x6C        ; 'l'
00F51E2B   wait
00F51E2C   fsave       [esp]
00F51E2F   push        0x1000
00F51E34   call        malloc (00F62DCC)
00F51E39   add         esp,4
00F51E3C   add         esp,0x6C        ; 'l'
00F51E3F   add         eax,0x1000
00F51E44   mov         esi,esp
00F51E46   sub         esi,0x6C        ; 'l'
00F51E49   mov         edi,eax
00F51E4B   sub         edi,0x90
00F51E51   mov         ecx,0x1B
00F51E56   rep         movsd
00F51E58   pop         [eax-0x24]
00F51E5B   pop         [eax-0x20]
00F51E5E   pop         [eax-0x1C]
00F51E61   pop         [eax-0x18]
00F51E64   pop         [eax-0x14]
00F51E67   pop         [eax-0x10]
00F51E6A   pop         [eax-0xC]
00F51E6D   pop         [eax-0x8]
00F51E70   pop         [eax-0x4]
00F51E73   push        eax
00F51E74   call        sub_00F51E7B (00F51E7B)
00F51E79   jmp         sub_00F51E7B+0x5 (00F51E80)
00F51E7B   mov         eax,[esp]
00F51E7E   push        eax
00F51E7F   ret
00F51E80   lea         edx,[MainFor (00F80610)]
00F51E86   push        edx
00F51E87   call        SysVMProtectFunction (00F52D40)
00F51E8C   add         esp,4
00F51E8F   pop         eax
00F51E90   pop         eax
00F51E91   mov         edi,[eax-0x24]
00F51E94   push        edi
00F51E95   popfd
00F51E96   mov         edi,[eax-0x20]
00F51E99   mov         esi,[eax-0x1C]
00F51E9C   mov         edx,[eax-0x18]
00F51E9F   mov         ecx,[eax-0x14]
00F51EA2   mov         ebx,[eax-0x10]
00F51EA5   push        esi
00F51EA6   mov         esi,eax
00F51EA8   sub         esi,0x90
00F51EAE   push        edi
00F51EAF   push        ecx
00F51EB0   sub         esp,0x6C        ; 'l'
00F51EB3   mov         edi,esp
00F51EB5   mov         ecx,0x1B
00F51EBA   rep         movsd
00F51EBC   frstor      [esp]
00F51EBF   add         esp,0x6C        ; 'l'
00F51EC2   pop         ecx
00F51EC3   pop         edi
00F51EC4   pop         esi
00F51EC5   push        edi
00F51EC6   mov         edi,[eax-0xC]
00F51EC9   pushad
00F51ECA   pushfd
00F51ECB   sub         eax,0x1000
00F51ED0   push        eax
00F51ED1   call        free (00F62D94)
00F51ED6   add         esp,4
00F51ED9   popfd
00F51EDA   popad
00F51EDB   mov         eax,edi
00F51EDD   pop         edi

上面这段代码,  就是:
SYS_PROTECT_BEGIN(...);
SYS_PROTECT_END();

包含的代码被SVMP的编译器提取出来后插入的虚拟机入口代码, 这入口是很明显的.
然后原始代码是被svmp的编译器删除了的, 所以里面肯定不会有源代码, 您最早之前的 + -法肯定不是加密函数的源代码。

不过您刚才说的地址记录, 我到是想到了一个安全隐患, 真的非常感谢您的无私奉献,下一次更新我将完全重写虚拟CPU的读写方式。

在此感谢您,希望您可以继续分析下去, 在给俺挖点坑出来,
2014-10-20 16:49
0
雪    币: 1844
活跃值: (35)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
14
下次你做个 cm 吧 。。。。,玩的人估计会多些
2014-10-20 16:59
0
雪    币: 51
活跃值: (30)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
15
好, 我下班后开始整一个。
您的这个意见不错。
感谢。
2014-10-20 17:02
0
雪    币: 81
活跃值: (100)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
16
讨论手动还原虚拟机没什么意义吧,手动只要愿意,早晚能还原出来的,太慢了没有实际价值而已
关键是能否建模做一个半自动或者全自动的分析器出来,能做出来你的虚拟机强度就没什么意义

从cracker角度来看,只要能攻破,谁关心是否能还原源代码呢
2014-10-21 11:41
0
雪    币: 51
活跃值: (30)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
17
您好,感谢您的意见。
说实话, 我一直没有说我这个是CrackMe,并且Cracker 除了‘过’ 之外, 难道您就没有学习过您'过'掉的那些加解密的实现吗?如果您学习了,您是不是也看过它们的实现代码呢?
2014-10-21 12:16
0
雪    币: 81
活跃值: (100)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
18
虚拟机本身是个新的概念,值得学习,有了大概念以后之后就是一些小打小闹了,并没有本质上的变化。是否有必要去再花大精力弄清楚每个细节取决是东西是否有这个价值
2014-10-21 13:10
0
雪    币: 51
活跃值: (30)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
19
您好,感谢您的回复。
阁下一定是对虚拟机有很深的分析成果了。
阁下是要告诉我造轮子并没有什么意义吗?
其实从我设计 编程语言 到各类工具,哪怕小到一个抓包器,到现在正在设计的SVMP,我都明白一个道理,那就是这些东西已经都有了,它们也都有了你说的大概念以及小打小闹的那些价值。
但我从来没有认为造轮子是件没有意义的事,所以一直在坚持。

好比您设计了一套Anti,您是否也想知道它的强度了?您的Anti在与同行交流时,您想听到的是什么呢?

2014-10-21 13:34
0
雪    币: 154
活跃值: (90)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
楼主厉害啊,我的qq:1838813638,  请教点问题
2016-6-24 16:13
0
游客
登录 | 注册 方可回帖
返回
//