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/enc_file/enc_file.vcxproj | 179 +++++++++++ legacy/enc_file/enc_file.vcxproj.filters | 22 ++ legacy/enc_file/source.cpp | 40 +++ 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 +++++ legacy/legacy.sln | 65 ++++ legacy/loader/Source.cpp | 190 +++++++++++ legacy/loader/color.hpp | 287 +++++++++++++++++ legacy/loader/console.h | 69 ++++ legacy/loader/d3d.cpp | 335 ++++++++++++++++++++ legacy/loader/d3d.hpp | 126 ++++++++ legacy/loader/d3d_sprite.cpp | 13 + legacy/loader/d3d_sprite.hpp | 107 +++++++ legacy/loader/http.h | 70 +++++ legacy/loader/iface.hpp | 198 ++++++++++++ legacy/loader/input_system.cpp | 523 +++++++++++++++++++++++++++++++ legacy/loader/input_system.hpp | 177 +++++++++++ legacy/loader/loader.vcxproj | 245 +++++++++++++++ legacy/loader/loader.vcxproj.filters | 147 +++++++++ legacy/loader/manualmap.cpp | 109 +++++++ legacy/loader/manualmap.hpp | 169 ++++++++++ legacy/loader/math.hpp | 60 ++++ legacy/loader/strings.hpp | 163 ++++++++++ legacy/loader/syscall.h | 167 ++++++++++ legacy/loader/ui.h | 123 ++++++++ legacy/loader/ui_base_item.h | 164 ++++++++++ legacy/loader/ui_button.h | 56 ++++ legacy/loader/ui_checkbox.h | 68 ++++ legacy/loader/ui_color_picker.h | 201 ++++++++++++ legacy/loader/ui_draw.h | 160 ++++++++++ legacy/loader/ui_dropdown.h | 217 +++++++++++++ legacy/loader/ui_dropdown_item.h | 22 ++ legacy/loader/ui_form.h | 130 ++++++++ legacy/loader/ui_key_picker.h | 164 ++++++++++ legacy/loader/ui_label.h | 18 ++ legacy/loader/ui_menu.h | 104 ++++++ legacy/loader/ui_progressbar.h | 44 +++ legacy/loader/ui_render.h | 57 ++++ legacy/loader/ui_slider.h | 165 ++++++++++ legacy/loader/ui_tab_manager.h | 224 +++++++++++++ legacy/loader/ui_text_input.cpp | 86 +++++ legacy/loader/ui_text_input.h | 38 +++ legacy/loader/util.hpp | 101 ++++++ legacy/loader/winapi.hpp | 64 ++++ legacy/loader/window.cpp | 148 +++++++++ legacy/loader/window.hpp | 59 ++++ legacy/loader/x86.h | 47 +++ 51 files changed, 6693 insertions(+) create mode 100644 legacy/enc_file/enc_file.vcxproj create mode 100644 legacy/enc_file/enc_file.vcxproj.filters create mode 100644 legacy/enc_file/source.cpp 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 create mode 100644 legacy/legacy.sln create mode 100644 legacy/loader/Source.cpp create mode 100644 legacy/loader/color.hpp create mode 100644 legacy/loader/console.h create mode 100644 legacy/loader/d3d.cpp create mode 100644 legacy/loader/d3d.hpp create mode 100644 legacy/loader/d3d_sprite.cpp create mode 100644 legacy/loader/d3d_sprite.hpp create mode 100644 legacy/loader/http.h create mode 100644 legacy/loader/iface.hpp create mode 100644 legacy/loader/input_system.cpp create mode 100644 legacy/loader/input_system.hpp create mode 100644 legacy/loader/loader.vcxproj create mode 100644 legacy/loader/loader.vcxproj.filters create mode 100644 legacy/loader/manualmap.cpp create mode 100644 legacy/loader/manualmap.hpp create mode 100644 legacy/loader/math.hpp create mode 100644 legacy/loader/strings.hpp create mode 100644 legacy/loader/syscall.h create mode 100644 legacy/loader/ui.h create mode 100644 legacy/loader/ui_base_item.h create mode 100644 legacy/loader/ui_button.h create mode 100644 legacy/loader/ui_checkbox.h create mode 100644 legacy/loader/ui_color_picker.h create mode 100644 legacy/loader/ui_draw.h create mode 100644 legacy/loader/ui_dropdown.h create mode 100644 legacy/loader/ui_dropdown_item.h create mode 100644 legacy/loader/ui_form.h create mode 100644 legacy/loader/ui_key_picker.h create mode 100644 legacy/loader/ui_label.h create mode 100644 legacy/loader/ui_menu.h create mode 100644 legacy/loader/ui_progressbar.h create mode 100644 legacy/loader/ui_render.h create mode 100644 legacy/loader/ui_slider.h create mode 100644 legacy/loader/ui_tab_manager.h create mode 100644 legacy/loader/ui_text_input.cpp create mode 100644 legacy/loader/ui_text_input.h create mode 100644 legacy/loader/util.hpp create mode 100644 legacy/loader/winapi.hpp create mode 100644 legacy/loader/window.cpp create mode 100644 legacy/loader/window.hpp create mode 100644 legacy/loader/x86.h (limited to 'legacy') diff --git a/legacy/enc_file/enc_file.vcxproj b/legacy/enc_file/enc_file.vcxproj new file mode 100644 index 0000000..0df84b6 --- /dev/null +++ b/legacy/enc_file/enc_file.vcxproj @@ -0,0 +1,179 @@ + + + + + Debug + Win32 + + + pHit + Win32 + + + pHit + x64 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {9EF8BCE2-B57C-413C-803B-0FAB5A0747D8} + encfile + 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/enc_file/enc_file.vcxproj.filters b/legacy/enc_file/enc_file.vcxproj.filters new file mode 100644 index 0000000..9fa84c5 --- /dev/null +++ b/legacy/enc_file/enc_file.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {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 + + + \ No newline at end of file diff --git a/legacy/enc_file/source.cpp b/legacy/enc_file/source.cpp new file mode 100644 index 0000000..9056764 --- /dev/null +++ b/legacy/enc_file/source.cpp @@ -0,0 +1,40 @@ +#include +#include + +int main( ) { + uint8_t key{ }; + std::cin >> key; + printf( "key: %d", key ); + + auto file = CreateFileA( "./enc.dll", GENERIC_READ, 0, 0, OPEN_ALWAYS, 0, 0 ); + if( !file ) return 0; + + auto size = GetFileSize( file, 0 ); + if( !size ) { + CloseHandle( file ); + return 0; + } + + uint8_t* data = ( uint8_t* )( malloc( size ) ); + if( !ReadFile( file, data, size, 0, 0 ) ) { + CloseHandle( file ); + free( data ); + return 0; + } + + CloseHandle( file ); + + for( size_t i{ }; i < size; ++i ) { + data[ i ] ^= key; + } + + data[ 0 ] = 'c'; + data[ 1 ] = 'd'; + + FILE* f; + fopen_s( &f, "./out.dll", "wb" ); + fwrite( data, 1, size, f ); + fclose( f ); + + return 0; +} \ No newline at end of file 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 diff --git a/legacy/legacy.sln b/legacy/legacy.sln new file mode 100644 index 0000000..60d7aa5 --- /dev/null +++ b/legacy/legacy.sln @@ -0,0 +1,65 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28307.106 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "enc_file", "enc_file\enc_file.vcxproj", "{9EF8BCE2-B57C-413C-803B-0FAB5A0747D8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "injector", "injector\injector.vcxproj", "{0CD36550-BDEB-4967-9AC1-9AB1AE778C64}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "loader", "loader\loader.vcxproj", "{C376FC6E-5E1C-4ADD-A921-BC8E2968E8B0}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + pHit|x64 = pHit|x64 + pHit|x86 = pHit|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9EF8BCE2-B57C-413C-803B-0FAB5A0747D8}.Debug|x64.ActiveCfg = Debug|x64 + {9EF8BCE2-B57C-413C-803B-0FAB5A0747D8}.Debug|x64.Build.0 = Debug|x64 + {9EF8BCE2-B57C-413C-803B-0FAB5A0747D8}.Debug|x86.ActiveCfg = Debug|Win32 + {9EF8BCE2-B57C-413C-803B-0FAB5A0747D8}.Debug|x86.Build.0 = Debug|Win32 + {9EF8BCE2-B57C-413C-803B-0FAB5A0747D8}.pHit|x64.ActiveCfg = pHit|x64 + {9EF8BCE2-B57C-413C-803B-0FAB5A0747D8}.pHit|x64.Build.0 = pHit|x64 + {9EF8BCE2-B57C-413C-803B-0FAB5A0747D8}.pHit|x86.ActiveCfg = pHit|Win32 + {9EF8BCE2-B57C-413C-803B-0FAB5A0747D8}.pHit|x86.Build.0 = pHit|Win32 + {9EF8BCE2-B57C-413C-803B-0FAB5A0747D8}.Release|x64.ActiveCfg = Release|x64 + {9EF8BCE2-B57C-413C-803B-0FAB5A0747D8}.Release|x64.Build.0 = Release|x64 + {9EF8BCE2-B57C-413C-803B-0FAB5A0747D8}.Release|x86.ActiveCfg = Release|Win32 + {9EF8BCE2-B57C-413C-803B-0FAB5A0747D8}.Release|x86.Build.0 = Release|Win32 + {0CD36550-BDEB-4967-9AC1-9AB1AE778C64}.Debug|x64.ActiveCfg = Debug|x64 + {0CD36550-BDEB-4967-9AC1-9AB1AE778C64}.Debug|x64.Build.0 = Debug|x64 + {0CD36550-BDEB-4967-9AC1-9AB1AE778C64}.Debug|x86.ActiveCfg = Debug|Win32 + {0CD36550-BDEB-4967-9AC1-9AB1AE778C64}.Debug|x86.Build.0 = Debug|Win32 + {0CD36550-BDEB-4967-9AC1-9AB1AE778C64}.pHit|x64.ActiveCfg = pHit|x64 + {0CD36550-BDEB-4967-9AC1-9AB1AE778C64}.pHit|x64.Build.0 = pHit|x64 + {0CD36550-BDEB-4967-9AC1-9AB1AE778C64}.pHit|x86.ActiveCfg = pHit|Win32 + {0CD36550-BDEB-4967-9AC1-9AB1AE778C64}.pHit|x86.Build.0 = pHit|Win32 + {0CD36550-BDEB-4967-9AC1-9AB1AE778C64}.Release|x64.ActiveCfg = Release|x64 + {0CD36550-BDEB-4967-9AC1-9AB1AE778C64}.Release|x64.Build.0 = Release|x64 + {0CD36550-BDEB-4967-9AC1-9AB1AE778C64}.Release|x86.ActiveCfg = Release|Win32 + {0CD36550-BDEB-4967-9AC1-9AB1AE778C64}.Release|x86.Build.0 = Release|Win32 + {C376FC6E-5E1C-4ADD-A921-BC8E2968E8B0}.Debug|x64.ActiveCfg = Debug|x64 + {C376FC6E-5E1C-4ADD-A921-BC8E2968E8B0}.Debug|x64.Build.0 = Debug|x64 + {C376FC6E-5E1C-4ADD-A921-BC8E2968E8B0}.Debug|x86.ActiveCfg = Debug|Win32 + {C376FC6E-5E1C-4ADD-A921-BC8E2968E8B0}.Debug|x86.Build.0 = Debug|Win32 + {C376FC6E-5E1C-4ADD-A921-BC8E2968E8B0}.pHit|x64.ActiveCfg = pHit|x64 + {C376FC6E-5E1C-4ADD-A921-BC8E2968E8B0}.pHit|x64.Build.0 = pHit|x64 + {C376FC6E-5E1C-4ADD-A921-BC8E2968E8B0}.pHit|x86.ActiveCfg = pHit|Win32 + {C376FC6E-5E1C-4ADD-A921-BC8E2968E8B0}.pHit|x86.Build.0 = pHit|Win32 + {C376FC6E-5E1C-4ADD-A921-BC8E2968E8B0}.Release|x64.ActiveCfg = Release|x64 + {C376FC6E-5E1C-4ADD-A921-BC8E2968E8B0}.Release|x64.Build.0 = Release|x64 + {C376FC6E-5E1C-4ADD-A921-BC8E2968E8B0}.Release|x86.ActiveCfg = Release|Win32 + {C376FC6E-5E1C-4ADD-A921-BC8E2968E8B0}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {85DF5E86-C3F3-431C-BFC6-95E3F13530E5} + EndGlobalSection +EndGlobal diff --git a/legacy/loader/Source.cpp b/legacy/loader/Source.cpp new file mode 100644 index 0000000..8d72c2b --- /dev/null +++ b/legacy/loader/Source.cpp @@ -0,0 +1,190 @@ +#include +#include +#include "d3d_sprite.hpp" +#include "window.hpp" +#include "ui.h" + +#include "http.h" + +#include "manualmap.hpp" +#include "iface.hpp" + +bool g_in_inject = false; + +void on_frame( ) { + if( g_d3d.run_frame( g_window.m_d3d_device ) ) { + g_d3d.begin( ); + for( auto& it : d3d::sprites ) { + it->begin( g_window.m_d3d_device ); + } + + static auto last_time = GetTickCount( ) * 0.001f; + auto cur_time = GetTickCount( ) * 0.001f; + + auto deltatime = cur_time - last_time; + + last_time = cur_time; + + constexpr float anim_step = 1.0f / 15.f; + static float anim_time = 0.f; + static bool flip = false; + if( anim_time == 1.0f ) { + flip = true; + } + if( anim_time == 0.f ) { + flip = false; + } + + if( flip ) anim_time = std::clamp( anim_time - anim_step * deltatime, 0.f, 1.0f ); + else anim_time = std::clamp( anim_time + anim_step * deltatime, 0.f, 1.0f ); + + ui::set_animtime( anim_time ); + ui::render( ); + + RECT cur_rect{ }; + GetWindowRect( g_window.get_hwnd( ), &cur_rect ); + + g_d3d.end( ); + for( auto& it : d3d::sprites ) { + it->end( ); + } + } +} + +void decrypt_file( std::vector< uint8_t >& file, uint8_t key ) { + for( size_t i{ }; i < file.size( ); ++i ) { + file.data( )[ i ] ^= key; + } +} + +int find_process( std::string name ) { + auto window = FindWindowA( 0, name.c_str( ) ); + if( !window ) return -1; + + ulong_t pid{ }; + GetWindowThreadProcessId( window, &pid ); + + return pid; +} + +void thread_fn( ) { + if( g_in_inject ) return; + + g_in_inject = true; + ulong_t hwid{ }; + GetVolumeInformationA( xors( "C:\\" ), 0, 0, &hwid, 0, 0, 0, 0 ); + + g_progress = 0.1f; + + std::string game{ }; + switch( g_game ) { + case 1: + game = xors( "Counter-Strike: Global Offensive" ); + break; + case 2: + game = xors( "Team Fortress 2" ); + break; + case 3: + game = xors( "Counter-Strike: Global Offensive" ); + break; + case 4: + game = xors( "Garry's Mod" ); + break; + default: + MessageBoxA( 0, xors( "unknown error" ), xors( "error" ), MB_OK ); + exit( 0 ); + break; + } + + auto pid = find_process( game ); + if( pid == -1 ) { + MessageBoxA( 0, xors( "game must be running" ), xors( "error" ), MB_OK ); + g_progress = 0.f; + g_in_inject = false; + return; + } + + auto h = OpenProcess( PROCESS_ALL_ACCESS, 0, pid ); + iface::manager mgr( h ); + + mgr.dump_all_modules( pid ); + if( !mgr.count( ) ) { + MessageBoxA( 0, xors( "unknown error" ), xors( "error" ), MB_OK ); + exit( 0 ); + } + + g_progress = 0.3f; + + //enter a new scope to run cleanup after we're done, epic life hack + { + auto result = http::send_request( g_login, hwid, g_game ); + + if( result.empty( ) ) { + MessageBoxA( 0, xors( "unknown error" ), xors( "error" ), MB_OK ); + exit( 0 ); + return; + } + + if( result[ 0 ] == '1' ) { + char str[ 256 ]; + strenc::w_sprintf_s( str, 256, xors( "hwid mismatch, request change: %08x" ), hwid ); + MessageBoxA( 0, str, xors( "error" ), MB_OK ); + exit( 0 ); + } + if( result[ 0 ] == '2' ) { + MessageBoxA( 0, xors( "user unknown" ), xors( "error" ), MB_OK ); + exit( 0 ); + } + if( result[ 0 ] == '3' ) { + MessageBoxA( 0, xors( "coming soon" ), xors( "error" ), MB_OK ); + g_progress = 0.f; + g_in_inject = false; + return; + } + + g_progress = 0.5f; + + //to meme whoever decides to reverse this + decrypt_file( result, [ ]( ) { + constexpr auto key_sqr = 49 * 49; + return 49; + }( ) ); + + inject::c_map map( result ); + g_progress = 0.7f; + + map.initialize( pid ); + std::this_thread::sleep_for( std::chrono::milliseconds( 300 ) ); + g_progress = 0.8f; + map.inject( mgr.write_to_process( ) ); + g_progress = 1.0f; + } + + MessageBoxA( 0, xors( "injection successful" ), xors( "success" ), MB_OK ); + exit( 0 ); + g_in_inject = false; +} + +void execute_login( ) { + std::thread t( thread_fn ); + + t.detach( ); +} + +int __stdcall WinMain( HINSTANCE inst, HINSTANCE prev, char* str, int cmdshow ) { + std::thread window_thread( [ & ]( ) { + g_window.create( ); + std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); + g_window.add_on_frame( &on_frame ); + for( ;; ) { + g_window.on_frame( ); + + std::this_thread::sleep_for( std::chrono::milliseconds( 1 ) ); + exit( -1 ); + } + } ); + + window_thread.detach( ); + + while( 1 ) { if( GetAsyncKeyState( VK_END ) & 0x8000 ) break; Sleep( 1 ); } +} \ No newline at end of file diff --git a/legacy/loader/color.hpp b/legacy/loader/color.hpp new file mode 100644 index 0000000..f28d35c --- /dev/null +++ b/legacy/loader/color.hpp @@ -0,0 +1,287 @@ +#pragma once + +#include +#include + +//this is a fucking mess + +class fclr_t { + float R, G, B, A; +public: + fclr_t( ) : R( 0 ), G( 0 ), B( 0 ), A( 0 ) { } + + fclr_t( float r, float g, float b, float a ) : R( r ), G( g ), B( b ), A( a ) { } + + fclr_t( float r, float g, float b ) : R( r ), G( g ), B( b ), A( 255 ) { } + + float& r( ) { return R; } + float& g( ) { return G; } + float& b( ) { return B; } + float& a( ) { return A; } + + fclr_t& operator =( fclr_t& c ) { + R = c.r( ); + G = c.g( ); + B = c.b( ); + A = c.a( ); + return *this; + } + + fclr_t operator+( const fclr_t& v ) const { + return fclr_t( R + v.R, G + v.G, B + v.B, A + v.A ); + } + + explicit operator bool( ) const noexcept { + return ( R > 0 || G > 0 || B > 0 || A > 0 ); + } + + bool operator==( fclr_t& c ) const { + return ( R == c.r( ) && G == c.g( ) && B == c.b( ) ); + } +}; + +class clr_t { + uint8_t R, G, B, A; +public: + clr_t( ) : R( 0 ), G( 0 ), B( 0 ), A( 0 ) { } + + clr_t( uint8_t r, uint8_t g, uint8_t b, uint8_t a ) : R( r ), G( g ), B( b ), A( a ) { } + + clr_t( uint8_t r, uint8_t g, uint8_t b ) : R( r ), G( g ), B( b ), A( 255 ) { } + + uint8_t& r( ) { return R; } + uint8_t& g( ) { return G; } + uint8_t& b( ) { return B; } + uint8_t& a( ) { return A; } + + clr_t& operator=( clr_t& c ) { + R = c.r( ); + G = c.g( ); + B = c.b( ); + A = c.a( ); + return *this; + } + + clr_t& operator=( clr_t c ) { + R = c.r( ); + G = c.g( ); + B = c.b( ); + A = c.a( ); + return *this; + } + + clr_t operator+( const clr_t& v ) const { + return clr_t( R + v.R, G + v.G, B + v.B, A + v.A ); + } + + clr_t operator*( float f ) { + return clr_t( uint8_t( R * f ), uint8_t( G * f ), uint8_t( B * f ), A ); + } + + explicit operator bool( ) const noexcept { + return ( R > 0 || G > 0 || B > 0 || A > 0 ); + } + + float brightness( ) { + typedef struct { + float h, s, v; + } hsv; + hsv out; + + float min = static_cast( R < G ? R : G ); + min = static_cast( min < B ? min : B ); + + float max = static_cast( R > G ? R : G ); + max = static_cast( max > B ? max : B ); + + out.v = max; + float delta = max - min; + if( delta < 0.0010f ) { + out.s = 0.f; + out.h = 0.f; + return out.h; + } + if( max > 0.0f ) { + out.s = delta / max; + } + else { + out.s = 0.0f; + out.h = NAN; + return out.h; + } + if( R >= max ) + out.h = static_cast( G - B ) / delta; + else if( G >= max ) + out.h = 2.0f + static_cast( B - R ) / delta; + else + out.h = 4.0f + static_cast( R - G ) / delta; + + out.h *= 60.0f; + out.h /= 360.f; + + if( out.h < 0.0f ) + out.h += 360.0f; + + return out.v; + } + + float saturation( ) { + typedef struct { + float h, s, v; + } hsv; + hsv out; + + float min = static_cast( R < G ? R : G ); + min = static_cast( min < B ? min : B ); + + float max = static_cast( R > G ? R : G ); + max = static_cast( max > B ? max : B ); + + out.v = max; + float delta = max - min; + if( delta < 0.0010f ) { + out.s = 0.f; + out.h = 0.f; + return out.h; + } + if( max > 0.0f ) { + out.s = delta / max; + } + else { + out.s = 0.0f; + out.h = NAN; + return out.h; + } + if( R >= max ) + out.h = static_cast( G - B ) / delta; + else if( G >= max ) + out.h = 2.0f + static_cast( B - R ) / delta; + else + out.h = 4.0f + static_cast( R - G ) / delta; + + out.h *= 60.0f; + out.h /= 360.f; + + if( out.h < 0.0f ) + out.h += 360.0f; + + return out.s; + } + + static clr_t from_hsb( float hue, float saturation, float brightness ) { + float h = hue == 1.0f ? 0 : hue * 6.0f; + float f = h - ( int )h; + float p = brightness * ( 1.0f - saturation ); + float q = brightness * ( 1.0f - saturation * f ); + float t = brightness * ( 1.0f - ( saturation * ( 1.0f - f ) ) ); + + if( h < 1 ) { + return clr_t( + ( unsigned char )( brightness * 255 ), + ( unsigned char )( t * 255 ), + ( unsigned char )( p * 255 ) + ); + } + else if( h < 2 ) { + return clr_t( + ( unsigned char )( q * 255 ), + ( unsigned char )( brightness * 255 ), + ( unsigned char )( p * 255 ) + ); + } + else if( h < 3 ) { + return clr_t( + ( unsigned char )( p * 255 ), + ( unsigned char )( brightness * 255 ), + ( unsigned char )( t * 255 ) + ); + } + else if( h < 4 ) { + return clr_t( + ( unsigned char )( p * 255 ), + ( unsigned char )( q * 255 ), + ( unsigned char )( brightness * 255 ) + ); + } + else if( h < 5 ) { + return clr_t( + ( unsigned char )( t * 255 ), + ( unsigned char )( p * 255 ), + ( unsigned char )( brightness * 255 ) + ); + } + else { + return clr_t( + ( unsigned char )( brightness * 255 ), + ( unsigned char )( p * 255 ), + ( unsigned char )( q * 255 ) + ); + } + } + + static clr_t blend( clr_t first, clr_t second, float t ) { + return clr_t( + first.r( ) + static_cast< int >( t * ( second.r( ) - first.r( ) ) ), + first.g( ) + static_cast< int >( t * ( second.g( ) - first.g( ) ) ), + first.b( ) + static_cast< int >( t * ( second.b( ) - first.b( ) ) ), + first.a( ) + static_cast< int >( t * ( second.a( ) - first.a( ) ) ) + ); + } + + float hue( ) { + typedef struct { + float h, s, v; + } hsv; + hsv out; + float min, max, delta; + + min = static_cast< float >( R < G ? R : G ); + min = static_cast< float >( min < B ? min : B ); + + max = static_cast< float >( R > G ? R : G ); + max = static_cast< float >( max > B ? max : B ); + + out.v = max; + delta = max - min; + if( delta < 0.0010f ) { + out.s = 0.f; + out.h = 0.f; + return out.h; + } + if( max > 0.0f ) { + out.s = ( delta / max ); + } + else { + out.s = 0.0f; + out.h = ( float )NAN; + return out.h; + } + if( R >= max ) + out.h = static_cast< float >( G - B ) / delta; + else + if( G >= max ) + out.h = 2.0f + static_cast< float >( B - R ) / delta; + else + out.h = 4.0f + static_cast< float >( R - G ) / delta; + + out.h *= 60.0f; + out.h /= 360.f; + + if( out.h < 0.0f ) + out.h += 360.0f; + + return out.h; + } + + fclr_t to_fclr( ) { + return fclr_t{ R / 255.f, G / 255.f, B / 255.f, A / 255.f }; + } + + operator fclr_t( ) { + return this->to_fclr( ); + } + + bool operator==( clr_t& c ) const { + return ( R == c.r( ) && G == c.g( ) && B == c.b( ) ); + } +}; \ No newline at end of file diff --git a/legacy/loader/console.h b/legacy/loader/console.h new file mode 100644 index 0000000..1494d94 --- /dev/null +++ b/legacy/loader/console.h @@ -0,0 +1,69 @@ +#pragma once +#include + +#define STD_HANDLE GetStdHandle( STD_OUTPUT_HANDLE ) + +namespace con +{ + enum class concol : int { + black = 0, + dark_blue = 1, + dark_green = 2, + dark_aqua, dark_cyan = 3, + dark_red = 4, + dark_purple = 5, dark_pink = 5, dark_magenta = 5, + dark_yellow = 6, + dark_white = 7, + gray = 8, + blue = 9, + green = 10, + aqua = 11, cyan = 11, + red = 12, + purple = 13, pink = 13, magenta = 13, + yellow = 14, + white = 15 + }; + + inline void set_console_cursor( bool cursor ) { + CONSOLE_CURSOR_INFO cursor_info; + cursor_info.bVisible = cursor; + cursor_info.dwSize = 1; + SetConsoleCursorInfo( STD_HANDLE, &cursor_info ); + } + + inline void set_cursor_pos( int x, int y ) { + COORD cursor_pos = { static_cast< short >( x ), static_cast< short >( y ) }; + SetConsoleCursorPosition( STD_HANDLE, cursor_pos ); + } + + inline void set_console_color( concol text, concol bg ) { + SetConsoleTextAttribute( STD_HANDLE, ( ( int )text + ( ( int )bg * 16 ) ) ); + } + + inline void clear_console( ) { + CONSOLE_SCREEN_BUFFER_INFO buf_info; + HANDLE std_out; + DWORD count; + DWORD cell_count; + COORD null_coord{ }; + + std_out = STD_HANDLE; + if ( std_out == INVALID_HANDLE_VALUE ) return; + + if ( !GetConsoleScreenBufferInfo( std_out, &buf_info ) ) return; + cell_count = buf_info.dwSize.X * buf_info.dwSize.Y; + + if ( !FillConsoleOutputCharacter( std_out, ( TCHAR )' ', cell_count, null_coord, &count ) ) return; + if ( !FillConsoleOutputAttribute( std_out, buf_info.wAttributes, cell_count, null_coord, &count ) ) return; + + set_cursor_pos( 0, 0 ); + } + + inline void set_size( int w, int h ) { + auto con = GetConsoleWindow( ); + RECT r; + + GetWindowRect( con, &r ); + MoveWindow( con, r.left, r.top, w, h, 1 ); + } +} \ No newline at end of file diff --git a/legacy/loader/d3d.cpp b/legacy/loader/d3d.cpp new file mode 100644 index 0000000..89005ee --- /dev/null +++ b/legacy/loader/d3d.cpp @@ -0,0 +1,335 @@ +#include "d3d.hpp" +#include "math.hpp" +#include "d3d_sprite.hpp" + +d3d::c_renderer g_d3d; +d3d::d3d_fonts_t d3d::fonts; + + +//theres shit still left to add like drawrect etc but thats really simple +//this is the base and it works so thats ok +//love +// - nave + +// note - dex; probably better idea to batch all calls up into one DrawPrimitive / DrawIndexedPrimitive call each (if you want to have index buffers too) +// DrawPrimitiveUP for each object will slow stuff down eventually +// dont know much about DrawIndexedPrimitive myself but msdn suggests to use strips over anything else + +namespace d3d +{ + void d3d_fonts_t::release( ) { + if( f_12 ) f_12->Release( ); + if( f_14 ) f_14->Release( ); + if( f_16 ) f_16->Release( ); + if( f_18 ) f_18->Release( ); + if( f_menu ) f_menu->Release( ); + if( f_con ) f_con->Release( ); + } + + void d3d_fonts_t::create( IDirect3DDevice9* device ) { + auto create_font = [ & ]( ID3DXFont** font, const char* font_name, bool bold, int size, int weight ) { + //auto wide_str = util::ascii_to_unicode( std::string( font_name ) ); + + auto code = D3DXCreateFontA( device, size, 0, FW_NORMAL, weight, false, DEFAULT_CHARSET, + OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, font_name, font ); + + if( code < 0 ) throw xors( "fuck d3d" ); + }; + + create_font( &f_12, xors( "Verdana" ), false, 12, 0 ); //change this idc + create_font( &f_14, xors( "Verdana" ), false, 14, 0 ); + create_font( &f_16, xors( "Verdana" ), false, 16, 0 ); + create_font( &f_18, xors( "Verdana" ), false, 18, 0 ); + create_font( &f_menu, xors( "Tahoma" ), true, 12, 700 ); + create_font( &f_con, xors( "Courier New" ), false, 12, 400 ); + } + + + c_renderer::c_renderer( IDirect3DDevice9* device ) : m_device( device ) { + create_objects( ); + } + + bool c_renderer::run_frame( IDirect3DDevice9* device ) { + if( !m_device ) { + m_device = device; + create_objects( ); + return false; + } + + return true; + } + + c_renderer::~c_renderer( ) { + invalidate_objects( ); + } + + void c_renderer::on_device_lost( ) { + invalidate_objects( ); + } + + void c_renderer::on_device_reset( ) { + create_objects( ); + } + + void c_renderer::invalidate_objects( ) { + if( m_block ) m_block->Release( ); + fonts.release( ); + } + + void c_renderer::create_objects( ) { + D3DVIEWPORT9 viewport; + + if( !m_device ) return; + + if( m_device->GetViewport( &viewport ) < 0 ) { + return; + } + + if( m_device->CreateStateBlock( D3DSBT_ALL, &m_block ) < 0 ) { + return; + } + + if( !m_block ) { + return; + } + + // get display size. + m_width = viewport.Width; + m_height = viewport.Height; + + fonts.create( m_device ); + } + + void c_renderer::begin( ) { + if( !m_device ) return; + + D3DVIEWPORT9 vp{ 0, 0, m_width, m_height, 0.f, 1.f }; + + m_block->Capture( ); + + m_device->SetViewport( &vp ); + + // set vertex stream declaration. + m_device->SetVertexShader( nullptr ); + m_device->SetPixelShader( nullptr ); + m_device->SetFVF( D3DFVF_XYZRHW | D3DFVF_DIFFUSE ); + + m_block->Capture( ); + + m_device->SetRenderState( D3DRS_LIGHTING, false ); + m_device->SetRenderState( D3DRS_FOGENABLE, false ); + m_device->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE ); + m_device->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID ); + + m_device->SetRenderState( D3DRS_ZENABLE, D3DZB_FALSE ); + m_device->SetRenderState( D3DRS_SCISSORTESTENABLE, true ); + m_device->SetRenderState( D3DRS_ZWRITEENABLE, false ); + m_device->SetRenderState( D3DRS_STENCILENABLE, false ); + + m_device->SetRenderState( D3DRS_MULTISAMPLEANTIALIAS, false ); + m_device->SetRenderState( D3DRS_ANTIALIASEDLINEENABLE, true ); + + m_device->SetRenderState( D3DRS_ALPHABLENDENABLE, true ); + m_device->SetRenderState( D3DRS_ALPHATESTENABLE, true ); + m_device->SetRenderState( D3DRS_SEPARATEALPHABLENDENABLE, true ); + + m_device->SetTexture( 0, nullptr ); + m_device->SetTexture( 1, nullptr ); + m_device->SetTexture( 2, nullptr ); + m_device->SetTexture( 3, nullptr ); + + m_device->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); + m_device->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); + m_device->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); + m_device->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); + m_device->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); + m_device->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); + m_device->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 ); + m_device->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE ); + m_device->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE ); + m_device->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); + + m_device->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA ); + m_device->SetRenderState( D3DRS_SRCBLENDALPHA, D3DBLEND_INVDESTALPHA ); + m_device->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); + m_device->SetRenderState( D3DRS_DESTBLENDALPHA, D3DBLEND_ONE ); + m_device->SetRenderState( D3DRS_BLENDOP, D3DBLENDOP_ADD ); + + m_device->SetRenderState( D3DRS_SRGBWRITEENABLE, false ); + m_device->SetRenderState( D3DRS_COLORWRITEENABLE, 0xffffffff ); + + // todo - dex; if we use textures, need to set those rendering states too + } + + void c_renderer::end( ) { + //m_device->SetTexture( 0, nullptr ); + //m_device->SetTexture( 1, nullptr ); + //m_device->SetTexture( 2, nullptr ); + //m_device->SetTexture( 3, nullptr ); + m_block->Apply( ); + //m_block->Release( ); + } + + void c_renderer::draw_line( clr_t color, int x0, int y0, int x1, int y1 ) { + d3d_vertex_t v[ 2 ] = { + d3d_vertex_t( float( x0 ), float( y0 ), 1.0f, color ), //because fuck you thats why + d3d_vertex_t( float( x1 ), float( y1 ), 1.0f, color ) + }; //edit: do we wanna use z for shit? i mean we could for like menu stuff + //so it renders above other stuff + + m_device->DrawPrimitiveUP( D3DPT_LINELIST, 1, v, VERTEX_SIZE ); + } + + void c_renderer::draw_rect( clr_t color, int x, int y, int w, int h ) { + d3d_vertex_t v[ 5 ] = { + d3d_vertex_t( float( x ), float( y ), 1.0f, color ), + d3d_vertex_t( float( x + w ), float( y ), 1.0f, color ), + d3d_vertex_t( float( x + w ), float( y + h ), 1.0f, color ), + d3d_vertex_t( float( x ), float( y + h ), 1.0f, color ), + d3d_vertex_t( float( x ), float( y ), 1.0f, color ) + }; + + m_device->DrawPrimitiveUP( D3DPT_LINESTRIP, 4, v, VERTEX_SIZE ); + } + + void c_renderer::draw_filled_rect( clr_t color, int x, int y, int w, int h ) { + d3d_vertex_t v[ 6 ] = { + d3d_vertex_t( float( x + w ), float( y ), 1.0f, color ), + d3d_vertex_t( float( x ), float( y + h ), 1.0f, color ), + d3d_vertex_t( float( x + w ), float( y + h ), 1.0f, color ), + d3d_vertex_t( float( x ), float( y ), 1.0f, color ), + d3d_vertex_t( float( x ), float( y + h ), 1.0f, color ), + d3d_vertex_t( float( x + w ), float( y ), 1.0f, color ) + }; + + m_device->DrawPrimitiveUP( D3DPT_TRIANGLELIST, 2, v, VERTEX_SIZE ); + } + + void c_renderer::draw_gradient( clr_t start, clr_t end, int x, int y, int w, int h, GradientType_t type ) { + d3d_vertex_t v[ 4 ]; + + switch( type ) { + case GRADIENT_VERTICAL: + v[ 0 ] = { float( x ), float( y ), 1.0f, start }; + v[ 1 ] = { float( x + w ), float( y ), 1.0f, start }; + v[ 2 ] = { float( x ), float( y + h ), 1.0f, end }; + v[ 3 ] = { float( x + w ), float( y + h ), 1.0f, end }; + break; + case GRADIENT_HORIZONTAL: + v[ 0 ] = { float( x ), float( y ), 1.0f, start }; + v[ 1 ] = { float( x + w ), float( y ), 1.0f, end }; + v[ 2 ] = { float( x ), float( y + h ), 1.0f, start }; + v[ 3 ] = { float( x + w ), float( y + h ), 1.0f, end }; + break; + } + + //m_device->SetRenderState( D3DRS_MULTISAMPLEANTIALIAS, true ); + m_device->DrawPrimitiveUP( D3DPT_TRIANGLESTRIP, 2, &v, VERTEX_SIZE ); + //m_device->SetRenderState( D3DRS_MULTISAMPLEANTIALIAS, false ); + } + + void c_renderer::draw_circle( clr_t color, int x, int y, int r, int res ) { + constexpr float PI = 3.1415926f; + const float step = PI * 2.0f / float( res ); + + int point_x = x + r, + point_y = y - r, + point_x_o{ }, + point_y_o{ }; + + m_device->SetRenderState( D3DRS_MULTISAMPLEANTIALIAS, true ); + for( int i{ }; i <= res; i++ ) { + float theta = float( i ) * step; + + point_x = x + ( int )( r * cos( theta ) ); + point_y = y - ( int )( r * sin( theta ) ); + if( i ) draw_line( color, point_x, point_y, point_x_o, point_y_o ); + point_x_o = point_x; + point_y_o = point_y; + } + m_device->SetRenderState( D3DRS_MULTISAMPLEANTIALIAS, false ); + } + + void c_renderer::draw_filled_circle( clr_t color, int x, int y, int r, int res ) { + d3d_vertex_t* v = ( d3d_vertex_t* )_alloca( VERTEX_SIZE * res ); + const float step = M_PI * 2.0f / res; + + for( size_t i{ }; i < res; ++i ) { + float theta = i * step; + float x_off = r * cos( theta ); + float y_off = r * sin( theta ); + + v[ i ] = { float( x + x_off ), float( y + y_off ), 1.0f, color }; + } + + m_device->SetRenderState( D3DRS_MULTISAMPLEANTIALIAS, true ); + m_device->DrawPrimitiveUP( D3DPT_TRIANGLESTRIP, res, v, VERTEX_SIZE ); + m_device->SetRenderState( D3DRS_MULTISAMPLEANTIALIAS, false ); + } + + void c_renderer::draw_text( ID3DXFont* font, clr_t color, + int x, int y, FontAlign_t align, long font_flags, const char* msg ) { + if( !msg ) return; + if( !font ) return; + + auto d3d_black = D3DCOLOR_RGBA( 0, 0, 0, color.a( ) ); + auto d3d_color = D3DCOLOR_RGBA( color.r( ), color.g( ), color.b( ), color.a( ) ); + auto buf = msg; + + if( align == ALIGN_CENTER ) x -= get_text_width( font, font_flags, msg ) / 2; + if( align == ALIGN_RIGHT ) x -= get_text_width( font, font_flags, msg ); + RECT rect{ x, y, 1000, 100 }; + + ulong_t flags = DT_NOCLIP | DT_LEFT | DT_TOP; + + if( font_flags & D3DFONTFLAG_DROPSHADOW ) { + RECT r{ rect }; + r.left++; + r.top++; + font->DrawTextA( 0, buf, -1, &r, flags, d3d_black ); + } + + if( font_flags & D3DFONTFLAG_OUTLINE ) { + for( int i = -1; i < 2; i++ ) { + RECT r{ rect }; + r.left += i; + r.top += i; + font->DrawTextA( 0, buf, -1, &r, flags, d3d_black ); + } + } + + font->DrawTextA( 0, buf, -1, &rect, flags, d3d_color ); + } + + int c_renderer::get_text_width( ID3DXFont* font, long flags, const char* msg, ... ) { + char* buffer = ( char* )_alloca( 2048 ); + va_list list{ }; + + memset( buffer, 0, 2048 ); + + __crt_va_start( list, msg ); + vsprintf_s( buffer, 2048, msg, list ); + __crt_va_end( list ); + + RECT temp{ }; + font->DrawTextA( 0, buffer, -1, &temp, DT_CALCRECT, 0x0 ); + + return ( temp.right - temp.left ); + } + + int c_renderer::get_text_height( ID3DXFont* font, long flags, const char* msg, ... ) { + char* buffer = ( char* )_alloca( 2048 ); + va_list list{ }; + + memset( buffer, 0, 2048 ); + + __crt_va_start( list, msg ); + vsprintf_s( buffer, 2048, msg, list ); + __crt_va_end( list ); + + RECT temp{ }; + font->DrawTextA( 0, buffer, -1, &temp, DT_CALCRECT, 0x0 ); + + return ( temp.bottom - temp.top ); + } +} diff --git a/legacy/loader/d3d.hpp b/legacy/loader/d3d.hpp new file mode 100644 index 0000000..034724a --- /dev/null +++ b/legacy/loader/d3d.hpp @@ -0,0 +1,126 @@ +#ifndef D3D_HEADER //stackoverflow my niggas +#define D3D_HEADER + +#include +#include + +#pragma comment(lib, "d3d9.lib") +#pragma comment(lib, "d3dx9.lib") +#pragma warning(disable : 4838) + +#include +#include + +#include +#pragma comment(lib, "dwmapi.lib") + +#include "util.hpp" +#include "color.hpp" + +enum FontAlign_t : size_t { + ALIGN_CENTER, + ALIGN_LEFT, + ALIGN_RIGHT +}; + +enum D3DFontFlags_t { + D3DFONTFLAG_OUTLINE = 0x10, + D3DFONTFLAG_DROPSHADOW = 0x100, +}; + +enum GradientType_t { + GRADIENT_HORIZONTAL, + GRADIENT_VERTICAL +}; + +//suck my dick +namespace d3d +{ + struct d3d_vertex_t { + d3d_vertex_t( float x, float y, float z, clr_t color ) : + m_x( x ), m_y( y ), m_z( z ), + m_clr( D3DCOLOR_RGBA( color.r( ), color.g( ), color.b( ), color.a( ) ) ) { }; + + d3d_vertex_t( ) : m_x( 0.f ), m_y( 0.f ), m_z( 0.f ), + m_clr( 0 ) { }; + + float m_x; + float m_y; + float m_z; + float m_rhw = 1.f; + D3DCOLOR m_clr; + }; + + constexpr size_t VERTEX_SIZE = sizeof( d3d_vertex_t ); + + struct d3d_fonts_t { + void release( ); + void create( IDirect3DDevice9* device ); + + ID3DXFont* f_12; + ID3DXFont* f_14; + ID3DXFont* f_16; + ID3DXFont* f_18; + ID3DXFont* f_menu; + ID3DXFont* f_con; + }; + + class c_renderer { + private: + IDirect3DDevice9* m_device; + IDirect3DStateBlock9* m_block; + public: + ulong_t m_width; + ulong_t m_height; + + c_renderer( ) { }; + c_renderer( IDirect3DDevice9* device ); + ~c_renderer( ); + + void on_device_lost( ); + void on_device_reset( ); + auto get_device( ) { + return m_device; + } + + bool run_frame( IDirect3DDevice9* device ); + void begin( ); + void end( ); + + void draw_line( clr_t color, int x0, int y0, int x1, int y1 ); + void draw_rect( clr_t color, int x, int y, int w, int h ); + void draw_filled_rect( clr_t color, int x, int y, int w, int h ); + void draw_circle( clr_t color, int x, int y, int r, int steps = 48 ); + void draw_filled_circle( clr_t color, int x, int y, int r, int steps = 48 ); + void draw_gradient( clr_t start, clr_t end, int x, int y, int w, int h, GradientType_t type ); + + void draw_text( ID3DXFont* font, clr_t color, int x, int y, FontAlign_t align, long font_flags, const char* msg ); + + template < FontAlign_t align = ALIGN_CENTER > + void draw_text( ID3DXFont* font, clr_t color, int x, int y, long font_flags, const char* msg, ... ) { + char* buffer = ( char* )_alloca( 2048 ); + va_list list{ }; + + memset( buffer, 0, 2048 ); + + __crt_va_start( list, msg ); + vsprintf_s( buffer, 2048, msg, list ); + __crt_va_end( list ); + + draw_text( font, color, x, y, align, font_flags, buffer ); + } + + int get_text_width( ID3DXFont* font, long font_flags, const char* msg, ... ); + int get_text_height( ID3DXFont* font, long font_flags, const char* msg, ... ); + + private: + void invalidate_objects( ); + void create_objects( ); + }; + + extern d3d::d3d_fonts_t fonts; +} + +extern d3d::c_renderer g_d3d; + +#endif \ No newline at end of file diff --git a/legacy/loader/d3d_sprite.cpp b/legacy/loader/d3d_sprite.cpp new file mode 100644 index 0000000..8dd6705 --- /dev/null +++ b/legacy/loader/d3d_sprite.cpp @@ -0,0 +1,13 @@ +#include "d3d_sprite.hpp" + +std::vector< d3d::c_sprite* > d3d::sprites; + +namespace icons +{ + d3d::c_sprite sprite_legit; + d3d::c_sprite sprite_visuals_; + d3d::c_sprite sprite_rage; + d3d::c_sprite sprite_visuals; + d3d::c_sprite sprite_misc; + d3d::c_sprite sprite_config; +} \ No newline at end of file diff --git a/legacy/loader/d3d_sprite.hpp b/legacy/loader/d3d_sprite.hpp new file mode 100644 index 0000000..584fddb --- /dev/null +++ b/legacy/loader/d3d_sprite.hpp @@ -0,0 +1,107 @@ +#pragma once +#include +#include "d3d.hpp" + + +namespace d3d +{ + class c_sprite; + + extern std::vector< c_sprite* > sprites; + + class c_sprite { + public: + size_t m_width{ }; + size_t m_height{ }; + + IDirect3DDevice9* m_device{ }; + ID3DXSprite* m_sprite{ }; + IDirect3DTexture9* m_texture{ }; + const byte* m_image{ }; + size_t m_image_size{ }; + + + public: + c_sprite( ) { + sprites.push_back( this ); + } + + ~c_sprite( ) { + on_reset( ); + } + + void init( IDirect3DDevice9* device, const byte* file, size_t img_size, size_t width, size_t height ) { + m_width = width; + m_height = height; + + m_device = device; + m_image = file; + m_image_size = img_size; + } + + void begin( IDirect3DDevice9* device ) { + m_device = device; + + if( !m_device ) { + return; + } + + if( !m_sprite ) + D3DXCreateSprite( m_device, &m_sprite ); + + if( m_sprite ) + m_sprite->Begin( D3DXSPRITE_ALPHABLEND ); + + if( !m_texture ) { + auto hr = D3DXCreateTextureFromFileInMemoryEx( + m_device, m_image, m_image_size, + m_width, m_height, D3DX_DEFAULT, 0, D3DFMT_A8B8G8R8, + D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, + 0, 0, &m_texture ); + } + } + + void end( ) { + if( !m_device || !m_sprite || !m_texture ) return; + if( m_sprite ) m_sprite->End( ); + } + + void on_reset( ) { + if( m_sprite && m_device && m_texture ) { + m_sprite->OnLostDevice( ); + m_sprite->OnResetDevice( ); + m_texture->Release( ); + m_texture = nullptr; + } + } + + void draw( int x, int y, clr_t color ) { + if( !m_device || !m_texture || !m_sprite ) { + return; + } + + ulong_t hr; + D3DXVECTOR2 center = D3DXVECTOR2( m_width * 0.5f, m_height * 0.5f ); + D3DXVECTOR2 trans = D3DXVECTOR2( x - center.x, y - center.y ); + D3DXMATRIX matrix; + D3DXVECTOR2 scale( 1.f, 1.f ); + D3DXMatrixTransformation2D( &matrix, 0, 0.f, &scale, ¢er, 0.f, &trans ); + + hr = m_sprite->SetTransform( &matrix ); + + auto d3dcolor = D3DCOLOR_RGBA( color.r( ), + color.g( ), color.b( ), color.a( ) ); + hr = m_sprite->Draw( m_texture, 0, 0, 0, d3dcolor ); + } + }; +} + +namespace icons +{ + extern d3d::c_sprite sprite_legit; + extern d3d::c_sprite sprite_visuals_; + extern d3d::c_sprite sprite_rage; + extern d3d::c_sprite sprite_visuals; + extern d3d::c_sprite sprite_misc; + extern d3d::c_sprite sprite_config; +} \ No newline at end of file diff --git a/legacy/loader/http.h b/legacy/loader/http.h new file mode 100644 index 0000000..a965dfe --- /dev/null +++ b/legacy/loader/http.h @@ -0,0 +1,70 @@ +#include +#include +#include +#include +#include +#include "strings.hpp" + +#pragma comment( lib, "wininet.lib" ) + +//very innovative PROTECTED !!! loader +// do NOT LEAK + +using namespace std::chrono_literals; +using ulong_t = unsigned long; + +namespace http { + class inethandle_t { + public: + operator HINTERNET( ) { return m_handle; } + inethandle_t( HINTERNET handle ) : m_handle( handle ) { }; + inethandle_t( ) : m_handle( nullptr ) { }; + ~inethandle_t( ) { + InternetCloseHandle( m_handle ); + } + + private: + HINTERNET m_handle; + }; + + auto send_request( char* uname, ulong_t hwid, int appid ) { + std::vector< uint8_t > response{ }; + inethandle_t intern = InternetOpenA( "none", INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, 0 ); + inethandle_t addr = InternetConnectA( intern, xors( "moneybot.cc" ), INTERNET_DEFAULT_HTTPS_PORT, xors( "HakNtBNxed" ), xors( "PYfBKRduQUdl3oR" ), INTERNET_SERVICE_HTTP, 0, 0 ); + if( !addr ) { + MessageBoxA( 0, xors( "error" ), xors( "server error" ), MB_OK ); + exit( 0 ); + } + + inethandle_t req = HttpOpenRequestA( addr, xors( "POST" ), xors( "iakSZFzfST/money.php" ), 0, 0, 0, INTERNET_FLAG_SECURE | INTERNET_FLAG_KEEP_CONNECTION, 0 ); + + auto headers = xors( "Content-Type: application/json\r\n" ); + const char* POST_FORMAT = xors( R"( +{ + "user": "%s", + "hwid": "%08x", + "app_id": "%d" +} +)" ); + + char send_data[ 300 ]; + sprintf_s( send_data, 300, POST_FORMAT, uname, hwid, appid ); + + auto sent = HttpSendRequestA( req, headers, strlen( headers ), ( void* )send_data, strlen( send_data ) ); + if( sent ) { + ulong_t blocksize = 4096; + ulong_t size{ }; + uint8_t* block = ( uint8_t* )malloc( blocksize ); + + while( InternetReadFile( req, block, blocksize, &size ) && size ) { + for( size_t i{ }; i < std::min< ulong_t >( blocksize, size ); ++i ) { + response.push_back( block[ i ] ); + } + } + + free( block ); + } + + return response; + } +} \ No newline at end of file diff --git a/legacy/loader/iface.hpp b/legacy/loader/iface.hpp new file mode 100644 index 0000000..49a4dc5 --- /dev/null +++ b/legacy/loader/iface.hpp @@ -0,0 +1,198 @@ +#pragma once +#include +#include +#include "winapi.hpp" +#include "util.hpp" + +namespace iface +{ + class container { + private: + struct reg { + char m_key; + uintptr_t m_ptr; + uintptr_t m_module; + char m_module_name[ 64 ]; + char m_name[ 64 ]; + }; + + std::vector< reg > m_regs; + public: + void emplace_reg( uintptr_t ptr, uintptr_t module_, const char* name, const char* module_name, char name_key ) { + reg new_reg{ }; + new_reg.m_ptr = ptr; + new_reg.m_module = module_; + + memcpy( new_reg.m_name, name, 64 ); + memcpy( new_reg.m_module_name, module_name, 64 ); + + new_reg.m_key = name_key; + + m_regs.emplace_back( new_reg ); + } + + auto& get_regs( ) { + return m_regs; + } + }; + + struct iface_reg_t { + void* m_create_fn; + const char* m_name; + uintptr_t m_next; + + inline auto follow( HANDLE process ) { + iface_reg_t buf; + ReadProcessMemory( process, ( void* )( m_next ), &buf, sizeof( buf ), nullptr ); + return buf; + } + }; + + class manager { + HANDLE& m_process; + container m_container; + + inline auto is_createinterface_export( uintptr_t export_ ) { + uint8_t buf[ 12 ]; + + ReadProcessMemory( m_process, ( void* )( export_ ), buf, sizeof( buf ), nullptr ); + + return( buf[ 0 ] == 0x55 + && buf[ 4 ] == 0xe9 + && buf[ 9 ] == 0xcc + && buf[ 10 ] == 0xcc ); + } + + inline auto is_createinterface_fn( uintptr_t fn_ ) { + uint8_t buf[ 12 ]; + + ReadProcessMemory( m_process, ( void* )( fn_ ), buf, sizeof( buf ), nullptr ); + + return( buf[ 0 ] == 0x55 + && buf[ 4 ] == 0x8b + && buf[ 10 ] == 0x57 ); + } + + inline auto follow_createinterface_export( uintptr_t export_ ) { + uintptr_t jmp = export_ + 0x4; + + uintptr_t rel; + ReadProcessMemory( m_process, ( void* )( jmp + 0x1 ), &rel, sizeof( rel ), nullptr ); + + return jmp + rel + 0x5; + } + + inline auto find_list_ptr( uintptr_t createinterface ) { + uintptr_t + first = createinterface + 0x6, + second, + third; + + ReadProcessMemory( m_process, ( void* )( first ), &second, sizeof( second ), nullptr ); + ReadProcessMemory( m_process, ( void* )( second ), &third, sizeof( third ), nullptr ); + + return third; + } + + inline auto get_list( uintptr_t ptr ) { + iface_reg_t reg; + ReadProcessMemory( m_process, ( void* )( ptr ), ®, sizeof( reg ), nullptr ); + + return reg; + } + + public: + manager( HANDLE& process ) : m_process( process ) { }; + + inline void dump_from_module( HMODULE mod, const char* module_name ) { + auto read_str = [ this ]( char* buf, size_t size, uintptr_t addr ) { + for( size_t i{ }; i < size; ++i ) { + char _c; + ReadProcessMemory( m_process, ( void* )( addr + i ), &_c, 1, 0 ); + buf[ i ] = _c; + if( !_c ) break; + } + + buf[ size - 1 ] = 0; + }; + + auto enc_str = [ ]( char* buf, size_t size, char key ) { + for( size_t i{ }; i < size; ++i ) { + buf[ i ] ^= key; + } + }; + + auto create_interface = winapi::get_procaddr_ex( m_process, mod, xors( "CreateInterface" ) ); + if( !create_interface || !is_createinterface_export( create_interface ) ) + return; + + auto fn = follow_createinterface_export( create_interface ); + if( !is_createinterface_fn( fn ) ) + return; + + auto list_ptr = find_list_ptr( fn ); + auto list = get_list( list_ptr ); + + char name_buf[ 64 ]; + char module_buf[ 64 ]; + + do { + read_str( name_buf, 64, ( uintptr_t )( list.m_name ) ); + strcpy( module_buf, module_name ); + + srand( list_ptr ); + auto key = rand( ) & 0xff; + + enc_str( name_buf, 64, key ); + enc_str( module_buf, 64, key ); + + uintptr_t iface_ptr = 0; + ReadProcessMemory( m_process, ( void* )( ( uintptr_t )list.m_create_fn + 1 ), + &iface_ptr, sizeof( uintptr_t ), nullptr ); + + m_container.emplace_reg( iface_ptr, uintptr_t( mod ), name_buf, module_name, key ); + + list_ptr = list.m_next; + list = get_list( list_ptr ); + } while( list_ptr && name_buf[ 0 ] && list_ptr != list.m_next ); + } + + void dump_all_modules( int pid ) { + HANDLE t32_snapshot; + MODULEENTRY32 entry; + + t32_snapshot = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, pid ); + entry.dwSize = sizeof( MODULEENTRY32 ); + + for( Module32First( t32_snapshot, &entry ); + !!Module32Next( t32_snapshot, &entry ); ) { + + //why valve troll me + if( strstr( entry.szModule, xors( "valve_avi" ) ) ) + continue; + + dump_from_module( ( HMODULE )( entry.modBaseAddr ), entry.szModule ); + } + } + + auto count( ) { + return m_container.get_regs( ).size( ); + } + + auto& get( ) { + return m_container; + } + + uintptr_t write_to_process( ) { + size_t count_ = count( ); + size_t size = count_ * 137 + sizeof( size_t ); + + auto allocation = VirtualAllocEx( m_process, 0, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE ); + WriteProcessMemory( m_process, allocation, &count_, sizeof( count_ ), nullptr ); + WriteProcessMemory( m_process, ( void* )( uintptr_t( allocation ) + 0x4 ), + get( ).get_regs( ).data( ), size, nullptr ); + + return ( uintptr_t )( allocation ); + } + }; +} \ No newline at end of file diff --git a/legacy/loader/input_system.cpp b/legacy/loader/input_system.cpp new file mode 100644 index 0000000..b71917e --- /dev/null +++ b/legacy/loader/input_system.cpp @@ -0,0 +1,523 @@ +#include + +#include "input_system.hpp" +#include "util.hpp" + +util::c_input_manager g_input; + +NAMESPACE_REGION( util ) + +const char* const key_names_short[] = { + "unk", + "m1", + "m2", + "can", + "m3", + "m4", + "m5", + "unk", + "back", + "tab", + "unk", + "unk", + "clr", + "ret", + "unk", + "unk", + "shift", + "ctrl", + "alt", + "pause", + "caps", + "kana", + "unk", + "junja", + "final", + "kanji", + "unk", + "esc", + "convert", + "nonconvert", + "accept", + "modechange", + " ", + "prior", + "next", + "end", + "home", + "left", + "up", + "right", + "down", + "slct", + "prnt", + "execute", + "snapshot", + "ins", + "del", + "help", + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "unk", + "unk", + "unk", + "unk", + "unk", + "unk", + "unk", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "lwin", + "rwin", + "apps", + "unk", + "unk", + "num0", + "num1", + "num2", + "num3", + "num4", + "num5", + "num6", + "num7", + "num8", + "num9", + "*", + "+", + "sep", + "-", + ",", + "/", + "f1", + "f2", + "f3", + "f4", + "f5", + "f6", + "f7", + "f8", + "f9", + "f10", + "f11", + "f12", + "f13", + "f14", + "f15", + "f16", + "f17", + "f18", + "f19", + "f20", + "f21", + "f22", + "f23", + "f24", + "unk", + "unk", + "unk", + "unk", + "unk", + "unk", + "unk", + "unk", + "numlock", + "scroll", + "oem_nec_equal", + "oem_fj_masshou", + "oem_fj_touroku", + "oem_fj_loya", + "oem_fj_roya", + "unk", + "unk", + "unk", + "unk", + "unk", + "unk", + "unk", + "unk", + "unk", + "lshift", + "rshift", + "lctrl", + "rctrl", + "lalt", + "ralt", +}; + +const char* const key_names[] = { + "unknown", + "mouse_1", + "mouse_2", + "cancel", + "mouse_3", + "mouse_4", + "mouse_5", + "unknown", + "back", + "tab", + "unknown", + "unknown", + "clear", + "return", + "unknown", + "unknown", + "shift", + "control", + "alt", + "pause", + "capital", + "kana", + "unknown", + "junja", + "final", + "kanji", + "unknown", + "escape", + "convert", + "nonconvert", + "accept", + "modechange", + "space", + "prior", + "next", + "end", + "home", + "left", + "up", + "right", + "down", + "select", + "print", + "execute", + "snapshot", + "insert", + "delete", + "help", + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "unknown", + "unknown", + "unknown", + "unknown", + "unknown", + "unknown", + "unknown", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "lwin", + "rwin", + "apps", + "unknown", + "unknown", + "numpad0", + "numpad1", + "numpad2", + "numpad3", + "numpad4", + "numpad5", + "numpad6", + "numpad7", + "numpad8", + "numpad9", + "multiply", + "add", + "separator", + "subtract", + "decimal", + "divide", + "f1", + "f2", + "f3", + "f4", + "f5", + "f6", + "f7", + "f8", + "f9", + "f10", + "f11", + "f12", + "f13", + "f14", + "f15", + "f16", + "f17", + "f18", + "f19", + "f20", + "f21", + "f22", + "f23", + "f24", + "unknown", + "unknown", + "unknown", + "unknown", + "unknown", + "unknown", + "unknown", + "unknown", + "numlock", + "scroll", + "oem_nec_equal", + "oem_fj_masshou", + "oem_fj_touroku", + "oem_fj_loya", + "oem_fj_roya", + "unknown", + "unknown", + "unknown", + "unknown", + "unknown", + "unknown", + "unknown", + "unknown", + "unknown", + "lshift", + "rshift", + "lcontrol", + "rcontrol", + "lmenu", + "rmenu", +}; + +void c_input_manager::capture_mouse_move( ulong_t lparam ) { + m_mouse_pos[ 0 ] = LOWORD( lparam ); + m_mouse_pos[ 1 ] = HIWORD( lparam ); +} + +bool c_input_manager::register_key_press( VirtualKeyEvents_t key_event, VirtualKeys_t key ) +{ + switch ( key_event ) { + case KEYDOWN: { + if ( is_valid_key( key ) ) + m_pressed_keys[ key ] = true; + return true; + } + case KEYUP: { + if ( is_valid_key( key ) ) + m_pressed_keys[ key ] = false; + return true; + } + case SYSKEYDOWN: { //WTF IS THIS STUPID SHIT, WHY IS ALT LITERALLY THE ONLY FUCKING KEY UNDER SYSKEYDOWN OUT OF ALL THE MODIFIER KEYS? + if ( key == KEYS_ALT ) + m_pressed_keys[ key ] = true; + break; + } + case SYSKEYUP: { + if ( key == KEYS_ALT ) + m_pressed_keys[ key ] = false; + break; + } + case LBUTTONDOWN: + m_pressed_keys[ KEYS_MOUSE1 ] = true; + return true; + case LBUTTONUP: + m_pressed_keys[ KEYS_MOUSE1 ] = false; + return true; + case RBUTTONDOWN: + m_pressed_keys[ KEYS_MOUSE2 ] = true; + return true; + case RBUTTONUP: + m_pressed_keys[ KEYS_MOUSE2 ] = false; + return true; + case MBUTTONDOWN: + m_pressed_keys[ KEYS_MOUSE3 ] = true; + return true; + case MBUTTONUP: + m_pressed_keys[ KEYS_MOUSE3 ] = false; + return true; + case XBUTTONDOWN: { + bool pressed_xbutton = static_cast( HIWORD( key ) - 1 ); //should result in mouse4 as false, and mouse5 as true + m_pressed_keys[ pressed_xbutton ? KEYS_MOUSE5 : KEYS_MOUSE4 ] = true; + return true; + } + case XBUTTONUP: { + bool pressed_xbutton = static_cast( HIWORD( key ) - 1 ); //should result in mouse4 as false, and mouse5 as true + m_pressed_keys[ pressed_xbutton ? KEYS_MOUSE5 : KEYS_MOUSE4 ] = false; + return true; + } + case MOUSEWHEEL: { + short scroll_input = ( short )HIWORD( key ); + m_scroll_wheel_state = scroll_input > 0 ? 1 : -1; + return true; + } + } + + return key_event == 0x200 || key_event == 0x203 || key_event == 0x206 || key_event == 0x209; //gotta block WM_MOUSEFIST | WM_LBUTTONDBLCLK | WM_RBUTTONDBLCLK | WM_MBUTTONDBLCLK +} + +bool c_input_manager::is_key_pressed( int key ) { + auto k = static_cast< VirtualKeys_t >( key ); + return is_valid_key( k ) && m_pressed_keys[ k ]; +} + +const char* c_input_manager::get_key_name( VirtualKeys_t key ) { + if ( !is_valid_key( key ) ) + return key_names[ KEYS_NONE ]; + + return key_names[ key ]; +} + +const char* c_input_manager::get_short_name( VirtualKeys_t key ) { + return key_names_short[ is_valid_key( key ) ? key : KEYS_NONE ]; +} + +VirtualKeys_t c_input_manager::is_any_key_pressed( ) { + for ( size_t i{ }; i < KEYS_MAX; ++i ) { + if ( m_pressed_keys[ i ] ) { + return VirtualKeys_t( i ); + } + } + + return KEYS_NONE; +} + +int c_input_manager::get_scroll_state( ) { + int current_state = m_scroll_wheel_state; + m_scroll_wheel_state = 0; + return current_state; +} + +char c_input_manager::get_pressed_char( VirtualKeys_t* out ) { + size_t pressed_character{ }; + for ( size_t i{ }; i < KEYS_MAX; ++i ) { + if ( is_key_pressed( VirtualKeys_t( i ) ) ) { + if ( ( i >= KEYS_A && i <= KEYS_Z ) + || ( i >= KEYS_N0 && i <= KEYS_N9 ) ) { + pressed_character = i; + } + } + } + + if ( pressed_character ) { + if ( out ) { + *out = VirtualKeys_t( pressed_character ); + } + + if ( is_key_pressed( KEYS_SHIFT ) ) { + if ( pressed_character >= KEYS_A + && pressed_character <= KEYS_Z ) + return char( pressed_character ); + + //gay way to shift it to symbols + if ( pressed_character >= KEYS_N0 + && pressed_character <= KEYS_N9 ) { + switch ( pressed_character ) { + case KEYS_N0: + return ')'; + case KEYS_N1: + return '!'; + case KEYS_N2: + return '@'; + case KEYS_N3: + return '#'; + case KEYS_N4: + return '$'; + case KEYS_N5: + return '%'; + case KEYS_N6: + return '^'; + case KEYS_N7: + return '&'; + case KEYS_N8: + return '*'; + case KEYS_N9: + return '('; + } + } + } + else { + if ( pressed_character >= KEYS_A + && pressed_character <= KEYS_Z ) + return char( ::tolower( pressed_character ) ); + + if ( pressed_character >= KEYS_N0 + && pressed_character <= KEYS_N9 ) + return char( pressed_character ); + } + } + else if ( is_key_pressed( KEYS_SPACE ) ) { + if ( out ) + *out = KEYS_SPACE; + + return ' '; + } + else if ( is_key_pressed( KEYS_BACK ) ) { + if ( out ) + *out = KEYS_BACK; + + return 0; + } + + if ( out ) + *out = KEYS_NONE; + + return 0; +} + +END_REGION \ No newline at end of file diff --git a/legacy/loader/input_system.hpp b/legacy/loader/input_system.hpp new file mode 100644 index 0000000..c517f38 --- /dev/null +++ b/legacy/loader/input_system.hpp @@ -0,0 +1,177 @@ +#pragma once +#include "util.hpp" + +enum VirtualKeyEvents_t { + KEYDOWN = 0x0100, + KEYUP = 0x0101, + SYSKEYDOWN = 0x104, + SYSKEYUP = 0x105, + LBUTTONDOWN = 0x0201, + LBUTTONUP = 0x0202, + RBUTTONDOWN = 0x0204, + RBUTTONUP = 0x0205, + MBUTTONDOWN = 0x0207, + MBUTTONUP = 0x0208, + MOUSEWHEEL = 0x020A, + XBUTTONDOWN = 0x020B, + XBUTTONUP = 0x020C, +}; + +enum VirtualKeys_t { + KEYS_NONE = 0, + KEYS_MOUSE1 = 0X01, + KEYS_MOUSE2 = 0X02, + KEYS_CANCEL = 0X03, + KEYS_MOUSE3 = 0X04, + KEYS_MOUSE4 = 0X05, + KEYS_MOUSE5 = 0X06, + KEYS_BACK = 0X08, + KEYS_TAB = 0X09, + KEYS_CLEAR = 0X0C, + KEYS_RETURN = 0X0D, + KEYS_SHIFT = 0X10, + KEYS_CONTROL = 0X11, + KEYS_ALT = 0X12, + KEYS_PAUSE = 0X13, + KEYS_CAPSLOCK = 0X14, + KEYS_ESCAPE = 0X1B, + KEYS_CONVERT = 0X1C, + KEYS_NONCONVERT = 0X1D, + KEYS_ACCEPT = 0X1E, + KEYS_MODECHANGE = 0X1F, + KEYS_SPACE = 0X20, + KEYS_PRIOR = 0X21, + KEYS_NEXT = 0X22, + KEYS_END = 0X23, + KEYS_HOME = 0X24, + KEYS_LEFT = 0X25, + KEYS_UP = 0X26, + KEYS_RIGHT = 0X27, + KEYS_DOWN = 0X28, + KEYS_SELECT = 0X29, + KEYS_PRINT = 0X2A, + KEYS_EXECUTE = 0X2B, + KEYS_SNAPSHOT = 0X2C, + KEYS_INSERT = 0X2D, + KEYS_DELETE = 0X2E, + KEYS_HELP = 0X2F, + KEYS_N0 = 0X30, + KEYS_N1 = 0X31, + KEYS_N2 = 0X32, + KEYS_N3 = 0X33, + KEYS_N4 = 0X34, + KEYS_N5 = 0X35, + KEYS_N6 = 0X36, + KEYS_N7 = 0X37, + KEYS_N8 = 0X38, + KEYS_N9 = 0X39, + KEYS_A = 0X41, + KEYS_B = 0X42, + KEYS_C = 0X43, + KEYS_D = 0X44, + KEYS_E = 0X45, + KEYS_F = 0X46, + KEYS_G = 0X47, + KEYS_H = 0X48, + KEYS_I = 0X49, + KEYS_J = 0X4A, + KEYS_K = 0X4B, + KEYS_L = 0X4C, + KEYS_M = 0X4D, + KEYS_N = 0X4E, + KEYS_O = 0X4F, + KEYS_P = 0X50, + KEYS_Q = 0X51, + KEYS_R = 0X52, + KEYS_S = 0X53, + KEYS_T = 0X54, + KEYS_U = 0X55, + KEYS_V = 0X56, + KEYS_W = 0X57, + KEYS_X = 0X58, + KEYS_Y = 0X59, + KEYS_Z = 0X5A, + KEYS_LEFTWINDOWS = 0X5B, + KEYS_RIGHTWINDOWS = 0X5C, + KEYS_APPLICATION = 0X5D, + KEYS_NUMPAD0 = 0X60, + KEYS_NUMPAD1 = 0X61, + KEYS_NUMPAD2 = 0X62, + KEYS_NUMPAD3 = 0X63, + KEYS_NUMPAD4 = 0X64, + KEYS_NUMPAD5 = 0X65, + KEYS_NUMPAD6 = 0X66, + KEYS_NUMPAD7 = 0X67, + KEYS_NUMPAD8 = 0X68, + KEYS_NUMPAD9 = 0X69, + KEYS_MULTIPLY = 0X6A, + KEYS_ADD = 0X6B, + KEYS_SEPARATOR = 0X6C, + KEYS_SUBTRACT = 0X6D, + KEYS_DECIMAL = 0X6E, + KEYS_DIVIDE = 0X6F, + KEYS_F1 = 0X70, + KEYS_F2 = 0X71, + KEYS_F3 = 0X72, + KEYS_F4 = 0X73, + KEYS_F5 = 0X74, + KEYS_F6 = 0X75, + KEYS_F7 = 0X76, + KEYS_F8 = 0X77, + KEYS_F9 = 0X78, + KEYS_F10 = 0X79, + KEYS_F11 = 0X7A, + KEYS_F12 = 0X7B, + KEYS_NUMLOCK = 0X90, + KEYS_SCROLLLOCK = 0X91, + KEYS_LEFTSHIFT = 0XA0, + KEYS_RIGHTSHIFT = 0XA1, + KEYS_LEFTCONTROL = 0XA2, + KEYS_RIGHTCONTROL = 0XA3, + KEYS_LEFTMENU = 0XA4, + KEYS_RIGHTMENU = 0XA5, + KEYS_PERIOD = 0xBE, + KEYS_MAX = 0XA6, + KEYS_LAST = 0xfe +}; + +namespace util +{ + class c_input_manager { + bool m_pressed_keys[ KEYS_MAX ]; + int m_mouse_pos[ 2 ]; + int m_scroll_wheel_state; + public: + void capture_mouse_move( ulong_t lparam ); + + //registers a key press from wndproc + bool register_key_press( VirtualKeyEvents_t key_event, VirtualKeys_t key ); + + //checks if the key is pressed + bool is_key_pressed( int key ); + + //returns the first found key pressed, or KEY_NONE if none are + VirtualKeys_t is_any_key_pressed( ); + + //returns the last scroll state and resets it to 0 + int get_scroll_state( ); + + //returns the key's name + const char* get_key_name( VirtualKeys_t key ); + const char* get_short_name( VirtualKeys_t key ); + + //returns the first found currently pressed key + char get_pressed_char( VirtualKeys_t* pressed_key = nullptr ); + + //check if a key is valid + inline bool is_valid_key( VirtualKeys_t key ) { return key > KEYS_NONE && key < KEYS_MAX; } + + //get cursor pos + inline void get_cursor_pos( int& x, int& y ) { + x = m_mouse_pos[ 0 ]; + y = m_mouse_pos[ 1 ]; + } + }; +} + +extern util::c_input_manager g_input; \ No newline at end of file diff --git a/legacy/loader/loader.vcxproj b/legacy/loader/loader.vcxproj new file mode 100644 index 0000000..e8202b2 --- /dev/null +++ b/legacy/loader/loader.vcxproj @@ -0,0 +1,245 @@ + + + + + Debug + Win32 + + + pHit + Win32 + + + pHit + x64 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {C376FC6E-5E1C-4ADD-A921-BC8E2968E8B0} + loader + 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;$(IncludePath) + C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86;$(LibraryPath) + + + C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;$(IncludePath) + C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86;$(LibraryPath) + + + C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;$(IncludePath) + C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86;$(LibraryPath) + + + + Level3 + MaxSpeed + true + true + true + _MBCS;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS + stdcpp17 + + + true + true + false + false + /NXCOMPAT:NO %(AdditionalOptions) + + RequireAdministrator + + + + + Level3 + MaxSpeed + true + true + true + _MBCS;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS + stdcpp17 + + + true + true + false + false + /NXCOMPAT:NO %(AdditionalOptions) + + + RequireAdministrator + + + + + Level3 + Disabled + true + true + stdcpp17 + _MBCS;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS + + + Windows + + + + + 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/loader/loader.vcxproj.filters b/legacy/loader/loader.vcxproj.filters new file mode 100644 index 0000000..7aeaacb --- /dev/null +++ b/legacy/loader/loader.vcxproj.filters @@ -0,0 +1,147 @@ + + + + + {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 + + + {2a67ca5a-84ca-481c-b6dd-d35db109320e} + + + {0ae239aa-5489-4d37-9ca5-f5ed596b8364} + + + {6f16eb64-7a39-4a36-84ed-a3ad1492b272} + + + {dc9e1541-2daf-4e48-b5fc-96803b1b5a26} + + + {4f442dba-539b-4639-a710-b7a4ef78465b} + + + {7a55fde6-06f2-45c5-bd1a-6a8a316739a8} + + + + + Source Files + + + Source Files\ui + + + Source Files\util + + + Source Files\util + + + Source Files\util + + + Source Files\util + + + Source Files\manualmap + + + + + Source Files\ui + + + Source Files\ui + + + Source Files\ui + + + Source Files\ui + + + Source Files\ui + + + Source Files\ui + + + Source Files\ui + + + Source Files\ui + + + Source Files\ui + + + Source Files\ui + + + Source Files\ui + + + Source Files\ui + + + Source Files\ui + + + Source Files\ui + + + Source Files\ui + + + Source Files\ui + + + Source Files\util + + + Source Files\util + + + Source Files\util + + + Source Files\util + + + Source Files\util + + + Source Files\util + + + Source Files\util + + + Source Files\manualmap + + + Source Files\http + + + Source Files\enc + + + Source Files\ui + + + Source Files\iface + + + Source Files\util + + + \ No newline at end of file diff --git a/legacy/loader/manualmap.cpp b/legacy/loader/manualmap.cpp new file mode 100644 index 0000000..da49a13 --- /dev/null +++ b/legacy/loader/manualmap.cpp @@ -0,0 +1,109 @@ +#include "manualmap.hpp" + +void inject::c_map::initialize( int pid ) { + m_handle = OpenProcess( PROCESS_ALL_ACCESS, 0, pid ); +} + +void inject::c_map::initialize( HANDLE process ) { + m_handle = process; +} + +void inject::c_map::write( uintptr_t address, void* data, size_t size ) { + WriteProcessMemory( m_handle, ( void* )address, data, size, nullptr ); +} + +uintptr_t inject::c_map::allocate( size_t size ) { + void* allocation = VirtualAllocEx( m_handle, 0, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE ); + m_allocations.push_back( allocation ); + + return uintptr_t( allocation ); +} + +void inject::c_map::free_allocated_regions( ) { + for( auto& it : m_allocations ) { + VirtualFreeEx( m_handle, it, 0, MEM_FREE ); + } + + m_allocations.clear( ); +} + +void inject::c_map::inject( uintptr_t interfaces ) { + HMODULE mod_data = ( HMODULE )m_inject_data.data( ); + + IMAGE_DOS_HEADER dos_hdr; + IMAGE_NT_HEADERS nt_hdrs; + + dos_hdr = *( decltype( dos_hdr )* )( mod_data ); + nt_hdrs = *( decltype( nt_hdrs )* )( uintptr_t( mod_data ) + dos_hdr.e_lfanew ); + + auto allocation = allocate( nt_hdrs.OptionalHeader.SizeOfImage ); + + auto size_of_headers = nt_hdrs.OptionalHeader.SizeOfHeaders; + auto num_of_sections = nt_hdrs.FileHeader.NumberOfSections; + + m_allocation = malloc( nt_hdrs.OptionalHeader.SizeOfImage ); + memset( m_allocation, 0, nt_hdrs.OptionalHeader.SizeOfImage ); + memcpy( m_allocation, mod_data, size_of_headers ); + write( allocation, m_allocation, size_of_headers ); + + auto sections = ( IMAGE_SECTION_HEADER* )( ( uintptr_t )( mod_data ) + dos_hdr.e_lfanew + sizeof( IMAGE_NT_HEADERS ) ); + for( size_t i{ }; i < num_of_sections; ++i ) { + auto section = sections[ i ]; + uintptr_t address = ( uintptr_t )m_allocation + section.VirtualAddress; + memcpy( ( void* )address, + ( void* )( uintptr_t( mod_data ) + section.PointerToRawData ), + ( size_t )section.SizeOfRawData ); + } + + auto base = nt_hdrs.OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_BASERELOC ].VirtualAddress; + auto base_reloc = ( IMAGE_BASE_RELOCATION* )( ( uintptr_t )m_allocation + base ); + auto delta = allocation - nt_hdrs.OptionalHeader.ImageBase; + + while( base_reloc->VirtualAddress ) { + if( base_reloc->SizeOfBlock >= sizeof( IMAGE_BASE_RELOCATION ) ) { + size_t count = ( base_reloc->SizeOfBlock - sizeof( IMAGE_BASE_RELOCATION ) ) / sizeof( uint16_t ); + + auto list = ( uint16_t* )( base_reloc + 1 ); + + uintptr_t* ptr{ }; + for( size_t i{ }; i < count; ++i ) { + if( list[ i ] ) { + ptr = ( uintptr_t* )( ( uintptr_t )( m_allocation ) + ( base_reloc->VirtualAddress + ( list[ i ] & 0xfff ) ) ); + *ptr += delta; + } + } + } + + base_reloc = ( IMAGE_BASE_RELOCATION* )( ( uintptr_t )base_reloc + base_reloc->SizeOfBlock ); + } + + write( allocation, m_allocation, nt_hdrs.OptionalHeader.SizeOfImage ); + free( m_allocation ); + + auto shellcode_allocation = allocate( 0x1000 ); + + img_data_t img_data{ + allocation, + nt_hdrs.OptionalHeader.ImageBase, + nt_hdrs.OptionalHeader.AddressOfEntryPoint, + nt_hdrs.OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_BASERELOC ].VirtualAddress, + nt_hdrs.OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_IMPORT ].VirtualAddress, + ( uintptr_t )( LoadLibraryA ), + ( uintptr_t )( GetProcAddress ), + interfaces + }; + + write( shellcode_allocation, &img_data, sizeof( img_data_t ) ); + + auto loader_code_start = shellcode_allocation + sizeof( img_data_t ); + auto loader_code_size = ( size_t )( ( uintptr_t )( &dummy_func_1 ) - ( uintptr_t )( &loader_shellcode ) ); + + write( loader_code_start, &loader_shellcode, loader_code_size ); + auto thread = CreateRemoteThread( m_handle, nullptr, 0, + ( LPTHREAD_START_ROUTINE )loader_code_start, + ( void* )shellcode_allocation, 0, 0 ); + + WaitForSingleObject( thread, INFINITE ); + ulong_t exit{ }; + GetExitCodeThread( thread, &exit ); +} \ No newline at end of file diff --git a/legacy/loader/manualmap.hpp b/legacy/loader/manualmap.hpp new file mode 100644 index 0000000..39cdecf --- /dev/null +++ b/legacy/loader/manualmap.hpp @@ -0,0 +1,169 @@ +#pragma once +#include +#include +#include +#include "util.hpp" + +enum DllSections_t { + SECTION_TEXT, //.text | allocation + write( obviously ) + SECTION_RDATA, //.rdata | allocation + write + SECTION_DATA, //.data | need to allocate + SECTION_RSRC, //.rsrc | not needed + SETCION_RELOC, //.reloc | will need to do on server + SECTION_MAX +}; + +namespace inject +{ + struct img_data_t { + uintptr_t m_base; + uintptr_t m_image; + uintptr_t m_entry; + uintptr_t m_relocation; + uintptr_t m_imports; + uintptr_t m_loadlib; + uintptr_t m_get_procaddr; + uintptr_t m_interface_ptr; + }; + + using dllmain_t = int( __stdcall* )( void*, ulong_t, void* ); + + static __declspec( naked ) ulong_t __stdcall loader_shellcode( void* address ) { + __asm { + push ebp + mov ebp, esp + sub esp, __LOCAL_SIZE + } + + img_data_t* data; data = ( img_data_t* )address; + + uintptr_t base; base = data->m_base; + uintptr_t entry_point; entry_point = base + data->m_entry; + uintptr_t delta; delta = base - data->m_image; + + IMAGE_BASE_RELOCATION* base_reloc; + IMAGE_IMPORT_DESCRIPTOR* import_dir; + + base_reloc = ( IMAGE_BASE_RELOCATION* )( base + data->m_relocation ); + import_dir = ( IMAGE_IMPORT_DESCRIPTOR* )( base + data->m_imports ); + + decltype( &LoadLibraryA ) loadlib; + decltype( &GetProcAddress ) get_procaddr; + + loadlib = ( decltype( &LoadLibraryA ) )( data->m_loadlib ); + get_procaddr = ( decltype( &GetProcAddress ) )( data->m_get_procaddr ); + + IMAGE_THUNK_DATA* orig_first_thunk; + IMAGE_THUNK_DATA* first_thunk; + + uintptr_t name; + HMODULE import_module; + uintptr_t ordinal; + uintptr_t import_fn; + + IMAGE_IMPORT_BY_NAME* import_; + + while( import_dir->Characteristics ) { + orig_first_thunk = ( IMAGE_THUNK_DATA* )( base + import_dir->OriginalFirstThunk ); + first_thunk = ( IMAGE_THUNK_DATA* )( base + import_dir->FirstThunk ); + + import_module = 0; + + name = base + import_dir->Name; + __asm { + push name + call loadlib + mov import_module, eax + } + + if( !import_module ) { + //return 0 + __asm mov eax, 0; + goto END; + } + + while( orig_first_thunk->u1.AddressOfData ) { + if( orig_first_thunk->u1.Ordinal & IMAGE_ORDINAL_FLAG ) { + ordinal = orig_first_thunk->u1.Ordinal & 0xffff; + import_fn = 0; + + __asm { + push ordinal + push import_module + call get_procaddr + mov import_fn, eax + } + + if( !import_fn ) { + __asm mov eax, 0; + goto END; + } + + + first_thunk->u1.Function = import_fn; + } + else { + import_ = ( IMAGE_IMPORT_BY_NAME* )( base + orig_first_thunk->u1.AddressOfData ); + name = ( uintptr_t )( import_->Name ); + + import_fn = 0; + + __asm { + push name + push import_module + call get_procaddr + mov import_fn, eax + } + + if( !import_fn ) { + __asm mov eax, 0; + goto END; + } + + first_thunk->u1.Function = import_fn; + } + + ++orig_first_thunk; + ++first_thunk; + } + + ++import_dir; + } + + void* interface_ptr; + interface_ptr = ( void* )( data->m_interface_ptr ); + + dllmain_t fn; fn = reinterpret_cast< dllmain_t >( entry_point ); + fn( ( void* )base, DLL_PROCESS_ATTACH, interface_ptr ); + + __asm mov eax, 1; + + END: + __asm { + mov esp, ebp + pop ebp + ret + } + } + + static ulong_t __stdcall dummy_func_1( ) { return 0; } + + class c_map { + HANDLE m_handle; + std::vector< void* > m_allocations; + std::vector< uint8_t > m_inject_data; + void* m_allocation; + + void write( uintptr_t address, void* data, size_t size ); + uintptr_t allocate( size_t size ); + + void free_allocated_regions( ); + public: + c_map( std::vector< uint8_t >& file ) : m_inject_data( file ) { }; + ~c_map( ) { if( m_handle ) { CloseHandle( m_handle ); } } + + void initialize( int process_id ); + void initialize( HANDLE process ); + void inject( uintptr_t interfaces ); + }; +} \ No newline at end of file diff --git a/legacy/loader/math.hpp b/legacy/loader/math.hpp new file mode 100644 index 0000000..bebe7d5 --- /dev/null +++ b/legacy/loader/math.hpp @@ -0,0 +1,60 @@ +#pragma once +#include +#include "util.hpp" + +static constexpr long double M_PI = 3.14159265358979323846f; +static constexpr long double M_RADPI = 57.295779513082f; +static constexpr long double M_PIRAD = 0.01745329251f; +static constexpr float M_PI_F = ( ( float )( M_PI ) ); +__forceinline float RAD2DEG( float x ) { return( ( float )( x ) * ( float )( 180.f / M_PI_F ) ); } +__forceinline float DEG2RAD( float x ) { return( ( float )( x ) * ( float )( M_PI_F / 180.f ) ); } + +namespace { + //make a random generator and seed it with a p random number + static std::random_device rd; + static std::mt19937 gen( rd( ) ); +} + +NAMESPACE_REGION( math ) + +#undef min +#undef max + +template < typename t > +t min( const t& t1, const t& t2 ) { + return t1 < t2 ? t1 : t2; +} + +template < typename t, typename... ts_ > +t min( const t& t1, const t& t2, ts_&&... ts ) { + return t1 < t2 ? + min( t1, std::forward< ts_ >( ts )... ) : + min( t2, std::forward< ts_ >( ts )... ); +} + +template < typename t > +t max( const t& t1, const t& t2 ) { + return t1 > t2 ? t1 : t2; +} + +template < typename t, typename... ts_ > +t max( const t& t1, const t& t2, ts_&&... ts ) { + return t1 > t2 ? + max( t1, std::forward< ts_ >( ts )... ) : + max( t2, std::forward< ts_ >( ts )... ); +} + +// todo - dex; make 2 random generator funcs here, this one only works for floats normally + +template < typename t > __forceinline t random_number( t min, t max ) { + if constexpr( !std::is_integral_v< t > ) { + std::uniform_real_distribution< t > dist( min, max ); + return dist( gen ); + } + else { + std::uniform_int_distribution< t > dist( min, max ); + return dist( gen ); + } +} + +END_REGION \ No newline at end of file diff --git a/legacy/loader/strings.hpp b/legacy/loader/strings.hpp new file mode 100644 index 0000000..569f9a0 --- /dev/null +++ b/legacy/loader/strings.hpp @@ -0,0 +1,163 @@ +//-------------------------------------------------------------------------------- +//-- XorCompileTime.hpp +// +// Author: frk +// Date: 12.12.2015 +// +//-------------------------------------------------------------------------------- + +#pragma once +#include +#include +#include + +#define BEGIN_NAMESPACE( x ) namespace x { +#define END_NAMESPACE } + +BEGIN_NAMESPACE( strenc ) + +constexpr auto time = __TIME__; +constexpr auto seed = static_cast< int >( time[ 7 ] ) + static_cast< int >( time[ 6 ] ) * 10 + static_cast< int >( time[ 4 ] ) * 60 + static_cast< int >( time[ 3 ] ) * 600 + static_cast< int >( time[ 1 ] ) * 3600 + static_cast< int >( time[ 0 ] ) * 36000; + +// 1988, Stephen Park and Keith Miller +// "Random Number Generators: Good Ones Are Hard To Find", considered as "minimal standard" +// Park-Miller 31 bit pseudo-random number generator, implemented with G. Carta's optimisation: +// with 32-bit math and without division + +template < int N > +struct RandomGenerator { +private: + static constexpr unsigned a = 16807; // 7^5 + static constexpr unsigned m = 2147483647; // 2^31 - 1 + + static constexpr unsigned s = RandomGenerator< N - 1 >::value; + static constexpr unsigned lo = a * ( s & 0xFFFF ); // Multiply lower 16 bits by 16807 + static constexpr unsigned hi = a * ( s >> 16 ); // Multiply higher 16 bits by 16807 + static constexpr unsigned lo2 = lo + ( ( hi & 0x7FFF ) << 16 ); // Combine lower 15 bits of hi with lo's upper bits + static constexpr unsigned hi2 = hi >> 15; // Discard lower 15 bits of hi + static constexpr unsigned lo3 = lo2 + hi; + +public: + static constexpr unsigned max = m; + static constexpr unsigned value = lo3 > m ? lo3 - m : lo3; +}; + +template <> +struct RandomGenerator< 0 > { + static constexpr unsigned value = seed; +}; + +template < int N, int M > +struct RandomInt { + static constexpr auto value = RandomGenerator< N + 1 >::value % M; +}; + +template < int N > +struct RandomChar { + static const char value = static_cast< char >( 1 + RandomInt< N, 0x7F - 1 >::value ); +}; + +template < size_t N, int K > +struct XorString { +private: + const char _key; + std::array< char, N + 1 > _encrypted; + bool decrypted = false; + + constexpr char enc( char c ) const { + return c ^ _key; + } + + char dec( char c ) const { + return c ^ _key; + } + +public: + template < size_t... Is > + constexpr __forceinline XorString( const char* const str, std::index_sequence< Is... > ) : _key( RandomChar< K >::value ), _encrypted{ enc( str[ Is ] )... } { + } + + __forceinline const char* decrypt( void ) { + if( !decrypted ) { + for( size_t i = 0; i < N; ++i ) { + _encrypted[ i ] = dec( _encrypted[ i ] ); + } + _encrypted[ N ] = '\0'; + decrypted = true; + } + + return _encrypted.data( ); + } +}; + +//-------------------------------------------------------------------------------- +//-- Note: XorStr will __NOT__ work directly with functions like printf. +// To work with them you need a wrapper function that takes a const char* +// as parameter and passes it to printf and alike. +// +// The Microsoft Compiler/Linker is not working correctly with variadic +// templates! +// +// Use the functions below or use std::cout (and similar)! +//-------------------------------------------------------------------------------- + +#if( 1 ) +static auto w_printf = [ ]( const char* fmt, ... ) { + va_list args; + va_start( args, fmt ); + vprintf_s( fmt, args ); + va_end( args ); +}; + +static auto w_printf_s = [ ]( const char* fmt, ... ) { + va_list args; + va_start( args, fmt ); + vprintf_s( fmt, args ); + va_end( args ); +}; + +static auto w_sprintf = [ ]( char* buf, const char* fmt, ... ) { + va_list args; + va_start( args, fmt ); + vsprintf( buf, fmt, args ); + va_end( args ); +}; + +static auto w_sprintf_s = [ ]( char* buf, size_t buf_size, const char* fmt, ... ) { + va_list args; + va_start( args, fmt ); + vsprintf_s( buf, buf_size, fmt, args ); + va_end( args ); +}; +#endif + +//for compatibility with debug mode +struct debug_ret { +private: + const char* ret; + +public: + debug_ret( const char* str ) : ret( str ) { }; + + auto decrypt( ) { + return ret; + } +}; + +constexpr size_t strlen_ct( const char* const str ) { + size_t out = 1; + + for( ; str[ out ] != '\0'; ++out ); + + return out; +} + +#if 1 +#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 +#define xors_raw( s ) ( [ ]{ strenc::debug_ret ret{ s }; return ret; }( ) ) +#define xors( s ) ( s ) +#endif + +END_NAMESPACE \ No newline at end of file diff --git a/legacy/loader/syscall.h b/legacy/loader/syscall.h new file mode 100644 index 0000000..0f608ba --- /dev/null +++ b/legacy/loader/syscall.h @@ -0,0 +1,167 @@ +#pragma once +#include + +#include "x86.h" + +using ulong_t = unsigned long; + +constexpr bool is86 = sizeof( uintptr_t ) == sizeof( uint32_t ); + +class c_syscalls { +protected: + std::unordered_map< std::string, std::pair< uint16_t, uint16_t > > m_syscalls; + + // 16 is very arbitrary... but whatever + // if something crashes this is why + __forceinline size_t syscall_wrapper_size( uint8_t* funptr, uint16_t *ret_c_out ) { + for ( size_t offset{ }; offset < 0x30; offset++ ) { + if ( funptr[ offset ] == x86::instruction::retn ) { + if ( ret_c_out ) + *ret_c_out = 0; + + return offset + 1; + } + else if ( funptr[ offset ] == x86::instruction::retn_imm16 ) { + if ( ret_c_out ) + *ret_c_out = *( uint16_t * )( &funptr[ offset + 1 ] ); + + return offset + 3; + } + } + return 0; + } + + __forceinline bool is_syscall( uint8_t* funptr, size_t func_size ) { + const uint32_t encoded_opcode = x86::encode_mov_imm32( x86::reg::eax ); + + if ( /*is86*/ true ? funptr[ 0 ] != encoded_opcode : !( funptr[ 0 ] == 0x4c && funptr[ 1 ] == 0x8b && funptr[ 2 ] == 0xd1 ) ) + return false; + + for ( size_t offset{ }; offset < func_size; offset++ ) { + if ( true /*is86*/ ) { + if ( ( funptr[ offset ] == x86::instruction::fs && // win7 + funptr[ offset + 1 ] == x86::instruction::call ) || + + ( funptr[ offset ] == x86::instruction::call && // win10 + funptr[ offset + 1 ] == 0xd2 /*call edx*/ ) ) + + return true; + + } + + else { + if ( funptr[ offset ] == 0x0f && // win7 + win10 + funptr[ offset + 1 ] == 0x05 ) + return true; + } + } + + return false; + } + + __forceinline uint16_t get_syscall_index( uintptr_t func_addr, std::ptrdiff_t *stub_offset = nullptr, uint16_t *ret_c_out = nullptr ) { + uint8_t* ubp_addr = reinterpret_cast< uint8_t* >( func_addr ); + uint16_t ret_c{ }; + size_t wrapper_size = syscall_wrapper_size( ubp_addr, &ret_c ); + + if ( ret_c_out ) + *ret_c_out = ret_c; + + wrapper_size = ( wrapper_size ) ? wrapper_size : 16; + + if ( is_syscall( ubp_addr, wrapper_size ) ) { + // mov eax, imm32 + const uint32_t encoded_opcode = x86::encode_mov_imm32( x86::reg::eax ); + + for ( size_t offset{ }; offset < wrapper_size; offset++ ) { + if ( *reinterpret_cast< uint8_t* >( func_addr + offset ) == encoded_opcode ) { + if ( stub_offset ) + *stub_offset = offset; + + return ( *reinterpret_cast< uint16_t* >( func_addr + offset + 1 ) ); + } + } + } + + return 0; + } + + std::pair< uint8_t*, size_t > m_shellcode_stub; + void *m_call_table; +public: + + __forceinline ~c_syscalls( ) { + if ( m_call_table ) + delete[ ] m_call_table; + + if ( m_shellcode_stub.first ) + delete[ ] m_shellcode_stub.first; + } + + __forceinline c_syscalls( ) : + m_syscalls{ }, m_shellcode_stub{ } { + + init( ); + + // b1gr0fl + m_call_table = new char[ 0x100000 ]; + util::set( m_call_table, 0, 0x100000 ); + + if ( true /*x86*/ ) { + for ( auto& syscall : m_syscalls ) { + void *stub_addr = ( void* )( uintptr_t( m_call_table ) + ( syscall.second.first * m_shellcode_stub.second ) ); + util::copy( stub_addr, m_shellcode_stub.first, m_shellcode_stub.second ); + + std::ptrdiff_t index_offset{ }; + get_syscall_index( ( uintptr_t )stub_addr, &index_offset ); + + auto stub_return = ( uint16_t * )( uintptr_t( stub_addr ) + m_shellcode_stub.second - 2 ); + *stub_return = syscall.second.second; + + *( uint32_t * )( uintptr_t( stub_addr ) + index_offset + 1 ) = ( syscall.second.first ); + + } + } + } + + __forceinline void init( ) { + uint32_t index; + uint16_t ret_c{ }; + + if ( g_nt.m_exports.empty( ) ) { + g_nt.dump_exports( ); + } + + for ( const auto& exp : g_nt.m_exports ) { + index = get_syscall_index( exp.second, nullptr, &ret_c ); + + if ( index ) { + m_syscalls[ exp.first ].first = index; + m_syscalls[ exp.first ].second = ret_c; + + if ( !m_shellcode_stub.first ) { + m_shellcode_stub.second = syscall_wrapper_size( reinterpret_cast< uint8_t* >( exp.second ), &ret_c ); + + m_shellcode_stub.first = new uint8_t[ m_shellcode_stub.second ]; + + m_syscalls[ exp.first ].second = ret_c; + + util::copy( m_shellcode_stub.first, reinterpret_cast< void* >( exp.second ), m_shellcode_stub.second ); + } + } + } + } + + template< typename t = void* > + __forceinline t get_syscall_func( std::string name ) { + return ( t )( GetProcAddress( GetModuleHandleA( "ntdll.dll" ), name.c_str( ) ) ); + } + + __forceinline uint16_t get_syscall( std::string name ) { + return m_syscalls[ name ].first; + } + + __forceinline auto& get_syscalls( ) { + return m_syscalls; + } +}; \ No newline at end of file diff --git a/legacy/loader/ui.h b/legacy/loader/ui.h new file mode 100644 index 0000000..a6874f5 --- /dev/null +++ b/legacy/loader/ui.h @@ -0,0 +1,123 @@ +#pragma once +#include "ui_base_item.h" +#include "ui_menu.h" +#include "ui_form.h" +#include "ui_render.h" +#include "ui_checkbox.h" +#include "ui_tab_manager.h" +#include "ui_slider.h" +#include "ui_dropdown.h" +#include "ui_key_picker.h" +#include "ui_button.h" +#include "ui_color_picker.h" +#include "ui_label.h" +#include "ui_text_input.h" +#include "ui_progressbar.h" + +char g_login[ 32 ]; +int g_game = 1; +float g_progress = 0.f; + +enum { + STATUS_LOGIN, + STATUS_LOGGING_IN, + STATUS_LOGGED_IN, + STATUS_LOADING, +}; + +int g_status = STATUS_LOGIN; + +extern void execute_login( ); + +enum { + GAME_UNSAFE = 0, + GAME_SAFE = 1, +}; + +struct game_t { + int status; + char name[ 32 ]; + bool valid_sub; +}; + + +std::vector< game_t > games = { + { GAME_SAFE, xors( "csgo" ), true }, + { GAME_UNSAFE, xors( "csgo ( beta )" ), false } +}; + + +//fill this vector when receiving game data based on the one above (this is just a test sample one) +std::vector< ui::dropdowns::dropdown_item_t< int > > game_list = { + { xors( "csgo" ), 1 }, + { xors( "csgo ( beta )" ), 2 }, +}; + +namespace ui +{ + auto menu = std::make_shared< ui::c_menu >( 0, 0, 500, 400, xors( "moneybot" ), "" ); + + static void render( ) { + static bool was_setup = false; + if( !was_setup ) { + menu = std::make_shared< ui::c_menu >( 0, 0, 450, 375, xors( "moneybot" ), "" ); + + auto login_form = menu->add_item( std::make_shared< ui::c_form >( 120, 20, 190, + 115, xors( "login" ) ) ); { + login_form->add_item( std::make_shared< ui::c_text_input >( 15, 0, 140, xors( "username" ), 32, g_login, true ) ); + login_form->add_item( std::make_shared< ui::base_item >( 0, 0, 0, 3 ) ); + login_form->add_item( std::make_shared< ui::c_button >( 15, 0, 140, 18, xors( "submit" ), [ ]( ) { + g_status = STATUS_LOGGING_IN; + /* + execute your code to log in here + */ + } ) ); + } + + login_form->set_cond( [ ]( ) { return g_status == STATUS_LOGIN; } ); + + auto logging_in_form = menu->add_item( std::make_shared< ui::c_form >( 120, 20, 190, 115, xors( "logging in" ) ) ); { + logging_in_form->add_item( std::make_shared< ui::c_label >( 54, 39, xors( "please wait." ) ) ); + } + + logging_in_form->set_cond( [ ]( ) { return g_status == STATUS_LOGGING_IN; } ); + + auto games_form = menu->add_item( std::make_shared< ui::c_form >( 120, 20, 190, 115, xors( "inject" ) ) ); { + games_form->add_item( std::make_shared< ui::c_dropdown< > >( 15, 0, 140, xors( "game" ), &g_game, &game_list ) ); + games_form->add_item( std::make_shared< ui::c_button >( 15, 0, 140, 18, xors( "inject" ), [ ]( ) { + g_status = STATUS_LOADING; + /* + execute your code to inject here + */ + } ) ); + + games_form->add_item( std::make_shared< ui::c_label >( 15, 0, xors( "subscription: active" ) ) )->set_cond( [ ]( ) { return games.at( g_game - 1 ).valid_sub; } ); + games_form->add_item( std::make_shared< ui::c_label >( 15, 0, xors( "subscription: inactive" ) ) )->set_cond( [ ]( ) { return !games.at( g_game - 1 ).valid_sub; } ); + games_form->add_item( std::make_shared< ui::c_label >( 15, 0, xors( "status: safe" ) ) )->set_cond( [ ]( ) { return games.at( g_game - 1 ).status == GAME_SAFE; } ); + games_form->add_item( std::make_shared< ui::c_label >( 15, 0, xors( "status: unsafe" ) ) )->set_cond( [ ]( ) { return games.at( g_game - 1 ).status == GAME_UNSAFE; } ); + } + + games_form->set_cond( [ ]( ) { return g_status == STATUS_LOGGED_IN; } ); + + auto loading_form = menu->add_item( std::make_shared< ui::c_form >( 120, 20, 190, 115, xors( "loading" ) ) ); { + loading_form->add_item( std::make_shared< ui::c_label >( 54, 39, xors( "please wait." ) ) ); + } + + loading_form->set_cond( [ ]( ) { return g_status == STATUS_LOADING; } ); + + menu->add_item( std::make_shared< ui::c_button >( 393, 208, 50, 18, xors( "exit" ), [ ]( ) { exit( 0 ); } ) ); + + was_setup = true; + } + else { + render_item( menu.get( ) ); + static float loading_time; + if( g_status == STATUS_LOGGING_IN && !loading_time ) { + loading_time = GetTickCount( ) * 0.001f + 2.f; + } + else if( g_status == STATUS_LOGGING_IN && GetTickCount( ) * 0.001f > loading_time ) { + g_status = STATUS_LOGGED_IN; + } + } + } +} \ No newline at end of file diff --git a/legacy/loader/ui_base_item.h b/legacy/loader/ui_base_item.h new file mode 100644 index 0000000..f33a21e --- /dev/null +++ b/legacy/loader/ui_base_item.h @@ -0,0 +1,164 @@ +#pragma once +#include +#include +#include + +#include "ui_draw.h" + +namespace ui +{ + //the offset between each item + constexpr int ITEM_OFFSET = 5; + + class base_item : public std::enable_shared_from_this< base_item > { + public: + base_item( ) { } + base_item( int x, int y, int w, int h, const char* name = nullptr ) : + m_x( x ), m_y( y ), m_width( w ), m_height( h ) { + if( name ) { + strcpy_s< 256 >( m_text, name ); + } + } + + virtual void render( ) { }; + virtual bool is_hovered( ) { return false; } + virtual bool is_form( ) const { return false; } + + virtual void reset( ) { + m_y_offset = 0; + } + + virtual int get_total_height( ) const { + return m_height; + } + + void set_y_offset( int offset ) { + m_y_offset = offset; + } + + int get_y_offset( ) const { + return m_y_offset; + } + + auto add_item( std::shared_ptr< base_item > item ) { + item.get( )->m_parent = shared_from_this( ); + m_items.emplace( m_items.begin( ), item ); + + return item; + } + + auto& get_items( ) { return m_items; } + auto get_parent( ) { return m_parent; } + + virtual int x( ) const { return m_x; } + virtual int y( ) const { return m_y; } + virtual int w( ) const { return m_width; } + virtual int h( ) const { return m_height; } + + void set_x( int x ) { m_x = x; } + void set_y( int y ) { m_y = y; } + + void set_width( int w ) { m_width = w; } + void set_height( int h ) { m_height = h; } + + bool get_visible( ) const { + if( m_cond && !m_cond( ) ) { + return false; + } + + return m_visible; + } + + void set_cond( std::function< bool( ) > func ) { + m_cond = func; + } + + void set_visible( bool vis ) { m_visible = vis; } + void set_text( const char* text ) { + strcpy_s< 256 >( m_text, text ); + } + auto get_text( ) const { + return m_text; + } + + std::shared_ptr< base_item > find_item( const char* name ) { + if( !m_items.empty( ) ) { + for( auto& it : m_items ) { + if( it->get_text( ) && !strcmp( it->get_text( ), name ) ) { + return it; + } + + auto it_find = it->find_item( name ); + if( it_find != it ) return it_find; + } + } + + return shared_from_this( ); + } + + auto get_top_parent( ) { + for( auto parent = m_parent; ; + parent = parent->get_parent( ) ) { + if( !parent->get_parent( ) ) { + return parent; + } + } + + return shared_from_this( ); + } + + int get_relative_x( ) { + int x = m_x; + for( auto parent = get_parent( ); !!parent; + parent = parent->get_parent( ) ) { + x += parent->x( ); + } + + return x; + } + + int get_relative_y( ) { + int y = m_y + get_y_offset( ); + for( auto parent = get_parent( ); !!parent; + parent = parent->get_parent( ) ) { + y += parent->y( ) + parent->get_y_offset( ); + } + + return y; + } + + void set_disabled( bool disabled ) { + m_disabled = disabled; + + for( auto& it : m_items ) { + it->set_disabled( disabled ); + } + } + + void set_disabled_callbacks( bool disabled ) { + auto top = get_top_parent( ); + + top->set_disabled( disabled ); + + m_disabled = false; + } + + protected: + int m_x{ }; + int m_y{ }; + + int m_width{ }; + int m_height{ }; + + //current y position for rendering + int m_y_offset{ }; + + bool m_visible = true; + bool m_disabled = false; + char m_text[ 256 ]{ }; + + std::shared_ptr< base_item > m_parent; + std::vector< std::shared_ptr< base_item > > m_items; + std::function< bool( ) > m_cond; + }; +} \ No newline at end of file diff --git a/legacy/loader/ui_button.h b/legacy/loader/ui_button.h new file mode 100644 index 0000000..022fc67 --- /dev/null +++ b/legacy/loader/ui_button.h @@ -0,0 +1,56 @@ +#pragma once + +#include + +#include "ui_base_item.h" + +namespace ui +{ + class c_button : public base_item { + public: + c_button( int x, int y, int w, int h, const char* name, std::function< void( ) > fn ) : + base_item( x, y, w, h, name ), m_fn( fn ) { } + + virtual bool is_hovered( ) override { + if ( m_disabled ) return false; + + int x = get_relative_x( ); + int y = get_relative_y( ); + int h = m_height; + + int mouse_x, mouse_y; + ui_get_cursor_pos( mouse_x, mouse_y ); + + + return mouse_x >= x && mouse_x <= x + m_width + && mouse_y >= y && mouse_y <= y + h; + } + + + virtual void render( ) override { + int x = get_relative_x( ); + int y = get_relative_y( ); + + ui_draw_rect( x, y, m_width, m_height, ui_get_disabled_col( ) ); + ui_draw_outlined_rect( x - 1, y - 1, m_width + 1, m_height + 1, + is_hovered( ) ? ui_get_text_col( ) : ui_get_accent_col( ) ); + + if ( is_hovered( ) && g_input.is_key_pressed( KEYS_MOUSE1 ) ) { + ui_draw_rect( x, y, m_width, m_height, ui_get_bg_col( ) ); + if ( !m_mouse_held ) { + m_fn( ); + } + m_mouse_held = true; + } + else { + m_mouse_held = false; + } + + ui_draw_string( x + m_width / 2, y + 2, true, ui_get_text_col( ), m_text ); + } + + protected: + std::function< void( ) > m_fn; + bool m_mouse_held{ }; + }; +} \ No newline at end of file diff --git a/legacy/loader/ui_checkbox.h b/legacy/loader/ui_checkbox.h new file mode 100644 index 0000000..50cad1c --- /dev/null +++ b/legacy/loader/ui_checkbox.h @@ -0,0 +1,68 @@ +#pragma once +#include "ui_base_item.h" + +namespace ui +{ + class c_checkbox : public base_item { + public: + c_checkbox( int x, int y, const char* txt, bool* setting ) : + base_item( x, y, 16, 16, txt ), m_setting( setting ) { } + + virtual bool is_hovered( ) override { + if ( m_disabled ) return false; + + int mouse_x, mouse_y; + ui_get_cursor_pos( mouse_x, mouse_y ); + + int rel_x = get_relative_x( ); + int rel_y = get_relative_y( ); + + return mouse_x >= rel_x && mouse_x <= rel_x + m_width + && mouse_y >= rel_y && mouse_y <= rel_y + m_height; + } + + inline void render_checkbox( const int& x, const int& y ) { + clr_t col = ui_get_bg_col( ); + if ( is_hovered( ) ) { + col = *m_setting ? ui_get_accent_col( ) * 0.8f : ui_get_bg_col( ) * 1.3f; + } + else if ( *m_setting ) { + col = ui_get_accent_col( ); + } + + ui_draw_rect( x, y, m_width, m_height, ui_get_disabled_col( ) ); + ui_draw_rect( x + 1, y + 1, m_width - 2, m_height - 2, col ); + + //ui_draw_outlined_rect( x, y, m_width, m_height, ui_get_accent_col( ) ); + } + + inline void input( ) { + bool mouse_presesed = g_input.is_key_pressed( KEYS_MOUSE1 ); + + if ( is_hovered( ) && mouse_presesed ) { + if ( !m_mouse_held ) { + *m_setting = !*m_setting; + } + m_mouse_held = true; + } + else { + m_mouse_held = false; + } + } + + virtual void render( ) override { + int x = get_relative_x( ); + int y = get_relative_y( ); + + render_checkbox( x, y ); + input( ); + + + ui_draw_string( x + m_width + 6, y + 2, false, ui_get_text_col( ), m_text ); + } + + protected: + bool* m_setting; + bool m_mouse_held{ }; + }; +} \ No newline at end of file diff --git a/legacy/loader/ui_color_picker.h b/legacy/loader/ui_color_picker.h new file mode 100644 index 0000000..2711d29 --- /dev/null +++ b/legacy/loader/ui_color_picker.h @@ -0,0 +1,201 @@ +#pragma once + +#include "ui_base_item.h" +#include "d3d.hpp" + +namespace ui +{ + class c_color_picker : public base_item { + static constexpr int BOX_WIDTH = 106; + static constexpr int BOX_HEIGHT = 125; + public: + c_color_picker( int x, int y, int w, const char* name, clr_t* setting ) : + base_item( x, y, w, 4, name ), m_setting( setting ), + m_has_text( true ) { } + + c_color_picker( int x, int y, int w, clr_t* setting ) : + base_item( x, y, w, 8, xors( "COLOR_PICKER" ) ), m_setting( setting ), + m_has_text( false ) { } + + virtual bool is_hovered( ) override { + if ( m_disabled ) return false; + + int x = get_relative_x( ); + int y = get_relative_y( ); + + int cursor_x, cursor_y; + ui_get_cursor_pos( cursor_x, cursor_y ); + + if ( m_has_text ) y += 12; + + if ( !m_active ) { + return cursor_x >= x && cursor_x <= x + m_width + && cursor_y >= y && cursor_y <= y + m_height; + } + + return cursor_x >= x && cursor_x <= x + BOX_WIDTH + 23 + && cursor_y >= y && cursor_y <= y + BOX_HEIGHT + 2; + } + + virtual int get_total_height( ) const override { + return m_has_text ? ( m_height + 12 ) : m_height; + } + + void input( ) { + bool active_backup = m_active; + bool active_changed = false; + + if ( is_hovered( ) && g_input.is_key_pressed( KEYS_MOUSE1 ) ) { + if ( !m_active ) { + m_mouse_held = true; + } + + m_active = true; + } + else if ( m_active && !is_hovered( ) && g_input.is_key_pressed( KEYS_MOUSE1 ) ) { + m_active = false; + } + else { + m_mouse_held = false; + } + + active_changed = active_backup != m_active; + if ( active_changed ) { + set_disabled_callbacks( m_active ); + } + + m_hue = m_setting->hue( ); + if ( m_hue > 1.0f ) { + m_hue -= 359.f; + } + + m_saturation = m_setting->saturation( ); + m_brightness = m_setting->brightness( ) / 255.f; + m_alpha = m_setting->a( ); + } + + void output( ) { + *m_setting = clr_t::from_hsb( m_hue, m_saturation, m_brightness ); + m_setting->a( ) = m_alpha; + } + + virtual void render( ) override { + int x = get_relative_x( ); + int y = get_relative_y( ); + + if ( m_has_text ) { + ui_draw_string( x + 2, y, false, ui_get_text_col( ), m_text ); + y += 12; + } + + input( ); + + if ( m_active ) { + RECT old_rect; + g_d3d.get_device( )->GetScissorRect( &old_rect ); + + RECT new_rect{ + x - 1, y - 1, + x + BOX_WIDTH + 22, + y + BOX_HEIGHT + 2 + }; + + g_d3d.get_device( )->SetScissorRect( &new_rect ); + + int mouse_x, mouse_y; + ui_get_cursor_pos( mouse_x, mouse_y ); + + clr_t bg_col( 0, 0, 0, 90 ); + ui_draw_rect( x, y, BOX_WIDTH + 20, BOX_HEIGHT, bg_col ); + ui_draw_outlined_rect( x - 1, y - 1, BOX_WIDTH + 22, BOX_HEIGHT + 2, ui_get_accent_col( ) ); + + for ( int i{ }; i < 100; i += 3 ) { + for ( int i2{ }; i2 < 100; i2 += 3 ) { + ui_draw_rect( x + i + 1, y + i2 + 1, 3, 3, + clr_t::from_hsb( m_hue, float( i2 ) * 0.01f, float( i ) * 0.01f ) ); + } + } + + if ( g_input.is_key_pressed( KEYS_MOUSE1 ) && !m_mouse_held + && mouse_x > x && mouse_x <= x + 100 + && mouse_y > y && mouse_y <= y + 100 ) { + + int mouse_x_c = std::clamp( mouse_x, x, x + 100 ); + int mouse_y_c = std::clamp( mouse_y, y, y + 100 ); + + int delta_y = std::clamp( mouse_y_c - y, 0, 100 ); + int delta_x = std::clamp( mouse_x_c - x, 0, 100 ); + + m_saturation = float( delta_y ) * 0.01f; + m_brightness = float( delta_x ) * 0.01f; + } + + auto is_hue_slider_hovered = [&]( ) -> bool { + return mouse_x > x + 110 && mouse_x < x + 122 + && mouse_y > y && mouse_y < y + 100; + }; + + auto draw_slider_hue = [&]( ) { + for ( int i{ }; i < 100; ++i ) { + auto cur_col = clr_t::from_hsb( float( i ) * 0.01f, m_saturation, m_brightness ); + + ui_draw_rect( x + 110, y + i + 1, 12, 2, cur_col ); + } + + ui_draw_outlined_rect( x + 109, y + int( m_hue * 100.f ) + 1, 14, 3, + is_hue_slider_hovered( ) ? ui_get_text_col( ) : ui_get_disabled_col( ) ); + }; + + auto is_alpha_slider_hovered = [&]( ) -> bool { + return mouse_x > x + 1 && mouse_x < x + 122 + && mouse_y > y + 110 && mouse_y < y + 124; + }; + + auto draw_slider_alpha = [&]( ) { + for ( int i{ 121 }; i >= 0; --i ) { + auto col = *m_setting; + col.a( ) = ( int )( float( i ) * 255.f / 121.f ); + + ui_draw_rect( x + i + 1, y + 110, 1, 12, col ); + } + + int a_pos = ( int )( float( m_alpha ) * 121.f / 255.f ); + ui_draw_outlined_rect( x + 1 + a_pos, y + 109, 3, 14, + is_alpha_slider_hovered( ) ? ui_get_text_col( ) : ui_get_disabled_col( ) ); + }; + + draw_slider_hue( ); + if ( is_hue_slider_hovered( ) && g_input.is_key_pressed( KEYS_MOUSE1 ) ) { + int delta = std::clamp( mouse_y - y, 0, 100 ); + m_hue = float( delta ) * 0.01f; + } + + draw_slider_alpha( ); + if ( is_alpha_slider_hovered( ) && g_input.is_key_pressed( KEYS_MOUSE1 ) ) { + int delta = std::clamp( mouse_x - x, 0, 121 ); + m_alpha = ( int )( float( delta ) * 255.f / 121.f ); + } + + output( ); + + g_d3d.get_device( )->SetScissorRect( &old_rect ); + } + else { + if ( is_hovered( ) ) { + ui_draw_rect( x - 1, y - 1, m_width + 2, m_height + 2, ui_get_text_col( ) ); + } + ui_draw_rect( x, y, m_width, m_height, *m_setting ); + } + } + + protected: + clr_t* m_setting = nullptr; + bool m_active = false; + bool m_mouse_held = false; + float m_saturation = 1.0f; + float m_brightness = 1.0f; + float m_hue = 0.f; + uint8_t m_alpha = 255; + bool m_has_text = false; + }; +} \ No newline at end of file diff --git a/legacy/loader/ui_draw.h b/legacy/loader/ui_draw.h new file mode 100644 index 0000000..46c91de --- /dev/null +++ b/legacy/loader/ui_draw.h @@ -0,0 +1,160 @@ +#pragma once +#include + +#include "color.hpp" +#include "d3d.hpp" +#include "d3d_sprite.hpp" +#include "input_system.hpp" +#include "window.hpp" + +namespace ui +{ + /*__forceinline auto ui_get_background_texture( ) { + static auto buffer = std::make_shared< byte[ 512 ] >( ); + static auto color = D3DCOLOR_RGBA( 27, 27, 27, 233 ); + static auto color_bright = D3DCOLOR_RGBA( 31, 31, 31, 255 ); + static IDirect3DTexture9* texture; + + if ( !texture ) { + for ( int i = 0; i < 512; i += 4 ) { + *( ulong_t* )( uintptr_t( buffer.get( ) ) + i ) = !( i % 12 ) ? color : color_bright; + } + + D3DXCreateTextureFromFileInMemory( g_d3d.get_device( ), buffer.get( ), 512, &texture ); + } + + return texture; + }*/ + + static float anim_time{ }; + + __forceinline void set_animtime( float animtime ) { + anim_time = animtime; + } + + __forceinline void setup_sprites( IDirect3DDevice9* device ) { + //fuck msvc + //icons::sprite_legit.init( device, icons::legit_icon, icons::legit_size, 66, 66 ); + //icons::sprite_visuals_.init( device, icons::legit_icon, icons::legit_size, 66, 66 ); + //icons::sprite_rage.init( device, icons::rage_icon, icons::rage_size, 66, 66 ); + //icons::sprite_visuals.init( device, icons::raw::visuals_raw, icons::visuals_size, 66, 66 ); + //icons::sprite_misc.init( device, icons::misc_icon, icons::misc_size, 66, 66 ); + //icons::sprite_config.init( device, icons::config_icon, icons::config_size, 66, 66 ); + } + + __forceinline clr_t ui_get_accent_col( ) { + static const clr_t col_start = clr_t( 231, 105, 105, 255 ); + static const clr_t col_end = clr_t( 0xf4, 0x7c, 0xa8, 255 ); + + clr_t col = clr_t::blend( col_start, col_end, anim_time ); + + return col; + } + + __forceinline clr_t& ui_get_disabled_col( ) { + static clr_t col = clr_t( 61, 61, 61, 255 ); + return col; + } + + __forceinline clr_t& ui_get_bg_col( ) { + static clr_t col = clr_t( 24, 25, 27, 255 ); + return col; + } + + __forceinline clr_t& ui_get_text_col( ) { + static clr_t col = clr_t( 221, 221, 221, 255 ); + return col; + } + + __forceinline void ui_draw_gradient( int x, int y, int w, int h, clr_t start, + clr_t end, GradientType_t type = GRADIENT_HORIZONTAL ) { + + g_d3d.draw_gradient( start, end, x, y, w, h, type ); + } + + __forceinline void ui_draw_line( int x, int y, int x1, int y1, clr_t color ) { + g_d3d.draw_line( color, x, y, x1, y1 ); + } + + __forceinline void ui_draw_rect( int x, int y, int w, int h, clr_t color ) { + g_d3d.draw_filled_rect( color, x, y, w, h ); + } + + __forceinline void ui_draw_outlined_rect( int x, int y, int w, int h, clr_t color ) { + g_d3d.draw_rect( color, x, y, w, h ); + } + + __forceinline void ui_draw_circle( int x, int y, int r, clr_t color, int res = 48 ) { + g_d3d.draw_circle( color, x, y, r, res ); + } + + __forceinline void ui_draw_filled_circle( int x, int y, int r, clr_t color, int res = 48 ) { + g_d3d.draw_filled_circle( color, x, y, r, res ); + } + + __forceinline void ui_draw_string( int x, int y, bool center, clr_t color, const char* str, ... ) { + char buf[ 2048 ]{ }; + va_list list{ }; + + __crt_va_start( list, str ); + vsprintf_s( buf, 2048, str, list ); + __crt_va_end( list ); + + g_d3d.draw_text( d3d::fonts.f_menu, color, x, y, + center ? ALIGN_CENTER : ALIGN_LEFT, D3DFONTFLAG_DROPSHADOW, buf ); + } + + __forceinline void ui_get_text_size( int& w, int& h, const char* text, ... ) { + char* buf = ( char* )_alloca( 2048 ); + va_list list{ }; + + __crt_va_start( list, text ); + vsprintf_s( buf, 2048, text, list ); + __crt_va_end( list ); + + w = g_d3d.get_text_width( d3d::fonts.f_menu, 0, buf ); + h = g_d3d.get_text_height( d3d::fonts.f_menu, 0, buf ); + } + + __forceinline void ui_get_cursor_pos( int& x, int& y ) { + POINT p; + GetCursorPos( &p ); + ScreenToClient( g_window.get_hwnd( ), &p ); + x = p.x; y = p.y; + } + + __forceinline float ui_get_frametime( ) { + return 0.0152f; + //return g_csgo.m_frametime; + } + + __forceinline void ui_draw_cursor( ) { + const clr_t black( 0, 0, 0, 255 ), accent( ui_get_accent_col( ) ); + int x, y; + ui_get_cursor_pos( x, y ); + + + for ( int i{ }; i <= 9; ++i ) { + ui_draw_line( x, y, x + i, y + 11, accent ); + } + + for ( int i{ }; i <= 7; ++i ) { + ui_draw_line( x, y + 9 + i, x + i, y + 9, accent ); + } + + for ( int i{ }; i <= 3; ++i ) { + ui_draw_line( x + 6 + i, y + 11, x, y + i, accent ); + } + + ui_draw_line( x + 5, y + 11, x + 8, y + 18, accent ); + ui_draw_line( x + 4, y + 11, x + 7, y + 18, accent ); + + ui_draw_line( x, y, x, y + 17, black ); + ui_draw_line( x, y + 17, x + 3, y + 14, black ); + ui_draw_line( x + 4, y + 14, x + 7, y + 19, black ); + ui_draw_line( x + 7, y + 18, x + 9, y + 18, black ); + ui_draw_line( x + 10, y + 18, x + 7, y + 12, black ); + ui_draw_line( x + 7, y + 12, x + 11, y + 12, black ); + ui_draw_line( x + 11, y + 12, x, y, black ); + } +} \ No newline at end of file diff --git a/legacy/loader/ui_dropdown.h b/legacy/loader/ui_dropdown.h new file mode 100644 index 0000000..ea626bc --- /dev/null +++ b/legacy/loader/ui_dropdown.h @@ -0,0 +1,217 @@ +#pragma once +#include "ui_dropdown_item.h" + +namespace ui +{ + template < typename t = int > + class c_dropdown : public base_item { + public: + c_dropdown( int x, int y, int w, const char* name, t* setting, + std::vector< dropdowns::dropdown_item_t< t > >* items, size_t max_items = 8 ) : + base_item( x, y, w, 16, name ), m_dropdown_items( items ), m_setting( setting ), + m_max_items( max_items ) { } + + virtual bool is_hovered( ) override { + if ( m_disabled ) return false; + + int x = get_relative_x( ); + int y = get_relative_y( ) + 12; + int h = m_height; + + int mouse_x, mouse_y; + ui_get_cursor_pos( mouse_x, mouse_y ); + + + return mouse_x >= x && mouse_x <= x + m_width + && mouse_y >= y && mouse_y <= y + h; + } + + inline bool is_any_item_hovered( ) { + if ( m_disabled || !m_active ) return false; + + int x = get_relative_x( ); + int y = get_relative_y( ) + m_height + 12; + int h = m_height * ( std::min< size_t >( + m_dropdown_items->size( ), m_max_items ) ); + + int mouse_x, mouse_y; + ui_get_cursor_pos( mouse_x, mouse_y ); + + + return mouse_x >= x && mouse_x <= x + m_width + && mouse_y >= y && mouse_y <= y + h; + } + + virtual int get_total_height( ) const override { + return m_height + 13; + } + + void draw_box( const int& x, const int& y, const char* str, bool hovered = false ) { + ui_draw_rect( x, y, m_width, m_height, hovered ? ui_get_disabled_col( ) : ui_get_bg_col( ) ); + ui_draw_line( x, y + m_height, x + m_width, y + m_height, ui_get_accent_col( ) ); + + ui_draw_string( x + m_width / 2, y + 2, true, ui_get_text_col( ), str ); + } + + void update_value( ) { + for ( auto& it : *m_dropdown_items ) { + if ( it.m_value == *m_setting ) { + m_selected_item = ⁢ + } + } + } + + void draw_items( const int& x, const int& y ) { + auto& items = *m_dropdown_items; + auto it = &items.front( ); + int offset = m_height + 1; + int hovered = 0; + int mouse_x, mouse_y; + ui_get_cursor_pos( mouse_x, mouse_y ); + + auto is_hovered = [ & ] ( int y_offset ) { + return mouse_x >= x && mouse_x <= x + m_width + && mouse_y >= y + y_offset && mouse_y <= y + y_offset + m_height; + }; + + + for ( size_t i = items.size( ) > m_max_items ? m_curr_scroll : 0; + i < std::min< size_t >( m_dropdown_items->size( ), m_max_items + m_curr_scroll ); + ++i, offset += m_height + 1 + ) { + it = &items.at( i ); + + draw_box( x, y + offset, it->m_name ); + + if ( is_hovered( offset ) ) { + hovered = offset; + if ( g_input.is_key_pressed( KEYS_MOUSE1 ) ) { + m_selected_item = it; + *m_setting = it->m_value; + m_active = false; + m_enable_time = GetTickCount( ) * 0.001f + 0.220f; + m_enable_next_frame = true; + } + } + } + + if ( hovered ) { + ui_draw_outlined_rect( x - 1, y - 1 + hovered, + m_width + 1, m_height + 1, ui_get_text_col( ) ); + } + } + + void input( ) { + bool active_backup = m_active; + bool active_changed = false; + + if ( is_hovered( ) && g_input.is_key_pressed( KEYS_MOUSE1 ) ) { + if ( !m_mouse_held ) { + m_active = !m_active; + } + m_mouse_held = true; + } + else if ( !is_any_item_hovered( ) ) { + m_mouse_held = false; + } + + if ( !is_hovered( ) && g_input.is_key_pressed( KEYS_MOUSE1 ) && !is_any_item_hovered( ) ) { + m_active = false; + } + + if ( GetTickCount( ) * 0.001f > m_enable_time && m_enable_next_frame ) { + set_disabled_callbacks( false ); + m_enable_next_frame = false; + } + + + active_changed = m_active != active_backup; + //disable input on all items + if ( active_changed ) { + if ( !m_active ) { + m_enable_time = GetTickCount( ) * 0.001f + 0.220f; + m_enable_next_frame = true; + } + else { + set_disabled_callbacks( true ); + } + } + + if ( m_selected_item ) { + *m_setting = m_selected_item->m_value; + } + + if ( m_active && m_dropdown_items->size( ) > m_max_items ) { + int scroll_input = g_input.get_scroll_state( ); + + if ( m_curr_scroll > 0 || scroll_input < 0 ) //we dont want scroll to loop around from 0 to max + m_curr_scroll -= scroll_input; //because positive is scroll up, we gotta flip it + + if ( m_curr_scroll > m_dropdown_items->size( ) - m_max_items ) + m_curr_scroll = m_dropdown_items->size( ) - m_max_items; + } + } + + virtual void render( ) override { + int x = get_relative_x( ); + int y = get_relative_y( ); + + bool restore = false; + RECT prev_rect{ }; + + if ( m_active ) { + restore = true; + g_d3d.get_device( )->GetScissorRect( &prev_rect ); + + RECT new_rect{ + prev_rect.left, + prev_rect.top, + g_d3d.m_width, + g_d3d.m_height, + }; + + g_d3d.get_device( )->SetScissorRect( &new_rect ); + + draw_items( x, y + 11 ); + + + //draw scrollbar + size_t total_items = m_dropdown_items->size( ); + if ( total_items > m_max_items ) { + const size_t height = ( m_height + 1 ) * m_max_items; + const float slider_step = ( float )( height ) / float( total_items - m_max_items + 1 ); + + size_t slider_pos = static_cast< size_t >( slider_step * m_curr_scroll ); + ui_draw_rect( x + m_width - 1, y + slider_pos + m_height + 13, 2, ( int )slider_step, ui_get_accent_col( ) ); + } + } + + update_value( ); + input( ); + + ui_draw_string( x + 2, y, false, ui_get_text_col( ), m_text ); + ui_draw_rect( x, y + 13, m_width, m_height, ui_get_disabled_col( ) ); + ui_draw_outlined_rect( x - 1, y + 12, m_width + 1, m_height + 1, + is_hovered( ) || m_active ? ui_get_text_col( ) : ui_get_accent_col( ) ); + + if ( m_selected_item ) { + ui_draw_string( x + m_width / 2, y + 14, true, ui_get_text_col( ), m_selected_item->m_name ); + } + + if( restore ) { + g_d3d.get_device( )->SetScissorRect( &prev_rect ); + } + } + + protected: + std::vector< dropdowns::dropdown_item_t< t > >* m_dropdown_items{ }; + dropdowns::dropdown_item_t< t >* m_selected_item{ }; + bool m_active = false; + bool m_mouse_held = false; + t* m_setting{ }; + size_t m_max_items{ }; + size_t m_curr_scroll{ }; + float m_enable_time{ }; + int m_enable_next_frame{ }; + }; +} \ No newline at end of file diff --git a/legacy/loader/ui_dropdown_item.h b/legacy/loader/ui_dropdown_item.h new file mode 100644 index 0000000..9ffa60d --- /dev/null +++ b/legacy/loader/ui_dropdown_item.h @@ -0,0 +1,22 @@ +#pragma once + +#include "ui_base_item.h" + +namespace ui +{ + namespace dropdowns + { + template < typename t = int > + struct dropdown_item_t { + const char* m_name; + t m_value; + }; + + std::vector< dropdown_item_t< > > games = { + { xors( "csgo" ), 1 }, + { xors( "csgo (beta)" ), 3 }, + { xors( "tf2" ), 2 }, + { xors( "gmod (beta)" ), 4 } + }; + } +} \ No newline at end of file diff --git a/legacy/loader/ui_form.h b/legacy/loader/ui_form.h new file mode 100644 index 0000000..2fdf6e7 --- /dev/null +++ b/legacy/loader/ui_form.h @@ -0,0 +1,130 @@ +#pragma once +#include "ui_base_item.h" + +namespace ui +{ + class c_form : public base_item { + public: + c_form( int x, int y, int w, int h, const char* name, int max_h = 0 ) : + base_item( x, y, w, h, name ), m_dynamic( !h ), m_max_height( max_h ) { }; + + virtual int x( ) const override { + return m_x + 10; + } + + virtual int y( ) const override { + return m_y + m_scroll_offset + 9; + } + + virtual bool is_form( ) const override { + return true; + } + + virtual bool is_hovered( ) override { + int mouse_x, mouse_y; + ui_get_cursor_pos( mouse_x, mouse_y ); + + int x = get_relative_x( ); + int y = get_relative_y( ); + + return mouse_x > x && mouse_x < x + w( ) + && mouse_y > y && mouse_y < y + h( ); + } + + inline void update_size( ) { + if ( !m_dynamic ) return; + + int total_height{ ITEM_OFFSET * 2 }; + for ( auto& it : m_items ) { + if ( it->get_visible( ) ) { + auto item_height = it->get_total_height( ) + ITEM_OFFSET; + if( m_max_height && total_height + item_height > m_max_height ) { + total_height = m_max_height; + break; + } + total_height += it->get_total_height( ) + ITEM_OFFSET; + } + } + + m_height = total_height; + } + + virtual int get_total_height( ) const override { + return m_height + 5; + } + + int get_total_item_height( ) { + int total_height{ ITEM_OFFSET * 2 }; + for( auto& it : m_items ) { + if( it->get_visible( ) ) { + auto item_height = it->get_total_height( ) + ITEM_OFFSET; + total_height += it->get_total_height( ) + ITEM_OFFSET; + } + } + + return total_height; + } + + void input( ) { + if( m_max_height && get_total_item_height( ) > m_max_height ) { + if( !m_disabled && is_hovered( ) ) { + auto scroll_state = g_input.get_scroll_state( ); + if( !!scroll_state && m_was_hovered ) { + scroll_state > 0 ? m_scroll_offset += 13 : m_scroll_offset -= 13; + } + m_scroll_offset = std::clamp( m_scroll_offset, -( get_total_item_height( ) - m_height + 3 ), 0 ); + } + } + else { + m_scroll_offset = 0; + } + } + + virtual void render( ) override { + update_size( ); + input( ); + int x = get_relative_x( ); + int y = get_relative_y( ); + + int text_w, text_h; + ui_get_text_size( text_w, text_h, m_text ); + + for( int i{ }; i < 8; ++i ) { + clr_t col = ui_get_bg_col( ) * ( 0.72f + i * 0.04f ); + ui_draw_rect( x, y + i, m_width, m_height - i * 2, col ); + } + + ui_draw_outlined_rect( x, y, m_width, m_height, ui_get_accent_col( ) ); + + if( m_max_height && get_total_item_height( ) > m_height ) { + const size_t height = get_total_height( ) - 20; + const float delta = ( float )( get_total_item_height( ) - height + 1 ); + const float slider_step = ( ( float )( height ) / delta ); + const float slider_height = slider_step * 13.f; + + size_t slider_pos = static_cast< size_t >( slider_step * m_scroll_offset ); + ui_draw_rect( x + m_width - 7, y + 8, 4, height, ui_get_disabled_col( ) ); + ui_draw_rect( x + m_width - 7, y - slider_pos + 8, 4, ( int )slider_height + 1, ui_get_accent_col( ) ); + } + + if( is_hovered( ) != m_was_hovered ) { + bool backup = m_disabled; + if( !backup ) { + set_disabled( !is_hovered( ) ); + } + m_disabled = backup; + } + + ui_draw_line( x + 3, y, x + text_w + 1, y, ui_get_bg_col( ) ); + ui_draw_string( x + 3, y - 7, false, ui_get_text_col( ), m_text ); + + m_was_hovered = is_hovered( ); + } + + protected: + bool m_dynamic{ }; + bool m_was_hovered{ }; + int m_max_height{ }; + int m_scroll_offset{ }; + }; +} \ No newline at end of file diff --git a/legacy/loader/ui_key_picker.h b/legacy/loader/ui_key_picker.h new file mode 100644 index 0000000..03aed84 --- /dev/null +++ b/legacy/loader/ui_key_picker.h @@ -0,0 +1,164 @@ +#pragma once +#include "ui_base_item.h" + +namespace ui +{ + class c_key_picker : public base_item { + public: + c_key_picker( int x, int y, int w, const char* name, int* setting ) : + base_item( x, y, w, 16, name ), m_setting( setting ) { } + + virtual bool is_hovered( ) override { + if ( m_disabled ) return false; + + int x = get_relative_x( ); + int y = get_relative_y( ) + 12; + int h = m_height; + + int mouse_x, mouse_y; + ui_get_cursor_pos( mouse_x, mouse_y ); + + + return mouse_x >= x && mouse_x <= x + m_width + && mouse_y >= y && mouse_y <= y + h; + } + + virtual int get_total_height( ) const override { + return m_height + 12; + } + + void input( ) { + bool active_backup = m_active; + bool active_changed = false; + + if ( is_hovered( ) && g_input.is_key_pressed( KEYS_MOUSE1 ) ) { + if ( !m_mouse_held ) { + m_active = true; + } + m_mouse_held = true; + } + + if ( g_input.is_key_pressed( KEYS_ESCAPE ) ) { + m_active = false; + *m_setting = KEYS_NONE; + } + + if ( m_active && !m_mouse_held ) { + int key = g_input.is_any_key_pressed( ); + if ( key != KEYS_NONE ) { + *m_setting = key; + m_active = false; + } + } + + active_changed = active_backup != m_active; + if ( active_changed ) { + set_disabled_callbacks( m_active ); + } + } + + virtual void render( ) override { + int x = get_relative_x( ); + int y = get_relative_y( ); + + input( ); + + ui_draw_string( x + 2, y, false, ui_get_text_col( ), m_text ); + ui_draw_rect( x, y + 13, m_width, m_height, ui_get_disabled_col( ) ); + ui_draw_outlined_rect( x - 1, y + 12, m_width + 1, m_height + 1, + is_hovered( ) || m_active ? ui_get_text_col( ) : ui_get_accent_col( ) ); + + ui_draw_string( x + m_width / 2, y + 14, true, ui_get_text_col( ), + g_input.get_key_name( ( VirtualKeys_t )*m_setting ) ); + } + + protected: + int* m_setting{ }; + bool m_active{ }; + bool m_mouse_held{ }; + }; + + //skEeT PiCkErS + class c_key_picker_small : public base_item { + public: + c_key_picker_small( int x, int y, int* setting ) : + base_item( x, y, 0, 0, xors( "KEY_PICKER" ) ), m_setting( setting ) { } + + virtual int get_total_height( ) const override { + const char* name = g_input.get_short_name( ( VirtualKeys_t )*m_setting ); + int w, h; + ui_get_text_size( w, h, name ); + + return h; + } + + virtual bool is_hovered( ) override { + if ( m_disabled ) return false; + + const char* name = g_input.get_short_name( ( VirtualKeys_t )*m_setting ); + int x = get_relative_x( ); + int y = get_relative_y( ); + int mouse_x, mouse_y; + int w, h; + + ui_get_text_size( w, h, "[%s]", name ); + ui_get_cursor_pos( mouse_x, mouse_y ); + + return mouse_x >= x - w && mouse_x <= x + && mouse_y >= y && mouse_y <= y + h; + } + + void input( ) { + + bool active_backup = m_active; + bool active_changed = false; + + if ( g_input.is_key_pressed( KEYS_ESCAPE ) ) { + m_active = false; + *m_setting = KEYS_NONE; + } + + if ( m_active && !m_mouse_held ) { + int key = g_input.is_any_key_pressed( ); + if ( key != KEYS_NONE ) { + *m_setting = key; + m_active = false; + } + } + + if ( is_hovered( ) && g_input.is_key_pressed( KEYS_MOUSE1 ) ) { + if ( !m_mouse_held ) { + m_active = true; + } + m_mouse_held = true; + } + else { + m_mouse_held = false; + } + + active_changed = active_backup != m_active; + if ( active_changed ) { + set_disabled_callbacks( m_active ); + } + } + + virtual void render( ) override { + const char* name = g_input.get_short_name( ( VirtualKeys_t )*m_setting ); + int x = get_relative_x( ); + int y = get_relative_y( ); + + int w, h; + ui_get_text_size( w, h, "[%s]", name ); + + input( ); + + ui_draw_string( x - w, y, false, is_hovered( ) || m_active ? + ui_get_accent_col( ) : ui_get_text_col( ), "[%s]", name ); + } + + protected: + int* m_setting; + bool m_active{ }; + bool m_mouse_held{ }; + }; +} \ No newline at end of file diff --git a/legacy/loader/ui_label.h b/legacy/loader/ui_label.h new file mode 100644 index 0000000..9df46b5 --- /dev/null +++ b/legacy/loader/ui_label.h @@ -0,0 +1,18 @@ +#pragma once +#include "ui_base_item.h" + +namespace ui +{ + class c_label : public base_item { + public: + c_label( int x, int y, const char* text ) : + base_item( x, y, 0, 16, text ) { } + + virtual void render( ) override { + int x = get_relative_x( ); + int y = get_relative_y( ); + + ui_draw_string( x + 2, y + 2, false, ui_get_text_col( ), m_text ); + } + }; +} \ No newline at end of file diff --git a/legacy/loader/ui_menu.h b/legacy/loader/ui_menu.h new file mode 100644 index 0000000..c7406b5 --- /dev/null +++ b/legacy/loader/ui_menu.h @@ -0,0 +1,104 @@ +#pragma once +#include "ui_base_item.h" + +namespace ui +{ + class c_menu : public base_item { + public: + c_menu( int start_x, int start_y, int width, + int height, const char* name, const char* right_text = nullptr ) : + base_item( start_x, start_y, width, height, name ), + m_right_text( right_text ) { } + + virtual bool is_hovered( ) override { + if ( m_disabled ) return false; + + int mouse_x, mouse_y; + ui_get_cursor_pos( mouse_x, mouse_y ); + + return mouse_x >= m_x && mouse_x <= m_x + w( ) + && mouse_y >= m_y && mouse_y <= m_y + 19; + } + + virtual int y( ) const override { + return m_y + 19; + } + + inline void input( ) { + int mouse_x, mouse_y; + ui_get_cursor_pos( mouse_x, mouse_y ); + bool mouse_clicked = g_input.is_key_pressed( KEYS_MOUSE1 ); + bool window_hovered = GetActiveWindow( ) == g_window.get_hwnd( ); + + RECT cur_rect{ }; + GetWindowRect( g_window.get_hwnd( ), &cur_rect ); + + POINT p{ cur_rect.left, cur_rect.top }; + ScreenToClient( g_window.get_hwnd( ), &p ); + + if( !window_hovered ) { + m_mouse_held = false; + mouse_clicked = false; + return; + } + + if ( is_hovered( ) ) { + m_mouse_held = true; + } + + if ( !mouse_clicked ) { + m_mouse_held = is_hovered( ); + } + + if ( m_mouse_held && !mouse_clicked ) { + m_drag_offset_y = mouse_y - p.y; + m_drag_offset_x = mouse_x - p.x; + } + + if ( m_mouse_held && mouse_clicked ) { + int new_x = mouse_x - m_drag_offset_x + cur_rect.left; + int new_y = mouse_y - m_drag_offset_y + cur_rect.top; + + MoveWindow( g_window.get_hwnd( ), new_x, new_y, 451, 376, true ); + } + } + + virtual void render( ) override { + constexpr auto top_height = 19; + + input( ); + + //draw a c00l shadow + ui_draw_outlined_rect( m_x, m_y + 1, m_width + 1, m_height, clr_t( 0, 0, 0, 166 ) ); + + ui_draw_rect( m_x + 1, m_y + 1, m_width - 1, top_height - 2, ui_get_bg_col( ) * 1.2f ); + if( is_hovered( ) ) { + ui_draw_rect( m_x + 1, m_y + 1, m_width - 1, top_height - 2, clr_t( 61, 61, 61 ) ); + } + + for( int i{ }; i < 8; ++i ) { + clr_t col = ui_get_bg_col( ) * ( 0.72f + i * 0.04f ); + ui_draw_rect( m_x, m_y + i + top_height - 1, m_width, m_height - i * 2 - top_height + 1, col ); + } + ui_draw_outlined_rect( m_x, m_y, m_width, m_height, ui_get_accent_col( ) ); + + if( m_right_text ) { + ui_draw_string( m_x + 5, m_y + 4, false, ui_get_text_col( ), m_text ); + + int width, height; + ui_get_text_size( width, height, m_right_text ); + + ui_draw_string( m_x + m_width - 5 - width, m_y + 4, false, ui_get_text_col( ), m_right_text ); + } + else { + ui_draw_string( m_x + m_width / 2, m_y + 4, true, ui_get_text_col( ), m_text ); + } + } + + protected: + int m_drag_offset_x{ }; + int m_drag_offset_y{ }; + bool m_mouse_held{ }; + const char* m_right_text{ }; + }; +} \ No newline at end of file diff --git a/legacy/loader/ui_progressbar.h b/legacy/loader/ui_progressbar.h new file mode 100644 index 0000000..33bcf65 --- /dev/null +++ b/legacy/loader/ui_progressbar.h @@ -0,0 +1,44 @@ +#pragma once +#include "ui_base_item.h" + +namespace ui +{ + class c_progress_bar : public base_item { + public: + c_progress_bar( int x, int y, int w, float* progress ) : + base_item( x, y, w, 4, xors( "PROGRESS_BAR" ) ), + m_progress( progress ) { } + + + virtual void render( ) override { + static const clr_t col_start = clr_t( 231, 105, 105, 255 ); + static const clr_t col_end = clr_t( 0xf4, 0x7c, 0xa8, 255 ); + + int x = get_relative_x( ); + int y = get_relative_y( ); + + ui_draw_rect( x, y, m_width, m_height, ui_get_disabled_col( ) ); + + if( *m_progress > 0.001f ) { + int fill = *m_progress * m_width; + + bool reverse = false; + for( int i{ }; i < fill; ++i ) { + float progress = std::fmod( float( i ) / fill - ( anim_time ), 1.f ); + if( progress == 1.0f ) reverse = true; + if( reverse ) { + progress = 1.0f - progress; + } + + clr_t col = clr_t::blend( col_start, col_end, progress ); + + + ui_draw_rect( x + i, y, 1, m_height, col ); + } + } + } + + private: + float* m_progress; + }; +} \ No newline at end of file diff --git a/legacy/loader/ui_render.h b/legacy/loader/ui_render.h new file mode 100644 index 0000000..6dd27cc --- /dev/null +++ b/legacy/loader/ui_render.h @@ -0,0 +1,57 @@ +#pragma once + +#include "ui_base_item.h" + +namespace ui +{ + //recursively render all items + static void render_item( base_item* item, int offset = 0, bool allow_rect = true ) { + if ( !item->get_visible( ) ) return; + + item->reset( ); + item->render( ); + bool reset = false; + RECT original; + + if( allow_rect && item->is_form( ) ) { + auto device = g_d3d.get_device( ); + device->GetScissorRect( &original ); + + auto x = item->get_relative_x( ); + auto y = item->get_relative_y( ); + + RECT new_rect{ + x, + y + 4, + x + item->w( ), + y + item->get_total_height( ) - 7 + }; + + device->SetScissorRect( &new_rect ); + reset = true; + } + + if ( item->get_items( ).size( ) ) { + //madr0fl + int* height_offset = ( int* )_alloca( sizeof( int ) * item->get_items( ).size( ) ); + int cur_offset = 0; + for ( int i = ( int )item->get_items( ).size( ) - 1; i >= 0; --i ) { + auto& cur_item = item->get_items( )[ i ]; + height_offset[ i ] = cur_offset; + cur_offset += cur_item->get_visible( ) ? cur_item->get_total_height( ) + ITEM_OFFSET : 0; + } + + int i{ }; + for ( auto& it : item->get_items( ) ) { + item->set_y_offset( height_offset[ i ] ); + render_item( it.get( ), height_offset[ i ], !reset && allow_rect ); + ++i; + } + } + + if( reset ) { + auto device = g_d3d.get_device( ); + device->SetScissorRect( &original ); + } + } +} \ No newline at end of file diff --git a/legacy/loader/ui_slider.h b/legacy/loader/ui_slider.h new file mode 100644 index 0000000..0e55a73 --- /dev/null +++ b/legacy/loader/ui_slider.h @@ -0,0 +1,165 @@ +#pragma once + +#include "ui_base_item.h" + +namespace ui +{ + template < typename t > + class c_slider : public base_item { + public: + c_slider( int x, int y, int w, t min, t max, const char* text, t* setting, t full, const char* suffix = 0 ) : + base_item( x, y, w, 5, text ), m_setting( setting ), m_suffix( suffix ), + m_min( float( min ) ), m_max( float( max ) ), m_full( full ), m_has_text( true ) { }; + + c_slider( int x, int y, int w, t min, t max, const char* text, t* setting, const char* suffix = 0 ) : + base_item( x, y, w, 5, text ), m_setting( setting ), m_suffix( suffix ), + m_min( float( min ) ), m_max( float( max ) ), m_full( max ), m_has_text( true ) { }; + + c_slider( int x, int y, int w, t min, t max, t* setting, const char* suffix = 0 ) : + base_item( x, y, w, 5, nullptr ), m_setting( setting ), m_suffix( suffix ), + m_min( float( min ) ), m_max( float( max ) ), m_full( max ), m_has_text( false ) { } + + virtual bool is_hovered( ) override { + if ( m_disabled ) return false; + + int x = get_relative_x( ); + int y = get_relative_y( ) + ( m_has_text ? 11 : 2 ); + + int mouse_x, mouse_y; + ui_get_cursor_pos( mouse_x, mouse_y ); + + if( !m_has_text ) { + x += 4; + return mouse_x >= x && mouse_x <= x + m_width - 8 + && mouse_y >= y && mouse_y <= y + m_height + 2; + } + + return mouse_x >= x - 1 && mouse_x <= x + m_width + 1 + && mouse_y >= y && mouse_y <= y + m_height + 2; + } + + void input( ) { + bool mouse_clicked = g_input.is_key_pressed( KEYS_MOUSE1 ); + bool hovered = is_hovered( ); + float progress = 0.f; + int x = get_relative_x( ); + int y = get_relative_y( ) + 2; + int mouse_x, mouse_y; + + *m_setting = ( t )( std::clamp< float >( *m_setting, m_min, m_max ) ); + ui_get_cursor_pos( mouse_x, mouse_y ); + + if ( hovered && mouse_clicked ) { + + float progress{ }; + + if( m_has_text ) { + progress = std::clamp< float >( float( mouse_x - x ) / ( m_width - 3 ), 0.f, 1.0f ); + } + else { + progress = std::clamp< float >( float( mouse_x - x - 4 ) / ( m_width - 10 ), 0.f, 1.0f ); + } + + *m_setting = progress == 1.0f ? m_full : ( t )( ( ( m_max - m_min ) * progress ) + m_min ); + } + + if( !m_has_text ) { + bool y_hover = mouse_y >= y && mouse_y <= y + m_height + 1; + + bool minus_hovered = mouse_x >= x - 1 && mouse_x <= x + 3 && y_hover; + bool plus_hovered = mouse_x >= x + m_width - 2 && mouse_x <= x + m_width + 2 && y_hover; + + if( mouse_clicked ) { + if( !m_mouse_held ) { + if( !std::is_floating_point< t >::value ) { + if( minus_hovered ) *m_setting -= ( t )1; + if( plus_hovered ) *m_setting += ( t )1; + } + else if( m_max - m_min <= 2.0f ) { + if( minus_hovered ) *m_setting -= ( t )0.1f; + if( plus_hovered ) *m_setting += ( t )0.1f; + } + } + + m_mouse_held = true; + } + else { + m_mouse_held = false; + } + } + }; + + void draw_slider( int x, int y ) { + float val = float( *m_setting ); + float progress = ( val - m_min ) / ( m_max - m_min ); + + ui_draw_rect( x, y, m_width, m_height, ui_get_disabled_col( ) ); + + ui_draw_rect( x, y, ( int )( ( m_width - 3 ) * progress ), m_height, ui_get_accent_col( ) ); + ui_draw_rect( x + ( int )( ( m_width - 3 ) * progress ), y, 3, m_height, + is_hovered( ) ? ui_get_text_col( ) : ui_get_accent_col( ) * 0.7f ); + } + + void draw_slider_small( int x, int y ) { + float val = float( *m_setting ); + float progress = ( val - m_min ) / ( m_max - m_min ); + x -= 1; //i couldnt be fucked + + ui_draw_rect( x + 5, y, m_width - 8, m_height, ui_get_disabled_col( ) ); + + ui_draw_rect( x + 5, y, ( int )( ( m_width - 10 ) * progress ), m_height, ui_get_accent_col( ) ); + ui_draw_rect( x + ( int )( ( m_width - 10 ) * progress ) + 3, y, 3, m_height, + is_hovered( ) ? ui_get_text_col( ) : ui_get_accent_col( ) * 0.7f ); + + ui_draw_string( x, y - 3, false, ui_get_text_col( ), "-" ); + ui_draw_string( x + m_width - 2, y - 3, false, ui_get_text_col( ), "+" ); + + char val_str[ 12 ]; + if( m_suffix ) + sprintf_s( val_str, 12, t( 0.1f ) == t( 0 ) ? "%d %s" : "%0.2f %s", *m_setting, m_suffix ); + else + sprintf_s( val_str, 12, t( 0.1f ) == t( 0 ) ? "%d" : "%0.2f", *m_setting ); + + ui_draw_string( x + ( int )( ( m_width - 8 ) * progress ) + 3, y + 2, true, ui_get_text_col( ), val_str ); + } + + virtual int get_total_height( ) const override { + return m_height + ( m_has_text ? 12 : 6 ); + } + + virtual void render( ) override { + int x = get_relative_x( ); + int y = get_relative_y( ); + int text_w, text_h; + char val[ 12 ]; + + input( ); + + //weird hacky fix for floating point vars + if ( m_suffix ) + sprintf_s( val, 12, t( 0.1f ) == t( 0 ) ? "%d %s" : "%0.2f %s", *m_setting, m_suffix ); + else + sprintf_s( val, 12, t( 0.1f ) == t( 0 ) ? "%d" : "%0.2f", *m_setting ); + + if( m_has_text ) { + ui_draw_string( x + 2, y, false, ui_get_text_col( ), m_text ); + ui_get_text_size( text_w, text_h, val ); + ui_draw_string( x + m_width - text_w - 1, y, false, ui_get_text_col( ), val ); + draw_slider( x, y + 12 ); + } + else { + draw_slider_small( x, y + 2 ); + } + } + + + protected: + t* m_setting; + t m_full; + float m_min; + float m_max; + bool m_has_text = true; + const char* m_suffix; + bool m_mouse_held = false; + }; +} \ No newline at end of file diff --git a/legacy/loader/ui_tab_manager.h b/legacy/loader/ui_tab_manager.h new file mode 100644 index 0000000..cf8dff6 --- /dev/null +++ b/legacy/loader/ui_tab_manager.h @@ -0,0 +1,224 @@ +#pragma once +#include "ui_base_item.h" + + + +namespace ui +{ + namespace { + constexpr int BUTTON_WIDTH = 120; + constexpr int BUTTON_HEIGHT = 80; + + constexpr int SUBTAB_HEIGHT = 25; + } + + class c_tab_sheet : public base_item { + public: + c_tab_sheet( const char* tab_name ) : + base_item( 0, 0, 0, 0, tab_name ), + m_fade_progress( 0 ) { }; + + c_tab_sheet( const char* tab_name, d3d::c_sprite* sprite ) : + base_item( 0, 0, 0, 0, tab_name ), m_sprite( sprite ), + m_fade_progress( 0.f ) { }; + + virtual void render( ) override { }; + virtual bool is_hovered( ) override { + return false; + }; + + public: + float m_fade_progress{ }; + d3d::c_sprite* m_sprite{ }; + }; + + + class c_tab_manager : public base_item { + public: + c_tab_manager( ) : base_item( BUTTON_WIDTH + 11, 0, 0, 0, + xors( "TAB_MANAGER" ) ) { }; + + virtual bool is_hovered( ) override { + return false; + } + + inline void scale_button_fade( c_tab_sheet* item, bool hovered ) { + if ( hovered ) { + constexpr float frequency = 1.f / 0.3f; + const float step = ui_get_frametime( ) * frequency; + + item->m_fade_progress = std::clamp( item->m_fade_progress + step, 0.f, 0.8f ); + } + else { + item->m_fade_progress = 0.f; + } + } + + auto get_selected_tab( ) { + return m_selected_tab; + } + + void draw_tab_button( decltype( m_parent )& button, int start, bool hovered ) { + auto item = ( c_tab_sheet* )button.get( ); + auto text = item->get_text( ); + auto parent_x = m_parent->x( ) + 5; + auto parent_y = m_parent->y( ) + 5; + int item_height = BUTTON_HEIGHT; + + scale_button_fade( item, hovered ); + + ui_draw_rect( parent_x, parent_y + start, BUTTON_WIDTH + 1, + item_height + 1, ui_get_bg_col( ) ); + + ui_draw_line( parent_x + BUTTON_WIDTH - 8, parent_y + start - 1, + parent_x + BUTTON_WIDTH - 8, parent_y + start + BUTTON_HEIGHT + 2, + ui_get_disabled_col( ) ); + + if( hovered ) { + ui_draw_line( parent_x + BUTTON_WIDTH - 8, parent_y + start - 1, + parent_x + BUTTON_WIDTH - 8, parent_y + start + BUTTON_HEIGHT + 2, + ui_get_accent_col( ) * ( item->m_fade_progress + 0.2f ) * 0.8f ); + } + + if( item->m_sprite ) { + auto sprite_color = hovered ? ui_get_text_col( ) * ( ( item->m_fade_progress + 0.3f ) * 0.7f ) : ui_get_disabled_col( ); + item->m_sprite->draw( parent_x + ( BUTTON_WIDTH - 8 ) / 2 - 2, + parent_y + BUTTON_HEIGHT / 2 + start, sprite_color ); + } + } + + inline bool is_button_hovered( int start ) { + auto item_x = m_parent->x( ) + 5; + auto item_y = m_parent->y( ) + 5 + start; + int item_height = BUTTON_HEIGHT; + int mouse_x, mouse_y; + + ui_get_cursor_pos( mouse_x, mouse_y ); + + return mouse_x >= item_x && mouse_x <= item_x + BUTTON_WIDTH - 8 + && mouse_y >= item_y && mouse_y <= item_y + item_height; + } + + virtual void render( ) override { + if ( !m_items.empty( ) ) { + int cur_y{ 10 }; + for ( auto& it : m_items ) { + it->set_visible( false ); + bool hovered = is_button_hovered( cur_y ); + if ( g_input.is_key_pressed( KEYS_MOUSE1 ) && hovered ) { + //fix items that disable input mess it up when changing tabs + set_disabled_callbacks( false ); + m_selected_tab = it; + } + + draw_tab_button( it, cur_y, hovered || it == m_selected_tab ); + cur_y += BUTTON_HEIGHT + 4; + } + } + + if ( !m_selected_tab ) { + m_selected_tab = m_items.front( ); + } + + m_selected_tab->set_visible( true ); + } + + protected: + decltype( m_parent ) m_selected_tab{ }; + }; + + + class c_subtab_manager : public base_item { + public: + c_subtab_manager( ) : base_item( 0, 35, 0, 5, + xors( "SUBTAB_MANAGER" ) ) { } + + virtual bool is_hovered( ) override { return false; } + + int get_button_width( ) { + int width = get_top_parent( )->w( ) - BUTTON_WIDTH - 26; + + if ( !m_items.empty( ) ) + return ( int )std::ceilf( float( width ) / float( m_items.size( ) ) ); + + return width; + } + + inline void scale_button_fade( c_tab_sheet* item, bool hovered ) { + if ( hovered ) { + constexpr float frequency = 1.f / 0.3f; + const float step = ui_get_frametime( ) * frequency; + + item->m_fade_progress = std::clamp( item->m_fade_progress + step, 0.f, 0.8f ); + } + else { + item->m_fade_progress = 0.f; + } + } + + auto get_selected_tab( ) { + return m_selected_tab; + } + + void render_button( decltype( m_parent )& button, int start, bool hovered ) { + auto item = ( c_tab_sheet* )button.get( ); + auto item_x = get_relative_x( ) + start - 2; + auto item_y = get_relative_y( ) + 3 - m_y; + auto width = get_button_width( ); + + scale_button_fade( item, hovered ); + clr_t tab_clr = ui_get_disabled_col( ); + + //ui_draw_rect( item_x, item_y, get_button_width( ), SUBTAB_HEIGHT, ui_get_bg_col( ) ); + ui_draw_rect( item_x + 1, item_y + SUBTAB_HEIGHT - 2, width, 2, tab_clr ); + if ( hovered ) { + clr_t col = ui_get_accent_col( ); + col.a( ) *= item->m_fade_progress; + ui_draw_rect( item_x + 1, item_y + SUBTAB_HEIGHT - 2, width, 2, col ); + } + + ui_draw_string( item_x + width / 2, item_y + 4, true, ui_get_text_col( ), item->get_text( ) ); + } + + bool is_button_hovered( decltype( m_parent )& button, int start ) { + int item_x = get_relative_x( ) + start - 2; + int item_y = get_relative_y( ) + 3 - m_y - 3; + int item_w = get_button_width( ); + int mouse_x, mouse_y; + + ui_get_cursor_pos( mouse_x, mouse_y ); + + return mouse_x >= item_x && mouse_x <= item_x + item_w && + mouse_y >= item_y && mouse_y <= item_y + SUBTAB_HEIGHT; + } + + virtual void render( ) override { + if ( !m_items.empty( ) ) { + int start = 2; + int width = get_button_width( ); + + for ( auto& it : m_items ) { + it->set_visible( false ); + bool hovered = is_button_hovered( it, start ); + if ( g_input.is_key_pressed( KEYS_MOUSE1 ) && hovered ) { + //fix items that disable input mess it up when changing tabs + set_disabled_callbacks( false ); + m_selected_tab = it; + } + + render_button( it, start, hovered || it == m_selected_tab ); + start += width; + } + + if ( !m_selected_tab ) { + m_selected_tab = m_items.front( ); + } + + m_selected_tab->set_visible( true ); + } + } + + protected: + decltype( m_parent ) m_selected_tab; + }; +} \ No newline at end of file diff --git a/legacy/loader/ui_text_input.cpp b/legacy/loader/ui_text_input.cpp new file mode 100644 index 0000000..db1ec7c --- /dev/null +++ b/legacy/loader/ui_text_input.cpp @@ -0,0 +1,86 @@ +#include "ui_text_input.h" +#include + +#include + +void ui::c_text_input::render( ) { + if( is_hovered( ) && g_input.is_key_pressed( KEYS_MOUSE1 ) ) { + if( !m_was_held ) { + m_active ^= 1; + } + m_was_held = true; + } + else { + m_was_held = false; + } + + if( m_active ) { + if( !is_hovered( ) && g_input.is_key_pressed( KEYS_MOUSE1 ) ) { + m_active = false; + } + + float current_time = GetTickCount( ) * 0.001f; + size_t length = strlen( m_text_ptr ); + + for( size_t i{ }; i < 0xfe; ++i ) { + if( g_input.is_key_pressed( i ) ) { + float delta_time = current_time - m_last_key_input[ i ]; + if( fabs( delta_time ) > 0.2f ) { + if( i == KEYS_BACK ) { + m_text_ptr[ length - 1 ] = 0; + m_last_key_input[ i ] = current_time; + continue; + } + + if( i == KEYS_RETURN ) { + m_active = false; + break; + } + + m_key_states[ i ] = 0xf0; + wchar_t pressed_char; + const auto scan = MapVirtualKeyA( i, 2 ); + auto ret = ToAscii( i, scan, ( BYTE* )m_key_states, ( LPWORD )&pressed_char, 1 ); + + if( ret == 1 ) { + if( length < m_text_len ) { + m_text_ptr[ length ] = ( char )( pressed_char ); + m_text_ptr[ length + 1 ] = 0; + } + } + m_last_key_input[ i ] = current_time; + } + } + else { + m_last_key_input[ i ] = 0.f; + m_key_states[ i ] = 0; + } + } + + if( g_input.is_key_pressed( KEYS_RETURN ) ) { + m_active = false; + } + } + + int x = get_relative_x( ); + int y = get_relative_y( ); + + ui_draw_string( x + 2, y, false, ui_get_text_col( ), m_text ); + y += 12; + + ui_draw_rect( x - 1, y - 1, m_width + 2, m_height + 2, + ( is_hovered( ) || m_active ) ? ui_get_text_col( ) : ui_get_accent_col( ) ); + ui_draw_rect( x, y, m_width, m_height, ui_get_disabled_col( ) ); + + if( !m_hidden ) + ui_draw_string( x + 2, y + 3, false, ui_get_text_col( ), m_active ? "%s_" : "%s", m_text_ptr ); + else { + std::string str; + str.append( strlen( m_text_ptr ), '*' ); + + if( m_active ) + str += '_'; + + ui_draw_string( x + 2, y + 3, false, ui_get_text_col( ), str.c_str( ) ); + } +} \ No newline at end of file diff --git a/legacy/loader/ui_text_input.h b/legacy/loader/ui_text_input.h new file mode 100644 index 0000000..243c40b --- /dev/null +++ b/legacy/loader/ui_text_input.h @@ -0,0 +1,38 @@ +#pragma once +#include "ui_base_item.h" + +namespace ui +{ + class c_text_input : public base_item { + public: + c_text_input( int x, int y, int w, const char* name, size_t max_chars, char* str, bool hidden = false ) : + base_item( x, y, w, 16, name ), m_text_len( max_chars ), m_text_ptr( str ), m_hidden( hidden ) { + } + + virtual bool is_hovered( ) override { + int cursor_x, cursor_y; + ui_get_cursor_pos( cursor_x, cursor_y ); + + int x = get_relative_x( ); + int y = get_relative_y( ) + 12; + + return cursor_x >= x && cursor_x <= x + m_width + && cursor_y >= y && cursor_y <= y + m_height; + } + + virtual int get_total_height( ) const override { + return m_height + 12; + } + + virtual void render( ) override; + + protected: + bool m_was_held{ }; + char* m_text_ptr{ }; + size_t m_text_len{ }; + bool m_active{ }; + float m_last_key_input[ KEYS_LAST ]{ }; + uint8_t m_key_states[ 256 ]{ }; + bool m_hidden{ }; + }; +} \ No newline at end of file diff --git a/legacy/loader/util.hpp b/legacy/loader/util.hpp new file mode 100644 index 0000000..68de3fb --- /dev/null +++ b/legacy/loader/util.hpp @@ -0,0 +1,101 @@ +#pragma once +#include +#include +#include + +#define xors( s ) s + +#define NAMESPACE_REGION( x ) namespace x { +#define END_REGION } + +extern int TIME_TO_TICKS( float dt ); +extern float TICKS_TO_TIME( int tick ); +extern float TICK_INTERVAL( ); + +//WEE WOO WEE WOO ITS THE DWORD POLICE +using ulong_t = unsigned long; +using uword_t = unsigned short; + +class IClientEntity; +class CTraceFilter; +class CGameTrace; +class vec3_t; +class vec2_t; + +NAMESPACE_REGION( util ) + +typedef std::unique_ptr< void, void( ) > unique_handle; + +template < typename t > +struct reverse_iterable { + reverse_iterable( t&& it ) : + iterable( it ) { } + + t& iterable; + inline auto begin( ) { + return std::rbegin( iterable ); + } + + inline auto end( ) { + return std::rend( iterable ); + } +}; + +template< typename t > +reverse_iterable< t > +reverse_iterator( t&& iter ) { + return reverse_iterable< t >{ iter }; +} + +template < typename fn > __forceinline fn get_vfunc( void* classbase, int index ) { + if( !classbase ) return fn{ }; + return ( fn )( *( uintptr_t** )classbase )[ index ]; +} + +template < size_t index, typename ret, class ... args_ > +__forceinline ret get_vfunc( void* thisptr, args_... args ) { + using fn = ret( __thiscall* )( void*, args_... ); + + auto fn_ptr = ( fn )( *( uintptr_t** )thisptr )[ index ]; + return fn_ptr( thisptr, args... ); +} + +__forceinline std::string unicode_to_ascii( const std::wstring& unicode ) { + std::string ascii_str( unicode.begin( ), unicode.end( ) ); + return ascii_str; +} + +__forceinline std::wstring ascii_to_unicode( const std::string& ascii ) { + std::wstring unicode_str( ascii.begin( ), ascii.end( ) ); + return unicode_str; +} + +template < typename integer > +__forceinline auto to_hex_str( const integer& w, + size_t hex_len = sizeof( integer ) << 1 ) { + constexpr char* hex_digits = xors( "0123456789abcdef" ); + std::string rc( hex_len, 0 ); + + for( size_t i{ }, j{ ( hex_len - 1 ) * 4 }; i < hex_len; ++i, j -= 4 ) + rc[ i ] = hex_digits[ ( w >> j ) & 0x0f ]; + + return rc; +} + +extern void clip_trace_to_player( IClientEntity* player, const vec3_t& src, const vec3_t& end, + unsigned mask, CTraceFilter* filter, CGameTrace* trace ); + +extern bool trace_ray( const vec3_t& start, const vec3_t& end, IClientEntity* a, IClientEntity* b ); +extern bool is_tick_valid( int tickcount ); +extern void set_random_seed( int seed ); +extern vec3_t get_spread_dir( float inaccuracy, float spread, vec3_t angles, int seed ); +extern float get_random_float( float min, float max ); +extern bool hitchance( int target, const vec3_t& angles, int percentage ); +extern float get_total_latency( ); +extern float get_lerptime( ); +extern int get_closest_player( ); +extern vec2_t screen_transform( vec3_t world ); +extern const char* definition_index_to_name( int index ); +extern void disable_pvs( ); + +END_REGION \ No newline at end of file diff --git a/legacy/loader/winapi.hpp b/legacy/loader/winapi.hpp new file mode 100644 index 0000000..72fdbfe --- /dev/null +++ b/legacy/loader/winapi.hpp @@ -0,0 +1,64 @@ +#pragma once +#include +#include "util.hpp" + +namespace winapi +{ + static uintptr_t get_procaddr_ex( HANDLE process, HMODULE mod, const char* proc ) { + IMAGE_DOS_HEADER dos_hdr; + IMAGE_NT_HEADERS nt_hdrs; + IMAGE_EXPORT_DIRECTORY export_dir; + uintptr_t export_addr; + char export_name[ 64 ]; + uintptr_t* names; + uintptr_t* funcs; + uint16_t* ords; + uintptr_t ret{ }; + + ReadProcessMemory( process, mod, &dos_hdr, sizeof( dos_hdr ), 0 ); + ReadProcessMemory( process, ( void* )( uintptr_t( mod ) + dos_hdr.e_lfanew ), + &nt_hdrs, sizeof( nt_hdrs ), nullptr ); + + export_addr = nt_hdrs.OptionalHeader.DataDirectory[ 0 ].VirtualAddress; + ReadProcessMemory( process, ( void* )( uintptr_t( mod ) + export_addr ), + &export_dir, sizeof( export_dir ), nullptr ); + + if( !export_dir.NumberOfFunctions ) + return uintptr_t{ }; + + funcs = ( uintptr_t* )( malloc( sizeof( uintptr_t ) * export_dir.AddressOfFunctions ) ); + names = ( uintptr_t* )( malloc( sizeof( uintptr_t ) * export_dir.NumberOfNames ) ); + ords = ( uint16_t* ) ( malloc( sizeof( uint16_t ) * export_dir.NumberOfNames ) ); + + ReadProcessMemory( process, ( void* )( uintptr_t( mod ) + export_dir.AddressOfFunctions ), + funcs, sizeof( uintptr_t ) * export_dir.NumberOfFunctions, nullptr ); + ReadProcessMemory( process, ( void* )( uintptr_t( mod ) + export_dir.AddressOfNames ), + names, sizeof( uintptr_t ) * export_dir.NumberOfNames, nullptr ); + ReadProcessMemory( process, ( void* )( uintptr_t( mod ) + export_dir.AddressOfNameOrdinals ), + ords, sizeof( uint16_t ) * export_dir.NumberOfNames, nullptr ); + + auto read_str = [ &process ]( char* buf, size_t size, uintptr_t addr ) { + for( size_t i{ }; i < size; ++i ) { + char _c; + ReadProcessMemory( process, ( void* )( addr + i ), &_c, 1, 0 ); + buf[ i ] = _c; + if( !_c ) break; + } + + buf[ size - 1 ] = 0; + }; + + for( size_t i{ }; i < export_dir.NumberOfNames; ++i ) { + read_str( export_name, 64, uintptr_t( mod ) + names[ i ] ); + + if( !strcmp( export_name, proc ) ) + ret = uintptr_t( mod ) + funcs[ ords[ i ] ]; + } + + ::free( funcs ); + ::free( names ); + ::free( ords ); + + return ret; + } +} \ No newline at end of file diff --git a/legacy/loader/window.cpp b/legacy/loader/window.cpp new file mode 100644 index 0000000..9699f72 --- /dev/null +++ b/legacy/loader/window.cpp @@ -0,0 +1,148 @@ +#pragma once +#include "window.hpp" +#include "d3d.hpp" + +d3d::c_window g_window; + +#define HACK_NAME xors( "moneybot $$$" ) + +namespace d3d +{ + c_window::c_window( ) { m_size[ 0 ] = 451; m_size[ 1 ] = 376; } //ugh + c_window::~c_window( ) { } + + LRESULT __stdcall c_window::window_procedure( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) { + if( msg == WM_MOUSEMOVE ) { + g_input.capture_mouse_move( lparam ); + } + + g_input.register_key_press( ( VirtualKeyEvents_t )( msg ), VirtualKeys_t( wparam ) ); + + switch( msg ) { + case WM_SIZE: + if( g_window.m_d3d_device && wparam != SIZE_MINIMIZED ) { + g_window.m_present_params.BackBufferWidth = LOWORD( lparam ); + g_window.m_present_params.BackBufferHeight = HIWORD( lparam ); + + g_d3d.on_device_lost( ); + auto result = g_window.m_d3d_device->Reset( &g_window.m_present_params ); + g_d3d.on_device_reset( ); + } + return 0; + case WM_SYSCOMMAND: + if( ( wparam & 0xfff0 ) == SC_KEYMENU ) //disable alt thing + return 0; + break; + + + case WM_DESTROY: + PostQuitMessage( 0 ); + return 0; + } + + return DefWindowProc( hwnd, msg, wparam, lparam ); + } + + bool c_window::create( ) { + m_wc.cbSize = sizeof( WNDCLASSEX ); + m_wc.style = CS_VREDRAW | CS_HREDRAW; + m_wc.lpfnWndProc = window_procedure; + m_wc.cbClsExtra = 0; + m_wc.cbWndExtra = 0; + m_wc.hInstance = 0; + m_wc.hIcon = LoadIcon( 0, IDI_APPLICATION ); + m_wc.hCursor = LoadCursor( 0, IDC_ARROW ); + m_wc.lpszMenuName = 0; + m_wc.lpszClassName = HACK_NAME; + m_wc.hIconSm = LoadIcon( 0, IDI_APPLICATION ); + + //m_wc.hbrBackground = ( HBRUSH )( RGB( 0, 0, 0 ) ); + + RegisterClassEx( &m_wc ); + + m_hwnd = CreateWindowExA( WS_EX_TRANSPARENT, HACK_NAME, HACK_NAME, WS_POPUP, + CW_USEDEFAULT, CW_USEDEFAULT, m_size[ 0 ], m_size[ 1 ], nullptr, nullptr, nullptr, 0 ); + + if( !m_hwnd ) { + return false; + } + + //SetLayeredWindowAttributes( m_hwnd, RGB( 0, 0, 0 ), 0, ULW_COLORKEY ); + //SetLayeredWindowAttributes( m_hwnd, RGB( 0, 0, 0 ), 255, LWA_ALPHA ); + ShowWindow( m_hwnd, SW_SHOWDEFAULT ); + UpdateWindow( m_hwnd ); + + //MARGINS margin = { -1, -1, -1, -1 }; + //DwmExtendFrameIntoClientArea( m_hwnd, &margin ); + + MoveWindow( m_hwnd, 20, 20, m_size[ 0 ], m_size[ 1 ], true ); + + return init_d3d( ); + } + + bool c_window::init_d3d( ) { + if( !( m_d3d = Direct3DCreate9( D3D_SDK_VERSION ) ) ) { + UnregisterClass( HACK_NAME, m_wc.hInstance ); + return false; + } + + ZeroMemory( &m_present_params, sizeof( m_present_params ) ); + + m_present_params.Windowed = true; + m_present_params.SwapEffect = D3DSWAPEFFECT_DISCARD; + m_present_params.BackBufferFormat = D3DFMT_A8R8G8B8; + m_present_params.hDeviceWindow = m_hwnd; + m_present_params.EnableAutoDepthStencil = true; + m_present_params.AutoDepthStencilFormat = D3DFMT_D16; + m_present_params.MultiSampleType = D3DMULTISAMPLE_NONE; + m_present_params.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + m_present_params.BackBufferCount = 1; + m_present_params.BackBufferWidth = m_size[ 0 ]; + m_present_params.BackBufferHeight = m_size[ 1 ]; + + if( m_d3d->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_hwnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &m_present_params, &m_d3d_device ) < 0 ) { + m_d3d->Release( ); + UnregisterClass( HACK_NAME, m_wc.hInstance ); + return false; + } + + return true; + } + + void c_window::on_frame( ) { + while( m_msg.message != WM_QUIT ) { + if( PeekMessage( &m_msg, 0, 0, 0, PM_REMOVE ) ) { + TranslateMessage( &m_msg ); + DispatchMessage( &m_msg ); + + continue; + } + + if( m_d3d_device ) { + auto device_state = m_d3d_device->TestCooperativeLevel( ); + if( device_state != D3D_OK ) { + g_d3d.on_device_lost( ); + m_d3d_device->Reset( &m_present_params ); + g_d3d.on_device_reset( ); + } + + + if( m_d3d_device->BeginScene( ) >= 0 ) { + for( auto& onframe : m_onframe_vec ) { + if( onframe ) { + onframe( ); + } + } + //m_d3d_device->SetRenderState( D3DRS_ZENABLE, false ); + //m_d3d_device->SetRenderState( D3DRS_ALPHABLENDENABLE, false ); + //m_d3d_device->SetRenderState( D3DRS_SCISSORTESTENABLE, false ); + m_d3d_device->EndScene( ); + } + + m_d3d_device->Present( nullptr, nullptr, nullptr, nullptr ); + Sleep( 1 ); + } + } + } +} + diff --git a/legacy/loader/window.hpp b/legacy/loader/window.hpp new file mode 100644 index 0000000..e1efc86 --- /dev/null +++ b/legacy/loader/window.hpp @@ -0,0 +1,59 @@ +#pragma once +#include +#include + +#pragma comment(lib, "d3d9.lib") +#pragma comment(lib, "d3dx9.lib") + +#include +#include + +#include +#pragma comment(lib, "dwmapi.lib") +#pragma comment(lib, "winmm.lib") + +#include + +#include "input_system.hpp" + +namespace d3d +{ + typedef void( *on_frame_fn )( ); + + class c_window { + public: + c_window( ); + ~c_window( ); + + bool create( ); + void on_frame( ); + void add_on_frame( on_frame_fn fn ) { + m_onframe_vec.push_back( fn ); + } + + HWND get_hwnd( ) { return m_hwnd; } + + private: + bool init_d3d( ); + + public: + static LRESULT __stdcall window_procedure( HWND, UINT, WPARAM, LPARAM ); + + private: + HWND m_hwnd{ }; + int m_size[ 2 ]{ }; + + WNDCLASSEX m_wc{ }; + MSG m_msg{ }; + + public: + LPDIRECT3DDEVICE9 m_d3d_device{ }; + D3DPRESENT_PARAMETERS m_present_params{ }; + LPDIRECT3D9 m_d3d{ }; + + private: + std::vector< on_frame_fn > m_onframe_vec; + }; +} + +extern d3d::c_window g_window; \ No newline at end of file diff --git a/legacy/loader/x86.h b/legacy/loader/x86.h new file mode 100644 index 0000000..5208225 --- /dev/null +++ b/legacy/loader/x86.h @@ -0,0 +1,47 @@ +#pragma once +#include + +namespace x86 +{ + enum class reg : size_t { + eax = 0, + ecx, + edx, + ebx, + esp, + ebp, + esi, + edi, + + /* + x64: + r8, + r9, + r10, + r11, + r12, + r13, + r14, + r15,*/ + }; + + enum instruction : uint8_t { + retn_imm16 = 0xc2, + retn = 0xc3, + fs = 0x64, + //its big nigga season + call = 0xff + }; + + __forceinline static uint32_t encode_mov_imm32( x86::reg dreg ) { + return ( 0xb8 + ( size_t( dreg ) ) ); + } + + __forceinline static uint32_t encode_push_reg( x86::reg dreg ) { + return ( 0x50 | ( ( size_t( dreg ) ) & 7 ) ); + } + + __forceinline static uint32_t encode_pop_reg( x86::reg dreg ) { + return ( 0x58 | ( ( size_t( dreg ) ) & 7 ) ); + } +}; \ No newline at end of file -- cgit v1.2.3