请教高人看看我的代码出什么问题了,内存加载DLL初始化DLL入口函数的时候卡死,

xiao14116 2013-12-02 07:21:37
这个代码只支持WIN32方式编译出来的DLL,MFC的应该是不支持的,因为两种规则的DLL入口函数是不一样的

BOOL C内存加载DLLDlg::MyLoadDll(LPCTSTR mDllPath)
{
//////////把DLL文件读取到内存中/////////////////////;
CFile mFile;
if (!mFile.Open(mDllPath,CFile::modeRead))
{
return FALSE;
}
DWORD nFileSize = (DWORD)mFile.GetLength();
PBYTE bTemp = new BYTE[nFileSize];
ZeroMemory(bTemp,nFileSize);
mFile.Read(bTemp,nFileSize);
mFile.Close();

PIMAGE_DOS_HEADER pImageDosHeader = (PIMAGE_DOS_HEADER)bTemp;
PIMAGE_NT_HEADERS pImageNtHeaders = (PIMAGE_NT_HEADERS)(pImageDosHeader->e_lfanew+(DWORD)bTemp);
if ((pImageDosHeader->e_magic!=IMAGE_DOS_SIGNATURE)||
(pImageNtHeaders->Signature!=IMAGE_NT_SIGNATURE))
{
return FALSE;
}
///////////////////申请内存加载DLL的空间///////////////////////////////;
PBYTE pDllBase = new BYTE[pImageNtHeaders->OptionalHeader.SizeOfImage];
ZeroMemory(pDllBase,pImageNtHeaders->OptionalHeader.SizeOfImage);

///////////////////拷贝文件头////////////////////////////;
memcpy(pDllBase,pImageDosHeader,pImageNtHeaders->OptionalHeader.SizeOfHeaders);

///////////////////转换DOS头和NT头地址以备释放bTemp内存//////////////////;
pImageDosHeader = (PIMAGE_DOS_HEADER)pDllBase;
pImageNtHeaders = (PIMAGE_NT_HEADERS)(pImageDosHeader->e_lfanew+(DWORD)pDllBase);

///////////////////按照内存加载方式拷贝区段数据/////////////////////////;
PIMAGE_SECTION_HEADER pImageSectionHeader = (PIMAGE_SECTION_HEADER)(
pImageDosHeader->e_lfanew+sizeof(IMAGE_NT_HEADERS)+(DWORD)pDllBase);
while (pImageSectionHeader->VirtualAddress!=0)
{
DWORD nSize = MAKEMAX(pImageSectionHeader->Misc.VirtualSize,pImageSectionHeader->SizeOfRawData);
memcpy((PVOID)((DWORD)pDllBase+pImageSectionHeader->VirtualAddress),
(PVOID)((DWORD)bTemp+pImageSectionHeader->PointerToRawData),nSize);
DWORD flOldProtect = 0;
VirtualProtect((PVOID)((DWORD)pDllBase+pImageSectionHeader->VirtualAddress),
nSize,PAGE_EXECUTE_READWRITE,&flOldProtect);
Sleep(100);
pImageSectionHeader++;
}

/////////////////////////释放bTemp内存//////////////////;
delete[]bTemp;

////////////////////////基址重定位/////////////////////;
PIMAGE_DATA_DIRECTORY pImageDataDir = (PIMAGE_DATA_DIRECTORY)
(&(pImageNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]));

PIMAGE_BASE_RELOCATION pImageBaseRelocation = (PIMAGE_BASE_RELOCATION)
(pImageDataDir->VirtualAddress+(DWORD)pDllBase);
while (pImageDataDir->Size>0)
{
DWORD BlockRva=0;
int nCont = (pImageBaseRelocation->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION))/sizeof(WORD);
WORD *pBlock = (WORD*)((DWORD)pImageBaseRelocation+sizeof(IMAGE_BASE_RELOCATION));
for (int i=0;i<nCont;i++)
{
WORD wTemp = pBlock[i];

if (pBlock[i]>>12==IMAGE_REL_BASED_HIGHLOW)
{
BlockRva = ((DWORD)(wTemp&0xfff) + (DWORD)pDllBase )+ pImageBaseRelocation->VirtualAddress;
*(DWORD*)BlockRva += ((DWORD)pDllBase - pImageNtHeaders->OptionalHeader.ImageBase);
}
}
pImageDataDir->Size -= pImageBaseRelocation->SizeOfBlock;
pImageBaseRelocation = (PIMAGE_BASE_RELOCATION)((DWORD)pImageBaseRelocation+pImageBaseRelocation->SizeOfBlock);
}

