1
0
Fork 0

Rewrite ReadTlsCallbacks() to use RtlImageDirectoryEntryToData and remove all TitanEngine calls. Also fix an anti-debug trick I found by accident: it is possible to have working TLS callbacks with a TLS directory size of 0. The loader does not check this field and always executes callbacks if they exist

This commit is contained in:
Mattiwatti 2018-03-20 06:59:19 +01:00 committed by Duncan Ogilvie
parent 28c03967c7
commit 6df9535ba4
No known key found for this signature in database
GPG Key ID: FC89E0AAA0C1AAD8
1 changed files with 14 additions and 13 deletions

View File

@ -241,29 +241,30 @@ static void ReadImportDirectory(MODINFO & Info, ULONG_PTR FileMapVA)
static void ReadTlsCallbacks(MODINFO & Info, ULONG_PTR FileMapVA)
{
// TODO: proper bounds checking
// Clear TLS callbacks
Info.tlsCallbacks.clear();
// Get address and size of base relocation table
duint tlsDirRva = GetPE32DataFromMappedFile(FileMapVA, 0, UE_TLSTABLEADDRESS);
duint tlsDirSize = GetPE32DataFromMappedFile(FileMapVA, 0, UE_TLSTABLESIZE);
if(tlsDirRva == 0 || tlsDirSize == 0)
// Get the TLS directory
ULONG tlsDirSize;
auto tlsDir = (PIMAGE_TLS_DIRECTORY)RtlImageDirectoryEntryToData((PVOID)FileMapVA,
FALSE,
IMAGE_DIRECTORY_ENTRY_TLS,
&tlsDirSize);
if(tlsDir == nullptr /*|| tlsDirSize == 0*/) // The loader completely ignores the directory size. Setting it to 0 is an anti-debug trick
return;
auto tlsDirOffset = ConvertVAtoFileOffsetEx(FileMapVA, Info.loadedSize, 0, tlsDirRva, true, false);
if(!tlsDirOffset)
return;
auto tlsDir = PIMAGE_TLS_DIRECTORY(tlsDirOffset + FileMapVA);
if(!tlsDir->AddressOfCallBacks)
ULONG64 addressOfCallbacks = IMAGE64(Info.headers)
? ((PIMAGE_TLS_DIRECTORY64)tlsDir)->AddressOfCallBacks
: (ULONG64)((PIMAGE_TLS_DIRECTORY32)tlsDir)->AddressOfCallBacks;
if(!addressOfCallbacks)
return;
auto imageBase = GetPE32DataFromMappedFile(FileMapVA, 0, UE_IMAGEBASE);
auto tlsArrayOffset = ConvertVAtoFileOffsetEx(FileMapVA, Info.loadedSize, 0, tlsDir->AddressOfCallBacks - imageBase, true, false);
auto imageBase = HEADER_FIELD(Info.headers, ImageBase);
auto tlsArrayOffset = RvaToVa(0, Info.headers, tlsDir->AddressOfCallBacks - imageBase);
if(!tlsArrayOffset)
return;
// TODO: proper bounds checking
auto tlsArray = PULONG_PTR(tlsArrayOffset + FileMapVA);
while(*tlsArray)
Info.tlsCallbacks.push_back(*tlsArray++ - imageBase + Info.base);