• Windows Phone 8加载外部动态链接库DLL(非安装包内的)


    Windows Phone 8加载外部动态链接库DLL(非安装包内的)

    在《动态加载与插件化》中大概介绍了下,wp8加载非安装包的下动态链接库,这次详细梳理下。

    加载外部DLL主要的原理:

    1. 通过NtCurrentTeb获得线程环境块
    2. 从线程环境块中获得进程环境块
    3. 在进程环境块中加载过得DLL链表
    4. 从链表中找到kernelbase.dll的模块句柄
    5. 从kernelbase.dll中获得LoadLibraryEx函数地址
    6. 加载指定地址下的DLL

    相关的结构体:

    typedef struct _CLIENT_ID 

    {  

        PVOID UniqueProcess;  

        PVOID UniqueThread;  

    } CLIENT_ID;  

     

    //模块链表实体

    typedef struct _MODULE_LIST_ENTRY

    {

        struct  _MODULE_LIST_ENTRY* Flink;

        struct  _MODULE_LIST_ENTRY* Blink;

        DWORD* baseAddress;

    }MODULE_LIST_ENTRY;

     

    //进程加载的模块信息

    typedef struct _PEB_LDR_DATA

    {

    //    BYTE fill[0x1c]; x86

        ULONG Length;

        BOOLEAN Initialized;

        PVOID SsHandle ;

        LIST_ENTRY InLoadOrderModuleList;

        LIST_ENTRY InMemoryOrderModuleList;

        MODULE_LIST_ENTRY* initModuleList;

    }PEB_LDR_DATA;

     

    //进程环境块

    typedef struct _PEB

    {

    //    BYTE fill[0x0c]; x86

        BYTE Reserved1[2];

        BYTE BeingDebugged;

        BYTE Reserved2[1];

        PVOID Reserved3[2];

        PEB_LDR_DATA* ldr;

    }PEB;

     

    //线程环境块

    typedef struct _TEB

    {

        //BYTE fill[0x30]; x86

        NT_TIB nt_tib;

        PVOID EnvironmentPointer;

        CLIENT_ID id;

        PVOID ActiveRpcHandle;

        PVOID ThreadLocalStoragePointer;

        PEB* currentPEB;

    }TEB;

     

    typedef HMODULE(*LoadLibraryEx)(

        LPCTSTR lpLibFileName,

        HANDLE hFile,

        DWORD dwFlags

        );

    获取kernelbase.dll模块句柄的类定义

    namespace Anye
    {
        namespace Native
        {
            public ref class DllHandle sealed
            {
                friend ref class NativeInterop;
                friend class NativeHelper;
            public:
                int GetModule();
            private:
                HMODULE _handle;
                DllHandle(HMODULE handle);
    
                    //获取指定名称的函数地址
                void* GetFunction(LPCSTR name);
            };

     

            public ref class NativeInterop sealed
            {
            public:
                NativeInterop();
                //加载指定路径下的DLL
    
                DllHandle^ LoadLibrary(Platform::String^ name);
    
        //获取KernelBase.dll的模块句柄
                DllHandle^ GetKernel();
                int GetModule();
            private:
                DllHandle^ _kernel;
                LoadLibraryEx _loadLibrary;
                HMODULE getKernelModule();
            };

     

            class NativeHelper
            {
            public:
                NativeHelper(const wchar_t* path);
                void* GetFunction(LPCSTR name);
            private:
                DllHandle^ _interop;
            };
            
    
        }
    }

    主要的加载逻辑

    HMODULE NativeInterop::getKernelModule()
    {
    
        //获取线程环境快
        TEB* teb = NtCurrentTeb();
        获取KernelBase.dll的模块句柄PS:保险点的方法市历遍DLL初始化链表通过模块名称确定
        return (HMODULE) teb->currentPEB->ldr->initModuleList->Flink->baseAddress;
    }

     

    DllHandle^ NativeInterop::LoadLibrary(Platform::String^ name)
    {
        if (_loadLibrary == nullptr)//获取LoadLibraryExW函数地址
            _loadLibrary = (LoadLibraryEx)_kernel->GetFunction("LoadLibraryExW");
        
    
        HMODULE module = _loadLibrary(name->Data(), nullptr, 0);
        if (module != nullptr)
            return ref new DllHandle(module);

     

        return nullptr;
    }
    

     

    void* DllHandle::GetFunction(LPCSTR name)
    {
        return GetProcAddress(_handle, name);
    }

     

    NativeHelper

    NativeHelper::NativeHelper(const wchar_t* path)
    {
        auto inter = ref new NativeInterop();
        String^ pathString = (Platform::String^)Platform::StringReference(path);
        _interop = inter->LoadLibrary(pathString);
    }

     

    void* NativeHelper::GetFunction(LPCSTR name)
    {
        return _interop->GetFunction(name);
    
    }

    下面是加载wp手机SD卡上的plugin.dll的例子

    动态库项目

     

    动态链接库逻辑

    extern "C"
    {
        __declspec(dllexport) void* Create();
    }

     

    namespace Plugin
    {
        class IPlugin
        {
        public:
            virtual void Show(Platform::String^ msg) = 0;
        };

     

        class TestPlugin : public IPlugin
        {
        public:
            TestPlugin()
            {

     

        }

     

            void Show(Platform::String^ msg)
            {
            (ref new Windows::UI::Popups::MessageDialog(msg))->ShowAsync();
            }
        };
    }

     

    void* Create()
    {
        return new Plugin::TestPlugin();
    }

    加载外部动态链接库

    class IPlugin
    {
    public:
        virtual void Show(Platform::String^ msg) = 0;
    };
    void NativeEntry::Load(Platform::String^ path)
    {    //path  D:\Downloads\plugin.dll,D盘就是sd
        Anye::Native::NativeHelper* h = new Anye::Native::NativeHelper(path->Data());
        CreateFunc func; 
    
        func = (CreateFunc)h->GetFunction("Create");

     

        IPlugin* plugin = (IPlugin*)func();

     

        plugin->Show("我是"+path+"里的插件^_^");
    }

    好了例子就到这了,我们获得了LoadLibraryExW函数,不局限于加载外部DLL,也可以去加载系统的DLL,去访问一些微软未公开的API,如只读访问注册表信息

    Anye::Native::NativeInterop interop;
        auto h = interop.LoadLibrary("ADVAPI32LEGACY.DLL");

     

        Anye_RegCreateKeyEx = (RegCreateKeyFunc)GetFunc(h->GetModule(), "RegCreateKeyW");
        Anye_RegSetValueEx = (RegSetValueFunc)GetFunc(h->GetModule(), "RegSetValueW");
        Anye_RegQueryValueEx = (RegQueryValueFunc)GetFunc(h->GetModule(), "RegQueryValueW");
        Anye_RegCloseKey = (RegCloseKeyFunc)GetFunc(h->GetModule(), "RegCloseKey");
        Anye_RegOpenKey = (RegOpenKeyFunc)GetFunc(h->GetModule(), "RegOpenKeyW");
        Anye_RegEnumKey = (RegEnumKeyFunc)GetFunc(h->GetModule(), "RegEnumKeyW");

     源码:https://onedrive.live.com/redir?resid=30D5EB407F085DD8!31587&authkey=!ABzmTswcDh91WQw&ithint=file%2czip

  • 相关阅读:
    Django ORM 进行查询操作和性能优化
    Python PIL 长文本换行,二维码,图片合成
    python 常用的资料链接
    人生苦短,我用Python
    windows下搭建Python virtualenvvirtualenvwrapper虚拟环境。
    Python 文件上传base64图片
    python实现中文转换url编码的方法
    同时装了Python3和Python2,怎么用pip?
    统计当天下单量
    Django ORM 级联删除
  • 原文地址:https://www.cnblogs.com/anye6488/p/3915852.html
Copyright © 2020-2023  润新知