diff options
| author | Alexander Gavrilov | 2012-08-17 14:32:04 +0400 |
|---|---|---|
| committer | Alexander Gavrilov | 2012-08-17 15:07:48 +0400 |
| commit | bcc41c081a43a68042c4757a6569cb690098d9b8 (patch) | |
| tree | 583f40741778c0e0634fd50610cf6c6f4d979a05 /library/Core.cpp | |
| parent | 509d9570908e1befa537d10285942006d148b3a3 (diff) | |
| download | dfhack-bcc41c081a43a68042c4757a6569cb690098d9b8.tar.gz dfhack-bcc41c081a43a68042c4757a6569cb690098d9b8.tar.bz2 dfhack-bcc41c081a43a68042c4757a6569cb690098d9b8.tar.xz | |
Add a utility function for patching read-only memory.
Diffstat (limited to 'library/Core.cpp')
| -rw-r--r-- | library/Core.cpp | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/library/Core.cpp b/library/Core.cpp index 826576b7..f129d952 100644 --- a/library/Core.cpp +++ b/library/Core.cpp @@ -1548,6 +1548,56 @@ void ClassNameCheck::getKnownClassNames(std::vector<std::string> &names) names.push_back(*it); } +bool Process::patchMemory(void *target, const void* src, size_t count) +{ + uint8_t *sptr = (uint8_t*)target; + uint8_t *eptr = sptr + count; + + // Find the valid memory ranges + std::vector<t_memrange> ranges; + getMemRanges(ranges); + + unsigned start = 0; + while (start < ranges.size() && ranges[start].end <= sptr) + start++; + if (start >= ranges.size() || ranges[start].start > sptr) + return false; + + unsigned end = start+1; + while (end < ranges.size() && ranges[end].start < eptr) + { + if (ranges[end].start != ranges[end-1].end) + return false; + end++; + } + if (ranges[end-1].end < eptr) + return false; + + // Verify current permissions + for (unsigned i = start; i < end; i++) + if (!ranges[i].valid || !(ranges[i].read || ranges[i].execute) || ranges[i].shared) + return false; + + // Apply writable permissions & update + bool ok = true; + + for (unsigned i = start; i < end && ok; i++) + { + t_memrange perms = ranges[i]; + perms.write = perms.read = true; + if (!setPermisions(perms, perms)) + ok = false; + } + + if (ok) + memmove(target, src, count); + + for (unsigned i = start; i < end && ok; i++) + setPermisions(ranges[i], ranges[i]); + + return ok; +} + /******************************************************************************* M O D U L E S *******************************************************************************/ |
