diff options
author | Tavis Ormandy <taviso@gmail.com> | 2019-08-20 22:00:08 +0300 |
---|---|---|
committer | Tavis Ormandy <taviso@gmail.com> | 2019-08-20 22:00:08 +0300 |
commit | e14ffb3ec82c9fdcefedabc1fe18f925db395035 (patch) | |
tree | 27a7d9d9e2103f6045622136d923a8814f4c2a9d | |
parent | bcef39830093b6152ce0cfc87851c58bbe802df5 (diff) |
First attempt at fixing #65
We need to do at least minimal processing of .tls sections.
-rw-r--r-- | peloader/pe_linker.c | 24 | ||||
-rw-r--r-- | peloader/pe_linker.h | 19 | ||||
-rw-r--r-- | peloader/winapi/TlsAlloc.c | 3 |
3 files changed, 38 insertions, 8 deletions
diff --git a/peloader/pe_linker.c b/peloader/pe_linker.c index 19b83ea..f9c3884 100644 --- a/peloader/pe_linker.c +++ b/peloader/pe_linker.c @@ -88,6 +88,8 @@ static const char *image_directory_name[] = { extern struct wrap_export crt_exports[]; +uintptr_t LocalStorage[1024] = {0}; + struct hsearch_data extraexports; struct hsearch_data crtexports; @@ -559,6 +561,26 @@ int link_pe_images(struct pe_image *pe_image, unsigned short n) pe->opt_hdr->AddressOfEntryPoint, void *); //TRACE1("entry is at %p, rva at %08X", pe->entry, // pe->opt_hdr->AddressOfEntryPoint); + + // Check if there were enough data directories for a TLS section. + if (pe->opt_hdr->NumberOfRvaAndSizes >= IMAGE_DIRECTORY_ENTRY_TLS) { + // Normally, we would be expected to allocate a TLS slot, + // place the number into *TlsData->AddressOfIndex, and make + // it a pointer to RawData, and then process the callbacks. + // + // We don't support threads, so it seems safe to just + // pre-allocate a slot and point it straight to the + // template data. + // + // FIXME: Verify callbacks list is empty and SizeOfZeroFill is zero. + // + PIMAGE_TLS_DIRECTORY TlsData = RVA2VA(pe->image, + pe->opt_hdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress, + IMAGE_TLS_DIRECTORY *); + + // This means that slot 0 is reserved. + LocalStorage[0] = TlsData->RawDataStart; + } } return 0; @@ -622,8 +644,6 @@ error: return false; } -uintptr_t LocalStorage[1024] = {0}; - bool setup_nt_threadinfo(PEXCEPTION_HANDLER ExceptionHandler) { static EXCEPTION_FRAME ExceptionFrame; diff --git a/peloader/pe_linker.h b/peloader/pe_linker.h index ac202a9..4837bf7 100644 --- a/peloader/pe_linker.h +++ b/peloader/pe_linker.h @@ -987,16 +987,25 @@ typedef struct _CLIENT_ID { } CLIENT_ID; typedef struct _TEB { - NT_TIB Tib; - PVOID EnvironmentPointer; - CLIENT_ID Cid; - PVOID ActiveRpcInfo; - PVOID ThreadLocalStoragePointer; + NT_TIB Tib; + PVOID EnvironmentPointer; + CLIENT_ID Cid; + PVOID ActiveRpcInfo; + PVOID ThreadLocalStoragePointer; // The fields below this are deliberately omitted so that access causes a // crash (because of the segment limit). This lets me know I have to fix // it, otherwise the error is very difficult to track down. } TEB, *PTEB; +typedef struct _IMAGE_TLS_DIRECTORY { + PVOID RawDataStart; + PVOID RawDataEnd; + PDWORD AddressOfIndex; + PVOID AddressOfCallbacks; + DWORD SizeOfZeroFill; + DWORD Characteristics; +} IMAGE_TLS_DIRECTORY, *PIMAGE_TLS_DIRECTORY; + struct user_desc { unsigned int entry_number; unsigned long base_addr; diff --git a/peloader/winapi/TlsAlloc.c b/peloader/winapi/TlsAlloc.c index 81d5ddf..e9ae9e4 100644 --- a/peloader/winapi/TlsAlloc.c +++ b/peloader/winapi/TlsAlloc.c @@ -16,7 +16,8 @@ # define TLS_OUT_OF_INDEXES 0xFFFFFFFF #endif -static int TlsIndex; +// Index zero is reserved for .tls +static int TlsIndex = 1; extern uintptr_t LocalStorage[1024]; STATIC DWORD WINAPI TlsAlloc(void) |