ntdll: Cache contents of IMAGE_TLS_DIRECTORY instead of saving a directory pointer.

Dmitry Timoshkov dmitry at baikal.ru
Tue Jul 14 03:36:12 CDT 2015


Molebox virtualizer zeros out the IMAGE_TLS_DIRECTORY contents of all
protected modules right after the module initialization. This leads
to inability to correctly initialize TLS storage and crashes due to
teb->ThreadLocalStoragePointer being NULL because dlls/ntdll/loader.c,
alloc_thread_tls() uses a pointer to IMAGE_TLS_DIRECTORY which contents
were trashed.

This patch makes pretty large and complex application written in Delphi
and protected by Molebox work.
---
 dlls/ntdll/loader.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 921bf57..bef0ab1 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -94,7 +94,7 @@ static struct builtin_load_info *builtin_load_info = &default_load_info;
 
 static HANDLE main_exe_file;
 static UINT tls_module_count;      /* number of modules with TLS directory */
-static const IMAGE_TLS_DIRECTORY **tls_dirs;  /* array of TLS directories */
+static IMAGE_TLS_DIRECTORY *tls_dirs;  /* array of TLS directories */
 LIST_ENTRY tls_links = { &tls_links, &tls_links };
 
 static RTL_CRITICAL_SECTION loader_section;
@@ -772,7 +772,12 @@ static SHORT alloc_tls_slot( LDR_MODULE *mod )
     size = dir->EndAddressOfRawData - dir->StartAddressOfRawData;
     if (!size && !dir->SizeOfZeroFill && !dir->AddressOfCallBacks) return -1;
 
-    for (i = 0; i < tls_module_count; i++) if (!tls_dirs[i]) break;
+    for (i = 0; i < tls_module_count; i++)
+    {
+        if (!tls_dirs[i].StartAddressOfRawData && !tls_dirs[i].EndAddressOfRawData &&
+            !tls_dirs[i].SizeOfZeroFill && !tls_dirs[i].AddressOfCallBacks)
+            break;
+    }
 
     TRACE( "module %p data %p-%p zerofill %u index %p callback %p flags %x -> slot %u\n", mod->BaseAddress,
            (void *)dir->StartAddressOfRawData, (void *)dir->EndAddressOfRawData, dir->SizeOfZeroFill,
@@ -824,7 +829,7 @@ static SHORT alloc_tls_slot( LDR_MODULE *mod )
     }
 
     *(DWORD *)dir->AddressOfIndex = i;
-    tls_dirs[i] = dir;
+    tls_dirs[i] = *dir;
     return i;
 }
 
@@ -841,7 +846,7 @@ static void free_tls_slot( LDR_MODULE *mod )
 
     if (mod->TlsIndex == -1) return;
     assert( i < tls_module_count );
-    tls_dirs[i] = NULL;
+    memset( &tls_dirs[i], 0, sizeof(tls_dirs[i]) );
 }
 
 
@@ -987,7 +992,7 @@ static NTSTATUS alloc_thread_tls(void)
 
     for (i = 0; i < tls_module_count; i++)
     {
-        const IMAGE_TLS_DIRECTORY *dir = tls_dirs[i];
+        const IMAGE_TLS_DIRECTORY *dir = &tls_dirs[i];
 
         if (!dir) continue;
         size = dir->EndAddressOfRawData - dir->StartAddressOfRawData;
-- 
2.4.5




More information about the wine-patches mailing list