mirror of https://github.com/x64dbg/TitanEngine
413 lines
15 KiB
C++
413 lines
15 KiB
C++
#include "stdafx.h"
|
|
#include "definitions.h"
|
|
#include "Global.Handle.h"
|
|
#include "Global.Mapping.h"
|
|
#include "Global.Engine.h"
|
|
|
|
static char* szSharedOverlay = 0;
|
|
static wchar_t* szSharedOverlayW = 0;
|
|
|
|
__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) 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);
|
|
}
|