不脫殼破解極光多能鬧鐘 (16千字)

看雪資料發表於2003-04-14

-------------------------------------------------------------------------------------
目標軟體:極光多能鬧鐘
軟體版本:4.4
軟體簡介:時鐘提醒
下載地址:http://jgsoft.wx-e.com/
保護方式:未註冊版有60天試用期,試用期間無功能限制。註冊碼一機一碼。
程式語言:VB,Native-code
破解工具:ollydbg,w32dasm
破解人 :sunrix
破解日期:2003-4-11
-------------------------------------------------------------------------------------

主程式JgClockXP.exe,用PEID檢查,報告用tElock 0.98b1加殼。因為在網上沒有找到相應的unpacker,
又不想手動脫殼,所以想用attach到程式的方式在不脫殼的方式下進行破解。

執行程式,用ollydbg attach到程式。調出註冊對話方塊,結果發現作者使用了一個小伎倆,就是把輸入註冊
碼的編輯框禁用了,無法直接輸入註冊碼。作者說在傳送註冊碼的郵件裡會告訴使用者如何解開編輯框。據估計,
應該是用一個鍵組合來開放編輯框,而且VB本身也提供了熱鍵的功能,即KeyDown,KeyUp,KeyPress事件。但如何
找到此熱鍵呢?

如果使用者輸入了特定的熱鍵,則程式中肯定有程式碼來開放註冊碼編輯框,以便使用者輸入註冊碼。即將冊碼編輯框
的Enabled屬性設為True。(雖然將編輯框設為不能輸入,可以用Enabled屬性,也可以用Locked屬性。但後者不
將編輯框變灰。從程式的註冊對話方塊來看,應該是用Enabled屬性)。

如果找到了將冊碼編輯框的Enabled屬性設為True的程式碼,這段程式碼應該是在KeyDown或KeyPress事件Handler中,
則找到相應的熱鍵就比較容易了。

在VB6.0中新建一個工程,在Form中加入一個Edit控制元件,然後加入FormLoad事件程式碼:
Private Sub Form_Load()
Text1.Enabled = True
MsgBox "enabled"
End Sub

之所以加了MsgBox的呼叫,是為了反彙編後找到編譯後的事件處理程式碼。注意用Native-code方式編譯。然後用
w32dasm反彙編,查詢rtcMsgBox,相關的程式碼如下:

:00401A40 55                      push ebp
:00401A41 8BEC                    mov ebp, esp
:00401A43 83EC0C                  sub esp, 0000000C
:00401A46 68A6104000              push 004010A6
:00401A4B 64A100000000            mov eax, dword ptr fs:[00000000]
:00401A51 50                      push eax
:00401A52 64892500000000          mov dword ptr fs:[00000000], esp
:00401A59 81EC94000000            sub esp, 00000094
:00401A5F 53                      push ebx
:00401A60 56                      push esi
:00401A61 57                      push edi
:00401A62 8965F4                  mov dword ptr [ebp-0C], esp
:00401A65 C745F890104000          mov [ebp-08], 00401090
:00401A6C 8B7508                  mov esi, dword ptr [ebp+08]
:00401A6F 8BC6                    mov eax, esi
:00401A71 83E001                  and eax, 00000001
:00401A74 8945FC                  mov dword ptr [ebp-04], eax
:00401A77 83E6FE                  and esi, FFFFFFFE
:00401A7A 56                      push esi
:00401A7B 897508                  mov dword ptr [ebp+08], esi
:00401A7E 8B0E                    mov ecx, dword ptr [esi]
:00401A80 FF5104                  call [ecx+04]
:00401A83 8B16                    mov edx, dword ptr [esi]
:00401A85 33FF                    xor edi, edi
:00401A87 56                      push esi
:00401A88 897DE8                  mov dword ptr [ebp-18], edi
:00401A8B 897DD8                  mov dword ptr [ebp-28], edi
:00401A8E 897DC8                  mov dword ptr [ebp-38], edi
:00401A91 897DB8                  mov dword ptr [ebp-48], edi
:00401A94 897DA8                  mov dword ptr [ebp-58], edi
:00401A97 897D98                  mov dword ptr [ebp-68], edi
:00401A9A FF92FC020000            call dword ptr [edx+000002FC]        // 取得Form上edit控制元件的物件指標
:00401AA0 50                      push eax
:00401AA1 8D45E8                  lea eax, dword ptr [ebp-18]
:00401AA4 50                      push eax

