这个代码只支持WIN32方式编译出来的DLL,MFC的应该是不支持的
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;
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)