• 标 题:吾等菜鸟的福音 - 闪电ASP 1.5 
  • 作 者:涩郎
  • 时 间:2003/04/29 11:45pm 
  • 链 接:http://bbs.pediy.com

程序中文名:闪电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