使用Crypto Obfuscator嵌入带有继承的DLL

时间:2014-07-09 21:14:59

标签: c# dll obfuscation embedded-resource crypto-obfuscator

我正在开发一个项目,我们使用Crypto Obfuscator将多个DLL嵌入到单个DLL中。然后DLL在另一个项目中动态加载到自己的应用程序域中。大多数嵌入式DLL似乎都能正常工作。但是,任何包含主DLL类继承的类的嵌入式DLL都不能正确加载。我让这个工作的唯一方法是将DLL保留在目录中(这违背了嵌入它们的目的)。

例如:

我有四个不同的DLL:MyLibrary,MyLibrary2,MyProgram和MyInterfaces

MyLibrary DLL中的

MyClass1 类继承自MyInterfaces DLL内部的接口 ClassInterface

MyLibrary2 DLL中的

MyClass2 类继承自 MyClass1 。 Crypto Obfuscator用于在MyLibrary2 DLL中嵌入DLL:MyInterfaces和MyLibrary。

MyProgram DLL中的

MyProgramClass 类具有对MyInterfaces DLL的引用,并使用它动态创建 MyClass2 的实例。

当程序运行时,它会在尝试创建MyClass2实例时抱怨它无法找到程序集MyLibrary。

无法加载文件或程序集' MyLibrary,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null'或其中一个依赖项。系统找不到指定的文件。

任何想法如何解决这个问题?

MyInterfaces DLL:

namespace MyInterfaces
{
    public interface ClassInterface
    {
        string Get();
    }
}

MyLibrary DLL:

namespace MyLibrary
{
    public class MyClass : MarshalByRefObject, ClassInterface
    {
        public string Get()
        {
            return "2.0.0.0";
        }
    }
}

MyLibrary2 DLL:

namespace MyLibrary2
{
    public class MyClass2 : MyClass, ClassInterface
    {
        public string Get()
        {
            return base.Get();
        }
    }
}

MyProgram DLL:

namespace MyProgram
{
    public class MyProgramClass
    {
        public MyProgramClass()
        {
            try
            {
                string typeName = "MyLibrary2.MyClass2";
                string appDomainName = "MyLibrary2";

                ClassInterface c2 = CreateInstance(@"X:\Temp\MyLibrary2.dll", typeName, appDomainName);

                if (c2 == null) return;

                MessageBox.Show(c2.Get());
            }
            catch
            {
                MessageBox.Show(":(");
            }
        }

        private ClassInterface CreateInstance(string filePath, string typeName, string appDomainName)
        {
            try
            {
                AppDomainSetup appDomainSetup = new AppDomainSetup();
                FileInfo fileInfo = new FileInfo(filePath);

                if (!fileInfo.Exists) return null;

                appDomainSetup.PrivateBinPath = string.Format("{0}", fileInfo.Directory.FullName);
                appDomainSetup.PrivateBinPathProbe = "True";

                appDomainSetup.ApplicationBase = fileInfo.Directory.FullName;
                appDomainSetup.ApplicationTrust = AppDomain.CurrentDomain.ApplicationTrust;

                Evidence evidence = new Evidence(AppDomain.CurrentDomain.Evidence);
                AppDomain appDomain = AppDomain.CreateDomain(appDomainName, evidence, appDomainSetup);

                string assemblyName = Path.GetFileNameWithoutExtension(fileInfo.FullName);

                return appDomain.CreateInstanceAndUnwrap(assemblyName, typeName) as ClassInterface;
            }
            catch (Exception e)
            {                
                MessageBox.Show(e.Message);
            }

            return null;
        }
    }
}

更新1

我已经研究过使用AssemblyResolve事件。我试图在我的测试应用程序中实现它,看看我是否可以让它工作。我在AssemblyResolve事件中放置了一个断点,但它永远不会被击中并且仍然会抛出错误。如果我设置 MyClass2 不继承 MyClass1 ,我的断点将被命中并正确执行。

作为旁注,在包含嵌入式DLL的DLL上使用JustDecompile,似乎Crypto Obfuscator将此事件设置在DLL的默认命名空间中。

我曾经使用以下链接来实现AssemblyResolve事件: http://blogs.msdn.com/b/microsoft_press/archive/2010/02/03/jeffrey-richter-excerpt-2-from-clr-via-c-third-edition.aspx

MyLibrary2 DLL更改:

namespace MyLibrary2
{
    public class MyClass2 : MyClass, ClassInterface
    {
        static MyClass2()
        {
            AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;                
        }

        static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
        {
            String resourceName = string.Format("{0}.{1}.dll", "MyLibrary2", new AssemblyName(args.Name).Name);

            using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
            {
                Byte[] assemblyData = new Byte[stream.Length];

                stream.Read(assemblyData, 0, assemblyData.Length);

                return Assembly.Load(assemblyData);
            }
        }

        public string Get()
        {
            return base.Get();
        }
    }
}

0 个答案:

没有答案