• 标 题:龙文输入通算法分析 (27千字)
  • 作 者:thl0057
  • 时 间:2003-10-25 05:15:46
  • 链 接:http://bbs.pediy.com

软件名称:龙文输入通  注册版 Ver3.36  Build 2003年9月30日
类型:共享软件
下载地址:www.inputsoft.com
简介:龙文通用输入法平台是一个综合性的、能够满足用户多种输入要求的软件,它集中了众多输入法的优点和功能,用户即可以挂接任意的形码方案作为形码输入法,如五笔输入,也可以用作拼音输入法,拼音输入支持字、词、句间的无缝转换,系统会根据用户输入的拼音由一定的算法自动选出最可能的汉字,免去用户逐字逐词进行选择的麻烦,提高了拼音输入的效率。
限制:时间限制,到期后会有功能限制
工具;TRW2000娃娃修改版,OllyDbg 1.09c,W32Dasm,呵呵 还有windows记事本
声明:初学Crack,只是感兴趣,没有其它目的。失误之处敬请诸位大侠赐教!

*********************************************************
由于是输入法,不可能用OllyDbg直接打开跟踪,想attach,居然在OllyDbg的进程窗口里找不到该输入法(高手一定在笑了‘SB啊,要是在进程里看到输入法就怪了’)。于是我就用了TRW2000,可在里面d来d去的就是看不出什么名堂(因为我是菜鸟嘛,俗话说的好“天下菜鸟是一家……”),还是回到了OllyDbg,毕竟OllyDbg是广大菜鸟的最爱嘛。我先随便打开一个记事本,选输入法为龙文输入平台,再在输入法条上打开注册窗口,在OllyDbg的进程窗口里赫然有了“龙文输入平台 系统设置与管理”的字样,不过该进程是WINDOWS的NOTEPAD.EXE。没关系用OllyDbg attach该进程后选择名为lwsrf的可执行模块(该模块指向WINDOWS\SYSTEM或WINNT\SYSTEM32下的lwsrf.ime文件,该文件应该是Dll类型,是该输入法安装后留在系统目录里的,用W32Dasm打开后会得到不少有用的提示),就会看到和TRW2000里一模一样的东西了。

*********************************************************
破解过程:
该软件在保护上做了不少手脚,不光有较大的跳跃和垃圾似的计算,连在注册窗口里给出的一长串机器码都是经过变化的假机器码,难怪作者提示说获取注册码时可以用复制-粘贴的方法发送机器码。害的我走了不少弯路浪费不少时间,不过这样的东西更值得一破!
软件给出的我的机器码:A177-8C79-9A8A-8084-3084-C631-A173-8339-9A8A-8084
试炼码:A123-4B56-7C8D-9087-4567-1234 (根据试验,注册码必须是6部分29位)

用OllyDbg在GetWindowTextA下断
100278B0   FF15 24B30410    CALL DWORD PTR DS:[<&USER32.GetWindowTextA>]     断在这
100278B6   8D7C24 18        LEA EDI,DWORD PTR SS:[ESP+18]
100278BA   83C9 FF          OR ECX,FFFFFFFF
100278BD   33C0             XOR EAX,EAX
100278BF   8D9424 40010000  LEA EDX,DWORD PTR SS:[ESP+140]
100278C6   F2:AE            REPNE SCAS BYTE PTR ES:[EDI]
100278C8   F7D1             NOT ECX
100278CA   2BF9             SUB EDI,ECX
100278CC   6A 00            PUSH 0
100278CE   8BC1             MOV EAX,ECX
100278D0   8BF7             MOV ESI,EDI
100278D2   8BFA             MOV EDI,EDX
100278D4   6A 00            PUSH 0
100278D6   C1E9 02          SHR ECX,2
100278D9   F3:A5            REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
100278DB   8BC8             MOV ECX,EAX
100278DD   6A 01            PUSH 1
100278DF   83E1 03          AND ECX,3
100278E2   F3:A4            REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
100278E4   8D4C24 24        LEA ECX,DWORD PTR SS:[ESP+24]
100278E8   51               PUSH ECX
100278E9   E8 62F1FFFF      CALL LWSRF.10026A50                              很重要的CALL,跟入
100278EE   83C4 10          ADD ESP,10
100278F1   A3 2EB30510      MOV DWORD PTR DS:[1005B32E],EAX                  这EAX=0和下面对应
100278F6   85C0             TEST EAX,EAX
100278F8   75 2E            JNZ SHORT LWSRF.10027928
100278FA   8D5424 18        LEA EDX,DWORD PTR SS:[ESP+18]
100278FE   6A 23            PUSH 23
10027900   52               PUSH EDX
10027901   68 C2040000      PUSH 4C2
10027906   53               PUSH EBX
10027907   FFD5             CALL EBP
10027909   50               PUSH EAX
1002790A   FF15 24B30410    CALL DWORD PTR DS:[<&USER32.GetWindowTextA>]
10027910   6A 01            PUSH 1
10027912   6A 00            PUSH 0
10027914   8D4424 20        LEA EAX,DWORD PTR SS:[ESP+20]
10027918   6A 01            PUSH 1
1002791A   50               PUSH EAX
1002791B   E8 30F1FFFF      CALL LWSRF.10026A50
10027920   83C4 10          ADD ESP,10
10027923   A3 2EB30510      MOV DWORD PTR DS:[1005B32E],EAX                  这EAX=0和下面对应
10027928   8DBC24 40010000  LEA EDI,DWORD PTR SS:[ESP+140]
1002792F   83C9 FF          OR ECX,FFFFFFFF
10027932   33C0             XOR EAX,EAX
10027934   8D5424 18        LEA EDX,DWORD PTR SS:[ESP+18]
10027938   F2:AE            REPNE SCAS BYTE PTR ES:[EDI]
1002793A   F7D1             NOT ECX
1002793C   2BF9             SUB EDI,ECX
1002793E   8B1D 34B30410    MOV EBX,DWORD PTR DS:[<&USER32.LoadStringA>]
10027944   8BC1             MOV EAX,ECX
10027946   8BF7             MOV ESI,EDI
10027948   8BFA             MOV EDI,EDX
1002794A   8B15 F4830510    MOV EDX,DWORD PTR DS:[100583F4]                  LWSRF.10000000
10027950   C1E9 02          SHR ECX,2
10027953   F3:A5            REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
10027955   8BC8             MOV ECX,EAX
10027957   6A 0A            PUSH 0A
10027959   83E1 03          AND ECX,3
1002795C   F3:A4            REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
1002795E   8D4C24 74        LEA ECX,DWORD PTR SS:[ESP+74]
10027962   51               PUSH ECX
10027963   68 06060000      PUSH 606
10027968   52               PUSH EDX
10027969   FFD3             CALL EBX
1002796B   BF 00A00510      MOV EDI,LWSRF.1005A000
10027970   83C9 FF          OR ECX,FFFFFFFF
10027973   33C0             XOR EAX,EAX
10027975   8D9424 40010000  LEA EDX,DWORD PTR SS:[ESP+140]
1002797C   F2:AE            REPNE SCAS BYTE PTR ES:[EDI]
1002797E   F7D1             NOT ECX
10027980   2BF9             SUB EDI,ECX
10027982   68 18270510      PUSH LWSRF.10052718
10027987   8BC1             MOV EAX,ECX
10027989   8BF7             MOV ESI,EDI
1002798B   8BFA             MOV EDI,EDX
1002798D   8D9424 44010000  LEA EDX,DWORD PTR SS:[ESP+144]
10027994   C1E9 02          SHR ECX,2
10027997   F3:A5            REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
10027999   8BC8             MOV ECX,EAX
1002799B   33C0             XOR EAX,EAX
1002799D   83E1 03          AND ECX,3
100279A0   F3:A4            REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
100279A2   8D7C24 74        LEA EDI,DWORD PTR SS:[ESP+74]
100279A6   83C9 FF          OR ECX,FFFFFFFF
100279A9   F2:AE            REPNE SCAS BYTE PTR ES:[EDI]
100279AB   F7D1             NOT ECX
100279AD   2BF9             SUB EDI,ECX
100279AF   8BF7             MOV ESI,EDI
100279B1   8BE9             MOV EBP,ECX
100279B3   8BFA             MOV EDI,EDX
100279B5   83C9 FF          OR ECX,FFFFFFFF
100279B8   F2:AE            REPNE SCAS BYTE PTR ES:[EDI]
100279BA   8BCD             MOV ECX,EBP
100279BC   4F               DEC EDI
100279BD   C1E9 02          SHR ECX,2
100279C0   F3:A5            REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
100279C2   8BCD             MOV ECX,EBP
100279C4   8D8424 44010000  LEA EAX,DWORD PTR SS:[ESP+144]
100279CB   83E1 03          AND ECX,3
100279CE   50               PUSH EAX
100279CF   F3:A4            REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
100279D1   E8 1FC60100      CALL LWSRF.10043FF5
100279D6   8BF0             MOV ESI,EAX
100279D8   83C4 08          ADD ESP,8
100279DB   85F6             TEST ESI,ESI
100279DD   74 14            JE SHORT LWSRF.100279F3
100279DF   8D4C24 18        LEA ECX,DWORD PTR SS:[ESP+18]
100279E3   56               PUSH ESI
100279E4   51               PUSH ECX
100279E5   E8 12CB0100      CALL LWSRF.100444FC
100279EA   56               PUSH ESI
100279EB   E8 75C50100      CALL LWSRF.10043F65
100279F0   83C4 0C          ADD ESP,0C
100279F3   A1 F4830510      MOV EAX,DWORD PTR DS:[100583F4]
100279F8   8D9424 2C010000  LEA EDX,DWORD PTR SS:[ESP+12C]
100279FF   6A 14            PUSH 14
10027A01   52               PUSH EDX
10027A02   68 06060000      PUSH 606
10027A07   50               PUSH EAX
10027A08   FFD3             CALL EBX
10027A0A   8D4C24 10        LEA ECX,DWORD PTR SS:[ESP+10]
10027A0E   51               PUSH ECX
10027A0F   68 02000080      PUSH 80000002
10027A14   E8 27C3FEFF      CALL LWSRF.10013D40
10027A19   83C4 08          ADD ESP,8
10027A1C   85C0             TEST EAX,EAX
10027A1E   74 15            JE SHORT LWSRF.10027A35
10027A20   8D5424 10        LEA EDX,DWORD PTR SS:[ESP+10]
10027A24   52               PUSH EDX
10027A25   68 C8E40410      PUSH LWSRF.1004E4C8                              ASCII "Software\Microsoft\Windows\CurrentVersion"
10027A2A   68 02000080      PUSH 80000002
10027A2F   FF15 08B00410    CALL DWORD PTR DS:[<&ADVAPI32.RegCreateKeyA>]
10027A35   8B4C24 10        MOV ECX,DWORD PTR SS:[ESP+10]
10027A39   8D4424 14        LEA EAX,DWORD PTR SS:[ESP+14]
10027A3D   6A 00            PUSH 0
10027A3F   50               PUSH EAX
10027A40   6A 00            PUSH 0
10027A42   68 3F000F00      PUSH 0F003F
10027A47   6A 00            PUSH 0
10027A49   6A 00            PUSH 0
10027A4B   6A 00            PUSH 0
10027A4D   68 60DA0510      PUSH LWSRF.1005DA60
10027A52   51               PUSH ECX
10027A53   FF15 0CB00410    CALL DWORD PTR DS:[<&ADVAPI32.RegCreateKeyExA>]
10027A59   8D7C24 18        LEA EDI,DWORD PTR SS:[ESP+18]
10027A5D   83C9 FF          OR ECX,FFFFFFFF
10027A60   33C0             XOR EAX,EAX
10027A62   8D5424 18        LEA EDX,DWORD PTR SS:[ESP+18]
10027A66   F2:AE            REPNE SCAS BYTE PTR ES:[EDI]
10027A68   F7D1             NOT ECX
10027A6A   51               PUSH ECX
10027A6B   8B4C24 18        MOV ECX,DWORD PTR SS:[ESP+18]
10027A6F   52               PUSH EDX
10027A70   6A 03            PUSH 3
10027A72   50               PUSH EAX
10027A73   8D8424 3C010000  LEA EAX,DWORD PTR SS:[ESP+13C]
10027A7A   50               PUSH EAX
10027A7B   51               PUSH ECX
10027A7C   FF15 14B00410    CALL DWORD PTR DS:[<&ADVAPI32.RegSetValueExA>]
10027A82   8B35 18B00410    MOV ESI,DWORD PTR DS:[<&ADVAPI32.RegCloseKey>]
10027A88   8B5424 14        MOV EDX,DWORD PTR SS:[ESP+14]
10027A8C   52               PUSH EDX
10027A8D   FFD6             CALL ESI
10027A8F   8B4424 10        MOV EAX,DWORD PTR SS:[ESP+10]
10027A93   50               PUSH EAX
10027A94   FFD6             CALL ESI
10027A96   8B15 F4830510    MOV EDX,DWORD PTR DS:[100583F4]                  LWSRF.10000000
10027A9C   8D8C24 40010000  LEA ECX,DWORD PTR SS:[ESP+140]
10027AA3   68 C8000000      PUSH 0C8
10027AA8   51               PUSH ECX
10027AA9   68 03060000      PUSH 603
10027AAE   52               PUSH EDX
10027AAF   FFD3             CALL EBX
10027AB1   8B0D F4830510    MOV ECX,DWORD PTR DS:[100583F4]                  LWSRF.10000000
10027AB7   8D4424 70        LEA EAX,DWORD PTR SS:[ESP+70]
10027ABB   6A 78            PUSH 78
10027ABD   50               PUSH EAX
10027ABE   68 04060000      PUSH 604
10027AC3   51               PUSH ECX
10027AC4   FFD3             CALL EBX
10027AC6   A1 F4830510      MOV EAX,DWORD PTR DS:[100583F4]
10027ACB   8D9424 E8000000  LEA EDX,DWORD PTR SS:[ESP+E8]
10027AD2   6A 14            PUSH 14
10027AD4   52               PUSH EDX
10027AD5   68 05060000      PUSH 605
10027ADA   50               PUSH EAX
10027ADB   FFD3             CALL EBX
10027ADD   A1 2EB30510      MOV EAX,DWORD PTR DS:[1005B32E]                  就是这让EAX=0
10027AE2   6A 00            PUSH 0
10027AE4   85C0             TEST EAX,EAX                                    以EAX为标志
10027AE6   74 27            JE SHORT LWSRF.10027B0F                         如果是0就弹出错误提示
10027AE8   8D8C24 EC000000  LEA ECX,DWORD PTR SS:[ESP+EC]
10027AEF   8D5424 74        LEA EDX,DWORD PTR SS:[ESP+74]
10027AF3   51               PUSH ECX
10027AF4   52               PUSH EDX
10027AF5   6A 00            PUSH 0
10027AF7   FF15 50B30410    CALL DWORD PTR DS:[<&USER32.MessageBoxA>]        注册成功提示
10027AFD   5F               POP EDI
10027AFE   5E               POP ESI
10027AFF   5D               POP EBP
10027B00   B8 01000000      MOV EAX,1
10027B05   5B               POP EBX
10027B06   81C4 D8020000    ADD ESP,2D8
10027B0C   C2 1000          RETN 10
10027B0F   8D8424 EC000000  LEA EAX,DWORD PTR SS:[ESP+EC]
10027B16   8D8C24 44010000  LEA ECX,DWORD PTR SS:[ESP+144]
10027B1D   50               PUSH EAX
10027B1E   51               PUSH ECX
10027B1F   6A 00            PUSH 0
10027B21   FF15 50B30410    CALL DWORD PTR DS:[<&USER32.MessageBoxA>]        ;注册失败提示
10027B27   5F               POP EDI
10027B28   5E               POP ESI
10027B29   5D               POP EBP
10027B2A   B8 01000000      MOV EAX,1
10027B2F   5B               POP EBX
10027B30   81C4 D8020000    ADD ESP,2D8
10027B36   C2 1000          RETN 10


由100278E9处的CALL LWSRF.10026A50 进入到此:
10026A50   83EC 6C          SUB ESP,6C
10026A53   8B0D F4830510    MOV ECX,DWORD PTR DS:[100583F4]                  LWSRF.10000000
10026A59   8D4424 34        LEA EAX,DWORD PTR SS:[ESP+34]
10026A5D   53               PUSH EBX
10026A5E   55               PUSH EBP
10026A5F   56               PUSH ESI
10026A60   57               PUSH EDI
10026A61   6A 0A            PUSH 0A
10026A63   50               PUSH EAX
10026A64   68 0B060000      PUSH 60B
10026A69   51               PUSH ECX
10026A6A   FF15 34B30410    CALL DWORD PTR DS:[<&USER32.LoadStringA>]
10026A70   8BB424 84000000  MOV ESI,DWORD PTR SS:[ESP+84]
10026A77   33DB             XOR EBX,EBX
10026A79   3BF3             CMP ESI,EBX
10026A7B   74 09            JE SHORT LWSRF.10026A86
10026A7D   8B15 684D0510    MOV EDX,DWORD PTR DS:[10054D68]
10026A83   895A 18          MOV DWORD PTR DS:[EDX+18],EBX
10026A86   53               PUSH EBX
10026A87   68 00040000      PUSH 400
10026A8C   6A 01            PUSH 1
10026A8E   FF15 C4B10410    CALL DWORD PTR DS:[<&KERNEL32.HeapCreate>]
10026A94   6A 64            PUSH 64
10026A96   6A 08            PUSH 8
10026A98   50               PUSH EAX
10026A99   894424 20        MOV DWORD PTR SS:[ESP+20],EAX
10026A9D   FF15 DCB10410    CALL DWORD PTR DS:[<&KERNEL32.HeapAlloc>]
10026AA3   8BE8             MOV EBP,EAX
10026AA5   33C0             XOR EAX,EAX
10026AA7   898424 8C000000  MOV DWORD PTR SS:[ESP+8C],EAX
10026AAE   8B0D 684D0510    MOV ECX,DWORD PTR DS:[10054D68]                第1次注册码检验错误后就会跳到这里,而后进行一些看上去眼花缭乱的计算,但命运终归是死亡
10026AB4   8D0440           LEA EAX,DWORD PTR DS:[EAX+EAX*2]
10026AB7   C1E0 02          SHL EAX,2
10026ABA   894424 24        MOV DWORD PTR SS:[ESP+24],EAX
10026ABE   8D5408 20        LEA EDX,DWORD PTR DS:[EAX+ECX+20]
10026AC2   8BC5             MOV EAX,EBP
10026AC4   8B0A             MOV ECX,DWORD PTR DS:[EDX]                       ECX=73865E8C
10026AC6   8908             MOV DWORD PTR DS:[EAX],ECX                       EAX->[0148F00C]=73865E8C
10026AC8   8B4A 04          MOV ECX,DWORD PTR DS:[EDX+4]                     ECX=7F7B6575
10026ACB   8948 04          MOV DWORD PTR DS:[EAX+4],ECX                     [0148F010]=7F7B6575
10026ACE   B9 06000000      MOV ECX,6
10026AD3   8B52 08          MOV EDX,DWORD PTR DS:[EDX+8]                     EDX=C9CECF7B
10026AD6   8950 08          MOV DWORD PTR DS:[EAX+8],EDX                     [0148F014]=C9CECF7B
10026AD9   895C24 10        MOV DWORD PTR SS:[ESP+10],EBX
10026ADD   66:8B10          MOV DX,WORD PTR DS:[EAX]              \          
10026AE0   83C0 02          ADD EAX,2                             |
10026AE3   66:F7D2          NOT DX                                |          
10026AE6   66:8950 FE       MOV WORD PTR DS:[EAX-2],DX            |
10026AEA   49               DEC ECX                               |         这个循环得到真正得机器码:A173-8C79-9A8A-8084-3084-3631
10026AEB  ^75 F0            JNZ SHORT LWSRF.10026ADD              /
10026AED   3BF3             CMP ESI,EBX
10026AEF   0F84 E5000000    JE LWSRF.10026BDA
10026AF5   33C0             XOR EAX,EAX
10026AF7   899C24 84000000  MOV DWORD PTR SS:[ESP+84],EBX
10026AFE   66:8B45 00       MOV AX,WORD PTR SS:[EBP]
10026B02   C1E0 05          SHL EAX,5                                        EAX=A173 SHL 5=00142E60
                           .
                           .
                           .
                           .
                           .
                           .
