• 标 题: 豪*超级解*别V8+SP1版 怒而解之全过程(新手教程、高手莫入)
  • 作 者:vipchenji
  • 时 间:004-06-08,08:58
  • 链 接:http://bbs.pediy.com

[标题]  豪*超级解*别V8+SP1版 怒而解之全过程(新手教程、高手莫入)

[难度]  低

[软件简介] 《豪*超级解*V8》是豪*公司在2004年精心制作的解*系列的最新版本! 
1、多年专注的DVD纠错防读死技术。
2、全格式,全兼容--影碟机VCD,无文件VCD光盘格式支持。
3、新增支持格式MOV、SWF、VQF、DAC、MP3PRO。
4、数字家庭的播放选择-DV,DC,摄像头都可以支持播放及截图。

[软件来源] 网上下载

[破解工具] olldbg1.10 、Peid0.92、eXeScope 6.00。

[注意事项] 本文系个人经验所得,内部交流,不得用于商业用途,否则后果自负!切记,切记!

[作者] chenjiwl

  [email]chenjiwl@sina.com

     昨日为一好友装机,非要装超级解*。然手中无有此软件,上网查之,有最新版+SP1补丁的
安装包,下载安装后运行才知需注册方可。查注册码不得,脸面甚是无光,今日怒而解之。解后
心有所感,遂得此文。
     
     开工!

作战手册第一条:收集情报
    凡事预则立,不预则废。先运行软件,如果没有注册将会出现提示注册的窗口。关闭软件
打开软件安装目录,先找可执行文件:

Directory of D:\HEROSOFT\HeroV8

SYSEXPLR EXE        89,088  06-06-04  20:19 SysExplr.exe
STHSDVD  EXE       757,760  06-06-04  20:19 STHSDVD.exe
MOBILE~1 EXE        53,248  06-06-04  20:19 MobilePhoto.exe
WEBPHOTO EXE        53,248  06-06-04  20:19 WebPhoto.exe
JMVKT    EXE       102,400  06-06-04  20:19 JmvKT.exe
AUTHREG  EXE        61,496  06-06-04  20:19 AuthReg.exe   ---->就是这个了!
MMXADO   EXE       655,360  06-06-04  20:19 Mmxado.exe
REGEXPLR EXE        94,208  06-06-04  20:19 RegExplr.exe
UNINST32 EXE       150,528  06-06-04  20:19 UNINST32.exe

一眼就看出AuthReg.exe是注册程序,运行试之果然如此。由此基本上可以确定此软件注册成
功后,一定会在注册表或INI文件中留下记号!果然在软件目录中发现了AuthReg.Ini,一定要
打开看看了,查保存注册码的字段,没有发现。但是发现,这个文件保存了三种语言(英语、
简体中文、繁体中文)的提示信息,看来这个软件应该支持三种语言的界面。
——————————————————————————
[ABOUTINF]
APPICON=
VERSION=看到精彩你就发 
VERYEAR=1997-2004
//名册
//
SOFTNAME=Her* Sup*r Player V8         --->  英文
SOFTNAME936=豪杰超级解霸V8 SP1        --->  简体中文
SOFTNAME950=花狽禬秆臦V8            --->  繁体中文
      :
      :
      :
——————————————————————————
不知大家有没有注意三种语言之间的标志区别:
1、英文没有特殊标志---SOFTNAME
2、简体中文在名称后加了936----SOFTNAME936
3、繁体中文在名称后加了950----SOFTNAME950

此处放下,暂且不表!
-----------------------------------------------------

确定目标后,立刻用Peid查壳,结果大喜,无壳。
********************************************************
*  Peid查壳-------->Microsoft Visual C++ 6.0 [Debug]   *
********************************************************
而且可知此程序用VC编写,很好,很好!

================================================================
进一步分析,再用eXeScope将AuthReg.exe载入分析。

发现问题了,在程序资源中,只有英文对话框和字符串,没有中文的?但我们运行的程
序是中文界面啊?
    可能程序从AuthReg.ini文件中读取中文字符串吗?
先试着把AuthReg.ini文件改名为AuthReg.ini1。再运行程序,界面依然是中文的!这说
明程序从另一个地方得到了中文资源,最有可能的地方就是DLL文件了,在目录中查找DLL
文件,很快就发现了二个可疑的文件。

     Auth936.dll      ------>简体中文的资源文件
     Auth950.dll      ------>繁体中文的资源文件

    还记得上面我对三种语言之间的标志区别进行的分析吗?很清楚了吧。
再用eXeScope将这两个文件载入进行分析,果然在Auth936.dll中保存了简体中文的界
面资源。
***************************************************************************
 一个常识请大家记一下:windows的语言定义中936代表简体中文,950代表繁体中文
***************************************************************************
    到此,对程序的情报收集已经告一段落!下面要动手了!呵呵

¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
¥                      人生不如意,十常八九!                         ¥
¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥

作战手册第二条:打入敌方
    
    现代战争,武器的强大往往决定了战争的成败!Olldbg大家都知道吧,绝世好剑啊!
最好用最新版本的,我用1.10版。
    武器是好啊,不会用也是白搭。在正式使用Olldbg之前,让我们先坐下来冷静的分
析一下:
    1、程序如果要使用DLL动态链接库中的资源,要使用什么API函数?
    2、程序如果要使用对话框,应该使用什么API函数?
    3、程序要取得你输入的注册信息,应该使用什么API函数?
    4、程序要取得你所使用的语言,应该使用什么API函数?
    5、程序要保存你的注册信息,应该使用什么API函数?
    在这五个问题没有得到答案之前,我建议你不要冲动的进行破解。真的!当然,这里
我先给出答案。至于为什么?这些函数是什么意思?请参阅看雪大哥的《加密与解密》第
二版或罗云彬大哥的《Windows环境32位汇编语言程序设计》。两本书是我辈案头必备品,
实乃居家旅行之长备良药啊!!!!!
……………………………………………………………………………………………………
答案:
    1、LoadLibraryA-->载入指定的动态链接库,并将它映射到当前进程使用的地址空间 
    2、DialogBoxParamA-->从资源模板建立一模态对话窗 
       备选还有:DialogBox、CreateDialog、CreateDialogParam
    3、GetWindowTextA--->从指定句柄的窗口控件中读出字符串
       备选还有:GetDlgItemText 得指定输入框输入字符串 
    4、GetACP------>得到你当前使用的字符代码页!
    5、RegSetValueExA--->设置指定项或子项的值  
       备选还有:RegSetValue 。。。。。。
……………………………………………………………………………………………………
OK!万是俱备,只欠东风,你是不是已经很激动了!出发了
……………………………………………………………………………………………………

作战手册第三条:勇敢向前
    兵熊熊一个,将熊熊一窝!前进的号角已经吹响!各位请拿起武器!
    先用olldbg将AutoReg.exe载入,分析程序!
   1、在CPU窗口处点右键,选择Search for->Name (Lable) in current module或者直接
按ctrl+N。很快就会出现程序所调用的所有API函数,在里面找出上面我所说的那些函数:
    DialogBoxParamA,
    GetACP,
    GetWindowsTextA,
    LoadLibraryA,
    RegSetValueExA
可能大家只能找到这五个函数,OK,已经足够了!请在每一个上面点右键并选择
"Set breakpoint on every reference",这样当这些函数被调用程序会被中断。按ALT+C回到
CPU窗口,再按F9运行程序。战争开始了
    很快,程序就断下来了:004058d7调用了GetACP函数。

004058A8  /$  8B>mov     eaxdword ptr ss:[esp+4]
004058AC  |.  83>and     dword ptr ds:[40CC0C], 0
004058B3  |.  83>cmp     eax, -2                                  ;  Switch (cases FFFFFFFC..FFFFFFFE)
004058B6  |.  75>jnz     short AUTHREG.004058C8
004058B8  |.  C7>mov     dword ptr ds:[40CC0C], 1                 ;  Case FFFFFFFE of switch 004058B3
004058C2  |.- FF>jmp     near dword ptr ds:[<&KERNEL32.GetOEMCP>]
004058C8  |>  83>cmp     eax, -3
004058CB  |.  75>jnz     short AUTHREG.004058DD
004058CD  |.  C7>mov     dword ptr ds:[40CC0C], 1                 ;  Case FFFFFFFD of switch 004058B3
004058D7  |.- FF>jmp     near dword ptr ds:[<&KERNEL32.GetACP>]   ;***断在这里
004058DD  |>  83>cmp     eax, -4
004058E0  |.  75>jnz     short AUTHREG.004058F1
004058E2  |.  A1>mov     eaxdword ptr ds:[40CC00]               ;  Case FFFFFFFC of switch 004058B3
004058E7  |.  C7>mov     dword ptr ds:[40CC0C], 1
004058F1  \>  C3 retn                                             ;  Default case of switch 004058B3

     检查代码,上下都没什么可疑之处,不理它,再按F9运行!很快又断下了。
