├── .gitignore ├── README.md ├── static_struct_assembler.sln └── static_struct_assembler ├── helper └── address.hpp ├── includes.hpp ├── main.cpp ├── static_struct_assembler.vcxproj ├── static_struct_assembler.vcxproj.filters └── static_struct_assembler.vcxproj.user /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # static_struct_assembler 2 | automatically assemble struct fields with given static addresses into a full struct 3 | 4 | edit STRUCT_NAME on line 20 to your wished name 5 | 6 | example: 7 | 8 | ### main.cpp 9 | ```c++ 10 | auto struct_fields = std::vector 11 | { 12 | ADD_FIELD( "m_iExample", int32_t, 0x02 ), 13 | ADD_FIELD( "m_iExample2", int32_t, 0x22C ), 14 | ADD_FIELD( "m_fExample1", float_t, 0x420 ), 15 | }; 16 | ``` 17 | 18 | ### generated out.hpp 19 | ```c++ 20 | struct example_t 21 | { 22 | int m_iExample; // 0x2 23 | char pad_0[ 0x226 ];// 0x6 24 | int m_iExample2; // 0x22c 25 | char pad_1[ 0x1f0 ];// 0x230 26 | float m_fExample2; // 0x420 27 | }; 28 | ``` 29 | -------------------------------------------------------------------------------- /static_struct_assembler.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.28803.156 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "static_struct_assembler", "static_struct_assembler\static_struct_assembler.vcxproj", "{2AED1A4E-3235-44DD-816A-01CF64FBA4FB}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {2AED1A4E-3235-44DD-816A-01CF64FBA4FB}.Debug|x64.ActiveCfg = Debug|x64 17 | {2AED1A4E-3235-44DD-816A-01CF64FBA4FB}.Debug|x64.Build.0 = Debug|x64 18 | {2AED1A4E-3235-44DD-816A-01CF64FBA4FB}.Debug|x86.ActiveCfg = Debug|Win32 19 | {2AED1A4E-3235-44DD-816A-01CF64FBA4FB}.Debug|x86.Build.0 = Debug|Win32 20 | {2AED1A4E-3235-44DD-816A-01CF64FBA4FB}.Release|x64.ActiveCfg = Release|x64 21 | {2AED1A4E-3235-44DD-816A-01CF64FBA4FB}.Release|x64.Build.0 = Release|x64 22 | {2AED1A4E-3235-44DD-816A-01CF64FBA4FB}.Release|x86.ActiveCfg = Release|Win32 23 | {2AED1A4E-3235-44DD-816A-01CF64FBA4FB}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {20ED7FC1-461F-40B8-9D2A-59476EB062D7} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /static_struct_assembler/helper/address.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct address_t 4 | { 5 | protected: 6 | uintptr_t m_ptr; 7 | public: 8 | 9 | // default c/dtor 10 | __forceinline address_t() : m_ptr{} {}; 11 | __forceinline ~address_t() {}; 12 | 13 | __forceinline address_t( uintptr_t a ) : 14 | m_ptr{ a } 15 | {} 16 | 17 | __forceinline address_t( const void* a ) : 18 | m_ptr{ ( uintptr_t )a } 19 | {} 20 | 21 | __forceinline operator uintptr_t() 22 | { 23 | return m_ptr; 24 | } 25 | 26 | __forceinline operator void* ( ) 27 | { 28 | return ( void* )m_ptr; 29 | } 30 | 31 | __forceinline operator const void* ( ) 32 | { 33 | return ( const void* )m_ptr; 34 | } 35 | 36 | // to is like as but dereferences. 37 | template< typename t = address_t > 38 | __forceinline t to() const 39 | { 40 | return *( t* )m_ptr; 41 | } 42 | 43 | template< typename t = address_t > 44 | __forceinline t as() const 45 | { 46 | return ( t )m_ptr; 47 | } 48 | 49 | template< typename t = address_t > 50 | __forceinline t at( ptrdiff_t offset ) const 51 | { 52 | return *( t* )( m_ptr + offset ); 53 | } 54 | 55 | template< typename t = address_t > 56 | __forceinline t add( ptrdiff_t offset ) const 57 | { 58 | return ( t )( m_ptr + offset ); 59 | } 60 | 61 | template< typename t = address_t > 62 | __forceinline t sub( ptrdiff_t offset ) const 63 | { 64 | return ( t )( m_ptr - offset ); 65 | } 66 | 67 | template< typename t = address_t > 68 | __forceinline t get( size_t dereferences = 1 ) 69 | { 70 | return ( t )( get_( dereferences ) ); 71 | } 72 | 73 | template< typename t = address_t > 74 | __forceinline void set( t val ) 75 | { 76 | *( t* )m_ptr = val; 77 | } 78 | 79 | template< typename t = address_t > 80 | __forceinline t rel( size_t offset = 0 ) 81 | { 82 | uintptr_t out; 83 | uint32_t rel; 84 | 85 | out = m_ptr + offset; 86 | 87 | rel = *( uint32_t* )out; 88 | if ( !rel ) 89 | return t{}; 90 | 91 | out = ( out + 0x4 ) + rel; 92 | 93 | return ( t )out; 94 | } 95 | 96 | __forceinline static bool safe( address_t to_check ) 97 | { 98 | static MEMORY_BASIC_INFORMATION32 mbi{}; 99 | 100 | if ( !to_check 101 | || to_check < 0x10000 102 | || to_check > 0xFFE00000 103 | || !VirtualQuery( to_check, ( PMEMORY_BASIC_INFORMATION )& mbi, sizeof( mbi ) ) ) 104 | return false; 105 | 106 | if ( !mbi.AllocationBase 107 | || mbi.State != MEM_COMMIT 108 | || mbi.Protect == PAGE_NOACCESS 109 | || mbi.Protect & PAGE_GUARD ) 110 | return false; 111 | 112 | return true; 113 | } 114 | private: 115 | __forceinline uintptr_t get_( size_t dereferences ) 116 | { 117 | uintptr_t temp = m_ptr; 118 | 119 | while ( dereferences-- && safe( temp ) ) 120 | temp = *reinterpret_cast< uintptr_t* >( temp ); 121 | 122 | return temp; 123 | } 124 | }; 125 | -------------------------------------------------------------------------------- /static_struct_assembler/includes.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) 4 | #include 5 | #endif 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "helper/address.hpp" -------------------------------------------------------------------------------- /static_struct_assembler/main.cpp: -------------------------------------------------------------------------------- 1 | #include "includes.hpp" 2 | 3 | struct info_entry_t 4 | { 5 | info_entry_t() = default; 6 | info_entry_t( const std::string& name, const std::string& type, uintptr_t size, address_t address ) : 7 | m_name( name ), m_type( type ), m_size( size ), m_offset( address ) 8 | {} 9 | 10 | ~info_entry_t() = default; 11 | 12 | std::string m_name; 13 | std::string m_type; 14 | 15 | address_t m_offset; 16 | 17 | uintptr_t m_size; 18 | }; 19 | 20 | #define STRUCT_NAME "example_t" 21 | 22 | #define ADD_FIELD( field_name, type, offset ) info_entry_t( field_name, typeid( type ).name(), sizeof( type ), offset ) 23 | 24 | BOOL main() 25 | { 26 | try 27 | { 28 | auto struct_fields = std::vector 29 | { 30 | ADD_FIELD( "m_iExample", int32_t, 0x02 ), 31 | ADD_FIELD( "m_iExample2", int32_t, 0x22C ), 32 | ADD_FIELD( "m_fExample1", float_t, 0x420 ), 33 | }; 34 | 35 | /// Sort vector by offset so everything is at the right position 36 | std::sort( struct_fields.begin(), struct_fields.end(), 37 | []( const auto & first, const auto & second ) -> bool 38 | { 39 | return first.m_offset.as() < second.m_offset.as(); 40 | } ); 41 | 42 | 43 | std::ofstream output( "out.hpp" ); 44 | if ( !output.is_open() ) 45 | throw std::exception( "Failed to open output file" ); 46 | 47 | output << "struct " << STRUCT_NAME <(); 60 | output << std::endl; 61 | 62 | /// Check if it's not the last item 63 | if ( i < struct_fields.size() - 1 ) 64 | { 65 | auto& next = struct_fields.at( i + 1 ); 66 | auto delta = next.m_offset - ( field.m_offset + field.m_size ); 67 | 68 | /// Check if we need a padding 69 | if ( delta > 0 ) 70 | { 71 | /// Add padding 72 | output << "\t"; 73 | output << "char "; 74 | output << "pad_" << std::dec << i << "[ 0x" << std::hex << delta << " ];"; 75 | output << "// 0x" << std::hex << field.m_offset + field.m_size; 76 | output << std::endl; 77 | } 78 | } 79 | } 80 | 81 | /// Everything good, let's complete the struct and close the file 82 | output << "};"; 83 | 84 | output.close(); 85 | } 86 | catch ( const std::exception & ex ) 87 | { 88 | MessageBoxA( NULL, ex.what(), "Error!", MB_OK | MB_ICONERROR ); 89 | } 90 | 91 | return TRUE; 92 | } -------------------------------------------------------------------------------- /static_struct_assembler/static_struct_assembler.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | {2AED1A4E-3235-44DD-816A-01CF64FBA4FB} 24 | staticstructassembler 25 | 10.0.17763.0 26 | 27 | 28 | 29 | Application 30 | true 31 | v142 32 | MultiByte 33 | 34 | 35 | Application 36 | false 37 | v142 38 | true 39 | MultiByte 40 | 41 | 42 | Application 43 | true 44 | v142 45 | MultiByte 46 | 47 | 48 | Application 49 | false 50 | v142 51 | true 52 | MultiByte 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | Level3 76 | Disabled 77 | true 78 | true 79 | 80 | 81 | Console 82 | 83 | 84 | 85 | 86 | Level3 87 | Disabled 88 | true 89 | true 90 | 91 | 92 | Console 93 | 94 | 95 | 96 | 97 | Level3 98 | MaxSpeed 99 | true 100 | true 101 | true 102 | true 103 | 104 | 105 | Console 106 | true 107 | true 108 | 109 | 110 | 111 | 112 | Level3 113 | MaxSpeed 114 | true 115 | true 116 | true 117 | true 118 | 119 | 120 | Console 121 | true 122 | true 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | -------------------------------------------------------------------------------- /static_struct_assembler/static_struct_assembler.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;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 | 23 | 24 | Header Files 25 | 26 | 27 | Header Files 28 | 29 | 30 | -------------------------------------------------------------------------------- /static_struct_assembler/static_struct_assembler.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | true 5 | 6 | --------------------------------------------------------------------------------