├── .gitignore ├── LICENSE ├── README.md ├── research.md ├── resources ├── demo.gif └── tamper.png └── src ├── defender-control.sln ├── defender-control ├── dcontrol.cpp ├── dcontrol.hpp ├── defender-control.vcxproj ├── defender-control.vcxproj.filters ├── gui.cpp ├── gui.hpp ├── gui_dx11.cpp ├── gui_dx11.hpp ├── imgui │ ├── LICENSE.txt │ ├── backends │ │ ├── imgui_impl_dx11.cpp │ │ ├── imgui_impl_dx11.h │ │ ├── imgui_impl_dx9.cpp │ │ ├── imgui_impl_dx9.h │ │ ├── imgui_impl_win32.cpp │ │ └── imgui_impl_win32.h │ ├── imconfig.h │ ├── imgui.cpp │ ├── imgui.h │ ├── imgui_demo.cpp │ ├── imgui_draw.cpp │ ├── imgui_internal.h │ ├── imgui_tables.cpp │ ├── imgui_widgets.cpp │ ├── imstb_rectpack.h │ ├── imstb_textedit.h │ └── imstb_truetype.h ├── main.cpp ├── reg.cpp ├── reg.hpp ├── settings.hpp ├── trusted.cpp ├── trusted.hpp ├── util.cpp ├── util.hpp ├── wmic.cpp └── wmic.hpp ├── detour ├── 64 │ ├── include │ │ ├── detours.h │ │ ├── detver.h │ │ └── syelog.h │ └── lib │ │ ├── detours.lib │ │ └── syelog.lib ├── 86 │ ├── include │ │ ├── detours.h │ │ ├── detver.h │ │ └── syelog.h │ └── lib │ │ ├── detours.lib │ │ └── syelog.lib └── README.md └── dumper ├── dumper.cpp ├── dumper.vcxproj ├── dumper.vcxproj.filters ├── framework.h ├── pch.cpp └── pch.h /.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 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Aa][Rr][Mm]/ 27 | [Aa][Rr][Mm]64/ 28 | bld/ 29 | [Bb]in/ 30 | [Oo]bj/ 31 | [Ll]og/ 32 | [Ll]ogs/ 33 | 34 | # Visual Studio 2015/2017 cache/options directory 35 | .vs/ 36 | # Uncomment if you have tasks that create the project's static files in wwwroot 37 | #wwwroot/ 38 | 39 | # Visual Studio 2017 auto generated files 40 | Generated\ Files/ 41 | 42 | # MSTest test Results 43 | [Tt]est[Rr]esult*/ 44 | [Bb]uild[Ll]og.* 45 | 46 | # NUnit 47 | *.VisualState.xml 48 | TestResult.xml 49 | nunit-*.xml 50 | 51 | # Build Results of an ATL Project 52 | [Dd]ebugPS/ 53 | [Rr]eleasePS/ 54 | dlldata.c 55 | 56 | # Benchmark Results 57 | BenchmarkDotNet.Artifacts/ 58 | 59 | # .NET Core 60 | project.lock.json 61 | project.fragment.lock.json 62 | artifacts/ 63 | 64 | # StyleCop 65 | StyleCopReport.xml 66 | 67 | # Files built by Visual Studio 68 | *_i.c 69 | *_p.c 70 | *_h.h 71 | *.ilk 72 | *.meta 73 | *.obj 74 | *.iobj 75 | *.pch 76 | *.pdb 77 | *.ipdb 78 | *.pgc 79 | *.pgd 80 | *.rsp 81 | *.sbr 82 | *.tlb 83 | *.tli 84 | *.tlh 85 | *.tmp 86 | *.tmp_proj 87 | *_wpftmp.csproj 88 | *.log 89 | *.vspscc 90 | *.vssscc 91 | .builds 92 | *.pidb 93 | *.svclog 94 | *.scc 95 | 96 | # Chutzpah Test files 97 | _Chutzpah* 98 | 99 | # Visual C++ cache files 100 | ipch/ 101 | *.aps 102 | *.ncb 103 | *.opendb 104 | *.opensdf 105 | *.sdf 106 | *.cachefile 107 | *.VC.db 108 | *.VC.VC.opendb 109 | 110 | # Visual Studio profiler 111 | *.psess 112 | *.vsp 113 | *.vspx 114 | *.sap 115 | 116 | # Visual Studio Trace Files 117 | *.e2e 118 | 119 | # TFS 2012 Local Workspace 120 | $tf/ 121 | 122 | # Guidance Automation Toolkit 123 | *.gpState 124 | 125 | # ReSharper is a .NET coding add-in 126 | _ReSharper*/ 127 | *.[Rr]e[Ss]harper 128 | *.DotSettings.user 129 | 130 | # TeamCity is a build add-in 131 | _TeamCity* 132 | 133 | # DotCover is a Code Coverage Tool 134 | *.dotCover 135 | 136 | # AxoCover is a Code Coverage Tool 137 | .axoCover/* 138 | !.axoCover/settings.json 139 | 140 | # Visual Studio code coverage results 141 | *.coverage 142 | *.coveragexml 143 | 144 | # NCrunch 145 | _NCrunch_* 146 | .*crunch*.local.xml 147 | nCrunchTemp_* 148 | 149 | # MightyMoose 150 | *.mm.* 151 | AutoTest.Net/ 152 | 153 | # Web workbench (sass) 154 | .sass-cache/ 155 | 156 | # Installshield output folder 157 | [Ee]xpress/ 158 | 159 | # DocProject is a documentation generator add-in 160 | DocProject/buildhelp/ 161 | DocProject/Help/*.HxT 162 | DocProject/Help/*.HxC 163 | DocProject/Help/*.hhc 164 | DocProject/Help/*.hhk 165 | DocProject/Help/*.hhp 166 | DocProject/Help/Html2 167 | DocProject/Help/html 168 | 169 | # Click-Once directory 170 | publish/ 171 | 172 | # Publish Web Output 173 | *.[Pp]ublish.xml 174 | *.azurePubxml 175 | # Note: Comment the next line if you want to checkin your web deploy settings, 176 | # but database connection strings (with potential passwords) will be unencrypted 177 | *.pubxml 178 | *.publishproj 179 | 180 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 181 | # checkin your Azure Web App publish settings, but sensitive information contained 182 | # in these scripts will be unencrypted 183 | PublishScripts/ 184 | 185 | # NuGet Packages 186 | *.nupkg 187 | # NuGet Symbol Packages 188 | *.snupkg 189 | # The packages folder can be ignored because of Package Restore 190 | **/[Pp]ackages/* 191 | # except build/, which is used as an MSBuild target. 192 | !**/[Pp]ackages/build/ 193 | # Uncomment if necessary however generally it will be regenerated when needed 194 | #!**/[Pp]ackages/repositories.config 195 | # NuGet v3's project.json files produces more ignorable files 196 | *.nuget.props 197 | *.nuget.targets 198 | 199 | # Microsoft Azure Build Output 200 | csx/ 201 | *.build.csdef 202 | 203 | # Microsoft Azure Emulator 204 | ecf/ 205 | rcf/ 206 | 207 | # Windows Store app package directories and files 208 | AppPackages/ 209 | BundleArtifacts/ 210 | Package.StoreAssociation.xml 211 | _pkginfo.txt 212 | *.appx 213 | *.appxbundle 214 | *.appxupload 215 | 216 | # Visual Studio cache files 217 | # files ending in .cache can be ignored 218 | *.[Cc]ache 219 | # but keep track of directories ending in .cache 220 | !?*.[Cc]ache/ 221 | 222 | # Others 223 | ClientBin/ 224 | ~$* 225 | *~ 226 | *.dbmdl 227 | *.dbproj.schemaview 228 | *.jfm 229 | *.pfx 230 | *.publishsettings 231 | orleans.codegen.cs 232 | 233 | # Including strong name files can present a security risk 234 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 235 | #*.snk 236 | 237 | # Since there are multiple workflows, uncomment next line to ignore bower_components 238 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 239 | #bower_components/ 240 | 241 | # RIA/Silverlight projects 242 | Generated_Code/ 243 | 244 | # Backup & report files from converting an old project file 245 | # to a newer Visual Studio version. Backup files are not needed, 246 | # because we have git ;-) 247 | _UpgradeReport_Files/ 248 | Backup*/ 249 | UpgradeLog*.XML 250 | UpgradeLog*.htm 251 | ServiceFabricBackup/ 252 | *.rptproj.bak 253 | 254 | # SQL Server files 255 | *.mdf 256 | *.ldf 257 | *.ndf 258 | 259 | # Business Intelligence projects 260 | *.rdl.data 261 | *.bim.layout 262 | *.bim_*.settings 263 | *.rptproj.rsuser 264 | *- [Bb]ackup.rdl 265 | *- [Bb]ackup ([0-9]).rdl 266 | *- [Bb]ackup ([0-9][0-9]).rdl 267 | 268 | # Microsoft Fakes 269 | FakesAssemblies/ 270 | 271 | # GhostDoc plugin setting file 272 | *.GhostDoc.xml 273 | 274 | # Node.js Tools for Visual Studio 275 | .ntvs_analysis.dat 276 | node_modules/ 277 | 278 | # Visual Studio 6 build log 279 | *.plg 280 | 281 | # Visual Studio 6 workspace options file 282 | *.opt 283 | 284 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 285 | *.vbw 286 | 287 | # Visual Studio LightSwitch build output 288 | **/*.HTMLClient/GeneratedArtifacts 289 | **/*.DesktopClient/GeneratedArtifacts 290 | **/*.DesktopClient/ModelManifest.xml 291 | **/*.Server/GeneratedArtifacts 292 | **/*.Server/ModelManifest.xml 293 | _Pvt_Extensions 294 | 295 | # Paket dependency manager 296 | .paket/paket.exe 297 | paket-files/ 298 | 299 | # FAKE - F# Make 300 | .fake/ 301 | 302 | # CodeRush personal settings 303 | .cr/personal 304 | 305 | # Python Tools for Visual Studio (PTVS) 306 | __pycache__/ 307 | *.pyc 308 | 309 | # Cake - Uncomment if you are using it 310 | # tools/** 311 | # !tools/packages.config 312 | 313 | # Tabs Studio 314 | *.tss 315 | 316 | # Telerik's JustMock configuration file 317 | *.jmconfig 318 | 319 | # BizTalk build output 320 | *.btp.cs 321 | *.btm.cs 322 | *.odx.cs 323 | *.xsd.cs 324 | 325 | # OpenCover UI analysis results 326 | OpenCover/ 327 | 328 | # Azure Stream Analytics local run output 329 | ASALocalRun/ 330 | 331 | # MSBuild Binary and Structured Log 332 | *.binlog 333 | 334 | # NVidia Nsight GPU debugger configuration file 335 | *.nvuser 336 | 337 | # MFractors (Xamarin productivity tool) working folder 338 | .mfractor/ 339 | 340 | # Local History for Visual Studio 341 | .localhistory/ 342 | 343 | # BeatPulse healthcheck temp database 344 | healthchecksdb 345 | 346 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 347 | MigrationBackup/ 348 | 349 | # Ionide (cross platform F# VS Code tools) working folder 350 | .ionide/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021-2022 qtKite 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Defender Control 2 | Open source windows defender disabler. 3 | Now you can disable windows defender permanently! 4 | Tested from Windows 10 20H2. 5 | 6 | ## What is this project? 7 | We all know that disabling windefender is very difficult since microsoft is constantly enforcing changes. 8 | The first solution is to install an anti-virus - but thats not the point if we are trying to disable it! 9 | The next easiest solution is to use freeware thats already available on the internet - but none of them are native & open source... 10 | I like open source, so I made a safe to use open source defender control. 11 | 12 | ## On windows updates / Windows 11 13 | Sometimes windows decides to update and turn itself back on. 14 | A common issue is that defender control sometimes doesn't want to disable tamper protection again. 15 | Please try turning off tamper protection manually then running disable-defender.exe again before posting an issue. 16 | 17 | ![Tamper](https://github.com/qtkite/defender-control/blob/main/resources/tamper.png?raw=true) 18 | 19 | ## What does it do? 20 | 1. It gains TrustedInstaller permissions 21 | 2. It will disable windefender services + smartscreen 22 | 3. It will disable anti-tamper protection 23 | 4. It will disable all relevant registries + wmi settings 24 | 25 | ## Is it safe? 26 | Yes it is safe, feel free to review the code in the repository yourself. 27 | Anti-virus & other programs might flag this as malicious since it disables defender - but feel free to compile it using visual studio. 28 | 29 | ## Compiling 30 | Open the project using visual studio 2022 preview. 31 | Set the build to Release and x64. 32 | Change the build type you want in settings.hpp. 33 | Compile. 34 | 35 | ## Demo 36 | ![Demo](https://github.com/qtkite/defender-control/blob/main/resources/demo.gif?raw=true) 37 | 38 | ## Release 39 | You can find the first release over at the releases on the right. 40 | Or alternatively click [here](https://github.com/qtkite/defender-control/releases/tag/v1.2). 41 | 42 | ## Windows 11 43 | Works for earlier versions of Windows 11. Correct registries have not been added yet for the latest version. 44 | Update, Trusted Installer no longer has effect on the current live versions of Windows 11. Use with caution. 45 | -------------------------------------------------------------------------------- /resources/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pgkt04/defender-control/f4bb9f3340c83e6a0ab50650697ce865e935ba37/resources/demo.gif -------------------------------------------------------------------------------- /resources/tamper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pgkt04/defender-control/f4bb9f3340c83e6a0ab50650697ce865e935ba37/resources/tamper.png -------------------------------------------------------------------------------- /src/defender-control.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.31229.75 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "defender-control", "defender-control\defender-control.vcxproj", "{7C2C0AEC-7B9D-4104-99FA-1844D609452C}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dumper", "dumper\dumper.vcxproj", "{089CA7D6-3277-4998-86AF-F6413290A442}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Debug|x64 = Debug|x64 14 | Debug|x86 = Debug|x86 15 | Release|Any CPU = Release|Any CPU 16 | Release|x64 = Release|x64 17 | Release|x86 = Release|x86 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {7C2C0AEC-7B9D-4104-99FA-1844D609452C}.Debug|Any CPU.ActiveCfg = Debug|Win32 21 | {7C2C0AEC-7B9D-4104-99FA-1844D609452C}.Debug|x64.ActiveCfg = Debug|x64 22 | {7C2C0AEC-7B9D-4104-99FA-1844D609452C}.Debug|x64.Build.0 = Debug|x64 23 | {7C2C0AEC-7B9D-4104-99FA-1844D609452C}.Debug|x86.ActiveCfg = Debug|Win32 24 | {7C2C0AEC-7B9D-4104-99FA-1844D609452C}.Debug|x86.Build.0 = Debug|Win32 25 | {7C2C0AEC-7B9D-4104-99FA-1844D609452C}.Release|Any CPU.ActiveCfg = Release|Win32 26 | {7C2C0AEC-7B9D-4104-99FA-1844D609452C}.Release|x64.ActiveCfg = Release|x64 27 | {7C2C0AEC-7B9D-4104-99FA-1844D609452C}.Release|x64.Build.0 = Release|x64 28 | {7C2C0AEC-7B9D-4104-99FA-1844D609452C}.Release|x86.ActiveCfg = Release|Win32 29 | {7C2C0AEC-7B9D-4104-99FA-1844D609452C}.Release|x86.Build.0 = Release|Win32 30 | {089CA7D6-3277-4998-86AF-F6413290A442}.Debug|Any CPU.ActiveCfg = Debug|Win32 31 | {089CA7D6-3277-4998-86AF-F6413290A442}.Debug|x64.ActiveCfg = Debug|x64 32 | {089CA7D6-3277-4998-86AF-F6413290A442}.Debug|x64.Build.0 = Debug|x64 33 | {089CA7D6-3277-4998-86AF-F6413290A442}.Debug|x86.ActiveCfg = Debug|Win32 34 | {089CA7D6-3277-4998-86AF-F6413290A442}.Debug|x86.Build.0 = Debug|Win32 35 | {089CA7D6-3277-4998-86AF-F6413290A442}.Release|Any CPU.ActiveCfg = Release|Win32 36 | {089CA7D6-3277-4998-86AF-F6413290A442}.Release|x64.ActiveCfg = Release|x64 37 | {089CA7D6-3277-4998-86AF-F6413290A442}.Release|x64.Build.0 = Release|x64 38 | {089CA7D6-3277-4998-86AF-F6413290A442}.Release|x86.ActiveCfg = Release|Win32 39 | {089CA7D6-3277-4998-86AF-F6413290A442}.Release|x86.Build.0 = Release|Win32 40 | EndGlobalSection 41 | GlobalSection(SolutionProperties) = preSolution 42 | HideSolutionNode = FALSE 43 | EndGlobalSection 44 | GlobalSection(ExtensibilityGlobals) = postSolution 45 | SolutionGuid = {708A26F9-CBFF-49C9-8F9D-1C62AF49488E} 46 | EndGlobalSection 47 | EndGlobal 48 | -------------------------------------------------------------------------------- /src/defender-control/dcontrol.cpp: -------------------------------------------------------------------------------- 1 | #include "dcontrol.hpp" 2 | 3 | namespace dcontrol 4 | { 5 | // Toggles windows tamper protection 6 | // 7 | void toggle_tamper(bool enable) 8 | { 9 | HKEY hkey; 10 | 11 | if (reg::create_registry(L"SOFTWARE\\Microsoft\\Windows Defender\\Features", hkey)) 12 | { 13 | if (enable) 14 | { 15 | if (!reg::set_keyval(hkey, L"TamperProtection", 5)) 16 | std::cout << "failed to write to TamperProtection" << std::endl; 17 | } 18 | else 19 | { 20 | if (!reg::set_keyval(hkey, L"TamperProtection", 0)) 21 | std::cout << "failed to write to TamperProtection" << std::endl; 22 | } 23 | } 24 | } 25 | 26 | // Ends the smart screen process 27 | // 28 | void kill_smartscreen() 29 | { 30 | auto pid = util::get_pid("smartscreen.exe"); 31 | auto proc = OpenProcess(PROCESS_TERMINATE, FALSE, pid); 32 | 33 | // TODO: Create a better solution to terminate smartscreen 34 | // https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-terminateprocess 35 | // The state of global data maintained by dynamic-link libraries 36 | // (DLLs) may be compromised if TerminateProcess is used rather than ExitProcess. 37 | // e.g. Injecting code to execute ExitProcess and manually unloaded everything 38 | 39 | TerminateProcess(proc, 0); 40 | 41 | if (proc) 42 | CloseHandle(proc); 43 | } 44 | 45 | // TODO: create a single function 46 | 47 | bool manage_security_service(bool enable, std::string service_name) 48 | { 49 | auto sc_manager = OpenSCManagerA(0, 0, SC_MANAGER_CONNECT); 50 | 51 | if (!sc_manager) 52 | return false; 53 | 54 | auto service = OpenServiceA( 55 | sc_manager, 56 | service_name.c_str(), 57 | enable ? SERVICE_ALL_ACCESS : 58 | (SERVICE_CHANGE_CONFIG | SERVICE_STOP | DELETE) 59 | ); 60 | 61 | if (!service) 62 | { 63 | CloseServiceHandle(sc_manager); 64 | return false; 65 | } 66 | 67 | if (enable) 68 | { 69 | // Change to auto-start 70 | if (!ChangeServiceConfigA( 71 | service, 72 | SERVICE_NO_CHANGE, 73 | SERVICE_AUTO_START, 74 | SERVICE_NO_CHANGE, 75 | 0, 0, 0, 0, 0, 0, 0 76 | )) 77 | { 78 | throw std::runtime_error("Failed to modify " + service_name + " " + std::to_string(GetLastError())); 79 | return false; 80 | } 81 | 82 | // Start the service 83 | if (!StartServiceA(service, 0, NULL)) 84 | { 85 | throw std::runtime_error("Failed to start " + service_name); 86 | return false; 87 | } 88 | } 89 | else 90 | { 91 | // Stop the service 92 | SERVICE_STATUS scStatus; 93 | if (!ControlService(service, SERVICE_CONTROL_STOP, &scStatus)) 94 | { 95 | auto last_error = GetLastError(); 96 | 97 | if (last_error == ERROR_SERVICE_NOT_ACTIVE) 98 | return true; 99 | 100 | throw std::runtime_error( 101 | "Failed to stop " + service_name + " " + std::to_string(last_error) 102 | ); 103 | return false; 104 | } 105 | 106 | // Change to DEMAND 107 | if (!ChangeServiceConfigA( 108 | service, 109 | SERVICE_NO_CHANGE, 110 | SERVICE_DEMAND_START, 111 | SERVICE_NO_CHANGE, 112 | 0, 0, 0, 0, 0, 0, 0 113 | )) 114 | { 115 | throw std::runtime_error( 116 | "Failed to modify " + service_name + " " + std::to_string(GetLastError()) 117 | ); 118 | 119 | return false; 120 | } 121 | 122 | // Allow time for service to stop 123 | // TODO: Handle this automatically 124 | Sleep(3000); 125 | } 126 | 127 | return true; 128 | } 129 | 130 | // Stop or run security center (wscvc) 131 | // The default value is autostart 132 | // 133 | bool manage_security_center(bool enable) 134 | { 135 | // handle registry calls 136 | // https://superuser.com/questions/1199112/how-to-tell-the-state-of-a-service-from-the-registry 137 | // https://stackoverflow.com/questions/291519/how-does-currentcontrolset-differ-from-controlset001-and-controlset002 138 | // https://web.archive.org/web/20110514163940/http://support.microsoft.com/kb/103000 139 | // 140 | 141 | // auto ret = manage_security_service(enable, "wscsvc"); 142 | 143 | HKEY hkey; 144 | if (reg::create_registry(L"SYSTEM\\CurrentControlSet\\Services\\wscsvc", hkey)) 145 | { 146 | if (enable) 147 | { 148 | if (!reg::set_keyval(hkey, L"Start", 2)) // Automatic 149 | { 150 | printf("failed to write to wscsvc\n"); 151 | return false; 152 | } 153 | } 154 | else 155 | { 156 | if (!reg::set_keyval(hkey, L"Start", 4)) // Disabled 157 | { 158 | printf("failed to write to wscsvc\n"); 159 | return false; 160 | } 161 | } 162 | } 163 | 164 | return true; 165 | } 166 | 167 | // Stop or run the windefend service 168 | // 169 | bool manage_windefend(bool enable) 170 | { 171 | return manage_security_service(enable, "WinDefend"); 172 | } 173 | 174 | // Disables window defender 175 | // 176 | bool disable_defender() 177 | { 178 | HKEY hkey; 179 | 180 | // DisableAntiSpyware 181 | if (reg::create_registry(L"SOFTWARE\\Policies\\Microsoft\\Windows Defender", hkey)) 182 | { 183 | if (!reg::set_keyval(hkey, L"DisableAntiSpyware", 1)) 184 | printf("failed to write to DisableAntiSpyware\n"); 185 | } 186 | else 187 | printf("Failed to access Policies\n"); 188 | 189 | // SecurityHealth 190 | if (reg::create_registry( 191 | L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StartupApproved\\Run", 192 | hkey)) 193 | { 194 | if (!reg::set_keyval_bin(hkey, L"SecurityHealth", 3)) 195 | printf("Failed to write to SecurityHealth\n"); 196 | } 197 | else 198 | printf("Failed to access CurrentVersion\n"); 199 | 200 | // Protected by anti-tamper 201 | if (reg::create_registry(L"SOFTWARE\\Microsoft\\Windows Defender", hkey)) 202 | { 203 | if (!reg::set_keyval(hkey, L"DisableAntiSpyware", 1)) 204 | printf("Failed to write to DisableAntiSpyware"); 205 | } 206 | else 207 | printf("Failed to access Windows Defender\n"); 208 | 209 | // Protected by anti-tamper 210 | // Start (3 off) (2 on) 211 | if (reg::create_registry(L"SYSTEM\\CurrentControlSet\\Services\\WinDefend", hkey)) 212 | { 213 | reg::set_keyval(hkey, L"Start", 3); 214 | } 215 | else 216 | printf("Failed to access CurrentControlSet\n"); 217 | 218 | // Protected by anti-tamper 219 | if (reg::create_registry(L"SOFTWARE\\Microsoft\\Windows Defender\\Real-Time Protection", hkey)) 220 | { 221 | if (!reg::set_keyval(hkey, L"DisableRealtimeMonitoring", 1)) 222 | printf("Failed to write to DisableRealTimeMonitoring\n"); 223 | } 224 | else 225 | printf("Failed to access Real-Time Protection"); 226 | 227 | auto helper = new wmic::helper( 228 | "Root\\Microsoft\\Windows\\Defender", 229 | "MSFT_MpPreference", 230 | "Set" 231 | ); 232 | 233 | if (auto error = helper->get_last_error()) 234 | { 235 | printf("Error has occured: %d\n", error); 236 | return false; 237 | } 238 | 239 | // string types 240 | helper->execute("EnableControlledFolderAccess", "Disabled"); 241 | helper->execute("PUAProtection", "disable"); 242 | 243 | // bool types 244 | helper->execute("DisableRealtimeMonitoring", wmic::variant_type::t_bool, TRUE); 245 | helper->execute("DisableBehaviorMonitoring", wmic::variant_type::t_bool, TRUE); 246 | helper->execute("DisableBlockAtFirstSeen", wmic::variant_type::t_bool, TRUE); 247 | helper->execute("DisableIOAVProtection", wmic::variant_type::t_bool, TRUE); 248 | helper->execute("DisablePrivacyMode", wmic::variant_type::t_bool, TRUE); 249 | helper->execute("SignatureDisableUpdateOnStartupWithoutEngine", wmic::variant_type::t_bool, TRUE); 250 | helper->execute("DisableArchiveScanning", wmic::variant_type::t_bool, TRUE); 251 | helper->execute("DisableIntrusionPreventionSystem", wmic::variant_type::t_bool, TRUE); 252 | helper->execute("DisableScriptScanning", wmic::variant_type::t_bool, TRUE); 253 | helper->execute("DisableAntiSpyware", wmic::variant_type::t_bool, TRUE); 254 | helper->execute("DisableAntiVirus", wmic::variant_type::t_bool, TRUE); 255 | 256 | // values 257 | helper->execute("SubmitSamplesConsent", wmic::variant_type::t_uint8, 2); 258 | helper->execute("MAPSReporting", wmic::variant_type::t_uint8, 0); 259 | helper->execute("HighThreatDefaultAction", wmic::variant_type::t_uint8, 6); 260 | helper->execute("ModerateThreatDefaultAction", wmic::variant_type::t_uint8, 6); 261 | helper->execute("LowThreatDefaultAction", wmic::variant_type::t_uint8, 6); 262 | helper->execute("SevereThreatDefaultAction", wmic::variant_type::t_uint8, 6); 263 | helper->execute("ScanScheduleDay", wmic::variant_type::t_uint8, 8); 264 | 265 | delete helper; 266 | 267 | return true; 268 | } 269 | 270 | // Enables defender, assumes we have TrustedInstaller permissions 271 | bool enable_defender() 272 | { 273 | HKEY hkey; 274 | 275 | // DisableAntiSpyware 276 | if (reg::create_registry(L"SOFTWARE\\Policies\\Microsoft\\Windows Defender", hkey)) 277 | { 278 | if (!reg::set_keyval(hkey, L"DisableAntiSpyware", 0)) 279 | printf("failed to write to DisableAntiSpyware\n"); 280 | } 281 | else 282 | printf("Failed to access Policies\n"); 283 | 284 | // SecurityHealth 285 | if (reg::create_registry( 286 | L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StartupApproved\\Run", 287 | hkey)) 288 | { 289 | if (!reg::set_keyval_bin(hkey, L"SecurityHealth", 2)) 290 | printf("Failed to write to SecurityHealth\n"); 291 | } 292 | else 293 | printf("Failed to access CurrentVersion\n"); 294 | 295 | // Protected by anti-tamper 296 | if (reg::create_registry(L"SOFTWARE\\Microsoft\\Windows Defender", hkey)) 297 | { 298 | if (!reg::set_keyval(hkey, L"DisableAntiSpyware", 0)) 299 | printf("Failed to write to DisableAntiSpyware"); 300 | } 301 | else 302 | printf("Failed to access Windows Defender\n"); 303 | 304 | // Protected by anti-tamper 305 | // Start (3 off) (2 on) 306 | if (reg::create_registry(L"SYSTEM\\CurrentControlSet\\Services\\WinDefend", hkey)) 307 | reg::set_keyval(hkey, L"Start", 2); 308 | else 309 | printf("Failed to access CurrentControlSet\n"); 310 | 311 | // Protected by anti-tamper 312 | if (reg::create_registry(L"SOFTWARE\\Microsoft\\Windows Defender\\Real-Time Protection", hkey)) 313 | { 314 | if (!reg::set_keyval(hkey, L"DisableRealtimeMonitoring", 0)) 315 | printf("Failed to write to DisableRealTimeMonitoring\n"); 316 | } 317 | else 318 | printf("Failed to access Real-Time Protection"); 319 | 320 | auto helper = new wmic::helper( 321 | "Root\\Microsoft\\Windows\\Defender", 322 | "MSFT_MpPreference", 323 | "Set" 324 | ); 325 | 326 | if (auto error = helper->get_last_error()) 327 | { 328 | printf("Error has occured: %d\n", error); 329 | return false; 330 | } 331 | 332 | // BSTR types 333 | helper->execute("EnableControlledFolderAccess", "Enabled"); 334 | helper->execute("PUAProtection", "enable"); 335 | 336 | auto helper_disable = [](wmic::helper* h, const char* name) { 337 | h->execute(name, wmic::variant_type::t_bool, FALSE); 338 | }; 339 | 340 | // BOOL types 341 | helper_disable(helper, "DisableRealtimeMonitoring"); 342 | helper_disable(helper, "DisableBehaviorMonitoring"); 343 | helper_disable(helper, "DisableBlockAtFirstSeen"); 344 | helper_disable(helper, "DisableIOAVProtection"); 345 | helper_disable(helper, "DisablePrivacyMode"); 346 | helper_disable(helper, "SignatureDisableUpdateOnStartupWithoutEngine"); 347 | helper_disable(helper, "DisableArchiveScanning"); 348 | helper_disable(helper, "DisableIntrusionPreventionSystem"); 349 | helper_disable(helper, "DisableScriptScanning"); 350 | helper_disable(helper, "DisableAntiSpyware"); 351 | helper_disable(helper, "DisableAntiVirus"); 352 | 353 | // Cleanup 354 | delete helper; 355 | 356 | manage_windefend(true); 357 | manage_security_center(true); 358 | 359 | return true; 360 | } 361 | 362 | // Returns true if RealTimeMonitoring is activated 363 | // 364 | bool check_defender(uint32_t flags) 365 | { 366 | // Unreliable method if anti-tamper is enabled. 367 | //return REG::read_key( 368 | // L"SOFTWARE\\Microsoft\\Windows Defender\\Real-Time Protection", 369 | // L"DisableRealtimeMonitoring") == 0; 370 | 371 | auto helper = new wmic::helper( 372 | "Root\\Microsoft\\Windows\\Defender", 373 | "MSFT_MpPreference", 374 | "Set" 375 | ); 376 | 377 | if (auto error = helper->get_last_error()) 378 | { 379 | // Throw error instead 380 | printf("Error has occured: %d\n", error); 381 | delete helper; 382 | return true; 383 | } 384 | 385 | bool result = false; 386 | helper->get("DisableRealtimeMonitoring", wmic::variant_type::t_bool, result); 387 | delete helper; 388 | return (!result); 389 | } 390 | } -------------------------------------------------------------------------------- /src/defender-control/dcontrol.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include "settings.hpp" 5 | #include "reg.hpp" 6 | #include "util.hpp" 7 | #include "wmic.hpp" 8 | 9 | namespace dcontrol 10 | { 11 | // Toggles windows tamper protection 12 | // 13 | void toggle_tamper(bool enable); 14 | 15 | // Disables window defender 16 | // 17 | bool disable_defender(); 18 | 19 | // Enables defender, assumes we have TrustedInstaller permissions 20 | // 21 | bool enable_defender(); 22 | 23 | // Returns true if RealTimeMonitoring is activated 24 | // 25 | bool check_defender(uint32_t flags = 0); 26 | 27 | // Ends the smart screen process 28 | // 29 | void kill_smartscreen(); 30 | 31 | // Stop or run the windefend service 32 | // 33 | bool manage_windefend(bool enable); 34 | 35 | // Stop or run the security center 36 | // 37 | bool manage_security_center(bool enable); 38 | } -------------------------------------------------------------------------------- /src/defender-control/defender-control.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | Win32Proj 24 | {7c2c0aec-7b9d-4104-99fa-1844d609452c} 25 | defendercontrol 26 | 10.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v143 33 | MultiByte 34 | 35 | 36 | Application 37 | false 38 | v143 39 | true 40 | MultiByte 41 | 42 | 43 | Application 44 | true 45 | v143 46 | MultiByte 47 | 48 | 49 | Application 50 | false 51 | v143 52 | true 53 | MultiByte 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 | false 78 | 79 | 80 | true 81 | $(Configuration)\ 82 | 83 | 84 | false 85 | $(Configuration)\ 86 | $(ProjectDir)\imgui;$(ProjectDir)\imgui\backends;$(IncludePath) 87 | 88 | 89 | 90 | Level3 91 | true 92 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 93 | true 94 | 95 | 96 | Console 97 | true 98 | RequireAdministrator 99 | 100 | 101 | 102 | 103 | Level3 104 | true 105 | true 106 | true 107 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 108 | true 109 | 110 | 111 | Console 112 | true 113 | true 114 | true 115 | RequireAdministrator 116 | 117 | 118 | 119 | 120 | Level3 121 | true 122 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 123 | true 124 | 125 | 126 | Console 127 | true 128 | RequireAdministrator 129 | 130 | 131 | 132 | 133 | Level3 134 | true 135 | true 136 | true 137 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 138 | true 139 | stdcpplatest 140 | MultiThreaded 141 | 142 | 143 | Console 144 | true 145 | true 146 | false 147 | RequireAdministrator 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 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | -------------------------------------------------------------------------------- /src/defender-control/defender-control.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {8a88e18b-d3f3-447e-a3b0-9867c153c3c1} 18 | 19 | 20 | {1d1c7c6d-6f90-49ce-a823-f7deee4d955d} 21 | 22 | 23 | {0cabcba0-6285-4ad6-9295-add0563d0d48} 24 | 25 | 26 | {db30358b-f563-460e-92fb-eacafe3a68cb} 27 | 28 | 29 | {3a8b4441-6ad3-4aeb-9259-dd027a433699} 30 | 31 | 32 | {3cb323f8-f95e-4d70-aa68-2389412f42ba} 33 | 34 | 35 | {702c3537-8c29-4a8c-95c8-496fbeb35fb8} 36 | 37 | 38 | {c59c8662-f1bf-4735-b45b-728abbd72075} 39 | 40 | 41 | {9dbce785-afd4-4c89-a5a0-81b38c2390f4} 42 | 43 | 44 | 45 | 46 | Source Files 47 | 48 | 49 | Source Files\defender-control 50 | 51 | 52 | Source Files\wmic 53 | 54 | 55 | Source Files\util 56 | 57 | 58 | Source Files\reg 59 | 60 | 61 | Source Files\trusted 62 | 63 | 64 | Source Files\gui 65 | 66 | 67 | Source Files\gui\dx11 68 | 69 | 70 | Source Files\gui\imgui 71 | 72 | 73 | Source Files\gui\imgui 74 | 75 | 76 | Source Files\gui\imgui 77 | 78 | 79 | Source Files\gui\imgui 80 | 81 | 82 | Source Files\gui\imgui 83 | 84 | 85 | Source Files\gui\imgui\backends 86 | 87 | 88 | Source Files\gui\imgui\backends 89 | 90 | 91 | Source Files\gui\imgui\backends 92 | 93 | 94 | 95 | 96 | Source Files\defender-control 97 | 98 | 99 | Source Files\wmic 100 | 101 | 102 | Source Files\util 103 | 104 | 105 | Source Files\reg 106 | 107 | 108 | Source Files 109 | 110 | 111 | Source Files\trusted 112 | 113 | 114 | Source Files\gui 115 | 116 | 117 | Source Files\gui\dx11 118 | 119 | 120 | Source Files\gui\imgui 121 | 122 | 123 | Source Files\gui\imgui 124 | 125 | 126 | Source Files\gui\imgui 127 | 128 | 129 | Source Files\gui\imgui 130 | 131 | 132 | Source Files\gui\imgui 133 | 134 | 135 | Source Files\gui\imgui 136 | 137 | 138 | Source Files\gui\imgui\backends 139 | 140 | 141 | Source Files\gui\imgui\backends 142 | 143 | 144 | Source Files\gui\imgui\backends 145 | 146 | 147 | -------------------------------------------------------------------------------- /src/defender-control/gui.cpp: -------------------------------------------------------------------------------- 1 | #include "gui.hpp" 2 | 3 | namespace gui 4 | { 5 | LRESULT CALLBACK window_proc(const HWND hwnd, const UINT msg, 6 | const WPARAM wParam, const LPARAM lParam) 7 | { 8 | if (ImGui_ImplWin32_WndProcHandler(hwnd, msg, wParam, lParam)) 9 | return true; 10 | 11 | // TODO: 12 | switch (msg) 13 | { 14 | case WM_SIZE: 15 | return 0; 16 | case WM_SYSCOMMAND: 17 | return 0; 18 | case WM_DESTROY: 19 | PostQuitMessage(0); 20 | return 0; 21 | } 22 | 23 | return DefWindowProcA(hwnd, msg, wParam, lParam); 24 | } 25 | 26 | int main() 27 | { 28 | WNDCLASSEXW wc{ 29 | sizeof(WNDCLASSEXW), CS_CLASSDC, window_proc, 0L, 0L, 30 | GetModuleHandle(0), NULL, NULL, NULL, NULL, L"dx", NULL 31 | }; 32 | 33 | RegisterClassExW(&wc); 34 | 35 | auto hwnd = CreateWindowExW( 36 | 0, wc.lpszClassName, L"dx", WS_OVERLAPPEDWINDOW, 0, 0, 1920, 1080, 0, 0, wc.hInstance, 0 37 | ); 38 | 39 | // TODO: 40 | // 41 | 42 | return EXIT_SUCCESS; 43 | } 44 | 45 | void render() 46 | { 47 | 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/defender-control/gui.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler( 6 | HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); 7 | 8 | namespace gui 9 | { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/defender-control/gui_dx11.cpp: -------------------------------------------------------------------------------- 1 | #include "gui_dx11.hpp" 2 | 3 | // https://github.com/ocornut/imgui/blob/master/examples/example_win32_directx11/main.cpp 4 | 5 | namespace gui::dx11 6 | { 7 | static ID3D11Device* g_device = NULL; 8 | static ID3D11DeviceContext* g_context = NULL; 9 | static IDXGISwapChain* g_swapchain = NULL; 10 | static ID3D11RenderTargetView* g_render_target = NULL; 11 | 12 | bool create_device(HWND hwnd) 13 | { 14 | // create swapchain 15 | DXGI_SWAP_CHAIN_DESC sd; 16 | ZeroMemory(&sd, sizeof(sd)); 17 | sd.BufferCount = 2; 18 | sd.BufferDesc.Width = 0; 19 | sd.BufferDesc.Height = 0; 20 | sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; 21 | sd.BufferDesc.RefreshRate.Numerator = 60; 22 | sd.BufferDesc.RefreshRate.Denominator = 1; 23 | sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; 24 | sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; 25 | sd.OutputWindow = hwnd; 26 | sd.SampleDesc.Count = 1; 27 | sd.SampleDesc.Quality = 0; 28 | sd.Windowed = TRUE; 29 | sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; 30 | 31 | D3D_FEATURE_LEVEL featureLevel; 32 | const D3D_FEATURE_LEVEL featureLevelArray[2] = { 33 | D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_0, 34 | }; 35 | 36 | if (D3D11CreateDeviceAndSwapChain( 37 | NULL, D3D_DRIVER_TYPE_HARDWARE, NULL,0, featureLevelArray, 38 | 2, D3D11_SDK_VERSION, &sd, &g_swapchain, &g_device, &featureLevel, &g_context) != S_OK) 39 | return false; 40 | 41 | // create render target 42 | ID3D11Texture2D* pBackBuffer = nullptr; 43 | g_swapchain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer)); 44 | 45 | if (!pBackBuffer) 46 | return false; 47 | 48 | g_device->CreateRenderTargetView(pBackBuffer, NULL, &g_render_target); 49 | pBackBuffer->Release(); 50 | 51 | return true; 52 | } 53 | 54 | void cleanup() 55 | { 56 | } 57 | 58 | void setup(HWND hwnd) 59 | { 60 | } 61 | 62 | void start() 63 | { 64 | } 65 | 66 | void end() 67 | { 68 | } 69 | 70 | void resize() 71 | { 72 | } 73 | } -------------------------------------------------------------------------------- /src/defender-control/gui_dx11.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #pragma comment (lib, "d3d11.lib") 5 | 6 | #include 7 | #include 8 | 9 | namespace gui::dx11 10 | { 11 | bool create_device(HWND hwnd); 12 | void cleanup(); 13 | void setup(HWND hwnd); 14 | void start(); 15 | void end(); 16 | 17 | // resize here: 18 | 19 | void resize(); 20 | } 21 | -------------------------------------------------------------------------------- /src/defender-control/imgui/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014-2021 Omar Cornut 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/defender-control/imgui/backends/imgui_impl_dx11.cpp: -------------------------------------------------------------------------------- 1 | // dear imgui: Renderer Backend for DirectX11 2 | // This needs to be used along with a Platform Backend (e.g. Win32) 3 | 4 | // Implemented features: 5 | // [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID! 6 | // [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices. 7 | 8 | // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. 9 | // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. 10 | // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. 11 | // Read online: https://github.com/ocornut/imgui/tree/master/docs 12 | 13 | // CHANGELOG 14 | // (minor and older changes stripped away, please see git history for details) 15 | // 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX). 16 | // 2021-05-19: DirectX11: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement) 17 | // 2021-02-18: DirectX11: Change blending equation to preserve alpha in output buffer. 18 | // 2019-08-01: DirectX11: Fixed code querying the Geometry Shader state (would generally error with Debug layer enabled). 19 | // 2019-07-21: DirectX11: Backup, clear and restore Geometry Shader is any is bound when calling ImGui_ImplDX10_RenderDrawData. Clearing Hull/Domain/Compute shaders without backup/restore. 20 | // 2019-05-29: DirectX11: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag. 21 | // 2019-04-30: DirectX11: Added support for special ImDrawCallback_ResetRenderState callback to reset render state. 22 | // 2018-12-03: Misc: Added #pragma comment statement to automatically link with d3dcompiler.lib when using D3DCompile(). 23 | // 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window. 24 | // 2018-08-01: DirectX11: Querying for IDXGIFactory instead of IDXGIFactory1 to increase compatibility. 25 | // 2018-07-13: DirectX11: Fixed unreleased resources in Init and Shutdown functions. 26 | // 2018-06-08: Misc: Extracted imgui_impl_dx11.cpp/.h away from the old combined DX11+Win32 example. 27 | // 2018-06-08: DirectX11: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle. 28 | // 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplDX11_RenderDrawData() in the .h file so you can call it yourself. 29 | // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. 30 | // 2016-05-07: DirectX11: Disabling depth-write. 31 | 32 | #include "imgui.h" 33 | #include "imgui_impl_dx11.h" 34 | 35 | // DirectX 36 | #include 37 | #include 38 | #include 39 | #ifdef _MSC_VER 40 | #pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below. 41 | #endif 42 | 43 | // DirectX11 data 44 | struct ImGui_ImplDX11_Data 45 | { 46 | ID3D11Device* pd3dDevice; 47 | ID3D11DeviceContext* pd3dDeviceContext; 48 | IDXGIFactory* pFactory; 49 | ID3D11Buffer* pVB; 50 | ID3D11Buffer* pIB; 51 | ID3D11VertexShader* pVertexShader; 52 | ID3D11InputLayout* pInputLayout; 53 | ID3D11Buffer* pVertexConstantBuffer; 54 | ID3D11PixelShader* pPixelShader; 55 | ID3D11SamplerState* pFontSampler; 56 | ID3D11ShaderResourceView* pFontTextureView; 57 | ID3D11RasterizerState* pRasterizerState; 58 | ID3D11BlendState* pBlendState; 59 | ID3D11DepthStencilState* pDepthStencilState; 60 | int VertexBufferSize; 61 | int IndexBufferSize; 62 | 63 | ImGui_ImplDX11_Data() { memset(this, 0, sizeof(*this)); VertexBufferSize = 5000; IndexBufferSize = 10000; } 64 | }; 65 | 66 | struct VERTEX_CONSTANT_BUFFER 67 | { 68 | float mvp[4][4]; 69 | }; 70 | 71 | // Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts 72 | // It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts. 73 | static ImGui_ImplDX11_Data* ImGui_ImplDX11_GetBackendData() 74 | { 75 | return ImGui::GetCurrentContext() ? (ImGui_ImplDX11_Data*)ImGui::GetIO().BackendRendererUserData : NULL; 76 | } 77 | 78 | // Functions 79 | static void ImGui_ImplDX11_SetupRenderState(ImDrawData* draw_data, ID3D11DeviceContext* ctx) 80 | { 81 | ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData(); 82 | 83 | // Setup viewport 84 | D3D11_VIEWPORT vp; 85 | memset(&vp, 0, sizeof(D3D11_VIEWPORT)); 86 | vp.Width = draw_data->DisplaySize.x; 87 | vp.Height = draw_data->DisplaySize.y; 88 | vp.MinDepth = 0.0f; 89 | vp.MaxDepth = 1.0f; 90 | vp.TopLeftX = vp.TopLeftY = 0; 91 | ctx->RSSetViewports(1, &vp); 92 | 93 | // Setup shader and vertex buffers 94 | unsigned int stride = sizeof(ImDrawVert); 95 | unsigned int offset = 0; 96 | ctx->IASetInputLayout(bd->pInputLayout); 97 | ctx->IASetVertexBuffers(0, 1, &bd->pVB, &stride, &offset); 98 | ctx->IASetIndexBuffer(bd->pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0); 99 | ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); 100 | ctx->VSSetShader(bd->pVertexShader, NULL, 0); 101 | ctx->VSSetConstantBuffers(0, 1, &bd->pVertexConstantBuffer); 102 | ctx->PSSetShader(bd->pPixelShader, NULL, 0); 103 | ctx->PSSetSamplers(0, 1, &bd->pFontSampler); 104 | ctx->GSSetShader(NULL, NULL, 0); 105 | ctx->HSSetShader(NULL, NULL, 0); // In theory we should backup and restore this as well.. very infrequently used.. 106 | ctx->DSSetShader(NULL, NULL, 0); // In theory we should backup and restore this as well.. very infrequently used.. 107 | ctx->CSSetShader(NULL, NULL, 0); // In theory we should backup and restore this as well.. very infrequently used.. 108 | 109 | // Setup blend state 110 | const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f }; 111 | ctx->OMSetBlendState(bd->pBlendState, blend_factor, 0xffffffff); 112 | ctx->OMSetDepthStencilState(bd->pDepthStencilState, 0); 113 | ctx->RSSetState(bd->pRasterizerState); 114 | } 115 | 116 | // Render function 117 | void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data) 118 | { 119 | // Avoid rendering when minimized 120 | if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f) 121 | return; 122 | 123 | ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData(); 124 | ID3D11DeviceContext* ctx = bd->pd3dDeviceContext; 125 | 126 | // Create and grow vertex/index buffers if needed 127 | if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount) 128 | { 129 | if (bd->pVB) { bd->pVB->Release(); bd->pVB = NULL; } 130 | bd->VertexBufferSize = draw_data->TotalVtxCount + 5000; 131 | D3D11_BUFFER_DESC desc; 132 | memset(&desc, 0, sizeof(D3D11_BUFFER_DESC)); 133 | desc.Usage = D3D11_USAGE_DYNAMIC; 134 | desc.ByteWidth = bd->VertexBufferSize * sizeof(ImDrawVert); 135 | desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; 136 | desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; 137 | desc.MiscFlags = 0; 138 | if (bd->pd3dDevice->CreateBuffer(&desc, NULL, &bd->pVB) < 0) 139 | return; 140 | } 141 | if (!bd->pIB || bd->IndexBufferSize < draw_data->TotalIdxCount) 142 | { 143 | if (bd->pIB) { bd->pIB->Release(); bd->pIB = NULL; } 144 | bd->IndexBufferSize = draw_data->TotalIdxCount + 10000; 145 | D3D11_BUFFER_DESC desc; 146 | memset(&desc, 0, sizeof(D3D11_BUFFER_DESC)); 147 | desc.Usage = D3D11_USAGE_DYNAMIC; 148 | desc.ByteWidth = bd->IndexBufferSize * sizeof(ImDrawIdx); 149 | desc.BindFlags = D3D11_BIND_INDEX_BUFFER; 150 | desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; 151 | if (bd->pd3dDevice->CreateBuffer(&desc, NULL, &bd->pIB) < 0) 152 | return; 153 | } 154 | 155 | // Upload vertex/index data into a single contiguous GPU buffer 156 | D3D11_MAPPED_SUBRESOURCE vtx_resource, idx_resource; 157 | if (ctx->Map(bd->pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vtx_resource) != S_OK) 158 | return; 159 | if (ctx->Map(bd->pIB, 0, D3D11_MAP_WRITE_DISCARD, 0, &idx_resource) != S_OK) 160 | return; 161 | ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource.pData; 162 | ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource.pData; 163 | for (int n = 0; n < draw_data->CmdListsCount; n++) 164 | { 165 | const ImDrawList* cmd_list = draw_data->CmdLists[n]; 166 | memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert)); 167 | memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx)); 168 | vtx_dst += cmd_list->VtxBuffer.Size; 169 | idx_dst += cmd_list->IdxBuffer.Size; 170 | } 171 | ctx->Unmap(bd->pVB, 0); 172 | ctx->Unmap(bd->pIB, 0); 173 | 174 | // Setup orthographic projection matrix into our constant buffer 175 | // Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps. 176 | { 177 | D3D11_MAPPED_SUBRESOURCE mapped_resource; 178 | if (ctx->Map(bd->pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK) 179 | return; 180 | VERTEX_CONSTANT_BUFFER* constant_buffer = (VERTEX_CONSTANT_BUFFER*)mapped_resource.pData; 181 | float L = draw_data->DisplayPos.x; 182 | float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x; 183 | float T = draw_data->DisplayPos.y; 184 | float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y; 185 | float mvp[4][4] = 186 | { 187 | { 2.0f/(R-L), 0.0f, 0.0f, 0.0f }, 188 | { 0.0f, 2.0f/(T-B), 0.0f, 0.0f }, 189 | { 0.0f, 0.0f, 0.5f, 0.0f }, 190 | { (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f }, 191 | }; 192 | memcpy(&constant_buffer->mvp, mvp, sizeof(mvp)); 193 | ctx->Unmap(bd->pVertexConstantBuffer, 0); 194 | } 195 | 196 | // Backup DX state that will be modified to restore it afterwards (unfortunately this is very ugly looking and verbose. Close your eyes!) 197 | struct BACKUP_DX11_STATE 198 | { 199 | UINT ScissorRectsCount, ViewportsCount; 200 | D3D11_RECT ScissorRects[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; 201 | D3D11_VIEWPORT Viewports[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; 202 | ID3D11RasterizerState* RS; 203 | ID3D11BlendState* BlendState; 204 | FLOAT BlendFactor[4]; 205 | UINT SampleMask; 206 | UINT StencilRef; 207 | ID3D11DepthStencilState* DepthStencilState; 208 | ID3D11ShaderResourceView* PSShaderResource; 209 | ID3D11SamplerState* PSSampler; 210 | ID3D11PixelShader* PS; 211 | ID3D11VertexShader* VS; 212 | ID3D11GeometryShader* GS; 213 | UINT PSInstancesCount, VSInstancesCount, GSInstancesCount; 214 | ID3D11ClassInstance *PSInstances[256], *VSInstances[256], *GSInstances[256]; // 256 is max according to PSSetShader documentation 215 | D3D11_PRIMITIVE_TOPOLOGY PrimitiveTopology; 216 | ID3D11Buffer* IndexBuffer, *VertexBuffer, *VSConstantBuffer; 217 | UINT IndexBufferOffset, VertexBufferStride, VertexBufferOffset; 218 | DXGI_FORMAT IndexBufferFormat; 219 | ID3D11InputLayout* InputLayout; 220 | }; 221 | BACKUP_DX11_STATE old = {}; 222 | old.ScissorRectsCount = old.ViewportsCount = D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; 223 | ctx->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects); 224 | ctx->RSGetViewports(&old.ViewportsCount, old.Viewports); 225 | ctx->RSGetState(&old.RS); 226 | ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask); 227 | ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef); 228 | ctx->PSGetShaderResources(0, 1, &old.PSShaderResource); 229 | ctx->PSGetSamplers(0, 1, &old.PSSampler); 230 | old.PSInstancesCount = old.VSInstancesCount = old.GSInstancesCount = 256; 231 | ctx->PSGetShader(&old.PS, old.PSInstances, &old.PSInstancesCount); 232 | ctx->VSGetShader(&old.VS, old.VSInstances, &old.VSInstancesCount); 233 | ctx->VSGetConstantBuffers(0, 1, &old.VSConstantBuffer); 234 | ctx->GSGetShader(&old.GS, old.GSInstances, &old.GSInstancesCount); 235 | 236 | ctx->IAGetPrimitiveTopology(&old.PrimitiveTopology); 237 | ctx->IAGetIndexBuffer(&old.IndexBuffer, &old.IndexBufferFormat, &old.IndexBufferOffset); 238 | ctx->IAGetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); 239 | ctx->IAGetInputLayout(&old.InputLayout); 240 | 241 | // Setup desired DX state 242 | ImGui_ImplDX11_SetupRenderState(draw_data, ctx); 243 | 244 | // Render command lists 245 | // (Because we merged all buffers into a single one, we maintain our own offset into them) 246 | int global_idx_offset = 0; 247 | int global_vtx_offset = 0; 248 | ImVec2 clip_off = draw_data->DisplayPos; 249 | for (int n = 0; n < draw_data->CmdListsCount; n++) 250 | { 251 | const ImDrawList* cmd_list = draw_data->CmdLists[n]; 252 | for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) 253 | { 254 | const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; 255 | if (pcmd->UserCallback != NULL) 256 | { 257 | // User callback, registered via ImDrawList::AddCallback() 258 | // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.) 259 | if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) 260 | ImGui_ImplDX11_SetupRenderState(draw_data, ctx); 261 | else 262 | pcmd->UserCallback(cmd_list, pcmd); 263 | } 264 | else 265 | { 266 | // Apply scissor/clipping rectangle 267 | const D3D11_RECT r = { (LONG)(pcmd->ClipRect.x - clip_off.x), (LONG)(pcmd->ClipRect.y - clip_off.y), (LONG)(pcmd->ClipRect.z - clip_off.x), (LONG)(pcmd->ClipRect.w - clip_off.y) }; 268 | ctx->RSSetScissorRects(1, &r); 269 | 270 | // Bind texture, Draw 271 | ID3D11ShaderResourceView* texture_srv = (ID3D11ShaderResourceView*)pcmd->GetTexID(); 272 | ctx->PSSetShaderResources(0, 1, &texture_srv); 273 | ctx->DrawIndexed(pcmd->ElemCount, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset); 274 | } 275 | } 276 | global_idx_offset += cmd_list->IdxBuffer.Size; 277 | global_vtx_offset += cmd_list->VtxBuffer.Size; 278 | } 279 | 280 | // Restore modified DX state 281 | ctx->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects); 282 | ctx->RSSetViewports(old.ViewportsCount, old.Viewports); 283 | ctx->RSSetState(old.RS); if (old.RS) old.RS->Release(); 284 | ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release(); 285 | ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release(); 286 | ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release(); 287 | ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release(); 288 | ctx->PSSetShader(old.PS, old.PSInstances, old.PSInstancesCount); if (old.PS) old.PS->Release(); 289 | for (UINT i = 0; i < old.PSInstancesCount; i++) if (old.PSInstances[i]) old.PSInstances[i]->Release(); 290 | ctx->VSSetShader(old.VS, old.VSInstances, old.VSInstancesCount); if (old.VS) old.VS->Release(); 291 | ctx->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); if (old.VSConstantBuffer) old.VSConstantBuffer->Release(); 292 | ctx->GSSetShader(old.GS, old.GSInstances, old.GSInstancesCount); if (old.GS) old.GS->Release(); 293 | for (UINT i = 0; i < old.VSInstancesCount; i++) if (old.VSInstances[i]) old.VSInstances[i]->Release(); 294 | ctx->IASetPrimitiveTopology(old.PrimitiveTopology); 295 | ctx->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); if (old.IndexBuffer) old.IndexBuffer->Release(); 296 | ctx->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); if (old.VertexBuffer) old.VertexBuffer->Release(); 297 | ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release(); 298 | } 299 | 300 | static void ImGui_ImplDX11_CreateFontsTexture() 301 | { 302 | // Build texture atlas 303 | ImGuiIO& io = ImGui::GetIO(); 304 | ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData(); 305 | unsigned char* pixels; 306 | int width, height; 307 | io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); 308 | 309 | // Upload texture to graphics system 310 | { 311 | D3D11_TEXTURE2D_DESC desc; 312 | ZeroMemory(&desc, sizeof(desc)); 313 | desc.Width = width; 314 | desc.Height = height; 315 | desc.MipLevels = 1; 316 | desc.ArraySize = 1; 317 | desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; 318 | desc.SampleDesc.Count = 1; 319 | desc.Usage = D3D11_USAGE_DEFAULT; 320 | desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; 321 | desc.CPUAccessFlags = 0; 322 | 323 | ID3D11Texture2D* pTexture = NULL; 324 | D3D11_SUBRESOURCE_DATA subResource; 325 | subResource.pSysMem = pixels; 326 | subResource.SysMemPitch = desc.Width * 4; 327 | subResource.SysMemSlicePitch = 0; 328 | bd->pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture); 329 | IM_ASSERT(pTexture != NULL); 330 | 331 | // Create texture view 332 | D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; 333 | ZeroMemory(&srvDesc, sizeof(srvDesc)); 334 | srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; 335 | srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; 336 | srvDesc.Texture2D.MipLevels = desc.MipLevels; 337 | srvDesc.Texture2D.MostDetailedMip = 0; 338 | bd->pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, &bd->pFontTextureView); 339 | pTexture->Release(); 340 | } 341 | 342 | // Store our identifier 343 | io.Fonts->SetTexID((ImTextureID)bd->pFontTextureView); 344 | 345 | // Create texture sampler 346 | { 347 | D3D11_SAMPLER_DESC desc; 348 | ZeroMemory(&desc, sizeof(desc)); 349 | desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; 350 | desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; 351 | desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; 352 | desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; 353 | desc.MipLODBias = 0.f; 354 | desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS; 355 | desc.MinLOD = 0.f; 356 | desc.MaxLOD = 0.f; 357 | bd->pd3dDevice->CreateSamplerState(&desc, &bd->pFontSampler); 358 | } 359 | } 360 | 361 | bool ImGui_ImplDX11_CreateDeviceObjects() 362 | { 363 | ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData(); 364 | if (!bd->pd3dDevice) 365 | return false; 366 | if (bd->pFontSampler) 367 | ImGui_ImplDX11_InvalidateDeviceObjects(); 368 | 369 | // By using D3DCompile() from / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A) 370 | // If you would like to use this DX11 sample code but remove this dependency you can: 371 | // 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [preferred solution] 372 | // 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL. 373 | // See https://github.com/ocornut/imgui/pull/638 for sources and details. 374 | 375 | // Create the vertex shader 376 | { 377 | static const char* vertexShader = 378 | "cbuffer vertexBuffer : register(b0) \ 379 | {\ 380 | float4x4 ProjectionMatrix; \ 381 | };\ 382 | struct VS_INPUT\ 383 | {\ 384 | float2 pos : POSITION;\ 385 | float4 col : COLOR0;\ 386 | float2 uv : TEXCOORD0;\ 387 | };\ 388 | \ 389 | struct PS_INPUT\ 390 | {\ 391 | float4 pos : SV_POSITION;\ 392 | float4 col : COLOR0;\ 393 | float2 uv : TEXCOORD0;\ 394 | };\ 395 | \ 396 | PS_INPUT main(VS_INPUT input)\ 397 | {\ 398 | PS_INPUT output;\ 399 | output.pos = mul( ProjectionMatrix, float4(input.pos.xy, 0.f, 1.f));\ 400 | output.col = input.col;\ 401 | output.uv = input.uv;\ 402 | return output;\ 403 | }"; 404 | 405 | ID3DBlob* vertexShaderBlob; 406 | if (FAILED(D3DCompile(vertexShader, strlen(vertexShader), NULL, NULL, NULL, "main", "vs_4_0", 0, 0, &vertexShaderBlob, NULL))) 407 | return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob! 408 | if (bd->pd3dDevice->CreateVertexShader(vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), NULL, &bd->pVertexShader) != S_OK) 409 | { 410 | vertexShaderBlob->Release(); 411 | return false; 412 | } 413 | 414 | // Create the input layout 415 | D3D11_INPUT_ELEMENT_DESC local_layout[] = 416 | { 417 | { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, pos), D3D11_INPUT_PER_VERTEX_DATA, 0 }, 418 | { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, uv), D3D11_INPUT_PER_VERTEX_DATA, 0 }, 419 | { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)IM_OFFSETOF(ImDrawVert, col), D3D11_INPUT_PER_VERTEX_DATA, 0 }, 420 | }; 421 | if (bd->pd3dDevice->CreateInputLayout(local_layout, 3, vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), &bd->pInputLayout) != S_OK) 422 | { 423 | vertexShaderBlob->Release(); 424 | return false; 425 | } 426 | vertexShaderBlob->Release(); 427 | 428 | // Create the constant buffer 429 | { 430 | D3D11_BUFFER_DESC desc; 431 | desc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER); 432 | desc.Usage = D3D11_USAGE_DYNAMIC; 433 | desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; 434 | desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; 435 | desc.MiscFlags = 0; 436 | bd->pd3dDevice->CreateBuffer(&desc, NULL, &bd->pVertexConstantBuffer); 437 | } 438 | } 439 | 440 | // Create the pixel shader 441 | { 442 | static const char* pixelShader = 443 | "struct PS_INPUT\ 444 | {\ 445 | float4 pos : SV_POSITION;\ 446 | float4 col : COLOR0;\ 447 | float2 uv : TEXCOORD0;\ 448 | };\ 449 | sampler sampler0;\ 450 | Texture2D texture0;\ 451 | \ 452 | float4 main(PS_INPUT input) : SV_Target\ 453 | {\ 454 | float4 out_col = input.col * texture0.Sample(sampler0, input.uv); \ 455 | return out_col; \ 456 | }"; 457 | 458 | ID3DBlob* pixelShaderBlob; 459 | if (FAILED(D3DCompile(pixelShader, strlen(pixelShader), NULL, NULL, NULL, "main", "ps_4_0", 0, 0, &pixelShaderBlob, NULL))) 460 | return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob! 461 | if (bd->pd3dDevice->CreatePixelShader(pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize(), NULL, &bd->pPixelShader) != S_OK) 462 | { 463 | pixelShaderBlob->Release(); 464 | return false; 465 | } 466 | pixelShaderBlob->Release(); 467 | } 468 | 469 | // Create the blending setup 470 | { 471 | D3D11_BLEND_DESC desc; 472 | ZeroMemory(&desc, sizeof(desc)); 473 | desc.AlphaToCoverageEnable = false; 474 | desc.RenderTarget[0].BlendEnable = true; 475 | desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; 476 | desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; 477 | desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; 478 | desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; 479 | desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; 480 | desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; 481 | desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; 482 | bd->pd3dDevice->CreateBlendState(&desc, &bd->pBlendState); 483 | } 484 | 485 | // Create the rasterizer state 486 | { 487 | D3D11_RASTERIZER_DESC desc; 488 | ZeroMemory(&desc, sizeof(desc)); 489 | desc.FillMode = D3D11_FILL_SOLID; 490 | desc.CullMode = D3D11_CULL_NONE; 491 | desc.ScissorEnable = true; 492 | desc.DepthClipEnable = true; 493 | bd->pd3dDevice->CreateRasterizerState(&desc, &bd->pRasterizerState); 494 | } 495 | 496 | // Create depth-stencil State 497 | { 498 | D3D11_DEPTH_STENCIL_DESC desc; 499 | ZeroMemory(&desc, sizeof(desc)); 500 | desc.DepthEnable = false; 501 | desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; 502 | desc.DepthFunc = D3D11_COMPARISON_ALWAYS; 503 | desc.StencilEnable = false; 504 | desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; 505 | desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; 506 | desc.BackFace = desc.FrontFace; 507 | bd->pd3dDevice->CreateDepthStencilState(&desc, &bd->pDepthStencilState); 508 | } 509 | 510 | ImGui_ImplDX11_CreateFontsTexture(); 511 | 512 | return true; 513 | } 514 | 515 | void ImGui_ImplDX11_InvalidateDeviceObjects() 516 | { 517 | ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData(); 518 | if (!bd->pd3dDevice) 519 | return; 520 | 521 | if (bd->pFontSampler) { bd->pFontSampler->Release(); bd->pFontSampler = NULL; } 522 | if (bd->pFontTextureView) { bd->pFontTextureView->Release(); bd->pFontTextureView = NULL; ImGui::GetIO().Fonts->SetTexID(NULL); } // We copied data->pFontTextureView to io.Fonts->TexID so let's clear that as well. 523 | if (bd->pIB) { bd->pIB->Release(); bd->pIB = NULL; } 524 | if (bd->pVB) { bd->pVB->Release(); bd->pVB = NULL; } 525 | if (bd->pBlendState) { bd->pBlendState->Release(); bd->pBlendState = NULL; } 526 | if (bd->pDepthStencilState) { bd->pDepthStencilState->Release(); bd->pDepthStencilState = NULL; } 527 | if (bd->pRasterizerState) { bd->pRasterizerState->Release(); bd->pRasterizerState = NULL; } 528 | if (bd->pPixelShader) { bd->pPixelShader->Release(); bd->pPixelShader = NULL; } 529 | if (bd->pVertexConstantBuffer) { bd->pVertexConstantBuffer->Release(); bd->pVertexConstantBuffer = NULL; } 530 | if (bd->pInputLayout) { bd->pInputLayout->Release(); bd->pInputLayout = NULL; } 531 | if (bd->pVertexShader) { bd->pVertexShader->Release(); bd->pVertexShader = NULL; } 532 | } 533 | 534 | bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context) 535 | { 536 | ImGuiIO& io = ImGui::GetIO(); 537 | IM_ASSERT(io.BackendRendererUserData == NULL && "Already initialized a renderer backend!"); 538 | 539 | // Setup backend capabilities flags 540 | ImGui_ImplDX11_Data* bd = IM_NEW(ImGui_ImplDX11_Data)(); 541 | io.BackendRendererUserData = (void*)bd; 542 | io.BackendRendererName = "imgui_impl_dx11"; 543 | io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. 544 | 545 | // Get factory from device 546 | IDXGIDevice* pDXGIDevice = NULL; 547 | IDXGIAdapter* pDXGIAdapter = NULL; 548 | IDXGIFactory* pFactory = NULL; 549 | 550 | if (device->QueryInterface(IID_PPV_ARGS(&pDXGIDevice)) == S_OK) 551 | if (pDXGIDevice->GetParent(IID_PPV_ARGS(&pDXGIAdapter)) == S_OK) 552 | if (pDXGIAdapter->GetParent(IID_PPV_ARGS(&pFactory)) == S_OK) 553 | { 554 | bd->pd3dDevice = device; 555 | bd->pd3dDeviceContext = device_context; 556 | bd->pFactory = pFactory; 557 | } 558 | if (pDXGIDevice) pDXGIDevice->Release(); 559 | if (pDXGIAdapter) pDXGIAdapter->Release(); 560 | bd->pd3dDevice->AddRef(); 561 | bd->pd3dDeviceContext->AddRef(); 562 | 563 | return true; 564 | } 565 | 566 | void ImGui_ImplDX11_Shutdown() 567 | { 568 | ImGuiIO& io = ImGui::GetIO(); 569 | ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData(); 570 | 571 | ImGui_ImplDX11_InvalidateDeviceObjects(); 572 | if (bd->pFactory) { bd->pFactory->Release(); } 573 | if (bd->pd3dDevice) { bd->pd3dDevice->Release(); } 574 | if (bd->pd3dDeviceContext) { bd->pd3dDeviceContext->Release(); } 575 | io.BackendRendererName = NULL; 576 | io.BackendRendererUserData = NULL; 577 | IM_DELETE(bd); 578 | } 579 | 580 | void ImGui_ImplDX11_NewFrame() 581 | { 582 | ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData(); 583 | IM_ASSERT(bd != NULL && "Did you call ImGui_ImplDX11_Init()?"); 584 | 585 | if (!bd->pFontSampler) 586 | ImGui_ImplDX11_CreateDeviceObjects(); 587 | } 588 | -------------------------------------------------------------------------------- /src/defender-control/imgui/backends/imgui_impl_dx11.h: -------------------------------------------------------------------------------- 1 | // dear imgui: Renderer Backend for DirectX11 2 | // This needs to be used along with a Platform Backend (e.g. Win32) 3 | 4 | // Implemented features: 5 | // [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID! 6 | // [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices. 7 | 8 | // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. 9 | // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. 10 | // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. 11 | // Read online: https://github.com/ocornut/imgui/tree/master/docs 12 | 13 | #pragma once 14 | #include "imgui.h" // IMGUI_IMPL_API 15 | 16 | struct ID3D11Device; 17 | struct ID3D11DeviceContext; 18 | 19 | IMGUI_IMPL_API bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context); 20 | IMGUI_IMPL_API void ImGui_ImplDX11_Shutdown(); 21 | IMGUI_IMPL_API void ImGui_ImplDX11_NewFrame(); 22 | IMGUI_IMPL_API void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data); 23 | 24 | // Use if you want to reset your rendering device without losing Dear ImGui state. 25 | IMGUI_IMPL_API void ImGui_ImplDX11_InvalidateDeviceObjects(); 26 | IMGUI_IMPL_API bool ImGui_ImplDX11_CreateDeviceObjects(); 27 | -------------------------------------------------------------------------------- /src/defender-control/imgui/backends/imgui_impl_dx9.cpp: -------------------------------------------------------------------------------- 1 | // dear imgui: Renderer Backend for DirectX9 2 | // This needs to be used along with a Platform Backend (e.g. Win32) 3 | 4 | // Implemented features: 5 | // [X] Renderer: User texture binding. Use 'LPDIRECT3DTEXTURE9' as ImTextureID. Read the FAQ about ImTextureID! 6 | // [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices. 7 | 8 | // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. 9 | // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. 10 | // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. 11 | // Read online: https://github.com/ocornut/imgui/tree/master/docs 12 | 13 | // CHANGELOG 14 | // (minor and older changes stripped away, please see git history for details) 15 | // 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX). 16 | // 2021-06-25: DirectX9: Explicitly disable texture state stages after >= 1. 17 | // 2021-05-19: DirectX9: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement) 18 | // 2021-04-23: DirectX9: Explicitly setting up more graphics states to increase compatibility with unusual non-default states. 19 | // 2021-03-18: DirectX9: Calling IDirect3DStateBlock9::Capture() after CreateStateBlock() as a workaround for state restoring issues (see #3857). 20 | // 2021-03-03: DirectX9: Added support for IMGUI_USE_BGRA_PACKED_COLOR in user's imconfig file. 21 | // 2021-02-18: DirectX9: Change blending equation to preserve alpha in output buffer. 22 | // 2019-05-29: DirectX9: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag. 23 | // 2019-04-30: DirectX9: Added support for special ImDrawCallback_ResetRenderState callback to reset render state. 24 | // 2019-03-29: Misc: Fixed erroneous assert in ImGui_ImplDX9_InvalidateDeviceObjects(). 25 | // 2019-01-16: Misc: Disabled fog before drawing UI's. Fixes issue #2288. 26 | // 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window. 27 | // 2018-06-08: Misc: Extracted imgui_impl_dx9.cpp/.h away from the old combined DX9+Win32 example. 28 | // 2018-06-08: DirectX9: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle. 29 | // 2018-05-07: Render: Saving/restoring Transform because they don't seem to be included in the StateBlock. Setting shading mode to Gouraud. 30 | // 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplDX9_RenderDrawData() in the .h file so you can call it yourself. 31 | // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. 32 | 33 | #include "imgui.h" 34 | #include "imgui_impl_dx9.h" 35 | 36 | // DirectX 37 | #include 38 | 39 | // DirectX data 40 | struct ImGui_ImplDX9_Data 41 | { 42 | LPDIRECT3DDEVICE9 pd3dDevice; 43 | LPDIRECT3DVERTEXBUFFER9 pVB; 44 | LPDIRECT3DINDEXBUFFER9 pIB; 45 | LPDIRECT3DTEXTURE9 FontTexture; 46 | int VertexBufferSize; 47 | int IndexBufferSize; 48 | 49 | ImGui_ImplDX9_Data() { memset(this, 0, sizeof(*this)); VertexBufferSize = 5000; IndexBufferSize = 10000; } 50 | }; 51 | 52 | struct CUSTOMVERTEX 53 | { 54 | float pos[3]; 55 | D3DCOLOR col; 56 | float uv[2]; 57 | }; 58 | #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1) 59 | 60 | #ifdef IMGUI_USE_BGRA_PACKED_COLOR 61 | #define IMGUI_COL_TO_DX9_ARGB(_COL) (_COL) 62 | #else 63 | #define IMGUI_COL_TO_DX9_ARGB(_COL) (((_COL) & 0xFF00FF00) | (((_COL) & 0xFF0000) >> 16) | (((_COL) & 0xFF) << 16)) 64 | #endif 65 | 66 | // Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts 67 | // It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts. 68 | static ImGui_ImplDX9_Data* ImGui_ImplDX9_GetBackendData() 69 | { 70 | return ImGui::GetCurrentContext() ? (ImGui_ImplDX9_Data*)ImGui::GetIO().BackendRendererUserData : NULL; 71 | } 72 | 73 | // Functions 74 | static void ImGui_ImplDX9_SetupRenderState(ImDrawData* draw_data) 75 | { 76 | ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData(); 77 | 78 | // Setup viewport 79 | D3DVIEWPORT9 vp; 80 | vp.X = vp.Y = 0; 81 | vp.Width = (DWORD)draw_data->DisplaySize.x; 82 | vp.Height = (DWORD)draw_data->DisplaySize.y; 83 | vp.MinZ = 0.0f; 84 | vp.MaxZ = 1.0f; 85 | bd->pd3dDevice->SetViewport(&vp); 86 | 87 | // Setup render state: fixed-pipeline, alpha-blending, no face culling, no depth testing, shade mode (for gradient) 88 | bd->pd3dDevice->SetPixelShader(NULL); 89 | bd->pd3dDevice->SetVertexShader(NULL); 90 | bd->pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); 91 | bd->pd3dDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD); 92 | bd->pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); 93 | bd->pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); 94 | bd->pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); 95 | bd->pd3dDevice->SetRenderState(D3DRS_ZENABLE, FALSE); 96 | bd->pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); 97 | bd->pd3dDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); 98 | bd->pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); 99 | bd->pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); 100 | bd->pd3dDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE); 101 | bd->pd3dDevice->SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_ONE); 102 | bd->pd3dDevice->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_INVSRCALPHA); 103 | bd->pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE); 104 | bd->pd3dDevice->SetRenderState(D3DRS_FOGENABLE, FALSE); 105 | bd->pd3dDevice->SetRenderState(D3DRS_RANGEFOGENABLE, FALSE); 106 | bd->pd3dDevice->SetRenderState(D3DRS_SPECULARENABLE, FALSE); 107 | bd->pd3dDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); 108 | bd->pd3dDevice->SetRenderState(D3DRS_CLIPPING, TRUE); 109 | bd->pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE); 110 | bd->pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); 111 | bd->pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); 112 | bd->pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); 113 | bd->pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); 114 | bd->pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); 115 | bd->pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); 116 | bd->pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); 117 | bd->pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); 118 | bd->pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); 119 | bd->pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); 120 | 121 | // Setup orthographic projection matrix 122 | // Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps. 123 | // Being agnostic of whether or can be used, we aren't relying on D3DXMatrixIdentity()/D3DXMatrixOrthoOffCenterLH() or DirectX::XMMatrixIdentity()/DirectX::XMMatrixOrthographicOffCenterLH() 124 | { 125 | float L = draw_data->DisplayPos.x + 0.5f; 126 | float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x + 0.5f; 127 | float T = draw_data->DisplayPos.y + 0.5f; 128 | float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y + 0.5f; 129 | D3DMATRIX mat_identity = { { { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f } } }; 130 | D3DMATRIX mat_projection = 131 | { { { 132 | 2.0f/(R-L), 0.0f, 0.0f, 0.0f, 133 | 0.0f, 2.0f/(T-B), 0.0f, 0.0f, 134 | 0.0f, 0.0f, 0.5f, 0.0f, 135 | (L+R)/(L-R), (T+B)/(B-T), 0.5f, 1.0f 136 | } } }; 137 | bd->pd3dDevice->SetTransform(D3DTS_WORLD, &mat_identity); 138 | bd->pd3dDevice->SetTransform(D3DTS_VIEW, &mat_identity); 139 | bd->pd3dDevice->SetTransform(D3DTS_PROJECTION, &mat_projection); 140 | } 141 | } 142 | 143 | // Render function. 144 | void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data) 145 | { 146 | // Avoid rendering when minimized 147 | if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f) 148 | return; 149 | 150 | // Create and grow buffers if needed 151 | ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData(); 152 | if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount) 153 | { 154 | if (bd->pVB) { bd->pVB->Release(); bd->pVB = NULL; } 155 | bd->VertexBufferSize = draw_data->TotalVtxCount + 5000; 156 | if (bd->pd3dDevice->CreateVertexBuffer(bd->VertexBufferSize * sizeof(CUSTOMVERTEX), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &bd->pVB, NULL) < 0) 157 | return; 158 | } 159 | if (!bd->pIB || bd->IndexBufferSize < draw_data->TotalIdxCount) 160 | { 161 | if (bd->pIB) { bd->pIB->Release(); bd->pIB = NULL; } 162 | bd->IndexBufferSize = draw_data->TotalIdxCount + 10000; 163 | if (bd->pd3dDevice->CreateIndexBuffer(bd->IndexBufferSize * sizeof(ImDrawIdx), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, sizeof(ImDrawIdx) == 2 ? D3DFMT_INDEX16 : D3DFMT_INDEX32, D3DPOOL_DEFAULT, &bd->pIB, NULL) < 0) 164 | return; 165 | } 166 | 167 | // Backup the DX9 state 168 | IDirect3DStateBlock9* d3d9_state_block = NULL; 169 | if (bd->pd3dDevice->CreateStateBlock(D3DSBT_ALL, &d3d9_state_block) < 0) 170 | return; 171 | if (d3d9_state_block->Capture() < 0) 172 | { 173 | d3d9_state_block->Release(); 174 | return; 175 | } 176 | 177 | // Backup the DX9 transform (DX9 documentation suggests that it is included in the StateBlock but it doesn't appear to) 178 | D3DMATRIX last_world, last_view, last_projection; 179 | bd->pd3dDevice->GetTransform(D3DTS_WORLD, &last_world); 180 | bd->pd3dDevice->GetTransform(D3DTS_VIEW, &last_view); 181 | bd->pd3dDevice->GetTransform(D3DTS_PROJECTION, &last_projection); 182 | 183 | // Allocate buffers 184 | CUSTOMVERTEX* vtx_dst; 185 | ImDrawIdx* idx_dst; 186 | if (bd->pVB->Lock(0, (UINT)(draw_data->TotalVtxCount * sizeof(CUSTOMVERTEX)), (void**)&vtx_dst, D3DLOCK_DISCARD) < 0) 187 | { 188 | d3d9_state_block->Release(); 189 | return; 190 | } 191 | if (bd->pIB->Lock(0, (UINT)(draw_data->TotalIdxCount * sizeof(ImDrawIdx)), (void**)&idx_dst, D3DLOCK_DISCARD) < 0) 192 | { 193 | bd->pVB->Unlock(); 194 | d3d9_state_block->Release(); 195 | return; 196 | } 197 | 198 | // Copy and convert all vertices into a single contiguous buffer, convert colors to DX9 default format. 199 | // FIXME-OPT: This is a minor waste of resource, the ideal is to use imconfig.h and 200 | // 1) to avoid repacking colors: #define IMGUI_USE_BGRA_PACKED_COLOR 201 | // 2) to avoid repacking vertices: #define IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT struct ImDrawVert { ImVec2 pos; float z; ImU32 col; ImVec2 uv; } 202 | for (int n = 0; n < draw_data->CmdListsCount; n++) 203 | { 204 | const ImDrawList* cmd_list = draw_data->CmdLists[n]; 205 | const ImDrawVert* vtx_src = cmd_list->VtxBuffer.Data; 206 | for (int i = 0; i < cmd_list->VtxBuffer.Size; i++) 207 | { 208 | vtx_dst->pos[0] = vtx_src->pos.x; 209 | vtx_dst->pos[1] = vtx_src->pos.y; 210 | vtx_dst->pos[2] = 0.0f; 211 | vtx_dst->col = IMGUI_COL_TO_DX9_ARGB(vtx_src->col); 212 | vtx_dst->uv[0] = vtx_src->uv.x; 213 | vtx_dst->uv[1] = vtx_src->uv.y; 214 | vtx_dst++; 215 | vtx_src++; 216 | } 217 | memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx)); 218 | idx_dst += cmd_list->IdxBuffer.Size; 219 | } 220 | bd->pVB->Unlock(); 221 | bd->pIB->Unlock(); 222 | bd->pd3dDevice->SetStreamSource(0, bd->pVB, 0, sizeof(CUSTOMVERTEX)); 223 | bd->pd3dDevice->SetIndices(bd->pIB); 224 | bd->pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX); 225 | 226 | // Setup desired DX state 227 | ImGui_ImplDX9_SetupRenderState(draw_data); 228 | 229 | // Render command lists 230 | // (Because we merged all buffers into a single one, we maintain our own offset into them) 231 | int global_vtx_offset = 0; 232 | int global_idx_offset = 0; 233 | ImVec2 clip_off = draw_data->DisplayPos; 234 | for (int n = 0; n < draw_data->CmdListsCount; n++) 235 | { 236 | const ImDrawList* cmd_list = draw_data->CmdLists[n]; 237 | for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) 238 | { 239 | const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; 240 | if (pcmd->UserCallback != NULL) 241 | { 242 | // User callback, registered via ImDrawList::AddCallback() 243 | // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.) 244 | if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) 245 | ImGui_ImplDX9_SetupRenderState(draw_data); 246 | else 247 | pcmd->UserCallback(cmd_list, pcmd); 248 | } 249 | else 250 | { 251 | const RECT r = { (LONG)(pcmd->ClipRect.x - clip_off.x), (LONG)(pcmd->ClipRect.y - clip_off.y), (LONG)(pcmd->ClipRect.z - clip_off.x), (LONG)(pcmd->ClipRect.w - clip_off.y) }; 252 | const LPDIRECT3DTEXTURE9 texture = (LPDIRECT3DTEXTURE9)pcmd->GetTexID(); 253 | bd->pd3dDevice->SetTexture(0, texture); 254 | bd->pd3dDevice->SetScissorRect(&r); 255 | bd->pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, pcmd->VtxOffset + global_vtx_offset, 0, (UINT)cmd_list->VtxBuffer.Size, pcmd->IdxOffset + global_idx_offset, pcmd->ElemCount / 3); 256 | } 257 | } 258 | global_idx_offset += cmd_list->IdxBuffer.Size; 259 | global_vtx_offset += cmd_list->VtxBuffer.Size; 260 | } 261 | 262 | // Restore the DX9 transform 263 | bd->pd3dDevice->SetTransform(D3DTS_WORLD, &last_world); 264 | bd->pd3dDevice->SetTransform(D3DTS_VIEW, &last_view); 265 | bd->pd3dDevice->SetTransform(D3DTS_PROJECTION, &last_projection); 266 | 267 | // Restore the DX9 state 268 | d3d9_state_block->Apply(); 269 | d3d9_state_block->Release(); 270 | } 271 | 272 | bool ImGui_ImplDX9_Init(IDirect3DDevice9* device) 273 | { 274 | ImGuiIO& io = ImGui::GetIO(); 275 | IM_ASSERT(io.BackendRendererUserData == NULL && "Already initialized a renderer backend!"); 276 | 277 | // Setup backend capabilities flags 278 | ImGui_ImplDX9_Data* bd = IM_NEW(ImGui_ImplDX9_Data)(); 279 | io.BackendRendererUserData = (void*)bd; 280 | io.BackendRendererName = "imgui_impl_dx9"; 281 | io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. 282 | 283 | bd->pd3dDevice = device; 284 | bd->pd3dDevice->AddRef(); 285 | 286 | return true; 287 | } 288 | 289 | void ImGui_ImplDX9_Shutdown() 290 | { 291 | ImGuiIO& io = ImGui::GetIO(); 292 | ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData(); 293 | 294 | ImGui_ImplDX9_InvalidateDeviceObjects(); 295 | if (bd->pd3dDevice) { bd->pd3dDevice->Release(); } 296 | io.BackendRendererName = NULL; 297 | io.BackendRendererUserData = NULL; 298 | IM_DELETE(bd); 299 | } 300 | 301 | static bool ImGui_ImplDX9_CreateFontsTexture() 302 | { 303 | // Build texture atlas 304 | ImGuiIO& io = ImGui::GetIO(); 305 | ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData(); 306 | unsigned char* pixels; 307 | int width, height, bytes_per_pixel; 308 | io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height, &bytes_per_pixel); 309 | 310 | // Convert RGBA32 to BGRA32 (because RGBA32 is not well supported by DX9 devices) 311 | #ifndef IMGUI_USE_BGRA_PACKED_COLOR 312 | if (io.Fonts->TexPixelsUseColors) 313 | { 314 | ImU32* dst_start = (ImU32*)ImGui::MemAlloc((size_t)width * height * bytes_per_pixel); 315 | for (ImU32* src = (ImU32*)pixels, *dst = dst_start, *dst_end = dst_start + (size_t)width * height; dst < dst_end; src++, dst++) 316 | *dst = IMGUI_COL_TO_DX9_ARGB(*src); 317 | pixels = (unsigned char*)dst_start; 318 | } 319 | #endif 320 | 321 | // Upload texture to graphics system 322 | bd->FontTexture = NULL; 323 | if (bd->pd3dDevice->CreateTexture(width, height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &bd->FontTexture, NULL) < 0) 324 | return false; 325 | D3DLOCKED_RECT tex_locked_rect; 326 | if (bd->FontTexture->LockRect(0, &tex_locked_rect, NULL, 0) != D3D_OK) 327 | return false; 328 | for (int y = 0; y < height; y++) 329 | memcpy((unsigned char*)tex_locked_rect.pBits + (size_t)tex_locked_rect.Pitch * y, pixels + (size_t)width * bytes_per_pixel * y, (size_t)width * bytes_per_pixel); 330 | bd->FontTexture->UnlockRect(0); 331 | 332 | // Store our identifier 333 | io.Fonts->SetTexID((ImTextureID)bd->FontTexture); 334 | 335 | #ifndef IMGUI_USE_BGRA_PACKED_COLOR 336 | if (io.Fonts->TexPixelsUseColors) 337 | ImGui::MemFree(pixels); 338 | #endif 339 | 340 | return true; 341 | } 342 | 343 | bool ImGui_ImplDX9_CreateDeviceObjects() 344 | { 345 | ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData(); 346 | if (!bd || !bd->pd3dDevice) 347 | return false; 348 | if (!ImGui_ImplDX9_CreateFontsTexture()) 349 | return false; 350 | return true; 351 | } 352 | 353 | void ImGui_ImplDX9_InvalidateDeviceObjects() 354 | { 355 | ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData(); 356 | if (!bd || !bd->pd3dDevice) 357 | return; 358 | if (bd->pVB) { bd->pVB->Release(); bd->pVB = NULL; } 359 | if (bd->pIB) { bd->pIB->Release(); bd->pIB = NULL; } 360 | if (bd->FontTexture) { bd->FontTexture->Release(); bd->FontTexture = NULL; ImGui::GetIO().Fonts->SetTexID(NULL); } // We copied bd->pFontTextureView to io.Fonts->TexID so let's clear that as well. 361 | } 362 | 363 | void ImGui_ImplDX9_NewFrame() 364 | { 365 | ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData(); 366 | IM_ASSERT(bd != NULL && "Did you call ImGui_ImplDX9_Init()?"); 367 | 368 | if (!bd->FontTexture) 369 | ImGui_ImplDX9_CreateDeviceObjects(); 370 | } 371 | -------------------------------------------------------------------------------- /src/defender-control/imgui/backends/imgui_impl_dx9.h: -------------------------------------------------------------------------------- 1 | // dear imgui: Renderer Backend for DirectX9 2 | // This needs to be used along with a Platform Backend (e.g. Win32) 3 | 4 | // Implemented features: 5 | // [X] Renderer: User texture binding. Use 'LPDIRECT3DTEXTURE9' as ImTextureID. Read the FAQ about ImTextureID! 6 | // [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices. 7 | 8 | // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. 9 | // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. 10 | // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. 11 | // Read online: https://github.com/ocornut/imgui/tree/master/docs 12 | 13 | #pragma once 14 | #include "imgui.h" // IMGUI_IMPL_API 15 | 16 | struct IDirect3DDevice9; 17 | 18 | IMGUI_IMPL_API bool ImGui_ImplDX9_Init(IDirect3DDevice9* device); 19 | IMGUI_IMPL_API void ImGui_ImplDX9_Shutdown(); 20 | IMGUI_IMPL_API void ImGui_ImplDX9_NewFrame(); 21 | IMGUI_IMPL_API void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data); 22 | 23 | // Use if you want to reset your rendering device without losing Dear ImGui state. 24 | IMGUI_IMPL_API bool ImGui_ImplDX9_CreateDeviceObjects(); 25 | IMGUI_IMPL_API void ImGui_ImplDX9_InvalidateDeviceObjects(); 26 | -------------------------------------------------------------------------------- /src/defender-control/imgui/backends/imgui_impl_win32.h: -------------------------------------------------------------------------------- 1 | // dear imgui: Platform Backend for Windows (standard windows API for 32 and 64 bits applications) 2 | // This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..) 3 | 4 | // Implemented features: 5 | // [X] Platform: Clipboard support (for Win32 this is actually part of core dear imgui) 6 | // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. 7 | // [X] Platform: Keyboard arrays indexed using VK_* Virtual Key Codes, e.g. ImGui::IsKeyPressed(VK_SPACE). 8 | // [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. 9 | 10 | // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. 11 | // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. 12 | // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. 13 | // Read online: https://github.com/ocornut/imgui/tree/master/docs 14 | 15 | #pragma once 16 | #include "imgui.h" // IMGUI_IMPL_API 17 | 18 | IMGUI_IMPL_API bool ImGui_ImplWin32_Init(void* hwnd); 19 | IMGUI_IMPL_API void ImGui_ImplWin32_Shutdown(); 20 | IMGUI_IMPL_API void ImGui_ImplWin32_NewFrame(); 21 | 22 | // Win32 message handler your application need to call. 23 | // - Intentionally commented out in a '#if 0' block to avoid dragging dependencies on from this helper. 24 | // - You should COPY the line below into your .cpp code to forward declare the function and then you can call it. 25 | #if 0 26 | extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); 27 | #endif 28 | 29 | // DPI-related helpers (optional) 30 | // - Use to enable DPI awareness without having to create an application manifest. 31 | // - Your own app may already do this via a manifest or explicit calls. This is mostly useful for our examples/ apps. 32 | // - In theory we could call simple functions from Windows SDK such as SetProcessDPIAware(), SetProcessDpiAwareness(), etc. 33 | // but most of the functions provided by Microsoft require Windows 8.1/10+ SDK at compile time and Windows 8/10+ at runtime, 34 | // neither we want to require the user to have. So we dynamically select and load those functions to avoid dependencies. 35 | IMGUI_IMPL_API void ImGui_ImplWin32_EnableDpiAwareness(); 36 | IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd); // HWND hwnd 37 | IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor); // HMONITOR monitor 38 | 39 | // Transparency related helpers (optional) [experimental] 40 | // - Use to enable alpha compositing transparency with the desktop. 41 | // - Use together with e.g. clearing your framebuffer with zero-alpha. 42 | IMGUI_IMPL_API void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd); // HWND hwnd 43 | -------------------------------------------------------------------------------- /src/defender-control/imgui/imconfig.h: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // COMPILE-TIME OPTIONS FOR DEAR IMGUI 3 | // Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure. 4 | // You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions. 5 | //----------------------------------------------------------------------------- 6 | // A) You may edit imconfig.h (and not overwrite it when updating Dear ImGui, or maintain a patch/rebased branch with your modifications to it) 7 | // B) or '#define IMGUI_USER_CONFIG "my_imgui_config.h"' in your project and then add directives in your own file without touching this template. 8 | //----------------------------------------------------------------------------- 9 | // You need to make sure that configuration settings are defined consistently _everywhere_ Dear ImGui is used, which include the imgui*.cpp 10 | // files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures. 11 | // Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts. 12 | // Call IMGUI_CHECKVERSION() from your .cpp files to verify that the data structures your files are using are matching the ones imgui.cpp is using. 13 | //----------------------------------------------------------------------------- 14 | 15 | #pragma once 16 | 17 | //---- Define assertion handler. Defaults to calling assert(). 18 | // If your macro uses multiple statements, make sure is enclosed in a 'do { .. } while (0)' block so it can be used as a single statement. 19 | //#define IM_ASSERT(_EXPR) MyAssert(_EXPR) 20 | //#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts 21 | 22 | //---- Define attributes of all API symbols declarations, e.g. for DLL under Windows 23 | // Using Dear ImGui via a shared library is not recommended, because of function call overhead and because we don't guarantee backward nor forward ABI compatibility. 24 | // DLL users: heaps and globals are not shared across DLL boundaries! You will need to call SetCurrentContext() + SetAllocatorFunctions() 25 | // for each static/DLL boundary you are calling from. Read "Context and Memory Allocators" section of imgui.cpp for more details. 26 | //#define IMGUI_API __declspec( dllexport ) 27 | //#define IMGUI_API __declspec( dllimport ) 28 | 29 | //---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to avoid using soon-to-be obsolete function/names. 30 | //#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS 31 | 32 | //---- Disable all of Dear ImGui or don't implement standard windows. 33 | // It is very strongly recommended to NOT disable the demo windows during development. Please read comments in imgui_demo.cpp. 34 | //#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty. 35 | //#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty. Not recommended. 36 | //#define IMGUI_DISABLE_METRICS_WINDOW // Disable metrics/debugger window: ShowMetricsWindow() will be empty. 37 | 38 | //---- Don't implement some functions to reduce linkage requirements. 39 | //#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. (user32.lib/.a, kernel32.lib/.a) 40 | //#define IMGUI_ENABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with Visual Studio] Implement default IME handler (require imm32.lib/.a, auto-link for Visual Studio, -limm32 on command-line for MinGW) 41 | //#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with non-Visual Studio compilers] Don't implement default IME handler (won't require imm32.lib/.a) 42 | //#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, ime). 43 | //#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default OSX clipboard handler (need to link with '-framework ApplicationServices', this is why this is not the default). 44 | //#define IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself (e.g. if you don't want to link with vsnprintf) 45 | //#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself. 46 | //#define IMGUI_DISABLE_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle at all (replace them with dummies) 47 | //#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function. 48 | //#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions(). 49 | //#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available 50 | 51 | //---- Include imgui_user.h at the end of imgui.h as a convenience 52 | //#define IMGUI_INCLUDE_IMGUI_USER_H 53 | 54 | //---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another) 55 | //#define IMGUI_USE_BGRA_PACKED_COLOR 56 | 57 | //---- Use 32-bit for ImWchar (default is 16-bit) to support unicode planes 1-16. (e.g. point beyond 0xFFFF like emoticons, dingbats, symbols, shapes, ancient languages, etc...) 58 | //#define IMGUI_USE_WCHAR32 59 | 60 | //---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version 61 | // By default the embedded implementations are declared static and not available outside of Dear ImGui sources files. 62 | //#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h" 63 | //#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h" 64 | //#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION 65 | //#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION 66 | 67 | //---- Use stb_printf's faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined) 68 | // Requires 'stb_sprintf.h' to be available in the include path. Compatibility checks of arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by STB sprintf. 69 | // #define IMGUI_USE_STB_SPRINTF 70 | 71 | //---- Use FreeType to build and rasterize the font atlas (instead of stb_truetype which is embedded by default in Dear ImGui) 72 | // Requires FreeType headers to be available in the include path. Requires program to be compiled with 'misc/freetype/imgui_freetype.cpp' (in this repository) + the FreeType library (not provided). 73 | // On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'. 74 | //#define IMGUI_ENABLE_FREETYPE 75 | 76 | //---- Use stb_truetype to build and rasterize the font atlas (default) 77 | // The only purpose of this define is if you want force compilation of the stb_truetype backend ALONG with the FreeType backend. 78 | //#define IMGUI_ENABLE_STB_TRUETYPE 79 | 80 | //---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4. 81 | // This will be inlined as part of ImVec2 and ImVec4 class declarations. 82 | /* 83 | #define IM_VEC2_CLASS_EXTRA \ 84 | ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \ 85 | operator MyVec2() const { return MyVec2(x,y); } 86 | 87 | #define IM_VEC4_CLASS_EXTRA \ 88 | ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \ 89 | operator MyVec4() const { return MyVec4(x,y,z,w); } 90 | */ 91 | 92 | //---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices. 93 | // Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices). 94 | // Another way to allow large meshes while keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer. 95 | // Read about ImGuiBackendFlags_RendererHasVtxOffset for details. 96 | //#define ImDrawIdx unsigned int 97 | 98 | //---- Override ImDrawCallback signature (will need to modify renderer backends accordingly) 99 | //struct ImDrawList; 100 | //struct ImDrawCmd; 101 | //typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data); 102 | //#define ImDrawCallback MyImDrawCallback 103 | 104 | //---- Debug Tools: Macro to break in Debugger 105 | // (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.) 106 | //#define IM_DEBUG_BREAK IM_ASSERT(0) 107 | //#define IM_DEBUG_BREAK __debugbreak() 108 | 109 | //---- Debug Tools: Have the Item Picker break in the ItemAdd() function instead of ItemHoverable(), 110 | // (which comes earlier in the code, will catch a few extra items, allow picking items other than Hovered one.) 111 | // This adds a small runtime cost which is why it is not enabled by default. 112 | //#define IMGUI_DEBUG_TOOL_ITEM_PICKER_EX 113 | 114 | //---- Debug Tools: Enable slower asserts 115 | //#define IMGUI_DEBUG_PARANOID 116 | 117 | //---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files. 118 | /* 119 | namespace ImGui 120 | { 121 | void MyFunction(const char* name, const MyMatrix44& v); 122 | } 123 | */ 124 | -------------------------------------------------------------------------------- /src/defender-control/imgui/imstb_rectpack.h: -------------------------------------------------------------------------------- 1 | // [DEAR IMGUI] 2 | // This is a slightly modified version of stb_rect_pack.h 1.00. 3 | // Those changes would need to be pushed into nothings/stb: 4 | // - Added STBRP__CDECL 5 | // Grep for [DEAR IMGUI] to find the changes. 6 | 7 | // stb_rect_pack.h - v1.00 - public domain - rectangle packing 8 | // Sean Barrett 2014 9 | // 10 | // Useful for e.g. packing rectangular textures into an atlas. 11 | // Does not do rotation. 12 | // 13 | // Not necessarily the awesomest packing method, but better than 14 | // the totally naive one in stb_truetype (which is primarily what 15 | // this is meant to replace). 16 | // 17 | // Has only had a few tests run, may have issues. 18 | // 19 | // More docs to come. 20 | // 21 | // No memory allocations; uses qsort() and assert() from stdlib. 22 | // Can override those by defining STBRP_SORT and STBRP_ASSERT. 23 | // 24 | // This library currently uses the Skyline Bottom-Left algorithm. 25 | // 26 | // Please note: better rectangle packers are welcome! Please 27 | // implement them to the same API, but with a different init 28 | // function. 29 | // 30 | // Credits 31 | // 32 | // Library 33 | // Sean Barrett 34 | // Minor features 35 | // Martins Mozeiko 36 | // github:IntellectualKitty 37 | // 38 | // Bugfixes / warning fixes 39 | // Jeremy Jaussaud 40 | // Fabian Giesen 41 | // 42 | // Version history: 43 | // 44 | // 1.00 (2019-02-25) avoid small space waste; gracefully fail too-wide rectangles 45 | // 0.99 (2019-02-07) warning fixes 46 | // 0.11 (2017-03-03) return packing success/fail result 47 | // 0.10 (2016-10-25) remove cast-away-const to avoid warnings 48 | // 0.09 (2016-08-27) fix compiler warnings 49 | // 0.08 (2015-09-13) really fix bug with empty rects (w=0 or h=0) 50 | // 0.07 (2015-09-13) fix bug with empty rects (w=0 or h=0) 51 | // 0.06 (2015-04-15) added STBRP_SORT to allow replacing qsort 52 | // 0.05: added STBRP_ASSERT to allow replacing assert 53 | // 0.04: fixed minor bug in STBRP_LARGE_RECTS support 54 | // 0.01: initial release 55 | // 56 | // LICENSE 57 | // 58 | // See end of file for license information. 59 | 60 | ////////////////////////////////////////////////////////////////////////////// 61 | // 62 | // INCLUDE SECTION 63 | // 64 | 65 | #ifndef STB_INCLUDE_STB_RECT_PACK_H 66 | #define STB_INCLUDE_STB_RECT_PACK_H 67 | 68 | #define STB_RECT_PACK_VERSION 1 69 | 70 | #ifdef STBRP_STATIC 71 | #define STBRP_DEF static 72 | #else 73 | #define STBRP_DEF extern 74 | #endif 75 | 76 | #ifdef __cplusplus 77 | extern "C" { 78 | #endif 79 | 80 | typedef struct stbrp_context stbrp_context; 81 | typedef struct stbrp_node stbrp_node; 82 | typedef struct stbrp_rect stbrp_rect; 83 | 84 | #ifdef STBRP_LARGE_RECTS 85 | typedef int stbrp_coord; 86 | #else 87 | typedef unsigned short stbrp_coord; 88 | #endif 89 | 90 | STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects); 91 | // Assign packed locations to rectangles. The rectangles are of type 92 | // 'stbrp_rect' defined below, stored in the array 'rects', and there 93 | // are 'num_rects' many of them. 94 | // 95 | // Rectangles which are successfully packed have the 'was_packed' flag 96 | // set to a non-zero value and 'x' and 'y' store the minimum location 97 | // on each axis (i.e. bottom-left in cartesian coordinates, top-left 98 | // if you imagine y increasing downwards). Rectangles which do not fit 99 | // have the 'was_packed' flag set to 0. 100 | // 101 | // You should not try to access the 'rects' array from another thread 102 | // while this function is running, as the function temporarily reorders 103 | // the array while it executes. 104 | // 105 | // To pack into another rectangle, you need to call stbrp_init_target 106 | // again. To continue packing into the same rectangle, you can call 107 | // this function again. Calling this multiple times with multiple rect 108 | // arrays will probably produce worse packing results than calling it 109 | // a single time with the full rectangle array, but the option is 110 | // available. 111 | // 112 | // The function returns 1 if all of the rectangles were successfully 113 | // packed and 0 otherwise. 114 | 115 | struct stbrp_rect 116 | { 117 | // reserved for your use: 118 | int id; 119 | 120 | // input: 121 | stbrp_coord w, h; 122 | 123 | // output: 124 | stbrp_coord x, y; 125 | int was_packed; // non-zero if valid packing 126 | 127 | }; // 16 bytes, nominally 128 | 129 | 130 | STBRP_DEF void stbrp_init_target (stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes); 131 | // Initialize a rectangle packer to: 132 | // pack a rectangle that is 'width' by 'height' in dimensions 133 | // using temporary storage provided by the array 'nodes', which is 'num_nodes' long 134 | // 135 | // You must call this function every time you start packing into a new target. 136 | // 137 | // There is no "shutdown" function. The 'nodes' memory must stay valid for 138 | // the following stbrp_pack_rects() call (or calls), but can be freed after 139 | // the call (or calls) finish. 140 | // 141 | // Note: to guarantee best results, either: 142 | // 1. make sure 'num_nodes' >= 'width' 143 | // or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1' 144 | // 145 | // If you don't do either of the above things, widths will be quantized to multiples 146 | // of small integers to guarantee the algorithm doesn't run out of temporary storage. 147 | // 148 | // If you do #2, then the non-quantized algorithm will be used, but the algorithm 149 | // may run out of temporary storage and be unable to pack some rectangles. 150 | 151 | STBRP_DEF void stbrp_setup_allow_out_of_mem (stbrp_context *context, int allow_out_of_mem); 152 | // Optionally call this function after init but before doing any packing to 153 | // change the handling of the out-of-temp-memory scenario, described above. 154 | // If you call init again, this will be reset to the default (false). 155 | 156 | 157 | STBRP_DEF void stbrp_setup_heuristic (stbrp_context *context, int heuristic); 158 | // Optionally select which packing heuristic the library should use. Different 159 | // heuristics will produce better/worse results for different data sets. 160 | // If you call init again, this will be reset to the default. 161 | 162 | enum 163 | { 164 | STBRP_HEURISTIC_Skyline_default=0, 165 | STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default, 166 | STBRP_HEURISTIC_Skyline_BF_sortHeight 167 | }; 168 | 169 | 170 | ////////////////////////////////////////////////////////////////////////////// 171 | // 172 | // the details of the following structures don't matter to you, but they must 173 | // be visible so you can handle the memory allocations for them 174 | 175 | struct stbrp_node 176 | { 177 | stbrp_coord x,y; 178 | stbrp_node *next; 179 | }; 180 | 181 | struct stbrp_context 182 | { 183 | int width; 184 | int height; 185 | int align; 186 | int init_mode; 187 | int heuristic; 188 | int num_nodes; 189 | stbrp_node *active_head; 190 | stbrp_node *free_head; 191 | stbrp_node extra[2]; // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2' 192 | }; 193 | 194 | #ifdef __cplusplus 195 | } 196 | #endif 197 | 198 | #endif 199 | 200 | ////////////////////////////////////////////////////////////////////////////// 201 | // 202 | // IMPLEMENTATION SECTION 203 | // 204 | 205 | #ifdef STB_RECT_PACK_IMPLEMENTATION 206 | #ifndef STBRP_SORT 207 | #include 208 | #define STBRP_SORT qsort 209 | #endif 210 | 211 | #ifndef STBRP_ASSERT 212 | #include 213 | #define STBRP_ASSERT assert 214 | #endif 215 | 216 | // [DEAR IMGUI] Added STBRP__CDECL 217 | #ifdef _MSC_VER 218 | #define STBRP__NOTUSED(v) (void)(v) 219 | #define STBRP__CDECL __cdecl 220 | #else 221 | #define STBRP__NOTUSED(v) (void)sizeof(v) 222 | #define STBRP__CDECL 223 | #endif 224 | 225 | enum 226 | { 227 | STBRP__INIT_skyline = 1 228 | }; 229 | 230 | STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic) 231 | { 232 | switch (context->init_mode) { 233 | case STBRP__INIT_skyline: 234 | STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight); 235 | context->heuristic = heuristic; 236 | break; 237 | default: 238 | STBRP_ASSERT(0); 239 | } 240 | } 241 | 242 | STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem) 243 | { 244 | if (allow_out_of_mem) 245 | // if it's ok to run out of memory, then don't bother aligning them; 246 | // this gives better packing, but may fail due to OOM (even though 247 | // the rectangles easily fit). @TODO a smarter approach would be to only 248 | // quantize once we've hit OOM, then we could get rid of this parameter. 249 | context->align = 1; 250 | else { 251 | // if it's not ok to run out of memory, then quantize the widths 252 | // so that num_nodes is always enough nodes. 253 | // 254 | // I.e. num_nodes * align >= width 255 | // align >= width / num_nodes 256 | // align = ceil(width/num_nodes) 257 | 258 | context->align = (context->width + context->num_nodes-1) / context->num_nodes; 259 | } 260 | } 261 | 262 | STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes) 263 | { 264 | int i; 265 | #ifndef STBRP_LARGE_RECTS 266 | STBRP_ASSERT(width <= 0xffff && height <= 0xffff); 267 | #endif 268 | 269 | for (i=0; i < num_nodes-1; ++i) 270 | nodes[i].next = &nodes[i+1]; 271 | nodes[i].next = NULL; 272 | context->init_mode = STBRP__INIT_skyline; 273 | context->heuristic = STBRP_HEURISTIC_Skyline_default; 274 | context->free_head = &nodes[0]; 275 | context->active_head = &context->extra[0]; 276 | context->width = width; 277 | context->height = height; 278 | context->num_nodes = num_nodes; 279 | stbrp_setup_allow_out_of_mem(context, 0); 280 | 281 | // node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly) 282 | context->extra[0].x = 0; 283 | context->extra[0].y = 0; 284 | context->extra[0].next = &context->extra[1]; 285 | context->extra[1].x = (stbrp_coord) width; 286 | #ifdef STBRP_LARGE_RECTS 287 | context->extra[1].y = (1<<30); 288 | #else 289 | context->extra[1].y = 65535; 290 | #endif 291 | context->extra[1].next = NULL; 292 | } 293 | 294 | // find minimum y position if it starts at x1 295 | static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0, int width, int *pwaste) 296 | { 297 | stbrp_node *node = first; 298 | int x1 = x0 + width; 299 | int min_y, visited_width, waste_area; 300 | 301 | STBRP__NOTUSED(c); 302 | 303 | STBRP_ASSERT(first->x <= x0); 304 | 305 | #if 0 306 | // skip in case we're past the node 307 | while (node->next->x <= x0) 308 | ++node; 309 | #else 310 | STBRP_ASSERT(node->next->x > x0); // we ended up handling this in the caller for efficiency 311 | #endif 312 | 313 | STBRP_ASSERT(node->x <= x0); 314 | 315 | min_y = 0; 316 | waste_area = 0; 317 | visited_width = 0; 318 | while (node->x < x1) { 319 | if (node->y > min_y) { 320 | // raise min_y higher. 321 | // we've accounted for all waste up to min_y, 322 | // but we'll now add more waste for everything we've visted 323 | waste_area += visited_width * (node->y - min_y); 324 | min_y = node->y; 325 | // the first time through, visited_width might be reduced 326 | if (node->x < x0) 327 | visited_width += node->next->x - x0; 328 | else 329 | visited_width += node->next->x - node->x; 330 | } else { 331 | // add waste area 332 | int under_width = node->next->x - node->x; 333 | if (under_width + visited_width > width) 334 | under_width = width - visited_width; 335 | waste_area += under_width * (min_y - node->y); 336 | visited_width += under_width; 337 | } 338 | node = node->next; 339 | } 340 | 341 | *pwaste = waste_area; 342 | return min_y; 343 | } 344 | 345 | typedef struct 346 | { 347 | int x,y; 348 | stbrp_node **prev_link; 349 | } stbrp__findresult; 350 | 351 | static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int width, int height) 352 | { 353 | int best_waste = (1<<30), best_x, best_y = (1 << 30); 354 | stbrp__findresult fr; 355 | stbrp_node **prev, *node, *tail, **best = NULL; 356 | 357 | // align to multiple of c->align 358 | width = (width + c->align - 1); 359 | width -= width % c->align; 360 | STBRP_ASSERT(width % c->align == 0); 361 | 362 | // if it can't possibly fit, bail immediately 363 | if (width > c->width || height > c->height) { 364 | fr.prev_link = NULL; 365 | fr.x = fr.y = 0; 366 | return fr; 367 | } 368 | 369 | node = c->active_head; 370 | prev = &c->active_head; 371 | while (node->x + width <= c->width) { 372 | int y,waste; 373 | y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste); 374 | if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) { // actually just want to test BL 375 | // bottom left 376 | if (y < best_y) { 377 | best_y = y; 378 | best = prev; 379 | } 380 | } else { 381 | // best-fit 382 | if (y + height <= c->height) { 383 | // can only use it if it first vertically 384 | if (y < best_y || (y == best_y && waste < best_waste)) { 385 | best_y = y; 386 | best_waste = waste; 387 | best = prev; 388 | } 389 | } 390 | } 391 | prev = &node->next; 392 | node = node->next; 393 | } 394 | 395 | best_x = (best == NULL) ? 0 : (*best)->x; 396 | 397 | // if doing best-fit (BF), we also have to try aligning right edge to each node position 398 | // 399 | // e.g, if fitting 400 | // 401 | // ____________________ 402 | // |____________________| 403 | // 404 | // into 405 | // 406 | // | | 407 | // | ____________| 408 | // |____________| 409 | // 410 | // then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned 411 | // 412 | // This makes BF take about 2x the time 413 | 414 | if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) { 415 | tail = c->active_head; 416 | node = c->active_head; 417 | prev = &c->active_head; 418 | // find first node that's admissible 419 | while (tail->x < width) 420 | tail = tail->next; 421 | while (tail) { 422 | int xpos = tail->x - width; 423 | int y,waste; 424 | STBRP_ASSERT(xpos >= 0); 425 | // find the left position that matches this 426 | while (node->next->x <= xpos) { 427 | prev = &node->next; 428 | node = node->next; 429 | } 430 | STBRP_ASSERT(node->next->x > xpos && node->x <= xpos); 431 | y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste); 432 | if (y + height <= c->height) { 433 | if (y <= best_y) { 434 | if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) { 435 | best_x = xpos; 436 | STBRP_ASSERT(y <= best_y); 437 | best_y = y; 438 | best_waste = waste; 439 | best = prev; 440 | } 441 | } 442 | } 443 | tail = tail->next; 444 | } 445 | } 446 | 447 | fr.prev_link = best; 448 | fr.x = best_x; 449 | fr.y = best_y; 450 | return fr; 451 | } 452 | 453 | static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, int width, int height) 454 | { 455 | // find best position according to heuristic 456 | stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height); 457 | stbrp_node *node, *cur; 458 | 459 | // bail if: 460 | // 1. it failed 461 | // 2. the best node doesn't fit (we don't always check this) 462 | // 3. we're out of memory 463 | if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) { 464 | res.prev_link = NULL; 465 | return res; 466 | } 467 | 468 | // on success, create new node 469 | node = context->free_head; 470 | node->x = (stbrp_coord) res.x; 471 | node->y = (stbrp_coord) (res.y + height); 472 | 473 | context->free_head = node->next; 474 | 475 | // insert the new node into the right starting point, and 476 | // let 'cur' point to the remaining nodes needing to be 477 | // stiched back in 478 | 479 | cur = *res.prev_link; 480 | if (cur->x < res.x) { 481 | // preserve the existing one, so start testing with the next one 482 | stbrp_node *next = cur->next; 483 | cur->next = node; 484 | cur = next; 485 | } else { 486 | *res.prev_link = node; 487 | } 488 | 489 | // from here, traverse cur and free the nodes, until we get to one 490 | // that shouldn't be freed 491 | while (cur->next && cur->next->x <= res.x + width) { 492 | stbrp_node *next = cur->next; 493 | // move the current node to the free list 494 | cur->next = context->free_head; 495 | context->free_head = cur; 496 | cur = next; 497 | } 498 | 499 | // stitch the list back in 500 | node->next = cur; 501 | 502 | if (cur->x < res.x + width) 503 | cur->x = (stbrp_coord) (res.x + width); 504 | 505 | #ifdef _DEBUG 506 | cur = context->active_head; 507 | while (cur->x < context->width) { 508 | STBRP_ASSERT(cur->x < cur->next->x); 509 | cur = cur->next; 510 | } 511 | STBRP_ASSERT(cur->next == NULL); 512 | 513 | { 514 | int count=0; 515 | cur = context->active_head; 516 | while (cur) { 517 | cur = cur->next; 518 | ++count; 519 | } 520 | cur = context->free_head; 521 | while (cur) { 522 | cur = cur->next; 523 | ++count; 524 | } 525 | STBRP_ASSERT(count == context->num_nodes+2); 526 | } 527 | #endif 528 | 529 | return res; 530 | } 531 | 532 | // [DEAR IMGUI] Added STBRP__CDECL 533 | static int STBRP__CDECL rect_height_compare(const void *a, const void *b) 534 | { 535 | const stbrp_rect *p = (const stbrp_rect *) a; 536 | const stbrp_rect *q = (const stbrp_rect *) b; 537 | if (p->h > q->h) 538 | return -1; 539 | if (p->h < q->h) 540 | return 1; 541 | return (p->w > q->w) ? -1 : (p->w < q->w); 542 | } 543 | 544 | // [DEAR IMGUI] Added STBRP__CDECL 545 | static int STBRP__CDECL rect_original_order(const void *a, const void *b) 546 | { 547 | const stbrp_rect *p = (const stbrp_rect *) a; 548 | const stbrp_rect *q = (const stbrp_rect *) b; 549 | return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed); 550 | } 551 | 552 | #ifdef STBRP_LARGE_RECTS 553 | #define STBRP__MAXVAL 0xffffffff 554 | #else 555 | #define STBRP__MAXVAL 0xffff 556 | #endif 557 | 558 | STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects) 559 | { 560 | int i, all_rects_packed = 1; 561 | 562 | // we use the 'was_packed' field internally to allow sorting/unsorting 563 | for (i=0; i < num_rects; ++i) { 564 | rects[i].was_packed = i; 565 | } 566 | 567 | // sort according to heuristic 568 | STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare); 569 | 570 | for (i=0; i < num_rects; ++i) { 571 | if (rects[i].w == 0 || rects[i].h == 0) { 572 | rects[i].x = rects[i].y = 0; // empty rect needs no space 573 | } else { 574 | stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h); 575 | if (fr.prev_link) { 576 | rects[i].x = (stbrp_coord) fr.x; 577 | rects[i].y = (stbrp_coord) fr.y; 578 | } else { 579 | rects[i].x = rects[i].y = STBRP__MAXVAL; 580 | } 581 | } 582 | } 583 | 584 | // unsort 585 | STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order); 586 | 587 | // set was_packed flags and all_rects_packed status 588 | for (i=0; i < num_rects; ++i) { 589 | rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL); 590 | if (!rects[i].was_packed) 591 | all_rects_packed = 0; 592 | } 593 | 594 | // return the all_rects_packed status 595 | return all_rects_packed; 596 | } 597 | #endif 598 | 599 | /* 600 | ------------------------------------------------------------------------------ 601 | This software is available under 2 licenses -- choose whichever you prefer. 602 | ------------------------------------------------------------------------------ 603 | ALTERNATIVE A - MIT License 604 | Copyright (c) 2017 Sean Barrett 605 | Permission is hereby granted, free of charge, to any person obtaining a copy of 606 | this software and associated documentation files (the "Software"), to deal in 607 | the Software without restriction, including without limitation the rights to 608 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 609 | of the Software, and to permit persons to whom the Software is furnished to do 610 | so, subject to the following conditions: 611 | The above copyright notice and this permission notice shall be included in all 612 | copies or substantial portions of the Software. 613 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 614 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 615 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 616 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 617 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 618 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 619 | SOFTWARE. 620 | ------------------------------------------------------------------------------ 621 | ALTERNATIVE B - Public Domain (www.unlicense.org) 622 | This is free and unencumbered software released into the public domain. 623 | Anyone is free to copy, modify, publish, use, compile, sell, or distribute this 624 | software, either in source code form or as a compiled binary, for any purpose, 625 | commercial or non-commercial, and by any means. 626 | In jurisdictions that recognize copyright laws, the author or authors of this 627 | software dedicate any and all copyright interest in the software to the public 628 | domain. We make this dedication for the benefit of the public at large and to 629 | the detriment of our heirs and successors. We intend this dedication to be an 630 | overt act of relinquishment in perpetuity of all present and future rights to 631 | this software under copyright law. 632 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 633 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 634 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 635 | AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 636 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 637 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 638 | ------------------------------------------------------------------------------ 639 | */ 640 | -------------------------------------------------------------------------------- /src/defender-control/main.cpp: -------------------------------------------------------------------------------- 1 | // to-do: 2 | // make a ui for this 3 | // argument support -s check 4 | // 5 | #include "dcontrol.hpp" 6 | #include "wmic.hpp" 7 | #include "trusted.hpp" 8 | 9 | bool check_silent(int argc, char** argv) 10 | { 11 | for (int i = 0; i < argc; i++) 12 | { 13 | if (!strcmp(argv[i], "-s")) 14 | return true; 15 | } 16 | return false; 17 | } 18 | 19 | int main(int argc, char** argv) 20 | { 21 | auto silent = check_silent(argc, argv); 22 | 23 | if (!trusted::has_admin()) 24 | { 25 | printf("Must run as admin!\n"); 26 | 27 | if (!silent) 28 | system("pause"); 29 | 30 | return EXIT_FAILURE; 31 | } 32 | 33 | // Because we are a primary token, we can't swap ourselves with an impersonation token. 34 | // There will always be a need to re-create the process with the token as primary. 35 | // we check for argc == 1, assuming we aren't launching with any parameters 36 | // 37 | if (!trusted::is_system_group()) // && argc == 1 38 | { 39 | printf("Restarting with privileges\n"); 40 | trusted::create_process(util::get_current_path().append(silent ? " -s" : "")); 41 | return EXIT_SUCCESS; 42 | } 43 | 44 | try 45 | { 46 | dcontrol::kill_smartscreen(); 47 | dcontrol::manage_windefend(false); 48 | dcontrol::toggle_tamper(false); 49 | 50 | printf(dcontrol::check_defender() ? 51 | "Windows defender is currently ACTIVE\n" : 52 | "Windows defender is currently OFF\n"); 53 | 54 | #if DEFENDER_CONFIG == DEFENDER_DISABLE 55 | if (dcontrol::disable_defender()) 56 | { 57 | dcontrol::manage_security_center(false); 58 | printf("Disabled windows defender!\n"); 59 | } 60 | else 61 | printf("Failed to disable defender...\n"); 62 | #elif DEFENDER_CONFIG == DEFENDER_ENABLE 63 | if (dcontrol::enable_defender()) 64 | printf("Enabled windows defender!\n"); 65 | else 66 | printf("Failed to enable defender...\n"); 67 | #elif DEFENDER_CONFIG == DEFENDER_GUI 68 | #endif 69 | 70 | 71 | 72 | } 73 | catch (std::exception e) 74 | { 75 | printf("%s\n", e.what()); 76 | } 77 | 78 | if (!silent) 79 | system("pause"); 80 | 81 | return EXIT_SUCCESS; 82 | } 83 | -------------------------------------------------------------------------------- /src/defender-control/reg.cpp: -------------------------------------------------------------------------------- 1 | #include "reg.hpp" 2 | 3 | namespace reg 4 | { 5 | // reads a key from HKEY_LOCAL_MACHINE 6 | // 7 | DWORD read_key(const wchar_t* root_name, const wchar_t* value_name, uint32_t flags) 8 | { 9 | LSTATUS status; 10 | HKEY hkey; 11 | DWORD result{}; 12 | DWORD buff_sz = sizeof(DWORD); 13 | 14 | // https://docs.microsoft.com/en-us/windows/win32/winprog64/accessing-an-alternate-registry-view 15 | status = RegOpenKeyExW( 16 | HKEY_LOCAL_MACHINE, 17 | root_name, 18 | 0, 19 | KEY_READ | KEY_WOW64_64KEY, 20 | &hkey 21 | ); 22 | 23 | if (status) 24 | { 25 | if (flags & DBG_MSG) 26 | wprintf(L"Error opening %ls key \n", root_name); 27 | return -1; 28 | } 29 | 30 | status = RegQueryValueExW( 31 | hkey, 32 | value_name, 33 | 0, NULL, 34 | reinterpret_cast(&result), 35 | &buff_sz 36 | ); 37 | 38 | if (status) 39 | { 40 | if (flags & DBG_MSG) 41 | wprintf(L"Failed to read %d\n", result); 42 | 43 | return -1; 44 | } 45 | 46 | RegCloseKey(hkey); 47 | 48 | return result; 49 | } 50 | 51 | // creates a registry in HKEY_LOCAL_MACHINE with KEY_ALL_ACCESS permissions 52 | // 53 | bool create_registry(const wchar_t* root_name, HKEY& hkey) 54 | { 55 | LSTATUS status; 56 | 57 | DWORD dwDisposition; 58 | 59 | status = RegCreateKeyExW( 60 | HKEY_LOCAL_MACHINE, 61 | root_name, 62 | 0, 0, 0, 63 | 131334, 64 | 0, 65 | &hkey, 66 | &dwDisposition 67 | ); 68 | 69 | if (status) 70 | { 71 | wprintf(L"Could not find or create %ls error %d\n", root_name, status); 72 | return false; 73 | } 74 | 75 | return true; 76 | } 77 | 78 | // Set value in registry as a DWORD 79 | // 80 | bool set_keyval(HKEY& hkey, const wchar_t* value_name, DWORD value) 81 | { 82 | auto ret = RegSetValueExW(hkey, value_name, 0, REG_DWORD, 83 | reinterpret_cast(&value), 4); 84 | 85 | if (ret) 86 | { 87 | // wprintf(L"Set error: %d\n", ret); 88 | return false; 89 | } 90 | 91 | return true; 92 | } 93 | 94 | // Set value in registry as binary mode 95 | // 96 | bool set_keyval_bin(HKEY& hkey, const wchar_t* value_name, DWORD value) 97 | { 98 | auto ret = RegSetValueExW(hkey, value_name, 0, REG_BINARY, 99 | reinterpret_cast(&value), 12); 100 | 101 | if (ret) 102 | { 103 | // wprintf(L"Set error: %d\n", ret); 104 | return false; 105 | } 106 | return true; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/defender-control/reg.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include "settings.hpp" 6 | 7 | namespace reg 8 | { 9 | DWORD read_key(const wchar_t* root_name, const wchar_t* value_name, uint32_t flags = 0); 10 | bool create_registry(const wchar_t* root_name, HKEY& hkey); 11 | bool set_keyval(HKEY& hkey, const wchar_t* value_name, DWORD value); 12 | bool set_keyval_bin(HKEY& hkey, const wchar_t* value_name, DWORD value); 13 | } 14 | -------------------------------------------------------------------------------- /src/defender-control/settings.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define DBG_MSG (1 << 0) 4 | 5 | #define DEFENDER_ENABLE 1 6 | #define DEFENDER_DISABLE 2 7 | #define DEFENDER_GUI 3 8 | 9 | #define DEFENDER_CONFIG DEFENDER_DISABLE 10 | -------------------------------------------------------------------------------- /src/defender-control/trusted.cpp: -------------------------------------------------------------------------------- 1 | #include "trusted.hpp" 2 | 3 | namespace trusted 4 | { 5 | // Enable prvileges 6 | // 7 | bool enable_privilege(std::string privilege) 8 | { 9 | HANDLE hToken; 10 | if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken)) 11 | return false; 12 | 13 | LUID luid; 14 | if (!LookupPrivilegeValueA(nullptr, privilege.c_str(), &luid)) 15 | { 16 | CloseHandle(hToken); 17 | return false; 18 | } 19 | 20 | TOKEN_PRIVILEGES tp; 21 | tp.PrivilegeCount = 1; 22 | tp.Privileges[0].Luid = luid; 23 | tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 24 | if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), nullptr, nullptr)) 25 | { 26 | CloseHandle(hToken); 27 | return false; 28 | } 29 | 30 | CloseHandle(hToken); 31 | return true; 32 | } 33 | 34 | // Give system permissions 35 | // 36 | bool impersonate_system() 37 | { 38 | auto systemPid = util::get_pid("winlogon.exe"); 39 | HANDLE hSystemProcess; 40 | if ((hSystemProcess = OpenProcess( 41 | PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION, 42 | FALSE, 43 | systemPid)) == nullptr) 44 | { 45 | return false; 46 | } 47 | 48 | HANDLE hSystemToken; 49 | if (!OpenProcessToken( 50 | hSystemProcess, 51 | MAXIMUM_ALLOWED, 52 | &hSystemToken)) 53 | { 54 | CloseHandle(hSystemProcess); 55 | return false; 56 | } 57 | 58 | HANDLE hDupToken; 59 | SECURITY_ATTRIBUTES tokenAttributes; 60 | tokenAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); 61 | tokenAttributes.lpSecurityDescriptor = nullptr; 62 | tokenAttributes.bInheritHandle = FALSE; 63 | if (!DuplicateTokenEx( 64 | hSystemToken, 65 | MAXIMUM_ALLOWED, 66 | &tokenAttributes, 67 | SecurityImpersonation, 68 | TokenImpersonation, 69 | &hDupToken)) 70 | { 71 | CloseHandle(hSystemToken); 72 | return false; 73 | } 74 | 75 | if (!ImpersonateLoggedOnUser(hDupToken)) 76 | { 77 | CloseHandle(hDupToken); 78 | CloseHandle(hSystemToken); 79 | return false; 80 | } 81 | 82 | // Optional 83 | // 84 | if (!SetThreadToken(0, hDupToken)) 85 | return false; 86 | 87 | CloseHandle(hDupToken); 88 | CloseHandle(hSystemToken); 89 | 90 | return true; 91 | } 92 | 93 | // Start the trusted installer service 94 | // 95 | DWORD start_trusted() 96 | { 97 | auto sc_manager = OpenSCManagerA( 98 | nullptr, 99 | SERVICES_ACTIVE_DATABASE, 100 | GENERIC_EXECUTE 101 | ); 102 | 103 | if (!sc_manager) 104 | return -1; 105 | 106 | auto service = OpenServiceA( 107 | sc_manager, 108 | "TrustedInstaller", 109 | GENERIC_READ | GENERIC_EXECUTE 110 | ); 111 | 112 | if (!service) 113 | { 114 | CloseServiceHandle(sc_manager); 115 | return -1; 116 | } 117 | 118 | SERVICE_STATUS_PROCESS statusBuffer; 119 | DWORD bytesNeeded; 120 | while (QueryServiceStatusEx( 121 | service, 122 | SC_STATUS_PROCESS_INFO, 123 | reinterpret_cast(&statusBuffer), 124 | sizeof(SERVICE_STATUS_PROCESS), 125 | &bytesNeeded)) 126 | { 127 | if (statusBuffer.dwCurrentState == SERVICE_STOPPED) 128 | { 129 | if (!StartServiceW(service, 0, nullptr)) 130 | { 131 | CloseServiceHandle(service); 132 | CloseServiceHandle(sc_manager); 133 | return -1; 134 | } 135 | } 136 | if (statusBuffer.dwCurrentState == SERVICE_START_PENDING || 137 | statusBuffer.dwCurrentState == SERVICE_STOP_PENDING) 138 | { 139 | Sleep(statusBuffer.dwWaitHint); 140 | continue; 141 | } 142 | if (statusBuffer.dwCurrentState == SERVICE_RUNNING) 143 | { 144 | CloseServiceHandle(service); 145 | CloseServiceHandle(sc_manager); 146 | return statusBuffer.dwProcessId; 147 | } 148 | } 149 | CloseServiceHandle(service); 150 | CloseServiceHandle(sc_manager); 151 | 152 | return -1; 153 | } 154 | 155 | // Being a process as TrustedInstaller 156 | // 157 | bool create_process(std::string commandLine) 158 | { 159 | auto pid = start_trusted(); 160 | 161 | enable_privilege(SE_DEBUG_NAME); 162 | enable_privilege(SE_IMPERSONATE_NAME); 163 | impersonate_system(); 164 | 165 | auto hTIProcess = OpenProcess( 166 | PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION, 167 | FALSE, pid 168 | ); 169 | 170 | if (!hTIProcess) 171 | return false; 172 | 173 | HANDLE hTIToken; 174 | if (!OpenProcessToken(hTIProcess, MAXIMUM_ALLOWED, &hTIToken)) 175 | { 176 | CloseHandle(hTIProcess); 177 | return false; 178 | } 179 | 180 | HANDLE hDupToken; 181 | SECURITY_ATTRIBUTES tokenAttributes; 182 | tokenAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); 183 | tokenAttributes.lpSecurityDescriptor = nullptr; 184 | tokenAttributes.bInheritHandle = FALSE; 185 | 186 | if (!DuplicateTokenEx( 187 | hTIToken, 188 | MAXIMUM_ALLOWED, 189 | &tokenAttributes, 190 | SecurityImpersonation, 191 | TokenImpersonation, 192 | &hDupToken 193 | )) 194 | { 195 | CloseHandle(hTIToken); 196 | return false; 197 | } 198 | 199 | STARTUPINFOW startupInfo; 200 | ZeroMemory(&startupInfo, sizeof(STARTUPINFOW)); 201 | startupInfo.lpDesktop = (LPWSTR)L"Winsta0\\Default"; 202 | PROCESS_INFORMATION processInfo; 203 | ZeroMemory(&processInfo, sizeof(PROCESS_INFORMATION)); 204 | 205 | if (!CreateProcessWithTokenW( 206 | hDupToken, 207 | LOGON_WITH_PROFILE, 208 | nullptr, 209 | const_cast(util::string_to_wide(commandLine).c_str()), 210 | CREATE_UNICODE_ENVIRONMENT, 211 | nullptr, 212 | nullptr, 213 | &startupInfo, 214 | &processInfo 215 | )) 216 | return false; 217 | 218 | return true; 219 | } 220 | 221 | // Check current permissions for SYSTEM 222 | // 223 | bool is_system_group() 224 | { 225 | DWORD dw_size = 0; 226 | DWORD dw_result = 0; 227 | HANDLE token; 228 | PTOKEN_USER token_user; 229 | LPWSTR SID = NULL; 230 | 231 | if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) 232 | return false; 233 | 234 | if (!GetTokenInformation(token, TokenUser, NULL, dw_size, &dw_size)) 235 | { 236 | dw_result = GetLastError(); 237 | if (dw_result != ERROR_INSUFFICIENT_BUFFER) 238 | return false; 239 | } 240 | 241 | token_user = (PTOKEN_USER)GlobalAlloc(GPTR, dw_size); 242 | 243 | if (!GetTokenInformation(token, TokenUser, token_user, dw_size, &dw_size)) 244 | return false; 245 | 246 | if (!token_user) 247 | return false; 248 | 249 | if (!ConvertSidToStringSidW(token_user->User.Sid, &SID)) 250 | return false; 251 | 252 | // All SID can be found here: 253 | // https://docs.microsoft.com/en-us/troubleshoot/windows-server/identity/security-identifiers-in-windows 254 | // S-1-5-18 Local System A service account that is used by the operating system. 255 | // 256 | if (_wcsicmp(L"S-1-5-18", SID) == 0) 257 | return true; 258 | 259 | if (token_user) 260 | GlobalFree(token_user); 261 | 262 | return false; 263 | } 264 | 265 | // Checks if the current process is elevated 266 | // 267 | bool has_admin() 268 | { 269 | BOOL ret = FALSE; 270 | HANDLE token = NULL; 271 | 272 | if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) 273 | { 274 | TOKEN_ELEVATION elevation; 275 | DWORD rlen = sizeof(TOKEN_ELEVATION); 276 | 277 | if (GetTokenInformation(token, TokenElevation, &elevation, sizeof(elevation), &rlen)) 278 | ret = elevation.TokenIsElevated; 279 | } 280 | 281 | if (token) 282 | CloseHandle(token); 283 | 284 | return ret; 285 | } 286 | } -------------------------------------------------------------------------------- /src/defender-control/trusted.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "util.hpp" 7 | 8 | namespace trusted 9 | { 10 | // Enable prvileges 11 | // 12 | bool enable_privilege(std::string privilege); 13 | 14 | // Give system permissions 15 | // 16 | bool impersonate_system(); 17 | 18 | // Start the trusted installer service 19 | // 20 | DWORD start_trusted(); 21 | 22 | // Being a process as TrustedInstaller 23 | // 24 | bool create_process(std::string commandLine); 25 | 26 | // Check current permissions for SYSTEM 27 | // 28 | bool is_system_group(); 29 | 30 | // Checks if the current process is elevated 31 | // 32 | bool has_admin(); 33 | } 34 | -------------------------------------------------------------------------------- /src/defender-control/util.cpp: -------------------------------------------------------------------------------- 1 | #include "util.hpp" 2 | 3 | namespace util 4 | { 5 | // Converts a string to wide 6 | // 7 | std::wstring string_to_wide(const std::string& s) 8 | { 9 | std::wstring temp(s.length(), L' '); 10 | std::copy(s.begin(), s.end(), temp.begin()); 11 | return temp; 12 | } 13 | 14 | // Converts a wide to string 15 | // 16 | std::string wide_to_string(const std::wstring& s) { 17 | std::string temp(s.length(), ' '); 18 | std::copy(s.begin(), s.end(), temp.begin()); 19 | return temp; 20 | } 21 | 22 | // Sets the programs debug priviliges 23 | // 24 | bool set_privilege(LPCSTR privilege, BOOL enable) 25 | { 26 | TOKEN_PRIVILEGES priv = { 0,0,0,0 }; 27 | HANDLE token = nullptr; 28 | LUID luid = { 0,0 }; 29 | 30 | if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token)) 31 | { 32 | if (token) 33 | CloseHandle(token); 34 | 35 | return false; 36 | } 37 | 38 | if (!LookupPrivilegeValueA(nullptr, SE_DEBUG_NAME, &luid)) 39 | { 40 | if (token) 41 | CloseHandle(token); 42 | 43 | return false; 44 | } 45 | priv.PrivilegeCount = 1; 46 | priv.Privileges[0].Luid = luid; 47 | priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 48 | 49 | if (!AdjustTokenPrivileges(token, false, &priv, 0, nullptr, nullptr)) 50 | { 51 | if (token) 52 | CloseHandle(token); 53 | 54 | return false; 55 | } 56 | if (token) 57 | CloseHandle(token); 58 | 59 | return true; 60 | } 61 | 62 | char sub_43604B() 63 | { 64 | char v0; // bl 65 | SC_HANDLE v1; // eax 66 | SC_HANDLE v2; // esi 67 | void* v3; // eax 68 | 69 | v0 = 0; 70 | v1 = OpenSCManagerW(0, 0, 8u); 71 | v2 = v1; 72 | if (v1) 73 | { 74 | v3 = LockServiceDatabase(v1); 75 | if (v3) 76 | { 77 | UnlockServiceDatabase(v3); 78 | CloseServiceHandle(v2); 79 | return 1; 80 | } 81 | if (GetLastError() == 1055) 82 | v0 = 1; 83 | CloseServiceHandle(v2); 84 | } 85 | return v0; 86 | } 87 | 88 | // Get current username 89 | // 90 | std::string get_user() 91 | { 92 | char username[UNLEN + 1]; 93 | DWORD username_len = UNLEN + 1; 94 | GetUserNameA(username, &username_len); 95 | return std::string(username); 96 | } 97 | 98 | // Get current path of process 99 | // 100 | std::string get_current_path() 101 | { 102 | char buf[256]; 103 | DWORD len = sizeof(buf); 104 | int bytes = GetModuleFileNameA(NULL, buf, len); 105 | return std::string(buf); 106 | } 107 | 108 | // Get target process id 109 | // 110 | DWORD get_pid(std::string process_name) 111 | { 112 | HANDLE hSnapshot; 113 | if ((hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)) == INVALID_HANDLE_VALUE) 114 | return -1; 115 | 116 | DWORD pid = -1; 117 | PROCESSENTRY32 pe; 118 | ZeroMemory(&pe, sizeof(PROCESSENTRY32)); 119 | pe.dwSize = sizeof(PROCESSENTRY32); 120 | 121 | if (!Process32First(hSnapshot, &pe)) 122 | { 123 | CloseHandle(hSnapshot); 124 | return -1; 125 | } 126 | 127 | while (Process32Next(hSnapshot, &pe)) 128 | { 129 | if (pe.szExeFile == process_name) 130 | { 131 | pid = pe.th32ProcessID; 132 | break; 133 | } 134 | } 135 | 136 | if (pid == -1) 137 | { 138 | CloseHandle(hSnapshot); 139 | return -1; 140 | } 141 | 142 | CloseHandle(hSnapshot); 143 | return pid; 144 | } 145 | 146 | } -------------------------------------------------------------------------------- /src/defender-control/util.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | namespace util 8 | { 9 | // Converts a string to wide 10 | // 11 | std::wstring string_to_wide(const std::string& s); 12 | 13 | // Converts a wide to string 14 | // 15 | std::string wide_to_string(const std::wstring& s); 16 | 17 | // Sets the programs debug priviliges 18 | // 19 | bool set_privilege(LPCSTR privilege, BOOL enable); 20 | char sub_43604B(); 21 | 22 | // Get current username 23 | // 24 | std::string get_user(); 25 | 26 | // Get current path of process 27 | // 28 | std::string get_current_path(); 29 | 30 | // Get target process id 31 | // 32 | DWORD get_pid(std::string process_name); 33 | } 34 | -------------------------------------------------------------------------------- /src/defender-control/wmic.cpp: -------------------------------------------------------------------------------- 1 | // WMIC controls for windows defender module (cmdlet) 2 | // mppreference: https://docs.microsoft.com/en-us/previous-versions/windows/desktop/defender/msft-mppreference 3 | // wmi: https://docs.microsoft.com/en-us/windows/win32/wmisdk/example--getting-wmi-data-from-the-local-computer 4 | // 5 | #include "wmic.hpp" 6 | 7 | namespace wmic 8 | { 9 | helper::helper(std::string wnamespace, std::string wclass, std::string wmethod) 10 | { 11 | // Initialize 12 | // 13 | last_error = 0; 14 | hres = 0; 15 | loc_ptr = nullptr; 16 | service_ptr = nullptr; 17 | class_ptr = nullptr; 18 | param_def_ptr = nullptr; 19 | class_inst_ptr = nullptr; 20 | 21 | method_name = SysAllocString(util::string_to_wide(wmethod).c_str()); 22 | class_name = SysAllocString(util::string_to_wide(wclass).c_str()); 23 | 24 | class_name_s = wclass; 25 | 26 | // Setup COM library 27 | // 28 | hres = CoInitializeEx(0, COINIT_MULTITHREADED); 29 | 30 | if (FAILED(hres)) 31 | { 32 | last_error = 1; 33 | return; 34 | } 35 | 36 | // Setup general security levels 37 | // 38 | hres = CoInitializeSecurity( 39 | NULL, 40 | -1, // COM authentication 41 | NULL, // Authentication services 42 | NULL, // Reserved 43 | RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication 44 | RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation 45 | NULL, // Authentication info 46 | EOAC_NONE, // Additional capabilities 47 | NULL // Reserved 48 | ); 49 | 50 | if (FAILED(hres)) 51 | { 52 | last_error = 2; 53 | CoUninitialize(); 54 | return; 55 | } 56 | 57 | // Obtain locator for wmi 58 | // 59 | hres = CoCreateInstance(CLSID_WbemLocator, 0, 60 | CLSCTX_INPROC_SERVER, 61 | IID_IWbemLocator, (LPVOID*)&loc_ptr); 62 | 63 | if (FAILED(hres)) 64 | { 65 | last_error = 3; 66 | CoUninitialize(); 67 | return; 68 | } 69 | 70 | // Connect to wmi with IbwemLocator::ConnectServer 71 | // 72 | hres = loc_ptr->ConnectServer( 73 | _bstr_t(wnamespace.c_str()), 74 | 0, 0, 0, 0, 0, 0, &service_ptr 75 | ); 76 | 77 | if (FAILED(hres)) 78 | { 79 | last_error = 4; 80 | loc_ptr->Release(); 81 | CoUninitialize(); 82 | return; 83 | } 84 | 85 | // Set security levels for the proxy 86 | // 87 | hres = CoSetProxyBlanket( 88 | service_ptr, // Indicates the proxy to set 89 | RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx 90 | RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx 91 | NULL, // Server principal name 92 | RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx 93 | RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx 94 | NULL, // client identity 95 | EOAC_NONE // proxy capabilities 96 | ); 97 | 98 | if (FAILED(hres)) 99 | { 100 | last_error = 5; 101 | service_ptr->Release(); 102 | loc_ptr->Release(); 103 | CoUninitialize(); 104 | return; 105 | } 106 | 107 | // Setup WMI request 108 | // 109 | hres = service_ptr->GetObjectA(class_name, 0, 0, &class_ptr, 0); 110 | hres = class_ptr->GetMethod(method_name, 0, ¶m_def_ptr, 0); 111 | hres = param_def_ptr->SpawnInstance(0, &class_inst_ptr); 112 | } 113 | 114 | helper::~helper() 115 | { 116 | SysFreeString(class_name); 117 | SysFreeString(method_name); 118 | 119 | if (class_ptr) 120 | class_ptr->Release(); 121 | 122 | if (class_inst_ptr) 123 | class_inst_ptr->Release(); 124 | 125 | if (param_def_ptr) 126 | param_def_ptr->Release(); 127 | 128 | if (loc_ptr) 129 | loc_ptr->Release(); 130 | 131 | if (service_ptr) 132 | service_ptr->Release(); 133 | 134 | CoUninitialize(); 135 | } 136 | 137 | // Return the last error 138 | // 139 | int helper::get_last_error() 140 | { 141 | return last_error; 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /src/defender-control/wmic.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include "util.hpp" 5 | 6 | // WMI Libs 7 | // 8 | #define _WIN32_DCOM 9 | #include 10 | #include 11 | #pragma comment(lib, "wbemuuid.lib") 12 | 13 | namespace wmic 14 | { 15 | enum class variant_type : int 16 | { 17 | t_bool, 18 | t_bstr, 19 | t_uint8, 20 | t_uint32 21 | }; 22 | 23 | class helper 24 | { 25 | int last_error; 26 | HRESULT hres; 27 | 28 | IWbemServices* service_ptr; 29 | IWbemLocator* loc_ptr; 30 | 31 | IWbemClassObject* class_ptr; 32 | IWbemClassObject* param_def_ptr; 33 | IWbemClassObject* class_inst_ptr; 34 | 35 | BSTR method_name; 36 | BSTR class_name; 37 | std::string class_name_s; 38 | 39 | public: 40 | 41 | helper(std::string wnamespace, std::string wclass, std::string wmethod); 42 | ~helper(); 43 | 44 | // Return the last error 45 | // 46 | int get_last_error(); 47 | 48 | // Get WMI function 49 | // 50 | bool get(std::string variable, variant_type type, bstr_t& value) 51 | { 52 | IEnumWbemClassObject* pEnumerator = NULL; 53 | auto query = "SELECT * FROM " + class_name_s; 54 | auto hres = service_ptr->ExecQuery( 55 | bstr_t("WQL"), 56 | bstr_t(query.c_str()), 57 | WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 58 | NULL, 59 | &pEnumerator 60 | ); 61 | 62 | if (FAILED(hres)) 63 | return false; 64 | 65 | IWbemClassObject* pclsObj = NULL; 66 | ULONG uReturn = 0; 67 | 68 | while (pEnumerator) 69 | { 70 | HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, 71 | &pclsObj, &uReturn); 72 | 73 | if (0 == uReturn) 74 | break; 75 | 76 | VARIANT vtProp = {}; 77 | hr = pclsObj->Get(util::string_to_wide(variable).c_str(), 0, &vtProp, 0, 0); 78 | 79 | value = vtProp.bstrVal; 80 | 81 | VariantClear(&vtProp); 82 | pclsObj->Release(); 83 | } 84 | 85 | return true; 86 | } 87 | 88 | // Get WMI function 89 | // 90 | template 91 | bool get(std::string variable, variant_type type, T& value) 92 | { 93 | IEnumWbemClassObject* pEnumerator = NULL; 94 | auto query = "SELECT * FROM " + class_name_s; 95 | auto hres = service_ptr->ExecQuery( 96 | bstr_t("WQL"), 97 | bstr_t(query.c_str()), 98 | WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 99 | NULL, 100 | &pEnumerator 101 | ); 102 | 103 | if (FAILED(hres)) 104 | return false; 105 | 106 | IWbemClassObject* pclsObj = NULL; 107 | ULONG uReturn = 0; 108 | 109 | while (pEnumerator) 110 | { 111 | HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, 112 | &pclsObj, &uReturn); 113 | 114 | if (0 == uReturn) 115 | break; 116 | 117 | VARIANT vtProp = {}; 118 | hr = pclsObj->Get(util::string_to_wide(variable).c_str(), 0, &vtProp, 0, 0); 119 | 120 | switch (type) 121 | { 122 | case variant_type::t_bool: 123 | value = vtProp.boolVal; 124 | break; 125 | 126 | case variant_type::t_uint8: 127 | value = vtProp.uintVal; 128 | break; 129 | 130 | case variant_type::t_uint32: 131 | value = vtProp.uintVal; 132 | break; 133 | 134 | default: 135 | last_error = 6; 136 | return false; 137 | } 138 | 139 | VariantClear(&vtProp); 140 | pclsObj->Release(); 141 | } 142 | 143 | return true; 144 | } 145 | 146 | void execute(std::string variable, std::string value) 147 | { 148 | VARIANT var_cmd; 149 | var_cmd.vt = VT_BSTR; 150 | var_cmd.bstrVal = _bstr_t(util::string_to_wide(value).c_str()); 151 | 152 | // Store the value for the parameters 153 | // 154 | hres = class_inst_ptr->Put(util::string_to_wide(variable).c_str(), 0, &var_cmd, 0); 155 | 156 | // Execute 157 | // 158 | IWbemClassObject* pOutParams = nullptr; 159 | hres = service_ptr->ExecMethod(class_name, method_name, 0, 160 | 0, class_inst_ptr, &pOutParams, 0); 161 | 162 | if (FAILED(hres)) 163 | last_error = 7; 164 | 165 | // Cleanup 166 | // 167 | VariantClear(&var_cmd); 168 | 169 | if (pOutParams) 170 | pOutParams->Release(); 171 | } 172 | 173 | // Execute WMI set function 174 | // 175 | template 176 | void execute(std::string variable, variant_type type, T value) 177 | { 178 | // Create values for in parameter 179 | // 180 | VARIANT var_cmd; 181 | 182 | switch (type) 183 | { 184 | case variant_type::t_bool: 185 | var_cmd.vt = VT_BOOL; 186 | var_cmd.boolVal = value; 187 | break; 188 | 189 | case variant_type::t_uint8: 190 | var_cmd.vt = VT_UI1; 191 | var_cmd.uintVal = value; 192 | break; 193 | 194 | case variant_type::t_uint32: 195 | var_cmd.vt = VT_UI4; 196 | var_cmd.uintVal = value; 197 | break; 198 | 199 | default: 200 | last_error = 6; 201 | return; 202 | } 203 | 204 | // Store the value for the parameters 205 | // 206 | hres = class_inst_ptr->Put(util::string_to_wide(variable).c_str(), 0, &var_cmd, 0); 207 | 208 | // Execute 209 | // 210 | IWbemClassObject* pOutParams = nullptr; 211 | hres = service_ptr->ExecMethod(class_name, method_name, 0, 212 | 0, class_inst_ptr, &pOutParams, 0); 213 | 214 | if (FAILED(hres)) 215 | last_error = 7; 216 | 217 | // Cleanup 218 | // 219 | VariantClear(&var_cmd); 220 | 221 | if (pOutParams) 222 | pOutParams->Release(); 223 | } 224 | }; 225 | } 226 | 227 | -------------------------------------------------------------------------------- /src/detour/64/include/detver.h: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Common version parameters. 4 | // 5 | // Microsoft Research Detours Package, Version 4.0.1 6 | // 7 | // Copyright (c) Microsoft Corporation. All rights reserved. 8 | // 9 | 10 | #define _USING_V110_SDK71_ 1 11 | #include "winver.h" 12 | #if 0 13 | #include 14 | #include 15 | #else 16 | #ifndef DETOURS_STRINGIFY 17 | #define DETOURS_STRINGIFY_(x) #x 18 | #define DETOURS_STRINGIFY(x) DETOURS_STRINGIFY_(x) 19 | #endif 20 | 21 | #define VER_FILEFLAGSMASK 0x3fL 22 | #define VER_FILEFLAGS 0x0L 23 | #define VER_FILEOS 0x00040004L 24 | #define VER_FILETYPE 0x00000002L 25 | #define VER_FILESUBTYPE 0x00000000L 26 | #endif 27 | #define VER_DETOURS_BITS DETOURS_STRINGIFY(DETOURS_BITS) 28 | -------------------------------------------------------------------------------- /src/detour/64/include/syelog.h: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Detours Test Program (syelog.h of syelog.lib) 4 | // 5 | // Microsoft Research Detours Package 6 | // 7 | // Copyright (c) Microsoft Corporation. All rights reserved. 8 | // 9 | #pragma once 10 | #ifndef _SYELOGD_H_ 11 | #define _SYELOGD_H_ 12 | #include 13 | 14 | #pragma pack(push, 1) 15 | #pragma warning(push) 16 | #pragma warning(disable: 4200) 17 | 18 | ////////////////////////////////////////////////////////////////////////////// 19 | // 20 | // 21 | #define SYELOG_PIPE_NAMEA "\\\\.\\pipe\\syelog" 22 | #define SYELOG_PIPE_NAMEW L"\\\\.\\pipe\\syelog" 23 | #ifdef UNICODE 24 | #define SYELOG_PIPE_NAME SYELOG_PIPE_NAMEW 25 | #else 26 | #define SYELOG_PIPE_NAME SYELOG_PIPE_NAMEA 27 | #endif 28 | 29 | ////////////////////////////////////////////////////////////////////////////// 30 | // 31 | #define SYELOG_MAXIMUM_MESSAGE 4086 // 4096 - sizeof(header stuff) 32 | 33 | typedef struct _SYELOG_MESSAGE 34 | { 35 | USHORT nBytes; 36 | BYTE nFacility; 37 | BYTE nSeverity; 38 | DWORD nProcessId; 39 | FILETIME ftOccurance; 40 | BOOL fTerminate; 41 | CHAR szMessage[SYELOG_MAXIMUM_MESSAGE]; 42 | } SYELOG_MESSAGE, *PSYELOG_MESSAGE; 43 | 44 | 45 | // Facility Codes. 46 | // 47 | #define SYELOG_FACILITY_KERNEL 0x10 // OS Kernel 48 | #define SYELOG_FACILITY_SECURITY 0x20 // OS Security 49 | #define SYELOG_FACILITY_LOGGING 0x30 // OS Logging-internal 50 | #define SYELOG_FACILITY_SERVICE 0x40 // User-mode system daemon 51 | #define SYELOG_FACILITY_APPLICATION 0x50 // User-mode application 52 | #define SYELOG_FACILITY_USER 0x60 // User self-generated. 53 | #define SYELOG_FACILITY_LOCAL0 0x70 // Locally defined. 54 | #define SYELOG_FACILITY_LOCAL1 0x71 // Locally defined. 55 | #define SYELOG_FACILITY_LOCAL2 0x72 // Locally defined. 56 | #define SYELOG_FACILITY_LOCAL3 0x73 // Locally defined. 57 | #define SYELOG_FACILITY_LOCAL4 0x74 // Locally defined. 58 | #define SYELOG_FACILITY_LOCAL5 0x75 // Locally defined. 59 | #define SYELOG_FACILITY_LOCAL6 0x76 // Locally defined. 60 | #define SYELOG_FACILITY_LOCAL7 0x77 // Locally defined. 61 | #define SYELOG_FACILITY_LOCAL8 0x78 // Locally defined. 62 | #define SYELOG_FACILITY_LOCAL9 0x79 // Locally defined. 63 | 64 | // Severity Codes. 65 | // 66 | #define SYELOG_SEVERITY_FATAL 0x00 // System is dead. 67 | #define SYELOG_SEVERITY_ALERT 0x10 // Take action immediately. 68 | #define SYELOG_SEVERITY_CRITICAL 0x20 // Critical condition. 69 | #define SYELOG_SEVERITY_ERROR 0x30 // Error 70 | #define SYELOG_SEVERITY_WARNING 0x40 // Warning 71 | #define SYELOG_SEVERITY_NOTICE 0x50 // Significant condition. 72 | #define SYELOG_SEVERITY_INFORMATION 0x60 // Informational 73 | #define SYELOG_SEVERITY_AUDIT_FAIL 0x66 // Audit Failed 74 | #define SYELOG_SEVERITY_AUDIT_PASS 0x67 // Audit Succeeeded 75 | #define SYELOG_SEVERITY_DEBUG 0x70 // Debugging 76 | 77 | // Logging Functions. 78 | // 79 | VOID SyelogOpen(PCSTR pszIdentifier, BYTE nFacility); 80 | VOID Syelog(BYTE nSeverity, PCSTR pszMsgf, ...); 81 | VOID SyelogV(BYTE nSeverity, PCSTR pszMsgf, va_list args); 82 | VOID SyelogClose(BOOL fTerminate); 83 | 84 | #pragma warning(pop) 85 | #pragma pack(pop) 86 | 87 | #endif // _SYELOGD_H_ 88 | // 89 | ///////////////////////////////////////////////////////////////// End of File. 90 | -------------------------------------------------------------------------------- /src/detour/64/lib/detours.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pgkt04/defender-control/f4bb9f3340c83e6a0ab50650697ce865e935ba37/src/detour/64/lib/detours.lib -------------------------------------------------------------------------------- /src/detour/64/lib/syelog.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pgkt04/defender-control/f4bb9f3340c83e6a0ab50650697ce865e935ba37/src/detour/64/lib/syelog.lib -------------------------------------------------------------------------------- /src/detour/86/include/detver.h: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Common version parameters. 4 | // 5 | // Microsoft Research Detours Package, Version 4.0.1 6 | // 7 | // Copyright (c) Microsoft Corporation. All rights reserved. 8 | // 9 | 10 | #define _USING_V110_SDK71_ 1 11 | #include "winver.h" 12 | #if 0 13 | #include 14 | #include 15 | #else 16 | #ifndef DETOURS_STRINGIFY 17 | #define DETOURS_STRINGIFY_(x) #x 18 | #define DETOURS_STRINGIFY(x) DETOURS_STRINGIFY_(x) 19 | #endif 20 | 21 | #define VER_FILEFLAGSMASK 0x3fL 22 | #define VER_FILEFLAGS 0x0L 23 | #define VER_FILEOS 0x00040004L 24 | #define VER_FILETYPE 0x00000002L 25 | #define VER_FILESUBTYPE 0x00000000L 26 | #endif 27 | #define VER_DETOURS_BITS DETOURS_STRINGIFY(DETOURS_BITS) 28 | -------------------------------------------------------------------------------- /src/detour/86/include/syelog.h: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Detours Test Program (syelog.h of syelog.lib) 4 | // 5 | // Microsoft Research Detours Package 6 | // 7 | // Copyright (c) Microsoft Corporation. All rights reserved. 8 | // 9 | #pragma once 10 | #ifndef _SYELOGD_H_ 11 | #define _SYELOGD_H_ 12 | #include 13 | 14 | #pragma pack(push, 1) 15 | #pragma warning(push) 16 | #pragma warning(disable: 4200) 17 | 18 | ////////////////////////////////////////////////////////////////////////////// 19 | // 20 | // 21 | #define SYELOG_PIPE_NAMEA "\\\\.\\pipe\\syelog" 22 | #define SYELOG_PIPE_NAMEW L"\\\\.\\pipe\\syelog" 23 | #ifdef UNICODE 24 | #define SYELOG_PIPE_NAME SYELOG_PIPE_NAMEW 25 | #else 26 | #define SYELOG_PIPE_NAME SYELOG_PIPE_NAMEA 27 | #endif 28 | 29 | ////////////////////////////////////////////////////////////////////////////// 30 | // 31 | #define SYELOG_MAXIMUM_MESSAGE 4086 // 4096 - sizeof(header stuff) 32 | 33 | typedef struct _SYELOG_MESSAGE 34 | { 35 | USHORT nBytes; 36 | BYTE nFacility; 37 | BYTE nSeverity; 38 | DWORD nProcessId; 39 | FILETIME ftOccurance; 40 | BOOL fTerminate; 41 | CHAR szMessage[SYELOG_MAXIMUM_MESSAGE]; 42 | } SYELOG_MESSAGE, *PSYELOG_MESSAGE; 43 | 44 | 45 | // Facility Codes. 46 | // 47 | #define SYELOG_FACILITY_KERNEL 0x10 // OS Kernel 48 | #define SYELOG_FACILITY_SECURITY 0x20 // OS Security 49 | #define SYELOG_FACILITY_LOGGING 0x30 // OS Logging-internal 50 | #define SYELOG_FACILITY_SERVICE 0x40 // User-mode system daemon 51 | #define SYELOG_FACILITY_APPLICATION 0x50 // User-mode application 52 | #define SYELOG_FACILITY_USER 0x60 // User self-generated. 53 | #define SYELOG_FACILITY_LOCAL0 0x70 // Locally defined. 54 | #define SYELOG_FACILITY_LOCAL1 0x71 // Locally defined. 55 | #define SYELOG_FACILITY_LOCAL2 0x72 // Locally defined. 56 | #define SYELOG_FACILITY_LOCAL3 0x73 // Locally defined. 57 | #define SYELOG_FACILITY_LOCAL4 0x74 // Locally defined. 58 | #define SYELOG_FACILITY_LOCAL5 0x75 // Locally defined. 59 | #define SYELOG_FACILITY_LOCAL6 0x76 // Locally defined. 60 | #define SYELOG_FACILITY_LOCAL7 0x77 // Locally defined. 61 | #define SYELOG_FACILITY_LOCAL8 0x78 // Locally defined. 62 | #define SYELOG_FACILITY_LOCAL9 0x79 // Locally defined. 63 | 64 | // Severity Codes. 65 | // 66 | #define SYELOG_SEVERITY_FATAL 0x00 // System is dead. 67 | #define SYELOG_SEVERITY_ALERT 0x10 // Take action immediately. 68 | #define SYELOG_SEVERITY_CRITICAL 0x20 // Critical condition. 69 | #define SYELOG_SEVERITY_ERROR 0x30 // Error 70 | #define SYELOG_SEVERITY_WARNING 0x40 // Warning 71 | #define SYELOG_SEVERITY_NOTICE 0x50 // Significant condition. 72 | #define SYELOG_SEVERITY_INFORMATION 0x60 // Informational 73 | #define SYELOG_SEVERITY_AUDIT_FAIL 0x66 // Audit Failed 74 | #define SYELOG_SEVERITY_AUDIT_PASS 0x67 // Audit Succeeeded 75 | #define SYELOG_SEVERITY_DEBUG 0x70 // Debugging 76 | 77 | // Logging Functions. 78 | // 79 | VOID SyelogOpen(PCSTR pszIdentifier, BYTE nFacility); 80 | VOID Syelog(BYTE nSeverity, PCSTR pszMsgf, ...); 81 | VOID SyelogV(BYTE nSeverity, PCSTR pszMsgf, va_list args); 82 | VOID SyelogClose(BOOL fTerminate); 83 | 84 | #pragma warning(pop) 85 | #pragma pack(pop) 86 | 87 | #endif // _SYELOGD_H_ 88 | // 89 | ///////////////////////////////////////////////////////////////// End of File. 90 | -------------------------------------------------------------------------------- /src/detour/86/lib/detours.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pgkt04/defender-control/f4bb9f3340c83e6a0ab50650697ce865e935ba37/src/detour/86/lib/detours.lib -------------------------------------------------------------------------------- /src/detour/86/lib/syelog.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pgkt04/defender-control/f4bb9f3340c83e6a0ab50650697ce865e935ba37/src/detour/86/lib/syelog.lib -------------------------------------------------------------------------------- /src/detour/README.md: -------------------------------------------------------------------------------- 1 | Please include microsoft detour binaries here. 2 | 3 | https://github.com/Microsoft/Detours/blob/master/samples/README.TXT 4 | -------------------------------------------------------------------------------- /src/dumper/dumper.cpp: -------------------------------------------------------------------------------- 1 | // this is to poc for dumping out registry files 2 | // 3 | 4 | #include "pch.h" 5 | 6 | std::wstring string_to_wide(const std::string& s) 7 | { 8 | std::wstring temp(s.length(), L' '); 9 | std::copy(s.begin(), s.end(), temp.begin()); 10 | return temp; 11 | } 12 | 13 | std::string wide_to_string(const std::wstring& s) { 14 | std::string temp(s.length(), ' '); 15 | std::copy(s.begin(), s.end(), temp.begin()); 16 | return temp; 17 | } 18 | 19 | namespace RegHooks 20 | { 21 | // 0x33FA4 22 | // 23 | using StartProcWrapper_t = BOOL(__stdcall*)(LPWSTR); 24 | uintptr_t StartProcWrapper_addr; 25 | 26 | BOOL __stdcall hk_StartProcWrapper(LPWSTR lpCommandLine) 27 | { 28 | std::cout << "[Start Proc Wrapper]" << std::endl; 29 | return (reinterpret_cast(StartProcWrapper_addr))(lpCommandLine); 30 | } 31 | 32 | // cmdlinestuff, 10/10 naming im tired 33 | // 0x63F19 34 | // 35 | using cmdlinestuff_t = int(__stdcall*)(DWORD*, char, char, int, int); 36 | uintptr_t cmdlinestuff_addr; 37 | 38 | int __stdcall hk_cmdlinestuff(DWORD* a1, char a2, char a3, int a4, int a5) 39 | { 40 | std::cout << "[cmd stuff]" << std::endl; 41 | 42 | return (reinterpret_cast(cmdlinestuff_addr)) 43 | (a1, a2, a3, a4, a5); 44 | } 45 | 46 | 47 | // 0x57C08 48 | // 49 | using execute_shell_stuff_t = int(__stdcall*)(DWORD*, char, int, unsigned int, DWORD*); 50 | uintptr_t execute_shell_stuff_addr; 51 | 52 | int __stdcall hk_execute_shell_stuff(DWORD* a1, char a2, int a3, unsigned int a4, DWORD* a5) 53 | { 54 | std::cout << "[shell execute stuff]" << std::endl; 55 | 56 | return (reinterpret_cast(execute_shell_stuff_addr)) 57 | (a1, a2, a3, a4, a5); 58 | } 59 | 60 | // 0x464DC 61 | // 62 | using alt_start_proc_t = char(__stdcall*)(LPCWSTR, LPCWSTR, LPCWSTR, LPVOID, LPWSTR, 63 | HANDLE, LPCWSTR, LPSTARTUPINFOW, LPPROCESS_INFORMATION); 64 | uintptr_t alt_start_proc_addr; 65 | 66 | char __stdcall hk_alt_start_proc(LPCWSTR lpUsername, LPCWSTR lpDomain, 67 | LPCWSTR lpPassword, LPVOID Environment, LPWSTR lpCommandLine, 68 | HANDLE TokenHandle, LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, 69 | LPPROCESS_INFORMATION lpProcessInformation) 70 | { 71 | std::cout << "[Alt Start Proc]" << std::endl; 72 | 73 | return (reinterpret_cast(alt_start_proc_addr))(lpUsername, lpDomain, 74 | lpPassword, Environment, lpCommandLine, 75 | TokenHandle, lpCurrentDirectory, lpStartupInfo, 76 | lpProcessInformation); 77 | } 78 | 79 | // 0x45E0 80 | // 81 | using control_table_t = int(__stdcall*)(DWORD*, int); 82 | uintptr_t ControlTable_addr; 83 | 84 | std::vector cache = 85 | { 86 | 0x493730, 0x49451c, 0x4950c8, 0x4956f8, 87 | 0x494db0, 0x495620, 0x493b20, 0x4954dc, 88 | 0x4947a4, 0x495b30, 0x494d44 89 | }; 90 | 91 | int __stdcall hk_ControlTable(DWORD* a1, int a2) 92 | { 93 | auto ret = (reinterpret_cast(ControlTable_addr))(a1, a2); 94 | 95 | bool found = false; 96 | 97 | for (auto i : cache) 98 | { 99 | if (i == ret) 100 | found = true; 101 | } 102 | 103 | if (!found) 104 | { 105 | std::cout << "[Control Table] 0x" << std::hex << ret << std::endl; 106 | cache.push_back(ret); 107 | } 108 | 109 | return ret; 110 | } 111 | 112 | // int __stdcall wmic_1(int a1, _DWORD *a2) 113 | // 0x6CDA0 114 | // 115 | using wmic_1_t = int(__stdcall*)(int, DWORD*); 116 | uintptr_t wmic_1_addr; 117 | 118 | int __stdcall hk_wmic_1(int a1, DWORD* a2) 119 | { 120 | std::cout << "[wmic_1]" << std::endl; 121 | return (reinterpret_cast(wmic_1_addr))(a1, a2); 122 | } 123 | 124 | // int __thiscall hk_wmic_2(void* this, int a2, int a3) 125 | // address: 0x75ACA 126 | // 127 | using hk_wmic_2_t = int(__thiscall*)(void*, int, int); 128 | uintptr_t wmic_2_addr; 129 | 130 | int __fastcall hk_wmic_2(void* pthis, void* edx, int a2, int a3) 131 | { 132 | std::cout << "[wmic_2]" << std::endl; 133 | return (reinterpret_cast(wmic_2_addr))(pthis, a2, a3); 134 | } 135 | 136 | // wmic helper for setup 137 | // address: 0x7A999 138 | // 139 | using wmic_helper_t = int(__stdcall*)(int, int, wchar_t*, void*, wchar_t*, void*); 140 | uintptr_t wmic_helper_addr; 141 | 142 | int __stdcall hk_wmic_helper(int a1, int a2, wchar_t* a3, void* Src, wchar_t* String, void* a6) 143 | { 144 | std::cout << "[wmic helper]" << std::endl; 145 | return (reinterpret_cast(wmic_helper_addr))(a1, a2, a3, Src, String, a6); 146 | } 147 | 148 | // helper to check when we enable defender 149 | // address: 6AB70 150 | // calling convention: https://www.unknowncheats.me/forum/849605-post6.html 151 | // pattern: 55 8B EC 83 E4 F8 83 EC 64 53 56 8B 75 08 8B 46 08 8B D9 57 8D 4C 24 50 89 44 24 20 C7 44 24 152 | // 153 | using enable_def_helper_t = int(__thiscall*)(void*, int, DWORD*); 154 | uintptr_t enable_def_help_addr; 155 | 156 | int __fastcall hk_enable_def(void* pThis, void* edx, int a2, DWORD* a3) 157 | { 158 | std::cout << "enabling defender" << std::endl; 159 | return (reinterpret_cast(enable_def_help_addr))(pThis, a2, a3); 160 | } 161 | 162 | // Disable defender handler 163 | using disable_def_t = int(__thiscall*)(void*, int, DWORD*); 164 | uintptr_t disable_def_addr; 165 | 166 | // disable defender routine: 167 | // 0x6AEAF 168 | // int __thiscall DisableDefender(void *this, int a1, _DWORD *a2) 169 | 170 | int __fastcall hk_disable_def(void* pThis, void* edx, int a1, DWORD* a2) 171 | { 172 | std::cout << "disabling defender" << std::endl; 173 | return (reinterpret_cast(disable_def_addr))(pThis, a1, a2); 174 | } 175 | 176 | // hook for RegEnumValueW 177 | // ms docs: https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regenumvaluew 178 | // 179 | using regenumvaluew_t = LSTATUS(__stdcall*)(HKEY, DWORD, LPWSTR, LPDWORD, LPDWORD, LPDWORD, LPBYTE, LPDWORD); 180 | uintptr_t regenumvaluew_addr; 181 | 182 | LSTATUS __stdcall hk_RegEnumValueW( 183 | HKEY hKey, 184 | DWORD dwIndex, 185 | LPWSTR lpValueName, 186 | LPDWORD lpcchValueName, 187 | LPDWORD lpReserved, 188 | LPDWORD lpType, 189 | LPBYTE lpData, 190 | LPDWORD lpcbData 191 | ) 192 | { 193 | // there is a bug with a ridiculously large string we want to skip if we see it 194 | // 195 | auto converted = wide_to_string(lpValueName); 196 | 197 | if (converted.size() < MAX_PATH) 198 | { 199 | std::cout << "[RegEnumValueW]" << std::endl; 200 | std::cout << "lpValueName: " << converted.c_str() << std::endl; 201 | } 202 | 203 | return (reinterpret_cast(regenumvaluew_addr)) 204 | (hKey, dwIndex, lpValueName, lpcchValueName, lpReserved, lpType, lpData, lpcbData); 205 | } 206 | 207 | // hook for RegDeleteValueW 208 | // ms docs: https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regdeletevaluew 209 | // 210 | using regdeletevaluew_t = LSTATUS(__stdcall*)(HKEY, LPCWSTR); 211 | uintptr_t regdeletevaluew_addr; 212 | 213 | LSTATUS __stdcall hk_RegDeleteValueW( 214 | HKEY hKey, 215 | LPCWSTR lpValueName 216 | ) 217 | { 218 | std::cout << "[RegDeleteValueW]" << std::endl; 219 | std::cout << "lpValueName" << wide_to_string(lpValueName).c_str() << std::endl; 220 | 221 | return (reinterpret_cast(regdeletevaluew_addr))(hKey, lpValueName);; 222 | } 223 | 224 | // hook for RegDeleteKeyW 225 | // https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regdeletekeyw 226 | // 227 | using regdeletekeyw_t = LSTATUS(__stdcall*)(HKEY, LPCWSTR); 228 | uintptr_t regdeletekeyw_addr; 229 | 230 | LSTATUS __stdcall hk_RegDeleteKeyW( 231 | HKEY hKey, 232 | LPCWSTR lpSubKey 233 | ) 234 | { 235 | std::cout << "[RegDeleteValueW]" << std::endl; 236 | std::cout << "lpSubkey" << wide_to_string(lpSubKey).c_str() << std::endl; 237 | 238 | return (reinterpret_cast(regdeletekeyw_addr))(hKey, lpSubKey); 239 | } 240 | 241 | // RegSetValueExW 242 | // ms docs: https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regsetvalueexw 243 | // 244 | using regsetkeyvalueexw_t = LSTATUS(__stdcall*)(HKEY, LPCWSTR, DWORD, DWORD, const BYTE*, DWORD); 245 | uintptr_t regsetvalue_addr; 246 | 247 | LSTATUS __stdcall hk_RegSetValueExW( 248 | HKEY hKey, 249 | LPCWSTR lpValueName, 250 | DWORD Reserved, 251 | DWORD dwType, 252 | const BYTE* lpData, 253 | DWORD cbData 254 | ) 255 | { 256 | std::cout << "[RegSetValueExW]" << std::endl; 257 | std::cout << "lpValueName: " << wide_to_string(lpValueName).c_str() << std::endl; 258 | std::cout << "Reserved: " << Reserved << std::endl; 259 | std::cout << "dwType: " << dwType << std::endl; 260 | std::cout << "cbData: " << cbData << std::endl; 261 | 262 | auto ret = (reinterpret_cast(regsetvalue_addr))(hKey, lpValueName, Reserved, dwType, lpData, cbData); 263 | 264 | std::cout << "Ret: " << ret << std::endl; 265 | 266 | return ret; 267 | } 268 | 269 | // RegCreateKeyExW 270 | // ms docs: https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regcreatekeyexw 271 | // 272 | using RegCreateKeyExW_t = LSTATUS(__stdcall*)(HKEY, LPCWSTR, DWORD, LPWSTR, DWORD, REGSAM, const LPSECURITY_ATTRIBUTES, 273 | PHKEY, LPDWORD); 274 | uintptr_t RegCreateKeyExW_addr; 275 | 276 | LSTATUS __stdcall hk_RegCreateKeyExW( 277 | HKEY hKey, 278 | LPCWSTR lpSubKey, 279 | DWORD Reserved, 280 | LPWSTR lpClass, 281 | DWORD dwOptions, 282 | REGSAM samDesired, 283 | const LPSECURITY_ATTRIBUTES lpSecurityAttributes, 284 | PHKEY phkResult, 285 | LPDWORD lpdwDisposition 286 | ) 287 | { 288 | 289 | std::cout << "[RegCreateKeyExW]" << std::endl; 290 | std::cout << "hKey: " << hKey << std::endl; 291 | std::cout << "lpSubKey: " << wide_to_string(lpSubKey).c_str() << std::endl; 292 | std::cout << "lpClass: " << wide_to_string(lpClass).c_str() << std::endl; 293 | std::cout << "samDesired: " << samDesired << std::endl; 294 | std::cout << "Reserved: " << Reserved << std::endl; 295 | std::cout << "lpSecurityAttributes: " << lpSecurityAttributes << std::endl; 296 | std::cout << "dwOptions: " << dwOptions << std::endl; 297 | std::cout << "lpdwDisposition: " << lpdwDisposition << std::endl; 298 | 299 | auto ret = (reinterpret_cast(RegCreateKeyExW_addr)) 300 | (hKey, lpSubKey, Reserved, lpClass, dwOptions, samDesired, lpSecurityAttributes, phkResult, lpdwDisposition); 301 | 302 | std::cout << "Ret: " << ret << std::endl; 303 | 304 | return ret; 305 | } 306 | 307 | // RegConnectRegistryW 308 | // ms docs: https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regconnectregistryw 309 | // 310 | using RegConnectRegistryW_t = LSTATUS(__stdcall*)(LPCWSTR, HKEY, PHKEY); 311 | uintptr_t RegConnectRegistryW_addr; 312 | 313 | LSTATUS __stdcall hk_RegConnectRegistryW( 314 | LPCWSTR lpMachineName, 315 | HKEY hKey, 316 | PHKEY phkResult 317 | ) 318 | { 319 | std::cout << "[RegConnectRegistryW]" << std::endl; 320 | std::cout << "MachineName: " << wide_to_string(lpMachineName).c_str() << std::endl; 321 | return (reinterpret_cast(RegConnectRegistryW_addr))(lpMachineName, hKey, phkResult); 322 | } 323 | 324 | // RegEnumKeyExW 325 | // ms docs: https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regenumkeyexw 326 | // 327 | using RegEnumKeyExW_t = LSTATUS(__stdcall*)(HKEY, DWORD, LPWSTR, LPDWORD, LPDWORD, LPWSTR, LPDWORD, PFILETIME); 328 | uintptr_t RegEnumKeyExW_addr; 329 | 330 | LSTATUS __stdcall hk_RegEnumKeyExW( 331 | HKEY hKey, 332 | DWORD dwIndex, 333 | LPWSTR lpName, 334 | LPDWORD lpcchName, 335 | LPDWORD lpReserved, 336 | LPWSTR lpClass, 337 | LPDWORD lpcchClass, 338 | PFILETIME lpftLastWriteTime 339 | ) 340 | { 341 | std::cout << "[RegEnumKeyExW]" << std::endl; 342 | std::cout << "lpName: " << wide_to_string(lpName).c_str() << std::endl; 343 | 344 | return (reinterpret_cast(RegEnumKeyExW_addr)) 345 | (hKey, dwIndex, lpName, lpcchName, lpReserved, lpClass, lpcchClass, lpftLastWriteTime); 346 | } 347 | 348 | // RegCloseKey 349 | // ms docs: https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regclosekey 350 | // seems redundant to hook 351 | // 352 | LSTATUS __stdcall hk_RegCloseKey( 353 | HKEY hKey 354 | ) 355 | { 356 | return EXIT_SUCCESS; 357 | } 358 | 359 | // RegQueryValueExW 360 | // ms docs: https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regqueryvalueexw 361 | // 362 | using RegQueryValueExW_t = LSTATUS(__stdcall*)(HKEY, LPCWSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD); 363 | uintptr_t RegQueryValueExW_addr; 364 | 365 | LSTATUS __stdcall hk_RegQueryValueExW( 366 | HKEY hKey, 367 | LPCWSTR lpValueName, 368 | LPDWORD lpReserved, 369 | LPDWORD lpType, 370 | LPBYTE lpData, 371 | LPDWORD lpcbData 372 | ) 373 | { 374 | std::cout << "[RegQueryValueExW]" << std::endl; 375 | std::cout << "lpValueName: " << wide_to_string(lpValueName).c_str() << std::endl; 376 | 377 | return (reinterpret_cast(RegQueryValueExW_addr)) 378 | (hKey, lpValueName, lpReserved, lpType, lpData, lpcbData); 379 | } 380 | 381 | // RegOpenKeyExW 382 | // ms docs: https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regopenkeyexw 383 | // 384 | using RegOpenKeyExW_t = LSTATUS(__stdcall*)(HKEY, LPCWSTR, DWORD, REGSAM, PHKEY); 385 | uintptr_t RegOpenKeyExW_addr; 386 | 387 | LSTATUS __stdcall hk_RegOpenKeyExW( 388 | HKEY hKey, 389 | LPCWSTR lpSubKey, 390 | DWORD ulOptions, 391 | REGSAM samDesired, 392 | PHKEY phkResult 393 | ) 394 | { 395 | std::cout << "[RegOpenKeyExW]" << std::endl; 396 | std::cout << "lpValueName: " << wide_to_string(lpSubKey).c_str() << std::endl; 397 | std::cout << "ulOptions: " << ulOptions << std::endl; 398 | std::cout << "samDesired: " << samDesired << std::endl; 399 | 400 | return (reinterpret_cast(RegOpenKeyExW_addr)) 401 | (hKey, lpSubKey, ulOptions, samDesired, phkResult); 402 | } 403 | 404 | // CreateProcessW 405 | // ms docs: https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessw 406 | // 407 | using CreateProcessW_t = BOOL(__stdcall*)(LPCWSTR, LPWSTR, LPSECURITY_ATTRIBUTES, 408 | LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPCWSTR, LPSTARTUPINFOW, LPPROCESS_INFORMATION); 409 | uintptr_t CreateProcessW_addr; 410 | 411 | BOOL __stdcall hk_CreateProcessW( 412 | LPCWSTR lpApplicationName, 413 | LPWSTR lpCommandLine, 414 | LPSECURITY_ATTRIBUTES lpProcessAttributes, 415 | LPSECURITY_ATTRIBUTES lpThreadAttributes, 416 | BOOL bInheritHandles, 417 | DWORD dwCreationFlags, 418 | LPVOID lpEnvironment, 419 | LPCWSTR lpCurrentDirectory, 420 | LPSTARTUPINFOW lpStartupInfo, 421 | LPPROCESS_INFORMATION lpProcessInformation 422 | ) 423 | { 424 | std::cout << "[CreateProcessW]" << std::endl; 425 | std::cout << "lpCommandLine: " << wide_to_string(lpCommandLine).c_str() << std::endl; 426 | 427 | return (reinterpret_cast(CreateProcessW_addr))( 428 | lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, 429 | bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, 430 | lpStartupInfo, lpProcessInformation); 431 | } 432 | 433 | // ShellExecuteEx 434 | // 435 | using ShellExecuteExW_t = BOOL(__stdcall*)(SHELLEXECUTEINFOW*); 436 | uintptr_t ShellExecuteExW_addr; 437 | BOOL __stdcall hk_ShellExecuteExW(SHELLEXECUTEINFOW* pExecInfo) 438 | { 439 | std::cout << "[ShellExecuteExW]" << std::endl; 440 | return (reinterpret_cast(ShellExecuteExW_addr))(pExecInfo); 441 | } 442 | } 443 | 444 | namespace DetourHelper 445 | { 446 | // places a hook 447 | // 448 | void perf_hook(PVOID* oFunction, PVOID pDetour) { 449 | DetourTransactionBegin(); 450 | DetourUpdateThread(GetCurrentThread()); 451 | DetourAttach(oFunction, pDetour); 452 | DetourTransactionCommit(); 453 | } 454 | 455 | // removes a hook 456 | // 457 | void undo_hook(PVOID* oFunction, PVOID pDetour) { 458 | DetourTransactionBegin(); 459 | DetourUpdateThread(GetCurrentThread()); 460 | DetourDetach(oFunction, pDetour); 461 | DetourTransactionCommit(); 462 | } 463 | } 464 | 465 | uintptr_t get_func_addr(HMODULE mod, const char* name) 466 | { 467 | auto ret = reinterpret_cast(GetProcAddress(mod, name)); 468 | if (!ret) 469 | std::cout << "failed to get " << name << std::endl; 470 | std::cout << "obtained " << name << " from " << mod << std::endl; 471 | return ret; 472 | } 473 | 474 | void thread_main() 475 | { 476 | // setup console 477 | // 478 | AllocConsole(); 479 | UNREFERENCED_PARAMETER(freopen("CONIN$", "r", stdin)); 480 | UNREFERENCED_PARAMETER(freopen("CONOUT$", "w", stdout)); 481 | UNREFERENCED_PARAMETER(freopen("CONOUT$", "w", stderr)); 482 | SetConsoleTitleA("Log"); 483 | 484 | // setup hooks 485 | // 486 | auto advapi32 = GetModuleHandleA("Advapi32.dll"); 487 | auto kernel32 = GetModuleHandleA("Kernel32.dll"); 488 | auto shell32 = GetModuleHandleA("shell32.dll"); 489 | 490 | if (!advapi32) 491 | { 492 | std::cout << "advapi32.dll not found" << std::endl; 493 | return; 494 | } 495 | 496 | if (!kernel32) 497 | { 498 | std::cout << "kernel32.dll not found" << std::endl; 499 | return; 500 | } 501 | 502 | RegHooks::regdeletekeyw_addr = get_func_addr(advapi32, "RegDeleteKeyW"); 503 | RegHooks::regdeletevaluew_addr = get_func_addr(advapi32, "RegDeleteValueW"); 504 | RegHooks::regenumvaluew_addr = get_func_addr(advapi32, "RegEnumValueW"); 505 | RegHooks::regsetvalue_addr = get_func_addr(advapi32, "RegSetValueExW"); 506 | RegHooks::RegCreateKeyExW_addr = get_func_addr(advapi32, "RegCreateKeyExW"); 507 | RegHooks::RegConnectRegistryW_addr = get_func_addr(advapi32, "RegConnectRegistryW"); 508 | RegHooks::RegEnumKeyExW_addr = get_func_addr(advapi32, "RegEnumKeyExW"); 509 | RegHooks::RegQueryValueExW_addr = get_func_addr(advapi32, "RegQueryValueExW"); 510 | RegHooks::RegOpenKeyExW_addr = get_func_addr(advapi32, "RegOpenKeyExW"); 511 | RegHooks::CreateProcessW_addr = get_func_addr(kernel32, "CreateProcessW"); 512 | RegHooks::ShellExecuteExW_addr = get_func_addr(shell32, "ShellExecuteExW"); 513 | 514 | std::cout << "imports resolved\npreparing to hook" << std::endl; 515 | 516 | // reg hooks 517 | // 518 | DetourHelper::perf_hook((PVOID*)&RegHooks::regdeletekeyw_addr, RegHooks::hk_RegDeleteKeyW); 519 | DetourHelper::perf_hook((PVOID*)&RegHooks::regdeletevaluew_addr, RegHooks::hk_RegDeleteValueW); 520 | DetourHelper::perf_hook((PVOID*)&RegHooks::regenumvaluew_addr, RegHooks::hk_RegEnumValueW); 521 | DetourHelper::perf_hook((PVOID*)&RegHooks::regsetvalue_addr, RegHooks::hk_RegSetValueExW); 522 | DetourHelper::perf_hook((PVOID*)&RegHooks::RegCreateKeyExW_addr, RegHooks::hk_RegCreateKeyExW); 523 | DetourHelper::perf_hook((PVOID*)&RegHooks::RegConnectRegistryW_addr, RegHooks::hk_RegConnectRegistryW); 524 | DetourHelper::perf_hook((PVOID*)&RegHooks::RegEnumKeyExW_addr, RegHooks::hk_RegEnumKeyExW); 525 | DetourHelper::perf_hook((PVOID*)&RegHooks::RegQueryValueExW_addr, RegHooks::hk_RegQueryValueExW); 526 | DetourHelper::perf_hook((PVOID*)&RegHooks::RegOpenKeyExW_addr, RegHooks::hk_RegOpenKeyExW); 527 | DetourHelper::perf_hook((PVOID*)&RegHooks::CreateProcessW_addr, RegHooks::hk_CreateProcessW); 528 | DetourHelper::perf_hook((PVOID*)&RegHooks::ShellExecuteExW_addr, RegHooks::hk_ShellExecuteExW); 529 | 530 | // native hooks 531 | // 532 | #if 0 533 | RegHooks::enable_def_help_addr = (uintptr_t)GetModuleHandleA(0) + 0x6AB70; 534 | DetourHelper::perf_hook((PVOID*)&RegHooks::enable_def_help_addr, RegHooks::hk_enable_def); 535 | 536 | RegHooks::disable_def_addr = (uintptr_t)GetModuleHandleA(0) + 0x6AEAF; 537 | DetourHelper::perf_hook((PVOID*)&RegHooks::disable_def_addr, RegHooks::hk_disable_def); 538 | 539 | RegHooks::wmic_helper_addr = (uintptr_t)GetModuleHandleA(0) + 0x7A999; 540 | DetourHelper::perf_hook((PVOID*)&RegHooks::wmic_helper_addr, RegHooks::hk_wmic_helper); 541 | 542 | RegHooks::wmic_1_addr = (uintptr_t)GetModuleHandleA(0) + 0x6CDA0; 543 | DetourHelper::perf_hook((PVOID*)&RegHooks::wmic_1_addr, RegHooks::hk_wmic_1); 544 | 545 | RegHooks::wmic_2_addr = (uintptr_t)GetModuleHandleA(0) + 0x75ACA; 546 | DetourHelper::perf_hook((PVOID*)&RegHooks::wmic_2_addr, RegHooks::hk_wmic_2); 547 | 548 | RegHooks::ControlTable_addr = (uintptr_t)GetModuleHandleA(0) + 0x45E0; 549 | DetourHelper::perf_hook((PVOID*)&RegHooks::ControlTable_addr, RegHooks::hk_ControlTable); 550 | 551 | RegHooks::alt_start_proc_addr = (uintptr_t)GetModuleHandleA(0) + 0x464DC; 552 | DetourHelper::perf_hook((PVOID*)&RegHooks::alt_start_proc_addr, RegHooks::hk_alt_start_proc); 553 | 554 | RegHooks::cmdlinestuff_addr = (uintptr_t)GetModuleHandleA(0) + 0x63F19; 555 | DetourHelper::perf_hook((PVOID*)&RegHooks::cmdlinestuff_addr, RegHooks::hk_cmdlinestuff); 556 | 557 | RegHooks::StartProcWrapper_addr = (uintptr_t)GetModuleHandleA(0) + 0x33FA4; 558 | DetourHelper::perf_hook((PVOID*)&RegHooks::StartProcWrapper_addr, RegHooks::hk_StartProcWrapper); 559 | 560 | RegHooks::execute_shell_stuff_addr = (uintptr_t)GetModuleHandleA(0) + 0x33FA4; 561 | DetourHelper::perf_hook((PVOID*)&RegHooks::execute_shell_stuff_addr, RegHooks::hk_execute_shell_stuff); 562 | #endif 563 | } 564 | 565 | BOOL APIENTRY DllMain(HMODULE hModule, 566 | DWORD ul_reason_for_call, 567 | LPVOID lpReserved 568 | ) 569 | { 570 | switch (ul_reason_for_call) 571 | { 572 | case DLL_PROCESS_ATTACH: 573 | CreateThread(0, 0, reinterpret_cast(thread_main), 0, 0, 0); 574 | case DLL_THREAD_ATTACH: 575 | case DLL_THREAD_DETACH: 576 | case DLL_PROCESS_DETACH: 577 | break; 578 | } 579 | return TRUE; 580 | } 581 | 582 | -------------------------------------------------------------------------------- /src/dumper/dumper.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | {089CA7D6-3277-4998-86AF-F6413290A442} 24 | Win32Proj 25 | dumper 26 | 10.0 27 | 28 | 29 | 30 | DynamicLibrary 31 | true 32 | v143 33 | Unicode 34 | 35 | 36 | DynamicLibrary 37 | false 38 | v143 39 | true 40 | Unicode 41 | 42 | 43 | DynamicLibrary 44 | true 45 | v143 46 | Unicode 47 | 48 | 49 | DynamicLibrary 50 | false 51 | v143 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 | 79 | 80 | false 81 | $(SolutionDir)\detour\86\include;$(IncludePath) 82 | $(SolutionDir)\detour\86\lib;$(LibraryPath) 83 | 84 | 85 | false 86 | $(Platform)\$(Configuration) 87 | $(SolutionDir)\detour\64\include;$(IncludePath) 88 | $(SolutionDir)\detour\64\lib;$(LibraryPath) 89 | 90 | 91 | 92 | Use 93 | Level3 94 | true 95 | _DEBUG;DUMPER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 96 | true 97 | pch.h 98 | 99 | 100 | Windows 101 | true 102 | false 103 | 104 | 105 | 106 | 107 | Use 108 | Level3 109 | true 110 | WIN32;_DEBUG;DUMPER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 111 | true 112 | pch.h 113 | 114 | 115 | Windows 116 | true 117 | false 118 | 119 | 120 | 121 | 122 | Use 123 | Level3 124 | true 125 | true 126 | true 127 | WIN32;NDEBUG;DUMPER_EXPORTS;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 128 | true 129 | pch.h 130 | 131 | 132 | Windows 133 | true 134 | true 135 | true 136 | false 137 | 138 | 139 | 140 | 141 | Use 142 | Level3 143 | true 144 | true 145 | true 146 | NDEBUG;DUMPER_EXPORTS;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 147 | true 148 | pch.h 149 | 150 | 151 | Windows 152 | true 153 | true 154 | true 155 | false 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | Create 166 | Create 167 | Create 168 | Create 169 | 170 | 171 | 172 | 173 | 174 | -------------------------------------------------------------------------------- /src/dumper/dumper.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Header Files 20 | 21 | 22 | Header Files 23 | 24 | 25 | 26 | 27 | Source Files 28 | 29 | 30 | Source Files 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/dumper/framework.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers 4 | // Windows Header Files 5 | #include 6 | -------------------------------------------------------------------------------- /src/dumper/pch.cpp: -------------------------------------------------------------------------------- 1 | // pch.cpp: source file corresponding to the pre-compiled header 2 | 3 | #include "pch.h" 4 | 5 | // When you are using pre-compiled headers, this source file is necessary for compilation to succeed. 6 | // 7 | -------------------------------------------------------------------------------- /src/dumper/pch.h: -------------------------------------------------------------------------------- 1 | // pch.h: This is a precompiled header file. 2 | // Files listed below are compiled only once, improving build performance for future builds. 3 | // This also affects IntelliSense performance, including code completion and many code browsing features. 4 | // However, files listed here are ALL re-compiled if any one of them is updated between builds. 5 | // Do not add files here that you will be updating frequently as this negates the performance advantage. 6 | 7 | #ifndef PCH_H 8 | #define PCH_H 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #pragma comment(lib, "detours.lib") 17 | 18 | #endif //PCH_H 19 | --------------------------------------------------------------------------------