add StaticEngine project

This commit is contained in:
Duncan Ogilvie 2019-08-19 16:14:53 +02:00
parent 85846e4ed1
commit 7ac6950874
10 changed files with 2953 additions and 0 deletions

View File

@ -15,6 +15,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TitanEngineEmulator", "Tita
{B65A3680-9B6B-44E6-A046-649F94DF9F56} = {B65A3680-9B6B-44E6-A046-649F94DF9F56} {B65A3680-9B6B-44E6-A046-649F94DF9F56} = {B65A3680-9B6B-44E6-A046-649F94DF9F56}
EndProjectSection EndProjectSection
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StaticEngine", "StaticEngine\StaticEngine.vcxproj", "{8E0C7F46-89CC-4510-BC17-07513A31BC7E}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32 Debug|Win32 = Debug|Win32
@ -47,8 +49,19 @@ Global
{2790D540-B51E-48F1-B8E9-F14F2EEAA676}.Release|Win32.Build.0 = Release|Win32 {2790D540-B51E-48F1-B8E9-F14F2EEAA676}.Release|Win32.Build.0 = Release|Win32
{2790D540-B51E-48F1-B8E9-F14F2EEAA676}.Release|x64.ActiveCfg = Release|x64 {2790D540-B51E-48F1-B8E9-F14F2EEAA676}.Release|x64.ActiveCfg = Release|x64
{2790D540-B51E-48F1-B8E9-F14F2EEAA676}.Release|x64.Build.0 = Release|x64 {2790D540-B51E-48F1-B8E9-F14F2EEAA676}.Release|x64.Build.0 = Release|x64
{8E0C7F46-89CC-4510-BC17-07513A31BC7E}.Debug|Win32.ActiveCfg = Debug|Win32
{8E0C7F46-89CC-4510-BC17-07513A31BC7E}.Debug|Win32.Build.0 = Debug|Win32
{8E0C7F46-89CC-4510-BC17-07513A31BC7E}.Debug|x64.ActiveCfg = Debug|x64
{8E0C7F46-89CC-4510-BC17-07513A31BC7E}.Debug|x64.Build.0 = Debug|x64
{8E0C7F46-89CC-4510-BC17-07513A31BC7E}.Release|Win32.ActiveCfg = Release|Win32
{8E0C7F46-89CC-4510-BC17-07513A31BC7E}.Release|Win32.Build.0 = Release|Win32
{8E0C7F46-89CC-4510-BC17-07513A31BC7E}.Release|x64.ActiveCfg = Release|x64
{8E0C7F46-89CC-4510-BC17-07513A31BC7E}.Release|x64.Build.0 = Release|x64
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {0F087011-78BB-4D18-A1E5-69DD2B8BDEC3}
EndGlobalSection
EndGlobal EndGlobal

713
StaticEngine/Emulator.h Normal file
View File

