(1)
该软件加了PEcompact壳,可以用风飘雪的脱壳机脱壳,然后就能看到它是用DELPHI编
写的。用W32dasm8反汇编。
试着运行软件,进行注册,先要让你填用户名和单位、地址,注意字数要够。然后点击生成
注册码文件。分析注册码文件,看到里面有一行字串:
userid=0310206410913919500818002711023914226309313612401220911328701503705316115
2071115115276163151041148019121215163174294049092008099084062121169134235004132
2550
点击注册,提示:没有有效的注册信息。在W32dasm反汇编的文件中搜索:“注册”
:0052C3AC E86F03F2FF call 0044C720
:0052C3B1 837DE800 cmp
dword ptr [ebp-18], 00000000
:0052C3B5 7522
jne 0052C3D9 //在这跳,为了更好的观
察,我先不让它强行跳,
看如何才能真正的跳。
:0052C3B7 6A10
push 00000010
* Possible StringData Ref from Code Obj ->"错误"
|
:0052C3B9 B9E4C45200 mov ecx,
0052C4E4
* Possible StringData Ref from Code Obj ->"文件中不存在有效的注册信息"
|
:0052C3BE BAECC45200 mov edx,
0052C4EC
:0052C3C3 A1F0285600 mov eax,
dword ptr [005628F0]
:0052C3C8 8B00
mov eax, dword ptr [eax]
:0052C3CA E8F909F4FF call 0046CDC8
//出现错误,看哪能跳过
:0052C3CF E8647FEDFF call 00404338
:0052C3D4 E9A6000000 jmp 0052C47F
? Referenced by a (U)nconditional or (C)onditional Jump at
Address:
》》》
》》》
在W32dasm反汇编的文件中搜索:“userid”,找到:
:0050B653 8D4598
lea eax, dword ptr [ebp-68]
:0050B656 50
push eax
* Possible StringData Ref from Code Obj ->"userid" //关键字
|
:0050B657 B9CCBB5000 mov ecx,
0050BBCC
* Possible StringData Ref from Code Obj ->"register" //关键字,所以在注册文件中写入一
行。
|
:0050B65C BAB8BB5000 mov edx,
0050BBB8
注册文件的内容设为:
userid=0310206410913919500818002711023914226309313612401220911328701503705316115
2071115115276163151041148019121215163174294049092008099084062121169134235004132
2550
register=67889898487684685674683228091890489843747578474732873877883684383738749
8739873987398574874987378436268374854759859875876985798748739473547598798798449
3759873(注:数字是乱填的)
这回上面的错误提示没有了,接着看:
由上面跳到这:
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0052C3B5(C)
|
:0052C3D9 33C0
xor eax, eax
:0052C3DB 5A
pop edx
:0052C3DC 59
pop ecx
:0052C3DD 59
pop ecx
:0052C3DE 648910
mov dword ptr fs:[eax], edx
:0052C3E1 68F8C35200 push 0052C3F8
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0052C3F6(U)
|
:0052C3E6 B201
mov dl, 01
:0052C3E8 8B45F8
mov eax, dword ptr [ebp-08]
:0052C3EB 8B08
mov ecx, dword ptr [eax]
:0052C3ED FF51FC
call [ecx-04]
:0052C3F0 C3
ret
:0052C3F1 E99A7DEDFF jmp 00404190
:0052C3F6 EBEE
jmp 0052C3E6
:0052C3F8 A1A4245600 mov eax,
dword ptr [005624A4]
:0052C3FD C60001
mov byte ptr [eax], 01
:0052C400 8D55E4
lea edx, dword ptr [ebp-1C]
:0052C403 8B45FC
mov eax, dword ptr [ebp-04]
:0052C406 8B8008030000 mov eax, dword
ptr [eax+00000308]
:0052C40C E80F03F2FF call 0044C720
:0052C411 8B4DE4
mov ecx, dword ptr [ebp-1C]
:0052C414 8B55F4
mov edx, dword ptr [ebp-0C]
:0052C417 B001
mov al, 01
:0052C419 E82202FEFF call 0050C640
//注册判断关键CALL
:0052C41E E86531FEFF call 0050F588
:0052C423 A124265600 mov eax,
dword ptr [00562624]
:0052C428 8B00
mov eax, dword ptr [eax]
:0052C42A E831D3EDFF call 00409760
:0052C42F E8901BFEFF call 0050DFC4
:0052C434 A1A4245600 mov eax,
dword ptr [005624A4]
:0052C439 803800
cmp byte ptr [eax], 00 //注意看EAX中的地址:
0056446C,下中断BPM
0056446C,重新跟踪。
:0052C43C 741A
je 0052C458 //关键跳转,直接改虽然可以看到
注册正确的提示,但不行。
:0052C43E 6A40
push 00000040
* Possible StringData Ref from Code Obj ->"提示"
|
:0052C440 B908C55200 mov ecx,
0052C508
* Possible StringData Ref from Code Obj ->"注册成功!感谢您的支持!"
|
:0052C445 BA10C55200 mov edx,
0052C510
:0052C44A A1F0285600 mov eax,
dword ptr [005628F0]
:0052C44F 8B00
mov eax, dword ptr [eax]
:0052C451 E87209F4FF call 0046CDC8
:0052C456 EB18
jmp 0052C470
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0052C43C(C)
|
:0052C458 6A10
push 00000010
* Possible StringData Ref from Code Obj ->"错误"
|
:0052C45A B9E4C45200 mov ecx,
0052C4E4
* Possible StringData Ref from Code Obj ->"注册失败,请与作者联系!"
|
:0052C45F BA2CC55200 mov edx,
0052C52C
:0052C464 A1F0285600 mov eax,
dword ptr [005628F0]
:0052C469 8B00
mov eax, dword ptr [eax]
:0052C46B E85809F4FF call 0046CDC8
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0052C456(U)
|
:0052C470 8B45FC
mov eax, dword ptr [ebp-04]
:0052C473 E824CFF3FF call 0046939C
:0052C478 C6054445560001 mov byte ptr [00564544],
01
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0052C32A(C), :0052C3D4(U)
|
:0052C47F 33C0
xor eax, eax
:0052C481 5A
pop edx
:0052C482 59
pop ecx
:0052C483 59
pop ecx
:0052C484 648910
mov dword ptr fs:[eax], edx
:0052C487 68B9C45200 push 0052C4B9
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0052C4B7(U)
|
:0052C48C 8D45E4
lea eax, dword ptr [ebp-1C]
:0052C48F BA02000000 mov edx,
00000002
:0052C494 E8D383EDFF call 0040486C
:0052C499 8D45EC
lea eax, dword ptr [ebp-14]
:0052C49C E8A783EDFF call 00404848
:0052C4A1 8D45F0
lea eax, dword ptr [ebp-10]
:0052C4A4 E89F83EDFF call 00404848
:0052C4A9 8D45F4
lea eax, dword ptr [ebp-0C]
:0052C4AC E89783EDFF call 00404848
:0052C4B1 C3
ret
0056446C是关键的判断注册与否的地址,但每次运行时软件要对它重新判断赋值。调用的
代码段和上面判断注册时是同一段。其关键CALL是上面的0052C419处的0050C640:
* Referenced by a CALL at Addresses:
|:0052C419 , :0052C60A , :0055E0A2
|
:0050C640 55
push ebp
:0050C641 8BEC
mov ebp, esp
。。。《略》 。。。
:0050C680 8945EC
mov dword ptr [ebp-14], eax
:0050C683 C645F300 mov
[ebp-0D], 00
:0050C687 C6056C44560000 mov byte ptr [0056446C],
00 //赋初始值
:0050C68E 8D45E0
lea eax, dword ptr [ebp-20]
* Possible StringData Ref from Code Obj ->"\wlm.dat"
|
:0050C691 B9FCCB5000 mov ecx,
0050CBFC
:0050C696 8B1570445600 mov edx, dword
ptr [00564470]
:0050C69C E8AB84EFFF call 00404B4C
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0050C62D(C)
|
:0050C6A1 8B45E0
mov eax, dword ptr [ebp-20]
* Possible StringData Ref from Code Obj ->"wlm"
|
:0050C6A4 BA10CC5000 mov edx,
0050CC10
:0050C6A9 E83E190000 call 0050DFEC
:0050C6AE B201
mov dl, 01
:0050C6B0 A144304700 mov eax,
dword ptr [00473044]
:0050C6B5 E88A6AF6FF call 00473144
:0050C6BA 8945E8
mov dword ptr [ebp-18], eax
:0050C6BD 807DFF00 cmp
byte ptr [ebp-01], 00
:0050C6C1 0F8552020000 jne 0050C919
:0050C6C7 BA02000080 mov edx,
80000002
:0050C6CC 8B45E8
mov eax, dword ptr [ebp-18]
:0050C6CF E8106BF6FF call 004731E4
:0050C6D4 B101
mov cl, 01
* Possible StringData Ref from Code Obj ->"Software\学生评语管理系统" //写入注册表
|
:0050C6D6 BA1CCC5000 mov edx,
0050CC1C
:0050C6DB 8B45E8
mov eax, dword ptr [ebp-18]
:0050C6DE E8656BF6FF call 00473248
:0050C6E3 84C0
test al, al
:0050C6E5 7413
je 0050C6FA
:0050C6E7 8B0D70445600 mov ecx, dword
ptr [00564470]
* Possible StringData Ref from Code Obj ->"installpath" //写入注册表
|
:0050C6ED BA40CC5000 mov edx,
0050CC40
:0050C6F2 8B45E8
mov eax, dword ptr [ebp-18]
:0050C6F5 E8EA6CF6FF call 004733E4
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0050C6E5(C)
|
:0050C6FA 8B45E8
mov eax, dword ptr [ebp-18]
:0050C6FD E8B26AF6FF call 004731B4
:0050C702 BA02000080 mov edx,
80000002
:0050C707 8B45E8
mov eax, dword ptr [ebp-18]
:0050C70A E8D56AF6FF call 004731E4
:0050C70F B101
mov cl, 01
* Possible StringData Ref from Code Obj ->"Software\Microsoft\Windows\CurrentVersion"
////写
入注册表中
的位置
|
:0050C711 BA54CC5000 mov edx,
0050CC54
:0050C716 8B45E8
mov eax, dword ptr [ebp-18]
:0050C719 E82A6BF6FF call 00473248
:0050C71E 84C0
test al, al
:0050C720 0F84E3010000 je 0050C909
* Possible StringData Ref from Code Obj ->"ProductWRemark" //注册表中关键性的键值,是
否注册,是否到使用次数等都决定于它,后面还会出现多处。
|
:0050C726 BA88CC5000 mov edx,
0050CC88
。。。《略》 。。。
:0050C74C 50
push eax
:0050C74D 8D4DD0
lea ecx, dword ptr [ebp-30]
* Possible StringData Ref from Code Obj ->"ProductWRemark"
|
:0050C750 BA88CC5000 mov edx,
0050CC88
。。。《略》 。。。
:0050C787 8D4DC4
lea ecx, dword ptr [ebp-3C]
* Possible StringData Ref from Code Obj ->"ProductWRemark"
|
:0050C78A BA88CC5000 mov edx,
0050CC88
。。。《略》 。。。
:0050C880 66BA97FF mov
dx, FF97
:0050C884 E88FD5FFFF call 00509E18
:0050C889 8B4DC0
mov ecx, dword ptr [ebp-40]
* Possible StringData Ref from Code Obj ->"ProductWRemark"
|
:0050C88C BA88CC5000 mov edx,
0050CC88
:0050C891 8B45E8
mov eax, dword ptr [ebp-18]
。。。《略》 。。。
:0050C8F4 E81FD5FFFF call 00509E18
:0050C8F9 8B4DB0
mov ecx, dword ptr [ebp-50]
* Possible StringData Ref from Code Obj ->"ProductWRemark"
|
:0050C8FC BA88CC5000 mov edx,
0050CC88
。。。《略》 。。。
:0050C92F E8B068F6FF call 004731E4
:0050C934 B101
mov cl, 01
* Possible StringData Ref from Code Obj ->"Software\Microsoft\Windows\CurrentVersion"
|
:0050C936 BA54CC5000 mov edx,
0050CC54
:0050C93B 8B45E8
mov eax, dword ptr [ebp-18]
:0050C93E E80569F6FF call 00473248
:0050C943 84C0
test al, al
:0050C945 0F84AF010000 je 0050CAFA
:0050C94B 8D45E4
lea eax, dword ptr [ebp-1C]
:0050C94E 8B55F4
mov edx, dword ptr [ebp-0C]
:0050C951 E88A7FEFFF call 004048E0
:0050C956 8D55A4
lea edx, dword ptr [ebp-5C]
:0050C959 8B45E4
mov eax, dword ptr [ebp-1C] //送入register值
:0050C95C E843CAEFFF call 004093A4
:0050C961 8B55A4
mov edx, dword ptr [ebp-5C]
:0050C964 8B45F8
mov eax, dword ptr [ebp-08] //送入usterid值
:0050C967 E8C8DDFFFF call 0050A734
//关键判断CALL,想知道算法
的话,就跟进去。我比较懒。
:0050C96C 84C0
test al, al
:0050C96E 0F8441010000 je 0050CAB5
//此处不让它跳就成功一半了!!
:0050C974 33C0
xor eax, eax
:0050C976 55
push ebp
:0050C977 68E9C95000 push 0050C9E9
:0050C97C 64FF30
push dword ptr fs:[eax]
:0050C97F 648920
mov dword ptr fs:[eax], esp
:0050C982 E8012C0000 call 0050F588
:0050C987 8D4598
lea eax, dword ptr [ebp-68]
:0050C98A B9C4CC5000 mov ecx,
0050CCC4
:0050C98F 8B1580445600 mov edx, dword
ptr [00564480]
:0050C995 E8B281EFFF call 00404B4C
:0050C99A 8B4598
mov eax, dword ptr [ebp-68]
:0050C99D 8D4D9C
lea ecx, dword ptr [ebp-64]
:0050C9A0 66BA14E2 mov
dx, E214
:0050C9A4 E86FD4FFFF call 00509E18
:0050C9A9 8B459C
mov eax, dword ptr [ebp-64]
:0050C9AC 8D4DA0
lea ecx, dword ptr [ebp-60]
:0050C9AF 66BA97FF mov
dx, FF97
:0050C9B3 E860D4FFFF call 00509E18
:0050C9B8 8B4DA0
mov ecx, dword ptr [ebp-60]
* Possible StringData Ref from Code Obj ->"ProductWRemark"
|
:0050C9BB BA88CC5000 mov edx,
0050CC88
:0050C9C0 8B45E8
mov eax, dword ptr [ebp-18]
:0050C9C3 E81C6AF6FF call 004733E4
:0050C9C8 C6056C44560001 mov byte ptr [0056446C],
01 //此处赋注册正确的
值。
:0050C9CF 8B45E8
mov eax, dword ptr [ebp-18]
:0050C9D2 E8DD67F6FF call 004731B4
:0050C9D7 8B45E8
mov eax, dword ptr [ebp-18]
:0050C9DA E81D70EFFF call 004039FC
:0050C9DF 33C0
xor eax, eax
:0050C9E1 5A
pop edx
:0050C9E2 59
pop ecx
:0050C9E3 59
pop ecx
:0050C9E4 648910
mov dword ptr fs:[eax], edx
:0050C9E7 EB0A
jmp 0050C9F3
:0050C9E9 E9EE74EFFF jmp 00403EDC
:0050C9EE E81579EFFF call 00404308
》》》 》》》
总结:在0050C96E处下断点,改跳转,就显示注册成功了,将注册表中值导出成注册文件。
REGEDIT4
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion]
"ProductWRemark"="BB21C32E08E9F15F750A"
注意:经过上面的修改并未破解成功,请看(2)。
(2)
大家好,上次的破解留了一个小尾巴,就是作者放了一个暗桩,导致程序运行三分钟之后自动退出。这回解决了这个问题,看下面:
:0050C961 8B55A4 mov edx, dword ptr [ebp-5C]
:0050C964 8B45F8 mov eax, dword ptr [ebp-08]
:0050C967 E8C8DDFFFF call 0050A734
:0050C96C 84C0 test al, al
:0050C96E 0F8441010000 je 0050CAB5 //上次告诉大家改这个跳转的。
:0050C974 33C0 xor eax, eax
:0050C976 55 push ebp
:0050C977 68E9C95000 push 0050C9E9
:0050C97C 64FF30 push dword ptr fs:[eax]
:0050C97F 648920 mov dword ptr fs:[eax], esp
:0050C982 E8012C0000 call 0050F588
:0050C987 8D4598 lea eax, dword ptr [ebp-68]
:0050C98A B9C4CC5000 mov ecx, 0050CCC4
:0050C98F 8B1580445600 mov edx, dword ptr [00564480]
:0050C995 E8B281EFFF call 00404B4C
:0050C99A 8B4598 mov eax, dword ptr [ebp-68]
:0050C99D 8D4D9C lea ecx, dword ptr [ebp-64]
:0050C9A0 66BA14E2 mov dx, E214
:0050C9A4 E86FD4FFFF call 00509E18
:0050C9A9 8B459C mov eax, dword ptr [ebp-64]
:0050C9AC 8D4DA0 lea ecx, dword ptr [ebp-60]
:0050C9AF 66BA97FF mov dx, FF97
:0050C9B3 E860D4FFFF call 00509E18
:0050C9B8 8B4DA0 mov ecx, dword ptr [ebp-60]
* Possible StringData Ref from Code Obj ->"ProductWRemark"
|
:0050C9BB BA88CC5000 mov edx, 0050CC88
:0050C9C0 8B45E8 mov eax, dword ptr [ebp-18]
:0050C9C3 E81C6AF6FF call 004733E4
:0050C9C8 C6056C44560001 mov byte ptr [0056446C], 01 //送注册成功标志,接着向下看
:0050C9CF 8B45E8 mov eax, dword ptr [ebp-18]
:0050C9D2 E8DD67F6FF call 004731B4
:0050C9D7 8B45E8 mov eax, dword ptr [ebp-18]
:0050C9DA E81D70EFFF call 004039FC
:0050C9DF 33C0 xor eax, eax
:0050C9E1 5A pop edx
:0050C9E2 59 pop ecx
:0050C9E3 59 pop ecx
:0050C9E4 648910 mov dword ptr fs:[eax], edx
:0050C9E7 EB0A jmp 0050C9F3
:0050C9E9 E9EE74EFFF jmp 00403EDC
:0050C9EE E81579EFFF call 00404308
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0050C9E7(U)
|
:0050C9F3 33C0 xor eax, eax
:0050C9F5 55 push ebp
* Possible StringData Ref from Code Obj ->"闉u? "
|
:0050C9F6 6865CA5000 push 0050CA65
:0050C9FB 64FF30 push dword ptr fs:[eax]
:0050C9FE 648920 mov dword ptr fs:[eax], esp
:0050CA01 8D4594 lea eax, dword ptr [ebp-6C]
* Possible StringData Ref from Code Obj ->"\wcgipk.dll" //要向这个文件中写东西,这个文件在哪?写的是什么?
ANSWER:原来注册成功后,他不但象上次我说的那样往注册表中写东西,也生成了一个KEY文件,就是wcgipk.dll喽!放在C:\WINDOWS\SYSTEM目录下。内容的形式是:
[register]
userid=510632020430861820451910210190621022870321460831522710451080891942471032811960840840312802670050940642890742350430050650
registerid=678898984876846856746832280918904898437475784747328738778836843837387498739873987398574874987378436268374854759859875876
可见这个文件是关键。下面对反汇编后的文件查找“wcgipk.dll”字串。
|
:0050CA04 B9D0CC5000 mov ecx, 0050CCD0 //送入文件名地址
:0050CA09 8B1574445600 mov edx, dword ptr [00564474]
:0050CA0F E83881EFFF call 00404B4C
:0050CA14 8B4D94 mov ecx, dword ptr [ebp-6C]
:0050CA17 B201 mov dl, 01
* Possible StringData Ref from Code Obj ->"?G"
|
:0050CA19 A1F4204700 mov eax, dword ptr [004720F4]
。。。 。。。
经过上面说的查找找到4个 相关地址:
0050B5AC 是暗桩的关键地址。
0050CA04 是注册成功后建立此文件,并向其中写入内容。
005117CC 是当我们点击了帮助菜单中的“关于”时,打开此文件从中转换出注册名和单位、地址信息。
0052C06A 不详,不过好象不是暗桩(大家可以帮忙测试一下)。
下面就到50B5AC处下断点(前提是你像我上一篇中说的,已注册成功),等待三分钟后,在断点处被拦下。接下来就是很长的一段注册判断,很麻烦的。好,下面看哪可以跳过判断:
:0050B56D 59 pop ecx
:0050B56E 648910 mov dword ptr fs:[eax], edx
:0050B571 EB16 jmp 0050B589
:0050B573 E96489EFFF jmp 00403EDC
:0050B578 A1F0285600 mov eax, dword ptr [005628F0]
:0050B57D 8B00 mov eax, dword ptr [eax]
:0050B57F E8A017F6FF call 0046CD24
:0050B584 E87F8DEFFF call 00404308
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0050B571(U)
|
:0050B589 837DF800 cmp dword ptr [ebp-08], 00000000
:0050B58D 0F8577050000 jne 0050BB0A //此处跳转就可以不判断了,我把50B589一句改为JMP 050BB0A,成功!!
:0050B593 33C0 xor eax, eax
:0050B595 55 push ebp
:0050B596 68D2BA5000 push 0050BAD2
:0050B59B 64FF30 push dword ptr fs:[eax]
:0050B59E 648920 mov dword ptr fs:[eax], esp
:0050B5A1 8B15BC285600 mov edx, dword ptr [005628BC]
:0050B5A7 8B12 mov edx, dword ptr [edx]
:0050B5A9 8D45C4 lea eax, dword ptr [ebp-3C]
* Possible StringData Ref from Code Obj ->"\wcgipk.dll"
|
:0050B5AC B990BB5000 mov ecx, 0050BB90
:0050B5B1 E89695EFFF call 00404B4C
:0050B5B6 8B4DC4 mov ecx, dword ptr [ebp-3C]
:0050B5B9 B201 mov dl, 01
* Possible StringData Ref from Code Obj ->"?G"
|
:0050B5BB A1F4204700 mov eax, dword ptr [004720F4]
:0050B5C0 E8DF6BF6FF call 004721A4
:0050B5C5 8945F0 mov dword ptr [ebp-10], eax
:0050B5C8 33C0 xor eax, eax
:0050B5CA 55 push ebp
:0050B5CB 68A3B65000 push 0050B6A3
:0050B5D0 64FF30 push dword ptr fs:[eax]
:0050B5D3 648920 mov dword ptr fs:[eax], esp
:0050B5D6 8B45E4 mov eax, dword ptr [ebp-1C]
调试中注意到的内幕:
此系统的数据文件是wlm.dat,它实际上是.mdb ACCESS型文件,文件的打开密码是:
“ooovvvwww”。可以看看他数据库的设计思想了。
:0050CB0F 648920 mov dword ptr fs:[eax], esp
* Possible StringData Ref from Code Obj ->"Provider=Microsoft.Jet.OLEDB.4.0;Data "
->"Source="
|
:0050CB12 6838CD5000 push 0050CD38
:0050CB17 FF3570445600 push dword ptr [00564470]
* Possible StringData Ref from Code Obj ->"\wlm.dat;Persist Security Info=False;Jet "
->"OLEDB:Database Password=ooovvvwww" //看到了吗?
|
:0050CB1D 6870CD5000 push 0050CD70
:0050CB22 8D4588 lea eax, dword ptr [ebp-78]
总结:
在调试中发现作者在注册问题上下了很大的功夫,关于注册的地方特别多,这样势必会影响整个程序的执行效率,这个软件是DELPHI写的,本应执行起来效率很高,其实不然。所以我想作者不应把精力过多的放在防破解上。