├── .gitignore ├── README.md ├── RPCInterface ├── meathook_interface.h ├── meathook_interface.idl ├── meathook_interface_c.c ├── meathook_interface_s.c ├── mhclient.cpp ├── mhclient.h └── mhserver.cpp ├── m34thook.sln ├── m34thook ├── alltypes.h ├── clipboard_helpers.hpp ├── cmdsystem.cpp ├── cmdsystem.hpp ├── compressedfile_override.cpp ├── doomoffs.hpp ├── errorhandling_hooks.cpp ├── errorhandling_hooks.hpp ├── eventdef.cpp ├── eventdef.hpp ├── fs_hooks.cpp ├── fs_hooks.hpp ├── game_exe_interface.cpp ├── game_exe_interface.hpp ├── gameapi.cpp ├── gameapi.hpp ├── generalized_number.hpp ├── grab_spawninfo_Command.cpp ├── idLib.cpp ├── idLib.hpp ├── idStr.hpp ├── id_resources_lowlevel.cpp ├── id_resources_lowlevel.hpp ├── idmath.hpp ├── idtypeinfo.cpp ├── idtypeinfo.hpp ├── m34thook.vcxproj ├── m34thook.vcxproj.filters ├── main.cpp ├── mapfile.hpp ├── meathook.cpp ├── meathook.h ├── memorySystem.hpp ├── memscan.cpp ├── memscan.hpp ├── mh_cmds_cheats.cpp ├── mh_cmds_dump_and_gen.cpp ├── mh_cmds_editor.cpp ├── mh_cmds_misc_and_dev.cpp ├── mh_cmds_queries.cpp ├── mh_cmds_spawning.cpp ├── mh_defs.hpp ├── mh_dev_hooks.cpp ├── mh_dev_hooks.hpp ├── mh_editor_math.hpp ├── mh_editor_mode.cpp ├── mh_editor_mode.hpp ├── mh_guirender.cpp ├── mh_guirender.hpp ├── mh_headergen.cpp ├── mh_headergen.hpp ├── mh_inputsys.cpp ├── mh_inputsys.hpp ├── mh_kwsearch.cpp ├── mh_mainloop.cpp ├── mh_mainloop.hpp ├── mh_memmanip_cmds.cpp ├── mh_memmanip_cmds.hpp ├── mh_native_api.cpp ├── mh_native_api.hpp ├── mh_staticmodel.cpp ├── mh_staticmodel.hpp ├── mhgui.cpp ├── mhgui.hpp ├── mhserver.cpp ├── mhutil │ ├── mh_filesystem.cpp │ └── mh_filesystem.hpp ├── objfiles │ ├── objloader.cpp │ └── objloader.h ├── optimizations │ └── mhoptimize.cpp ├── pregenerated │ ├── doom_eternal_cvars_generated.cpp │ ├── doom_eternal_cvars_generated.hpp │ ├── doom_eternal_properties_generated.cpp │ └── doom_eternal_properties_generated.hpp ├── rapiddecl.hpp ├── rapiddecl │ ├── allocators.h │ ├── cursorstreamwrapper.h │ ├── document.h │ ├── encodedstream.h │ ├── encodings.h │ ├── error │ │ ├── en.h │ │ └── error.h │ ├── filereadstream.h │ ├── filewritestream.h │ ├── fwd.h │ ├── internal │ │ ├── biginteger.h │ │ ├── diyfp.h │ │ ├── dtoa.h │ │ ├── ieee754.h │ │ ├── itoa.h │ │ ├── meta.h │ │ ├── pow10.h │ │ ├── regex.h │ │ ├── stack.h │ │ ├── strfunc.h │ │ ├── strtod.h │ │ └── swap.h │ ├── istreamwrapper.h │ ├── memorybuffer.h │ ├── memorystream.h │ ├── msinttypes │ │ ├── inttypes.h │ │ └── stdint.h │ ├── ostreamwrapper.h │ ├── pointer.h │ ├── prettywriter.h │ ├── rapidjson.h │ ├── reader.h │ ├── schema.h │ ├── stream.h │ ├── stringbuffer.h │ └── writer.h ├── rendermodelgui.cpp ├── resource.hpp ├── scanner_core.cpp ├── scanner_core.hpp ├── scanners │ ├── initial_scangroup.hpp │ ├── scanner_core_incl.hpp │ ├── scanners_avx2.cpp │ ├── scanners_avx512.cpp │ ├── scanners_generic.cpp │ ├── scanners_typeinfo.hpp │ ├── secondary_scangroup.hpp │ └── tertiary_scangroup.hpp ├── thunkstrementer.cpp ├── win32 │ └── ntdll.h ├── xbyak │ ├── xbyak.h │ ├── xbyak_bin2hex.h │ ├── xbyak_mnemonic.h │ └── xbyak_util.h ├── xmacro_mh_config.hpp └── xmacro_scanned_features.hpp ├── snaphak_algo ├── asmbits.asm ├── impls │ ├── avx2 │ │ └── memops_avx2.hpp │ ├── avx512 │ │ └── memops_avx512.hpp │ ├── bmp_impl.hpp │ ├── bulkint_impl.hpp │ ├── generic │ │ └── memops_generic.hpp │ ├── include_impls.hpp │ ├── init_impls_avx2.cpp │ ├── init_impls_avx512.cpp │ ├── init_impls_generic.cpp │ ├── memop_impl.hpp │ ├── rb_impl.hpp │ ├── sortnsearch_impl.hpp │ └── str_impl.hpp ├── init_snapalgo.cpp ├── memclasses.hpp ├── sh_heap_shared.hpp ├── snaphak_algo.vcxproj ├── snaphak_algo.vcxproj.filters ├── snaphak_allocator.hpp ├── snaphak_bitmap.hpp ├── snaphak_coro.hpp ├── snaphak_coros.asm ├── snaphak_fmath.hpp ├── snaphak_heap.hpp ├── snaphak_intbulk.hpp ├── snaphak_memops.hpp ├── snaphak_networking.hpp ├── snaphak_rbtree.hpp ├── snaphak_smt.hpp ├── snaphak_sortnsearch.hpp ├── snaphak_string.hpp ├── snaphak_vmemops.hpp ├── snaphakalgo.hpp ├── snaphakalgo_coro.cpp ├── snaphakalgo_heap.cpp ├── snaphakalgo_networking.cpp ├── snaphakalgo_predef.hpp ├── snaphakalgo_real.cpp ├── snaphakalgo_smt.cpp ├── snaphakalgo_vmem.cpp ├── syscall_interface.cpp ├── syscall_list.hpp └── win_syscall_list.asm └── udis86test ├── config.h ├── decode.cpp ├── decode.h ├── extern.h ├── itab.cpp ├── itab.h ├── syn-att.cpp ├── syn-intel.cpp ├── syn.cpp ├── syn.h ├── types.h ├── udint.h ├── udis86.cpp ├── udis86.h ├── udis86test.vcxproj └── udis86test.vcxproj.filters /README.md: -------------------------------------------------------------------------------- 1 | ### Meathook v7.2 2 | 3 | This version of Meathook was created by chrispy. It was released on November 15, 2021. I take no credit for the creation of this tool. 4 | 5 | ### Instructions 6 | 7 | Copy the "XINPUT1_3.dll" file into your Doom Eternal directory. Overwrite the existing file if prompted. 8 | 9 | ### Known Issues with Game Update v6.66 10 | 11 | Certain mods may cause the game to crash with an Engine Error. An example of the error is: 12 | `component 20 (aicomponent/jetpack/revenant_test) on 'master_level_ai_heavy_revenant_retro' has an invalid component id` 13 | 14 | This is a problem with version 7.1 of Meathook. If you encounter this error, please download the newest version (v7.2). 15 | 16 | ### Changelog 17 | 18 | - Fixes `chrispy` command which broke in v6.66 game update 19 | - Adds several new commands, use `find mh_` in console to see a list. 20 | 21 | ### Console Commands 22 | 23 | Command | Description 24 | ------------ | ------------- 25 | chrispy | chrispy \ \ - spawns an entity at the position 26 | idlib_dump | idlib_dump 27 | mh_active_encounter | Get the list of active encounter managers 28 | mh_ang2mat | mh_ang2mat pitch yaw roll : converts the pitch, yaw and roll values for idAngles to a decl - formatted matrix, copying the result to your clipboard 29 | mh_angleincr | amount to inc/dec by with angle editing 30 | mh_cpuinfo | takes no args, dumps info about your cpu for dev purposes 31 | mh_current_checkpoint | Get the current checkpoint name 32 | mh_dump_bmodel | Finds a staticmodel and then executes writestaticbmodel to the provided path 33 | mh_dumpeventdefs | mh_dumpeventdefs 34 | mh_dumpmap | Dump current idMapLocal to a .map file. 35 | mh_dumppropidxinfo | Debug command for dumping the corresponding addresses/rvas for property indices 36 | mh_editor | Sets up the editor session 37 | mh_editor_keys | tells you editor stuff 38 | mh_editor_spawn | Spawns an entity, saving it to the map and grabbing it for manipulation 39 | mh_end_spawnrec | No args, closes current spawnfile 40 | mh_force_reload | Force reload current level 41 | mh_gencvarset | Regenerate doom_eternal_cvars_generated.cpp/hpp for mh build 42 | mh_genpropset | Regenerated doom_eternal_properties_generated.cpp/hpp for use in mh builds. not for users 43 | mh_grab | Grab an object 44 | mh_killAi | Kills all living ai 45 | mh_kw | Searches all types, enums, typedefs, their comments, field names, typename, template args, eventdefs, vtbl names, cvar names, cvar descriptions for the provided keywords 46 | mh_list_entity_types | lists the names of all subclasses of idEntity with optional filter 47 | mh_list_resource_lists | lists all resource lists by classname/typename, copying the result to the clipboard (the clipboard might not be helpful here) 48 | mh_list_resources_of_class | lists all resources in a given list, copying result to clipboard 49 | mh_locate_fspec_char_uses | Finds all usages of a provided char in event formatspecs/rettypes 50 | mh_optimize | Patches the engine to make stuff run faster. Do not use online, might result in slightly different floating point results (probably not though) 51 | mh_printentitydef | Print the entitydef of the entity with the provided name to the console 52 | mh_randomact | uses scalar + random values to randomly change the color, scale, and velocity of all entities within distance from player 53 | mh_reload_decl | mh_reload_decl 54 | mh_removeAi | Removes all living ai 55 | mh_ScriptCmd | ai_ScriptCmd resurrected, now copies the results of the eventcall to your clipboard for chaining commands together 56 | mh_ScriptCmdEnt | ai_ScriptCmdEnt resurrected, now copies the results of the eventcall to your clipboard for chaining commands together 57 | mh_set_charscaling | smallchar w/h override 58 | mh_spawnfile | spawns the entities at the positions from the file 59 | mh_spawninfo | Copy your current position and orientation, formatted as spawnPosition and spawnOrientation to the clipboard 60 | mh_spmap | shortcut for map maps/game/sp// 61 | mh_start_spawnrec | starts recording all chrispy/rechrispy spawns/spawn positions to a file for later exec by mh_spawnfile 62 | mh_test_genbmodel | (YOU MUST BE ON V1 WITH RANDOMBASEADDR FLAG OFF ON EXE FOR THIS RIGHT NOW) generate bmodel in standalone resource from .obj 63 | mh_testgui | test 64 | mh_testmaterial | Takes one arg, a material name. Renders the material to the test window. Passing no args clears the test window 65 | mh_type | Dump fields for provided class 66 | noclip | Toggle noclip 67 | notarget | Toggle notarget 68 | rechrispy | Repeats last usage chrispy command with same args 69 | -------------------------------------------------------------------------------- /RPCInterface/meathook_interface.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | /* this ALWAYS GENERATED file contains the definitions for the interfaces */ 4 | 5 | 6 | /* File created by MIDL compiler version 8.01.0622 */ 7 | /* at Mon Jan 18 19:14:07 2038 8 | */ 9 | /* Compiler settings for meathook_interface.idl: 10 | Oicf, W1, Zp8, env=Win64 (32b run), target_arch=AMD64 8.01.0622 11 | protocol : dce , ms_ext, c_ext, robust 12 | error checks: allocation ref bounds_check enum stub_data 13 | VC __declspec() decoration level: 14 | __declspec(uuid()), __declspec(selectany), __declspec(novtable) 15 | DECLSPEC_UUID(), MIDL_INTERFACE() 16 | */ 17 | /* @@MIDL_FILE_HEADING( ) */ 18 | 19 | #pragma warning( disable: 4049 ) /* more than 64k source lines */ 20 | 21 | 22 | /* verify that the version is high enough to compile this file*/ 23 | #ifndef __REQUIRED_RPCNDR_H_VERSION__ 24 | #define __REQUIRED_RPCNDR_H_VERSION__ 475 25 | #endif 26 | 27 | #include "rpc.h" 28 | #include "rpcndr.h" 29 | 30 | #ifndef __RPCNDR_H_VERSION__ 31 | #error this stub requires an updated version of 32 | #endif /* __RPCNDR_H_VERSION__ */ 33 | 34 | 35 | #ifndef __meathook_interface_h__ 36 | #define __meathook_interface_h__ 37 | 38 | #if defined(_MSC_VER) && (_MSC_VER >= 1020) 39 | #pragma once 40 | #endif 41 | 42 | /* Forward Declarations */ 43 | 44 | #ifdef __cplusplus 45 | extern "C"{ 46 | #endif 47 | 48 | 49 | #ifndef __meathook_interface_INTERFACE_DEFINED__ 50 | #define __meathook_interface_INTERFACE_DEFINED__ 51 | 52 | /* interface meathook_interface */ 53 | /* [version][uuid] */ 54 | 55 | void ExecuteConsoleCommand( 56 | /* [in] */ handle_t IDL_handle, 57 | /* [string][in] */ unsigned char *pszString); 58 | 59 | void PushEntitiesFile( 60 | /* [in] */ handle_t IDL_handle, 61 | /* [string][in] */ unsigned char *pBuffer, 62 | /* [in] */ boolean Start, 63 | /* [in] */ int Size); 64 | 65 | void UploadData( 66 | /* [in] */ handle_t IDL_handle, 67 | /* [in] */ int Size, 68 | /* [in] */ int Offset, 69 | /* [size_is][in] */ unsigned char *pBuffer); 70 | 71 | void GetEntitiesFile( 72 | /* [in] */ handle_t IDL_handle, 73 | /* [out][in] */ int *Size, 74 | /* [size_is][out] */ unsigned char *pBuffer); 75 | 76 | void GetActiveEncounter( 77 | /* [in] */ handle_t IDL_handle, 78 | /* [out][in] */ int *Size, 79 | /* [size_is][out] */ unsigned char *pBuffer); 80 | 81 | void GetCurrentCheckpoint( 82 | /* [in] */ handle_t IDL_handle, 83 | /* [out][in] */ int *Size, 84 | /* [size_is][out] */ unsigned char *pBuffer); 85 | 86 | void GetSpawnInfo( 87 | /* [in] */ handle_t IDL_handle, 88 | /* [out][in] */ int *Size, 89 | /* [size_is][out] */ unsigned char *pBuffer); 90 | 91 | void KeepAlive( 92 | /* [in] */ handle_t IDL_handle, 93 | /* [out][in] */ int *Size); 94 | 95 | 96 | 97 | extern RPC_IF_HANDLE meathook_interface_v1_0_c_ifspec; 98 | extern RPC_IF_HANDLE meathook_interface_v1_0_s_ifspec; 99 | #endif /* __meathook_interface_INTERFACE_DEFINED__ */ 100 | 101 | /* Additional Prototypes for ALL interfaces */ 102 | 103 | /* end of Additional Prototypes */ 104 | 105 | #ifdef __cplusplus 106 | } 107 | #endif 108 | 109 | #endif 110 | 111 | 112 | -------------------------------------------------------------------------------- /RPCInterface/meathook_interface.idl: -------------------------------------------------------------------------------- 1 | //file meathook_interface.idl 2 | [ 3 | uuid(1c9ca7c8-d421-482d-b85d-79fac33b2658), 4 | version(1.0) 5 | ] 6 | interface meathook_interface 7 | { 8 | void ExecuteConsoleCommand([in, string] unsigned char * pszString); 9 | void PushEntitiesFile([in, string] char* pBuffer, [in] boolean Start, [in] int Size); 10 | void UploadData([in] int Size, [in] int Offset, [in, size_is(Size)] char * pBuffer); 11 | void GetEntitiesFile([in, out] int *Size, [out, size_is(*Size)] unsigned char * pBuffer ); 12 | void GetActiveEncounter([in, out] int *Size, [out, size_is(*Size)] unsigned char * pBuffer ); 13 | void GetCurrentCheckpoint([in, out] int *Size, [out, size_is(*Size)] unsigned char * pBuffer ); 14 | void GetSpawnInfo([in, out] int *Size, [out, size_is(*Size)] unsigned char * pBuffer); 15 | void KeepAlive([in, out] int *Size); 16 | } -------------------------------------------------------------------------------- /RPCInterface/mhclient.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include "meathook_interface.h" 6 | #include 7 | 8 | class MeathookInterface 9 | { 10 | HANDLE m_UnInitialized; 11 | char m_SpawnInfoBuffer[MAX_PATH]; 12 | void StartKeepAliveThread(); 13 | DWORD m_ThreadId; 14 | unsigned char* pszStringBinding = NULL; 15 | 16 | public: 17 | bool m_Initialized; 18 | MeathookInterface() { StartKeepAliveThread(); } 19 | ~MeathookInterface() {} 20 | bool DestroyRpcInterface(); 21 | bool InitializeRpcInterface(); 22 | 23 | bool ExecuteConsoleCommand(unsigned char* pszString); 24 | bool PushEntitiesFile(char* pFileName, char* pBuffer, int Size); 25 | bool GetSpawnInfo(unsigned char* pBuffer); 26 | bool GetEntitiesFile(unsigned char* pBuffer, size_t* Size); 27 | bool GetActiveEncounter(int* Size, char* pBuffer); 28 | bool GetCurrentCheckpoint(int* Size, char* pBuffer); 29 | 30 | static DWORD WINAPI KeepAlive(LPVOID Data); 31 | }; -------------------------------------------------------------------------------- /m34thook/clipboard_helpers.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | const char* get_clipboard_data(); 5 | void set_clipboard_data(const char* dat); -------------------------------------------------------------------------------- /m34thook/cmdsystem.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | struct idCmdArgs { 3 | //offset 0 , size 4 4 | int argc; 5 | //offset 8 , size 1024 6 | char* argv[128]; 7 | //offset 1032 , size 2048 8 | char tokenized[2048]; 9 | }; 10 | 11 | using cmdcb_t = void (*)(idCmdArgs*); 12 | namespace idCmd { 13 | void register_command(const char* name, cmdcb_t, const char* description); 14 | 15 | 16 | void execute_command_text(const char* txt); 17 | 18 | void add_command(const char* txt); 19 | void execute_command_buffer(); 20 | /* 21 | added this so we can scan command implementations 22 | */ 23 | void* find_command_by_name(const char* name); 24 | //das right, im a sneaky fucker i am 25 | cmdcb_t swap_command_impl(const char* name, cmdcb_t function); 26 | } 27 | 28 | struct __declspec(align(8)) idCVar 29 | { 30 | struct cvarCallback_t 31 | { 32 | struct idCallback* callback; 33 | idCVar::cvarCallback_t* next; 34 | }; 35 | 36 | 37 | struct __declspec(align(8)) cvarData_t 38 | { 39 | char* valueString; 40 | int valueInteger; 41 | float valueFloat; 42 | long long valueGameTime; 43 | __declspec(align(8)) float valueSeconds; 44 | int valueMilliseconds; 45 | long long valueMicroseconds; 46 | char* name; 47 | char* resetString; 48 | char* description; 49 | int flags; 50 | float valueMin; 51 | float valueMax; 52 | char** valueStrings; 53 | void* valueCompletion; 54 | idCVar::cvarCallback_t* onChange; 55 | MH_NOINLINE 56 | void call_onchange_functions(); 57 | }; 58 | 59 | idCVar::cvarData_t* data; 60 | idCVar::cvarData_t dataStorage; 61 | idCVar* next; 62 | 63 | 64 | static idCVar* Find(const char* name); 65 | 66 | static idCVar** GetList(unsigned& out_n); 67 | 68 | 69 | static void generate_name_table(); 70 | 71 | static void get_cvardata_rvas(); 72 | 73 | }; 74 | 75 | #include "pregenerated/doom_eternal_cvars_generated.hpp" 76 | 77 | 78 | //array of rvas to each de_cvar_e's location 79 | extern unsigned g_cvardata_rvas[DE_NUMCVARS]; 80 | 81 | 82 | MH_PURE 83 | static idCVar::cvarData_t* cvar_data(de_cvar_e cv) { 84 | 85 | unsigned rv = g_cvardata_rvas[cv]; 86 | 87 | 88 | 89 | return from_de_rva(rv); 90 | } 91 | 92 | 93 | 94 | MH_PURE 95 | static void set_cvar_integer(de_cvar_e cv, int value) { 96 | auto cvd = cvar_data(cv); 97 | cvd->flags |= 0x40000; // CVAR_MODIFIED 98 | cvd->valueInteger = value; 99 | cvd->valueFloat = value; 100 | cvd->call_onchange_functions(); 101 | } -------------------------------------------------------------------------------- /m34thook/compressedfile_override.cpp: -------------------------------------------------------------------------------- 1 | #include "mh_defs.hpp" 2 | 3 | #include "game_exe_interface.hpp" 4 | #include "doomoffs.hpp" 5 | #include "idStr.hpp" 6 | #include 7 | #include "idLib.hpp" 8 | #include "scanner_core.hpp" 9 | #include "fs_hooks.hpp" 10 | using _QWORD = unsigned long long; 11 | using _BYTE = unsigned char; 12 | using _DWORD = unsigned int; 13 | 14 | struct idStrStatic_260_ { 15 | idStr base; 16 | //offset 48 , size 256 17 | char buffer[260]; 18 | }; 19 | struct idFile_Memory { 20 | void* vftbl; 21 | //offset 8 , size 312 22 | //Name of the file, static so we can use files across map heap boundaries without pushing heap 23 | idStrStatic_260_ name; 24 | //offset 320 , size 4 25 | //Open mode. 26 | int mode; 27 | //offset 328 , size 8 28 | //Maximum size of file. 29 | size_t maxSize; 30 | //offset 336 , size 8 31 | //Size of the file. 32 | size_t fileSize; 33 | //offset 344 , size 8 34 | //Allocated size. 35 | size_t allocated; 36 | //offset 352 , size 4 37 | //needed when an idFile_memory is substituted for a real file 38 | unsigned int timestamp; 39 | //offset 360 , size 8 40 | //Buffer holding the file data. 41 | char* filePtr; 42 | //offset 368 , size 8 43 | //Current read/write pointer. 44 | char* curPtr; 45 | //offset 376 , size 1 46 | bool ownsData; 47 | }; 48 | static void __fastcall sub_14033ECC0(idFile_Memory* a1, __int64 a2, __int64 a3) 49 | { 50 | a1->maxSize = a3; 51 | a1->fileSize = a3; 52 | a1->allocated = a3; 53 | a1->mode = 0; 54 | a1->filePtr = (char*)a2; 55 | a1->curPtr = (char*)a2; 56 | a1->ownsData = 0; 57 | } 58 | 59 | void WriteOverloadMemorySize(void* Memory, size_t Size) 60 | { 61 | idFile_Memory* a1 = (idFile_Memory*)Memory; 62 | a1->maxSize = Size; 63 | a1->fileSize = Size; 64 | a1->allocated = Size; 65 | } 66 | 67 | void WriteOverloadMemory(void* Memory, void* Data, size_t Size, size_t Offset) 68 | { 69 | idFile_Memory* a1 = (idFile_Memory*)Memory; 70 | memcpy(a1->filePtr + Offset, Data, Size); 71 | char String[MAX_PATH]; 72 | sprintf_s(String, "MemoryOverload: Written %llu bytes from %llX to %llX\n", Size, (__int64)Data, (__int64)a1->filePtr); 73 | OutputDebugStringA(String); 74 | } 75 | 76 | void OverloadMemory(void *Memory, void* Data, size_t Size) 77 | { 78 | idFile_Memory* a1 = (idFile_Memory*)Memory; 79 | a1->maxSize = Size; 80 | a1->fileSize = Size; 81 | a1->allocated = Size; 82 | a1->mode = 0; 83 | memcpy(a1->filePtr, Data, Size); 84 | char String[MAX_PATH]; 85 | sprintf_s(String, "MemoryOverload: Written %llu bytes from %llX to %llX\n", Size, (__int64)Data, (__int64)a1->filePtr); 86 | OutputDebugStringA(String); 87 | // a1->filePtr = (char*)a2; 88 | // a1->curPtr = (char*)a2; 89 | //(idFile_Memory*)Memory)->ownsData = 1; 90 | } 91 | 92 | void* __fastcall idFileResourceCompressed__GetFile(__int64 a1) 93 | { 94 | __int64 v1; // rsi 95 | idFile_Memory* v3; // rax 96 | idFile_Memory* v4; // rdi 97 | __int64 v5; // rbp 98 | 99 | //the resource size 100 | v1 = *(_QWORD*)(a1 + 112); 101 | v3 = (idFile_Memory*) reinterpret_cast(descan::g_doom_operator_new)(0x180); 102 | //doomcall(doomoffs::doom_operator_new, 0x180); 103 | 104 | char* resource_name = *(char**)(a1 + 8); 105 | idLib::Printf("Compressed resource %s\n", resource_name); 106 | 107 | void*** memorysys = *reinterpret_cast(descan::g_doom_memorysystem); 108 | //*doomsym(doomoffs::memorySystem); 109 | 110 | if (v3) 111 | v4 = reinterpret_cast(descan::g_idfilememory_ctor)(v3, resource_name); 112 | //doomcall(doomoffs::_ZN13idFile_MemoryC2EPKc, v3, resource_name); 113 | else 114 | v4 = 0i64; 115 | size_t override_size = 0; 116 | 117 | FILE* overridef = get_override_for_resource(resource_name, &override_size); 118 | if (overridef) { 119 | v5 = ((__int64(__fastcall*)(void*, __int64, __int64, _QWORD, int, int))memorysys[0][4])(memorysys, override_size, 120 | 154i64, 121 | 0i64, 122 | 16, 123 | -1); 124 | 125 | fread((void*)v5, override_size, 1, overridef); 126 | fclose(overridef); 127 | 128 | //*(_QWORD*)(a1 + 112) = override_size; 129 | v1 = override_size; 130 | goto donezo; 131 | 132 | } 133 | 134 | if (*(_BYTE*)(a1 + 120)) 135 | { 136 | 137 | 138 | v5 = ((__int64(__fastcall*)(void*, __int64, __int64, _QWORD, int, int))memorysys[0][4])(memorysys, v1, 139 | 154i64, 140 | 0i64, 141 | 16, 142 | -1); 143 | { 144 | bool decompress_result = call_as(descan::g_idoodle_decompress, *(_QWORD*)(a1 + 88), *(_QWORD*)(a1 + 96), v5, v1, 0xDu); 145 | 146 | assert(decompress_result); 147 | } 148 | // assert(doomcall(doomoffs::_ZN7idOodle16DecompressBufferEPKvxPvxNS_12compressor_tE, *(_QWORD*)(a1 + 88), *(_QWORD*)(a1 + 96), v5, v1, 0xDu)); 149 | donezo: 150 | sub_14033ECC0(v4, v5, v1); 151 | v4->ownsData = 1; 152 | } 153 | else 154 | { 155 | sub_14033ECC0(v4, *(_QWORD*)(a1 + 88), v1); 156 | } 157 | return v4; 158 | } 159 | -------------------------------------------------------------------------------- /m34thook/doomoffs.hpp: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /m34thook/errorhandling_hooks.cpp: -------------------------------------------------------------------------------- 1 | #include "mh_defs.hpp" 2 | 3 | #include "game_exe_interface.hpp" 4 | #include "doomoffs.hpp" 5 | #include "meathook.h" 6 | #include "cmdsystem.hpp" 7 | #include "idtypeinfo.hpp" 8 | #include "eventdef.hpp" 9 | #include "scanner_core.hpp" 10 | #include "errorhandling_hooks.hpp" 11 | #include 12 | 13 | //trying to help out guy on discord 14 | #define LOG_ERROR_BEFORE_REBOOT 15 | 16 | #define QUICKLOG_PATH "quicklog.txt" 17 | template 18 | __declspec(noreturn) 19 | static void idfatalerror_override(const char* msg, ...) { 20 | va_list ap; 21 | va_start(ap, msg); 22 | char tmpbuf[16384]{ 0 }; 23 | vsprintf_s(tmpbuf, msg, ap); 24 | #ifdef LOG_ERROR_BEFORE_REBOOT 25 | FILE* quicklog_file=nullptr; 26 | fopen_s(&quicklog_file, QUICKLOG_PATH, "w"); 27 | fputs(tmpbuf, quicklog_file); 28 | fclose(quicklog_file); 29 | 30 | #endif 31 | //too lazy to check ret 32 | // 33 | MessageBoxA(nullptr, tmpbuf, Fatal ? "Engine Fatal Error" : "Engine Error", MB_ICONERROR); 34 | 35 | TerminateProcess(GetCurrentProcess(), 1); 36 | 37 | } 38 | 39 | void install_error_handling_hooks() { 40 | redirect_to_func((void*)idfatalerror_override, (uintptr_t)descan::g_idlib_fatalerror); 41 | redirect_to_func((void*)idfatalerror_override, (uintptr_t)descan::g_idlib_error); 42 | } -------------------------------------------------------------------------------- /m34thook/errorhandling_hooks.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | void install_error_handling_hooks(); -------------------------------------------------------------------------------- /m34thook/eventdef.cpp: -------------------------------------------------------------------------------- 1 | #include "mh_defs.hpp" 2 | 3 | #include "eventdef.hpp" 4 | #include 5 | #include 6 | #include "idtypeinfo.hpp" 7 | #include "gameapi.hpp" 8 | idEventDefInterfaceLocal* idEventDefInterfaceLocal::Singleton() { 9 | return reinterpret_cast(get_eventdef_interface()); 10 | } 11 | #pragma clang optimize off 12 | static std::string event_to_string(idEventDefInterfaceLocal* iface, unsigned evnum, bool as_enum) { 13 | 14 | const char* name = iface->GetEventNameForNum(evnum); 15 | 16 | if (!as_enum) { 17 | struct arginfo_t { 18 | std::string name; 19 | std::string type; 20 | }; 21 | 22 | std::vector allargs{}; 23 | 24 | unsigned narg = iface->GetNumEventArgs(evnum); 25 | allargs.reserve(narg); 26 | 27 | 28 | for (unsigned i = 0; i < narg; ++i) { 29 | arginfo_t info{}; 30 | { 31 | idStr temp{}; 32 | iface->GetEventArgName(evnum, i, &temp); 33 | info.name = temp.data; 34 | } 35 | { 36 | idStr temp{}; 37 | iface->GetEventArgTypeName(evnum, i, &temp); 38 | info.type = temp.data; 39 | } 40 | 41 | allargs.push_back(std::move(info)); 42 | } 43 | 44 | 45 | std::string result = name; 46 | result += ":\n"; 47 | 48 | for (auto&& arg : allargs) { 49 | result += "\t"; 50 | result += arg.name; 51 | result += " : "; 52 | result += arg.type; 53 | result += "\n"; 54 | 55 | } 56 | 57 | return result; 58 | } 59 | else { 60 | return "EVID_" + std::string{ name } + " = " + std::to_string(evnum) + ","; 61 | } 62 | } 63 | 64 | void DumpEventDefs(bool as_enum) { 65 | auto iface = idEventDefInterfaceLocal::Singleton(); 66 | 67 | unsigned nevent = iface->GetNumEvents(); 68 | 69 | std::string result_text = as_enum ? "enum evnum_t {\n" : ""; 70 | 71 | 72 | for (unsigned i = 0; i < nevent; ++i) { 73 | result_text += event_to_string(iface, i, as_enum); 74 | result_text += "\n"; 75 | } 76 | 77 | if(as_enum) { 78 | result_text += "};"; 79 | } 80 | FILE* outfile = nullptr; 81 | fopen_s(&outfile, "eternalevents.txt", "w"); 82 | fputs(result_text.c_str(), outfile); 83 | 84 | fclose(outfile); 85 | 86 | 87 | 88 | } 89 | 90 | #pragma clang optimize on 91 | 92 | bool idEventDef::GetArgTypeName(int arg, std::string* tname) { 93 | 94 | char* argTypes; // rcx 95 | int v8; // ebx 96 | int v9; // edi 97 | int v10; // eax 98 | signed int v11; // eax 99 | __int64 v12; // rbx 100 | char Dst[256]; // [rsp+20h] [rbp-128h] BYREF 101 | 102 | argTypes = this->argTypes; 103 | if (!argTypes) 104 | return 0; 105 | v8 = 0; 106 | v9 = 0; 107 | v10 = idStr::Find(argTypes, 59, 0, -1); 108 | if (v10 == -1) 109 | return 0; 110 | while (v8 != arg) 111 | { 112 | v9 = v10 + 1; 113 | ++v8; 114 | v10 = idStr::Find(this->argTypes, 59, v10 + 1, -1); 115 | if (v10 == -1) 116 | return 0; 117 | } 118 | v11 = v10 - v9; 119 | if ((unsigned int)v11 > 0xFF) 120 | v11 = 255; 121 | v12 = v11; 122 | memmove(Dst, &this->argTypes[v9], v11); 123 | Dst[v12] = 0; 124 | *tname = Dst; 125 | 126 | return 1; 127 | } -------------------------------------------------------------------------------- /m34thook/eventdef.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | struct idEventDefInterfaceLocal; 3 | #include "idStr.hpp" 4 | 5 | struct idEventDef; 6 | struct idEventDefInterfaceLocalVftbl 7 | { 8 | void *(__fastcall *dctor)(void *Memory, char a2); 9 | void *_ZN24idEventDefInterfaceLocal8AddEventE11eventType_tPKcS2_cP10idEventDef; 10 | void (__fastcall *nullsub_1)(); 11 | void* (__fastcall *_ZNK24idEventDefInterfaceLocal15GetEventCommandEi)(idEventDefInterfaceLocal * thiz, int); 12 | char **(__fastcall *_ZNK24idEventDefInterfaceLocal9FindEventEPKc)(idEventDefInterfaceLocal* a1, __int64 a2); 13 | __int64 (__fastcall *_ZNK24idEventDefInterfaceLocal18GetEventNumForNameEPKc)(idEventDefInterfaceLocal* a1); 14 | const char *(__fastcall *_ZNK24idEventDefInterfaceLocal18GetEventNameForNumEi)(idEventDefInterfaceLocal* a1, unsigned); 15 | unsigned (*_ZNK24idEventDefInterfaceLocal12GetNumEventsEv)(idEventDefInterfaceLocal*); 16 | unsigned (__fastcall *_ZNK24idEventDefInterfaceLocal15GetNumEventArgsEi)(idEventDefInterfaceLocal* a1, int evt); 17 | void (__fastcall *_ZNK24idEventDefInterfaceLocal19GetEventArgTypeNameEiiR5idStr)(idEventDefInterfaceLocal * thiz, int, int, idStr *); 18 | void (__fastcall *_ZNK24idEventDefInterfaceLocal15GetEventArgNameEiiR5idStr)(idEventDefInterfaceLocal * thiz, int, int, idStr *); 19 | void *field_58; 20 | void (__fastcall *anonymous_0)(); 21 | void *field_68; 22 | }; 23 | 24 | struct idEventDefInterfaceLocal { 25 | idEventDefInterfaceLocalVftbl* vftbl; 26 | 27 | unsigned GetNumEvents() { 28 | return vftbl->_ZNK24idEventDefInterfaceLocal12GetNumEventsEv(this); 29 | } 30 | 31 | const char* GetEventNameForNum(unsigned evtnum) { 32 | return vftbl->_ZNK24idEventDefInterfaceLocal18GetEventNameForNumEi(this, evtnum); 33 | } 34 | 35 | 36 | 37 | unsigned GetNumEventArgs(unsigned evtnum) { 38 | return vftbl->_ZNK24idEventDefInterfaceLocal15GetNumEventArgsEi(this, evtnum); 39 | } 40 | void GetEventArgTypeName(int evt, int arg, idStr* outstr) { 41 | vftbl->_ZNK24idEventDefInterfaceLocal19GetEventArgTypeNameEiiR5idStr(this, evt, arg, outstr); 42 | } 43 | void GetEventArgName(int evt, int arg, idStr* outstr) { 44 | vftbl->_ZNK24idEventDefInterfaceLocal15GetEventArgNameEiiR5idStr(this, evt, arg, outstr); 45 | } 46 | 47 | 48 | idEventDef* FindEvent(const char* name) { 49 | 50 | return (idEventDef*) vftbl->_ZNK24idEventDefInterfaceLocal9FindEventEPKc(this, (long long)name); 51 | } 52 | idEventDef* GetEventForNum(unsigned idx) { 53 | //ewww 54 | return FindEvent(GetEventNameForNum(idx)); 55 | } 56 | static idEventDefInterfaceLocal* Singleton(); 57 | }; 58 | 59 | 60 | void DumpEventDefs(bool as_enum); 61 | enum eventType_t 62 | { 63 | EVENT_GAME = 0x0, 64 | EVENT_ACTION = 0x1, 65 | EVENT_ANIMEVENT = 0x2, 66 | EVENT_FSMEVENT = 0x3, 67 | EVENT_NOTICE = 0x4, 68 | EVENT_SSACTION = 0x5, 69 | }; 70 | 71 | struct idEventDef { 72 | char* name; 73 | char* formatspec; 74 | char* argTypes; 75 | char* argNames; 76 | char* argDefaultValues; 77 | int returnType; 78 | int numargs; 79 | int numstrings; 80 | int eventnum; 81 | int flags; 82 | eventType_t type; 83 | char* timelineEventGroup; 84 | char* comment; 85 | idEventDef* noticeEvent; 86 | idEventDef* next; 87 | //copied from decompilation, for reimplementing scriptcmdent 88 | bool GetArgTypeName(int arg, std::string* tname); 89 | }; -------------------------------------------------------------------------------- /m34thook/fs_hooks.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "idStr.hpp" 4 | 5 | void hook_idfilesystem(); 6 | 7 | #define OVERRIDE_PATHBUF_SIZE 512 8 | 9 | FILE* get_override_for_resource(const char* name, size_t* size_out); 10 | 11 | 12 | void get_override_path(const char* override_relative, char (&buf)[OVERRIDE_PATHBUF_SIZE]); 13 | struct idFile; 14 | enum fsLock_t { 15 | FS_LOCK_SHARED = 0, 16 | FS_LOCK_EXCLUSIVE = 1, 17 | }; 18 | enum fsOrigin_t { 19 | FS_SEEK_CUR = 0, 20 | FS_SEEK_END = 1, 21 | FS_SEEK_SET = 2, 22 | }; 23 | #if 1 24 | /* 25 | checked this against the generated code and vtbl in the game, it matches up perfectly! 26 | */ 27 | class cs_idFile_t { 28 | public: 29 | virtual ~cs_idFile_t() {} 30 | virtual bool IsIDFile_Memory() = 0; 31 | virtual bool IsIDFile_Permanent() = 0; 32 | virtual bool isIDFile_Verified() = 0; 33 | virtual const char* GetFullPath() = 0; 34 | virtual const char* GetName() = 0; 35 | virtual uint64_t Read(void*, unsigned int len) = 0; 36 | virtual uint64_t Write(const void*, unsigned int) = 0; 37 | virtual uint64_t ReadOfs(long long offset, void*, unsigned int) = 0; 38 | virtual uint64_t WriteOfs(long long offset, const void*, unsigned int) = 0; 39 | virtual void* chunky_op(void*, void*, void*) = 0; 40 | virtual bool Lock(unsigned int, fsLock_t) = 0; 41 | virtual bool Unlock(unsigned int) = 0; 42 | virtual size_t Length() = 0; 43 | virtual void SetLength(unsigned int newlength) = 0; 44 | virtual size_t Tell() = 0; 45 | virtual int SeekEx(long long, fsOrigin_t origin) = 0; 46 | virtual size_t Printf(const char*, ...) = 0; 47 | virtual size_t VPrintf(const char* fmt, va_list va) = 0; 48 | virtual size_t WriteFloatString(const char*, ...) = 0; 49 | virtual size_t WriteFloatStringVA(const char* fmt, va_list va) = 0; 50 | virtual size_t Timestamp() = 0; 51 | virtual bool IsWritable() = 0; 52 | virtual void Flush() = 0; 53 | virtual void ForceFlush() = 0; 54 | virtual size_t GetSectorSize() = 0; 55 | virtual int GetDevice() = 0; 56 | virtual bool IsOSNative() = 0; 57 | virtual int GetFileErrorCode() = 0; 58 | virtual void SetFileError() = 0; 59 | virtual size_t ReadString(idStr*) = 0; 60 | virtual size_t ReadDebugTag(const char*, const char*, int) = 0; 61 | virtual uint64_t WriteDebugTag(const char*, const char*) = 0; 62 | 63 | }; 64 | struct idFileVftbl 65 | { 66 | void (*dctor)(idFile* thiz, unsigned int); 67 | bool (*IsIDFile_Memory)(const idFile*); 68 | bool (*IsIDFile_Permanent)(const idFile*); 69 | //name is an assumption, only returns true for idfile_verified 70 | bool (*isIDFile_Verified)(const idFile*); 71 | const char* (*GetFullPath)(idFile* thiz); 72 | const char* (*GetName)(idFile* thiz); 73 | uint64_t(*Read)(idFile* thiz, void*, unsigned int len); 74 | uint64_t(*Write)(idFile* thiz, const void*, unsigned int); 75 | uint64_t(*ReadOfs)(idFile* thiz, long long offset, void*, unsigned int); 76 | uint64_t(*WriteOfs)(idFile* thiz, long long offset, const void*, unsigned int); 77 | void* (*chunky_op)(idFile*, void*, void*, void*); 78 | bool (*Lock)(idFile*, unsigned int, fsLock_t); 79 | bool (*Unlock)(idFile*, unsigned int); 80 | size_t(*Length)(const idFile* thiz); 81 | void (*SetLength)(idFile* thiz, unsigned int newlength); 82 | size_t(*Tell)(const idFile* thiz); 83 | int (*SeekEx)(idFile* thiz, long long, fsOrigin_t origin); 84 | size_t(*Printf)(idFile* thiz, const char*, ...); 85 | size_t(*VPrintf)(idFile* thiz, const char* fmt, va_list va); 86 | size_t(*WriteFloatString)(idFile* thiz, const char*, ...); 87 | size_t(*WriteFloatStringVA)(idFile* thiz, const char* fmt, va_list va); 88 | size_t(*Timestamp)(const idFile* thiz); 89 | bool (*IsWritable)(const idFile* thiz); 90 | void (*Flush)(idFile*); 91 | void (*ForceFlush)(idFile*); 92 | size_t(*GetSectorSize)(const idFile*); 93 | int (*GetDevice)(const idFile*); 94 | bool (*IsOSNative)(const idFile*); 95 | int (*GetFileErrorCode)(const idFile*); 96 | void (*SetFileError)(idFile*); 97 | size_t(*ReadString)(idFile* thiz, idStr*); 98 | size_t(*ReadDebugTag)(idFile* thiz, const char*, const char*, int); 99 | uint64_t(*WriteDebugTag)(idFile* thiz, const char*, const char*); 100 | }; 101 | 102 | struct idFile { 103 | idFileVftbl* vftbl; 104 | }; 105 | #endif -------------------------------------------------------------------------------- /m34thook/grab_spawninfo_Command.cpp: -------------------------------------------------------------------------------- 1 | #include "mh_defs.hpp" 2 | 3 | #include "game_exe_interface.hpp" 4 | #include "doomoffs.hpp" 5 | #include "meathook.h" 6 | #include "cmdsystem.hpp" 7 | #include "idtypeinfo.hpp" 8 | #include "eventdef.hpp" 9 | #include "scanner_core.hpp" 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #if 0 16 | namespace idMath { 17 | void SinCos(float a, float& s, float& c) 18 | { 19 | 20 | //byte_angle_t by = rad2byte(a); 21 | 22 | // DG: non-MSVC version 23 | s = sinf(a); 24 | c = cosf(a); 25 | 26 | } 27 | 28 | const float PI = 3.14159265358979323846f; 29 | 30 | const float M_DEG2RAD = PI / 180.0f; 31 | const float M_RAD2DEG = 180.0f / PI; 32 | 33 | } 34 | 35 | #endif 36 | struct idVec3 { 37 | float x, y, z; 38 | void Set(float _x, float _y, float _z){ 39 | x=_x; 40 | y=_y; 41 | z=_z; 42 | } 43 | }; 44 | 45 | struct idMat3 { 46 | idVec3 mat[ 3 ]; 47 | }; 48 | class idAngles 49 | { 50 | public: 51 | float pitch; 52 | float yaw; 53 | float roll; 54 | idMat3 ToMat3() const; 55 | }; 56 | 57 | //#define DEG2RAD(a) ( (a) * idMath::M_DEG2RAD ) 58 | 59 | idMat3 idAngles::ToMat3() const 60 | { 61 | idMat3 mat; 62 | double sr, sp, sy, cr, cp, cy; 63 | using namespace sh::math; 64 | 65 | 66 | sincos( DEG2RAD( yaw ), sy, cy ); 67 | sincos( DEG2RAD( pitch ), sp, cp ); 68 | sincos( DEG2RAD( roll ),sr, cr ); 69 | 70 | mat.mat[ 0 ].Set( cp * cy, cp * sy, -sp ); 71 | mat.mat[ 1 ].Set( sr * sp * cy + cr * -sy, sr * sp * sy + cr * cy, sr * cp ); 72 | mat.mat[ 2 ].Set( cr * sp * cy + -sr * -sy, cr * sp * sy + -sr * cy, cr * cp ); 73 | 74 | return mat; 75 | } 76 | 77 | 78 | static char clipboard_buffer[1024]; 79 | 80 | const char* get_clipboard_data() { 81 | 82 | if (!OpenClipboard(NULL)) 83 | return nullptr; 84 | HANDLE cbhandle = GetClipboardData(CF_TEXT); 85 | CloseClipboard(); 86 | return (const char*)cbhandle; 87 | } 88 | 89 | void set_clipboard_data(const char* dat) { 90 | if (!OpenClipboard(NULL)) 91 | return; 92 | size_t datsize=strlen(dat)+1; 93 | 94 | HGLOBAL mem = GlobalAlloc( GMEM_MOVEABLE, datsize ); 95 | char *str = (char *)GlobalLock( mem ); 96 | 97 | memcpy(str, dat,datsize); 98 | GlobalUnlock( str ); 99 | EmptyClipboard(); 100 | SetClipboardData(CF_TEXT,mem); 101 | CloseClipboard(); 102 | } 103 | 104 | void cmd_mh_spawninfo(idCmdArgs* args) { 105 | 106 | idCmd::execute_command_text("getviewpos"); 107 | 108 | if (!OpenClipboard(NULL)) 109 | return; 110 | HANDLE cbhandle = GetClipboardData(CF_TEXT); 111 | 112 | float x, y, z; 113 | float yaw, pitch; 114 | 115 | sscanf_s((const char*)cbhandle, "%f %f %f %f %f", &x, &y, &z, &yaw, &pitch); 116 | idAngles angles{pitch, yaw, .0}; 117 | idMat3 mat = angles.ToMat3(); 118 | const char* fmtstr = "spawnOrientation = {\n\tmat = {\n\t\tmat[0] = {\n\t\t\tx = %f;\n\t\t\ty = %f;\n\t\t\tz = %f;\n\t\t}\n\t\tmat[1] = {\n\t\t\tx = %f;\n\t\t\ty = %f;\n\t\t\tz=%f;\n\t\t}\n\t\tmat[2] = {\n\t\t\tx = %f;\n\t\t\ty = %f;\n\t\t\tz = %f;\n\t\t}\n\t}\n}\nspawnPosition = {\n\tx = %f;\n\ty = %f;\n\tz = %f;\n}"; 119 | auto& m = mat.mat; 120 | sprintf_s(clipboard_buffer, fmtstr, m[0].x, m[0].y, m[0].z, m[1].x, m[1].y, m[1].z, m[2].x, m[2].y, m[2].z, x, y, z); 121 | HGLOBAL mem = GlobalAlloc( GMEM_MOVEABLE, 2048 ); 122 | char *str = (char *)GlobalLock( mem ); 123 | 124 | memcpy(str, clipboard_buffer, 2048); 125 | GlobalUnlock( str ); 126 | EmptyClipboard(); 127 | SetClipboardData(CF_TEXT,mem); 128 | CloseClipboard(); 129 | } 130 | 131 | void cmd_mh_ang2mat(idCmdArgs* args) { 132 | double inv1 = .0; 133 | if (args->argc > 1) { 134 | inv1 = atof(args->argv[1]); 135 | } 136 | double inv2 = .0f; 137 | if (args->argc > 2) { 138 | inv2 = atof(args->argv[2]); 139 | } 140 | 141 | double inv3 = .0f; 142 | if (args->argc > 3) { 143 | inv3 = atof(args->argv[3]); 144 | } 145 | idAngles angles{ (float)inv1, (float)inv2, (float)inv3 }; 146 | idMat3 mat = angles.ToMat3(); 147 | //copypaste 148 | const char* fmtstr = "{\n\tmat = {\n\t\tmat[0] = {\n\t\t\tx = %f;\n\t\t\ty = %f;\n\t\t\tz = %f;\n\t\t}\n\t\tmat[1] = {\n\t\t\tx = %f;\n\t\t\ty = %f;\n\t\t\tz=%f;\n\t\t}\n\t\tmat[2] = {\n\t\t\tx = %f;\n\t\t\ty = %f;\n\t\t\tz = %f;\n\t\t}\n\t}\n}\n"; 149 | auto& m = mat.mat; 150 | sprintf_s(clipboard_buffer, fmtstr, m[0].x, m[0].y, m[0].z, m[1].x, m[1].y, m[1].z, m[2].x, m[2].y, m[2].z); 151 | set_clipboard_data(clipboard_buffer); 152 | } 153 | -------------------------------------------------------------------------------- /m34thook/idLib.cpp: -------------------------------------------------------------------------------- 1 | #include "mh_defs.hpp" 2 | 3 | #include "game_exe_interface.hpp" 4 | #include "doomoffs.hpp" 5 | #include "idLib.hpp" 6 | #include "scanner_core.hpp" 7 | void idLib::VPrintf(int severity, const char* fmt, va_list ap) { 8 | // doomcall(doomoffs::_ZN5idLib7VPrintfE15printSeverity_tPKcSt9__va_list,1, severity, fmt, ap); 9 | call_as(descan::g_idlib_vprintf,1, severity, fmt, ap); 10 | } -------------------------------------------------------------------------------- /m34thook/idLib.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace idLib { 5 | void VPrintf(int severity, const char* fmt, va_list ap); 6 | static void Printf(const char* format, ...) { 7 | va_list ap; 8 | va_start(ap, format); 9 | VPrintf(1, format, ap); 10 | va_end(ap); 11 | } 12 | //for compat with decomp code 13 | template 14 | static void Warning(const char* format, Ts... vs) { 15 | 16 | Printf(format, vs...); 17 | } 18 | } 19 | enum memTag_t; 20 | struct __declspec(align(8)) idHashIndex 21 | { 22 | int* hash; 23 | int* indexChain; 24 | int hashSize; 25 | int indexSize; 26 | int granularity; 27 | int hashMask; 28 | int lookupMask; 29 | memTag_t memTag; 30 | }; 31 | struct idHashIndexWithExtra 32 | { 33 | idHashIndex base; 34 | int field_28; 35 | int initial_gran; 36 | }; 37 | struct idListVoid 38 | { 39 | unsigned __int64* list; 40 | int num; 41 | int size; 42 | __int16 granularity; 43 | unsigned __int8 memTag; 44 | unsigned __int8 listStatic; 45 | }; 46 | 47 | 48 | class idCallback { 49 | public: 50 | virtual ~idCallback() {} 51 | virtual void Call() = 0; 52 | virtual idCallback* Clone() = 0; 53 | }; -------------------------------------------------------------------------------- /m34thook/idStr.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "game_exe_interface.hpp" 3 | #include "scanner_core.hpp" 4 | struct idStr { 5 | void* vftbl; 6 | char* data; 7 | int len; 8 | //top bit is used to store a flag that indicates if the string data is static or not 9 | int allocedAndFlag; 10 | char baseBuffer[20]; 11 | 12 | 13 | idStr() { 14 | call_as(descan::g_idstr__idstr, this); 15 | //doomcall(doomoffs::_ZN5idStrC2Ev, this); 16 | } 17 | 18 | 19 | ~idStr() { 20 | call_as(descan::g_idstr_dctor, this); 21 | } 22 | 23 | idStr& operator = (const char* s) { 24 | call_as(descan::g_idstr_assign_charptr, this, s); 25 | return *this; 26 | } 27 | static int idStr::Find(const char* str, const char c, int start, int end) 28 | { 29 | __int64 v4; // r10 30 | int v5; // er8 31 | const char* v6; // rax 32 | __int64 v7; // rax 33 | 34 | v4 = start; 35 | if (end == -1) 36 | { 37 | v5 = 0; 38 | if (*str) 39 | { 40 | v6 = str; 41 | do 42 | { 43 | ++v6; 44 | ++v5; 45 | } while (*v6); 46 | } 47 | end = v5 - 1; 48 | } 49 | v7 = v4; 50 | if (v4 > end) 51 | return 0xFFFFFFFFi64; 52 | while (str[v7] != c) 53 | { 54 | ++v7; 55 | v4 = v4 + 1; 56 | if (v7 > end) 57 | return 0xFFFFFFFFi64; 58 | } 59 | return (unsigned int)v4; 60 | } 61 | }; 62 | static const char* blankstr = ""; 63 | struct idAtomicString 64 | { 65 | char* str; 66 | void set(const char* s) { 67 | call_as(descan::g_atomic_string_set, this, s); 68 | } 69 | }; 70 | template 71 | struct idStrStaticBase 72 | { 73 | idStr base; 74 | char buffer[N]; 75 | }; 76 | 77 | template 78 | struct idStrStatic 79 | { 80 | idStrStaticBase base; 81 | }; 82 | template 83 | struct idStrDynStatic 84 | { 85 | idStrStaticBase base; 86 | }; 87 | -------------------------------------------------------------------------------- /m34thook/id_resources_lowlevel.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | std::uint64_t checksum_override_data(std::uint8_t* a1, int a2, int a3) 3 | { 4 | unsigned int v4; // er11 5 | unsigned int v5; // er8 6 | unsigned __int64 v6; // r10 7 | unsigned int v7; // ecx 8 | int v8; // eax 9 | int v9; // eax 10 | int v10; // edx 11 | int v11; // edx 12 | 13 | v4 = a3 ^ a2; 14 | v5 = 0; 15 | if (a2 >= 8) 16 | { 17 | v6 = (unsigned __int64)(unsigned int)a2 >> 3; 18 | a2 -= 8 * ((unsigned int)a2 >> 3); 19 | do 20 | { 21 | v7 = 1540483477 * ((1540483477 * *(unsigned int*)a1) ^ ((unsigned int)(1540483477 * *(unsigned int*)a1) >> 24)); 22 | v8 = *((unsigned int*)a1 + 1); 23 | a1 += 8; 24 | v4 = v7 ^ (1540483477 * v4); 25 | v5 = (1540483477 * ((1540483477 * v8) ^ ((unsigned int)(1540483477 * v8) >> 24))) ^ (1540483477 * v5); 26 | --v6; 27 | } while (v6); 28 | } 29 | if (a2 >= 4) 30 | { 31 | v9 = *(unsigned int*)a1; 32 | a1 += 4; 33 | v4 = (1540483477 * ((1540483477 * v9) ^ ((unsigned int)(1540483477 * v9) >> 24))) ^ (1540483477 * v4); 34 | a2 -= 4; 35 | } 36 | v10 = a2 - 1; 37 | if (!v10) 38 | goto LABEL_11; 39 | v11 = v10 - 1; 40 | if (!v11) 41 | { 42 | LABEL_10: 43 | v5 ^= a1[1] << 8; 44 | LABEL_11: 45 | v5 = 1540483477 * (v5 ^ *a1); 46 | return ((unsigned __int64)(1540483477 47 | * ((1540483477 * (v4 ^ (v5 >> 18))) ^ ((1540483477 48 | * (v5 ^ ((1540483477 * (v4 ^ (v5 >> 18))) >> 22))) >> 17))) << 32) | (1540483477 * ((1540483477 * (v5 ^ ((1540483477 * (v4 ^ (v5 >> 18))) >> 22))) ^ ((1540483477 * ((1540483477 * (v4 ^ (v5 >> 18))) ^ ((1540483477 * (v5 ^ ((1540483477 * (v4 ^ (v5 >> 18))) >> 22))) >> 17))) >> 19))); 49 | } 50 | if (v11 != 1) 51 | return ((unsigned __int64)(1540483477 52 | * ((1540483477 * (v4 ^ (v5 >> 18))) ^ ((1540483477 53 | * (v5 ^ ((1540483477 * (v4 ^ (v5 >> 18))) >> 22))) >> 17))) << 32) | (1540483477 * ((1540483477 * (v5 ^ ((1540483477 * (v4 ^ (v5 >> 18))) >> 22))) ^ ((1540483477 * ((1540483477 * (v4 ^ (v5 >> 18))) ^ ((1540483477 * (v5 ^ ((1540483477 * (v4 ^ (v5 >> 18))) >> 22))) >> 17))) >> 19))); 54 | v5 ^= a1[2] << 16; 55 | goto LABEL_10; 56 | } -------------------------------------------------------------------------------- /m34thook/id_resources_lowlevel.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | struct idResourceStorageDiskStreamer {}; 3 | struct idResourceStorageInterface {}; 4 | struct idResourceHeader 5 | { 6 | char bytes[119]; 7 | char end; 8 | }; 9 | 10 | struct idResourceSpecialHash 11 | { 12 | int hashType; 13 | int reserved; 14 | __int64 hash; 15 | }; 16 | struct idResourceMetaData; 17 | struct idResourceEntryOptions 18 | { 19 | unsigned __int64 uncompressedSize; 20 | unsigned __int64 dataCheckSum; 21 | unsigned __int64 generationTimeStamp; 22 | unsigned __int64 defaultHash; 23 | unsigned int version; 24 | unsigned int flags; 25 | char compMode; 26 | char reserved0; 27 | unsigned __int16 variation; 28 | unsigned int reserved2; 29 | unsigned __int64 reservedForVariations; 30 | }; 31 | 32 | struct idResourceEntry 33 | { 34 | const char* resourceTypeString; 35 | const char* nameString; 36 | const char* descString; 37 | unsigned int* depIndices; 38 | char** strings; 39 | idResourceSpecialHash* specialHashes; 40 | idResourceMetaData** metaEntries; 41 | unsigned __int64 dataOffset; 42 | unsigned __int64 dataSize; 43 | idResourceEntryOptions options; 44 | unsigned __int16 numStrings; 45 | unsigned __int16 numSources; 46 | unsigned __int16 numDependencies; 47 | unsigned __int16 numSpecialHashes; 48 | unsigned __int16 numMetaEntries; 49 | char field_8A; 50 | char field_8B; 51 | int field_8C; 52 | }; 53 | enum idResourceDependencyType 54 | { 55 | RES_DEP_UNKNOWN = 0x0, 56 | RES_DEP_FILE = 0x1, 57 | RES_DEP_RESOURCE = 0x2, 58 | RES_DEP_DECL_SRC = 0x3, 59 | RES_DEP_CVAR = 0x4, 60 | RES_DEP_EMBEDDED_RESOURCE = 0x5, 61 | RES_DEP_CALLBACK = 0x6, 62 | }; 63 | 64 | struct idResourceDependency 65 | { 66 | char* type; 67 | char* name; 68 | idResourceDependencyType depType; 69 | unsigned int depSubType; 70 | unsigned __int64 hashOrTimestamp; 71 | }; 72 | 73 | struct __declspec(align(8)) resourceStorage_t 74 | { 75 | idStrDynStatic<256> containerFilename; 76 | struct idFile* containerFile; 77 | __int64 timestamp; 78 | __int64 field_140; 79 | idResourceHeader field_148; 80 | idResourceEntry* resourceEntries; 81 | idHashIndexWithExtra resourceEntryMap; 82 | idResourceDependency* containerDependencies; 83 | __int64 field_200; 84 | __int64 field_208; 85 | __int64** pqword210; 86 | __int64 magic; 87 | char field_220; 88 | }; 89 | std::uint64_t checksum_override_data(std::uint8_t* a1, int a2, int a3); -------------------------------------------------------------------------------- /m34thook/idmath.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | struct idColor { 3 | float r, g, b, a; 4 | int PackColor() const 5 | { 6 | int v1; // edx 7 | unsigned __int8 v2; // al 8 | int v3; // er9 9 | int v4; // edx 10 | unsigned __int8 v5; // al 11 | int v6; // er8 12 | int v7; // edx 13 | unsigned __int8 v8; // al 14 | int v9; // edx 15 | int v10; // ecx 16 | unsigned __int8 v11; // al 17 | 18 | v1 = (int)(float)(this->r * 255.0); 19 | if (v1 >= 0) 20 | { 21 | v2 = (int)(float)(this->r * 255.0); 22 | if (v1 > 255) 23 | v2 = -1; 24 | } 25 | else 26 | { 27 | v2 = 0; 28 | } 29 | v3 = v2; 30 | v4 = (int)(float)(this->g * 255.0); 31 | if (v4 >= 0) 32 | { 33 | v5 = (int)(float)(this->g * 255.0); 34 | if (v4 > 255) 35 | v5 = -1; 36 | } 37 | else 38 | { 39 | v5 = 0; 40 | } 41 | v6 = v5; 42 | v7 = (int)(float)(this->b * 255.0); 43 | if (v7 >= 0) 44 | { 45 | v8 = (int)(float)(this->b * 255.0); 46 | if (v7 > 255) 47 | v8 = -1; 48 | } 49 | else 50 | { 51 | v8 = 0; 52 | } 53 | v9 = v8; 54 | v10 = (int)(float)(this->a * 255.0); 55 | if (v10 >= 0) 56 | { 57 | v11 = v10; 58 | if (v10 > 255) 59 | v11 = -1; 60 | } 61 | else 62 | { 63 | v11 = 0; 64 | } 65 | return v3 | ((v6 | ((v9 | (v11 << 8)) << 8)) << 8); 66 | } 67 | }; 68 | 69 | struct idVec3 { 70 | float x, y, z; 71 | 72 | float Distance(idVec3& other) { 73 | 74 | float xx = x - other.x; 75 | float yy = y - other.y; 76 | float zz = z - other.z; 77 | xx *= xx; 78 | yy *= yy; 79 | zz *= zz; 80 | 81 | return sqrtf(xx + yy + zz); 82 | 83 | } 84 | 85 | void Set(float val) { 86 | x = val; 87 | y = val; 88 | z = val; 89 | } 90 | }; 91 | struct idVec2 { 92 | float x, y; 93 | }; 94 | struct idVec4 { 95 | float x, y, z, w; 96 | }; 97 | struct idAngles 98 | { 99 | float pitch; 100 | float yaw; 101 | float roll; 102 | }; 103 | 104 | struct idDrawVert 105 | { 106 | idVec3 pos; 107 | idVec2 lightmapUV; 108 | unsigned __int8 normal[4]; 109 | unsigned __int8 tangent[4]; 110 | unsigned __int8 color[4]; 111 | idVec2 materialUV; 112 | unsigned __int16 materials[2]; 113 | unsigned __int16 unused[2]; 114 | }; 115 | 116 | 117 | struct idMat3 { 118 | idVec3 mat[3]; 119 | }; 120 | /* 121 | extern idColor colorBlack; 122 | extern idColor colorWhite; 123 | extern idColor colorRed; 124 | extern idColor colorGreen; 125 | extern idColor colorBlue; 126 | extern idColor colorYellow; 127 | extern idColor colorMagenta; 128 | extern idColor colorCyan; 129 | extern idColor colorOrange; 130 | extern idColor colorPurple; 131 | extern idColor colorPink; 132 | extern idColor colorBrown; 133 | extern idColor colorLtGrey; 134 | extern idColor colorMdGrey; 135 | extern idColor colorDkGrey;*/ 136 | static constexpr idColor colorBlack = idColor{ 0.00f, 0.00f, 0.00f, 1.00f }; 137 | static constexpr idColor colorWhite = idColor{ 1.00f, 1.00f, 1.00f, 1.00f }; 138 | static constexpr idColor colorRed = idColor{ 1.00f, 0.00f, 0.00f, 1.00f }; 139 | static constexpr idColor colorGreen = idColor{ 0.00f, 1.00f, 0.00f, 1.00f }; 140 | static constexpr idColor colorBlue = idColor{ 0.00f, 0.00f, 1.00f, 1.00f }; 141 | static constexpr idColor colorYellow = idColor{ 1.00f, 1.00f, 0.00f, 1.00f }; 142 | static constexpr idColor colorMagenta = idColor{ 1.00f, 0.00f, 1.00f, 1.00f }; 143 | static constexpr idColor colorCyan = idColor{ 0.00f, 1.00f, 1.00f, 1.00f }; 144 | static constexpr idColor colorOrange = idColor{ 1.00f, 0.50f, 0.00f, 1.00f }; 145 | static constexpr idColor colorPurple = idColor{ 0.60f, 0.00f, 0.60f, 1.00f }; 146 | static constexpr idColor colorPink = idColor{ 0.73f, 0.40f, 0.48f, 1.00f }; 147 | static constexpr idColor colorBrown = idColor{ 0.40f, 0.35f, 0.08f, 1.00f }; 148 | static constexpr idColor colorLtGrey = idColor{ 0.75f, 0.75f, 0.75f, 1.00f }; 149 | static constexpr idColor colorMdGrey = idColor{ 0.50f, 0.50f, 0.50f, 1.00f }; 150 | static constexpr idColor colorDkGrey = idColor{ 0.25f, 0.25f, 0.25f, 1.00f }; 151 | 152 | -------------------------------------------------------------------------------- /m34thook/mapfile.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | struct idMapGroups { 3 | void* vftbl; 4 | //Offset 8, size 24 5 | idList < idStr , TAG_IDLIST , false > groupList; 6 | }; 7 | struct idMapEntity : public idMapGroups { 8 | 9 | }; 10 | struct idMapEntityLocal : public idMapEntity { 11 | //Offset 32, size 8 12 | idDeclEntityDef* entityDef; 13 | //Offset 40, size 4 14 | int entityDefLine; 15 | //Offset 48, size 80 16 | idMapModel model; 17 | //Offset 128, size 8 18 | //the parent of this reference 19 | idMapEntityLocal* parentReference; 20 | //Offset 136, size 48 21 | //reference map id, "" by default 22 | idStr refId; 23 | //Offset 184, size 4 24 | //prefab instanceId 25 | unsigned int instanceId; 26 | //Offset 192, size 48 27 | //original name if instanced from prefab 28 | idStr originalName; 29 | //Offset 240, size 24 30 | idList < idStr , TAG_IDLIST , false > layerList; 31 | //Offset 264, size 8 32 | idMapEntityEditorData* mapEntityEditorData; 33 | }; 34 | 35 | struct idMapFile { 36 | void* vftbl; 37 | }; 38 | 39 | 40 | struct idMapFileLocal : public idMapFile { 41 | //Offset 8, size 48 42 | idStr name; 43 | //Offset 56, size 4 44 | int version; 45 | //Offset 60, size 4 46 | int hierarchyVersion; 47 | //Offset 64, size 4 48 | unsigned int fileTime; 49 | //Offset 68, size 4 50 | unsigned int geometryCRC; 51 | //Offset 72, size 1 52 | bool hasPrimitiveData; 53 | //Offset 73, size 1 54 | bool isEntitiesFile; 55 | //Offset 80, size 24 56 | idList < idMapEntityLocal * , TAG_IDLIST , false > entities; 57 | //Offset 104, size 56 58 | idMapEditorStates groupStates; 59 | //Offset 160, size 24 60 | idList < idMapReference * , TAG_IDLIST , false > referenceMaps; 61 | //Offset 184, size 8 62 | idMapEntityLocal* parentReference; 63 | //Offset 192, size 48 64 | idStr mapModelFolder; 65 | //Offset 240, size 1 66 | bool expandReferences; 67 | //Offset 248, size 8 68 | idMapInstance* mapInstance; 69 | //Offset 256, size 1 70 | bool entitiesAreReference; 71 | //Offset 257, size 1 72 | bool ignoreGroupInfo; 73 | //Offset 258, size 1 74 | //If true, refmaps that are parsed can be skipped based on map properties. 75 | bool isRefmapSkippingAllowed; 76 | //Offset 264, size 24 77 | idList < idPrefabInstance * , TAG_IDLIST , false > prefabInstances; 78 | //Offset 288, size 24 79 | //A list of identifier-value string pairs for storing properties in the map. Properties identifiers are NOT unique. 80 | idList < idPair < idStr , idStr > , TAG_IDLIST , false > properties; 81 | }; 82 | -------------------------------------------------------------------------------- /m34thook/meathook.cpp: -------------------------------------------------------------------------------- 1 | #include "xbyak/xbyak.h" 2 | #include "mh_defs.hpp" 3 | 4 | #include "game_exe_interface.hpp" 5 | #include "doomoffs.hpp" 6 | #include "meathook.h" 7 | #include "cmdsystem.hpp" 8 | #include "idtypeinfo.hpp" 9 | #include "eventdef.hpp" 10 | #include "scanner_core.hpp" 11 | #include "idLib.hpp" 12 | #include "idStr.hpp" 13 | #include "clipboard_helpers.hpp" 14 | #include 15 | #include "errorhandling_hooks.hpp" 16 | #include "gameapi.hpp" 17 | #include "idmath.hpp" 18 | #include "memscan.hpp" 19 | #include "mh_memmanip_cmds.hpp" 20 | #include "snaphakalgo.hpp" 21 | #include 22 | #include "mh_guirender.hpp" 23 | #include "mh_editor_mode.hpp" 24 | #include 25 | #include 26 | 27 | extern void install_spawning_commands(); 28 | extern void install_cheat_cmds(); 29 | extern void install_query_cmds(); 30 | extern void install_editor_cmds(); 31 | extern void install_dumpngen_cmds(); 32 | extern void install_miscndev_cmds(); 33 | //executed on first frame 34 | //see mh_cmds_cheats 35 | extern void cheats_postinit(); 36 | 37 | 38 | void* __fastcall idFileResourceCompressed__GetFile(__int64 a1); 39 | 40 | static bool return_1() { 41 | 42 | return 1; 43 | } 44 | 45 | 46 | static void do_nothing() { 47 | 48 | } 49 | 50 | 51 | 52 | 53 | static void* g_original_renderthread_run = nullptr; 54 | static __int64 testdebugtools(void* x) { 55 | 56 | //call_as(descan::g_renderDebugTools, get_rendersystem()); 57 | return call_as<__int64>(g_original_renderthread_run, x); 58 | } 59 | void meathook_final_init() { 60 | //compute classinfo object super object deltas for quick inheritance traversal 61 | idType::init_prop_rva_table(); 62 | idType::compute_classinfo_mh_payloads(); 63 | idCVar::get_cvardata_rvas(); 64 | 65 | 66 | 67 | descan::run_gamelib_postinit_scangroups(); 68 | cheats_postinit(); 69 | } 70 | 71 | static void* nothinfunc = (void*)do_nothing; 72 | static void do_cvar_toggle() { 73 | 74 | /* 75 | replace offset 16 on vftbl of idcmdsystem with a no-op function. 76 | the function sets a variable on a pointer in tls, and it is called twice to disable first dev commands, then executing bound dev commands 77 | swapping it out eliminates this issue, also renders g_command_patch_area useless 78 | */ 79 | void* cmdsystem = *(void**)descan::g_idcmdsystem; 80 | 81 | void* cmdsystem_vftbl = *(void**)cmdsystem; 82 | 83 | 84 | swap_out_ptrs(reinterpret_cast(cmdsystem_vftbl) + 16, ¬hinfunc, 1, false); 85 | 86 | 87 | } 88 | static void test_cvar_disable(idCmdArgs* args) { 89 | do_cvar_toggle(); 90 | 91 | 92 | } 93 | 94 | 95 | 96 | void meathook_init() { 97 | 98 | install_gameapi_hooks(); 99 | 100 | void** vtbl_render = get_class_vtbl(".?AVidRenderThread@@"); 101 | g_original_renderthread_run = (void*)testdebugtools; 102 | 103 | 104 | swap_out_ptrs(&vtbl_render[1], &g_original_renderthread_run, 1, false); 105 | 106 | 107 | 108 | 109 | 110 | //redirect_to_func(descan::g_renderDebugTools, (uintptr_t)descan::g_idRender_PrintStats, true); 111 | redirect_to_func((void*)idFileResourceCompressed__GetFile, (uintptr_t)/* doomsym(doomoffs::idFileResourceCompressed__GetFile)*/ descan::g_idfilecompressed_getfile, true); 112 | //g_levelReload = redirect_to_func((void*)LevelReload_CaptureParameters, (uintptr_t)/* doomsym(doomoffs::idFileResourceCompressed__GetFile)*/ descan::g_levelreload, true); 113 | //g_func992170 = redirect_to_func((void*)LevelReload_PreventUninitializedTick, (uintptr_t)/* doomsym(doomoffs::idFileResourceCompressed__GetFile)*/ descan::g_init_func_rva_992170, true); 114 | install_error_handling_hooks(); 115 | //no longer needed, see below 116 | //unsigned patchval_enable_commands = 0; 117 | do_cvar_toggle(); 118 | 119 | 120 | //patch_memory(descan::g_command_patch_area, 4, (char*)&patchval_enable_commands); 121 | 122 | #ifdef MH_DEV_BUILD 123 | //for array patch for expanding ai 124 | //please remove for actual release 125 | DWORD fuckyu; 126 | VirtualProtect(g_blamdll.image_base, g_blamdll.image_size, PAGE_EXECUTE_READWRITE, &fuckyu); 127 | #endif 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | idCmd::register_command("test_cvar_disable", test_cvar_disable, "fff"); 136 | 137 | install_memmanip_cmds(); 138 | install_spawning_commands(); 139 | install_cheat_cmds(); 140 | install_query_cmds(); 141 | install_editor_cmds(); 142 | install_dumpngen_cmds(); 143 | install_miscndev_cmds(); 144 | //idCmd::register_command("mh_test_persistent_text", test_persistent_text, "Test persistent onscreen text"); 145 | //idCmd::register_command("mh_phys_test", test_physics_op, "test physics ops"); 146 | // Start rpc server. 147 | } -------------------------------------------------------------------------------- /m34thook/meathook.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | void meathook_init(); 5 | /* 6 | * executes on first tick of idCommonLocal::Frame 7 | run late-stage scanners, and load plugins 8 | */ 9 | void meathook_final_init(); 10 | 11 | -------------------------------------------------------------------------------- /m34thook/memorySystem.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "game_exe_interface.hpp" 3 | #include "doomoffs.hpp" 4 | 5 | #include "scanner_core.hpp" 6 | 7 | static inline void* idMemorySystem_malloc(size_t sz, unsigned tag, unsigned unk) { 8 | void*** memorysys = *reinterpret_cast(descan::g_doom_memorysystem); 9 | return ((void*(__fastcall*)(void*, __int64, __int64, unsigned long long, int, int))memorysys[0][4])(memorysys, sz, 10 | tag, 11 | unk, 12 | 16, 13 | -1); 14 | } 15 | 16 | static inline void idMemorySystem_free(void* ptr) { 17 | void*** memorysys = *reinterpret_cast(descan::g_doom_memorysystem); 18 | return ((void(__fastcall*)(void*, void*))memorysys[0][6])(memorysys, ptr); 19 | 20 | } 21 | 22 | static inline void* idNew(size_t nbytes) { 23 | 24 | return call_as(descan::g_doom_operator_new, nbytes, 0); 25 | } 26 | 27 | static inline void idDelete(void* vp) { 28 | call_as(descan::g_doom_operator_delete, vp); 29 | } -------------------------------------------------------------------------------- /m34thook/memscan.cpp: -------------------------------------------------------------------------------- 1 | #include "mh_defs.hpp" 2 | 3 | #include "memscan.hpp" 4 | #include "cmdsystem.hpp" 5 | #include "game_exe_interface.hpp" 6 | #include "scanner_core.hpp" 7 | #include "idtypeinfo.hpp" 8 | #include "gameapi.hpp" 9 | #include "eventdef.hpp" 10 | static std::mutex g_failure_message_mutex{}; 11 | 12 | __declspec(noinline) 13 | void scanner_failure_message(const char* scanner_name) { 14 | g_failure_message_mutex.lock(); 15 | { 16 | char tmpbuf[1024]; 17 | sprintf_s(tmpbuf, "Blockscan entry %s failed to locate its required patterns. The DLL may still function normally, but some features may not work. If the game does not start up, go into your doom eternal install directory and delete XINPUT1_3.dll. Check the Doom 2016+ Mods discord for an updated version of MH for this version of Eternal.", scanner_name); 18 | MessageBoxA(nullptr, tmpbuf, "M347h00k (XINPUT1_3.dll, in your Doom Eternal directory) -> Scanner Failed", 0); 19 | } 20 | g_failure_message_mutex.unlock(); 21 | } 22 | 23 | void* scanner_late_get_cvar(const char* s) { 24 | return idCVar::Find(s); 25 | } 26 | 27 | unsigned scanner_late_get_struct_size(const char* s) { 28 | return idType::FindClassInfo(s)->size; 29 | } 30 | void* scanner_late_get_eventdef(const char* name) { 31 | 32 | return idEventDefInterfaceLocal::Singleton()->FindEvent(name); 33 | } -------------------------------------------------------------------------------- /m34thook/mh_cmds_dump_and_gen.cpp: -------------------------------------------------------------------------------- 1 | #include "xbyak/xbyak.h" 2 | #include "mh_defs.hpp" 3 | 4 | #include "game_exe_interface.hpp" 5 | #include "doomoffs.hpp" 6 | #include "meathook.h" 7 | #include "cmdsystem.hpp" 8 | #include "idtypeinfo.hpp" 9 | #include "eventdef.hpp" 10 | #include "scanner_core.hpp" 11 | #include "idLib.hpp" 12 | #include "idStr.hpp" 13 | #include "clipboard_helpers.hpp" 14 | #include 15 | #include "errorhandling_hooks.hpp" 16 | #include "gameapi.hpp" 17 | #include "idmath.hpp" 18 | #include "memscan.hpp" 19 | #include "mh_memmanip_cmds.hpp" 20 | #include "snaphakalgo.hpp" 21 | #include 22 | #include "mh_guirender.hpp" 23 | #include "mh_editor_mode.hpp" 24 | #include 25 | 26 | 27 | void idlib_dump(idCmdArgs* args) { 28 | idType::do_idlib_dump(); 29 | return; 30 | } 31 | 32 | void event_dump(idCmdArgs* args) { 33 | DumpEventDefs(args->argc < 2 ? false : args->argv[1][0] != '0'); 34 | } 35 | 36 | 37 | 38 | 39 | static void mh_genproptree(idCmdArgs* args) { 40 | 41 | idType::generate_unique_property_key_tree(); 42 | } 43 | static void mh_dumppropidxinfo(idCmdArgs* args) { 44 | 45 | idType::dump_prop_rvas(); 46 | } 47 | 48 | static void mh_gencvarset(idCmdArgs* args) { 49 | 50 | idCVar::generate_name_table(); 51 | } 52 | 53 | void idc_dump(idCmdArgs* args) { 54 | idType::generate_idc(); 55 | } 56 | 57 | void install_dumpngen_cmds() { 58 | 59 | 60 | idCmd::register_command("mh_dumpeventdefs", event_dump, "mh_dumpeventdefs "); 61 | 62 | idCmd::register_command("idlib_dump", idlib_dump, "idlib_dump"); 63 | idCmd::register_command("mh_genpropset", mh_genproptree, "Regenerated doom_eternal_properties_generated.cpp/hpp for use in mh builds. not for users"); 64 | 65 | idCmd::register_command("mh_gencvarset", mh_gencvarset, "Regenerate doom_eternal_cvars_generated.cpp/hpp for mh build"); 66 | idCmd::register_command("mh_dumppropidxinfo", mh_dumppropidxinfo, "Debug command for dumping the corresponding addresses/rvas for property indices"); 67 | idCmd::register_command("idlib_idc", idc_dump, "Generates a .idc file for ida that defines all structs and enums that have typeinfo for this build of eternal"); 68 | 69 | } 70 | -------------------------------------------------------------------------------- /m34thook/mh_dev_hooks.cpp: -------------------------------------------------------------------------------- 1 | #if 1 2 | 3 | 4 | #include "xbyak/xbyak.h" 5 | #include "mh_defs.hpp" 6 | 7 | #include "game_exe_interface.hpp" 8 | #include "memscan.hpp" 9 | #include "scanner_core.hpp" 10 | 11 | //one granula 12 | #define EXECMEM_NEEDED 65536 13 | 14 | 15 | struct register_ringbuff_element_t { 16 | uintptr_t g_calltime; 17 | uintptr_t gpregs[15]; 18 | }; 19 | 20 | //17*8 = 136b per 21 | //there are about 100k functions, lets assume 80k total actually are large enough to have a check 22 | // assume machine has 256 gb, about 10-15% used up by ida instances+the game running 23 | // 24 | // **** this math has changed somewhat, cut gpregs down to 15 registers+calltime so that the memory is always 32 bytes aligned and can be written with nt writes 25 | // 26 | //so lets say 220gb 27 | //220gb / 80k = 2952790 per call 28 | //so 21711 ringbuffer elements per call, but to make wrapping around easier, we can round down to 16384 29 | //so we use only around 166 gb total, but we will probably need a good chunk for the lookup table 30 | 31 | 32 | static uintptr_t g_current_calltime = 0; 33 | 34 | 35 | #define NUM_RESERVED_RINGBUFFS 10000ULL 36 | #define NUM_ELEMENTS_PER_RINGBUFF 16384ULL 37 | 38 | 39 | static uintptr_t get_actual_returnaddr(uintptr_t addr){ 40 | return addr - 5; //points to 0xE8 now 41 | } 42 | /* 43 | writing the logic out, but this should be jitted 44 | */ 45 | static unsigned get_returnaddr_key(uintptr_t addr) { 46 | 47 | addr = get_actual_returnaddr(addr); 48 | addr -= (uintptr_t)g_blamdll.image_base; 49 | /* 50 | all functions starts get aligned to 16 bytes, so we will always still be in the function if we align down 51 | */ 52 | 53 | return (addr & ~15ULL) >> 4; 54 | 55 | } 56 | 57 | 58 | using ringbuffer_list_ele_t = std::array; 59 | /* 60 | //todo: allocate using hugepages 61 | */ 62 | static ringbuffer_list_ele_t* g_ringbuffers= nullptr; 63 | 64 | static uintptr_t g_current_free_ringbuff = 0; 65 | 66 | /* 67 | a huge lookup table that we use to look up our recordkeeping object for a given function call 68 | 69 | 70 | 71 | */ 72 | static void* g_retaddr2context_table = nullptr; 73 | 74 | 75 | static size_t g_execmem_current_size = 0; 76 | static char* g_execmem_region = nullptr; 77 | 78 | static void allocate_execmem_takelist() { 79 | 80 | g_execmem_current_size = EXECMEM_NEEDED; 81 | g_execmem_region =(char*) VirtualAlloc(nullptr, EXECMEM_NEEDED, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE); 82 | 83 | __stosb((unsigned char*)g_execmem_region, 0, g_execmem_current_size); 84 | } 85 | 86 | 87 | static void allocate_retaddr2context_table() { 88 | 89 | size_t total_bytes_for_table = static_cast(g_blamdll.image_size >> 4) * sizeof(void*); 90 | 91 | 92 | void* table = VirtualAlloc(nullptr, total_bytes_for_table, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE); 93 | //prefault the pages so we arent getting pagefaults while playing 94 | __stosb((unsigned char*)table, 0, total_bytes_for_table); 95 | g_retaddr2context_table = table; 96 | 97 | 98 | } 99 | 100 | 101 | static void callinstrument_logic(uintptr_t retaddr) { 102 | auto key = get_returnaddr_key(retaddr); 103 | auto ringbufferpos_for = &reinterpret_cast(g_retaddr2context_table)[key]; 104 | 105 | ringbuffer_list_ele_t* ringbuff = *ringbufferpos_for; 106 | 107 | if(!ringbuff) { 108 | size_t newringbuffpos = _interlockedincrement64((volatile long long*) &g_current_free_ringbuff); 109 | if(newringbuffpos >= NUM_RESERVED_RINGBUFFS) { 110 | return; 111 | } 112 | ringbuff = &g_ringbuffers[newringbuffpos]; 113 | 114 | _mm_stream_si64(reinterpret_cast(ringbufferpos_for), (long long)ringbuff); 115 | } 116 | 117 | 118 | uintptr_t decode_buffer_pos = (uintptr_t)ringbuff; 119 | 120 | 121 | uintptr_t rgbuff_base = decode_buffer_pos >> 48; 122 | 123 | 124 | 125 | 126 | size_t currtime = _interlockedincrement64((volatile long long*)&g_current_calltime); 127 | 128 | 129 | /* 130 | build 4 ymm values from regs, stream out 131 | */ 132 | 133 | } 134 | static void* emit_function(Xbyak::CodeGenerator& cgen) { 135 | 136 | if(g_execmem_current_size < cgen.getSize()) { 137 | MessageBoxA(0, "Out of exec mem!", "Exec mem exhausted",0); 138 | exit(1); 139 | } 140 | 141 | char* emitdest = g_execmem_region; 142 | g_execmem_region += cgen.getSize(); 143 | 144 | __movsb((unsigned char*)emitdest, cgen.getCode(), cgen.getSize()); 145 | return emitdest; 146 | } 147 | 148 | 149 | 150 | /* 151 | we can get information on the values in registers at the end of a function by hooking security_check_cookie 152 | 153 | */ 154 | 155 | 156 | void mh_install_security_cookie_regval_hook() { 157 | 158 | } 159 | 160 | 161 | 162 | #endif -------------------------------------------------------------------------------- /m34thook/mh_dev_hooks.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | void mh_install_security_cookie_regval_hook(); -------------------------------------------------------------------------------- /m34thook/mh_editor_mode.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | class mh_editor_interface_t { 5 | public: 6 | virtual void grab(void* entity) = 0; 7 | 8 | //grabs the entity the player is looking at 9 | virtual void grab_player_focus() = 0; 10 | virtual void ungrab() = 0; 11 | 12 | virtual void editor_spawn_entitydef(void* entitydef) = 0; 13 | 14 | virtual void init_for_session() = 0; 15 | 16 | virtual bool is_initialized_for_sess() = 0; 17 | virtual void set_angle_increment(double inc) = 0; 18 | }; 19 | 20 | mh_editor_interface_t* get_current_editor(); -------------------------------------------------------------------------------- /m34thook/mh_guirender.cpp: -------------------------------------------------------------------------------- 1 | #include "mh_defs.hpp" 2 | 3 | #include "game_exe_interface.hpp" 4 | #include "doomoffs.hpp" 5 | #include "meathook.h" 6 | #include "cmdsystem.hpp" 7 | #include "idtypeinfo.hpp" 8 | #include "eventdef.hpp" 9 | #include "scanner_core.hpp" 10 | #include "idLib.hpp" 11 | #include "idStr.hpp" 12 | #include "idmath.hpp" 13 | #include 14 | #include 15 | #include 16 | #include "gameapi.hpp" 17 | #include "snaphakalgo.hpp" 18 | 19 | #include "mh_guirender.hpp" 20 | 21 | #include "mhgui.hpp" 22 | #include 23 | static idCVar* com_debugHUD = nullptr; 24 | 25 | static void* g_original_rendergui = nullptr; 26 | static std::string g_testmaterial = ""; 27 | 28 | static std::mutex g_doms_mutex{}; 29 | 30 | struct domentry_t { 31 | rb_node m_node; 32 | const char* m_name; 33 | mh_dom_t* m_dom; 34 | 35 | domentry_t() { 36 | rb_init_node(&m_node); 37 | m_name=nullptr; 38 | m_dom=nullptr; 39 | } 40 | 41 | }; 42 | 43 | static rb_root g_doms_search_tree{}; 44 | 45 | 46 | static void mh_render_doms(idRenderModelGui* guimodel) { 47 | 48 | g_doms_mutex.lock(); 49 | 50 | for(auto&& domnode : sh::rb::rb_iterate(g_doms_search_tree)) { 51 | domnode->m_dom->snapgui_render(guimodel); 52 | } 53 | 54 | g_doms_mutex.unlock(); 55 | } 56 | 57 | 58 | static void mh_rendergui_callback(idDebugHUD* dbghud, idRenderModelGui* rgui) { 59 | //always show debughud 60 | //com_debugHUD->data->valueInteger=1; 61 | /*if (!com_debugHUD) { 62 | com_debugHUD = // idCVar::Find("com_debugHUD"); 63 | }*/ 64 | 65 | if (!cvar_data(cvr_com_debugHUD)) { 66 | return; //we're on v1, and running before the rvas have been populated 67 | 68 | } 69 | cvar_data(cvr_com_debugHUD)->valueInteger = 1; 70 | 71 | 72 | //com_debugHUD->data->valueInteger = 1; 73 | 74 | call_as(g_original_rendergui, dbghud, rgui); 75 | 76 | mh_render_doms(rgui); 77 | //also has memory corruption :( 78 | // 79 | //rgui->DrawFilled(colorBlue, 100, 100, 200, 200); 80 | if(g_testmaterial.length()) { 81 | 82 | void* mtr = get_material(g_testmaterial.c_str()); 83 | 84 | if(mtr) { 85 | rgui->DrawRectMaterial(0, 0, 400, 400, mtr); 86 | } 87 | 88 | 89 | } 90 | 91 | /*rgui->DrawFilled(colorBrown, 0, 0, 200, 200); 92 | rgui->DrawString(500, 500, "yo yo yo, we got some text baybee", &colorCyan, true, 3);*/ 93 | } 94 | 95 | static void cmd_set_testmaterial(idCmdArgs* args) { 96 | if(args->argc < 2){ 97 | g_testmaterial.clear(); 98 | } 99 | else { 100 | g_testmaterial = args->argv[1]; 101 | } 102 | } 103 | 104 | static void mh_testgui(idCmdArgs* args) { 105 | 106 | mh_gui::show_test_gui(); 107 | } 108 | 109 | #define idDebugHUDLocal_Render_VtblIdx 1 110 | void mh_gui::install_gui_hooks() { 111 | 112 | 113 | void** debughudvtbl = get_class_vtbl(".?AVidDebugHUDLocal@@"); 114 | 115 | 116 | g_original_rendergui = (void*)mh_rendergui_callback; 117 | swap_out_ptrs(&debughudvtbl[idDebugHUDLocal_Render_VtblIdx], &g_original_rendergui, 1, false); 118 | 119 | init_sh_ingame_ui(); 120 | idCmd::register_command("mh_testgui", mh_testgui, "test"); 121 | 122 | idCmd::register_command("mh_testmaterial", cmd_set_testmaterial, "Takes one arg, a material name. Renders the material to the test window. Passing no args clears the test window"); 123 | } 124 | 125 | 126 | 127 | mh_dom_t* mh_gui::new_named_dom(const char* name) { 128 | 129 | g_doms_mutex.lock(); 130 | sh::rb::insert_hint_t hint{}; 131 | domentry_t* domfor = sh::rb::rbnode_find(&g_doms_search_tree, name, [](domentry_t* entry, const char* name) { 132 | return sh::string::strcmp(entry->m_name, name); 133 | }, &hint); 134 | 135 | if(domfor) { 136 | idLib::Printf("Attempted to create dom named %s, but it already exists! returning existing dom.\n"); 137 | 138 | } 139 | else { 140 | domfor = new domentry_t(); 141 | domfor->m_name = _strdup(name); 142 | domfor->m_dom = new_dom(); 143 | hint.insert(&domfor->m_node, &g_doms_search_tree); 144 | } 145 | 146 | mh_dom_t* result = domfor->m_dom; 147 | 148 | g_doms_mutex.unlock(); 149 | 150 | return result; 151 | 152 | } 153 | 154 | void mh_gui::show_test_gui() { 155 | 156 | mh_dom_t* mydom = new_named_dom("testgui1"); 157 | 158 | auto testele = mydom->alloc_e2d("testele", 0.25, 0.25, 0.5, 0.5); 159 | testele->m_text_positioning_style = _text_style_centered; 160 | testele->init_rect("swf/hud/menus/re_spec_station_textures/swf_images/common/frame/frame_backplate_", colorWhite); 161 | testele->init_text("Heres some text for our testgui", 1.0, colorCyan); 162 | } -------------------------------------------------------------------------------- /m34thook/mh_guirender.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class mh_dom_t; 4 | 5 | namespace mh_gui { 6 | void install_gui_hooks(); 7 | 8 | void show_test_gui(); 9 | 10 | mh_dom_t* new_named_dom(const char* name); 11 | 12 | } -------------------------------------------------------------------------------- /m34thook/mh_headergen.cpp: -------------------------------------------------------------------------------- 1 | #include "mh_headergen.hpp" 2 | #include 3 | #pragma comment(lib, "cabinet.lib") 4 | #include "compressapi.h" 5 | #define PROPERTY_KEY_TABLE_COMPRESSION_ALGO COMPRESS_ALGORITHM_LZMS 6 | 7 | bvec_t pack_strset(strviewset_t& sset) { 8 | unsigned total_required_bytes = 0; 9 | for (auto&& chrs : sset) { 10 | 11 | total_required_bytes += chrs.length() + 1; 12 | 13 | 14 | } 15 | 16 | bvec_t bbuff{}; 17 | bbuff.resize(total_required_bytes); 18 | 19 | unsigned writepos = 0; 20 | for (auto&& chrs : sset) { 21 | 22 | memcpy(&bbuff[writepos], chrs.data(), chrs.length() + 1); 23 | writepos += chrs.length() + 1; 24 | 25 | } 26 | 27 | return bbuff; 28 | } 29 | bvec_t compress_packet_strset(bvec_t& pss) { 30 | COMPRESSOR_HANDLE comp; 31 | CreateCompressor(PROPERTY_KEY_TABLE_COMPRESSION_ALGO, nullptr, &comp); 32 | 33 | 34 | bvec_t compout{}; 35 | compout.resize(pss.size() * 2); 36 | SIZE_T decompres; 37 | Compress(comp, (LPCVOID)pss.data(), pss.size(), compout.data(), compout.size(), &decompres); 38 | 39 | CloseCompressor(comp); 40 | 41 | compout.resize(decompres); 42 | return compout; 43 | } 44 | 45 | 46 | void write_cfile(std::string txt, const char* name) { 47 | 48 | FILE* outf; 49 | fopen_s(&outf, name, "wb"); 50 | 51 | 52 | 53 | /*for (auto&& name : allprops) { 54 | 55 | fprintf(outf, "%s\n", name.data()); 56 | } 57 | */ 58 | 59 | fwrite(txt.data(), txt.length(), 1, outf); 60 | fclose(outf); 61 | 62 | } 63 | 64 | std::string expand_bytes_to_c_bytearray(bvec_t bvals) { 65 | 66 | std::string result = std::to_string(bvals[0]); 67 | 68 | for (unsigned i = 1; i < bvals.size(); ++i) { 69 | 70 | result += ","; 71 | result += std::to_string(bvals[i]); 72 | } 73 | return result; 74 | } 75 | 76 | bvec_t decompress_strset(unsigned char* values, unsigned numvalues, unsigned expected_decompress) { 77 | 78 | DECOMPRESSOR_HANDLE decomp; 79 | CreateDecompressor(PROPERTY_KEY_TABLE_COMPRESSION_ALGO, nullptr, &decomp); 80 | 81 | bvec_t decompdata; 82 | decompdata.resize(expected_decompress); 83 | 84 | SIZE_T decompressed_size; 85 | Decompress(decomp, values, numvalues, decompdata.data(), expected_decompress, &decompressed_size); 86 | 87 | 88 | CloseDecompressor(decomp); 89 | return decompdata; 90 | } 91 | 92 | strviewset_t unpack_strset(bvec_t& bvals, unsigned numstrs) { 93 | 94 | strviewset_t decompressed_set; 95 | 96 | const char* consumepos = (const char*)(bvals.data()); 97 | for (unsigned i = 0; i < numstrs; ++i) { 98 | 99 | std::string_view current = consumepos; 100 | 101 | consumepos += current.length() + 1; 102 | decompressed_set.emplace_hint(decompressed_set.end(), std::move(current)); 103 | 104 | 105 | } 106 | return decompressed_set; 107 | } -------------------------------------------------------------------------------- /m34thook/mh_headergen.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | using strviewset_t = std::set; 9 | using bvec_t = std::vector; 10 | 11 | bvec_t pack_strset(strviewset_t& sset); 12 | bvec_t compress_packet_strset(bvec_t& pss); 13 | void write_cfile(std::string txt, const char* name); 14 | std::string expand_bytes_to_c_bytearray(bvec_t bvals); 15 | 16 | 17 | bvec_t decompress_strset(unsigned char* values, unsigned numvalues, unsigned expected_decompress); 18 | 19 | strviewset_t unpack_strset(bvec_t& bvals, unsigned numstrs); -------------------------------------------------------------------------------- /m34thook/mh_mainloop.cpp: -------------------------------------------------------------------------------- 1 | #include "mh_defs.hpp" 2 | 3 | #include "game_exe_interface.hpp" 4 | #include "doomoffs.hpp" 5 | #include "meathook.h" 6 | #include "cmdsystem.hpp" 7 | #include "idtypeinfo.hpp" 8 | #include "eventdef.hpp" 9 | #include "scanner_core.hpp" 10 | #include "idLib.hpp" 11 | #include "idStr.hpp" 12 | #include "idmath.hpp" 13 | #include 14 | #include 15 | #include 16 | #include "gameapi.hpp" 17 | #include "snaphakalgo.hpp" 18 | #include "mh_mainloop.hpp" 19 | #include "mh_guirender.hpp" 20 | 21 | 22 | 23 | 24 | struct alignas(64) frame_callbacks_t { 25 | mh_mainloop::frame_cb_t m_cbs[MAX_FRAME_CALLBACKS]; 26 | void* m_uds[MAX_FRAME_CALLBACKS]; 27 | size_t m_numcallbacks; 28 | 29 | 30 | void init() { 31 | //sh::memops::nt_zero_mem(this, sizeof(*this)); 32 | m_numcallbacks=0; 33 | // sh::memops::sfence_if(); 34 | } 35 | 36 | /* 37 | in theory a race condition could happen where another thread is registering a callback just as 38 | the main thread is executing all callbacks 39 | 40 | but its like a less than 1 in a trillion chance lol, which i think is acceptable 41 | */ 42 | unsigned add_callback(mh_mainloop::frame_cb_t cb, void* ud) { 43 | 44 | //doofus, it returns the incremented value so thats why it was segfaulting 45 | long long numcb = _InterlockedIncrement64((volatile long long*)&m_numcallbacks) - 1; 46 | MH_UNLIKELY_IF(numcb >= MAX_FRAME_CALLBACKS) { 47 | sh::fatal("M347h00k exceeded MAX_FRAME_CALLBACKS!"); 48 | 49 | } 50 | store8_no_cache(&m_cbs[numcb], cb); 51 | store8_no_cache(&m_uds[numcb], ud); 52 | 53 | 54 | return (unsigned)numcb; 55 | } 56 | 57 | 58 | void run_callbacks() { 59 | unsigned numcb = load8_no_cache((volatile long long*)&m_numcallbacks); 60 | 61 | for(unsigned i = 0; i < numcb; ++i) { 62 | mh_mainloop::frame_cb_t cb = load8_no_cache(&m_cbs[i]); 63 | void* ud = load8_no_cache(&m_uds[i]); 64 | 65 | cb(ud); 66 | } 67 | } 68 | 69 | 70 | }; 71 | 72 | 73 | 74 | static frame_callbacks_t g_preframe{}; 75 | static frame_callbacks_t g_postframe{}; 76 | 77 | static bool g_isfirstframe = true; 78 | 79 | 80 | MH_NOINLINE 81 | MH_REGFREE_CALL 82 | CS_COLD_CODE 83 | static void run_firstframe_code() { 84 | g_isfirstframe = false; 85 | //run the late stage scanners, load all plugins 86 | meathook_final_init(); 87 | mh_gui::install_gui_hooks(); 88 | } 89 | 90 | static uint64_t g_num_ticks = 0; 91 | 92 | static __int64 meathook_game_frame(__int64 framearg) { 93 | MH_UNLIKELY_IF (g_isfirstframe) { 94 | run_firstframe_code(); 95 | 96 | } 97 | g_preframe.run_callbacks(); 98 | __int64 result = call_as<__int64>(descan::g_idCommonLocal_Frame, framearg); 99 | g_postframe.run_callbacks(); 100 | g_num_ticks++; 101 | return result; 102 | } 103 | uint64_t mh_mainloop::num_ticks() { 104 | return g_num_ticks; 105 | } 106 | 107 | void mh_mainloop::install_mainloop_hooks() { 108 | *reinterpret_cast(descan::g_idCommonLocal_Frame_CallbackPtr) = (void*)meathook_game_frame; 109 | g_preframe.init(); 110 | g_postframe.init(); 111 | } 112 | 113 | void mh_mainloop::add_preframe_callback(frame_cb_t cb, void* ud) { 114 | g_preframe.add_callback(cb, ud); 115 | } 116 | void mh_mainloop::add_postframe_callback(frame_cb_t cb, void* ud) { 117 | g_postframe.add_callback(cb, ud); 118 | } -------------------------------------------------------------------------------- /m34thook/mh_mainloop.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define MAX_FRAME_CALLBACKS 64 4 | 5 | namespace mh_mainloop { 6 | using frame_cb_t = void (*)(void*); 7 | 8 | void install_mainloop_hooks(); 9 | void add_preframe_callback(frame_cb_t cb, void* ud = nullptr); 10 | void add_postframe_callback(frame_cb_t cb, void* ud = nullptr); 11 | 12 | uint64_t num_ticks(); 13 | } -------------------------------------------------------------------------------- /m34thook/mh_memmanip_cmds.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | void install_memmanip_cmds(); -------------------------------------------------------------------------------- /m34thook/mh_native_api.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define MH_OPAQUE(name) typedef struct{}*name 4 | 5 | MH_OPAQUE(mh_classtype_t); 6 | 7 | MH_OPAQUE(mh_classvar_t); 8 | 9 | MH_OPAQUE(mh_enumtype_t); 10 | MH_OPAQUE(mh_enumval_t); 11 | 12 | /* 13 | an ingame entity at runtime 14 | */ 15 | MH_OPAQUE(mh_game_entity_t); 16 | 17 | typedef void (*mh_mainloop_cb_t)(void*); 18 | /* 19 | struct with pointers instead of virtual to ensure mingw compat 20 | */ 21 | struct mh_interface_t { 22 | /* 23 | warning: command text may not exceed 2048 bytes or the game will crash (see idCmdArgs) 24 | */ 25 | 26 | void (*m_execute_cmd_text)(const char* txt); 27 | 28 | void (*m_console_printf)(const char* format, ...); 29 | 30 | const char* (*m_get_clipboard_data)(); 31 | void (*m_set_clipboard_data)(const char* data); 32 | 33 | //memory allocation functions that are assured to be compatible with this api 34 | void* (*m_mh_malloc)(size_t size); 35 | 36 | void (*m_mh_free)(void* vp); 37 | void* (*m_mh_realloc)(void* vp, size_t newsize); 38 | mh_classtype_t (*m_find_classtype)(const char* name); 39 | mh_enumtype_t (*m_find_enumtype)(const char* name); 40 | 41 | bool (*m_enumval_iterator_is_done)(mh_enumval_t val); 42 | bool (*m_classvar_iterator_is_done)(mh_classvar_t var); 43 | 44 | const char* (*m_enumval_get_name)(mh_enumval_t val); 45 | long long (*m_enumval_get_value)(mh_enumval_t val); 46 | 47 | mh_enumval_t (*m_enumval_next)(mh_enumval_t val); 48 | 49 | mh_classvar_t (*m_classvar_next)(mh_classvar_t var); 50 | 51 | const char* (*m_classvar_type)(mh_classvar_t var); 52 | const char* (*m_classvar_name)(mh_classvar_t var); 53 | const char* (*m_classvar_ops)(mh_classvar_t var); 54 | const char* (*m_classvar_comment)(mh_classvar_t var); 55 | 56 | size_t (*m_classvar_size)(mh_classvar_t var); 57 | size_t (*m_classvar_offset)(mh_classvar_t var); 58 | 59 | mh_game_entity_t (*m_find_entity_by_name)(const char* entity_name); 60 | 61 | unsigned m_sizeof_generalized_number; 62 | unsigned m_pad; 63 | 64 | mh_game_entity_t (*m_find_next_entity_with_class)(const char* classname, mh_game_entity_t after); 65 | 66 | const char* (*m_get_entity_name)(mh_game_entity_t ent); 67 | void (*m_add_persistent_text)(unsigned x, unsigned y, unsigned RGBA, float scale, const char* fmt, ...); 68 | 69 | void (*m_remove_persistent_text)(unsigned x, unsigned y); 70 | mh_game_entity_t (*m_get_player1)(); 71 | mh_game_entity_t (*m_get_player_looktarget)(); 72 | 73 | void (*m_register_premainloop_cb)(mh_mainloop_cb_t cb, void* ud); 74 | void (*m_register_postmainloop_cb)(mh_mainloop_cb_t cb, void* ud); 75 | }; -------------------------------------------------------------------------------- /m34thook/mh_staticmodel.cpp: -------------------------------------------------------------------------------- 1 | #include "mh_defs.hpp" 2 | 3 | #include "game_exe_interface.hpp" 4 | #include "doomoffs.hpp" 5 | #include "meathook.h" 6 | #include "cmdsystem.hpp" 7 | #include "idtypeinfo.hpp" 8 | #include "eventdef.hpp" 9 | #include "scanner_core.hpp" 10 | #include "idLib.hpp" 11 | #include "idStr.hpp" 12 | #include "idmath.hpp" 13 | #include 14 | #include 15 | #include 16 | #include "gameapi.hpp" 17 | #include "snaphakalgo.hpp" 18 | #include "memorySystem.hpp" 19 | #include "mh_staticmodel.hpp" 20 | 21 | mh_typesizecached_t g_idStaticModelSize{}; 22 | 23 | 24 | static mh_new_fieldcached_t g_model_surfs; 25 | /* 26 | struct idStaticModelSurface 27 | { 28 | idMaterial2 *material; 29 | idArray geometry; 30 | int materialNum; 31 | char geometryIsReference; 32 | char field_35[3]; 33 | }; 34 | 35 | */ 36 | static mh_new_fieldcached_t g_model_material; 37 | static mh_new_fieldcached_t g_model_geometryIsReference; 38 | static mh_new_fieldcached_t g_model_materialNum; 39 | 40 | static mh_new_fieldcached_t g_model_geometry; 41 | 42 | 43 | mh_typesizecached_t g_idStaticModelSurfaceSize{}; 44 | 45 | idStaticModelPtr idStaticModelPtr::CreateNew() { 46 | 47 | void* instance = idNew(g_idStaticModelSize()); 48 | 49 | call_as(descan::g_idStaticModel_ctor, instance); 50 | 51 | idStaticModelPtr result; 52 | result.m_ptr = instance; 53 | return result; 54 | 55 | 56 | } 57 | 58 | void idStaticModelPtr::Write(const char* output_path, bool skip_compression) { 59 | call_as(descan::g_idStaticModel_WriteStaticBModel, m_ptr, output_path, 0, skip_compression); 60 | } 61 | 62 | 63 | void idStaticModelPtr::Setup_Singlesurface_hack(unsigned num_verts, unsigned num_tris, idDrawVert** out_verts, unsigned short** out_tris) { 64 | 65 | 66 | auto old_freetrival = cvar_data(cvr_r_freeTriangleCPUData)->valueInteger; 67 | 68 | 69 | cvar_data(cvr_r_freeTriangleCPUData)->valueInteger = 0; 70 | 71 | //try not doing this hack and see if we avoid segfault 72 | #if 0 73 | call_as(descan::g_idStaticModel_MakeTexturedCube, m_ptr, 10.0f, 10.0f); 74 | #else 75 | 76 | void* tri = idNew(descan::g_idTriangles_sizeof); 77 | idListVoid* surfptr = g_model_surfs(m_ptr); 78 | call_as(descan::g_idTriangles_ctor, tri); 79 | surfptr->list = (unsigned long long*) idNew(g_idStaticModelSurfaceSize() * 32); 80 | memset(surfptr->list, 0, g_idStaticModelSurfaceSize() * 32); 81 | 82 | surfptr->size = 32; 83 | surfptr->num = 1; 84 | void* current_surf = surfptr->list; 85 | 86 | 87 | *g_model_material(current_surf) = locate_resourcelist_member("idMaterial2", "_blue"); 88 | 89 | *g_model_geometry(current_surf) = tri; 90 | *g_model_geometryIsReference(current_surf) = 0; 91 | //idk? 92 | *g_model_materialNum(current_surf) = 0; 93 | #endif 94 | cvar_data(cvr_r_freeTriangleCPUData)->valueInteger = old_freetrival; 95 | 96 | idListVoid* surfptr2 = g_model_surfs(m_ptr); 97 | 98 | 99 | //classTypeInfo_t* modelsurf_type = idType::FindClassInfo("idStaticModelSurface"); 100 | 101 | 102 | //get first element of geometry array in first element of our surface array 103 | void* current_idtriangles = *g_model_geometry(surfptr2->list); 104 | 105 | 106 | *out_verts = call_as(descan::g_idTriangles_AllocStaticTriSurfVerts, current_idtriangles, num_verts); 107 | *out_tris = call_as(descan::g_idTriangles_AllocStaticTriSurfIndexes, current_idtriangles, num_tris); 108 | /* 109 | .text:0000000140878CC6 83 83 F8 00 00 00 04 add dword ptr [rbx+248], 4 110 | .text:0000000140878CCD ; 87: a1->numIndexes += 6; 111 | .text:0000000140878CCD 83 83 F4 00 00 00 06 add dword ptr [rbx+244], 6 112 | */ 113 | *mh_lea(current_idtriangles, 0xF8) = num_verts; 114 | *mh_lea(current_idtriangles, 0xF4) = num_tris; 115 | } 116 | 117 | void idStaticModelPtr::Finalize_geo() { 118 | 119 | call_as(descan::g_idRenderModelStatic_FinishStaticModel, m_ptr, 1u, 1, 1); 120 | call_as((void*)0x140645400, m_ptr, 0, 0); 121 | } 122 | 123 | void idStaticModelPtr::Destroy() { 124 | //lol we probably leak memory here since we're not actually calling the staticmodel dctor 125 | call_as(descan::g_idStaticModel_FreeSurfaces, m_ptr); 126 | idDelete(m_ptr); 127 | } 128 | 129 | void idStaticModelPtr::make_standard_tris() { 130 | idListVoid* surfptr2 = g_model_surfs(m_ptr); 131 | void* current_idtriangles = *g_model_geometry(surfptr2->list); 132 | 133 | *g_model_geometry(surfptr2->list) = call_as((void*)0x14087C000, current_idtriangles); 134 | //boundsfromvertscan 135 | call_as((void*)0x0140586DA0, current_idtriangles); 136 | } -------------------------------------------------------------------------------- /m34thook/mh_staticmodel.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | MH_TRIVIAL_ABI 4 | struct idStaticModelPtr { 5 | void* m_ptr; 6 | 7 | static idStaticModelPtr CreateNew(); 8 | 9 | 10 | void Destroy(); 11 | 12 | void Write(const char* output_path, bool skip_compression = true); 13 | 14 | 15 | 16 | void Setup_Singlesurface_hack(unsigned num_verts, unsigned num_indexes, idDrawVert** out_verts, unsigned short** out_indexes); 17 | 18 | void make_standard_tris(); 19 | void Finalize_geo(); 20 | 21 | }; -------------------------------------------------------------------------------- /m34thook/mhgui.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* 4 | good gui-looking materials we can use: 5 | loading/loading_info_textures/swf_images/loading_screen/loading_tip_box_ 6 | swf/hud/menus/dossier/dossier_arsenal_textures/swf_images/dossier/arsenal/weaponnav_bg_ 7 | 8 | 9 | really good: 10 | swf/hud/menus/dossier/dossier_arsenal_textures/swf_images/end_of_level/bg_window_large_ 11 | swf/hud/menus/dossier/dossier_map_textures/swf_images/hud/demonic_corruption/hud_slayer_demoncorruption_container_single_ 12 | swf/main_menu/screens/seasons_textures/swf_images/seasons/profile_nameplate_rect_bg_ 13 | swf/main_menu/screens/seasons_textures/swf_images/seasons/profile_icon_circle_bg_ 14 | swf/hud/menus/re_spec_station_textures/swf_images/common/frame/frame_backplate_ 15 | good icons: 16 | swf/hud/menus/dossier/dossier_arsenal_textures/swf_images/icons/icon_list_item_notification_ 17 | 18 | scrollbar-y: 19 | swf/hud/menus/dossier/dossier_codex_textures/swf_images/common/scrollbar/hud_scrollbar_track_center_ 20 | */ 21 | 22 | void calculate_text_size(const char* msg, float* out_w, float* out_h, float scale, unsigned* out_longest_line, unsigned* out_nlines); 23 | 24 | struct gui_draw_context_t { 25 | struct idRenderModelGui* m_guimod; 26 | float m_virtwidth; 27 | float m_virtheight; 28 | 29 | }; 30 | 31 | class mh_dom_t; 32 | 33 | enum text_positioning_style_t { 34 | _text_style_centered = 0, 35 | _text_style_origin = 1, 36 | }; 37 | 38 | struct mh_ui_ele_t { 39 | rb_node m_tree_id_iter; 40 | mh_dom_t* m_owning_dom; 41 | 42 | const char* id; 43 | float x, y; 44 | float width, height; 45 | 46 | struct { 47 | unsigned m_hidden : 1; 48 | unsigned m_text_positioning_style : 4; 49 | 50 | }; 51 | unsigned scrollYPos; 52 | 53 | unsigned mat_color; 54 | void* material; 55 | unsigned txt_color; 56 | const char* txt; 57 | float txt_scale; 58 | 59 | void set_text_positioning_style(text_positioning_style_t styl) { 60 | m_text_positioning_style = styl; 61 | } 62 | 63 | text_positioning_style_t get_text_positioning_style() { 64 | return (text_positioning_style_t)m_text_positioning_style; 65 | } 66 | 67 | gui_draw_context_t* m_current_ctx; 68 | void draw(gui_draw_context_t& rmg); 69 | void set_text(const char* newtxt); 70 | 71 | void init_text(const char* message, float scale, idColor color); 72 | void init_rect(const char* material, idColor color); 73 | void init_common(const char* id, float _x, float _y, float w, float h); 74 | 75 | static void* operator new(size_t sz); 76 | 77 | static void operator delete(void* vp); 78 | mh_ui_ele_t(); 79 | ~mh_ui_ele_t(); 80 | 81 | void scroll_text_up(); 82 | void scroll_text_down(); 83 | 84 | float calcw() const { 85 | return width*m_current_ctx->m_virtwidth; 86 | } 87 | float calch() const { 88 | return height * m_current_ctx->m_virtheight; 89 | } 90 | 91 | float calcx() const { 92 | return x* m_current_ctx->m_virtwidth; 93 | } 94 | float calcy() const { 95 | return y * m_current_ctx->m_virtheight; 96 | } 97 | 98 | float centerx() const { 99 | return (x + (width / 2.0f)) * m_current_ctx->m_virtwidth; 100 | } 101 | float centery() const { 102 | return (y + (height / 2.0f)) * m_current_ctx->m_virtheight; 103 | } 104 | void hide() { 105 | m_hidden = true; 106 | } 107 | 108 | void unhide() { 109 | m_hidden =false; 110 | } 111 | }; 112 | 113 | 114 | 115 | class mh_dom_t { 116 | public: 117 | virtual ~mh_dom_t() { 118 | } 119 | virtual mh_ui_ele_t* alloc_e2d(const char* id, float x, float y, float w, float h) = 0; 120 | 121 | virtual mh_ui_ele_t* find_ele_by_id(const char* id) = 0; 122 | virtual void snapgui_render(struct idRenderModelGui* guimod) = 0; 123 | 124 | 125 | }; 126 | void init_sh_ingame_ui(); 127 | mh_dom_t* new_dom(); 128 | 129 | 130 | -------------------------------------------------------------------------------- /m34thook/mhutil/mh_filesystem.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | enum class filemode_e 4 | { 5 | READ = 0, 6 | WRITE = 1, 7 | APPEND = 2 8 | } ; 9 | using cs_fd_t = void*; 10 | 11 | enum class seekmode_e { 12 | begin = 0, 13 | current = 1, 14 | end = 2 15 | }; 16 | 17 | #define MH_FILESYS_PATHBUFFER_LENGTH 512 18 | 19 | static constexpr unsigned WIN32_INTERNAL_SIZEOF_UNICODE_STRING = 16; 20 | 21 | //RtlDosPathNameToRelativeNtPathName_U 22 | //temporary objects/buffers used by win32 path conversion 23 | struct win32_path_conversion_context_extern_t { 24 | char m_unicode_str_storage[WIN32_INTERNAL_SIZEOF_UNICODE_STRING]; 25 | wchar_t m_unicode_path_result[MH_FILESYS_PATHBUFFER_LENGTH]; 26 | }; 27 | 28 | namespace filesys { 29 | cs_fd_t open_file(const char* name, filemode_e mode); 30 | void close_file(cs_fd_t fd); 31 | std::int64_t file_length(cs_fd_t fd); 32 | 33 | std::int64_t read_file(cs_fd_t fd, void* buffer, size_t ntoread); 34 | std::int64_t write_file(cs_fd_t fd, const void* buffer, size_t size); 35 | 36 | 37 | 38 | /* 39 | using this is faster than the end-relative or current relative seek operations 40 | with SetFilePointer, because those require an extra syscall (queryinformation) to 41 | get the length or current pointer 42 | */ 43 | void seek_file(cs_fd_t fd, std::int64_t position ); 44 | 45 | /* 46 | very fast file existence check. calls NtQueryAttributesFile, so does not 47 | require creating a handle to check 48 | */ 49 | bool file_exists(const char* filename); 50 | 51 | bool get_ntpath_for(const char* path, win32_path_conversion_context_extern_t* conversion_temp, wchar_t* output); 52 | } -------------------------------------------------------------------------------- /m34thook/objfiles/objloader.h: -------------------------------------------------------------------------------- 1 | #ifndef OBJLOADER_H 2 | #define OBJLOADER_H 3 | 4 | #include 5 | 6 | namespace sp // simple and to the point 7 | { 8 | 9 | struct Vec3 10 | { 11 | float x; 12 | float y; 13 | float z; 14 | Vec3(): x(0), y(0), z(0) {} 15 | Vec3(float _x, float _y, float _z): x(_x), y(_y), z(_z) {} 16 | float& operator[](int idx); 17 | }; 18 | 19 | struct TexCoord 20 | { 21 | float u; 22 | float v; 23 | TexCoord(): u(0), v(0) {} 24 | TexCoord(float _u, float _v): u(_u), v(_v) {} 25 | float& operator[](int idx); 26 | }; 27 | 28 | struct Face 29 | { 30 | int a; 31 | int b; 32 | int c; 33 | }; 34 | 35 | class ObjLoader 36 | { 37 | public: 38 | ObjLoader(); 39 | 40 | void load(char* filename); 41 | 42 | int getIndexCount(); 43 | int getVertCount(); 44 | 45 | const unsigned int* getFaces(); 46 | const float* getPositions(); 47 | const float* getNormals(); 48 | 49 | int getTexCoordLayers(); 50 | const float* getTexCoords(int multiTexCoordLayer); 51 | 52 | private: 53 | 54 | std::vector Faces; 55 | std::vector Positions; 56 | std::vector Normals; 57 | 58 | // obj's only have 1 layer ever 59 | std::vector TexCoords; 60 | unsigned int TexCoordLayers; 61 | }; 62 | } 63 | #endif // OBJLOADER_H 64 | -------------------------------------------------------------------------------- /m34thook/optimizations/mhoptimize.cpp: -------------------------------------------------------------------------------- 1 | #include "xbyak/xbyak.h" 2 | #include "mh_defs.hpp" 3 | 4 | #include "game_exe_interface.hpp" 5 | #include "meathook.h" 6 | #include "cmdsystem.hpp" 7 | #include "idtypeinfo.hpp" 8 | #include "scanner_core.hpp" 9 | #include "idLib.hpp" 10 | #include "idStr.hpp" 11 | #include "gameapi.hpp" 12 | #include "memscan.hpp" 13 | #include "snaphakalgo.hpp" 14 | 15 | 16 | //extern declared in meathook.cpp 17 | void cmd_optimize(idCmdArgs* args) { 18 | make_ret(descan::g_security_check_cookie); 19 | make_ret(descan::g_alloca_probe); 20 | 21 | /* 22 | sqrtss xmm0, xmm0 23 | ret 24 | */ 25 | char sqrtf_override[] = { (char)0xF3, 0x0F, 0x51, (char)0xC0, (char)0xC3 }; 26 | 27 | patch_memory_with_undo(descan::g_sqrtf, sizeof(sqrtf_override), sqrtf_override); 28 | 29 | char sqrt_override[] = { (char)0xF2, 0x0F, 0x51, (char)0xC0, (char)0xC3 }; 30 | 31 | patch_memory_with_undo(descan::g_sqrt, sizeof(sqrtf_override), sqrt_override); 32 | if(args->argc > 1) { 33 | make_ret(descan::g_idlib_vprintf); 34 | } 35 | 36 | #if 0 37 | redirect_to_func(g_shalgo.m_sroutines.m_strcmp, 0x1403B2A20ULL, true);//test idStr::cmp redirect 38 | redirect_to_func(g_shalgo.m_sroutines.m_strlen, 0x1403B5460ULL, true);//test strlen redirect 39 | #endif 40 | 41 | //redirect_to_func(g_shalgo.m_sroutines. descan::g__ZN5idStr4IcmpEPKcS1_) 42 | } 43 | -------------------------------------------------------------------------------- /m34thook/rapiddecl.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define RAPIDJSON_48BITPOINTER_OPTIMIZATION 1 4 | 5 | 6 | #include "rapiddecl/rapidjson.h" 7 | #include "rapiddecl/document.h" 8 | #include "rapiddecl/prettywriter.h" 9 | #include "rapiddecl/stringbuffer.h" 10 | 11 | using dmemb_iter_t = rapiddecl::Value::MemberIterator; 12 | -------------------------------------------------------------------------------- /m34thook/rapiddecl/cursorstreamwrapper.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_CURSORSTREAMWRAPPER_H_ 16 | #define RAPIDJSON_CURSORSTREAMWRAPPER_H_ 17 | 18 | #include "stream.h" 19 | 20 | #if defined(__GNUC__) 21 | RAPIDJSON_DIAG_PUSH 22 | RAPIDJSON_DIAG_OFF(effc++) 23 | #endif 24 | 25 | #if defined(_MSC_VER) && _MSC_VER <= 1800 26 | RAPIDJSON_DIAG_PUSH 27 | RAPIDJSON_DIAG_OFF(4702) // unreachable code 28 | RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated 29 | #endif 30 | 31 | RAPIDJSON_NAMESPACE_BEGIN 32 | 33 | 34 | //! Cursor stream wrapper for counting line and column number if error exists. 35 | /*! 36 | \tparam InputStream Any stream that implements Stream Concept 37 | */ 38 | template > 39 | class CursorStreamWrapper : public GenericStreamWrapper { 40 | public: 41 | typedef typename Encoding::Ch Ch; 42 | 43 | CursorStreamWrapper(InputStream& is): 44 | GenericStreamWrapper(is), line_(1), col_(0) {} 45 | 46 | // counting line and column number 47 | Ch Take() { 48 | Ch ch = this->is_.Take(); 49 | if(ch == '\n') { 50 | line_ ++; 51 | col_ = 0; 52 | } else { 53 | col_ ++; 54 | } 55 | return ch; 56 | } 57 | 58 | //! Get the error line number, if error exists. 59 | size_t GetLine() const { return line_; } 60 | //! Get the error column number, if error exists. 61 | size_t GetColumn() const { return col_; } 62 | 63 | private: 64 | size_t line_; //!< Current Line 65 | size_t col_; //!< Current Column 66 | }; 67 | 68 | #if defined(_MSC_VER) && _MSC_VER <= 1800 69 | RAPIDJSON_DIAG_POP 70 | #endif 71 | 72 | #if defined(__GNUC__) 73 | RAPIDJSON_DIAG_POP 74 | #endif 75 | 76 | RAPIDJSON_NAMESPACE_END 77 | 78 | #endif // RAPIDJSON_CURSORSTREAMWRAPPER_H_ 79 | -------------------------------------------------------------------------------- /m34thook/rapiddecl/error/en.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_ERROR_EN_H_ 16 | #define RAPIDJSON_ERROR_EN_H_ 17 | 18 | #include "error.h" 19 | 20 | #ifdef __clang__ 21 | RAPIDJSON_DIAG_PUSH 22 | RAPIDJSON_DIAG_OFF(switch-enum) 23 | RAPIDJSON_DIAG_OFF(covered-switch-default) 24 | #endif 25 | 26 | RAPIDJSON_NAMESPACE_BEGIN 27 | 28 | //! Maps error code of parsing into error message. 29 | /*! 30 | \ingroup RAPIDJSON_ERRORS 31 | \param parseErrorCode Error code obtained in parsing. 32 | \return the error message. 33 | \note User can make a copy of this function for localization. 34 | Using switch-case is safer for future modification of error codes. 35 | */ 36 | inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErrorCode) { 37 | switch (parseErrorCode) { 38 | case kParseErrorNone: return RAPIDJSON_ERROR_STRING("No error."); 39 | 40 | case kParseErrorDocumentEmpty: return RAPIDJSON_ERROR_STRING("The document is empty."); 41 | case kParseErrorDocumentRootNotSingular: return RAPIDJSON_ERROR_STRING("The document root must not be followed by other values."); 42 | 43 | case kParseErrorValueInvalid: return RAPIDJSON_ERROR_STRING("Invalid value."); 44 | 45 | case kParseErrorObjectMissName: return RAPIDJSON_ERROR_STRING("Missing a name for object member."); 46 | case kParseErrorObjectMissColon: return RAPIDJSON_ERROR_STRING("Missing a colon after a name of object member."); 47 | case kParseErrorObjectMissCommaOrCurlyBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or '}' after an object member."); 48 | 49 | case kParseErrorArrayMissCommaOrSquareBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or ']' after an array element."); 50 | 51 | case kParseErrorStringUnicodeEscapeInvalidHex: return RAPIDJSON_ERROR_STRING("Incorrect hex digit after \\u escape in string."); 52 | case kParseErrorStringUnicodeSurrogateInvalid: return RAPIDJSON_ERROR_STRING("The surrogate pair in string is invalid."); 53 | case kParseErrorStringEscapeInvalid: return RAPIDJSON_ERROR_STRING("Invalid escape character in string."); 54 | case kParseErrorStringMissQuotationMark: return RAPIDJSON_ERROR_STRING("Missing a closing quotation mark in string."); 55 | case kParseErrorStringInvalidEncoding: return RAPIDJSON_ERROR_STRING("Invalid encoding in string."); 56 | 57 | case kParseErrorNumberTooBig: return RAPIDJSON_ERROR_STRING("Number too big to be stored in double."); 58 | case kParseErrorNumberMissFraction: return RAPIDJSON_ERROR_STRING("Miss fraction part in number."); 59 | case kParseErrorNumberMissExponent: return RAPIDJSON_ERROR_STRING("Miss exponent in number."); 60 | 61 | case kParseErrorTermination: return RAPIDJSON_ERROR_STRING("Terminate parsing due to Handler error."); 62 | case kParseErrorUnspecificSyntaxError: return RAPIDJSON_ERROR_STRING("Unspecific syntax error."); 63 | 64 | default: return RAPIDJSON_ERROR_STRING("Unknown error."); 65 | } 66 | } 67 | 68 | RAPIDJSON_NAMESPACE_END 69 | 70 | #ifdef __clang__ 71 | RAPIDJSON_DIAG_POP 72 | #endif 73 | 74 | #endif // RAPIDJSON_ERROR_EN_H_ 75 | -------------------------------------------------------------------------------- /m34thook/rapiddecl/filereadstream.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_FILEREADSTREAM_H_ 16 | #define RAPIDJSON_FILEREADSTREAM_H_ 17 | 18 | #include "stream.h" 19 | #include 20 | 21 | #ifdef __clang__ 22 | RAPIDJSON_DIAG_PUSH 23 | RAPIDJSON_DIAG_OFF(padded) 24 | RAPIDJSON_DIAG_OFF(unreachable-code) 25 | RAPIDJSON_DIAG_OFF(missing-noreturn) 26 | #endif 27 | 28 | RAPIDJSON_NAMESPACE_BEGIN 29 | 30 | //! File byte stream for input using fread(). 31 | /*! 32 | \note implements Stream concept 33 | */ 34 | class FileReadStream { 35 | public: 36 | typedef char Ch; //!< Character type (byte). 37 | 38 | //! Constructor. 39 | /*! 40 | \param fp File pointer opened for read. 41 | \param buffer user-supplied buffer. 42 | \param bufferSize size of buffer in bytes. Must >=4 bytes. 43 | */ 44 | FileReadStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) { 45 | RAPIDJSON_ASSERT(fp_ != 0); 46 | RAPIDJSON_ASSERT(bufferSize >= 4); 47 | Read(); 48 | } 49 | 50 | Ch Peek() const { return *current_; } 51 | Ch Take() { Ch c = *current_; Read(); return c; } 52 | size_t Tell() const { return count_ + static_cast(current_ - buffer_); } 53 | 54 | // Not implemented 55 | void Put(Ch) { RAPIDJSON_ASSERT(false); } 56 | void Flush() { RAPIDJSON_ASSERT(false); } 57 | Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } 58 | size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } 59 | 60 | // For encoding detection only. 61 | const Ch* Peek4() const { 62 | return (current_ + 4 <= bufferLast_) ? current_ : 0; 63 | } 64 | 65 | private: 66 | void Read() { 67 | if (current_ < bufferLast_) 68 | ++current_; 69 | else if (!eof_) { 70 | count_ += readCount_; 71 | readCount_ = std::fread(buffer_, 1, bufferSize_, fp_); 72 | bufferLast_ = buffer_ + readCount_ - 1; 73 | current_ = buffer_; 74 | 75 | if (readCount_ < bufferSize_) { 76 | buffer_[readCount_] = '\0'; 77 | ++bufferLast_; 78 | eof_ = true; 79 | } 80 | } 81 | } 82 | 83 | std::FILE* fp_; 84 | Ch *buffer_; 85 | size_t bufferSize_; 86 | Ch *bufferLast_; 87 | Ch *current_; 88 | size_t readCount_; 89 | size_t count_; //!< Number of characters read 90 | bool eof_; 91 | }; 92 | 93 | RAPIDJSON_NAMESPACE_END 94 | 95 | #ifdef __clang__ 96 | RAPIDJSON_DIAG_POP 97 | #endif 98 | 99 | #endif // RAPIDJSON_FILESTREAM_H_ 100 | -------------------------------------------------------------------------------- /m34thook/rapiddecl/filewritestream.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_FILEWRITESTREAM_H_ 16 | #define RAPIDJSON_FILEWRITESTREAM_H_ 17 | 18 | #include "stream.h" 19 | #include 20 | 21 | #ifdef __clang__ 22 | RAPIDJSON_DIAG_PUSH 23 | RAPIDJSON_DIAG_OFF(unreachable-code) 24 | #endif 25 | 26 | RAPIDJSON_NAMESPACE_BEGIN 27 | 28 | //! Wrapper of C file stream for output using fwrite(). 29 | /*! 30 | \note implements Stream concept 31 | */ 32 | class FileWriteStream { 33 | public: 34 | typedef char Ch; //!< Character type. Only support char. 35 | 36 | FileWriteStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferEnd_(buffer + bufferSize), current_(buffer_) { 37 | RAPIDJSON_ASSERT(fp_ != 0); 38 | } 39 | 40 | void Put(char c) { 41 | if (current_ >= bufferEnd_) 42 | Flush(); 43 | 44 | *current_++ = c; 45 | } 46 | 47 | void PutN(char c, size_t n) { 48 | size_t avail = static_cast(bufferEnd_ - current_); 49 | while (n > avail) { 50 | std::memset(current_, c, avail); 51 | current_ += avail; 52 | Flush(); 53 | n -= avail; 54 | avail = static_cast(bufferEnd_ - current_); 55 | } 56 | 57 | if (n > 0) { 58 | std::memset(current_, c, n); 59 | current_ += n; 60 | } 61 | } 62 | 63 | void Flush() { 64 | if (current_ != buffer_) { 65 | size_t result = std::fwrite(buffer_, 1, static_cast(current_ - buffer_), fp_); 66 | if (result < static_cast(current_ - buffer_)) { 67 | // failure deliberately ignored at this time 68 | // added to avoid warn_unused_result build errors 69 | } 70 | current_ = buffer_; 71 | } 72 | } 73 | 74 | // Not implemented 75 | char Peek() const { RAPIDJSON_ASSERT(false); return 0; } 76 | char Take() { RAPIDJSON_ASSERT(false); return 0; } 77 | size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } 78 | char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } 79 | size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; } 80 | 81 | private: 82 | // Prohibit copy constructor & assignment operator. 83 | FileWriteStream(const FileWriteStream&); 84 | FileWriteStream& operator=(const FileWriteStream&); 85 | 86 | std::FILE* fp_; 87 | char *buffer_; 88 | char *bufferEnd_; 89 | char *current_; 90 | }; 91 | 92 | //! Implement specialized version of PutN() with memset() for better performance. 93 | template<> 94 | inline void PutN(FileWriteStream& stream, char c, size_t n) { 95 | stream.PutN(c, n); 96 | } 97 | 98 | RAPIDJSON_NAMESPACE_END 99 | 100 | #ifdef __clang__ 101 | RAPIDJSON_DIAG_POP 102 | #endif 103 | 104 | #endif // RAPIDJSON_FILESTREAM_H_ 105 | -------------------------------------------------------------------------------- /m34thook/rapiddecl/fwd.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_FWD_H_ 16 | #define RAPIDJSON_FWD_H_ 17 | 18 | #include "rapidjson.h" 19 | 20 | RAPIDJSON_NAMESPACE_BEGIN 21 | 22 | // encodings.h 23 | 24 | template struct UTF8; 25 | template struct UTF16; 26 | template struct UTF16BE; 27 | template struct UTF16LE; 28 | template struct UTF32; 29 | template struct UTF32BE; 30 | template struct UTF32LE; 31 | template struct ASCII; 32 | template struct AutoUTF; 33 | 34 | template 35 | struct Transcoder; 36 | 37 | // allocators.h 38 | 39 | class CrtAllocator; 40 | 41 | template 42 | class MemoryPoolAllocator; 43 | 44 | // stream.h 45 | 46 | template 47 | struct GenericStringStream; 48 | 49 | typedef GenericStringStream > StringStream; 50 | 51 | template 52 | struct GenericInsituStringStream; 53 | 54 | typedef GenericInsituStringStream > InsituStringStream; 55 | 56 | // stringbuffer.h 57 | 58 | template 59 | class GenericStringBuffer; 60 | 61 | typedef GenericStringBuffer, CrtAllocator> StringBuffer; 62 | 63 | // filereadstream.h 64 | 65 | class FileReadStream; 66 | 67 | // filewritestream.h 68 | 69 | class FileWriteStream; 70 | 71 | // memorybuffer.h 72 | 73 | template 74 | struct GenericMemoryBuffer; 75 | 76 | typedef GenericMemoryBuffer MemoryBuffer; 77 | 78 | // memorystream.h 79 | 80 | struct MemoryStream; 81 | 82 | // reader.h 83 | 84 | template 85 | struct BaseReaderHandler; 86 | 87 | template 88 | class GenericReader; 89 | 90 | typedef GenericReader, UTF8, CrtAllocator> Reader; 91 | 92 | // writer.h 93 | 94 | template 95 | class Writer; 96 | 97 | // prettywriter.h 98 | 99 | template 100 | class PrettyWriter; 101 | 102 | // document.h 103 | 104 | template 105 | struct GenericMember; 106 | 107 | template 108 | class GenericMemberIterator; 109 | 110 | template 111 | struct GenericStringRef; 112 | 113 | template 114 | class GenericValue; 115 | 116 | typedef GenericValue, MemoryPoolAllocator > Value; 117 | 118 | template 119 | class GenericDocument; 120 | 121 | typedef GenericDocument, MemoryPoolAllocator, CrtAllocator> Document; 122 | 123 | // pointer.h 124 | 125 | template 126 | class GenericPointer; 127 | 128 | typedef GenericPointer Pointer; 129 | 130 | // schema.h 131 | 132 | template 133 | class IGenericRemoteSchemaDocumentProvider; 134 | 135 | template 136 | class GenericSchemaDocument; 137 | 138 | typedef GenericSchemaDocument SchemaDocument; 139 | typedef IGenericRemoteSchemaDocumentProvider IRemoteSchemaDocumentProvider; 140 | 141 | template < 142 | typename SchemaDocumentType, 143 | typename OutputHandler, 144 | typename StateAllocator> 145 | class GenericSchemaValidator; 146 | 147 | typedef GenericSchemaValidator, void>, CrtAllocator> SchemaValidator; 148 | 149 | RAPIDJSON_NAMESPACE_END 150 | 151 | #endif // RAPIDJSON_RAPIDJSONFWD_H_ 152 | -------------------------------------------------------------------------------- /m34thook/rapiddecl/internal/ieee754.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_IEEE754_ 16 | #define RAPIDJSON_IEEE754_ 17 | 18 | #include "../rapidjson.h" 19 | 20 | RAPIDJSON_NAMESPACE_BEGIN 21 | namespace internal { 22 | 23 | class Double { 24 | public: 25 | Double() {} 26 | Double(double d) : d_(d) {} 27 | Double(uint64_t u) : u_(u) {} 28 | 29 | double Value() const { return d_; } 30 | uint64_t Uint64Value() const { return u_; } 31 | 32 | double NextPositiveDouble() const { 33 | RAPIDJSON_ASSERT(!Sign()); 34 | return Double(u_ + 1).Value(); 35 | } 36 | 37 | bool Sign() const { return (u_ & kSignMask) != 0; } 38 | uint64_t Significand() const { return u_ & kSignificandMask; } 39 | int Exponent() const { return static_cast(((u_ & kExponentMask) >> kSignificandSize) - kExponentBias); } 40 | 41 | bool IsNan() const { return (u_ & kExponentMask) == kExponentMask && Significand() != 0; } 42 | bool IsInf() const { return (u_ & kExponentMask) == kExponentMask && Significand() == 0; } 43 | bool IsNanOrInf() const { return (u_ & kExponentMask) == kExponentMask; } 44 | bool IsNormal() const { return (u_ & kExponentMask) != 0 || Significand() == 0; } 45 | bool IsZero() const { return (u_ & (kExponentMask | kSignificandMask)) == 0; } 46 | 47 | uint64_t IntegerSignificand() const { return IsNormal() ? Significand() | kHiddenBit : Significand(); } 48 | int IntegerExponent() const { return (IsNormal() ? Exponent() : kDenormalExponent) - kSignificandSize; } 49 | uint64_t ToBias() const { return (u_ & kSignMask) ? ~u_ + 1 : u_ | kSignMask; } 50 | 51 | static int EffectiveSignificandSize(int order) { 52 | if (order >= -1021) 53 | return 53; 54 | else if (order <= -1074) 55 | return 0; 56 | else 57 | return order + 1074; 58 | } 59 | 60 | private: 61 | static const int kSignificandSize = 52; 62 | static const int kExponentBias = 0x3FF; 63 | static const int kDenormalExponent = 1 - kExponentBias; 64 | static const uint64_t kSignMask = RAPIDJSON_UINT64_C2(0x80000000, 0x00000000); 65 | static const uint64_t kExponentMask = RAPIDJSON_UINT64_C2(0x7FF00000, 0x00000000); 66 | static const uint64_t kSignificandMask = RAPIDJSON_UINT64_C2(0x000FFFFF, 0xFFFFFFFF); 67 | static const uint64_t kHiddenBit = RAPIDJSON_UINT64_C2(0x00100000, 0x00000000); 68 | 69 | union { 70 | double d_; 71 | uint64_t u_; 72 | }; 73 | }; 74 | 75 | } // namespace internal 76 | RAPIDJSON_NAMESPACE_END 77 | 78 | #endif // RAPIDJSON_IEEE754_ 79 | -------------------------------------------------------------------------------- /m34thook/rapiddecl/internal/pow10.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_POW10_ 16 | #define RAPIDJSON_POW10_ 17 | 18 | #include "../rapidjson.h" 19 | 20 | RAPIDJSON_NAMESPACE_BEGIN 21 | namespace internal { 22 | 23 | //! Computes integer powers of 10 in double (10.0^n). 24 | /*! This function uses lookup table for fast and accurate results. 25 | \param n non-negative exponent. Must <= 308. 26 | \return 10.0^n 27 | */ 28 | inline double Pow10(int n) { 29 | static const double e[] = { // 1e-0...1e308: 309 * 8 bytes = 2472 bytes 30 | 1e+0, 31 | 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8, 1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20, 32 | 1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40, 33 | 1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60, 34 | 1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80, 35 | 1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100, 36 | 1e+101,1e+102,1e+103,1e+104,1e+105,1e+106,1e+107,1e+108,1e+109,1e+110,1e+111,1e+112,1e+113,1e+114,1e+115,1e+116,1e+117,1e+118,1e+119,1e+120, 37 | 1e+121,1e+122,1e+123,1e+124,1e+125,1e+126,1e+127,1e+128,1e+129,1e+130,1e+131,1e+132,1e+133,1e+134,1e+135,1e+136,1e+137,1e+138,1e+139,1e+140, 38 | 1e+141,1e+142,1e+143,1e+144,1e+145,1e+146,1e+147,1e+148,1e+149,1e+150,1e+151,1e+152,1e+153,1e+154,1e+155,1e+156,1e+157,1e+158,1e+159,1e+160, 39 | 1e+161,1e+162,1e+163,1e+164,1e+165,1e+166,1e+167,1e+168,1e+169,1e+170,1e+171,1e+172,1e+173,1e+174,1e+175,1e+176,1e+177,1e+178,1e+179,1e+180, 40 | 1e+181,1e+182,1e+183,1e+184,1e+185,1e+186,1e+187,1e+188,1e+189,1e+190,1e+191,1e+192,1e+193,1e+194,1e+195,1e+196,1e+197,1e+198,1e+199,1e+200, 41 | 1e+201,1e+202,1e+203,1e+204,1e+205,1e+206,1e+207,1e+208,1e+209,1e+210,1e+211,1e+212,1e+213,1e+214,1e+215,1e+216,1e+217,1e+218,1e+219,1e+220, 42 | 1e+221,1e+222,1e+223,1e+224,1e+225,1e+226,1e+227,1e+228,1e+229,1e+230,1e+231,1e+232,1e+233,1e+234,1e+235,1e+236,1e+237,1e+238,1e+239,1e+240, 43 | 1e+241,1e+242,1e+243,1e+244,1e+245,1e+246,1e+247,1e+248,1e+249,1e+250,1e+251,1e+252,1e+253,1e+254,1e+255,1e+256,1e+257,1e+258,1e+259,1e+260, 44 | 1e+261,1e+262,1e+263,1e+264,1e+265,1e+266,1e+267,1e+268,1e+269,1e+270,1e+271,1e+272,1e+273,1e+274,1e+275,1e+276,1e+277,1e+278,1e+279,1e+280, 45 | 1e+281,1e+282,1e+283,1e+284,1e+285,1e+286,1e+287,1e+288,1e+289,1e+290,1e+291,1e+292,1e+293,1e+294,1e+295,1e+296,1e+297,1e+298,1e+299,1e+300, 46 | 1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308 47 | }; 48 | RAPIDJSON_ASSERT(n >= 0 && n <= 308); 49 | return e[n]; 50 | } 51 | 52 | } // namespace internal 53 | RAPIDJSON_NAMESPACE_END 54 | 55 | #endif // RAPIDJSON_POW10_ 56 | -------------------------------------------------------------------------------- /m34thook/rapiddecl/internal/strfunc.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_INTERNAL_STRFUNC_H_ 16 | #define RAPIDJSON_INTERNAL_STRFUNC_H_ 17 | 18 | #include "../stream.h" 19 | #include 20 | 21 | RAPIDJSON_NAMESPACE_BEGIN 22 | namespace internal { 23 | 24 | //! Custom strlen() which works on different character types. 25 | /*! \tparam Ch Character type (e.g. char, wchar_t, short) 26 | \param s Null-terminated input string. 27 | \return Number of characters in the string. 28 | \note This has the same semantics as strlen(), the return value is not number of Unicode codepoints. 29 | */ 30 | template 31 | inline SizeType StrLen(const Ch* s) { 32 | RAPIDJSON_ASSERT(s != 0); 33 | const Ch* p = s; 34 | while (*p) ++p; 35 | return SizeType(p - s); 36 | } 37 | 38 | template <> 39 | inline SizeType StrLen(const char* s) { 40 | return SizeType(std::strlen(s)); 41 | } 42 | 43 | template <> 44 | inline SizeType StrLen(const wchar_t* s) { 45 | return SizeType(std::wcslen(s)); 46 | } 47 | 48 | //! Returns number of code points in a encoded string. 49 | template 50 | bool CountStringCodePoint(const typename Encoding::Ch* s, SizeType length, SizeType* outCount) { 51 | RAPIDJSON_ASSERT(s != 0); 52 | RAPIDJSON_ASSERT(outCount != 0); 53 | GenericStringStream is(s); 54 | const typename Encoding::Ch* end = s + length; 55 | SizeType count = 0; 56 | while (is.src_ < end) { 57 | unsigned codepoint; 58 | if (!Encoding::Decode(is, &codepoint)) 59 | return false; 60 | count++; 61 | } 62 | *outCount = count; 63 | return true; 64 | } 65 | 66 | } // namespace internal 67 | RAPIDJSON_NAMESPACE_END 68 | 69 | #endif // RAPIDJSON_INTERNAL_STRFUNC_H_ 70 | -------------------------------------------------------------------------------- /m34thook/rapiddecl/internal/swap.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_INTERNAL_SWAP_H_ 16 | #define RAPIDJSON_INTERNAL_SWAP_H_ 17 | 18 | #include "../rapidjson.h" 19 | 20 | #if defined(__clang__) 21 | RAPIDJSON_DIAG_PUSH 22 | RAPIDJSON_DIAG_OFF(c++98-compat) 23 | #endif 24 | 25 | RAPIDJSON_NAMESPACE_BEGIN 26 | namespace internal { 27 | 28 | //! Custom swap() to avoid dependency on C++ header 29 | /*! \tparam T Type of the arguments to swap, should be instantiated with primitive C++ types only. 30 | \note This has the same semantics as std::swap(). 31 | */ 32 | template 33 | inline void Swap(T& a, T& b) RAPIDJSON_NOEXCEPT { 34 | T tmp = a; 35 | a = b; 36 | b = tmp; 37 | } 38 | 39 | } // namespace internal 40 | RAPIDJSON_NAMESPACE_END 41 | 42 | #if defined(__clang__) 43 | RAPIDJSON_DIAG_POP 44 | #endif 45 | 46 | #endif // RAPIDJSON_INTERNAL_SWAP_H_ 47 | -------------------------------------------------------------------------------- /m34thook/rapiddecl/istreamwrapper.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_ISTREAMWRAPPER_H_ 16 | #define RAPIDJSON_ISTREAMWRAPPER_H_ 17 | 18 | #include "stream.h" 19 | #include 20 | 21 | #ifdef __clang__ 22 | RAPIDJSON_DIAG_PUSH 23 | RAPIDJSON_DIAG_OFF(padded) 24 | #endif 25 | 26 | #ifdef _MSC_VER 27 | RAPIDJSON_DIAG_PUSH 28 | RAPIDJSON_DIAG_OFF(4351) // new behavior: elements of array 'array' will be default initialized 29 | #endif 30 | 31 | RAPIDJSON_NAMESPACE_BEGIN 32 | 33 | //! Wrapper of \c std::basic_istream into RapidJSON's Stream concept. 34 | /*! 35 | The classes can be wrapped including but not limited to: 36 | 37 | - \c std::istringstream 38 | - \c std::stringstream 39 | - \c std::wistringstream 40 | - \c std::wstringstream 41 | - \c std::ifstream 42 | - \c std::fstream 43 | - \c std::wifstream 44 | - \c std::wfstream 45 | 46 | \tparam StreamType Class derived from \c std::basic_istream. 47 | */ 48 | 49 | template 50 | class BasicIStreamWrapper { 51 | public: 52 | typedef typename StreamType::char_type Ch; 53 | BasicIStreamWrapper(StreamType& stream) : stream_(stream), count_(), peekBuffer_() {} 54 | 55 | Ch Peek() const { 56 | typename StreamType::int_type c = stream_.peek(); 57 | return RAPIDJSON_LIKELY(c != StreamType::traits_type::eof()) ? static_cast(c) : static_cast('\0'); 58 | } 59 | 60 | Ch Take() { 61 | typename StreamType::int_type c = stream_.get(); 62 | if (RAPIDJSON_LIKELY(c != StreamType::traits_type::eof())) { 63 | count_++; 64 | return static_cast(c); 65 | } 66 | else 67 | return '\0'; 68 | } 69 | 70 | // tellg() may return -1 when failed. So we count by ourself. 71 | size_t Tell() const { return count_; } 72 | 73 | Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } 74 | void Put(Ch) { RAPIDJSON_ASSERT(false); } 75 | void Flush() { RAPIDJSON_ASSERT(false); } 76 | size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } 77 | 78 | // For encoding detection only. 79 | const Ch* Peek4() const { 80 | RAPIDJSON_ASSERT(sizeof(Ch) == 1); // Only usable for byte stream. 81 | int i; 82 | bool hasError = false; 83 | for (i = 0; i < 4; ++i) { 84 | typename StreamType::int_type c = stream_.get(); 85 | if (c == StreamType::traits_type::eof()) { 86 | hasError = true; 87 | stream_.clear(); 88 | break; 89 | } 90 | peekBuffer_[i] = static_cast(c); 91 | } 92 | for (--i; i >= 0; --i) 93 | stream_.putback(peekBuffer_[i]); 94 | return !hasError ? peekBuffer_ : 0; 95 | } 96 | 97 | private: 98 | BasicIStreamWrapper(const BasicIStreamWrapper&); 99 | BasicIStreamWrapper& operator=(const BasicIStreamWrapper&); 100 | 101 | StreamType& stream_; 102 | size_t count_; //!< Number of characters read. Note: 103 | mutable Ch peekBuffer_[4]; 104 | }; 105 | 106 | typedef BasicIStreamWrapper IStreamWrapper; 107 | typedef BasicIStreamWrapper WIStreamWrapper; 108 | 109 | #if defined(__clang__) || defined(_MSC_VER) 110 | RAPIDJSON_DIAG_POP 111 | #endif 112 | 113 | RAPIDJSON_NAMESPACE_END 114 | 115 | #endif // RAPIDJSON_ISTREAMWRAPPER_H_ 116 | -------------------------------------------------------------------------------- /m34thook/rapiddecl/memorybuffer.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_MEMORYBUFFER_H_ 16 | #define RAPIDJSON_MEMORYBUFFER_H_ 17 | 18 | #include "stream.h" 19 | #include "internal/stack.h" 20 | 21 | RAPIDJSON_NAMESPACE_BEGIN 22 | 23 | //! Represents an in-memory output byte stream. 24 | /*! 25 | This class is mainly for being wrapped by EncodedOutputStream or AutoUTFOutputStream. 26 | 27 | It is similar to FileWriteBuffer but the destination is an in-memory buffer instead of a file. 28 | 29 | Differences between MemoryBuffer and StringBuffer: 30 | 1. StringBuffer has Encoding but MemoryBuffer is only a byte buffer. 31 | 2. StringBuffer::GetString() returns a null-terminated string. MemoryBuffer::GetBuffer() returns a buffer without terminator. 32 | 33 | \tparam Allocator type for allocating memory buffer. 34 | \note implements Stream concept 35 | */ 36 | template 37 | struct GenericMemoryBuffer { 38 | typedef char Ch; // byte 39 | 40 | GenericMemoryBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {} 41 | 42 | void Put(Ch c) { *stack_.template Push() = c; } 43 | void Flush() {} 44 | 45 | void Clear() { stack_.Clear(); } 46 | void ShrinkToFit() { stack_.ShrinkToFit(); } 47 | Ch* Push(size_t count) { return stack_.template Push(count); } 48 | void Pop(size_t count) { stack_.template Pop(count); } 49 | 50 | const Ch* GetBuffer() const { 51 | return stack_.template Bottom(); 52 | } 53 | 54 | size_t GetSize() const { return stack_.GetSize(); } 55 | 56 | static const size_t kDefaultCapacity = 256; 57 | mutable internal::Stack stack_; 58 | }; 59 | 60 | typedef GenericMemoryBuffer<> MemoryBuffer; 61 | 62 | //! Implement specialized version of PutN() with memset() for better performance. 63 | template<> 64 | inline void PutN(MemoryBuffer& memoryBuffer, char c, size_t n) { 65 | std::memset(memoryBuffer.stack_.Push(n), c, n * sizeof(c)); 66 | } 67 | 68 | RAPIDJSON_NAMESPACE_END 69 | 70 | #endif // RAPIDJSON_MEMORYBUFFER_H_ 71 | -------------------------------------------------------------------------------- /m34thook/rapiddecl/memorystream.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_MEMORYSTREAM_H_ 16 | #define RAPIDJSON_MEMORYSTREAM_H_ 17 | 18 | #include "stream.h" 19 | 20 | #ifdef __clang__ 21 | RAPIDJSON_DIAG_PUSH 22 | RAPIDJSON_DIAG_OFF(unreachable-code) 23 | RAPIDJSON_DIAG_OFF(missing-noreturn) 24 | #endif 25 | 26 | RAPIDJSON_NAMESPACE_BEGIN 27 | 28 | //! Represents an in-memory input byte stream. 29 | /*! 30 | This class is mainly for being wrapped by EncodedInputStream or AutoUTFInputStream. 31 | 32 | It is similar to FileReadBuffer but the source is an in-memory buffer instead of a file. 33 | 34 | Differences between MemoryStream and StringStream: 35 | 1. StringStream has encoding but MemoryStream is a byte stream. 36 | 2. MemoryStream needs size of the source buffer and the buffer don't need to be null terminated. StringStream assume null-terminated string as source. 37 | 3. MemoryStream supports Peek4() for encoding detection. StringStream is specified with an encoding so it should not have Peek4(). 38 | \note implements Stream concept 39 | */ 40 | struct MemoryStream { 41 | typedef char Ch; // byte 42 | 43 | MemoryStream(const Ch *src, size_t size) : src_(src), begin_(src), end_(src + size), size_(size) {} 44 | 45 | Ch Peek() const { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\0' : *src_; } 46 | Ch Take() { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\0' : *src_++; } 47 | size_t Tell() const { return static_cast(src_ - begin_); } 48 | 49 | Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } 50 | void Put(Ch) { RAPIDJSON_ASSERT(false); } 51 | void Flush() { RAPIDJSON_ASSERT(false); } 52 | size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } 53 | 54 | // For encoding detection only. 55 | const Ch* Peek4() const { 56 | return Tell() + 4 <= size_ ? src_ : 0; 57 | } 58 | 59 | const Ch* src_; //!< Current read position. 60 | const Ch* begin_; //!< Original head of the string. 61 | const Ch* end_; //!< End of stream. 62 | size_t size_; //!< Size of the stream. 63 | }; 64 | 65 | RAPIDJSON_NAMESPACE_END 66 | 67 | #ifdef __clang__ 68 | RAPIDJSON_DIAG_POP 69 | #endif 70 | 71 | #endif // RAPIDJSON_MEMORYBUFFER_H_ 72 | -------------------------------------------------------------------------------- /m34thook/rapiddecl/ostreamwrapper.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_OSTREAMWRAPPER_H_ 16 | #define RAPIDJSON_OSTREAMWRAPPER_H_ 17 | 18 | #include "stream.h" 19 | #include 20 | 21 | #ifdef __clang__ 22 | RAPIDJSON_DIAG_PUSH 23 | RAPIDJSON_DIAG_OFF(padded) 24 | #endif 25 | 26 | RAPIDJSON_NAMESPACE_BEGIN 27 | 28 | //! Wrapper of \c std::basic_ostream into RapidJSON's Stream concept. 29 | /*! 30 | The classes can be wrapped including but not limited to: 31 | 32 | - \c std::ostringstream 33 | - \c std::stringstream 34 | - \c std::wpstringstream 35 | - \c std::wstringstream 36 | - \c std::ifstream 37 | - \c std::fstream 38 | - \c std::wofstream 39 | - \c std::wfstream 40 | 41 | \tparam StreamType Class derived from \c std::basic_ostream. 42 | */ 43 | 44 | template 45 | class BasicOStreamWrapper { 46 | public: 47 | typedef typename StreamType::char_type Ch; 48 | BasicOStreamWrapper(StreamType& stream) : stream_(stream) {} 49 | 50 | void Put(Ch c) { 51 | stream_.put(c); 52 | } 53 | 54 | void Flush() { 55 | stream_.flush(); 56 | } 57 | 58 | // Not implemented 59 | char Peek() const { RAPIDJSON_ASSERT(false); return 0; } 60 | char Take() { RAPIDJSON_ASSERT(false); return 0; } 61 | size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } 62 | char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } 63 | size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; } 64 | 65 | private: 66 | BasicOStreamWrapper(const BasicOStreamWrapper&); 67 | BasicOStreamWrapper& operator=(const BasicOStreamWrapper&); 68 | 69 | StreamType& stream_; 70 | }; 71 | 72 | typedef BasicOStreamWrapper OStreamWrapper; 73 | typedef BasicOStreamWrapper WOStreamWrapper; 74 | 75 | #ifdef __clang__ 76 | RAPIDJSON_DIAG_POP 77 | #endif 78 | 79 | RAPIDJSON_NAMESPACE_END 80 | 81 | #endif // RAPIDJSON_OSTREAMWRAPPER_H_ 82 | -------------------------------------------------------------------------------- /m34thook/rapiddecl/stringbuffer.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_STRINGBUFFER_H_ 16 | #define RAPIDJSON_STRINGBUFFER_H_ 17 | 18 | #include "stream.h" 19 | #include "internal/stack.h" 20 | 21 | #if RAPIDJSON_HAS_CXX11_RVALUE_REFS 22 | #include // std::move 23 | #endif 24 | 25 | #include "internal/stack.h" 26 | 27 | #if defined(__clang__) 28 | RAPIDJSON_DIAG_PUSH 29 | RAPIDJSON_DIAG_OFF(c++98-compat) 30 | #endif 31 | 32 | RAPIDJSON_NAMESPACE_BEGIN 33 | 34 | //! Represents an in-memory output stream. 35 | /*! 36 | \tparam Encoding Encoding of the stream. 37 | \tparam Allocator type for allocating memory buffer. 38 | \note implements Stream concept 39 | */ 40 | template 41 | class GenericStringBuffer { 42 | public: 43 | typedef typename Encoding::Ch Ch; 44 | 45 | GenericStringBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {} 46 | 47 | #if RAPIDJSON_HAS_CXX11_RVALUE_REFS 48 | GenericStringBuffer(GenericStringBuffer&& rhs) : stack_(std::move(rhs.stack_)) {} 49 | GenericStringBuffer& operator=(GenericStringBuffer&& rhs) { 50 | if (&rhs != this) 51 | stack_ = std::move(rhs.stack_); 52 | return *this; 53 | } 54 | #endif 55 | 56 | void Put(Ch c) { *stack_.template Push() = c; } 57 | void PutUnsafe(Ch c) { *stack_.template PushUnsafe() = c; } 58 | void Flush() {} 59 | 60 | void Clear() { stack_.Clear(); } 61 | void ShrinkToFit() { 62 | // Push and pop a null terminator. This is safe. 63 | *stack_.template Push() = '\0'; 64 | stack_.ShrinkToFit(); 65 | stack_.template Pop(1); 66 | } 67 | 68 | void Reserve(size_t count) { stack_.template Reserve(count); } 69 | Ch* Push(size_t count) { return stack_.template Push(count); } 70 | Ch* PushUnsafe(size_t count) { return stack_.template PushUnsafe(count); } 71 | void Pop(size_t count) { stack_.template Pop(count); } 72 | 73 | const Ch* GetString() const { 74 | // Push and pop a null terminator. This is safe. 75 | *stack_.template Push() = '\0'; 76 | stack_.template Pop(1); 77 | 78 | return stack_.template Bottom(); 79 | } 80 | 81 | //! Get the size of string in bytes in the string buffer. 82 | size_t GetSize() const { return stack_.GetSize(); } 83 | 84 | //! Get the length of string in Ch in the string buffer. 85 | size_t GetLength() const { return stack_.GetSize() / sizeof(Ch); } 86 | 87 | static const size_t kDefaultCapacity = 256; 88 | mutable internal::Stack stack_; 89 | 90 | private: 91 | // Prohibit copy constructor & assignment operator. 92 | GenericStringBuffer(const GenericStringBuffer&); 93 | GenericStringBuffer& operator=(const GenericStringBuffer&); 94 | }; 95 | 96 | //! String buffer with UTF8 encoding 97 | typedef GenericStringBuffer > StringBuffer; 98 | 99 | template 100 | inline void PutReserve(GenericStringBuffer& stream, size_t count) { 101 | stream.Reserve(count); 102 | } 103 | 104 | template 105 | inline void PutUnsafe(GenericStringBuffer& stream, typename Encoding::Ch c) { 106 | stream.PutUnsafe(c); 107 | } 108 | 109 | //! Implement specialized version of PutN() with memset() for better performance. 110 | template<> 111 | inline void PutN(GenericStringBuffer >& stream, char c, size_t n) { 112 | std::memset(stream.stack_.Push(n), c, n * sizeof(c)); 113 | } 114 | 115 | RAPIDJSON_NAMESPACE_END 116 | 117 | #if defined(__clang__) 118 | RAPIDJSON_DIAG_POP 119 | #endif 120 | 121 | #endif // RAPIDJSON_STRINGBUFFER_H_ 122 | -------------------------------------------------------------------------------- /m34thook/resource.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | struct resourceList_t; 3 | struct idResourceList { 4 | resourceList_t* resourceList; 5 | char* typeName; 6 | char* className; 7 | idResourceList* next; 8 | void (*postInitCallback)(idResourceList * const resourceList); 9 | }; -------------------------------------------------------------------------------- /m34thook/scanner_core.cpp: -------------------------------------------------------------------------------- 1 | #include "mh_defs.hpp" 2 | 3 | #include "game_exe_interface.hpp" 4 | #include "memscan.hpp" 5 | #include "scanner_core.hpp" 6 | #include 7 | #include 8 | #include "snaphakalgo.hpp" 9 | #include 10 | #include "idtypeinfo.hpp" 11 | #include "gameapi.hpp" 12 | 13 | #define SCANNED_PTR_FEATURE(name, ...) located_feature_t descan:: name = 0; 14 | #define SCANNED_UINT_FEATURE(name,...) unsigned descan:: name = 0; 15 | #include "xmacro_scanned_features.hpp" 16 | #undef SCANNED_PTR_FEATURE 17 | #undef SCANNED_UINT_FEATURE 18 | 19 | std::map g_str_to_rrti_type_descr{}; 20 | MH_NOINLINE 21 | MH_PURE 22 | static scanner_ops_t* get_scanops_for_curr_cpu() { 23 | switch(g_shalgo.m_cpulevel) { 24 | case snaphak_cpu_lvl_t::AVX2Cpu: 25 | return &g_scanops_avx2; 26 | 27 | case snaphak_cpu_lvl_t::AVX512Cpu: 28 | return &g_scanops_avx512; 29 | 30 | default: 31 | return &g_scanops_generic; 32 | } 33 | } 34 | 35 | MH_NOINLINE 36 | void descan::locate_critical_features(){ 37 | get_scanops_for_curr_cpu()->locate_critical_features(); 38 | } 39 | 40 | MH_NOINLINE 41 | void descan::run_late_scangroups(){ 42 | get_scanops_for_curr_cpu()->run_late_scangroups(); 43 | } 44 | 45 | 46 | MH_NOINLINE 47 | void descan::run_gamelib_postinit_scangroups() { 48 | get_scanops_for_curr_cpu()->run_gamelib_postinit_scangroups(); 49 | } -------------------------------------------------------------------------------- /m34thook/scanner_core.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "mh_defs.hpp" 3 | #include 4 | #include 5 | using located_feature_t = void*; 6 | //need 1080 getlevelmap 7 | 8 | 9 | extern std::map g_str_to_rrti_type_descr; 10 | 11 | namespace descan { 12 | #define SCANNED_PTR_FEATURE(name, ...) extern located_feature_t name; 13 | #define SCANNED_UINT_FEATURE(name,...) extern unsigned name; 14 | #include "xmacro_scanned_features.hpp" 15 | #undef SCANNED_PTR_FEATURE 16 | #undef SCANNED_UINT_FEATURE 17 | 18 | 19 | 20 | MH_NOINLINE 21 | void locate_critical_features(); 22 | 23 | MH_NOINLINE 24 | void run_late_scangroups(); 25 | 26 | /* 27 | at this point we have access to things like typeinfotools, 28 | runs on very first frame of idCommonLocal::Frame 29 | */ 30 | MH_NOINLINE 31 | void run_gamelib_postinit_scangroups(); 32 | } 33 | 34 | struct scanner_ops_t { 35 | void (*locate_critical_features)(); 36 | void (*run_late_scangroups)(); 37 | void (*run_gamelib_postinit_scangroups)(); 38 | }; 39 | 40 | extern scanner_ops_t g_scanops_generic; 41 | extern scanner_ops_t g_scanops_avx2; 42 | extern scanner_ops_t g_scanops_avx512; -------------------------------------------------------------------------------- /m34thook/scanners/scanners_avx2.cpp: -------------------------------------------------------------------------------- 1 | #include "mh_defs.hpp" 2 | 3 | #include "game_exe_interface.hpp" 4 | #include "memscan.hpp" 5 | #include "scanner_core.hpp" 6 | #include 7 | #include 8 | #include "snaphakalgo.hpp" 9 | #include 10 | #include "idtypeinfo.hpp" 11 | #include "gameapi.hpp" 12 | #include "cmdsystem.hpp" 13 | 14 | #include "scanners/scanner_core_incl.hpp" 15 | 16 | scanner_ops_t g_scanops_avx2{ .locate_critical_features = descan_locate_critical_features, 17 | .run_late_scangroups = descan_run_late_scangroups, .run_gamelib_postinit_scangroups = descan_run_gamelib_postinit_scangroups }; -------------------------------------------------------------------------------- /m34thook/scanners/scanners_avx512.cpp: -------------------------------------------------------------------------------- 1 | #include "mh_defs.hpp" 2 | 3 | #include "game_exe_interface.hpp" 4 | #include "memscan.hpp" 5 | #include "scanner_core.hpp" 6 | #include 7 | #include 8 | #include "snaphakalgo.hpp" 9 | #include 10 | #include "idtypeinfo.hpp" 11 | #include "gameapi.hpp" 12 | #include "cmdsystem.hpp" 13 | 14 | #include "scanners/scanner_core_incl.hpp" 15 | 16 | scanner_ops_t g_scanops_avx512{ .locate_critical_features = descan_locate_critical_features, 17 | .run_late_scangroups = descan_run_late_scangroups, .run_gamelib_postinit_scangroups = descan_run_gamelib_postinit_scangroups }; -------------------------------------------------------------------------------- /m34thook/scanners/scanners_generic.cpp: -------------------------------------------------------------------------------- 1 | #include "mh_defs.hpp" 2 | 3 | #include "game_exe_interface.hpp" 4 | #include "memscan.hpp" 5 | #include "scanner_core.hpp" 6 | #include 7 | #include 8 | #include "snaphakalgo.hpp" 9 | #include 10 | #include "idtypeinfo.hpp" 11 | #include "gameapi.hpp" 12 | #include "cmdsystem.hpp" 13 | 14 | #include "scanners/scanner_core_incl.hpp" 15 | 16 | scanner_ops_t g_scanops_generic{ .locate_critical_features = descan_locate_critical_features, 17 | .run_late_scangroups = descan_run_late_scangroups, .run_gamelib_postinit_scangroups = descan_run_gamelib_postinit_scangroups }; -------------------------------------------------------------------------------- /m34thook/scanners/scanners_typeinfo.hpp: -------------------------------------------------------------------------------- 1 | 2 | #if !defined(MH_ETERNAL_V6) 3 | using scanner_locate_findclassinfo = memscanner_t< 4 | /* scanbytes<0x48, 0x89, 0x5c, 0x24, 0x20, 0x56, 0x48, 0x83, 0xec, 0x20, 0x48, 0x8b, 0xf2, 0x48, 0x8b, 0xd9, 0x48, 0x85, 0xd2, 0x0F, 0x84>, 5 | skip<4>, 6 | scanbytes< 0x80, 0x3A, 0x00, 0x0F, 0x84>, 7 | skip<4>,*/ 8 | scanbytes<0x48, 0x89, 0x6c, 0x24, 0x30, 0x48, 0x8b, 0xca, 0x48, 0x89, 0x7c, 0x24, 0x38, 0x4c, 0x89, 0x74, 0x24, 0x40, 0xe8>, 9 | match_riprel32_to<&descan::g_idstr_hash>>; 10 | 11 | #else 12 | //this should work pre v6 as well 13 | 14 | using scanner_locate_findclassinfo = memscanner_t< 15 | scanbytes<0x48,0x8d,0x15>, 16 | riprel32_data_equals<0x69, 0x64, 0x50, 0x61, 0x72, 0x74, 0x69, 0x63, 0x6C, 0x65, 0x50, 0x61, 0x72, 0x6D, 0x00>, 17 | scanbytes<0x48,0x8b,0xcf,0xe8> 18 | >; 19 | 20 | #endif 21 | //141187E21 22 | using scanner_locate_findenuminfo = memscanner_t< 23 | scanbytes<0x48, 0x8B, 0x0D>, 24 | match_riprel32_to<&descan::g_global_typeinfo_tools>, 25 | scanbytes<0x48, 0x8D, 0x15>, 26 | riprel32_data_equals< 0x69, 0x64, 0x41, 0x6E, 0x69, 0x6D, 0x61, 0x74, 0x65, 0x64, 27 | 0x53, 0x69, 0x6D, 0x70, 0x6C, 0x65, 0x5F, 0x46, 0x61, 0x75, 28 | 0x73, 0x74, 0x3A, 0x3A, 0x6E, 0x6F, 0x64, 0x65, 0x46, 0x6C, 29 | 0x61, 0x67, 0x73, 0x5F, 0x74, 0x00>, 30 | scanbytes<0x48,0x8b,0xd8,0xe8> 31 | >; 32 | /*scanbytes<0xf,0xb6,0x11,0x33,0xc0,0x84,0xd2,0x74,0x1a,0xf,0x1f,0x80,0x0,0x0,0x0,0x0,0x6b,0xc0,0x1f,0x48,0x8d,0x49,0x1,0xf,0xb6,0xd2,0x3,0xc2,0xf,0xb6,0x11,0x84,0xd2,0x75,0xed,0xc3>*///>; 33 | 34 | using scanner_locate_global_typeinfo_tools = memscanner_t< 35 | scanbytes<0x48, 0x8D, 0x15>, 36 | riprel32_data_equals< 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x5F, 0x74, 37 | 0x00>,//duration_t 38 | scanbytes<0x48, 0x8B, 0x0D>>; 39 | 40 | 41 | /* 42 | match using readresource in v1.0 at 141889400 43 | this could be potentially problematic because its such a long pattern, 44 | but theres only one call to the function and this is it 45 | */ 46 | 47 | using scanner_locate_resourcelist_for_classname = memscanner_t< 48 | scanbytes<0x48, 0x89, 0x5c, 0x24, 0x8, 0x48, 0x89, 0x74, 0x24, 0x18, 0x57, 0x48, 0x81, 0xec, 0x60, 0x1, 0x0, 0x0, 0x48, 0x8B, 5>, 49 | match_riprel32_to<&descan::g_security_cookie>, 50 | scanbytes<0x48, 0x33, 0xc4, 0x48, 0x89, 0x84, 0x24, 0x50, 0x1, 0x0, 0x0, 0x48, 0x8b, 0xb4, 0x24, 0xb0, 0x1, 0x0, 0x0, 0x48, 0x8d, 0x4c, 0x24, 0x20, 0x49, 0x8b, 0xf9, 0x48, 0x8b, 0xda, 51 | 0xe8>, 52 | match_riprel32_to<&descan::g_idstr__idstr>, 53 | scanbytes<0x48, 0x8d, 0x44, 0x24, 0x50, 0xc6, 0x44, 0x24, 0x50, 0x0, 0x48, 0x89, 0x44, 0x24, 0x28, 0x48, 0x8d, 0x54, 0x24, 0x20, 0x8b, 0x44, 0x24, 0x34, 0x48, 0x8b, 0xcb, 0x25, 0x0, 0x1, 0x0, 0xc0, 0xc7, 0x44, 0x24, 0x30, 0x0, 0x0, 0x0, 0x0, 0xd, 54 | 0x0, 0x1, 0x0, 0x80, 0x89, 0x44, 0x24, 0x34, 55 | 0x48, 0x8d>, 56 | skip<5>, 57 | scanbytes<0x48, 0x89, 0x44, 0x24, 0x20, 0xe8>, 58 | skip_and_capture_rva<&descan::g_idTypeInfoFile_readstr>, //capturing this address, just because we can 59 | scanbytes<0x48, 0x8b, 0xcf, 0xe8>>/* rva after is the address of resourcelistforclassname */; 60 | 61 | /* 62 | use scan function bounds on resourcelistforclassname 63 | */ 64 | using scanner_locate_listofResourceLists_and_idstricmp = memscanner_t< 65 | scanbytes<0x48, 0x89, 0x5c, 0x24, 0x8, 0x57, 0x48, 0x83, 0xec, 0x20, 66 | 0x48, 0x8B, 0x1D>, 67 | skip_and_capture_rva<&descan::g_listOfResourceLists>, 68 | scanbytes<0x48, 0x8b, 0xf9, 0x48, 0x85, 0xdb, 0x74>, 69 | skip<1>, 70 | align_next<16>, 71 | scanbytes<0x48, 0x8b, 0x4b, 0x8, 0x48, 0x8b, 0xd7, 0x48, 0x8b, 0x49, 0x8, 0xe8>>; 72 | 73 | 74 | 75 | //g_declentitydef_setentitystate 76 | using locate_setentitystate = memscanner_t< 77 | 78 | scanbytes<0x48, 0x85, 0xd2, 0xf, 0x84>, 79 | skip<4>, 80 | scanbytes<0x4c, 0x8b, 0xdc, 0x55, 0x57, 0x41, 0x56, 0x49, 0x8d, 0xab, 0x8, 0xff, 0xff, 0xff, 0x48, 0x81, 0xec, 0xe0, 0x1, 0x0, 0x0, 0x48, 0x8b, 5>, 81 | match_riprel32_to<&descan::g_security_cookie>, 82 | scanbytes<0x48, 0x33, 0xc4, 0x48, 0x89, 0x85, 0xb0, 0x0, 0x0, 0x0, 0x48, 0x8b, 0xf9, 0x49, 0x89, 0x5b, 0x18>>; 83 | -------------------------------------------------------------------------------- /m34thook/scanners/tertiary_scangroup.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | //most complicated scanner so far imo 4 | // checked against ms store, v1 5 | //v1= 14046AD57 6 | //use scanbehavior_simple, we get a pointer to an int 7 | using rendermodelgui_vertexcolor_offset_locator = memscanner_t< 8 | scanbytes<0xE8>,//might as well grab setviewport while we're here 9 | skip_and_capture_rva<&descan::g_idRenderModelGui_SetViewPort>, 10 | scanbytes<0x48,0x8b,0x47>, skip_and_push<1>, scanbytes<0x48,0x8d,0x4c,0x24>, 11 | skip_and_push<1>, 12 | scanbytes<0x0F,0x28,0x05>, 13 | riprel32_data_equals< 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 14 | 0x80, 0x3F, 0x00, 0x00, 0x80, 0x3F>, 15 | scanbytes<0xf,0x11,0x44,0x24>, 16 | cmp_backref<1, 1>,//0x60 17 | scanbytes<0x48,0xc7,0x80>, 18 | skip<2>, 19 | scanbytes<0x0,0x0,0x2c,0x0,0x0,0x0, 20 | 0x48,0x8b,0x5f>, 21 | cmp_backref<2, 1>,//0x30 22 | scanbytes<0xe8>, 23 | match_riprel32_to<&descan::g_idcolor_packcolor>, 24 | scanbytes<0x89,0x83> //last four is the offset to vertexcolor 25 | //0xeb,0xea,0xea,0xff> 26 | >; 27 | 28 | using ideventarg_from_entity_ctor_locator = memscanner_t< 29 | scanbytes<0x4c, 0x8d, 0x4c, 0x24>, skip<2>, 30 | 31 | scanbytes< 0x8b>, skip<1>, 32 | scanbytes<0x4C,0x8D,0x05>, 33 | late_riprel_to_eventdef_m("volumeMemberRemoved") 34 | >; 35 | //can use to call all ingame events.can get event results too. prettttty handy especially if scriptcmdent isnt present, 36 | //although unlike scriptcmdent process_eventargs can get the result 37 | using ideventreceiver_process_eventargs = memscanner_t< 38 | scanbytes<0xEB>, skip<1>, 39 | scanbytes<0x48, 0x8b, 0x16, 0x48, 0x8d, 0xd>, 40 | riprel32_data_equals< 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6E, 0x61, 0x6C, 0x43, 0x61, 41 | 0x6C, 0x6C, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x28, 0x29, 0x20, 42 | 0x64, 0x6F, 0x65, 0x73, 0x6E, 0x27, 0x74, 0x20, 0x68, 0x61, 43 | 0x6E, 0x64, 0x6C, 0x65, 0x20, 0x65, 0x76, 0x65, 0x6E, 0x74, 44 | 0x20, 0x25, 0x73, 0x2E, 0x00>>; 45 | 46 | 47 | namespace scanners_phase3 { 48 | BSCANENT(locate_vertexcolor_offset_entry, &descan::g_idRenderModelGui_VertexColorOffsPtr, scanbehavior_simple); 49 | BSCANENT(ideventarg_from_entity_ctor_enty, &descan::g_eventarg_ctor_identityptr, scanbehavior_locate_csrel_preceding< ideventarg_from_entity_ctor_locator>); 50 | 51 | BSCANENT(locate_processeventargs, &descan::g_eventreceiver_processeventargs, scanbehavior_locate_csrel_preceding< ideventreceiver_process_eventargs>); 52 | static scangroup_t tertiary_scangroup_pass{}; 53 | 54 | } 55 | -------------------------------------------------------------------------------- /m34thook/thunkstrementer.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | we want to determine, for all functions that are pointed to on virtual function tables, what instructions may call them 4 | 5 | so we JIT special thunks that load the current return address, subtract the base of the exe, and then search for it in an array to see if we already have that return address 6 | 7 | so that reallocation is not needed we greatly overallocate. (this assumes the user has enormous amounts of memory, in this case a workstation with 256 gb of ddr4 is used) 8 | */ -------------------------------------------------------------------------------- /m34thook/win32/ntdll.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brongo/m3337ho0o0ok/e12dd752884ba443afe13f94e326d500b390bd14/m34thook/win32/ntdll.h -------------------------------------------------------------------------------- /m34thook/xmacro_mh_config.hpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /snaphak_algo/impls/avx2/memops_avx2.hpp: -------------------------------------------------------------------------------- 1 | IMPL_CODE_SEG 2 | static 3 | void cs_zeromem_nt(void* _to, size_t size) { 4 | 5 | char* to = (char*)_to; 6 | #pragma clang loop vectorize(disable) 7 | #pragma clang loop unroll(disable) 8 | while((reinterpret_cast(to)&31) && size != 0) { 9 | *to = 0; 10 | --size; 11 | ++to; 12 | } 13 | 14 | while(size >= 32) { 15 | _mm256_stream_si256((__m256i*)to, _mm256_setzero_si256()); 16 | size-=32; 17 | to+=32; 18 | } 19 | 20 | #pragma clang loop vectorize(disable) 21 | #pragma clang loop unroll(disable) 22 | while(size) { 23 | *to = 0; 24 | ++to; 25 | --size; 26 | } 27 | } 28 | IMPL_CODE_SEG 29 | static 30 | void cs_movemem_nt(void* _to, const void* _from, size_t size) { 31 | 32 | char* to = (char*)_to; 33 | const char* from = (const char*)_from; 34 | #pragma clang loop vectorize(disable) 35 | #pragma clang loop unroll(disable) 36 | while((reinterpret_cast(to)&31) && size != 0) { 37 | *to = *from; 38 | --size; 39 | ++to; 40 | ++from; 41 | } 42 | 43 | while(size >= 32) { 44 | _mm256_stream_si256((__m256i*)to, _mm256_loadu_si256((const __m256i*)from)); 45 | size-=32; 46 | from += 32; 47 | to+=32; 48 | } 49 | 50 | #pragma clang loop vectorize(disable) 51 | #pragma clang loop unroll(disable) 52 | while(size) { 53 | *to = *from; 54 | ++to; 55 | ++from; 56 | --size; 57 | } 58 | } 59 | IMPL_CODE_SEG 60 | static 61 | void cs_movemem_flush_opt_nt(void* _to, const void* _from, size_t size) { 62 | 63 | char* to = (char*)_to; 64 | const char* from = (const char*)_from; 65 | #pragma clang loop vectorize(disable) 66 | #pragma clang loop unroll(disable) 67 | while((reinterpret_cast(to)&31) && size != 0) { 68 | *to = *from; 69 | --size; 70 | ++to; 71 | ++from; 72 | } 73 | 74 | 75 | 76 | 77 | while(size >= 64) { 78 | _mm256_stream_si256((__m256i*)to, _mm256_loadu_si256((const __m256i*)from)); 79 | _mm256_stream_si256(((__m256i*)to) + 1, _mm256_loadu_si256(((const __m256i*)from) +1)); 80 | __asm__("clflushopt (%0)" 81 | : 82 | : "r"(from - 64) 83 | : 84 | ); 85 | size-=64; 86 | from += 64; 87 | to+=64; 88 | } 89 | 90 | #pragma clang loop vectorize(disable) 91 | #pragma clang loop unroll(disable) 92 | while(size) { 93 | *to = *from; 94 | ++to; 95 | ++from; 96 | --size; 97 | } 98 | } 99 | IMPL_CODE_SEG 100 | static 101 | void cs_movemem_clean_nt(void* _to, const void* _from, size_t size) { 102 | 103 | char* to = (char*)_to; 104 | const char* from = (const char*)_from; 105 | #pragma clang loop vectorize(disable) 106 | #pragma clang loop unroll(disable) 107 | while((reinterpret_cast(to)&31) && size != 0) { 108 | *to = *from; 109 | --size; 110 | ++to; 111 | ++from; 112 | } 113 | 114 | 115 | 116 | while(size >= 64) { 117 | _mm256_stream_si256((__m256i*)to, _mm256_loadu_si256((const __m256i*)from)); 118 | _mm256_stream_si256(((__m256i*)to) + 1, _mm256_loadu_si256(((const __m256i*)from) +1)); 119 | __asm__("clwb (%0)" 120 | : 121 | : "r"(from - 64) 122 | : 123 | ); 124 | size-=64; 125 | from += 64; 126 | to+=64; 127 | } 128 | #pragma clang loop vectorize(disable) 129 | #pragma clang loop unroll(disable) 130 | while(size) { 131 | *to = *from; 132 | ++to; 133 | ++from; 134 | --size; 135 | } 136 | } 137 | IMPL_CODE_SEG 138 | static 139 | void cs_movemem_flush_noopt_nt(void* _to, const void* _from, size_t size) { 140 | 141 | char* to = (char*)_to; 142 | const char* from = (const char*)_from; 143 | #pragma clang loop vectorize(disable) 144 | #pragma clang loop unroll(disable) 145 | while((reinterpret_cast(to)&31) && size != 0) { 146 | *to = *from; 147 | --size; 148 | ++to; 149 | ++from; 150 | } 151 | 152 | 153 | 154 | 155 | while(size >= 64) { 156 | _mm256_stream_si256((__m256i*)to, _mm256_loadu_si256((const __m256i*)from)); 157 | _mm256_stream_si256(((__m256i*)to) + 1, _mm256_loadu_si256(((const __m256i*)from) +1)); 158 | _mm_clflush(from - 64); 159 | size-=64; 160 | from += 64; 161 | to+=64; 162 | } 163 | 164 | #pragma clang loop vectorize(disable) 165 | #pragma clang loop unroll(disable) 166 | while(size) { 167 | *to = *from; 168 | ++to; 169 | ++from; 170 | --size; 171 | } 172 | } -------------------------------------------------------------------------------- /snaphak_algo/impls/avx512/memops_avx512.hpp: -------------------------------------------------------------------------------- 1 | IMPL_CODE_SEG 2 | static 3 | void cs_zeromem_nt(void* _to, size_t size) { 4 | 5 | char* to = (char*)_to; 6 | #pragma clang loop vectorize(disable) 7 | #pragma clang loop unroll(disable) 8 | while((reinterpret_cast(to)&63) && size != 0) { 9 | *to = 0; 10 | --size; 11 | ++to; 12 | } 13 | 14 | while(size >= 64) { 15 | _mm512_stream_si512((__m512i*)to, _mm512_setzero_si512()); 16 | size-=64; 17 | to+=64; 18 | } 19 | 20 | #pragma clang loop vectorize(disable) 21 | #pragma clang loop unroll(disable) 22 | while(size) { 23 | *to = 0; 24 | ++to; 25 | --size; 26 | } 27 | } 28 | IMPL_CODE_SEG 29 | static 30 | void cs_movemem_nt(void* _to, const void* _from, size_t size) { 31 | 32 | char* to = (char*)_to; 33 | const char* from = (const char*)_from; 34 | #pragma clang loop vectorize(disable) 35 | #pragma clang loop unroll(disable) 36 | while((reinterpret_cast(to)&63) && size != 0) { 37 | *to = *from; 38 | --size; 39 | ++to; 40 | ++from; 41 | } 42 | 43 | while(size >= 64) { 44 | _mm512_stream_si512((__m512i*)to, _mm512_loadu_si512((const __m512i*)from)); 45 | size-=64; 46 | from += 64; 47 | to+=64; 48 | } 49 | 50 | #pragma clang loop vectorize(disable) 51 | #pragma clang loop unroll(disable) 52 | while(size) { 53 | *to = *from; 54 | ++to; 55 | ++from; 56 | --size; 57 | } 58 | } 59 | IMPL_CODE_SEG 60 | static 61 | void cs_movemem_flush_opt_nt(void* _to, const void* _from, size_t size) { 62 | 63 | char* to = (char*)_to; 64 | const char* from = (const char*)_from; 65 | #pragma clang loop vectorize(disable) 66 | #pragma clang loop unroll(disable) 67 | while((reinterpret_cast(to)&63) && size != 0) { 68 | *to = *from; 69 | --size; 70 | ++to; 71 | ++from; 72 | } 73 | 74 | 75 | 76 | 77 | while(size >= 64) { 78 | _mm512_stream_si512((__m512i*)to, _mm512_loadu_si512((const __m512i*)from)); 79 | 80 | __asm__("clflushopt (%0)" 81 | : 82 | : "r"(from - 64) 83 | : 84 | ); 85 | size-=64; 86 | from += 64; 87 | to+=64; 88 | } 89 | 90 | #pragma clang loop vectorize(disable) 91 | #pragma clang loop unroll(disable) 92 | while(size) { 93 | *to = *from; 94 | ++to; 95 | ++from; 96 | --size; 97 | } 98 | } 99 | IMPL_CODE_SEG 100 | static 101 | void cs_movemem_clean_nt(void* _to, const void* _from, size_t size) { 102 | 103 | char* to = (char*)_to; 104 | const char* from = (const char*)_from; 105 | #pragma clang loop vectorize(disable) 106 | #pragma clang loop unroll(disable) 107 | while((reinterpret_cast(to)&63) && size != 0) { 108 | *to = *from; 109 | --size; 110 | ++to; 111 | ++from; 112 | } 113 | 114 | 115 | 116 | while(size >= 64) { 117 | _mm512_stream_si512((__m512i*)to, _mm512_loadu_si512((const __m512i*)from)); 118 | 119 | __asm__("clwb (%0)" 120 | : 121 | : "r"(from - 64) 122 | : 123 | ); 124 | size-=64; 125 | from += 64; 126 | to+=64; 127 | } 128 | #pragma clang loop vectorize(disable) 129 | #pragma clang loop unroll(disable) 130 | while(size) { 131 | *to = *from; 132 | ++to; 133 | ++from; 134 | --size; 135 | } 136 | } 137 | IMPL_CODE_SEG 138 | static 139 | void cs_movemem_flush_noopt_nt(void* _to, const void* _from, size_t size) { 140 | 141 | char* to = (char*)_to; 142 | const char* from = (const char*)_from; 143 | #pragma clang loop unroll(disable) vectorize(disable) 144 | while((reinterpret_cast(to)&63) && size != 0) { 145 | *to = *from; 146 | --size; 147 | ++to; 148 | ++from; 149 | } 150 | 151 | 152 | 153 | 154 | while(size >= 64) { 155 | _mm512_stream_si512((__m512i*)to, _mm512_loadu_si512((const __m512i*)from)); 156 | 157 | _mm_clflush(from - 64); 158 | size-=64; 159 | from += 64; 160 | to+=64; 161 | } 162 | 163 | #pragma clang loop vectorize(disable) 164 | #pragma clang loop unroll(disable) 165 | while(size) { 166 | *to = *from; 167 | ++to; 168 | ++from; 169 | --size; 170 | } 171 | } -------------------------------------------------------------------------------- /snaphak_algo/impls/include_impls.hpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "rb_impl.hpp" 4 | #include "bmp_impl.hpp" 5 | #include "str_impl.hpp" 6 | #include "memop_impl.hpp" 7 | #include "sortnsearch_impl.hpp" 8 | #include "bulkint_impl.hpp" 9 | extern void heapalgos_init(snaphak_heaproutines_t* routines); 10 | extern void vmemalgos_init(snaphak_virtmemroutines_t* routines); 11 | extern void coroalgos_init(snaphak_cororoutines_t* routines); 12 | extern void smtalgos_init(snaphak_algo_t* algo); 13 | extern void realnum_init(snaphak_realroutines_t* algo); 14 | extern void netroutines_init(snaphak_netroutines_t* net); 15 | #ifndef SHALGO_DISABLE_INTBULK 16 | #define INIT_IBULK(algos) ibulkalgos_init(&algos->m_ibulkroutines) 17 | #else 18 | #define INIT_IBULK(algos) 19 | #endif 20 | 21 | #ifndef SHALGO_DISABLE_BITMAP 22 | #define INIT_BMP_ROUTINES(algos) bmp_algos_init(&algos->m_bmproutines); 23 | #else 24 | #define INIT_BMP_ROUTINES(algos) 25 | #endif 26 | 27 | #define __INIT__IMPLS(suffix) \ 28 | CS_NOINLINE \ 29 | CS_COLD_CODE \ 30 | void init_impls_##suffix (snaphak_algo_t* algos) {\ 31 | rb_algos_init(&algos->m_rbroutines);\ 32 | heapalgos_init(&algos->m_heaproutines);\ 33 | INIT_BMP_ROUTINES(algos);\ 34 | memop_algos_init(algos);\ 35 | vmemalgos_init(&algos->m_vmemroutines);\ 36 | coroalgos_init(&algos->m_cororoutines);\ 37 | str_algos_init(&algos->m_sroutines);\ 38 | smtalgos_init(algos);\ 39 | snsalgos_init(&algos->m_snsroutines);\ 40 | INIT_IBULK(algos);\ 41 | realnum_init(&algos->m_realroutines);\ 42 | netroutines_init(&algos->m_netroutines);\ 43 | } -------------------------------------------------------------------------------- /snaphak_algo/impls/init_impls_avx2.cpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "snaphakalgo_predef.hpp" 4 | #include "snaphakalgo.hpp" 5 | 6 | #ifndef SHALGO_ONE_SEGMENT 7 | #define IMPL_CODE_SEG CS_CODE_SEG(".avx2_path") 8 | #else 9 | #define IMPL_CODE_SEG 10 | #endif 11 | 12 | #define IMPL_VECTOR_WIDTH 32 13 | #include "include_impls.hpp" 14 | 15 | 16 | __INIT__IMPLS(avx2) 17 | -------------------------------------------------------------------------------- /snaphak_algo/impls/init_impls_avx512.cpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "snaphakalgo_predef.hpp" 4 | #include "snaphakalgo.hpp" 5 | 6 | 7 | #ifndef SHALGO_ONE_SEGMENT 8 | #define IMPL_CODE_SEG CS_CODE_SEG(".avx512_path") 9 | #else 10 | #define IMPL_CODE_SEG 11 | #endif 12 | 13 | 14 | #define IMPL_VECTOR_WIDTH 64 15 | #include "include_impls.hpp" 16 | 17 | 18 | __INIT__IMPLS(avx512) 19 | -------------------------------------------------------------------------------- /snaphak_algo/impls/init_impls_generic.cpp: -------------------------------------------------------------------------------- 1 | #include "snaphakalgo_predef.hpp" 2 | #include "snaphakalgo.hpp" 3 | 4 | #ifndef SHALGO_ONE_SEGMENT 5 | #define IMPL_CODE_SEG CS_CODE_SEG(".generic_path") 6 | #else 7 | #define IMPL_CODE_SEG 8 | #endif 9 | 10 | 11 | #define IMPL_VECTOR_WIDTH 16 12 | #include "include_impls.hpp" 13 | 14 | __INIT__IMPLS(generic) -------------------------------------------------------------------------------- /snaphak_algo/impls/memop_impl.hpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | #if defined(__AVX512F__) 4 | #include "avx512/memops_avx512.hpp" 5 | #elif defined(__AVX2__) 6 | #include "avx2/memops_avx2.hpp" 7 | #else 8 | #include "generic/memops_generic.hpp" 9 | #endif 10 | 11 | __attribute__((target("clflushopt"))) 12 | static 13 | bool flushcache(const void* mem, size_t size) { 14 | 15 | const char* memmem = (const char*)mem; 16 | 17 | uintptr_t delt = (64 - (reinterpret_cast(memmem) & 0x63)) & 0x63; 18 | 19 | if(size < delt) 20 | return false; 21 | 22 | 23 | size -= delt; 24 | memmem += delt; 25 | 26 | 27 | if(size < 64) 28 | return false; 29 | 30 | 31 | while(size >= 64) { 32 | __asm__("clflushopt (%0)" 33 | : 34 | : "r"(memmem) 35 | : 36 | ); 37 | size -= 64; 38 | memmem += 64; 39 | } 40 | return true; 41 | 42 | 43 | } 44 | static 45 | bool flushcache_noopt(const void* mem, size_t size) { 46 | 47 | const char* memmem = (const char*)mem; 48 | 49 | /*while(!!(reinterpret_cast(memmem) & 0x63) && size) { 50 | ++memmem; 51 | --size; 52 | }*/ 53 | 54 | uintptr_t delt = (64 - (reinterpret_cast(memmem) & 0x63)) & 0x63; 55 | 56 | if(size < delt) 57 | return false; 58 | 59 | 60 | size -= delt; 61 | memmem += delt; 62 | 63 | 64 | 65 | if(size < 64) 66 | return false; 67 | 68 | 69 | while(size >= 64) { 70 | __asm__("clflush (%0)" 71 | : 72 | : "r"(memmem) 73 | : 74 | ); 75 | size -= 64; 76 | memmem += 64; 77 | } 78 | return false; 79 | 80 | 81 | } 82 | __attribute__((target("clflushopt"))) 83 | static 84 | bool writebackcache(const void* mem, size_t size) { 85 | 86 | const char* memmem = (const char*)mem; 87 | 88 | uintptr_t delt = (64 - (reinterpret_cast(memmem) & 0x63)) & 0x63; 89 | 90 | if(size < delt) 91 | return false; 92 | 93 | 94 | size -= delt; 95 | memmem += delt; 96 | 97 | 98 | if(size < 64) 99 | return false; 100 | 101 | 102 | while(size >= 64) { 103 | 104 | __asm__("clwb (%0)" 105 | : 106 | : "r"(memmem) 107 | : 108 | ); 109 | size -= 64; 110 | memmem += 64; 111 | } 112 | return true; 113 | 114 | 115 | } 116 | 117 | static 118 | void smolmemzero_fast_small_stosb(void* mem, size_t size){ 119 | // __stosb(mem, 0, size); 120 | __asm__("rep stosb" : : "D"(mem), "a"(0), "c"(size)); 121 | 122 | } 123 | static 124 | void smolmemzero_no_fast_small_stosb(void* mem, size_t size){ 125 | //__stosb(mem, 0, size); 126 | memset(mem, 0, size); 127 | } 128 | 129 | static void smolmemcpy_fast_small_movsb(void* mem, const void* from, size_t size) { 130 | __asm__("rep movsb" : : "D"(mem), "S"(from), "c"(size)); 131 | //__movsb(mem, from, size); 132 | } 133 | 134 | static void smolmemcpy_no_fast_small_movsb(void* mem, const void* from, size_t size) { 135 | memcpy(mem, from, size); 136 | } 137 | 138 | static 139 | bool writebackcache_unsupported(const void* mem, size_t size) { 140 | return false; 141 | } 142 | CS_COLD_CODE 143 | CS_NOINLINE 144 | static void memop_algos_init(snaphak_algo_t* out_m) { 145 | 146 | out_m->m_memroutines.m_ntzeromem = cs_zeromem_nt; 147 | out_m->m_memroutines.m_ntmovemem = cs_movemem_nt; 148 | 149 | if(out_m->m_has_clflushopt) { 150 | out_m->m_memroutines.m_flushcache = flushcache; 151 | out_m->m_memroutines.m_cleancache = writebackcache; 152 | out_m->m_memroutines.m_movemem_flush = cs_movemem_flush_opt_nt; 153 | out_m->m_memroutines.m_movemem_clean = cs_movemem_clean_nt; 154 | 155 | } 156 | else { 157 | out_m->m_memroutines.m_flushcache = flushcache_noopt; 158 | out_m->m_memroutines.m_cleancache = writebackcache_unsupported; 159 | out_m->m_memroutines.m_movemem_flush = cs_movemem_flush_noopt_nt; 160 | out_m->m_memroutines.m_movemem_clean = cs_movemem_nt; 161 | } 162 | 163 | if(out_m->m_has_fast_shortrep) { 164 | out_m->m_memroutines.m_smol_memzero = smolmemzero_fast_small_stosb; 165 | out_m->m_memroutines.m_smol_memcpy = smolmemcpy_fast_small_movsb; 166 | } 167 | else { 168 | out_m->m_memroutines.m_smol_memzero = smolmemzero_no_fast_small_stosb; 169 | out_m->m_memroutines.m_smol_memcpy = smolmemcpy_no_fast_small_movsb; 170 | } 171 | 172 | } -------------------------------------------------------------------------------- /snaphak_algo/memclasses.hpp: -------------------------------------------------------------------------------- 1 | DECLARE_MEMCLASS(CONSTRAINED,4) 2 | MEMSEP 3 | DECLARE_MEMCLASS(LIGHT, 8) 4 | MEMSEP 5 | DECLARE_MEMCLASS(AVERAGE, 16) 6 | MEMSEP 7 | DECLARE_MEMCLASS(WORKSTATION, 32) 8 | MEMSEP 9 | DECLARE_MEMCLASS(CHRISPY, 128) -------------------------------------------------------------------------------- /snaphak_algo/sh_heap_shared.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | enum { 3 | _heapflag_no_serialize = 1, 4 | }; -------------------------------------------------------------------------------- /snaphak_algo/snaphak_allocator.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct snaphak_allocator_procs_t { 4 | void* (*m_allocate)(void* ud, size_t size); 5 | void (*m_free)(void* ud, void* mem, size_t memsize); 6 | void* (*m_reallocate)(void* ud, void* mem, size_t newsize,size_t oldsize); 7 | void (*m_bulk_free)(void* ud, void** mems, size_t* sizes, size_t nentries); 8 | 9 | bool (*m_lock_access)(void* ud); 10 | bool (*m_unlock_access)(void* ud); 11 | }; 12 | 13 | 14 | struct snaphak_allocator_t { 15 | snaphak_allocator_procs_t* m_alprocs; 16 | void* m_ud; 17 | 18 | void* allocate(size_t size) { 19 | return m_alprocs->m_allocate(m_ud, size); 20 | 21 | } 22 | 23 | void free(void* mem, size_t memsize = 0) { 24 | m_alprocs->m_free(m_ud, mem, memsize); 25 | } 26 | void *reallocate(void* mem, size_t newsize,size_t oldsize = 0) { 27 | return m_alprocs->m_reallocate(m_ud, mem, newsize,oldsize); 28 | } 29 | void bulk_free(void** mems, size_t nentries, size_t* sizes = nullptr) { 30 | if(m_alprocs->m_bulk_free) { 31 | m_alprocs->m_bulk_free(m_ud, mems, sizes, nentries); 32 | 33 | } 34 | else { 35 | if(sizes) { 36 | for(unsigned i = 0; i < nentries; ++i) { 37 | m_alprocs->m_free(m_ud, mems[i], sizes[i]); 38 | } 39 | } 40 | else { 41 | for(unsigned i = 0; i < nentries; ++i) { 42 | m_alprocs->m_free(m_ud, mems[i], 0); 43 | } 44 | } 45 | } 46 | } 47 | bool lock() { 48 | if(m_alprocs->m_lock_access) 49 | return m_alprocs->m_lock_access(m_ud); 50 | else 51 | return true; 52 | } 53 | bool unlock() { 54 | if(m_alprocs->m_unlock_access) 55 | return m_alprocs->m_unlock_access(m_ud); 56 | else 57 | return true; 58 | } 59 | }; 60 | -------------------------------------------------------------------------------- /snaphak_algo/snaphak_bitmap.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | todo: _mm512_lzcnt_epi64 might be pretty handy (AVX512CD) 4 | */ 5 | 6 | struct snaphak_bmproutines_t { 7 | bool (*m_bitmap_bits_are_set)(unsigned* bits, unsigned nbits_allocated_for, unsigned startidx, unsigned length); 8 | bool (*m_bitmap_bits_are_clear)(unsigned* bits, unsigned nbits_allocated_for, unsigned startidx, unsigned length); 9 | void (*m_bitmap_clear_bits)(unsigned* bits, unsigned nbits_allocated_for, unsigned startidx, unsigned ntoclear); 10 | unsigned (*m_bitmap_find_n_clear_from)(unsigned* bits, unsigned nbits_allocated_for, unsigned ntofind, unsigned start); 11 | unsigned (*m_bitmap_find_n_clear_from_and_set)(unsigned* bits, unsigned nbits_allocated_for, unsigned ntofind, unsigned start); 12 | 13 | void (*m_bitmap_set_bits)(unsigned* bits, unsigned nbits_allocated_for, unsigned startidx, unsigned ntoset); 14 | unsigned (*m_bitmap_find_n_set_from)(unsigned* bits, unsigned nbits_allocated_for, unsigned ntofind, unsigned start); 15 | unsigned (*m_bitmap_find_n_set_from_and_clear)(unsigned* bits, unsigned nbits_allocated_for, unsigned ntofind, unsigned start); 16 | }; -------------------------------------------------------------------------------- /snaphak_algo/snaphak_coro.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | struct coro_t; 3 | 4 | /* 5 | when a coro is first called it receives 6 | 7 | userdata pointer - arg 1 8 | 9 | pointer to self coro - arg 2 10 | pointer to the coro we were called from - arg 3 11 | */ 12 | 13 | 14 | //RBX, RBP, RDI, RSI, RSP, R12, R13, R14, R15, and XMM6-15 15 | 16 | struct alignas(64) coro_base_t { 17 | __m128i xmms[10]; 18 | uintptr_t m_rbx; 19 | uintptr_t m_rbp; 20 | uintptr_t m_rdi; 21 | uintptr_t m_rsi; 22 | uintptr_t m_rsp; 23 | uintptr_t m_r12; 24 | uintptr_t m_r13; 25 | uintptr_t m_r14; 26 | uintptr_t m_r15; 27 | uintptr_t m_back_rip; 28 | uintptr_t m_rax; //return value 29 | uintptr_t m_rcx; //passes params 30 | 31 | template 32 | void coro_set_up_calling_context(TStack* stackptr, TFunc* fn, TArg arg) { 33 | m_rsp = (uintptr_t)stackptr; 34 | m_back_rip = (uintptr_t)(void*)fn; 35 | m_rcx = (uintptr_t)arg; 36 | } 37 | 38 | /*uintptr_t yield_to(coro_t* other) { 39 | return coroswitch(this, other); 40 | } 41 | template 42 | uintptr_t yield_to(coro_t* other, TYield valto) { 43 | static_assert(sizeof(TYield) == 8); 44 | other->m_rax = (uintptr_t)valto; 45 | return coroswitch(this, other); 46 | }*/ 47 | }; 48 | 49 | constexpr unsigned corosize = sizeof(coro_base_t); 50 | 51 | 52 | template 53 | using corofn_t = TRet (*)(TArg userdata, coro_base_t* self, coro_base_t* caller ); 54 | 55 | 56 | struct snaphak_cororoutines_t { 57 | /* 58 | when a coro is first called it receives 59 | 60 | userdata pointer - arg 1 61 | 62 | pointer to self coro - arg 2 63 | pointer to the coro we were called from - arg 3 64 | */ 65 | uintptr_t (*m_coroswitch)(coro_base_t* from, coro_base_t* to); 66 | }; -------------------------------------------------------------------------------- /snaphak_algo/snaphak_coros.asm: -------------------------------------------------------------------------------- 1 | _text SEGMENT 2 | 3 | 4 | PUBLIC coroswitch 5 | 6 | sto_gp_coro macro TO, N, REGVAL 7 | mov [TO+(N*8)+160], REGVAL 8 | endm 9 | 10 | ld_gp_coro macro FROM, N, REGTO 11 | mov REGTO,[FROM+(N*8)+160] 12 | endm 13 | 14 | coroswitch PROC 15 | 16 | ;rcx = coro we're switching from 17 | ;rdx = coro we're switching to 18 | pop r8 19 | ;r8 contains the return address for our current coro, we need to save it 20 | ;so when our state is restored we execute at the point we switched from 21 | 22 | ;RBX, RBP, RDI, RSI, RSP, R12, R13, R14, R15, and XMM6-15 23 | 24 | movaps [rcx], xmm6 25 | movaps [rcx+16], xmm7 26 | movaps [rcx+32], xmm8 27 | movaps [rcx+48], xmm9 28 | movaps [rcx+64], xmm10 29 | movaps [rcx+80], xmm11 30 | movaps [rcx+96], xmm12 31 | movaps [rcx+112], xmm13 32 | movaps [rcx+128], xmm14 33 | movaps [rcx+144], xmm15 34 | 35 | sto_gp_coro rcx, 0, rbx 36 | sto_gp_coro rcx, 1, rbp 37 | 38 | sto_gp_coro rcx, 2, rdi 39 | sto_gp_coro rcx, 3, rsi 40 | sto_gp_coro rcx, 4, rsp 41 | sto_gp_coro rcx, 5, r12 42 | sto_gp_coro rcx, 6, r13 43 | sto_gp_coro rcx, 7, r14 44 | sto_gp_coro rcx, 8, r15 45 | sto_gp_coro rcx, 9, r8 46 | 47 | movaps xmm6, [rdx] 48 | movaps xmm7, [rdx+16] 49 | movaps xmm8, [rdx+32] 50 | mov r8, rcx 51 | movaps xmm9, [rdx+48] 52 | movaps xmm10, [rdx+64] 53 | 54 | movaps xmm11, [rdx+80] 55 | movaps xmm12, [rdx+96] 56 | movaps xmm13, [rdx+112] 57 | 58 | movaps xmm14, [rdx+128] 59 | movaps xmm15, [rdx+144] 60 | 61 | 62 | ld_gp_coro rdx, 0, rbx 63 | ld_gp_coro rdx, 1, rbp 64 | 65 | ld_gp_coro rdx, 2, rdi 66 | ld_gp_coro rdx, 3, rsi 67 | ld_gp_coro rdx, 4, rsp 68 | ld_gp_coro rdx, 5, r12 69 | ld_gp_coro rdx, 6, r13 70 | ld_gp_coro rdx, 7, r14 71 | ld_gp_coro rdx, 8, r15 72 | ld_gp_coro rdx, 9, r9 73 | push r9 74 | ld_gp_coro rdx, 10, rax 75 | ld_gp_coro rdx, 11, rcx 76 | ret 77 | 78 | 79 | coroswitch endp 80 | 81 | _text ENDS 82 | 83 | END -------------------------------------------------------------------------------- /snaphak_algo/snaphak_fmath.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | routines for using 80-bit floating point 4 | */ 5 | struct sh_real_t { 6 | char m_bytes[10]; 7 | }; 8 | 9 | struct snaphak_realroutines_t { 10 | sh_real_t (*m_add_real)(sh_real_t x, sh_real_t y); 11 | sh_real_t (*m_sub_real)(sh_real_t x, sh_real_t y); 12 | sh_real_t (*m_mul_real)(sh_real_t x, sh_real_t y); 13 | sh_real_t (*m_div_real)(sh_real_t x, sh_real_t y); 14 | sh_real_t (*m_sqrt_real)(sh_real_t x); 15 | sh_real_t (*m_neg_real)(sh_real_t x); 16 | sh_real_t (*m_real_from_double)(double input); 17 | double (*m_double_from_real)(sh_real_t x); 18 | float (*m_float_from_real)(sh_real_t x); 19 | 20 | sh_real_t (*m_floor)(sh_real_t x); 21 | 22 | sh_real_t (*m_real_from_i16)(int16_t ival); 23 | sh_real_t (*m_real_from_i32)(int32_t ival); 24 | sh_real_t (*m_real_from_i64)(int64_t ival); 25 | 26 | void (*m_sincos)(sh_real_t value, sh_real_t* out_sin, sh_real_t* out_cos); 27 | sh_real_t (*m_atan2)(sh_real_t iny, sh_real_t inx); 28 | }; -------------------------------------------------------------------------------- /snaphak_algo/snaphak_heap.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | typedef struct { 3 | 4 | }* sh_heap_t; 5 | 6 | 7 | #if defined(SNAPHAKALGO_BUILDING) 8 | namespace sh::heap { 9 | #include "sh_heap_shared.hpp" 10 | } 11 | #endif 12 | 13 | struct snaphak_heaproutines_t { 14 | sh_heap_t (*m_create_heap_from_mem)(void* mem, size_t memsize, unsigned heapflags); 15 | void (*m_destroy_heap)(sh_heap_t heap); 16 | 17 | void* (*m_alloc_from_heap)(sh_heap_t heap, size_t nbytes, unsigned heapflags); 18 | void (*m_free_from_heap)(sh_heap_t heap, void* mem, unsigned heapflags); 19 | 20 | void* (*m_realloc_from_heap)(sh_heap_t heap, void* oldmem, size_t nbytes_new, unsigned heapflags); 21 | bool (*m_lock_heap)(sh_heap_t heap); 22 | bool (*m_unlock_heap)(sh_heap_t heap); 23 | 24 | }; 25 | -------------------------------------------------------------------------------- /snaphak_algo/snaphak_intbulk.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | using snaphak_simdintegral_t = __m128i; 4 | 5 | struct snaphak_ibulkroutines_t { 6 | 7 | unsigned (*m_find_first_equal32)(unsigned* values, unsigned nvalues, unsigned tofind); 8 | unsigned (*m_find_first_equal16)(unsigned short* values, unsigned nvalues, unsigned tofind); 9 | unsigned (*m_find_first_notequal32)(unsigned* values, unsigned nvalues, unsigned tofind); 10 | void (*m_addscalar_32)(unsigned * values, unsigned nvalues, unsigned addend); 11 | void (*m_subscalar_32)(unsigned * values, unsigned nvalues, unsigned addend); 12 | void (*m_mulscalar_32)(unsigned * values, unsigned nvalues, unsigned mult); 13 | //finds first index of findval in values 14 | //warning: assumes values are unique. only intended for use in search variable hashes for idtypeinfo 15 | unsigned (*m_indexof_u64)(unsigned long long* values, unsigned long long findval); 16 | 17 | }; 18 | -------------------------------------------------------------------------------- /snaphak_algo/snaphak_memops.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | enum class memcpy_strategy_e { 4 | STANDARD_MEMCPY = 0, 5 | NT_COPY = 1, 6 | NT_COPY_FLUSH = 2, 7 | NT_COPY_CLEAN = 3, 8 | SMOL_CPY = 4 9 | }; 10 | 11 | 12 | struct generalized_ifield_t { 13 | struct { 14 | uint32_t m_offset : 24; 15 | uint32_t m_dtype : 2; //0 = uint8, 1 = uint16, 2 = uint32, 3 = uint64 16 | uint32_t m_signed_type : 1; 17 | }; 18 | }; 19 | struct snaphak_memroutines_t { 20 | //does not fence 21 | void (*m_ntmovemem)(void* to, const void* from, size_t size); 22 | 23 | void (*m_movemem_flush)(void* to, const void* from, size_t size); 24 | void (*m_movemem_clean)(void* to, const void* from, size_t size); 25 | //does not fence 26 | void (*m_ntzeromem)(void* to, size_t size); 27 | //returns true if sfence needed 28 | bool (*m_flushcache)(const void* mem, size_t size); 29 | //clean a region from the cache (keep it in cache but no longer dirty, so when evicted does not need to be written back) 30 | bool (*m_cleancache)(const void* mem, size_t size); 31 | 32 | void (*m_smol_memzero)( void* mem, size_t size); 33 | void (*m_smol_memcpy)(void* to, const void* from, size_t size); 34 | 35 | 36 | }; 37 | 38 | 39 | -------------------------------------------------------------------------------- /snaphak_algo/snaphak_networking.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | typedef struct { 3 | 4 | }*snaphak_socket_t; 5 | 6 | struct snaphak_netroutines_t { 7 | snaphak_socket_t (*m_connect_tcp)(const char* ipaddr, uint16_t portnum); 8 | bool (*m_try_send)(snaphak_socket_t sock, const void* data, size_t datasize); 9 | 10 | size_t (*m_try_recv)(snaphak_socket_t sock, void* buffer, size_t buffersize); 11 | 12 | }; -------------------------------------------------------------------------------- /snaphak_algo/snaphak_rbtree.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * ============================================================================= 4 | * 5 | * Filename: rbtree.h 6 | * 7 | * Description: rbtree(Red-Black tree) implementation adapted from linux 8 | * kernel thus can be used in userspace c program. 9 | * 10 | * Created: 09/02/2012 11:36:11 PM 11 | * 12 | * Author: Fu Haiping (forhappy), haipingf@gmail.com 13 | * Company: ICT ( Institute Of Computing Technology, CAS ) 14 | * 15 | * ============================================================================= 16 | */ 17 | #if defined(container_of) 18 | #undef container_of 19 | #define container_of(ptr, type, member) ({ \ 20 | const typeof( ((type *)0)->member ) *__mptr = (ptr); \ 21 | (type *)( (char *)__mptr - offsetof(type,member) );}) 22 | #else 23 | #define container_of(ptr, type, member) ({ \ 24 | const typeof( ((type *)0)->member ) *__mptr = (ptr); \ 25 | (type *)( (char *)__mptr - offsetof(type,member) );}) 26 | #endif 27 | 28 | #if defined(offsetof) 29 | #undef offsetof 30 | #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 31 | #else 32 | #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 33 | #endif 34 | 35 | #undef NULL 36 | #if defined(__cplusplus) 37 | #define NULL 0 38 | #else 39 | #define NULL ((void *)0) 40 | #endif 41 | 42 | struct rb_node 43 | { 44 | unsigned long long rb_parent_color; 45 | #define RB_RED 0 46 | #define RB_BLACK 1 47 | struct rb_node *rb_right; 48 | struct rb_node *rb_left; 49 | }; 50 | /* The alignment might seem pointless, but allegedly CRIS needs it */ 51 | 52 | struct rb_root 53 | { 54 | struct rb_node *rb_node; 55 | }; 56 | 57 | 58 | #define rb_parent(r) ((struct rb_node *)((r)->rb_parent_color & ~1ULL)) 59 | #define rb_color(r) ((r)->rb_parent_color & 1ULL) 60 | #define rb_is_red(r) (!rb_color(r)) 61 | #define rb_is_black(r) rb_color(r) 62 | #define rb_set_red(r) do { (r)->rb_parent_color &= ~1ULL; } while (0) 63 | #define rb_set_black(r) do { (r)->rb_parent_color |= 1ULL; } while (0) 64 | 65 | static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p) 66 | { 67 | rb->rb_parent_color = (rb->rb_parent_color & 1ULL) | (unsigned long long)p; 68 | } 69 | static inline void rb_set_color(struct rb_node *rb, int color) 70 | { 71 | rb->rb_parent_color = (rb->rb_parent_color & ~1ULL) | color; 72 | } 73 | 74 | #define RB_ROOT (struct rb_root) { NULL, } 75 | #define rb_entry(ptr, type, member) container_of(ptr, type, member) 76 | 77 | #define RB_EMPTY_ROOT(root) ((root)->rb_node == NULL) 78 | #define RB_EMPTY_NODE(node) (rb_parent(node) == node) 79 | #define RB_CLEAR_NODE(node) (rb_set_parent(node, node)) 80 | 81 | static inline void rb_init_node(struct rb_node *rb) 82 | { 83 | rb->rb_parent_color = 0; 84 | rb->rb_right = NULL; 85 | rb->rb_left = NULL; 86 | RB_CLEAR_NODE(rb); 87 | } 88 | 89 | static inline void rb_link_node(struct rb_node * node, struct rb_node * parent, 90 | struct rb_node ** rb_link) 91 | { 92 | node->rb_parent_color = (unsigned long long )parent; 93 | node->rb_left = node->rb_right = NULL; 94 | 95 | *rb_link = node; 96 | } 97 | 98 | #if 0 99 | extern void rb_insert_color(struct rb_node *, struct rb_root *); 100 | extern void rb_erase(struct rb_node *, struct rb_root *); 101 | 102 | typedef void (*rb_augment_f)(struct rb_node *node, void *data); 103 | 104 | extern void rb_augment_insert(struct rb_node *node, 105 | rb_augment_f func, void *data); 106 | extern struct rb_node *rb_augment_erase_begin(struct rb_node *node); 107 | extern void rb_augment_erase_end(struct rb_node *node, 108 | rb_augment_f func, void *data); 109 | 110 | /* Find logical next and previous nodes in a tree */ 111 | extern struct rb_node *rb_next(const struct rb_node *); 112 | extern struct rb_node *rb_prev(const struct rb_node *); 113 | extern struct rb_node *rb_first(const struct rb_root *); 114 | extern struct rb_node *rb_last(const struct rb_root *); 115 | 116 | /* Fast replacement of a single node without remove/rebalance/add/rebalance */ 117 | extern void rb_replace_node(struct rb_node *victim, struct rb_node *new, 118 | struct rb_root *root); 119 | #endif 120 | 121 | struct snaphak_rbroutines_t { 122 | rb_node* (*m_rb_next)(const struct rb_node*); 123 | rb_node* (*m_rb_prev)(const struct rb_node*); 124 | rb_node* (*m_rb_first)(const struct rb_root*); 125 | rb_node* (*m_rb_last)(const struct rb_root*); 126 | void (*m_rb_insert_color)(struct rb_node *, struct rb_root *); 127 | void (*m_rb_erase)(struct rb_node *, struct rb_root *); 128 | }; 129 | -------------------------------------------------------------------------------- /snaphak_algo/snaphak_smt.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | using sh_thrdproc_t = int (*)(void*); 4 | typedef struct {}*snaphak_signal_t; 5 | 6 | static constexpr int64_t* snaphak_ms_to_timeout(int timeout, int64_t* scratch) { 7 | if(!scratch) { 8 | return nullptr; 9 | } 10 | *scratch = static_cast(timeout) * -10000i64; 11 | return scratch; 12 | } 13 | 14 | #define SNAPHAK_FOREVER (nullptr) 15 | 16 | struct snaphak_smtroutines_t { 17 | bool (*m_cmpxchg16b)(volatile uint64_t* destination, uint64_t xhigh, uint64_t xlow, uint64_t* cmpres); 18 | int (*m_xadd32)(volatile int* value, int addend); 19 | int64_t (*m_xadd64)(volatile int64_t* value, int64_t addend); 20 | 21 | bool (*m_bts64)(volatile uint64_t* m_ptr, unsigned m_bitidx); 22 | bool (*m_btr64)(volatile uint64_t* m_ptr, unsigned m_bitidx); 23 | bool (*m_btc64)(volatile uint64_t* m_ptr, unsigned m_bitidx); 24 | uintptr_t (*m_create_thread)(sh_thrdproc_t function, void* parms, unsigned procnum, size_t stackSize, bool suspended, int* out_threadid); 25 | 26 | void (*m_yield_thread)(); 27 | void (*m_sleep_thread)(size_t ms); 28 | 29 | 30 | snaphak_signal_t (*m_create_signal)(); 31 | void (*m_destroy_signal)(snaphak_signal_t); 32 | void (*m_signal_raise)(snaphak_signal_t sig); 33 | bool (*m_signal_wait)(snaphak_signal_t sig, int64_t* timeout); 34 | bool (*m_signal_raise_and_wait)(snaphak_signal_t raise, snaphak_signal_t wait, int64_t* timeout); 35 | }; -------------------------------------------------------------------------------- /snaphak_algo/snaphak_sortnsearch.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct snaphak_snsroutines_t { 4 | void (*m_sort4ptr)(void** ptrs); 5 | //void (*m_sort16ptr_with_scratch)(void** ptrs, void** scratchbuf); 6 | void (*m_sort16ptr_unrolled)(void** ptrs); 7 | void (*m_sort16ptr)(void* ptrs[8]); 8 | }; -------------------------------------------------------------------------------- /snaphak_algo/snaphak_string.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | struct snaphak_sroutines_t { 5 | bool (*m_streq)(const char* s1, const char* s2); 6 | bool (*m_strieq)(const char* s1, const char* s2); 7 | unsigned (*m_strlen)(const char* s1); 8 | unsigned (*m_asm_strlen)(const char* s1); 9 | unsigned (*m_hashfnv32)(const char* s1, unsigned length); 10 | 11 | 12 | int (*m_str_to_long)(const char* str, const char** out_endptr, unsigned base); 13 | 14 | int (*m_atoi_fast)(const char* str); 15 | unsigned (*m_int2str_base10)(unsigned int val, char* dstbuf, unsigned size); 16 | unsigned(*m_int2str_base16)(unsigned int val, char* dstbuf, unsigned size); 17 | unsigned (*m_uint2str_base10)(unsigned int val, char* dstbuf, unsigned size); 18 | 19 | //precision default=4 20 | unsigned (*m_float2str_fast)(float fvalue, char* dstbuf, unsigned precision); 21 | //out_endpos default = nullptr 22 | double (*m_fast_atof)(const char* p, const char** out_endpos); 23 | 24 | int (*m_strcmp)(const char* s1, const char* s2); 25 | 26 | const char* (*m_strstr)(const char* s, const char* fnd); 27 | const char* (*m_strchr)(const char* s, char fnd); 28 | 29 | unsigned (*m_strcspn)(const char* s, const char* spanner); 30 | size_t (*m_strspn)(const char* s, const char* s2); 31 | 32 | char* (*m_strtok_r)(char* str, const char* delim, char** saveptr); 33 | 34 | //returns destbuf end position 35 | char* (*m_strcpy)(char* destbuf, const char* srcbuf); 36 | 37 | unsigned (*m_to_unicode)(wchar_t* dstbuf, const char* inbuf); 38 | unsigned (*m_from_unicode)(char* dstbuf, const wchar_t* inbuf); 39 | unsigned (*m_find_str_insens)(const char* haystack, const char* needle); 40 | }; -------------------------------------------------------------------------------- /snaphak_algo/snaphak_vmemops.hpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | struct snaphak_virtmemroutines_t { 4 | void* (*m_allocate_rw)(size_t size); 5 | void* (*m_allocate_rwx_absolute)(size_t size,void* where); 6 | void* (*m_allocate_rw_absolute)(size_t size,void* where); 7 | void (*m_release_rw)(void* mem); 8 | void (*m_discard_contents)(void* mem, size_t size); 9 | void (*m_prefetch_for_seq_access)(void* mem, size_t size); 10 | //for engine instrumentation purposes only, we dont need hugepages for normal user releases that dont collect info on the engine 11 | int (*m_try_enable_hugepages)(); 12 | }; -------------------------------------------------------------------------------- /snaphak_algo/snaphakalgo_coro.cpp: -------------------------------------------------------------------------------- 1 | #include "snaphakalgo_predef.hpp" 2 | #include "snaphakalgo.hpp" 3 | extern "C" 4 | uintptr_t coroswitch(coro_base_t* from, coro_base_t* to); 5 | 6 | void coroalgos_init(snaphak_cororoutines_t* routines) { 7 | routines->m_coroswitch = coroswitch; 8 | } -------------------------------------------------------------------------------- /snaphak_algo/snaphakalgo_heap.cpp: -------------------------------------------------------------------------------- 1 | #include "snaphakalgo_predef.hpp" 2 | #include "snaphakalgo.hpp" 3 | #include 4 | 5 | static void* g_rtl_createheap = nullptr; 6 | 7 | 8 | static unsigned heapflags_to_winheap_flags(unsigned flags) { 9 | unsigned res_flags = 0; 10 | if(flags & sh::heap::_heapflag_no_serialize) { 11 | res_flags |= HEAP_NO_SERIALIZE; 12 | } 13 | return res_flags; 14 | } 15 | struct RTL_HEAP_PARAMETERS { 16 | ULONG Length; 17 | SIZE_T SegmentReserve; 18 | SIZE_T SegmentCommit; 19 | SIZE_T DeCommitFreeBlockThreshold; 20 | SIZE_T DeCommitTotalFreeThreshold; 21 | SIZE_T MaximumAllocationSize; 22 | SIZE_T VirtualMemoryThreshold; 23 | SIZE_T InitialCommit; 24 | SIZE_T InitialReserve; 25 | void* CommitRoutine; 26 | SIZE_T Reserved[2]; 27 | }; 28 | CS_COLD_CODE 29 | static 30 | sh_heap_t create_heap_from_mem(void* mem, size_t memsize, unsigned flags ) { 31 | 32 | RTL_HEAP_PARAMETERS params; 33 | memset(¶ms, 0, sizeof(params)); 34 | params.Length = sizeof(params); 35 | auto heapfn = reinterpret_cast(g_rtl_createheap); 43 | 44 | 45 | return reinterpret_cast(heapfn(heapflags_to_winheap_flags(flags), mem, memsize, memsize, nullptr, ¶ms)); 46 | } 47 | 48 | /* 49 | void (*m_destroy_heap)(sh_heap_t heap); 50 | 51 | void* (*m_alloc_from_heap)(sh_heap_t heap, size_t nbytes, unsigned heapflags); 52 | void (*m_free_from_heap)(sh_heap_t heap, void* mem, unsigned heapflags); 53 | 54 | void* (*m_realloc_from_heap)(sh_heap_t heap, void* oldmem, size_t nbytes_new, unsigned heapflags); 55 | */ 56 | 57 | CS_COLD_CODE 58 | static void destroy_heap(sh_heap_t heap) { 59 | HeapDestroy((HANDLE)heap); 60 | } 61 | SNAPHAK_SHARED_SEG 62 | static void* alloc_from_heap(sh_heap_t heap, size_t nbytes, unsigned heapflags) { 63 | return HeapAlloc((HANDLE)heap, heapflags_to_winheap_flags(heapflags), nbytes); 64 | } 65 | SNAPHAK_SHARED_SEG 66 | static void free_from_heap(sh_heap_t heap, void* mem, unsigned heapflags) { 67 | HeapFree((HANDLE)heap, heapflags_to_winheap_flags(heapflags), mem); 68 | } 69 | SNAPHAK_SHARED_SEG 70 | static void* realloc_from_heap(sh_heap_t heap, void* oldmem, size_t nbytes_new, unsigned heapflags) { 71 | return HeapReAlloc((HANDLE)heap, heapflags_to_winheap_flags(heapflags), oldmem, nbytes_new); 72 | } 73 | SNAPHAK_SHARED_SEG 74 | static 75 | bool _lock_heap(sh_heap_t heap){ 76 | return HeapLock((HANDLE)heap); 77 | } 78 | SNAPHAK_SHARED_SEG 79 | static 80 | bool unlock_heap(sh_heap_t heap){ 81 | return HeapUnlock((HANDLE)heap); 82 | } 83 | 84 | void heapalgos_init(snaphak_heaproutines_t* routines) { 85 | g_rtl_createheap = GetProcAddress(GetModuleHandleA("ntdll.dll"), "RtlCreateHeap"); 86 | 87 | routines->m_create_heap_from_mem = create_heap_from_mem; 88 | routines->m_destroy_heap = destroy_heap; 89 | routines->m_alloc_from_heap = alloc_from_heap; 90 | routines->m_free_from_heap = free_from_heap; 91 | routines->m_realloc_from_heap = realloc_from_heap; 92 | routines->m_lock_heap = _lock_heap; 93 | routines->m_unlock_heap = unlock_heap; 94 | 95 | 96 | } 97 | -------------------------------------------------------------------------------- /snaphak_algo/snaphakalgo_networking.cpp: -------------------------------------------------------------------------------- 1 | #include "snaphakalgo.hpp" 2 | #if 0 3 | #include 4 | #include 5 | #pragma comment(lib,"ws2_32.lib") //Winsock Library 6 | 7 | struct snaphak_socket_internal_t { 8 | const char* m_ipaddr; 9 | uint16_t m_port; 10 | int m_socket; 11 | }; 12 | 13 | static 14 | snaphak_socket_t cs_connect_tcp(const char* ipaddr, uint16_t portnum) { 15 | int sockres= socket(AF_INET , SOCK_STREAM , 0 ); 16 | if(sockres ==INVALID_SOCKET) { 17 | return nullptr; 18 | } 19 | else { 20 | snaphak_socket_internal_t* result = new snaphak_socket_internal_t(); 21 | 22 | result->m_ipaddr = _strdup(ipaddr); 23 | result->m_port=portnum; 24 | result->m_socket =sockres; 25 | return (snaphak_socket_t)result; 26 | } 27 | } 28 | static 29 | 30 | bool cs_try_send(snaphak_socket_t sock, const void* data, size_t datasize) { 31 | if(!sock) 32 | return false; 33 | if(!data) 34 | return false; 35 | if(!datasize) 36 | return true; 37 | if(send(reinterpret_cast(sock)->m_socket, (const char*)data, datasize, 0) < 0) 38 | return false; 39 | return true; 40 | } 41 | static 42 | 43 | size_t cs_try_recv(snaphak_socket_t sock, void* buffer, size_t buffersize) { 44 | if(!sock) 45 | return 0; 46 | if(!buffer) 47 | return 0; 48 | if(!buffersize) 49 | return 0; 50 | int recv_size = recv(reinterpret_cast(sock)->m_socket , (char*)buffer , buffersize , 0); 51 | if(recv_size==SOCKET_ERROR) 52 | return 0; 53 | return static_cast(recv_size); 54 | } 55 | 56 | static WSADATA g_wsa; 57 | #endif 58 | void netroutines_init(snaphak_netroutines_t* net) { 59 | #if 0 60 | net->m_connect_tcp = cs_connect_tcp; 61 | net->m_try_recv = cs_try_recv; 62 | net->m_try_send=cs_try_send; 63 | WSAStartup(MAKEWORD(2,2),&g_wsa); 64 | #else 65 | net->m_connect_tcp = nullptr; 66 | net->m_try_recv = nullptr; 67 | net->m_try_send=nullptr; 68 | #endif 69 | } 70 | -------------------------------------------------------------------------------- /snaphak_algo/snaphakalgo_predef.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define CS_NOINLINE __declspec(noinline) 4 | 5 | #define CS_FORCEINLINE __forceinline 6 | 7 | #define CS_RESTRICT 8 | #define CS_DATA_SEG(name) __declspec(allocate(name)) 9 | #define CS_CODE_SEG(name) __declspec(code_seg(name)) 10 | #define CS_COLD_CODE CS_CODE_SEG(".cold") 11 | #define CS_NORETURN __declspec(noreturn) 12 | #if defined(__clang__) 13 | 14 | #define cs_assume_m(...) if(!(__VA_ARGS__)) __builtin_unreachable() 15 | 16 | #else 17 | #define cs_assume_m(...) if(!(__VA_ARGS__)) __assume(false) 18 | #endif 19 | 20 | #define cs_offsetof_m(...) __builtin_offsetof(__VA_ARGS__) 21 | 22 | static unsigned long long pair2u32(unsigned low, unsigned high) { 23 | return static_cast(low) | (static_cast(high)<<32); 24 | } 25 | 26 | static void unpair2u32(unsigned long long paired, unsigned& lo, unsigned& hi) { 27 | lo = paired; 28 | hi = paired>>32; 29 | } 30 | 31 | #if defined(__clang__) 32 | 33 | #define MH_TRIVIAL_ABI __attribute__((trivial_abi)) 34 | 35 | #define MH_LEAF __attribute__((leaf)) 36 | 37 | #define MH_DISABLE_STATIC_DCTOR __attribute__((no_destroy)) 38 | 39 | #define MH_NOESCAPE __attribute__((noescape)) 40 | 41 | #else 42 | #define MH_TRIVIAL_ABI 43 | 44 | #define MH_LEAF 45 | 46 | #define MH_DISABLE_STATIC_DCTOR 47 | 48 | #define MH_NOESCAPE 49 | #endif 50 | #define MH_NOALIAS __declspec(noalias) 51 | 52 | #define MH_SMALLLOOP _Pragma("clang loop unroll(disable) vectorize(disable)") 53 | 54 | //#define SHALGO_DISABLE_INTBULK 55 | #define SHALGO_DISABLE_BITMAP 56 | #define SHALGO_ONE_SEGMENT 57 | 58 | //matches asm version 59 | struct low_gpregs_t { 60 | unsigned long long m_rax; 61 | unsigned long long m_rcx; 62 | unsigned long long m_rdx; 63 | unsigned long long m_rbx; 64 | unsigned long long m_rsi; 65 | unsigned long long m_rdi; 66 | unsigned long long m_rbp; 67 | }; 68 | 69 | -------------------------------------------------------------------------------- /snaphak_algo/snaphakalgo_real.cpp: -------------------------------------------------------------------------------- 1 | #include "snaphakalgo_predef.hpp" 2 | #include "snaphakalgo.hpp" 3 | 4 | //putting these in a seperate seg is wasteful 5 | //#define REALSEG CS_CODE_SEG(".realnum") 6 | #define REALSEG 7 | 8 | REALSEG 9 | static sh_real_t cs_realadd(sh_real_t x, sh_real_t y) { 10 | 11 | sh_real_t result; 12 | 13 | __asm { 14 | fld x 15 | fld y 16 | faddp st(1), st 17 | fstp result 18 | } 19 | return result; 20 | } 21 | 22 | REALSEG 23 | static sh_real_t cs_realsub(sh_real_t x, sh_real_t y) { 24 | 25 | sh_real_t result; 26 | 27 | __asm { 28 | fld x 29 | fld y 30 | fsubp st(1), st 31 | fstp result 32 | } 33 | return result; 34 | } 35 | REALSEG 36 | static sh_real_t cs_realmul(sh_real_t x, sh_real_t y) { 37 | 38 | sh_real_t result; 39 | 40 | __asm { 41 | fld x 42 | fld y 43 | fmulp st(1), st 44 | fstp result 45 | } 46 | return result; 47 | } 48 | 49 | REALSEG 50 | static sh_real_t cs_realdiv(sh_real_t x, sh_real_t y) { 51 | 52 | sh_real_t result; 53 | 54 | __asm { 55 | fld x 56 | fld y 57 | fdivp st(1), st 58 | fstp result 59 | } 60 | return result; 61 | } 62 | REALSEG 63 | static sh_real_t cs_realsqrt(sh_real_t x) { 64 | 65 | sh_real_t result; 66 | 67 | __asm { 68 | fld x 69 | fsqrt 70 | fstp result 71 | } 72 | return result; 73 | } 74 | 75 | REALSEG 76 | static sh_real_t cs_realneg(sh_real_t x) { 77 | 78 | sh_real_t result; 79 | 80 | __asm { 81 | fld x 82 | fchs 83 | fstp result 84 | } 85 | return result; 86 | } 87 | REALSEG 88 | static 89 | sh_real_t cs_real_from_double(double input) { 90 | double stackval = input; 91 | sh_real_t result; 92 | __asm { 93 | fld qword ptr stackval 94 | fstp tbyte ptr result 95 | } 96 | return result; 97 | } 98 | REALSEG 99 | static 100 | sh_real_t cs_real_from_i16(int16_t input) { 101 | int16_t stackval = input; 102 | sh_real_t result; 103 | __asm { 104 | fild word ptr stackval 105 | fstp tbyte ptr result 106 | } 107 | return result; 108 | } 109 | REALSEG 110 | static 111 | sh_real_t cs_real_from_i32(int32_t input) { 112 | int32_t stackval = input; 113 | sh_real_t result; 114 | __asm { 115 | fild dword ptr stackval 116 | fstp tbyte ptr result 117 | } 118 | return result; 119 | } 120 | REALSEG 121 | static 122 | sh_real_t cs_real_from_i64(int64_t input) { 123 | int64_t stackval = input; 124 | sh_real_t result; 125 | __asm { 126 | fild qword ptr stackval 127 | fstp tbyte ptr result 128 | } 129 | return result; 130 | } 131 | 132 | /* 133 | sh_real_t (*m_real_from_i16)(int64_t ival); 134 | sh_real_t (*m_real_from_i32)(int32_t ival); 135 | sh_real_t (*m_real_from_i64)(int64_t ival);*/ 136 | REALSEG 137 | static double cs_double_from_real(sh_real_t realnum) { 138 | double res; 139 | __asm { 140 | fld tbyte ptr realnum 141 | fstp qword ptr res 142 | } 143 | return res; 144 | } 145 | 146 | REALSEG 147 | static float cs_flt_from_real(sh_real_t realnum) { 148 | float res; 149 | __asm { 150 | fld tbyte ptr realnum 151 | fstp dword ptr res 152 | } 153 | return res; 154 | } 155 | 156 | REALSEG 157 | static void cs_realsincos(sh_real_t val, sh_real_t* out_sin, sh_real_t* out_cos) { 158 | __asm { 159 | fld tbyte ptr val 160 | fsincos 161 | mov rax, qword ptr[out_cos] 162 | 163 | fstp tbyte ptr [rax] 164 | mov rax, qword ptr[out_sin] 165 | fstp tbyte ptr [rax] 166 | 167 | 168 | } 169 | } 170 | 171 | 172 | REALSEG 173 | static 174 | sh_real_t cs_atan2 (sh_real_t iny, sh_real_t inx) { 175 | sh_real_t res; 176 | 177 | __asm { 178 | fld tbyte ptr [iny] 179 | fld tbyte ptr [inx] 180 | fpatan 181 | fstp tbyte ptr [res] 182 | 183 | } 184 | return res; 185 | } 186 | 187 | REALSEG 188 | static 189 | sh_real_t cs_floorl(sh_real_t v){ 190 | sh_real_t res; 191 | unsigned short tmpword; 192 | unsigned short tmpword2; 193 | __asm { 194 | fnstcw WORD PTR tmpword 195 | fld TBYTE PTR v 196 | movzx eax, WORD PTR tmpword 197 | and ah, -13 198 | or ah, 4 199 | mov WORD PTR tmpword2, ax 200 | fldcw WORD PTR tmpword2 201 | frndint 202 | fldcw WORD PTR tmpword 203 | fstp TBYTE PTR [res] 204 | } 205 | return res; 206 | } 207 | void realnum_init(snaphak_realroutines_t* algo) { 208 | algo->m_add_real = cs_realadd; 209 | algo->m_sub_real = cs_realsub; 210 | algo->m_mul_real = cs_realmul; 211 | algo->m_div_real = cs_realdiv; 212 | algo->m_sqrt_real = cs_realsqrt; 213 | algo->m_neg_real = cs_realneg; 214 | algo->m_real_from_double = cs_real_from_double; 215 | algo->m_double_from_real = cs_double_from_real; 216 | algo->m_float_from_real = cs_flt_from_real; 217 | algo->m_real_from_i16 = cs_real_from_i16; 218 | algo->m_real_from_i32 = cs_real_from_i32; 219 | algo->m_real_from_i64 = cs_real_from_i64; 220 | algo->m_sincos=cs_realsincos; 221 | algo->m_atan2 = cs_atan2; 222 | algo->m_floor = cs_floorl; 223 | } -------------------------------------------------------------------------------- /snaphak_algo/win_syscall_list.asm: -------------------------------------------------------------------------------- 1 | 2 | 3 | _text SEGMENT 4 | 5 | ALIGN 8 6 | doswi PROC 7 | mov r10, rcx 8 | syscall 9 | ret 10 | 11 | 12 | doswi endp 13 | ALIGN 16 14 | perform_syscall_impl PROC 15 | Counter = 0 16 | 17 | REPEAT 462 18 | ALIGN 16 19 | mov eax, Counter 20 | jmp doswi 21 | Counter = Counter + 1 22 | ENDM 23 | perform_syscall_impl endp 24 | 25 | _text ENDS 26 | END -------------------------------------------------------------------------------- /udis86test/config.h: -------------------------------------------------------------------------------- 1 | /* config.h. Generated from config.h.in by configure. */ 2 | /* config.h.in. Generated from configure.ac by autoheader. */ 3 | 4 | /* Define to 1 if you have the header file. */ 5 | #define HAVE_ASSERT_H 1 6 | 7 | /* Define to 1 if you have the header file. */ 8 | /* #undef HAVE_DLFCN_H */ 9 | 10 | /* Define to 1 if you have the header file. */ 11 | #define HAVE_INTTYPES_H 1 12 | 13 | /* Define to 1 if you have the header file. */ 14 | #define HAVE_MEMORY_H 1 15 | 16 | /* Define to 1 if you have the header file. */ 17 | #define HAVE_STDINT_H 1 18 | 19 | /* Define to 1 if you have the header file. */ 20 | #define HAVE_STDIO_H 1 21 | 22 | /* Define to 1 if you have the header file. */ 23 | #define HAVE_STDLIB_H 1 24 | 25 | /* Define to 1 if you have the header file. */ 26 | #define HAVE_STRINGS_H 1 27 | 28 | /* Define to 1 if you have the header file. */ 29 | #define HAVE_STRING_H 1 30 | 31 | /* Define to 1 if you have the header file. */ 32 | #define HAVE_SYS_STAT_H 1 33 | 34 | /* Define to 1 if you have the header file. */ 35 | #define HAVE_SYS_TYPES_H 1 36 | 37 | /* Define to 1 if you have the header file. */ 38 | #define HAVE_UNISTD_H 1 39 | 40 | /* Define to the sub-directory in which libtool stores uninstalled libraries. 41 | */ 42 | #define LT_OBJDIR ".libs/" 43 | 44 | /* Define to 1 if your C compiler doesn't accept -c and -o together. */ 45 | /* #undef NO_MINUS_C_MINUS_O */ 46 | 47 | /* Name of package */ 48 | #define PACKAGE "udis86" 49 | 50 | /* Define to the address where bug reports for this package should be sent. */ 51 | #define PACKAGE_BUGREPORT "vivek.mt@gmail.com" 52 | 53 | /* Define to the full name of this package. */ 54 | #define PACKAGE_NAME "udis86" 55 | 56 | /* Define to the full name and version of this package. */ 57 | #define PACKAGE_STRING "udis86 1.7.2" 58 | 59 | /* Define to the one symbol short name of this package. */ 60 | #define PACKAGE_TARNAME "udis86" 61 | 62 | /* Define to the home page for this package. */ 63 | #define PACKAGE_URL "" 64 | 65 | /* Define to the version of this package. */ 66 | #define PACKAGE_VERSION "1.7.2" 67 | 68 | /* Define to 1 if you have the ANSI C header files. */ 69 | #define STDC_HEADERS 1 70 | 71 | /* Version number of package */ 72 | #define VERSION "1.7.2" 73 | -------------------------------------------------------------------------------- /udis86test/extern.h: -------------------------------------------------------------------------------- 1 | /* udis86 - libudis86/extern.h 2 | * 3 | * Copyright (c) 2002-2009, 2013 Vivek Thampi 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #ifndef UD_EXTERN_H 27 | #define UD_EXTERN_H 28 | 29 | 30 | 31 | #include "types.h" 32 | #define UD_EXPORT extern 33 | 34 | 35 | /* ============================= PUBLIC API ================================= */ 36 | 37 | UD_EXPORT void ud_init(struct ud*); 38 | 39 | //UD_EXPORT void ud_set_mode(struct ud*, uint8_t); 40 | 41 | UD_EXPORT void ud_set_pc(struct ud*, uint64_t); 42 | 43 | UD_EXPORT void ud_set_input_hook(struct ud*, int (*)(struct ud*)); 44 | 45 | UD_EXPORT void ud_set_input_buffer(struct ud*, const uint8_t*, size_t); 46 | 47 | #ifndef __UD_STANDALONE__ 48 | UD_EXPORT void ud_set_input_file(struct ud*, FILE*); 49 | #endif /* __UD_STANDALONE__ */ 50 | 51 | UD_EXPORT void ud_set_vendor(struct ud*, unsigned); 52 | 53 | UD_EXPORT void ud_set_syntax(struct ud*, void (*)(struct ud*)); 54 | 55 | UD_EXPORT void ud_input_skip(struct ud*, size_t); 56 | 57 | UD_EXPORT int ud_input_end(const struct ud*); 58 | 59 | unsigned int ud_decode(struct ud*); 60 | 61 | UD_EXPORT unsigned int ud_disassemble(struct ud*); 62 | 63 | UD_EXPORT void ud_translate_intel(struct ud*); 64 | 65 | UD_EXPORT void ud_translate_att(struct ud*); 66 | 67 | UD_EXPORT const char* ud_insn_asm(const struct ud* u); 68 | 69 | UD_EXPORT const uint8_t* ud_insn_ptr(const struct ud* u); 70 | 71 | UD_EXPORT uint64_t ud_insn_off(const struct ud*); 72 | 73 | UD_EXPORT const char* ud_insn_hex(struct ud*); 74 | 75 | UD_EXPORT unsigned int ud_insn_len(const struct ud* u); 76 | 77 | UD_EXPORT const struct ud_operand* ud_insn_opr(const struct ud *u, unsigned int n); 78 | 79 | UD_EXPORT int ud_opr_is_sreg(const struct ud_operand *opr); 80 | 81 | UD_EXPORT int ud_opr_is_gpr(const struct ud_operand *opr); 82 | 83 | UD_EXPORT enum ud_mnemonic_code ud_insn_mnemonic(const struct ud *u); 84 | 85 | UD_EXPORT const char* ud_lookup_mnemonic(enum ud_mnemonic_code c); 86 | 87 | UD_EXPORT void ud_set_user_opaque_data(struct ud*, void*); 88 | 89 | UD_EXPORT void* ud_get_user_opaque_data(const struct ud*); 90 | 91 | UD_EXPORT uint64_t ud_insn_sext_imm(const struct ud*, const struct ud_operand*); 92 | 93 | UD_EXPORT void ud_set_asm_buffer(struct ud *u, char *buf, size_t size); 94 | 95 | UD_EXPORT void ud_set_sym_resolver(struct ud *u, 96 | const char* (*resolver)(struct ud*, 97 | uint64_t addr, 98 | int64_t *offset)); 99 | 100 | /* ========================================================================== */ 101 | 102 | 103 | #endif /* UD_EXTERN_H */ 104 | -------------------------------------------------------------------------------- /udis86test/syn.h: -------------------------------------------------------------------------------- 1 | /* udis86 - libudis86/syn.h 2 | * 3 | * Copyright (c) 2002-2009 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #ifndef UD_SYN_H 27 | #define UD_SYN_H 28 | 29 | #include "types.h" 30 | #ifndef __UD_STANDALONE__ 31 | # include 32 | #endif /* __UD_STANDALONE__ */ 33 | 34 | extern const char* ud_reg_tab[]; 35 | 36 | uint64_t ud_syn_rel_target(struct ud*, struct ud_operand*); 37 | 38 | #ifdef __GNUC__ 39 | int ud_asmprintf(struct ud *u, const char *fmt, ...) 40 | __attribute__ ((format (printf, 2, 3))); 41 | #else 42 | int ud_asmprintf(struct ud *u, const char *fmt, ...); 43 | #endif 44 | 45 | void ud_syn_print_addr(struct ud *u, uint64_t addr); 46 | void ud_syn_print_imm(struct ud* u, const struct ud_operand *op); 47 | void ud_syn_print_mem_disp(struct ud* u, const struct ud_operand *, int sign); 48 | 49 | #endif /* UD_SYN_H */ 50 | 51 | /* 52 | vim: set ts=2 sw=2 expandtab 53 | */ 54 | -------------------------------------------------------------------------------- /udis86test/udint.h: -------------------------------------------------------------------------------- 1 | /* udis86 - libudis86/udint.h -- definitions for internal use only 2 | * 3 | * Copyright (c) 2002-2009 Vivek Thampi 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #ifndef _UDINT_H_ 27 | #define _UDINT_H_ 28 | 29 | #ifdef HAVE_CONFIG_H 30 | # include 31 | #endif /* HAVE_CONFIG_H */ 32 | 33 | #if defined(UD_DEBUG) && HAVE_ASSERT_H 34 | # include 35 | # define UD_ASSERT(_x) assert(_x) 36 | #else 37 | # define UD_ASSERT(_x) 38 | #endif /* !HAVE_ASSERT_H */ 39 | 40 | #if defined(UD_DEBUG) 41 | #define UDERR(u, msg) \ 42 | do { \ 43 | (u)->error = 1; \ 44 | fprintf(stderr, "decode-error: %s:%d: %s", \ 45 | __FILE__, __LINE__, (msg)); \ 46 | } while (0) 47 | #else 48 | #define UDERR(u, m) \ 49 | do { \ 50 | (u)->error = 1; \ 51 | } while (0) 52 | #endif /* !LOGERR */ 53 | 54 | #define UD_RETURN_ON_ERROR(u) \ 55 | do { \ 56 | if ((u)->error != 0) { \ 57 | return (u)->error; \ 58 | } \ 59 | } while (0) 60 | 61 | #define UD_RETURN_WITH_ERROR(u, m) \ 62 | do { \ 63 | UDERR(u, m); \ 64 | return (u)->error; \ 65 | } while (0) 66 | 67 | #ifndef __UD_STANDALONE__ 68 | # define UD_NON_STANDALONE(x) x 69 | #else 70 | # define UD_NON_STANDALONE(x) 71 | #endif 72 | 73 | /* printf formatting int64 specifier */ 74 | #ifdef FMT64 75 | # undef FMT64 76 | #endif 77 | #if defined(_MSC_VER) || defined(__BORLANDC__) 78 | # define FMT64 "I64" 79 | #else 80 | # if defined(__APPLE__) 81 | # define FMT64 "ll" 82 | # elif defined(__amd64__) || defined(__x86_64__) 83 | # define FMT64 "l" 84 | # else 85 | # define FMT64 "ll" 86 | # endif /* !x64 */ 87 | #endif 88 | 89 | #endif /* _UDINT_H_ */ 90 | -------------------------------------------------------------------------------- /udis86test/udis86.h: -------------------------------------------------------------------------------- 1 | /* udis86 - udis86.h 2 | * 3 | * Copyright (c) 2002-2009 Vivek Thampi 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #ifndef UDIS86_H 27 | #define UDIS86_H 28 | 29 | #include "libudis86/types.h" 30 | #include "libudis86/extern.h" 31 | #include "libudis86/itab.h" 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /udis86test/udis86test.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | 38 | 39 | Header Files 40 | 41 | 42 | Header Files 43 | 44 | 45 | Header Files 46 | 47 | 48 | Header Files 49 | 50 | 51 | Header Files 52 | 53 | 54 | Header Files 55 | 56 | 57 | Header Files 58 | 59 | 60 | Header Files 61 | 62 | 63 | --------------------------------------------------------------------------------