Net内存程序集通用脱壳机实现原理(二、反射以及重建方法头)

简介: 在 .Net程序加密的原理及解密探讨三(实例解密)  一文中我们介绍了反射,主要提到三个函数 DumpAssembly,DumpType, DumpMethod。 这里我们将就 DumpMethod 这个函数讨论。


.Net程序加密的原理及解密探讨三(实例解密)  一文中我们介绍了反射,
主要提到三个函数
 DumpAssembly,DumpType, DumpMethod。

这里我们将就 DumpMethod 这个函数讨论。

前一篇我们已经提到的dump的整体流程。
先把PE整体dump出来,然后在文件后面增加一个段。

接下来就是这次要讲的反射和方法体重建。
依靠上面的三个函数反射枚举所有方法。

取得 MethodBody 对象,重建 方法体,将方法体保存到 PE文件新建的段中,修改元数据中该方法对应的RVA,指向刚保存的位置。
只修改元数据中方法的RVA值,元数据的大小不会改变,所以元数据最后可以直接写回到原始位置。

下面介绍方法体重建。

DotNet程序一个方法的函数体一般由三部份组成。
ILHeader + ILByteArray + [DataSection]
其中第三部份是可选的,有些方法只有前两个部分。

前面提到的 MethodBody.GetILAsByteArray 是函数体的第二部分。
所以现在的任务是重建第一部分和第三部份。
今回只介绍第一部分的重建。

ILHeader 分两种模式 Tiny的和 Fat的,Tiny的Header只有1字节,Fat的Header有12字节。
为了简便起见,我们可以全部重建为Fat的Header。

先看看 Fat Header的定义
typedef struct IMAGE_COR_ILMETHOD_FAT
{
    unsigned Flags    : 12;     // Flags
    unsigned Size     :  4;     // size in DWords of this structure (currently 3)
    unsigned MaxStack : 16;     // 
    DWORD   CodeSize;           // size of the code
    mdSignature   LocalVarSigTok;    
} IMAGE_COR_ILMETHOD_FAT;

红色的三项一共 4 字节。mdSignature   大小也是4字节。整个结构12字节。
1、Size 的值是 3,固定不变的。
2、MaxStack的值 取 MethodBody.MaxStackSize 即可。
3、CodeSize 的值就是 MethodBody.GetILAsByteArray 字节数组的长度。
4、LocalVarSigTok 的值 取 MethodBody.LocalSignatureMetadataToken 即可。

这个Fat Header的重建还是很容易的,现在只剩下 Flags 的值了。
这里我们只需要给 Flags 赋 三个标志值。
第一个 标识该函数体是 Fat 格式:0x03

第二个 标识该函数是否 InitLocals:0x10
我们可以通过 MethodBody.InitLocals 来判断是否需要增加一个标识值。

第三个 标识该函数是否有异常处理结构:0x08
这个可以通过 MethodBody.ExceptionHandlingClauses 这个列表的大小判断是否需要增加这个标识值。

如果函数没有异常处理结构,那么整个方法体的重建工作就完成了。
如果有,就需要继续重建 第三部份了。

而第三部份的重建就是依靠 MethodBody.ExceptionHandlingClauses  中的信息完成的。



目录
相关文章
|
3月前
|
NoSQL 测试技术
内存程序崩溃
【10月更文挑战第13天】
148 62
|
29天前
|
算法 Java 测试技术
Benchmark.NET:让 C# 测试程序性能变得既酷又简单
Benchmark.NET是一款专为 .NET 平台设计的性能基准测试框架,它可以帮助你测量代码的执行时间、内存使用情况等性能指标。它就像是你代码的 "健身教练",帮助你找到瓶颈,优化性能,让你的应用跑得更快、更稳!希望这个小教程能让你在追求高性能的路上越走越远,享受编程带来的无限乐趣!
86 13
|
2月前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
65 1
|
2月前
|
开发框架 监控 .NET
【Azure App Service】部署在App Service上的.NET应用内存消耗不能超过2GB的情况分析
x64 dotnet runtime is not installed on the app service by default. Since we had the app service running in x64, it was proxying the request to a 32 bit dotnet process which was throwing an OutOfMemoryException with requests >100MB. It worked on the IaaS servers because we had the x64 runtime install
|
2月前
|
存储 缓存 Java
结构体和类在内存管理方面的差异对程序性能有何影响?
【10月更文挑战第30天】结构体和类在内存管理方面的差异对程序性能有着重要的影响。在实际编程中,需要根据具体的应用场景和性能要求,合理地选择使用结构体或类,以优化程序的性能和内存使用效率。
|
3月前
|
存储 程序员 编译器
简述 C、C++程序编译的内存分配情况
在C和C++程序编译过程中,内存被划分为几个区域进行分配:代码区存储常量和执行指令;全局/静态变量区存放全局变量及静态变量;栈区管理函数参数、局部变量等;堆区则用于动态分配内存,由程序员控制释放,共同支撑着程序运行时的数据存储与处理需求。
182 21
|
4月前
|
C语言 Android开发 C++
基于MTuner软件进行qt的mingw编译程序的内存泄漏检测
本文介绍了使用MTuner软件进行Qt MinGW编译程序的内存泄漏检测的方法,提供了MTuner的下载链接和测试代码示例,并通过将Debug程序拖入MTuner来定位内存泄漏问题。
基于MTuner软件进行qt的mingw编译程序的内存泄漏检测
|
4月前
|
存储 缓存 Java
java线程内存模型底层实现原理
java线程内存模型底层实现原理
java线程内存模型底层实现原理
|
3月前
|
数据库连接 开发者
.NET 内存管理两种有效的资源释放方式
【10月更文挑战第15天】在.NET中,有两种有效的资源释放方式:一是使用`using`语句,适用于实现`IDisposable`接口的对象,如文件流、数据库连接等,能确保资源及时释放,避免泄漏;二是手动调用`Dispose`方法并处理异常,提供更灵活的资源管理方式,适用于复杂场景。这两种方式都能有效管理资源,提高应用性能和稳定性。
|
3月前
|
算法 Java 数据库连接
.NET 内存管理两种有效的资源释放方式
【10月更文挑战第14天】在 .NET 中,`IDisposable` 接口提供了一种标准机制来释放非托管资源,如文件句柄、数据库连接等。此类资源需手动释放以避免泄漏。实现 `IDisposable` 的类可通过 `Dispose` 方法释放资源。使用 `using` 语句可确保资源自动释放。此外,.NET 的垃圾回收器会自动回收托管对象所占内存,提高程序效率。示例代码展示了如何使用 `MyFileHandler` 类处理文件操作并释放 `FileStream` 资源。