#pragma once #include #include #include #include #include // if we compile on linux, we won't have access to windows.h (?) // i'll put there here just so we can access them anyway namespace nt { struct data_directory_t { uint32_t virtual_address; uint32_t size; }; struct optional_header_t { uint16_t magic; uint8_t major_link_version; uint8_t minor_link_version; uint32_t size_of_code; uint32_t size_of_init_data; uint32_t size_of_uninit_data; uint32_t entry_point; uint32_t base_of_code; uint32_t base_of_data; uint32_t image_base; uint32_t section_align; uint32_t file_align; uint16_t major_os_version; uint16_t minor_os_version; uint16_t major_img_version; uint16_t minor_img_version; uint16_t major_sub_version; uint16_t minor_sub_version; uint32_t win32_version; uint32_t size_image; uint32_t size_headers; uint32_t checksum; uint16_t subsystem; uint16_t dll_characteristics; uint32_t size_of_stack_reserve; uint32_t size_of_stack_commit; uint32_t size_of_heap_reserve; uint32_t size_of_heap_commit; uint32_t ldr_flags; uint32_t number_of_rva_and_sizes; data_directory_t data_directory[16]; }; struct file_header_t { uint16_t machine; uint16_t number_of_sections; uint32_t time_stamp; uint32_t ptr_symbol_table; uint32_t sym_number; uint16_t opt_header_size; uint16_t characteristics; }; struct dos_header_t { uint16_t e_magic; uint16_t e_cblp; uint16_t e_cp; uint16_t e_crlc; uint16_t e_cparhdr; uint16_t e_minalloc; uint16_t e_maxalloc; uint16_t e_ss; uint16_t e_sp; uint16_t e_csum; uint16_t e_ip; uint16_t e_cs; uint16_t e_lfarlc; uint16_t e_ovno; uint16_t e_res[4]; uint16_t e_oemid; uint16_t e_oeminfo; uint16_t e_res2[10]; int32_t e_lfanew; }; struct nt_headers_t { uint32_t signature; file_header_t file_header; optional_header_t opt_header; }; } // 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 { class c_pe_file { protected: std::vector< uint8_t > m_file; public: c_pe_file(const char *file); bool valid(); uint8_t *data(); size_t size() const; }; }