@ -0,0 +1,713 @@
#include "TitanEngine.h"
#include <Psapi.h>
#include <TlHelp32.h>
#include <unordered_map>
#include "ntdll.h"
#include "FileMap.h"
#include <GleeBug/Static.Pe.h>
#include <GleeBug/Static.Bufferfile.h>
#pragma comment(lib, "psapi.lib")
//https://www.codeproject.com/Questions/78801/How-to-get-the-main-thread-ID-of-a-process-known-b
#ifndef MAKEULONGLONG
#define MAKEULONGLONG(ldw, hdw) ((ULONGLONG(hdw) << 32) | ((ldw) & 0xFFFFFFFF))
#endif
#ifndef MAXULONGLONG
#define MAXULONGLONG ((ULONGLONG)~((ULONGLONG)0))
#endif
using namespace GleeBug;
class Emulator
{
public:
HINSTANCE engineHandle;
//Debugger
PROCESS_INFORMATION* InitDebugW(const wchar_t* szFileName, const wchar_t* szCommandLine, const wchar_t* szCurrentFolder)
{
//TODO
mCbATTACHBREAKPOINT = nullptr;
return nullptr;
}
PROCESS_INFORMATION* InitDLLDebugW(const wchar_t* szFileName, bool ReserveModuleBase, const wchar_t* szCommandLine, const wchar_t* szCurrentFolder, LPVOID EntryCallBack)
{
//TODO
return nullptr;
}
bool StopDebug()
{
SetEvent(hEvent);
return true;
}
static std::vector<HMODULE> enumModules(HANDLE hProcess)
{
std::vector<HMODULE> result;
DWORD cbNeeded = 0;
if(EnumProcessModules(hProcess, nullptr, 0, &cbNeeded))
{
result.resize(cbNeeded / sizeof(HMODULE));
if(!EnumProcessModules(hProcess, result.data(), cbNeeded, &cbNeeded))
result.clear();
}
return result;
}
static std::wstring getModuleName(HANDLE hProcess, HMODULE hModule)
{
wchar_t szFileName[MAX_PATH] = L"";
if(!GetModuleFileNameExW(hProcess, hModule, szFileName, _countof(szFileName)))
*szFileName = L'\0';
return szFileName;
}
static MODULEINFO getModuleInfo(HANDLE hProcess, HMODULE hModule)
{
MODULEINFO info;
if(!GetModuleInformation(hProcess, hModule, &info, sizeof(MODULEINFO)))
memset(&info, 0, sizeof(info));
return info;
}
void getThreadList(DWORD dwProcessId)
{
//https://blogs.msdn.microsoft.com/oldnewthing/20060223-14/?p=32173
HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if(h != INVALID_HANDLE_VALUE)
{
THREADENTRY32 te;
te.dwSize = sizeof(te);
ULONGLONG ullMinCreateTime = MAXULONGLONG;
dwMainThreadId = 0;
if(Thread32First(h, &te))
{
do
{
if(te.dwSize >= FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + sizeof(te.th32OwnerProcessID) && te.th32OwnerProcessID == dwProcessId)
{
auto hThread = TitanOpenThread(THREAD_ALL_ACCESS, FALSE, te.th32ThreadID);
mThreadList[te.th32ThreadID] = hThread;
FILETIME afTimes[4] = { 0 };
if(GetThreadTimes(hThread, &afTimes[0], &afTimes[1], &afTimes[2], &afTimes[3]))
{
ULONGLONG ullTest = MAKEULONGLONG(afTimes[0].dwLowDateTime, afTimes[0].dwHighDateTime);
if(ullTest && ullTest < ullMinCreateTime)
{
ullMinCreateTime = ullTest;
dwMainThreadId = te.th32ThreadID;
}
}
else if(!dwMainThreadId)
dwMainThreadId = te.th32ThreadID;
}
te.dwSize = sizeof(te);
} while(Thread32Next(h, &te));
}
CloseHandle(h);
}
}
DWORD dwMainThreadId;
std::unordered_map<DWORD, HANDLE> mThreadList;
bool mIsDebugging = false;
PVOID mEntryPoint;
HANDLE hEvent;
bool cleanup(bool result)
{
if(mProcessInfo.hProcess)
CloseHandle(mProcessInfo.hProcess);
if(mProcessInfo.hThread)
CloseHandle(mProcessInfo.hThread);
for(auto it : mThreadList)
CloseHandle(it.second);
mThreadList.clear();
mIsDebugging = false;
return result;
}
bool AttachDebugger(DWORD ProcessId, bool KillOnExit, LPVOID DebugInfo, LPVOID CallBack)
{
//initialization + open process
mCbATTACHBREAKPOINT = STEPCALLBACK(CallBack);
mAttachProcessInfo = (PROCESS_INFORMATION*)DebugInfo;
memset(&mProcessInfo, 0, sizeof(PROCESS_INFORMATION));
mProcessInfo.dwProcessId = ProcessId;
mProcessInfo.hProcess = TitanOpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessId);
if(!mProcessInfo.hProcess)
return cleanup(false);
//get threads
getThreadList(mProcessInfo.dwProcessId);
if(!mThreadList.count(dwMainThreadId))
return cleanup(false);
mProcessInfo.dwThreadId = dwMainThreadId;
mProcessInfo.hThread = mThreadList[dwMainThreadId];
*mAttachProcessInfo = mProcessInfo;
//create process
CREATE_PROCESS_DEBUG_INFO createProcess;
memset(&createProcess, 0, sizeof(CREATE_PROCESS_DEBUG_INFO));
auto mods = enumModules(mProcessInfo.hProcess);
if(mods.empty())
return cleanup(false);
auto mainMod = mods[0]; //undocumented might not be always true
auto mainName = getModuleName(mProcessInfo.hProcess, mainMod);
auto mainInfo = getModuleInfo(mProcessInfo.hProcess, mainMod);
if(!mainInfo.lpBaseOfDll || mainName.empty())
return cleanup(false);
mIsDebugging = true;
createProcess.hFile = CreateFileW(mainName.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr);
createProcess.hProcess = mProcessInfo.hProcess;
createProcess.hThread = mProcessInfo.hThread;
createProcess.lpBaseOfImage = mainMod;
createProcess.lpStartAddress = LPTHREAD_START_ROUTINE(mEntryPoint = mainInfo.EntryPoint);
createProcess.lpThreadLocalBase = GetTEBLocation(createProcess.hThread);
mCbCREATEPROCESS(&createProcess);
CloseHandle(createProcess.hFile);
memset(&mDebugEvent, 0, sizeof(DEBUG_EVENT));
mDebugEvent.dwProcessId = mProcessInfo.dwProcessId;
mDebugEvent.dwThreadId = mProcessInfo.dwThreadId;
//load modules
for(size_t i = 1; i < mods.size(); i++)
{
LOAD_DLL_DEBUG_INFO loadDll;
memset(&loadDll, 0, sizeof(LOAD_DLL_DEBUG_INFO));
loadDll.lpBaseOfDll = mods[i];
auto dllName = getModuleName(mProcessInfo.hProcess, mods[i]);
if(!dllName.empty())
loadDll.hFile = CreateFileW(dllName.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr);
mCbLOADDLL(&loadDll);
if(!dllName.empty())
CloseHandle(loadDll.hFile);
}
//create threads
for(auto it : mThreadList)
{
if(it.first == dwMainThreadId)
continue;
CREATE_THREAD_DEBUG_INFO createThread;
memset(&createThread, 0, sizeof(CREATE_THREAD_DEBUG_INFO));
createThread.hThread = it.second;
ULONG len = sizeof(PVOID);
if(NtQueryInformationThread(createThread.hThread, ThreadQuerySetWin32StartAddress, &createThread.lpStartAddress, len, &len))
createThread.lpStartAddress = nullptr;
createThread.lpThreadLocalBase = GetTEBLocation(createThread.hThread);
mCbCREATETHREAD(&createThread);
}
//create the event that gets trigged in StopDebug
hEvent = CreateEventW(nullptr, FALSE, FALSE, nullptr);
//attach breakpoint
mCbATTACHBREAKPOINT();
//system breakpoint
mCbSYSTEMBREAKPOINT(nullptr);
//return after stop/detach is called
WaitForSingleObject(hEvent, INFINITE);
CloseHandle(hEvent);
return cleanup(true);
}
bool DetachDebuggerEx(DWORD ProcessId)
{
//TODO
return false;
}
void DebugLoop()
{
//TODO
}
void SetNextDbgContinueStatus(DWORD SetDbgCode)
{
//TODO
}
//Memory
bool MemoryReadSafe(HANDLE hProcess, LPVOID lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesRead) const
{
SIZE_T s;
if(!lpNumberOfBytesRead)
lpNumberOfBytesRead = &s;
return !!ReadProcessMemory(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesRead);
}
bool MemoryWriteSafe(HANDLE hProcess, LPVOID lpBaseAddress, LPCVOID lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesWritten)
{
SIZE_T s;
if(!lpNumberOfBytesWritten)
lpNumberOfBytesWritten = &s;
return !!WriteProcessMemory(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesWritten);
}
bool Fill(LPVOID MemoryStart, DWORD MemorySize, PBYTE FillByte)
{
//TODO
return false;
}
//Engine
bool EngineCheckStructAlignment(DWORD StructureType, ULONG_PTR StructureSize) const
{
if (StructureType == UE_STRUCT_TITAN_ENGINE_CONTEXT)
return StructureSize == sizeof(TITAN_ENGINE_CONTEXT_t);
return false;
}
bool IsFileBeingDebugged() const
{
return mIsDebugging;
}
DEBUG_EVENT* GetDebugData()
{
return &mDebugEvent;
}
void SetCustomHandler(DWORD ExceptionId, PVOID CallBack)
{
switch (ExceptionId)
{
case UE_CH_CREATEPROCESS:
mCbCREATEPROCESS = CUSTOMHANDLER(CallBack);
break;
case UE_CH_EXITPROCESS:
mCbEXITPROCESS = CUSTOMHANDLER(CallBack);
break;
case UE_CH_CREATETHREAD:
mCbCREATETHREAD = CUSTOMHANDLER(CallBack);
break;
case UE_CH_EXITTHREAD:
mCbEXITTHREAD = CUSTOMHANDLER(CallBack);
break;
case UE_CH_SYSTEMBREAKPOINT:
mCbSYSTEMBREAKPOINT = CUSTOMHANDLER(CallBack);
break;
case UE_CH_LOADDLL:
mCbLOADDLL = CUSTOMHANDLER(CallBack);
break;
case UE_CH_UNLOADDLL:
mCbUNLOADDLL = CUSTOMHANDLER(CallBack);
break;
case UE_CH_OUTPUTDEBUGSTRING:
mCbOUTPUTDEBUGSTRING = CUSTOMHANDLER(CallBack);
break;
case UE_CH_UNHANDLEDEXCEPTION:
mCbUNHANDLEDEXCEPTION = CUSTOMHANDLER(CallBack);
break;
case UE_CH_DEBUGEVENT:
mCbDEBUGEVENT = CUSTOMHANDLER(CallBack);
break;
default:
break;
}
}
void SetEngineVariable(DWORD VariableId, bool VariableSet)
{
if(VariableId == UE_ENGINE_SET_DEBUG_PRIVILEGE)
mSetDebugPrivilege = VariableSet;
}
//Misc
void* GetPEBLocation(HANDLE hProcess)
{
ULONG RequiredLen = 0;
void* PebAddress = 0;
PROCESS_BASIC_INFORMATION myProcessBasicInformation[5] = { 0 };
if(NtQueryInformationProcess(hProcess, ProcessBasicInformation, myProcessBasicInformation, sizeof(PROCESS_BASIC_INFORMATION), &RequiredLen) == 0)
{
PebAddress = (void*)myProcessBasicInformation->PebBaseAddress;
}
else
{
if(NtQueryInformationProcess(hProcess, ProcessBasicInformation, myProcessBasicInformation, RequiredLen, &RequiredLen) == 0)
{
PebAddress = (void*)myProcessBasicInformation->PebBaseAddress;
}
}
return PebAddress;
}
void* GetTEBLocation(HANDLE hThread)
{
ULONG RequiredLen = 0;
void* TebAddress = 0;
THREAD_BASIC_INFORMATION myThreadBasicInformation[5] = { 0 };
if(NtQueryInformationThread(hThread, ThreadBasicInformation, myThreadBasicInformation, sizeof(THREAD_BASIC_INFORMATION), &RequiredLen) == 0)
{
TebAddress = (void*)myThreadBasicInformation->TebBaseAddress;
}
else
{
if(NtQueryInformationThread(hThread, ThreadBasicInformation, myThreadBasicInformation, RequiredLen, &RequiredLen) == 0)
{
TebAddress = (void*)myThreadBasicInformation->TebBaseAddress;
}
}
return TebAddress;
}
bool HideDebugger(HANDLE hProcess, DWORD PatchAPILevel)
{
//TODO
return false;
}
HANDLE TitanOpenProcess(DWORD dwDesiredAccess, bool bInheritHandle, DWORD dwProcessId)
{
if (mSetDebugPrivilege)
setDebugPrivilege(GetCurrentProcess(), true);
HANDLE hProcess = OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId);
DWORD dwLastError = GetLastError();
if (mSetDebugPrivilege)
setDebugPrivilege(GetCurrentProcess(), false);
SetLastError(dwLastError);
return hProcess;
}
HANDLE TitanOpenThread(DWORD dwDesiredAccess, bool bInheritHandle, DWORD dwThreadId)
{
if (mSetDebugPrivilege)
setDebugPrivilege(GetCurrentProcess(), true);
HANDLE hThread = OpenThread(dwDesiredAccess, bInheritHandle, dwThreadId);
DWORD dwLastError = GetLastError();
if (mSetDebugPrivilege)
setDebugPrivilege(GetCurrentProcess(), false);
SetLastError(dwLastError);
return hThread;
}
//Registers
ULONG_PTR GetContextDataEx(HANDLE hActiveThread, DWORD IndexOfRegister) const
{
switch(IndexOfRegister)
{
case UE_EIP:
case UE_RIP:
case UE_CIP:
return ULONG_PTR(mEntryPoint);
}
//TODO
return 0;
}
bool SetContextDataEx(HANDLE hActiveThread, DWORD IndexOfRegister, ULONG_PTR NewRegisterValue)
{
//TODO
return false;
}
bool GetFullContextDataEx(HANDLE hActiveThread, TITAN_ENGINE_CONTEXT_t* titcontext) const
{
//TODO
titcontext->cip = ULONG_PTR(mEntryPoint);
return true;
}
bool SetFullContextDataEx(HANDLE hActiveThread, TITAN_ENGINE_CONTEXT_t* titcontext)
{
//TODO
return false;
}
void GetMMXRegisters(uint64_t mmx[8], TITAN_ENGINE_CONTEXT_t* titcontext)
{
//TODO
memset(mmx, 0, sizeof(uint64_t) * 8);
}
void Getx87FPURegisters(x87FPURegister_t x87FPURegisters[8], TITAN_ENGINE_CONTEXT_t* titcontext)
{
//TODO
memset(x87FPURegisters, 0, sizeof(x87FPURegister_t) * 8);
}
struct MappedPe
{
FileMap<unsigned char>* file;
BufferFile* buffer;
Pe* pe;
};
std::unordered_map<ULONG_PTR, MappedPe> mappedFiles;
//PE
bool StaticFileLoadW(const wchar_t* szFileName, DWORD DesiredAccess, bool SimulateLoad, LPHANDLE FileHandle, LPDWORD LoadedSize, LPHANDLE FileMap, PULONG_PTR FileMapVA)
{
auto file = new ::FileMap<unsigned char>;
if (!file->Map(szFileName, DesiredAccess == UE_ACCESS_ALL))
__debugbreak(); //return false;
*FileHandle = file->hFile;
*LoadedSize = file->size;
*FileMap = file->hMap;
*FileMapVA = ULONG_PTR(file->data);
MappedPe mappedPe;
mappedPe.file = std::move(file);
mappedPe.buffer = new BufferFile(mappedPe.file->data, mappedPe.file->size);
mappedPe.pe = new Pe(*mappedPe.buffer);
if (mappedPe.pe->Parse(true) != Pe::ErrorOk)
__debugbreak();
mappedFiles.insert({ *FileMapVA, mappedPe });
return true;
}
bool StaticFileUnloadW(const wchar_t* szFileName, bool CommitChanges, HANDLE FileHandle, DWORD LoadedSize, HANDLE FileMap, ULONG_PTR FileMapVA)
{
auto found = mappedFiles.find(FileMapVA);
if (found == mappedFiles.end())
__debugbreak(); //return false;
delete found->second.pe;
delete found->second.buffer;
delete found->second.file;
mappedFiles.erase(found);
return true;
}
ULONG_PTR ConvertFileOffsetToVA(ULONG_PTR FileMapVA, ULONG_PTR AddressToConvert, bool ReturnType)
{
auto found = mappedFiles.find(FileMapVA);
if (found == mappedFiles.end())
__debugbreak(); //return 0;
if (!found->second.pe->IsValidPe())
__debugbreak(); //return 0;
return found->second.pe->ConvertOffsetToRva(uint32(AddressToConvert));
}
ULONG_PTR ConvertVAtoFileOffsetEx(ULONG_PTR FileMapVA, DWORD FileSize, ULONG_PTR ImageBase, ULONG_PTR AddressToConvert, bool AddressIsRVA, bool ReturnType)
{
auto found = mappedFiles.find(FileMapVA);
if (found == mappedFiles.end())
__debugbreak(); //return 0;
if (!found->second.pe->IsValidPe())
__debugbreak(); //return 0;
return found->second.pe->ConvertRvaToOffset(uint32(AddressToConvert));
}
template<typename T>
ULONG_PTR GetPE32DataW_impl(const Region<T> & headers, DWORD WhichSection, DWORD WhichData, const std::vector<Section> & sections)
{
switch (WhichData)
{
case UE_PE_OFFSET:
return headers.Offset();
case UE_IMPORTTABLEADDRESS:
return headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
case UE_IMPORTTABLESIZE:
return headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size;
case UE_EXPORTTABLEADDRESS:
return headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
case UE_EXPORTTABLESIZE:
return headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
case UE_CHARACTERISTICS:
return headers->FileHeader.Characteristics;
case UE_DLLCHARACTERISTICS:
return headers->OptionalHeader.DllCharacteristics;
case UE_OEP:
return headers->OptionalHeader.AddressOfEntryPoint;
case UE_SECTIONNUMBER:
return sections.size();
case UE_SECTIONVIRTUALOFFSET: //WhichSection: IMAGE_DIRECTORY_ENTRY_EXCEPTION
return WhichSection < sections.size() ? sections.at(WhichSection).GetHeader().VirtualAddress : 0;
case UE_SECTIONVIRTUALSIZE: //WhichSection: IMAGE_DIRECTORY_ENTRY_EXCEPTION
return WhichSection < sections.size() ? sections.at(WhichSection).GetHeader().Misc.VirtualSize : 0;
case UE_SECTIONNAME:
return WhichSection < sections.size() ? ULONG_PTR(&sections.at(WhichSection).GetHeader().Name[0]) : 0;
case UE_IMAGEBASE:
return headers->OptionalHeader.ImageBase;
case UE_SIZEOFIMAGE:
return headers->OptionalHeader.SizeOfImage;
case UE_RELOCATIONTABLEADDRESS:
return headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
case UE_RELOCATIONTABLESIZE:
return headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
case UE_TLSTABLEADDRESS:
return headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress;
case UE_TLSTABLESIZE:
return headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size;
default:
__debugbreak();
}
return 0;
}
ULONG_PTR GetPE32DataFromMappedFile(ULONG_PTR FileMapVA, DWORD WhichSection, DWORD WhichData)
{
auto found = mappedFiles.find(FileMapVA);
if (found == mappedFiles.end())
__debugbreak(); //return 0;
if (!found->second.pe->IsValidPe())
__debugbreak(); //return 0;
auto sections = found->second.pe->GetSections();
return found->second.pe->IsPe64()
? GetPE32DataW_impl(found->second.pe->GetNtHeaders64(), WhichSection, WhichData, sections)
: GetPE32DataW_impl(found->second.pe->GetNtHeaders32(), WhichSection, WhichData, sections);
}
ULONG_PTR GetPE32DataW(const wchar_t* szFileName, DWORD WhichSection, DWORD WhichData)
{
FileMap<unsigned char> file;
if (!file.Map(szFileName))
__debugbreak(); //return 0;
BufferFile buf(file.data, file.size);
Pe pe(buf);
if (pe.Parse(true) != Pe::ErrorOk)
__debugbreak(); //return 0;
if (!pe.IsValidPe())
__debugbreak(); //return 0;
auto sections = pe.GetSections();
return pe.IsPe64()
? GetPE32DataW_impl(pe.GetNtHeaders64(), WhichSection, WhichData, sections)
: GetPE32DataW_impl(pe.GetNtHeaders32(), WhichSection, WhichData, sections);
}
bool IsFileDLLW(const wchar_t* szFileName, ULONG_PTR FileMapVA)
{
return (GetPE32DataW(szFileName, NULL, UE_CHARACTERISTICS) & IMAGE_FILE_DLL) == IMAGE_FILE_DLL;
}
//Software Breakpoints
bool SetBPX(ULONG_PTR bpxAddress, DWORD bpxType, LPVOID bpxCallBack)
{
//TODO
return false;
}
bool DeleteBPX(ULONG_PTR bpxAddress)
{
//TODO
return false;
}
bool IsBPXEnabled(ULONG_PTR bpxAddress)
{
//TODO
return false;
}
void SetBPXOptions(long DefaultBreakPointType)
{
}
//Memory Breakpoints
bool SetMemoryBPXEx(ULONG_PTR MemoryStart, SIZE_T SizeOfMemory, DWORD BreakPointType, bool RestoreOnHit, LPVOID bpxCallBack)
{
//TODO
return false;
}
bool RemoveMemoryBPX(ULONG_PTR MemoryStart, SIZE_T SizeOfMemory)
{
//TODO
return false;
}
//Hardware Breakpoints
bool SetHardwareBreakPoint(ULONG_PTR bpxAddress, DWORD IndexOfRegister, DWORD bpxType, DWORD bpxSize, LPVOID bpxCallBack)
{
//TODO
return false;
}
bool DeleteHardwareBreakPoint(DWORD IndexOfRegister)
{
//TODO
return false;
}
bool GetUnusedHardwareBreakPointRegister(LPDWORD RegisterIndex)
{
//TODO
return false;
}
//Generic Breakpoints
bool RemoveAllBreakPoints(DWORD RemoveOption)
{
//TODO
return false;
}
//Stepping
void StepOver(LPVOID CallBack)
{
//TODO
}
void StepInto(LPVOID CallBack)
{
//TODO
}
private: //functions
static DWORD setDebugPrivilege(HANDLE hProcess, bool bEnablePrivilege)
{
DWORD dwLastError;
HANDLE hToken = 0;
if (!OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
{
dwLastError = GetLastError();
if (hToken)
CloseHandle(hToken);
return dwLastError;
}
TOKEN_PRIVILEGES tokenPrivileges;
memset(&tokenPrivileges, 0, sizeof(TOKEN_PRIVILEGES));
LUID luid;
if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid))
{
dwLastError = GetLastError();
CloseHandle(hToken);
return dwLastError;
}
tokenPrivileges.PrivilegeCount = 1;
tokenPrivileges.Privileges[0].Luid = luid;
if (bEnablePrivilege)
tokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
else
tokenPrivileges.Privileges[0].Attributes = 0;
AdjustTokenPrivileges(hToken, FALSE, &tokenPrivileges, sizeof(TOKEN_PRIVILEGES), NULL, NULL);
dwLastError = GetLastError();
CloseHandle(hToken);
return dwLastError;
}
private: //variables
bool mSetDebugPrivilege = false;
typedef void(*CUSTOMHANDLER)(const void*);
typedef void(*STEPCALLBACK)();
typedef STEPCALLBACK BPCALLBACK;
typedef CUSTOMHANDLER HWBPCALLBACK;
typedef CUSTOMHANDLER MEMBPCALLBACK;
CUSTOMHANDLER mCbCREATEPROCESS = nullptr;
CUSTOMHANDLER mCbEXITPROCESS = nullptr;
CUSTOMHANDLER mCbCREATETHREAD = nullptr;
CUSTOMHANDLER mCbEXITTHREAD = nullptr;
CUSTOMHANDLER mCbSYSTEMBREAKPOINT = nullptr;
CUSTOMHANDLER mCbLOADDLL = nullptr;
CUSTOMHANDLER mCbUNLOADDLL = nullptr;
CUSTOMHANDLER mCbOUTPUTDEBUGSTRING = nullptr;
CUSTOMHANDLER mCbUNHANDLEDEXCEPTION = nullptr;
CUSTOMHANDLER mCbDEBUGEVENT = nullptr;
STEPCALLBACK mCbATTACHBREAKPOINT = nullptr;
PROCESS_INFORMATION* mAttachProcessInfo = nullptr;
PROCESS_INFORMATION mProcessInfo;
DEBUG_EVENT mDebugEvent;
};