10026E86   0F85 61010000    JNZ LWSRF.10026FED                              上面省略的一段都是一堆垃圾,把个机器码变来变去的,耍花招呢,不用怕,就在下面又还机器码真实面目
10026E8C   8B0D 684D0510    MOV ECX,DWORD PTR DS:[10054D68]                  ECX=83B8B000下面这段又重新得到机器码,并进行计算
10026E92   884424 2C        MOV BYTE PTR SS:[ESP+2C],AL
10026E96   8B4424 24        MOV EAX,DWORD PTR SS:[ESP+24]
10026E9A   8D4C08 20        LEA ECX,DWORD PTR DS:[EAX+ECX+20]                ECX=83B8B020
10026E9E   8BC5             MOV EAX,EBP
10026EA0   8B31             MOV ESI,DWORD PTR DS:[ECX]                       ESI=73865E8C
10026EA2   8930             MOV DWORD PTR DS:[EAX],ESI
10026EA4   8B71 04          MOV ESI,DWORD PTR DS:[ECX+4]                     ESI=7F7B6575
10026EA7   8970 04          MOV DWORD PTR DS:[EAX+4],ESI
10026EAA   8B49 08          MOV ECX,DWORD PTR DS:[ECX+8]                     ECX=C9CECF7B
10026EAD   8948 08          MOV DWORD PTR DS:[EAX+8],ECX
10026EB0   33C9             XOR ECX,ECX
10026EB2  >66:8B444D 00     MOV AX,WORD PTR SS:[EBP+ECX*2]         \          
10026EB7   66:F7D0          NOT AX                                 |         
10026EBA   66:89444D 00     MOV WORD PTR SS:[EBP+ECX*2],AX         |
10026EBF   25 FFFF0000      AND EAX,0FFFF                          |
10026EC4   03D8             ADD EBX,EAX                            |
10026EC6   83F9 03          CMP ECX,3                              |                                   
10026EC9   75 03            JNZ SHORT LWSRF.10026ECE               |
10026ECB   8D1C43           LEA EBX,DWORD PTR DS:[EBX+EAX*2]       |
10026ECE   41               INC ECX                                |          这个循环把真机器码的6个部分
10026ECF   83F9 06          CMP ECX,6                              |          按①+②+③+④+④*2+⑤+⑥的式子计算得3B0B7
10026ED2  ^7C DE            JL SHORT LWSRF.10026EB2                /
10026ED4   33F6             XOR ESI,ESI
10026ED6   8BFA             MOV EDI,EDX
10026ED8   89AC24 84000000  MOV DWORD PTR SS:[ESP+84],EBP                  
10026EDF   83FE 06          CMP ESI,6                                \     
10026EE2   0F8D 49010000    JGE LWSRF.10027031                       |
10026EE8   85F6             TEST ESI,ESI                             |
10026EEA   7D 27            JGE SHORT LWSRF.10026F13                 |
10026EEC   8B8424 84000000  MOV EAX,DWORD PTR SS:[ESP+84]            |
10026EF3   33D2             XOR EDX,EDX                              |
10026EF5   8BC8             MOV ECX,EAX                              |
10026EF7   66:8B10          MOV DX,WORD PTR DS:[EAX]                 |
10026EFA   83C1 02          ADD ECX,2
10026EFD   0FAFD6           IMUL EDX,ESI
10026F00   D1E2             SHL EDX,1                                |
10026F02   46               INC ESI
10026F03   895424 10        MOV DWORD PTR SS:[ESP+10],EDX            |
10026F07   898C24 84000000  MOV DWORD PTR SS:[ESP+84],ECX
10026F0E   83C7 05          ADD EDI,5
10026F11  ^EB CC            JMP SHORT LWSRF.10026EDF                 |
10026F13   8B0F             MOV ECX,DWORD PTR DS:[EDI]                      
10026F15   8D5424 10        LEA EDX,DWORD PTR SS:[ESP+10]            |
10026F19   52               PUSH EDX
10026F1A   8D4424 2C        LEA EAX,DWORD PTR SS:[ESP+2C]            |      
10026F1E   68 98E60410      PUSH LWSRF.1004E698                              ASCII "%lx"
10026F23   50               PUSH EAX
10026F24   C64424 38 00     MOV BYTE PTR SS:[ESP+38],0
10026F29   894C24 34        MOV DWORD PTR SS:[ESP+34],ECX            |
10026F2D   E8 2AD20100      CALL LWSRF.1004415C
10026F32   83C4 0C          ADD ESP,0C                               |
10026F35   83FE 05          CMP ESI,5
10026F38   7D 1D            JGE SHORT LWSRF.10026F57
10026F3A   8B4424 10        MOV EAX,DWORD PTR SS:[ESP+10]            |
10026F3E   8B8C24 84000000  MOV ECX,DWORD PTR SS:[ESP+84]
10026F45   03D8             ADD EBX,EAX                              |       EBX=3B0B7+A123=451DA+4B56=49D30+7C8D=519BD+9087=5AA44+4567=5EFAB
10026F47   83C1 02          ADD ECX,2                                |       EBX=7FFF8+A123=8A11B+4B56=8EC71+7C8D=968FE+9087=9F985+4567=A3EEC
10026F4A   46               INC ESI                                  |
10026F4B   898C24 84000000  MOV DWORD PTR SS:[ESP+84],ECX            |
10026F52   83C7 05          ADD EDI,5                                |       这个循环是把上面得到的3B0B7依次加上假码的每一部分
10026F55  ^EB 88            JMP SHORT LWSRF.10026EDF                 /       结果放在EBX中
10026F57   8B4424 10        MOV EAX,DWORD PTR SS:[ESP+10]                    把假码的最后一部分放入EAX
10026F5B   81E3 FFFF0000    AND EBX,0FFFF                                    取结果的后两字节EBX=EFAB
10026F61   25 FFFF0000      AND EAX,0FFFF                                    与假码的最后一部分比较
10026F66   3BC3             CMP EAX,EBX                                     在这里用内存注册机中断,取得寄存器EBX的值,就应该是真码的最后一部分
10026F68   894424 10        MOV DWORD PTR SS:[ESP+10],EAX
10026F6C   75 1A            JNZ SHORT LWSRF.10026F88                        相等就不跳,跳就完蛋!
10026F6E   8B8C24 84000000  MOV ECX,DWORD PTR SS:[ESP+84]                   可见我的正确注册码的最后一部分应该等于EFAB,即A123-4B56-7C8D-9087-4567-EFAB
10026F75   46               INC ESI
10026F76   83C1 02          ADD ECX,2
10026F79   83C7 05          ADD EDI,5
10026F7C   898C24 84000000  MOV DWORD PTR SS:[ESP+84],ECX
10026F83  ^E9 57FFFFFF      JMP LWSRF.10026EDF
10026F88   8B8424 8C000000  MOV EAX,DWORD PTR SS:[ESP+8C]
10026F8F   85C0             TEST EAX,EAX
10026F91   75 7C            JNZ SHORT LWSRF.1002700F
10026F93   C78424 8C000000 >MOV DWORD PTR SS:[ESP+8C],1
10026F9E   83CE FF          OR ESI,FFFFFFFF
10026FA1   8B8424 8C000000  MOV EAX,DWORD PTR SS:[ESP+8C]
10026FA8   33DB             XOR EBX,EBX
10026FAA  ^E9 FFFAFFFF      JMP LWSRF.10026AAE                                如果上面跳了的话,这里就再跳到最前面算出一些很奇怪的值来,反正是死路一条
10026FAF   8D7C24 58        LEA EDI,DWORD PTR SS:[ESP+58]
10026FB3   83C9 FF          OR ECX,FFFFFFFF
10026FB6   33C0             XOR EAX,EAX
10026FB8   F2:AE            REPNE SCAS BYTE PTR ES:[EDI]
10026FBA   F7D1             NOT ECX
10026FBC   2BF9             SUB EDI,ECX
10026FBE   8B4424 14        MOV EAX,DWORD PTR SS:[ESP+14]
10026FC2   8BD1             MOV EDX,ECX
10026FC4   8BF7             MOV ESI,EDI
10026FC6   8BBC24 80000000  MOV EDI,DWORD PTR SS:[ESP+80]
10026FCD   50               PUSH EAX
10026FCE   C1E9 02          SHR ECX,2
10026FD1   F3:A5            REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
10026FD3   8BCA             MOV ECX,EDX
10026FD5   83E1 03          AND ECX,3
10026FD8   F3:A4            REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
10026FDA   FF15 C8B10410    CALL DWORD PTR DS:[<&KERNEL32.HeapDestroy>]
10026FE0   5F               POP EDI
10026FE1   5E               POP ESI
10026FE2   5D               POP EBP
10026FE3   B8 01000000      MOV EAX,1
10026FE8   5B               POP EBX
10026FE9   83C4 6C          ADD ESP,6C
10026FEC   C3               RETN
10026FED   8B4C24 14        MOV ECX,DWORD PTR SS:[ESP+14]
10026FF1   51               PUSH ECX
10026FF2   FF15 C8B10410    CALL DWORD PTR DS:[<&KERNEL32.HeapDestroy>]
10026FF8   8B15 684D0510    MOV EDX,DWORD PTR DS:[10054D68]
10026FFE   5F               POP EDI
10026FFF   5E               POP ESI
10027000   5D               POP EBP
10027001   C742 18 00000000 MOV DWORD PTR DS:[EDX+18],0
10027008   33C0             XOR EAX,EAX
1002700A   5B               POP EBX
1002700B   83C4 6C          ADD ESP,6C
1002700E   C3               RETN
1002700F   8B4424 14        MOV EAX,DWORD PTR SS:[ESP+14]
10027013   50               PUSH EAX
10027014   FF15 C8B10410    CALL DWORD PTR DS:[<&KERNEL32.HeapDestroy>]
1002701A   8B0D 684D0510    MOV ECX,DWORD PTR DS:[10054D68]
10027020   5F               POP EDI
10027021   5E               POP ESI
10027022   5D               POP EBP
10027023   C741 18 00000000 MOV DWORD PTR DS:[ECX+18],0
1002702A   33C0             XOR EAX,EAX
1002702C   5B               POP EBX
1002702D   83C4 6C          ADD ESP,6C
10027030   C3               RETN
10027031   8B15 684D0510    MOV EDX,DWORD PTR DS:[10054D68]
10027037   8B4C24 14        MOV ECX,DWORD PTR SS:[ESP+14]
1002703B   51               PUSH ECX
1002703C   C742 18 01000000 MOV DWORD PTR DS:[EDX+18],1
10027043   A1 684D0510      MOV EAX,DWORD PTR DS:[10054D68]
10027048   66:C740 50 BC00  MOV WORD PTR DS:[EAX+50],0BC
1002704E   FF15 C8B10410    CALL DWORD PTR DS:[<&KERNEL32.HeapDestroy>]
10027054   5F               POP EDI
10027055   5E               POP ESI
10027056   5D               POP EBP
10027057   B8 01000000      MOV EAX,1
1002705C   5B               POP EBX
1002705D   83C4 6C          ADD ESP,6C
10027060   C3               RETN
***********************************************************************
算法总结:
    软件的算法本身没什么新意,但加了不少没用的东西掩人耳目,基本算法为:真机器码的6个部分(不包含'-')按①+②+③+④+④*2+⑤+⑥求和(是直接作为16进制相加),再用这个和依次累加注册码的前5部分(不包含'-'),设累加结果为SUM(也是直接作为16进制相加),最后检验注册码最后一部分即第6部分是否等于SUM,等于就成功,不等于就跳死。
假机器码的由来:
    软件在启动注册窗口时得到真机器码,把它的前4部分接到它自己的屁股后面去,再经过下面的变换得到假的也就是显示在注册窗口上的机器码
10027429   F3:A4            REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI>
1002742B   8A8424 8F000000  MOV AL,BYTE PTR SS:[ESP+8F]
10027432   8A4C24 71        MOV CL,BYTE PTR SS:[ESP+71]
10027436   8A9424 89000000  MOV DL,BYTE PTR SS:[ESP+89]
1002743D   884424 71        MOV BYTE PTR SS:[ESP+71],AL
10027441   8A8424 94000000  MOV AL,BYTE PTR SS:[ESP+94]
10027448   888C24 8F000000  MOV BYTE PTR SS:[ESP+8F],CL
1002744F   8A8C24 86000000  MOV CL,BYTE PTR SS:[ESP+86]
10027456   888424 89000000  MOV BYTE PTR SS:[ESP+89],AL
1002745D   8A8424 9F000000  MOV AL,BYTE PTR SS:[ESP+9F]
10027464   889424 94000000  MOV BYTE PTR SS:[ESP+94],DL
1002746B   8A9424 95000000  MOV DL,BYTE PTR SS:[ESP+95]
10027472   888424 86000000  MOV BYTE PTR SS:[ESP+86],AL
10027479   8A4424 73        MOV AL,BYTE PTR SS:[ESP+73]
1002747D   888C24 9F000000  MOV BYTE PTR SS:[ESP+9F],CL
10027484   888424 95000000  MOV BYTE PTR SS:[ESP+95],AL
1002748B   8D4424 70        LEA EAX,DWORD PTR SS:[ESP+70]
如:我的真机器码是A173-8C79-9A8A-8084-3084-3631,把前4部分接到后面得:A173-8C79-9A8A-8084-3084-3631-A173-8C79-9A8A-8084,经变换后得到的假机器码为A177-8C79-9A8A-8084-3084-C631-A173-8339-9A8A-8084
我大致看了一下好象是做了下面的对掉:
                  第2位<---->第32位
                  第4位<---->第38位
                 第23位<---->第48位
                 第26位<---->第37位
