| 
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       <==================注册码
 
 
 
 
 
 
 
 
 
   
 | 
 评分
查看全部评分
 |