From 9399210d238f3f3e0c0ab63fa23d87ff8c34e117 Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Tue, 1 Feb 2005 23:09:49 +0000 Subject: [PATCH 1/4] started writing PEB compatible code --- MemoryModule.c | 404 +++++++++++++++++------------ MemoryModule.h | 11 +- example/DllLoader/DllLoader.cpp | 81 +++++- example/DllLoader/DllLoader.vcproj | 7 +- example/DllMemory.sln | 8 + example/SampleDLL/SampleDLL.cpp | 12 + 6 files changed, 351 insertions(+), 172 deletions(-) diff --git a/MemoryModule.c b/MemoryModule.c index 10a6c30..56ac062 100644 --- a/MemoryModule.c +++ b/MemoryModule.c @@ -26,23 +26,24 @@ #include #include +#include "ntinternals.h" + +#define DEBUG_OUTPUT 0 + #ifdef DEBUG_OUTPUT #include #endif #include "MemoryModule.h" -typedef struct { - PIMAGE_NT_HEADERS headers; - unsigned char *codeBase; - HMODULE *modules; - int numModules; - int initialized; -} MEMORYMODULE, *PMEMORYMODULE; - typedef BOOL (WINAPI *DllEntryProc)(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved); -#define GET_HEADER_DICTIONARY(module, idx) &(module)->headers->OptionalHeader.DataDirectory[idx] +#define GET_NT_HEADER(module) ((PIMAGE_NT_HEADERS)&((const unsigned char *)(module))[((PIMAGE_DOS_HEADER)(module))->e_lfanew]) +#define GET_HEADER_DICTIONARY(module, idx) &GET_NT_HEADER(module)->OptionalHeader.DataDirectory[idx] +#define CALCULATE_REAL_ADDRESS(base, offset) (((unsigned char *)(base)) + (offset)) + +// stores number of modules loaded +static DWORD ModuleCount = 0; #ifdef DEBUG_OUTPUT static void @@ -61,13 +62,14 @@ OutputLastError(const char *msg) #endif static void -CopySections(const unsigned char *data, PIMAGE_NT_HEADERS old_headers, PMEMORYMODULE module) +CopySections(const unsigned char *data, PIMAGE_NT_HEADERS old_headers, HMODULE 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++) + DWORD i, size; + LPVOID dest; + PIMAGE_SECTION_HEADER section; + + section = IMAGE_FIRST_SECTION(GET_NT_HEADER(module)); + for (i=0; iFileHeader.NumberOfSections; i++, section++) { if (section->SizeOfRawData == 0) { @@ -76,7 +78,7 @@ CopySections(const unsigned char *data, PIMAGE_NT_HEADERS old_headers, PMEMORYMO size = old_headers->OptionalHeader.SectionAlignment; if (size > 0) { - dest = (unsigned char *)VirtualAlloc(codeBase + section->VirtualAddress, + dest = VirtualAlloc(CALCULATE_REAL_ADDRESS(module, section->VirtualAddress), size, MEM_COMMIT, PAGE_READWRITE); @@ -90,7 +92,7 @@ CopySections(const unsigned char *data, PIMAGE_NT_HEADERS old_headers, PMEMORYMO } // commit memory block and copy data from dll - dest = (unsigned char *)VirtualAlloc(codeBase + section->VirtualAddress, + dest = VirtualAlloc(CALCULATE_REAL_ADDRESS(module, section->VirtualAddress), section->SizeOfRawData, MEM_COMMIT, PAGE_READWRITE); @@ -113,13 +115,14 @@ static int ProtectionFlags[2][2][2] = { }; static void -FinalizeSections(PMEMORYMODULE module) +FinalizeSections(HMODULE module) { - int i; - PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(module->headers); + DWORD i; + PIMAGE_SECTION_HEADER section; // loop through all sections and change access flags - for (i=0; iheaders->FileHeader.NumberOfSections; i++, section++) + section = IMAGE_FIRST_SECTION(GET_NT_HEADER(module)); + for (i=0; iFileHeader.NumberOfSections; i++, section++) { DWORD protect, oldProtect, size; int executable = (section->Characteristics & IMAGE_SCN_MEM_EXECUTE) != 0; @@ -143,9 +146,9 @@ FinalizeSections(PMEMORYMODULE module) if (size == 0) { if (section->Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA) - size = module->headers->OptionalHeader.SizeOfInitializedData; + size = GET_NT_HEADER(module)->OptionalHeader.SizeOfInitializedData; else if (section->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) - size = module->headers->OptionalHeader.SizeOfUninitializedData; + size = GET_NT_HEADER(module)->OptionalHeader.SizeOfUninitializedData; } if (size > 0) @@ -161,19 +164,19 @@ FinalizeSections(PMEMORYMODULE module) } static void -PerformBaseRelocation(PMEMORYMODULE module, DWORD delta) +PerformBaseRelocation(HMODULE module, DWORD delta) { DWORD i; - unsigned char *codeBase = module->codeBase; - - PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY(module, IMAGE_DIRECTORY_ENTRY_BASERELOC); + PIMAGE_DATA_DIRECTORY directory; + + directory = GET_HEADER_DICTIONARY(module, IMAGE_DIRECTORY_ENTRY_BASERELOC); if (directory->Size > 0) { - PIMAGE_BASE_RELOCATION relocation = (PIMAGE_BASE_RELOCATION)(codeBase + directory->VirtualAddress); + PIMAGE_BASE_RELOCATION relocation = (PIMAGE_BASE_RELOCATION)CALCULATE_REAL_ADDRESS(module, directory->VirtualAddress); for (; relocation->VirtualAddress > 0; ) { - unsigned char *dest = (unsigned char *)(codeBase + relocation->VirtualAddress); - unsigned short *relInfo = (unsigned short *)((unsigned char *)relocation + IMAGE_SIZEOF_BASE_RELOCATION); + unsigned char *dest = (unsigned char *)CALCULATE_REAL_ADDRESS(module, relocation->VirtualAddress); + unsigned short *relInfo = (unsigned short *)CALCULATE_REAL_ADDRESS(relocation, IMAGE_SIZEOF_BASE_RELOCATION); for (i=0; i<((relocation->SizeOfBlock-IMAGE_SIZEOF_BASE_RELOCATION) / 2); i++, relInfo++) { DWORD *patchAddrHL; @@ -209,21 +212,21 @@ PerformBaseRelocation(PMEMORYMODULE module, DWORD delta) } static int -BuildImportTable(PMEMORYMODULE module) +BuildImportTable(HMODULE module) { int result=1; - unsigned char *codeBase = module->codeBase; 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); + PIMAGE_IMPORT_DESCRIPTOR importDesc = (PIMAGE_IMPORT_DESCRIPTOR)CALCULATE_REAL_ADDRESS(module, directory->VirtualAddress); for (; !IsBadReadPtr(importDesc, sizeof(IMAGE_IMPORT_DESCRIPTOR)) && importDesc->Name; importDesc++) { DWORD *thunkRef, *funcRef; - HMODULE handle = LoadLibrary((LPCSTR)(codeBase + importDesc->Name)); + HMODULE handle = LoadLibrary((LPCSTR)CALCULATE_REAL_ADDRESS(module, importDesc->Name)); if (handle == INVALID_HANDLE_VALUE) { + SetLastError(ERROR_MOD_NOT_FOUND); #if DEBUG_OUTPUT OutputLastError("Can't load library"); #endif @@ -231,33 +234,26 @@ BuildImportTable(PMEMORYMODULE module) break; } - module->modules = (HMODULE *)realloc(module->modules, (module->numModules+1)*(sizeof(HMODULE))); - if (module->modules == NULL) - { - result = 0; - break; - } - - module->modules[module->numModules++] = handle; if (importDesc->OriginalFirstThunk) { - thunkRef = (DWORD *)(codeBase + importDesc->OriginalFirstThunk); - funcRef = (DWORD *)(codeBase + importDesc->FirstThunk); + thunkRef = (DWORD *)CALCULATE_REAL_ADDRESS(module, importDesc->OriginalFirstThunk); + funcRef = (DWORD *)CALCULATE_REAL_ADDRESS(module, importDesc->FirstThunk); } else { // no hint table - thunkRef = (DWORD *)(codeBase + importDesc->FirstThunk); - funcRef = (DWORD *)(codeBase + importDesc->FirstThunk); + thunkRef = (DWORD *)CALCULATE_REAL_ADDRESS(module, importDesc->FirstThunk); + funcRef = (DWORD *)CALCULATE_REAL_ADDRESS(module, importDesc->FirstThunk); } for (; *thunkRef; thunkRef++, funcRef++) { if IMAGE_SNAP_BY_ORDINAL(*thunkRef) *funcRef = (DWORD)GetProcAddress(handle, (LPCSTR)IMAGE_ORDINAL(*thunkRef)); else { - PIMAGE_IMPORT_BY_NAME thunkData = (PIMAGE_IMPORT_BY_NAME)(codeBase + *thunkRef); + PIMAGE_IMPORT_BY_NAME thunkData = (PIMAGE_IMPORT_BY_NAME)CALCULATE_REAL_ADDRESS(module, *thunkRef); *funcRef = (DWORD)GetProcAddress(handle, (LPCSTR)&thunkData->Name); } if (*funcRef == 0) { + SetLastError(ERROR_PROC_NOT_FOUND); result = 0; break; } @@ -271,15 +267,163 @@ BuildImportTable(PMEMORYMODULE module) return result; } -HMEMORYMODULE MemoryLoadLibrary(const void *data) +static PPEB +GetPEB(void) { - PMEMORYMODULE result; + // XXX: is there a better or even documented way to do this? + __asm { + // get PEB + mov eax, dword ptr fs:[30h] + } +} + +static HMODULE +FindLibraryInPEB(const unsigned char *name, int incLoadCount) +{ + PPEB_LDR_DATA loaderData; + PLDR_MODULE loaderModule; + PWSTR longName; + size_t i; + HMODULE result=NULL; + + if (name == NULL) + return NULL; + + // convert name to long character name + longName = (PWSTR)calloc((strlen(name)+1)*2, 1); + for (i=0; iLoaderData; + loaderModule = (PLDR_MODULE)(loaderData->InLoadOrderModuleList.Flink); + while (1) + { + if (wcsicmp(longName, loaderModule->BaseDllName.Buffer) == 0) + { + result = loaderModule->BaseAddress; + if (incLoadCount && loaderModule->LoadCount != 0xffff) + // we use this module, so increate the load count + loaderModule->LoadCount++; + + goto exit; + } + + // advance to next module + loaderModule = (PLDR_MODULE)(loaderModule->InLoadOrderModuleList.Flink); + if (loaderModule->BaseAddress == NULL || loaderModule == (PLDR_MODULE)(loaderData->InLoadOrderModuleList.Flink)) + // we traversed through the complete list + // and didn't find the library + goto exit; + } + +exit: + free(longName); + + return result; +} + +// Append a loader module to the end of the loader data list of the PEB +#define AppendToChain(module, list, chain) { \ + (module)->##chain##.Flink = (list)->##chain##.Flink; \ + (module)->##chain##.Blink = (list)->##chain##.Blink; \ + ((PLDR_MODULE)((list)->##chain##.Blink))->##chain##.Flink = &(module)->##chain##; \ + (list)->##chain##.Blink = &(module)->##chain##; \ +}; + +static PLDR_MODULE +InsertModuleInPEB(HMODULE module, unsigned char *name, unsigned char *baseName, DWORD locationDelta) +{ + PLDR_MODULE loaderModule; + PPEB_LDR_DATA loaderData = GetPEB()->LoaderData; + DWORD entry = GET_NT_HEADER(module)->OptionalHeader.AddressOfEntryPoint; + size_t i; + + loaderModule = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LDR_MODULE)); + if (loaderModule == NULL) + return NULL; + + loaderModule->BaseAddress = module; + loaderModule->EntryPoint = (PVOID)(entry ? CALCULATE_REAL_ADDRESS(module, entry) : 0); + loaderModule->SizeOfImage = GET_NT_HEADER(module)->OptionalHeader.SizeOfImage; + loaderModule->LoadCount = 1; + + loaderModule->BaseDllName.Buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (strlen(baseName)+1)*2); + if (loaderModule->BaseDllName.Buffer == NULL) + { + HeapFree(GetProcessHeap(), 0, loaderModule); + return NULL; + } + loaderModule->BaseDllName.Length = (USHORT)strlen(baseName)*2; + loaderModule->BaseDllName.MaximumLength = (USHORT)HeapSize(GetProcessHeap(), 0, loaderModule->BaseDllName.Buffer); + for (i=0; iBaseDllName.Buffer[i] = baseName[i]; + + loaderModule->FullDllName.Buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (strlen(name)+1)*2); + if (loaderModule->BaseDllName.Buffer == NULL) + { + HeapFree(GetProcessHeap(), 0, loaderModule->BaseDllName.Buffer); + HeapFree(GetProcessHeap(), 0, loaderModule); + return NULL; + } + loaderModule->FullDllName.Length = (USHORT)strlen(name)*2; + loaderModule->FullDllName.MaximumLength = (USHORT)HeapSize(GetProcessHeap(), 0, loaderModule->FullDllName.Buffer); + for (i=0; iFullDllName.Buffer[i] = name[i]; + + // XXX: are these the correct flags? + loaderModule->Flags = IMAGE_DLL | ENTRY_PROCESSED; + if (locationDelta != 0) + loaderModule->Flags |= IMAGE_NOT_AT_BASE; + loaderModule->TimeDateStamp = GET_NT_HEADER(module)->FileHeader.TimeDateStamp; + + // XXX: do we need more set the hash table? + //loaderModule->HashTableEntry.Flink = &loaderModule->HashTableEntry; + //loaderModule->HashTableEntry.Blink = &loaderModule->HashTableEntry; + + AppendToChain(loaderModule, loaderData, InLoadOrderModuleList); + AppendToChain(loaderModule, loaderData, InInitializationOrderModuleList); + + // XXX: insert at the correct position in the chain + AppendToChain(loaderModule, loaderData, InMemoryOrderModuleList); + return loaderModule; +} + +HMODULE MemoryLoadLibrary(const void *data, unsigned char *name) +{ + HMODULE result; PIMAGE_DOS_HEADER dos_header; PIMAGE_NT_HEADERS old_header; - unsigned char *code, *headers; + LPVOID headers; + unsigned char *baseName; + unsigned char fullname[MAX_DLL_NAME_LENGTH], tempname[MAX_DLL_NAME_LENGTH]; DWORD locationDelta; DllEntryProc DllEntry; BOOL successfull; + DWORD hasFullName; + PLDR_MODULE loaderModule=NULL; + + // make sure we have a module name + if (name == NULL || strlen(name) == 0) + { + sprintf(tempname, "memorymodule%d", ModuleCount); + name = (unsigned char *)&tempname; + } + + // maybe a module with the given name has been loaded already + hasFullName = GetFullPathName(name, sizeof(fullname), (LPSTR)&fullname, &baseName); + + // search for module in PEB + result = FindLibraryInPEB(hasFullName ? baseName : name, 1); + if (result != NULL) + // already loaded this module + goto exit; + + if (hasFullName) + // use complete filename as module name + name = (unsigned char *)&fullname; + else + baseName = name; dos_header = (PIMAGE_DOS_HEADER)data; if (dos_header->e_magic != IMAGE_DOS_SIGNATURE) @@ -287,70 +431,61 @@ HMEMORYMODULE MemoryLoadLibrary(const void *data) #if DEBUG_OUTPUT OutputDebugString("Not a valid executable file.\n"); #endif - return NULL; + goto error; } - old_header = (PIMAGE_NT_HEADERS)&((const unsigned char *)(data))[dos_header->e_lfanew]; + old_header = GET_NT_HEADER(data); if (old_header->Signature != IMAGE_NT_SIGNATURE) { #if DEBUG_OUTPUT OutputDebugString("No PE header found.\n"); #endif - return NULL; + goto error; } // reserve memory for image of library - code = (unsigned char *)VirtualAlloc((LPVOID)(old_header->OptionalHeader.ImageBase), + result = (HMODULE)VirtualAlloc((LPVOID)(old_header->OptionalHeader.ImageBase), old_header->OptionalHeader.SizeOfImage, MEM_RESERVE, PAGE_READWRITE); - if (code == NULL) + if (result == NULL) // try to allocate memory at arbitrary position - code = (unsigned char *)VirtualAlloc(NULL, + result = (HMODULE)VirtualAlloc(NULL, old_header->OptionalHeader.SizeOfImage, MEM_RESERVE, PAGE_READWRITE); - if (code == NULL) + if (result == NULL) { -#if DEBUG_OUTPUT - OutputLastError("Can't reserve memory"); -#endif - return NULL; + SetLastError(ERROR_OUTOFMEMORY); + goto error; } - result = (PMEMORYMODULE)HeapAlloc(GetProcessHeap(), 0, sizeof(MEMORYMODULE)); - result->codeBase = code; - result->numModules = 0; - result->modules = NULL; - result->initialized = 0; - // XXX: is it correct to commit the complete memory region at once? // calling DllEntry raises an exception if we don't... - VirtualAlloc(code, + VirtualAlloc(result, old_header->OptionalHeader.SizeOfImage, MEM_COMMIT, PAGE_READWRITE); // commit memory for headers - headers = (unsigned char *)VirtualAlloc(code, - old_header->OptionalHeader.SizeOfHeaders, + headers = VirtualAlloc(result, + dos_header->e_lfanew + 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 = (DWORD)code; + GET_NT_HEADER(result)->OptionalHeader.ImageBase = (DWORD)result; // copy sections from DLL file block to new memory location CopySections(data, old_header, result); // adjust base address of imported data - locationDelta = (DWORD)(code - old_header->OptionalHeader.ImageBase); + locationDelta = (DWORD)((DWORD)result - old_header->OptionalHeader.ImageBase); if (locationDelta != 0) PerformBaseRelocation(result, locationDelta); @@ -362,106 +497,53 @@ HMEMORYMODULE MemoryLoadLibrary(const void *data) // sections that are marked as "discardable" FinalizeSections(result); + // Add loaded module to PEB + if (!(loaderModule = InsertModuleInPEB(result, name, baseName, locationDelta))) + goto error; + // get entry point of loaded library - if (result->headers->OptionalHeader.AddressOfEntryPoint != 0) + if (GET_NT_HEADER(result)->OptionalHeader.AddressOfEntryPoint != 0) { - DllEntry = (DllEntryProc)(code + result->headers->OptionalHeader.AddressOfEntryPoint); - if (DllEntry == 0) - { -#if DEBUG_OUTPUT - OutputDebugString("Library has no entry point.\n"); -#endif - goto error; - } - // notify library about attaching to process - successfull = (*DllEntry)((HINSTANCE)code, DLL_PROCESS_ATTACH, 0); + DllEntry = (DllEntryProc)CALCULATE_REAL_ADDRESS(result, GET_NT_HEADER(result)->OptionalHeader.AddressOfEntryPoint); + successfull = (*DllEntry)(result, DLL_PROCESS_ATTACH, 0); if (!successfull) { -#if DEBUG_OUTPUT - OutputDebugString("Can't attach library.\n"); -#endif + SetLastError(ERROR_DLL_INIT_FAILED); goto error; } - result->initialized = 1; + loaderModule->Flags |= PROCESS_ATTACH_CALLED; } - return (HMEMORYMODULE)result; + ModuleCount++; + goto exit; error: - // 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 - return NULL; - - exports = (PIMAGE_EXPORT_DIRECTORY)(codeBase + directory->VirtualAddress); - if (exports->NumberOfNames == 0 || exports->NumberOfFunctions == 0) - // DLL doesn't export anything - 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; - } - - if (idx == -1) - // exported symbol not found - return NULL; - - if ((DWORD)idx > exports->NumberOfFunctions) - // name <-> ordinal number don't match - return NULL; - - // 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; - - if (module != NULL) + // perform some cleanup... + if (loaderModule != 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] != INVALID_HANDLE_VALUE) - FreeLibrary(module->modules[i]); + if ((loaderModule->Flags & PROCESS_ATTACH_CALLED) != 0) + (*DllEntry)(result, DLL_PROCESS_DETACH, 0); + + // remove from module chains + loaderModule->InInitializationOrderModuleList.Flink->Blink = loaderModule->InInitializationOrderModuleList.Blink; + loaderModule->InInitializationOrderModuleList.Blink->Flink = loaderModule->InInitializationOrderModuleList.Flink; + loaderModule->InLoadOrderModuleList.Flink->Blink = loaderModule->InLoadOrderModuleList.Blink; + loaderModule->InLoadOrderModuleList.Blink->Flink = loaderModule->InLoadOrderModuleList.Flink; + loaderModule->InMemoryOrderModuleList.Flink->Blink = loaderModule->InMemoryOrderModuleList.Blink; + loaderModule->InMemoryOrderModuleList.Blink->Flink = loaderModule->InMemoryOrderModuleList.Flink; + + // free memory for PEB structures + HeapFree(GetProcessHeap(), 0, loaderModule->BaseDllName.Buffer); + HeapFree(GetProcessHeap(), 0, loaderModule->FullDllName.Buffer); + HeapFree(GetProcessHeap(), 0, loaderModule); + } - free(module->modules); - } + if (result != NULL) + VirtualFree(result, 0, MEM_RELEASE); - if (module->codeBase != NULL) - // release memory of library - VirtualFree(module->codeBase, 0, MEM_RELEASE); + result = NULL; - HeapFree(GetProcessHeap(), 0, module); - } +exit: + return result; } diff --git a/MemoryModule.h b/MemoryModule.h index 15a7b8e..9dd4c31 100644 --- a/MemoryModule.h +++ b/MemoryModule.h @@ -26,17 +26,16 @@ #include -typedef void *HMEMORYMODULE; - #ifdef __cplusplus extern "C" { #endif -HMEMORYMODULE MemoryLoadLibrary(const void *); - -FARPROC MemoryGetProcAddress(HMEMORYMODULE, const char *); +HMODULE MemoryLoadLibrary(const void *, unsigned char *); -void MemoryFreeLibrary(HMEMORYMODULE); +// backwards compatibility +#define HMEMORYMODULE HMODULE +#define MemoryGetProcAddress GetProcAddress +#define MemoryFreeLibrary FreeLibrary #ifdef __cplusplus } diff --git a/example/DllLoader/DllLoader.cpp b/example/DllLoader/DllLoader.cpp index 4fa8ca3..743434d 100644 --- a/example/DllLoader/DllLoader.cpp +++ b/example/DllLoader/DllLoader.cpp @@ -4,22 +4,92 @@ #include #include +#include "../../ntinternals.h" #include "../../MemoryModule.h" typedef int (*addNumberProc)(int, int); #define DLL_FILE "..\\..\\SampleDLL\\Debug\\SampleDLL.dll" +PPEB GetPEB(void) +{ + // XXX: is there a better or even documented way to do this? + __asm { + // get PEB + mov eax, dword ptr fs:[30h] + } +} + +void DumpPEB(void) +{ + PPEB peb = GetPEB(); + PPEB_LDR_DATA loaderData = peb->LoaderData; + PLDR_MODULE loaderModule; + + printf("-------------------------------------\n"); + printf("PEB at 0x%x\n", (DWORD)peb); + printf("Modules (Load Order)\n"); + loaderModule = (PLDR_MODULE)(loaderData->InLoadOrderModuleList.Flink); + printf("Last: %x\n", (DWORD)loaderData->InLoadOrderModuleList.Blink); + while (1) + { + printf("Info: %x\n", (DWORD)loaderModule); + if (!IsBadReadPtr(loaderModule->BaseDllName.Buffer, loaderModule->BaseDllName.Length)) + { + wprintf(L"Library: %s\n", loaderModule->BaseDllName.Buffer); + wprintf(L"Fullname: %s\n", loaderModule->FullDllName.Buffer); + } else + printf("Unknown module\n"); + printf("Address: %x\n", (DWORD)loaderModule->BaseAddress); + printf("Load count: %d\n", loaderModule->LoadCount); + printf("Flags: %d\n", loaderModule->Flags); + printf("Size: %d\n", loaderModule->SizeOfImage); + printf("Entry: %x\n", (DWORD)loaderModule->EntryPoint); + printf("Hash: %x %x\n", (DWORD)loaderModule->HashTableEntry.Flink, (DWORD)loaderModule->HashTableEntry.Blink); + + // advance to next module + loaderModule = (PLDR_MODULE)(loaderModule->InLoadOrderModuleList.Flink); + if (loaderModule == (PLDR_MODULE)(loaderData->InLoadOrderModuleList.Flink)) + // we traversed through the complete list + // and didn't find the library + goto exit; + + printf("\n"); + } + +exit: + printf("=====================================\n"); + printf("\n"); +} + +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 *)malloc(strlen(msg) + strlen((const char *)tmp) + 3); + sprintf(tmpmsg, "%s: %s", msg, tmp); + OutputDebugString(tmpmsg); + free(tmpmsg); + LocalFree(tmp); +} + void LoadFromFile(void) { addNumberProc addNumber; - HINSTANCE handle = LoadLibrary(DLL_FILE); + HINSTANCE handle; + DumpPEB(); + handle = LoadLibrary(DLL_FILE); if (handle == INVALID_HANDLE_VALUE) return; + DumpPEB(); addNumber = (addNumberProc)GetProcAddress(handle, "addNumbers"); printf("From file: %d\n", addNumber(1, 2)); FreeLibrary(handle); + DumpPEB(); } void LoadFromMemory(void) @@ -44,15 +114,20 @@ void LoadFromMemory(void) fread(data, 1, size, fp); fclose(fp); - module = MemoryLoadLibrary(data); + DumpPEB(); + module = MemoryLoadLibrary(data, (unsigned char *)DLL_FILE); if (module == NULL) { printf("Can't load library from memory.\n"); goto exit; } + DumpPEB(); addNumber = (addNumberProc)MemoryGetProcAddress(module, "addNumbers"); - printf("From memory: %d\n", addNumber(1, 2)); + if (addNumber) + printf("From memory: %d\n", addNumber(1, 2)); + else + printf("Not found\n"); MemoryFreeLibrary(module); exit: diff --git a/example/DllLoader/DllLoader.vcproj b/example/DllLoader/DllLoader.vcproj index e6e24dd..ddde550 100644 --- a/example/DllLoader/DllLoader.vcproj +++ b/example/DllLoader/DllLoader.vcproj @@ -19,7 +19,7 @@ + + +#include + #include "SampleDLL.h" extern "C" { +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + printf("DllMain called:\n"); + printf("Instance: %x\n", (DWORD)hinstDLL); + printf("Reason: %d\n", fdwReason); + printf("Reserved: %x\n", (DWORD)lpvReserved); + return 1; +} + SAMPLEDLL_API int addNumbers(int a, int b) { return a + b; From af834a6af406510eb418bd4b1705de70c9ca1f68 Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Tue, 1 Feb 2005 23:11:28 +0000 Subject: [PATCH 2/4] initial checkin --- ntinternals.h | 215 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 215 insertions(+) create mode 100644 ntinternals.h diff --git a/ntinternals.h b/ntinternals.h new file mode 100644 index 0000000..1ceca8d --- /dev/null +++ b/ntinternals.h @@ -0,0 +1,215 @@ +/* + * Undocumented Windows structures + * + * Found on http://undocumented.ntinternals.net/ + */ + +#ifndef __NT_INTERNALS +#define __NT_INTERNALS + +#include +#include + +#ifndef UNICODE_STRING +// usually included in "winternl.h" + +typedef struct _UNICODE_STRING { + USHORT Length; + USHORT MaximumLength; + PWSTR Buffer; +} UNICODE_STRING; +typedef UNICODE_STRING *PUNICODE_STRING; +typedef const UNICODE_STRING *PCUNICODE_STRING; + +#endif + +// constants from the article +// "What Goes On Inside Windows 2000: Solving the Mysteries of the Loader" +// by Russ Osterlund +// http://msdn.microsoft.com/msdnmag/issues/02/03/Loader/default.aspx +#define MAX_DLL_NAME_LENGTH 0x214 + +#define STATIC_LINK 0x00000002 +#define IMAGE_DLL 0x00000004 +#define LOAD_IN_PROGRESS 0x00001000 +#define UNLOAD_IN_PROGRESS 0x00002000 +#define ENTRY_PROCESSED 0x00004000 +#define ENTRY_INSERTED 0x00008000 +#define CURRENT_LOAD 0x00010000 +#define FAILED_BUILTIN_LOAD 0x00020000 +#define DONT_CALL_FOR_THREAD 0x00040000 +#define PROCESS_ATTACH_CALLED 0x00080000 +#define DEBUG_SYMBOLS_LOADED 0x00100000 +#define IMAGE_NOT_AT_BASE 0x00200000 +#define WX86_IGNORE_MACHINETYPE 0x00400000 + +/* + * Documented by: + * Reactos + * Tomasz Nowak + */ +typedef struct _LDR_MODULE { + LIST_ENTRY InLoadOrderModuleList; + LIST_ENTRY InMemoryOrderModuleList; + LIST_ENTRY InInitializationOrderModuleList; + PVOID BaseAddress; + PVOID EntryPoint; + ULONG SizeOfImage; + UNICODE_STRING FullDllName; + UNICODE_STRING BaseDllName; + ULONG Flags; + SHORT LoadCount; + SHORT TlsIndex; + LIST_ENTRY HashTableEntry; + ULONG TimeDateStamp; +} LDR_MODULE, *PLDR_MODULE; + +/* + * Documented by: + * Reactos + * Tomasz Nowak + */ +typedef struct _PEB_LDR_DATA { + ULONG Length; + BOOLEAN Initialized; + PVOID SsHandle; + LIST_ENTRY InLoadOrderModuleList; + LIST_ENTRY InMemoryOrderModuleList; + LIST_ENTRY InInitializationOrderModuleList; +} PEB_LDR_DATA, *PPEB_LDR_DATA; + +/* + * Documented by: + * Reactos + */ +typedef struct _RTL_DRIVE_LETTER_CURDIR { + USHORT Flags; + USHORT Length; + ULONG TimeStamp; + UNICODE_STRING DosPath; +} RTL_DRIVE_LETTER_CURDIR, *PRTL_DRIVE_LETTER_CURDIR; + +/* + * Documented by: + * Reactos + * Tomasz Nowak + */ +typedef struct _RTL_USER_PROCESS_PARAMETERS { + ULONG MaximumLength; + ULONG Length; + ULONG Flags; + ULONG DebugFlags; + PVOID ConsoleHandle; + ULONG ConsoleFlags; + HANDLE StdInputHandle; + HANDLE StdOutputHandle; + HANDLE StdErrorHandle; + UNICODE_STRING CurrentDirectoryPath; + HANDLE CurrentDirectoryHandle; + UNICODE_STRING DllPath; + UNICODE_STRING ImagePathName; + UNICODE_STRING CommandLine; + PVOID Environment; + ULONG StartingPositionLeft; + ULONG StartingPositionTop; + ULONG Width; + ULONG Height; + ULONG CharWidth; + ULONG CharHeight; + ULONG ConsoleTextAttributes; + ULONG WindowFlags; + ULONG ShowWindowFlags; + UNICODE_STRING WindowTitle; + UNICODE_STRING DesktopName; + UNICODE_STRING ShellInfo; + UNICODE_STRING RuntimeData; + RTL_DRIVE_LETTER_CURDIR DLCurrentDirectory[0x20]; +} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS; + +/* + * Address of fast-locking routine for PEB + */ +typedef void (*PPEBLOCKROUTINE)( + PVOID PebLock +); + +typedef LPVOID *PPVOID; + +/* + * Structure PEB_FREE_BLOCK is used internally in PEB (Process Enviroment Block) + * structure for describe free blocks in memory allocated for PEB. + * + * Documented by: + * Reactos + */ +typedef struct _PEB_FREE_BLOCK { + struct _PEB_FREE_BLOCK *Next; + ULONG Size; +} PEB_FREE_BLOCK, *PPEB_FREE_BLOCK; + +/* + * Structure PEB (Process Enviroment Block) contains all User-Mode parameters + * associated by system with current process. + * + * Documented by: + * Reactos + * Tomasz Nowak + */ +typedef struct _PEB { + BOOLEAN InheritedAddressSpace; + BOOLEAN ReadImageFileExecOptions; + BOOLEAN BeingDebugged; + BOOLEAN Spare; + HANDLE Mutant; + PVOID ImageBaseAddress; + PPEB_LDR_DATA LoaderData; + PRTL_USER_PROCESS_PARAMETERS ProcessParameters; + PVOID SubSystemData; + PVOID ProcessHeap; + PVOID FastPebLock; + PPEBLOCKROUTINE FastPebLockRoutine; + PPEBLOCKROUTINE FastPebUnlockRoutine; + ULONG EnvironmentUpdateCount; + PPVOID KernelCallbackTable; + PVOID EventLogSection; + PVOID EventLog; + PPEB_FREE_BLOCK FreeList; + ULONG TlsExpansionCounter; + PVOID TlsBitmap; + ULONG TlsBitmapBits[0x2]; + PVOID ReadOnlySharedMemoryBase; + PVOID ReadOnlySharedMemoryHeap; + PPVOID ReadOnlyStaticServerData; + PVOID AnsiCodePageData; + PVOID OemCodePageData; + PVOID UnicodeCaseTableData; + ULONG NumberOfProcessors; + ULONG NtGlobalFlag; + BYTE Spare2[0x4]; + LARGE_INTEGER CriticalSectionTimeout; + ULONG HeapSegmentReserve; + ULONG HeapSegmentCommit; + ULONG HeapDeCommitTotalFreeThreshold; + ULONG HeapDeCommitFreeBlockThreshold; + ULONG NumberOfHeaps; + ULONG MaximumNumberOfHeaps; + PPVOID *ProcessHeaps; + PVOID GdiSharedHandleTable; + PVOID ProcessStarterHelper; + PVOID GdiDCAttributeList; + PVOID LoaderLock; + ULONG OSMajorVersion; + ULONG OSMinorVersion; + ULONG OSBuildNumber; + ULONG OSPlatformId; + ULONG ImageSubSystem; + ULONG ImageSubSystemMajorVersion; + ULONG ImageSubSystemMinorVersion; + ULONG GdiHandleBuffer[0x22]; + ULONG PostProcessInitRoutine; + ULONG TlsExpansionBitmap; + BYTE TlsExpansionBitmapBits[0x80]; + ULONG SessionId; +} PEB, *PPEB; + +#endif // __NT_INTERNALS From d650d3032575fc7175674c6ea31c679cd70dab05 Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Tue, 15 Mar 2005 23:50:39 +0000 Subject: [PATCH 3/4] updated registration of module in PEB --- MemoryModule.c | 50 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/MemoryModule.c b/MemoryModule.c index 56ac062..e641c09 100644 --- a/MemoryModule.c +++ b/MemoryModule.c @@ -277,6 +277,7 @@ GetPEB(void) } } +// XXX: this should use the hash table to speed up finding modules static HMODULE FindLibraryInPEB(const unsigned char *name, int incLoadCount) { @@ -306,7 +307,7 @@ FindLibraryInPEB(const unsigned char *name, int incLoadCount) // we use this module, so increate the load count loaderModule->LoadCount++; - goto exit; + break; } // advance to next module @@ -314,23 +315,36 @@ FindLibraryInPEB(const unsigned char *name, int incLoadCount) if (loaderModule->BaseAddress == NULL || loaderModule == (PLDR_MODULE)(loaderData->InLoadOrderModuleList.Flink)) // we traversed through the complete list // and didn't find the library - goto exit; + break; } -exit: free(longName); - return result; } // Append a loader module to the end of the loader data list of the PEB -#define AppendToChain(module, list, chain) { \ - (module)->##chain##.Flink = (list)->##chain##.Flink; \ +#define AppendToChain(module, list, chain, offset) { \ + (module)->##chain##.Flink = &(list)->##chain##; \ (module)->##chain##.Blink = (list)->##chain##.Blink; \ - ((PLDR_MODULE)((list)->##chain##.Blink))->##chain##.Flink = &(module)->##chain##; \ + ((PLDR_MODULE)(((char *)(list)->##chain##.Blink) - offset))->##chain##.Flink = &(module)->##chain##; \ (list)->##chain##.Blink = &(module)->##chain##; \ }; +#define GET_FIRST_CHAR(module) ((_toupper((module)->BaseDllName.Buffer[0]) - 1) & 0x1f) + +static PLIST_ENTRY +GetPEBHashTable(void) +{ + PPEB_LDR_DATA loaderData; + PLDR_MODULE loaderModule; + unsigned char firstChar; + + loaderData = GetPEB()->LoaderData; + loaderModule = (PLDR_MODULE)(loaderData->InLoadOrderModuleList.Flink); + firstChar = GET_FIRST_CHAR(loaderModule); + return (PLIST_ENTRY)(((char *)loaderModule->HashTableEntry.Blink) - (firstChar * sizeof(LIST_ENTRY))); +} + static PLDR_MODULE InsertModuleInPEB(HMODULE module, unsigned char *name, unsigned char *baseName, DWORD locationDelta) { @@ -338,6 +352,8 @@ InsertModuleInPEB(HMODULE module, unsigned char *name, unsigned char *baseName, PPEB_LDR_DATA loaderData = GetPEB()->LoaderData; DWORD entry = GET_NT_HEADER(module)->OptionalHeader.AddressOfEntryPoint; size_t i; + unsigned char firstChar; + PLIST_ENTRY hashTable = GetPEBHashTable(); loaderModule = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LDR_MODULE)); if (loaderModule == NULL) @@ -377,15 +393,21 @@ InsertModuleInPEB(HMODULE module, unsigned char *name, unsigned char *baseName, loaderModule->Flags |= IMAGE_NOT_AT_BASE; loaderModule->TimeDateStamp = GET_NT_HEADER(module)->FileHeader.TimeDateStamp; - // XXX: do we need more set the hash table? - //loaderModule->HashTableEntry.Flink = &loaderModule->HashTableEntry; - //loaderModule->HashTableEntry.Blink = &loaderModule->HashTableEntry; - - AppendToChain(loaderModule, loaderData, InLoadOrderModuleList); - AppendToChain(loaderModule, loaderData, InInitializationOrderModuleList); + // add module to lookup table to speed up detection of already loaded libraries + firstChar = GET_FIRST_CHAR(loaderModule); + loaderModule->HashTableEntry.Flink = &hashTable[firstChar]; + loaderModule->HashTableEntry.Blink = &hashTable[firstChar]; + hashTable[firstChar].Blink = (PLIST_ENTRY)loaderModule; + hashTable[firstChar].Flink = (PLIST_ENTRY)loaderModule; + AppendToChain(loaderModule, loaderData, InLoadOrderModuleList, 0); + if (loaderModule->EntryPoint == 0) + loaderModule->InInitializationOrderModuleList.Blink = loaderModule->InInitializationOrderModuleList.Flink = 0; + else + AppendToChain(loaderModule, loaderData, InInitializationOrderModuleList, sizeof(LIST_ENTRY)*2); + // XXX: insert at the correct position in the chain - AppendToChain(loaderModule, loaderData, InMemoryOrderModuleList); + AppendToChain(loaderModule, loaderData, InMemoryOrderModuleList, sizeof(LIST_ENTRY)); return loaderModule; } From 0ee387d7baf93f83ac197459d1388c1d1aff1543 Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Fri, 8 Apr 2005 13:44:21 +0000 Subject: [PATCH 4/4] license changed to MPL 1.1, updated copyright years --- LICENSE.txt | 974 ++++++++++++++++++++++++------------------------- MemoryModule.c | 31 +- MemoryModule.h | 31 +- doc/readme.txt | 4 +- 4 files changed, 506 insertions(+), 534 deletions(-) diff --git a/LICENSE.txt b/LICENSE.txt index f3926a6..7714141 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,504 +1,470 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - + MOZILLA PUBLIC LICENSE + Version 1.1 + + --------------- + +1. Definitions. + + 1.0.1. "Commercial Use" means distribution or otherwise making the + Covered Code available to a third party. + + 1.1. "Contributor" means each entity that creates or contributes to + the creation of Modifications. + + 1.2. "Contributor Version" means the combination of the Original + Code, prior Modifications used by a Contributor, and the Modifications + made by that particular Contributor. + + 1.3. "Covered Code" means the Original Code or Modifications or the + combination of the Original Code and Modifications, in each case + including portions thereof. + + 1.4. "Electronic Distribution Mechanism" means a mechanism generally + accepted in the software development community for the electronic + transfer of data. + + 1.5. "Executable" means Covered Code in any form other than Source + Code. + + 1.6. "Initial Developer" means the individual or entity identified + as the Initial Developer in the Source Code notice required by Exhibit + A. + + 1.7. "Larger Work" means a work which combines Covered Code or + portions thereof with code not governed by the terms of this License. + + 1.8. "License" means this document. + + 1.8.1. "Licensable" means having the right to grant, to the maximum + extent possible, whether at the time of the initial grant or + subsequently acquired, any and all of the rights conveyed herein. + + 1.9. "Modifications" means any addition to or deletion from the + substance or structure of either the Original Code or any previous + Modifications. When Covered Code is released as a series of files, a + Modification is: + A. Any addition to or deletion from the contents of a file + containing Original Code or previous Modifications. + + B. Any new file that contains any part of the Original Code or + previous Modifications. + + 1.10. "Original Code" means Source Code of computer software code + which is described in the Source Code notice required by Exhibit A as + Original Code, and which, at the time of its release under this + License is not already Covered Code governed by this License. + + 1.10.1. "Patent Claims" means any patent claim(s), now owned or + hereafter acquired, including without limitation, method, process, + and apparatus claims, in any patent Licensable by grantor. + + 1.11. "Source Code" means the preferred form of the Covered Code for + making modifications to it, including all modules it contains, plus + any associated interface definition files, scripts used to control + compilation and installation of an Executable, or source code + differential comparisons against either the Original Code or another + well known, available Covered Code of the Contributor's choice. The + Source Code can be in a compressed or archival form, provided the + appropriate decompression or de-archiving software is widely available + for no charge. + + 1.12. "You" (or "Your") means an individual or a legal entity + exercising rights under, and complying with all of the terms of, this + License or a future version of this License issued under Section 6.1. + For legal entities, "You" includes any entity which controls, is + controlled by, or is under common control with You. For purposes of + this definition, "control" means (a) the power, direct or indirect, + to cause the direction or management of such entity, whether by + contract or otherwise, or (b) ownership of more than fifty percent + (50%) of the outstanding shares or beneficial ownership of such + entity. + +2. Source Code License. + + 2.1. The Initial Developer Grant. + The Initial Developer hereby grants You a world-wide, royalty-free, + non-exclusive license, subject to third party intellectual property + claims: + (a) under intellectual property rights (other than patent or + trademark) Licensable by Initial Developer to use, reproduce, + modify, display, perform, sublicense and distribute the Original + Code (or portions thereof) with or without Modifications, and/or + as part of a Larger Work; and + + (b) under Patents Claims infringed by the making, using or + selling of Original Code, to make, have made, use, practice, + sell, and offer for sale, and/or otherwise dispose of the + Original Code (or portions thereof). + + (c) the licenses granted in this Section 2.1(a) and (b) are + effective on the date Initial Developer first distributes + Original Code under the terms of this License. + + (d) Notwithstanding Section 2.1(b) above, no patent license is + granted: 1) for code that You delete from the Original Code; 2) + separate from the Original Code; or 3) for infringements caused + by: i) the modification of the Original Code or ii) the + combination of the Original Code with other software or devices. + + 2.2. Contributor Grant. + Subject to third party intellectual property claims, each Contributor + hereby grants You a world-wide, royalty-free, non-exclusive license + + (a) under intellectual property rights (other than patent or + trademark) Licensable by Contributor, to use, reproduce, modify, + display, perform, sublicense and distribute the Modifications + created by such Contributor (or portions thereof) either on an + unmodified basis, with other Modifications, as Covered Code + and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using, or + selling of Modifications made by that Contributor either alone + and/or in combination with its Contributor Version (or portions + of such combination), to make, use, sell, offer for sale, have + made, and/or otherwise dispose of: 1) Modifications made by that + Contributor (or portions thereof); and 2) the combination of + Modifications made by that Contributor with its Contributor + Version (or portions of such combination). + + (c) the licenses granted in Sections 2.2(a) and 2.2(b) are + effective on the date Contributor first makes Commercial Use of + the Covered Code. + + (d) Notwithstanding Section 2.2(b) above, no patent license is + granted: 1) for any code that Contributor has deleted from the + Contributor Version; 2) separate from the Contributor Version; + 3) for infringements caused by: i) third party modifications of + Contributor Version or ii) the combination of Modifications made + by that Contributor with other software (except as part of the + Contributor Version) or other devices; or 4) under Patent Claims + infringed by Covered Code in the absence of Modifications made by + that Contributor. + +3. Distribution Obligations. + + 3.1. Application of License. + The Modifications which You create or to which You contribute are + governed by the terms of this License, including without limitation + Section 2.2. The Source Code version of Covered Code may be + distributed only under the terms of this License or a future version + of this License released under Section 6.1, and You must include a + copy of this License with every copy of the Source Code You + distribute. You may not offer or impose any terms on any Source Code + version that alters or restricts the applicable version of this + License or the recipients' rights hereunder. However, You may include + an additional document offering the additional rights described in + Section 3.5. + + 3.2. Availability of Source Code. + Any Modification which You create or to which You contribute must be + made available in Source Code form under the terms of this License + either on the same media as an Executable version or via an accepted + Electronic Distribution Mechanism to anyone to whom you made an + Executable version available; and if made available via Electronic + Distribution Mechanism, must remain available for at least twelve (12) + months after the date it initially became available, or at least six + (6) months after a subsequent version of that particular Modification + has been made available to such recipients. You are responsible for + ensuring that the Source Code version remains available even if the + Electronic Distribution Mechanism is maintained by a third party. + + 3.3. Description of Modifications. + You must cause all Covered Code to which You contribute to contain a + file documenting the changes You made to create that Covered Code and + the date of any change. You must include a prominent statement that + the Modification is derived, directly or indirectly, from Original + Code provided by the Initial Developer and including the name of the + Initial Developer in (a) the Source Code, and (b) in any notice in an + Executable version or related documentation in which You describe the + origin or ownership of the Covered Code. + + 3.4. Intellectual Property Matters + (a) Third Party Claims. + If Contributor has knowledge that a license under a third party's + intellectual property rights is required to exercise the rights + granted by such Contributor under Sections 2.1 or 2.2, + Contributor must include a text file with the Source Code + distribution titled "LEGAL" which describes the claim and the + party making the claim in sufficient detail that a recipient will + know whom to contact. If Contributor obtains such knowledge after + the Modification is made available as described in Section 3.2, + Contributor shall promptly modify the LEGAL file in all copies + Contributor makes available thereafter and shall take other steps + (such as notifying appropriate mailing lists or newsgroups) + reasonably calculated to inform those who received the Covered + Code that new knowledge has been obtained. + + (b) Contributor APIs. + If Contributor's Modifications include an application programming + interface and Contributor has knowledge of patent licenses which + are reasonably necessary to implement that API, Contributor must + also include this information in the LEGAL file. + + (c) Representations. + Contributor represents that, except as disclosed pursuant to + Section 3.4(a) above, Contributor believes that Contributor's + Modifications are Contributor's original creation(s) and/or + Contributor has sufficient rights to grant the rights conveyed by + this License. + + 3.5. Required Notices. + You must duplicate the notice in Exhibit A in each file of the Source + Code. If it is not possible to put such notice in a particular Source + Code file due to its structure, then You must include such notice in a + location (such as a relevant directory) where a user would be likely + to look for such a notice. If You created one or more Modification(s) + You may add your name as a Contributor to the notice described in + Exhibit A. You must also duplicate this License in any documentation + for the Source Code where You describe recipients' rights or ownership + rights relating to Covered Code. You may choose to offer, and to + charge a fee for, warranty, support, indemnity or liability + obligations to one or more recipients of Covered Code. However, You + may do so only on Your own behalf, and not on behalf of the Initial + Developer or any Contributor. You must make it absolutely clear than + any such warranty, support, indemnity or liability obligation is + offered by You alone, and You hereby agree to indemnify the Initial + Developer and every Contributor for any liability incurred by the + Initial Developer or such Contributor as a result of warranty, + support, indemnity or liability terms You offer. + + 3.6. Distribution of Executable Versions. + You may distribute Covered Code in Executable form only if the + requirements of Section 3.1-3.5 have been met for that Covered Code, + and if You include a notice stating that the Source Code version of + the Covered Code is available under the terms of this License, + including a description of how and where You have fulfilled the + obligations of Section 3.2. The notice must be conspicuously included + in any notice in an Executable version, related documentation or + collateral in which You describe recipients' rights relating to the + Covered Code. You may distribute the Executable version of Covered + Code or ownership rights under a license of Your choice, which may + contain terms different from this License, provided that You are in + compliance with the terms of this License and that the license for the + Executable version does not attempt to limit or alter the recipient's + rights in the Source Code version from the rights set forth in this + License. If You distribute the Executable version under a different + license You must make it absolutely clear that any terms which differ + from this License are offered by You alone, not by the Initial + Developer or any Contributor. You hereby agree to indemnify the + Initial Developer and every Contributor for any liability incurred by + the Initial Developer or such Contributor as a result of any such + terms You offer. + + 3.7. Larger Works. + You may create a Larger Work by combining Covered Code with other code + not governed by the terms of this License and distribute the Larger + Work as a single product. In such a case, You must make sure the + requirements of this License are fulfilled for the Covered Code. + +4. Inability to Comply Due to Statute or Regulation. + + If it is impossible for You to comply with any of the terms of this + License with respect to some or all of the Covered Code due to + statute, judicial order, or regulation then You must: (a) comply with + the terms of this License to the maximum extent possible; and (b) + describe the limitations and the code they affect. Such description + must be included in the LEGAL file described in Section 3.4 and must + be included with all distributions of the Source Code. Except to the + extent prohibited by statute or regulation, such description must be + sufficiently detailed for a recipient of ordinary skill to be able to + understand it. + +5. Application of this License. + + This License applies to code to which the Initial Developer has + attached the notice in Exhibit A and to related Covered Code. + +6. Versions of the License. + + 6.1. New Versions. + Netscape Communications Corporation ("Netscape") may publish revised + and/or new versions of the License from time to time. Each version + will be given a distinguishing version number. + + 6.2. Effect of New Versions. + Once Covered Code has been published under a particular version of the + License, You may always continue to use it under the terms of that + version. You may also choose to use such Covered Code under the terms + of any subsequent version of the License published by Netscape. No one + other than Netscape has the right to modify the terms applicable to + Covered Code created under this License. + + 6.3. Derivative Works. + If You create or use a modified version of this License (which you may + only do in order to apply it to code which is not already Covered Code + governed by this License), You must (a) rename Your license so that + the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", + "MPL", "NPL" or any confusingly similar phrase do not appear in your + license (except to note that your license differs from this License) + and (b) otherwise make it clear that Your version of the license + contains terms which differ from the Mozilla Public License and + Netscape Public License. (Filling in the name of the Initial + Developer, Original Code or Contributor in the notice described in + Exhibit A shall not of themselves be deemed to be modifications of + this License.) + +7. DISCLAIMER OF WARRANTY. + + COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF + DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. + THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE + IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, + YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE + COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER + OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF + ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. + +8. TERMINATION. + + 8.1. This License and the rights granted hereunder will terminate + automatically if You fail to comply with terms herein and fail to cure + such breach within 30 days of becoming aware of the breach. All + sublicenses to the Covered Code which are properly granted shall + survive any termination of this License. Provisions which, by their + nature, must remain in effect beyond the termination of this License + shall survive. + + 8.2. If You initiate litigation by asserting a patent infringement + claim (excluding declatory judgment actions) against Initial Developer + or a Contributor (the Initial Developer or Contributor against whom + You file such action is referred to as "Participant") alleging that: + + (a) such Participant's Contributor Version directly or indirectly + infringes any patent, then any and all rights granted by such + Participant to You under Sections 2.1 and/or 2.2 of this License + shall, upon 60 days notice from Participant terminate prospectively, + unless if within 60 days after receipt of notice You either: (i) + agree in writing to pay Participant a mutually agreeable reasonable + royalty for Your past and future use of Modifications made by such + Participant, or (ii) withdraw Your litigation claim with respect to + the Contributor Version against such Participant. If within 60 days + of notice, a reasonable royalty and payment arrangement are not + mutually agreed upon in writing by the parties or the litigation claim + is not withdrawn, the rights granted by Participant to You under + Sections 2.1 and/or 2.2 automatically terminate at the expiration of + the 60 day notice period specified above. + + (b) any software, hardware, or device, other than such Participant's + Contributor Version, directly or indirectly infringes any patent, then + any rights granted to You by such Participant under Sections 2.1(b) + and 2.2(b) are revoked effective as of the date You first made, used, + sold, distributed, or had made, Modifications made by that + Participant. + + 8.3. If You assert a patent infringement claim against Participant + alleging that such Participant's Contributor Version directly or + indirectly infringes any patent where such claim is resolved (such as + by license or settlement) prior to the initiation of patent + infringement litigation, then the reasonable value of the licenses + granted by such Participant under Sections 2.1 or 2.2 shall be taken + into account in determining the amount or value of any payment or + license. + + 8.4. In the event of termination under Sections 8.1 or 8.2 above, + all end user license agreements (excluding distributors and resellers) + which have been validly granted by You or any distributor hereunder + prior to termination shall survive termination. + +9. LIMITATION OF LIABILITY. + + UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT + (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL + DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, + OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR + ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY + CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, + WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER + COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN + INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF + LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY + RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW + PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE + EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO + THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. + +10. U.S. GOVERNMENT END USERS. + + The Covered Code is a "commercial item," as that term is defined in + 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer + software" and "commercial computer software documentation," as such + terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 + C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), + all U.S. Government End Users acquire Covered Code with only those + rights set forth herein. + +11. MISCELLANEOUS. + + This License represents the complete agreement concerning subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the extent + necessary to make it enforceable. This License shall be governed by + California law provisions (except to the extent applicable law, if + any, provides otherwise), excluding its conflict-of-law provisions. + With respect to disputes in which at least one party is a citizen of, + or an entity chartered or registered to do business in the United + States of America, any litigation relating to this License shall be + subject to the jurisdiction of the Federal Courts of the Northern + District of California, with venue lying in Santa Clara County, + California, with the losing party responsible for costs, including + without limitation, court costs and reasonable attorneys' fees and + expenses. The application of the United Nations Convention on + Contracts for the International Sale of Goods is expressly excluded. + Any law or regulation which provides that the language of a contract + shall be construed against the drafter shall not apply to this + License. + +12. RESPONSIBILITY FOR CLAIMS. + + As between Initial Developer and the Contributors, each party is + responsible for claims and damages arising, directly or indirectly, + out of its utilization of rights under this License and You agree to + work with Initial Developer and Contributors to distribute such + responsibility on an equitable basis. Nothing herein is intended or + shall be deemed to constitute any admission of liability. + +13. MULTIPLE-LICENSED CODE. + + Initial Developer may designate portions of the Covered Code as + "Multiple-Licensed". "Multiple-Licensed" means that the Initial + Developer permits you to utilize portions of the Covered Code under + Your choice of the NPL or the alternative licenses, if any, specified + by the Initial Developer in the file described in Exhibit A. + +EXHIBIT A -Mozilla Public License. + + ``The contents of this file are subject to the Mozilla Public License + Version 1.1 (the "License"); you may not use this file except in + compliance with the License. You may obtain a copy of the License at + http://www.mozilla.org/MPL/ + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the + License for the specific language governing rights and limitations + under the License. + + The Original Code is ______________________________________. + + The Initial Developer of the Original Code is ________________________. + Portions created by ______________________ are Copyright (C) ______ + _______________________. All Rights Reserved. + + Contributor(s): ______________________________________. + + Alternatively, the contents of this file may be used under the terms + of the _____ license (the "[___] License"), in which case the + provisions of [______] License are applicable instead of those + above. If you wish to allow use of your version of this file only + under the terms of the [____] License and not to allow others to use + your version of this file under the MPL, indicate your decision by + deleting the provisions above and replace them with the notice and + other provisions required by the [___] License. If you do not delete + the provisions above, a recipient may use your version of this file + under either the MPL or the [___] License." + + [NOTE: The text of this Exhibit A may differ slightly from the text of + the notices in the Source Code files of the Original Code. You should + use the text of this Exhibit A rather than the text found in the + Original Code Source Code for Your Modifications.] + diff --git a/MemoryModule.c b/MemoryModule.c index e641c09..fa08b8d 100644 --- a/MemoryModule.c +++ b/MemoryModule.c @@ -2,22 +2,25 @@ * Memory DLL loading code * Version 0.0.1 * - * Copyright (c) 2004 by Joachim Bauch / mail@joachim-bauch.de + * Copyright (c) 2004-2005 by Joachim Bauch / mail@joachim-bauch.de * http://www.joachim-bauch.de * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is MemoryModule.c + * + * The Initial Developer of the Original Code is Joachim Bauch. + * + * Portions created by Joachim Bauch are Copyright (C) 2004-2005 + * Joachim Bauch. All Rights Reserved. * */ diff --git a/MemoryModule.h b/MemoryModule.h index 9dd4c31..5758b8e 100644 --- a/MemoryModule.h +++ b/MemoryModule.h @@ -2,22 +2,25 @@ * Memory DLL loading code * Version 0.0.1 * - * Copyright (c) 2004 by Joachim Bauch / mail@joachim-bauch.de + * Copyright (c) 2004-2005 by Joachim Bauch / mail@joachim-bauch.de * http://www.joachim-bauch.de * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is MemoryModule.h + * + * The Initial Developer of the Original Code is Joachim Bauch. + * + * Portions created by Joachim Bauch are Copyright (C) 2004-2005 + * Joachim Bauch. All Rights Reserved. * */ diff --git a/doc/readme.txt b/doc/readme.txt index 88bac81..1c6db6b 100644 --- a/doc/readme.txt +++ b/doc/readme.txt @@ -539,7 +539,7 @@ Known issues License -------- -The MemoryModule library is released under the Lesser General Public License (LGPL). +The MemoryModule library is released under the Mozilla Public License (MPL). It is provided as-is without ANY warranty. You may use it at your own risk. @@ -548,4 +548,4 @@ Copyright ========== The MemoryModule library and this tutorial are -Copyright (c) 2004 by Joachim Bauch. +Copyright (c) 2004-2005 by Joachim Bauch.