From a199afce7c85f2b2c48499c5c60c8d8d46ee54c8 Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Sat, 9 Mar 2013 00:42:29 +0100 Subject: [PATCH] Use spaces instead of tabs - sorry for the noise. --- MemoryModule.c | 658 ++++++++++++++++---------------- example/DllLoader/DllLoader.cpp | 80 ++-- example/SampleDLL/SampleDLL.cpp | 2 +- 3 files changed, 370 insertions(+), 370 deletions(-) diff --git a/MemoryModule.c b/MemoryModule.c index c32b128..9930965 100644 --- a/MemoryModule.c +++ b/MemoryModule.c @@ -49,15 +49,15 @@ #include "MemoryModule.h" typedef struct { - PIMAGE_NT_HEADERS headers; - unsigned char *codeBase; - HCUSTOMMODULE *modules; - int numModules; - int initialized; - CustomLoadLibraryFunc loadLibrary; - CustomGetProcAddressFunc getProcAddress; - CustomFreeLibraryFunc freeLibrary; - void *userdata; + PIMAGE_NT_HEADERS headers; + unsigned char *codeBase; + HCUSTOMMODULE *modules; + int numModules; + int initialized; + CustomLoadLibraryFunc loadLibrary; + CustomGetProcAddressFunc getProcAddress; + CustomFreeLibraryFunc freeLibrary; + void *userdata; } MEMORYMODULE, *PMEMORYMODULE; typedef BOOL (WINAPI *DllEntryProc)(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved); @@ -68,116 +68,116 @@ typedef BOOL (WINAPI *DllEntryProc)(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID static void OutputLastError(const char *msg) { - LPVOID tmp; - char *tmpmsg; - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&tmp, 0, NULL); - tmpmsg = (char *)LocalAlloc(LPTR, strlen(msg) + strlen(tmp) + 3); - sprintf(tmpmsg, "%s: %s", msg, tmp); - OutputDebugString(tmpmsg); - LocalFree(tmpmsg); - LocalFree(tmp); + LPVOID tmp; + char *tmpmsg; + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&tmp, 0, NULL); + tmpmsg = (char *)LocalAlloc(LPTR, strlen(msg) + strlen(tmp) + 3); + sprintf(tmpmsg, "%s: %s", msg, tmp); + OutputDebugString(tmpmsg); + LocalFree(tmpmsg); + LocalFree(tmp); } #endif static void CopySections(const unsigned char *data, PIMAGE_NT_HEADERS old_headers, PMEMORYMODULE module) { - int i, size; - unsigned char *codeBase = module->codeBase; - unsigned char *dest; - PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(module->headers); - for (i=0; iheaders->FileHeader.NumberOfSections; i++, section++) { - if (section->SizeOfRawData == 0) { - // section doesn't contain data in the dll itself, but may define - // uninitialized data - size = old_headers->OptionalHeader.SectionAlignment; - if (size > 0) { - dest = (unsigned char *)VirtualAlloc(codeBase + section->VirtualAddress, - size, - MEM_COMMIT, - PAGE_READWRITE); + int i, size; + unsigned char *codeBase = module->codeBase; + unsigned char *dest; + PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(module->headers); + for (i=0; iheaders->FileHeader.NumberOfSections; i++, section++) { + if (section->SizeOfRawData == 0) { + // section doesn't contain data in the dll itself, but may define + // uninitialized data + size = old_headers->OptionalHeader.SectionAlignment; + if (size > 0) { + dest = (unsigned char *)VirtualAlloc(codeBase + section->VirtualAddress, + size, + MEM_COMMIT, + PAGE_READWRITE); - section->Misc.PhysicalAddress = (POINTER_TYPE)dest; - memset(dest, 0, size); - } + section->Misc.PhysicalAddress = (POINTER_TYPE)dest; + memset(dest, 0, size); + } - // section is empty - continue; - } + // section is empty + continue; + } - // commit memory block and copy data from dll - dest = (unsigned char *)VirtualAlloc(codeBase + section->VirtualAddress, - section->SizeOfRawData, - MEM_COMMIT, - PAGE_READWRITE); - memcpy(dest, data + section->PointerToRawData, section->SizeOfRawData); - section->Misc.PhysicalAddress = (POINTER_TYPE)dest; - } + // commit memory block and copy data from dll + dest = (unsigned char *)VirtualAlloc(codeBase + section->VirtualAddress, + section->SizeOfRawData, + MEM_COMMIT, + PAGE_READWRITE); + memcpy(dest, data + section->PointerToRawData, section->SizeOfRawData); + section->Misc.PhysicalAddress = (POINTER_TYPE)dest; + } } // Protection flags for memory pages (Executable, Readable, Writeable) static int ProtectionFlags[2][2][2] = { - { - // not executable - {PAGE_NOACCESS, PAGE_WRITECOPY}, - {PAGE_READONLY, PAGE_READWRITE}, - }, { - // executable - {PAGE_EXECUTE, PAGE_EXECUTE_WRITECOPY}, - {PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE}, - }, + { + // not executable + {PAGE_NOACCESS, PAGE_WRITECOPY}, + {PAGE_READONLY, PAGE_READWRITE}, + }, { + // executable + {PAGE_EXECUTE, PAGE_EXECUTE_WRITECOPY}, + {PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE}, + }, }; static void FinalizeSections(PMEMORYMODULE module) { - int i; - PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(module->headers); + int i; + PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(module->headers); #ifdef _WIN64 - POINTER_TYPE imageOffset = (module->headers->OptionalHeader.ImageBase & 0xffffffff00000000); + POINTER_TYPE imageOffset = (module->headers->OptionalHeader.ImageBase & 0xffffffff00000000); #else - #define imageOffset 0 + #define imageOffset 0 #endif - - // loop through all sections and change access flags - for (i=0; iheaders->FileHeader.NumberOfSections; i++, section++) { - DWORD protect, oldProtect, size; - int executable = (section->Characteristics & IMAGE_SCN_MEM_EXECUTE) != 0; - int readable = (section->Characteristics & IMAGE_SCN_MEM_READ) != 0; - int writeable = (section->Characteristics & IMAGE_SCN_MEM_WRITE) != 0; + + // loop through all sections and change access flags + for (i=0; iheaders->FileHeader.NumberOfSections; i++, section++) { + DWORD protect, oldProtect, size; + int executable = (section->Characteristics & IMAGE_SCN_MEM_EXECUTE) != 0; + int readable = (section->Characteristics & IMAGE_SCN_MEM_READ) != 0; + int writeable = (section->Characteristics & IMAGE_SCN_MEM_WRITE) != 0; - if (section->Characteristics & IMAGE_SCN_MEM_DISCARDABLE) { - // section is not needed any more and can safely be freed - VirtualFree((LPVOID)((POINTER_TYPE)section->Misc.PhysicalAddress | imageOffset), section->SizeOfRawData, MEM_DECOMMIT); - continue; - } + if (section->Characteristics & IMAGE_SCN_MEM_DISCARDABLE) { + // section is not needed any more and can safely be freed + VirtualFree((LPVOID)((POINTER_TYPE)section->Misc.PhysicalAddress | imageOffset), section->SizeOfRawData, MEM_DECOMMIT); + continue; + } - // determine protection flags based on characteristics - protect = ProtectionFlags[executable][readable][writeable]; - if (section->Characteristics & IMAGE_SCN_MEM_NOT_CACHED) { - protect |= PAGE_NOCACHE; - } + // determine protection flags based on characteristics + protect = ProtectionFlags[executable][readable][writeable]; + if (section->Characteristics & IMAGE_SCN_MEM_NOT_CACHED) { + protect |= PAGE_NOCACHE; + } - // determine size of region - size = section->SizeOfRawData; - if (size == 0) { - if (section->Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA) { - size = module->headers->OptionalHeader.SizeOfInitializedData; - } else if (section->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) { - size = module->headers->OptionalHeader.SizeOfUninitializedData; - } - } + // determine size of region + size = section->SizeOfRawData; + if (size == 0) { + if (section->Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA) { + size = module->headers->OptionalHeader.SizeOfInitializedData; + } else if (section->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) { + size = module->headers->OptionalHeader.SizeOfUninitializedData; + } + } - if (size > 0) { - // change memory access flags - if (VirtualProtect((LPVOID)((POINTER_TYPE)section->Misc.PhysicalAddress | imageOffset), size, protect, &oldProtect) == 0) + if (size > 0) { + // change memory access flags + if (VirtualProtect((LPVOID)((POINTER_TYPE)section->Misc.PhysicalAddress | imageOffset), size, protect, &oldProtect) == 0) #ifdef DEBUG_OUTPUT - OutputLastError("Error protecting memory page") + OutputLastError("Error protecting memory page") #endif - ; - } - } + ; + } + } #ifndef _WIN64 #undef imageOffset #endif @@ -186,118 +186,118 @@ FinalizeSections(PMEMORYMODULE module) static void PerformBaseRelocation(PMEMORYMODULE module, SIZE_T delta) { - DWORD i; - unsigned char *codeBase = module->codeBase; + DWORD i; + unsigned char *codeBase = module->codeBase; - PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY(module, IMAGE_DIRECTORY_ENTRY_BASERELOC); - if (directory->Size > 0) { - PIMAGE_BASE_RELOCATION relocation = (PIMAGE_BASE_RELOCATION) (codeBase + directory->VirtualAddress); - for (; relocation->VirtualAddress > 0; ) { - unsigned char *dest = codeBase + relocation->VirtualAddress; - unsigned short *relInfo = (unsigned short *)((unsigned char *)relocation + IMAGE_SIZEOF_BASE_RELOCATION); - for (i=0; i<((relocation->SizeOfBlock-IMAGE_SIZEOF_BASE_RELOCATION) / 2); i++, relInfo++) { - DWORD *patchAddrHL; + PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY(module, IMAGE_DIRECTORY_ENTRY_BASERELOC); + if (directory->Size > 0) { + PIMAGE_BASE_RELOCATION relocation = (PIMAGE_BASE_RELOCATION) (codeBase + directory->VirtualAddress); + for (; relocation->VirtualAddress > 0; ) { + unsigned char *dest = codeBase + relocation->VirtualAddress; + unsigned short *relInfo = (unsigned short *)((unsigned char *)relocation + IMAGE_SIZEOF_BASE_RELOCATION); + for (i=0; i<((relocation->SizeOfBlock-IMAGE_SIZEOF_BASE_RELOCATION) / 2); i++, relInfo++) { + DWORD *patchAddrHL; #ifdef _WIN64 - ULONGLONG *patchAddr64; + ULONGLONG *patchAddr64; #endif - int type, offset; + int type, offset; - // the upper 4 bits define the type of relocation - type = *relInfo >> 12; - // the lower 12 bits define the offset - offset = *relInfo & 0xfff; - - switch (type) - { - case IMAGE_REL_BASED_ABSOLUTE: - // skip relocation - break; + // the upper 4 bits define the type of relocation + type = *relInfo >> 12; + // the lower 12 bits define the offset + offset = *relInfo & 0xfff; + + switch (type) + { + case IMAGE_REL_BASED_ABSOLUTE: + // skip relocation + break; - case IMAGE_REL_BASED_HIGHLOW: - // change complete 32 bit address - patchAddrHL = (DWORD *) (dest + offset); - *patchAddrHL += delta; - break; - + case IMAGE_REL_BASED_HIGHLOW: + // change complete 32 bit address + patchAddrHL = (DWORD *) (dest + offset); + *patchAddrHL += delta; + break; + #ifdef _WIN64 - case IMAGE_REL_BASED_DIR64: - patchAddr64 = (ULONGLONG *) (dest + offset); - *patchAddr64 += delta; - break; + case IMAGE_REL_BASED_DIR64: + patchAddr64 = (ULONGLONG *) (dest + offset); + *patchAddr64 += delta; + break; #endif - default: - //printf("Unknown relocation: %d\n", type); - break; - } - } + default: + //printf("Unknown relocation: %d\n", type); + break; + } + } - // advance to next relocation block - relocation = (PIMAGE_BASE_RELOCATION) (((char *) relocation) + relocation->SizeOfBlock); - } - } + // advance to next relocation block + relocation = (PIMAGE_BASE_RELOCATION) (((char *) relocation) + relocation->SizeOfBlock); + } + } } static int BuildImportTable(PMEMORYMODULE module) { - int result=1; - unsigned char *codeBase = module->codeBase; - HCUSTOMMODULE *tmp; + int result=1; + unsigned char *codeBase = module->codeBase; + HCUSTOMMODULE *tmp; - PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY(module, IMAGE_DIRECTORY_ENTRY_IMPORT); - if (directory->Size > 0) { - PIMAGE_IMPORT_DESCRIPTOR importDesc = (PIMAGE_IMPORT_DESCRIPTOR) (codeBase + directory->VirtualAddress); - for (; !IsBadReadPtr(importDesc, sizeof(IMAGE_IMPORT_DESCRIPTOR)) && importDesc->Name; importDesc++) { - POINTER_TYPE *thunkRef; - FARPROC *funcRef; - HCUSTOMMODULE handle = module->loadLibrary((LPCSTR) (codeBase + importDesc->Name), module->userdata); - if (handle == NULL) { - SetLastError(ERROR_MOD_NOT_FOUND); - result = 0; - break; - } + PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY(module, IMAGE_DIRECTORY_ENTRY_IMPORT); + if (directory->Size > 0) { + PIMAGE_IMPORT_DESCRIPTOR importDesc = (PIMAGE_IMPORT_DESCRIPTOR) (codeBase + directory->VirtualAddress); + for (; !IsBadReadPtr(importDesc, sizeof(IMAGE_IMPORT_DESCRIPTOR)) && importDesc->Name; importDesc++) { + POINTER_TYPE *thunkRef; + FARPROC *funcRef; + HCUSTOMMODULE handle = module->loadLibrary((LPCSTR) (codeBase + importDesc->Name), module->userdata); + if (handle == NULL) { + SetLastError(ERROR_MOD_NOT_FOUND); + result = 0; + break; + } - tmp = (HCUSTOMMODULE *) realloc(module->modules, (module->numModules+1)*(sizeof(HCUSTOMMODULE))); - if (tmp == NULL) { - module->freeLibrary(handle, module->userdata); - SetLastError(ERROR_OUTOFMEMORY); - result = 0; - break; - } - module->modules = tmp; + tmp = (HCUSTOMMODULE *) realloc(module->modules, (module->numModules+1)*(sizeof(HCUSTOMMODULE))); + if (tmp == NULL) { + module->freeLibrary(handle, module->userdata); + SetLastError(ERROR_OUTOFMEMORY); + result = 0; + break; + } + module->modules = tmp; - module->modules[module->numModules++] = handle; - if (importDesc->OriginalFirstThunk) { - thunkRef = (POINTER_TYPE *) (codeBase + importDesc->OriginalFirstThunk); - funcRef = (FARPROC *) (codeBase + importDesc->FirstThunk); - } else { - // no hint table - thunkRef = (POINTER_TYPE *) (codeBase + importDesc->FirstThunk); - funcRef = (FARPROC *) (codeBase + importDesc->FirstThunk); - } - for (; *thunkRef; thunkRef++, funcRef++) { - if (IMAGE_SNAP_BY_ORDINAL(*thunkRef)) { - *funcRef = module->getProcAddress(handle, (LPCSTR)IMAGE_ORDINAL(*thunkRef), module->userdata); - } else { - PIMAGE_IMPORT_BY_NAME thunkData = (PIMAGE_IMPORT_BY_NAME) (codeBase + (*thunkRef)); - *funcRef = module->getProcAddress(handle, (LPCSTR)&thunkData->Name, module->userdata); - } - if (*funcRef == 0) { - result = 0; - break; - } - } + module->modules[module->numModules++] = handle; + if (importDesc->OriginalFirstThunk) { + thunkRef = (POINTER_TYPE *) (codeBase + importDesc->OriginalFirstThunk); + funcRef = (FARPROC *) (codeBase + importDesc->FirstThunk); + } else { + // no hint table + thunkRef = (POINTER_TYPE *) (codeBase + importDesc->FirstThunk); + funcRef = (FARPROC *) (codeBase + importDesc->FirstThunk); + } + for (; *thunkRef; thunkRef++, funcRef++) { + if (IMAGE_SNAP_BY_ORDINAL(*thunkRef)) { + *funcRef = module->getProcAddress(handle, (LPCSTR)IMAGE_ORDINAL(*thunkRef), module->userdata); + } else { + PIMAGE_IMPORT_BY_NAME thunkData = (PIMAGE_IMPORT_BY_NAME) (codeBase + (*thunkRef)); + *funcRef = module->getProcAddress(handle, (LPCSTR)&thunkData->Name, module->userdata); + } + if (*funcRef == 0) { + result = 0; + break; + } + } - if (!result) { - module->freeLibrary(handle, module->userdata); - SetLastError(ERROR_PROC_NOT_FOUND); - break; - } - } - } + if (!result) { + module->freeLibrary(handle, module->userdata); + SetLastError(ERROR_PROC_NOT_FOUND); + break; + } + } + } - return result; + return result; } static HCUSTOMMODULE _LoadLibrary(LPCSTR filename, void *userdata) @@ -331,33 +331,33 @@ HMEMORYMODULE MemoryLoadLibraryEx(const void *data, CustomFreeLibraryFunc freeLibrary, void *userdata) { - PMEMORYMODULE result; - PIMAGE_DOS_HEADER dos_header; - PIMAGE_NT_HEADERS old_header; - unsigned char *code, *headers; - SIZE_T locationDelta; - DllEntryProc DllEntry; - BOOL successfull; + PMEMORYMODULE result; + PIMAGE_DOS_HEADER dos_header; + PIMAGE_NT_HEADERS old_header; + unsigned char *code, *headers; + SIZE_T locationDelta; + DllEntryProc DllEntry; + BOOL successfull; - dos_header = (PIMAGE_DOS_HEADER)data; - if (dos_header->e_magic != IMAGE_DOS_SIGNATURE) { - SetLastError(ERROR_BAD_EXE_FORMAT); - return NULL; - } + dos_header = (PIMAGE_DOS_HEADER)data; + if (dos_header->e_magic != IMAGE_DOS_SIGNATURE) { + SetLastError(ERROR_BAD_EXE_FORMAT); + return NULL; + } - old_header = (PIMAGE_NT_HEADERS)&((const unsigned char *)(data))[dos_header->e_lfanew]; - if (old_header->Signature != IMAGE_NT_SIGNATURE) { - SetLastError(ERROR_BAD_EXE_FORMAT); - return NULL; - } + old_header = (PIMAGE_NT_HEADERS)&((const unsigned char *)(data))[dos_header->e_lfanew]; + if (old_header->Signature != IMAGE_NT_SIGNATURE) { + SetLastError(ERROR_BAD_EXE_FORMAT); + return NULL; + } - // reserve memory for image of library - // XXX: is it correct to commit the complete memory region at once? + // reserve memory for image of library + // XXX: is it correct to commit the complete memory region at once? // calling DllEntry raises an exception if we don't... - code = (unsigned char *)VirtualAlloc((LPVOID)(old_header->OptionalHeader.ImageBase), - old_header->OptionalHeader.SizeOfImage, - MEM_RESERVE | MEM_COMMIT, - PAGE_READWRITE); + code = (unsigned char *)VirtualAlloc((LPVOID)(old_header->OptionalHeader.ImageBase), + old_header->OptionalHeader.SizeOfImage, + MEM_RESERVE | MEM_COMMIT, + PAGE_READWRITE); if (code == NULL) { // try to allocate memory at arbitrary position @@ -365,155 +365,155 @@ HMEMORYMODULE MemoryLoadLibraryEx(const void *data, old_header->OptionalHeader.SizeOfImage, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); - if (code == NULL) { - SetLastError(ERROR_OUTOFMEMORY); - return NULL; - } - } + if (code == NULL) { + SetLastError(ERROR_OUTOFMEMORY); + return NULL; + } + } - result = (PMEMORYMODULE)HeapAlloc(GetProcessHeap(), 0, sizeof(MEMORYMODULE)); - if (result == NULL) { - SetLastError(ERROR_OUTOFMEMORY); - VirtualFree(code, 0, MEM_RELEASE); - return NULL; - } + result = (PMEMORYMODULE)HeapAlloc(GetProcessHeap(), 0, sizeof(MEMORYMODULE)); + if (result == NULL) { + SetLastError(ERROR_OUTOFMEMORY); + VirtualFree(code, 0, MEM_RELEASE); + return NULL; + } - result->codeBase = code; - result->numModules = 0; - result->modules = NULL; - result->initialized = 0; - result->loadLibrary = loadLibrary; - result->getProcAddress = getProcAddress; - result->freeLibrary = freeLibrary; - result->userdata = userdata; + result->codeBase = code; + result->numModules = 0; + result->modules = NULL; + result->initialized = 0; + result->loadLibrary = loadLibrary; + result->getProcAddress = getProcAddress; + result->freeLibrary = freeLibrary; + result->userdata = userdata; - // commit memory for headers - headers = (unsigned char *)VirtualAlloc(code, - old_header->OptionalHeader.SizeOfHeaders, - MEM_COMMIT, - PAGE_READWRITE); - - // copy PE header to code - memcpy(headers, dos_header, dos_header->e_lfanew + old_header->OptionalHeader.SizeOfHeaders); - result->headers = (PIMAGE_NT_HEADERS)&((const unsigned char *)(headers))[dos_header->e_lfanew]; + // commit memory for headers + headers = (unsigned char *)VirtualAlloc(code, + old_header->OptionalHeader.SizeOfHeaders, + MEM_COMMIT, + PAGE_READWRITE); + + // copy PE header to code + memcpy(headers, dos_header, dos_header->e_lfanew + old_header->OptionalHeader.SizeOfHeaders); + result->headers = (PIMAGE_NT_HEADERS)&((const unsigned char *)(headers))[dos_header->e_lfanew]; - // update position - result->headers->OptionalHeader.ImageBase = (POINTER_TYPE)code; + // update position + result->headers->OptionalHeader.ImageBase = (POINTER_TYPE)code; - // copy sections from DLL file block to new memory location - CopySections(data, old_header, result); + // copy sections from DLL file block to new memory location + CopySections(data, old_header, result); - // adjust base address of imported data - locationDelta = (SIZE_T)(code - old_header->OptionalHeader.ImageBase); - if (locationDelta != 0) { - PerformBaseRelocation(result, locationDelta); - } + // adjust base address of imported data + locationDelta = (SIZE_T)(code - old_header->OptionalHeader.ImageBase); + if (locationDelta != 0) { + PerformBaseRelocation(result, locationDelta); + } - // load required dlls and adjust function table of imports - if (!BuildImportTable(result)) { - goto error; - } + // load required dlls and adjust function table of imports + if (!BuildImportTable(result)) { + goto error; + } - // mark memory pages depending on section headers and release - // sections that are marked as "discardable" - FinalizeSections(result); + // mark memory pages depending on section headers and release + // sections that are marked as "discardable" + FinalizeSections(result); - // get entry point of loaded library - if (result->headers->OptionalHeader.AddressOfEntryPoint != 0) { - DllEntry = (DllEntryProc) (code + result->headers->OptionalHeader.AddressOfEntryPoint); - // notify library about attaching to process - successfull = (*DllEntry)((HINSTANCE)code, DLL_PROCESS_ATTACH, 0); - if (!successfull) { - SetLastError(ERROR_DLL_INIT_FAILED); - goto error; - } - result->initialized = 1; - } + // get entry point of loaded library + if (result->headers->OptionalHeader.AddressOfEntryPoint != 0) { + DllEntry = (DllEntryProc) (code + result->headers->OptionalHeader.AddressOfEntryPoint); + // notify library about attaching to process + successfull = (*DllEntry)((HINSTANCE)code, DLL_PROCESS_ATTACH, 0); + if (!successfull) { + SetLastError(ERROR_DLL_INIT_FAILED); + goto error; + } + result->initialized = 1; + } - return (HMEMORYMODULE)result; + return (HMEMORYMODULE)result; error: - // cleanup - MemoryFreeLibrary(result); - return NULL; + // cleanup + MemoryFreeLibrary(result); + return NULL; } FARPROC MemoryGetProcAddress(HMEMORYMODULE module, const char *name) { - unsigned char *codeBase = ((PMEMORYMODULE)module)->codeBase; - int idx=-1; - DWORD i, *nameRef; - WORD *ordinal; - PIMAGE_EXPORT_DIRECTORY exports; - PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY((PMEMORYMODULE)module, IMAGE_DIRECTORY_ENTRY_EXPORT); - if (directory->Size == 0) { - // no export table found - SetLastError(ERROR_PROC_NOT_FOUND); - return NULL; - } + unsigned char *codeBase = ((PMEMORYMODULE)module)->codeBase; + int idx=-1; + DWORD i, *nameRef; + WORD *ordinal; + PIMAGE_EXPORT_DIRECTORY exports; + PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY((PMEMORYMODULE)module, IMAGE_DIRECTORY_ENTRY_EXPORT); + if (directory->Size == 0) { + // no export table found + SetLastError(ERROR_PROC_NOT_FOUND); + return NULL; + } - exports = (PIMAGE_EXPORT_DIRECTORY) (codeBase + directory->VirtualAddress); - if (exports->NumberOfNames == 0 || exports->NumberOfFunctions == 0) { - // DLL doesn't export anything - SetLastError(ERROR_PROC_NOT_FOUND); - return NULL; - } + exports = (PIMAGE_EXPORT_DIRECTORY) (codeBase + directory->VirtualAddress); + if (exports->NumberOfNames == 0 || exports->NumberOfFunctions == 0) { + // DLL doesn't export anything + SetLastError(ERROR_PROC_NOT_FOUND); + return NULL; + } - // search function name in list of exported names - nameRef = (DWORD *) (codeBase + exports->AddressOfNames); - ordinal = (WORD *) (codeBase + exports->AddressOfNameOrdinals); - for (i=0; iNumberOfNames; i++, nameRef++, ordinal++) { - if (stricmp(name, (const char *) (codeBase + (*nameRef))) == 0) { - idx = *ordinal; - break; - } - } + // search function name in list of exported names + nameRef = (DWORD *) (codeBase + exports->AddressOfNames); + ordinal = (WORD *) (codeBase + exports->AddressOfNameOrdinals); + for (i=0; iNumberOfNames; i++, nameRef++, ordinal++) { + if (stricmp(name, (const char *) (codeBase + (*nameRef))) == 0) { + idx = *ordinal; + break; + } + } - if (idx == -1) { - // exported symbol not found - SetLastError(ERROR_PROC_NOT_FOUND); - return NULL; - } + if (idx == -1) { + // exported symbol not found + SetLastError(ERROR_PROC_NOT_FOUND); + return NULL; + } - if ((DWORD)idx > exports->NumberOfFunctions) { - // name <-> ordinal number don't match - SetLastError(ERROR_PROC_NOT_FOUND); - return NULL; - } + if ((DWORD)idx > exports->NumberOfFunctions) { + // name <-> ordinal number don't match + SetLastError(ERROR_PROC_NOT_FOUND); + return NULL; + } - // AddressOfFunctions contains the RVAs to the "real" functions - return (FARPROC) (codeBase + (*(DWORD *) (codeBase + exports->AddressOfFunctions + (idx*4)))); + // AddressOfFunctions contains the RVAs to the "real" functions + return (FARPROC) (codeBase + (*(DWORD *) (codeBase + exports->AddressOfFunctions + (idx*4)))); } void MemoryFreeLibrary(HMEMORYMODULE mod) { - int i; - PMEMORYMODULE module = (PMEMORYMODULE)mod; + int i; + PMEMORYMODULE module = (PMEMORYMODULE)mod; - if (module != NULL) { - if (module->initialized != 0) { - // notify library about detaching from process - DllEntryProc DllEntry = (DllEntryProc) (module->codeBase + module->headers->OptionalHeader.AddressOfEntryPoint); - (*DllEntry)((HINSTANCE)module->codeBase, DLL_PROCESS_DETACH, 0); - module->initialized = 0; - } + if (module != NULL) { + if (module->initialized != 0) { + // notify library about detaching from process + DllEntryProc DllEntry = (DllEntryProc) (module->codeBase + module->headers->OptionalHeader.AddressOfEntryPoint); + (*DllEntry)((HINSTANCE)module->codeBase, DLL_PROCESS_DETACH, 0); + module->initialized = 0; + } - if (module->modules != NULL) { - // free previously opened libraries - for (i=0; inumModules; i++) { - if (module->modules[i] != NULL) { - module->freeLibrary(module->modules[i], module->userdata); - } - } + if (module->modules != NULL) { + // free previously opened libraries + for (i=0; inumModules; i++) { + if (module->modules[i] != NULL) { + module->freeLibrary(module->modules[i], module->userdata); + } + } - free(module->modules); - } + free(module->modules); + } - if (module->codeBase != NULL) { - // release memory of library - VirtualFree(module->codeBase, 0, MEM_RELEASE); - } + if (module->codeBase != NULL) { + // release memory of library + VirtualFree(module->codeBase, 0, MEM_RELEASE); + } - HeapFree(GetProcessHeap(), 0, module); - } + HeapFree(GetProcessHeap(), 0, module); + } } diff --git a/example/DllLoader/DllLoader.cpp b/example/DllLoader/DllLoader.cpp index c34cf6f..d723c93 100644 --- a/example/DllLoader/DllLoader.cpp +++ b/example/DllLoader/DllLoader.cpp @@ -12,59 +12,59 @@ typedef int (*addNumberProc)(int, int); void LoadFromFile(void) { - addNumberProc addNumber; - HINSTANCE handle = LoadLibrary(DLL_FILE); - if (handle == NULL) - return; + addNumberProc addNumber; + HINSTANCE handle = LoadLibrary(DLL_FILE); + if (handle == NULL) + return; - addNumber = (addNumberProc)GetProcAddress(handle, "addNumbers"); - printf("From file: %d\n", addNumber(1, 2)); - FreeLibrary(handle); + addNumber = (addNumberProc)GetProcAddress(handle, "addNumbers"); + printf("From file: %d\n", addNumber(1, 2)); + FreeLibrary(handle); } void LoadFromMemory(void) { - FILE *fp; - unsigned char *data=NULL; - size_t size; - HMEMORYMODULE module; - addNumberProc addNumber; - - fp = fopen(DLL_FILE, "rb"); - if (fp == NULL) - { - printf("Can't open DLL file \"%s\".", DLL_FILE); - goto exit; - } + FILE *fp; + unsigned char *data=NULL; + size_t size; + HMEMORYMODULE module; + addNumberProc addNumber; + + fp = fopen(DLL_FILE, "rb"); + if (fp == NULL) + { + printf("Can't open DLL file \"%s\".", DLL_FILE); + goto exit; + } - fseek(fp, 0, SEEK_END); - size = ftell(fp); - data = (unsigned char *)malloc(size); - fseek(fp, 0, SEEK_SET); - fread(data, 1, size, fp); - fclose(fp); + fseek(fp, 0, SEEK_END); + size = ftell(fp); + data = (unsigned char *)malloc(size); + fseek(fp, 0, SEEK_SET); + fread(data, 1, size, fp); + fclose(fp); - module = MemoryLoadLibrary(data); - if (module == NULL) - { - printf("Can't load library from memory.\n"); - goto exit; - } + module = MemoryLoadLibrary(data); + if (module == NULL) + { + printf("Can't load library from memory.\n"); + goto exit; + } - addNumber = (addNumberProc)MemoryGetProcAddress(module, "addNumbers"); - printf("From memory: %d\n", addNumber(1, 2)); - MemoryFreeLibrary(module); + addNumber = (addNumberProc)MemoryGetProcAddress(module, "addNumbers"); + printf("From memory: %d\n", addNumber(1, 2)); + MemoryFreeLibrary(module); exit: - if (data) - free(data); + if (data) + free(data); } int main(int argc, char* argv[]) { - LoadFromFile(); - printf("\n\n"); - LoadFromMemory(); - return 0; + LoadFromFile(); + printf("\n\n"); + LoadFromMemory(); + return 0; } diff --git a/example/SampleDLL/SampleDLL.cpp b/example/SampleDLL/SampleDLL.cpp index 342d371..7bf03ef 100644 --- a/example/SampleDLL/SampleDLL.cpp +++ b/example/SampleDLL/SampleDLL.cpp @@ -4,7 +4,7 @@ extern "C" { SAMPLEDLL_API int addNumbers(int a, int b) { - return a + b; + return a + b; } }