文章导航PC6首页软件下载单机游戏安卓资源苹果资源

pc软件新闻网络操作系统办公工具编程服务器软件评测

安卓新闻资讯应用教程刷机教程安卓游戏攻略tv资讯深度阅读综合安卓评测

苹果ios资讯苹果手机越狱备份教程美化教程ios软件教程mac教程

单机游戏角色扮演即时战略动作射击棋牌游戏体育竞技模拟经营其它游戏游戏工具

网游cf活动dnf活动lol周免英雄lol礼包

手游最新动态手游评测手游活动新游预告手游问答

您的位置:首页精文荟萃破解文章 → 变脸王算法分析标准(DES)的运算过程

变脸王算法分析标准(DES)的运算过程

时间:2004/10/15 0:57:00来源:本站整理作者:蓝点我要评论(0)

顺便来一篇DES的,庆祝自己平安回到老家:)

 

这东东都作了半年了,一直没写文章,这次是帮朋友分析才写的,朋友说还算可以,所以才有脸往上放:)
这是某软件后半部分的注册码的实现过程,变脸王的作者注册码后半部分只用了DES一种算法!而且是标准DES,无任何变化:)脱壳后运行变脸王(不脱壳无法bpx MessageBoxa),断点设在MessageBoxa上,设置两次鼠标主题就可以断下
了,显示"确定使用...?",继续往下走,到这里:
* Possible StringData Ref from Data Obj ->"holer@21cn.com"
|
:004CCF4A BAC4D44C00 mov edx, 004CD4C4
:004CCF4F 8B45F4 mov eax, dword ptr [ebp-0C]
:004CCF52 E84964FFFF call 004C33A0 //那么这里就是逆推注册码的过程了
:004CCF57 8B55CC mov edx, dword ptr [ebp-34]
:004CCF5A 8B45F8 mov eax, dword ptr [ebp-08]
:004CCF5D E82671F3FF call 00404088 //这里是用来将逆推后的注册码
:004CCF62 7447 je 004CCFAB //与输入的名字作比较
:004CCF64 6A40 push 00000040

 

跟进4C33A0:
一直到4C342E是将输入的码的后半部分转成数字的部分,然后:
:004C3430 8B55F8 mov edx, dword ptr [ebp-08]
:004C3433 8B45F4 mov eax, dword ptr [ebp-0C]
:004C3436 E8E1FCFFFF call 004C311C //这里跟进去研究研究
还有:
:004C3450 E8C708F4FF call 00403D1C //这里也要进去逛逛
:004C3455 C3 ret

 

进入4C311C后会发现他取"holer@21cn.com"前8位"holer@21"用来做密钥,后面要有耐心,如想看出算法就要跟进去好几层
才可以,从这里进去:
:004C319F E848FBFFFF call 004C2CEC
进去走到这里,再进:
:004C2D11 E846FEFFFF call 004C2B5C
然后这里,我们可以发现一些有趣的数据:)
:004C2B81 BA07000000 mov edx, 00000007
:004C2B86 E8B100F4FF call 00402C3C
:004C2B8B 33D2 xor edx, edx //设edx为i;
:004C2B8D B800874F00 mov eax, 004F8700 //这里我们得到这样一组16进制数据
/*PC1="0x38,0x30,0x28,0x20,0x18,0x10,0x08, 0x00,0x39,0x31,0x29,0x21,0x19,0x11,
0x09,0x01,0x3A,0x32,0x2A,0x22,0x1A, 0x12,0x0A,0x02,0x3B,0x33,0x2B,0x23,
0x3E,0x36,0x2E,0x26,0x1E,0x16,0x0E, 0x06,0x3D,0x35,0x2D,0x25,0x1D,0x15,
0x0D,0x05,0x3C,0x34,0x2C,0x24,0x1C, 0x14,0x0C,0x04,0x1B,0x13,0x0B,0x03";
*///将每个数字都加上1后再一看就可以想到是DES密钥的置换子密钥的参数,有点感觉了,那就继续往下看
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004C2BE3(C)
|
:004C2B92 8A18 mov bl, byte ptr [eax] //设eax为指向这个数组的指针*p
:004C2B94 8BCB mov ecx, ebx //temp=*p
:004C2B96 80E107 and cl, 07 //以下的操作实质是bit级的操作,较为微观:)
:004C2B99 81E1FF000000 and ecx, 000000FF
:004C2B9F 51 push ecx //push temp&0x7
:004C2BA0 B907000000 mov ecx, 00000007 //temp&0x7和temp mod 8
:004C2BA5 5E pop esi //效果一样:)
:004C2BA6 2BCE sub ecx, esi //7-temp&0x7

 

