mirror of https://github.com/x64dbg/TitanEngine
804 lines
34 KiB
C++
804 lines
34 KiB
C++
#include "stdafx.h"
|
|
#include "definitions.h"
|
|
#include "Global.Mapping.h"
|
|
#include "Global.Engine.h"
|
|
#include "Global.Garbage.h"
|
|
|
|
static LPVOID RelocationData = NULL;
|
|
LPVOID RelocationLastPage = NULL;
|
|
LPVOID RelocationStartPosition = NULL;
|
|
LPVOID RelocationWritePosition = NULL;
|
|
ULONG_PTR RelocationOldImageBase;
|
|
ULONG_PTR RelocationNewImageBase;
|
|
|
|
// 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.Protect;
|
|
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;
|
|
DynBuf mem;
|
|
|
|
if(RelocationData != NULL)
|
|
{
|
|
VirtualQueryEx(hProcess, (LPVOID)MemoryStart, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
|
|
OldProtect = MemInfo.Protect;
|
|
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 = mem.Allocate(MemorySize);
|
|
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);
|
|
}
|
|
return(RelocaterGrabRelocationTable(hProcess, MemoryStart, (DWORD)((ULONG_PTR)ReadMemoryStorage - (ULONG_PTR)mReadMemoryStorage)));
|
|
}
|
|
else
|
|
{
|
|
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;
|
|
}
|