您的位置:首页精文荟萃破解文章 → 变脸王算法分析标准(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破解如何给软件脱壳基础教程