summaryrefslogtreecommitdiff
path: root/loader/client
diff options
context:
space:
mode:
authorboris <wzn@moneybot.cc>2018-11-28 20:34:17 +1300
committerboris <wzn@moneybot.cc>2018-11-28 20:34:17 +1300
commitcf9a9d4fd2cf95a5c534302a3eb776f74d5dd6cf (patch)
tree834c13577f16429d699767aeaf89d82ea9cfde2d /loader/client
parent61c2c13eba885e38b71379e1400ead6057ea9f2d (diff)
scuffed syscalls
they worked on windows 10 but fuck up on 8.1 now this is epic
Diffstat (limited to 'loader/client')
-rw-r--r--loader/client/client.vcxproj3
-rw-r--r--loader/client/client.vcxproj.filters3
-rw-r--r--loader/client/client_windows.cpp13
-rw-r--r--loader/client/fnv.hpp64
-rw-r--r--loader/client/strings.hpp2
-rw-r--r--loader/client/syscall.cpp99
-rw-r--r--loader/client/syscall.hpp51
7 files changed, 233 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