#include <iostream>
#include <cstdint>
#include <cstring>
#include <stdexcept>
#include <memory>
using namespace std;
using DWORD = uint32_t;
using DWORD_PTR = uintptr_t;
using BOOL = int;
using HANDLE = void*;
using LPCVOID = const void*;
using LPVOID = void*;
using SIZE_T = size_t;
BOOL ReadProcessMemory(HANDLE hProcess, LPCVOID lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesRead)
{
memcpy(lpBuffer, lpBaseAddress, nSize);
if (lpNumberOfBytesRead) *lpNumberOfBytesRead = nSize;
return 1;
}
HANDLE targetProcess = nullptr;
template<typename T>
T read(DWORD_PTR addy)
{
T buffer;
if (!ReadProcessMemory(targetProcess, (LPVOID)addy, &buffer, sizeof(T), NULL))
throw std::runtime_error("ReadProcessMemory failed");
return buffer;
}
template<typename T, typename... OffsetTypes>
T read(DWORD_PTR addy, DWORD offset, OffsetTypes... offsets)
{
DWORD_PTR ptr = read<DWORD_PTR>(addy);
return read<T>(ptr + offset, offsets...);
}
// I couldn't get alignas(1) to work correctly in this compiler,
// so using some hacks to force it to work...
struct Struct1
{
/*
char padding[0x50];
LPVOID ptr;
*/
char padding_and_ptr[0x50 + sizeof(LPVOID)];
} s1;
struct Struct2
{
/*
char padding[0x70];
float value;
*/
char padding_and_value[0x70 + sizeof(float)];
} s2;
struct FakeProcessInfo
{
/*
char padding[0x12345];
LPVOID ptr;
*/
char padding_and_ptr[0x12345 + sizeof(LPVOID)];
};
int main()
{
auto FakeProcess = std::make_unique<FakeProcessInfo>();
// hacks
LPVOID &fp_ptr = reinterpret_cast<LPVOID&>(FakeProcess->padding_and_ptr[0x12345]);
LPVOID &s1_ptr = reinterpret_cast<LPVOID&>(s1.padding_and_ptr[0x50]);
float &value = reinterpret_cast<float&>(s2.padding_and_value[0x70]);
//
fp_ptr = std::addressof(s1);
s1_ptr = std::addressof(s2);
value = 12345.0f;
DWORD_PTR baseAddr = reinterpret_cast<DWORD_PTR>(FakeProcess.get());
float data = read<float>(baseAddr+0x12345, 0x50, 0x70);
cout << "data: " << data << endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8Y3N0ZGludD4KI2luY2x1ZGUgPGNzdHJpbmc+CiNpbmNsdWRlIDxzdGRleGNlcHQ+CiNpbmNsdWRlIDxtZW1vcnk+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7Cgp1c2luZyBEV09SRCA9IHVpbnQzMl90Owp1c2luZyBEV09SRF9QVFIgPSB1aW50cHRyX3Q7CnVzaW5nIEJPT0wgPSBpbnQ7CnVzaW5nIEhBTkRMRSA9IHZvaWQqOwp1c2luZyBMUENWT0lEID0gY29uc3Qgdm9pZCo7CnVzaW5nIExQVk9JRCA9IHZvaWQqOwp1c2luZyBTSVpFX1QgPSBzaXplX3Q7CgpCT09MIFJlYWRQcm9jZXNzTWVtb3J5KEhBTkRMRSBoUHJvY2VzcywgTFBDVk9JRCBscEJhc2VBZGRyZXNzLCBMUFZPSUQgbHBCdWZmZXIsIFNJWkVfVCBuU2l6ZSwgU0laRV9UICpscE51bWJlck9mQnl0ZXNSZWFkKQp7CgltZW1jcHkobHBCdWZmZXIsIGxwQmFzZUFkZHJlc3MsIG5TaXplKTsKCWlmIChscE51bWJlck9mQnl0ZXNSZWFkKSAqbHBOdW1iZXJPZkJ5dGVzUmVhZCA9IG5TaXplOwoJcmV0dXJuIDE7Cn0KCkhBTkRMRSB0YXJnZXRQcm9jZXNzID0gbnVsbHB0cjsKCnRlbXBsYXRlPHR5cGVuYW1lIFQ+ClQgcmVhZChEV09SRF9QVFIgYWRkeSkKewogICAgVCBidWZmZXI7CiAgICBpZiAoIVJlYWRQcm9jZXNzTWVtb3J5KHRhcmdldFByb2Nlc3MsIChMUFZPSUQpYWRkeSwgJmJ1ZmZlciwgc2l6ZW9mKFQpLCBOVUxMKSkKICAgICAgICB0aHJvdyBzdGQ6OnJ1bnRpbWVfZXJyb3IoIlJlYWRQcm9jZXNzTWVtb3J5IGZhaWxlZCIpOwogICAgcmV0dXJuIGJ1ZmZlcjsKfQoKdGVtcGxhdGU8dHlwZW5hbWUgVCwgdHlwZW5hbWUuLi4gT2Zmc2V0VHlwZXM+ClQgcmVhZChEV09SRF9QVFIgYWRkeSwgRFdPUkQgb2Zmc2V0LCBPZmZzZXRUeXBlcy4uLiBvZmZzZXRzKQp7CiAgICBEV09SRF9QVFIgcHRyID0gcmVhZDxEV09SRF9QVFI+KGFkZHkpOwogICAgcmV0dXJuIHJlYWQ8VD4ocHRyICsgb2Zmc2V0LCBvZmZzZXRzLi4uKTsKfQoKLy8gSSBjb3VsZG4ndCBnZXQgYWxpZ25hcygxKSB0byB3b3JrIGNvcnJlY3RseSBpbiB0aGlzIGNvbXBpbGVyLAovLyBzbyB1c2luZyBzb21lIGhhY2tzIHRvIGZvcmNlIGl0IHRvIHdvcmsuLi4KCnN0cnVjdCBTdHJ1Y3QxCnsKCS8qCgljaGFyIHBhZGRpbmdbMHg1MF07CglMUFZPSUQgcHRyOwoJKi8KCWNoYXIgcGFkZGluZ19hbmRfcHRyWzB4NTAgKyBzaXplb2YoTFBWT0lEKV07Cn0gczE7CgpzdHJ1Y3QgU3RydWN0Mgp7CgkvKgoJY2hhciBwYWRkaW5nWzB4NzBdOwoJZmxvYXQgdmFsdWU7CgkqLwoJY2hhciBwYWRkaW5nX2FuZF92YWx1ZVsweDcwICsgc2l6ZW9mKGZsb2F0KV07Cn0gczI7CgpzdHJ1Y3QgRmFrZVByb2Nlc3NJbmZvCnsKCS8qCgljaGFyIHBhZGRpbmdbMHgxMjM0NV07CglMUFZPSUQgcHRyOwoJKi8KCWNoYXIgcGFkZGluZ19hbmRfcHRyWzB4MTIzNDUgKyBzaXplb2YoTFBWT0lEKV07Cn07CgppbnQgbWFpbigpCnsKCWF1dG8gRmFrZVByb2Nlc3MgPSBzdGQ6Om1ha2VfdW5pcXVlPEZha2VQcm9jZXNzSW5mbz4oKTsKCgkvLyBoYWNrcwoJTFBWT0lEICZmcF9wdHIgPSByZWludGVycHJldF9jYXN0PExQVk9JRCY+KEZha2VQcm9jZXNzLT5wYWRkaW5nX2FuZF9wdHJbMHgxMjM0NV0pOwoJTFBWT0lEICZzMV9wdHIgPSByZWludGVycHJldF9jYXN0PExQVk9JRCY+KHMxLnBhZGRpbmdfYW5kX3B0clsweDUwXSk7CglmbG9hdCAmdmFsdWUgPSByZWludGVycHJldF9jYXN0PGZsb2F0Jj4oczIucGFkZGluZ19hbmRfdmFsdWVbMHg3MF0pOwoJLy8KCglmcF9wdHIgPSBzdGQ6OmFkZHJlc3NvZihzMSk7CglzMV9wdHIgPSBzdGQ6OmFkZHJlc3NvZihzMik7Cgl2YWx1ZSA9IDEyMzQ1LjBmOwoKCURXT1JEX1BUUiBiYXNlQWRkciA9IHJlaW50ZXJwcmV0X2Nhc3Q8RFdPUkRfUFRSPihGYWtlUHJvY2Vzcy5nZXQoKSk7CglmbG9hdCBkYXRhID0gcmVhZDxmbG9hdD4oYmFzZUFkZHIrMHgxMjM0NSwgMHg1MCwgMHg3MCk7Cgljb3V0IDw8ICJkYXRhOiAiIDw8IGRhdGEgPDwgZW5kbDsKCXJldHVybiAwOwp9