57
StaticEngine/FileMap.h Normal file
View File

@ -0,0 +1,57 @@
#pragma once
#include <windows.h>
template<typename T>
struct FileMap
{
HANDLE hFile = INVALID_HANDLE_VALUE;
HANDLE hMap = nullptr;
T* data = nullptr;
unsigned int size = 0;
FileMap() { }
~FileMap()
{
Unmap();
}
FileMap(const FileMap<T> &) = delete;
FileMap(FileMap<T> && other)
{
other.hFile = hFile;
other.hMap = hMap;
other.data = data;
other.size = size;
}
bool Map(const wchar_t* szFileName, bool write = false)
{
hFile = CreateFileW(szFileName, GENERIC_READ | (write ? GENERIC_WRITE : 0), FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr);
if(hFile != INVALID_HANDLE_VALUE)
{
size = GetFileSize(hFile, nullptr);
hMap = CreateFileMappingW(hFile, nullptr, write ? PAGE_READWRITE : PAGE_READONLY, 0, 0, nullptr);
if(hMap)
data = (T*)MapViewOfFile(hMap, write ? FILE_MAP_WRITE : FILE_MAP_READ, 0, 0, 0);
}
return data != nullptr;
}
void Unmap()
{
if(data)
UnmapViewOfFile(data);
if(hMap)
CloseHandle(hMap);
if(hFile != INVALID_HANDLE_VALUE)
CloseHandle(hFile);
hFile = INVALID_HANDLE_VALUE;
hMap = nullptr;
data = nullptr;
size = 0;
}
};