我数的不是太仔细,有兴趣的可以自己看看,不对的地方还请指正 :P
    注册码不管对错都以二进制保存在注册表“HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\龙文输入法”的“注册码”主键下
软件还在“HKEY_LOCAL_MACHINE\SOFTWARE\Zlocksoft\Zlock20020630”下写了“Name”“Serial”和“Version”3个主键,我没看懂什么意思,可能是用来判断是否过期的吧,哪位知道请告诉我哦
**********************************************************
内存注册机:with keymake1.73

           程序名:  NOTEPAD.EXE
           中断地址:10026F66
           中断次数:1   
           第1字节: 3B
           指令长度:2字节

           寄存器方式
           EBX   十六进制

使用方法:把注册机放在WINDOWS或WINNT目录下,运行后在出现的记事本上选出龙文输入平台输入法,打开它的注册窗口,填好注册码(必须是29位6部分,以'-'分隔,每部分4位),点注册,断下后在注册机上看到的数可能是重复的两部分,如EFABEFAB,取其中的一部分(4位,不足4位在前面加0),就是你注册码的最后一部分,如果不是重复的两部分,就取其前4位,也应该是你注册码的最后一部分。为什么可能重复也可能不重复我也说不清楚,在OllyDbg跟踪时明明看到断后EBX只有两个低位字节,可用内存注册机断后看到的就不只两位,还请哪位大哥指教 :)

呵,终于写完了,可以睡觉了。我的上一篇破文居然引的软件作者跑到论坛上来和我理论,希望这篇不要再引的作者来,不然我可睡不好觉哦 ^_^

              
                                                                   thl0057 
                                                               2003/10/25 凌晨 于 HD