吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 6067|回复: 13
收起左侧

[CrackMe] 【吾爱2013CM大赛解答】----驱动crackme -- 网际座山雕 CM解题过程+KEYGEN源码

  [复制链接]
Sandman 发表于 2013-12-14 03:21
CM是什么?Crackme是什么?这是什么东西?楼主发的什么?
他们都是一些公开给别人尝试破解的小程序,制作 Crackme 的人可能是程序员,想测试一下自己的软件保护技术,也可能是一位 Cracker,想挑战一下其它 Cracker 的破解实力,也可能是一些正在学习破解的人,自己编一些小程序给自己破解,KeyGenMe是要求别人做出它的 keygen (序号产生器), ReverseMe 要求别人把它的算法做出逆向分析, UnpackMe 是要求别人把它成功脱壳,本版块禁止回复非技术无关水贴。

本帖最后由 Sandman 于 2013-12-14 12:00 编辑

【文章标题】 【吾爱2013CM大赛解答】----驱动crackme -- 网际座山雕 CM解题过程+KEYGEN源码
【文章作者】 Sandman
【作者邮箱】
【作者主页】 无~
【软件名称】 CrackMe
【下载地址】 http://www.52pojie.cn/thread-228427-1-1.html
【加壳方式】 无~
【保护方式】 无~
【编写语言】 VC
【使用工具】 OD+IDA
【操作平台】 XPSP3
【软件介绍】 吾爱2013CM大赛题目

由于本题目涉及到RING3程序与RING0程序通信,考虑到常见的应用程序与驱动程序通信方式为CreateFileA+DeviceIoControl方式,使用OD将程序载入后,在CreateFileADeviceIoControl函数上下断点。F9运行后,在序列号输入Edit输入任意字符串后,回车,程序在CreateFileADeviceIoControl函数上断下。


OD断点可知,驱动程序创建一个\\.\crackme的符号链接用于与应用程序通信。其中DeviceIoControl函数对驱动程序的控制码为0x222004,查看InBuffer内容,可知程序送往RING0Buffer内容为机器码+用户设置的序列号,Buffer长度为0x103字节。


DeviceIoControl函数执行到返回,查看返回Buffer,发现返回Buffer10字节发生了变化,肯定是驱动程序对这个Buffer做了什么。



SYS拖到IDA反编译,发现只有6个函数,分别为驱动程序的各个派遣函数,其中sub_10748为驱动程序的DeviceIoControl的处理例程,选择此函数进行F5,找到对驱动控制码0x222004相应的部分,结果如下:

由上述伪代码可知,注册码长度为9位,返回应用程序的格式为:
pIoBuffer = RegCode - MachineCode + 1;
现在继续回到OD,在DeviceIoControlOutputBuffer上下硬件访问断点,长度为1。因为后面的注册码验证部分肯定是要读取这部分数据的。F9后,断下。进入如下循环体


其中ECX控制循环计数。
下面的代码实际上是EAX = EAX * ECX
其中EAX为结果的低32位,EDX为结果的高32位。
00401B7B  .  B8 398EE338   mov    eax, 38E38E39
00401B80  .  F7E1          mul     ecx
00401B82  .  D1EA          shr     edx, 1
EDX左移一位,总体上来看,实际是ECX * 0x38E38E39 的结果右移了33:
EDX = (ECX * 0x38E38E39) shr 33

M= (ECX * 0x38E38E39) / 2n  其中n=33  ECX > 0 M>0 ECXM均为整数
因此,EDX = ECX / 9

上述代码段从0x4438F8处读取1字节的数据,与0xE0比较,如果小于等于则与驱动返回数据中的一个字节做减法,这个字节是谁取决于ECX除以9的结果(并且9次一个循环),并将结果保存至0x446780处,一共循环0xA3次。
上述代码对应的C语言表示为:

[C] 纯文本查看 复制代码
[/align]
[align=left]VOID DecryptCode(PUCHAR SrcBuffer,PUCHAR KeyBuffer)
{
         int i;
         unsigned char j;
         for(i=0;i<0xA3;i++)
         {
                  if(Buffer[i]<=0xE0)
                  {
                          j = i / 9;
                          j += j*8;
                          j = i -j;
                          DstBuffer[i] = SrcBuffer[i] - KeyBuffer[j];
                  }
         }
}[/i][/i][/align][i][i]
[align=left][i]

待上述代码解密完成后,继续跟。


其中有2段代码引起注意:
cmp byte ptr [446822],0x21.............................1
还有
mov eax,00406780...........................................2
call eax

