程序中文名:闪电ASP
程序英文名: Flash ASP
版
本:1.5
完成 日期:2001年9月21日
作 者:党峰
电子
邮件:my007@netease.com
作者 主页:wn.126.com
软件 性质:共享软件
此文
目的: 学习该软件的注册码生成方法
调试 工具: ollydbg1.09中文版、language、DEDE2.5汉化版(看见方块字的感觉真好-_-)
调试
平台: Windows XP (哈哈,ollydbg真好,XP下也能调试了,想想吧,还有MP3)
功能 简介:
闪电ASP(Flash ASP)是国内第一款中文ASP网页制作工具,具有使用简单,容
易上手的特点。并具有分色显示功能,可区分网页显示部分,脚本代码部分。配合
“闪电工具栏”可实现插入Vb,Java脚本的制作,使您的网页更具有“动态”效果。
开放的“闪电工具”也可由您自由定制自己的网页风格,定义各类网页模板。大大的
节省制作时间,提高工作效率。未注册版本只能使用本软件所缺省的“闪电工具库”,
而不能重新加入用户自定义的工具库(如自定义的“SQL”、“JAVA脚本”“本企业
工具库”等)。也将不能获得今后本软件“闪电工具库”升级时所新增加的新数据内
容!但您仍可继续使用本软件,并没有时间限制和其它功能限制。
※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
过程:
1) 使用 language 检测主程序“FlashASP.exe”,没有壳.(作者真是仁慈到家了;-))
2) 因为 language
检测出程序是 Delphi 编的,所出请出它的克星 DEDE 反之.完成后
切换到窗体(forms),发现有模块名(Class
Name):Tfrmzc,点击之在右边又发现有:
object OKBtn: TButton
Left
= 55
Top = 84
Width = 75
Height
= 25
Caption = '填写完成'
Default = True
TabOrder = 0
onClick = OKBtnClick
于是又切换到程序(Procedures),找到单元名(Unit
Name)下的"zc"点击之,然后双击
右边的事件(Events)下的OKBtnClick,来到以下地方:
0049DA90
55
push ebp
0049DA91 8BEC
mov ebp, esp
0049DA93 6A00
push $00
0049DA95
6A00 push
$00
0049DA97 53
push ebx
0049DA98 56
push esi
0049DA99
8BF0 mov
esi, eax
0049DA9B 33C0
xor eax, eax
0049DA9D 55
push ebp
0049DA9E
6857DB4900 push $0049DB57
*****
TRY
|
0049DAA3 64FF30
push dword ptr fs:[eax]
0049DAA6 648920
mov fs:[eax], esp
0049DAA9
8D55FC lea
edx, [ebp-$04]
*
Reference to control Tfrmzc.ed : TEdit
|
0049DAAC 8B86E0020000
mov eax, [esi+$02E0]
*
Reference to: controls.TControl.GetText(TControl):System.String;
|
0049DAB2
E86D40F9FF call 00431B24
<----"GetText" 取输入的字符
0049DAB7 8B45FC
mov eax, [ebp-$04]
0049DABA
50
push eax
0049DABB 8BC3
mov eax, ebx
|
0049DABD
E8D6FCFFFF call 0049D798
<----计算的CALL跟进
0049DAC2 52
push edx
0049DAC3 50
push
eax
0049DAC4 8D45F8
lea eax, [ebp-$08]
*
Reference to: sysutils.IntToStr(System.Int64):System.AnsiString;overload;
|
0049DAC7
E8ACB8F6FF call 00409378
<----"IntToStr"好像是数值转
换为字符没什么用,所以
跟进上面的 0049DABD
0049DACC
8B55F8 mov
edx, [ebp-$08] <----正确的SN
0049DACF 58
pop eax
<----你输入的SN
*
Reference to: system.@LStrCmp; <----- 好像明码比较的delphi程序都用这个
|
0049DAD0
E8FB66F6FF call 004041D0
<----正误两码的比较
0049DAD5 754A
jnz 0049DB21 <----不等就跳,关键跳转,跳到出错处
0049DAD7
B201 mov
dl, $01
*
Reference to class TLDreg
|
0049DAD9 A1B0D64900
mov eax, dword ptr [$49D6B0]
*
Reference to: system.TObject.Create(TObject;Boolean);
|
0049DADE
E8A555F6FF call 00403088
0049DAE3
8BD8 mov
ebx, eax
*
Reference to field TLDreg.OFFS_0004
|
0049DAE5 8D4304
lea eax, [ebx+$04]
*
Possible String Reference to: 'Software\Microsoft\Alworder\FTM'
|
0049DAE8
BA6CDB4900 mov
edx, $0049DB6C
* Reference
to: system.@LStrAsg;
|
0049DAED E8A263F6FF
call 00403E94
0049DAF2 8BC3
mov eax,
ebx
|
0049DAF4
E81FFCFFFF call 0049D718
0049DAF9
8BC3 mov
eax, ebx
*
Reference to: system.TObject.Free(TObject);
|
0049DAFB E8B855F6FF
call 004030B8
0049DB00
6A40 push
$40
* Possible
String Reference to: '注册'
|
0049DB02 B98CDB4900
mov ecx, $0049DB8C
*
Possible String Reference to: '注册成功,感谢您对"闪电 ASP "的支持?
|
? <---- MY GOD
|
0049DB07
BA94DB4900 mov edx, $0049DB94
*
Reference to TApplication instance
|
0049DB0C A154264B00
mov eax, dword ptr [$4B2654]
0049DB11
8B00 mov
eax, [eax]
* Reference to:
forms.TApplication.MessageBox(TApplication;System.PChar;System.PChar;System.Longint):Syste
m.Integer;
|
0049DB13
E8182DFBFF call 00450830
0049DB18
8BC6 mov
eax, esi
|
0049DB1A
E83DF3FAFF call 0044CE5C
0049DB1F
EB18 jmp
0049DB39
0049DB21 6A10
push $10
<---- 注册码不对就跳到这了
*
Possible String Reference to: '注册'
|
0049DB23 B98CDB4900
mov ecx, $0049DB8C
*
Possible String Reference to: '注册码错误,请重新填写!' <---- 玩完了
|
0049DB28
BABCDB4900 mov
edx, $0049DBBC
* Reference
to TApplication instance
|
0049DB2D A154264B00
mov eax, dword ptr [$4B2654]
0049DB32
8B00 mov
eax, [eax]
* Reference to:
forms.TApplication.MessageBox(TApplication;System.PChar;System.PChar;System.Longint):Syste
m.Integer;
|
0049DB34
E8F72CFBFF call 00450830
0049DB39
33C0 xor
eax, eax
0049DB3B 5A
pop edx
0049DB3C 59
pop
ecx
0049DB3D 59
pop ecx
0049DB3E 648910
mov fs:[eax], edx
******
FINALLY
|
0049DB41 685EDB4900
push $0049DB5E
0049DB46 8D45F8
lea eax, [ebp-$08]
*
Reference to: system.@LStrClr(String);
|
0049DB49 E8F262F6FF
call 00403E40
0049DB4E
8D45FC lea
eax, [ebp-$04]
*
Reference to: system.@LStrClr(String);
|
0049DB51 E8EA62F6FF
call 00403E40
0049DB56
C3
ret
0049DB57
E9BC5CF6FF jmp 00403818
0049DB5C
EBE8 jmp
0049DB46
******
END
|
0049DB5E 5E
pop esi
0049DB5F 5B
pop ebx
0049DB60
59
pop ecx
0049DB61 59
pop ecx
0049DB62 5D
pop
ebp
0049DB63 C3
ret
3)
跟进 0049DABD 来到以下地方:
0049D798 83C4F0
add esp, -$10
0049D79B B003
mov al,
$03
* Reference to:
sysutils.DiskSize(System.Byte):System.Int64;
|
0049D79D E89AC1F6FF
call 0040993C <-----"DiskSize"?不是眼花吧求磁盘空间?
0049D7A2
89442408 mov
[esp+$08], eax <----EAX=C盘容量,单位字节
0049D7A6 8954240C
mov [esp+$0C], edx
0049D7AA
6A00 push
$00
0049D7AC 6A02
push $02
<------ 2 入栈
0049D7AE DF6C2410
fild qword ptr [esp+$10]
0049D7B2
D835F8D74900 fdiv dword
ptr [$49D7F8] <----浮点除十进制数1024
EAX=EAX/1024得出以
KB表示的C盘容量
* Reference to: system.@ROUND;
|
0049D7B8
E8B753F6FF call 00402B74
<-----检查边界?????
|
0049D7BD E83696F6FF
call 00406DF8 <---此CALL的功能好像是EAX=EAX*先前那个2
进入0049D7BD来到:
00406DF8
52
push edx
00406DF9 50
push eax
00406DFA 8B442410
mov eax, [esp+$10]
00406DFE
F72424 mul
dword ptr [esp]
00406E01 8BC8
mov ecx, eax
00406E03 8B442404
mov eax, [esp+$04]
00406E07
F764240C mul
dword ptr [esp+$0C]
00406E0B 03C8
add ecx, eax
00406E0D 8B0424
mov eax,
[esp]
00406E10 F764240C
mul dword ptr [esp+$0C] <---- EAX=EAX*2
00406E14
03D1 add
edx, ecx
00406E16 59
pop ecx
00406E17 59
pop
ecx
00406E18 C208
ret $08
出来继续
0049D7C2
83C002 add
eax, +$02 <---- EAX=EAX+2 此处的EAX即为
在程序中的帮助菜单下的"获得注
册码"命令所得到的注册码
0049D7C5 83D200
adc edx, +$00
0049D7C8
89442408 mov
[esp+$08], eax
0049D7CC 8954240C
mov [esp+$0C], edx
0049D7D0 8B442408
mov eax, [esp+$08]
0049D7D4
8B54240C mov
edx, [esp+$0C]
0049D7D8 81F0853A0300
xor eax, $00033A85 <----- EAX=EAX XOR &H33A85
此时的EAX即为程序的注册码
0049D7DE 81F200000000
xor edx, $00000000
0049D7E4
890424 mov
[esp], eax
0049D7E7 89542404
mov [esp+$04], edx
0049D7EB 8B0424
mov eax, [esp]
0049D7EE
8B542404 mov
edx, [esp+$04]
0049D7F2 83C410
add esp, +$10
0049D7F5 C3
ret
<------返回0049DABD下一条指令
4)
至此全部分析结束,好像只要DEDE就能完成全部工作(有一个好工具会简化很多工作),可是我太
菜,还得依靠 ollydbg 才能分析出算法,唉菜呀.程序的算法大概是这样:
首先,取C盘空间,以字节为单位.
第二步,浮点运算将字节转化为千字节(KB)
第三步,浮点运算乘2
第四步,浮点运算加2,此时得到的结果就是程序提供的注册码.
第五步,将结果与&H33A85异或,此步为关键,其实程序真正的注册算法也就这一步.
下面给出VB的注册机:
Option
Explicit
Private Declare Function GetDiskFreeSpace Lib "kernel32"
Alias "GetDiskFreeSpaceA" (ByVal
lpRootPathName As String, lpSectorsPerCluster As Long, lpBytesPerSector As Long,
lpNumberOfFreeClusters
As Long, lpTotalNumberOfClusters As Long) As Long
Private Type 磁盘空间信息
lp簇扇区数
As Long
lp扇区字节数 As Long
lp剩余簇数 As Long
lp磁盘总簇数 As Long
End Type
Sub
main()
On Error GoTo errmsg
Dim DiskSpaceInfo
As 磁盘空间信息
Dim sn As Long, sn1 As Long
With DiskSpaceInfo
GetDiskFreeSpace "c:\", .lp簇扇区数, .lp扇区字节数,
.lp剩余簇数, .lp磁盘总簇数
sn1 = (.lp磁盘总簇数 / 1024 * .lp簇扇区数
* .lp扇区字节数) * 2 + 2 '为避免缢出只好
将除法运算提前,不知大家有没有更好的办法
End With
sn = sn1 Xor Val(&H33A85) '关键算法!!
MsgBox "闪电ASP生成的注册码为:" + CStr(sn1) + Chr(13) + Chr(10)
+ "正确的注册码为:
" + CStr(sn) + Chr(13) + Chr(10) + "希望与大家交流,我的E-MAIL是:" + Chr(13) +
Chr(10)
+ "yantuse.student@sina.com", 64, "作者涩郎恭喜你!"
Exit
Sub
errmsg:
MsgBox "程序因错误不能运行!", 16, "可惜!"
End
Sub