Skip to content

Instantly share code, notes, and snippets.

@mrexodia
Last active January 15, 2023 22:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mrexodia/4eb01c90e9be30058fb07cd449fb6cae to your computer and use it in GitHub Desktop.
Save mrexodia/4eb01c90e9be30058fb07cd449fb6cae to your computer and use it in GitHub Desktop.
Remote<T>
#include <cstdio>
#include <cstdint>
#include <cstring>
#include <type_traits>
#include <Windows.h>
void read_memory(const void* address, void* dst, size_t len)
{
printf("read_memory(%p, %zu)\n", address, len);
SIZE_T read = 0;
ReadProcessMemory(GetCurrentProcess(), address, dst, len, &read);
}
template<class T>
class Remote
{
T* ptr = nullptr;
Remote() = default;
friend class Remote<T*>;
public:
explicit Remote(uint64_t ptr) : ptr((T*)ptr) { }
explicit Remote(const void* ptr) : ptr((T*)ptr) { }
using Result = std::conditional_t<std::is_pointer_v<T>, Remote<std::remove_pointer_t<T>>, T>;
Result operator[](size_t index) const
{
Result result;
read_memory(ptr + index, &result, sizeof(result));
return result;
}
Result operator*() const
{
return (*this)[0];
}
};
static_assert(sizeof(Remote<int>) == sizeof(uint64_t), "");
static_assert(sizeof(Remote<int*>) == sizeof(uint64_t), "");
int main()
{
int secret = 1337;
int* secret_ptr = &secret;
int** secret_ptr_ptr = &secret_ptr;
printf("&&&secret: %p\n", &secret_ptr_ptr);
printf("&&secret: %p\n", secret_ptr_ptr);
printf("&secret: %p\n", &secret);
Remote<int**> r_secret_ptr_ptr(&secret_ptr_ptr);
Remote<int> r_secret_ptr = **r_secret_ptr_ptr;
printf("secret: %d\n", *r_secret_ptr);
int secret_arr[] = { 13, 37 };
printf("&secret_arr[0]: %p\n", &secret_arr[0]);
Remote<int> r_secret_arr(secret_arr);
printf("secret: %d\n", r_secret_arr[0] * 100 + r_secret_arr[1]);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment