序:Tankaiha在他的“用PEBrowse对.Net程序进行动态调试”中曾经提到过3种方法可以破解.NET程序,我下面介绍的方法,刚好是他说的第一种,但又不完全是。就是用.NET SDK中自带的调试程序\Microsoft.NET\SDK\v2.0\GuiDebug 对.NET的可执行文件直接进行调试。
因为.NET版本的不同,安装目录有所差别,都可以在1.1和2.0版本的目录里找到GuiDebug这个目录,里面的DbgCLR.EXE就是我今天要说的动态调试器。DbgCLR.EXE程序是我在破解.NET程序过程中,被逼无耐而到处狂翻,无意中找到的工具,而且经过自己的使用,知道了一些皮毛的用法,如果您是老手,还不要取消我J另:在上篇文章中,忘记告诉大家opcode类查找的地址,可找到opcode指令对应的16进制字节,这样可以方便的修改程序:http://msdn.microsoft.com/library/chs/default.asp?url=/library/CHS/cpref/html/frlrfSystemReflectionEmitOpCodesClassLdargTopic.asp一、
破解目标:crackeme.exe(为某些原因隐藏程序的名称),我会把附件上传到网络空间,给出地址。程序有注册号的限制,而且采用了代码混淆和反跟踪的手段。二、
破解工具:DbgCLR.EXE, Reflector在4.2.36.0三、
DbgCLR.EXE的一些简单设置和使用启动DbgCLR.EXE,是中文版本的,对我们而言很容易就能看懂,我只把几个关键地方提一下。如下图所示。1、设置调试配置如下:
点菜单中的“工具”——“选项”进行设置。如图一 图一点选项后出现下面的选择,选中下面的“如果源不可用,则显示汇编”。然后“确定”(下面图二是2.0版的显示)图二或者在1.1版中如下图三所显示图三注:把实时里的项目都选中2、加载程序:从菜单中选择“调试”---“要调试的程序”,从“程序”按钮中选择我们的需要调试的crackme.exe,然后“确定”就可以了。如下图四所示:图四选择并确定后,程序不会立刻运行,也不会象在OD中那样立刻分析代码,而是等待我们的下一部命令的输入,而且“调试”菜单中已经多了很多功能。如图五所示图五3、设置“异常”选项:可以根据程序的情况来设置,因为正在讨论的这个crackeme.exe采用了很多手段反跟踪等,所以我把异常里所有的选项都选择上了,并且激活。点图五菜单中的“异常”,图六调试器环境的设置都差不多了,可以进行下一部的跟踪了。四、
调试分析1、分析:用PEID查看,为Microsoft Visual C# / Basic .NET,所以用Reflector打开crackme.exe进行分析,发现Reflector不支持,crackme已经对代码进行了混淆(我把此crackme.exe发送给了Reflector的作者,所以Reflector在4.2.36.0版本以后开始支持此crackme混淆代码的处理,这也就是我最初破解采用动态跟踪这个程序的原因)改用《NET程序的破解(一)》中的Xenocode Fox 2006 Evaluation打开crackme.exe,发现crackme中很多代码都显示不出来,或者反编译出来的信息对我们基本没任何作用L,即使看到了里面很多reg信息有关的东西,还是没有任何的成型的代码让我们来分析,你的心凉了吗?最初在没发现DbgCLR这个工具的时候,我彻底陷入了悲哀中,用OD和SOFTICE调试.NET的程序,无疑就是一种炼狱生活。到现在我也很感叹对这个crackme进行混淆的人的水平,或者是我刚接触.NET,对.NET了解的太少了,记得Reflector的作者曾经问过我一句” What tool was this file obfuscated with?”,我告诉他我也很想知道。2、动态调试在图五中点“启动”或者“逐语句”“逐过程”都可以启动crackme,crackme启动中看来没有对注册信息的验证,点crackme中的“开始”按钮,才提示让你注册,出现注册框,如下图:
图七
在出现的对话框里,我们输入假的注册号”miaomiao”,点“确定”后,crackme会提示你重新启动验证,然后重新启动。第2次启动crackeme,然后点“开始”后,DbgCLR异常中断,出现提示框,问我们是否中断,选择“中断”后,程序立刻被断下来(多次调试后发现程序已经把我们注册过的信息写入了系统里,点“开始”后就对我们的输入的注册号进行了动态检测比较,并且采用了多处异常的方式来进行)。此时可以打开几个窗口,从“调试”—“窗口”中选择自己所需要的窗口,我习惯用下面的几个:
图八Crackme被中断后,看到图八中的“调用堆栈”里的数据,嘿嘿,你看到什么了?秘密就在这里,放大如图九:图九
在“调用堆栈”中任意双击其中的一个函数,对应的函数代码立刻在“反汇编”窗口里显示出来,显示的效果,跟Reflector里显示的结构很相似,也让我们很顺利的了解了程序的执行结构。哈,这正是我们所需要的;绿色箭头所指的,正是子程序要返回的位置,在我们需要的代码上点鼠标右键,选择“插入断点”,这样程序执行完现在的子程序返回后,就可以中断在这里了。
图十经过多次的跟踪分析,发现做如下的修改,就可以让程序正常运行而不再提示注册;如果要研究这个软件的注册算法,你就要自己去跟踪分析了J:NQQTools.CheckReg.Check00000093 0F B6 F0
movzx
esi,al
;修改mov al,0100000096 8B C6
mov
eax,esi
;修改为 mov esi,eax00000098 25 FF 00 00 00
and
eax,0FFh 0000009d 89 45 E0
mov
dword ptr [ebp-20h],eax 000000a0 90
nop
000000a1 EB 0E
jmp
000000B1 000000a3 C7 45 E0 00 00 00 00 mov
dword ptr [ebp-20h],0 ;修改为 mov [ebp-20],1000000aa E8 4B 6B 20 78
call
78206BFA 000000af EB 00
jmp
000000B1 NQQTools.Form1.button2_Click00000031 0F B6 F8
movzx
edi,al 00000034 85 FF
test
edi,edi 00000036 75 1E
jne
00000056 ;改为 jmp 56000000a0 8B CF
mov
ecx,edi 000000a2 E8 89 04 A3 78
call
78A30530 000000a7 0F B6 F8
movzx
edi,al 000000aa 85 FF
test
edi,edi 000000ac 74 0A
je
000000B8 ;修改为跳(注:在代码窗口里可以直接选取,然后从菜单“编辑”—“复制”里把代码复制出来)五、
总结程序的注册过程到现在我也没时间去研究了,对我来说注册不注册都不重要了,我写到这里的目的,也同样是告诉你们如何来动态跟踪.NET程序,除了Tankaiha所说的PEBrowseDbg动态跟踪方法外,这应该也算是一个不错的方法了,只要让.NET程序变成我们所熟悉的ASM代码结构,一切都显的那么自然。DbgCLR.EXE在调试程序的时候,并不一定非要到异常才能断下来的,这是我需要说明的一点,这是我对抗这个crackeme的策略而已。如果在调试其他程序的时候,断点的方法就要靠你们自己去发掘去了,记得有好的经验就告诉我J,我也在摸索中前进。我对这个混淆.NET代码的人真的很佩服,我曾经用winhex对代码的内存进行动态修改,结果发现内存中的代码类似于动态解码状态,就是函数执行完毕后,代码就没有了,需要执行加密函数时,代码又恢复出来了L,连做内存补丁的机会都不给我。哎,让我想起了论坛里Bi11's Simple Packer for some .net executables的压缩壳。