Repository navigation
Expand file tree
/
Copy pathwindump.cpp
More file actions
186 lines (165 loc) · 5.72 KB
/
Copy pathwindump.cpp
File metadata and controls
186 lines (165 loc) · 5.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#include "common.h"
#include <windows.h>
#include <tlhelp32.h>
#include <psapi.h>
#include <iostream>
#include <cstring>
using namespace std;
HANDLE dolphinProcHandle = 0;
uint64_t emuRAMAddressStart = 0;
bool MEM2Present = false;
// Shamelessly ripped from Dolphin-memory-engine
// https://github.com/aldelaro5/Dolphin-memory-engine/blob/master/Source/DolphinProcess/Windows/WindowsDolphinProcess.cpp
// Returns true if we found and set emuRAMAddressStart
bool getEmuRAMAddressStart() {
if (!dolphinProcHandle)
return false;
MEMORY_BASIC_INFORMATION info;
bool MEM1Found = false;
for (unsigned char* p = nullptr; VirtualQueryEx(dolphinProcHandle, p, &info, sizeof(info)) == sizeof(info); p += info.RegionSize) {
if (MEM1Found) {
uint64_t regionBaseAddress = 0;
memcpy(®ionBaseAddress, &(info.BaseAddress), sizeof(info.BaseAddress));
if (regionBaseAddress == emuRAMAddressStart + 0x10000000) {
// View the comment for MEM1
PSAPI_WORKING_SET_EX_INFORMATION wsInfo;
wsInfo.VirtualAddress = info.BaseAddress;
if (QueryWorkingSetEx(dolphinProcHandle, &wsInfo, sizeof(PSAPI_WORKING_SET_EX_INFORMATION))) {
if (wsInfo.VirtualAttributes.Valid)
MEM2Present = true;
}
break;
} else if (regionBaseAddress > emuRAMAddressStart + 0x10000000) {
MEM2Present = false;
break;
}
continue;
}
if (info.RegionSize == 0x2000000 && info.Type == MEM_MAPPED) {
// Here, it's likely the right page, but it can happen that multiple pages with these criteria
// exists and have nothing to do with the emulated memory. Only the right page has valid
// working set information so an additional check is required that it is backed by physical memory.
PSAPI_WORKING_SET_EX_INFORMATION wsInfo;
wsInfo.VirtualAddress = info.BaseAddress;
if (QueryWorkingSetEx(dolphinProcHandle, &wsInfo, sizeof(PSAPI_WORKING_SET_EX_INFORMATION))) {
if (wsInfo.VirtualAttributes.Valid) {
memcpy(&emuRAMAddressStart, &(info.BaseAddress), sizeof(info.BaseAddress));
MEM1Found = true;
cout << "Found ram start: " << emuRAMAddressStart << endl;
}
}
}
}
if (!emuRAMAddressStart)
return false; // Dolphin is running, but the emulation hasn't started
return true;
}
void findAndAttachProcess() {
PROCESSENTRY32 entry;
entry.dwSize = sizeof(PROCESSENTRY32);
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
bool found = false;
if (Process32First(snapshot, &entry) == TRUE) {
while (Process32Next(snapshot, &entry) == TRUE) {
if (strncmp(entry.szExeFile, "Dolphin.exe", 10) == 0) {
cout << "Found Dolphin, PID " << entry.th32ProcessID << endl;
dolphinProcHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_READ, FALSE, entry.th32ProcessID);
found = true;
break;
}
}
}
CloseHandle(snapshot);
if (!found) {
cerr << "Can't find dolphin. Launch dolphin first!" << endl;
exit(1);
}
if (!getEmuRAMAddressStart()) {
// Wait for dolphin to start running a game
cout << "Detected dolphin isn't running a game. Waiting for game to start" << endl;
while (!getEmuRAMAddressStart())
Sleep(1000);
}
}
uint32_t getRealPtr(uint32_t address) {
uint32_t masked = address & 0x7FFFFFFFu;
if (masked > 0x1800000) {
return 0;
}
return masked;
}
void dolphin_memcpy(void *dest, size_t offset, size_t size) {
if (size > 0x1800000) {
size = 0x1800000;
}
SIZE_T read = 0;
if (ReadProcessMemory(dolphinProcHandle, reinterpret_cast<void*>(emuRAMAddressStart + getRealPtr(address)), dest, 4, &read) == 0) {
cerr << "Failed to read memory from" << address << ". Error: " << GetLastError() << endl;
}
if (read != size) {
cerr << "Failed to read enough from " << hex << address << ". Read: " << read << " of " << size << dec << endl;
}
}
//namespace GameMemory {
// uint32_t getRealPtr(uint32_t address) {
// uint32_t masked = address & 0x7FFFFFFF;
// if (masked > 0x1800000) {
// return 0;
// }
// return masked;
// }
//
// uint32_t read_u32(uint32_t address) {
// if (!emuRAMAddressStart)
// return 0;
//
// uint32_t res = 0;
// SIZE_T read = 0;
// if (ReadProcessMemory(dolphinProcHandle, reinterpret_cast<void*>(emuRAMAddressStart + getRealPtr(address)), &res, 4, &read) == 0) {
// cerr << "Failed to read memory from" << address << ". Error: " << GetLastError() << endl;
// return 0;
// }
//
// if (read != 4) {
// return 0;
// } else {
// return beToHost32(res);
// }
// }
//
// uint64_t read_u64(uint32_t address) {
// if (!emuRAMAddressStart)
// return 0;
//
// uint64_t res = 0;
// SIZE_T read = 0;
// if (ReadProcessMemory(dolphinProcHandle, reinterpret_cast<void*>(emuRAMAddressStart + getRealPtr(address)), &res, 8, &read) == 0) {
// cerr << "Failed to read memory from" << address << ". Error: " << GetLastError() << endl;
// return 0;
// }
//
// if (read != 8) {
// return 0;
// } else {
// return beToHost64(res);
// }
// }
//
// float read_float(uint32_t address) {
// union {
// uint32_t i;
// float f;
// } u;
// u.i = read_u32(address);
// return u.f;
// }
//
// double read_double(uint32_t address) {
// union {
// uint64_t i;
// double d;
// } u;
// u.i = read_u64(address);
// return u.d;
// }
//}