[标题] 豪*超级解*别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] [email]chenjiwl@sina.com[/email]
昨日为一好友装机,非要装超级解*。然手中无有此软件,上网查之,有最新版+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 eax, dword 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 eax, dword 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 eax, dword 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 ecx, dword 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 edx, dword 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 eax, dword ptr ss:[esp+C]
004017A7 |. 50 push eax ; /压入动态连接库的名称
004017A8 |. FF>call near dword ptr ds:[<&KERNEL32.LoadLibraryA>] ; \LoadLibraryA调入内存
004017AE |. 85>test eax, eax ;
004017B0 |. A3>mov dword ptr ds:[40CD64], eax ;保存DLL句柄到ds:[40CD64]
004017B5 |. /75>jnz short AUTHREG.004017C8 ;如果调入成功就跳转
004017B7 |. |8B>mov ecx, dword 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 eax, dword ptr ss:[esp]
004017DD |. 85>test eax, eax ; 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 ecx, dword ptr ss:[esp+4]
004017EF |. A3>mov dword ptr ds:[40F838], eax ; 保存得到的当前激活窗口的句柄
004017F4 |. 85>test ecx, ecx
004017F6 |. 6A>push 0
004017F8 |. 74>je short AUTHREG.0040180B
004017FA |. 8B>mov edx, dword 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 eax, dword 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 eax, dword ptr ds:[40CD64]
00401824 |. 8B>mov ecx, dword ptr ds:[40CC2C] ; AUTHREG.00400000
0040182A |. 3B>cmp eax, ecx
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 eax, dword 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 ebp, dword ptr ss:[esp+2B0]
00401868 . 56 push esi
00401869 . 8B>mov esi, dword 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 edi, ebp ; 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 eax, dword ptr ds:[40F83C] ; Case 3F4 of switch 00401886
004018B7 . 8D>lea ecx, dword 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 eax, dword ptr ds:[40CC30] ;
00402355 |. 56 push esi ;
00402356 |. 8B>mov esi, dword ptr ds:[<&USER32.GetWindowTextLengthA>] ;将GetWindowTextLengthA函数地址复制给ESI
0040235C |. 50 push eax ; /hWnd = NULL压入“注册码”编辑框的句柄,
0040235D |. FF>call near esi ; \GetWindowTextLengthA
0040235F |. 85>test eax, eax ; 得到注册名的长度
00402361 |. 75>jnz short AUTHREG.00402380 ; 如果有注册名就跳跳转
00402363 |. 8B>mov eax, dword ptr ss:[esp+C]
00402367 |. 85>test eax, eax
00402369 |. 75>jnz short AUTHREG.004023D3
0040236B |. 8B>mov ecx, dword 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 eax, eax
0040237E |. 5E pop esi ; AUTHREG.004019A3
0040237F |. C3 retn
00402380 |> 8B>mov edx, dword 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 edi, eax ; edi中是长度
0040238E |. A1>mov eax, dword ptr ds:[40CC34]
00402393 |. 50 push eax
00402394 |. FF>call near esi ; 得到第二段注册码的长度
00402396 |. 8B>mov ecx, dword ptr ds:[40CC40]
0040239C |. 8B>mov ebx, eax ; ebx 中是长度
0040239E |. 51 push ecx
0040239F |. FF>call near esi ; 得到第三段注册码的长度
004023A1 |. 8B>mov edx, dword ptr ds:[40CC3C]
004023A7 |. 8B>mov ebp, eax ; ebp中是长度
004023A9 |. 52 push edx
004023AA |. FF>call near esi ;得到第四段注册码的长度
004023AC |. 23>and eax, ebp ;eax中是长度
004023AE |. 23>and eax, ebx ;检查长度
004023B0 |. 23>and eax, edi ;检查长度
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 eax, dword ptr ss:[esp+C]
004023BE |. 85>test eax, eax
004023C0 |. 75>jnz short AUTHREG.004023D3
004023C2 |. 8B>mov eax, dword 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 eax, eax
004023D5 |> 5E pop esi ; AUTHREG.004019A3
004023D6 \. C3 retn
看来这个函数只是进行基本检查,不是关键!
004019A3 . 83>add esp, 8
004019A6 . 85>test eax, eax
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 eax, eax
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 ecx, dword ptr ds:[40CC38]
00402489 |. 56 push esi
0040248A |. 8B>mov esi, dword ptr ds:[<&USER32.GetWindowTextA>]
00402490 |. 8D>lea eax, dword 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 eax, dword ptr ds:[40CC34] ; 得到注册码中的第一段
0040249F |. 8D>lea edx, dword 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 edx, dword ptr ds:[40CC40] ; 得到注册码中的第二段
004024AF |. 8D>lea ecx, dword 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 ecx, dword ptr ds:[40CC3C] ; 得到注册码中的第三段
004024BF |. 8D>lea eax, dword 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 edx, dword 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 eax, dword ptr ds:[40C758] ; 得到注册名
004024F4 |. 5E pop esi ; AUTHREG.004019B4
004024F5 |. 85>test eax, eax
004024F7 |. /74>je short AUTHREG.00402507 ;如果取值成功就跳转
004024F9 |. |8D>lea ecx, dword 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 edx, dword 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 ebp, dword ptr ss:[esp+58]
00403A84 |. 8B>mov ebx, dword ptr ss:[esp+9C]
00403A8B |. 8D>lea edx, dword ptr ss:[esp+14]
00403A8F |. 83>add esp, 4
00403A92 |. 8D>lea ecx, dword ptr ds:[eax+ebp]
00403A95 |. 0F>imul eax, dword ptr ss:[esp+50]
00403A9A |. 0F>imul ecx, dword ptr ss:[esp+58]
00403A9F |. 03>add ecx, ebp
00403AA1 |. 33>xor esi, esi
00403AA3 |. 33>xor ecx, eax
00403AA5 |. 0F>imul ecx, dword ptr ss:[esp+6C]
00403AAA |. 89>mov dword ptr ss:[esp+10], ecx
00403AAE |. 2B>sub ebx, edx
00403AB0 |> 8D>/lea edi, dword ptr ss:[esp+esi+10]
00403AB4 |. 0F>|movsx eax, byte 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 edx, edx ;以上是第一段正确注册码的运算
00403AD8 |> 8D>/lea ecx, dword ptr ss:[esp+edx+10] ; 第一段注册码比较
00403ADC |. 0F>|movsx eax, byte 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 ecx, byte ptr ds:[ecx]
00403AF0 |. 3B>|cmp eax, ecx
00403AF2 |. 0F>|jnz AUTHREG.00403C6E ;如果不相同就跳走了,不要跳走!调试的时候不要让它跳走
00403AF8 |. 42 |inc edx
00403AF9 |. 83>|cmp edx, 4
00403AFC |.^ 7C>\jl short AUTHREG.00403AD8
********************************第二段**********************************
00403AFE |. 8B>mov ecx, dword ptr ss:[esp+10]
00403B02 |. 8B>mov eax, ecx
00403B04 |. 0F>imul eax, dword ptr ss:[esp+60]
00403B09 |. 03>add eax, ebp
00403B0B |. 0F>imul eax, ecx
00403B0E |. 0F>imul ecx, dword ptr ss:[esp+6C]
00403B13 |. 0F>imul eax, dword ptr ss:[esp+68]
00403B18 |. 03>add eax, ecx
00403B1A |. 33>xor esi, esi
00403B1C |. 89>mov dword ptr ss:[esp+14], eax
00403B20 |> 8A>/mov dl, byte 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 ecx, ecx ;以上是第二段正确注册码的运算
00403B45 |> 8B>/mov edi, dword ptr ss:[esp+98] ; 第二段注册码比较
00403B4C |. 0F>|movsx eax, byte 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 edx, byte ptr ss:[esp+ecx+14]
00403B63 |. 3B>|cmp eax, edx
00403B65 0F>|jnz AUTHREG.00403C6E ;如果不相同就跳走了,不要跳走!调试的时候不要让它跳走
00403B6B |. 41 |inc ecx
00403B6C |. 83>|cmp ecx, 4
00403B6F |.^ 7C>\jl short AUTHREG.00403B45
********************************第三段**********************************
00403B71 |. 8B>mov ecx, dword ptr ss:[esp+14]
00403B75 |. 8B>mov edx, dword ptr ss:[esp+10]
00403B79 |. 8B>mov eax, ecx
00403B7B |. 8B>mov esi, dword ptr ss:[esp+78]
00403B7F |. 33>xor eax, edx
00403B81 |. 0F>imul ecx, dword ptr ss:[esp+74]
00403B86 |. 0F>imul eax, dword ptr ss:[esp+70]
00403B8B |. 03>add eax, esi
00403B8D |. 0F>imul eax, edx
00403B90 |. 03>add eax, ecx
00403B92 |. 0F>imul eax, dword ptr ss:[esp+7C]
00403B97 |. 89>mov dword ptr ss:[esp+18], eax
00403B9B |. 33>xor esi, esi
00403B9D |> 0F>/movsx eax, byte 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 ecx, ecx
00403BB7 |> 0F>/movsx eax, byte 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 edx, byte ptr ss:[esp+ecx+18]
00403BCE |. 3B>|cmp eax, edx
00403BD0 0F>|jnz AUTHREG.00403C6E ;如果不相同就跳走了,不要跳走!调试的时候不要让它跳走
00403BD6 |. 41 |inc ecx
00403BD7 |. 83>|cmp ecx, 4
00403BDA |.^ 7C>\jl short AUTHREG.00403BB7
********************************第四段**********************************
00403BDC |. 8B>mov ecx, dword ptr ss:[esp+18]
00403BE0 |. 8B>mov esi, dword ptr ss:[esp+14]
00403BE4 |. 8B>mov eax, ecx
00403BE6 |. 8B>mov edx, dword ptr ss:[esp+10]
00403BEA |. 0F>imul eax, esi
00403BED |. 0F>imul eax, edx
00403BF0 |. 0F>imul eax, dword ptr ss:[esp+80]
00403BF8 |. 8D>lea ebx, dword ptr ds:[ecx+edx]
00403BFB |. 03>add ecx, esi
00403BFD |. 0F>imul ebx, dword ptr ss:[esp+84]
00403C05 |. 03>add eax, ebx
00403C07 |. 03>add ecx, edx
00403C09 |. 0F>imul ecx, dword ptr ss:[esp+8C]
00403C11 |. 0F>imul eax, dword ptr ss:[esp+88]
00403C19 |. 03>add ecx, eax
00403C1B |. 33>xor esi, esi
00403C1D |. 89>mov dword ptr ss:[esp+1C], ecx
00403C21 |> 0F>/movsx eax, byte 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 ecx, ecx
00403C3B |> 0F>/movsx eax, byte 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 edx, byte ptr ss:[esp+ecx+1C]
00403C52 |. 3B>|cmp eax, edx
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 eax, eax
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 ecx, ecx
00402518 |. 8D>lea edx, dword ptr ss:[esp]
0040251C |. 85>test eax, eax
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 ecx, dword ptr ss:[esp+4C]
00402536 |. 8B>mov edx, dword ptr ds:[40CD64] ; AUTH936.00C90000
0040253C |. 83>add esp, 8
0040253F |. 8D>lea eax, dword 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 eax, dword ptr ds:[40F840]
00402558 |. 83>add esp, 40
0040255B \. C3 retn ;成功返回
作战手册第五条:成功永远属于我们
你记住刚才的那段数字了吗?OK!按F9回到主对话框,点“继续试用”退出程序,然后再关闭olldbg,
记住先后顺序不要搞反了,不然你很麻烦。
关闭你所有的程序,然后打开豪*超级解*V8的程序,很自然又会弹出请你注册的信息,没关系我们已经
有了正确的注册码,输入吧!然后享受影音快乐吧!成功永远属于我们
总结:
关键要头脑冷静,认真分析和观察,了解常用API函数的使用途径、使用方法。
******************************
* 注册名:ILOVEYOU *
* 注册码:4321-lqh2-5ts1-535s *
******************************
作者:chenjiwl
[email]chenjiwl@sina.com[/email]:D
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)