好久没有写这方面的文章了,常常都是随手破了后丢到论坛里。
由于博客新开,内容实在是太少了,只好努力一点,多写写东西了,希望大家从中能有所得,呵呵……
具体的软件介绍或者下载,大家可以到这里查阅:http://www.newhua.com/soft/12371.htm
如果需要下载破解版,则请到论坛下载:http://bbs.7softs.com/read.php?tid=30682&page=1&toread=1
好了,不多说了,开始我们的分析,按照流程来吧:
1、查壳,显示为:Microsoft Visual C++ 7.0 [调试]
2、载入后,看了看文件头,肯定了无壳:
00507F7E S> 6A 60 push 60
00507F80 68 E04F7300 push ScreenHu.00734FE0
00507F85 E8 22480000 call ScreenHu.0050C7AC
00507F8A BF 94000000 mov edi,94
00507F8F 8BC7 mov eax,edi
00507F91 E8 BACDFFFF call ScreenHu.00504D50
00507F96 8965 E8 mov dword ptr ss:[ebp-18],esp
00507F99 8BF4 mov esi,esp
00507F9B 893E mov dword ptr ds:[esi],edi
00507F9D 56 push esi
00507F9E FF15 08B97B00 call dword ptr ds:[<&KERNEL32.GetVersi>; kernel32.GetVersionExA
3、F9运行起来,然后输入假码:11111-22222-33333-44444-55555
有错误提示,不过不是通过弹出对话框,而是通过文本控件来显示的:“Invalid License……”
用插件和OD自带的字符查找工具查找了一下,都没有找到,不过却找到了一些相关的看似有用的信息,如图:
4、试着在上面下了断点,然后再次注册,不过没有断下来:
005B09C0 68 A8C46F00 push ScreenHu.006FC4A8 ; licensekey1
//在上面一行下了断点!
005B09C5 B9 C8F17800 mov ecx,ScreenHu.0078F1C8
005B09CA E8 3D36E5FF call ScreenHu.0040400C
005B09CF 68 705C6700 push ScreenHu.00675C70
005B09D4 E8 3D3BF5FF call ScreenHu.00504516
005B09D9 59 pop ecx
005B09DA C3 retn
5、对一些常用的API函数下断点:
万能断点————————–无效
bp GetDlgItemTextA———-无效
bp SetDlgitemTextA———–无效
于是我又现次下了一个:SetWindowTextA的断点,呵呵终于断了下来
77D2F56B U> 8BFF mov edi,edi
//此时提示窗口提示为
//edi=0109BF78, (ASCII "Invalid License Key. Please try again or contact Wisdom Software.")
77D2F56D 55 push ebp
77D2F56E 8BEC mov ebp,esp
77D2F570 8B4D 08 mov ecx,dword ptr ss:[ebp+8]
77D2F573 56 push esi
77D2F574 E8 678FFEFF call USER32.77D184E0
留意此时的堆栈窗口:
0012F5A0 0054D397 /CALL 到 SetWindowTextA 来自 ScreenHu.0054D391
0012F5A4 0007060C |hWnd = 0007060C ('Invalid License Key. Please t...',class='Static',parent=000E05C4)
0012F5A8 0109C038 \Text = "Invalid License Key. Please try again or contact Wisdom Software."
0012F5AC 0044032D 返回到 ScreenHu.0044032D 来自 ScreenHu.0054D383
//在这一行,我们右键跟随到反汇编窗口,就找到了关键断,不过我没有细跟
//这里,我又试着另一种方法去分析!
0012F5B0 0109C038 ASCII "Invalid License Key. Please try again or contact Wisdom Software."
0012F5B4 00000001
0012F5B8 0070129C ScreenHu.0070129C
0012F5BC 0109C038 ASCII "Invalid License Key. Please try again or contact Wisdom Software."
0012F5C0 0012F700 指针到下一个 SEH 记录
0012F5C4 005A4218 SE 句柄
6、让我们想一想,程序是如何确定要显示程序前的这个注册窗口的呢??
所以在这个注册窗口运行起来之前必然有一个是否注册的判断,而我们只要找到这个判断的位置,我们也就可以十分容易的破解掉这个注册机制了!!!如何找到这个位置呢???呵,我常用的F12堆栈暂停法,又有了用武之地了……
7、在程序运行来那个注册窗口之后,稍等一下(等待其完全运行好),按F12暂停:
7C92E4F4 n> C3 retn
7C92E4F5 8DA424 0000000>lea esp,dword ptr ss:[esp]
7C92E4FC 8D6424 00 lea esp,dword ptr ss:[esp]
再然后打开堆栈调用窗口,如图:
在这一行上,点击右键->显示调用,来到反汇编窗口:
调用堆栈 ,项目 6
地址=0012FE34
堆栈=00467A7F
函数例程=ScreenHu.004034D6
调用来自=ScreenHu.00467A7A
00467A5C 50 push eax
00467A5D E8 95ADF9FF call ScreenHu.004027F7
00467A62 8B86 1C010000 mov eax,dword ptr ds:[esi+11C]
00467A68 83C4 04 add esp,4
00467A6B 3BC5 cmp eax,ebp
00467A6D 74 09 je short ScreenHu.00467A78
00467A6F E8 789FF9FF call ScreenHu.004019EC
00467A74 85C0 test eax,eax
00467A76 7F 07 jg short ScreenHu.00467A7F
00467A78 8BCE mov ecx,esi
00467A7A E8 57BAF9FF call ScreenHu.004034D6
//返回到这里:
//由此可知,此处调用是用来显示注册窗口的!(可以测试一下)
我们往上面找,在00467A5C处下断,然后重新载入程序,中断后单步运行,通过分析上面的代码,我们可以得出:
A、00467A6D处跳转不能实现,否则就直接跳向了注册对话框了,我们单步时,通过修改寄存器的ZF标志位,让其没有跳转
B、00467A76处的跳转必须跳,否则不能跳过注册对话框,同样的,通过修改寄存器的ZF标志位,让其实现
然后我们F9运行起程序来,果然没有了注册对话框,不过依然显示为未注册版(UNREGISTED!)
这说明直接改上面的跳转是不是行的了
8、重新载入程序,跟进上面一段代码里的两个CALL
A、call ScreenHu.004027F7,直接来到段尾:
0041C673 84DB test bl,bl
0041C675 74 12 je short ScreenHu.0041C689
0041C677 5E pop esi
0041C678 C705 743B7A00 >mov dword ptr ds:[7A3B74],0
0041C682 33C0 xor eax,eax
0041C684 5B pop ebx
0041C685 83C4 10 add esp,10
0041C688 C3 retn
0041C689 5E pop esi //如果能够跳到这里,必须是正确注册的了
0041C68A B8 01000000 mov eax,1
0041C68F 5B pop ebx
0041C690 83C4 10 add esp,10
我们单步时,会发现我们跳到了这里:0041C678
好了,开始我们的第1 个修改:
0041C678 C705 743B7A00 >mov dword ptr ds:[7A3B74],1
0041C682 B0 01 mov al,1
0041C684 5B pop ebx
0041C685 83C4 10 add esp,10
0041C688 C3 retn
B、call ScreenHu.004019EC
0041ADA0 A1 CC407A00 mov eax,dword ptr ds:[7A40CC]
0041ADA5 8B0D 24287900 mov ecx,dword ptr ds:[792824]
0041ADAB 56 push esi
0041ADAC 50 push eax
0041ADAD 51 push ecx
0041ADAE 33F6 xor esi,esi
0041ADB0 E8 21990E00 call ScreenHu.005046D6
0041ADB5 83C4 08 add esp,8
0041ADB8 85C0 test eax,eax
0041ADBA 75 07 jnz short ScreenHu.0041ADC3
0041ADBC B8 01000000 mov eax,1
0041ADC1 5E pop esi
0041ADC2 C3 retn
这个CALL里的修改更为直接,直接将0041ADBA 处的跳转NOP掉,然后运行起来,OK了!
然后把修改后的程序保存一份!
这样,一个破解过程就完成了,呵呵!!