软件名称:
powerarchiver 8.00.58
软件简介: 超强的文件压缩解压缩工具,有点像WINZIP,但比WINZIP强大,支持更多的格式.
下载地址:
http://www.powerarchiver.com/
此文目的:
学习该软件的注册码生成方法
调试工具: ollydbg1.09中文版、W32dsm9.0中文版、language
调试平台: Windows
XP (哈哈,ollydbg真好,XP下也能调试了,想想吧,还有MP3)
过程:
1) 运行程序,按CTRL+HOME输入NAME和REGISTRATION CODE,程序弹出对话框:Incomplete or incorrect
information,关闭程序.
2) 使用 language 检测主程序“POWERARC.exe”,没有壳.
3)
用W32dasm反编译POWERARC.exe,然后查找字符串"Incomplete or incorrect information"
双击找到的字符串,来到以下地方:
走到005E5E23时弹出出错对话框,于是向上看,发现005E5DBF有一个跳转,于是在005E5CC4处设断.
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:005E5D79(C),
:005E5D93(C), :005E5DA4(C)
|
:005E5DB2 8B55F8
mov edx, dword ptr [ebp-08]
<------输入的REGISTRATION CODE
:005E5DB5 8B45FC
mov eax, dword ptr [ebp-04]
<------输入的NAME
:005E5DB8 E807FFFFFF
call 005E5CC4
:005E5DBD 84C0
test al, al
:005E5DBF 0F859D000000
jne 005E5E62
:005E5DC5 FE050C93BD00
inc byte ptr [00BD930C]
:005E5DCB
A12C986800 mov eax, dword ptr
[0068982C]
:005E5DD0 8B55FC
mov edx, dword ptr [ebp-04]
:005E5DD3 E848EBE1FF
call 00404920
:005E5DD8 A1BC906800
mov eax, dword ptr [006890BC]
:005E5DDD
8B55F8 mov edx,
dword ptr [ebp-08]
:005E5DE0 E83BEBE1FF
call 00404920
:005E5DE5 A1FC906800
mov eax, dword ptr [006890FC]
:005E5DEA C60000
mov byte ptr [eax], 00
:005E5DED
A1DC926800 mov eax, dword ptr
[006892DC]
:005E5DF2 8B00
mov eax, dword ptr [eax]
:005E5DF4 8B8064060000
mov eax, dword ptr [eax+00000664]
:005E5DFA
B201 mov
dl, 01
:005E5DFC E8E3FDE4FF call
00435BE4
:005E5E01 A1DC926800 mov
eax, dword ptr [006892DC]
:005E5E06 8B00
mov eax, dword ptr [eax]
:005E5E08 8B8068060000
mov eax, dword ptr [eax+00000668]
:005E5E0E
B201 mov
dl, 01
:005E5E10 E8CFFDE4FF call
00435BE4
:005E5E15 668B0D545F5E00 mov cx,
word ptr [005E5F54]
:005E5E1C B201
mov dl, 01
*
Possible StringData Ref from Code Obj ->"Incomplete or incorrect information."
|
:005E5E1E B8605F5E00
mov eax, 005E5F60
:005E5E23 E878650500
call 0063C3A0
:005E5E28 A1AC916800
mov eax, dword ptr [006891AC]
:005E5E2D
833800 cmp dword
ptr [eax], 00000000
:005E5E30 7517
jne 005E5E49
:005E5E32 A1DC926800
mov eax, dword ptr [006892DC]
:005E5E37 8B00
mov eax,
dword ptr [eax]
:005E5E39 8B809C030000 mov
eax, dword ptr [eax+0000039C]
*
Possible StringData Ref from Code Obj ->"PowerArchiver 2002 v8.00 (Unregistered)"
|
:005E5E3F BA905F5E00
mov edx, 005E5F90
:005E5E44 E8B3FEE4FF
call 00435CFC
(略)
*
Possible StringData Ref from Code Obj ->"Registration accepted! Thank
you "
->"for
purchasing PowerArchiver."
|
:005E5EEC
B8C05F5E00 mov eax, 005E5FC0
:005E5EF1
E8AA640500 call 0063C3A0
:005E5EF6
A1AC916800 mov eax, dword ptr
[006891AC]
:005E5EFB 833800
cmp dword ptr [eax], 00000000
:005E5EFE 7517
jne 005E5F17
:005E5F00 A1DC926800
mov eax, dword ptr [006892DC]
:005E5F05
8B00 mov
eax, dword ptr [eax]
:005E5F07 8B809C030000
mov eax, dword ptr [eax+0000039C]
*
Possible StringData Ref from Code Obj ->"PowerArchiver 2002 v8.00"
|
:005E5F0D BA08605E00
mov edx, 005E6008
:005E5F12 E8E5FDE4FF
call 00435CFC
4)
使用ollydbg载入POWERARC.exe在005E5CC4处设置断点,F9运行程序,输入name and regcode 点OK中断于此
*
Referenced by a CALL at Address:
|:005E5DB8
|
:005E5CC4 55
push ebp
:005E5CC5
8BEC mov
ebp, esp
:005E5CC7 83C4F4
add esp, FFFFFFF4
:005E5CCA 53
push ebx
:005E5CCB 33C9
xor ecx, ecx
:005E5CCD
894DF4 mov dword
ptr [ebp-0C], ecx
:005E5CD0 8955F8
mov dword ptr [ebp-08], edx
:005E5CD3 8945FC
mov dword ptr [ebp-04], eax
:005E5CD6
8B45FC mov eax,
dword ptr [ebp-04]
:005E5CD9 E85AF0E1FF
call 00404D38
:005E5CDE 8B45F8
mov eax, dword ptr [ebp-08]
:005E5CE1 E852F0E1FF
call 00404D38
:005E5CE6 33C0
xor eax,
eax
:005E5CE8 55
push ebp
:005E5CE9 682D5D5E00
push 005E5D2D
:005E5CEE 64FF30
push dword ptr fs:[eax]
:005E5CF1 648920
mov dword ptr fs:[eax],
esp
:005E5CF4 8D55F4
lea edx, dword ptr [ebp-0C]
:005E5CF7 8B45FC
mov eax, dword ptr [ebp-04] <------输入的NAME
:005E5CFA
E8E5AB0800 call 006708E4
:005E5CFF
8B55F4 mov edx,
dword ptr [ebp-0C] <------正确的regcode
:005E5D02 8B45F8
mov eax, dword ptr [ebp-08]
<------输入的regcode
:005E5D05 E88AEFE1FF
call 00404C94
:005E5D0A 7504
jne 005E5D10
:005E5D0C B301
mov bl, 01
:005E5D0E
EB02 jmp
005E5D12
(略)
按F8一步步跟踪,在005E5CF7处发现输入的NAME,同时在005E5CFF发现正确的regcode,直觉告诉我005E5CFA的CALL是计算注册码的,于是跟入.
而且在005E5CFF发现一个经典对比:
:005E5CFF
8B55F4 mov edx,
dword ptr [ebp-0C]
:005E5D02 8B45F8
mov eax, dword ptr [ebp-08]
:005E5D05 E88AEFE1FF
call 00404C94
:005E5D0A 7504
jne 005E5D10
跟入005E5CFA来到此地:
*
Referenced by a CALL at Addresses:
|:005E5CFA , :0067681F
|
:006708E4
55 push
ebp
:006708E5 8BEC
mov ebp, esp
:006708E7 81C4CCFDFFFF
add esp, FFFFFDCC
:006708ED 53
push ebx
:006708EE 56
push esi
:006708EF
57 push
edi
:006708F0 33C9
xor ecx, ecx
:006708F2 898DD0FDFFFF
mov dword ptr [ebp+FFFFFDD0], ecx
:006708F8 898DCCFDFFFF
mov dword ptr [ebp+FFFFFDCC], ecx
:006708FE
898DDCFDFFFF mov dword ptr [ebp+FFFFFDDC],
ecx
:00670904 898DD8FDFFFF mov dword
ptr [ebp+FFFFFDD8], ecx
:0067090A 898DE0FDFFFF
mov dword ptr [ebp+FFFFFDE0], ecx
:00670910 894DF0
mov dword ptr [ebp-10], ecx
:00670913
8955F8 mov dword
ptr [ebp-08], edx
:00670916 8945FC
mov dword ptr [ebp-04], eax
:00670919 8B45FC
mov eax, dword ptr [ebp-04]
:0067091C
E81744D9FF call 00404D38
:00670921
33C0 xor
eax, eax
:00670923 55
push ebp
:00670924 68330B6700
push 00670B33
:00670929 64FF30
push dword ptr fs:[eax]
:0067092C 648920
mov dword ptr fs:[eax],
esp
* Referenced by
a (U)nconditional or (C)onditional Jump at Address:
|:006708BD(C)
|
*
Possible StringData Ref from Code Obj ->"IP-POWERARC"
|
:0067092F BE440B6700
mov esi, 00670B44
:00670934 8DBDECFEFFFF
lea edi, dword ptr [ebp+FFFFFEEC]
:0067093A A5
movsd
:0067093B
A5 movsd
:0067093C
A5 movsd
:0067093D
8D85ECFDFFFF lea eax, dword ptr [ebp+FFFFFDEC]
:00670943
8B55FC mov edx,
dword ptr [ebp-04]
:00670946 B9FF000000
mov ecx, 000000FF
:0067094B E81042D9FF
call 00404B60
:00670950 33C0
xor eax, eax
:00670952 8A85ECFEFFFF
mov al, byte ptr [ebp+FFFFFEEC]
:00670958
8945F4 mov dword
ptr [ebp-0C], eax
:0067095B 33FF
xor edi, edi
:0067095D BE03140000
mov esi, 00001403
<-----ESI=1403(H)=5123(O)
:00670962
8D45F0 lea eax,
dword ptr [ebp-10]
:00670965 50
push eax
:00670966 89B5E4FDFFFF
mov dword ptr [ebp+FFFFFDE4], esi
:0067096C C685E8FDFFFF00
mov byte ptr [ebp+FFFFFDE8], 00
:00670973
8D95E4FDFFFF lea edx, dword ptr [ebp+FFFFFDE4]
:00670979
33C9 xor
ecx, ecx
* Possible
StringData Ref from Code Obj ->"%1.2x"
|
:0067097B B8580B6700 mov
eax, 00670B58
:00670980 E89BBBD9FF
call 0040C520
:00670985 33C0
xor eax, eax
:00670987 8A85ECFDFFFF
mov al, byte ptr [ebp+FFFFFDEC]
:0067098D 85C0
test eax, eax
:0067098F
7E6B jle
006709FC
:00670991 8945EC
mov dword ptr [ebp-14], eax
:00670994 8D9DEDFDFFFF
lea ebx, dword ptr [ebp+FFFFFDED]
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:006709FA(C)
|
:0067099A
33C0 xor
eax, eax
:0067099C 8A03
mov al, byte ptr [ebx] <-----用户名依次ASC()入AL
:0067099E
03C6 add
eax, esi
<-----EAX=EAX+ESI
:006709A0 B9FF000000
mov ecx, 000000FF
<-----ECX=FF(H)=255(O)
:006709A5 99
cdq
:006709A6 F7F9
idiv ecx
<-----除法运算
:006709A8
8BF2 mov
esi, edx
<-----ESI=EAX MOD ECX (EAX除以ECX的余数入ESI)
:006709AA 3B7DF4
cmp edi, dword ptr [ebp-0C]
<-----检查是否超出"IP-POWERARC"的长度,保证程序取其中的字符
:006709AD 7D03
jge 006709B2
<-----大于等于就跳
:006709AF
47 inc
edi
<-----否则EDI=EDI+1
:006709B0 EB05
jmp 006709B7
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:006709AD(C)
|
:006709B2
BF01000000 mov edi, 00000001
<-----如果EDI超出"IP-POWERARC"的长度,则EDI=1
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:006709B0(U)
|
:006709B7
33C0 xor
eax, eax
:006709B9 8A843DECFEFFFF mov al,
byte ptr [ebp+edi-00000114] <----"IP-POWERARC"指定位置的字符依次ASC()入AL
:006709C0
33F0 xor
esi, eax
<---- ESI=ESI XOR EAX
:006709C2 8D85E0FDFFFF
lea eax, dword ptr [ebp+FFFFFDE0]
:006709C8
50 push
eax
:006709C9 89B5E4FDFFFF mov dword
ptr [ebp+FFFFFDE4], esi
:006709CF C685E8FDFFFF00
mov byte ptr [ebp+FFFFFDE8], 00
:006709D6 8D95E4FDFFFF
lea edx, dword ptr [ebp+FFFFFDE4]
:006709DC 33C9
xor ecx,
ecx
* Possible StringData
Ref from Code Obj ->"%1.2x"
|
:006709DE
B8580B6700 mov eax, 00670B58
:006709E3
E838BBD9FF call 0040C520
:006709E8
8B95E0FDFFFF mov edx, dword ptr [ebp+FFFFFDE0]
<---- EDX=ESI(ESI的值作为字符串付给EDX.可能这个功能,因
为我是汇编盲)
:006709EE
8D45F0 lea eax,
dword ptr [ebp-10]
:006709F1 E89641D9FF
call 00404B8C
:006709F6 43
inc ebx
:006709F7 FF4DEC
dec [ebp-14]
:006709FA 759E
jne 0067099A
<------下一循环
* Referenced
by a (U)nconditional or (C)onditional Jump at Address:
|:0067098F(C)
<----此处向下的程序功能是在字符串中取字符,因为我是汇编盲
|
具体方法也不是太清楚,只是靠猜的,好像是从最后开始向前
两个一组在下面这段字串中取字符,还请哪个大侠不吝赐教
:006709FC
8B45F0 mov eax,
dword ptr [ebp-10] <---NAME经处理后形成的字符串,也就是每次运算后的字符串联接起来
:006709FF E88041D9FF
call 00404B84
:00670A04 8BF0
mov esi,
eax
:00670A06 85F6
test esi, esi
:00670A08 7903
jns 00670A0D
:00670A0A 83C603
add esi, 00000003
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00670A08(C)
|
:00670A0D
C1FE02 sar esi,
02
:00670A10 C685ECFDFFFF00 mov byte ptr
[ebp+FFFFFDEC], 00
:00670A17 BB01000000
mov ebx, 00000001
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00670AE1(C)
|
:00670A1C
8D85DCFDFFFF lea eax, dword ptr [ebp+FFFFFDDC]
:00670A22
8D95ECFDFFFF lea edx, dword ptr [ebp+FFFFFDEC]
:00670A28
E8FB40D9FF call 00404B28
:00670A2D
8D85DCFDFFFF lea eax, dword ptr [ebp+FFFFFDDC]
:00670A33
50 push
eax
:00670A34 8D85D4FDFFFF lea eax,
dword ptr [ebp+FFFFFDD4]
:00670A3A 8BFB
mov edi, ebx
:00670A3C 0FAFFE
imul edi, esi
:00670A3F 8B55F0
mov edx, dword ptr
[ebp-10]
:00670A42 8A543AFF
mov dl, byte ptr [edx+edi-01]
:00670A46 885001
mov byte ptr [eax+01], dl
:00670A49 C60001
mov byte ptr [eax],
01
:00670A4C 8D95D4FDFFFF lea edx,
dword ptr [ebp+FFFFFDD4]
:00670A52 8D85D8FDFFFF
lea eax, dword ptr [ebp+FFFFFDD8]
:00670A58 E8CB40D9FF
call 00404B28
:00670A5D 8B95D8FDFFFF
mov edx, dword ptr [ebp+FFFFFDD8]
:00670A63
58 pop
eax
:00670A64 E82341D9FF call
00404B8C
:00670A69 8B95DCFDFFFF mov
edx, dword ptr [ebp+FFFFFDDC]
:00670A6F 8D85ECFDFFFF
lea eax, dword ptr [ebp+FFFFFDEC]
:00670A75 B9FF000000
mov ecx, 000000FF
:00670A7A E8E140D9FF
call 00404B60
:00670A7F 8D85D0FDFFFF
lea eax, dword ptr [ebp+FFFFFDD0]
:00670A85
8D95ECFDFFFF lea edx, dword ptr [ebp+FFFFFDEC]
:00670A8B
E89840D9FF call 00404B28
:00670A90
8D85D0FDFFFF lea eax, dword ptr [ebp+FFFFFDD0]
:00670A96
50 push
eax
:00670A97 8D85D4FDFFFF lea eax,
dword ptr [ebp+FFFFFDD4]
:00670A9D 8B55F0
mov edx, dword ptr [ebp-10]
:00670AA0 8A543AFE
mov dl, byte ptr [edx+edi-02]
:00670AA4
885001 mov byte
ptr [eax+01], dl
:00670AA7 C60001
mov byte ptr [eax], 01
:00670AAA 8D95D4FDFFFF
lea edx, dword ptr [ebp+FFFFFDD4]
:00670AB0 8D85CCFDFFFF
lea eax, dword ptr [ebp+FFFFFDCC]
:00670AB6
E86D40D9FF call 00404B28
:00670ABB
8B95CCFDFFFF mov edx, dword ptr [ebp+FFFFFDCC]
:00670AC1
58 pop
eax
:00670AC2 E8C540D9FF call
00404B8C
:00670AC7 8B95D0FDFFFF mov
edx, dword ptr [ebp+FFFFFDD0]
:00670ACD 8D85ECFDFFFF
lea eax, dword ptr [ebp+FFFFFDEC]
:00670AD3 B9FF000000
mov ecx, 000000FF
:00670AD8 E88340D9FF
call 00404B60
:00670ADD 43
inc ebx
:00670ADE 83FB05
cmp ebx, 00000005
:00670AE1 0F8535FFFFFF
jne 00670A1C
<-----此处与00670A1C之间的代码不是太清楚望各位大侠指教
:00670AE7 8B45F8
mov eax, dword ptr [ebp-08]
:00670AEA
8D95ECFDFFFF lea edx, dword ptr [ebp+FFFFFDEC]
<-----此处可见正确的注册码
:00670AF0 E83340D9FF
call 00404B28
:00670AF5 33C0
xor eax, eax
:00670AF7 5A
pop edx
:00670AF8
59 pop
ecx
:00670AF9 59
pop ecx
:00670AFA 648910
mov dword ptr fs:[eax], edx
:00670AFD 683A0B6700
push 00670B3A
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00670B38(U)
|
:00670B02
8D85CCFDFFFF lea eax, dword ptr [ebp+FFFFFDCC]
:00670B08
BA02000000 mov edx, 00000002
:00670B0D
E8DE3DD9FF call 004048F0
:00670B12
8D85D8FDFFFF lea eax, dword ptr [ebp+FFFFFDD8]
:00670B18
BA03000000 mov edx, 00000003
:00670B1D
E8CE3DD9FF call 004048F0
:00670B22
8D45F0 lea eax,
dword ptr [ebp-10]
:00670B25 E8A23DD9FF
call 004048CC
:00670B2A 8D45FC
lea eax, dword ptr [ebp-04]
:00670B2D E89A3DD9FF
call 004048CC
:00670B32 C3
ret
说了这么多真是累死了,看来得好好学一下汇编了.还是用粗通的VB来还原这个过程吧,希望大家能看懂
Sub
Main()
On Error Resume Next
Dim yourname As
String, initstr As String, esi As Long
Dim tmp As String, i As
Integer, temp As String
Dim sn As String
yourname
= Trim(InputBox("请输入注册名,名字太短可能会有错误的结果."+chr(13)+chr(10)+"因为对字符串的筛选方法是猜的"))
yourname = StrConv(yourname, 128) '因为是VB所以要解决UNICODE问题
If LenB(yourname) = 0 Then End
initstr = "IP-POWERARC"
Do Until LenB(yourname) \ Len(initstr) = 0 '保证initstr的长度大于等于yourname的长度以便计算
initstr = initstr + "IP-POWERARC"
DoEvents
Loop
esi = &H1403
'esi的初值
tmp = Hex(esi)
For i = 1 To LenB(yourname)
esi = (AscB(MidB(yourname,
i, 1)) + esi) Mod &HFF Xor Asc(Mid(initstr, i, 1))
'每一位依次ASC()后加ESI,然后对255取模,最后与程序内置的一段字符串"IP-POWERARC"的相应位
'的ASC进行异或
If esi < 16 Then
'在小于16(也就是小于等于&hF)的数前加"0"
temp = "0" + Hex(esi)
Else
temp = Hex(esi)
End If
tmp = tmp + temp
Next i
'tmp为程序生成的一串字符,至此应该都是正确的,下面可不敢保证.因为我是汇编盲,以下取注册码的过程是猜的.
'程序从最后两位开始,在tmp中平均取8位注册码
For i = Len(tmp) To 1 Step
-(Len(tmp) \ 4)
sn = Mid(tmp, i, 1) + Mid(tmp,
i - 1, 1) + sn
Next i
If Len(sn) > 8 Then
sn = Left(sn,
MsgBox "Your sn is: " + sn, 64, "大概吧!祝好运!"
End
End Sub