* Reference To: MSVBVM60.__vbaObjSet, Ord:0000h
                                  |
:00401AA5 FF151C104000            Call dword ptr [0040101C]
:00401AAB 8BF0                    mov esi, eax
:00401AAD 6AFF                    push FFFFFFFF
:00401AAF 56                      push esi
:00401AB0 8B0E                    mov ecx, dword ptr [esi]        // Edit控制元件的vtable
:00401AB2 FF918C000000            call dword ptr [ecx+0000008C]        // Enabled屬性的property let函式的指標在vtable偏移8C處
:00401AB8 3BC7                    cmp eax, edi
:00401ABA DBE2                    fclex
:00401ABC 7D12                    jge 00401AD0
:00401ABE 688C000000              push 0000008C
:00401AC3 68E0164000              push 004016E0
:00401AC8 56                      push esi
:00401AC9 50                      push eax

* Reference To: MSVBVM60.__vbaHresultCheckObj, Ord:0000h
                                  |
:00401ACA FF1514104000            Call dword ptr [00401014]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401ABC(C)
|
:00401AD0 8D4DE8                  lea ecx, dword ptr [ebp-18]

* Reference To: MSVBVM60.__vbaFreeObj, Ord:0000h
                                  |
:00401AD3 FF1584104000            Call dword ptr [00401084]
:00401AD9 B904000280              mov ecx, 80020004
:00401ADE B80A000000              mov eax, 0000000A
:00401AE3 894DB0                  mov dword ptr [ebp-50], ecx
:00401AE6 894DC0                  mov dword ptr [ebp-40], ecx
:00401AE9 894DD0                  mov dword ptr [ebp-30], ecx
:00401AEC 8D5598                  lea edx, dword ptr [ebp-68]
:00401AEF 8D4DD8                  lea ecx, dword ptr [ebp-28]
:00401AF2 8945A8                  mov dword ptr [ebp-58], eax
:00401AF5 8945B8                  mov dword ptr [ebp-48], eax
:00401AF8 8945C8                  mov dword ptr [ebp-38], eax
:00401AFB C745A0F4164000          mov [ebp-60], 004016F4
:00401B02 C7459808000000          mov [ebp-68], 00000008

* Reference To: MSVBVM60.__vbaVarDup, Ord:0000h
                                  |
:00401B09 FF1570104000            Call dword ptr [00401070]
:00401B0F 8D55A8                  lea edx, dword ptr [ebp-58]
:00401B12 8D45B8                  lea eax, dword ptr [ebp-48]
:00401B15 52                      push edx
:00401B16 8D4DC8                  lea ecx, dword ptr [ebp-38]
:00401B19 50                      push eax
:00401B1A 51                      push ecx
:00401B1B 8D55D8                  lea edx, dword ptr [ebp-28]
:00401B1E 57                      push edi
:00401B1F 52                      push edx

* Reference To: MSVBVM60.rtcMsgBox, Ord:0253h
                                  |
:00401B20 FF1520104000            Call dword ptr [00401020]        // 故意安排的MsgBox呼叫
:00401B26 8D45A8                  lea eax, dword ptr [ebp-58]

從上面知道,Enabled屬性的property set函式的指標在編輯框物件vtable偏移8C處。然而光憑這個還無法找到開放註冊碼
編輯框enabled屬性的程式碼。還需要配合取註冊對話方塊Form上註冊碼編輯框的程式碼來查詢。

執行XXXX鬧鐘,用ollydbg attach。在MSVBVM60.DLL的rtcMsgBox函式上設定斷點。進入註冊對話方塊,此時還不能輸入註冊碼,
直接點<ok>按鈕。Ollydbg攔下,ctrl-f9返回。然後往上翻一翻,

