From 35ad992665096e0313bc3d514da9cceacb25ba5d Mon Sep 17 00:00:00 2001 From: boris Date: Sun, 2 Dec 2018 11:54:04 +1300 Subject: epic shellcode also made code less gay --- loader/server/manual_map.cpp | 102 +++++++++++++++++++++++++++++++++++++-- loader/server/manual_map.hpp | 10 ++++ loader/server/server_windows.cpp | 57 +--------------------- 3 files changed, 109 insertions(+), 60 deletions(-) (limited to 'loader/server') diff --git a/loader/server/manual_map.cpp b/loader/server/manual_map.cpp index d2de29c..712d1a1 100644 --- a/loader/server/manual_map.cpp +++ b/loader/server/manual_map.cpp @@ -1,5 +1,94 @@ #include "manual_map.hpp" +namespace remote_code { + //i really hope you do this the turbochad way and sigscan your own shellcode for 69696969 + // u rite + constexpr size_t shellcode_size = 83; + constexpr uint8_t shellcode_code[] = { + 0x55, // push ebp + 0x8B, 0xEC, // mov ebp, esp + 0x51, // push ecx + 0x56, // push esi + 0x8D, 0x45, 0xFC, // lea eax, dword ptr[ ebp-4 ] + 0xC7, 0x45, 0xFC, 0x00, 0x00, 0x00, 0x00, // mov dword ptr[ ebp-4 ], 0 + // ; remove memory protection so we can write + 0x50, // push eax + 0x6A, 0x40, // push 40h + 0x6A, 0x04, // push 4h + 0x68, 0x69, 0x69, 0x69, 0x69, // push dword ptr[ vmt_endscene ] + 0xBE, 0xEF, 0xBE, 0xAD, 0xDE, // mov esi, dword ptr[ virtual_protect ] + 0xFF, 0xD6, // call esi + 0x84, 0xC0, // test al, al + 0x74, 0x2A, // jz clean_up + 0x8D, 0x45, 0xFC, // lea eax, dword ptr[ ebp-4 ] + // ; restore endscene ptr + 0xC7, 0x05, 0x69, 0x69, 0x69, 0x69, 0x0F, 0xD0, 0x0F, 0xD0, // mov [ vmt_endscene ], [ vmt_endscene_o ] + // ; restore memory protection + 0x50, // push eax + 0xFF, 0x75, 0xFC, // push dword ptr[ ebp-4 ] + 0x6A, 0x04, // push 4h + 0x68, 0x69, 0x69, 0x69, 0x69, // push dword ptr[ vmt_endscene ] + 0xFF, 0xD6, // call esi + // ; call cheat entrypoint + 0x6A, 0x00, // push 0h + 0x6A, 0x01, // push 1h + 0x68, 0xDE, 0xC0, 0xAD, 0xDE, // push dword ptr[ cheat_header ] + 0xB8, 0x0D, 0xF0, 0xAD, 0xDE, // mov eax, dword ptr[ cheat_entry ] + 0xFF, 0xD0, // call eax + // clean_up: + 0x5E, // pop esi + 0x8B, 0xE5, // mov esp, ebp + 0x5D, // pop ebp + 0xC3 // retn + }; + + struct shellcode_args_t { + uint32_t m_virtual_protect; // 0xDEADBEEF + uint32_t m_cheat_entrypoint; // 0xDEADF00D + uint32_t m_cheat_header; // 0xDEADC0DE + uint32_t m_endscene; // 0x69696969 + uint32_t m_endscene_o; // 0xD00FD00F + }; + + // turbo chad sig scanner (c) bowis + int32_t find_byte_pattern(std::vector &code, std::vector pattern) { + for (int32_t n = 0; n < code.size(); ++n) { + // check if code matches + if ((code.size() - n) >= pattern.size()) { + if (!memcmp(&code[n], pattern.data(), pattern.size())) + return n; + } + } + + return -1; + } + + // turbo chad code patcher (c) bowis + void patch_code(std::vector &code, int32_t offset, uint32_t value) { + std::memset(&code[offset], value, sizeof uint32_t); + } + + std::vector make_code(shellcode_args_t *arg) { + std::vector code; + code.insert(code.begin(), shellcode_code, shellcode_code + shellcode_size); + + patch_code(code, find_byte_pattern(code, { 0xEF, 0xBE, 0xAD, 0xDE }), arg->m_virtual_protect); + patch_code(code, find_byte_pattern(code, { 0x0D, 0xF0, 0xAD, 0xDE }), arg->m_cheat_entrypoint); + patch_code(code, find_byte_pattern(code, { 0xDE, 0xC0, 0xAD, 0xDE }), arg->m_cheat_header); + patch_code(code, find_byte_pattern(code, { 0x0F, 0xD0, 0x0F, 0xD0 }), arg->m_endscene_o); + + // there are three occurences of endscene + for(int n = 0; n < 3; ++n) + patch_code(code, find_byte_pattern(code, { 0x69, 0x69, 0x69, 0x69 }), arg->m_endscene); + + for (auto &c : code) { + printf("%02x ", c); + } + + return code; + } +} + namespace inject { // pe file implementation c_pe_file::c_pe_file(const char *file) { @@ -12,7 +101,7 @@ namespace inject { pe_file.seekg(0, pe_file.end); - uint32_t pe_size = pe_file.tellg(); + auto pe_size = pe_file.tellg(); m_file.resize(pe_size); pe_file.seekg(0, pe_file.beg); @@ -22,6 +111,10 @@ namespace inject { pe_file.read((char*)&m_file[0], pe_size); pe_file.close(); + + //remote_code::shellcode_args_t args; + //args = { 0x11111111, 0x22222222, 0x33333333, 0x44444444, 0x55555555 }; + //remote_code::make_code(&args); } bool c_pe_file::valid() { @@ -29,13 +122,13 @@ namespace inject { nt::nt_headers_t *nt_headers; // check dos header - dos_header = reinterpret_cast((uint32_t)data()); + dos_header = reinterpret_cast(data()); if (dos_header->e_magic != 0x45DA) return false; // check nt header - nt_headers = reinterpret_cast((uint32_t)data() + dos_header->e_lfanew); + nt_headers = reinterpret_cast(data() + dos_header->e_lfanew); if (nt_headers->signature != 0x50450000) return false; @@ -45,8 +138,7 @@ namespace inject { uint8_t *c_pe_file::data() { // go to the beginning of the file - // yes i know i could've just done 'new uint8_t[pe_size]' but fuck u. - return reinterpret_cast(&m_file[0]); + return m_file.data(); } size_t c_pe_file::size() const { diff --git a/loader/server/manual_map.hpp b/loader/server/manual_map.hpp index 1fbaddb..c23ac90 100644 --- a/loader/server/manual_map.hpp +++ b/loader/server/manual_map.hpp @@ -108,4 +108,14 @@ namespace inject { size_t size() const; }; + // server part of the manual mapper + class c_map_server { + protected: + using section_data_t = std::vector< uint8_t >; + using section_t = std::pair< uint32_t /* address */, section_data_t >; + + std::vector< section_t > m_sections; + public: + + }; } \ No newline at end of file diff --git a/loader/server/server_windows.cpp b/loader/server/server_windows.cpp index a098f35..548259b 100644 --- a/loader/server/server_windows.cpp +++ b/loader/server/server_windows.cpp @@ -21,65 +21,12 @@ #include #include "server.hpp" -//#include "manual_map.hpp" +#include "manual_map.hpp" server::c_server g_server; -// boris note: -// i spent most of today working on getting the manual mapping code to work (i'll put it here once it does) -// and i had to get this thing off my head, which is v epic -// give it a read and see what i mean -// we can abuse this for basically any other dx9 based game -// hopefully this will be assembled on server and sent off to client to trigger as entrypoint -// rather than the relocation code we would usually run on client with crappy manual mappers -// also: -// manual mapper will be written with a server/client approach in mind, it will be very easy to split the -// two apart once it's ready for implementation. i'll tell u about it in pms if you really want to know - -//i really hope you do this the turbochad way and sigscan your own shellcode for 69696969 - -// u rite - -uint8_t shellcode[] = { - 0x55, // push ebp - 0x8B, 0xEC, // mov ebp, esp - 0x51, // push ecx - 0x56, // push esi - 0x8D, 0x45, 0xFC, // lea eax, dword ptr[ ebp-4 ] - 0xC7, 0x45, 0xFC, 0x00, 0x00, 0x00, 0x00, // mov dword ptr[ ebp-4 ], 0 - // ; remove memory protection so we can write - 0x50, // push eax - 0x6A, 0x40, // push 40h - 0x6A, 0x04, // push 4h - 0x68, 0x69, 0x69, 0x69, 0x69, // push dword ptr[ vmt_endscene ] - 0xBE, 0xEF, 0xBE, 0xAD, 0xDE, // mov esi, dword ptr[ virtual_protect ] - 0xFF, 0xD6, // call esi - 0x84, 0xC0, // test al, al - 0x74, 0x2A, // jz clean_up - 0x8D, 0x45, 0xFC, // lea eax, dword ptr[ ebp-4 ] - // ; restore endscene ptr - 0xC7, 0x05, 0x69, 0x69, 0x69, 0x69, 0x0F, 0xD0, 0x0F, 0xD0, // mov [ vmt_endscene ], [ vmt_endscene_o ] - // ; restore memory protection - 0x50, // push eax - 0xFF, 0x75, 0xFC, // push dword ptr[ ebp-4 ] - 0x6A, 0x04, // push 4h - 0x68, 0x69, 0x69, 0x69, 0x69, // push dword ptr[ vmt_endscene ] - 0xFF, 0xD6, // call esi - // ; call cheat entrypoint - 0x6A, 0x00, // push 0h - 0x6A, 0x01, // push 1h - 0x68, 0xDE, 0xC0, 0xAD, 0xDE, // push dword ptr[ cheat_header ] - 0xB8, 0x0D, 0xF0, 0xAD, 0xDE, // mov eax, dword ptr[ cheat_entry ] - 0xFF, 0xD0, // call eax - // clean_up: - 0x5E, // pop esi - 0x8B, 0xE5, // mov esp, ebp - 0x5D, // pop ebp - 0xC3 // retn -}; - int main( ) { - //inject::c_pe_file file("test.bin"); + inject::c_pe_file file("test.bin"); //file.test(); int result = g_server.init( ); -- cgit v1.2.3