- implemented MemoryWriteSafe

- renamed FilterBreakPoints
- fixed a bug in EnableBPX (now it re-reads the original bytes)
This commit is contained in:
Mr. eXoDia 2014-03-10 01:23:05 +01:00
parent 92eb890c7f
commit 3963d18771
4 changed files with 124 additions and 24 deletions

View File

@ -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();
}
}
}

View File

@ -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

View File

@ -67,32 +67,41 @@ __declspec(dllexport) bool TITCALL EnableBPX(ULONG_PTR bpxAddress)
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))
{ {
if(BreakPointBuffer.at(i).AdvancedBreakPointType == UE_BREAKPOINT_INT3) //re-read original byte(s)
if(ReadProcessMemory(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, BreakPointBuffer.at(i).OriginalByte, BreakPointBuffer.at(i).BreakPointSize, 0))
{ {
if(WriteProcessMemory(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, &INT3BreakPoint, 1, &NumberOfBytesReadWritten)) if(BreakPointBuffer.at(i).AdvancedBreakPointType == UE_BREAKPOINT_INT3)
{ {
testWrite = true; if(WriteProcessMemory(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, &INT3BreakPoint, 1, &NumberOfBytesReadWritten))
{
testWrite = true;
}
} }
} else if(BreakPointBuffer.at(i).AdvancedBreakPointType == UE_BREAKPOINT_LONG_INT3)
else if(BreakPointBuffer.at(i).AdvancedBreakPointType == UE_BREAKPOINT_LONG_INT3)
{
if(WriteProcessMemory(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, &INT3LongBreakPoint, 2, &NumberOfBytesReadWritten))
{ {
testWrite = true; if(WriteProcessMemory(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, &INT3LongBreakPoint, 2, &NumberOfBytesReadWritten))
{
testWrite = true;
}
} }
} else if(BreakPointBuffer.at(i).AdvancedBreakPointType == UE_BREAKPOINT_UD2)
else if(BreakPointBuffer.at(i).AdvancedBreakPointType == UE_BREAKPOINT_UD2)
{
if(WriteProcessMemory(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, &UD2BreakPoint, 2, &NumberOfBytesReadWritten))
{ {
testWrite = true; if(WriteProcessMemory(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, &UD2BreakPoint, 2, &NumberOfBytesReadWritten))
{
testWrite = true;
}
}
if(testWrite)
{
BreakPointBuffer.at(i).BreakPointActive = UE_BPXACTIVE;
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, BreakPointBuffer.at(i).BreakPointSize, OldProtect, &OldProtect);
return true;
}
else
{
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, BreakPointBuffer.at(i).BreakPointSize, OldProtect, &OldProtect);
return false;
} }
}
if(testWrite)
{
BreakPointBuffer.at(i).BreakPointActive = UE_BPXACTIVE;
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, BreakPointBuffer.at(i).BreakPointSize, OldProtect, &OldProtect);
return true;
} }
else else
{ {

View File

@ -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;
} }