• 大小: 225KB
    文件类型: .7z
    金币: 1
    下载: 0 次
    发布日期: 2021-05-31
  • 语言: 其他
  • 标签: 内存dll  

资源简介

从资源或内存中加载dll

资源截图

代码片段和文件信息

// MemLoadDll.cpp: implementation of the CMemLoadDll class.
//
//////////////////////////////////////////////////////////////////////
#include “StdAfx.h“
#include “MemLoadDll.h“

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMemLoadDll::CMemLoadDll()
{
m_bIsLoadOk = FALSE;
m_pImagebase = NULL;
m_pDllMain = NULL;
}

CMemLoadDll::~CMemLoadDll()
{
if(m_bIsLoadOk)
{
// ASSERT(m_pImagebase != NULL);
// ASSERT(m_pDllMain   != NULL);
//脱钩,准备卸载dll
m_pDllMain((HINSTANCE)m_pImagebase DLL_PROCESS_DETACH 0);
VirtualFree(m_pImagebase 0 MEM_RELEASE);
}
}

//MemLoadLibrary函数从内存缓冲区数据中加载一个dll到当前进程的地址空间,缺省位置0x10000000
//返回值: 成功返回TRUE  失败返回FALSE
//lpFileData: 存放dll文件数据的缓冲区
//nDataLength: 缓冲区中数据的总长度
BOOL CMemLoadDll::MemLoadLibrary(void* lpFileData int nDataLength)
{
if (m_pImagebase != NULL)
{
return FALSE;  //已经加载一个dll,还没有释放,不能加载新的dll
}
//检查数据有效性,并初始化
if (!CheckDataValide(lpFileData nDataLength))
{
return FALSE;
}
//计算所需的加载空间
int nImageSize = CalcTotalImageSize();

if (nImageSize == 0)
{
return FALSE;
}
// 分配虚拟内存
void *pMemoryAddress = VirtualAlloc(NULL nImageSize MEM_COMMIT|MEM_RESERVE PAGE_EXECUTE_READWRITE);

if (pMemoryAddress == NULL)
{
return FALSE;
}
else
{
CopyDllDatas(pMemoryAddress lpFileData); //复制dll数据,并对齐每个段
//重定位信息
if (m_pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_baseRELOC].VirtualAddress > 0
&& m_pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_baseRELOC].Size > 0)
{
DoRelocation(pMemoryAddress);
}
//填充引入地址表
if (!FillRavAddress(pMemoryAddress)) //修正引入地址表失败
{
VirtualFree(pMemoryAddress 0 MEM_RELEASE);
return FALSE;
}
//修改页属性。应该根据每个页的属性单独设置其对应内存页的属性。这里简化一下。
//统一设置成一个属性PAGE_EXECUTE_READWRITE
unsigned long unOld;

VirtualProtect(pMemoryAddress nImageSize PAGE_EXECUTE_READWRITE &unOld);
}
//修正基地址
#ifdef WIN32
m_pNTHeader->OptionalHeader.Imagebase = (DWORD)pMemoryAddress;
#else
m_pNTHeader->OptionalHeader.Imagebase = (ULONGULONG)pMemoryAddress;
#endif
//接下来要调用一下dll的入口函数,做初始化工作。
m_pDllMain = (ProcDllMain)(m_pNTHeader->OptionalHeader.AddressOfEntryPoint + (PBYTE)pMemoryAddress);

BOOL InitResult = m_pDllMain((HINSTANCE)pMemoryAddress DLL_PROCESS_ATTACH 0);

if (!InitResult) //初始化失败
{
m_pDllMain((HINSTANCE)pMemoryAddress DLL_PROCESS_DETACH 0);
VirtualFree(pMemoryAddress 0 MEM_RELEASE);
m_pDllMain = NULL;
return FALSE;
}

m_bIsLoadOk = TRUE;
m_pImagebase = pMemoryAddress;
return TRUE;
}

BOOL CMemLoadDll::IsLoadOk()
{
return m_bIsLoadOk;
}

//MemGetProcAddress函数从dll中获取指定函数的地址
//返回值: 成功返回函数地址  失败返回NULL
//lpProcName: 要查找函数的名字或者序号
FARPROC CMemLoadDll::MemGetProcAddress(LPCSTR lp

评论

共有 条评论