////////////////////////修复IAT表/////////////////////;
pImageDataDir = (PIMAGE_DATA_DIRECTORY)
(&(pImageNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]));
PIMAGE_IMPORT_DESCRIPTOR pImageImportDes = (PIMAGE_IMPORT_DESCRIPTOR)(
pImageDataDir->VirtualAddress+(DWORD)pDllBase);
char *pName = NULL;
while (pImageImportDes->OriginalFirstThunk!=0)
{
pName = (char *)(pImageImportDes->Name+(DWORD)pDllBase);//导入DLL名称;
PIMAGE_THUNK_DATA pImageOriginalThunk = (PIMAGE_THUNK_DATA)(pImageImportDes->OriginalFirstThunk+(DWORD)pDllBase);
PIMAGE_THUNK_DATA pImageFirstThunk = (PIMAGE_THUNK_DATA)(pImageImportDes->FirstThunk+(DWORD)pDllBase);
DWORD dTemp = pImageOriginalThunk->u1.Function;
HMODULE hMod = LoadLibraryA(pName);
if (!hMod)
{
delete[]pDllBase;
return FALSE;
}
while (pImageOriginalThunk->u1.Function>0)
{
DWORD mFuncAddr = 0;
if (dTemp>>31==0)
{
PIMAGE_IMPORT_BY_NAME pImageImportByName = (PIMAGE_IMPORT_BY_NAME)(
pImageOriginalThunk->u1.Function+(DWORD)pDllBase);
pName = pImageImportByName->Name;
mFuncAddr = (DWORD)GetProcAddress(hMod,pName);
}else
{
mFuncAddr = (DWORD)GetProcAddress(hMod,(char *)(pImageOriginalThunk->u1.Ordinal^0x7FFFFF));
}
pImageFirstThunk->u1.Function = mFuncAddr;
pImageOriginalThunk++;
pImageFirstThunk++;
}
pImageImportDes++;
}

m_dllMain=(myDllMain)(pImageNtHeaders->OptionalHeader.AddressOfEntryPoint+ (DWORD)pDllBase);
m_dllMain((HINSTANCE)pDllBase,DLL_PROCESS_ATTACH,NULL);
// delete[]pDllBase;
return TRUE;
}
...全文
4862 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
shen_wei 2014-05-27
  • 打赏
  • 举报
回复
 
#include <windows.h> 
#include <stdio.h> 
 
typedef int (__cdecl *MYPROC)(LPWSTR); 
 
VOID main(VOID) 
{ 
    HINSTANCE hinstLib; 
    MYPROC ProcAdd; 
    BOOL fFreeResult, fRunTimeLinkSuccess = FALSE; 
 
    // Get a handle to the DLL module.
 
    hinstLib = LoadLibrary(TEXT("myputs")); 
 
    // If the handle is valid, try to get the function address.
 
    if (hinstLib != NULL) 
    { 
        ProcAdd = (MYPROC) GetProcAddress(hinstLib, "myPuts"); 
 
        // If the function address is valid, call the function.
 
        if (NULL != ProcAdd) 
        {
            fRunTimeLinkSuccess = TRUE;
            (ProcAdd) (L"Message sent to the DLL function\n"); 
        }
 
        // Free the DLL module.
 
        fFreeResult = FreeLibrary(hinstLib); 
    } 
 
    // If unable to call the DLL function, use an alternative.
 
    if (! fRunTimeLinkSuccess) 
        printf("Message printed from executable\n"); 
}
zhangwuji154 2014-05-23
  • 打赏
  • 举报
回复
一个函数里写这么多东西,就不是很好
许文君 2013-12-17
  • 打赏
  • 举报
回复
你的dllmain呢

2,586

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 资源
社区管理员
  • 资源
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