mirror of https://github.com/x64dbg/TitanEngine
27484 lines
1.2 MiB
27484 lines
1.2 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"
|
|
// scylla wrapper
|
|
#include "scylla_wrapper.h"
|
|
|
|
#define TE_VER_MAJOR 2
|
|
#define TE_VER_MIDDLE 1
|
|
#define TE_VER_MINOR 0
|
|
|
|
/*#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;
|
|
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;
|
|
}
|
|
else
|
|
{
|
|
MaxDisassmSize = 512;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
MaxDisassmSize = 512;
|
|
}
|
|
|
|
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_FIELD_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)
|
|
{
|
|
RtlZeroMemory(ueReadBuffer, 0x2000);
|
|
|
|
if(OverlaySize > 0x1000)
|
|
{
|
|
if(ReadFile(hFile, ueReadBuffer, 0x1000, &ueNumberOfBytesRead, NULL))
|
|
{
|
|
if(!WriteFile(hFileWrite, ueReadBuffer, 0x1000, &ueNumberOfBytesRead, NULL))
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
|
|
OverlaySize = OverlaySize - 0x1000;
|
|
}
|
|
else
|
|
{
|
|
if(ReadFile(hFile, ueReadBuffer, OverlaySize, &ueNumberOfBytesRead, NULL))
|
|
{
|
|
if(!WriteFile(hFileWrite, ueReadBuffer, OverlaySize, &ueNumberOfBytesRead, NULL))
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
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)
|
|
{
|
|
RtlZeroMemory(ueReadBuffer, 0x2000);
|
|
|
|
if(OverlaySize > 0x1000)
|
|
{
|
|
if(ReadFile(hFileRead, ueReadBuffer, 0x1000, &uedNumberOfBytesRead, NULL))
|
|
{
|
|
if(!WriteFile(hFile, ueReadBuffer, 0x1000, &uedNumberOfBytesRead, NULL))
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
|
|
OverlaySize = OverlaySize - 0x1000;
|
|
}
|
|
else
|
|
{
|
|
if(ReadFile(hFileRead, ueReadBuffer, OverlaySize, &uedNumberOfBytesRead, NULL))
|
|
{
|
|
if(!WriteFile(hFile, ueReadBuffer, OverlaySize, &uedNumberOfBytesRead, NULL))
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
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_FIELD_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_FIELD_FIXABLE_NON_CRITICAL;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
myFileStatusInfo.SectionAlignment = UE_FIELD_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_FIELD_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_FIELD_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_FIELD_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_FIELD_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_FIELD_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_FIELD_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_FIELD_FIXABLE_CRITICAL;
|
|
}
|
|
else if(PETls32->EndAddressOfRawData != NULL && (PETls32->EndAddressOfRawData < PEHeader32->OptionalHeader.ImageBase || PETls32->EndAddressOfRawData > CorrectedImageSize + PEHeader32->OptionalHeader.ImageBase))
|
|
{
|
|
myFileStatusInfo.TLSTable = UE_FIELD_FIXABLE_CRITICAL;
|
|
}
|
|
else if(PETls32->AddressOfIndex != NULL && (PETls32->AddressOfIndex < PEHeader32->OptionalHeader.ImageBase || PETls32->AddressOfIndex > CorrectedImageSize + PEHeader32->OptionalHeader.ImageBase))
|
|
{
|
|
myFileStatusInfo.TLSTable = UE_FIELD_FIXABLE_CRITICAL;
|
|
}
|
|
else if(PETls32->AddressOfCallBacks != NULL && (PETls32->AddressOfCallBacks < PEHeader32->OptionalHeader.ImageBase || PETls32->AddressOfCallBacks > CorrectedImageSize + PEHeader32->OptionalHeader.ImageBase))
|
|
{
|
|
myFileStatusInfo.TLSTable = UE_FIELD_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_FIELD_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_FIELD_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_FIELD_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_FIELD_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_FIELD_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_FIELD_FIXABLE_CRITICAL;
|
|
}
|
|
else if(!EngineIsPointedMemoryString(ConvertedAddress + BoundIID->OffsetModuleName))
|
|
{
|
|
myFileStatusInfo.BoundImportTable = UE_FIELD_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_FIELD_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_FIELD_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_FIELD_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_FIELD_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_FIELD_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_FIELD_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_FIELD_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_FIELD_FIXABLE_NON_CRITICAL;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
myFileStatusInfo.SectionAlignment = UE_FIELD_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_FIELD_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_FIELD_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_FIELD_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_FIELD_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_FIELD_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_FIELD_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_FIELD_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_FIELD_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_FIELD_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_FIELD_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_FIELD_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_FIELD_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_FIELD_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_FIELD_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_FIELD_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_FIELD_FIXABLE_CRITICAL;
|
|
}
|
|
else if(!EngineIsPointedMemoryString(ConvertedAddress + BoundIID->OffsetModuleName))
|
|
{
|
|
myFileStatusInfo.BoundImportTable = UE_FIELD_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_FIELD_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_FIELD_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_FIELD_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_FIELD_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_FIELD_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_FIELD_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_FIELD_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);
|
|
}
|
|
|
|
static bool isAtleastVista()
|
|
{
|
|
static bool isAtleastVista=false;
|
|
static bool isSet=false;
|
|
if(isSet)
|
|
return isAtleastVista;
|
|
OSVERSIONINFO versionInfo= {0};
|
|
versionInfo.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
|
|
GetVersionEx(&versionInfo);
|
|
isAtleastVista=versionInfo.dwMajorVersion >= 6;
|
|
isSet=true;
|
|
return isAtleastVista;
|
|
}
|
|
|
|
// Global.Engine.Hider.functions:
|
|
bool ChangeHideDebuggerState(HANDLE hProcess, DWORD PatchAPILevel, bool Hide)
|
|
{
|
|
static ULONG OldHeapFlags=0;
|
|
static ULONG OldForceFlag=0;
|
|
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;
|
|
//Fix heap flags: https://github.com/eschweiler/ProReversing
|
|
BYTE* Heap=(BYTE*)myPEB.ProcessHeap;
|
|
|
|
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, SIZE_T 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, SIZE_T 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, SIZE_T 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((ULONG_PTR)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((ULONG_PTR)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;
|
|
SIZE_T 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)
|
|
{
|
|
|
|
}
|
|
}
|
|
|
|
//Debug event
|
|
switch(DBGEvent.dwDebugEventCode)
|
|
{
|
|
case CREATE_PROCESS_DEBUG_EVENT:
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 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;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 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;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 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;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 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;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 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);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 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;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case EXCEPTION_DEBUG_EVENT:
|
|
{
|
|
printf("Exception: 0x%X\n", DBGEvent.u.Exception.ExceptionRecord.ExceptionCode);
|
|
//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
|
|
|
|
switch(DBGEvent.u.Exception.ExceptionRecord.ExceptionCode)
|
|
{
|
|
case 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_PEBONLY);
|
|
}
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case STATUS_GUARD_PAGE_VIOLATION:
|
|
{
|
|
MemoryBpxFound = false;
|
|
MaximumBreakPoints = 0;
|
|
ULONG_PTR bpaddr;
|
|
for(MaximumBreakPoints = 0; MaximumBreakPoints < BreakPointSetCount; MaximumBreakPoints++)
|
|
{
|
|
ULONG_PTR addr=BreakPointBuffer[MaximumBreakPoints].BreakPointAddress;
|
|
|
|
bpaddr=(ULONG_PTR)DBGEvent.u.Exception.ExceptionRecord.ExceptionInformation[1]; //page accessed
|
|
|
|
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; //debugger handled the exception
|
|
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) //do not restore the memory breakpoint
|
|
{
|
|
if(DBGEvent.u.Exception.ExceptionRecord.ExceptionInformation[0] == 0) //read operation
|
|
RemoveMemoryBPX(BreakPointBuffer[MaximumBreakPoints].BreakPointAddress, BreakPointBuffer[MaximumBreakPoints].BreakPointSize);
|
|
}
|
|
else //restore the memory breakpoint
|
|
{
|
|
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 //no write 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_EXECUTE) //EXECUTE
|
|
{
|
|
if(BreakPointBuffer[MaximumBreakPoints].MemoryBpxRestoreOnHit != 1)
|
|
{
|
|
if(DBGEvent.u.Exception.ExceptionRecord.ExceptionInformation[0] == 0 && //read flag
|
|
(ULONG_PTR)DBGEvent.u.Exception.ExceptionRecord.ExceptionAddress == DBGEvent.u.Exception.ExceptionRecord.ExceptionInformation[1]) //exception address == read address
|
|
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 flag
|
|
(ULONG_PTR)DBGEvent.u.Exception.ExceptionRecord.ExceptionAddress == DBGEvent.u.Exception.ExceptionRecord.ExceptionInformation[1]) //exception address == read address
|
|
{
|
|
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; //debugger did not handle the exception
|
|
}
|
|
}
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 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;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 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;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 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;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 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;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 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;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 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;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 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;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 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;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
//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;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case RIP_EVENT:
|
|
{
|
|
//TODO: RIP event
|
|
}
|
|
break;
|
|
}
|
|
|
|
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 ImporterAddNewDll(char* szDLLName, ULONG_PTR FirstThunk)
|
|
{
|
|
wchar_t uniDLLName[MAX_PATH] = {};
|
|
|
|
MultiByteToWideChar(CP_ACP, NULL, szDLLName, lstrlenA(szDLLName)+1, uniDLLName, sizeof(uniDLLName)/(sizeof(uniDLLName[0])));
|
|
|
|
scylla_addModule(uniDLLName, FirstThunk);
|
|
}
|
|
__declspec(dllexport) void TITCALL ImporterAddNewAPI(char* szAPIName, ULONG_PTR ThunkValue)
|
|
{
|
|
wchar_t uniAPIName[MAX_PATH] = {};
|
|
|
|
MultiByteToWideChar(CP_ACP, NULL, szAPIName, lstrlenA(szAPIName)+1, uniAPIName, sizeof(uniAPIName)/(sizeof(uniAPIName[0])));
|
|
|
|
scylla_addImport(uniAPIName, ThunkValue);
|
|
}
|
|
__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 scylla_getModuleCount();
|
|
}
|
|
__declspec(dllexport) long TITCALL ImporterGetAddedAPICount()
|
|
{
|
|
return scylla_getImportCount();
|
|
}
|
|
__declspec(dllexport) bool TITCALL ImporterExportIAT(ULONG_PTR StorePlace, ULONG_PTR FileMapVA, HANDLE hFileMap)
|
|
{
|
|
if(scylla_fixMappedDump(StorePlace, FileMapVA, hFileMap) != SCY_ERROR_SUCCESS)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
__declspec(dllexport) long TITCALL ImporterEstimatedSize()
|
|
{
|
|
return scylla_estimatedIATSize();
|
|
}
|
|
__declspec(dllexport) bool TITCALL ImporterExportIATEx(char* szDumpFileName, char* szExportFileName, char* szSectionName)
|
|
{
|
|
|
|
wchar_t uniExportFileName[MAX_PATH] = {};
|
|
wchar_t uniDumpFileName[MAX_PATH] = {};
|
|
wchar_t uniSectionName[MAX_PATH] = {};
|
|
|
|
if(szExportFileName != NULL && szDumpFileName != NULL)
|
|
{
|
|
MultiByteToWideChar(CP_ACP, NULL, szExportFileName, lstrlenA(szExportFileName)+1, uniExportFileName, sizeof(uniExportFileName)/(sizeof(uniExportFileName[0])));
|
|
MultiByteToWideChar(CP_ACP, NULL, szDumpFileName, lstrlenA(szDumpFileName)+1, uniDumpFileName, sizeof(uniDumpFileName)/(sizeof(uniDumpFileName[0])));
|
|
MultiByteToWideChar(CP_ACP, NULL, szSectionName, lstrlenA(szSectionName)+1, uniSectionName, sizeof(uniSectionName)/(sizeof(uniSectionName[0])));
|
|
return(ImporterExportIATExW(uniDumpFileName, uniExportFileName, uniSectionName));
|
|
}
|
|
else
|
|
{
|
|
return(false);
|
|
}
|
|
}
|
|
__declspec(dllexport) bool TITCALL ImporterExportIATExW(wchar_t* szDumpFileName, wchar_t* szExportFileName, wchar_t* szSectionName)
|
|
{
|
|
if(scylla_fixDump(szDumpFileName, szExportFileName, szSectionName) != SCY_ERROR_SUCCESS)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
__declspec(dllexport) long long TITCALL ImporterFindAPIWriteLocation(char* szAPIName)
|
|
{
|
|
return(scylla_findImportWriteLocation(szAPIName));
|
|
}
|
|
__declspec(dllexport) long long TITCALL ImporterFindOrdinalAPIWriteLocation(ULONG_PTR OrdinalNumber)
|
|
{
|
|
return(scylla_findOrdinalImportWriteLocation(OrdinalNumber));
|
|
}
|
|
__declspec(dllexport) long long TITCALL ImporterFindAPIByWriteLocation(ULONG_PTR APIWriteLocation)
|
|
{
|
|
return(scylla_findImportNameByWriteLocation(APIWriteLocation));
|
|
}
|
|
__declspec(dllexport) long long TITCALL ImporterFindDLLByWriteLocation(ULONG_PTR APIWriteLocation)
|
|
{
|
|
return scylla_findModuleNameByWriteLocation(APIWriteLocation);
|
|
}
|
|
__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 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)
|
|
{
|
|
//TODO scylla enable
|
|
return false;
|
|
/*
|
|
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(DWORD ProcessId, char* szFileName, ULONG_PTR SearchStart, 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(ProcessId, uniFileName, SearchStart, pIATStart, pIATSize));
|
|
}
|
|
}
|
|
__declspec(dllexport) void TITCALL ImporterAutoSearchIATW(DWORD ProcessId, wchar_t* szFileName, ULONG_PTR SearchStart, LPVOID pIATStart, LPVOID pIATSize)
|
|
{
|
|
ULONG_PTR iatStart = NULL;
|
|
DWORD iatSize = NULL;
|
|
|
|
scylla_searchIAT(ProcessId, iatStart, iatSize, SearchStart, false);
|
|
|
|
//we also try to automatically read imports so following call to ExportIAT has a chance
|
|
if(iatStart != NULL && iatSize != NULL)
|
|
{
|
|
scylla_getImports(iatStart, iatSize, ProcessId);
|
|
}
|
|
|
|
RtlMoveMemory(pIATStart, &iatStart, sizeof ULONG_PTR);
|
|
RtlMoveMemory(pIATSize, &iatSize, sizeof ULONG_PTR);
|
|
|
|
return;
|
|
}
|
|
__declspec(dllexport) void TITCALL ImporterAutoSearchIATEx(DWORD ProcessId, ULONG_PTR ImageBase, ULONG_PTR SearchStart, 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))
|
|
{
|
|
HANDLE hProcess = OpenProcess(PROCESS_VM_READ|PROCESS_QUERY_INFORMATION, FALSE, ProcessId);
|
|
|
|
DumpProcessW(hProcess, (LPVOID)ImageBase, szTempName, NULL);
|
|
ImporterAutoSearchIATW(ProcessId, szTempName, SearchStart, pIATStart, pIATSize);
|
|
DeleteFileW(szTempName);
|
|
}
|
|
}
|
|
}
|
|
__declspec(dllexport) void TITCALL ImporterEnumAddedData(LPVOID EnumCallBack)
|
|
{
|
|
return scylla_enumImportTree(EnumCallBack);
|
|
}
|
|
__declspec(dllexport) long TITCALL ImporterAutoFixIATEx(DWORD ProcessId, char* szDumpedFile, char* szSectionName, bool DumpRunningProcess, bool RealignFile, ULONG_PTR EntryPointAddress, ULONG_PTR ImageBase, ULONG_PTR SearchStart, bool TryAutoFix, bool FixEliminations, LPVOID UnknownPointerFixCallback)
|
|
{
|
|
|
|
wchar_t uniDumpedFile[MAX_PATH] = {};
|
|
wchar_t uniSectionName[MAX_PATH] = {};
|
|
|
|
if(szDumpedFile != NULL)
|
|
{
|
|
MultiByteToWideChar(CP_ACP, NULL, szDumpedFile, lstrlenA(szDumpedFile)+1, uniDumpedFile, sizeof(uniDumpedFile)/(sizeof(uniDumpedFile[0])));
|
|
MultiByteToWideChar(CP_ACP, NULL, szSectionName, lstrlenA(szSectionName)+1, uniSectionName, sizeof(uniSectionName)/(sizeof(uniSectionName[0])));
|
|
return(ImporterAutoFixIATExW(ProcessId, uniDumpedFile, uniSectionName, DumpRunningProcess, RealignFile, EntryPointAddress, ImageBase, SearchStart, TryAutoFix, FixEliminations, UnknownPointerFixCallback));
|
|
}
|
|
else
|
|
{
|
|
return(NULL); // Critical error! *just to be safe, but it should never happen!
|
|
}
|
|
}
|
|
__declspec(dllexport) long TITCALL ImporterAutoFixIATExW(DWORD ProcessId, wchar_t* szDumpedFile, wchar_t* szSectionName, bool DumpRunningProcess, bool RealignFile, ULONG_PTR EntryPointAddress, ULONG_PTR ImageBase, ULONG_PTR SearchStart, bool TryAutoFix, bool FixEliminations, LPVOID UnknownPointerFixCallback)
|
|
{
|
|
HANDLE FileHandle;
|
|
DWORD FileSize;
|
|
HANDLE FileMap;
|
|
ULONG_PTR FileMapVA;
|
|
ULONG_PTR iatStart = NULL;
|
|
DWORD iatSize = NULL;
|
|
WCHAR IatFixFileName[MAX_PATH];
|
|
WCHAR DumpFileName[MAX_PATH];
|
|
|
|
lstrcpyW(DumpFileName, szDumpedFile);
|
|
|
|
WCHAR* Extension = wcsrchr(DumpFileName, L'.');
|
|
WCHAR Bak = *Extension;
|
|
*Extension = 0;
|
|
lstrcpyW(IatFixFileName, DumpFileName);
|
|
*Extension = Bak;
|
|
lstrcatW(IatFixFileName, L"_scy");
|
|
lstrcatW(IatFixFileName, Extension);
|
|
lstrcatW(DumpFileName, Extension);
|
|
|
|
//do we need to dump first?
|
|
if(DumpRunningProcess)
|
|
{
|
|
HANDLE hProcess = OpenProcess(PROCESS_VM_READ|PROCESS_QUERY_INFORMATION, FALSE, ProcessId);
|
|
|
|
if(!DumpProcessW(hProcess, (LPVOID)ImageBase, szDumpedFile, EntryPointAddress))
|
|
{
|
|
return(NULL); // Critical error! *just to be safe, but it should never happen!
|
|
}
|
|
}
|
|
|
|
//we need to fix iat, thats for sure
|
|
int ret = scylla_searchIAT(ProcessId, iatStart, iatSize, SearchStart, false);
|
|
|
|
if(ret != SCY_ERROR_SUCCESS)
|
|
{
|
|
if(ret == SCY_ERROR_PROCOPEN)
|
|
{
|
|
return (0x401); //error proc terminated
|
|
}
|
|
if(ret == SCY_ERROR_IATNOTFOUND || ret == SCY_ERROR_IATSEARCH)
|
|
{
|
|
return (0x405); //no API found
|
|
}
|
|
}
|
|
|
|
scylla_getImports(iatStart, iatSize, ProcessId, UnknownPointerFixCallback);
|
|
|
|
if(!scylla_importsValid())
|
|
{
|
|
return (0x405);
|
|
}
|
|
|
|
ret = scylla_fixDump(szDumpedFile, IatFixFileName, szSectionName);
|
|
|
|
if(ret == SCY_ERROR_IATWRITE)
|
|
{
|
|
return (0x407);
|
|
}
|
|
|
|
//do we need to realign ?
|
|
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!
|
|
}
|
|
__declspec(dllexport) long TITCALL ImporterAutoFixIAT(DWORD ProcessId, char* szDumpedFile, ULONG_PTR SearchStart)
|
|
{
|
|
return(ImporterAutoFixIATEx(ProcessId, szDumpedFile, ".RL!TEv2", false, false, NULL, NULL, SearchStart, false, false, NULL));
|
|
}
|
|
__declspec(dllexport) long TITCALL ImporterAutoFixIATW(DWORD ProcessId, wchar_t* szDumpedFile, ULONG_PTR SearchStart)
|
|
{
|
|
return(ImporterAutoFixIATExW(ProcessId, szDumpedFile, L".RL!TEv2", false, false, NULL, NULL, SearchStart, false, false, NULL));
|
|
}
|
|
__declspec(dllexport) bool TITCALL ImporterDeleteAPI(DWORD_PTR apiAddr)
|
|
{
|
|
return scylla_cutImport(apiAddr);
|
|
}
|
|
// 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, ©Handle, 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;
|
|
/* broken since scylla integration but we dont care
|
|
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, FileHandle))
|
|
{
|
|
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();
|
|
//broken since scylla integration but we dont care
|
|
//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;
|
|
}
|
|
break;
|
|
case DLL_THREAD_ATTACH:
|
|
case DLL_THREAD_DETACH:
|
|
case DLL_PROCESS_DETACH:
|
|
if(lpReserved != NULL)
|
|
{
|
|
EngineExecutePluginReleaseCallBack();
|
|
}
|
|
break;
|
|
}
|
|
return TRUE;
|
|
}
|