diff options
author | jbzdarkid <jbzdarkid@gmail.com> | 2018-10-27 23:28:42 -0700 |
---|---|---|
committer | jbzdarkid <jbzdarkid@gmail.com> | 2018-10-27 23:28:42 -0700 |
commit | 2c9afc07fe5cc53fefb90540d5db2ca424c71a51 (patch) | |
tree | 55ba19ae0e3f52f732d9382b6deccf6d879035c7 /Source/Memory.cpp | |
parent | ecc14a3463c0c1c52b5de17d2aeb719ce2942a4a (diff) | |
download | witness-tutorializer-2c9afc07fe5cc53fefb90540d5db2ca424c71a51.tar.gz witness-tutorializer-2c9afc07fe5cc53fefb90540d5db2ca424c71a51.tar.bz2 witness-tutorializer-2c9afc07fe5cc53fefb90540d5db2ca424c71a51.zip |
Major restructuring -- also set up for UI work tomorrow
Diffstat (limited to 'Source/Memory.cpp')
-rw-r--r-- | Source/Memory.cpp | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/Source/Memory.cpp b/Source/Memory.cpp new file mode 100644 index 0000000..0afeded --- /dev/null +++ b/Source/Memory.cpp | |||
@@ -0,0 +1,80 @@ | |||
1 | #include "Memory.h" | ||
2 | #include <psapi.h> | ||
3 | #include <tlhelp32.h> | ||
4 | #include <iostream> | ||
5 | |||
6 | #undef PROCESSENTRY32 | ||
7 | #undef Process32Next | ||
8 | |||
9 | Memory::Memory(const std::string& processName) { | ||
10 | // First, get the handle of the process | ||
11 | PROCESSENTRY32 entry; | ||
12 | entry.dwSize = sizeof(entry); | ||
13 | HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); | ||
14 | while (Process32Next(snapshot, &entry)) { | ||
15 | if (processName == entry.szExeFile) { | ||
16 | _handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID); | ||
17 | break; | ||
18 | } | ||
19 | } | ||
20 | if (!_handle) { | ||
21 | std::cout << "Couldn't find " << processName.c_str() << ", is it open?" << std::endl; | ||
22 | exit(EXIT_FAILURE); | ||
23 | } | ||
24 | |||
25 | // Next, get the process base address | ||
26 | DWORD numModules; | ||
27 | std::vector<HMODULE> moduleList(1024); | ||
28 | EnumProcessModulesEx(_handle, &moduleList[0], static_cast<DWORD>(moduleList.size()), &numModules, 3); | ||
29 | |||
30 | std::string name(64, 0); | ||
31 | for (DWORD i = 0; i < numModules / sizeof(HMODULE); i++) { | ||
32 | GetModuleBaseNameA(_handle, moduleList[i], &name[0], sizeof(name)); | ||
33 | |||
34 | // TODO: Filling with 0s still yeilds name.size() == 64... | ||
35 | if (strcmp(processName.c_str(), name.c_str()) == 0) { | ||
36 | _baseAddress = (uintptr_t)moduleList[i]; | ||
37 | break; | ||
38 | } | ||
39 | } | ||
40 | if (_baseAddress == 0) { | ||
41 | std::cout << "Couldn't find the base process address!" << std::endl; | ||
42 | exit(EXIT_FAILURE); | ||
43 | } | ||
44 | } | ||
45 | |||
46 | Memory::~Memory() { | ||
47 | CloseHandle(_handle); | ||
48 | } | ||
49 | |||
50 | void Memory::ThrowError() { | ||
51 | std::string message(256, '\0'); | ||
52 | FormatMessageA(4096, nullptr, GetLastError(), 1024, &message[0], static_cast<DWORD>(message.length()), nullptr); | ||
53 | std::cout << message.c_str() << std::endl; | ||
54 | exit(EXIT_FAILURE); | ||
55 | } | ||
56 | |||
57 | void* Memory::ComputeOffset(std::vector<int> offsets) | ||
58 | { | ||
59 | // Leave off the last offset, since it will be either read/write, and may not be of type unitptr_t. | ||
60 | int final_offset = offsets.back(); | ||
61 | offsets.pop_back(); | ||
62 | |||
63 | uintptr_t cumulativeAddress = _baseAddress; | ||
64 | for (const int offset : offsets) { | ||
65 | cumulativeAddress += offset; | ||
66 | |||
67 | const auto search = _computedAddresses.find(cumulativeAddress); | ||
68 | if (search == std::end(_computedAddresses)) { | ||
69 | // If the address is not yet computed, then compute it. | ||
70 | uintptr_t computedAddress = 0; | ||
71 | if (!ReadProcessMemory(_handle, reinterpret_cast<LPVOID>(cumulativeAddress), &computedAddress, sizeof(uintptr_t), NULL)) { | ||
72 | ThrowError(); | ||
73 | } | ||
74 | _computedAddresses[cumulativeAddress] = computedAddress; | ||
75 | } | ||
76 | |||
77 | cumulativeAddress = _computedAddresses[cumulativeAddress]; | ||
78 | } | ||
79 | return reinterpret_cast<void*>(cumulativeAddress + final_offset); | ||
80 | } | ||