其中代码1判断0x00406780 + 0xA2的位置是否为0x21 如果不是则跳转到弹出错误的窗口。
如果是则执行代码2.代码2是将解密后的数据作为代码进行调用。程序根据代码的调用结果来判断是否注册成功的。这就引来一个问题:如果代码解密不正确的话,这些代码是不能被CPU成功执行的,将会触发异常。因此解密的关键在于那个KeyBuffer的数据。
仔细整理一下已有的思路:
原始数据地址       = 0x004438F8
解密后数据地址  = 0x00406780
成功解密的一个前提条件是0x00406780 +0xA2处的数据是0x21。而0x004438F8 + 0xA2= 0x22,而解密算法是由原始数据做减法得出的,由DecryptCode函数可知:
DstBuffer[0xA2] = SrcBuffer[0xA2] -KeyBuffer[0]
可以推出KeyBuffer[0] = 1。第一个值我们算出来了。
那么后面的8个值怎么办呢?
综合上面的结果可以知道,驱动程序做的只是做一个减法而已,根据不同电脑的分析结果发现,原始数据是不变的,与机器码无关,而解密后的代码具有可执行的属性,也就是说解密后的代码也是不变的,具有唯一性。此时可以得到一个结论:注册码 - 机器码是一个固定值,并且 注册码第一位 - 机器码第一位 + 1的结果是1.
此时我做了一个大胆的推测,那个KeyBuffer的内容可能是KeyBuffer[9] = {1,2,3,4,5,6,7,8}; 因为上面的解密循环是9次一个循环。所以我写了一段注册机代码:
[C] 纯文本查看 复制代码
#include <stdio.h>
 
void KeyGen(unsigned char *MachineID)
{
         unsigned int i;
         unsigned char Key[10] = {0};
 
         for(i=0;i<9;i++)
         {
                  Key = MachineID + i;
         }
         printf("KeyCode:%s\n",Key);
}
 
void main()
{
         unsigned char MachineID[10] = {0};
         scanf("%s",&MachineID[0]);
         KeyGen(MachineID);
}

经过验证,上面的注册算法是可用的。结果如下图:



这个分析过程最后有点不太完美,不是说完整分析出来的,有猜的成分在里面。希望有人能有更好的解决方法贴出来。是怎么得出那个KeyBuffer = {1,2,3,4,5,6,7,8},这个只是我的一个猜测,最终得到了验证而已。

这个弄完实在太晚了,第一次写,时间匆忙,写的不是很好。并且后面的KEYBuffer是我猜出来的,如果论坛有人有更好的解法,希望贴出来一起交流。有错误之处,还请各位高手指正。



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册[Register]

x

免费评分

参与人数 4热心值 +4 收起 理由
wqnmlgb + 1 昨天看过了,就是无解的,只能猜
Chief + 1 吾爱破解2013CM大赛,有你更精彩!
xjun + 1 我很赞同!
a070458 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

黑夜伴影 发表于 2013-12-14 03:53
不会破解的小菜   只能膜拜!
baby 发表于 2013-12-14 05:20
个人认为没有好办法 我搞到这里也是猜的Key是 {0 1 2 3 4 5 6 7 8 9}
因为只有第一个key[0]能确定下来
如果他密钥复杂 我觉得这东西根本没办法分析了就
另外 这个CM的 shellcode在WIN7下有问题 主要是在PEB遍历DL双向链表有问题

点评

遍历InLoadOrderModuleList模块就OK了。  发表于 2013-12-15 02:29
头像被屏蔽
点击下载 发表于 2013-12-14 06:23
snrjdf 发表于 2013-12-14 06:27
谢谢分享
mycc 发表于 2013-12-14 08:01
没时间玩了,来顶顶人气
brack 发表于 2013-12-14 08:50
你为什么这么牛逼
马斯维尔 发表于 2013-12-14 09:29
Orz 跪拜!前来学习!
 楼主| Sandman 发表于 2013-12-14 11:00
本帖最后由 Sandman 于 2013-12-14 11:06 编辑
baby 发表于 2013-12-14 05:20
个人认为没有好办法 我搞到这里也是猜的Key是 {0 1 2 3 4 5 6 7 8 9}
因为只有第一个key[0]能确定下来
如 ...

我没在Win7下做调试,我是在XP虚拟机下搞的
他那个KeyBuffer = {0,1,2,3,4,5,6,7,8}这个没有见到有哪里能跟出来的,个人认为只能猜了。因为整个题目贯穿着就是一个0-8的9个数字的循环。。。似乎就是告诉你KEY跟0-8有关。。。
要是搞得复杂了,确实没办法了
a070458 发表于 2013-12-14 12:08
{:1_931:}好文章
给你32个赞~
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止回复与主题无关非技术内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-5-4 07:34

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表