00478DE0  PUSH EBP
00478DE1  MOV EBP,ESP
00478DE3  SUB ESP,14
00478DE6  PUSH JgClockX.00402996                                ;  JMP to MSVBVM60.__vbaExceptHandler; SE handler installation
00478DEB  MOV EAX,DWORD PTR FS:[0]
00478DF1  PUSH EAX
00478DF2  MOV DWORD PTR FS:[0],ESP
00478DF9  SUB ESP,124
00478DFF  PUSH EBX
00478E00  PUSH ESI
00478E01  PUSH EDI
00478E02  MOV DWORD PTR SS:[EBP-14],ESP
00478E05  MOV DWORD PTR SS:[EBP-10],JgClockX.00402068
00478E0C  MOV EDI,DWORD PTR SS:[EBP+8]
00478E0F  MOV EAX,EDI
00478E11  AND EAX,1
00478E14  MOV DWORD PTR SS:[EBP-C],EAX
00478E17  AND EDI,FFFFFFFE
00478E1A  MOV DWORD PTR SS:[EBP+8],EDI
00478E1D  XOR EBX,EBX
00478E1F  MOV DWORD PTR SS:[EBP-8],EBX
00478E22  MOV ECX,DWORD PTR DS:[EDI]
00478E24  PUSH EDI
00478E25  CALL DWORD PTR DS:[ECX+4]
00478E28  MOV DWORD PTR SS:[EBP-20],EBX
00478E2B  MOV DWORD PTR SS:[EBP-30],EBX
00478E2E  MOV DWORD PTR SS:[EBP-34],EBX
00478E31  MOV DWORD PTR SS:[EBP-38],EBX
00478E34  MOV DWORD PTR SS:[EBP-40],EBX
00478E37  MOV DWORD PTR SS:[EBP-44],EBX
00478E3A  MOV DWORD PTR SS:[EBP-48],EBX
00478E3D  MOV DWORD PTR SS:[EBP-4C],EBX
00478E40  MOV DWORD PTR SS:[EBP-50],EBX
00478E43  MOV DWORD PTR SS:[EBP-54],EBX
00478E46  MOV DWORD PTR SS:[EBP-58],EBX
00478E49  MOV DWORD PTR SS:[EBP-5C],EBX
00478E4C  MOV DWORD PTR SS:[EBP-60],EBX
00478E4F  MOV DWORD PTR SS:[EBP-64],EBX
00478E52  MOV DWORD PTR SS:[EBP-68],EBX
00478E55  MOV DWORD PTR SS:[EBP-6C],EBX
00478E58  MOV DWORD PTR SS:[EBP-70],EBX
00478E5B  MOV DWORD PTR SS:[EBP-80],EBX
00478E5E  MOV DWORD PTR SS:[EBP-90],EBX
00478E64  MOV DWORD PTR SS:[EBP-A0],EBX
00478E6A  MOV DWORD PTR SS:[EBP-B0],EBX
00478E70  MOV DWORD PTR SS:[EBP-C0],EBX
00478E76  MOV DWORD PTR SS:[EBP-D0],EBX
00478E7C  MOV DWORD PTR SS:[EBP-F4],EBX
00478E82  MOV DWORD PTR SS:[EBP-F8],EBX
00478E88  PUSH 1
00478E8A  CALL DWORD PTR DS:[4010D4]                            ;  MSVBVM60.__vbaOnError
00478E90  MOV EDX,DWORD PTR DS:[EDI]
00478E92  PUSH EDI
00478E93  CALL DWORD PTR DS:[EDX+314]        // 獲得註冊Form上註冊碼Edit控制元件的物件指標
00478E99  PUSH EAX
00478E9A  LEA EAX,DWORD PTR SS:[EBP-68]
00478E9D  PUSH EAX
00478E9E  CALL DWORD PTR DS:[4010D0]                            ;  MSVBVM60.__vbaObjSet
00478EA4  MOV ESI,EAX
00478EA6  MOV ECX,DWORD PTR DS:[ESI]
00478EA8  LEA EDX,DWORD PTR SS:[EBP-40]
00478EAB  PUSH EDX
00478EAC  PUSH ESI
00478EAD  CALL DWORD PTR DS:[ECX+A0]
00478EB3  FCLEX
00478EB5  CMP EAX,EBX
00478EB7  JGE SHORT JgClockX.00478ECB
00478EB9  PUSH 0A0
00478EBE  PUSH JgClockX.004124C0
00478EC3  PUSH ESI
00478EC4  PUSH EAX
00478EC5  CALL DWORD PTR DS:[4010A4]                            ;  MSVBVM60.__vbaHresultCheckObj
00478ECB  MOV EDX,DWORD PTR SS:[EBP-40]
00478ECE  MOV DWORD PTR SS:[EBP-40],EBX
00478ED1  LEA ECX,DWORD PTR SS:[EBP-38]
00478ED4  MOV ESI,DWORD PTR DS:[4012C8]                        ;  MSVBVM60.__vbaStrMove
00478EDA  CALL ESI
00478EDC  LEA ECX,DWORD PTR SS:[EBP-68]
00478EDF  CALL DWORD PTR DS:[40130C]                            ;  MSVBVM60.__vbaFreeObj
00478EE5  MOV EAX,DWORD PTR SS:[EBP-38]
00478EE8  PUSH EAX
00478EE9  PUSH JgClockX.00412344
00478EEE  CALL DWORD PTR DS:[401148]                            ;  MSVBVM60.__vbaStrCmp
00478EF4  TEST EAX,EAX
00478EF6  JNZ JgClockX.00478FAC
00478EFC  MOV ECX,80020004
00478F01  MOV DWORD PTR SS:[EBP-A8],ECX
00478F07  MOV EAX,0A
00478F0C  MOV DWORD PTR SS:[EBP-B0],EAX
00478F12  MOV DWORD PTR SS:[EBP-98],ECX
00478F18  MOV DWORD PTR SS:[EBP-A0],EAX
00478F1E  MOV DWORD PTR SS:[EBP-C8],JgClockX.00415A28
00478F28  MOV EDI,8
00478F2D  MOV DWORD PTR SS:[EBP-D0],EDI
00478F33  LEA EDX,DWORD PTR SS:[EBP-D0]
00478F39  LEA ECX,DWORD PTR SS:[EBP-90]
00478F3F  MOV ESI,DWORD PTR DS:[401290]                        ;  MSVBVM60.__vbaVarDup
00478F45  CALL ESI
00478F47  MOV DWORD PTR SS:[EBP-B8],JgClockX.00415A10
00478F51  MOV DWORD PTR SS:[EBP-C0],EDI
00478F57  LEA EDX,DWORD PTR SS:[EBP-C0]
00478F5D  LEA ECX,DWORD PTR SS:[EBP-80]
00478F60  CALL ESI
00478F62  LEA ECX,DWORD PTR SS:[EBP-B0]
00478F68  PUSH ECX
00478F69  LEA EDX,DWORD PTR SS:[EBP-A0]
00478F6F  PUSH EDX
00478F70  LEA EAX,DWORD PTR SS:[EBP-90]
00478F76  PUSH EAX
00478F77  PUSH 40
00478F79  LEA ECX,DWORD PTR SS:[EBP-80]
00478F7C  PUSH ECX
00478F7D  CALL DWORD PTR DS:[4010D8]                            ;  MSVBVM60.rtcMsgBox
00478F83  LEA EDX,DWORD PTR SS:[EBP-B0]        // <--- 返回到這裡