View File

@ -0,0 +1,163 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{8E0C7F46-89CC-4510-BC17-07513A31BC7E}</ProjectGuid>
<RootNamespace>StaticEngine</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140_xp</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140_xp</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140_xp</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140_xp</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<TargetName>StaticEngine</TargetName>
<TargetExt>.dll</TargetExt>
<IncludePath>$(SolutionDir);$(IncludePath)</IncludePath>
<OutDir>$(SolutionDir)bin\$(Configuration)\x32\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<TargetName>StaticEngine</TargetName>
<TargetExt>.dll</TargetExt>
<IncludePath>$(SolutionDir);$(IncludePath)</IncludePath>
<OutDir>$(SolutionDir)bin\$(Configuration)\x64\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<TargetName>StaticEngine</TargetName>
<TargetExt>.dll</TargetExt>
<IncludePath>$(SolutionDir);$(IncludePath)</IncludePath>
<OutDir>$(SolutionDir)bin\$(Configuration)\x32\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetName>StaticEngine</TargetName>
<TargetExt>.dll</TargetExt>
<IncludePath>$(SolutionDir);$(IncludePath)</IncludePath>
<OutDir>$(SolutionDir)bin\$(Configuration)\x64\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>$(SolutionDir)bin\$(Configuration)\x32\GleeBug.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Windows</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>$(SolutionDir)bin\$(Configuration)\x64\GleeBug.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Windows</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>$(SolutionDir)bin\$(Configuration)\x32\GleeBug.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Windows</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>$(SolutionDir)bin\$(Configuration)\x64\GleeBug.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Windows</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="TitanEngineEmulator.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Emulator.h" />
<ClInclude Include="FileMap.h" />
<ClInclude Include="TitanEngine.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="TitanEngineEmulator.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="TitanEngine.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Emulator.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="FileMap.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

