├── .DS_Store ├── .gitignore ├── Carbon_Address.h ├── Helpers.h ├── LICENSE ├── MW_Address.h ├── PS_Address.h ├── README.md ├── TexWizard.h ├── TexWizard.sln ├── TexWizard.vcxproj ├── TexWizard.vcxproj.user ├── UC_Address.h ├── UG2_Address.h ├── UG_Address.h ├── dllmain.cpp ├── includes ├── CPatch.h ├── IniReader.h ├── ini_parser.hpp ├── injector │ ├── assembly.hpp │ ├── calling.hpp │ ├── gvm │ │ ├── gvm.hpp │ │ └── translator.hpp │ ├── hooking.hpp │ ├── injector.hpp │ └── utility.hpp └── stdafx.h ├── json ├── json-forwards.h └── json.h ├── jsoncpp.cpp ├── stdafx.cpp ├── stdafx.h └── targetver.h /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-033/texwizard/a1af0b52eaac30f043bffa7cfd001789d72a4a9b/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | *.VC.db 13 | 14 | # 15 | Debug_Carbon/ 16 | Debug_MW/ 17 | Debug_PS/ 18 | Debug_UC/ 19 | Debug_UG/ 20 | Debug_UG2/ 21 | Release_Carbon/ 22 | Release_MW/ 23 | Release_PS/ 24 | Release_UC/ 25 | Release_UG/ 26 | Release_UG2/ 27 | 28 | # Build results 29 | [Dd]ebug/ 30 | [Dd]ebugPublic/ 31 | [Rr]elease/ 32 | [Rr]eleases/ 33 | x64/ 34 | x86/ 35 | bld/ 36 | [Bb]in/ 37 | [Oo]bj/ 38 | 39 | # Visual Studio 2015 cache/options directory 40 | .vs/ 41 | # Uncomment if you have tasks that create the project's static files in wwwroot 42 | #wwwroot/ 43 | 44 | # MSTest test Results 45 | [Tt]est[Rr]esult*/ 46 | [Bb]uild[Ll]og.* 47 | 48 | # NUNIT 49 | *.VisualState.xml 50 | TestResult.xml 51 | 52 | # Build Results of an ATL Project 53 | [Dd]ebugPS/ 54 | [Rr]eleasePS/ 55 | dlldata.c 56 | 57 | # DNX 58 | project.lock.json 59 | artifacts/ 60 | 61 | *_i.c 62 | *_p.c 63 | *_i.h 64 | *.ilk 65 | *.meta 66 | *.obj 67 | *.pch 68 | *.pdb 69 | *.pgc 70 | *.pgd 71 | *.rsp 72 | *.sbr 73 | *.tlb 74 | *.tli 75 | *.tlh 76 | *.tmp 77 | *.tmp_proj 78 | *.log 79 | *.vspscc 80 | *.vssscc 81 | .builds 82 | *.pidb 83 | *.svclog 84 | *.scc 85 | 86 | # Chutzpah Test files 87 | _Chutzpah* 88 | 89 | # Visual C++ cache files 90 | ipch/ 91 | *.aps 92 | *.ncb 93 | *.opendb 94 | *.opensdf 95 | *.sdf 96 | *.cachefile 97 | 98 | # Visual Studio profiler 99 | *.psess 100 | *.vsp 101 | *.vspx 102 | *.sap 103 | 104 | # TFS 2012 Local Workspace 105 | $tf/ 106 | 107 | # Guidance Automation Toolkit 108 | *.gpState 109 | 110 | # ReSharper is a .NET coding add-in 111 | _ReSharper*/ 112 | *.[Rr]e[Ss]harper 113 | *.DotSettings.user 114 | 115 | # JustCode is a .NET coding add-in 116 | .JustCode 117 | 118 | # TeamCity is a build add-in 119 | _TeamCity* 120 | 121 | # DotCover is a Code Coverage Tool 122 | *.dotCover 123 | 124 | # NCrunch 125 | _NCrunch_* 126 | .*crunch*.local.xml 127 | nCrunchTemp_* 128 | 129 | # MightyMoose 130 | *.mm.* 131 | AutoTest.Net/ 132 | 133 | # Web workbench (sass) 134 | .sass-cache/ 135 | 136 | # Installshield output folder 137 | [Ee]xpress/ 138 | 139 | # DocProject is a documentation generator add-in 140 | DocProject/buildhelp/ 141 | DocProject/Help/*.HxT 142 | DocProject/Help/*.HxC 143 | DocProject/Help/*.hhc 144 | DocProject/Help/*.hhk 145 | DocProject/Help/*.hhp 146 | DocProject/Help/Html2 147 | DocProject/Help/html 148 | 149 | # Click-Once directory 150 | publish/ 151 | 152 | # Publish Web Output 153 | *.[Pp]ublish.xml 154 | *.azurePubxml 155 | # TODO: Comment the next line if you want to checkin your web deploy settings 156 | # but database connection strings (with potential passwords) will be unencrypted 157 | *.pubxml 158 | *.publishproj 159 | 160 | # NuGet Packages 161 | *.nupkg 162 | # The packages folder can be ignored because of Package Restore 163 | **/packages/* 164 | # except build/, which is used as an MSBuild target. 165 | !**/packages/build/ 166 | # Uncomment if necessary however generally it will be regenerated when needed 167 | #!**/packages/repositories.config 168 | # NuGet v3's project.json files produces more ignoreable files 169 | *.nuget.props 170 | *.nuget.targets 171 | 172 | # Microsoft Azure Build Output 173 | csx/ 174 | *.build.csdef 175 | 176 | # Microsoft Azure Emulator 177 | ecf/ 178 | rcf/ 179 | 180 | # Microsoft Azure ApplicationInsights config file 181 | ApplicationInsights.config 182 | 183 | # Windows Store app package directory 184 | AppPackages/ 185 | BundleArtifacts/ 186 | 187 | # Visual Studio cache files 188 | # files ending in .cache can be ignored 189 | *.[Cc]ache 190 | # but keep track of directories ending in .cache 191 | !*.[Cc]ache/ 192 | 193 | # Others 194 | ClientBin/ 195 | ~$* 196 | *~ 197 | *.dbmdl 198 | *.dbproj.schemaview 199 | *.pfx 200 | *.publishsettings 201 | node_modules/ 202 | orleans.codegen.cs 203 | 204 | # RIA/Silverlight projects 205 | Generated_Code/ 206 | 207 | # Backup & report files from converting an old project file 208 | # to a newer Visual Studio version. Backup files are not needed, 209 | # because we have git ;-) 210 | _UpgradeReport_Files/ 211 | Backup*/ 212 | UpgradeLog*.XML 213 | UpgradeLog*.htm 214 | 215 | # SQL Server files 216 | *.mdf 217 | *.ldf 218 | 219 | # Business Intelligence projects 220 | *.rdl.data 221 | *.bim.layout 222 | *.bim_*.settings 223 | 224 | # Microsoft Fakes 225 | FakesAssemblies/ 226 | 227 | # GhostDoc plugin setting file 228 | *.GhostDoc.xml 229 | 230 | # Node.js Tools for Visual Studio 231 | .ntvs_analysis.dat 232 | 233 | # Visual Studio 6 build log 234 | *.plg 235 | 236 | # Visual Studio 6 workspace options file 237 | *.opt 238 | 239 | # Visual Studio LightSwitch build output 240 | **/*.HTMLClient/GeneratedArtifacts 241 | **/*.DesktopClient/GeneratedArtifacts 242 | **/*.DesktopClient/ModelManifest.xml 243 | **/*.Server/GeneratedArtifacts 244 | **/*.Server/ModelManifest.xml 245 | _Pvt_Extensions 246 | 247 | # Paket dependency manager 248 | .paket/paket.exe 249 | 250 | # FAKE - F# Make 251 | .fake/ 252 | -------------------------------------------------------------------------------- /Carbon_Address.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef GAME_CARBON 3 | #define GAME_CARBON 4 | #endif 5 | 6 | #define EntryPoint 0x87E926 7 | #define WrongEntryPointErrorString "This .exe is not supported.\nPlease use v1.4 English nfsc.exe (6,88 MB (7.217.152 bytes))." 8 | 9 | #define bStringHash_Addr 0x471050 10 | #define CreateResourceFile_Addr 0x6B32C0 11 | #define ResourceFileBeginLoading_Addr 0x6B5910 12 | #define LoadGlobalChunks_Addr 0x6B6E00 13 | #define GetTextureInfo_Addr 0x55CFD0 14 | 15 | #define LoadGlobalChunks_Hook_Addr_1 0x6B776F 16 | 17 | #define GetTextureInfo_Hook_Addr_1 0x44E3E2 18 | #define GetTextureInfo_Hook_Addr_2 0x44E401 19 | #define GetTextureInfo_Hook_Addr_3 0x45F3A1 20 | #define GetTextureInfo_Hook_Addr_4 0x45F3C0 21 | #define GetTextureInfo_Hook_Addr_5 0x4B6BC1 22 | #define GetTextureInfo_Hook_Addr_6 0x4BABC8 23 | #define GetTextureInfo_Hook_Addr_7 0x4BABF1 24 | #define GetTextureInfo_Hook_Addr_8 0x4C457B 25 | #define GetTextureInfo_Hook_Addr_9 0x55D149 26 | #define GetTextureInfo_Hook_Addr_10 0x55D1B9 27 | #define GetTextureInfo_Hook_Addr_11 0x55D22A 28 | #define GetTextureInfo_Hook_Addr_12 0x55D27E 29 | #define GetTextureInfo_Hook_Addr_13 0x55D28E 30 | #define GetTextureInfo_Hook_Addr_14 0x55D348 31 | #define GetTextureInfo_Hook_Addr_15 0x55D35B 32 | #define GetTextureInfo_Hook_Addr_16 0x55D36E 33 | #define GetTextureInfo_Hook_Addr_17 0x55D381 34 | #define GetTextureInfo_Hook_Addr_18 0x55D394 35 | #define GetTextureInfo_Hook_Addr_19 0x55D850 36 | #define GetTextureInfo_Hook_Addr_20 0x55DA51 37 | #define GetTextureInfo_Hook_Addr_21 0x55DA80 38 | #define GetTextureInfo_Hook_Addr_22 0x55DB0D 39 | #define GetTextureInfo_Hook_Addr_23 0x55DB8E 40 | #define GetTextureInfo_Hook_Addr_24 0x55DD85 41 | #define GetTextureInfo_Hook_Addr_25 0x55DE57 42 | #define GetTextureInfo_Hook_Addr_26 0x55DF7F 43 | #define GetTextureInfo_Hook_Addr_27 0x55E109 44 | #define GetTextureInfo_Hook_Addr_28 0x570837 45 | #define GetTextureInfo_Hook_Addr_29 0x5708A7 46 | #define GetTextureInfo_Hook_Addr_30 0x57092E 47 | #define GetTextureInfo_Hook_Addr_31 0x5709FE 48 | #define GetTextureInfo_Hook_Addr_32 0x570B01 49 | #define GetTextureInfo_Hook_Addr_33 0x570B51 50 | #define GetTextureInfo_Hook_Addr_34 0x570BA1 51 | #define GetTextureInfo_Hook_Addr_35 0x570BF1 52 | #define GetTextureInfo_Hook_Addr_36 0x57F39E 53 | #define GetTextureInfo_Hook_Addr_37 0x5822C1 54 | #define GetTextureInfo_Hook_Addr_38 0x582302 55 | #define GetTextureInfo_Hook_Addr_39 0x582325 56 | #define GetTextureInfo_Hook_Addr_40 0x585385 57 | #define GetTextureInfo_Hook_Addr_41 0x585F6C 58 | #define GetTextureInfo_Hook_Addr_42 0x586032 59 | #define GetTextureInfo_Hook_Addr_43 0x586542 60 | #define GetTextureInfo_Hook_Addr_44 0x590C9E 61 | #define GetTextureInfo_Hook_Addr_45 0x590DF6 62 | #define GetTextureInfo_Hook_Addr_46 0x593630 63 | #define GetTextureInfo_Hook_Addr_47 0x596DE5 64 | #define GetTextureInfo_Hook_Addr_48 0x596F9E 65 | #define GetTextureInfo_Hook_Addr_49 0x598FF6 66 | #define GetTextureInfo_Hook_Addr_50 0x599010 67 | #define GetTextureInfo_Hook_Addr_51 0x599452 68 | #define GetTextureInfo_Hook_Addr_52 0x5996ED 69 | #define GetTextureInfo_Hook_Addr_53 0x59AA73 70 | #define GetTextureInfo_Hook_Addr_54 0x59F10C 71 | #define GetTextureInfo_Hook_Addr_55 0x59F120 72 | #define GetTextureInfo_Hook_Addr_56 0x59F482 73 | #define GetTextureInfo_Hook_Addr_57 0x59F4AC 74 | #define GetTextureInfo_Hook_Addr_58 0x59F789 75 | #define GetTextureInfo_Hook_Addr_59 0x5D8654 76 | #define GetTextureInfo_Hook_Addr_60 0x5D8744 77 | #define GetTextureInfo_Hook_Addr_61 0x5E4F6E 78 | #define GetTextureInfo_Hook_Addr_62 0x6B6F9E 79 | #define GetTextureInfo_Hook_Addr_63 0x708E98 80 | #define GetTextureInfo_Hook_Addr_64 0x70FB72 81 | #define GetTextureInfo_Hook_Addr_65 0x70FB91 82 | #define GetTextureInfo_Hook_Addr_66 0x70FBB0 83 | #define GetTextureInfo_Hook_Addr_67 0x70FBCF 84 | #define GetTextureInfo_Hook_Addr_68 0x70FBEE 85 | #define GetTextureInfo_Hook_Addr_69 0x70FC72 86 | #define GetTextureInfo_Hook_Addr_70 0x70FDCA 87 | #define GetTextureInfo_Hook_Addr_71 0x70FE31 88 | #define GetTextureInfo_Hook_Addr_72 0x71336C 89 | #define GetTextureInfo_Hook_Addr_73 0x71CE22 90 | #define GetTextureInfo_Hook_Addr_74 0x722D8C 91 | #define GetTextureInfo_Hook_Addr_75 0x73AB2A 92 | #define GetTextureInfo_Hook_Addr_76 0x73C267 93 | #define GetTextureInfo_Hook_Addr_77 0x73C282 94 | #define GetTextureInfo_Hook_Addr_78 0x73C29E 95 | #define GetTextureInfo_Hook_Addr_79 0x73C2BA 96 | #define GetTextureInfo_Hook_Addr_80 0x73D37E 97 | #define GetTextureInfo_Hook_Addr_81 0x73DF85 98 | #define GetTextureInfo_Hook_Addr_82 0x73E025 99 | #define GetTextureInfo_Hook_Addr_83 0x73E125 100 | #define GetTextureInfo_Hook_Addr_84 0x73E355 101 | #define GetTextureInfo_Hook_Addr_85 0x73E4C5 102 | #define GetTextureInfo_Hook_Addr_86 0x73E4E5 103 | #define GetTextureInfo_Hook_Addr_87 0x73F9B2 104 | #define GetTextureInfo_Hook_Addr_88 0x73F9D1 105 | #define GetTextureInfo_Hook_Addr_89 0x73F9F0 106 | #define GetTextureInfo_Hook_Addr_90 0x740CB7 107 | #define GetTextureInfo_Hook_Addr_91 0x748230 108 | #define GetTextureInfo_Hook_Addr_92 0x749A89 109 | #define GetTextureInfo_Hook_Addr_93 0x749C38 110 | #define GetTextureInfo_Hook_Addr_94 0x749C63 111 | #define GetTextureInfo_Hook_Addr_95 0x74EB3B 112 | #define GetTextureInfo_Hook_Addr_96 0x74F011 113 | #define GetTextureInfo_Hook_Addr_97 0x7590AC 114 | #define GetTextureInfo_Hook_Addr_98 0x7590DD 115 | #define GetTextureInfo_Hook_Addr_99 0x7591B4 116 | #define GetTextureInfo_Hook_Addr_100 0x759E7B 117 | #define GetTextureInfo_Hook_Addr_101 0x75AA4C 118 | #define GetTextureInfo_Hook_Addr_102 0x75AA68 119 | #define GetTextureInfo_Hook_Addr_103 0x798F4E 120 | #define GetTextureInfo_Hook_Addr_104 0x79ACE5 121 | #define GetTextureInfo_Hook_Addr_105 0x79AD04 122 | #define GetTextureInfo_Hook_Addr_106 0x79AD28 123 | #define GetTextureInfo_Hook_Addr_107 0x79AD53 124 | #define GetTextureInfo_Hook_Addr_108 0x7ACCB3 125 | #define GetTextureInfo_Hook_Addr_109 0x7AEFF4 126 | #define GetTextureInfo_Hook_Addr_110 0x7AF00D 127 | #define GetTextureInfo_Hook_Addr_111 0x7AF026 128 | #define GetTextureInfo_Hook_Addr_112 0x7AF03F 129 | #define GetTextureInfo_Hook_Addr_113 0x7B117A 130 | #define GetTextureInfo_Hook_Addr_114 0x7B11A7 131 | #define GetTextureInfo_Hook_Addr_115 0x7B3685 132 | #define GetTextureInfo_Hook_Addr_116 0x7B9CE6 133 | #define GetTextureInfo_Hook_Addr_117 0x7BE2AA 134 | #define GetTextureInfo_Hook_Addr_118 0x7C3C3F 135 | #define GetTextureInfo_Hook_Addr_119 0x7C3C53 136 | #define GetTextureInfo_Hook_Addr_120 0x7C3C67 137 | #define GetTextureInfo_Hook_Addr_121 0x7C3CB2 138 | #define GetTextureInfo_Hook_Addr_122 0x7C3E3A 139 | #define GetTextureInfo_Hook_Addr_123 0x7C3E6C 140 | #define GetTextureInfo_Hook_Addr_124 0x7C3E7C 141 | #define GetTextureInfo_Hook_Addr_125 0x7D13A4 142 | #define GetTextureInfo_Hook_Addr_126 0x7D13DF 143 | #define GetTextureInfo_Hook_Addr_127 0x7D148B 144 | #define GetTextureInfo_Hook_Addr_128 0x7D14E8 145 | #define GetTextureInfo_Hook_Addr_129 0x7D15AF 146 | #define GetTextureInfo_Hook_Addr_130 0x7D15F5 147 | #define GetTextureInfo_Hook_Addr_131 0x7D758F 148 | #define GetTextureInfo_Hook_Addr_132 0x7D75AE 149 | #define GetTextureInfo_Hook_Addr_133 0x7D7637 150 | #define GetTextureInfo_Hook_Addr_134 0x7D9DA9 151 | #define GetTextureInfo_Hook_Addr_135 0x7D9DBC 152 | #define GetTextureInfo_Hook_Addr_136 0x7DBA29 153 | #define GetTextureInfo_Hook_Addr_137 0x7DBA55 154 | #define GetTextureInfo_Hook_Addr_138 0x7DBA81 155 | #define GetTextureInfo_Hook_Addr_139 0x7DBABC 156 | #define GetTextureInfo_Hook_Addr_140 0x7DBAFB 157 | #define GetTextureInfo_Hook_Addr_141 0x7DBB35 158 | #define GetTextureInfo_Hook_Addr_142 0x7DBB4D 159 | #define GetTextureInfo_Hook_Addr_143 0x7DBB6B 160 | #define GetTextureInfo_Hook_Addr_144 0x7DBC2C 161 | #define GetTextureInfo_Hook_Addr_145 0x7DBC46 162 | #define GetTextureInfo_Hook_Addr_146 0x7DBC87 163 | #define GetTextureInfo_Hook_Addr_147 0x7DBCA1 164 | #define GetTextureInfo_Hook_Addr_148 0x7DBD27 165 | #define GetTextureInfo_Hook_Addr_149 0x7DBD3D 166 | #define GetTextureInfo_Hook_Addr_150 0x7DBD55 167 | #define GetTextureInfo_Hook_Addr_151 0x7E5A73 168 | #define GetTextureInfo_Hook_Addr_152 0x7E5A85 169 | #define GetTextureInfo_Hook_Addr_153 0x813EBE 170 | #define GetTextureInfo_Hook_Addr_154 0x83DED6 171 | #define GetTextureInfo_Hook_Addr_155 0x84D584 172 | #define GetTextureInfo_Hook_Addr_156 0x84D681 173 | 174 | unsigned int(*bStringHash)(char* StringToHash) = (unsigned int(*)(char*))bStringHash_Addr; 175 | 176 | DWORD* (__cdecl* CreateResourceFile)(int a1, int a2, int a3, int a4, int a5) = (DWORD * (__cdecl*)(int, int, int, int, int))CreateResourceFile_Addr; 177 | int(__thiscall* ResourceFileBeginLoading)(DWORD* r, int unk1, int unk2) = (int(__thiscall*)(DWORD*, int, int))ResourceFileBeginLoading_Addr; 178 | 179 | int(__fastcall* LoadGlobalChunks)() = (int(__fastcall*)())LoadGlobalChunks_Addr; 180 | 181 | DWORD* (__cdecl* GetTextureInfo)(unsigned int hash, int returnDefault, int includeUnloadedTextures) = (DWORD * (__cdecl*)(unsigned int, int, int))GetTextureInfo_Addr; 182 | -------------------------------------------------------------------------------- /Helpers.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | inline bool DoesFileExist(char const* path) 4 | { 5 | struct stat buffer; 6 | return (stat(path, &buffer) == 0); 7 | } -------------------------------------------------------------------------------- /MW_Address.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef GAME_MW 3 | #define GAME_MW 4 | #endif 5 | 6 | #define EntryPoint 0x7C4040 7 | #define WrongEntryPointErrorString "This .exe is not supported.\nPlease use v1.3 English speed.exe (5,75 MB (6.029.312 bytes))." 8 | 9 | #define bStringHash_Addr 0x460BF0 10 | #define CreateResourceFile_Addr 0x65FD30 11 | #define ResourceFileBeginLoading_Addr 0x6616F0 12 | #define LoadGlobalChunks_Addr 0x664780 13 | #define GetTextureInfo_Addr 0x503400 14 | 15 | 16 | #define LoadGlobalChunks_Hook_Addr_1 0x6660c0 17 | 18 | #define GetTextureInfo_Hook_Addr_1 0x4465B2 19 | #define GetTextureInfo_Hook_Addr_2 0x450d8d 20 | #define GetTextureInfo_Hook_Addr_3 0x503579 21 | #define GetTextureInfo_Hook_Addr_4 0x5035e9 22 | #define GetTextureInfo_Hook_Addr_5 0x50364A 23 | #define GetTextureInfo_Hook_Addr_6 0x5036AE 24 | #define GetTextureInfo_Hook_Addr_7 0x5036BE 25 | #define GetTextureInfo_Hook_Addr_8 0x5037c8 26 | #define GetTextureInfo_Hook_Addr_9 0x5037db 27 | #define GetTextureInfo_Hook_Addr_10 0x5037ee 28 | #define GetTextureInfo_Hook_Addr_11 0x503801 29 | #define GetTextureInfo_Hook_Addr_12 0x503814 30 | #define GetTextureInfo_Hook_Addr_13 0x503dae 31 | #define GetTextureInfo_Hook_Addr_14 0x504F4D 32 | #define GetTextureInfo_Hook_Addr_15 0x504fc8 33 | #define GetTextureInfo_Hook_Addr_16 0x5051f5 34 | #define GetTextureInfo_Hook_Addr_17 0x5052f7 35 | #define GetTextureInfo_Hook_Addr_18 0x50535e 36 | #define GetTextureInfo_Hook_Addr_19 0x505a2d 37 | #define GetTextureInfo_Hook_Addr_20 0x5152c7 38 | #define GetTextureInfo_Hook_Addr_21 0x515337 39 | #define GetTextureInfo_Hook_Addr_22 0x5153be 40 | #define GetTextureInfo_Hook_Addr_23 0x51548e 41 | #define GetTextureInfo_Hook_Addr_24 0x515651 42 | #define GetTextureInfo_Hook_Addr_25 0x5156F1 43 | #define GetTextureInfo_Hook_Addr_26 0x5156a1 44 | #define GetTextureInfo_Hook_Addr_27 0x515741 45 | #define GetTextureInfo_Hook_Addr_28 0x517a15 46 | #define GetTextureInfo_Hook_Addr_29 0x51f562 47 | #define GetTextureInfo_Hook_Addr_30 0x56feee 48 | #define GetTextureInfo_Hook_Addr_31 0x57229c 49 | #define GetTextureInfo_Hook_Addr_32 0x579464 50 | #define GetTextureInfo_Hook_Addr_33 0x579554 51 | #define GetTextureInfo_Hook_Addr_34 0x585ca2 52 | #define GetTextureInfo_Hook_Addr_35 0x586012 53 | #define GetTextureInfo_Hook_Addr_36 0x5912c2 54 | #define GetTextureInfo_Hook_Addr_37 0x591376 55 | #define GetTextureInfo_Hook_Addr_38 0x59a166 56 | #define GetTextureInfo_Hook_Addr_39 0x59a180 57 | #define GetTextureInfo_Hook_Addr_40 0x59a5f2 58 | #define GetTextureInfo_Hook_Addr_41 0x59a885 59 | #define GetTextureInfo_Hook_Addr_42 0x6648f5 60 | #define GetTextureInfo_Hook_Addr_43 0x6C57F6 61 | #define GetTextureInfo_Hook_Addr_44 0x6D1C72 62 | #define GetTextureInfo_Hook_Addr_45 0x6D740E 63 | #define GetTextureInfo_Hook_Addr_46 0x6bf552 64 | #define GetTextureInfo_Hook_Addr_47 0x6bf571 65 | #define GetTextureInfo_Hook_Addr_48 0x6bf590 66 | #define GetTextureInfo_Hook_Addr_49 0x6bf609 67 | #define GetTextureInfo_Hook_Addr_50 0x6bf775 68 | #define GetTextureInfo_Hook_Addr_51 0x6bf7e1 69 | #define GetTextureInfo_Hook_Addr_52 0x6c58e0 70 | #define GetTextureInfo_Hook_Addr_53 0x6c5aac 71 | #define GetTextureInfo_Hook_Addr_54 0x6d03cc 72 | #define GetTextureInfo_Hook_Addr_55 0x6d1d6e 73 | #define GetTextureInfo_Hook_Addr_56 0x6d1d8d 74 | #define GetTextureInfo_Hook_Addr_57 0x6d1dac 75 | #define GetTextureInfo_Hook_Addr_58 0x6d4407 76 | #define GetTextureInfo_Hook_Addr_59 0x6d471d 77 | #define GetTextureInfo_Hook_Addr_60 0x6dae65 78 | #define GetTextureInfo_Hook_Addr_61 0x6dc38c 79 | #define GetTextureInfo_Hook_Addr_62 0x7222de 80 | #define GetTextureInfo_Hook_Addr_63 0x737103 81 | #define GetTextureInfo_Hook_Addr_64 0x738210 82 | #define GetTextureInfo_Hook_Addr_65 0x739EEA 83 | #define GetTextureInfo_Hook_Addr_66 0x739F17 84 | #define GetTextureInfo_Hook_Addr_67 0x73c6d0 85 | #define GetTextureInfo_Hook_Addr_68 0x74910d 86 | #define GetTextureInfo_Hook_Addr_69 0x74953b 87 | #define GetTextureInfo_Hook_Addr_70 0x7496b8 88 | #define GetTextureInfo_Hook_Addr_71 0x74972b 89 | #define GetTextureInfo_Hook_Addr_72 0x749a43 90 | #define GetTextureInfo_Hook_Addr_73 0x749a53 91 | #define GetTextureInfo_Hook_Addr_74 0x75fc0c 92 | #define GetTextureInfo_Hook_Addr_75 0x75fc1f 93 | #define GetTextureInfo_Hook_Addr_76 0x75fc8c 94 | #define GetTextureInfo_Hook_Addr_77 0x75fc9e 95 | #define GetTextureInfo_Hook_Addr_78 0x7B42DF 96 | #define GetTextureInfo_Hook_Addr_79 0x7B432D 97 | #define GetTextureInfo_Hook_Addr_80 0x7a352f 98 | #define GetTextureInfo_Hook_Addr_81 0x7b3320 99 | 100 | unsigned int(*bStringHash)(char* StringToHash) = (unsigned int(*)(char*))bStringHash_Addr; 101 | 102 | DWORD* (__cdecl* CreateResourceFile)(int a1, int a2, int a3, int a4, int a5) = (DWORD * (__cdecl*)(int, int, int, int, int))CreateResourceFile_Addr; 103 | int(__thiscall* ResourceFileBeginLoading)(DWORD* r, int unk1, int unk2) = (int(__thiscall*)(DWORD*, int, int))ResourceFileBeginLoading_Addr; 104 | 105 | int(__fastcall* LoadGlobalChunks)() = (int(__fastcall*)())LoadGlobalChunks_Addr; 106 | 107 | DWORD* (__cdecl* GetTextureInfo)(unsigned int hash, int returnDefault, int includeUnloadedTextures) = (DWORD * (__cdecl*)(unsigned int, int, int))GetTextureInfo_Addr; 108 | -------------------------------------------------------------------------------- /PS_Address.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef GAME_PS 3 | #define GAME_PS 4 | #endif 5 | 6 | //#define EntryPoint 0x828C25 7 | #define WrongEntryPointErrorString "This .exe is not supported.\nPlease use a NOCD v1.1 NFS.exe." 8 | 9 | #define bStringHash_Addr 0x436680 10 | #define CreateResourceFile_Addr 0x6D6DE0 11 | #define ResourceFileBeginLoading_Addr 0x6D9430 12 | #define LoadGlobalChunks_Addr 0x6DA4D0 13 | #define GetTextureInfo_Addr 0x459C10 14 | 15 | #define LoadGlobalChunks_Hook_Addr_1 0x6DAC3A 16 | 17 | #define GetTextureInfo_Hook_Addr_1 0x458969 18 | #define GetTextureInfo_Hook_Addr_2 0x458A29 19 | #define GetTextureInfo_Hook_Addr_3 0x459170 20 | #define GetTextureInfo_Hook_Addr_4 0x4A2137 21 | #define GetTextureInfo_Hook_Addr_5 0x4A215F 22 | #define GetTextureInfo_Hook_Addr_6 0x4A8E3E 23 | #define GetTextureInfo_Hook_Addr_7 0x4A8E74 24 | #define GetTextureInfo_Hook_Addr_8 0x4A8EAB 25 | #define GetTextureInfo_Hook_Addr_9 0x4A8EE1 26 | #define GetTextureInfo_Hook_Addr_10 0x4A8F1B 27 | #define GetTextureInfo_Hook_Addr_11 0x4A8F51 28 | #define GetTextureInfo_Hook_Addr_12 0x4A8F8B 29 | #define GetTextureInfo_Hook_Addr_13 0x4A8FC2 30 | #define GetTextureInfo_Hook_Addr_14 0x4A8FFD 31 | #define GetTextureInfo_Hook_Addr_15 0x4A903D 32 | #define GetTextureInfo_Hook_Addr_16 0x4ABAE8 33 | #define GetTextureInfo_Hook_Addr_17 0x4AD22D 34 | #define GetTextureInfo_Hook_Addr_18 0x4AD25F 35 | #define GetTextureInfo_Hook_Addr_19 0x4B411F 36 | #define GetTextureInfo_Hook_Addr_20 0x4B417F 37 | #define GetTextureInfo_Hook_Addr_21 0x4B819C 38 | #define GetTextureInfo_Hook_Addr_22 0x4B992B 39 | #define GetTextureInfo_Hook_Addr_23 0x4B9960 40 | #define GetTextureInfo_Hook_Addr_24 0x4BDF5D 41 | #define GetTextureInfo_Hook_Addr_25 0x4C32A5 42 | #define GetTextureInfo_Hook_Addr_26 0x4C36CB 43 | #define GetTextureInfo_Hook_Addr_27 0x4C36FF 44 | #define GetTextureInfo_Hook_Addr_28 0x4C3731 45 | #define GetTextureInfo_Hook_Addr_29 0x4C6CDB 46 | #define GetTextureInfo_Hook_Addr_30 0x4C7379 47 | #define GetTextureInfo_Hook_Addr_31 0x4EC514 48 | #define GetTextureInfo_Hook_Addr_32 0x4EC533 49 | #define GetTextureInfo_Hook_Addr_33J 0x5489D3 50 | #define GetTextureInfo_Hook_Addr_34J 0x558618 51 | #define GetTextureInfo_Hook_Addr_35 0x58DE6A 52 | #define GetTextureInfo_Hook_Addr_36 0x58DF3A 53 | #define GetTextureInfo_Hook_Addr_37 0x58E021 54 | #define GetTextureInfo_Hook_Addr_38 0x58E091 55 | #define GetTextureInfo_Hook_Addr_39 0x592B55 56 | #define GetTextureInfo_Hook_Addr_40 0x59EA11 57 | #define GetTextureInfo_Hook_Addr_41 0x59EA61 58 | #define GetTextureInfo_Hook_Addr_42 0x5A0BFD 59 | #define GetTextureInfo_Hook_Addr_43 0x5A216D 60 | #define GetTextureInfo_Hook_Addr_44 0x5AD674 61 | #define GetTextureInfo_Hook_Addr_45 0x5B5A82 62 | #define GetTextureInfo_Hook_Addr_46 0x5B5A9C 63 | #define GetTextureInfo_Hook_Addr_47 0x5B5FA2 64 | #define GetTextureInfo_Hook_Addr_48 0x5B6279 65 | #define GetTextureInfo_Hook_Addr_49 0x5D1ADF 66 | #define GetTextureInfo_Hook_Addr_50 0x5D1C93 67 | #define GetTextureInfo_Hook_Addr_51 0x6DA6A9 68 | #define GetTextureInfo_Hook_Addr_52 0x6F92F2 69 | #define GetTextureInfo_Hook_Addr_53 0x6F9311 70 | #define GetTextureInfo_Hook_Addr_54 0x6F9330 71 | #define GetTextureInfo_Hook_Addr_55 0x6F934F 72 | #define GetTextureInfo_Hook_Addr_56 0x6F936E 73 | #define GetTextureInfo_Hook_Addr_57 0x6FAE0D 74 | #define GetTextureInfo_Hook_Addr_58 0x7433CD 75 | #define GetTextureInfo_Hook_Addr_59 0x7535F6 76 | #define GetTextureInfo_Hook_Addr_60 0x75360F 77 | #define GetTextureInfo_Hook_Addr_61 0x753628 78 | #define GetTextureInfo_Hook_Addr_62 0x753641 79 | #define GetTextureInfo_Hook_Addr_63 0x754876 80 | #define GetTextureInfo_Hook_Addr_64 0x758024 81 | #define GetTextureInfo_Hook_Addr_65 0x75FC75 82 | #define GetTextureInfo_Hook_Addr_66 0x7636A6 83 | #define GetTextureInfo_Hook_Addr_67 0x76C2DF 84 | #define GetTextureInfo_Hook_Addr_68 0x76C2F3 85 | #define GetTextureInfo_Hook_Addr_69 0x76C307 86 | #define GetTextureInfo_Hook_Addr_70 0x76C350 87 | #define GetTextureInfo_Hook_Addr_71 0x76C54A 88 | #define GetTextureInfo_Hook_Addr_72 0x76C57E 89 | #define GetTextureInfo_Hook_Addr_73 0x76C58E 90 | #define GetTextureInfo_Hook_Addr_74 0x77A6D2 91 | #define GetTextureInfo_Hook_Addr_75 0x77E8D9 92 | #define GetTextureInfo_Hook_Addr_76 0x77E8FF 93 | #define GetTextureInfo_Hook_Addr_77 0x78289E 94 | #define GetTextureInfo_Hook_Addr_78 0x782919 95 | #define GetTextureInfo_Hook_Addr_79 0x782943 96 | #define GetTextureInfo_Hook_Addr_80 0x782994 97 | #define GetTextureInfo_Hook_Addr_81 0x7829DB 98 | #define GetTextureInfo_Hook_Addr_82 0x782B0F 99 | #define GetTextureInfo_Hook_Addr_83 0x782B2E 100 | #define GetTextureInfo_Hook_Addr_84 0x782BA2 101 | #define GetTextureInfo_Hook_Addr_85 0x785A29 102 | #define GetTextureInfo_Hook_Addr_86 0x785A61 103 | #define GetTextureInfo_Hook_Addr_87 0x785A88 104 | #define GetTextureInfo_Hook_Addr_88 0x785AD0 105 | #define GetTextureInfo_Hook_Addr_89 0x785AEF 106 | #define GetTextureInfo_Hook_Addr_90 0x785B58 107 | #define GetTextureInfo_Hook_Addr_91 0x785B70 108 | #define GetTextureInfo_Hook_Addr_92 0x785B8E 109 | #define GetTextureInfo_Hook_Addr_93 0x785C6C 110 | #define GetTextureInfo_Hook_Addr_94 0x785C86 111 | #define GetTextureInfo_Hook_Addr_95 0x785CC9 112 | #define GetTextureInfo_Hook_Addr_96 0x785CE3 113 | #define GetTextureInfo_Hook_Addr_97 0x785D62 114 | #define GetTextureInfo_Hook_Addr_98 0x785D80 115 | #define GetTextureInfo_Hook_Addr_99 0x785D9C 116 | #define GetTextureInfo_Hook_Addr_100 0x787F60 117 | #define GetTextureInfo_Hook_Addr_101 0x787F73 118 | #define GetTextureInfo_Hook_Addr_102 0x78BE5E 119 | #define GetTextureInfo_Hook_Addr_103 0x78BE70 120 | #define GetTextureInfo_Hook_Addr_104 0x78C734 121 | #define GetTextureInfo_Hook_Addr_105 0x7AFF26 122 | #define GetTextureInfo_Hook_Addr_106P 0x01A17796 123 | #define GetTextureInfo_Hook_Addr_107P 0x01A177B5 124 | #define GetTextureInfo_Hook_Addr_108J 0x01A19F25 125 | #define GetTextureInfo_Hook_Addr_109J 0x01DFA029 126 | 127 | unsigned int(*bStringHash)(char* StringToHash) = (unsigned int(*)(char*))bStringHash_Addr; 128 | 129 | DWORD* (__cdecl* CreateResourceFile)(int a1, int a2, int a3, int a4, int a5) = (DWORD * (__cdecl*)(int, int, int, int, int))CreateResourceFile_Addr; 130 | int(__thiscall* ResourceFileBeginLoading)(DWORD* r, int unk1, int unk2) = (int(__thiscall*)(DWORD*, int, int))ResourceFileBeginLoading_Addr; 131 | 132 | int(__fastcall* LoadGlobalChunks)() = (int(__fastcall*)())LoadGlobalChunks_Addr; 133 | 134 | DWORD* (__cdecl* GetTextureInfo)(unsigned int hash, int returnDefault, int includeUnloadedTextures) = (DWORD * (__cdecl*)(unsigned int, int, int))GetTextureInfo_Addr; 135 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Texture Wizard 2 | 3 | Simple script that allows you to easily replace any texture. Initially supported only MW, later was expanded by nlgxzef and now supports following titles: 4 | - NFS Underground 5 | - NFS Underground 2 6 | - NFS Most Wanted 7 | - NFS Carbon 8 | - NFS ProStreet 9 | - NFS Undercover 10 | 11 | The main purpose of this script is to be a more stable alternative to TexMod. It works similar to texture packs in Minecraft - each "pack" contains it's own textures and a list of bindings to replace existing textures. Multiple packs can be used at once in a single game installation. 12 | 13 | Compiled .asi script and an example pack are included in releases. 14 | 15 | For usage refer to wiki. 16 | -------------------------------------------------------------------------------- /TexWizard.h: -------------------------------------------------------------------------------- 1 | #include "Helpers.h" 2 | #include 3 | #include "json/json.h" 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #ifdef GAME_UG 10 | #include "UG_Address.h" 11 | #endif 12 | 13 | #ifdef GAME_UG2 14 | #include "UG2_Address.h" 15 | #endif 16 | 17 | #ifdef GAME_MW 18 | #include "MW_Address.h" 19 | #endif 20 | 21 | #ifdef GAME_CARBON 22 | #include "Carbon_Address.h" 23 | #endif 24 | 25 | #ifdef GAME_PS 26 | #include "PS_Address.h" 27 | #endif 28 | 29 | #ifdef GAME_UC 30 | #include "UC_Address.h" 31 | #endif 32 | 33 | std::vector packList = {}; 34 | std::map textureMap = {}; 35 | 36 | DWORD* __cdecl ReplaceTexture(unsigned int hash, int returnDefault, int includeUnloadedTextures) 37 | { 38 | if (textureMap.count(hash) > 0) 39 | { 40 | hash = textureMap[hash]; 41 | } 42 | 43 | return GetTextureInfo(hash, returnDefault, includeUnloadedTextures); 44 | } 45 | 46 | int __fastcall LoadPacks() 47 | { 48 | #ifdef GAME_UC 49 | int result = LoadGlobalAChunks(); 50 | #else 51 | int result = LoadGlobalChunks(); 52 | #endif 53 | 54 | 55 | // https://github.com/xan1242/xnfsmodfiles 56 | for (int index = 0; index < packList.size(); index++) 57 | { 58 | DWORD* r = CreateResourceFile((int)packList[index], 1, 0, 0, 0); 59 | #ifdef GAME_UC 60 | r[10] = 0x2000; 61 | r[11] = *(int*)0xD3BDD4; 62 | r[9] = SharedStringPoolAllocate(packList[index]); 63 | #endif 64 | ResourceFileBeginLoading(r, 0, 0); 65 | } 66 | 67 | return result; 68 | } 69 | 70 | 71 | void Init() 72 | { 73 | // load config 74 | std::ifstream ifs; 75 | ifs.open("TexWizard.json"); 76 | 77 | Json::CharReaderBuilder builder; 78 | Json::Value root; 79 | JSONCPP_STRING errs; 80 | if (!parseFromStream(builder, ifs, &root, &errs)) 81 | { 82 | MessageBoxA(NULL, "Failed to parse TexWizard configuration.", "TexWizard", MB_ICONERROR); 83 | return; 84 | } 85 | 86 | // load texture packs 87 | Json::Value packs = root["packs"]; 88 | 89 | for (int index = 0; index < packs.size(); index++) 90 | { 91 | Json::Value pack = packs[index]; 92 | 93 | Json::String packString = pack.asString(); 94 | 95 | std::string packRoot = packString.c_str(); 96 | 97 | std::string configPath = packRoot + "\\meta.json"; 98 | std::string dataPath = packRoot + "\\textures.bin"; 99 | 100 | std::ifstream ifs2; 101 | ifs2.open("..\\" + configPath); 102 | 103 | Json::CharReaderBuilder builder2; 104 | Json::Value root2; 105 | 106 | JSONCPP_STRING errs2; 107 | if (!parseFromStream(builder2, ifs2, &root2, &errs2)) 108 | { 109 | MessageBoxA(NULL, ((std::string)"Failed to parse texture pack configuration " + configPath).c_str(), "TexWizard", MB_ICONERROR); 110 | continue; 111 | } 112 | 113 | char* dataPathChar = new char[dataPath.length() + 1]; 114 | strcpy(dataPathChar, dataPath.c_str()); 115 | 116 | packList.push_back(dataPathChar); 117 | 118 | Json::Value textures = root2["textures"]; 119 | 120 | for (int index = 0; index < textures.size(); index++) 121 | { 122 | Json::Value texture = textures[index]; 123 | 124 | Json::String key = texture[0].asString(); 125 | Json::String value = texture[1].asString(); 126 | 127 | unsigned int keyHash; 128 | unsigned int valueHash; 129 | 130 | if (key.rfind("0x", 0) == 0) 131 | { 132 | key.erase(0, 2); 133 | 134 | std::istringstream converter(key); 135 | 136 | converter >> std::hex >> keyHash; 137 | } 138 | else 139 | { 140 | char* keyChar = new char[key.length() + 1]; 141 | strcpy(keyChar, key.c_str()); 142 | 143 | keyHash = bStringHash(keyChar); 144 | } 145 | 146 | if (value.rfind("0x", 0) == 0) 147 | { 148 | value.erase(0, 2); 149 | 150 | std::istringstream converter(value); 151 | 152 | converter >> std::hex >> valueHash; 153 | } 154 | else 155 | { 156 | char* valueChar = new char[value.length() + 1]; 157 | strcpy(valueChar, value.c_str()); 158 | 159 | valueHash = bStringHash(valueChar); 160 | } 161 | 162 | textureMap[keyHash] = valueHash; 163 | } 164 | } 165 | 166 | #ifdef GAME_UC 167 | // replace LoadGlobalAChunks call 168 | injector::MakeJMP(LoadGlobalAChunks_Hook_Addr_1, LoadPacks, true); 169 | #else 170 | // replace LoadGlobalChunks call 171 | injector::MakeCALL(LoadGlobalChunks_Hook_Addr_1, LoadPacks, true); 172 | #endif 173 | 174 | // replace all GetTextureInfo calls 175 | #ifdef GAME_UC 176 | injector::MakeJMP(GetTextureInfo_Hook_Addr_1J, ReplaceTexture, true); 177 | #else 178 | injector::MakeCALL(GetTextureInfo_Hook_Addr_1, ReplaceTexture, true); 179 | #endif 180 | injector::MakeCALL(GetTextureInfo_Hook_Addr_2, ReplaceTexture, true); 181 | injector::MakeCALL(GetTextureInfo_Hook_Addr_3, ReplaceTexture, true); 182 | injector::MakeCALL(GetTextureInfo_Hook_Addr_4, ReplaceTexture, true); 183 | injector::MakeCALL(GetTextureInfo_Hook_Addr_5, ReplaceTexture, true); 184 | injector::MakeCALL(GetTextureInfo_Hook_Addr_6, ReplaceTexture, true); 185 | injector::MakeCALL(GetTextureInfo_Hook_Addr_7, ReplaceTexture, true); 186 | injector::MakeCALL(GetTextureInfo_Hook_Addr_8, ReplaceTexture, true); 187 | injector::MakeCALL(GetTextureInfo_Hook_Addr_9, ReplaceTexture, true); 188 | injector::MakeCALL(GetTextureInfo_Hook_Addr_10, ReplaceTexture, true); 189 | injector::MakeCALL(GetTextureInfo_Hook_Addr_11, ReplaceTexture, true); 190 | injector::MakeCALL(GetTextureInfo_Hook_Addr_12, ReplaceTexture, true); 191 | injector::MakeCALL(GetTextureInfo_Hook_Addr_13, ReplaceTexture, true); 192 | 193 | #ifndef GAME_UC 194 | injector::MakeCALL(GetTextureInfo_Hook_Addr_14, ReplaceTexture, true); 195 | injector::MakeCALL(GetTextureInfo_Hook_Addr_15, ReplaceTexture, true); 196 | injector::MakeCALL(GetTextureInfo_Hook_Addr_16, ReplaceTexture, true); 197 | injector::MakeCALL(GetTextureInfo_Hook_Addr_17, ReplaceTexture, true); 198 | injector::MakeCALL(GetTextureInfo_Hook_Addr_18, ReplaceTexture, true); 199 | injector::MakeCALL(GetTextureInfo_Hook_Addr_19, ReplaceTexture, true); 200 | injector::MakeCALL(GetTextureInfo_Hook_Addr_20, ReplaceTexture, true); 201 | injector::MakeCALL(GetTextureInfo_Hook_Addr_21, ReplaceTexture, true); 202 | injector::MakeCALL(GetTextureInfo_Hook_Addr_22, ReplaceTexture, true); 203 | injector::MakeCALL(GetTextureInfo_Hook_Addr_23, ReplaceTexture, true); 204 | injector::MakeCALL(GetTextureInfo_Hook_Addr_24, ReplaceTexture, true); 205 | injector::MakeCALL(GetTextureInfo_Hook_Addr_25, ReplaceTexture, true); 206 | injector::MakeCALL(GetTextureInfo_Hook_Addr_26, ReplaceTexture, true); 207 | injector::MakeCALL(GetTextureInfo_Hook_Addr_27, ReplaceTexture, true); 208 | injector::MakeCALL(GetTextureInfo_Hook_Addr_28, ReplaceTexture, true); 209 | injector::MakeCALL(GetTextureInfo_Hook_Addr_29, ReplaceTexture, true); 210 | injector::MakeCALL(GetTextureInfo_Hook_Addr_30, ReplaceTexture, true); 211 | injector::MakeCALL(GetTextureInfo_Hook_Addr_31, ReplaceTexture, true); 212 | injector::MakeCALL(GetTextureInfo_Hook_Addr_32, ReplaceTexture, true); 213 | #ifdef GAME_PS 214 | injector::MakeJMP(GetTextureInfo_Hook_Addr_33J, ReplaceTexture, true); 215 | injector::MakeJMP(GetTextureInfo_Hook_Addr_34J, ReplaceTexture, true); 216 | #else 217 | injector::MakeCALL(GetTextureInfo_Hook_Addr_33, ReplaceTexture, true); 218 | injector::MakeCALL(GetTextureInfo_Hook_Addr_34, ReplaceTexture, true); 219 | #endif 220 | injector::MakeCALL(GetTextureInfo_Hook_Addr_35, ReplaceTexture, true); 221 | injector::MakeCALL(GetTextureInfo_Hook_Addr_36, ReplaceTexture, true); 222 | injector::MakeCALL(GetTextureInfo_Hook_Addr_37, ReplaceTexture, true); 223 | injector::MakeCALL(GetTextureInfo_Hook_Addr_38, ReplaceTexture, true); 224 | injector::MakeCALL(GetTextureInfo_Hook_Addr_39, ReplaceTexture, true); 225 | injector::MakeCALL(GetTextureInfo_Hook_Addr_40, ReplaceTexture, true); 226 | injector::MakeCALL(GetTextureInfo_Hook_Addr_41, ReplaceTexture, true); 227 | injector::MakeCALL(GetTextureInfo_Hook_Addr_42, ReplaceTexture, true); 228 | injector::MakeCALL(GetTextureInfo_Hook_Addr_43, ReplaceTexture, true); 229 | injector::MakeCALL(GetTextureInfo_Hook_Addr_44, ReplaceTexture, true); 230 | injector::MakeCALL(GetTextureInfo_Hook_Addr_45, ReplaceTexture, true); 231 | injector::MakeCALL(GetTextureInfo_Hook_Addr_46, ReplaceTexture, true); 232 | injector::MakeCALL(GetTextureInfo_Hook_Addr_47, ReplaceTexture, true); 233 | injector::MakeCALL(GetTextureInfo_Hook_Addr_48, ReplaceTexture, true); 234 | injector::MakeCALL(GetTextureInfo_Hook_Addr_49, ReplaceTexture, true); 235 | injector::MakeCALL(GetTextureInfo_Hook_Addr_50, ReplaceTexture, true); 236 | injector::MakeCALL(GetTextureInfo_Hook_Addr_51, ReplaceTexture, true); 237 | injector::MakeCALL(GetTextureInfo_Hook_Addr_52, ReplaceTexture, true); 238 | injector::MakeCALL(GetTextureInfo_Hook_Addr_53, ReplaceTexture, true); 239 | injector::MakeCALL(GetTextureInfo_Hook_Addr_54, ReplaceTexture, true); 240 | injector::MakeCALL(GetTextureInfo_Hook_Addr_55, ReplaceTexture, true); 241 | injector::MakeCALL(GetTextureInfo_Hook_Addr_56, ReplaceTexture, true); 242 | injector::MakeCALL(GetTextureInfo_Hook_Addr_57, ReplaceTexture, true); 243 | injector::MakeCALL(GetTextureInfo_Hook_Addr_58, ReplaceTexture, true); 244 | injector::MakeCALL(GetTextureInfo_Hook_Addr_59, ReplaceTexture, true); 245 | injector::MakeCALL(GetTextureInfo_Hook_Addr_60, ReplaceTexture, true); 246 | injector::MakeCALL(GetTextureInfo_Hook_Addr_61, ReplaceTexture, true); 247 | injector::MakeCALL(GetTextureInfo_Hook_Addr_62, ReplaceTexture, true); 248 | injector::MakeCALL(GetTextureInfo_Hook_Addr_63, ReplaceTexture, true); 249 | injector::MakeCALL(GetTextureInfo_Hook_Addr_64, ReplaceTexture, true); 250 | injector::MakeCALL(GetTextureInfo_Hook_Addr_65, ReplaceTexture, true); 251 | 252 | #if (defined (GAME_PS) ||defined (GAME_CARBON) || defined (GAME_MW) || defined (GAME_UG2)) 253 | injector::MakeCALL(GetTextureInfo_Hook_Addr_66, ReplaceTexture, true); 254 | injector::MakeCALL(GetTextureInfo_Hook_Addr_67, ReplaceTexture, true); 255 | injector::MakeCALL(GetTextureInfo_Hook_Addr_68, ReplaceTexture, true); 256 | injector::MakeCALL(GetTextureInfo_Hook_Addr_69, ReplaceTexture, true); 257 | injector::MakeCALL(GetTextureInfo_Hook_Addr_70, ReplaceTexture, true); 258 | injector::MakeCALL(GetTextureInfo_Hook_Addr_71, ReplaceTexture, true); 259 | injector::MakeCALL(GetTextureInfo_Hook_Addr_72, ReplaceTexture, true); 260 | injector::MakeCALL(GetTextureInfo_Hook_Addr_73, ReplaceTexture, true); 261 | injector::MakeCALL(GetTextureInfo_Hook_Addr_74, ReplaceTexture, true); 262 | injector::MakeCALL(GetTextureInfo_Hook_Addr_75, ReplaceTexture, true); 263 | injector::MakeCALL(GetTextureInfo_Hook_Addr_76, ReplaceTexture, true); 264 | injector::MakeCALL(GetTextureInfo_Hook_Addr_77, ReplaceTexture, true); 265 | injector::MakeCALL(GetTextureInfo_Hook_Addr_78, ReplaceTexture, true); 266 | injector::MakeCALL(GetTextureInfo_Hook_Addr_79, ReplaceTexture, true); 267 | injector::MakeCALL(GetTextureInfo_Hook_Addr_80, ReplaceTexture, true); 268 | injector::MakeCALL(GetTextureInfo_Hook_Addr_81, ReplaceTexture, true); 269 | #endif 270 | 271 | #if (defined (GAME_PS) ||defined (GAME_CARBON)) 272 | 273 | injector::MakeCALL(GetTextureInfo_Hook_Addr_82, ReplaceTexture, true); 274 | injector::MakeCALL(GetTextureInfo_Hook_Addr_83, ReplaceTexture, true); 275 | injector::MakeCALL(GetTextureInfo_Hook_Addr_84, ReplaceTexture, true); 276 | injector::MakeCALL(GetTextureInfo_Hook_Addr_85, ReplaceTexture, true); 277 | injector::MakeCALL(GetTextureInfo_Hook_Addr_86, ReplaceTexture, true); 278 | injector::MakeCALL(GetTextureInfo_Hook_Addr_87, ReplaceTexture, true); 279 | injector::MakeCALL(GetTextureInfo_Hook_Addr_88, ReplaceTexture, true); 280 | injector::MakeCALL(GetTextureInfo_Hook_Addr_89, ReplaceTexture, true); 281 | injector::MakeCALL(GetTextureInfo_Hook_Addr_90, ReplaceTexture, true); 282 | injector::MakeCALL(GetTextureInfo_Hook_Addr_91, ReplaceTexture, true); 283 | injector::MakeCALL(GetTextureInfo_Hook_Addr_92, ReplaceTexture, true); 284 | injector::MakeCALL(GetTextureInfo_Hook_Addr_93, ReplaceTexture, true); 285 | injector::MakeCALL(GetTextureInfo_Hook_Addr_94, ReplaceTexture, true); 286 | injector::MakeCALL(GetTextureInfo_Hook_Addr_95, ReplaceTexture, true); 287 | injector::MakeCALL(GetTextureInfo_Hook_Addr_96, ReplaceTexture, true); 288 | injector::MakeCALL(GetTextureInfo_Hook_Addr_97, ReplaceTexture, true); 289 | injector::MakeCALL(GetTextureInfo_Hook_Addr_98, ReplaceTexture, true); 290 | injector::MakeCALL(GetTextureInfo_Hook_Addr_99, ReplaceTexture, true); 291 | injector::MakeCALL(GetTextureInfo_Hook_Addr_100, ReplaceTexture, true); 292 | injector::MakeCALL(GetTextureInfo_Hook_Addr_101, ReplaceTexture, true); 293 | injector::MakeCALL(GetTextureInfo_Hook_Addr_102, ReplaceTexture, true); 294 | injector::MakeCALL(GetTextureInfo_Hook_Addr_103, ReplaceTexture, true); 295 | injector::MakeCALL(GetTextureInfo_Hook_Addr_104, ReplaceTexture, true); 296 | injector::MakeCALL(GetTextureInfo_Hook_Addr_105, ReplaceTexture, true); 297 | 298 | #endif 299 | 300 | #ifdef GAME_PS 301 | injector::WriteMemory(GetTextureInfo_Hook_Addr_106P, &ReplaceTexture, true); 302 | injector::WriteMemory(GetTextureInfo_Hook_Addr_107P, &ReplaceTexture, true); 303 | injector::MakeJMP(GetTextureInfo_Hook_Addr_108J, ReplaceTexture, true); 304 | injector::MakeJMP(GetTextureInfo_Hook_Addr_109J, ReplaceTexture, true); 305 | #endif 306 | 307 | #ifdef GAME_CARBON 308 | 309 | injector::MakeCALL(GetTextureInfo_Hook_Addr_106, ReplaceTexture, true); 310 | injector::MakeCALL(GetTextureInfo_Hook_Addr_107, ReplaceTexture, true); 311 | injector::MakeCALL(GetTextureInfo_Hook_Addr_108, ReplaceTexture, true); 312 | injector::MakeCALL(GetTextureInfo_Hook_Addr_109, ReplaceTexture, true); 313 | injector::MakeCALL(GetTextureInfo_Hook_Addr_110, ReplaceTexture, true); 314 | injector::MakeCALL(GetTextureInfo_Hook_Addr_111, ReplaceTexture, true); 315 | injector::MakeCALL(GetTextureInfo_Hook_Addr_112, ReplaceTexture, true); 316 | injector::MakeCALL(GetTextureInfo_Hook_Addr_113, ReplaceTexture, true); 317 | injector::MakeCALL(GetTextureInfo_Hook_Addr_114, ReplaceTexture, true); 318 | injector::MakeCALL(GetTextureInfo_Hook_Addr_115, ReplaceTexture, true); 319 | injector::MakeCALL(GetTextureInfo_Hook_Addr_116, ReplaceTexture, true); 320 | injector::MakeCALL(GetTextureInfo_Hook_Addr_117, ReplaceTexture, true); 321 | injector::MakeCALL(GetTextureInfo_Hook_Addr_118, ReplaceTexture, true); 322 | injector::MakeCALL(GetTextureInfo_Hook_Addr_119, ReplaceTexture, true); 323 | injector::MakeCALL(GetTextureInfo_Hook_Addr_120, ReplaceTexture, true); 324 | injector::MakeCALL(GetTextureInfo_Hook_Addr_121, ReplaceTexture, true); 325 | injector::MakeCALL(GetTextureInfo_Hook_Addr_122, ReplaceTexture, true); 326 | injector::MakeCALL(GetTextureInfo_Hook_Addr_123, ReplaceTexture, true); 327 | injector::MakeCALL(GetTextureInfo_Hook_Addr_124, ReplaceTexture, true); 328 | injector::MakeCALL(GetTextureInfo_Hook_Addr_125, ReplaceTexture, true); 329 | injector::MakeCALL(GetTextureInfo_Hook_Addr_126, ReplaceTexture, true); 330 | injector::MakeCALL(GetTextureInfo_Hook_Addr_127, ReplaceTexture, true); 331 | injector::MakeCALL(GetTextureInfo_Hook_Addr_128, ReplaceTexture, true); 332 | injector::MakeCALL(GetTextureInfo_Hook_Addr_129, ReplaceTexture, true); 333 | injector::MakeCALL(GetTextureInfo_Hook_Addr_130, ReplaceTexture, true); 334 | injector::MakeCALL(GetTextureInfo_Hook_Addr_131, ReplaceTexture, true); 335 | injector::MakeCALL(GetTextureInfo_Hook_Addr_132, ReplaceTexture, true); 336 | injector::MakeCALL(GetTextureInfo_Hook_Addr_133, ReplaceTexture, true); 337 | injector::MakeCALL(GetTextureInfo_Hook_Addr_134, ReplaceTexture, true); 338 | injector::MakeCALL(GetTextureInfo_Hook_Addr_135, ReplaceTexture, true); 339 | injector::MakeCALL(GetTextureInfo_Hook_Addr_136, ReplaceTexture, true); 340 | injector::MakeCALL(GetTextureInfo_Hook_Addr_137, ReplaceTexture, true); 341 | injector::MakeCALL(GetTextureInfo_Hook_Addr_138, ReplaceTexture, true); 342 | injector::MakeCALL(GetTextureInfo_Hook_Addr_139, ReplaceTexture, true); 343 | injector::MakeCALL(GetTextureInfo_Hook_Addr_140, ReplaceTexture, true); 344 | injector::MakeCALL(GetTextureInfo_Hook_Addr_141, ReplaceTexture, true); 345 | injector::MakeCALL(GetTextureInfo_Hook_Addr_142, ReplaceTexture, true); 346 | injector::MakeCALL(GetTextureInfo_Hook_Addr_143, ReplaceTexture, true); 347 | injector::MakeCALL(GetTextureInfo_Hook_Addr_144, ReplaceTexture, true); 348 | injector::MakeCALL(GetTextureInfo_Hook_Addr_145, ReplaceTexture, true); 349 | injector::MakeCALL(GetTextureInfo_Hook_Addr_146, ReplaceTexture, true); 350 | injector::MakeCALL(GetTextureInfo_Hook_Addr_147, ReplaceTexture, true); 351 | injector::MakeCALL(GetTextureInfo_Hook_Addr_148, ReplaceTexture, true); 352 | injector::MakeCALL(GetTextureInfo_Hook_Addr_149, ReplaceTexture, true); 353 | injector::MakeCALL(GetTextureInfo_Hook_Addr_150, ReplaceTexture, true); 354 | injector::MakeCALL(GetTextureInfo_Hook_Addr_151, ReplaceTexture, true); 355 | injector::MakeCALL(GetTextureInfo_Hook_Addr_152, ReplaceTexture, true); 356 | injector::MakeCALL(GetTextureInfo_Hook_Addr_153, ReplaceTexture, true); 357 | injector::MakeCALL(GetTextureInfo_Hook_Addr_154, ReplaceTexture, true); 358 | injector::MakeCALL(GetTextureInfo_Hook_Addr_155, ReplaceTexture, true); 359 | injector::MakeCALL(GetTextureInfo_Hook_Addr_156, ReplaceTexture, true); 360 | 361 | #endif 362 | 363 | #endif 364 | } -------------------------------------------------------------------------------- /TexWizard.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.4.33122.133 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TexWizard", "TexWizard.vcxproj", "{3C558AD9-5F9C-4A14-8F07-800F46C132C7}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug_Carbon|Win32 = Debug_Carbon|Win32 11 | Debug_MW|Win32 = Debug_MW|Win32 12 | Debug_PS|Win32 = Debug_PS|Win32 13 | Debug_UC|Win32 = Debug_UC|Win32 14 | Debug_UG|Win32 = Debug_UG|Win32 15 | Debug_UG2|Win32 = Debug_UG2|Win32 16 | Release_Carbon|Win32 = Release_Carbon|Win32 17 | Release_MW|Win32 = Release_MW|Win32 18 | Release_PS|Win32 = Release_PS|Win32 19 | Release_UC|Win32 = Release_UC|Win32 20 | Release_UG|Win32 = Release_UG|Win32 21 | Release_UG2|Win32 = Release_UG2|Win32 22 | EndGlobalSection 23 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 24 | {3C558AD9-5F9C-4A14-8F07-800F46C132C7}.Debug_Carbon|Win32.ActiveCfg = Debug_Carbon|Win32 25 | {3C558AD9-5F9C-4A14-8F07-800F46C132C7}.Debug_Carbon|Win32.Build.0 = Debug_Carbon|Win32 26 | {3C558AD9-5F9C-4A14-8F07-800F46C132C7}.Debug_MW|Win32.ActiveCfg = Debug_MW|Win32 27 | {3C558AD9-5F9C-4A14-8F07-800F46C132C7}.Debug_MW|Win32.Build.0 = Debug_MW|Win32 28 | {3C558AD9-5F9C-4A14-8F07-800F46C132C7}.Debug_PS|Win32.ActiveCfg = Debug_PS|Win32 29 | {3C558AD9-5F9C-4A14-8F07-800F46C132C7}.Debug_PS|Win32.Build.0 = Debug_PS|Win32 30 | {3C558AD9-5F9C-4A14-8F07-800F46C132C7}.Debug_UC|Win32.ActiveCfg = Debug_UC|Win32 31 | {3C558AD9-5F9C-4A14-8F07-800F46C132C7}.Debug_UC|Win32.Build.0 = Debug_UC|Win32 32 | {3C558AD9-5F9C-4A14-8F07-800F46C132C7}.Debug_UG|Win32.ActiveCfg = Debug_UG|Win32 33 | {3C558AD9-5F9C-4A14-8F07-800F46C132C7}.Debug_UG|Win32.Build.0 = Debug_UG|Win32 34 | {3C558AD9-5F9C-4A14-8F07-800F46C132C7}.Debug_UG2|Win32.ActiveCfg = Debug_UG2|Win32 35 | {3C558AD9-5F9C-4A14-8F07-800F46C132C7}.Debug_UG2|Win32.Build.0 = Debug_UG2|Win32 36 | {3C558AD9-5F9C-4A14-8F07-800F46C132C7}.Release_Carbon|Win32.ActiveCfg = Release_Carbon|Win32 37 | {3C558AD9-5F9C-4A14-8F07-800F46C132C7}.Release_Carbon|Win32.Build.0 = Release_Carbon|Win32 38 | {3C558AD9-5F9C-4A14-8F07-800F46C132C7}.Release_MW|Win32.ActiveCfg = Release_MW|Win32 39 | {3C558AD9-5F9C-4A14-8F07-800F46C132C7}.Release_MW|Win32.Build.0 = Release_MW|Win32 40 | {3C558AD9-5F9C-4A14-8F07-800F46C132C7}.Release_PS|Win32.ActiveCfg = Release_PS|Win32 41 | {3C558AD9-5F9C-4A14-8F07-800F46C132C7}.Release_PS|Win32.Build.0 = Release_PS|Win32 42 | {3C558AD9-5F9C-4A14-8F07-800F46C132C7}.Release_UC|Win32.ActiveCfg = Release_UC|Win32 43 | {3C558AD9-5F9C-4A14-8F07-800F46C132C7}.Release_UC|Win32.Build.0 = Release_UC|Win32 44 | {3C558AD9-5F9C-4A14-8F07-800F46C132C7}.Release_UG|Win32.ActiveCfg = Release_UG|Win32 45 | {3C558AD9-5F9C-4A14-8F07-800F46C132C7}.Release_UG|Win32.Build.0 = Release_UG|Win32 46 | {3C558AD9-5F9C-4A14-8F07-800F46C132C7}.Release_UG2|Win32.ActiveCfg = Release_UG2|Win32 47 | {3C558AD9-5F9C-4A14-8F07-800F46C132C7}.Release_UG2|Win32.Build.0 = Release_UG2|Win32 48 | EndGlobalSection 49 | GlobalSection(SolutionProperties) = preSolution 50 | HideSolutionNode = FALSE 51 | EndGlobalSection 52 | GlobalSection(ExtensibilityGlobals) = postSolution 53 | SolutionGuid = {9ADB3677-48BB-4E65-A3B5-22CF0510D47D} 54 | EndGlobalSection 55 | EndGlobal 56 | -------------------------------------------------------------------------------- /TexWizard.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug_Carbon 6 | Win32 7 | 8 | 9 | Debug_MW 10 | Win32 11 | 12 | 13 | Debug_PS 14 | Win32 15 | 16 | 17 | Debug_UC 18 | Win32 19 | 20 | 21 | Debug_UG2 22 | Win32 23 | 24 | 25 | Debug_UG 26 | Win32 27 | 28 | 29 | Release_Carbon 30 | Win32 31 | 32 | 33 | Release_MW 34 | Win32 35 | 36 | 37 | Release_PS 38 | Win32 39 | 40 | 41 | Release_UC 42 | Win32 43 | 44 | 45 | Release_UG2 46 | Win32 47 | 48 | 49 | Release_UG 50 | Win32 51 | 52 | 53 | 54 | {3C558AD9-5F9C-4A14-8F07-800F46C132C7} 55 | Win32Proj 56 | TexWizard 57 | TexWizard 58 | 10.0 59 | 60 | 61 | 62 | DynamicLibrary 63 | true 64 | v143 65 | MultiByte 66 | 67 | 68 | DynamicLibrary 69 | true 70 | v143 71 | MultiByte 72 | 73 | 74 | DynamicLibrary 75 | true 76 | v143 77 | MultiByte 78 | 79 | 80 | DynamicLibrary 81 | true 82 | v143 83 | MultiByte 84 | 85 | 86 | DynamicLibrary 87 | true 88 | v143 89 | MultiByte 90 | 91 | 92 | DynamicLibrary 93 | true 94 | v143 95 | MultiByte 96 | 97 | 98 | DynamicLibrary 99 | false 100 | v143 101 | true 102 | MultiByte 103 | 104 | 105 | DynamicLibrary 106 | false 107 | v143 108 | true 109 | MultiByte 110 | 111 | 112 | DynamicLibrary 113 | false 114 | v143 115 | true 116 | MultiByte 117 | 118 | 119 | DynamicLibrary 120 | false 121 | v143 122 | true 123 | MultiByte 124 | 125 | 126 | DynamicLibrary 127 | false 128 | v143 129 | true 130 | MultiByte 131 | 132 | 133 | DynamicLibrary 134 | false 135 | v143 136 | true 137 | MultiByte 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | true 181 | .asi 182 | $(ProjectName) 183 | 184 | 185 | true 186 | .asi 187 | $(ProjectName) 188 | 189 | 190 | true 191 | .asi 192 | $(ProjectName) 193 | 194 | 195 | true 196 | .asi 197 | $(ProjectName) 198 | 199 | 200 | true 201 | .asi 202 | $(ProjectName) 203 | 204 | 205 | true 206 | .asi 207 | $(ProjectName) 208 | 209 | 210 | false 211 | .asi 212 | $(SolutionDir)$(Configuration)\$(ProjectName)\scripts\ 213 | TexWizard 214 | 215 | 216 | false 217 | .asi 218 | $(SolutionDir)$(Configuration)\$(ProjectName)\scripts\ 219 | TexWizard 220 | 221 | 222 | false 223 | .asi 224 | $(SolutionDir)$(Configuration)\$(ProjectName)\scripts\ 225 | TexWizard 226 | 227 | 228 | false 229 | .asi 230 | $(SolutionDir)$(Configuration)\$(ProjectName)\scripts\ 231 | TexWizard 232 | 233 | 234 | false 235 | .asi 236 | $(SolutionDir)$(Configuration)\$(ProjectName)\scripts\ 237 | TexWizard 238 | 239 | 240 | false 241 | .asi 242 | $(SolutionDir)$(Configuration)\$(ProjectName)\scripts\ 243 | TexWizard 244 | 245 | 246 | 247 | Use 248 | Level3 249 | Disabled 250 | WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;GAME_MW;%(PreprocessorDefinitions) 251 | MultiThreadedDebug 252 | 253 | 254 | Windows 255 | true 256 | 257 | 258 | copy "$(TargetDir)*.asi" "G:\Oyunlar\Need for Speed Most Wanted Dirty\scripts" /y 259 | copy "$(TargetDir)*.pdb" "G:\Oyunlar\Need for Speed Most Wanted Dirty\scripts" /y 260 | 261 | 262 | 263 | 264 | Use 265 | Level3 266 | Disabled 267 | WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;GAME_UG2;%(PreprocessorDefinitions) 268 | MultiThreadedDebug 269 | 270 | 271 | Windows 272 | true 273 | 274 | 275 | copy "$(TargetDir)*.asi" "G:\Games\Need for Speed Underground 2\scripts" /y 276 | copy "$(TargetDir)*.pdb" "G:\Games\Need for Speed Underground 2\scripts" /y 277 | 278 | 279 | 280 | 281 | Use 282 | Level3 283 | Disabled 284 | WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;GAME_UG;%(PreprocessorDefinitions) 285 | MultiThreadedDebug 286 | 287 | 288 | Windows 289 | true 290 | 291 | 292 | copy "$(TargetDir)*.asi" "G:\Games\Need for Speed Underground\scripts" /y 293 | copy "$(TargetDir)*.pdb" "G:\Games\Need for Speed Underground\scripts" /y 294 | 295 | 296 | 297 | 298 | Use 299 | Level3 300 | Disabled 301 | WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;GAME_CARBON;%(PreprocessorDefinitions) 302 | MultiThreadedDebug 303 | 304 | 305 | Windows 306 | true 307 | 308 | 309 | copy "$(TargetDir)*.asi" "G:\Oyunlar\Need for Speed Carbon Dirty\scripts" /y 310 | copy "$(TargetDir)*.pdb" "G:\Oyunlar\Need for Speed Carbon Dirty\scripts" /y 311 | 312 | 313 | 314 | 315 | Use 316 | Level3 317 | Disabled 318 | WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;GAME_PS;%(PreprocessorDefinitions) 319 | MultiThreadedDebug 320 | 321 | 322 | Windows 323 | true 324 | 325 | 326 | copy "$(TargetDir)*.asi" "G:\Oyunlar\Need for Speed ProStreet\scripts" /y 327 | copy "$(TargetDir)*.pdb" "G:\Oyunlar\Need for Speed ProStreet\scripts" /y 328 | 329 | 330 | 331 | 332 | Use 333 | Level3 334 | Disabled 335 | WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;GAME_UC;%(PreprocessorDefinitions) 336 | MultiThreadedDebug 337 | 338 | 339 | Windows 340 | true 341 | 342 | 343 | copy "$(TargetDir)*.asi" "G:\Oyunlar\Need for Speed Undercover\scripts" /y 344 | copy "$(TargetDir)*.pdb" "G:\Oyunlar\Need for Speed Undercover\scripts" /y 345 | 346 | 347 | 348 | 349 | Level4 350 | Use 351 | MaxSpeed 352 | true 353 | true 354 | WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;GAME_MW;%(PreprocessorDefinitions) 355 | MultiThreaded 356 | 357 | 358 | Windows 359 | true 360 | true 361 | true 362 | 363 | 364 | copy "$(TargetDir)*.asi" "G:\Oyunlar\Need for Speed Most Wanted Dirty\scripts" /y 365 | 366 | 367 | 368 | 369 | Level4 370 | Use 371 | MaxSpeed 372 | true 373 | true 374 | WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;GAME_UG2;%(PreprocessorDefinitions) 375 | MultiThreaded 376 | 377 | 378 | Windows 379 | true 380 | true 381 | true 382 | 383 | 384 | copy "$(TargetDir)*.asi" "G:\Games\Need for Speed Underground 2\scripts" /y 385 | 386 | 387 | 388 | 389 | Level4 390 | Use 391 | MaxSpeed 392 | true 393 | true 394 | WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;GAME_UG;%(PreprocessorDefinitions) 395 | MultiThreaded 396 | 397 | 398 | Windows 399 | true 400 | true 401 | true 402 | 403 | 404 | copy "$(TargetDir)*.asi" "G:\Games\Need for Speed Underground\scripts" /y 405 | 406 | 407 | 408 | 409 | Level4 410 | Use 411 | MaxSpeed 412 | true 413 | true 414 | WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;GAME_CARBON;%(PreprocessorDefinitions) 415 | MultiThreaded 416 | 417 | 418 | Windows 419 | true 420 | true 421 | true 422 | 423 | 424 | copy "$(TargetDir)*.asi" "G:\Oyunlar\Need for Speed Carbon Dirty\scripts" /y 425 | 426 | 427 | 428 | 429 | Level4 430 | Use 431 | MaxSpeed 432 | true 433 | true 434 | WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;GAME_PS;%(PreprocessorDefinitions) 435 | MultiThreaded 436 | 437 | 438 | Windows 439 | true 440 | true 441 | true 442 | 443 | 444 | copy "$(TargetDir)*.asi" "G:\Oyunlar\Need for Speed ProStreet\scripts" /y 445 | 446 | 447 | 448 | 449 | Level4 450 | Use 451 | MaxSpeed 452 | true 453 | true 454 | WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;GAME_UC;%(PreprocessorDefinitions) 455 | MultiThreaded 456 | 457 | 458 | Windows 459 | true 460 | true 461 | true 462 | 463 | 464 | copy "$(TargetDir)*.asi" "G:\Oyunlar\Need for Speed Undercover\scripts" /y 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | false 482 | false 483 | false 484 | false 485 | false 486 | false 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | false 500 | false 501 | false 502 | false 503 | false 504 | false 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | NotUsing 520 | NotUsing 521 | NotUsing 522 | NotUsing 523 | NotUsing 524 | NotUsing 525 | NotUsing 526 | NotUsing 527 | NotUsing 528 | NotUsing 529 | NotUsing 530 | NotUsing 531 | 532 | 533 | Create 534 | Create 535 | Create 536 | Create 537 | Create 538 | Create 539 | Create 540 | Create 541 | Create 542 | Create 543 | Create 544 | Create 545 | 546 | 547 | 548 | 549 | 550 | -------------------------------------------------------------------------------- /TexWizard.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | G:\Oyunlar\Need for Speed Carbon Dirty\NFSC.exe 5 | G:\Oyunlar\Need for Speed Carbon Dirty 6 | WindowsLocalDebugger 7 | 8 | 9 | G:\Oyunlar\Need for Speed ProStreet\NFS.exe 10 | G:\Oyunlar\Need for Speed ProStreet 11 | WindowsLocalDebugger 12 | 13 | 14 | G:\Oyunlar\Need for Speed Undercover\NFS.exe 15 | G:\Oyunlar\Need for Speed Undercover 16 | WindowsLocalDebugger 17 | 18 | 19 | G:\Oyunlar\Need for Speed Carbon Dirty\NFSC.exe 20 | G:\Oyunlar\Need for Speed Carbon Dirty 21 | WindowsLocalDebugger 22 | 23 | 24 | G:\Oyunlar\Need for Speed ProStreet\NFS.exe 25 | G:\Oyunlar\Need for Speed ProStreet 26 | WindowsLocalDebugger 27 | 28 | 29 | G:\Oyunlar\Need for Speed Undercover\NFS.exe 30 | G:\Oyunlar\Need for Speed Undercover 31 | WindowsLocalDebugger 32 | 33 | 34 | G:\Games\Need for Speed Underground 2\SPEED2.EXE 35 | G:\Games\Need for Speed Underground 2 36 | WindowsLocalDebugger 37 | 38 | 39 | G:\Games\Need for Speed Underground\SPEED.EXE 40 | G:\Games\Need for Speed Underground 41 | WindowsLocalDebugger 42 | 43 | 44 | G:\Games\Need for Speed Underground 2\SPEED2.EXE 45 | G:\Games\Need for Speed Underground 2 46 | WindowsLocalDebugger 47 | 48 | 49 | G:\Games\Need for Speed Underground\SPEED.EXE 50 | G:\Games\Need for Speed Underground 51 | WindowsLocalDebugger 52 | 53 | -------------------------------------------------------------------------------- /UC_Address.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef GAME_UC 3 | #define GAME_UC 4 | #endif 5 | 6 | #define EntryPoint 0x8AEC55 7 | #define WrongEntryPointErrorString "This .exe is not supported.\nPlease use v1.0.0.1 STEAM nfs.exe (10,0 MB (10.584.064 bytes))." 8 | 9 | #define bStringHash_Addr 0x4B3ED0 10 | #define CreateResourceFile_Addr 0x6AC350 11 | #define ResourceFileBeginLoading_Addr 0x6AE570 12 | #define LoadGlobalAChunks_Addr 0x6AE680 13 | #define GetTextureInfo_Addr 0x53CF30 14 | 15 | #define SharedStringPoolAllocate_Addr 0x4B4BA0 16 | 17 | #define LoadGlobalAChunks_Hook_Addr_1 0x6AF043 18 | 19 | #define GetTextureInfo_Hook_Addr_1J 0x53DF50 20 | #define GetTextureInfo_Hook_Addr_2 0x53DF98 21 | #define GetTextureInfo_Hook_Addr_3 0x53DFAB 22 | #define GetTextureInfo_Hook_Addr_4 0x53DFBE 23 | #define GetTextureInfo_Hook_Addr_5 0x53DFD1 24 | #define GetTextureInfo_Hook_Addr_6 0x53DFE4 25 | #define GetTextureInfo_Hook_Addr_7 0x53EA93 26 | #define GetTextureInfo_Hook_Addr_8 0x53EDAD 27 | #define GetTextureInfo_Hook_Addr_9 0x53F172 28 | #define GetTextureInfo_Hook_Addr_10 0x53F3E9 29 | #define GetTextureInfo_Hook_Addr_11 0x53F439 30 | #define GetTextureInfo_Hook_Addr_12 0x53F508 31 | #define GetTextureInfo_Hook_Addr_13 0x53F5FF 32 | 33 | unsigned int(*bStringHash)(char* StringToHash) = (unsigned int(*)(char*))bStringHash_Addr; 34 | 35 | DWORD* (__cdecl* CreateResourceFile)(int a1, int a2, int a3, int a4, int a5) = (DWORD * (__cdecl*)(int, int, int, int, int))CreateResourceFile_Addr; 36 | int(__thiscall* ResourceFileBeginLoading)(DWORD* r, int unk1, int unk2) = (int(__thiscall*)(DWORD*, int, int))ResourceFileBeginLoading_Addr; 37 | 38 | int(__fastcall* LoadGlobalAChunks)() = (int(__fastcall*)())LoadGlobalAChunks_Addr; 39 | 40 | DWORD* (__cdecl* GetTextureInfo)(unsigned int hash, int returnDefault, int includeUnloadedTextures) = (DWORD * (__cdecl*)(unsigned int, int, int))GetTextureInfo_Addr; 41 | 42 | unsigned int(*SharedStringPoolAllocate)(const char* String) = (unsigned int(*)(const char*))SharedStringPoolAllocate_Addr; -------------------------------------------------------------------------------- /UG2_Address.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef GAME_UG2 3 | #define GAME_UG2 4 | #endif 5 | 6 | #define EntryPoint 0x75BCC7 7 | #define WrongEntryPointErrorString "This .exe is not supported.\nPlease use v1.2 NTSC speed2.exe (4,57 MB (4.800.512 bytes))." 8 | 9 | #define bStringHash_Addr 0x43DB50 10 | #define CreateResourceFile_Addr 0x57CEF0 11 | #define ResourceFileBeginLoading_Addr 0x57BD70 12 | #define LoadGlobalChunks_Addr 0x57FB40 13 | #define GetTextureInfo_Addr 0x4901D0 14 | 15 | 16 | #define LoadGlobalChunks_Hook_Addr_1 0x57ED99 17 | 18 | #define GetTextureInfo_Hook_Addr_1 0x4398C8 19 | #define GetTextureInfo_Hook_Addr_2 0x44823E 20 | #define GetTextureInfo_Hook_Addr_3 0x448252 21 | #define GetTextureInfo_Hook_Addr_4 0x448266 22 | #define GetTextureInfo_Hook_Addr_5 0x490319 23 | #define GetTextureInfo_Hook_Addr_6 0x49034A 24 | #define GetTextureInfo_Hook_Addr_7 0x49035D 25 | #define GetTextureInfo_Hook_Addr_8 0x490370 26 | #define GetTextureInfo_Hook_Addr_9 0x490383 27 | #define GetTextureInfo_Hook_Addr_10 0x490396 28 | #define GetTextureInfo_Hook_Addr_11 0x4905E0 29 | #define GetTextureInfo_Hook_Addr_12 0x4907C5 30 | #define GetTextureInfo_Hook_Addr_13 0x490897 31 | #define GetTextureInfo_Hook_Addr_14 0x4908FE 32 | #define GetTextureInfo_Hook_Addr_15 0x49126D 33 | #define GetTextureInfo_Hook_Addr_16 0x491CCE 34 | #define GetTextureInfo_Hook_Addr_17 0x495DA5 35 | #define GetTextureInfo_Hook_Addr_18 0x4A2430 36 | #define GetTextureInfo_Hook_Addr_19 0x4A2479 37 | #define GetTextureInfo_Hook_Addr_20 0x4A5375 38 | #define GetTextureInfo_Hook_Addr_21 0x4AFE22 39 | #define GetTextureInfo_Hook_Addr_22 0x4AFE78 40 | #define GetTextureInfo_Hook_Addr_23 0x4B0358 41 | #define GetTextureInfo_Hook_Addr_24 0x4B2560 42 | #define GetTextureInfo_Hook_Addr_25 0x4B25B6 43 | #define GetTextureInfo_Hook_Addr_26 0x4B53B0 44 | #define GetTextureInfo_Hook_Addr_27 0x4BE463 45 | #define GetTextureInfo_Hook_Addr_28 0x4BE4B9 46 | #define GetTextureInfo_Hook_Addr_29 0x4C6704 47 | #define GetTextureInfo_Hook_Addr_30 0x4C67F4 48 | #define GetTextureInfo_Hook_Addr_31 0x4CDDBD 49 | #define GetTextureInfo_Hook_Addr_32 0x4CDF5A 50 | #define GetTextureInfo_Hook_Addr_33 0x4F68ED 51 | #define GetTextureInfo_Hook_Addr_34 0x50B50F 52 | #define GetTextureInfo_Hook_Addr_35 0x50BBF2 53 | #define GetTextureInfo_Hook_Addr_36 0x50CB7E 54 | #define GetTextureInfo_Hook_Addr_37 0x50CC3E 55 | #define GetTextureInfo_Hook_Addr_38 0x5109FE 56 | #define GetTextureInfo_Hook_Addr_39 0x510A1D 57 | #define GetTextureInfo_Hook_Addr_40 0x510A39 58 | #define GetTextureInfo_Hook_Addr_41 0x510A55 59 | #define GetTextureInfo_Hook_Addr_42 0x51BEFC 60 | #define GetTextureInfo_Hook_Addr_43 0x53688A 61 | #define GetTextureInfo_Hook_Addr_44 0x536ADE 62 | #define GetTextureInfo_Hook_Addr_45 0x536D0E 63 | #define GetTextureInfo_Hook_Addr_46 0x53B9B0 64 | #define GetTextureInfo_Hook_Addr_47 0x57FBFA 65 | #define GetTextureInfo_Hook_Addr_48 0x5B98C2 66 | #define GetTextureInfo_Hook_Addr_49 0x5B98E1 67 | #define GetTextureInfo_Hook_Addr_50 0x5B9900 68 | #define GetTextureInfo_Hook_Addr_51 0x5B993C 69 | #define GetTextureInfo_Hook_Addr_52 0x5B995A 70 | #define GetTextureInfo_Hook_Addr_53 0x5B9978 71 | #define GetTextureInfo_Hook_Addr_54 0x5B9996 72 | #define GetTextureInfo_Hook_Addr_55 0x5B99B4 73 | #define GetTextureInfo_Hook_Addr_56 0x5B99D2 74 | #define GetTextureInfo_Hook_Addr_57 0x5BC706 75 | #define GetTextureInfo_Hook_Addr_58 0x5BC8B0 76 | #define GetTextureInfo_Hook_Addr_59 0x5BCA2A 77 | #define GetTextureInfo_Hook_Addr_60 0x5C5762 78 | #define GetTextureInfo_Hook_Addr_61 0x5C73C8 79 | #define GetTextureInfo_Hook_Addr_62 0x5C7BDC 80 | #define GetTextureInfo_Hook_Addr_63 0x5CBB46 81 | #define GetTextureInfo_Hook_Addr_64 0x5CF6A1 82 | #define GetTextureInfo_Hook_Addr_65 0x5D32AA 83 | #define GetTextureInfo_Hook_Addr_66 0x60C7F5 84 | #define GetTextureInfo_Hook_Addr_67 0x613074 85 | #define GetTextureInfo_Hook_Addr_68 0x613092 86 | #define GetTextureInfo_Hook_Addr_69 0x61D7AD 87 | #define GetTextureInfo_Hook_Addr_70 0x61DAA7 88 | #define GetTextureInfo_Hook_Addr_71 0x61DB0A 89 | #define GetTextureInfo_Hook_Addr_72 0x61DE9D 90 | #define GetTextureInfo_Hook_Addr_73 0x61DED3 91 | #define GetTextureInfo_Hook_Addr_74 0x61DEE3 92 | #define GetTextureInfo_Hook_Addr_75 0x62064A 93 | #define GetTextureInfo_Hook_Addr_76 0x638700 94 | #define GetTextureInfo_Hook_Addr_77 0x638713 95 | #define GetTextureInfo_Hook_Addr_78 0x638827 96 | #define GetTextureInfo_Hook_Addr_79 0x638858 97 | #define GetTextureInfo_Hook_Addr_80 0x638877 98 | #define GetTextureInfo_Hook_Addr_81 0x638889 99 | 100 | unsigned int(*bStringHash)(char* StringToHash) = (unsigned int(*)(char*))bStringHash_Addr; 101 | 102 | DWORD* (__cdecl* CreateResourceFile)(int a1, int a2, int a3, int a4, int a5) = (DWORD * (__cdecl*)(int, int, int, int, int))CreateResourceFile_Addr; 103 | int(__thiscall* ResourceFileBeginLoading)(DWORD* r, int unk1, int unk2) = (int(__thiscall*)(DWORD*, int, int))ResourceFileBeginLoading_Addr; 104 | 105 | int(__fastcall* LoadGlobalChunks)() = (int(__fastcall*)())LoadGlobalChunks_Addr; 106 | 107 | DWORD* (__cdecl* GetTextureInfo)(unsigned int hash, int returnDefault, int includeUnloadedTextures) = (DWORD * (__cdecl*)(unsigned int, int, int))GetTextureInfo_Addr; 108 | -------------------------------------------------------------------------------- /UG_Address.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef GAME_UG 3 | #define GAME_UG 4 | #endif 5 | 6 | #define EntryPoint 0x670CB5 7 | #define WrongEntryPointErrorString "This .exe is not supported.\nPlease use v1.4 English speed.exe (3,03 MB (3.178.496 bytes))." 8 | 9 | #define bStringHash_Addr 0x567C70 // edx 10 | #define CreateResourceFile_Addr 0x4482F0 11 | #define ResourceFileBeginLoading_Addr 0x448110 // edx, eax, ecx 12 | 13 | #define LoadGlobalChunks_Addr 0x448650 14 | #define GetTextureInfo_Addr 0x5461C0 15 | 16 | 17 | #define LoadGlobalChunks_Hook_Addr_1 0x447285 18 | 19 | #define GetTextureInfo_Hook_Addr_1 0x40287E 20 | #define GetTextureInfo_Hook_Addr_2 0x402A40 21 | #define GetTextureInfo_Hook_Addr_3 0x408635 22 | #define GetTextureInfo_Hook_Addr_4 0x408665 23 | #define GetTextureInfo_Hook_Addr_5 0x408695 24 | #define GetTextureInfo_Hook_Addr_6 0x409BB9 25 | #define GetTextureInfo_Hook_Addr_7 0x40E766 26 | #define GetTextureInfo_Hook_Addr_8 0x40E929 27 | #define GetTextureInfo_Hook_Addr_9 0x40EAAC 28 | #define GetTextureInfo_Hook_Addr_10 0x4487B2 29 | #define GetTextureInfo_Hook_Addr_11 0x4800F0 30 | #define GetTextureInfo_Hook_Addr_12 0x480104 31 | #define GetTextureInfo_Hook_Addr_13 0x490690 32 | #define GetTextureInfo_Hook_Addr_14 0x49FF5F 33 | #define GetTextureInfo_Hook_Addr_15 0x4A0E31 34 | #define GetTextureInfo_Hook_Addr_16 0x4A476A 35 | #define GetTextureInfo_Hook_Addr_17 0x4BA304 36 | #define GetTextureInfo_Hook_Addr_18 0x4BB990 37 | #define GetTextureInfo_Hook_Addr_19 0x4BB99F 38 | #define GetTextureInfo_Hook_Addr_20 0x4E22AC 39 | #define GetTextureInfo_Hook_Addr_21 0x4F20EB 40 | #define GetTextureInfo_Hook_Addr_22 0x4F2377 41 | #define GetTextureInfo_Hook_Addr_23 0x4F3161 42 | #define GetTextureInfo_Hook_Addr_24 0x4F464F 43 | #define GetTextureInfo_Hook_Addr_25 0x4F4765 44 | #define GetTextureInfo_Hook_Addr_26 0x4F746B 45 | #define GetTextureInfo_Hook_Addr_27 0x4F752B 46 | #define GetTextureInfo_Hook_Addr_28 0x5072D5 47 | #define GetTextureInfo_Hook_Addr_29 0x51BC24 48 | #define GetTextureInfo_Hook_Addr_30 0x51BC43 49 | #define GetTextureInfo_Hook_Addr_31 0x51BC5F 50 | #define GetTextureInfo_Hook_Addr_32 0x51BC9C 51 | #define GetTextureInfo_Hook_Addr_33 0x51BCB3 52 | #define GetTextureInfo_Hook_Addr_34 0x51BCCA 53 | #define GetTextureInfo_Hook_Addr_35 0x53F580 54 | #define GetTextureInfo_Hook_Addr_36 0x53F9CE 55 | #define GetTextureInfo_Hook_Addr_37 0x53FACD 56 | #define GetTextureInfo_Hook_Addr_38 0x54479E 57 | #define GetTextureInfo_Hook_Addr_39 0x545FC9 58 | #define GetTextureInfo_Hook_Addr_40 0x546029 59 | #define GetTextureInfo_Hook_Addr_41 0x5465A6 60 | #define GetTextureInfo_Hook_Addr_42 0x5465B9 61 | #define GetTextureInfo_Hook_Addr_43 0x5465CC 62 | #define GetTextureInfo_Hook_Addr_44 0x5465DF 63 | #define GetTextureInfo_Hook_Addr_45 0x5465F2 64 | #define GetTextureInfo_Hook_Addr_46 0x56A3CD 65 | #define GetTextureInfo_Hook_Addr_47 0x56A8A8 66 | #define GetTextureInfo_Hook_Addr_48 0x56A8BF 67 | #define GetTextureInfo_Hook_Addr_49 0x56AC67 68 | #define GetTextureInfo_Hook_Addr_50 0x56ACB5 69 | #define GetTextureInfo_Hook_Addr_51 0x56B07F 70 | #define GetTextureInfo_Hook_Addr_52 0x589C2A 71 | #define GetTextureInfo_Hook_Addr_53 0x58E651 72 | #define GetTextureInfo_Hook_Addr_54 0x58E674 73 | #define GetTextureInfo_Hook_Addr_55 0x58E68D 74 | #define GetTextureInfo_Hook_Addr_56 0x58E6A9 75 | #define GetTextureInfo_Hook_Addr_57 0x58E6C5 76 | #define GetTextureInfo_Hook_Addr_58 0x58E6E1 77 | #define GetTextureInfo_Hook_Addr_59 0x58E6FD 78 | #define GetTextureInfo_Hook_Addr_60 0x5A9CFD 79 | #define GetTextureInfo_Hook_Addr_61 0x5A9FEB 80 | #define GetTextureInfo_Hook_Addr_62 0x5AA025 81 | #define GetTextureInfo_Hook_Addr_63 0x5AA812 82 | #define GetTextureInfo_Hook_Addr_64 0x5AA847 83 | #define GetTextureInfo_Hook_Addr_65 0x5AA85D 84 | 85 | #pragma runtime_checks( "", off ) 86 | DWORD ResourceFile_BeginLoading_Func_Addr = ResourceFileBeginLoading_Addr; 87 | void __stdcall ResourceFileBeginLoading(void* ResourceFile, void* unk1, void* unk2) 88 | { 89 | _asm 90 | { 91 | mov edx, ResourceFile 92 | mov ecx, unk2 93 | mov eax, unk1 94 | call ResourceFile_BeginLoading_Func_Addr 95 | } 96 | } 97 | 98 | DWORD bStringHash_EDX = 0; 99 | DWORD bStringHash_Func_Addr = bStringHash_Addr; 100 | unsigned int __stdcall bStringHash(char* StringToHash) 101 | { 102 | unsigned int result; 103 | 104 | _asm 105 | { 106 | mov bStringHash_EDX, edx 107 | mov edx, StringToHash 108 | call bStringHash_Func_Addr 109 | mov result, eax 110 | mov edx, bStringHash_EDX 111 | } 112 | 113 | return result; 114 | } 115 | 116 | DWORD* (__cdecl* CreateResourceFile)(int a1, int a2, int a3, int a4, int a5) = (DWORD * (__cdecl*)(int, int, int, int, int))CreateResourceFile_Addr; 117 | 118 | int(__fastcall* LoadGlobalChunks)() = (int(__fastcall*)())LoadGlobalChunks_Addr; 119 | 120 | DWORD* (__cdecl* GetTextureInfo)(unsigned int hash, int returnDefault, int includeUnloadedTextures) = (DWORD * (__cdecl*)(unsigned int, int, int))GetTextureInfo_Addr; 121 | -------------------------------------------------------------------------------- /dllmain.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "stdio.h" 3 | #include 4 | #include 5 | #include "includes\injector\injector.hpp" 6 | #include "includes\IniReader.h" 7 | #include "TexWizard.h" 8 | 9 | BOOL APIENTRY DllMain(HMODULE /*hModule*/, DWORD reason, LPVOID /*lpReserved*/) 10 | { 11 | if (reason == DLL_PROCESS_ATTACH) 12 | { 13 | uintptr_t base = (uintptr_t)GetModuleHandleA(NULL); 14 | IMAGE_DOS_HEADER* dos = (IMAGE_DOS_HEADER*)(base); 15 | IMAGE_NT_HEADERS* nt = (IMAGE_NT_HEADERS*)(base + dos->e_lfanew); 16 | 17 | #ifdef GAME_PS 18 | 19 | if (strstr((const char*)(base + (0xA49742 - base)), "ProStreet08Release.exe")) 20 | { 21 | Init(); 22 | } 23 | #else 24 | if ((base + nt->OptionalHeader.AddressOfEntryPoint + (0x400000 - base)) == EntryPoint) // Check if .exe file is compatible - Thanks to thelink2012 and MWisBest 25 | { 26 | Init(); 27 | } 28 | #endif 29 | else 30 | { 31 | MessageBoxA(NULL, WrongEntryPointErrorString, "TexWizard", MB_ICONERROR); 32 | return FALSE; 33 | } 34 | } 35 | return TRUE; 36 | } 37 | -------------------------------------------------------------------------------- /includes/CPatch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class CPatch 5 | { 6 | public: 7 | inline static void Patch(void* address, void* data, int size) 8 | { 9 | unsigned long protect[2]; 10 | VirtualProtect(address, size, PAGE_EXECUTE_READWRITE, &protect[0]); 11 | memcpy(address, data, size); 12 | VirtualProtect(address, size, protect[0], &protect[1]); 13 | } 14 | 15 | inline static void Patch2(int address, void* data, int size) 16 | { 17 | unsigned long protect[2]; 18 | VirtualProtect((void *)address, size, PAGE_EXECUTE_READWRITE, &protect[0]); 19 | memcpy((void *)address, data, size); 20 | VirtualProtect((void *)address, size, protect[0], &protect[1]); 21 | } 22 | 23 | inline static void Unprotect(int address, int size) 24 | { 25 | unsigned long protect[2]; 26 | VirtualProtect((void *)address, size, PAGE_EXECUTE_READWRITE, &protect[0]); 27 | } 28 | inline static void Nop(int address, int size) 29 | { 30 | unsigned long protect[2]; 31 | VirtualProtect((void *)address, size, PAGE_EXECUTE_READWRITE, &protect[0]); 32 | memset((void *)address, 0x90, size); 33 | VirtualProtect((void *)address, size, protect[0], &protect[1]); 34 | } 35 | inline static void FillWithZeroes(int address, int size) 36 | { 37 | unsigned long protect[2]; 38 | VirtualProtect((void *)address, size, PAGE_EXECUTE_READWRITE, &protect[0]); 39 | memset((void *)address, 0x00, size); 40 | VirtualProtect((void *)address, size, protect[0], &protect[1]); 41 | } 42 | inline static void RedirectCall(int address, void *func) 43 | { 44 | int temp = 0xE8; 45 | Patch((void *)address, &temp, 1); 46 | temp = (int)func - ((int)address + 5); 47 | Patch((void *)((int)address + 1), &temp, 4); 48 | } 49 | inline static void RedirectJump(int address, void *func) 50 | { 51 | int temp = 0xE9; 52 | Patch((void *)address, &temp, 1); 53 | temp = (int)func - ((int)address + 5); 54 | Patch((void *)((int)address + 1), &temp, 4); 55 | } 56 | inline static void SetChar(int address, char value) 57 | { 58 | Patch((void *)address, &value, 1); 59 | } 60 | inline static void SetUChar(int address, unsigned char value) 61 | { 62 | Patch((void *)address, &value, 1); 63 | } 64 | inline static void SetShort(int address, short value) 65 | { 66 | Patch((void *)address, &value, 2); 67 | } 68 | inline static void SetUShort(int address, unsigned short value) 69 | { 70 | Patch((void *)address, &value, 2); 71 | } 72 | inline static void SetInt(int address, int value) 73 | { 74 | Patch((void *)address, &value, 4); 75 | } 76 | inline static void SetUInt(int address, unsigned int value) 77 | { 78 | Patch((void *)address, &value, 4); 79 | } 80 | inline static void SetUIntWithCheck(int address, unsigned int value, unsigned int expectedValue) 81 | { 82 | if (*(unsigned int *)address == expectedValue) 83 | Patch((void *)address, &value, 4); 84 | } 85 | inline static void SetFloat(int address, float value) 86 | { 87 | Patch((void *)address, &value, 4); 88 | } 89 | inline static void SetDouble(int address, double value) 90 | { 91 | Patch((void *)address, &value, 8); 92 | } 93 | inline static void SetPointer(int address, void *value) 94 | { 95 | Patch((void *)address, &value, 4); 96 | } 97 | 98 | inline static void AdjustPointer(int address, void *value, DWORD offset, DWORD end) 99 | { 100 | int result; 101 | if((DWORD)*(DWORD*)address >= offset && (DWORD)*(DWORD*)address <= end) { 102 | result = (DWORD)value + (DWORD)*(DWORD*)address - (DWORD)offset; 103 | Patch((void *)address, &result, 4); 104 | } else { 105 | address = address + 1; 106 | if((DWORD)*(DWORD*)address >= offset && (DWORD)*(DWORD*)address <= end) { 107 | result = (DWORD)value + (DWORD)*(DWORD*)address - (DWORD)offset; 108 | Patch((void *)address, &result, 4); 109 | } else { 110 | address = address + 1; 111 | if((DWORD)*(DWORD*)address >= offset && (DWORD)*(DWORD*)address <= end) { 112 | result = (DWORD)value + (DWORD)*(DWORD*)address - (DWORD)offset; 113 | Patch((void *)address, &result, 4); 114 | } else { 115 | address = address + 1; 116 | if((DWORD)*(DWORD*)address >= offset && (DWORD)*(DWORD*)address <= end) { 117 | result = (DWORD)value + (DWORD)*(DWORD*)address - (DWORD)offset; 118 | Patch((void *)address, &result, 4); 119 | } else { 120 | address = address + 1; 121 | if((DWORD)*(DWORD*)address >= offset && (DWORD)*(DWORD*)address <= end) { 122 | result = (DWORD)value + (DWORD)*(DWORD*)address - (DWORD)offset; 123 | Patch((void *)address, &result, 4); 124 | } else { 125 | address = address + 1; 126 | if((DWORD)*(DWORD*)address >= offset && (DWORD)*(DWORD*)address <= end) { 127 | result = (DWORD)value + (DWORD)*(DWORD*)address - (DWORD)offset; 128 | Patch((void *)address, &result, 4); 129 | } 130 | } 131 | } 132 | } 133 | } 134 | } 135 | } 136 | 137 | inline static bool FileExists(const TCHAR *fileName) 138 | { 139 | DWORD fileAttr; 140 | fileAttr = GetFileAttributes(fileName); 141 | if (0xFFFFFFFF == fileAttr && GetLastError()==ERROR_FILE_NOT_FOUND) 142 | return false; 143 | return true; 144 | } 145 | }; -------------------------------------------------------------------------------- /includes/IniReader.h: -------------------------------------------------------------------------------- 1 | #ifndef INIREADER_H 2 | #define INIREADER_H 3 | #include "ini_parser.hpp" 4 | #include 5 | #include 6 | 7 | /* 8 | * String comparision functions, with case sensitive option 9 | */ 10 | 11 | using std::strcmp; 12 | 13 | inline int strcmp(const char* str1, const char* str2, bool csensitive) 14 | { 15 | return (csensitive ? ::strcmp(str1, str2) : ::_stricmp(str1, str2)); 16 | } 17 | 18 | inline int strcmp(const char* str1, const char* str2, size_t num, bool csensitive) 19 | { 20 | return (csensitive ? ::strncmp(str1, str2, num) : ::_strnicmp(str1, str2, num)); 21 | } 22 | 23 | inline int compare(const std::string& str1, const std::string& str2, bool case_sensitive) 24 | { 25 | if (str1.length() == str2.length()) 26 | return strcmp(str1.c_str(), str2.c_str(), case_sensitive); 27 | return (str1.length() < str2.length() ? -1 : 1); 28 | } 29 | 30 | inline int compare(const std::string& str1, const std::string& str2, size_t num, bool case_sensitive) 31 | { 32 | if (str1.length() == str2.length()) 33 | return strcmp(str1.c_str(), str2.c_str(), num, case_sensitive); 34 | return (str1.length() < str2.length() ? -1 : 1); 35 | } 36 | 37 | inline int compare(const char* str1, const char* str2, bool case_sensitive) 38 | { 39 | return strcmp(str1, str2, case_sensitive); 40 | } 41 | 42 | inline int compare(const char* str1, const char* str2, size_t num, bool case_sensitive) 43 | { 44 | return strcmp(str1, str2, num, case_sensitive); 45 | } 46 | 47 | inline bool starts_with(const char* str, const char* prefix, bool case_sensitive) 48 | { 49 | while (*prefix) 50 | { 51 | bool equal; 52 | if (case_sensitive) 53 | equal = (*str++ == *prefix++); 54 | else 55 | equal = (::tolower(*str++) == ::tolower(*prefix++)); 56 | 57 | if (!equal) return false; 58 | } 59 | return true; 60 | } 61 | 62 | inline bool ends_with(const char* str, const char* prefix, bool case_sensitive) 63 | { 64 | auto str2 = &str[strlen(str) - 1]; 65 | auto prefix2 = &prefix[strlen(prefix) - 1]; 66 | 67 | while (prefix2 >= prefix) 68 | { 69 | bool equal; 70 | if (case_sensitive) 71 | equal = (*str2-- == *prefix2--); 72 | else 73 | equal = (::tolower(*str2--) == ::tolower(*prefix2--)); 74 | 75 | if (!equal) return false; 76 | } 77 | return true; 78 | } 79 | 80 | class CIniReader 81 | { 82 | private: 83 | std::string m_szFileName; 84 | 85 | public: 86 | linb::ini data; 87 | 88 | CIniReader() 89 | { 90 | SetIniPath(""); 91 | } 92 | 93 | CIniReader(char* szFileName) 94 | { 95 | SetIniPath(szFileName); 96 | } 97 | 98 | CIniReader(const char* szFileName) 99 | { 100 | SetIniPath((char*)szFileName); 101 | } 102 | 103 | CIniReader(std::stringstream& ini_mem) 104 | { 105 | data.load_file(ini_mem); 106 | } 107 | 108 | bool operator==(CIniReader& ir) 109 | { 110 | if (data.size() != ir.data.size()) 111 | return false; 112 | 113 | for (auto& section : data) 114 | { 115 | for (auto& key : data[section.first]) 116 | { 117 | if (key.second != ir.data[section.first][key.first]) 118 | return false; 119 | } 120 | } 121 | return true; 122 | } 123 | 124 | bool operator!=(CIniReader& ir) 125 | { 126 | return !(*this == ir); 127 | } 128 | 129 | bool CompareBySections(CIniReader& ir) 130 | { 131 | if (data.size() != ir.data.size()) 132 | return false; 133 | 134 | for (auto& section : data) 135 | { 136 | if (ir.data.find(section.first) == ir.data.end()) 137 | return false; 138 | 139 | if (section.second.size() != ir.data.find(section.first)->second.size()) 140 | return false; 141 | 142 | if (section.first != ir.data.find(section.first)->first) 143 | return false; 144 | } 145 | return true; 146 | } 147 | 148 | bool CompareByValues(CIniReader& ir) 149 | { 150 | return *this == ir; 151 | } 152 | 153 | const std::string& GetIniPath() 154 | { 155 | return m_szFileName; 156 | } 157 | 158 | void SetIniPath() 159 | { 160 | SetIniPath(""); 161 | } 162 | 163 | void SetIniPath(char* szFileName) 164 | { 165 | char buffer[MAX_PATH]; 166 | HMODULE hm = NULL; 167 | GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCSTR)&ends_with, &hm); 168 | GetModuleFileNameA(hm, buffer, sizeof(buffer)); 169 | std::string modulePath = buffer; 170 | 171 | if (strchr(szFileName, ':') != NULL) 172 | { 173 | m_szFileName = szFileName; 174 | } 175 | else if (std::string(szFileName).length() == 0) 176 | { 177 | m_szFileName = modulePath.substr(0, modulePath.find_last_of('.')) + ".ini"; 178 | } 179 | else 180 | { 181 | m_szFileName = modulePath.substr(0, modulePath.rfind('\\') + 1) + szFileName; 182 | } 183 | 184 | data.load_file(m_szFileName); 185 | } 186 | 187 | int ReadInteger(char* szSection, char* szKey, int iDefaultValue) 188 | { 189 | try { 190 | auto str = data.get(szSection, szKey, std::to_string(iDefaultValue)); 191 | return std::stoi(str, nullptr, starts_with(str.c_str(), "0x", false) ? 16 : 10); 192 | } 193 | catch (...) { 194 | return iDefaultValue; 195 | } 196 | } 197 | 198 | float ReadFloat(char* szSection, char* szKey, float fltDefaultValue) 199 | { 200 | try { 201 | return (float)atof(data.get(szSection, szKey, std::to_string(fltDefaultValue)).c_str()); 202 | } 203 | catch (...) { 204 | return fltDefaultValue; 205 | } 206 | } 207 | 208 | bool ReadBoolean(char* szSection, char* szKey, bool bolDefaultValue) 209 | { 210 | try { 211 | auto& config = data[szSection]; 212 | if (config.count(szKey)) 213 | { 214 | if (config[szKey].size() == 1) return config[szKey].front() != '0'; 215 | return !!compare(config[szKey], "false", false); 216 | } 217 | } 218 | catch (...) { 219 | return bolDefaultValue; 220 | } 221 | } 222 | 223 | char* ReadString(char* szSection, char* szKey, const char* szDefaultValue) 224 | { 225 | char* szResult = new char[255]; 226 | try { 227 | auto& config = data[szSection]; 228 | if (config.count(szKey)) 229 | { 230 | if (config[szKey].at(0) == '\"' || config[szKey].at(0) == '\'') 231 | config[szKey].erase(0, 1); 232 | 233 | if (config[szKey].at(config[szKey].size() - 1) == '\"' || config[szKey].at(config[szKey].size() - 1) == '\'') 234 | config[szKey].erase(config[szKey].size() - 1); 235 | 236 | strcpy(szResult, config[szKey].c_str()); 237 | return szResult; 238 | } 239 | } 240 | catch (...) { } 241 | strcpy(szResult, szDefaultValue); 242 | return szResult; 243 | } 244 | 245 | std::string ReadString(char* szSection, char* szKey, std::string szDefaultValue) 246 | { 247 | char* str = ReadString(szSection, szKey, szDefaultValue.c_str()); 248 | std::string* szResult = new std::string(str); 249 | return *szResult; 250 | } 251 | 252 | void WriteInteger(char* szSection, char* szKey, int iValue, bool useparser = false) 253 | { 254 | if (useparser) 255 | { 256 | data.set(szSection, szKey, std::to_string(iValue)); 257 | data.write_file(m_szFileName); 258 | } 259 | else 260 | { 261 | char szValue[255]; 262 | _snprintf_s(szValue, 255, "%s%d", " ", iValue); 263 | WritePrivateProfileStringA(szSection, szKey, szValue, m_szFileName.c_str()); 264 | } 265 | } 266 | 267 | void WriteFloat(char* szSection, char* szKey, float fltValue, bool useparser = false) 268 | { 269 | if (useparser) 270 | { 271 | data.set(szSection, szKey, std::to_string(fltValue)); 272 | data.write_file(m_szFileName); 273 | } 274 | else 275 | { 276 | char szValue[255]; 277 | _snprintf_s(szValue, 255, "%s%f", " ", fltValue); 278 | WritePrivateProfileStringA(szSection, szKey, szValue, m_szFileName.c_str()); 279 | } 280 | } 281 | 282 | void WriteBoolean(char* szSection, char* szKey, bool bolValue, bool useparser = false) 283 | { 284 | if (useparser) 285 | { 286 | data.set(szSection, szKey, std::to_string(bolValue)); 287 | data.write_file(m_szFileName); 288 | } 289 | else 290 | { 291 | char szValue[255]; 292 | _snprintf_s(szValue, 255, "%s%s", " ", bolValue ? "True" : "False"); 293 | WritePrivateProfileStringA(szSection, szKey, szValue, m_szFileName.c_str()); 294 | } 295 | } 296 | 297 | void WriteString(char* szSection, char* szKey, char* szValue, bool useparser = false) 298 | { 299 | if (useparser) 300 | { 301 | data.set(szSection, szKey, szValue); 302 | data.write_file(m_szFileName); 303 | } 304 | else 305 | { 306 | WritePrivateProfileStringA(szSection, szKey, szValue, m_szFileName.c_str()); 307 | } 308 | } 309 | }; 310 | 311 | #endif //INIREADER_H 312 | -------------------------------------------------------------------------------- /includes/ini_parser.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2015 Denilson das Mercês Amorim 3 | * Copyright (c) 2017 ThirteenAG 4 | * 5 | * This software is provided 'as-is', without any express or implied 6 | * warranty. In no event will the authors be held liable for any damages 7 | * arising from the use of this software. 8 | * 9 | * Permission is granted to anyone to use this software for any purpose, 10 | * including commercial applications, and to alter it and redistribute it 11 | * freely, subject to the following restrictions: 12 | * 13 | * 1. The origin of this software must not be misrepresented; you must not 14 | * claim that you wrote the original software. If you use this software 15 | * in a product, an acknowledgment in the product documentation would be 16 | * appreciated but is not required. 17 | * 18 | * 2. Altered source versions must be plainly marked as such, and must not be 19 | * misrepresented as being the original software. 20 | * 21 | * 3. This notice may not be removed or altered from any source 22 | * distribution. 23 | * 24 | */ 25 | #ifndef LINB_INI_PARSER_HPP 26 | #define LINB_INI_PARSER_HPP 27 | 28 | /* 29 | * STL-like INI Container 30 | */ 31 | 32 | #include // for std::string 33 | #include // for std::map 34 | #include // for std::FILE 35 | #include // for std::find_if 36 | #include // for std::function 37 | #include // for std::vector 38 | #include 39 | #include 40 | 41 | namespace linb 42 | { 43 | template< 44 | class CharT = char, /* Not compatible with other type here, since we're using C streams */ 45 | class StringType = std::basic_string, 46 | class KeyContainer = std::map, 47 | class SectionContainer = std::map 48 | > class basic_ini 49 | { 50 | public: 51 | typedef CharT char_type; 52 | typedef StringType string_type; 53 | typedef KeyContainer key_container; 54 | typedef SectionContainer section_container; 55 | 56 | // Typedef container values types 57 | typedef typename section_container::value_type value_type; 58 | typedef typename section_container::key_type key_type; 59 | typedef typename section_container::mapped_type mapped_type; 60 | 61 | // Typedef common types 62 | typedef typename section_container::size_type size_type; 63 | typedef typename section_container::difference_type difference_type; 64 | 65 | // Typedef iterators 66 | typedef typename section_container::iterator iterator; 67 | typedef typename section_container::const_iterator const_iterator; 68 | typedef typename section_container::reverse_iterator reverse_iterator; 69 | typedef typename section_container::const_reverse_iterator const_reverse_iterator; 70 | 71 | // typedef References and pointers 72 | typedef typename section_container::reference reference; 73 | typedef typename section_container::const_reference const_reference; 74 | typedef typename section_container::pointer pointer; 75 | typedef typename section_container::const_pointer const_pointer; 76 | 77 | private: 78 | section_container data; 79 | 80 | public: 81 | 82 | basic_ini() 83 | { } 84 | 85 | basic_ini(const char_type* filename) 86 | { this->read_file(filename); } 87 | 88 | /* Iterator methods */ 89 | iterator begin() 90 | { return data.begin(); } 91 | const_iterator begin() const 92 | { return data.begin(); } 93 | iterator end() 94 | { return data.end(); } 95 | const_iterator end() const 96 | { return data.end(); } 97 | const_iterator cbegin() const 98 | { return data.cbegin(); } 99 | const_iterator cend() const 100 | { return data.cend(); } 101 | 102 | /* Reverse iterator methods */ 103 | reverse_iterator rbegin() 104 | { return data.rbegin(); } 105 | const_reverse_iterator rbegin() const 106 | { return data.rbegin(); } 107 | reverse_iterator rend() 108 | { return data.rend(); } 109 | const_reverse_iterator rend() const 110 | { return data.rend(); } 111 | const_reverse_iterator crbegin() const 112 | { return data.crbegin(); } 113 | const_reverse_iterator crend() const 114 | { return data.crend(); } 115 | 116 | /* Acessing index methods */ 117 | mapped_type& operator[](const string_type& sect) 118 | { return data[sect]; } 119 | mapped_type& operator[](string_type&& sect) 120 | { return data[std::forward(sect)]; } 121 | mapped_type& at( const string_type& sect) 122 | { return data.at(sect); } 123 | const mapped_type& at(const string_type& sect) const 124 | { return data.at(sect); } 125 | 126 | /* Capacity information */ 127 | bool empty() const 128 | { return data.empty(); } 129 | size_type size() const 130 | { return data.size(); } 131 | size_type max_size() const 132 | { return data.max_size(); } 133 | 134 | /* Modifiers */ 135 | void clear() 136 | { return data.clear(); } 137 | 138 | /* Lookup */ 139 | size_type count(const string_type& sect) 140 | { return data.count(sect); } 141 | iterator find(const string_type& sect) 142 | { return data.find(sect); } 143 | 144 | /* Gets a value from the specified section & key, default_value is returned if the sect & key doesn't exist */ 145 | string_type get(const string_type& sect, const key_type& key, const string_type& default_value) 146 | { 147 | auto it = this->find(sect); 148 | if(it != this->end()) 149 | { 150 | auto itv = it->second.find(key); 151 | if(itv != it->second.end()) 152 | return itv->second; 153 | } 154 | return default_value; 155 | } 156 | 157 | /* Sets the value of a value in the ini */ 158 | void set(const string_type& sect, const key_type& key, const string_type& value) 159 | { 160 | (*this)[sect][key] = value; // no emplace since overwrite! 161 | } 162 | 163 | /* Too lazy to continue this container... If you need more methods, just add it */ 164 | 165 | 166 | bool read_file(std::stringstream& ini_mem) 167 | { 168 | if(ini_mem.rdbuf()->in_avail()) 169 | { 170 | key_container* keys = nullptr; 171 | string_type line; 172 | string_type key; 173 | string_type value; 174 | string_type null_string; 175 | size_type pos; 176 | 177 | // Trims an string 178 | auto trim = [](string_type& s, bool trimLeft, bool trimRight) -> string_type& 179 | { 180 | if(s.size()) 181 | { 182 | // Ignore UTF-8 BOM 183 | while(s.size() >= 3 && s[0] == (char)(0xEF) && s[1] == (char)(0xBB) && s[2] == (char)(0xBF)) 184 | s.erase(s.begin(), s.begin() + 3); 185 | 186 | if(trimLeft) 187 | s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::function(::isspace)))); 188 | if(trimRight) 189 | s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::function(::isspace))).base(), s.end()); 190 | } 191 | return s; 192 | }; 193 | 194 | // Start parsing 195 | while (std::getline(ini_mem, line)) 196 | { 197 | // Find comment and remove anything after it from the line 198 | if((pos = line.find_first_of(';')) != line.npos) 199 | line.erase(pos); 200 | 201 | if ((pos = line.rfind(" //")) != line.npos) 202 | line.erase(pos); 203 | 204 | // Trim the string, and if it gets empty, skip this line 205 | if(trim(line, true, true).empty()) 206 | continue; 207 | 208 | // Find section name 209 | if(line.front() == '[' && line.back() == ']') 210 | { 211 | pos = line.length() - 1; //line.find_first_of(']'); 212 | if(pos != line.npos) 213 | { 214 | trim(key.assign(line, 1, pos-1), true, true); 215 | keys = &data[std::move(key)]; // Create section 216 | } 217 | else 218 | keys = nullptr; 219 | } 220 | else 221 | { 222 | // Find key and value positions 223 | pos = line.find_first_of('='); 224 | if(pos == line.npos) 225 | { 226 | // There's only the key 227 | key = line; // No need for trim, line is already trimmed 228 | value.clear(); 229 | } 230 | else 231 | { 232 | // There's the key and the value 233 | trim(key.assign(line, 0, pos), false, true); // trim the right 234 | trim(value.assign(line, pos + 1, line.npos), true, false); // trim the left 235 | } 236 | 237 | // Put the key/value into the current keys object, or into the section "" if no section has been found 238 | #if __cplusplus >= 201103L || _MSC_VER >= 1800 239 | (keys ? *keys : data[null_string]).emplace(std::move(key), std::move(value)); 240 | #else 241 | (keys ? *keys : data[null_string])[key] = value; 242 | key.clear(); value.clear(); 243 | #endif 244 | } 245 | } 246 | 247 | return true; 248 | } 249 | return false; 250 | } 251 | 252 | bool read_file(const char_type* filename) 253 | { 254 | std::ifstream file(filename, std::ios::in); 255 | if (file.is_open()) 256 | { 257 | std::stringstream ss; 258 | ss << file.rdbuf(); 259 | file.close(); 260 | return read_file(ss); 261 | } 262 | return false; 263 | } 264 | 265 | /* 266 | * Dumps the content of this container into an ini file 267 | */ 268 | bool write_file(const char_type* filename) 269 | { 270 | if(FILE* f = fopen(filename, "w")) 271 | { 272 | bool first = true; 273 | for(auto& sec : this->data) 274 | { 275 | fprintf(f, first? "[%s]\n" : "\n[%s]\n", sec.first.c_str()); 276 | first = false; 277 | for(auto& kv : sec.second) 278 | { 279 | if(kv.second.empty()) 280 | fprintf(f, "%s\n", kv.first.c_str()); 281 | else 282 | fprintf(f, "%s = %s\n", kv.first.c_str(), kv.second.c_str()); 283 | } 284 | } 285 | fclose(f); 286 | return true; 287 | } 288 | return false; 289 | } 290 | 291 | 292 | /* 293 | */ 294 | bool load_file(const char_type* filename) 295 | { 296 | return read_file(filename); 297 | } 298 | 299 | bool load_file(const StringType& filename) 300 | { 301 | return load_file(filename.c_str()); 302 | } 303 | 304 | bool load_file(std::stringstream& filename) 305 | { 306 | return read_file(filename); 307 | } 308 | 309 | bool write_file(const StringType& filename) 310 | { 311 | return write_file(filename.c_str()); 312 | } 313 | }; 314 | 315 | 316 | /* Use default basic_ini 317 | * 318 | * Limitations: 319 | * * Not unicode aware 320 | * * Case sensitive 321 | * * Sections must have unique keys 322 | */ 323 | typedef basic_ini<> ini; 324 | } 325 | 326 | #endif 327 | 328 | -------------------------------------------------------------------------------- /includes/injector/assembly.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Injectors - Useful Assembly Stuff 3 | * 4 | * Copyright (C) 2012-2014 LINK/2012 5 | * 6 | * This software is provided 'as-is', without any express or implied 7 | * warranty. In no event will the authors be held liable for any damages 8 | * arising from the use of this software. 9 | * 10 | * Permission is granted to anyone to use this software for any purpose, 11 | * including commercial applications, and to alter it and redistribute it 12 | * freely, subject to the following restrictions: 13 | * 14 | * 1. The origin of this software must not be misrepresented; you must not 15 | * claim that you wrote the original software. If you use this software 16 | * in a product, an acknowledgment in the product documentation would be 17 | * appreciated but is not required. 18 | * 19 | * 2. Altered source versions must be plainly marked as such, and must not be 20 | * misrepresented as being the original software. 21 | * 22 | * 3. This notice may not be removed or altered from any source 23 | * distribution. 24 | * 25 | */ 26 | #pragma once 27 | 28 | // This header is very restrict about compiler and architecture 29 | #ifndef _MSC_VER // MSVC is much more flexible when we're talking about inline assembly 30 | #error Cannot use this header in another compiler other than MSVC 31 | #endif 32 | #ifndef _M_IX86 33 | #error Supported only in x86 34 | #endif 35 | 36 | // 37 | #include "injector.hpp" 38 | 39 | namespace injector 40 | { 41 | struct reg_pack 42 | { 43 | // The ordering is very important, don't change 44 | // The first field is the last to be pushed and first to be poped 45 | 46 | // PUSHFD / POPFD 47 | uint32_t ef; 48 | 49 | // PUSHAD/POPAD -- must be the lastest fields (because of esp) 50 | union 51 | { 52 | uint32_t arr[8]; 53 | struct { uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; }; 54 | }; 55 | 56 | enum reg_name { 57 | reg_edi, reg_esi, reg_ebp, reg_esp, reg_ebx, reg_edx, reg_ecx, reg_eax 58 | }; 59 | 60 | enum ef_flag { 61 | carry_flag = 0, parity_flag = 2, adjust_flag = 4, zero_flag = 6, sign_flag = 7, 62 | direction_flag = 10, overflow_flag = 11 63 | }; 64 | 65 | uint32_t& operator[](size_t i) 66 | { return this->arr[i]; } 67 | const uint32_t& operator[](size_t i) const 68 | { return this->arr[i]; } 69 | 70 | template // bit starts from 0, use ef_flag enum 71 | bool flag() 72 | { 73 | return (this->ef & (1 << bit)) != 0; 74 | } 75 | 76 | bool jnb() 77 | { 78 | return flag() == false; 79 | } 80 | }; 81 | 82 | // Lowest level stuff (actual assembly) goes on the following namespace 83 | // PRIVATE! Skip this, not interesting for you. 84 | namespace injector_asm 85 | { 86 | // Wrapper functor, so the assembly can use some templating 87 | template 88 | struct wrapper 89 | { 90 | static void call(reg_pack* regs) 91 | { 92 | T fun; fun(*regs); 93 | } 94 | }; 95 | 96 | // Constructs a reg_pack and calls the wrapper functor 97 | template // where W is of type wrapper 98 | inline void __declspec(naked) make_reg_pack_and_call() 99 | { 100 | _asm 101 | { 102 | // Construct the reg_pack structure on the stack 103 | pushad // Pushes general purposes registers to reg_pack 104 | add [esp+12], 4 // Add 4 to reg_pack::esp 'cuz of our return pointer, let it be as before this func is called 105 | pushfd // Pushes EFLAGS to reg_pack 106 | 107 | // Call wrapper sending reg_pack as parameter 108 | push esp 109 | call W::call 110 | add esp, 4 111 | 112 | // Destructs the reg_pack from the stack 113 | sub [esp+12+4], 4 // Fix reg_pack::esp before popping it (doesn't make a difference though) (+4 because eflags) 114 | popfd // Warning: Do not use any instruction that changes EFLAGS after this (-> sub affects EF!! <-) 115 | popad 116 | 117 | // Back to normal flow 118 | ret 119 | } 120 | } 121 | }; 122 | 123 | 124 | /* 125 | * MakeInline 126 | * Makes inline assembly (but not assembly, an actual functor of type FuncT) at address 127 | */ 128 | template 129 | void MakeInline(memory_pointer_tr at) 130 | { 131 | typedef injector_asm::wrapper functor; 132 | if(false) functor::call(nullptr); // To instantiate the template, if not done _asm will fail 133 | MakeCALL(at, injector_asm::make_reg_pack_and_call); 134 | } 135 | 136 | /* 137 | * MakeInline 138 | * Same as above, but it NOPs everything between at and end (exclusive), then performs MakeInline 139 | */ 140 | template 141 | void MakeInline(memory_pointer_tr at, memory_pointer_tr end) 142 | { 143 | MakeRangedNOP(at, end); 144 | MakeInline(at); 145 | } 146 | 147 | /* 148 | * MakeInline 149 | * Same as above, but (at,end) are template parameters. 150 | * On this case the functor can be passed as argument since there will be one func instance for each at,end not just for each FuncT 151 | */ 152 | template 153 | void MakeInline(FuncT func) 154 | { 155 | static std::unique_ptr static_func; 156 | static_func.reset(new FuncT(std::move(func))); 157 | 158 | // Encapsulates the call to static_func 159 | struct Caps 160 | { 161 | void operator()(reg_pack& regs) 162 | { (*static_func)(regs); } 163 | }; 164 | 165 | // Does the actual MakeInline 166 | return MakeInline(lazy_pointer::get(), lazy_pointer::get()); 167 | } 168 | 169 | /* 170 | * MakeInline 171 | * Same as above, but (end) is calculated by the length of a call instruction 172 | */ 173 | template 174 | void MakeInline(FuncT func) 175 | { 176 | return MakeInline(func); 177 | } 178 | }; 179 | -------------------------------------------------------------------------------- /includes/injector/calling.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Injectors - Function Calls Using Variadic Templates 3 | * 4 | * Copyright (C) 2014 LINK/2012 5 | * 6 | * This software is provided 'as-is', without any express or implied 7 | * warranty. In no event will the authors be held liable for any damages 8 | * arising from the use of this software. 9 | * 10 | * Permission is granted to anyone to use this software for any purpose, 11 | * including commercial applications, and to alter it and redistribute it 12 | * freely, subject to the following restrictions: 13 | * 14 | * 1. The origin of this software must not be misrepresented; you must not 15 | * claim that you wrote the original software. If you use this software 16 | * in a product, an acknowledgment in the product documentation would be 17 | * appreciated but is not required. 18 | * 19 | * 2. Altered source versions must be plainly marked as such, and must not be 20 | * misrepresented as being the original software. 21 | * 22 | * 3. This notice may not be removed or altered from any source 23 | * distribution. 24 | * 25 | */ 26 | #pragma once 27 | #include "injector.hpp" 28 | #include 29 | #include 30 | 31 | #if __cplusplus >= 201103L || _MSC_VER >= 1800 // MSVC 2013 32 | #else 33 | #error "This feature is not supported on this compiler" 34 | #endif 35 | 36 | namespace injector 37 | { 38 | template 39 | struct cstd; 40 | 41 | template 42 | struct cstd 43 | { 44 | // Call function at @p returning @Ret with args @Args 45 | static Ret call(memory_pointer_tr p, Args... a) 46 | { 47 | auto fn = (Ret(*)(Args...)) p.get(); 48 | return fn(std::forward(a)...); 49 | } 50 | 51 | template // Uses lazy pointer 52 | static Ret call(Args... a) 53 | { 54 | return call(lazy_pointer::get(), std::forward(a)...); 55 | } 56 | }; 57 | 58 | template 59 | struct stdcall; 60 | 61 | template 62 | struct stdcall 63 | { 64 | // Call function at @p returning @Ret with args @Args 65 | static Ret call(memory_pointer_tr p, Args... a) 66 | { 67 | auto fn = (Ret(__stdcall *)(Args...)) p.get(); 68 | return fn(std::forward(a)...); 69 | } 70 | 71 | template // Uses lazy pointer 72 | static Ret call(Args... a) 73 | { 74 | return call(lazy_pointer::get(), std::forward(a)...); 75 | } 76 | }; 77 | 78 | template 79 | struct fastcall; 80 | 81 | template 82 | struct fastcall 83 | { 84 | // Call function at @p returning @Ret with args @Args 85 | static Ret call(memory_pointer_tr p, Args... a) 86 | { 87 | auto fn = (Ret(__fastcall *)(Args...)) p.get();; 88 | return fn(std::forward(a)...); 89 | } 90 | 91 | template // Uses lazy pointer 92 | static Ret call(Args... a) 93 | { 94 | return call(lazy_pointer::get(), std::forward(a)...); 95 | } 96 | }; 97 | 98 | template 99 | struct thiscall; 100 | 101 | template 102 | struct thiscall 103 | { 104 | // Call function at @p returning @Ret with args @Args 105 | static Ret call(memory_pointer_tr p, Args... a) 106 | { 107 | auto fn = (Ret(__thiscall *)(Args...)) p.get(); 108 | return fn(std::forward(a)...); 109 | } 110 | 111 | // Call function at the index @i from the vtable of the object @a[0] 112 | template 113 | static Ret vtbl(Args... a) 114 | { 115 | auto obj = raw_ptr(std::get<0>(std::forward_as_tuple(a...))); 116 | auto p = raw_ptr( (*obj.template get()) [i] ); 117 | return call(p, std::forward(a)...); 118 | } 119 | 120 | template // Uses lazy pointer 121 | static Ret call(Args... a) 122 | { 123 | return call(lazy_pointer::get(), std::forward(a)...); 124 | } 125 | }; 126 | } 127 | 128 | -------------------------------------------------------------------------------- /includes/injector/gvm/gvm.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Injectors - Base Header 3 | * 4 | * Copyright (C) 2012-2014 LINK/2012 5 | * 6 | * This software is provided 'as-is', without any express or implied 7 | * warranty. In no event will the authors be held liable for any damages 8 | * arising from the use of this software. 9 | * 10 | * Permission is granted to anyone to use this software for any purpose, 11 | * including commercial applications, and to alter it and redistribute it 12 | * freely, subject to the following restrictions: 13 | * 14 | * 1. The origin of this software must not be misrepresented; you must not 15 | * claim that you wrote the original software. If you use this software 16 | * in a product, an acknowledgment in the product documentation would be 17 | * appreciated but is not required. 18 | * 19 | * 2. Altered source versions must be plainly marked as such, and must not be 20 | * misrepresented as being the original software. 21 | * 22 | * 3. This notice may not be removed or altered from any source 23 | * distribution. 24 | * 25 | */ 26 | #pragma once 27 | #include 28 | #include 29 | #include 30 | 31 | namespace injector 32 | { 33 | 34 | #if 1 // GVM and Address Translator, Not very interesting for the users, so skip reading those... 35 | 36 | /* 37 | * game_version_manager 38 | * Detects the game, the game version and the game region 39 | * This assumes the executable is decrypted, so, Silent's ASI Loader is recommended. 40 | */ 41 | #ifndef INJECTOR_OWN_GVM 42 | #ifndef INJECTOR_GVM_DUMMY 43 | class game_version_manager 44 | { 45 | public: 46 | // Set this if you would like that MessagesBox contain PluginName as caption 47 | const char* PluginName; 48 | 49 | private: 50 | char game, region, major, minor, majorRevision, minorRevision, cracker, steam; 51 | 52 | public: 53 | game_version_manager() 54 | { 55 | #ifdef INJECTOR_GVM_PLUGIN_NAME 56 | PluginName = INJECTOR_GVM_PLUGIN_NAME; 57 | #else 58 | PluginName = "Unknown Plugin Name"; 59 | #endif 60 | 61 | this->Clear(); 62 | } 63 | 64 | 65 | // Clear any information about game version 66 | void Clear() 67 | { 68 | game = region = major = minor = majorRevision = minorRevision = cracker = steam = 0; 69 | } 70 | 71 | // Checks if I don't know the game we are attached to 72 | bool IsUnknown() { return game == 0; } 73 | // Checks if this is the steam version 74 | bool IsSteam() { return steam != 0; } 75 | // Gets the game we are attached to (0, '3', 'V', 'S', 'I', 'E') 76 | char GetGame() { return game; } 77 | // Gets the region from the game we are attached to (0, 'U', 'E'); 78 | char GetRegion() { return region; } 79 | // Get major and minor version of the game (e.g. [major = 1, minor = 0] = 1.0) 80 | int GetMajorVersion() { return major; } 81 | int GetMinorVersion() { return minor; } 82 | int GetMajorRevisionVersion() { return majorRevision; } 83 | int GetMinorRevisionVersion() { return minorRevision; } 84 | 85 | bool IsHoodlum() { return cracker == 'H'; } 86 | 87 | // Region conditions 88 | bool IsUS() { return region == 'U'; } 89 | bool IsEU() { return region == 'E'; } 90 | 91 | // Game Conditions 92 | bool IsIII() { return game == '3'; } 93 | bool IsVC () { return game == 'V'; } 94 | bool IsSA () { return game == 'S'; } 95 | bool IsIV () { return game == 'I'; } 96 | bool IsEFLC(){ return game == 'E'; } 97 | 98 | // Detects game, region and version; returns false if could not detect it 99 | bool Detect(); 100 | 101 | // Gets the game version as text, the buffer must contain at least 32 bytes of space. 102 | char* GetVersionText(char* buffer) 103 | { 104 | if(this->IsUnknown()) 105 | { 106 | strcpy(buffer, "UNKNOWN GAME"); 107 | return buffer; 108 | } 109 | 110 | const char* g = this->IsIII() ? "III" : this->IsVC() ? "VC" : this->IsSA() ? "SA" : this->IsIV() ? "IV" : this->IsEFLC() ? "EFLC" : "UNK"; 111 | const char* r = this->IsUS()? "US" : this->IsEU()? "EURO" : "UNK_REGION"; 112 | const char* s = this->IsSteam()? "Steam" : ""; 113 | sprintf(buffer, "GTA %s %d.%d.%d.%d %s%s", g, major, minor, majorRevision, minorRevision, r, s); 114 | return buffer; 115 | } 116 | 117 | 118 | public: 119 | // Raises a error saying that you could not detect the game version 120 | void RaiseCouldNotDetect() 121 | { 122 | MessageBoxA(0, 123 | "Could not detect the game version\nContact the mod creator!", 124 | PluginName, MB_ICONERROR 125 | ); 126 | } 127 | 128 | // Raises a error saying that the exe version is incompatible (and output the exe name) 129 | void RaiseIncompatibleVersion() 130 | { 131 | char buf[128], v[32]; 132 | sprintf(buf, 133 | "An incompatible exe version has been detected! (%s)\nContact the mod creator!", 134 | GetVersionText(v) 135 | ); 136 | MessageBoxA(0, buf, PluginName, MB_ICONERROR); 137 | } 138 | }; 139 | #else // INJECTOR_GVM_DUMMY 140 | class game_version_manager 141 | { 142 | public: 143 | bool Detect() { return true; } 144 | }; 145 | #endif // INJECTOR_GVM_DUMMY 146 | #endif // INJECTOR_OWN_GVM 147 | 148 | 149 | /* 150 | * address_manager 151 | * Address translator from 1.0 executables to other executables offsets 152 | * Inherits from game_version_manager ;) 153 | */ 154 | class address_manager : public game_version_manager 155 | { 156 | private: 157 | address_manager() 158 | { 159 | this->Detect(); 160 | } 161 | 162 | // You could implement your translator for the address your plugin uses 163 | // If not implemented, the translator won't translate anything, just return the samething as before 164 | #ifdef INJECTOR_GVM_HAS_TRANSLATOR 165 | void* translator(void* p); 166 | #else 167 | void* translator(void* p) { return p; } 168 | #endif 169 | 170 | public: 171 | // Translates address p to the running executable pointer 172 | void* translate(void* p) 173 | { 174 | return translator(p); 175 | } 176 | 177 | 178 | public: 179 | // Address manager singleton 180 | static address_manager& singleton() 181 | { 182 | static address_manager m; 183 | return m; 184 | } 185 | 186 | // Static version of translate() 187 | static void* translate_address(void* p) 188 | { 189 | return singleton().translate(p); 190 | } 191 | 192 | // 193 | static void set_name(const char* modname) 194 | { 195 | singleton().PluginName = modname; 196 | } 197 | 198 | public: 199 | // Functors for memory translation: 200 | 201 | // Translates aslr translator 202 | struct fn_mem_translator_aslr 203 | { 204 | void* operator()(void* p) const 205 | { 206 | static uintptr_t module = (uintptr_t)GetModuleHandle(NULL); 207 | return (void*)((uintptr_t)(p)-(0x400000 - module)); 208 | } 209 | }; 210 | 211 | // Translates nothing translator 212 | struct fn_mem_translator_nop 213 | { 214 | void* operator()(void* p) const 215 | { return p; } 216 | }; 217 | 218 | // Real translator 219 | struct fn_mem_translator 220 | { 221 | void* operator()(void* p) const 222 | { return translate_address(p); } 223 | }; 224 | }; 225 | 226 | #endif // #if 1 227 | 228 | 229 | } -------------------------------------------------------------------------------- /includes/injector/gvm/translator.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Injectors - Address Translation Management 3 | * 4 | * Copyright (C) 2014 LINK/2012 5 | * 6 | * This software is provided 'as-is', without any express or implied 7 | * warranty. In no event will the authors be held liable for any damages 8 | * arising from the use of this software. 9 | * 10 | * Permission is granted to anyone to use this software for any purpose, 11 | * including commercial applications, and to alter it and redistribute it 12 | * freely, subject to the following restrictions: 13 | * 14 | * 1. The origin of this software must not be misrepresented; you must not 15 | * claim that you wrote the original software. If you use this software 16 | * in a product, an acknowledgment in the product documentation would be 17 | * appreciated but is not required. 18 | * 19 | * 2. Altered source versions must be plainly marked as such, and must not be 20 | * misrepresented as being the original software. 21 | * 22 | * 3. This notice may not be removed or altered from any source 23 | * distribution. 24 | * 25 | */ 26 | #pragma once 27 | 28 | #if !defined(INJECTOR_GVM_HAS_TRANSLATOR) 29 | #error Missing INJECTOR_GVM_HAS_TRANSLATOR on compiler definitions 30 | #endif 31 | 32 | /* 33 | * This is a quick solution for address translations if you're too lazy to implement a proper address_manager::translator by yourself 34 | * So, just call address_translator_manager::singleton().translate(p) from your address_manager::translator and that's it. 35 | * It'll translate addresses based on 'address_translator' objects, when one gets constructed it turns into a possible translator. 36 | * At the constructor of your derived 'address_translator' make the map object to have [addr_to_translate] = translated_addr; 37 | * There's also the virtual method 'fallback' that will get called when the translation wasn't possible, you can do some fallback stuff here 38 | * (such as return the pointer as is or output a error message) 39 | */ 40 | 41 | #include "../injector.hpp" 42 | #include 43 | #include 44 | #include 45 | 46 | namespace injector 47 | { 48 | /* 49 | * address_translator 50 | * Base for an address translator 51 | */ 52 | class address_translator 53 | { 54 | private: 55 | bool enabled; 56 | void add(); 57 | void remove(); 58 | 59 | protected: 60 | friend class address_translator_manager; 61 | std::map map; 62 | 63 | public: 64 | address_translator() : enabled(true) 65 | { 66 | // Must have bounds filled with min ptr and max ptr to have search working properly 67 | map.insert(std::make_pair(raw_ptr(0x00000000u), raw_ptr(0x00000000u))); 68 | map.insert(std::make_pair(raw_ptr(0xffffffffu), raw_ptr(0xffffffffu))); 69 | add(); 70 | } 71 | 72 | ~address_translator() 73 | { 74 | remove(); 75 | } 76 | 77 | virtual void* fallback(void*) const 78 | { 79 | return nullptr; 80 | } 81 | 82 | 83 | // Enables or disables this translator 84 | void enable(bool enable_it) 85 | { 86 | if(enable_it) this->enable(); 87 | else this->disable(); 88 | } 89 | 90 | // Enables this translator 91 | void enable() 92 | { 93 | this->enabled = true; 94 | } 95 | 96 | // Disables this translator 97 | void disable() 98 | { 99 | this->enabled = false; 100 | } 101 | 102 | // Checks if this translator is enabled 103 | bool is_enabled() const 104 | { 105 | return enabled; 106 | } 107 | }; 108 | 109 | /* 110 | * address_translator_manager 111 | * Manages the address_translator objects 112 | */ 113 | class address_translator_manager 114 | { 115 | protected: 116 | friend class address_manager; 117 | friend class address_translator; 118 | 119 | std::list translators; 120 | 121 | void add(const address_translator& t) 122 | { 123 | translators.push_front(&t); 124 | } 125 | 126 | void remove(const address_translator& t) 127 | { 128 | translators.remove(&t); 129 | } 130 | 131 | public: 132 | // Translates the address p 133 | void* translator(void* p); 134 | 135 | // Singleton object 136 | static address_translator_manager& singleton() 137 | { 138 | static address_translator_manager mgr; 139 | return mgr; 140 | } 141 | }; 142 | 143 | 144 | 145 | inline void* address_translator_manager::translator(void* p_) 146 | { 147 | static const size_t max_ptr_dist = 7; 148 | 149 | // Tries to find an address in a translator map 150 | auto try_map = [](const std::map& map, memory_pointer_raw p) -> memory_pointer_raw 151 | { 152 | memory_pointer_raw result = nullptr; 153 | 154 | // Find first element in the map that is greater than or equal to p 155 | auto it = map.lower_bound(p); 156 | if(it != map.end()) 157 | { 158 | // If it's not exactly the address, get back one position on the table 159 | if(it->first != p) --it; 160 | 161 | auto diff = (p - it->first).as_int(); // What's the difference between p and that address? 162 | if(diff <= max_ptr_dist) // Could we live with this difference in hands? 163 | result = it->second + raw_ptr(diff); // Yes, we can! 164 | } 165 | 166 | return result; 167 | }; 168 | 169 | 170 | // 171 | memory_pointer_raw result = nullptr; 172 | 173 | // Try to find translation for this pointer 174 | auto& mgr = address_translator_manager::singleton().translators; 175 | for(auto it = mgr.begin(); result == nullptr && it != mgr.end(); ++it) 176 | { 177 | auto& t = **it; 178 | if(t.is_enabled()) result = try_map(t.map, p_); 179 | } 180 | 181 | // If we couldn't translate the address, notify and try to fallback 182 | if(result.is_null()) 183 | { 184 | for(auto it = mgr.begin(); result == nullptr && it != mgr.end(); ++it) 185 | { 186 | auto& t = **it; 187 | if(t.is_enabled()) result = t.fallback(p_); 188 | } 189 | } 190 | 191 | return result.get(); 192 | } 193 | 194 | inline void address_translator::add() 195 | { 196 | address_translator_manager::singleton().add(*this); 197 | } 198 | 199 | inline void address_translator::remove() 200 | { 201 | address_translator_manager::singleton().remove(*this); 202 | } 203 | } 204 | -------------------------------------------------------------------------------- /includes/injector/hooking.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Injectors - Classes for making your hooking life easy 3 | * 4 | * Copyright (C) 2013-2014 LINK/2012 5 | * 6 | * This software is provided 'as-is', without any express or implied 7 | * warranty. In no event will the authors be held liable for any damages 8 | * arising from the use of this software. 9 | * 10 | * Permission is granted to anyone to use this software for any purpose, 11 | * including commercial applications, and to alter it and redistribute it 12 | * freely, subject to the following restrictions: 13 | * 14 | * 1. The origin of this software must not be misrepresented; you must not 15 | * claim that you wrote the original software. If you use this software 16 | * in a product, an acknowledgment in the product documentation would be 17 | * appreciated but is not required. 18 | * 19 | * 2. Altered source versions must be plainly marked as such, and must not be 20 | * misrepresented as being the original software. 21 | * 22 | * 3. This notice may not be removed or altered from any source 23 | * distribution. 24 | * 25 | */ 26 | #pragma once 27 | #include "injector.hpp" 28 | #include 29 | #include 30 | #include // for std::shared_ptr 31 | #include 32 | 33 | namespace injector 34 | { 35 | /* 36 | * scoped_base 37 | * Base for any scoped hooking type 38 | * !!!! NOTICE !!!! --> Any derived which implements/reimplements restore() should implement a destructor calling it 39 | */ 40 | class scoped_base 41 | { 42 | public: 43 | virtual ~scoped_base() {} 44 | virtual void restore() = 0; 45 | }; 46 | 47 | /* 48 | * scoped_basic 49 | * Base for scoped types which will need a buffer to save/restore stuff 50 | */ 51 | template // TODO specialize bufsize=0 to be dynamic 52 | class scoped_basic : public scoped_base 53 | { 54 | private: 55 | uint8_t buf[bufsize];// Saved content 56 | memory_pointer_raw addr; // Data saved from this address 57 | size_t size; // Size saved 58 | bool saved; // Something saved? 59 | bool vp; // Virtual protect? 60 | 61 | public: 62 | 63 | static const bool is_dynamic = false; 64 | 65 | // Restore the previosly saved data 66 | // Problems may arise if someone else hooked the same place using the same method 67 | virtual void restore() 68 | { 69 | #ifndef INJECTOR_SCOPED_NOSAVE_NORESTORE 70 | if(this->saved) 71 | { 72 | WriteMemoryRaw(this->addr, this->buf, this->size, this->vp); 73 | this->saved = false; 74 | } 75 | #endif 76 | } 77 | 78 | // Save buffer at @addr with @size and virtual protect @vp 79 | virtual void save(memory_pointer_tr addr, size_t size, bool vp) 80 | { 81 | #ifndef INJECTOR_SCOPED_NOSAVE_NORESTORE 82 | assert(size <= bufsize); // Debug Safeness 83 | this->restore(); // Restore anything we have saved 84 | this->saved = true; // Mark that we have data save 85 | this->addr = addr.get(); // Save address 86 | this->size = size; // Save size 87 | this->vp = vp; // Save virtual protect 88 | ReadMemoryRaw(addr, buf, size, vp); // Save buffer 89 | #endif 90 | } 91 | 92 | public: 93 | // Constructor, initialises 94 | scoped_basic() : saved(false) 95 | {} 96 | 97 | ~scoped_basic() 98 | { 99 | this->restore(); 100 | } 101 | 102 | // No copy construction, we can't do this! Sure we can move construct :) 103 | scoped_basic(const scoped_basic&) = delete; 104 | scoped_basic(scoped_basic&& rhs) 105 | { 106 | *this = std::move(rhs); 107 | } 108 | 109 | scoped_basic& operator=(const scoped_basic& rhs) = delete; 110 | scoped_basic& operator=(scoped_basic&& rhs) 111 | { 112 | if(this->saved = rhs.saved) 113 | { 114 | assert(bufsize >= rhs.size); 115 | 116 | this->addr = rhs.addr; 117 | this->size = rhs.size; 118 | this->vp = rhs.vp; 119 | memcpy(buf, rhs.buf, rhs.size); 120 | 121 | rhs.saved = false; 122 | } 123 | return *this; 124 | } 125 | }; 126 | 127 | /* 128 | * RAII wrapper for memory writes 129 | * Can save only basic and POD types 130 | */ 131 | template 132 | class scoped_write : public scoped_basic 133 | { 134 | public: 135 | // Save buffer at @addr with @size and virtual protect @vp and then overwrite it with @value 136 | void write(memory_pointer_tr addr, void* value, size_t size, bool vp) 137 | { 138 | this->save(addr, size, vp); 139 | return WriteMemoryRaw(addr, value, size, vp); 140 | } 141 | 142 | // Save buffer at @addr with size sizeof(@value) and virtual protect @vp and then overwrite it with @value 143 | template 144 | void write(memory_pointer_tr addr, T value, bool vp = false) 145 | { 146 | this->save(addr, sizeof(T), vp); 147 | return WriteMemory(addr, value, vp); 148 | } 149 | 150 | // Constructors, move constructors, assigment operators........ 151 | scoped_write() = default; 152 | scoped_write(const scoped_write&) = delete; 153 | scoped_write(scoped_write&& rhs) : scoped_basic(std::move(rhs)) {} 154 | scoped_write& operator=(const scoped_write& rhs) = delete; 155 | scoped_write& operator=(scoped_write&& rhs) 156 | { scoped_basic::operator=(std::move(rhs)); return *this; } 157 | }; 158 | 159 | /* 160 | * RAII wrapper for filling 161 | */ 162 | template 163 | class scoped_fill : public scoped_basic 164 | { 165 | public: 166 | // Fills memory at @addr with value @value and size @size and virtual protect @vp 167 | void fill(memory_pointer_tr addr, uint8_t value, size_t size, bool vp) 168 | { 169 | this->save(addr, size, vp); 170 | return MemoryFill(addr, value, size, vp); 171 | } 172 | 173 | // Constructors, move constructors, assigment operators........ 174 | scoped_fill() = default; 175 | scoped_fill(const scoped_fill&) = delete; 176 | scoped_fill(scoped_fill&& rhs) : scoped_basic(std::move(rhs)) {} 177 | scoped_fill& operator=(const scoped_fill& rhs) = delete; 178 | scoped_fill& operator=(scoped_fill&& rhs) 179 | { scoped_basic::operator=(std::move(rhs)); return *this; } 180 | 181 | scoped_fill(memory_pointer_tr addr, uint8_t value, size_t size, bool vp) 182 | { fill(addr, value, vp); } 183 | }; 184 | 185 | /* 186 | * RAII wrapper for nopping 187 | */ 188 | template 189 | class scoped_nop : public scoped_basic 190 | { 191 | public: 192 | // Makes NOP at @addr with value @value and size @size and virtual protect @vp 193 | void make_nop(memory_pointer_tr addr, size_t size = 1, bool vp = true) 194 | { 195 | this->save(addr, size, vp); 196 | return MakeNOP(addr, size, vp); 197 | } 198 | 199 | // Constructors, move constructors, assigment operators........ 200 | scoped_nop() = default; 201 | scoped_nop(const scoped_nop&) = delete; 202 | scoped_nop(scoped_nop&& rhs) : scoped_basic(std::move(rhs)) {} 203 | scoped_nop& operator=(const scoped_nop& rhs) = delete; 204 | scoped_nop& operator=(scoped_nop&& rhs) 205 | { scoped_basic::operator=(std::move(rhs)); return *this; } 206 | 207 | scoped_nop(memory_pointer_tr addr, size_t size = 1, bool vp = true) 208 | { make_nop(addr, size, vp); } 209 | }; 210 | 211 | /* 212 | * RAII wrapper for MakeJMP 213 | */ 214 | class scoped_jmp : public scoped_basic<5> 215 | { 216 | public: 217 | // Makes NOP at @addr with value @value and size @size and virtual protect @vp 218 | memory_pointer_raw make_jmp(memory_pointer_tr at, memory_pointer_raw dest, bool vp = true) 219 | { 220 | this->save(at, 5, vp); 221 | return MakeJMP(at, dest, vp); 222 | } 223 | 224 | // Constructors, move constructors, assigment operators........ 225 | scoped_jmp() = default; 226 | scoped_jmp(const scoped_jmp&) = delete; 227 | scoped_jmp(scoped_jmp&& rhs) : scoped_basic<5>(std::move(rhs)) {} 228 | scoped_jmp& operator=(const scoped_jmp& rhs) = delete; 229 | scoped_jmp& operator=(scoped_jmp&& rhs) 230 | { scoped_basic<5>::operator=(std::move(rhs)); return *this; } 231 | 232 | scoped_jmp(memory_pointer_tr at, memory_pointer_raw dest, bool vp = true) 233 | { make_jmp(at, dest, vp); } 234 | }; 235 | 236 | /* 237 | * RAII wrapper for MakeCALL 238 | */ 239 | class scoped_call : public scoped_basic<5> 240 | { 241 | public: 242 | // Makes NOP at @addr with value @value and size @size and virtual protect @vp 243 | memory_pointer_raw make_call(memory_pointer_tr at, memory_pointer_raw dest, bool vp = true) 244 | { 245 | this->save(at, 5, vp); 246 | return MakeCALL(at, dest, vp); 247 | } 248 | 249 | // Constructors, move constructors, assigment operators........ 250 | scoped_call() = default; 251 | scoped_call(const scoped_call&) = delete; 252 | scoped_call(scoped_call&& rhs) : scoped_basic<5>(std::move(rhs)) {} 253 | scoped_call& operator=(const scoped_call& rhs) = delete; 254 | scoped_call& operator=(scoped_call&& rhs) 255 | { scoped_basic<5>::operator=(std::move(rhs)); return *this; } 256 | 257 | scoped_call(memory_pointer_tr at, memory_pointer_raw dest, bool vp = true) 258 | { make_call(at, dest, vp); } 259 | }; 260 | 261 | 262 | #if __cplusplus >= 201103L || _MSC_VER >= 1800 // C++11 or MSVC 2013 required for variadic templates 263 | 264 | /* 265 | * function_hooker_manager 266 | * Manages many function_hookers that points to the same address 267 | * The need for this function arises because otherwise we would only be able to allow one hook per address using function_hookers 268 | * This manager takes care of the amount of hooks placed in a particular address, calls the hooks and unhooks when necessary. 269 | */ 270 | template 271 | class function_hooker_manager : protected scoped_call 272 | { 273 | private: 274 | using func_type_raw = typename ToManage::func_type_raw; 275 | using func_type = typename ToManage::func_type; 276 | using functor_type = typename ToManage::functor_type; 277 | using assoc_type = std::list>; 278 | 279 | // Only construction is allowed... by myself ofcourse... 280 | function_hooker_manager() = default; 281 | function_hooker_manager(const function_hooker_manager&) = delete; 282 | function_hooker_manager(function_hooker_manager&&) = delete; 283 | 284 | // 285 | func_type_raw original; // Pointer to the original function we've replaced 286 | assoc_type assoc; // Association between owners of a hook and the hook (map) 287 | bool has_hooked = false; // Is the hook already in place? 288 | 289 | // Find assoc iterator for the content owned by 'owned' 290 | typename assoc_type::iterator find_assoc(const ToManage& owner) 291 | { 292 | for(auto it = assoc.begin(); it != assoc.end(); ++it) 293 | if(it->first == &owner) return it; 294 | return assoc.end(); 295 | } 296 | 297 | // Adds a new item to the association map (or override if already in the map) 298 | void add(const ToManage& hooker, functor_type functor) 299 | { 300 | auto it = find_assoc(hooker); 301 | if(it != assoc.end()) 302 | it->second = std::move(functor); 303 | else 304 | assoc.emplace_back(&hooker, std::move(functor)); 305 | } 306 | 307 | public: 308 | // Forwards the call to all the installed hooks 309 | static Ret call_hooks(Args&... args) 310 | { 311 | auto& manager = *instance(); 312 | 313 | if(manager.assoc.size() == 0) // This may be uncommon but may happen (?), no hook installed 314 | return manager.original(args...); 315 | 316 | // Functor for the original call 317 | func_type original = [&manager](Args... args) -> Ret { 318 | return manager.original(args...); 319 | }; 320 | 321 | if(manager.assoc.size() == 1) 322 | { 323 | // We have only one hook, just use it directly no need to go further in complexity 324 | auto& functor = manager.assoc.begin()->second; 325 | return functor(std::move(original), args...); 326 | } 327 | else 328 | { 329 | // Build a serie of functors which captures the previous functor sending it to the next functor, 330 | // that's what would happen if the hooks took place independent of the template staticness (AAAAAAA) 331 | func_type next = std::move(original); 332 | for(auto it = manager.assoc.begin(); it != manager.assoc.end(); ++it) 333 | { 334 | auto& functor = it->second; 335 | next = [functor, next](Args... args) -> Ret 336 | { 337 | return functor(next, args...); 338 | }; 339 | } 340 | return next(args...); 341 | } 342 | } 343 | 344 | public: 345 | 346 | // Installs a hook associated with the function_hooker 'hooker' which would call the specified 'functor' 347 | // We need an auxiliar function pointer 'ptr' (to abstract calling conventions) which should forward itself to ^call_hooks 348 | void make_call(const ToManage& hooker, functor_type functor, memory_pointer_raw ptr) 349 | { 350 | this->add(hooker, std::move(functor)); 351 | 352 | // Make sure we only hook this address for the manager once 353 | if(!this->has_hooked) 354 | { 355 | // (the following cast is needed for __thiscall functions) 356 | this->original = (func_type_raw) (void*) scoped_call::make_call(hooker.addr, ptr).get(); 357 | this->has_hooked = true; 358 | } 359 | } 360 | 361 | // Restores the state of the call we've replaced in the game code 362 | // All installed hooks gets uninstalled after this 363 | void restore() 364 | { 365 | if(this->has_hooked) 366 | { 367 | this->has_hooked = false; 368 | this->assoc.clear(); 369 | return scoped_call::restore(); 370 | } 371 | } 372 | 373 | // Replaces the hook associated with 'from' to be associated with 'to' 374 | // After this call the 'from' object has no association in this manager 375 | void replace(const ToManage& from, const ToManage& to) 376 | { 377 | auto it = find_assoc(from); 378 | if(it != assoc.end()) 379 | { 380 | auto functor = std::move(it->second); 381 | assoc.erase(it); 382 | this->add(to, std::move(functor)); 383 | } 384 | } 385 | 386 | // Removes the hook associated with the specified 'hooker' 387 | // If the number of hooks reaches zero after the remotion, a restore will take place 388 | void remove(const ToManage& hooker) 389 | { 390 | auto it = find_assoc(hooker); 391 | if(it != assoc.end()) 392 | { 393 | assoc.erase(it); 394 | if(assoc.size() == 0) this->restore(); 395 | } 396 | } 397 | 398 | // The instance of this specific manager 399 | // This work as a shared pointer to avoid the static destruction of the manager even when a static function_hooker 400 | // still wants to use it. 401 | static std::shared_ptr instance() 402 | { 403 | static auto fm_ptr = std::shared_ptr(new function_hooker_manager()); 404 | return fm_ptr; 405 | } 406 | 407 | }; 408 | 409 | 410 | /* 411 | * function_hooker_base 412 | * Base for any function_hooker, this class manages the relationship with the function hooker manager 413 | */ 414 | template 415 | class function_hooker_base : public scoped_base 416 | { 417 | public: 418 | static const uintptr_t addr = addr1; 419 | 420 | using func_type_raw = FuncType; 421 | using func_type = std::function; 422 | using functor_type = std::function; 423 | using manager_type = function_hooker_manager; 424 | 425 | public: 426 | // Constructors, move constructors, assigment operators........ 427 | function_hooker_base(const function_hooker_base&) = delete; 428 | function_hooker_base& operator=(const function_hooker_base& rhs) = delete; 429 | 430 | function_hooker_base() : manager(manager_type::instance()) 431 | {} 432 | 433 | // 434 | virtual ~function_hooker_base() 435 | { 436 | this->restore(); 437 | } 438 | 439 | // The move constructor should do a replace in the manager 440 | function_hooker_base(function_hooker_base&& rhs) 441 | : scoped_base(std::move(rhs)), has_call(rhs.has_call), 442 | manager(rhs.manager) // (don't move the manager!, every function_hooker should own one) 443 | { 444 | manager->replace(rhs, *this); 445 | } 446 | 447 | // The move assignment operator should also do a replace in the manager 448 | function_hooker_base& operator=(function_hooker_base&& rhs) 449 | { 450 | scoped_base::operator=(std::move(rhs)); 451 | manager->replace(rhs, *this); 452 | this->has_call = rhs.has_call; 453 | this->manager = rhs.manager; // (don't move the manager! every function_hooker should own one) 454 | return *this; 455 | } 456 | 457 | // Deriveds should implement a proper make_call (yeah it's virtual so derived-deriveds can do some fest) 458 | virtual void make_call(functor_type functor) = 0; 459 | 460 | // Restores the state of the call we've replaced in the game code 461 | virtual void restore() 462 | { 463 | this->has_call = false; 464 | manager->remove(*this); 465 | } 466 | 467 | // Checkers whether a hook is installed 468 | bool has_hooked() 469 | { 470 | return this->has_call; 471 | } 472 | 473 | private: 474 | bool has_call = false; // Has a hook installed? 475 | std::shared_ptr manager; // **EVERY** function_hooker should have a ownership over it's manager_type 476 | // this prevents the static destruction of the manager_type while it may be still needed. 477 | 478 | protected: // Forwarders to the function hooker manager 479 | 480 | void make_call(functor_type functor, memory_pointer_raw ptr) 481 | { 482 | this->has_call = true; 483 | manager->make_call(*this, std::move(functor), ptr); 484 | } 485 | 486 | static Ret call_hooks(Args&... a) 487 | { 488 | return manager_type::call_hooks(a...); 489 | } 490 | }; 491 | 492 | 493 | 494 | 495 | /* 496 | * function_hooker 497 | * For standard conventions (usually __cdecl) 498 | */ 499 | template 500 | struct function_hooker; 501 | 502 | template 503 | class function_hooker 504 | : public function_hooker_base 505 | { 506 | private: 507 | using base = function_hooker_base; 508 | 509 | // The hook caller 510 | static Ret call(Args... a) 511 | { 512 | return base::call_hooks(a...); 513 | } 514 | 515 | public: 516 | // Constructors, move constructors, assigment operators........ 517 | function_hooker() = default; 518 | function_hooker(const function_hooker&) = delete; 519 | function_hooker(function_hooker&& rhs) : base(std::move(rhs)) {} 520 | function_hooker& operator=(const function_hooker& rhs) = delete; 521 | function_hooker& operator=(function_hooker&& rhs) 522 | { base::operator=(std::move(rhs)); return *this; } 523 | 524 | // Makes the hook 525 | void make_call(typename base::functor_type functor) 526 | { 527 | return base::make_call(std::move(functor), raw_ptr(call)); 528 | } 529 | }; 530 | 531 | 532 | /* 533 | * function_hooker_stdcall 534 | * For stdcall conventions (__stdcall) 535 | */ 536 | template 537 | struct function_hooker_stdcall; 538 | 539 | template 540 | struct function_hooker_stdcall 541 | : public function_hooker_base 542 | { 543 | private: 544 | using base = function_hooker_base; 545 | 546 | // The hook caller 547 | static Ret __stdcall call(Args... a) 548 | { 549 | return base::call_hooks(a...); 550 | } 551 | 552 | public: 553 | // Constructors, move constructors, assigment operators........ 554 | function_hooker_stdcall() = default; 555 | function_hooker_stdcall(const function_hooker_stdcall&) = delete; 556 | function_hooker_stdcall(function_hooker_stdcall&& rhs) : base(std::move(rhs)) {} 557 | function_hooker_stdcall& operator=(const function_hooker_stdcall& rhs) = delete; 558 | function_hooker_stdcall& operator=(function_hooker_stdcall&& rhs) 559 | { base::operator=(std::move(rhs)); return *this; } 560 | 561 | // Makes the hook 562 | void make_call(typename base::functor_type functor) 563 | { 564 | return base::make_call(std::move(functor), raw_ptr(call)); 565 | } 566 | }; 567 | 568 | 569 | /* 570 | * function_hooker_fastcall 571 | * For fastcall conventions (__fastcall) 572 | */ 573 | template 574 | struct function_hooker_fastcall; 575 | 576 | template 577 | struct function_hooker_fastcall 578 | : public function_hooker_base 579 | { 580 | private: 581 | using base = function_hooker_base; 582 | 583 | // The hook caller 584 | static Ret __fastcall call(Args... a) 585 | { 586 | return base::call_hooks(a...); 587 | } 588 | 589 | public: 590 | // Constructors, move constructors, assigment operators........ 591 | function_hooker_fastcall() = default; 592 | function_hooker_fastcall(const function_hooker_fastcall&) = delete; 593 | function_hooker_fastcall(function_hooker_fastcall&& rhs) : base(std::move(rhs)) {} 594 | function_hooker_fastcall& operator=(const function_hooker_fastcall& rhs) = delete; 595 | function_hooker_fastcall& operator=(function_hooker_fastcall&& rhs) 596 | { base::operator=(std::move(rhs)); return *this; } 597 | 598 | // Makes the hook 599 | void make_call(typename base::functor_type functor) 600 | { 601 | return base::make_call(std::move(functor), raw_ptr(call)); 602 | } 603 | }; 604 | 605 | 606 | /* 607 | * function_hooker_thiscall 608 | * For thiscall conventions (__thiscall, class methods) 609 | */ 610 | template 611 | struct function_hooker_thiscall; 612 | 613 | template 614 | struct function_hooker_thiscall 615 | : public function_hooker_base 616 | { 617 | private: 618 | using base = function_hooker_base; 619 | 620 | // The hook caller 621 | static Ret __thiscall call(Args... a) 622 | { 623 | return base::call_hooks(a...); 624 | } 625 | 626 | public: 627 | // Constructors, move constructors, assigment operators........ 628 | function_hooker_thiscall() = default; 629 | function_hooker_thiscall(const function_hooker_thiscall&) = delete; 630 | function_hooker_thiscall(function_hooker_thiscall&& rhs) : base(std::move(rhs)) {} 631 | function_hooker_thiscall& operator=(const function_hooker_thiscall& rhs) = delete; 632 | function_hooker_thiscall& operator=(function_hooker_thiscall&& rhs) 633 | { base::operator=(std::move(rhs)); return *this; } 634 | 635 | // Makes the hook 636 | void make_call(typename base::functor_type functor) 637 | { 638 | return base::make_call(std::move(functor), raw_ptr(call)); 639 | } 640 | }; 641 | 642 | 643 | 644 | /******************* HELPERS ******************/ 645 | 646 | /* 647 | * Adds a hook to be alive for the entire program lifetime 648 | * That means the hook received will be alive until the program dies. 649 | * Note: Parameter must be a rvalue 650 | */ 651 | template inline 652 | T& add_static_hook(T&& hooker) 653 | { 654 | static std::list a; 655 | return *a.emplace(a.end(), std::move(hooker)); 656 | } 657 | 658 | /* 659 | * Makes a hook which is alive until it gets out of scope 660 | * 'T' must be any function_hooker object 661 | */ 662 | template inline 663 | T make_function_hook(F functor) 664 | { 665 | T a; 666 | a.make_call(std::move(functor)); 667 | return a; 668 | } 669 | 670 | /* 671 | * Makes a hook which is alive for the entire lifetime of this program 672 | * 'T' must be any function_hooker object 673 | */ 674 | template inline 675 | T& make_static_hook(F functor) 676 | { 677 | return add_static_hook(make_function_hook(std::move(functor))); 678 | } 679 | 680 | 681 | // TODO when we have access to C++14 add a make_function_hook, make_stdcall_function_hook, and so on 682 | // the problem behind implement it with C++11 is that lambdas cannot be generic and the first param of a hook is a functor pointing 683 | // to the previous call pointer 684 | 685 | #endif 686 | 687 | } 688 | -------------------------------------------------------------------------------- /includes/injector/injector.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Injectors - Base Header 3 | * 4 | * Copyright (C) 2012-2014 LINK/2012 5 | * 6 | * This software is provided 'as-is', without any express or implied 7 | * warranty. In no event will the authors be held liable for any damages 8 | * arising from the use of this software. 9 | * 10 | * Permission is granted to anyone to use this software for any purpose, 11 | * including commercial applications, and to alter it and redistribute it 12 | * freely, subject to the following restrictions: 13 | * 14 | * 1. The origin of this software must not be misrepresented; you must not 15 | * claim that you wrote the original software. If you use this software 16 | * in a product, an acknowledgment in the product documentation would be 17 | * appreciated but is not required. 18 | * 19 | * 2. Altered source versions must be plainly marked as such, and must not be 20 | * misrepresented as being the original software. 21 | * 22 | * 3. This notice may not be removed or altered from any source 23 | * distribution. 24 | * 25 | */ 26 | #pragma once 27 | #define INJECTOR_HAS_INJECTOR_HPP 28 | #include 29 | #include 30 | #include 31 | #include "gvm/gvm.hpp" 32 | /* 33 | The following macros (#define) are relevant on this header: 34 | 35 | INJECTOR_GVM_HAS_TRANSLATOR 36 | If defined, the user should provide their own address_manager::translator function. 37 | That function is responssible for translating a void pointer (that mayn't be an actual pointer) into an actual address. 38 | The meaning of that void pointer will be made by YOU when you send it to the functions that receive pointers on this library. 39 | The default translator does nothing but returns that void pointer as the address. 40 | 41 | INJECTOR_GVM_OWN_DETECT 42 | If defined, the user should provide it's own game detection function thought game_version_manager::Detect 43 | By default it provide an good detection for the Grand Theft Auto series. 44 | 45 | INJECTOR_GVM_PLUGIN_NAME 46 | If this is defined, it will be used as the plugin name used at error messages. 47 | By default it will use ""Unknown Plugin Name" 48 | 49 | INJECTOR_GVM_DUMMY 50 | If defined, the game_version_manager will be a dummy object 51 | By default it provides a nice gvm for Grand Theft Auto series 52 | 53 | INJECTOR_OWN_GVM 54 | If defined, the game_version_manager should be implemented by the user before including this library. 55 | By default it provides a nice gvm for Grand Theft Auto series 56 | */ 57 | #include "gvm/gvm.hpp" 58 | 59 | 60 | 61 | namespace injector 62 | { 63 | 64 | 65 | /* 66 | * auto_pointer 67 | * Casts itself to another pointer type in the lhs 68 | */ 69 | union auto_pointer 70 | { 71 | protected: 72 | friend union memory_pointer_tr; 73 | template friend union basic_memory_pointer; 74 | 75 | void* p; 76 | uintptr_t a; 77 | 78 | public: 79 | auto_pointer() : p(0) {} 80 | auto_pointer(const auto_pointer& x) : p(x.p) {} 81 | explicit auto_pointer(void* x) : p(x) {} 82 | explicit auto_pointer(uint32_t x) : a(x) {} 83 | 84 | bool is_null() const { return this->p != nullptr; } 85 | 86 | #if __cplusplus >= 201103L || _MSC_VER >= 1800 87 | explicit operator bool() const { return is_null(); } 88 | #endif 89 | 90 | auto_pointer get() const { return *this; } 91 | template T* get() const { return (T*) this->p; } 92 | template T* get_raw() const { return (T*) this->p; } 93 | 94 | template 95 | operator T*() const { return reinterpret_cast(p); } 96 | }; 97 | 98 | /* 99 | * basic_memory_pointer 100 | * A memory pointer class that is capable of many operations, including address translation 101 | * MemTranslator is the translator functor 102 | */ 103 | template 104 | union basic_memory_pointer 105 | { 106 | protected: 107 | void* p; 108 | uintptr_t a; 109 | 110 | // Translates address p to the running executable pointer 111 | static auto_pointer memory_translate(void* p) 112 | { 113 | return auto_pointer(MemTranslator()(p)); 114 | } 115 | 116 | public: 117 | basic_memory_pointer() : p(nullptr) {} 118 | basic_memory_pointer(std::nullptr_t) : p(nullptr) {} 119 | basic_memory_pointer(uintptr_t x) : a(x) {} 120 | basic_memory_pointer(const auto_pointer& x) : p(x.p) {} 121 | basic_memory_pointer(const basic_memory_pointer& rhs) : p(rhs.p) {} 122 | 123 | template 124 | basic_memory_pointer(T* x) : p((void*)x) {} 125 | 126 | 127 | 128 | 129 | // Gets the translated pointer (plus automatic casting to lhs) 130 | auto_pointer get() const { return memory_translate(p); } 131 | 132 | // Gets the translated pointer (casted to T*) 133 | template T* get() const { return get(); } 134 | 135 | // Gets the raw pointer, without translation (casted to T*) 136 | template T* get_raw() const { return auto_pointer(p); } 137 | 138 | // This type can get assigned from void* and uintptr_t 139 | basic_memory_pointer& operator=(void* x) { return p = x, *this; } 140 | basic_memory_pointer& operator=(uintptr_t x) { return a = x, *this; } 141 | 142 | /* Arithmetic */ 143 | basic_memory_pointer operator+(const basic_memory_pointer& rhs) const 144 | { return basic_memory_pointer(this->a + rhs.a); } 145 | 146 | basic_memory_pointer operator-(const basic_memory_pointer& rhs) const 147 | { return basic_memory_pointer(this->a - rhs.a); } 148 | 149 | basic_memory_pointer operator*(const basic_memory_pointer& rhs) const 150 | { return basic_memory_pointer(this->a * rhs.a); } 151 | 152 | basic_memory_pointer operator/(const basic_memory_pointer& rhs) const 153 | { return basic_memory_pointer(this->a / rhs.a); } 154 | 155 | 156 | /* Comparision */ 157 | bool operator==(const basic_memory_pointer& rhs) const 158 | { return this->a == rhs.a; } 159 | 160 | bool operator!=(const basic_memory_pointer& rhs) const 161 | { return this->a != rhs.a; } 162 | 163 | bool operator<(const basic_memory_pointer& rhs) const 164 | { return this->a < rhs.a; } 165 | 166 | bool operator<=(const basic_memory_pointer& rhs) const 167 | { return this->a <= rhs.a; } 168 | 169 | bool operator>(const basic_memory_pointer& rhs) const 170 | { return this->a > rhs.a; } 171 | 172 | bool operator>=(const basic_memory_pointer& rhs) const 173 | { return this->a >=rhs.a; } 174 | 175 | bool is_null() const { return this->p == nullptr; } 176 | uintptr_t as_int() const { return this->a; } // does not perform translation 177 | 178 | 179 | 180 | #if __cplusplus >= 201103L || _MSC_VER >= 1800 // MSVC 2013 181 | /* Conversion to other types */ 182 | explicit operator uintptr_t() const 183 | { return this->a; } // does not perform translation 184 | explicit operator bool() const 185 | { return this->p != nullptr; } 186 | #else 187 | //operator bool() -------------- Causes casting problems because of implicitness, use !is_null() 188 | //{ return this->p != nullptr; } 189 | #endif 190 | 191 | }; 192 | 193 | // Typedefs including memory translator for the above type 194 | typedef basic_memory_pointer memory_pointer; 195 | typedef basic_memory_pointer memory_pointer_raw; 196 | typedef basic_memory_pointer memory_pointer_aslr; 197 | 198 | 199 | 200 | /* 201 | * memory_pointer_tr 202 | * Stores a basic_memory_pointer as a raw pointer from translated pointer 203 | */ 204 | union memory_pointer_tr 205 | { 206 | protected: 207 | void* p; 208 | uintptr_t a; 209 | 210 | public: 211 | template 212 | memory_pointer_tr(const basic_memory_pointer& ptr) 213 | : p(ptr.get()) 214 | {} // Constructs from a basic_memory_pointer 215 | 216 | memory_pointer_tr(const auto_pointer& ptr) 217 | : p(ptr.p) 218 | {} // Constructs from a auto_pointer, probably comming from basic_memory_pointer::get 219 | 220 | memory_pointer_tr(const memory_pointer_tr& rhs) 221 | : p(rhs.p) 222 | {} // Constructs from my own type, copy constructor 223 | 224 | memory_pointer_tr(uintptr_t x) 225 | : p(memory_pointer(x).get()) 226 | {} // Constructs from a integer, translating the address 227 | 228 | memory_pointer_tr(void* x) 229 | : p(memory_pointer(x).get()) 230 | {} // Constructs from a void pointer, translating the address 231 | 232 | // Just to be method-compatible with basic_memory_pointer ... 233 | auto_pointer get() { return auto_pointer(p); } 234 | template T* get() { return get(); } 235 | template T* get_raw() { return get(); } 236 | 237 | memory_pointer_tr operator+(const uintptr_t& rhs) const 238 | { return memory_pointer_raw(this->a + rhs); } 239 | 240 | memory_pointer_tr operator-(const uintptr_t& rhs) const 241 | { return memory_pointer_raw(this->a - rhs); } 242 | 243 | memory_pointer_tr operator*(const uintptr_t& rhs) const 244 | { return memory_pointer_raw(this->a * rhs); } 245 | 246 | memory_pointer_tr operator/(const uintptr_t& rhs) const 247 | { return memory_pointer_raw(this->a / rhs); } 248 | 249 | bool is_null() const { return this->p == nullptr; } 250 | uintptr_t as_int() const { return this->a; } 251 | 252 | #if __cplusplus >= 201103L 253 | explicit operator uintptr_t() const 254 | { return this->a; } 255 | #else 256 | #endif 257 | 258 | }; 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | /* 267 | * ProtectMemory 268 | * Makes the address @addr have a protection of @protection 269 | */ 270 | inline bool ProtectMemory(memory_pointer_tr addr, size_t size, DWORD protection) 271 | { 272 | return VirtualProtect(addr.get(), size, protection, &protection) != 0; 273 | } 274 | 275 | /* 276 | * UnprotectMemory 277 | * Unprotect the memory at @addr with size @size so it have all accesses (execute, read and write) 278 | * Returns the old protection to out_oldprotect 279 | */ 280 | inline bool UnprotectMemory(memory_pointer_tr addr, size_t size, DWORD& out_oldprotect) 281 | { 282 | return VirtualProtect(addr.get(), size, PAGE_EXECUTE_READWRITE, &out_oldprotect) != 0; 283 | } 284 | 285 | /* 286 | * scoped_unprotect 287 | * RAII wrapper for UnprotectMemory 288 | * On construction unprotects the memory, on destruction reprotects the memory 289 | */ 290 | struct scoped_unprotect 291 | { 292 | memory_pointer_raw addr; 293 | size_t size; 294 | DWORD dwOldProtect; 295 | bool bUnprotected; 296 | 297 | scoped_unprotect(memory_pointer_tr addr, size_t size) 298 | { 299 | if(size == 0) bUnprotected = false; 300 | else bUnprotected = UnprotectMemory(this->addr = addr.get(), this->size = size, dwOldProtect); 301 | } 302 | 303 | ~scoped_unprotect() 304 | { 305 | if(bUnprotected) ProtectMemory(this->addr.get(), this->size, this->dwOldProtect); 306 | } 307 | }; 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | /* 317 | * WriteMemoryRaw 318 | * Writes into memory @addr the content of @value with a sizeof @size 319 | * Does memory unprotection if @vp is true 320 | */ 321 | inline void WriteMemoryRaw(memory_pointer_tr addr, void* value, size_t size, bool vp) 322 | { 323 | scoped_unprotect xprotect(addr, vp? size : 0); 324 | memcpy(addr.get(), value, size); 325 | } 326 | 327 | /* 328 | * ReadMemoryRaw 329 | * Reads the memory at @addr with a sizeof @size into address @ret 330 | * Does memory unprotection if @vp is true 331 | */ 332 | inline void ReadMemoryRaw(memory_pointer_tr addr, void* ret, size_t size, bool vp) 333 | { 334 | scoped_unprotect xprotect(addr, vp? size : 0); 335 | memcpy(ret, addr.get(), size); 336 | } 337 | 338 | /* 339 | * MemoryFill 340 | * Fills the memory at @addr with the byte @value doing it @size times 341 | * Does memory unprotection if @vp is true 342 | */ 343 | inline void MemoryFill(memory_pointer_tr addr, uint8_t value, size_t size, bool vp) 344 | { 345 | scoped_unprotect xprotect(addr, vp? size : 0); 346 | memset(addr.get(), value, size); 347 | } 348 | 349 | /* 350 | * WriteObject 351 | * Assigns the object @value into the same object type at @addr 352 | * Does memory unprotection if @vp is true 353 | */ 354 | template 355 | inline T& WriteObject(memory_pointer_tr addr, const T& value, bool vp = false) 356 | { 357 | scoped_unprotect xprotect(addr, vp? sizeof(value) : 0); 358 | return (*addr.get() = value); 359 | } 360 | 361 | /* 362 | * ReadObject 363 | * Assigns the object @value with the value of the same object type at @addr 364 | * Does memory unprotection if @vp is true 365 | */ 366 | template 367 | inline T& ReadObject(memory_pointer_tr addr, T& value, bool vp = false) 368 | { 369 | scoped_unprotect xprotect(addr, vp? sizeof(value) : 0); 370 | return (value = *addr.get()); 371 | } 372 | 373 | 374 | /* 375 | * WriteMemory 376 | * Writes the object of type T into the address @addr 377 | * Does memory unprotection if @vp is true 378 | */ 379 | template 380 | inline void WriteMemory(memory_pointer_tr addr, T value, bool vp = false) 381 | { 382 | WriteObject(addr, value, vp); 383 | } 384 | 385 | /* 386 | * ReadMemory 387 | * Reads the object type T at address @addr 388 | * Does memory unprotection if @vp is true 389 | */ 390 | template 391 | inline T ReadMemory(memory_pointer_tr addr, bool vp = false) 392 | { 393 | T value; 394 | return ReadObject(addr, value, vp); 395 | } 396 | 397 | /* 398 | * AdjustPointer 399 | * Searches in the range [@addr, @addr + @max_search] for a pointer in the range [@default_base, @default_end] and replaces 400 | * it with the proper offset in the pointer @replacement_base. 401 | * Does memory unprotection if @vp is true. 402 | */ 403 | inline memory_pointer_raw AdjustPointer(memory_pointer_tr addr, 404 | memory_pointer_raw replacement_base, memory_pointer_tr default_base, memory_pointer_tr default_end, 405 | size_t max_search = 8, bool vp = true) 406 | { 407 | scoped_unprotect xprotect(addr, vp? max_search + sizeof(void*) : 0); 408 | for(size_t i = 0; i < max_search; ++i) 409 | { 410 | memory_pointer_raw ptr = ReadMemory(addr + i); 411 | if(ptr >= default_base.get() && ptr <= default_end.get()) 412 | { 413 | auto result = replacement_base + (ptr - default_base.get()); 414 | WriteMemory(addr + i, result.get()); 415 | return result; 416 | } 417 | } 418 | return nullptr; 419 | } 420 | 421 | 422 | 423 | 424 | 425 | 426 | /* 427 | * GetAbsoluteOffset 428 | * Gets absolute address based on relative offset @rel_value from instruction that ends at @end_of_instruction 429 | */ 430 | inline memory_pointer_raw GetAbsoluteOffset(int rel_value, memory_pointer_tr end_of_instruction) 431 | { 432 | return end_of_instruction.get() + rel_value; 433 | } 434 | 435 | /* 436 | * GetRelativeOffset 437 | * Gets relative offset based on absolute address @abs_value for instruction that ends at @end_of_instruction 438 | */ 439 | inline int GetRelativeOffset(memory_pointer_tr abs_value, memory_pointer_tr end_of_instruction) 440 | { 441 | return uintptr_t(abs_value.get() - end_of_instruction.get()); 442 | } 443 | 444 | /* 445 | * ReadRelativeOffset 446 | * Reads relative offset from address @at 447 | */ 448 | inline memory_pointer_raw ReadRelativeOffset(memory_pointer_tr at, size_t sizeof_addr = 4, bool vp = true) 449 | { 450 | switch(sizeof_addr) 451 | { 452 | case 1: return (GetAbsoluteOffset(ReadMemory (at, vp), at+sizeof_addr)); 453 | case 2: return (GetAbsoluteOffset(ReadMemory(at, vp), at+sizeof_addr)); 454 | case 4: return (GetAbsoluteOffset(ReadMemory(at, vp), at+sizeof_addr)); 455 | } 456 | return nullptr; 457 | } 458 | 459 | /* 460 | * MakeRelativeOffset 461 | * Writes relative offset into @at based on absolute destination @dest 462 | */ 463 | inline void MakeRelativeOffset(memory_pointer_tr at, memory_pointer_tr dest, size_t sizeof_addr = 4, bool vp = true) 464 | { 465 | switch(sizeof_addr) 466 | { 467 | case 1: WriteMemory (at, static_cast (GetRelativeOffset(dest, at+sizeof_addr)), vp); 468 | case 2: WriteMemory(at, static_cast(GetRelativeOffset(dest, at+sizeof_addr)), vp); 469 | case 4: WriteMemory(at, static_cast(GetRelativeOffset(dest, at+sizeof_addr)), vp); 470 | } 471 | } 472 | 473 | /* 474 | * GetBranchDestination 475 | * Gets the destination of a branch instruction at address @at 476 | * *** Works only with JMP and CALL for now *** 477 | */ 478 | inline memory_pointer_raw GetBranchDestination(memory_pointer_tr at, bool vp = true) 479 | { 480 | switch(ReadMemory(at, vp)) 481 | { 482 | // We need to handle other instructions (and prefixes) later... 483 | case 0xE8: // call rel 484 | case 0xE9: // jmp rel 485 | return ReadRelativeOffset(at + 1, 4, vp); 486 | 487 | case 0xFF: 488 | switch(ReadMemory(at + 1, vp)) 489 | { 490 | case 0x15: // call dword ptr [addr] 491 | case 0x25: // jmp dword ptr [addr] 492 | return *(ReadMemory(at + 2, vp)); 493 | } 494 | break; 495 | } 496 | return nullptr; 497 | } 498 | 499 | /* 500 | * MakeJMP 501 | * Creates a JMP instruction at address @at that jumps into address @dest 502 | * If there was already a branch instruction there, returns the previosly destination of the branch 503 | */ 504 | inline memory_pointer_raw MakeJMP(memory_pointer_tr at, memory_pointer_raw dest, bool vp = true) 505 | { 506 | auto p = GetBranchDestination(at, vp); 507 | WriteMemory(at, 0xE9, vp); 508 | MakeRelativeOffset(at+1, dest, 4, vp); 509 | return p; 510 | } 511 | 512 | /* 513 | * MakeCALL 514 | * Creates a CALL instruction at address @at that jumps into address @dest 515 | * If there was already a branch instruction there, returns the previosly destination of the branch 516 | */ 517 | inline memory_pointer_raw MakeCALL(memory_pointer_tr at, memory_pointer_raw dest, bool vp = true) 518 | { 519 | auto p = GetBranchDestination(at, vp); 520 | WriteMemory(at, 0xE8, vp); 521 | MakeRelativeOffset(at+1, dest, 4, vp); 522 | return p; 523 | } 524 | 525 | /* 526 | * MakeJA 527 | * Creates a JA instruction at address @at that jumps if above into address @dest 528 | * If there was already a branch instruction there, returns the previosly destination of the branch 529 | */ 530 | inline void MakeJA(memory_pointer_tr at, memory_pointer_raw dest, bool vp = true) 531 | { 532 | WriteMemory(at, 0x87F0, vp); 533 | MakeRelativeOffset(at+2, dest, 4, vp); 534 | } 535 | 536 | /* 537 | * MakeNOP 538 | * Creates a bunch of NOP instructions at address @at 539 | */ 540 | inline void MakeNOP(memory_pointer_tr at, size_t count = 1, bool vp = true) 541 | { 542 | MemoryFill(at, 0x90, count, vp); 543 | } 544 | 545 | /* 546 | * MakeRangedNOP 547 | * Creates a bunch of NOP instructions at address @at until address @until 548 | */ 549 | inline void MakeRangedNOP(memory_pointer_tr at, memory_pointer_tr until, bool vp = true) 550 | { 551 | return MakeNOP(at, size_t(until.get_raw() - at.get_raw()), vp); 552 | } 553 | 554 | 555 | /* 556 | * MakeRET 557 | * Creates a RET instruction at address @at popping @pop values from the stack 558 | * If @pop is equal to 0 it will use the 1 byte form of the instruction 559 | */ 560 | inline void MakeRET(memory_pointer_tr at, uint16_t pop = 0, bool vp = true) 561 | { 562 | WriteMemory(at, pop? 0xC2 : 0xC3, vp); 563 | if(pop) WriteMemory(at+1, pop, vp); 564 | } 565 | 566 | 567 | 568 | 569 | 570 | /* 571 | * lazy_pointer 572 | * Lazy pointer, where it's final value will get evaluated only once when finally needed. 573 | */ 574 | template 575 | struct lazy_pointer 576 | { 577 | public: 578 | // Returns the final raw pointer 579 | static auto_pointer get() 580 | { 581 | return xget().get(); 582 | } 583 | 584 | template 585 | static T* get() 586 | { 587 | return get().get(); 588 | } 589 | 590 | private: 591 | // Returns the final pointer 592 | static memory_pointer_raw xget() 593 | { 594 | static void* ptr = nullptr; 595 | if(!ptr) ptr = memory_pointer(addr).get(); 596 | return memory_pointer_raw(ptr); 597 | } 598 | }; 599 | 600 | /* 601 | * lazy_object 602 | * Lazy object, where it's final object will get evaluated only once when finally needed. 603 | */ 604 | template 605 | struct lazy_object 606 | { 607 | static T& get() 608 | { 609 | static T data; 610 | static bool has_data = false; 611 | if(!has_data) 612 | { 613 | ReadObject(addr, data, true); 614 | has_data = true; 615 | } 616 | return data; 617 | } 618 | }; 619 | 620 | 621 | /* 622 | Helpers 623 | */ 624 | 625 | template 626 | inline memory_pointer mem_ptr(T p) 627 | { 628 | return memory_pointer(p); 629 | } 630 | 631 | template 632 | inline memory_pointer_raw raw_ptr(T p) 633 | { 634 | return memory_pointer_raw(p); 635 | } 636 | 637 | template 638 | inline memory_pointer_raw raw_ptr(basic_memory_pointer p) 639 | { 640 | return raw_ptr(p.get()); 641 | } 642 | 643 | template 644 | inline memory_pointer_raw lazy_ptr() 645 | { 646 | return lazy_pointer::get(); 647 | } 648 | 649 | template 650 | inline memory_pointer_aslr aslr_ptr(T p) 651 | { 652 | return memory_pointer_aslr(p); 653 | } 654 | 655 | 656 | 657 | 658 | 659 | 660 | #ifndef INJECTOR_GVM_OWN_DETECT // Should we implement our detection method? 661 | 662 | // Detects game, region and version; returns false if could not detect it 663 | inline bool game_version_manager::Detect() 664 | { 665 | // Cleanup data 666 | this->Clear(); 667 | 668 | // Find NT header 669 | uintptr_t base = (uintptr_t) GetModuleHandleA(NULL); 670 | IMAGE_DOS_HEADER* dos = (IMAGE_DOS_HEADER*)(base); 671 | IMAGE_NT_HEADERS* nt = (IMAGE_NT_HEADERS*)(base + dos->e_lfanew); 672 | 673 | // Look for game and version thought the entry-point 674 | // Thanks to Silent for many of the entry point offsets 675 | switch (base + nt->OptionalHeader.AddressOfEntryPoint + (0x400000 - base)) 676 | { 677 | case 0x5C1E70: // GTA III 1.0 678 | game = '3', major = 1, minor = 0, region = 0, steam = false; 679 | return true; 680 | 681 | case 0x5C2130: // GTA III 1.1 682 | game = '3', major = 1, minor = 1, region = 0, steam = false; 683 | return true; 684 | 685 | case 0x5C6FD0: // GTA III 1.1 (Cracked Steam Version) 686 | case 0x9912ED: // GTA III 1.1 (Encrypted Steam Version) 687 | game = '3', major = 1, minor = 1, region = 0, steam = true; 688 | return true; 689 | 690 | case 0x667BF0: // GTA VC 1.0 691 | game = 'V', major = 1, minor = 0, region = 0, steam = false; 692 | return true; 693 | 694 | case 0x667C40: // GTA VC 1.1 695 | game = 'V', major = 1, minor = 1, region = 0, steam = false; 696 | return true; 697 | 698 | case 0x666BA0: // GTA VC 1.1 (Cracked Steam Version) 699 | case 0xA402ED: // GTA VC 1.1 (Encrypted Steam Version) 700 | game = 'V', major = 1, minor = 1, region = 0, steam = true; 701 | return true; 702 | 703 | case 0x82457C: // GTA SA 1.0 US Cracked 704 | case 0x824570: // GTA SA 1.0 US Compact 705 | game = 'S', major = 1, minor = 0, region = 'U', steam = false; 706 | cracker = injector::ReadMemory(raw_ptr(0x406A20), true) == 0xE9? 'H' : 0; 707 | return true; 708 | 709 | case 0x8245BC: // GTA SA 1.0 EU Cracked (??????) 710 | case 0x8245B0: // GTA SA 1.0 EU Cracked 711 | game = 'S', major = 1, minor = 0, region = 'E', steam = false; 712 | cracker = injector::ReadMemory(raw_ptr(0x406A20), true) == 0xE9? 'H' : 0; // just to say 'securom' 713 | return true; 714 | 715 | case 0x8252FC: // GTA SA 1.1 US Cracked 716 | game = 'S', major = 1, minor = 1, region = 'U', steam = false; 717 | return true; 718 | 719 | case 0x82533C: // GTA SA 1.1 EU Cracked 720 | game = 'S', major = 1, minor = 1, region = 'E', steam = false; 721 | return true; 722 | 723 | case 0x85EC4A: // GTA SA 3.0 (Cracked Steam Version) 724 | case 0xD3C3DB: // GTA SA 3.0 (Encrypted Steam Version) 725 | game = 'S', major = 3, minor = 0, region = 0, steam = true; 726 | return true; 727 | 728 | case 0xC965AD: // GTA IV 1.0.0.4 US 729 | game = 'I', major = 1, minor = 0, majorRevision = 0, minorRevision = 4, region = 'U', steam = false; 730 | return true; 731 | 732 | case 0xD0D011: // GTA IV 1.0.0.7 US 733 | game = 'I', major = 1, minor = 0, majorRevision = 0, minorRevision = 7, region = 'U', steam = false; 734 | return true; 735 | 736 | case 0xD0AF06: // GTA EFLC 1.1.2.0 US 737 | game = 'E', major = 1, minor = 1, majorRevision = 2, minorRevision = 0, region = 'U', steam = false; 738 | return true; 739 | 740 | default: 741 | return false; 742 | } 743 | } 744 | 745 | #endif 746 | 747 | 748 | } // namespace 749 | 750 | -------------------------------------------------------------------------------- /includes/injector/utility.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Injectors - Utility / Helpers 3 | * 4 | * Copyright (C) 2014 LINK/2012 5 | * 6 | * This software is provided 'as-is', without any express or implied 7 | * warranty. In no event will the authors be held liable for any damages 8 | * arising from the use of this software. 9 | * 10 | * Permission is granted to anyone to use this software for any purpose, 11 | * including commercial applications, and to alter it and redistribute it 12 | * freely, subject to the following restrictions: 13 | * 14 | * 1. The origin of this software must not be misrepresented; you must not 15 | * claim that you wrote the original software. If you use this software 16 | * in a product, an acknowledgment in the product documentation would be 17 | * appreciated but is not required. 18 | * 19 | * 2. Altered source versions must be plainly marked as such, and must not be 20 | * misrepresented as being the original software. 21 | * 22 | * 3. This notice may not be removed or altered from any source 23 | * distribution. 24 | * 25 | */ 26 | #pragma once 27 | 28 | namespace injector 29 | { 30 | template 31 | T return_value() 32 | { 33 | return value; 34 | } 35 | 36 | template 37 | void* force_ptr(const T& fun) 38 | { 39 | auto ptr = fun; 40 | return *(void**)&ptr; 41 | } 42 | 43 | 44 | // Helper structure to help calling back what was there before a hook 45 | // e.g. hb.fun = MakeCALL(0x0, raw_ptr(my_hook)); 46 | template 47 | struct hook_back 48 | { 49 | typedef FuncType func_type; 50 | 51 | func_type fun; 52 | 53 | hook_back() : fun(nullptr) 54 | {} 55 | }; 56 | }; 57 | -------------------------------------------------------------------------------- /includes/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers 11 | // Windows Header Files: 12 | #include 13 | 14 | 15 | 16 | // TODO: reference additional headers your program requires here 17 | -------------------------------------------------------------------------------- /json/json-forwards.h: -------------------------------------------------------------------------------- 1 | /// Json-cpp amalgamated forward header (http://jsoncpp.sourceforge.net/). 2 | /// It is intended to be used with #include "json/json-forwards.h" 3 | /// This header provides forward declaration for all JsonCpp types. 4 | 5 | // ////////////////////////////////////////////////////////////////////// 6 | // Beginning of content of file: LICENSE 7 | // ////////////////////////////////////////////////////////////////////// 8 | 9 | /* 10 | The JsonCpp library's source code, including accompanying documentation, 11 | tests and demonstration applications, are licensed under the following 12 | conditions... 13 | 14 | Baptiste Lepilleur and The JsonCpp Authors explicitly disclaim copyright in all 15 | jurisdictions which recognize such a disclaimer. In such jurisdictions, 16 | this software is released into the Public Domain. 17 | 18 | In jurisdictions which do not recognize Public Domain property (e.g. Germany as of 19 | 2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur and 20 | The JsonCpp Authors, and is released under the terms of the MIT License (see below). 21 | 22 | In jurisdictions which recognize Public Domain property, the user of this 23 | software may choose to accept it either as 1) Public Domain, 2) under the 24 | conditions of the MIT License (see below), or 3) under the terms of dual 25 | Public Domain/MIT License conditions described here, as they choose. 26 | 27 | The MIT License is about as close to Public Domain as a license can get, and is 28 | described in clear, concise terms at: 29 | 30 | http://en.wikipedia.org/wiki/MIT_License 31 | 32 | The full text of the MIT License follows: 33 | 34 | ======================================================================== 35 | Copyright (c) 2007-2010 Baptiste Lepilleur and The JsonCpp Authors 36 | 37 | Permission is hereby granted, free of charge, to any person 38 | obtaining a copy of this software and associated documentation 39 | files (the "Software"), to deal in the Software without 40 | restriction, including without limitation the rights to use, copy, 41 | modify, merge, publish, distribute, sublicense, and/or sell copies 42 | of the Software, and to permit persons to whom the Software is 43 | furnished to do so, subject to the following conditions: 44 | 45 | The above copyright notice and this permission notice shall be 46 | included in all copies or substantial portions of the Software. 47 | 48 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 49 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 50 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 51 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 52 | BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 53 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 54 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 55 | SOFTWARE. 56 | ======================================================================== 57 | (END LICENSE TEXT) 58 | 59 | The MIT license is compatible with both the GPL and commercial 60 | software, affording one all of the rights of Public Domain with the 61 | minor nuisance of being required to keep the above copyright notice 62 | and license text in the source code. Note also that by accepting the 63 | Public Domain "license" you can re-license your copy using whatever 64 | license you like. 65 | 66 | */ 67 | 68 | // ////////////////////////////////////////////////////////////////////// 69 | // End of content of file: LICENSE 70 | // ////////////////////////////////////////////////////////////////////// 71 | 72 | 73 | 74 | 75 | 76 | #ifndef JSON_FORWARD_AMALGAMATED_H_INCLUDED 77 | # define JSON_FORWARD_AMALGAMATED_H_INCLUDED 78 | /// If defined, indicates that the source file is amalgamated 79 | /// to prevent private header inclusion. 80 | #define JSON_IS_AMALGAMATION 81 | 82 | // ////////////////////////////////////////////////////////////////////// 83 | // Beginning of content of file: include/json/version.h 84 | // ////////////////////////////////////////////////////////////////////// 85 | 86 | #ifndef JSON_VERSION_H_INCLUDED 87 | #define JSON_VERSION_H_INCLUDED 88 | 89 | // Note: version must be updated in three places when doing a release. This 90 | // annoying process ensures that amalgamate, CMake, and meson all report the 91 | // correct version. 92 | // 1. /meson.build 93 | // 2. /include/json/version.h 94 | // 3. /CMakeLists.txt 95 | // IMPORTANT: also update the SOVERSION!! 96 | 97 | #define JSONCPP_VERSION_STRING "1.9.5" 98 | #define JSONCPP_VERSION_MAJOR 1 99 | #define JSONCPP_VERSION_MINOR 9 100 | #define JSONCPP_VERSION_PATCH 5 101 | #define JSONCPP_VERSION_QUALIFIER 102 | #define JSONCPP_VERSION_HEXA \ 103 | ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | \ 104 | (JSONCPP_VERSION_PATCH << 8)) 105 | 106 | #ifdef JSONCPP_USING_SECURE_MEMORY 107 | #undef JSONCPP_USING_SECURE_MEMORY 108 | #endif 109 | #define JSONCPP_USING_SECURE_MEMORY 0 110 | // If non-zero, the library zeroes any memory that it has allocated before 111 | // it frees its memory. 112 | 113 | #endif // JSON_VERSION_H_INCLUDED 114 | 115 | // ////////////////////////////////////////////////////////////////////// 116 | // End of content of file: include/json/version.h 117 | // ////////////////////////////////////////////////////////////////////// 118 | 119 | 120 | 121 | 122 | 123 | 124 | // ////////////////////////////////////////////////////////////////////// 125 | // Beginning of content of file: include/json/allocator.h 126 | // ////////////////////////////////////////////////////////////////////// 127 | 128 | // Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors 129 | // Distributed under MIT license, or public domain if desired and 130 | // recognized in your jurisdiction. 131 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 132 | 133 | #ifndef JSON_ALLOCATOR_H_INCLUDED 134 | #define JSON_ALLOCATOR_H_INCLUDED 135 | 136 | #include 137 | #include 138 | 139 | #pragma pack(push, 8) 140 | 141 | namespace Json { 142 | template class SecureAllocator { 143 | public: 144 | // Type definitions 145 | using value_type = T; 146 | using pointer = T*; 147 | using const_pointer = const T*; 148 | using reference = T&; 149 | using const_reference = const T&; 150 | using size_type = std::size_t; 151 | using difference_type = std::ptrdiff_t; 152 | 153 | /** 154 | * Allocate memory for N items using the standard allocator. 155 | */ 156 | pointer allocate(size_type n) { 157 | // allocate using "global operator new" 158 | return static_cast(::operator new(n * sizeof(T))); 159 | } 160 | 161 | /** 162 | * Release memory which was allocated for N items at pointer P. 163 | * 164 | * The memory block is filled with zeroes before being released. 165 | */ 166 | void deallocate(pointer p, size_type n) { 167 | // memset_s is used because memset may be optimized away by the compiler 168 | memset_s(p, n * sizeof(T), 0, n * sizeof(T)); 169 | // free using "global operator delete" 170 | ::operator delete(p); 171 | } 172 | 173 | /** 174 | * Construct an item in-place at pointer P. 175 | */ 176 | template void construct(pointer p, Args&&... args) { 177 | // construct using "placement new" and "perfect forwarding" 178 | ::new (static_cast(p)) T(std::forward(args)...); 179 | } 180 | 181 | size_type max_size() const { return size_t(-1) / sizeof(T); } 182 | 183 | pointer address(reference x) const { return std::addressof(x); } 184 | 185 | const_pointer address(const_reference x) const { return std::addressof(x); } 186 | 187 | /** 188 | * Destroy an item in-place at pointer P. 189 | */ 190 | void destroy(pointer p) { 191 | // destroy using "explicit destructor" 192 | p->~T(); 193 | } 194 | 195 | // Boilerplate 196 | SecureAllocator() {} 197 | template SecureAllocator(const SecureAllocator&) {} 198 | template struct rebind { using other = SecureAllocator; }; 199 | }; 200 | 201 | template 202 | bool operator==(const SecureAllocator&, const SecureAllocator&) { 203 | return true; 204 | } 205 | 206 | template 207 | bool operator!=(const SecureAllocator&, const SecureAllocator&) { 208 | return false; 209 | } 210 | 211 | } // namespace Json 212 | 213 | #pragma pack(pop) 214 | 215 | #endif // JSON_ALLOCATOR_H_INCLUDED 216 | 217 | // ////////////////////////////////////////////////////////////////////// 218 | // End of content of file: include/json/allocator.h 219 | // ////////////////////////////////////////////////////////////////////// 220 | 221 | 222 | 223 | 224 | 225 | 226 | // ////////////////////////////////////////////////////////////////////// 227 | // Beginning of content of file: include/json/config.h 228 | // ////////////////////////////////////////////////////////////////////// 229 | 230 | // Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors 231 | // Distributed under MIT license, or public domain if desired and 232 | // recognized in your jurisdiction. 233 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 234 | 235 | #ifndef JSON_CONFIG_H_INCLUDED 236 | #define JSON_CONFIG_H_INCLUDED 237 | #include 238 | #include 239 | #include 240 | #include 241 | #include 242 | #include 243 | #include 244 | #include 245 | 246 | // If non-zero, the library uses exceptions to report bad input instead of C 247 | // assertion macros. The default is to use exceptions. 248 | #ifndef JSON_USE_EXCEPTION 249 | #define JSON_USE_EXCEPTION 1 250 | #endif 251 | 252 | // Temporary, tracked for removal with issue #982. 253 | #ifndef JSON_USE_NULLREF 254 | #define JSON_USE_NULLREF 1 255 | #endif 256 | 257 | /// If defined, indicates that the source file is amalgamated 258 | /// to prevent private header inclusion. 259 | /// Remarks: it is automatically defined in the generated amalgamated header. 260 | // #define JSON_IS_AMALGAMATION 261 | 262 | // Export macros for DLL visibility 263 | #if defined(JSON_DLL_BUILD) 264 | #if defined(_MSC_VER) || defined(__MINGW32__) 265 | #define JSON_API __declspec(dllexport) 266 | #define JSONCPP_DISABLE_DLL_INTERFACE_WARNING 267 | #elif defined(__GNUC__) || defined(__clang__) 268 | #define JSON_API __attribute__((visibility("default"))) 269 | #endif // if defined(_MSC_VER) 270 | 271 | #elif defined(JSON_DLL) 272 | #if defined(_MSC_VER) || defined(__MINGW32__) 273 | #define JSON_API __declspec(dllimport) 274 | #define JSONCPP_DISABLE_DLL_INTERFACE_WARNING 275 | #endif // if defined(_MSC_VER) 276 | #endif // ifdef JSON_DLL_BUILD 277 | 278 | #if !defined(JSON_API) 279 | #define JSON_API 280 | #endif 281 | 282 | #if defined(_MSC_VER) && _MSC_VER < 1800 283 | #error \ 284 | "ERROR: Visual Studio 12 (2013) with _MSC_VER=1800 is the oldest supported compiler with sufficient C++11 capabilities" 285 | #endif 286 | 287 | #if defined(_MSC_VER) && _MSC_VER < 1900 288 | // As recommended at 289 | // https://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010 290 | extern JSON_API int msvc_pre1900_c99_snprintf(char* outBuf, size_t size, 291 | const char* format, ...); 292 | #define jsoncpp_snprintf msvc_pre1900_c99_snprintf 293 | #else 294 | #define jsoncpp_snprintf std::snprintf 295 | #endif 296 | 297 | // If JSON_NO_INT64 is defined, then Json only support C++ "int" type for 298 | // integer 299 | // Storages, and 64 bits integer support is disabled. 300 | // #define JSON_NO_INT64 1 301 | 302 | // JSONCPP_OVERRIDE is maintained for backwards compatibility of external tools. 303 | // C++11 should be used directly in JSONCPP. 304 | #define JSONCPP_OVERRIDE override 305 | 306 | #ifdef __clang__ 307 | #if __has_extension(attribute_deprecated_with_message) 308 | #define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message))) 309 | #endif 310 | #elif defined(__GNUC__) // not clang (gcc comes later since clang emulates gcc) 311 | #if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)) 312 | #define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message))) 313 | #elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) 314 | #define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__)) 315 | #endif // GNUC version 316 | #elif defined(_MSC_VER) // MSVC (after clang because clang on Windows emulates 317 | // MSVC) 318 | #define JSONCPP_DEPRECATED(message) __declspec(deprecated(message)) 319 | #endif // __clang__ || __GNUC__ || _MSC_VER 320 | 321 | #if !defined(JSONCPP_DEPRECATED) 322 | #define JSONCPP_DEPRECATED(message) 323 | #endif // if !defined(JSONCPP_DEPRECATED) 324 | 325 | #if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 6)) 326 | #define JSON_USE_INT64_DOUBLE_CONVERSION 1 327 | #endif 328 | 329 | #if !defined(JSON_IS_AMALGAMATION) 330 | 331 | #include "allocator.h" 332 | #include "version.h" 333 | 334 | #endif // if !defined(JSON_IS_AMALGAMATION) 335 | 336 | namespace Json { 337 | using Int = int; 338 | using UInt = unsigned int; 339 | #if defined(JSON_NO_INT64) 340 | using LargestInt = int; 341 | using LargestUInt = unsigned int; 342 | #undef JSON_HAS_INT64 343 | #else // if defined(JSON_NO_INT64) 344 | // For Microsoft Visual use specific types as long long is not supported 345 | #if defined(_MSC_VER) // Microsoft Visual Studio 346 | using Int64 = __int64; 347 | using UInt64 = unsigned __int64; 348 | #else // if defined(_MSC_VER) // Other platforms, use long long 349 | using Int64 = int64_t; 350 | using UInt64 = uint64_t; 351 | #endif // if defined(_MSC_VER) 352 | using LargestInt = Int64; 353 | using LargestUInt = UInt64; 354 | #define JSON_HAS_INT64 355 | #endif // if defined(JSON_NO_INT64) 356 | 357 | template 358 | using Allocator = 359 | typename std::conditional, 360 | std::allocator>::type; 361 | using String = std::basic_string, Allocator>; 362 | using IStringStream = 363 | std::basic_istringstream; 365 | using OStringStream = 366 | std::basic_ostringstream; 368 | using IStream = std::istream; 369 | using OStream = std::ostream; 370 | } // namespace Json 371 | 372 | // Legacy names (formerly macros). 373 | using JSONCPP_STRING = Json::String; 374 | using JSONCPP_ISTRINGSTREAM = Json::IStringStream; 375 | using JSONCPP_OSTRINGSTREAM = Json::OStringStream; 376 | using JSONCPP_ISTREAM = Json::IStream; 377 | using JSONCPP_OSTREAM = Json::OStream; 378 | 379 | #endif // JSON_CONFIG_H_INCLUDED 380 | 381 | // ////////////////////////////////////////////////////////////////////// 382 | // End of content of file: include/json/config.h 383 | // ////////////////////////////////////////////////////////////////////// 384 | 385 | 386 | 387 | 388 | 389 | 390 | // ////////////////////////////////////////////////////////////////////// 391 | // Beginning of content of file: include/json/forwards.h 392 | // ////////////////////////////////////////////////////////////////////// 393 | 394 | // Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors 395 | // Distributed under MIT license, or public domain if desired and 396 | // recognized in your jurisdiction. 397 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 398 | 399 | #ifndef JSON_FORWARDS_H_INCLUDED 400 | #define JSON_FORWARDS_H_INCLUDED 401 | 402 | #if !defined(JSON_IS_AMALGAMATION) 403 | #include "config.h" 404 | #endif // if !defined(JSON_IS_AMALGAMATION) 405 | 406 | namespace Json { 407 | 408 | // writer.h 409 | class StreamWriter; 410 | class StreamWriterBuilder; 411 | class Writer; 412 | class FastWriter; 413 | class StyledWriter; 414 | class StyledStreamWriter; 415 | 416 | // reader.h 417 | class Reader; 418 | class CharReader; 419 | class CharReaderBuilder; 420 | 421 | // json_features.h 422 | class Features; 423 | 424 | // value.h 425 | using ArrayIndex = unsigned int; 426 | class StaticString; 427 | class Path; 428 | class PathArgument; 429 | class Value; 430 | class ValueIteratorBase; 431 | class ValueIterator; 432 | class ValueConstIterator; 433 | 434 | } // namespace Json 435 | 436 | #endif // JSON_FORWARDS_H_INCLUDED 437 | 438 | // ////////////////////////////////////////////////////////////////////// 439 | // End of content of file: include/json/forwards.h 440 | // ////////////////////////////////////////////////////////////////////// 441 | 442 | 443 | 444 | 445 | 446 | #endif //ifndef JSON_FORWARD_AMALGAMATED_H_INCLUDED 447 | -------------------------------------------------------------------------------- /stdafx.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | -------------------------------------------------------------------------------- /stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers 11 | // Windows Header Files: 12 | #include 13 | 14 | 15 | 16 | // TODO: reference additional headers your program requires here 17 | -------------------------------------------------------------------------------- /targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | --------------------------------------------------------------------------------