首页 电脑 电脑学堂 查看内容

Screen Demo Maker 3.0 注册算法分析

2004-9-29 20:05 783 0

摘要: 使用工具:  Fi、AspackDie、W32dasm、Filemon、WinHex、OllyDbg 破解过程:   在序列号框中随意输入,点 注册 后弹出对话...
关键词: nbsp eax ptr ecx 004060 dword 注册码 edx mov 004061

使用工具:  Fi、AspackDie、W32dasm、Filemon、WinHex、OllyDbg 破解过程:   在序列号框中随意输入,点 注册 后弹出对话框“无效的注册编码!”。用 Fi 侦测,发现其用 ASPack 加壳,用 AspackDie 脱掉,在用 W32dasm 反汇编,在串式参考中找到“无效的注册编码!”,来到如下代码。* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:|:00406B2F(C), :00406B42(C)|:00406B62 6A00                    push 00000000:00406B64 6A00                    push 00000000* Possible StringData Ref from Data Obj ->"无效的注册编码!"                                 |:00406B66 68A8F34100              push 0041F3A8:00406B6B 8BCE                    mov ecx, esi它由两个地方跳转来,分别查看。:00406B17 E806D30000              Call 00413E22:00406B1C 8B7E64                  mov edi, dword ptr [esi+64]:00406B1F 8D5E64                  lea ebx, dword ptr [esi+64]:00406B22 83C9FF                  or ecx, FFFFFFFF:00406B25 33C0                    xor eax, eax:00406B27 F2                      repnz:00406B28 AE                      scasb:00406B29 F7D1                    not ecx:00406B2B 49                      dec ecx:00406B2C 83F906                  cmp ecx, 00000006:00406B2F 7531                    jne 00406B62  ---------------> 与 6 比较,不等就跳 "无效的注册编码!":00406B31 8B7E68                  mov edi, dword ptr [esi+68]:00406B34 8D5668                  lea edx, dword ptr [esi+68]:00406B37 83C9FF                  or ecx, FFFFFFFF:00406B3A F2                      repnz:00406B3B AE                      scasb:00406B3C F7D1                    not ecx:00406B3E 49                      dec ecx:00406B3F 83F909                  cmp ecx, 00000009:00406B42 751E                    jne 00406B62  ---------------> 与 9 比较,不等就跳 "无效的注册编码!":00406B44 6A0A                    push 0000000A:00406B46 8BCA                    mov ecx, edx因为注册码由两部分组成,猜想可能是判断两部分各自的长度,再在第一部分随便输入 6 个字符,第二部分输入 9 个字符,点 注册 ,果然不在弹出对话框了!(居然蒙对了 :) )可再看看软件,还是未注册,接着用 Filemon 监视,在点下 注册 后,发现其对C:\WINDOWS\system32\stpk.obj 进行操作,看来是将输入的注册码保存到 stpk.obj 中了,用 WinHex 打开这个文件,里面果然有刚才输入的注册码。接着请出OllyDbg,装载程序,进行动态跟踪,在其字符参考中搜索 stpk.obj ,发现两处,均下断。按 F9 运行程序,在 0040643B 处中断。现对其代码分析如下:00406410  /$ 81EC DC030000  SUB ESP,3DC00406416  |. 55             PUSH EBP00406417  |. 56             PUSH ESI00406418  |. 57             PUSH EDI00406419  |. 8D4424 58      LEA EAX,DWORD PTR SS:[ESP+58]0040641D  |. 8BF9           MOV EDI,ECX0040641F  |. 68 90010000    PUSH 190                                 ; /BufSize = 190 (400.)00406424  |. 50             PUSH EAX                                 ; |Buffer00406425  |. 897C24 18      MOV DWORD PTR SS:[ESP+18],EDI            ; |00406429  |. FF15 60904100  CALL DWORD PTR DS:[; \GetSystemDirectoryA0040642F  |. 8D4C24 58      LEA ECX,DWORD PTR SS:[ESP+58]00406433  |. 8D9424 E801000>LEA EDX,DWORD PTR SS:[ESP+1E8]0040643A  |. 51             PUSH ECX                                 ; /0040643B  |. 68 74F34100    PUSH unpacked.0041F374                   ; |format = "%s\stpk.obj"00406440  |. 52             PUSH EDX                                 ; |s00406441  |. FF15 88964100  CALL DWORD PTR DS:[]    ; \sprintf00406447  |. 8B35 94964100  MOV ESI,DWORD PTR DS:[]   ;  msvcrt.fopen0040644D  |. 8D8424 F401000>LEA EAX,DWORD PTR SS:[ESP+1F4]…………                                                             ;  [ 省略若干行 ]00406506  |. 6A 0A          PUSH 0A                                  ;  [ 0A 入栈,后面计算注册码会用到 ]…………                                                             ;  [ 省略若干行 ]0040651A  |. 50             PUSH EAX0040651B  |. 894F 08        MOV DWORD PTR DS:[EDI+8],ECX0040651E  |. E8 7DFBFFFF    CALL unpacked.004060A0                   ;  [ 计算注册码的关键 Call ]00406523  |. 8B4424 24      MOV EAX,DWORD PTR SS:[ESP+24]00406527  |. 83C4 0C        ADD ESP,0C0040652A  |. 83C0 04        ADD EAX,40040652D  |. 8BCF           MOV ECX,EDI0040652F  |. 6A 32          PUSH 3200406531  |. 50             PUSH EAX00406532  |. C747 04 010000>MOV DWORD PTR DS:[EDI+4],100406539  |. E8 D2020000    CALL unpacked.00406810                   ;  [ 关键 Call ,判断注册码的第一部分是否全为数字 ]0040653E  |. 8B47 04        MOV EAX,DWORD PTR DS:[EDI+4]             ;  [ EAX = DS:[EDI+4] ]                                                                       [ 此处的 EAX 至与 00406539 的 Call 有关 ]00406541  |. 85C0           TEST EAX,EAX00406543  |. 74 54          JE SHORT unpacked.00406599               ;  [ 若 EAX = 00000000 , 则跳至 00406599 ]                                                                       [ 即跳过注册码第二部分的判断,直接以未注册版运行 ]00406545  |. 8B4C24 18      MOV ECX,DWORD PTR SS:[ESP+18]00406549  |. 6A 09          PUSH 9                                   ; /maxlen = 90040654B  |. 83C1 0B        ADD ECX,0B                               ; |0040654E  |. 8D5424 47      LEA EDX,DWORD PTR SS:[ESP+47]            ; |00406552  |. 51             PUSH ECX                                 ; |s2         [ 读入假码的第二部分 ]00406553  |. 52             PUSH EDX                                 ; |s1         [ 读入真码的第二部分 ]00406554  |. FF15 84964100  CALL DWORD PTR DS:[]    ; \strncmp    [ 进行比较 ]…………                                                             ;  [ 以下省略 ]**************计算注册码的关键 Call*******************************************************004060A0  /$ 53             PUSH EBX004060A1  |. 55             PUSH EBP004060A2  |. 8B6C24 10      MOV EBP,DWORD PTR SS:[ESP+10]004060A6  |. 56             PUSH ESI004060A7  |. 8B7424 10      MOV ESI,DWORD PTR SS:[ESP+10]004060AB  |. 57             PUSH EDI004060AC  |. 8BCE           MOV ECX,ESI004060AE  |. 8D5D 07        LEA EBX,DWORD PTR SS:[EBP+7]004060B1  |. C646 06 00     MOV BYTE PTR DS:[ESI+6],0004060B5  |. 8BC5           MOV EAX,EBP004060B7  |. 2BCD           SUB ECX,EBP004060B9  |. BF 06000000    MOV EDI,6004060BE  |> 8A1401         /MOV DL,BYTE PTR DS:[ECX+EAX]            ; /  004060BE~004060C5这一段的功能是:004060C1  |. 8810           |MOV BYTE PTR DS:[EAX],DL                ; |  将注册码的第一部分复制 0012F8A0004060C3  |. 40             |INC EAX                                 ; |  0012F8A0 就是真码出现的地方004060C4  |. 4F             |DEC EDI                                 ; |004060C5  |.^75 F7          \JNZ SHORT unpacked.004060BE             ; \004060C7  |. 8B7C24 1C      MOV EDI,DWORD PTR SS:[ESP+1C]            ;  [ 将 SS:[ESP+1C] 的值给 EDI ]                                                                    ;  [ EDI = 0000000A ,即前面入栈的 0A ]004060CB  |. C645 06 2D     MOV BYTE PTR SS:[EBP+6],2D               ;  [ 0012F8A0 中注册码第一部分的后面加上 - ]--------------- 计算第二部分的前三个字母开始 ------------004060CF  |. 0FBE4E 03      MOVSX ECX,BYTE PTR DS:[ESI+3]            ;  [ 将第一部分的第四个数字的 ASCII 码给 ECX ]004060D3  |. 0FBE06         MOVSX EAX,BYTE PTR DS:[ESI]              ;  [ 将第一部分的第一个数字的 ASCII 码给 EAX ]004060D6  |. 8BD7           MOV EDX,EDI                              ;  [ EDX = EDI = 0000000A ]004060D8  |. 6A 03          PUSH 3 004060DA  |. 03D1           ADD EDX,ECX                              ;  [ EDX = EDX +ECX ]             004060DC  |. B9 19000000    MOV ECX,19                               ;  [ ECX = 19h ]004060E1  |. 03C2           ADD EAX,EDX                              ;  [ EAX = EAX + EDX ]004060E3  |. C64424 1B 00   MOV BYTE PTR SS:[ESP+1B],0 004060E8  |. 99             CDQ                                      ;  [ EAX 符号扩展为 64 位 EDX:EAX ]                                                                       [ 此处 CDQ 的作用实际就是将 EDX 清零 ]                                                                       ( 不知道我的理解对不对,望高手指点。)004060E9  |. F7F9           IDIV ECX                                 ;  [ EAX 除以 ECX 商存入 EAX ,余数存入 EDX ]004060EB  |. 0FBE46 01      MOVSX EAX,BYTE PTR DS:[ESI+1]            ;  [ 将第一部分的第二个数字的 ASCII 码给 EAX ]004060EF  |. 8BCF           MOV ECX,EDI                              ;  [ ECX = EDI ]004060F1  |. 80C2 41        ADD DL,41                                ;  [ DL = DL +41h ]004060F4  |. 885424 18      MOV BYTE PTR SS:[ESP+18],DL              ;  [ 将 DL 值存入 SS:[ESP+18] ]                                                                       [ 这就是注册码第二部分的第一位 ]                                                                       [ 接下来是计算注册码第二部分的第二、三位]                                                                       [ 算法与此相同,不再赘述 ]004060F8  |. 0FBE56 04      MOVSX EDX,BYTE PTR DS:[ESI+4]             004060FC  |. 03CA           ADD ECX,EDX                               004060FE  |. 03C1           ADD EAX,ECX                               00406100  |. B9 19000000    MOV ECX,19                                00406105  |. 99             CDQ                                       00406106  |. F7F9           IDIV ECX                                  00406108  |. 0FBE46 02      MOVSX EAX,BYTE PTR DS:[ESI+2]             0040610C  |. 8BCF           MOV ECX,EDI                               0040610E  |. 80C2 41        ADD DL,41                                 00406111  |. 885424 19      MOV BYTE PTR SS:[ESP+19],DL               00406115  |. 0FBE56 05      MOVSX EDX,BYTE PTR DS:[ESI+5]             00406119  |. 03CA           ADD ECX,EDX                               0040611B  |. 03C1           ADD EAX,ECX                               0040611D  |. B9 19000000    MOV ECX,19                                00406122  |. 99             CDQ                                      00406123  |. F7F9           IDIV ECX                                 00406125  |. 80C2 41        ADD DL,41                                00406128  |. 885424 1A      MOV BYTE PTR SS:[ESP+1A],DL--------------- 计算第二部分的前三个字母结束 -------------0040612C  |. 8D5424 18      LEA EDX,DWORD PTR SS:[ESP+18]             00406130  |. 52             PUSH EDX                                  00406131  |. 53             PUSH EBX                                 00406132  |. 8B1D 8C964100  MOV EBX,DWORD PTR DS:[]   00406138  |. FFD3           CALL EBX                                 ;  [ 将这三个字母接在 0012F8A0 中部分注册码的后面 ]--------------- 计算第二部分的中间三个字母开始 --------------0040613A  |. 0FBE46 03      MOVSX EAX,BYTE PTR DS:[ESI+3]            ;  [ 将第一部分的第四个数字的 ASCII 码给 EAX ]0040613E  |. 0FBE0E         MOVSX ECX,BYTE PTR DS:[ESI]              ;  [ 将第一部分的第一个数字的 ASCII 码给 ECX ]00406141  |. 2BC8           SUB ECX,EAX                              ;  [ ECX = ECX - EAX ]00406143  |. 6A 03          PUSH 300406145  |. 8D4439 20      LEA EAX,DWORD PTR DS:[ECX+EDI+20]        ;  [ EAX = ECX + EDI + 20h ]00406149  |. B9 19000000    MOV ECX,19                               ;  [ ECX = 19h ]0040614E  |. 99             CDQ                                      ;  [ 将 EDX 清零 ]0040614F  |. F7F9           IDIV ECX                                 ;  [ EAX 除以 ECX 商存入 EAX ,余数存入 EDX ]00406151  |. 0FBE46 04      MOVSX EAX,BYTE PTR DS:[ESI+4]            ;  [ 将第一部分的第五个数字的 ASCII 码给 EAX ]00406155  |. 80C2 41        ADD DL,41                                ;  [ DL = DL + 41h ]00406158  |. 885424 24      MOV BYTE PTR SS:[ESP+24],DL              ;  [ 将 DL 值存入 DS:[ESI+24] ]                                                                       [ 这就是注册码第二部分的第四位 ]                                                                       [ 接下来是计算注册码第二部分的第五、六位]                                                                       [ 算法与此相同,不再赘述 ]0040615C  |. 0FBE56 01      MOVSX EDX,BYTE PTR DS:[ESI+1]00406160  |. 2BD0           SUB EDX,EAX00406162  |. 8D443A 20      LEA EAX,DWORD PTR DS:[EDX+EDI+20]00406166  |. 99             CDQ00406167  |. F7F9           IDIV ECX00406169  |. 0FBE46 05      MOVSX EAX,BYTE PTR DS:[ESI+5]0040616D  |. 80C2 41        ADD DL,4100406170  |. 885424 25      MOV BYTE PTR SS:[ESP+25],DL00406174  |. 0FBE56 02      MOVSX EDX,BYTE PTR DS:[ESI+2]00406178  |. 2BD0           SUB EDX,EAX0040617A  |. 8D443A 20      LEA EAX,DWORD PTR DS:[EDX+EDI+20]0040617E  |. 99             CDQ0040617F  |. F7F9           IDIV ECX00406181  |. 8D45 0A        LEA EAX,DWORD PTR SS:[EBP+A]00406184  |. 80C2 41        ADD DL,4100406187  |. 885424 26      MOV BYTE PTR SS:[ESP+26],DL--------------- 计算第二部分的中间三个字母结束 -----------------0040618B  |. 8D5424 24      LEA EDX,DWORD PTR SS:[ESP+24]0040618F  |. 52             PUSH EDX00406190  |. 50             PUSH EAX00406191  |. FFD3           CALL EBX                                 ;  [ 将这三个字母接在 0012F8A0 中部分注册码的后面 ]--------------- 计算第二部分的后三个字母开始 -------------------00406193  |. 0FBE46 03      MOVSX EAX,BYTE PTR DS:[ESI+3]            ;  [ 将第一部分的第四个数字的 ASCII 码给 EAX ]00406197  |. 0FBE0E         MOVSX ECX,BYTE PTR DS:[ESI]              ;  [ 将第一部分的第一个数字的 ASCII 码给 ECX ]0040619A  |. 03C7           ADD EAX,EDI                              ;  [ EAX = EAX + EDI ]0040619C  |. 33C1           XOR EAX,ECX                              ;  [ EAX = EAX XOR ECX ]0040619E  |. B9 19000000    MOV ECX,19                               ;  [ ECX = 19h ]004061A3  |. 99             CDQ                                      ;  [ 将 EDX 清零 ]004061A4  |. F7F9           IDIV ECX                                 ;  [ EAX 除以 ECX 商存入 EAX ,余数存入 EDX ]004061A6  |. 0FBE46 04      MOVSX EAX,BYTE PTR DS:[ESI+4]            ;  [ 将第一部分的第五个数字的 ASCII 码给 EAX ]004061AA  |. 80C2 41        ADD DL,41                                ;  [ DL = DL + 41h ]004061AD  |. 03C7           ADD EAX,EDI                              ;  [ EAX = EAX + EDI ]004061AF  |. 885424 2C      MOV BYTE PTR SS:[ESP+2C],DL              ;  [ DL 存入 SS:[ESP+2C] ]                                                                       [ 这就是注册码第二部分的第七位 ]                                                                       [ 接下来是计算注册码第二部分的第八、九位]                                                                       [ 算法与此相同,不再赘述 ]004061B3  |. 0FBE56 01      MOVSX EDX,BYTE PTR DS:[ESI+1]004061B7  |. 33C2           XOR EAX,EDX004061B9  |. 6A 03          PUSH 3004061BB  |. 99             CDQ004061BC  |. F7F9           IDIV ECX004061BE  |. 0FBE46 05      MOVSX EAX,BYTE PTR DS:[ESI+5]004061C2  |. 03C7           ADD EAX,EDI004061C4  |. 80C2 41        ADD DL,41004061C7  |. 885424 31      MOV BYTE PTR SS:[ESP+31],DL004061CB  |. 0FBE56 02      MOVSX EDX,BYTE PTR DS:[ESI+2]004061CF  |. 33C2           XOR EAX,EDX004061D1  |. 99             CDQ004061D2  |. F7F9           IDIV ECX004061D4  |. 8D45 0D        LEA EAX,DWORD PTR SS:[EBP+D]004061D7  |. 80C2 41        ADD DL,41004061DA  |. 885424 32      MOV BYTE PTR SS:[ESP+32],DL--------------- 计算第二部分的后三个字母结束 -------------------004061DE  |. 8D5424 30      LEA EDX,DWORD PTR SS:[ESP+30]004061E2  |. 52             PUSH EDX004061E3  |. 50             PUSH EAX004061E4  |. FFD3           CALL EBX                               ;  [ 将这三个字母接在 0012F8A0 中部分注册码的后面 ]                                                                     [ 至此,从 0012F8A0 开始为完整的正确注册码 ]004061E6  |. 83C4 24        ADD ESP,24004061E9  |. C645 10 00     MOV BYTE PTR SS:[EBP+10],0004061ED  |. B8 01000000    MOV EAX,1004061F2  |. 5F             POP EDI004061F3  |. 5E             POP ESI004061F4  |. 5D             POP EBP004061F5  |. 5B             POP EBX004061F6  \. C3             RETN**********判断注册码的第一部分是否全为数字关键 Call *******************************00406810  /$ 8B51 04        MOV EDX,DWORD PTR DS:[ECX+4]00406813  |. 85D2           TEST EDX,EDX00406815  |. 74 30          JE SHORT unpacked.0040684700406817  |. 8B4424 08      MOV EAX,DWORD PTR SS:[ESP+8]0040681B  |> 85C0           /TEST EAX,EAX0040681D  |. 7E 08          |JLE SHORT unpacked.004068270040681F  |. 48             |DEC EAX00406820  |. 85D2           |TEST EDX,EDX00406822  |.^75 F7          \JNZ SHORT unpacked.0040681B00406824  |. C2 0800        RETN 800406827  |> 56             PUSH ESI00406828  |. 8B7424 08      MOV ESI,DWORD PTR SS:[ESP+8]0040682C  |. 33D2           XOR EDX,EDX0040682E  |> 8A0432         /MOV AL,BYTE PTR DS:[EDX+ESI]00406831  |. 3C 30          |CMP AL,3000406833  |. 7C 04          |JL SHORT unpacked.00406839              ;  [ 比 30 小就令 DS:[ECX+4]=0 ]00406835  |. 3C 39          |CMP AL,3900406837  |. 7E 07          |JLE SHORT unpacked.00406840             ;  [ 比 39 大就令 DS:[ECX+4]=0 ]00406839  |> C741 04 000000>|MOV DWORD PTR DS:[ECX+4],000406840  |> 42             |INC EDX00406841  |. 83FA 06        |CMP EDX,600406844  |.^7C E8          \JL SHORT unpacked.0040682E00406846  |. 5E             POP ESI00406847  \> C2 0800        RETN 8***********算法总结***************************************************************注册码由两段组成:第一段必须为数字,有六位;第二段有九位,由第一部分算得。第二部分九位的算法:( !注意:以下均指 ASCII码 )前三个字母:   1) ( 第一段第一个 + 第一段第四个 + 0Ah ) 除以 19h 的余数 + 41h 的和即为第二段第1个字母              2) ( 第一段第二个 + 第一段第五个 + 0Ah ) 除以 19h 的余数 + 41h 的和即为第二段第2个字母              3) ( 第一段第三个 + 第一段第六个 + 0Ah ) 除以 19h 的余数 + 41h 的和即为第二段第3个字母  中间三个字母: 4) ( 第一段第一个 - 第一段第四个 + 0Ah + 20h ) 除以 19h 的余数 + 41h 即为第二段第4个字母              5) ( 第一段第二个 - 第一段第五个 + 0Ah + 20h ) 除以 19h 的余数 + 41h 即为第二段第5个字母              6) ( 第一段第三个 - 第一段第六个 + 0Ah + 20h ) 除以 19h 的余数 + 41h 即为第二段第6个字母后三个字母:   7) ( 第一段第四个 + 0Ah 的和与第一段第一个异或 ) 除以 19h 的余数 + 41h 即为第二段第7个字母              8) ( 第一段第五个 + 0Ah 的和与第一段第二个异或 ) 除以 19h 的余数 + 41h 即为第二段第8个字母              9) ( 第一段第六个 + 0Ah 的和与第一段第三个异或 ) 除以 19h 的余数 + 41h 即为第二段第9个字母
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

最新评论

返回顶部