📄 dllload.cpp
字号:
LeaveCriticalSection(&g_DLLCrit);
return 1;
}
LeaveCriticalSection(&g_DLLCrit);
return 0;
}
static int MapDLLFromImage(void *pDLLFileImage, void *pMemoryImage)
{
// Get Number of Sections
IMAGE_FILE_HEADER * pe = GetFileHeader((HMODULE)pDLLFileImage);
IMAGE_OPTIONAL_HEADER * oh = GetOptionalHeader((HMODULE)pDLLFileImage);
IMAGE_SECTION_HEADER * sh = GetSectionHeader((HMODULE)pDLLFileImage);
DWORD hdrlen = oh->SizeOfHeaders;
int nSectionCount = pe->NumberOfSections;
// Copy PE Header + Section Headers
memcpy(pMemoryImage, pDLLFileImage, hdrlen);
// Copy Sections one by one
for(int i = 0; i < nSectionCount; i++, sh++)
{
char * secMemAddr = (char *)pMemoryImage + sh->VirtualAddress;
char * secFileAddr = (char *)pDLLFileImage + sh->PointerToRawData;
// Copy Section data
memcpy(secMemAddr, secFileAddr, sh->SizeOfRawData);
}
return ERROR_SUCCESS;
}
int PrepareDLLImage(void *pMemoryImage, DWORD /* dwImageSize */, BOOL /* bResolve */, BOOL bRebind)
{
// Get headers
IMAGE_OPTIONAL_HEADER * oh = GetOptionalHeader((HMODULE)pMemoryImage);
// IMAGE_SECTION_HEADER * sh = GetSectionHeader((HMODULE)pMemoryImage);
int nDirCount = oh->NumberOfRvaAndSizes;
// Get number of image directories in list
if(nDirCount < 16)
return ERROR_CAN_NOT_COMPLETE;
// - Process import table -----------------------------------------------
if(oh->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size !=0 )
{
IMAGE_IMPORT_DESCRIPTOR * id = (IMAGE_IMPORT_DESCRIPTOR *)MovePtr((HMODULE)pMemoryImage,oh->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
// For all imported DLLs
while(id->OriginalFirstThunk != 0)
{
char * svDllName = (char *)MovePtr((HMODULE)pMemoryImage, id->Name);
// Map library into address space (could also use LoadDLL())
HMODULE hDll = GetModuleHandle(svDllName);
if(hDll == NULL)
hDll = LoadLibrary(svDllName);
if(hDll == NULL)
return ERROR_CAN_NOT_COMPLETE;
// Bind if not bound already
if(id->TimeDateStamp==0 || bRebind)
{
// Store DLL infoz
id->ForwarderChain = (DWORD)hDll;
id->TimeDateStamp = 0xCDC31337; // This is bullshit cuz I don't want to call libc.
// Fill in Import Address Table
IMAGE_THUNK_DATA * td_in = (IMAGE_THUNK_DATA *)MovePtr((HMODULE)pMemoryImage, (DWORD)id->OriginalFirstThunk);
IMAGE_THUNK_DATA * td_out = (IMAGE_THUNK_DATA *)MovePtr((HMODULE)pMemoryImage, (DWORD)id->FirstThunk);
while(td_in->u1.Function != NULL)
{
IMAGE_IMPORT_BY_NAME * ibn;
FARPROC func;
// Determine if ordinal or name pointer
if(td_in->u1.Ordinal & 0x80000000)
// Ordinal
func = GetProcAddress(hDll, MAKEINTRESOURCE(td_in->u1.Ordinal));
else
{
// Function name
ibn = (IMAGE_IMPORT_BY_NAME *)MovePtr((HMODULE)pMemoryImage, (DWORD)td_in->u1.AddressOfData);
func = GetProcAddress(hDll, (char *)ibn->Name);
}
if(func == NULL)
return ERROR_CAN_NOT_COMPLETE;
// Write address to appropriate location
td_out->u1.Ordinal = (DWORD)func;
td_in++;
td_out++;
}
}
id++;
}
}
// - Process relocation tables if necessary ----------------------------------
// Calculate fixup delta
DWORD delta = (DWORD)pMemoryImage - (DWORD)oh->ImageBase;
if((delta != 0) && oh->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size != 0)
{
IMAGE_FIXUP_BLOCK * fb = (IMAGE_FIXUP_BLOCK *)MovePtr((HMODULE)pMemoryImage,oh->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
// For each fixup block
while(fb->dwPageRVA != 0)
{
IMAGE_FIXUP_ENTRY * fe = (IMAGE_FIXUP_ENTRY *)((char *)fb + sizeof(IMAGE_FIXUP_BLOCK));
int count = (fb->dwBlockSize - sizeof(IMAGE_FIXUP_BLOCK)) / sizeof(IMAGE_FIXUP_ENTRY);
// For each fixup entry
for(int i=0; i < count; i++, fe++)
{
VOID * fixaddr = MovePtr((HMODULE)pMemoryImage, fb->dwPageRVA + fe->offset);
WORD * pwFixAddr = (WORD *)fixaddr;
int adjust;
switch(fe->type)
{
case IMAGE_REL_BASED_ABSOLUTE:
break;
case IMAGE_REL_BASED_HIGH:
*pwFixAddr = (WORD)(*pwFixAddr + HIWORD(delta));
break;
case IMAGE_REL_BASED_LOW:
*pwFixAddr = (WORD)(*pwFixAddr + LOWORD(delta));
break;
case IMAGE_REL_BASED_HIGHLOW:
*((DWORD *)fixaddr) += delta;
break;
case IMAGE_REL_BASED_HIGHADJ: // This one's really fucked up.
adjust=((*((WORD *)fixaddr)) << 16) | (*(WORD *)(fe+1));
adjust += delta;
adjust += 0x00008000;
*((WORD *)fixaddr) = HIWORD(adjust);
fe++;
break;
default:
return ERROR_CAN_NOT_COMPLETE;
}
}
fb = (IMAGE_FIXUP_BLOCK *)((char *)fb + fb->dwBlockSize);
}
}
return 0;
}
HMODULE LoadDLLFromImage(void * pDLLFileImage, char * mapName, DWORD dwFlags)
{
IMAGE_OPTIONAL_HEADER * oh;
HANDLE hMapping = NULL;
void * pImageBase = NULL;
int nSectionCount; // Number of sections
int error = ERROR_CAN_NOT_COMPLETE;
__try
{
// Check DOS Header
if(((IMAGE_DOS_HEADER *)pDLLFileImage)->e_magic != IMAGE_DOS_SIGNATURE)
return NULL;
// Check NT magic word. If not found => Bad file format
if(*GetNTSignature((HMODULE)pDLLFileImage) != IMAGE_NT_SIGNATURE)
return NULL;
// Get section count
nSectionCount = GetFileHeader((HMODULE)pDLLFileImage)->NumberOfSections;
// Ensure we are an executable image, not a rom image
oh = GetOptionalHeader((HMODULE)pDLLFileImage);
if(oh->Magic != 0x010B)
return NULL;
// Get preferred image base and image length
void *pPreferredImageBase = (void *)oh->ImageBase;
DWORD dwImageSize = oh->SizeOfImage;
// Get base address of virtual image
if((pImageBase = GetDLLHandle(mapName)) == NULL)
{
BOOL bCreated = FALSE;
// BOOL bRebased = FALSE;
// If not mapped into this process, then we should map it now
if(g_bIsWinNT)
{
// === Windows NT DLL Loading (supports shared sections) ===
if(mapName != NULL)
hMapping = OpenFileMapping(FILE_MAP_WRITE, TRUE, mapName);
if(hMapping == NULL)
{
hMapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, dwImageSize+SIZE_OF_PARAMETER_BLOCK, mapName);
if(hMapping == NULL)
return NULL;
bCreated = TRUE;
}
// Try to load file mapping view at preferred image base (not gonna happen in Win9x..sigh)
if((pImageBase = MapViewOfFileEx(hMapping, FILE_MAP_WRITE, 0, 0, 0, pPreferredImageBase)) == NULL)
pImageBase = MapViewOfFileEx(hMapping, FILE_MAP_WRITE, 0, 0, 0, NULL);
CloseHandle(hMapping);
if(pImageBase == NULL)
return NULL;
}
else
{
// === Windows 9x DLL Loading (does not support shared sections) ===
pImageBase = VirtualAlloc(pPreferredImageBase, dwImageSize, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
if(pImageBase == NULL)
{
pImageBase = VirtualAlloc(NULL,dwImageSize,MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE);
if(pImageBase == NULL)
return NULL;
}
bCreated = TRUE;
}
// Now map DLL from file image into appropriate memory image (if just created)
// Also remap if DLL is being rebased as well (gotta fix relocations)
if(bCreated || (pImageBase != pPreferredImageBase))
{
if((error = MapDLLFromImage(pDLLFileImage,pImageBase)) != 0)
return NULL;
}
// Prepare DLL image (handle relocations/import/export/etc)
if(!(dwFlags & LOAD_LIBRARY_AS_DATAFILE))
{
if(PrepareDLLImage(pImageBase, dwImageSize, (dwFlags & DONT_RESOLVE_DLL_REFERENCES) ? FALSE : TRUE, (dwFlags & REBIND_IMAGE_IMPORTS) ? TRUE:FALSE))
return NULL;
}
// Resolve DLL references
if(!(dwFlags & DONT_RESOLVE_DLL_REFERENCES))
{
if(!RunDLLMain(pImageBase,dwImageSize,DLL_ATTACH))
return NULL;
}
// Apply appropriate protections
if((error = ProtectDLLImage(pImageBase, (dwFlags & RWX_PERMISSIONS) ? TRUE : FALSE)) != 0)
return NULL;
}
// Add to DLL table/increase reference count
if(AddDLLReference(pImageBase, mapName, dwFlags) == -1)
return NULL;
// All done OK, reset error
error = 0;
}
__finally
{
// If any error, cleanup and return NULL
if(error != 0 || pImageBase == NULL)
{
if(g_bIsWinNT)
UnmapViewOfFile(pImageBase);
else
VirtualFree(pImageBase,0,MEM_RELEASE);
pImageBase = NULL;
}
}
return (HMODULE)pImageBase;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// GetDLLHandle() //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Like GetModuleHandle(), returns null if the module is not loaded, returns a base address otherwise
HMODULE GetDLLHandle(char *svName)
{
if(svName == NULL)
return NULL;
EnterCriticalSection(&g_DLLCrit);
// Find DLL in list
IMAGE_PARAMETERS *cur;
for(cur = g_pImageParamHead;cur!=NULL;cur=cur->next) {
if(lstrcmpi(cur->svName,svName)==0) break;
}
if(cur!=NULL) {
LeaveCriticalSection(&g_DLLCrit);
return (HMODULE) cur->pImageBase;
}
LeaveCriticalSection(&g_DLLCrit);
return NULL;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -