【.Net】.Net程序 OEP
概述:.Net 程序OEP(静态分析,调试)
相关参考
Stack OverFlow:
文章:
本文环境:
- Win10
- .Net 运行库:.NET Framework 4.7.2
OEP
OEP(Original Entry Point,原始入口点)通常指的是程序在没有被加壳或加密的情况下,代码的正常执行起点。当一个软件被加壳保护之后,其执行起点会被改为壳的代码段,真正的程序代码(也就是我们说的OEP)会被加密或者压缩存放在其他位置,只有在适当的时机下才会被解密和加载出来执行。
Visual Studio 工具中提供了 DumpBin 可以用来查看程序入口点,结合 windbg 调试可以看到具体的入口点出的执行情况
1 |
|
.Net 程序
众所周知,.Net 编译出来的文件是中间文件,只有在执行时才会编译为机器码。而且由于跨平台的特性,在启动上有很多不同于 C++ 的方式。可以说,.Net 程序并没有 OEP 这个概念(.Net 程序的OEP是固定且不能修改的)。
用 x32dbg 调试某 .Net Exe 程序,在单步启动后,可以看到相关信息如下所示的日志数据:
显示入口点位于 00588B1A
处(目前来看,这行代码是不能中断的):
汇编代码如下所示:
如上所示的跳转,在每个 .Net 编译出来的 PE 文件中都有。借 c# - does .net dll have an entry point like dll in c++ dll - Stack Overflow 回答中的描述,每个 .Net 程序都包括一个 5 bytes 大小(x64下为 9 bytes)的非托管入口,正是上图所示的跳转。这行跳转会交由系统,最终执行到 mscoree.dll 的入口,最终跳转到哪个接口则是取决于当前进程是 Exe 还是 dll。如果是 Exe,则跳转到 _CorExeMain_Exported
,如果是 dll,则跳转到 _CorDllMain_Exported
。之后 mscoree 则会根据源程序的清单文件决定加载哪些 DLL 文件。
对应上图,此时,当前进程已经加载了如下所示的系统动态库:
仅仅一行跳转,就执行了这么多操作,相对来说这个过程还是比较复杂,具体还要看 mscoree 是如何处理的。所以也导致 Hook .Net 程序的 OEP 会失效问题。
如果要从 mscoree 开始调试,则需要再 MSCOREE!_CorExeMain_Exported
添加断点,建议使用 windbg。
备注:wntdll
AssemblyRef
在 .Net 程序清单中,AssemblyReg 位于元数据表 存储流
中 表流
中。AssemblyRef 表明了当前程序集依赖哪些其他程序集。