-=Msdn5 君临 =- Net破解里不得不说的秘密系统环境:
Win7x64
调试工具:
Vs2010
OllyDbg
0x00 .Net运行机制
0.1 OEP是啥
AddressOfEntryPoint 说白了就是程序入口点
程序第一次进入的地方,这玩意儿就是OEP.
学习更多的知识,请自行搜索PE结构
0.2 Net的OEP长啥样?
在.net编程开发中也就是Main函数
咱们在汇编下看,OEP长啥样,
打开VS 2010 在入口函数下断点(F9)
记得生成的工程得是X86的..不然anycpu会生成X64的..回头看汇编的时候那酸爽..
工程,右键,属性..选择生成选项卡,然后切换到X86模式
F5 让程序跑起来
此时对着空白处右键 “转到反汇编”
到反汇编选项卡中.可以看见熟悉的汇编代码了…
从第一个push 开始,这就是.net OEP的长相..是不是看起来很怪.
然后咱们还需要一些配置…打开堆栈,寄存器,还有模块
接着你就会看见和OD差不多的界面了…..
就是堆栈有点不一样,看起来很怪.不会直接显示堆栈信息,因为有CLR的交互.
VS 先不要关闭…
这时候使用OD载入程序,啥也断不下来.程序绝逼跑飞…
为啥会这样…?
载入程序至CFF
选择引入目录,可以看见就加载了 mscoree.dll , 而且就一个函数 _CorExeMain
默认_CorExeMain可不会被断下来..
接着在Command 窗口bp _CorExeMain 下这个函数的断点.
然后重新载入程序.ctrl+f2
别着急,向下翻翻.注意下当前的模块,也就是程序的领空 现在并不是在程序领空
C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorwks.dll
这玩意儿的作用:
在用reflector查看dotnet类库源代码时经常会遇到一些函数看不到源代码,只是标记成内部实现。这些函数基本上实际实现的代码就在这个dll里面,是native实现的。如反射功能的相关对象以及实现就是这里面。
也就是常说的CLR环境.
net程序的执行主要由它来完成,还有另外一个重要的文件mscorjit.dll 被它所调用。
现在我们把mscorwks.dll 分成两个区 A 和 B,
A 是主要执行引擎(ee)和native 实现。
B 是ee调用jit的处理部分。
net2.0的反射功能是在A区实现的。加密壳如果要实现完美的兼容性(即不破坏DotNet本身的任何功能和特性)就应该在 A 区挂入其内核。
在A区有一个函数实现获取方法体的内容,ee层需要取得方法体内容是通过这个函数来获得的。因此完美的方法就是替换这个函数,用加密壳的内核实现这个函数。
这样的最大缺点就是反射漏洞,因为反射也是调用这个函数取得方法体的。
在这个基础上要要破坏反射有什么办法呢?
在反射是需要调用Method的成员函数GetMethodBody,这个函数是native实现的,就在mscorwks。dll中,因此加密壳可以hook这个函数做一些预防处理。
但是效果不理想,咱们可以恢复这个函数的原始实现.
在这个基础上要要破坏反射有什么办法呢?
在反射是需要调用Method的成员函数GetMethodBody,这个函数是native实现的,就在mscorwks.dll中,因此一些混淆工具可能hook这个函数做一些预防处理,所以在它干活之前你懂的….
向下翻翻,就走到最终被编译的位置了.
Push eax的地方,其实就是加载ctor了…
先不着急,一直向下走.
6928F523 E8 33FAFFFF callmscorwks.6928EF5B 这个地址就是程序要加载起来运行了..
F7单步 跟进这个Call
然后使用API断点下CreateWindowExA 也可以bp下
断下后,第一个Call就是在准备创建窗口了,走完这个Call Net程序就是真正意义上运行起来了.
回到模块,进入程序领空
可以尝试分析下代码,第一句就是加载_CorExeMain函数.不过在这下断点没任何用…
向下翻翻,你可以看见很多好东西..^_^
当程序跑起来的时候你会看见很多叫ctor的方法名,
辣么,ctor 又是啥玩意儿…将程序载入到ILSPY,用我汉化的那个也行,或者原版的也行;
任意一个反编译.NET的程序都可以看见.
然后转换到IL代码..
其实每一次调用的东西都会走到底层去,可以清楚的看到是由谁来实现的这些方法.
现在,我们来改造一下程序代码.更好的理解.net运行的汇编
窗体很简单.
窗体加载完成后(OnLoad的时候)弹个提示框,顺手写个点击域名打开论坛的方法.(调用默认浏览器)
顺便在26行下断.启动程序后直接右键转到反汇编
注意下
00000038 mov eax,dword ptr ds:[034020A0h]
因为我们没法看到堆栈信息,但是.Net推送这些信息的时候都会存放在Eax寄存器
按照之前的方法打开寄存器窗口.复制当前EAX的值.然后在内存窗口监视
在内存窗口中右键,选择Unicode文本,可以看见当前的信息了.
用OD对比调试下
记得下MessageBoxW 的断点
堆栈信息可以看见,前面几个push获取文字信息的地址,最后得到欢迎消息
可以发现,在VS调试程序的时候和OD完全不是一个样.
OD调试的是带着CLR的.而VS调试是直接得到当前的汇编语句,如果希望更深刻的理解Net汇编后还是推荐大家用VS调试..当然,爆破除外.
再次改造代码.做个简单的判断.继续到反汇编
有对照的看,是不是省事多了..
将123的值放到了EDX
接着你可以很清晰的看见判断的正确数据.
前面两个mov 分别把欢迎消息和123 分别给了edx和ecx.
然后下面的CALL就开始比较.接着给eax赋值.这里等同Z标志位是0还是1.
各位看官在自行尝试的时候会发现
00000066 cmp dword ptr [ebp-48h],0 这里直接就会跳到false
也就是,并没有执行jnz的判断
0000007d nop MessageBox.Show(str); 0000007e mov ecx,dword ptr [ebp-44h] 00000081 call 6538E980 原因就是因为执行了cmp,其他jnz就已经得到了标志位..所以如果不明白请自行百度下CMP指令
换到OD看下
在这之前,先改造下代码.让它先弹出,这样比较好分析后面的代码
弹窗时可以自己算下在内存里欢迎信息的位置.
F7出CALL.
进入主线程
F9 继续跑飞程序,然后会在下一次弹窗被断下.然后单步出CALL.上面就是判断的地方了.
当然,如果追CM的码可以用回朔慢慢分析.遇见JMP千万别直接就跑了..OD调试起来很费劲.还有要注意MOV EDX 和mov exc 会经常把判断和交换的数据丢在这俩寄存器.
想知道如何追码的,看画眉的帖子吧…http://www.52pojie.cn/thread-365683-1-1.html
代码以及文档打包下载
Msdn5Unpack.zip
(1.6 MB, 下载次数: 65)
由于作者身在祖国的敏感地区,所有运营商无耻的屏蔽了各种分享(百度云,腾讯云,360云盘)...且屏蔽52破解(发贴和看内容都得出国...)所以只能上传附件了..有热心的小伙儿来个分享,不胜感激.
|