diff --git a/GleeBug/Debugger.Process.Memory.cpp b/GleeBug/Debugger.Process.Memory.cpp index 2ce0b8f..58ab6e5 100644 --- a/GleeBug/Debugger.Process.Memory.cpp +++ b/GleeBug/Debugger.Process.Memory.cpp @@ -64,7 +64,8 @@ namespace GleeBug bool Process::MemWriteSafe(ptr address, const void* buffer, ptr size, ptr* bytesWritten) { - return false; + //TODO: correctly implement this + return MemWrite(address, buffer, size, bytesWritten); } bool Process::MemIsValidPtr(ptr address) const @@ -73,7 +74,7 @@ namespace GleeBug return MemReadUnsafe(address, &byte, sizeof(byte)); } - ptr Process::MemFindPattern(ptr data, size_t datasize, const std::vector & pattern, bool safe) const + ptr Process::MemFindPattern(ptr data, size_t datasize, const Pattern::WildcardPattern & pattern, bool safe) const { std::vector buffer(datasize); if (!MemRead(data, buffer.data(), datasize, nullptr, safe)) @@ -82,11 +83,6 @@ namespace GleeBug 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 buffer(datasize); @@ -95,4 +91,22 @@ namespace GleeBug auto found = Pattern::Find(buffer.data(), datasize, pattern, patternsize); return found == -1 ? 0 : found + data; } + + bool Process::MemWritePattern(ptr data, size_t datasize, const Pattern::WildcardPattern & pattern, bool safe) + { + std::vector buffer(datasize); + if (!MemRead(data, buffer.data(), datasize, nullptr, safe)) + return false; + Pattern::Write(buffer.data(), datasize, pattern); + return MemWrite(data, buffer.data(), datasize, nullptr, safe); + } + + bool Process::MemSearchAndReplacePattern(ptr data, size_t datasize, const Pattern::WildcardPattern & searchpattern, const Pattern::WildcardPattern & replacepattern, bool safe) + { + std::vector buffer(datasize); + if (!MemRead(data, buffer.data(), datasize, nullptr, safe)) + return false; + Pattern::SearchAndReplace(buffer.data(), datasize, searchpattern, replacepattern); + return MemWrite(data, buffer.data(), datasize, nullptr, safe); + } }; \ No newline at end of file diff --git a/GleeBug/Debugger.Process.h b/GleeBug/Debugger.Process.h index f7b679b..8c15ac5 100644 --- a/GleeBug/Debugger.Process.h +++ b/GleeBug/Debugger.Process.h @@ -124,7 +124,7 @@ namespace GleeBug \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, bool safe = true) const; + ptr MemFindPattern(ptr data, size_t datasize, const Pattern::WildcardPattern & pattern, bool safe = true) const; /** \brief Finds the first occurrence of a pattern in process memory. @@ -134,7 +134,10 @@ namespace GleeBug \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; + ptr MemFindPattern(ptr data, size_t datasize, const std::string & pattern, bool safe = true) const + { + return MemFindPattern(data, datasize, Pattern::Transform(pattern), safe); + } /** \brief Finds the first occurrence of a pattern in process memory. @@ -147,6 +150,54 @@ namespace GleeBug */ ptr MemFindPattern(ptr data, size_t datasize, const uint8* pattern, size_t patternsize, bool safe = true) const; + /** + \brief Writes a pattern in process memory. This function writes as many bytes as possible from the pattern. + \param [in,out] data The address to write the pattern in. + \param datasize The size to write in. + \param pattern Specifies the pattern. + \param safe Use the safe memory functions (eg do not consider software breakpoint data). + \return true if it succeeds, false if it fails. + */ + bool MemWritePattern(ptr data, size_t datasize, const Pattern::WildcardPattern & pattern, bool safe = true); + + /** + \brief Writes a pattern in process memory. This function writes as many bytes as possible from the pattern. + \param [in,out] data The address to write the pattern in. + \param datasize The size to write in. + \param pattern Specifies the pattern. The pattern supports wildcards (1? ?? ?6 78). + \param safe Use the safe memory functions (eg do not consider software breakpoint data). + \return true if it succeeds, false if it fails. + */ + bool MemWritePattern(ptr data, size_t datasize, const std::string & pattern, bool safe = true) + { + return MemWritePattern(data, datasize, Pattern::Transform(pattern), safe); + } + + /** + \brief Search and replace a pattern in process memory. + \param [in,out] data The address to search and replace in. + \param datasize The size to search and replace in. + \param searchpattern The pattern to find. + \param replacepattern The pattern to replace the found occurrence with. + \param safe Use the safe memory functions (eg do not consider software breakpoint data). + \return true if it succeeds, false if it fails. + */ + bool MemSearchAndReplacePattern(ptr data, size_t datasize, const Pattern::WildcardPattern & searchpattern, const Pattern::WildcardPattern & replacepattern, bool safe = true); + + /** + \brief Search and replace a pattern in process memory. + \param [in,out] data The address to search and replace in. + \param datasize The size to search and replace in. + \param searchpattern The pattern to find. The pattern supports wildcards (1? ?? ?6 78). + \param replacepattern The pattern to replace the found occurrence with. The pattern supports wildcards (1? ?? ?6 78). + \param safe Use the safe memory functions (eg do not consider software breakpoint data). + \return true if it succeeds, false if it fails. + */ + bool MemSearchAndReplacePattern(ptr data, size_t datasize, const std::string & searchpattern, const std::string & replacepattern, bool safe = true) + { + return MemSearchAndReplacePattern(data, datasize, Pattern::Transform(searchpattern), Pattern::Transform(replacepattern), safe); + } + /** \brief Sets a software breakpoint. \param address The address to set the breakpoint on. diff --git a/GleeBug/Static.Pattern.cpp b/GleeBug/Static.Pattern.cpp index acffb03..2cf61eb 100644 --- a/GleeBug/Static.Pattern.cpp +++ b/GleeBug/Static.Pattern.cpp @@ -65,7 +65,7 @@ namespace GleeBug return pattern; } - size_t Pattern::Find(const uint8* data, size_t datasize, const std::vector & pattern) + size_t Pattern::Find(const uint8* data, size_t datasize, const WildcardPattern & pattern) { auto MatchByte = [](uint8 byte, const Byte & pbyte) { @@ -129,14 +129,8 @@ namespace GleeBug return -1; } - size_t Pattern::Find(const uint8* data, size_t datasize, const char* pattern) + void Pattern::Write(uint8* data, size_t datasize, const WildcardPattern & writepattern) { - return Find(data, datasize, Transform(pattern)); - } - - void Pattern::Write(uint8* data, size_t datasize, const char* pattern) - { - auto writepattern = Transform(pattern); if (!writepattern.size()) return; @@ -159,7 +153,7 @@ namespace GleeBug WriteByte(&data[i], writepattern.at(i)); } - bool Pattern::SearchAndReplace(uint8* data, size_t datasize, const char* searchpattern, const char* replacepattern) + bool Pattern::SearchAndReplace(uint8* data, size_t datasize, const WildcardPattern & searchpattern, const WildcardPattern & replacepattern) { auto found = Find(data, datasize, searchpattern); if (found == -1) diff --git a/GleeBug/Static.Pattern.h b/GleeBug/Static.Pattern.h index 6780689..34757eb 100644 --- a/GleeBug/Static.Pattern.h +++ b/GleeBug/Static.Pattern.h @@ -17,6 +17,8 @@ namespace GleeBug } nibble[2]; }; + typedef std::vector WildcardPattern; + /** \brief Formats pattern string to only contain [0-9A-Fa-f\?]. \param pattern Pattern to format. @@ -38,7 +40,7 @@ namespace GleeBug \param pattern The pattern to find. \return Offset of the first occurrence found. -1 when not found. */ - static size_t Find(const uint8* data, size_t datasize, const std::vector & pattern); + static size_t Find(const uint8* data, size_t datasize, const WildcardPattern & pattern); /** \brief Finds the first occurrence of a pattern in a buffer. @@ -47,7 +49,10 @@ namespace GleeBug \param pattern The pattern to find. The pattern supports wildcards (1? ?? ?6 78). \return Offset of the first occurrence found. -1 when not found. */ - static size_t Find(const uint8* data, size_t datasize, const char* pattern); + static size_t Find(const uint8* data, size_t datasize, const std::string & pattern) + { + return Find(data, datasize, Transform(pattern)); + } /** \brief Finds the first occurrence of a pattern in a buffer. @@ -59,13 +64,34 @@ namespace GleeBug */ static size_t Find(const uint8* data, size_t datasize, const uint8* pattern, size_t patternsize); + /** + \brief Writes a pattern in a buffer. This function writes as many bytes as possible from the pattern. + \param [in,out] data The buffer to write the pattern in. + \param datasize The size of the buffer. + \param pattern Specifies the pattern. + */ + static void Write(uint8* data, size_t datasize, const WildcardPattern & pattern); + /** \brief Writes a pattern in a buffer. This function writes as many bytes as possible from the pattern. \param [in,out] data The buffer to write the pattern in. \param datasize The size of the buffer. \param pattern Specifies the pattern. The pattern supports wildcards (1? ?? ?6 78). */ - static void Write(uint8* data, size_t datasize, const char* pattern); + static void Write(uint8* data, size_t datasize, const std::string & pattern) + { + return Write(data, datasize, Transform(pattern)); + } + + /** + \brief Search and replace a pattern in a buffer. + \param [in,out] data The buffer to search and replace in. + \param datasize The size of the buffer. + \param searchpattern The pattern to find. + \param replacepattern The pattern to replace the found occurrence with. + \return true if it succeeds, false if it fails. + */ + static bool SearchAndReplace(uint8* data, size_t datasize, const WildcardPattern & searchpattern, const WildcardPattern & replacepattern); /** \brief Search and replace a pattern in a buffer. @@ -75,7 +101,10 @@ 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 SearchAndReplace(uint8* data, size_t datasize, const char* searchpattern, const char* replacepattern); + static bool SearchAndReplace(uint8* data, size_t datasize, const std::string & searchpattern, const std::string & replacepattern) + { + return SearchAndReplace(data, datasize, Transform(searchpattern), Transform(replacepattern)); + } }; };