动态加载dll

动态加载dll

    static string passStr = "Dxl";
    static string targetPath = "Assets/Resources/DllTest/TestDll.bytes";
    static string dllPath = "Assets/Plugins/Test2019Dll.dll";
//将一个正常的dll变成一个加密的dll
    static void CreateBinaryDll(string dllPath)
    {
        //读取原始数据
        var fileStream = new FileStream(dllPath, FileMode.Open);
        var bytes = new byte[fileStream.Length];
        fileStream.Read(bytes, 0, bytes.Length);
        fileStream.Close();


        if(File.Exists(targetPath))
        {
            File.Delete(targetPath);
        }

        FileStream fs = new FileStream(targetPath, FileMode.Create);
        BinaryWriter bw = new BinaryWriter(fs);

        //加密位        
        byte[] passTemp = System.Text.Encoding.UTF8.GetBytes(passStr);

        //保存加密后的数据
        byte[] temps = new byte[bytes.Length + passStr.Length];

        //先写入加密数据
        for (int i = 0; i < passTemp.Length; ++i)
        {
            temps[i] = passTemp[i];
        }

        //再写入原始数据
        for (int i = 0; i < bytes.Length; ++i)
        {
            temps[i + passTemp.Length] = bytes[i];
        }                

        //写入数据
        bw.Write(temps);

        AssetDatabase.Refresh();
        Debug.Log("write over");

    }

接下来是动态加载部分

//加密字符,和生成加密文件时的密码一致
    string passStr = "Dxl";
    //加载加密的dll文件,先解密,再使用
    void LoadEncryDll()
    {
        //先解密,再调用
        TextAsset tx = Resources.Load<TextAsset>("DllTest/TestDll");
        if (tx == null)
        {
            Debug.Log("tx is null");
            return;
        }

        byte[] passTemp = Encoding.UTF8.GetBytes(passStr);
        byte[] dllbytes = new byte[tx.bytes.Length - passTemp.Length];
        for (int i=passTemp.Length; i<tx.bytes.Length;++i)
        {
            dllbytes[i - passTemp.Length] = tx.bytes[i];
        }

        Assembly assembly = Assembly.Load(dllbytes);

        if (assembly != null)
        {
            Type type = assembly.GetType("Test2019Dll.Class1");//类型

            //静态方法
            //public static void TestFunc1()
            MethodInfo method1 = type.GetMethod("TestFunc1");
            //public static void TestFunc2(string str)
            MethodInfo method2 = type.GetMethod("TestFunc2");
            //public static void TestFunc3(string str1, string str2)
            MethodInfo method3 = type.GetMethod("TestFunc3");
            //非静态方法
            //public void TestFunc4()
            MethodInfo method4 = type.GetMethod("TestFunc4");
            //public void TestFunc5(string str)
            MethodInfo method5 = type.GetMethod("TestFunc5");
            //void TestFunc6()
            MethodInfo method6 = type.GetMethod("TestFunc6", BindingFlags.NonPublic | BindingFlags.Instance);
            //void TestFunc7(string str)
            MethodInfo method7 = type.GetMethod("TestFunc7", BindingFlags.NonPublic | BindingFlags.Instance);


            //调用静态无惨方法
            method1.Invoke(null, null);
            //调用静态有参方法
            object[] pars2 = new object[1] { "hello,I'm test 2" };
            method2.Invoke(null, pars2);
            //调用静态有2个参数方法
            object[] pars3 = new object[2] { "hello1", "hello2" };
            method3.Invoke(null, pars3);

            //调用非静态方法
            object obj = Activator.CreateInstance(type);//绑定对象
            method4.Invoke(obj, null);
            object[] pars5 = new object[1] { "hello,I'm test 5" };
            method5.Invoke(obj, pars5);

            //调用私有方法
            method6.Invoke(obj, null);
            method7.Invoke(obj, pars5);
        }
        else
        {
            Debug.Log("oh ,on");
        }
    }
程序中加载了一个DLL文件,但生成的EXE在脱离了DLL文件后仍然可以 单独使用,这是动态加载DLL技术。即:调用资源中的DLL。 此技术的好处:EXE可以使用DLL中的函数,但不会额外增加一 个DLL文件,在使用DLL文件的时候不需要先把DLL释放到硬盘。 在动态加载的这个DLL中定义了一个函数MRun,该函数可以动态执行一 个EXE,即:调用资源中的EXE文件或TMemoryStream中被载入的EXE流。 此技术的好处:直接把资源中的EXE加载到内存中执行,使用程序自 身嵌入的EXE文件的时候不需要先把EXE释放到硬盘上就可以直接执行。 对保密EXE文件很有用。例如:我编写的程序是A.exe,它在运行后需要 使用B.exe,而B.exe是别人编写的我没有源码,但我必须又要在我的程 序中用B.exe,这时我就把它包含到我的A.exe中,这个非常容易做到, 但是,程序A.exe在使用程序B.exe的时候按照常理必须先把B.exe释放 到硬盘上才可以用WinExec或ShellExecute等函数调用它,但你在释放 到硬盘上的时候容易被别人直接复制走,而你只想让别人用你的A.exe不 想让别人直接用B.exe(因为B.exe是别人写的等原因),此时如何保密 B.exe呢?这时只要用到上面所说的MRun函数就可以了,程序A.exe在执 行B.exe的时候不需要释放到硬盘上就可以直接执行B.exe啦,是不是很爽? 说一下MRun的调用方式: MRun(流,参数,进程id); 调用成功返回True,失败返回False,三个参数解释如下: 第一个参数:一个载入了EXE的资源流或者内存流等流类型。 第二个参数:传递调用EXE的参数。如果EXE调用不需要参数,可设置为空串。 第三个参数:如果调用成功,则返回被调用的EXE对应的进程ID。 细节性问题,请直接双击Project1.dpr文件进入演示代码,了解更多。演示代 码中动态加载了MemRun.dll文件,动态调用了5555044.exe文件,如果你想更换 动态调用的EXE文件,只需要用其它EXE覆盖5555044.exe文件并双击Clear.bat 文件后,在Delphi中按F9重新编译运行即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值