mirror of https://github.com/x64dbg/TitanEngine
296 lines
14 KiB
C++
296 lines
14 KiB
C++
#include "stdafx.h"
|
|
#include "definitions.h"
|
|
#include "Global.OEPFinder.h"
|
|
#include "Global.Engine.h"
|
|
#include "Global.Breakpoints.h"
|
|
#include "Global.Debugger.h"
|
|
#include "Global.Mapping.h"
|
|
#include "Global.Handle.h"
|
|
|
|
GenericOEPTracerData glbEntryTracerData = {};
|
|
|
|
// Global.FindOEP.functions:
|
|
void GenericOEPVirtualProtectHit()
|
|
{
|
|
MEMORY_BASIC_INFORMATION MemInfo;
|
|
DWORD MaximumBreakPoints = 0;
|
|
DWORD NewProtect = 0;
|
|
DWORD OldProtect = 0;
|
|
|
|
int bpcount=BreakPointBuffer.size();
|
|
for(int i=0; i<bpcount; i++)
|
|
{
|
|
BreakPointDetail curDetail=BreakPointBuffer.at(i);
|
|
if(curDetail.BreakPointType == UE_MEMORY && curDetail.BreakPointActive == UE_BPXACTIVE)
|
|
{
|
|
VirtualQueryEx(dbgProcessInformation.hProcess, (LPVOID)curDetail.BreakPointAddress, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
|
|
OldProtect = MemInfo.Protect;
|
|
if(!(OldProtect & PAGE_GUARD))
|
|
{
|
|
NewProtect = OldProtect ^ PAGE_GUARD;
|
|
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)curDetail.BreakPointAddress, curDetail.BreakPointSize, NewProtect, &OldProtect);
|
|
}
|
|
}
|
|
MaximumBreakPoints++;
|
|
}
|
|
}
|
|
|
|
void GenericOEPTraceHit()
|
|
{
|
|
|
|
char* szInstructionType;
|
|
typedef void(TITCALL *fEPCallBack)();
|
|
fEPCallBack myEPCallBack = (fEPCallBack)glbEntryTracerData.EPCallBack;
|
|
LPDEBUG_EVENT myDbgEvent = (LPDEBUG_EVENT)GetDebugData();
|
|
|
|
glbEntryTracerData.MemoryAccessedFrom = (ULONG_PTR)GetContextData(UE_CIP);
|
|
glbEntryTracerData.MemoryAccessed = myDbgEvent->u.Exception.ExceptionRecord.ExceptionInformation[1];
|
|
glbEntryTracerData.AccessType = myDbgEvent->u.Exception.ExceptionRecord.ExceptionInformation[0];
|
|
szInstructionType = (char*)DisassembleEx(dbgProcessInformation.hProcess, (void*)glbEntryTracerData.MemoryAccessedFrom, true);
|
|
StepInto(&GenericOEPTraceHited);
|
|
}
|
|
|
|
void GenericOEPTraceHited()
|
|
{
|
|
|
|
int i;
|
|
//void* lpHashBuffer;
|
|
char lpHashBuffer[0x1000] = {0};
|
|
bool FakeEPDetected = false;
|
|
ULONG_PTR NumberOfBytesRW;
|
|
LPDEBUG_EVENT myDbgEvent = (LPDEBUG_EVENT)GetDebugData();
|
|
typedef void(TITCALL *fEPCallBack)();
|
|
fEPCallBack myEPCallBack = (fEPCallBack)glbEntryTracerData.EPCallBack;
|
|
PMEMORY_COMPARE_HANDLER myCmpHandler;
|
|
ULONG_PTR memBpxAddress;
|
|
ULONG_PTR memBpxSize;
|
|
DWORD originalHash;
|
|
DWORD currentHash;
|
|
|
|
if(myDbgEvent->u.Exception.ExceptionRecord.ExceptionCode == STATUS_SINGLE_STEP)
|
|
{
|
|
if(glbEntryTracerData.MemoryAccessed >= glbEntryTracerData.LoadedImageBase && glbEntryTracerData.MemoryAccessed <= glbEntryTracerData.LoadedImageBase + glbEntryTracerData.SizeOfImage)
|
|
{
|
|
for(i = 0; i < glbEntryTracerData.SectionNumber; i++)
|
|
{
|
|
if(glbEntryTracerData.MemoryAccessed >= glbEntryTracerData.SectionData[i].SectionVirtualOffset + glbEntryTracerData.LoadedImageBase && glbEntryTracerData.MemoryAccessed < glbEntryTracerData.SectionData[i].SectionVirtualOffset + glbEntryTracerData.SectionData[i].SectionVirtualSize + glbEntryTracerData.LoadedImageBase)
|
|
{
|
|
if(glbEntryTracerData.AccessType == 1)
|
|
{
|
|
glbEntryTracerData.SectionData[i].AccessedAlready = true;
|
|
}
|
|
if(glbEntryTracerData.MemoryAccessedFrom >= glbEntryTracerData.SectionData[i].SectionVirtualOffset + glbEntryTracerData.LoadedImageBase && glbEntryTracerData.MemoryAccessedFrom <= glbEntryTracerData.SectionData[i].SectionVirtualOffset + glbEntryTracerData.SectionData[i].SectionVirtualSize + glbEntryTracerData.LoadedImageBase)
|
|
{
|
|
if(i != glbEntryTracerData.OriginalEntryPointNum)
|
|
{
|
|
glbEntryTracerData.SectionData[i].AccessedAlready = true;
|
|
}
|
|
memBpxAddress = (glbEntryTracerData.MemoryAccessed / sizeof(lpHashBuffer)) * sizeof(lpHashBuffer);
|
|
memBpxSize = glbEntryTracerData.SectionData[i].SectionVirtualOffset + glbEntryTracerData.SectionData[i].SectionVirtualSize + glbEntryTracerData.LoadedImageBase - memBpxAddress;
|
|
if(memBpxSize > sizeof(lpHashBuffer))
|
|
{
|
|
memBpxSize = sizeof(lpHashBuffer);
|
|
}
|
|
if(ReadProcessMemory(dbgProcessInformation.hProcess, (void*)(memBpxAddress), lpHashBuffer, memBpxSize, &NumberOfBytesRW))
|
|
{
|
|
currentHash = EngineHashMemory((char*)lpHashBuffer, (DWORD)memBpxSize, NULL);
|
|
originalHash = EngineHashMemory((char*)((ULONG_PTR)glbEntryTracerData.SectionData[i].AllocatedSection + memBpxAddress - glbEntryTracerData.LoadedImageBase - glbEntryTracerData.SectionData[i].SectionVirtualOffset), (DWORD)memBpxSize, NULL);
|
|
if(ReadProcessMemory(dbgProcessInformation.hProcess, (void*)(glbEntryTracerData.CurrentIntructionPointer), lpHashBuffer, MAXIMUM_INSTRUCTION_SIZE, &NumberOfBytesRW))
|
|
{
|
|
myCmpHandler = (PMEMORY_COMPARE_HANDLER)(lpHashBuffer);
|
|
if(myCmpHandler->Array.bArrayEntry[0] == 0xC3) // RET
|
|
{
|
|
FakeEPDetected = true;
|
|
}
|
|
else if(myCmpHandler->Array.bArrayEntry[0] == 0x33 && myCmpHandler->Array.bArrayEntry[1] == 0xC0 && myCmpHandler->Array.bArrayEntry[2] == 0xC3) // XOR EAX,EAX; RET
|
|
{
|
|
FakeEPDetected = true;
|
|
}
|
|
}
|
|
if(currentHash != originalHash && glbEntryTracerData.SectionData[i].AccessedAlready == true && i != glbEntryTracerData.OriginalEntryPointNum && FakeEPDetected == false)
|
|
{
|
|
__try
|
|
{
|
|
if(glbEntryTracerData.EPCallBack != NULL)
|
|
{
|
|
glbEntryTracerData.CurrentIntructionPointer = (ULONG_PTR)GetContextData(UE_CIP);
|
|
SetContextData(UE_CIP, glbEntryTracerData.MemoryAccessedFrom);
|
|
DeleteAPIBreakPoint("kernel32.dll", "VirtualProtect", UE_APIEND);
|
|
RemoveAllBreakPoints(UE_OPTION_REMOVEALL);
|
|
myEPCallBack();
|
|
SetContextData(UE_CIP, glbEntryTracerData.CurrentIntructionPointer);
|
|
}
|
|
else
|
|
{
|
|
StopDebug();
|
|
}
|
|
}
|
|
__except(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
StopDebug();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SetMemoryBPXEx((ULONG_PTR)(glbEntryTracerData.SectionData[i].SectionVirtualOffset + glbEntryTracerData.LoadedImageBase), glbEntryTracerData.SectionData[i].SectionVirtualSize, UE_MEMORY, false, &GenericOEPTraceHit);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SetMemoryBPXEx((ULONG_PTR)(glbEntryTracerData.SectionData[i].SectionVirtualOffset + glbEntryTracerData.LoadedImageBase), glbEntryTracerData.SectionData[i].SectionVirtualSize, UE_MEMORY, false, &GenericOEPTraceHit);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
StopDebug();
|
|
}
|
|
}
|
|
|
|
void GenericOEPLibraryDetailsHit()
|
|
{
|
|
|
|
int i;
|
|
bool memBreakPointSet = false;
|
|
char szModuleName[2 * MAX_PATH] = {};
|
|
#if !defined(_WIN64)
|
|
int inReg = UE_EAX;
|
|
#else
|
|
int inReg = UE_RAX;
|
|
#endif
|
|
|
|
if(GetModuleBaseNameA(dbgProcessInformation.hProcess, (HMODULE)GetContextData(inReg), szModuleName, sizeof szModuleName) > NULL)
|
|
{
|
|
if(lstrcmpiA(szModuleName, "kernel32.dll") != NULL)
|
|
{
|
|
if(glbEntryTracerData.FileIsDLL)
|
|
{
|
|
glbEntryTracerData.LoadedImageBase = (ULONG_PTR)GetDebuggedDLLBaseAddress();
|
|
}
|
|
else
|
|
{
|
|
glbEntryTracerData.LoadedImageBase = (ULONG_PTR)GetDebuggedFileBaseAddress();
|
|
}
|
|
for(i = 0; i < glbEntryTracerData.SectionNumber; i++)
|
|
{
|
|
if(glbEntryTracerData.SectionData[i].SectionAttributes & IMAGE_SCN_MEM_EXECUTE || glbEntryTracerData.SectionData[i].SectionAttributes & IMAGE_SCN_CNT_CODE)
|
|
{
|
|
SetMemoryBPXEx((ULONG_PTR)(glbEntryTracerData.SectionData[i].SectionVirtualOffset + glbEntryTracerData.LoadedImageBase), glbEntryTracerData.SectionData[i].SectionVirtualSize, UE_MEMORY, false, &GenericOEPTraceHit);
|
|
memBreakPointSet = true;
|
|
}
|
|
}
|
|
if(!memBreakPointSet)
|
|
{
|
|
StopDebug();
|
|
}
|
|
else
|
|
{
|
|
DeleteAPIBreakPoint("kernel32.dll", "GetModuleHandleW", UE_APIEND);
|
|
DeleteAPIBreakPoint("kernel32.dll", "LoadLibraryExW", UE_APIEND);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void GenericOEPTraceInit()
|
|
{
|
|
|
|
int i;
|
|
void* lpHashBuffer;
|
|
ULONG_PTR NumberOfBytesRW;
|
|
typedef void(TITCALL *fInitCallBack)();
|
|
fInitCallBack myInitCallBack = (fInitCallBack)glbEntryTracerData.InitCallBack;
|
|
|
|
if(glbEntryTracerData.FileIsDLL)
|
|
{
|
|
glbEntryTracerData.LoadedImageBase = (ULONG_PTR)GetDebuggedDLLBaseAddress();
|
|
}
|
|
else
|
|
{
|
|
glbEntryTracerData.LoadedImageBase = (ULONG_PTR)GetDebuggedFileBaseAddress();
|
|
}
|
|
for(i = 0; i < glbEntryTracerData.SectionNumber; i++)
|
|
{
|
|
lpHashBuffer = VirtualAlloc(NULL, glbEntryTracerData.SectionData[i].SectionVirtualSize, MEM_COMMIT, PAGE_READWRITE);
|
|
if(lpHashBuffer != NULL)
|
|
{
|
|
if(ReadProcessMemory(dbgProcessInformation.hProcess, (void*)(glbEntryTracerData.SectionData[i].SectionVirtualOffset + glbEntryTracerData.LoadedImageBase), lpHashBuffer, glbEntryTracerData.SectionData[i].SectionVirtualSize, &NumberOfBytesRW))
|
|
{
|
|
glbEntryTracerData.SectionData[i].AllocatedSection = lpHashBuffer;
|
|
}
|
|
}
|
|
}
|
|
SetAPIBreakPoint("kernel32.dll", "VirtualProtect", UE_BREAKPOINT, UE_APIEND, &GenericOEPVirtualProtectHit);
|
|
SetAPIBreakPoint("kernel32.dll", "GetModuleHandleW", UE_BREAKPOINT, UE_APIEND, &GenericOEPLibraryDetailsHit);
|
|
SetAPIBreakPoint("kernel32.dll", "LoadLibraryExW", UE_BREAKPOINT, UE_APIEND, &GenericOEPLibraryDetailsHit);
|
|
if(glbEntryTracerData.InitCallBack != NULL)
|
|
{
|
|
__try
|
|
{
|
|
myInitCallBack();
|
|
}
|
|
__except(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
StopDebug();
|
|
}
|
|
}
|
|
}
|
|
|
|
bool GenericOEPFileInitW(wchar_t* szFileName, LPVOID TraceInitCallBack, LPVOID CallBack)
|
|
{
|
|
|
|
int i;
|
|
#if defined(_WIN64)
|
|
PE64Struct PEStruct = {};
|
|
#else
|
|
PE32Struct PEStruct = {};
|
|
#endif
|
|
HANDLE FileHandle;
|
|
DWORD FileSize;
|
|
HANDLE FileMap;
|
|
ULONG_PTR FileMapVA;
|
|
|
|
if(MapFileExW(szFileName, UE_ACCESS_READ, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
|
|
{
|
|
if(GetPE32DataFromMappedFileEx(FileMapVA, &PEStruct))
|
|
{
|
|
RtlZeroMemory(&glbEntryTracerData, sizeof GenericOEPTracerData);
|
|
glbEntryTracerData.OriginalImageBase = PEStruct.ImageBase;
|
|
glbEntryTracerData.OriginalEntryPoint = PEStruct.OriginalEntryPoint;
|
|
glbEntryTracerData.SizeOfImage = PEStruct.NtSizeOfImage;
|
|
glbEntryTracerData.SectionNumber = PEStruct.SectionNumber;
|
|
glbEntryTracerData.FileIsDLL = IsFileDLL(NULL, FileMapVA);
|
|
glbEntryTracerData.OriginalEntryPointNum = GetPE32SectionNumberFromVA(FileMapVA, glbEntryTracerData.OriginalImageBase + glbEntryTracerData.OriginalEntryPoint);
|
|
for(i = 0; i < glbEntryTracerData.SectionNumber; i++)
|
|
{
|
|
glbEntryTracerData.SectionData[i].SectionVirtualOffset = (DWORD)GetPE32DataFromMappedFile(FileMapVA, i, UE_SECTIONVIRTUALOFFSET);
|
|
glbEntryTracerData.SectionData[i].SectionVirtualSize = (DWORD)GetPE32DataFromMappedFile(FileMapVA, i, UE_SECTIONVIRTUALSIZE);
|
|
if(glbEntryTracerData.SectionData[i].SectionVirtualSize % 0x1000 != 0) //SectionAlignment, the default value is the page size for the system.
|
|
{
|
|
glbEntryTracerData.SectionData[i].SectionVirtualSize = ((glbEntryTracerData.SectionData[i].SectionVirtualSize / 0x1000) + 1) * 0x1000;
|
|
}
|
|
glbEntryTracerData.SectionData[i].SectionAttributes = (DWORD)GetPE32DataFromMappedFile(FileMapVA, i, UE_SECTIONFLAGS);
|
|
}
|
|
glbEntryTracerData.EPCallBack = CallBack;
|
|
glbEntryTracerData.InitCallBack = TraceInitCallBack;
|
|
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
|
|
if(glbEntryTracerData.FileIsDLL)
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
|
|
}
|
|
}
|
|
return false;
|
|
}
|