mirror of https://github.com/x64dbg/GleeBug
initial GleeBug implementation ready
This commit is contained in:
parent
ebe1973c26
commit
b0b4f5ded3
|
|
@ -1,41 +0,0 @@
|
||||||
#include "GleeBug.h"
|
|
||||||
|
|
||||||
namespace GleeBug
|
|
||||||
{
|
|
||||||
//Conversion functions taken from: http://www.nubaria.com/en/blog/?p=289
|
|
||||||
std::string Utf16ToUtf8(const std::wstring & wstr)
|
|
||||||
{
|
|
||||||
std::string convertedString;
|
|
||||||
auto requiredSize = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, nullptr, 0, nullptr, nullptr);
|
|
||||||
if(requiredSize > 0)
|
|
||||||
{
|
|
||||||
std::vector<char> buffer(requiredSize);
|
|
||||||
WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, &buffer[0], requiredSize, nullptr, nullptr);
|
|
||||||
convertedString.assign(buffer.begin(), buffer.end() - 1);
|
|
||||||
}
|
|
||||||
return convertedString;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Utf16ToUtf8(const wchar_t* wstr)
|
|
||||||
{
|
|
||||||
return Utf16ToUtf8(wstr ? std::wstring(wstr) : std::wstring());
|
|
||||||
}
|
|
||||||
|
|
||||||
std::wstring Utf8ToUtf16(const std::string & str)
|
|
||||||
{
|
|
||||||
std::wstring convertedString;
|
|
||||||
int requiredSize = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, nullptr, 0);
|
|
||||||
if(requiredSize > 0)
|
|
||||||
{
|
|
||||||
std::vector<wchar_t> buffer(requiredSize);
|
|
||||||
MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, &buffer[0], requiredSize);
|
|
||||||
convertedString.assign(buffer.begin(), buffer.end() - 1);
|
|
||||||
}
|
|
||||||
return convertedString;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::wstring Utf8ToUtf16(const char* str)
|
|
||||||
{
|
|
||||||
return Utf8ToUtf16(str ? std::string(str) : std::string());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
@ -70,11 +70,6 @@ namespace GleeBug
|
||||||
return a.second < b.first;
|
return a.second < b.first;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string Utf16ToUtf8(const std::wstring & wstr);
|
|
||||||
std::string Utf16ToUtf8(const wchar_t* wstr);
|
|
||||||
std::wstring Utf8ToUtf16(const std::string & str);
|
|
||||||
std::wstring Utf8ToUtf16(const char* str);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //GLEEBUG_H
|
#endif //GLEEBUG_H
|
||||||
|
|
@ -167,7 +167,6 @@
|
||||||
<ClCompile Include="Debugger.Thread.HardwareBreakpoint.cpp" />
|
<ClCompile Include="Debugger.Thread.HardwareBreakpoint.cpp" />
|
||||||
<ClCompile Include="Debugger.Thread.Registers.cpp" />
|
<ClCompile Include="Debugger.Thread.Registers.cpp" />
|
||||||
<ClCompile Include="Debugger.Thread.Registers.GetSet.cpp" />
|
<ClCompile Include="Debugger.Thread.Registers.GetSet.cpp" />
|
||||||
<ClCompile Include="GleeBug.cpp" />
|
|
||||||
<ClCompile Include="Static.BufferFile.cpp" />
|
<ClCompile Include="Static.BufferFile.cpp" />
|
||||||
<ClCompile Include="Static.File.cpp" />
|
<ClCompile Include="Static.File.cpp" />
|
||||||
<ClCompile Include="Static.Pattern.cpp" />
|
<ClCompile Include="Static.Pattern.cpp" />
|
||||||
|
|
|
||||||
|
|
@ -83,9 +83,6 @@
|
||||||
<ClCompile Include="Static.Pattern.cpp">
|
<ClCompile Include="Static.Pattern.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="GleeBug.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="zyan-disassembler-engine\src\Decoder.c">
|
<ClCompile Include="zyan-disassembler-engine\src\Decoder.c">
|
||||||
<Filter>Source Files\Zydis</Filter>
|
<Filter>Source Files\Zydis</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
#include <GleeBug/Debugger.h>
|
#include <GleeBug/Debugger.h>
|
||||||
|
#include <GleeBug/Static.Pe.h>
|
||||||
|
#include <GleeBug/Static.Bufferfile.h>
|
||||||
#include "TitanEngine.h"
|
#include "TitanEngine.h"
|
||||||
#include "ntdll.h"
|
#include "ntdll.h"
|
||||||
|
#include "FileMap.h"
|
||||||
|
|
||||||
using namespace GleeBug;
|
using namespace GleeBug;
|
||||||
|
|
||||||
|
|
@ -54,7 +57,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
//Memory
|
//Memory
|
||||||
bool MemoryReadSafe(HANDLE hProcess, LPVOID lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesRead) const
|
bool MemoryReadSafe(HANDLE hProcess, LPVOID lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesRead)
|
||||||
{
|
{
|
||||||
auto process = processFromHandle(hProcess);
|
auto process = processFromHandle(hProcess);
|
||||||
if (!process)
|
if (!process)
|
||||||
|
|
@ -72,6 +75,7 @@ public:
|
||||||
|
|
||||||
bool Fill(LPVOID MemoryStart, DWORD MemorySize, PBYTE FillByte)
|
bool Fill(LPVOID MemoryStart, DWORD MemorySize, PBYTE FillByte)
|
||||||
{
|
{
|
||||||
|
//TODO: this is fucking inefficient
|
||||||
if (!mProcess)
|
if (!mProcess)
|
||||||
return false;
|
return false;
|
||||||
for (DWORD i = 0; i < MemorySize; i++)
|
for (DWORD i = 0; i < MemorySize; i++)
|
||||||
|
|
@ -177,25 +181,30 @@ public:
|
||||||
return PebAddress;
|
return PebAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* GetTEBLocation(HANDLE hThread)
|
static bool getThreadInfo(HANDLE hThread, THREAD_BASIC_INFORMATION & tbi)
|
||||||
{
|
{
|
||||||
ULONG RequiredLen = 0;
|
ULONG RequiredLen = 0;
|
||||||
void* TebAddress = 0;
|
|
||||||
THREAD_BASIC_INFORMATION myThreadBasicInformation[5] = { 0 };
|
THREAD_BASIC_INFORMATION myThreadBasicInformation[5] = { 0 };
|
||||||
|
|
||||||
if(NtQueryInformationThread(hThread, ThreadBasicInformation, myThreadBasicInformation, sizeof(THREAD_BASIC_INFORMATION), &RequiredLen) == 0)
|
if(NtQueryInformationThread(hThread, ThreadBasicInformation, myThreadBasicInformation, sizeof(THREAD_BASIC_INFORMATION), &RequiredLen) == 0)
|
||||||
{
|
{
|
||||||
TebAddress = (void*)myThreadBasicInformation->TebBaseAddress;
|
tbi = myThreadBasicInformation[0];
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(NtQueryInformationThread(hThread, ThreadBasicInformation, myThreadBasicInformation, RequiredLen, &RequiredLen) == 0)
|
if(NtQueryInformationThread(hThread, ThreadBasicInformation, myThreadBasicInformation, RequiredLen, &RequiredLen) == 0)
|
||||||
{
|
{
|
||||||
TebAddress = (void*)myThreadBasicInformation->TebBaseAddress;
|
tbi = myThreadBasicInformation[0];
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return TebAddress;
|
void* GetTEBLocation(HANDLE hThread)
|
||||||
|
{
|
||||||
|
THREAD_BASIC_INFORMATION tbi;
|
||||||
|
return getThreadInfo(hThread, tbi) ? tbi.TebBaseAddress : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HideDebugger(HANDLE hProcess, DWORD PatchAPILevel)
|
bool HideDebugger(HANDLE hProcess, DWORD PatchAPILevel)
|
||||||
|
|
@ -232,11 +241,13 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
//Registers
|
//Registers
|
||||||
ULONG_PTR GetContextDataEx(HANDLE hActiveThread, DWORD IndexOfRegister) const
|
ULONG_PTR GetContextDataEx(HANDLE hActiveThread, DWORD IndexOfRegister)
|
||||||
{
|
{
|
||||||
auto thread = threadFromHandle(hActiveThread);
|
if(!hActiveThread)
|
||||||
if (!thread)
|
|
||||||
return 0;
|
return 0;
|
||||||
|
auto thread = threadFromHandle(hActiveThread);
|
||||||
|
if(!thread)
|
||||||
|
__debugbreak(); //return 0;
|
||||||
if(mIsRunning)
|
if(mIsRunning)
|
||||||
thread->RegReadContext();
|
thread->RegReadContext();
|
||||||
return thread->registers.Get(registerFromDword(IndexOfRegister));
|
return thread->registers.Get(registerFromDword(IndexOfRegister));
|
||||||
|
|
@ -246,7 +257,7 @@ public:
|
||||||
{
|
{
|
||||||
auto thread = threadFromHandle(hActiveThread);
|
auto thread = threadFromHandle(hActiveThread);
|
||||||
if (!thread)
|
if (!thread)
|
||||||
return false;
|
__debugbreak(); //return false;
|
||||||
if(mIsRunning)
|
if(mIsRunning)
|
||||||
thread->RegReadContext();
|
thread->RegReadContext();
|
||||||
thread->registers.Set(registerFromDword(IndexOfRegister), NewRegisterValue);
|
thread->registers.Set(registerFromDword(IndexOfRegister), NewRegisterValue);
|
||||||
|
|
@ -255,11 +266,13 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetFullContextDataEx(HANDLE hActiveThread, TITAN_ENGINE_CONTEXT_t* titcontext) const
|
bool GetFullContextDataEx(HANDLE hActiveThread, TITAN_ENGINE_CONTEXT_t* titcontext)
|
||||||
{
|
{
|
||||||
|
if(!hActiveThread)
|
||||||
|
return false;
|
||||||
auto thread = threadFromHandle(hActiveThread);
|
auto thread = threadFromHandle(hActiveThread);
|
||||||
if (!thread || !titcontext)
|
if (!thread || !titcontext)
|
||||||
return false;
|
__debugbreak(); //return false;
|
||||||
if(mIsRunning)
|
if(mIsRunning)
|
||||||
thread->RegReadContext();
|
thread->RegReadContext();
|
||||||
memset(titcontext, 0, sizeof(TITAN_ENGINE_CONTEXT_t));
|
memset(titcontext, 0, sizeof(TITAN_ENGINE_CONTEXT_t));
|
||||||
|
|
@ -303,7 +316,7 @@ public:
|
||||||
{
|
{
|
||||||
auto thread = threadFromHandle(hActiveThread);
|
auto thread = threadFromHandle(hActiveThread);
|
||||||
if (!thread || !titcontext)
|
if (!thread || !titcontext)
|
||||||
return false;
|
__debugbreak(); //return false;
|
||||||
if(mIsRunning)
|
if(mIsRunning)
|
||||||
thread->RegReadContext();
|
thread->RegReadContext();
|
||||||
thread->registers.Gax = titcontext->cax;
|
thread->registers.Gax = titcontext->cax;
|
||||||
|
|
@ -357,77 +370,149 @@ public:
|
||||||
memset(x87FPURegisters, 0, sizeof(x87FPURegister_t) * 8);
|
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
|
//PE
|
||||||
bool StaticFileLoadW(const wchar_t* szFileName, DWORD DesiredAccess, bool SimulateLoad, LPHANDLE FileHandle, LPDWORD LoadedSize, LPHANDLE FileMap, PULONG_PTR FileMapVA)
|
bool StaticFileLoadW(const wchar_t* szFileName, DWORD DesiredAccess, bool SimulateLoad, LPHANDLE FileHandle, LPDWORD LoadedSize, LPHANDLE FileMap, PULONG_PTR FileMapVA)
|
||||||
{
|
{
|
||||||
//TODO
|
auto file = new ::FileMap<unsigned char>;
|
||||||
return false;
|
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)
|
bool StaticFileUnloadW(const wchar_t* szFileName, bool CommitChanges, HANDLE FileHandle, DWORD LoadedSize, HANDLE FileMap, ULONG_PTR FileMapVA)
|
||||||
{
|
{
|
||||||
//TODO
|
auto found = mappedFiles.find(FileMapVA);
|
||||||
return false;
|
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)
|
ULONG_PTR ConvertFileOffsetToVA(ULONG_PTR FileMapVA, ULONG_PTR AddressToConvert, bool ReturnType)
|
||||||
{
|
{
|
||||||
//TODO
|
auto found = mappedFiles.find(FileMapVA);
|
||||||
return 0;
|
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)
|
ULONG_PTR ConvertVAtoFileOffsetEx(ULONG_PTR FileMapVA, DWORD FileSize, ULONG_PTR ImageBase, ULONG_PTR AddressToConvert, bool AddressIsRVA, bool ReturnType)
|
||||||
{
|
{
|
||||||
//TODO
|
auto found = mappedFiles.find(FileMapVA);
|
||||||
return 0;
|
if(found == mappedFiles.end())
|
||||||
|
__debugbreak(); //return 0;
|
||||||
|
if(!found->second.pe->IsValidPe())
|
||||||
|
__debugbreak(); //return 0;
|
||||||
|
return found->second.pe->ConvertRvaToOffset(uint32(AddressToConvert));
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG_PTR GetPE32DataFromMappedFile(ULONG_PTR FileMapVA, DWORD WhichSection, DWORD WhichData)
|
ULONG_PTR GetPE32DataFromMappedFile(ULONG_PTR FileMapVA, DWORD WhichSection, DWORD WhichData)
|
||||||
{
|
{
|
||||||
//TODO
|
auto found = mappedFiles.find(FileMapVA);
|
||||||
|
if(found == mappedFiles.end())
|
||||||
|
__debugbreak(); //return 0;
|
||||||
|
if(!found->second.pe->IsValidPe())
|
||||||
|
__debugbreak(); //return 0;
|
||||||
|
#ifdef _WIN64
|
||||||
|
if(!found->second.pe->IsPe64()) __debugbreak(); //return 0;
|
||||||
|
auto headers = found->second.pe->GetNtHeaders64();
|
||||||
|
#else
|
||||||
|
if(found->second.pe->IsPe64()) __debugbreak(); //return 0;
|
||||||
|
auto headers = found->second.pe->GetNtHeaders32();
|
||||||
|
#endif //_WIN64
|
||||||
|
const auto & sections = found->second.pe->GetSections();
|
||||||
switch(WhichData)
|
switch(WhichData)
|
||||||
{
|
{
|
||||||
case UE_PE_OFFSET:
|
case UE_PE_OFFSET:
|
||||||
break;
|
return headers.Offset();
|
||||||
case UE_IMPORTTABLEADDRESS:
|
case UE_IMPORTTABLEADDRESS:
|
||||||
break;
|
return headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
|
||||||
case UE_IMPORTTABLESIZE:
|
case UE_IMPORTTABLESIZE:
|
||||||
break;
|
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:
|
case UE_CHARACTERISTICS:
|
||||||
break;
|
return headers->FileHeader.Characteristics;
|
||||||
case UE_DLLCHARACTERISTICS:
|
case UE_DLLCHARACTERISTICS:
|
||||||
break;
|
return headers->OptionalHeader.DllCharacteristics;
|
||||||
case UE_OEP:
|
case UE_OEP:
|
||||||
break;
|
return headers->OptionalHeader.AddressOfEntryPoint;
|
||||||
case UE_SECTIONNUMBER:
|
case UE_SECTIONNUMBER:
|
||||||
break;
|
return sections.size();
|
||||||
case UE_SECTIONVIRTUALOFFSET: //WhichSection: IMAGE_DIRECTORY_ENTRY_EXCEPTION
|
case UE_SECTIONVIRTUALOFFSET: //WhichSection: IMAGE_DIRECTORY_ENTRY_EXCEPTION
|
||||||
break;
|
return WhichSection < sections.size() ? sections[WhichSection].GetHeader().VirtualAddress : 0;
|
||||||
case UE_SECTIONVIRTUALSIZE: //WhichSection: IMAGE_DIRECTORY_ENTRY_EXCEPTION
|
case UE_SECTIONVIRTUALSIZE: //WhichSection: IMAGE_DIRECTORY_ENTRY_EXCEPTION
|
||||||
break;
|
return WhichSection < sections.size() ? sections[WhichSection].GetHeader().Misc.VirtualSize : 0;
|
||||||
case UE_SECTIONNAME:
|
case UE_SECTIONNAME:
|
||||||
break;
|
return WhichSection < sections.size() ? ULONG_PTR(§ions[WhichSection].GetHeader().Name[0]) : 0;
|
||||||
|
default:
|
||||||
|
__debugbreak();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG_PTR GetPE32DataW(const wchar_t* szFileName, DWORD WhichSection, DWORD WhichData)
|
ULONG_PTR GetPE32DataW(const wchar_t* szFileName, DWORD WhichSection, DWORD WhichData)
|
||||||
{
|
{
|
||||||
//TODO
|
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;
|
||||||
|
#ifdef _WIN64
|
||||||
|
if(!pe.IsPe64()) __debugbreak(); //return 0;
|
||||||
|
auto headers = pe.GetNtHeaders64().Data();
|
||||||
|
#else
|
||||||
|
if(pe.IsPe64()) __debugbreak(); //return 0;
|
||||||
|
auto headers = pe.GetNtHeaders32().Data();
|
||||||
|
#endif //_WIN64
|
||||||
switch(WhichData)
|
switch(WhichData)
|
||||||
{
|
{
|
||||||
|
case UE_CHARACTERISTICS:
|
||||||
|
return headers->FileHeader.Characteristics;
|
||||||
case UE_IMAGEBASE:
|
case UE_IMAGEBASE:
|
||||||
break;
|
return headers->OptionalHeader.ImageBase;
|
||||||
case UE_OEP:
|
case UE_OEP:
|
||||||
break;
|
return headers->OptionalHeader.AddressOfEntryPoint;
|
||||||
|
default:
|
||||||
|
__debugbreak();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsFileDLLW(const wchar_t* szFileName, ULONG_PTR FileMapVA)
|
bool IsFileDLLW(const wchar_t* szFileName, ULONG_PTR FileMapVA)
|
||||||
{
|
{
|
||||||
//TODO
|
return (GetPE32DataW(szFileName, NULL, UE_CHARACTERISTICS) & IMAGE_FILE_DLL) == IMAGE_FILE_DLL;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TLSGrabCallBackDataW(const wchar_t* szFileName, LPVOID ArrayOfCallBacks, LPDWORD NumberOfCallBacks)
|
bool TLSGrabCallBackDataW(const wchar_t* szFileName, LPVOID ArrayOfCallBacks, LPDWORD NumberOfCallBacks)
|
||||||
|
|
@ -663,20 +748,26 @@ private: //functions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread* threadFromHandle(HANDLE hThread) const
|
Thread* threadFromHandle(HANDLE hThread)
|
||||||
{
|
{
|
||||||
if(!hThread)
|
THREAD_BASIC_INFORMATION tbi;
|
||||||
return mThread;
|
if(!getThreadInfo(hThread, tbi))
|
||||||
//TODO: properly implement this
|
return nullptr;
|
||||||
return mThread;
|
auto foundP = mProcesses.find(uint32(tbi.ClientId.UniqueProcess));
|
||||||
|
if(foundP == mProcesses.end())
|
||||||
|
return nullptr;
|
||||||
|
auto foundT = foundP->second.threads.find(uint32(tbi.ClientId.UniqueThread));
|
||||||
|
if(foundT == foundP->second.threads.end())
|
||||||
|
return nullptr;
|
||||||
|
return &foundT->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
Process* processFromHandle(HANDLE hProcess) const
|
Process* processFromHandle(HANDLE hProcess)
|
||||||
{
|
{
|
||||||
if(!hProcess)
|
auto foundP = mProcesses.find(GetProcessId(hProcess));
|
||||||
return mProcess;
|
if(foundP == mProcesses.end())
|
||||||
//TODO: properly implement this
|
return nullptr;
|
||||||
return mProcess;
|
return &foundP->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HardwareType hwtypeFromTitan(DWORD type)
|
static HardwareType hwtypeFromTitan(DWORD type)
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -159,11 +159,6 @@ __declspec(dllexport) bool TITCALL StaticFileLoadW(const wchar_t* szFileName, DW
|
||||||
return emu.StaticFileLoadW(szFileName, DesiredAccess, SimulateLoad, FileHandle, LoadedSize, FileMap, FileMapVA);
|
return emu.StaticFileLoadW(szFileName, DesiredAccess, SimulateLoad, FileHandle, LoadedSize, FileMap, FileMapVA);
|
||||||
}
|
}
|
||||||
|
|
||||||
__declspec(dllexport) bool TITCALL StaticFileLoad(const char* szFileName, DWORD DesiredAccess, bool SimulateLoad, LPHANDLE FileHandle, LPDWORD LoadedSize, LPHANDLE FileMap, PULONG_PTR FileMapVA)
|
|
||||||
{
|
|
||||||
return StaticFileLoadW(Utf8ToUtf16(szFileName).c_str(), 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)
|
__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);
|
return emu.StaticFileUnloadW(szFileName, CommitChanges, FileHandle, LoadedSize, FileMap, FileMapVA);
|
||||||
|
|
@ -194,11 +189,6 @@ __declspec(dllexport) ULONG_PTR TITCALL GetPE32DataW(const wchar_t* szFileName,
|
||||||
return emu.GetPE32DataW(szFileName, WhichSection, WhichData);
|
return emu.GetPE32DataW(szFileName, WhichSection, WhichData);
|
||||||
}
|
}
|
||||||
|
|
||||||
__declspec(dllexport) ULONG_PTR TITCALL GetPE32Data(const char* szFileName, DWORD WhichSection, DWORD WhichData)
|
|
||||||
{
|
|
||||||
return GetPE32DataW(Utf8ToUtf16(szFileName).c_str(), WhichSection, WhichData);
|
|
||||||
}
|
|
||||||
|
|
||||||
__declspec(dllexport) bool TITCALL IsFileDLLW(const wchar_t* szFileName, ULONG_PTR FileMapVA)
|
__declspec(dllexport) bool TITCALL IsFileDLLW(const wchar_t* szFileName, ULONG_PTR FileMapVA)
|
||||||
{
|
{
|
||||||
return emu.IsFileDLLW(szFileName, FileMapVA);
|
return emu.IsFileDLLW(szFileName, FileMapVA);
|
||||||
|
|
|
||||||
|
|
@ -154,6 +154,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Emulator.h" />
|
<ClInclude Include="Emulator.h" />
|
||||||
|
<ClInclude Include="FileMap.h" />
|
||||||
<ClInclude Include="TitanEngine.h" />
|
<ClInclude Include="TitanEngine.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
|
|
||||||
|
|
@ -22,5 +22,8 @@
|
||||||
<ClInclude Include="Emulator.h">
|
<ClInclude Include="Emulator.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="FileMap.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
Loading…
Reference in New Issue