├── .gitignore ├── demo ├── show.gif └── ObfsDemo │ ├── Release │ └── ObfsDemo.exe │ ├── ObfsDemo │ ├── ObfsDemo.cpp │ ├── ObfsDemo.vcxproj.filters │ └── ObfsDemo.vcxproj │ ├── ObfsDemo.sln │ └── .gitignore ├── vs_config ├── vs_config.jpg ├── vs_config2.jpg ├── vs_config3.jpg └── Platforms │ ├── Win32 │ └── PlatformToolsets │ │ └── LLVM-vs2017 │ │ ├── toolset.targets │ │ └── toolset.props │ └── x64 │ └── PlatformToolsets │ └── LLVM-vs2017 │ ├── toolset.targets │ └── toolset.props ├── README.md └── obfuscation.h /.gitignore: -------------------------------------------------------------------------------- 1 | .vs/ -------------------------------------------------------------------------------- /demo/show.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tai7sy/vs-obfuscation/HEAD/demo/show.gif -------------------------------------------------------------------------------- /vs_config/vs_config.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tai7sy/vs-obfuscation/HEAD/vs_config/vs_config.jpg -------------------------------------------------------------------------------- /vs_config/vs_config2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tai7sy/vs-obfuscation/HEAD/vs_config/vs_config2.jpg -------------------------------------------------------------------------------- /vs_config/vs_config3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tai7sy/vs-obfuscation/HEAD/vs_config/vs_config3.jpg -------------------------------------------------------------------------------- /demo/ObfsDemo/Release/ObfsDemo.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tai7sy/vs-obfuscation/HEAD/demo/ObfsDemo/Release/ObfsDemo.exe -------------------------------------------------------------------------------- /vs_config/Platforms/Win32/PlatformToolsets/LLVM-vs2017/toolset.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /vs_config/Platforms/x64/PlatformToolsets/LLVM-vs2017/toolset.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## About 2 | Help you hide ALL the string in your program and ALL the api in your program 3 | 4 | ## Usage 5 | 6 | 使用LLVM Obfuscator / constexpr / PEB调用API 进行程序混淆 7 | 8 | ## Demo 9 | ![show.gif](demo/show.gif) 10 | -------------------------------------------------------------------------------- /demo/ObfsDemo/ObfsDemo/ObfsDemo.cpp: -------------------------------------------------------------------------------- 1 | // ObfsDemo.cpp: 定义控制台应用程序的入口点。 2 | // 3 | 4 | 5 | #include 6 | #include 7 | #include "../../../obfuscation.h" 8 | 9 | int main() { 10 | printf("I'am the main"); 11 | IFN(LoadLibraryA)(XorString("user32.dll")); 12 | // 方式1 13 | IFN(MessageBoxA)(0, XorString("World!"), XorString("Hello"), MB_OK); 14 | // 方式2 15 | IFN_DLL(XorStringW(L"user32.dll"), MessageBoxA)(0, XorString("World!"), XorString("Hello"), MB_OK); 16 | // IFN(MessageBoxW)(0, XorStringW(L"World!"), XorStringW(L"Hello"), MB_OK); 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /demo/ObfsDemo/ObfsDemo/ObfsDemo.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 源文件 20 | 21 | 22 | -------------------------------------------------------------------------------- /demo/ObfsDemo/ObfsDemo.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.27428.2037 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ObfsDemo", "ObfsDemo\ObfsDemo.vcxproj", "{8772866D-33B7-4D0D-BE55-9351A50B30B6}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {8772866D-33B7-4D0D-BE55-9351A50B30B6}.Debug|x64.ActiveCfg = Debug|x64 17 | {8772866D-33B7-4D0D-BE55-9351A50B30B6}.Debug|x64.Build.0 = Debug|x64 18 | {8772866D-33B7-4D0D-BE55-9351A50B30B6}.Debug|x86.ActiveCfg = Debug|Win32 19 | {8772866D-33B7-4D0D-BE55-9351A50B30B6}.Debug|x86.Build.0 = Debug|Win32 20 | {8772866D-33B7-4D0D-BE55-9351A50B30B6}.Release|x64.ActiveCfg = Release|x64 21 | {8772866D-33B7-4D0D-BE55-9351A50B30B6}.Release|x64.Build.0 = Release|x64 22 | {8772866D-33B7-4D0D-BE55-9351A50B30B6}.Release|x86.ActiveCfg = Release|Win32 23 | {8772866D-33B7-4D0D-BE55-9351A50B30B6}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {9DD0B23E-2720-4AFF-A3FC-8BFDC69DE67C} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /vs_config/Platforms/Win32/PlatformToolsets/LLVM-vs2017/toolset.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\LLVM\LLVM) 7 | $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\LLVM\LLVM) 8 | C:\Program Files\LLVM 9 | $(LLVMInstallDir)\msbuild-bin;$(ExecutablePath) 10 | $(LLVMInstallDir)\lib;$(LibraryPath) 11 | $(LLVMInstallDir)\include;$(IncludePath) 12 | 13 | 14 | 15 | 16 | 17 | -mllvm -bcf -mllvm -bcf_loop=4 -mllvm -bcf_prob=100 -mllvm -sub -mllvm -sub_loop=2 18 | -m32 -fmsc-version=1910 %(ObfsOptions) 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /vs_config/Platforms/x64/PlatformToolsets/LLVM-vs2017/toolset.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\LLVM\LLVM) 7 | $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\LLVM\LLVM) 8 | C:\Program Files\LLVM 9 | $(LLVMInstallDir)\msbuild-bin;$(ExecutablePath) 10 | $(LLVMInstallDir)\lib;$(LibraryPath) 11 | $(LLVMInstallDir)\include;$(IncludePath) 12 | 13 | 14 | 15 | 16 | 17 | -mllvm -bcf -mllvm -bcf_loop=4 -mllvm -bcf_prob=100 -mllvm -sub -mllvm -sub_loop=2 18 | -m64 -fmsc-version=1910 %(ObfsOptions) 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /demo/ObfsDemo/.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | # [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # MSTest test Results 33 | [Tt]est[Rr]esult*/ 34 | [Bb]uild[Ll]og.* 35 | 36 | # NUNIT 37 | *.VisualState.xml 38 | TestResult.xml 39 | 40 | # Build Results of an ATL Project 41 | [Dd]ebugPS/ 42 | [Rr]eleasePS/ 43 | dlldata.c 44 | 45 | # .NET Core 46 | project.lock.json 47 | project.fragment.lock.json 48 | artifacts/ 49 | **/Properties/launchSettings.json 50 | 51 | *_i.c 52 | *_p.c 53 | *_i.h 54 | *.ilk 55 | *.meta 56 | *.obj 57 | *.pch 58 | *.pdb 59 | *.pgc 60 | *.pgd 61 | *.rsp 62 | *.sbr 63 | *.tlb 64 | *.tli 65 | *.tlh 66 | *.tmp 67 | *.tmp_proj 68 | *.log 69 | *.vspscc 70 | *.vssscc 71 | .builds 72 | *.pidb 73 | *.svclog 74 | *.scc 75 | 76 | # Chutzpah Test files 77 | _Chutzpah* 78 | 79 | # Visual C++ cache files 80 | ipch/ 81 | *.aps 82 | *.ncb 83 | *.opendb 84 | *.opensdf 85 | *.sdf 86 | *.cachefile 87 | *.VC.db 88 | *.VC.VC.opendb 89 | 90 | # Visual Studio profiler 91 | *.psess 92 | *.vsp 93 | *.vspx 94 | *.sap 95 | 96 | # TFS 2012 Local Workspace 97 | $tf/ 98 | 99 | # Guidance Automation Toolkit 100 | *.gpState 101 | 102 | # ReSharper is a .NET coding add-in 103 | _ReSharper*/ 104 | *.[Rr]e[Ss]harper 105 | *.DotSettings.user 106 | 107 | # JustCode is a .NET coding add-in 108 | .JustCode 109 | 110 | # TeamCity is a build add-in 111 | _TeamCity* 112 | 113 | # DotCover is a Code Coverage Tool 114 | *.dotCover 115 | 116 | # Visual Studio code coverage results 117 | *.coverage 118 | *.coveragexml 119 | 120 | # NCrunch 121 | _NCrunch_* 122 | .*crunch*.local.xml 123 | nCrunchTemp_* 124 | 125 | # MightyMoose 126 | *.mm.* 127 | AutoTest.Net/ 128 | 129 | # Web workbench (sass) 130 | .sass-cache/ 131 | 132 | # Installshield output folder 133 | [Ee]xpress/ 134 | 135 | # DocProject is a documentation generator add-in 136 | DocProject/buildhelp/ 137 | DocProject/Help/*.HxT 138 | DocProject/Help/*.HxC 139 | DocProject/Help/*.hhc 140 | DocProject/Help/*.hhk 141 | DocProject/Help/*.hhp 142 | DocProject/Help/Html2 143 | DocProject/Help/html 144 | 145 | # Click-Once directory 146 | publish/ 147 | 148 | # Publish Web Output 149 | *.[Pp]ublish.xml 150 | *.azurePubxml 151 | # TODO: Comment the next line if you want to checkin your web deploy settings 152 | # but database connection strings (with potential passwords) will be unencrypted 153 | *.pubxml 154 | *.publishproj 155 | 156 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 157 | # checkin your Azure Web App publish settings, but sensitive information contained 158 | # in these scripts will be unencrypted 159 | PublishScripts/ 160 | 161 | # NuGet Packages 162 | *.nupkg 163 | # The packages folder can be ignored because of Package Restore 164 | **/packages/* 165 | # except build/, which is used as an MSBuild target. 166 | !**/packages/build/ 167 | # Uncomment if necessary however generally it will be regenerated when needed 168 | #!**/packages/repositories.config 169 | # NuGet v3's project.json files produces more ignorable files 170 | *.nuget.props 171 | *.nuget.targets 172 | 173 | # Microsoft Azure Build Output 174 | csx/ 175 | *.build.csdef 176 | 177 | # Microsoft Azure Emulator 178 | ecf/ 179 | rcf/ 180 | 181 | # Windows Store app package directories and files 182 | AppPackages/ 183 | BundleArtifacts/ 184 | Package.StoreAssociation.xml 185 | _pkginfo.txt 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 | *.jfm 200 | *.pfx 201 | *.publishsettings 202 | orleans.codegen.cs 203 | 204 | # Since there are multiple workflows, uncomment next line to ignore bower_components 205 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 206 | #bower_components/ 207 | 208 | # RIA/Silverlight projects 209 | Generated_Code/ 210 | 211 | # Backup & report files from converting an old project file 212 | # to a newer Visual Studio version. Backup files are not needed, 213 | # because we have git ;-) 214 | _UpgradeReport_Files/ 215 | Backup*/ 216 | UpgradeLog*.XML 217 | UpgradeLog*.htm 218 | 219 | # SQL Server files 220 | *.mdf 221 | *.ldf 222 | *.ndf 223 | 224 | # Business Intelligence projects 225 | *.rdl.data 226 | *.bim.layout 227 | *.bim_*.settings 228 | 229 | # Microsoft Fakes 230 | FakesAssemblies/ 231 | 232 | # GhostDoc plugin setting file 233 | *.GhostDoc.xml 234 | 235 | # Node.js Tools for Visual Studio 236 | .ntvs_analysis.dat 237 | node_modules/ 238 | 239 | # Typescript v1 declaration files 240 | typings/ 241 | 242 | # Visual Studio 6 build log 243 | *.plg 244 | 245 | # Visual Studio 6 workspace options file 246 | *.opt 247 | 248 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 249 | *.vbw 250 | 251 | # Visual Studio LightSwitch build output 252 | **/*.HTMLClient/GeneratedArtifacts 253 | **/*.DesktopClient/GeneratedArtifacts 254 | **/*.DesktopClient/ModelManifest.xml 255 | **/*.Server/GeneratedArtifacts 256 | **/*.Server/ModelManifest.xml 257 | _Pvt_Extensions 258 | 259 | # Paket dependency manager 260 | .paket/paket.exe 261 | paket-files/ 262 | 263 | # FAKE - F# Make 264 | .fake/ 265 | 266 | # JetBrains Rider 267 | .idea/ 268 | *.sln.iml 269 | 270 | # CodeRush 271 | .cr/ 272 | 273 | # Python Tools for Visual Studio (PTVS) 274 | __pycache__/ 275 | *.pyc 276 | 277 | # Cake - Uncomment if you are using it 278 | # tools/** 279 | # !tools/packages.config 280 | 281 | # Telerik's JustMock configuration file 282 | *.jmconfig 283 | 284 | # BizTalk build output 285 | *.btp.cs 286 | *.btm.cs 287 | *.odx.cs 288 | *.xsd.cs -------------------------------------------------------------------------------- /demo/ObfsDemo/ObfsDemo/ObfsDemo.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 15.0 23 | {8772866D-33B7-4D0D-BE55-9351A50B30B6} 24 | Win32Proj 25 | ObfsDemo 26 | 10.0.16299.0 27 | 28 | 29 | 30 | Application 31 | true 32 | LLVM-vs2017 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | LLVM-vs2017 39 | true 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | LLVM-vs2017 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | LLVM-vs2017 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | 76 | 77 | true 78 | $(SolutionDir)\$(Configuration)_x64\ 79 | $(Configuration)_x64\ 80 | 81 | 82 | false 83 | 84 | 85 | false 86 | $(SolutionDir)\$(Configuration)_x64\ 87 | $(Configuration)_x64\ 88 | 89 | 90 | 91 | NotUsing 92 | Level3 93 | Disabled 94 | false 95 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 96 | false 97 | false 98 | 99 | 100 | Console 101 | true 102 | 103 | 104 | 105 | 106 | NotUsing 107 | Level3 108 | Disabled 109 | false 110 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 111 | false 112 | false 113 | 114 | 115 | Console 116 | true 117 | 118 | 119 | 120 | 121 | NotUsing 122 | Level3 123 | MaxSpeed 124 | true 125 | true 126 | false 127 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 128 | false 129 | false 130 | MultiThreaded 131 | 132 | 133 | Console 134 | true 135 | true 136 | true 137 | 138 | 139 | 140 | 141 | NotUsing 142 | Level3 143 | MaxSpeed 144 | true 145 | true 146 | false 147 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 148 | false 149 | false 150 | MultiThreaded 151 | 152 | 153 | Console 154 | true 155 | true 156 | true 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | -------------------------------------------------------------------------------- /obfuscation.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef OBFS_STRING_FUNC 3 | #define OBFS_STRING_FUNC 4 | #include 5 | 6 | //-------------------------------------------------------------// 7 | // "Malware related compile-time hacks with C++11" by LeFF // 8 | // You can use this code however you like, I just don't really // 9 | // give a shit, but if you feel some respect for me, please // 10 | // don't cut off this comment when copy-pasting... ;-) // 11 | //-------------------------------------------------------------// 12 | 13 | //////////////////////////////////////////////////////////////////// 14 | template struct EnsureCompileTime { 15 | enum : int { 16 | Value = X 17 | }; 18 | }; 19 | //////////////////////////////////////////////////////////////////// 20 | 21 | 22 | //////////////////////////////////////////////////////////////////// 23 | //Use Compile-Time as Myseed 24 | #define Myseed ((__TIME__[7] - '0') * 1 + (__TIME__[6] - '0') * 10 + \ 25 | (__TIME__[4] - '0') * 60 + (__TIME__[3] - '0') * 600 + \ 26 | (__TIME__[1] - '0') * 3600 + (__TIME__[0] - '0') * 36000) 27 | //////////////////////////////////////////////////////////////////// 28 | 29 | 30 | //////////////////////////////////////////////////////////////////// 31 | constexpr int LinearCongruentGenerator(int Rounds) { 32 | return 1013904223 + 1664525 * ((Rounds> 0) ? LinearCongruentGenerator(Rounds - 1) : Myseed & 0xFFFFFFFF); 33 | } 34 | #define Random() EnsureCompileTime::Value //10 Rounds 35 | #define RandomNumber(Min, Max) (Min + (Random() % (Max - Min + 1))) 36 | //////////////////////////////////////////////////////////////////// 37 | 38 | 39 | //////////////////////////////////////////////////////////////////// 40 | template struct IndexList {}; 41 | //////////////////////////////////////////////////////////////////// 42 | 43 | 44 | //////////////////////////////////////////////////////////////////// 45 | template struct Append; 46 | template struct Append, Right> { 47 | typedef IndexList Result; 48 | }; 49 | //////////////////////////////////////////////////////////////////// 50 | 51 | 52 | //////////////////////////////////////////////////////////////////// 53 | template struct ConstructIndexList { 54 | typedef typename Append::Result, N - 1>::Result Result; 55 | }; 56 | template <> struct ConstructIndexList<0> { 57 | typedef IndexList<> Result; 58 | }; 59 | //////////////////////////////////////////////////////////////////// 60 | 61 | 62 | //////////////////////////////////////////////////////////////////// 63 | const char XORKEY = static_cast(RandomNumber(0, 0xFF)); 64 | __forceinline constexpr char EncryptCharacter(const char Character, int Index) { 65 | return Character ^ (XORKEY + Index); 66 | } 67 | template class CXorString; 68 | template class CXorString > { 69 | private: 70 | char Value[sizeof...(Index)+1]; 71 | public: 72 | __forceinline constexpr CXorString(const char* const String) 73 | : Value{ EncryptCharacter(String[Index], Index)... } {} 74 | 75 | __forceinline char* decrypt() { 76 | for (int t = 0; t < sizeof...(Index); t++) { 77 | Value[t] = Value[t] ^ (XORKEY + t); 78 | } 79 | Value[sizeof...(Index)] = '\0'; 80 | return Value; 81 | } 82 | 83 | __forceinline char* get() { 84 | return Value; 85 | } 86 | }; 87 | 88 | const wchar_t XORKEYW = static_cast(RandomNumber(0, 0xFFFF)); 89 | __forceinline constexpr wchar_t EncryptCharacterW(const wchar_t Character, int Index) { 90 | return Character ^ (XORKEYW + Index); 91 | } 92 | template class CXorStringW; 93 | template class CXorStringW > { 94 | private: 95 | wchar_t Value[sizeof...(Index)+1]; 96 | public: 97 | __forceinline constexpr CXorStringW(const wchar_t* const String) 98 | : Value{ EncryptCharacterW(String[Index], Index)... } {} 99 | 100 | __forceinline wchar_t* decrypt() { 101 | for (int t = 0; t < sizeof...(Index); t++) { 102 | Value[t] = Value[t] ^ (XORKEYW + t); 103 | } 104 | Value[sizeof...(Index)] = '\0'; 105 | return Value; 106 | } 107 | 108 | __forceinline wchar_t* get() { 109 | return Value; 110 | } 111 | }; 112 | 113 | #define XorS(X, String) CXorString::Result> X(String) 114 | #define XorString( String ) ( CXorString::Result>( String ).decrypt() ) 115 | #define XorSW(X, String) CXorStringW::Result> X(String) 116 | #define XorStringW( String ) ( CXorStringW::Result>( String ).decrypt() ) 117 | //////////////////////////////////////////////////////////////////// 118 | 119 | 120 | 121 | 122 | 123 | 124 | #include 125 | #include 126 | 127 | constexpr uint32_t val_32_const = 0x811c9dc5; 128 | constexpr uint32_t prime_32_const = 0x1000193; 129 | constexpr uint64_t val_64_const = 0xcbf29ce484222325; 130 | constexpr uint64_t prime_64_const = 0x100000001b3; 131 | 132 | inline constexpr uint32_t hash_32_fnv1a_const(const char* const str, const uint32_t value = val_32_const) noexcept { 133 | return (str[0] == '\0') ? value : hash_32_fnv1a_const(&str[1], (value ^ uint32_t(str[0])) * prime_32_const); 134 | } 135 | 136 | inline constexpr uint64_t hash_64_fnv1a_const(const char* const str, const uint64_t value = val_64_const) noexcept { 137 | return (str[0] == '\0') ? value : hash_64_fnv1a_const(&str[1], (value ^ uint64_t(str[0])) * prime_64_const); 138 | } 139 | 140 | 141 | constexpr uint32_t cx_fnv_hash(const char* str) { 142 | return hash_32_fnv1a_const(str); 143 | } 144 | 145 | // Thread Environment Block (TEB) 146 | #if defined(_M_X64) // x64 147 | static PTEB tebPtr = reinterpret_cast(__readgsqword(reinterpret_cast(&static_cast(nullptr)->Self))); 148 | #else // x86 149 | static PTEB tebPtr = reinterpret_cast(__readfsdword(reinterpret_cast(&static_cast(nullptr)->Self))); 150 | #endif 151 | // Process Environment Block (PEB) 152 | 153 | static void* GetModuleProcAddressByHash(void* moduleBase, uint32_t procNameHash) { 154 | 155 | PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)moduleBase; 156 | if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE) return NULL; 157 | PIMAGE_NT_HEADERS headers32 = (PIMAGE_NT_HEADERS)((char*)moduleBase + dosHeader->e_lfanew); 158 | if (headers32->Signature != IMAGE_NT_SIGNATURE) return NULL; 159 | if (headers32->FileHeader.SizeOfOptionalHeader < 96 || headers32->OptionalHeader.NumberOfRvaAndSizes == 0) return NULL; 160 | DWORD EdtOffset = headers32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; 161 | if (!EdtOffset) return NULL; 162 | 163 | typedef struct _EXPORT_DIRECTORY_TABLE { 164 | DWORD ExportFlags; 165 | DWORD TimeStamp; 166 | WORD MajorVersion; 167 | WORD MinorVersion; 168 | DWORD NameRVA; 169 | DWORD OrdinalBase; 170 | DWORD ExportAddressTableSize; 171 | DWORD NamePointerTableSize; 172 | DWORD ExportAddressTableRVA; 173 | DWORD NamePointerTableRVA; 174 | DWORD OrdinalTableRVA; 175 | } EXPORT_DIRECTORY_TABLE, *PEXPORT_DIRECTORY_TABLE; 176 | 177 | PEXPORT_DIRECTORY_TABLE EdtPtr = 178 | (PEXPORT_DIRECTORY_TABLE)((char*)moduleBase + EdtOffset); 179 | PVOID OrdinalTable = (PBYTE)moduleBase + EdtPtr->OrdinalTableRVA; 180 | PVOID NamePointerTable = (PBYTE)moduleBase + EdtPtr->NamePointerTableRVA; 181 | PVOID ExportAddressTable = (PBYTE)moduleBase + EdtPtr->ExportAddressTableRVA; 182 | 183 | for (DWORD i = 0; i < EdtPtr->NamePointerTableSize; i++) { 184 | DWORD NameRVA = ((PDWORD)NamePointerTable)[i]; 185 | const char* NameAddr = (char*)moduleBase + NameRVA; 186 | 187 | //if (strcmp(NameAddr, procName)) 188 | // continue; 189 | if (cx_fnv_hash(NameAddr) != procNameHash) 190 | continue; 191 | 192 | 193 | WORD Ordinal = ((PWORD)OrdinalTable)[i] + (WORD)EdtPtr->OrdinalBase; 194 | WORD RealOrdinal = Ordinal - (WORD)EdtPtr->OrdinalBase; 195 | DWORD ExportAddress = 0; 196 | ExportAddress = ((PDWORD)ExportAddressTable)[RealOrdinal]; 197 | void* FinalAddr = (char*)moduleBase + ExportAddress; 198 | return FinalAddr; 199 | } 200 | return NULL; 201 | } 202 | static void* GetProcPtr(uint32_t procNameHash, const wchar_t* dllName = NULL, const char* name = NULL) { 203 | //Get Pointer to PEB structure 204 | PPEB pebPtr = tebPtr->ProcessEnvironmentBlock; 205 | //Reference point / tail to compare against, since the list is circular 206 | PLIST_ENTRY moduleListTail = &pebPtr->Ldr->InMemoryOrderModuleList; 207 | PLIST_ENTRY moduleList = moduleListTail->Flink; 208 | //Traverse the list until moduleList gets back to moduleListTail 209 | do { 210 | char* modulePtrWithOffset = (char*)moduleList; 211 | //List is intrusive, a part of a larger LDR_DATA_TABLE structure, 212 | //so cast the pointer 213 | PLDR_DATA_TABLE_ENTRY module = (PLDR_DATA_TABLE_ENTRY)modulePtrWithOffset; 214 | //Compare the name of the entry against our parameter name 215 | //Note that the name is a wide string 216 | 217 | void *funcPtr = nullptr; 218 | //The actual position of the image base address inside 219 | //the LDR_DATA_TABLE_ENTRY seems to change *a lot*. 220 | //Apparently on Windows 8.1 it wasn't located in the 221 | //correct place according to my structures defined above. 222 | //It should have been "DllBase", but apparently it 223 | //was 8 bytes back, inside Reserved2[0] 224 | void* DllBase = module->Reserved2[0]; 225 | 226 | if (!dllName || _wcsicmp(module->FullDllName.Buffer, dllName) == 0) 227 | if (funcPtr = GetModuleProcAddressByHash(DllBase, procNameHash)) { 228 | 229 | #if defined(_DEBUG) || defined(_MY_DEBUG) 230 | if (name && strcmp(name, "DefWindowProcW1222_test") == 0) { 231 | 232 | wchar_t errMsg[1024] = { 0 }; 233 | swprintf_s(errMsg, L"Module: %s\n%u\n", module->FullDllName.Buffer, (int)funcPtr); 234 | (MessageBoxW)(0, errMsg, (L"Find function HeapAlloc"), MB_OK); 235 | } 236 | else 237 | #endif 238 | return funcPtr; 239 | } 240 | moduleList = moduleList->Flink; 241 | } while (moduleList != moduleListTail); 242 | #if defined(_DEBUG) || defined(_MY_DEBUG) 243 | char errMsg[1024] = { 0 }; 244 | sprintf_s(errMsg, "Function: %s\nHash: %u", name ? name : "NULL", procNameHash); 245 | (MessageBoxA)(0, errMsg, ("Can't find function"), MB_ICONERROR | MB_OK); 246 | ExitProcess(0); 247 | #endif 248 | return NULL; 249 | } 250 | 251 | 252 | 253 | 254 | static void *get_func_by_hash(uint32_t hash, const wchar_t* dllName = NULL, const char* name = NULL) { 255 | return GetProcPtr(hash, dllName, name); 256 | } 257 | template 258 | static void* lazyimport_get(const wchar_t* dllName = NULL, const char* name = NULL) 259 | { 260 | static void* pfn; 261 | if (!pfn) 262 | pfn = get_func_by_hash(hash, dllName, name); 263 | return pfn; 264 | } 265 | 266 | #if defined(_DEBUG) || defined(_MY_DEBUG) 267 | #define IFN_DLL(dllName,name) (reinterpret_cast(lazyimport_get(dllName,#name))) 268 | #define IFN(name) (reinterpret_cast(lazyimport_get(0,#name))) 269 | #define IFN_PTR_DLL(dllName,name) (lazyimport_get(dllName,#name)) 270 | #define IFN_PTR(name) (lazyimport_get(0,#name)) 271 | #else 272 | #define IFN_DLL(dllName,name) (reinterpret_cast(lazyimport_get(dllName))) 273 | #define IFN(name) (reinterpret_cast(lazyimport_get())) 274 | #define IFN_PTR_DLL(dllName,name) (lazyimport_get(dllName)) 275 | #define IFN_PTR(name) (lazyimport_get()) 276 | #endif // DEBUG 277 | 278 | 279 | #endif --------------------------------------------------------------------------------