mirror of https://github.com/x64dbg/TitanEngine
- implemented MemoryWriteSafe
- renamed FilterBreakPoints - fixed a bug in EnableBPX (now it re-reads the original bytes)
This commit is contained in:
parent
92eb890c7f
commit
3963d18771
|
|
@ -111,8 +111,9 @@ void uintdr7(ULONG_PTR dr7, DR7* ret)
|
||||||
BITSET(ret->HWBP_SIZE[3],1);
|
BITSET(ret->HWBP_SIZE[3],1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FilterBreakPoints(ULONG_PTR lpBaseAddress, unsigned char* lpBuffer, SIZE_T nSize)
|
void BreakPointPostReadFilter(ULONG_PTR lpBaseAddress, unsigned char* lpBuffer, SIZE_T nSize)
|
||||||
{
|
{
|
||||||
|
MutexLocker lock("BreakPointBuffer");
|
||||||
ULONG_PTR start=lpBaseAddress;
|
ULONG_PTR start=lpBaseAddress;
|
||||||
ULONG_PTR end=start+nSize;
|
ULONG_PTR end=start+nSize;
|
||||||
int bpcount=BreakPointBuffer.size();
|
int bpcount=BreakPointBuffer.size();
|
||||||
|
|
@ -120,7 +121,7 @@ void FilterBreakPoints(ULONG_PTR lpBaseAddress, unsigned char* lpBuffer, SIZE_T
|
||||||
{
|
{
|
||||||
BreakPointDetail* curBp=&BreakPointBuffer.at(i);
|
BreakPointDetail* curBp=&BreakPointBuffer.at(i);
|
||||||
//check if the breakpoint is one we should be concerned about
|
//check if the breakpoint is one we should be concerned about
|
||||||
if(!curBp->BreakPointActive || (curBp->BreakPointType != UE_BREAKPOINT && curBp->BreakPointType != UE_SINGLESHOOT))
|
if(curBp->BreakPointActive != UE_BPXINACTIVE || (curBp->BreakPointType != UE_BREAKPOINT && curBp->BreakPointType != UE_SINGLESHOOT))
|
||||||
continue;
|
continue;
|
||||||
ULONG_PTR cur_addr=curBp->BreakPointAddress;
|
ULONG_PTR cur_addr=curBp->BreakPointAddress;
|
||||||
if(cur_addr>=start && cur_addr<end) //breakpoint is in range
|
if(cur_addr>=start && cur_addr<end) //breakpoint is in range
|
||||||
|
|
@ -133,3 +134,47 @@ void FilterBreakPoints(ULONG_PTR lpBaseAddress, unsigned char* lpBuffer, SIZE_T
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BreakPointPreWriteFilter(ULONG_PTR lpBaseAddress, SIZE_T nSize, MutexLocker* lock)
|
||||||
|
{
|
||||||
|
ULONG_PTR start=lpBaseAddress;
|
||||||
|
ULONG_PTR end=start+nSize;
|
||||||
|
int bpcount=BreakPointBuffer.size();
|
||||||
|
for(int i=0; i<bpcount; i++)
|
||||||
|
{
|
||||||
|
BreakPointDetail* curBp=&BreakPointBuffer.at(i);
|
||||||
|
//check if the breakpoint is one we should be concerned about
|
||||||
|
if(curBp->BreakPointActive != UE_BPXINACTIVE || (curBp->BreakPointType != UE_BREAKPOINT && curBp->BreakPointType != UE_SINGLESHOOT))
|
||||||
|
continue;
|
||||||
|
ULONG_PTR cur_addr=curBp->BreakPointAddress;
|
||||||
|
if(cur_addr>=start && cur_addr<end) //breakpoint is in range
|
||||||
|
{
|
||||||
|
lock->unlock();
|
||||||
|
DisableBPX(cur_addr); //needs a cleaner solution
|
||||||
|
lock->relock();
|
||||||
|
curBp->BreakPointActive = UE_BPXACTIVE; //little hack
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BreakPointPostWriteFilter(ULONG_PTR lpBaseAddress, SIZE_T nSize, MutexLocker* lock)
|
||||||
|
{
|
||||||
|
ULONG_PTR start=lpBaseAddress;
|
||||||
|
ULONG_PTR end=start+nSize;
|
||||||
|
int bpcount=BreakPointBuffer.size();
|
||||||
|
for(int i=0; i<bpcount; i++)
|
||||||
|
{
|
||||||
|
BreakPointDetail* curBp=&BreakPointBuffer.at(i);
|
||||||
|
//check if the breakpoint is one we should be concerned about
|
||||||
|
if(curBp->BreakPointActive != UE_BPXINACTIVE || (curBp->BreakPointType != UE_BREAKPOINT && curBp->BreakPointType != UE_SINGLESHOOT))
|
||||||
|
continue;
|
||||||
|
ULONG_PTR cur_addr=curBp->BreakPointAddress;
|
||||||
|
if(cur_addr>=start && cur_addr<end) //breakpoint is in range
|
||||||
|
{
|
||||||
|
curBp->BreakPointActive = UE_BPXINACTIVE; //little hack
|
||||||
|
lock->unlock();
|
||||||
|
EnableBPX(cur_addr); //needs a cleaner solution
|
||||||
|
lock->relock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,11 +2,14 @@
|
||||||
#define _GLOBAL_BREAKPOINTS_H
|
#define _GLOBAL_BREAKPOINTS_H
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include "Global.Engine.Threading.h"
|
||||||
|
|
||||||
extern std::vector<BreakPointDetail> BreakPointBuffer;
|
extern std::vector<BreakPointDetail> BreakPointBuffer;
|
||||||
|
|
||||||
void uintdr7(ULONG_PTR dr7, DR7* ret);
|
void uintdr7(ULONG_PTR dr7, DR7* ret);
|
||||||
ULONG_PTR dr7uint(DR7* dr7);
|
ULONG_PTR dr7uint(DR7* dr7);
|
||||||
void FilterBreakPoints(ULONG_PTR lpBaseAddress, unsigned char* lpBuffer, SIZE_T nSize);
|
void BreakPointPostReadFilter(ULONG_PTR lpBaseAddress, unsigned char* lpBuffer, SIZE_T nSize);
|
||||||
|
void BreakPointPreWriteFilter(ULONG_PTR lpBaseAddress, SIZE_T nSize, MutexLocker* lock);
|
||||||
|
void BreakPointPostWriteFilter(ULONG_PTR lpBaseAddress, SIZE_T nSize, MutexLocker* lock);
|
||||||
|
|
||||||
#endif //_GLOBAL_BREAKPOINTS_H
|
#endif //_GLOBAL_BREAKPOINTS_H
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,9 @@ __declspec(dllexport) bool TITCALL EnableBPX(ULONG_PTR bpxAddress)
|
||||||
OldProtect = MemInfo.Protect;
|
OldProtect = MemInfo.Protect;
|
||||||
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, BreakPointBuffer.at(i).BreakPointSize, PAGE_EXECUTE_READWRITE, &OldProtect);
|
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, BreakPointBuffer.at(i).BreakPointSize, PAGE_EXECUTE_READWRITE, &OldProtect);
|
||||||
if(BreakPointBuffer.at(i).BreakPointActive == UE_BPXINACTIVE && (BreakPointBuffer.at(i).BreakPointType == UE_BREAKPOINT || BreakPointBuffer.at(i).BreakPointType == UE_SINGLESHOOT))
|
if(BreakPointBuffer.at(i).BreakPointActive == UE_BPXINACTIVE && (BreakPointBuffer.at(i).BreakPointType == UE_BREAKPOINT || BreakPointBuffer.at(i).BreakPointType == UE_SINGLESHOOT))
|
||||||
|
{
|
||||||
|
//re-read original byte(s)
|
||||||
|
if(ReadProcessMemory(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, BreakPointBuffer.at(i).OriginalByte, BreakPointBuffer.at(i).BreakPointSize, 0))
|
||||||
{
|
{
|
||||||
if(BreakPointBuffer.at(i).AdvancedBreakPointType == UE_BREAKPOINT_INT3)
|
if(BreakPointBuffer.at(i).AdvancedBreakPointType == UE_BREAKPOINT_INT3)
|
||||||
{
|
{
|
||||||
|
|
@ -106,6 +109,12 @@ __declspec(dllexport) bool TITCALL EnableBPX(ULONG_PTR bpxAddress)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, BreakPointBuffer.at(i).BreakPointSize, OldProtect, &OldProtect);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -402,7 +402,7 @@ __declspec(dllexport) bool TITCALL MemoryReadSafe(HANDLE hProcess, LPVOID lpBase
|
||||||
|
|
||||||
//filter breakpoints
|
//filter breakpoints
|
||||||
if(retValue)
|
if(retValue)
|
||||||
FilterBreakPoints((ULONG_PTR)lpBaseAddress, (unsigned char*)lpBuffer, nSize);
|
BreakPointPostReadFilter((ULONG_PTR)lpBaseAddress, (unsigned char*)lpBuffer, nSize);
|
||||||
|
|
||||||
return retValue;
|
return retValue;
|
||||||
}
|
}
|
||||||
|
|
@ -412,5 +412,48 @@ __declspec(dllexport) bool TITCALL MemoryReadSafe(HANDLE hProcess, LPVOID lpBase
|
||||||
//- re-set breakpoints when overwritten
|
//- re-set breakpoints when overwritten
|
||||||
__declspec(dllexport) bool TITCALL MemoryWriteSafe(HANDLE hProcess, LPVOID lpBaseAddress, LPCVOID lpBuffer, SIZE_T nSize, SIZE_T * lpNumberOfBytesWritten)
|
__declspec(dllexport) bool TITCALL MemoryWriteSafe(HANDLE hProcess, LPVOID lpBaseAddress, LPCVOID lpBuffer, SIZE_T nSize, SIZE_T * lpNumberOfBytesWritten)
|
||||||
{
|
{
|
||||||
return !!WriteProcessMemory(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesWritten);
|
SIZE_T ueNumberOfBytesWritten = 0;
|
||||||
|
SIZE_T * pNumBytes = 0;
|
||||||
|
DWORD dwProtect = 0;
|
||||||
|
bool retValue = false;
|
||||||
|
|
||||||
|
//read memory
|
||||||
|
if ( (hProcess == 0) || (lpBaseAddress == 0) || (lpBuffer == 0) || (nSize == 0))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
MutexLocker lock("BreakPointBuffer"); //thread-safe
|
||||||
|
//disable breakpoints that interfere with the memory to write
|
||||||
|
BreakPointPreWriteFilter((ULONG_PTR)lpBaseAddress, nSize, &lock);
|
||||||
|
|
||||||
|
if (!lpNumberOfBytesWritten)
|
||||||
|
{
|
||||||
|
pNumBytes = &ueNumberOfBytesWritten;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pNumBytes = lpNumberOfBytesWritten;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!WriteProcessMemory(hProcess, lpBaseAddress, lpBuffer, nSize, pNumBytes))
|
||||||
|
{
|
||||||
|
if (VirtualProtectEx(hProcess, lpBaseAddress, nSize, PAGE_EXECUTE_READWRITE, &dwProtect))
|
||||||
|
{
|
||||||
|
if (WriteProcessMemory(hProcess, lpBaseAddress, lpBuffer, nSize, pNumBytes))
|
||||||
|
{
|
||||||
|
retValue = true;
|
||||||
|
}
|
||||||
|
VirtualProtectEx(hProcess, lpBaseAddress, nSize, dwProtect, &dwProtect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
retValue = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//re-enable breakpoints that interfere with the memory to write
|
||||||
|
BreakPointPostWriteFilter((ULONG_PTR)lpBaseAddress, nSize, &lock);
|
||||||
|
|
||||||
|
return retValue;
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue