文書處理LemmyV4.0演算法淺析!

看雪資料發表於2003-07-03

軟體大小:  851 KB
軟體語言:  英文
軟體類別:  國外軟體 / 共享版 / 文書處理
應用平臺:  Win9x/NT/2000/XP
介面預覽:  無
加入時間:  2003-07-02 17:09:04
推薦等級:  ★★★★
軟體下載:  http://count.skycn.com/softdown.php?id=12742&url=http://on165-http.skycn.net:8080/down/lemmy40.exe

軟體介紹:
   是一套文字編輯軟體。是Unix上的檔案編輯器(vi)的Windows版本。它提供了vi的所有功能。以下列出幾個unix下的vi所沒有的功能:1、分割視窗模式,允許向上移四個分割視窗。2、支援Windows的剪貼簿。3、可以直接拖拉檔案到Lemmy中。4、可以設定字型與顏色,並且支援語法高亮度顯示。5、狀態列顯示資訊。6、可從檔案選單中,選取最近使用過的檔案。7、支援印表機列印,也可以把語法高亮度印出來喔。雖然它是個文字編輯器,但對Windows的使用者來說,是一套很不好用的編輯器。


破解工具:OllyDby1.09,TRW1.22
作者宣告:初學破解,僅作學習交流之用,失誤之處敬請大俠賜教!

無殼,VC編寫,這個軟體的註冊部分是在安裝資料夾下的lemreg.exe檔案中!
先在TRW中用bpx getwindowtexta下斷找斷點,再用OD載入lemreg.exe分析!

【簡要過程】:
使用者名稱:ShenGe[BCG]
試驗碼:1234567887654321

.............(略)
0040179B  PUSH    EAX  
                 <---EAX="1234567887654321",假碼                      
0040179C  PUSH    ECX
                 <---ECX="ShenGe[BCG]",使用者名稱
0040179D  LEA     ECX, DWORD PTR DS:[ESI+68]
004017A0  CALL    LEMREG.004019F0
                 <---這個是關鍵的Call,跟進!①
004017A5  TEST    EAX, EAX                        
004017A7  JE      SHORT LEMREG.004017FF
                 <---關鍵跳轉!不跳就完了!
004017A9  PUSH    0
004017AB  PUSH    30
004017AD  PUSH    LEMREG.0042E0B0                  
                 <---"Check the values supplied"入棧!
004017B2  CALL    LEMREG.0041EE0E
                 <---註冊碼錯誤!
004017B7  PUSH    3E8
004017BC  MOV     ECX, ESI
004017BE  CALL    LEMREG.0041B8AA
004017C3  MOV     ECX, EAX                        
004017C5  CALL    LEMREG.0041BB07
004017CA  PUSH    3E8
004017CF  MOV     ECX, ESI
004017D1  CALL    LEMREG.0041B8AA
004017D6  MOV     EDI, DWORD PTR DS:[<&USER32.Send>
004017DC  MOV     ESI, EAX                        
004017DE  PUSH    -1                               ; /lParam = FFFFFFFF
004017E0  PUSH    0                                ; |wParam = 0
004017E2  MOV     ECX, DWORD PTR DS:[ESI+1C]       ; |
004017E5  PUSH    0B1                              ; |Message = EM_SETSEL
004017EA  PUSH    ECX                              ; |hWnd = 81637000
004017EB  CALL    EDI                              ; \SendMessageA
004017ED  MOV     EDX, DWORD PTR DS:[ESI+1C]
004017F0  PUSH    0                                ; /lParam = 0
004017F2  PUSH    0                                ; |wParam = 0
004017F4  PUSH    0B7                              ; |Message = EM_SCROLLCARET
004017F9  PUSH    EDX                              ; |hWnd = 81637040
004017FA  CALL    EDI                              ; \SendMessageA
004017FC  POP     EDI    
004017FD  POP     ESI                          
004017FE  RETN
004017FF  MOV     ECX, ESI
00401801  CALL    LEMREG.00418656
00401806  POP     EDI                              
00401807  POP     ESI                              
00401808  RETN

★★★★★★★★★
①跟進那個關鍵的Call,來到以下程式碼:
004019F0  PUSH    EBX
004019F1  PUSH    EBP
004019F2  PUSH    ESI
004019F3  PUSH    EDI
004019F4  MOV     EDI, ECX
004019F6  PUSH    8
004019F8  OR      EBP, FFFFFFFF
004019FB  CALL    LEMREG.00417E88
00401A00  MOV     ESI, DWORD PTR SS:[ESP+1C]
00401A04  ADD     ESP, 4
00401A07  MOV     EBX, EAX
00401A09  XOR     EDX, EDX

☆☆☆☆☆☆☆☆☆☆
00401A0B  MOVSX   EAX, BYTE PTR DS:[ESI]
                 <---取假碼第1位
00401A0E  MOVSX   ECX, BYTE PTR DS:[ESI+1]
                 <---取假碼第2位

下面這1段對取得的字元進行判斷,並進行不同的處理:
對於字元在[0,9]的,Hex值減0x30
對於字元在[A,F]的,Hex值減0x37
其餘字元為不合法字元
≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈
00401A12  CMP     EAX, 30
00401A15  JL      SHORT LEMREG.00401A21
00401A17  CMP     EAX, 39
00401A1A  JG      SHORT LEMREG.00401A21
00401A1C  SUB     EAX, 30
00401A1F  JMP     SHORT LEMREG.00401A32
00401A21  CMP     EAX, 41
00401A24  JL      SHORT LEMREG.00401A30
00401A26  CMP     EAX, 46
00401A29  JG      SHORT LEMREG.00401A30
00401A2B  SUB     EAX, 37
00401A2E  JMP     SHORT LEMREG.00401A32
00401A30  XOR     EAX, EAX
00401A32  CMP     ECX, 30
00401A35  JL      SHORT LEMREG.00401A41
00401A37  CMP     ECX, 39
00401A3A  JG      SHORT LEMREG.00401A41
00401A3C  SUB     ECX, 30
00401A3F  JMP     SHORT LEMREG.00401A52
00401A41  CMP     ECX, 41
00401A44  JL      SHORT LEMREG.00401A50
00401A46  CMP     ECX, 46
00401A49  JG      SHORT LEMREG.00401A50
00401A4B  SUB     ECX, 37
00401A4E  JMP     SHORT LEMREG.00401A52
≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈

00401A50  XOR     ECX, ECX
-------------------------
00401A52  SHL     AL, 4
00401A55  ADD     AL, CL
-------------------------
☆☆☆☆☆☆☆☆☆☆
這1段實現如下功能:Char(如"12")--->Hex(轉換成0x12)

00401A57  ADD     ESI, 2
                 <---指標指向下一組
00401A5A  MOV     BYTE PTR DS:[EBX+EDX], AL
                 <---結果存入DS:[EBX+EDX]中
                 我的結果在記憶體中表示為:
                 12 34 56 78 87 65 43 21
00401A5D  INC     EDX
00401A5E  CMP     EDX, 8
                 <---迴圈控制,迴圈8次
00401A61  JL      SHORT LEMREG.00401A0B
00401A63  PUSH    EBX
                 <---EBX的值為上面運算後的結果
                 在記憶體中為12 34 56 78 87 65 43 21  
00401A64  MOV     ECX, EDI                          
00401A66  CALL    LEMREG.00401060  
                 <---跟進此Call看看②,此Call後的返回
                 值在EBX中為:B6 7C EE 16 84 13 91 EE
00401A6B  MOV     EDX, DWORD PTR SS:[ESP+14]
                 <---EDX="ShenGe[BCG]"      
00401A6F  OR      ECX, FFFFFFFF
00401A72  MOV     EDI, EDX
00401A74  XOR     EAX, EAX
00401A76  REPNE   SCAS BYTE PTR ES:[EDI]
                 <---取使用者名稱位數
00401A78  NOT     ECX
00401A7A  DEC     ECX
00401A7B  CMP     ECX, 8
                 <---判斷使用者名稱位數是否大於等於8
00401A7E  JBE     SHORT LEMREG.00401A87
00401A80  MOV     ECX, 8
                 <---ECX=8,估計只取使用者名稱8位運算
00401A85  JMP     SHORT LEMREG.00401A93
00401A87  MOV     EDI, EDX
00401A89  OR      ECX, FFFFFFFF
00401A8C  XOR     EAX, EAX
00401A8E  REPNE   SCAS BYTE PTR ES:[EDI]
00401A90  NOT     ECX
00401A92  DEC     ECX
00401A93  TEST    ECX, ECX
00401A95  JLE     SHORT LEMREG.00401AA8
00401A97  PUSH    ECX
                 <---ECX=8
00401A98  PUSH    EBX
                 <---EBX指向B6 7C EE 16 84 13 91 EE
00401A99  PUSH    EDX
                 <---EDX="ShenGe[BCG]"
00401A9A  CALL    LEMREG.004079F0
                 <---比對的Call,這個程式碼我就不列出來了
                 這個Call將使用者名稱的前8位字元的Hex與
                 B6 7C EE 16 84 13 91 EE分別進行比較是否相等,
                 即要求註冊碼經過轉換後的值要與使用者名稱
                 的Hex值相等。
00401A9F  ADD     ESP, 0C
00401AA2  TEST    EAX, EAX
00401AA4  JNZ     SHORT LEMREG.00401AA8
                 <---比較不相等此處會跳!
00401AA6  XOR     EBP, EBP
                 <---EBP=0
00401AA8  PUSH    EBX
00401AA9  CALL    LEMREG.00417EC4
00401AAE  ADD     ESP, 4
00401AB1  MOV     EAX, EBP
                 <---EAX=EBP,標誌位!
00401AB3  POP     EDI                              
00401AB4  POP     ESI                              
00401AB5  POP     EBP                              
00401AB6  POP     EBX                            
00401AB7  RETN    8


★★★★★★★★★
②跟進這個Call:
00401060  SUB     ESP, 8
00401063  MOV     EDX, DWORD PTR SS:[ESP+C]
                 <---EDX指向記憶體中
                 12 34 56 78 87 65 43 21
00401067  PUSH    EBX
00401068  PUSH    ESI
00401069  PUSH    EDI
☆☆☆☆☆☆☆☆☆☆
0040106A  MOV     AL, BYTE PTR DS:[EDX+4]
                 <---AL=87,取第5位
0040106D  MOV     EDI, ECX
0040106F  MOV     CL, BYTE PTR DS:[EDX+2]
                 <---CL=56,取第3位
00401072  MOV     BYTE PTR SS:[ESP+C], AL
                 <---AL的值存入SS:[ESP+C]
00401076  MOV     AL, BYTE PTR DS:[EDX+7]
                 <---AL=21,取第8位
00401079  MOV     BYTE PTR SS:[ESP+D], CL
                 <---CL的值存入SS:[ESP+D]中
0040107D  MOV     CL, BYTE PTR DS:[EDX]
                 <---CL=12,取第1位,唉!後面懶得寫了!
0040107F  MOV     BYTE PTR SS:[ESP+E], AL
00401083  MOV     AL, BYTE PTR DS:[EDX+6]
00401086  MOV     BYTE PTR SS:[ESP+F], CL
0040108A  MOV     CL, BYTE PTR DS:[EDX+3]
0040108D  MOV     BYTE PTR SS:[ESP+10], AL
00401091  MOV     AL, BYTE PTR DS:[EDX+5]
00401094  MOV     BYTE PTR SS:[ESP+11], CL
00401098  MOV     CL, BYTE PTR DS:[EDX+1]
0040109B  MOV     BYTE PTR SS:[ESP+12], AL
☆☆☆☆☆☆☆☆☆☆
上面這一小段是將記憶體中的值重新排序,對應關係如下:

原值:                12 34 56 78 87 65 43 21
                     ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
對應於在原值中的位置:5  3  8  1  7  4  6  2
----------------------------------------------
排序後:              87 56 21 12 43 78 65 34
                 
0040109F  LEA     ESI, DWORD PTR SS:[ESP+C]
004010A3  XOR     EAX, EAX
004010A5  MOV     BYTE PTR SS:[ESP+13], CL
004010A9  SUB     ESI, EDX
004010AB  MOV     CL, BYTE PTR DS:[EAX+EDI+14]
                 <---[EDI+14]中指向的記憶體中為
                定值31 2A CF 04 C7 6B F4 DA
                 CL=0x31
                 CL=0x2A
                 .....(略)
004010AF  MOV     BL, BYTE PTR DS:[ESI+EDX]
                 <---[ESI]中為重新排序後的值
                 87 56 21 12 43 78 65 34
                 BL=0x87
                 BL=0x56
                 ....(略)
004010B2  XOR     CL, BL
                 <---CL=CL^BL=0x31^0x87=0xB6
                     CL=0x2A^0x56=0x7C
                     ....(略)
004010B4  INC     EAX
004010B5  MOV     BYTE PTR DS:[EDX], CL
                 <---作或運算後的結果存入DS:[EDX]中
                 我最後得到的為:B6 7C EE 16 84 13 91 EE
004010B7  INC     EDX
004010B8  CMP     EAX, 8
004010BB  JL      SHORT LEMREG.004010AB
004010BD  POP     EDI                              
004010BE  POP     ESI                              
004010BF  POP     EBX                              
004010C0  ADD     ESP, 8
004010C3  RETN    4

【總結】:使用者名稱長度必須大於或等於8,註冊碼與使用者名稱前8位有關。具體演算法見我下
面逆推我的註冊碼過程:
程式中置定值31 2A CF 04 C7 6B F4 DA與註冊碼作運算!

 S--->53---->53^31=62
 h--->68---->68^2A=42
 e--->65====>65^CF=AA
 n--->6E====>6E^04=6A
 G--->47====>47^C7=80
 e--->65====>65^6B=0E
 [--->5B====>5B^F4=AF
 B--->42====>42^DA=98

原值:               6A 98 42 0E 62 AF 80 AA
--------------------------------------------
對應於在原值的位置: 5  3  8  1  7  4  6  2
                    ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑
排序後:             62 42 AA 6A 80 0E AF 98

由此得到我的註冊碼為:6A98420E62AF80AA
軟體註冊成功後將註冊資訊儲存在登錄檔的:
"HKEY_LOCAL_MACHINE\Software\Lemmy\Lemmy\Registration"下。
                 
給出一個可用註冊碼:
使用者名稱:ShenGe[BCG]
註冊碼:6A98420E62AF80AA

                                             Cracked By ShenGe[BCG]  2003.07.03


相關文章