Windows Phone 8加載外部動態連接庫DLL(非安裝包內的)

Windows Phone 8加載外部動態連接庫DLL(非安裝包內的)

在《動態加載與插件化》中大概介紹了下,wp8加載非安裝包的下動態連接庫,此次詳細梳理下。html

加載外部DLL主要的原理:函數

  1. 經過NtCurrentTeb得到線程環境塊
  2. 從線程環境塊中得到進程環境塊
  3. 在進程環境塊中加載過得DLL鏈表
  4. 從鏈表中找到kernelbase.dll的模塊句柄
  5. 從kernelbase.dll中得到LoadLibraryEx函數地址
  6. 加載指定地址下的DLL

相關的結構體:spa

typedef struct _CLIENT_ID  插件

{   線程

    PVOID UniqueProcess;   3d

    PVOID UniqueThread;   code

} CLIENT_ID;   orm

 

//模塊鏈表實體htm

typedef struct _MODULE_LIST_ENTRYblog

{

    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

相關文章
相關標籤/搜索