From 3d412a4b30a9f7c7f51ea6562e694315948bd3da Mon Sep 17 00:00:00 2001 From: boris Date: Wed, 28 Nov 2018 16:00:02 +1300 Subject: cleaned up in short, the cheat and loader are now separate solutions. unused stuff was moved into the legacy solution in case anyone wants to compile it or whatever. i can change this back if you want to. also, i configured the loader to compile in x64, and have separate build types for linux and win64 --- legacy/injector/injector.vcxproj | 184 ++++++++++++++++++ legacy/injector/injector.vcxproj.filters | 33 ++++ legacy/injector/main.cpp | 121 ++++++++++++ legacy/injector/pe.h | 309 +++++++++++++++++++++++++++++++ legacy/injector/util.h | 44 +++++ legacy/injector/winapi.h | 81 ++++++++ 6 files changed, 772 insertions(+) create mode 100644 legacy/injector/injector.vcxproj create mode 100644 legacy/injector/injector.vcxproj.filters create mode 100644 legacy/injector/main.cpp create mode 100644 legacy/injector/pe.h create mode 100644 legacy/injector/util.h create mode 100644 legacy/injector/winapi.h (limited to 'legacy/injector') diff --git a/legacy/injector/injector.vcxproj b/legacy/injector/injector.vcxproj new file mode 100644 index 0000000..b376272 --- /dev/null +++ b/legacy/injector/injector.vcxproj @@ -0,0 +1,184 @@ + + + + + Debug + Win32 + + + pHit + Win32 + + + pHit + x64 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {0CD36550-BDEB-4967-9AC1-9AB1AE778C64} + injector + 10.0.17763.0 + + + + Application + true + v141 + MultiByte + + + Application + false + v141 + true + MultiByte + + + Application + false + v141 + true + MultiByte + + + Application + true + v141 + MultiByte + + + Application + false + v141 + true + MultiByte + + + Application + false + v141 + true + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Level3 + MaxSpeed + true + true + true + true + + + true + true + + + + + Level3 + MaxSpeed + true + true + true + true + + + true + true + + + + + Level3 + Disabled + true + true + + + + + Level3 + Disabled + true + true + + + + + Level3 + MaxSpeed + true + true + true + true + + + true + true + + + + + Level3 + MaxSpeed + true + true + true + true + + + true + true + + + + + + + + + + + + + + \ No newline at end of file diff --git a/legacy/injector/injector.vcxproj.filters b/legacy/injector/injector.vcxproj.filters new file mode 100644 index 0000000..d81baf0 --- /dev/null +++ b/legacy/injector/injector.vcxproj.filters @@ -0,0 +1,33 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + + + Source Files + + + \ No newline at end of file diff --git a/legacy/injector/main.cpp b/legacy/injector/main.cpp new file mode 100644 index 0000000..f3d3511 --- /dev/null +++ b/legacy/injector/main.cpp @@ -0,0 +1,121 @@ +#include +#include "winapi.h" + +const wchar_t* const kernel32_str = L"KERNEL32.DLL"; +const wchar_t* const ucrtbase_str = L"ucrtbase.dll"; +const char* const loadlib_str = "LoadLibraryA"; +const char* const printf_str = "printf"; + +const char* const printf_fmt = "print: %08x\n\0"; +const char* const fail_msg = "k32 null\n"; +const char* const pause_str = "pause"; +const char* const system_str = "system"; + +uintptr_t printf_addr = ( uintptr_t )&printf; +uintptr_t system_addr = 0; + +//i dont even +//unfinished btw + +__declspec( naked ) int print_var( uint32_t var ) { + __asm { + push ebp + mov ebp, esp + sub esp, __LOCAL_SIZE + + mov eax, var + push eax + push printf_fmt + call printf_addr + + add esp, 8 + mov esp, ebp + pop ebp + + mov eax, 0 + ret + } +} + +__declspec( naked ) void print_error( const char* err ) { + __asm { + push ebp + mov ebp, esp + sub esp, __LOCAL_SIZE + + mov eax, err + push eax + call printf_addr + + add esp, 8 + mov esp, ebp + pop ebp + } +} + +__declspec( naked ) int main( void ) { + void* k32; + void* ucrtbase; + uintptr_t loadlib; + + __asm { + push ebp + mov ebp, esp + sub esp, __LOCAL_SIZE + + mov eax, ds:ucrtbase_str + push eax + call winapi::k32::get_module_handle + add esp, 4 + mov ucrtbase, eax + + mov eax, ds:system_str + push eax + mov ecx, ucrtbase + push ecx + call winapi::k32::get_proc_address + add esp, 4 + mov system_addr, eax + + mov eax, ds:kernel32_str + push eax + call winapi::k32::get_module_handle + add esp, 4 + mov k32, eax + + mov eax, k32 + push eax + call print_var + + cmp k32, 0 + je K32_FAIL + + mov eax, ds:loadlib_str + push eax + mov ecx, k32 + push ecx + call winapi::k32::get_proc_address + + add esp, 8 + mov loadlib, eax + + mov eax, loadlib + push eax + call print_var + + jmp END + + K32_FAIL: + mov eax, fail_msg + push eax + call printf_addr + + END: + mov eax, pause_str + push eax + call system_addr + mov esp, ebp + pop ebp + ret + } +} \ No newline at end of file diff --git a/legacy/injector/pe.h b/legacy/injector/pe.h new file mode 100644 index 0000000..f67e46d --- /dev/null +++ b/legacy/injector/pe.h @@ -0,0 +1,309 @@ +#pragma once +#include + +namespace nt { + using WORD = short; + using BYTE = unsigned char; + using DWORD = unsigned long; + + typedef struct _IMAGE_DATA_DIRECTORY { + DWORD VirtualAddress; + DWORD Size; + } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY; + + typedef struct _IMAGE_OPTIONAL_HEADER { + WORD Magic; + BYTE MajorLinkerVersion; + BYTE MinorLinkerVersion; + DWORD SizeOfCode; + DWORD SizeOfInitializedData; + DWORD SizeOfUninitializedData; + DWORD AddressOfEntryPoint; + DWORD BaseOfCode; + DWORD BaseOfData; + DWORD ImageBase; + DWORD SectionAlignment; + DWORD FileAlignment; + WORD MajorOperatingSystemVersion; + WORD MinorOperatingSystemVersion; + WORD MajorImageVersion; + WORD MinorImageVersion; + WORD MajorSubsystemVersion; + WORD MinorSubsystemVersion; + DWORD Win32VersionValue; + DWORD SizeOfImage; + DWORD SizeOfHeaders; + DWORD CheckSum; + WORD Subsystem; + WORD DllCharacteristics; + DWORD SizeOfStackReserve; + DWORD SizeOfStackCommit; + DWORD SizeOfHeapReserve; + DWORD SizeOfHeapCommit; + DWORD LoaderFlags; + DWORD NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORY DataDirectory[ 16 ]; + } IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER; + + typedef struct _IMAGE_FILE_HEADER { + WORD Machine; + WORD NumberOfSections; + DWORD TimeDateStamp; + DWORD PointerToSymbolTable; + DWORD NumberOfSymbols; + WORD SizeOfOptionalHeader; + WORD Characteristics; + } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; + + typedef struct _IMAGE_NT_HEADERS { + DWORD Signature; + IMAGE_FILE_HEADER FileHeader; + IMAGE_OPTIONAL_HEADER OptionalHeader; + } IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS; + + typedef struct _IMAGE_EXPORT_DIRECTORY { + uint32_t Characteristics; + uint32_t TimeDateStamp; + uint16_t MajorVersion; + uint16_t MinorVersion; + uint32_t Name; + uint32_t Base; + uint32_t NumberOfFunctions; + uint32_t NumberOfNames; + uint32_t AddressOfFunctions; // RVA from base of image + uint32_t AddressOfNames; // RVA from base of image + uint32_t AddressOfNameOrdinals; // RVA from base of image + } IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY; + + typedef struct _IMAGE_DOS_HEADER { + WORD e_magic; + WORD e_cblp; + WORD e_cp; + WORD e_crlc; + WORD e_cparhdr; + WORD e_minalloc; + WORD e_maxalloc; + WORD e_ss; + WORD e_sp; + WORD e_csum; + WORD e_ip; + WORD e_cs; + WORD e_lfarlc; + WORD e_ovno; + WORD e_res[ 4 ]; + WORD e_oemid; + WORD e_oeminfo; + WORD e_res2[ 10 ]; + long e_lfanew; + } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; + + typedef struct _LIST_ENTRY { + struct _LIST_ENTRY *Flink; + struct _LIST_ENTRY *Blink; + } LIST_ENTRY, *PLIST_ENTRY; + + struct PEB_LDR_DATA { + uint32_t Length; + uint8_t Initialized; + uintptr_t SsHandle; + LIST_ENTRY InLoadOrderModuleList; + LIST_ENTRY InMemoryOrderModuleList; + LIST_ENTRY InInitializationOrderModuleList; + uintptr_t EntryInProgress; + uint8_t ShutdownInProgress; + uintptr_t ShutdownThreadId; + }; + + struct UNICODE_STRING { + uint16_t Length; + uint16_t MaximumLength; + wchar_t *Buffer; + }; + + struct STRING { + uint16_t Length; + uint16_t MaximumLength; + char *Buffer; + }; + + struct CURDIR { + UNICODE_STRING DosPath; + uintptr_t Handle; + }; + + struct RTL_DRIVE_LETTER_CURDIR { + uint16_t Flags; + uint16_t Length; + uint32_t TimeStamp; + STRING DosPath; + }; + + struct RTL_USER_PROCESS_PARAMETERS { + uint32_t MaximumLength; + uint32_t Length; + uint32_t Flags; + uint32_t DebugFlags; + uintptr_t ConsoleHandle; + uint32_t ConsoleFlags; + uintptr_t StandardInput; + uintptr_t StandardOutput; + uintptr_t StandardError; + CURDIR CurrentDirectory; + UNICODE_STRING DllPath; + UNICODE_STRING ImagePathName; + UNICODE_STRING CommandLine; + uintptr_t Environment; + uint32_t StartingX; + uint32_t StartingY; + uint32_t CountX; + uint32_t CountY; + uint32_t CountCharsX; + uint32_t CountCharsY; + uint32_t FillAttribute; + uint32_t WindowFlags; + uint32_t ShowWindowFlags; + UNICODE_STRING WindowTitle; + UNICODE_STRING DesktopInfo; + UNICODE_STRING ShellInfo; + UNICODE_STRING RuntimeData; + RTL_DRIVE_LETTER_CURDIR CurrentDirectores[ 32 ]; + uintptr_t EnvironmentSize; + uintptr_t EnvironmentVersion; + uintptr_t PackageDependencyData; + uint32_t ProcessGroupId; + uint32_t LoaderThreads; + }; + + struct RTL_BALANCED_NODE { + RTL_BALANCED_NODE *Children[ 2 ]; + RTL_BALANCED_NODE *Left; + RTL_BALANCED_NODE *Right; + uintptr_t ParentValue; + }; + + struct _PEB { + uint8_t InheritedAddressSpace; + uint8_t ReadImageFileExecOptions; + uint8_t BeingDebugged; + uint8_t BitField; + //uchar Padding0[ 4 ]; + uintptr_t Mutant; + uintptr_t ImageBaseAddress; + PEB_LDR_DATA *Ldr; + RTL_USER_PROCESS_PARAMETERS *ProcessParameters; + uintptr_t SubSystemData; + uintptr_t ProcessHeap; + uintptr_t *FastPebLock; + uintptr_t AtlThunkSListPtr; + uintptr_t IFEOKey; + uint32_t CrossProcessFlags; + uint8_t Padding1[ 4 ]; + uintptr_t KernelCallbackTable; + uintptr_t UserSharedInfoPtr; + uint32_t SystemReserved[ 1 ]; + uint32_t AtlThunkSListPtr32; + uintptr_t ApiSetMap; + uint32_t TlsExpansionCounter; + uint8_t Padding2[ 4 ]; + uintptr_t TlsBitmap; + uint32_t TlsBitmapBits[ 2 ]; + uintptr_t ReadOnlySharedMemoryBase; + uintptr_t SparePvoid0; + uintptr_t ReadOnlyStaticServerData; + uintptr_t AnsiCodePageData; + uintptr_t OemCodePageData; + uintptr_t UnicodeCaseTableData; + uint32_t NumberOfProcessors; + uint32_t NtGlobalFlag; + uint64_t CriticalSectionTimeout; + uintptr_t HeapSegmentReserve; + uintptr_t HeapSegmentCommit; + uintptr_t HeapDeCommitTotalFreeThreshold; + uintptr_t HeapDeCommitFreeBlockThreshold; + uint32_t NumberOfHeaps; + uint32_t MaximumNumberOfHeaps; + uintptr_t ProcessHeaps; + uintptr_t GdiSharedHandleTable; + uintptr_t ProcessStarterHelper; + uint32_t GdiDCAttributeList; + uint8_t Padding3[ 4 ]; + uintptr_t *LoaderLock; + uint32_t OSMajorVersion; + uint32_t OSMinorVersion; + uint16_t OSBuildNumber; + uint16_t OSCSDVersion; + uint32_t OSPlatformId; + uint32_t ImageSubsystem; + uint32_t ImageSubsystemMajorVersion; + uint32_t ImageSubsystemMinorVersion; + uint8_t Padding4[ 4 ]; + uintptr_t ActiveProcessAffinityMask; +#ifdef _WIN32 + uint32_t GdiHandleBuffer[ 34 ]; +#else + uint32_t GdiHandleBuffer[ 60 ]; +#endif + uintptr_t PostProcessInitRoutine; + uintptr_t TlsExpansionBitmap; + uint32_t TlsExpansionBitmapBits[ 32 ]; + uint32_t SessionId; + uint8_t Padding5[ 4 ]; + uint64_t AppCompatFlags; + uint64_t AppCompatFlagsUser; + uintptr_t pShimData; + uintptr_t AppCompatInfo; + UNICODE_STRING CSDVersion; + uintptr_t ActivationContextData; + uintptr_t ProcessAssemblyStorageMap; + uintptr_t SystemDefaultActivationContextData; + uintptr_t SystemAssemblyStorageMap; + uintptr_t MinimumStackCommit; + uintptr_t FlsCallback; + LIST_ENTRY FlsListHead; + uintptr_t FlsBitmap; + uint32_t FlsBitmapBits[ 4 ]; + uint32_t FlsHighIndex; + uintptr_t WerRegistrationData; + uintptr_t WerShipAssertPtr; + uintptr_t pUnused; + uintptr_t pImageHeaderHash; + uint32_t TracingFlags; + uint8_t Padding6[ 4 ]; + uint64_t CsrServerReadOnlySharedMemoryBase; + uintptr_t TppWorkerpListLock; + LIST_ENTRY TppWorkerpList; + uintptr_t WaitOnAddressHashTable[ 128 ]; + }; + + struct LDR_DATA_TABLE_ENTRY { + LIST_ENTRY InLoadOrderLinks; + LIST_ENTRY InMemoryOrderLinks; + LIST_ENTRY InInitializationOrderLinks; + uintptr_t DllBase; + uintptr_t EntryPoint; + uint32_t SizeOfImage; + UNICODE_STRING FullDllName; + UNICODE_STRING BaseDllName; + uint8_t FlagGroup[ 4 ]; + uint32_t Flags; + uint16_t ObsoleteLoadCount; + uint16_t TlsIndex; + LIST_ENTRY HashLinks; + uint32_t TimeDateStamp; + uintptr_t EntryPointActivationContext; + uintptr_t Lock; + uintptr_t DdagNode; + LIST_ENTRY NodeModuleLink; + uintptr_t LoadContext; + uintptr_t ParentDllBase; + uintptr_t SwitchBackContext; + RTL_BALANCED_NODE BaseAddressIndexNode; + RTL_BALANCED_NODE MappingInfoIndexNode; + uintptr_t OriginalBase; + int64_t LoadTime; + uint32_t BaseNameHashValue; + uint32_t LoadReason; + uint32_t ImplicitPathOptions; + uint32_t ReferenceCount; + }; +}; \ No newline at end of file diff --git a/legacy/injector/util.h b/legacy/injector/util.h new file mode 100644 index 0000000..61b18dc --- /dev/null +++ b/legacy/injector/util.h @@ -0,0 +1,44 @@ +#pragma once +#include + +namespace util +{ + __forceinline void memcpy( void* dst, void* src, size_t size ) { + uint8_t* data = ( uint8_t* )src; + uint8_t* dest = ( uint8_t* )dst; + + for( size_t i{ }; i < size; ++i ) { + dest[ i ] = data[ i ]; + } + } + + __forceinline size_t strlen( const char* str ) { + size_t len; + for( len = 0; !!str[ len ]; ++len ); + + return len; + } + + __forceinline bool strcmp( const char* str, const char* comp ) { + for( size_t i{ }; i < strlen( comp ); ++i ) { + if( str[ i ] != comp[ i ] ) return false; + } + + return true; + } + + __forceinline size_t wstrlen( const wchar_t* str ) { + size_t len; + for( len = 0; !!str[ len ]; ++len ); + + return len; + } + + __forceinline bool wstrcmp( const wchar_t* str, const wchar_t* comp ) { + for( size_t i{ }; i < wstrlen( comp ); ++i ) { + if( str[ i ] != comp[ i ] ) return false; + } + + return true; + } +} \ No newline at end of file diff --git a/legacy/injector/winapi.h b/legacy/injector/winapi.h new file mode 100644 index 0000000..6fceeb7 --- /dev/null +++ b/legacy/injector/winapi.h @@ -0,0 +1,81 @@ +#pragma once +#include + +#include "pe.h" +#include "util.h" + +namespace winapi +{ + auto get_peb( ) { + return ( nt::_PEB* )( __readfsdword( 0x30 ) ); + } + + namespace k32 { + __declspec( noinline ) static void* get_module_handle( const wchar_t* module_ ) { + auto peb = get_peb( ); + auto ldr = peb->Ldr; + + auto root = &ldr->InMemoryOrderModuleList; + + for( auto mod = root->Flink; mod != root; mod = mod->Flink ) { + nt::LDR_DATA_TABLE_ENTRY* data_table; + void* module_base; + wchar_t* module_name; + + data_table = reinterpret_cast< decltype( data_table ) >( mod ); + module_base = reinterpret_cast< void* >( ( ( void** )( uintptr_t( data_table ) + 0x10 ) )[ 0 ] ); + + module_name = ( wchar_t* )_alloca( ( data_table->FullDllName.Length + 1 ) * 2 ); + util::memcpy( module_name, data_table->FullDllName.Buffer, data_table->FullDllName.Length * 2 ); + module_name[ data_table->FullDllName.Length ] = L'0'; + + if( util::wstrcmp( module_name, module_ ) ) { + return module_base; + } + } + + return false; + } + + __declspec( noinline ) uintptr_t get_proc_address( void* module_, const char* proc_name ) { + nt::IMAGE_DOS_HEADER* dos_header; + nt::IMAGE_NT_HEADERS* nt_headers; + uintptr_t export_address; + nt::IMAGE_EXPORT_DIRECTORY* export_dir; + const char* export_name; + uintptr_t* names; + uintptr_t* funcs; + uint16_t* ords; + uint32_t export_hash; + + dos_header = reinterpret_cast< decltype( dos_header ) >( uintptr_t( module_ ) ); + nt_headers = reinterpret_cast< decltype( nt_headers ) >( uintptr_t( module_ ) + dos_header->e_lfanew ); + + //find addresses of functions from nt headers + export_address = nt_headers->OptionalHeader.DataDirectory[ 0 ].VirtualAddress; + export_dir = reinterpret_cast< decltype( export_dir ) >( uintptr_t( module_ ) + export_address ); + + if( !export_dir->NumberOfFunctions ) + return uintptr_t{ }; + + names = reinterpret_cast< uintptr_t* >( uintptr_t( module_ ) + export_dir->AddressOfNames ); + funcs = reinterpret_cast< uintptr_t* >( uintptr_t( module_ ) + export_dir->AddressOfFunctions ); + + ords = reinterpret_cast< uint16_t* >( uintptr_t( module_ ) + export_dir->AddressOfNameOrdinals ); + + if( names && funcs && ords ) { + //iterate the exports + for( size_t i{ }; i < export_dir->NumberOfNames; ++i ) { + export_name = reinterpret_cast< const char* >( uintptr_t( module_ ) + names[ i ] ); + if( util::strcmp( export_name, proc_name ) ) { + return uintptr_t( module_ ) + funcs[ ords[ i ] ]; + } + } + } + + while( 1 ) { } + + return uintptr_t{ }; + } + } +} \ No newline at end of file -- cgit v1.2.3