various interface changes

This commit is contained in:
mrexodia 2016-01-11 00:01:50 +01:00
parent f1ac2efec5
commit 8a6ad0e697
9 changed files with 121 additions and 36 deletions

View File

@ -28,12 +28,12 @@ namespace GleeBug
mRegisters->Gip = info.address;
//restore the original breakpoint byte and do an internal step
mProcess->MemWrite(info.address, info.internal.software.oldbytes, info.internal.software.size);
mProcess->MemWriteUnsafe(info.address, info.internal.software.oldbytes, info.internal.software.size);
mThread->StepInternal(std::bind([this, info]()
{
//only restore the bytes if the breakpoint still exists
if (mProcess->breakpoints.find({ BreakpointType::Software, info.address }) != mProcess->breakpoints.end())
mProcess->MemWrite(info.address, info.internal.software.newbytes, info.internal.software.size);
mProcess->MemWriteUnsafe(info.address, info.internal.software.newbytes, info.internal.software.size);
}));
//call the generic callback

View File

@ -29,10 +29,10 @@ namespace GleeBug
}
//read/write the breakpoint
if (!MemRead(address, info.internal.software.oldbytes, info.internal.software.size))
if (!MemReadUnsafe(address, info.internal.software.oldbytes, info.internal.software.size))
return false;
if (!MemWrite(address, info.internal.software.newbytes, info.internal.software.size))
if (!MemWriteUnsafe(address, info.internal.software.newbytes, info.internal.software.size))
return false;
FlushInstructionCache(hProcess, nullptr, 0);
@ -67,7 +67,7 @@ namespace GleeBug
//restore the breakpoint bytes if the breakpoint is enabled
if (info.enabled)
{
if (!MemWrite(address, info.internal.software.oldbytes, info.internal.software.size))
if (!MemWriteUnsafe(address, info.internal.software.oldbytes, info.internal.software.size))
return false;
FlushInstructionCache(hProcess, nullptr, 0);
}

View File

@ -2,7 +2,7 @@
namespace GleeBug
{
bool Process::MemRead(ptr address, void* buffer, ptr size, ptr* bytesRead) const
bool Process::MemReadUnsafe(ptr address, void* buffer, ptr size, ptr* bytesRead) const
{
ptr read;
if (!bytesRead)
@ -12,7 +12,7 @@ namespace GleeBug
bool Process::MemReadSafe(ptr address, void* buffer, ptr size, ptr* bytesRead) const
{
if (!MemRead(address, buffer, size, bytesRead))
if (!MemReadUnsafe(address, buffer, size, bytesRead))
return false;
//choose the filter method that has the lowest cost
@ -54,7 +54,7 @@ namespace GleeBug
return true;
}
bool Process::MemWrite(ptr address, const void* buffer, ptr size, ptr* bytesWritten)
bool Process::MemWriteUnsafe(ptr address, const void* buffer, ptr size, ptr* bytesWritten)
{
ptr written;
if (!bytesWritten)
@ -70,6 +70,29 @@ namespace GleeBug
bool Process::MemIsValidPtr(ptr address) const
{
uint8 byte;
return MemRead(address, &byte, sizeof(byte));
return MemReadUnsafe(address, &byte, sizeof(byte));
}
ptr Process::MemFindPattern(ptr data, size_t datasize, const std::vector<Pattern::Byte> & pattern, bool safe) const
{
std::vector<uint8> buffer(datasize);
if (!MemRead(data, buffer.data(), datasize, nullptr, safe))
return 0;
auto found = Pattern::Find(buffer.data(), datasize, pattern);
return found == -1 ? 0 : found + data;
}
ptr Process::MemFindPattern(ptr data, size_t datasize, const char* pattern, bool safe) const
{
return MemFindPattern(data, datasize, Pattern::Transform(pattern), safe);
}
ptr Process::MemFindPattern(ptr data, size_t datasize, const uint8* pattern, size_t patternsize, bool safe) const
{
std::vector<uint8> buffer(datasize);
if (!MemRead(data, buffer.data(), datasize, nullptr, safe))
return 0;
auto found = Pattern::Find(buffer.data(), datasize, pattern, patternsize);
return found == -1 ? 0 : found + data;
}
};

View File

@ -5,6 +5,7 @@
#include "Debugger.Thread.h"
#include "Debugger.Dll.h"
#include "Debugger.Breakpoint.h"
#include "Static.Pattern.h"
namespace GleeBug
{
@ -42,9 +43,25 @@ namespace GleeBug
\param [out] buffer Destination buffer. Cannot be null. May be filled partially on failure.
\param size The size to read.
\param bytesRead (Optional) Number of bytes read (should be equal to size on success).
\param safe Whether to call MemReadSafe or MemReadUnsafe.
\return true if it succeeds, false if it fails.
*/
bool MemRead(ptr address, void* buffer, ptr size, ptr* bytesRead = nullptr) const;
bool MemRead(ptr address, void* buffer, ptr size, ptr* bytesRead = nullptr, bool safe = true) const
{
if (safe)
return MemReadSafe(address, buffer, size, bytesRead);
return MemRead(address, buffer, size, bytesRead);
}
/**
\brief Read memory from the process. This function should be used for internal reasons only!
\param address The virtual address to read from.
\param [out] buffer Destination buffer. Cannot be null. May be filled partially on failure.
\param size The size to read.
\param bytesRead (Optional) Number of bytes read (should be equal to size on success).
\return true if it succeeds, false if it fails.
*/
bool MemReadUnsafe(ptr address, void* buffer, ptr size, ptr* bytesRead = nullptr) const;
/**
\brief Safely read memory from the process, filtering out breakpoint bytes.
@ -62,9 +79,25 @@ namespace GleeBug
\param [in] buffer Source buffer. Cannot be null.
\param size The size to write.
\param bytesWritten (Optional) Number of bytes written (should be equal to size on success).
\param safe Wheter to call MemWriteSafe or MemWriteUnsafe.
\return true if it succeeds, false if it fails.
*/
bool MemWrite(ptr address, const void* buffer, ptr size, ptr* bytesWritten = nullptr);
bool MemWrite(ptr address, const void* buffer, ptr size, ptr* bytesWritten = nullptr, bool safe = true)
{
if (safe)
return MemWriteSafe(address, buffer, size, bytesWritten);
return MemWriteUnsafe(address, buffer, size, bytesWritten);
}
/**
\brief Write memory to the process. This function should be used for internal reasons only!
\param address The virtual address to write to.
\param [in] buffer Source buffer. Cannot be null.
\param size The size to write.
\param bytesWritten (Optional) Number of bytes written (should be equal to size on success).
\return true if it succeeds, false if it fails.
*/
bool MemWriteUnsafe(ptr address, const void* buffer, ptr size, ptr* bytesWritten = nullptr);
/**
\brief Safely write memory to the process, preserving breakpoint bytes.
@ -83,6 +116,37 @@ namespace GleeBug
*/
bool MemIsValidPtr(ptr address) const;
/**
\brief Finds the first occurrence of a pattern in process memory.
\param data The address to start searching from.
\param datasize The size to search in.
\param pattern The pattern to find.
\param safe Use the safe memory functions (eg do not consider software breakpoint data).
\return Memory address when found, 0 when not found.
*/
ptr MemFindPattern(ptr data, size_t datasize, const std::vector<Pattern::Byte> & pattern, bool safe = true) const;
/**
\brief Finds the first occurrence of a pattern in process memory.
\param data The address to start searching from.
\param datasize The size to search in.
\param pattern The pattern to find.
\param safe Use the safe memory functions (eg do not consider software breakpoint data).
\return Memory address when found, 0 when not found.
*/
ptr MemFindPattern(ptr data, size_t datasize, const char* pattern, bool safe = true) const;
/**
\brief Finds the first occurrence of a pattern in process memory.
\param data The address to start searching from.
\param datasize The size to search in.
\param pattern The pattern to find.
\param patternsize The size of the pattern to find.
\param safe Use the safe memory functions (eg do not consider software breakpoint data).
\return Memory address when found, 0 when not found.
*/
ptr MemFindPattern(ptr data, size_t datasize, const uint8* pattern, size_t patternsize, bool safe = true) const;
/**
\brief Sets a software breakpoint.
\param address The address to set the breakpoint on.

View File

@ -47,7 +47,7 @@ namespace GleeBug
bool Detach() const;
/**
\brief Run the debug loop (does not return until the debuggee is detached or terminated).
\brief Run the debug loop (does not return until the debuggee is detached or terminated). This function should be run from the same thread as you ran Init.
*/
void Start();

View File

@ -1,12 +1,10 @@
#include "Static.Pattern.h"
using namespace std;
namespace GleeBug
{
string Pattern::FormatPattern(const string & patterntext)
std::string Pattern::FormatPattern(const std::string & patterntext)
{
string result;
std::string result;
result.reserve(patterntext.length());
for (auto ch : patterntext)
{
@ -16,13 +14,13 @@ namespace GleeBug
return result;
}
bool Pattern::Transform(const std::string & patterntext, std::vector<Byte> & pattern)
std::vector<Pattern::Byte> Pattern::Transform(const std::string & patterntext)
{
pattern.clear();
std::vector<Byte> pattern;
auto formattext = FormatPattern(patterntext);
auto len = formattext.length();
if (!len)
return false;
return pattern;
if (len % 2) //not a multiple of 2
{
@ -30,6 +28,8 @@ namespace GleeBug
len++;
}
pattern.reserve(len / 2);
auto hexChToInt = [](char ch)
{
if (ch >= '0' && ch <= '9')
@ -62,7 +62,7 @@ namespace GleeBug
pattern.push_back(newByte);
}
}
return true;
return pattern;
}
size_t Pattern::Find(const uint8* data, size_t datasize, const std::vector<Byte> & pattern)
@ -87,6 +87,8 @@ namespace GleeBug
};
auto searchpatternsize = pattern.size();
if (!searchpatternsize)
return -1;
for (size_t i = 0, pos = 0; i < datasize; i++) //search for the pattern
{
if (MatchByte(data[i], pattern.at(pos))) //check if our pattern matches the current byte
@ -106,6 +108,8 @@ namespace GleeBug
size_t Pattern::Find(const uint8* data, size_t datasize, const uint8* pattern, size_t patternsize)
{
if (!patternsize)
return -1;
if (patternsize > datasize)
patternsize = datasize;
for (size_t i = 0, pos = 0; i < datasize; i++)
@ -127,18 +131,13 @@ namespace GleeBug
size_t Pattern::Find(const uint8* data, size_t datasize, const char* pattern)
{
string patterntext(pattern);
vector<Byte> searchpattern;
if (!Transform(patterntext, searchpattern))
return -1;
return Find(data, datasize, searchpattern);
return Find(data, datasize, Transform(pattern));
}
void Pattern::Write(uint8* data, size_t datasize, const char* pattern)
{
vector<Byte> writepattern;
string patterntext(pattern);
if (!Transform(patterntext, writepattern))
auto writepattern = Transform(pattern);
if (!writepattern.size())
return;
auto writepatternsize = writepattern.size();
@ -160,7 +159,7 @@ namespace GleeBug
WriteByte(&data[i], writepattern.at(i));
}
bool Pattern::Snr(uint8* data, size_t datasize, const char* searchpattern, const char* replacepattern)
bool Pattern::SearchAndReplace(uint8* data, size_t datasize, const char* searchpattern, const char* replacepattern)
{
auto found = Find(data, datasize, searchpattern);
if (found == -1)

View File

@ -26,11 +26,10 @@ namespace GleeBug
/**
\brief Transforms a string pattern to a nibble structure.
\param patterntext The pattern string to find.
\param [out] pattern Transformed pattern.
\return true if it succeeds, false otherwise.
\param patterntext The pattern string to transform.
\return Non-empty vector on success.
*/
static bool Transform(const std::string & patterntext, std::vector<Byte> & pattern);
static std::vector<Byte> Transform(const std::string & patterntext);
/**
\brief Finds the first occurrence of a pattern in a buffer.
@ -76,7 +75,7 @@ namespace GleeBug
\param replacepattern The pattern to replace the found occurrence with. The pattern supports wildcards (1? ?? ?6 78).
\return true if it succeeds, false if it fails.
*/
static bool Snr(uint8* data, size_t datasize, const char* searchpattern, const char* replacepattern);
static bool SearchAndReplace(uint8* data, size_t datasize, const char* searchpattern, const char* replacepattern);
};
};

View File

@ -68,7 +68,7 @@ protected:
uint8 test[5];
ptr start = entry - 2;
printf("unsafe: ");
mProcess->MemRead(start, test, sizeof(test));
mProcess->MemReadUnsafe(start, test, sizeof(test));
for (int i = 0; i < sizeof(test); i++)
printf("%02X ", test[i]);
puts("");

View File

@ -62,7 +62,7 @@ public:
if (!process)
return false;
//TODO process->MemWriteSafe
return process->MemWrite(ptr(lpBaseAddress), lpBuffer, nSize, (ptr*)lpNumberOfBytesWritten);
return process->MemWriteUnsafe(ptr(lpBaseAddress), lpBuffer, nSize, (ptr*)lpNumberOfBytesWritten);
}
bool Fill(LPVOID MemoryStart, DWORD MemorySize, PBYTE FillByte)