DLL Loader
-
Upload
vasilexxl5 -
Category
Documents
-
view
221 -
download
0
description
Transcript of DLL Loader
/** Loading dll from memory** Written by Vitaliy Shitts ([email protected])* Copyright (c) 2004 Vitaliy Shittz.** THIS CODE IS PROVIDED "AS IS". NO WARRANTY OF ANY KIND IS EXPRESSED* OR IMPLIED. YOU USE AT YOUR OWN RISK. THE AUTHOR ACCEPTS NO LIABILITY * IF IT CAUSES ANY DAMAGE TO YOU OR YOUR COMPUTER WHATSOEVER.** Beware of bugs.*/
#include "commonheaders.h"
#ifdef DLL_FROM_RESOURCE
#ifndef MIN# define MIN(a,b) ((a)<(b)?(a):(b))#endif
typedef BOOL (WINAPI *DLLMAIN)(HINSTANCE,DWORD,LPVOID);
#pragma warning (push)#pragma warning (disable: 4311; disable: 4312; disable: 4018)
DWORD GetSectionProtection(DWORD sc){ DWORD dwResult=0; if (sc & IMAGE_SCN_MEM_NOT_CACHED) dwResult |= PAGE_NOCACHE;
if (sc & IMAGE_SCN_MEM_EXECUTE) { if (sc & IMAGE_SCN_MEM_READ) { if (sc & IMAGE_SCN_MEM_WRITE) dwResult |= PAGE_EXECUTE_READWRITE; else dwResult |= PAGE_EXECUTE_READ; } else
{ if (sc & IMAGE_SCN_MEM_WRITE) dwResult |= PAGE_EXECUTE_WRITECOPY; else dwResult |= PAGE_EXECUTE; } } else { if (sc & IMAGE_SCN_MEM_READ) { if (sc & IMAGE_SCN_MEM_WRITE) dwResult|=PAGE_READWRITE; else dwResult|=PAGE_READONLY; } else { if (sc & IMAGE_SCN_MEM_WRITE) dwResult|=PAGE_WRITECOPY; else dwResult|=PAGE_NOACCESS; } } return dwResult;}
inline BOOL IsImportByOrdinal(DWORD ImportDescriptor){ return (ImportDescriptor & IMAGE_ORDINAL_FLAG32)!=0;}
HMODULE MemLoadLibrary(PBYTE data){ IMAGE_FILE_HEADER *pFileHeader = NULL; IMAGE_OPTIONAL_HEADER *pOptionalHeader = NULL; IMAGE_SECTION_HEADER *pSectionHeader = NULL; IMAGE_IMPORT_DESCRIPTOR *pImportDscrtr = NULL; USHORT e_lfanew = *((USHORT*)(data+0x3c)); PCHAR ImageBase = NULL;
PCHAR SectionBase = NULL;
DWORD dwSize, dwOldProt, ImageBaseDelta; int i;
pFileHeader = (IMAGE_FILE_HEADER *)(data+e_lfanew+4); pOptionalHeader = (IMAGE_OPTIONAL_HEADER *)(data+e_lfanew+4+sizeof(IMAGE_FILE_HEADER)); if (pOptionalHeader->Magic!=IMAGE_NT_OPTIONAL_HDR32_MAGIC) return NULL;
// Let's try to reserv memory ImageBase = (PCHAR)VirtualAlloc( (PVOID)pOptionalHeader->ImageBase, pOptionalHeader->SizeOfImage, MEM_RESERVE,PAGE_NOACCESS);
if(ImageBase==NULL) { ImageBase=(PCHAR)VirtualAlloc(NULL, pOptionalHeader->SizeOfImage, MEM_RESERVE,PAGE_NOACCESS); if(ImageBase==NULL) return NULL; }
// copy the header SectionBase=(PCHAR)VirtualAlloc(ImageBase, pOptionalHeader->SizeOfHeaders, MEM_COMMIT,PAGE_READWRITE); memcpy(SectionBase,data,pOptionalHeader->SizeOfHeaders); // Do headers read-only (to be on the safe side) VirtualProtect(SectionBase,pOptionalHeader->SizeOfHeaders,PAGE_READONLY,&dwOldProt);
// find sections ... pSectionHeader = (IMAGE_SECTION_HEADER *)(pOptionalHeader+1); for (i=0; i<pFileHeader->NumberOfSections; i++) { SectionBase = (PCHAR)VirtualAlloc( ImageBase+pSectionHeader[i].VirtualAddress, pSectionHeader[i].Misc.VirtualSize, MEM_COMMIT,PAGE_READWRITE); if (SectionBase==NULL)
{ VirtualFree(ImageBase, 0, MEM_RELEASE); return NULL; } // ... and copy initialization data SectionBase = ImageBase+pSectionHeader[i].VirtualAddress; dwSize = MIN(pSectionHeader[i].SizeOfRawData,pSectionHeader[i].Misc.VirtualSize); memcpy(SectionBase, data+pSectionHeader[i].PointerToRawData,dwSize); }
// check addersses ImageBaseDelta = (DWORD)ImageBase-pOptionalHeader->ImageBase; if (ImageBaseDelta!=0 && pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress!=0 ) { IMAGE_BASE_RELOCATION *pBaseReloc = (IMAGE_BASE_RELOCATION *)(ImageBase+ pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress); IMAGE_BASE_RELOCATION *pBaseReloc0 = pBaseReloc; WORD *wPointer = NULL; DWORD dwModCount; int i;
while ((DWORD)pBaseReloc0-(DWORD)pBaseReloc < pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size) { dwModCount = (pBaseReloc0->SizeOfBlock-sizeof(pBaseReloc))/2; wPointer = (WORD *)(pBaseReloc+1); for (i=0; i<dwModCount; i++, wPointer++) if ((*wPointer & 0xf000) !=0) { PDWORD pdw = (PDWORD)(ImageBase+pBaseReloc0->VirtualAddress+((*wPointer)&0xfff)); (*pdw)+=ImageBaseDelta; } pBaseReloc = (IMAGE_BASE_RELOCATION *)wPointer; } } else if (ImageBaseDelta!=0) { VirtualFree(ImageBase, 0, MEM_RELEASE); return NULL; }
pImportDscrtr = (IMAGE_IMPORT_DESCRIPTOR *)(ImageBase+ pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
for (;pImportDscrtr->Name!=0; pImportDscrtr++) { PCHAR pLibName = (PCHAR)(ImageBase+pImportDscrtr->Name); PCHAR pImortName = NULL; HMODULE hLibModule = LoadLibrary(pLibName); DWORD *pImport = NULL, *pAddress = NULL; DWORD ProcAddress;
pAddress=(DWORD *)(ImageBase+pImportDscrtr->/*Original*/FirstThunk); if (pImportDscrtr->TimeDateStamp==0) pImport=(DWORD *)(ImageBase+pImportDscrtr->FirstThunk); else pImport=(DWORD *)(ImageBase+pImportDscrtr->OriginalFirstThunk); for (i=0; pImport[i]!=0; i++) { if (IsImportByOrdinal(pImport[i])) ProcAddress=(DWORD)GetProcAddress(hLibModule, (PCHAR)(pImport[i]&0xFFFF)); else // import by name { pImortName=(PCHAR)(ImageBase+(pImport[i])+2); ProcAddress=(DWORD)GetProcAddress(hLibModule, pImortName); } pAddress[i]=ProcAddress; } }
// set section protection for (i=0; i<pFileHeader->NumberOfSections; i++) VirtualProtect((PVOID)(ImageBase+pSectionHeader[i].VirtualAddress), pSectionHeader[i].Misc.VirtualSize, GetSectionProtection(pSectionHeader[i].Characteristics), &dwOldProt);
// call DLLMain if (pOptionalHeader->AddressOfEntryPoint!=0) { DLLMAIN dllMain=(DLLMAIN)(ImageBase+pOptionalHeader->AddressOfEntryPoint);
if (!dllMain((HMODULE)ImageBase, DLL_PROCESS_ATTACH, NULL)) { VirtualFree(ImageBase, 0, MEM_RELEASE); return NULL; } }
return (HMODULE)ImageBase;}
BOOL MemFreeLibrary(HMODULE hDll){ PIMAGE_DOS_HEADER pDosHeader = NULL; PIMAGE_FILE_HEADER pFileHeader = NULL; PIMAGE_OPTIONAL_HEADER pOptionalHeader = NULL; pDosHeader=(PIMAGE_DOS_HEADER)hDll; pFileHeader=(PIMAGE_FILE_HEADER)(((PBYTE)hDll)+pDosHeader->e_lfanew+4); pOptionalHeader=(PIMAGE_OPTIONAL_HEADER)(pFileHeader+1);
// Call to DllMain if (pOptionalHeader->AddressOfEntryPoint!=0) { DLLMAIN dllMain=(DLLMAIN)((PBYTE)hDll+pOptionalHeader->AddressOfEntryPoint); dllMain(hDll, DLL_PROCESS_DETACH, NULL); }// free loaded librares PIMAGE_IMPORT_DESCRIPTOR pImportDscrtr = (IMAGE_IMPORT_DESCRIPTOR *)((PBYTE)hDll+ pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); for (;pImportDscrtr->Name!=0; pImportDscrtr++) { PCHAR pLibName = (PCHAR)((PBYTE)hDll+pImportDscrtr->Name); HMODULE hLib = GetModuleHandle(pLibName); FreeLibrary(hLib); }
return VirtualFree((PVOID)hDll, 0, MEM_RELEASE);}
FARPROC MemGetProcAddress(HMODULE hDll, LPCTSTR fname){
PIMAGE_DOS_HEADER pDosHeader = NULL; PIMAGE_FILE_HEADER pFileHeader = NULL; PIMAGE_OPTIONAL_HEADER pOptionalHeader = NULL;
pDosHeader=(PIMAGE_DOS_HEADER)hDll; pFileHeader=(PIMAGE_FILE_HEADER)(((PBYTE)hDll)+pDosHeader->e_lfanew+4); pOptionalHeader=(PIMAGE_OPTIONAL_HEADER)(pFileHeader+1);
DWORD dwExpRVA = pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; PBYTE pb = (PBYTE)hDll; PIMAGE_EXPORT_DIRECTORY pExportDir=(PIMAGE_EXPORT_DIRECTORY)(pb+dwExpRVA); PDWORD pNamesRVA=(PDWORD)(pb+pExportDir->AddressOfNames); PDWORD pFuncRVA=(PDWORD)(pb+pExportDir->AddressOfFunctions); PWORD ord=(PWORD)(pb+pExportDir->AddressOfNameOrdinals);
DWORD dwFunc=pExportDir->NumberOfNames; for (int i=0; i<dwFunc; i++) { PCHAR name =((PCHAR)(pb+pNamesRVA[i])); if (0==strcmp(fname, name)) return (FARPROC)(pb+pFuncRVA[ord[i]]); }
return NULL;}
#pragma warning (pop)
#endif