设为首页 收藏本站
查看: 999|回复: 0

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

[复制链接]
累计签到:2 天
连续签到:1 天
发表于 2015-5-22 11:45:12 | 显示全部楼层 |阅读模式
Windows Phone 8加载外部动态链接库DLL(非安装包内的)
  在《动态加载与插件化》中大概介绍了下,wp8加载非安装包的下动态链接库,这次详细梳理下。
  加载外部DLL主要的原理:


  • 通过NtCurrentTeb获得线程环境块
  • 从线程环境块中获得进程环境块
  • 在进程环境块中加载过得DLL链表
  • 从链表中找到kernelbase.dll的模块句柄
  • 从kernelbase.dll中获得LoadLibraryEx函数地址
  • 加载指定地址下的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的例子
DSC0000.png
  动态库项目
  
  
DSC0001.png
  动态链接库逻辑

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

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-69546-1-1.html 上篇帖子: Windows Phone 8 本地代码实现游戏 下篇帖子: Windows 8 学习笔记(十五)--.Windows 8 RP Metro 墓碑机制思考
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表