dotnet/runtime有一个issue[1]讨论了如何使用ModuleInitializer
投放恶意代码,但是微软的开发经理表示不背这个锅!
什么是ModuleInitializer?
ModuleInitializerAttribute[2]是在.NET5.0中新增加的API。它的作用是应用于编译中的任意数量的静态方法, 标记的方法保证在调用任何其他方法或在整个模块中访问字段之前运行。
针对此属性的方法必须满足下列要求:
方法必须是
static
方法必须是普通成员方法,而不是属性访问器、构造函数、本地函数等
方法必须是无参数的
该方法必须返回 void
方法不能是泛型或包含在泛型类型中
此方法的有效可访问性必须为 internal 或 public
Demo
创建一个ConsoleApp1项目和ClassLibrary1项目,ConsoleApp1引用ClassLibrary1,目标框架都要选择 .NET 5.0。
代码如下:
//ClassLibrary1
public class Class1
{
public void Test()
{
Console.WriteLine("执行Test方法");
}
}
class Class2
{
[ModuleInitializer]
internal static void Hack()
{
Console.WriteLine("执行恶意代码!");
}
}
//ConsoleApp2
static void Main(string[] args)
{
Console.WriteLine("公众号“My IO”");
new Class1().Test();
}
运行效果如下图,可以看到ModuleInitializer标记的方法在所有其他方法之前执行了,虽然并没有任何代码显式调用它:
结论
实际上,无论是否使用ModuleInitializer,都可以在代码中隐藏恶意代码,只是这种方式隐蔽性会更高一些。 试想一下,存在一大堆类的情况下,即使你反编译了源代码,也不容易注意到隐藏在角落的恶意代码。
最好的解决方案是只使用可信任来源的第3方库。
说实话,个人感觉增加这个特性的意义不大,反而显式初始化更容易控制和理解。
欢迎关注我的个人公众号”My IO“
参考资料
[1]
issue: https://github.com/dotnet/runtime/issues/43328#issuecomment-858422230
[2]ModuleInitializerAttribute: https://docs.microsoft.com/zh-cn/dotnet/api/system.runtime.compilerservices.moduleinitializerattribute?view=net-5.0