#pragma once #include #include #include #include namespace RemoteCode { // The module wrapper. class RemoteProcess; class RemoteModule { HANDLE m_Module; int32_t m_SizeOfModule; // All the module data will be read upon class initialisation. ByteArray m_ModuleData; public: // The constructor (reads all module data into m_ModuleData). RemoteModule(HANDLE Module, RemoteProcess &Process); // TODO: Add support for wild-cards (not currently implemented) uintptr_t Scan(ByteArray &Pattern); // Allow us to access the module by just passing the // handle as a parameter. operator HANDLE() { return m_Module; } operator HINSTANCE() { return (HINSTANCE)m_Module; } }; // The process wrapper. class RemoteProcess { HANDLE m_Process; int32_t m_ProcessId; // Exposing the syscalls in a convenient way to use with templating. void ReadMemoryWrapper_Internal(void *Address, void *Data, size_t SizeOfData); void WriteMemoryWrapper_Internal(void *Address, void *Data, size_t SizeOfData); public: RemoteProcess() = default; // For portability, will ignore exceptions. RemoteProcess(const char *ProcessName) { Start(ProcessName); } // Release the handle when the process goes out of scope. ~RemoteProcess() { if(m_Process) CloseHandle(m_Process); } // Find the process ID and initialise the process. bool Start(const char *ProcessName); // Writes to the process memory. template void Write(void *Address, T Data) { WriteMemoryWrapper_Internal(Address, (void *)&Data, sizeof T); } void Write(void *Address, uint8_t *Data, size_t SizeOfData) { WriteMemoryWrapper_Internal(Address, (void *)Data, SizeOfData); } // Reads from the process memory. template T Read(void *Address) { T Buffer{}; ReadMemoryWrapper_Internal(Address, (void *)&Buffer, sizeof T); return Buffer; } void Read(void *Address, uint8_t *Data, size_t SizeOfData) { ReadMemoryWrapper_Internal(Address, (void *)Data, SizeOfData); } // Allocates a memory region in the process. void *Allocate(size_t AllocationSize); // Finds a module in the process. RemoteModule FindModule(const char *ModuleName); // Allow us to access the process by just passing the // handle as a parameter. operator HANDLE() { return m_Process; } }; }