我有一个客户端应用程序,一旦用户通过我的服务器进行身份验证,它就会发送一个字节数组,然后使用 Assembly.Load 加载它。我很确定一旦发生这种情况,即使加载的字节从内存中转储,它们也不能用于重新构建源代码。我只是想确认一下,或者获取更多信息,以防我错了。
谢谢!
我有一个客户端应用程序,一旦用户通过我的服务器进行身份验证,它就会发送一个字节数组,然后使用 Assembly.Load 加载它。我很确定一旦发生这种情况,即使加载的字节从内存中转储,它们也不能用于重新构建源代码。我只是想确认一下,或者获取更多信息,以防我错了。
谢谢!
为了模仿所描述的场景,我编写了一些简单的示例代码:
using System.IO;
using System.Reflection;
namespace DumpAssembly
{
class Program
{
static void Main(string[] args)
{
var rawAssembly = File.ReadAllBytes("Test.dll");
var assembly = Assembly.Load(rawAssembly);
foreach(var type in assembly.ExportedTypes)
{
if (type.Name == "Test")
{
var method = type.GetMethod("DoCoolStuff");
method.Invoke(null, null);
break;
}
}
}
}
}
将生成的程序集放到 dnSpy 中,开始调试并逐步执行 Main 方法。很快您就可以保存新加载的模块:
保存模块后,在 dnSpy 中打开它很容易泄露您的知识产权:
现在,部分解决方案是使用ConfuserEx之类的东西来混淆你的模块(它是开源的,商业产品可用)。这可能会减慢您的攻击者的速度,但假设他们无法在合理的时间内反编译和理解您的代码是幼稚的。