在00401779处,又是GetACP函数,再看看下面的代码,出现了LoadLibraryA函数,可能是要
调入DLL文件了,小心按F8跟下去!调用GetACP后停下,EAX中就是你使用的语言代码,我这里是0x3A8(936)。
看来下面的wsprintfa将会生成dll的文件名了!(如果你将EAX中的值改成0x3B6(950)一定会出现繁体界面)
当你按F8运行到004017A0时在堆栈中就可以看到DLL的文件名了:Auth936.dll
00401771  |. /74>je      short AUTHREG.00401779
00401773  |. |8B>mov     eaxdword ptr ss:[esp+8]
00401777  |. |EB>jmp     short AUTHREG.0040177F
00401779  |> \FF>call    near dword ptr ds:[<&KERNEL32.GetACP>]   ; [GetACP**断在这里
0040177F  |>  50 push    eax                                      ; / EAX中就是语言代码:3A8H(936)
00401780  |.  8D>lea     ecxdword ptr ss:[esp+10]               ; |
00401784  |.  68>push    AUTHREG.0040A07C                         ; |Format = "Auth%d.dll"
00401789  |.  51 push    ecx                                      ; |/String = NULL**字符串缓冲区的地址
0040178A  |.  A3>mov     dword ptr ds:[40F83C], eax               ; ||
0040178F  |.  FF>call    near dword ptr ds:[<&KERNEL32.lstrlenA>] ; |\lstrlenA
00401795  |.  8D>lea     edxdword ptr ss:[esp+eax+14]           ; |
00401799  |.  52 push    edx                                      ; |s = 815DD1E0
0040179A  |.  FF>call    near dword ptr ds:[<&USER32.wsprintfA>]  ; \wsprintfA
004017A0  |.  83>add     esp, 0C                                  ;你可以看到堆栈中已经出现了DLL文件的名称
004017A3  |.  8D>lea     eaxdword ptr ss:[esp+C]
004017A7  |.  50 push    eax                                      ; /压入动态连接库的名称
004017A8  |.  FF>call    near dword ptr ds:[<&KERNEL32.LoadLibraryA>]  ; \LoadLibraryA调入内存
004017AE  |.  85>test    eaxeax                                 ;
004017B0  |.  A3>mov     dword ptr ds:[40CD64], eax               ;保存DLL句柄到ds:[40CD64]
004017B5  |. /75>jnz     short AUTHREG.004017C8                   ;如果调入成功就跳转
004017B7  |. |8B>mov     ecxdword ptr ds:[40CC2C]               ;调入失败,则使用英文界面
004017BD  |. |A3>mov     dword ptr ds:[40F83C], eax               ; 
004017C2  |. |89>mov     dword ptr ds:[40CD64], ecx      ;将英文资源句柄保存到ds:[40CD64]
004017C8  |> \C6>mov     byte ptr ds:[40CD80], 0      ;  运行到这里时,Auth936.dll已经调入内存了

     如下。接着就出现了一个CALL,而且之后就调用DialogBoxParamA显示对话框了,里面一定有问题,
先在004017CF处按F2下一个断点,下次调试时再跟进去。按F8继续走。

004017CF  |.  E8>call    AUTHREG.004020F0                    ; **事实证明这里面就是注册码生成和比较的地方

004017D4  |.  A3>mov     dword ptr ds:[40F840], eax   
004017D9  |.  8B>mov     eaxdword ptr ss:[esp]
004017DD  |.  85>test    eaxeax                                           ;  AUTH936.00C90000
004017DF  |.  75>jnz     short AUTHREG.004017EB
    
    注意了:下面这一招很有意思的!可以做为反调试的一个小技巧!先用GetForegroundWindows
函数得到当前桌面上激活的窗口句柄,这时这个句柄就是我们的Olldbg窗口的句柄,不信请你运行
到004017E7后停下来,记住EAX中的值。然后用windowJuggler插件查看Olldbg主窗口的句柄,比较
一下是不是一样的。看来它针对我们的olldbg做些什么事情!?果然在00401810处将这个句柄压入,
原来它是想用前景窗口做它的父窗口,而它又是一个模态的对话框,当对话框建立之后,这个父窗
口将会被暂时冻结,直到对话框结束才解冻,如果父窗口是调试器的话,对不起,在它结束之前调
试器将会被系统冻结而失去作用!这里它的父窗口就是我们的Olldbg了,看来敌人想要冻结我们。
没关系,你可以停在00401810处将EAX中的值改为00000000就可以不被冻结了。但是我不想这样做,
我按了F9(千万不要按F8运行下去了,不然你会死得很惨,Win9x系统会因此而挂机的,原因自己
分析)。果然我们的Olldbg光荣了。如果你不强行关闭AuthReg.exe的话,还可以保存数据重启计
算机。在下就是挂机重启了!在WIN2000/xp上不会挂机,但olldbg一定死了。看来这个技巧对防
olldbg这一类ring-3级的调试器是很有用的!*****

004017E1  |.  FF>call    near dword ptr ds:[<&USER32.GetForegroundWindow>]  ; [GetForegroundWindow
004017E7  |.  89>mov     dword ptr ss:[esp], eax             ; 保存得到的当前激活窗口的句柄
004017EB  |>  8B>mov     ecxdword ptr ss:[esp+4]
004017EF  |.  A3>mov     dword ptr ds:[40F838], eax          ; 保存得到的当前激活窗口的句柄
004017F4  |.  85>test    ecxecx
004017F6  |.  6A>push    0
004017F8  |.  74>je      short AUTHREG.0040180B
004017FA  |.  8B>mov     edxdword ptr ds:[40CD64]                         ;  AUTH936.00C90000
00401800  |.  68>push    AUTHREG.00401CF0
00401805  |.  50 push    eax                                                ;  AUTH936.00C90000
00401806  |.  6A>push    68
00401808  |.  52 push    edx
00401809  |.  EB>jmp     short AUTHREG.00401819
0040180B  |>  68>push    AUTHREG.00401850                                   ; |对话框的处理函数******
00401810  |.  50 push    eax                                  ; 压入前景窗口的句柄,做对话框的父窗口
00401811  |.  A1>mov     eaxdword ptr ds:[40CD64]                         ; |
00401816  |.  6A>push    67                                                 ; |pTemplate = 67
00401818  |.  50 push    eax                                                ; |hInst = 00C90000
00401819  |>  FF>call    near dword ptr ds:[<&USER32.DialogBoxParamA>]      ; \显示对话框
0040181F  |.  A1>mov     eaxdword ptr ds:[40CD64]
00401824  |.  8B>mov     ecxdword ptr ds:[40CC2C]                         ;  AUTHREG.00400000
0040182A  |.  3B>cmp     eaxecx
0040182C  |.  74>je      short AUTHREG.00401835
0040182E  |.  50 push    eax                                                ; /hLibModule = 00C90000
0040182F  |.  FF>call    near dword ptr ds:[<&KERNEL32.FreeLibrary>]        ; \FreeLibrary,释放DLL文件
00401835  |>  B8>mov     eax, 1
0040183A  |.  81>add     esp, 8C
00401840  \.  C2>retn    10                                                 ;退出

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

作战手册第四条:屡败屡战
     只不过是从头在来!OK,死机了!没关系,关键是要总结经验教训。血的事实告诉我们,
破解不能有一点失误。看来如果不在00401810处修改EAX的值,Olldbg将不能正常发挥作用。
没事,olldbg给了我们另一个选择,这就是Attath(挂接)。请先运行authreg.exe,再打开olldbg。
在olldbg的File菜单中选择Attach,并在弹出的窗口中选择AuthReg.exe文件。OK!敌人再次进入了
我们的包围圈!很快olldbg完成分析并停在了Kernel.dll中,按F9运行,还在Kernel.dll中,没关系
按ALT+E,选择AuthReg.exe文件,双击就可以回到Authreg.exe的代码中了,记得再按ctrl+A,对程序
进行分析,这样程序会好看得多!
    由于对话框已经运行了,上面的分析已经没有太多作用了,不过请大家看到0040180B这个位置
就在上面的代码中,我做了注释:push AUTHREG.00401850这个指令就是将这个对话框的处理函数压入
堆栈。简单的说,从00401850开始就是处理这个对话框的各种信息和指令的位置。这就好说了!
按ctrl+G输入00401850,跳转到这里:

00401850   .  8B>mov     eaxdword ptr ss:[esp+8]   ;处理函数的入口
00401854   .  81>sub     esp, 29C
0040185A   .  2D>sub     eax, 110                    ;  Switch (cases 110..111)各种消息的分支
0040185F   .  53 push    ebx
00401860   .  55 push    ebp
00401861   .  8B>mov     ebpdword ptr ss:[esp+2B0]
00401868   .  56 push    esi
00401869   .  8B>mov     esidword ptr ss:[esp+2AC]
00401870   .  57 push    edi
00401871   .  0F>je      AUTHREG.00401B0B
00401877   .  48 dec     eax
00401878   .  0F>jnz     AUTHREG.00401C7A
0040187E   .  8B>mov     ediebp                     ;  Case 111 of switch 0040185A 处理WM_COMMAND消息的入口
00401880   .  81>and     edi, 0FFFF          ; 请记住,111代表WM_COMMAND消息
00401886   .  81>cmp     edi, 9C41                    ;  Switch (cases 1..9C45)
0040188C   .  0F>jg      AUTHREG.00401A0D        ;先下断点
00401892   .  0F>je      AUTHREG.004019D2        ; 先下断点
00401898   .  4F dec     edi
00401899   .  0F>je      AUTHREG.0040199B        ; 先下断点;这个地方跳到处理“确定”按钮的代码
0040189F   .  4F dec     edi
004018A0   .  0F>je      AUTHREG.004019BF        ; 先下断点
004018A6   .  81>sub     edi, 3F2
004018AC   .  0F>jnz     AUTHREG.00401C7A        ; 先下断点
004018B2   .  A1>mov     eaxdword ptr ds:[40F83C]   ;  Case 3F4 of switch 00401886
004018B7   .  8D>lea     ecxdword ptr ss:[esp+2C]

    由于Windows是基于消息驱动的,所有的动作都会产生消息,同时根据消息进行不同的处理!
请观察程序运行的对话窗,其中有两个按钮,“确定”按钮和“继续试用”按钮,可以推测当按下
“确定”按钮的时候,程序将进行注册码的判断。所以要捕获按钮的消息。而按钮的消息代码是
WM_COMMAND其值就是111。很容易看到,在对话框消息处理函数入口处下面不远就是处理WM_COMMAND
消息的代码(请看上面的注释)。从0040187E到004018AC都是处理WM_COMMAND消息的代码,其中有
五处跳转,不知跳到什么地方。不管它,先对这五个地方都按F2下断点,一个一个试就知道了。
下断点后,转到注册对话框,马上就断下了。停在0040188C处,看来这个断点不是处理“确定”按钮
的,按F2取消这个断点,再按F9到运行。又停在00401892处,这个断点也不是处理“确定”按钮的,
按F2取消这个断点,再按F9运行。对话框出现了,输入注册名:ILOVEYOU,注册码:4321-5678-0987-1234
,点“确定”按钮。呵呵,断下来了在00401899这个位置,一步一步的跟吧!按F8走到0040199B。

0040199B   > \6A>push    0                              ;  按下“确定”按钮后就到这里了; Case 1 of switch 00401886
0040199D   .  56 push    esi
0040199E   .  E8>call    AUTHREG.00402350               ;  对你输入的注册名和注册码的长度进行检查

步步为营,按F7进入0040199e的CALL AUTHREG.00402350中:

00402350  /$  A1>mov     eaxdword ptr ds:[40CC30]     ;
00402355  |.  56 push    esi                            ;
00402356  |.  8B>mov     esidword ptr ds:[<&USER32.GetWindowTextLengthA>] ;将GetWindowTextLengthA函数地址复制给ESI
0040235C  |.  50 push    eax                            ; /hWnd = NULL压入“注册码”编辑框的句柄,
0040235D  |.  FF>call    near esi                       ; \GetWindowTextLengthA 
0040235F  |.  85>test    eaxeax                       ;  得到注册名的长度
00402361  |.  75>jnz     short AUTHREG.00402380         ; 如果有注册名就跳跳转
00402363  |.  8B>mov     eaxdword ptr ss:[esp+C]
00402367  |.  85>test    eaxeax
00402369  |.  75>jnz     short AUTHREG.004023D3        
0040236B  |.  8B>mov     ecxdword ptr ss:[esp+8]
0040236F  |.  6A>push    2
00402371  |.  6A>push    3
00402373  |.  51 push    ecx
00402374  |.  E8>call    AUTHREG.004022B0               ; 如果是注册名空就提示错误信息,并返回
00402379  |.  83>add     esp, 0C
0040237C  |.  33>xor     eaxeax
0040237E  |.  5E pop     esi                                                ;  AUTHREG.004019A3
0040237F  |.  C3 retn
00402380  |>  8B>mov     edxdword ptr ds:[40CC38]                         ;  得到注册码文字框的句柄!
00402386  |.  53 push    ebx                                                ;  保存计数器
00402387  |.  55 push    ebp                                                ;  保存计数器
00402388  |.  57 push    edi                                                ;  保存计数器
00402389  |.  52 push    edx                                                ;  压入句柄
0040238A  |.  FF>call    near esi                                           ;  得到第一段注册码的长度
0040238C  |.  8B>mov     edieax                                           ;  edi中是长度
0040238E  |.  A1>mov     eaxdword ptr ds:[40CC34]
00402393  |.  50 push    eax
00402394  |.  FF>call    near esi                                           ;  得到第二段注册码的长度
00402396  |.  8B>mov     ecxdword ptr ds:[40CC40]
0040239C  |.  8B>mov     ebxeax                                           ;  ebx 中是长度
0040239E  |.  51 push    ecx
0040239F  |.  FF>call    near esi                                           ;  得到第三段注册码的长度
004023A1  |.  8B>mov     edxdword ptr ds:[40CC3C]
004023A7  |.  8B>mov     ebpeax                                           ;  ebp中是长度
004023A9  |.  52 push    edx
004023AA  |.  FF>call    near esi              ;得到第四段注册码的长度
004023AC  |.  23>and     eaxebp                                           ;eax中是长度
004023AE  |.  23>and     eaxebx              ;检查长度
004023B0  |.  23>and     eaxedi              ;检查长度
004023B2  |.  5F pop     edi                                                ;  恢复计数器
004023B3  |.  5D pop     ebp                                                ;  恢复计数器
004023B4  |.  83>and     eax, 4                      ;检查长度
004023B7  |.  5B pop     ebx                                                ;  恢复计数器
004023B8  |.  75>jnz     short AUTHREG.004023D5                             ;  如果都正确输入四位密码就返回
004023BA  |.  8B>mov     eaxdword ptr ss:[esp+C]
004023BE  |.  85>test    eaxeax
004023C0  |.  75>jnz     short AUTHREG.004023D3
004023C2  |.  8B>mov     eaxdword ptr ss:[esp+8]
004023C6  |.  6A>push    2
004023C8  |.  6A>push    4
004023CA  |.  50 push    eax
004023CB  |.  E8>call    AUTHREG.004022B0                                    ;提示错误信息
004023D0  |.  83>add     esp, 0C
004023D3  |>  33>xor     eaxeax
004023D5  |>  5E pop     esi                                                ;  AUTHREG.004019A3
004023D6  \.  C3 retn

看来这个函数只是进行基本检查,不是关键!

004019A3   .  83>add     esp, 8
004019A6   .  85>test    eaxeax                       
004019A8   .  0F>je      AUTHREG.00401C7A                        ;  如果输入不正确就跳回,再次输入

又出现一个CALL了,而且后面就调用EndDialog退出程序了!一定要F7进入,

004019AE   .  56 push    esi                                    ;压入对话框句柄
004019AF   .  E8>call    AUTHREG.00402480                       ;关键调用啊!!!F7进入
004019B4   .  83>add     esp, 4
004019B7   .  85>test    eaxeax
004019B9   .  0F>je      AUTHREG.00401C7A
004019BF   >  E8>call    AUTHREG.00401500                          ;  Case 2 of switch 00401886
004019C4   .  6A>push    0                                         ; /Result = 0
004019C6   .  56 push    esi                                       ; |hWnd = 00000A50 ('注册',class='#32770',wndproc=801E6DCA,parent=00000970)
004019C7   .  FF>call    near dword ptr ds:[<&USER32.EndDialog>]   ; \EndDialog
004019CD   .  E9>jmp     AUTHREG.00401C7A

出现了,关键调用出现了!

00402480  /$  83>sub     esp, 40
00402483  |.  8B>mov     ecxdword ptr ds:[40CC38]
00402489  |.  56 push    esi
0040248A  |.  8B>mov     esidword ptr ds:[<&USER32.GetWindowTextA>]
00402490  |.  8D>lea     eaxdword ptr ss:[esp+4]
00402494  |.  6A>push    8                                              ; /Count = 8
00402496  |.  50 push    eax                                            ; |Buffer = 00000004
00402497  |.  51 push    ecx                                            ; |hWnd = C159E320
00402498  |.  FF>call    near esi                                       ; \GetWindowTextA
0040249A  |.  A1>mov     eaxdword ptr ds:[40CC34]                     ;  得到注册码中的第一段
0040249F  |.  8D>lea     edxdword ptr ss:[esp+9]
004024A3  |.  6A>push    8                                              ; /Count = 8
004024A5  |.  52 push    edx                                            ; |Buffer = 815D0000
004024A6  |.  50 push    eax                                            ; |hWnd = 00000004
004024A7  |.  FF>call    near esi                                       ; \GetWindowTextA
004024A9  |.  8B>mov     edxdword ptr ds:[40CC40]                     ;  得到注册码中的第二段
004024AF  |.  8D>lea     ecxdword ptr ss:[esp+E]
004024B3  |.  6A>push    8                                              ; /Count = 8
004024B5  |.  51 push    ecx                                            ; |Buffer = C159E320
004024B6  |.  52 push    edx                                            ; |hWnd = 815D0000
004024B7  |.  FF>call    near esi                                       ; \GetWindowTextA
004024B9  |.  8B>mov     ecxdword ptr ds:[40CC3C]                     ;  得到注册码中的第三段
004024BF  |.  8D>lea     eaxdword ptr ss:[esp+13]
004024C3  |.  6A>push    8                                              ; /Count = 8
004024C5  |.  50 push    eax                                            ; |Buffer = 00000004
004024C6  |.  51 push    ecx                                            ; |hWnd = C159E320
004024C7  |.  FF>call    near esi                                       ; \GetWindowTextA
004024C9  |.  8B>mov     edxdword ptr ds:[40CC30]                     ;  得到注册码中的第四段
004024CF  |.  68>push    100                                            ; /Count = 100 (256.)
004024D4  |.  B0>mov     al, 2D                                         ; |
004024D6  |.  68>push    AUTHREG.0040CD80                               ; |Buffer = AUTHREG.0040CD80
004024DB  |.  52 push    edx                                            ; |hWnd = 815D0000
004024DC  |.  88>mov     byte ptr ss:[esp+1E], al                       ; |
004024E0  |.  88>mov     byte ptr ss:[esp+19], al                       ; |
004024E4  |.  88>mov     byte ptr ss:[esp+14], al                       ; |
004024E8  |.  C6>mov     byte ptr ss:[esp+23], 0                        ; |
004024ED  |.  FF>call    near esi                                       ; \GetWindowTextA
004024EF  |.  A1>mov     eaxdword ptr ds:[40C758]                     ;  得到注册名
004024F4  |.  5E pop     esi                                            ;  AUTHREG.004019B4
004024F5  |.  85>test    eaxeax
004024F7  |. /74>je      short AUTHREG.00402507              ;如果取值成功就跳转
004024F9  |. |8D>lea     ecxdword ptr ss:[esp]
004024FD  |. |51 push    ecx
004024FE  |. |68>push    AUTHREG.0040CD80                     ;  ASCII "ILOVEYOU"
00402503  |. |FF>call    near eax
00402505  |. |EB>jmp     short AUTHREG.00402516
00402507  |> \8D>lea     edxdword ptr ss:[esp]              ;  注意了,下面压入了注册名和注册码
0040250B  |.  52 push    edx                                  ; /Arg2 = 80005140
0040250C  |.  68>push    AUTHREG.0040CD80                     ; |Arg1 = 0040CD80 ASCII "ILOVEYOU"
00402511  |.  E8>call    AUTHREG.004039F0                     ; \关键的调用,F7进入!

上面两句push代码分别压入注册名和注册码,看来Call AUTHREG.004039F0一定是注册比较过程了,
F7进入后按F8一直走到00403A80,发现随后有四段类似的运算与比较

********************************第一段**********************************
00403A80  |.  8B>mov     ebpdword ptr ss:[esp+58]
00403A84  |.  8B>mov     ebxdword ptr ss:[esp+9C]
00403A8B  |.  8D>lea     edxdword ptr ss:[esp+14]
00403A8F  |.  83>add     esp, 4
00403A92  |.  8D>lea     ecxdword ptr ds:[eax+ebp]
00403A95  |.  0F>imul    eaxdword ptr ss:[esp+50]
00403A9A  |.  0F>imul    ecxdword ptr ss:[esp+58]
00403A9F  |.  03>add     ecxebp
00403AA1  |.  33>xor     esiesi
00403AA3  |.  33>xor     ecxeax
00403AA5  |.  0F>imul    ecxdword ptr ss:[esp+6C]
00403AAA  |.  89>mov     dword ptr ss:[esp+10], ecx
00403AAE  |.  2B>sub     ebxedx
00403AB0  |>  8D>/lea     edidword ptr ss:[esp+esi+10]
00403AB4  |.  0F>|movsx   eaxbyte ptr ds:[ebx+edi]
00403AB8  |.  83>|cmp     eax, 41
00403ABB  |.  7C>|jl      short AUTHREG.00403AC5
00403ABD  |.  83>|cmp     eax, 5A
00403AC0  |.  7F>|jg      short AUTHREG.00403AC5
00403AC2  |.  83>|add     eax, 20
00403AC5  |>  50 |push    eax
00403AC6  |.  E8>|call    AUTHREG.00403D70
00403ACB  |.  83>|add     esp, 4
00403ACE  |.  46 |inc     esi
00403ACF  |.  83>|cmp     esi, 4
00403AD2  |.  88>|mov     byte ptr ds:[edi], al  
00403AD4  |.^ 7C>\jl      short AUTHREG.00403AB0
00403AD6  |.  33>xor     edxedx                            ;以上是第一段正确注册码的运算

00403AD8  |>  8D>/lea     ecxdword ptr ss:[esp+edx+10]     ;  第一段注册码比较
00403ADC  |.  0F>|movsx   eaxbyte ptr ds:[ebx+ecx]
00403AE0  |.  83>|cmp     eax, 41
00403AE3  |.  7C>|jl      short AUTHREG.00403AED
00403AE5  |.  83>|cmp     eax, 5A
00403AE8  |.  7F>|jg      short AUTHREG.00403AED
00403AEA  |.  83>|add     eax, 20
00403AED  |>  0F>|movsx   ecxbyte ptr ds:[ecx]
00403AF0  |.  3B>|cmp     eaxecx                            
00403AF2  |.  0F>|jnz     AUTHREG.00403C6E               ;如果不相同就跳走了,不要跳走!调试的时候不要让它跳走
00403AF8  |.  42 |inc     edx
00403AF9  |.  83>|cmp     edx, 4
00403AFC  |.^ 7C>\jl      short AUTHREG.00403AD8

********************************第二段**********************************
00403AFE  |.  8B>mov     ecxdword ptr ss:[esp+10]
00403B02  |.  8B>mov     eaxecx
00403B04  |.  0F>imul    eaxdword ptr ss:[esp+60]
00403B09  |.  03>add     eaxebp
00403B0B  |.  0F>imul    eaxecx
00403B0E  |.  0F>imul    ecxdword ptr ss:[esp+6C]
00403B13  |.  0F>imul    eaxdword ptr ss:[esp+68]
00403B18  |.  03>add     eaxecx
00403B1A  |.  33>xor     esiesi
00403B1C  |.  89>mov     dword ptr ss:[esp+14], eax
00403B20  |>  8A>/mov     dlbyte ptr ss:[esp+esi+14]
00403B24  |.  52 |push    edx
00403B25  |.  56 |push    esi
00403B26  |.  E8>|call    AUTHREG.00403C80
00403B2B  |.  25>|and     eax, 0FF
00403B30  |.  50 |push    eax
00403B31  |.  E8>|call    AUTHREG.00403D70
00403B36  |.  83>|add     esp, 0C
00403B39  |.  88>|mov     byte ptr ss:[esp+esi+14], al
00403B3D  |.  46 |inc     esi
00403B3E  |.  83>|cmp     esi, 4
00403B41  |.^ 7C>\jl      short AUTHREG.00403B20
00403B43  |.  33>xor     ecxecx                                   ;以上是第二段正确注册码的运算

00403B45  |>  8B>/mov     edidword ptr ss:[esp+98]               ;  第二段注册码比较
00403B4C  |.  0F>|movsx   eaxbyte ptr ds:[edi+ecx+5]
00403B51  |.  83>|cmp     eax, 41
00403B54  |.  7C>|jl      short AUTHREG.00403B5E
00403B56  |.  83>|cmp     eax, 5A
00403B59  |.  7F>|jg      short AUTHREG.00403B5E
00403B5B  |.  83>|add     eax, 20
00403B5E  |>  0F>|movsx   edxbyte ptr ss:[esp+ecx+14]
00403B63  |.  3B>|cmp     eaxedx                            
00403B65      0F>|jnz     AUTHREG.00403C6E             ;如果不相同就跳走了,不要跳走!调试的时候不要让它跳走
00403B6B  |.  41 |inc     ecx
00403B6C  |.  83>|cmp     ecx, 4
00403B6F  |.^ 7C>\jl      short AUTHREG.00403B45

********************************第三段**********************************
00403B71  |.  8B>mov     ecxdword ptr ss:[esp+14]
00403B75  |.  8B>mov     edxdword ptr ss:[esp+10]
00403B79  |.  8B>mov     eaxecx
00403B7B  |.  8B>mov     esidword ptr ss:[esp+78]
00403B7F  |.  33>xor     eaxedx
00403B81  |.  0F>imul    ecxdword ptr ss:[esp+74]
00403B86  |.  0F>imul    eaxdword ptr ss:[esp+70]
00403B8B  |.  03>add     eaxesi
00403B8D  |.  0F>imul    eaxedx
00403B90  |.  03>add     eaxecx
00403B92  |.  0F>imul    eaxdword ptr ss:[esp+7C]
00403B97  |.  89>mov     dword ptr ss:[esp+18], eax
00403B9B  |.  33>xor     esiesi
00403B9D  |>  0F>/movsx   eaxbyte ptr ss:[esp+esi+18]
00403BA2  |.  50 |push    eax
00403BA3  |.  E8>|call    AUTHREG.00403D70
00403BA8  |.  83>|add     esp, 4
00403BAB  |.  88>|mov     byte ptr ss:[esp+esi+18], al
00403BAF  |.  46 |inc     esi
00403BB0  |.  83>|cmp     esi, 4
00403BB3  |.^ 7C>\jl      short AUTHREG.00403B9D
00403BB5  |.  33>xor     ecxecx

00403BB7  |>  0F>/movsx   eaxbyte ptr ds:[edi+ecx+A]            ;  第三段比较
00403BBC  |.  83>|cmp     eax, 41
00403BBF  |.  7C>|jl      short AUTHREG.00403BC9
00403BC1  |.  83>|cmp     eax, 5A
00403BC4  |.  7F>|jg      short AUTHREG.00403BC9
00403BC6  |.  83>|add     eax, 20
00403BC9  |>  0F>|movsx   edxbyte ptr ss:[esp+ecx+18]
00403BCE  |.  3B>|cmp     eaxedx                            
00403BD0      0F>|jnz     AUTHREG.00403C6E                         ;如果不相同就跳走了,不要跳走!调试的时候不要让它跳走
00403BD6  |.  41 |inc     ecx
00403BD7  |.  83>|cmp     ecx, 4
00403BDA  |.^ 7C>\jl      short AUTHREG.00403BB7

********************************第四段**********************************
00403BDC  |.  8B>mov     ecxdword ptr ss:[esp+18]
00403BE0  |.  8B>mov     esidword ptr ss:[esp+14]
00403BE4  |.  8B>mov     eaxecx
00403BE6  |.  8B>mov     edxdword ptr ss:[esp+10]
00403BEA  |.  0F>imul    eaxesi
00403BED  |.  0F>imul    eaxedx
00403BF0  |.  0F>imul    eaxdword ptr ss:[esp+80]
00403BF8  |.  8D>lea     ebxdword ptr ds:[ecx+edx]
00403BFB  |.  03>add     ecxesi
00403BFD  |.  0F>imul    ebxdword ptr ss:[esp+84]
00403C05  |.  03>add     eaxebx
00403C07  |.  03>add     ecxedx
00403C09  |.  0F>imul    ecxdword ptr ss:[esp+8C]
00403C11  |.  0F>imul    eaxdword ptr ss:[esp+88]
00403C19  |.  03>add     ecxeax
00403C1B  |.  33>xor     esiesi
00403C1D  |.  89>mov     dword ptr ss:[esp+1C], ecx
00403C21  |>  0F>/movsx   eaxbyte ptr ss:[esp+esi+1C]
00403C26  |.  50 |push    eax
00403C27  |.  E8>|call    AUTHREG.00403D70
00403C2C  |.  83>|add     esp, 4
00403C2F  |.  88>|mov     byte ptr ss:[esp+esi+1C], al
00403C33  |.  46 |inc     esi
00403C34  |.  83>|cmp     esi, 4
00403C37  |.^ 7C>\jl      short AUTHREG.00403C21
00403C39  |.  33>xor     ecxecx

00403C3B  |>  0F>/movsx   eaxbyte ptr ds:[edi+ecx+F]       ;  第四段比较
00403C40  |.  83>|cmp     eax, 41
00403C43  |.  7C>|jl      short AUTHREG.00403C4D
00403C45  |.  83>|cmp     eax, 5A
00403C48  |.  7F>|jg      short AUTHREG.00403C4D
00403C4A  |.  83>|add     eax, 20
00403C4D  |>  0F>|movsx   edxbyte ptr ss:[esp+ecx+1C]
00403C52  |.  3B>|cmp     eaxedx                     
00403C54      75>|jnz     short AUTHREG.00403C6E         ;如果不相同就跳走了,不要跳走!调试的时候不要让它跳走
00403C56  |.  41 |inc     ecx
00403C57  |.  83>|cmp     ecx, 4
00403C5A  |.^ 7C>\jl      short AUTHREG.00403C3B
00403C5C  |.  5F pop     edi
00403C5D  |.  5E pop     esi
00403C5E  |.  5D pop     ebp
00403C5F  |.  B8>mov     eax, 1
00403C64  |.  5B pop     ebx
00403C65  |.  81>add     esp, 80                              ;  ESP中就是正确的注册码
00403C6B  |.  C2>retn    8
00403C6E  |>  5F pop     edi                                  ;如果不相同就跳到这里了
00403C6F  |.  5E pop     esi
00403C70  |.  5D pop     ebp
00403C71  |.  33>xor     eaxeax
00403C73  |.  5B pop     ebx
00403C74  |.  81>add     esp, 80
00403C7A  \.  C2>retn    8

运行到00403c65时请停下来,在ESP中你看到什么了?呵呵,我这里是:4321lqh25ts1535s
     4321lqh25ts1535s----->>>> 4321-lqh2-5ts1-535s  (正确的注册码)
还等什么?用笔记下来啊!好吧,我们继续走返回到00402516

00402516  |>  33>xor     ecxecx
00402518  |.  8D>lea     edxdword ptr ss:[esp]
0040251C  |.  85>test    eaxeax
0040251E  |.  0F>setne   cl
00402521  |.  52 push    edx
00402522  |.  68>push    AUTHREG.0040CD80                     ;  ASCII "ILOVEYOU"
00402527  |.  89>mov     dword ptr ds:[40F840], ecx
0040252D  |.  E8>call    AUTHREG.00402560                     ;  这里将注册码保存到注册表中!

上面这个CALL将你的注册信息保存到注册表,各位请自己分析。

00402532  |.  8B>mov     ecxdword ptr ss:[esp+4C]
00402536  |.  8B>mov     edxdword ptr ds:[40CD64]           ;  AUTH936.00C90000
0040253C  |.  83>add     esp, 8
0040253F  |.  8D>lea     eaxdword ptr ss:[esp]
00402543  |.  50 push    eax                                  ; /lParam = NULL
00402544  |.  68>push    AUTHREG.004023E0                     ; |DlgProc = AUTHREG.004023E0
00402549  |.  51 push    ecx                                  ; |hOwner = 800050B8
0040254A  |.  6A>push    69                                   ; |pTemplate = 69
0040254C  |.  52 push    edx                                  ; |hInst = 80005140
0040254D  |.  FF>call    near dword ptr ds:[<&USER32.DialogBo>; \DialogBoxParamA:这里将显示我们成功的信息!
00402553  |.  A1>mov     eaxdword ptr ds:[40F840]
00402558  |.  83>add     esp, 40
0040255B  \.  C3 retn                                         ;成功返回

作战手册第五条:成功永远属于我们
     你记住刚才的那段数字了吗?OK!按F9回到主对话框,点“继续试用”退出程序,然后再关闭olldbg,
记住先后顺序不要搞反了,不然你很麻烦。
     关闭你所有的程序,然后打开豪*超级解*V8的程序,很自然又会弹出请你注册的信息,没关系我们已经
有了正确的注册码,输入吧!然后享受影音快乐吧!成功永远属于我们


总结:
   关键要头脑冷静,认真分析和观察,了解常用API函数的使用途径、使用方法。
******************************
*  注册名:ILOVEYOU                  *
*  注册码:4321-lqh2-5ts1-535s   *
******************************

作者:chenjiwl
chenjiwl@sina.com