* Possible Reference to String Resource ID=00001
:004C2BA8 BE01000000 mov esi, 00000001
:004C2BAD D3E6 shl esi, cl //需要将0x00000001向左移(7-temp&7)位
:004C2BAF 33C9 xor ecx, ecx //
:004C2BB1 8ACB mov cl, bl //temp=*p
:004C2BB3 C1E903 shr ecx, 03 //我们知道向右移位相当于除法,这里是整除以8
:004C2BB6 8B5DFC mov ebx, dword ptr [ebp-04] //这里是"holer@21"
:004C2BB9 0FB60C0B movzx ecx, byte ptr [ebx+ecx] //得到第(*p)bit的值
:004C2BBD 23F1 and esi, ecx //用来判断第(*p)bit 的值是否为0
:004C2BBF 741D je 004C2BDE //如果是0就不用操作了
:004C2BC1 8BCA mov ecx, edx //不为0就将第i位置1
:004C2BC3 83E107 and ecx, 00000007
:004C2BC6 51 push ecx
:004C2BC7 B907000000 mov ecx, 00000007
:004C2BCC 5B pop ebx
:004C2BCD 2BCB sub ecx, ebx
:004C2BCF B301 mov bl, 01
:004C2BD1 D2E3 shl bl, cl
:004C2BD3 8BCA mov ecx, edx
:004C2BD5 C1E903 shr ecx, 03
:004C2BD8 8B75F8 mov esi, dword ptr [ebp-08] //
:004C2BDB 081C0E or byte ptr [esi+ecx], bl //第i位置一!

 

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004C2BBF(C)
|
:004C2BDE 42 inc edx //i++;hoho
:004C2BDF 40 inc eax
:004C2BE0 83FA38 cmp edx, 00000038 //计数器为56就停止工作
:004C2BE3 75AD jne 004C2B92
/*作者是这样来查表的,假设字符串"12345678",2进制表示"0011 0001......",相当于2进制数组a[8][8],要判断第i位是否为0,那就
先取第i/8组,a[i/8][?],然后再来取这个'?'的值,?就是i mod 8了,也可以用i & 0x7实现,判断的时候,先取得a[i/8]这8bit数据,然后将
0x1左移i&0x7bit,就可以通过和a[i/8]的这8bit数据的第i&0x7位相与来判断是否为0,可能有的人一看就明白,不过我一开始弄的挺迷糊
,sigh....所以说明一下
*/
上面这一部分看懂那么下面那些置换也能轻松pass了,出来之后来到这里:
:004C2D16 8A06 mov al, byte ptr [esi]
;
..... //这一部分是将置换后得到的56bit密钥分成2部分,一部分28bit
;
:004C2D70 BF10000000 mov edi, 00000010
:004C2D75 BB68874F00 mov ebx, 004F8768 //这里d一下看看,
//turnit[]="0x1,0x1,0x2,0x2,0x2,0x2,0x2,0x2,0x1,0x2,0x2,0x2,0x2,0x2,0x2,0x1"
//正好是DES的子密钥产生过程需要的每轮旋转数
:004C2D7A 8B75FC mov esi, dword ptr [ebp-04]

 

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004C2E06(C)
|
:004C2D7D 8D45F1 lea eax, dword ptr [ebp-0F] //把前28bit转一转:)
:004C2D80 8A0B mov cl, byte ptr [ebx] //转turnit[ebx]下,一下一位

 

* Possible Reference to String Resource ID=00003: "
|
:004C2D82 BA03000000 mov edx, 00000003
:004C2D87 E800FFFFFF call 004C2C8C //这个函数负责转圈的
:004C2D8C 8D45ED lea eax, dword ptr [ebp-13] //后28也进去转转
:004C2D8F 8A0B mov cl, byte ptr [ebx] //同样的圈数

 

