From cf9a9d4fd2cf95a5c534302a3eb776f74d5dd6cf Mon Sep 17 00:00:00 2001 From: boris Date: Wed, 28 Nov 2018 20:34:17 +1300 Subject: scuffed syscalls they worked on windows 10 but fuck up on 8.1 now this is epic --- loader/client/client.vcxproj | 3 ++ loader/client/client.vcxproj.filters | 3 ++ loader/client/client_windows.cpp | 13 ++++- loader/client/fnv.hpp | 64 +++++++++++++++++++++++ loader/client/strings.hpp | 2 +- loader/client/syscall.cpp | 99 ++++++++++++++++++++++++++++++++++++ loader/client/syscall.hpp | 51 +++++++++++++++++++ loader/server/server_windows.cpp | 4 ++ 8 files changed, 237 insertions(+), 2 deletions(-) create mode 100644 loader/client/fnv.hpp create mode 100644 loader/client/syscall.cpp create mode 100644 loader/client/syscall.hpp diff --git a/loader/client/client.vcxproj b/loader/client/client.vcxproj index 0e44455..21241a8 100644 --- a/loader/client/client.vcxproj +++ b/loader/client/client.vcxproj @@ -37,11 +37,14 @@ + + + 15.0 diff --git a/loader/client/client.vcxproj.filters b/loader/client/client.vcxproj.filters index b5f56db..30aadc5 100644 --- a/loader/client/client.vcxproj.filters +++ b/loader/client/client.vcxproj.filters @@ -5,8 +5,11 @@ + + + \ No newline at end of file diff --git a/loader/client/client_windows.cpp b/loader/client/client_windows.cpp index 15e4af7..1753088 100644 --- a/loader/client/client_windows.cpp +++ b/loader/client/client_windows.cpp @@ -1,3 +1,7 @@ +//moneybot client +//written with love by +//im friendly and boris + #include #include #include @@ -8,6 +12,7 @@ #pragma comment( lib, "ws2_32.lib" ) #include "connect.hpp" +#include "syscall.hpp" /* 1. Connect @@ -39,6 +44,12 @@ int main( ) { std::string ip = "127.0.0.1"; // std::cin >> ip; + //okay now this is epic + auto syscaller = std::make_shared(); + + if (!syscaller->start()) + return 3; + // START. client::c_connect c( ip.c_str( ) ); if( !c.setup( ) ) @@ -46,7 +57,7 @@ int main( ) { if( !c.connect( ) ) return 2; - + c.handle( ); system( "pause" ); diff --git a/loader/client/fnv.hpp b/loader/client/fnv.hpp new file mode 100644 index 0000000..08a478b --- /dev/null +++ b/loader/client/fnv.hpp @@ -0,0 +1,64 @@ +#pragma once + +#pragma warning( disable : 4307 ) // '*': integral constant overflow +#pragma warning( disable : 4244 ) // possible loss of data + +#include +#include + +using hash_t = unsigned int; + +// used for compile-time FNV-1a 32bit hashes. +#define fnv( str ) \ + [&]() { \ + constexpr hash_t out = hash::fnv1a( str ); \ + \ + return out; \ + }() + +// used for compile-time FNV-1a 32bit hashes when above macro cant be used for constexpr variables. +#define fnv_const( str ) Hash::fnv1a_32( str ) + +namespace hash // FNV-1a ( Fowler-Noll-Vo hash ). +{ + // FNV-1a constants. + enum : hash_t { + FNV1A_PRIME = 0x1000193, + FNV1A_BASIS = 0x811C9DC5 + }; + + // compile-time strlen. + __forceinline constexpr size_t ct_strlen( const char *str ) { + size_t out = 1; + + for( ; str[ out ] != '\0'; ++out ); + + return out; + } + + // hash data. + __forceinline constexpr hash_t fnv1a( const uint8_t *data, const size_t len ) { + hash_t out = FNV1A_BASIS; + + for( size_t i = 0; i < len; ++i ) + out = ( out ^ data[ i ] ) * FNV1A_PRIME; + + return out; + } + + // hash c-style string. + __forceinline constexpr hash_t fnv1a( const char *str ) { + hash_t out = FNV1A_BASIS; + size_t len = ct_strlen( str ); + + for( size_t i = 0; i < len; ++i ) + out = ( out ^ str[ i ] ) * FNV1A_PRIME; + + return out; + } + + // hash C++-style string ( runtime only ). + __forceinline hash_t fnv1a( const std::string &str ) { + return fnv1a( ( uint8_t* )str.c_str( ), str.length( ) ); + } +} \ No newline at end of file diff --git a/loader/client/strings.hpp b/loader/client/strings.hpp index b5dba75..382ddb2 100644 --- a/loader/client/strings.hpp +++ b/loader/client/strings.hpp @@ -152,7 +152,7 @@ constexpr size_t strlen_ct( const char* const str ) { return out; } -#if TRUE +#if 0 #define xors_raw( s ) ( strenc::XorString< strenc::strlen_ct( s ), __COUNTER__ >( s, std::make_index_sequence< sizeof( s ) - 1>() ) ) #define xors( s ) ( strenc::XorString< strenc::strlen_ct( s ), __COUNTER__ >( s, std::make_index_sequence< sizeof( s ) - 1>() ).decrypt() ) #else diff --git a/loader/client/syscall.cpp b/loader/client/syscall.cpp new file mode 100644 index 0000000..7257456 --- /dev/null +++ b/loader/client/syscall.cpp @@ -0,0 +1,99 @@ +#include "syscall.hpp" +#include +#include + +//fuck balloon head +namespace syscall { + uint8_t *c_syscall_mgr::load_ntdll() { + //load ntdll from disk + char path[MAX_PATH]; + GetSystemDirectoryA(path, MAX_PATH); + + std::string ntdll_path(path); + ntdll_path += xors("\\ntdll.dll"); + + FILE* file; + if (fopen_s(&file, ntdll_path.c_str(), "rb") != 0) + return nullptr; + + fseek(file, 0, SEEK_END); + size_t ntdll_size = ftell(file); + rewind(file); + + uint8_t* ntdll = new uint8_t[ntdll_size]; + fread(ntdll, ntdll_size, 1, file); + fclose(file); + + return ntdll; + } + + bool c_syscall_mgr::start() { + uint8_t* ntdll = load_ntdll(); + if (!ntdll) + return false; + + IMAGE_DOS_HEADER* dos_header = (IMAGE_DOS_HEADER*)(&ntdll[0]); + IMAGE_NT_HEADERS* nt_header = (IMAGE_NT_HEADERS*)(&ntdll[dos_header->e_lfanew]); + + if (dos_header->e_magic != IMAGE_DOS_SIGNATURE) { + delete[] ntdll; + return false; + } + + if (nt_header->Signature != IMAGE_NT_SIGNATURE) { + delete[] ntdll; + return false; + } + + IMAGE_SECTION_HEADER* section_header = (IMAGE_SECTION_HEADER*)(&ntdll[dos_header->e_lfanew + sizeof(IMAGE_NT_HEADERS)]); + uintptr_t export_rva = nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; + + uint32_t delta = 0; + for (size_t i = 0; i < nt_header->FileHeader.NumberOfSections; i++) { + if (export_rva > section_header[i].VirtualAddress) + delta = section_header[i].VirtualAddress - section_header[i].PointerToRawData; + } + + //exports + IMAGE_EXPORT_DIRECTORY* export_directory = (IMAGE_EXPORT_DIRECTORY*)(&ntdll[export_rva - delta]); + + size_t number_of_functions = export_directory->NumberOfFunctions; + uintptr_t names = export_directory->AddressOfNames - delta; + uintptr_t funcs = export_directory->AddressOfFunctions - delta; + uintptr_t ords = export_directory->AddressOfNameOrdinals - delta; + + for (size_t i = 0; i < number_of_functions; i++) { + uint32_t name_rva = *(uint32_t*)(&ntdll[names + i * sizeof(uint32_t)]) - delta; + char* name = (char*)(&ntdll[name_rva]); + + uint16_t ordinal = *(uint16_t*)(&ntdll[ords + i * sizeof(uint16_t)]); + uint32_t func_rva = *(uint32_t*)(&ntdll[funcs + ordinal * sizeof(uint32_t)]); + + uint32_t func_delta = 0; + for (size_t j = 0; j < nt_header->FileHeader.NumberOfSections; j++) { + if (func_rva > section_header[j].VirtualAddress) + func_delta = section_header[j].VirtualAddress - section_header[j].PointerToRawData; + } + + func_rva -= func_delta; + + uint32_t code = *(uint32_t*)(&ntdll[func_rva + 0]);//crashes here? + uint32_t index = *(uint32_t*)(&ntdll[func_rva + 4]); + + //syscall + if (code == 0xB8D18B4C) + { + m_syscalls[hash::fnv1a(name)].set_index(index); + } + } + + delete[] ntdll; + + // check if we succesfully got the syscalls + hash_t hash = fnv("ZwWriteVirtualMemory"); + if (m_syscalls.find(hash) != m_syscalls.end()) + return m_syscalls[hash].validate(); + + return false; + } +} \ No newline at end of file diff --git a/loader/client/syscall.hpp b/loader/client/syscall.hpp new file mode 100644 index 0000000..55135ca --- /dev/null +++ b/loader/client/syscall.hpp @@ -0,0 +1,51 @@ +#pragma once + +#include +#include + +#include +#include "fnv.hpp" +#include "strings.hpp" + +namespace syscall { + //stub for calling the syscalls + class c_syscall_stub { + uint8_t m_stub[11] = { + 0x4c, 0x8b, 0xd1, // mov r10, rcx + 0xb8, 0x00, 0x00, 0x00, 0x00, // mov eax, 0h + 0x0f, 0x05, // syscall + 0xc3 // retn + }; + + public: + void set_index(uint32_t index) { + unsigned long old; + if (VirtualProtect(m_stub, sizeof m_stub, PAGE_EXECUTE_READWRITE, &old)) { + //okay now this is epic + *(uint32_t*)(&m_stub[4]) = index; + } + } + + __forceinline bool validate() { + return *(uint32_t*)(&m_stub[4]) != 0; + } + + uintptr_t operator()() { + return (uintptr_t)m_stub; + } + }; + + //syscaller + class c_syscall_mgr { + std::map< hash_t, c_syscall_stub > m_syscalls; + + uint8_t *load_ntdll(); + public: + bool start(); + + template + T get(hash_t hash) { + return (T)(m_syscalls[hash]()); + } + }; +} \ No newline at end of file diff --git a/loader/server/server_windows.cpp b/loader/server/server_windows.cpp index cdc6ac4..fe6b572 100644 --- a/loader/server/server_windows.cpp +++ b/loader/server/server_windows.cpp @@ -1,3 +1,7 @@ +//moneybot server +//written with love by +//im friendly and boris + #ifdef WIN64 #include #pragma comment(lib, "ws2_32.lib") -- cgit v1.2.3