#pragma once // TODO: get stripped down version of what we need and shove it in here #include #include #include #include #include #include // here's the game plan: // - client runs, waits for game to start and whatnot // - we wait for serverbrowser.dll to load (if source game, we should have an option in the game struct to wait for module) // - client walks peb of process, dumps exports and packs them into { fnv, addy }, sends to server // - server sends module size, client allocates and replies back with module address // - server resolves imports through { fnv, addy } that were networked to us // - server fixes reloc // - we send back addy, then section data to client // - server packs shellcode with data from client, sends to client // - client runs shellcode, we're injected namespace inject { // used as generic wrapper for pe, tells client how much to allocate, etc. class c_pe_file { protected: std::vector< uint8_t > m_file; public: c_pe_file() = default; c_pe_file(const char *file); bool valid(); uint8_t *data(); size_t size() const; }; // used for fixing imports struct process_export_t { uint32_t m_hash; uint32_t m_address; }; // used for writing memory in client struct memory_page_t { uint32_t m_address; uint32_t m_protection; }; // container for sections using byte_array_t = std::vector; using memory_section_t = std::pair; // used as server wrapper for the manual mapper class c_mapper { protected: std::vector m_exports; std::vector m_sections; c_pe_file m_pe; private: bool process_reloc(uint32_t remote_address); bool process_imports(uint32_t remote_address); public: c_mapper() = default; c_mapper(c_pe_file &pe_file); // returns size of module to allocate on client size_t initialise(std::vector &exports); // handles reloc and fixing imports bool process_pe_file(uint32_t remote_address); // returns all sections std::vector get_pe_sections(); }; }