我們知道程式用CALL DWORD PTR DS:[EDX+314]指令來獲得註冊Form上註冊碼Edit控制元件的物件指標。在ollydbg中用ctrl-f
查詢ALL DWORD PTR DS:[EDX+314],如果附近有call dword ptr [ecx+0000008C]類似的指令應該就是註冊碼edit控制元件的
KeyDown事件的程式碼。幸運的是,果然找到了。

註冊對話方塊Form的KeyDown事件處理函式:
Private Sub object_KeyDown([index As Integer,]keycode As Integer, shift As Integer)
shift 是在該事件發生時響應 SHIFT ,CTRL 和 ALT 鍵的狀態的一個整數。shift、CTRL、ALT 鍵在這些位分別對應於值 1、2 和 4。

0047A110  PUSH EBP
0047A111  MOV EBP,ESP
0047A113  SUB ESP,14
0047A116  PUSH JgClockX.00402996                            ; JMP to MSVBVM60.__vbaExceptHandler
0047A11B  MOV EAX,DWORD PTR FS:[0]
0047A121  PUSH EAX
0047A122  MOV DWORD PTR FS:[0],ESP
0047A129  SUB ESP,148
0047A12F  PUSH EBX
0047A130  PUSH ESI
0047A131  PUSH EDI
0047A132  MOV DWORD PTR SS:[EBP-14],ESP
0047A135  MOV DWORD PTR SS:[EBP-10],JgClockX.00402090
0047A13C  MOV ESI,DWORD PTR SS:[EBP+8]
0047A13F  MOV EAX,ESI
0047A141  AND EAX,1
0047A144  MOV DWORD PTR SS:[EBP-C],EAX
0047A147  AND ESI,FFFFFFFE
0047A14A  MOV DWORD PTR SS:[EBP+8],ESI
0047A14D  XOR EDI,EDI
0047A14F  MOV DWORD PTR SS:[EBP-8],EDI
0047A152  MOV ECX,DWORD PTR DS:[ESI]
0047A154  PUSH ESI
0047A155  CALL DWORD PTR DS:[ECX+4]
0047A158  MOV DWORD PTR SS:[EBP-2C],EDI
0047A15B  MOV DWORD PTR SS:[EBP-3C],EDI
0047A15E  MOV DWORD PTR SS:[EBP-4C],EDI
0047A161  MOV DWORD PTR SS:[EBP-5C],EDI
0047A164  MOV DWORD PTR SS:[EBP-60],EDI
0047A167  MOV DWORD PTR SS:[EBP-64],EDI
0047A16A  MOV DWORD PTR SS:[EBP-68],EDI
0047A16D  MOV DWORD PTR SS:[EBP-6C],EDI
0047A170  MOV DWORD PTR SS:[EBP-70],EDI
0047A173  MOV DWORD PTR SS:[EBP-80],EDI
0047A176  MOV DWORD PTR SS:[EBP-90],EDI
0047A17C  MOV DWORD PTR SS:[EBP-A0],EDI
0047A182  MOV DWORD PTR SS:[EBP-B0],EDI
0047A188  MOV DWORD PTR SS:[EBP-C0],EDI
0047A18E  MOV DWORD PTR SS:[EBP-D0],EDI
0047A194  MOV DWORD PTR SS:[EBP-E0],EDI
0047A19A  MOV DWORD PTR SS:[EBP-F0],EDI
0047A1A0  MOV DWORD PTR SS:[EBP-100],EDI
0047A1A6  MOV DWORD PTR SS:[EBP-110],EDI
0047A1AC  MOV DWORD PTR SS:[EBP-120],EDI
0047A1B2  MOV DWORD PTR SS:[EBP-144],EDI
0047A1B8  PUSH 1
0047A1BA  CALL DWORD PTR DS:[4010D4]                        ; MSVBVM60.__vbaOnError

0047A1C0  MOV EBX,DWORD PTR SS:[EBP+10]                ; 引數:shift
0047A1C3  TEST BYTE PTR DS:[EBX],1                ; Shift鍵按下?
0047A1C6  MOV EDX,EDI
0047A1C8  SETG DL
0047A1CB  NEG EDX
0047A1CD  MOV WORD PTR SS:[EBP-F8],DX
0047A1D4  MOV DWORD PTR SS:[EBP-100],0B
0047A1DE  LEA EDX,DWORD PTR SS:[EBP-100]
0047A1E4  LEA ECX,DWORD PTR SS:[EBP-5C]                ; Shift鍵標誌
0047A1E7  CALL DWORD PTR DS:[401020]                        ; MSVBVM60.__vbaVarMove

0047A1ED  TEST BYTE PTR DS:[EBX],4                ; Alt鍵按下?
0047A1F0  MOV EAX,EDI
0047A1F2  SETG AL
0047A1F5  NEG EAX
0047A1F7  MOV WORD PTR SS:[EBP-F8],AX
0047A1FE  MOV DWORD PTR SS:[EBP-100],0B
0047A208  LEA EDX,DWORD PTR SS:[EBP-100]
0047A20E  LEA ECX,DWORD PTR SS:[EBP-2C]                ; Alt標誌
0047A211  CALL DWORD PTR DS:[401020]                        ; MSVBVM60.__vbaVarMove

