diff --git a/TitanEngine/Global.Breakpoints.cpp b/TitanEngine/Global.Breakpoints.cpp index 787ced3..62b1093 100644 --- a/TitanEngine/Global.Breakpoints.cpp +++ b/TitanEngine/Global.Breakpoints.cpp @@ -111,8 +111,9 @@ void uintdr7(ULONG_PTR dr7, DR7* ret) 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 end=start+nSize; int bpcount=BreakPointBuffer.size(); @@ -120,7 +121,7 @@ void FilterBreakPoints(ULONG_PTR lpBaseAddress, unsigned char* lpBuffer, SIZE_T { BreakPointDetail* curBp=&BreakPointBuffer.at(i); //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; ULONG_PTR cur_addr=curBp->BreakPointAddress; if(cur_addr>=start && cur_addrOriginalByte, n); } } +} + +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; iBreakPointActive != UE_BPXINACTIVE || (curBp->BreakPointType != UE_BREAKPOINT && curBp->BreakPointType != UE_SINGLESHOOT)) + continue; + ULONG_PTR cur_addr=curBp->BreakPointAddress; + if(cur_addr>=start && cur_addrunlock(); + 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; iBreakPointActive != UE_BPXINACTIVE || (curBp->BreakPointType != UE_BREAKPOINT && curBp->BreakPointType != UE_SINGLESHOOT)) + continue; + ULONG_PTR cur_addr=curBp->BreakPointAddress; + if(cur_addr>=start && cur_addrBreakPointActive = UE_BPXINACTIVE; //little hack + lock->unlock(); + EnableBPX(cur_addr); //needs a cleaner solution + lock->relock(); + } + } } \ No newline at end of file diff --git a/TitanEngine/Global.Breakpoints.h b/TitanEngine/Global.Breakpoints.h index 1e59776..3077ef7 100644 --- a/TitanEngine/Global.Breakpoints.h +++ b/TitanEngine/Global.Breakpoints.h @@ -2,11 +2,14 @@ #define _GLOBAL_BREAKPOINTS_H #include +#include "Global.Engine.Threading.h" extern std::vector BreakPointBuffer; void uintdr7(ULONG_PTR dr7, DR7* ret); 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 diff --git a/TitanEngine/TitanEngine.Breakpoints.cpp b/TitanEngine/TitanEngine.Breakpoints.cpp index 5cd1ce8..4413013 100644 --- a/TitanEngine/TitanEngine.Breakpoints.cpp +++ b/TitanEngine/TitanEngine.Breakpoints.cpp @@ -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); 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) - { - if(WriteProcessMemory(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, &INT3LongBreakPoint, 2, &NumberOfBytesReadWritten)) + else if(BreakPointBuffer.at(i).AdvancedBreakPointType == UE_BREAKPOINT_LONG_INT3) { - testWrite = true; + if(WriteProcessMemory(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, &INT3LongBreakPoint, 2, &NumberOfBytesReadWritten)) + { + testWrite = true; + } } - } - else if(BreakPointBuffer.at(i).AdvancedBreakPointType == UE_BREAKPOINT_UD2) - { - if(WriteProcessMemory(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, &UD2BreakPoint, 2, &NumberOfBytesReadWritten)) + else if(BreakPointBuffer.at(i).AdvancedBreakPointType == UE_BREAKPOINT_UD2) { - 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 { diff --git a/TitanEngine/TitanEngine.Debugger.Memory.cpp b/TitanEngine/TitanEngine.Debugger.Memory.cpp index ebed079..505af2f 100644 --- a/TitanEngine/TitanEngine.Debugger.Memory.cpp +++ b/TitanEngine/TitanEngine.Debugger.Memory.cpp @@ -402,7 +402,7 @@ __declspec(dllexport) bool TITCALL MemoryReadSafe(HANDLE hProcess, LPVOID lpBase //filter breakpoints if(retValue) - FilterBreakPoints((ULONG_PTR)lpBaseAddress, (unsigned char*)lpBuffer, nSize); + BreakPointPostReadFilter((ULONG_PTR)lpBaseAddress, (unsigned char*)lpBuffer, nSize); return retValue; } @@ -412,5 +412,48 @@ __declspec(dllexport) bool TITCALL MemoryReadSafe(HANDLE hProcess, LPVOID lpBase //- re-set breakpoints when overwritten __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; } \ No newline at end of file