diff options
| -rw-r--r-- | loader/client/client.vcxproj | 3 | ||||
| -rw-r--r-- | loader/client/client.vcxproj.filters | 3 | ||||
| -rw-r--r-- | loader/client/client_windows.cpp | 13 | ||||
| -rw-r--r-- | loader/client/fnv.hpp | 64 | ||||
| -rw-r--r-- | loader/client/strings.hpp | 2 | ||||
| -rw-r--r-- | loader/client/syscall.cpp | 99 | ||||
| -rw-r--r-- | loader/client/syscall.hpp | 51 | ||||
| -rw-r--r-- | loader/server/server_windows.cpp | 4 |
8 files changed, 237 insertions, 2 deletions
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 @@ <ItemGroup>
<ClInclude Include="connect.hpp" />
<ClInclude Include="err.hpp" />
+ <ClInclude Include="fnv.hpp" />
<ClInclude Include="strings.hpp" />
+ <ClInclude Include="syscall.hpp" />
<ClInclude Include="util.hpp" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="client_windows.cpp" />
+ <ClCompile Include="syscall.cpp" />
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>
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 @@ <ClInclude Include="err.hpp" />
<ClInclude Include="strings.hpp" />
<ClInclude Include="util.hpp" />
+ <ClInclude Include="syscall.hpp" />
+ <ClInclude Include="fnv.hpp" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="client_windows.cpp" />
+ <ClCompile Include="syscall.cpp" />
</ItemGroup>
</Project>
\ 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 <Windows.h>
#include <stdio.h>
#include <stdlib.h>
@@ -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<syscall::c_syscall_mgr>();
+
+ 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 <cstdint> +#include <string> + +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 <vector>
+#include <fstream>
+
+//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 <windows.h>
+#include <winternl.h>
+
+#include <map>
+#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 <typename T>
+ 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 <Windows.h>
#pragma comment(lib, "ws2_32.lib")
|