0047A217  TEST BYTE PTR DS:[EBX],2                ; Ctrl鍵按下?
0047A21A  MOV ECX,EDI
0047A21C  SETG CL
0047A21F  NEG ECX
0047A221  MOV WORD PTR SS:[EBP-F8],CX
0047A228  MOV DWORD PTR SS:[EBP-100],0B
0047A232  LEA EDX,DWORD PTR SS:[EBP-100]
0047A238  LEA ECX,DWORD PTR SS:[EBP-4C]                ; Ctrl鍵標誌
0047A23B  CALL DWORD PTR DS:[401020]                        ; MSVBVM60.__vbaVarMove

0047A241  MOV EDX,DWORD PTR SS:[EBP+C]                ; 引數: Keycode
0047A244  CMP WORD PTR DS:[EDX],4B                ; 按下了"K"鍵?
0047A248  JNZ JgClockX.0047A5B4

0047A24E  LEA EAX,DWORD PTR SS:[EBP-4C]                ; Ctrl
0047A251  PUSH EAX
0047A252  LEA ECX,DWORD PTR SS:[EBP-2C]                ; Alt
0047A255  PUSH ECX
0047A256  LEA EDX,DWORD PTR SS:[EBP-80]
0047A259  PUSH EDX
0047A25A  MOV EBX,DWORD PTR DS:[4011A8]                    ; MSVBVM60.__vbaVarAnd
0047A260  CALL EBX
0047A262  PUSH EAX
0047A263  LEA EAX,DWORD PTR SS:[EBP-5C]                ; Shift
0047A266  PUSH EAX
0047A267  LEA ECX,DWORD PTR SS:[EBP-90]
0047A26D  PUSH ECX
0047A26E  CALL EBX
0047A270  PUSH EAX
0047A271  CALL DWORD PTR DS:[40110C]                        ; MSVBVM60.__vbaBoolVarNull
0047A277  TEST AX,AX
0047A27A  JE JgClockX.0047A5B4

0047A280  MOV EDX,DWORD PTR DS:[ESI]
0047A282  PUSH ESI
0047A283  CALL DWORD PTR DS:[EDX+314]        // 這裡!
0047A289  PUSH EAX
0047A28A  LEA EAX,DWORD PTR SS:[EBP-6C]
0047A28D  PUSH EAX
0047A28E  CALL DWORD PTR DS:[4010D0]                        ; MSVBVM60.__vbaObjSet
0047A294  MOV EBX,EAX
0047A296  MOV ECX,DWORD PTR DS:[EBX]

      如果同時按下了Ctrl-shift-alt+K鍵,則註冊碼輸入控制元件開放。

      註冊碼edit控制元件的Enabled屬性設為TRUE,允許輸入註冊碼
     
0047A298  PUSH -1                        ; VB中TRUE的值為-1
0047A29A  PUSH EBX
0047A29B  CALL DWORD PTR DS:[ECX+8C]        // 這裡!  ; Enabled屬性的Property Let procedure
0047A2A1  FCLEX
0047A2A3  CMP EAX,EDI
0047A2A5  JGE SHORT JgClockX.0047A2B9

知道了如何輸入註冊碼,下面的破解就比較容易了。隨便填入註冊碼,一步一步跟蹤就可以了。
經過跟蹤,發現註冊碼的長度和機器碼的長度相同。程式使用了明碼比較。

00479671  MOV EDX,DWORD PTR SS:[EBP-4C]        // 註冊碼
00479674  PUSH EDX
00479675  MOV EAX,DWORD PTR SS:[EBP-48]        // 正確註冊碼!
00479678  PUSH EAX
00479679  CALL DWORD PTR DS:[401148]                      ; MSVBVM60.__vbaStrCmp // 關鍵的比較!

試圖用keymaker做記憶體序號產生器,結果失敗。可能跟加殼有關。哪位大俠有興趣作個記憶體序號產生器。

另外程式的安裝日期和輸入的註冊碼存放在windows系統目錄下的homepage.inf檔案中。

相關文章