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

Windows Phone 8加载外部动态链接库DLL(非安装包内的)的更多相关文章

  1. PhoneGap 白名单安全机制 navigator.app 加载外部页面返回以及退出介绍

    一. Phonegap 白名单安全机制 Phonegap应用的页面大多存在于本地,但有时需要加载外部的Web页面到应用内置的浏览器 视图中已完成特定的应用功能,出于安全性考虑,PhoneGap 设立了 ...

  2. 背水一战 Windows 10 (11) - 资源: CustomResource, ResourceDictionary, 加载外部的 ResourceDictionary 文件

    [源码下载] 背水一战 Windows 10 (11) - 资源: CustomResource, ResourceDictionary, 加载外部的 ResourceDictionary 文件 作者 ...

  3. windows 通过AppInit加载任意dll

    windows操作系统允许将用户提供的dll加载到所有的进程的内存空间中.该功能可以用来做后门持久化.有点类似于linux的ld_preload环境变量.在进程启动的时候,操作系统会将用户提供的dll ...

  4. Silverlight实用窍门系列:2.Silverlight动态加载外部XML指定地址的WebService---(动态加载外部XML文件中指定的WebService地址)【附带实例源码】

    接上节所讲的,Silverlight可以加载外部的XML文件里面的内容,那么我们可不可以在外部XML里面配置一个WebService地址,并且以此加载这个地址来动态加载WebService呢?这样子就 ...

  5. 其原因可能是堆被损坏,这说明**.exe中或它加载的任何DLL中有Bug

    最近在写一个写日志文件的线程时,调用了HeapAlloc/HeapFree 申请/释放堆缓冲内存.调用HeapFree释放有个条件就是,日志的空闲缓冲队列中内存块超过100个.在测试的时候,发现调用H ...

  6. 资源: CustomResource, ResourceDictionary, 加载外部的 ResourceDictionary 文件

    CustomResource ResourceDictionary 加载外部的 ResourceDictionary 文件 示例1.演示“CustomResource”相关知识点Resource/Cu ...

  7. AppDomain加载与释放dll

    AppDomain加载与释放dll 几年前写过同名随笔,但今天应不大适用了.但还有几个朋友留言关注,我重新发布相关代码. 首先我们的目的就是运行期间更新dll,并应用dll.这个过程需要应用 AppD ...

  8. 【Win 10 应用开发】加载外部的 srt 字幕

    据说系统内置的多媒体功能支持 srt. ssa 等字幕,老周测试过几种格式的字幕均能加载. SRT 字幕是最简单的字幕结构,甚至你用记事本都能做出来,就是分为几行来写. 第一行是字幕的编号,应该是从1 ...

  9. 删除 Windows 旧 OS 加载器

    装过多个系统,然后又删除掉了,系统启动引导时,又把以前的废弃的系统引导给带了出来,试过多种方式,以下方法是最好的. 开始->运行->cmd bcdedit /v 查看要删除的"W ...

随机推荐

  1. cordova APP 检查更新

    原文:cordova APP 检查更新 //升级程序 .factory('UpdateService', function ($rootScope, $cordovaAppVersion, $cord ...

  2. NET媒体文件操作组件TagLib

    开源的.NET媒体文件操作组件TagLib#解析   人生得意须尽欢 莫使金樽空对月.写博客都会在吃饭后,每次吃饭都要喝上二两小酒,写博客前都要闲扯,这些都是个人爱好,改不掉了,看不惯的人,还望多多包 ...

  3. 【29.41%】【codeforces 724D】Dense Subsequence

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  4. Dual Dijkstra search for planning multiple paths

    The dual Dijkstra search for planning multiple paths is performed by: (1) calculating a first shorte ...

  5. zlib minizip 实现解压zip

    #include <stdio.h> #include <string.h> #include "unzip.h" #define dir_delimter ...

  6. solr+ Eclipse 4.3+ tomcat 7.5 +winds7(一)

    这种方法是我自己依据对tomcat运行项目流程和solr的运行流程来自己弄的,所以有点麻烦,请到原地址查看心血谢谢:http://blog.csdn.net/chunlei_zhang/article ...

  7. springCloud跨域访问

    转自:http://blog.csdn.net/wangkang80/article/details/72829390 什么是跨域? 假设你在http://xxx.com/test/下有一个js文件, ...

  8. uwp - RichEditBox 解决设置字体样式后滚动条自动回滚顶部的问题

    原文:uwp - RichEditBox 解决设置字体样式后滚动条自动回滚顶部的问题 开发中碰到一个问题,当RichEditBox输入的文本达到一定行数的时候,滚动条此时位于底部,改变文本样式(如字体 ...

  9. 创建asp.net core 的静态网站

    这个名字听起来很怪 既然是静态网站 为什么要是asp.net core的呢? 1.在vs上面好像不能创建纯静态的网站,所以我们就想创建一个asp.net core的空网站 然后在里面使用静态的html ...

  10. wpf中的倒影效果实现

    原文:wpf中的倒影效果实现        <TextBox Name="txt"                      FontSize="30" ...