* Possible Reference to String Resource ID=00003: "
|
:004C2D91 BA03000000 mov edx, 00000003
:004C2D96 E8F1FEFFFF call 004C2C8C //还是这破函数:(
:004C2D9B 8A55F1 mov dl, byte ptr [ebp-0F]
:004C2D9E C1E204 shl edx, 04
圈圈函数在这儿:
:004C2C97 8A08 mov cl, byte ptr [eax]
:004C2C99 03C9 add ecx, ecx //用加法实现左移一位的效果
:004C2C9B 33DB xor ebx, ebx
:004C2C9D 8A5801 mov bl, byte ptr [eax+01] //取下一个字节
:004C2CA0 C1EB07 shr ebx, 07 //取最高位
:004C2CA3 0ACB or cl, bl //下一字节最高位放入上一字节最低位
:004C2CA5 8808 mov byte ptr [eax], cl //存储一下
;
... //这是后3个字节的处理,相同所以省略了
;
:004C2CE0 884803 mov byte ptr [eax+03], cl
:004C2CE3 80200F and byte ptr [eax], 0F //最后将前4位清0
:004C2CE6 4A dec edx //这个edx就是旋转的轮数,是几就转几下
:004C2CE7 75AE jne 004C2C97 //感觉这个函数不是很高效
//用#define ROL(a,n) (((a)<<(n))|((a)>>(28-(n))))岂不是更好些???
继续,转完出去之后:
:004C2DF7 BA06000000 mov edx, 00000006
:004C2DFC E8F3FDFFFF call 004C2BF4 //这里是从56取48的过程
:004C2E01 83C606 add esi, 00000006
:004C2E04 43 inc ebx
:004C2E05 4F dec edi //要得到16个子密钥...
:004C2E06 0F8571FFFFFF jne 004C2D7D
:004C2E0C 8B7DD8 mov edi, dword ptr [ebp-28]
:004C2E0F 8B75DC mov esi, dword ptr [ebp-24]
进去那个call里面,会有:
:004C2C23 33D2 xor edx, edx
:004C2C25 B838874F00 mov eax, 004F8738 //这也是个重要的数组
/*"0D 10 0A 17 00 04 02 1B-0E 05 14 09 16 12 0B 03
19 07 0F 06 1A 13 0C 01-28 33 1E 24 2E 36 1D 27
32 2C 20 2F 2B 30 26 37-21 34 2D 29 31 23 1C 1F "*/用来从56选48的...
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004C2C7B(C)
|
:004C2C2A 8A18 mov bl, byte ptr [eax]
:004C2C2C 8BCB mov ecx, ebx
:004C2C2E 80E107 and cl, 07
;
... //略掉,选数过程和初始置换相同
;
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004C2C57(C)
|
:004C2C76 42 inc edx
:004C2C77 40 inc eax
:004C2C78 83FA30 cmp edx, 00000030 //是否全部选完
:004C2C7B 75AD jne 004C2C2A
出去之后跳过16次循环后到上一层:
会发现软件判断注册码是否为16的倍数,不是会导致出错...
然后从这里进去:
:004C31FA E845FDFFFF call 004C2F44
然后到这里进去:
:004C2F82 E881F9FFFF call 004C2908
这里面就是将明文也就是输入的注册码后半部分,进行初始置换,过程也都是类似的,省略掉,自己看就好啦
:004C2F87 84DB test bl, bl //bl的值不同,下面的流程也不同,我猜是加解密的两个过程:)
:004C2F89 0F85B5000000 jne 004C3044//bl=1解密,bl=0加密,由于作者设bl为定值1,所以必跳
:004C3044 80FB01 cmp bl, 01
:004C3047 0F85B2000000 jne 004C30FF
:004C304D C745F8F0FFFFFF mov [ebp-08], FFFFFFF0 //猜测的依据在这个数据上,这里-16,那里是+16:)
:004C3054 BBCA2A5000 mov ebx, 00502ACA
;
...
;
:004C3089 8BCB mov ecx, ebx
:004C308B 8B450C mov eax, dword ptr [ebp+0C]
:004C308E 8B5508 mov edx, dword ptr [ebp+08]
:004C3091 E886FDFFFF call 004C2E1C //从这里进去
里面是:

 

