- rewrote TitanEngine.TLS (resolved issue #38) (tested&working partially on x32)

This commit is contained in:
Mr. eXoDia 2014-03-18 22:38:00 +01:00
parent 2ddae28d52
commit 05f9b7a3fc
6 changed files with 171 additions and 224 deletions

View File

@ -25,7 +25,7 @@ DEBUG_EVENT DBGEvent = {};
DEBUG_EVENT TerminateDBGEvent = {}; DEBUG_EVENT TerminateDBGEvent = {};
DWORD ProcessExitCode = 0; DWORD ProcessExitCode = 0;
HANDLE DBGFileHandle; HANDLE DBGFileHandle;
ULONG_PTR tlsCallBackList[100]; std::vector<ULONG_PTR> tlsCallBackList;
std::vector<PROCESS_ITEM_DATA> hListProcess; std::vector<PROCESS_ITEM_DATA> hListProcess;
int engineStepCount = INFINITE; int engineStepCount = INFINITE;
LPVOID engineStepCallBack = NULL; LPVOID engineStepCallBack = NULL;
@ -74,6 +74,11 @@ void ClearProcessList()
std::vector<PROCESS_ITEM_DATA>().swap(hListProcess); std::vector<PROCESS_ITEM_DATA>().swap(hListProcess);
} }
void ClearTlsCallBackList()
{
std::vector<ULONG_PTR>().swap(tlsCallBackList);
}
void StepOutStepCallBack() void StepOutStepCallBack()
{ {
BYTE cipch = 0x90; BYTE cipch = 0x90;

View File

@ -25,7 +25,7 @@ extern DEBUG_EVENT DBGEvent;
extern DEBUG_EVENT TerminateDBGEvent; extern DEBUG_EVENT TerminateDBGEvent;
extern DWORD ProcessExitCode; extern DWORD ProcessExitCode;
extern HANDLE DBGFileHandle; extern HANDLE DBGFileHandle;
extern ULONG_PTR tlsCallBackList[100]; extern std::vector<ULONG_PTR> tlsCallBackList;
extern std::vector<PROCESS_ITEM_DATA> hListProcess; extern std::vector<PROCESS_ITEM_DATA> hListProcess;
extern int engineStepCount; extern int engineStepCount;
extern LPVOID engineStepCallBack; extern LPVOID engineStepCallBack;
@ -42,6 +42,7 @@ extern LPVOID StepOutCallBack;
long DebugLoopInSecondThread(LPVOID InputParameter); long DebugLoopInSecondThread(LPVOID InputParameter);
void DebuggerReset(); void DebuggerReset();
void ClearProcessList(); void ClearProcessList();
void ClearTlsCallBackList();
void StepOutStepCallBack(); void StepOutStepCallBack();
#endif //_GLOBAL_DEBUGGER_H #endif //_GLOBAL_DEBUGGER_H

View File

@ -4,3 +4,8 @@
ULONG_PTR engineTLSBreakOnCallBackAddress; ULONG_PTR engineTLSBreakOnCallBackAddress;
bool engineTLSBreakOnCallBack = false; bool engineTLSBreakOnCallBack = false;
void ClearTlsVector(std::vector<ULONG_PTR>* vec)
{
std::vector<ULONG_PTR>().swap(*vec);
}

View File

@ -1,7 +1,11 @@
#ifndef _GLOBAL_TLS_H #ifndef _GLOBAL_TLS_H
#define _GLOBAL_TLS_H #define _GLOBAL_TLS_H
#include <vector>
extern ULONG_PTR engineTLSBreakOnCallBackAddress; extern ULONG_PTR engineTLSBreakOnCallBackAddress;
extern bool engineTLSBreakOnCallBack; extern bool engineTLSBreakOnCallBack;
void ClearTlsVector(std::vector<ULONG_PTR>* vec);
#endif //_GLOBAL_TLS_H #endif //_GLOBAL_TLS_H

View File

@ -588,13 +588,9 @@ __declspec(dllexport) void TITCALL DebugLoop()
} }
if(engineTLSBreakOnCallBack) //set TLS callback breakpoints if(engineTLSBreakOnCallBack) //set TLS callback breakpoints
{ {
int i = NULL; for(unsigned int i=0; i<tlsCallBackList.size(); i++)
while(tlsCallBackList[i] != NULL) SetBPX(tlsCallBackList.at(i), UE_SINGLESHOOT, (LPVOID)engineTLSBreakOnCallBackAddress);
{ ClearTlsCallBackList();
SetBPX((ULONG_PTR)tlsCallBackList[i], UE_SINGLESHOOT, (LPVOID)engineTLSBreakOnCallBackAddress);
tlsCallBackList[i] = NULL;
i++;
}
engineTLSBreakOnCallBackAddress = NULL; engineTLSBreakOnCallBackAddress = NULL;
engineTLSBreakOnCallBack = false; engineTLSBreakOnCallBack = false;
} }

View File

