-------------------------------------------------------------------------------------
目标软件:极光多能闹钟
软件版本: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文件中。