1117
StaticEngine/TitanEngine.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,251 @@
#include <windows.h>
#include "Emulator.h"
Emulator emu;
//Debugger basics
__declspec(dllexport) void* TITCALL InitDebugW(const wchar_t* szFileName, const wchar_t* szCommandLine, const wchar_t* szCurrentFolder)
{
return emu.InitDebugW(szFileName, szCommandLine, szCurrentFolder);
}
__declspec(dllexport) void* TITCALL InitDLLDebugW(const wchar_t* szFileName, bool ReserveModuleBase, const wchar_t* szCommandLine, const wchar_t* szCurrentFolder, LPVOID EntryCallBack)
{
return emu.InitDLLDebugW(szFileName, ReserveModuleBase, szCommandLine, szCurrentFolder, EntryCallBack);
}
__declspec(dllexport) bool TITCALL StopDebug()
{
return emu.StopDebug();
}
__declspec(dllexport) bool TITCALL AttachDebugger(DWORD ProcessId, bool KillOnExit, LPVOID DebugInfo, LPVOID CallBack)
{
return emu.AttachDebugger(ProcessId, KillOnExit, DebugInfo, CallBack);
}
__declspec(dllexport) bool TITCALL DetachDebuggerEx(DWORD ProcessId)
{
return emu.DetachDebuggerEx(ProcessId);
}
__declspec(dllexport) void TITCALL DebugLoop()
{
emu.DebugLoop();
}
__declspec(dllexport) void TITCALL SetNextDbgContinueStatus(DWORD SetDbgCode)
{
emu.SetNextDbgContinueStatus(SetDbgCode);
}
//Memory
__declspec(dllexport) bool TITCALL MemoryReadSafe(HANDLE hProcess, LPVOID lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesRead)
{
return emu.MemoryReadSafe(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesRead);
}
__declspec(dllexport) bool TITCALL MemoryWriteSafe(HANDLE hProcess, LPVOID lpBaseAddress, LPCVOID lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesWritten)
{
return emu.MemoryWriteSafe(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesWritten);
}
__declspec(dllexport) bool TITCALL Fill(LPVOID MemoryStart, DWORD MemorySize, PBYTE FillByte)
{
return emu.Fill(MemoryStart, MemorySize, FillByte);
}
//Engine
__declspec(dllexport) bool TITCALL EngineCheckStructAlignment(DWORD StructureType, ULONG_PTR StructureSize)
{
return emu.EngineCheckStructAlignment(StructureType, StructureSize);
}
__declspec(dllexport) bool TITCALL IsFileBeingDebugged()
{
return emu.IsFileBeingDebugged();
}
__declspec(dllexport) void* TITCALL GetDebugData()
{
return emu.GetDebugData();
}
__declspec(dllexport) void TITCALL SetCustomHandler(DWORD ExceptionId, LPVOID CallBack)
{
emu.SetCustomHandler(ExceptionId, CallBack);
}
__declspec(dllexport) void TITCALL SetEngineVariable(DWORD VariableId, bool VariableSet)
{
emu.SetEngineVariable(VariableId, VariableSet);
}
//Misc
__declspec(dllexport) void* TITCALL GetPEBLocation(HANDLE hProcess)
{
return emu.GetPEBLocation(hProcess);
}
__declspec(dllexport) void* TITCALL GetTEBLocation(HANDLE hThread)
{
return emu.GetTEBLocation(hThread);
}
__declspec(dllexport) bool TITCALL HideDebugger(HANDLE hProcess, DWORD PatchAPILevel)
{
return emu.HideDebugger(hProcess, PatchAPILevel);
}
__declspec(dllexport) HANDLE TITCALL TitanOpenProcess(DWORD dwDesiredAccess, bool bInheritHandle, DWORD dwProcessId)
{
return emu.TitanOpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId);
}
__declspec(dllexport) HANDLE TITCALL TitanOpenThread(DWORD dwDesiredAccess, bool bInheritHandle, DWORD dwThreadId)
{
return emu.TitanOpenThread(dwDesiredAccess, bInheritHandle, dwThreadId);
}
//Registers
__declspec(dllexport) ULONG_PTR TITCALL GetContextDataEx(HANDLE hActiveThread, DWORD IndexOfRegister)
{
return emu.GetContextDataEx(hActiveThread, IndexOfRegister);
}
__declspec(dllexport) bool TITCALL SetContextDataEx(HANDLE hActiveThread, DWORD IndexOfRegister, ULONG_PTR NewRegisterValue)
{
return emu.SetContextDataEx(hActiveThread, IndexOfRegister, NewRegisterValue);
}
__declspec(dllexport) bool TITCALL GetFullContextDataEx(HANDLE hActiveThread, TITAN_ENGINE_CONTEXT_t* titcontext)
{
return emu.GetFullContextDataEx(hActiveThread, titcontext);
}
__declspec(dllexport) bool TITCALL SetFullContextDataEx(HANDLE hActiveThread, TITAN_ENGINE_CONTEXT_t* titcontext)
{
return emu.SetFullContextDataEx(hActiveThread, titcontext);
}
__declspec(dllexport) void TITCALL GetMMXRegisters(uint64_t mmx[8], TITAN_ENGINE_CONTEXT_t* titcontext)
{
emu.GetMMXRegisters(mmx, titcontext);
}
__declspec(dllexport) void TITCALL Getx87FPURegisters(x87FPURegister_t x87FPURegisters[8], TITAN_ENGINE_CONTEXT_t* titcontext)
{
emu.Getx87FPURegisters(x87FPURegisters, titcontext);
}
//PE
__declspec(dllexport) bool TITCALL StaticFileLoadW(const wchar_t* szFileName, DWORD DesiredAccess, bool SimulateLoad, LPHANDLE FileHandle, LPDWORD LoadedSize, LPHANDLE FileMap, PULONG_PTR FileMapVA)
{
return emu.StaticFileLoadW(szFileName, DesiredAccess, SimulateLoad, FileHandle, LoadedSize, FileMap, FileMapVA);
}
__declspec(dllexport) bool TITCALL StaticFileUnloadW(const wchar_t* szFileName, bool CommitChanges, HANDLE FileHandle, DWORD LoadedSize, HANDLE FileMap, ULONG_PTR FileMapVA)
{
return emu.StaticFileUnloadW(szFileName, CommitChanges, FileHandle, LoadedSize, FileMap, FileMapVA);
}
__declspec(dllexport) ULONG_PTR TITCALL ConvertFileOffsetToVA(ULONG_PTR FileMapVA, ULONG_PTR AddressToConvert, bool ReturnType)
{
return emu.ConvertFileOffsetToVA(FileMapVA, AddressToConvert, ReturnType);
}
__declspec(dllexport) ULONG_PTR TITCALL ConvertVAtoFileOffsetEx(ULONG_PTR FileMapVA, DWORD FileSize, ULONG_PTR ImageBase, ULONG_PTR AddressToConvert, bool AddressIsRVA, bool ReturnType)
{
return emu.ConvertVAtoFileOffsetEx(FileMapVA, FileSize, ImageBase, AddressToConvert, AddressIsRVA, ReturnType);
}
__declspec(dllexport) ULONG_PTR TITCALL GetPE32DataFromMappedFile(ULONG_PTR FileMapVA, DWORD WhichSection, DWORD WhichData)
{
return emu.GetPE32DataFromMappedFile(FileMapVA, WhichSection, WhichData);
}
__declspec(dllexport) ULONG_PTR TITCALL GetPE32DataW(const wchar_t* szFileName, DWORD WhichSection, DWORD WhichData)
{
return emu.GetPE32DataW(szFileName, WhichSection, WhichData);
}
__declspec(dllexport) bool TITCALL IsFileDLLW(const wchar_t* szFileName, ULONG_PTR FileMapVA)
{
return emu.IsFileDLLW(szFileName, FileMapVA);
}
//Software Breakpoints
__declspec(dllexport) bool TITCALL SetBPX(ULONG_PTR bpxAddress, DWORD bpxType, LPVOID bpxCallBack)
{
return emu.SetBPX(bpxAddress, bpxType, bpxCallBack);
}
__declspec(dllexport) bool TITCALL DeleteBPX(ULONG_PTR bpxAddress)
{
return emu.DeleteBPX(bpxAddress);
}
__declspec(dllexport) bool TITCALL IsBPXEnabled(ULONG_PTR bpxAddress)
{
return emu.IsBPXEnabled(bpxAddress);
}
__declspec(dllexport) void TITCALL SetBPXOptions(long DefaultBreakPointType)
{
emu.SetBPXOptions(DefaultBreakPointType);
}
//Memory Breakpoints
__declspec(dllexport) bool TITCALL SetMemoryBPXEx(ULONG_PTR MemoryStart, SIZE_T SizeOfMemory, DWORD BreakPointType, bool RestoreOnHit, LPVOID bpxCallBack)
{
return emu.SetMemoryBPXEx(MemoryStart, SizeOfMemory, BreakPointType, RestoreOnHit, bpxCallBack);
}
__declspec(dllexport) bool TITCALL RemoveMemoryBPX(ULONG_PTR MemoryStart, SIZE_T SizeOfMemory)
{
return emu.RemoveMemoryBPX(MemoryStart, SizeOfMemory);
}
//Hardware Breakpoints
__declspec(dllexport) bool TITCALL SetHardwareBreakPoint(ULONG_PTR bpxAddress, DWORD IndexOfRegister, DWORD bpxType, DWORD bpxSize, LPVOID bpxCallBack)
{
return emu.SetHardwareBreakPoint(bpxAddress, IndexOfRegister, bpxType, bpxSize, bpxCallBack);
}
__declspec(dllexport) bool TITCALL DeleteHardwareBreakPoint(DWORD IndexOfRegister)
{
return emu.DeleteHardwareBreakPoint(IndexOfRegister);
}
__declspec(dllexport) bool TITCALL GetUnusedHardwareBreakPointRegister(LPDWORD RegisterIndex)
{
return emu.GetUnusedHardwareBreakPointRegister(RegisterIndex);
}
//Generic Breakpoints
__declspec(dllexport) bool TITCALL RemoveAllBreakPoints(DWORD RemoveOption)
{
return emu.RemoveAllBreakPoints(RemoveOption);
}
//Stepping
__declspec(dllexport) void TITCALL StepOver(LPVOID traceCallBack)
{
emu.StepOver(traceCallBack);
}
__declspec(dllexport) void TITCALL StepInto(LPVOID traceCallBack)
{
emu.StepInto(traceCallBack);
}
BOOL WINAPI DllMain(
_In_ HINSTANCE hinstDLL,
_In_ DWORD fdwReason,
_In_ LPVOID lpvReserved
)
{
if (fdwReason == DLL_PROCESS_ATTACH)
emu.engineHandle = hinstDLL;
return TRUE;
}

