summary refs log tree commit diff stats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/Memory.cpp106
-rw-r--r--Source/Memory.h15
-rw-r--r--Source/Source.vcxproj2
3 files changed, 79 insertions, 44 deletions
diff --git a/Source/Memory.cpp b/Source/Memory.cpp index b0e2e9d..7b4b9c7 100644 --- a/Source/Memory.cpp +++ b/Source/Memory.cpp
@@ -2,25 +2,87 @@
2#include <psapi.h> 2#include <psapi.h>
3#include <tlhelp32.h> 3#include <tlhelp32.h>
4#include <iostream> 4#include <iostream>
5#include <string>
5#include <cassert> 6#include <cassert>
6 7
7#undef PROCESSENTRY32 8#undef PROCESSENTRY32
8#undef Process32Next 9#undef Process32Next
9 10
11Memory::Memory(const std::wstring& processName) : _processName(processName) {
12}
13
14Memory::~Memory() {
15 if (_threadActive) {
16 _threadActive = false;
17 _thread.join();
18 }
19 if (_handle != nullptr) {
20 CloseHandle(_handle);
21 }
22}
23
24void Memory::StartHeartbeat(HWND window, std::chrono::milliseconds beat) {
25 if (_threadActive) return;
26 _threadActive = true;
27 _thread = std::thread([sharedThis = shared_from_this(), window, beat]{
28 while (sharedThis->_threadActive) {
29 sharedThis->Heartbeat(window);
30 std::this_thread::sleep_for(beat);
31 }
32 });
33 _thread.detach();
34}
35
36void Memory::Heartbeat(HWND window) {
37 if (!_handle && !Initialize()) {
38 // Couldn't initialize, definitely not running
39 PostMessage(window, WM_COMMAND, HEARTBEAT, (LPARAM)ProcStatus::NotRunning);
40 return;
41 }
42
43 DWORD exitCode = 0;
44 assert(_handle);
45 GetExitCodeProcess(_handle, &exitCode);
46 if (exitCode != STILL_ACTIVE) {
47 // Process has exited, clean up.
48 _computedAddresses.clear();
49 _handle = NULL;
50 PostMessage(window, WM_COMMAND, HEARTBEAT, (LPARAM)ProcStatus::NotRunning);
51 return;
52 }
53
54#if GLOBALS == 0x5B28C0
55 int currentFrame = ReadData<int>({0x5BE3B0}, 1)[0];
56#elif GLOBALS == 0x62D0A0
57 int currentFrame = ReadData<int>({0x63954C}, 1)[0];
58#endif
59 int frameDelta = currentFrame - _previousFrame;
60 _previousFrame = currentFrame;
61 if (frameDelta < 0 && currentFrame < 250) {
62 PostMessage(window, WM_COMMAND, HEARTBEAT, (LPARAM)ProcStatus::NewGame);
63 return;
64 }
65
66 // TODO: Some way to return ProcStatus::Randomized vs ProcStatus::NotRandomized vs ProcStatus::DeRandomized;
67
68 PostMessage(window, WM_COMMAND, HEARTBEAT, (LPARAM)ProcStatus::Running);
69}
70
71
10[[nodiscard]] 72[[nodiscard]]
11bool Memory::Initialize(const std::wstring& processName) { 73bool Memory::Initialize() {
12 // First, get the handle of the process 74 // First, get the handle of the process
13 PROCESSENTRY32W entry; 75 PROCESSENTRY32W entry;
14 entry.dwSize = sizeof(entry); 76 entry.dwSize = sizeof(entry);
15 HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 77 HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
16 while (Process32NextW(snapshot, &entry)) { 78 while (Process32NextW(snapshot, &entry)) {
17 if (processName == entry.szExeFile) { 79 if (_processName == entry.szExeFile) {
18 _handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID); 80 _handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID);
19 break; 81 break;
20 } 82 }
21 } 83 }
22 if (!_handle) { 84 if (!_handle) {
23 std::cerr << "Couldn't find " << processName.c_str() << ", is it open?" << std::endl; 85 std::cerr << "Couldn't find " << _processName.c_str() << ", is it open?" << std::endl;
24 return false; 86 return false;
25 } 87 }
26 88
@@ -33,7 +95,7 @@ bool Memory::Initialize(const std::wstring& processName) {
33 for (DWORD i = 0; i < numModules / sizeof(HMODULE); i++) { 95 for (DWORD i = 0; i < numModules / sizeof(HMODULE); i++) {
34 int length = GetModuleBaseNameW(_handle, moduleList[i], &name[0], static_cast<DWORD>(name.size())); 96 int length = GetModuleBaseNameW(_handle, moduleList[i], &name[0], static_cast<DWORD>(name.size()));
35 name.resize(length); 97 name.resize(length);
36 if (processName == name) { 98 if (_processName == name) {
37 _baseAddress = (uintptr_t)moduleList[i]; 99 _baseAddress = (uintptr_t)moduleList[i];
38 break; 100 break;
39 } 101 }
@@ -45,42 +107,6 @@ bool Memory::Initialize(const std::wstring& processName) {
45 return true; 107 return true;
46} 108}
47 109
48ProcStatus Memory::Heartbeat(const std::wstring& processName) {
49 if (!_handle && !Initialize(processName)) {
50 // Couldn't initialize, definitely not running
51 return ProcStatus::NotRunning;
52 }
53
54 DWORD exitCode = 0;
55 GetExitCodeProcess(_handle, &exitCode);
56 if (exitCode != STILL_ACTIVE) {
57 // Process has exited, clean up.
58 _computedAddresses.clear();
59 _handle = NULL;
60 return ProcStatus::NotRunning;
61 }
62
63 int currentFrame = 0x7FFFFFFF;
64 if (GLOBALS == 0x5B28C0) {
65 currentFrame = ReadData<int>({0x5BE3B0}, 1)[0];
66 } else if (GLOBALS == 0x62D0A0) {
67 currentFrame = ReadData<int>({0x63954C}, 1)[0];
68 } else {
69 assert(false);
70 }
71 if (currentFrame < 80) return ProcStatus::NewGame;
72
73 // TODO: Some way to return ProcStatus::Randomized vs ProcStatus::NotRandomized vs ProcStatus::DeRandomized;
74
75 return ProcStatus::Running;
76}
77
78Memory::~Memory() {
79 if (_handle != nullptr) {
80 CloseHandle(_handle);
81 }
82}
83
84void Memory::AddSigScan(const std::vector<byte>& scanBytes, const std::function<void(int index)>& scanFunc) 110void Memory::AddSigScan(const std::vector<byte>& scanBytes, const std::function<void(int index)>& scanFunc)
85{ 111{
86 _sigScans[scanBytes] = {scanFunc, false}; 112 _sigScans[scanBytes] = {scanFunc, false};
diff --git a/Source/Memory.h b/Source/Memory.h index d7552c5..c19d92b 100644 --- a/Source/Memory.h +++ b/Source/Memory.h
@@ -1,12 +1,14 @@
1#pragma once 1#pragma once
2#include <functional> 2#include <functional>
3#include <map> 3#include <map>
4#include <thread>
4#include <vector> 5#include <vector>
5#include <windows.h> 6#include <windows.h>
6 7
7// #define GLOBALS 0x5B28C0 8// #define GLOBALS 0x5B28C0
8#define GLOBALS 0x62D0A0 9#define GLOBALS 0x62D0A0
9 10
11#define HEARTBEAT 0x401
10enum class ProcStatus { 12enum class ProcStatus {
11 NotRunning, 13 NotRunning,
12 Running, 14 Running,
@@ -17,11 +19,11 @@ enum class ProcStatus {
17// http://stackoverflow.com/q/32798185 19// http://stackoverflow.com/q/32798185
18// http://stackoverflow.com/q/36018838 20// http://stackoverflow.com/q/36018838
19// http://stackoverflow.com/q/1387064 21// http://stackoverflow.com/q/1387064
20class Memory { 22class Memory final : public std::enable_shared_from_this<Memory> {
21public: 23public:
22 Memory() = default; 24 Memory(const std::wstring& processName);
23 ProcStatus Heartbeat(const std::wstring& processName);
24 ~Memory(); 25 ~Memory();
26 void StartHeartbeat(HWND window, std::chrono::milliseconds beat = std::chrono::milliseconds(1000));
25 27
26 Memory(const Memory& memory) = delete; 28 Memory(const Memory& memory) = delete;
27 Memory& operator=(const Memory& other) = delete; 29 Memory& operator=(const Memory& other) = delete;
@@ -74,10 +76,15 @@ private:
74 ThrowError(); 76 ThrowError();
75 } 77 }
76 78
77 bool Initialize(const std::wstring& processName); 79 void Heartbeat(HWND window);
80 bool Initialize();
78 void ThrowError(); 81 void ThrowError();
79 void* ComputeOffset(std::vector<int> offsets); 82 void* ComputeOffset(std::vector<int> offsets);
80 83
84 int _previousFrame = 0;
85 bool _threadActive = false;
86 std::thread _thread;
87 std::wstring _processName;
81 std::map<uintptr_t, uintptr_t> _computedAddresses; 88 std::map<uintptr_t, uintptr_t> _computedAddresses;
82 uintptr_t _baseAddress = 0; 89 uintptr_t _baseAddress = 0;
83 HANDLE _handle = nullptr; 90 HANDLE _handle = nullptr;
diff --git a/Source/Source.vcxproj b/Source/Source.vcxproj index 3e66f83..e7f716c 100644 --- a/Source/Source.vcxproj +++ b/Source/Source.vcxproj
@@ -158,9 +158,11 @@
158 </ItemDefinitionGroup> 158 </ItemDefinitionGroup>
159 <ItemGroup> 159 <ItemGroup>
160 <ClInclude Include="Memory.h" /> 160 <ClInclude Include="Memory.h" />
161 <ClInclude Include="Random.h" />
161 </ItemGroup> 162 </ItemGroup>
162 <ItemGroup> 163 <ItemGroup>
163 <ClCompile Include="Memory.cpp" /> 164 <ClCompile Include="Memory.cpp" />
165 <ClCompile Include="Random.cpp" />
164 </ItemGroup> 166 </ItemGroup>
165 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> 167 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
166 <ImportGroup Label="ExtensionTargets"> 168 <ImportGroup Label="ExtensionTargets">