:004C2E4C 6A05 push 00000005
:004C2E4E 8D4DF6 lea ecx, dword ptr [ebp-0A]
:004C2E51 E8BAFBFFFF call 004C2A10 //这里面是DES加解密的迭代过程
:004C2E56 BB06000000 mov ebx, 00000006 //f函数中32变48的扩展过程,同上这里略掉不分析
:004C2E5B 8B45FC mov eax, dword ptr [ebp-04] //上面ebx=6!!是因为48bit,每次异或一个字节!
:004C2E5E 8D55F6 lea edx, dword ptr [ebp-0A]

 

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004C2E68(C)
|
:004C2E61 8A08 mov cl, byte ptr [eax]
:004C2E63 300A xor byte ptr [edx], cl //膨胀后与子密钥相异或
:004C2E65 42 inc edx
:004C2E66 40 inc eax
:004C2E67 4B dec ebx
:004C2E68 75F7 jne 004C2E61
:004C2E6A 8A45F6 mov al, byte ptr [ebp-0A]
;
... //以下是将异或后得到的数修改,因为得到的数是连贯的48bit,所以要将他们分开成为6bit一字节
;
:004C2EE6 8BC3 mov eax, ebx
:004C2EE8 8A16 mov dl, byte ptr [esi]
:004C2EEA E831FCFFFF call 004C2B20 //这里面是将上面得到那8个字节调整用来查表,(每6个用来查一个表)
:004C2EEF 8806 mov byte ptr [esi], al
:004C2EF1 43 inc ebx
:004C2EF2 46 inc esi
:004C2EF3 83FB08 cmp ebx, 00000008 //查8次...
:004C2EF6 75EE jne 004C2EE6

 

然后再出来,好累啊.......坚持就是胜利,这里快结束了
:004C3096 B804000000 mov eax, 00000004
:004C309B 8D55F4 lea edx, dword ptr [ebp-0C]
:004C309E 8D75F0 lea esi, dword ptr [ebp-10]
:004C30A1 8B4D0C mov ecx, dword ptr [ebp+0C]
:004C30A4 83C104 add ecx, 00000004
:004C30A7 894DE8 mov dword ptr [ebp-18], ecx

 

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004C30B9(C)
|
:004C30AA 8A0A mov cl, byte ptr [edx] //经过f函数作用后,左半部分
:004C30AC 320E xor cl, byte ptr [esi] //和右半部分异或得到下一轮的右半部分
:004C30AE 8B7DE8 mov edi, dword ptr [ebp-18]
:004C30B1 880F mov byte ptr [edi], cl
:004C30B3 FF45E8 inc [ebp-18]
:004C30B6 46 inc esi
:004C30B7 42 inc edx
:004C30B8 48 dec eax
:004C30B9 75EF jne 004C30AA //每字节异或...
:004C30BB 83EB06 sub ebx, 00000006
:004C30BE FF45F8 inc [ebp-08] //这是调整子密钥,每轮用的子密钥不同
:004C30C1 7596 jne 004C3059
下面还有一个函数是用来将得到的最后结果做初始置换的逆置换...
:004C3105 E882F8FFFF call 004C298C//不看了,全都一样的取数方式:(

 

就这样,这就是一个标准DES的运算过程,不知道能不能看懂,我讲的可真是够累,好长好长............睡觉去啦

相关阅读 Windows错误代码大全 Windows错误代码查询激活windows有什么用Mac QQ和Windows QQ聊天记录怎么合并 Mac QQ和Windows QQ聊天记录Windows 10自动更新怎么关闭 如何关闭Windows 10自动更新windows 10 rs4快速预览版17017下载错误问题Win10秋季创意者更新16291更新了什么 win10 16291更新内容windows10秋季创意者更新时间 windows10秋季创意者更新内容kb3150513补丁更新了什么 Windows 10补丁kb3150513是什么

文章评论
发表评论

热门文章 去除winrar注册框方法

最新文章 比特币病毒怎么破解 比去除winrar注册框方法 华为无线路由器HG522-C破解教程(附超级密码JEB格式文件京东电子书下载和阅读限制破解教UltraISO注册码全集(最新)通过Access破解MSSQL获得数据

人气排行 华为无线路由器HG522-C破解教程(附超级密码JEB格式文件京东电子书下载和阅读限制破解教UltraISO注册码全集(最新)qq相册密码破解方法去除winrar注册框方法(适应任何版本)怎么用手机破解收费游戏华为无线猫HG522破解如何给软件脱壳基础教程