610
StaticEngine/ntdll.h Normal file
View File

@ -0,0 +1,610 @@
#pragma once
#include <windows.h>
#ifndef _WIN64
#pragma comment(lib, "ntdll_x86.lib")
#else
#pragma comment(lib, "ntdll_x64.lib")
#endif
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
typedef LONG NTSTATUS;
typedef LONG KPRIORITY;
typedef struct _CLIENT_ID
{
HANDLE UniqueProcess;
HANDLE UniqueThread;
} CLIENT_ID, *PCLIENT_ID;
typedef enum _KTHREAD_STATE
{
Initialized,
Ready,
Running,
Standby,
Terminated,
Waiting,
Transition,
DeferredReady,
GateWait
} KTHREAD_STATE;
typedef enum _KWAIT_REASON
{
Executive,
FreePage,
PageIn,
PoolAllocation,
DelayExecution,
Suspended,
UserRequest,
WrExecutive,
WrFreePage,
WrPageIn,
WrPoolAllocation,
WrDelayExecution,
WrSuspended,
WrUserRequest,
WrEventPair,
WrQueue,
WrLpcReceive,
WrLpcReply,
WrVirtualMemory,
WrPageOut,
WrRendezvous,
Spare2,
Spare3,
Spare4,
Spare5,
Spare6,
WrKernel,
WrResource,
WrPushLock,
WrMutex,
WrQuantumEnd,
WrDispatchInt,
WrPreempted,
WrYieldExecution,
WrFastMutex,
WrGuardedMutex,
WrRundown,
MaximumWaitReason
} KWAIT_REASON;
typedef struct _UNICODE_STRING
{
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
typedef struct _SYSTEM_SESSION_PROCESS_INFORMATION
{
ULONG SessionId;
ULONG SizeOfBuf;
PVOID Buffer;
} SYSTEM_SESSION_PROCESS_INFORMATION, *PSYSTEM_SESSION_PROCESS_INFORMATION;
typedef struct _SYSTEM_THREAD_INFORMATION
{
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER CreateTime;
ULONG WaitTime;
PVOID StartAddress;
CLIENT_ID ClientId;
KPRIORITY Priority;
LONG BasePriority;
ULONG ContextSwitches;
ULONG ThreadState;
ULONG WaitReason;
} SYSTEM_THREAD_INFORMATION, *PSYSTEM_THREAD_INFORMATION;
typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO
{
USHORT UniqueProcessId;
USHORT CreatorBackTraceIndex;
UCHAR ObjectTypeIndex;
UCHAR HandleAttributes;
USHORT HandleValue;
PVOID Object;
ULONG GrantedAccess;
} SYSTEM_HANDLE_TABLE_ENTRY_INFO, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO;
typedef struct _SYSTEM_HANDLE_INFORMATION
{
ULONG NumberOfHandles;
SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[1];
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
typedef struct _SYSTEM_EXTENDED_THREAD_INFORMATION
{
SYSTEM_THREAD_INFORMATION ThreadInfo;
PVOID StackBase;
PVOID StackLimit;
PVOID Win32StartAddress;
PVOID TebAddress; /* This is only filled in on Vista and above */
ULONG_PTR Reserved2;
ULONG_PTR Reserved3;
ULONG_PTR Reserved4;
} SYSTEM_EXTENDED_THREAD_INFORMATION, *PSYSTEM_EXTENDED_THREAD_INFORMATION;
typedef struct _SYSTEM_PROCESS_INFORMATION
{
ULONG NextEntryOffset;
ULONG NumberOfThreads;
LARGE_INTEGER SpareLi1;
LARGE_INTEGER SpareLi2;
LARGE_INTEGER SpareLi3;
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ImageName;
KPRIORITY BasePriority;
HANDLE UniqueProcessId;
HANDLE InheritedFromUniqueProcessId;
ULONG HandleCount;
ULONG SessionId;
ULONG_PTR PageDirectoryBase;
SIZE_T PeakVirtualSize;
SIZE_T VirtualSize;
ULONG PageFaultCount;
SIZE_T PeakWorkingSetSize;
SIZE_T WorkingSetSize;
SIZE_T QuotaPeakPagedPoolUsage;
SIZE_T QuotaPagedPoolUsage;
SIZE_T QuotaPeakNonPagedPoolUsage;
SIZE_T QuotaNonPagedPoolUsage;
SIZE_T PagefileUsage;
SIZE_T PeakPagefileUsage;
SIZE_T PrivatePageCount;
LARGE_INTEGER ReadOperationCount;
LARGE_INTEGER WriteOperationCount;
LARGE_INTEGER OtherOperationCount;
LARGE_INTEGER ReadTransferCount;
LARGE_INTEGER WriteTransferCount;
LARGE_INTEGER OtherTransferCount;
SYSTEM_THREAD_INFORMATION Threads[1];
} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;
typedef struct _OBJECT_BASIC_INFORMATION
{
ULONG Attributes;
ACCESS_MASK GrantedAccess;
ULONG HandleCount;
ULONG PointerCount;
ULONG PagedPoolCharge;
ULONG NonPagedPoolCharge;
ULONG Reserved[ 3 ];
ULONG NameInfoSize;
ULONG TypeInfoSize;
ULONG SecurityDescriptorSize;
LARGE_INTEGER CreationTime;
} OBJECT_BASIC_INFORMATION, *POBJECT_BASIC_INFORMATION;
typedef struct _OBJECT_NAME_INFORMATION
{
UNICODE_STRING Name;
} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;
typedef struct _OBJECT_TYPE_INFORMATION
{
UNICODE_STRING TypeName;
ULONG TotalNumberOfObjects;
ULONG TotalNumberOfHandles;
ULONG TotalPagedPoolUsage;
ULONG TotalNonPagedPoolUsage;
ULONG TotalNamePoolUsage;
ULONG TotalHandleTableUsage;
ULONG HighWaterNumberOfObjects;
ULONG HighWaterNumberOfHandles;
ULONG HighWaterPagedPoolUsage;
ULONG HighWaterNonPagedPoolUsage;
ULONG HighWaterNamePoolUsage;
ULONG HighWaterHandleTableUsage;
ULONG InvalidAttributes;
GENERIC_MAPPING GenericMapping;
ULONG ValidAccessMask;
BOOLEAN SecurityRequired;
BOOLEAN MaintainHandleCount;
ULONG PoolType;
ULONG DefaultPagedPoolCharge;
ULONG DefaultNonPagedPoolCharge;
} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;
typedef struct _OBJECT_TYPES_INFORMATION
{
ULONG NumberOfTypes;
OBJECT_TYPE_INFORMATION TypeInformation[1];
} OBJECT_TYPES_INFORMATION, *POBJECT_TYPES_INFORMATION;
//typedef struct _PUBLIC_OBJECT_BASIC_INFORMATION
//{
// ULONG Attributes;
// ACCESS_MASK GrantedAccess;
// ULONG HandleCount;
// ULONG PointerCount;
//
// ULONG Reserved[10]; // reserved for internal use
//
//} PUBLIC_OBJECT_BASIC_INFORMATION, *PPUBLIC_OBJECT_BASIC_INFORMATION;
typedef struct __PUBLIC_OBJECT_TYPE_INFORMATION
{
UNICODE_STRING TypeName;
ULONG Reserved [22]; // reserved for internal use
} PUBLIC_OBJECT_TYPE_INFORMATION, *PPUBLIC_OBJECT_TYPE_INFORMATION;
typedef struct _PROCESS_BASIC_INFORMATION
{
PVOID Reserved1;
PVOID PebBaseAddress;
PVOID Reserved2[2];
ULONG_PTR UniqueProcessId;
PVOID Reserved3;
} PROCESS_BASIC_INFORMATION;
typedef PROCESS_BASIC_INFORMATION* PPROCESS_BASIC_INFORMATION;
typedef struct _THREAD_BASIC_INFORMATION
{
NTSTATUS ExitStatus;
PVOID TebBaseAddress;
CLIENT_ID ClientId;
ULONG_PTR AffinityMask;
KPRIORITY Priority;
LONG BasePriority;
} THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION;
typedef
VOID
(*PPS_APC_ROUTINE)(
__in_opt PVOID ApcArgument1,
__in_opt PVOID ApcArgument2,
__in_opt PVOID ApcArgument3
);
typedef enum _PROCESSINFOCLASS
{
ProcessBasicInformation,
ProcessQuotaLimits,
ProcessIoCounters,
ProcessVmCounters,
ProcessTimes,
ProcessBasePriority,
ProcessRaisePriority,
ProcessDebugPort,
ProcessExceptionPort,
ProcessAccessToken,
ProcessLdtInformation,
ProcessLdtSize,
ProcessDefaultHardErrorMode,
ProcessIoPortHandlers, // Note: this is kernel mode only
ProcessPooledUsageAndLimits,
ProcessWorkingSetWatch,
ProcessUserModeIOPL,
ProcessEnableAlignmentFaultFixup,
ProcessPriorityClass,
ProcessWx86Information,
ProcessHandleCount,
ProcessAffinityMask,
ProcessPriorityBoost,
ProcessDeviceMap,
ProcessSessionInformation,
ProcessForegroundInformation,
ProcessWow64Information,
ProcessImageFileName,
ProcessLUIDDeviceMapsEnabled,
ProcessBreakOnTermination,
ProcessDebugObjectHandle,
ProcessDebugFlags,
ProcessHandleTracing,
ProcessIoPriority,
ProcessExecuteFlags,
ProcessResourceManagement,
ProcessCookie,
ProcessImageInformation,
MaxProcessInfoClass // MaxProcessInfoClass should always be the last enum
} PROCESSINFOCLASS;
typedef enum _SYSTEM_INFORMATION_CLASS
{
SystemBasicInformation,
SystemProcessorInformation, // obsolete...delete
SystemPerformanceInformation,
SystemTimeOfDayInformation,
SystemPathInformation,
SystemProcessInformation,
SystemCallCountInformation,
SystemDeviceInformation,
SystemProcessorPerformanceInformation,
SystemFlagsInformation,
SystemCallTimeInformation,
SystemModuleInformation,
SystemLocksInformation,
SystemStackTraceInformation,
SystemPagedPoolInformation,
SystemNonPagedPoolInformation,
SystemHandleInformation,
SystemObjectInformation,
SystemPageFileInformation,
SystemVdmInstemulInformation,
SystemVdmBopInformation,
SystemFileCacheInformation,
SystemPoolTagInformation,
SystemInterruptInformation,
SystemDpcBehaviorInformation,
SystemFullMemoryInformation,
SystemLoadGdiDriverInformation,
SystemUnloadGdiDriverInformation,
SystemTimeAdjustmentInformation,
SystemSummaryMemoryInformation,
SystemMirrorMemoryInformation,
SystemPerformanceTraceInformation,
SystemObsolete0,
SystemExceptionInformation,
SystemCrashDumpStateInformation,
SystemKernelDebuggerInformation,
SystemContextSwitchInformation,
SystemRegistryQuotaInformation,
SystemExtendServiceTableInformation,
SystemPrioritySeperation,
SystemVerifierAddDriverInformation,
SystemVerifierRemoveDriverInformation,
SystemProcessorIdleInformation,
SystemLegacyDriverInformation,
SystemCurrentTimeZoneInformation,
SystemLookasideInformation,
SystemTimeSlipNotification,
SystemSessionCreate,
SystemSessionDetach,
SystemSessionInformation,
SystemRangeStartInformation,
SystemVerifierInformation,
SystemVerifierThunkExtend,
SystemSessionProcessInformation,
SystemLoadGdiDriverInSystemSpace,
SystemNumaProcessorMap,
SystemPrefetcherInformation,
SystemExtendedProcessInformation,
SystemRecommendedSharedDataAlignment,
SystemComPlusPackage,
SystemNumaAvailableMemory,
SystemProcessorPowerInformation,
SystemEmulationBasicInformation,
SystemEmulationProcessorInformation,
SystemExtendedHandleInformation,
SystemLostDelayedWriteInformation,
SystemBigPoolInformation,
SystemSessionPoolTagInformation,
SystemSessionMappedViewInformation,
SystemHotpatchInformation,
SystemObjectSecurityMode,
SystemWatchdogTimerHandler,
SystemWatchdogTimerInformation,
SystemLogicalProcessorInformation,
SystemWow64SharedInformation,
SystemRegisterFirmwareTableInformationHandler,
SystemFirmwareTableInformation,
SystemModuleInformationEx,
SystemVerifierTriageInformation,
SystemSuperfetchInformation,
SystemMemoryListInformation,
SystemFileCacheInformationEx,
MaxSystemInfoClass // MaxSystemInfoClass should always be the last enum
} SYSTEM_INFORMATION_CLASS;
typedef enum _OBJECT_INFORMATION_CLASS
{
ObjectBasicInformation,
ObjectNameInformation,
ObjectTypeInformation,
ObjectTypesInformation,
ObjectHandleFlagInformation,
ObjectSessionInformation,
MaxObjectInfoClass // MaxObjectInfoClass should always be the last enum
} OBJECT_INFORMATION_CLASS;
typedef enum _THREADINFOCLASS
{
ThreadBasicInformation,
ThreadTimes,
ThreadPriority,
ThreadBasePriority,
ThreadAffinityMask,
ThreadImpersonationToken,
ThreadDescriptorTableEntry,
ThreadEnableAlignmentFaultFixup,
ThreadEventPair_Reusable,
ThreadQuerySetWin32StartAddress,
ThreadZeroTlsCell,
ThreadPerformanceCount,
ThreadAmILastThread,
ThreadIdealProcessor,
ThreadPriorityBoost,
ThreadSetTlsArrayAddress,
ThreadIsIoPending,
ThreadHideFromDebugger,
ThreadBreakOnTermination,
ThreadSwitchLegacyState,
ThreadIsTerminated,
MaxThreadInfoClass
} THREADINFOCLASS;
#ifdef __cplusplus
extern "C" {
#endif
NTSYSCALLAPI
NTSTATUS
NTAPI
NtSetInformationProcess(
__in HANDLE ProcessHandle,
__in PROCESSINFOCLASS ProcessInformationClass,
__in_bcount(ProcessInformationLength) PVOID ProcessInformation,
__in ULONG ProcessInformationLength
);
NTSYSCALLAPI
NTSTATUS
NTAPI
NtQueryInformationProcess(
__in HANDLE ProcessHandle,
__in PROCESSINFOCLASS ProcessInformationClass,
__out_bcount(ProcessInformationLength) PVOID ProcessInformation,
__in ULONG ProcessInformationLength,
__out_opt PULONG ReturnLength
);
NTSYSCALLAPI
NTSTATUS
NTAPI
NtQueryObject(
__in HANDLE Handle,
__in OBJECT_INFORMATION_CLASS ObjectInformationClass,
__out_bcount_opt(ObjectInformationLength) PVOID ObjectInformation,
__in ULONG ObjectInformationLength,
__out_opt PULONG ReturnLength
);
NTSYSCALLAPI
NTSTATUS
NTAPI
NtSetSystemInformation(
__in SYSTEM_INFORMATION_CLASS SystemInformationClass,
__in_bcount_opt(SystemInformationLength) PVOID SystemInformation,
__in ULONG SystemInformationLength
);
NTSYSCALLAPI
NTSTATUS
NTAPI
NtQuerySystemInformation(
__in SYSTEM_INFORMATION_CLASS SystemInformationClass,
__out_bcount_opt(SystemInformationLength) PVOID SystemInformation,
__in ULONG SystemInformationLength,
__out_opt PULONG ReturnLength
);
NTSYSCALLAPI
NTSTATUS
NTAPI
NtSetInformationThread(
__in HANDLE ThreadHandle,
__in THREADINFOCLASS ThreadInformationClass,
__in_bcount(ThreadInformationLength) PVOID ThreadInformation,
__in ULONG ThreadInformationLength
);
NTSYSCALLAPI
NTSTATUS
NTAPI
NtQueryInformationThread(
__in HANDLE ThreadHandle,
__in THREADINFOCLASS ThreadInformationClass,
__out_bcount(ThreadInformationLength) PVOID ThreadInformation,
__in ULONG ThreadInformationLength,
__out_opt PULONG ReturnLength
);
NTSYSCALLAPI
NTSTATUS
NTAPI
NtUnmapViewOfSection(
__in HANDLE ProcessHandle,
__in PVOID BaseAddress
);
NTSYSCALLAPI
NTSTATUS
NTAPI
NtSuspendThread(
__in HANDLE ThreadHandle,
__out_opt PULONG PreviousSuspendCount
);
NTSYSCALLAPI
NTSTATUS
NTAPI
NtResumeThread(
__in HANDLE ThreadHandle,
__out_opt PULONG PreviousSuspendCount
);
NTSYSCALLAPI
NTSTATUS
NTAPI
NtSuspendProcess(
__in HANDLE ProcessHandle
);
NTSYSCALLAPI
NTSTATUS
NTAPI
NtResumeProcess(
__in HANDLE ProcessHandle
);
NTSYSCALLAPI
NTSTATUS
NTAPI
NtQueueApcThread(
__in HANDLE ThreadHandle,
__in PPS_APC_ROUTINE ApcRoutine,
__in_opt PVOID ApcArgument1,
__in_opt PVOID ApcArgument2,
__in_opt PVOID ApcArgument3
);
NTSYSCALLAPI
NTSTATUS
NTAPI
RtlGetCompressionWorkSpaceSize(
IN USHORT CompressionFormatAndEngine,
OUT PULONG CompressBufferWorkSpaceSize,
OUT PULONG CompressFragmentWorkSpaceSize
);
NTSYSCALLAPI
NTSTATUS
NTAPI
RtlCompressBuffer(
IN USHORT CompressionFormatAndEngine,
IN PUCHAR UncompressedBuffer,
IN ULONG UncompressedBufferSize,
OUT PUCHAR CompressedBuffer,
IN ULONG CompressedBufferSize,
IN ULONG UncompressedChunkSize,
OUT PULONG FinalCompressedSize,
IN PVOID WorkSpace
);
NTSYSCALLAPI
NTSTATUS
NTAPI
RtlDecompressBuffer(
IN USHORT CompressionFormat,
OUT PUCHAR UncompressedBuffer,
IN ULONG UncompressedBufferSize,
IN PUCHAR CompressedBuffer,
IN ULONG CompressedBufferSize,
OUT PULONG FinalUncompressedSize
);
NTSYSCALLAPI
ULONG
NTAPI
RtlNtStatusToDosError(
NTSTATUS Status
);
#ifdef __cplusplus
};
#endif

BIN
StaticEngine/ntdll_x64.lib Normal file

Binary file not shown.

BIN
StaticEngine/ntdll_x86.lib Normal file

Binary file not shown.