mirror of https://github.com/x64dbg/TitanEngine
Merge pull request #9 from thejanit0r/patch-1
Alternative memory breakpoint (PAGE_NOACCESS)
This commit is contained in:
commit
d4ad8293f7
|
|
@ -57,6 +57,7 @@
|
||||||
#define UE_ENGINE_CALL_PLUGIN_DEBUG_CALLBACK 8
|
#define UE_ENGINE_CALL_PLUGIN_DEBUG_CALLBACK 8
|
||||||
#define UE_ENGINE_SET_DEBUG_PRIVILEGE 9
|
#define UE_ENGINE_SET_DEBUG_PRIVILEGE 9
|
||||||
#define UE_ENGINE_SAFE_ATTACH 10
|
#define UE_ENGINE_SAFE_ATTACH 10
|
||||||
|
#define UE_ENGINE_MEMBP_ALT 11
|
||||||
|
|
||||||
#define UE_OPTION_REMOVEALL 1
|
#define UE_OPTION_REMOVEALL 1
|
||||||
#define UE_OPTION_DISABLEALL 2
|
#define UE_OPTION_DISABLEALL 2
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ const BYTE UE_ENGINE_RESET_CUSTOM_HANDLER = 7;
|
||||||
const BYTE UE_ENGINE_CALL_PLUGIN_DEBUG_CALLBACK = 8;
|
const BYTE UE_ENGINE_CALL_PLUGIN_DEBUG_CALLBACK = 8;
|
||||||
const BYTE UE_ENGINE_SET_DEBUG_PRIVILEGE = 9;
|
const BYTE UE_ENGINE_SET_DEBUG_PRIVILEGE = 9;
|
||||||
const BYTE UE_ENGINE_SAFE_ATTACH = 10;
|
const BYTE UE_ENGINE_SAFE_ATTACH = 10;
|
||||||
|
const BYTE UE_ENGINE_MEMBP_ALT = 11;
|
||||||
|
|
||||||
const BYTE UE_OPTION_REMOVEALL = 1;
|
const BYTE UE_OPTION_REMOVEALL = 1;
|
||||||
const BYTE UE_OPTION_DISABLEALL = 2;
|
const BYTE UE_OPTION_DISABLEALL = 2;
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,7 @@ enum eEngineVariable : DWORD
|
||||||
UE_ENGINE_CALL_PLUGIN_DEBUG_CALLBACK = UE::UE_ENGINE_CALL_PLUGIN_DEBUG_CALLBACK,
|
UE_ENGINE_CALL_PLUGIN_DEBUG_CALLBACK = UE::UE_ENGINE_CALL_PLUGIN_DEBUG_CALLBACK,
|
||||||
UE_ENGINE_SET_DEBUG_PRIVILEGE = UE::UE_ENGINE_SET_DEBUG_PRIVILEGE,
|
UE_ENGINE_SET_DEBUG_PRIVILEGE = UE::UE_ENGINE_SET_DEBUG_PRIVILEGE,
|
||||||
UE_ENGINE_SAFE_ATTACH = UE::UE_ENGINE_SAFE_ATTACH,
|
UE_ENGINE_SAFE_ATTACH = UE::UE_ENGINE_SAFE_ATTACH,
|
||||||
|
UE_ENGINE_MEMBP_ALT = UE::UE_ENGINE_MEMBP_ALT;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum eBPRemoveOption : DWORD
|
enum eBPRemoveOption : DWORD
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ bool engineExecutePluginCallBack = true;
|
||||||
bool engineAutoHideFromDebugger = false; // hardcoded
|
bool engineAutoHideFromDebugger = false; // hardcoded
|
||||||
bool engineEnableDebugPrivilege = false;
|
bool engineEnableDebugPrivilege = false;
|
||||||
bool engineSafeAttach = false;
|
bool engineSafeAttach = false;
|
||||||
|
bool engineMembpAlt = false;
|
||||||
|
|
||||||
char engineFoundDLLName[512] = {0};
|
char engineFoundDLLName[512] = {0};
|
||||||
char engineFoundAPIName[512] = {0};
|
char engineFoundAPIName[512] = {0};
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ extern bool engineExecutePluginCallBack;
|
||||||
extern bool engineAutoHideFromDebugger;
|
extern bool engineAutoHideFromDebugger;
|
||||||
extern bool engineEnableDebugPrivilege;
|
extern bool engineEnableDebugPrivilege;
|
||||||
extern bool engineSafeAttach;
|
extern bool engineSafeAttach;
|
||||||
|
extern bool engineMembpAlt;
|
||||||
|
|
||||||
//Global.Engine.Functions
|
//Global.Engine.Functions
|
||||||
void EngineInit();
|
void EngineInit();
|
||||||
|
|
|
||||||
|
|
@ -446,6 +446,7 @@ __declspec(dllexport) bool TITCALL SetMemoryBPXEx(ULONG_PTR MemoryStart, SIZE_T
|
||||||
MEMORY_BASIC_INFORMATION MemInfo;
|
MEMORY_BASIC_INFORMATION MemInfo;
|
||||||
ULONG_PTR NumberOfBytesReadWritten = 0;
|
ULONG_PTR NumberOfBytesReadWritten = 0;
|
||||||
int bpcount = (int)BreakPointBuffer.size();
|
int bpcount = (int)BreakPointBuffer.size();
|
||||||
|
DWORD OldProtect = 0;
|
||||||
//search for breakpoint
|
//search for breakpoint
|
||||||
for(int i = 0; i < bpcount; i++)
|
for(int i = 0; i < bpcount; i++)
|
||||||
{
|
{
|
||||||
|
|
@ -461,15 +462,32 @@ __declspec(dllexport) bool TITCALL SetMemoryBPXEx(ULONG_PTR MemoryStart, SIZE_T
|
||||||
}
|
}
|
||||||
//set PAGE_GUARD on all the pages separately
|
//set PAGE_GUARD on all the pages separately
|
||||||
size_t pages = SizeOfMemory / TITANENGINE_PAGESIZE;
|
size_t pages = SizeOfMemory / TITANENGINE_PAGESIZE;
|
||||||
|
|
||||||
for(size_t i = 0; i < pages; i++)
|
for(size_t i = 0; i < pages; i++)
|
||||||
{
|
{
|
||||||
const LPVOID curPage = (LPVOID)(MemoryStart + i * TITANENGINE_PAGESIZE);
|
const LPVOID curPage = (LPVOID)(MemoryStart + i * TITANENGINE_PAGESIZE);
|
||||||
|
|
||||||
VirtualQueryEx(dbgProcessInformation.hProcess, curPage, &MemInfo, sizeof(MEMORY_BASIC_INFORMATION));
|
VirtualQueryEx(dbgProcessInformation.hProcess, curPage, &MemInfo, sizeof(MEMORY_BASIC_INFORMATION));
|
||||||
DWORD OldProtect = MemInfo.Protect;
|
|
||||||
if(!(OldProtect & PAGE_GUARD))
|
if (OldProtect == 0)
|
||||||
|
OldProtect = MemInfo.Protect;
|
||||||
|
|
||||||
|
// Check if the alternative memory breakpoint method should be used
|
||||||
|
if (engineMembpAlt)
|
||||||
{
|
{
|
||||||
DWORD NewProtect = OldProtect ^ PAGE_GUARD;
|
if(!(MemInfo.Protect & PAGE_NOACCESS))
|
||||||
VirtualProtectEx(dbgProcessInformation.hProcess, curPage, TITANENGINE_PAGESIZE, NewProtect, &OldProtect);
|
{
|
||||||
|
VirtualProtectEx(dbgProcessInformation.hProcess, curPage, TITANENGINE_PAGESIZE, PAGE_NOACCESS, &MemInfo.Protect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Default to using PAGE_GUARD memory breakpoint
|
||||||
|
if(!(MemInfo.Protect & PAGE_GUARD))
|
||||||
|
{
|
||||||
|
DWORD NewProtect = MemInfo.Protect ^ PAGE_GUARD;
|
||||||
|
VirtualProtectEx(dbgProcessInformation.hProcess, curPage, TITANENGINE_PAGESIZE, NewProtect, &MemInfo.Protect);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//add new breakpoint
|
//add new breakpoint
|
||||||
|
|
@ -479,6 +497,7 @@ __declspec(dllexport) bool TITCALL SetMemoryBPXEx(ULONG_PTR MemoryStart, SIZE_T
|
||||||
NewBreakPoint.BreakPointAddress = MemoryStart;
|
NewBreakPoint.BreakPointAddress = MemoryStart;
|
||||||
NewBreakPoint.BreakPointType = BreakPointType;
|
NewBreakPoint.BreakPointType = BreakPointType;
|
||||||
NewBreakPoint.BreakPointSize = SizeOfMemory;
|
NewBreakPoint.BreakPointSize = SizeOfMemory;
|
||||||
|
NewBreakPoint.OldProtect = OldProtect;
|
||||||
NewBreakPoint.MemoryBpxRestoreOnHit = (BYTE)RestoreOnHit;
|
NewBreakPoint.MemoryBpxRestoreOnHit = (BYTE)RestoreOnHit;
|
||||||
NewBreakPoint.ExecuteCallBack = (ULONG_PTR)bpxCallBack;
|
NewBreakPoint.ExecuteCallBack = (ULONG_PTR)bpxCallBack;
|
||||||
BreakPointBuffer.push_back(NewBreakPoint);
|
BreakPointBuffer.push_back(NewBreakPoint);
|
||||||
|
|
@ -508,25 +527,45 @@ __declspec(dllexport) bool TITCALL RemoveMemoryBPX(ULONG_PTR MemoryStart, SIZE_T
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(found == -1) //not found
|
if(found == -1) //not found
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(!SizeOfMemory)
|
if(!SizeOfMemory)
|
||||||
SizeOfMemory = BreakPointBuffer.at(found).BreakPointSize;
|
SizeOfMemory = BreakPointBuffer.at(found).BreakPointSize;
|
||||||
//remove PAGE_GUARD from all the pages in the range
|
|
||||||
|
// Revert to the original permission on all the pages in the range
|
||||||
size_t pages = SizeOfMemory / TITANENGINE_PAGESIZE;
|
size_t pages = SizeOfMemory / TITANENGINE_PAGESIZE;
|
||||||
|
|
||||||
for(size_t i = 0; i < pages; i++)
|
for(size_t i = 0; i < pages; i++)
|
||||||
{
|
{
|
||||||
const LPVOID curPage = (LPVOID)(MemoryStart + i * TITANENGINE_PAGESIZE);
|
const LPVOID curPage = (LPVOID)(MemoryStart + i * TITANENGINE_PAGESIZE);
|
||||||
|
|
||||||
VirtualQueryEx(dbgProcessInformation.hProcess, curPage, &MemInfo, sizeof(MEMORY_BASIC_INFORMATION));
|
VirtualQueryEx(dbgProcessInformation.hProcess, curPage, &MemInfo, sizeof(MEMORY_BASIC_INFORMATION));
|
||||||
DWORD OldProtect = MemInfo.Protect;
|
|
||||||
if((OldProtect & PAGE_GUARD))
|
// Check if the alternative memory breakpoint method is being used
|
||||||
|
if (engineMembpAlt)
|
||||||
{
|
{
|
||||||
DWORD NewProtect = OldProtect ^ PAGE_GUARD;
|
if(MemInfo.Protect & PAGE_NOACCESS)
|
||||||
VirtualProtectEx(dbgProcessInformation.hProcess, curPage, TITANENGINE_PAGESIZE, NewProtect, &OldProtect);
|
{
|
||||||
|
VirtualProtectEx(dbgProcessInformation.hProcess, curPage, TITANENGINE_PAGESIZE,
|
||||||
|
BreakPointBuffer.at(found).OldProtect, &MemInfo.Protect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(MemInfo.Protect & PAGE_GUARD)
|
||||||
|
{
|
||||||
|
DWORD NewProtect = MemInfo.Protect ^ PAGE_GUARD;
|
||||||
|
|
||||||
|
VirtualProtectEx(dbgProcessInformation.hProcess, curPage, TITANENGINE_PAGESIZE, NewProtect, &MemInfo.Protect);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//remove breakpoint from list
|
//remove breakpoint from list
|
||||||
BreakPointBuffer.erase(BreakPointBuffer.begin() + found);
|
BreakPointBuffer.erase(BreakPointBuffer.begin() + found);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -667,10 +667,36 @@ __declspec(dllexport) void TITCALL DebugLoop()
|
||||||
if(ResetMemBPX) //restore memory breakpoint
|
if(ResetMemBPX) //restore memory breakpoint
|
||||||
{
|
{
|
||||||
ResetMemBPX = false;
|
ResetMemBPX = false;
|
||||||
VirtualQueryEx(dbgProcessInformation.hProcess, (LPCVOID)ResetMemBPXAddress, &MemInfo, sizeof MEMORY_BASIC_INFORMATION);
|
|
||||||
OldProtect = MemInfo.Protect;
|
// Check if the alternative memory breakpoint method should be used
|
||||||
NewProtect = OldProtect | PAGE_GUARD; //guard page protection
|
if (engineMembpAlt)
|
||||||
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)ResetMemBPXAddress, ResetMemBPXSize, NewProtect, &OldProtect);
|
{
|
||||||
|
// Check if the breakpoint is still enabled/present and has not been removed
|
||||||
|
for(int i = 0; i < BreakPointBuffer.size(); i++)
|
||||||
|
{
|
||||||
|
if (BreakPointBuffer.at(i).BreakPointAddress == ResetMemBPXAddress &&
|
||||||
|
(BreakPointBuffer.at(i).BreakPointType == UE_MEMORY ||
|
||||||
|
BreakPointBuffer.at(i).BreakPointType == UE_MEMORY_READ ||
|
||||||
|
BreakPointBuffer.at(i).BreakPointType == UE_MEMORY_WRITE ||
|
||||||
|
BreakPointBuffer.at(i).BreakPointType == UE_MEMORY_EXECUTE) &&
|
||||||
|
BreakPointBuffer.at(i).BreakPointActive == UE_BPXACTIVE)
|
||||||
|
{
|
||||||
|
// Restore the breakpoint
|
||||||
|
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)ResetMemBPXAddress,
|
||||||
|
ResetMemBPXSize, PAGE_NOACCESS, &OldProtect);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VirtualQueryEx(dbgProcessInformation.hProcess, (LPCVOID)ResetMemBPXAddress, &MemInfo, sizeof(MEMORY_BASIC_INFORMATION));
|
||||||
|
OldProtect = MemInfo.Protect;
|
||||||
|
NewProtect = OldProtect | PAGE_GUARD; //guard page protection
|
||||||
|
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)ResetMemBPXAddress, ResetMemBPXSize, NewProtect, &OldProtect);
|
||||||
|
}
|
||||||
|
|
||||||
if(engineStepActive)
|
if(engineStepActive)
|
||||||
{
|
{
|
||||||
if(engineStepCount == 0)
|
if(engineStepCount == 0)
|
||||||
|
|
@ -1012,10 +1038,182 @@ __declspec(dllexport) void TITCALL DebugLoop()
|
||||||
|
|
||||||
case STATUS_ACCESS_VIOLATION:
|
case STATUS_ACCESS_VIOLATION:
|
||||||
{
|
{
|
||||||
if(DBGCustomHandler->chAccessViolation != NULL)
|
ULONG_PTR bpaddr;
|
||||||
|
bool bFoundBreakPoint = false;
|
||||||
|
bool bCallCustomHandler = false;
|
||||||
|
BreakPointDetail FoundBreakPoint;
|
||||||
|
int bpcount = (int)BreakPointBuffer.size();
|
||||||
|
|
||||||
|
for(int i = 0; i < bpcount; i++)
|
||||||
{
|
{
|
||||||
myCustomHandler = (fCustomHandler)((LPVOID)DBGCustomHandler->chAccessViolation);
|
ULONG_PTR addr = BreakPointBuffer.at(i).BreakPointAddress;
|
||||||
myCustomHandler(&DBGEvent.u.Exception.ExceptionRecord);
|
bpaddr = (ULONG_PTR)DBGEvent.u.Exception.ExceptionRecord.ExceptionInformation[1]; //page accessed
|
||||||
|
if(bpaddr >= addr && bpaddr < (addr + BreakPointBuffer.at(i).BreakPointSize) &&
|
||||||
|
(BreakPointBuffer.at(i).BreakPointType == UE_MEMORY ||
|
||||||
|
BreakPointBuffer.at(i).BreakPointType == UE_MEMORY_READ ||
|
||||||
|
BreakPointBuffer.at(i).BreakPointType == UE_MEMORY_WRITE ||
|
||||||
|
BreakPointBuffer.at(i).BreakPointType == UE_MEMORY_EXECUTE) &&
|
||||||
|
BreakPointBuffer.at(i).BreakPointActive == UE_BPXACTIVE)
|
||||||
|
{
|
||||||
|
FoundBreakPoint = BreakPointBuffer.at(i);
|
||||||
|
bFoundBreakPoint = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Most of the logic has been copied from the STATUS_GUARD_PAGE_VIOLATION handler
|
||||||
|
|
||||||
|
if(bFoundBreakPoint && engineMembpAlt) //found memory breakpoint
|
||||||
|
{
|
||||||
|
hActiveThread = EngineOpenThread(THREAD_GETSETSUSPEND, false, DBGEvent.dwThreadId);
|
||||||
|
myDBGContext.ContextFlags = CONTEXT_CONTROL;
|
||||||
|
GetThreadContext(hActiveThread, &myDBGContext);
|
||||||
|
DBGCode = DBG_CONTINUE; //debugger handled the exception
|
||||||
|
MemoryBpxCallBack = FoundBreakPoint.ExecuteCallBack;
|
||||||
|
|
||||||
|
if(FoundBreakPoint.BreakPointType == UE_MEMORY) //READ|WRITE|EXECUTE
|
||||||
|
{
|
||||||
|
if(FoundBreakPoint.MemoryBpxRestoreOnHit != 1)
|
||||||
|
{
|
||||||
|
RemoveMemoryBPX(FoundBreakPoint.BreakPointAddress, FoundBreakPoint.BreakPointSize);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
myDBGContext.EFlags |= UE_TRAP_FLAG;
|
||||||
|
SetThreadContext(hActiveThread, &myDBGContext);
|
||||||
|
ResetMemBPXAddress = FoundBreakPoint.BreakPointAddress;
|
||||||
|
ResetMemBPXSize = FoundBreakPoint.BreakPointSize;
|
||||||
|
ResetMemBPX = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bCallCustomHandler = true;
|
||||||
|
}
|
||||||
|
else if(FoundBreakPoint.BreakPointType == UE_MEMORY_READ) //READ
|
||||||
|
{
|
||||||
|
if(FoundBreakPoint.MemoryBpxRestoreOnHit != 1) //do not restore the memory breakpoint
|
||||||
|
{
|
||||||
|
if(DBGEvent.u.Exception.ExceptionRecord.ExceptionInformation[0] == 0) //read operation
|
||||||
|
RemoveMemoryBPX(FoundBreakPoint.BreakPointAddress, FoundBreakPoint.BreakPointSize);
|
||||||
|
}
|
||||||
|
else //restore the memory breakpoint
|
||||||
|
{
|
||||||
|
myDBGContext.EFlags |= UE_TRAP_FLAG;
|
||||||
|
SetThreadContext(hActiveThread, &myDBGContext);
|
||||||
|
ResetMemBPXAddress = FoundBreakPoint.BreakPointAddress;
|
||||||
|
ResetMemBPXSize = FoundBreakPoint.BreakPointSize;
|
||||||
|
ResetMemBPX = true;
|
||||||
|
}
|
||||||
|
if(DBGEvent.u.Exception.ExceptionRecord.ExceptionInformation[0] == 0) //read operation
|
||||||
|
{
|
||||||
|
bCallCustomHandler = true;
|
||||||
|
}
|
||||||
|
else //no read operation, restore breakpoint
|
||||||
|
{
|
||||||
|
myDBGContext.EFlags |= UE_TRAP_FLAG;
|
||||||
|
SetThreadContext(hActiveThread, &myDBGContext);
|
||||||
|
ResetMemBPXAddress = FoundBreakPoint.BreakPointAddress;
|
||||||
|
ResetMemBPXSize = FoundBreakPoint.BreakPointSize;
|
||||||
|
ResetMemBPX = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(FoundBreakPoint.BreakPointType == UE_MEMORY_WRITE) //WRITE
|
||||||
|
{
|
||||||
|
if(FoundBreakPoint.MemoryBpxRestoreOnHit != 1) //remove breakpoint
|
||||||
|
{
|
||||||
|
if(DBGEvent.u.Exception.ExceptionRecord.ExceptionInformation[0] == 1) //write operation
|
||||||
|
RemoveMemoryBPX(FoundBreakPoint.BreakPointAddress, FoundBreakPoint.BreakPointSize);
|
||||||
|
}
|
||||||
|
else //restore breakpoint after trap flag
|
||||||
|
{
|
||||||
|
myDBGContext.EFlags |= UE_TRAP_FLAG;
|
||||||
|
SetThreadContext(hActiveThread, &myDBGContext);
|
||||||
|
ResetMemBPXAddress = FoundBreakPoint.BreakPointAddress;
|
||||||
|
ResetMemBPXSize = FoundBreakPoint.BreakPointSize;
|
||||||
|
ResetMemBPX = true;
|
||||||
|
}
|
||||||
|
if(DBGEvent.u.Exception.ExceptionRecord.ExceptionInformation[0] == 1) //write operation
|
||||||
|
{
|
||||||
|
bCallCustomHandler = true;
|
||||||
|
}
|
||||||
|
else //no write operation, restore breakpoint
|
||||||
|
{
|
||||||
|
myDBGContext.EFlags |= UE_TRAP_FLAG;
|
||||||
|
SetThreadContext(hActiveThread, &myDBGContext);
|
||||||
|
ResetMemBPXAddress = FoundBreakPoint.BreakPointAddress;
|
||||||
|
ResetMemBPXSize = FoundBreakPoint.BreakPointSize;
|
||||||
|
ResetMemBPX = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(FoundBreakPoint.BreakPointType == UE_MEMORY_EXECUTE) //EXECUTE
|
||||||
|
{
|
||||||
|
if(FoundBreakPoint.MemoryBpxRestoreOnHit != 1)
|
||||||
|
{
|
||||||
|
if((DBGEvent.u.Exception.ExceptionRecord.ExceptionInformation[0] == 8 || DBGEvent.u.Exception.ExceptionRecord.ExceptionInformation[0] == 0) && //data execution prevention (DEP) violation
|
||||||
|
(ULONG_PTR)DBGEvent.u.Exception.ExceptionRecord.ExceptionAddress == DBGEvent.u.Exception.ExceptionRecord.ExceptionInformation[1]) //exception address == read address
|
||||||
|
RemoveMemoryBPX(FoundBreakPoint.BreakPointAddress, FoundBreakPoint.BreakPointSize);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
myDBGContext.EFlags |= UE_TRAP_FLAG;
|
||||||
|
SetThreadContext(hActiveThread, &myDBGContext);
|
||||||
|
ResetMemBPXAddress = FoundBreakPoint.BreakPointAddress;
|
||||||
|
ResetMemBPXSize = FoundBreakPoint.BreakPointSize;
|
||||||
|
ResetMemBPX = true;
|
||||||
|
}
|
||||||
|
if((DBGEvent.u.Exception.ExceptionRecord.ExceptionInformation[0] == 8 || DBGEvent.u.Exception.ExceptionRecord.ExceptionInformation[0] == 0) && //data execution prevention (DEP) violation
|
||||||
|
(ULONG_PTR)DBGEvent.u.Exception.ExceptionRecord.ExceptionAddress == DBGEvent.u.Exception.ExceptionRecord.ExceptionInformation[1]) //exception address == read address
|
||||||
|
{
|
||||||
|
bCallCustomHandler = true;
|
||||||
|
}
|
||||||
|
else //no execute operation, restore breakpoint
|
||||||
|
{
|
||||||
|
myDBGContext.EFlags |= UE_TRAP_FLAG;
|
||||||
|
SetThreadContext(hActiveThread, &myDBGContext);
|
||||||
|
ResetMemBPXAddress = FoundBreakPoint.BreakPointAddress;
|
||||||
|
ResetMemBPXSize = FoundBreakPoint.BreakPointSize;
|
||||||
|
ResetMemBPX = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the breakpoint has to be restored...
|
||||||
|
if (ResetMemBPX)
|
||||||
|
{
|
||||||
|
// ...temporarily revert the PAGE_NOACCESS permission
|
||||||
|
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)ResetMemBPXAddress,
|
||||||
|
ResetMemBPXSize, FoundBreakPoint.OldProtect, &OldProtect);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call the custom memory breakpoint handler
|
||||||
|
if (bCallCustomHandler)
|
||||||
|
{
|
||||||
|
myCustomHandler = (fCustomHandler)(MemoryBpxCallBack);
|
||||||
|
myCustomHandler((void*)bpaddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
EngineCloseHandle(hActiveThread);
|
||||||
|
}
|
||||||
|
else //no memory breakpoint found
|
||||||
|
{
|
||||||
|
DBGCode = DBG_EXCEPTION_NOT_HANDLED;
|
||||||
|
}
|
||||||
|
if(ResetMemBPX) //memory breakpoint hit
|
||||||
|
{
|
||||||
|
ULONG_PTR ueCurrentPosition = GetContextData(UE_CIP);
|
||||||
|
unsigned char instr[16];
|
||||||
|
MemoryReadSafe(dbgProcessInformation.hProcess, (void*)ueCurrentPosition, instr, sizeof(instr), 0);
|
||||||
|
char* DisassembledString = (char*)StaticDisassembleEx(ueCurrentPosition, (LPVOID)instr);
|
||||||
|
if(strstr(DisassembledString, "PUSHF"))
|
||||||
|
PushfBPX = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Debuggee generated access violation exception
|
||||||
|
if(DBGCode == DBG_EXCEPTION_NOT_HANDLED)
|
||||||
|
{
|
||||||
|
if(DBGCustomHandler->chAccessViolation != NULL)
|
||||||
|
{
|
||||||
|
myCustomHandler = (fCustomHandler)((LPVOID)DBGCustomHandler->chAccessViolation);
|
||||||
|
myCustomHandler(&DBGEvent.u.Exception.ExceptionRecord);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,10 @@ __declspec(dllexport) void TITCALL SetEngineVariable(DWORD VariableId, bool Vari
|
||||||
{
|
{
|
||||||
engineSafeAttach = VariableSet;
|
engineSafeAttach = VariableSet;
|
||||||
}
|
}
|
||||||
|
else if(VariableId == UE_ENGINE_MEMBP_ALT)
|
||||||
|
{
|
||||||
|
engineMembpAlt = VariableSet;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__declspec(dllexport) bool TITCALL EngineCreateMissingDependencies(char* szFileName, char* szOutputFolder, bool LogCreatedFiles)
|
__declspec(dllexport) bool TITCALL EngineCreateMissingDependencies(char* szFileName, char* szOutputFolder, bool LogCreatedFiles)
|
||||||
|
|
|
||||||
|
|
@ -245,6 +245,7 @@ typedef struct
|
||||||
int AdvancedBreakPointType;
|
int AdvancedBreakPointType;
|
||||||
int MemoryBpxRestoreOnHit;
|
int MemoryBpxRestoreOnHit;
|
||||||
ULONG_PTR ExecuteCallBack;
|
ULONG_PTR ExecuteCallBack;
|
||||||
|
DWORD OldProtect;
|
||||||
} BreakPointDetail, *PBreakPointDetail;
|
} BreakPointDetail, *PBreakPointDetail;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|
@ -470,6 +471,7 @@ typedef struct HOOK_ENTRY
|
||||||
#define UE_ENGINE_CALL_PLUGIN_DEBUG_CALLBACK 8
|
#define UE_ENGINE_CALL_PLUGIN_DEBUG_CALLBACK 8
|
||||||
#define UE_ENGINE_SET_DEBUG_PRIVILEGE 9
|
#define UE_ENGINE_SET_DEBUG_PRIVILEGE 9
|
||||||
#define UE_ENGINE_SAFE_ATTACH 10
|
#define UE_ENGINE_SAFE_ATTACH 10
|
||||||
|
#define UE_ENGINE_MEMBP_ALT 11
|
||||||
|
|
||||||
#define UE_OPTION_REMOVEALL 1
|
#define UE_OPTION_REMOVEALL 1
|
||||||
#define UE_OPTION_DISABLEALL 2
|
#define UE_OPTION_DISABLEALL 2
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue