summaryrefslogtreecommitdiff
path: root/library/Core.cpp
diff options
context:
space:
mode:
authorAlexander Gavrilov2012-08-17 14:32:04 +0400
committerAlexander Gavrilov2012-08-17 15:07:48 +0400
commitbcc41c081a43a68042c4757a6569cb690098d9b8 (patch)
tree583f40741778c0e0634fd50610cf6c6f4d979a05 /library/Core.cpp
parent509d9570908e1befa537d10285942006d148b3a3 (diff)
downloaddfhack-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.cpp50
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
*******************************************************************************/