TA的每日心情 | 开心 2015-8-23 23:49 |
---|
签到天数: 27 天 [LV.4]偶尔看看III
|
本帖最后由 GGLHY 于 2012-4-1 22:38 编辑
某CHM文件生成器的注册解码分析 by GGLHY
想起论坛的echo兄给出了这个软件的内存注册机帖子(https://www.chinapyg.com/viewthread.php?tid=59513&extra=page%3D1)的时候,我当时大致看了下这个软件的算法但没深究(凌晨3点多,呵呵头昏脑胀的也懒得继续),正好下午难得有点空闲,OD了下,于是有了这篇破文。
【初涉算法,如有错误还望大牛指正!谢谢!】
直奔主题,来到:
- 005E5441 E8 52F9F6FF call 00554D98
- 005E5446 8B45 9C mov eax, dword ptr [ebp-64]
- 005E5449 8B55 FC mov edx, dword ptr [ebp-4]
- 005E544C E8 EBC8FDFF call 005C1D3C ; 看看这里和下面的标志位比较,经典的比较句式!Let`s F7
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////
- 005C1D3C 55 push ebp
- 005C1D3D 8BEC mov ebp, esp
- 005C1D3F B9 04000000 mov ecx, 4
- 005C1D44 6A 00 push 0
- 005C1D46 6A 00 push 0
- 005C1D48 49 dec ecx
- 005C1D49 ^ 75 F9 jnz short 005C1D44
- ( ...省略部分代码...)
- 005C1D68 E8 53FCFFFF call 005C19C0
- 005C1D6D 8D55 EC lea edx, dword ptr [ebp-14]
- 005C1D70 8B45 F0 mov eax, dword ptr [ebp-10] ; 机器码到EAX
- 005C1D73 E8 C0FCFFFF call 005C1A38 ; 呵呵,这里有宝贝哦!F7(算法核心部分)
- /////////////////////////////////////////////////////////////////////////////////////////////
- 005C1A38 55 push ebp
- 005C1A39 8BEC mov ebp, esp
- 005C1A3B 83C4 88 add esp, -78
- 005C1A3E 53 push ebx
- 005C1A3F 56 push esi
- 005C1A40 57 push edi
- 005C1A41 33C9 xor ecx, ecx
- 005C1A43 894D 88 mov dword ptr [ebp-78], ecx
- 005C1A46 894D F4 mov dword ptr [ebp-C], ecx
- 005C1A49 8955 F8 mov dword ptr [ebp-8], edx
- 005C1A4C 8945 FC mov dword ptr [ebp-4], eax
- 005C1A4F 33C0 xor eax, eax
- 005C1A51 55 push ebp
- 005C1A52 68 071B5C00 push 005C1B07
- 005C1A57 64:FF30 push dword ptr fs:[eax]
- 005C1A5A 64:8920 mov dword ptr fs:[eax], esp
- 005C1A5D 8B45 F8 mov eax, dword ptr [ebp-8]
- 005C1A60 E8 AB30F9FF call 00554B10
- 005C1A65 8B45 FC mov eax, dword ptr [ebp-4] ; 机器码GHJ63G53(本例)到EAX
- 005C1A68 E8 6333F9FF call 00554DD0
- 005C1A6D 8945 F0 mov dword ptr [ebp-10], eax ; 机器码长度,本例为8
- 005C1A70 837D F0 00 cmp dword ptr [ebp-10], 0 ; 机器码长度是否为0,是则跳则挂!
- 005C1A74 74 73 je short 005C1AE9
- 005C1A76 B9 01000000 mov ecx, 1 ; ECX=1,
- 005C1A7B 33DB xor ebx, ebx ; ebx=0
- 005C1A7D 8D75 8C lea esi, dword ptr [ebp-74]
- 005C1A80 3B4D F0 cmp ecx, dword ptr [ebp-10] ; 机器码位置指针S:机器码长度指针i
- 005C1A83 7E 05 jle short 005C1A8A ; 机器码位置指针S超过机器码长度指针i后则初始化为1
- 005C1A85 B9 01000000 mov ecx, 1
- 005C1A8A 8B45 FC mov eax, dword ptr [ebp-4] ; 机器码GHJ63G53
- 005C1A8D 0FB67C08 FF movzx edi, byte ptr [eax+ecx-1] ; 依次取机器码ASC到EDI
- 005C1A92 8BC7 mov eax, edi ; 所取机器码ASC到eax
- 005C1A94 99 cdq
- 005C1A95 F7F9 idiv ecx ; 依次取机器码ASC / 机器码位置指针S
- 005C1A97 8BC2 mov eax, edx ; 余数到EAX
- 005C1A99 8BD3 mov edx, ebx ; ebx初始为0,每循环1次+1,看做循环指针k
- 005C1A9B 0FAFD7 imul edx, edi ; 循环指针k * 所取机器码的ASC,积到EDX
- 005C1A9E 03C2 add eax, edx ; 积 + 余数
- 005C1AA0 2BC3 sub eax, ebx ; 和 - 循环指针k
- 005C1AA2 03C1 add eax, ecx ; 差 + 机器码位置指针S
- 005C1AA4 BF 18000000 mov edi, 18 ; EDI=18h=24
- 005C1AA9 99 cdq
- 005C1AAA F7FF idiv edi ; 和/18h=24
- 005C1AAC 8916 mov dword ptr [esi], edx ; 保存余数到[ESI]
- 005C1AAE 41 inc ecx ; ecx + 1
- 005C1AAF 43 inc ebx ; ebx + 1
- 005C1AB0 83C6 04 add esi, 4
- 005C1AB3 83FB 19 cmp ebx, 19 ; 与25比较(即机器码循环取到25位为止)
- 005C1AB6 ^ 75 C8 jnz short 005C1A80
- 005C1AB8 BB 19000000 mov ebx, 19 ; 循环结束后得到的结果,设为Y。本例为:010107150E010B0109110F0D06091311110917051611030901
- 005C1ABD 8D75 8C lea esi, dword ptr [ebp-74]
- 005C1AC0 8D45 88 lea eax, dword ptr [ebp-78]
- 005C1AC3 8A16 mov dl, byte ptr [esi] ; 依次将上面每次循环得到的结果放 到DL
- 005C1AC5 80C2 41 add dl, 41 ; +41(65)
- 005C1AC8 E8 2B32F9FF call 00554CF8
- 005C1ACD 8B55 88 mov edx, dword ptr [ebp-78] ; 相加的结果到EDX,输出对应ASC的字符
- 005C1AD0 8D45 F4 lea eax, dword ptr [ebp-C]
- 005C1AD3 E8 0033F9FF call 00554DD8
- 005C1AD8 83C6 04 add esi, 4
- 005C1ADB 4B dec ebx
- 005C1ADC ^ 75 E2 jnz short 005C1AC0
- 005C1ADE 8B45 F8 mov eax, dword ptr [ebp-8]
- 005C1AE1 8B55 F4 mov edx, dword ptr [ebp-C] ; 真码到EDX
- 005C1AE4 E8 7B30F9FF call 00554B64
- 005C1AE9 33C0 xor eax, eax
- 005C1AEB 5A pop edx
- 005C1AEC 59 pop ecx
- 005C1AED 59 pop ecx
- 005C1AEE 64:8910 mov dword ptr fs:[eax], edx
- 005C1AF1 68 0E1B5C00 push 005C1B0E
- 005C1AF6 8D45 88 lea eax, dword ptr [ebp-78]
- 005C1AF9 E8 1230F9FF call 00554B10
- 005C1AFE 8D45 F4 lea eax, dword ptr [ebp-C]
- 005C1B01 E8 0A30F9FF call 00554B10
- 005C1B06 C3 retn
- /////////////////////////////////////////////////////////////////////////////////////////
- 005C1D78 8B45 EC mov eax, dword ptr [ebp-14] ; 真码
- 005C1D7B 8BD3 mov edx, ebx ; 假码
- 005C1D7D E8 9A31F9FF call 00554F1C
- 005C1D82 0F85 29010000 jnz 005C1EB1 ; 跳还是不跳?这算不算个问题呢?呵呵
- 005C1D88 B2 01 mov dl, 1
- 005C1D8A A1 1C505700 mov eax, dword ptr [57501C]
- ( ...省略部分代码...)
- 005C1DE0 50 push eax
- 005C1DE1 8D55 E4 lea edx, dword ptr [ebp-1C]
- 005C1DE4 B8 E81E5C00 mov eax, 005C1EE8 ; ASCII "user"
- 005C1DE9 E8 26F4FFFF call 005C1214
- 005C1DEE 8B55 E4 mov edx, dword ptr [ebp-1C]
- 005C1DF1 8B45 F8 mov eax, dword ptr [ebp-8]
- 005C1DF4 59 pop ecx
- 005C1DF5 E8 5E39FBFF call 00575758
- ( ...省略部分代码...)
- 005C1EBE 8D45 DC lea eax, dword ptr [ebp-24]
- 005C1EC1 BA 07000000 mov edx, 7
- 005C1EC6 E8 692CF9FF call 00554B34
- 005C1ECB C3 retn
- /////////////////////////////////////////////////////////////////////////////////////////////////////////////
- 005E5451 84C0 test al, al ;标志位
- 005E5453 74 34 je short 005E5489 ;传说中的关键跳!!!
- 005E5455 68 40000400 push 40040
- 005E545A 68 E0545E00 push 005E54E0 ; ASCII "鄀鏮C"
- ( ...省略部分代码...)
- 005E547C 50 push eax
- 005E547D 68 FFFF0000 push 0FFFF
- 005E5482 E8 D927F7FF call <jmp.&user32.SendNotifyMess>
- 005E5487 EB 16 jmp short 005E549F
- 005E5489 68 10000400 push 40010
- 005E548E 68 E0545E00 push 005E54E0 ; ASCII "鄀鏮C"
- 005E5493 68 6C555E00 push 005E556C
- 005E5498 6A 00 push 0
- 005E549A E8 1127F7FF call <jmp.&user32.MessageBoxW> ; 出错框!出错啦~~~
- 005E549F 33C0 xor eax, eax
- 005E54A1 5A pop edx
复制代码
*************************************************************************************************************************
呵呵,算法总结:
0.与用户名无关。
1.机器码决定机器码长度指针i。
2.循环指针k表示初始值为0,每循环1次+1直到24为止。
3.依次取机器码的ASC / S,(比如取机器码:GHJ63G53的第一个“G”时,其ASC码为47,其位置指针S为1,(这里可以理解为G在第1位))
所得的余数 + (k * 所取机器码的ASC)- k + S,得到的和设为Q
Q / 18h 取其余数
4.Q / 18h的余数 + 41 得到的和作为ASC,输出对应的字符,相连得到25位字符,每5位1组,共5组即为注册码。
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
说明:
机器码长度指针i:(比如本例中机器码:GHJ63G53,其长度指针为8)
机器码位置指针S:这与机器码长度指针i有点关系。其实就是所取机器码字符在机器码中的位置值。比如:机器码:GHJ63G53中,“6”的位置指针为4。且位置指针S不大于i
循环指针k:0-24,每循环1次,其值+1
循环指针所表示的值即当前循环指针数值。(比如循环到第2次时,其值为2)
*************************************************************************************************************************
本例中机器码:GHJ63G53,长度指针为8,但循环指针最大可到24(0~24)共25次,当GHJ63G53依次取完并运算后(即长度指针为8后),又重新取机器码GHJ63G53开始运算,(重新开始时,机器码长度指针再次从1开始,到8结束),这样一直运行到循环指针=24时为止。
呵呵,说半天还不如举个例子来得直接明了:
(为方便理解特用彩色标识:蓝色的是当前取机器码字符的的ASC,暗红色是位置指针,红色是余数,黑色的是循环指针)
比如说,循环指针k=7时,机器码位置指针=8。这时所取的机器码为最后一位“3”,其ASC为33。
33 / 8 得到其余数为3 ///取机器码GHJ63G53中的最后1个“3”的ASC码33 除以 这个“3”在机器码中的位置值8(S)
3(余数)+ ((7 * 33 ) - 7 + 8) = Q = 169 ///169(16进制) = 361(10进制)
169 / 18 = 0E + 1 ///余数为1
1 + 41 = 42 ///看做ASC码
哈哈,我们随便找个ASC表来看看,41对应的字符为"A",那么42对应的就是"B"了
接下来,循环指针k=8时,所取的机器码中的字符的其位置指针=1,(因为机器码已经取完了,这时机器码重新开始计算),所取的应该是重新开始的机器码GHJ63G53中的第一个“G”...
直至循环指针k=24为止。
换句话说,在外循环指针从0-24的循环过程中,机器码复制并相连直到25位,每机器码长度位(我这里是8位)作为内循环指针(1~8),共循环25/8 = 4 + 1 次;且位置指针从1~8后再循环,一直循环到K=24为止。
附本机注册信息:
机器码:GHJ63G53
这样够直观了吧,呵呵
G H J 6 3 G 5 3 G H J 6 3 G 5 3 G H J 6 3 G 5 3 G <------------------机器码复制并相连直到25位为止
S:1--------------8 1---------------8 1------------8 1 - <---|位置指针
. . . . . . . . . . . . . . . . . . . . . . . . . <---|
k 0--------------------------------------------------24 <---|循环指针
. . . . . . . . . . . . . . . . . . . . . . . . . <-------------算法过程
010107150E 010B010911 0F0D060913 1111091705 1611030901 <------------------Y
+ 41("A")
------------------------------------------------------------------------------------------------------------------------
B B H V O B L B J R P N G J T R R J X F W R D J B <==================注册码
|
评分
-
查看全部评分
|