TitanEngine/TitanEngine/TitanEngine.cpp

28905 lines
1.3 MiB

//
// TitanEngine SDK 2.0.3
// TitanEngine.cpp : Defines the exported functions for the DLL application.
//
// Global.constants
#include "stdafx.h"
// Disassembler.engine
#include "distorm.h"
// Windows libs
#include <time.h>
#include <stdlib.h>
#include <Imagehlp.h>
#include <Tlhelp32.h>
#include <ShellApi.h>
#include <CommDlg.h>
#include <psapi.h>
#include <intrin.h>
#include <vector>
// Global.Engine:
#include "definitions.h"
#include "resource.h"
#define TE_VER_MAJOR 2
#define TE_VER_MIDDLE 0
#define TE_VER_MINOR 3
/*#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0'" \
"processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")*/
// Global.variables:
char* szSharedOverlay = 0;
wchar_t* szSharedOverlayW = 0;
STARTUPINFOW dbgStartupInfo = {};
PROCESS_INFORMATION dbgProcessInformation = {};
DWORD DBGCode = DBG_CONTINUE;
DWORD CurrentExceptionsNumber = 0;
int BreakPointSetCount = 0;
BreakPointDetail BreakPointBuffer[MAXIMUM_BREAKPOINTS] = {};
BYTE INT3BreakPoint = 0xCC;
BYTE INT3LongBreakPoint[2] = {0xCD, 0x03};
BYTE UD2BreakPoint[2] = {0x0F, 0x0B};
CustomHandler myDBGCustomHandler = {};
PCustomHandler DBGCustomHandler = &myDBGCustomHandler;
DEBUG_EVENT DBGEvent = {};
DEBUG_EVENT TerminateDBGEvent = {};
CONTEXT DBGContext = {};
HANDLE DBGFileHandle;
DWORD ProcessExitCode = 0;
LPVOID hListProcess = 0;
LPVOID hListThread = 0;
LPVOID hListLibrary = 0;
ULONG_PTR impDeltaStart = NULL;
ULONG_PTR impDeltaCurrent = NULL;
ULONG_PTR impImageBase = 0;
DWORD impAllocSize = 20 * 1024;
DWORD impDLLNumber = 0;
bool impMoveIAT = false;
ULONG_PTR impDLLDataList[1000][2];
ULONG_PTR impDLLStringList[1000][2];
ULONG_PTR impOrdinalList[1000][2];
LPVOID expTableData = NULL;
LPVOID expTableDataCWP = NULL;
ULONG_PTR expImageBase = 0;
DWORD expExportNumber = 0;
bool expNamePresent = false;
DWORD expExportAddress[1000];
DWORD expSortedNamePointers[1000];
ULONG_PTR expNamePointers[1000];
DWORD expNameHashes[1000];
WORD expOrdinals[1000];
IMAGE_EXPORT_DIRECTORY expExportData;
ULONG_PTR tlsCallBackList[100];
int engineCurrentPlatform = UE_PLATFORM_x86;
ULONG_PTR engineTLSBreakOnCallBackAddress;
bool engineBackupTLSx64 = false;
bool engineTLSBreakOnCallBack = false;
LPVOID engineBackupArrayOfCallBacks = VirtualAlloc(NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE);
DWORD engineBackupNumberOfCallBacks = NULL;
DWORD engineBackupTLSAddress = NULL;
IMAGE_TLS_DIRECTORY32 engineBackupTLSDataX86 = {};
IMAGE_TLS_DIRECTORY64 engineBackupTLSDataX64 = {};
bool engineAlowModuleLoading = false;
bool engineCheckForwarders = true;
bool enginePassAllExceptions = true;
bool engineRemoveConsoleForDebugee = false;
bool engineBackupForCriticalFunctions = true;
bool engineCreatePathForFiles = true; // hardcoded
bool engineResetCustomHandler = true;
bool engineExecutePluginCallBack = true;
bool engineFileIsBeingDebugged = false;
ULONG_PTR engineReserveModuleBase = NULL;
DWORD engineWaitForDebugEventTimeOut = INFINITE;
LPVOID engineStepCallBack = NULL;
int engineStepCount = INFINITE;
bool engineStepActive = false;
bool engineAttachedToProcess = false;
bool engineProcessIsNowDetached = false;
ULONG_PTR engineAttachedProcessCallBack = NULL;
LPVOID engineAttachedProcessDebugInfo = NULL;
LPVOID engineExitThreadOneShootCallBack = NULL;
bool engineResumeProcessIfNoThreadIsActive = false;
bool engineAutoHideFromDebugger = false;
long engineDefaultBreakPointType = UE_BREAKPOINT_INT3;
bool engineDebuggingDLL = false;
wchar_t* engineDebuggingDLLFullFileName;
wchar_t* engineDebuggingDLLFileName;
//wchar_t* engineDebuggingDLLReserveFileName;
ULONG_PTR engineDebuggingDLLBase = NULL;
unsigned long long engineDebuggingMainModuleBase = NULL;
ULONG_PTR engineFakeDLLHandle = NULL;
char engineDisassembledInstruction[128];
ExpertDebug engineExpertDebug = {};
ULONG_PTR engineReservedMemoryLeft[UE_MAX_RESERVED_MEMORY_LEFT];
HANDLE engineReservedMemoryProcess = NULL;
void* engineFindOEPCallBack = NULL;
void* engineFindOEPUserCallBack = NULL;
ULONG_PTR DebugModuleEntryPoint;
ULONG_PTR DebugModuleImageBase;
LPVOID DebugModuleEntryPointCallBack;
LPVOID DebugExeFileEntryPointCallBack;
HMODULE engineHandle;
HARDWARE_DATA DebugRegister[4] = {};
LPVOID RelocationData = NULL;
LPVOID RelocationLastPage = NULL;
LPVOID RelocationStartPosition = NULL;
LPVOID RelocationWritePosition = NULL;
ULONG_PTR RelocationOldImageBase;
ULONG_PTR RelocationNewImageBase;
char engineExtractedFolderName[512];
char engineExtractedFileName[512];
wchar_t engineExtractedFileNameW[512];
char engineFoundAPIName[512];
char engineFoundDLLName[512];
wchar_t szBackupDebuggedFileName[512];
//wchar_t szReserveModuleName[512];
wchar_t szDebuggerName[512];
char szParameterString[512];
// Global.Engine.Strings:
wchar_t engineSzEngineFile[MAX_PATH];
wchar_t engineSzEngineFolder[MAX_PATH];
wchar_t engineSzEngineGarbageFolder[MAX_PATH];
// Global.Engine.Librarian:
LIBRARY_ITEM_DATA LibraryInfoData = {};
LPVOID LibrarianData = VirtualAlloc(NULL, MAX_LIBRARY_BPX * sizeof LIBRARY_BREAK_DATA, MEM_COMMIT, PAGE_READWRITE);
// Global.Engine.TraceOEP:
GenericOEPTracerData glbEntryTracerData = {};
// Global.Engine.Dependency:
LPVOID engineDependencyFiles;
LPVOID engineDependencyFilesCWP;
// Global.Engine.Window:
HWND EngineBoxHandle;
HWND EngineWindowHandle;
char szWindowUnpackerName[128];
char szWindowUnpackerTitle[128];
char szWindowUnpackerLongTitle[128];
char szWindowUnpackerAuthor[128];
void* EngineStartUnpackingCallBack;
// Global.Engine.Simplify
bool EngineUnpackerOptionLogData;
bool EngineUnpackerFileImporterInit;
bool EngineUnpackerOptionRealingFile;
bool EngineUnpackerOptionMoveOverlay;
bool EngineUnpackerOptionRelocationFix;
ULONG_PTR EngineUnpackerOptionUnpackedOEP;
wchar_t szEngineUnpackerInputFile[MAX_PATH];
wchar_t szEngineUnpackerOutputFile[MAX_PATH];
wchar_t szEngineUnpackerSnapShot1[MAX_PATH];
wchar_t szEngineUnpackerSnapShot2[MAX_PATH];
FILE_STATUS_INFO EngineUnpackerFileStatus = {};
LPPROCESS_INFORMATION pEngineUnpackerProcessHandle;
std::vector<UnpackerInformation> EngineUnpackerBreakInfo;
// Global.Engine.Hooks:
DWORD buffPatchedEntrySize = 0x3000;
void* CwpBuffPatchedEntry;
void* buffPatchedEntry;
std::vector<HOOK_ENTRY> hookEntry;
// Global.Engine.Plugins:
std::vector<PluginInformation> Plugin;
// Global.Engine.Hash:
unsigned long Crc32Table[256];
// Global.Engine.Constants:
#define UE_MODULEx86 0x2000;
#define UE_MODULEx64 0x2000;
// Global.Handle.functions:
bool EngineCloseHandle(HANDLE myHandle)
{
DWORD HandleFlags;
if(GetHandleInformation(myHandle, &HandleFlags))
{
if(CloseHandle(myHandle))
{
return(true);
}
}
return(false);
}
// Global.Mapping.functions:
bool MapFileEx(char* szFileName, DWORD ReadOrWrite, LPHANDLE FileHandle, LPDWORD FileSize, LPHANDLE FileMap, LPVOID FileMapVA, DWORD SizeModifier)
{
HANDLE hFile = 0;
DWORD FileAccess = 0;
DWORD FileMapType = 0;
DWORD FileMapViewType = 0;
DWORD mfFileSize = 0;
HANDLE mfFileMap = 0;
LPVOID mfFileMapVA = 0;
if(ReadOrWrite == UE_ACCESS_READ)
{
FileAccess = GENERIC_READ;
FileMapType = PAGE_READONLY;
FileMapViewType = FILE_MAP_READ;
}
else if(ReadOrWrite == UE_ACCESS_WRITE)
{
FileAccess = GENERIC_WRITE;
FileMapType = PAGE_READWRITE;
FileMapViewType = FILE_MAP_WRITE;
}
else if(ReadOrWrite == UE_ACCESS_ALL)
{
FileAccess = GENERIC_READ+GENERIC_WRITE+GENERIC_EXECUTE;
FileMapType = PAGE_EXECUTE_READWRITE;
FileMapViewType = FILE_MAP_WRITE;
}
else
{
FileAccess = GENERIC_READ+GENERIC_WRITE+GENERIC_EXECUTE;
FileMapType = PAGE_EXECUTE_READWRITE;
FileMapViewType = FILE_MAP_ALL_ACCESS;
}
hFile = CreateFileA(szFileName, FileAccess, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile != INVALID_HANDLE_VALUE)
{
*FileHandle = hFile;
mfFileSize = GetFileSize(hFile,NULL);
mfFileSize = mfFileSize + SizeModifier;
*FileSize = mfFileSize;
mfFileMap = CreateFileMappingA(hFile, NULL, FileMapType, NULL, mfFileSize, NULL);
if(mfFileMap != NULL)
{
*FileMap = mfFileMap;
mfFileMapVA = MapViewOfFile(mfFileMap, FileMapViewType, NULL, NULL, NULL);
if(mfFileMapVA != NULL)
{
RtlMoveMemory(FileMapVA, &mfFileMapVA, sizeof ULONG_PTR);
return(true);
}
}
RtlZeroMemory(FileMapVA, sizeof ULONG_PTR);
*FileHandle = NULL;
*FileSize = NULL;
EngineCloseHandle(hFile);
}
else
{
RtlZeroMemory(FileMapVA, sizeof ULONG_PTR);
}
return(false);
}
bool MapFileExW(wchar_t* szFileName, DWORD ReadOrWrite, LPHANDLE FileHandle, LPDWORD FileSize, LPHANDLE FileMap, LPVOID FileMapVA, DWORD SizeModifier)
{
HANDLE hFile = 0;
DWORD FileAccess = 0;
DWORD FileMapType = 0;
DWORD FileMapViewType = 0;
DWORD mfFileSize = 0;
HANDLE mfFileMap = 0;
LPVOID mfFileMapVA = 0;
if(ReadOrWrite == UE_ACCESS_READ)
{
FileAccess = GENERIC_READ;
FileMapType = PAGE_READONLY;
FileMapViewType = FILE_MAP_READ;
}
else if(ReadOrWrite == UE_ACCESS_WRITE)
{
FileAccess = GENERIC_WRITE;
FileMapType = PAGE_READWRITE;
FileMapViewType = FILE_MAP_WRITE;
}
else if(ReadOrWrite == UE_ACCESS_ALL)
{
FileAccess = GENERIC_READ+GENERIC_WRITE+GENERIC_EXECUTE;
FileMapType = PAGE_EXECUTE_READWRITE;
FileMapViewType = FILE_MAP_WRITE;
}
else
{
FileAccess = GENERIC_READ+GENERIC_WRITE+GENERIC_EXECUTE;
FileMapType = PAGE_EXECUTE_READWRITE;
FileMapViewType = FILE_MAP_ALL_ACCESS;
}
hFile = CreateFileW(szFileName, FileAccess, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile != INVALID_HANDLE_VALUE)
{
*FileHandle = hFile;
mfFileSize = GetFileSize(hFile,NULL);
mfFileSize = mfFileSize + SizeModifier;
*FileSize = mfFileSize;
mfFileMap = CreateFileMappingA(hFile, NULL, FileMapType, NULL, mfFileSize, NULL);
if(mfFileMap != NULL)
{
*FileMap = mfFileMap;
mfFileMapVA = MapViewOfFile(mfFileMap, FileMapViewType, NULL, NULL, NULL);
if(mfFileMapVA != NULL)
{
RtlMoveMemory(FileMapVA, &mfFileMapVA, sizeof ULONG_PTR);
return(true);
}
}
RtlZeroMemory(FileMapVA, sizeof ULONG_PTR);
*FileHandle = NULL;
*FileSize = NULL;
EngineCloseHandle(hFile);
}
else
{
RtlZeroMemory(FileMapVA, sizeof ULONG_PTR);
}
return(false);
}
void UnMapFileEx(HANDLE FileHandle, DWORD FileSize, HANDLE FileMap, ULONG_PTR FileMapVA)
{
LPVOID ufFileMapVA = (void*)FileMapVA;
if(UnmapViewOfFile(ufFileMapVA))
{
EngineCloseHandle(FileMap);
SetFilePointer(FileHandle,FileSize,NULL,FILE_BEGIN);
SetEndOfFile(FileHandle);
EngineCloseHandle(FileHandle);
}
}
// Global.Engine.functions:
void EngineGlobalTestFunction()
{
MessageBoxA(NULL, "TitanEngine test message!", "TitanEngine2:", 0x40);
}
void EngineExecutePluginReleaseCallBack()
{
typedef void(TITCALL *fPluginReleaseExec)();
fPluginReleaseExec myPluginReleaseExec;
for(unsigned int i = 0; i < Plugin.size(); i++)
{
__try
{
if(Plugin[i].TitanReleasePlugin != NULL)
{
myPluginReleaseExec = (fPluginReleaseExec)Plugin[i].TitanReleasePlugin;
myPluginReleaseExec();
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
}
}
void EngineExecutePluginResetCallBack()
{
typedef void(TITCALL *fPluginResetExec)();
fPluginResetExec myPluginResetExec;
for(unsigned int i = 0; i < Plugin.size(); i++)
{
__try
{
if(Plugin[i].TitanResetPlugin != NULL)
{
myPluginResetExec = (fPluginResetExec)Plugin[i].TitanResetPlugin;
myPluginResetExec();
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
}
}
void EngineExecutePluginDebugCallBack(LPDEBUG_EVENT debugEvent, int CallReason)
{
typedef void(TITCALL *fPluginDebugExec)(LPDEBUG_EVENT debugEvent, int CallReason);
fPluginDebugExec myPluginDebugExec;
for(unsigned int i = 0; i < Plugin.size(); i++)
{
__try
{
if(!Plugin[i].PluginDisabled)
{
if(Plugin[i].TitanDebuggingCallBack != NULL)
{
myPluginDebugExec = (fPluginDebugExec)Plugin[i].TitanDebuggingCallBack;
myPluginDebugExec(debugEvent, CallReason);
}
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
}
}
bool EngineIsThereFreeHardwareBreakSlot(LPDWORD FreeRegister)
{
if(DebugRegister[0].DrxEnabled == false)
{
if(FreeRegister != NULL)
{
*FreeRegister = UE_DR0;
}
return(true);
}
else if(DebugRegister[1].DrxEnabled == false)
{
if(FreeRegister != NULL)
{
*FreeRegister = UE_DR1;
}
return(true);
}
else if(DebugRegister[2].DrxEnabled == false)
{
if(FreeRegister != NULL)
{
*FreeRegister = UE_DR2;
}
return(true);
}
else if(DebugRegister[3].DrxEnabled == false)
{
if(FreeRegister != NULL)
{
*FreeRegister = UE_DR3;
}
return(true);
}
return(false);
}
bool EngineFileExists(char* szFileName)
{
HANDLE hFile = CreateFileA(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile != INVALID_HANDLE_VALUE)
{
EngineCloseHandle(hFile);
return(true);
}
else
{
return(false);
}
}
static char* EngineExtractPath(char* szFileName)
{
int i;
RtlZeroMemory(&engineExtractedFolderName, sizeof(engineExtractedFolderName));
lstrcpyA(engineExtractedFolderName, szFileName);
i = lstrlenA(engineExtractedFolderName);
while(i > 0 && engineExtractedFolderName[i] != 0x5C)
{
engineExtractedFolderName[i] = 0x00;
i--;
}
return(engineExtractedFolderName);
}
char* EngineExtractFileName(char* szFileName)
{
int i;
int j;
int x = 0;
i = lstrlenA(szFileName);
RtlZeroMemory(&engineExtractedFileName, sizeof(engineExtractedFileName));
while(i > 0 && szFileName[i] != 0x5C)
{
i--;
}
if(szFileName[i] == 0x5C)
{
for(j = i + 1; j <= lstrlenA(szFileName); j++)
{
engineExtractedFileName[x] = szFileName[j];
x++;
}
}
else
{
return(szFileName);
}
return(engineExtractedFileName);
}
bool EngineCreatePathForFile(char* szFileName)
{
int i,j;
char szFolderName[2 * MAX_PATH] = {};
char szCreateFolder[2 * MAX_PATH] = {};
if(engineCreatePathForFiles)
{
i = lstrlenA(szFileName);
while(szFileName[i] != '\\' && i > NULL)
{
i--;
}
if(i != NULL)
{
RtlMoveMemory(szFolderName, szFileName, i + 1);
if(!CreateDirectoryA(szFolderName, NULL))
{
if(GetLastError() != ERROR_ALREADY_EXISTS)
{
j = lstrlenA(szFolderName);
for(i = 4; i < j; i++)
{
if(szFileName[i] == '\\')
{
RtlZeroMemory(szCreateFolder, 2 * MAX_PATH);
RtlCopyMemory(szCreateFolder, szFileName, i + 1);
CreateDirectoryA(szCreateFolder, NULL);
}
}
}
}
}
}
return(true);
}
bool EngineCreatePathForFileW(wchar_t* szFileName)
{
int i,j;
wchar_t szFolderName[MAX_PATH] = {};
wchar_t szCreateFolder[MAX_PATH] = {};
if(engineCreatePathForFiles)
{
i = lstrlenW(szFileName);
while(szFileName[i] != '\\' && i > 0)
{
i--;
}
if(i != 0)
{
RtlCopyMemory(szFolderName, szFileName, (i * 2) + 2);
if(!CreateDirectoryW(szFolderName, NULL))
{
if(GetLastError() != ERROR_ALREADY_EXISTS)
{
j = lstrlenW(szFolderName);
for(i = 4; i < j; i++)
{
if(szFileName[i] == '\\')
{
RtlZeroMemory(szCreateFolder, 2 * MAX_PATH);
RtlCopyMemory(szCreateFolder, szFileName, (i * 2) + 1);
CreateDirectoryW(szCreateFolder, NULL);
}
}
}
}
}
}
return(true);
}
wchar_t* EngineExtractFileNameW(wchar_t* szFileName)
{
int i;
int j;
int x = 0;
i = lstrlenW(szFileName);
RtlZeroMemory(&engineExtractedFileNameW, sizeof engineExtractedFileNameW);
while(i > 0 && szFileName[i] != 0x5C)
{
i--;
}
if(szFileName[i] == 0x5C)
{
int len=lstrlenW(szFileName);
for(j = i + 1; j <= len; j++)
{
engineExtractedFileNameW[x] = szFileName[j];
x++;
}
}
else
{
return(szFileName);
}
return(engineExtractedFileNameW);
}
bool EngineIsPointedMemoryString(ULONG_PTR PossibleStringPtr)
{
bool StringIsValid = true;
unsigned int i = 512;
MEMORY_BASIC_INFORMATION MemInfo = {0};
DWORD MaxDisassmSize = 512;
BYTE TestChar;
VirtualQueryEx(GetCurrentProcess(), (LPVOID)PossibleStringPtr, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
if(MemInfo.State == MEM_COMMIT)
{
if((ULONG_PTR)MemInfo.BaseAddress + (ULONG_PTR)MemInfo.RegionSize - PossibleStringPtr <= 512)
{
MaxDisassmSize = (DWORD)((ULONG_PTR)MemInfo.BaseAddress + (ULONG_PTR)MemInfo.RegionSize - PossibleStringPtr - 1);
VirtualQueryEx(GetCurrentProcess(), (LPVOID)(PossibleStringPtr + (ULONG_PTR)MemInfo.RegionSize), &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
if(MemInfo.State != MEM_COMMIT)
{
i = MaxDisassmSize;
}
}
TestChar = *((BYTE*)PossibleStringPtr);
while(i > NULL && StringIsValid == true && TestChar != 0x00)
{
TestChar = *((BYTE*)PossibleStringPtr);
if(TestChar < 32 || TestChar > 126)
{
if(TestChar != 0x00)
{
StringIsValid = false;
}
}
PossibleStringPtr++;
i--;
}
if(StringIsValid == true && MaxDisassmSize - i > 4)
{
return(true);
}
}
return(false);
}
int EnginePointedMemoryStringLength(ULONG_PTR PossibleStringPtr)
{
bool StringIsValid = true;
unsigned int i = 512;
MEMORY_BASIC_INFORMATION MemInfo;
DWORD MaxDisassmSize = 512;
BYTE TestChar;
VirtualQueryEx(GetCurrentProcess(), (LPVOID)PossibleStringPtr, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
if(MemInfo.State == MEM_COMMIT)
{
if((ULONG_PTR)MemInfo.BaseAddress + (ULONG_PTR)MemInfo.RegionSize - PossibleStringPtr <= 512)
{
MaxDisassmSize = (DWORD)((ULONG_PTR)MemInfo.BaseAddress + (ULONG_PTR)MemInfo.RegionSize - PossibleStringPtr - 1);
VirtualQueryEx(GetCurrentProcess(), (LPVOID)(PossibleStringPtr + (ULONG_PTR)MemInfo.RegionSize), &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
if(MemInfo.State != MEM_COMMIT)
{
i = MaxDisassmSize;
}
}
TestChar = *((BYTE*)PossibleStringPtr);
while(i > NULL && StringIsValid == true && TestChar != 0x00)
{
TestChar = *((BYTE*)PossibleStringPtr);
if(TestChar < 32 || TestChar > 126)
{
if(TestChar != 0x00)
{
StringIsValid = false;
}
}
PossibleStringPtr++;
i--;
}
if(StringIsValid == true && 512 - i > 4)
{
i = 512 - i;
return(i);
}
}
return(NULL);
}
bool EngineCompareResourceString(wchar_t* String1, wchar_t* String2)
{
PMEMORY_COMPARE_HANDLER memData = (PMEMORY_COMPARE_HANDLER)String1;
wchar_t StringCmp[MAX_PATH] = {};
String1 = (wchar_t*)((ULONG_PTR)String1 + 2);
RtlMoveMemory(&StringCmp[0], &String1[0], memData->Array.wArrayEntry[0] * 2);
if(lstrcmpiW(StringCmp, String2) == NULL)
{
return(true);
}
return(false);
}
long long EngineEstimateNewSectionRVA(ULONG_PTR FileMapVA)
{
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
PIMAGE_SECTION_HEADER PESections;
DWORD NewSectionVirtualOffset = 0;
DWORD SectionNumber = 0;
BOOL FileIs64;
if(FileMapVA != NULL)
{
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
return(0);
}
if(!FileIs64)
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader32 + PEHeader32->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
SectionNumber = PEHeader32->FileHeader.NumberOfSections;
__try
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + (SectionNumber - 1) * IMAGE_SIZEOF_SECTION_HEADER);
NewSectionVirtualOffset = PESections->VirtualAddress + (PESections->Misc.VirtualSize / PEHeader32->OptionalHeader.SectionAlignment) * PEHeader32->OptionalHeader.SectionAlignment;
if(NewSectionVirtualOffset < PESections->VirtualAddress + PESections->Misc.VirtualSize)
{
NewSectionVirtualOffset = NewSectionVirtualOffset + PEHeader32->OptionalHeader.SectionAlignment;
}
return((ULONG_PTR)(NewSectionVirtualOffset + PEHeader32->OptionalHeader.ImageBase));
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return(0);
}
}
else
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader64 + PEHeader64->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
SectionNumber = PEHeader64->FileHeader.NumberOfSections;
__try
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + (SectionNumber - 1) * IMAGE_SIZEOF_SECTION_HEADER);
NewSectionVirtualOffset = PESections->VirtualAddress + (PESections->Misc.VirtualSize / PEHeader64->OptionalHeader.SectionAlignment) * PEHeader64->OptionalHeader.SectionAlignment;
if(NewSectionVirtualOffset < PESections->VirtualAddress + PESections->Misc.VirtualSize)
{
NewSectionVirtualOffset = NewSectionVirtualOffset + PEHeader32->OptionalHeader.SectionAlignment;
}
return((ULONG_PTR)(NewSectionVirtualOffset + PEHeader64->OptionalHeader.ImageBase));
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return(0);
}
}
}
return(0);
}
bool EngineExtractForwarderData(ULONG_PTR PossibleStringPtr, LPVOID szFwdDLLName, LPVOID szFwdAPIName)
{
__try
{
LPVOID lpPossibleStringPtr = (LPVOID)PossibleStringPtr;
BYTE TestChar;
TestChar = *((BYTE*)PossibleStringPtr);
while(TestChar != 0x2E && TestChar != 0x00)
{
TestChar = *((BYTE*)PossibleStringPtr);
PossibleStringPtr++;
}
if(TestChar == 0x00)
{
return(false);
}
PossibleStringPtr--;
RtlCopyMemory(szFwdDLLName, lpPossibleStringPtr, PossibleStringPtr - (ULONG_PTR)lpPossibleStringPtr);
lstrcatA((LPSTR)szFwdDLLName, ".dll");
lpPossibleStringPtr = (LPVOID)(PossibleStringPtr + 1);
TestChar = *((BYTE*)PossibleStringPtr);
if(TestChar == 0x23)
{
lpPossibleStringPtr = (LPVOID)(PossibleStringPtr + 1);
}
while(TestChar != 0x00)
{
TestChar = *((BYTE*)PossibleStringPtr);
PossibleStringPtr++;
}
RtlCopyMemory(szFwdAPIName, lpPossibleStringPtr, PossibleStringPtr - (ULONG_PTR)lpPossibleStringPtr);
return(true);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return(false);
}
}
bool EngineGrabDataFromMappedFile(HANDLE hFile, ULONG_PTR FileMapVA, ULONG_PTR FileOffset, DWORD CopySize, LPVOID CopyToMemory)
{
DWORD rfNumberOfBytesRead = NULL;
RtlZeroMemory(CopyToMemory, CopySize);
SetFilePointer(hFile, (DWORD)(FileOffset - FileMapVA), NULL, FILE_BEGIN);
return !!ReadFile(hFile, CopyToMemory, CopySize, &rfNumberOfBytesRead, NULL);
}
bool EngineExtractResource(char* szResourceName, wchar_t* szExtractedFileName)
{
HRSRC hResource;
HGLOBAL hResourceGlobal;
DWORD ResourceSize;
LPVOID ResourceData;
DWORD NumberOfBytesWritten;
HANDLE hFile;
hResource = FindResourceA(engineHandle, (LPCSTR)szResourceName, "BINARY");
if(hResource != NULL)
{
hResourceGlobal = LoadResource(engineHandle, hResource);
if(hResourceGlobal != NULL)
{
ResourceSize = SizeofResource(engineHandle, hResource);
ResourceData = LockResource(hResourceGlobal);
if(EngineCreatePathForFileW(szExtractedFileName))
{
hFile = CreateFileW(szExtractedFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile != INVALID_HANDLE_VALUE)
{
WriteFile(hFile, ResourceData, ResourceSize, &NumberOfBytesWritten, NULL);
EngineCloseHandle(hFile);
}
else
{
return(false);
}
}
}
return(true);
}
return(false);
}
bool EngineIsDependencyPresent(char* szFileName, char* szDependencyForFile, char* szPresentInFolder)
{
int i,j;
HANDLE hFile;
char szTryFileName[512] = {0};
if(szPresentInFolder != NULL && szFileName != NULL)
{
lstrcpyA(szTryFileName, szPresentInFolder);
if(szTryFileName[lstrlenA(szTryFileName)-1] != 0x5C)
{
szTryFileName[lstrlenA(szTryFileName)] = 0x5C;
}
lstrcatA(szTryFileName, szFileName);
hFile = CreateFileA(szTryFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile != INVALID_HANDLE_VALUE)
{
EngineCloseHandle(hFile);
return(true);
}
}
if(szFileName != NULL)
{
hFile = CreateFileA(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile != INVALID_HANDLE_VALUE)
{
EngineCloseHandle(hFile);
return(true);
}
if(GetSystemDirectoryA(szTryFileName, 512) > NULL)
{
lstrcatA(szTryFileName, "\\");
lstrcatA(szTryFileName, szFileName);
hFile = CreateFileA(szTryFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile != INVALID_HANDLE_VALUE)
{
EngineCloseHandle(hFile);
return(true);
}
}
if(GetWindowsDirectoryA(szTryFileName, 512) > NULL)
{
lstrcatA(szTryFileName, "\\");
lstrcatA(szTryFileName, szFileName);
hFile = CreateFileA(szTryFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile != INVALID_HANDLE_VALUE)
{
EngineCloseHandle(hFile);
return(true);
}
}
if(szDependencyForFile != NULL)
{
RtlZeroMemory(&szTryFileName, 512);
i = lstrlenA(szDependencyForFile);
while(i > 0 && szDependencyForFile[i] != 0x5C)
{
i--;
}
for(j = 0; j <= i; j++)
{
szTryFileName[j] = szDependencyForFile[j];
}
lstrcatA(szTryFileName, szFileName);
hFile = CreateFileA(szTryFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile != INVALID_HANDLE_VALUE)
{
EngineCloseHandle(hFile);
return(true);
}
}
}
return(false);
}
bool EngineIsDependencyPresentW(wchar_t* szFileName, wchar_t* szDependencyForFile, wchar_t* szPresentInFolder)
{
int i,j;
HANDLE hFile;
wchar_t szTryFileName[512] = {0};
if(szPresentInFolder != NULL)
{
lstrcpyW(szTryFileName, szPresentInFolder);
if(szTryFileName[lstrlenW(szTryFileName)-1] != 0x5C)
{
szTryFileName[lstrlenW(szTryFileName)] = 0x5C;
}
lstrcatW(szTryFileName, szFileName);
hFile = CreateFileW(szTryFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile != INVALID_HANDLE_VALUE)
{
EngineCloseHandle(hFile);
return(true);
}
}
if(szFileName != NULL)
{
hFile = CreateFileW(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile != INVALID_HANDLE_VALUE)
{
EngineCloseHandle(hFile);
return(true);
}
if(GetSystemDirectoryW(szTryFileName, 512) > NULL)
{
lstrcatW(szTryFileName, L"\\");
lstrcatW(szTryFileName, szFileName);
hFile = CreateFileW(szTryFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile != INVALID_HANDLE_VALUE)
{
EngineCloseHandle(hFile);
return(true);
}
}
if(GetWindowsDirectoryW(szTryFileName, 512) > NULL)
{
lstrcatW(szTryFileName, L"\\");
lstrcatW(szTryFileName, szFileName);
hFile = CreateFileW(szTryFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile != INVALID_HANDLE_VALUE)
{
EngineCloseHandle(hFile);
return(true);
}
}
if(szDependencyForFile != NULL)
{
i = lstrlenW(szDependencyForFile);
while(i > 0 && szDependencyForFile[i] != 0x5C)
{
i--;
}
for(j = 0; j <= i; j++)
{
szTryFileName[j] = szDependencyForFile[j];
}
lstrcatW(szTryFileName, szFileName);
hFile = CreateFileW(szTryFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile != INVALID_HANDLE_VALUE)
{
EngineCloseHandle(hFile);
return(true);
}
}
}
return(false);
}
bool EngineGetDependencyLocation(char* szFileName, char* szDependencyForFile, void* szLocationOfTheFile, int MaxStringSize)
{
int i,j;
HANDLE hFile;
char szTryFileName[512] = {0};
if(szFileName != NULL)
{
hFile = CreateFileA(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile != INVALID_HANDLE_VALUE)
{
RtlZeroMemory(szLocationOfTheFile, MaxStringSize);
if(lstrlenA(szFileName) <= MaxStringSize)
{
RtlCopyMemory(szLocationOfTheFile, szFileName, lstrlenA(szFileName));
}
EngineCloseHandle(hFile);
return(true);
}
if(GetSystemDirectoryA(szTryFileName, 512) > NULL)
{
lstrcatA(szTryFileName, "\\");
lstrcatA(szTryFileName, szFileName);
hFile = CreateFileA(szTryFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile != INVALID_HANDLE_VALUE)
{
RtlZeroMemory(szLocationOfTheFile, MaxStringSize);
if(lstrlenA(szTryFileName) <= MaxStringSize)
{
RtlCopyMemory(szLocationOfTheFile, &szTryFileName, lstrlenA(szTryFileName));
}
EngineCloseHandle(hFile);
return(true);
}
}
if(GetWindowsDirectoryA(szTryFileName, 512) > NULL)
{
lstrcatA(szTryFileName, "\\");
lstrcatA(szTryFileName, szFileName);
hFile = CreateFileA(szTryFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile != INVALID_HANDLE_VALUE)
{
RtlZeroMemory(szLocationOfTheFile, MaxStringSize);
if(lstrlenA(szTryFileName) <= MaxStringSize)
{
RtlCopyMemory(szLocationOfTheFile, &szTryFileName, lstrlenA(szTryFileName));
}
EngineCloseHandle(hFile);
return(true);
}
}
if(szDependencyForFile != NULL)
{
RtlZeroMemory(&szTryFileName, 512);
i = lstrlenA(szDependencyForFile);
while(i > 0 && szDependencyForFile[i] != 0x5C)
{
i--;
}
for(j = 0; j <= i; j++)
{
szTryFileName[j] = szDependencyForFile[j];
}
lstrcatA(szTryFileName, szFileName);
hFile = CreateFileA(szTryFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile != INVALID_HANDLE_VALUE)
{
RtlZeroMemory(szLocationOfTheFile, MaxStringSize);
if(lstrlenA(szTryFileName) <= MaxStringSize)
{
RtlCopyMemory(szLocationOfTheFile, &szTryFileName, lstrlenA(szTryFileName));
}
EngineCloseHandle(hFile);
return(true);
}
}
}
return(false);
}
long EngineHashString(char* szStringToHash)
{
int i = NULL;
DWORD HashValue = NULL;
if(szStringToHash != NULL)
{
for(i = 0; i < lstrlenA(szStringToHash); i++)
{
HashValue = (((HashValue << 7) | (HashValue >> (32 - 7))) ^ szStringToHash[i]);
}
}
return(HashValue);
}
long EngineHashMemory(char* MemoryAddress, int MemorySize, DWORD InitialHashValue)
{
int i = NULL;
DWORD HashValue = InitialHashValue;
for(i = 0; i < MemorySize; i++)
{
if(MemoryAddress[i] != NULL)
{
HashValue = (((HashValue << 7) | (HashValue >> (32 - 7))) ^ MemoryAddress[i]);
}
}
return(HashValue);
}
bool EngineIsBadReadPtrEx(LPVOID DataPointer, DWORD DataSize)
{
MEMORY_BASIC_INFORMATION MemInfo = {0};
while(DataSize > NULL)
{
VirtualQuery(DataPointer, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
if(MemInfo.AllocationProtect == MEM_FREE || MemInfo.AllocationProtect == MEM_PRIVATE)
{
return(false);
}
DataPointer = (LPVOID)((ULONG_PTR)DataPointer + MemInfo.RegionSize);
if(MemInfo.RegionSize > DataSize)
{
DataSize = NULL;
}
else
{
DataSize = DataSize - (DWORD)MemInfo.RegionSize;
}
}
return(true);
}
bool EngineValidateResource(HMODULE hModule, LPCTSTR lpszType, LPTSTR lpszName, LONG_PTR lParam)
{
HRSRC hResource;
HGLOBAL hResourceGlobal;
DWORD ResourceSize;
LPVOID ResourceData;
BYTE ReturnData = UE_FILED_FIXABLE_CRITICAL;
hResource = FindResourceA(hModule, (LPCSTR)lpszName, (LPCSTR)lpszType);
if(hResource != NULL)
{
hResourceGlobal = LoadResource(hModule, hResource);
if(hResourceGlobal != NULL)
{
ResourceSize = SizeofResource(hModule, hResource);
ResourceData = LockResource(hResourceGlobal);
if(ResourceData != NULL)
{
if(!EngineIsBadReadPtrEx(ResourceData, ResourceSize))
{
*((LONG*)lParam) = ReturnData;
return(false);
}
}
else
{
*((LONG*)lParam) = ReturnData;
return(false);
}
}
return(true);
}
*((LONG*)lParam) = ReturnData;
return(false);
}
bool EngineValidateHeader(ULONG_PTR FileMapVA, HANDLE hFileProc, LPVOID ImageBase, PIMAGE_DOS_HEADER DOSHeader, bool IsFile)
{
MODULEINFO ModuleInfo;
DWORD MemorySize = NULL;
PIMAGE_NT_HEADERS32 PEHeader32;
IMAGE_NT_HEADERS32 RemotePEHeader32;
MEMORY_BASIC_INFORMATION MemoryInfo={0};
ULONG_PTR NumberOfBytesRW = NULL;
if(IsFile)
{
if(hFileProc == NULL)
{
VirtualQueryEx(GetCurrentProcess(), (LPVOID)FileMapVA, &MemoryInfo, sizeof MEMORY_BASIC_INFORMATION);
VirtualQueryEx(GetCurrentProcess(), MemoryInfo.AllocationBase, &MemoryInfo, sizeof MEMORY_BASIC_INFORMATION);
MemorySize = (DWORD)((ULONG_PTR)MemoryInfo.AllocationBase + (ULONG_PTR)MemoryInfo.RegionSize - (ULONG_PTR)FileMapVA);
}
else
{
MemorySize = GetFileSize(hFileProc, NULL);
}
__try
{
if(DOSHeader->e_magic == 0x5A4D)
{
if(DOSHeader->e_lfanew + sizeof IMAGE_DOS_HEADER + sizeof(IMAGE_NT_HEADERS64) < MemorySize)
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->Signature != 0x4550)
{
return(false);
}
else
{
return(true);
}
}
else
{
return(false);
}
}
else
{
return(false);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return(false);
}
}
else
{
RtlZeroMemory(&ModuleInfo, sizeof MODULEINFO);
GetModuleInformation(hFileProc, (HMODULE)ImageBase, &ModuleInfo, sizeof MODULEINFO);
__try
{
if(DOSHeader->e_magic == 0x5A4D)
{
if(DOSHeader->e_lfanew + sizeof IMAGE_DOS_HEADER + sizeof(IMAGE_NT_HEADERS64) < ModuleInfo.SizeOfImage)
{
if(ReadProcessMemory(hFileProc, (LPVOID)((ULONG_PTR)ImageBase + DOSHeader->e_lfanew), &RemotePEHeader32, sizeof IMAGE_NT_HEADERS32, &NumberOfBytesRW))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)(&RemotePEHeader32);
if(PEHeader32->Signature != 0x4550)
{
return(false);
}
else
{
return(true);
}
}
else
{
return(false);
}
}
else
{
return(false);
}
}
else
{
return(false);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return(false);
}
}
}
long long EngineSimulateNtLoaderW(wchar_t* szFileName)
{
DWORD PeHeaderSize;
LPVOID AllocatedFile;
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
PIMAGE_SECTION_HEADER PESections;
DWORD SectionNumber = 0;
DWORD SectionRawOffset = 0;
DWORD SectionRawSize = 0;
BOOL FileIs64;
HANDLE FileHandle;
DWORD FileSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
if(MapFileExW(szFileName, UE_ACCESS_READ, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, FileHandle, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(NULL);
}
if(!FileIs64)
{
AllocatedFile = VirtualAlloc(NULL, PEHeader32->OptionalHeader.SizeOfImage, MEM_COMMIT, PAGE_READWRITE);
__try
{
PeHeaderSize = DOSHeader->e_lfanew + PEHeader32->FileHeader.SizeOfOptionalHeader + (sizeof(IMAGE_SECTION_HEADER) * PEHeader32->FileHeader.NumberOfSections) + sizeof(IMAGE_FILE_HEADER) + 4;
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader32 + PEHeader32->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
SectionNumber = PEHeader32->FileHeader.NumberOfSections;
RtlCopyMemory(AllocatedFile, (LPVOID)FileMapVA, PeHeaderSize);
while(SectionNumber > 0)
{
RtlCopyMemory((LPVOID)((ULONG_PTR)AllocatedFile + PESections->VirtualAddress), (LPVOID)(FileMapVA + PESections->PointerToRawData), PESections->SizeOfRawData);
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + IMAGE_SIZEOF_SECTION_HEADER);
SectionNumber--;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
VirtualFree(AllocatedFile, NULL, MEM_RELEASE);
AllocatedFile = NULL;
}
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return((ULONG_PTR)AllocatedFile);
}
else
{
AllocatedFile = VirtualAlloc(NULL, PEHeader64->OptionalHeader.SizeOfImage, MEM_COMMIT, PAGE_READWRITE);
__try
{
PeHeaderSize = DOSHeader->e_lfanew + PEHeader64->FileHeader.SizeOfOptionalHeader + (sizeof(IMAGE_SECTION_HEADER) * PEHeader64->FileHeader.NumberOfSections) + sizeof(IMAGE_FILE_HEADER) + 4;
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader64 + PEHeader64->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
SectionNumber = PEHeader64->FileHeader.NumberOfSections;
RtlCopyMemory(AllocatedFile, (LPVOID)FileMapVA, PeHeaderSize);
while(SectionNumber > 0)
{
RtlCopyMemory((LPVOID)((ULONG_PTR)AllocatedFile + PESections->VirtualAddress), (LPVOID)(FileMapVA + PESections->PointerToRawData), PESections->SizeOfRawData);
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + IMAGE_SIZEOF_SECTION_HEADER);
SectionNumber--;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
VirtualFree(AllocatedFile, NULL, MEM_RELEASE);
AllocatedFile = NULL;
}
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return((ULONG_PTR)AllocatedFile);
}
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(NULL);
}
}
return(NULL);
}
long long EngineSimulateNtLoader(char* szFileName)
{
wchar_t uniFileName[MAX_PATH] = {};
if(szFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
return(EngineSimulateNtLoaderW(uniFileName));
}
else
{
return(NULL);
}
}
long long EngineSimulateDllLoader(HANDLE hProcess, char* szFileName)
{
int n;
BOOL FileIs64;
DWORD FileSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
HANDLE FileHandle;
LPVOID DLLMemory = NULL;
DWORD ExportDelta = NULL;
DWORD PEHeaderSize = NULL;
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
PIMAGE_EXPORT_DIRECTORY PEExports;
PEXPORTED_DATA ExportedFunctionNames;
ULONG_PTR ConvertedExport = NULL;
char szFileRemoteProc[1024]={0};
char szDLLFileLocation[512]={0};
char* szTranslatedProcName=0;
GetProcessImageFileNameA(hProcess, szFileRemoteProc, sizeof(szFileRemoteProc));
szTranslatedProcName = (char*)TranslateNativeName(szFileRemoteProc);
if(EngineIsDependencyPresent(szFileName, NULL, NULL))
{
if(EngineGetDependencyLocation(szFileName, szTranslatedProcName, &szDLLFileLocation, sizeof(szDLLFileLocation)))
{
VirtualFree((void*)szTranslatedProcName, NULL, MEM_RELEASE);
if(MapFileEx(szDLLFileLocation, UE_ACCESS_READ, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, FileHandle, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
PEHeaderSize = PEHeader32->FileHeader.NumberOfSections * IMAGE_SIZEOF_SECTION_HEADER + PEHeader32->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4;
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
PEHeaderSize = PEHeader64->FileHeader.NumberOfSections * IMAGE_SIZEOF_SECTION_HEADER + PEHeader64->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4;
FileIs64 = true;
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(NULL);
}
if(!FileIs64)
{
if(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress != NULL)
{
DLLMemory = VirtualAlloc(NULL, DOSHeader->e_lfanew + PEHeaderSize + PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size + 0x1000, MEM_COMMIT, PAGE_READWRITE);
if(DLLMemory != NULL)
{
__try
{
if((DOSHeader->e_lfanew + PEHeaderSize) % 0x1000 != 0)
{
ExportDelta = (((DOSHeader->e_lfanew + PEHeaderSize) / 0x1000) + 1) * 0x1000;
}
else
{
ExportDelta = ((DOSHeader->e_lfanew + PEHeaderSize) / 0x1000) * 0x1000;
}
ConvertedExport = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, PEHeader32->OptionalHeader.ImageBase, PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress, true, true);
if(ConvertedExport != NULL)
{
PEExports = (PIMAGE_EXPORT_DIRECTORY)((ULONG_PTR)DLLMemory + ExportDelta);
RtlCopyMemory(DLLMemory, (LPVOID)FileMapVA, PEHeaderSize + DOSHeader->e_lfanew);
RtlCopyMemory((LPVOID)((ULONG_PTR)DLLMemory + ExportDelta), (LPVOID)ConvertedExport, PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size);
PEExports->AddressOfFunctions = PEExports->AddressOfFunctions - PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + ExportDelta;
PEExports->AddressOfNameOrdinals = PEExports->AddressOfNameOrdinals - PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + ExportDelta;
PEExports->AddressOfNames = PEExports->AddressOfNames - PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + ExportDelta;
PEExports->Name = PEExports->Name - PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + ExportDelta;
ExportedFunctionNames = (PEXPORTED_DATA)(PEExports->AddressOfNames + (ULONG_PTR)DLLMemory);
for(n = 0; n < (int)PEExports->NumberOfNames; n++)
{
ExportedFunctionNames->ExportedItem = ExportedFunctionNames->ExportedItem - PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + ExportDelta;
ExportedFunctionNames = (PEXPORTED_DATA)((ULONG_PTR)ExportedFunctionNames + 4);
}
DOSHeader = (PIMAGE_DOS_HEADER)DLLMemory;
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = ExportDelta;
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return((ULONG_PTR)DLLMemory);
}
else
{
VirtualFree(DLLMemory, NULL, MEM_RELEASE);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
VirtualFree(DLLMemory, NULL, MEM_RELEASE);
}
}
}
}
else
{
if(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress != NULL)
{
DLLMemory = VirtualAlloc(NULL, DOSHeader->e_lfanew + PEHeaderSize + PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size + 0x1000, MEM_COMMIT, PAGE_READWRITE);
if(DLLMemory != NULL)
{
__try
{
if((DOSHeader->e_lfanew + PEHeaderSize) % 0x1000 != 0)
{
ExportDelta = (((DOSHeader->e_lfanew + PEHeaderSize) % 0x1000) + 1) * 0x1000;
}
else
{
ExportDelta = ((DOSHeader->e_lfanew + PEHeaderSize) % 0x1000) * 0x1000;
}
ConvertedExport = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress, true, true);
if(ConvertedExport != NULL)
{
PEExports = (PIMAGE_EXPORT_DIRECTORY)((ULONG_PTR)DLLMemory + ExportDelta);
RtlCopyMemory(DLLMemory, (LPVOID)FileMapVA, PEHeaderSize + PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size);
RtlCopyMemory((LPVOID)((ULONG_PTR)DLLMemory + ExportDelta), (LPVOID)ConvertedExport, PEHeaderSize + DOSHeader->e_lfanew);
PEExports->AddressOfFunctions = PEExports->AddressOfFunctions - PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + ExportDelta;
PEExports->AddressOfNameOrdinals = PEExports->AddressOfNameOrdinals - PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + ExportDelta;
PEExports->AddressOfNames = PEExports->AddressOfNames - PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + ExportDelta;
PEExports->Name = PEExports->Name - PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + ExportDelta;
ExportedFunctionNames = (PEXPORTED_DATA)(PEExports->AddressOfNames + (ULONG_PTR)DLLMemory);
for(n = 0; n < (int)PEExports->NumberOfNames; n++)
{
ExportedFunctionNames->ExportedItem = ExportedFunctionNames->ExportedItem - PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + ExportDelta;
ExportedFunctionNames = (PEXPORTED_DATA)((ULONG_PTR)ExportedFunctionNames + 4);
}
DOSHeader = (PIMAGE_DOS_HEADER)DLLMemory;
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = ExportDelta;
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return((ULONG_PTR)DLLMemory);
}
else
{
VirtualFree(DLLMemory, NULL, MEM_RELEASE);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
VirtualFree(DLLMemory, NULL, MEM_RELEASE);
}
}
}
}
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
}
}
}
}
VirtualFree((void*)szTranslatedProcName, NULL, MEM_RELEASE);
return(NULL);
}
long long EngineGetProcAddress(ULONG_PTR ModuleBase, char* szAPIName)
{
int i = 0;
int j = 0;
ULONG_PTR APIFoundAddress = 0;
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
PIMAGE_EXPORT_DIRECTORY PEExports;
PEXPORTED_DATA ExportedFunctions;
PEXPORTED_DATA ExportedFunctionNames;
PEXPORTED_DATA_WORD ExportedFunctionOrdinals;
char szModuleName[MAX_PATH] = {};
bool FileIs64 = false;
if(GetModuleFileNameA((HMODULE)ModuleBase, szModuleName, MAX_PATH) == NULL)
{
__try
{
DOSHeader = (PIMAGE_DOS_HEADER)ModuleBase;
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
return(NULL);
}
if(!FileIs64)
{
PEExports = (PIMAGE_EXPORT_DIRECTORY)(ModuleBase + (ULONG_PTR)PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
ExportedFunctions = (PEXPORTED_DATA)(ModuleBase + (ULONG_PTR)PEExports->AddressOfFunctions);
ExportedFunctionNames = (PEXPORTED_DATA)(ModuleBase + (ULONG_PTR)PEExports->AddressOfNames);
ExportedFunctionOrdinals = (PEXPORTED_DATA_WORD)(ModuleBase + (ULONG_PTR)PEExports->AddressOfNameOrdinals);
}
else
{
PEExports = (PIMAGE_EXPORT_DIRECTORY)(ModuleBase + (ULONG_PTR)PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
ExportedFunctions = (PEXPORTED_DATA)(ModuleBase + (ULONG_PTR)PEExports->AddressOfFunctions);
ExportedFunctionNames = (PEXPORTED_DATA)(ModuleBase + (ULONG_PTR)PEExports->AddressOfNames);
ExportedFunctionOrdinals = (PEXPORTED_DATA_WORD)(ModuleBase + (ULONG_PTR)PEExports->AddressOfNameOrdinals);
}
for(j = 0; j < (int)PEExports->NumberOfNames; j++)
{
if(lstrcmpiA((LPCSTR)szAPIName, (LPCSTR)(ModuleBase + (ULONG_PTR)ExportedFunctionNames->ExportedItem)) == NULL)
{
ExportedFunctionOrdinals = (PEXPORTED_DATA_WORD)((ULONG_PTR)ExportedFunctionOrdinals + j * 2);
ExportedFunctions = (PEXPORTED_DATA)((ULONG_PTR)ExportedFunctions + (ExportedFunctionOrdinals->OrdinalNumber) * 4);
APIFoundAddress = ExportedFunctions->ExportedItem + (ULONG_PTR)ModuleBase;
return((ULONG_PTR)APIFoundAddress);
}
ExportedFunctionNames = (PEXPORTED_DATA)((ULONG_PTR)ExportedFunctionNames + 4);
}
return(NULL);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return(NULL);
}
}
else
{
return((ULONG_PTR)GetProcAddress((HMODULE)ModuleBase, szAPIName));
}
}
bool EngineGetLibraryOrdinalData(ULONG_PTR ModuleBase, LPDWORD ptrOrdinalBase, LPDWORD ptrOrdinalCount)
{
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
PIMAGE_EXPORT_DIRECTORY PEExports;
bool FileIs64 = false;
__try
{
DOSHeader = (PIMAGE_DOS_HEADER)ModuleBase;
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
return(false);
}
if(!FileIs64)
{
PEExports = (PIMAGE_EXPORT_DIRECTORY)(ModuleBase + (ULONG_PTR)PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
*ptrOrdinalBase = PEExports->Base;
*ptrOrdinalCount = PEExports->NumberOfNames;
}
else
{
PEExports = (PIMAGE_EXPORT_DIRECTORY)(ModuleBase + (ULONG_PTR)PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
*ptrOrdinalBase = PEExports->Base;
*ptrOrdinalCount = PEExports->NumberOfNames;
}
return(true);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return(false);
}
return(false);
}
long long EngineGlobalAPIHandler(HANDLE handleProcess, ULONG_PTR EnumedModulesBases, ULONG_PTR APIAddress, char* szAPIName, DWORD ReturnType)
{
unsigned int i = 0;
unsigned int j = 0;
unsigned int n = 0;
unsigned int x = 0;
unsigned int y = 0;
unsigned int z = 0;
DWORD Dummy = NULL;
HANDLE hProcess = NULL;
ULONG_PTR EnumeratedModules[0x2000];
ULONG_PTR LoadedModules[1000][4];
char RemoteDLLName[MAX_PATH]={0};
char FullRemoteDLLName[MAX_PATH]={0};
char szWindowsSideBySide[MAX_PATH]={0};
char szWindowsSideBySideCmp[MAX_PATH]={0};
char szWindowsKernelBase[MAX_PATH]={0};
HANDLE hLoadedModule = NULL;
HANDLE ModuleHandle = NULL;
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
PIMAGE_EXPORT_DIRECTORY PEExports;
PEXPORTED_DATA ExportedFunctions;
PEXPORTED_DATA ExportedFunctionNames;
PEXPORTED_DATA_WORD ExportedFunctionOrdinals;
ULONG_PTR APIFoundAddress = NULL;
MODULEINFO RemoteModuleInfo;
bool ValidateHeader = false;
bool FileIs64 = false;
bool APINameFound = false;
bool SkipModule = false;
unsigned int FoundIndex = 0;
unsigned int FoundOrdinalNumber = 0;
ULONG_PTR FileMapVA;
char szFwdDLLName[512] = {0};
char szFwdAPIName[512] = {0};
ULONG_PTR RealignedAPIAddress;
ULONG_PTR ForwarderData = NULL;
unsigned int ClosestAPI = 0x1000;
int Vista64UserForwarderFix = 0;
unsigned int Windows7KernelBase = 0xFFFFFFFF;
RtlZeroMemory(&engineFoundDLLName, sizeof(szFwdDLLName));
RtlZeroMemory(&EnumeratedModules, 0x2000 * sizeof ULONG_PTR);
RtlZeroMemory(&LoadedModules, 1000 * 4 * sizeof ULONG_PTR);
GetWindowsDirectoryA(szWindowsSideBySide, MAX_PATH);
lstrcpyA(szWindowsKernelBase, szWindowsSideBySide);
lstrcatA(szWindowsSideBySide, "\\WinSxS");
if(EnumedModulesBases != NULL)
{
RtlMoveMemory(&EnumeratedModules, (LPVOID)EnumedModulesBases, 0x1000);
i--;
}
if(handleProcess == NULL)
{
if(dbgProcessInformation.hProcess == NULL)
{
hProcess = GetCurrentProcess();
}
else
{
hProcess = dbgProcessInformation.hProcess;
}
}
else
{
hProcess = handleProcess;
}
if(EnumedModulesBases != NULL || EnumProcessModules(hProcess, (HMODULE*)EnumeratedModules, 0x2000, &Dummy))
{
i++;
z = i;
y = i;
while(EnumeratedModules[y] != NULL)
{
// Vista x64 fix
if(Vista64UserForwarderFix == NULL)
{
GetModuleBaseNameA(hProcess, (HMODULE)EnumeratedModules[y], (LPSTR)RemoteDLLName, MAX_PATH);
if(!lstrcmpiA(RemoteDLLName, "user32.dll"))
Vista64UserForwarderFix = y;
//NOTE: this code is used to ignore all APIs inside kernelbase.dll
else if(!lstrcmpiA(RemoteDLLName, "kernelbase.dll"))
{
GetModuleFileNameExA(hProcess, (HMODULE)EnumeratedModules[y], (LPSTR)RemoteDLLName, MAX_PATH);
RemoteDLLName[lstrlenA(szWindowsKernelBase)] = 0x00;
if(lstrcmpiA(RemoteDLLName, szWindowsKernelBase) == NULL)
{
Windows7KernelBase = y;
}
}
}
y++;
}
while(APINameFound == false && EnumeratedModules[i] != NULL)
{
//NOTE: un-comment when kernelbase should be ignored
/*if(i == Windows7KernelBase)
{
i++;
if(EnumeratedModules[i] == NULL)
{
break;
}
}*/
ValidateHeader = false;
RtlZeroMemory(&RemoteDLLName, MAX_PATH);
GetModuleFileNameExA(hProcess, (HMODULE)EnumeratedModules[i], (LPSTR)RemoteDLLName, MAX_PATH);
lstrcpyA(FullRemoteDLLName, RemoteDLLName);
RtlZeroMemory(&szWindowsSideBySideCmp, MAX_PATH);
RtlCopyMemory(&szWindowsSideBySideCmp, FullRemoteDLLName, lstrlenA(szWindowsSideBySide));
if(GetModuleHandleA(RemoteDLLName) == NULL)
{
RtlZeroMemory(&RemoteDLLName, MAX_PATH);
GetModuleBaseNameA(hProcess, (HMODULE)EnumeratedModules[i], (LPSTR)RemoteDLLName, MAX_PATH);
if(GetModuleHandleA(RemoteDLLName) == NULL || lstrcmpiA(szWindowsSideBySideCmp, szWindowsSideBySide) == NULL)
{
if(engineAlowModuleLoading)
{
hLoadedModule = LoadLibraryA(FullRemoteDLLName);
if(hLoadedModule != NULL)
{
LoadedModules[i][0] = EnumeratedModules[i];
LoadedModules[i][1] = (ULONG_PTR)hLoadedModule;
LoadedModules[i][2] = 1;
}
}
else
{
hLoadedModule = (HANDLE)EngineSimulateDllLoader(hProcess, FullRemoteDLLName);
if(hLoadedModule != NULL)
{
LoadedModules[i][0] = EnumeratedModules[i];
LoadedModules[i][1] = (ULONG_PTR)hLoadedModule;
LoadedModules[i][2] = 1;
ValidateHeader = true;
}
}
}
else
{
LoadedModules[i][0] = EnumeratedModules[i];
LoadedModules[i][1] = (ULONG_PTR)GetModuleHandleA(RemoteDLLName);
LoadedModules[i][2] = 0;
}
}
else
{
LoadedModules[i][0] = EnumeratedModules[i];
LoadedModules[i][1] = (ULONG_PTR)GetModuleHandleA(RemoteDLLName);
LoadedModules[i][2] = 0;
}
if(ReturnType != UE_OPTION_IMPORTER_RETURN_FORWARDER_DLLNAME && ReturnType != UE_OPTION_IMPORTER_RETURN_FORWARDER_DLLINDEX && ReturnType != UE_OPTION_IMPORTER_RETURN_FORWARDER_APINAME)
{
if(szAPIName == NULL && ReturnType == UE_OPTION_IMPORTER_REALIGN_APIADDRESS)
{
RtlZeroMemory(&RemoteModuleInfo, sizeof MODULEINFO);
//GetModuleInformation(GetCurrentProcess(), (HMODULE)LoadedModules[i][1], &RemoteModuleInfo, sizeof MODULEINFO);
GetModuleInformation(hProcess, (HMODULE)LoadedModules[i][0], &RemoteModuleInfo, sizeof MODULEINFO);
if(APIAddress >= LoadedModules[i][1] && APIAddress <= LoadedModules[i][1] + RemoteModuleInfo.SizeOfImage)
{
GetModuleBaseNameA(hProcess, (HMODULE)LoadedModules[i][0], (LPSTR)engineFoundDLLName, 512);
APIFoundAddress = (ULONG_PTR)(APIAddress - LoadedModules[i][1] + LoadedModules[i][0]);
APINameFound = true;
FoundIndex = i;
break;
}
}
else if(szAPIName == NULL && ReturnType == UE_OPTION_IMPORTER_REALIGN_LOCAL_APIADDRESS)
{
RtlZeroMemory(&RemoteModuleInfo, sizeof MODULEINFO);
GetModuleInformation(hProcess, (HMODULE)LoadedModules[i][0], &RemoteModuleInfo, sizeof MODULEINFO);
if(APIAddress >= LoadedModules[i][0] && APIAddress <= LoadedModules[i][0] + RemoteModuleInfo.SizeOfImage)
{
GetModuleBaseNameA(hProcess, (HMODULE)LoadedModules[i][0], (LPSTR)engineFoundDLLName, 512);
APIFoundAddress = (ULONG_PTR)(APIAddress - LoadedModules[i][0] + LoadedModules[i][1]);
APINameFound = true;
FoundIndex = i;
break;
}
}
else if(szAPIName == NULL && ReturnType == UE_OPTION_IMPORTER_RETURN_DLLBASE)
{
if(APIAddress == LoadedModules[i][1])
{
APIFoundAddress = LoadedModules[i][0];
APINameFound = true;
FoundIndex = i;
break;
}
}
else if(ReturnType == UE_OPTION_IMPORTER_RETURN_NEAREST_APIADDRESS || ReturnType == UE_OPTION_IMPORTER_RETURN_NEAREST_APINAME)
{
RtlZeroMemory(&RemoteModuleInfo, sizeof MODULEINFO);
GetModuleInformation(hProcess, (HMODULE)LoadedModules[i][0], &RemoteModuleInfo, sizeof MODULEINFO);
if(APIAddress >= LoadedModules[i][0] && APIAddress <= LoadedModules[i][0] + RemoteModuleInfo.SizeOfImage)
{
DOSHeader = (PIMAGE_DOS_HEADER)LoadedModules[i][1];
if(ValidateHeader || EngineValidateHeader((ULONG_PTR)LoadedModules[i][1], GetCurrentProcess(), RemoteModuleInfo.lpBaseOfDll, DOSHeader, false))
{
__try
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
return(NULL);
}
if(!FileIs64)
{
PEExports = (PIMAGE_EXPORT_DIRECTORY)(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + LoadedModules[i][1]);
ExportedFunctions = (PEXPORTED_DATA)(PEExports->AddressOfFunctions + LoadedModules[i][1]);
}
else
{
PEExports = (PIMAGE_EXPORT_DIRECTORY)(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + LoadedModules[i][1]);
ExportedFunctions = (PEXPORTED_DATA)(PEExports->AddressOfFunctions + LoadedModules[i][1]);
}
for(n = 0; n < PEExports->NumberOfFunctions; n++) //NumberOfNames
{
if(APIAddress - (ExportedFunctions->ExportedItem + LoadedModules[i][0]) < ClosestAPI)
{
ClosestAPI = (unsigned int)(APIAddress - (ExportedFunctions->ExportedItem + LoadedModules[i][0]));
ExportedFunctionNames = (PEXPORTED_DATA)(PEExports->AddressOfNames + LoadedModules[i][1]);
ExportedFunctionOrdinals = (PEXPORTED_DATA_WORD)(PEExports->AddressOfNameOrdinals + LoadedModules[i][1]);
GetModuleBaseNameA(hProcess, (HMODULE)LoadedModules[i][0], (LPSTR)engineFoundDLLName, 512);
RtlZeroMemory(&engineFoundAPIName, sizeof(engineFoundAPIName));
x = n;
FoundOrdinalNumber = (unsigned int)PEExports->Base;
for(j = 0; j < PEExports->NumberOfNames; j++)
{
if(ExportedFunctionOrdinals->OrdinalNumber != x)
{
ExportedFunctionOrdinals = (PEXPORTED_DATA_WORD)((ULONG_PTR)ExportedFunctionOrdinals + 2);
}
else
{
FoundOrdinalNumber = FoundOrdinalNumber + (unsigned int)ExportedFunctionOrdinals->OrdinalNumber;
break;
}
}
ExportedFunctionNames = (PEXPORTED_DATA)((ULONG_PTR)ExportedFunctionNames + j * 4);
if(EngineIsPointedMemoryString((ULONG_PTR)(ExportedFunctionNames->ExportedItem + LoadedModules[i][1])))
{
lstrcpyA((LPSTR)engineFoundAPIName, (LPCSTR)(ExportedFunctionNames->ExportedItem + LoadedModules[i][1]));
}
APIFoundAddress = ExportedFunctions->ExportedItem + LoadedModules[i][0];
APINameFound = true;
FoundIndex = i;
}
ExportedFunctions = (PEXPORTED_DATA)((ULONG_PTR)ExportedFunctions + 4);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
ClosestAPI = 0x1000;
APINameFound = false;
}
}
}
}
if((ReturnType == UE_OPTION_IMPORTER_RETURN_API_ORDINAL_NUMBER || (ReturnType > UE_OPTION_IMPORTER_REALIGN_APIADDRESS && ReturnType < UE_OPTION_IMPORTER_RETURN_FORWARDER_DLLNAME)) && ReturnType != UE_OPTION_IMPORTER_RETURN_DLLBASE && LoadedModules[i][1] != NULL)
{
RtlZeroMemory(&RemoteModuleInfo, sizeof MODULEINFO);
DOSHeader = (PIMAGE_DOS_HEADER)LoadedModules[i][1];
//GetModuleInformation(GetCurrentProcess(), (HMODULE)LoadedModules[i][1], &RemoteModuleInfo, sizeof MODULEINFO);
GetModuleInformation(hProcess, (HMODULE)LoadedModules[i][0], &RemoteModuleInfo, sizeof MODULEINFO);
if(APIAddress >= LoadedModules[i][0] && APIAddress <= LoadedModules[i][0] + RemoteModuleInfo.SizeOfImage)
{
if(ValidateHeader || EngineValidateHeader((ULONG_PTR)LoadedModules[i][1], GetCurrentProcess(), RemoteModuleInfo.lpBaseOfDll, DOSHeader, false))
{
__try
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
return(NULL);
}
if(!FileIs64)
{
PEExports = (PIMAGE_EXPORT_DIRECTORY)(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + LoadedModules[i][1]);
ExportedFunctions = (PEXPORTED_DATA)(PEExports->AddressOfFunctions + LoadedModules[i][1]);
ExportedFunctionNames = (PEXPORTED_DATA)(PEExports->AddressOfNames + LoadedModules[i][1]);
ExportedFunctionOrdinals = (PEXPORTED_DATA_WORD)(PEExports->AddressOfNameOrdinals + LoadedModules[i][1]);
}
else
{
PEExports = (PIMAGE_EXPORT_DIRECTORY)(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + LoadedModules[i][1]);
ExportedFunctions = (PEXPORTED_DATA)(PEExports->AddressOfFunctions + LoadedModules[i][1]);
ExportedFunctionNames = (PEXPORTED_DATA)(PEExports->AddressOfNames + LoadedModules[i][1]);
ExportedFunctionOrdinals = (PEXPORTED_DATA_WORD)(PEExports->AddressOfNameOrdinals + LoadedModules[i][1]);
}
if(ReturnType == UE_OPTION_IMPORTER_RETURN_APINAME || ReturnType == UE_OPTION_IMPORTER_RETURN_DLLNAME || ReturnType == UE_OPTION_IMPORTER_RETURN_DLLINDEX || ReturnType == UE_OPTION_IMPORTER_RETURN_API_ORDINAL_NUMBER)
{
for(j = 0; j < PEExports->NumberOfFunctions; j++) //NumberOfNames
{
if(ExportedFunctions->ExportedItem + LoadedModules[i][0] == APIAddress)
{
GetModuleBaseNameA(hProcess, (HMODULE)LoadedModules[i][0], (LPSTR)engineFoundDLLName, 512);
RtlZeroMemory(&engineFoundAPIName, sizeof(engineFoundAPIName));
x = j;
FoundOrdinalNumber = (unsigned int)PEExports->Base;
for(j = 0; j < PEExports->NumberOfNames; j++)
{
if(ExportedFunctionOrdinals->OrdinalNumber != x)
{
ExportedFunctionOrdinals = (PEXPORTED_DATA_WORD)((ULONG_PTR)ExportedFunctionOrdinals + 2);
}
else
{
FoundOrdinalNumber = FoundOrdinalNumber + (unsigned int)ExportedFunctionOrdinals->OrdinalNumber;
break;
}
}
ExportedFunctionNames = (PEXPORTED_DATA)((ULONG_PTR)ExportedFunctionNames + j * 4);
if(EngineIsPointedMemoryString((ULONG_PTR)(ExportedFunctionNames->ExportedItem + LoadedModules[i][1])))
{
lstrcpyA((LPSTR)engineFoundAPIName, (LPCSTR)(ExportedFunctionNames->ExportedItem + LoadedModules[i][1]));
}
APINameFound = true;
FoundIndex = i;
break;
}
ExportedFunctions = (PEXPORTED_DATA)((ULONG_PTR)ExportedFunctions + 4);
}
}
else if(ReturnType == UE_OPTION_IMPORTER_RETURN_APIADDRESS)
{
for(j = 0; j < PEExports->NumberOfFunctions; j++) //NumberOfNames
{
if(lstrcmpiA((LPCSTR)szAPIName, (LPCSTR)(ExportedFunctionNames->ExportedItem + LoadedModules[i][1])) == NULL)
{
ExportedFunctionOrdinals = (PEXPORTED_DATA_WORD)((ULONG_PTR)ExportedFunctionOrdinals + j * 2);
ExportedFunctions = (PEXPORTED_DATA)((ULONG_PTR)ExportedFunctions + (ExportedFunctionOrdinals->OrdinalNumber) * 4);
GetModuleBaseNameA(hProcess, (HMODULE)LoadedModules[i][0], (LPSTR)engineFoundDLLName, 512);
RtlZeroMemory(&engineFoundAPIName, sizeof(engineFoundAPIName));
ExportedFunctions = (PEXPORTED_DATA)((ULONG_PTR)ExportedFunctions + (j + PEExports->Base) * 4);
APIFoundAddress = ExportedFunctions->ExportedItem + LoadedModules[i][0];
APINameFound = true;
FoundIndex = i;
break;
}
ExportedFunctionNames = (PEXPORTED_DATA)((ULONG_PTR)ExportedFunctionNames + 4);
}
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
RtlZeroMemory(&engineFoundAPIName, sizeof(engineFoundAPIName));
APINameFound = false;
}
}
}
}
}
i++;
}
if(ReturnType == UE_OPTION_IMPORTER_RETURN_FORWARDER_DLLNAME || ReturnType == UE_OPTION_IMPORTER_RETURN_FORWARDER_APINAME || ReturnType == UE_OPTION_IMPORTER_RETURN_FORWARDER_DLLINDEX || ReturnType == UE_OPTION_IMPORTER_RETURN_FORWARDER_API_ORDINAL_NUMBER)
{
RealignedAPIAddress = (ULONG_PTR)EngineGlobalAPIHandler(hProcess, NULL, APIAddress, NULL, UE_OPTION_IMPORTER_REALIGN_APIADDRESS);
if(z <= 1)
{
z = 2;
}
for(i = y; i >= z; i--)
{
FileMapVA = LoadedModules[i][1];
if(FileMapVA != NULL)
{
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
RtlZeroMemory(&RemoteModuleInfo, sizeof MODULEINFO);
//GetModuleInformation(GetCurrentProcess(), (HMODULE)LoadedModules[i][1], &RemoteModuleInfo, sizeof MODULEINFO);
GetModuleInformation(hProcess, (HMODULE)LoadedModules[i][0], &RemoteModuleInfo, sizeof MODULEINFO);
if(ValidateHeader || EngineValidateHeader((ULONG_PTR)LoadedModules[i][1], GetCurrentProcess(), RemoteModuleInfo.lpBaseOfDll, DOSHeader, false))
{
__try
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
SkipModule = true;
}
if(!SkipModule)
{
if(!FileIs64)
{
PEExports = (PIMAGE_EXPORT_DIRECTORY)(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + LoadedModules[i][1]);
ExportedFunctionNames = (PEXPORTED_DATA)(PEExports->AddressOfNames + LoadedModules[i][1]);
ExportedFunctions = (PEXPORTED_DATA)(PEExports->AddressOfFunctions + LoadedModules[i][1]);
ExportedFunctionOrdinals = (PEXPORTED_DATA_WORD)(PEExports->AddressOfNameOrdinals + LoadedModules[i][1]);
}
else
{
PEExports = (PIMAGE_EXPORT_DIRECTORY)(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + LoadedModules[i][1]);
ExportedFunctionNames = (PEXPORTED_DATA)(PEExports->AddressOfNames + LoadedModules[i][1]);
ExportedFunctions = (PEXPORTED_DATA)(PEExports->AddressOfFunctions + LoadedModules[i][1]);
ExportedFunctionOrdinals = (PEXPORTED_DATA_WORD)(PEExports->AddressOfNameOrdinals + LoadedModules[i][1]);
}
for(j = 0; j < PEExports->NumberOfFunctions; j++)
{
if(EngineIsPointedMemoryString((ULONG_PTR)ExportedFunctions->ExportedItem + LoadedModules[i][1]))
{
RtlZeroMemory(&szFwdAPIName, 512);
RtlZeroMemory(&szFwdDLLName, 512);
if(EngineExtractForwarderData((ULONG_PTR)ExportedFunctions->ExportedItem + LoadedModules[i][1], &szFwdDLLName, &szFwdAPIName))
{
if((ULONG_PTR)GetProcAddress(GetModuleHandleA(szFwdDLLName), szFwdAPIName) == RealignedAPIAddress)
{
GetModuleBaseNameA(hProcess, (HMODULE)LoadedModules[i][0], (LPSTR)engineFoundDLLName, 512);
RtlZeroMemory(&engineFoundAPIName, 512);
x = j;
FoundOrdinalNumber = (unsigned int)PEExports->Base;
for(j = 0; j < PEExports->NumberOfNames; j++)
{
if(ExportedFunctionOrdinals->OrdinalNumber != x)
{
ExportedFunctionOrdinals = (PEXPORTED_DATA_WORD)((ULONG_PTR)ExportedFunctionOrdinals + 2);
}
else
{
FoundOrdinalNumber = FoundOrdinalNumber + (unsigned int)ExportedFunctionOrdinals->OrdinalNumber;
break;
}
}
ExportedFunctionNames = (PEXPORTED_DATA)((ULONG_PTR)ExportedFunctionNames + j * 4);
if(EngineIsPointedMemoryString((ULONG_PTR)(ExportedFunctionNames->ExportedItem + LoadedModules[i][1])))
{
lstrcpyA((LPSTR)engineFoundAPIName, (LPCSTR)(ExportedFunctionNames->ExportedItem + LoadedModules[i][1]));
}
APINameFound = true;
FoundIndex = i;
break;
}
}
}
ExportedFunctions = (PEXPORTED_DATA)((ULONG_PTR)ExportedFunctions + 4);
}
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
RtlZeroMemory(&szFwdAPIName, 512);
RtlZeroMemory(&szFwdDLLName, 512);
APINameFound = false;
}
}
}
if(APINameFound)
{
break;
}
}
}
i = 1;
while(EnumeratedModules[i] != NULL)
{
if(engineAlowModuleLoading)
{
if(LoadedModules[i][2] == 1)
{
FreeLibrary((HMODULE)LoadedModules[i][1]);
}
}
else
{
if(LoadedModules[i][2] == 1)
{
VirtualFree((void*)LoadedModules[i][1], NULL, MEM_RELEASE);
}
}
i++;
}
if(APINameFound)
{
//
// Vista/w7 x64 fix
//
if(lstrcmpiA(engineFoundAPIName, "NtdllDefWindowProc_A") == NULL)
{
lstrcpyA(engineFoundAPIName, "DefWindowProcA");
lstrcpyA(engineFoundDLLName, "user32.dll");
FoundIndex = Vista64UserForwarderFix;
}
else if(lstrcmpiA(engineFoundAPIName, "NtdllDefWindowProc_W") == NULL)
{
lstrcpyA(engineFoundAPIName, "DefWindowProcW");
lstrcpyA(engineFoundDLLName, "user32.dll");
FoundIndex = Vista64UserForwarderFix;
}
else if(lstrcmpiA(engineFoundAPIName, "NtdllDialogWndProc_A") == NULL)
{
lstrcpyA(engineFoundAPIName, "DefDlgProcA");
lstrcpyA(engineFoundDLLName, "user32.dll");
FoundIndex = Vista64UserForwarderFix;
}
else if(lstrcmpiA(engineFoundAPIName, "NtdllDialogWndProc_W") == NULL)
{
lstrcpyA(engineFoundAPIName, "DefDlgProcW");
lstrcpyA(engineFoundDLLName, "user32.dll");
FoundIndex = Vista64UserForwarderFix;
}
if(ReturnType == UE_OPTION_IMPORTER_RETURN_APINAME || ReturnType == UE_OPTION_IMPORTER_RETURN_FORWARDER_APINAME)
{
if(ReturnType == UE_OPTION_IMPORTER_RETURN_APINAME && engineCheckForwarders == true)
{
if(engineAlowModuleLoading == true || (engineAlowModuleLoading == false && LoadedModules[FoundIndex][2] != 1))
{
if(lstrcmpiA(engineFoundDLLName, "ntdll.dll") == NULL)
{
ForwarderData = (ULONG_PTR)EngineGlobalAPIHandler(handleProcess, EnumedModulesBases, APIAddress, NULL, UE_OPTION_IMPORTER_RETURN_FORWARDER_APINAME);
}
else
{
ForwarderData = NULL;
}
if(ForwarderData != NULL)
{
return(ForwarderData);
}
else
{
if(engineFoundAPIName[0] != 0x00)
{
return((ULONG_PTR)engineFoundAPIName);
}
else
{
return(NULL);
}
}
}
else
{
if(engineFoundAPIName[0] != 0x00)
{
return((ULONG_PTR)engineFoundAPIName);
}
else
{
return(NULL);
}
}
}
else
{
if(engineFoundAPIName[0] != 0x00)
{
return((ULONG_PTR)engineFoundAPIName);
}
else
{
return(NULL);
}
}
}
else if(ReturnType == UE_OPTION_IMPORTER_RETURN_APIADDRESS)
{
return(APIFoundAddress);
}
else if(ReturnType == UE_OPTION_IMPORTER_RETURN_API_ORDINAL_NUMBER || ReturnType == UE_OPTION_IMPORTER_RETURN_FORWARDER_API_ORDINAL_NUMBER)
{
return((ULONG_PTR)FoundOrdinalNumber);
}
else if(ReturnType == UE_OPTION_IMPORTER_RETURN_DLLNAME || ReturnType == UE_OPTION_IMPORTER_RETURN_FORWARDER_DLLNAME)
{
if(ReturnType == UE_OPTION_IMPORTER_RETURN_DLLNAME && engineCheckForwarders == true)
{
if(engineAlowModuleLoading == true || (engineAlowModuleLoading == false && LoadedModules[FoundIndex][2] != 1))
{
if(lstrcmpiA(engineFoundDLLName, "ntdll.dll") == NULL)
{
ForwarderData = (ULONG_PTR)EngineGlobalAPIHandler(handleProcess, EnumedModulesBases, APIAddress, NULL, UE_OPTION_IMPORTER_RETURN_FORWARDER_DLLNAME);
}
else
{
ForwarderData = NULL;
}
if(ForwarderData != NULL)
{
return(ForwarderData);
}
else
{
if(engineFoundDLLName[0] != 0x00)
{
return((ULONG_PTR)engineFoundDLLName);
}
else
{
return(NULL);
}
}
}
else
{
if(engineFoundDLLName[0] != 0x00)
{
return((ULONG_PTR)engineFoundDLLName);
}
else
{
return(NULL);
}
}
}
else
{
if(engineFoundDLLName[0] != 0x00)
{
return((ULONG_PTR)engineFoundDLLName);
}
else
{
return(NULL);
}
}
}
else if(ReturnType == UE_OPTION_IMPORTER_RETURN_DLLINDEX || ReturnType == UE_OPTION_IMPORTER_RETURN_FORWARDER_DLLINDEX)
{
if(ReturnType == UE_OPTION_IMPORTER_RETURN_DLLINDEX && engineCheckForwarders == true)
{
if(engineAlowModuleLoading == true || (engineAlowModuleLoading == false && LoadedModules[FoundIndex][2] != 1))
{
if(lstrcmpiA(engineFoundDLLName, "ntdll.dll") == NULL)
{
ForwarderData = (ULONG_PTR)EngineGlobalAPIHandler(handleProcess, EnumedModulesBases, APIAddress, NULL, UE_OPTION_IMPORTER_RETURN_FORWARDER_DLLINDEX);
}
else
{
ForwarderData = NULL;
}
if(ForwarderData != NULL)
{
return(ForwarderData);
}
else
{
return(FoundIndex);
}
}
else
{
return(FoundIndex);
}
}
else
{
return(FoundIndex);
}
}
else if(ReturnType == UE_OPTION_IMPORTER_RETURN_DLLBASE)
{
return(APIFoundAddress);
}
else if(ReturnType == UE_OPTION_IMPORTER_RETURN_NEAREST_APIADDRESS)
{
return(APIFoundAddress);
}
else if(ReturnType == UE_OPTION_IMPORTER_RETURN_NEAREST_APINAME)
{
if(engineCheckForwarders)
{
if(engineAlowModuleLoading == true || (engineAlowModuleLoading == false && LoadedModules[FoundIndex][2] != 1))
{
if(lstrcmpiA(engineFoundDLLName, "ntdll.dll") == NULL)
{
ForwarderData = (ULONG_PTR)EngineGlobalAPIHandler(handleProcess, EnumedModulesBases, APIAddress, NULL, UE_OPTION_IMPORTER_RETURN_FORWARDER_APINAME);
}
else
{
ForwarderData = NULL;
}
if(ForwarderData != NULL)
{
return(ForwarderData);
}
else
{
if(engineFoundAPIName[0] != 0x00)
{
return((ULONG_PTR)engineFoundAPIName);
}
else
{
return(NULL);
}
}
}
else
{
if(engineFoundAPIName[0] != 0x00)
{
return((ULONG_PTR)engineFoundAPIName);
}
else
{
return(NULL);
}
}
}
else
{
if(engineFoundAPIName[0] != 0x00)
{
return((ULONG_PTR)engineFoundAPIName);
}
else
{
return(NULL);
}
}
}
else
{
return(APIFoundAddress);
}
}
else
{
if(ReturnType == UE_OPTION_IMPORTER_RETURN_API_ORDINAL_NUMBER || ReturnType == UE_OPTION_IMPORTER_RETURN_FORWARDER_API_ORDINAL_NUMBER)
{
return((ULONG_PTR)-1);
}
else
{
return(NULL);
}
}
}
else
{
return(NULL);
}
return(NULL);
}
// Global.Engine.Hash.functions:
unsigned long EngineCrc32Reflect(unsigned long ulReflect, const char cChar)
{
unsigned long ulValue = 0;
// Swap bit 0 for bit 7, bit 1 For bit 6, etc....
for(int iPos = 1; iPos < (cChar + 1); iPos++)
{
if(ulReflect & 1)
{
ulValue |= (1 << (cChar - iPos));
}
ulReflect >>= 1;
}
return ulValue;
}
void EngineCrc32PartialCRC(unsigned long *ulCRC, const unsigned char *sData, unsigned long ulDataLength)
{
while(ulDataLength--)
{
//If your compiler complains about the following line, try changing each
// occurrence of *ulCRC with "((unsigned long)*ulCRC)" or "*(unsigned long *)ulCRC".
*(unsigned long *)ulCRC = ((*(unsigned long *)ulCRC) >> 8) ^ Crc32Table[((*(unsigned long *)ulCRC) & 0xFF) ^ *sData++];
}
}
// TitanEngine.Dumper.functions:
__declspec(dllexport) bool TITCALL DumpProcess(HANDLE hProcess, LPVOID ImageBase, char* szDumpFileName, ULONG_PTR EntryPoint)
{
wchar_t uniDumpFileName[MAX_PATH] = {};
if(szDumpFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szDumpFileName, lstrlenA(szDumpFileName)+1, uniDumpFileName, sizeof(uniDumpFileName)/(sizeof(uniDumpFileName[0])));
return(DumpProcessW(hProcess, ImageBase, uniDumpFileName, EntryPoint));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL DumpProcessW(HANDLE hProcess, LPVOID ImageBase, wchar_t* szDumpFileName, ULONG_PTR EntryPoint)
{
int i = 0;
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_DOS_HEADER DOSFixHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
PIMAGE_NT_HEADERS32 PEFixHeader32;
PIMAGE_NT_HEADERS64 PEFixHeader64;
PIMAGE_SECTION_HEADER PESections;
PIMAGE_SECTION_HEADER PEFixSection;
ULONG_PTR ueNumberOfBytesRead = 0;
DWORD uedNumberOfBytesRead = 0;
DWORD SizeOfImageDump = 0;
int NumberOfSections = 0;
BOOL FileIs64 = false;
HANDLE hFile = 0;
DWORD RealignedVirtualSize = 0;
ULONG_PTR ProcReadBase = 0;
LPVOID ReadBase = ImageBase;
SIZE_T CalculatedHeaderSize = NULL;
SIZE_T AlignedHeaderSize = NULL;
LPVOID ueReadBuffer = VirtualAlloc(NULL, 0x2000, MEM_COMMIT, PAGE_READWRITE);
LPVOID ueCopyBuffer = VirtualAlloc(NULL, 0x2000, MEM_COMMIT, PAGE_READWRITE);
MEMORY_BASIC_INFORMATION MemInfo;
if(ReadProcessMemory(hProcess, ImageBase, ueReadBuffer, 0x1000, &ueNumberOfBytesRead))
{
DOSHeader = (PIMAGE_DOS_HEADER)ueReadBuffer;
CalculatedHeaderSize = DOSHeader->e_lfanew + sizeof IMAGE_DOS_HEADER + sizeof IMAGE_NT_HEADERS64;
if(CalculatedHeaderSize > 0x1000)
{
if(CalculatedHeaderSize % 0x1000 == NULL)
{
AlignedHeaderSize = 0x1000;
}
else
{
AlignedHeaderSize = ((CalculatedHeaderSize / 0x1000) + 1) * 0x1000;
}
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
VirtualFree(ueCopyBuffer, NULL, MEM_RELEASE);
ueReadBuffer = VirtualAlloc(NULL, AlignedHeaderSize, MEM_COMMIT, PAGE_READWRITE);
ueCopyBuffer = VirtualAlloc(NULL, AlignedHeaderSize, MEM_COMMIT, PAGE_READWRITE);
if(!ReadProcessMemory(hProcess, ImageBase, ueReadBuffer, AlignedHeaderSize, &ueNumberOfBytesRead))
{
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
VirtualFree(ueCopyBuffer, NULL, MEM_RELEASE);
return(false);
}
else
{
DOSHeader = (PIMAGE_DOS_HEADER)ueReadBuffer;
}
}
else
{
CalculatedHeaderSize = 0x1000;
AlignedHeaderSize = 0x1000;
}
if(EngineValidateHeader((ULONG_PTR)ueReadBuffer, hProcess, ImageBase, DOSHeader, false))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
VirtualFree(ueCopyBuffer, NULL, MEM_RELEASE);
return(false);
}
if(!FileIs64)
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader32 + PEHeader32->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
NumberOfSections = PEHeader32->FileHeader.NumberOfSections;
NumberOfSections++;
if(PEHeader32->OptionalHeader.SizeOfImage % PEHeader32->OptionalHeader.SectionAlignment == NULL)
{
SizeOfImageDump = ((PEHeader32->OptionalHeader.SizeOfImage / PEHeader32->OptionalHeader.SectionAlignment)) * PEHeader32->OptionalHeader.SectionAlignment;
}
else
{
SizeOfImageDump = ((PEHeader32->OptionalHeader.SizeOfImage / PEHeader32->OptionalHeader.SectionAlignment) + 1) * PEHeader32->OptionalHeader.SectionAlignment;
}
SizeOfImageDump = SizeOfImageDump - (DWORD)AlignedHeaderSize;
if(EngineCreatePathForFileW(szDumpFileName))
{
hFile = CreateFileW(szDumpFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile != INVALID_HANDLE_VALUE)
{
if(ReadProcessMemory(hProcess, ImageBase, ueCopyBuffer, AlignedHeaderSize, &ueNumberOfBytesRead))
{
__try
{
DOSFixHeader = (PIMAGE_DOS_HEADER)ueCopyBuffer;
PEFixHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSFixHeader + DOSFixHeader->e_lfanew);
PEFixSection = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEFixHeader32 + PEHeader32->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
if(PEFixHeader32->OptionalHeader.FileAlignment > 0x200)
{
PEFixHeader32->OptionalHeader.FileAlignment = PEHeader32->OptionalHeader.SectionAlignment;
}
PEFixHeader32->OptionalHeader.AddressOfEntryPoint = (DWORD)(EntryPoint - (ULONG_PTR)ImageBase);
PEFixHeader32->OptionalHeader.ImageBase = (DWORD)((ULONG_PTR)ImageBase);
i = NumberOfSections;
while(i >= 1)
{
PEFixSection->PointerToRawData = PEFixSection->VirtualAddress;
RealignedVirtualSize = (PEFixSection->Misc.VirtualSize / PEHeader32->OptionalHeader.SectionAlignment) * PEHeader32->OptionalHeader.SectionAlignment;
if(RealignedVirtualSize < PEFixSection->Misc.VirtualSize)
{
RealignedVirtualSize = RealignedVirtualSize + PEHeader32->OptionalHeader.SectionAlignment;
}
PEFixSection->SizeOfRawData = RealignedVirtualSize;
PEFixSection->Misc.VirtualSize = RealignedVirtualSize;
PEFixSection = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEFixSection + IMAGE_SIZEOF_SECTION_HEADER);
i--;
}
WriteFile(hFile, ueCopyBuffer, (DWORD)AlignedHeaderSize, &uedNumberOfBytesRead, NULL);
ReadBase = (LPVOID)((ULONG_PTR)ReadBase + AlignedHeaderSize - TITANENGINE_PAGESIZE);
while(SizeOfImageDump > NULL)
{
ProcReadBase = (ULONG_PTR)ReadBase + TITANENGINE_PAGESIZE;
ReadBase = (LPVOID)ProcReadBase;
if(SizeOfImageDump >= TITANENGINE_PAGESIZE)
{
RtlZeroMemory(ueCopyBuffer, AlignedHeaderSize);
if(!ReadProcessMemory(hProcess, ReadBase, ueCopyBuffer, TITANENGINE_PAGESIZE, &ueNumberOfBytesRead))
{
VirtualQueryEx(hProcess, ReadBase, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
VirtualProtectEx(hProcess, ReadBase, TITANENGINE_PAGESIZE, PAGE_EXECUTE_READWRITE, &MemInfo.Protect);
ReadProcessMemory(hProcess, ReadBase, ueCopyBuffer, TITANENGINE_PAGESIZE, &ueNumberOfBytesRead);
VirtualProtectEx(hProcess, ReadBase, TITANENGINE_PAGESIZE, MemInfo.Protect, &MemInfo.Protect);
}
WriteFile(hFile, ueCopyBuffer, TITANENGINE_PAGESIZE, &uedNumberOfBytesRead, NULL);
SizeOfImageDump = SizeOfImageDump - TITANENGINE_PAGESIZE;
}
else
{
RtlZeroMemory(ueCopyBuffer, AlignedHeaderSize);
if(!ReadProcessMemory(hProcess, ReadBase, ueCopyBuffer, SizeOfImageDump, &ueNumberOfBytesRead))
{
VirtualQueryEx(hProcess, ReadBase, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
VirtualProtectEx(hProcess, ReadBase, TITANENGINE_PAGESIZE, PAGE_EXECUTE_READWRITE, &MemInfo.Protect);
ReadProcessMemory(hProcess, ReadBase, ueCopyBuffer, TITANENGINE_PAGESIZE, &ueNumberOfBytesRead);
VirtualProtectEx(hProcess, ReadBase, TITANENGINE_PAGESIZE, MemInfo.Protect, &MemInfo.Protect);
}
WriteFile(hFile, ueCopyBuffer, SizeOfImageDump, &uedNumberOfBytesRead, NULL);
SizeOfImageDump = NULL;
}
}
EngineCloseHandle(hFile);
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
VirtualFree(ueCopyBuffer, NULL, MEM_RELEASE);
return(true);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
EngineCloseHandle(hFile);
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
VirtualFree(ueCopyBuffer, NULL, MEM_RELEASE);
return(false);
}
}
else
{
EngineCloseHandle(hFile);
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
VirtualFree(ueCopyBuffer, NULL, MEM_RELEASE);
return(false);
}
}
else
{
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
VirtualFree(ueCopyBuffer, NULL, MEM_RELEASE);
return(false);
}
}
}
else
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader64 + PEHeader64->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
NumberOfSections = PEHeader64->FileHeader.NumberOfSections;
NumberOfSections++;
if(PEHeader64->OptionalHeader.SizeOfImage % PEHeader64->OptionalHeader.SectionAlignment == NULL)
{
SizeOfImageDump = ((PEHeader64->OptionalHeader.SizeOfImage / PEHeader64->OptionalHeader.SectionAlignment)) * PEHeader64->OptionalHeader.SectionAlignment;
}
else
{
SizeOfImageDump = ((PEHeader64->OptionalHeader.SizeOfImage / PEHeader64->OptionalHeader.SectionAlignment) + 1) * PEHeader64->OptionalHeader.SectionAlignment;
}
SizeOfImageDump = SizeOfImageDump - (DWORD)AlignedHeaderSize;
if(EngineCreatePathForFileW(szDumpFileName))
{
hFile = CreateFileW(szDumpFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile != INVALID_HANDLE_VALUE)
{
if(ReadProcessMemory(hProcess, ImageBase, ueCopyBuffer, AlignedHeaderSize, &ueNumberOfBytesRead))
{
__try
{
DOSFixHeader = (PIMAGE_DOS_HEADER)ueCopyBuffer;
PEFixHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSFixHeader + DOSFixHeader->e_lfanew);
PEFixSection = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEFixHeader64 + PEHeader64->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
if(PEFixHeader64->OptionalHeader.FileAlignment > 0x200)
{
PEFixHeader64->OptionalHeader.FileAlignment = PEHeader64->OptionalHeader.SectionAlignment;
}
PEFixHeader64->OptionalHeader.AddressOfEntryPoint = (DWORD)(EntryPoint - (ULONG_PTR)ImageBase);
PEFixHeader64->OptionalHeader.ImageBase = (DWORD64)((ULONG_PTR)ImageBase);
i = NumberOfSections;
while(i >= 1)
{
PEFixSection->PointerToRawData = PEFixSection->VirtualAddress;
RealignedVirtualSize = (PEFixSection->Misc.VirtualSize / PEHeader64->OptionalHeader.SectionAlignment) * PEHeader64->OptionalHeader.SectionAlignment;
if(RealignedVirtualSize < PEFixSection->Misc.VirtualSize)
{
RealignedVirtualSize = RealignedVirtualSize + PEHeader64->OptionalHeader.SectionAlignment;
}
PEFixSection->SizeOfRawData = RealignedVirtualSize;
PEFixSection->Misc.VirtualSize = RealignedVirtualSize;
PEFixSection = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEFixSection + IMAGE_SIZEOF_SECTION_HEADER);
i--;
}
WriteFile(hFile,ueCopyBuffer, (DWORD)AlignedHeaderSize, &uedNumberOfBytesRead, NULL);
ReadBase = (LPVOID)((ULONG_PTR)ReadBase + (DWORD)AlignedHeaderSize - TITANENGINE_PAGESIZE);
while(SizeOfImageDump > NULL)
{
ProcReadBase = (ULONG_PTR)ReadBase + TITANENGINE_PAGESIZE;
ReadBase = (LPVOID)ProcReadBase;
if(SizeOfImageDump >= TITANENGINE_PAGESIZE)
{
RtlZeroMemory(ueCopyBuffer, AlignedHeaderSize);
if(!ReadProcessMemory(hProcess, ReadBase, ueCopyBuffer, TITANENGINE_PAGESIZE, &ueNumberOfBytesRead))
{
VirtualQueryEx(hProcess, ReadBase, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
VirtualProtectEx(hProcess, ReadBase, TITANENGINE_PAGESIZE, PAGE_EXECUTE_READWRITE, &MemInfo.Protect);
ReadProcessMemory(hProcess, ReadBase, ueCopyBuffer, TITANENGINE_PAGESIZE, &ueNumberOfBytesRead);
VirtualProtectEx(hProcess, ReadBase, TITANENGINE_PAGESIZE, MemInfo.Protect, &MemInfo.Protect);
}
WriteFile(hFile, ueCopyBuffer, TITANENGINE_PAGESIZE, &uedNumberOfBytesRead, NULL);
SizeOfImageDump = SizeOfImageDump - TITANENGINE_PAGESIZE;
}
else
{
RtlZeroMemory(ueCopyBuffer, AlignedHeaderSize);
if(!ReadProcessMemory(hProcess, ReadBase, ueCopyBuffer, SizeOfImageDump, &ueNumberOfBytesRead))
{
VirtualQueryEx(hProcess, ReadBase, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
VirtualProtectEx(hProcess, ReadBase, TITANENGINE_PAGESIZE, PAGE_EXECUTE_READWRITE, &MemInfo.Protect);
ReadProcessMemory(hProcess, ReadBase, ueCopyBuffer, TITANENGINE_PAGESIZE, &ueNumberOfBytesRead);
VirtualProtectEx(hProcess, ReadBase, TITANENGINE_PAGESIZE, MemInfo.Protect, &MemInfo.Protect);
}
WriteFile(hFile, ueCopyBuffer, SizeOfImageDump, &uedNumberOfBytesRead, NULL);
SizeOfImageDump = NULL;
}
}
EngineCloseHandle(hFile);
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
VirtualFree(ueCopyBuffer, NULL, MEM_RELEASE);
return(true);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
VirtualFree(ueCopyBuffer, NULL, MEM_RELEASE);
return(false);
}
}
else
{
EngineCloseHandle(hFile);
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
VirtualFree(ueCopyBuffer, NULL, MEM_RELEASE);
return(false);
}
}
else
{
EngineCloseHandle(hFile);
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
VirtualFree(ueCopyBuffer, NULL, MEM_RELEASE);
return(false);
}
}
}
}
else
{
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
VirtualFree(ueCopyBuffer, NULL, MEM_RELEASE);
return(false);
}
}
else
{
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
VirtualFree(ueCopyBuffer, NULL, MEM_RELEASE);
return(false);
}
return(false);
}
__declspec(dllexport) bool TITCALL DumpProcessEx(DWORD ProcessId, LPVOID ImageBase, char* szDumpFileName, ULONG_PTR EntryPoint)
{
wchar_t uniDumpFileName[MAX_PATH] = {};
if(szDumpFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szDumpFileName, lstrlenA(szDumpFileName)+1, uniDumpFileName, sizeof(uniDumpFileName)/(sizeof(uniDumpFileName[0])));
return(DumpProcessExW(ProcessId, ImageBase, uniDumpFileName, EntryPoint));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL DumpProcessExW(DWORD ProcessId, LPVOID ImageBase, wchar_t* szDumpFileName, ULONG_PTR EntryPoint)
{
HANDLE hProcess = 0;
BOOL ReturnValue = false;
hProcess = OpenProcess(PROCESS_VM_READ|PROCESS_QUERY_INFORMATION, FALSE, ProcessId);
if(hProcess != INVALID_HANDLE_VALUE)
{
ReturnValue = DumpProcessW(hProcess, ImageBase, szDumpFileName, EntryPoint);
EngineCloseHandle(hProcess);
if(ReturnValue)
{
return(true);
}
else
{
return(false);
}
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL DumpMemory(HANDLE hProcess, LPVOID MemoryStart, ULONG_PTR MemorySize, char* szDumpFileName)
{
wchar_t uniDumpFileName[MAX_PATH] = {};
if(szDumpFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szDumpFileName, lstrlenA(szDumpFileName)+1, uniDumpFileName, sizeof(uniDumpFileName)/(sizeof(uniDumpFileName[0])));
return(DumpMemoryW(hProcess, MemoryStart, MemorySize, uniDumpFileName));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL DumpMemoryW(HANDLE hProcess, LPVOID MemoryStart, ULONG_PTR MemorySize, wchar_t* szDumpFileName)
{
ULONG_PTR ueNumberOfBytesRead = 0;
DWORD uedNumberOfBytesRead = 0;
HANDLE hFile = 0;
LPVOID ReadBase = MemoryStart;
ULONG_PTR ProcReadBase = (ULONG_PTR)ReadBase;
LPVOID ueCopyBuffer = VirtualAlloc(NULL, 0x2000, MEM_COMMIT, PAGE_READWRITE);
MEMORY_BASIC_INFORMATION MemInfo;
if(EngineCreatePathForFileW(szDumpFileName))
{
hFile = CreateFileW(szDumpFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile != INVALID_HANDLE_VALUE)
{
while(MemorySize > NULL)
{
ReadBase = (LPVOID)ProcReadBase;
if(MemorySize >= 0x1000)
{
RtlZeroMemory(ueCopyBuffer,0x2000);
if(!ReadProcessMemory(hProcess, ReadBase, ueCopyBuffer, 0x1000, &ueNumberOfBytesRead))
{
VirtualQueryEx(hProcess, ReadBase, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
VirtualProtectEx(hProcess, ReadBase, 0x1000, PAGE_EXECUTE_READWRITE, &MemInfo.Protect);
ReadProcessMemory(hProcess, ReadBase, ueCopyBuffer, 0x1000, &ueNumberOfBytesRead);
VirtualProtectEx(hProcess, ReadBase, 0x1000, MemInfo.Protect, &MemInfo.Protect);
}
WriteFile(hFile,ueCopyBuffer, 0x1000, &uedNumberOfBytesRead, NULL);
MemorySize = MemorySize - 0x1000;
}
else
{
RtlZeroMemory(ueCopyBuffer,0x2000);
if(!ReadProcessMemory(hProcess, ReadBase, ueCopyBuffer, MemorySize, &ueNumberOfBytesRead))
{
VirtualQueryEx(hProcess, ReadBase, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
VirtualProtectEx(hProcess, ReadBase, 0x1000, PAGE_EXECUTE_READWRITE, &MemInfo.Protect);
ReadProcessMemory(hProcess, ReadBase, ueCopyBuffer, 0x1000, &ueNumberOfBytesRead);
VirtualProtectEx(hProcess, ReadBase, 0x1000, MemInfo.Protect, &MemInfo.Protect);
}
WriteFile(hFile, ueCopyBuffer, (DWORD)MemorySize, &uedNumberOfBytesRead, NULL);
MemorySize = NULL;
}
ProcReadBase = (ULONG_PTR)ReadBase + 0x1000;
}
EngineCloseHandle(hFile);
VirtualFree(ueCopyBuffer, NULL, MEM_RELEASE);
return(true);
}
else
{
VirtualFree(ueCopyBuffer, NULL, MEM_RELEASE);
return(false);
}
}
return(true);
}
__declspec(dllexport) bool TITCALL DumpMemoryEx(DWORD ProcessId, LPVOID MemoryStart, ULONG_PTR MemorySize, char* szDumpFileName)
{
wchar_t uniDumpFileName[MAX_PATH] = {};
if(szDumpFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szDumpFileName, lstrlenA(szDumpFileName)+1, uniDumpFileName, sizeof(uniDumpFileName)/(sizeof(uniDumpFileName[0])));
return(DumpMemoryExW(ProcessId, MemoryStart, MemorySize, uniDumpFileName));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL DumpMemoryExW(DWORD ProcessId, LPVOID MemoryStart, ULONG_PTR MemorySize, wchar_t* szDumpFileName)
{
HANDLE hProcess = 0;
BOOL ReturnValue = false;
hProcess = OpenProcess(PROCESS_VM_READ, FALSE, ProcessId);
if(hProcess != INVALID_HANDLE_VALUE)
{
ReturnValue = DumpMemoryW(hProcess, MemoryStart, MemorySize, szDumpFileName);
EngineCloseHandle(hProcess);
if(ReturnValue)
{
return(true);
}
}
return(false);
}
__declspec(dllexport) bool TITCALL DumpRegions(HANDLE hProcess, char* szDumpFolder, bool DumpAboveImageBaseOnly)
{
wchar_t uniDumpFolder[MAX_PATH] = {};
if(szDumpFolder != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szDumpFolder, lstrlenA(szDumpFolder)+1, uniDumpFolder, sizeof(uniDumpFolder)/(sizeof(uniDumpFolder[0])));
return(DumpRegionsW(hProcess, uniDumpFolder, DumpAboveImageBaseOnly));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL DumpRegionsW(HANDLE hProcess, wchar_t* szDumpFolder, bool DumpAboveImageBaseOnly)
{
int i;
DWORD Dummy = NULL;
wchar_t szDumpName[MAX_PATH];
wchar_t szDumpFileName[MAX_PATH];
MEMORY_BASIC_INFORMATION MemInfo;
ULONG_PTR DumpAddress = NULL;
ULONG_PTR EnumeratedModules[1024];
bool AddressIsModuleBase = false;
if(hProcess != NULL)
{
EnumProcessModules(hProcess, (HMODULE*)EnumeratedModules, sizeof(EnumeratedModules), &Dummy);
while(VirtualQueryEx(hProcess, (LPVOID)DumpAddress, &MemInfo, sizeof MEMORY_BASIC_INFORMATION) != NULL)
{
AddressIsModuleBase = false;
for(i = 0; i < 1024; i++)
{
if(EnumeratedModules[i] == (ULONG_PTR)MemInfo.AllocationBase)
{
AddressIsModuleBase = true;
i = 1024;
}
else if(EnumeratedModules[i] == 0)
{
i = 1024;
}
}
if(!(MemInfo.Protect & PAGE_NOACCESS) && AddressIsModuleBase == false)
{
if(DumpAboveImageBaseOnly == false || (DumpAboveImageBaseOnly == true && EnumeratedModules[0] < (ULONG_PTR)MemInfo.BaseAddress))
{
RtlZeroMemory(&szDumpName, MAX_PATH);
RtlZeroMemory(&szDumpFileName, MAX_PATH);
lstrcpyW(szDumpFileName, szDumpFolder);
if(szDumpFileName[lstrlenW(szDumpFileName)-1] != 0x5C)
{
szDumpFileName[lstrlenW(szDumpFileName)] = 0x5C;
}
wsprintfW(szDumpName, L"Dump-%x_%x.dmp", (ULONG_PTR)MemInfo.BaseAddress, (ULONG_PTR)MemInfo.RegionSize);
lstrcatW(szDumpFileName, szDumpName);
DumpMemoryW(hProcess, (LPVOID)MemInfo.BaseAddress, (ULONG_PTR)MemInfo.RegionSize, szDumpFileName);
}
}
DumpAddress = DumpAddress + (ULONG_PTR)MemInfo.RegionSize;
}
return(true);
}
return(false);
}
__declspec(dllexport) bool TITCALL DumpRegionsEx(DWORD ProcessId, char* szDumpFolder, bool DumpAboveImageBaseOnly)
{
wchar_t uniDumpFolder[MAX_PATH] = {};
if(szDumpFolder != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szDumpFolder, lstrlenA(szDumpFolder)+1, uniDumpFolder, sizeof(uniDumpFolder)/(sizeof(uniDumpFolder[0])));
return(DumpRegionsExW(ProcessId, uniDumpFolder, DumpAboveImageBaseOnly));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL DumpRegionsExW(DWORD ProcessId, wchar_t* szDumpFolder, bool DumpAboveImageBaseOnly)
{
HANDLE hProcess = 0;
BOOL ReturnValue = false;
hProcess = OpenProcess(PROCESS_VM_READ, FALSE, ProcessId);
if(hProcess != INVALID_HANDLE_VALUE)
{
ReturnValue = DumpRegionsW(hProcess, szDumpFolder, DumpAboveImageBaseOnly);
EngineCloseHandle(hProcess);
if(ReturnValue)
{
return(true);
}
}
return(false);
}
__declspec(dllexport) bool TITCALL DumpModule(HANDLE hProcess, LPVOID ModuleBase, char* szDumpFileName)
{
wchar_t uniDumpFileName[MAX_PATH] = {};
if(szDumpFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szDumpFileName, lstrlenA(szDumpFileName)+1, uniDumpFileName, sizeof(uniDumpFileName)/(sizeof(uniDumpFileName[0])));
return(DumpModuleW(hProcess, ModuleBase, uniDumpFileName));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL DumpModuleW(HANDLE hProcess, LPVOID ModuleBase, wchar_t* szDumpFileName)
{
int i;
DWORD Dummy = NULL;
MODULEINFO RemoteModuleInfo;
ULONG_PTR EnumeratedModules[1024];
if(EnumProcessModules(hProcess, (HMODULE*)EnumeratedModules, sizeof(EnumeratedModules), &Dummy))
{
for(i = 0; i < 512; i++)
{
if(EnumeratedModules[i] == (ULONG_PTR)ModuleBase)
{
GetModuleInformation(hProcess, (HMODULE)EnumeratedModules[i], &RemoteModuleInfo, sizeof MODULEINFO);
return(DumpMemoryW(hProcess, (LPVOID)EnumeratedModules[i], RemoteModuleInfo.SizeOfImage, szDumpFileName));
}
}
}
return(false);
}
__declspec(dllexport) bool TITCALL DumpModuleEx(DWORD ProcessId, LPVOID ModuleBase, char* szDumpFileName)
{
wchar_t uniDumpFileName[MAX_PATH] = {};
if(szDumpFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szDumpFileName, lstrlenA(szDumpFileName)+1, uniDumpFileName, sizeof(uniDumpFileName)/(sizeof(uniDumpFileName[0])));
return(DumpModuleExW(ProcessId, ModuleBase, uniDumpFileName));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL DumpModuleExW(DWORD ProcessId, LPVOID ModuleBase, wchar_t* szDumpFileName)
{
HANDLE hProcess = 0;
BOOL ReturnValue = false;
hProcess = OpenProcess(PROCESS_VM_READ, FALSE, ProcessId);
if(hProcess != INVALID_HANDLE_VALUE)
{
ReturnValue = DumpModuleW(hProcess, ModuleBase, szDumpFileName);
EngineCloseHandle(hProcess);
if(ReturnValue)
{
return(true);
}
}
return(false);
}
__declspec(dllexport) bool TITCALL PastePEHeader(HANDLE hProcess, LPVOID ImageBase, char* szDebuggedFileName)
{
wchar_t uniDebuggedFileName[MAX_PATH] = {};
if(szDebuggedFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szDebuggedFileName, lstrlenA(szDebuggedFileName)+1, uniDebuggedFileName, sizeof(uniDebuggedFileName)/(sizeof(uniDebuggedFileName[0])));
return(PastePEHeaderW(hProcess, ImageBase, uniDebuggedFileName));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL PastePEHeaderW(HANDLE hProcess, LPVOID ImageBase, wchar_t* szDebuggedFileName)
{
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
IMAGE_NT_HEADERS32 RemotePEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
IMAGE_NT_HEADERS64 RemotePEHeader64;
ULONG_PTR ueNumberOfBytesRead = 0;
DWORD uedNumberOfBytesRead = 0;
DWORD FileSize = 0;
DWORD PEHeaderSize = 0;
ULONG_PTR dwImageBase = (ULONG_PTR)ImageBase;
BOOL FileIs64 = false;
HANDLE hFile = 0;
SIZE_T CalculatedHeaderSize = NULL;
LPVOID ueReadBuffer = VirtualAlloc(NULL, 0x2000, MEM_COMMIT, PAGE_READWRITE);
DWORD OldProtect = PAGE_READWRITE;
hFile = CreateFileW(szDebuggedFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile != INVALID_HANDLE_VALUE)
{
FileSize = GetFileSize(hFile, NULL);
if(FileSize < 0x1000)
{
if(!ReadFile(hFile, ueReadBuffer, FileSize, &uedNumberOfBytesRead, NULL))
return false;
}
else
{
if(!ReadFile(hFile, ueReadBuffer, 0x1000, &uedNumberOfBytesRead, NULL))
return false;
}
if(FileSize > 0x200)
{
DOSHeader = (PIMAGE_DOS_HEADER)ueReadBuffer;
if(EngineValidateHeader((ULONG_PTR)ueReadBuffer, hProcess, ImageBase, DOSHeader, false))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
CalculatedHeaderSize = DOSHeader->e_lfanew + sizeof IMAGE_DOS_HEADER + sizeof IMAGE_NT_HEADERS64;
if(CalculatedHeaderSize > 0x1000)
{
SetFilePointer(hFile, NULL, NULL, FILE_BEGIN);
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
ueReadBuffer = VirtualAlloc(NULL, CalculatedHeaderSize, MEM_COMMIT, PAGE_READWRITE);
if(!ReadFile(hFile, ueReadBuffer, (DWORD)CalculatedHeaderSize, &uedNumberOfBytesRead, NULL))
{
EngineCloseHandle(hFile);
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
return(false);
}
}
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
if(ReadProcessMemory(hProcess, (LPVOID)((ULONG_PTR)ImageBase + DOSHeader->e_lfanew), &RemotePEHeader32, sizeof IMAGE_NT_HEADERS32, &ueNumberOfBytesRead))
{
PEHeaderSize = PEHeader32->FileHeader.NumberOfSections * IMAGE_SIZEOF_SECTION_HEADER + PEHeader32->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4;
FileIs64 = false;
}
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
if(ReadProcessMemory(hProcess, (LPVOID)((ULONG_PTR)ImageBase + DOSHeader->e_lfanew), &RemotePEHeader64, sizeof IMAGE_NT_HEADERS32, &ueNumberOfBytesRead))
{
PEHeaderSize = PEHeader64->FileHeader.NumberOfSections * IMAGE_SIZEOF_SECTION_HEADER + PEHeader64->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4;
FileIs64 = true;
}
}
else
{
EngineCloseHandle(hFile);
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
return(false);
}
if(!FileIs64)
{
PEHeader32->OptionalHeader.ImageBase = (DWORD)(dwImageBase);
if(VirtualProtectEx(hProcess, ImageBase, PEHeaderSize, PAGE_READWRITE, &OldProtect))
{
if(WriteProcessMemory(hProcess, ImageBase, ueReadBuffer, PEHeaderSize, &ueNumberOfBytesRead))
{
EngineCloseHandle(hFile);
VirtualProtectEx(hProcess, ImageBase, PEHeaderSize, OldProtect, &OldProtect);
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
return(true);
}
else
{
EngineCloseHandle(hFile);
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
return(false);
}
}
else
{
EngineCloseHandle(hFile);
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
return(false);
}
}
else
{
PEHeader64->OptionalHeader.ImageBase = dwImageBase;
if(VirtualProtectEx(hProcess, ImageBase, PEHeaderSize, PAGE_READWRITE, &OldProtect))
{
if(WriteProcessMemory(hProcess, ImageBase, ueReadBuffer, PEHeaderSize, &ueNumberOfBytesRead))
{
EngineCloseHandle(hFile);
VirtualProtectEx(hProcess, ImageBase, PEHeaderSize, OldProtect, &OldProtect);
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
return(true);
}
else
{
EngineCloseHandle(hFile);
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
return(false);
}
}
else
{
EngineCloseHandle(hFile);
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
return(false);
}
}
}
else
{
EngineCloseHandle(hFile);
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
return(false);
}
}
else
{
EngineCloseHandle(hFile);
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
return(false);
}
}
else
{
EngineCloseHandle(hFile);
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
return(false);
}
return(false);
}
__declspec(dllexport) bool TITCALL ExtractSection(char* szFileName, char* szDumpFileName, DWORD SectionNumber)
{
wchar_t uniFileName[MAX_PATH] = {};
wchar_t uniDumpFileName[MAX_PATH] = {};
if(szFileName != NULL && szDumpFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
MultiByteToWideChar(CP_ACP, NULL, szDumpFileName, lstrlenA(szDumpFileName)+1, uniDumpFileName, sizeof(uniDumpFileName)/(sizeof(uniDumpFileName[0])));
return(ExtractSectionW(uniFileName, uniDumpFileName, SectionNumber));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL ExtractSectionW(wchar_t* szFileName, wchar_t* szDumpFileName, DWORD SectionNumber)
{
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
PIMAGE_SECTION_HEADER PESections;
DWORD NumberOfBytesWritten;
BOOL FileIs64;
HANDLE FileHandle;
DWORD FileSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
HANDLE hFile;
if(MapFileExW(szFileName, UE_ACCESS_READ, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, FileHandle, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
if(!FileIs64)
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader32 + PEHeader32->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
if(SectionNumber <= PEHeader32->FileHeader.NumberOfSections)
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + SectionNumber * IMAGE_SIZEOF_SECTION_HEADER);
if(EngineCreatePathForFileW(szDumpFileName))
{
hFile = CreateFileW(szDumpFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile != INVALID_HANDLE_VALUE)
{
__try
{
WriteFile(hFile, (LPCVOID)(FileMapVA + PESections->PointerToRawData), PESections->SizeOfRawData, &NumberOfBytesWritten, NULL);
EngineCloseHandle(hFile);
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(true);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
EngineCloseHandle(hFile);
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
DeleteFileW(szDumpFileName);
return(false);
}
}
}
}
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
else
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader64 + PEHeader64->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
if(SectionNumber <= PEHeader64->FileHeader.NumberOfSections)
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + SectionNumber * IMAGE_SIZEOF_SECTION_HEADER);
if(EngineCreatePathForFileW(szDumpFileName))
{
hFile = CreateFileW(szDumpFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile != INVALID_HANDLE_VALUE)
{
__try
{
WriteFile(hFile, (LPCVOID)(FileMapVA + PESections->PointerToRawData), PESections->SizeOfRawData, &NumberOfBytesWritten, NULL);
EngineCloseHandle(hFile);
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(true);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
EngineCloseHandle(hFile);
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
DeleteFileW(szDumpFileName);
return(false);
}
}
}
}
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
return(false);
}
__declspec(dllexport) bool TITCALL ResortFileSections(char* szFileName)
{
wchar_t uniFileName[MAX_PATH] = {};
if(szFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
return(ResortFileSectionsW(uniFileName));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL ResortFileSectionsW(wchar_t* szFileName)
{
int i = 0;
int j = 0;
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
PIMAGE_SECTION_HEADER PESections;
DWORD SectionNumber = 0;
BOOL FileIs64;
HANDLE FileHandle;
DWORD FileSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
wchar_t szBackupFile[MAX_PATH] = {};
wchar_t szBackupItem[MAX_PATH] = {};
ULONG_PTR fileSectionData[MAXIMUM_SECTION_NUMBER][3];
ULONG_PTR fileSectionTemp;
LPVOID sortedFileName;
if(engineBackupForCriticalFunctions && CreateGarbageItem(&szBackupItem, sizeof szBackupItem))
{
if(!FillGarbageItem(szBackupItem, szFileName, &szBackupFile, sizeof szBackupItem))
{
RtlZeroMemory(&szBackupItem, sizeof szBackupItem);
lstrcpyW(szBackupFile, szFileName);
}
}
else
{
RtlZeroMemory(&szBackupItem, sizeof szBackupItem);
lstrcpyW(szBackupFile, szFileName);
}
if(MapFileExW(szBackupFile, UE_ACCESS_ALL, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, FileHandle, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
RemoveGarbageItem(szBackupItem, true);
return(false);
}
if(!FileIs64)
{
sortedFileName = VirtualAlloc(NULL, FileSize, MEM_COMMIT, PAGE_READWRITE);
__try
{
RtlMoveMemory(sortedFileName, (LPVOID)FileMapVA, FileSize);
SectionNumber = PEHeader32->FileHeader.NumberOfSections;
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader32 + PEHeader32->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
while(SectionNumber > 0)
{
fileSectionData[i][0] = (ULONG_PTR)(PESections->PointerToRawData);
fileSectionData[i][1] = PESections->SizeOfRawData;
fileSectionData[i][2] = PEHeader32->FileHeader.NumberOfSections - SectionNumber;
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + IMAGE_SIZEOF_SECTION_HEADER);
SectionNumber--;
i++;
}
for(j = 0; j < PEHeader32->FileHeader.NumberOfSections; j++)
{
for(i = 0; i < PEHeader32->FileHeader.NumberOfSections; i++)
{
if(fileSectionData[i][0] > fileSectionData[j][0])
{
fileSectionTemp = fileSectionData[j][0];
fileSectionData[j][0] = fileSectionData[i][0];
fileSectionData[i][0] = fileSectionTemp;
fileSectionTemp = fileSectionData[j][1];
fileSectionData[j][1] = fileSectionData[i][1];
fileSectionData[i][1] = fileSectionTemp;
}
}
}
for(i = 0; i < PEHeader32->FileHeader.NumberOfSections; i++)
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader32 - FileMapVA + (ULONG_PTR)sortedFileName + PEHeader32->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + fileSectionData[i][2] * IMAGE_SIZEOF_SECTION_HEADER);
RtlMoveMemory((LPVOID)((ULONG_PTR)sortedFileName + fileSectionData[i][0]), (LPVOID)((ULONG_PTR)FileMapVA + PESections->PointerToRawData), fileSectionData[i][1]);
PESections->PointerToRawData = (DWORD)fileSectionData[i][0];
PESections->SizeOfRawData = (DWORD)fileSectionData[i][1];
}
RtlMoveMemory((LPVOID)FileMapVA, sortedFileName, FileSize);
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
VirtualFree(sortedFileName, NULL, MEM_RELEASE);
if(szBackupItem[0] != NULL)
{
if(CopyFileW(szBackupFile, szFileName, false))
{
RemoveGarbageItem(szBackupItem, true);
return(true);
}
else
{
RemoveGarbageItem(szBackupItem, true);
return(false);
}
}
else
{
return(true);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
VirtualFree(sortedFileName, NULL, MEM_RELEASE);
RemoveGarbageItem(szBackupItem, true);
return(false);
}
}
else
{
sortedFileName = VirtualAlloc(NULL, FileSize, MEM_COMMIT, PAGE_READWRITE);
__try
{
RtlMoveMemory(sortedFileName, (LPVOID)FileMapVA, FileSize);
SectionNumber = PEHeader64->FileHeader.NumberOfSections;
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader64 + PEHeader64->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
while(SectionNumber > 0)
{
fileSectionData[i][0] = (ULONG_PTR)(PESections->PointerToRawData);
fileSectionData[i][1] = PESections->SizeOfRawData;
fileSectionData[i][2] = PEHeader64->FileHeader.NumberOfSections - SectionNumber;
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + IMAGE_SIZEOF_SECTION_HEADER);
SectionNumber--;
i++;
}
for(j = 0; j < PEHeader64->FileHeader.NumberOfSections; j++)
{
for(i = 0; i < PEHeader64->FileHeader.NumberOfSections; i++)
{
if(fileSectionData[i][0] > fileSectionData[j][0])
{
fileSectionTemp = fileSectionData[j][0];
fileSectionData[j][0] = fileSectionData[i][0];
fileSectionData[i][0] = fileSectionTemp;
fileSectionTemp = fileSectionData[j][1];
fileSectionData[j][1] = fileSectionData[i][1];
fileSectionData[i][1] = fileSectionTemp;
}
}
}
for(i = 0; i < PEHeader64->FileHeader.NumberOfSections; i++)
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader64 - FileMapVA + (ULONG_PTR)sortedFileName + PEHeader64->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + fileSectionData[i][2] * IMAGE_SIZEOF_SECTION_HEADER);
RtlMoveMemory((LPVOID)((ULONG_PTR)sortedFileName + fileSectionData[i][0]), (LPVOID)((ULONG_PTR)FileMapVA + PESections->PointerToRawData), fileSectionData[i][1]);
PESections->PointerToRawData = (DWORD)fileSectionData[i][0];
PESections->SizeOfRawData = (DWORD)fileSectionData[i][1];
}
RtlMoveMemory((LPVOID)FileMapVA, sortedFileName, FileSize);
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
VirtualFree(sortedFileName, NULL, MEM_RELEASE);
if(szBackupItem[0] != NULL)
{
if(CopyFileW(szBackupFile, szFileName, false))
{
RemoveGarbageItem(szBackupItem, true);
return(true);
}
else
{
RemoveGarbageItem(szBackupItem, true);
return(false);
}
}
else
{
return(true);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
VirtualFree(sortedFileName, NULL, MEM_RELEASE);
RemoveGarbageItem(szBackupItem, true);
return(false);
}
}
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
RemoveGarbageItem(szBackupItem, true);
return(false);
}
}
RemoveGarbageItem(szBackupItem, true);
return(false);
}
__declspec(dllexport) bool TITCALL FindOverlay(char* szFileName, LPDWORD OverlayStart, LPDWORD OverlaySize)
{
wchar_t uniFileName[MAX_PATH] = {};
if(szFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
return(FindOverlayW(uniFileName, OverlayStart, OverlaySize));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL FindOverlayW(wchar_t* szFileName, LPDWORD OverlayStart, LPDWORD OverlaySize)
{
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
PIMAGE_SECTION_HEADER PESections;
DWORD SectionNumber = 0;
DWORD SectionRawOffset = 0;
DWORD SectionRawSize = 0;
BOOL FileIs64;
HANDLE FileHandle;
DWORD FileSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
if(MapFileExW(szFileName, UE_ACCESS_READ, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, FileHandle, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
if(!FileIs64)
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader32 + PEHeader32->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
SectionNumber = PEHeader32->FileHeader.NumberOfSections;
__try
{
while(SectionNumber > 0)
{
if(PESections->PointerToRawData >= SectionRawOffset)
{
if(PESections->SizeOfRawData != NULL || (SectionRawOffset != PESections->PointerToRawData))
{
SectionRawSize = PESections->SizeOfRawData;
}
SectionRawOffset = PESections->PointerToRawData;
}
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + IMAGE_SIZEOF_SECTION_HEADER);
SectionNumber--;
}
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
if(SectionRawOffset + SectionRawSize < FileSize)
{
if(OverlayStart != NULL && OverlaySize != NULL)
{
*OverlayStart = (DWORD)(SectionRawOffset + SectionRawSize);
*OverlaySize = (DWORD)(FileSize - SectionRawOffset - SectionRawSize);
}
return(true);
}
else
{
return(false);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
else
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader64 + PEHeader64->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
SectionNumber = PEHeader64->FileHeader.NumberOfSections;
__try
{
while(SectionNumber > 0)
{
if(PESections->PointerToRawData >= SectionRawOffset)
{
if(PESections->SizeOfRawData != NULL || (SectionRawOffset != PESections->PointerToRawData))
{
SectionRawSize = PESections->SizeOfRawData;
}
SectionRawOffset = PESections->PointerToRawData;
}
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + IMAGE_SIZEOF_SECTION_HEADER);
SectionNumber--;
}
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
if(SectionRawOffset + SectionRawSize < FileSize)
{
if(OverlayStart != NULL && OverlaySize != NULL)
{
*OverlayStart = (DWORD)(SectionRawOffset + SectionRawSize);
*OverlaySize = (DWORD)(FileSize - SectionRawOffset - SectionRawSize);
}
return(true);
}
else
{
return(false);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
return(false);
}
__declspec(dllexport) bool TITCALL ExtractOverlay(char* szFileName, char* szExtactedFileName)
{
wchar_t uniFileName[MAX_PATH] = {};
wchar_t uniExtactedFileName[MAX_PATH] = {};
if(szFileName != NULL && szExtactedFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
MultiByteToWideChar(CP_ACP, NULL, szExtactedFileName, lstrlenA(szExtactedFileName)+1, uniExtactedFileName, sizeof(uniExtactedFileName)/(sizeof(uniExtactedFileName[0])));
return(ExtractOverlayW(uniFileName, uniExtactedFileName));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL ExtractOverlayW(wchar_t* szFileName, wchar_t* szExtactedFileName)
{
HANDLE hFile = 0;
HANDLE hFileWrite = 0;
BOOL Return = false;
DWORD OverlayStart = 0;
DWORD OverlaySize = 0;
DWORD ueNumberOfBytesRead = 0;
LPVOID ueReadBuffer = VirtualAlloc(NULL, 0x2000, MEM_COMMIT, PAGE_READWRITE);
Return = FindOverlayW(szFileName, &OverlayStart, &OverlaySize);
if(Return)
{
hFile = CreateFileW(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile != INVALID_HANDLE_VALUE)
{
if(EngineCreatePathForFileW(szExtactedFileName))
{
hFileWrite = CreateFileW(szExtactedFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFileWrite != INVALID_HANDLE_VALUE)
{
SetFilePointer(hFile, OverlayStart, NULL, FILE_BEGIN);
while(OverlaySize > 0)
{
if(OverlaySize > 0x1000)
{
RtlZeroMemory(ueReadBuffer, 0x2000);
if(!ReadFile(hFile, ueReadBuffer, 0x1000, &ueNumberOfBytesRead, NULL) || !WriteFile(hFileWrite, ueReadBuffer, 0x1000, &ueNumberOfBytesRead, NULL))
return false;
OverlaySize = OverlaySize - 0x1000;
}
else
{
RtlZeroMemory(ueReadBuffer, 0x2000);
if(!ReadFile(hFile, ueReadBuffer, OverlaySize, &ueNumberOfBytesRead, NULL) || !WriteFile(hFileWrite, ueReadBuffer, OverlaySize, &ueNumberOfBytesRead, NULL))
return false;
OverlaySize = 0;
}
}
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
EngineCloseHandle(hFile);
EngineCloseHandle(hFileWrite);
return(true);
}
else
{
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
EngineCloseHandle(hFile);
return(false);
}
}
}
}
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
return(false);
}
__declspec(dllexport) bool TITCALL AddOverlay(char* szFileName, char* szOverlayFileName)
{
wchar_t uniFileName[MAX_PATH] = {};
wchar_t uniOverlayFileName[MAX_PATH] = {};
if(szFileName != NULL && szOverlayFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
MultiByteToWideChar(CP_ACP, NULL, szOverlayFileName, lstrlenA(szOverlayFileName)+1, uniOverlayFileName, sizeof(uniOverlayFileName)/(sizeof(uniOverlayFileName[0])));
return(AddOverlayW(uniFileName, uniOverlayFileName));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL AddOverlayW(wchar_t* szFileName, wchar_t* szOverlayFileName)
{
HANDLE hFile = 0;
HANDLE hFileRead = 0;
DWORD FileSize = 0;
DWORD OverlaySize = 0;
ULONG_PTR ueNumberOfBytesRead = 0;
DWORD uedNumberOfBytesRead = 0;
LPVOID ueReadBuffer = VirtualAlloc(NULL, 0x2000, MEM_COMMIT, PAGE_READWRITE);
hFile = CreateFileW(szFileName, GENERIC_READ+GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile != INVALID_HANDLE_VALUE)
{
hFileRead = CreateFileW(szOverlayFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFileRead != INVALID_HANDLE_VALUE)
{
FileSize = GetFileSize(hFile, NULL);
OverlaySize = GetFileSize(hFileRead, NULL);
SetFilePointer(hFile, FileSize, NULL, FILE_BEGIN);
while(OverlaySize > 0)
{
if(OverlaySize > 0x1000)
{
RtlZeroMemory(ueReadBuffer, 0x2000);
if(!ReadFile(hFileRead, ueReadBuffer, 0x1000, &uedNumberOfBytesRead, NULL) || !WriteFile(hFile, ueReadBuffer, 0x1000, &uedNumberOfBytesRead, NULL))
return false;
OverlaySize = OverlaySize - 0x1000;
}
else
{
RtlZeroMemory(ueReadBuffer, 0x2000);
if(!ReadFile(hFileRead, ueReadBuffer, OverlaySize, &uedNumberOfBytesRead, NULL) || !WriteFile(hFile, ueReadBuffer, OverlaySize, &uedNumberOfBytesRead, NULL))
return false;
OverlaySize = 0;
}
}
EngineCloseHandle(hFile);
EngineCloseHandle(hFileRead);
return(true);
}
else
{
EngineCloseHandle(hFile);
return(false);
}
}
return(false);
}
__declspec(dllexport) bool TITCALL CopyOverlay(char* szInFileName, char* szOutFileName)
{
wchar_t uniInFileName[MAX_PATH] = {};
wchar_t uniOutFileName[MAX_PATH] = {};
if(szInFileName != NULL && szOutFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szInFileName, lstrlenA(szInFileName)+1, uniInFileName, sizeof(uniInFileName)/(sizeof(uniInFileName[0])));
MultiByteToWideChar(CP_ACP, NULL, szOutFileName, lstrlenA(szOutFileName)+1, uniOutFileName, sizeof(uniOutFileName)/(sizeof(uniOutFileName[0])));
return(CopyOverlayW(uniInFileName, uniOutFileName));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL CopyOverlayW(wchar_t* szInFileName, wchar_t* szOutFileName)
{
wchar_t szTempName[MAX_PATH] = {};
wchar_t szTempFolder[MAX_PATH] = {};
if(GetTempPathW(MAX_PATH, szTempFolder) < MAX_PATH)
{
if(GetTempFileNameW(szTempFolder, L"OverlayTemp", GetTickCount() + 101, szTempName))
{
if(ExtractOverlayW(szInFileName, szTempName))
{
AddOverlayW(szOutFileName, szTempName);
DeleteFileW(szTempName);
return(true);
}
}
}
return(false);
}
__declspec(dllexport) bool TITCALL RemoveOverlay(char* szFileName)
{
wchar_t uniFileName[MAX_PATH] = {};
if(szFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
return(RemoveOverlayW(uniFileName));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL RemoveOverlayW(wchar_t* szFileName)
{
HANDLE FileHandle;
DWORD FileSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
DWORD OverlayStart = 0;
DWORD OverlaySize = 0;
if(FindOverlayW(szFileName, &OverlayStart, &OverlaySize))
{
if(MapFileExW(szFileName, UE_ACCESS_ALL, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
FileSize = FileSize - OverlaySize;
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(true);
}
}
return(false);
}
__declspec(dllexport) bool TITCALL MakeAllSectionsRWE(char* szFileName)
{
wchar_t uniFileName[MAX_PATH] = {};
if(szFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
return(MakeAllSectionsRWEW(uniFileName));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL MakeAllSectionsRWEW(wchar_t* szFileName)
{
wchar_t szBackupFile[MAX_PATH] = {};
wchar_t szBackupItem[MAX_PATH] = {};
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
PIMAGE_SECTION_HEADER PESections;
DWORD SectionNumber = 0;
BOOL FileIs64;
HANDLE FileHandle;
DWORD FileSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
if(engineBackupForCriticalFunctions && CreateGarbageItem(&szBackupItem, sizeof szBackupItem))
{
if(!FillGarbageItem(szBackupItem, szFileName, &szBackupFile, sizeof szBackupItem))
{
RtlZeroMemory(&szBackupItem, sizeof szBackupItem);
lstrcpyW(szBackupFile, szFileName);
}
}
else
{
RtlZeroMemory(&szBackupItem, sizeof szBackupItem);
lstrcpyW(szBackupFile, szFileName);
}
if(MapFileExW(szBackupFile, UE_ACCESS_ALL, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, FileHandle, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
RemoveGarbageItem(szBackupItem, true);
return(false);
}
if(!FileIs64)
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader32 + PEHeader32->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
SectionNumber = PEHeader32->FileHeader.NumberOfSections;
__try
{
while(SectionNumber > 0)
{
PESections->Characteristics = 0xE0000020;
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + IMAGE_SIZEOF_SECTION_HEADER);
SectionNumber--;
}
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
if(szBackupItem[0] != NULL)
{
if(CopyFileW(szBackupFile, szFileName, false))
{
RemoveGarbageItem(szBackupItem, true);
return(true);
}
else
{
RemoveGarbageItem(szBackupItem, true);
return(false);
}
}
else
{
return(true);
}
return(true);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
RemoveGarbageItem(szBackupItem, true);
return(false);
}
}
else
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader64 + PEHeader64->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
SectionNumber = PEHeader64->FileHeader.NumberOfSections;
__try
{
while(SectionNumber > 0)
{
PESections->Characteristics = 0xE0000020;
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + IMAGE_SIZEOF_SECTION_HEADER);
SectionNumber--;
}
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
if(szBackupItem[0] != NULL)
{
if(CopyFileW(szBackupFile, szFileName, false))
{
RemoveGarbageItem(szBackupItem, true);
return(true);
}
else
{
RemoveGarbageItem(szBackupItem, true);
return(false);
}
}
else
{
return(true);
}
return(true);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
RemoveGarbageItem(szBackupItem, true);
return(false);
}
}
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
RemoveGarbageItem(szBackupItem, true);
return(false);
}
}
RemoveGarbageItem(szBackupItem, true);
return(false);
}
__declspec(dllexport) long TITCALL AddNewSectionEx(char* szFileName, char* szSectionName, DWORD SectionSize, DWORD SectionAttributes, LPVOID SectionContent, DWORD ContentSize)
{
wchar_t uniFileName[MAX_PATH] = {};
if(szFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
return(AddNewSectionExW(uniFileName, szSectionName, SectionSize, SectionAttributes, SectionContent, ContentSize));
}
else
{
return(NULL);
}
}
__declspec(dllexport) long TITCALL AddNewSectionExW(wchar_t* szFileName, char* szSectionName, DWORD SectionSize, DWORD SectionAttributes, LPVOID SectionContent, DWORD ContentSize)
{
bool OverlayHasBeenRemoved = false;
wchar_t szBackupOverlayFile[MAX_PATH] = {};
wchar_t szBackupFile[MAX_PATH] = {};
wchar_t szBackupItem[MAX_PATH] = {};
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
PIMAGE_SECTION_HEADER PESections;
DWORD SectionNameLength = 0;
DWORD NewSectionVirtualOffset = 0;
DWORD FileResizeValue = 0;
DWORD LastSectionRawSize = 0;
DWORD alignedSectionSize = 0;
DWORD NtSizeOfImage = 0;
DWORD SectionNumber = 0;
DWORD SpaceLeft = 0;
LPVOID NameOffset;
BOOL FileIs64;
HANDLE FileHandle;
DWORD FileSize;
DWORD OldFileSize = 0;
HANDLE FileMap;
ULONG_PTR FileMapVA;
if(ContentSize < SectionSize && ContentSize != 0)
{
ContentSize = SectionSize;
}
else if(ContentSize > SectionSize)
{
SectionSize = ContentSize;
}
if(engineBackupForCriticalFunctions && CreateGarbageItem(&szBackupItem, sizeof szBackupItem))
{
if(!FillGarbageItem(szBackupItem, szFileName, &szBackupFile, sizeof szBackupItem))
{
RtlZeroMemory(&szBackupItem, sizeof szBackupItem);
lstrcpyW(szBackupFile, szFileName);
}
if(FindOverlayW(szBackupFile, NULL, NULL))
{
if(!FillGarbageItem(szBackupItem, NULL, &szBackupOverlayFile, sizeof szBackupItem))
{
RtlZeroMemory(&szBackupOverlayFile, sizeof szBackupOverlayFile);
}
else
{
if(ExtractOverlayW(szBackupFile, szBackupOverlayFile) && RemoveOverlayW(szBackupFile))
{
OverlayHasBeenRemoved = true;
}
}
}
}
else
{
RtlZeroMemory(&szBackupItem, sizeof szBackupItem);
lstrcpyW(szBackupFile, szFileName);
}
if(MapFileExW(szBackupFile, UE_ACCESS_READ, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
OldFileSize = FileSize;
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, FileHandle, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
RemoveGarbageItem(szBackupItem, true);
return(0);
}
if(!FileIs64)
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader32 + PEHeader32->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
SectionNumber = PEHeader32->FileHeader.NumberOfSections;
__try
{
alignedSectionSize = ((DWORD)SectionSize / PEHeader32->OptionalHeader.FileAlignment) * PEHeader32->OptionalHeader.FileAlignment;
if(alignedSectionSize < SectionSize)
{
SectionSize = alignedSectionSize + PEHeader32->OptionalHeader.FileAlignment;
}
else
{
SectionSize = alignedSectionSize;
}
SpaceLeft = PESections->PointerToRawData - (SectionNumber * IMAGE_SIZEOF_SECTION_HEADER) - DOSHeader->e_lfanew - sizeof IMAGE_NT_HEADERS32;
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + (SectionNumber - 1) * IMAGE_SIZEOF_SECTION_HEADER);
LastSectionRawSize = (PESections->SizeOfRawData / PEHeader32->OptionalHeader.FileAlignment) * PEHeader32->OptionalHeader.FileAlignment;
if(LastSectionRawSize < PESections->SizeOfRawData)
{
LastSectionRawSize = LastSectionRawSize + PEHeader32->OptionalHeader.FileAlignment;
}
LastSectionRawSize = LastSectionRawSize - PESections->SizeOfRawData;
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
FileResizeValue = LastSectionRawSize + SectionSize;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
RemoveGarbageItem(szBackupItem, true);
return(0);
}
}
else
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader64 + PEHeader64->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
SectionNumber = PEHeader64->FileHeader.NumberOfSections;
__try
{
alignedSectionSize = ((DWORD)SectionSize / PEHeader64->OptionalHeader.FileAlignment) * PEHeader64->OptionalHeader.FileAlignment;
if(alignedSectionSize < SectionSize)
{
SectionSize = alignedSectionSize + PEHeader64->OptionalHeader.FileAlignment;
}
else
{
SectionSize = alignedSectionSize;
}
SpaceLeft = PESections->PointerToRawData - (SectionNumber * IMAGE_SIZEOF_SECTION_HEADER) - DOSHeader->e_lfanew - sizeof IMAGE_NT_HEADERS64;
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + (SectionNumber - 1) * IMAGE_SIZEOF_SECTION_HEADER);
LastSectionRawSize = (PESections->SizeOfRawData / PEHeader64->OptionalHeader.FileAlignment) * PEHeader64->OptionalHeader.FileAlignment;
if(LastSectionRawSize < PESections->SizeOfRawData)
{
LastSectionRawSize = LastSectionRawSize + PEHeader64->OptionalHeader.FileAlignment;
}
LastSectionRawSize = LastSectionRawSize - PESections->SizeOfRawData;
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
FileResizeValue = LastSectionRawSize + SectionSize;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
RemoveGarbageItem(szBackupItem, true);
return(0);
}
}
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
RemoveGarbageItem(szBackupItem, true);
return(0);
}
}
if(SpaceLeft > IMAGE_SIZEOF_SECTION_HEADER)
{
if(MapFileExW(szBackupFile, UE_ACCESS_ALL, &FileHandle, &FileSize, &FileMap, &FileMapVA, FileResizeValue))
{
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, FileHandle, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
RemoveGarbageItem(szBackupItem, true);
return(0);
}
if(!FileIs64)
{
__try
{
if(SectionSize == 0)
{
SectionSize = PEHeader32->OptionalHeader.FileAlignment;
}
alignedSectionSize = ((DWORD)SectionSize / PEHeader32->OptionalHeader.SectionAlignment) * PEHeader32->OptionalHeader.SectionAlignment;
if(alignedSectionSize < SectionSize)
{
alignedSectionSize = alignedSectionSize + PEHeader32->OptionalHeader.SectionAlignment;
}
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader32 + PEHeader32->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
SectionNumber = PEHeader32->FileHeader.NumberOfSections;
PEHeader32->FileHeader.NumberOfSections = PEHeader32->FileHeader.NumberOfSections + 1;
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + (SectionNumber - 1)* IMAGE_SIZEOF_SECTION_HEADER);
NewSectionVirtualOffset = PESections->VirtualAddress + (PESections->Misc.VirtualSize / PEHeader32->OptionalHeader.SectionAlignment) * PEHeader32->OptionalHeader.SectionAlignment;
if(NewSectionVirtualOffset < PESections->VirtualAddress + PESections->Misc.VirtualSize)
{
NewSectionVirtualOffset = NewSectionVirtualOffset + PEHeader32->OptionalHeader.SectionAlignment;
}
PESections->SizeOfRawData = PESections->SizeOfRawData + LastSectionRawSize;
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + IMAGE_SIZEOF_SECTION_HEADER);
PEHeader32->OptionalHeader.SizeOfImage = NewSectionVirtualOffset + alignedSectionSize;
NameOffset = &PESections->Name;
if(lstrlenA(szSectionName) >= 8)
{
SectionNameLength = 8;
}
else
{
SectionNameLength = lstrlenA(szSectionName);
}
RtlMoveMemory(NameOffset, szSectionName, SectionNameLength);
if(SectionAttributes == 0)
{
PESections->Characteristics = 0xE0000020;
}
else
{
PESections->Characteristics = (DWORD)(SectionAttributes);
}
PESections->Misc.VirtualSize = alignedSectionSize;
PESections->SizeOfRawData = (DWORD)(SectionSize);
PESections->VirtualAddress = NewSectionVirtualOffset;
PESections->PointerToRawData = OldFileSize + LastSectionRawSize;
if(SectionContent != NULL)
{
RtlMoveMemory((LPVOID)(FileMapVA + OldFileSize), SectionContent, ContentSize);
}
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
if(szBackupItem[0] != NULL)
{
if(CopyFileW(szBackupFile, szFileName, false))
{
if(OverlayHasBeenRemoved && !AddOverlayW(szFileName, szBackupOverlayFile))
{
RemoveGarbageItem(szBackupItem, true);
return(0);
}
RemoveGarbageItem(szBackupItem, true);
return(NewSectionVirtualOffset);
}
else
{
RemoveGarbageItem(szBackupItem, true);
return(0);
}
}
else
{
return(NewSectionVirtualOffset);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
RemoveGarbageItem(szBackupItem, true);
return(0);
}
}
else
{
__try
{
if(SectionSize == 0)
{
SectionSize = PEHeader64->OptionalHeader.FileAlignment;
}
alignedSectionSize = ((DWORD)SectionSize / PEHeader64->OptionalHeader.SectionAlignment) * PEHeader64->OptionalHeader.SectionAlignment;
if(alignedSectionSize < SectionSize)
{
alignedSectionSize = alignedSectionSize + PEHeader64->OptionalHeader.SectionAlignment;
}
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader64 + PEHeader64->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
SectionNumber = PEHeader64->FileHeader.NumberOfSections;
PEHeader32->FileHeader.NumberOfSections = PEHeader32->FileHeader.NumberOfSections + 1;
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + (SectionNumber - 1)* IMAGE_SIZEOF_SECTION_HEADER);
NewSectionVirtualOffset = PESections->VirtualAddress + (PESections->Misc.VirtualSize / PEHeader64->OptionalHeader.SectionAlignment) * PEHeader64->OptionalHeader.SectionAlignment;
if(NewSectionVirtualOffset < PESections->VirtualAddress + PESections->Misc.VirtualSize)
{
NewSectionVirtualOffset = NewSectionVirtualOffset + PEHeader64->OptionalHeader.SectionAlignment;
}
PESections->SizeOfRawData = PESections->SizeOfRawData + LastSectionRawSize;
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + IMAGE_SIZEOF_SECTION_HEADER);
PEHeader64->OptionalHeader.SizeOfImage = NewSectionVirtualOffset + alignedSectionSize;
NameOffset = &PESections->Name;
if(lstrlenA(szSectionName) >= 8)
{
SectionNameLength = 8;
}
else
{
SectionNameLength = lstrlenA(szSectionName);
}
RtlMoveMemory(NameOffset, szSectionName, SectionNameLength);
if(SectionAttributes == 0)
{
PESections->Characteristics = 0xE0000020;
}
else
{
PESections->Characteristics = (DWORD)(SectionAttributes);
}
PESections->Misc.VirtualSize = alignedSectionSize;
PESections->SizeOfRawData = (DWORD)(SectionSize);
PESections->VirtualAddress = NewSectionVirtualOffset;
PESections->PointerToRawData = OldFileSize + LastSectionRawSize;
if(SectionContent != NULL)
{
RtlMoveMemory((LPVOID)(FileMapVA + OldFileSize), SectionContent, ContentSize);
}
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
if(szBackupItem[0] != NULL)
{
if(CopyFileW(szBackupFile, szFileName, false))
{
if(OverlayHasBeenRemoved && !AddOverlayW(szFileName, szBackupOverlayFile))
{
RemoveGarbageItem(szBackupItem, true);
return(0);
}
RemoveGarbageItem(szBackupItem, true);
return(NewSectionVirtualOffset);
}
else
{
RemoveGarbageItem(szBackupItem, true);
return(0);
}
}
else
{
return(NewSectionVirtualOffset);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
RemoveGarbageItem(szBackupItem, true);
return(0);
}
}
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
RemoveGarbageItem(szBackupItem, true);
return(0);
}
}
}
RemoveGarbageItem(szBackupItem, true);
return(0);
}
__declspec(dllexport) long TITCALL AddNewSection(char* szFileName, char* szSectionName, DWORD SectionSize)
{
return(AddNewSectionEx(szFileName, szSectionName, SectionSize, NULL, NULL, NULL));
}
__declspec(dllexport) long TITCALL AddNewSectionW(wchar_t* szFileName, char* szSectionName, DWORD SectionSize)
{
return(AddNewSectionExW(szFileName, szSectionName, SectionSize, NULL, NULL, NULL));
}
__declspec(dllexport) bool TITCALL ResizeLastSection(char* szFileName, DWORD NumberOfExpandBytes, bool AlignResizeData)
{
wchar_t uniFileName[MAX_PATH] = {};
if(szFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
return(ResizeLastSectionW(uniFileName, NumberOfExpandBytes, AlignResizeData));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL ResizeLastSectionW(wchar_t* szFileName, DWORD NumberOfExpandBytes, bool AlignResizeData)
{
wchar_t szBackupFile[MAX_PATH] = {};
wchar_t szBackupItem[MAX_PATH] = {};
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
PIMAGE_SECTION_HEADER PESections;
DWORD SectionNumber = 0;
DWORD SectionRawSize = 0;
BOOL FileIs64;
HANDLE FileHandle;
DWORD FileSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
if(engineBackupForCriticalFunctions && CreateGarbageItem(&szBackupItem, sizeof szBackupItem))
{
if(!FillGarbageItem(szBackupItem, szFileName, &szBackupFile, sizeof szBackupItem))
{
RtlZeroMemory(&szBackupItem, sizeof szBackupItem);
lstrcpyW(szBackupFile, szFileName);
}
}
else
{
RtlZeroMemory(&szBackupItem, sizeof szBackupItem);
lstrcpyW(szBackupFile, szFileName);
}
if(MapFileExW(szBackupFile, UE_ACCESS_ALL, &FileHandle, &FileSize, &FileMap, &FileMapVA, NumberOfExpandBytes))
{
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, FileHandle, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
FileSize = FileSize - NumberOfExpandBytes;
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
RemoveGarbageItem(szBackupItem, true);
return(false);
}
if(!FileIs64)
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader32 + PEHeader32->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
SectionNumber = PEHeader32->FileHeader.NumberOfSections;
SectionNumber--;
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + SectionNumber * IMAGE_SIZEOF_SECTION_HEADER);
__try
{
if(AlignResizeData)
{
SectionRawSize = PESections->SizeOfRawData;
if((PESections->SizeOfRawData + NumberOfExpandBytes) % PEHeader32->OptionalHeader.FileAlignment == NULL)
{
PESections->SizeOfRawData = (((PESections->SizeOfRawData + NumberOfExpandBytes) / PEHeader32->OptionalHeader.FileAlignment)) * PEHeader32->OptionalHeader.FileAlignment;
}
else
{
PESections->SizeOfRawData = (((PESections->SizeOfRawData + NumberOfExpandBytes) / PEHeader32->OptionalHeader.FileAlignment) + 1) * PEHeader32->OptionalHeader.FileAlignment;
}
if(SectionRawSize > 0x7FFFFFFF)
{
SectionRawSize = NULL;
}
SectionRawSize = PESections->SizeOfRawData - SectionRawSize - NumberOfExpandBytes;
PEHeader32->OptionalHeader.SizeOfImage = PEHeader32->OptionalHeader.SizeOfImage - PESections->Misc.VirtualSize;
if((PESections->Misc.VirtualSize + NumberOfExpandBytes + SectionRawSize) % PEHeader32->OptionalHeader.SectionAlignment == NULL)
{
PESections->Misc.VirtualSize = (((PESections->Misc.VirtualSize + NumberOfExpandBytes + SectionRawSize) / PEHeader32->OptionalHeader.SectionAlignment)) * PEHeader32->OptionalHeader.SectionAlignment;
}
else
{
PESections->Misc.VirtualSize = (((PESections->Misc.VirtualSize + NumberOfExpandBytes + SectionRawSize) / PEHeader32->OptionalHeader.SectionAlignment) + 1) * PEHeader32->OptionalHeader.SectionAlignment;
}
PEHeader32->OptionalHeader.SizeOfImage = PEHeader32->OptionalHeader.SizeOfImage + PESections->Misc.VirtualSize;
if(SectionRawSize > NULL)
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
MapFileExW(szFileName, UE_ACCESS_ALL, &FileHandle, &FileSize, &FileMap, &FileMapVA, SectionRawSize);
}
}
else
{
PESections->SizeOfRawData = PESections->SizeOfRawData + NumberOfExpandBytes;
}
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
if(szBackupItem[0] != NULL)
{
RemoveGarbageItem(szBackupItem, true);
if(CopyFileW(szBackupFile, szFileName, false))
{
return(true);
}
else
{
return(false);
}
}
else
{
return(true);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
RemoveGarbageItem(szBackupItem, true);
return(false);
}
}
else
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader64 + PEHeader64->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
SectionNumber = PEHeader64->FileHeader.NumberOfSections;
SectionNumber--;
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + SectionNumber * IMAGE_SIZEOF_SECTION_HEADER);
__try
{
if(AlignResizeData)
{
SectionRawSize = PESections->SizeOfRawData;
if((PESections->SizeOfRawData + NumberOfExpandBytes) % PEHeader64->OptionalHeader.FileAlignment == NULL)
{
PESections->SizeOfRawData = (((PESections->SizeOfRawData + NumberOfExpandBytes) / PEHeader64->OptionalHeader.FileAlignment)) * PEHeader64->OptionalHeader.FileAlignment;
}
else
{
PESections->SizeOfRawData = (((PESections->SizeOfRawData + NumberOfExpandBytes) / PEHeader64->OptionalHeader.FileAlignment) + 1) * PEHeader64->OptionalHeader.FileAlignment;
}
if(SectionRawSize > 0x7FFFFFFF)
{
SectionRawSize = NULL;
}
SectionRawSize = PESections->SizeOfRawData - SectionRawSize - NumberOfExpandBytes;
PEHeader64->OptionalHeader.SizeOfImage = PEHeader64->OptionalHeader.SizeOfImage - PESections->Misc.VirtualSize;
if((PESections->Misc.VirtualSize + NumberOfExpandBytes) % PEHeader64->OptionalHeader.SectionAlignment == NULL)
{
PESections->Misc.VirtualSize = (((PESections->Misc.VirtualSize + NumberOfExpandBytes + SectionRawSize) / PEHeader32->OptionalHeader.SectionAlignment)) * PEHeader64->OptionalHeader.SectionAlignment;
}
else
{
PESections->Misc.VirtualSize = (((PESections->Misc.VirtualSize + NumberOfExpandBytes + SectionRawSize) / PEHeader32->OptionalHeader.SectionAlignment) + 1) * PEHeader64->OptionalHeader.SectionAlignment;
}
PEHeader64->OptionalHeader.SizeOfImage = PEHeader64->OptionalHeader.SizeOfImage + PESections->Misc.VirtualSize;
if(SectionRawSize > NULL)
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
MapFileExW(szFileName, UE_ACCESS_ALL, &FileHandle, &FileSize, &FileMap, &FileMapVA, SectionRawSize);
}
}
else
{
PESections->SizeOfRawData = PESections->SizeOfRawData + NumberOfExpandBytes;
}
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
if(szBackupItem[0] != NULL)
{
if(CopyFileW(szBackupFile, szFileName, false))
{
RemoveGarbageItem(szBackupItem, true);
return(true);
}
else
{
RemoveGarbageItem(szBackupItem, true);
return(false);
}
}
else
{
return(true);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
RemoveGarbageItem(szBackupItem, true);
return(false);
}
}
}
else
{
FileSize = FileSize - NumberOfExpandBytes;
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
RemoveGarbageItem(szBackupItem, true);
return(false);
}
}
RemoveGarbageItem(szBackupItem, true);
return(false);
}
__declspec(dllexport) void TITCALL SetSharedOverlay(char* szFileName)
{
szSharedOverlay = szFileName;
}
__declspec(dllexport) void TITCALL SetSharedOverlayW(wchar_t* szFileName)
{
szSharedOverlayW = szFileName;
}
__declspec(dllexport) char* TITCALL GetSharedOverlay()
{
return(szSharedOverlay);
}
__declspec(dllexport) wchar_t* TITCALL GetSharedOverlayW()
{
return(szSharedOverlayW);
}
__declspec(dllexport) bool TITCALL DeleteLastSection(char* szFileName)
{
wchar_t uniFileName[MAX_PATH] = {};
if(szFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
return(DeleteLastSectionW(uniFileName));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL DeleteLastSectionW(wchar_t* szFileName)
{
wchar_t szBackupFile[MAX_PATH] = {};
wchar_t szBackupItem[MAX_PATH] = {};
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
PIMAGE_SECTION_HEADER PESections;
DWORD SectionNumber = 0;
BOOL FileIs64;
HANDLE FileHandle;
DWORD FileSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
if(engineBackupForCriticalFunctions && CreateGarbageItem(&szBackupItem, sizeof szBackupItem))
{
if(!FillGarbageItem(szBackupItem, szFileName, &szBackupFile, sizeof szBackupItem))
{
RtlZeroMemory(&szBackupItem, sizeof szBackupItem);
lstrcpyW(szBackupFile, szFileName);
}
}
else
{
RtlZeroMemory(&szBackupItem, sizeof szBackupItem);
lstrcpyW(szBackupFile, szFileName);
}
if(MapFileExW(szBackupFile, UE_ACCESS_ALL, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, FileHandle, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
RemoveGarbageItem(szBackupItem, true);
return(false);
}
if(!FileIs64)
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader32 + PEHeader32->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
SectionNumber = PEHeader32->FileHeader.NumberOfSections;
__try
{
if(SectionNumber > 1)
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + (SectionNumber - 1) * IMAGE_SIZEOF_SECTION_HEADER);
PEHeader32->OptionalHeader.SizeOfImage = PEHeader32->OptionalHeader.SizeOfImage - PESections->Misc.VirtualSize;
FileSize = PESections->PointerToRawData;
RtlZeroMemory(PESections, IMAGE_SIZEOF_SECTION_HEADER);
PEHeader32->FileHeader.NumberOfSections--;
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
if(szBackupItem[0] != NULL)
{
if(CopyFileW(szBackupFile, szFileName, false))
{
RemoveGarbageItem(szBackupItem, true);
return(true);
}
else
{
RemoveGarbageItem(szBackupItem, true);
return(false);
}
}
else
{
return(true);
}
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
RemoveGarbageItem(szBackupItem, true);
return(false);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
RemoveGarbageItem(szBackupItem, true);
return(false);
}
}
else
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader64 + PEHeader64->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
SectionNumber = PEHeader64->FileHeader.NumberOfSections;
__try
{
if(SectionNumber > 1)
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + (SectionNumber - 1) * IMAGE_SIZEOF_SECTION_HEADER);
PEHeader64->OptionalHeader.SizeOfImage = PEHeader64->OptionalHeader.SizeOfImage - PESections->Misc.VirtualSize;
FileSize = PESections->PointerToRawData;
RtlZeroMemory(PESections, IMAGE_SIZEOF_SECTION_HEADER);
PEHeader64->FileHeader.NumberOfSections--;
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
if(szBackupItem[0] != NULL)
{
if(CopyFileW(szBackupFile, szFileName, false))
{
RemoveGarbageItem(szBackupItem, true);
return(true);
}
else
{
RemoveGarbageItem(szBackupItem, true);
return(false);
}
}
else
{
return(true);
}
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
RemoveGarbageItem(szBackupItem, true);
return(false);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
RemoveGarbageItem(szBackupItem, true);
return(false);
}
}
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
RemoveGarbageItem(szBackupItem, true);
return(false);
}
}
RemoveGarbageItem(szBackupItem, true);
return(false);
}
__declspec(dllexport) bool TITCALL DeleteLastSectionEx(char* szFileName, DWORD NumberOfSections)
{
while(NumberOfSections > 0)
{
DeleteLastSection(szFileName);
NumberOfSections--;
}
return(true);
}
__declspec(dllexport) bool TITCALL DeleteLastSectionExW(wchar_t* szFileName, DWORD NumberOfSections)
{
while(NumberOfSections > 0)
{
DeleteLastSectionW(szFileName);
NumberOfSections--;
}
return(true);
}
__declspec(dllexport) long long TITCALL GetPE32DataFromMappedFile(ULONG_PTR FileMapVA, DWORD WhichSection, DWORD WhichData)
{
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
PIMAGE_SECTION_HEADER PESections;
DWORD SectionNumber = 0;
BOOL FileIs64;
static char sectionName[9] = "";
if(FileMapVA != NULL)
{
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, NULL, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
return(0);
}
if(!FileIs64)
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader32 + PEHeader32->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
SectionNumber = PEHeader32->FileHeader.NumberOfSections;
if(WhichData < UE_SECTIONNAME)
{
if(WhichData == UE_PE_OFFSET)
{
return(DOSHeader->e_lfanew);
}
else if(WhichData == UE_IMAGEBASE)
{
return(PEHeader32->OptionalHeader.ImageBase);
}
else if(WhichData == UE_OEP)
{
return(PEHeader32->OptionalHeader.AddressOfEntryPoint);
}
else if(WhichData == UE_BASEOFCODE)
{
return(PEHeader32->OptionalHeader.BaseOfCode);
}
else if(WhichData == UE_BASEOFDATA)
{
return(PEHeader32->OptionalHeader.BaseOfData);
}
else if(WhichData == UE_SIZEOFIMAGE)
{
return(PEHeader32->OptionalHeader.SizeOfImage);
}
else if(WhichData == UE_SIZEOFHEADERS)
{
return(PEHeader32->OptionalHeader.SizeOfHeaders);
}
else if(WhichData == UE_SIZEOFOPTIONALHEADER)
{
return(PEHeader32->FileHeader.SizeOfOptionalHeader);
}
else if(WhichData == UE_SECTIONALIGNMENT)
{
return(PEHeader32->OptionalHeader.SectionAlignment);
}
else if(WhichData == UE_IMPORTTABLEADDRESS)
{
return(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
}
else if(WhichData == UE_IMPORTTABLESIZE)
{
return(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size);
}
else if(WhichData == UE_RESOURCETABLEADDRESS)
{
return(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress);
}
else if(WhichData == UE_RESOURCETABLESIZE)
{
return(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size);
}
else if(WhichData == UE_EXPORTTABLEADDRESS)
{
return(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
}
else if(WhichData == UE_EXPORTTABLESIZE)
{
return(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size);
}
else if(WhichData == UE_TLSTABLEADDRESS)
{
return(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress);
}
else if(WhichData == UE_TLSTABLESIZE)
{
return(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size);
}
else if(WhichData == UE_RELOCATIONTABLEADDRESS)
{
return(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
}
else if(WhichData == UE_RELOCATIONTABLESIZE)
{
return(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size);
}
else if(WhichData == UE_TIMEDATESTAMP)
{
return(PEHeader32->FileHeader.TimeDateStamp);
}
else if(WhichData == UE_SECTIONNUMBER)
{
return(PEHeader32->FileHeader.NumberOfSections);
}
else if(WhichData == UE_CHECKSUM)
{
return(PEHeader32->OptionalHeader.CheckSum);
}
else if(WhichData == UE_SUBSYSTEM)
{
return(PEHeader32->OptionalHeader.Subsystem);
}
else if(WhichData == UE_CHARACTERISTICS)
{
return(PEHeader32->FileHeader.Characteristics);
}
else if(WhichData == UE_NUMBEROFRVAANDSIZES)
{
return(PEHeader32->OptionalHeader.NumberOfRvaAndSizes);
}
else
{
return(0);
}
}
else
{
if(SectionNumber >= WhichSection)
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + WhichSection * IMAGE_SIZEOF_SECTION_HEADER);
if(WhichData == UE_SECTIONNAME)
{
memcpy(sectionName, PESections->Name, 8);
return (long long)sectionName;
}
else if(WhichData == UE_SECTIONVIRTUALOFFSET)
{
return(PESections->VirtualAddress);
}
else if(WhichData == UE_SECTIONVIRTUALSIZE)
{
return(PESections->Misc.VirtualSize);
}
else if(WhichData == UE_SECTIONRAWOFFSET)
{
return(PESections->PointerToRawData);
}
else if(WhichData == UE_SECTIONRAWSIZE)
{
return(PESections->SizeOfRawData);
}
else if(WhichData == UE_SECTIONFLAGS)
{
return(PESections->Characteristics);
}
else
{
return(0);
}
}
}
return(0);
}
else
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader64 + PEHeader64->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
SectionNumber = PEHeader64->FileHeader.NumberOfSections;
if(WhichData < UE_SECTIONNAME)
{
if(WhichData == UE_PE_OFFSET)
{
return(DOSHeader->e_lfanew);
}
else if(WhichData == UE_IMAGEBASE)
{
return(PEHeader64->OptionalHeader.ImageBase);
}
else if(WhichData == UE_OEP)
{
return(PEHeader64->OptionalHeader.AddressOfEntryPoint);
}
else if(WhichData == UE_BASEOFCODE)
{
return(PEHeader64->OptionalHeader.BaseOfCode);
}
/* non-existent in IMAGE_OPTIONAL_HEADER64
else if(WhichData == UE_BASEOFDATA)
{
return(PEHeader64->OptionalHeader.BaseOfData);
}*/
else if(WhichData == UE_SIZEOFIMAGE)
{
return(PEHeader64->OptionalHeader.SizeOfImage);
}
else if(WhichData == UE_SIZEOFHEADERS)
{
return(PEHeader64->OptionalHeader.SizeOfHeaders);
}
else if(WhichData == UE_SIZEOFOPTIONALHEADER)
{
return(PEHeader64->FileHeader.SizeOfOptionalHeader);
}
else if(WhichData == UE_SECTIONALIGNMENT)
{
return(PEHeader64->OptionalHeader.SectionAlignment);
}
else if(WhichData == UE_IMPORTTABLEADDRESS)
{
return(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
}
else if(WhichData == UE_IMPORTTABLESIZE)
{
return(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size);
}
else if(WhichData == UE_RESOURCETABLEADDRESS)
{
return(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress);
}
else if(WhichData == UE_RESOURCETABLESIZE)
{
return(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size);
}
else if(WhichData == UE_EXPORTTABLEADDRESS)
{
return(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
}
else if(WhichData == UE_EXPORTTABLESIZE)
{
return(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size);
}
else if(WhichData == UE_TLSTABLEADDRESS)
{
return(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress);
}
else if(WhichData == UE_TLSTABLESIZE)
{
return(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size);
}
else if(WhichData == UE_RELOCATIONTABLEADDRESS)
{
return(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
}
else if(WhichData == UE_RELOCATIONTABLESIZE)
{
return(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size);
}
else if(WhichData == UE_TIMEDATESTAMP)
{
return(PEHeader64->FileHeader.TimeDateStamp);
}
else if(WhichData == UE_SECTIONNUMBER)
{
return(PEHeader64->FileHeader.NumberOfSections);
}
else if(WhichData == UE_CHECKSUM)
{
return(PEHeader64->OptionalHeader.CheckSum);
}
else if(WhichData == UE_SUBSYSTEM)
{
return(PEHeader64->OptionalHeader.Subsystem);
}
else if(WhichData == UE_CHARACTERISTICS)
{
return(PEHeader64->FileHeader.Characteristics);
}
else if(WhichData == UE_NUMBEROFRVAANDSIZES)
{
return(PEHeader64->OptionalHeader.NumberOfRvaAndSizes);
}
else
{
return(0);
}
}
else
{
if(SectionNumber >= WhichSection)
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + WhichSection * IMAGE_SIZEOF_SECTION_HEADER);
if(WhichData == UE_SECTIONNAME)
{
return((ULONG_PTR)PESections->Name);
}
else if(WhichData == UE_SECTIONVIRTUALOFFSET)
{
return(PESections->VirtualAddress);
}
else if(WhichData == UE_SECTIONVIRTUALSIZE)
{
return(PESections->Misc.VirtualSize);
}
else if(WhichData == UE_SECTIONRAWOFFSET)
{
return(PESections->PointerToRawData);
}
else if(WhichData == UE_SECTIONRAWSIZE)
{
return(PESections->SizeOfRawData);
}
else if(WhichData == UE_SECTIONFLAGS)
{
return(PESections->Characteristics);
}
else
{
return(0);
}
}
}
return(0);
}
}
else
{
return(0);
}
}
return(0);
}
__declspec(dllexport) long long TITCALL GetPE32Data(char* szFileName, DWORD WhichSection, DWORD WhichData)
{
HANDLE FileHandle;
DWORD FileSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
long long ReturnValue = 0;
if(MapFileEx(szFileName, UE_ACCESS_READ, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
ReturnValue = GetPE32DataFromMappedFile(FileMapVA, WhichSection, WhichData);
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(ReturnValue);
}
else
{
return(0);
}
}
__declspec(dllexport) long long TITCALL GetPE32DataW(wchar_t* szFileName, DWORD WhichSection, DWORD WhichData)
{
HANDLE FileHandle;
DWORD FileSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
long long ReturnValue = 0;
if(MapFileExW(szFileName, UE_ACCESS_READ, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
ReturnValue = GetPE32DataFromMappedFile(FileMapVA, WhichSection, WhichData);
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(ReturnValue);
}
else
{
return(0);
}
}
__declspec(dllexport) bool TITCALL GetPE32DataFromMappedFileEx(ULONG_PTR FileMapVA, LPVOID DataStorage)
{
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
BOOL FileIs64;
PPE32Struct PE32Structure = (PPE32Struct)DataStorage;
PPE64Struct PE64Structure = (PPE64Struct)DataStorage;
if(FileMapVA != NULL)
{
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, NULL, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
return(false);
}
if(!FileIs64)
{
PE32Structure->PE32Offset = DOSHeader->e_lfanew;
PE32Structure->ImageBase = PEHeader32->OptionalHeader.ImageBase;
PE32Structure->OriginalEntryPoint = PEHeader32->OptionalHeader.AddressOfEntryPoint;
PE32Structure->BaseOfCode = PEHeader32->OptionalHeader.BaseOfCode;
PE32Structure->BaseOfData = PEHeader32->OptionalHeader.BaseOfData;
PE32Structure->NtSizeOfImage = PEHeader32->OptionalHeader.SizeOfImage;
PE32Structure->NtSizeOfHeaders = PEHeader32->OptionalHeader.SizeOfHeaders;
PE32Structure->SizeOfOptionalHeaders = PEHeader32->FileHeader.SizeOfOptionalHeader;
PE32Structure->FileAlignment = PEHeader32->OptionalHeader.FileAlignment;
PE32Structure->SectionAligment = PEHeader32->OptionalHeader.SectionAlignment;
PE32Structure->ImportTableAddress = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
PE32Structure->ImportTableSize = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size;
PE32Structure->ResourceTableAddress = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;
PE32Structure->ResourceTableSize = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size;
PE32Structure->ExportTableAddress = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
PE32Structure->ExportTableSize = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
PE32Structure->TLSTableAddress = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress;
PE32Structure->TLSTableSize = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size;
PE32Structure->RelocationTableAddress = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
PE32Structure->RelocationTableSize = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
PE32Structure->TimeDateStamp = PEHeader32->FileHeader.TimeDateStamp;
PE32Structure->SectionNumber = PEHeader32->FileHeader.NumberOfSections;
PE32Structure->CheckSum = PEHeader32->OptionalHeader.CheckSum;
PE32Structure->SubSystem = PEHeader32->OptionalHeader.Subsystem;
PE32Structure->Characteristics = PEHeader32->FileHeader.Characteristics;
PE32Structure->NumberOfRvaAndSizes = PEHeader32->OptionalHeader.NumberOfRvaAndSizes;
return(true);
}
else
{
PE64Structure->PE64Offset = DOSHeader->e_lfanew;
PE64Structure->ImageBase = PEHeader64->OptionalHeader.ImageBase;
PE64Structure->OriginalEntryPoint = PEHeader64->OptionalHeader.AddressOfEntryPoint;
PE64Structure->BaseOfCode = PEHeader32->OptionalHeader.BaseOfCode;
PE64Structure->BaseOfData = PEHeader32->OptionalHeader.BaseOfData;
PE64Structure->NtSizeOfImage = PEHeader64->OptionalHeader.SizeOfImage;
PE64Structure->NtSizeOfHeaders = PEHeader64->OptionalHeader.SizeOfHeaders;
PE64Structure->SizeOfOptionalHeaders = PEHeader64->FileHeader.SizeOfOptionalHeader;
PE64Structure->FileAlignment = PEHeader64->OptionalHeader.FileAlignment;
PE64Structure->SectionAligment = PEHeader64->OptionalHeader.SectionAlignment;
PE64Structure->ImportTableAddress = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
PE64Structure->ImportTableSize = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size;
PE64Structure->ResourceTableAddress = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;
PE64Structure->ResourceTableSize = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size;
PE64Structure->ExportTableAddress = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
PE64Structure->ExportTableSize = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
PE64Structure->TLSTableAddress = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress;
PE64Structure->TLSTableSize = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size;
PE64Structure->RelocationTableAddress = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
PE64Structure->RelocationTableSize = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
PE64Structure->TimeDateStamp = PEHeader64->FileHeader.TimeDateStamp;
PE64Structure->SectionNumber = PEHeader64->FileHeader.NumberOfSections;
PE64Structure->CheckSum = PEHeader64->OptionalHeader.CheckSum;
PE64Structure->SubSystem = PEHeader64->OptionalHeader.Subsystem;
PE64Structure->Characteristics = PEHeader64->FileHeader.Characteristics;
PE64Structure->NumberOfRvaAndSizes = PEHeader64->OptionalHeader.NumberOfRvaAndSizes;
return(true);
}
}
else
{
return(false);
}
}
return(false);
}
__declspec(dllexport) bool TITCALL GetPE32DataEx(char* szFileName, LPVOID DataStorage)
{
HANDLE FileHandle;
DWORD FileSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
long long ReturnValue = 0;
if(MapFileEx(szFileName, UE_ACCESS_READ, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
ReturnValue = GetPE32DataFromMappedFileEx(FileMapVA, DataStorage);
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
if(ReturnValue)
{
return(true);
}
else
{
return(false);
}
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL GetPE32DataExW(wchar_t* szFileName, LPVOID DataStorage)
{
HANDLE FileHandle;
DWORD FileSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
long long ReturnValue = 0;
if(MapFileExW(szFileName, UE_ACCESS_READ, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
ReturnValue = GetPE32DataFromMappedFileEx(FileMapVA, DataStorage);
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
if(ReturnValue)
{
return(true);
}
else
{
return(false);
}
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL SetPE32DataForMappedFile(ULONG_PTR FileMapVA, DWORD WhichSection, DWORD WhichData, ULONG_PTR NewDataValue)
{
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
PIMAGE_SECTION_HEADER PESections;
DWORD SectionNumber = 0;
BOOL FileIs64;
if(FileMapVA != NULL)
{
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, NULL, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
return(false);
}
if(!FileIs64)
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader32 + PEHeader32->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
SectionNumber = PEHeader32->FileHeader.NumberOfSections;
__try
{
if(WhichData < UE_SECTIONNAME)
{
if(WhichData == UE_PE_OFFSET)
{
DOSHeader->e_lfanew = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_IMAGEBASE)
{
PEHeader32->OptionalHeader.ImageBase = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_OEP)
{
PEHeader32->OptionalHeader.AddressOfEntryPoint = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_BASEOFCODE)
{
PEHeader32->OptionalHeader.BaseOfCode = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_BASEOFDATA)
{
PEHeader32->OptionalHeader.BaseOfData = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_SIZEOFIMAGE)
{
PEHeader32->OptionalHeader.SizeOfImage = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_SIZEOFHEADERS)
{
PEHeader32->OptionalHeader.SizeOfHeaders = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_SIZEOFOPTIONALHEADER)
{
PEHeader32->FileHeader.SizeOfOptionalHeader = (WORD)NewDataValue;
return(true);
}
else if(WhichData == UE_SECTIONALIGNMENT)
{
PEHeader32->OptionalHeader.SectionAlignment = (WORD)NewDataValue;
return(true);
}
else if(WhichData == UE_IMPORTTABLEADDRESS)
{
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_IMPORTTABLESIZE)
{
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_RESOURCETABLEADDRESS)
{
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_RESOURCETABLESIZE)
{
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_EXPORTTABLEADDRESS)
{
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_EXPORTTABLESIZE)
{
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_TLSTABLEADDRESS)
{
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_TLSTABLESIZE)
{
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_RELOCATIONTABLEADDRESS)
{
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_RELOCATIONTABLESIZE)
{
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_TIMEDATESTAMP)
{
PEHeader32->FileHeader.TimeDateStamp = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_SECTIONNUMBER)
{
PEHeader32->FileHeader.NumberOfSections = (WORD)NewDataValue;
return(true);
}
else if(WhichData == UE_CHECKSUM)
{
PEHeader32->OptionalHeader.CheckSum = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_SUBSYSTEM)
{
PEHeader32->OptionalHeader.Subsystem = (WORD)NewDataValue;
return(true);
}
else if(WhichData == UE_CHARACTERISTICS)
{
PEHeader32->FileHeader.Characteristics = (WORD)NewDataValue;
return(true);
}
else if(WhichData == UE_NUMBEROFRVAANDSIZES)
{
PEHeader32->OptionalHeader.NumberOfRvaAndSizes = (DWORD)NewDataValue;
return(true);
}
else
{
return(false);
}
}
else
{
if(WhichSection <= SectionNumber)
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + WhichSection * IMAGE_SIZEOF_SECTION_HEADER);
if(WhichData == UE_SECTIONNAME)
{
memcpy(PESections->Name, (void*)NewDataValue, 8);
return(true);
}
else if(WhichData == UE_SECTIONVIRTUALOFFSET)
{
PESections->VirtualAddress = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_SECTIONVIRTUALSIZE)
{
PESections->Misc.VirtualSize = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_SECTIONRAWOFFSET)
{
PESections->PointerToRawData = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_SECTIONRAWSIZE)
{
PESections->SizeOfRawData = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_SECTIONFLAGS)
{
PESections->Characteristics = (DWORD)NewDataValue;
return(true);
}
else
{
return(false);
}
}
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return(false);
}
return(false);
}
else
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader64 + PEHeader64->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
SectionNumber = PEHeader64->FileHeader.NumberOfSections;
__try
{
if(WhichData < UE_SECTIONNAME)
{
if(WhichData == UE_PE_OFFSET)
{
DOSHeader->e_lfanew = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_IMAGEBASE)
{
PEHeader64->OptionalHeader.ImageBase = NewDataValue;
return(true);
}
else if(WhichData == UE_OEP)
{
PEHeader64->OptionalHeader.AddressOfEntryPoint = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_BASEOFCODE)
{
PEHeader64->OptionalHeader.BaseOfCode = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_BASEOFDATA)
{
//non-existant in IMAGE_OPTIONAL_HEADER64
return(false);
}
else if(WhichData == UE_SIZEOFIMAGE)
{
PEHeader64->OptionalHeader.SizeOfImage = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_SIZEOFHEADERS)
{
PEHeader64->OptionalHeader.SizeOfHeaders = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_SIZEOFOPTIONALHEADER)
{
PEHeader64->FileHeader.SizeOfOptionalHeader = (WORD)NewDataValue;
return(true);
}
else if(WhichData == UE_SECTIONALIGNMENT)
{
PEHeader64->OptionalHeader.SectionAlignment = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_IMPORTTABLEADDRESS)
{
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_IMPORTTABLESIZE)
{
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_RESOURCETABLEADDRESS)
{
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_RESOURCETABLESIZE)
{
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_EXPORTTABLEADDRESS)
{
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_EXPORTTABLESIZE)
{
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_TLSTABLEADDRESS)
{
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_TLSTABLESIZE)
{
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_RELOCATIONTABLEADDRESS)
{
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_RELOCATIONTABLESIZE)
{
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_TIMEDATESTAMP)
{
PEHeader64->FileHeader.TimeDateStamp = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_SECTIONNUMBER)
{
PEHeader64->FileHeader.NumberOfSections = (WORD)NewDataValue;
return(true);
}
else if(WhichData == UE_CHECKSUM)
{
PEHeader64->OptionalHeader.CheckSum = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_SUBSYSTEM)
{
PEHeader64->OptionalHeader.Subsystem = (WORD)NewDataValue;
return(true);
}
else if(WhichData == UE_CHARACTERISTICS)
{
PEHeader64->FileHeader.Characteristics = (WORD)NewDataValue;
return(true);
}
else if(WhichData == UE_NUMBEROFRVAANDSIZES)
{
PEHeader64->OptionalHeader.NumberOfRvaAndSizes = (DWORD)NewDataValue;
return(true);
}
else
{
return(0);
}
}
else
{
if(WhichSection <= SectionNumber)
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + WhichSection * IMAGE_SIZEOF_SECTION_HEADER);
if(WhichData == UE_SECTIONNAME)
{
return(false);
}
else if(WhichData == UE_SECTIONVIRTUALOFFSET)
{
PESections->VirtualAddress = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_SECTIONVIRTUALSIZE)
{
PESections->Misc.VirtualSize = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_SECTIONRAWOFFSET)
{
PESections->PointerToRawData = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_SECTIONRAWSIZE)
{
PESections->SizeOfRawData = (DWORD)NewDataValue;
return(true);
}
else if(WhichData == UE_SECTIONFLAGS)
{
PESections->Characteristics = (DWORD)NewDataValue;
return(true);
}
else
{
return(false);
}
}
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return(false);
}
return(false);
}
}
else
{
return(false);
}
}
return(false);
}
__declspec(dllexport) bool TITCALL SetPE32Data(char* szFileName, DWORD WhichSection, DWORD WhichData, ULONG_PTR NewDataValue)
{
HANDLE FileHandle;
DWORD FileSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
long long ReturnValue = 0;
if(MapFileEx(szFileName, UE_ACCESS_ALL, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
ReturnValue = SetPE32DataForMappedFile(FileMapVA, WhichSection, WhichData, NewDataValue);
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
if(ReturnValue)
{
return(true);
}
else
{
return(false);
}
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL SetPE32DataW(wchar_t* szFileName, DWORD WhichSection, DWORD WhichData, ULONG_PTR NewDataValue)
{
HANDLE FileHandle;
DWORD FileSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
long long ReturnValue = 0;
if(MapFileExW(szFileName, UE_ACCESS_ALL, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
ReturnValue = SetPE32DataForMappedFile(FileMapVA, WhichSection, WhichData, NewDataValue);
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
if(ReturnValue)
{
return(true);
}
else
{
return(false);
}
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL SetPE32DataForMappedFileEx(ULONG_PTR FileMapVA, LPVOID DataStorage)
{
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
BOOL FileIs64;
PPE32Struct PE32Structure = (PPE32Struct)DataStorage;
PPE64Struct PE64Structure = (PPE64Struct)DataStorage;
if(FileMapVA != NULL)
{
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, NULL, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
return(false);
}
if(!FileIs64)
{
__try
{
DOSHeader->e_lfanew = PE32Structure->PE32Offset;
PEHeader32->OptionalHeader.ImageBase = PE32Structure->ImageBase;
PEHeader32->OptionalHeader.AddressOfEntryPoint = PE32Structure->OriginalEntryPoint;
PEHeader32->OptionalHeader.BaseOfCode = PE32Structure->BaseOfCode;
PEHeader32->OptionalHeader.BaseOfData = PE32Structure->BaseOfData;
PEHeader32->OptionalHeader.SizeOfImage = PE32Structure->NtSizeOfImage;
PEHeader32->OptionalHeader.SizeOfHeaders = PE32Structure->NtSizeOfHeaders;
PEHeader32->FileHeader.SizeOfOptionalHeader = PE32Structure->SizeOfOptionalHeaders;
PEHeader32->OptionalHeader.FileAlignment = PE32Structure->FileAlignment;
PEHeader32->OptionalHeader.SectionAlignment = PE32Structure->SectionAligment;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = PE32Structure->ImportTableAddress;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = PE32Structure->ImportTableSize;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = PE32Structure->ResourceTableAddress;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = PE32Structure->ResourceTableSize;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = PE32Structure->ExportTableAddress;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = PE32Structure->ExportTableSize;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress = PE32Structure->TLSTableAddress;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size = PE32Structure->TLSTableSize;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = PE32Structure->RelocationTableAddress;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = PE32Structure->RelocationTableSize;
PEHeader32->FileHeader.TimeDateStamp = PE32Structure->TimeDateStamp;
PEHeader32->FileHeader.NumberOfSections = PE32Structure->SectionNumber;
PEHeader32->OptionalHeader.CheckSum = PE32Structure->CheckSum;
PEHeader32->OptionalHeader.Subsystem = PE32Structure->SubSystem;
PEHeader32->FileHeader.Characteristics = PE32Structure->Characteristics;
PEHeader32->OptionalHeader.NumberOfRvaAndSizes = PE32Structure->NumberOfRvaAndSizes;
return(true);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return(false);
}
}
else
{
__try
{
DOSHeader->e_lfanew = PE64Structure->PE64Offset;
PEHeader64->OptionalHeader.ImageBase = PE64Structure->ImageBase;
PEHeader64->OptionalHeader.AddressOfEntryPoint = PE64Structure->OriginalEntryPoint;
PEHeader64->OptionalHeader.BaseOfCode = PE64Structure->BaseOfCode;
PEHeader64->OptionalHeader.SizeOfImage = PE64Structure->NtSizeOfImage;
PEHeader64->OptionalHeader.SizeOfHeaders = PE64Structure->NtSizeOfHeaders;
PEHeader64->FileHeader.SizeOfOptionalHeader = PE64Structure->SizeOfOptionalHeaders;
PEHeader64->OptionalHeader.FileAlignment = PE64Structure->FileAlignment;
PEHeader64->OptionalHeader.SectionAlignment = PE64Structure->SectionAligment;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = PE64Structure->ImportTableAddress;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = PE64Structure->ImportTableSize;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = PE64Structure->ResourceTableAddress;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = PE64Structure->ResourceTableSize;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = PE64Structure->ExportTableAddress;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = PE64Structure->ExportTableSize;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress = PE64Structure->TLSTableAddress;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size = PE64Structure->TLSTableSize;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = PE64Structure->RelocationTableAddress;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = PE64Structure->RelocationTableSize;
PEHeader64->FileHeader.TimeDateStamp = PE64Structure->TimeDateStamp;
PEHeader64->FileHeader.NumberOfSections = PE64Structure->SectionNumber;
PEHeader64->OptionalHeader.CheckSum = PE64Structure->CheckSum;
PEHeader64->OptionalHeader.Subsystem = PE64Structure->SubSystem;
PEHeader64->FileHeader.Characteristics = PE64Structure->Characteristics;
PEHeader64->OptionalHeader.NumberOfRvaAndSizes = PE64Structure->NumberOfRvaAndSizes;
return(true);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return(false);
}
}
}
else
{
return(false);
}
}
return(false);
}
__declspec(dllexport) bool TITCALL SetPE32DataEx(char* szFileName, LPVOID DataStorage)
{
HANDLE FileHandle;
DWORD FileSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
long long ReturnValue = 0;
if(MapFileEx(szFileName, UE_ACCESS_ALL, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
ReturnValue = SetPE32DataForMappedFileEx(FileMapVA, DataStorage);
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
if(ReturnValue)
{
return(true);
}
else
{
return(false);
}
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL SetPE32DataExW(wchar_t* szFileName, LPVOID DataStorage)
{
HANDLE FileHandle;
DWORD FileSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
long long ReturnValue = 0;
if(MapFileExW(szFileName, UE_ACCESS_ALL, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
ReturnValue = SetPE32DataForMappedFileEx(FileMapVA, DataStorage);
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
if(ReturnValue)
{
return(true);
}
else
{
return(false);
}
}
else
{
return(false);
}
}
__declspec(dllexport) long TITCALL GetPE32SectionNumberFromVA(ULONG_PTR FileMapVA, ULONG_PTR AddressToConvert)
{
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
PIMAGE_SECTION_HEADER PESections;
ULONG_PTR FoundInSection = -1;
DWORD SectionNumber = 0;
DWORD ConvertAddress = 0;
BOOL FileIs64;
if(FileMapVA != NULL)
{
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, NULL, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
return(-2);
}
if(!FileIs64)
{
__try
{
ConvertAddress = (DWORD)((DWORD)AddressToConvert - PEHeader32->OptionalHeader.ImageBase);
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader32 + PEHeader32->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
SectionNumber = PEHeader32->FileHeader.NumberOfSections;
while(SectionNumber > 0)
{
if(PESections->VirtualAddress <= ConvertAddress && ConvertAddress < PESections->VirtualAddress + PESections->Misc.VirtualSize)
{
FoundInSection = PEHeader32->FileHeader.NumberOfSections - SectionNumber;
}
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + IMAGE_SIZEOF_SECTION_HEADER);
SectionNumber--;
}
return((DWORD)FoundInSection);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return(-2);
}
}
else
{
__try
{
ConvertAddress = (DWORD)(AddressToConvert - PEHeader64->OptionalHeader.ImageBase);
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader64 + PEHeader64->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
SectionNumber = PEHeader64->FileHeader.NumberOfSections;
while(SectionNumber > 0)
{
if(PESections->VirtualAddress <= ConvertAddress && ConvertAddress < PESections->VirtualAddress + PESections->Misc.VirtualSize)
{
FoundInSection = PEHeader64->FileHeader.NumberOfSections - SectionNumber;
}
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + IMAGE_SIZEOF_SECTION_HEADER);
SectionNumber--;
}
return((DWORD)FoundInSection);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return(-2);
}
}
}
else
{
return(-2);
}
}
return(-2);
}
__declspec(dllexport) long long TITCALL ConvertVAtoFileOffset(ULONG_PTR FileMapVA, ULONG_PTR AddressToConvert, bool ReturnType)
{
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
PIMAGE_SECTION_HEADER PESections;
DWORD SectionNumber = 0;
ULONG_PTR ConvertedAddress = 0;
ULONG_PTR ConvertAddress = 0;
BOOL FileIs64;
if(FileMapVA != NULL)
{
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, NULL, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
return(0);
}
if(!FileIs64)
{
ConvertAddress = (DWORD)((DWORD)AddressToConvert - PEHeader32->OptionalHeader.ImageBase);
if(ConvertAddress < PEHeader32->OptionalHeader.SectionAlignment)
{
ConvertedAddress = ConvertAddress;
}
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader32 + PEHeader32->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
SectionNumber = PEHeader32->FileHeader.NumberOfSections;
__try
{
while(SectionNumber > 0)
{
if(PESections->VirtualAddress <= ConvertAddress && ConvertAddress <= PESections->VirtualAddress + PESections->Misc.VirtualSize)
{
if(ConvertAddress - PESections->VirtualAddress <= PESections->SizeOfRawData)
{
ConvertedAddress = PESections->PointerToRawData + (ConvertAddress - PESections->VirtualAddress);
}
}
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + IMAGE_SIZEOF_SECTION_HEADER);
SectionNumber--;
}
if(ReturnType)
{
if(ConvertedAddress != NULL)
{
ConvertedAddress = ConvertedAddress + FileMapVA;
}
else if(ConvertAddress == NULL)
{
ConvertedAddress = FileMapVA;
}
}
return(ConvertedAddress);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return(0);
}
}
else
{
ConvertAddress = (DWORD)(AddressToConvert - PEHeader64->OptionalHeader.ImageBase);
if(ConvertAddress < PEHeader64->OptionalHeader.SectionAlignment)
{
ConvertedAddress = ConvertAddress;
}
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader64 + PEHeader64->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
SectionNumber = PEHeader64->FileHeader.NumberOfSections;
__try
{
while(SectionNumber > 0)
{
if(PESections->VirtualAddress <= ConvertAddress && ConvertAddress <= PESections->VirtualAddress + PESections->Misc.VirtualSize)
{
if(ConvertAddress - PESections->VirtualAddress <= PESections->SizeOfRawData)
{
ConvertedAddress = PESections->PointerToRawData + (ConvertAddress - PESections->VirtualAddress);
}
}
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + IMAGE_SIZEOF_SECTION_HEADER);
SectionNumber--;
}
if(ReturnType)
{
if(ConvertedAddress != NULL)
{
ConvertedAddress = ConvertedAddress + FileMapVA;
}
else if(ConvertAddress == NULL)
{
ConvertedAddress = FileMapVA;
}
}
return(ConvertedAddress);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return(0);
}
}
}
else
{
return(0);
}
}
return(0);
}
__declspec(dllexport) long long TITCALL ConvertVAtoFileOffsetEx(ULONG_PTR FileMapVA, DWORD FileSize, ULONG_PTR ImageBase, ULONG_PTR AddressToConvert, bool AddressIsRVA, bool ReturnType)
{
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
PIMAGE_SECTION_HEADER PESections;
DWORD SectionNumber = 0;
ULONG_PTR ConvertedAddress = 0;
ULONG_PTR ConvertAddress = 0;
BOOL FileIs64;
if(FileMapVA != NULL)
{
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, NULL, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
return(0);
}
if(!FileIs64)
{
if(!AddressIsRVA)
{
if(ImageBase == NULL)
{
ConvertAddress = (DWORD)((DWORD)AddressToConvert - PEHeader32->OptionalHeader.ImageBase);
}
else
{
ConvertAddress = (DWORD)((DWORD)AddressToConvert - ImageBase);
}
}
else
{
ConvertAddress = (DWORD)AddressToConvert;
}
if(ConvertAddress < PEHeader32->OptionalHeader.SectionAlignment)
{
ConvertedAddress = ConvertAddress;
}
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader32 + PEHeader32->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
SectionNumber = PEHeader32->FileHeader.NumberOfSections;
__try
{
while(SectionNumber > 0)
{
if(PESections->VirtualAddress <= ConvertAddress && ConvertAddress <= PESections->VirtualAddress + PESections->Misc.VirtualSize)
{
if(ConvertAddress - PESections->VirtualAddress <= PESections->SizeOfRawData)
{
ConvertedAddress = PESections->PointerToRawData + (ConvertAddress - PESections->VirtualAddress);
}
}
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + IMAGE_SIZEOF_SECTION_HEADER);
SectionNumber--;
}
if(ReturnType)
{
if(ConvertedAddress != NULL)
{
ConvertedAddress = ConvertedAddress + FileMapVA;
}
}
if(ReturnType)
{
if(ConvertedAddress >= FileMapVA && ConvertedAddress <= FileMapVA + FileSize)
{
return((ULONG_PTR)ConvertedAddress);
}
else
{
return(NULL);
}
}
else
{
if(ConvertedAddress > NULL && ConvertedAddress <= FileSize)
{
return((ULONG_PTR)ConvertedAddress);
}
else
{
return(NULL);
}
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return(NULL);
}
}
else
{
if(!AddressIsRVA)
{
if(ImageBase == NULL)
{
ConvertAddress = (DWORD)(AddressToConvert - PEHeader64->OptionalHeader.ImageBase);
}
else
{
ConvertAddress = (DWORD)(AddressToConvert - ImageBase);
}
}
else
{
ConvertAddress = (DWORD)AddressToConvert;
}
if(ConvertAddress < PEHeader64->OptionalHeader.SectionAlignment)
{
ConvertedAddress = ConvertAddress;
}
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader64 + PEHeader64->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
SectionNumber = PEHeader64->FileHeader.NumberOfSections;
__try
{
while(SectionNumber > 0)
{
if(PESections->VirtualAddress <= ConvertAddress && ConvertAddress <= PESections->VirtualAddress + PESections->Misc.VirtualSize)
{
if(ConvertAddress - PESections->VirtualAddress <= PESections->SizeOfRawData)
{
ConvertedAddress = PESections->PointerToRawData + (ConvertAddress - PESections->VirtualAddress);
}
}
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + IMAGE_SIZEOF_SECTION_HEADER);
SectionNumber--;
}
if(ReturnType)
{
if(ConvertedAddress != NULL)
{
ConvertedAddress = ConvertedAddress + FileMapVA;
}
}
if(ReturnType)
{
if(ConvertedAddress >= FileMapVA && ConvertedAddress <= FileMapVA + FileSize)
{
return((ULONG_PTR)ConvertedAddress);
}
else
{
return(NULL);
}
}
else
{
if(ConvertedAddress > NULL && ConvertedAddress <= FileSize)
{
return((ULONG_PTR)ConvertedAddress);
}
else
{
return(NULL);
}
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return(NULL);
}
}
}
else
{
return(0);
}
}
return(0);
}
__declspec(dllexport) long long TITCALL ConvertFileOffsetToVA(ULONG_PTR FileMapVA, ULONG_PTR AddressToConvert, bool ReturnType)
{
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
PIMAGE_SECTION_HEADER PESections;
DWORD SectionNumber = 0;
ULONG_PTR ConvertedAddress = 0;
ULONG_PTR ConvertAddress = 0;
BOOL FileIs64;
if(FileMapVA != NULL)
{
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, NULL, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
return(0);
}
if(!FileIs64)
{
ConvertAddress = (DWORD)((DWORD)AddressToConvert - FileMapVA);
if(ConvertAddress < PEHeader32->OptionalHeader.FileAlignment)
{
ConvertedAddress = ConvertAddress;
}
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader32 + PEHeader32->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
SectionNumber = PEHeader32->FileHeader.NumberOfSections;
__try
{
while(SectionNumber > 0)
{
if(PESections->PointerToRawData <= ConvertAddress && ConvertAddress <= PESections->PointerToRawData + PESections->SizeOfRawData)
{
ConvertedAddress = PESections->VirtualAddress + (ConvertAddress - PESections->PointerToRawData);
}
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + IMAGE_SIZEOF_SECTION_HEADER);
SectionNumber--;
}
if(ReturnType)
{
if(ConvertedAddress != NULL)
{
ConvertedAddress = ConvertedAddress + PEHeader32->OptionalHeader.ImageBase;
}
}
else if(ConvertAddress == NULL)
{
ConvertedAddress = PEHeader32->OptionalHeader.ImageBase;
}
return(ConvertedAddress);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return(0);
}
}
else
{
ConvertAddress = (DWORD)(AddressToConvert - FileMapVA);
if(ConvertAddress < PEHeader64->OptionalHeader.FileAlignment)
{
ConvertedAddress = ConvertAddress;
}
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader64 + PEHeader64->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
SectionNumber = PEHeader64->FileHeader.NumberOfSections;
__try
{
while(SectionNumber > 0)
{
if(PESections->PointerToRawData <= ConvertAddress && ConvertAddress <= PESections->PointerToRawData + PESections->SizeOfRawData)
{
ConvertedAddress = PESections->VirtualAddress + (ConvertAddress - PESections->PointerToRawData);
}
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + IMAGE_SIZEOF_SECTION_HEADER);
SectionNumber--;
}
if(ReturnType)
{
if(ConvertedAddress != NULL)
{
ConvertedAddress = ConvertedAddress + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase;
}
}
else if(ConvertAddress == NULL)
{
ConvertedAddress = (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase;
}
return(ConvertedAddress);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return(0);
}
}
}
else
{
return(0);
}
}
return(0);
}
__declspec(dllexport) long long TITCALL ConvertFileOffsetToVAEx(ULONG_PTR FileMapVA, DWORD FileSize, ULONG_PTR ImageBase, ULONG_PTR AddressToConvert, bool ReturnType)
{
ULONG_PTR ConvertedAddress = NULL;
DWORD cnvSectionAlignment = NULL;
ULONG_PTR cnvImageBase = NULL;
DWORD cnvSizeOfImage = NULL;
if(FileMapVA != NULL)
{
if(ImageBase == NULL)
{
cnvImageBase = (ULONG_PTR)GetPE32DataFromMappedFile(FileMapVA, NULL, UE_IMAGEBASE);
}
else
{
cnvImageBase = ImageBase;
}
cnvSizeOfImage = (DWORD)GetPE32DataFromMappedFile(FileMapVA, NULL, UE_SIZEOFIMAGE);
cnvSectionAlignment = (DWORD)GetPE32DataFromMappedFile(FileMapVA, NULL, UE_SECTIONALIGNMENT);
ConvertedAddress = (ULONG_PTR)ConvertFileOffsetToVA(FileMapVA, AddressToConvert, ReturnType);
if(ReturnType)
{
if(ConvertedAddress >= cnvImageBase + cnvSectionAlignment && ConvertedAddress <= cnvImageBase + cnvSizeOfImage)
{
return((ULONG_PTR)ConvertedAddress);
}
else
{
return(NULL);
}
}
else
{
if(ConvertedAddress >= cnvSectionAlignment && ConvertedAddress <= cnvSizeOfImage)
{
return((ULONG_PTR)ConvertedAddress);
}
else
{
return(NULL);
}
}
}
return(NULL);
}
// Global.Realigner.functions:
void SetOverallFileStatus(PFILE_STATUS_INFO myFileInfo, BYTE FiledStatus, bool FiledCritical)
{
if(myFileInfo->OveralEvaluation == UE_RESULT_FILE_OK || myFileInfo->OveralEvaluation == UE_RESULT_FILE_INVALID_BUT_FIXABLE)
{
if(FiledStatus == UE_FILED_FIXABLE_CRITICAL || FiledStatus == UE_FIELD_BROKEN_FIXABLE_FOR_STATIC_USE || FiledStatus == UE_FIELD_BROKEN_BUT_CAN_BE_EMULATED)
{
myFileInfo->OveralEvaluation = UE_RESULT_FILE_INVALID_BUT_FIXABLE;
}
else if(FiledStatus == UE_FIELD_BROKEN_NON_FIXABLE && FiledCritical == true)
{
myFileInfo->OveralEvaluation = UE_RESULT_FILE_INVALID_AND_NON_FIXABLE;
}
else if(FiledStatus == UE_FIELD_BROKEN_FIXABLE_FOR_STATIC_USE)
{
myFileInfo->OveralEvaluation = UE_RESULT_FILE_INVALID_BUT_FIXABLE;
}
}
}
// TitanEngine.Realigner.functions:
__declspec(dllexport) bool TITCALL FixHeaderCheckSum(char* szFileName)
{
DWORD HeaderSum = NULL;
DWORD CheckSum = NULL;
if(MapFileAndCheckSumA(szFileName, &HeaderSum, &CheckSum) == NULL)
{
SetPE32Data(szFileName, NULL, UE_CHECKSUM, (ULONG_PTR)CheckSum);
return(true);
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL FixHeaderCheckSumW(wchar_t* szFileName)
{
DWORD HeaderSum = NULL;
DWORD CheckSum = NULL;
if(MapFileAndCheckSumW(szFileName, &HeaderSum, &CheckSum) == NULL)
{
SetPE32DataW(szFileName, NULL, UE_CHECKSUM, (ULONG_PTR)CheckSum);
return(true);
}
else
{
return(false);
}
}
__declspec(dllexport) long TITCALL RealignPE(ULONG_PTR FileMapVA, DWORD FileSize, DWORD RealingMode)
{
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
PIMAGE_SECTION_HEADER PESections;
DWORD NewVirtualSectionSize = 0;
DWORD NewSectionRawPointer = 0;
DWORD OldSectionDataRawPtr = 0;
DWORD OldSectionDataPtr = 0;
DWORD SectionDataPtr = 0;
DWORD SectionNumber = 0;
DWORD CurrentSection = 0;
DWORD FileAlignment = 0;
BOOL FileIs64;
if(FileMapVA != NULL)
{
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, NULL, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
return(-1);
}
if(!FileIs64)
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader32 + PEHeader32->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
SectionNumber = PEHeader32->FileHeader.NumberOfSections;
FileAlignment = PEHeader32->OptionalHeader.FileAlignment;
if(FileAlignment == 0x1000)
{
FileAlignment = 0x200;
}
__try
{
PEHeader32->OptionalHeader.FileAlignment = FileAlignment;
while(SectionNumber > 0)
{
SectionDataPtr = PESections->PointerToRawData + PESections->SizeOfRawData;
if(PESections->SizeOfRawData > NULL)
{
SectionDataPtr--;
while(*(PUCHAR)(FileMapVA + SectionDataPtr) == 0x00 && SectionDataPtr > PESections->PointerToRawData)
{
SectionDataPtr--;
}
}
SectionDataPtr = SectionDataPtr - PESections->PointerToRawData;
OldSectionDataPtr = SectionDataPtr;
SectionDataPtr = (SectionDataPtr / FileAlignment) * FileAlignment;
if(SectionDataPtr < OldSectionDataPtr)
{
SectionDataPtr = SectionDataPtr + FileAlignment;
}
if(CurrentSection == NULL)
{
PEHeader32->OptionalHeader.SizeOfHeaders = PESections->PointerToRawData;
PEHeader32->OptionalHeader.SectionAlignment = PESections->VirtualAddress;
PESections->SizeOfRawData = SectionDataPtr;
}
else
{
OldSectionDataRawPtr = PESections->PointerToRawData;
PESections->SizeOfRawData = SectionDataPtr;
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections - IMAGE_SIZEOF_SECTION_HEADER);
NewSectionRawPointer = PESections->PointerToRawData + PESections->SizeOfRawData;
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + IMAGE_SIZEOF_SECTION_HEADER);
PESections->PointerToRawData = NewSectionRawPointer;
RtlMoveMemory((LPVOID)((ULONG_PTR)FileMapVA + NewSectionRawPointer), (LPVOID)((ULONG_PTR)FileMapVA + OldSectionDataRawPtr), SectionDataPtr);
}
NewVirtualSectionSize = (PESections->Misc.VirtualSize / PEHeader32->OptionalHeader.SectionAlignment) * PEHeader32->OptionalHeader.SectionAlignment;
if(NewVirtualSectionSize < PESections->Misc.VirtualSize)
{
NewVirtualSectionSize = NewVirtualSectionSize + PEHeader32->OptionalHeader.SectionAlignment;
}
PESections->Misc.VirtualSize = NewVirtualSectionSize;
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + IMAGE_SIZEOF_SECTION_HEADER);
CurrentSection++;
SectionNumber--;
}
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections - IMAGE_SIZEOF_SECTION_HEADER);
return(PESections->PointerToRawData + PESections->SizeOfRawData);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return(-1);
}
}
else
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader64 + PEHeader64->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
SectionNumber = PEHeader64->FileHeader.NumberOfSections;
FileAlignment = PEHeader64->OptionalHeader.FileAlignment;
if(FileAlignment == 0x1000)
{
FileAlignment = 0x200;
}
__try
{
PEHeader64->OptionalHeader.FileAlignment = FileAlignment;
while(SectionNumber > 0)
{
SectionDataPtr = PESections->PointerToRawData + PESections->SizeOfRawData;
if(PESections->SizeOfRawData > NULL)
{
SectionDataPtr--;
while(*(PUCHAR)(FileMapVA + SectionDataPtr) == 0x00 && SectionDataPtr > PESections->PointerToRawData)
{
SectionDataPtr--;
}
}
SectionDataPtr = SectionDataPtr - PESections->PointerToRawData;
OldSectionDataPtr = SectionDataPtr;
SectionDataPtr = (SectionDataPtr / FileAlignment) * FileAlignment;
if(SectionDataPtr < OldSectionDataPtr)
{
SectionDataPtr = SectionDataPtr + FileAlignment;
}
if(CurrentSection == NULL)
{
PEHeader64->OptionalHeader.SizeOfHeaders = PESections->PointerToRawData;
PEHeader64->OptionalHeader.SectionAlignment = PESections->VirtualAddress;
PESections->SizeOfRawData = SectionDataPtr;
}
else
{
OldSectionDataRawPtr = PESections->PointerToRawData;
PESections->SizeOfRawData = SectionDataPtr;
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections - IMAGE_SIZEOF_SECTION_HEADER);
NewSectionRawPointer = PESections->PointerToRawData + PESections->SizeOfRawData;
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + IMAGE_SIZEOF_SECTION_HEADER);
PESections->PointerToRawData = NewSectionRawPointer;
RtlMoveMemory((LPVOID)((ULONG_PTR)FileMapVA + NewSectionRawPointer), (LPVOID)((ULONG_PTR)FileMapVA + OldSectionDataRawPtr), SectionDataPtr);
}
NewVirtualSectionSize = (PESections->Misc.VirtualSize / PEHeader64->OptionalHeader.SectionAlignment) * PEHeader64->OptionalHeader.SectionAlignment;
if(NewVirtualSectionSize < PESections->Misc.VirtualSize)
{
NewVirtualSectionSize = NewVirtualSectionSize + PEHeader64->OptionalHeader.SectionAlignment;
}
PESections->Misc.VirtualSize = NewVirtualSectionSize;
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + IMAGE_SIZEOF_SECTION_HEADER);
CurrentSection++;
SectionNumber--;
}
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections - IMAGE_SIZEOF_SECTION_HEADER);
return(PESections->PointerToRawData + PESections->SizeOfRawData);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return(-1);
}
}
}
else
{
return(-1);
}
}
return(-1);
}
__declspec(dllexport) long TITCALL RealignPEEx(char* szFileName, DWORD RealingFileSize, DWORD ForcedFileAlignment)
{
wchar_t uniFileName[MAX_PATH] = {};
if(szFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
return(RealignPEExW(uniFileName, RealingFileSize, ForcedFileAlignment));
}
else
{
return(-1);
}
}
__declspec(dllexport) long TITCALL RealignPEExW(wchar_t* szFileName, DWORD RealingFileSize, DWORD ForcedFileAlignment)
{
wchar_t szBackupFile[MAX_PATH] = {};
wchar_t szBackupItem[MAX_PATH] = {};
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
PIMAGE_SECTION_HEADER PESections;
DWORD NewVirtualSectionSize = 0;
DWORD NewSectionRawPointer = 0;
DWORD OldSectionDataRawPtr = 0;
DWORD OldSectionDataPtr = 0;
DWORD SectionDataPtr = 0;
DWORD SectionNumber = 0;
DWORD CurrentSection = 0;
BOOL FileIs64;
HANDLE FileHandle;
DWORD FileSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
if(engineBackupForCriticalFunctions && CreateGarbageItem(&szBackupItem, sizeof szBackupItem))
{
if(!FillGarbageItem(szBackupItem, szFileName, &szBackupFile, sizeof szBackupItem))
{
RtlZeroMemory(&szBackupItem, sizeof szBackupItem);
lstrcpyW(szBackupFile, szFileName);
}
}
else
{
RtlZeroMemory(&szBackupItem, sizeof szBackupItem);
lstrcpyW(szBackupFile, szFileName);
}
if(MapFileExW(szBackupFile, UE_ACCESS_ALL, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, FileHandle, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
RemoveGarbageItem(szBackupItem, true);
return(-1);
}
if(!FileIs64)
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader32 + PEHeader32->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
SectionNumber = PEHeader32->FileHeader.NumberOfSections;
if(ForcedFileAlignment == 0x0)
{
ForcedFileAlignment = 0x200;
}
__try
{
PEHeader32->OptionalHeader.FileAlignment = ForcedFileAlignment;
while(SectionNumber > 0)
{
SectionDataPtr = PESections->PointerToRawData + PESections->SizeOfRawData;
if(PESections->SizeOfRawData > NULL)
{
SectionDataPtr--;
while(*(PUCHAR)(FileMapVA + SectionDataPtr) == 0x00 && SectionDataPtr > PESections->PointerToRawData)
{
SectionDataPtr--;
}
}
SectionDataPtr = SectionDataPtr - PESections->PointerToRawData;
OldSectionDataPtr = SectionDataPtr;
SectionDataPtr = (SectionDataPtr / ForcedFileAlignment) * ForcedFileAlignment;
if(SectionDataPtr < OldSectionDataPtr)
{
SectionDataPtr = SectionDataPtr + ForcedFileAlignment;
}
if(CurrentSection == NULL)
{
PEHeader32->OptionalHeader.SizeOfHeaders = PESections->PointerToRawData;
PEHeader32->OptionalHeader.SectionAlignment = PESections->VirtualAddress;
PESections->SizeOfRawData = SectionDataPtr;
}
else
{
OldSectionDataRawPtr = PESections->PointerToRawData;
PESections->SizeOfRawData = SectionDataPtr;
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections - IMAGE_SIZEOF_SECTION_HEADER);
NewSectionRawPointer = PESections->PointerToRawData + PESections->SizeOfRawData;
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + IMAGE_SIZEOF_SECTION_HEADER);
PESections->PointerToRawData = NewSectionRawPointer;
RtlMoveMemory((LPVOID)((ULONG_PTR)FileMapVA + NewSectionRawPointer), (LPVOID)((ULONG_PTR)FileMapVA + OldSectionDataRawPtr), SectionDataPtr);
}
NewVirtualSectionSize = (PESections->Misc.VirtualSize / PEHeader32->OptionalHeader.SectionAlignment) * PEHeader32->OptionalHeader.SectionAlignment;
if(NewVirtualSectionSize < PESections->Misc.VirtualSize)
{
NewVirtualSectionSize = NewVirtualSectionSize + PEHeader32->OptionalHeader.SectionAlignment;
}
PESections->Misc.VirtualSize = NewVirtualSectionSize;
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + IMAGE_SIZEOF_SECTION_HEADER);
CurrentSection++;
SectionNumber--;
}
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections - IMAGE_SIZEOF_SECTION_HEADER);
if(RealingFileSize == NULL)
{
FileSize = PESections->PointerToRawData + PESections->SizeOfRawData;
}
else
{
FileSize = RealingFileSize;
}
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
if(szBackupItem[0] != NULL)
{
if(CopyFileW(szBackupFile, szFileName, false))
{
RemoveGarbageItem(szBackupItem, true);
return(FileSize);
}
else
{
RemoveGarbageItem(szBackupItem, true);
return(-1);
}
}
else
{
return(FileSize);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
RemoveGarbageItem(szBackupItem, true);
return(-1);
}
}
else
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader64 + PEHeader64->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
SectionNumber = PEHeader64->FileHeader.NumberOfSections;
if(ForcedFileAlignment == 0x0)
{
ForcedFileAlignment = 0x200;
}
__try
{
PEHeader64->OptionalHeader.FileAlignment = ForcedFileAlignment;
while(SectionNumber > 0)
{
SectionDataPtr = PESections->PointerToRawData + PESections->SizeOfRawData;
if(PESections->SizeOfRawData > NULL)
{
SectionDataPtr--;
while(*(PUCHAR)(FileMapVA + SectionDataPtr) == 0x00 && SectionDataPtr > PESections->PointerToRawData)
{
SectionDataPtr--;
}
}
SectionDataPtr = SectionDataPtr - PESections->PointerToRawData;
OldSectionDataPtr = SectionDataPtr;
SectionDataPtr = (SectionDataPtr / ForcedFileAlignment) * ForcedFileAlignment;
if(SectionDataPtr < OldSectionDataPtr)
{
SectionDataPtr = SectionDataPtr + ForcedFileAlignment;
}
if(CurrentSection == NULL)
{
PEHeader64->OptionalHeader.SizeOfHeaders = PESections->PointerToRawData;
PEHeader64->OptionalHeader.SectionAlignment = PESections->VirtualAddress;
PESections->SizeOfRawData = SectionDataPtr;
}
else
{
OldSectionDataRawPtr = PESections->PointerToRawData;
PESections->SizeOfRawData = SectionDataPtr;
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections - IMAGE_SIZEOF_SECTION_HEADER);
NewSectionRawPointer = PESections->PointerToRawData + PESections->SizeOfRawData;
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + IMAGE_SIZEOF_SECTION_HEADER);
PESections->PointerToRawData = NewSectionRawPointer;
RtlMoveMemory((LPVOID)((ULONG_PTR)FileMapVA + NewSectionRawPointer), (LPVOID)((ULONG_PTR)FileMapVA + OldSectionDataRawPtr), SectionDataPtr);
}
NewVirtualSectionSize = (PESections->Misc.VirtualSize / PEHeader64->OptionalHeader.SectionAlignment) * PEHeader64->OptionalHeader.SectionAlignment;
if(NewVirtualSectionSize < PESections->Misc.VirtualSize)
{
NewVirtualSectionSize = NewVirtualSectionSize + PEHeader64->OptionalHeader.SectionAlignment;
}
PESections->Misc.VirtualSize = NewVirtualSectionSize;
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + IMAGE_SIZEOF_SECTION_HEADER);
CurrentSection++;
SectionNumber--;
}
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections - IMAGE_SIZEOF_SECTION_HEADER);
if(RealingFileSize == NULL)
{
FileSize = PESections->PointerToRawData + PESections->SizeOfRawData;
}
else
{
FileSize = RealingFileSize;
}
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
if(szBackupItem[0] != NULL)
{
if(CopyFileW(szBackupFile, szFileName, false))
{
RemoveGarbageItem(szBackupItem, true);
return(FileSize);
}
else
{
RemoveGarbageItem(szBackupItem, true);
return(-1);
}
}
else
{
return(FileSize);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
RemoveGarbageItem(szBackupItem, true);
return(-1);
}
}
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
RemoveGarbageItem(szBackupItem, true);
return(-1);
}
}
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
RemoveGarbageItem(szBackupItem, true);
return(-1);
}
__declspec(dllexport) bool TITCALL WipeSection(char* szFileName, int WipeSectionNumber, bool RemovePhysically)
{
wchar_t uniFileName[MAX_PATH] = {};
if(szFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
return(WipeSectionW(uniFileName, WipeSectionNumber, RemovePhysically));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL WipeSectionW(wchar_t* szFileName, int WipeSectionNumber, bool RemovePhysically)
{
wchar_t szBackupFile[MAX_PATH] = {};
wchar_t szBackupItem[MAX_PATH] = {};
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
PIMAGE_SECTION_HEADER PESections;
DWORD NewVirtualSectionSize = 0;
DWORD NewSectionRawPointer = 0;
DWORD OldSectionDataRawPtr = 0;
DWORD OldSectionDataPtr = 0;
DWORD CurrentSectionPSize = 0;
DWORD WipeSectionVirSize = 0;
DWORD WipeSectionSize = 0;
DWORD SectionDataPtr = 0;
DWORD FileAlignment = 0;
int SectionNumber = 0;
BOOL FileIs64;
HANDLE FileHandle;
DWORD FileSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
if(engineBackupForCriticalFunctions && CreateGarbageItem(&szBackupItem, sizeof szBackupItem))
{
if(!FillGarbageItem(szBackupItem, szFileName, &szBackupFile, sizeof szBackupItem))
{
RtlZeroMemory(&szBackupItem, sizeof szBackupItem);
lstrcpyW(szBackupFile, szFileName);
}
}
else
{
RtlZeroMemory(&szBackupItem, sizeof szBackupItem);
lstrcpyW(szBackupFile, szFileName);
}
if(MapFileExW(szBackupFile, UE_ACCESS_ALL, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, FileHandle, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
RemoveGarbageItem(szBackupItem, true);
return(false);
}
if(!FileIs64)
{
if(WipeSectionNumber != -1 && WipeSectionNumber <= PEHeader32->FileHeader.NumberOfSections)
{
WipeSectionVirSize = (DWORD)GetPE32DataFromMappedFile(FileMapVA, WipeSectionNumber, UE_SECTIONVIRTUALSIZE);
WipeSectionSize = (DWORD)GetPE32DataFromMappedFile(FileMapVA, WipeSectionNumber, UE_SECTIONRAWSIZE);
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader32 + PEHeader32->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
FileAlignment = PEHeader32->OptionalHeader.FileAlignment;
__try
{
while(SectionNumber < PEHeader32->FileHeader.NumberOfSections)
{
if(SectionNumber == WipeSectionNumber - 1)
{
CurrentSectionPSize = PESections->SizeOfRawData;
if(CurrentSectionPSize % FileAlignment == NULL)
{
CurrentSectionPSize = ((CurrentSectionPSize / FileAlignment)) * FileAlignment;
}
else
{
CurrentSectionPSize = ((CurrentSectionPSize / FileAlignment) + 1) * FileAlignment;
}
PESections->SizeOfRawData = CurrentSectionPSize;
WipeSectionVirSize = WipeSectionVirSize + PESections->Misc.VirtualSize;
if(WipeSectionVirSize % PEHeader32->OptionalHeader.SectionAlignment == NULL)
{
WipeSectionVirSize = ((WipeSectionVirSize / PEHeader32->OptionalHeader.SectionAlignment)) * PEHeader32->OptionalHeader.SectionAlignment;
}
else
{
WipeSectionVirSize = ((WipeSectionVirSize / PEHeader32->OptionalHeader.SectionAlignment) + 1) * PEHeader32->OptionalHeader.SectionAlignment;
}
PESections->Misc.VirtualSize = WipeSectionVirSize;
CurrentSectionPSize = CurrentSectionPSize - PESections->SizeOfRawData;
WipeSectionSize = WipeSectionSize - CurrentSectionPSize;
}
else if(SectionNumber > WipeSectionNumber)
{
RtlMoveMemory((LPVOID)((ULONG_PTR)PESections - IMAGE_SIZEOF_SECTION_HEADER), (LPVOID)PESections, IMAGE_SIZEOF_SECTION_HEADER);
}
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + IMAGE_SIZEOF_SECTION_HEADER);
SectionNumber++;
}
RtlZeroMemory((LPVOID)PESections, IMAGE_SIZEOF_SECTION_HEADER);
PEHeader32->FileHeader.NumberOfSections--;
if(RemovePhysically)
{
FileSize = RealignPE(FileMapVA, FileSize, NULL);
}
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
if(szBackupItem[0] != NULL)
{
if(CopyFileW(szBackupFile, szFileName, false))
{
RemoveGarbageItem(szBackupItem, true);
return(true);
}
else
{
RemoveGarbageItem(szBackupItem, true);
return(false);
}
}
else
{
return(true);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
RemoveGarbageItem(szBackupItem, true);
return(false);
}
}
}
else
{
if(WipeSectionNumber != -1 && WipeSectionNumber <= PEHeader64->FileHeader.NumberOfSections)
{
WipeSectionVirSize = (DWORD)GetPE32DataFromMappedFile(FileMapVA, WipeSectionNumber, UE_SECTIONVIRTUALOFFSET);
WipeSectionVirSize = WipeSectionVirSize + (DWORD)GetPE32DataFromMappedFile(FileMapVA, WipeSectionNumber, UE_SECTIONVIRTUALSIZE);
if(WipeSectionVirSize % PEHeader32->OptionalHeader.SectionAlignment == NULL)
{
WipeSectionVirSize = ((WipeSectionVirSize / PEHeader32->OptionalHeader.SectionAlignment)) * PEHeader32->OptionalHeader.SectionAlignment;
}
else
{
WipeSectionVirSize = ((WipeSectionVirSize / PEHeader32->OptionalHeader.SectionAlignment) + 1) * PEHeader32->OptionalHeader.SectionAlignment;
}
WipeSectionSize = (DWORD)GetPE32DataFromMappedFile(FileMapVA, WipeSectionNumber, UE_SECTIONRAWSIZE);
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader64 + PEHeader64->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
FileAlignment = PEHeader64->OptionalHeader.FileAlignment;
__try
{
while(SectionNumber < PEHeader64->FileHeader.NumberOfSections)
{
if(SectionNumber == WipeSectionNumber - 1)
{
CurrentSectionPSize = PESections->SizeOfRawData;
if(CurrentSectionPSize % FileAlignment == NULL)
{
CurrentSectionPSize = ((CurrentSectionPSize / FileAlignment)) * FileAlignment;
}
else
{
CurrentSectionPSize = ((CurrentSectionPSize / FileAlignment) + 1) * FileAlignment;
}
PESections->SizeOfRawData = CurrentSectionPSize;
WipeSectionVirSize = WipeSectionVirSize + PESections->Misc.VirtualSize;
if(WipeSectionVirSize % PEHeader64->OptionalHeader.SectionAlignment == NULL)
{
WipeSectionVirSize = ((WipeSectionVirSize / PEHeader64->OptionalHeader.SectionAlignment)) * PEHeader64->OptionalHeader.SectionAlignment;
}
else
{
WipeSectionVirSize = ((WipeSectionVirSize / PEHeader64->OptionalHeader.SectionAlignment) + 1) * PEHeader64->OptionalHeader.SectionAlignment;
}
PESections->Misc.VirtualSize = WipeSectionVirSize;
CurrentSectionPSize = CurrentSectionPSize - PESections->SizeOfRawData;
WipeSectionSize = WipeSectionSize - CurrentSectionPSize;
}
else if(SectionNumber > WipeSectionNumber)
{
RtlMoveMemory((LPVOID)((ULONG_PTR)PESections - IMAGE_SIZEOF_SECTION_HEADER), (LPVOID)PESections, IMAGE_SIZEOF_SECTION_HEADER);
}
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + IMAGE_SIZEOF_SECTION_HEADER);
SectionNumber++;
}
RtlZeroMemory((LPVOID)PESections, IMAGE_SIZEOF_SECTION_HEADER);
PEHeader64->FileHeader.NumberOfSections--;
if(RemovePhysically)
{
FileSize = RealignPE(FileMapVA, FileSize, NULL);
}
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
if(szBackupItem[0] != NULL)
{
if(CopyFileW(szBackupFile, szFileName, false))
{
RemoveGarbageItem(szBackupItem, true);
return(true);
}
else
{
RemoveGarbageItem(szBackupItem, true);
return(false);
}
}
else
{
return(true);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
RemoveGarbageItem(szBackupItem, true);
return(false);
}
}
}
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
RemoveGarbageItem(szBackupItem, true);
return(false);
}
}
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
RemoveGarbageItem(szBackupItem, true);
return(false);
}
__declspec(dllexport) bool TITCALL IsPE32FileValidEx(char* szFileName, DWORD CheckDepth, LPVOID FileStatusInfo)
{
wchar_t uniFileName[MAX_PATH] = {};
if(szFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
return(IsPE32FileValidExW(uniFileName, CheckDepth, FileStatusInfo));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL IsPE32FileValidExW(wchar_t* szFileName, DWORD CheckDepth, LPVOID FileStatusInfo)
{
unsigned int i;
ULONG_PTR ReadData = NULL;
DWORD ReadSize = 0;
WORD ReadDataWORD = 0;
ULONG_PTR hSimulatedFileLoad;
long SectionNumber = 0;
DWORD SectionAttributes = 0;
ULONG_PTR ConvertedAddress = NULL;
DWORD CorrectedImageSize = 0;
DWORD SectionVirtualSize = 0;
DWORD SectionVirtualSizeFixed = 0;
DWORD NumberOfSections = 0;
FILE_STATUS_INFO myFileStatusInfo;
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
PIMAGE_SECTION_HEADER PESections;
PIMAGE_EXPORT_DIRECTORY PEExports;
PIMAGE_TLS_DIRECTORY32 PETls32;
PIMAGE_TLS_DIRECTORY64 PETls64;
PIMAGE_IMPORT_DESCRIPTOR ImportIID;
PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundIID;
PIMAGE_THUNK_DATA32 ThunkData32;
PIMAGE_THUNK_DATA64 ThunkData64;
bool hLoadedModuleSimulated = false;
HMODULE hLoadedModule;
ULONG_PTR ImportNamePtr;
ULONG_PTR CurrentThunk;
BOOL FileIsDLL = false;
BOOL FileIs64;
HANDLE FileHandle;
DWORD FileSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
WORD ResourceNamesTable[22] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, 17, 18, 19, 20, 21, 22, 23, 24};
RtlZeroMemory(&myFileStatusInfo, sizeof FILE_STATUS_INFO);
if(MapFileExW(szFileName, UE_ACCESS_READ, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
myFileStatusInfo.OveralEvaluation = UE_RESULT_FILE_OK;
if(EngineValidateHeader(FileMapVA, FileHandle, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->Signature == 0x4550 && PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->Signature == 0x4550 && PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
myFileStatusInfo.FileIs64Bit = true;
}
else
{
myFileStatusInfo.OveralEvaluation = UE_RESULT_FILE_INVALID_FORMAT;
myFileStatusInfo.SignaturePE = UE_FIELD_BROKEN_NON_FIXABLE;
if(FileStatusInfo != NULL)
{
RtlMoveMemory(FileStatusInfo, &myFileStatusInfo, sizeof FILE_STATUS_INFO);
}
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
if(!FileIs64)
{
/*
x86 Surface check
*/
__try
{
if(PEHeader32->OptionalHeader.SizeOfImage % PEHeader32->OptionalHeader.SectionAlignment == NULL)
{
CorrectedImageSize = ((PEHeader32->OptionalHeader.SizeOfImage / PEHeader32->OptionalHeader.SectionAlignment)) * PEHeader32->OptionalHeader.SectionAlignment;
}
else
{
CorrectedImageSize = ((PEHeader32->OptionalHeader.SizeOfImage / PEHeader32->OptionalHeader.SectionAlignment) + 1) * PEHeader32->OptionalHeader.SectionAlignment;
}
if(PEHeader32->OptionalHeader.SectionAlignment != NULL && PEHeader32->OptionalHeader.SectionAlignment >= PEHeader32->OptionalHeader.FileAlignment)
{
myFileStatusInfo.SectionAlignment = UE_FIELD_OK;
if(PEHeader32->OptionalHeader.SizeOfImage % PEHeader32->OptionalHeader.SectionAlignment == NULL)
{
myFileStatusInfo.SizeOfImage = UE_FIELD_OK;
}
else
{
if(CorrectedImageSize < PEHeader32->OptionalHeader.AddressOfEntryPoint)
{
myFileStatusInfo.SizeOfImage = UE_FIELD_BROKEN_NON_FIXABLE;
}
else
{
myFileStatusInfo.SizeOfImage = UE_FILED_FIXABLE_NON_CRITICAL;
}
}
}
else
{
myFileStatusInfo.SectionAlignment = UE_FILED_FIXABLE_CRITICAL;
}
SetOverallFileStatus(&myFileStatusInfo, myFileStatusInfo.SectionAlignment, true);
if(PEHeader32->OptionalHeader.ImageBase % 0x1000 == NULL)
{
myFileStatusInfo.ImageBase = UE_FIELD_OK;
}
else
{
myFileStatusInfo.ImageBase = UE_FIELD_BROKEN_NON_FIXABLE;
}
SetOverallFileStatus(&myFileStatusInfo, myFileStatusInfo.ImageBase, true);
if(PEHeader32->OptionalHeader.FileAlignment % 2 == NULL)
{
myFileStatusInfo.FileAlignment = UE_FIELD_OK;
}
else
{
myFileStatusInfo.FileAlignment = UE_FILED_FIXABLE_CRITICAL;
}
SetOverallFileStatus(&myFileStatusInfo, myFileStatusInfo.FileAlignment, false);
/*
Get the console flag
*/
if(PEHeader32->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI)
{
myFileStatusInfo.FileIsConsole = true;
}
/*
Export and relocation checks [for DLL and EXE]
*/
if(PEHeader32->FileHeader.Characteristics & 0x2000)
{
/*
Export table check
*/
FileIsDLL = true;
myFileStatusInfo.FileIsDLL = true;
if(PEHeader32->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_EXPORT && PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress != NULL)
{
if(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress > CorrectedImageSize || PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size > CorrectedImageSize)
{
myFileStatusInfo.ExportTable = UE_FIELD_BROKEN_NON_FIXABLE;
}
else
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + PEHeader32->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress != NULL)
{
if(EngineIsBadReadPtrEx((LPVOID)ConvertedAddress, PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size))
{
PEExports = (PIMAGE_EXPORT_DIRECTORY)ConvertedAddress;
if(PEExports->AddressOfFunctions > CorrectedImageSize || PEExports->AddressOfFunctions + 4 * PEExports->NumberOfFunctions > CorrectedImageSize)
{
myFileStatusInfo.ExportTable = UE_FIELD_BROKEN_NON_FIXABLE;
}
else if(PEExports->AddressOfNameOrdinals > CorrectedImageSize || PEExports->AddressOfNameOrdinals + 4 * PEExports->NumberOfNames > CorrectedImageSize)
{
myFileStatusInfo.ExportTable = UE_FIELD_BROKEN_NON_FIXABLE;
}
else if(PEExports->AddressOfNames > CorrectedImageSize || PEExports->AddressOfNames + 4 * PEExports->NumberOfNames > CorrectedImageSize)
{
myFileStatusInfo.ExportTable = UE_FIELD_BROKEN_NON_FIXABLE;
}
else if(PEExports->Name > CorrectedImageSize)
{
myFileStatusInfo.ExportTable = UE_FIELD_BROKEN_NON_FIXABLE;
}
else
{
if(CheckDepth == UE_DEPTH_DEEP)
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEExports->AddressOfFunctions + PEHeader32->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress != NULL)
{
for(i = 0; i < PEExports->NumberOfFunctions; i++)
{
RtlMoveMemory(&ReadData, (LPVOID)ConvertedAddress, 4);
if(ReadData > CorrectedImageSize || ReadData < PEHeader32->OptionalHeader.SectionAlignment)
{
myFileStatusInfo.ExportTable = UE_FIELD_BROKEN_NON_FIXABLE;
i = PEExports->NumberOfFunctions;
}
else
{
ConvertedAddress = ConvertedAddress + 4;
}
}
}
else
{
myFileStatusInfo.ExportTable = UE_FIELD_BROKEN_NON_FIXABLE;
}
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEExports->AddressOfNames + PEHeader32->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress != NULL)
{
for(i = 0; i < PEExports->NumberOfNames; i++)
{
RtlMoveMemory(&ReadData, (LPVOID)ConvertedAddress, 4);
if(ReadData > CorrectedImageSize || ReadData < PEHeader32->OptionalHeader.SectionAlignment)
{
myFileStatusInfo.ExportTable = UE_FIELD_BROKEN_NON_FIXABLE;
i = PEExports->NumberOfNames;
}
else
{
ConvertedAddress = ConvertedAddress + 4;
}
}
}
else
{
myFileStatusInfo.ExportTable = UE_FIELD_BROKEN_NON_FIXABLE;
}
}
}
}
else
{
myFileStatusInfo.ExportTable = UE_FIELD_BROKEN_NON_FIXABLE;
}
}
else
{
myFileStatusInfo.ExportTable = UE_FIELD_BROKEN_NON_FIXABLE;
}
}
SetOverallFileStatus(&myFileStatusInfo, myFileStatusInfo.ExportTable, true);
}
else
{
myFileStatusInfo.ExportTable = UE_FIELD_NOT_PRESET;
}
/*
Relocation table check
*/
if(PEHeader32->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_BASERELOC && PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress != NULL)
{
if(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress > CorrectedImageSize || PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress + PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size > CorrectedImageSize)
{
myFileStatusInfo.RelocationTable = UE_FIELD_BROKEN_NON_FIXABLE;
}
else
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress + PEHeader32->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress != NULL)
{
if(EngineIsBadReadPtrEx((LPVOID)ConvertedAddress, PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size))
{
RtlMoveMemory(&ReadData, (LPVOID)ConvertedAddress, 4);
RtlMoveMemory(&ReadSize, (LPVOID)(ConvertedAddress + 4), 4);
while(ReadData != NULL)
{
ReadSize = ReadSize - 8;
ConvertedAddress = ConvertedAddress + 8;
while(ReadSize > NULL)
{
RtlMoveMemory(&ReadDataWORD, (LPVOID)ConvertedAddress, 2);
if(ReadDataWORD > 0xCFFF)
{
myFileStatusInfo.RelocationTable = UE_FIELD_BROKEN_FIXABLE_FOR_STATIC_USE;
}
ConvertedAddress = ConvertedAddress + 2;
ReadSize = ReadSize - 2;
}
RtlMoveMemory(&ReadData, (LPVOID)ConvertedAddress, 4);
RtlMoveMemory(&ReadSize, (LPVOID)(ConvertedAddress + 4), 4);
}
}
else
{
myFileStatusInfo.RelocationTable = UE_FIELD_BROKEN_FIXABLE_FOR_STATIC_USE;
}
}
else
{
myFileStatusInfo.RelocationTable = UE_FIELD_BROKEN_FIXABLE_FOR_STATIC_USE;
}
}
SetOverallFileStatus(&myFileStatusInfo, myFileStatusInfo.RelocationTable, true);
}
else
{
myFileStatusInfo.RelocationTable = UE_FIELD_NOT_PRESET_WARNING;
}
}
else
{
/*
Export table check
*/
if(PEHeader32->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_EXPORT && PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress != NULL)
{
if(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress > CorrectedImageSize || PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size > CorrectedImageSize)
{
myFileStatusInfo.ExportTable = UE_FIELD_BROKEN_NON_CRITICAL;
}
else
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + PEHeader32->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress != NULL)
{
if(EngineIsBadReadPtrEx((LPVOID)ConvertedAddress, PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size))
{
PEExports = (PIMAGE_EXPORT_DIRECTORY)ConvertedAddress;
if(PEExports->AddressOfFunctions > CorrectedImageSize || PEExports->AddressOfFunctions + 4 * PEExports->NumberOfFunctions > CorrectedImageSize)
{
myFileStatusInfo.ExportTable = UE_FIELD_BROKEN_NON_CRITICAL;
}
else if(PEExports->AddressOfNameOrdinals > CorrectedImageSize || PEExports->AddressOfNameOrdinals + 4 * PEExports->NumberOfNames > CorrectedImageSize)
{
myFileStatusInfo.ExportTable = UE_FIELD_BROKEN_NON_CRITICAL;
}
else if(PEExports->AddressOfNames > CorrectedImageSize || PEExports->AddressOfNames + 4 * PEExports->NumberOfNames > CorrectedImageSize)
{
myFileStatusInfo.ExportTable = UE_FIELD_BROKEN_NON_CRITICAL;
}
else if(PEExports->Name > CorrectedImageSize)
{
myFileStatusInfo.ExportTable = UE_FIELD_BROKEN_NON_CRITICAL;
}
}
else
{
myFileStatusInfo.ExportTable = UE_FIELD_BROKEN_NON_CRITICAL;
}
}
}
SetOverallFileStatus(&myFileStatusInfo, myFileStatusInfo.ExportTable, false);
}
else
{
myFileStatusInfo.ExportTable = UE_FIELD_NOT_PRESET;
}
/*
Relocation table check
*/
if(PEHeader32->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_BASERELOC && PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress != NULL)
{
if(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress > CorrectedImageSize || PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress + PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size > CorrectedImageSize)
{
myFileStatusInfo.RelocationTable = UE_FIELD_BROKEN_NON_FIXABLE;
}
else
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress + PEHeader32->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress == NULL || ConvertedAddress - FileMapVA > FileSize)
{
myFileStatusInfo.RelocationTable = UE_FILED_FIXABLE_NON_CRITICAL;
}
}
SetOverallFileStatus(&myFileStatusInfo, myFileStatusInfo.RelocationTable, false);
}
else
{
myFileStatusInfo.RelocationTable = UE_FIELD_NOT_PRESET;
}
}
/*
Import table check
*/
if(PEHeader32->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_IMPORT && PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress != NULL)
{
if(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress > CorrectedImageSize)
{
myFileStatusInfo.ImportTable = UE_FIELD_BROKEN_NON_FIXABLE;
}
else
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + PEHeader32->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress == NULL || ConvertedAddress - FileMapVA > FileSize)
{
myFileStatusInfo.ImportTable = UE_FIELD_BROKEN_NON_FIXABLE;
}
else
{
SectionNumber = GetPE32SectionNumberFromVA(FileMapVA, PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + PEHeader32->OptionalHeader.ImageBase);
if(SectionNumber < 0x7FFFFFFF)
{
SectionAttributes = (DWORD)GetPE32DataFromMappedFile(FileMapVA, SectionNumber, UE_SECTIONFLAGS);
if(SectionAttributes & IMAGE_SCN_MEM_EXECUTE || SectionAttributes & IMAGE_SCN_CNT_CODE || SectionAttributes & IMAGE_SCN_MEM_WRITE || SectionAttributes & IMAGE_SCN_CNT_INITIALIZED_DATA)
{
myFileStatusInfo.ImportTableSection = UE_FIELD_OK;
}
else
{
myFileStatusInfo.ImportTableSection = UE_FILED_FIXABLE_CRITICAL;
}
if(CheckDepth == UE_DEPTH_DEEP)
{
if(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress != NULL)
{
ImportIID = (PIMAGE_IMPORT_DESCRIPTOR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, (ULONG_PTR)PEHeader32->OptionalHeader.ImageBase, (ULONG_PTR)(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + PEHeader32->OptionalHeader.ImageBase), false, true);
while(myFileStatusInfo.ImportTableData == UE_FIELD_OK && ImportIID->FirstThunk != NULL)
{
hLoadedModule = NULL;
ImportNamePtr = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, (ULONG_PTR)PEHeader32->OptionalHeader.ImageBase, (ULONG_PTR)((ULONG_PTR)ImportIID->Name + PEHeader32->OptionalHeader.ImageBase), false, true);
if(ImportNamePtr != NULL)
{
if(!EngineIsDependencyPresent((char*)ImportNamePtr, NULL, NULL))
{
myFileStatusInfo.MissingDependencies = true;
hLoadedModuleSimulated = false;
}
else
{
hLoadedModuleSimulated = false;
hLoadedModule = GetModuleHandleA((char*)ImportNamePtr);
if(hLoadedModule == NULL)
{
hLoadedModule = (HMODULE)EngineSimulateDllLoader(GetCurrentProcess(), (char*)ImportNamePtr);
hLoadedModuleSimulated = true;
}
}
}
else
{
myFileStatusInfo.ImportTableData = UE_FIELD_BROKEN_NON_FIXABLE;
}
if(ImportIID->OriginalFirstThunk != NULL)
{
ThunkData32 = (PIMAGE_THUNK_DATA32)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, (ULONG_PTR)PEHeader32->OptionalHeader.ImageBase, (ULONG_PTR)((ULONG_PTR)ImportIID->OriginalFirstThunk + PEHeader32->OptionalHeader.ImageBase), false, true);
CurrentThunk = (ULONG_PTR)ImportIID->OriginalFirstThunk;
}
else
{
ThunkData32 = (PIMAGE_THUNK_DATA32)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, (ULONG_PTR)PEHeader32->OptionalHeader.ImageBase, (ULONG_PTR)((ULONG_PTR)ImportIID->FirstThunk + PEHeader32->OptionalHeader.ImageBase), false, true);
CurrentThunk = (ULONG_PTR)ImportIID->FirstThunk;
}
if(ThunkData32 != NULL)
{
while(myFileStatusInfo.ImportTableData == UE_FIELD_OK && ThunkData32->u1.AddressOfData != NULL)
{
if(ThunkData32->u1.Ordinal & IMAGE_ORDINAL_FLAG32)
{
if((int)(ThunkData32->u1.Ordinal ^ IMAGE_ORDINAL_FLAG32) >= 0x10000)
{
myFileStatusInfo.ImportTableData = UE_FIELD_BROKEN_NON_FIXABLE;
}
}
else
{
ImportNamePtr = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, (ULONG_PTR)PEHeader32->OptionalHeader.ImageBase, (ULONG_PTR)((ULONG_PTR)ThunkData32->u1.AddressOfData + 2 + PEHeader32->OptionalHeader.ImageBase), false, true);
if(ImportNamePtr != NULL)
{
if(!EngineIsBadReadPtrEx((LPVOID)ImportNamePtr, 8))
{
myFileStatusInfo.ImportTableData = UE_FIELD_BROKEN_NON_FIXABLE;
}
else
{
if(hLoadedModule != NULL)
{
if(EngineGetProcAddress((ULONG_PTR)hLoadedModule, (char*)ImportNamePtr) == NULL)
{
myFileStatusInfo.MissingDeclaredAPIs = true;
SetOverallFileStatus(&myFileStatusInfo, UE_FILED_FIXABLE_CRITICAL, true);
}
}
}
}
else
{
myFileStatusInfo.ImportTableData = UE_FIELD_BROKEN_NON_FIXABLE;
}
}
CurrentThunk = CurrentThunk + 4;
ThunkData32 = (PIMAGE_THUNK_DATA32)((ULONG_PTR)ThunkData32 + sizeof IMAGE_THUNK_DATA32);
}
}
else
{
myFileStatusInfo.ImportTableData = UE_FIELD_BROKEN_NON_FIXABLE;
}
if(hLoadedModuleSimulated)
{
VirtualFree((LPVOID)hLoadedModule, NULL, MEM_RELEASE);
}
ImportIID = (PIMAGE_IMPORT_DESCRIPTOR)((ULONG_PTR)ImportIID + sizeof IMAGE_IMPORT_DESCRIPTOR);
}
}
}
}
else
{
myFileStatusInfo.ImportTable = UE_FIELD_BROKEN_NON_FIXABLE;
}
}
}
SetOverallFileStatus(&myFileStatusInfo, myFileStatusInfo.ImportTable, true);
SetOverallFileStatus(&myFileStatusInfo, myFileStatusInfo.ImportTableData, true);
SetOverallFileStatus(&myFileStatusInfo, myFileStatusInfo.ImportTableSection, true);
}
else
{
myFileStatusInfo.ImportTable = UE_FIELD_NOT_PRESET;
}
/*
TLS table check
*/
if(PEHeader32->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_TLS && PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress != NULL)
{
if(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress > CorrectedImageSize || PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress + PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size > CorrectedImageSize)
{
myFileStatusInfo.TLSTable = UE_FILED_FIXABLE_CRITICAL;
}
else
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress + PEHeader32->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress == NULL || ConvertedAddress - FileMapVA > FileSize)
{
myFileStatusInfo.TLSTable = UE_FILED_FIXABLE_CRITICAL;
}
else
{
PETls32 = (PIMAGE_TLS_DIRECTORY32)ConvertedAddress;
if(PETls32->StartAddressOfRawData != NULL && (PETls32->StartAddressOfRawData < PEHeader32->OptionalHeader.ImageBase || PETls32->StartAddressOfRawData > CorrectedImageSize + PEHeader32->OptionalHeader.ImageBase))
{
myFileStatusInfo.TLSTable = UE_FILED_FIXABLE_CRITICAL;
}
else if(PETls32->EndAddressOfRawData != NULL && (PETls32->EndAddressOfRawData < PEHeader32->OptionalHeader.ImageBase || PETls32->EndAddressOfRawData > CorrectedImageSize + PEHeader32->OptionalHeader.ImageBase))
{
myFileStatusInfo.TLSTable = UE_FILED_FIXABLE_CRITICAL;
}
else if(PETls32->AddressOfIndex != NULL && (PETls32->AddressOfIndex < PEHeader32->OptionalHeader.ImageBase || PETls32->AddressOfIndex > CorrectedImageSize + PEHeader32->OptionalHeader.ImageBase))
{
myFileStatusInfo.TLSTable = UE_FILED_FIXABLE_CRITICAL;
}
else if(PETls32->AddressOfCallBacks != NULL && (PETls32->AddressOfCallBacks < PEHeader32->OptionalHeader.ImageBase || PETls32->AddressOfCallBacks > CorrectedImageSize + PEHeader32->OptionalHeader.ImageBase))
{
myFileStatusInfo.TLSTable = UE_FILED_FIXABLE_CRITICAL;
}
if(PETls32->AddressOfCallBacks != NULL && CheckDepth == UE_DEPTH_DEEP)
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PETls32->AddressOfCallBacks + PEHeader32->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress != NULL)
{
while(ReadData != NULL)
{
RtlMoveMemory(&ReadData, (LPVOID)ConvertedAddress, 4);
if(ReadData < PEHeader32->OptionalHeader.ImageBase || ReadData > CorrectedImageSize + PEHeader32->OptionalHeader.ImageBase)
{
myFileStatusInfo.TLSTable = UE_FILED_FIXABLE_CRITICAL;
}
ConvertedAddress = ConvertedAddress + 4;
}
}
}
}
}
SetOverallFileStatus(&myFileStatusInfo, myFileStatusInfo.TLSTable, false);
}
else
{
myFileStatusInfo.TLSTable = UE_FIELD_NOT_PRESET;
}
/*
Load config table check
*/
if(PEHeader32->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG && PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress != NULL)
{
if(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress > CorrectedImageSize || PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress + PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].Size > CorrectedImageSize)
{
myFileStatusInfo.LoadConfigTable = UE_FILED_FIXABLE_CRITICAL;
}
else
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress + PEHeader32->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress == NULL || ConvertedAddress - FileMapVA > FileSize)
{
myFileStatusInfo.LoadConfigTable = UE_FILED_FIXABLE_CRITICAL;
}
}
}
else
{
myFileStatusInfo.LoadConfigTable = UE_FIELD_NOT_PRESET;
}
SetOverallFileStatus(&myFileStatusInfo, myFileStatusInfo.LoadConfigTable, false);
/*
Bound import table check
*/
if(PEHeader32->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT && PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress != NULL)
{
if(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress > CorrectedImageSize || PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress + PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size > CorrectedImageSize)
{
myFileStatusInfo.BoundImportTable = UE_FILED_FIXABLE_CRITICAL;
}
else
{
ConvertedAddress = (ULONG_PTR)PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress + FileMapVA;
if(ConvertedAddress == NULL || ConvertedAddress - FileMapVA > FileSize)
{
myFileStatusInfo.BoundImportTable = UE_FILED_FIXABLE_CRITICAL;
}
else
{
BoundIID = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)ConvertedAddress;
while(BoundIID->TimeDateStamp != NULL)
{
if(BoundIID->OffsetModuleName > PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size)
{
myFileStatusInfo.BoundImportTable = UE_FILED_FIXABLE_CRITICAL;
}
else if(!EngineIsPointedMemoryString(ConvertedAddress + BoundIID->OffsetModuleName))
{
myFileStatusInfo.BoundImportTable = UE_FILED_FIXABLE_CRITICAL;
}
BoundIID = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)((ULONG_PTR)BoundIID + sizeof IMAGE_BOUND_IMPORT_DESCRIPTOR);
}
}
}
}
else
{
myFileStatusInfo.BoundImportTable = UE_FIELD_NOT_PRESET;
}
SetOverallFileStatus(&myFileStatusInfo, myFileStatusInfo.BoundImportTable, false);
/*
IAT check
*/
if(PEHeader32->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_IAT && PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress != NULL)
{
if(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress > CorrectedImageSize || PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress + PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size > CorrectedImageSize)
{
myFileStatusInfo.IATTable = UE_FILED_FIXABLE_NON_CRITICAL;
}
else
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress + PEHeader32->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress == NULL || ConvertedAddress - FileMapVA > FileSize)
{
myFileStatusInfo.IATTable = UE_FILED_FIXABLE_NON_CRITICAL;
}
}
}
else
{
myFileStatusInfo.IATTable = UE_FIELD_NOT_PRESET;
}
SetOverallFileStatus(&myFileStatusInfo, myFileStatusInfo.IATTable, false);
/*
COM header check
*/
if(PEHeader32->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR && PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress != NULL)
{
if(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress > CorrectedImageSize || PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress + PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size > CorrectedImageSize)
{
myFileStatusInfo.COMHeaderTable = UE_FILED_FIXABLE_NON_CRITICAL;
}
else
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress + PEHeader32->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress == NULL || ConvertedAddress - FileMapVA > FileSize)
{
myFileStatusInfo.COMHeaderTable = UE_FILED_FIXABLE_NON_CRITICAL;
}
}
}
else
{
myFileStatusInfo.COMHeaderTable = UE_FIELD_NOT_PRESET;
}
SetOverallFileStatus(&myFileStatusInfo, myFileStatusInfo.COMHeaderTable, false);
/*
Resource header check
*/
if(PEHeader32->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_RESOURCE && PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress != NULL)
{
if(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress > CorrectedImageSize || PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress + PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size > CorrectedImageSize)
{
myFileStatusInfo.ResourceTable = UE_FILED_FIXABLE_NON_CRITICAL;
}
else
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress + PEHeader32->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress == NULL || ConvertedAddress - FileMapVA > FileSize || ConvertedAddress - FileMapVA + PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size > FileSize)
{
myFileStatusInfo.ResourceTable = UE_FIELD_BROKEN_BUT_CAN_BE_EMULATED;
}
if(CheckDepth == UE_DEPTH_DEEP)
{
hSimulatedFileLoad = (ULONG_PTR)EngineSimulateNtLoaderW(szFileName);
if(hSimulatedFileLoad != NULL)
{
for(i = 0; i < 22; i++)
{
if(myFileStatusInfo.ResourceData == UE_FIELD_OK)
{
EnumResourceNamesA((HMODULE)hSimulatedFileLoad, MAKEINTRESOURCEA(ResourceNamesTable[i]), (ENUMRESNAMEPROCA)EngineValidateResource, (ULONG_PTR)&myFileStatusInfo.ResourceData);
}
else
{
i = 22;
}
}
VirtualFree((LPVOID)hSimulatedFileLoad, NULL, MEM_RELEASE);
}
}
}
if(myFileStatusInfo.ResourceTable == UE_FIELD_BROKEN_BUT_CAN_BE_EMULATED && myFileStatusInfo.ResourceData == UE_FIELD_OK)
{
myFileStatusInfo.ResourceTable = UE_FIELD_OK;
}
SetOverallFileStatus(&myFileStatusInfo, myFileStatusInfo.ResourceTable, true);
}
else
{
myFileStatusInfo.ResourceTable = UE_FIELD_NOT_PRESET;
}
/*
Section check
*/
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader32 + PEHeader32->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
NumberOfSections = PEHeader32->FileHeader.NumberOfSections;
while(NumberOfSections > NULL)
{
SectionVirtualSize = PESections->VirtualAddress + PESections->Misc.VirtualSize;
if(PESections->Misc.VirtualSize % PEHeader32->OptionalHeader.SectionAlignment == NULL)
{
SectionVirtualSizeFixed = SectionVirtualSize;
}
else
{
SectionVirtualSizeFixed = PESections->VirtualAddress + (((PESections->Misc.VirtualSize / PEHeader32->OptionalHeader.SectionAlignment) + 1) * PEHeader32->OptionalHeader.SectionAlignment);
}
if(NumberOfSections > 1)
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + sizeof IMAGE_SECTION_HEADER);
if(SectionVirtualSize > PESections->VirtualAddress || SectionVirtualSizeFixed > PESections->VirtualAddress)
{
myFileStatusInfo.SectionTable = UE_FILED_FIXABLE_CRITICAL;
}
}
NumberOfSections--;
}
if(PESections->PointerToRawData + PESections->SizeOfRawData > FileSize && PESections->SizeOfRawData != NULL)
{
myFileStatusInfo.SectionTable = UE_FIELD_BROKEN_NON_FIXABLE;
}
SectionVirtualSizeFixed = SectionVirtualSizeFixed + 0xF000;
if(PEHeader32->OptionalHeader.SizeOfImage > SectionVirtualSizeFixed)
{
myFileStatusInfo.SizeOfImage = UE_FILED_FIXABLE_CRITICAL;
}
SetOverallFileStatus(&myFileStatusInfo, myFileStatusInfo.SizeOfImage, true);
SetOverallFileStatus(&myFileStatusInfo, myFileStatusInfo.SectionTable, true);
/*
Entry point check
*/
SectionNumber = GetPE32SectionNumberFromVA(FileMapVA, PEHeader32->OptionalHeader.AddressOfEntryPoint + PEHeader32->OptionalHeader.ImageBase);
if(SectionNumber != -1)
{
SectionAttributes = (DWORD)GetPE32DataFromMappedFile(FileMapVA, SectionNumber, UE_SECTIONFLAGS);
if(SectionAttributes & IMAGE_SCN_MEM_EXECUTE || SectionAttributes & IMAGE_SCN_CNT_CODE)
{
myFileStatusInfo.EntryPoint = UE_FIELD_OK;
}
else
{
myFileStatusInfo.EntryPoint = UE_FIELD_BROKEN_NON_CRITICAL;
}
}
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEHeader32->OptionalHeader.AddressOfEntryPoint + PEHeader32->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress == NULL)
{
myFileStatusInfo.EntryPoint = UE_FIELD_BROKEN_NON_FIXABLE;
}
else
{
ReadData = NULL;
if(memcmp(&ReadData, (LPVOID)ConvertedAddress, 4) == NULL)
{
myFileStatusInfo.EntryPoint = UE_FIELD_BROKEN_NON_FIXABLE;
}
}
SetOverallFileStatus(&myFileStatusInfo, myFileStatusInfo.EntryPoint, true);
/*
Return data
*/
if(FileStatusInfo != NULL)
{
RtlMoveMemory(FileStatusInfo, &myFileStatusInfo, sizeof FILE_STATUS_INFO);
}
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
if(myFileStatusInfo.OveralEvaluation == UE_RESULT_FILE_OK)
{
return(true);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
myFileStatusInfo.EvaluationTerminatedByException = true;
myFileStatusInfo.OveralEvaluation = UE_RESULT_FILE_INVALID_FORMAT;
myFileStatusInfo.SignaturePE = UE_FIELD_BROKEN_NON_FIXABLE;
if(FileStatusInfo != NULL)
{
RtlMoveMemory(FileStatusInfo, &myFileStatusInfo, sizeof FILE_STATUS_INFO);
}
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
else
{
/*
x64 Surface check
*/
__try
{
if(PEHeader64->OptionalHeader.SizeOfImage % PEHeader64->OptionalHeader.SectionAlignment == NULL)
{
CorrectedImageSize = ((PEHeader64->OptionalHeader.SizeOfImage / PEHeader64->OptionalHeader.SectionAlignment)) * PEHeader64->OptionalHeader.SectionAlignment;
}
else
{
CorrectedImageSize = ((PEHeader64->OptionalHeader.SizeOfImage / PEHeader64->OptionalHeader.SectionAlignment) + 1) * PEHeader64->OptionalHeader.SectionAlignment;
}
if(PEHeader64->OptionalHeader.SectionAlignment != NULL && PEHeader64->OptionalHeader.SectionAlignment >= PEHeader64->OptionalHeader.FileAlignment)
{
myFileStatusInfo.SectionAlignment = UE_FIELD_OK;
if(PEHeader64->OptionalHeader.SizeOfImage % PEHeader64->OptionalHeader.SectionAlignment == NULL)
{
myFileStatusInfo.SizeOfImage = UE_FIELD_OK;
}
else
{
if(CorrectedImageSize < PEHeader64->OptionalHeader.AddressOfEntryPoint)
{
myFileStatusInfo.SizeOfImage = UE_FIELD_BROKEN_NON_FIXABLE;
}
else
{
myFileStatusInfo.SizeOfImage = UE_FILED_FIXABLE_NON_CRITICAL;
}
}
}
else
{
myFileStatusInfo.SectionAlignment = UE_FILED_FIXABLE_CRITICAL;
}
SetOverallFileStatus(&myFileStatusInfo, myFileStatusInfo.SectionAlignment, true);
if((ULONG_PTR)PEHeader64->OptionalHeader.ImageBase % 0x1000 == NULL)
{
myFileStatusInfo.ImageBase = UE_FIELD_OK;
}
else
{
myFileStatusInfo.ImageBase = UE_FIELD_BROKEN_NON_FIXABLE;
}
SetOverallFileStatus(&myFileStatusInfo, myFileStatusInfo.ImageBase, true);
if(PEHeader64->OptionalHeader.FileAlignment % 2 == NULL)
{
myFileStatusInfo.FileAlignment = UE_FIELD_OK;
}
else
{
myFileStatusInfo.FileAlignment = UE_FILED_FIXABLE_CRITICAL;
}
SetOverallFileStatus(&myFileStatusInfo, myFileStatusInfo.FileAlignment, false);
/*
Get the console flag
*/
if(PEHeader64->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI)
{
myFileStatusInfo.FileIsConsole = true;
}
/*
Export and relocation checks [for DLL and EXE]
*/
if(PEHeader64->FileHeader.Characteristics & 0x2000)
{
/*
Export table check
*/
FileIsDLL = true;
myFileStatusInfo.FileIsDLL = true;
if(PEHeader64->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_EXPORT && PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress != NULL)
{
if(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress > CorrectedImageSize || PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size > CorrectedImageSize)
{
myFileStatusInfo.ExportTable = UE_FIELD_BROKEN_NON_FIXABLE;
}
else
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress != NULL)
{
if(EngineIsBadReadPtrEx((LPVOID)ConvertedAddress, PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size))
{
PEExports = (PIMAGE_EXPORT_DIRECTORY)ConvertedAddress;
if(PEExports->AddressOfFunctions > CorrectedImageSize || PEExports->AddressOfFunctions + 4 * PEExports->NumberOfFunctions > CorrectedImageSize)
{
myFileStatusInfo.ExportTable = UE_FIELD_BROKEN_NON_FIXABLE;
}
else if(PEExports->AddressOfNameOrdinals > CorrectedImageSize || PEExports->AddressOfNameOrdinals + 4 * PEExports->NumberOfNames > CorrectedImageSize)
{
myFileStatusInfo.ExportTable = UE_FIELD_BROKEN_NON_FIXABLE;
}
else if(PEExports->AddressOfNames > CorrectedImageSize || PEExports->AddressOfNames + 4 * PEExports->NumberOfNames > CorrectedImageSize)
{
myFileStatusInfo.ExportTable = UE_FIELD_BROKEN_NON_FIXABLE;
}
else if(PEExports->Name > CorrectedImageSize)
{
myFileStatusInfo.ExportTable = UE_FIELD_BROKEN_NON_FIXABLE;
}
else
{
if(CheckDepth == UE_DEPTH_DEEP)
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEExports->AddressOfFunctions + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress != NULL)
{
for(i = 0; i < PEExports->NumberOfFunctions; i++)
{
RtlMoveMemory(&ReadData, (LPVOID)ConvertedAddress, 4);
if(ReadData > CorrectedImageSize || ReadData < PEHeader64->OptionalHeader.SectionAlignment)
{
myFileStatusInfo.ExportTable = UE_FIELD_BROKEN_NON_FIXABLE;
i = PEExports->NumberOfFunctions;
}
else
{
ConvertedAddress = ConvertedAddress + 4;
}
}
}
else
{
myFileStatusInfo.ExportTable = UE_FIELD_BROKEN_NON_FIXABLE;
}
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEExports->AddressOfNames + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress != NULL)
{
for(i = 0; i < PEExports->NumberOfNames; i++)
{
RtlMoveMemory(&ReadData, (LPVOID)ConvertedAddress, 4);
if(ReadData > CorrectedImageSize || ReadData < PEHeader64->OptionalHeader.SectionAlignment)
{
myFileStatusInfo.ExportTable = UE_FIELD_BROKEN_NON_FIXABLE;
i = PEExports->NumberOfNames;
}
else
{
ConvertedAddress = ConvertedAddress + 4;
}
}
}
else
{
myFileStatusInfo.ExportTable = UE_FIELD_BROKEN_NON_FIXABLE;
}
}
}
}
else
{
myFileStatusInfo.ExportTable = UE_FIELD_BROKEN_NON_FIXABLE;
}
}
else
{
myFileStatusInfo.ExportTable = UE_FIELD_BROKEN_NON_FIXABLE;
}
}
SetOverallFileStatus(&myFileStatusInfo, myFileStatusInfo.ExportTable, true);
}
else
{
myFileStatusInfo.ExportTable = UE_FIELD_NOT_PRESET;
}
/*
Relocation table check
*/
if(PEHeader64->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_BASERELOC && PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress != NULL)
{
if(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress > CorrectedImageSize || PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress + PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size > CorrectedImageSize)
{
myFileStatusInfo.RelocationTable = UE_FIELD_BROKEN_NON_FIXABLE;
}
else
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress != NULL)
{
if(EngineIsBadReadPtrEx((LPVOID)ConvertedAddress, PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size))
{
RtlMoveMemory(&ReadData, (LPVOID)ConvertedAddress, 4);
RtlMoveMemory(&ReadSize, (LPVOID)(ConvertedAddress + 4), 4);
while(ReadData != NULL)
{
ReadSize = ReadSize - 8;
ConvertedAddress = ConvertedAddress + 8;
while(ReadSize > NULL)
{
RtlMoveMemory(&ReadDataWORD, (LPVOID)ConvertedAddress, 2);
if(ReadDataWORD > 0xCFFF)
{
myFileStatusInfo.RelocationTable = UE_FIELD_BROKEN_FIXABLE_FOR_STATIC_USE;
}
ConvertedAddress = ConvertedAddress + 2;
ReadSize = ReadSize - 2;
}
RtlMoveMemory(&ReadData, (LPVOID)ConvertedAddress, 4);
RtlMoveMemory(&ReadSize, (LPVOID)(ConvertedAddress + 4), 4);
}
}
else
{
myFileStatusInfo.RelocationTable = UE_FIELD_BROKEN_FIXABLE_FOR_STATIC_USE;
}
}
else
{
myFileStatusInfo.RelocationTable = UE_FIELD_BROKEN_FIXABLE_FOR_STATIC_USE;
}
}
SetOverallFileStatus(&myFileStatusInfo, myFileStatusInfo.RelocationTable, true);
}
else
{
myFileStatusInfo.RelocationTable = UE_FIELD_NOT_PRESET_WARNING;
}
}
else
{
/*
Export table check
*/
if(PEHeader64->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_EXPORT && PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress != NULL)
{
if(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress > CorrectedImageSize || PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size > CorrectedImageSize)
{
myFileStatusInfo.ExportTable = UE_FIELD_BROKEN_NON_CRITICAL;
}
else
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress != NULL)
{
if(EngineIsBadReadPtrEx((LPVOID)ConvertedAddress, PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size))
{
PEExports = (PIMAGE_EXPORT_DIRECTORY)ConvertedAddress;
if(PEExports->AddressOfFunctions > CorrectedImageSize || PEExports->AddressOfFunctions + 4 * PEExports->NumberOfFunctions > CorrectedImageSize)
{
myFileStatusInfo.ExportTable = UE_FIELD_BROKEN_NON_CRITICAL;
}
else if(PEExports->AddressOfNameOrdinals > CorrectedImageSize || PEExports->AddressOfNameOrdinals + 4 * PEExports->NumberOfNames > CorrectedImageSize)
{
myFileStatusInfo.ExportTable = UE_FIELD_BROKEN_NON_CRITICAL;
}
else if(PEExports->AddressOfNames > CorrectedImageSize || PEExports->AddressOfNames + 4 * PEExports->NumberOfNames > CorrectedImageSize)
{
myFileStatusInfo.ExportTable = UE_FIELD_BROKEN_NON_CRITICAL;
}
else if(PEExports->Name > CorrectedImageSize)
{
myFileStatusInfo.ExportTable = UE_FIELD_BROKEN_NON_CRITICAL;
}
}
else
{
myFileStatusInfo.ExportTable = UE_FIELD_BROKEN_NON_CRITICAL;
}
}
}
SetOverallFileStatus(&myFileStatusInfo, myFileStatusInfo.ExportTable, false);
}
else
{
myFileStatusInfo.ExportTable = UE_FIELD_NOT_PRESET;
}
/*
Relocation table check
*/
if(PEHeader64->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_BASERELOC && PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress != NULL)
{
if(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress > CorrectedImageSize || PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress + PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size > CorrectedImageSize)
{
myFileStatusInfo.RelocationTable = UE_FIELD_BROKEN_NON_FIXABLE;
}
else
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress == NULL || ConvertedAddress - FileMapVA > FileSize)
{
myFileStatusInfo.RelocationTable = UE_FILED_FIXABLE_NON_CRITICAL;
}
}
SetOverallFileStatus(&myFileStatusInfo, myFileStatusInfo.RelocationTable, false);
}
else
{
myFileStatusInfo.RelocationTable = UE_FIELD_NOT_PRESET;
}
}
/*
Import table check
*/
if(PEHeader64->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_IMPORT && PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress != NULL)
{
if(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress > CorrectedImageSize)
{
myFileStatusInfo.ImportTable = UE_FIELD_BROKEN_NON_FIXABLE;
}
else
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress == NULL || ConvertedAddress - FileMapVA > FileSize)
{
myFileStatusInfo.ImportTable = UE_FIELD_BROKEN_NON_FIXABLE;
}
else
{
SectionNumber = GetPE32SectionNumberFromVA(FileMapVA, PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase);
if(SectionNumber >= NULL)
{
SectionAttributes = (DWORD)GetPE32DataFromMappedFile(FileMapVA, SectionNumber, UE_SECTIONFLAGS);
if(SectionAttributes & IMAGE_SCN_MEM_EXECUTE || SectionAttributes & IMAGE_SCN_CNT_CODE || SectionAttributes & IMAGE_SCN_MEM_WRITE || SectionAttributes & IMAGE_SCN_CNT_INITIALIZED_DATA)
{
myFileStatusInfo.ImportTableSection = UE_FIELD_OK;
}
else
{
myFileStatusInfo.ImportTableSection = UE_FILED_FIXABLE_CRITICAL;
}
if(CheckDepth == UE_DEPTH_DEEP)
{
if(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress != NULL)
{
ImportIID = (PIMAGE_IMPORT_DESCRIPTOR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, (ULONG_PTR)(ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, (ULONG_PTR)(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase), false, true);
while(myFileStatusInfo.ImportTableData == UE_FIELD_OK && ImportIID->FirstThunk != NULL)
{
hLoadedModule = NULL;
ImportNamePtr = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, (ULONG_PTR)(ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, (ULONG_PTR)((ULONG_PTR)ImportIID->Name + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase), false, true);
if(ImportNamePtr != NULL)
{
if(!EngineIsDependencyPresent((char*)ImportNamePtr, NULL, NULL))
{
myFileStatusInfo.MissingDependencies = true;
hLoadedModuleSimulated = false;
}
else
{
hLoadedModuleSimulated = false;
hLoadedModule = GetModuleHandleA((char*)ImportNamePtr);
if(hLoadedModule == NULL)
{
hLoadedModule = (HMODULE)EngineSimulateDllLoader(GetCurrentProcess(), (char*)ImportNamePtr);
hLoadedModuleSimulated = true;
}
}
}
else
{
myFileStatusInfo.ImportTableData = UE_FIELD_BROKEN_NON_FIXABLE;
}
if(ImportIID->OriginalFirstThunk != NULL)
{
ThunkData64 = (PIMAGE_THUNK_DATA64)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, (ULONG_PTR)((ULONG_PTR)ImportIID->OriginalFirstThunk + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase), false, true);
CurrentThunk = (ULONG_PTR)ImportIID->OriginalFirstThunk;
}
else
{
ThunkData32 = (PIMAGE_THUNK_DATA32)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, (ULONG_PTR)PEHeader32->OptionalHeader.ImageBase, (ULONG_PTR)((ULONG_PTR)ImportIID->FirstThunk + PEHeader32->OptionalHeader.ImageBase), false, true);
CurrentThunk = (ULONG_PTR)ImportIID->FirstThunk;
}
if(ThunkData64 != NULL)
{
while(myFileStatusInfo.ImportTableData == UE_FIELD_OK && ThunkData64->u1.AddressOfData != NULL)
{
if(ThunkData64->u1.Ordinal & IMAGE_ORDINAL_FLAG64)
{
if((int)(ThunkData64->u1.Ordinal ^ IMAGE_ORDINAL_FLAG64) >= 0x10000)
{
myFileStatusInfo.ImportTableData = UE_FIELD_BROKEN_NON_FIXABLE;
}
}
else
{
ImportNamePtr = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, (ULONG_PTR)(ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, (ULONG_PTR)((ULONG_PTR)ThunkData64->u1.AddressOfData + 2 + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase), false, true);
if(ImportNamePtr != NULL)
{
if(!EngineIsBadReadPtrEx((LPVOID)ImportNamePtr, 8))
{
myFileStatusInfo.ImportTableData = UE_FIELD_BROKEN_NON_FIXABLE;
}
else
{
if(hLoadedModule != NULL)
{
if(EngineGetProcAddress((ULONG_PTR)hLoadedModule, (char*)ImportNamePtr) == NULL)
{
myFileStatusInfo.MissingDeclaredAPIs = true;
SetOverallFileStatus(&myFileStatusInfo, UE_FILED_FIXABLE_CRITICAL, true);
}
}
}
}
else
{
myFileStatusInfo.ImportTableData = UE_FIELD_BROKEN_NON_FIXABLE;
}
}
CurrentThunk = CurrentThunk + 8;
ThunkData64 = (PIMAGE_THUNK_DATA64)((ULONG_PTR)ThunkData64 + sizeof IMAGE_THUNK_DATA64);
}
}
else
{
myFileStatusInfo.ImportTableData = UE_FIELD_BROKEN_NON_FIXABLE;
}
if(hLoadedModuleSimulated)
{
VirtualFree((LPVOID)hLoadedModule, NULL, MEM_RELEASE);
}
ImportIID = (PIMAGE_IMPORT_DESCRIPTOR)((ULONG_PTR)ImportIID + sizeof IMAGE_IMPORT_DESCRIPTOR);
}
}
}
}
else
{
myFileStatusInfo.ImportTable = UE_FIELD_BROKEN_NON_FIXABLE;
}
}
}
SetOverallFileStatus(&myFileStatusInfo, myFileStatusInfo.ImportTable, true);
SetOverallFileStatus(&myFileStatusInfo, myFileStatusInfo.ImportTableData, true);
SetOverallFileStatus(&myFileStatusInfo, myFileStatusInfo.ImportTableSection, true);
}
else
{
myFileStatusInfo.ImportTable = UE_FIELD_NOT_PRESET;
}
/*
TLS table check
*/
if(PEHeader64->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_TLS && PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress != NULL)
{
if(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress > CorrectedImageSize || PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress + PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size > CorrectedImageSize)
{
myFileStatusInfo.TLSTable = UE_FILED_FIXABLE_CRITICAL;
}
else
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress == NULL || ConvertedAddress - FileMapVA > FileSize)
{
myFileStatusInfo.TLSTable = UE_FILED_FIXABLE_CRITICAL;
}
else
{
PETls64 = (PIMAGE_TLS_DIRECTORY64)ConvertedAddress;
if(PETls64->StartAddressOfRawData != NULL && (PETls64->StartAddressOfRawData < (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase || PETls64->StartAddressOfRawData > CorrectedImageSize + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase))
{
myFileStatusInfo.TLSTable = UE_FILED_FIXABLE_CRITICAL;
}
else if(PETls64->EndAddressOfRawData != NULL && (PETls64->EndAddressOfRawData < (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase || PETls64->EndAddressOfRawData > CorrectedImageSize + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase))
{
myFileStatusInfo.TLSTable = UE_FILED_FIXABLE_CRITICAL;
}
else if(PETls64->AddressOfIndex != NULL && (PETls64->AddressOfIndex < (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase || PETls64->AddressOfIndex > CorrectedImageSize + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase))
{
myFileStatusInfo.TLSTable = UE_FILED_FIXABLE_CRITICAL;
}
else if(PETls64->AddressOfCallBacks != NULL && (PETls64->AddressOfCallBacks < (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase || PETls64->AddressOfCallBacks > CorrectedImageSize + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase))
{
myFileStatusInfo.TLSTable = UE_FILED_FIXABLE_CRITICAL;
}
if(PETls64->AddressOfCallBacks != NULL && CheckDepth == UE_DEPTH_DEEP)
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, (ULONG_PTR)PETls64->AddressOfCallBacks + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress != NULL)
{
while(ReadData != NULL)
{
RtlMoveMemory(&ReadData, (LPVOID)ConvertedAddress, 8);
if(ReadData < (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase || ReadData > CorrectedImageSize + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase)
{
myFileStatusInfo.TLSTable = UE_FILED_FIXABLE_CRITICAL;
}
ConvertedAddress = ConvertedAddress + 8;
}
}
}
}
}
SetOverallFileStatus(&myFileStatusInfo, myFileStatusInfo.TLSTable, false);
}
else
{
myFileStatusInfo.TLSTable = UE_FIELD_NOT_PRESET;
}
/*
Load config table check
*/
if(PEHeader64->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG && PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress != NULL)
{
if(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress > CorrectedImageSize || PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress + PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].Size > CorrectedImageSize)
{
myFileStatusInfo.LoadConfigTable = UE_FILED_FIXABLE_CRITICAL;
}
else
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress == NULL || ConvertedAddress - FileMapVA > FileSize)
{
myFileStatusInfo.LoadConfigTable = UE_FILED_FIXABLE_CRITICAL;
}
}
}
else
{
myFileStatusInfo.LoadConfigTable = UE_FIELD_NOT_PRESET;
}
SetOverallFileStatus(&myFileStatusInfo, myFileStatusInfo.LoadConfigTable, false);
/*
Bound import table check
*/
if(PEHeader64->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT && PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress != NULL)
{
if(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress > CorrectedImageSize || PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress + PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size > CorrectedImageSize)
{
myFileStatusInfo.BoundImportTable = UE_FILED_FIXABLE_CRITICAL;
}
else
{
ConvertedAddress = (ULONG_PTR)PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress + FileMapVA;
if(ConvertedAddress == NULL || ConvertedAddress - FileMapVA > FileSize)
{
myFileStatusInfo.BoundImportTable = UE_FILED_FIXABLE_CRITICAL;
}
else
{
BoundIID = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)ConvertedAddress;
while(BoundIID->TimeDateStamp != NULL)
{
if(BoundIID->OffsetModuleName > PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size)
{
myFileStatusInfo.BoundImportTable = UE_FILED_FIXABLE_CRITICAL;
}
else if(!EngineIsPointedMemoryString(ConvertedAddress + BoundIID->OffsetModuleName))
{
myFileStatusInfo.BoundImportTable = UE_FILED_FIXABLE_CRITICAL;
}
BoundIID = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)((ULONG_PTR)BoundIID + sizeof IMAGE_BOUND_IMPORT_DESCRIPTOR);
}
}
}
}
else
{
myFileStatusInfo.BoundImportTable = UE_FIELD_NOT_PRESET;
}
SetOverallFileStatus(&myFileStatusInfo, myFileStatusInfo.BoundImportTable, false);
/*
IAT check
*/
if(PEHeader64->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_IAT && PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress != NULL)
{
if(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress > CorrectedImageSize || PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress + PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size > CorrectedImageSize)
{
myFileStatusInfo.IATTable = UE_FILED_FIXABLE_NON_CRITICAL;
}
else
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress == NULL || ConvertedAddress - FileMapVA > FileSize)
{
myFileStatusInfo.IATTable = UE_FILED_FIXABLE_NON_CRITICAL;
}
}
}
else
{
myFileStatusInfo.IATTable = UE_FIELD_NOT_PRESET;
}
SetOverallFileStatus(&myFileStatusInfo, myFileStatusInfo.IATTable, false);
/*
COM header check
*/
if(PEHeader64->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR && PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress != NULL)
{
if(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress > CorrectedImageSize || PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress + PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size > CorrectedImageSize)
{
myFileStatusInfo.COMHeaderTable = UE_FILED_FIXABLE_NON_CRITICAL;
}
else
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress == NULL || ConvertedAddress - FileMapVA > FileSize)
{
myFileStatusInfo.COMHeaderTable = UE_FILED_FIXABLE_NON_CRITICAL;
}
}
}
else
{
myFileStatusInfo.COMHeaderTable = UE_FIELD_NOT_PRESET;
}
SetOverallFileStatus(&myFileStatusInfo, myFileStatusInfo.COMHeaderTable, false);
/*
Resource header check
*/
if(PEHeader64->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_RESOURCE && PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress != NULL)
{
if(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress > CorrectedImageSize || PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress + PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size > CorrectedImageSize)
{
myFileStatusInfo.ResourceTable = UE_FILED_FIXABLE_NON_CRITICAL;
}
else
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress == NULL || ConvertedAddress - FileMapVA > FileSize || ConvertedAddress - FileMapVA + PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size > FileSize)
{
myFileStatusInfo.ResourceTable = UE_FIELD_BROKEN_BUT_CAN_BE_EMULATED;
}
if(CheckDepth == UE_DEPTH_DEEP)
{
hSimulatedFileLoad = (ULONG_PTR)EngineSimulateNtLoaderW(szFileName);
if(hSimulatedFileLoad != NULL)
{
for(i = 0; i < 22; i++)
{
if(myFileStatusInfo.ResourceData == UE_FIELD_OK)
{
EnumResourceNamesA((HMODULE)hSimulatedFileLoad, MAKEINTRESOURCEA(ResourceNamesTable[i]), (ENUMRESNAMEPROCA)EngineValidateResource, (ULONG_PTR)&myFileStatusInfo.ResourceData);
}
else
{
i = 22;
}
}
VirtualFree((LPVOID)hSimulatedFileLoad, NULL, MEM_RELEASE);
}
}
}
if(myFileStatusInfo.ResourceTable == UE_FIELD_BROKEN_BUT_CAN_BE_EMULATED && myFileStatusInfo.ResourceData == UE_FIELD_OK)
{
myFileStatusInfo.ResourceTable = UE_FIELD_OK;
}
SetOverallFileStatus(&myFileStatusInfo, myFileStatusInfo.ResourceTable, true);
}
else
{
myFileStatusInfo.ResourceTable = UE_FIELD_NOT_PRESET;
}
/*
Section check
*/
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader64 + PEHeader64->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
NumberOfSections = PEHeader64->FileHeader.NumberOfSections;
while(NumberOfSections > NULL)
{
SectionVirtualSize = PESections->VirtualAddress + PESections->Misc.VirtualSize;
if(PESections->Misc.VirtualSize % PEHeader64->OptionalHeader.SectionAlignment == NULL)
{
SectionVirtualSizeFixed = SectionVirtualSize;
}
else
{
SectionVirtualSizeFixed = PESections->VirtualAddress + (((PESections->Misc.VirtualSize / PEHeader64->OptionalHeader.SectionAlignment) + 1) * PEHeader64->OptionalHeader.SectionAlignment);
}
if(NumberOfSections > 1)
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + sizeof IMAGE_SECTION_HEADER);
if(SectionVirtualSize > PESections->VirtualAddress || SectionVirtualSizeFixed > PESections->VirtualAddress)
{
myFileStatusInfo.SectionTable = UE_FILED_FIXABLE_CRITICAL;
}
}
NumberOfSections--;
}
if(PESections->PointerToRawData + PESections->SizeOfRawData > FileSize && PESections->SizeOfRawData != NULL)
{
myFileStatusInfo.SectionTable = UE_FIELD_BROKEN_NON_FIXABLE;
}
SectionVirtualSizeFixed = SectionVirtualSizeFixed + 0xF000;
if(PEHeader64->OptionalHeader.SizeOfImage > SectionVirtualSizeFixed)
{
myFileStatusInfo.SizeOfImage = UE_FILED_FIXABLE_CRITICAL;
}
SetOverallFileStatus(&myFileStatusInfo, myFileStatusInfo.SizeOfImage, true);
SetOverallFileStatus(&myFileStatusInfo, myFileStatusInfo.SectionTable, true);
/*
Entry point check
*/
SectionNumber = GetPE32SectionNumberFromVA(FileMapVA, PEHeader64->OptionalHeader.AddressOfEntryPoint + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase);
if(SectionNumber != -1)
{
SectionAttributes = (DWORD)GetPE32DataFromMappedFile(FileMapVA, SectionNumber, UE_SECTIONFLAGS);
if(SectionAttributes & IMAGE_SCN_MEM_EXECUTE || SectionAttributes & IMAGE_SCN_CNT_CODE)
{
myFileStatusInfo.EntryPoint = UE_FIELD_OK;
}
else
{
myFileStatusInfo.EntryPoint = UE_FIELD_BROKEN_NON_CRITICAL;
}
}
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEHeader64->OptionalHeader.AddressOfEntryPoint + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress == NULL)
{
myFileStatusInfo.EntryPoint = UE_FIELD_BROKEN_NON_FIXABLE;
}
else
{
ReadData = NULL;
if(memcmp(&ReadData, (LPVOID)ConvertedAddress, 4) == NULL)
{
myFileStatusInfo.EntryPoint = UE_FIELD_BROKEN_NON_FIXABLE;
}
}
SetOverallFileStatus(&myFileStatusInfo, myFileStatusInfo.EntryPoint, true);
/*
Return data
*/
if(FileStatusInfo != NULL)
{
RtlMoveMemory(FileStatusInfo, &myFileStatusInfo, sizeof FILE_STATUS_INFO);
}
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
if(myFileStatusInfo.OveralEvaluation == UE_RESULT_FILE_OK)
{
return(true);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
myFileStatusInfo.EvaluationTerminatedByException = true;
myFileStatusInfo.OveralEvaluation = UE_RESULT_FILE_INVALID_FORMAT;
myFileStatusInfo.SignaturePE = UE_FIELD_BROKEN_NON_FIXABLE;
if(FileStatusInfo != NULL)
{
RtlMoveMemory(FileStatusInfo, &myFileStatusInfo, sizeof FILE_STATUS_INFO);
}
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
}
else
{
myFileStatusInfo.OveralEvaluation = UE_RESULT_FILE_INVALID_FORMAT;
myFileStatusInfo.SignatureMZ = UE_FIELD_BROKEN_NON_FIXABLE;
if(FileStatusInfo != NULL)
{
RtlMoveMemory(FileStatusInfo, &myFileStatusInfo, sizeof FILE_STATUS_INFO);
}
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
if(FileStatusInfo != NULL)
{
RtlMoveMemory(FileStatusInfo, &myFileStatusInfo, sizeof FILE_STATUS_INFO);
}
return(false);
}
__declspec(dllexport) bool TITCALL FixBrokenPE32FileEx(char* szFileName, LPVOID FileStatusInfo, LPVOID FileFixInfo)
{
wchar_t uniFileName[MAX_PATH] = {};
if(szFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
return(FixBrokenPE32FileExW(uniFileName, FileStatusInfo, FileFixInfo));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL FixBrokenPE32FileExW(wchar_t* szFileName, LPVOID FileStatusInfo, LPVOID FileFixInfo)
{
if(!FileFixInfo)
return false;
DWORD ReadData = NULL;
DWORD ReadSize = NULL;
WORD ReadDataWORD = NULL;
ULONG_PTR ReadDataQWORD = NULL;
DWORD OrdinalBase = NULL;
DWORD OrdinalCount = NULL;
long SectionNumber = NULL;
DWORD SectionAttributes = NULL;
ULONG_PTR ConvertedAddress = NULL;
DWORD CorrectedImageSize = NULL;
DWORD SectionVirtualSize = NULL;
DWORD SectionVirtualSizeFixed = NULL;
DWORD NumberOfSections = NULL;
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
PIMAGE_SECTION_HEADER PESections;
PIMAGE_EXPORT_DIRECTORY PEExports;
PIMAGE_TLS_DIRECTORY32 PETls32;
PIMAGE_TLS_DIRECTORY64 PETls64;
PIMAGE_IMPORT_DESCRIPTOR ImportIID;
PIMAGE_THUNK_DATA32 ThunkData32;
PIMAGE_THUNK_DATA64 ThunkData64;
PFILE_STATUS_INFO myFileStatusInfo = (PFILE_STATUS_INFO)FileStatusInfo;
PFILE_FIX_INFO myFileFixInfo = (PFILE_FIX_INFO)FileFixInfo; //can bad point
bool hLoadedModuleSimulated = false;
HMODULE hLoadedModule;
ULONG_PTR ImportNamePtr;
ULONG_PTR CurrentThunk;
BOOL FileIs64;
HANDLE FileHandle;
DWORD FileSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
bool FileFixed = true;
bool FeatureFixed = false;
FILE_STANDARD_INFO filestatusinfo; //for internal use
if(myFileStatusInfo == NULL) //here check for myfilestrus..ah lol, youre right
{
myFileStatusInfo=(PFILE_STATUS_INFO)&filestatusinfo;
IsPE32FileValidExW(szFileName, UE_DEPTH_DEEP, myFileStatusInfo);
}
if(myFileFixInfo->FileFixPerformed == false && myFileStatusInfo->OveralEvaluation == UE_RESULT_FILE_INVALID_BUT_FIXABLE)
{
if(MapFileExW(szFileName, UE_ACCESS_ALL, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
myFileFixInfo->OveralEvaluation = UE_RESULT_FILE_INVALID_AND_NON_FIXABLE;
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, FileHandle, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->Signature == 0x4550 && PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->Signature == 0x4550 && PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
if(myFileStatusInfo->SignatureMZ != UE_FIELD_OK)
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
else if(myFileStatusInfo->SignaturePE != UE_FIELD_OK)
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
else if(myFileStatusInfo->SectionAlignment != UE_FIELD_OK)
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
else if(myFileStatusInfo->FileAlignment != UE_FIELD_OK)
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
else if(myFileStatusInfo->ImportTable != UE_FIELD_OK)
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
else if(myFileStatusInfo->ImportTableData != UE_FIELD_OK)
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
if(!FileIs64)
{
/*
x86 Surface check
*/
__try
{
if(PEHeader32->OptionalHeader.SizeOfImage % PEHeader32->OptionalHeader.SectionAlignment == NULL)
{
CorrectedImageSize = (PEHeader32->OptionalHeader.SizeOfImage / PEHeader32->OptionalHeader.SectionAlignment) * PEHeader32->OptionalHeader.SectionAlignment;
}
else
{
CorrectedImageSize = ((PEHeader32->OptionalHeader.SizeOfImage / PEHeader32->OptionalHeader.SectionAlignment) + 1) * PEHeader32->OptionalHeader.SectionAlignment;
}
/*
Fixing import table
*/
if(myFileStatusInfo->MissingDeclaredAPIs)
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + PEHeader32->OptionalHeader.ImageBase, false, true);
SectionNumber = GetPE32SectionNumberFromVA(FileMapVA, PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + PEHeader32->OptionalHeader.ImageBase);
if(SectionNumber >= NULL)
{
SectionAttributes = (DWORD)GetPE32DataFromMappedFile(FileMapVA, SectionNumber, UE_SECTIONFLAGS);
if(SectionAttributes & IMAGE_SCN_MEM_EXECUTE || SectionAttributes & IMAGE_SCN_CNT_CODE || SectionAttributes & IMAGE_SCN_MEM_WRITE || SectionAttributes & IMAGE_SCN_CNT_INITIALIZED_DATA)
{
// Should not execute!
}
else
{
if(!SetPE32DataForMappedFile(FileMapVA, SectionAttributes, UE_SECTIONFLAGS, 0xE0000020))
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
if(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress != NULL)
{
ImportIID = (PIMAGE_IMPORT_DESCRIPTOR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, (ULONG_PTR)PEHeader32->OptionalHeader.ImageBase, (ULONG_PTR)(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + PEHeader32->OptionalHeader.ImageBase), false, true);
while(ImportIID->FirstThunk != NULL)
{
hLoadedModule = NULL;
ImportNamePtr = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, (ULONG_PTR)PEHeader32->OptionalHeader.ImageBase, (ULONG_PTR)((ULONG_PTR)ImportIID->Name + PEHeader32->OptionalHeader.ImageBase), false, true);
if(ImportNamePtr != NULL)
{
if(!EngineIsDependencyPresent((char*)ImportNamePtr, NULL, NULL))
{
hLoadedModuleSimulated = false;
}
else
{
hLoadedModuleSimulated = false;
hLoadedModule = GetModuleHandleA((char*)ImportNamePtr);
if(hLoadedModule == NULL)
{
hLoadedModule = (HMODULE)EngineSimulateDllLoader(GetCurrentProcess(), (char*)ImportNamePtr);
hLoadedModuleSimulated = true;
}
}
}
if(ImportIID->OriginalFirstThunk != NULL)
{
ThunkData32 = (PIMAGE_THUNK_DATA32)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, (ULONG_PTR)PEHeader32->OptionalHeader.ImageBase, (ULONG_PTR)((ULONG_PTR)ImportIID->OriginalFirstThunk + PEHeader32->OptionalHeader.ImageBase), false, true);
CurrentThunk = (ULONG_PTR)ImportIID->OriginalFirstThunk;
}
else
{
ThunkData32 = (PIMAGE_THUNK_DATA32)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, (ULONG_PTR)PEHeader32->OptionalHeader.ImageBase, (ULONG_PTR)((ULONG_PTR)ImportIID->FirstThunk + PEHeader32->OptionalHeader.ImageBase), false, true);
CurrentThunk = (ULONG_PTR)ImportIID->FirstThunk;
}
if(ThunkData32 != NULL)
{
while(ThunkData32->u1.AddressOfData != NULL)
{
if(ThunkData32->u1.Ordinal & IMAGE_ORDINAL_FLAG32)
{
if((int)(ThunkData32->u1.Ordinal ^ IMAGE_ORDINAL_FLAG32) >= 0x10000)
{
FileFixed = false;
}
}
else
{
ImportNamePtr = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, (ULONG_PTR)PEHeader32->OptionalHeader.ImageBase, (ULONG_PTR)((ULONG_PTR)ThunkData32->u1.AddressOfData + 2 + PEHeader32->OptionalHeader.ImageBase), false, true);
if(ImportNamePtr != NULL)
{
if(EngineIsBadReadPtrEx((LPVOID)ImportNamePtr, 8))
{
if(hLoadedModule != NULL)
{
if(EngineGetProcAddress((ULONG_PTR)hLoadedModule, (char*)ImportNamePtr) == NULL)
{
OrdinalBase = NULL;
OrdinalCount = NULL;
if(EngineGetLibraryOrdinalData((ULONG_PTR)hLoadedModule, &OrdinalBase, &OrdinalCount))
{
if(OrdinalBase != NULL && OrdinalCount != NULL)
{
ThunkData32->u1.Ordinal = (OrdinalBase + 1) ^ IMAGE_ORDINAL_FLAG32;
}
else
{
FileFixed = false;
}
}
}
}
}
}
}
CurrentThunk = CurrentThunk + 4;
ThunkData32 = (PIMAGE_THUNK_DATA32)((ULONG_PTR)ThunkData32 + sizeof IMAGE_THUNK_DATA32);
}
}
if(hLoadedModuleSimulated)
{
VirtualFree((LPVOID)hLoadedModule, NULL, MEM_RELEASE);
}
ImportIID = (PIMAGE_IMPORT_DESCRIPTOR)((ULONG_PTR)ImportIID + sizeof IMAGE_IMPORT_DESCRIPTOR);
}
}
}
}
/*
Fixing Export table
*/
if(myFileStatusInfo->ExportTable == UE_FIELD_NOT_PRESET_WARNING)
{
FileFixed = false;
}
else if(myFileFixInfo->DontFixExports == false && myFileStatusInfo->ExportTable != UE_FIELD_OK && myFileStatusInfo->ExportTable != UE_FIELD_NOT_PRESET)
{
if(PEHeader32->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_EXPORT && PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress != NULL)
{
if(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress > CorrectedImageSize || PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size > CorrectedImageSize)
{
myFileFixInfo->StrippedExports = true;
myFileFixInfo->OriginalExportTableAddress = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
myFileFixInfo->OriginalExportTableSize = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = NULL;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = NULL;
}
else
{
FeatureFixed = true;
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + PEHeader32->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress != NULL)
{
if(EngineIsBadReadPtrEx((LPVOID)ConvertedAddress, PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size))
{
PEExports = (PIMAGE_EXPORT_DIRECTORY)ConvertedAddress;
if(PEExports->AddressOfFunctions > CorrectedImageSize || PEExports->AddressOfFunctions + 4 * PEExports->NumberOfFunctions > CorrectedImageSize)
{
FeatureFixed = false;
}
else if(PEExports->AddressOfNameOrdinals > CorrectedImageSize || PEExports->AddressOfNameOrdinals + 4 * PEExports->NumberOfNames > CorrectedImageSize)
{
FeatureFixed = false;
}
else if(PEExports->AddressOfNames > CorrectedImageSize || PEExports->AddressOfNames + 4 * PEExports->NumberOfNames > CorrectedImageSize)
{
FeatureFixed = false;
}
else if(PEExports->Name > CorrectedImageSize)
{
FeatureFixed = false;
}
if(!FeatureFixed)
{
myFileFixInfo->StrippedExports = true;
myFileFixInfo->OriginalExportTableAddress = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
myFileFixInfo->OriginalExportTableSize = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = NULL;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = NULL;
}
}
else
{
myFileFixInfo->StrippedExports = true;
myFileFixInfo->OriginalExportTableAddress = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
myFileFixInfo->OriginalExportTableSize = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = NULL;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = NULL;
}
}
}
}
}
/*
Fixing Relocation table
*/
if(myFileStatusInfo->FileIsDLL == true && myFileStatusInfo->RelocationTable == UE_FIELD_BROKEN_NON_FIXABLE)
{
FileFixed = false;
}
else if(myFileFixInfo->DontFixRelocations == false && myFileStatusInfo->RelocationTable != UE_FIELD_OK)
{
if(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress > CorrectedImageSize || PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress + PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size > CorrectedImageSize)
{
if(myFileStatusInfo->FileIsDLL)
{
FileFixed = false;
}
else
{
myFileFixInfo->StrippedRelocation = true;
myFileFixInfo->OriginalRelocationTableAddress = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
myFileFixInfo->OriginalRelocationTableSize = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = NULL;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = NULL;
}
}
else
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress + PEHeader32->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress != NULL)
{
if(EngineIsBadReadPtrEx((LPVOID)ConvertedAddress, PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size))
{
RtlMoveMemory(&ReadData, (LPVOID)ConvertedAddress, 4);
RtlMoveMemory(&ReadSize, (LPVOID)(ConvertedAddress + 4), 4);
while(ReadData != NULL)
{
ReadSize = ReadSize - 8;
ConvertedAddress = ConvertedAddress + 8;
while(ReadSize > NULL)
{
RtlMoveMemory(&ReadDataWORD, (LPVOID)ConvertedAddress, 2);
if(ReadDataWORD > 0xCFFF)
{
RtlZeroMemory((LPVOID)ConvertedAddress, 2);
}
ConvertedAddress = ConvertedAddress + 2;
ReadSize = ReadSize - 2;
}
RtlMoveMemory(&ReadData, (LPVOID)ConvertedAddress, 4);
RtlMoveMemory(&ReadSize, (LPVOID)(ConvertedAddress + 4), 4);
}
}
else
{
if(myFileStatusInfo->FileIsDLL)
{
FileFixed = false;
}
else
{
myFileFixInfo->StrippedRelocation = true;
myFileFixInfo->OriginalRelocationTableAddress = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
myFileFixInfo->OriginalRelocationTableSize = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = NULL;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = NULL;
}
}
}
else
{
if(myFileStatusInfo->FileIsDLL)
{
FileFixed = false;
}
else
{
myFileFixInfo->StrippedRelocation = true;
myFileFixInfo->OriginalRelocationTableAddress = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
myFileFixInfo->OriginalRelocationTableSize = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = NULL;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = NULL;
}
}
}
}
else if(myFileStatusInfo->RelocationTable == UE_FIELD_OK)
{
// Filter case!
}
else
{
FileFixed = false;
}
/*
Fixing Resource table
*/
if(myFileFixInfo->DontFixResources == false && myFileStatusInfo->ResourceData != UE_FIELD_OK && myFileStatusInfo->ResourceData != UE_FIELD_NOT_PRESET)
{
myFileFixInfo->StrippedResources = true;
myFileFixInfo->OriginalResourceTableAddress = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;
myFileFixInfo->OriginalResourceTableSize = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = NULL;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = NULL;
}
else if(myFileFixInfo->DontFixResources == false && myFileStatusInfo->ResourceTable != UE_FIELD_OK && myFileStatusInfo->ResourceTable != UE_FIELD_NOT_PRESET)
{
if(PEHeader32->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_RESOURCE && PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress != NULL)
{
if(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress > CorrectedImageSize || PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress + PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size > CorrectedImageSize)
{
myFileFixInfo->StrippedResources = true;
myFileFixInfo->OriginalResourceTableAddress = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;
myFileFixInfo->OriginalResourceTableSize = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = NULL;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = NULL;
}
else
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress + PEHeader32->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress == NULL || ConvertedAddress - FileMapVA > FileSize || ConvertedAddress - FileMapVA + PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size > FileSize)
{
myFileFixInfo->StrippedResources = true;
myFileFixInfo->OriginalResourceTableAddress = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;
myFileFixInfo->OriginalResourceTableSize = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = NULL;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = NULL;
}
}
}
}
/*
Fixing TLS table
*/
if(myFileFixInfo->DontFixTLS == false && myFileStatusInfo->TLSTable != UE_FIELD_OK && myFileStatusInfo->TLSTable != UE_FIELD_NOT_PRESET)
{
if(PEHeader32->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_TLS && PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress != NULL)
{
if(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress > CorrectedImageSize || PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress + PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size > CorrectedImageSize)
{
myFileFixInfo->StrippedTLS = true;
myFileFixInfo->OriginalTLSTableAddress = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress;
myFileFixInfo->OriginalTLSTableSize = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress = NULL;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size = NULL;
}
else
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress + PEHeader32->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress == NULL || ConvertedAddress - FileMapVA > FileSize)
{
myFileFixInfo->StrippedTLS = true;
myFileFixInfo->OriginalTLSTableAddress = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress;
myFileFixInfo->OriginalTLSTableSize = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress = NULL;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size = NULL;
}
else
{
FeatureFixed = true;
PETls32 = (PIMAGE_TLS_DIRECTORY32)ConvertedAddress;
if(PETls32->StartAddressOfRawData != NULL && (PETls32->StartAddressOfRawData < PEHeader32->OptionalHeader.ImageBase || PETls32->StartAddressOfRawData > CorrectedImageSize + PEHeader32->OptionalHeader.ImageBase))
{
FeatureFixed = false;
}
else if(PETls32->EndAddressOfRawData != NULL && (PETls32->EndAddressOfRawData < PEHeader32->OptionalHeader.ImageBase || PETls32->EndAddressOfRawData > CorrectedImageSize + PEHeader32->OptionalHeader.ImageBase))
{
FeatureFixed = false;
}
else if(PETls32->AddressOfIndex != NULL && (PETls32->AddressOfIndex < PEHeader32->OptionalHeader.ImageBase || PETls32->AddressOfIndex > CorrectedImageSize + PEHeader32->OptionalHeader.ImageBase))
{
FeatureFixed = false;
}
else if(PETls32->AddressOfCallBacks != NULL && (PETls32->AddressOfCallBacks < PEHeader32->OptionalHeader.ImageBase || PETls32->AddressOfCallBacks > CorrectedImageSize + PEHeader32->OptionalHeader.ImageBase))
{
FeatureFixed = false;
}
if(!FeatureFixed)
{
myFileFixInfo->StrippedTLS = true;
myFileFixInfo->OriginalTLSTableAddress = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress;
myFileFixInfo->OriginalTLSTableSize = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress = NULL;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size = NULL;
}
else
{
if(PETls32->AddressOfCallBacks != NULL)
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PETls32->AddressOfCallBacks + PEHeader32->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress != NULL)
{
while(ReadData != NULL)
{
RtlMoveMemory(&ReadData, (LPVOID)ConvertedAddress, 4);
if(ReadData < PEHeader32->OptionalHeader.ImageBase || ReadData > CorrectedImageSize + PEHeader32->OptionalHeader.ImageBase)
{
RtlZeroMemory((LPVOID)ConvertedAddress, 4);
}
ConvertedAddress = ConvertedAddress + 4;
}
}
}
}
}
}
}
}
/*
Fix Load config table
*/
if(myFileFixInfo->DontFixLoadConfig == false && myFileStatusInfo->LoadConfigTable != UE_FIELD_OK && myFileStatusInfo->LoadConfigTable != UE_FIELD_NOT_PRESET)
{
if(PEHeader32->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG && PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress != NULL)
{
if(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress > CorrectedImageSize || PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress + PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].Size > CorrectedImageSize)
{
myFileFixInfo->StrippedLoadConfig = true;
myFileFixInfo->OriginalLoadConfigTableAddress = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress;
myFileFixInfo->OriginalLoadConfigTableSize = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].Size;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress = NULL;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].Size = NULL;
}
else
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress + PEHeader32->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress == NULL || ConvertedAddress - FileMapVA > FileSize)
{
myFileFixInfo->StrippedLoadConfig = true;
myFileFixInfo->OriginalLoadConfigTableAddress = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress;
myFileFixInfo->OriginalLoadConfigTableSize = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].Size;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress = NULL;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].Size = NULL;
}
}
}
}
/*
Fix Bound import table
*/
if(myFileFixInfo->DontFixBoundImports == false && myFileStatusInfo->BoundImportTable != UE_FIELD_OK && myFileStatusInfo->BoundImportTable != UE_FIELD_NOT_PRESET)
{
if(PEHeader32->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT && PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress != NULL)
{
if(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress > CorrectedImageSize || PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress + PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size > CorrectedImageSize)
{
myFileFixInfo->StrippedBoundImports = true;
myFileFixInfo->OriginalBoundImportTableAddress = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress;
myFileFixInfo->OriginalBoundImportTableSize = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = NULL;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = NULL;
}
else
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress + PEHeader32->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress == NULL || ConvertedAddress - FileMapVA > FileSize)
{
myFileFixInfo->StrippedBoundImports = true;
myFileFixInfo->OriginalBoundImportTableAddress = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress;
myFileFixInfo->OriginalBoundImportTableSize = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = NULL;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = NULL;
}
}
}
}
/*
Fix IAT
*/
if(myFileFixInfo->DontFixIAT == false && myFileStatusInfo->IATTable != UE_FIELD_OK && myFileStatusInfo->IATTable != UE_FIELD_NOT_PRESET)
{
if(PEHeader32->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_IAT && PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress != NULL)
{
if(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress > CorrectedImageSize || PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress + PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size > CorrectedImageSize)
{
myFileFixInfo->StrippedIAT = true;
myFileFixInfo->OriginalImportAddressTableAddress = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress;
myFileFixInfo->OriginalImportAddressTableSize = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = NULL;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = NULL;
}
else
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress + PEHeader32->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress == NULL || ConvertedAddress - FileMapVA > FileSize)
{
myFileFixInfo->StrippedIAT = true;
myFileFixInfo->OriginalImportAddressTableAddress = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress;
myFileFixInfo->OriginalImportAddressTableSize = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = NULL;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = NULL;
}
}
}
}
/*
Fix COM header
*/
if(myFileFixInfo->DontFixCOM == false && myFileStatusInfo->COMHeaderTable != UE_FIELD_OK && myFileStatusInfo->COMHeaderTable != UE_FIELD_NOT_PRESET)
{
if(PEHeader32->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR && PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress != NULL)
{
if(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress > CorrectedImageSize || PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress + PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size > CorrectedImageSize)
{
myFileFixInfo->StrippedCOM = true;
myFileFixInfo->OriginalCOMTableAddress = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress;
myFileFixInfo->OriginalCOMTableSize = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress = NULL;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size = NULL;
}
else
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress + PEHeader32->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress == NULL || ConvertedAddress - FileMapVA > FileSize)
{
myFileFixInfo->StrippedCOM = true;
myFileFixInfo->OriginalCOMTableAddress = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress;
myFileFixInfo->OriginalCOMTableSize = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress = NULL;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size = NULL;
}
}
}
}
/*
Fix sections and SizeOfImage
*/
if(myFileStatusInfo->SectionTable != UE_FIELD_OK || myFileStatusInfo->SizeOfImage != UE_FIELD_OK)
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader32 + PEHeader32->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
NumberOfSections = PEHeader32->FileHeader.NumberOfSections;
while(NumberOfSections > NULL)
{
SectionVirtualSize = PESections->VirtualAddress + PESections->Misc.VirtualSize;
if(PESections->Misc.VirtualSize % PEHeader32->OptionalHeader.SectionAlignment == NULL)
{
SectionVirtualSizeFixed = SectionVirtualSize;
}
else
{
SectionVirtualSizeFixed = PESections->VirtualAddress + (((PESections->Misc.VirtualSize / PEHeader32->OptionalHeader.SectionAlignment) + 1) * PEHeader32->OptionalHeader.SectionAlignment);
}
if(NumberOfSections > 1)
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + sizeof IMAGE_SECTION_HEADER);
if(SectionVirtualSize > PESections->VirtualAddress || SectionVirtualSizeFixed > PESections->VirtualAddress)
{
PESections->Misc.VirtualSize = SectionVirtualSizeFixed;
}
}
NumberOfSections--;
}
if(PESections->PointerToRawData + PESections->SizeOfRawData > FileSize && PESections->SizeOfRawData != NULL)
{
PESections->SizeOfRawData = FileSize - PESections->PointerToRawData;
}
if(myFileStatusInfo->SizeOfImage != UE_FIELD_OK)
{
SectionVirtualSizeFixed = SectionVirtualSizeFixed + 0xF000;
if(PEHeader32->OptionalHeader.SizeOfImage > SectionVirtualSizeFixed)
{
PEHeader32->OptionalHeader.SizeOfImage = SectionVirtualSizeFixed - 0xF000;
}
}
}
/*
Entry point check
*/
if(myFileStatusInfo->EntryPoint != UE_FIELD_OK)
{
SectionNumber = GetPE32SectionNumberFromVA(FileMapVA, PEHeader32->OptionalHeader.AddressOfEntryPoint + (ULONG_PTR)PEHeader32->OptionalHeader.ImageBase);
if(SectionNumber != -1)
{
SectionAttributes = (DWORD)GetPE32DataFromMappedFile(FileMapVA, SectionNumber, UE_SECTIONFLAGS);
if(SectionAttributes & IMAGE_SCN_MEM_EXECUTE || SectionAttributes & IMAGE_SCN_CNT_CODE)
{
// Should never execute
}
else
{
if(!SetPE32DataForMappedFile(FileMapVA, SectionNumber, UE_SECTIONFLAGS, 0xE0000020))
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
}
}
/*
Fix end
*/
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
if(FileFixed)
{
myFileFixInfo->OveralEvaluation = UE_RESULT_FILE_OK;
myFileFixInfo->FileFixPerformed = FileFixed;
}
return(true);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
myFileFixInfo->FixingTerminatedByException = true;
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
else
{
/*
x64 Surface check
*/
__try
{
if(PEHeader64->OptionalHeader.SizeOfImage % PEHeader64->OptionalHeader.SectionAlignment == NULL)
{
CorrectedImageSize = (PEHeader64->OptionalHeader.SizeOfImage / PEHeader64->OptionalHeader.SectionAlignment) * PEHeader64->OptionalHeader.SectionAlignment;
}
else
{
CorrectedImageSize = ((PEHeader64->OptionalHeader.SizeOfImage / PEHeader64->OptionalHeader.SectionAlignment) + 1) * PEHeader64->OptionalHeader.SectionAlignment;
}
/*
Fixing import table
*/
if(myFileStatusInfo->MissingDeclaredAPIs)
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, false, true);
SectionNumber = GetPE32SectionNumberFromVA(FileMapVA, PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase);
if(SectionNumber >= NULL)
{
SectionAttributes = (DWORD)GetPE32DataFromMappedFile(FileMapVA, SectionNumber, UE_SECTIONFLAGS);
if(SectionAttributes & IMAGE_SCN_MEM_EXECUTE || SectionAttributes & IMAGE_SCN_CNT_CODE || SectionAttributes & IMAGE_SCN_MEM_WRITE || SectionAttributes & IMAGE_SCN_CNT_INITIALIZED_DATA)
{
// Should not execute!
}
else
{
if(!SetPE32DataForMappedFile(FileMapVA, SectionAttributes, UE_SECTIONFLAGS, 0xE0000020))
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
if(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress != NULL)
{
ImportIID = (PIMAGE_IMPORT_DESCRIPTOR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, (ULONG_PTR)(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase), false, true);
while(ImportIID->FirstThunk != NULL)
{
hLoadedModule = NULL;
ImportNamePtr = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, (ULONG_PTR)((ULONG_PTR)ImportIID->Name + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase), false, true);
if(ImportNamePtr != NULL)
{
if(!EngineIsDependencyPresent((char*)ImportNamePtr, NULL, NULL))
{
hLoadedModuleSimulated = false;
}
else
{
hLoadedModuleSimulated = false;
hLoadedModule = GetModuleHandleA((char*)ImportNamePtr);
if(hLoadedModule == NULL)
{
hLoadedModule = (HMODULE)EngineSimulateDllLoader(GetCurrentProcess(), (char*)ImportNamePtr);
hLoadedModuleSimulated = true;
}
}
}
if(ImportIID->OriginalFirstThunk != NULL)
{
ThunkData64 = (PIMAGE_THUNK_DATA64)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, (ULONG_PTR)((ULONG_PTR)ImportIID->OriginalFirstThunk + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase), false, true);
CurrentThunk = (ULONG_PTR)ImportIID->OriginalFirstThunk;
}
else
{
ThunkData32 = (PIMAGE_THUNK_DATA32)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, (ULONG_PTR)PEHeader32->OptionalHeader.ImageBase, (ULONG_PTR)((ULONG_PTR)ImportIID->FirstThunk + PEHeader32->OptionalHeader.ImageBase), false, true);
CurrentThunk = (ULONG_PTR)ImportIID->FirstThunk;
}
if(ThunkData64 != NULL)
{
while(ThunkData64->u1.AddressOfData != NULL)
{
if(ThunkData64->u1.Ordinal & IMAGE_ORDINAL_FLAG64)
{
if((int)(ThunkData64->u1.Ordinal ^ IMAGE_ORDINAL_FLAG64) >= 0x10000)
{
FileFixed = false;
}
}
else
{
ImportNamePtr = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, (ULONG_PTR)((ULONG_PTR)ThunkData64->u1.AddressOfData + 2 + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase), false, true);
if(ImportNamePtr != NULL)
{
if(EngineIsBadReadPtrEx((LPVOID)ImportNamePtr, 8))
{
if(hLoadedModule != NULL)
{
if(EngineGetProcAddress((ULONG_PTR)hLoadedModule, (char*)ImportNamePtr) == NULL)
{
OrdinalBase = NULL;
OrdinalCount = NULL;
if(EngineGetLibraryOrdinalData((ULONG_PTR)hLoadedModule, &OrdinalBase, &OrdinalCount))
{
if(OrdinalBase != NULL && OrdinalCount != NULL)
{
ThunkData64->u1.Ordinal = (OrdinalBase + 1) ^ IMAGE_ORDINAL_FLAG64;
}
else
{
FileFixed = false;
}
}
}
}
}
}
}
CurrentThunk = CurrentThunk + 8;
ThunkData64 = (PIMAGE_THUNK_DATA64)((ULONG_PTR)ThunkData64 + sizeof IMAGE_THUNK_DATA64);
}
}
if(hLoadedModuleSimulated)
{
VirtualFree((LPVOID)hLoadedModule, NULL, MEM_RELEASE);
}
ImportIID = (PIMAGE_IMPORT_DESCRIPTOR)((ULONG_PTR)ImportIID + sizeof IMAGE_IMPORT_DESCRIPTOR);
}
}
}
}
/*
Fixing Export table
*/
if(myFileStatusInfo->ExportTable == UE_FIELD_NOT_PRESET_WARNING)
{
FileFixed = false;
}
else if(myFileFixInfo->DontFixExports == false && myFileStatusInfo->ExportTable != UE_FIELD_OK && myFileStatusInfo->ExportTable != UE_FIELD_NOT_PRESET)
{
if(PEHeader64->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_EXPORT && PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress != NULL)
{
if(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress > CorrectedImageSize || PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size > CorrectedImageSize)
{
myFileFixInfo->StrippedExports = true;
myFileFixInfo->OriginalExportTableAddress = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
myFileFixInfo->OriginalExportTableSize = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = NULL;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = NULL;
}
else
{
FeatureFixed = true;
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress != NULL)
{
if(EngineIsBadReadPtrEx((LPVOID)ConvertedAddress, PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size))
{
PEExports = (PIMAGE_EXPORT_DIRECTORY)ConvertedAddress;
if(PEExports->AddressOfFunctions > CorrectedImageSize || PEExports->AddressOfFunctions + 4 * PEExports->NumberOfFunctions > CorrectedImageSize)
{
FeatureFixed = false;
}
else if(PEExports->AddressOfNameOrdinals > CorrectedImageSize || PEExports->AddressOfNameOrdinals + 4 * PEExports->NumberOfNames > CorrectedImageSize)
{
FeatureFixed = false;
}
else if(PEExports->AddressOfNames > CorrectedImageSize || PEExports->AddressOfNames + 4 * PEExports->NumberOfNames > CorrectedImageSize)
{
FeatureFixed = false;
}
else if(PEExports->Name > CorrectedImageSize)
{
FeatureFixed = false;
}
if(!FeatureFixed)
{
myFileFixInfo->StrippedExports = true;
myFileFixInfo->OriginalExportTableAddress = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
myFileFixInfo->OriginalExportTableSize = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = NULL;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = NULL;
}
}
else
{
myFileFixInfo->StrippedExports = true;
myFileFixInfo->OriginalExportTableAddress = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
myFileFixInfo->OriginalExportTableSize = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = NULL;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = NULL;
}
}
}
}
}
/*
Fixing Relocation table
*/
if(myFileStatusInfo->FileIsDLL == true && myFileStatusInfo->RelocationTable == UE_FIELD_BROKEN_NON_FIXABLE)
{
FileFixed = false;
}
else if(myFileFixInfo->DontFixRelocations == false && myFileStatusInfo->RelocationTable != UE_FIELD_OK)
{
if(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress > CorrectedImageSize || PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress + PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size > CorrectedImageSize)
{
if(myFileStatusInfo->FileIsDLL)
{
FileFixed = false;
}
else
{
myFileFixInfo->StrippedRelocation = true;
myFileFixInfo->OriginalRelocationTableAddress = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
myFileFixInfo->OriginalRelocationTableSize = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = NULL;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = NULL;
}
}
else
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress != NULL)
{
if(EngineIsBadReadPtrEx((LPVOID)ConvertedAddress, PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size))
{
RtlMoveMemory(&ReadData, (LPVOID)ConvertedAddress, 4);
RtlMoveMemory(&ReadSize, (LPVOID)(ConvertedAddress + 4), 4);
while(ReadData != NULL)
{
ReadSize = ReadSize - 8;
ConvertedAddress = ConvertedAddress + 8;
while(ReadSize > NULL)
{
RtlMoveMemory(&ReadDataWORD, (LPVOID)ConvertedAddress, 2);
if(ReadDataWORD > 0xCFFF)
{
RtlZeroMemory((LPVOID)ConvertedAddress, 2);
}
ConvertedAddress = ConvertedAddress + 2;
ReadSize = ReadSize - 2;
}
RtlMoveMemory(&ReadData, (LPVOID)ConvertedAddress, 4);
RtlMoveMemory(&ReadSize, (LPVOID)(ConvertedAddress + 4), 4);
}
}
else
{
if(myFileStatusInfo->FileIsDLL)
{
FileFixed = false;
}
else
{
myFileFixInfo->StrippedRelocation = true;
myFileFixInfo->OriginalRelocationTableAddress = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
myFileFixInfo->OriginalRelocationTableSize = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = NULL;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = NULL;
}
}
}
else
{
if(myFileStatusInfo->FileIsDLL)
{
FileFixed = false;
}
else
{
myFileFixInfo->StrippedRelocation = true;
myFileFixInfo->OriginalRelocationTableAddress = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
myFileFixInfo->OriginalRelocationTableSize = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = NULL;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = NULL;
}
}
}
}
else if(myFileStatusInfo->RelocationTable == UE_FIELD_OK)
{
// Filter case!
}
else
{
FileFixed = false;
}
/*
Fixing Resource table
*/
if(myFileFixInfo->DontFixResources == false && myFileStatusInfo->ResourceData != UE_FIELD_OK && myFileStatusInfo->ResourceData != UE_FIELD_NOT_PRESET)
{
myFileFixInfo->StrippedResources = true;
myFileFixInfo->OriginalResourceTableAddress = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;
myFileFixInfo->OriginalResourceTableSize = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = NULL;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = NULL;
}
else if(myFileFixInfo->DontFixResources == false && myFileStatusInfo->ResourceTable != UE_FIELD_OK && myFileStatusInfo->ResourceTable != UE_FIELD_NOT_PRESET)
{
if(PEHeader64->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_RESOURCE && PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress != NULL)
{
if(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress > CorrectedImageSize || PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress + PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size > CorrectedImageSize)
{
myFileFixInfo->StrippedResources = true;
myFileFixInfo->OriginalResourceTableAddress = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;
myFileFixInfo->OriginalResourceTableSize = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = NULL;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = NULL;
}
else
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress == NULL || ConvertedAddress - FileMapVA > FileSize || ConvertedAddress - FileMapVA + PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size > FileSize)
{
myFileFixInfo->StrippedResources = true;
myFileFixInfo->OriginalResourceTableAddress = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;
myFileFixInfo->OriginalResourceTableSize = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = NULL;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = NULL;
}
}
}
}
/*
Fixing TLS table
*/
if(myFileFixInfo->DontFixTLS == false && myFileStatusInfo->TLSTable != UE_FIELD_OK && myFileStatusInfo->TLSTable != UE_FIELD_NOT_PRESET)
{
if(PEHeader64->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_TLS && PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress != NULL)
{
if(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress > CorrectedImageSize || PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress + PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size > CorrectedImageSize)
{
myFileFixInfo->StrippedTLS = true;
myFileFixInfo->OriginalTLSTableAddress = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress;
myFileFixInfo->OriginalTLSTableSize = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress = NULL;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size = NULL;
}
else
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress == NULL || ConvertedAddress - FileMapVA > FileSize)
{
myFileFixInfo->StrippedTLS = true;
myFileFixInfo->OriginalTLSTableAddress = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress;
myFileFixInfo->OriginalTLSTableSize = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress = NULL;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size = NULL;
}
else
{
FeatureFixed = true;
PETls64 = (PIMAGE_TLS_DIRECTORY64)ConvertedAddress;
if(PETls64->StartAddressOfRawData != NULL && (PETls64->StartAddressOfRawData < (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase || PETls64->StartAddressOfRawData > CorrectedImageSize + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase))
{
FeatureFixed = false;
}
else if(PETls64->EndAddressOfRawData != NULL && (PETls64->EndAddressOfRawData < (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase || PETls64->EndAddressOfRawData > CorrectedImageSize + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase))
{
FeatureFixed = false;
}
else if(PETls64->AddressOfIndex != NULL && (PETls64->AddressOfIndex < (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase || PETls64->AddressOfIndex > CorrectedImageSize + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase))
{
FeatureFixed = false;
}
else if(PETls64->AddressOfCallBacks != NULL && (PETls64->AddressOfCallBacks < (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase || PETls64->AddressOfCallBacks > CorrectedImageSize + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase))
{
FeatureFixed = false;
}
if(!FeatureFixed)
{
myFileFixInfo->StrippedTLS = true;
myFileFixInfo->OriginalTLSTableAddress = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress;
myFileFixInfo->OriginalTLSTableSize = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress = NULL;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size = NULL;
}
else
{
if(PETls64->AddressOfCallBacks != NULL)
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, (ULONG_PTR)PETls64->AddressOfCallBacks + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress != NULL)
{
while(ReadData != NULL)
{
RtlMoveMemory(&ReadDataQWORD, (LPVOID)ConvertedAddress, 8);
if(ReadDataQWORD < (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase || ReadDataQWORD > CorrectedImageSize + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase)
{
RtlZeroMemory((LPVOID)ConvertedAddress, 8);
}
ConvertedAddress = ConvertedAddress + 8;
}
}
}
}
}
}
}
}
/*
Fix Load config table
*/
if(myFileFixInfo->DontFixLoadConfig == false && myFileStatusInfo->LoadConfigTable != UE_FIELD_OK && myFileStatusInfo->LoadConfigTable != UE_FIELD_NOT_PRESET)
{
if(PEHeader64->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG && PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress != NULL)
{
if(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress > CorrectedImageSize || PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress + PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].Size > CorrectedImageSize)
{
myFileFixInfo->StrippedLoadConfig = true;
myFileFixInfo->OriginalLoadConfigTableAddress = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress;
myFileFixInfo->OriginalLoadConfigTableSize = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].Size;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress = NULL;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].Size = NULL;
}
else
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress == NULL || ConvertedAddress - FileMapVA > FileSize)
{
myFileFixInfo->StrippedLoadConfig = true;
myFileFixInfo->OriginalLoadConfigTableAddress = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress;
myFileFixInfo->OriginalLoadConfigTableSize = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].Size;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress = NULL;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].Size = NULL;
}
}
}
}
/*
Fix Bound import table
*/
if(myFileFixInfo->DontFixBoundImports == false && myFileStatusInfo->BoundImportTable != UE_FIELD_OK && myFileStatusInfo->BoundImportTable != UE_FIELD_NOT_PRESET)
{
if(PEHeader64->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT && PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress != NULL)
{
if(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress > CorrectedImageSize || PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress + PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size > CorrectedImageSize)
{
myFileFixInfo->StrippedBoundImports = true;
myFileFixInfo->OriginalBoundImportTableAddress = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress;
myFileFixInfo->OriginalBoundImportTableSize = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = NULL;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = NULL;
}
else
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress == NULL || ConvertedAddress - FileMapVA > FileSize)
{
myFileFixInfo->StrippedBoundImports = true;
myFileFixInfo->OriginalBoundImportTableAddress = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress;
myFileFixInfo->OriginalBoundImportTableSize = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = NULL;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = NULL;
}
}
}
}
/*
Fix IAT
*/
if(myFileFixInfo->DontFixIAT == false && myFileStatusInfo->IATTable != UE_FIELD_OK && myFileStatusInfo->IATTable != UE_FIELD_NOT_PRESET)
{
if(PEHeader64->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_IAT && PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress != NULL)
{
if(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress > CorrectedImageSize || PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress + PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size > CorrectedImageSize)
{
myFileFixInfo->StrippedIAT = true;
myFileFixInfo->OriginalImportAddressTableAddress = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress;
myFileFixInfo->OriginalImportAddressTableSize = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = NULL;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = NULL;
}
else
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress == NULL || ConvertedAddress - FileMapVA > FileSize)
{
myFileFixInfo->StrippedIAT = true;
myFileFixInfo->OriginalImportAddressTableAddress = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress;
myFileFixInfo->OriginalImportAddressTableSize = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = NULL;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = NULL;
}
}
}
}
/*
Fix COM header
*/
if(myFileFixInfo->DontFixCOM == false && myFileStatusInfo->COMHeaderTable != UE_FIELD_OK && myFileStatusInfo->COMHeaderTable != UE_FIELD_NOT_PRESET)
{
if(PEHeader64->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR && PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress != NULL)
{
if(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress > CorrectedImageSize || PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress + PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size > CorrectedImageSize)
{
myFileFixInfo->StrippedCOM = true;
myFileFixInfo->OriginalCOMTableAddress = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress;
myFileFixInfo->OriginalCOMTableSize = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress = NULL;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size = NULL;
}
else
{
ConvertedAddress = (ULONG_PTR)ConvertVAtoFileOffsetEx(FileMapVA, FileSize, NULL, PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, false, true);
if(ConvertedAddress == NULL || ConvertedAddress - FileMapVA > FileSize)
{
myFileFixInfo->StrippedCOM = true;
myFileFixInfo->OriginalCOMTableAddress = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress;
myFileFixInfo->OriginalCOMTableSize = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress = NULL;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size = NULL;
}
}
}
}
/*
Fix sections and SizeOfImage
*/
if(myFileStatusInfo->SectionTable != UE_FIELD_OK || myFileStatusInfo->SizeOfImage != UE_FIELD_OK)
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader64 + PEHeader64->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
NumberOfSections = PEHeader64->FileHeader.NumberOfSections;
while(NumberOfSections > NULL)
{
SectionVirtualSize = PESections->VirtualAddress + PESections->Misc.VirtualSize;
if(PESections->Misc.VirtualSize % PEHeader64->OptionalHeader.SectionAlignment == NULL)
{
SectionVirtualSizeFixed = SectionVirtualSize;
}
else
{
SectionVirtualSizeFixed = PESections->VirtualAddress + (((PESections->Misc.VirtualSize / PEHeader64->OptionalHeader.SectionAlignment) + 1) * PEHeader64->OptionalHeader.SectionAlignment);
}
if(NumberOfSections > 1)
{
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + sizeof IMAGE_SECTION_HEADER);
if(SectionVirtualSize > PESections->VirtualAddress || SectionVirtualSizeFixed > PESections->VirtualAddress)
{
PESections->Misc.VirtualSize = SectionVirtualSizeFixed;
}
}
NumberOfSections--;
}
if(PESections->PointerToRawData + PESections->SizeOfRawData > FileSize && PESections->SizeOfRawData != NULL)
{
PESections->SizeOfRawData = FileSize - PESections->PointerToRawData;
}
if(myFileStatusInfo->SizeOfImage != UE_FIELD_OK)
{
SectionVirtualSizeFixed = SectionVirtualSizeFixed + 0xF000;
if(PEHeader64->OptionalHeader.SizeOfImage > SectionVirtualSizeFixed)
{
PEHeader64->OptionalHeader.SizeOfImage = SectionVirtualSizeFixed - 0xF000;
}
}
}
/*
Entry point check
*/
if(myFileStatusInfo->EntryPoint != UE_FIELD_OK)
{
SectionNumber = GetPE32SectionNumberFromVA(FileMapVA, PEHeader64->OptionalHeader.AddressOfEntryPoint + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase);
if(SectionNumber != -1)
{
SectionAttributes = (DWORD)GetPE32DataFromMappedFile(FileMapVA, SectionNumber, UE_SECTIONFLAGS);
if(SectionAttributes & IMAGE_SCN_MEM_EXECUTE || SectionAttributes & IMAGE_SCN_CNT_CODE)
{
// Should never execute
}
else
{
if(!SetPE32DataForMappedFile(FileMapVA, SectionNumber, UE_SECTIONFLAGS, 0xE0000020))
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
}
}
/*
Fix end
*/
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
if(FileFixed)
{
myFileFixInfo->OveralEvaluation = UE_RESULT_FILE_OK;
myFileFixInfo->FileFixPerformed = FileFixed;
}
return(true);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
myFileFixInfo->FixingTerminatedByException = true;
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
}
else if(myFileFixInfo->FileFixPerformed)
{
if(MapFileExW(szFileName, UE_ACCESS_ALL, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, FileHandle, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->Signature == 0x4550 && PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->Signature == 0x4550 && PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
if(!FileIs64)
{
if(myFileFixInfo->StrippedRelocation)
{
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = myFileFixInfo->OriginalRelocationTableAddress;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = myFileFixInfo->OriginalRelocationTableSize;
}
if(myFileFixInfo->StrippedExports)
{
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = myFileFixInfo->OriginalExportTableAddress;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = myFileFixInfo->OriginalExportTableSize;
}
if(myFileFixInfo->StrippedResources)
{
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = myFileFixInfo->OriginalResourceTableAddress;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = myFileFixInfo->OriginalResourceTableSize;
}
if(myFileFixInfo->StrippedTLS)
{
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress = myFileFixInfo->OriginalTLSTableAddress;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size = myFileFixInfo->OriginalTLSTableSize;
}
if(myFileFixInfo->StrippedLoadConfig)
{
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress = myFileFixInfo->OriginalLoadConfigTableAddress;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].Size = myFileFixInfo->OriginalLoadConfigTableSize;
}
if(myFileFixInfo->StrippedBoundImports)
{
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = myFileFixInfo->OriginalBoundImportTableAddress;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = myFileFixInfo->OriginalBoundImportTableSize;
}
if(myFileFixInfo->StrippedIAT)
{
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress = myFileFixInfo->OriginalImportAddressTableAddress;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size = myFileFixInfo->OriginalImportAddressTableSize;
}
if(myFileFixInfo->StrippedCOM)
{
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress = myFileFixInfo->OriginalCOMTableAddress;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size = myFileFixInfo->OriginalCOMTableSize;
}
}
else
{
if(myFileFixInfo->StrippedRelocation)
{
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = myFileFixInfo->OriginalRelocationTableAddress;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = myFileFixInfo->OriginalRelocationTableSize;
}
if(myFileFixInfo->StrippedExports)
{
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = myFileFixInfo->OriginalExportTableAddress;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = myFileFixInfo->OriginalExportTableSize;
}
if(myFileFixInfo->StrippedResources)
{
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = myFileFixInfo->OriginalResourceTableAddress;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = myFileFixInfo->OriginalResourceTableSize;
}
if(myFileFixInfo->StrippedTLS)
{
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress = myFileFixInfo->OriginalTLSTableAddress;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size = myFileFixInfo->OriginalTLSTableSize;
}
if(myFileFixInfo->StrippedLoadConfig)
{
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress = myFileFixInfo->OriginalLoadConfigTableAddress;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].Size = myFileFixInfo->OriginalLoadConfigTableSize;
}
if(myFileFixInfo->StrippedBoundImports)
{
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = myFileFixInfo->OriginalBoundImportTableAddress;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = myFileFixInfo->OriginalBoundImportTableSize;
}
if(myFileFixInfo->StrippedIAT)
{
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress = myFileFixInfo->OriginalImportAddressTableAddress;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size = myFileFixInfo->OriginalImportAddressTableSize;
}
if(myFileFixInfo->StrippedCOM)
{
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress = myFileFixInfo->OriginalCOMTableAddress;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size = myFileFixInfo->OriginalCOMTableSize;
}
}
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(true);
}
}
}
return(false);
}
__declspec(dllexport) bool TITCALL IsFileDLL(char* szFileName, ULONG_PTR FileMapVA)
{
if(szFileName != NULL)
{
if((DWORD)GetPE32Data(szFileName, NULL, UE_CHARACTERISTICS) & 0x2000)
{
return(true);
}
}
else if(FileMapVA != NULL)
{
if((DWORD)GetPE32DataFromMappedFile(FileMapVA, NULL, UE_CHARACTERISTICS) & 0x2000)
{
return(true);
}
}
return(false);
}
__declspec(dllexport) bool TITCALL IsFileDLLW(wchar_t* szFileName, ULONG_PTR FileMapVA)
{
if(szFileName != NULL)
{
if((DWORD)GetPE32DataW(szFileName, NULL, UE_CHARACTERISTICS) & 0x2000)
{
return(true);
}
}
else if(FileMapVA != NULL)
{
if((DWORD)GetPE32DataFromMappedFile(FileMapVA, NULL, UE_CHARACTERISTICS) & 0x2000)
{
return(true);
}
}
return(false);
}
// Global.Engine.Hider.functions:
bool ChangeHideDebuggerState(HANDLE hProcess, DWORD PatchAPILevel, bool Hide)
{
ULONG_PTR AddressOfPEB = NULL;
ULONG_PTR ueNumberOfBytesRead = NULL;
BYTE patchCheckRemoteDebuggerPresent[5] = {0x33, 0xC0, 0xC2, 0x08, 0x00};
BYTE patchGetTickCount[3] = {0x33, 0xC0, 0xC3};
MEMORY_BASIC_INFORMATION MemInfo;
ULONG_PTR APIPatchAddress = NULL;
DWORD OldProtect;
NTPEB myPEB = {};
if(hProcess != NULL)
{
AddressOfPEB = (ULONG_PTR)GetPEBLocation(hProcess);
if(ReadProcessMemory(hProcess, (void*)AddressOfPEB, (void*)&myPEB, sizeof NTPEB, &ueNumberOfBytesRead))
{
if(Hide)
{
myPEB.BeingDebugged = false;
myPEB.NtGlobalFlag = NULL;
if(WriteProcessMemory(hProcess, (void*)AddressOfPEB, (void*)&myPEB, sizeof NTPEB, &ueNumberOfBytesRead))
{
if(PatchAPILevel == UE_HIDE_BASIC)
{
APIPatchAddress = (ULONG_PTR)EngineGlobalAPIHandler(hProcess, NULL, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"),"CheckRemoteDebuggerPresent"), NULL, UE_OPTION_IMPORTER_REALIGN_APIADDRESS);
VirtualQueryEx(dbgProcessInformation.hProcess, (LPVOID)APIPatchAddress, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
OldProtect = MemInfo.AllocationProtect;
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)APIPatchAddress, 5, PAGE_EXECUTE_READWRITE, &OldProtect);
WriteProcessMemory(hProcess, (LPVOID)(APIPatchAddress), &patchCheckRemoteDebuggerPresent, 5, &ueNumberOfBytesRead);
APIPatchAddress = (ULONG_PTR)EngineGlobalAPIHandler(hProcess, NULL, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"),"GetTickCount"), NULL, UE_OPTION_IMPORTER_REALIGN_APIADDRESS);
VirtualQueryEx(dbgProcessInformation.hProcess, (LPVOID)APIPatchAddress, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
OldProtect = MemInfo.AllocationProtect;
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)APIPatchAddress, 3, PAGE_EXECUTE_READWRITE, &OldProtect);
WriteProcessMemory(hProcess, (LPVOID)(APIPatchAddress), &patchGetTickCount, 3, &ueNumberOfBytesRead);
}
return(true);
}
else
{
return(false);
}
}
else
{
myPEB.BeingDebugged = true;
if(WriteProcessMemory(hProcess, (void*)AddressOfPEB, (void*)&myPEB, sizeof NTPEB, &ueNumberOfBytesRead))
{
if(PatchAPILevel == UE_HIDE_BASIC)
{
APIPatchAddress = (ULONG_PTR)EngineGlobalAPIHandler(hProcess, NULL, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"),"CheckRemoteDebuggerPresent"), NULL, UE_OPTION_IMPORTER_REALIGN_APIADDRESS);
VirtualQueryEx(dbgProcessInformation.hProcess, (LPVOID)APIPatchAddress, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
OldProtect = MemInfo.AllocationProtect;
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)APIPatchAddress, 5, PAGE_EXECUTE_READWRITE, &OldProtect);
WriteProcessMemory(hProcess, (LPVOID)(APIPatchAddress), (void*)GetProcAddress(GetModuleHandleA("kernel32.dll"),"CheckRemoteDebuggerPresent"), 5, &ueNumberOfBytesRead);
APIPatchAddress = (ULONG_PTR)EngineGlobalAPIHandler(hProcess, NULL, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"),"GetTickCount"), NULL, UE_OPTION_IMPORTER_REALIGN_APIADDRESS);
VirtualQueryEx(dbgProcessInformation.hProcess, (LPVOID)APIPatchAddress, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
OldProtect = MemInfo.AllocationProtect;
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)APIPatchAddress, 3, PAGE_EXECUTE_READWRITE, &OldProtect);
WriteProcessMemory(hProcess, (LPVOID)(APIPatchAddress), (void*)GetProcAddress(GetModuleHandleA("kernel32.dll"),"GetTickCount"), 3, &ueNumberOfBytesRead);
}
return(true);
}
else
{
return(false);
}
}
}
else
{
return(false);
}
}
else
{
return(false);
}
return(false);
}
// TitanEngine.Hider.functions:
__declspec(dllexport) void* TITCALL GetPEBLocation(HANDLE hProcess)
{
ULONG RequiredLen = NULL;
PPROCESS_BASIC_INFORMATION myProcessBasicInformation = (PPROCESS_BASIC_INFORMATION)VirtualAlloc(NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE);
if(!myProcessBasicInformation)
return 0;
#if !defined(_WIN64)
typedef NTSTATUS(WINAPI *fZwQueryInformationProcess)(HANDLE ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength);
#else
typedef NTSTATUS(__fastcall *fZwQueryInformationProcess)(HANDLE ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength);
#endif
LPVOID ZwQueryInformationProcess = (LPVOID)GetProcAddress(GetModuleHandleA("ntdll.dll"),"ZwQueryInformationProcess");
fZwQueryInformationProcess cZwQueryInformationProcess = (fZwQueryInformationProcess)(ZwQueryInformationProcess);
if(cZwQueryInformationProcess != NULL)
{
if(cZwQueryInformationProcess(hProcess, ProcessBasicInformation, myProcessBasicInformation, sizeof PROCESS_BASIC_INFORMATION, &RequiredLen) == STATUS_SUCCESS)
{
return((void*)myProcessBasicInformation->PebBaseAddress);
}
else
{
if(cZwQueryInformationProcess(hProcess, ProcessBasicInformation, myProcessBasicInformation, RequiredLen, &RequiredLen) == STATUS_SUCCESS)
{
return((void*)myProcessBasicInformation->PebBaseAddress);
}
}
}
return(NULL);
}
__declspec(dllexport) bool TITCALL HideDebugger(HANDLE hProcess, DWORD PatchAPILevel)
{
return(ChangeHideDebuggerState(hProcess, PatchAPILevel, true));
}
__declspec(dllexport) bool TITCALL UnHideDebugger(HANDLE hProcess, DWORD PatchAPILevel)
{
return(ChangeHideDebuggerState(hProcess, PatchAPILevel, false));
}
// TitanEngine.Relocater.functions:
__declspec(dllexport) void TITCALL RelocaterCleanup()
{
if(RelocationData != NULL)
{
VirtualFree(RelocationData, NULL, MEM_RELEASE);
RelocationLastPage = NULL;
RelocationStartPosition = NULL;
RelocationWritePosition = NULL;
RelocationOldImageBase = NULL;
RelocationNewImageBase = NULL;
}
}
__declspec(dllexport) void TITCALL RelocaterInit(DWORD MemorySize, ULONG_PTR OldImageBase, ULONG_PTR NewImageBase)
{
if(RelocationData != NULL)
{
VirtualFree(RelocationData, NULL, MEM_RELEASE);
}
RelocationData = VirtualAlloc(NULL, MemorySize, MEM_COMMIT, PAGE_READWRITE);
RelocationLastPage = NULL;
RelocationStartPosition = RelocationData;
RelocationWritePosition = (LPVOID)((ULONG_PTR)RelocationData + 8);
RelocationOldImageBase = OldImageBase;
RelocationNewImageBase = NewImageBase;
}
__declspec(dllexport) void TITCALL RelocaterAddNewRelocation(HANDLE hProcess, ULONG_PTR RelocateAddress, DWORD RelocateState)
{
MEMORY_BASIC_INFORMATION MemInfo;
DWORD CompareDummy = NULL;
DWORD CopyDummy = NULL;
VirtualQueryEx(hProcess, (LPVOID)RelocateAddress, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
if(MemInfo.BaseAddress != RelocationLastPage || RelocationLastPage == NULL)
{
RelocationLastPage = MemInfo.BaseAddress;
if(memcmp(RelocationStartPosition, &CompareDummy, 4) == NULL)
{
CopyDummy = (DWORD)((ULONG_PTR)MemInfo.BaseAddress - (ULONG_PTR)RelocationNewImageBase);
RtlMoveMemory(RelocationStartPosition, &CopyDummy, 4);
}
else
{
CopyDummy = (DWORD)((ULONG_PTR)RelocationWritePosition - (ULONG_PTR)RelocationStartPosition);
if(CopyDummy % 4 == NULL)
{
RtlMoveMemory((LPVOID)((ULONG_PTR)RelocationStartPosition + 4), &CopyDummy, 4);
}
else
{
RelocationWritePosition = (LPVOID)((ULONG_PTR)RelocationWritePosition + 2);
CopyDummy = (DWORD)((ULONG_PTR)RelocationWritePosition - (ULONG_PTR)RelocationStartPosition);
if(CopyDummy % 4 == NULL)
{
RtlMoveMemory((LPVOID)((ULONG_PTR)RelocationStartPosition + 4), &CopyDummy, 4);
}
else
{
RelocationWritePosition = (LPVOID)((ULONG_PTR)RelocationWritePosition + 2);
CopyDummy = (DWORD)((ULONG_PTR)RelocationWritePosition - (ULONG_PTR)RelocationStartPosition);
RtlMoveMemory((LPVOID)((ULONG_PTR)RelocationStartPosition + 4), &CopyDummy, 4);
}
}
RelocationStartPosition = RelocationWritePosition;
CopyDummy = (DWORD)((ULONG_PTR)RelocationLastPage - (ULONG_PTR)RelocationNewImageBase);
RtlMoveMemory(RelocationWritePosition, &CopyDummy, 4);
RelocationWritePosition = (LPVOID)((ULONG_PTR)RelocationWritePosition + 8);
}
}
#if !defined(_WIN64)
CopyDummy = (DWORD)((RelocateAddress - (ULONG_PTR)RelocationLastPage) ^ 0x3000);
#else
CopyDummy = (DWORD)((RelocateAddress - (ULONG_PTR)RelocationLastPage) ^ 0x8000);
#endif
RtlMoveMemory(RelocationWritePosition, &CopyDummy, 2);
RelocationWritePosition = (LPVOID)((ULONG_PTR)RelocationWritePosition + 2);
}
__declspec(dllexport) long TITCALL RelocaterEstimatedSize()
{
return((DWORD)((ULONG_PTR)RelocationWritePosition - (ULONG_PTR)RelocationData + 8));
}
__declspec(dllexport) bool TITCALL RelocaterExportRelocation(ULONG_PTR StorePlace, DWORD StorePlaceRVA, ULONG_PTR FileMapVA)
{
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
BOOL FileIs64 = false;
DWORD CopyDummy = NULL;
__try
{
if((ULONG_PTR)RelocationStartPosition != -1)
{
CopyDummy = (DWORD)((ULONG_PTR)RelocationWritePosition - (ULONG_PTR)RelocationStartPosition);
if(CopyDummy % 4 == NULL)
{
RtlMoveMemory((LPVOID)((ULONG_PTR)RelocationStartPosition + 4), &CopyDummy, 4);
}
else
{
RelocationWritePosition = (LPVOID)((ULONG_PTR)RelocationWritePosition + 2);
CopyDummy = (DWORD)((ULONG_PTR)RelocationWritePosition - (ULONG_PTR)RelocationStartPosition);
if(CopyDummy % 4 == NULL)
{
RtlMoveMemory((LPVOID)((ULONG_PTR)RelocationStartPosition + 4), &CopyDummy, 4);
}
else
{
RelocationWritePosition = (LPVOID)((ULONG_PTR)RelocationWritePosition + 2);
CopyDummy = (DWORD)((ULONG_PTR)RelocationWritePosition - (ULONG_PTR)RelocationStartPosition);
RtlMoveMemory((LPVOID)((ULONG_PTR)RelocationStartPosition + 4), &CopyDummy, 4);
}
}
}
RtlMoveMemory((LPVOID)StorePlace, RelocationData, (DWORD)((ULONG_PTR)RelocationWritePosition - (ULONG_PTR)RelocationData));
VirtualFree(RelocationData, NULL, MEM_RELEASE);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return(false);
}
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, NULL, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
RelocationData = NULL;
return(false);
}
if(!FileIs64)
{
PEHeader32->OptionalHeader.ImageBase = (DWORD)RelocationNewImageBase;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = StorePlaceRVA;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = (DWORD)((ULONG_PTR)RelocationWritePosition - (ULONG_PTR)RelocationData);
}
else
{
PEHeader64->OptionalHeader.ImageBase = (ULONG_PTR)RelocationNewImageBase;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = StorePlaceRVA;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = (DWORD)((ULONG_PTR)RelocationWritePosition - (ULONG_PTR)RelocationData);
}
RelocationData = NULL;
return(true);
}
RelocationData = NULL;
return(false);
}
__declspec(dllexport) bool TITCALL RelocaterExportRelocationEx(char* szFileName, char* szSectionName)
{
wchar_t uniFileName[MAX_PATH] = {};
if(szFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
return(RelocaterExportRelocationExW(uniFileName, szSectionName));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL RelocaterExportRelocationExW(wchar_t* szFileName, char* szSectionName)
{
HANDLE FileHandle;
DWORD FileSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
DWORD NewSectionVO = NULL;
DWORD NewSectionFO = NULL;
bool ReturnValue = false;
if(RelocaterEstimatedSize() > NULL)
{
NewSectionVO = AddNewSectionW(szFileName, szSectionName, RelocaterEstimatedSize());
if(MapFileExW(szFileName, UE_ACCESS_ALL, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
NewSectionFO = (DWORD)ConvertVAtoFileOffset(FileMapVA, NewSectionVO + (ULONG_PTR)GetPE32DataFromMappedFile(FileMapVA, NULL, UE_IMAGEBASE), true);
ReturnValue = RelocaterExportRelocation(NewSectionFO, NewSectionVO, FileMapVA);
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
if(ReturnValue)
{
return(true);
}
else
{
return(false);
}
}
else
{
return(false);
}
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL RelocaterGrabRelocationTable(HANDLE hProcess, ULONG_PTR MemoryStart, DWORD MemorySize)
{
MEMORY_BASIC_INFORMATION MemInfo;
ULONG_PTR ueNumberOfBytesRead = NULL;
DWORD OldProtect;
if(RelocationData != NULL)
{
VirtualQueryEx(hProcess, (LPVOID)MemoryStart, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
OldProtect = MemInfo.AllocationProtect;
VirtualProtectEx(hProcess, (LPVOID)MemoryStart, MemorySize, PAGE_EXECUTE_READWRITE, &OldProtect);
if(ReadProcessMemory(hProcess, (LPVOID)MemoryStart, RelocationData, MemorySize, &ueNumberOfBytesRead))
{
RelocationWritePosition = (LPVOID)((ULONG_PTR)RelocationData + MemorySize);
RelocationStartPosition = (LPVOID)(-1);
return(true);
}
}
return(false);
}
__declspec(dllexport) bool TITCALL RelocaterGrabRelocationTableEx(HANDLE hProcess, ULONG_PTR MemoryStart, ULONG_PTR MemorySize, DWORD NtSizeOfImage)
{
MEMORY_BASIC_INFORMATION MemInfo;
LPVOID ReadMemoryStorage = NULL;
LPVOID mReadMemoryStorage = NULL;
ULONG_PTR ueNumberOfBytesRead = NULL;
DWORD CompareDummy = NULL;
DWORD RelocationBase = NULL;
DWORD RelocationSize = NULL;
DWORD OldProtect;
if(RelocationData != NULL)
{
VirtualQueryEx(hProcess, (LPVOID)MemoryStart, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
OldProtect = MemInfo.AllocationProtect;
VirtualQueryEx(hProcess, (LPVOID)MemInfo.BaseAddress, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
if(MemInfo.RegionSize < MemorySize || MemorySize == NULL)
{
MemorySize = MemInfo.RegionSize;
}
VirtualProtectEx(hProcess, (LPVOID)MemoryStart, MemorySize, PAGE_EXECUTE_READWRITE, &OldProtect);
ReadMemoryStorage = VirtualAlloc(NULL, MemorySize, MEM_COMMIT, PAGE_READWRITE);
mReadMemoryStorage = ReadMemoryStorage;
if(ReadProcessMemory(hProcess, (LPVOID)MemoryStart, ReadMemoryStorage, MemorySize, &ueNumberOfBytesRead))
{
RtlMoveMemory(&RelocationBase, ReadMemoryStorage, 4);
RtlMoveMemory(&RelocationSize, (LPVOID)((ULONG_PTR)ReadMemoryStorage + 4), 4);
while(memcmp(ReadMemoryStorage, &CompareDummy, 4) != NULL && RelocationBase < NtSizeOfImage && RelocationSize < 0x2000)
{
ReadMemoryStorage = (LPVOID)((ULONG_PTR)ReadMemoryStorage + RelocationSize);
RtlMoveMemory(&RelocationBase, ReadMemoryStorage, 4);
RtlMoveMemory(&RelocationSize, (LPVOID)((ULONG_PTR)ReadMemoryStorage + 4), 4);
}
VirtualFree(mReadMemoryStorage, NULL, MEM_RELEASE);
return(RelocaterGrabRelocationTable(hProcess, MemoryStart, (DWORD)((ULONG_PTR)ReadMemoryStorage - (ULONG_PTR)mReadMemoryStorage)));
}
else
{
VirtualFree(ReadMemoryStorage, NULL, MEM_RELEASE);
return(false);
}
}
return(false);
}
__declspec(dllexport) bool TITCALL RelocaterMakeSnapshot(HANDLE hProcess, char* szSaveFileName, LPVOID MemoryStart, ULONG_PTR MemorySize)
{
return(DumpMemory(hProcess, MemoryStart, MemorySize, szSaveFileName));
}
__declspec(dllexport) bool TITCALL RelocaterMakeSnapshotW(HANDLE hProcess, wchar_t* szSaveFileName, LPVOID MemoryStart, ULONG_PTR MemorySize)
{
return(DumpMemoryW(hProcess, MemoryStart, MemorySize, szSaveFileName));
}
__declspec(dllexport) bool TITCALL RelocaterCompareTwoSnapshots(HANDLE hProcess, ULONG_PTR LoadedImageBase, ULONG_PTR NtSizeOfImage, char* szDumpFile1, char* szDumpFile2, ULONG_PTR MemStart)
{
wchar_t uniDumpFile1[MAX_PATH] = {};
wchar_t uniDumpFile2[MAX_PATH] = {};
if(szDumpFile1 != NULL && szDumpFile2 != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szDumpFile1, lstrlenA(szDumpFile1)+1, uniDumpFile1, sizeof(uniDumpFile1)/(sizeof(uniDumpFile1[0])));
MultiByteToWideChar(CP_ACP, NULL, szDumpFile2, lstrlenA(szDumpFile2)+1, uniDumpFile2, sizeof(uniDumpFile2)/(sizeof(uniDumpFile2[0])));
return(RelocaterCompareTwoSnapshotsW(hProcess, LoadedImageBase, NtSizeOfImage, uniDumpFile1, uniDumpFile2, MemStart));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL RelocaterCompareTwoSnapshotsW(HANDLE hProcess, ULONG_PTR LoadedImageBase, ULONG_PTR NtSizeOfImage, wchar_t* szDumpFile1, wchar_t* szDumpFile2, ULONG_PTR MemStart)
{
int i = NULL;
ULONG_PTR DeltaByte = NULL;
int RelativeBase = NULL;
ULONG_PTR ReadData = NULL;
HANDLE FileHandle1;
DWORD FileSize1;
HANDLE FileMap1;
ULONG_PTR FileMapVA1;
HANDLE FileHandle2;
DWORD FileSize2;
HANDLE FileMap2;
ULONG_PTR FileMapVA2;
DWORD SearchSize;
LPVOID Search1;
LPVOID Search2;
DWORD bkSearchSize;
LPVOID bkSearch1;
LPVOID bkSearch2;
if(MapFileExW(szDumpFile1, UE_ACCESS_READ, &FileHandle1, &FileSize1, &FileMap1, &FileMapVA1, NULL))
{
if(MapFileExW(szDumpFile2, UE_ACCESS_READ, &FileHandle2, &FileSize2, &FileMap2, &FileMapVA2, NULL))
{
if(RelocationOldImageBase != NULL && RelocationNewImageBase != NULL && RelocationOldImageBase != RelocationNewImageBase)
{
__try
{
if(RelocationOldImageBase > RelocationNewImageBase)
{
DeltaByte = (ULONG_PTR)((ULONG_PTR)RelocationOldImageBase - (ULONG_PTR)RelocationNewImageBase);
}
else
{
DeltaByte = (ULONG_PTR)((ULONG_PTR)RelocationNewImageBase - (ULONG_PTR)RelocationOldImageBase);
}
while((BYTE)DeltaByte == NULL)
{
DeltaByte = DeltaByte / 0x10;
i++;
}
DeltaByte = i - 1;
Search1 = (LPVOID)FileMapVA1;
Search2 = (LPVOID)FileMapVA2;
NtSizeOfImage = NtSizeOfImage + LoadedImageBase;
SearchSize = FileSize2;
SearchSize--;
while((int)SearchSize > NULL)
{
if(memcmp(Search1, Search2, 1) != 0)
{
i = sizeof HANDLE;
RelativeBase = NULL;
bkSearch1 = Search1;
bkSearch2 = Search2;
bkSearchSize = SearchSize;
if(Search1 >= (void*)((ULONG_PTR)FileMapVA1 + DeltaByte))
{
Search1 = (LPVOID)((ULONG_PTR)Search1 - DeltaByte);
Search2 = (LPVOID)((ULONG_PTR)Search2 - DeltaByte);
SearchSize = SearchSize + (DWORD)DeltaByte;
}
while(i > NULL && RelativeBase == NULL)
{
RtlMoveMemory(&ReadData, Search2, sizeof HANDLE);
if(ReadData >= LoadedImageBase && ReadData <= NtSizeOfImage)
{
RelativeBase++;
}
else
{
Search1 = (LPVOID)((ULONG_PTR)Search1 + 1);
Search2 = (LPVOID)((ULONG_PTR)Search2 + 1);
SearchSize = SearchSize - 1;
i--;
}
}
if(RelativeBase == NULL)
{
Search1 = bkSearch1;
Search2 = bkSearch2;
SearchSize = bkSearchSize;
}
else
{
RelocaterAddNewRelocation(hProcess, MemStart + ((ULONG_PTR)Search2 - (ULONG_PTR)FileMapVA2), NULL);
Search1 = (LPVOID)((ULONG_PTR)Search1 + sizeof HANDLE - 1);
Search2 = (LPVOID)((ULONG_PTR)Search2 + sizeof HANDLE - 1);
SearchSize = SearchSize - sizeof HANDLE + 1;
}
}
Search1 = (LPVOID)((ULONG_PTR)Search1 + 1);
Search2 = (LPVOID)((ULONG_PTR)Search2 + 1);
SearchSize = SearchSize - 1;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
RelocaterCleanup();
UnMapFileEx(FileHandle2, FileSize2, FileMap2, FileMapVA2);
UnMapFileEx(FileHandle1, FileSize1, FileMap1, FileMapVA1);
return(false);
}
}
UnMapFileEx(FileHandle2, FileSize2, FileMap2, FileMapVA2);
}
UnMapFileEx(FileHandle1, FileSize1, FileMap1, FileMapVA1);
return(true);
}
return(false);
}
__declspec(dllexport) bool TITCALL RelocaterChangeFileBase(char* szFileName, ULONG_PTR NewImageBase)
{
wchar_t uniFileName[MAX_PATH] = {};
if(szFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
return(RelocaterChangeFileBaseW(uniFileName, NewImageBase));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL RelocaterChangeFileBaseW(wchar_t* szFileName, ULONG_PTR NewImageBase)
{
DWORD RelocSize;
ULONG_PTR RelocData;
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
BOOL FileIs64;
HANDLE FileHandle;
DWORD FileSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
DWORD CompareDummy = NULL;
DWORD RelocDelta = NULL;
DWORD RelocDeltaSize = NULL;
WORD RelocAddressData = NULL;
ULONG_PTR RelocWriteAddress = NULL;
ULONG_PTR RelocWriteData = NULL;
DWORD64 RelocWriteData64 = NULL;
wchar_t szBackupFile[MAX_PATH] = {};
wchar_t szBackupItem[MAX_PATH] = {};
if(engineBackupForCriticalFunctions && CreateGarbageItem(&szBackupItem, sizeof szBackupItem))
{
if(!FillGarbageItem(szBackupItem, szFileName, &szBackupFile, sizeof szBackupItem))
{
RtlZeroMemory(&szBackupItem, sizeof szBackupItem);
lstrcpyW(szBackupFile, szFileName);
}
}
else
{
RtlZeroMemory(&szBackupItem, sizeof szBackupItem);
lstrcpyW(szBackupFile, szFileName);
}
if(MapFileExW(szBackupFile, UE_ACCESS_ALL, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, FileHandle, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
RemoveGarbageItem(szBackupItem, true);
return(false);
}
if(!FileIs64)
{
if(PEHeader32->OptionalHeader.ImageBase == (DWORD)NewImageBase)
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
RemoveGarbageItem(szBackupItem, true);
return(true);
}
RelocData = (ULONG_PTR)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress + PEHeader32->OptionalHeader.ImageBase), true);
RelocSize = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
}
else
{
if((ULONG_PTR)PEHeader64->OptionalHeader.ImageBase == NewImageBase)
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
RemoveGarbageItem(szBackupItem, true);
return(true);
}
RelocData = (ULONG_PTR)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress + PEHeader64->OptionalHeader.ImageBase), true);
RelocSize = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
}
__try
{
while(memcmp((LPVOID)RelocData, &CompareDummy, 4))
{
RtlMoveMemory(&RelocDelta, (LPVOID)RelocData, 4);
RtlMoveMemory(&RelocDeltaSize, (LPVOID)((ULONG_PTR)RelocData + 4), 4);
RelocDeltaSize = RelocDeltaSize - 8;
RelocData = RelocData + 8;
while(RelocDeltaSize > NULL)
{
RtlMoveMemory(&RelocAddressData, (LPVOID)RelocData, 2);
if(RelocAddressData != NULL)
{
if(RelocAddressData & 0x8000)
{
RelocAddressData = RelocAddressData ^ 0x8000;
RelocWriteAddress = (ULONG_PTR)(RelocAddressData + RelocDelta);
RelocWriteAddress = (ULONG_PTR)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)((DWORD64)PEHeader64->OptionalHeader.ImageBase + RelocWriteAddress), true);
RtlMoveMemory(&RelocWriteData64, (LPVOID)RelocWriteAddress, 8);
RelocWriteData64 = RelocWriteData64 - (DWORD64)PEHeader64->OptionalHeader.ImageBase + (DWORD64)NewImageBase;
RtlMoveMemory((LPVOID)RelocWriteAddress, &RelocWriteData64, 8);
}
else if(RelocAddressData & 0x3000)
{
RelocAddressData = RelocAddressData ^ 0x3000;
RelocWriteAddress = (ULONG_PTR)(RelocAddressData + RelocDelta);
RelocWriteAddress = (ULONG_PTR)ConvertVAtoFileOffset(FileMapVA, PEHeader32->OptionalHeader.ImageBase + RelocWriteAddress, true);
RtlMoveMemory(&RelocWriteData, (LPVOID)RelocWriteAddress, 4);
RelocWriteData = RelocWriteData - PEHeader32->OptionalHeader.ImageBase + NewImageBase;
RtlMoveMemory((LPVOID)RelocWriteAddress, &RelocWriteData, 4);
}
}
RelocDeltaSize = RelocDeltaSize - 2;
RelocData = RelocData + 2;
}
}
if(!FileIs64)
{
PEHeader32->OptionalHeader.ImageBase = (DWORD)NewImageBase;
}
else
{
PEHeader64->OptionalHeader.ImageBase = (ULONG_PTR)NewImageBase;
}
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
if(szBackupItem[0] != NULL)
{
if(CopyFileW(szBackupFile, szFileName, false))
{
RemoveGarbageItem(szBackupItem, true);
return(true);
}
else
{
RemoveGarbageItem(szBackupItem, true);
return(false);
}
}
else
{
return(true);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
RemoveGarbageItem(szBackupItem, true);
return(false);
}
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
RemoveGarbageItem(szBackupItem, true);
return(false);
}
}
RemoveGarbageItem(szBackupItem, true);
return(false);
}
__declspec(dllexport) bool TITCALL RelocaterRelocateMemoryBlock(ULONG_PTR FileMapVA, ULONG_PTR MemoryLocation, void* RelocateMemory, DWORD RelocateMemorySize, ULONG_PTR CurrentLoadedBase, ULONG_PTR RelocateBase)
{
BOOL FileIs64;
DWORD RelocSize;
ULONG_PTR RelocData;
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
DWORD CompareDummy = NULL;
DWORD RelocDelta = NULL;
DWORD RelocDeltaSize = NULL;
WORD RelocAddressData = NULL;
ULONG_PTR RelocWriteAddress = NULL;
ULONG_PTR RelocWriteData = NULL;
DWORD64 RelocWriteData64 = NULL;
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
MemoryLocation = MemoryLocation - CurrentLoadedBase;
if(EngineValidateHeader(FileMapVA, NULL, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
return(false);
}
if(!FileIs64)
{
if(PEHeader32->OptionalHeader.ImageBase == (DWORD)RelocateBase)
{
return(true);
}
RelocData = (ULONG_PTR)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress + PEHeader32->OptionalHeader.ImageBase), true);
RelocSize = PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
}
else
{
if((ULONG_PTR)PEHeader64->OptionalHeader.ImageBase == RelocateBase)
{
return(true);
}
RelocData = (ULONG_PTR)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress + PEHeader64->OptionalHeader.ImageBase), true);
RelocSize = PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
}
__try
{
while(memcmp((LPVOID)RelocData, &CompareDummy, 4))
{
RtlMoveMemory(&RelocDelta, (LPVOID)RelocData, 4);
RtlMoveMemory(&RelocDeltaSize, (LPVOID)((ULONG_PTR)RelocData + 4), 4);
RelocDeltaSize = RelocDeltaSize - 8;
RelocData = RelocData + 8;
while(RelocDeltaSize > NULL)
{
RtlMoveMemory(&RelocAddressData, (LPVOID)RelocData, 2);
if(RelocAddressData != NULL)
{
if(RelocAddressData & 0x8000)
{
RelocAddressData = RelocAddressData ^ 0x8000;
if(RelocAddressData >= MemoryLocation && RelocAddressData < MemoryLocation + RelocateMemorySize)
{
RelocWriteAddress = (ULONG_PTR)(RelocAddressData + RelocDelta - MemoryLocation + (ULONG_PTR)RelocateMemory);
RtlMoveMemory(&RelocWriteData64, (LPVOID)RelocWriteAddress, 8);
RelocWriteData64 = RelocWriteData64 - (DWORD64)PEHeader64->OptionalHeader.ImageBase + (DWORD64)RelocateBase;
RtlMoveMemory((LPVOID)RelocWriteAddress, &RelocWriteData64, 8);
}
}
else if(RelocAddressData & 0x3000)
{
RelocAddressData = RelocAddressData ^ 0x3000;
if(RelocAddressData >= MemoryLocation && RelocAddressData < MemoryLocation + RelocateMemorySize)
{
RelocWriteAddress = (ULONG_PTR)(RelocAddressData + RelocDelta - MemoryLocation + (ULONG_PTR)RelocateMemory);
RtlMoveMemory(&RelocWriteData, (LPVOID)RelocWriteAddress, 4);
RelocWriteData = RelocWriteData - PEHeader32->OptionalHeader.ImageBase + RelocateBase;
RtlMoveMemory((LPVOID)RelocWriteAddress, &RelocWriteData, 4);
}
}
}
RelocDeltaSize = RelocDeltaSize - 2;
RelocData = RelocData + 2;
}
}
return(true);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return(false);
}
}
else
{
return(false);
}
return(false);
}
__declspec(dllexport) bool TITCALL RelocaterWipeRelocationTable(char* szFileName)
{
wchar_t uniFileName[MAX_PATH] = {};
if(szFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
return(RelocaterWipeRelocationTableW(uniFileName));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL RelocaterWipeRelocationTableW(wchar_t* szFileName)
{
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
DWORD WipeSectionNumber = NULL;
ULONG_PTR Characteristics;
BOOL FileIs64;
HANDLE FileHandle;
DWORD FileSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
if(MapFileExW(szFileName, UE_ACCESS_READ, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, FileHandle, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
if(!FileIs64)
{
if(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress != NULL)
{
Characteristics = (ULONG_PTR)GetPE32DataFromMappedFile(FileMapVA, NULL, UE_CHARACTERISTICS) ^ 1;
SetPE32DataForMappedFile(FileMapVA, NULL, UE_CHARACTERISTICS, Characteristics);
WipeSectionNumber = GetPE32SectionNumberFromVA(FileMapVA, (ULONG_PTR)((ULONG_PTR)PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress + (ULONG_PTR)PEHeader32->OptionalHeader.ImageBase));
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(WipeSectionW(szFileName, (int)WipeSectionNumber, true));
}
}
else
{
if(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress != NULL)
{
Characteristics = (ULONG_PTR)GetPE32DataFromMappedFile(FileMapVA, NULL, UE_CHARACTERISTICS) ^ 1;
SetPE32DataForMappedFile(FileMapVA, NULL, UE_CHARACTERISTICS, Characteristics);
WipeSectionNumber = GetPE32SectionNumberFromVA(FileMapVA, (ULONG_PTR)((ULONG_PTR)PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase));
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(WipeSectionW(szFileName, (int)WipeSectionNumber, true));
}
}
}
}
return(false);
}
// TitanEngine.Resourcer.functions:
__declspec(dllexport) long long TITCALL ResourcerLoadFileForResourceUse(char* szFileName)
{
return((ULONG_PTR)EngineSimulateNtLoader(szFileName));
}
__declspec(dllexport) long long TITCALL ResourcerLoadFileForResourceUseW(wchar_t* szFileName)
{
return((ULONG_PTR)EngineSimulateNtLoaderW(szFileName));
}
__declspec(dllexport) bool TITCALL ResourcerFreeLoadedFile(LPVOID LoadedFileBase)
{
if(VirtualFree(LoadedFileBase, NULL, MEM_RELEASE))
{
return(true);
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL ResourcerExtractResourceFromFileEx(ULONG_PTR FileMapVA, char* szResourceType, char* szResourceName, char* szExtractedFileName)
{
HRSRC hResource;
HGLOBAL hResourceGlobal;
DWORD ResourceSize;
LPVOID ResourceData;
DWORD NumberOfBytesWritten;
HANDLE hFile;
hResource = FindResourceA((HMODULE)FileMapVA, (LPCSTR)szResourceName, (LPCSTR)szResourceType);
if(hResource != NULL)
{
hResourceGlobal = LoadResource((HMODULE)FileMapVA, hResource);
if(hResourceGlobal != NULL)
{
ResourceSize = SizeofResource((HMODULE)FileMapVA, hResource);
ResourceData = LockResource(hResourceGlobal);
if(EngineCreatePathForFile(szExtractedFileName))
{
hFile = CreateFileA(szExtractedFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile != INVALID_HANDLE_VALUE)
{
WriteFile(hFile, ResourceData, ResourceSize, &NumberOfBytesWritten, NULL);
EngineCloseHandle(hFile);
}
else
{
return(false);
}
}
}
return(true);
}
return(false);
}
__declspec(dllexport) bool TITCALL ResourcerExtractResourceFromFile(char* szFileName, char* szResourceType, char* szResourceName, char* szExtractedFileName)
{
HANDLE FileHandle;
DWORD FileSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
bool bReturn;
if(MapFileEx(szFileName, UE_ACCESS_READ, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
bReturn = ResourcerExtractResourceFromFileEx(FileMapVA, szResourceType, szResourceName, szExtractedFileName);
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
if(bReturn)
{
return(true);
}
}
return(false);
}
__declspec(dllexport) bool TITCALL ResourcerExtractResourceFromFileW(wchar_t* szFileName, char* szResourceType, char* szResourceName, char* szExtractedFileName)
{
HANDLE FileHandle;
DWORD FileSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
bool bReturn;
if(MapFileExW(szFileName, UE_ACCESS_READ, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
bReturn = ResourcerExtractResourceFromFileEx(FileMapVA, szResourceType, szResourceName, szExtractedFileName);
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
if(bReturn)
{
return(true);
}
}
return(false);
}
__declspec(dllexport) bool TITCALL ResourcerFindResource(char* szFileName, char* szResourceType, DWORD ResourceType, char* szResourceName, DWORD ResourceName, DWORD ResourceLanguage, PULONG_PTR pResourceData, LPDWORD pResourceSize)
{
wchar_t uniFileName[MAX_PATH] = {};
wchar_t* PtrResourceType = NULL;
wchar_t uniResourceType[MAX_PATH] = {};
wchar_t* PtrResourceName = NULL;
wchar_t uniResourceName[MAX_PATH] = {};
if(szFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
if(szResourceName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szResourceName, lstrlenA(szResourceName)+1, uniResourceName, sizeof(uniResourceName)/(sizeof(uniResourceName[0])));
}
else
{
PtrResourceType = &uniResourceType[0];
}
if(szResourceType != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szResourceType, lstrlenA(szResourceType)+1, uniResourceType, sizeof(uniResourceType)/(sizeof(uniResourceType[0])));
}
else
{
PtrResourceName = &uniResourceName[0];
}
return(ResourcerFindResourceW(uniFileName, PtrResourceType, ResourceType, PtrResourceName, ResourceName, ResourceLanguage, pResourceData, pResourceSize));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL ResourcerFindResourceW(wchar_t* szFileName, wchar_t* szResourceType, DWORD ResourceType, wchar_t* szResourceName, DWORD ResourceName, DWORD ResourceLanguage, PULONG_PTR pResourceData, LPDWORD pResourceSize)
{
bool ReturnValue;
ULONG_PTR FileMapVA;
HANDLE FileHandle;
HANDLE FileMap;
DWORD FileSize;
if(MapFileExW(szFileName, UE_ACCESS_ALL, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
ReturnValue = ResourcerFindResourceEx(FileMapVA, FileSize, szResourceType, ResourceType, szResourceName, ResourceName, ResourceLanguage, pResourceData, pResourceSize);
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
if(ReturnValue)
{
return(true);
}
}
else
{
return(false);
}
return(false);
}
__declspec(dllexport) bool TITCALL ResourcerFindResourceEx(ULONG_PTR FileMapVA, DWORD FileSize, wchar_t* szResourceType, DWORD ResourceType, wchar_t* szResourceName, DWORD ResourceName, DWORD ResourceLanguage, PULONG_PTR pResourceData, LPDWORD pResourceSize)
{
int i,j,n;
wchar_t* uniResourceName;
wchar_t* uniResourceType;
PIMAGE_RESOURCE_DIRECTORY PEResource;
PIMAGE_RESOURCE_DIRECTORY PEResourcePtr;
PIMAGE_RESOURCE_DIRECTORY_ENTRY PEResourceDir;
PIMAGE_RESOURCE_DIRECTORY PESubResourcePtr1;
PIMAGE_RESOURCE_DIRECTORY_ENTRY PEResourceDir1;
PIMAGE_RESOURCE_DIRECTORY PESubResourcePtr2;
PIMAGE_RESOURCE_DIRECTORY_ENTRY PEResourceDir2;
PIMAGE_RESOURCE_DATA_ENTRY PEResourceItem;
__try
{
if(FileMapVA != NULL && FileSize != NULL)
{
PEResource = (PIMAGE_RESOURCE_DIRECTORY)(ConvertVAtoFileOffsetEx(FileMapVA, FileSize, (ULONG_PTR)GetPE32DataFromMappedFile(FileMapVA, NULL, UE_IMAGEBASE), (ULONG_PTR)GetPE32DataFromMappedFile(FileMapVA, NULL, UE_RESOURCETABLEADDRESS), true, true));
if(PEResource != NULL)
{
PEResourceDir = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((ULONG_PTR)PEResource + sizeof IMAGE_RESOURCE_DIRECTORY);
i = PEResource->NumberOfIdEntries + PEResource->NumberOfNamedEntries;
PEResourcePtr = PEResource;
while(i > NULL)
{
PESubResourcePtr1 = (PIMAGE_RESOURCE_DIRECTORY)((ULONG_PTR)PEResourcePtr + (PEResourceDir->OffsetToData ^ IMAGE_RESOURCE_DATA_IS_DIRECTORY));
PEResourceDir1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((ULONG_PTR)PESubResourcePtr1 + sizeof IMAGE_RESOURCE_DIRECTORY);
j = PESubResourcePtr1->NumberOfIdEntries + PESubResourcePtr1->NumberOfNamedEntries;
uniResourceType = (wchar_t*)((ULONG_PTR)PEResourcePtr + PEResourceDir->NameOffset);
if(((bool)PEResourceDir->NameIsString == true && EngineCompareResourceString(uniResourceType, szResourceType) == true) || ((bool)PEResourceDir->NameIsString == false && PEResourceDir->Id == ResourceType))
{
while(j > NULL)
{
PESubResourcePtr2 = (PIMAGE_RESOURCE_DIRECTORY)((ULONG_PTR)PEResourcePtr + (PEResourceDir1->OffsetToData ^ IMAGE_RESOURCE_DATA_IS_DIRECTORY));
PEResourceDir2 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((ULONG_PTR)PESubResourcePtr2 + sizeof IMAGE_RESOURCE_DIRECTORY);
n = PESubResourcePtr2->NumberOfIdEntries + PESubResourcePtr2->NumberOfNamedEntries;
uniResourceName = (wchar_t*)((ULONG_PTR)PEResourcePtr + PEResourceDir1->NameOffset);
if(((bool)PEResourceDir1->NameIsString == true && EngineCompareResourceString(uniResourceName, szResourceName) == true) || ((bool)PEResourceDir1->NameIsString == false && PEResourceDir1->Id == ResourceName))
{
while(n > NULL)
{
PEResourceItem = (PIMAGE_RESOURCE_DATA_ENTRY)((ULONG_PTR)PEResourcePtr + PEResourceDir2->OffsetToData);
if(ResourceLanguage == UE_RESOURCE_LANGUAGE_ANY || ResourceLanguage == PEResourceDir2->Id)
{
*pResourceData = PEResourceItem->OffsetToData;
*pResourceSize = PEResourceItem->Size;
return(true);
}
PEResourceDir2 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((ULONG_PTR)PEResourceDir2 + sizeof IMAGE_RESOURCE_DIRECTORY_ENTRY);
n--;
}
}
else
{
PEResourceDir2 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((ULONG_PTR)PEResourceDir2 + sizeof IMAGE_RESOURCE_DIRECTORY_ENTRY * n);
}
PEResourceDir1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((ULONG_PTR)PEResourceDir1 + sizeof IMAGE_RESOURCE_DIRECTORY_ENTRY);
j--;
}
}
else
{
PEResourceDir1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((ULONG_PTR)PEResourceDir1 + sizeof IMAGE_RESOURCE_DIRECTORY_ENTRY * j);
}
PEResourceDir = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((ULONG_PTR)PEResourceDir + sizeof IMAGE_RESOURCE_DIRECTORY_ENTRY);
i--;
}
}
}
else
{
return(false);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
return(false);
}
__declspec(dllexport) void TITCALL ResourcerEnumerateResource(char* szFileName, void* CallBack)
{
wchar_t uniFileName[MAX_PATH] = {};
if(szFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
ResourcerEnumerateResourceW(uniFileName, CallBack);
}
}
__declspec(dllexport) void TITCALL ResourcerEnumerateResourceW(wchar_t* szFileName, void* CallBack)
{
ULONG_PTR FileMapVA;
HANDLE FileHandle;
HANDLE FileMap;
DWORD FileSize;
if(MapFileExW(szFileName, UE_ACCESS_ALL, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
ResourcerEnumerateResourceEx(FileMapVA, FileSize, CallBack);
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
}
}
__declspec(dllexport) void TITCALL ResourcerEnumerateResourceEx(ULONG_PTR FileMapVA, DWORD FileSize, void* CallBack)
{
int i,j,n;
wchar_t* uniResourceName;
wchar_t* uniResourceType;
PIMAGE_RESOURCE_DIRECTORY PEResource;
PIMAGE_RESOURCE_DIRECTORY PEResourcePtr;
PIMAGE_RESOURCE_DIRECTORY_ENTRY PEResourceDir;
PIMAGE_RESOURCE_DIRECTORY PESubResourcePtr1;
PIMAGE_RESOURCE_DIRECTORY_ENTRY PEResourceDir1;
PIMAGE_RESOURCE_DIRECTORY PESubResourcePtr2;
PIMAGE_RESOURCE_DIRECTORY_ENTRY PEResourceDir2;
PIMAGE_RESOURCE_DATA_ENTRY PEResourceItem;
typedef bool(TITCALL *fResourceEnumerator)(wchar_t* szResourceType, DWORD ResourceType, wchar_t* szResourceName, DWORD ResourceName, DWORD ResourceLanguage, DWORD ResourceData, DWORD ResourceSize);
fResourceEnumerator myResourceEnumerator = (fResourceEnumerator)CallBack;
__try
{
if(CallBack != NULL)
{
if(FileMapVA != NULL && FileSize != NULL)
{
PEResource = (PIMAGE_RESOURCE_DIRECTORY)(ConvertVAtoFileOffsetEx(FileMapVA, FileSize, (ULONG_PTR)GetPE32DataFromMappedFile(FileMapVA, NULL, UE_IMAGEBASE), (ULONG_PTR)GetPE32DataFromMappedFile(FileMapVA, NULL, UE_RESOURCETABLEADDRESS), true, true));
if(PEResource != NULL)
{
PEResourceDir = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((ULONG_PTR)PEResource + sizeof IMAGE_RESOURCE_DIRECTORY);
i = PEResource->NumberOfIdEntries + PEResource->NumberOfNamedEntries;
PEResourcePtr = PEResource;
while(i > NULL)
{
PESubResourcePtr1 = (PIMAGE_RESOURCE_DIRECTORY)((ULONG_PTR)PEResourcePtr + (PEResourceDir->OffsetToData ^ IMAGE_RESOURCE_DATA_IS_DIRECTORY));
PEResourceDir1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((ULONG_PTR)PESubResourcePtr1 + sizeof IMAGE_RESOURCE_DIRECTORY);
j = PESubResourcePtr1->NumberOfIdEntries + PESubResourcePtr1->NumberOfNamedEntries;
while(j > NULL)
{
PESubResourcePtr2 = (PIMAGE_RESOURCE_DIRECTORY)((ULONG_PTR)PEResourcePtr + (PEResourceDir1->OffsetToData ^ IMAGE_RESOURCE_DATA_IS_DIRECTORY));
PEResourceDir2 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((ULONG_PTR)PESubResourcePtr2 + sizeof IMAGE_RESOURCE_DIRECTORY);
n = PESubResourcePtr2->NumberOfIdEntries + PESubResourcePtr2->NumberOfNamedEntries;
while(n > NULL)
{
PEResourceItem = (PIMAGE_RESOURCE_DATA_ENTRY)((ULONG_PTR)PEResourcePtr + PEResourceDir2->OffsetToData);
if(PEResourceDir->NameIsString)
{
uniResourceType = (wchar_t*)((ULONG_PTR)PEResourcePtr + PEResourceDir->NameOffset);
}
else
{
uniResourceType = NULL;
}
if(PEResourceDir1->NameIsString)
{
uniResourceName = (wchar_t*)((ULONG_PTR)PEResourcePtr + PEResourceDir1->NameOffset);
}
else
{
uniResourceName = NULL;
}
if(!myResourceEnumerator(uniResourceType, PEResourceDir->Id, uniResourceName, PEResourceDir1->Id, PEResourceDir2->Id, PEResourceItem->OffsetToData, PEResourceItem->Size))
{
return;
}
PEResourceDir2 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((ULONG_PTR)PEResourceDir2 + sizeof IMAGE_RESOURCE_DIRECTORY_ENTRY);
n--;
}
PEResourceDir1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((ULONG_PTR)PEResourceDir1 + sizeof IMAGE_RESOURCE_DIRECTORY_ENTRY);
j--;
}
PEResourceDir = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((ULONG_PTR)PEResourceDir + sizeof IMAGE_RESOURCE_DIRECTORY_ENTRY);
i--;
}
}
}
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
}
// TitanEngine.Threader.functions:
__declspec(dllexport) bool TITCALL ThreaderImportRunningThreadData(DWORD ProcessId)
{
HANDLE hSnapShot;
THREADENTRY32 ThreadEntry = {};
PTHREAD_ITEM_DATA hListThreadPtr = NULL;
if(dbgProcessInformation.hProcess == NULL && ProcessId != NULL)
{
if(hListThread == NULL)
{
hListThread = VirtualAlloc(NULL, MAX_DEBUG_DATA * sizeof THREAD_ITEM_DATA, MEM_COMMIT, PAGE_READWRITE);
}
else
{
RtlZeroMemory(hListThread, MAX_DEBUG_DATA * sizeof THREAD_ITEM_DATA);
}
ThreadEntry.dwSize = sizeof THREADENTRY32;
hListThreadPtr = (PTHREAD_ITEM_DATA)hListThread;
hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, ProcessId);
if(hSnapShot != INVALID_HANDLE_VALUE)
{
if(Thread32First(hSnapShot, &ThreadEntry))
{
do
{
if(ThreadEntry.th32OwnerProcessID == ProcessId)
{
hListThreadPtr->dwThreadId = ThreadEntry.th32ThreadID;
hListThreadPtr->hThread = OpenThread(THREAD_GET_CONTEXT+THREAD_SET_CONTEXT+THREAD_QUERY_INFORMATION+THREAD_SUSPEND_RESUME, false, hListThreadPtr->dwThreadId);
hListThreadPtr = (PTHREAD_ITEM_DATA)((ULONG_PTR)hListThreadPtr + sizeof THREAD_ITEM_DATA);
}
}
while(Thread32Next(hSnapShot, &ThreadEntry));
}
EngineCloseHandle(hSnapShot);
return(true);
}
}
return(false);
}
__declspec(dllexport) void* TITCALL ThreaderGetThreadInfo(HANDLE hThread, DWORD ThreadId)
{
PTHREAD_ITEM_DATA hListThreadPtr = (PTHREAD_ITEM_DATA)hListThread;
if(hListThreadPtr != NULL)
{
if(hThread != NULL)
{
while(hListThreadPtr->hThread != NULL && hListThreadPtr->hThread != hThread)
{
hListThreadPtr = (PTHREAD_ITEM_DATA)((ULONG_PTR)hListThreadPtr + sizeof THREAD_ITEM_DATA);
}
if(hListThreadPtr->hThread == hThread)
{
return((void*)hListThreadPtr);
}
}
else if(ThreadId != NULL)
{
while(hListThreadPtr->hThread != NULL && hListThreadPtr->dwThreadId != ThreadId)
{
hListThreadPtr = (PTHREAD_ITEM_DATA)((ULONG_PTR)hListThreadPtr + sizeof THREAD_ITEM_DATA);
}
if(hListThreadPtr->dwThreadId == ThreadId)
{
return((void*)hListThreadPtr);
}
}
}
return(NULL);
}
__declspec(dllexport) void TITCALL ThreaderEnumThreadInfo(void* EnumCallBack)
{
PTHREAD_ITEM_DATA hListThreadPtr = (PTHREAD_ITEM_DATA)hListThread;
typedef void(TITCALL *fEnumCallBack)(LPVOID fThreadDetail);
fEnumCallBack myEnumCallBack = (fEnumCallBack)EnumCallBack;
if(hListThreadPtr != NULL)
{
while(EnumCallBack != NULL && hListThreadPtr->hThread != NULL)
{
if(hListThreadPtr->hThread != NULL)
{
__try
{
myEnumCallBack((void*)hListThreadPtr);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
EnumCallBack = NULL;
}
}
hListThreadPtr = (PTHREAD_ITEM_DATA)((ULONG_PTR)hListThreadPtr + sizeof THREAD_ITEM_DATA);
}
}
}
__declspec(dllexport) bool TITCALL ThreaderPauseThread(HANDLE hThread)
{
PTHREAD_ITEM_DATA hListThreadPtr = (PTHREAD_ITEM_DATA)hListThread;
if(hListThreadPtr != NULL)
{
if(hThread != NULL)
{
while(hListThreadPtr->hThread != NULL && hListThreadPtr->hThread != hThread)
{
hListThreadPtr = (PTHREAD_ITEM_DATA)((ULONG_PTR)hListThreadPtr + sizeof THREAD_ITEM_DATA);
}
if(hListThreadPtr->hThread == hThread)
{
if(SuspendThread(hThread) != -1)
{
return(true);
}
else
{
return(false);
}
}
else
{
return(false);
}
}
}
return(false);
}
__declspec(dllexport) bool TITCALL ThreaderResumeThread(HANDLE hThread)
{
PTHREAD_ITEM_DATA hListThreadPtr = (PTHREAD_ITEM_DATA)hListThread;
if(hListThreadPtr != NULL)
{
if(hThread != NULL)
{
while(hListThreadPtr->hThread != NULL && hListThreadPtr->hThread != hThread)
{
hListThreadPtr = (PTHREAD_ITEM_DATA)((ULONG_PTR)hListThreadPtr + sizeof THREAD_ITEM_DATA);
}
if(hListThreadPtr->hThread == hThread)
{
if(ResumeThread(hThread) != -1)
{
return(true);
}
else
{
return(false);
}
}
else
{
return(false);
}
}
}
return(false);
}
__declspec(dllexport) bool TITCALL ThreaderTerminateThread(HANDLE hThread, DWORD ThreadExitCode)
{
PTHREAD_ITEM_DATA hListThreadPtr = (PTHREAD_ITEM_DATA)hListThread;
if(hListThreadPtr != NULL)
{
if(hThread != NULL)
{
while(hListThreadPtr->hThread != NULL && hListThreadPtr->hThread != hThread)
{
hListThreadPtr = (PTHREAD_ITEM_DATA)((ULONG_PTR)hListThreadPtr + sizeof THREAD_ITEM_DATA);
}
if(hListThreadPtr->hThread == hThread)
{
if(TerminateThread(hThread, ThreadExitCode) != NULL)
{
hListThreadPtr->hThread = (HANDLE)-1;
hListThreadPtr->dwThreadId = NULL;
hListThreadPtr->ThreadLocalBase = NULL;
hListThreadPtr->ThreadStartAddress = NULL;
return(true);
}
else
{
return(false);
}
}
else
{
return(false);
}
}
}
return(false);
}
__declspec(dllexport) bool TITCALL ThreaderPauseAllThreads(bool LeaveMainRunning)
{
PTHREAD_ITEM_DATA hListThreadPtr = (PTHREAD_ITEM_DATA)hListThread;
if(hListThreadPtr != NULL)
{
while(hListThreadPtr->hThread != NULL)
{
if(LeaveMainRunning)
{
if(hListThreadPtr->hThread != dbgProcessInformation.hThread)
{
SuspendThread((HANDLE)hListThreadPtr->hThread);
}
}
else
{
SuspendThread(hListThreadPtr->hThread);
}
hListThreadPtr = (PTHREAD_ITEM_DATA)((ULONG_PTR)hListThreadPtr + sizeof THREAD_ITEM_DATA);
}
return(true);
}
return(false);
}
__declspec(dllexport) bool TITCALL ThreaderResumeAllThreads(bool LeaveMainPaused)
{
PTHREAD_ITEM_DATA hListThreadPtr = (PTHREAD_ITEM_DATA)hListThread;
if(hListThreadPtr != NULL)
{
while(hListThreadPtr->hThread != NULL)
{
if(LeaveMainPaused)
{
if(hListThreadPtr->hThread != dbgProcessInformation.hThread)
{
ResumeThread(hListThreadPtr->hThread);
}
}
else
{
ResumeThread(hListThreadPtr->hThread);
}
hListThreadPtr = (PTHREAD_ITEM_DATA)((ULONG_PTR)hListThreadPtr + sizeof THREAD_ITEM_DATA);
}
return(true);
}
return(false);
}
__declspec(dllexport) bool TITCALL ThreaderPauseProcess()
{
return(ThreaderPauseAllThreads(false));
}
__declspec(dllexport) bool TITCALL ThreaderResumeProcess()
{
return(ThreaderResumeAllThreads(false));
}
__declspec(dllexport) long long TITCALL ThreaderCreateRemoteThread(ULONG_PTR ThreadStartAddress, bool AutoCloseTheHandle, LPVOID ThreadPassParameter, LPDWORD ThreadId)
{
HANDLE myThread;
if(dbgProcessInformation.hProcess != NULL)
{
if(!AutoCloseTheHandle)
{
return((ULONG_PTR)CreateRemoteThread(dbgProcessInformation.hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)ThreadStartAddress, ThreadPassParameter, NULL, ThreadId));
}
else
{
myThread = CreateRemoteThread(dbgProcessInformation.hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)ThreadStartAddress, ThreadPassParameter, NULL, ThreadId);
EngineCloseHandle(myThread);
return(NULL);
}
}
return(NULL);
}
__declspec(dllexport) bool TITCALL ThreaderInjectAndExecuteCode(LPVOID InjectCode, DWORD StartDelta, DWORD InjectSize)
{
LPVOID ThreadBase = 0;
ULONG_PTR ueNumberOfBytesRead = 0;
if(dbgProcessInformation.hProcess != NULL)
{
ThreadBase = VirtualAllocEx(dbgProcessInformation.hProcess, NULL, InjectSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if(WriteProcessMemory(dbgProcessInformation.hProcess, ThreadBase, InjectCode, InjectSize, &ueNumberOfBytesRead))
{
ThreaderCreateRemoteThread((ULONG_PTR)((ULONG_PTR)InjectCode + StartDelta), true, NULL, NULL);
return(true);
}
else
{
return(false);
}
}
return(false);
}
__declspec(dllexport) long long TITCALL ThreaderCreateRemoteThreadEx(HANDLE hProcess, ULONG_PTR ThreadStartAddress, bool AutoCloseTheHandle, LPVOID ThreadPassParameter, LPDWORD ThreadId)
{
HANDLE myThread;
if(hProcess != NULL)
{
if(!AutoCloseTheHandle)
{
return((ULONG_PTR)CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)ThreadStartAddress, ThreadPassParameter, NULL, ThreadId));
}
else
{
myThread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)ThreadStartAddress, ThreadPassParameter, NULL, ThreadId);
EngineCloseHandle(myThread);
return(NULL);
}
}
return(NULL);
}
__declspec(dllexport) bool TITCALL ThreaderInjectAndExecuteCodeEx(HANDLE hProcess, LPVOID InjectCode, DWORD StartDelta, DWORD InjectSize)
{
LPVOID ThreadBase = 0;
ULONG_PTR ueNumberOfBytesRead = 0;
if(hProcess != NULL)
{
ThreadBase = VirtualAllocEx(hProcess, NULL, InjectSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if(WriteProcessMemory(hProcess, ThreadBase, InjectCode, InjectSize, &ueNumberOfBytesRead))
{
ThreaderCreateRemoteThread((ULONG_PTR)((ULONG_PTR)InjectCode + StartDelta), true, NULL, NULL);
return(true);
}
else
{
return(false);
}
}
return(false);
}
__declspec(dllexport) void TITCALL ThreaderSetCallBackForNextExitThreadEvent(LPVOID exitThreadCallBack)
{
engineExitThreadOneShootCallBack = exitThreadCallBack;
}
__declspec(dllexport) bool TITCALL ThreaderIsThreadStillRunning(HANDLE hThread)
{
CONTEXT myDBGContext;
RtlZeroMemory(&myDBGContext, sizeof CONTEXT);
myDBGContext.ContextFlags = CONTEXT_ALL;
if(GetThreadContext(hThread, &myDBGContext))
{
return(true);
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL ThreaderIsThreadActive(HANDLE hThread)
{
if(SuspendThread(hThread)) //if previous suspend count is above 0 (which means thread is suspended)
{
ResumeThread(hThread); //decrement suspend count
return(true);
}
return(false);
}
__declspec(dllexport) bool TITCALL ThreaderIsAnyThreadActive()
{
PTHREAD_ITEM_DATA hListThreadPtr = (PTHREAD_ITEM_DATA)hListThread;
if(hListThreadPtr != NULL)
{
while(hListThreadPtr->hThread != NULL)
{
if(hListThreadPtr->hThread != (HANDLE)-1)
{
if(ThreaderIsThreadActive(hListThreadPtr->hThread))
{
return(true);
}
}
hListThreadPtr = (PTHREAD_ITEM_DATA)((ULONG_PTR)hListThreadPtr + sizeof THREAD_ITEM_DATA);
}
}
return(false);
}
__declspec(dllexport) bool TITCALL ThreaderExecuteOnlyInjectedThreads()
{
if(ThreaderPauseProcess())
{
engineResumeProcessIfNoThreadIsActive = true;
return(true);
}
return(false);
}
__declspec(dllexport) long long TITCALL ThreaderGetOpenHandleForThread(DWORD ThreadId)
{
PTHREAD_ITEM_DATA hListThreadPtr = (PTHREAD_ITEM_DATA)hListThread;
if(hListThread != NULL)
{
while(hListThreadPtr->hThread != NULL)
{
if(hListThreadPtr->hThread != (HANDLE)-1 && hListThreadPtr->dwThreadId == ThreadId)
{
return((ULONG_PTR)hListThreadPtr->hThread);
}
hListThreadPtr = (PTHREAD_ITEM_DATA)((ULONG_PTR)hListThreadPtr + sizeof THREAD_ITEM_DATA);
}
}
return(NULL);
}
__declspec(dllexport) void* TITCALL ThreaderGetThreadData()
{
return(hListThread);
}
__declspec(dllexport) bool TITCALL ThreaderIsExceptionInMainThread()
{
LPDEBUG_EVENT myDBGEvent;
myDBGEvent = (LPDEBUG_EVENT)GetDebugData();
if(myDBGEvent->dwThreadId == dbgProcessInformation.dwThreadId)
{
return(true);
}
return(false);
}
// Global.Debugger.functions:
long DebugLoopInSecondThread(LPVOID InputParameter)
{
__try
{
if(InputParameter == NULL)
{
InitDebugExW(engineExpertDebug.szFileName, engineExpertDebug.szCommandLine, engineExpertDebug.szCurrentFolder, engineExpertDebug.EntryCallBack);
}
else
{
InitDLLDebugW(engineExpertDebug.szFileName, engineExpertDebug.ReserveModuleBase, engineExpertDebug.szCommandLine, engineExpertDebug.szCurrentFolder, engineExpertDebug.EntryCallBack);
}
DebugLoop();
return(NULL);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return(-1);
}
}
void DebuggerReset()
{
if(engineResetCustomHandler)
{
RtlZeroMemory(&myDBGCustomHandler, sizeof CustomHandler);
}
}
// TitanEngine.Debugger.functions:
__declspec(dllexport) void* TITCALL StaticDisassembleEx(ULONG_PTR DisassmStart, LPVOID DisassmAddress)
{
_DecodeResult DecodingResult;
_DecodedInst engineDecodedInstructions[MAX_DECODE_INSTRUCTIONS];
unsigned int DecodedInstructionsCount = 0;
#if !defined(_WIN64)
_DecodeType DecodingType = Decode32Bits;
#else
_DecodeType DecodingType = Decode64Bits;
#endif
MEMORY_BASIC_INFORMATION MemInfo;
DWORD MaxDisassmSize;
VirtualQueryEx(GetCurrentProcess(), DisassmAddress, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
if(MemInfo.State == MEM_COMMIT)
{
if((ULONG_PTR)MemInfo.BaseAddress + (ULONG_PTR)MemInfo.RegionSize - (ULONG_PTR)DisassmAddress <= MAXIMUM_INSTRUCTION_SIZE)
{
MaxDisassmSize = (DWORD)((ULONG_PTR)MemInfo.BaseAddress + (ULONG_PTR)MemInfo.RegionSize - (ULONG_PTR)DisassmAddress - 1);
VirtualQueryEx(GetCurrentProcess(), (LPVOID)((ULONG_PTR)DisassmAddress + (ULONG_PTR)MemInfo.RegionSize), &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
if(MemInfo.State == MEM_COMMIT)
{
MaxDisassmSize = MAXIMUM_INSTRUCTION_SIZE;
}
}
else
{
MaxDisassmSize = MAXIMUM_INSTRUCTION_SIZE;
}
DecodingResult = distorm_decode((ULONG_PTR)DisassmStart, (const unsigned char*)DisassmAddress, MaxDisassmSize, DecodingType, engineDecodedInstructions, MAX_DECODE_INSTRUCTIONS, &DecodedInstructionsCount);
RtlZeroMemory(&engineDisassembledInstruction, 128);
lstrcpyA(engineDisassembledInstruction, (LPCSTR)engineDecodedInstructions[0].mnemonic.p);
if(engineDecodedInstructions[0].size != NULL)
{
lstrcatA(engineDisassembledInstruction, " ");
}
lstrcatA(engineDisassembledInstruction, (LPCSTR)engineDecodedInstructions[0].operands.p);
return((char*)engineDisassembledInstruction);
}
else
{
return(NULL);
}
}
__declspec(dllexport) void* TITCALL StaticDisassemble(LPVOID DisassmAddress)
{
return(StaticDisassembleEx((ULONG_PTR)DisassmAddress, DisassmAddress));
}
__declspec(dllexport) void* TITCALL DisassembleEx(HANDLE hProcess, LPVOID DisassmAddress, bool ReturnInstructionType)
{
_DecodeResult DecodingResult;
_DecodedInst engineDecodedInstructions[MAX_DECODE_INSTRUCTIONS];
unsigned int DecodedInstructionsCount = 0;
#if !defined(_WIN64)
_DecodeType DecodingType = Decode32Bits;
#else
_DecodeType DecodingType = Decode64Bits;
#endif
ULONG_PTR ueNumberOfBytesRead = 0;
LPVOID ueReadBuffer = VirtualAlloc(NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE);
MEMORY_BASIC_INFORMATION MemInfo;
DWORD MaxDisassmSize;
if(hProcess != NULL)
{
VirtualQueryEx(hProcess, DisassmAddress, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
if(MemInfo.State == MEM_COMMIT)
{
if((ULONG_PTR)MemInfo.BaseAddress + (ULONG_PTR)MemInfo.RegionSize - (ULONG_PTR)DisassmAddress <= MAXIMUM_INSTRUCTION_SIZE)
{
MaxDisassmSize = (DWORD)((ULONG_PTR)MemInfo.BaseAddress + (ULONG_PTR)MemInfo.RegionSize - (ULONG_PTR)DisassmAddress - 1);
VirtualQueryEx(hProcess, (LPVOID)((ULONG_PTR)DisassmAddress + (ULONG_PTR)MemInfo.RegionSize), &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
if(MemInfo.State == MEM_COMMIT)
{
MaxDisassmSize = MAXIMUM_INSTRUCTION_SIZE;
}
}
else
{
MaxDisassmSize = MAXIMUM_INSTRUCTION_SIZE;
}
bool isbp=false;
if(IsBPXEnabled((ULONG_PTR)DisassmAddress))
{
isbp=true;
DisableBPX((ULONG_PTR)DisassmAddress);
}
BOOL rpm=ReadProcessMemory(hProcess, (LPVOID)DisassmAddress, ueReadBuffer, MaxDisassmSize, &ueNumberOfBytesRead);
if(isbp)
{
EnableBPX((ULONG_PTR)DisassmAddress);
}
if(rpm)
{
DecodingResult = distorm_decode((ULONG_PTR)DisassmAddress, (const unsigned char*)ueReadBuffer, MaxDisassmSize, DecodingType, engineDecodedInstructions, MAX_DECODE_INSTRUCTIONS, &DecodedInstructionsCount);
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
RtlZeroMemory(&engineDisassembledInstruction, 128);
lstrcpyA(engineDisassembledInstruction, (LPCSTR)engineDecodedInstructions[0].mnemonic.p);
if(!ReturnInstructionType)
{
if(engineDecodedInstructions[0].size != NULL)
{
lstrcatA(engineDisassembledInstruction, " ");
}
lstrcatA(engineDisassembledInstruction, (LPCSTR)engineDecodedInstructions[0].operands.p);
}
return((char*)engineDisassembledInstruction);
}
else
{
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
return(NULL);
}
}
else
{
return(NULL);
}
}
else
{
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
return(NULL);
}
}
__declspec(dllexport) void* TITCALL Disassemble(LPVOID DisassmAddress)
{
return(DisassembleEx(dbgProcessInformation.hProcess, DisassmAddress, false));
}
__declspec(dllexport) long TITCALL StaticLengthDisassemble(LPVOID DisassmAddress)
{
_DecodeResult DecodingResult;
_DecodedInst DecodedInstructions[MAX_DECODE_INSTRUCTIONS];
unsigned int DecodedInstructionsCount = 0;
#if !defined(_WIN64)
_DecodeType DecodingType = Decode32Bits;
#else
_DecodeType DecodingType = Decode64Bits;
#endif
MEMORY_BASIC_INFORMATION MemInfo;
DWORD MaxDisassmSize;
VirtualQueryEx(GetCurrentProcess(), DisassmAddress, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
if(MemInfo.State == MEM_COMMIT)
{
if((ULONG_PTR)MemInfo.BaseAddress + (ULONG_PTR)MemInfo.RegionSize - (ULONG_PTR)DisassmAddress <= MAXIMUM_INSTRUCTION_SIZE)
{
MaxDisassmSize = (DWORD)((ULONG_PTR)MemInfo.BaseAddress + (ULONG_PTR)MemInfo.RegionSize - (ULONG_PTR)DisassmAddress - 1);
VirtualQueryEx(GetCurrentProcess(), (LPVOID)((ULONG_PTR)DisassmAddress + (ULONG_PTR)MemInfo.RegionSize), &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
if(MemInfo.State == MEM_COMMIT)
{
MaxDisassmSize = MAXIMUM_INSTRUCTION_SIZE;
}
}
else
{
MaxDisassmSize = MAXIMUM_INSTRUCTION_SIZE;
}
DecodingResult = distorm_decode(NULL, (const unsigned char*)DisassmAddress, MaxDisassmSize, DecodingType, DecodedInstructions, MAX_DECODE_INSTRUCTIONS, &DecodedInstructionsCount);
return(DecodedInstructions[0].size);
}
else
{
return(NULL);
}
}
__declspec(dllexport) long TITCALL LengthDisassembleEx(HANDLE hProcess, LPVOID DisassmAddress)
{
_DecodeResult DecodingResult;
_DecodedInst DecodedInstructions[MAX_DECODE_INSTRUCTIONS];
unsigned int DecodedInstructionsCount = 0;
#if !defined(_WIN64)
_DecodeType DecodingType = Decode32Bits;
#else
_DecodeType DecodingType = Decode64Bits;
#endif
ULONG_PTR ueNumberOfBytesRead = 0;
LPVOID ueReadBuffer = VirtualAlloc(NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE);
MEMORY_BASIC_INFORMATION MemInfo;
DWORD MaxDisassmSize;
if(hProcess != NULL)
{
VirtualQueryEx(GetCurrentProcess(), DisassmAddress, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
if(MemInfo.State == MEM_COMMIT)
{
if((ULONG_PTR)MemInfo.BaseAddress + (ULONG_PTR)MemInfo.RegionSize - (ULONG_PTR)DisassmAddress <= MAXIMUM_INSTRUCTION_SIZE)
{
MaxDisassmSize = (DWORD)((ULONG_PTR)MemInfo.BaseAddress + (ULONG_PTR)MemInfo.RegionSize - (ULONG_PTR)DisassmAddress - 1);
VirtualQueryEx(GetCurrentProcess(), (LPVOID)((ULONG_PTR)DisassmAddress + (ULONG_PTR)MemInfo.RegionSize), &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
if(MemInfo.State == MEM_COMMIT)
{
MaxDisassmSize = MAXIMUM_INSTRUCTION_SIZE;
}
}
else
{
MaxDisassmSize = MAXIMUM_INSTRUCTION_SIZE;
}
if(ReadProcessMemory(hProcess, (LPVOID)DisassmAddress, ueReadBuffer, MaxDisassmSize, &ueNumberOfBytesRead))
{
DecodingResult = distorm_decode(NULL, (const unsigned char*)ueReadBuffer, MaxDisassmSize, DecodingType, DecodedInstructions, MAX_DECODE_INSTRUCTIONS, &DecodedInstructionsCount);
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
return(DecodedInstructions[0].size);
}
else
{
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
return(-1);
}
}
else
{
return(NULL);
}
}
else
{
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
return(-1);
}
}
__declspec(dllexport) long TITCALL LengthDisassemble(LPVOID DisassmAddress)
{
return(LengthDisassembleEx(dbgProcessInformation.hProcess, DisassmAddress));
}
__declspec(dllexport) void* TITCALL InitDebug(char* szFileName, char* szCommandLine, char* szCurrentFolder)
{
wchar_t* PtrUniFileName = NULL;
wchar_t uniFileName[MAX_PATH] = {};
wchar_t* PtrUniCommandLine = NULL;
wchar_t uniCommandLine[MAX_PATH] = {};
wchar_t* PtrUniCurrentFolder = NULL;
wchar_t uniCurrentFolder[MAX_PATH] = {};
if(szFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
MultiByteToWideChar(CP_ACP, NULL, szCommandLine, lstrlenA(szCommandLine)+1, uniCommandLine, sizeof(uniCommandLine)/(sizeof(uniCommandLine[0])));
MultiByteToWideChar(CP_ACP, NULL, szCurrentFolder, lstrlenA(szCurrentFolder)+1, uniCurrentFolder, sizeof(uniCurrentFolder)/(sizeof(uniCurrentFolder[0])));
if(szFileName != NULL)
{
PtrUniFileName = &uniFileName[0];
}
if(szCommandLine != NULL)
{
PtrUniCommandLine = &uniCommandLine[0];
}
if(szCurrentFolder != NULL)
{
PtrUniCurrentFolder = &uniCurrentFolder[0];
}
return(InitDebugW(PtrUniFileName, PtrUniCommandLine, PtrUniCurrentFolder));
}
else
{
return NULL;
}
}
__declspec(dllexport) void* TITCALL InitDebugW(wchar_t* szFileName, wchar_t* szCommandLine, wchar_t* szCurrentFolder)
{
wchar_t szCreateWithCmdLine[1024];
int DebugConsoleFlag = NULL;
DebuggerReset();
if(engineRemoveConsoleForDebugee)
{
DebugConsoleFlag = CREATE_NO_WINDOW;
}
BreakPointSetCount = 0;
RtlZeroMemory(&BreakPointBuffer, sizeof BreakPointBuffer);
if(szCommandLine == NULL)
{
if(CreateProcessW(szFileName, NULL, NULL, NULL, false, DEBUG_PROCESS+DEBUG_ONLY_THIS_PROCESS+DebugConsoleFlag+CREATE_NEW_CONSOLE, NULL, szCurrentFolder, &dbgStartupInfo, &dbgProcessInformation))
{
engineAttachedToProcess = false;
engineAttachedProcessCallBack = NULL;
RtlZeroMemory(&BreakPointBuffer, sizeof BreakPointBuffer);
return(&dbgProcessInformation);
}
else
{
RtlZeroMemory(&dbgProcessInformation,sizeof PROCESS_INFORMATION);
return(0);
}
}
else
{
wsprintfW(szCreateWithCmdLine, L"\"%s\" %s", szFileName, szCommandLine);
if(CreateProcessW(NULL, szCreateWithCmdLine, NULL, NULL, false, DEBUG_PROCESS+DEBUG_ONLY_THIS_PROCESS+DebugConsoleFlag+CREATE_NEW_CONSOLE, NULL, szCurrentFolder, &dbgStartupInfo, &dbgProcessInformation))
{
engineAttachedToProcess = false;
engineAttachedProcessCallBack = NULL;
RtlZeroMemory(&BreakPointBuffer, sizeof BreakPointBuffer);
return(&dbgProcessInformation);
}
else
{
RtlZeroMemory(&dbgProcessInformation,sizeof PROCESS_INFORMATION);
return(0);
}
}
}
__declspec(dllexport) void* TITCALL InitDebugEx(char* szFileName, char* szCommandLine, char* szCurrentFolder, LPVOID EntryCallBack)
{
DebugExeFileEntryPointCallBack = EntryCallBack;
return(InitDebug(szFileName, szCommandLine, szCurrentFolder));
}
__declspec(dllexport) void* TITCALL InitDebugExW(wchar_t* szFileName, wchar_t* szCommandLine, wchar_t* szCurrentFolder, LPVOID EntryCallBack)
{
DebugExeFileEntryPointCallBack = EntryCallBack;
return(InitDebugW(szFileName, szCommandLine, szCurrentFolder));
}
__declspec(dllexport) void* TITCALL InitDLLDebug(char* szFileName, bool ReserveModuleBase, char* szCommandLine, char* szCurrentFolder, LPVOID EntryCallBack)
{
wchar_t* PtrUniFileName = NULL;
wchar_t uniFileName[MAX_PATH] = {};
wchar_t* PtrUniCommandLine = NULL;
wchar_t uniCommandLine[MAX_PATH] = {};
wchar_t* PtrUniCurrentFolder = NULL;
wchar_t uniCurrentFolder[MAX_PATH] = {};
if(szFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
MultiByteToWideChar(CP_ACP, NULL, szCommandLine, lstrlenA(szCommandLine)+1, uniCommandLine, sizeof(uniCommandLine)/(sizeof(uniCommandLine[0])));
MultiByteToWideChar(CP_ACP, NULL, szCurrentFolder, lstrlenA(szCurrentFolder)+1, uniCurrentFolder, sizeof(uniCurrentFolder)/(sizeof(uniCurrentFolder[0])));
if(szFileName != NULL)
{
PtrUniFileName = &uniFileName[0];
}
if(szCommandLine != NULL)
{
PtrUniCommandLine = &uniCommandLine[0];
}
if(szCurrentFolder != NULL)
{
PtrUniCurrentFolder = &uniCurrentFolder[0];
}
return(InitDLLDebugW(PtrUniFileName, ReserveModuleBase, PtrUniCommandLine, PtrUniCurrentFolder, EntryCallBack));
}
else
{
return NULL;
}
}
__declspec(dllexport) void* TITCALL InitDLLDebugW(wchar_t* szFileName, bool ReserveModuleBase, wchar_t* szCommandLine, wchar_t* szCurrentFolder, LPVOID EntryCallBack)
{
int i = NULL;
int j = NULL;
bool ReturnData = false;
engineReserveModuleBase = NULL;
RtlZeroMemory(&szDebuggerName, sizeof szDebuggerName);
if(lstrlenW(szFileName) < 512)
{
RtlZeroMemory(&szBackupDebuggedFileName, sizeof szBackupDebuggedFileName);
lstrcpyW(szBackupDebuggedFileName, szFileName);
szFileName = &szBackupDebuggedFileName[0];
}
lstrcpyW(szDebuggerName, szFileName);
i = lstrlenW(szDebuggerName);
while(szDebuggerName[i] != 0x5C && i >= NULL)
{
i--;
}
if(i > NULL)
{
szDebuggerName[i+1] = 0x00;
lstrcatW(szDebuggerName, L"DLLLoader.exe");
}
else
{
lstrcpyW(szDebuggerName, L"DLLLoader.exe");
}
//RtlZeroMemory(&szReserveModuleName, sizeof szReserveModuleName);
//lstrcpyW(szReserveModuleName, szFileName);
//lstrcatW(szReserveModuleName, L".module");
#if defined(_WIN64)
ReturnData = EngineExtractResource("LOADERx64", szDebuggerName);
/*if(ReserveModuleBase)
{
EngineExtractResource("MODULEx64", szReserveModuleName);
}*/
#else
ReturnData = EngineExtractResource("LOADERx86", szDebuggerName);
/*if(ReserveModuleBase)
{
EngineExtractResource("MODULEx86", szReserveModuleName);
}*/
#endif
if(ReturnData)
{
engineDebuggingDLL = true;
i = lstrlenW(szFileName);
while(szFileName[i] != 0x5C && i >= NULL)
{
i--;
}
/*j = lstrlenW(szReserveModuleName);
while(szReserveModuleName[j] != 0x5C && j >= NULL)
{
j--;
}*/
engineDebuggingDLLBase = NULL;
engineDebuggingMainModuleBase = NULL;
engineDebuggingDLLFullFileName = szFileName;
engineDebuggingDLLFileName = &szFileName[i+1];
//engineDebuggingDLLReserveFileName = &szReserveModuleName[j+1];
DebugModuleImageBase = (ULONG_PTR)GetPE32DataW(szFileName, NULL, UE_IMAGEBASE);
engineReserveModuleBase = DebugModuleImageBase;
DebugModuleEntryPoint = (ULONG_PTR)GetPE32DataW(szFileName, NULL, UE_OEP);
DebugModuleEntryPointCallBack = EntryCallBack;
/*if(ReserveModuleBase)
{
RelocaterChangeFileBaseW(szReserveModuleName, DebugModuleImageBase);
}*/
return(InitDebugW(szDebuggerName, szCommandLine, szCurrentFolder));
}
else
{
return(NULL);
}
return(NULL);
}
__declspec(dllexport) bool TITCALL StopDebug()
{
if(dbgProcessInformation.hProcess != NULL)
{
TerminateThread(dbgProcessInformation.hThread, NULL);
TerminateProcess(dbgProcessInformation.hProcess, NULL);
return(true);
}
else
{
return(false);
}
}
__declspec(dllexport) void TITCALL SetBPXOptions(long DefaultBreakPointType)
{
engineDefaultBreakPointType = DefaultBreakPointType;
}
__declspec(dllexport) bool TITCALL IsBPXEnabled(ULONG_PTR bpxAddress)
{
int i;
ULONG_PTR NumberOfBytesReadWritten = 0;
DWORD MaximumBreakPoints = 0;
BYTE ReadData[10] = {};
for(i = 0; i < BreakPointSetCount; i++)
{
if(BreakPointBuffer[i].BreakPointAddress == bpxAddress)
{
if(BreakPointBuffer[i].BreakPointActive != UE_BPXINACTIVE && BreakPointBuffer[i].BreakPointActive != UE_BPXREMOVED)
{
if(ReadProcessMemory(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, &ReadData[0], UE_MAX_BREAKPOINT_SIZE, &NumberOfBytesReadWritten))
{
if(BreakPointBuffer[i].AdvancedBreakPointType == UE_BREAKPOINT_INT3 && ReadData[0] == INT3BreakPoint)
{
return(true);
}
else if(BreakPointBuffer[i].AdvancedBreakPointType == UE_BREAKPOINT_LONG_INT3 && ReadData[0] == INT3LongBreakPoint[0] && ReadData[1] == INT3LongBreakPoint[1])
{
return(true);
}
else if(BreakPointBuffer[i].AdvancedBreakPointType == UE_BREAKPOINT_UD2 && ReadData[0] == UD2BreakPoint[0] && ReadData[1] == UD2BreakPoint[1])
{
return(true);
}
else
{
return(false);
}
}
else
{
return(false);
}
}
else
{
return(false);
}
}
}
return(false);
}
__declspec(dllexport) bool TITCALL EnableBPX(ULONG_PTR bpxAddress)
{
int i;
MEMORY_BASIC_INFORMATION MemInfo;
ULONG_PTR NumberOfBytesReadWritten = 0;
DWORD MaximumBreakPoints = 0;
bool testWrite = false;
DWORD OldProtect;
for(i = 0; i < BreakPointSetCount; i++)
{
if(BreakPointBuffer[i].BreakPointAddress == bpxAddress)
{
VirtualQueryEx(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
OldProtect = MemInfo.AllocationProtect;
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, BreakPointBuffer[i].BreakPointSize, PAGE_EXECUTE_READWRITE, &OldProtect);
if(BreakPointBuffer[i].BreakPointActive == UE_BPXINACTIVE && (BreakPointBuffer[i].BreakPointType == UE_BREAKPOINT || BreakPointBuffer[i].BreakPointType == UE_SINGLESHOOT))
{
if(BreakPointBuffer[i].AdvancedBreakPointType == UE_BREAKPOINT_INT3)
{
if(WriteProcessMemory(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, &INT3BreakPoint, 1, &NumberOfBytesReadWritten))
{
testWrite = true;
}
}
else if(BreakPointBuffer[i].AdvancedBreakPointType == UE_BREAKPOINT_LONG_INT3)
{
if(WriteProcessMemory(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, &INT3LongBreakPoint, 2, &NumberOfBytesReadWritten))
{
testWrite = true;
}
}
else if(BreakPointBuffer[i].AdvancedBreakPointType == UE_BREAKPOINT_UD2)
{
if(WriteProcessMemory(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, &UD2BreakPoint, 2, &NumberOfBytesReadWritten))
{
testWrite = true;
}
}
if(testWrite)
{
BreakPointBuffer[i].BreakPointActive = UE_BPXACTIVE;
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, BreakPointBuffer[i].BreakPointSize, OldProtect, &OldProtect);
return(true);
}
else
{
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, BreakPointBuffer[i].BreakPointSize, OldProtect, &OldProtect);
return(false);
}
}
else
{
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, BreakPointBuffer[i].BreakPointSize, OldProtect, &OldProtect);
return(false);
}
}
}
return(false);
}
__declspec(dllexport) bool TITCALL DisableBPX(ULONG_PTR bpxAddress)
{
int i;
MEMORY_BASIC_INFORMATION MemInfo;
ULONG_PTR NumberOfBytesReadWritten = 0;
DWORD MaximumBreakPoints = 0;
DWORD OldProtect;
for(i = 0; i < BreakPointSetCount; i++)
{
if(BreakPointBuffer[i].BreakPointAddress == bpxAddress)
{
VirtualQueryEx(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
OldProtect = MemInfo.AllocationProtect;
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, BreakPointBuffer[i].BreakPointSize, PAGE_EXECUTE_READWRITE, &OldProtect);
if(BreakPointBuffer[i].BreakPointActive == UE_BPXACTIVE && (BreakPointBuffer[i].BreakPointType == UE_BREAKPOINT || BreakPointBuffer[i].BreakPointType == UE_SINGLESHOOT))
{
if(WriteProcessMemory(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, &BreakPointBuffer[i].OriginalByte[0], BreakPointBuffer[i].BreakPointSize, &NumberOfBytesReadWritten))
{
BreakPointBuffer[i].BreakPointActive = UE_BPXINACTIVE;
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, BreakPointBuffer[i].BreakPointSize, OldProtect, &OldProtect);
return(true);
}
else
{
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, BreakPointBuffer[i].BreakPointSize, OldProtect, &OldProtect);
return(false);
}
}
else
{
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, BreakPointBuffer[i].BreakPointSize, OldProtect, &OldProtect);
return(false);
}
}
}
return(false);
}
__declspec(dllexport) bool TITCALL SetBPX(ULONG_PTR bpxAddress, DWORD bpxType, LPVOID bpxCallBack)
{
int i = 0;
int j = -1;
void* bpxDataPrt;
PMEMORY_COMPARE_HANDLER bpxDataCmpPtr;
MEMORY_BASIC_INFORMATION MemInfo;
ULONG_PTR NumberOfBytesReadWritten = 0;
BYTE SelectedBreakPointType;
DWORD checkBpxType;
DWORD OldProtect;
if(bpxCallBack == NULL)
{
return(false);
}
for(i = 0; i < BreakPointSetCount; i++)
{
if(BreakPointBuffer[i].BreakPointAddress == bpxAddress && BreakPointBuffer[i].BreakPointActive == UE_BPXACTIVE && (BreakPointBuffer[i].BreakPointType == UE_SINGLESHOOT || BreakPointBuffer[i].BreakPointType == UE_BREAKPOINT))
{
return(false);
}
else if(BreakPointBuffer[i].BreakPointAddress == bpxAddress && BreakPointBuffer[i].BreakPointActive == UE_BPXINACTIVE && (BreakPointBuffer[i].BreakPointType == UE_SINGLESHOOT || BreakPointBuffer[i].BreakPointType == UE_BREAKPOINT))
{
return(EnableBPX(bpxAddress));
}
else if(j == -1 && BreakPointBuffer[i].BreakPointActive == UE_BPXREMOVED)
{
j = i;
}
}
if(j == -1)
{
BreakPointSetCount++;
}
else
{
i = j;
}
if(i < MAXIMUM_BREAKPOINTS)
{
RtlZeroMemory(&BreakPointBuffer[i], sizeof BreakPointDetail);
if(bpxType < UE_BREAKPOINT_TYPE_INT3)
{
if(engineDefaultBreakPointType == UE_BREAKPOINT_INT3)
{
SelectedBreakPointType = UE_BREAKPOINT_INT3;
BreakPointBuffer[i].BreakPointSize = 1;
bpxDataPrt = &INT3BreakPoint;
}
else if(engineDefaultBreakPointType == UE_BREAKPOINT_LONG_INT3)
{
SelectedBreakPointType = UE_BREAKPOINT_LONG_INT3;
BreakPointBuffer[i].BreakPointSize = 2;
bpxDataPrt = &INT3LongBreakPoint;
}
else if(engineDefaultBreakPointType == UE_BREAKPOINT_UD2)
{
SelectedBreakPointType = UE_BREAKPOINT_UD2;
BreakPointBuffer[i].BreakPointSize = 2;
bpxDataPrt = &UD2BreakPoint;
}
}
else
{
checkBpxType = bpxType >> 24;
checkBpxType = checkBpxType << 24;
if(checkBpxType == UE_BREAKPOINT_TYPE_INT3)
{
SelectedBreakPointType = UE_BREAKPOINT_INT3;
BreakPointBuffer[i].BreakPointSize = 1;
bpxDataPrt = &INT3BreakPoint;
}
else if(checkBpxType == UE_BREAKPOINT_TYPE_LONG_INT3)
{
SelectedBreakPointType = UE_BREAKPOINT_LONG_INT3;
BreakPointBuffer[i].BreakPointSize = 2;
bpxDataPrt = &INT3LongBreakPoint;
}
else if(checkBpxType == UE_BREAKPOINT_TYPE_UD2)
{
SelectedBreakPointType = UE_BREAKPOINT_UD2;
BreakPointBuffer[i].BreakPointSize = 2;
bpxDataPrt = &UD2BreakPoint;
}
}
bpxDataCmpPtr = (PMEMORY_COMPARE_HANDLER)bpxDataPrt;
VirtualQueryEx(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
OldProtect = MemInfo.AllocationProtect;
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, BreakPointBuffer[i].BreakPointSize, PAGE_EXECUTE_READWRITE, &OldProtect);
if(ReadProcessMemory(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, &BreakPointBuffer[i].OriginalByte[0], BreakPointBuffer[i].BreakPointSize, &NumberOfBytesReadWritten))
{
/*if(BreakPointBuffer[i].OriginalByte[0] != bpxDataCmpPtr->Array.bArrayEntry[0])
{*/
if(WriteProcessMemory(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, bpxDataPrt, BreakPointBuffer[i].BreakPointSize, &NumberOfBytesReadWritten))
{
BreakPointBuffer[i].AdvancedBreakPointType = (BYTE)SelectedBreakPointType;
BreakPointBuffer[i].BreakPointActive = UE_BPXACTIVE;
BreakPointBuffer[i].BreakPointAddress = bpxAddress;
BreakPointBuffer[i].BreakPointType = (BYTE)bpxType;
BreakPointBuffer[i].NumberOfExecutions = -1;
BreakPointBuffer[i].ExecuteCallBack = (ULONG_PTR)bpxCallBack;
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, BreakPointBuffer[i].BreakPointSize, OldProtect, &OldProtect);
return(true);
}
else
{
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, BreakPointBuffer[i].BreakPointSize, OldProtect, &OldProtect);
return(false);
}
/*}
else
{
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, BreakPointBuffer[i].BreakPointSize, OldProtect, &OldProtect);
return(false);
}*/
}
else
{
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, BreakPointBuffer[i].BreakPointSize, OldProtect, &OldProtect);
return(false);
}
}
else
{
BreakPointSetCount--;
return(false);
}
}
__declspec(dllexport) bool TITCALL SetBPXEx(ULONG_PTR bpxAddress, DWORD bpxType, DWORD NumberOfExecution, DWORD CmpRegister, DWORD CmpCondition, ULONG_PTR CmpValue, LPVOID bpxCallBack, LPVOID bpxCompareCallBack, LPVOID bpxRemoveCallBack)
{
int i = 0;
int j = -1;
void* bpxDataPrt;
PMEMORY_COMPARE_HANDLER bpxDataCmpPtr;
MEMORY_BASIC_INFORMATION MemInfo;
ULONG_PTR NumberOfBytesReadWritten = 0;
BYTE SelectedBreakPointType;
DWORD checkBpxType;
DWORD OldProtect;
if(bpxCallBack == NULL)
{
return(false);
}
for(i = 0; i < BreakPointSetCount; i++)
{
if(BreakPointBuffer[i].BreakPointAddress == bpxAddress && BreakPointBuffer[i].BreakPointActive == UE_BPXACTIVE)
{
return(true);
}
else if(BreakPointBuffer[i].BreakPointAddress == bpxAddress && BreakPointBuffer[i].BreakPointActive == UE_BPXINACTIVE)
{
return(EnableBPX(bpxAddress));
}
else if(j == -1 && BreakPointBuffer[i].BreakPointActive == UE_BPXREMOVED)
{
j = i;
}
}
if(j == -1)
{
BreakPointSetCount++;
}
else
{
i = j;
}
if(i < MAXIMUM_BREAKPOINTS)
{
RtlZeroMemory(&BreakPointBuffer[i], sizeof BreakPointDetail);
if(bpxType < UE_BREAKPOINT_TYPE_INT3)
{
if(engineDefaultBreakPointType == UE_BREAKPOINT_INT3)
{
SelectedBreakPointType = UE_BREAKPOINT_INT3;
BreakPointBuffer[i].BreakPointSize = 1;
bpxDataPrt = &INT3BreakPoint;
}
else if(engineDefaultBreakPointType == UE_BREAKPOINT_LONG_INT3)
{
SelectedBreakPointType = UE_BREAKPOINT_LONG_INT3;
BreakPointBuffer[i].BreakPointSize = 2;
bpxDataPrt = &INT3LongBreakPoint;
}
else if(engineDefaultBreakPointType == UE_BREAKPOINT_UD2)
{
SelectedBreakPointType = UE_BREAKPOINT_UD2;
BreakPointBuffer[i].BreakPointSize = 2;
bpxDataPrt = &UD2BreakPoint;
}
}
else
{
checkBpxType = bpxType >> 24;
checkBpxType = checkBpxType << 24;
if(checkBpxType == UE_BREAKPOINT_TYPE_INT3)
{
SelectedBreakPointType = UE_BREAKPOINT_INT3;
BreakPointBuffer[i].BreakPointSize = 1;
bpxDataPrt = &INT3BreakPoint;
}
else if(checkBpxType == UE_BREAKPOINT_TYPE_LONG_INT3)
{
SelectedBreakPointType = UE_BREAKPOINT_LONG_INT3;
BreakPointBuffer[i].BreakPointSize = 2;
bpxDataPrt = &INT3LongBreakPoint;
}
else if(checkBpxType == UE_BREAKPOINT_TYPE_UD2)
{
SelectedBreakPointType = UE_BREAKPOINT_UD2;
BreakPointBuffer[i].BreakPointSize = 2;
bpxDataPrt = &UD2BreakPoint;
}
}
bpxDataCmpPtr = (PMEMORY_COMPARE_HANDLER)bpxDataPrt;
VirtualQueryEx(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
OldProtect = MemInfo.AllocationProtect;
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, BreakPointBuffer[i].BreakPointSize, PAGE_EXECUTE_READWRITE, &OldProtect);
if(ReadProcessMemory(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, &BreakPointBuffer[i].OriginalByte[0], BreakPointBuffer[i].BreakPointSize, &NumberOfBytesReadWritten))
{
/*if(BreakPointBuffer[i].OriginalByte[0] != bpxDataCmpPtr->Array.bArrayEntry[0])
{*/
if(WriteProcessMemory(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, bpxDataPrt, BreakPointBuffer[i].BreakPointSize, &NumberOfBytesReadWritten))
{
BreakPointBuffer[i].AdvancedBreakPointType = (BYTE)SelectedBreakPointType;
BreakPointBuffer[i].BreakPointActive = UE_BPXACTIVE;
BreakPointBuffer[i].BreakPointAddress = bpxAddress;
BreakPointBuffer[i].BreakPointType = (BYTE)bpxType;
BreakPointBuffer[i].NumberOfExecutions = NumberOfExecution;
BreakPointBuffer[i].CmpRegister = CmpRegister;
BreakPointBuffer[i].CmpCondition = (BYTE)CmpCondition;
BreakPointBuffer[i].CmpValue = CmpValue;
BreakPointBuffer[i].ExecuteCallBack = (ULONG_PTR)bpxCallBack;
BreakPointBuffer[i].RemoveCallBack = (ULONG_PTR)bpxRemoveCallBack;
BreakPointBuffer[i].CompareCallBack = (ULONG_PTR)bpxCompareCallBack;
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, BreakPointBuffer[i].BreakPointSize, OldProtect, &OldProtect);
return(true);
}
else
{
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, BreakPointBuffer[i].BreakPointSize, OldProtect, &OldProtect);
return(false);
}
/*}
else
{
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, BreakPointBuffer[i].BreakPointSize, OldProtect, &OldProtect);
return(false);
}*/
}
else
{
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, BreakPointBuffer[i].BreakPointSize, OldProtect, &OldProtect);
return(false);
}
}
else
{
BreakPointSetCount--;
return(false);
}
}
__declspec(dllexport) bool TITCALL DeleteBPX(ULONG_PTR bpxAddress)
{
int i;
typedef void(TITCALL *fCustomBreakPoint)(void* myBreakPointAddress);
fCustomBreakPoint myCustomBreakPoint;
MEMORY_BASIC_INFORMATION MemInfo;
ULONG_PTR NumberOfBytesReadWritten = 0;
DWORD OldProtect;
for(i = 0; i < BreakPointSetCount; i++)
{
if(BreakPointBuffer[i].BreakPointAddress == bpxAddress)
{
if(i - 1 == BreakPointSetCount)
{
BreakPointSetCount--;
}
break;
}
}
if(BreakPointBuffer[i].BreakPointAddress == bpxAddress)
{
VirtualQueryEx(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
OldProtect = MemInfo.AllocationProtect;
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, BreakPointBuffer[i].BreakPointSize, PAGE_EXECUTE_READWRITE, &OldProtect);
if(BreakPointBuffer[i].BreakPointType == UE_BREAKPOINT || BreakPointBuffer[i].BreakPointType == UE_SINGLESHOOT)
{
if(BreakPointBuffer[i].BreakPointActive == UE_BPXACTIVE)
{
if(WriteProcessMemory(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, &BreakPointBuffer[i].OriginalByte[0], BreakPointBuffer[i].BreakPointSize, &NumberOfBytesReadWritten))
{
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, BreakPointBuffer[i].BreakPointSize, OldProtect, &OldProtect);
if(BreakPointBuffer[i].RemoveCallBack != NULL)
{
__try
{
myCustomBreakPoint = (fCustomBreakPoint)((LPVOID)BreakPointBuffer[i].RemoveCallBack);
myCustomBreakPoint((void*)BreakPointBuffer[i].BreakPointAddress);
RtlZeroMemory(&BreakPointBuffer[i], sizeof BreakPointDetail);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
RtlZeroMemory(&BreakPointBuffer[i], sizeof BreakPointDetail);
return(true);
}
}
else
{
RtlZeroMemory(&BreakPointBuffer[i], sizeof BreakPointDetail);
}
return(true);
}
else
{
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, BreakPointBuffer[i].BreakPointSize, OldProtect, &OldProtect);
return(false);
}
}
else
{
RtlZeroMemory(&BreakPointBuffer[i], sizeof BreakPointDetail);
return(true);
}
}
else
{
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, BreakPointBuffer[i].BreakPointSize, OldProtect, &OldProtect);
return(false);
}
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL SafeDeleteBPX(ULONG_PTR bpxAddress)
{
return(DeleteBPX(bpxAddress));
}
__declspec(dllexport) bool TITCALL SetAPIBreakPoint(char* szDLLName, char* szAPIName, DWORD bpxType, DWORD bpxPlace, LPVOID bpxCallBack)
{
BYTE ReadByte = NULL;
HMODULE hModule = NULL;
DWORD ReadMemSize = NULL;
ULONG_PTR APIAddress = NULL;
ULONG_PTR tryAPIAddress = NULL;
ULONG_PTR QueryAPIAddress = NULL;
int i = MAX_RET_SEARCH_INSTRUCTIONS;
ULONG_PTR ueNumberOfReadWrite = NULL;
int currentInstructionLen = NULL;
bool ModuleLoaded = false;
void* CmdBuffer = NULL;
bool RemovedBpx = false;
if(szDLLName != NULL && szAPIName != NULL)
{
hModule = GetModuleHandleA(szDLLName);
if(hModule == NULL)
{
if(engineAlowModuleLoading)
{
hModule = LoadLibraryA(szDLLName);
ModuleLoaded = true;
}
else
{
ReadMemSize = MAX_RET_SEARCH_INSTRUCTIONS * MAXIMUM_INSTRUCTION_SIZE;
APIAddress = (ULONG_PTR)EngineGlobalAPIHandler(dbgProcessInformation.hProcess, NULL, NULL, szAPIName, UE_OPTION_IMPORTER_RETURN_APIADDRESS);
if(APIAddress != NULL)
{
CmdBuffer = VirtualAlloc(NULL, ReadMemSize, MEM_COMMIT, PAGE_READWRITE);
while(ReadProcessMemory(dbgProcessInformation.hProcess, (void*)APIAddress, CmdBuffer, ReadMemSize, &ueNumberOfReadWrite) == false && ReadMemSize > NULL)
{
ReadMemSize = ReadMemSize - (MAXIMUM_INSTRUCTION_SIZE * 10);
}
if(ReadMemSize == NULL)
{
VirtualFree(CmdBuffer, NULL, MEM_RELEASE);
APIAddress = NULL;
}
else
{
tryAPIAddress = (ULONG_PTR)CmdBuffer;
}
}
}
}
if(hModule != NULL || APIAddress != NULL)
{
if(hModule != NULL)
{
APIAddress = (ULONG_PTR)GetProcAddress(hModule, szAPIName);
}
if(bpxPlace == UE_APIEND)
{
if(tryAPIAddress == NULL)
{
tryAPIAddress = APIAddress;
}
QueryAPIAddress = APIAddress;
RtlMoveMemory(&ReadByte, (LPVOID)tryAPIAddress, 1);
while(i > 0 && ReadByte != 0xC3 && ReadByte != 0xC2)
{
if(engineAlowModuleLoading == false && CmdBuffer != NULL)
{
if(IsBPXEnabled(QueryAPIAddress))
{
DisableBPX(QueryAPIAddress);
ReadProcessMemory(dbgProcessInformation.hProcess, (void*)APIAddress, CmdBuffer, ReadMemSize, &ueNumberOfReadWrite);
RemovedBpx = true;
}
}
currentInstructionLen = StaticLengthDisassemble((LPVOID)tryAPIAddress);
tryAPIAddress = tryAPIAddress + currentInstructionLen;
RtlMoveMemory(&ReadByte, (LPVOID)tryAPIAddress, 1);
QueryAPIAddress = QueryAPIAddress + currentInstructionLen;
if(!engineAlowModuleLoading)
{
if(RemovedBpx)
{
EnableBPX(QueryAPIAddress - currentInstructionLen);
}
}
RemovedBpx = false;
i--;
}
if(i != NULL)
{
if((engineAlowModuleLoading == true && ModuleLoaded == true) || (engineAlowModuleLoading == true && ModuleLoaded == false))
{
APIAddress = tryAPIAddress;
}
else if(!engineAlowModuleLoading)
{
if(CmdBuffer != NULL)
{
APIAddress = tryAPIAddress - (ULONG_PTR)CmdBuffer + APIAddress;
}
else
{
APIAddress = tryAPIAddress;
}
}
}
else
{
if(ModuleLoaded)
{
FreeLibrary(hModule);
}
if(CmdBuffer != NULL)
{
VirtualFree(CmdBuffer, NULL, MEM_RELEASE);
}
return(false);
}
}
if(engineAlowModuleLoading)
{
APIAddress = (ULONG_PTR)EngineGlobalAPIHandler(dbgProcessInformation.hProcess, NULL, APIAddress, NULL, UE_OPTION_IMPORTER_REALIGN_APIADDRESS);
if(ModuleLoaded)
{
FreeLibrary(hModule);
}
}
else
{
if(CmdBuffer != NULL)
{
VirtualFree(CmdBuffer, NULL, MEM_RELEASE);
}
}
return(SetBPX(APIAddress, bpxType, bpxCallBack));
}
else
{
if(engineAlowModuleLoading)
{
if(ModuleLoaded)
{
FreeLibrary(hModule);
}
}
else
{
if(CmdBuffer != NULL)
{
VirtualFree(CmdBuffer, NULL, MEM_RELEASE);
}
}
return(false);
}
}
else
{
return(false);
}
return(false);
}
__declspec(dllexport) bool TITCALL DeleteAPIBreakPoint(char* szDLLName, char* szAPIName, DWORD bpxPlace)
{
BYTE ReadByte = NULL;
HMODULE hModule = NULL;
DWORD ReadMemSize = NULL;
ULONG_PTR APIAddress = NULL;
ULONG_PTR tryAPIAddress = NULL;
ULONG_PTR QueryAPIAddress = NULL;
int i = MAX_RET_SEARCH_INSTRUCTIONS;
ULONG_PTR ueNumberOfReadWrite = NULL;
int currentInstructionLen = NULL;
bool ModuleLoaded = false;
void* CmdBuffer = NULL;
bool RemovedBpx = false;
if(szDLLName != NULL && szAPIName != NULL)
{
hModule = GetModuleHandleA(szDLLName);
if(hModule == NULL)
{
if(engineAlowModuleLoading)
{
hModule = LoadLibraryA(szDLLName);
ModuleLoaded = true;
}
else
{
ReadMemSize = MAX_RET_SEARCH_INSTRUCTIONS * MAXIMUM_INSTRUCTION_SIZE;
APIAddress = (ULONG_PTR)EngineGlobalAPIHandler(dbgProcessInformation.hProcess, NULL, NULL, szAPIName, UE_OPTION_IMPORTER_RETURN_APIADDRESS);
if(APIAddress != NULL)
{
CmdBuffer = VirtualAlloc(NULL, ReadMemSize, MEM_COMMIT, PAGE_READWRITE);
while(ReadProcessMemory(dbgProcessInformation.hProcess, (void*)APIAddress, CmdBuffer, ReadMemSize, &ueNumberOfReadWrite) == false && ReadMemSize > NULL)
{
ReadMemSize = ReadMemSize - (MAXIMUM_INSTRUCTION_SIZE * 10);
}
if(ReadMemSize == NULL)
{
VirtualFree(CmdBuffer, NULL, MEM_RELEASE);
APIAddress = NULL;
}
else
{
tryAPIAddress = (ULONG_PTR)CmdBuffer;
}
}
}
}
if(hModule != NULL || APIAddress != NULL)
{
if(hModule != NULL)
{
APIAddress = (ULONG_PTR)GetProcAddress(hModule, szAPIName);
}
if(bpxPlace == UE_APIEND)
{
if(tryAPIAddress == NULL)
{
tryAPIAddress = APIAddress;
}
QueryAPIAddress = APIAddress;
RtlMoveMemory(&ReadByte, (LPVOID)tryAPIAddress, 1);
while(i > 0 && ReadByte != 0xC3 && ReadByte != 0xC2)
{
if(engineAlowModuleLoading == false && CmdBuffer != NULL)
{
if(IsBPXEnabled(QueryAPIAddress))
{
DisableBPX(QueryAPIAddress);
ReadProcessMemory(dbgProcessInformation.hProcess, (void*)APIAddress, CmdBuffer, ReadMemSize, &ueNumberOfReadWrite);
RemovedBpx = true;
}
}
currentInstructionLen = StaticLengthDisassemble((LPVOID)tryAPIAddress);
tryAPIAddress = tryAPIAddress + currentInstructionLen;
RtlMoveMemory(&ReadByte, (LPVOID)tryAPIAddress, 1);
QueryAPIAddress = QueryAPIAddress + currentInstructionLen;
if(!engineAlowModuleLoading)
{
if(RemovedBpx)
{
EnableBPX(QueryAPIAddress - currentInstructionLen);
}
}
RemovedBpx = false;
i--;
}
if(i != NULL)
{
if((engineAlowModuleLoading == true && ModuleLoaded == true) || (engineAlowModuleLoading == true && ModuleLoaded == false))
{
APIAddress = tryAPIAddress;
}
else if(!engineAlowModuleLoading)
{
if(CmdBuffer != NULL)
{
APIAddress = tryAPIAddress - (ULONG_PTR)CmdBuffer + APIAddress;
}
else
{
APIAddress = tryAPIAddress;
}
}
}
else
{
if(ModuleLoaded)
{
FreeLibrary(hModule);
}
if(CmdBuffer != NULL)
{
VirtualFree(CmdBuffer, NULL, MEM_RELEASE);
}
return(false);
}
}
if(engineAlowModuleLoading)
{
APIAddress = (ULONG_PTR)EngineGlobalAPIHandler(dbgProcessInformation.hProcess, NULL, APIAddress, NULL, UE_OPTION_IMPORTER_REALIGN_APIADDRESS);
if(ModuleLoaded)
{
FreeLibrary(hModule);
}
}
else
{
if(CmdBuffer != NULL)
{
VirtualFree(CmdBuffer, NULL, MEM_RELEASE);
}
}
return(DeleteBPX(APIAddress));
}
else
{
if(engineAlowModuleLoading)
{
if(ModuleLoaded)
{
FreeLibrary(hModule);
}
}
else
{
if(CmdBuffer != NULL)
{
VirtualFree(CmdBuffer, NULL, MEM_RELEASE);
}
}
return(false);
}
}
else
{
return(false);
}
return(false);
}
__declspec(dllexport) bool TITCALL SafeDeleteAPIBreakPoint(char* szDLLName, char* szAPIName, DWORD bpxPlace)
{
return(DeleteAPIBreakPoint(szDLLName, szAPIName, bpxPlace));
}
__declspec(dllexport) bool TITCALL SetMemoryBPX(ULONG_PTR MemoryStart, DWORD SizeOfMemory, LPVOID bpxCallBack)
{
int i = 0;
int j = -1;
MEMORY_BASIC_INFORMATION MemInfo;
ULONG_PTR NumberOfBytesReadWritten = 0;
DWORD NewProtect = 0;
DWORD OldProtect = 0;
for(i = 0; i < BreakPointSetCount; i++)
{
if(BreakPointBuffer[i].BreakPointAddress == MemoryStart)
{
if(BreakPointBuffer[i].BreakPointActive == UE_BPXACTIVE)
{
RemoveMemoryBPX(BreakPointBuffer[i].BreakPointAddress, BreakPointBuffer[i].BreakPointSize);
}
j = i;
break;
}
else if(j == -1 && BreakPointBuffer[i].BreakPointActive == UE_BPXREMOVED)
{
j = i;
}
}
if(BreakPointBuffer[i].BreakPointAddress != MemoryStart)
{
if(j != -1)
{
i = j;
}
else
{
BreakPointSetCount++;
}
}
if(i < MAXIMUM_BREAKPOINTS)
{
RtlZeroMemory(&BreakPointBuffer[i], sizeof BreakPointDetail);
VirtualQueryEx(dbgProcessInformation.hProcess, (LPVOID)MemoryStart, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
OldProtect = MemInfo.Protect;
if(!(OldProtect & PAGE_GUARD))
{
NewProtect = OldProtect ^ PAGE_GUARD;
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)MemoryStart, SizeOfMemory, NewProtect, &OldProtect);
BreakPointBuffer[i].BreakPointActive = UE_BPXACTIVE;
BreakPointBuffer[i].BreakPointAddress = MemoryStart;
BreakPointBuffer[i].BreakPointType = UE_MEMORY;
BreakPointBuffer[i].BreakPointSize = SizeOfMemory;
BreakPointBuffer[i].NumberOfExecutions = -1;
BreakPointBuffer[i].ExecuteCallBack = (ULONG_PTR)bpxCallBack;
}
return(true);
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL SetMemoryBPXEx(ULONG_PTR MemoryStart, DWORD SizeOfMemory, DWORD BreakPointType, bool RestoreOnHit, LPVOID bpxCallBack)
{
int i = 0;
int j = -1;
MEMORY_BASIC_INFORMATION MemInfo;
ULONG_PTR NumberOfBytesReadWritten = 0;
DWORD NewProtect = 0;
DWORD OldProtect = 0;
for(i = 0; i < BreakPointSetCount; i++)
{
if(BreakPointBuffer[i].BreakPointAddress == MemoryStart)
{
if(BreakPointBuffer[i].BreakPointActive == UE_BPXACTIVE)
{
RemoveMemoryBPX(BreakPointBuffer[i].BreakPointAddress, BreakPointBuffer[i].BreakPointSize);
}
j = i;
break;
}
else if(j == -1 && BreakPointBuffer[i].BreakPointActive == UE_BPXREMOVED)
{
j = i;
}
}
if(BreakPointBuffer[i].BreakPointAddress != MemoryStart)
{
if(j != -1)
{
i = j;
}
else
{
BreakPointSetCount++;
}
}
if(i < MAXIMUM_BREAKPOINTS)
{
RtlZeroMemory(&BreakPointBuffer[i], sizeof BreakPointDetail);
VirtualQueryEx(dbgProcessInformation.hProcess, (LPVOID)MemoryStart, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
OldProtect = MemInfo.Protect;
if(!(OldProtect & PAGE_GUARD))
{
NewProtect = OldProtect ^ PAGE_GUARD;
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)MemoryStart, SizeOfMemory, NewProtect, &OldProtect);
BreakPointBuffer[i].BreakPointActive = UE_BPXACTIVE;
BreakPointBuffer[i].BreakPointAddress = MemoryStart;
BreakPointBuffer[i].BreakPointType = BreakPointType;
BreakPointBuffer[i].BreakPointSize = SizeOfMemory;
BreakPointBuffer[i].NumberOfExecutions = -1;
BreakPointBuffer[i].MemoryBpxRestoreOnHit = (BYTE)RestoreOnHit;
BreakPointBuffer[i].ExecuteCallBack = (ULONG_PTR)bpxCallBack;
}
return(true);
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL RemoveMemoryBPX(ULONG_PTR MemoryStart, DWORD SizeOfMemory)
{
int i = 0;
MEMORY_BASIC_INFORMATION MemInfo;
ULONG_PTR NumberOfBytesReadWritten = 0;
DWORD NewProtect = 0;
DWORD OldProtect = 0;
for(i = 0; i < BreakPointSetCount; i++)
{
if(BreakPointBuffer[i].BreakPointAddress == MemoryStart &&
(BreakPointBuffer[i].BreakPointType == UE_MEMORY ||
BreakPointBuffer[i].BreakPointType == UE_MEMORY_READ ||
BreakPointBuffer[i].BreakPointType == UE_MEMORY_WRITE ||
BreakPointBuffer[i].BreakPointType == UE_MEMORY_EXECUTE)
)
{
if(i - 1 == BreakPointSetCount)
{
BreakPointSetCount--;
}
break;
}
}
if(BreakPointBuffer[i].BreakPointAddress == MemoryStart)
{
VirtualQueryEx(dbgProcessInformation.hProcess, (LPVOID)MemoryStart, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
OldProtect = MemInfo.AllocationProtect;
if(OldProtect & PAGE_GUARD)
{
NewProtect = OldProtect ^ PAGE_GUARD;
}
else
{
NewProtect = OldProtect;
}
if(SizeOfMemory != NULL)
{
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)MemoryStart, SizeOfMemory, NewProtect, &OldProtect);
}
else
{
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)MemoryStart, BreakPointBuffer[i].BreakPointSize, NewProtect, &OldProtect);
}
RtlZeroMemory(&BreakPointBuffer[i], sizeof BreakPointDetail);
return(true);
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL GetContextFPUDataEx(HANDLE hActiveThread, void* FPUSaveArea)
{
if(FPUSaveArea != NULL)
{
RtlZeroMemory(&DBGContext, sizeof CONTEXT);
DBGContext.ContextFlags = CONTEXT_ALL;
GetThreadContext(hActiveThread, &DBGContext);
#if !defined (_WIN64)
RtlMoveMemory(FPUSaveArea, &DBGContext.FloatSave, sizeof FLOATING_SAVE_AREA);
#else
RtlMoveMemory(FPUSaveArea, &DBGContext.FltSave, sizeof XMM_SAVE_AREA32);
#endif
return(true);
}
else
{
return(false);
}
}
__declspec(dllexport) long long TITCALL GetContextDataEx(HANDLE hActiveThread, DWORD IndexOfRegister)
{
RtlZeroMemory(&DBGContext, sizeof CONTEXT);
DBGContext.ContextFlags = CONTEXT_ALL;
#if defined(_WIN64)
GetThreadContext(hActiveThread, &DBGContext);
if(IndexOfRegister == UE_EAX)
{
return((DWORD)DBGContext.Rax);
}
else if(IndexOfRegister == UE_EBX)
{
return((DWORD)DBGContext.Rbx);
}
else if(IndexOfRegister == UE_ECX)
{
return((DWORD)DBGContext.Rcx);
}
else if(IndexOfRegister == UE_EDX)
{
return((DWORD)DBGContext.Rdx);
}
else if(IndexOfRegister == UE_EDI)
{
return((DWORD)DBGContext.Rdi);
}
else if(IndexOfRegister == UE_ESI)
{
return((DWORD)DBGContext.Rsi);
}
else if(IndexOfRegister == UE_EBP)
{
return((DWORD)DBGContext.Rbp);
}
else if(IndexOfRegister == UE_ESP)
{
return((DWORD)DBGContext.Rsp);
}
else if(IndexOfRegister == UE_EIP)
{
return((DWORD)DBGContext.Rip);
}
else if(IndexOfRegister == UE_EFLAGS)
{
return((DWORD)DBGContext.EFlags);
}
else if(IndexOfRegister == UE_RAX)
{
return(DBGContext.Rax);
}
else if(IndexOfRegister == UE_RBX)
{
return(DBGContext.Rbx);
}
else if(IndexOfRegister == UE_RCX)
{
return(DBGContext.Rcx);
}
else if(IndexOfRegister == UE_RDX)
{
return(DBGContext.Rdx);
}
else if(IndexOfRegister == UE_RDI)
{
return(DBGContext.Rdi);
}
else if(IndexOfRegister == UE_RSI)
{
return(DBGContext.Rsi);
}
else if(IndexOfRegister == UE_RBP)
{
return(DBGContext.Rbp);
}
else if(IndexOfRegister == UE_RSP)
{
return(DBGContext.Rsp);
}
else if(IndexOfRegister == UE_RIP)
{
return(DBGContext.Rip);
}
else if(IndexOfRegister == UE_RFLAGS)
{
return(DBGContext.EFlags);
}
else if(IndexOfRegister == UE_DR0)
{
return(DBGContext.Dr0);
}
else if(IndexOfRegister == UE_DR1)
{
return(DBGContext.Dr1);
}
else if(IndexOfRegister == UE_DR2)
{
return(DBGContext.Dr2);
}
else if(IndexOfRegister == UE_DR3)
{
return(DBGContext.Dr3);
}
else if(IndexOfRegister == UE_DR6)
{
return(DBGContext.Dr6);
}
else if(IndexOfRegister == UE_DR7)
{
return(DBGContext.Dr7);
}
else if(IndexOfRegister == UE_R8)
{
return(DBGContext.R8);
}
else if(IndexOfRegister == UE_R9)
{
return(DBGContext.R9);
}
else if(IndexOfRegister == UE_R10)
{
return(DBGContext.R10);
}
else if(IndexOfRegister == UE_R11)
{
return(DBGContext.R11);
}
else if(IndexOfRegister == UE_R12)
{
return(DBGContext.R12);
}
else if(IndexOfRegister == UE_R13)
{
return(DBGContext.R13);
}
else if(IndexOfRegister == UE_R14)
{
return(DBGContext.R14);
}
else if(IndexOfRegister == UE_R15)
{
return(DBGContext.R15);
}
else if(IndexOfRegister == UE_CIP)
{
return(DBGContext.Rip);
}
else if(IndexOfRegister == UE_CSP)
{
return(DBGContext.Rsp);
}
else if(IndexOfRegister == UE_SEG_GS)
{
return(DBGContext.SegGs);
}
else if(IndexOfRegister == UE_SEG_FS)
{
return(DBGContext.SegFs);
}
else if(IndexOfRegister == UE_SEG_ES)
{
return(DBGContext.SegEs);
}
else if(IndexOfRegister == UE_SEG_DS)
{
return(DBGContext.SegDs);
}
else if(IndexOfRegister == UE_SEG_CS)
{
return(DBGContext.SegCs);
}
else if(IndexOfRegister == UE_SEG_SS)
{
return(DBGContext.SegSs);
}
#else
GetThreadContext(hActiveThread, &DBGContext);
if(IndexOfRegister == UE_EAX)
{
return(DBGContext.Eax);
}
else if(IndexOfRegister == UE_EBX)
{
return(DBGContext.Ebx);
}
else if(IndexOfRegister == UE_ECX)
{
return(DBGContext.Ecx);
}
else if(IndexOfRegister == UE_EDX)
{
return(DBGContext.Edx);
}
else if(IndexOfRegister == UE_EDI)
{
return(DBGContext.Edi);
}
else if(IndexOfRegister == UE_ESI)
{
return(DBGContext.Esi);
}
else if(IndexOfRegister == UE_EBP)
{
return(DBGContext.Ebp);
}
else if(IndexOfRegister == UE_ESP)
{
return(DBGContext.Esp);
}
else if(IndexOfRegister == UE_EIP)
{
return(DBGContext.Eip);
}
else if(IndexOfRegister == UE_EFLAGS)
{
return(DBGContext.EFlags);
}
else if(IndexOfRegister == UE_DR0)
{
return(DBGContext.Dr0);
}
else if(IndexOfRegister == UE_DR1)
{
return(DBGContext.Dr1);
}
else if(IndexOfRegister == UE_DR2)
{
return(DBGContext.Dr2);
}
else if(IndexOfRegister == UE_DR3)
{
return(DBGContext.Dr3);
}
else if(IndexOfRegister == UE_DR6)
{
return(DBGContext.Dr6);
}
else if(IndexOfRegister == UE_DR7)
{
return(DBGContext.Dr7);
}
else if(IndexOfRegister == UE_CIP)
{
return(DBGContext.Eip);
}
else if(IndexOfRegister == UE_CSP)
{
return(DBGContext.Esp);
}
else if(IndexOfRegister == UE_SEG_GS)
{
return(DBGContext.SegGs);
}
else if(IndexOfRegister == UE_SEG_FS)
{
return(DBGContext.SegFs);
}
else if(IndexOfRegister == UE_SEG_ES)
{
return(DBGContext.SegEs);
}
else if(IndexOfRegister == UE_SEG_DS)
{
return(DBGContext.SegDs);
}
else if(IndexOfRegister == UE_SEG_CS)
{
return(DBGContext.SegCs);
}
else if(IndexOfRegister == UE_SEG_SS)
{
return(DBGContext.SegSs);
}
#endif
return(NULL);
}
__declspec(dllexport) long long TITCALL GetContextData(DWORD IndexOfRegister)
{
HANDLE hActiveThread = 0;
long long ContextReturn;
hActiveThread = OpenThread(THREAD_GET_CONTEXT+THREAD_SET_CONTEXT+THREAD_QUERY_INFORMATION, false, DBGEvent.dwThreadId);
ContextReturn = GetContextDataEx(hActiveThread, IndexOfRegister);
EngineCloseHandle(hActiveThread);
return(ContextReturn);
}
__declspec(dllexport) bool TITCALL SetContextFPUDataEx(HANDLE hActiveThread, void* FPUSaveArea)
{
if(FPUSaveArea != NULL)
{
RtlZeroMemory(&DBGContext, sizeof CONTEXT);
DBGContext.ContextFlags = CONTEXT_ALL;
GetThreadContext(hActiveThread, &DBGContext);
#if !defined (_WIN64)
RtlMoveMemory(&DBGContext.FloatSave, FPUSaveArea, sizeof FLOATING_SAVE_AREA);
#else
RtlMoveMemory(&DBGContext.FltSave, FPUSaveArea, sizeof XMM_SAVE_AREA32);
#endif
if(SetThreadContext(hActiveThread, &DBGContext))
{
return(true);
}
}
return(false);
}
__declspec(dllexport) bool TITCALL SetContextDataEx(HANDLE hActiveThread, DWORD IndexOfRegister, ULONG_PTR NewRegisterValue)
{
SuspendThread(hActiveThread);
RtlZeroMemory(&DBGContext, sizeof CONTEXT);
DBGContext.ContextFlags = CONTEXT_ALL;
#ifdef _WIN64
GetThreadContext(hActiveThread, &DBGContext);
if(IndexOfRegister == UE_EAX)
{
NewRegisterValue = DBGContext.Rax - (DWORD)DBGContext.Rax + NewRegisterValue;
DBGContext.Rax = NewRegisterValue;
}
else if(IndexOfRegister == UE_EBX)
{
NewRegisterValue = DBGContext.Rbx - (DWORD)DBGContext.Rbx + NewRegisterValue;
DBGContext.Rbx = NewRegisterValue;
}
else if(IndexOfRegister == UE_ECX)
{
NewRegisterValue = DBGContext.Rcx - (DWORD)DBGContext.Rcx + NewRegisterValue;
DBGContext.Rcx = NewRegisterValue;
}
else if(IndexOfRegister == UE_EDX)
{
NewRegisterValue = DBGContext.Rdx - (DWORD)DBGContext.Rdx + NewRegisterValue;
DBGContext.Rdx = NewRegisterValue;
}
else if(IndexOfRegister == UE_EDI)
{
NewRegisterValue = DBGContext.Rdi - (DWORD)DBGContext.Rdi + NewRegisterValue;
DBGContext.Rdi = NewRegisterValue;
}
else if(IndexOfRegister == UE_ESI)
{
NewRegisterValue = DBGContext.Rsi - (DWORD)DBGContext.Rsi + NewRegisterValue;
DBGContext.Rsi = NewRegisterValue;
}
else if(IndexOfRegister == UE_EBP)
{
NewRegisterValue = DBGContext.Rbp - (DWORD)DBGContext.Rbp + NewRegisterValue;
DBGContext.Rbp = NewRegisterValue;
}
else if(IndexOfRegister == UE_ESP)
{
NewRegisterValue = DBGContext.Rsp - (DWORD)DBGContext.Rsp + NewRegisterValue;
DBGContext.Rsp = NewRegisterValue;
}
else if(IndexOfRegister == UE_EIP)
{
NewRegisterValue = DBGContext.Rip - (DWORD)DBGContext.Rip + NewRegisterValue;
DBGContext.Rip = NewRegisterValue;
}
else if(IndexOfRegister == UE_EFLAGS)
{
DBGContext.EFlags = (DWORD)NewRegisterValue;
}
else if(IndexOfRegister == UE_RAX)
{
DBGContext.Rax = NewRegisterValue;
}
else if(IndexOfRegister == UE_RBX)
{
DBGContext.Rbx = NewRegisterValue;
}
else if(IndexOfRegister == UE_RCX)
{
DBGContext.Rcx = NewRegisterValue;
}
else if(IndexOfRegister == UE_RDX)
{
DBGContext.Rdx = NewRegisterValue;
}
else if(IndexOfRegister == UE_RDI)
{
DBGContext.Rdi = NewRegisterValue;
}
else if(IndexOfRegister == UE_RSI)
{
DBGContext.Rsi = NewRegisterValue;
}
else if(IndexOfRegister == UE_RBP)
{
DBGContext.Rbp = NewRegisterValue;
}
else if(IndexOfRegister == UE_RSP)
{
DBGContext.Rsp = NewRegisterValue;
}
else if(IndexOfRegister == UE_RIP)
{
DBGContext.Rip = NewRegisterValue;
}
else if(IndexOfRegister == UE_RFLAGS)
{
DBGContext.EFlags = (DWORD)NewRegisterValue;
}
else if(IndexOfRegister == UE_DR0)
{
DBGContext.Dr0 = NewRegisterValue;
}
else if(IndexOfRegister == UE_DR1)
{
DBGContext.Dr1 = NewRegisterValue;
}
else if(IndexOfRegister == UE_DR2)
{
DBGContext.Dr2 = NewRegisterValue;
}
else if(IndexOfRegister == UE_DR3)
{
DBGContext.Dr3 = NewRegisterValue;
}
else if(IndexOfRegister == UE_DR6)
{
DBGContext.Dr6 = NewRegisterValue;
}
else if(IndexOfRegister == UE_DR7)
{
DBGContext.Dr7 = NewRegisterValue;
}
else if(IndexOfRegister == UE_R8)
{
DBGContext.R8 = NewRegisterValue;
}
else if(IndexOfRegister == UE_R9)
{
DBGContext.R9 = NewRegisterValue;
}
else if(IndexOfRegister == UE_R10)
{
DBGContext.R10 = NewRegisterValue;
}
else if(IndexOfRegister == UE_R11)
{
DBGContext.R11 = NewRegisterValue;
}
else if(IndexOfRegister == UE_R12)
{
DBGContext.R12 = NewRegisterValue;
}
else if(IndexOfRegister == UE_R13)
{
DBGContext.R13 = NewRegisterValue;
}
else if(IndexOfRegister == UE_R14)
{
DBGContext.R14 = NewRegisterValue;
}
else if(IndexOfRegister == UE_R15)
{
DBGContext.R15 = NewRegisterValue;
}
else if(IndexOfRegister == UE_CIP)
{
DBGContext.Rip = NewRegisterValue;
}
else if(IndexOfRegister == UE_CSP)
{
DBGContext.Rsp = NewRegisterValue;
}
else if(IndexOfRegister == UE_SEG_GS)
{
DBGContext.SegGs = (WORD)NewRegisterValue;
}
else if(IndexOfRegister == UE_SEG_FS)
{
DBGContext.SegFs = (WORD)NewRegisterValue;
}
else if(IndexOfRegister == UE_SEG_ES)
{
DBGContext.SegEs = (WORD)NewRegisterValue;
}
else if(IndexOfRegister == UE_SEG_DS)
{
DBGContext.SegDs = (WORD)NewRegisterValue;
}
else if(IndexOfRegister == UE_SEG_CS)
{
DBGContext.SegCs = (WORD)NewRegisterValue;
}
else if(IndexOfRegister == UE_SEG_SS)
{
DBGContext.SegSs = (WORD)NewRegisterValue;
}
else
{
ResumeThread(hActiveThread);
return(false);
}
if(SetThreadContext(hActiveThread, &DBGContext))
{
ResumeThread(hActiveThread);
return(true);
}
#else
GetThreadContext(hActiveThread, &DBGContext);
if(IndexOfRegister == UE_EAX)
{
DBGContext.Eax = NewRegisterValue;
}
else if(IndexOfRegister == UE_EBX)
{
DBGContext.Ebx = NewRegisterValue;
}
else if(IndexOfRegister == UE_ECX)
{
DBGContext.Ecx = NewRegisterValue;
}
else if(IndexOfRegister == UE_EDX)
{
DBGContext.Edx = NewRegisterValue;
}
else if(IndexOfRegister == UE_EDI)
{
DBGContext.Edi = NewRegisterValue;
}
else if(IndexOfRegister == UE_ESI)
{
DBGContext.Esi = NewRegisterValue;
}
else if(IndexOfRegister == UE_EBP)
{
DBGContext.Ebp = NewRegisterValue;
}
else if(IndexOfRegister == UE_ESP)
{
DBGContext.Esp = NewRegisterValue;
}
else if(IndexOfRegister == UE_EIP)
{
DBGContext.Eip = NewRegisterValue;
}
else if(IndexOfRegister == UE_EFLAGS)
{
DBGContext.EFlags = NewRegisterValue;
}
else if(IndexOfRegister == UE_DR0)
{
DBGContext.Dr0 = NewRegisterValue;
}
else if(IndexOfRegister == UE_DR1)
{
DBGContext.Dr1 = NewRegisterValue;
}
else if(IndexOfRegister == UE_DR2)
{
DBGContext.Dr2 = NewRegisterValue;
}
else if(IndexOfRegister == UE_DR3)
{
DBGContext.Dr3 = NewRegisterValue;
}
else if(IndexOfRegister == UE_DR6)
{
DBGContext.Dr6 = NewRegisterValue;
}
else if(IndexOfRegister == UE_DR7)
{
DBGContext.Dr7 = NewRegisterValue;
}
else if(IndexOfRegister == UE_CIP)
{
DBGContext.Eip = NewRegisterValue;
}
else if(IndexOfRegister == UE_CSP)
{
DBGContext.Esp = NewRegisterValue;
}
else if(IndexOfRegister == UE_SEG_GS)
{
DBGContext.SegGs = NewRegisterValue;
}
else if(IndexOfRegister == UE_SEG_FS)
{
DBGContext.SegFs = NewRegisterValue;
}
else if(IndexOfRegister == UE_SEG_ES)
{
DBGContext.SegEs = NewRegisterValue;
}
else if(IndexOfRegister == UE_SEG_DS)
{
DBGContext.SegDs = NewRegisterValue;
}
else if(IndexOfRegister == UE_SEG_CS)
{
DBGContext.SegCs = NewRegisterValue;
}
else if(IndexOfRegister == UE_SEG_SS)
{
DBGContext.SegSs = NewRegisterValue;
}
else
{
ResumeThread(hActiveThread);
return(false);
}
if(SetThreadContext(hActiveThread, &DBGContext))
{
ResumeThread(hActiveThread);
return(true);
}
#endif
ResumeThread(hActiveThread);
return(false);
}
__declspec(dllexport) bool TITCALL SetContextData(DWORD IndexOfRegister, ULONG_PTR NewRegisterValue)
{
HANDLE hActiveThread = 0;
bool ContextReturn;
hActiveThread = OpenThread(THREAD_ALL_ACCESS, false, DBGEvent.dwThreadId);
ContextReturn = SetContextDataEx(hActiveThread, IndexOfRegister, NewRegisterValue);
EngineCloseHandle(hActiveThread);
return(ContextReturn);
}
__declspec(dllexport) void TITCALL ClearExceptionNumber()
{
CurrentExceptionsNumber = 0;
}
__declspec(dllexport) long TITCALL CurrentExceptionNumber()
{
return(CurrentExceptionsNumber);
}
__declspec(dllexport) bool TITCALL MatchPatternEx(HANDLE hProcess, void* MemoryToCheck, int SizeOfMemoryToCheck, void* PatternToMatch, int SizeOfPatternToMatch, PBYTE WildCard)
{
if(!MemoryToCheck || !PatternToMatch)
return false;
int i = NULL;
BYTE intWildCard = NULL;
LPVOID ueReadBuffer = NULL;
ULONG_PTR ueNumberOfBytesRead = NULL;
MEMORY_BASIC_INFORMATION memoryInformation = {};
PMEMORY_COMPARE_HANDLER memCmp = (PMEMORY_COMPARE_HANDLER)MemoryToCheck;
PMEMORY_COMPARE_HANDLER memPattern = (PMEMORY_COMPARE_HANDLER)PatternToMatch;
if(WildCard == NULL)
{
WildCard = &intWildCard;
}
if(SizeOfMemoryToCheck >= SizeOfPatternToMatch)
{
if(hProcess != GetCurrentProcess())
{
ueReadBuffer = VirtualAlloc(NULL, SizeOfMemoryToCheck, MEM_COMMIT, PAGE_READWRITE);
if(!ReadProcessMemory(hProcess, MemoryToCheck, ueReadBuffer, SizeOfMemoryToCheck, &ueNumberOfBytesRead))
{
if(ueNumberOfBytesRead == NULL)
{
if(VirtualQueryEx(hProcess, MemoryToCheck, &memoryInformation, sizeof memoryInformation) != NULL)
{
SizeOfMemoryToCheck = (int)((ULONG_PTR)memoryInformation.BaseAddress + memoryInformation.RegionSize - (ULONG_PTR)MemoryToCheck);
if(!ReadProcessMemory(hProcess, MemoryToCheck, ueReadBuffer, SizeOfMemoryToCheck, &ueNumberOfBytesRead))
{
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
return(NULL);
}
else
{
memCmp = (PMEMORY_COMPARE_HANDLER)ueReadBuffer;
}
}
else
{
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
return(NULL);
}
}
else
{
memCmp = (PMEMORY_COMPARE_HANDLER)ueReadBuffer;
}
}
else
{
memCmp = (PMEMORY_COMPARE_HANDLER)ueReadBuffer;
}
}
__try
{
while(SizeOfPatternToMatch > NULL)
{
if(memCmp->Array.bArrayEntry[i] != memPattern->Array.bArrayEntry[i] && memPattern->Array.bArrayEntry[i] != *WildCard)
{
return(false);
}
SizeOfPatternToMatch--;
i++;
}
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
return(true);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
return(false);
}
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL MatchPattern(void* MemoryToCheck, int SizeOfMemoryToCheck, void* PatternToMatch, int SizeOfPatternToMatch, PBYTE WildCard)
{
if(dbgProcessInformation.hProcess != NULL)
{
return(MatchPatternEx(dbgProcessInformation.hProcess, MemoryToCheck, SizeOfMemoryToCheck, PatternToMatch, SizeOfPatternToMatch, WildCard));
}
else
{
return(MatchPatternEx(GetCurrentProcess(), MemoryToCheck, SizeOfMemoryToCheck, PatternToMatch, SizeOfPatternToMatch, WildCard));
}
}
__declspec(dllexport) long long TITCALL FindEx(HANDLE hProcess, LPVOID MemoryStart, DWORD MemorySize, LPVOID SearchPattern, DWORD PatternSize, LPBYTE WildCard)
{
int i = NULL;
int j = NULL;
ULONG_PTR Return = NULL;
LPVOID ueReadBuffer = NULL;
PUCHAR SearchBuffer = NULL;
PUCHAR CompareBuffer = NULL;
MEMORY_BASIC_INFORMATION memoryInformation = {};
ULONG_PTR ueNumberOfBytesRead = NULL;
LPVOID currentSearchPosition = NULL;
DWORD currentSizeOfSearch = NULL;
BYTE nWildCard = NULL;
if(WildCard == NULL)
{
WildCard = &nWildCard;
}
if(hProcess != NULL && MemoryStart != NULL && MemorySize != NULL)
{
if(hProcess != GetCurrentProcess())
{
ueReadBuffer = VirtualAlloc(NULL, MemorySize, MEM_COMMIT, PAGE_READWRITE);
if(!ReadProcessMemory(hProcess, MemoryStart, ueReadBuffer, MemorySize, &ueNumberOfBytesRead))
{
if(ueNumberOfBytesRead == NULL)
{
if(VirtualQueryEx(hProcess, MemoryStart, &memoryInformation, sizeof memoryInformation) != NULL)
{
MemorySize = (DWORD)((ULONG_PTR)memoryInformation.BaseAddress + memoryInformation.RegionSize - (ULONG_PTR)MemoryStart);
if(!ReadProcessMemory(hProcess, MemoryStart, ueReadBuffer, MemorySize, &ueNumberOfBytesRead))
{
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
return(NULL);
}
else
{
SearchBuffer = (PUCHAR)ueReadBuffer;
}
}
else
{
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
return(NULL);
}
}
else
{
SearchBuffer = (PUCHAR)ueReadBuffer;
}
}
else
{
SearchBuffer = (PUCHAR)ueReadBuffer;
}
}
else
{
SearchBuffer = (PUCHAR)MemoryStart;
}
__try
{
CompareBuffer = (PUCHAR)SearchPattern;
for(i = 0; i < (int)MemorySize && Return == NULL; i++)
{
for(j = 0; j < (int)PatternSize; j++)
{
if(CompareBuffer[j] != *(PUCHAR)WildCard && SearchBuffer[i + j] != CompareBuffer[j])
{
break;
}
}
if(j == (int)PatternSize)
{
Return = (ULONG_PTR)MemoryStart + i;
}
}
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
return(Return);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
VirtualFree(ueReadBuffer, NULL, MEM_RELEASE);
return(NULL);
}
}
else
{
return(NULL);
}
}
extern "C" __declspec(dllexport) long long TITCALL Find(LPVOID MemoryStart, DWORD MemorySize, LPVOID SearchPattern, DWORD PatternSize, LPBYTE WildCard)
{
if(dbgProcessInformation.hProcess != NULL)
{
return(FindEx(dbgProcessInformation.hProcess, MemoryStart, MemorySize, SearchPattern, PatternSize, WildCard));
}
else
{
return(FindEx(GetCurrentProcess(), MemoryStart, MemorySize, SearchPattern, PatternSize, WildCard));
}
}
__declspec(dllexport) bool TITCALL FillEx(HANDLE hProcess, LPVOID MemoryStart, DWORD MemorySize, PBYTE FillByte)
{
unsigned int i;
MEMORY_BASIC_INFORMATION MemInfo;
ULONG_PTR ueNumberOfBytesRead;
BYTE defFillByte = 0x90;
DWORD OldProtect;
if(hProcess != NULL)
{
if(FillByte == NULL)
{
FillByte = &defFillByte;
}
VirtualQueryEx(hProcess, MemoryStart, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
OldProtect = MemInfo.AllocationProtect;
VirtualProtectEx(hProcess, MemoryStart, MemorySize, PAGE_EXECUTE_READWRITE, &OldProtect);
for(i = 0; i < MemorySize; i++)
{
WriteProcessMemory(hProcess, MemoryStart, FillByte, 1, &ueNumberOfBytesRead);
MemoryStart = (LPVOID)((ULONG_PTR)MemoryStart + 1);
}
VirtualProtectEx(hProcess, MemoryStart, MemorySize, OldProtect, &OldProtect);
return(true);
}
return(false);
}
__declspec(dllexport) bool TITCALL Fill(LPVOID MemoryStart, DWORD MemorySize, PBYTE FillByte)
{
if(dbgProcessInformation.hProcess != NULL)
{
return(FillEx(dbgProcessInformation.hProcess, MemoryStart, MemorySize, FillByte));
}
else
{
return(FillEx(GetCurrentProcess(), MemoryStart, MemorySize, FillByte));
}
}
__declspec(dllexport) bool TITCALL PatchEx(HANDLE hProcess, LPVOID MemoryStart, DWORD MemorySize, LPVOID ReplacePattern, DWORD ReplaceSize, bool AppendNOP, bool PrependNOP)
{
unsigned int i,recalcSize;
LPVOID lpMemoryStart = MemoryStart;
MEMORY_BASIC_INFORMATION MemInfo;
ULONG_PTR ueNumberOfBytesRead;
BYTE FillByte = 0x90;
DWORD OldProtect;
if(hProcess != NULL)
{
VirtualQueryEx(hProcess, MemoryStart, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
OldProtect = MemInfo.AllocationProtect;
VirtualProtectEx(hProcess, MemoryStart, MemorySize, PAGE_EXECUTE_READWRITE, &OldProtect);
if(MemorySize - ReplaceSize != NULL)
{
recalcSize = abs((long)(MemorySize - ReplaceSize));
if(AppendNOP)
{
WriteProcessMemory(hProcess, MemoryStart, ReplacePattern, ReplaceSize, &ueNumberOfBytesRead);
lpMemoryStart = (LPVOID)((ULONG_PTR)MemoryStart + ReplaceSize);
for(i = 0; i < recalcSize; i++)
{
WriteProcessMemory(hProcess, lpMemoryStart, &FillByte, 1, &ueNumberOfBytesRead);
lpMemoryStart = (LPVOID)((ULONG_PTR)lpMemoryStart + 1);
}
}
else if(PrependNOP)
{
lpMemoryStart = MemoryStart;
for(i = 0; i < recalcSize; i++)
{
WriteProcessMemory(hProcess, lpMemoryStart, &FillByte, 1, &ueNumberOfBytesRead);
lpMemoryStart = (LPVOID)((ULONG_PTR)lpMemoryStart + 1);
}
WriteProcessMemory(hProcess, lpMemoryStart, ReplacePattern, ReplaceSize, &ueNumberOfBytesRead);
}
else
{
WriteProcessMemory(hProcess, MemoryStart, ReplacePattern, ReplaceSize, &ueNumberOfBytesRead);
}
}
else
{
WriteProcessMemory(hProcess, MemoryStart, ReplacePattern, ReplaceSize, &ueNumberOfBytesRead);
}
VirtualProtectEx(hProcess, MemoryStart, MemorySize, OldProtect, &OldProtect);
return(true);
}
return(false);
}
__declspec(dllexport) bool TITCALL Patch(LPVOID MemoryStart, DWORD MemorySize, LPVOID ReplacePattern, DWORD ReplaceSize, bool AppendNOP, bool PrependNOP)
{
if(dbgProcessInformation.hProcess != NULL)
{
return(PatchEx(dbgProcessInformation.hProcess, MemoryStart, MemorySize, ReplacePattern, ReplaceSize, AppendNOP, PrependNOP));
}
else
{
return(PatchEx(GetCurrentProcess(), MemoryStart, MemorySize, ReplacePattern, ReplaceSize, AppendNOP, PrependNOP));
}
}
__declspec(dllexport) bool TITCALL ReplaceEx(HANDLE hProcess, LPVOID MemoryStart, DWORD MemorySize, LPVOID SearchPattern, DWORD PatternSize, DWORD NumberOfRepetitions, LPVOID ReplacePattern, DWORD ReplaceSize, PBYTE WildCard)
{
unsigned int i;
ULONG_PTR ueNumberOfBytesRead;
ULONG_PTR CurrentFoundPattern;
LPVOID cMemoryStart = MemoryStart;
DWORD cMemorySize = MemorySize;
LPVOID lpReadMemory = VirtualAlloc(NULL, PatternSize, MEM_COMMIT, PAGE_READWRITE);
CurrentFoundPattern = (ULONG_PTR)FindEx(hProcess, cMemoryStart, cMemorySize, SearchPattern, PatternSize, WildCard);
NumberOfRepetitions--;
while(CurrentFoundPattern != NULL && NumberOfRepetitions != NULL)
{
if(ReadProcessMemory(hProcess, (LPVOID)CurrentFoundPattern, lpReadMemory, PatternSize, &ueNumberOfBytesRead))
{
for(i = 0; i < ReplaceSize; i++)
{
if(memcmp((LPVOID)((ULONG_PTR)ReplacePattern + i), WildCard, 1) != NULL)
{
RtlMoveMemory((LPVOID)((ULONG_PTR)lpReadMemory + i), (LPVOID)((ULONG_PTR)ReplacePattern + i), 1);
}
}
PatchEx(hProcess, (LPVOID)CurrentFoundPattern, PatternSize, lpReadMemory, ReplaceSize, true, false);
}
cMemoryStart = (LPVOID)(CurrentFoundPattern + PatternSize);
cMemorySize = (DWORD)((ULONG_PTR)MemoryStart + MemorySize - CurrentFoundPattern);
CurrentFoundPattern = (ULONG_PTR)FindEx(hProcess, cMemoryStart, cMemorySize, SearchPattern, PatternSize, WildCard);
NumberOfRepetitions--;
}
VirtualFree(lpReadMemory, NULL, MEM_RELEASE);
if(NumberOfRepetitions != NULL)
{
return(false);
}
else
{
return(true);
}
}
__declspec(dllexport) bool TITCALL Replace(LPVOID MemoryStart, DWORD MemorySize, LPVOID SearchPattern, DWORD PatternSize, DWORD NumberOfRepetitions, LPVOID ReplacePattern, DWORD ReplaceSize, PBYTE WildCard)
{
if(dbgProcessInformation.hProcess != NULL)
{
return(ReplaceEx(dbgProcessInformation.hProcess, MemoryStart, MemorySize, SearchPattern, PatternSize, NumberOfRepetitions, ReplacePattern, ReplaceSize, WildCard));
}
else
{
return(ReplaceEx(GetCurrentProcess(), MemoryStart, MemorySize, SearchPattern, PatternSize, NumberOfRepetitions, ReplacePattern, ReplaceSize, WildCard));
}
}
__declspec(dllexport) void* TITCALL GetDebugData()
{
return(&DBGEvent);
}
__declspec(dllexport) void* TITCALL GetTerminationData()
{
return(&TerminateDBGEvent);
}
__declspec(dllexport) long TITCALL GetExitCode()
{
return(ProcessExitCode);
}
__declspec(dllexport) long long TITCALL GetDebuggedDLLBaseAddress()
{
return((ULONG_PTR)engineDebuggingDLLBase);
}
__declspec(dllexport) unsigned long long TITCALL GetDebuggedFileBaseAddress()
{
return (unsigned long long)engineDebuggingMainModuleBase;
}
__declspec(dllexport) bool TITCALL GetRemoteString(HANDLE hProcess, LPVOID StringAddress, LPVOID StringStorage, int MaximumStringSize)
{
MEMORY_BASIC_INFORMATION MemInfo;
ULONG_PTR ueNumberOfBytesRW = NULL;
DWORD StringReadSize = NULL;
if(MaximumStringSize == NULL)
{
MaximumStringSize = 512;
}
VirtualQueryEx(hProcess, (LPVOID)StringAddress, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
if((int)((ULONG_PTR)MemInfo.BaseAddress + (ULONG_PTR)MemInfo.RegionSize - (ULONG_PTR)StringAddress) < MaximumStringSize)
{
StringReadSize = (DWORD)((ULONG_PTR)StringAddress - (ULONG_PTR)MemInfo.BaseAddress);
VirtualQueryEx(hProcess, (LPVOID)((ULONG_PTR)StringAddress + (ULONG_PTR)MemInfo.RegionSize), &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
if(MemInfo.State == MEM_COMMIT)
{
StringReadSize = MaximumStringSize;
}
}
else
{
StringReadSize = MaximumStringSize;
}
RtlZeroMemory(StringStorage, MaximumStringSize);
if(ReadProcessMemory(hProcess, (LPVOID)StringAddress, StringStorage, StringReadSize, &ueNumberOfBytesRW))
{
return(true);
}
else
{
return(false);
}
}
__declspec(dllexport) long long TITCALL GetFunctionParameter(HANDLE hProcess, DWORD FunctionType, DWORD ParameterNumber, DWORD ParameterType)
{
MEMORY_BASIC_INFORMATION MemInfo;
ULONG_PTR ueNumberOfBytesRW = NULL;
ULONG_PTR StackReadBuffer = NULL;
ULONG_PTR StackFinalBuffer = NULL;
ULONG_PTR StackReadAddress = NULL;
DWORD StackSecondReadSize = NULL;
DWORD StackReadSize = 512;
DWORD StringReadSize = 512;
bool ValueIsPointer = false;
if(ParameterType == UE_PARAMETER_BYTE)
{
StackReadSize = 1;
}
else if(ParameterType == UE_PARAMETER_WORD)
{
StackReadSize = 2;
}
else if(ParameterType == UE_PARAMETER_DWORD)
{
StackReadSize = 4;
}
else if(ParameterType == UE_PARAMETER_QWORD)
{
StackReadSize = 8;
}
else
{
if(ParameterType >= UE_PARAMETER_PTR_BYTE && ParameterType <= UE_PARAMETER_UNICODE)
{
ValueIsPointer = true;
}
if(ParameterType == UE_PARAMETER_PTR_BYTE)
{
StackSecondReadSize = 1;
}
else if(ParameterType == UE_PARAMETER_PTR_WORD)
{
StackSecondReadSize = 2;
}
else if(ParameterType == UE_PARAMETER_PTR_DWORD)
{
StackSecondReadSize = 4;
}
else if(ParameterType == UE_PARAMETER_PTR_QWORD)
{
StackSecondReadSize = 8;
}
else
{
StackSecondReadSize = 0;
}
StackReadSize = sizeof ULONG_PTR;
}
if(FunctionType >= UE_FUNCTION_STDCALL && FunctionType <= UE_FUNCTION_CCALL_CALL && FunctionType != UE_FUNCTION_FASTCALL_RET)
{
StackReadAddress = (ULONG_PTR)GetContextData(UE_CSP);
if(FunctionType != UE_FUNCTION_FASTCALL_CALL)
{
StackReadAddress = StackReadAddress + (ParameterNumber * sizeof ULONG_PTR);
if(FunctionType >= UE_FUNCTION_STDCALL_CALL)
{
StackReadAddress = StackReadAddress - sizeof ULONG_PTR;
}
}
else
{
if(ParameterNumber <= 4)
{
if(!ValueIsPointer)
{
if(ParameterNumber == 1)
{
return((ULONG_PTR)GetContextData(UE_RCX));
}
else if(ParameterNumber == 2)
{
return((ULONG_PTR)GetContextData(UE_RDX));
}
else if(ParameterNumber == 3)
{
return((ULONG_PTR)GetContextData(UE_R8));
}
else if(ParameterNumber == 4)
{
return((ULONG_PTR)GetContextData(UE_R9));
}
}
else
{
if(ParameterNumber == 1)
{
StackReadAddress = (ULONG_PTR)GetContextData(UE_RCX);
}
else if(ParameterNumber == 2)
{
StackReadAddress = (ULONG_PTR)GetContextData(UE_RDX);
}
else if(ParameterNumber == 3)
{
StackReadAddress = (ULONG_PTR)GetContextData(UE_R8);
}
else if(ParameterNumber == 4)
{
StackReadAddress = (ULONG_PTR)GetContextData(UE_R9);
}
}
}
else
{
StackReadAddress = StackReadAddress + 0x20 + ((ParameterNumber - 4) * sizeof ULONG_PTR) - sizeof ULONG_PTR;
}
}
if(ReadProcessMemory(hProcess, (LPVOID)StackReadAddress, &StackReadBuffer, sizeof ULONG_PTR, &ueNumberOfBytesRW))
{
if(!ValueIsPointer)
{
RtlMoveMemory((LPVOID)((ULONG_PTR)&StackFinalBuffer + sizeof ULONG_PTR - StackReadSize), (LPVOID)((ULONG_PTR)&StackReadBuffer + sizeof ULONG_PTR - StackReadSize), StackReadSize);
}
else
{
StackReadAddress = StackReadBuffer;
if(StackSecondReadSize > NULL)
{
if(ReadProcessMemory(hProcess, (LPVOID)StackReadAddress, &StackReadBuffer, sizeof ULONG_PTR, &ueNumberOfBytesRW))
{
RtlMoveMemory((LPVOID)((ULONG_PTR)&StackFinalBuffer + sizeof ULONG_PTR - StackSecondReadSize), (LPVOID)((ULONG_PTR)&StackReadBuffer + sizeof ULONG_PTR - StackSecondReadSize), StackSecondReadSize);
}
else
{
return(-1);
}
}
else
{
VirtualQueryEx(hProcess, (LPVOID)StackReadAddress, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
if((ULONG_PTR)MemInfo.BaseAddress + (ULONG_PTR)MemInfo.RegionSize - StackReadAddress < 512)
{
StringReadSize = (DWORD)((ULONG_PTR)StackReadAddress - (ULONG_PTR)MemInfo.BaseAddress);
VirtualQueryEx(hProcess, (LPVOID)(StackReadAddress + (ULONG_PTR)MemInfo.RegionSize), &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
if(MemInfo.State == MEM_COMMIT)
{
StringReadSize = 512;
}
}
RtlZeroMemory(&szParameterString, 512);
if(ReadProcessMemory(hProcess, (LPVOID)StackReadAddress, &szParameterString, StringReadSize, &ueNumberOfBytesRW))
{
return((ULONG_PTR)&szParameterString);
}
else
{
return(-1);
}
}
}
return(StackFinalBuffer);
}
else
{
return(-1);
}
}
return(-1);
}
__declspec(dllexport) long long TITCALL GetJumpDestinationEx(HANDLE hProcess, ULONG_PTR InstructionAddress, bool JustJumps)
{
LPVOID ReadMemory;
MEMORY_BASIC_INFORMATION MemInfo;
ULONG_PTR ueNumberOfBytesRead = NULL;
PMEMORY_CMP_HANDLER CompareMemory;
ULONG_PTR TargetedAddress = NULL;
DWORD CurrentInstructionSize;
int ReadMemData = NULL;
BYTE ReadByteData = NULL;
if(hProcess != NULL)
{
VirtualQueryEx(hProcess, (LPVOID)InstructionAddress, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
if(MemInfo.RegionSize > NULL)
{
ReadMemory = VirtualAlloc(NULL, MAXIMUM_INSTRUCTION_SIZE, MEM_COMMIT, PAGE_READWRITE);
if(!ReadMemory)
return 0;
if(ReadProcessMemory(hProcess, (LPVOID)InstructionAddress, ReadMemory, MAXIMUM_INSTRUCTION_SIZE, &ueNumberOfBytesRead))
{
CompareMemory = (PMEMORY_CMP_HANDLER)ReadMemory;
CurrentInstructionSize = StaticLengthDisassemble(ReadMemory);
if(CompareMemory->DataByte[0] == 0xE9 && CurrentInstructionSize == 5)
{
RtlMoveMemory(&ReadMemData, (LPVOID)((ULONG_PTR)ReadMemory + 1), 4);
TargetedAddress = ReadMemData + InstructionAddress + CurrentInstructionSize;
}
else if(CompareMemory->DataByte[0] == 0xEB && CurrentInstructionSize == 2)
{
RtlMoveMemory(&ReadByteData, (LPVOID)((ULONG_PTR)ReadMemory + 1), 1);
if(ReadByteData > 0x7F)
{
ReadByteData = 0xFF - ReadByteData;
ReadMemData = NULL - ReadByteData - CurrentInstructionSize + 1;
}
else
{
ReadMemData = ReadByteData;
}
TargetedAddress = InstructionAddress + ReadMemData + CurrentInstructionSize;
}
else if(CompareMemory->DataByte[0] == 0xE3 && CurrentInstructionSize == 2)
{
RtlMoveMemory(&ReadByteData, (LPVOID)((ULONG_PTR)ReadMemory + 1), 1);
if(ReadByteData > 0x7F)
{
ReadByteData = 0xFF - ReadByteData;
ReadMemData = NULL - ReadByteData - CurrentInstructionSize + 1;
}
else
{
ReadMemData = ReadByteData;
}
TargetedAddress = InstructionAddress + ReadMemData + CurrentInstructionSize;
}
else if(CompareMemory->DataByte[0] >= 0x71 && CompareMemory->DataByte[0] <= 0x7F && CurrentInstructionSize == 2)
{
RtlMoveMemory(&ReadByteData, (LPVOID)((ULONG_PTR)ReadMemory + 1), 1);
if(ReadByteData > 0x7F)
{
ReadByteData = 0xFF - ReadByteData;
ReadMemData = NULL - ReadByteData - CurrentInstructionSize + 1;
}
TargetedAddress = InstructionAddress + ReadMemData + CurrentInstructionSize;
}
else if(CompareMemory->DataByte[0] >= 0xE0 && CompareMemory->DataByte[0] <= 0xE2 && CurrentInstructionSize == 2)
{
RtlMoveMemory(&ReadByteData, (LPVOID)((ULONG_PTR)ReadMemory + 1), 1);
if(ReadByteData > 0x7F)
{
ReadByteData = 0xFF - ReadByteData;
ReadMemData = NULL - ReadByteData - CurrentInstructionSize + 1;
}
else
{
ReadMemData = ReadByteData;
}
TargetedAddress = InstructionAddress + ReadMemData + CurrentInstructionSize;
}
else if(CompareMemory->DataByte[0] == 0x0F && CompareMemory->DataByte[1] >= 0x81 && CompareMemory->DataByte[1] <= 0x8F && CurrentInstructionSize == 6)
{
RtlMoveMemory(&ReadMemData, (LPVOID)((ULONG_PTR)ReadMemory + 2), 4);
TargetedAddress = ReadMemData + InstructionAddress + CurrentInstructionSize;
}
else if(CompareMemory->DataByte[0] == 0x0F && CompareMemory->DataByte[1] >= 0x81 && CompareMemory->DataByte[1] <= 0x8F && CurrentInstructionSize == 4)
{
RtlMoveMemory(&ReadMemData, (LPVOID)((ULONG_PTR)ReadMemory + 2), 2);
TargetedAddress = ReadMemData + InstructionAddress + CurrentInstructionSize;
}
else if(CompareMemory->DataByte[0] == 0xE8 && CurrentInstructionSize == 5 && JustJumps == false)
{
RtlMoveMemory(&ReadMemData, (LPVOID)((ULONG_PTR)ReadMemory + 1), 4);
TargetedAddress = ReadMemData + InstructionAddress + CurrentInstructionSize;
}
else if(CompareMemory->DataByte[0] == 0xFF && CompareMemory->DataByte[1] == 0x25 && CurrentInstructionSize == 6)
{
RtlMoveMemory(&ReadMemData, (LPVOID)((ULONG_PTR)ReadMemory + 2), 4);
TargetedAddress = ReadMemData;
if(sizeof HANDLE == 8)
{
TargetedAddress = TargetedAddress + InstructionAddress;
}
}
else if(CompareMemory->DataByte[0] == 0xFF && CompareMemory->DataByte[1] == 0x15 && CurrentInstructionSize == 6 && JustJumps == false)
{
RtlMoveMemory(&ReadMemData, (LPVOID)((ULONG_PTR)ReadMemory + 2), 4);
TargetedAddress = ReadMemData;
if(sizeof HANDLE == 8)
{
TargetedAddress = TargetedAddress + InstructionAddress;
}
}
else if(CompareMemory->DataByte[0] == 0xFF && CompareMemory->DataByte[1] != 0x64 && CompareMemory->DataByte[1] >= 0x60 && CompareMemory->DataByte[1] <= 0x67 && CurrentInstructionSize == 3)
{
RtlMoveMemory(&ReadMemData, (LPVOID)((ULONG_PTR)ReadMemory + 2), 1);
TargetedAddress = ReadMemData;
if(CompareMemory->DataByte[1] == 0x60)
{
TargetedAddress = TargetedAddress + (ULONG_PTR)GetContextData(UE_EAX);
}
else if(CompareMemory->DataByte[1] == 0x61)
{
TargetedAddress = TargetedAddress + (ULONG_PTR)GetContextData(UE_ECX);
}
else if(CompareMemory->DataByte[1] == 0x62)
{
TargetedAddress = TargetedAddress + (ULONG_PTR)GetContextData(UE_EDX);
}
else if(CompareMemory->DataByte[1] == 0x63)
{
TargetedAddress = TargetedAddress + (ULONG_PTR)GetContextData(UE_EBX);
}
else if(CompareMemory->DataByte[1] == 0x65)
{
TargetedAddress = TargetedAddress + (ULONG_PTR)GetContextData(UE_EBP);
}
else if(CompareMemory->DataByte[1] == 0x66)
{
TargetedAddress = TargetedAddress + (ULONG_PTR)GetContextData(UE_ESI);
}
else if(CompareMemory->DataByte[1] == 0x67)
{
TargetedAddress = TargetedAddress + (ULONG_PTR)GetContextData(UE_EDI);
}
ReadProcessMemory(hProcess, (LPVOID)TargetedAddress, &TargetedAddress, 4, &ueNumberOfBytesRead);
}
}
VirtualFree(ReadMemory, NULL, MEM_RELEASE);
return((ULONG_PTR)TargetedAddress);
}
return(NULL);
}
else
{
CompareMemory = (PMEMORY_CMP_HANDLER)InstructionAddress;
CurrentInstructionSize = StaticLengthDisassemble((LPVOID)InstructionAddress);
if(CompareMemory->DataByte[0] == 0xE9 && CurrentInstructionSize == 5)
{
RtlMoveMemory(&ReadMemData, (LPVOID)((ULONG_PTR)InstructionAddress + 1), 4);
TargetedAddress = ReadMemData + InstructionAddress + CurrentInstructionSize;
}
else if(CompareMemory->DataByte[0] == 0xEB && CurrentInstructionSize == 2)
{
RtlMoveMemory(&ReadByteData, (LPVOID)((ULONG_PTR)InstructionAddress + 1), 1);
if(ReadByteData > 0x7F)
{
ReadByteData = 0xFF - ReadByteData;
ReadMemData = NULL - ReadByteData - CurrentInstructionSize + 1;
}
else
{
ReadMemData = ReadByteData;
}
TargetedAddress = InstructionAddress + ReadMemData + CurrentInstructionSize;
}
else if(CompareMemory->DataByte[0] == 0xE3 && CurrentInstructionSize == 2)
{
RtlMoveMemory(&ReadByteData, (LPVOID)((ULONG_PTR)InstructionAddress + 1), 1);
if(ReadByteData > 0x7F)
{
ReadByteData = 0xFF - ReadByteData;
ReadMemData = NULL - ReadByteData - CurrentInstructionSize + 1;
}
else
{
ReadMemData = ReadByteData;
}
TargetedAddress = InstructionAddress + ReadMemData + CurrentInstructionSize;
}
else if(CompareMemory->DataByte[0] >= 0x71 && CompareMemory->DataByte[0] <= 0x7F && CurrentInstructionSize == 2)
{
RtlMoveMemory(&ReadByteData, (LPVOID)((ULONG_PTR)InstructionAddress + 1), 1);
if(ReadByteData > 0x7F)
{
ReadByteData = 0xFF - ReadByteData;
ReadMemData = NULL - ReadByteData - CurrentInstructionSize + 1;
}
TargetedAddress = InstructionAddress + ReadMemData + CurrentInstructionSize;
}
else if(CompareMemory->DataByte[0] >= 0xE0 && CompareMemory->DataByte[0] <= 0xE2 && CurrentInstructionSize == 2)
{
RtlMoveMemory(&ReadByteData, (LPVOID)((ULONG_PTR)InstructionAddress + 1), 1);
if(ReadByteData > 0x7F)
{
ReadByteData = 0xFF - ReadByteData;
ReadMemData = NULL - ReadByteData - CurrentInstructionSize + 1;
}
else
{
ReadMemData = ReadByteData;
}
TargetedAddress = InstructionAddress + ReadMemData + CurrentInstructionSize;
}
else if(CompareMemory->DataByte[0] == 0x0F && CompareMemory->DataByte[1] >= 0x81 && CompareMemory->DataByte[1] <= 0x8F && CurrentInstructionSize == 6)
{
RtlMoveMemory(&ReadMemData, (LPVOID)((ULONG_PTR)InstructionAddress + 2), 4);
TargetedAddress = ReadMemData + InstructionAddress + CurrentInstructionSize;
}
else if(CompareMemory->DataByte[0] == 0x0F && CompareMemory->DataByte[1] >= 0x81 && CompareMemory->DataByte[1] <= 0x8F && CurrentInstructionSize == 4)
{
RtlMoveMemory(&ReadMemData, (LPVOID)((ULONG_PTR)InstructionAddress + 2), 2);
TargetedAddress = ReadMemData + InstructionAddress + CurrentInstructionSize;
}
else if(CompareMemory->DataByte[0] == 0xE8 && CurrentInstructionSize == 5 && JustJumps == false)
{
RtlMoveMemory(&ReadMemData, (LPVOID)((ULONG_PTR)InstructionAddress + 1), 4);
TargetedAddress = ReadMemData + InstructionAddress + CurrentInstructionSize;
}
else if(CompareMemory->DataByte[0] == 0xFF && CompareMemory->DataByte[1] == 0x25 && CurrentInstructionSize == 6)
{
RtlMoveMemory(&ReadMemData, (LPVOID)((ULONG_PTR)InstructionAddress + 2), 4);
TargetedAddress = ReadMemData;
if(sizeof HANDLE == 8)
{
TargetedAddress = TargetedAddress + InstructionAddress;
}
}
else if(CompareMemory->DataByte[0] == 0xFF && CompareMemory->DataByte[1] == 0x15 && CurrentInstructionSize == 6 && JustJumps == false)
{
RtlMoveMemory(&ReadMemData, (LPVOID)((ULONG_PTR)InstructionAddress + 2), 4);
TargetedAddress = ReadMemData;
if(sizeof HANDLE == 8)
{
TargetedAddress = TargetedAddress + InstructionAddress;
}
}
else if(CompareMemory->DataByte[0] == 0xFF && CompareMemory->DataByte[1] != 0x64 && CompareMemory->DataByte[1] >= 0x60 && CompareMemory->DataByte[1] <= 0x67 && CurrentInstructionSize == 3)
{
RtlMoveMemory(&ReadMemData, (LPVOID)((ULONG_PTR)InstructionAddress + 2), 1);
TargetedAddress = ReadMemData;
if(CompareMemory->DataByte[1] == 0x60)
{
TargetedAddress = TargetedAddress + (ULONG_PTR)GetContextData(UE_EAX);
}
else if(CompareMemory->DataByte[1] == 0x61)
{
TargetedAddress = TargetedAddress + (ULONG_PTR)GetContextData(UE_ECX);
}
else if(CompareMemory->DataByte[1] == 0x62)
{
TargetedAddress = TargetedAddress + (ULONG_PTR)GetContextData(UE_EDX);
}
else if(CompareMemory->DataByte[1] == 0x63)
{
TargetedAddress = TargetedAddress + (ULONG_PTR)GetContextData(UE_EBX);
}
else if(CompareMemory->DataByte[1] == 0x65)
{
TargetedAddress = TargetedAddress + (ULONG_PTR)GetContextData(UE_EBP);
}
else if(CompareMemory->DataByte[1] == 0x66)
{
TargetedAddress = TargetedAddress + (ULONG_PTR)GetContextData(UE_ESI);
}
else if(CompareMemory->DataByte[1] == 0x67)
{
TargetedAddress = TargetedAddress + (ULONG_PTR)GetContextData(UE_EDI);
}
RtlMoveMemory(&TargetedAddress, (LPVOID)((ULONG_PTR)TargetedAddress), 4);
}
return((ULONG_PTR)TargetedAddress);
}
return(NULL);
}
__declspec(dllexport) long long TITCALL GetJumpDestination(HANDLE hProcess, ULONG_PTR InstructionAddress)
{
return((ULONG_PTR)GetJumpDestinationEx(hProcess, InstructionAddress, false));
}
__declspec(dllexport) bool TITCALL IsJumpGoingToExecuteEx(HANDLE hProcess, HANDLE hThread, ULONG_PTR InstructionAddress, ULONG_PTR RegFlags)
{
ULONG_PTR ThreadCIP = NULL;
DWORD ThreadEflags = NULL;
char* DisassembledString;
bool bCF = false;
bool bPF = false;
bool bAF = false;
bool bZF = false;
bool bSF = false;
bool bTF = false;
bool bIF = false;
bool bDF = false;
bool bOF = false;
if(hProcess != NULL && (hThread || RegFlags))
{
if(InstructionAddress == NULL)
{
ThreadCIP = (ULONG_PTR)GetContextDataEx(hThread, UE_CIP);
}
else
{
ThreadCIP = InstructionAddress;
}
if(RegFlags == NULL)
{
ThreadEflags = (DWORD)GetContextDataEx(hThread, UE_EFLAGS);
}
else
{
ThreadEflags = (DWORD)RegFlags;
}
DisassembledString = (char*)DisassembleEx(hProcess, (LPVOID)ThreadCIP, true);
if(DisassembledString != NULL)
{
if(ThreadEflags & (1 << 0))
{
bCF = true;
}
if(ThreadEflags & (1 << 2))
{
bPF = true;
}
if(ThreadEflags & (1 << 4))
{
bAF = true;
}
if(ThreadEflags & (1 << 6))
{
bZF = true;
}
if(ThreadEflags & (1 << 7))
{
bSF = true;
}
if(ThreadEflags & (1 << 8))
{
bTF = true;
}
if(ThreadEflags & (1 << 9))
{
bIF = true;
}
if(ThreadEflags & (1 << 10))
{
bDF = true;
}
if(ThreadEflags & (1 << 11))
{
bOF = true;
}
if(lstrcmpiA(DisassembledString, "RET") == NULL)
{
return (true);
}
else if(lstrcmpiA(DisassembledString, "RETF") == NULL)
{
return (true);
}
else if(lstrcmpiA(DisassembledString, "JMP") == NULL)
{
return(true);
}
else if(lstrcmpiA(DisassembledString, "JA") == NULL)
{
if(bCF == false && bZF == false)
{
return(true);
}
}
else if(lstrcmpiA(DisassembledString, "JAE") == NULL)
{
if(!bCF)
{
return(true);
}
}
else if(lstrcmpiA(DisassembledString, "JB") == NULL)
{
if(bCF)
{
return(true);
}
}
else if(lstrcmpiA(DisassembledString, "JBE") == NULL)
{
if(bCF == true || bZF == true)
{
return(true);
}
}
else if(lstrcmpiA(DisassembledString, "JC") == NULL)
{
if(bCF)
{
return(true);
}
}
else if(lstrcmpiA(DisassembledString, "JCXZ") == NULL)
{
if((WORD)GetContextDataEx(hThread, UE_ECX) == NULL)
{
return(true);
}
}
else if(lstrcmpiA(DisassembledString, "JECXZ") == NULL)
{
if((DWORD)GetContextDataEx(hThread, UE_ECX) == NULL)
{
return(true);
}
}
else if(lstrcmpiA(DisassembledString, "JRCXZ") == NULL)
{
if((ULONG_PTR)GetContextDataEx(hThread, UE_RCX) == NULL)
{
return(true);
}
}
else if(lstrcmpiA(DisassembledString, "JZ") == NULL)
{
if(bZF)
{
return(true);
}
}
else if(lstrcmpiA(DisassembledString, "JNZ") == NULL)
{
if(!bZF)
{
return(true);
}
}
else if(lstrcmpiA(DisassembledString, "JE") == NULL)
{
if(bZF)
{
return(true);
}
}
else if(lstrcmpiA(DisassembledString, "JNE") == NULL)
{
if(!bZF)
{
return(true);
}
}
else if(lstrcmpiA(DisassembledString, "JG") == NULL)
{
if(bZF == false && bSF == bOF)
{
return(true);
}
}
else if(lstrcmpiA(DisassembledString, "JGE") == NULL)
{
if(bSF == bOF)
{
return(true);
}
}
else if(lstrcmpiA(DisassembledString, "JL") == NULL)
{
if(bSF != bOF)
{
return(true);
}
}
else if(lstrcmpiA(DisassembledString, "JLE") == NULL)
{
if(bZF == true || bSF != bOF)
{
return(true);
}
}
else if(lstrcmpiA(DisassembledString, "JNA") == NULL)
{
if(bCF == true || bZF == true)
{
return(true);
}
}
else if(lstrcmpiA(DisassembledString, "JNAE") == NULL)
{
if(bCF)
{
return(true);
}
}
else if(lstrcmpiA(DisassembledString, "JNB") == NULL)
{
if(!bCF)
{
return(true);
}
}
else if(lstrcmpiA(DisassembledString, "JNBE") == NULL)
{
if(bCF == false && bZF == false)
{
return(true);
}
}
else if(lstrcmpiA(DisassembledString, "JNC") == NULL)
{
if(!bCF)
{
return(true);
}
}
else if(lstrcmpiA(DisassembledString, "JNG") == NULL)
{
if(bZF == true || bSF != bOF)
{
return(true);
}
}
else if(lstrcmpiA(DisassembledString, "JNGE") == NULL)
{
if(bSF != bOF)
{
return(true);
}
}
else if(lstrcmpiA(DisassembledString, "JNL") == NULL)
{
if(bSF == bOF)
{
return(true);
}
}
else if(lstrcmpiA(DisassembledString, "JNLE") == NULL)
{
if(bZF == false && bSF == bOF)
{
return(true);
}
}
else if(lstrcmpiA(DisassembledString, "JNO") == NULL)
{
if(!bOF)
{
return(true);
}
}
else if(lstrcmpiA(DisassembledString, "JNP") == NULL)
{
if(!bPF)
{
return(true);
}
}
else if(lstrcmpiA(DisassembledString, "JNS") == NULL)
{
if(!bSF)
{
return(true);
}
}
else if(lstrcmpiA(DisassembledString, "JO") == NULL)
{
if(bOF)
{
return(true);
}
}
else if(lstrcmpiA(DisassembledString, "JP") == NULL)
{
if(bPF)
{
return(true);
}
}
else if(lstrcmpiA(DisassembledString, "JPE") == NULL)
{
if(bPF)
{
return(true);
}
}
else if(lstrcmpiA(DisassembledString, "JPO") == NULL)
{
if(!bPF)
{
return(true);
}
}
else if(lstrcmpiA(DisassembledString, "JS") == NULL)
{
if(bSF)
{
return(true);
}
}
}
}
return(false);
}
__declspec(dllexport) bool TITCALL IsJumpGoingToExecute()
{
return(IsJumpGoingToExecuteEx(dbgProcessInformation.hProcess, dbgProcessInformation.hThread, NULL, NULL));
}
__declspec(dllexport) void TITCALL SetCustomHandler(DWORD ExceptionId, LPVOID CallBack)
{
if(ExceptionId == UE_CH_BREAKPOINT)
{
DBGCustomHandler->chBreakPoint = (ULONG_PTR)CallBack;
}
else if(ExceptionId == UE_CH_SINGLESTEP)
{
DBGCustomHandler->chSingleStep = (ULONG_PTR)CallBack;
}
else if(ExceptionId == UE_CH_ACCESSVIOLATION)
{
DBGCustomHandler->chAccessViolation = (ULONG_PTR)CallBack;
}
else if(ExceptionId == UE_CH_ILLEGALINSTRUCTION)
{
DBGCustomHandler->chIllegalInstruction = (ULONG_PTR)CallBack;
}
else if(ExceptionId == UE_CH_NONCONTINUABLEEXCEPTION)
{
DBGCustomHandler->chNonContinuableException = (ULONG_PTR)CallBack;
}
else if(ExceptionId == UE_CH_ARRAYBOUNDSEXCEPTION)
{
DBGCustomHandler->chArrayBoundsException = (ULONG_PTR)CallBack;
}
else if(ExceptionId == UE_CH_FLOATDENORMALOPERAND)
{
DBGCustomHandler->chFloatDenormalOperand = (ULONG_PTR)CallBack;
}
else if(ExceptionId == UE_CH_FLOATDEVIDEBYZERO)
{
DBGCustomHandler->chFloatDevideByZero = (ULONG_PTR)CallBack;
}
else if(ExceptionId == UE_CH_INTEGERDEVIDEBYZERO)
{
DBGCustomHandler->chIntegerDevideByZero = (ULONG_PTR)CallBack;
}
else if(ExceptionId == UE_CH_INTEGEROVERFLOW)
{
DBGCustomHandler->chIntegerOverflow = (ULONG_PTR)CallBack;
}
else if(ExceptionId == UE_CH_PRIVILEGEDINSTRUCTION)
{
DBGCustomHandler->chPrivilegedInstruction = (ULONG_PTR)CallBack;
}
else if(ExceptionId == UE_CH_PAGEGUARD)
{
DBGCustomHandler->chPageGuard = (ULONG_PTR)CallBack;
}
else if(ExceptionId == UE_CH_EVERYTHINGELSE)
{
DBGCustomHandler->chEverythingElse = (ULONG_PTR)CallBack;
}
else if(ExceptionId == UE_CH_CREATETHREAD)
{
DBGCustomHandler->chCreateThread = (ULONG_PTR)CallBack;
}
else if(ExceptionId == UE_CH_EXITTHREAD)
{
DBGCustomHandler->chExitThread = (ULONG_PTR)CallBack;
}
else if(ExceptionId == UE_CH_CREATEPROCESS)
{
DBGCustomHandler->chCreateProcess = (ULONG_PTR)CallBack;
}
else if(ExceptionId == UE_CH_EXITPROCESS)
{
DBGCustomHandler->chExitProcess = (ULONG_PTR)CallBack;
}
else if(ExceptionId == UE_CH_LOADDLL)
{
DBGCustomHandler->chLoadDll = (ULONG_PTR)CallBack;
}
else if(ExceptionId == UE_CH_UNLOADDLL)
{
DBGCustomHandler->chUnloadDll = (ULONG_PTR)CallBack;
}
else if(ExceptionId == UE_CH_OUTPUTDEBUGSTRING)
{
DBGCustomHandler->chOutputDebugString = (ULONG_PTR)CallBack;
}
else if(ExceptionId == UE_CH_AFTEREXCEPTIONPROCESSING)
{
DBGCustomHandler->chAfterException = (ULONG_PTR)CallBack;
}
else if(ExceptionId == UE_CH_SYSTEMBREAKPOINT)
{
DBGCustomHandler->chSystemBreakpoint = (ULONG_PTR)CallBack;
}
else if(ExceptionId == UE_CH_UNHANDLEDEXCEPTION)
{
DBGCustomHandler->chUnhandledException = (ULONG_PTR)CallBack;
}
else if(ExceptionId == UE_CH_ALLEVENTS)
{
DBGCustomHandler->chEverythingElse = (ULONG_PTR)CallBack;
DBGCustomHandler->chCreateThread = (ULONG_PTR)CallBack;
DBGCustomHandler->chExitThread = (ULONG_PTR)CallBack;
DBGCustomHandler->chCreateProcess = (ULONG_PTR)CallBack;
DBGCustomHandler->chExitProcess = (ULONG_PTR)CallBack;
DBGCustomHandler->chLoadDll = (ULONG_PTR)CallBack;
DBGCustomHandler->chUnloadDll = (ULONG_PTR)CallBack;
DBGCustomHandler->chOutputDebugString = (ULONG_PTR)CallBack;
DBGCustomHandler->chSystemBreakpoint = (ULONG_PTR)CallBack;
}
}
__declspec(dllexport) void TITCALL ForceClose()
{
/*wchar_t szTempName[MAX_PATH];
wchar_t szTempFolder[MAX_PATH];*/
PPROCESS_ITEM_DATA hListProcessPtr = NULL;
PTHREAD_ITEM_DATA hListThreadPtr = NULL;
PLIBRARY_ITEM_DATAW hListLibraryPtr = NULL;
if(hListProcess != NULL)
{
hListProcessPtr = (PPROCESS_ITEM_DATA)hListProcess;
while(hListProcessPtr->hProcess != NULL)
{
__try
{
EngineCloseHandle(hListProcessPtr->hFile);
EngineCloseHandle(hListProcessPtr->hProcess);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
hListProcessPtr = (PPROCESS_ITEM_DATA)((ULONG_PTR)hListProcessPtr + sizeof PROCESS_ITEM_DATA);
}
RtlZeroMemory(hListProcess, MAX_DEBUG_DATA * sizeof PROCESS_ITEM_DATA);
}
if(hListThread != NULL)
{
hListThreadPtr = (PTHREAD_ITEM_DATA)hListThread;
while(hListThreadPtr->hThread != NULL)
{
if(hListThreadPtr->hThread != (HANDLE)-1)
{
__try
{
if(EngineCloseHandle(hListThreadPtr->hThread))
{
hListThreadPtr->hThread = NULL;
hListThreadPtr->dwThreadId = NULL;
hListThreadPtr->ThreadLocalBase = NULL;
hListThreadPtr->ThreadStartAddress = NULL;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hListThreadPtr->hThread = NULL;
hListThreadPtr->dwThreadId = NULL;
hListThreadPtr->ThreadLocalBase = NULL;
hListThreadPtr->ThreadStartAddress = NULL;
}
}
hListThreadPtr = (PTHREAD_ITEM_DATA)((ULONG_PTR)hListThreadPtr + sizeof THREAD_ITEM_DATA);
}
RtlZeroMemory(hListThread, MAX_DEBUG_DATA * sizeof THREAD_ITEM_DATA);
}
if(hListLibrary != NULL)
{
hListLibraryPtr = (PLIBRARY_ITEM_DATAW)hListLibrary;
while(hListLibraryPtr->hFile != NULL)
{
if(hListLibraryPtr->hFile != (HANDLE)-1)
{
if(hListLibraryPtr->hFileMappingView != NULL)
{
UnmapViewOfFile(hListLibraryPtr->hFileMappingView);
__try
{
EngineCloseHandle(hListLibraryPtr->hFileMapping);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
}
__try
{
EngineCloseHandle(hListLibraryPtr->hFile);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
}
hListLibraryPtr = (PLIBRARY_ITEM_DATAW)((ULONG_PTR)hListLibraryPtr + sizeof LIBRARY_ITEM_DATAW);
}
RtlZeroMemory(hListLibrary, MAX_DEBUG_DATA * sizeof LIBRARY_ITEM_DATAW);
}
if(!engineProcessIsNowDetached)
{
StopDebug();
}
RtlZeroMemory(&dbgProcessInformation, sizeof PROCESS_INFORMATION);
/*if(engineDebuggingDLL)
{
RtlZeroMemory(&szTempName, sizeof szTempName);
RtlZeroMemory(&szTempFolder, sizeof szTempFolder);
if(GetTempPathW(MAX_PATH, szTempFolder) < MAX_PATH)
{
if(GetTempFileNameW(szTempFolder, L"DeleteTempFile", GetTickCount(), szTempName))
{
DeleteFileW(szTempName);
if(!MoveFileW(szDebuggerName, szTempName))
{
DeleteFileW(szDebuggerName);
}
else
{
DeleteFileW(szTempName);
}
}
RtlZeroMemory(&szTempName, sizeof szTempName);
if(GetTempFileNameW(szTempFolder, L"DeleteTempFile", GetTickCount() + 1, szTempName))
{
DeleteFileW(szTempName);
if(!MoveFileW(szReserveModuleName, szTempName))
{
DeleteFileW(szReserveModuleName);
}
else
{
DeleteFileW(szTempName);
}
}
}
}*/
engineDebuggingDLL = false;
DebugExeFileEntryPointCallBack = NULL;
}
__declspec(dllexport) void TITCALL StepInto(LPVOID StepCallBack)
{
ULONG_PTR ueContext = NULL;
ueContext = (ULONG_PTR)GetContextData(UE_EFLAGS);
if(!(ueContext & 0x100))
{
ueContext = ueContext ^ 0x100;
}
SetContextData(UE_EFLAGS, ueContext);
engineStepActive = true;
engineStepCallBack = StepCallBack;
engineStepCount = NULL;
}
__declspec(dllexport) void TITCALL StepOver(LPVOID StepCallBack)
{
ULONG_PTR ueCurrentPosition = NULL;
#if !defined(_WIN64)
ueCurrentPosition = (ULONG_PTR)GetContextData(UE_EIP);
#else
ueCurrentPosition = GetContextData(UE_RIP);
#endif
unsigned char instr[16];
ReadProcessMemory(dbgProcessInformation.hProcess, (void*)ueCurrentPosition, instr, sizeof(instr), 0);
char* DisassembledString=(char*)StaticDisassembleEx(ueCurrentPosition, (LPVOID)instr);
if(strstr(DisassembledString, "CALL")||strstr(DisassembledString, "REP")||strstr(DisassembledString, "PUSHF"))
{
ueCurrentPosition+=StaticLengthDisassemble((void*)instr);
SetBPX(ueCurrentPosition, UE_BREAKPOINT_TYPE_INT3+UE_SINGLESHOOT, StepCallBack);
}
else
StepInto(StepCallBack);
}
__declspec(dllexport) void TITCALL SingleStep(DWORD StepCount, LPVOID StepCallBack)
{
ULONG_PTR ueContext = NULL;
ueContext = (ULONG_PTR)GetContextData(UE_EFLAGS);
if(!(ueContext & 0x100))
{
ueContext = ueContext ^ 0x100;
}
SetContextData(UE_EFLAGS, ueContext);
engineStepActive = true;
engineStepCount = (int)StepCount;
engineStepCallBack = StepCallBack;
engineStepCount--;
}
__declspec(dllexport) bool TITCALL GetUnusedHardwareBreakPointRegister(LPDWORD RegisterIndex)
{
return(EngineIsThereFreeHardwareBreakSlot(RegisterIndex));
}
static ULONG_PTR dr7uint(DR7* dr7)
{
ULONG_PTR ret=0;
if(BITGET(dr7->HWBP_MODE[0],0))
BITSET(ret,0);
if(BITGET(dr7->HWBP_MODE[0],1))
BITSET(ret,1);
if(BITGET(dr7->HWBP_MODE[1],0))
BITSET(ret,2);
if(BITGET(dr7->HWBP_MODE[1],1))
BITSET(ret,3);
if(BITGET(dr7->HWBP_MODE[2],0))
BITSET(ret,4);
if(BITGET(dr7->HWBP_MODE[2],1))
BITSET(ret,5);
if(BITGET(dr7->HWBP_MODE[3],0))
BITSET(ret,6);
if(BITGET(dr7->HWBP_MODE[3],1))
BITSET(ret,7);
if(BITGET(dr7->HWBP_TYPE[0],0))
BITSET(ret,16);
if(BITGET(dr7->HWBP_TYPE[0],1))
BITSET(ret,17);
if(BITGET(dr7->HWBP_SIZE[0],0))
BITSET(ret,18);
if(BITGET(dr7->HWBP_SIZE[0],1))
BITSET(ret,19);
if(BITGET(dr7->HWBP_TYPE[1],0))
BITSET(ret,20);
if(BITGET(dr7->HWBP_TYPE[1],1))
BITSET(ret,21);
if(BITGET(dr7->HWBP_SIZE[1],0))
BITSET(ret,22);
if(BITGET(dr7->HWBP_SIZE[1],1))
BITSET(ret,23);
if(BITGET(dr7->HWBP_TYPE[2],0))
BITSET(ret,24);
if(BITGET(dr7->HWBP_TYPE[2],1))
BITSET(ret,25);
if(BITGET(dr7->HWBP_SIZE[2],0))
BITSET(ret,26);
if(BITGET(dr7->HWBP_SIZE[2],1))
BITSET(ret,27);
if(BITGET(dr7->HWBP_TYPE[3],0))
BITSET(ret,28);
if(BITGET(dr7->HWBP_TYPE[3],1))
BITSET(ret,29);
if(BITGET(dr7->HWBP_SIZE[3],0))
BITSET(ret,30);
if(BITGET(dr7->HWBP_SIZE[3],1))
BITSET(ret,31);
return ret;
}
static void uintdr7(ULONG_PTR dr7, DR7* ret)
{
memset(ret, 0, sizeof(DR7));
if(BITGET(dr7,0))
BITSET(ret->HWBP_MODE[0],0);
if(BITGET(dr7,1))
BITSET(ret->HWBP_MODE[0],1);
if(BITGET(dr7,2))
BITSET(ret->HWBP_MODE[1],0);
if(BITGET(dr7,3))
BITSET(ret->HWBP_MODE[1],1);
if(BITGET(dr7,4))
BITSET(ret->HWBP_MODE[2],0);
if(BITGET(dr7,5))
BITSET(ret->HWBP_MODE[2],1);
if(BITGET(dr7,6))
BITSET(ret->HWBP_MODE[3],0);
if(BITGET(dr7,7))
BITSET(ret->HWBP_MODE[3],1);
if(BITGET(dr7,16))
BITSET(ret->HWBP_TYPE[0],0);
if(BITGET(dr7,17))
BITSET(ret->HWBP_TYPE[0],1);
if(BITGET(dr7,18))
BITSET(ret->HWBP_SIZE[0],0);
if(BITGET(dr7,19))
BITSET(ret->HWBP_SIZE[0],1);
if(BITGET(dr7,20))
BITSET(ret->HWBP_TYPE[1],0);
if(BITGET(dr7,21))
BITSET(ret->HWBP_TYPE[1],1);
if(BITGET(dr7,22))
BITSET(ret->HWBP_SIZE[1],0);
if(BITGET(dr7,23))
BITSET(ret->HWBP_SIZE[1],1);
if(BITGET(dr7,24))
BITSET(ret->HWBP_TYPE[2],0);
if(BITGET(dr7,25))
BITSET(ret->HWBP_TYPE[2],1);
if(BITGET(dr7,26))
BITSET(ret->HWBP_SIZE[2],0);
if(BITGET(dr7,27))
BITSET(ret->HWBP_SIZE[2],1);
if(BITGET(dr7,28))
BITSET(ret->HWBP_TYPE[3],0);
if(BITGET(dr7,29))
BITSET(ret->HWBP_TYPE[3],1);
if(BITGET(dr7,30))
BITSET(ret->HWBP_SIZE[3],0);
if(BITGET(dr7,31))
BITSET(ret->HWBP_SIZE[3],1);
}
__declspec(dllexport) bool TITCALL SetHardwareBreakPoint(ULONG_PTR bpxAddress, DWORD IndexOfRegister, DWORD bpxType, DWORD bpxSize, LPVOID bpxCallBack)
{
HWBP_SIZE hwbpSize;
HWBP_MODE hwbpMode;
HWBP_TYPE hwbpType;
int hwbpIndex=-1;
DR7 dr7;
switch(bpxSize)
{
case UE_HARDWARE_SIZE_1:
hwbpSize=SIZE_1;
break;
case UE_HARDWARE_SIZE_2:
hwbpSize=SIZE_2;
if((bpxAddress%2)!=0)
return false;
break;
case UE_HARDWARE_SIZE_4:
hwbpSize=SIZE_4;
if((bpxAddress%4)!=0)
return false;
break;
case UE_HARDWARE_SIZE_8:
hwbpSize=SIZE_8;
if((bpxAddress%8)!=0)
return false;
break;
default:
return false;
}
if(!IndexOfRegister)
{
if(!DebugRegister[0].DrxEnabled)
IndexOfRegister = UE_DR0;
else if(!DebugRegister[1].DrxEnabled)
IndexOfRegister = UE_DR1;
else if(!DebugRegister[2].DrxEnabled)
IndexOfRegister = UE_DR2;
else if(!DebugRegister[3].DrxEnabled)
IndexOfRegister = UE_DR3;
else
return false;
}
switch(IndexOfRegister)
{
case UE_DR0:
hwbpIndex=0;
break;
case UE_DR1:
hwbpIndex=1;
break;
case UE_DR2:
hwbpIndex=2;
break;
case UE_DR3:
hwbpIndex=3;
break;
default:
return false;
}
uintdr7(GetContextData(UE_DR7), &dr7);
DebugRegister[hwbpIndex].DrxExecution=false;
switch(bpxType)
{
case UE_HARDWARE_EXECUTE:
hwbpSize=SIZE_1;
hwbpType=TYPE_EXECUTE;
DebugRegister[hwbpIndex].DrxExecution=true;
break;
case UE_HARDWARE_WRITE:
hwbpType=TYPE_WRITE;
break;
case UE_HARDWARE_READWRITE:
hwbpType=TYPE_READWRITE;
break;
default:
return false;
}
hwbpMode=MODE_LOCAL;
dr7.HWBP_MODE[hwbpIndex]=hwbpMode;
dr7.HWBP_SIZE[hwbpIndex]=hwbpSize;
dr7.HWBP_TYPE[hwbpIndex]=hwbpType;
SetContextData(UE_DR7, dr7uint(&dr7)); //NOTE: MUST SET THIS FIRST FOR X64!
SetContextData(IndexOfRegister, (ULONG_PTR)bpxAddress);
DebugRegister[hwbpIndex].DrxBreakPointType=bpxType;
DebugRegister[hwbpIndex].DrxBreakPointSize=bpxSize;
DebugRegister[hwbpIndex].DrxEnabled=true;
DebugRegister[hwbpIndex].DrxBreakAddress=(ULONG_PTR)bpxAddress;
DebugRegister[hwbpIndex].DrxCallBack=(ULONG_PTR)bpxCallBack;
return true;
}
__declspec(dllexport) bool TITCALL DeleteHardwareBreakPoint(DWORD IndexOfRegister)
{
ULONG_PTR HardwareBPX = NULL;
ULONG_PTR bpxAddress = NULL;
if(IndexOfRegister == UE_DR0)
{
HardwareBPX = (ULONG_PTR)GetContextData(UE_DR7);
HardwareBPX = HardwareBPX &~ (1 << 0);
HardwareBPX = HardwareBPX &~ (1 << 1);
SetContextData(UE_DR0, (ULONG_PTR)bpxAddress);
SetContextData(UE_DR7, HardwareBPX);
DebugRegister[0].DrxEnabled = false;
DebugRegister[0].DrxBreakAddress = NULL;
DebugRegister[0].DrxCallBack = NULL;
return(true);
}
else if(IndexOfRegister == UE_DR1)
{
HardwareBPX = (ULONG_PTR)GetContextData(UE_DR7);
HardwareBPX = HardwareBPX &~ (1 << 2);
HardwareBPX = HardwareBPX &~ (1 << 3);
SetContextData(UE_DR1, (ULONG_PTR)bpxAddress);
SetContextData(UE_DR7, HardwareBPX);
DebugRegister[1].DrxEnabled = false;
DebugRegister[1].DrxBreakAddress = NULL;
DebugRegister[1].DrxCallBack = NULL;
return(true);
}
else if(IndexOfRegister == UE_DR2)
{
HardwareBPX = (ULONG_PTR)GetContextData(UE_DR7);
HardwareBPX = HardwareBPX &~ (1 << 4);
HardwareBPX = HardwareBPX &~ (1 << 5);
SetContextData(UE_DR2, (ULONG_PTR)bpxAddress);
SetContextData(UE_DR7, HardwareBPX);
DebugRegister[2].DrxEnabled = false;
DebugRegister[2].DrxBreakAddress = NULL;
DebugRegister[2].DrxCallBack = NULL;
return(true);
}
else if(IndexOfRegister == UE_DR3)
{
HardwareBPX = (ULONG_PTR)GetContextData(UE_DR7);
HardwareBPX = HardwareBPX &~ (1 << 6);
HardwareBPX = HardwareBPX &~ (1 << 7);
SetContextData(UE_DR3, (ULONG_PTR)bpxAddress);
SetContextData(UE_DR7, HardwareBPX);
DebugRegister[3].DrxEnabled = false;
DebugRegister[3].DrxBreakAddress = NULL;
DebugRegister[3].DrxCallBack = NULL;
return(true);
}
else
{
return(false);
}
return(false);
}
__declspec(dllexport) bool TITCALL SetHardwareBreakPointEx(HANDLE hActiveThread, ULONG_PTR bpxAddress, DWORD IndexOfRegister, DWORD bpxType, DWORD bpxSize, LPVOID bpxCallBack, LPDWORD IndexOfSelectedRegister)
{
HWBP_SIZE hwbpSize;
HWBP_MODE hwbpMode;
HWBP_TYPE hwbpType;
int hwbpIndex=-1;
DR7 dr7;
switch(bpxSize)
{
case UE_HARDWARE_SIZE_1:
hwbpSize=SIZE_1;
break;
case UE_HARDWARE_SIZE_2:
hwbpSize=SIZE_2;
if((bpxAddress%2)!=0)
return false;
break;
case UE_HARDWARE_SIZE_4:
hwbpSize=SIZE_4;
if((bpxAddress%4)!=0)
return false;
break;
case UE_HARDWARE_SIZE_8:
hwbpSize=SIZE_8;
if((bpxAddress%8)!=0)
return false;
break;
default:
return false;
}
if(!IndexOfRegister)
{
if(!DebugRegister[0].DrxEnabled)
IndexOfRegister = UE_DR0;
else if(!DebugRegister[1].DrxEnabled)
IndexOfRegister = UE_DR1;
else if(!DebugRegister[2].DrxEnabled)
IndexOfRegister = UE_DR2;
else if(!DebugRegister[3].DrxEnabled)
IndexOfRegister = UE_DR3;
else
return false;
}
if(IndexOfSelectedRegister)
*IndexOfSelectedRegister=IndexOfRegister;
switch(IndexOfRegister)
{
case UE_DR0:
hwbpIndex=0;
break;
case UE_DR1:
hwbpIndex=1;
break;
case UE_DR2:
hwbpIndex=2;
break;
case UE_DR3:
hwbpIndex=3;
break;
default:
return false;
}
uintdr7(GetContextDataEx(hActiveThread, UE_DR7), &dr7);
DebugRegister[hwbpIndex].DrxExecution=false;
switch(bpxType)
{
case UE_HARDWARE_EXECUTE:
hwbpSize=SIZE_1;
hwbpType=TYPE_EXECUTE;
DebugRegister[hwbpIndex].DrxExecution=true;
break;
case UE_HARDWARE_WRITE:
hwbpType=TYPE_WRITE;
break;
case UE_HARDWARE_READWRITE:
hwbpType=TYPE_READWRITE;
break;
default:
return false;
}
hwbpMode=MODE_LOCAL;
dr7.HWBP_MODE[hwbpIndex]=hwbpMode;
dr7.HWBP_SIZE[hwbpIndex]=hwbpSize;
dr7.HWBP_TYPE[hwbpIndex]=hwbpType;
SetContextDataEx(hActiveThread, UE_DR7, dr7uint(&dr7));
SetContextDataEx(hActiveThread, IndexOfRegister, (ULONG_PTR)bpxAddress);
DebugRegister[hwbpIndex].DrxBreakPointType=bpxType;
DebugRegister[hwbpIndex].DrxBreakPointSize=bpxSize;
DebugRegister[hwbpIndex].DrxEnabled=true;
DebugRegister[hwbpIndex].DrxBreakAddress=(ULONG_PTR)bpxAddress;
DebugRegister[hwbpIndex].DrxCallBack=(ULONG_PTR)bpxCallBack;
return true;
}
__declspec(dllexport) bool TITCALL RemoveAllBreakPoints(DWORD RemoveOption)
{
int i = 0;
int CurrentBreakPointSetCount = -1;
if(RemoveOption == UE_OPTION_REMOVEALL)
{
for(i = BreakPointSetCount - 1; i >= 0; i--)
{
if(BreakPointBuffer[i].BreakPointType == UE_BREAKPOINT)
{
DeleteBPX((ULONG_PTR)BreakPointBuffer[i].BreakPointAddress);
}
else if(BreakPointBuffer[i].BreakPointType >= UE_MEMORY && BreakPointBuffer[i].BreakPointType <= UE_MEMORY_EXECUTE)
{
RemoveMemoryBPX((ULONG_PTR)BreakPointBuffer[i].BreakPointAddress, BreakPointBuffer[i].BreakPointSize);
}
else if(CurrentBreakPointSetCount == -1 && BreakPointBuffer[i].BreakPointActive != UE_BPXREMOVED)
{
CurrentBreakPointSetCount = BreakPointSetCount;
}
RtlZeroMemory(&BreakPointBuffer[i], sizeof BreakPointDetail);
}
DeleteHardwareBreakPoint(UE_DR0);
DeleteHardwareBreakPoint(UE_DR1);
DeleteHardwareBreakPoint(UE_DR2);
DeleteHardwareBreakPoint(UE_DR3);
BreakPointSetCount = 0;
return(true);
}
else if(RemoveOption == UE_OPTION_DISABLEALL)
{
for(i = BreakPointSetCount - 1; i >= 0; i--)
{
if(BreakPointBuffer[i].BreakPointType == UE_BREAKPOINT && BreakPointBuffer[i].BreakPointActive == UE_BPXACTIVE)
{
DisableBPX((ULONG_PTR)BreakPointBuffer[i].BreakPointAddress);
}
else if(BreakPointBuffer[i].BreakPointType >= UE_MEMORY && BreakPointBuffer[i].BreakPointType <= UE_MEMORY_EXECUTE)
{
RemoveMemoryBPX((ULONG_PTR)BreakPointBuffer[i].BreakPointAddress, BreakPointBuffer[i].BreakPointSize);
RtlZeroMemory(&BreakPointBuffer[i], sizeof BreakPointDetail);
}
}
return(true);
}
else if(RemoveOption == UE_OPTION_REMOVEALLDISABLED)
{
for(i = BreakPointSetCount - 1; i >= 0; i--)
{
if(BreakPointBuffer[i].BreakPointType == UE_BREAKPOINT && BreakPointBuffer[i].BreakPointActive == UE_BPXINACTIVE)
{
DeleteBPX((ULONG_PTR)BreakPointBuffer[i].BreakPointAddress);
}
else if(CurrentBreakPointSetCount == -1 && BreakPointBuffer[i].BreakPointActive != UE_BPXREMOVED)
{
CurrentBreakPointSetCount = BreakPointSetCount;
}
}
if(CurrentBreakPointSetCount == -1)
{
BreakPointSetCount = 0;
}
else
{
BreakPointSetCount = CurrentBreakPointSetCount;
}
return(true);
}
else if(RemoveOption == UE_OPTION_REMOVEALLENABLED)
{
for(i = BreakPointSetCount - 1; i >= 0; i--)
{
if(BreakPointBuffer[i].BreakPointType == UE_BREAKPOINT && BreakPointBuffer[i].BreakPointActive == UE_BPXACTIVE)
{
DeleteBPX((ULONG_PTR)BreakPointBuffer[i].BreakPointAddress);
}
else if(CurrentBreakPointSetCount == -1 && BreakPointBuffer[i].BreakPointActive != UE_BPXREMOVED)
{
CurrentBreakPointSetCount = BreakPointSetCount;
}
}
if(CurrentBreakPointSetCount == -1)
{
BreakPointSetCount = 0;
}
else
{
BreakPointSetCount = CurrentBreakPointSetCount;
}
return(true);
}
return(false);
}
__declspec(dllexport) void* TITCALL GetProcessInformation()
{
return(&dbgProcessInformation);
}
__declspec(dllexport) void* TITCALL GetStartupInformation()
{
return(&dbgStartupInfo);
}
__declspec(dllexport) void TITCALL DebugLoop()
{
int i = NULL;
int j = NULL;
int k = NULL;
bool FirstBPX = true;
bool ResetBPX = false;
bool BreakDBG = false;
bool ResetHwBPX = false;
bool ResetMemBPX = false;
bool CompareResult = false;
bool SecondChance = false;
ULONG_PTR CmpValue1 = NULL;
ULONG_PTR CmpValue2 = NULL;
bool hListProcessFirst = true;
bool hListThreadFirst = true;
bool hListLibraryFirst = true;
PPROCESS_ITEM_DATA hListProcessPtr = NULL;
PTHREAD_ITEM_DATA hListThreadPtr = NULL;
PLIBRARY_ITEM_DATAW hListLibraryPtr = NULL;
PLIBRARY_ITEM_DATAW hLoadedLibData = NULL;
PLIBRARY_BREAK_DATA ptrLibrarianData = NULL;
typedef void(TITCALL *fCustomBreakPoint)(void);
typedef void(TITCALL *fCustomHandler)(void* SpecialDBG);
typedef void(TITCALL *fFindOEPHandler)(LPPROCESS_INFORMATION fProcessInfo, LPVOID fCallBack);
fCustomHandler myCustomHandler;
fCustomBreakPoint myCustomBreakPoint;
fFindOEPHandler myFindOEPHandler;
ULONG_PTR MemoryBpxCallBack = 0;
DWORD ResetBPXSize = 0;
ULONG_PTR ResetBPXAddressTo = 0;
ULONG_PTR ResetMemBPXAddress = 0;
SIZE_T ResetMemBPXSize = 0;
int MaximumBreakPoints = 0;
ULONG_PTR NumberOfBytesReadWritten = 0;
MEMORY_BASIC_INFORMATION MemInfo;
HANDLE hActiveThread;
CONTEXT myDBGContext;
DWORD OldProtect;
DWORD NewProtect;
DWORD DebugRegisterXId = NULL;
HARDWARE_DATA DebugRegisterX;
wchar_t DLLDebugFileName[512];
char szAnsiLibraryName[MAX_PATH];
ULONG_PTR DLLPatchAddress;
HANDLE hFileMapping;
LPVOID hFileMappingView;
LPVOID DBGEntryPoint;
bool MemoryBpxFound = false;
wchar_t* szTranslatedNativeName;
DBGFileHandle = NULL;
DBGCode = DBG_CONTINUE;
engineFakeDLLHandle = NULL;
DebugRegister[0].DrxEnabled = false;
DebugRegister[1].DrxEnabled = false;
DebugRegister[2].DrxEnabled = false;
DebugRegister[3].DrxEnabled = false;
engineProcessIsNowDetached = false;
engineResumeProcessIfNoThreadIsActive = false;
RtlZeroMemory(&DBGEvent, sizeof DEBUG_EVENT);
RtlZeroMemory(&TerminateDBGEvent, sizeof DEBUG_EVENT);
RtlZeroMemory(&DLLDebugFileName, 512);
EngineExecutePluginResetCallBack();
engineFileIsBeingDebugged = true;
if(engineExecutePluginCallBack)
{
EngineExecutePluginDebugCallBack(&DBGEvent, UE_PLUGIN_CALL_REASON_PREDEBUG);
}
while(!BreakDBG) //actual debug loop
{
WaitForDebugEvent(&DBGEvent, engineWaitForDebugEventTimeOut);
if(engineExecutePluginCallBack)
{
EngineExecutePluginDebugCallBack(&DBGEvent, UE_PLUGIN_CALL_REASON_EXCEPTION);
}
if(engineFindOEPCallBack != NULL)
{
myFindOEPHandler = (fFindOEPHandler)engineFindOEPCallBack;
engineFindOEPCallBack = NULL;
__try
{
myFindOEPHandler(&dbgProcessInformation, engineFindOEPUserCallBack);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
}
if(DBGEvent.dwDebugEventCode == CREATE_PROCESS_DEBUG_EVENT) //debuggee is created
{
if(DBGFileHandle == NULL) //we didn't set the handle yet
{
DBGEntryPoint = DBGEvent.u.CreateProcessInfo.lpStartAddress;
DBGFileHandle = DBGEvent.u.CreateProcessInfo.hFile;
EngineCloseHandle(DBGFileHandle); //handle is never used inside the code
engineDebuggingMainModuleBase = (unsigned long long) DBGEvent.u.CreateProcessInfo.lpBaseOfImage;
if(engineAttachedToProcess) //we attached, set information
{
dbgProcessInformation.hProcess = DBGEvent.u.CreateProcessInfo.hProcess;
dbgProcessInformation.hThread = DBGEvent.u.CreateProcessInfo.hThread;
dbgProcessInformation.dwThreadId = NULL;
if(engineAttachedProcessDebugInfo != NULL)
{
RtlMoveMemory(engineAttachedProcessDebugInfo, &dbgProcessInformation, sizeof PROCESS_INFORMATION);
}
}
if(engineDebuggingDLL) //the DLL loader just started, set DLL names
{
#if defined(_WIN64)
DLLPatchAddress = (ULONG_PTR)DBGEvent.u.CreateProcessInfo.lpBaseOfImage;
DLLPatchAddress = (ULONG_PTR)DLLPatchAddress + UE_MODULEx64;
#else
DLLPatchAddress = (ULONG_PTR)DBGEvent.u.CreateProcessInfo.lpBaseOfImage;
DLLPatchAddress = (ULONG_PTR)DLLPatchAddress + UE_MODULEx86;
#endif
if(!WriteProcessMemory(DBGEvent.u.CreateProcessInfo.hProcess, (LPVOID)DLLPatchAddress, engineDebuggingDLLFullFileName, lstrlenW(engineDebuggingDLLFullFileName) * 2, &NumberOfBytesReadWritten))
{
StopDebug();
return;
}
if(engineReserveModuleBase) //reserve original image base
{
VirtualAllocEx(dbgProcessInformation.hProcess, (void*)engineReserveModuleBase, 0x1000, MEM_RESERVE, PAGE_READWRITE); //return value nt used, yea just ignore. return value doesnt matter and there is no possible fix when failed :D this is only used to make sure DLL loads on another image base
}
}
if(hListProcess == NULL)
{
hListProcess = VirtualAlloc(NULL, MAX_DEBUG_DATA * sizeof PROCESS_ITEM_DATA, MEM_COMMIT, PAGE_READWRITE);
}
else
{
if(hListProcessFirst == true)
{
RtlZeroMemory(hListProcess, MAX_DEBUG_DATA * sizeof PROCESS_ITEM_DATA);
}
}
if(hListThread == NULL)
{
hListThread = VirtualAlloc(NULL, MAX_DEBUG_DATA * sizeof THREAD_ITEM_DATA, MEM_COMMIT, PAGE_READWRITE);
}
else
{
if(hListThreadFirst == true)
{
RtlZeroMemory(hListThread, MAX_DEBUG_DATA * sizeof THREAD_ITEM_DATA);
}
}
hListProcessPtr = (PPROCESS_ITEM_DATA)hListProcess;
hListProcessPtr->hFile = DBGEvent.u.CreateProcessInfo.hFile;
hListProcessPtr->hProcess = DBGEvent.u.CreateProcessInfo.hProcess;
hListProcessPtr->hThread = DBGEvent.u.CreateProcessInfo.hThread;
hListProcessPtr->dwProcessId = DBGEvent.dwProcessId;
hListProcessPtr->dwThreadId = DBGEvent.dwThreadId;
hListProcessPtr->BaseOfImage = (void*)DBGEvent.u.CreateProcessInfo.lpBaseOfImage;
hListProcessPtr->ThreadStartAddress = (void*)DBGEvent.u.CreateProcessInfo.lpStartAddress;
hListProcessPtr->ThreadLocalBase = (void*)DBGEvent.u.CreateProcessInfo.lpThreadLocalBase;
hListThreadPtr = (PTHREAD_ITEM_DATA)hListThread;
hListThreadPtr->dwThreadId = DBGEvent.dwThreadId;
hListThreadPtr->hThread = DBGEvent.u.CreateProcessInfo.hThread;
hListThreadPtr->ThreadStartAddress = (void*)DBGEvent.u.CreateProcessInfo.lpStartAddress;
hListThreadPtr->ThreadLocalBase = (void*)DBGEvent.u.CreateProcessInfo.lpThreadLocalBase;
hListThreadFirst = false;
}
else //we have a valid handle already (which means a child process started)
{
hListProcessPtr = (PPROCESS_ITEM_DATA)hListProcess;
while(hListProcessPtr->hProcess != NULL)
{
hListProcessPtr = (PPROCESS_ITEM_DATA)((ULONG_PTR)hListProcessPtr + sizeof PROCESS_ITEM_DATA);
}
if(hListProcessPtr->hProcess == NULL)
{
hListProcessPtr->hFile = DBGEvent.u.CreateProcessInfo.hFile;
hListProcessPtr->hProcess = DBGEvent.u.CreateProcessInfo.hProcess;
hListProcessPtr->hThread = DBGEvent.u.CreateProcessInfo.hThread;
hListProcessPtr->dwProcessId = DBGEvent.dwProcessId;
hListProcessPtr->dwThreadId = DBGEvent.dwThreadId;
hListProcessPtr->BaseOfImage = (void*)DBGEvent.u.CreateProcessInfo.lpBaseOfImage;
hListProcessPtr->ThreadStartAddress = (void*)DBGEvent.u.CreateProcessInfo.lpStartAddress;
hListProcessPtr->ThreadLocalBase = (void*)DBGEvent.u.CreateProcessInfo.lpThreadLocalBase;
hListProcessFirst = false;
}
}
//process created callback
if(DBGCustomHandler->chCreateProcess != NULL)
{
myCustomHandler = (fCustomHandler)((LPVOID)DBGCustomHandler->chCreateProcess);
__try
{
myCustomHandler(&DBGEvent.u.CreateProcessInfo);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DBGCustomHandler->chCreateProcess = NULL;
}
}
}
else if(DBGEvent.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
{
ProcessExitCode = DBGEvent.u.ExitProcess.dwExitCode;
DBGCode = DBG_CONTINUE;
if(DBGEvent.dwProcessId == dbgProcessInformation.dwProcessId) //main process closed
BreakDBG = true;
//exit process handler
if(DBGCustomHandler->chExitProcess != NULL)
{
myCustomHandler = (fCustomHandler)((LPVOID)DBGCustomHandler->chExitProcess);
__try
{
myCustomHandler(&DBGEvent.u.ExitProcess);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DBGCustomHandler->chExitProcess = NULL;
}
}
}
else if(DBGEvent.dwDebugEventCode == CREATE_THREAD_DEBUG_EVENT)
{
//maintain thread list
if(hListThread == NULL)
{
hListThread = VirtualAlloc(NULL, MAX_DEBUG_DATA * sizeof THREAD_ITEM_DATA, MEM_COMMIT, PAGE_READWRITE);
}
hListThreadPtr = (PTHREAD_ITEM_DATA)hListThread;
__try
{
while(hListThreadPtr->hThread != NULL)
{
hListThreadPtr = (PTHREAD_ITEM_DATA)((ULONG_PTR)hListThreadPtr + sizeof THREAD_ITEM_DATA);
}
hListThreadPtr->dwThreadId = DBGEvent.dwThreadId;
hListThreadPtr->hThread = DBGEvent.u.CreateThread.hThread;
hListThreadPtr->ThreadStartAddress = (void*)DBGEvent.u.CreateThread.lpStartAddress;
hListThreadPtr->ThreadLocalBase = (void*)DBGEvent.u.CreateThread.lpThreadLocalBase;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
//custom handler
if(DBGCustomHandler->chCreateThread != NULL)
{
myCustomHandler = (fCustomHandler)((LPVOID)DBGCustomHandler->chCreateThread);
__try
{
myCustomHandler(&DBGEvent.u.CreateThread);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DBGCustomHandler->chCreateThread = NULL;
}
}
}
else if(DBGEvent.dwDebugEventCode == EXIT_THREAD_DEBUG_EVENT)
{
//custom handler
if(DBGCustomHandler->chExitThread != NULL)
{
myCustomHandler = (fCustomHandler)((LPVOID)DBGCustomHandler->chExitThread);
__try
{
myCustomHandler(&DBGEvent.u.ExitThread);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DBGCustomHandler->chExitThread = NULL;
}
}
if(engineExitThreadOneShootCallBack != NULL)
{
myCustomHandler = (fCustomHandler)(engineExitThreadOneShootCallBack);
__try
{
myCustomHandler(&DBGEvent.u.ExitThread);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
engineExitThreadOneShootCallBack = NULL;
}
//maintain thread list
hListThreadPtr = (PTHREAD_ITEM_DATA)hListThread;
while(hListThreadPtr->hThread != NULL && hListThreadPtr->dwThreadId != DBGEvent.dwThreadId)
{
hListThreadPtr = (PTHREAD_ITEM_DATA)((ULONG_PTR)hListThreadPtr + sizeof THREAD_ITEM_DATA);
}
if(hListThreadPtr->dwThreadId == DBGEvent.dwThreadId)
{
hListThreadPtr->hThread = (HANDLE)-1;
hListThreadPtr->dwThreadId = NULL;
hListThreadPtr->ThreadLocalBase = NULL;
hListThreadPtr->ThreadStartAddress = NULL;
}
}
else if(DBGEvent.dwDebugEventCode == LOAD_DLL_DEBUG_EVENT)
{
//maintain library list
if(hListLibrary == NULL)
{
hListLibrary = VirtualAlloc(NULL, MAX_DEBUG_DATA * sizeof LIBRARY_ITEM_DATAW, MEM_COMMIT, PAGE_READWRITE);
}
else
{
if(hListLibraryFirst == true)
{
RtlZeroMemory(hListLibrary, MAX_DEBUG_DATA * sizeof LIBRARY_ITEM_DATAW);
}
}
hListLibraryFirst = false;
hListLibraryPtr = (PLIBRARY_ITEM_DATAW)hListLibrary;
while(hListLibraryPtr->hFile != NULL)
{
hListLibraryPtr = (PLIBRARY_ITEM_DATAW)((ULONG_PTR)hListLibraryPtr + sizeof LIBRARY_ITEM_DATAW);
}
hListLibraryPtr->hFile = DBGEvent.u.LoadDll.hFile;
hListLibraryPtr->BaseOfDll = DBGEvent.u.LoadDll.lpBaseOfDll;
hFileMapping = CreateFileMappingA(DBGEvent.u.LoadDll.hFile, NULL, PAGE_READONLY, NULL, GetFileSize(DBGEvent.u.LoadDll.hFile, NULL), NULL);
if(hFileMapping != NULL)
{
hFileMappingView = MapViewOfFile(hFileMapping, FILE_MAP_READ, NULL, NULL, NULL);
if(hFileMappingView != NULL)
{
hListLibraryPtr->hFileMapping = hFileMapping;
hListLibraryPtr->hFileMappingView = hFileMappingView;
if(GetMappedFileNameW(GetCurrentProcess(), hFileMappingView, DLLDebugFileName, sizeof(DLLDebugFileName)/sizeof(DLLDebugFileName[0])) > NULL)
{
i = lstrlenW(DLLDebugFileName);
while(DLLDebugFileName[i] != 0x5C && i >= NULL)
{
i--;
}
if(engineDebuggingDLL)
{
if(lstrcmpiW(&DLLDebugFileName[i+1], engineDebuggingDLLFileName) == NULL)
{
SetBPX(DebugModuleEntryPoint + (ULONG_PTR)DBGEvent.u.LoadDll.lpBaseOfDll, UE_SINGLESHOOT, DebugModuleEntryPointCallBack);
engineDebuggingDLLBase = (ULONG_PTR)DBGEvent.u.LoadDll.lpBaseOfDll;
}
/*else if(lstrcmpiW(&DLLDebugFileName[i+1], engineDebuggingDLLReserveFileName) == NULL)
{
if((ULONG_PTR)DBGEvent.u.LoadDll.lpBaseOfDll != DebugModuleImageBase)
{
VirtualAllocEx(dbgProcessInformation.hProcess, (void*)DebugModuleImageBase, 0x1000, MEM_RESERVE, PAGE_READWRITE);
}
}*/
}
if(engineFakeDLLHandle == NULL)
{
if(lstrcmpiW(&DLLDebugFileName[i+1], L"kernel32.dll") == NULL)
{
engineFakeDLLHandle = (ULONG_PTR)DBGEvent.u.LoadDll.lpBaseOfDll;
}
}
lstrcpyW(hListLibraryPtr->szLibraryName, &DLLDebugFileName[i+1]);
szTranslatedNativeName = (wchar_t*)TranslateNativeNameW(DLLDebugFileName);
lstrcpyW(hListLibraryPtr->szLibraryPath, szTranslatedNativeName);
VirtualFree((void*)szTranslatedNativeName, NULL, MEM_RELEASE);
RtlZeroMemory(szAnsiLibraryName, sizeof szAnsiLibraryName);
WideCharToMultiByte(CP_ACP, NULL, hListLibraryPtr->szLibraryName, -1, szAnsiLibraryName, sizeof szAnsiLibraryName, NULL, NULL);
ptrLibrarianData = (PLIBRARY_BREAK_DATA)LibrarianData;
k = NULL;
if(ptrLibrarianData != NULL)
{
while(k < MAX_LIBRARY_BPX)
{
if(ptrLibrarianData->szLibraryName[0] != 0x00)
{
if(lstrcmpiA(ptrLibrarianData->szLibraryName, szAnsiLibraryName) == NULL)
{
if(ptrLibrarianData->bpxType == UE_ON_LIB_LOAD || ptrLibrarianData->bpxType == UE_ON_LIB_ALL)
{
myCustomHandler = (fCustomHandler)(ptrLibrarianData->bpxCallBack);
__try
{
myCustomHandler(&DBGEvent.u.LoadDll);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
LibrarianRemoveBreakPoint(ptrLibrarianData->szLibraryName, ptrLibrarianData->bpxType);
}
if(ptrLibrarianData->bpxSingleShoot)
{
LibrarianRemoveBreakPoint(ptrLibrarianData->szLibraryName, ptrLibrarianData->bpxType);
}
}
}
}
ptrLibrarianData = (PLIBRARY_BREAK_DATA)((ULONG_PTR)ptrLibrarianData + sizeof LIBRARY_BREAK_DATA);
k++;
}
}
}
}
}
//loadDLL callback
if(DBGCustomHandler->chLoadDll != NULL)
{
myCustomHandler = (fCustomHandler)((LPVOID)DBGCustomHandler->chLoadDll);
__try
{
myCustomHandler(&DBGEvent.u.LoadDll);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DBGCustomHandler->chLoadDll = NULL;
}
}
}
else if(DBGEvent.dwDebugEventCode == UNLOAD_DLL_DEBUG_EVENT)
{
//unload DLL callback
if(DBGCustomHandler->chUnloadDll != NULL)
{
myCustomHandler = (fCustomHandler)((LPVOID)DBGCustomHandler->chUnloadDll);
__try
{
myCustomHandler(&DBGEvent.u.UnloadDll);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DBGCustomHandler->chUnloadDll = NULL;
}
}
//maintain library list
k = NULL;
ptrLibrarianData = (PLIBRARY_BREAK_DATA)LibrarianData;
hLoadedLibData = (PLIBRARY_ITEM_DATAW)LibrarianGetLibraryInfoEx(DBGEvent.u.UnloadDll.lpBaseOfDll);
if(hLoadedLibData != NULL)
{
RtlZeroMemory(szAnsiLibraryName, sizeof szAnsiLibraryName);
WideCharToMultiByte(CP_ACP, NULL, hLoadedLibData->szLibraryName, -1, szAnsiLibraryName, sizeof szAnsiLibraryName, NULL, NULL);
if(ptrLibrarianData != NULL)
{
while(k < MAX_LIBRARY_BPX)
{
if(ptrLibrarianData->szLibraryName[0] != 0x00)
{
if(lstrcmpiA(ptrLibrarianData->szLibraryName, szAnsiLibraryName) == NULL)
{
if(ptrLibrarianData->bpxType == UE_ON_LIB_UNLOAD || ptrLibrarianData->bpxType == UE_ON_LIB_ALL)
{
myCustomHandler = (fCustomHandler)(ptrLibrarianData->bpxCallBack);
__try
{
myCustomHandler(&DBGEvent.u.UnloadDll);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
LibrarianRemoveBreakPoint(ptrLibrarianData->szLibraryName, ptrLibrarianData->bpxType);
}
if(ptrLibrarianData->bpxSingleShoot)
{
LibrarianRemoveBreakPoint(ptrLibrarianData->szLibraryName, ptrLibrarianData->bpxType);
}
}
}
}
ptrLibrarianData = (PLIBRARY_BREAK_DATA)((ULONG_PTR)ptrLibrarianData + sizeof LIBRARY_BREAK_DATA);
k++;
}
}
}
hListLibraryPtr = (PLIBRARY_ITEM_DATAW)hListLibrary;
if(hListLibraryPtr != NULL)
{
while(hListLibraryPtr->hFile != NULL)
{
if(hListLibraryPtr->BaseOfDll == DBGEvent.u.UnloadDll.lpBaseOfDll)
{
if(hListLibraryPtr->hFile != (HANDLE)-1)
{
if(hListLibraryPtr->hFileMappingView != NULL)
{
UnmapViewOfFile(hListLibraryPtr->hFileMappingView);
EngineCloseHandle(hListLibraryPtr->hFileMapping);
}
EngineCloseHandle(hListLibraryPtr->hFile);
RtlZeroMemory(hListLibraryPtr, sizeof LIBRARY_ITEM_DATAW);
hListLibraryPtr->hFile = (HANDLE)-1;
}
}
hListLibraryPtr = (PLIBRARY_ITEM_DATAW)((ULONG_PTR)hListLibraryPtr + sizeof LIBRARY_ITEM_DATAW);
}
}
}
else if(DBGEvent.dwDebugEventCode == OUTPUT_DEBUG_STRING_EVENT)
{
//debug string callback
if(DBGCustomHandler->chOutputDebugString != NULL)
{
myCustomHandler = (fCustomHandler)((LPVOID)DBGCustomHandler->chOutputDebugString);
__try
{
myCustomHandler(&DBGEvent.u.DebugString);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DBGCustomHandler->chOutputDebugString = NULL;
}
}
}
else if(DBGEvent.dwDebugEventCode == EXCEPTION_DEBUG_EVENT)
{
//NOTE: useless callback?
if(DBGCustomHandler->chEverythingElse != NULL)
{
myCustomHandler = (fCustomHandler)((LPVOID)DBGCustomHandler->chEverythingElse);
__try
{
myCustomHandler(&DBGEvent.u.Exception.ExceptionRecord);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DBGCustomHandler->chEverythingElse = NULL;
}
}
if(DBGEvent.u.Exception.dwFirstChance == FALSE) //second chance exception
{
//NOTE: unclear behavious of ->Pass<- all exceptions (not to debuggee, but to debugger)
if(!enginePassAllExceptions)
{
DBGCode = DBG_CONTINUE;
}
else
{
DBGCode = DBG_EXCEPTION_NOT_HANDLED; //let debuggee handle the exception
}
RtlMoveMemory(&TerminateDBGEvent, &DBGEvent, sizeof DEBUG_EVENT);
}
//handle different exception codes
//NOTE: breakpoint exception
if(DBGEvent.u.Exception.ExceptionRecord.ExceptionCode == STATUS_BREAKPOINT)
{
MaximumBreakPoints = 0;
for(MaximumBreakPoints = 0; MaximumBreakPoints < BreakPointSetCount; MaximumBreakPoints++)
{
if(BreakPointBuffer[MaximumBreakPoints].BreakPointAddress == (ULONG_PTR)DBGEvent.u.Exception.ExceptionRecord.ExceptionAddress - (BreakPointBuffer[MaximumBreakPoints].BreakPointSize - 1))
{
break;
}
}
if(BreakPointBuffer[MaximumBreakPoints].BreakPointActive == UE_BPXACTIVE && MaximumBreakPoints < MAXIMUM_BREAKPOINTS)
{
VirtualQueryEx(dbgProcessInformation.hProcess, (LPVOID)BreakPointBuffer[MaximumBreakPoints].BreakPointAddress, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
OldProtect = MemInfo.AllocationProtect;
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)BreakPointBuffer[MaximumBreakPoints].BreakPointAddress, BreakPointBuffer[MaximumBreakPoints].BreakPointSize, PAGE_EXECUTE_READWRITE, &OldProtect);
if(BreakPointBuffer[MaximumBreakPoints].BreakPointActive == UE_BPXACTIVE && (BreakPointBuffer[MaximumBreakPoints].BreakPointType == UE_BREAKPOINT || BreakPointBuffer[MaximumBreakPoints].BreakPointType == UE_SINGLESHOOT) && (BreakPointBuffer[MaximumBreakPoints].NumberOfExecutions == -1 || BreakPointBuffer[MaximumBreakPoints].NumberOfExecutions > 0))
{
if(WriteProcessMemory(dbgProcessInformation.hProcess, (LPVOID)BreakPointBuffer[MaximumBreakPoints].BreakPointAddress, &BreakPointBuffer[MaximumBreakPoints].OriginalByte[0], BreakPointBuffer[MaximumBreakPoints].BreakPointSize, &NumberOfBytesReadWritten))
{
DBGCode = DBG_CONTINUE;
hActiveThread = OpenThread(THREAD_GET_CONTEXT|THREAD_SET_CONTEXT|THREAD_QUERY_INFORMATION, false, DBGEvent.dwThreadId);
myDBGContext.ContextFlags = CONTEXT_ALL;
GetThreadContext(hActiveThread, &myDBGContext);
if(BreakPointBuffer[MaximumBreakPoints].BreakPointType != UE_SINGLESHOOT)
{
if(!(myDBGContext.EFlags & 0x100))
{
myDBGContext.EFlags = myDBGContext.EFlags ^ 0x100;
}
}
if(!(myDBGContext.EFlags & 0x10000))
{
myDBGContext.EFlags = myDBGContext.EFlags ^ 0x10000;
}
#if defined(_WIN64)
myDBGContext.Rip = myDBGContext.Rip - BreakPointBuffer[MaximumBreakPoints].BreakPointSize;
#else
myDBGContext.Eip = myDBGContext.Eip - BreakPointBuffer[MaximumBreakPoints].BreakPointSize;
#endif
SetThreadContext(hActiveThread, &myDBGContext);
EngineCloseHandle(hActiveThread);
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)BreakPointBuffer[MaximumBreakPoints].BreakPointAddress, BreakPointBuffer[MaximumBreakPoints].BreakPointSize, OldProtect, &OldProtect);
myCustomBreakPoint = (fCustomBreakPoint)((LPVOID)BreakPointBuffer[MaximumBreakPoints].ExecuteCallBack);
if(BreakPointBuffer[MaximumBreakPoints].NumberOfExecutions != -1 && BreakPointBuffer[MaximumBreakPoints].NumberOfExecutions != 0)
{
BreakPointBuffer[MaximumBreakPoints].NumberOfExecutions--;
}
if(BreakPointBuffer[MaximumBreakPoints].CmpCondition != UE_CMP_NOCONDITION)
{
CompareResult = false;
CmpValue1 = (ULONG_PTR)GetContextData((DWORD)BreakPointBuffer[MaximumBreakPoints].CmpRegister);
myCustomBreakPoint = (fCustomBreakPoint)((LPVOID)BreakPointBuffer[MaximumBreakPoints].CompareCallBack);
if(BreakPointBuffer[MaximumBreakPoints].CmpCondition == UE_CMP_EQUAL)
{
CmpValue2 = BreakPointBuffer[MaximumBreakPoints].CmpValue;
if(CmpValue1 == CmpValue2)
{
CompareResult = true;
}
}
else if(BreakPointBuffer[MaximumBreakPoints].CmpCondition == UE_CMP_NOTEQUAL)
{
CmpValue2 = BreakPointBuffer[MaximumBreakPoints].CmpValue;
if(CmpValue1 != CmpValue2)
{
CompareResult = true;
}
}
else if(BreakPointBuffer[MaximumBreakPoints].CmpCondition == UE_CMP_GREATER)
{
CmpValue2 = BreakPointBuffer[MaximumBreakPoints].CmpValue;
if(CmpValue1 > CmpValue2)
{
CompareResult = true;
}
}
else if(BreakPointBuffer[MaximumBreakPoints].CmpCondition == UE_CMP_GREATEROREQUAL)
{
CmpValue2 = BreakPointBuffer[MaximumBreakPoints].CmpValue;
if(CmpValue1 >= CmpValue2)
{
CompareResult = true;
}
}
else if(BreakPointBuffer[MaximumBreakPoints].CmpCondition == UE_CMP_LOWER)
{
CmpValue2 = BreakPointBuffer[MaximumBreakPoints].CmpValue;
if(CmpValue1 < CmpValue2)
{
CompareResult = true;
}
}
else if(BreakPointBuffer[MaximumBreakPoints].CmpCondition == UE_CMP_LOWEROREQUAL)
{
CmpValue2 = BreakPointBuffer[MaximumBreakPoints].CmpValue;
if(CmpValue1 <= CmpValue2)
{
CompareResult = true;
}
}
else if(BreakPointBuffer[MaximumBreakPoints].CmpCondition == UE_CMP_REG_EQUAL)
{
CmpValue2 = (ULONG_PTR)GetContextData((DWORD)BreakPointBuffer[MaximumBreakPoints].CmpValue);
if(CmpValue1 == CmpValue2)
{
CompareResult = true;
}
}
else if(BreakPointBuffer[MaximumBreakPoints].CmpCondition == UE_CMP_REG_NOTEQUAL)
{
CmpValue2 = (ULONG_PTR)GetContextData((DWORD)BreakPointBuffer[MaximumBreakPoints].CmpValue);
if(CmpValue1 != CmpValue2)
{
CompareResult = true;
}
}
else if(BreakPointBuffer[MaximumBreakPoints].CmpCondition == UE_CMP_REG_GREATER)
{
CmpValue2 = (ULONG_PTR)GetContextData((DWORD)BreakPointBuffer[MaximumBreakPoints].CmpValue);
if(CmpValue1 > CmpValue2)
{
CompareResult = true;
}
}
else if(BreakPointBuffer[MaximumBreakPoints].CmpCondition == UE_CMP_REG_GREATEROREQUAL)
{
CmpValue2 = (ULONG_PTR)GetContextData((DWORD)BreakPointBuffer[MaximumBreakPoints].CmpValue);
if(CmpValue1 >= CmpValue2)
{
CompareResult = true;
}
}
else if(BreakPointBuffer[MaximumBreakPoints].CmpCondition == UE_CMP_REG_LOWER)
{
CmpValue2 = (ULONG_PTR)GetContextData((DWORD)BreakPointBuffer[MaximumBreakPoints].CmpValue);
if(CmpValue1 < CmpValue2)
{
CompareResult = true;
}
}
else if(BreakPointBuffer[MaximumBreakPoints].CmpCondition == UE_CMP_REG_LOWEROREQUAL)
{
CmpValue2 = (ULONG_PTR)GetContextData((DWORD)BreakPointBuffer[MaximumBreakPoints].CmpValue);
if(CmpValue1 <= CmpValue2)
{
CompareResult = true;
}
}
if(CompareResult)
{
__try
{
myCustomBreakPoint();
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
}
}
else
{
__try
{
myCustomBreakPoint();
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
}
if(BreakPointBuffer[MaximumBreakPoints].BreakPointType != UE_SINGLESHOOT)
{
DisableBPX((ULONG_PTR)BreakPointBuffer[MaximumBreakPoints].BreakPointAddress);
ResetBPXSize = BreakPointBuffer[MaximumBreakPoints].BreakPointSize - 1;
ResetBPXAddressTo = (ULONG_PTR)BreakPointBuffer[MaximumBreakPoints].BreakPointAddress;
ResetBPX = true;
}
else
{
DeleteBPX((ULONG_PTR)BreakPointBuffer[MaximumBreakPoints].BreakPointAddress);
ResetBPXSize = BreakPointBuffer[MaximumBreakPoints].BreakPointSize - 1;
ResetBPXAddressTo = NULL;
ResetBPX = false;
}
}
else
{
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)BreakPointBuffer[MaximumBreakPoints].BreakPointAddress, BreakPointBuffer[MaximumBreakPoints].BreakPointSize, OldProtect, &OldProtect);
DBGCode = DBG_CONTINUE;
}
}
else
{
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)BreakPointBuffer[MaximumBreakPoints].BreakPointAddress, BreakPointBuffer[MaximumBreakPoints].BreakPointSize, OldProtect, &OldProtect);
DBGCode = DBG_EXCEPTION_NOT_HANDLED;
}
}
else //breakpoint not in list
{
if(!FirstBPX) //program generated a breakpoint exception
{
DBGCode = DBG_EXCEPTION_NOT_HANDLED;
if(DBGCustomHandler->chBreakPoint != NULL)
{
myCustomHandler = (fCustomHandler)((LPVOID)DBGCustomHandler->chBreakPoint);
__try
{
myCustomHandler(&DBGEvent.u.Exception.ExceptionRecord);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DBGCustomHandler->chBreakPoint = NULL;
}
}
}
else //system breakpoint
{
FirstBPX = false;
DBGCode = DBG_CONTINUE;
if(engineAttachedToProcess)
{
myCustomBreakPoint = (fCustomBreakPoint)(engineAttachedProcessCallBack);
__try
{
myCustomBreakPoint();
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
}
if(engineAutoHideFromDebugger)
{
HideDebugger(dbgProcessInformation.hProcess, UE_HIDE_BASIC);
}
if(DebugExeFileEntryPointCallBack != NULL) //set entry breakpoint
{
SetBPX((ULONG_PTR)DBGEntryPoint, UE_SINGLESHOOT, DebugExeFileEntryPointCallBack);
}
if(engineTLSBreakOnCallBack) //set TLS callback breakpoints
{
i = NULL;
while(tlsCallBackList[i] != NULL)
{
SetBPX((ULONG_PTR)tlsCallBackList[i], UE_SINGLESHOOT, (LPVOID)engineTLSBreakOnCallBackAddress);
tlsCallBackList[i] = NULL;
i++;
}
engineTLSBreakOnCallBackAddress = NULL;
engineTLSBreakOnCallBack = false;
}
//system breakpoint callback
if(DBGCustomHandler->chSystemBreakpoint != NULL)
{
myCustomHandler = (fCustomHandler)((LPVOID)DBGCustomHandler->chSystemBreakpoint);
__try
{
myCustomHandler(&DBGEvent);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DBGCustomHandler->chSystemBreakpoint = NULL;
}
}
}
}
}
//NOTE: single step exception
else if(DBGEvent.u.Exception.ExceptionRecord.ExceptionCode == STATUS_SINGLE_STEP)
{
if(ResetBPX == true || ResetHwBPX == true || ResetMemBPX == true) //restore breakpoints (internal step)
{
DBGCode = DBG_CONTINUE;
if(ResetBPX) //restore 'normal' breakpoint
{
if(ResetBPXAddressTo + ResetBPXSize != (ULONG_PTR)DBGEvent.u.Exception.ExceptionRecord.ExceptionAddress)
{
EnableBPX(ResetBPXAddressTo);
ResetBPXAddressTo = NULL;
ResetBPX = false;
if(engineStepActive)
{
if(engineStepCount == NULL)
{
myCustomBreakPoint = (fCustomBreakPoint)(engineStepCallBack);
__try
{
engineStepActive = false;
engineStepCallBack = NULL;
myCustomBreakPoint();
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
}
else
{
SingleStep(engineStepCount, engineStepCallBack);
}
}
}
else
{
hActiveThread = OpenThread(THREAD_GET_CONTEXT+THREAD_SET_CONTEXT+THREAD_QUERY_INFORMATION, false, DBGEvent.dwThreadId);
myDBGContext.ContextFlags = CONTEXT_ALL;
GetThreadContext(hActiveThread, &myDBGContext);
if(!(myDBGContext.EFlags & 0x100))
{
myDBGContext.EFlags = myDBGContext.EFlags ^ 0x100;
}
SetThreadContext(hActiveThread, &myDBGContext);
EngineCloseHandle(hActiveThread);
}
}
else if(ResetHwBPX) //restore hardware breakpoint
{
ResetHwBPX = false;
SetHardwareBreakPoint(DebugRegisterX.DrxBreakAddress, DebugRegisterXId, DebugRegisterX.DrxBreakPointType, DebugRegisterX.DrxBreakPointSize, (LPVOID)DebugRegisterX.DrxCallBack);
if(engineStepActive)
{
if(engineStepCount == NULL)
{
myCustomBreakPoint = (fCustomBreakPoint)(engineStepCallBack);
__try
{
engineStepActive = false;
engineStepCallBack = NULL;
myCustomBreakPoint();
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
}
else
{
SingleStep(engineStepCount, engineStepCallBack);
}
}
}
else if(ResetMemBPX) //restore memory breakpoint
{
ResetMemBPX = false;
VirtualQueryEx(dbgProcessInformation.hProcess, (LPCVOID)ResetMemBPXAddress, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
OldProtect = MemInfo.AllocationProtect;
NewProtect = OldProtect | PAGE_GUARD;
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)ResetMemBPXAddress, ResetMemBPXSize, NewProtect, &OldProtect);
if(engineStepActive)
{
if(engineStepCount == NULL)
{
myCustomBreakPoint = (fCustomBreakPoint)(engineStepCallBack);
__try
{
engineStepActive = false;
engineStepCallBack = NULL;
myCustomBreakPoint();
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
}
else
{
SingleStep(engineStepCount, engineStepCallBack);
}
}
}
}
else //no resetting needed (debugger reached hardware breakpoint or the user stepped)
{
if(engineStepActive)
{
DBGCode = DBG_CONTINUE;
if(engineStepCount == NULL)
{
myCustomBreakPoint = (fCustomBreakPoint)(engineStepCallBack);
__try
{
engineStepActive = false;
engineStepCallBack = NULL;
myCustomBreakPoint();
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
}
else
{
SingleStep(engineStepCount, engineStepCallBack);
}
}
else //handle hardware breakpoints
{
hActiveThread = OpenThread(THREAD_GET_CONTEXT+THREAD_SET_CONTEXT+THREAD_QUERY_INFORMATION, false, DBGEvent.dwThreadId);
myDBGContext.ContextFlags = CONTEXT_ALL;
GetThreadContext(hActiveThread, &myDBGContext);
if((ULONG_PTR)DBGEvent.u.Exception.ExceptionRecord.ExceptionAddress == myDBGContext.Dr0 || (myDBGContext.Dr6 & 0x1))
{
if(DebugRegister[0].DrxEnabled)
{
DBGCode = DBG_CONTINUE;
if(!(myDBGContext.EFlags & 0x100))
{
myDBGContext.EFlags = myDBGContext.EFlags ^ 0x100;
}
SetThreadContext(hActiveThread, &myDBGContext);
myCustomHandler = (fCustomHandler)(DebugRegister[0].DrxCallBack);
__try
{
myCustomHandler((void*)myDBGContext.Dr0);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
RtlZeroMemory(&DebugRegisterX, sizeof HARDWARE_DATA);
RtlMoveMemory(&DebugRegisterX, &DebugRegister[0], sizeof HARDWARE_DATA);
DeleteHardwareBreakPoint(UE_DR0);
DebugRegisterXId = UE_DR0;
ResetHwBPX = true;
}
else
{
DBGCode = DBG_EXCEPTION_NOT_HANDLED;
}
}
else if((ULONG_PTR)DBGEvent.u.Exception.ExceptionRecord.ExceptionAddress == myDBGContext.Dr1 || (myDBGContext.Dr6 & 0x2))
{
if(DebugRegister[1].DrxEnabled)
{
DBGCode = DBG_CONTINUE;
if(!(myDBGContext.EFlags & 0x100))
{
myDBGContext.EFlags = myDBGContext.EFlags ^ 0x100;
}
SetThreadContext(hActiveThread, &myDBGContext);
myCustomHandler = (fCustomHandler)(DebugRegister[1].DrxCallBack);
__try
{
myCustomHandler((void*)myDBGContext.Dr1);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
RtlZeroMemory(&DebugRegisterX, sizeof HARDWARE_DATA);
RtlMoveMemory(&DebugRegisterX, &DebugRegister[1], sizeof HARDWARE_DATA);
DeleteHardwareBreakPoint(UE_DR1);
DebugRegisterXId = UE_DR1;
ResetHwBPX = true;
}
else
{
DBGCode = DBG_EXCEPTION_NOT_HANDLED;
}
}
else if((ULONG_PTR)DBGEvent.u.Exception.ExceptionRecord.ExceptionAddress == myDBGContext.Dr2 || (myDBGContext.Dr6 & 0x4))
{
if(DebugRegister[2].DrxEnabled)
{
DBGCode = DBG_CONTINUE;
if(!(myDBGContext.EFlags & 0x100))
{
myDBGContext.EFlags = myDBGContext.EFlags ^ 0x100;
}
SetThreadContext(hActiveThread, &myDBGContext);
myCustomHandler = (fCustomHandler)(DebugRegister[2].DrxCallBack);
__try
{
myCustomHandler((void*)myDBGContext.Dr2);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
RtlZeroMemory(&DebugRegisterX, sizeof HARDWARE_DATA);
RtlMoveMemory(&DebugRegisterX, &DebugRegister[2], sizeof HARDWARE_DATA);
DeleteHardwareBreakPoint(UE_DR2);
DebugRegisterXId = UE_DR2;
ResetHwBPX = true;
}
else
{
DBGCode = DBG_EXCEPTION_NOT_HANDLED;
}
}
else if((ULONG_PTR)DBGEvent.u.Exception.ExceptionRecord.ExceptionAddress == myDBGContext.Dr3 || (myDBGContext.Dr6 & 0x8))
{
if(DebugRegister[3].DrxEnabled)
{
DBGCode = DBG_CONTINUE;
if(!(myDBGContext.EFlags & 0x100))
{
myDBGContext.EFlags = myDBGContext.EFlags ^ 0x100;
}
SetThreadContext(hActiveThread, &myDBGContext);
myCustomHandler = (fCustomHandler)(DebugRegister[3].DrxCallBack);
__try
{
myCustomHandler((void*)myDBGContext.Dr3);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
RtlZeroMemory(&DebugRegisterX, sizeof HARDWARE_DATA);
RtlMoveMemory(&DebugRegisterX, &DebugRegister[3], sizeof HARDWARE_DATA);
DeleteHardwareBreakPoint(UE_DR3);
DebugRegisterXId = UE_DR3;
ResetHwBPX = true;
}
else
{
DBGCode = DBG_EXCEPTION_NOT_HANDLED;
}
}
else //debuggee generated exception
{
DBGCode = DBG_EXCEPTION_NOT_HANDLED;
}
EngineCloseHandle(hActiveThread);
}
}
if(DBGCode==DBG_EXCEPTION_NOT_HANDLED) //NOTE: only call the chSingleStep callback when the debuggee generated the exception
{
if(DBGCustomHandler->chSingleStep != NULL)
{
myCustomHandler = (fCustomHandler)((LPVOID)DBGCustomHandler->chSingleStep);
__try
{
myCustomHandler(&DBGEvent.u.Exception.ExceptionRecord);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DBGCustomHandler->chSingleStep = NULL;
}
}
}
}
//NOTE: guard page exception
else if(DBGEvent.u.Exception.ExceptionRecord.ExceptionCode == STATUS_GUARD_PAGE_VIOLATION)
{
MemoryBpxFound = false;
MaximumBreakPoints = 0;
ULONG_PTR bpaddr;
for(MaximumBreakPoints = 0; MaximumBreakPoints < BreakPointSetCount; MaximumBreakPoints++)
{
ULONG_PTR addr=BreakPointBuffer[MaximumBreakPoints].BreakPointAddress;
if(DBGEvent.u.Exception.ExceptionRecord.ExceptionInformation[0] == 1)
bpaddr=(ULONG_PTR)DBGEvent.u.Exception.ExceptionRecord.ExceptionInformation[1]; //page accessed
else
bpaddr=(ULONG_PTR)DBGEvent.u.Exception.ExceptionRecord.ExceptionAddress;
if(((BreakPointBuffer[MaximumBreakPoints].BreakPointType >= UE_MEMORY) && (BreakPointBuffer[MaximumBreakPoints].BreakPointType <= UE_MEMORY_EXECUTE)) && bpaddr>=addr && bpaddr<=(addr+BreakPointBuffer[MaximumBreakPoints].BreakPointSize))
{
MemoryBpxFound = true;
break;
}
}
if(MaximumBreakPoints < MAXIMUM_BREAKPOINTS || MemoryBpxFound == true) //found memory breakpoint
{
if(BreakPointBuffer[MaximumBreakPoints].BreakPointActive == UE_BPXACTIVE) //memory breakpoint is active
{
hActiveThread = OpenThread(THREAD_GET_CONTEXT+THREAD_SET_CONTEXT+THREAD_QUERY_INFORMATION, false, DBGEvent.dwThreadId);
myDBGContext.ContextFlags = CONTEXT_ALL;
GetThreadContext(hActiveThread, &myDBGContext);
DBGCode = DBG_CONTINUE;
MemoryBpxCallBack = BreakPointBuffer[MaximumBreakPoints].ExecuteCallBack;
if(BreakPointBuffer[MaximumBreakPoints].BreakPointType == UE_MEMORY) //READ|WRITE|EXECUTE
{
if(BreakPointBuffer[MaximumBreakPoints].MemoryBpxRestoreOnHit != 1)
{
RemoveMemoryBPX(BreakPointBuffer[MaximumBreakPoints].BreakPointAddress, BreakPointBuffer[MaximumBreakPoints].BreakPointSize);
}
else
{
if(!(myDBGContext.EFlags & 0x100))
{
myDBGContext.EFlags = myDBGContext.EFlags ^ 0x100;
}
SetThreadContext(hActiveThread, &myDBGContext);
ResetMemBPXAddress = BreakPointBuffer[MaximumBreakPoints].BreakPointAddress;
ResetMemBPXSize = BreakPointBuffer[MaximumBreakPoints].BreakPointSize;
ResetMemBPX = true;
}
myCustomHandler = (fCustomHandler)(MemoryBpxCallBack);
__try
{
myCustomHandler((void*)bpaddr);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
}
else if(BreakPointBuffer[MaximumBreakPoints].BreakPointType == UE_MEMORY_READ) //READ
{
if(BreakPointBuffer[MaximumBreakPoints].MemoryBpxRestoreOnHit != 1)
{
if(DBGEvent.u.Exception.ExceptionRecord.ExceptionInformation[0] == 0) //read operation
RemoveMemoryBPX(BreakPointBuffer[MaximumBreakPoints].BreakPointAddress, BreakPointBuffer[MaximumBreakPoints].BreakPointSize);
}
else
{
if(!(myDBGContext.EFlags & 0x100))
{
myDBGContext.EFlags = myDBGContext.EFlags ^ 0x100;
}
SetThreadContext(hActiveThread, &myDBGContext);
ResetMemBPXAddress = BreakPointBuffer[MaximumBreakPoints].BreakPointAddress;
ResetMemBPXSize = BreakPointBuffer[MaximumBreakPoints].BreakPointSize;
ResetMemBPX = true;
}
if(DBGEvent.u.Exception.ExceptionRecord.ExceptionInformation[0] == 0) //read operation
{
myCustomHandler = (fCustomHandler)(MemoryBpxCallBack);
__try
{
myCustomHandler((void*)bpaddr);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
}
else //no read operation, restore breakpoint
{
if(!(myDBGContext.EFlags & 0x100))
{
myDBGContext.EFlags = myDBGContext.EFlags ^ 0x100;
}
SetThreadContext(hActiveThread, &myDBGContext);
ResetMemBPXAddress = BreakPointBuffer[MaximumBreakPoints].BreakPointAddress;
ResetMemBPXSize = BreakPointBuffer[MaximumBreakPoints].BreakPointSize;
ResetMemBPX = true;
}
}
else if(BreakPointBuffer[MaximumBreakPoints].BreakPointType == UE_MEMORY_WRITE) //WRITE
{
if(BreakPointBuffer[MaximumBreakPoints].MemoryBpxRestoreOnHit != 1) //remove breakpoint
{
if(DBGEvent.u.Exception.ExceptionRecord.ExceptionInformation[0] == 1) //write operation
RemoveMemoryBPX(BreakPointBuffer[MaximumBreakPoints].BreakPointAddress, BreakPointBuffer[MaximumBreakPoints].BreakPointSize);
}
else //restore breakpoint after trap flag
{
if(!(myDBGContext.EFlags & 0x100))
{
myDBGContext.EFlags = myDBGContext.EFlags ^ 0x100;
}
SetThreadContext(hActiveThread, &myDBGContext);
ResetMemBPXAddress = BreakPointBuffer[MaximumBreakPoints].BreakPointAddress;
ResetMemBPXSize = BreakPointBuffer[MaximumBreakPoints].BreakPointSize;
ResetMemBPX = true;
}
if(DBGEvent.u.Exception.ExceptionRecord.ExceptionInformation[0] == 1) //write operation
{
myCustomHandler = (fCustomHandler)(MemoryBpxCallBack);
__try
{
myCustomHandler((void*)bpaddr);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
}
else
{
if(!(myDBGContext.EFlags & 0x100))
{
myDBGContext.EFlags = myDBGContext.EFlags ^ 0x100;
}
SetThreadContext(hActiveThread, &myDBGContext);
ResetMemBPXAddress = BreakPointBuffer[MaximumBreakPoints].BreakPointAddress;
ResetMemBPXSize = BreakPointBuffer[MaximumBreakPoints].BreakPointSize;
ResetMemBPX = true;
}
}
else if(BreakPointBuffer[MaximumBreakPoints].BreakPointType == UE_MEMORY_EXECUTE) //EXECUTE
{
if(BreakPointBuffer[MaximumBreakPoints].MemoryBpxRestoreOnHit != 1)
{
if(DBGEvent.u.Exception.ExceptionRecord.ExceptionInformation[0] == 0 && (ULONG_PTR)DBGEvent.u.Exception.ExceptionRecord.ExceptionAddress >= BreakPointBuffer[MaximumBreakPoints].BreakPointAddress && (ULONG_PTR)DBGEvent.u.Exception.ExceptionRecord.ExceptionAddress <= BreakPointBuffer[MaximumBreakPoints].BreakPointAddress + BreakPointBuffer[MaximumBreakPoints].BreakPointSize) //read operation
RemoveMemoryBPX(BreakPointBuffer[MaximumBreakPoints].BreakPointAddress, BreakPointBuffer[MaximumBreakPoints].BreakPointSize);
}
else
{
if(!(myDBGContext.EFlags & 0x100))
{
myDBGContext.EFlags = myDBGContext.EFlags ^ 0x100;
}
SetThreadContext(hActiveThread, &myDBGContext);
ResetMemBPXAddress = BreakPointBuffer[MaximumBreakPoints].BreakPointAddress;
ResetMemBPXSize = BreakPointBuffer[MaximumBreakPoints].BreakPointSize;
ResetMemBPX = true;
}
if(DBGEvent.u.Exception.ExceptionRecord.ExceptionInformation[0] == 0 && (ULONG_PTR)DBGEvent.u.Exception.ExceptionRecord.ExceptionAddress >= BreakPointBuffer[MaximumBreakPoints].BreakPointAddress && (ULONG_PTR)DBGEvent.u.Exception.ExceptionRecord.ExceptionAddress <= BreakPointBuffer[MaximumBreakPoints].BreakPointAddress + BreakPointBuffer[MaximumBreakPoints].BreakPointSize) //read operation
{
myCustomHandler = (fCustomHandler)(MemoryBpxCallBack);
__try
{
myCustomHandler((void*)bpaddr);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
}
else //no execute operation, restore breakpoint
{
if(!(myDBGContext.EFlags & 0x100))
{
myDBGContext.EFlags = myDBGContext.EFlags ^ 0x100;
}
SetThreadContext(hActiveThread, &myDBGContext);
ResetMemBPXAddress = BreakPointBuffer[MaximumBreakPoints].BreakPointAddress;
ResetMemBPXSize = BreakPointBuffer[MaximumBreakPoints].BreakPointSize;
ResetMemBPX = true;
}
}
EngineCloseHandle(hActiveThread);
}
else
{
DBGCode = DBG_EXCEPTION_NOT_HANDLED;
}
}
else //no memory breakpoint found
{
DBGCode = DBG_EXCEPTION_NOT_HANDLED;
}
//debuggee generated GUARD_PAGE exception
if(DBGCode==DBG_EXCEPTION_NOT_HANDLED)
{
//TODO: restore memory breakpoint?
if(DBGCustomHandler->chPageGuard != NULL)
{
myCustomHandler = (fCustomHandler)((LPVOID)DBGCustomHandler->chPageGuard);
__try
{
myCustomHandler(&DBGEvent.u.Exception.ExceptionRecord);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DBGCustomHandler->chPageGuard = NULL;
}
}
}
}
//NOTE: access violation exception
else if(DBGEvent.u.Exception.ExceptionRecord.ExceptionCode == STATUS_ACCESS_VIOLATION)
{
DBGCode = DBG_EXCEPTION_NOT_HANDLED;
if(DBGCustomHandler->chAccessViolation != NULL)
{
myCustomHandler = (fCustomHandler)((LPVOID)DBGCustomHandler->chAccessViolation);
__try
{
myCustomHandler(&DBGEvent.u.Exception.ExceptionRecord);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DBGCustomHandler->chAccessViolation = NULL;
}
}
}
//NOTE: illegal instruction exception
else if(DBGEvent.u.Exception.ExceptionRecord.ExceptionCode == STATUS_ILLEGAL_INSTRUCTION)
{
//UD2 breakpoint
MaximumBreakPoints = 0;
for(MaximumBreakPoints = 0; MaximumBreakPoints < BreakPointSetCount; MaximumBreakPoints++)
{
if(BreakPointBuffer[MaximumBreakPoints].BreakPointAddress == (ULONG_PTR)DBGEvent.u.Exception.ExceptionRecord.ExceptionAddress)
{
break;
}
}
if(BreakPointBuffer[MaximumBreakPoints].BreakPointActive == UE_BPXACTIVE && MaximumBreakPoints < MAXIMUM_BREAKPOINTS)
{
VirtualQueryEx(dbgProcessInformation.hProcess, (LPVOID)BreakPointBuffer[MaximumBreakPoints].BreakPointAddress, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
OldProtect = MemInfo.AllocationProtect;
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)BreakPointBuffer[MaximumBreakPoints].BreakPointAddress, BreakPointBuffer[MaximumBreakPoints].BreakPointSize, PAGE_EXECUTE_READWRITE, &OldProtect);
if(BreakPointBuffer[MaximumBreakPoints].BreakPointActive == UE_BPXACTIVE && (BreakPointBuffer[MaximumBreakPoints].BreakPointType == UE_BREAKPOINT || BreakPointBuffer[MaximumBreakPoints].BreakPointType == UE_SINGLESHOOT) && (BreakPointBuffer[MaximumBreakPoints].NumberOfExecutions == -1 || BreakPointBuffer[MaximumBreakPoints].NumberOfExecutions > 0))
{
if(WriteProcessMemory(dbgProcessInformation.hProcess, (LPVOID)BreakPointBuffer[MaximumBreakPoints].BreakPointAddress, &BreakPointBuffer[MaximumBreakPoints].OriginalByte[0], BreakPointBuffer[MaximumBreakPoints].BreakPointSize, &NumberOfBytesReadWritten))
{
DBGCode = DBG_CONTINUE;
hActiveThread = OpenThread(THREAD_GET_CONTEXT+THREAD_SET_CONTEXT+THREAD_QUERY_INFORMATION, false, DBGEvent.dwThreadId);
myDBGContext.ContextFlags = CONTEXT_ALL;
GetThreadContext(hActiveThread, &myDBGContext);
if(BreakPointBuffer[MaximumBreakPoints].BreakPointType != UE_SINGLESHOOT)
{
if(!(myDBGContext.EFlags & 0x100))
{
myDBGContext.EFlags = myDBGContext.EFlags ^ 0x100;
}
}
if(!(myDBGContext.EFlags & 0x10000))
{
myDBGContext.EFlags = myDBGContext.EFlags ^ 0x10000;
}
SetThreadContext(hActiveThread, &myDBGContext);
EngineCloseHandle(hActiveThread);
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)BreakPointBuffer[MaximumBreakPoints].BreakPointAddress, BreakPointBuffer[MaximumBreakPoints].BreakPointSize, OldProtect, &OldProtect);
myCustomBreakPoint = (fCustomBreakPoint)((LPVOID)BreakPointBuffer[MaximumBreakPoints].ExecuteCallBack);
if(BreakPointBuffer[MaximumBreakPoints].NumberOfExecutions != -1 && BreakPointBuffer[MaximumBreakPoints].NumberOfExecutions != 0)
{
BreakPointBuffer[MaximumBreakPoints].NumberOfExecutions--;
}
if(BreakPointBuffer[MaximumBreakPoints].CmpCondition != UE_CMP_NOCONDITION)
{
CompareResult = false;
CmpValue1 = (ULONG_PTR)GetContextData((DWORD)BreakPointBuffer[MaximumBreakPoints].CmpRegister);
myCustomBreakPoint = (fCustomBreakPoint)((LPVOID)BreakPointBuffer[MaximumBreakPoints].CompareCallBack);
if(BreakPointBuffer[MaximumBreakPoints].CmpCondition == UE_CMP_EQUAL)
{
CmpValue2 = BreakPointBuffer[MaximumBreakPoints].CmpValue;
if(CmpValue1 == CmpValue2)
{
CompareResult = true;
}
}
else if(BreakPointBuffer[MaximumBreakPoints].CmpCondition == UE_CMP_NOTEQUAL)
{
CmpValue2 = BreakPointBuffer[MaximumBreakPoints].CmpValue;
if(CmpValue1 != CmpValue2)
{
CompareResult = true;
}
}
else if(BreakPointBuffer[MaximumBreakPoints].CmpCondition == UE_CMP_GREATER)
{
CmpValue2 = BreakPointBuffer[MaximumBreakPoints].CmpValue;
if(CmpValue1 > CmpValue2)
{
CompareResult = true;
}
}
else if(BreakPointBuffer[MaximumBreakPoints].CmpCondition == UE_CMP_GREATEROREQUAL)
{
CmpValue2 = BreakPointBuffer[MaximumBreakPoints].CmpValue;
if(CmpValue1 >= CmpValue2)
{
CompareResult = true;
}
}
else if(BreakPointBuffer[MaximumBreakPoints].CmpCondition == UE_CMP_LOWER)
{
CmpValue2 = BreakPointBuffer[MaximumBreakPoints].CmpValue;
if(CmpValue1 < CmpValue2)
{
CompareResult = true;
}
}
else if(BreakPointBuffer[MaximumBreakPoints].CmpCondition == UE_CMP_LOWEROREQUAL)
{
CmpValue2 = BreakPointBuffer[MaximumBreakPoints].CmpValue;
if(CmpValue1 <= CmpValue2)
{
CompareResult = true;
}
}
else if(BreakPointBuffer[MaximumBreakPoints].CmpCondition == UE_CMP_REG_EQUAL)
{
CmpValue2 = (ULONG_PTR)GetContextData((DWORD)BreakPointBuffer[MaximumBreakPoints].CmpValue);
if(CmpValue1 == CmpValue2)
{
CompareResult = true;
}
}
else if(BreakPointBuffer[MaximumBreakPoints].CmpCondition == UE_CMP_REG_NOTEQUAL)
{
CmpValue2 = (ULONG_PTR)GetContextData((DWORD)BreakPointBuffer[MaximumBreakPoints].CmpValue);
if(CmpValue1 != CmpValue2)
{
CompareResult = true;
}
}
else if(BreakPointBuffer[MaximumBreakPoints].CmpCondition == UE_CMP_REG_GREATER)
{
CmpValue2 = (ULONG_PTR)GetContextData((DWORD)BreakPointBuffer[MaximumBreakPoints].CmpValue);
if(CmpValue1 > CmpValue2)
{
CompareResult = true;
}
}
else if(BreakPointBuffer[MaximumBreakPoints].CmpCondition == UE_CMP_REG_GREATEROREQUAL)
{
CmpValue2 = (ULONG_PTR)GetContextData((DWORD)BreakPointBuffer[MaximumBreakPoints].CmpValue);
if(CmpValue1 >= CmpValue2)
{
CompareResult = true;
}
}
else if(BreakPointBuffer[MaximumBreakPoints].CmpCondition == UE_CMP_REG_LOWER)
{
CmpValue2 = (ULONG_PTR)GetContextData((DWORD)BreakPointBuffer[MaximumBreakPoints].CmpValue);
if(CmpValue1 < CmpValue2)
{
CompareResult = true;
}
}
else if(BreakPointBuffer[MaximumBreakPoints].CmpCondition == UE_CMP_REG_LOWEROREQUAL)
{
CmpValue2 = (ULONG_PTR)GetContextData((DWORD)BreakPointBuffer[MaximumBreakPoints].CmpValue);
if(CmpValue1 <= CmpValue2)
{
CompareResult = true;
}
}
if(CompareResult)
{
__try
{
myCustomBreakPoint();
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
}
}
else
{
__try
{
myCustomBreakPoint();
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
}
if(BreakPointBuffer[MaximumBreakPoints].BreakPointType != UE_SINGLESHOOT)
{
DisableBPX((ULONG_PTR)BreakPointBuffer[MaximumBreakPoints].BreakPointAddress);
ResetBPXSize = BreakPointBuffer[MaximumBreakPoints].BreakPointSize - 1;
ResetBPXAddressTo = (ULONG_PTR)BreakPointBuffer[MaximumBreakPoints].BreakPointAddress;
ResetBPX = true;
}
else
{
DeleteBPX((ULONG_PTR)BreakPointBuffer[MaximumBreakPoints].BreakPointAddress);
ResetBPXSize = BreakPointBuffer[MaximumBreakPoints].BreakPointSize - 1;
ResetBPXAddressTo = NULL;
ResetBPX = false;
}
}
else
{
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)BreakPointBuffer[MaximumBreakPoints].BreakPointAddress, BreakPointBuffer[MaximumBreakPoints].BreakPointSize, OldProtect, &OldProtect);
DBGCode = DBG_CONTINUE;
}
}
else
{
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)BreakPointBuffer[MaximumBreakPoints].BreakPointAddress, BreakPointBuffer[MaximumBreakPoints].BreakPointSize, OldProtect, &OldProtect);
DBGCode = DBG_EXCEPTION_NOT_HANDLED;
}
}
else
{
DBGCode = DBG_EXCEPTION_NOT_HANDLED;
}
//application-generated exception
if(DBGCode==DBG_EXCEPTION_NOT_HANDLED)
{
if(DBGCustomHandler->chIllegalInstruction != NULL)
{
myCustomHandler = (fCustomHandler)((LPVOID)DBGCustomHandler->chIllegalInstruction);
__try
{
myCustomHandler(&DBGEvent.u.Exception.ExceptionRecord);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DBGCustomHandler->chIllegalInstruction = NULL;
}
}
}
}
//NOTE: uncontinuable exception
else if(DBGEvent.u.Exception.ExceptionRecord.ExceptionCode == STATUS_NONCONTINUABLE_EXCEPTION)
{
DBGCode = DBG_EXCEPTION_NOT_HANDLED;
if(DBGCustomHandler->chNonContinuableException != NULL)
{
myCustomHandler = (fCustomHandler)((LPVOID)DBGCustomHandler->chNonContinuableException);
__try
{
myCustomHandler(&DBGEvent.u.Exception.ExceptionRecord);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DBGCustomHandler->chNonContinuableException = NULL;
}
}
}
//NOTE: array bounds exception
else if(DBGEvent.u.Exception.ExceptionRecord.ExceptionCode == STATUS_ARRAY_BOUNDS_EXCEEDED)
{
DBGCode = DBG_EXCEPTION_NOT_HANDLED;
if(DBGCustomHandler->chArrayBoundsException != NULL)
{
myCustomHandler = (fCustomHandler)((LPVOID)DBGCustomHandler->chArrayBoundsException);
__try
{
myCustomHandler(&DBGEvent.u.Exception.ExceptionRecord);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DBGCustomHandler->chArrayBoundsException = NULL;
}
}
}
//NOTE: float denormal operand exception
else if(DBGEvent.u.Exception.ExceptionRecord.ExceptionCode == STATUS_FLOAT_DENORMAL_OPERAND)
{
DBGCode = DBG_EXCEPTION_NOT_HANDLED;
if(DBGCustomHandler->chFloatDenormalOperand != NULL)
{
myCustomHandler = (fCustomHandler)((LPVOID)DBGCustomHandler->chFloatDenormalOperand);
__try
{
myCustomHandler(&DBGEvent.u.Exception.ExceptionRecord);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DBGCustomHandler->chFloatDenormalOperand = NULL;
}
}
}
//NOTE: float devide by zero exception
else if(DBGEvent.u.Exception.ExceptionRecord.ExceptionCode == STATUS_FLOAT_DIVIDE_BY_ZERO)
{
DBGCode = DBG_EXCEPTION_NOT_HANDLED;
if(DBGCustomHandler->chFloatDevideByZero != NULL)
{
myCustomHandler = (fCustomHandler)((LPVOID)DBGCustomHandler->chFloatDevideByZero);
__try
{
myCustomHandler(&DBGEvent.u.Exception.ExceptionRecord);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DBGCustomHandler->chFloatDevideByZero = NULL;
}
}
}
//NOTE: devide by zero exception
else if(DBGEvent.u.Exception.ExceptionRecord.ExceptionCode == STATUS_INTEGER_DIVIDE_BY_ZERO)
{
DBGCode = DBG_EXCEPTION_NOT_HANDLED;
if(DBGCustomHandler->chIntegerDevideByZero != NULL)
{
myCustomHandler = (fCustomHandler)((LPVOID)DBGCustomHandler->chIntegerDevideByZero);
__try
{
myCustomHandler(&DBGEvent.u.Exception.ExceptionRecord);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DBGCustomHandler->chIntegerDevideByZero = NULL;
}
}
}
//NOTE: integer overflow exception
else if(DBGEvent.u.Exception.ExceptionRecord.ExceptionCode == STATUS_INTEGER_OVERFLOW)
{
DBGCode = DBG_EXCEPTION_NOT_HANDLED;
if(DBGCustomHandler->chIntegerOverflow != NULL)
{
myCustomHandler = (fCustomHandler)((LPVOID)DBGCustomHandler->chIntegerOverflow);
__try
{
myCustomHandler(&DBGEvent.u.Exception.ExceptionRecord);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DBGCustomHandler->chIntegerOverflow = NULL;
}
}
}
//NOTE: privileged instruction exception
else if(DBGEvent.u.Exception.ExceptionRecord.ExceptionCode == STATUS_PRIVILEGED_INSTRUCTION)
{
DBGCode = DBG_EXCEPTION_NOT_HANDLED;
if(DBGCustomHandler->chPrivilegedInstruction != NULL)
{
myCustomHandler = (fCustomHandler)((LPVOID)DBGCustomHandler->chPrivilegedInstruction);
__try
{
myCustomHandler(&DBGEvent.u.Exception.ExceptionRecord);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DBGCustomHandler->chPrivilegedInstruction = NULL;
}
}
}
//general unhandled exception callback
if(DBGCode==DBG_EXCEPTION_NOT_HANDLED)
{
if(DBGCustomHandler->chUnhandledException != NULL)
{
myCustomHandler = (fCustomHandler)((LPVOID)DBGCustomHandler->chUnhandledException);
__try
{
myCustomHandler(&DBGEvent.u.Exception.ExceptionRecord);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DBGCustomHandler->chUnhandledException = NULL;
}
}
}
//general after-exception callback (includes debugger exceptions)
if(DBGCustomHandler->chAfterException != NULL)
{
myCustomHandler = (fCustomHandler)((LPVOID)DBGCustomHandler->chAfterException);
__try
{
myCustomHandler(&DBGEvent.u.Exception.ExceptionRecord);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DBGCustomHandler->chAfterException = NULL;
}
}
}
if(engineResumeProcessIfNoThreadIsActive)
{
if(!ThreaderIsAnyThreadActive())
{
ThreaderResumeProcess();
}
}
if(!ContinueDebugEvent(DBGEvent.dwProcessId, DBGEvent.dwThreadId, DBGCode)) //continue debugging
{
break;
}
}
if(!SecondChance) //debugger didn't close with a second chance exception (normal exit)
{
RtlMoveMemory(&TerminateDBGEvent, &DBGEvent, sizeof DEBUG_EVENT);
}
ForceClose();
engineFileIsBeingDebugged = false;
if(engineExecutePluginCallBack)
{
EngineExecutePluginDebugCallBack(&DBGEvent, UE_PLUGIN_CALL_REASON_POSTDEBUG);
}
}
__declspec(dllexport) void TITCALL SetDebugLoopTimeOut(DWORD TimeOut)
{
if(TimeOut == NULL)
{
TimeOut = INFINITE;
}
engineWaitForDebugEventTimeOut = TimeOut;
}
__declspec(dllexport) void TITCALL SetNextDbgContinueStatus(DWORD SetDbgCode)
{
if(SetDbgCode != DBG_CONTINUE)
{
DBGCode = DBG_EXCEPTION_NOT_HANDLED;
}
else
{
DBGCode = DBG_CONTINUE;
}
}
__declspec(dllexport) void TITCALL DebugLoopEx(DWORD TimeOut)
{
SetDebugLoopTimeOut(TimeOut);
DebugLoop();
SetDebugLoopTimeOut(INFINITE);
}
__declspec(dllexport) bool TITCALL AttachDebugger(DWORD ProcessId, bool KillOnExit, LPVOID DebugInfo, LPVOID CallBack)
{
typedef void(WINAPI *fDebugSetProcessKillOnExit)(bool KillExitingDebugee);
fDebugSetProcessKillOnExit myDebugSetProcessKillOnExit;
LPVOID funcDebugSetProcessKillOnExit = NULL;
if(ProcessId != NULL && dbgProcessInformation.hProcess == NULL)
{
RtlZeroMemory(&BreakPointBuffer, sizeof BreakPointBuffer);
if(DebugActiveProcess(ProcessId))
{
if(KillOnExit)
{
funcDebugSetProcessKillOnExit = GetProcAddress(GetModuleHandleA("kernel32.dll"), "DebugSetProcessKillOnExit");
if(funcDebugSetProcessKillOnExit != NULL)
{
myDebugSetProcessKillOnExit = (fDebugSetProcessKillOnExit)(funcDebugSetProcessKillOnExit);
myDebugSetProcessKillOnExit(KillOnExit);
}
}
BreakPointSetCount = 0;
engineDebuggingDLL = false;
engineAttachedToProcess = true;
engineAttachedProcessCallBack = (ULONG_PTR)CallBack;
engineAttachedProcessDebugInfo = DebugInfo;
dbgProcessInformation.dwProcessId = ProcessId;
DebugLoop();
engineAttachedToProcess = false;
engineAttachedProcessCallBack = NULL;
return(true);
}
}
else
{
return(false);
}
return(false);
}
__declspec(dllexport) bool TITCALL DetachDebugger(DWORD ProcessId)
{
typedef bool(WINAPI *fDebugActiveProcessStop)(DWORD dwProcessId);
fDebugActiveProcessStop myDebugActiveProcessStop;
LPVOID funcDebugActiveProcessStop = NULL;
bool FuncReturn = false;
if(ProcessId != NULL)
{
funcDebugActiveProcessStop = GetProcAddress(GetModuleHandleA("kernel32.dll"), "DebugActiveProcessStop");
if(funcDebugActiveProcessStop != NULL)
{
myDebugActiveProcessStop = (fDebugActiveProcessStop)(funcDebugActiveProcessStop);
FuncReturn = myDebugActiveProcessStop(ProcessId);
engineProcessIsNowDetached = true;
Sleep(250);
}
engineAttachedToProcess = false;
if(FuncReturn)
{
return(true);
}
else
{
return(false);
}
}
return(false);
}
__declspec(dllexport) bool TITCALL DetachDebuggerEx(DWORD ProcessId)
{
HANDLE hActiveThread;
CONTEXT myDBGContext;
PTHREAD_ITEM_DATA hListThreadPtr = (PTHREAD_ITEM_DATA)hListThread;
if(hListThreadPtr != NULL)
{
ThreaderPauseProcess();
while(hListThreadPtr->hThread != NULL)
{
hActiveThread = OpenThread(THREAD_GET_CONTEXT+THREAD_SET_CONTEXT+THREAD_QUERY_INFORMATION, false, hListThreadPtr->dwThreadId);
myDBGContext.ContextFlags = CONTEXT_ALL;
GetThreadContext(hActiveThread, &myDBGContext);
if((myDBGContext.EFlags & 0x100))
{
myDBGContext.EFlags = myDBGContext.EFlags ^ 0x100;
}
if(!(myDBGContext.EFlags & 0x10000))
{
myDBGContext.EFlags = myDBGContext.EFlags ^ 0x10000;
}
SetThreadContext(hActiveThread, &myDBGContext);
EngineCloseHandle(hActiveThread);
hListThreadPtr = (PTHREAD_ITEM_DATA)((ULONG_PTR)hListThreadPtr + sizeof THREAD_ITEM_DATA);
}
ContinueDebugEvent(DBGEvent.dwProcessId, DBGEvent.dwThreadId, DBG_CONTINUE);
ThreaderResumeProcess();
return(DetachDebugger(ProcessId));
}
else
{
return(false);
}
}
__declspec(dllexport) void TITCALL AutoDebugEx(char* szFileName, bool ReserveModuleBase, char* szCommandLine, char* szCurrentFolder, DWORD TimeOut, LPVOID EntryCallBack)
{
wchar_t* PtrUniFileName = NULL;
wchar_t uniFileName[MAX_PATH] = {};
wchar_t* PtrUniCommandLine = NULL;
wchar_t uniCommandLine[MAX_PATH] = {};
wchar_t* PtrUniCurrentFolder = NULL;
wchar_t uniCurrentFolder[MAX_PATH] = {};
if(szFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
MultiByteToWideChar(CP_ACP, NULL, szCommandLine, lstrlenA(szCommandLine)+1, uniCommandLine, sizeof(uniCommandLine)/(sizeof(uniCommandLine[0])));
MultiByteToWideChar(CP_ACP, NULL, szCurrentFolder, lstrlenA(szCurrentFolder)+1, uniCurrentFolder, sizeof(uniCurrentFolder)/(sizeof(uniCurrentFolder[0])));
if(szFileName != NULL)
{
PtrUniFileName = &uniFileName[0];
}
if(szCommandLine != NULL)
{
PtrUniCommandLine = &uniCommandLine[0];
}
if(szCurrentFolder != NULL)
{
PtrUniCurrentFolder = &uniCurrentFolder[0];
}
return(AutoDebugExW(PtrUniFileName, ReserveModuleBase, PtrUniCommandLine, PtrUniCurrentFolder, TimeOut, EntryCallBack));
}
}
__declspec(dllexport) void TITCALL AutoDebugExW(wchar_t* szFileName, bool ReserveModuleBase, wchar_t* szCommandLine, wchar_t* szCurrentFolder, DWORD TimeOut, LPVOID EntryCallBack)
{
engineReserveModuleBase = NULL;
DWORD ThreadId;
DWORD ExitCode = 0;
HANDLE hSecondThread;
bool FileIsDll = false;
#if !defined(_WIN64)
PE32Struct PEStructure;
#else
PE64Struct PEStructure;
#endif
if(TimeOut == NULL)
{
TimeOut = INFINITE;
}
if(szFileName != NULL)
{
RtlZeroMemory(&engineExpertDebug, sizeof ExpertDebug);
engineExpertDebug.ExpertModeActive = true;
engineExpertDebug.szFileName = szFileName;
engineExpertDebug.szCommandLine = szCommandLine;
engineExpertDebug.szCurrentFolder = szCurrentFolder;
engineExpertDebug.ReserveModuleBase = ReserveModuleBase;
engineExpertDebug.EntryCallBack = EntryCallBack;
GetPE32DataExW(szFileName, (LPVOID)&PEStructure);
if(PEStructure.Characteristics & 0x2000)
{
FileIsDll = true;
}
SetDebugLoopTimeOut(TimeOut);
hSecondThread = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)DebugLoopInSecondThread, (LPVOID)FileIsDll, NULL, &ThreadId);
WaitForSingleObject(hSecondThread, INFINITE);
if(GetExitCodeThread(hSecondThread, &ExitCode))
{
if(ExitCode == -1)
{
ForceClose();
}
}
RtlZeroMemory(&engineExpertDebug, sizeof ExpertDebug);
SetDebugLoopTimeOut(INFINITE);
}
}
__declspec(dllexport) bool TITCALL IsFileBeingDebugged()
{
return(engineFileIsBeingDebugged);
}
__declspec(dllexport) void TITCALL SetErrorModel(bool DisplayErrorMessages)
{
if(DisplayErrorMessages)
{
SetErrorMode(NULL);
}
else
{
SetErrorMode(SEM_FAILCRITICALERRORS);
}
}
// Global.FindOEP.functions:
void GenericOEPVirtualProtectHit()
{
PBreakPointDetail bpxList = (PBreakPointDetail)BreakPointBuffer;
MEMORY_BASIC_INFORMATION MemInfo;
DWORD MaximumBreakPoints = 0;
DWORD NewProtect = 0;
DWORD OldProtect = 0;
while(MaximumBreakPoints < MAXIMUM_BREAKPOINTS)
{
bpxList = (PBreakPointDetail)((ULONG_PTR)bpxList + sizeof BreakPointDetail);
if(bpxList->BreakPointType == UE_MEMORY && bpxList->BreakPointActive == UE_BPXACTIVE)
{
VirtualQueryEx(dbgProcessInformation.hProcess, (LPVOID)bpxList->BreakPointAddress, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
OldProtect = MemInfo.Protect;
if(!(OldProtect & PAGE_GUARD))
{
NewProtect = OldProtect ^ PAGE_GUARD;
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)bpxList->BreakPointAddress, bpxList->BreakPointSize, NewProtect, &OldProtect);
}
}
MaximumBreakPoints++;
}
}
void GenericOEPTraceHit()
{
char* szInstructionType;
typedef void(TITCALL *fEPCallBack)();
fEPCallBack myEPCallBack = (fEPCallBack)glbEntryTracerData.EPCallBack;
LPDEBUG_EVENT myDbgEvent = (LPDEBUG_EVENT)GetDebugData();
glbEntryTracerData.MemoryAccessedFrom = (ULONG_PTR)GetContextData(UE_CIP);
glbEntryTracerData.MemoryAccessed = myDbgEvent->u.Exception.ExceptionRecord.ExceptionInformation[1];
glbEntryTracerData.AccessType = myDbgEvent->u.Exception.ExceptionRecord.ExceptionInformation[0];
szInstructionType = (char*)DisassembleEx(dbgProcessInformation.hProcess, (void*)glbEntryTracerData.MemoryAccessedFrom, true);
StepInto(&GenericOEPTraceHited);
}
void GenericOEPTraceHited()
{
int i;
void* lpHashBuffer;
bool FakeEPDetected = false;
ULONG_PTR NumberOfBytesRW;
LPDEBUG_EVENT myDbgEvent = (LPDEBUG_EVENT)GetDebugData();
typedef void(TITCALL *fEPCallBack)();
fEPCallBack myEPCallBack = (fEPCallBack)glbEntryTracerData.EPCallBack;
PMEMORY_COMPARE_HANDLER myCmpHandler;
ULONG_PTR memBpxAddress;
ULONG_PTR memBpxSize;
DWORD originalHash;
DWORD currentHash;
if(myDbgEvent->u.Exception.ExceptionRecord.ExceptionCode == STATUS_SINGLE_STEP)
{
if(glbEntryTracerData.MemoryAccessed >= glbEntryTracerData.LoadedImageBase && glbEntryTracerData.MemoryAccessed <= glbEntryTracerData.LoadedImageBase + glbEntryTracerData.SizeOfImage)
{
for(i = 0; i < glbEntryTracerData.SectionNumber; i++)
{
if(glbEntryTracerData.MemoryAccessed >= glbEntryTracerData.SectionData[i].SectionVirtualOffset + glbEntryTracerData.LoadedImageBase && glbEntryTracerData.MemoryAccessed < glbEntryTracerData.SectionData[i].SectionVirtualOffset + glbEntryTracerData.SectionData[i].SectionVirtualSize + glbEntryTracerData.LoadedImageBase)
{
if(glbEntryTracerData.AccessType == 1)
{
glbEntryTracerData.SectionData[i].AccessedAlready = true;
}
if(glbEntryTracerData.MemoryAccessedFrom >= glbEntryTracerData.SectionData[i].SectionVirtualOffset + glbEntryTracerData.LoadedImageBase && glbEntryTracerData.MemoryAccessedFrom <= glbEntryTracerData.SectionData[i].SectionVirtualOffset + glbEntryTracerData.SectionData[i].SectionVirtualSize + glbEntryTracerData.LoadedImageBase)
{
if(i != glbEntryTracerData.OriginalEntryPointNum)
{
glbEntryTracerData.SectionData[i].AccessedAlready = true;
}
lpHashBuffer = VirtualAlloc(NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE);
memBpxAddress = (glbEntryTracerData.MemoryAccessed / 0x1000) * 0x1000;
memBpxSize = glbEntryTracerData.SectionData[i].SectionVirtualOffset + glbEntryTracerData.SectionData[i].SectionVirtualSize + glbEntryTracerData.LoadedImageBase - memBpxAddress;
if(memBpxSize > 0x1000)
{
memBpxSize = 0x1000;
}
if(ReadProcessMemory(dbgProcessInformation.hProcess, (void*)(memBpxAddress), lpHashBuffer, memBpxSize, &NumberOfBytesRW))
{
currentHash = EngineHashMemory((char*)lpHashBuffer, (DWORD)memBpxSize, NULL);
originalHash = EngineHashMemory((char*)((ULONG_PTR)glbEntryTracerData.SectionData[i].AllocatedSection + memBpxAddress - glbEntryTracerData.LoadedImageBase - glbEntryTracerData.SectionData[i].SectionVirtualOffset), (DWORD)memBpxSize, NULL);
if(ReadProcessMemory(dbgProcessInformation.hProcess, (void*)(glbEntryTracerData.CurrentIntructionPointer), lpHashBuffer, MAXIMUM_INSTRUCTION_SIZE, &NumberOfBytesRW))
{
myCmpHandler = (PMEMORY_COMPARE_HANDLER)(lpHashBuffer);
if(myCmpHandler->Array.bArrayEntry[0] == 0xC3) // RET
{
FakeEPDetected = true;
}
else if(myCmpHandler->Array.bArrayEntry[0] == 0x33 && myCmpHandler->Array.bArrayEntry[1] == 0xC0 && myCmpHandler->Array.bArrayEntry[2] == 0xC3) // XOR EAX,EAX; RET
{
FakeEPDetected = true;
}
}
VirtualFree(lpHashBuffer, NULL, MEM_RELEASE);
if(currentHash != originalHash && glbEntryTracerData.SectionData[i].AccessedAlready == true && i != glbEntryTracerData.OriginalEntryPointNum && FakeEPDetected == false)
{
__try
{
if(glbEntryTracerData.EPCallBack != NULL)
{
glbEntryTracerData.CurrentIntructionPointer = (ULONG_PTR)GetContextData(UE_CIP);
SetContextData(UE_CIP, glbEntryTracerData.MemoryAccessedFrom);
DeleteAPIBreakPoint("kernel32.dll", "VirtualProtect", UE_APIEND);
RemoveAllBreakPoints(UE_OPTION_REMOVEALL);
myEPCallBack();
SetContextData(UE_CIP, glbEntryTracerData.CurrentIntructionPointer);
}
else
{
StopDebug();
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
StopDebug();
}
}
}
}
else
{
SetMemoryBPXEx((ULONG_PTR)(glbEntryTracerData.SectionData[i].SectionVirtualOffset + glbEntryTracerData.LoadedImageBase), glbEntryTracerData.SectionData[i].SectionVirtualSize, UE_MEMORY, false, &GenericOEPTraceHit);
}
}
else
{
SetMemoryBPXEx((ULONG_PTR)(glbEntryTracerData.SectionData[i].SectionVirtualOffset + glbEntryTracerData.LoadedImageBase), glbEntryTracerData.SectionData[i].SectionVirtualSize, UE_MEMORY, false, &GenericOEPTraceHit);
}
}
}
}
else
{
StopDebug();
}
}
void GenericOEPLibraryDetailsHit()
{
int i;
bool memBreakPointSet = false;
char szModuleName[2 * MAX_PATH] = {};
#if !defined(_WIN64)
int inReg = UE_EAX;
#else
int inReg = UE_RAX;
#endif
if(GetModuleBaseNameA(dbgProcessInformation.hProcess, (HMODULE)GetContextData(inReg), szModuleName, sizeof szModuleName) > NULL)
{
if(lstrcmpiA(szModuleName, "kernel32.dll") != NULL)
{
if(glbEntryTracerData.FileIsDLL)
{
glbEntryTracerData.LoadedImageBase = (ULONG_PTR)GetDebuggedDLLBaseAddress();
}
else
{
glbEntryTracerData.LoadedImageBase = (ULONG_PTR)GetDebuggedFileBaseAddress();
}
for(i = 0; i < glbEntryTracerData.SectionNumber; i++)
{
if(glbEntryTracerData.SectionData[i].SectionAttributes & IMAGE_SCN_MEM_EXECUTE || glbEntryTracerData.SectionData[i].SectionAttributes & IMAGE_SCN_CNT_CODE)
{
SetMemoryBPXEx((ULONG_PTR)(glbEntryTracerData.SectionData[i].SectionVirtualOffset + glbEntryTracerData.LoadedImageBase), glbEntryTracerData.SectionData[i].SectionVirtualSize, UE_MEMORY, false, &GenericOEPTraceHit);
memBreakPointSet = true;
}
}
if(!memBreakPointSet)
{
StopDebug();
}
else
{
DeleteAPIBreakPoint("kernel32.dll", "GetModuleHandleW", UE_APIEND);
DeleteAPIBreakPoint("kernel32.dll", "LoadLibraryExW", UE_APIEND);
}
}
}
}
void GenericOEPTraceInit()
{
int i;
void* lpHashBuffer;
ULONG_PTR NumberOfBytesRW;
typedef void(TITCALL *fInitCallBack)();
fInitCallBack myInitCallBack = (fInitCallBack)glbEntryTracerData.InitCallBack;
if(glbEntryTracerData.FileIsDLL)
{
glbEntryTracerData.LoadedImageBase = (ULONG_PTR)GetDebuggedDLLBaseAddress();
}
else
{
glbEntryTracerData.LoadedImageBase = (ULONG_PTR)GetDebuggedFileBaseAddress();
}
for(i = 0; i < glbEntryTracerData.SectionNumber; i++)
{
lpHashBuffer = VirtualAlloc(NULL, glbEntryTracerData.SectionData[i].SectionVirtualSize, MEM_COMMIT, PAGE_READWRITE);
if(lpHashBuffer != NULL)
{
if(ReadProcessMemory(dbgProcessInformation.hProcess, (void*)(glbEntryTracerData.SectionData[i].SectionVirtualOffset + glbEntryTracerData.LoadedImageBase), lpHashBuffer, glbEntryTracerData.SectionData[i].SectionVirtualSize, &NumberOfBytesRW))
{
glbEntryTracerData.SectionData[i].AllocatedSection = lpHashBuffer;
}
}
}
SetAPIBreakPoint("kernel32.dll", "VirtualProtect", UE_BREAKPOINT, UE_APIEND, &GenericOEPVirtualProtectHit);
SetAPIBreakPoint("kernel32.dll", "GetModuleHandleW", UE_BREAKPOINT, UE_APIEND, &GenericOEPLibraryDetailsHit);
SetAPIBreakPoint("kernel32.dll", "LoadLibraryExW", UE_BREAKPOINT, UE_APIEND, &GenericOEPLibraryDetailsHit);
if(glbEntryTracerData.InitCallBack != NULL)
{
__try
{
myInitCallBack();
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
StopDebug();
}
}
}
bool GenericOEPFileInitW(wchar_t* szFileName, LPVOID TraceInitCallBack, LPVOID CallBack)
{
int i;
#if defined(_WIN64)
PE64Struct PEStruct = {};
#else
PE32Struct PEStruct = {};
#endif
HANDLE FileHandle;
DWORD FileSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
if(MapFileExW(szFileName, UE_ACCESS_READ, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
if(GetPE32DataFromMappedFileEx(FileMapVA, &PEStruct))
{
RtlZeroMemory(&glbEntryTracerData, sizeof GenericOEPTracerData);
glbEntryTracerData.OriginalImageBase = PEStruct.ImageBase;
glbEntryTracerData.OriginalEntryPoint = PEStruct.OriginalEntryPoint;
glbEntryTracerData.SizeOfImage = PEStruct.NtSizeOfImage;
glbEntryTracerData.SectionNumber = PEStruct.SectionNumber;
glbEntryTracerData.FileIsDLL = IsFileDLL(NULL, FileMapVA);
glbEntryTracerData.OriginalEntryPointNum = GetPE32SectionNumberFromVA(FileMapVA, glbEntryTracerData.OriginalImageBase + glbEntryTracerData.OriginalEntryPoint);
for(i = 0; i < glbEntryTracerData.SectionNumber; i++)
{
glbEntryTracerData.SectionData[i].SectionVirtualOffset = (DWORD)GetPE32DataFromMappedFile(FileMapVA, i, UE_SECTIONVIRTUALOFFSET);
glbEntryTracerData.SectionData[i].SectionVirtualSize = (DWORD)GetPE32DataFromMappedFile(FileMapVA, i, UE_SECTIONVIRTUALSIZE);
if(glbEntryTracerData.SectionData[i].SectionVirtualSize % 0x1000 != 0)
{
glbEntryTracerData.SectionData[i].SectionVirtualSize = ((glbEntryTracerData.SectionData[i].SectionVirtualSize / 0x1000) + 1) * 0x1000;
}
else
{
glbEntryTracerData.SectionData[i].SectionVirtualSize = (glbEntryTracerData.SectionData[i].SectionVirtualSize / 0x1000) * 0x1000;
}
glbEntryTracerData.SectionData[i].SectionAttributes = (DWORD)GetPE32DataFromMappedFile(FileMapVA, i, UE_SECTIONFLAGS);
}
glbEntryTracerData.EPCallBack = CallBack;
glbEntryTracerData.InitCallBack = TraceInitCallBack;
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
if(glbEntryTracerData.FileIsDLL)
{
return(false);
}
else
{
return(true);
}
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
}
}
return(false);
}
// TitanEngine.FindOEP.functions:
__declspec(dllexport) void TITCALL FindOEPInit()
{
RemoveAllBreakPoints(UE_OPTION_REMOVEALL);
}
__declspec(dllexport) bool TITCALL FindOEPGenerically(char* szFileName, LPVOID TraceInitCallBack, LPVOID CallBack)
{
wchar_t uniFileName[MAX_PATH] = {};
if(szFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
return(FindOEPGenericallyW(uniFileName, TraceInitCallBack, CallBack));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL FindOEPGenericallyW(wchar_t* szFileName, LPVOID TraceInitCallBack, LPVOID CallBack)
{
int i;
if(GenericOEPFileInitW(szFileName, TraceInitCallBack, CallBack))
{
InitDebugExW(szFileName, NULL, NULL, &GenericOEPTraceInit);
DebugLoop();
for(i = 0; i < glbEntryTracerData.SectionNumber; i++)
{
VirtualFree(glbEntryTracerData.SectionData[i].AllocatedSection, NULL, MEM_RELEASE);
}
}
return(false);
}
// TitanEngine.Importer.functions:
__declspec(dllexport) void TITCALL ImporterCleanup()
{
int i = 0;
for(i = 0; i < 1000; i++)
{
if(impDLLDataList[i][0] != NULL)
{
VirtualFree((LPVOID)(impDLLDataList[i][0]), NULL, MEM_RELEASE);
impDLLDataList[i][0] = 0;
impDLLDataList[i][1] = 0;
}
if(impDLLStringList[i][0] != NULL)
{
VirtualFree((LPVOID)(impDLLStringList[i][0]), NULL, MEM_RELEASE);
impDLLStringList[i][0] = 0;
impDLLStringList[i][1] = 0;
}
impOrdinalList[i][0] = 0;
impOrdinalList[i][1] = 0;
}
}
__declspec(dllexport) void TITCALL ImporterSetImageBase(ULONG_PTR ImageBase)
{
impImageBase = ImageBase;
}
__declspec(dllexport) void TITCALL ImporterSetUnknownDelta(ULONG_PTR DeltaAddress)
{
impDeltaStart = DeltaAddress;
impDeltaCurrent = DeltaAddress;
}
__declspec(dllexport) long long TITCALL ImporterGetCurrentDelta()
{
return((ULONG_PTR)impDeltaCurrent);
}
__declspec(dllexport) void TITCALL ImporterInit(DWORD MemorySize, ULONG_PTR ImageBase)
{
impImageBase = ImageBase;
if(MemorySize != NULL)
{
impAllocSize = MemorySize;
}
else
{
impAllocSize = 20 * 1024;
}
ImporterCleanup();
impMoveIAT = false;
impDLLNumber = 0xFFFFFFFF;
impDeltaStart = NULL;
impDeltaCurrent = NULL;
}
__declspec(dllexport) void TITCALL ImporterAddNewDll(char* szDLLName, ULONG_PTR FirstThunk)
{
int CopyDummy = 1;
impDLLNumber++;
if(impDLLNumber>=1000)
{
impDLLNumber--;
return;
}
impDLLDataList[impDLLNumber][0] = (ULONG_PTR)(VirtualAlloc(NULL, 0x2000, MEM_COMMIT, PAGE_READWRITE));
impDLLDataList[impDLLNumber][1] = impDLLDataList[impDLLNumber][0];
impDLLStringList[impDLLNumber][0] = (ULONG_PTR)(VirtualAlloc(NULL, impAllocSize, MEM_COMMIT, PAGE_READWRITE));
impDLLStringList[impDLLNumber][1] = impDLLStringList[impDLLNumber][0];
RtlMoveMemory((LPVOID)(impDLLDataList[impDLLNumber][1]), &FirstThunk, sizeof ULONG_PTR);
RtlMoveMemory((LPVOID)(impDLLDataList[impDLLNumber][1] + sizeof ULONG_PTR), &FirstThunk, sizeof ULONG_PTR);
RtlMoveMemory((LPVOID)(impDLLDataList[impDLLNumber][1] + 2 * sizeof ULONG_PTR), &CopyDummy, 4);
#if !defined(_WIN64)
impDLLDataList[impDLLNumber][1] = impDLLDataList[impDLLNumber][0] + 12;
#else
impDLLDataList[impDLLNumber][1] = impDLLDataList[impDLLNumber][0] + 20;
#endif
RtlMoveMemory((LPVOID)(impDLLStringList[impDLLNumber][1]), szDLLName, lstrlenA((LPCSTR)szDLLName));
impDLLStringList[impDLLNumber][1] = impDLLStringList[impDLLNumber][1] + lstrlenA((LPCSTR)szDLLName) + 3;
if(FirstThunk == NULL && impDeltaStart != NULL)
{
impDeltaCurrent = impDeltaCurrent + sizeof ULONG_PTR;
}
}
__declspec(dllexport) void TITCALL ImporterAddNewAPI(char* szAPIName, ULONG_PTR ThunkValue)
{
int i = NULL;
int CopyDummy = NULL;
ULONG_PTR LastThunkValue = NULL;
RtlMoveMemory(&LastThunkValue, (LPVOID)(impDLLDataList[impDLLNumber][0] + sizeof ULONG_PTR), sizeof ULONG_PTR);
if(ThunkValue == NULL && impDeltaCurrent != NULL)
{
ThunkValue = impDeltaCurrent;
impDeltaCurrent = impDeltaCurrent + sizeof ULONG_PTR;
}
if(LastThunkValue != NULL && LastThunkValue != ThunkValue)
{
ImporterAddNewDll((char*)(LPVOID)impDLLStringList[impDLLNumber][0], ThunkValue);
}
else
{
if(LastThunkValue != NULL)
{
LastThunkValue = LastThunkValue + sizeof ULONG_PTR;
}
else
{
RtlMoveMemory((LPVOID)(impDLLDataList[impDLLNumber][0]), &ThunkValue, sizeof ULONG_PTR);
LastThunkValue = ThunkValue + sizeof ULONG_PTR;
}
RtlMoveMemory((LPVOID)(impDLLDataList[impDLLNumber][0] + sizeof ULONG_PTR), &LastThunkValue, sizeof ULONG_PTR);
}
CopyDummy = (int)(impDLLStringList[impDLLNumber][1] - impDLLStringList[impDLLNumber][0]);
RtlMoveMemory((LPVOID)(impDLLDataList[impDLLNumber][1]), &CopyDummy, 4);
impDLLDataList[impDLLNumber][1] = impDLLDataList[impDLLNumber][1] + 4;
if((ULONG_PTR)szAPIName > 0x10000)
{
RtlMoveMemory((LPVOID)(impDLLStringList[impDLLNumber][1] + 2), szAPIName, lstrlenA((LPCSTR)szAPIName));
impDLLStringList[impDLLNumber][1] = impDLLStringList[impDLLNumber][1] + lstrlenA((LPCSTR)szAPIName) + 3;
}
else
{
for(i = 0; i < 1000; i++)
{
if(impOrdinalList[i][0] == NULL && impOrdinalList[i][1] == NULL)
{
break;
}
}
if(i < 1000)
{
impOrdinalList[i][0] = ThunkValue;
if(sizeof ULONG_PTR == 4)
{
impOrdinalList[i][1] = (ULONG_PTR)szAPIName ^ IMAGE_ORDINAL_FLAG32;
}
else
{
impOrdinalList[i][1] = (ULONG_PTR)((ULONG_PTR)szAPIName ^ IMAGE_ORDINAL_FLAG64);
}
}
}
RtlMoveMemory(&CopyDummy, (LPVOID)(impDLLDataList[impDLLNumber][0] + 2 * sizeof ULONG_PTR), 4);
CopyDummy++;
RtlMoveMemory((LPVOID)(impDLLDataList[impDLLNumber][0] + 2 * sizeof ULONG_PTR), &CopyDummy, 4);
}
__declspec(dllexport) void TITCALL ImporterAddNewOrdinalAPI(ULONG_PTR OrdinalNumber, ULONG_PTR ThunkValue)
{
if(OrdinalNumber & IMAGE_ORDINAL_FLAG)
{
OrdinalNumber = OrdinalNumber ^ IMAGE_ORDINAL_FLAG;
ImporterAddNewAPI((char*)OrdinalNumber, ThunkValue);
}
else
{
ImporterAddNewAPI((char*)OrdinalNumber, ThunkValue);
}
}
__declspec(dllexport) long TITCALL ImporterGetAddedDllCount()
{
return(impDLLNumber + 1);
}
__declspec(dllexport) long TITCALL ImporterGetAddedAPICount()
{
int i = 0;
int CopyDummy = NULL;
DWORD DLLNumber = NULL;
long APINumber = NULL;
DLLNumber = impDLLNumber + 1;
while(DLLNumber > NULL)
{
RtlMoveMemory(&CopyDummy, (LPVOID)(impDLLDataList[i][0] + 2 * sizeof ULONG_PTR), 4);
APINumber = APINumber + CopyDummy - 1;
DLLNumber--;
i++;
}
return(APINumber);
}
__declspec(dllexport) void* TITCALL ImporterGetLastAddedDLLName()
{
if(impDLLNumber != 0xFFFFFFFF && impDLLNumber < 1000)
{
return((void*)impDLLStringList[impDLLNumber][0]);
}
else
{
return(NULL);
}
}
__declspec(dllexport) void TITCALL ImporterMoveIAT()
{
impMoveIAT = true;
}
__declspec(dllexport) bool TITCALL ImporterExportIAT(ULONG_PTR StorePlace, ULONG_PTR FileMapVA)
{
int i = 0;
int j = 0;
int x = 0;
int NumberOfAPIs = NULL;
DWORD DLLNumber = NULL;
DWORD APINumber = NULL;
PIMAGE_IMPORT_DESCRIPTOR StoreIID = (PIMAGE_IMPORT_DESCRIPTOR)StorePlace;
ULONG_PTR StorePlaceVA = (ULONG_PTR)ConvertFileOffsetToVA(FileMapVA, StorePlace, true);
ULONG_PTR OriginalStorePlaceRVA = (DWORD)(StorePlaceVA - impImageBase);
ULONG_PTR StringStorePlaceFO = StorePlace + ((impDLLNumber + 2) * sizeof IMAGE_IMPORT_DESCRIPTOR);
ULONG_PTR StringStorePlaceVA = StorePlaceVA + ((impDLLNumber + 2) * sizeof IMAGE_IMPORT_DESCRIPTOR);
ULONG_PTR ThunkStorePlaceFO = NULL;
ULONG_PTR ThunkReadValue = NULL;
LPVOID ThunkReadPlace = NULL;
ULONG_PTR FirstThunk = NULL;
ULONG_PTR CurrentThunk = NULL;
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
bool FileIs64 = false;
bool OrdinalImport = false;
if(ImporterGetAddedDllCount() > NULL)
{
if(impMoveIAT)
{
NumberOfAPIs = ImporterGetAddedAPICount() + ImporterGetAddedDllCount();
StorePlaceVA = StorePlaceVA + (NumberOfAPIs * sizeof ULONG_PTR);
StringStorePlaceFO = StringStorePlaceFO + (NumberOfAPIs * sizeof ULONG_PTR);
StringStorePlaceVA = StringStorePlaceVA + (NumberOfAPIs * sizeof ULONG_PTR);
OriginalStorePlaceRVA = OriginalStorePlaceRVA + (NumberOfAPIs * sizeof ULONG_PTR);
StoreIID = (PIMAGE_IMPORT_DESCRIPTOR)((ULONG_PTR)StorePlace + (NumberOfAPIs * sizeof ULONG_PTR));
}
__try
{
DLLNumber = impDLLNumber + 1;
while(DLLNumber > NULL)
{
RtlMoveMemory(&FirstThunk, (LPVOID)impDLLDataList[i][0], sizeof ULONG_PTR);
StoreIID->FirstThunk = (DWORD)(FirstThunk - impImageBase);
StoreIID->Name = (DWORD)(StringStorePlaceVA - impImageBase);
RtlMoveMemory((LPVOID)StringStorePlaceFO, (LPVOID)impDLLStringList[i][0], (int)(impDLLStringList[i][1] - impDLLStringList[i][0]));
StringStorePlaceFO = StringStorePlaceFO + (int)(impDLLStringList[i][1] - impDLLStringList[i][0]);
#if !defined(_WIN64)
ThunkReadPlace = (LPVOID)(impDLLDataList[i][0] + 12);
#else
ThunkReadPlace = (LPVOID)(impDLLDataList[i][0] + 20);
#endif
ThunkStorePlaceFO = (ULONG_PTR)ConvertVAtoFileOffset(FileMapVA, FirstThunk, true);
RtlMoveMemory(&APINumber, (LPVOID)(impDLLDataList[i][0] + 2 * sizeof ULONG_PTR), 4);
CurrentThunk = FirstThunk;
APINumber--;
while(APINumber > NULL)
{
OrdinalImport = false;
for(j = 0; j < 1000; j++)
{
if(impOrdinalList[j][0] == CurrentThunk)
{
OrdinalImport = true;
x = j;
j = 1000;
}
else if(impOrdinalList[j][0] == NULL)
{
j = 1000;
}
}
if(!OrdinalImport)
{
RtlMoveMemory(&ThunkReadValue, ThunkReadPlace, 4);
ThunkReadValue = ThunkReadValue + StringStorePlaceVA - impImageBase;
RtlMoveMemory((LPVOID)ThunkStorePlaceFO, &ThunkReadValue, sizeof ULONG_PTR);
ThunkReadPlace = (LPVOID)((ULONG_PTR)ThunkReadPlace + 4);
ThunkStorePlaceFO = ThunkStorePlaceFO + sizeof ULONG_PTR;
}
else
{
j = x;
ThunkReadValue = impOrdinalList[j][1];
RtlMoveMemory((LPVOID)ThunkStorePlaceFO, &ThunkReadValue, sizeof ULONG_PTR);
ThunkReadPlace = (LPVOID)((ULONG_PTR)ThunkReadPlace + 4);
ThunkStorePlaceFO = ThunkStorePlaceFO + sizeof ULONG_PTR;
}
CurrentThunk = CurrentThunk + sizeof ULONG_PTR;
APINumber--;
}
ThunkReadValue = 0;
RtlMoveMemory((LPVOID)ThunkStorePlaceFO, &ThunkReadValue, sizeof ULONG_PTR);
StorePlaceVA = StorePlaceVA + (int)(impDLLStringList[i][1] - impDLLStringList[i][0]);
StringStorePlaceVA = StringStorePlaceVA + (int)(impDLLStringList[i][1] - impDLLStringList[i][0]);
StoreIID = (PIMAGE_IMPORT_DESCRIPTOR)((ULONG_PTR)StoreIID + sizeof IMAGE_IMPORT_DESCRIPTOR);
DLLNumber--;
i++;
}
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, NULL, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
if(!FileIs64)
{
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = (DWORD)OriginalStorePlaceRVA;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = (DWORD)((impDLLNumber + 2) * sizeof IMAGE_IMPORT_DESCRIPTOR);
}
else
{
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = (DWORD)OriginalStorePlaceRVA;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = (DWORD)((impDLLNumber + 2) * sizeof IMAGE_IMPORT_DESCRIPTOR);
}
}
ImporterCleanup();
return(true);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
ImporterCleanup();
return(false);
}
}
else
{
return(false);
}
}
__declspec(dllexport) long TITCALL ImporterEstimatedSize()
{
int i = 0;
DWORD DLLNumber = NULL;
long EstimatedSize = 0x200;
if(impMoveIAT)
{
EstimatedSize = EstimatedSize + (ImporterGetAddedAPICount() * sizeof ULONG_PTR) + ((impDLLNumber + 1) * sizeof ULONG_PTR);
}
EstimatedSize = EstimatedSize + ((impDLLNumber + 2) * sizeof IMAGE_IMPORT_DESCRIPTOR);
DLLNumber = impDLLNumber + 1;
while(DLLNumber > NULL)
{
EstimatedSize = EstimatedSize + (DWORD)(impDLLStringList[i][1] - impDLLStringList[i][0]);
DLLNumber--;
i++;
}
for(i = 0; i < 1000; i++)
{
if(impOrdinalList[i][0] != NULL && impOrdinalList[i][1] != NULL)
{
EstimatedSize = EstimatedSize + sizeof ULONG_PTR;
}
}
return(EstimatedSize);
}
__declspec(dllexport) bool TITCALL ImporterExportIATEx(char* szExportFileName, char* szSectionName)
{
wchar_t uniExportFileName[MAX_PATH] = {};
if(szExportFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szExportFileName, lstrlenA(szExportFileName)+1, uniExportFileName, sizeof(uniExportFileName)/(sizeof(uniExportFileName[0])));
return(ImporterExportIATExW(uniExportFileName, szSectionName));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL ImporterExportIATExW(wchar_t* szExportFileName, char* szSectionName)
{
HANDLE FileHandle;
DWORD FileSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
DWORD NewSectionVO = NULL;
DWORD NewSectionFO = NULL;
bool ReturnValue = false;
if(ImporterGetAddedDllCount() > NULL)
{
NewSectionVO = AddNewSectionW(szExportFileName, szSectionName, ImporterEstimatedSize());
if(MapFileExW(szExportFileName, UE_ACCESS_ALL, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
NewSectionFO = (DWORD)ConvertVAtoFileOffset(FileMapVA, NewSectionVO + impImageBase, true);
ReturnValue = ImporterExportIAT(NewSectionFO, FileMapVA);
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
if(ReturnValue)
{
return(true);
}
else
{
return(false);
}
}
else
{
return(false);
}
}
else
{
return(false);
}
}
__declspec(dllexport) long long TITCALL ImporterFindAPIWriteLocation(char* szAPIName)
{
int i = 0;
int j = 0;
DWORD DLLNumber = NULL;
DWORD NumberOfAPIs = NULL;
LPVOID NameReadPlace = NULL;
ULONG_PTR CurrentAPILocation = NULL;
DWORD APINameRelativeOffset = NULL;
ULONG_PTR APIWriteLocation = NULL;
if(ImporterGetAddedDllCount() > NULL)
{
if((ULONG_PTR)szAPIName > 0x10000)
{
DLLNumber = impDLLNumber + 1;
while(DLLNumber > NULL)
{
#if !defined(_WIN64)
NameReadPlace = (LPVOID)(impDLLDataList[i][0] + 12);
#else
NameReadPlace = (LPVOID)(impDLLDataList[i][0] + 20);
#endif
RtlMoveMemory(&CurrentAPILocation, (LPVOID)(impDLLDataList[i][0]), sizeof ULONG_PTR);
RtlMoveMemory(&NumberOfAPIs, (LPVOID)(impDLLDataList[i][0] + 2 * sizeof ULONG_PTR), 4);
while(NumberOfAPIs > NULL)
{
RtlMoveMemory(&APINameRelativeOffset, NameReadPlace, 4);
if(lstrcmpiA((LPCSTR)((ULONG_PTR)impDLLStringList[i][0] + APINameRelativeOffset + 2), (LPCSTR)szAPIName) == NULL)
{
APIWriteLocation = CurrentAPILocation;
break;
}
CurrentAPILocation = CurrentAPILocation + sizeof ULONG_PTR;
NameReadPlace = (LPVOID)((ULONG_PTR)NameReadPlace + sizeof ULONG_PTR);
NumberOfAPIs--;
}
DLLNumber--;
i++;
}
return(APIWriteLocation);
}
else
{
for(j = 0; j < 1000; j++)
{
if(impOrdinalList[j][1] == ((ULONG_PTR)szAPIName ^ IMAGE_ORDINAL_FLAG))
{
return(impOrdinalList[j][0]);
}
}
}
}
return(NULL);
}
__declspec(dllexport) long long TITCALL ImporterFindOrdinalAPIWriteLocation(ULONG_PTR OrdinalNumber)
{
return(ImporterFindAPIWriteLocation((char*)OrdinalNumber));
}
__declspec(dllexport) long long TITCALL ImporterFindAPIByWriteLocation(ULONG_PTR APIWriteLocation)
{
int i = 0;
DWORD DLLNumber = NULL;
LPVOID NameReadPlace = NULL;
ULONG_PTR MinAPILocation = NULL;
ULONG_PTR MaxAPILocation = NULL;
DWORD APINameRelativeOffset = NULL;
ULONG_PTR APINameOffset = NULL;
if(ImporterGetAddedDllCount() > NULL)
{
DLLNumber = impDLLNumber + 1;
while(DLLNumber > NULL)
{
#if !defined(_WIN64)
NameReadPlace = (LPVOID)(impDLLDataList[i][0] + 12);
#else
NameReadPlace = (LPVOID)(impDLLDataList[i][0] + 20);
#endif
RtlMoveMemory(&MinAPILocation, (LPVOID)(impDLLDataList[i][0]), sizeof ULONG_PTR);
RtlMoveMemory(&MaxAPILocation, (LPVOID)(impDLLDataList[i][0] + sizeof ULONG_PTR), sizeof ULONG_PTR);
if(MinAPILocation <= APIWriteLocation && APIWriteLocation <= MaxAPILocation)
{
RtlMoveMemory(&APINameRelativeOffset, (LPVOID)((ULONG_PTR)NameReadPlace + (APIWriteLocation - MinAPILocation)), 4);
return((ULONG_PTR)(impDLLStringList[i][0] + APINameRelativeOffset + 2));
}
DLLNumber--;
i++;
}
}
return(NULL);
}
__declspec(dllexport) long long TITCALL ImporterFindDLLByWriteLocation(ULONG_PTR APIWriteLocation)
{
int i = 0;
DWORD DLLNumber = NULL;
LPVOID NameReadPlace = NULL;
ULONG_PTR MinAPILocation = NULL;
ULONG_PTR MaxAPILocation = NULL;
DWORD APINameRelativeOffset = NULL;
ULONG_PTR APINameOffset = NULL;
if(ImporterGetAddedDllCount() > NULL)
{
DLLNumber = impDLLNumber + 1;
while(DLLNumber > NULL)
{
#if !defined(_WIN64)
NameReadPlace = (LPVOID)(impDLLDataList[i][0] + 12);
#else
NameReadPlace = (LPVOID)(impDLLDataList[i][0] + 20);
#endif
RtlMoveMemory(&MinAPILocation, (LPVOID)(impDLLDataList[i][0]), sizeof ULONG_PTR);
RtlMoveMemory(&MaxAPILocation, (LPVOID)(impDLLDataList[i][0] + sizeof ULONG_PTR), sizeof ULONG_PTR);
if(MinAPILocation <= APIWriteLocation && APIWriteLocation <= MaxAPILocation)
{
return((ULONG_PTR)(impDLLStringList[i][0]));
}
DLLNumber--;
i++;
}
}
return(NULL);
}
__declspec(dllexport) void* TITCALL ImporterGetDLLName(ULONG_PTR APIAddress)
{
return((LPVOID)EngineGlobalAPIHandler(NULL, NULL, APIAddress, NULL, UE_OPTION_IMPORTER_RETURN_DLLNAME));
}
__declspec(dllexport) void* TITCALL ImporterGetAPIName(ULONG_PTR APIAddress)
{
return((LPVOID)EngineGlobalAPIHandler(NULL, NULL, APIAddress, NULL, UE_OPTION_IMPORTER_RETURN_APINAME));
}
__declspec(dllexport) long long TITCALL ImporterGetAPIOrdinalNumber(ULONG_PTR APIAddress)
{
return((long)EngineGlobalAPIHandler(NULL, NULL, APIAddress, NULL, UE_OPTION_IMPORTER_RETURN_API_ORDINAL_NUMBER));
}
__declspec(dllexport) void* TITCALL ImporterGetAPINameEx(ULONG_PTR APIAddress, ULONG_PTR DLLBasesList)
{
return((LPVOID)EngineGlobalAPIHandler(NULL, DLLBasesList, APIAddress, NULL, UE_OPTION_IMPORTER_RETURN_APINAME));
}
__declspec(dllexport) long long TITCALL ImporterGetRemoteAPIAddress(HANDLE hProcess, ULONG_PTR APIAddress)
{
return((ULONG_PTR)EngineGlobalAPIHandler(hProcess, NULL, APIAddress, NULL, UE_OPTION_IMPORTER_REALIGN_APIADDRESS));
}
__declspec(dllexport) long long TITCALL ImporterGetRemoteAPIAddressEx(char* szDLLName, char* szAPIName)
{
int i = 0;
int j = 0;
char szAnsiLibraryName[MAX_PATH];
PLIBRARY_ITEM_DATAW hListLibraryPtr = NULL;
ULONG_PTR APIFoundAddress = 0;
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
PIMAGE_EXPORT_DIRECTORY PEExports;
PEXPORTED_DATA ExportedFunctions;
PEXPORTED_DATA ExportedFunctionNames;
PEXPORTED_DATA_WORD ExportedFunctionOrdinals;
bool FileIs64 = false;
hListLibraryPtr = (PLIBRARY_ITEM_DATAW)hListLibrary;
if(hListLibraryPtr != NULL)
{
while(hListLibraryPtr->hFile != NULL)
{
WideCharToMultiByte(CP_ACP, NULL, hListLibraryPtr->szLibraryName, -1, szAnsiLibraryName, sizeof szAnsiLibraryName, NULL, NULL);
if(lstrcmpiA(szAnsiLibraryName, szDLLName) == NULL)
{
__try
{
DOSHeader = (PIMAGE_DOS_HEADER)hListLibraryPtr->hFileMappingView;
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
return(NULL);
}
if(!FileIs64)
{
PEExports = (PIMAGE_EXPORT_DIRECTORY)((ULONG_PTR)ConvertVAtoFileOffsetEx((ULONG_PTR)hListLibraryPtr->hFileMappingView, GetFileSize(hListLibraryPtr->hFile, NULL), (ULONG_PTR)PEHeader32->OptionalHeader.ImageBase, PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress, true, true));
ExportedFunctions = (PEXPORTED_DATA)((ULONG_PTR)ConvertVAtoFileOffsetEx((ULONG_PTR)hListLibraryPtr->hFileMappingView, GetFileSize(hListLibraryPtr->hFile, NULL), (ULONG_PTR)PEHeader32->OptionalHeader.ImageBase, PEExports->AddressOfFunctions, true, true));
ExportedFunctionNames = (PEXPORTED_DATA)((ULONG_PTR)ConvertVAtoFileOffsetEx((ULONG_PTR)hListLibraryPtr->hFileMappingView, GetFileSize(hListLibraryPtr->hFile, NULL), (ULONG_PTR)PEHeader32->OptionalHeader.ImageBase, PEExports->AddressOfNames, true, true));
ExportedFunctionOrdinals = (PEXPORTED_DATA_WORD)((ULONG_PTR)ConvertVAtoFileOffsetEx((ULONG_PTR)hListLibraryPtr->hFileMappingView, GetFileSize(hListLibraryPtr->hFile, NULL), (ULONG_PTR)PEHeader32->OptionalHeader.ImageBase, PEExports->AddressOfNameOrdinals, true, true));
}
else
{
PEExports = (PIMAGE_EXPORT_DIRECTORY)((ULONG_PTR)ConvertVAtoFileOffsetEx((ULONG_PTR)hListLibraryPtr->hFileMappingView, GetFileSize(hListLibraryPtr->hFile, NULL), (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress, true, true));
ExportedFunctions = (PEXPORTED_DATA)((ULONG_PTR)ConvertVAtoFileOffsetEx((ULONG_PTR)hListLibraryPtr->hFileMappingView, GetFileSize(hListLibraryPtr->hFile, NULL), (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, PEExports->AddressOfFunctions, true, true));
ExportedFunctionNames = (PEXPORTED_DATA)((ULONG_PTR)ConvertVAtoFileOffsetEx((ULONG_PTR)hListLibraryPtr->hFileMappingView, GetFileSize(hListLibraryPtr->hFile, NULL), (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, PEExports->AddressOfNames, true, true));
ExportedFunctionOrdinals = (PEXPORTED_DATA_WORD)((ULONG_PTR)ConvertVAtoFileOffsetEx((ULONG_PTR)hListLibraryPtr->hFileMappingView, GetFileSize(hListLibraryPtr->hFile, NULL), (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, PEExports->AddressOfNameOrdinals, true, true));
}
for(j = 0; j <= (int)PEExports->NumberOfNames; j++)
{
if(!FileIs64)
{
if(lstrcmpiA((LPCSTR)szAPIName, (LPCSTR)((ULONG_PTR)ConvertVAtoFileOffsetEx((ULONG_PTR)hListLibraryPtr->hFileMappingView, GetFileSize(hListLibraryPtr->hFile, NULL), (ULONG_PTR)PEHeader32->OptionalHeader.ImageBase, ExportedFunctionNames->ExportedItem, true, true))) == NULL)
{
ExportedFunctionOrdinals = (PEXPORTED_DATA_WORD)((ULONG_PTR)ExportedFunctionOrdinals + j * 2);
ExportedFunctions = (PEXPORTED_DATA)((ULONG_PTR)ExportedFunctions + (ExportedFunctionOrdinals->OrdinalNumber) * 4);
APIFoundAddress = ExportedFunctions->ExportedItem + (ULONG_PTR)hListLibraryPtr->BaseOfDll;
return((ULONG_PTR)APIFoundAddress);
}
}
else
{
if(lstrcmpiA((LPCSTR)szAPIName, (LPCSTR)((ULONG_PTR)ConvertVAtoFileOffsetEx((ULONG_PTR)hListLibraryPtr->hFileMappingView, GetFileSize(hListLibraryPtr->hFile, NULL), (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, ExportedFunctionNames->ExportedItem, true, true))) == NULL)
{
ExportedFunctionOrdinals = (PEXPORTED_DATA_WORD)((ULONG_PTR)ExportedFunctionOrdinals + j * 2);
ExportedFunctions = (PEXPORTED_DATA)((ULONG_PTR)ExportedFunctions + (ExportedFunctionOrdinals->OrdinalNumber) * 4);
APIFoundAddress = ExportedFunctions->ExportedItem + (ULONG_PTR)hListLibraryPtr->BaseOfDll;
return((ULONG_PTR)APIFoundAddress);
}
}
ExportedFunctionNames = (PEXPORTED_DATA)((ULONG_PTR)ExportedFunctionNames + 4);
}
return(NULL);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return(NULL);
}
}
hListLibraryPtr = (PLIBRARY_ITEM_DATAW)((ULONG_PTR)hListLibraryPtr + sizeof LIBRARY_ITEM_DATAW);
}
}
return(NULL);
}
__declspec(dllexport) long long TITCALL ImporterGetLocalAPIAddress(HANDLE hProcess, ULONG_PTR APIAddress)
{
return((ULONG_PTR)EngineGlobalAPIHandler(hProcess, NULL, APIAddress, NULL, UE_OPTION_IMPORTER_REALIGN_LOCAL_APIADDRESS));
}
__declspec(dllexport) void* TITCALL ImporterGetDLLNameFromDebugee(HANDLE hProcess, ULONG_PTR APIAddress)
{
return((LPVOID)EngineGlobalAPIHandler(hProcess, NULL, APIAddress, NULL, UE_OPTION_IMPORTER_RETURN_DLLNAME));
}
__declspec(dllexport) void* TITCALL ImporterGetAPINameFromDebugee(HANDLE hProcess, ULONG_PTR APIAddress)
{
return((LPVOID)EngineGlobalAPIHandler(hProcess, NULL, APIAddress, NULL, UE_OPTION_IMPORTER_RETURN_APINAME));
}
__declspec(dllexport) long long TITCALL ImporterGetAPIOrdinalNumberFromDebugee(HANDLE hProcess, ULONG_PTR APIAddress)
{
return((long)EngineGlobalAPIHandler(hProcess, NULL, APIAddress, NULL, UE_OPTION_IMPORTER_RETURN_API_ORDINAL_NUMBER));
}
__declspec(dllexport) long TITCALL ImporterGetDLLIndexEx(ULONG_PTR APIAddress, ULONG_PTR DLLBasesList)
{
return((DWORD)EngineGlobalAPIHandler(NULL, DLLBasesList, APIAddress, NULL, UE_OPTION_IMPORTER_RETURN_DLLINDEX));
}
__declspec(dllexport) long TITCALL ImporterGetDLLIndex(HANDLE hProcess, ULONG_PTR APIAddress, ULONG_PTR DLLBasesList)
{
return((DWORD)EngineGlobalAPIHandler(hProcess, DLLBasesList, APIAddress, NULL, UE_OPTION_IMPORTER_RETURN_DLLINDEX));
}
__declspec(dllexport) long long TITCALL ImporterGetRemoteDLLBase(HANDLE hProcess, HMODULE LocalModuleBase)
{
return((ULONG_PTR)EngineGlobalAPIHandler(hProcess, NULL, (ULONG_PTR)LocalModuleBase, NULL, UE_OPTION_IMPORTER_RETURN_DLLBASE));
}
__declspec(dllexport) long long TITCALL ImporterGetRemoteDLLBaseEx(HANDLE hProcess, char* szModuleName)
{
int i = 1;
DWORD Dummy = NULL;
ULONG_PTR EnumeratedModules[0x2000];
char RemoteDLLName[MAX_PATH];
if(EnumProcessModules(hProcess, (HMODULE*)EnumeratedModules, 0x2000, &Dummy))
{
RtlZeroMemory(&RemoteDLLName, MAX_PATH);
while(EnumeratedModules[i] != NULL)
{
if(GetModuleBaseNameA(hProcess, (HMODULE)EnumeratedModules[i], (LPSTR)RemoteDLLName, MAX_PATH) > NULL)
{
if(lstrcmpiA((LPCSTR)RemoteDLLName, (LPCSTR)szModuleName))
{
return((ULONG_PTR)EnumeratedModules[i]);
}
}
i++;
}
}
return(NULL);
}
__declspec(dllexport) bool TITCALL ImporterRelocateWriteLocation(ULONG_PTR AddValue)
{
unsigned int i;
ULONG_PTR RealignData = NULL;
if(impDLLNumber)
{
for(i = 0; i < impDLLNumber + 1; i++)
{
RtlMoveMemory(&RealignData, (LPVOID)impDLLDataList[i][0], sizeof ULONG_PTR);
RealignData = RealignData + AddValue;
RtlMoveMemory((LPVOID)impDLLDataList[i][0], &RealignData, sizeof ULONG_PTR);
RtlMoveMemory(&RealignData, (LPVOID)((ULONG_PTR)impDLLDataList[i][0] + sizeof ULONG_PTR), sizeof ULONG_PTR);
RealignData = RealignData + AddValue;
RtlMoveMemory((LPVOID)((ULONG_PTR)impDLLDataList[i][0] + sizeof ULONG_PTR), &RealignData, sizeof ULONG_PTR);
}
for(i = 0; i < 1000; i++)
{
if(impOrdinalList[i][0] != NULL && impOrdinalList[i][1] != NULL)
{
impOrdinalList[i][0] = impOrdinalList[i][0] + AddValue;
}
}
return(true);
}
else
{
return(false);
}
return(false);
}
__declspec(dllexport) bool TITCALL ImporterIsForwardedAPI(HANDLE hProcess, ULONG_PTR APIAddress)
{
if((ULONG_PTR)EngineGlobalAPIHandler(hProcess, NULL, APIAddress, NULL, UE_OPTION_IMPORTER_RETURN_FORWARDER_DLLINDEX) > NULL)
{
return(true);
}
else
{
return(false);
}
}
__declspec(dllexport) void* TITCALL ImporterGetForwardedAPIName(HANDLE hProcess, ULONG_PTR APIAddress)
{
return((LPVOID)EngineGlobalAPIHandler(hProcess, NULL, APIAddress, NULL, UE_OPTION_IMPORTER_RETURN_FORWARDER_APINAME));
}
__declspec(dllexport) void* TITCALL ImporterGetForwardedDLLName(HANDLE hProcess, ULONG_PTR APIAddress)
{
return((LPVOID)EngineGlobalAPIHandler(hProcess, NULL, APIAddress, NULL, UE_OPTION_IMPORTER_RETURN_FORWARDER_DLLNAME));
}
__declspec(dllexport) long TITCALL ImporterGetForwardedDLLIndex(HANDLE hProcess, ULONG_PTR APIAddress, ULONG_PTR DLLBasesList)
{
return((DWORD)EngineGlobalAPIHandler(hProcess, NULL, APIAddress, NULL, UE_OPTION_IMPORTER_RETURN_FORWARDER_DLLINDEX));
}
__declspec(dllexport) long long TITCALL ImporterGetForwardedAPIOrdinalNumber(HANDLE hProcess, ULONG_PTR APIAddress)
{
return((DWORD)EngineGlobalAPIHandler(hProcess, NULL, APIAddress, NULL, UE_OPTION_IMPORTER_RETURN_FORWARDER_API_ORDINAL_NUMBER));
}
__declspec(dllexport) long long TITCALL ImporterGetNearestAPIAddress(HANDLE hProcess, ULONG_PTR APIAddress)
{
return((ULONG_PTR)EngineGlobalAPIHandler(hProcess, NULL, APIAddress, NULL, UE_OPTION_IMPORTER_RETURN_NEAREST_APIADDRESS));
}
__declspec(dllexport) void* TITCALL ImporterGetNearestAPIName(HANDLE hProcess, ULONG_PTR APIAddress)
{
return((LPVOID)EngineGlobalAPIHandler(hProcess, NULL, APIAddress, NULL, UE_OPTION_IMPORTER_RETURN_NEAREST_APINAME));
}
__declspec(dllexport) bool TITCALL ImporterCopyOriginalIAT(char* szOriginalFile, char* szDumpFile)
{
wchar_t uniDumpFile[MAX_PATH] = {};
wchar_t uniOriginalFile[MAX_PATH] = {};
if(szOriginalFile != NULL && szDumpFile != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szDumpFile, lstrlenA(szDumpFile)+1, uniDumpFile, sizeof(uniDumpFile)/(sizeof(uniDumpFile[0])));
MultiByteToWideChar(CP_ACP, NULL, szOriginalFile, lstrlenA(szOriginalFile)+1, uniOriginalFile, sizeof(uniOriginalFile)/(sizeof(uniOriginalFile[0])));
return(ImporterCopyOriginalIATW(uniOriginalFile, uniDumpFile));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL ImporterCopyOriginalIATW(wchar_t* szOriginalFile, wchar_t* szDumpFile)
{
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
BOOL FileIs64;
HANDLE FileHandle=0;
DWORD FileSize;
HANDLE FileMap=0;
ULONG_PTR FileMapVA;
HANDLE FileHandle1=0;
DWORD FileSize1;
HANDLE FileMap1=0;
ULONG_PTR FileMapVA1;
ULONG_PTR IATPointer;
ULONG_PTR IATWritePointer;
ULONG_PTR IATCopyStart;
DWORD IATSection;
DWORD IATCopySize;
DWORD IATHeaderData;
if(MapFileExW(szOriginalFile, UE_ACCESS_READ, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
if(MapFileExW(szDumpFile, UE_ACCESS_ALL, &FileHandle1, &FileSize1, &FileMap1, &FileMapVA1, NULL))
{
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, FileHandle, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
UnMapFileEx(FileHandle1, FileSize1, FileMap1, FileMapVA1);
return(false);
}
if(!FileIs64)
{
IATPointer = (ULONG_PTR)(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + PEHeader32->OptionalHeader.ImageBase);
}
else
{
IATPointer = (ULONG_PTR)(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + PEHeader64->OptionalHeader.ImageBase);
}
IATSection = GetPE32SectionNumberFromVA(FileMapVA, IATPointer);
IATPointer = (ULONG_PTR)ConvertVAtoFileOffset(FileMapVA, IATPointer, true);
if((int)IATSection >= NULL)
{
IATWritePointer = (ULONG_PTR)GetPE32DataFromMappedFile(FileMapVA1, IATSection, UE_SECTIONRAWOFFSET) + FileMapVA1;
IATCopyStart = (ULONG_PTR)GetPE32DataFromMappedFile(FileMapVA, IATSection, UE_SECTIONRAWOFFSET) + FileMapVA;
IATCopySize = (DWORD)GetPE32DataFromMappedFile(FileMapVA1, IATSection, UE_SECTIONRAWSIZE);
__try
{
RtlMoveMemory((LPVOID)IATWritePointer, (LPVOID)IATCopyStart, IATCopySize);
IATHeaderData = (DWORD)GetPE32DataFromMappedFile(FileMapVA, NULL, UE_IMPORTTABLEADDRESS);
SetPE32DataForMappedFile(FileMapVA1, NULL, UE_IMPORTTABLEADDRESS, (ULONG_PTR)IATHeaderData);
IATHeaderData = (DWORD)GetPE32DataFromMappedFile(FileMapVA, NULL, UE_IMPORTTABLESIZE);
SetPE32DataForMappedFile(FileMapVA1, NULL, UE_IMPORTTABLESIZE, (ULONG_PTR)IATHeaderData);
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
UnMapFileEx(FileHandle1, FileSize1, FileMap1, FileMapVA1);
return(true);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
UnMapFileEx(FileHandle1, FileSize1, FileMap1, FileMapVA1);
return(false);
}
}
}
UnMapFileEx(FileHandle1, FileSize1, FileMap1, FileMapVA1);
}
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
}
return(false);
}
__declspec(dllexport) bool TITCALL ImporterLoadImportTable(char* szFileName)
{
wchar_t uniFileName[MAX_PATH] = {};
if(szFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
return(ImporterLoadImportTableW(uniFileName));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL ImporterLoadImportTableW(wchar_t* szFileName)
{
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
PIMAGE_IMPORT_DESCRIPTOR ImportIID;
PIMAGE_THUNK_DATA32 ThunkData32;
PIMAGE_THUNK_DATA64 ThunkData64;
ULONG_PTR CurrentThunk;
BOOL FileIs64;
HANDLE FileHandle;
DWORD FileSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
if(MapFileExW(szFileName, UE_ACCESS_READ, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, FileHandle, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
if(!FileIs64)
{
if(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress != NULL)
{
ImporterInit(MAX_IMPORT_ALLOC, (ULONG_PTR)PEHeader32->OptionalHeader.ImageBase);
ImportIID = (PIMAGE_IMPORT_DESCRIPTOR)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + PEHeader32->OptionalHeader.ImageBase), true);
__try
{
while(ImportIID->FirstThunk != NULL)
{
ImporterAddNewDll((char*)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)((ULONG_PTR)ImportIID->Name + PEHeader32->OptionalHeader.ImageBase), true), NULL);
if(ImportIID->OriginalFirstThunk != NULL)
{
ThunkData32 = (PIMAGE_THUNK_DATA32)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)((ULONG_PTR)ImportIID->OriginalFirstThunk + PEHeader32->OptionalHeader.ImageBase), true);
CurrentThunk = (ULONG_PTR)ImportIID->FirstThunk;
}
else
{
ThunkData32 = (PIMAGE_THUNK_DATA32)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)((ULONG_PTR)ImportIID->FirstThunk + PEHeader32->OptionalHeader.ImageBase), true);
CurrentThunk = (ULONG_PTR)ImportIID->FirstThunk;
}
while(ThunkData32->u1.AddressOfData != NULL)
{
if(ThunkData32->u1.Ordinal & IMAGE_ORDINAL_FLAG32)
{
ImporterAddNewAPI((char*)(ThunkData32->u1.Ordinal ^ IMAGE_ORDINAL_FLAG32), (ULONG_PTR)CurrentThunk + PEHeader32->OptionalHeader.ImageBase);
}
else
{
ImporterAddNewAPI((char*)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)((ULONG_PTR)ThunkData32->u1.AddressOfData + 2 + PEHeader32->OptionalHeader.ImageBase), true), (ULONG_PTR)CurrentThunk + PEHeader32->OptionalHeader.ImageBase);
}
CurrentThunk = CurrentThunk + 4;
ThunkData32 = (PIMAGE_THUNK_DATA32)((ULONG_PTR)ThunkData32 + sizeof IMAGE_THUNK_DATA32);
}
ImportIID = (PIMAGE_IMPORT_DESCRIPTOR)((ULONG_PTR)ImportIID + sizeof IMAGE_IMPORT_DESCRIPTOR);
}
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(true);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
ImporterCleanup();
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
}
else
{
if(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress != NULL)
{
ImporterInit(MAX_IMPORT_ALLOC, (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase);
ImportIID = (PIMAGE_IMPORT_DESCRIPTOR)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + PEHeader64->OptionalHeader.ImageBase), true);
__try
{
while(ImportIID->FirstThunk != NULL)
{
ImporterAddNewDll((char*)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)((ULONG_PTR)ImportIID->Name + PEHeader64->OptionalHeader.ImageBase), true), NULL);
if(ImportIID->OriginalFirstThunk != NULL)
{
ThunkData64 = (PIMAGE_THUNK_DATA64)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)((ULONG_PTR)ImportIID->OriginalFirstThunk + PEHeader64->OptionalHeader.ImageBase), true);
CurrentThunk = (ULONG_PTR)ImportIID->OriginalFirstThunk;
}
else
{
ThunkData64 = (PIMAGE_THUNK_DATA64)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)((ULONG_PTR)ImportIID->FirstThunk + PEHeader64->OptionalHeader.ImageBase), true);
CurrentThunk = (ULONG_PTR)ImportIID->FirstThunk;
}
while(ThunkData64->u1.AddressOfData != NULL)
{
if(ThunkData64->u1.Ordinal & IMAGE_ORDINAL_FLAG64)
{
ImporterAddNewAPI((char*)(ThunkData64->u1.Ordinal ^ (ULONG_PTR)IMAGE_ORDINAL_FLAG64), (ULONG_PTR)CurrentThunk + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase);
}
else
{
ImporterAddNewAPI((char*)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)((ULONG_PTR)ThunkData64->u1.AddressOfData + 2 + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase), true), (ULONG_PTR)CurrentThunk + (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase);
}
CurrentThunk = CurrentThunk + 8;
ThunkData64 = (PIMAGE_THUNK_DATA64)((ULONG_PTR)ThunkData64 + sizeof IMAGE_THUNK_DATA64);
}
ImportIID = (PIMAGE_IMPORT_DESCRIPTOR)((ULONG_PTR)ImportIID + sizeof IMAGE_IMPORT_DESCRIPTOR);
}
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(true);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
ImporterCleanup();
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
}
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
else
{
return(false);
}
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
__declspec(dllexport) bool TITCALL ImporterMoveOriginalIAT(char* szOriginalFile, char* szDumpFile, char* szSectionName)
{
if(ImporterLoadImportTable(szOriginalFile))
{
return(ImporterExportIATEx(szDumpFile, szSectionName));
}
return(false);
}
__declspec(dllexport) bool TITCALL ImporterMoveOriginalIATW(wchar_t* szOriginalFile, wchar_t* szDumpFile, char* szSectionName)
{
if(ImporterLoadImportTableW(szOriginalFile))
{
return(ImporterExportIATExW(szDumpFile, szSectionName));
}
return(false);
}
__declspec(dllexport) void TITCALL ImporterAutoSearchIAT(HANDLE hProcess, char* szFileName, ULONG_PTR ImageBase, ULONG_PTR SearchStart, DWORD SearchSize, LPVOID pIATStart, LPVOID pIATSize)
{
wchar_t uniFileName[MAX_PATH] = {};
if(szFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
return(ImporterAutoSearchIATW(hProcess, uniFileName, ImageBase, SearchStart, SearchSize, pIATStart, pIATSize));
}
}
__declspec(dllexport) void TITCALL ImporterAutoSearchIATW(HANDLE hProcess, wchar_t* szFileName, ULONG_PTR ImageBase, ULONG_PTR SearchStart, DWORD SearchSize, LPVOID pIATStart, LPVOID pIATSize)
{
int i = NULL;
int j = NULL;
int MaximumBlankSpaces;
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
MEMORY_BASIC_INFORMATION MemInfo;
PMEMORY_COMPARE_HANDLER cmpHandler;
BOOL FileIs64;
HANDLE FileHandle;
DWORD FileSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
ULONG_PTR IATThunkSize;
ULONG_PTR SearchStartFO;
ULONG_PTR OriginalSearchStartFO;
LPVOID SearchMemory = VirtualAlloc(NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE);
LPVOID memSearchMemory = SearchMemory;
LPVOID CheckMemory = VirtualAlloc(NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE);
LPVOID memCheckMemory = CheckMemory;
ULONG_PTR IATThunkPossiblePointer = NULL;
DWORD IATThunkPossiblePointerFO = NULL;
WORD IATCmpNearCall = 0x15FF;
WORD IATCmpNearJump = 0x25FF;
DWORD NtSizeOfImage = NULL;
ULONG_PTR IATHigh = NULL;
ULONG_PTR IATHighestFound = NULL;
ULONG_PTR IATLow = NULL;
ULONG_PTR IATLowestFound = NULL;
ULONG_PTR SearchStartX64 = SearchStart;
DWORD CurrentSearchSize;
char* CompareBuffer[12];
void* LastValidPtr;
bool ValidPointer;
RtlZeroMemory(&CompareBuffer, 10 * sizeof ULONG_PTR);
if(MapFileExW(szFileName, UE_ACCESS_READ, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, FileHandle, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
VirtualFree(SearchMemory, NULL, MEM_RELEASE);
VirtualFree(CheckMemory, NULL, MEM_RELEASE);
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return;
}
if(!FileIs64)
{
IATThunkSize = 4;
NtSizeOfImage = PEHeader32->OptionalHeader.SizeOfImage;
}
else
{
IATThunkSize = 8;
NtSizeOfImage = PEHeader64->OptionalHeader.SizeOfImage;
}
SearchStartFO = (ULONG_PTR)ConvertVAtoFileOffset(FileMapVA, SearchStart, true);
OriginalSearchStartFO = SearchStartFO;
if(SearchSize > 0x1000)
{
CurrentSearchSize = 0x1000;
}
else
{
CurrentSearchSize = SearchSize;
}
while(SearchSize > NULL && EngineGrabDataFromMappedFile(FileHandle, FileMapVA, SearchStartFO, CurrentSearchSize, SearchMemory) == true)
{
memSearchMemory = SearchMemory;
i = CurrentSearchSize - 6;
while(i > NULL)
{
if(memcmp(memSearchMemory, &IATCmpNearCall, 2) == NULL || memcmp(memSearchMemory, &IATCmpNearJump, 2) == NULL)
{
RtlMoveMemory(&IATThunkPossiblePointer, (LPVOID)((ULONG_PTR)memSearchMemory + 2), 4);
if(!FileIs64)
{
if(IATThunkPossiblePointer >= (DWORD)ImageBase && IATThunkPossiblePointer <= (DWORD)ImageBase + NtSizeOfImage)
{
if(IATHigh == NULL && IATLow == NULL)
{
IATThunkPossiblePointerFO = (DWORD)ConvertVAtoFileOffset(FileMapVA, IATThunkPossiblePointer, true);
if(IATThunkPossiblePointerFO - FileMapVA > 0x1000 && FileSize - (IATThunkPossiblePointerFO - FileMapVA) > 0x1000)
{
j = NULL;
while(j == NULL)
{
EngineGrabDataFromMappedFile(FileHandle, FileMapVA, IATThunkPossiblePointerFO, 0x1000, CheckMemory);
memCheckMemory = CheckMemory;
LastValidPtr = memCheckMemory;
MaximumBlankSpaces = 4;
ValidPointer = true;
j = 0x1000 - 2 * 4;
while(j > NULL && ValidPointer == true && MaximumBlankSpaces > NULL)
{
if(memcmp(memCheckMemory, &CompareBuffer, sizeof ULONG_PTR) != NULL)
{
cmpHandler = (PMEMORY_COMPARE_HANDLER)memCheckMemory;
VirtualQueryEx(hProcess, (void*)cmpHandler->Array.dwArrayEntry[0], &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
if(MemInfo.State != MEM_COMMIT)
{
ValidPointer = false;
memCheckMemory = LastValidPtr;
}
else
{
LastValidPtr = memCheckMemory;
memCheckMemory = (LPVOID)((ULONG_PTR)memCheckMemory + 4);
MaximumBlankSpaces = 4;
}
}
else
{
memCheckMemory = (LPVOID)((ULONG_PTR)memCheckMemory + 4);
MaximumBlankSpaces--;
}
j = j - 4;
}
IATThunkPossiblePointerFO = IATThunkPossiblePointerFO + 0x1000;
}
if(MaximumBlankSpaces == NULL)
{
memCheckMemory = (LPVOID)((ULONG_PTR)memCheckMemory - (5 * sizeof ULONG_PTR));
}
IATHigh = (DWORD)ConvertFileOffsetToVA(FileMapVA, IATThunkPossiblePointerFO + (ULONG_PTR)memCheckMemory - (ULONG_PTR)CheckMemory - 0x1000, true);
IATThunkPossiblePointerFO = (DWORD)ConvertVAtoFileOffset(FileMapVA, IATThunkPossiblePointer, true) - 0x1000;
j = NULL;
while(j == NULL)
{
EngineGrabDataFromMappedFile(FileHandle, FileMapVA, IATThunkPossiblePointerFO, 0x1000, CheckMemory);
memCheckMemory = (LPVOID)((ULONG_PTR)CheckMemory + 0x1000 - 8);
LastValidPtr = (LPVOID)((ULONG_PTR)CheckMemory + 0x1000);
MaximumBlankSpaces = 4;
ValidPointer = true;
j = 0x1000 - 2 * 4;
while(j > NULL && ValidPointer == true && MaximumBlankSpaces > NULL)
{
if(memcmp(memCheckMemory, &CompareBuffer, sizeof ULONG_PTR) != NULL)
{
cmpHandler = (PMEMORY_COMPARE_HANDLER)memCheckMemory;
VirtualQueryEx(hProcess, (void*)cmpHandler->Array.dwArrayEntry[0], &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
if(MemInfo.State != MEM_COMMIT)
{
ValidPointer = false;
memCheckMemory = LastValidPtr;
}
else
{
LastValidPtr = memCheckMemory;
memCheckMemory = (LPVOID)((ULONG_PTR)memCheckMemory - 4);
MaximumBlankSpaces = 4;
}
}
else
{
memCheckMemory = (LPVOID)((ULONG_PTR)memCheckMemory - 4);
MaximumBlankSpaces--;
}
j = j - 4;
}
IATThunkPossiblePointerFO = IATThunkPossiblePointerFO - 0x1000;
}
if(MaximumBlankSpaces == NULL)
{
memCheckMemory = (LPVOID)((ULONG_PTR)memCheckMemory + (5 * sizeof ULONG_PTR));
}
IATLow = (DWORD)ConvertFileOffsetToVA(FileMapVA, IATThunkPossiblePointerFO + (ULONG_PTR)memCheckMemory - (ULONG_PTR)CheckMemory + 0x1000, true);
memSearchMemory = (LPVOID)((ULONG_PTR)memSearchMemory + 6);
i = i - 6;
}
else
{
memSearchMemory = (LPVOID)((ULONG_PTR)memSearchMemory + 2);
i = i - 2;
}
}
else
{
if(IATHighestFound < IATThunkPossiblePointer || IATHighestFound == NULL)
{
if(IATThunkPossiblePointer < IATHigh || IATHighestFound == NULL)
{
IATHighestFound = IATThunkPossiblePointer;
}
}
if(IATLowestFound > IATThunkPossiblePointer || IATLowestFound == NULL)
{
if(IATThunkPossiblePointer > IATLow || IATLowestFound == NULL)
{
IATLowestFound = IATThunkPossiblePointer;
}
}
}
}
else
{
memSearchMemory = (LPVOID)((ULONG_PTR)memSearchMemory + 2);
i = i - 2;
}
}
else
{
SearchStartX64 = SearchStartFO - OriginalSearchStartFO + ((ULONG_PTR)memSearchMemory - (ULONG_PTR)SearchMemory) + SearchStart;
IATThunkPossiblePointer = IATThunkPossiblePointer + SearchStartX64 + 6;
if(IATThunkPossiblePointer >= ImageBase && IATThunkPossiblePointer <= ImageBase + NtSizeOfImage)
{
if(IATHigh == NULL && IATLow == NULL)
{
IATThunkPossiblePointerFO = (DWORD)ConvertVAtoFileOffset(FileMapVA, IATThunkPossiblePointer, true);
if(IATThunkPossiblePointerFO - FileMapVA > 0x1000 && FileSize - (IATThunkPossiblePointerFO - FileMapVA) > 0x1000)
{
j = NULL;
while(j == NULL)
{
EngineGrabDataFromMappedFile(FileHandle, FileMapVA, IATThunkPossiblePointerFO, 0x1000, CheckMemory);
memCheckMemory = CheckMemory;
LastValidPtr = memCheckMemory;
MaximumBlankSpaces = 4;
ValidPointer = true;
j = 0x1000 - 2 * 8;
while(j > NULL && ValidPointer == true && MaximumBlankSpaces > NULL)
{
if(memcmp(memCheckMemory, &CompareBuffer, sizeof ULONG_PTR) != NULL)
{
cmpHandler = (PMEMORY_COMPARE_HANDLER)memCheckMemory;
VirtualQueryEx(hProcess, (void*)cmpHandler->Array.dwArrayEntry[0], &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
if(MemInfo.State != MEM_COMMIT)
{
ValidPointer = false;
memCheckMemory = LastValidPtr;
}
else
{
LastValidPtr = memCheckMemory;
memCheckMemory = (LPVOID)((ULONG_PTR)memCheckMemory + 8);
MaximumBlankSpaces = 4;
}
}
else
{
memCheckMemory = (LPVOID)((ULONG_PTR)memCheckMemory + 8);
MaximumBlankSpaces--;
}
j = j - 8;
}
IATThunkPossiblePointerFO = IATThunkPossiblePointerFO + 0x1000;
}
if(MaximumBlankSpaces == NULL)
{
memCheckMemory = (LPVOID)((ULONG_PTR)memCheckMemory - (5 * sizeof ULONG_PTR));
}
IATHigh = (DWORD)ConvertFileOffsetToVA(FileMapVA, IATThunkPossiblePointerFO + (ULONG_PTR)memCheckMemory - (ULONG_PTR)CheckMemory - 0x1000, true);
IATThunkPossiblePointerFO = (DWORD)ConvertVAtoFileOffset(FileMapVA, IATThunkPossiblePointer, true) - 0x1000;
j = NULL;
while(j == NULL)
{
EngineGrabDataFromMappedFile(FileHandle, FileMapVA, IATThunkPossiblePointerFO, 0x1000, CheckMemory);
memCheckMemory = (LPVOID)((ULONG_PTR)CheckMemory + 0x1000 - 8);
LastValidPtr = (LPVOID)((ULONG_PTR)CheckMemory + 0x1000);
MaximumBlankSpaces = 4;
ValidPointer = true;
j = 0x1000 - 2 * 8;
while(j > NULL && ValidPointer == true && MaximumBlankSpaces > NULL)
{
if(memcmp(memCheckMemory, &CompareBuffer, sizeof ULONG_PTR) != NULL)
{
cmpHandler = (PMEMORY_COMPARE_HANDLER)memCheckMemory;
VirtualQueryEx(hProcess, (void*)cmpHandler->Array.dwArrayEntry[0], &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
if(MemInfo.State != MEM_COMMIT)
{
ValidPointer = false;
memCheckMemory = LastValidPtr;
}
else
{
LastValidPtr = memCheckMemory;
memCheckMemory = (LPVOID)((ULONG_PTR)memCheckMemory - 8);
MaximumBlankSpaces = 4;
}
}
else
{
memCheckMemory = (LPVOID)((ULONG_PTR)memCheckMemory - 8);
MaximumBlankSpaces--;
}
j = j - 8;
}
IATThunkPossiblePointerFO = IATThunkPossiblePointerFO - 0x1000;
}
if(MaximumBlankSpaces == NULL)
{
memCheckMemory = (LPVOID)((ULONG_PTR)memCheckMemory + (5 * sizeof ULONG_PTR));
}
IATLow = (DWORD)ConvertFileOffsetToVA(FileMapVA, IATThunkPossiblePointerFO + (ULONG_PTR)memCheckMemory - (ULONG_PTR)CheckMemory + 0x1000, true);
memSearchMemory = (LPVOID)((ULONG_PTR)memSearchMemory + 6);
i = i - 6;
}
else
{
memSearchMemory = (LPVOID)((ULONG_PTR)memSearchMemory + 2);
i = i - 2;
}
}
else
{
if(IATHighestFound < IATThunkPossiblePointer || IATHighestFound == NULL)
{
if(IATThunkPossiblePointer < IATHigh || IATHighestFound == NULL)
{
IATHighestFound = IATThunkPossiblePointer;
}
}
if(IATLowestFound > IATThunkPossiblePointer || IATLowestFound == NULL)
{
if(IATThunkPossiblePointer > IATLow || IATLowestFound == NULL)
{
IATLowestFound = IATThunkPossiblePointer;
}
}
}
}
else
{
memSearchMemory = (LPVOID)((ULONG_PTR)memSearchMemory + 2);
i = i - 2;
}
}
}
memSearchMemory = (LPVOID)((ULONG_PTR)memSearchMemory + 1);
i--;
}
if(SearchSize > 0x1000)
{
SearchSize = SearchSize - 0x1000;
CurrentSearchSize = 0x1000;
}
else
{
SearchSize = NULL;
CurrentSearchSize = SearchSize;
}
SearchStartFO = SearchStartFO + CurrentSearchSize;
}
IATHigh = IATHigh - IATLow + sizeof ULONG_PTR;
RtlMoveMemory(pIATStart, &IATLow, sizeof ULONG_PTR);
RtlMoveMemory(pIATSize, &IATHigh, sizeof ULONG_PTR);
VirtualFree(SearchMemory, NULL, MEM_RELEASE);
VirtualFree(CheckMemory, NULL, MEM_RELEASE);
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return;
}
else
{
VirtualFree(SearchMemory, NULL, MEM_RELEASE);
VirtualFree(CheckMemory, NULL, MEM_RELEASE);
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return;
}
}
VirtualFree(SearchMemory, NULL, MEM_RELEASE);
VirtualFree(CheckMemory, NULL, MEM_RELEASE);
return;
}
__declspec(dllexport) void TITCALL ImporterAutoSearchIATEx(HANDLE hProcess, ULONG_PTR ImageBase, ULONG_PTR SearchStart, DWORD SearchSize, LPVOID pIATStart, LPVOID pIATSize)
{
wchar_t szTempName[MAX_PATH];
wchar_t szTempFolder[MAX_PATH];
RtlZeroMemory(&szTempName, sizeof szTempName);
RtlZeroMemory(&szTempFolder, sizeof szTempFolder);
if(GetTempPathW(MAX_PATH, szTempFolder) < MAX_PATH)
{
if(GetTempFileNameW(szTempFolder, L"DumpTemp", GetTickCount() + 102, szTempName))
{
DumpProcessW(hProcess, (LPVOID)ImageBase, szTempName, NULL);
ImporterAutoSearchIATW(hProcess, szTempName, ImageBase, SearchStart, SearchSize, pIATStart, pIATSize);
DeleteFileW(szTempName);
}
}
}
__declspec(dllexport) void TITCALL ImporterEnumAddedData(LPVOID EnumCallBack)
{
int i = 0;
int j = 0;
int x = 0;
bool OrdinalImport;
DWORD DLLNumber = NULL;
DWORD NumberOfAPIs = NULL;
LPVOID NameReadPlace = NULL;
ULONG_PTR CurrentAPILocation = NULL;
DWORD APINameRelativeOffset = NULL;
typedef void(TITCALL *fEnumCallBack)(LPVOID fImportDetail);
fEnumCallBack myEnumCallBack = (fEnumCallBack)EnumCallBack;
ImportEnumData myImportEnumData;
char szOrdinalAPIName[MAX_PATH];
if(EnumCallBack != NULL && ImporterGetAddedDllCount() > NULL)
{
DLLNumber = impDLLNumber + 1;
while(DLLNumber > NULL)
{
#if !defined(_WIN64)
NameReadPlace = (LPVOID)(impDLLDataList[i][0] + 12);
#else
NameReadPlace = (LPVOID)(impDLLDataList[i][0] + 20);
#endif
RtlMoveMemory(&CurrentAPILocation, (LPVOID)(impDLLDataList[i][0]), sizeof ULONG_PTR);
RtlMoveMemory(&NumberOfAPIs, (LPVOID)(impDLLDataList[i][0] + 2 * sizeof ULONG_PTR), 4);
RtlZeroMemory(&myImportEnumData, sizeof ImportEnumData);
myImportEnumData.NumberOfImports = (int)(NumberOfAPIs - 1);
myImportEnumData.BaseImportThunk = CurrentAPILocation;
myImportEnumData.ImageBase = impImageBase;
myImportEnumData.NewDll = true;
while(NumberOfAPIs > 1)
{
RtlMoveMemory(&APINameRelativeOffset, NameReadPlace, 4);
myImportEnumData.ImportThunk = CurrentAPILocation;
OrdinalImport = false;
for(j = 0; j < 1000; j++)
{
if(impOrdinalList[j][0] == CurrentAPILocation)
{
OrdinalImport = true;
x = j;
j = 1000;
}
else if(impOrdinalList[j][0] == NULL)
{
j = 1000;
}
}
if(OrdinalImport)
{
wsprintfA(szOrdinalAPIName, "%08X", impOrdinalList[x][1] & IMAGE_ORDINAL_FLAG);
myImportEnumData.APIName = (char*)(szOrdinalAPIName);
}
else
{
myImportEnumData.APIName = (char*)((ULONG_PTR)impDLLStringList[i][0] + APINameRelativeOffset + 2);
}
myImportEnumData.DLLName = (char*)((ULONG_PTR)impDLLStringList[i][0]);
__try
{
myEnumCallBack(&myImportEnumData);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
NumberOfAPIs = 2;
}
myImportEnumData.NewDll = false;
CurrentAPILocation = CurrentAPILocation + sizeof ULONG_PTR;
NameReadPlace = (LPVOID)((ULONG_PTR)NameReadPlace + sizeof ULONG_PTR);
NumberOfAPIs--;
}
DLLNumber--;
i++;
}
}
}
__declspec(dllexport) long TITCALL ImporterAutoFixIATEx(HANDLE hProcess, char* szDumpedFile, char* szSectionName, bool DumpRunningProcess, bool RealignFile, ULONG_PTR EntryPointAddress, ULONG_PTR ImageBase, ULONG_PTR SearchStart, DWORD SearchSize, DWORD SearchStep, bool TryAutoFix, bool FixEliminations, LPVOID UnknownPointerFixCallback)
{
wchar_t uniDumpedFile[MAX_PATH] = {};
if(szDumpedFile != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szDumpedFile, lstrlenA(szDumpedFile)+1, uniDumpedFile, sizeof(uniDumpedFile)/(sizeof(uniDumpedFile[0])));
return(ImporterAutoFixIATExW(hProcess, uniDumpedFile, szSectionName, DumpRunningProcess, RealignFile, EntryPointAddress, ImageBase, SearchStart, SearchSize, SearchStep, TryAutoFix, FixEliminations, UnknownPointerFixCallback));
}
else
{
return(NULL); // Critical error! *just to be safe, but it should never happen!
}
}
__declspec(dllexport) long TITCALL ImporterAutoFixIATExW(HANDLE hProcess, wchar_t* szDumpedFile, char* szSectionName, bool DumpRunningProcess, bool RealignFile, ULONG_PTR EntryPointAddress, ULONG_PTR ImageBase, ULONG_PTR SearchStart, DWORD SearchSize, DWORD SearchStep, bool TryAutoFix, bool FixEliminations, LPVOID UnknownPointerFixCallback)
{
int i;
int j;
int delta;
int currentSectionSize;
#if !defined(_WIN64)
PE32Struct PEStructure;
#else
PE64Struct PEStructure;
#endif
typedef void*(TITCALL *fFixerCallback)(LPVOID fIATPointer);
fFixerCallback myFixerCallback = (fFixerCallback)UnknownPointerFixCallback;
MEMORY_BASIC_INFORMATION MemInfo;
DWORD SectionFlags;
HANDLE FileHandle;
DWORD FileSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
LPVOID aSearchMemory;
LPVOID cSearchMemory;
LPVOID aEnumeratedModules;
ULONG_PTR ueNumberOfBytesRead;
DWORD dwPossibleIATPointer;
ULONG_PTR qwPossibleIATPointer;
ULONG_PTR PossibleIATPointer;
ULONG_PTR TracedIATPointer;
PMEMORY_COMPARE_HANDLER currentSearchPos;
DWORD SetionVirtualOffset;
ULONG_PTR TestReadData;
DWORD LastDllId = 1024;
bool FileIs64 = false;
bool PossibleThunk = false;
bool UpdateJump = false;
DWORD CurrentDllId;
char* szDLLName;
char* szAPIName;
DWORD TraceIndex;
DWORD Dummy;
if(hProcess == NULL)
{
return(0x401); // Error, process terminated
}
if(SearchStep == NULL)
{
SearchStep++;
}
if(DumpRunningProcess)
{
if(!DumpProcessW(hProcess, (LPVOID)ImageBase, szDumpedFile, EntryPointAddress))
{
return(NULL); // Critical error! *just to be safe, but it should never happen!
}
}
aEnumeratedModules = VirtualAlloc(NULL, 0x2000, MEM_COMMIT, PAGE_READWRITE);
if(EnumProcessModules(hProcess, (HMODULE*)aEnumeratedModules, 0x2000, &Dummy))
{
aSearchMemory = VirtualAlloc(NULL, SearchSize, MEM_COMMIT, PAGE_READWRITE);
cSearchMemory = aSearchMemory;
__try
{
if(SearchStart == NULL || ReadProcessMemory(hProcess, (LPVOID)SearchStart, aSearchMemory, SearchSize, &ueNumberOfBytesRead))
{
ImporterInit(MAX_IMPORT_ALLOC, ImageBase);
if(SearchStart != NULL)
{
//SearchSize = SearchSize / SearchStep;
while((int)SearchSize > NULL)
{
RtlMoveMemory(&PossibleIATPointer, cSearchMemory, sizeof ULONG_PTR);
if(ReadProcessMemory(hProcess, (LPVOID)PossibleIATPointer, &TestReadData, sizeof ULONG_PTR, &ueNumberOfBytesRead))
{
//CurrentDllId = ImporterGetDLLIndexEx(PossibleIATPointer, (ULONG_PTR)aEnumeratedModules);
CurrentDllId = ImporterGetDLLIndex(hProcess, PossibleIATPointer, (ULONG_PTR)aEnumeratedModules);
if(CurrentDllId == NULL && TryAutoFix == true)
{
TraceIndex = TracerDetectRedirection(hProcess, PossibleIATPointer);
if(TraceIndex > NULL)
{
PossibleIATPointer = (ULONG_PTR)TracerFixKnownRedirection(hProcess, PossibleIATPointer, TraceIndex);
if(PossibleIATPointer != NULL)
{
//CurrentDllId = ImporterGetDLLIndexEx(PossibleIATPointer, (ULONG_PTR)aEnumeratedModules);
CurrentDllId = ImporterGetDLLIndex(hProcess, PossibleIATPointer, (ULONG_PTR)aEnumeratedModules);
}
}
else
{
TracedIATPointer = (ULONG_PTR)TracerLevel1(hProcess, PossibleIATPointer);
if(TracedIATPointer > 0x1000)
{
PossibleIATPointer = TracedIATPointer;
//CurrentDllId = ImporterGetDLLIndexEx(PossibleIATPointer, (ULONG_PTR)aEnumeratedModules);
CurrentDllId = ImporterGetDLLIndex(hProcess, PossibleIATPointer, (ULONG_PTR)aEnumeratedModules);
}
else
{
if(TracedIATPointer != NULL)
{
TracedIATPointer = (ULONG_PTR)HashTracerLevel1(hProcess, PossibleIATPointer, (DWORD)TracedIATPointer);
if(TracedIATPointer != NULL)
{
PossibleIATPointer = TracedIATPointer;
//CurrentDllId = ImporterGetDLLIndexEx(PossibleIATPointer, (ULONG_PTR)aEnumeratedModules);
CurrentDllId = ImporterGetDLLIndex(hProcess, PossibleIATPointer, (ULONG_PTR)aEnumeratedModules);
}
}
}
}
}
if(CurrentDllId == NULL && UnknownPointerFixCallback != NULL)
{
__try
{
PossibleIATPointer = (ULONG_PTR)myFixerCallback((LPVOID)PossibleIATPointer);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
UnknownPointerFixCallback = NULL;
PossibleIATPointer = NULL;
}
if(PossibleIATPointer != NULL)
{
//CurrentDllId = ImporterGetDLLIndexEx(PossibleIATPointer, (ULONG_PTR)aEnumeratedModules);
CurrentDllId = ImporterGetDLLIndex(hProcess, PossibleIATPointer, (ULONG_PTR)aEnumeratedModules);
}
}
if(CurrentDllId != NULL)
{
if(LastDllId != CurrentDllId)
{
LastDllId = CurrentDllId;
szDLLName = (char*)ImporterGetDLLNameFromDebugee(hProcess, PossibleIATPointer);
szAPIName = (char*)ImporterGetAPINameFromDebugee(hProcess, PossibleIATPointer);
if(szDLLName != NULL && szAPIName != NULL)
{
ImporterAddNewDll(szDLLName, (ULONG_PTR)((ULONG_PTR)cSearchMemory - (ULONG_PTR)aSearchMemory + SearchStart));
ImporterAddNewAPI(szAPIName, (ULONG_PTR)((ULONG_PTR)cSearchMemory - (ULONG_PTR)aSearchMemory + SearchStart));
}
else if(szDLLName != NULL && szAPIName == NULL)
{
ImporterAddNewDll(szDLLName, (ULONG_PTR)((ULONG_PTR)cSearchMemory - (ULONG_PTR)aSearchMemory + SearchStart));
ImporterAddNewAPI((char*)ImporterGetAPIOrdinalNumberFromDebugee(hProcess, PossibleIATPointer), (ULONG_PTR)((ULONG_PTR)cSearchMemory - (ULONG_PTR)aSearchMemory + SearchStart));
}
}
else
{
szAPIName = (char*)ImporterGetAPINameFromDebugee(hProcess, PossibleIATPointer);
if(szAPIName != NULL)
{
ImporterAddNewAPI(szAPIName, (ULONG_PTR)((ULONG_PTR)cSearchMemory - (ULONG_PTR)aSearchMemory + SearchStart));
}
else
{
szAPIName = (char*)ImporterGetAPIOrdinalNumberFromDebugee(hProcess, PossibleIATPointer);
if(szAPIName != NULL)
{
ImporterAddNewAPI(szAPIName, (ULONG_PTR)((ULONG_PTR)cSearchMemory - (ULONG_PTR)aSearchMemory + SearchStart));
}
}
}
}
}
else
{
if(PossibleIATPointer == NULL)
{
LastDllId = NULL;
}
}
cSearchMemory = (LPVOID)((ULONG_PTR)cSearchMemory + SearchStep);
SearchSize = SearchSize - SearchStep;
}
}
if(FixEliminations)
{
LastDllId = 1024;
if(ImporterGetAddedDllCount() == NULL)
{
ImporterCleanup();
ImporterInit(MAX_IMPORT_ALLOC, ImageBase);
}
if(GetPE32DataExW(szDumpedFile, &PEStructure))
{
if(MapFileExW(szDumpedFile, UE_ACCESS_ALL, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
ImporterMoveIAT();
ImporterSetUnknownDelta((ULONG_PTR)EngineEstimateNewSectionRVA(FileMapVA));
for(i = 0; i < PEStructure.SectionNumber; i++)
{
if(GetPE32DataFromMappedFile(FileMapVA, i, UE_SECTIONRAWSIZE) > 4)
{
SectionFlags = (DWORD)GetPE32DataFromMappedFile(FileMapVA, i, UE_SECTIONFLAGS);
SetionVirtualOffset = (DWORD)GetPE32DataFromMappedFile(FileMapVA, i, UE_SECTIONVIRTUALOFFSET);
if(SectionFlags & IMAGE_SCN_MEM_EXECUTE || SectionFlags & IMAGE_SCN_CNT_CODE || SectionFlags & IMAGE_SCN_MEM_WRITE || SectionFlags & IMAGE_SCN_CNT_INITIALIZED_DATA)
{
currentSearchPos = (PMEMORY_COMPARE_HANDLER)(FileMapVA + GetPE32DataFromMappedFile(FileMapVA, i, UE_SECTIONRAWOFFSET));
currentSectionSize = (int)GetPE32DataFromMappedFile(FileMapVA, i, UE_SECTIONRAWSIZE) - 6;
for(j = 0; j < currentSectionSize; j++)
{
if(!FileIs64)
{
// x86
delta = 0;
PossibleThunk = false;
UpdateJump = false;
if(currentSearchPos->Array.bArrayEntry[0] == 0xFF && (currentSearchPos->Array.bArrayEntry[1] == 0x15 || currentSearchPos->Array.bArrayEntry[1] == 0x25))
{
currentSearchPos = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)currentSearchPos + 2);
PossibleIATPointer = currentSearchPos->Array.dwArrayEntry[0];
currentSearchPos = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)currentSearchPos - 2);
if(PossibleIATPointer > PEStructure.ImageBase && PossibleIATPointer < PEStructure.ImageBase + PEStructure.NtSizeOfImage)
{
PossibleThunk = true;
delta = 2;
}
else
{
VirtualQueryEx(hProcess, (LPVOID)PossibleIATPointer, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
if(MemInfo.State == MEM_COMMIT && (MemInfo.Protect & PAGE_READWRITE || MemInfo.Protect & PAGE_EXECUTE_READWRITE || MemInfo.Protect & PAGE_EXECUTE))
{
PossibleIATPointer = currentSearchPos->Array.dwArrayEntry[0];
PossibleThunk = true;
delta = 2;
}
}
}
else if(currentSearchPos->Array.bArrayEntry[0] == 0xE8 || currentSearchPos->Array.bArrayEntry[0] == 0xE9)
{
currentSearchPos = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)currentSearchPos + 1);
PossibleIATPointer = currentSearchPos->Array.dwArrayEntry[0] + j + SetionVirtualOffset + ImageBase;
currentSearchPos = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)currentSearchPos - 1);
if(PossibleIATPointer > PEStructure.ImageBase && PossibleIATPointer < PEStructure.ImageBase + PEStructure.NtSizeOfImage)
{
PossibleThunk = true;
UpdateJump = true;
delta = 1;
}
else
{
VirtualQueryEx(hProcess, (LPVOID)PossibleIATPointer, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
if(MemInfo.State == MEM_COMMIT && (MemInfo.Protect & PAGE_READWRITE || MemInfo.Protect & PAGE_EXECUTE_READWRITE || MemInfo.Protect & PAGE_EXECUTE))
{
PossibleIATPointer = currentSearchPos->Array.dwArrayEntry[0];
PossibleThunk = true;
UpdateJump = true;
delta = 1;
}
}
}
else if(currentSearchPos->Array.dwArrayEntry[0] > PEStructure.ImageBase && currentSearchPos->Array.dwArrayEntry[0] < PEStructure.ImageBase + PEStructure.NtSizeOfImage)
{
PossibleIATPointer = currentSearchPos->Array.dwArrayEntry[0];
PossibleThunk = true;
delta = 0;
}
else
{
VirtualQueryEx(hProcess, (LPVOID)currentSearchPos->Array.dwArrayEntry[0], &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
if(MemInfo.State == MEM_COMMIT && (MemInfo.Protect & PAGE_READWRITE || MemInfo.Protect & PAGE_EXECUTE_READWRITE || MemInfo.Protect & PAGE_EXECUTE))
{
PossibleIATPointer = currentSearchPos->Array.dwArrayEntry[0];
PossibleThunk = true;
delta = 0;
}
}
if(PossibleThunk)
{
if(ReadProcessMemory(hProcess, (LPVOID)PossibleIATPointer, &dwPossibleIATPointer, 4, &ueNumberOfBytesRead))
{
VirtualQueryEx(hProcess, (LPVOID)dwPossibleIATPointer, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
if(MemInfo.State == MEM_COMMIT && (MemInfo.Protect >= PAGE_READONLY || MemInfo.Protect <= PAGE_EXECUTE_READWRITE))
{
PossibleIATPointer = (ULONG_PTR)dwPossibleIATPointer;
//CurrentDllId = ImporterGetDLLIndexEx(PossibleIATPointer, (ULONG_PTR)aEnumeratedModules);
CurrentDllId = ImporterGetDLLIndex(hProcess, PossibleIATPointer, (ULONG_PTR)aEnumeratedModules);
if(CurrentDllId == NULL && TryAutoFix == true)
{
TraceIndex = TracerDetectRedirection(hProcess, PossibleIATPointer);
if(TraceIndex > NULL)
{
PossibleIATPointer = (ULONG_PTR)TracerFixKnownRedirection(hProcess, PossibleIATPointer, TraceIndex);
if(PossibleIATPointer != NULL)
{
//CurrentDllId = ImporterGetDLLIndexEx(PossibleIATPointer, (ULONG_PTR)aEnumeratedModules);
CurrentDllId = ImporterGetDLLIndex(hProcess, PossibleIATPointer, (ULONG_PTR)aEnumeratedModules);
}
}
else
{
TracedIATPointer = (ULONG_PTR)TracerLevel1(hProcess, PossibleIATPointer);
if(TracedIATPointer > 0x1000)
{
PossibleIATPointer = TracedIATPointer;
//CurrentDllId = ImporterGetDLLIndexEx(PossibleIATPointer, (ULONG_PTR)aEnumeratedModules);
CurrentDllId = ImporterGetDLLIndex(hProcess, PossibleIATPointer, (ULONG_PTR)aEnumeratedModules);
}
else
{
if(TracedIATPointer != NULL)
{
TracedIATPointer = (ULONG_PTR)HashTracerLevel1(hProcess, PossibleIATPointer, (DWORD)TracedIATPointer);
if(TracedIATPointer != NULL)
{
PossibleIATPointer = TracedIATPointer;
//CurrentDllId = ImporterGetDLLIndexEx(PossibleIATPointer, (ULONG_PTR)aEnumeratedModules);
CurrentDllId = ImporterGetDLLIndex(hProcess, PossibleIATPointer, (ULONG_PTR)aEnumeratedModules);
}
}
}
}
}
if(CurrentDllId == NULL && UnknownPointerFixCallback != NULL)
{
__try
{
PossibleIATPointer = (ULONG_PTR)myFixerCallback((LPVOID)PossibleIATPointer);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
UnknownPointerFixCallback = NULL;
PossibleIATPointer = NULL;
}
if(PossibleIATPointer != NULL)
{
//CurrentDllId = ImporterGetDLLIndexEx(PossibleIATPointer, (ULONG_PTR)aEnumeratedModules);
CurrentDllId = ImporterGetDLLIndex(hProcess, PossibleIATPointer, (ULONG_PTR)aEnumeratedModules);
}
}
if(CurrentDllId != NULL)
{
szDLLName = (char*)ImporterGetDLLNameFromDebugee(hProcess, PossibleIATPointer);
szAPIName = (char*)ImporterGetAPINameFromDebugee(hProcess, PossibleIATPointer);
if(szAPIName == NULL)
{
szAPIName = (char*)ImporterGetAPIOrdinalNumberFromDebugee(hProcess, PossibleIATPointer);
}
if(szDLLName != NULL && szAPIName != NULL)
{
if(ImporterGetAddedDllCount() > NULL)
{
PossibleIATPointer = (ULONG_PTR)ImporterFindAPIWriteLocation(szAPIName);
}
else
{
PossibleIATPointer = NULL;
}
if(PossibleIATPointer != NULL)
{
dwPossibleIATPointer = (DWORD)(PossibleIATPointer);
if(!UpdateJump)
{
RtlMoveMemory(&currentSearchPos->Array.dwArrayEntry[0 + delta], &dwPossibleIATPointer, 4);
}
else
{
dwPossibleIATPointer = dwPossibleIATPointer - (j + SetionVirtualOffset) - (DWORD)ImageBase - 5;
RtlMoveMemory(&currentSearchPos->Array.dwArrayEntry[0 + delta], &dwPossibleIATPointer, 4);
}
currentSearchPos = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)currentSearchPos + delta + 4 - 1);
}
else
{
if(CurrentDllId != LastDllId)
{
LastDllId = CurrentDllId;
ImporterAddNewDll(szDLLName, NULL);
dwPossibleIATPointer = (DWORD)(ImporterGetCurrentDelta());
if(!UpdateJump)
{
RtlMoveMemory(&currentSearchPos->Array.dwArrayEntry[0 + delta], &dwPossibleIATPointer, 4);
}
else
{
dwPossibleIATPointer = dwPossibleIATPointer - (j + SetionVirtualOffset) - (DWORD)ImageBase - 5;
RtlMoveMemory(&currentSearchPos->Array.dwArrayEntry[0 + delta], &dwPossibleIATPointer, 4);
}
ImporterAddNewAPI(szAPIName, NULL);
currentSearchPos = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)currentSearchPos + delta + 4 - 1);
}
else
{
dwPossibleIATPointer = (DWORD)(ImporterGetCurrentDelta());
if(!UpdateJump)
{
RtlMoveMemory(&currentSearchPos->Array.dwArrayEntry[0 + delta], &dwPossibleIATPointer, 4);
}
else
{
dwPossibleIATPointer = dwPossibleIATPointer - (j + SetionVirtualOffset) - (DWORD)ImageBase - 5;
RtlMoveMemory(&currentSearchPos->Array.dwArrayEntry[0 + delta], &dwPossibleIATPointer, 4);
}
ImporterAddNewAPI(szAPIName, NULL);
currentSearchPos = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)currentSearchPos + delta + 4 - 1);
}
}
}
}
}
}
else
{
if(PossibleIATPointer == NULL)
{
LastDllId = NULL;
}
}
}
}
else
{
// x64
delta = 0;
PossibleThunk = false;
UpdateJump = false;
if(currentSearchPos->Array.bArrayEntry[0] == 0xFF && (currentSearchPos->Array.bArrayEntry[1] == 0x15 || currentSearchPos->Array.bArrayEntry[1] == 0x25))
{
currentSearchPos = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)currentSearchPos + 2);
PossibleIATPointer = currentSearchPos->Array.dwArrayEntry[0] + j + SetionVirtualOffset + ImageBase;
currentSearchPos = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)currentSearchPos - 2);
if(PossibleIATPointer > PEStructure.ImageBase && PossibleIATPointer < PEStructure.ImageBase + PEStructure.NtSizeOfImage)
{
PossibleThunk = true;
delta = 2;
}
else
{
VirtualQueryEx(hProcess, (LPVOID)PossibleIATPointer, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
if(MemInfo.State == MEM_COMMIT && (MemInfo.Protect & PAGE_READWRITE || MemInfo.Protect & PAGE_EXECUTE_READWRITE || MemInfo.Protect & PAGE_EXECUTE))
{
PossibleIATPointer = currentSearchPos->Array.dwArrayEntry[0];
PossibleThunk = true;
delta = 2;
}
}
}
else if(currentSearchPos->Array.bArrayEntry[0] == 0xE8 || currentSearchPos->Array.bArrayEntry[0] == 0xE9)
{
currentSearchPos = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)currentSearchPos + 1);
PossibleIATPointer = currentSearchPos->Array.dwArrayEntry[0] + j + SetionVirtualOffset + ImageBase;
currentSearchPos = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)currentSearchPos - 1);
if(PossibleIATPointer > PEStructure.ImageBase && PossibleIATPointer < PEStructure.ImageBase + PEStructure.NtSizeOfImage)
{
PossibleThunk = true;
UpdateJump = true;
delta = 1;
}
else
{
VirtualQueryEx(hProcess, (LPVOID)PossibleIATPointer, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
if(MemInfo.State == MEM_COMMIT && (MemInfo.Protect & PAGE_READWRITE || MemInfo.Protect & PAGE_EXECUTE_READWRITE || MemInfo.Protect & PAGE_EXECUTE))
{
PossibleIATPointer = currentSearchPos->Array.dwArrayEntry[0];
PossibleThunk = true;
UpdateJump = true;
delta = 1;
}
}
}
else if(currentSearchPos->Array.dwArrayEntry[0] + j + SetionVirtualOffset > PEStructure.ImageBase && currentSearchPos->Array.dwArrayEntry[0] + j + SetionVirtualOffset < PEStructure.ImageBase + PEStructure.NtSizeOfImage)
{
PossibleIATPointer = currentSearchPos->Array.dwArrayEntry[0] + j + SetionVirtualOffset + ImageBase;
PossibleThunk = true;
delta = 0;
}
else
{
VirtualQueryEx(hProcess, (LPVOID)(currentSearchPos->Array.dwArrayEntry[0] + j + SetionVirtualOffset), &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
if(MemInfo.State == MEM_COMMIT && (MemInfo.Protect & PAGE_READWRITE || MemInfo.Protect & PAGE_EXECUTE_READWRITE || MemInfo.Protect & PAGE_EXECUTE))
{
PossibleIATPointer = currentSearchPos->Array.dwArrayEntry[0] + j + SetionVirtualOffset + ImageBase;
PossibleThunk = true;
delta = 0;
}
}
if(PossibleThunk)
{
if(ReadProcessMemory(hProcess, (LPVOID)PossibleIATPointer, &qwPossibleIATPointer, 8, &ueNumberOfBytesRead))
{
VirtualQueryEx(hProcess, (LPVOID)qwPossibleIATPointer, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
if(MemInfo.State == MEM_COMMIT && (MemInfo.Protect >= PAGE_READONLY || MemInfo.Protect <= PAGE_EXECUTE_READWRITE))
{
PossibleIATPointer = qwPossibleIATPointer;
//CurrentDllId = ImporterGetDLLIndexEx(PossibleIATPointer, (ULONG_PTR)aEnumeratedModules);
CurrentDllId = ImporterGetDLLIndex(hProcess, PossibleIATPointer, (ULONG_PTR)aEnumeratedModules);
if(CurrentDllId == NULL && TryAutoFix == true)
{
TraceIndex = TracerDetectRedirection(hProcess, PossibleIATPointer);
if(TraceIndex > NULL)
{
PossibleIATPointer = (ULONG_PTR)TracerFixKnownRedirection(hProcess, PossibleIATPointer, TraceIndex);
if(PossibleIATPointer != NULL)
{
//CurrentDllId = ImporterGetDLLIndexEx(PossibleIATPointer, (ULONG_PTR)aEnumeratedModules);
CurrentDllId = ImporterGetDLLIndex(hProcess, PossibleIATPointer, (ULONG_PTR)aEnumeratedModules);
}
}
else
{
TracedIATPointer = (ULONG_PTR)TracerLevel1(hProcess, PossibleIATPointer);
if(TracedIATPointer > 0x1000)
{
PossibleIATPointer = TracedIATPointer;
//CurrentDllId = ImporterGetDLLIndexEx(PossibleIATPointer, (ULONG_PTR)aEnumeratedModules);
CurrentDllId = ImporterGetDLLIndex(hProcess, PossibleIATPointer, (ULONG_PTR)aEnumeratedModules);
}
else
{
if(TracedIATPointer != NULL)
{
TracedIATPointer = (ULONG_PTR)HashTracerLevel1(hProcess, PossibleIATPointer, (DWORD)TracedIATPointer);
if(TracedIATPointer != NULL)
{
PossibleIATPointer = TracedIATPointer;
//CurrentDllId = ImporterGetDLLIndexEx(PossibleIATPointer, (ULONG_PTR)aEnumeratedModules);
CurrentDllId = ImporterGetDLLIndex(hProcess, PossibleIATPointer, (ULONG_PTR)aEnumeratedModules);
}
}
}
}
}
if(CurrentDllId == NULL && UnknownPointerFixCallback != NULL)
{
__try
{
PossibleIATPointer = (ULONG_PTR)myFixerCallback((LPVOID)PossibleIATPointer);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
UnknownPointerFixCallback = NULL;
PossibleIATPointer = NULL;
}
if(PossibleIATPointer != NULL)
{
//CurrentDllId = ImporterGetDLLIndexEx(PossibleIATPointer, (ULONG_PTR)aEnumeratedModules);
CurrentDllId = ImporterGetDLLIndex(hProcess, PossibleIATPointer, (ULONG_PTR)aEnumeratedModules);
}
}
if(CurrentDllId != NULL)
{
szDLLName = (char*)ImporterGetDLLNameFromDebugee(hProcess, PossibleIATPointer);
szAPIName = (char*)ImporterGetAPINameFromDebugee(hProcess, PossibleIATPointer);
if(szAPIName == NULL)
{
szAPIName = (char*)ImporterGetAPIOrdinalNumberFromDebugee(hProcess, PossibleIATPointer);
}
if(szDLLName != NULL && szAPIName != NULL)
{
if(ImporterGetAddedDllCount() > NULL)
{
PossibleIATPointer = (ULONG_PTR)ImporterFindAPIWriteLocation(szAPIName);
}
else
{
PossibleIATPointer = NULL;
}
if(PossibleIATPointer != NULL)
{
if(!UpdateJump)
{
dwPossibleIATPointer = (DWORD)(PossibleIATPointer - j - SetionVirtualOffset - ImageBase);
RtlMoveMemory(&currentSearchPos->Array.dwArrayEntry[0 + delta], &dwPossibleIATPointer, 4);
}
else
{
dwPossibleIATPointer = (DWORD)(PossibleIATPointer);
dwPossibleIATPointer = (DWORD)(dwPossibleIATPointer - (j + SetionVirtualOffset) - (ULONG_PTR)ImageBase - 5);
RtlMoveMemory(&currentSearchPos->Array.dwArrayEntry[0 + delta], &dwPossibleIATPointer, 4);
}
currentSearchPos = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)currentSearchPos + delta + 4 - 1);
}
else
{
if(CurrentDllId != LastDllId)
{
LastDllId = CurrentDllId;
ImporterAddNewDll(szDLLName, NULL);
qwPossibleIATPointer = (ULONG_PTR)(ImporterGetCurrentDelta());
if(!UpdateJump)
{
qwPossibleIATPointer = (DWORD)(qwPossibleIATPointer - j - SetionVirtualOffset - ImageBase);
RtlMoveMemory(&currentSearchPos->Array.dwArrayEntry[0 + delta], &qwPossibleIATPointer, 4);
}
else
{
qwPossibleIATPointer = (DWORD)(qwPossibleIATPointer - j - SetionVirtualOffset - ImageBase - 5);
RtlMoveMemory(&currentSearchPos->Array.dwArrayEntry[0 + delta], &qwPossibleIATPointer, 4);
}
ImporterAddNewAPI(szAPIName, NULL);
currentSearchPos = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)currentSearchPos + delta + 4 - 1);
}
else
{
qwPossibleIATPointer = (ULONG_PTR)(ImporterGetCurrentDelta());
if(!UpdateJump)
{
qwPossibleIATPointer = (DWORD)(qwPossibleIATPointer - j - SetionVirtualOffset - ImageBase);
RtlMoveMemory(&currentSearchPos->Array.dwArrayEntry[0 + delta], &qwPossibleIATPointer, 4);
}
else
{
qwPossibleIATPointer = (DWORD)(qwPossibleIATPointer - j - SetionVirtualOffset - ImageBase - 5);
RtlMoveMemory(&currentSearchPos->Array.dwArrayEntry[0 + delta], &qwPossibleIATPointer, 4);
}
ImporterAddNewAPI(szAPIName, NULL);
currentSearchPos = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)currentSearchPos + delta + 4 - 1);
}
}
}
}
}
}
else
{
if(PossibleIATPointer == NULL)
{
LastDllId = NULL;
}
}
}
}
currentSearchPos = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)currentSearchPos + 1);
}
}
}
}
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
}
else
{
return(0x405); // Error, no API found!
}
}
}
VirtualFree(aEnumeratedModules, NULL, MEM_RELEASE);
VirtualFree(aSearchMemory, NULL, MEM_RELEASE);
if(ImporterGetAddedDllCount() > NULL && ImporterGetAddedAPICount() > NULL)
{
if(!ImporterExportIATExW(szDumpedFile, szSectionName))
{
return(NULL); // Critical error! *just to be safe, but it should never happen!
}
}
else
{
return(0x405); // Error, no API found!
}
if(RealignFile)
{
if(MapFileExW(szDumpedFile, UE_ACCESS_ALL, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
FileSize = RealignPE(FileMapVA, FileSize, NULL);
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
}
else
{
return(0x406); // Success, but realign failed!
}
}
return(0x400); // Success!
}
else
{
VirtualFree(aEnumeratedModules, NULL, MEM_RELEASE);
VirtualFree(aSearchMemory, NULL, MEM_RELEASE);
return(0x404); // Error, memory could not be read!
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
ImporterCleanup();
VirtualFree(aEnumeratedModules, NULL, MEM_RELEASE);
VirtualFree(aSearchMemory, NULL, MEM_RELEASE);
return(NULL); // Critical error! *just to be safe, but it should never happen!
}
}
VirtualFree(aEnumeratedModules, NULL, MEM_RELEASE);
return(NULL); // Critical error! *just te bo safe, but it should never happen!
}
__declspec(dllexport) long TITCALL ImporterAutoFixIAT(HANDLE hProcess, char* szDumpedFile, ULONG_PTR ImageBase, ULONG_PTR SearchStart, DWORD SearchSize, DWORD SearchStep)
{
return(ImporterAutoFixIATEx(hProcess, szDumpedFile, ".RL!TEv2", false, false, NULL, ImageBase, SearchStart, SearchSize, SearchStep, false, false, NULL));
}
__declspec(dllexport) long TITCALL ImporterAutoFixIATW(HANDLE hProcess, wchar_t* szDumpedFile, ULONG_PTR ImageBase, ULONG_PTR SearchStart, DWORD SearchSize, DWORD SearchStep)
{
return(ImporterAutoFixIATExW(hProcess, szDumpedFile, ".RL!TEv2", false, false, NULL, ImageBase, SearchStart, SearchSize, SearchStep, false, false, NULL));
}
// Internal.Engine.Hook.functions:
bool ProcessHookScanAddNewHook(PHOOK_ENTRY HookDetails, void* ptrOriginalInstructions, PLIBRARY_ITEM_DATAW ModuleInformation, DWORD SizeOfImage)
{
HOOK_ENTRY MyhookEntry = {};
RtlMoveMemory(&MyhookEntry, HookDetails, sizeof HOOK_ENTRY);
hookEntry.push_back(MyhookEntry);
return(true);
}
// Global.Engine.Hook.functions:
__declspec(dllexport) bool TITCALL HooksSafeTransitionEx(LPVOID HookAddressArray, int NumberOfHooks, bool TransitionStart)
{
int i;
ULONG_PTR CurrentIP;
ULONG_PTR HookAddress;
PTHREAD_ITEM_DATA hListThreadPtr = (PTHREAD_ITEM_DATA)hListThread;
PMEMORY_COMPARE_HANDLER myHookAddressArray;
if(dbgProcessInformation.hProcess == NULL)
{
if(!TransitionStart || ThreaderImportRunningThreadData(GetCurrentProcessId()))
{
hListThreadPtr = (PTHREAD_ITEM_DATA)hListThread;
if(hListThreadPtr != NULL)
{
while(hListThreadPtr->hThread != NULL)
{
if(hListThreadPtr->hThread != INVALID_HANDLE_VALUE)
{
if(TransitionStart)
{
if(hListThreadPtr->dwThreadId != GetCurrentThreadId())
{
SuspendThread(hListThreadPtr->hThread);
CurrentIP = (ULONG_PTR)GetContextDataEx(hListThreadPtr->hThread, UE_CIP);
myHookAddressArray = (PMEMORY_COMPARE_HANDLER)HookAddressArray;
for(i = 0; i < NumberOfHooks; i++)
{
#if defined (_WIN64)
HookAddress = (ULONG_PTR)myHookAddressArray->Array.qwArrayEntry[0];
myHookAddressArray = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)myHookAddressArray + sizeof ULONG_PTR);
#else
HookAddress = (ULONG_PTR)myHookAddressArray->Array.dwArrayEntry[0];
myHookAddressArray = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)myHookAddressArray + sizeof ULONG_PTR);
#endif
while(CurrentIP >= (ULONG_PTR)HookAddress && CurrentIP <= (ULONG_PTR)HookAddress + 5)
{
ResumeThread(hListThreadPtr->hThread);
Sleep(5);
SuspendThread(hListThreadPtr->hThread);
CurrentIP = (ULONG_PTR)GetContextDataEx(hListThreadPtr->hThread, UE_CIP);
i = 0;
}
}
}
}
else
{
ResumeThread(hListThreadPtr->hThread);
EngineCloseHandle(hListThreadPtr->hThread);
}
}
hListThreadPtr = (PTHREAD_ITEM_DATA)((ULONG_PTR)hListThreadPtr + sizeof THREAD_ITEM_DATA);
}
if(!TransitionStart)
{
VirtualFree(hListThread, NULL, MEM_RELEASE);
hListThread = NULL;
}
return(true);
}
}
else
{
return(false);
}
}
return(false);
}
__declspec(dllexport) bool TITCALL HooksSafeTransition(LPVOID HookAddress, bool TransitionStart)
{
void* aHookAddress[1];
aHookAddress[0] = HookAddress;
return(HooksSafeTransitionEx(&aHookAddress[0], sizeof aHookAddress, TransitionStart));
}
__declspec(dllexport) bool TITCALL HooksIsAddressRedirected(LPVOID HookAddress)
{
for(unsigned int i = 0; i < hookEntry.size(); i++)
{
if(hookEntry[i].HookAddress == HookAddress && hookEntry[i].IATHook == false && hookEntry[i].HookIsEnabled == true)
{
return(true);
}
}
return(false);
}
__declspec(dllexport) void* TITCALL HooksGetTrampolineAddress(LPVOID HookAddress)
{
for(unsigned int i = 0; i < hookEntry.size(); i++)
{
if(hookEntry[i].HookAddress == HookAddress)
{
return(hookEntry[i].PatchedEntry);
}
}
return(NULL);
}
__declspec(dllexport) void* TITCALL HooksGetHookEntryDetails(LPVOID HookAddress)
{
for(unsigned int i = 0; i < hookEntry.size(); i++)
{
if(hookEntry[i].HookAddress == HookAddress)
{
return(&hookEntry[i]);
}
}
return(NULL);
}
__declspec(dllexport) bool TITCALL HooksInsertNewRedirection(LPVOID HookAddress, LPVOID RedirectTo, int HookType)
{
#if !defined(_WIN64)
int j;
unsigned int i;
#endif
HOOK_ENTRY myHook = {};
DWORD CalculatedRealingJump;
ULONG_PTR x64CalculatedRealingJump;
ULONG_PTR RealignAddressTarget;
int ProcessedBufferSize = NULL;
int CurrentInstructionSize = NULL;
PMEMORY_COMPARE_HANDLER WriteMemory = (PMEMORY_COMPARE_HANDLER)CwpBuffPatchedEntry;
PMEMORY_COMPARE_HANDLER CompareMemory;
#if !defined(_WIN64)
PMEMORY_COMPARE_HANDLER RelocateMemory;
#endif
void* cHookAddress = HookAddress;
DWORD OldProtect = PAGE_READONLY;
void* TempBuffPatchedEntry;
bool returnData;
x64CalculatedRealingJump = NULL;
if(buffPatchedEntry == NULL || (ULONG_PTR)CwpBuffPatchedEntry - (ULONG_PTR)buffPatchedEntry + TEE_MAXIMUM_HOOK_SIZE > buffPatchedEntrySize)
{
buffPatchedEntrySize = buffPatchedEntrySize + 0x1000;
CwpBuffPatchedEntry = (void*)((ULONG_PTR)CwpBuffPatchedEntry - (ULONG_PTR)buffPatchedEntry);
TempBuffPatchedEntry = VirtualAlloc(NULL, buffPatchedEntrySize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if(TempBuffPatchedEntry != NULL)
{
if(hookEntry.size() > NULL)
{
RtlMoveMemory(TempBuffPatchedEntry, buffPatchedEntry, (ULONG_PTR)CwpBuffPatchedEntry);
}
#if !defined(_WIN64)
for(i = 0; i < hookEntry.size(); i++)
{
hookEntry[i].PatchedEntry = (void*)((ULONG_PTR)hookEntry[i].PatchedEntry - (ULONG_PTR)buffPatchedEntry + (ULONG_PTR)TempBuffPatchedEntry);
CalculatedRealingJump = (DWORD)((ULONG_PTR)hookEntry[i].PatchedEntry - (ULONG_PTR)hookEntry[i].HookAddress - 5);
RtlMoveMemory(&hookEntry[i].HookBytes[1], &CalculatedRealingJump, 4);
if(hookEntry[i].RelocationCount > NULL)
{
for(j = 0; j < hookEntry[i].RelocationCount; j++)
{
CompareMemory = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)buffPatchedEntry + hookEntry[i].RelocationInfo[j]);
RelocateMemory = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)TempBuffPatchedEntry + hookEntry[i].RelocationInfo[j]);
CurrentInstructionSize = StaticLengthDisassemble((void*)CompareMemory);
RealignAddressTarget = (ULONG_PTR)GetJumpDestination(GetCurrentProcess(), (ULONG_PTR)CompareMemory);
if(RealignAddressTarget != NULL)
{
if(CompareMemory->Array.bArrayEntry[0] == 0xE9 && CurrentInstructionSize == 5)
{
CalculatedRealingJump = (DWORD)((ULONG_PTR)RealignAddressTarget - (ULONG_PTR)RelocateMemory - CurrentInstructionSize);
RtlMoveMemory(&RelocateMemory->Array.bArrayEntry[1], &CalculatedRealingJump, sizeof CalculatedRealingJump);
}
else if(CompareMemory->Array.bArrayEntry[0] >= 0x70 && CompareMemory->Array.bArrayEntry[0] <= 0x7F && CurrentInstructionSize == 2)
{
CalculatedRealingJump = (DWORD)((ULONG_PTR)RealignAddressTarget - (ULONG_PTR)RelocateMemory - CurrentInstructionSize);
RtlMoveMemory(&RelocateMemory->Array.bArrayEntry[2], &CalculatedRealingJump, sizeof CalculatedRealingJump);
}
else if(CompareMemory->Array.bArrayEntry[0] == 0x0F && CompareMemory->Array.bArrayEntry[1] >= 0x80 && CompareMemory->Array.bArrayEntry[1] <= 0x8F && CurrentInstructionSize == 6)
{
CalculatedRealingJump = (DWORD)((ULONG_PTR)RealignAddressTarget - (ULONG_PTR)RelocateMemory - CurrentInstructionSize);
RtlMoveMemory(&RelocateMemory->Array.bArrayEntry[2], &CalculatedRealingJump, sizeof CalculatedRealingJump);
}
else if(CompareMemory->Array.bArrayEntry[0] == 0xE8 && CurrentInstructionSize == 5)
{
CalculatedRealingJump = (DWORD)((ULONG_PTR)RealignAddressTarget - (ULONG_PTR)RelocateMemory - CurrentInstructionSize);
RtlMoveMemory(&RelocateMemory->Array.bArrayEntry[1], &CalculatedRealingJump, sizeof CalculatedRealingJump);
}
}
}
}
}
#endif
if(hookEntry.size() > NULL)
{
VirtualFree(buffPatchedEntry, NULL, MEM_RELEASE);
}
CwpBuffPatchedEntry = (void*)((ULONG_PTR)CwpBuffPatchedEntry + (ULONG_PTR)TempBuffPatchedEntry);
WriteMemory = (PMEMORY_COMPARE_HANDLER)CwpBuffPatchedEntry;
buffPatchedEntry = TempBuffPatchedEntry;
}
}
while(ProcessedBufferSize < TEE_MAXIMUM_HOOK_INSERT_SIZE)
{
CompareMemory = (PMEMORY_COMPARE_HANDLER)cHookAddress;
CurrentInstructionSize = StaticLengthDisassemble(cHookAddress);
RealignAddressTarget = (ULONG_PTR)GetJumpDestination(GetCurrentProcess(), (ULONG_PTR)cHookAddress);
if(RealignAddressTarget != NULL)
{
if(CompareMemory->Array.bArrayEntry[0] == 0xE9 && CurrentInstructionSize == 5)
{
if(cHookAddress == HookAddress)
{
if(HooksIsAddressRedirected(HookAddress))
{
if(HooksRemoveRedirection(HookAddress, false))
{
returnData = HooksInsertNewRedirection(HookAddress, RedirectTo, HookType);
if(returnData)
{
return(true);
}
else
{
return(false);
}
}
}
}
CalculatedRealingJump = (DWORD)((ULONG_PTR)RealignAddressTarget - (ULONG_PTR)WriteMemory - CurrentInstructionSize);
WriteMemory->Array.bArrayEntry[0] = 0xE9;
RtlMoveMemory(&WriteMemory->Array.bArrayEntry[1], &CalculatedRealingJump, sizeof CalculatedRealingJump);
myHook.RelocationInfo[myHook.RelocationCount] = (DWORD)((ULONG_PTR)WriteMemory - (ULONG_PTR)buffPatchedEntry);
WriteMemory = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)WriteMemory + CurrentInstructionSize);
myHook.RelocationCount++;
}
else if(CompareMemory->Array.bArrayEntry[0] == 0xEB && CurrentInstructionSize == 2)
{
CalculatedRealingJump = (DWORD)((ULONG_PTR)RealignAddressTarget - (ULONG_PTR)WriteMemory - 5);
WriteMemory->Array.bArrayEntry[0] = 0xE9;
RtlMoveMemory(&WriteMemory->Array.bArrayEntry[1], &CalculatedRealingJump, sizeof CalculatedRealingJump);
myHook.RelocationInfo[myHook.RelocationCount] = (DWORD)((ULONG_PTR)WriteMemory - (ULONG_PTR)buffPatchedEntry);
WriteMemory = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)WriteMemory + 5);
myHook.RelocationCount++;
}
else if(CompareMemory->Array.bArrayEntry[0] >= 0x70 && CompareMemory->Array.bArrayEntry[0] <= 0x7F && CurrentInstructionSize == 2)
{
#if !defined(_WIN64)
CalculatedRealingJump = (DWORD)((ULONG_PTR)RealignAddressTarget - (ULONG_PTR)WriteMemory - 6);
WriteMemory->Array.bArrayEntry[0] = 0x0F;
WriteMemory->Array.bArrayEntry[1] = CompareMemory->Array.bArrayEntry[0] + 0x10;
RtlMoveMemory(&WriteMemory->Array.bArrayEntry[2], &CalculatedRealingJump, sizeof CalculatedRealingJump);
myHook.RelocationInfo[myHook.RelocationCount] = (DWORD)((ULONG_PTR)WriteMemory - (ULONG_PTR)buffPatchedEntry);
WriteMemory = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)WriteMemory + 6);
myHook.RelocationCount++;
#else
x64CalculatedRealingJump = RealignAddressTarget;
WriteMemory->Array.bArrayEntry[0] = CompareMemory->Array.bArrayEntry[0];
WriteMemory->Array.bArrayEntry[1] = 0x02;
WriteMemory->Array.bArrayEntry[2] = 0xEB;
WriteMemory->Array.bArrayEntry[3] = 0x0E;
WriteMemory->Array.bArrayEntry[4] = 0xFF;
WriteMemory->Array.bArrayEntry[5] = 0x25;
RtlZeroMemory(&WriteMemory->Array.bArrayEntry[6], 4);
RtlMoveMemory(&WriteMemory->Array.bArrayEntry[10], &x64CalculatedRealingJump, sizeof x64CalculatedRealingJump);
WriteMemory = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)WriteMemory + 18);
#endif
}
else if(CompareMemory->Array.bArrayEntry[0] == 0x0F && CompareMemory->Array.bArrayEntry[1] >= 0x80 && CompareMemory->Array.bArrayEntry[1] <= 0x8F && CurrentInstructionSize == 6)
{
#if !defined(_WIN64)
CalculatedRealingJump = (DWORD)((ULONG_PTR)RealignAddressTarget - (ULONG_PTR)WriteMemory - CurrentInstructionSize);
RtlMoveMemory(&WriteMemory->Array.bArrayEntry[0], &CompareMemory->Array.bArrayEntry[0], 2);
RtlMoveMemory(&WriteMemory->Array.bArrayEntry[2], &CalculatedRealingJump, sizeof CalculatedRealingJump);
myHook.RelocationInfo[myHook.RelocationCount] = (DWORD)((ULONG_PTR)WriteMemory - (ULONG_PTR)buffPatchedEntry);
WriteMemory = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)WriteMemory + CurrentInstructionSize);
myHook.RelocationCount++;
#else
x64CalculatedRealingJump = RealignAddressTarget;
WriteMemory->Array.bArrayEntry[0] = CompareMemory->Array.bArrayEntry[0];
WriteMemory->Array.bArrayEntry[1] = CompareMemory->Array.bArrayEntry[1];
WriteMemory->Array.bArrayEntry[2] = 0x02;
WriteMemory->Array.bArrayEntry[3] = 0x00;
WriteMemory->Array.bArrayEntry[4] = 0x00;
WriteMemory->Array.bArrayEntry[5] = 0x00;
WriteMemory->Array.bArrayEntry[6] = 0xEB;
WriteMemory->Array.bArrayEntry[7] = 0x0E;
WriteMemory->Array.bArrayEntry[8] = 0xFF;
WriteMemory->Array.bArrayEntry[9] = 0x25;
RtlZeroMemory(&WriteMemory->Array.bArrayEntry[10], 4);
RtlMoveMemory(&WriteMemory->Array.bArrayEntry[14], &x64CalculatedRealingJump, sizeof x64CalculatedRealingJump);
WriteMemory = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)WriteMemory + 22);
#endif
}
else if(CompareMemory->Array.bArrayEntry[0] == 0xE8 && CurrentInstructionSize == 5)
{
CalculatedRealingJump = (DWORD)((ULONG_PTR)RealignAddressTarget - (ULONG_PTR)WriteMemory - CurrentInstructionSize);
WriteMemory->Array.bArrayEntry[0] = 0xE8;
RtlMoveMemory(&WriteMemory->Array.bArrayEntry[1], &CalculatedRealingJump, sizeof CalculatedRealingJump);
myHook.RelocationInfo[myHook.RelocationCount] = (DWORD)((ULONG_PTR)WriteMemory - (ULONG_PTR)buffPatchedEntry);
WriteMemory = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)WriteMemory + CurrentInstructionSize);
myHook.RelocationCount++;
#if defined(_WIN64)
}
else if(CompareMemory->Array.bArrayEntry[0] == 0xFF && (CompareMemory->Array.bArrayEntry[1] == 0x15 || CompareMemory->Array.bArrayEntry[1] == 0x25) && CurrentInstructionSize == 6)
{
CalculatedRealingJump = (DWORD)((ULONG_PTR)RealignAddressTarget - (ULONG_PTR)WriteMemory - CurrentInstructionSize);
RtlMoveMemory(&WriteMemory->Array.bArrayEntry[0], &CompareMemory->Array.bArrayEntry[0], 2);
RtlMoveMemory(&WriteMemory->Array.bArrayEntry[2], &CalculatedRealingJump, sizeof CalculatedRealingJump);
WriteMemory = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)WriteMemory + CurrentInstructionSize);
#endif
}
else
{
RtlMoveMemory(&WriteMemory->Array.bArrayEntry[0], cHookAddress, CurrentInstructionSize);
WriteMemory = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)WriteMemory + CurrentInstructionSize);
}
}
else
{
RtlMoveMemory(&WriteMemory->Array.bArrayEntry[0], cHookAddress, CurrentInstructionSize);
WriteMemory = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)WriteMemory + CurrentInstructionSize);
}
cHookAddress = (void*)((ULONG_PTR)cHookAddress + CurrentInstructionSize);
ProcessedBufferSize = ProcessedBufferSize + CurrentInstructionSize;
}
if(ProcessedBufferSize >= TEE_MAXIMUM_HOOK_INSERT_SIZE)
{
WriteMemory->Array.bArrayEntry[0] = 0xFF;
WriteMemory->Array.bArrayEntry[1] = 0x25;
#if !defined(_WIN64)
CalculatedRealingJump = (DWORD)((ULONG_PTR)WriteMemory + 6);
#else
CalculatedRealingJump = NULL;
#endif
RtlMoveMemory(&WriteMemory->Array.bArrayEntry[2], &CalculatedRealingJump, sizeof CalculatedRealingJump);
RtlMoveMemory(&WriteMemory->Array.bArrayEntry[6], &cHookAddress, sizeof CalculatedRealingJump);
WriteMemory = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)WriteMemory + 6 + sizeof ULONG_PTR);
myHook.HookIsEnabled = true;
myHook.HookType = (BYTE)HookType;
myHook.HookAddress = HookAddress;
myHook.RedirectionAddress = RedirectTo;
myHook.PatchedEntry = CwpBuffPatchedEntry;
myHook.HookSize = TEE_MAXIMUM_HOOK_SIZE;
RtlMoveMemory(&myHook.OriginalBytes[0], HookAddress, TEE_MAXIMUM_HOOK_SIZE);
CalculatedRealingJump = (DWORD)((ULONG_PTR)RedirectTo - (ULONG_PTR)HookAddress);
CwpBuffPatchedEntry = (void*)((ULONG_PTR)WriteMemory);
WriteMemory = (PMEMORY_COMPARE_HANDLER)HookAddress;
if(HookType == TEE_HOOK_NRM_JUMP)
{
#if !defined(_WIN64)
CalculatedRealingJump = CalculatedRealingJump - 5;
if(VirtualProtect(HookAddress, TEE_MAXIMUM_HOOK_SIZE, PAGE_EXECUTE_READWRITE, &OldProtect))
{
WriteMemory->Array.bArrayEntry[0] = 0xE9;
RtlMoveMemory(&WriteMemory->Array.bArrayEntry[1], &CalculatedRealingJump, sizeof CalculatedRealingJump);
RtlMoveMemory(&myHook.HookBytes[0], HookAddress, TEE_MAXIMUM_HOOK_SIZE);
VirtualProtect(HookAddress, TEE_MAXIMUM_HOOK_SIZE, OldProtect, &OldProtect);
hookEntry.push_back(myHook);
return(true);
}
#else
if(VirtualProtect(HookAddress, TEE_MAXIMUM_HOOK_SIZE, PAGE_EXECUTE_READWRITE, &OldProtect))
{
WriteMemory->Array.bArrayEntry[0] = 0xFF;
WriteMemory->Array.bArrayEntry[1] = 0x25;
RtlZeroMemory(&WriteMemory->Array.bArrayEntry[2], 4);
RtlMoveMemory(&WriteMemory->Array.bArrayEntry[6], &RedirectTo, sizeof RedirectTo);
RtlMoveMemory(&myHook.HookBytes[0], HookAddress, TEE_MAXIMUM_HOOK_SIZE);
VirtualProtect(HookAddress, TEE_MAXIMUM_HOOK_SIZE, OldProtect, &OldProtect);
hookEntry.push_back(myHook);
return(true);
}
#endif
}
else if(HookType == TEE_HOOK_NRM_CALL)
{
#if !defined(_WIN64)
CalculatedRealingJump = CalculatedRealingJump - 5;
if(VirtualProtect(HookAddress, TEE_MAXIMUM_HOOK_SIZE, PAGE_EXECUTE_READWRITE, &OldProtect))
{
WriteMemory->Array.bArrayEntry[0] = 0xE8;
RtlMoveMemory(&WriteMemory->Array.bArrayEntry[1], &CalculatedRealingJump, sizeof CalculatedRealingJump);
RtlMoveMemory(&myHook.HookBytes[0], HookAddress, TEE_MAXIMUM_HOOK_SIZE);
VirtualProtect(HookAddress, TEE_MAXIMUM_HOOK_SIZE, OldProtect, &OldProtect);
hookEntry.push_back(myHook);
return(true);
}
#else
if(VirtualProtect(HookAddress, TEE_MAXIMUM_HOOK_SIZE, PAGE_EXECUTE_READWRITE, &OldProtect))
{
WriteMemory->Array.bArrayEntry[0] = 0xFF;
WriteMemory->Array.bArrayEntry[1] = 0x15;
RtlZeroMemory(&WriteMemory->Array.bArrayEntry[2], 4);
RtlMoveMemory(&WriteMemory->Array.bArrayEntry[6], &RedirectTo, sizeof RedirectTo);
RtlMoveMemory(&myHook.HookBytes[0], HookAddress, TEE_MAXIMUM_HOOK_SIZE);
VirtualProtect(HookAddress, TEE_MAXIMUM_HOOK_SIZE, OldProtect, &OldProtect);
hookEntry.push_back(myHook);
return(true);
}
#endif
}
}
return(false);
}
__declspec(dllexport) bool TITCALL HooksInsertNewIATRedirectionEx(ULONG_PTR FileMapVA, ULONG_PTR LoadedModuleBase, char* szHookFunction, LPVOID RedirectTo)
{
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
PIMAGE_IMPORT_DESCRIPTOR ImportIID;
PIMAGE_THUNK_DATA32 ThunkData32;
PIMAGE_THUNK_DATA64 ThunkData64;
DWORD OldProtect = PAGE_READONLY;
ULONG_PTR CurrentThunk;
HOOK_ENTRY myHook = {};
BOOL FileIs64;
if(FileMapVA != NULL && LoadedModuleBase != NULL)
{
myHook.IATHook = true;
myHook.HookIsEnabled = true;
myHook.HookType = TEE_HOOK_IAT;
myHook.HookSize = sizeof ULONG_PTR;
myHook.RedirectionAddress = RedirectTo;
myHook.IATHookModuleBase = (void*)LoadedModuleBase;
myHook.IATHookNameHash = EngineHashString(szHookFunction);
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, NULL, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
return(false);
}
if(!FileIs64)
{
if(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress != NULL)
{
ImportIID = (PIMAGE_IMPORT_DESCRIPTOR)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + PEHeader32->OptionalHeader.ImageBase), true);
__try
{
while(ImportIID->FirstThunk != NULL)
{
if(ImportIID->OriginalFirstThunk != NULL)
{
ThunkData32 = (PIMAGE_THUNK_DATA32)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)((ULONG_PTR)ImportIID->OriginalFirstThunk + PEHeader32->OptionalHeader.ImageBase), true);
CurrentThunk = (ULONG_PTR)ImportIID->FirstThunk;
}
else
{
ThunkData32 = (PIMAGE_THUNK_DATA32)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)((ULONG_PTR)ImportIID->FirstThunk + PEHeader32->OptionalHeader.ImageBase), true);
CurrentThunk = (ULONG_PTR)ImportIID->FirstThunk;
}
while(ThunkData32->u1.AddressOfData != NULL)
{
if(!(ThunkData32->u1.Ordinal & IMAGE_ORDINAL_FLAG32))
{
if(lstrcmpiA((char*)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)((ULONG_PTR)ThunkData32->u1.AddressOfData + 2 + PEHeader32->OptionalHeader.ImageBase), true), szHookFunction) == NULL)
{
myHook.HookAddress = (void*)(CurrentThunk + LoadedModuleBase);
if(VirtualProtect(myHook.HookAddress, myHook.HookSize, PAGE_EXECUTE_READWRITE, &OldProtect))
{
RtlMoveMemory(&myHook.OriginalBytes[0], myHook.HookAddress, myHook.HookSize);
RtlMoveMemory(&myHook.HookBytes[0], &myHook.RedirectionAddress, myHook.HookSize);
RtlMoveMemory(myHook.HookAddress, &myHook.RedirectionAddress, myHook.HookSize);
VirtualProtect(myHook.HookAddress, myHook.HookSize, OldProtect, &OldProtect);
}
hookEntry.push_back(myHook);
}
}
CurrentThunk = CurrentThunk + 4;
ThunkData32 = (PIMAGE_THUNK_DATA32)((ULONG_PTR)ThunkData32 + sizeof IMAGE_THUNK_DATA32);
}
ImportIID = (PIMAGE_IMPORT_DESCRIPTOR)((ULONG_PTR)ImportIID + sizeof IMAGE_IMPORT_DESCRIPTOR);
}
return(true);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return(false);
}
}
}
else
{
if(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress != NULL)
{
ImportIID = (PIMAGE_IMPORT_DESCRIPTOR)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + PEHeader64->OptionalHeader.ImageBase), true);
__try
{
while(ImportIID->FirstThunk != NULL)
{
if(ImportIID->OriginalFirstThunk != NULL)
{
ThunkData64 = (PIMAGE_THUNK_DATA64)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)((ULONG_PTR)ImportIID->OriginalFirstThunk + PEHeader64->OptionalHeader.ImageBase), true);
CurrentThunk = (ULONG_PTR)ImportIID->OriginalFirstThunk;
}
else
{
ThunkData64 = (PIMAGE_THUNK_DATA64)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)((ULONG_PTR)ImportIID->FirstThunk + PEHeader64->OptionalHeader.ImageBase), true);
CurrentThunk = (ULONG_PTR)ImportIID->FirstThunk;
}
while(ThunkData64->u1.AddressOfData != NULL)
{
if(!(ThunkData64->u1.Ordinal & IMAGE_ORDINAL_FLAG64))
{
if(lstrcmpiA((char*)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)((ULONG_PTR)ThunkData64->u1.AddressOfData + 2 + PEHeader64->OptionalHeader.ImageBase), true), szHookFunction) == NULL)
{
myHook.HookAddress = (void*)(CurrentThunk + LoadedModuleBase);
if(VirtualProtect(myHook.HookAddress, myHook.HookSize, PAGE_EXECUTE_READWRITE, &OldProtect))
{
RtlMoveMemory(&myHook.OriginalBytes[0], myHook.HookAddress, myHook.HookSize);
RtlMoveMemory(&myHook.HookBytes[0], &myHook.RedirectionAddress, myHook.HookSize);
RtlMoveMemory(myHook.HookAddress, &myHook.RedirectionAddress, myHook.HookSize);
VirtualProtect(myHook.HookAddress, myHook.HookSize, OldProtect, &OldProtect);
}
hookEntry.push_back(myHook);
}
}
CurrentThunk = CurrentThunk + 8;
ThunkData64 = (PIMAGE_THUNK_DATA64)((ULONG_PTR)ThunkData64 + sizeof IMAGE_THUNK_DATA64);
}
ImportIID = (PIMAGE_IMPORT_DESCRIPTOR)((ULONG_PTR)ImportIID + sizeof IMAGE_IMPORT_DESCRIPTOR);
}
return(true);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return(false);
}
}
}
}
else
{
return(false);
}
}
else
{
return(false);
}
return(false);
}
__declspec(dllexport) bool TITCALL HooksInsertNewIATRedirection(char* szModuleName, char* szHookFunction, LPVOID RedirectTo)
{
HANDLE FileHandle;
DWORD FileSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
DWORD NewSectionVO = NULL;
DWORD NewSectionFO = NULL;
HMODULE SelectedModule = NULL;
SelectedModule = GetModuleHandleA(szModuleName);
if(SelectedModule != NULL)
{
if(MapFileEx(szModuleName, UE_ACCESS_READ, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
if(HooksInsertNewIATRedirectionEx(FileMapVA, (ULONG_PTR)SelectedModule, szHookFunction, RedirectTo))
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(true);
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
}
}
}
return(false);
}
__declspec(dllexport) bool TITCALL HooksRemoveRedirection(LPVOID HookAddress, bool RemoveAll)
{
DWORD OldProtect = PAGE_READONLY;
if(!RemoveAll)
{
for(unsigned int i = 0; i < hookEntry.size(); i++)
{
if(hookEntry[i].HookAddress == HookAddress && hookEntry[i].IATHook == false)
{
if(VirtualProtect(HookAddress, TEE_MAXIMUM_HOOK_SIZE, PAGE_EXECUTE_READWRITE, &OldProtect))
{
RtlMoveMemory(HookAddress, &hookEntry[i].OriginalBytes, hookEntry[i].HookSize);
VirtualProtect(HookAddress, TEE_MAXIMUM_HOOK_SIZE, OldProtect, &OldProtect);
hookEntry.erase(hookEntry.begin() + i);
return(true);
}
}
}
return(false);
}
else
{
for(unsigned int i = 0; i < hookEntry.size(); i++)
{
if(VirtualProtect(hookEntry[i].HookAddress, TEE_MAXIMUM_HOOK_SIZE, PAGE_EXECUTE_READWRITE, &OldProtect))
{
RtlMoveMemory(hookEntry[i].HookAddress, &hookEntry[i].OriginalBytes, hookEntry[i].HookSize);
VirtualProtect(hookEntry[i].HookAddress, TEE_MAXIMUM_HOOK_SIZE, OldProtect, &OldProtect);
}
}
hookEntry.clear();
return(true);
}
}
__declspec(dllexport) bool TITCALL HooksRemoveRedirectionsForModule(HMODULE ModuleBase)
{
int j = NULL;
unsigned int i = (unsigned int)hookEntry.size();
DWORD OldProtect = PAGE_READONLY;
MODULEINFO RemoteModuleInfo;
if(GetModuleInformation(GetCurrentProcess(), ModuleBase, &RemoteModuleInfo, sizeof MODULEINFO))
{
while(i > NULL)
{
if((ULONG_PTR)hookEntry[i].HookAddress >= (ULONG_PTR)ModuleBase && (ULONG_PTR)hookEntry[i].HookAddress <= (ULONG_PTR)ModuleBase + RemoteModuleInfo.SizeOfImage)
{
if(VirtualProtect(hookEntry[i].HookAddress, TEE_MAXIMUM_HOOK_SIZE, PAGE_EXECUTE_READWRITE, &OldProtect))
{
RtlMoveMemory(hookEntry[i].HookAddress, &hookEntry[i].OriginalBytes, hookEntry[i].HookSize);
VirtualProtect(hookEntry[i].HookAddress, TEE_MAXIMUM_HOOK_SIZE, OldProtect, &OldProtect);
hookEntry.erase(hookEntry.begin() + i);
j++;
}
}
i--;
}
if(j == NULL)
{
return(false);
}
}
else
{
return(false);
}
return(true);
}
__declspec(dllexport) bool TITCALL HooksRemoveIATRedirection(char* szModuleName, char* szHookFunction, bool RemoveAll)
{
unsigned int i = (unsigned int)hookEntry.size() - 1;
DWORD OldProtect = PAGE_READONLY;
HMODULE ModuleBase = GetModuleHandleA(szModuleName);
DWORD FunctionNameHash = EngineHashString(szHookFunction);
if(ModuleBase != NULL)
{
while(i > 0)
{
if((hookEntry[i].IATHookModuleBase == (void*)ModuleBase && RemoveAll == true) || (hookEntry[i].IATHookNameHash == FunctionNameHash && hookEntry[i].IATHook == true))
{
if(VirtualProtect(hookEntry[i].HookAddress, TEE_MAXIMUM_HOOK_SIZE, PAGE_EXECUTE_READWRITE, &OldProtect))
{
RtlMoveMemory(hookEntry[i].HookAddress, &hookEntry[i].OriginalBytes, hookEntry[i].HookSize);
VirtualProtect(hookEntry[i].HookAddress, TEE_MAXIMUM_HOOK_SIZE, OldProtect, &OldProtect);
hookEntry.erase(hookEntry.begin() + i);
}
}
i--;
}
}
return(false);
}
__declspec(dllexport) bool TITCALL HooksDisableRedirection(LPVOID HookAddress, bool DisableAll)
{
DWORD OldProtect = PAGE_READONLY;
if(!DisableAll)
{
for(unsigned int i = 0; i < hookEntry.size(); i++)
{
if(hookEntry[i].HookAddress == HookAddress && hookEntry[i].HookIsEnabled == true)
{
if(VirtualProtect(HookAddress, TEE_MAXIMUM_HOOK_SIZE, PAGE_EXECUTE_READWRITE, &OldProtect))
{
RtlMoveMemory(HookAddress, &hookEntry[i].OriginalBytes, hookEntry[i].HookSize);
VirtualProtect(HookAddress, TEE_MAXIMUM_HOOK_SIZE, OldProtect, &OldProtect);
hookEntry[i].HookIsEnabled = false;
return(true);
}
}
}
return(false);
}
else
{
for(unsigned int i = 0; i < hookEntry.size(); i++)
{
if(VirtualProtect(hookEntry[i].HookAddress, TEE_MAXIMUM_HOOK_SIZE, PAGE_EXECUTE_READWRITE, &OldProtect))
{
RtlMoveMemory(hookEntry[i].HookAddress, &hookEntry[i].OriginalBytes, hookEntry[i].HookSize);
VirtualProtect(hookEntry[i].HookAddress, TEE_MAXIMUM_HOOK_SIZE, OldProtect, &OldProtect);
hookEntry[i].HookIsEnabled = false;
}
}
return(true);
}
}
__declspec(dllexport) bool TITCALL HooksDisableRedirectionsForModule(HMODULE ModuleBase)
{
int j = NULL;
unsigned int i = (unsigned int)hookEntry.size();
DWORD OldProtect = PAGE_READONLY;
MODULEINFO RemoteModuleInfo;
if(GetModuleInformation(GetCurrentProcess(), ModuleBase, &RemoteModuleInfo, sizeof MODULEINFO))
{
while(i > NULL)
{
if((ULONG_PTR)hookEntry[i].HookAddress >= (ULONG_PTR)ModuleBase && (ULONG_PTR)hookEntry[i].HookAddress <= (ULONG_PTR)ModuleBase + RemoteModuleInfo.SizeOfImage)
{
if(VirtualProtect(hookEntry[i].HookAddress, TEE_MAXIMUM_HOOK_SIZE, PAGE_EXECUTE_READWRITE, &OldProtect))
{
RtlMoveMemory(hookEntry[i].HookAddress, &hookEntry[i].OriginalBytes, hookEntry[i].HookSize);
VirtualProtect(hookEntry[i].HookAddress, TEE_MAXIMUM_HOOK_SIZE, OldProtect, &OldProtect);
hookEntry[i].HookIsEnabled = false;
j++;
}
}
i--;
}
if(j == NULL)
{
return(false);
}
}
else
{
return(false);
}
return(true);
}
__declspec(dllexport) bool TITCALL HooksDisableIATRedirection(char* szModuleName, char* szHookFunction, bool DisableAll)
{
unsigned int i = (unsigned int)hookEntry.size() - 1;
DWORD OldProtect = PAGE_READONLY;
HMODULE ModuleBase = GetModuleHandleA(szModuleName);
DWORD FunctionNameHash = EngineHashString(szHookFunction);
if(ModuleBase != NULL)
{
while(i > 0)
{
if((hookEntry[i].IATHookModuleBase == (void*)ModuleBase && DisableAll == true) || (hookEntry[i].IATHookNameHash == FunctionNameHash && hookEntry[i].IATHook == true))
{
if(hookEntry[i].HookIsEnabled)
{
if(VirtualProtect(hookEntry[i].HookAddress, TEE_MAXIMUM_HOOK_SIZE, PAGE_EXECUTE_READWRITE, &OldProtect))
{
RtlMoveMemory(hookEntry[i].HookAddress, &hookEntry[i].OriginalBytes, hookEntry[i].HookSize);
VirtualProtect(hookEntry[i].HookAddress, TEE_MAXIMUM_HOOK_SIZE, OldProtect, &OldProtect);
hookEntry[i].HookIsEnabled = false;
}
}
}
i--;
}
}
return(false);
}
__declspec(dllexport) bool TITCALL HooksEnableRedirection(LPVOID HookAddress, bool EnableAll)
{
DWORD OldProtect = PAGE_READONLY;
if(!EnableAll)
{
for(unsigned int i = 0; i < hookEntry.size(); i++)
{
if(hookEntry[i].HookAddress == HookAddress && hookEntry[i].HookIsEnabled == false)
{
if(VirtualProtect(HookAddress, TEE_MAXIMUM_HOOK_SIZE, PAGE_EXECUTE_READWRITE, &OldProtect))
{
RtlMoveMemory(HookAddress, &hookEntry[i].HookBytes, hookEntry[i].HookSize);
VirtualProtect(HookAddress, TEE_MAXIMUM_HOOK_SIZE, OldProtect, &OldProtect);
hookEntry[i].HookIsEnabled = true;
return(true);
}
}
}
return(false);
}
else
{
for(unsigned int i = 0; i < hookEntry.size(); i++)
{
if(VirtualProtect(hookEntry[i].HookAddress, TEE_MAXIMUM_HOOK_SIZE, PAGE_EXECUTE_READWRITE, &OldProtect))
{
RtlMoveMemory(hookEntry[i].HookAddress, &hookEntry[i].HookBytes, hookEntry[i].HookSize);
VirtualProtect(hookEntry[i].HookAddress, TEE_MAXIMUM_HOOK_SIZE, OldProtect, &OldProtect);
hookEntry[i].HookIsEnabled = true;
}
}
return(true);
}
}
__declspec(dllexport) bool TITCALL HooksEnableRedirectionsForModule(HMODULE ModuleBase)
{
int j = NULL;
unsigned int i = (unsigned int)hookEntry.size();
DWORD OldProtect = PAGE_READONLY;
MODULEINFO RemoteModuleInfo;
if(GetModuleInformation(GetCurrentProcess(), ModuleBase, &RemoteModuleInfo, sizeof MODULEINFO))
{
while(i > NULL)
{
if((ULONG_PTR)hookEntry[i].HookAddress >= (ULONG_PTR)ModuleBase && (ULONG_PTR)hookEntry[i].HookAddress <= (ULONG_PTR)ModuleBase + RemoteModuleInfo.SizeOfImage)
{
if(VirtualProtect(hookEntry[i].HookAddress, TEE_MAXIMUM_HOOK_SIZE, PAGE_EXECUTE_READWRITE, &OldProtect))
{
RtlMoveMemory(hookEntry[i].HookAddress, &hookEntry[i].HookBytes, hookEntry[i].HookSize);
VirtualProtect(hookEntry[i].HookAddress, TEE_MAXIMUM_HOOK_SIZE, OldProtect, &OldProtect);
hookEntry[i].HookIsEnabled = true;
j++;
}
}
i--;
}
if(j == NULL)
{
return(false);
}
}
else
{
return(false);
}
return(true);
}
__declspec(dllexport) bool TITCALL HooksEnableIATRedirection(char* szModuleName, char* szHookFunction, bool EnableAll)
{
unsigned int i = (unsigned int)hookEntry.size() - 1;
DWORD OldProtect = PAGE_READONLY;
HMODULE ModuleBase = GetModuleHandleA(szModuleName);
DWORD FunctionNameHash = EngineHashString(szHookFunction);
if(ModuleBase != NULL)
{
while(i > 0)
{
if((hookEntry[i].IATHookModuleBase == (void*)ModuleBase && EnableAll == true) || (hookEntry[i].IATHookNameHash == FunctionNameHash && hookEntry[i].IATHook == true))
{
if(!hookEntry[i].HookIsEnabled)
{
if(VirtualProtect(hookEntry[i].HookAddress, TEE_MAXIMUM_HOOK_SIZE, PAGE_EXECUTE_READWRITE, &OldProtect))
{
RtlMoveMemory(hookEntry[i].HookAddress, &hookEntry[i].HookBytes, hookEntry[i].HookSize);
VirtualProtect(hookEntry[i].HookAddress, TEE_MAXIMUM_HOOK_SIZE, OldProtect, &OldProtect);
hookEntry[i].HookIsEnabled = true;
}
}
}
i--;
}
}
return(false);
}
__declspec(dllexport) void TITCALL HooksScanModuleMemory(HMODULE ModuleBase, LPVOID CallBack)
{
unsigned int i;
bool FileIs64 = false;
bool FileError = false;
void* pOriginalInstruction;
bool ManuallyMapped = false;
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
PIMAGE_EXPORT_DIRECTORY PEExports;
HANDLE hProcess = GetCurrentProcess();
LIBRARY_ITEM_DATA RemoteLibInfo = {};
PLIBRARY_ITEM_DATA pRemoteLibInfo = (PLIBRARY_ITEM_DATA)LibrarianGetLibraryInfoEx((void*)ModuleBase);
typedef bool(TITCALL *fEnumCallBack)(PHOOK_ENTRY HookDetails, void* ptrOriginalInstructions, PLIBRARY_ITEM_DATA ModuleInformation, DWORD SizeOfImage);
fEnumCallBack myEnumCallBack = (fEnumCallBack)CallBack;
BYTE CheckHookMemory[TEE_MAXIMUM_HOOK_SIZE];
PMEMORY_COMPARE_HANDLER ExportedFunctions;
PMEMORY_COMPARE_HANDLER FunctionMemory;
ULONG_PTR lpNumberOfBytesWritten;
HOOK_ENTRY MyhookEntry = {};
ULONG_PTR HookDestination;
MODULEINFO ModuleInfo;
BYTE HookType = NULL;
DWORD hSize;
if(pRemoteLibInfo == NULL)
{
RemoteLibInfo.BaseOfDll = (void*)ModuleBase;
GetModuleBaseNameA(hProcess, ModuleBase, &RemoteLibInfo.szLibraryName[0], MAX_PATH);
GetModuleFileNameExA(hProcess, ModuleBase, &RemoteLibInfo.szLibraryPath[0], MAX_PATH);
RemoteLibInfo.hFile = CreateFileA(RemoteLibInfo.szLibraryPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(RemoteLibInfo.hFile != INVALID_HANDLE_VALUE)
{
RemoteLibInfo.hFileMapping = CreateFileMappingA(RemoteLibInfo.hFile, NULL, 2, NULL, GetFileSize(RemoteLibInfo.hFile, NULL), NULL);
if(RemoteLibInfo.hFileMapping != NULL)
{
RemoteLibInfo.hFileMappingView = MapViewOfFile(RemoteLibInfo.hFileMapping, 4, NULL, NULL, NULL);
if(RemoteLibInfo.hFileMappingView == NULL)
{
CloseHandle(RemoteLibInfo.hFile);
CloseHandle(RemoteLibInfo.hFileMapping);
FileError = true;
}
else
{
ManuallyMapped = true;
}
}
else
{
CloseHandle(RemoteLibInfo.hFile);
FileError = true;
}
}
else
{
FileError = true;
}
}
else
{
RtlMoveMemory(&RemoteLibInfo, pRemoteLibInfo, sizeof LIBRARY_ITEM_DATA);
}
if(!FileError)
{
hSize = GetFileSize(RemoteLibInfo.hFile, NULL);
GetModuleInformation(hProcess, ModuleBase, &ModuleInfo, sizeof MODULEINFO);
DOSHeader = (PIMAGE_DOS_HEADER)RemoteLibInfo.hFileMappingView;
__try
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
FileError = true;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
FileError = true;
}
if(!FileError)
{
FunctionMemory = (PMEMORY_COMPARE_HANDLER)&CheckHookMemory[0];
if(!FileIs64)
{
__try
{
if(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress != NULL)
{
PEExports = (PIMAGE_EXPORT_DIRECTORY)ConvertVAtoFileOffsetEx((ULONG_PTR)RemoteLibInfo.hFileMappingView, hSize, PEHeader32->OptionalHeader.ImageBase, PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress, true, true);
if(PEExports != NULL)
{
ExportedFunctions = (PMEMORY_COMPARE_HANDLER)(ConvertVAtoFileOffsetEx((ULONG_PTR)RemoteLibInfo.hFileMappingView, hSize, PEHeader32->OptionalHeader.ImageBase, PEExports->AddressOfFunctions, true, true));
for(i = 0; i < PEExports->NumberOfFunctions; i++)
{
if(ReadProcessMemory(hProcess, (void*)((ULONG_PTR)RemoteLibInfo.BaseOfDll + ExportedFunctions->Array.dwArrayEntry[i]), &CheckHookMemory[0], TEE_MAXIMUM_HOOK_SIZE, &lpNumberOfBytesWritten))
{
if(FunctionMemory->Array.bArrayEntry[0] == 0xE9 || FunctionMemory->Array.bArrayEntry[0] == 0xE8)
{
HookDestination = (ULONG_PTR)GetJumpDestination(hProcess, (ULONG_PTR)RemoteLibInfo.BaseOfDll + ExportedFunctions->Array.dwArrayEntry[i]);
if(HookDestination >= (ULONG_PTR)RemoteLibInfo.BaseOfDll && HookDestination <= (ULONG_PTR)RemoteLibInfo.BaseOfDll + (ULONG_PTR)ModuleInfo.SizeOfImage)
{
if(CallBack != NULL)
{
if(FunctionMemory->Array.bArrayEntry[0] == 0xE9)
{
HookType = TEE_HOOK_NRM_JUMP;
}
else
{
HookType = TEE_HOOK_NRM_CALL;
}
MyhookEntry.HookSize = 5;
MyhookEntry.HookType = HookType;
MyhookEntry.HookIsEnabled = true;
MyhookEntry.RedirectionAddress = (void*)HookDestination;
MyhookEntry.HookAddress = (void*)((ULONG_PTR)RemoteLibInfo.BaseOfDll + ExportedFunctions->Array.dwArrayEntry[i]);
pOriginalInstruction = (void*)ConvertVAtoFileOffsetEx((ULONG_PTR)RemoteLibInfo.hFileMappingView, hSize, PEHeader32->OptionalHeader.ImageBase, ExportedFunctions->Array.dwArrayEntry[i], true, true);
RtlZeroMemory(&MyhookEntry.HookBytes[0], TEE_MAXIMUM_HOOK_SIZE);
RtlMoveMemory(&MyhookEntry.HookBytes[0], &CheckHookMemory[0], MyhookEntry.HookSize);
RtlZeroMemory(&MyhookEntry.OriginalBytes[0], TEE_MAXIMUM_HOOK_SIZE);
RtlMoveMemory(&MyhookEntry.OriginalBytes[0], pOriginalInstruction, MyhookEntry.HookSize);
RelocaterRelocateMemoryBlock((ULONG_PTR)RemoteLibInfo.hFileMappingView, (ULONG_PTR)PEHeader32->OptionalHeader.ImageBase + ExportedFunctions->Array.dwArrayEntry[i], &MyhookEntry.OriginalBytes[0], MyhookEntry.HookSize, (ULONG_PTR)PEHeader32->OptionalHeader.ImageBase, (ULONG_PTR)RemoteLibInfo.BaseOfDll);
if(!myEnumCallBack(&MyhookEntry, pOriginalInstruction, &RemoteLibInfo, ModuleInfo.SizeOfImage))
{
break;
}
}
}
}
}
}
}
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
}
else
{
__try
{
if(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress != NULL)
{
PEExports = (PIMAGE_EXPORT_DIRECTORY)ConvertVAtoFileOffsetEx((ULONG_PTR)RemoteLibInfo.hFileMappingView, hSize, (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress, true, true);
if(PEExports != NULL)
{
ExportedFunctions = (PMEMORY_COMPARE_HANDLER)(ConvertVAtoFileOffsetEx((ULONG_PTR)RemoteLibInfo.hFileMappingView, hSize, (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, PEExports->AddressOfFunctions, true, true));
for(i = 0; i < PEExports->NumberOfFunctions; i++)
{
if(ReadProcessMemory(hProcess, (void*)((ULONG_PTR)RemoteLibInfo.BaseOfDll + ExportedFunctions->Array.dwArrayEntry[i]), &CheckHookMemory[0], TEE_MAXIMUM_HOOK_SIZE, &lpNumberOfBytesWritten))
{
if(FunctionMemory->Array.bArrayEntry[0] == 0xE9 || FunctionMemory->Array.bArrayEntry[0] == 0xE8)
{
HookDestination = (ULONG_PTR)GetJumpDestination(hProcess, (ULONG_PTR)RemoteLibInfo.BaseOfDll + ExportedFunctions->Array.dwArrayEntry[i]);
if(HookDestination >= (ULONG_PTR)RemoteLibInfo.BaseOfDll && HookDestination <= (ULONG_PTR)RemoteLibInfo.BaseOfDll + (ULONG_PTR)ModuleInfo.SizeOfImage)
{
if(CallBack != NULL)
{
if(FunctionMemory->Array.bArrayEntry[0] == 0xE9)
{
HookType = TEE_HOOK_NRM_JUMP;
}
else
{
HookType = TEE_HOOK_NRM_CALL;
}
MyhookEntry.HookSize = 5;
MyhookEntry.HookType = HookType;
MyhookEntry.HookIsEnabled = true;
MyhookEntry.RedirectionAddress = (void*)HookDestination;
MyhookEntry.HookAddress = (void*)((ULONG_PTR)RemoteLibInfo.BaseOfDll + ExportedFunctions->Array.dwArrayEntry[i]);
pOriginalInstruction = (void*)ConvertVAtoFileOffsetEx((ULONG_PTR)RemoteLibInfo.hFileMappingView, hSize, (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, ExportedFunctions->Array.dwArrayEntry[i], true, true);
RtlZeroMemory(&MyhookEntry.HookBytes[0], TEE_MAXIMUM_HOOK_SIZE);
RtlMoveMemory(&MyhookEntry.HookBytes[0], &CheckHookMemory[0], MyhookEntry.HookSize);
RtlZeroMemory(&MyhookEntry.OriginalBytes[0], TEE_MAXIMUM_HOOK_SIZE);
RtlMoveMemory(&MyhookEntry.OriginalBytes[0], pOriginalInstruction, MyhookEntry.HookSize);
RelocaterRelocateMemoryBlock((ULONG_PTR)RemoteLibInfo.hFileMappingView, (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase + ExportedFunctions->Array.dwArrayEntry[i], &MyhookEntry.OriginalBytes[0], MyhookEntry.HookSize, (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, (ULONG_PTR)RemoteLibInfo.BaseOfDll);
if(!myEnumCallBack(&MyhookEntry, pOriginalInstruction, &RemoteLibInfo, ModuleInfo.SizeOfImage))
{
break;
}
}
}
}
}
}
}
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
}
}
if(ManuallyMapped)
{
if(UnmapViewOfFile(RemoteLibInfo.hFileMappingView))
{
CloseHandle(RemoteLibInfo.hFileMapping);
CloseHandle(RemoteLibInfo.hFile);
}
}
}
}
__declspec(dllexport) void TITCALL HooksScanEntireProcessMemory(LPVOID CallBack)
{
unsigned int i;
DWORD ModulesLoaded;
HMODULE EnumeratedModules[1024];
hookEntry.clear();
if(EnumProcessModules(GetCurrentProcess(), &EnumeratedModules[0], sizeof EnumeratedModules, &ModulesLoaded))
{
ModulesLoaded = ModulesLoaded / sizeof HANDLE;
for(i = 1; i < ModulesLoaded; i++)
{
HooksScanModuleMemory(EnumeratedModules[i], CallBack);
}
}
}
__declspec(dllexport) void TITCALL HooksScanEntireProcessMemoryEx()
{
HooksScanEntireProcessMemory(&ProcessHookScanAddNewHook);
}
// Global.Engine.Tracer.functions:
long long EngineGlobalTracerHandler1(HANDLE hProcess, ULONG_PTR AddressToTrace, bool HashInstructions, DWORD InputNumberOfInstructions)
{
SIZE_T memSize = 0;
int NumberOfInstructions = 0;
int LengthOfValidInstruction = 0;
int CurrentNumberOfInstructions = 0;
MEMORY_BASIC_INFORMATION MemInfo;
LPVOID TraceMemory, cTraceMemory;
ULONG_PTR ueNumberOfBytesRead = NULL;
DWORD LastPushValue = NULL;
ULONG_PTR TraceStartAddress;
ULONG_PTR TraceTestAddress;
ULONG_PTR TraceTestReadAddress;
DWORD CurrentInstructionSize;
PMEMORY_CMP_HANDLER CompareMemory;
PMEMORY_COMPARE_HANDLER longCompareMemory;
DWORD InstructionHash = NULL;
bool FoundValidAPI = false;
bool SkipThisInstruction = false;
bool LoopCondition = true;
bool SkipHashing = false;
BYTE EmptyCall[5] = {0xE8, 0x00, 0x00, 0x00, 0x00};
if(VirtualQueryEx(hProcess, (LPVOID)AddressToTrace, &MemInfo, sizeof MEMORY_BASIC_INFORMATION) != NULL)
{
if(MemInfo.RegionSize > NULL)
{
memSize = MemInfo.RegionSize;
if(memSize > 0x4000)
{
memSize = 0x4000;
}
TraceMemory = VirtualAlloc(NULL, memSize, MEM_COMMIT, PAGE_READWRITE);
cTraceMemory = TraceMemory;
if(ReadProcessMemory(hProcess, (LPVOID)MemInfo.BaseAddress, TraceMemory, memSize, &ueNumberOfBytesRead))
{
TraceStartAddress = AddressToTrace - (ULONG_PTR)MemInfo.BaseAddress + (ULONG_PTR)TraceMemory;
if(HashInstructions && InputNumberOfInstructions > NULL)
{
LoopCondition = true;
}
else
{
LoopCondition = false;
}
while(LoopCondition)
{
SkipHashing = false;
SkipThisInstruction = false;
CompareMemory = (PMEMORY_CMP_HANDLER)TraceStartAddress;
CurrentInstructionSize = StaticLengthDisassemble((LPVOID)TraceStartAddress);
CurrentNumberOfInstructions++;
/*
Long JUMP (0xE9)
*/
if(HashInstructions == false && CompareMemory->DataByte[0] == 0xE9 && CurrentInstructionSize == 5)
{
TraceTestAddress = (ULONG_PTR)GetJumpDestination(NULL, TraceStartAddress) - (ULONG_PTR)TraceMemory + (ULONG_PTR)MemInfo.BaseAddress;
if(TraceTestAddress <= (ULONG_PTR)MemInfo.BaseAddress || TraceTestAddress >= (ULONG_PTR)MemInfo.BaseAddress + MemInfo.RegionSize)
{
if(LengthOfValidInstruction == NULL)
{
if(ImporterGetAPINameFromDebugee(hProcess, TraceTestAddress) != NULL)
{
FoundValidAPI = true;
break;
}
}
if(ImporterGetAPINameFromDebugee(hProcess, TraceTestAddress) != NULL)
{
FoundValidAPI = true;
break;
}
else
{
if(ImporterGetAPINameFromDebugee(hProcess, TraceTestAddress - LengthOfValidInstruction) != NULL)
{
FoundValidAPI = true;
TraceTestAddress = TraceTestAddress - LengthOfValidInstruction;
break;
}
}
}
/*
Near JUMP (0xFF25)
*/
}
else if(HashInstructions == false && CompareMemory->DataByte[0] == 0xFF && CompareMemory->DataByte[1] == 0x25 && CurrentInstructionSize == 6)
{
TraceTestAddress = (ULONG_PTR)GetJumpDestination(NULL, TraceStartAddress);
if(ReadProcessMemory(hProcess, (LPVOID)TraceTestAddress, &TraceTestAddress, 4, &ueNumberOfBytesRead))
{
if(TraceTestAddress <= (ULONG_PTR)MemInfo.BaseAddress || TraceTestAddress >= (ULONG_PTR)MemInfo.BaseAddress + MemInfo.RegionSize)
{
if(LengthOfValidInstruction == NULL)
{
if(ImporterGetAPINameFromDebugee(hProcess, TraceTestAddress) != NULL)
{
FoundValidAPI = true;
break;
}
}
if(ImporterGetAPINameFromDebugee(hProcess, TraceTestAddress) != NULL)
{
FoundValidAPI = true;
break;
}
else
{
if(ImporterGetAPINameFromDebugee(hProcess, TraceTestAddress - LengthOfValidInstruction) != NULL)
{
FoundValidAPI = true;
TraceTestAddress = TraceTestAddress - LengthOfValidInstruction;
break;
}
}
}
}
/*
PUSH then RET (0x68 ???????? 0xC3)
*/
}
else if(HashInstructions == false && CompareMemory->DataByte[0] == 0x68 && CompareMemory->DataByte[5] == 0xC3 && CurrentInstructionSize == 5)
{
longCompareMemory = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)CompareMemory + 1);
TraceTestAddress = (DWORD)(longCompareMemory->Array.dwArrayEntry[0]);
if(ReadProcessMemory(hProcess, (LPVOID)TraceTestAddress, &TraceTestReadAddress, 4, &ueNumberOfBytesRead))
{
if(TraceTestAddress <= (ULONG_PTR)MemInfo.BaseAddress || TraceTestAddress >= (ULONG_PTR)MemInfo.BaseAddress + MemInfo.RegionSize)
{
if(LengthOfValidInstruction == NULL)
{
if(ImporterGetAPINameFromDebugee(hProcess, TraceTestAddress) != NULL)
{
FoundValidAPI = true;
break;
}
}
if(ImporterGetAPINameFromDebugee(hProcess, TraceTestAddress) != NULL)
{
FoundValidAPI = true;
break;
}
else
{
if(ImporterGetAPINameFromDebugee(hProcess, TraceTestAddress - LengthOfValidInstruction) != NULL)
{
FoundValidAPI = true;
TraceTestAddress = TraceTestAddress - LengthOfValidInstruction;
break;
}
}
}
else
{
TraceStartAddress = TraceStartAddress - (ULONG_PTR)MemInfo.BaseAddress + (ULONG_PTR)TraceMemory;
}
}
/*
CALL (0xE8)
*/
}
else if(HashInstructions == true && CompareMemory->DataByte[0] == 0xE8 && CurrentInstructionSize == 5)
{
SkipHashing = true;
InstructionHash = EngineHashMemory((char*)&EmptyCall, CurrentInstructionSize, InstructionHash);
/*
PUSH (0x68)
*/
}
else if(CompareMemory->DataByte[0] == 0x68 && CurrentInstructionSize == 5)
{
LastPushValue = (DWORD)(CompareMemory->DataByte[1] + CompareMemory->DataByte[2] * 0x1000 + CompareMemory->DataByte[3] * 0x100000 + CompareMemory->DataByte[4] * 0x10000000);
/*
ADD BYTE PTR[AL],AL (0x00, 0x00) -> End of page!
*/
}
else if(CompareMemory->DataByte[0] == 0x00 && CurrentInstructionSize == 2)
{
FoundValidAPI = false;
break;
/*
RET (0xC3)
*/
}
else if(CompareMemory->DataByte[0] == 0xC3 && CurrentInstructionSize == 1)
{
NumberOfInstructions++;
break;
/*
RET (0xC2)
*/
}
else if(CompareMemory->DataByte[0] == 0xC2 && CurrentInstructionSize == 3)
{
NumberOfInstructions++;
break;
/*
Short JUMP (0xEB)
*/
}
else if(CompareMemory->DataByte[0] == 0xEB && CurrentInstructionSize == 2)
{
TraceStartAddress = TraceStartAddress + CompareMemory->DataByte[1];
SkipThisInstruction = true;
/*
CLC (0xF8)
*/
}
else if(CompareMemory->DataByte[0] == 0xF8 && CurrentInstructionSize == 1)
{
SkipThisInstruction = true;
/*
STC (0xF9)
*/
}
else if(CompareMemory->DataByte[0] == 0xF9 && CurrentInstructionSize == 1)
{
SkipThisInstruction = true;
/*
NOP (0x90)
*/
}
else if(CompareMemory->DataByte[0] == 0x90 && CurrentInstructionSize == 1)
{
SkipThisInstruction = true;
/*
FNOP (0xD9 0xD0)
*/
}
else if(CompareMemory->DataByte[0] == 0xD9 && CompareMemory->DataByte[1] == 0xD0 && CurrentInstructionSize == 2)
{
SkipThisInstruction = true;
/*
Multiple MOV
*/
}
else if(CompareMemory->DataByte[0] >= 0x8A && CompareMemory->DataByte[0] <= 0x8B)
{
/*
MOV EAX,EAX (0x8B 0xC8)
*/
if(CompareMemory->DataByte[0] == 0x8B && CompareMemory->DataByte[1] == 0xC8 && CurrentInstructionSize == 2)
{
SkipThisInstruction = true;
}
/*
MOV EBX,EBX (0x8B 0xC9)
*/
else if(CompareMemory->DataByte[0] == 0x8B && CompareMemory->DataByte[1] == 0xC9 && CurrentInstructionSize == 2)
{
SkipThisInstruction = true;
}
/*
MOV ECX,ECX (0x8B 0xDB)
*/
else if(CompareMemory->DataByte[0] == 0x8B && CompareMemory->DataByte[1] == 0xDB && CurrentInstructionSize == 2)
{
SkipThisInstruction = true;
}
/*
MOV (0x8B 0xED)
*/
else if(CompareMemory->DataByte[0] == 0x8B && CompareMemory->DataByte[1] == 0xED && CurrentInstructionSize == 2)
{
SkipThisInstruction = true;
}
/*
MOV (0x8B 0xF6)
*/
else if(CompareMemory->DataByte[0] == 0x8B && CompareMemory->DataByte[1] == 0xF6 && CurrentInstructionSize == 2)
{
SkipThisInstruction = true;
}
/*
MOV (0x8B 0xE4)
*/
else if(CompareMemory->DataByte[0] == 0x8B && CompareMemory->DataByte[1] == 0xE4 && CurrentInstructionSize == 2)
{
SkipThisInstruction = true;
}
/*
MOV EDX,EDX (0x8B 0xD2)
*/
else if(CompareMemory->DataByte[0] == 0x8B && CompareMemory->DataByte[1] == 0xD2 && CurrentNumberOfInstructions != 1 && CurrentInstructionSize == 2)
{
SkipThisInstruction = true;
}
/*
MOV EDI,EDI (0x8B 0xFF)
*/
else if(CompareMemory->DataByte[0] == 0x8B && CompareMemory->DataByte[1] == 0xFF && CurrentNumberOfInstructions != 1 && CurrentInstructionSize == 2)
{
SkipThisInstruction = true;
}
/*
MOV AL,AL (0x8A 0xC0)
*/
else if(CompareMemory->DataByte[0] == 0x8A && CompareMemory->DataByte[1] == 0xC0 && CurrentInstructionSize == 2)
{
SkipThisInstruction = true;
}
/*
MOV BL,BL (0x8A 0xDB)
*/
else if(CompareMemory->DataByte[0] == 0x8A && CompareMemory->DataByte[1] == 0xDB && CurrentInstructionSize == 2)
{
SkipThisInstruction = true;
}
/*
MOV CL,CL (0x8A 0xC9)
*/
else if(CompareMemory->DataByte[0] == 0x8A && CompareMemory->DataByte[1] == 0xC9 && CurrentInstructionSize == 2)
{
SkipThisInstruction = true;
}
/*
MOV (0x8A 0xD2)
*/
else if(CompareMemory->DataByte[0] == 0x8A && CompareMemory->DataByte[1] == 0xD2 && CurrentInstructionSize == 2)
{
SkipThisInstruction = true;
}
/*
MOV (0x8A 0xE4)
*/
else if(CompareMemory->DataByte[0] == 0x8A && CompareMemory->DataByte[1] == 0xE4 && CurrentInstructionSize == 2)
{
SkipThisInstruction = true;
}
/*
MOV (0x8A 0xED)
*/
else if(CompareMemory->DataByte[0] == 0x8A && CompareMemory->DataByte[1] == 0xED && CurrentInstructionSize == 2)
{
SkipThisInstruction = true;
}
/*
MOV (0x8A 0xFF)
*/
else if(CompareMemory->DataByte[0] == 0x8A && CompareMemory->DataByte[1] == 0xFF && CurrentInstructionSize == 2)
{
SkipThisInstruction = true;
}
/*
MOV (0x8A 0xF6)
*/
else if(CompareMemory->DataByte[0] == 0x8A && CompareMemory->DataByte[1] == 0xF6 && CurrentInstructionSize == 2)
{
SkipThisInstruction = true;
}
/*
MOV AX,AX (0x8B 0xC0)
*/
else if(CompareMemory->DataByte[0] == 0x8B && CompareMemory->DataByte[1] == 0xC0 && CurrentInstructionSize == 2)
{
SkipThisInstruction = true;
}
/*
MOV (0x8B 0xDB)
*/
else if(CompareMemory->DataByte[0] == 0x8B && CompareMemory->DataByte[1] == 0xDB && CurrentInstructionSize == 2)
{
SkipThisInstruction = true;
}
/*
MOV (0x8B 0xC9)
*/
else if(CompareMemory->DataByte[0] == 0x8B && CompareMemory->DataByte[1] == 0xC9 && CurrentInstructionSize == 2)
{
SkipThisInstruction = true;
}
/*
MOV (0x8B 0xF6)
*/
else if(CompareMemory->DataByte[0] == 0x8B && CompareMemory->DataByte[1] == 0xF6 && CurrentInstructionSize == 2)
{
SkipThisInstruction = true;
}
/*
MOV (0x8B 0xED)
*/
else if(CompareMemory->DataByte[0] == 0x8B && CompareMemory->DataByte[1] == 0xED && CurrentInstructionSize == 2)
{
SkipThisInstruction = true;
}
}
/*
RDTSC (0x0F 0x31)
*/
else if(CompareMemory->DataByte[0] == 0x0F && CompareMemory->DataByte[1] == 0x31 && CurrentInstructionSize == 2)
{
SkipThisInstruction = true;
/*
CPUID (0x0F 0xA2)
*/
}
else if(CompareMemory->DataByte[0] == 0x0F && CompareMemory->DataByte[1] == 0xA2 && CurrentInstructionSize == 2)
{
SkipThisInstruction = true;
/*
XCHG EAX,EAX (0x87 0xC0)
*/
}
else if(CompareMemory->DataByte[0] == 0x87 && CompareMemory->DataByte[1] == 0xC0 && CurrentInstructionSize == 2)
{
SkipThisInstruction = true;
/*
SHL EAX,0 - SHL EDI,0 && SHR EAX,0 - SHR EDI,0
*/
}
else if(CompareMemory->DataByte[0] == 0xC1 && CurrentInstructionSize == 3)
{
if(CompareMemory->DataByte[1] >= 0xE0 && CompareMemory->DataByte[1] <= 0xEF && CompareMemory->DataByte[2] == 0x00)
{
SkipThisInstruction = true;
}
/*
ROR EAX,0 - ROR EDI,0 && ROL EAX,0 - ROL EDI,0
*/
}
else if(CompareMemory->DataByte[0] == 0xC1 && CurrentInstructionSize == 3)
{
if(CompareMemory->DataByte[1] >= 0xC0 && CompareMemory->DataByte[1] <= 0xCF && CompareMemory->DataByte[2] == 0x00)
{
SkipThisInstruction = true;
}
/*
LEA EAX,DWORD PTR[EAX] -> LEA EDI,DWORD PTR[EDI]
*/
}
else if(CompareMemory->DataByte[0] == 0x8D && CurrentInstructionSize == 2)
{
if(CompareMemory->DataByte[1] == 0x00 || CompareMemory->DataByte[1] == 0x09 || CompareMemory->DataByte[1] == 0x1B || CompareMemory->DataByte[1] == 0x12)
{
SkipThisInstruction = true;
}
if(CompareMemory->DataByte[1] == 0x36 || CompareMemory->DataByte[1] == 0x3F)
{
SkipThisInstruction = true;
}
if(CompareMemory->DataByte[1] == 0x6D && CompareMemory->DataByte[2] == 0x00)
{
SkipThisInstruction = true;
}
}
if(!SkipThisInstruction)
{
if(HashInstructions == true && SkipHashing == false)
{
InstructionHash = EngineHashMemory((char*)TraceStartAddress, CurrentInstructionSize, InstructionHash);
}
LengthOfValidInstruction = LengthOfValidInstruction + CurrentInstructionSize;
NumberOfInstructions++;
}
if(HashInstructions)
{
InputNumberOfInstructions--;
if(InputNumberOfInstructions > NULL)
{
LoopCondition = true;
}
else
{
LoopCondition = false;
}
}
else
{
if(CurrentNumberOfInstructions < 1000 && FoundValidAPI == false)
{
LoopCondition = true;
}
else
{
LoopCondition = false;
}
}
TraceStartAddress = TraceStartAddress + CurrentInstructionSize;
}
VirtualFree(TraceMemory, NULL, MEM_RELEASE);
if(!HashInstructions)
{
if(FoundValidAPI == true)
{
return((ULONG_PTR)TraceTestAddress);
}
else if(CurrentNumberOfInstructions < 1000)
{
if(ImporterGetAPINameFromDebugee(hProcess, LastPushValue) != NULL)
{
return((ULONG_PTR)LastPushValue);
}
else if(ImporterGetAPINameFromDebugee(hProcess, LastPushValue - LengthOfValidInstruction) != NULL)
{
return((ULONG_PTR)(LastPushValue - LengthOfValidInstruction));
}
return((DWORD)NumberOfInstructions);
}
}
else
{
return((DWORD)InstructionHash);
}
}
else
{
VirtualFree(TraceMemory, NULL, MEM_RELEASE);
}
}
}
return(NULL);
}
// TitanEngine.Tracer.functions:
__declspec(dllexport) void TITCALL TracerInit()
{
return; // UE 1.5 compatibility mode
}
__declspec(dllexport) long long TITCALL TracerLevel1(HANDLE hProcess, ULONG_PTR AddressToTrace)
{
return((ULONG_PTR)EngineGlobalTracerHandler1(hProcess, AddressToTrace, false, NULL));
}
__declspec(dllexport) long long TITCALL HashTracerLevel1(HANDLE hProcess, ULONG_PTR AddressToTrace, DWORD InputNumberOfInstructions)
{
unsigned int i = 0;
unsigned int j = 0;
DWORD Dummy = NULL;
MODULEINFO RemoteModuleInfo;
ULONG_PTR EnumeratedModules[0x2000];
ULONG_PTR LoadedModules[1000][4];
char RemoteDLLName[MAX_PATH];
HANDLE hLoadedModule = NULL;
HANDLE ModuleHandle = NULL;
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
PIMAGE_EXPORT_DIRECTORY PEExports;
PEXPORTED_DATA ExportedFunctions;
ULONG_PTR APIFoundAddress = NULL;
bool ValidateHeader = false;
bool FileIs64 = false;
bool FoundAPI = false;
DWORD CompareHash = NULL;
DWORD TestHash = NULL;
if(InputNumberOfInstructions > NULL)
{
CompareHash = (DWORD)EngineGlobalTracerHandler1(hProcess, AddressToTrace, true, InputNumberOfInstructions);
}
else
{
InputNumberOfInstructions = (DWORD)TracerLevel1(hProcess, AddressToTrace);
if(InputNumberOfInstructions < 1000)
{
CompareHash = (DWORD)EngineGlobalTracerHandler1(hProcess, AddressToTrace, true, InputNumberOfInstructions);
}
else
{
return(NULL);
}
}
RtlZeroMemory(&EnumeratedModules, 0x2000 * sizeof ULONG_PTR);
RtlZeroMemory(&LoadedModules, 1000 * 4 * sizeof ULONG_PTR);
if(hProcess == NULL)
{
if(dbgProcessInformation.hProcess == NULL)
{
hProcess = GetCurrentProcess();
}
else
{
hProcess = dbgProcessInformation.hProcess;
}
}
if(EnumProcessModules(hProcess, (HMODULE*)EnumeratedModules, 0x2000, &Dummy))
{
i++;
while(FoundAPI == false && EnumeratedModules[i] != NULL)
{
ValidateHeader = false;
RtlZeroMemory(&RemoteDLLName, MAX_PATH);
GetModuleFileNameExA(hProcess, (HMODULE)EnumeratedModules[i], (LPSTR)RemoteDLLName, MAX_PATH);
if(GetModuleHandleA(RemoteDLLName) == NULL)
{
RtlZeroMemory(&RemoteDLLName, MAX_PATH);
GetModuleBaseNameA(hProcess, (HMODULE)EnumeratedModules[i], (LPSTR)RemoteDLLName, MAX_PATH);
if(GetModuleHandleA(RemoteDLLName) == NULL)
{
if(engineAlowModuleLoading)
{
hLoadedModule = LoadLibraryA(RemoteDLLName);
if(hLoadedModule != NULL)
{
LoadedModules[i][0] = EnumeratedModules[i];
LoadedModules[i][1] = (ULONG_PTR)hLoadedModule;
LoadedModules[i][2] = 1;
}
}
else
{
hLoadedModule = (HANDLE)EngineSimulateDllLoader(hProcess, RemoteDLLName);
if(hLoadedModule != NULL)
{
LoadedModules[i][0] = EnumeratedModules[i];
LoadedModules[i][1] = (ULONG_PTR)hLoadedModule;
LoadedModules[i][2] = 1;
ValidateHeader = true;
}
}
}
else
{
LoadedModules[i][0] = EnumeratedModules[i];
LoadedModules[i][1] = (ULONG_PTR)GetModuleHandleA(RemoteDLLName);
LoadedModules[i][2] = 0;
}
}
else
{
LoadedModules[i][0] = EnumeratedModules[i];
LoadedModules[i][1] = (ULONG_PTR)GetModuleHandleA(RemoteDLLName);
LoadedModules[i][2] = 0;
}
if(!FoundAPI)
{
DOSHeader = (PIMAGE_DOS_HEADER)LoadedModules[i][1];
RtlZeroMemory(&RemoteModuleInfo, sizeof MODULEINFO);
GetModuleInformation(hProcess, (HMODULE)LoadedModules[i][1], &RemoteModuleInfo, sizeof MODULEINFO);
if(ValidateHeader || EngineValidateHeader((ULONG_PTR)LoadedModules[i][1], hProcess, RemoteModuleInfo.lpBaseOfDll, DOSHeader, false))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
return(NULL);
}
if(!FileIs64)
{
PEExports = (PIMAGE_EXPORT_DIRECTORY)(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + LoadedModules[i][1]);
ExportedFunctions = (PEXPORTED_DATA)(PEExports->AddressOfFunctions + LoadedModules[i][1]);
}
else
{
PEExports = (PIMAGE_EXPORT_DIRECTORY)(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + LoadedModules[i][1]);
ExportedFunctions = (PEXPORTED_DATA)(PEExports->AddressOfFunctions + LoadedModules[i][1]);
}
for(j = 0; j < PEExports->NumberOfFunctions; j++)
{
TestHash = (DWORD)EngineGlobalTracerHandler1(hProcess, (ULONG_PTR)(ExportedFunctions->ExportedItem + LoadedModules[i][1]), true, InputNumberOfInstructions);
if(TestHash == CompareHash)
{
APIFoundAddress = (ULONG_PTR)(ExportedFunctions->ExportedItem + LoadedModules[i][0]);
FoundAPI = true;
}
ExportedFunctions = (PEXPORTED_DATA)((ULONG_PTR)ExportedFunctions + 4);
}
}
}
i++;
}
i = 1;
while(EnumeratedModules[i] != NULL)
{
if(engineAlowModuleLoading)
{
if(LoadedModules[i][2] == 1)
{
FreeLibrary((HMODULE)LoadedModules[i][1]);
}
}
else
{
if(LoadedModules[i][2] == 1)
{
VirtualFree((void*)LoadedModules[i][1], NULL, MEM_RELEASE);
}
}
i++;
}
}
return((ULONG_PTR)APIFoundAddress);
}
__declspec(dllexport) long TITCALL TracerDetectRedirection(HANDLE hProcess, ULONG_PTR AddressToTrace)
{
int i,j;
MEMORY_BASIC_INFORMATION MemInfo;
DWORD KnownRedirectionIndex = NULL;
ULONG_PTR ueNumberOfBytesRead = NULL;
PMEMORY_CMP_HANDLER cMem;
DWORD MemoryHash = NULL;
DWORD MaximumReadSize = 0;
DWORD TestAddressX86;
LPVOID TraceMemory;
bool HashCheck = false;
VirtualQueryEx(hProcess, (LPVOID)AddressToTrace, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
if(MemInfo.RegionSize > NULL)
{
MaximumReadSize = (DWORD)((ULONG_PTR)MemInfo.AllocationBase + MemInfo.RegionSize - AddressToTrace);
if(MaximumReadSize > 0x1000)
{
MaximumReadSize = 0x1000;
HashCheck = true;
}
else if(MaximumReadSize > 256)
{
HashCheck = true;
}
if(sizeof HANDLE == 4)
{
TraceMemory = VirtualAlloc(NULL, MaximumReadSize, MEM_COMMIT, PAGE_READWRITE);
if(!TraceMemory)
{
return (NULL);
}
if(ReadProcessMemory(hProcess, (LPVOID)AddressToTrace, TraceMemory, MaximumReadSize, &ueNumberOfBytesRead))
{
cMem = (PMEMORY_CMP_HANDLER)TraceMemory;
if(cMem->DataByte[0] == 0xEB && cMem->DataByte[1] == 0x01 && ((cMem->DataByte[3] >= 0x50 && cMem->DataByte[3] <= 0x5F) || cMem->DataByte[3] == 0x6A || cMem->DataByte[3] == 0x68))
{
KnownRedirectionIndex = NULL; // ; PeX 0.99 fail safe!
}
else if(cMem->DataByte[0] == 0x68 && cMem->DataByte[5] == 0x81 && cMem->DataByte[12] == 0xC3)
{
KnownRedirectionIndex = 1; // ; RLP 0.7.4 & CryptoPeProtector 0.9.x & ACProtect
/* ;$ ==> > 68 904B4013 PUSH 13404B90
;$+5 > 812C24 0A9E589B SUB DWORD PTR SS:[ESP],9B589E0A
;$+C > C3 RET
;$+D > 68 E21554DF PUSH DF5415E2
;$+12 > 813424 B6DCB2A8 XOR DWORD PTR SS:[ESP],A8B2DCB6
;$+19 > C3 RET
;$+1A > 68 34B2C6B1 PUSH B1C6B234
;$+1F > 810424 4A2C21C6 ADD DWORD PTR SS:[ESP],C6212C4A
;$+26 > C3 RET */
}
else if(cMem->DataByte[0] == 0xFF && cMem->DataByte[1] == 0x25)
{
KnownRedirectionIndex = 2; // ; tELock 0.80 - 0.85
// ;$ ==> >- FF25 48018E00 JMP NEAR DWORD PTR DS:[8E0148]
}
else if((cMem->DataByte[0] == 0xFF && cMem->DataByte[1] == 0x35) || (cMem->DataByte[1] == 0xFF && cMem->DataByte[2] == 0x35) && (cMem->DataByte[8] == 0xC3 || cMem->DataByte[9] == 0xC3))
{
KnownRedirectionIndex = 3; // ; tELock 0.90 - 0.95
/* ;$ ==> > FF35 AE018E00 PUSH DWORD PTR DS:[8E01AE] ; kernel32.InitializeCriticalSection
;$+6 > A8 C3 TEST AL,0C3
;$+8 > C3 RET
;$+9 > F9 STC
;$+A > FF35 B2018E00 PUSH DWORD PTR DS:[8E01B2] ; kernel32.VirtualFree
;$+10 > 80FA C3 CMP DL,0C3
;$+13 > C3 RET */
}
else if(cMem->DataByte[0] == 0xEB && cMem->DataByte[1] == 0x01 && cMem->DataByte[2] == 0xC9 && cMem->DataByte[3] == 0x60 && cMem->DataByte[4] == 0x0F && cMem->DataByte[5] == 0x31)
{
KnownRedirectionIndex = 8; // ; AlexProtector 1.x
/* ;$ ==> > /EB 01 JMP SHORT 008413F9
;$+2 > |C9 LEAVE
;$+3 > \60 PUSHAD
;$+4 > 0F31 RDTSC
;$+6 > EB 01 JMP SHORT 008413FF
;$+8 > C9 LEAVE
;$+9 > 8BD8 MOV EBX,EAX
;$+B > EB 01 JMP SHORT 00841404
;...
;$+33 > 68 E9B9D477 PUSH USER32.PostQuitMessage
;$+38 > EB 01 JMP SHORT 00841431
;$+3A >- E9 C3EB01E9 JMP E985FFF8 */
}
else if((cMem->DataByte[0] == 0x0B && cMem->DataByte[1] == 0xC5) || (cMem->DataByte[0] == 0x05 && cMem->DataByte[5] == 0xB8 && cMem->DataByte[10] == 0xEB && cMem->DataByte[11] == 0x02))
{
KnownRedirectionIndex = 5; // ; tELock 0.99 - 1.0 Private!
/* ;008E0122 05 F9DEBE71 ADD EAX,71BEDEF9
;008E0127 B8 28018E00 MOV EAX,8E0128
;008E012C EB 02 JMP SHORT 008E0130
;008E012E CD 20 INT 20
;008E0130 05 18000000 ADD EAX,18
;008E0135 8B00 MOV EAX,DWORD PTR DS:[EAX]
;008E0137 35 22018E00 XOR EAX,8E0122
;008E013C 90 NOP
;008E013D 90 NOP
;008E013E 50 PUSH EAX
;008E013F C3 RET
;
;00850036 13C4 ADC EAX,ESP
;00850038 E8 0A000000 CALL 00850047
;0085003D 90 NOP
;0085003E 1BC2 SBB EAX,EDX
;00850040 E9 09000000 JMP 0085004E
;00850045 1BC3 SBB EAX,EBX
;00850047 83F8 74 CMP EAX,74
;0085004A C3 RET
;0085004B 98 CWDE
;0085004C 33C7 XOR EAX,EDI
;0085004E D6 SALC
;0085004F B8 50008500 MOV EAX,850050
;00850054 EB 02 JMP SHORT 00850058
;00850056 CD 20 INT 20
;00850058 05 18000000 ADD EAX,18
;0085005D 8B00 MOV EAX,DWORD PTR DS:[EAX]
;0085005F 35 36008500 XOR EAX,850036
;00850064 90 NOP
;00850065 90 NOP
;00850066 50 PUSH EAX
;00850067 C3 RET */
}
else if((cMem->DataByte[0] == 0x13 && cMem->DataByte[1] == 0xC4 && cMem->DataByte[2] == 0xE8) || (cMem->DataByte[0] == 0x83 && cMem->DataByte[3] == 0xE8))
{
KnownRedirectionIndex = 5; // ; tELock 0.99 - 1.0 Private!
}
else if((cMem->DataByte[0] == 0xB8 || cMem->DataByte[0] == 0x1D || cMem->DataByte[0] == 0x0D || cMem->DataByte[0] == 0x2D) && cMem->DataByte[5] == 0xB8 && cMem->DataByte[10] == 0xEB && cMem->DataByte[11] == 0x02)
{
KnownRedirectionIndex = 5; // ; tELock 0.99 - 1.0 Private!
/* ;011F0000 B8 2107F205 MOV EAX,5F20721
;011F0005 B8 06008D00 MOV EAX,8D0006
;011F000A EB 02 JMP SHORT 011F000E
;011F000C CD 20 INT 20
;011F000E 05 18000000 ADD EAX,18
;011F0013 8B00 MOV EAX,DWORD PTR DS:[EAX]
;011F0015 35 00008D00 XOR EAX,8D0000
;011F001A 90 NOP
;011F001B 90 NOP
;011F001C 50 PUSH EAX
;011F001D C3 RET
;
;01360000 1D A508F205 SBB EAX,5F208A5
;01360005 B8 28008D00 MOV EAX,8D0028
;0136000A EB 02 JMP SHORT 0136000E
;0136000C CD 20 INT 20
;0136000E 05 18000000 ADD EAX,18
;01360013 8B00 MOV EAX,DWORD PTR DS:[EAX]
;01360015 35 22008D00 XOR EAX,8D0022
;0136001A 90 NOP
;0136001B 90 NOP
;0136001C 50 PUSH EAX
;0136001D C3 RET
;
;014B0000 0D F918F205 OR EAX,5F218F9
;014B0005 B8 4A008D00 MOV EAX,8D004A
;014B000A EB 02 JMP SHORT 014B000E
;014B000C CD 20 INT 20
;014B000E 05 18000000 ADD EAX,18
;014B0013 8B00 MOV EAX,DWORD PTR DS:[EAX]
;014B0015 35 44008D00 XOR EAX,8D0044
;014B001A 90 NOP
;014B001B 90 NOP
;014B001C 50 PUSH EAX
;014B001D C3 RET
;
;01750000 2D 0B37F205 SUB EAX,5F2370B
;01750005 B8 8E008D00 MOV EAX,8D008E
;0175000A EB 02 JMP SHORT 0175000E
;0175000C CD 20 INT 20
;0175000E 05 18000000 ADD EAX,18
;01750013 8B00 MOV EAX,DWORD PTR DS:[EAX]
;01750015 35 88008D00 XOR EAX,8D0088
;0175001A 90 NOP
;0175001B 90 NOP
;0175001C 50 PUSH EAX
;0175001D C3 RET
;
;019F0000 0BC4 OR EAX,ESP
;019F0002 F9 STC
;019F0003 E8 0B000000 CALL 019F0013
;019F0008 90 NOP
;019F0009 13C4 ADC EAX,ESP
;019F000B E9 0A000000 JMP 019F001A
;019F0010 F9 STC
;019F0011 13C3 ADC EAX,EBX
;019F0013 98 CWDE
;019F0014 03C2 ADD EAX,EDX
;019F0016 C3 RET
;
;01B40000 48 DEC EAX
;01B40001 E8 0D000000 CALL 01B40013
;01B40006 03C5 ADD EAX,EBP
;01B40008 FC CLD
;01B40009 E9 0A000000 JMP 01B40018
;01B4000E 35 D82FF205 XOR EAX,5F22FD8
;01B40013 C1C8 9A ROR EAX,9A
;01B40016 C3 RET */
}
else if((cMem->DataByte[0] == 0x0B && cMem->DataByte[1] == 0xC4 && cMem->DataByte[2] == 0xF9 && cMem->DataByte[3] == 0xE8) || (cMem->DataByte[0] == 0x48 && cMem->DataByte[1] == 0xE8))
{
KnownRedirectionIndex = 5; // ; tELock 0.99 - 1.0 Private!
}
else if((cMem->DataByte[0] == 0xB8 && cMem->DataByte[5] == 0xE8 && cMem->DataByte[10] == 0xF9 && cMem->DataByte[11] == 0xE9) && (cMem->DataByte[0] == 0xE8 && cMem->DataByte[1] == 0x0B && cMem->DataByte[10] == 0xE9 && cMem->DataByte[11] == 0x05 && cMem->DataByte[15] == 0x90 && cMem->DataByte[16] == 0xC3))
{
KnownRedirectionIndex = 5; // ; tELock 0.99 - 1.0 Private!
/* ;01C90000 B8 B853F205 MOV EAX,5F253B8
;01C90005 E8 07000000 CALL 01C90011
;01C9000A F9 STC
;01C9000B E9 07000000 JMP 01C90017
;01C90010 90 NOP
;01C90011 23C3 AND EAX,EBX
;01C90013 C3 RET
;
;00A40022 1BC2 SBB EAX,EDX
;00A40024 E8 08000000 CALL 00A40031
;00A40029 40 INC EAX
;00A4002A E9 09000000 JMP 00A40038
;00A4002F 33C7 XOR EAX,EDI
;00A40031 C1E8 92 SHR EAX,92
;00A40034 C3 RET
;00A40035 83E0 25 AND EAX,25
;00A40038 25 E5AE65DD AND EAX,DD65AEE5
;00A4003D B8 3E00A400 MOV EAX,0A4003E
;00A40042 EB 02 JMP SHORT 00A40046
;00A40044 CD 20 INT 20
;00A40046 05 18000000 ADD EAX,18
;00A4004B 8B00 MOV EAX,DWORD PTR DS:[EAX]
;00A4004D 35 2200A400 XOR EAX,0A40022
;00A40052 90 NOP
;00A40053 90 NOP
;00A40054 50 PUSH EAX
;00A40055 C3 RET
;
;00A4005A E8 0B000000 CALL 00A4006A
;00A4005F 15 06F265DD ADC EAX,DD65F206
;00A40064 E9 05000000 JMP 00A4006E
;00A40069 90 NOP
;00A4006A C3 RET
;00A4006B 1BC5 SBB EAX,EBP
;00A4006D 40 INC EAX
;00A4006E 1BC0 SBB EAX,EAX
;00A40070 F9 STC
;00A40071 B8 7200A400 MOV EAX,0A40072
;00A40076 EB 02 JMP SHORT 00A4007A
;00A40078 CD 20 INT 20
;00A4007A 05 18000000 ADD EAX,18
;00A4007F 8B00 MOV EAX,DWORD PTR DS:[EAX]
;00A40081 35 5A00A400 XOR EAX,0A4005A
;00A40086 90 NOP
;00A40087 90 NOP
;00A40088 50 PUSH EAX
;00A40089 C3 RET */
}
else if(cMem->DataByte[0] == 0x1B && cMem->DataByte[1] == 0xC2 && cMem->DataByte[2] == 0xE8 && cMem->DataByte[3] == 0x08 && cMem->DataByte[7] == 0x40 && cMem->DataByte[8] == 0xE9 && cMem->DataByte[9] == 0x09 && cMem->DataByte[10] == 0x00)
{
KnownRedirectionIndex = 5; // ; tELock 0.99 - 1.0 Private!
}
else if(cMem->DataByte[0] == 0x68 && cMem->DataByte[5] == 0xE9)
{
RtlMoveMemory(&TestAddressX86, &cMem->DataByte[1], 4);
if(TestAddressX86 > AddressToTrace)
{
if(ImporterGetAPIName((ULONG_PTR)TestAddressX86) != NULL)
{
KnownRedirectionIndex = 6; // ; ReCrypt 0.74
/* ;001739F1 68 E9D9D477 PUSH User32.EndDialog
;001739F6 ^ E9 FDFEFFFF JMP 001738F8 */
}
}
}
else if((cMem->DataByte[0] == 0xE8 && cMem->DataByte[5] == 0x58 && cMem->DataByte[6] == 0xEB && cMem->DataByte[7] == 0x01) || (cMem->DataByte[0] == 0xC8 && cMem->DataByte[4] == 0xE8 && cMem->DataByte[9] == 0x5B))
{
KnownRedirectionIndex = 7; // ; Orien 2.1x
/* ;GetCommandLineA
;$ ==> >/$ E8 00000000 CALL crackme_.0040DF8F
;$+5 >|$ 58 POP EAX
;$+6 >|. EB 01 JMP SHORT crackme_.0040DF93
;$+8 >| B8 DB B8
;$+9 >|> 85DB TEST EBX,EBX
;$+B >|. 2D 8F1F0000 SUB EAX,1F8F
;$+10 >|. EB 01 JMP SHORT crackme_.0040DF9D
;$+12 >| A8 DB A8
;$+13 >|> 8D80 F0550000 LEA EAX,DWORD PTR DS:[EAX+55F0]
;$+19 >\. C3 RET
;GetCommandLineW
;$ ==> > . E8 00000000 CALL crackme_.0040DFA9
;$+5 >/$ 58 POP EAX
;$+6 >|. EB 01 JMP SHORT crackme_.0040DFAD
;$+8 >| B8 DB B8
;$+9 >|> 85DB TEST EBX,EBX
;$+B >|. 2D A91F0000 SUB EAX,1FA9
;$+10 >|. EB 01 JMP SHORT crackme_.0040DFB7
;$+12 >| A8 DB A8
;$+13 >|> 8D80 F4560000 LEA EAX,DWORD PTR DS:[EAX+56F4]
;$+19 >\. C3 RET
;ExitProcess
;$ ==> > $ C8 000000 ENTER 0,0
;$+4 > . E8 00000000 CALL crackme_.0040DF2A
;$+9 > $ 5B POP EBX
;$+A > . EB 01 JMP SHORT crackme_.0040DF2E
;$+C > B8 DB B8
;$+D > > 85DB TEST EBX,EBX
;$+F > . 81EB 2A1F0000 SUB EBX,1F2A
;$+15 > . EB 01 JMP SHORT crackme_.0040DF39
;$+17 > A8 DB A8
;$+18 > > 8D83 4D310000 LEA EAX,DWORD PTR DS:[EBX+314D]
;$+1E > . 8038 00 CMP BYTE PTR DS:[EAX],0
;$+21 > . 74 29 JE SHORT crackme_.0040DF6D
;$+23 > . EB 01 JMP SHORT crackme_.0040DF47
;$+25 > A8 DB A8
;$+26 > > 8D93 55380000 LEA EDX,DWORD PTR DS:[EBX+3855]
;$+2C > . E8 01000000 CALL crackme_.0040DF53
;$+31 > E9 DB E9
;$+32 > $ 83EC FC SUB ESP,-4
;$+35 > . 6A 00 PUSH 0
;$+37 > . 52 PUSH EDX
;$+38 > . 50 PUSH EAX
;$+39 > . 6A 00 PUSH 0
;$+3B > . E8 05000000 CALL crackme_.0040DF66
;$+40 > . EB 0A JMP SHORT crackme_.0040DF6D
;$+42 > 88 DB 88
;$+43 > FC DB FC
;$+44 > B6 DB B6
;$+45 > $ FFA3 FF3A0000 JMP NEAR DWORD PTR DS:[EBX+3AFF]
;$+4B > CD DB CD
;$+4C > > E8 01000000 CALL crackme_.0040DF73
;$+51 > E9 DB E9
;$+52 > $ 83EC FC SUB ESP,-4
;$+55 > . FF75 08 PUSH DWORD PTR SS:[EBP+8]
;$+58 > . E8 05000000 CALL crackme_.0040DF83
;$+5D > . EB 0A JMP SHORT crackme_.0040DF8A
;$+5F > 88 DB 88
;$+60 > FC DB FC
;$+61 > B6 DB B6
;$+62 > $ FFA3 BF3A0000 JMP NEAR DWORD PTR DS:[EBX+3ABF] */
}
else if((cMem->DataByte[0] == 0xEB && cMem->DataByte[1] == 0x01 && cMem->DataByte[2] == 0x66 && cMem->DataByte[3] == 0x1B) || (cMem->DataByte[0] == 0xEB && cMem->DataByte[1] == 0x02 && cMem->DataByte[2] == 0xCD && cMem->DataByte[3] == 0x20) || (cMem->DataByte[0] == 0xEB && cMem->DataByte[1] == 0x01 && cMem->DataByte[2] == 0xB8 && cMem->DataByte[3] == 0xEB))
{
KnownRedirectionIndex = 4; // ; tELock 0.96 - 0.98
/* ;(BYTE PTR[ESI] == 0EBh && (BYTE PTR[ESI+3] == 0EBh || BYTE PTR[ESI+2] == 0EBh))
;017B0000 0BE4 OR ESP,ESP
;017B0002 75 01 JNZ SHORT 017B0005
;
;15940000 85E4 TEST ESP,ESP
;15940002 79 03 JNS SHORT 15940007
;
;008E0359 B8 8DE44500 MOV EAX,45E48D
;008E035E 90 NOP
;008E035F FF30 PUSH DWORD PTR DS:[EAX]
;008E0361 C3 RET
;
;008F0033 B8 AF008F00 MOV EAX,8F00AF
;008F0038 40 INC EAX
;008F0039 FF30 PUSH DWORD PTR DS:[EAX]
;008F003B C3 RET
;
;008E02F7 B8 20078E00 MOV EAX,8E0720
;008E02FC FF20 JMP NEAR DWORD PTR DS:[EAX] */
}
else if((cMem->DataByte[0] == 0xEB && cMem->DataByte[1] == 0x03 && cMem->DataByte[2] == 0xFF && cMem->DataByte[3] == 0xEB) || (cMem->DataByte[0] == 0xEB && cMem->DataByte[1] == 0x01 && cMem->DataByte[2] == 0xB8 && cMem->DataByte[3] == 0x05) || (cMem->DataByte[0] == 0xEB && cMem->DataByte[1] == 0x02 && cMem->DataByte[2] == 0xFF && cMem->DataByte[3] == 0x20))
{
KnownRedirectionIndex = 4; // ; tELock 0.96 - 0.98
}
else if((cMem->DataByte[0] == 0xF9 || cMem->DataByte[0] == 0xF8) || (cMem->DataByte[0] == 0x0B && cMem->DataByte[1] == 0xE4) || (cMem->DataByte[0] == 0x85 && cMem->DataByte[1] == 0xE4))
{
KnownRedirectionIndex = 4; // ; tELock 0.96 - 0.98
}
else if(cMem->DataByte[0] == 0xEB && (cMem->DataByte[1] > NULL && cMem->DataByte[1] < 4))
{
i = 2;
j = 30;
while(j > NULL)
{
if(cMem->DataByte[i] == 0xB8 && (cMem->DataByte[i+5] == 0x40 || cMem->DataByte[i+5] == 0x90) && cMem->DataByte[i+6] == 0xFF && cMem->DataByte[i+7] == 0x30 && cMem->DataByte[i+8] == 0xC3)
{
KnownRedirectionIndex = 4; // ; tELock 0.96 - 0.98
j = 1;
}
i++;
j--;
}
}
else if(HashCheck)
{
if(cMem->DataByte[0] == 0x9C || cMem->DataByte[0] == 0xEB)
{
MemoryHash = EngineHashMemory((char*)TraceMemory, 192, MemoryHash);
if(MemoryHash == 0x5AF7E209 || MemoryHash == 0xEB480CAC || MemoryHash == 0x86218561 || MemoryHash == 0xCA9ABD85)
{
KnownRedirectionIndex = 9; // ; SVKP 1.x
}
else if(MemoryHash == 0xF1F84A98 || MemoryHash == 0x91823290 || MemoryHash == 0xBEE6BAA0 || MemoryHash == 0x79603232)
{
KnownRedirectionIndex = 9; // ; SVKP 1.x
}
}
}
VirtualFree(TraceMemory, NULL, MEM_RELEASE);
return(KnownRedirectionIndex);
}
else
{
VirtualFree(TraceMemory, NULL, MEM_RELEASE);
}
}
}
return(NULL);
}
__declspec(dllexport) long long TITCALL TracerFixKnownRedirection(HANDLE hProcess, ULONG_PTR AddressToTrace, DWORD RedirectionId)
{
int i = NULL;
DWORD TestAddressX86;
DWORD ReadAddressX86;
DWORD MemoryHash = NULL;
PMEMORY_CMP_HANDLER cMem;
MEMORY_BASIC_INFORMATION MemInfo;
ULONG_PTR ueNumberOfBytesRead = NULL;
LPVOID TracerReadMemory = VirtualAlloc(NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE);
DWORD MaximumReadSize=0x1000;
if(!TracerReadMemory)
return (NULL);
cMem = (PMEMORY_CMP_HANDLER)TracerReadMemory;
VirtualQueryEx(hProcess, (LPVOID)AddressToTrace, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
if(MemInfo.RegionSize > NULL)
{
MaximumReadSize = (DWORD)((ULONG_PTR)MemInfo.BaseAddress + MemInfo.RegionSize - AddressToTrace);
if(MaximumReadSize > 0x1000)
{
MaximumReadSize = 0x1000;
}
}
if(RedirectionId == NULL)
{
RedirectionId = (DWORD)TracerDetectRedirection(hProcess, AddressToTrace);
}
if(RedirectionId == 1) // TracerFix_ACProtect
{
__try
{
if(ReadProcessMemory(hProcess, (LPVOID)AddressToTrace, TracerReadMemory, MaximumReadSize, &ueNumberOfBytesRead))
{
RtlMoveMemory(&TestAddressX86, &cMem->DataByte[1], 4);
if(cMem->DataByte[5] == 0x81 && cMem->DataByte[6] == 0x2C)
{
RtlMoveMemory(&ReadAddressX86, &cMem->DataByte[8], 4);
TestAddressX86 = TestAddressX86 - ReadAddressX86;
}
else if(cMem->DataByte[5] == 0x81 && cMem->DataByte[6] == 0x34)
{
RtlMoveMemory(&ReadAddressX86, &cMem->DataByte[8], 4);
TestAddressX86 = TestAddressX86 ^ ReadAddressX86;
}
else if(cMem->DataByte[5] == 0x81 && cMem->DataByte[6] == 0x04)
{
RtlMoveMemory(&ReadAddressX86, &cMem->DataByte[8], 4);
TestAddressX86 = TestAddressX86 + ReadAddressX86;
}
VirtualFree(TracerReadMemory, NULL, MEM_RELEASE);
return((DWORD)TestAddressX86);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
VirtualFree(TracerReadMemory, NULL, MEM_RELEASE);
return(NULL);
}
}
else if(RedirectionId == 2) // TracerFix_tELock_varA
{
__try
{
if(ReadProcessMemory(hProcess, (LPVOID)AddressToTrace, TracerReadMemory, MaximumReadSize, &ueNumberOfBytesRead))
{
RtlMoveMemory(&TestAddressX86, &cMem->DataByte[2], 4);
if(ReadProcessMemory(hProcess, (LPVOID)TestAddressX86, &TestAddressX86, 4, &ueNumberOfBytesRead))
{
VirtualFree(TracerReadMemory, NULL, MEM_RELEASE);
return((DWORD)TestAddressX86);
}
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
VirtualFree(TracerReadMemory, NULL, MEM_RELEASE);
return(NULL);
}
}
else if(RedirectionId == 3) // TracerFix_tELock_varB
{
__try
{
if(ReadProcessMemory(hProcess, (LPVOID)AddressToTrace, TracerReadMemory, MaximumReadSize, &ueNumberOfBytesRead))
{
if(cMem->DataByte[0] == 0xFF && cMem->DataByte[1] == 0x35)
{
RtlMoveMemory(&TestAddressX86, &cMem->DataByte[2], 4);
}
else
{
RtlMoveMemory(&TestAddressX86, &cMem->DataByte[3], 4);
}
if(ReadProcessMemory(hProcess, (LPVOID)TestAddressX86, &TestAddressX86, 4, &ueNumberOfBytesRead))
{
VirtualFree(TracerReadMemory, NULL, MEM_RELEASE);
return((DWORD)TestAddressX86);
}
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
VirtualFree(TracerReadMemory, NULL, MEM_RELEASE);
return(NULL);
}
}
else if(RedirectionId == 4) // TracerFix_tELock_varC
{
__try
{
if(ReadProcessMemory(hProcess, (LPVOID)AddressToTrace, TracerReadMemory, MaximumReadSize, &ueNumberOfBytesRead))
{
i = 100;
if(cMem->DataByte[0] == 0xEB && (cMem->DataByte[1] > 0 && cMem->DataByte[1] < 4))
{
cMem = (PMEMORY_CMP_HANDLER)((ULONG_PTR)cMem + cMem->DataByte[1] + 2);
}
while(i > NULL && (cMem->DataByte[0] != 0xFF && (cMem->DataByte[1] != 0x20 || cMem->DataByte[1] != 0x30)))
{
cMem = (PMEMORY_CMP_HANDLER)((ULONG_PTR)cMem + 1);
i--;
}
if(i != NULL && cMem->DataByte[0] == 0xFF && cMem->DataByte[1] == 0x20)
{
if(cMem->DataByte[2] != 0x90)
{
cMem = (PMEMORY_CMP_HANDLER)((ULONG_PTR)cMem + 1);
while(i > NULL && (cMem->DataByte[0] != 0xFF && (cMem->DataByte[1] != 0x20 || cMem->DataByte[1] != 0x30)))
{
cMem = (PMEMORY_CMP_HANDLER)((ULONG_PTR)cMem + 1);
i--;
}
}
}
if(i != NULL && cMem->DataByte[0] == 0xFF && cMem->DataByte[1] == 0x30)
{
cMem = (PMEMORY_CMP_HANDLER)((ULONG_PTR)cMem - 6);
if(cMem->DataByte[0] == 0xB8)
{
RtlMoveMemory(&TestAddressX86, &cMem->DataByte[1], 4);
if(cMem->DataByte[5] == 0x40)
{
TestAddressX86++;
}
}
else
{
RtlMoveMemory(&TestAddressX86, &cMem->DataByte[2], 4);
}
if(ReadProcessMemory(hProcess, (LPVOID)TestAddressX86, &TestAddressX86, 4, &ueNumberOfBytesRead))
{
VirtualFree(TracerReadMemory, NULL, MEM_RELEASE);
return((DWORD)TestAddressX86);
}
}
else if(i != NULL && cMem->DataByte[0] == 0xFF && cMem->DataByte[1] == 0x20)
{
cMem = (PMEMORY_CMP_HANDLER)((ULONG_PTR)cMem - 6);
RtlMoveMemory(&TestAddressX86, &cMem->DataByte[2], 4);
if(ReadProcessMemory(hProcess, (LPVOID)TestAddressX86, &TestAddressX86, 4, &ueNumberOfBytesRead))
{
VirtualFree(TracerReadMemory, NULL, MEM_RELEASE);
return((DWORD)TestAddressX86);
}
}
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
VirtualFree(TracerReadMemory, NULL, MEM_RELEASE);
return(NULL);
}
}
else if(RedirectionId == 5) // TracerFix_tELock_varD
{
__try
{
if(ReadProcessMemory(hProcess, (LPVOID)AddressToTrace, TracerReadMemory, MaximumReadSize, &ueNumberOfBytesRead))
{
i = 100;
while(i > NULL && (cMem->DataByte[0] != 0x50 || cMem->DataByte[1] != 0xC3))
{
cMem = (PMEMORY_CMP_HANDLER)((ULONG_PTR)cMem + 1);
i--;
}
if(i != NULL && cMem->DataByte[0] == 0x50 && cMem->DataByte[1] == 0xC3)
{
cMem = (PMEMORY_CMP_HANDLER)((ULONG_PTR)cMem - 0x16);
RtlMoveMemory(&ReadAddressX86, &cMem->DataByte[0x10], 4);
RtlMoveMemory(&TestAddressX86, &cMem->DataByte[0], 4);
TestAddressX86 = TestAddressX86 + 0x18;
if(ReadProcessMemory(hProcess, (LPVOID)TestAddressX86, &TestAddressX86, 4, &ueNumberOfBytesRead))
{
TestAddressX86 = TestAddressX86 ^ ReadAddressX86;
VirtualFree(TracerReadMemory, NULL, MEM_RELEASE);
return((DWORD)TestAddressX86);
}
}
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
VirtualFree(TracerReadMemory, NULL, MEM_RELEASE);
return(NULL);
}
}
else if(RedirectionId == 6) // TracerFix_ReCrypt
{
__try
{
if(ReadProcessMemory(hProcess, (LPVOID)AddressToTrace, TracerReadMemory, MaximumReadSize, &ueNumberOfBytesRead))
{
RtlMoveMemory(&TestAddressX86, &cMem->DataByte[1], 4);
VirtualFree(TracerReadMemory, NULL, MEM_RELEASE);
return((DWORD)TestAddressX86);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
VirtualFree(TracerReadMemory, NULL, MEM_RELEASE);
return(NULL);
}
}
else if(RedirectionId == 7) // TracerFix_Orien
{
__try
{
if(ReadProcessMemory(hProcess, (LPVOID)AddressToTrace, TracerReadMemory, MaximumReadSize, &ueNumberOfBytesRead))
{
if(cMem->DataByte[0] == 0xE8)
{
RtlMoveMemory(&ReadAddressX86, &cMem->DataByte[0x15], 4);
if(ReadAddressX86 == 0x55F0)
{
TestAddressX86 = (DWORD)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetCommandLineA"));
}
else
{
TestAddressX86 = (DWORD)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetCommandLineW"));
}
VirtualFree(TracerReadMemory, NULL, MEM_RELEASE);
return((DWORD)TestAddressX86);
}
else if(cMem->DataByte[0] == 0xC8)
{
TestAddressX86 = (DWORD)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "ExitProcess"));
VirtualFree(TracerReadMemory, NULL, MEM_RELEASE);
return((DWORD)TestAddressX86);
}
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
VirtualFree(TracerReadMemory, NULL, MEM_RELEASE);
return(NULL);
}
}
else if(RedirectionId == 8) // TracerFix_AlexProtector
{
__try
{
if(ReadProcessMemory(hProcess, (LPVOID)AddressToTrace, TracerReadMemory, MaximumReadSize, &ueNumberOfBytesRead))
{
cMem = (PMEMORY_CMP_HANDLER)((ULONG_PTR)cMem + 0x34);
RtlMoveMemory(&TestAddressX86, &cMem->DataByte[0], 4);
VirtualFree(TracerReadMemory, NULL, MEM_RELEASE);
return((DWORD)TestAddressX86);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
VirtualFree(TracerReadMemory, NULL, MEM_RELEASE);
return(NULL);
}
}
else if(RedirectionId == 9 && MaximumReadSize > 192) // TracerFix_SVKP
{
__try
{
if(ReadProcessMemory(hProcess, (LPVOID)AddressToTrace, TracerReadMemory, MaximumReadSize, &ueNumberOfBytesRead))
{
if(cMem->DataByte[0] == 0x9C || cMem->DataByte[0] == 0xEB)
{
MemoryHash = EngineHashMemory((char*)TracerReadMemory, 192, MemoryHash);
if(MemoryHash == 0x5AF7E209)
{
TestAddressX86 = (DWORD)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetCommandLineA"));
}
else if(MemoryHash == 0xEB480CAC)
{
TestAddressX86 = (DWORD)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "ExitProcess"));
}
else if(MemoryHash == 0x86218561)
{
TestAddressX86 = (DWORD)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetCurrentProcess"));
}
else if(MemoryHash == 0xCA9ABD85)
{
TestAddressX86 = (DWORD)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetVersion"));
}
else if(MemoryHash == 0xF1F84A98)
{
TestAddressX86 = (DWORD)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetVersionExA"));
}
else if(MemoryHash == 0x91823290)
{
TestAddressX86 = (DWORD)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetModuleHandleA"));
}
else if(MemoryHash == 0xBEE6BAA0)
{
TestAddressX86 = (DWORD)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("user32.dll"), "MessageBoxA"));
}
else if(MemoryHash == 0x79603232)
{
TestAddressX86 = (DWORD)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetModuleHandleA"));
}
VirtualFree(TracerReadMemory, NULL, MEM_RELEASE);
return((DWORD)TestAddressX86);
}
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
VirtualFree(TracerReadMemory, NULL, MEM_RELEASE);
return(NULL);
}
}
VirtualFree(TracerReadMemory, NULL, MEM_RELEASE);
return(NULL);
}
// TitanEngine.Exporter.functions:
__declspec(dllexport) void TITCALL ExporterCleanup()
{
int i = NULL;
for(i = 0; i < 1000; i++)
{
expExportAddress[i] = 0;
expSortedNamePointers[i] = 0;
expNamePointers[i] = 0;
expNameHashes[i] = 0;
expOrdinals[i] = 0;
}
//RtlZeroMemory(&szExportFileName, 512);
RtlZeroMemory(&expExportData, sizeof IMAGE_EXPORT_DIRECTORY);
VirtualFree(expTableData, NULL, MEM_RELEASE);
expExportNumber = NULL;
expTableData = NULL;
expImageBase = NULL;
}
__declspec(dllexport) void TITCALL ExporterSetImageBase(ULONG_PTR ImageBase)
{
expImageBase = ImageBase;
}
__declspec(dllexport) void TITCALL ExporterInit(DWORD MemorySize, ULONG_PTR ImageBase, DWORD ExportOrdinalBase, char* szExportModuleName)
{
if(expTableData != NULL)
{
ExporterCleanup();
}
expExportData.Base = ExportOrdinalBase;
expTableData = VirtualAlloc(NULL, MemorySize, MEM_COMMIT, PAGE_READWRITE);
if(szExportModuleName != NULL)
{
RtlMoveMemory(expTableData, szExportModuleName, lstrlenA(szExportModuleName));
expTableDataCWP = (LPVOID)((ULONG_PTR)expTableData + lstrlenA(szExportModuleName) + 2);
expNamePresent = true;
}
else
{
expTableDataCWP = expTableData;
expNamePresent = false;
}
expImageBase = ImageBase;
}
__declspec(dllexport) bool TITCALL ExporterAddNewExport(char* szExportName, DWORD ExportRelativeAddress)
{
unsigned int i;
DWORD NameHash;
if(expTableDataCWP != NULL && szExportName != NULL)
{
NameHash = (DWORD)EngineHashString(szExportName);
for(i = 0; i < expExportNumber; i++)
{
if(expNameHashes[i] == NameHash)
{
return(true);
}
}
expExportAddress[expExportNumber] = ExportRelativeAddress;
expNamePointers[expExportNumber] = (ULONG_PTR)expTableDataCWP;
expNameHashes[expExportNumber] = (DWORD)EngineHashString(szExportName);
expOrdinals[expExportNumber] = (WORD)(expExportNumber);
RtlMoveMemory(expTableDataCWP, szExportName, lstrlenA(szExportName));
expTableDataCWP = (LPVOID)((ULONG_PTR)expTableDataCWP + lstrlenA(szExportName) + 2);
expExportNumber++;
return(true);
}
return(false);
}
__declspec(dllexport) bool TITCALL ExporterAddNewOrdinalExport(DWORD OrdinalNumber, DWORD ExportRelativeAddress)
{
unsigned int i = NULL;
char szExportFunctionName[512];
RtlZeroMemory(&szExportFunctionName, 512);
if(expTableDataCWP != NULL)
{
if(expExportNumber == NULL)
{
expExportData.Base = OrdinalNumber;
wsprintfA(szExportFunctionName, "Func%d", expExportNumber + 1);
return(ExporterAddNewExport(szExportFunctionName, ExportRelativeAddress));
}
else
{
if(OrdinalNumber == expExportData.Base + expExportNumber - 1)
{
wsprintfA(szExportFunctionName, "Func%d", expExportNumber + 1);
return(ExporterAddNewExport(szExportFunctionName, ExportRelativeAddress));
}
else if(OrdinalNumber > expExportData.Base + expExportNumber - 1)
{
for(i = expExportData.Base + expExportNumber - 1; i <= OrdinalNumber; i++)
{
RtlZeroMemory(&szExportFunctionName, 512);
wsprintfA(szExportFunctionName, "Func%d", expExportNumber + 1);
ExporterAddNewExport(szExportFunctionName, ExportRelativeAddress);
}
return(true);
}
else
{
return(true);
}
}
}
return(false);
}
__declspec(dllexport) long TITCALL ExporterGetAddedExportCount()
{
return(expExportNumber);
}
__declspec(dllexport) long TITCALL ExporterEstimatedSize()
{
DWORD EstimatedSize = NULL;
EstimatedSize = (DWORD)((ULONG_PTR)expTableDataCWP - (ULONG_PTR)expTableData);
EstimatedSize = EstimatedSize + (expExportNumber * 12) + sizeof IMAGE_EXPORT_DIRECTORY;
return(EstimatedSize);
}
__declspec(dllexport) bool TITCALL ExporterBuildExportTable(ULONG_PTR StorePlace, ULONG_PTR FileMapVA)
{
unsigned int i = NULL;
unsigned int j = NULL;
LPVOID expBuildExportDataOld;
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
LPVOID expBuildExportData;
LPVOID expBuildExportDataCWP;
DWORD StorePlaceRVA = (DWORD)ConvertFileOffsetToVA(FileMapVA, StorePlace, false);
ULONG_PTR TempULONG;
DWORD TempDWORD;
BOOL FileIs64 = false;
if(expTableDataCWP != NULL)
{
expBuildExportData = VirtualAlloc(NULL, ExporterEstimatedSize(), MEM_COMMIT, PAGE_READWRITE);
expBuildExportDataCWP = (LPVOID)((ULONG_PTR)expBuildExportData + sizeof IMAGE_EXPORT_DIRECTORY);
expExportData.NumberOfNames = expExportNumber;
expExportData.NumberOfFunctions = expExportNumber;
for(i = 0; i < expExportNumber; i++)
{
for(j = 0; j < expExportNumber; j++)
{
if(lstrcmpiA((PCHAR)expNamePointers[i], (PCHAR)expNamePointers[j]) < NULL)
{
TempULONG = expNamePointers[j];
expNamePointers[j] = expNamePointers[i];
expNamePointers[i] = TempULONG;
TempDWORD = expExportAddress[j];
expExportAddress[j] = expExportAddress[i];
expExportAddress[i] = TempDWORD;
}
}
}
if(expNamePresent)
{
expExportData.Name = StorePlaceRVA + (DWORD)((ULONG_PTR)expBuildExportDataCWP - (ULONG_PTR)expBuildExportData);
RtlMoveMemory(expBuildExportDataCWP, (LPVOID)expTableData, lstrlenA((PCHAR)expTableData));
expBuildExportDataCWP = (LPVOID)((ULONG_PTR)expBuildExportDataCWP + lstrlenA((PCHAR)expTableData) + 2);
}
for(i = 0; i < expExportNumber; i++)
{
RtlMoveMemory(expBuildExportDataCWP, (LPVOID)expNamePointers[i], lstrlenA((PCHAR)expNamePointers[i]));
expBuildExportDataOld = expBuildExportDataCWP;
expBuildExportDataCWP = (LPVOID)((ULONG_PTR)expBuildExportDataCWP + lstrlenA((PCHAR)expNamePointers[i]) + 2);
expSortedNamePointers[i] = (DWORD)((ULONG_PTR)expBuildExportDataOld - (ULONG_PTR)expBuildExportData) + StorePlaceRVA;
}
expExportData.AddressOfFunctions = StorePlaceRVA + (DWORD)((ULONG_PTR)expBuildExportDataCWP - (ULONG_PTR)expBuildExportData);
RtlMoveMemory(expBuildExportDataCWP, &expExportAddress, 4 * expExportNumber);
expBuildExportDataCWP = (LPVOID)((ULONG_PTR)expBuildExportDataCWP + 4 * expExportNumber);
expExportData.AddressOfNames = StorePlaceRVA + (DWORD)((ULONG_PTR)expBuildExportDataCWP - (ULONG_PTR)expBuildExportData);
RtlMoveMemory(expBuildExportDataCWP, &expSortedNamePointers, 4 * expExportNumber);
expBuildExportDataCWP = (LPVOID)((ULONG_PTR)expBuildExportDataCWP + 4 * expExportNumber);
expExportData.AddressOfNameOrdinals = StorePlaceRVA + (DWORD)((ULONG_PTR)expBuildExportDataCWP - (ULONG_PTR)expBuildExportData);
RtlMoveMemory(expBuildExportDataCWP, &expOrdinals, 2 * expExportNumber);
expBuildExportDataCWP = (LPVOID)((ULONG_PTR)expBuildExportDataCWP + 2 * expExportNumber);
RtlMoveMemory(expBuildExportData, &expExportData, sizeof IMAGE_EXPORT_DIRECTORY);
__try
{
RtlMoveMemory((LPVOID)StorePlace, expBuildExportData, (DWORD)((ULONG_PTR)expBuildExportDataCWP - (ULONG_PTR)expBuildExportData));
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
VirtualFree(expBuildExportData, NULL, MEM_RELEASE);
ExporterCleanup();
return(false);
}
if(FileMapVA != NULL)
{
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, NULL, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
return false;
}
if(!FileIs64)
{
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = (DWORD)StorePlaceRVA;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = (DWORD)((ULONG_PTR)expBuildExportDataCWP - (ULONG_PTR)expBuildExportData);
}
else
{
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = (DWORD)StorePlaceRVA;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = (DWORD)((ULONG_PTR)expBuildExportDataCWP - (ULONG_PTR)expBuildExportData);
}
}
}
VirtualFree(expBuildExportData, NULL, MEM_RELEASE);
ExporterCleanup();
return(true);
}
return(false);
}
__declspec(dllexport) bool TITCALL ExporterBuildExportTableEx(char* szExportFileName, char* szSectionName)
{
wchar_t uniExportFileName[MAX_PATH] = {};
if(szExportFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szExportFileName, lstrlenA(szExportFileName)+1, uniExportFileName, sizeof(uniExportFileName)/(sizeof(uniExportFileName[0])));
return(ExporterBuildExportTableExW(uniExportFileName, szSectionName));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL ExporterBuildExportTableExW(wchar_t* szExportFileName, char* szSectionName)
{
HANDLE FileHandle;
DWORD FileSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
DWORD NewSectionVO = NULL;
DWORD NewSectionFO = NULL;
bool ReturnValue = false;
if(ExporterGetAddedExportCount() > NULL)
{
NewSectionVO = AddNewSectionW(szExportFileName, szSectionName, ExporterEstimatedSize());
if(MapFileExW(szExportFileName, UE_ACCESS_ALL, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
NewSectionFO = (DWORD)ConvertVAtoFileOffset(FileMapVA, NewSectionVO + (ULONG_PTR)GetPE32DataFromMappedFile(FileMapVA, NULL, UE_IMAGEBASE), true);
ReturnValue = ExporterBuildExportTable(NewSectionFO, FileMapVA);
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
if(ReturnValue)
{
return(true);
}
else
{
return(false);
}
}
else
{
return(false);
}
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL ExporterLoadExportTable(char* szFileName)
{
wchar_t uniFileName[MAX_PATH] = {};
if(szFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
return(ExporterLoadExportTableW(uniFileName));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL ExporterLoadExportTableW(wchar_t* szFileName)
{
unsigned int i = 0;
unsigned int j = 0;
unsigned int n = 0;
unsigned int x = 0;
bool ExportPresent = false;
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
PIMAGE_EXPORT_DIRECTORY PEExports;
PEXPORTED_DATA ExportedFunctions;
PEXPORTED_DATA ExportedFunctionNames;
PEXPORTED_DATA_WORD ExportedFunctionOrdinals;
char* ExportName = NULL;
BOOL FileIs64;
HANDLE FileHandle;
DWORD FileSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
if(MapFileExW(szFileName, UE_ACCESS_READ, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, FileHandle, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
if(!FileIs64)
{
if(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress != NULL)
{
PEExports = (PIMAGE_EXPORT_DIRECTORY)(ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + PEHeader32->OptionalHeader.ImageBase), true));
ExportedFunctions = (PEXPORTED_DATA)(ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)(PEExports->AddressOfFunctions + PEHeader32->OptionalHeader.ImageBase), true));
ExporterInit(50 * 1024, (ULONG_PTR)PEHeader32->OptionalHeader.ImageBase, PEExports->Base, NULL);
ExportPresent = true;
}
}
else
{
if(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress != NULL)
{
PEExports = (PIMAGE_EXPORT_DIRECTORY)(ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + PEHeader64->OptionalHeader.ImageBase), true));
ExportedFunctions = (PEXPORTED_DATA)(ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)(PEExports->AddressOfFunctions + PEHeader64->OptionalHeader.ImageBase), true));
ExporterInit(50 * 1024, (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, PEExports->Base, NULL);
ExportPresent = true;
}
}
if(ExportPresent)
{
for(n = 0; n <= PEExports->NumberOfNames; n++)
{
ExportPresent = false;
x = n;
if(!FileIs64)
{
ExportedFunctionNames = (PEXPORTED_DATA)(ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)(PEExports->AddressOfNames + PEHeader32->OptionalHeader.ImageBase), true));
ExportedFunctionOrdinals = (PEXPORTED_DATA_WORD)(ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)(PEExports->AddressOfNameOrdinals + PEHeader32->OptionalHeader.ImageBase), true));
}
else
{
ExportedFunctionNames = (PEXPORTED_DATA)(ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)(PEExports->AddressOfNames + PEHeader64->OptionalHeader.ImageBase), true));
ExportedFunctionOrdinals = (PEXPORTED_DATA_WORD)(ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)(PEExports->AddressOfNameOrdinals + PEHeader64->OptionalHeader.ImageBase), true));
}
for(j = 0; j <= PEExports->NumberOfNames; j++)
{
if(ExportedFunctionOrdinals->OrdinalNumber != x)
{
ExportedFunctionOrdinals = (PEXPORTED_DATA_WORD)((ULONG_PTR)ExportedFunctionOrdinals + 2);
}
else
{
ExportPresent = true;
break;
}
}
if(ExportPresent)
{
ExportedFunctionNames = (PEXPORTED_DATA)((ULONG_PTR)ExportedFunctionNames + j * 4);
if(!FileIs64)
{
ExportName = (char*)(ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)(ExportedFunctionNames->ExportedItem + PEHeader32->OptionalHeader.ImageBase), true));
}
else
{
ExportName = (char*)(ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)(ExportedFunctionNames->ExportedItem + PEHeader64->OptionalHeader.ImageBase), true));
}
ExporterAddNewExport(ExportName, ExportedFunctions->ExportedItem);
}
ExportedFunctions = (PEXPORTED_DATA)((ULONG_PTR)ExportedFunctions + 4);
}
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(true);
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
else
{
return(false);
}
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
// TitanEngine.Librarian.functions:
__declspec(dllexport) bool TITCALL LibrarianSetBreakPoint(char* szLibraryName, DWORD bpxType, bool SingleShoot, LPVOID bpxCallBack)
{
int i = MAX_LIBRARY_BPX;
PLIBRARY_BREAK_DATA ptrLibrarianData = (PLIBRARY_BREAK_DATA)LibrarianData;
if(szLibraryName != NULL && ptrLibrarianData != NULL)
{
while(i > NULL && ptrLibrarianData->szLibraryName[0] != 0x00)
{
ptrLibrarianData = (PLIBRARY_BREAK_DATA)((ULONG_PTR)ptrLibrarianData + sizeof LIBRARY_BREAK_DATA);
i--;
}
lstrcpyA(&ptrLibrarianData->szLibraryName[0], szLibraryName);
ptrLibrarianData->bpxCallBack = bpxCallBack;
ptrLibrarianData->bpxSingleShoot = SingleShoot;
ptrLibrarianData->bpxType = bpxType;
return(true);
}
return(false);
}
__declspec(dllexport) bool TITCALL LibrarianRemoveBreakPoint(char* szLibraryName, DWORD bpxType)
{
int i = MAX_LIBRARY_BPX;
PLIBRARY_BREAK_DATA ptrLibrarianData = (PLIBRARY_BREAK_DATA)LibrarianData;
if(szLibraryName != NULL && ptrLibrarianData != NULL)
{
while(i > NULL)
{
if(ptrLibrarianData->szLibraryName[0] != 0x00)
{
if(lstrcmpiA(szLibraryName, ptrLibrarianData->szLibraryName) == NULL && (ptrLibrarianData->bpxType == bpxType || bpxType == UE_ON_LIB_ALL))
{
RtlZeroMemory(ptrLibrarianData, sizeof LIBRARY_BREAK_DATA);
}
}
ptrLibrarianData = (PLIBRARY_BREAK_DATA)((ULONG_PTR)ptrLibrarianData + sizeof LIBRARY_BREAK_DATA);
i--;
}
return(true);
}
return(false);
}
__declspec(dllexport) void* TITCALL LibrarianGetLibraryInfo(char* szLibraryName)
{
wchar_t uniLibraryName[MAX_PATH] = {};
PLIBRARY_ITEM_DATAW LibInfo;
if(szLibraryName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szLibraryName, lstrlenA(szLibraryName)+1, uniLibraryName, sizeof(uniLibraryName)/(sizeof(uniLibraryName[0])));
LibInfo = (PLIBRARY_ITEM_DATAW)LibrarianGetLibraryInfoW(uniLibraryName);
if(LibInfo != NULL)
{
RtlZeroMemory(&LibraryInfoData, sizeof LIBRARY_ITEM_DATA);
LibraryInfoData.hFile = LibInfo->hFile;
LibraryInfoData.BaseOfDll = LibInfo->BaseOfDll;
LibraryInfoData.hFileMapping = LibInfo->hFileMapping;
LibraryInfoData.hFileMappingView = LibInfo->hFileMappingView;
WideCharToMultiByte(CP_ACP, NULL, LibInfo->szLibraryName, -1, &LibraryInfoData.szLibraryName[0], sizeof LibraryInfoData.szLibraryName, NULL, NULL);
WideCharToMultiByte(CP_ACP, NULL, LibInfo->szLibraryPath, -1, &LibraryInfoData.szLibraryPath[0], sizeof LibraryInfoData.szLibraryPath, NULL, NULL);
return((void*)&LibraryInfoData);
}
else
{
return(NULL);
}
}
else
{
return(NULL);
}
}
__declspec(dllexport) void* TITCALL LibrarianGetLibraryInfoW(wchar_t* szLibraryName)
{
PLIBRARY_ITEM_DATAW hListLibraryPtr = NULL;
if(hListLibrary != NULL)
{
hListLibraryPtr = (PLIBRARY_ITEM_DATAW)hListLibrary;
while(hListLibraryPtr->hFile != NULL)
{
if(hListLibraryPtr->hFile != (HANDLE)-1)
{
if(lstrcmpiW(hListLibraryPtr->szLibraryName, szLibraryName) == NULL)
{
return((void*)hListLibraryPtr);
}
}
hListLibraryPtr = (PLIBRARY_ITEM_DATAW)((ULONG_PTR)hListLibraryPtr + sizeof LIBRARY_ITEM_DATAW);
}
}
return(NULL);
}
__declspec(dllexport) void* TITCALL LibrarianGetLibraryInfoEx(void* BaseOfDll)
{
PLIBRARY_ITEM_DATAW LibInfo;
LibInfo = (PLIBRARY_ITEM_DATAW)LibrarianGetLibraryInfoExW(BaseOfDll);
if(LibInfo != NULL)
{
RtlZeroMemory(&LibraryInfoData, sizeof LIBRARY_ITEM_DATA);
LibraryInfoData.hFile = LibInfo->hFile;
LibraryInfoData.BaseOfDll = LibInfo->BaseOfDll;
LibraryInfoData.hFileMapping = LibInfo->hFileMapping;
LibraryInfoData.hFileMappingView = LibInfo->hFileMappingView;
WideCharToMultiByte(CP_ACP, NULL, LibInfo->szLibraryName, -1, &LibraryInfoData.szLibraryName[0], sizeof LibraryInfoData.szLibraryName, NULL, NULL);
WideCharToMultiByte(CP_ACP, NULL, LibInfo->szLibraryPath, -1, &LibraryInfoData.szLibraryPath[0], sizeof LibraryInfoData.szLibraryPath, NULL, NULL);
return((void*)&LibraryInfoData);
}
else
{
return(NULL);
}
}
__declspec(dllexport) void* TITCALL LibrarianGetLibraryInfoExW(void* BaseOfDll)
{
PLIBRARY_ITEM_DATAW hListLibraryPtr = NULL;
if(hListLibrary != NULL)
{
hListLibraryPtr = (PLIBRARY_ITEM_DATAW)hListLibrary;
while(hListLibraryPtr->hFile != NULL)
{
if(hListLibraryPtr->hFile != (HANDLE)-1)
{
if(hListLibraryPtr->BaseOfDll == BaseOfDll)
{
return((void*)hListLibraryPtr);
}
}
hListLibraryPtr = (PLIBRARY_ITEM_DATAW)((ULONG_PTR)hListLibraryPtr + sizeof LIBRARY_ITEM_DATAW);
}
}
return(NULL);
}
__declspec(dllexport) void TITCALL LibrarianEnumLibraryInfo(void* EnumCallBack)
{
PLIBRARY_ITEM_DATAW hListLibraryPtr = NULL;
typedef void(TITCALL *fEnumCallBack)(LPVOID fLibraryDetail);
fEnumCallBack myEnumCallBack = (fEnumCallBack)EnumCallBack;
if(hListLibrary != NULL)
{
hListLibraryPtr = (PLIBRARY_ITEM_DATAW)hListLibrary;
while(EnumCallBack != NULL && hListLibraryPtr->hFile != NULL)
{
if(hListLibraryPtr->hFile != (HANDLE)-1)
{
__try
{
myEnumCallBack((void*)hListLibraryPtr);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
EnumCallBack = NULL;
}
}
hListLibraryPtr = (PLIBRARY_ITEM_DATAW)((ULONG_PTR)hListLibraryPtr + sizeof LIBRARY_ITEM_DATAW);
}
}
}
__declspec(dllexport) void TITCALL LibrarianEnumLibraryInfoW(void* EnumCallBack)
{
LIBRARY_ITEM_DATA myLibraryInfoData;
PLIBRARY_ITEM_DATAW hListLibraryPtr = NULL;
typedef void(TITCALL *fEnumCallBack)(LPVOID fLibraryDetail);
fEnumCallBack myEnumCallBack = (fEnumCallBack)EnumCallBack;
if(hListLibrary != NULL)
{
hListLibraryPtr = (PLIBRARY_ITEM_DATAW)hListLibrary;
while(EnumCallBack != NULL && hListLibraryPtr->hFile != NULL)
{
if(hListLibraryPtr->hFile != (HANDLE)-1)
{
__try
{
RtlZeroMemory(&myLibraryInfoData, sizeof LIBRARY_ITEM_DATA);
myLibraryInfoData.hFile = hListLibraryPtr->hFile;
myLibraryInfoData.BaseOfDll = hListLibraryPtr->BaseOfDll;
myLibraryInfoData.hFileMapping = hListLibraryPtr->hFileMapping;
myLibraryInfoData.hFileMappingView = hListLibraryPtr->hFileMappingView;
WideCharToMultiByte(CP_ACP, NULL, hListLibraryPtr->szLibraryName, -1, &myLibraryInfoData.szLibraryName[0], sizeof myLibraryInfoData.szLibraryName, NULL, NULL);
WideCharToMultiByte(CP_ACP, NULL, hListLibraryPtr->szLibraryPath, -1, &myLibraryInfoData.szLibraryPath[0], sizeof myLibraryInfoData.szLibraryPath, NULL, NULL);
myEnumCallBack((void*)&myLibraryInfoData);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
EnumCallBack = NULL;
}
}
hListLibraryPtr = (PLIBRARY_ITEM_DATAW)((ULONG_PTR)hListLibraryPtr + sizeof LIBRARY_ITEM_DATAW);
}
}
}
// TitanEngine.Process.functions:
__declspec(dllexport) long TITCALL GetActiveProcessId(char* szImageName)
{
wchar_t uniImageName[MAX_PATH] = {};
if(szImageName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szImageName, lstrlenA(szImageName)+1, uniImageName, sizeof(uniImageName)/(sizeof(uniImageName[0])));
return(GetActiveProcessIdW(uniImageName));
}
else
{
return(NULL);
}
}
__declspec(dllexport) long TITCALL GetActiveProcessIdW(wchar_t* szImageName)
{
int i;
wchar_t* szTranslatedProcName;
DWORD bProcessId[1024] = {};
wchar_t szProcessPath[1024] = {};
DWORD pProcessIdCount = NULL;
HANDLE hProcess;
if(EnumProcesses(bProcessId, sizeof bProcessId, &pProcessIdCount))
{
for(i = 0; i < (int)pProcessIdCount; i++)
{
if(bProcessId[i] != NULL)
{
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, false, bProcessId[i]);
if(hProcess != NULL)
{
if(GetProcessImageFileNameW(hProcess, szProcessPath, 1024) > NULL)
{
szTranslatedProcName = (wchar_t*)TranslateNativeNameW(szProcessPath);
lstrcpyW(szProcessPath, szTranslatedProcName);
VirtualFree((void*)szTranslatedProcName, NULL, MEM_RELEASE);
EngineCloseHandle(hProcess);
if(lstrcmpiW(szProcessPath, szImageName) == NULL)
{
return(bProcessId[i]);
}
else if(lstrcmpiW(EngineExtractFileNameW(szProcessPath), szImageName) == NULL)
{
return(bProcessId[i]);
}
}
else
{
EngineCloseHandle(hProcess);
}
}
}
}
}
return(NULL);
}
__declspec(dllexport) void TITCALL EnumProcessesWithLibrary(char* szLibraryName, void* EnumFunction)
{
int i;
int j;
typedef void(TITCALL *fEnumFunction)(DWORD ProcessId, HMODULE ModuleBaseAddress);
fEnumFunction myEnumFunction = (fEnumFunction)EnumFunction;
HMODULE EnumeratedModules[1024] = {};
DWORD bProcessId[1024] = {};
char szModuleName[1024] = {};
DWORD pProcessIdCount = NULL;
DWORD pModuleCount;
HANDLE hProcess;
if(EnumFunction != NULL)
{
if(EnumProcesses(bProcessId, sizeof bProcessId, &pProcessIdCount))
{
for(i = 0; i < (int)pProcessIdCount; i++)
{
if(bProcessId[i] != NULL)
{
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, false, bProcessId[i]);
if(hProcess != NULL)
{
RtlZeroMemory(&EnumeratedModules[0], sizeof EnumeratedModules);
if(EnumProcessModules(hProcess, (HMODULE*)EnumeratedModules, sizeof EnumeratedModules, &pModuleCount))
{
for(j = 0; j < (int)pModuleCount; j++)
{
if(EnumeratedModules[j] != NULL)
{
if(GetModuleBaseNameA(hProcess, EnumeratedModules[j], szModuleName, 1024) > NULL)
{
if(lstrcmpiA(szModuleName, szLibraryName) == NULL)
{
__try
{
myEnumFunction(bProcessId[i], EnumeratedModules[j]);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
EngineCloseHandle(hProcess);
return;
}
}
}
}
}
}
EngineCloseHandle(hProcess);
}
}
}
}
}
}
// TitanEngine.TLSFixer.functions:
__declspec(dllexport) bool TITCALL TLSBreakOnCallBack(LPVOID ArrayOfCallBacks, DWORD NumberOfCallBacks, LPVOID bpxCallBack)
{
unsigned int i;
LPVOID ReadArrayOfCallBacks = ArrayOfCallBacks;
if(NumberOfCallBacks > NULL)
{
for(i = 0; i < NumberOfCallBacks; i++)
{
RtlMoveMemory(&tlsCallBackList[i], ReadArrayOfCallBacks, sizeof ULONG_PTR);
ReadArrayOfCallBacks = (LPVOID)((ULONG_PTR)ReadArrayOfCallBacks + sizeof ULONG_PTR);
}
engineTLSBreakOnCallBackAddress = (ULONG_PTR)bpxCallBack;
engineTLSBreakOnCallBack = true;
return(true);
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL TLSGrabCallBackData(char* szFileName, LPVOID ArrayOfCallBacks, LPDWORD NumberOfCallBacks)
{
wchar_t uniFileName[MAX_PATH] = {};
if(szFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
return(TLSGrabCallBackDataW(uniFileName, ArrayOfCallBacks, NumberOfCallBacks));
}
else
{
return(false);
}
}
__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;
DWORD FileSize;
HANDLE FileMap;
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))
{
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, FileHandle, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
if(!FileIs64)
{
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);
TLSDirectoryX86 = (PIMAGE_TLS_DIRECTORY32)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)TLSDirectoryAddress, true);
if(TLSDirectoryX86->AddressOfCallBacks != NULL)
{
TLSCallBackAddress = (ULONG_PTR)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)TLSDirectoryX86->AddressOfCallBacks, true);
while(memcmp((LPVOID)TLSCallBackAddress, &TLSCompareData, sizeof ULONG_PTR) != NULL)
{
RtlMoveMemory(ArrayOfCallBacks, (LPVOID)TLSCallBackAddress, sizeof ULONG_PTR);
ArrayOfCallBacks = (LPVOID)((ULONG_PTR)ArrayOfCallBacks + sizeof ULONG_PTR);
TLSCallBackAddress = TLSCallBackAddress + sizeof ULONG_PTR;
NumberOfTLSCallBacks++;
}
*NumberOfCallBacks = NumberOfTLSCallBacks;
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(true);
}
else
{
*NumberOfCallBacks = NULL;
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
else
{
*NumberOfCallBacks = NULL;
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
else
{
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);
TLSDirectoryX64 = (PIMAGE_TLS_DIRECTORY64)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)TLSDirectoryAddress, true);
if(TLSDirectoryX64->AddressOfCallBacks != NULL)
{
TLSCallBackAddress = (ULONG_PTR)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)TLSDirectoryX64->AddressOfCallBacks, true);
while(memcmp((LPVOID)TLSCallBackAddress, &TLSCompareData, sizeof ULONG_PTR) != NULL)
{
RtlMoveMemory(ArrayOfCallBacks, (LPVOID)TLSCallBackAddress, sizeof ULONG_PTR);
ArrayOfCallBacks = (LPVOID)((ULONG_PTR)ArrayOfCallBacks + sizeof ULONG_PTR);
TLSCallBackAddress = TLSCallBackAddress + sizeof ULONG_PTR;
NumberOfTLSCallBacks++;
}
*NumberOfCallBacks = NumberOfTLSCallBacks;
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(true);
}
else
{
*NumberOfCallBacks = NULL;
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
else
{
*NumberOfCallBacks = NULL;
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
}
else
{
*NumberOfCallBacks = NULL;
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
return(false);
}
__declspec(dllexport) bool TITCALL TLSBreakOnCallBackEx(char* szFileName, LPVOID bpxCallBack)
{
wchar_t uniFileName[MAX_PATH] = {};
if(szFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
return(TLSBreakOnCallBackExW(uniFileName, bpxCallBack));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL TLSBreakOnCallBackExW(wchar_t* szFileName, LPVOID bpxCallBack)
{
ULONG_PTR TlsArrayOfCallBacks[100];
DWORD TlsNumberOfCallBacks;
RtlZeroMemory(&TlsArrayOfCallBacks, 100 * sizeof ULONG_PTR);
if(szFileName != NULL)
{
if(TLSGrabCallBackDataW(szFileName, &TlsArrayOfCallBacks, &TlsNumberOfCallBacks))
{
TLSBreakOnCallBack(&TlsArrayOfCallBacks, TlsNumberOfCallBacks, bpxCallBack);
return(true);
}
else
{
return(false);
}
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL TLSRemoveCallback(char* szFileName)
{
wchar_t uniFileName[MAX_PATH] = {};
if(szFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
return(TLSRemoveCallbackW(uniFileName));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL TLSRemoveCallbackW(wchar_t* szFileName)
{
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
HANDLE FileHandle;
DWORD FileSize;
HANDLE FileMap;
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))
{
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, FileHandle, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
if(!FileIs64)
{
if(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress != NULL)
{
__try
{
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);
if(TLSDirectoryX86->AddressOfCallBacks != NULL)
{
TLSDirectoryX86->AddressOfCallBacks = NULL;
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(true);
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
else
{
if(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress != NULL)
{
__try
{
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);
if(TLSDirectoryX64->AddressOfCallBacks != NULL)
{
TLSDirectoryX64->AddressOfCallBacks = NULL;
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(true);
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
return(false);
}
__declspec(dllexport) bool TITCALL TLSRemoveTable(char* szFileName)
{
wchar_t uniFileName[MAX_PATH] = {};
if(szFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
return(TLSRemoveTableW(uniFileName));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL TLSRemoveTableW(wchar_t* szFileName)
{
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
HANDLE FileHandle;
DWORD FileSize;
HANDLE FileMap;
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))
{
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, FileHandle, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
if(!FileIs64)
{
if(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress != NULL)
{
__try
{
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);
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress = NULL;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size = NULL;
RtlZeroMemory(TLSDirectoryX86, sizeof IMAGE_TLS_DIRECTORY32);
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(true);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
else
{
if(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress != NULL)
{
__try
{
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);
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress = NULL;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size = NULL;
RtlZeroMemory(TLSDirectoryX64, sizeof IMAGE_TLS_DIRECTORY64);
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(true);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
return(false);
}
__declspec(dllexport) bool TITCALL TLSBackupData(char* szFileName)
{
wchar_t uniFileName[MAX_PATH] = {};
if(szFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
return(TLSBackupDataW(uniFileName));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL TLSBackupDataW(wchar_t* szFileName)
{
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
HANDLE FileHandle;
DWORD FileSize;
HANDLE FileMap;
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))
{
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, FileHandle, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
if(!FileIs64)
{
if(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress != NULL)
{
__try
{
engineBackupTLSx64 = false;
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);
TLSDirectoryX86 = (PIMAGE_TLS_DIRECTORY32)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)TLSDirectoryAddress, true);
RtlMoveMemory(&engineBackupTLSDataX86, (LPVOID)TLSDirectoryX86, sizeof IMAGE_TLS_DIRECTORY32);
if(TLSDirectoryX86->AddressOfCallBacks != NULL)
{
TLSCallBackAddress = (ULONG_PTR)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)TLSDirectoryX86->AddressOfCallBacks, true);
while(memcmp((LPVOID)TLSCallBackAddress, &TLSCompareData, sizeof ULONG_PTR) != NULL)
{
RtlMoveMemory(ArrayOfCallBacks, (LPVOID)TLSCallBackAddress, sizeof ULONG_PTR);
ArrayOfCallBacks = (LPVOID)((ULONG_PTR)ArrayOfCallBacks + sizeof ULONG_PTR);
TLSCallBackAddress = TLSCallBackAddress + sizeof ULONG_PTR;
NumberOfTLSCallBacks++;
}
*NumberOfCallBacks = NumberOfTLSCallBacks;
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(true);
}
else
{
*NumberOfCallBacks = NULL;
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
*NumberOfCallBacks = NULL;
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
else
{
*NumberOfCallBacks = NULL;
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
else
{
if(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress != NULL)
{
__try
{
engineBackupTLSx64 = true;
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);
TLSDirectoryX64 = (PIMAGE_TLS_DIRECTORY64)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)TLSDirectoryAddress, true);
RtlMoveMemory(&engineBackupTLSDataX64, (LPVOID)TLSDirectoryX64, sizeof IMAGE_TLS_DIRECTORY64);
if(TLSDirectoryX64->AddressOfCallBacks != NULL)
{
TLSCallBackAddress = (ULONG_PTR)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)TLSDirectoryX64->AddressOfCallBacks, true);
while(memcmp((LPVOID)TLSCallBackAddress, &TLSCompareData, sizeof ULONG_PTR) != NULL)
{
RtlMoveMemory(ArrayOfCallBacks, (LPVOID)TLSCallBackAddress, sizeof ULONG_PTR);
ArrayOfCallBacks = (LPVOID)((ULONG_PTR)ArrayOfCallBacks + sizeof ULONG_PTR);
TLSCallBackAddress = TLSCallBackAddress + sizeof ULONG_PTR;
NumberOfTLSCallBacks++;
}
*NumberOfCallBacks = NumberOfTLSCallBacks;
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(true);
}
else
{
*NumberOfCallBacks = NULL;
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
*NumberOfCallBacks = NULL;
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
else
{
*NumberOfCallBacks = NULL;
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
}
else
{
*NumberOfCallBacks = NULL;
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
return(false);
}
__declspec(dllexport) bool TITCALL TLSRestoreData()
{
ULONG_PTR ueNumberOfBytesRead = NULL;
if(dbgProcessInformation.hProcess != NULL && engineBackupTLSAddress != NULL)
{
if(engineBackupTLSx64)
{
if(WriteProcessMemory(dbgProcessInformation.hProcess, (LPVOID)(engineBackupTLSAddress + GetDebuggedFileBaseAddress()), &engineBackupTLSDataX64, sizeof IMAGE_TLS_DIRECTORY64, &ueNumberOfBytesRead))
{
if(engineBackupTLSDataX64.AddressOfCallBacks != NULL && engineBackupNumberOfCallBacks != NULL)
{
if(WriteProcessMemory(dbgProcessInformation.hProcess, (LPVOID)(engineBackupTLSDataX64.AddressOfCallBacks + GetDebuggedFileBaseAddress()), engineBackupArrayOfCallBacks, sizeof IMAGE_TLS_DIRECTORY64, &ueNumberOfBytesRead))
{
engineBackupTLSAddress = NULL;
return(true);
}
}
else
{
engineBackupTLSAddress = NULL;
return(true);
}
}
}
else
{
if(WriteProcessMemory(dbgProcessInformation.hProcess, (LPVOID)(engineBackupTLSAddress + GetDebuggedFileBaseAddress()), &engineBackupTLSDataX86, sizeof IMAGE_TLS_DIRECTORY32, &ueNumberOfBytesRead))
{
if(engineBackupTLSDataX86.AddressOfCallBacks != NULL && engineBackupNumberOfCallBacks != NULL)
{
if(WriteProcessMemory(dbgProcessInformation.hProcess, (LPVOID)(engineBackupTLSDataX86.AddressOfCallBacks + GetDebuggedFileBaseAddress()), engineBackupArrayOfCallBacks, sizeof IMAGE_TLS_DIRECTORY32, &ueNumberOfBytesRead))
{
engineBackupTLSAddress = NULL;
return(true);
}
}
else
{
engineBackupTLSAddress = NULL;
return(true);
}
}
}
}
return(false);
}
__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)
{
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, NULL, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
return(false);
}
if(!FileIs64)
{
__try
{
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress = (DWORD)StorePlaceRVA;
PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size = sizeof IMAGE_TLS_DIRECTORY32;
TLSDirectoryX86 = (PIMAGE_TLS_DIRECTORY32)StorePlace;
TLSDirectoryX86->StartAddressOfRawData = (DWORD)TLSWriteData;
TLSDirectoryX86->EndAddressOfRawData = (DWORD)TLSWriteData + 0x10;
TLSDirectoryX86->AddressOfIndex = (DWORD)TLSWriteData + 0x14;
TLSDirectoryX86->AddressOfCallBacks = (DWORD)TLSWriteData + sizeof IMAGE_TLS_DIRECTORY32 + 8;
RtlMoveMemory((LPVOID)(StorePlace + sizeof IMAGE_TLS_DIRECTORY32 + 8), ArrayOfCallBacks, NumberOfCallBacks * 4);
return(true);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return(false);
}
}
else
{
__try
{
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress = (DWORD)StorePlaceRVA;
PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size = sizeof IMAGE_TLS_DIRECTORY64;
TLSDirectoryX64 = (PIMAGE_TLS_DIRECTORY64)StorePlace;
TLSDirectoryX64->StartAddressOfRawData = TLSWriteData;
TLSDirectoryX64->EndAddressOfRawData = TLSWriteData + 0x20;
TLSDirectoryX64->AddressOfIndex = TLSWriteData + 0x28;
TLSDirectoryX64->AddressOfCallBacks = TLSWriteData + sizeof IMAGE_TLS_DIRECTORY64 + 12;
RtlMoveMemory((LPVOID)(StorePlace + sizeof IMAGE_TLS_DIRECTORY64 + 12), ArrayOfCallBacks, NumberOfCallBacks * 8);
return(true);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return(false);
}
}
}
else
{
return(false);
}
}
return(false);
}
__declspec(dllexport) bool TITCALL TLSBuildNewTableEx(char* szFileName, char* szSectionName, LPVOID ArrayOfCallBacks, DWORD NumberOfCallBacks)
{
wchar_t uniFileName[MAX_PATH] = {};
if(szFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
return(TLSBuildNewTableExW(uniFileName, szSectionName, ArrayOfCallBacks, NumberOfCallBacks));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL TLSBuildNewTableExW(wchar_t* szFileName, char* szSectionName, LPVOID ArrayOfCallBacks, DWORD NumberOfCallBacks)
{
HANDLE FileHandle;
DWORD FileSize;
HANDLE FileMap;
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))
{
NewSectionFO = (DWORD)ConvertVAtoFileOffset(FileMapVA, NewSectionVO + tlsImageBase, true);
ReturnValue = TLSBuildNewTable(FileMapVA, NewSectionFO, NewSectionVO, ArrayOfCallBacks, NumberOfCallBacks);
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
if(ReturnValue)
{
return(true);
}
else
{
return(false);
}
}
else
{
return(false);
}
}
// TitanEngine.TranslateName.functions:
__declspec(dllexport) void* TITCALL TranslateNativeName(char* szNativeName)
{
LPVOID TranslatedName = VirtualAlloc(NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE);
char szDeviceName[3] = "A:";
char szDeviceCOMName[5] = "COM0";
int CurrentDeviceLen;
while(szDeviceName[0] <= 0x5A)
{
RtlZeroMemory(TranslatedName, 0x1000);
if(QueryDosDeviceA(szDeviceName, (LPSTR)TranslatedName, 0x1000) > NULL)
{
CurrentDeviceLen = lstrlenA((LPSTR)TranslatedName);
lstrcatA((LPSTR)TranslatedName, (LPCSTR)(szNativeName + CurrentDeviceLen));
if(lstrcmpiA((LPCSTR)TranslatedName, szNativeName) == NULL)
{
RtlZeroMemory(TranslatedName, 0x1000);
lstrcatA((LPSTR)TranslatedName, szDeviceName);
lstrcatA((LPSTR)TranslatedName, (LPCSTR)(szNativeName + CurrentDeviceLen));
return(TranslatedName);
}
}
szDeviceName[0]++;
}
while(szDeviceCOMName[3] <= 0x39)
{
RtlZeroMemory(TranslatedName, 0x1000);
if(QueryDosDeviceA(szDeviceCOMName, (LPSTR)TranslatedName, 0x1000) > NULL)
{
CurrentDeviceLen = lstrlenA((LPSTR)TranslatedName);
lstrcatA((LPSTR)TranslatedName, (LPCSTR)(szNativeName + CurrentDeviceLen));
if(lstrcmpiA((LPCSTR)TranslatedName, szNativeName) == NULL)
{
RtlZeroMemory(TranslatedName, 0x1000);
lstrcatA((LPSTR)TranslatedName, szDeviceCOMName);
lstrcatA((LPSTR)TranslatedName, (LPCSTR)(szNativeName + CurrentDeviceLen));
return(TranslatedName);
}
}
szDeviceCOMName[3]++;
}
VirtualFree(TranslatedName, NULL, MEM_RELEASE);
return(NULL);
}
__declspec(dllexport) void* TITCALL TranslateNativeNameW(wchar_t* szNativeName)
{
LPVOID TranslatedName = VirtualAlloc(NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE);
wchar_t szDeviceName[3] = L"A:";
wchar_t szDeviceCOMName[5] = L"COM0";
int CurrentDeviceLen;
while(szDeviceName[0] <= 0x5A)
{
RtlZeroMemory(TranslatedName, 0x1000);
if(QueryDosDeviceW(szDeviceName, (LPWSTR)TranslatedName, MAX_PATH * 2) > NULL)
{
CurrentDeviceLen = lstrlenW((LPWSTR)TranslatedName);
lstrcatW((LPWSTR)TranslatedName, (LPCWSTR)(szNativeName + CurrentDeviceLen));
if(lstrcmpiW((LPCWSTR)TranslatedName, szNativeName) == NULL)
{
RtlZeroMemory(TranslatedName, 0x1000);
lstrcatW((LPWSTR)TranslatedName, szDeviceName);
lstrcatW((LPWSTR)TranslatedName, (LPWSTR)(szNativeName + CurrentDeviceLen));
return(TranslatedName);
}
}
szDeviceName[0]++;
}
while(szDeviceCOMName[3] <= 0x39)
{
RtlZeroMemory(TranslatedName, 0x1000);
if(QueryDosDeviceW(szDeviceCOMName, (LPWSTR)TranslatedName, MAX_PATH * 2) > NULL)
{
CurrentDeviceLen = lstrlenW((LPWSTR)TranslatedName);
lstrcatW((LPWSTR)TranslatedName, (LPCWSTR)(szNativeName + CurrentDeviceLen));
if(lstrcmpiW((LPCWSTR)TranslatedName, szNativeName) == NULL)
{
RtlZeroMemory(TranslatedName, 0x1000);
lstrcatW((LPWSTR)TranslatedName, szDeviceCOMName);
lstrcatW((LPWSTR)TranslatedName, (LPWSTR)(szNativeName + CurrentDeviceLen));
return(TranslatedName);
}
}
szDeviceCOMName[3]++;
}
VirtualFree(TranslatedName, NULL, MEM_RELEASE);
return(NULL);
}
// TitanEngine.Handler.functions:
__declspec(dllexport) long TITCALL HandlerGetActiveHandleCount(DWORD ProcessId)
{
int HandleCount = NULL;
LPVOID QuerySystemBuffer;
ULONG QuerySystemBufferSize = 0x2000;
ULONG RequiredSize = NULL;
ULONG TotalHandleCount = NULL;
#if !defined(_WIN64)
typedef NTSTATUS(WINAPI *fZwQuerySystemInformation)(DWORD fInfoType, LPVOID fBuffer, ULONG fBufferSize, PULONG fRequiredSize);
typedef NTSTATUS(WINAPI *fZwQueryObject)(HANDLE hObject, DWORD fInfoType, LPVOID fBuffer, ULONG fBufferSize, PULONG fRequiredSize);
#else
typedef NTSTATUS(__fastcall *fZwQuerySystemInformation)(DWORD fInfoType, LPVOID fBuffer, ULONG fBufferSize, PULONG fRequiredSize);
typedef NTSTATUS(__fastcall *fZwQueryObject)(HANDLE hObject, DWORD fInfoType, LPVOID fBuffer, ULONG fBufferSize, PULONG fRequiredSize);
#endif
LPVOID ZwQuerySystemInformation = (LPVOID)GetProcAddress(GetModuleHandleA("ntdll.dll"),"ZwQuerySystemInformation");
LPVOID ZwQueryObject = (LPVOID)GetProcAddress(GetModuleHandleA("ntdll.dll"),"ZwQueryObject");
fZwQuerySystemInformation cZwQuerySystemInformation = (fZwQuerySystemInformation)(ZwQuerySystemInformation);
fZwQueryObject cZwQueryObject = (fZwQueryObject)(ZwQueryObject);
PNTDLL_QUERY_HANDLE_INFO HandleInfo;
if(ZwQuerySystemInformation != NULL && ZwQueryObject != NULL)
{
QuerySystemBuffer = VirtualAlloc(NULL, QuerySystemBufferSize, MEM_COMMIT, PAGE_READWRITE);
while(cZwQuerySystemInformation(NTDLL_SystemHandleInfo, QuerySystemBuffer, QuerySystemBufferSize, &RequiredSize) == (NTSTATUS)0xC0000004L)
{
QuerySystemBufferSize = RequiredSize;
VirtualFree(QuerySystemBuffer, NULL, MEM_RELEASE);
QuerySystemBuffer = VirtualAlloc(NULL, QuerySystemBufferSize, MEM_COMMIT, PAGE_READWRITE);
}
RtlMoveMemory(&TotalHandleCount, QuerySystemBuffer, sizeof ULONG);
QuerySystemBuffer = (LPVOID)((ULONG_PTR)QuerySystemBuffer + 4);
HandleInfo = (PNTDLL_QUERY_HANDLE_INFO)QuerySystemBuffer;
while(TotalHandleCount > NULL)
{
if(HandleInfo->ProcessId == ProcessId)
{
HandleCount++;
}
HandleInfo = (PNTDLL_QUERY_HANDLE_INFO)((ULONG_PTR)HandleInfo + sizeof NTDLL_QUERY_HANDLE_INFO);
TotalHandleCount--;
}
VirtualFree(QuerySystemBuffer, NULL, MEM_RELEASE);
return(HandleCount);
}
return(NULL);
}
__declspec(dllexport) bool TITCALL HandlerIsHandleOpen(DWORD ProcessId, HANDLE hHandle)
{
bool HandleActive = false;
LPVOID QuerySystemBuffer;
ULONG QuerySystemBufferSize = 0x2000;
ULONG RequiredSize = NULL;
ULONG TotalHandleCount = NULL;
#if !defined(_WIN64)
typedef NTSTATUS(WINAPI *fZwQuerySystemInformation)(DWORD fInfoType, LPVOID fBuffer, ULONG fBufferSize, PULONG fRequiredSize);
#else
typedef NTSTATUS(__fastcall *fZwQuerySystemInformation)(DWORD fInfoType, LPVOID fBuffer, ULONG fBufferSize, PULONG fRequiredSize);
#endif
LPVOID ZwQuerySystemInformation = (LPVOID)GetProcAddress(GetModuleHandleA("ntdll.dll"),"ZwQuerySystemInformation");
fZwQuerySystemInformation cZwQuerySystemInformation = (fZwQuerySystemInformation)(ZwQuerySystemInformation);
PNTDLL_QUERY_HANDLE_INFO HandleInfo;
if(ZwQuerySystemInformation != NULL)
{
QuerySystemBuffer = VirtualAlloc(NULL, QuerySystemBufferSize, MEM_COMMIT, PAGE_READWRITE);
while(cZwQuerySystemInformation(NTDLL_SystemHandleInfo, QuerySystemBuffer, QuerySystemBufferSize, &RequiredSize) == (NTSTATUS)0xC0000004L)
{
QuerySystemBufferSize = RequiredSize;
VirtualFree(QuerySystemBuffer, NULL, MEM_RELEASE);
QuerySystemBuffer = VirtualAlloc(NULL, QuerySystemBufferSize, MEM_COMMIT, PAGE_READWRITE);
}
RtlMoveMemory(&TotalHandleCount, QuerySystemBuffer, sizeof ULONG);
QuerySystemBuffer = (LPVOID)((ULONG_PTR)QuerySystemBuffer + 4);
HandleInfo = (PNTDLL_QUERY_HANDLE_INFO)QuerySystemBuffer;
while(TotalHandleCount > NULL)
{
if(HandleInfo->ProcessId == ProcessId && (HANDLE)HandleInfo->hHandle == hHandle)
{
HandleActive = true;
break;
}
HandleInfo = (PNTDLL_QUERY_HANDLE_INFO)((ULONG_PTR)HandleInfo + sizeof NTDLL_QUERY_HANDLE_INFO);
TotalHandleCount--;
}
VirtualFree(QuerySystemBuffer, NULL, MEM_RELEASE);
if(HandleActive)
{
return(true);
}
}
return(false);
}
__declspec(dllexport) void* TITCALL HandlerGetHandleName(HANDLE hProcess, DWORD ProcessId, HANDLE hHandle, bool TranslateName)
{
bool NameFound = false;
HANDLE myHandle = NULL;
LPVOID QuerySystemBuffer;
ULONG QuerySystemBufferSize = 0x2000;
ULONG RequiredSize = NULL;
ULONG TotalHandleCount = NULL;
#if !defined(_WIN64)
typedef NTSTATUS(WINAPI *fZwQuerySystemInformation)(DWORD fInfoType, LPVOID fBuffer, ULONG fBufferSize, PULONG fRequiredSize);
typedef NTSTATUS(WINAPI *fZwQueryObject)(HANDLE hObject, DWORD fInfoType, LPVOID fBuffer, ULONG fBufferSize, PULONG fRequiredSize);
#else
typedef NTSTATUS(__fastcall *fZwQuerySystemInformation)(DWORD fInfoType, LPVOID fBuffer, ULONG fBufferSize, PULONG fRequiredSize);
typedef NTSTATUS(__fastcall *fZwQueryObject)(HANDLE hObject, DWORD fInfoType, LPVOID fBuffer, ULONG fBufferSize, PULONG fRequiredSize);
#endif
LPVOID ZwQuerySystemInformation = (LPVOID)GetProcAddress(GetModuleHandleA("ntdll.dll"),"ZwQuerySystemInformation");
LPVOID ZwQueryObject = (LPVOID)GetProcAddress(GetModuleHandleA("ntdll.dll"),"ZwQueryObject");
fZwQuerySystemInformation cZwQuerySystemInformation = (fZwQuerySystemInformation)(ZwQuerySystemInformation);
fZwQueryObject cZwQueryObject = (fZwQueryObject)(ZwQueryObject);
PNTDLL_QUERY_HANDLE_INFO HandleInfo;
PUBLIC_OBJECT_BASIC_INFORMATION ObjectBasicInfo;
LPVOID ObjectNameInfo = VirtualAlloc(NULL, 0x2000, MEM_COMMIT, PAGE_READWRITE);
PPUBLIC_OBJECT_NAME_INFORMATION pObjectNameInfo = (PPUBLIC_OBJECT_NAME_INFORMATION)ObjectNameInfo;
LPVOID HandleFullName = VirtualAlloc(NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE);
LPVOID tmpHandleFullName = NULL;
if(ZwQuerySystemInformation != NULL && ZwQueryObject != NULL)
{
QuerySystemBuffer = VirtualAlloc(NULL, QuerySystemBufferSize, MEM_COMMIT, PAGE_READWRITE);
while(cZwQuerySystemInformation(NTDLL_SystemHandleInfo, QuerySystemBuffer, QuerySystemBufferSize, &RequiredSize) == (NTSTATUS)0xC0000004L)
{
QuerySystemBufferSize = RequiredSize;
VirtualFree(QuerySystemBuffer, NULL, MEM_RELEASE);
QuerySystemBuffer = VirtualAlloc(NULL, QuerySystemBufferSize, MEM_COMMIT, PAGE_READWRITE);
}
RtlMoveMemory(&TotalHandleCount, QuerySystemBuffer, sizeof ULONG);
QuerySystemBuffer = (LPVOID)((ULONG_PTR)QuerySystemBuffer + 4);
HandleInfo = (PNTDLL_QUERY_HANDLE_INFO)QuerySystemBuffer;
while(TotalHandleCount > NULL)
{
if(HandleInfo->ProcessId == ProcessId && (HANDLE)HandleInfo->hHandle == hHandle)
{
//if(!(HandleInfo->GrantedAccess & SYNCHRONIZE) || ((HandleInfo->GrantedAccess & SYNCHRONIZE) && ((WORD)HandleInfo->GrantedAccess != 0x19F9))){// && (WORD)HandleInfo->GrantedAccess != 0x89))){
if(HandleInfo->GrantedAccess != 0x0012019F)
{
if(DuplicateHandle(hProcess, hHandle, GetCurrentProcess(), &myHandle, NULL, false, DUPLICATE_SAME_ACCESS))
{
RtlZeroMemory(&ObjectBasicInfo, sizeof PUBLIC_OBJECT_BASIC_INFORMATION);
cZwQueryObject(myHandle, ObjectBasicInformation, &ObjectBasicInfo, sizeof PUBLIC_OBJECT_BASIC_INFORMATION, &RequiredSize);
cZwQueryObject(myHandle, ObjectNameInformation, ObjectNameInfo, 8, &RequiredSize);
cZwQueryObject(myHandle, ObjectNameInformation, ObjectNameInfo, RequiredSize, &RequiredSize);
RtlZeroMemory(HandleFullName, 0x1000);
if(pObjectNameInfo->Name.Length != NULL)
{
WideCharToMultiByte(CP_ACP, NULL, (LPCWSTR)pObjectNameInfo->Name.Buffer, -1, (LPSTR)HandleFullName, 0x1000, NULL, NULL);
NameFound = true;
if(TranslateName)
{
tmpHandleFullName = TranslateNativeName((char*)HandleFullName);
if(tmpHandleFullName != NULL)
{
VirtualFree(HandleFullName, NULL, MEM_RELEASE);
HandleFullName = tmpHandleFullName;
}
}
}
EngineCloseHandle(myHandle);
break;
}
}
}
HandleInfo = (PNTDLL_QUERY_HANDLE_INFO)((ULONG_PTR)HandleInfo + sizeof NTDLL_QUERY_HANDLE_INFO);
TotalHandleCount--;
}
VirtualFree(ObjectNameInfo, NULL, MEM_RELEASE);
VirtualFree(QuerySystemBuffer, NULL, MEM_RELEASE);
if(!NameFound)
{
VirtualFree(HandleFullName, NULL, MEM_RELEASE);
return(NULL);
}
else
{
return(HandleFullName);
}
}
VirtualFree(HandleFullName, NULL, MEM_RELEASE);
VirtualFree(ObjectNameInfo, NULL, MEM_RELEASE);
return(NULL);
}
__declspec(dllexport) void* TITCALL HandlerGetHandleNameW(HANDLE hProcess, DWORD ProcessId, HANDLE hHandle, bool TranslateName)
{
bool NameFound = false;
HANDLE myHandle = NULL;
LPVOID QuerySystemBuffer;
ULONG QuerySystemBufferSize = 0x2000;
ULONG RequiredSize = NULL;
ULONG TotalHandleCount = NULL;
#if !defined(_WIN64)
typedef NTSTATUS(WINAPI *fZwQuerySystemInformation)(DWORD fInfoType, LPVOID fBuffer, ULONG fBufferSize, PULONG fRequiredSize);
typedef NTSTATUS(WINAPI *fZwQueryObject)(HANDLE hObject, DWORD fInfoType, LPVOID fBuffer, ULONG fBufferSize, PULONG fRequiredSize);
#else
typedef NTSTATUS(__fastcall *fZwQuerySystemInformation)(DWORD fInfoType, LPVOID fBuffer, ULONG fBufferSize, PULONG fRequiredSize);
typedef NTSTATUS(__fastcall *fZwQueryObject)(HANDLE hObject, DWORD fInfoType, LPVOID fBuffer, ULONG fBufferSize, PULONG fRequiredSize);
#endif
LPVOID ZwQuerySystemInformation = (LPVOID)GetProcAddress(GetModuleHandleA("ntdll.dll"),"ZwQuerySystemInformation");
LPVOID ZwQueryObject = (LPVOID)GetProcAddress(GetModuleHandleA("ntdll.dll"),"ZwQueryObject");
fZwQuerySystemInformation cZwQuerySystemInformation = (fZwQuerySystemInformation)(ZwQuerySystemInformation);
fZwQueryObject cZwQueryObject = (fZwQueryObject)(ZwQueryObject);
PNTDLL_QUERY_HANDLE_INFO HandleInfo;
PUBLIC_OBJECT_BASIC_INFORMATION ObjectBasicInfo;
LPVOID ObjectNameInfo = VirtualAlloc(NULL, 0x2000, MEM_COMMIT, PAGE_READWRITE);
PPUBLIC_OBJECT_NAME_INFORMATION pObjectNameInfo = (PPUBLIC_OBJECT_NAME_INFORMATION)ObjectNameInfo;
LPVOID HandleFullName = VirtualAlloc(NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE);
LPVOID tmpHandleFullName = NULL;
if(ZwQuerySystemInformation != NULL && ZwQueryObject != NULL)
{
QuerySystemBuffer = VirtualAlloc(NULL, QuerySystemBufferSize, MEM_COMMIT, PAGE_READWRITE);
while(cZwQuerySystemInformation(NTDLL_SystemHandleInfo, QuerySystemBuffer, QuerySystemBufferSize, &RequiredSize) == (NTSTATUS)0xC0000004L)
{
QuerySystemBufferSize = RequiredSize;
VirtualFree(QuerySystemBuffer, NULL, MEM_RELEASE);
QuerySystemBuffer = VirtualAlloc(NULL, QuerySystemBufferSize, MEM_COMMIT, PAGE_READWRITE);
}
RtlMoveMemory(&TotalHandleCount, QuerySystemBuffer, sizeof ULONG);
QuerySystemBuffer = (LPVOID)((ULONG_PTR)QuerySystemBuffer + 4);
HandleInfo = (PNTDLL_QUERY_HANDLE_INFO)QuerySystemBuffer;
while(TotalHandleCount > NULL)
{
if(HandleInfo->ProcessId == ProcessId && (HANDLE)HandleInfo->hHandle == hHandle)
{
//if(!(HandleInfo->GrantedAccess & SYNCHRONIZE) || ((HandleInfo->GrantedAccess & SYNCHRONIZE) && ((WORD)HandleInfo->GrantedAccess != 0x19F9))){// && (WORD)HandleInfo->GrantedAccess != 0x89))){
if(HandleInfo->GrantedAccess != 0x0012019F)
{
if(DuplicateHandle(hProcess, hHandle, GetCurrentProcess(), &myHandle, NULL, false, DUPLICATE_SAME_ACCESS))
{
RtlZeroMemory(&ObjectBasicInfo, sizeof PUBLIC_OBJECT_BASIC_INFORMATION);
cZwQueryObject(myHandle, ObjectBasicInformation, &ObjectBasicInfo, sizeof PUBLIC_OBJECT_BASIC_INFORMATION, &RequiredSize);
cZwQueryObject(myHandle, ObjectNameInformation, ObjectNameInfo, 8, &RequiredSize);
cZwQueryObject(myHandle, ObjectNameInformation, ObjectNameInfo, RequiredSize, &RequiredSize);
RtlZeroMemory(HandleFullName, 0x1000);
if(pObjectNameInfo->Name.Length != NULL)
{
//WideCharToMultiByte(CP_ACP, NULL, (LPCWSTR)pObjectNameInfo->Name.Buffer, -1, (LPSTR)HandleFullName, 0x1000, NULL, NULL);
NameFound = true;
lstrcpyW((wchar_t*)HandleFullName, (wchar_t*)pObjectNameInfo->Name.Buffer);
if(TranslateName)
{
tmpHandleFullName = TranslateNativeNameW((wchar_t*)HandleFullName);
if(tmpHandleFullName != NULL)
{
VirtualFree(HandleFullName, NULL, MEM_RELEASE);
HandleFullName = tmpHandleFullName;
}
}
}
EngineCloseHandle(myHandle);
break;
}
}
}
HandleInfo = (PNTDLL_QUERY_HANDLE_INFO)((ULONG_PTR)HandleInfo + sizeof NTDLL_QUERY_HANDLE_INFO);
TotalHandleCount--;
}
VirtualFree(ObjectNameInfo, NULL, MEM_RELEASE);
VirtualFree(QuerySystemBuffer, NULL, MEM_RELEASE);
if(!NameFound)
{
VirtualFree(HandleFullName, NULL, MEM_RELEASE);
return(NULL);
}
else
{
return(HandleFullName);
}
}
VirtualFree(HandleFullName, NULL, MEM_RELEASE);
VirtualFree(ObjectNameInfo, NULL, MEM_RELEASE);
return(NULL);
}
__declspec(dllexport) long TITCALL HandlerEnumerateOpenHandles(DWORD ProcessId, LPVOID HandleBuffer, DWORD MaxHandleCount)
{
HANDLE myHandle = NULL;
LPVOID QuerySystemBuffer;
ULONG RequiredSize = NULL;
ULONG TotalHandleCount = NULL;
unsigned int HandleCount = NULL;
ULONG QuerySystemBufferSize = 0x2000;
#if !defined(_WIN64)
typedef NTSTATUS(WINAPI *fZwQuerySystemInformation)(DWORD fInfoType, LPVOID fBuffer, ULONG fBufferSize, PULONG fRequiredSize);
#else
typedef NTSTATUS(__fastcall *fZwQuerySystemInformation)(DWORD fInfoType, LPVOID fBuffer, ULONG fBufferSize, PULONG fRequiredSize);
#endif
LPVOID ZwQuerySystemInformation = (LPVOID)GetProcAddress(GetModuleHandleA("ntdll.dll"),"ZwQuerySystemInformation");
fZwQuerySystemInformation cZwQuerySystemInformation = (fZwQuerySystemInformation)(ZwQuerySystemInformation);
PNTDLL_QUERY_HANDLE_INFO HandleInfo;
if(ZwQuerySystemInformation != NULL)
{
QuerySystemBuffer = VirtualAlloc(NULL, QuerySystemBufferSize, MEM_COMMIT, PAGE_READWRITE);
while(cZwQuerySystemInformation(NTDLL_SystemHandleInfo, QuerySystemBuffer, QuerySystemBufferSize, &RequiredSize) == (NTSTATUS)0xC0000004L)
{
QuerySystemBufferSize = RequiredSize;
VirtualFree(QuerySystemBuffer, NULL, MEM_RELEASE);
QuerySystemBuffer = VirtualAlloc(NULL, QuerySystemBufferSize, MEM_COMMIT, PAGE_READWRITE);
}
RtlMoveMemory(&TotalHandleCount, QuerySystemBuffer, sizeof ULONG);
QuerySystemBuffer = (LPVOID)((ULONG_PTR)QuerySystemBuffer + 4);
HandleInfo = (PNTDLL_QUERY_HANDLE_INFO)QuerySystemBuffer;
while(TotalHandleCount > NULL)
{
if(HandleInfo->ProcessId == ProcessId && HandleCount < MaxHandleCount)
{
myHandle = (HANDLE)HandleInfo->hHandle;
RtlMoveMemory(HandleBuffer, &myHandle, sizeof HANDLE);
HandleBuffer = (LPVOID)((ULONG_PTR)HandleBuffer + sizeof HANDLE);
HandleCount++;
}
HandleInfo = (PNTDLL_QUERY_HANDLE_INFO)((ULONG_PTR)HandleInfo + sizeof NTDLL_QUERY_HANDLE_INFO);
TotalHandleCount--;
}
VirtualFree(QuerySystemBuffer, NULL, MEM_RELEASE);
return(HandleCount);
}
return(NULL);
}
__declspec(dllexport) long long TITCALL HandlerGetHandleDetails(HANDLE hProcess, DWORD ProcessId, HANDLE hHandle, DWORD InformationReturn)
{
HANDLE myHandle = NULL;
LPVOID QuerySystemBuffer;
ULONG QuerySystemBufferSize = 0x2000;
ULONG RequiredSize = NULL;
ULONG TotalHandleCount = NULL;
#if !defined(_WIN64)
typedef NTSTATUS(WINAPI *fZwQuerySystemInformation)(DWORD fInfoType, LPVOID fBuffer, ULONG fBufferSize, PULONG fRequiredSize);
typedef NTSTATUS(WINAPI *fZwQueryObject)(HANDLE hObject, DWORD fInfoType, LPVOID fBuffer, ULONG fBufferSize, PULONG fRequiredSize);
#else
typedef NTSTATUS(__fastcall *fZwQuerySystemInformation)(DWORD fInfoType, LPVOID fBuffer, ULONG fBufferSize, PULONG fRequiredSize);
typedef NTSTATUS(__fastcall *fZwQueryObject)(HANDLE hObject, DWORD fInfoType, LPVOID fBuffer, ULONG fBufferSize, PULONG fRequiredSize);
#endif
LPVOID ZwQuerySystemInformation = (LPVOID)GetProcAddress(GetModuleHandleA("ntdll.dll"),"ZwQuerySystemInformation");
LPVOID ZwQueryObject = (LPVOID)GetProcAddress(GetModuleHandleA("ntdll.dll"),"ZwQueryObject");
fZwQuerySystemInformation cZwQuerySystemInformation = (fZwQuerySystemInformation)(ZwQuerySystemInformation);
fZwQueryObject cZwQueryObject = (fZwQueryObject)(ZwQueryObject);
PNTDLL_QUERY_HANDLE_INFO HandleInfo;
PUBLIC_OBJECT_BASIC_INFORMATION ObjectBasicInfo;
LPVOID HandleFullData = VirtualAlloc(NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE);
LPVOID HandleNameData = VirtualAlloc(NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE);
PPUBLIC_OBJECT_TYPE_INFORMATION pObjectTypeInfo = (PPUBLIC_OBJECT_TYPE_INFORMATION)HandleFullData;
bool DontFreeStringMemory = false;
ULONG_PTR ReturnData = NULL;
if(ZwQuerySystemInformation != NULL && ZwQueryObject != NULL)
{
QuerySystemBuffer = VirtualAlloc(NULL, QuerySystemBufferSize, MEM_COMMIT, PAGE_READWRITE);
while(cZwQuerySystemInformation(NTDLL_SystemHandleInfo, QuerySystemBuffer, QuerySystemBufferSize, &RequiredSize) == (NTSTATUS)0xC0000004L)
{
QuerySystemBufferSize = RequiredSize;
VirtualFree(QuerySystemBuffer, NULL, MEM_RELEASE);
QuerySystemBuffer = VirtualAlloc(NULL, QuerySystemBufferSize, MEM_COMMIT, PAGE_READWRITE);
}
RtlMoveMemory(&TotalHandleCount, QuerySystemBuffer, sizeof ULONG);
QuerySystemBuffer = (LPVOID)((ULONG_PTR)QuerySystemBuffer + 4);
HandleInfo = (PNTDLL_QUERY_HANDLE_INFO)QuerySystemBuffer;
while(TotalHandleCount > NULL)
{
if(HandleInfo->ProcessId == ProcessId && (HANDLE)HandleInfo->hHandle == hHandle)
{
if(DuplicateHandle(hProcess, hHandle, GetCurrentProcess(), &myHandle, NULL, false, DUPLICATE_SAME_ACCESS))
{
RtlZeroMemory(&ObjectBasicInfo, sizeof PUBLIC_OBJECT_BASIC_INFORMATION);
cZwQueryObject(myHandle, ObjectBasicInformation, &ObjectBasicInfo, sizeof PUBLIC_OBJECT_BASIC_INFORMATION, &RequiredSize);
if(InformationReturn == UE_OPTION_HANDLER_RETURN_HANDLECOUNT)
{
ReturnData = (ULONG_PTR)ObjectBasicInfo.HandleCount;
}
else if(InformationReturn == UE_OPTION_HANDLER_RETURN_ACCESS)
{
ReturnData = (ULONG_PTR)HandleInfo->GrantedAccess;
}
else if(InformationReturn == UE_OPTION_HANDLER_RETURN_FLAGS)
{
ReturnData = (ULONG_PTR)HandleInfo->Flags;
}
else if(InformationReturn == UE_OPTION_HANDLER_RETURN_TYPENAME)
{
//if(!(HandleInfo->GrantedAccess & SYNCHRONIZE) || ((HandleInfo->GrantedAccess & SYNCHRONIZE) && ((WORD)HandleInfo->GrantedAccess != 0x19F9))){// && (WORD)HandleInfo->GrantedAccess != 0x89))){
if(HandleInfo->GrantedAccess != 0x0012019F)
{
RtlZeroMemory(HandleFullData, 0x1000);
cZwQueryObject(myHandle, ObjectTypeInformation, HandleFullData, 8, &RequiredSize);
cZwQueryObject(myHandle, ObjectTypeInformation, HandleFullData, RequiredSize, &RequiredSize);
RtlZeroMemory(HandleNameData, 0x1000);
if(pObjectTypeInfo->TypeName.Length != NULL)
{
WideCharToMultiByte(CP_ACP, NULL, (LPCWSTR)pObjectTypeInfo->TypeName.Buffer, -1, (LPSTR)HandleNameData, 0x1000, NULL, NULL);
ReturnData = (ULONG_PTR)HandleNameData;
DontFreeStringMemory = true;
}
}
}
else if(InformationReturn == UE_OPTION_HANDLER_RETURN_TYPENAME_UNICODE)
{
//if(!(HandleInfo->GrantedAccess & SYNCHRONIZE) || ((HandleInfo->GrantedAccess & SYNCHRONIZE) && ((WORD)HandleInfo->GrantedAccess != 0x19F9))){// && (WORD)HandleInfo->GrantedAccess != 0x89))){
if(HandleInfo->GrantedAccess != 0x0012019F)
{
RtlZeroMemory(HandleFullData, 0x1000);
cZwQueryObject(myHandle, ObjectTypeInformation, HandleFullData, 8, &RequiredSize);
cZwQueryObject(myHandle, ObjectTypeInformation, HandleFullData, RequiredSize, &RequiredSize);
RtlZeroMemory(HandleNameData, 0x1000);
if(pObjectTypeInfo->TypeName.Length != NULL)
{
//WideCharToMultiByte(CP_ACP, NULL, (LPCWSTR)pObjectTypeInfo->TypeName.Buffer, -1, (LPSTR)HandleNameData, 0x1000, NULL, NULL);
lstrcpyW((wchar_t*)HandleNameData, (wchar_t*)pObjectTypeInfo->TypeName.Buffer);
ReturnData = (ULONG_PTR)HandleNameData;
DontFreeStringMemory = true;
}
}
}
EngineCloseHandle(myHandle);
break;
}
}
HandleInfo = (PNTDLL_QUERY_HANDLE_INFO)((ULONG_PTR)HandleInfo + sizeof NTDLL_QUERY_HANDLE_INFO);
TotalHandleCount--;
}
if(!DontFreeStringMemory)
{
VirtualFree(HandleNameData, NULL, MEM_RELEASE);
}
VirtualFree(HandleFullData, NULL, MEM_RELEASE);
VirtualFree(QuerySystemBuffer, NULL, MEM_RELEASE);
return(ReturnData);
}
if(!DontFreeStringMemory)
{
VirtualFree(HandleNameData, NULL, MEM_RELEASE);
}
VirtualFree(HandleFullData, NULL, MEM_RELEASE);
return(NULL);
}
__declspec(dllexport) bool TITCALL HandlerCloseRemoteHandle(HANDLE hProcess, HANDLE hHandle)
{
HANDLE myHandle;
if(hProcess != NULL)
{
DuplicateHandle(hProcess, hHandle, GetCurrentProcess(), &myHandle, NULL, false, DUPLICATE_CLOSE_SOURCE);
EngineCloseHandle(myHandle);
}
return(false);
}
__declspec(dllexport) long TITCALL HandlerEnumerateLockHandles(char* szFileOrFolderName, bool NameIsFolder, bool NameIsTranslated, LPVOID HandleDataBuffer, DWORD MaxHandleCount)
{
wchar_t uniFileOrFolderName[MAX_PATH] = {};
if(szFileOrFolderName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileOrFolderName, lstrlenA(szFileOrFolderName)+1, uniFileOrFolderName, sizeof(uniFileOrFolderName)/(sizeof(uniFileOrFolderName[0])));
return(HandlerEnumerateLockHandlesW(uniFileOrFolderName, NameIsFolder, NameIsTranslated, HandleDataBuffer, MaxHandleCount));
}
else
{
return(NULL);
}
}
__declspec(dllexport) long TITCALL HandlerEnumerateLockHandlesW(wchar_t* szFileOrFolderName, bool NameIsFolder, bool NameIsTranslated, LPVOID HandleDataBuffer, DWORD MaxHandleCount)
{
int FoundHandles = NULL;
HANDLE hProcess = NULL;
HANDLE myHandle = NULL;
HANDLE CopyHandle = NULL;
LPVOID QuerySystemBuffer;
ULONG QuerySystemBufferSize = 0x2000;
ULONG RequiredSize = NULL;
ULONG TotalHandleCount = NULL;
DWORD LastProcessId = NULL;
#if !defined(_WIN64)
typedef NTSTATUS(WINAPI *fZwQuerySystemInformation)(DWORD fInfoType, LPVOID fBuffer, ULONG fBufferSize, PULONG fRequiredSize);
typedef NTSTATUS(WINAPI *fZwQueryObject)(HANDLE hObject, DWORD fInfoType, LPVOID fBuffer, ULONG fBufferSize, PULONG fRequiredSize);
#else
typedef NTSTATUS(__fastcall *fZwQuerySystemInformation)(DWORD fInfoType, LPVOID fBuffer, ULONG fBufferSize, PULONG fRequiredSize);
typedef NTSTATUS(__fastcall *fZwQueryObject)(HANDLE hObject, DWORD fInfoType, LPVOID fBuffer, ULONG fBufferSize, PULONG fRequiredSize);
#endif
LPVOID ZwQuerySystemInformation = (LPVOID)GetProcAddress(GetModuleHandleA("ntdll.dll"),"ZwQuerySystemInformation");
LPVOID ZwQueryObject = (LPVOID)GetProcAddress(GetModuleHandleA("ntdll.dll"),"ZwQueryObject");
fZwQuerySystemInformation cZwQuerySystemInformation = (fZwQuerySystemInformation)(ZwQuerySystemInformation);
fZwQueryObject cZwQueryObject = (fZwQueryObject)(ZwQueryObject);
PNTDLL_QUERY_HANDLE_INFO HandleInfo;
PUBLIC_OBJECT_BASIC_INFORMATION ObjectBasicInfo;
LPVOID ObjectNameInfo = VirtualAlloc(NULL, 0x2000, MEM_COMMIT, PAGE_READWRITE);
PPUBLIC_OBJECT_NAME_INFORMATION pObjectNameInfo = (PPUBLIC_OBJECT_NAME_INFORMATION)ObjectNameInfo;
LPVOID HandleFullName = VirtualAlloc(NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE);
int LenFileOrFolderName = lstrlenW(szFileOrFolderName);
LPVOID tmpHandleFullName = NULL;
if(ZwQuerySystemInformation != NULL && ZwQueryObject != NULL)
{
QuerySystemBuffer = VirtualAlloc(NULL, QuerySystemBufferSize, MEM_COMMIT, PAGE_READWRITE);
while(cZwQuerySystemInformation(NTDLL_SystemHandleInfo, QuerySystemBuffer, QuerySystemBufferSize, &RequiredSize) == (NTSTATUS)0xC0000004L)
{
QuerySystemBufferSize = RequiredSize;
VirtualFree(QuerySystemBuffer, NULL, MEM_RELEASE);
QuerySystemBuffer = VirtualAlloc(NULL, QuerySystemBufferSize, MEM_COMMIT, PAGE_READWRITE);
}
RtlMoveMemory(&TotalHandleCount, QuerySystemBuffer, sizeof ULONG);
QuerySystemBuffer = (LPVOID)((ULONG_PTR)QuerySystemBuffer + 4);
HandleInfo = (PNTDLL_QUERY_HANDLE_INFO)QuerySystemBuffer;
while(TotalHandleCount > NULL)
{
if(LastProcessId != HandleInfo->ProcessId)
{
if(hProcess != NULL)
{
EngineCloseHandle(hProcess);
}
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_DUP_HANDLE, false, HandleInfo->ProcessId);
LastProcessId = HandleInfo->ProcessId;
}
if(hProcess != NULL)
{
//if(!(HandleInfo->GrantedAccess & SYNCHRONIZE) || ((HandleInfo->GrantedAccess & SYNCHRONIZE) && ((WORD)HandleInfo->GrantedAccess != 0x19F9))){// && (WORD)HandleInfo->GrantedAccess != 0x89))){
if(HandleInfo->GrantedAccess != 0x0012019F)
{
if(DuplicateHandle(hProcess, (HANDLE)HandleInfo->hHandle, GetCurrentProcess(), &myHandle, NULL, false, DUPLICATE_SAME_ACCESS))
{
RtlZeroMemory(&ObjectBasicInfo, sizeof PUBLIC_OBJECT_BASIC_INFORMATION);
cZwQueryObject(myHandle, ObjectBasicInformation, &ObjectBasicInfo, sizeof PUBLIC_OBJECT_BASIC_INFORMATION, &RequiredSize);
cZwQueryObject(myHandle, ObjectNameInformation, ObjectNameInfo, 8, &RequiredSize);
cZwQueryObject(myHandle, ObjectNameInformation, ObjectNameInfo, RequiredSize, &RequiredSize);
RtlZeroMemory(HandleFullName, 0x1000);
if(pObjectNameInfo->Name.Length != NULL)
{
//WideCharToMultiByte(CP_ACP, NULL, (LPCWSTR)pObjectNameInfo->Name.Buffer, -1, (LPSTR)HandleFullName, 0x1000, NULL, NULL);
lstrcpyW((wchar_t*)HandleFullName, (wchar_t*)pObjectNameInfo->Name.Buffer);
if(NameIsTranslated)
{
tmpHandleFullName = TranslateNativeNameW((wchar_t*)HandleFullName);
if(tmpHandleFullName != NULL)
{
VirtualFree(HandleFullName, NULL, MEM_RELEASE);
HandleFullName = tmpHandleFullName;
}
}
if(NameIsFolder)
{
if(lstrlenW((LPCWSTR)HandleFullName) > LenFileOrFolderName)
{
RtlZeroMemory((LPVOID)((ULONG_PTR)HandleFullName + LenFileOrFolderName * 2), 2);
}
}
if(lstrcmpiW((LPCWSTR)HandleFullName, szFileOrFolderName) == NULL && MaxHandleCount > NULL)
{
RtlMoveMemory(HandleDataBuffer, &HandleInfo->ProcessId, sizeof ULONG);
HandleDataBuffer = (LPVOID)((ULONG_PTR)HandleDataBuffer + sizeof ULONG);
CopyHandle = (HANDLE)HandleInfo->hHandle;
RtlMoveMemory(HandleDataBuffer, &CopyHandle, sizeof HANDLE);
HandleDataBuffer = (LPVOID)((ULONG_PTR)HandleDataBuffer + sizeof HANDLE);
FoundHandles++;
MaxHandleCount--;
}
}
EngineCloseHandle(myHandle);
}
}
}
HandleInfo = (PNTDLL_QUERY_HANDLE_INFO)((ULONG_PTR)HandleInfo + sizeof NTDLL_QUERY_HANDLE_INFO);
TotalHandleCount--;
}
VirtualFree(ObjectNameInfo, NULL, MEM_RELEASE);
VirtualFree(QuerySystemBuffer, NULL, MEM_RELEASE);
VirtualFree(HandleFullName, NULL, MEM_RELEASE);
return(FoundHandles);
}
VirtualFree(ObjectNameInfo, NULL, MEM_RELEASE);
VirtualFree(HandleFullName, NULL, MEM_RELEASE);
return(NULL);
}
__declspec(dllexport) bool TITCALL HandlerCloseAllLockHandles(char* szFileOrFolderName, bool NameIsFolder, bool NameIsTranslated)
{
wchar_t uniFileOrFolderName[MAX_PATH] = {};
if(szFileOrFolderName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileOrFolderName, lstrlenA(szFileOrFolderName)+1, uniFileOrFolderName, sizeof(uniFileOrFolderName)/(sizeof(uniFileOrFolderName[0])));
return(HandlerCloseAllLockHandlesW(uniFileOrFolderName, NameIsFolder, NameIsTranslated));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL HandlerCloseAllLockHandlesW(wchar_t* szFileOrFolderName, bool NameIsFolder, bool NameIsTranslated)
{
bool AllHandled = true;
HANDLE hProcess = NULL;
HANDLE myHandle = NULL;
HANDLE CopyHandle = NULL;
LPVOID QuerySystemBuffer;
ULONG QuerySystemBufferSize = 0x2000;
ULONG RequiredSize = NULL;
ULONG TotalHandleCount = NULL;
DWORD LastProcessId = NULL;
#if !defined(_WIN64)
typedef NTSTATUS(WINAPI *fZwQuerySystemInformation)(DWORD fInfoType, LPVOID fBuffer, ULONG fBufferSize, PULONG fRequiredSize);
typedef NTSTATUS(WINAPI *fZwQueryObject)(HANDLE hObject, DWORD fInfoType, LPVOID fBuffer, ULONG fBufferSize, PULONG fRequiredSize);
#else
typedef NTSTATUS(__fastcall *fZwQuerySystemInformation)(DWORD fInfoType, LPVOID fBuffer, ULONG fBufferSize, PULONG fRequiredSize);
typedef NTSTATUS(__fastcall *fZwQueryObject)(HANDLE hObject, DWORD fInfoType, LPVOID fBuffer, ULONG fBufferSize, PULONG fRequiredSize);
#endif
LPVOID ZwQuerySystemInformation = (LPVOID)GetProcAddress(GetModuleHandleA("ntdll.dll"),"ZwQuerySystemInformation");
LPVOID ZwQueryObject = (LPVOID)GetProcAddress(GetModuleHandleA("ntdll.dll"),"ZwQueryObject");
fZwQuerySystemInformation cZwQuerySystemInformation = (fZwQuerySystemInformation)(ZwQuerySystemInformation);
fZwQueryObject cZwQueryObject = (fZwQueryObject)(ZwQueryObject);
PNTDLL_QUERY_HANDLE_INFO HandleInfo;
PUBLIC_OBJECT_BASIC_INFORMATION ObjectBasicInfo;
LPVOID ObjectNameInfo = VirtualAlloc(NULL, 0x2000, MEM_COMMIT, PAGE_READWRITE);
PPUBLIC_OBJECT_NAME_INFORMATION pObjectNameInfo = (PPUBLIC_OBJECT_NAME_INFORMATION)ObjectNameInfo;
LPVOID HandleFullName = VirtualAlloc(NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE);
int LenFileOrFolderName = lstrlenW(szFileOrFolderName);
LPVOID tmpHandleFullName = NULL;
if(ZwQuerySystemInformation != NULL && ZwQueryObject != NULL)
{
QuerySystemBuffer = VirtualAlloc(NULL, QuerySystemBufferSize, MEM_COMMIT, PAGE_READWRITE);
while(cZwQuerySystemInformation(NTDLL_SystemHandleInfo, QuerySystemBuffer, QuerySystemBufferSize, &RequiredSize) == (NTSTATUS)0xC0000004L)
{
QuerySystemBufferSize = RequiredSize;
VirtualFree(QuerySystemBuffer, NULL, MEM_RELEASE);
QuerySystemBuffer = VirtualAlloc(NULL, QuerySystemBufferSize, MEM_COMMIT, PAGE_READWRITE);
}
RtlMoveMemory(&TotalHandleCount, QuerySystemBuffer, sizeof ULONG);
QuerySystemBuffer = (LPVOID)((ULONG_PTR)QuerySystemBuffer + 4);
HandleInfo = (PNTDLL_QUERY_HANDLE_INFO)QuerySystemBuffer;
while(TotalHandleCount > NULL)
{
if(LastProcessId != HandleInfo->ProcessId)
{
if(hProcess != NULL)
{
EngineCloseHandle(hProcess);
}
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_DUP_HANDLE, false, HandleInfo->ProcessId);
LastProcessId = HandleInfo->ProcessId;
}
if(hProcess != NULL)
{
//if(!(HandleInfo->GrantedAccess & SYNCHRONIZE) || ((HandleInfo->GrantedAccess & SYNCHRONIZE) && ((WORD)HandleInfo->GrantedAccess != 0x19F9))){// && (WORD)HandleInfo->GrantedAccess != 0x89))){
if(HandleInfo->GrantedAccess != 0x0012019F)
{
if(DuplicateHandle(hProcess, (HANDLE)HandleInfo->hHandle, GetCurrentProcess(), &myHandle, NULL, false, DUPLICATE_SAME_ACCESS))
{
RtlZeroMemory(&ObjectBasicInfo, sizeof PUBLIC_OBJECT_BASIC_INFORMATION);
cZwQueryObject(myHandle, ObjectBasicInformation, &ObjectBasicInfo, sizeof PUBLIC_OBJECT_BASIC_INFORMATION, &RequiredSize);
cZwQueryObject(myHandle, ObjectNameInformation, ObjectNameInfo, 8, &RequiredSize);
cZwQueryObject(myHandle, ObjectNameInformation, ObjectNameInfo, RequiredSize, &RequiredSize);
RtlZeroMemory(HandleFullName, 0x1000);
if(pObjectNameInfo->Name.Length != NULL)
{
//WideCharToMultiByte(CP_ACP, NULL, (LPCWSTR)pObjectNameInfo->Name.Buffer, -1, (LPSTR)HandleFullName, 0x1000, NULL, NULL);
lstrcpyW((wchar_t*)HandleFullName, (wchar_t*)pObjectNameInfo->Name.Buffer);
if(NameIsTranslated)
{
tmpHandleFullName = TranslateNativeNameW((wchar_t*)HandleFullName);
if(tmpHandleFullName != NULL)
{
VirtualFree(HandleFullName, NULL, MEM_RELEASE);
HandleFullName = tmpHandleFullName;
}
}
if(NameIsFolder)
{
if(lstrlenW((LPCWSTR)HandleFullName) > LenFileOrFolderName)
{
RtlZeroMemory((LPVOID)((ULONG_PTR)HandleFullName + LenFileOrFolderName * 2), 2);
}
}
if(lstrcmpiW((LPCWSTR)HandleFullName, szFileOrFolderName) == NULL)
{
if(!HandlerCloseRemoteHandle(hProcess, (HANDLE)HandleInfo->hHandle))
{
AllHandled = false;
}
}
}
EngineCloseHandle(myHandle);
}
}
}
HandleInfo = (PNTDLL_QUERY_HANDLE_INFO)((ULONG_PTR)HandleInfo + sizeof NTDLL_QUERY_HANDLE_INFO);
TotalHandleCount--;
}
VirtualFree(ObjectNameInfo, NULL, MEM_RELEASE);
VirtualFree(QuerySystemBuffer, NULL, MEM_RELEASE);
VirtualFree(HandleFullName, NULL, MEM_RELEASE);
if(AllHandled)
{
return(true);
}
else
{
return(false);
}
}
VirtualFree(ObjectNameInfo, NULL, MEM_RELEASE);
VirtualFree(HandleFullName, NULL, MEM_RELEASE);
return(false);
}
__declspec(dllexport) bool TITCALL HandlerIsFileLocked(char* szFileOrFolderName, bool NameIsFolder, bool NameIsTranslated)
{
wchar_t uniFileOrFolderName[MAX_PATH] = {};
if(szFileOrFolderName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileOrFolderName, lstrlenA(szFileOrFolderName)+1, uniFileOrFolderName, sizeof(uniFileOrFolderName)/(sizeof(uniFileOrFolderName[0])));
return(HandlerIsFileLockedW(uniFileOrFolderName, NameIsFolder, NameIsTranslated));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL HandlerIsFileLockedW(wchar_t* szFileOrFolderName, bool NameIsFolder, bool NameIsTranslated)
{
HANDLE hProcess = NULL;
HANDLE myHandle = NULL;
HANDLE CopyHandle = NULL;
LPVOID QuerySystemBuffer;
ULONG QuerySystemBufferSize = 0x2000;
ULONG RequiredSize = NULL;
ULONG TotalHandleCount = NULL;
DWORD LastProcessId = NULL;
#if !defined(_WIN64)
typedef NTSTATUS(WINAPI *fZwQuerySystemInformation)(DWORD fInfoType, LPVOID fBuffer, ULONG fBufferSize, PULONG fRequiredSize);
typedef NTSTATUS(WINAPI *fZwQueryObject)(HANDLE hObject, DWORD fInfoType, LPVOID fBuffer, ULONG fBufferSize, PULONG fRequiredSize);
#else
typedef NTSTATUS(__fastcall *fZwQuerySystemInformation)(DWORD fInfoType, LPVOID fBuffer, ULONG fBufferSize, PULONG fRequiredSize);
typedef NTSTATUS(__fastcall *fZwQueryObject)(HANDLE hObject, DWORD fInfoType, LPVOID fBuffer, ULONG fBufferSize, PULONG fRequiredSize);
#endif
LPVOID ZwQuerySystemInformation = (LPVOID)GetProcAddress(GetModuleHandleA("ntdll.dll"),"ZwQuerySystemInformation");
LPVOID ZwQueryObject = (LPVOID)GetProcAddress(GetModuleHandleA("ntdll.dll"),"ZwQueryObject");
fZwQuerySystemInformation cZwQuerySystemInformation = (fZwQuerySystemInformation)(ZwQuerySystemInformation);
fZwQueryObject cZwQueryObject = (fZwQueryObject)(ZwQueryObject);
PNTDLL_QUERY_HANDLE_INFO HandleInfo;
PUBLIC_OBJECT_BASIC_INFORMATION ObjectBasicInfo;
LPVOID ObjectNameInfo = VirtualAlloc(NULL, 0x2000, MEM_COMMIT, PAGE_READWRITE);
PPUBLIC_OBJECT_NAME_INFORMATION pObjectNameInfo = (PPUBLIC_OBJECT_NAME_INFORMATION)ObjectNameInfo;
LPVOID HandleFullName = VirtualAlloc(NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE);
int LenFileOrFolderName = lstrlenW(szFileOrFolderName);
LPVOID tmpHandleFullName = NULL;
if(ZwQuerySystemInformation != NULL && ZwQueryObject != NULL)
{
QuerySystemBuffer = VirtualAlloc(NULL, QuerySystemBufferSize, MEM_COMMIT, PAGE_READWRITE);
while(cZwQuerySystemInformation(NTDLL_SystemHandleInfo, QuerySystemBuffer, QuerySystemBufferSize, &RequiredSize) == (NTSTATUS)0xC0000004L)
{
QuerySystemBufferSize = RequiredSize;
VirtualFree(QuerySystemBuffer, NULL, MEM_RELEASE);
QuerySystemBuffer = VirtualAlloc(NULL, QuerySystemBufferSize, MEM_COMMIT, PAGE_READWRITE);
}
RtlMoveMemory(&TotalHandleCount, QuerySystemBuffer, sizeof ULONG);
QuerySystemBuffer = (LPVOID)((ULONG_PTR)QuerySystemBuffer + 4);
HandleInfo = (PNTDLL_QUERY_HANDLE_INFO)QuerySystemBuffer;
while(TotalHandleCount > NULL)
{
if(LastProcessId != HandleInfo->ProcessId)
{
if(hProcess != NULL)
{
EngineCloseHandle(hProcess);
}
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_DUP_HANDLE, false, HandleInfo->ProcessId);
LastProcessId = HandleInfo->ProcessId;
}
if(hProcess != NULL)
{
//if(!(HandleInfo->GrantedAccess & SYNCHRONIZE) || ((HandleInfo->GrantedAccess & SYNCHRONIZE) && ((WORD)HandleInfo->GrantedAccess != 0x19F9))){// && (WORD)HandleInfo->GrantedAccess != 0x89))){
if(HandleInfo->GrantedAccess != 0x0012019F)
{
if(DuplicateHandle(hProcess, (HANDLE)HandleInfo->hHandle, GetCurrentProcess(), &myHandle, NULL, false, DUPLICATE_SAME_ACCESS))
{
RtlZeroMemory(&ObjectBasicInfo, sizeof PUBLIC_OBJECT_BASIC_INFORMATION);
cZwQueryObject(myHandle, ObjectBasicInformation, &ObjectBasicInfo, sizeof PUBLIC_OBJECT_BASIC_INFORMATION, &RequiredSize);
cZwQueryObject(myHandle, ObjectNameInformation, ObjectNameInfo, 8, &RequiredSize);
cZwQueryObject(myHandle, ObjectNameInformation, ObjectNameInfo, RequiredSize, &RequiredSize);
RtlZeroMemory(HandleFullName, 0x1000);
if(pObjectNameInfo->Name.Length != NULL)
{
//WideCharToMultiByte(CP_ACP, NULL, (LPCWSTR)pObjectNameInfo->Name.Buffer, -1, (LPSTR)HandleFullName, 0x1000, NULL, NULL);
lstrcpyW((wchar_t*)HandleFullName, (wchar_t*)pObjectNameInfo->Name.Buffer);
if(NameIsTranslated)
{
tmpHandleFullName = TranslateNativeNameW((wchar_t*)HandleFullName);
if(tmpHandleFullName != NULL)
{
VirtualFree(HandleFullName, NULL, MEM_RELEASE);
HandleFullName = tmpHandleFullName;
}
}
if(NameIsFolder)
{
if(lstrlenW((LPCWSTR)HandleFullName) > LenFileOrFolderName)
{
RtlZeroMemory((LPVOID)((ULONG_PTR)HandleFullName + LenFileOrFolderName * 2), 2);
}
}
if(lstrcmpiW((LPCWSTR)HandleFullName, szFileOrFolderName) == NULL)
{
VirtualFree(ObjectNameInfo, NULL, MEM_RELEASE);
VirtualFree(QuerySystemBuffer, NULL, MEM_RELEASE);
VirtualFree(HandleFullName, NULL, MEM_RELEASE);
EngineCloseHandle(myHandle);
return(true);
}
}
EngineCloseHandle(myHandle);
}
}
}
HandleInfo = (PNTDLL_QUERY_HANDLE_INFO)((ULONG_PTR)HandleInfo + sizeof NTDLL_QUERY_HANDLE_INFO);
TotalHandleCount--;
}
VirtualFree(ObjectNameInfo, NULL, MEM_RELEASE);
VirtualFree(QuerySystemBuffer, NULL, MEM_RELEASE);
VirtualFree(HandleFullName, NULL, MEM_RELEASE);
return(false);
}
VirtualFree(ObjectNameInfo, NULL, MEM_RELEASE);
VirtualFree(HandleFullName, NULL, MEM_RELEASE);
return(false);
}
// TitanEngine.Handler[Mutex].functions:
__declspec(dllexport) long TITCALL HandlerEnumerateOpenMutexes(HANDLE hProcess, DWORD ProcessId, LPVOID HandleBuffer, DWORD MaxHandleCount)
{
HANDLE myHandle = NULL;
HANDLE copyHandle = NULL;
LPVOID QuerySystemBuffer;
ULONG RequiredSize = NULL;
ULONG TotalHandleCount = NULL;
unsigned int HandleCount = NULL;
ULONG QuerySystemBufferSize = 0x2000;
#if !defined(_WIN64)
typedef NTSTATUS(WINAPI *fZwQuerySystemInformation)(DWORD fInfoType, LPVOID fBuffer, ULONG fBufferSize, PULONG fRequiredSize);
typedef NTSTATUS(WINAPI *fZwQueryObject)(HANDLE hObject, DWORD fInfoType, LPVOID fBuffer, ULONG fBufferSize, PULONG fRequiredSize);
#else
typedef NTSTATUS(__fastcall *fZwQuerySystemInformation)(DWORD fInfoType, LPVOID fBuffer, ULONG fBufferSize, PULONG fRequiredSize);
typedef NTSTATUS(__fastcall *fZwQueryObject)(HANDLE hObject, DWORD fInfoType, LPVOID fBuffer, ULONG fBufferSize, PULONG fRequiredSize);
#endif
LPVOID ZwQuerySystemInformation = (LPVOID)GetProcAddress(GetModuleHandleA("ntdll.dll"),"ZwQuerySystemInformation");
LPVOID ZwQueryObject = (LPVOID)GetProcAddress(GetModuleHandleA("ntdll.dll"),"ZwQueryObject");
fZwQuerySystemInformation cZwQuerySystemInformation = (fZwQuerySystemInformation)(ZwQuerySystemInformation);
fZwQueryObject cZwQueryObject = (fZwQueryObject)(ZwQueryObject);
PNTDLL_QUERY_HANDLE_INFO HandleInfo;
LPVOID HandleFullData = VirtualAlloc(NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE);
LPVOID HandleNameData = VirtualAlloc(NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE);
PPUBLIC_OBJECT_TYPE_INFORMATION pObjectTypeInfo = (PPUBLIC_OBJECT_TYPE_INFORMATION)HandleFullData;
if(ZwQuerySystemInformation != NULL && ZwQueryObject != NULL)
{
QuerySystemBuffer = VirtualAlloc(NULL, QuerySystemBufferSize, MEM_COMMIT, PAGE_READWRITE);
while(cZwQuerySystemInformation(NTDLL_SystemHandleInfo, QuerySystemBuffer, QuerySystemBufferSize, &RequiredSize) == (NTSTATUS)0xC0000004L)
{
QuerySystemBufferSize = RequiredSize;
VirtualFree(QuerySystemBuffer, NULL, MEM_RELEASE);
QuerySystemBuffer = VirtualAlloc(NULL, QuerySystemBufferSize, MEM_COMMIT, PAGE_READWRITE);
}
RtlMoveMemory(&TotalHandleCount, QuerySystemBuffer, sizeof ULONG);
QuerySystemBuffer = (LPVOID)((ULONG_PTR)QuerySystemBuffer + 4);
HandleInfo = (PNTDLL_QUERY_HANDLE_INFO)QuerySystemBuffer;
while(TotalHandleCount > NULL)
{
if(HandleInfo->ProcessId == ProcessId && HandleCount < MaxHandleCount)
{
//if(!(HandleInfo->GrantedAccess & SYNCHRONIZE) || ((HandleInfo->GrantedAccess & SYNCHRONIZE) && ((WORD)HandleInfo->GrantedAccess != 0x19F9))){// && (WORD)HandleInfo->GrantedAccess != 0x89))){
if(HandleInfo->GrantedAccess != 0x0012019F)
{
if(DuplicateHandle(hProcess, (HANDLE)HandleInfo->hHandle, GetCurrentProcess(), &myHandle, NULL, false, DUPLICATE_SAME_ACCESS))
{
RtlZeroMemory(HandleFullData, 0x1000);
cZwQueryObject(myHandle, ObjectTypeInformation, HandleFullData, 8, &RequiredSize);
cZwQueryObject(myHandle, ObjectTypeInformation, HandleFullData, RequiredSize, &RequiredSize);
RtlZeroMemory(HandleNameData, 0x1000);
if(pObjectTypeInfo->TypeName.Length != NULL)
{
WideCharToMultiByte(CP_ACP, NULL, (LPCWSTR)pObjectTypeInfo->TypeName.Buffer, -1, (LPSTR)HandleNameData, 0x1000, NULL, NULL);
if(lstrcmpiA((LPCSTR)HandleNameData, "Mutant") == NULL)
{
copyHandle = (HANDLE)HandleInfo->hHandle;
RtlMoveMemory(HandleBuffer, &copyHandle, sizeof HANDLE);
HandleBuffer = (LPVOID)((ULONG_PTR)HandleBuffer + sizeof HANDLE);
HandleCount++;
}
}
EngineCloseHandle(myHandle);
}
}
}
HandleInfo = (PNTDLL_QUERY_HANDLE_INFO)((ULONG_PTR)HandleInfo + sizeof NTDLL_QUERY_HANDLE_INFO);
TotalHandleCount--;
}
VirtualFree(HandleFullData, NULL, MEM_RELEASE);
VirtualFree(HandleNameData, NULL, MEM_RELEASE);
VirtualFree(QuerySystemBuffer, NULL, MEM_RELEASE);
return(HandleCount);
}
VirtualFree(HandleFullData, NULL, MEM_RELEASE);
VirtualFree(HandleNameData, NULL, MEM_RELEASE);
return(NULL);
}
__declspec(dllexport) long long TITCALL HandlerGetOpenMutexHandle(HANDLE hProcess, DWORD ProcessId, char* szMutexString)
{
wchar_t uniMutexString[MAX_PATH] = {};
if(szMutexString != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szMutexString, lstrlenA(szMutexString)+1, uniMutexString, sizeof(uniMutexString)/(sizeof(uniMutexString[0])));
return((ULONG_PTR)HandlerGetOpenMutexHandleW(hProcess, ProcessId, uniMutexString));
}
else
{
return(NULL);
}
}
__declspec(dllexport) long long TITCALL HandlerGetOpenMutexHandleW(HANDLE hProcess, DWORD ProcessId, wchar_t* szMutexString)
{
if(!szMutexString || lstrlenW(szMutexString)>=512)
return 0;
int i;
HANDLE myHandle;
LPVOID HandleBuffer = VirtualAlloc(NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE);
LPVOID cHandleBuffer = HandleBuffer;
int OpenHandleCount = HandlerEnumerateOpenMutexes(hProcess, ProcessId, HandleBuffer, 0x1000 / sizeof HANDLE);
wchar_t RealMutexName[512] = L"\\BaseNamedObjects\\";
wchar_t* HandleName;
if(OpenHandleCount > NULL)
{
lstrcatW(RealMutexName, szMutexString);
for(i = 0; i < OpenHandleCount; i++)
{
RtlMoveMemory(&myHandle, cHandleBuffer, sizeof HANDLE);
HandleName = (wchar_t*)HandlerGetHandleNameW(hProcess, ProcessId, myHandle, true);
if(HandleName != NULL)
{
if(lstrcmpiW(HandleName, RealMutexName) == NULL)
{
VirtualFree(HandleBuffer, NULL, MEM_RELEASE);
return((ULONG_PTR)myHandle);
}
}
cHandleBuffer = (LPVOID)((ULONG_PTR)cHandleBuffer + sizeof HANDLE);
}
}
VirtualFree(HandleBuffer, NULL, MEM_RELEASE);
return(NULL);
}
__declspec(dllexport) long TITCALL HandlerGetProcessIdWhichCreatedMutex(char* szMutexString)
{
wchar_t uniMutexString[MAX_PATH] = {};
if(szMutexString != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szMutexString, lstrlenA(szMutexString)+1, uniMutexString, sizeof(uniMutexString)/(sizeof(uniMutexString[0])));
return(HandlerGetProcessIdWhichCreatedMutexW(uniMutexString));
}
else
{
return(NULL);
}
}
__declspec(dllexport) long TITCALL HandlerGetProcessIdWhichCreatedMutexW(wchar_t* szMutexString)
{
if(!szMutexString || lstrlenW(szMutexString)>=512)
return 0;
HANDLE hProcess = NULL;
DWORD ReturnData = NULL;
HANDLE myHandle = NULL;
LPVOID QuerySystemBuffer;
ULONG RequiredSize = NULL;
DWORD LastProcessId = NULL;
ULONG TotalHandleCount = NULL;
ULONG QuerySystemBufferSize = 0x2000;
#if !defined(_WIN64)
typedef NTSTATUS(WINAPI *fZwQuerySystemInformation)(DWORD fInfoType, LPVOID fBuffer, ULONG fBufferSize, PULONG fRequiredSize);
typedef NTSTATUS(WINAPI *fZwQueryObject)(HANDLE hObject, DWORD fInfoType, LPVOID fBuffer, ULONG fBufferSize, PULONG fRequiredSize);
#else
typedef NTSTATUS(__fastcall *fZwQuerySystemInformation)(DWORD fInfoType, LPVOID fBuffer, ULONG fBufferSize, PULONG fRequiredSize);
typedef NTSTATUS(__fastcall *fZwQueryObject)(HANDLE hObject, DWORD fInfoType, LPVOID fBuffer, ULONG fBufferSize, PULONG fRequiredSize);
#endif
LPVOID ZwQuerySystemInformation = (LPVOID)GetProcAddress(GetModuleHandleA("ntdll.dll"),"ZwQuerySystemInformation");
LPVOID ZwQueryObject = (LPVOID)GetProcAddress(GetModuleHandleA("ntdll.dll"),"ZwQueryObject");
fZwQuerySystemInformation cZwQuerySystemInformation = (fZwQuerySystemInformation)(ZwQuerySystemInformation);
fZwQueryObject cZwQueryObject = (fZwQueryObject)(ZwQueryObject);
PNTDLL_QUERY_HANDLE_INFO HandleInfo;
LPVOID HandleFullData = VirtualAlloc(NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE);
LPVOID HandleNameData = VirtualAlloc(NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE);
PPUBLIC_OBJECT_TYPE_INFORMATION pObjectTypeInfo = (PPUBLIC_OBJECT_TYPE_INFORMATION)HandleFullData;
LPVOID ObjectNameInfo = VirtualAlloc(NULL, 0x2000, MEM_COMMIT, PAGE_READWRITE);
PPUBLIC_OBJECT_NAME_INFORMATION pObjectNameInfo = (PPUBLIC_OBJECT_NAME_INFORMATION)ObjectNameInfo;
wchar_t RealMutexName[512] = L"\\BaseNamedObjects\\";
if(ZwQuerySystemInformation != NULL && ZwQueryObject != NULL)
{
lstrcatW(RealMutexName, szMutexString);
QuerySystemBuffer = VirtualAlloc(NULL, QuerySystemBufferSize, MEM_COMMIT, PAGE_READWRITE);
while(cZwQuerySystemInformation(NTDLL_SystemHandleInfo, QuerySystemBuffer, QuerySystemBufferSize, &RequiredSize) == (NTSTATUS)0xC0000004L)
{
QuerySystemBufferSize = RequiredSize;
VirtualFree(QuerySystemBuffer, NULL, MEM_RELEASE);
QuerySystemBuffer = VirtualAlloc(NULL, QuerySystemBufferSize, MEM_COMMIT, PAGE_READWRITE);
}
RtlMoveMemory(&TotalHandleCount, QuerySystemBuffer, sizeof ULONG);
QuerySystemBuffer = (LPVOID)((ULONG_PTR)QuerySystemBuffer + 4);
HandleInfo = (PNTDLL_QUERY_HANDLE_INFO)QuerySystemBuffer;
while(TotalHandleCount > NULL)
{
if(LastProcessId != HandleInfo->ProcessId)
{
if(hProcess != NULL)
{
EngineCloseHandle(hProcess);
}
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_DUP_HANDLE, false, HandleInfo->ProcessId);
LastProcessId = HandleInfo->ProcessId;
}
if(hProcess != NULL)
{
//if(!(HandleInfo->GrantedAccess & SYNCHRONIZE) || ((HandleInfo->GrantedAccess & SYNCHRONIZE) && ((WORD)HandleInfo->GrantedAccess != 0x19F9))){// && (WORD)HandleInfo->GrantedAccess != 0x89))){
if(HandleInfo->GrantedAccess != 0x0012019F)
{
if(DuplicateHandle(hProcess, (HANDLE)HandleInfo->hHandle, GetCurrentProcess(), &myHandle, NULL, false, DUPLICATE_SAME_ACCESS))
{
RtlZeroMemory(HandleFullData, 0x1000);
cZwQueryObject(myHandle, ObjectTypeInformation, HandleFullData, 8, &RequiredSize);
cZwQueryObject(myHandle, ObjectTypeInformation, HandleFullData, RequiredSize, &RequiredSize);
RtlZeroMemory(HandleNameData, 0x1000);
if(pObjectTypeInfo->TypeName.Length != NULL)
{
//WideCharToMultiByte(CP_ACP, NULL, (LPCWSTR)pObjectTypeInfo->TypeName.Buffer, -1, (LPSTR)HandleNameData, 0x1000, NULL, NULL);
lstrcpyW((wchar_t*)HandleNameData, (wchar_t*)pObjectNameInfo->Name.Buffer);
if(lstrcmpiW((LPCWSTR)HandleNameData, L"Mutant") == NULL)
{
cZwQueryObject(myHandle, ObjectNameInformation, ObjectNameInfo, 8, &RequiredSize);
cZwQueryObject(myHandle, ObjectNameInformation, ObjectNameInfo, RequiredSize, &RequiredSize);
RtlZeroMemory(HandleNameData, 0x1000);
if(pObjectNameInfo->Name.Length != NULL)
{
RtlZeroMemory(HandleNameData, 0x1000);
//WideCharToMultiByte(CP_ACP, NULL, (LPCWSTR)pObjectNameInfo->Name.Buffer, -1, (LPSTR)HandleNameData, 0x1000, NULL, NULL);
lstrcpyW((wchar_t*)HandleNameData, (wchar_t*)pObjectNameInfo->Name.Buffer);
if(lstrcmpiW((LPCWSTR)HandleNameData, RealMutexName) == NULL)
{
ReturnData = HandleInfo->ProcessId;
break;
}
}
}
}
EngineCloseHandle(myHandle);
}
}
}
HandleInfo = (PNTDLL_QUERY_HANDLE_INFO)((ULONG_PTR)HandleInfo + sizeof NTDLL_QUERY_HANDLE_INFO);
TotalHandleCount--;
}
VirtualFree(HandleFullData, NULL, MEM_RELEASE);
VirtualFree(HandleNameData, NULL, MEM_RELEASE);
VirtualFree(ObjectNameInfo, NULL, MEM_RELEASE);
VirtualFree(QuerySystemBuffer, NULL, MEM_RELEASE);
return(ReturnData);
}
VirtualFree(HandleFullData, NULL, MEM_RELEASE);
VirtualFree(HandleNameData, NULL, MEM_RELEASE);
VirtualFree(ObjectNameInfo, NULL, MEM_RELEASE);
return(NULL);
}
// Global.Injector.functions: {DO NOT REORDER! USE ONLY IN RELEASE MODE!}
long injectedImpRec(LPVOID Parameter)
{
HANDLE hFile;
HANDLE hFileMap;
PInjectImpRecCodeData APIData = (PInjectImpRecCodeData)Parameter;
LPVOID szFileName = (LPVOID)((ULONG_PTR)Parameter + sizeof InjectImpRecCodeData);
typedef ULONG_PTR(__cdecl *fTrace)(DWORD hFileMap, DWORD dwSizeMap, DWORD dwTimeOut, DWORD dwToTrace, DWORD dwExactCall);
typedef HANDLE(WINAPI *fCreateFileW)(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);
typedef HANDLE(WINAPI *fCreateFileMappingA)(HANDLE hFile, LPSECURITY_ATTRIBUTES lpFileMappingAttributes, DWORD flProtect, DWORD dwMaximumSizeHigh, DWORD dwMaximumSizeLow, LPCSTR lpName);
typedef BOOL(__cdecl *fCloseHandle)(HANDLE hHandle);
fTrace cTrace = (fTrace)(APIData->fTrace);
fCreateFileW cCreateFileW = (fCreateFileW)(APIData->fCreateFileA);
fCloseHandle cCloseHandle = (fCloseHandle)(APIData->fCloseHandle);
fCreateFileMappingA cCreateFileMappingA = (fCreateFileMappingA)(APIData->fCreateFileMappingA);
hFile = cCreateFileW((LPCWSTR)szFileName, GENERIC_READ+GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile != INVALID_HANDLE_VALUE)
{
hFileMap = cCreateFileMappingA(hFile, NULL, 4, NULL, 0x100, NULL);
cTrace((DWORD)hFileMap, 0x100, -1, (DWORD)APIData->AddressToTrace, NULL);
cCloseHandle(hFile);
return(1);
}
else
{
return(0);
}
}
long injectedRemoteLoadLibrary(LPVOID Parameter)
{
PInjectCodeData APIData = (PInjectCodeData)Parameter;
Parameter = (LPVOID)((ULONG_PTR)Parameter + sizeof InjectCodeData);
#if !defined(_WIN64)
typedef ULONG_PTR(WINAPI *fLoadLibraryW)(LPCWSTR fLibraryName);
typedef ULONG_PTR(WINAPI *fVirtualFree)(LPVOID fMemBase, SIZE_T fMemSize, DWORD fFreeType);
#else
typedef ULONG_PTR(__fastcall *fLoadLibraryW)(LPCWSTR fLibraryName);
typedef ULONG_PTR(__fastcall *fVirtualFree)(LPVOID fMemBase, SIZE_T fMemSize, DWORD fFreeType);
#endif
fLoadLibraryW cLoadLibraryW = (fLoadLibraryW)(APIData->fLoadLibrary);
fVirtualFree cVirtualFree = (fVirtualFree)(APIData->fVirtualFree);
long retValue = NULL;
if(cLoadLibraryW((LPCWSTR)Parameter) != NULL)
{
retValue++;
}
cVirtualFree(Parameter, NULL, MEM_RELEASE);
return(retValue);
}
long injectedRemoteFreeLibrary(LPVOID Parameter)
{
PInjectCodeData APIData = (PInjectCodeData)Parameter;
#if !defined(_WIN64)
typedef ULONG_PTR(WINAPI *fFreeLibrary)(HMODULE fLibBase);
typedef ULONG_PTR(WINAPI *fVirtualFree)(LPVOID fMemBase, SIZE_T fMemSize, DWORD fFreeType);
#else
typedef ULONG_PTR(__fastcall *fFreeLibrary)(HMODULE fLibBase);
typedef ULONG_PTR(__fastcall *fVirtualFree)(LPVOID fMemBase, SIZE_T fMemSize, DWORD fFreeType);
#endif
fFreeLibrary cFreeLibrary = (fFreeLibrary)(APIData->fFreeLibrary);
fVirtualFree cVirtualFree = (fVirtualFree)(APIData->fVirtualFree);
long retValue = NULL;
if(cFreeLibrary(APIData->fFreeLibraryHandle))
{
retValue++;
}
cVirtualFree(Parameter, NULL, MEM_RELEASE);
return(retValue);
}
long injectedRemoteFreeLibrarySimple(LPVOID Parameter)
{
PInjectCodeData APIData = (PInjectCodeData)Parameter;
LPVOID orgParameter = Parameter;
Parameter = (LPVOID)((ULONG_PTR)Parameter + sizeof InjectCodeData);
#if !defined(_WIN64)
typedef ULONG_PTR(WINAPI *fFreeLibrary)(HMODULE fLibBase);
typedef HMODULE(WINAPI *fGetModuleHandleW)(LPCWSTR fLibraryName);
typedef ULONG_PTR(WINAPI *fVirtualFree)(LPVOID fMemBase, SIZE_T fMemSize, DWORD fFreeType);
#else
typedef ULONG_PTR(__fastcall *fFreeLibrary)(HMODULE fLibBase);
typedef HMODULE(__fastcall *fGetModuleHandleW)(LPCWSTR fLibraryName);
typedef ULONG_PTR(__fastcall *fVirtualFree)(LPVOID fMemBase, SIZE_T fMemSize, DWORD fFreeType);
#endif
fGetModuleHandleW cGetModuleHandleW = (fGetModuleHandleW)(APIData->fGetModuleHandle);
fFreeLibrary cFreeLibrary = (fFreeLibrary)(APIData->fFreeLibrary);
fVirtualFree cVirtualFree = (fVirtualFree)(APIData->fVirtualFree);
long retValue = NULL;
HMODULE hModule;
hModule = cGetModuleHandleW((LPCWSTR)Parameter);
if(hModule != NULL)
{
if(cFreeLibrary(hModule))
{
retValue++;
}
}
else
{
retValue++;
}
cVirtualFree(orgParameter, NULL, MEM_RELEASE);
return(retValue);
}
long injectedExitProcess(LPVOID Parameter)
{
PInjectCodeData APIData = (PInjectCodeData)Parameter;
#if !defined(_WIN64)
typedef ULONG_PTR(WINAPI *fExitProcess)(DWORD fExitCode);
#else
typedef ULONG_PTR(__fastcall *fExitProcess)(DWORD fExitCode);
#endif
fExitProcess cExitProcess = (fExitProcess)(APIData->fExitProcess);
long retValue = NULL;
cExitProcess(APIData->fExitProcessCode);
return(NULL);
}
void injectedTerminator()
{
int i;
for(i = 0; i < UE_MAX_RESERVED_MEMORY_LEFT; i++)
{
if(engineReservedMemoryLeft[i] != NULL)
{
VirtualFreeEx(engineReservedMemoryProcess, (LPVOID)engineReservedMemoryLeft[i], NULL, MEM_RELEASE);
engineReservedMemoryLeft[i] = NULL;
}
}
}
// TitanEngine.Injector.functions:
__declspec(dllexport) bool TITCALL RemoteLoadLibrary(HANDLE hProcess, char* szLibraryFile, bool WaitForThreadExit)
{
wchar_t uniLibraryFile[MAX_PATH] = {};
if(szLibraryFile != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szLibraryFile, lstrlenA(szLibraryFile)+1, uniLibraryFile, sizeof(uniLibraryFile)/(sizeof(uniLibraryFile[0])));
return(RemoteLoadLibraryW(hProcess, uniLibraryFile, WaitForThreadExit));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL RemoteLoadLibraryW(HANDLE hProcess, wchar_t* szLibraryFile, bool WaitForThreadExit)
{
int i;
InjectCodeData APIData;
LPVOID remStringData;
LPVOID remCodeData;
ULONG_PTR remInjectSize = (ULONG_PTR)((ULONG_PTR)&injectedRemoteFreeLibrary - (ULONG_PTR)&injectedRemoteLoadLibrary);
#if !defined(_WIN64)
typedef NTSTATUS(WINAPI *fZwSetInformationThread)(HANDLE fThreadHandle, DWORD fThreadInfoClass, LPVOID fBuffer, ULONG fBufferSize);
#else
typedef NTSTATUS(__fastcall *fZwSetInformationThread)(HANDLE fThreadHandle, DWORD fThreadInfoClass, LPVOID fBuffer, ULONG fBufferSize);
#endif
LPVOID ZwSetInformationThread = (LPVOID)GetProcAddress(GetModuleHandleA("ntdll.dll"),"ZwSetInformationThread");
fZwSetInformationThread cZwSetInformationThread = (fZwSetInformationThread)(ZwSetInformationThread);
ULONG_PTR NumberOfBytesWritten;
DWORD ThreadId;
HANDLE hThread;
DWORD ExitCode;
if(hProcess != NULL)
{
RtlZeroMemory(&APIData, sizeof InjectCodeData);
APIData.fLoadLibrary = (ULONG_PTR)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryW"));
APIData.fFreeLibrary = (ULONG_PTR)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "FreeLibrary"));
APIData.fGetModuleHandle = (ULONG_PTR)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetModuleHandleW"));
APIData.fGetProcAddress = (ULONG_PTR)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetProcAddress"));
APIData.fVirtualFree = (ULONG_PTR)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "VirtualFree"));
APIData.fExitProcess = (ULONG_PTR)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "ExitProcess"));
remCodeData = VirtualAllocEx(hProcess, NULL, remInjectSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
remStringData = VirtualAllocEx(hProcess, NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE);
if(WriteProcessMemory(hProcess, (LPVOID)((ULONG_PTR)remStringData + sizeof InjectCodeData), (LPCVOID)szLibraryFile, lstrlenW(szLibraryFile) * 2, &NumberOfBytesWritten))
{
WriteProcessMemory(hProcess, remStringData, &APIData, sizeof InjectCodeData, &NumberOfBytesWritten);
WriteProcessMemory(hProcess, remCodeData, (LPCVOID)&injectedRemoteLoadLibrary, remInjectSize, &NumberOfBytesWritten);
if(WaitForThreadExit)
{
hThread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)remCodeData, remStringData, CREATE_SUSPENDED, &ThreadId);
if(ZwSetInformationThread != NULL)
{
cZwSetInformationThread(hThread, 0x11, NULL, NULL);
}
ResumeThread(hThread);
WaitForSingleObject(hThread, INFINITE);
VirtualFreeEx(hProcess, remCodeData, NULL, MEM_RELEASE);
VirtualFreeEx(hProcess, remStringData, NULL, MEM_RELEASE);
if(GetExitCodeThread(hThread, &ExitCode))
{
if(ExitCode == NULL)
{
return(false);
}
}
}
else
{
hThread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)remCodeData, remStringData, NULL, &ThreadId);
for(i = 0; i < UE_MAX_RESERVED_MEMORY_LEFT; i++)
{
if(engineReservedMemoryLeft[i] == NULL)
{
break;
}
}
engineReservedMemoryLeft[i] = (ULONG_PTR)remCodeData;
engineReservedMemoryProcess = hProcess;
ThreaderSetCallBackForNextExitThreadEvent((LPVOID)&injectedTerminator);
}
return(true);
}
else
{
VirtualFreeEx(hProcess, remCodeData, NULL, MEM_RELEASE);
VirtualFreeEx(hProcess, remStringData, NULL, MEM_RELEASE);
}
}
return(false);
}
__declspec(dllexport) bool TITCALL RemoteFreeLibrary(HANDLE hProcess, HMODULE hModule, char* szLibraryFile, bool WaitForThreadExit)
{
wchar_t uniLibraryFile[MAX_PATH] = {};
if(szLibraryFile != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szLibraryFile, lstrlenA(szLibraryFile)+1, uniLibraryFile, sizeof(uniLibraryFile)/(sizeof(uniLibraryFile[0])));
return(RemoteFreeLibraryW(hProcess, hModule, uniLibraryFile, WaitForThreadExit));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL RemoteFreeLibraryW(HANDLE hProcess, HMODULE hModule, wchar_t* szLibraryFile, bool WaitForThreadExit)
{
int i;
InjectCodeData APIData;
LPVOID remStringData;
LPVOID remCodeData;
ULONG_PTR remInjectSize1 = (ULONG_PTR)((ULONG_PTR)&injectedExitProcess - (ULONG_PTR)&injectedRemoteFreeLibrarySimple);
ULONG_PTR remInjectSize2 = (ULONG_PTR)((ULONG_PTR)&injectedRemoteFreeLibrarySimple - (ULONG_PTR)&injectedRemoteFreeLibrary);
#if !defined(_WIN64)
typedef NTSTATUS(WINAPI *fZwSetInformationThread)(HANDLE fThreadHandle, DWORD fThreadInfoClass, LPVOID fBuffer, ULONG fBufferSize);
#else
typedef NTSTATUS(__fastcall *fZwSetInformationThread)(HANDLE fThreadHandle, DWORD fThreadInfoClass, LPVOID fBuffer, ULONG fBufferSize);
#endif
LPVOID ZwSetInformationThread = (LPVOID)GetProcAddress(GetModuleHandleA("ntdll.dll"),"ZwSetInformationThread");
fZwSetInformationThread cZwSetInformationThread = (fZwSetInformationThread)(ZwSetInformationThread);
ULONG_PTR NumberOfBytesWritten;
DWORD ThreadId;
HANDLE hThread;
DWORD ExitCode;
if(hProcess != NULL)
{
RtlZeroMemory(&APIData, sizeof InjectCodeData);
APIData.fLoadLibrary = (ULONG_PTR)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryW"));
APIData.fFreeLibrary = (ULONG_PTR)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "FreeLibrary"));
APIData.fGetModuleHandle = (ULONG_PTR)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetModuleHandleW"));
APIData.fGetProcAddress = (ULONG_PTR)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetProcAddress"));
APIData.fVirtualFree = (ULONG_PTR)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "VirtualFree"));
APIData.fExitProcess = (ULONG_PTR)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "ExitProcess"));
APIData.fFreeLibraryHandle = hModule;
remCodeData = VirtualAllocEx(hProcess, NULL, remInjectSize1, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if(hModule == NULL)
{
remStringData = VirtualAllocEx(hProcess, NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE);
if(WriteProcessMemory(hProcess, (LPVOID)((ULONG_PTR)remStringData + sizeof InjectCodeData), (LPCVOID)szLibraryFile, lstrlenW(szLibraryFile) * 2, &NumberOfBytesWritten))
{
WriteProcessMemory(hProcess, remStringData, &APIData, sizeof InjectCodeData, &NumberOfBytesWritten);
WriteProcessMemory(hProcess, remCodeData, (LPCVOID)&injectedRemoteFreeLibrarySimple, remInjectSize1, &NumberOfBytesWritten);
if(WaitForThreadExit)
{
hThread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)remCodeData, remStringData, CREATE_SUSPENDED, &ThreadId);
if(ZwSetInformationThread != NULL)
{
cZwSetInformationThread(hThread, 0x11, NULL, NULL);
}
ResumeThread(hThread);
WaitForSingleObject(hThread, INFINITE);
VirtualFreeEx(hProcess, remCodeData, NULL, MEM_RELEASE);
VirtualFreeEx(hProcess, remStringData, NULL, MEM_RELEASE);
if(GetExitCodeThread(hThread, &ExitCode))
{
if(ExitCode == NULL)
{
return(false);
}
}
}
else
{
hThread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)remCodeData, remStringData, NULL, &ThreadId);
for(i = 0; i < UE_MAX_RESERVED_MEMORY_LEFT; i++)
{
if(engineReservedMemoryLeft[i] == NULL)
{
break;
}
}
engineReservedMemoryLeft[i] = (ULONG_PTR)remCodeData;
engineReservedMemoryProcess = hProcess;
ThreaderSetCallBackForNextExitThreadEvent((LPVOID)&injectedTerminator);
}
return(true);
}
else
{
VirtualFreeEx(hProcess, remCodeData, NULL, MEM_RELEASE);
VirtualFreeEx(hProcess, remStringData, NULL, MEM_RELEASE);
}
}
else
{
remStringData = VirtualAllocEx(hProcess, NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE);
if(WriteProcessMemory(hProcess, remStringData, &APIData, sizeof InjectCodeData, &NumberOfBytesWritten))
{
WriteProcessMemory(hProcess, remCodeData, (LPCVOID)&injectedRemoteFreeLibrary, remInjectSize2, &NumberOfBytesWritten);
if(WaitForThreadExit)
{
hThread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)remCodeData, remStringData, CREATE_SUSPENDED, &ThreadId);
if(ZwSetInformationThread != NULL)
{
cZwSetInformationThread(hThread, 0x11, NULL, NULL);
}
ResumeThread(hThread);
WaitForSingleObject(hThread, INFINITE);
VirtualFreeEx(hProcess, remCodeData, NULL, MEM_RELEASE);
if(GetExitCodeThread(hThread, &ExitCode))
{
if(ExitCode == NULL)
{
return(false);
}
}
}
else
{
hThread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)remCodeData, remStringData, NULL, &ThreadId);
for(i = 0; i < UE_MAX_RESERVED_MEMORY_LEFT; i++)
{
if(engineReservedMemoryLeft[i] == NULL)
{
break;
}
}
engineReservedMemoryLeft[i] = (ULONG_PTR)remCodeData;
engineReservedMemoryProcess = hProcess;
ThreaderSetCallBackForNextExitThreadEvent((LPVOID)&injectedTerminator);
}
return(true);
}
else
{
VirtualFreeEx(hProcess, remCodeData, NULL, MEM_RELEASE);
VirtualFreeEx(hProcess, remStringData, NULL, MEM_RELEASE);
}
}
}
return(false);
}
__declspec(dllexport) bool TITCALL RemoteExitProcess(HANDLE hProcess, DWORD ExitCode)
{
InjectCodeData APIData;
LPVOID remCodeData;
LPVOID remStringData;
ULONG_PTR remInjectSize = (ULONG_PTR)((ULONG_PTR)&injectedTerminator - (ULONG_PTR)&injectedExitProcess);
ULONG_PTR NumberOfBytesWritten;
DWORD ThreadId;
HANDLE hThread;
if(hProcess != NULL)
{
RtlZeroMemory(&APIData, sizeof InjectCodeData);
APIData.fLoadLibrary = (ULONG_PTR)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA"));
APIData.fFreeLibrary = (ULONG_PTR)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "FreeLibrary"));
APIData.fGetModuleHandle = (ULONG_PTR)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetModuleHandleA"));
APIData.fGetProcAddress = (ULONG_PTR)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetProcAddress"));
APIData.fVirtualFree = (ULONG_PTR)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "VirtualFree"));
APIData.fExitProcess = (ULONG_PTR)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "ExitProcess"));
APIData.fExitProcessCode = ExitCode;
remStringData = VirtualAllocEx(hProcess, NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE);
remCodeData = VirtualAllocEx(hProcess, NULL, remInjectSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if(WriteProcessMemory(hProcess, remCodeData, (LPCVOID)&injectedExitProcess, remInjectSize, &NumberOfBytesWritten))
{
WriteProcessMemory(hProcess, remStringData, &APIData, sizeof InjectCodeData, &NumberOfBytesWritten);
hThread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)remCodeData, remStringData, NULL, &ThreadId);
VirtualFreeEx(hProcess, remCodeData, NULL, MEM_RELEASE);
return(true);
}
else
{
VirtualFreeEx(hProcess, remCodeData, NULL, MEM_RELEASE);
VirtualFreeEx(hProcess, remStringData, NULL, MEM_RELEASE);
}
}
return(false);
}
// TitanEngine.Tracer.functions:
__declspec(dllexport) long TITCALL TracerFixRedirectionViaImpRecPlugin(HANDLE hProcess, char* szPluginName, ULONG_PTR AddressToTrace)
{
int szLenght = NULL;
HMODULE hImpRecModule = NULL;
ULONG_PTR fImpRecTrace = NULL;
PMEMORY_CMP_HANDLER cmpModuleName;
ULONG_PTR remInjectSize = (ULONG_PTR)((ULONG_PTR)&injectedRemoteLoadLibrary - (ULONG_PTR)&injectedImpRec);
#if !defined(_WIN64)
typedef NTSTATUS(WINAPI *fZwSetInformationThread)(HANDLE fThreadHandle, DWORD fThreadInfoClass, LPVOID fBuffer, ULONG fBufferSize);
#else
typedef NTSTATUS(__fastcall *fZwSetInformationThread)(HANDLE fThreadHandle, DWORD fThreadInfoClass, LPVOID fBuffer, ULONG fBufferSize);
#endif
LPVOID ZwSetInformationThread = (LPVOID)GetProcAddress(GetModuleHandleA("ntdll.dll"),"ZwSetInformationThread");
fZwSetInformationThread cZwSetInformationThread = (fZwSetInformationThread)(ZwSetInformationThread);
LPVOID szModuleName = VirtualAlloc(NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE);
LPVOID szGarbageFile = VirtualAlloc(NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE);
LPVOID cModuleName = szModuleName;
ULONG_PTR NumberOfBytesWritten;
InjectImpRecCodeData APIData;
DWORD TracedAddress = NULL;
DWORD TraceAddress = NULL;
LPVOID remStringData;
LPVOID remCodeData;
DWORD ThreadId;
HANDLE hThread;
DWORD ExitCode;
HANDLE FileHandle;
DWORD FileSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
if(GetModuleFileNameA(engineHandle, (LPCH)szModuleName, 0x1000) > NULL)
{
cModuleName = (LPVOID)((ULONG_PTR)cModuleName + lstrlenA((LPCSTR)szModuleName));
cmpModuleName = (PMEMORY_CMP_HANDLER)(cModuleName);
while(cmpModuleName->DataByte[0] != 0x5C)
{
cmpModuleName = (PMEMORY_CMP_HANDLER)((ULONG_PTR)cmpModuleName - 1);
}
cmpModuleName = (PMEMORY_CMP_HANDLER)((ULONG_PTR)cmpModuleName + 1);
cmpModuleName->DataByte[0] = 0x00;
lstrcpyA((LPSTR)szGarbageFile, (LPCSTR)szModuleName);
lstrcatA((LPSTR)szGarbageFile, "garbage\\ImpRec.txt");
lstrcatA((LPSTR)szModuleName, "imports\\ImpRec\\");
lstrcatA((LPSTR)szModuleName, szPluginName);
if(ReadProcessMemory(hProcess, (LPVOID)AddressToTrace, &TraceAddress, 4, &NumberOfBytesWritten))
{
if(RemoteLoadLibrary(hProcess, (char*)szModuleName, true))
{
hImpRecModule = LoadLibraryA((char*)szModuleName);
if(hImpRecModule != NULL)
{
fImpRecTrace = (ULONG_PTR)GetProcAddress(hImpRecModule, "Trace");
if(fImpRecTrace != NULL)
{
fImpRecTrace = fImpRecTrace - (ULONG_PTR)hImpRecModule;
remCodeData = VirtualAllocEx(hProcess, NULL, remInjectSize, MEM_COMMIT, PAGE_READWRITE);
remStringData = VirtualAllocEx(hProcess, NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE);
RtlZeroMemory(&APIData, sizeof InjectImpRecCodeData);
APIData.fTrace = fImpRecTrace + (ULONG_PTR)ImporterGetRemoteDLLBase(hProcess, hImpRecModule);
APIData.AddressToTrace = (ULONG_PTR)TraceAddress;
APIData.fCreateFileA = (ULONG_PTR)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "CreateFileA"));
APIData.fCreateFileMappingA = (ULONG_PTR)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "CreateFileMappingA"));
APIData.fCloseHandle = (ULONG_PTR)ImporterGetRemoteAPIAddress(hProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "CloseHandle"));
if(WriteProcessMemory(hProcess, remCodeData, (LPCVOID)&injectedImpRec, remInjectSize, &NumberOfBytesWritten))
{
WriteProcessMemory(hProcess, remStringData, &APIData, sizeof InjectImpRecCodeData, &NumberOfBytesWritten);
WriteProcessMemory(hProcess, (LPVOID)((ULONG_PTR)remStringData + sizeof InjectImpRecCodeData), (LPCVOID)szGarbageFile, lstrlenA((LPSTR)szGarbageFile), &NumberOfBytesWritten);
hThread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)remCodeData, remStringData, CREATE_SUSPENDED, &ThreadId);
if(ZwSetInformationThread != NULL)
{
cZwSetInformationThread(hThread, 0x11, NULL, NULL);
}
ResumeThread(hThread);
WaitForSingleObject(hThread, INFINITE);
if(GetExitCodeThread(hThread, &ExitCode))
{
if(ExitCode != NULL)
{
if(MapFileEx((char*)szGarbageFile, UE_ACCESS_READ, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
RtlMoveMemory(&TracedAddress, (LPVOID)FileMapVA, 4);
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
}
if(!DeleteFileA((LPCSTR)szGarbageFile))
{
HandlerCloseAllLockHandles((char*)szGarbageFile, false, true);
DeleteFileA((LPCSTR)szGarbageFile);
}
}
}
}
RemoteFreeLibrary(hProcess, NULL, (char*)szModuleName, true);
VirtualFreeEx(hProcess, remCodeData, NULL, MEM_RELEASE);
VirtualFreeEx(hProcess, remStringData, NULL, MEM_RELEASE);
}
else
{
RemoteFreeLibrary(hProcess, NULL, (char*)szModuleName, true);
}
FreeLibrary(hImpRecModule);
}
}
}
}
VirtualFree(szModuleName, NULL, MEM_RELEASE);
VirtualFree(szGarbageFile, NULL, MEM_RELEASE);
return(TracedAddress);
}
// TitanEngine.StaticUnpacker.functions:
__declspec(dllexport) bool TITCALL StaticFileLoad(char* szFileName, DWORD DesiredAccess, bool SimulateLoad, LPHANDLE FileHandle, LPDWORD LoadedSize, LPHANDLE FileMap, PULONG_PTR FileMapVA)
{
if(!SimulateLoad)
{
if(MapFileEx(szFileName, DesiredAccess, FileHandle, LoadedSize, FileMap, FileMapVA, NULL))
{
return(true);
}
}
else
{
*FileMapVA = (ULONG_PTR)ResourcerLoadFileForResourceUse(szFileName);
if(*FileMapVA != NULL)
{
*LoadedSize = (DWORD)GetPE32DataFromMappedFile(*FileMapVA, NULL, UE_SIZEOFIMAGE);
*FileHandle = NULL;
*FileMap = NULL;
return(true);
}
}
return(false);
}
__declspec(dllexport) bool TITCALL StaticFileLoadW(wchar_t* szFileName, DWORD DesiredAccess, bool SimulateLoad, LPHANDLE FileHandle, LPDWORD LoadedSize, LPHANDLE FileMap, PULONG_PTR FileMapVA)
{
if(!SimulateLoad)
{
if(MapFileExW(szFileName, DesiredAccess, FileHandle, LoadedSize, FileMap, FileMapVA, NULL))
{
return(true);
}
}
else
{
*FileMapVA = (ULONG_PTR)ResourcerLoadFileForResourceUseW(szFileName);
if(*FileMapVA != NULL)
{
*LoadedSize = (DWORD)GetPE32DataFromMappedFile(*FileMapVA, NULL, UE_SIZEOFIMAGE);
*FileHandle = NULL;
*FileMap = NULL;
return(true);
}
}
return(false);
}
__declspec(dllexport) bool TITCALL StaticFileUnload(char* szFileName, bool CommitChanges, HANDLE FileHandle, DWORD LoadedSize, HANDLE FileMap, ULONG_PTR FileMapVA)
{
wchar_t uniFileName[MAX_PATH] = {};
if(szFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
return(StaticFileUnloadW(uniFileName, CommitChanges, FileHandle, LoadedSize, FileMap, FileMapVA));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL StaticFileUnloadW(wchar_t* szFileName, bool CommitChanges, HANDLE FileHandle, DWORD LoadedSize, HANDLE FileMap, ULONG_PTR FileMapVA)
{
DWORD PeHeaderSize;
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
PIMAGE_SECTION_HEADER PESections;
DWORD SectionNumber = 0;
DWORD SectionRawOffset = 0;
DWORD SectionRawSize = 0;
BOOL FileIs64;
HANDLE myFileHandle;
DWORD myFileSize;
HANDLE myFileMap;
ULONG_PTR myFileMapVA;
if(FileHandle != NULL && FileMap != NULL)
{
UnMapFileEx(FileHandle, LoadedSize, FileMap, FileMapVA);
return(true);
}
else
{
if(!CommitChanges)
{
return(ResourcerFreeLoadedFile((LPVOID)FileMapVA));
}
else
{
if(MapFileExW(szFileName, UE_ACCESS_ALL, &myFileHandle, &myFileSize, &myFileMap, &myFileMapVA, NULL))
{
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(DOSHeader->e_lfanew < 0x1000 - 108)
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
ResourcerFreeLoadedFile((LPVOID)FileMapVA);
UnMapFileEx(myFileHandle, myFileSize, myFileMap, myFileMapVA);
return(false);
}
if(!FileIs64)
{
PeHeaderSize = PEHeader32->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_SECTION_HEADER) * PEHeader32->FileHeader.NumberOfSections;
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader32 + PEHeader32->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
SectionNumber = PEHeader32->FileHeader.NumberOfSections;
RtlMoveMemory((LPVOID)myFileMapVA, (LPVOID)FileMapVA, PeHeaderSize);
while(SectionNumber > 0)
{
RtlMoveMemory((LPVOID)((ULONG_PTR)myFileMapVA + PESections->PointerToRawData), (LPVOID)(FileMapVA + PESections->VirtualAddress), PESections->SizeOfRawData);
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + IMAGE_SIZEOF_SECTION_HEADER);
SectionNumber--;
}
ResourcerFreeLoadedFile((LPVOID)FileMapVA);
UnMapFileEx(myFileHandle, myFileSize, myFileMap, myFileMapVA);
return(true);
}
else
{
PeHeaderSize = PEHeader64->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_SECTION_HEADER) * PEHeader64->FileHeader.NumberOfSections;
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PEHeader64 + PEHeader64->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + 4);
SectionNumber = PEHeader64->FileHeader.NumberOfSections;
RtlMoveMemory((LPVOID)myFileMapVA, (LPVOID)FileMapVA, PeHeaderSize);
while(SectionNumber > 0)
{
RtlMoveMemory((LPVOID)((ULONG_PTR)myFileMapVA + PESections->PointerToRawData), (LPVOID)(FileMapVA + PESections->VirtualAddress), PESections->SizeOfRawData);
PESections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)PESections + IMAGE_SIZEOF_SECTION_HEADER);
SectionNumber--;
}
ResourcerFreeLoadedFile((LPVOID)FileMapVA);
UnMapFileEx(myFileHandle, myFileSize, myFileMap, myFileMapVA);
return(true);
}
}
else
{
ResourcerFreeLoadedFile((LPVOID)FileMapVA);
UnMapFileEx(myFileHandle, myFileSize, myFileMap, myFileMapVA);
return(false);
}
}
}
}
return(false);
}
__declspec(dllexport) bool TITCALL StaticFileOpen(char* szFileName, DWORD DesiredAccess, LPHANDLE FileHandle, LPDWORD FileSizeLow, LPDWORD FileSizeHigh)
{
wchar_t uniFileName[MAX_PATH] = {};
if(szFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
return(StaticFileOpenW(uniFileName, DesiredAccess, FileHandle, FileSizeLow, FileSizeHigh));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL StaticFileOpenW(wchar_t* szFileName, DWORD DesiredAccess, LPHANDLE FileHandle, LPDWORD FileSizeLow, LPDWORD FileSizeHigh)
{
__try
{
*FileHandle = CreateFileW(szFileName, DesiredAccess, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(FileHandle != INVALID_HANDLE_VALUE)
{
*FileSizeLow = GetFileSize(*FileHandle, FileSizeHigh);
return(true);
}
else
{
return(false);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return(false);
}
}
__declspec(dllexport) bool TITCALL StaticFileGetContent(HANDLE FileHandle, DWORD FilePositionLow, LPDWORD FilePositionHigh, void* Buffer, DWORD Size)
{
DWORD rfNumberOfBytesRead;
if(SetFilePointer(FileHandle, FilePositionLow, (PLONG)FilePositionHigh, FILE_BEGIN) != INVALID_SET_FILE_POINTER)
{
if(ReadFile(FileHandle, Buffer, Size, &rfNumberOfBytesRead, NULL))
{
if(rfNumberOfBytesRead == Size)
{
return(true);
}
else
{
RtlZeroMemory(Buffer, Size);
}
}
}
return(false);
}
__declspec(dllexport) void TITCALL StaticFileClose(HANDLE FileHandle)
{
EngineCloseHandle(FileHandle);
}
__declspec(dllexport) void TITCALL StaticMemoryDecrypt(LPVOID MemoryStart, DWORD MemorySize, DWORD DecryptionType, DWORD DecryptionKeySize, ULONG_PTR DecryptionKey)
{
DWORD LoopCount = NULL;
BYTE DataByte = NULL;
WORD DataWord = NULL;
DWORD DataDword = NULL;
ULONG_PTR DataQword = NULL;
//ignore too big stuff
if(DecryptionKeySize>sizeof(ULONG_PTR))
return;
if(MemoryStart != NULL && MemorySize > NULL)
{
LoopCount = MemorySize / DecryptionKeySize;
while(LoopCount > NULL)
{
if(DecryptionType == UE_STATIC_DECRYPTOR_XOR)
{
if(DecryptionKeySize == UE_STATIC_KEY_SIZE_1)
{
RtlMoveMemory(&DataByte, MemoryStart, UE_STATIC_KEY_SIZE_1);
DataByte = DataByte ^ (BYTE)DecryptionKey;
RtlMoveMemory(MemoryStart, &DataByte, UE_STATIC_KEY_SIZE_1);
}
else if(DecryptionKeySize == UE_STATIC_KEY_SIZE_2)
{
RtlMoveMemory(&DataWord, MemoryStart, UE_STATIC_KEY_SIZE_2);
DataWord = DataWord ^ (WORD)DecryptionKey;
RtlMoveMemory(MemoryStart, &DataWord, UE_STATIC_KEY_SIZE_2);
}
else if(DecryptionKeySize == UE_STATIC_KEY_SIZE_4)
{
RtlMoveMemory(&DataDword, MemoryStart, UE_STATIC_KEY_SIZE_4);
DataDword = DataDword ^ (DWORD)DecryptionKey;
RtlMoveMemory(MemoryStart, &DataDword, UE_STATIC_KEY_SIZE_4);
}
else if(DecryptionKeySize == UE_STATIC_KEY_SIZE_8)
{
RtlMoveMemory(&DataQword, MemoryStart, UE_STATIC_KEY_SIZE_8);
DataQword = DataQword ^ (ULONG_PTR)DecryptionKey;
RtlMoveMemory(MemoryStart, &DataQword, UE_STATIC_KEY_SIZE_8);
}
}
else if(DecryptionType == UE_STATIC_DECRYPTOR_SUB)
{
if(DecryptionKeySize == UE_STATIC_KEY_SIZE_1)
{
RtlMoveMemory(&DataByte, MemoryStart, UE_STATIC_KEY_SIZE_1);
DataByte = DataByte - (BYTE)DecryptionKey;
RtlMoveMemory(MemoryStart, &DataByte, UE_STATIC_KEY_SIZE_1);
}
else if(DecryptionKeySize == UE_STATIC_KEY_SIZE_2)
{
RtlMoveMemory(&DataWord, MemoryStart, UE_STATIC_KEY_SIZE_2);
DataWord = DataWord - (WORD)DecryptionKey;
RtlMoveMemory(MemoryStart, &DataWord, UE_STATIC_KEY_SIZE_2);
}
else if(DecryptionKeySize == UE_STATIC_KEY_SIZE_4)
{
RtlMoveMemory(&DataDword, MemoryStart, UE_STATIC_KEY_SIZE_4);
DataDword = DataDword - (DWORD)DecryptionKey;
RtlMoveMemory(MemoryStart, &DataDword, UE_STATIC_KEY_SIZE_4);
}
else if(DecryptionKeySize == UE_STATIC_KEY_SIZE_8)
{
RtlMoveMemory(&DataQword, MemoryStart, UE_STATIC_KEY_SIZE_8);
DataQword = DataQword - (ULONG_PTR)DecryptionKey;
RtlMoveMemory(MemoryStart, &DataQword, UE_STATIC_KEY_SIZE_8);
}
}
else if(DecryptionType == UE_STATIC_DECRYPTOR_ADD)
{
if(DecryptionKeySize == UE_STATIC_KEY_SIZE_1)
{
RtlMoveMemory(&DataByte, MemoryStart, UE_STATIC_KEY_SIZE_1);
DataByte = DataByte + (BYTE)DecryptionKey;
RtlMoveMemory(MemoryStart, &DataByte, UE_STATIC_KEY_SIZE_1);
}
else if(DecryptionKeySize == UE_STATIC_KEY_SIZE_2)
{
RtlMoveMemory(&DataWord, MemoryStart, UE_STATIC_KEY_SIZE_2);
DataWord = DataWord + (WORD)DecryptionKey;
RtlMoveMemory(MemoryStart, &DataWord, UE_STATIC_KEY_SIZE_2);
}
else if(DecryptionKeySize == UE_STATIC_KEY_SIZE_4)
{
RtlMoveMemory(&DataDword, MemoryStart, UE_STATIC_KEY_SIZE_4);
DataDword = DataDword + (DWORD)DecryptionKey;
RtlMoveMemory(MemoryStart, &DataDword, UE_STATIC_KEY_SIZE_4);
}
else if(DecryptionKeySize == UE_STATIC_KEY_SIZE_8)
{
RtlMoveMemory(&DataQword, MemoryStart, UE_STATIC_KEY_SIZE_8);
DataQword = DataQword + (ULONG_PTR)DecryptionKey;
RtlMoveMemory(MemoryStart, &DataQword, UE_STATIC_KEY_SIZE_8);
}
}
MemoryStart = (LPVOID)((ULONG_PTR)MemoryStart + DecryptionKeySize);
LoopCount--;
}
}
}
__declspec(dllexport) void TITCALL StaticMemoryDecryptEx(LPVOID MemoryStart, DWORD MemorySize, DWORD DecryptionKeySize, void* DecryptionCallBack)
{
DWORD LoopCount = NULL;
typedef bool(TITCALL *fStaticCallBack)(void* sMemoryStart, int sKeySize);
fStaticCallBack myStaticCallBack = (fStaticCallBack)DecryptionCallBack;
if(MemoryStart != NULL && MemorySize > NULL)
{
LoopCount = MemorySize / DecryptionKeySize;
while(LoopCount > NULL)
{
__try
{
if(!myStaticCallBack(MemoryStart, (int)DecryptionKeySize))
{
break;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
break;
}
MemoryStart = (LPVOID)((ULONG_PTR)MemoryStart + DecryptionKeySize);
LoopCount--;
}
}
}
__declspec(dllexport) void TITCALL StaticMemoryDecryptSpecial(LPVOID MemoryStart, DWORD MemorySize, DWORD DecryptionKeySize, DWORD SpecDecryptionType, void* DecryptionCallBack)
{
DWORD LoopCount = NULL;
typedef bool(TITCALL *fStaticCallBack)(void* sMemoryStart, int sKeySize);
fStaticCallBack myStaticCallBack = (fStaticCallBack)DecryptionCallBack;
if(MemoryStart != NULL && MemorySize > NULL)
{
if(SpecDecryptionType == UE_STATIC_DECRYPTOR_BACKWARD)
{
MemoryStart = (LPVOID)((ULONG_PTR)MemoryStart + MemorySize - DecryptionKeySize);
}
LoopCount = MemorySize / DecryptionKeySize;
while(LoopCount > NULL)
{
__try
{
if(!myStaticCallBack(MemoryStart, (int)DecryptionKeySize))
{
break;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
break;
}
if(SpecDecryptionType == UE_STATIC_DECRYPTOR_BACKWARD)
{
MemoryStart = (LPVOID)((ULONG_PTR)MemoryStart - DecryptionKeySize);
}
else
{
MemoryStart = (LPVOID)((ULONG_PTR)MemoryStart + DecryptionKeySize);
}
LoopCount--;
}
}
}
__declspec(dllexport) void TITCALL StaticSectionDecrypt(ULONG_PTR FileMapVA, DWORD SectionNumber, bool SimulateLoad, DWORD DecryptionType, DWORD DecryptionKeySize, ULONG_PTR DecryptionKey)
{
if(!SimulateLoad)
{
StaticMemoryDecrypt((LPVOID)((ULONG_PTR)GetPE32DataFromMappedFile(FileMapVA, SectionNumber, UE_SECTIONRAWOFFSET) + FileMapVA), (DWORD)GetPE32DataFromMappedFile(FileMapVA, SectionNumber, UE_SECTIONRAWSIZE), DecryptionType, DecryptionKeySize, DecryptionKey);
}
else
{
StaticMemoryDecrypt((LPVOID)((ULONG_PTR)GetPE32DataFromMappedFile(FileMapVA, SectionNumber, UE_SECTIONVIRTUALOFFSET) + FileMapVA), (DWORD)GetPE32DataFromMappedFile(FileMapVA, SectionNumber, UE_SECTIONRAWSIZE), DecryptionType, DecryptionKeySize, DecryptionKey);
}
}
__declspec(dllexport) bool TITCALL StaticMemoryDecompress(void* Source, DWORD SourceSize, void* Destination, DWORD DestinationSize, int Algorithm)
{
if(!Source || !Destination)
return false;
ELzmaStatus lzStatus;
CLzmaProps lzProps = {};
ISzAlloc lzAlloc = {&LzmaAllocMem, &LzmaFreeMem};
if(Algorithm == UE_STATIC_APLIB)
{
#if !defined (_WIN64)
if(aP_depack_asm_safe(Source, SourceSize, Destination, DestinationSize) != APLIB_ERROR)
{
return(true);
}
else if(aPsafe_depack(Source, SourceSize, Destination, DestinationSize) != APLIB_ERROR)
{
return(true);
}
#endif
}
else if(Algorithm == UE_STATIC_LZMA)
{
if(LzmaDecode((unsigned char*)Destination, (size_t*)DestinationSize, (unsigned char*)Source, (size_t*)SourceSize, (unsigned char*)&lzProps, LZMA_PROPS_SIZE, LZMA_FINISH_ANY, &lzStatus, &lzAlloc) == SZ_OK)
{
return(true);
}
}
return(false);
}
__declspec(dllexport) bool TITCALL StaticRawMemoryCopy(HANDLE hFile, ULONG_PTR FileMapVA, ULONG_PTR VitualAddressToCopy, DWORD Size, bool AddressIsRVA, char* szDumpFileName)
{
wchar_t uniFileName[MAX_PATH] = {};
if(szDumpFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szDumpFileName, lstrlenA(szDumpFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
return(StaticRawMemoryCopyW(hFile, FileMapVA, VitualAddressToCopy, Size, AddressIsRVA, uniFileName));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL StaticRawMemoryCopyW(HANDLE hFile, ULONG_PTR FileMapVA, ULONG_PTR VitualAddressToCopy, DWORD Size, bool AddressIsRVA, wchar_t* szDumpFileName)
{
DWORD SizeToRead;
HANDLE hReadFile;
HANDLE hWriteFile;
LPVOID ueCopyBuffer;
ULONG_PTR AddressToCopy;
DWORD rfNumberOfBytesRead;
if(FileMapVA != NULL)
{
if(DuplicateHandle(GetCurrentProcess(), hFile, GetCurrentProcess(), &hReadFile, NULL, false, DUPLICATE_SAME_ACCESS))
{
if(AddressIsRVA)
{
VitualAddressToCopy = VitualAddressToCopy + (ULONG_PTR)GetPE32DataFromMappedFile(FileMapVA, NULL, UE_IMAGEBASE);
AddressToCopy = (ULONG_PTR)ConvertVAtoFileOffset(FileMapVA, VitualAddressToCopy, false);
}
else
{
AddressToCopy = (ULONG_PTR)ConvertVAtoFileOffset(FileMapVA, VitualAddressToCopy, false);
}
if(SetFilePointer(hReadFile, (long)AddressToCopy, NULL, FILE_BEGIN) != INVALID_SET_FILE_POINTER)
{
ueCopyBuffer = VirtualAlloc(NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE);
if(ueCopyBuffer != NULL)
{
if(EngineCreatePathForFileW(szDumpFileName))
{
hWriteFile = CreateFileW(szDumpFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(hWriteFile != INVALID_HANDLE_VALUE)
{
if(Size < 0x1000)
{
SizeToRead = Size;
}
else
{
SizeToRead = 0x1000;
}
while((int)Size > NULL)
{
if(ReadFile(hFile, ueCopyBuffer, SizeToRead, &rfNumberOfBytesRead, NULL) && rfNumberOfBytesRead == SizeToRead)
{
WriteFile(hWriteFile, ueCopyBuffer, SizeToRead, &rfNumberOfBytesRead, NULL);
if(Size > 0x1000)
{
Size = Size - 0x1000;
}
else if(SizeToRead != Size)
{
if(ReadFile(hFile, ueCopyBuffer, Size, &rfNumberOfBytesRead, NULL) && rfNumberOfBytesRead == SizeToRead)
{
WriteFile(hWriteFile, ueCopyBuffer, Size, &rfNumberOfBytesRead, NULL);
}
else
{
WriteFile(hWriteFile, ueCopyBuffer, rfNumberOfBytesRead, &rfNumberOfBytesRead, NULL);
}
SizeToRead = Size;
Size = NULL;
}
else
{
SizeToRead = Size;
Size = NULL;
}
}
else
{
WriteFile(hWriteFile, ueCopyBuffer, rfNumberOfBytesRead, &rfNumberOfBytesRead, NULL);
Size = NULL;
}
}
EngineCloseHandle(hReadFile);
EngineCloseHandle(hWriteFile);
VirtualFree(ueCopyBuffer, NULL, MEM_RELEASE);
return(true);
}
else
{
VirtualFree(ueCopyBuffer, NULL, MEM_RELEASE);
}
}
}
}
EngineCloseHandle(hReadFile);
}
}
return(false);
}
__declspec(dllexport) bool TITCALL StaticRawMemoryCopyEx(HANDLE hFile, DWORD RawAddressToCopy, DWORD Size, char* szDumpFileName)
{
wchar_t uniFileName[MAX_PATH] = {};
if(szDumpFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szDumpFileName, lstrlenA(szDumpFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
return(StaticRawMemoryCopyExW(hFile, RawAddressToCopy, Size, uniFileName));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL StaticRawMemoryCopyExW(HANDLE hFile, DWORD RawAddressToCopy, DWORD Size, wchar_t* szDumpFileName)
{
DWORD SizeToRead;
HANDLE hReadFile;
HANDLE hWriteFile;
LPVOID ueCopyBuffer;
DWORD rfNumberOfBytesRead;
if(DuplicateHandle(GetCurrentProcess(), hFile, GetCurrentProcess(), &hReadFile, NULL, false, DUPLICATE_SAME_ACCESS))
{
if(SetFilePointer(hReadFile, (long)(RawAddressToCopy), NULL, FILE_BEGIN) != INVALID_SET_FILE_POINTER)
{
ueCopyBuffer = VirtualAlloc(NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE);
if(ueCopyBuffer != NULL)
{
if(EngineCreatePathForFileW(szDumpFileName))
{
hWriteFile = CreateFileW(szDumpFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(hWriteFile != INVALID_HANDLE_VALUE)
{
if(Size < 0x1000)
{
SizeToRead = Size;
}
else
{
SizeToRead = 0x1000;
}
while((int)Size > NULL)
{
if(ReadFile(hFile, ueCopyBuffer, SizeToRead, &rfNumberOfBytesRead, NULL) && rfNumberOfBytesRead == SizeToRead)
{
WriteFile(hWriteFile, ueCopyBuffer, SizeToRead, &rfNumberOfBytesRead, NULL);
if(Size > 0x1000)
{
Size = Size - 0x1000;
}
else if(SizeToRead != Size)
{
if(ReadFile(hFile, ueCopyBuffer, Size, &rfNumberOfBytesRead, NULL) && rfNumberOfBytesRead == SizeToRead)
{
WriteFile(hWriteFile, ueCopyBuffer, Size, &rfNumberOfBytesRead, NULL);
}
else
{
WriteFile(hWriteFile, ueCopyBuffer, rfNumberOfBytesRead, &rfNumberOfBytesRead, NULL);
}
SizeToRead = Size;
Size = NULL;
}
else
{
SizeToRead = Size;
Size = NULL;
}
}
else
{
WriteFile(hWriteFile, ueCopyBuffer, rfNumberOfBytesRead, &rfNumberOfBytesRead, NULL);
Size = NULL;
}
}
EngineCloseHandle(hReadFile);
EngineCloseHandle(hWriteFile);
VirtualFree(ueCopyBuffer, NULL, MEM_RELEASE);
return(true);
}
else
{
VirtualFree(ueCopyBuffer, NULL, MEM_RELEASE);
}
}
}
}
EngineCloseHandle(hReadFile);
}
return(false);
}
__declspec(dllexport) bool TITCALL StaticRawMemoryCopyEx64(HANDLE hFile, DWORD64 RawAddressToCopy, DWORD64 Size, char* szDumpFileName)
{
wchar_t uniFileName[MAX_PATH] = {};
if(szDumpFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szDumpFileName, lstrlenA(szDumpFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
return(StaticRawMemoryCopyEx64W(hFile, RawAddressToCopy, Size, uniFileName));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL StaticRawMemoryCopyEx64W(HANDLE hFile, DWORD64 RawAddressToCopy, DWORD64 Size, wchar_t* szDumpFileName)
{
DWORD SizeToRead;
HANDLE hReadFile;
HANDLE hWriteFile;
LPVOID ueCopyBuffer;
DWORD rfNumberOfBytesRead;
long FilePosLow;
long FilePosHigh;
if(DuplicateHandle(GetCurrentProcess(), hFile, GetCurrentProcess(), &hReadFile, NULL, false, DUPLICATE_SAME_ACCESS))
{
FilePosLow = (DWORD)RawAddressToCopy;
RtlMoveMemory(&FilePosHigh, (void*)((ULONG_PTR)(&RawAddressToCopy) + 4), 4);
if(SetFilePointer(hReadFile, FilePosLow, &FilePosHigh, FILE_BEGIN) != INVALID_SET_FILE_POINTER)
{
ueCopyBuffer = VirtualAlloc(NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE);
if(ueCopyBuffer != NULL)
{
if(EngineCreatePathForFileW(szDumpFileName))
{
hWriteFile = CreateFileW(szDumpFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(hWriteFile != INVALID_HANDLE_VALUE)
{
if(Size < 0x1000)
{
SizeToRead = (DWORD)Size;
}
else
{
SizeToRead = 0x1000;
}
while(Size != NULL)
{
if(ReadFile(hFile, ueCopyBuffer, SizeToRead, &rfNumberOfBytesRead, NULL) && rfNumberOfBytesRead == SizeToRead)
{
WriteFile(hWriteFile, ueCopyBuffer, SizeToRead, &rfNumberOfBytesRead, NULL);
if(Size > 0x1000)
{
Size = Size - 0x1000;
}
else if((DWORD64)SizeToRead != Size)
{
if(ReadFile(hFile, ueCopyBuffer, (DWORD)Size, &rfNumberOfBytesRead, NULL) && rfNumberOfBytesRead == SizeToRead)
{
WriteFile(hWriteFile, ueCopyBuffer, (DWORD)Size, &rfNumberOfBytesRead, NULL);
}
else
{
WriteFile(hWriteFile, ueCopyBuffer, rfNumberOfBytesRead, &rfNumberOfBytesRead, NULL);
}
SizeToRead = (DWORD)Size;
Size = NULL;
}
else
{
SizeToRead = (DWORD)Size;
Size = NULL;
}
}
else
{
WriteFile(hWriteFile, ueCopyBuffer, rfNumberOfBytesRead, &rfNumberOfBytesRead, NULL);
Size = NULL;
}
}
EngineCloseHandle(hReadFile);
EngineCloseHandle(hWriteFile);
VirtualFree(ueCopyBuffer, NULL, MEM_RELEASE);
return(true);
}
else
{
VirtualFree(ueCopyBuffer, NULL, MEM_RELEASE);
}
}
}
}
EngineCloseHandle(hReadFile);
}
return(false);
}
__declspec(dllexport) bool TITCALL StaticHashMemory(void* MemoryToHash, DWORD SizeOfMemory, void* HashDigest, bool OutputString, int Algorithm)
{
#define MD5LEN 16
#define SHA1LEN 20
#define HASH_MAX_LENGTH 20
HCRYPTPROV hProv = 0;
HCRYPTHASH hHash = 0;
HANDLE hFile = NULL;
DWORD rgbHash[HASH_MAX_LENGTH / 4];
DWORD cbHash = 0;
DWORD crc32 = -1;
ALG_ID hashAlgo;
if(Algorithm != UE_STATIC_HASH_CRC32)
{
if(!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, NULL)) //CRYPT_VERIFYCONTEXT
{
if(!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET))
{
return(false);
}
}
if(Algorithm == UE_STATIC_HASH_MD5)
{
hashAlgo = CALG_MD5;
}
else
{
hashAlgo = CALG_SHA;
}
if(!CryptCreateHash(hProv, hashAlgo, NULL, NULL, &hHash))
{
CryptReleaseContext(hProv, NULL);
return(false);
}
else
{
if(!CryptHashData(hHash, (const BYTE*)MemoryToHash, SizeOfMemory, NULL))
{
CryptReleaseContext(hProv, NULL);
CryptDestroyHash(hHash);
return(false);
}
}
if(Algorithm == UE_STATIC_HASH_MD5)
{
cbHash = MD5LEN;
if(!CryptGetHashParam(hHash, HP_HASHVAL, (BYTE*)&rgbHash[0], &cbHash, NULL))
{
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, NULL);
return(false);
}
else
{
rgbHash[0] = _byteswap_ulong(rgbHash[0]);
rgbHash[1] = _byteswap_ulong(rgbHash[1]);
rgbHash[2] = _byteswap_ulong(rgbHash[2]);
rgbHash[3] = _byteswap_ulong(rgbHash[3]);
__try
{
if(OutputString)
{
wsprintfA((char*)HashDigest, "%08X%08X%08X%08X", rgbHash[0], rgbHash[1], rgbHash[2], rgbHash[3]);
}
else
{
RtlMoveMemory(HashDigest, &rgbHash[0], MD5LEN / 4);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, NULL);
return(false);
}
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, NULL);
return(true);
}
}
else if(Algorithm == UE_STATIC_HASH_SHA1)
{
cbHash = SHA1LEN;
if(!CryptGetHashParam(hHash, HP_HASHVAL, (BYTE*)&rgbHash[0], &cbHash, NULL))
{
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, NULL);
return(false);
}
else
{
rgbHash[0] = _byteswap_ulong(rgbHash[0]);
rgbHash[1] = _byteswap_ulong(rgbHash[1]);
rgbHash[2] = _byteswap_ulong(rgbHash[2]);
rgbHash[3] = _byteswap_ulong(rgbHash[3]);
rgbHash[4] = _byteswap_ulong(rgbHash[4]);
__try
{
if(OutputString)
{
wsprintfA((char*)HashDigest, "%08X%08X%08X%08X%08X", rgbHash[0], rgbHash[1], rgbHash[2], rgbHash[3], rgbHash[4]);
}
else
{
RtlMoveMemory(HashDigest, &rgbHash[0], SHA1LEN / 4);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, NULL);
return(false);
}
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, NULL);
return(true);
}
}
}
else
{
EngineCrc32PartialCRC(&crc32, (unsigned char*)MemoryToHash, (unsigned long)SizeOfMemory);
crc32 = crc32 ^ 0xFFFFFFFF;
if(OutputString)
{
wsprintfA((char*)HashDigest, "%08X", crc32);
}
else
{
RtlMoveMemory(HashDigest, &crc32, sizeof crc32);
}
return(true);
}
return(false);
}
__declspec(dllexport) bool TITCALL StaticHashFile(char* szFileName, char* HashDigest, bool OutputString, int Algorithm)
{
wchar_t uniFileName[MAX_PATH] = {};
if(szFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
return(StaticHashFileW(uniFileName, HashDigest, OutputString, Algorithm));
}
else
{
return(false);
}
}
__declspec(dllexport) bool TITCALL StaticHashFileW(wchar_t* szFileName, char* HashDigest, bool OutputString, int Algorithm)
{
#define MD5LEN 16
#define SHA1LEN 20
#define HASH_MAX_LENGTH 20
bool bResult = true;
HCRYPTPROV hProv = 0;
HCRYPTHASH hHash = 0;
HANDLE hFile = NULL;
BYTE rgbFile[1024];
DWORD cbRead = 0;
DWORD rgbHash[HASH_MAX_LENGTH / 4];
DWORD cbHash = 0;
DWORD crc32 = -1;
ALG_ID hashAlgo;
hFile = CreateFileW(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if(hFile == INVALID_HANDLE_VALUE || HashDigest == NULL)
{
return(false);
}
if(Algorithm != UE_STATIC_HASH_CRC32)
{
if(!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, NULL)) //CRYPT_VERIFYCONTEXT
{
if(!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET))
{
CloseHandle(hFile);
return(false);
}
}
if(Algorithm == UE_STATIC_HASH_MD5)
{
hashAlgo = CALG_MD5;
}
else
{
hashAlgo = CALG_SHA;
}
if(!CryptCreateHash(hProv, hashAlgo, NULL, NULL, &hHash))
{
CloseHandle(hFile);
CryptReleaseContext(hProv, NULL);
return(false);
}
while(bResult)
{
if(!ReadFile(hFile, rgbFile, 1024, &cbRead, NULL))
{
bResult = false;
}
else if(cbRead == NULL)
{
break;
}
if(!CryptHashData(hHash, rgbFile, cbRead, NULL))
{
CryptReleaseContext(hProv, NULL);
CryptDestroyHash(hHash);
CloseHandle(hFile);
return(false);
}
}
if(!bResult)
{
CryptReleaseContext(hProv, NULL);
CryptDestroyHash(hHash);
CloseHandle(hFile);
return(false);
}
if(Algorithm == UE_STATIC_HASH_MD5)
{
cbHash = MD5LEN;
if(!CryptGetHashParam(hHash, HP_HASHVAL, (BYTE*)&rgbHash[0], &cbHash, NULL))
{
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, NULL);
CloseHandle(hFile);
return(false);
}
else
{
rgbHash[0] = _byteswap_ulong(rgbHash[0]);
rgbHash[1] = _byteswap_ulong(rgbHash[1]);
rgbHash[2] = _byteswap_ulong(rgbHash[2]);
rgbHash[3] = _byteswap_ulong(rgbHash[3]);
__try
{
if(OutputString)
{
wsprintfA(HashDigest, "%08X%08X%08X%08X", rgbHash[0], rgbHash[1], rgbHash[2], rgbHash[3]);
}
else
{
RtlMoveMemory(HashDigest, &rgbHash[0], MD5LEN / 4);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, NULL);
CloseHandle(hFile);
return(false);
}
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, NULL);
CloseHandle(hFile);
return(true);
}
}
else if(Algorithm == UE_STATIC_HASH_SHA1)
{
cbHash = SHA1LEN;
if(!CryptGetHashParam(hHash, HP_HASHVAL, (BYTE*)&rgbHash[0], &cbHash, NULL))
{
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, NULL);
CloseHandle(hFile);
return(false);
}
else
{
rgbHash[0] = _byteswap_ulong(rgbHash[0]);
rgbHash[1] = _byteswap_ulong(rgbHash[1]);
rgbHash[2] = _byteswap_ulong(rgbHash[2]);
rgbHash[3] = _byteswap_ulong(rgbHash[3]);
rgbHash[4] = _byteswap_ulong(rgbHash[4]);
__try
{
if(OutputString)
{
wsprintfA(HashDigest, "%08X%08X%08X%08X%08X", rgbHash[0], rgbHash[1], rgbHash[2], rgbHash[3], rgbHash[4]);
}
else
{
RtlMoveMemory(HashDigest, &rgbHash[0], SHA1LEN / 4);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, NULL);
CloseHandle(hFile);
return(false);
}
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, NULL);
CloseHandle(hFile);
return(true);
}
}
}
else
{
while(bResult)
{
if(!ReadFile(hFile, rgbFile, 1024, &cbRead, NULL))
{
bResult = false;
}
else if(cbRead == NULL)
{
break;
}
EngineCrc32PartialCRC(&crc32, (unsigned char*)&rgbFile[0], cbRead);
}
crc32 = crc32 ^ 0xFFFFFFFF;
if(OutputString)
{
wsprintfA(HashDigest, "%08X", crc32);
}
else
{
RtlMoveMemory(HashDigest, &crc32, sizeof crc32);
}
CloseHandle(hFile);
return(true);
}
CloseHandle(hFile);
return(false);
}
// TitanEngine.Engine.functions:
__declspec(dllexport) void TITCALL SetEngineVariable(DWORD VariableId, bool VariableSet)
{
if(VariableId == UE_ENGINE_ALOW_MODULE_LOADING)
{
engineAlowModuleLoading = VariableSet;
}
else if(VariableId == UE_ENGINE_AUTOFIX_FORWARDERS)
{
engineCheckForwarders = VariableSet;
}
else if(VariableId == UE_ENGINE_PASS_ALL_EXCEPTIONS)
{
enginePassAllExceptions = VariableSet;
}
else if(VariableId == UE_ENGINE_NO_CONSOLE_WINDOW)
{
engineRemoveConsoleForDebugee = VariableSet;
}
else if(VariableId == UE_ENGINE_BACKUP_FOR_CRITICAL_FUNCTIONS)
{
engineBackupForCriticalFunctions = VariableSet;
}
else if(VariableId == UE_ENGINE_RESET_CUSTOM_HANDLER)
{
engineResetCustomHandler = VariableSet;
}
else if(VariableId == UE_ENGINE_CALL_PLUGIN_DEBUG_CALLBACK)
{
engineExecutePluginCallBack = VariableSet;
}
}
// Global.Engine.Hook.functions:
void EngineFakeLoadLibraryReturn()
{
ULONG_PTR ParameterData;
LPDEBUG_EVENT currentDBGEvent;
HANDLE currentProcess;
currentDBGEvent = (LPDEBUG_EVENT)GetDebugData();
currentProcess = dbgProcessInformation.hProcess;
if(currentProcess != NULL)
{
#if !defined(_WIN64)
ParameterData = (ULONG_PTR)GetFunctionParameter(currentProcess, UE_FUNCTION_STDCALL_RET, 1, UE_PARAMETER_DWORD);
if(ParameterData != NULL)
{
if(engineFakeDLLHandle != NULL)
{
SetContextData(UE_EAX, engineFakeDLLHandle);
}
else
{
SetContextData(UE_EAX, 0x10000000);
}
}
#else
ParameterData = (ULONG_PTR)GetFunctionParameter(currentProcess, UE_FUNCTION_FASTCALL, 1, UE_PARAMETER_QWORD);
if(ParameterData != NULL)
{
if(engineFakeDLLHandle != NULL)
{
SetContextData(UE_RAX, engineFakeDLLHandle);
}
else
{
SetContextData(UE_RAX, 0x10000000);
}
}
#endif
}
}
void EngineFakeGetProcAddressReturn()
{
ULONG_PTR ParameterData;
LPDEBUG_EVENT currentDBGEvent;
HANDLE currentProcess;
currentDBGEvent = (LPDEBUG_EVENT)GetDebugData();
currentProcess = dbgProcessInformation.hProcess;
if(currentProcess != NULL)
{
#if !defined(_WIN64)
ParameterData = (ULONG_PTR)GetFunctionParameter(currentProcess, UE_FUNCTION_STDCALL_RET, 1, UE_PARAMETER_DWORD);
if(ParameterData != NULL)
{
SetContextData(UE_EAX, (ULONG_PTR)ImporterGetRemoteAPIAddress(currentProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "ExitProcess")));
}
#else
ParameterData = (ULONG_PTR)GetFunctionParameter(currentProcess, UE_FUNCTION_FASTCALL, 1, UE_PARAMETER_QWORD);
if(ParameterData != NULL)
{
SetContextData(UE_RAX, (ULONG_PTR)ImporterGetRemoteAPIAddress(currentProcess, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "ExitProcess")));
}
#endif
}
}
// Global.TitanEngine.Engine.functions:
bool EngineGetFileDialog(char* GlobalBuffer)
{
OPENFILENAMEA sOpenFileName;
char szFilterString[] = "All Files \0*.*\0\0";
char szDialogTitle[] = "TitanEngine2 from Reversing Labs";
RtlZeroMemory(&sOpenFileName, sizeof(OPENFILENAMEA));
sOpenFileName.lStructSize = sizeof(OPENFILENAMEA);
sOpenFileName.lpstrFilter = &szFilterString[0];
sOpenFileName.lpstrFile = &GlobalBuffer[0];
sOpenFileName.nMaxFile = 1024;
sOpenFileName.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_LONGNAMES | OFN_EXPLORER | OFN_HIDEREADONLY;
sOpenFileName.lpstrTitle = &szDialogTitle[0];
if(!GetOpenFileNameA(&sOpenFileName))
{
RtlZeroMemory(&GlobalBuffer[0], 1024);
return(false);
}
else
{
return(true);
}
}
long EngineWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
char szAboutTitle[] = "[ About ]";
char szAboutText[] = "%s \r\n\r\n ReversingLabs - http://www.reversinglabs.com \r\n\r\n Minimum engine version needed:\r\n- TitanEngine %i.%i.%i by RevLabs\r\n\r\nUnpacker coded by %s";
typedef void(TITCALL *fStartUnpacking)(char* szInputFile, bool RealignFile, bool CopyOverlay);
fStartUnpacking myStartUnpacking = (fStartUnpacking)EngineStartUnpackingCallBack;
char GlobalBuffer[1024] = {};
char AboutBuffer[1024] = {};
bool bRealignFile = false;
bool bCopyOverlay = false;
if(uMsg == WM_INITDIALOG)
{
SendMessageA(hwndDlg, WM_SETTEXT, NULL, (LPARAM)&szWindowUnpackerTitle);
SendMessageA(hwndDlg, WM_SETICON, NULL, (LPARAM)LoadIconA((HINSTANCE)engineHandle, MAKEINTRESOURCEA(IDI_ICON2)));
SetDlgItemTextA(hwndDlg, IDD_UNPACKERTITLE, szWindowUnpackerLongTitle);
SetDlgItemTextA(hwndDlg, IDC_FILENAME, "filename.exe");
CheckDlgButton(hwndDlg, IDC_REALING, 1);
EngineWindowHandle = hwndDlg;
}
else if(uMsg == WM_DROPFILES)
{
DragQueryFileA((HDROP)wParam, NULL, GlobalBuffer, 1024);
SetDlgItemTextA(hwndDlg, IDC_FILENAME, GlobalBuffer);
}
else if(uMsg == WM_CLOSE)
{
EndDialog(hwndDlg, NULL);
}
else if(uMsg == WM_COMMAND)
{
if(wParam == IDC_UNPACK)
{
GetDlgItemTextA(hwndDlg, IDC_FILENAME, GlobalBuffer, 1024);
if(!IsFileBeingDebugged() && EngineFileExists(GlobalBuffer))
{
EngineBoxHandle = GetDlgItem(hwndDlg, IDC_LISTBOX);
SendMessageA(EngineBoxHandle, LB_RESETCONTENT, NULL, NULL);
if(IsDlgButtonChecked(EngineWindowHandle, IDC_REALING))
{
bRealignFile = true;
}
if(IsDlgButtonChecked(EngineWindowHandle, IDC_COPYOVERLAY))
{
bCopyOverlay = true;
}
myStartUnpacking(GlobalBuffer, bRealignFile, bCopyOverlay);
}
}
else if(wParam == IDC_BROWSE)
{
if(EngineGetFileDialog(GlobalBuffer))
{
SetDlgItemTextA(hwndDlg, IDC_FILENAME, GlobalBuffer);
}
}
else if(wParam == IDC_ABOUT)
{
wsprintfA(AboutBuffer, szAboutText, szWindowUnpackerName, TE_VER_MAJOR, TE_VER_MIDDLE, TE_VER_MINOR, szWindowUnpackerAuthor);
MessageBoxA(hwndDlg, AboutBuffer, szAboutTitle, MB_ICONASTERISK);
}
else if(wParam == IDC_EXIT)
{
EndDialog(hwndDlg, NULL);
}
}
return(NULL);
}
// Global.Engine.Simplification.functions:
void EngineSimplifyLoadLibraryCallBack()
{
ULONG_PTR iParameter1;
char szLogBufferData[MAX_PATH] = {};
char szReadStringData[MAX_PATH] = {};
ULONG_PTR CurrentBreakAddress = (ULONG_PTR)GetContextData(UE_CIP);
if(!EngineUnpackerFileImporterInit)
{
EngineUnpackerFileImporterInit = true;
if(EngineUnpackerFileStatus.FileIsDLL)
{
ImporterInit(50 * 1024, (ULONG_PTR)GetDebuggedDLLBaseAddress());
}
else
{
ImporterInit(50 * 1024, (ULONG_PTR)GetDebuggedFileBaseAddress());
}
}
for(int i = 0; i < (int)EngineUnpackerBreakInfo.size(); i++)
{
if(EngineUnpackerBreakInfo[i].BreakPointAddress == CurrentBreakAddress)
{
iParameter1 = (ULONG_PTR)GetContextData((DWORD)EngineUnpackerBreakInfo[i].Parameter1);
if(EngineUnpackerBreakInfo[i].SingleBreak)
{
EngineUnpackerBreakInfo.erase(EngineUnpackerBreakInfo.begin() + i);
}
if(GetRemoteString(pEngineUnpackerProcessHandle->hProcess, (void*)iParameter1, &szReadStringData[0], MAX_PATH))
{
ImporterAddNewDll(szReadStringData, (ULONG_PTR)GetContextData((DWORD)EngineUnpackerBreakInfo[i].Parameter2));
if(EngineUnpackerOptionLogData)
{
wsprintfA(szLogBufferData,"[x] LoadLibrary BPX -> %s",szReadStringData);
EngineAddUnpackerWindowLogMessage(szLogBufferData);
}
}
break;
}
}
}
void EngineSimplifyGetProcAddressCallBack()
{
ULONG_PTR iParameter1;
char szLogBufferData[MAX_PATH] = {};
char szReadStringData[MAX_PATH] = {};
ULONG_PTR CurrentBreakAddress = (ULONG_PTR)GetContextData(UE_CIP);
for(int i = 0; i < (int)EngineUnpackerBreakInfo.size(); i++)
{
if(EngineUnpackerBreakInfo[i].BreakPointAddress == CurrentBreakAddress)
{
iParameter1 = (ULONG_PTR)GetContextData((DWORD)EngineUnpackerBreakInfo[i].Parameter1);
if(EngineUnpackerBreakInfo[i].SingleBreak)
{
EngineUnpackerBreakInfo.erase(EngineUnpackerBreakInfo.begin() + i);
}
if(EngineUnpackerFileStatus.FileIsDLL)
{
if(iParameter1 > (ULONG_PTR)GetDebuggedDLLBaseAddress())
{
if(GetRemoteString(pEngineUnpackerProcessHandle->hProcess, (void*)iParameter1, &szReadStringData[0], MAX_PATH))
{
ImporterAddNewAPI(szReadStringData, (ULONG_PTR)GetContextData((DWORD)EngineUnpackerBreakInfo[i].Parameter2));
if(EngineUnpackerOptionLogData)
{
wsprintfA(szLogBufferData,"[x] GetProcAddress BPX -> %s",szReadStringData);
EngineAddUnpackerWindowLogMessage(szLogBufferData);
}
}
}
else
{
ImporterAddNewOrdinalAPI(iParameter1, (ULONG_PTR)GetContextData((DWORD)EngineUnpackerBreakInfo[i].Parameter2));
if(EngineUnpackerOptionLogData)
{
wsprintfA(szLogBufferData,"[x] GetProcAddress BPX -> %08X",iParameter1);
EngineAddUnpackerWindowLogMessage(szLogBufferData);
}
}
}
else
{
if(iParameter1 > (ULONG_PTR)GetDebuggedFileBaseAddress())
{
if(GetRemoteString(pEngineUnpackerProcessHandle->hProcess, (void*)iParameter1, &szReadStringData[0], MAX_PATH))
{
ImporterAddNewAPI(szReadStringData, (ULONG_PTR)GetContextData((DWORD)EngineUnpackerBreakInfo[i].Parameter2));
if(EngineUnpackerOptionLogData)
{
wsprintfA(szLogBufferData,"[x] GetProcAddress BPX -> %s",szReadStringData);
EngineAddUnpackerWindowLogMessage(szLogBufferData);
}
}
}
else
{
ImporterAddNewOrdinalAPI(iParameter1, (ULONG_PTR)GetContextData((DWORD)EngineUnpackerBreakInfo[i].Parameter2));
if(EngineUnpackerOptionLogData)
{
wsprintfA(szLogBufferData,"[x] GetProcAddress BPX -> %08X",iParameter1);
EngineAddUnpackerWindowLogMessage(szLogBufferData);
}
}
}
break;
}
}
}
void EngineSimplifyMakeSnapshotCallBack()
{
ULONG_PTR fdLoadedBase;
wchar_t szTempName[MAX_PATH] = {};
wchar_t szTempFolder[MAX_PATH] = {};
ULONG_PTR CurrentBreakAddress = (ULONG_PTR)GetContextData(UE_CIP);
if(EngineUnpackerFileStatus.FileIsDLL)
{
fdLoadedBase = (ULONG_PTR)GetDebuggedDLLBaseAddress();
}
else
{
fdLoadedBase = (ULONG_PTR)GetDebuggedFileBaseAddress();
}
for(int i = 0; i < (int)EngineUnpackerBreakInfo.size(); i++)
{
if(EngineUnpackerBreakInfo[i].BreakPointAddress == CurrentBreakAddress)
{
if(EngineUnpackerBreakInfo[i].SnapShotNumber == 1)
{
if(GetTempPathW(MAX_PATH, szTempFolder) < MAX_PATH)
{
if(GetTempFileNameW(szTempFolder, L"OverlayTemp", GetTickCount() + 101, szTempName))
{
lstrcpyW(szEngineUnpackerSnapShot1, szTempName);
RelocaterMakeSnapshotW(pEngineUnpackerProcessHandle->hProcess, szEngineUnpackerSnapShot1, (void*)(EngineUnpackerBreakInfo[i].Parameter1 + fdLoadedBase), EngineUnpackerBreakInfo[i].Parameter2);
}
}
}
else
{
if(GetTempPathW(MAX_PATH, szTempFolder) < MAX_PATH)
{
if(GetTempFileNameW(szTempFolder, L"OverlayTemp", GetTickCount() + 201, szTempName))
{
lstrcpyW(szEngineUnpackerSnapShot2, szTempName);
RelocaterMakeSnapshotW(pEngineUnpackerProcessHandle->hProcess, szEngineUnpackerSnapShot2, (void*)(EngineUnpackerBreakInfo[i].Parameter1 + fdLoadedBase), EngineUnpackerBreakInfo[i].Parameter2);
}
}
}
return;
}
}
}
void EngineSimplifyEntryPointCallBack()
{
int i = 0;
int j = 0;
DWORD FileSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
HANDLE FileHandle;
long mImportTableOffset;
long mRelocTableOffset;
DWORD pOverlayStart;
DWORD pOverlaySize;
ULONG_PTR fdLoadedBase;
char szLogBufferData[MAX_PATH] = {};
wchar_t szTempFolder[MAX_PATH] = {};
wchar_t szTempName[MAX_PATH] = {};
__try
{
if(EngineUnpackerOptionUnpackedOEP == NULL)
{
EngineUnpackerOptionUnpackedOEP = (ULONG_PTR)GetContextData(UE_CIP);
}
if(EngineUnpackerOptionLogData)
{
wsprintfA(szLogBufferData,"[x] Entry Point at: %08X", EngineUnpackerOptionUnpackedOEP);
EngineAddUnpackerWindowLogMessage(szLogBufferData);
}
if(EngineUnpackerFileStatus.FileIsDLL)
{
fdLoadedBase = (ULONG_PTR)GetDebuggedDLLBaseAddress();
RelocaterInit(100 * 1024, (ULONG_PTR)GetPE32DataW(szEngineUnpackerInputFile, NULL, UE_IMAGEBASE), fdLoadedBase);
for(i = 0; i < (int)EngineUnpackerBreakInfo.size(); i++)
{
if(EngineUnpackerBreakInfo[i].SnapShotNumber == 1)
{
j = i;
}
}
if(szEngineUnpackerSnapShot2[0] == 0x00)
{
if(GetTempPathW(MAX_PATH, szTempFolder) < MAX_PATH)
{
if(GetTempFileNameW(szTempFolder, L"OverlayTemp", GetTickCount() + 301, szTempName))
{
lstrcpyW(szEngineUnpackerSnapShot2, szTempName);
RelocaterMakeSnapshotW(pEngineUnpackerProcessHandle->hProcess, szEngineUnpackerSnapShot2, (void*)(EngineUnpackerBreakInfo[j].Parameter1 + fdLoadedBase), EngineUnpackerBreakInfo[j].Parameter2);
}
}
}
RelocaterCompareTwoSnapshotsW(pEngineUnpackerProcessHandle->hProcess, fdLoadedBase, (ULONG_PTR)GetPE32DataW(szEngineUnpackerInputFile, NULL, UE_SIZEOFIMAGE), szEngineUnpackerSnapShot1, szEngineUnpackerSnapShot2, EngineUnpackerBreakInfo[j].Parameter1 + fdLoadedBase);
EngineUnpackerOptionRelocationFix = true;
}
else
{
fdLoadedBase = (ULONG_PTR)GetDebuggedFileBaseAddress();
}
if(PastePEHeaderW(pEngineUnpackerProcessHandle->hProcess, (void*)fdLoadedBase, szEngineUnpackerInputFile))
{
if(EngineUnpackerOptionLogData)
{
EngineAddUnpackerWindowLogMessage("[x] Paste PE header");
}
}
DumpProcessW(pEngineUnpackerProcessHandle->hProcess, (void*)fdLoadedBase, szEngineUnpackerOutputFile, EngineUnpackerOptionUnpackedOEP);
if(EngineUnpackerOptionLogData)
{
EngineAddUnpackerWindowLogMessage("[x] Process dumped!");
}
mImportTableOffset = AddNewSectionW(szEngineUnpackerOutputFile, ".TEv2", ImporterEstimatedSize() + 200) + (DWORD)fdLoadedBase;
if(EngineUnpackerOptionRelocationFix)
{
if(EngineUnpackerFileStatus.FileIsDLL)
{
mRelocTableOffset = AddNewSectionW(szEngineUnpackerOutputFile, ".TEv2", RelocaterEstimatedSize() + 200);
}
}
if(StaticFileLoadW(szEngineUnpackerOutputFile, UE_ACCESS_ALL, false, &FileHandle, &FileSize, &FileMap, &FileMapVA))
{
if(ImporterExportIAT((ULONG_PTR)ConvertVAtoFileOffset(FileMapVA, mImportTableOffset, true), FileMapVA))
{
if(EngineUnpackerOptionLogData)
{
EngineAddUnpackerWindowLogMessage("[x] IAT has been fixed!");
}
}
if(EngineUnpackerOptionRelocationFix)
{
if(EngineUnpackerFileStatus.FileIsDLL)
{
RelocaterExportRelocation((ULONG_PTR)ConvertVAtoFileOffset(FileMapVA, mRelocTableOffset + fdLoadedBase, true), mRelocTableOffset, FileMapVA);
if(EngineUnpackerOptionLogData)
{
EngineAddUnpackerWindowLogMessage("[x] Exporting relocations!");
}
}
}
if(EngineUnpackerOptionRealingFile)
{
FileSize = RealignPE(FileMapVA, FileSize, 2);
if(EngineUnpackerOptionLogData)
{
EngineAddUnpackerWindowLogMessage("[x] Realigning file!");
}
}
StaticFileUnloadW(szEngineUnpackerOutputFile, false, FileHandle, FileSize, FileMap, FileMapVA);
MakeAllSectionsRWEW(szEngineUnpackerOutputFile);
if(EngineUnpackerFileStatus.FileIsDLL)
{
if(RelocaterChangeFileBaseW(szEngineUnpackerOutputFile, (ULONG_PTR)GetPE32DataW(szEngineUnpackerInputFile, NULL, UE_IMAGEBASE)))
{
if(EngineUnpackerOptionLogData)
{
EngineAddUnpackerWindowLogMessage("[x] Rebase file image!");
}
}
}
if(EngineUnpackerOptionMoveOverlay && FindOverlayW(szEngineUnpackerInputFile, &pOverlayStart, &pOverlaySize))
{
CopyOverlayW(szEngineUnpackerInputFile, szEngineUnpackerOutputFile);
if(EngineUnpackerOptionLogData)
{
EngineAddUnpackerWindowLogMessage("[x] Moving overlay to unpacked file!");
}
}
StopDebug();
if(EngineUnpackerOptionLogData)
{
EngineAddUnpackerWindowLogMessage("[Success] File has been unpacked!");
}
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
ForceClose();
ImporterCleanup();
if(FileMapVA > NULL)
{
StaticFileUnloadW(szEngineUnpackerOutputFile, false, FileHandle, FileSize, FileMap, FileMapVA);
}
DeleteFileW(szEngineUnpackerOutputFile);
if(EngineUnpackerOptionLogData)
{
EngineAddUnpackerWindowLogMessage("[Fatal Unpacking Error] Please mail file you tried to unpack to ReversingLabs Corporation!");
}
}
if(EngineUnpackerOptionLogData)
{
EngineAddUnpackerWindowLogMessage("-> Unpack ended...");
}
}
// TitanEngine.Engine.Simplification.functions:
__declspec(dllexport) void TITCALL EngineUnpackerInitialize(char* szFileName, char* szUnpackedFileName, bool DoLogData, bool DoRealignFile, bool DoMoveOverlay, void* EntryCallBack)
{
wchar_t uniFileName[MAX_PATH] = {};
wchar_t uniUnpackedFileName[MAX_PATH] = {};
if(szFileName != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
if(szUnpackedFileName == NULL)
{
return(EngineUnpackerInitializeW(uniFileName, NULL, DoLogData, DoRealignFile, DoMoveOverlay, EntryCallBack));
}
else
{
MultiByteToWideChar(CP_ACP, NULL, szUnpackedFileName, lstrlenA(szUnpackedFileName)+1, uniUnpackedFileName, sizeof(uniUnpackedFileName)/(sizeof(uniUnpackedFileName[0])));
EngineUnpackerInitializeW(uniFileName, uniUnpackedFileName, DoLogData, DoRealignFile, DoMoveOverlay, EntryCallBack);
}
}
}
__declspec(dllexport) void TITCALL EngineUnpackerInitializeW(wchar_t* szFileName, wchar_t* szUnpackedFileName, bool DoLogData, bool DoRealignFile, bool DoMoveOverlay, void* EntryCallBack)
{
int i,j;
wchar_t TempBackBuffer[MAX_PATH] = {};
if(szFileName != NULL)
{
RtlZeroMemory(&szEngineUnpackerSnapShot1[0], MAX_PATH * 2);
RtlZeroMemory(&szEngineUnpackerSnapShot2[0], MAX_PATH * 2);
RtlZeroMemory(&EngineUnpackerFileStatus, sizeof FILE_STATUS_INFO);
if(IsPE32FileValidExW(szFileName, UE_DEPTH_DEEP, &EngineUnpackerFileStatus))
{
if(!EngineUnpackerFileStatus.FileIsDLL)
{
pEngineUnpackerProcessHandle = (LPPROCESS_INFORMATION)InitDebugExW(szFileName, NULL, NULL, EntryCallBack);
}
else
{
pEngineUnpackerProcessHandle = (LPPROCESS_INFORMATION)InitDLLDebugW(szFileName, true, NULL, NULL, EntryCallBack);
}
if(pEngineUnpackerProcessHandle != NULL)
{
lstrcpyW(szEngineUnpackerInputFile, szFileName);
if(szUnpackedFileName != NULL)
{
lstrcpyW(szEngineUnpackerOutputFile, szUnpackedFileName);
}
else
{
lstrcpyW(TempBackBuffer, szFileName);
i = lstrlenW(TempBackBuffer);
while(TempBackBuffer[i] != 0x2E)
{
i--;
}
TempBackBuffer[i] = 0x00;
j = i + 1;
wsprintfW(szEngineUnpackerOutputFile, L"%s.unpacked.%s", &TempBackBuffer[0], &TempBackBuffer[j]);
}
EngineUnpackerOptionRealingFile = DoRealignFile;
EngineUnpackerOptionMoveOverlay = DoMoveOverlay;
EngineUnpackerOptionRelocationFix = false;
EngineUnpackerOptionLogData = DoLogData;
EngineUnpackerOptionUnpackedOEP = NULL;
EngineUnpackerFileImporterInit = false;
if(EngineUnpackerOptionLogData)
{
EngineAddUnpackerWindowLogMessage("-> Unpack started...");
}
EngineUnpackerBreakInfo.clear();
DebugLoop();
}
}
}
}
__declspec(dllexport) bool TITCALL EngineUnpackerSetBreakCondition(void* SearchStart, DWORD SearchSize, void* SearchPattern, DWORD PatternSize, DWORD PatternDelta, ULONG_PTR BreakType, bool SingleBreak, DWORD Parameter1, DWORD Parameter2)
{
ULONG_PTR fPatternLocation;
DWORD fBreakPointType = UE_BREAKPOINT;
UnpackerInformation fUnpackerInformation = {};
if((int)SearchStart == UE_UNPACKER_CONDITION_SEARCH_FROM_EP)
{
if(EngineUnpackerFileStatus.FileIsDLL)
{
SearchStart = (void*)((ULONG_PTR)GetPE32DataW(szEngineUnpackerInputFile, NULL, UE_OEP) + (ULONG_PTR)GetDebuggedDLLBaseAddress());
}
else
{
SearchStart = (void*)((ULONG_PTR)GetPE32DataW(szEngineUnpackerInputFile, NULL, UE_OEP) + (ULONG_PTR)GetDebuggedFileBaseAddress());
}
}
if(SearchSize == NULL)
{
SearchSize = 0x1000;
}
fPatternLocation = (ULONG_PTR)FindEx(pEngineUnpackerProcessHandle->hProcess, SearchStart, SearchSize, SearchPattern, PatternSize, NULL);
if(fPatternLocation != NULL)
{
if(SingleBreak)
{
fBreakPointType = UE_SINGLESHOOT;
}
fPatternLocation = fPatternLocation + (int)PatternDelta;
fUnpackerInformation.Parameter1 = Parameter1;
fUnpackerInformation.Parameter2 = Parameter2;
fUnpackerInformation.SingleBreak = SingleBreak;
fUnpackerInformation.BreakPointAddress = fPatternLocation;
if(BreakType == UE_UNPACKER_CONDITION_LOADLIBRARY)
{
if(SetBPX(fPatternLocation, UE_BREAKPOINT, &EngineSimplifyLoadLibraryCallBack))
{
EngineUnpackerBreakInfo.push_back(fUnpackerInformation);
return(true);
}
}
else if(BreakType == UE_UNPACKER_CONDITION_GETPROCADDRESS)
{
if(SetBPX(fPatternLocation, UE_BREAKPOINT, &EngineSimplifyGetProcAddressCallBack))
{
EngineUnpackerBreakInfo.push_back(fUnpackerInformation);
return(true);
}
}
else if(BreakType == UE_UNPACKER_CONDITION_ENTRYPOINTBREAK)
{
if(SetBPX(fPatternLocation, UE_BREAKPOINT, &EngineSimplifyGetProcAddressCallBack))
{
EngineUnpackerBreakInfo.push_back(fUnpackerInformation);
return(true);
}
}
else if(BreakType == UE_UNPACKER_CONDITION_RELOCSNAPSHOT1)
{
if(SetBPX(fPatternLocation, UE_BREAKPOINT, &EngineSimplifyMakeSnapshotCallBack))
{
fUnpackerInformation.SnapShotNumber = 1;
EngineUnpackerBreakInfo.push_back(fUnpackerInformation);
return(true);
}
}
else if(BreakType == UE_UNPACKER_CONDITION_RELOCSNAPSHOT2)
{
if(SetBPX(fPatternLocation, UE_BREAKPOINT, &EngineSimplifyMakeSnapshotCallBack))
{
fUnpackerInformation.SnapShotNumber = 2;
EngineUnpackerBreakInfo.push_back(fUnpackerInformation);
return(true);
}
}
else
{
if(SetBPX(fPatternLocation, fBreakPointType, (void*)BreakType))
{
EngineUnpackerBreakInfo.push_back(fUnpackerInformation);
return(true);
}
}
}
return(false);
}
__declspec(dllexport) void TITCALL EngineUnpackerSetEntryPointAddress(ULONG_PTR UnpackedEntryPointAddress)
{
EngineUnpackerOptionUnpackedOEP = UnpackedEntryPointAddress;
}
__declspec(dllexport) void TITCALL EngineUnpackerFinalizeUnpacking()
{
EngineSimplifyEntryPointCallBack();
EmptyGarbage();
}
// TitanEngine.Engine.functions:
__declspec(dllexport) bool TITCALL EngineCreateMissingDependencies(char* szFileName, char* szOutputFolder, bool LogCreatedFiles)
{
wchar_t uniFileName[MAX_PATH] = {};
wchar_t uniOutputFolder[MAX_PATH] = {};
if(szFileName != NULL && szOutputFolder != NULL)
{
MultiByteToWideChar(CP_ACP, NULL, szFileName, lstrlenA(szFileName)+1, uniFileName, sizeof(uniFileName)/(sizeof(uniFileName[0])));
MultiByteToWideChar(CP_ACP, NULL, szOutputFolder, lstrlenA(szOutputFolder)+1, uniOutputFolder, sizeof(uniOutputFolder)/(sizeof(uniOutputFolder[0])));
return(EngineCreateMissingDependenciesW(uniFileName, uniOutputFolder, LogCreatedFiles));
}
else
{
return(NULL);
}
}
__declspec(dllexport) bool TITCALL EngineCreateMissingDependenciesW(wchar_t* szFileName, wchar_t* szOutputFolder, bool LogCreatedFiles)
{
char* ImportDllName;
wchar_t ImportDllNameW[512];
wchar_t BuildExportName[512];
PIMAGE_THUNK_DATA32 ImportThunkX86;
PIMAGE_THUNK_DATA64 ImportThunkX64;
PIMAGE_IMPORT_DESCRIPTOR ImportPointer;
ULONG_PTR ImportTableAddress = NULL;
ULONG_PTR ImportThunkName = NULL;
DWORD ImportThunkAddress = NULL;
ULONG_PTR ImageBase = NULL;
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
HANDLE FileHandle;
DWORD FileSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
BOOL FileIs64;
if(MapFileExW(szFileName, UE_ACCESS_READ, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(DOSHeader->e_lfanew < 0x1000 - 108)
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
if(LogCreatedFiles)
{
if(engineDependencyFiles != NULL)
{
VirtualFree(engineDependencyFiles, NULL, MEM_RELEASE);
}
engineDependencyFiles = VirtualAlloc(NULL, 20 * 1024, MEM_COMMIT, PAGE_READWRITE);
engineDependencyFilesCWP = engineDependencyFiles;
}
if(!FileIs64)
{
ImageBase = (ULONG_PTR)PEHeader32->OptionalHeader.ImageBase;
ImportTableAddress = (ULONG_PTR)PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
ImportTableAddress = (ULONG_PTR)ConvertVAtoFileOffset(FileMapVA, ImportTableAddress + ImageBase, true);
ImportPointer = (PIMAGE_IMPORT_DESCRIPTOR)ImportTableAddress;
while(ImportPointer->FirstThunk != NULL)
{
ImportDllName = (PCHAR)((ULONG_PTR)ConvertVAtoFileOffset(FileMapVA, ImportPointer->Name + ImageBase, true));
MultiByteToWideChar(CP_ACP, NULL, ImportDllName, lstrlenA(ImportDllName)+1, ImportDllNameW, sizeof(ImportDllNameW)/(sizeof(ImportDllNameW[0])));
if(!EngineIsDependencyPresentW(ImportDllNameW, szFileName, szOutputFolder))
{
RtlZeroMemory(&BuildExportName, 512);
lstrcatW(BuildExportName, szOutputFolder);
if(BuildExportName[lstrlenW(BuildExportName)-1] != 0x5C)
{
BuildExportName[lstrlenW(BuildExportName)] = 0x5C;
}
lstrcatW(BuildExportName, ImportDllNameW);
if(LogCreatedFiles)
{
RtlMoveMemory(engineDependencyFilesCWP, &BuildExportName, lstrlenW(BuildExportName) * 2);
engineDependencyFilesCWP = (LPVOID)((ULONG_PTR)engineDependencyFilesCWP + (lstrlenW(BuildExportName) * 2) + 2);
}
EngineExtractResource("MODULEx86", BuildExportName);
ExporterInit(20 * 1024, (ULONG_PTR)GetPE32DataW(BuildExportName, NULL, UE_IMAGEBASE), NULL, ImportDllName);
ImportThunkAddress = ImportPointer->FirstThunk;
if(ImportPointer->OriginalFirstThunk != NULL)
{
ImportThunkX86 = (PIMAGE_THUNK_DATA32)((ULONG_PTR)ConvertVAtoFileOffset(FileMapVA, ImportPointer->OriginalFirstThunk + ImageBase, true));
}
else
{
ImportThunkX86 = (PIMAGE_THUNK_DATA32)((ULONG_PTR)ConvertVAtoFileOffset(FileMapVA, ImportPointer->FirstThunk + ImageBase, true));
}
while(ImportThunkX86->u1.Function != NULL)
{
if(ImportThunkX86->u1.Ordinal & IMAGE_ORDINAL_FLAG32)
{
ExporterAddNewOrdinalExport(ImportThunkX86->u1.Ordinal ^ IMAGE_ORDINAL_FLAG32, 0x1000);
}
else
{
ImportThunkName = (ULONG_PTR)(ConvertVAtoFileOffset(FileMapVA, ImportThunkX86->u1.AddressOfData + ImageBase, true) + 2);
ExporterAddNewExport((PCHAR)ImportThunkName, 0x1000);
}
ImportThunkX86 = (PIMAGE_THUNK_DATA32)((ULONG_PTR)ImportThunkX86 + 4);
ImportThunkAddress = ImportThunkAddress + 4;
}
ExporterBuildExportTableExW(BuildExportName, ".export");
}
ImportPointer = (PIMAGE_IMPORT_DESCRIPTOR)((ULONG_PTR)ImportPointer + sizeof IMAGE_IMPORT_DESCRIPTOR);
}
}
else
{
ImageBase = (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase;
ImportTableAddress = (ULONG_PTR)PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
ImportTableAddress = (ULONG_PTR)ConvertVAtoFileOffset(FileMapVA, ImportTableAddress + ImageBase, true);
ImportPointer = (PIMAGE_IMPORT_DESCRIPTOR)ImportTableAddress;
while(ImportPointer->FirstThunk != NULL)
{
ImportDllName = (PCHAR)((ULONG_PTR)ConvertVAtoFileOffset(FileMapVA, ImportPointer->Name + ImageBase, true));
MultiByteToWideChar(CP_ACP, NULL, ImportDllName, lstrlenA(ImportDllName)+1, ImportDllNameW, sizeof(ImportDllNameW)/(sizeof(ImportDllNameW[0])));
if(!EngineIsDependencyPresentW(ImportDllNameW, szFileName, szOutputFolder))
{
RtlZeroMemory(&BuildExportName, 512);
lstrcatW(BuildExportName, szOutputFolder);
if(BuildExportName[lstrlenW(BuildExportName)-1] != 0x5C)
{
BuildExportName[lstrlenW(BuildExportName)] = 0x5C;
}
lstrcatW(BuildExportName, ImportDllNameW);
if(LogCreatedFiles)
{
RtlMoveMemory(engineDependencyFilesCWP, &BuildExportName, lstrlenW(BuildExportName) * 2);
engineDependencyFilesCWP = (LPVOID)((ULONG_PTR)engineDependencyFilesCWP + (lstrlenW(BuildExportName) * 2) + 2);
}
EngineExtractResource("MODULEx64", BuildExportName);
ExporterInit(20 * 1024, (ULONG_PTR)GetPE32DataW(BuildExportName, NULL, UE_IMAGEBASE), NULL, ImportDllName);
ImportThunkAddress = ImportPointer->FirstThunk;
if(ImportPointer->OriginalFirstThunk != NULL)
{
ImportThunkX64 = (PIMAGE_THUNK_DATA64)((ULONG_PTR)ConvertVAtoFileOffset(FileMapVA, ImportPointer->OriginalFirstThunk + ImageBase, true));
}
else
{
ImportThunkX64 = (PIMAGE_THUNK_DATA64)((ULONG_PTR)ConvertVAtoFileOffset(FileMapVA, ImportPointer->FirstThunk + ImageBase, true));
}
while(ImportThunkX64->u1.Function != NULL)
{
if(ImportThunkX64->u1.Ordinal & IMAGE_ORDINAL_FLAG64)
{
ExporterAddNewOrdinalExport((DWORD)(ImportThunkX64->u1.Ordinal ^ IMAGE_ORDINAL_FLAG64), 0x1000);
}
else
{
ImportThunkName = (ULONG_PTR)(ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)(ImportThunkX64->u1.AddressOfData + ImageBase), true) + 2);
ExporterAddNewExport((PCHAR)ImportThunkName, 0x1000);
}
ImportThunkX64 = (PIMAGE_THUNK_DATA64)((ULONG_PTR)ImportThunkX64 + 8);
ImportThunkAddress = ImportThunkAddress + 8;
}
ExporterBuildExportTableExW(BuildExportName, ".export");
}
ImportPointer = (PIMAGE_IMPORT_DESCRIPTOR)((ULONG_PTR)ImportPointer + sizeof IMAGE_IMPORT_DESCRIPTOR);
}
}
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(true);
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return(false);
}
}
return(false);
}
__declspec(dllexport) bool TITCALL EngineFakeMissingDependencies(HANDLE hProcess)
{
if(hProcess != NULL)
{
SetAPIBreakPoint("ntdll.dll", "LdrLoadDll", UE_BREAKPOINT, UE_APIEND, (LPVOID)&EngineFakeLoadLibraryReturn);
SetAPIBreakPoint("ntdll.dll", "LdrGetProcedureAddress", UE_BREAKPOINT, UE_APIEND, (LPVOID)&EngineFakeGetProcAddressReturn);
}
return(false);
}
__declspec(dllexport) bool TITCALL EngineDeleteCreatedDependencies()
{
wchar_t szTempName[MAX_PATH];
wchar_t szTempFolder[MAX_PATH];
if(engineDependencyFiles != NULL)
{
engineDependencyFilesCWP = engineDependencyFiles;
while(*((char*)engineDependencyFilesCWP) != 0)
{
RtlZeroMemory(&szTempName, sizeof szTempName);
RtlZeroMemory(&szTempFolder, sizeof szTempFolder);
if(GetTempPathW(MAX_PATH, szTempFolder) < MAX_PATH)
{
if(GetTempFileNameW(szTempFolder, L"DeleteTempGenFile", GetTickCount(), szTempName))
{
DeleteFileW(szTempName);
if(!MoveFileW((LPCWSTR)engineDependencyFilesCWP, szTempName))
{
DeleteFileW((LPCWSTR)engineDependencyFilesCWP);
}
else
{
DeleteFileW(szTempName);
}
}
}
engineDependencyFilesCWP = (LPVOID)((ULONG_PTR)engineDependencyFilesCWP + (lstrlenW((PWCHAR)engineDependencyFilesCWP) * 2) + 2);
}
VirtualFree(engineDependencyFiles, NULL, MEM_RELEASE);
engineDependencyFiles = NULL;
engineDependencyFilesCWP = NULL;
return(true);
}
return(false);
}
__declspec(dllexport) bool TITCALL EngineCreateUnpackerWindow(char* WindowUnpackerTitle, char* WindowUnpackerLongTitle, char* WindowUnpackerName, char* WindowUnpackerAuthor, void* StartUnpackingCallBack)
{
if(!WindowUnpackerTitle || !WindowUnpackerLongTitle || !WindowUnpackerName || !WindowUnpackerAuthor || !StartUnpackingCallBack)
return false;
EngineStartUnpackingCallBack = StartUnpackingCallBack;
lstrcpyA(szWindowUnpackerTitle, WindowUnpackerTitle);
lstrcpyA(szWindowUnpackerLongTitle, WindowUnpackerLongTitle);
lstrcpyA(szWindowUnpackerAuthor, WindowUnpackerAuthor);
lstrcpyA(szWindowUnpackerName, WindowUnpackerName);
if(DialogBoxParamA((HINSTANCE)engineHandle, MAKEINTRESOURCEA(IDD_MAINWINDOW), NULL, (DLGPROC)EngineWndProc, NULL) != -1)
{
return(true);
}
else
{
return(false);
}
}
__declspec(dllexport) void TITCALL EngineAddUnpackerWindowLogMessage(char* szLogMessage)
{
int cSelect;
SendMessageA(EngineBoxHandle, LB_ADDSTRING, NULL, (LPARAM)szLogMessage);
cSelect = (int)SendMessageA(EngineBoxHandle, LB_GETCOUNT, NULL, NULL);
cSelect--;
SendMessageA(EngineBoxHandle, LB_SETCURSEL, (WPARAM)cSelect, NULL);
}
// Global.Engine.Extension.Functions:
__declspec(dllexport) bool TITCALL ExtensionManagerIsPluginLoaded(char* szPluginName)
{
for(unsigned int i = 0; i < Plugin.size(); i++)
{
if(lstrcmpiA(Plugin[i].PluginName, szPluginName) == NULL)
{
return(true);
}
}
return(false);
}
__declspec(dllexport) bool TITCALL ExtensionManagerIsPluginEnabled(char* szPluginName)
{
for(unsigned int i = 0; i < Plugin.size(); i++)
{
if(lstrcmpiA(Plugin[i].PluginName, szPluginName) == NULL)
{
if(!Plugin[i].PluginDisabled)
{
return(true);
}
else
{
return(false);
}
}
}
return(false);
}
__declspec(dllexport) bool TITCALL ExtensionManagerDisableAllPlugins()
{
for(unsigned int i = 0; i < Plugin.size(); i++)
{
Plugin[i].PluginDisabled = true;
}
return(true);
}
__declspec(dllexport) bool TITCALL ExtensionManagerDisablePlugin(char* szPluginName)
{
for(unsigned int i = 0; i < Plugin.size(); i++)
{
if(lstrcmpiA(Plugin[i].PluginName, szPluginName) == NULL)
{
Plugin[i].PluginDisabled = true;
return(true);
}
}
return(false);
}
__declspec(dllexport) bool TITCALL ExtensionManagerEnableAllPlugins()
{
for(unsigned int i = 0; i < Plugin.size(); i++)
{
Plugin[i].PluginDisabled = false;
}
return(true);
}
__declspec(dllexport) bool TITCALL ExtensionManagerEnablePlugin(char* szPluginName)
{
for(unsigned int i = 0; i < Plugin.size(); i++)
{
if(lstrcmpiA(Plugin[i].PluginName, szPluginName) == NULL)
{
Plugin[i].PluginDisabled = false;
return(true);
}
}
return(false);
}
__declspec(dllexport) bool TITCALL ExtensionManagerUnloadAllPlugins()
{
for(unsigned int i = 0; i < Plugin.size(); i++)
{
if(FreeLibrary(Plugin[i].PluginBaseAddress))
{
Plugin.erase(Plugin.begin() + i);
}
}
return(true);
}
__declspec(dllexport) bool TITCALL ExtensionManagerUnloadPlugin(char* szPluginName)
{
typedef void(TITCALL *fPluginReleaseExec)();
fPluginReleaseExec myPluginReleaseExec;
for(unsigned int i = 0; i < Plugin.size(); i++)
{
if(lstrcmpiA(Plugin[i].PluginName, szPluginName) == NULL)
{
__try
{
if(Plugin[i].TitanReleasePlugin != NULL)
{
myPluginReleaseExec = (fPluginReleaseExec)Plugin[i].TitanReleasePlugin;
myPluginReleaseExec();
if(FreeLibrary(Plugin[i].PluginBaseAddress))
{
Plugin.erase(Plugin.begin() + i);
return(true);
}
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
if(FreeLibrary(Plugin[i].PluginBaseAddress))
{
Plugin.erase(Plugin.begin() + i);
return(true);
}
}
}
}
return(false);
}
__declspec(dllexport) void* TITCALL ExtensionManagerGetPluginInfo(char* szPluginName)
{
for(unsigned int i = 0; i < Plugin.size(); i++)
{
if(lstrcmpiA(Plugin[i].PluginName, szPluginName) == NULL)
{
return(&Plugin[i]);
}
}
return(NULL);
}
// Global.Garbage.functions:
bool CreateGarbageItem(void* outGargabeItem, int MaxGargabeStringSize)
{
bool Created = false;
wchar_t szGarbageItem[512];
wchar_t szGargabeItemBuff[128];
while(!Created)
{
RtlZeroMemory(&szGarbageItem, sizeof szGarbageItem);
RtlZeroMemory(&szGargabeItemBuff, sizeof szGargabeItemBuff);
srand((unsigned int)time(NULL));
wsprintfW(szGargabeItemBuff, L"Junk-%08x\\", (rand() % 128 + 1) * (rand() % 128 + 1) + (rand() % 1024 + 1));
lstrcpyW(szGarbageItem, engineSzEngineGarbageFolder);
lstrcatW(szGarbageItem, szGargabeItemBuff);
if(EngineCreatePathForFileW(szGarbageItem))
{
Created = true;
}
}
if(lstrlenW(szGarbageItem) * 2 >= MaxGargabeStringSize)
{
RtlMoveMemory(outGargabeItem, &szGarbageItem, MaxGargabeStringSize);
return(false);
}
else
{
RtlMoveMemory(outGargabeItem, &szGarbageItem, lstrlenW(szGarbageItem) * 2);
return(true);
}
}
bool RemoveGarbageItem(wchar_t* szGarbageItem, bool RemoveFolder)
{
wchar_t szFindSearchString[MAX_PATH];
wchar_t szFoundFile[MAX_PATH];
WIN32_FIND_DATAW FindData;
bool QueryNextFile = true;
HANDLE CurrentFile;
if(szGarbageItem != NULL)
{
lstrcpyW(szFindSearchString, szGarbageItem);
if(szFindSearchString[0] != NULL)
{
lstrcatW(szFindSearchString, L"\\*.*");
CurrentFile = FindFirstFileW(szFindSearchString, &FindData);
while(QueryNextFile == true && CurrentFile != INVALID_HANDLE_VALUE)
{
RtlZeroMemory(&szFoundFile, sizeof szFoundFile);
lstrcpyW(szFoundFile, szGarbageItem);
lstrcatW(szFoundFile, FindData.cFileName);
if(FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if(FindData.cFileName[0] != 0x2E)
{
lstrcatW(szFoundFile, L"\\");
RemoveGarbageItem(szFoundFile, true);
}
}
else
{
if(!DeleteFileW(szFoundFile))
{
if(HandlerCloseAllLockHandlesW(szFoundFile, false, true))
{
DeleteFileW(szFoundFile);
}
}
}
if(!FindNextFileW(CurrentFile, &FindData))
{
QueryNextFile = false;
}
}
FindClose(CurrentFile);
if(RemoveFolder)
{
if(lstrlenW(engineSzEngineGarbageFolder) < lstrlenW(szGarbageItem))
{
if(!RemoveDirectoryW(szGarbageItem))
{
if(HandlerCloseAllLockHandlesW(szGarbageItem, true, true))
{
RemoveDirectoryW(szGarbageItem);
}
}
}
}
return(true);
}
else
{
return(false);
}
}
else
{
return(false);
}
}
bool FillGarbageItem(wchar_t* szGarbageItem, wchar_t* szFileName, void* outGargabeItem, int MaxGargabeStringSize)
{
if(!szGarbageItem || !szFileName || !outGargabeItem)
return false;
wchar_t szCopyFileName[512];
wchar_t szGargabeItemBuff[128];
lstrcpyW(szCopyFileName, szGarbageItem);
if(szFileName != NULL)
{
lstrcatW(szCopyFileName, EngineExtractFileNameW(szFileName));
}
else
{
srand((unsigned int)time(NULL));
wsprintfW(szGargabeItemBuff, L"Junk-Data-%08x.bin", (rand() % 128 + 1) * (rand() % 128 + 1) + (rand() % 1024 + 1));
lstrcatW(szCopyFileName, szGargabeItemBuff);
}
if(lstrlenW(szCopyFileName) >= MaxGargabeStringSize)
{
RtlMoveMemory(outGargabeItem, &szCopyFileName, MaxGargabeStringSize);
if(szFileName != NULL)
{
CopyFileW(szFileName, szCopyFileName, false);
}
}
else
{
RtlMoveMemory(outGargabeItem, &szCopyFileName, lstrlenW(szCopyFileName) * 2);
if(szFileName != NULL)
{
CopyFileW(szFileName, szCopyFileName, false);
}
}
return(true);
}
void EmptyGarbage()
{
RemoveGarbageItem(engineSzEngineGarbageFolder, false);
}
// Global.Engine.Functions:
void EngineInitPlugins(wchar_t* szEngineFolder)
{
bool MoreFiles = true;
bool NameHasBeenRegistered = false;
PluginInformation myPluginInfo = {};
#if defined (_WIN64)
wchar_t* szPluginFolder = L"plugins\\x64\\";
#else
wchar_t* szPluginFolder = L"plugins\\x86\\";
#endif
typedef bool(TITCALL *fPluginRegister)(char* szPluginName, LPDWORD titanPluginMajorVersion, LPDWORD titanPluginMinorVersion);
wchar_t szPluginSearchString[MAX_PATH] = {};
wchar_t szPluginFullPath[MAX_PATH] = {};
fPluginRegister myPluginRegister;
WIN32_FIND_DATAW FindData;
HANDLE CurrentFile;
lstrcpyW(szPluginSearchString, szEngineFolder);
lstrcatW(szPluginSearchString, szPluginFolder);
lstrcatW(szPluginSearchString, L"*.dll");
CurrentFile = FindFirstFileW(szPluginSearchString, &FindData);
while(MoreFiles)
{
lstrcpyW(szPluginFullPath, szEngineFolder);
lstrcatW(szPluginFullPath, szPluginFolder);
lstrcatW(szPluginFullPath, FindData.cFileName);
RtlZeroMemory(&myPluginInfo, sizeof PluginInformation);
myPluginInfo.PluginBaseAddress = LoadLibraryW(szPluginFullPath);
if(myPluginInfo.PluginBaseAddress != NULL)
{
myPluginInfo.TitanResetPlugin = (void*)GetProcAddress(myPluginInfo.PluginBaseAddress, "TitanResetPlugin");
myPluginInfo.TitanReleasePlugin = (void*)GetProcAddress(myPluginInfo.PluginBaseAddress, "TitanReleasePlugin");
myPluginInfo.TitanRegisterPlugin = (void*)GetProcAddress(myPluginInfo.PluginBaseAddress, "TitanRegisterPlugin");
myPluginInfo.TitanDebuggingCallBack = (void*)GetProcAddress(myPluginInfo.PluginBaseAddress, "TitanDebuggingCallBack");
myPluginRegister = (fPluginRegister)myPluginInfo.TitanRegisterPlugin;
if(myPluginRegister != NULL)
{
__try
{
if(myPluginRegister((char*)&myPluginInfo.PluginName[0], &myPluginInfo.PluginMajorVersion, &myPluginInfo.PluginMinorVersion))
{
if(lstrlenA(myPluginInfo.PluginName) <= 64)
{
NameHasBeenRegistered = false;
for(unsigned int i = 0; i < Plugin.size(); i++)
{
if(lstrcmpiA(Plugin[i].PluginName, myPluginInfo.PluginName) == NULL)
{
NameHasBeenRegistered = true;
}
}
if(!NameHasBeenRegistered)
{
Plugin.push_back(myPluginInfo);
}
else
{
FreeLibrary(myPluginInfo.PluginBaseAddress);
}
}
else
{
FreeLibrary(myPluginInfo.PluginBaseAddress);
}
}
else
{
FreeLibrary(myPluginInfo.PluginBaseAddress);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
FreeLibrary(myPluginInfo.PluginBaseAddress);
}
}
}
if(!FindNextFileW(CurrentFile, &FindData))
{
MoreFiles = false;
}
}
FindClose(CurrentFile);
}
void EngineInit()
{
int i;
unsigned long ulPolynomial = 0x04C11DB7; //0x04C11DB7 is the official polynomial used by PKZip, WinZip and Ethernet.
RtlZeroMemory(&engineSzEngineFile, sizeof engineSzEngineFile);
RtlZeroMemory(&engineSzEngineFolder, sizeof engineSzEngineFolder);
if(GetModuleFileNameW(engineHandle, engineSzEngineFile, MAX_PATH) > NULL)
{
lstrcpyW(engineSzEngineFolder, engineSzEngineFile);
i = lstrlenW(engineSzEngineFolder);
while(i > NULL && engineSzEngineFolder[i] != 0x5C)
{
engineSzEngineFolder[i] = 0x00;
i--;
}
if(i > NULL)
{
lstrcpyW(engineSzEngineGarbageFolder, engineSzEngineFolder);
lstrcatW(engineSzEngineGarbageFolder, L"garbage\\");
}
EngineInitPlugins(engineSzEngineFolder);
}
// CRC32 table initialization
for(int iCodes = 0; iCodes <= 0xFF; iCodes++)
{
Crc32Table[iCodes] = EngineCrc32Reflect(iCodes, 8) << 24;
for(int iPos = 0; iPos < 8; iPos++)
{
Crc32Table[iCodes] = (Crc32Table[iCodes] << 1) ^ ((Crc32Table[iCodes] & (1 << 31)) ? ulPolynomial : 0);
}
Crc32Table[iCodes] = EngineCrc32Reflect(Crc32Table[iCodes], 32);
}
}
// Global.Engine.Entry:
bool APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
int i;
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
engineHandle = hModule;
if(sizeof HANDLE != 4)
{
engineCurrentPlatform = UE_PLATFORM_x64;
}
EngineInit();
EmptyGarbage();
for(i = 0; i < UE_MAX_RESERVED_MEMORY_LEFT; i++)
{
engineReservedMemoryLeft[i] = NULL;
}
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
if(lpReserved != NULL)
{
EngineExecutePluginReleaseCallBack();
}
break;
}
return TRUE;
}