@ -9,72 +9,52 @@ static bool engineBackupTLSx64 = false;
static IMAGE_TLS_DIRECTORY32 engineBackupTLSDataX86 = {}; static IMAGE_TLS_DIRECTORY32 engineBackupTLSDataX86 = {};
static IMAGE_TLS_DIRECTORY64 engineBackupTLSDataX64 = {}; static IMAGE_TLS_DIRECTORY64 engineBackupTLSDataX64 = {};
static DWORD engineBackupNumberOfCallBacks = NULL; static DWORD engineBackupNumberOfCallBacks = NULL;
static LPVOID engineBackupArrayOfCallBacks = VirtualAlloc(NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE); static std::vector<ULONG_PTR> engineBackupArrayOfCallBacks;
static DWORD engineBackupTLSAddress = NULL; static DWORD engineBackupTLSAddress = NULL;
// TitanEngine.TLSFixer.functions: // TitanEngine.TLS.functions:
__declspec(dllexport) bool TITCALL TLSBreakOnCallBack(LPVOID ArrayOfCallBacks, DWORD NumberOfCallBacks, LPVOID bpxCallBack) __declspec(dllexport) bool TITCALL TLSBreakOnCallBack(LPVOID ArrayOfCallBacks, DWORD NumberOfCallBacks, LPVOID bpxCallBack)
{ {
ULONG_PTR* ReadArrayOfCallBacks = (ULONG_PTR*)ArrayOfCallBacks;
unsigned int i; if(NumberOfCallBacks && EngineIsValidReadPtrEx(ReadArrayOfCallBacks, sizeof(ULONG_PTR)*NumberOfCallBacks) && bpxCallBack)
LPVOID ReadArrayOfCallBacks = ArrayOfCallBacks;
if(NumberOfCallBacks > NULL)
{ {
for(i = 0; i < NumberOfCallBacks; i++) ClearTlsCallBackList(); //clear TLS cb list
{ for(unsigned int i=0; i<NumberOfCallBacks; i++)
RtlMoveMemory(&tlsCallBackList[i], ReadArrayOfCallBacks, sizeof ULONG_PTR); tlsCallBackList.push_back(ReadArrayOfCallBacks[i]);
ReadArrayOfCallBacks = (LPVOID)((ULONG_PTR)ReadArrayOfCallBacks + sizeof ULONG_PTR);
}
engineTLSBreakOnCallBackAddress = (ULONG_PTR)bpxCallBack; engineTLSBreakOnCallBackAddress = (ULONG_PTR)bpxCallBack;
engineTLSBreakOnCallBack = true; engineTLSBreakOnCallBack = true;
return true; return true;
} }
else
{
return false; return false;
} }
}
__declspec(dllexport) bool TITCALL TLSGrabCallBackData(char* szFileName, LPVOID ArrayOfCallBacks, LPDWORD NumberOfCallBacks) __declspec(dllexport) bool TITCALL TLSGrabCallBackData(char* szFileName, LPVOID ArrayOfCallBacks, LPDWORD NumberOfCallBacks)
{ {
wchar_t uniFileName[MAX_PATH] = {}; wchar_t uniFileName[MAX_PATH] = {};
if(szFileName)
if(szFileName != NULL)
{ {
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0]))); MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
return(TLSGrabCallBackDataW(uniFileName, ArrayOfCallBacks, NumberOfCallBacks)); return TLSGrabCallBackDataW(uniFileName, ArrayOfCallBacks, NumberOfCallBacks);
} }
else
{
return false; return false;
} }
}
__declspec(dllexport) bool TITCALL TLSGrabCallBackDataW(wchar_t* szFileName, LPVOID ArrayOfCallBacks, LPDWORD NumberOfCallBacks) __declspec(dllexport) bool TITCALL TLSGrabCallBackDataW(wchar_t* szFileName, LPVOID ArrayOfCallBacks, LPDWORD NumberOfCallBacks)
{ {
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
HANDLE FileHandle; HANDLE FileHandle;
DWORD FileSize; DWORD FileSize;
HANDLE FileMap; HANDLE FileMap;
ULONG_PTR FileMapVA; ULONG_PTR FileMapVA;
BOOL FileIs64;
PIMAGE_TLS_DIRECTORY32 TLSDirectoryX86;
PIMAGE_TLS_DIRECTORY64 TLSDirectoryX64;
ULONG_PTR TLSDirectoryAddress;
ULONG_PTR TLSCallBackAddress;
ULONG_PTR TLSCompareData = NULL;
DWORD NumberOfTLSCallBacks = NULL;
if(MapFileExW(szFileName, UE_ACCESS_READ, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL)) if(MapFileExW(szFileName, UE_ACCESS_READ, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{ {
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA; PIMAGE_DOS_HEADER DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, FileHandle, NULL, DOSHeader, true)) if(EngineValidateHeader(FileMapVA, FileHandle, NULL, DOSHeader, true))
{ {
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew); DWORD NumberOfTLSCallBacks = 0;
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew); PIMAGE_NT_HEADERS32 PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PIMAGE_NT_HEADERS64 PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
bool FileIs64;
if(PEHeader32->OptionalHeader.Magic == 0x10B) if(PEHeader32->OptionalHeader.Magic == 0x10B)
{ {
FileIs64 = false; FileIs64 = false;
@ -88,70 +68,84 @@ __declspec(dllexport) bool TITCALL TLSGrabCallBackDataW(wchar_t* szFileName, LPV
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA); UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return false; return false;
} }
if(!FileIs64) if(!FileIs64) //x86
{ {
if(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress != NULL) if(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress != NULL)
{ {
TLSDirectoryAddress = (ULONG_PTR)((ULONG_PTR)PEHeader32->OptionalHeader.ImageBase + PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress); ULONG_PTR TLSDirectoryAddress = (ULONG_PTR)((ULONG_PTR)PEHeader32->OptionalHeader.ImageBase + PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress);
TLSDirectoryX86 = (PIMAGE_TLS_DIRECTORY32)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)TLSDirectoryAddress, true); PIMAGE_TLS_DIRECTORY32 TLSDirectoryX86 = (PIMAGE_TLS_DIRECTORY32)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)TLSDirectoryAddress, true);
if(TLSDirectoryX86->AddressOfCallBacks != NULL) if(TLSDirectoryX86->AddressOfCallBacks != NULL)
{ {
TLSCallBackAddress = (ULONG_PTR)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)TLSDirectoryX86->AddressOfCallBacks, true); ULONG_PTR TLSCompareData = 0;
ULONG_PTR TLSCallBackAddress = (ULONG_PTR)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)TLSDirectoryX86->AddressOfCallBacks, true);
while(memcmp((LPVOID)TLSCallBackAddress, &TLSCompareData, sizeof ULONG_PTR) != NULL) while(memcmp((LPVOID)TLSCallBackAddress, &TLSCompareData, sizeof ULONG_PTR) != NULL)
{
if(ArrayOfCallBacks)
{ {
RtlMoveMemory(ArrayOfCallBacks, (LPVOID)TLSCallBackAddress, sizeof ULONG_PTR); RtlMoveMemory(ArrayOfCallBacks, (LPVOID)TLSCallBackAddress, sizeof ULONG_PTR);
ArrayOfCallBacks = (LPVOID)((ULONG_PTR)ArrayOfCallBacks + sizeof ULONG_PTR); ArrayOfCallBacks = (LPVOID)((ULONG_PTR)ArrayOfCallBacks + sizeof ULONG_PTR);
}
TLSCallBackAddress = TLSCallBackAddress + sizeof ULONG_PTR; TLSCallBackAddress = TLSCallBackAddress + sizeof ULONG_PTR;
NumberOfTLSCallBacks++; NumberOfTLSCallBacks++;
} }
if(NumberOfCallBacks)
*NumberOfCallBacks = NumberOfTLSCallBacks; *NumberOfCallBacks = NumberOfTLSCallBacks;
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA); UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return true; return true;
} }
else else
{ {
*NumberOfCallBacks = NULL; if(NumberOfCallBacks)
*NumberOfCallBacks = 0;
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA); UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return false; return false;
} }
} }
else else
{ {
*NumberOfCallBacks = NULL; if(NumberOfCallBacks)
*NumberOfCallBacks = 0;
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA); UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return false; return false;
} }
} }
else else //x64
{ {
if(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress != NULL) if(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress != NULL)
{ {
TLSDirectoryAddress = (ULONG_PTR)((ULONG_PTR)PEHeader64->OptionalHeader.ImageBase + PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress); ULONG_PTR TLSDirectoryAddress = (ULONG_PTR)((ULONG_PTR)PEHeader64->OptionalHeader.ImageBase + PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress);
TLSDirectoryX64 = (PIMAGE_TLS_DIRECTORY64)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)TLSDirectoryAddress, true); PIMAGE_TLS_DIRECTORY64 TLSDirectoryX64 = (PIMAGE_TLS_DIRECTORY64)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)TLSDirectoryAddress, true);
if(TLSDirectoryX64->AddressOfCallBacks != NULL) if(TLSDirectoryX64->AddressOfCallBacks != NULL)
{ {
TLSCallBackAddress = (ULONG_PTR)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)TLSDirectoryX64->AddressOfCallBacks, true); ULONG_PTR TLSCompareData = NULL;
ULONG_PTR TLSCallBackAddress = (ULONG_PTR)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)TLSDirectoryX64->AddressOfCallBacks, true);
while(memcmp((LPVOID)TLSCallBackAddress, &TLSCompareData, sizeof ULONG_PTR) != NULL) while(memcmp((LPVOID)TLSCallBackAddress, &TLSCompareData, sizeof ULONG_PTR) != NULL)
{
if(ArrayOfCallBacks)
{ {
RtlMoveMemory(ArrayOfCallBacks, (LPVOID)TLSCallBackAddress, sizeof ULONG_PTR); RtlMoveMemory(ArrayOfCallBacks, (LPVOID)TLSCallBackAddress, sizeof ULONG_PTR);
ArrayOfCallBacks = (LPVOID)((ULONG_PTR)ArrayOfCallBacks + sizeof ULONG_PTR); ArrayOfCallBacks = (LPVOID)((ULONG_PTR)ArrayOfCallBacks + sizeof ULONG_PTR);
}
TLSCallBackAddress = TLSCallBackAddress + sizeof ULONG_PTR; TLSCallBackAddress = TLSCallBackAddress + sizeof ULONG_PTR;
NumberOfTLSCallBacks++; NumberOfTLSCallBacks++;
} }
if(NumberOfCallBacks)
*NumberOfCallBacks = NumberOfTLSCallBacks; *NumberOfCallBacks = NumberOfTLSCallBacks;
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA); UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return true; return true;
} }
else else
{ {
*NumberOfCallBacks = NULL; if(NumberOfCallBacks)
*NumberOfCallBacks = 0;
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA); UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return false; return false;
} }
} }
else else
{ {
*NumberOfCallBacks = NULL; if(NumberOfCallBacks)
*NumberOfCallBacks = 0;
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA); UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return false; return false;
} }
@ -159,89 +153,65 @@ __declspec(dllexport) bool TITCALL TLSGrabCallBackDataW(wchar_t* szFileName, LPV
} }
else else
{ {
*NumberOfCallBacks = NULL; if(NumberOfCallBacks)
*NumberOfCallBacks = 0;
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA); UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return false; return false;
} }
} }
return false; return false;
} }
__declspec(dllexport) bool TITCALL TLSBreakOnCallBackEx(char* szFileName, LPVOID bpxCallBack) __declspec(dllexport) bool TITCALL TLSBreakOnCallBackEx(char* szFileName, LPVOID bpxCallBack)
{ {
wchar_t uniFileName[MAX_PATH] = {}; wchar_t uniFileName[MAX_PATH] = {};
if(szFileName)
if(szFileName != NULL)
{ {
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0]))); MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
return(TLSBreakOnCallBackExW(uniFileName, bpxCallBack)); return TLSBreakOnCallBackExW(uniFileName, bpxCallBack);
} }
else
{
return false; return false;
} }
}
__declspec(dllexport) bool TITCALL TLSBreakOnCallBackExW(wchar_t* szFileName, LPVOID bpxCallBack) __declspec(dllexport) bool TITCALL TLSBreakOnCallBackExW(wchar_t* szFileName, LPVOID bpxCallBack)
{ {
DWORD NumberOfCallBacks;
ULONG_PTR TlsArrayOfCallBacks[100]; if(TLSGrabCallBackDataW(szFileName, NULL, &NumberOfCallBacks))
DWORD TlsNumberOfCallBacks;
RtlZeroMemory(&TlsArrayOfCallBacks, 100 * sizeof ULONG_PTR);
if(szFileName != NULL)
{ {
if(TLSGrabCallBackDataW(szFileName, &TlsArrayOfCallBacks, &TlsNumberOfCallBacks)) DynBuf TlsArrayOfCallBacks(NumberOfCallBacks*sizeof(ULONG_PTR));
if(TLSGrabCallBackDataW(szFileName, TlsArrayOfCallBacks.GetPtr(), &NumberOfCallBacks))
{ {
TLSBreakOnCallBack(&TlsArrayOfCallBacks, TlsNumberOfCallBacks, bpxCallBack); return TLSBreakOnCallBack(TlsArrayOfCallBacks.GetPtr(), NumberOfCallBacks, bpxCallBack);
return true; }
} }
else
{
return false; return false;
} }
}
else
{
return false;
}
}
__declspec(dllexport) bool TITCALL TLSRemoveCallback(char* szFileName) __declspec(dllexport) bool TITCALL TLSRemoveCallback(char* szFileName)
{ {
wchar_t uniFileName[MAX_PATH] = {}; wchar_t uniFileName[MAX_PATH] = {};
if(szFileName)
if(szFileName != NULL)
{ {
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0]))); MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
return(TLSRemoveCallbackW(uniFileName)); return TLSRemoveCallbackW(uniFileName);
} }
else
{
return false; return false;
} }
}
__declspec(dllexport) bool TITCALL TLSRemoveCallbackW(wchar_t* szFileName) __declspec(dllexport) bool TITCALL TLSRemoveCallbackW(wchar_t* szFileName)
{ {
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
HANDLE FileHandle; HANDLE FileHandle;
DWORD FileSize; DWORD FileSize;
HANDLE FileMap; HANDLE FileMap;
ULONG_PTR FileMapVA; ULONG_PTR FileMapVA;
BOOL FileIs64;
PIMAGE_TLS_DIRECTORY32 TLSDirectoryX86;
PIMAGE_TLS_DIRECTORY64 TLSDirectoryX64;
ULONG_PTR TLSDirectoryAddress;
if(MapFileExW(szFileName, UE_ACCESS_ALL, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL)) if(MapFileExW(szFileName, UE_ACCESS_ALL, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{ {
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA; PIMAGE_DOS_HEADER DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, FileHandle, NULL, DOSHeader, true)) if(EngineValidateHeader(FileMapVA, FileHandle, NULL, DOSHeader, true))
{ {
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew); PIMAGE_NT_HEADERS32 PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew); PIMAGE_NT_HEADERS64 PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
bool FileIs64;
if(PEHeader32->OptionalHeader.Magic == 0x10B) if(PEHeader32->OptionalHeader.Magic == 0x10B)
{ {
FileIs64 = false; FileIs64 = false;
@ -261,8 +231,8 @@ __declspec(dllexport) bool TITCALL TLSRemoveCallbackW(wchar_t* szFileName)
{ {
__try __try
{ {
TLSDirectoryAddress = (ULONG_PTR)((ULONG_PTR)PEHeader32->OptionalHeader.ImageBase + PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress); ULONG_PTR TLSDirectoryAddress = (ULONG_PTR)((ULONG_PTR)PEHeader32->OptionalHeader.ImageBase + PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress);
TLSDirectoryX86 = (PIMAGE_TLS_DIRECTORY32)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)TLSDirectoryAddress, true); PIMAGE_TLS_DIRECTORY32 TLSDirectoryX86 = (PIMAGE_TLS_DIRECTORY32)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)TLSDirectoryAddress, true);
if(TLSDirectoryX86->AddressOfCallBacks != NULL) if(TLSDirectoryX86->AddressOfCallBacks != NULL)
{ {
TLSDirectoryX86->AddressOfCallBacks = NULL; TLSDirectoryX86->AddressOfCallBacks = NULL;
@ -293,8 +263,8 @@ __declspec(dllexport) bool TITCALL TLSRemoveCallbackW(wchar_t* szFileName)
{ {
__try __try
{ {
TLSDirectoryAddress = (ULONG_PTR)((ULONG_PTR)PEHeader64->OptionalHeader.ImageBase + PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress); ULONG_PTR TLSDirectoryAddress = (ULONG_PTR)((ULONG_PTR)PEHeader64->OptionalHeader.ImageBase + PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress);
TLSDirectoryX64 = (PIMAGE_TLS_DIRECTORY64)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)TLSDirectoryAddress, true); PIMAGE_TLS_DIRECTORY64 TLSDirectoryX64 = (PIMAGE_TLS_DIRECTORY64)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)TLSDirectoryAddress, true);
if(TLSDirectoryX64->AddressOfCallBacks != NULL) if(TLSDirectoryX64->AddressOfCallBacks != NULL)
{ {
TLSDirectoryX64->AddressOfCallBacks = NULL; TLSDirectoryX64->AddressOfCallBacks = NULL;
@ -328,43 +298,32 @@ __declspec(dllexport) bool TITCALL TLSRemoveCallbackW(wchar_t* szFileName)
} }
return false; return false;
} }
__declspec(dllexport) bool TITCALL TLSRemoveTable(char* szFileName) __declspec(dllexport) bool TITCALL TLSRemoveTable(char* szFileName)
{ {
wchar_t uniFileName[MAX_PATH] = {}; wchar_t uniFileName[MAX_PATH] = {};
if(szFileName)
if(szFileName != NULL)
{ {
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0]))); MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
return(TLSRemoveTableW(uniFileName)); return TLSRemoveTableW(uniFileName);
} }
else
{
return false; return false;
} }
}
__declspec(dllexport) bool TITCALL TLSRemoveTableW(wchar_t* szFileName) __declspec(dllexport) bool TITCALL TLSRemoveTableW(wchar_t* szFileName)
{ {
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
HANDLE FileHandle; HANDLE FileHandle;
DWORD FileSize; DWORD FileSize;
HANDLE FileMap; HANDLE FileMap;
ULONG_PTR FileMapVA; ULONG_PTR FileMapVA;
BOOL FileIs64;
PIMAGE_TLS_DIRECTORY32 TLSDirectoryX86;
PIMAGE_TLS_DIRECTORY64 TLSDirectoryX64;
ULONG_PTR TLSDirectoryAddress;
if(MapFileExW(szFileName, UE_ACCESS_ALL, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL)) if(MapFileExW(szFileName, UE_ACCESS_ALL, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{ {
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA; PIMAGE_DOS_HEADER DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, FileHandle, NULL, DOSHeader, true)) if(EngineValidateHeader(FileMapVA, FileHandle, NULL, DOSHeader, true))
{ {
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew); PIMAGE_NT_HEADERS32 PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew); PIMAGE_NT_HEADERS64 PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
bool FileIs64;
if(PEHeader32->OptionalHeader.Magic == 0x10B) if(PEHeader32->OptionalHeader.Magic == 0x10B)
{ {
FileIs64 = false; FileIs64 = false;
@ -384,8 +343,8 @@ __declspec(dllexport) bool TITCALL TLSRemoveTableW(wchar_t* szFileName)
{ {
__try __try
{ {
TLSDirectoryAddress = (ULONG_PTR)((ULONG_PTR)PEHeader32->OptionalHeader.ImageBase + PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress); ULONG_PTR TLSDirectoryAddress = (ULONG_PTR)((ULONG_PTR)PEHeader32->OptionalHeader.ImageBase + PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress);
TLSDirectoryX86 = (PIMAGE_TLS_DIRECTORY32)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)TLSDirectoryAddress, true); PIMAGE_TLS_DIRECTORY32 TLSDirectoryX86 = (PIMAGE_TLS_DIRECTORY32)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)TLSDirectoryAddress, true);
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress = NULL; PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress = NULL;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size = NULL; PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size = NULL;
RtlZeroMemory(TLSDirectoryX86, sizeof IMAGE_TLS_DIRECTORY32); RtlZeroMemory(TLSDirectoryX86, sizeof IMAGE_TLS_DIRECTORY32);
@ -410,8 +369,8 @@ __declspec(dllexport) bool TITCALL TLSRemoveTableW(wchar_t* szFileName)
{ {
__try __try
{ {
TLSDirectoryAddress = (ULONG_PTR)((ULONG_PTR)PEHeader64->OptionalHeader.ImageBase + PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress); ULONG_PTR TLSDirectoryAddress = (ULONG_PTR)((ULONG_PTR)PEHeader64->OptionalHeader.ImageBase + PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress);
TLSDirectoryX64 = (PIMAGE_TLS_DIRECTORY64)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)TLSDirectoryAddress, true); PIMAGE_TLS_DIRECTORY64 TLSDirectoryX64 = (PIMAGE_TLS_DIRECTORY64)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)TLSDirectoryAddress, true);
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress = NULL; PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress = NULL;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size = NULL; PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size = NULL;
RtlZeroMemory(TLSDirectoryX64, sizeof IMAGE_TLS_DIRECTORY64); RtlZeroMemory(TLSDirectoryX64, sizeof IMAGE_TLS_DIRECTORY64);
@ -439,52 +398,41 @@ __declspec(dllexport) bool TITCALL TLSRemoveTableW(wchar_t* szFileName)
} }
return false; return false;
} }
__declspec(dllexport) bool TITCALL TLSBackupData(char* szFileName) __declspec(dllexport) bool TITCALL TLSBackupData(char* szFileName)
{ {
wchar_t uniFileName[MAX_PATH] = {}; wchar_t uniFileName[MAX_PATH] = {};
if(szFileName)
if(szFileName != NULL)
{ {
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0]))); MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
return(TLSBackupDataW(uniFileName)); return TLSBackupDataW(uniFileName);
} }
else
{
return false; return false;
} }
}
__declspec(dllexport) bool TITCALL TLSBackupDataW(wchar_t* szFileName) __declspec(dllexport) bool TITCALL TLSBackupDataW(wchar_t* szFileName)
{ {
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
HANDLE FileHandle; HANDLE FileHandle;
DWORD FileSize; DWORD FileSize;
HANDLE FileMap; HANDLE FileMap;
ULONG_PTR FileMapVA; ULONG_PTR FileMapVA;
BOOL FileIs64;
PIMAGE_TLS_DIRECTORY32 TLSDirectoryX86;
PIMAGE_TLS_DIRECTORY64 TLSDirectoryX64;
ULONG_PTR TLSDirectoryAddress;
ULONG_PTR TLSCallBackAddress;
ULONG_PTR TLSCompareData = NULL;
DWORD NumberOfTLSCallBacks = NULL;
LPVOID ArrayOfCallBacks = &engineBackupArrayOfCallBacks;
LPDWORD NumberOfCallBacks = &engineBackupNumberOfCallBacks;
engineBackupTLSAddress = NULL;
RtlZeroMemory(engineBackupArrayOfCallBacks, 0x1000);
RtlZeroMemory(&engineBackupTLSDataX86, sizeof IMAGE_TLS_DIRECTORY32);
RtlZeroMemory(&engineBackupTLSDataX64, sizeof IMAGE_TLS_DIRECTORY64);
if(MapFileExW(szFileName, UE_ACCESS_READ, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL)) if(MapFileExW(szFileName, UE_ACCESS_READ, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{ {
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA; PIMAGE_DOS_HEADER DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, FileHandle, NULL, DOSHeader, true)) if(EngineValidateHeader(FileMapVA, FileHandle, NULL, DOSHeader, true))
{ {
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew); DWORD NumberOfTLSCallBacks = NULL;
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew); engineBackupTLSAddress = NULL;
RtlZeroMemory(&engineBackupTLSDataX86, sizeof IMAGE_TLS_DIRECTORY32);
RtlZeroMemory(&engineBackupTLSDataX64, sizeof IMAGE_TLS_DIRECTORY64);
ClearTlsVector(&engineBackupArrayOfCallBacks); //clear backup array
std::vector<ULONG_PTR>* ArrayOfCallBacks = &engineBackupArrayOfCallBacks;
LPDWORD NumberOfCallBacks = &engineBackupNumberOfCallBacks;
PIMAGE_NT_HEADERS32 PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PIMAGE_NT_HEADERS64 PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
bool FileIs64;
if(PEHeader32->OptionalHeader.Magic == 0x10B) if(PEHeader32->OptionalHeader.Magic == 0x10B)
{ {
FileIs64 = false; FileIs64 = false;
@ -498,7 +446,7 @@ __declspec(dllexport) bool TITCALL TLSBackupDataW(wchar_t* szFileName)
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA); UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return false; return false;
} }
if(!FileIs64) if(!FileIs64) //x86
{ {
if(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress != NULL) if(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress != NULL)
{ {
@ -506,17 +454,17 @@ __declspec(dllexport) bool TITCALL TLSBackupDataW(wchar_t* szFileName)
{ {
engineBackupTLSx64 = false; engineBackupTLSx64 = false;
engineBackupTLSAddress = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress; engineBackupTLSAddress = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress;
TLSDirectoryAddress = (ULONG_PTR)((ULONG_PTR)PEHeader32->OptionalHeader.ImageBase + PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress); ULONG_PTR TLSDirectoryAddress = (ULONG_PTR)((ULONG_PTR)PEHeader32->OptionalHeader.ImageBase + PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress);
TLSDirectoryX86 = (PIMAGE_TLS_DIRECTORY32)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)TLSDirectoryAddress, true); PIMAGE_TLS_DIRECTORY32 TLSDirectoryX86 = (PIMAGE_TLS_DIRECTORY32)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)TLSDirectoryAddress, true);
RtlMoveMemory(&engineBackupTLSDataX86, (LPVOID)TLSDirectoryX86, sizeof IMAGE_TLS_DIRECTORY32); RtlMoveMemory(&engineBackupTLSDataX86, (LPVOID)TLSDirectoryX86, sizeof IMAGE_TLS_DIRECTORY32);
if(TLSDirectoryX86->AddressOfCallBacks != NULL) if(TLSDirectoryX86->AddressOfCallBacks != NULL)
{ {
TLSCallBackAddress = (ULONG_PTR)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)TLSDirectoryX86->AddressOfCallBacks, true); ULONG_PTR TLSCompareData = 0;
ULONG_PTR* TLSCallBackAddress = (ULONG_PTR*)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)TLSDirectoryX86->AddressOfCallBacks, true);
while(memcmp((LPVOID)TLSCallBackAddress, &TLSCompareData, sizeof ULONG_PTR) != NULL) while(memcmp((LPVOID)TLSCallBackAddress, &TLSCompareData, sizeof ULONG_PTR) != NULL)
{ {
RtlMoveMemory(ArrayOfCallBacks, (LPVOID)TLSCallBackAddress, sizeof ULONG_PTR); ArrayOfCallBacks->push_back(*TLSCallBackAddress);
ArrayOfCallBacks = (LPVOID)((ULONG_PTR)ArrayOfCallBacks + sizeof ULONG_PTR); TLSCallBackAddress++; //next callback
TLSCallBackAddress = TLSCallBackAddress + sizeof ULONG_PTR;
NumberOfTLSCallBacks++; NumberOfTLSCallBacks++;
} }
*NumberOfCallBacks = NumberOfTLSCallBacks; *NumberOfCallBacks = NumberOfTLSCallBacks;
@ -544,7 +492,7 @@ __declspec(dllexport) bool TITCALL TLSBackupDataW(wchar_t* szFileName)
return false; return false;
} }
} }
else else //x64
{ {
if(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress != NULL) if(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress != NULL)
{ {
@ -552,17 +500,17 @@ __declspec(dllexport) bool TITCALL TLSBackupDataW(wchar_t* szFileName)
{ {
engineBackupTLSx64 = true; engineBackupTLSx64 = true;
engineBackupTLSAddress = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress; engineBackupTLSAddress = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress;
TLSDirectoryAddress = (ULONG_PTR)((ULONG_PTR)PEHeader64->OptionalHeader.ImageBase + PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress); ULONG_PTR TLSDirectoryAddress = (ULONG_PTR)((ULONG_PTR)PEHeader64->OptionalHeader.ImageBase + PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress);
TLSDirectoryX64 = (PIMAGE_TLS_DIRECTORY64)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)TLSDirectoryAddress, true); PIMAGE_TLS_DIRECTORY64 TLSDirectoryX64 = (PIMAGE_TLS_DIRECTORY64)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)TLSDirectoryAddress, true);
RtlMoveMemory(&engineBackupTLSDataX64, (LPVOID)TLSDirectoryX64, sizeof IMAGE_TLS_DIRECTORY64); RtlMoveMemory(&engineBackupTLSDataX64, (LPVOID)TLSDirectoryX64, sizeof IMAGE_TLS_DIRECTORY64);
if(TLSDirectoryX64->AddressOfCallBacks != NULL) if(TLSDirectoryX64->AddressOfCallBacks != NULL)
{ {
TLSCallBackAddress = (ULONG_PTR)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)TLSDirectoryX64->AddressOfCallBacks, true); ULONG_PTR TLSCompareData = 0;
ULONG_PTR* TLSCallBackAddress = (ULONG_PTR*)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)TLSDirectoryX64->AddressOfCallBacks, true);
while(memcmp((LPVOID)TLSCallBackAddress, &TLSCompareData, sizeof ULONG_PTR) != NULL) while(memcmp((LPVOID)TLSCallBackAddress, &TLSCompareData, sizeof ULONG_PTR) != NULL)
{ {
RtlMoveMemory(ArrayOfCallBacks, (LPVOID)TLSCallBackAddress, sizeof ULONG_PTR); ArrayOfCallBacks->push_back(*TLSCallBackAddress);
ArrayOfCallBacks = (LPVOID)((ULONG_PTR)ArrayOfCallBacks + sizeof ULONG_PTR); TLSCallBackAddress++; //next callback
TLSCallBackAddress = TLSCallBackAddress + sizeof ULONG_PTR;
NumberOfTLSCallBacks++; NumberOfTLSCallBacks++;
} }
*NumberOfCallBacks = NumberOfTLSCallBacks; *NumberOfCallBacks = NumberOfTLSCallBacks;
@ -593,18 +541,16 @@ __declspec(dllexport) bool TITCALL TLSBackupDataW(wchar_t* szFileName)
} }
else else
{ {
*NumberOfCallBacks = NULL;
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA); UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return false; return false;
} }
} }
return false; return false;
} }
__declspec(dllexport) bool TITCALL TLSRestoreData() __declspec(dllexport) bool TITCALL TLSRestoreData()
{ {
ULONG_PTR ueNumberOfBytesRead = NULL; ULONG_PTR ueNumberOfBytesRead = NULL;
if(dbgProcessInformation.hProcess != NULL && engineBackupTLSAddress != NULL) if(dbgProcessInformation.hProcess != NULL && engineBackupTLSAddress != NULL)
{ {
if(engineBackupTLSx64) if(engineBackupTLSx64)
@ -613,7 +559,11 @@ __declspec(dllexport) bool TITCALL TLSRestoreData()
{ {
if(engineBackupTLSDataX64.AddressOfCallBacks != NULL && engineBackupNumberOfCallBacks != NULL) if(engineBackupTLSDataX64.AddressOfCallBacks != NULL && engineBackupNumberOfCallBacks != NULL)
{ {
if(WriteProcessMemory(dbgProcessInformation.hProcess, (LPVOID)(engineBackupTLSDataX64.AddressOfCallBacks + GetDebuggedFileBaseAddress()), engineBackupArrayOfCallBacks, sizeof IMAGE_TLS_DIRECTORY64, &ueNumberOfBytesRead)) DynBuf BackupData(sizeof(ULONG_PTR)*engineBackupArrayOfCallBacks.size());
ULONG_PTR* Backup=(ULONG_PTR*)BackupData.GetPtr();
for(unsigned int i=0; i<engineBackupArrayOfCallBacks.size(); i++)
Backup[i]=engineBackupArrayOfCallBacks.at(i);
if(WriteProcessMemory(dbgProcessInformation.hProcess, (LPVOID)(engineBackupTLSDataX64.AddressOfCallBacks + GetDebuggedFileBaseAddress()), Backup, BackupData.Size(), &ueNumberOfBytesRead))
{ {
engineBackupTLSAddress = NULL; engineBackupTLSAddress = NULL;
return true; return true;
@ -632,7 +582,11 @@ __declspec(dllexport) bool TITCALL TLSRestoreData()
{ {
if(engineBackupTLSDataX86.AddressOfCallBacks != NULL && engineBackupNumberOfCallBacks != NULL) if(engineBackupTLSDataX86.AddressOfCallBacks != NULL && engineBackupNumberOfCallBacks != NULL)
{ {
if(WriteProcessMemory(dbgProcessInformation.hProcess, (LPVOID)(engineBackupTLSDataX86.AddressOfCallBacks + GetDebuggedFileBaseAddress()), engineBackupArrayOfCallBacks, sizeof IMAGE_TLS_DIRECTORY32, &ueNumberOfBytesRead)) DynBuf BackupData(sizeof(ULONG_PTR)*engineBackupArrayOfCallBacks.size());
ULONG_PTR* Backup=(ULONG_PTR*)BackupData.GetPtr();
for(unsigned int i=0; i<engineBackupArrayOfCallBacks.size(); i++)
Backup[i]=engineBackupArrayOfCallBacks.at(i);
if(WriteProcessMemory(dbgProcessInformation.hProcess, (LPVOID)(engineBackupTLSDataX86.AddressOfCallBacks + GetDebuggedFileBaseAddress()), Backup, BackupData.Size(), &ueNumberOfBytesRead))
{ {
engineBackupTLSAddress = NULL; engineBackupTLSAddress = NULL;
return true; return true;
@ -648,24 +602,18 @@ __declspec(dllexport) bool TITCALL TLSRestoreData()
} }
return false; return false;
} }
__declspec(dllexport) bool TITCALL TLSBuildNewTable(ULONG_PTR FileMapVA, ULONG_PTR StorePlace, ULONG_PTR StorePlaceRVA, LPVOID ArrayOfCallBacks, DWORD NumberOfCallBacks) __declspec(dllexport) bool TITCALL TLSBuildNewTable(ULONG_PTR FileMapVA, ULONG_PTR StorePlace, ULONG_PTR StorePlaceRVA, LPVOID ArrayOfCallBacks, DWORD NumberOfCallBacks)
{ {
BOOL FileIs64;
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
PIMAGE_TLS_DIRECTORY32 TLSDirectoryX86;
PIMAGE_TLS_DIRECTORY64 TLSDirectoryX64;
ULONG_PTR TLSWriteData = StorePlaceRVA;
if(FileMapVA != NULL) if(FileMapVA != NULL)
{ {
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA; PIMAGE_DOS_HEADER DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, NULL, NULL, DOSHeader, true)) if(EngineValidateHeader(FileMapVA, NULL, NULL, DOSHeader, true))
{ {
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew); PIMAGE_NT_HEADERS32 PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew); PIMAGE_NT_HEADERS64 PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
bool FileIs64;
ULONG_PTR TLSWriteData = StorePlaceRVA;
if(PEHeader32->OptionalHeader.Magic == 0x10B) if(PEHeader32->OptionalHeader.Magic == 0x10B)
{ {
FileIs64 = false; FileIs64 = false;
@ -684,7 +632,7 @@ __declspec(dllexport) bool TITCALL TLSBuildNewTable(ULONG_PTR FileMapVA, ULONG_P
{ {
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress = (DWORD)StorePlaceRVA; PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress = (DWORD)StorePlaceRVA;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size = sizeof IMAGE_TLS_DIRECTORY32; PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size = sizeof IMAGE_TLS_DIRECTORY32;
TLSDirectoryX86 = (PIMAGE_TLS_DIRECTORY32)StorePlace; PIMAGE_TLS_DIRECTORY32 TLSDirectoryX86 = (PIMAGE_TLS_DIRECTORY32)StorePlace;
TLSDirectoryX86->StartAddressOfRawData = (DWORD)TLSWriteData; TLSDirectoryX86->StartAddressOfRawData = (DWORD)TLSWriteData;
TLSDirectoryX86->EndAddressOfRawData = (DWORD)TLSWriteData + 0x10; TLSDirectoryX86->EndAddressOfRawData = (DWORD)TLSWriteData + 0x10;
TLSDirectoryX86->AddressOfIndex = (DWORD)TLSWriteData + 0x14; TLSDirectoryX86->AddressOfIndex = (DWORD)TLSWriteData + 0x14;
@ -703,7 +651,7 @@ __declspec(dllexport) bool TITCALL TLSBuildNewTable(ULONG_PTR FileMapVA, ULONG_P
{ {
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress = (DWORD)StorePlaceRVA; PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress = (DWORD)StorePlaceRVA;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size = sizeof IMAGE_TLS_DIRECTORY64; PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size = sizeof IMAGE_TLS_DIRECTORY64;
TLSDirectoryX64 = (PIMAGE_TLS_DIRECTORY64)StorePlace; PIMAGE_TLS_DIRECTORY64 TLSDirectoryX64 = (PIMAGE_TLS_DIRECTORY64)StorePlace;
TLSDirectoryX64->StartAddressOfRawData = TLSWriteData; TLSDirectoryX64->StartAddressOfRawData = TLSWriteData;
TLSDirectoryX64->EndAddressOfRawData = TLSWriteData + 0x20; TLSDirectoryX64->EndAddressOfRawData = TLSWriteData + 0x20;
TLSDirectoryX64->AddressOfIndex = TLSWriteData + 0x28; TLSDirectoryX64->AddressOfIndex = TLSWriteData + 0x28;
@ -724,39 +672,30 @@ __declspec(dllexport) bool TITCALL TLSBuildNewTable(ULONG_PTR FileMapVA, ULONG_P
} }
return false; return false;
} }
__declspec(dllexport) bool TITCALL TLSBuildNewTableEx(char* szFileName, char* szSectionName, LPVOID ArrayOfCallBacks, DWORD NumberOfCallBacks) __declspec(dllexport) bool TITCALL TLSBuildNewTableEx(char* szFileName, char* szSectionName, LPVOID ArrayOfCallBacks, DWORD NumberOfCallBacks)
{ {
wchar_t uniFileName[MAX_PATH] = {}; wchar_t uniFileName[MAX_PATH] = {};
if(szFileName)
if(szFileName != NULL)
{ {
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0]))); MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
return(TLSBuildNewTableExW(uniFileName, szSectionName, ArrayOfCallBacks, NumberOfCallBacks)); return TLSBuildNewTableExW(uniFileName, szSectionName, ArrayOfCallBacks, NumberOfCallBacks);
} }
else
{
return false; return false;
} }
}
__declspec(dllexport) bool TITCALL TLSBuildNewTableExW(wchar_t* szFileName, char* szSectionName, LPVOID ArrayOfCallBacks, DWORD NumberOfCallBacks) __declspec(dllexport) bool TITCALL TLSBuildNewTableExW(wchar_t* szFileName, char* szSectionName, LPVOID ArrayOfCallBacks, DWORD NumberOfCallBacks)
{ {
ULONG_PTR tlsImageBase = (ULONG_PTR)GetPE32DataW(szFileName, NULL, UE_IMAGEBASE);
DWORD NewSectionVO = AddNewSectionW(szFileName, szSectionName, sizeof IMAGE_TLS_DIRECTORY64 * 2);
HANDLE FileHandle; HANDLE FileHandle;
DWORD FileSize; DWORD FileSize;
HANDLE FileMap; HANDLE FileMap;
ULONG_PTR FileMapVA; ULONG_PTR FileMapVA;
DWORD NewSectionVO = NULL;
DWORD NewSectionFO = NULL;
bool ReturnValue = false;
ULONG_PTR tlsImageBase;
tlsImageBase = (ULONG_PTR)GetPE32DataW(szFileName, NULL, UE_IMAGEBASE);
NewSectionVO = AddNewSectionW(szFileName, szSectionName, sizeof IMAGE_TLS_DIRECTORY64 * 2);
if(MapFileExW(szFileName, UE_ACCESS_ALL, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL)) if(MapFileExW(szFileName, UE_ACCESS_ALL, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{ {
NewSectionFO = (DWORD)ConvertVAtoFileOffset(FileMapVA, NewSectionVO + tlsImageBase, true); DWORD NewSectionFO = (DWORD)ConvertVAtoFileOffset(FileMapVA, NewSectionVO + tlsImageBase, true);
ReturnValue = TLSBuildNewTable(FileMapVA, NewSectionFO, NewSectionVO, ArrayOfCallBacks, NumberOfCallBacks); bool ReturnValue = TLSBuildNewTable(FileMapVA, NewSectionFO, NewSectionVO, ArrayOfCallBacks, NumberOfCallBacks);
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA); UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
if(ReturnValue) if(ReturnValue)
{ {
@ -767,8 +706,5 @@ __declspec(dllexport) bool TITCALL TLSBuildNewTableExW(wchar_t* szFileName, char
return false; return false;
} }
} }
else
{
return false; return false;
} }
}