飘云 发表于 2014-2-5 00:46:14

内存加载模块 -- 飘云测试通过


模块代码过长,详见附件~~测试很稳定,支持win764bit    我已经封装了几个函数方便使用,见测试代码
测试代码:

//MyDll.h

extern "C"
{
      __declspec(dllexport) int AddFun(int a, int b);
      __declspec(dllexport) void GotoPYG(char *url);
}

//MyDll.cpp
#include <windows.h>
#include "MyDll.h"

int AddFun(int a, int b)
{
      return a + b;
}

void GotoPYG(char *url)
{
      ShellExecute(NULL,"open", url, "", "", SW_SHOW );
}

/************************************************************************/
/* 函数名称: GetMemoryDllPointer                                        */
/* 函数功能: 获取内存DLL指针                                          */
/* 函数参数: WORD wResID---资源IDchar *szFileType -- 资源类型         */
/* 函数返回: 内存DLL指针位置                                          */
/* 函数封装: 飘云/P.Y.G -- WWW.CHINAPYG.COM                           */
/************************************************************************/
LPVOID GetMemoryDllPointer(WORD wResID, char *szFileType)
{   
    // 先取出资源文件
    HRSRC hRsrc =FindResource(NULL, MAKEINTRESOURCE(wResID), szFileType);
      if (!hRsrc)
                return NULL;
      
    DWORD dwSize = SizeofResource(NULL, hRsrc);
      if (!dwSize)
                return NULL;
      
      HGLOBAL hG = LoadResource(NULL, hRsrc);
      if (!hG)
                return NULL;
      
      //FreeResource(hG);
      // 加载DLL到内存
      return MemoryLoadLibrary(hG);
}

/************************************************************************/
/* 函数名称: GetMemoryDllFunPointer                                     */
/* 函数功能: 获取内存DLL某导出函数指针                                  */
/* 函数参数: LPVOID lpMemoryDll -- 内存DLL指针 char *szFunName -- 函数名*/
/* 函数返回: 内存DLL导出函数指针                                        */
/* 函数封装: 飘云/P.Y.G -- WWW.CHINAPYG.COM                           */
/************************************************************************/
LPVOID GetMemoryDllFunPointer(LPVOID lpMemoryDll, char *szFunName)
{   
      return MemoryGetProcAddress(lpMemoryDll, szFunName);
}

/************************************************************************/
/* 函数名称: FreeMemoryDll                                              */
/* 函数功能: 释放内存DLL                                                */
/* 函数参数: LPVOID lpMemoryDll -- 内存DLL指针                        */
/* 函数返回: 无                                                         */
/* 函数封装: 飘云/P.Y.G -- WWW.CHINAPYG.COM                           */
/************************************************************************/
VOID FreeMemoryDll(LPVOID lpMemoryDll)
{   
      MemoryFreeLibrary(lpMemoryDll);
}


// DLL导出函数原型
typedef int (*AddProc)(int, int);
typedef void (*GotoPYGProc)(char*);

VOID TestIt()
{
      char str = {0};
      
      HMEMORYMODULE lpMemoryDll = (HMEMORYMODULE)GetMemoryDllPointer((WORD)MYDLL, "DLL");

      if(!lpMemoryDll)
                return;

      // 类型转换
      AddProc AddFun = (AddProc)GetMemoryDllFunPointer(lpMemoryDll, "AddFun");
      GotoPYGProc GotoPYG = (GotoPYGProc)GetMemoryDllFunPointer(lpMemoryDll, "GotoPYG");
      
      // 调用DLL导出函数
      sprintf(str,"调用内存DLL导出函数: AddFun(10,20) = %d",AddFun(10, 20));
      GotoPYG("www.chinapyg.com");
      
      ::MessageBox(NULL, str, "提示", MB_OK);

      FreeMemoryDll(lpMemoryDll);
}

void CTestDlg::OnTest()
{
      // TODO: Add your control notification handler code here
      TestIt();
}





sdnyzjzx 发表于 2014-2-5 17:47:48

这个是一定要学习的。

sunflover 发表于 2014-2-6 11:03:38

这是不是传说中的ReLoadAndRun大法?
建议下次把bin源码也附件打包了,省的自己去新建工程,文件,复制代码等等.

xingbing 发表于 2014-2-6 16:26:31

好东西,学习

yusheng 发表于 2014-2-21 07:11:45

非常感谢楼主,我一直想研究这个

yusheng 发表于 2014-2-21 12:36:42

有个问题哎……
HANDLE hFile = CreateFile(L"c:\\windows\\syswow64\\user32.dll",...);
HANDLE hMap = CreateFileMapping(hFile,0,PAGE_READONLY,...);
LPVOID buffer = MapViewOfFile(...);
HMEMORYMODULE hDll = MemoryLoadLibrary(buffer);   //这里调用DLLMAIN会失败,请问为何呢?我单步调试看不出原因。。

飘云 发表于 2014-2-21 17:06:49

yusheng 发表于 2014-2-21 12:36
有个问题哎……
HANDLE hFile = CreateFile(L"c:\\windows\\syswow64\\user32.dll",...);
HANDLE hMap =...

把DLL放到资源里面去

yusheng 发表于 2014-2-23 17:45:08

飘云 发表于 2014-2-21 17:06
把DLL放到资源里面去

依然无效。
而且从资源读取内容和从硬盘读取内容不应该是一样的么?我测试系统的一些DLL
除了kernel32.dll可以正常内存载入以外,都无法载入。
系统是win7 x64
页: [1]
查看完整版本: 内存加载模块 -- 飘云测试通过