知道这个论坛也将近一年了,经常来这里听各位的高论,受益匪浅,看了论坛精华2和3之后,禁不住手痒,也学着破软件,可功力浅,只好专捏“软柿子”了。(这是我第一次写破解,有言不达意之处,请多多包涵。^O^)
软件:股霸5.0
功能:通视卡用户接收东方上证信息工具,有通视卡的兄弟可以试试,可能我不会用,算出注册码注册成功后仍就接收不到股市信息(不过拿来练练手倒不错)。
下载地址:http://stockhot.my.west163.com/down/Gb50SHM.exe
软件保护:加壳,代码采用花指令法加密,使用了cih的技术(使TRW2000在某些地址不能中断),注册码在DLL文件中计算对比(注册码算法中使用了硬件信息)。
工具:TRW2000,WinHex9.5,caspr1.011(一个非常好的脱壳软件,我喜欢,感谢作者的不懈努力),fs2k55(也是一个很好的侦测加壳类型的软件),w32dasm8.93。
过程:
运行主程序sdlzc.exe后,输入注册码“787878787878787878”一共十六位,按现在注册按钮后,出现“对不起,注册失败!!!”注册错误消息窗口,至此,通常破解方法为设断bpx
MessageBoxA,然后采用逆推法,寻找能跳过CALL MessageBoxA的地方,这样可以尽快找到核心比较代码(大部分程序是这样的吧)。
用fs2k55侦测文件,发现有加壳,用caspr让它一丝不挂吧。
用w32dasm反汇编,寻找“对不起,注册失败!!!”的错误信息,Ok!,w32dasm总是不会让人失望,在0040129A地址找到了这个错误信息,好!,往上找,原来是从00401266跳来的,看来0040125F的call
00401822必有问题,追进去看看。
:00401249 817D0C11010000 cmp dword ptr [ebp+0C],
00000111
:00401250 0F8584000000 jne 004012DA
:00401256 817D10E8030000 cmp dword ptr [ebp+10],
000003E8
:0040125D 7550
jne 004012AF
:0040125F E8BE050000 call 00401822
:00401264 0BC0
or eax, eax *eax如果为0则死,不为0则注册成功。
:00401266 752A
jne 00401292
:00401268 6A00
push 00000000
:0040126A FF35FF684000 push dword ptr
[004068FF]
* Possible StringData Ref from Data Obj ->"恭喜您,注册成功!"
|
:00401270 68CD624000 push 004062CD
:00401275 FF358A644000 push dword ptr
[0040648A]
* Reference To: USER32.MessageBoxA, Ord:01BBh
|
:0040127B E8560D0000 Call 00401FD6
:00401280 6A00
push 00000000
:00401282 FF358A644000 push dword ptr
[0040648A]
* Possible StringData Ref from Data Obj ->"对不起,注册失败!!!"
|
:0040129A 68E0624000 push 004062E0
:0040129F FF358A644000 push dword ptr
[0040648A]
* Reference To: USER32.MessageBoxA, Ord:01BBh
|
:004012A5 E82C0D0000 Call 00401FD6
:004012AA E9B9000000 jmp 00401368
0040125F的call 00401822果然有问题,以下见代码中注解。
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040101E(U)
|
:00401822 55
push ebp
:00401823 8BEC
mov ebp, esp
:00401825 83C4F8
add esp, FFFFFFF8
:00401828 60
pushad
:00401829 B805000000 mov eax,
00000005
:0040182E 8945FC
mov dword ptr [ebp-04], eax
:00401831 6A1E
push 0000001E
:00401833 68A5624000 push 004062A5
:00401838 6A64
push 00000064
:0040183A FF358A644000 push dword ptr
[0040648A]
* Reference To: KERNEL32.lstrlenA, Ord:02E2h
|
:00401865 E890070000 Call 00401FFA
:0040186A 83F810
cmp eax, 00000010 *这里比较注册码长度,不等于16位则死
:0040186D 7516
jne 00401885
:0040186F 6857634000 push 00406357
:00401874 6853634000 push 00406353
:00401879 68A5624000 push 004062A5
* Reference To: sdldll.GetDateInKJMReg, Ord:000Ah
|
:0040187E E8430B0000 Call 004023C6
*按f10到这里后,再按f10则直接出现注册
:00401883 EB0C
jmp 00401891 *失败的错误信息,这里也有问题,追吧。
sdldll.dll也有加壳,直接用caspr脱。
Exported fn(): GetDateInKJMReg - Ord:000Bh
:10007FFA 55
push ebp
:10007FFB 8BEC
mov ebp, esp
:10007FFD 83C4F8
add esp, FFFFFFF8
:10008000 60
pushad
:10008001 8B7D08
mov edi, dword ptr [ebp+08]
:10008004 8D35BEF80010 lea esi, dword
ptr [1000F8BE]
:1000800A 56
push esi
:1000800B 57
push edi
:1000800C 6A09
push 00000009
:1000800E 57
push edi
:1000800F 68AAF80010 push 1000F8AA
* Reference To: KERNEL32.lstrcpynA, Ord:02DFh
|
:10008037 E806070000 Call 10008742
:1000803C 68AAF80010 push 1000F8AA
:10008041 E86E050000 call 100085B4
:10008046 5F
pop edi
:10008047 5E
pop esi
:10008048 8906
mov dword ptr [esi], eax
:1000804A 8D35BEF80010 lea esi, dword
ptr [1000F8BE]
:10008050 8B06
mov eax, dword ptr [esi]
:10008052 8945FC
mov dword ptr [ebp-04], eax
* Reference To: sdldll.GetJQZW
|
:10008055 E866FEFFFF call 10007EC0
*此call获得硬件信息
:1000805A 50
push eax
:1000805B FF1590F80010 call dword ptr
[1000F890] *此F(1)对EAX中硬件信息作复杂转换
:10008061 83C404
add esp, 00000004
:10008064 A38FF90010 mov dword
ptr [1000F98F], eax
:10008069 3345FC
xor eax, dword ptr [ebp-04] *[ebp-4]中为注册码前8位
:1000806C 50
push eax
:1000806D FF158CF80010 call dword ptr
[1000F88C] *此F(2)对EAX作复杂转换(看的头都:10008073 83C404
add esp, 00000004
*大了还是不明白算法)
:10008076 6652
push dx
:10008078 6650
push ax
:1000807A 58
pop eax *EAX为上call结果
:1000807B EB02
jmp 1000807F
:1000807D EA3360EB026967 jmp 6769:02EB6033
***这里以后采用了“花指令”法。***
:10008084 EB02
jmp 10008088
我倒,用trw2000追到1000807B后,按一下F8,代码变一变,再按几下F8,前后代码都不对了(挂在半空的滋味真不错,你也来尝尝。),原来作者用了“花指令”,经仔细分析后,祭出了winHex,修改后代码如下。
:1000807D 90
nop
:1000807E 90
nop
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1000807B(U)
|
:1000807F 60
pushad
:10008080 EB02
jmp 10008084
:10008082 90
nop
:10008083 90
nop
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10008080(U)
|
:10008084 EB02
jmp 10008088
这样看起来顺眼多了。
噫!追着追着怎么出现了......
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10008089(U)
|
:1000808D B903000000 mov ecx,
00000003
:10008092 8D05BB550010 lea eax, dword
ptr [100055BB] **这里为修改int 3入口作准备
:10008098 8B1D02A00010 mov ebx, dword
ptr [1000A002]
:1000809E EB02
jmp 100080A2
:100080A0 90
nop
:100080A1 90
nop
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1000809E(U)
|
:100080A2 8D1CCB
lea ebx, dword ptr [ebx+8*ecx]
:100080A5 668903
mov word ptr [ebx], ax **这里修改int 3入口
:100080A8 EB02
jmp 100080AC
:100080AA 90
nop
:100080AB 90
nop
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100080A8(U)
|
:100080AC C1E810
shr eax, 10
:100080AF EB02
jmp 100080B3
:100080B1 90
nop
:100080B2 90
nop
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100080AF(U)
|
:100080B3 66894306 mov
word ptr [ebx+06], ax
:100080B7 EB02
jmp 100080BB
:100080B9 90
nop
:100080BA 90
nop
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100080C0(U)
|
:100080C4 CC
int 03 **这里是cih病毒的技术,获得了0级特权,它想做什么
**呢??自己U 100055BB看看吧。
**这里F8、F10都死,只好在100055BB中作作手脚了。
继续追吧......
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10008111(U)
|
:10008115 BB34122989 mov ebx,
89291234
:1000811A 81E3FFFF0000 and ebx, 0000FFFF
:10008120 EB02
jmp 10008124
:10008122 90
nop
:10008123 90
nop
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10008120(U)
|
* Reference To: sdldll.NewKjmSuanFa
|
:10008124 E824D0FFFF call 1000514D
**关键,开机码(注册码前8位)算法,算法很简单
:10008129 EB02
jmp 1000812D **(大概为eax xor 1234h,eax xor 52071197,eax xor
**12345678)但不容易找到计算子程序,此子程序代替了
**int 1处理程序,trw2000没办法追。
来到了......
:100081C3 80FC09
cmp ah, 09 **eax为注册码前8位经计算后内容,看来此程序只允许
:100081C6 7704
ja 100081CC **用到2009年12月,程序中另有一处比较当前日期。
:100081C8 3C12
cmp al, 12
:100081CA 7606
jbe 100081D2
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100081C6(C)
|
:100081CC EB02
jmp 100081D0
:100081CE 90
nop
:100081CF 90
nop
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100081CC(U)
|
:100081D0 33C0
xor eax, eax **EAX为0则注册错误。
以下比较计算注册码后8位。
:10008271 8D35BEF80010 lea esi, dword
ptr [1000F8BE] *注册码前8位地址
:10008277 FC
cld
:10008278 AD
lodsd
:10008279 33058FF90010 xor eax, dword
ptr [1000F98F] *经转换后硬件信息地址
:1000827F 8945F8
mov dword ptr [ebp-08], eax
:10008282 AD
lodsd
:10008283 33058FF90010 xor eax, dword
ptr [1000F98F] *注册码后8位地址
:10008289 50
push eax
:1000828A FF158CF80010 call dword ptr
[1000F88C] *同前面:1000806D之F(2)
:10008290 83C404
add esp, 00000004
:10008293 6652
push dx
:10008295 6650
push ax
:10008297 58
pop eax *注册码后8位经转换后内容
:10008298 3345F8
xor eax, dword ptr [ebp-08]
:1000829B 66B90800 mov
cx, 0008
:1000829F 8BD8
mov ebx, eax
:100082A1 53
push ebx
:100082A2 83E30F
and ebx, 0000000F
:100082A5 83FB09
cmp ebx, 00000009
:100082A8 7602
jbe 100082AC
:100082AA 33C0
xor eax, eax *EAX为0注册失败,必须跳过。
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100082A8(C)
|
:100082AC 5B
pop ebx
:100082AD C1EB04
shr ebx, 04
:100082B0 E2EF
loop 100082A1
:100082B2 8B7510
mov esi, dword ptr [ebp+10]
:100082B5 8906
mov dword ptr [esi], eax
:100082B7 61
popad
:100082B8 C9
leave
:100082B9 C20C00
ret 000C
至此程序注册算法基本上已弄明白,有兴趣的朋友可写注册机了(函数F(1)和F(2)互逆)。
- 标 题:第一篇破文,请各位老大指教。 (11千字)
- 作 者:hyzhang001
- 时 间:2001-10-17 0:22:04
- 链 接:http://bbs.pediy.com