├── .gitattributes ├── .gitignore ├── README.md ├── Resurgence.sln ├── Resurgence ├── Resurgence.vcxproj ├── Resurgence.vcxproj.filters ├── include │ ├── headers.hpp │ ├── misc │ │ ├── exceptions.hpp │ │ ├── native.hpp │ │ └── safe_handle.hpp │ ├── native_enums.hpp │ ├── native_functions.hpp │ ├── native_structs.hpp │ ├── resurgence.hpp │ └── system │ │ ├── driver │ │ ├── TDL │ │ │ ├── TDL.cpp │ │ │ ├── TDL.h │ │ │ └── vbox.h │ │ ├── driver.hpp │ │ └── driver_shellcode.hpp │ │ ├── portable_executable.hpp │ │ ├── process.hpp │ │ ├── process_memory.hpp │ │ ├── process_modules.hpp │ │ ├── process_threads.hpp │ │ └── symbols │ │ └── symbol_system.hpp └── src │ ├── misc │ ├── native.cpp │ └── safe_handle.cpp │ └── system │ ├── driver │ ├── driver.cpp │ └── driver_shellcode.cpp │ ├── portable_executable.cpp │ ├── process.cpp │ ├── process_memory.cpp │ ├── process_modules.cpp │ ├── process_threads.cpp │ └── symbols │ └── symbol_system.cpp ├── ResurgenceDrv ├── ResurgenceDrv.h ├── ResurgenceDrv.vcxproj ├── dispatch.c ├── dispatch.h ├── driver_entry.c ├── imports.h ├── injection.c ├── injection.h ├── internal.c ├── internal.h ├── kernel_imports.h ├── memory.c ├── mmap.c ├── mmap.h ├── native_enums.h ├── native_structs.h ├── object.c ├── pe_structs.h ├── process.c ├── routines.c ├── routines.h ├── thread.c ├── utils.c ├── utils.h ├── zw_imports.c └── zw_imports.h └── TestApp ├── Source.cpp ├── TestApp.rc ├── TestApp.vcxproj └── resource.h /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | [Xx]64/ 19 | [Xx]86/ 20 | [Bb]uild/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opendb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | *.VC.db 84 | 85 | # Visual Studio profiler 86 | *.psess 87 | *.vsp 88 | *.vspx 89 | *.sap 90 | 91 | # TFS 2012 Local Workspace 92 | $tf/ 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | *.DotSettings.user 101 | 102 | # JustCode is a .NET coding add-in 103 | .JustCode 104 | 105 | # TeamCity is a build add-in 106 | _TeamCity* 107 | 108 | # DotCover is a Code Coverage Tool 109 | *.dotCover 110 | 111 | # NCrunch 112 | _NCrunch_* 113 | .*crunch*.local.xml 114 | nCrunchTemp_* 115 | 116 | # MightyMoose 117 | *.mm.* 118 | AutoTest.Net/ 119 | 120 | # Web workbench (sass) 121 | .sass-cache/ 122 | 123 | # Installshield output folder 124 | [Ee]xpress/ 125 | 126 | # DocProject is a documentation generator add-in 127 | DocProject/buildhelp/ 128 | DocProject/Help/*.HxT 129 | DocProject/Help/*.HxC 130 | DocProject/Help/*.hhc 131 | DocProject/Help/*.hhk 132 | DocProject/Help/*.hhp 133 | DocProject/Help/Html2 134 | DocProject/Help/html 135 | 136 | # Click-Once directory 137 | publish/ 138 | 139 | # Publish Web Output 140 | *.[Pp]ublish.xml 141 | *.azurePubxml 142 | 143 | # TODO: Un-comment the next line if you do not want to checkin 144 | # your web deploy settings because they may include unencrypted 145 | # passwords 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # NuGet Packages 150 | *.nupkg 151 | # The packages folder can be ignored because of Package Restore 152 | **/packages/* 153 | # except build/, which is used as an MSBuild target. 154 | !**/packages/build/ 155 | # Uncomment if necessary however generally it will be regenerated when needed 156 | #!**/packages/repositories.config 157 | # NuGet v3's project.json files produces more ignoreable files 158 | *.nuget.props 159 | *.nuget.targets 160 | 161 | # Microsoft Azure Build Output 162 | csx/ 163 | *.build.csdef 164 | 165 | # Microsoft Azure Emulator 166 | ecf/ 167 | rcf/ 168 | 169 | # Microsoft Azure ApplicationInsights config file 170 | ApplicationInsights.config 171 | 172 | # Windows Store app package directory 173 | AppPackages/ 174 | BundleArtifacts/ 175 | 176 | # Visual Studio cache files 177 | # files ending in .cache can be ignored 178 | *.[Cc]ache 179 | # but keep track of directories ending in .cache 180 | !*.[Cc]ache/ 181 | 182 | # Others 183 | ClientBin/ 184 | [Ss]tyle[Cc]op.* 185 | ~$* 186 | *~ 187 | *.dbmdl 188 | *.dbproj.schemaview 189 | *.pfx 190 | *.publishsettings 191 | node_modules/ 192 | orleans.codegen.cs 193 | 194 | # RIA/Silverlight projects 195 | Generated_Code/ 196 | 197 | # Backup & report files from converting an old project file 198 | # to a newer Visual Studio version. Backup files are not needed, 199 | # because we have git ;-) 200 | _UpgradeReport_Files/ 201 | Backup*/ 202 | UpgradeLog*.XML 203 | UpgradeLog*.htm 204 | 205 | # SQL Server files 206 | *.mdf 207 | *.ldf 208 | 209 | # Business Intelligence projects 210 | *.rdl.data 211 | *.bim.layout 212 | *.bim_*.settings 213 | 214 | # Microsoft Fakes 215 | FakesAssemblies/ 216 | 217 | # GhostDoc plugin setting file 218 | *.GhostDoc.xml 219 | 220 | # Node.js Tools for Visual Studio 221 | .ntvs_analysis.dat 222 | 223 | # Visual Studio 6 build log 224 | *.plg 225 | 226 | # Visual Studio 6 workspace options file 227 | *.opt 228 | 229 | # Visual Studio LightSwitch build output 230 | **/*.HTMLClient/GeneratedArtifacts 231 | **/*.DesktopClient/GeneratedArtifacts 232 | **/*.DesktopClient/ModelManifest.xml 233 | **/*.Server/GeneratedArtifacts 234 | **/*.Server/ModelManifest.xml 235 | _Pvt_Extensions 236 | 237 | # LightSwitch generated files 238 | GeneratedArtifacts/ 239 | ModelManifest.xml 240 | 241 | # Paket dependency manager 242 | .paket/paket.exe 243 | 244 | # FAKE - F# Make 245 | .fake/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Resurgence 2 | ====== 3 | 4 | ##### A *work in progress* project. 5 | 6 | Resurgence is a x86/x64 game hacking framework, althought it can be used for more than just game hacking (or that is the plan). 7 | 8 | Features are limited as of right now (again, WIP). 9 | 10 | ## Examples: 11 | 12 | #### Iterating over processes 13 | ```C++ 14 | using namespace resurgence; 15 | 16 | auto processes = system::process::get_processes(); 17 | 18 | for(auto& process : processes) { 19 | wcout << process.get_name() << ": " << ((process.get_platform() == system::platform_x86) ? "x86" : "x64") << endl; 20 | } 21 | ``` 22 | 23 | #### Retrieving process by name 24 | ```C++ 25 | using namespace resurgence; 26 | 27 | auto processes = system::process::get_process_by_name(L"notepad++.exe"); 28 | 29 | //There can be multiple processes with the same name 30 | for(auto& process : processes) { 31 | wcout << process.get_name() << ": " << ((process.get_platform() == system::platform_x86) ? "x86" : "x64") << endl; 32 | } 33 | ``` 34 | 35 | #### Listing process modules 36 | ```C++ 37 | using namespace resurgence; 38 | 39 | auto process = system::process::get_current_process(); 40 | 41 | wcout << process.get_name() << endl; 42 | for(auto& module : process.modules()->get_all_modules()) { 43 | wcout << " " << module.get_name() << endl; 44 | } 45 | ``` 46 | 47 | #### Reading/Writing to memory 48 | ```C++ 49 | using namespace resurgence; 50 | 51 | auto process = system::process::get_process_by_name(L"notepad++.exe").front(); 52 | 53 | if(failed(process.open(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE))) 54 | wcout << "Failed to open process" << endl; 55 | 56 | auto mainModule = process.modules()->get_module_by_load_order(0); 57 | auto mem = process.memory(); 58 | 59 | //Read value 60 | wcout << mem->read(mainModule.get_base()) << endl; 61 | 62 | //Change it 63 | mem->protect(mainModule.get_base(), PAGE_SIZE, PAGE_READWRITE); 64 | mem->write(mainModule.get_base(), 69); 65 | mem->protect(mainModule.get_base(), PAGE_SIZE, PAGE_READONLY); 66 | 67 | //Read again 68 | wcout << mem->read(mainModule.get_base()) << endl; 69 | ``` 70 | -------------------------------------------------------------------------------- /Resurgence.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Resurgence", "Resurgence\Resurgence.vcxproj", "{6872536E-3320-48D7-91A2-363B8CA39055}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestApp", "TestApp\TestApp.vcxproj", "{BBC7A05C-0562-40B9-859C-A7E2977C5D79}" 9 | ProjectSection(ProjectDependencies) = postProject 10 | {6872536E-3320-48D7-91A2-363B8CA39055} = {6872536E-3320-48D7-91A2-363B8CA39055} 11 | EndProjectSection 12 | EndProject 13 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ResurgenceDrv", "ResurgenceDrv\ResurgenceDrv.vcxproj", "{F2FEB18E-9FD6-4023-BB2B-BF3D41779514}" 14 | EndProject 15 | Global 16 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 17 | Debug|x64 = Debug|x64 18 | Debug|x86 = Debug|x86 19 | Release|x64 = Release|x64 20 | Release|x86 = Release|x86 21 | Win10|x64 = Win10|x64 22 | Win10|x86 = Win10|x86 23 | Win7|x64 = Win7|x64 24 | Win7|x86 = Win7|x86 25 | Win8.1|x64 = Win8.1|x64 26 | Win8.1|x86 = Win8.1|x86 27 | Win8|x64 = Win8|x64 28 | Win8|x86 = Win8|x86 29 | EndGlobalSection 30 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 31 | {6872536E-3320-48D7-91A2-363B8CA39055}.Debug|x64.ActiveCfg = Debug|x64 32 | {6872536E-3320-48D7-91A2-363B8CA39055}.Debug|x64.Build.0 = Debug|x64 33 | {6872536E-3320-48D7-91A2-363B8CA39055}.Debug|x86.ActiveCfg = Debug|Win32 34 | {6872536E-3320-48D7-91A2-363B8CA39055}.Debug|x86.Build.0 = Debug|Win32 35 | {6872536E-3320-48D7-91A2-363B8CA39055}.Release|x64.ActiveCfg = Release|x64 36 | {6872536E-3320-48D7-91A2-363B8CA39055}.Release|x64.Build.0 = Release|x64 37 | {6872536E-3320-48D7-91A2-363B8CA39055}.Release|x86.ActiveCfg = Release|Win32 38 | {6872536E-3320-48D7-91A2-363B8CA39055}.Release|x86.Build.0 = Release|Win32 39 | {6872536E-3320-48D7-91A2-363B8CA39055}.Win10|x64.ActiveCfg = Release|x64 40 | {6872536E-3320-48D7-91A2-363B8CA39055}.Win10|x64.Build.0 = Release|x64 41 | {6872536E-3320-48D7-91A2-363B8CA39055}.Win10|x86.ActiveCfg = Release|Win32 42 | {6872536E-3320-48D7-91A2-363B8CA39055}.Win10|x86.Build.0 = Release|Win32 43 | {6872536E-3320-48D7-91A2-363B8CA39055}.Win7|x64.ActiveCfg = Release|x64 44 | {6872536E-3320-48D7-91A2-363B8CA39055}.Win7|x64.Build.0 = Release|x64 45 | {6872536E-3320-48D7-91A2-363B8CA39055}.Win7|x86.ActiveCfg = Release|Win32 46 | {6872536E-3320-48D7-91A2-363B8CA39055}.Win7|x86.Build.0 = Release|Win32 47 | {6872536E-3320-48D7-91A2-363B8CA39055}.Win8.1|x64.ActiveCfg = Release|x64 48 | {6872536E-3320-48D7-91A2-363B8CA39055}.Win8.1|x64.Build.0 = Release|x64 49 | {6872536E-3320-48D7-91A2-363B8CA39055}.Win8.1|x86.ActiveCfg = Release|Win32 50 | {6872536E-3320-48D7-91A2-363B8CA39055}.Win8.1|x86.Build.0 = Release|Win32 51 | {6872536E-3320-48D7-91A2-363B8CA39055}.Win8|x64.ActiveCfg = Release|x64 52 | {6872536E-3320-48D7-91A2-363B8CA39055}.Win8|x64.Build.0 = Release|x64 53 | {6872536E-3320-48D7-91A2-363B8CA39055}.Win8|x86.ActiveCfg = Release|Win32 54 | {6872536E-3320-48D7-91A2-363B8CA39055}.Win8|x86.Build.0 = Release|Win32 55 | {BBC7A05C-0562-40B9-859C-A7E2977C5D79}.Debug|x64.ActiveCfg = Debug|x64 56 | {BBC7A05C-0562-40B9-859C-A7E2977C5D79}.Debug|x64.Build.0 = Debug|x64 57 | {BBC7A05C-0562-40B9-859C-A7E2977C5D79}.Debug|x86.ActiveCfg = Debug|Win32 58 | {BBC7A05C-0562-40B9-859C-A7E2977C5D79}.Debug|x86.Build.0 = Debug|Win32 59 | {BBC7A05C-0562-40B9-859C-A7E2977C5D79}.Release|x64.ActiveCfg = Release|x64 60 | {BBC7A05C-0562-40B9-859C-A7E2977C5D79}.Release|x64.Build.0 = Release|x64 61 | {BBC7A05C-0562-40B9-859C-A7E2977C5D79}.Release|x86.ActiveCfg = Release|Win32 62 | {BBC7A05C-0562-40B9-859C-A7E2977C5D79}.Release|x86.Build.0 = Release|Win32 63 | {BBC7A05C-0562-40B9-859C-A7E2977C5D79}.Win10|x64.ActiveCfg = Release|x64 64 | {BBC7A05C-0562-40B9-859C-A7E2977C5D79}.Win10|x64.Build.0 = Release|x64 65 | {BBC7A05C-0562-40B9-859C-A7E2977C5D79}.Win10|x86.ActiveCfg = Release|Win32 66 | {BBC7A05C-0562-40B9-859C-A7E2977C5D79}.Win10|x86.Build.0 = Release|Win32 67 | {BBC7A05C-0562-40B9-859C-A7E2977C5D79}.Win7|x64.ActiveCfg = Release|x64 68 | {BBC7A05C-0562-40B9-859C-A7E2977C5D79}.Win7|x64.Build.0 = Release|x64 69 | {BBC7A05C-0562-40B9-859C-A7E2977C5D79}.Win7|x86.ActiveCfg = Release|Win32 70 | {BBC7A05C-0562-40B9-859C-A7E2977C5D79}.Win7|x86.Build.0 = Release|Win32 71 | {BBC7A05C-0562-40B9-859C-A7E2977C5D79}.Win8.1|x64.ActiveCfg = Release|x64 72 | {BBC7A05C-0562-40B9-859C-A7E2977C5D79}.Win8.1|x64.Build.0 = Release|x64 73 | {BBC7A05C-0562-40B9-859C-A7E2977C5D79}.Win8.1|x86.ActiveCfg = Release|Win32 74 | {BBC7A05C-0562-40B9-859C-A7E2977C5D79}.Win8.1|x86.Build.0 = Release|Win32 75 | {BBC7A05C-0562-40B9-859C-A7E2977C5D79}.Win8|x64.ActiveCfg = Release|x64 76 | {BBC7A05C-0562-40B9-859C-A7E2977C5D79}.Win8|x64.Build.0 = Release|x64 77 | {BBC7A05C-0562-40B9-859C-A7E2977C5D79}.Win8|x86.ActiveCfg = Release|Win32 78 | {BBC7A05C-0562-40B9-859C-A7E2977C5D79}.Win8|x86.Build.0 = Release|Win32 79 | {F2FEB18E-9FD6-4023-BB2B-BF3D41779514}.Debug|x64.ActiveCfg = Debug|x64 80 | {F2FEB18E-9FD6-4023-BB2B-BF3D41779514}.Debug|x64.Deploy.0 = Debug|x64 81 | {F2FEB18E-9FD6-4023-BB2B-BF3D41779514}.Debug|x86.ActiveCfg = Debug|x64 82 | {F2FEB18E-9FD6-4023-BB2B-BF3D41779514}.Release|x64.ActiveCfg = Release|x64 83 | {F2FEB18E-9FD6-4023-BB2B-BF3D41779514}.Release|x64.Build.0 = Release|x64 84 | {F2FEB18E-9FD6-4023-BB2B-BF3D41779514}.Release|x64.Deploy.0 = Release|x64 85 | {F2FEB18E-9FD6-4023-BB2B-BF3D41779514}.Release|x86.ActiveCfg = Release|x64 86 | {F2FEB18E-9FD6-4023-BB2B-BF3D41779514}.Win10|x64.ActiveCfg = Win10|x64 87 | {F2FEB18E-9FD6-4023-BB2B-BF3D41779514}.Win10|x64.Build.0 = Win10|x64 88 | {F2FEB18E-9FD6-4023-BB2B-BF3D41779514}.Win10|x64.Deploy.0 = Win10|x64 89 | {F2FEB18E-9FD6-4023-BB2B-BF3D41779514}.Win10|x86.ActiveCfg = Win10|x64 90 | {F2FEB18E-9FD6-4023-BB2B-BF3D41779514}.Win7|x64.ActiveCfg = Win7|x64 91 | {F2FEB18E-9FD6-4023-BB2B-BF3D41779514}.Win7|x64.Build.0 = Win7|x64 92 | {F2FEB18E-9FD6-4023-BB2B-BF3D41779514}.Win7|x64.Deploy.0 = Win7|x64 93 | {F2FEB18E-9FD6-4023-BB2B-BF3D41779514}.Win7|x86.ActiveCfg = Win7|x64 94 | {F2FEB18E-9FD6-4023-BB2B-BF3D41779514}.Win8.1|x64.ActiveCfg = Win8.1|x64 95 | {F2FEB18E-9FD6-4023-BB2B-BF3D41779514}.Win8.1|x64.Build.0 = Win8.1|x64 96 | {F2FEB18E-9FD6-4023-BB2B-BF3D41779514}.Win8.1|x64.Deploy.0 = Win8.1|x64 97 | {F2FEB18E-9FD6-4023-BB2B-BF3D41779514}.Win8.1|x86.ActiveCfg = Win8.1|x64 98 | {F2FEB18E-9FD6-4023-BB2B-BF3D41779514}.Win8|x64.ActiveCfg = Win8|x64 99 | {F2FEB18E-9FD6-4023-BB2B-BF3D41779514}.Win8|x64.Build.0 = Win8|x64 100 | {F2FEB18E-9FD6-4023-BB2B-BF3D41779514}.Win8|x64.Deploy.0 = Win8|x64 101 | {F2FEB18E-9FD6-4023-BB2B-BF3D41779514}.Win8|x86.ActiveCfg = Win8|x64 102 | EndGlobalSection 103 | GlobalSection(SolutionProperties) = preSolution 104 | HideSolutionNode = FALSE 105 | EndGlobalSection 106 | EndGlobal 107 | -------------------------------------------------------------------------------- /Resurgence/Resurgence.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 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | {6872536E-3320-48D7-91A2-363B8CA39055} 56 | Resurgence 57 | 10.0.10586.0 58 | 59 | 60 | 61 | StaticLibrary 62 | true 63 | v140 64 | Unicode 65 | 66 | 67 | StaticLibrary 68 | false 69 | v140 70 | true 71 | Unicode 72 | 73 | 74 | StaticLibrary 75 | true 76 | v140 77 | Unicode 78 | 79 | 80 | StaticLibrary 81 | false 82 | v140 83 | true 84 | Unicode 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | $(SolutionDir)bin\$(Platform)\lib\ 106 | $(SolutionDir)build\$(ProjectName)\$(Platform)\$(Configuration)\ 107 | Resurgence_d 108 | .lib 109 | $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)\include\ 110 | 111 | 112 | $(SolutionDir)bin\$(Platform)\lib\ 113 | $(SolutionDir)build\$(ProjectName)\$(Platform)\$(Configuration)\ 114 | Resurgence 115 | .lib 116 | $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)\include\ 117 | 118 | 119 | $(SolutionDir)bin\$(Platform)\lib\ 120 | $(SolutionDir)build\$(ProjectName)\$(Platform)\$(Configuration)\ 121 | Resurgence_d 122 | .lib 123 | $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)\include\ 124 | 125 | 126 | $(SolutionDir)bin\$(Platform)\lib\ 127 | $(SolutionDir)build\$(ProjectName)\$(Platform)\$(Configuration)\ 128 | Resurgence 129 | .lib 130 | $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)\include\ 131 | 132 | 133 | 134 | Level3 135 | Disabled 136 | false 137 | 4996; 4302; 4311; 4312 138 | true 139 | Cdecl 140 | 141 | 142 | 143 | 144 | MachineX86 145 | 146 | 147 | 148 | 149 | Level3 150 | Disabled 151 | false 152 | 4996; 4302; 4311; 4312 153 | true 154 | Cdecl 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | Level3 164 | MaxSpeed 165 | true 166 | true 167 | false 168 | true 169 | 4996; 4302; 4311; 4312 170 | true 171 | AnySuitable 172 | Speed 173 | Cdecl 174 | 175 | 176 | true 177 | true 178 | 179 | 180 | true 181 | 182 | 183 | MachineX86 184 | 185 | 186 | 187 | 188 | Level3 189 | MaxSpeed 190 | true 191 | true 192 | false 193 | true 194 | 4996; 4302; 4311; 4312 195 | true 196 | AnySuitable 197 | Speed 198 | Cdecl 199 | 200 | 201 | true 202 | true 203 | 204 | 205 | true 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | -------------------------------------------------------------------------------- /Resurgence/Resurgence.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;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 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | Header Files 32 | 33 | 34 | Header Files 35 | 36 | 37 | Header Files 38 | 39 | 40 | Header Files 41 | 42 | 43 | Header Files 44 | 45 | 46 | Header Files 47 | 48 | 49 | Header Files 50 | 51 | 52 | Header Files 53 | 54 | 55 | Header Files 56 | 57 | 58 | Header Files 59 | 60 | 61 | Header Files 62 | 63 | 64 | Header Files 65 | 66 | 67 | Header Files 68 | 69 | 70 | Header Files 71 | 72 | 73 | 74 | 75 | Source Files 76 | 77 | 78 | Source Files 79 | 80 | 81 | Source Files 82 | 83 | 84 | Source Files 85 | 86 | 87 | Source Files 88 | 89 | 90 | Source Files 91 | 92 | 93 | Source Files 94 | 95 | 96 | Source Files 97 | 98 | 99 | Source Files 100 | 101 | 102 | Source Files 103 | 104 | 105 | Source Files 106 | 107 | 108 | -------------------------------------------------------------------------------- /Resurgence/include/headers.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #pragma warning(disable: 4005) // macro redefinition 4 | #pragma warning(disable: 4152) // nonstandard extension, function/data pointer conversion in expression 5 | #pragma warning(disable: 4201) // nonstandard extension used : nameless struct/union 6 | #pragma warning(disable: 6102) // Using %s from !NT_SUCCESS function call at line %u 7 | #pragma warning(disable: 6320) // exception-filter expression is the constant EXCEPTION_EXECUTE_HANDLER 8 | 9 | typedef long NTSTATUS; 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #ifndef PTR_ADD 22 | #define PTR_ADD(ptr, off) ((uint8_t*)ptr + off) 23 | #endif 24 | 25 | #if !defined PAGE_SIZE 26 | #define PAGE_SIZE 0x1000 27 | #endif 28 | 29 | #if !defined(DEFAULT_DRIVER_NAMES) 30 | #define DEFAULT_DRIVER_NAMES 31 | #define DEFAULT_DRIVER_WIN7 TEXT(".\\ResurgenceDrvWin7.sys") 32 | #define DEFAULT_DRIVER_WIN8 TEXT(".\\ResurgenceDrvWin8.sys") 33 | #define DEFAULT_DRIVER_WIN81 TEXT(".\\ResurgenceDrvWin81.sys") 34 | #define DEFAULT_DRIVER_WIN10 TEXT(".\\ResurgenceDrvWin10.sys") 35 | #endif 36 | 37 | __forceinline NTSTATUS get_last_ntstatus() 38 | { 39 | return NtCurrentTeb()->LastStatusValue; 40 | } 41 | __forceinline NTSTATUS set_last_ntstatus(NTSTATUS status) 42 | { 43 | return NtCurrentTeb()->LastStatusValue = status; 44 | } 45 | -------------------------------------------------------------------------------- /Resurgence/include/misc/exceptions.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #ifdef GetMessage 9 | #undef GetMessage 10 | #endif 11 | 12 | namespace resurgence 13 | { 14 | namespace misc 15 | { 16 | class exception 17 | { 18 | public: 19 | exception() 20 | : _message(L"") 21 | { 22 | } 23 | 24 | exception(std::wstring msg) 25 | : _message(std::move(msg)) 26 | { 27 | } 28 | exception(std::string msg) 29 | { 30 | std::wstring_convert, wchar_t> converter; 31 | _message = converter.from_bytes(msg); 32 | } 33 | virtual ~exception() 34 | { 35 | } 36 | virtual const std::wstring& get_message() const 37 | { 38 | return _message; 39 | } 40 | 41 | protected: 42 | std::wstring _message; 43 | }; 44 | 45 | class file_not_found_exception 46 | : public exception 47 | { 48 | public: 49 | file_not_found_exception() 50 | : exception() 51 | { 52 | } 53 | file_not_found_exception(std::wstring msg) 54 | : exception(msg) 55 | { 56 | } 57 | file_not_found_exception(std::string msg) 58 | : exception(msg) 59 | { 60 | } 61 | }; 62 | 63 | class win32_exception 64 | : public exception 65 | { 66 | public: 67 | win32_exception(NTSTATUS status) 68 | : exception(L"A Win32 routine !NT_SUCCESS."), _status(status) 69 | { 70 | 71 | } 72 | win32_exception(std::wstring msg, NTSTATUS status) 73 | : exception(msg), _status(status) 74 | { 75 | 76 | } 77 | win32_exception(std::string msg, NTSTATUS status) 78 | : exception(msg), _status(status) 79 | { 80 | 81 | } 82 | 83 | NTSTATUS get_status() const 84 | { 85 | return _status; 86 | } 87 | 88 | protected: 89 | NTSTATUS _status; 90 | }; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /Resurgence/include/misc/safe_handle.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace resurgence 6 | { 7 | namespace misc 8 | { 9 | namespace detail 10 | { 11 | class safe_handle 12 | { 13 | public: 14 | safe_handle(HANDLE invalidValue); 15 | safe_handle(HANDLE value, HANDLE invalidValue); 16 | safe_handle(const safe_handle& rhs); 17 | virtual ~safe_handle(); 18 | 19 | HANDLE get() const; 20 | void set(HANDLE value); 21 | void close(); 22 | bool is_valid() const; 23 | uint32_t access_mask() const; 24 | void update_access(); 25 | bool has_access(uint32_t access) const; 26 | 27 | virtual safe_handle& operator=(const safe_handle& rhs); 28 | 29 | protected: 30 | void duplicate(safe_handle& other) const; 31 | 32 | HANDLE _value; 33 | HANDLE _invalid; 34 | uint32_t _grantedBits; 35 | }; 36 | } 37 | 38 | class safe_process_handle 39 | : public detail::safe_handle 40 | { 41 | public: 42 | safe_process_handle(); 43 | safe_process_handle(HANDLE value); 44 | safe_process_handle(const safe_process_handle& rhs); 45 | virtual ~safe_process_handle() {} 46 | }; 47 | 48 | class safe_generic_handle 49 | : public detail::safe_handle 50 | { 51 | public: 52 | safe_generic_handle(); 53 | safe_generic_handle(HANDLE value); 54 | safe_generic_handle(const safe_generic_handle& rhs); 55 | virtual ~safe_generic_handle() {} 56 | }; 57 | } 58 | } -------------------------------------------------------------------------------- /Resurgence/include/resurgence.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | -------------------------------------------------------------------------------- /Resurgence/include/system/driver/TDL/TDL.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | long __stdcall TDLload_driver( 10 | LPCWSTR lpDriverFullName 11 | ); 12 | 13 | #ifdef __cplusplus 14 | } 15 | #endif 16 | -------------------------------------------------------------------------------- /Resurgence/include/system/driver/TDL/vbox.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef void* RTR0PTR; 4 | 5 | typedef struct _SUPREQHDR 6 | { 7 | /** Cookie. */ 8 | uint32_t u32Cookie; 9 | /** Session cookie. */ 10 | uint32_t u32SessionCookie; 11 | /** The size of the input. */ 12 | uint32_t cbIn; 13 | /** The size of the output. */ 14 | uint32_t cbOut; 15 | /** Flags. See SUPREQHDR_FLAGS_* for details and values. */ 16 | uint32_t fFlags; 17 | /** The VBox status code of the operation, out direction only. */ 18 | int32_t rc; 19 | } SUPREQHDR; 20 | 21 | /** SUP_IOCTL_COOKIE. */ 22 | typedef struct _SUPCOOKIE 23 | { 24 | /** The header. 25 | * u32Cookie must be set to SUPCOOKIE_INITIAL_COOKIE. 26 | * u32SessionCookie should be set to some random value. */ 27 | SUPREQHDR Hdr; 28 | union 29 | { 30 | struct 31 | { 32 | /** Magic word. */ 33 | char szMagic[16]; 34 | /** The requested interface version number. */ 35 | uint32_t u32ReqVersion; 36 | /** The minimum interface version number. */ 37 | uint32_t u32MinVersion; 38 | } In; 39 | struct 40 | { 41 | /** Cookie. */ 42 | uint32_t u32Cookie; 43 | /** Session cookie. */ 44 | uint32_t u32SessionCookie; 45 | /** Interface version for this session. */ 46 | uint32_t u32SessionVersion; 47 | /** The actual interface version in the driver. */ 48 | uint32_t u32DriverVersion; 49 | /** Number of functions available for the SUP_IOCTL_QUERY_FUNCS request. */ 50 | uint32_t cFunctions; 51 | /** Session handle. */ 52 | /*R0PTRTYPE(PSUPDRVSESSION)*/ PVOID pSession; 53 | } Out; 54 | } u; 55 | } SUPCOOKIE, *PSUPCOOKIE; 56 | 57 | typedef struct _SUPLDROPEN 58 | { 59 | /** The header. */ 60 | SUPREQHDR Hdr; 61 | union 62 | { 63 | struct 64 | { 65 | /** size of the image we'll be loading. */ 66 | uint32_t cbImage; 67 | /** Image name. 68 | * This is the NAME of the image, not the file name. It is used 69 | * to share code with other processes. (Max len is 32 chars!) */ 70 | char szName[32]; 71 | } In; 72 | struct 73 | { 74 | /** The base address of the image. */ 75 | RTR0PTR pvImageBase; 76 | /** Indicate whether or not the image requires loading. */ 77 | BOOLEAN fNeedsLoading; 78 | } Out; 79 | } u; 80 | } SUPLDROPEN, *PSUPLDROPEN; 81 | 82 | typedef enum _SUPLDRLOADEP 83 | { 84 | SUPLDRLOADEP_NOTHING = 0, 85 | SUPLDRLOADEP_VMMR0, 86 | SUPLDRLOADEP_SERVICE, 87 | SUPLDRLOADEP_32BIT_HACK = 0x7fffffff 88 | } SUPLDRLOADEP; 89 | 90 | typedef struct _SUPSETVMFORFAST 91 | { 92 | /** The header. */ 93 | SUPREQHDR Hdr; 94 | union 95 | { 96 | struct 97 | { 98 | /** The ring-0 VM handle (pointer). */ 99 | PVOID pVMR0; 100 | } In; 101 | } u; 102 | } SUPSETVMFORFAST, *PSUPSETVMFORFAST; 103 | 104 | typedef struct _SUPLDRLOAD 105 | { 106 | /** The header. */ 107 | SUPREQHDR Hdr; 108 | union 109 | { 110 | struct 111 | { 112 | /** The address of module initialization function. Similar to _DLL_InitTerm(hmod, 0). */ 113 | PVOID pfnModuleInit; 114 | /** The address of module termination function. Similar to _DLL_InitTerm(hmod, 1). */ 115 | PVOID pfnModuleTerm; 116 | /** Special entry points. */ 117 | union 118 | { 119 | /** SUPLDRLOADEP_VMMR0. */ 120 | struct 121 | { 122 | /** The module handle (i.e. address). */ 123 | RTR0PTR pvVMMR0; 124 | /** Address of VMMR0EntryInt function. */ 125 | RTR0PTR pvVMMR0EntryInt; 126 | /** Address of VMMR0EntryFast function. */ 127 | RTR0PTR pvVMMR0EntryFast; 128 | /** Address of VMMR0EntryEx function. */ 129 | RTR0PTR pvVMMR0EntryEx; 130 | } VMMR0; 131 | /** SUPLDRLOADEP_SERVICE. */ 132 | struct 133 | { 134 | /** The service request handler. 135 | * (PFNR0SERVICEREQHANDLER isn't defined yet.) */ 136 | RTR0PTR pfnServiceReq; 137 | /** Reserved, must be NIL. */ 138 | RTR0PTR apvReserved[3]; 139 | } Service; 140 | } EP; 141 | /** Address. */ 142 | RTR0PTR pvImageBase; 143 | /** Entry point type. */ 144 | SUPLDRLOADEP eEPType; 145 | /** The offset of the symbol table. */ 146 | uint32_t offSymbols; 147 | /** The number of entries in the symbol table. */ 148 | uint32_t cSymbols; 149 | /** The offset of the string table. */ 150 | uint32_t offStrTab; 151 | /** size of the string table. */ 152 | uint32_t cbStrTab; 153 | /** size of image (including string and symbol tables). */ 154 | uint32_t cbImage; 155 | /** The image data. */ 156 | char achImage[1]; 157 | } In; 158 | } u; 159 | } SUPLDRLOAD, *PSUPLDRLOAD; 160 | 161 | 162 | #define RT_SIZEOFMEMB(type, member) ( sizeof(((type *)(void *)0)->member) ) 163 | #define SUPCOOKIE_INITIAL_COOKIE 0x69726f74 /* 'tori' */ 164 | #define SUP_IOCTL_COOKIE_SIZE_IN sizeof(SUPREQHDR) + RT_SIZEOFMEMB(SUPCOOKIE, u.In) 165 | #define SUP_IOCTL_COOKIE_SIZE_OUT sizeof(SUPREQHDR) + RT_SIZEOFMEMB(SUPCOOKIE, u.Out) 166 | 167 | #define SUP_IOCTL_FLAG 128 168 | 169 | #define SUP_CTL_CODE_SIZE(Function, size) CTL_CODE(FILE_DEVICE_UNKNOWN, (Function) | SUP_IOCTL_FLAG, METHOD_BUFFERED, FILE_WRITE_ACCESS) 170 | #define SUP_CTL_CODE_BIG(Function) CTL_CODE(FILE_DEVICE_UNKNOWN, (Function) | SUP_IOCTL_FLAG, METHOD_BUFFERED, FILE_WRITE_ACCESS) 171 | #define SUP_CTL_CODE_FAST(Function) CTL_CODE(FILE_DEVICE_UNKNOWN, (Function) | SUP_IOCTL_FLAG, METHOD_NEITHER, FILE_WRITE_ACCESS) 172 | #define SUP_CTL_CODE_NO_SIZE(uIOCtl) (uIOCtl) 173 | 174 | /** The magic value. */ 175 | #define SUPREQHDR_FLAGS_MAGIC UINT32_C(0x42000042) 176 | /** The default value. Use this when no special stuff is requested. */ 177 | #define SUPREQHDR_FLAGS_DEFAULT SUPREQHDR_FLAGS_MAGIC 178 | #define VERR_INTERNAL_ERROR (-225) 179 | #define SUPCOOKIE_MAGIC "The Magic Word!" 180 | #define SUPDRV_IOC_VERSION 0x001a0007 181 | /** The request size. */ 182 | #define SUP_IOCTL_COOKIE_SIZE sizeof(SUPCOOKIE) 183 | /** Negotiate cookie. */ 184 | #define SUP_IOCTL_COOKIE SUP_CTL_CODE_SIZE(1, SUP_IOCTL_COOKIE_SIZE) 185 | 186 | /** There is extra input that needs copying on some platforms. */ 187 | #define SUPREQHDR_FLAGS_EXTRA_IN UINT32_C(0x00000100) 188 | /** There is extra output that needs copying on some platforms. */ 189 | #define SUPREQHDR_FLAGS_EXTRA_OUT UINT32_C(0x00000200) 190 | 191 | /** @name SUP_IOCTL_SET_VM_FOR_FAST 192 | * Set the VM handle for doing fast call ioctl calls. 193 | * @{ 194 | */ 195 | #define SUP_IOCTL_SET_VM_FOR_FAST SUP_CTL_CODE_SIZE(19, SUP_IOCTL_SET_VM_FOR_FAST_SIZE) 196 | #define SUP_IOCTL_SET_VM_FOR_FAST_SIZE sizeof(SUPSETVMFORFAST) 197 | #define SUP_IOCTL_SET_VM_FOR_FAST_SIZE_IN sizeof(SUPSETVMFORFAST) 198 | #define SUP_IOCTL_SET_VM_FOR_FAST_SIZE_OUT sizeof(SUPREQHDR) 199 | #define SUP_IOCTL_FAST_DO_NOP SUP_CTL_CODE_FAST(66) 200 | 201 | #define SUP_IOCTL_LDR_OPEN SUP_CTL_CODE_SIZE(5, SUP_IOCTL_LDR_OPEN_SIZE) 202 | #define SUP_IOCTL_LDR_OPEN_SIZE sizeof(SUPLDROPEN) 203 | #define SUP_IOCTL_LDR_OPEN_SIZE_IN sizeof(SUPLDROPEN) 204 | #define SUP_IOCTL_LDR_OPEN_SIZE_OUT (sizeof(SUPREQHDR) + RT_SIZEOFMEMB(SUPLDROPEN, u.Out)) 205 | 206 | #define SUP_IOCTL_LDR_LOAD SUP_CTL_CODE_BIG(6) 207 | #define SUP_IOCTL_LDR_LOAD_SIZE(cbImage) RT_UOFFSETOF(SUPLDRLOAD, u.In.achImage[cbImage]) 208 | #define SUP_IOCTL_LDR_LOAD_SIZE_IN(cbImage) RT_UOFFSETOF(SUPLDRLOAD, u.In.achImage[cbImage]) 209 | #define SUP_IOCTL_LDR_LOAD_SIZE_OUT sizeof(SUPREQHDR) 210 | 211 | /** @name SUP_IOCTL_LDR_FREE 212 | * Free an image. 213 | * @{ 214 | */ 215 | #define SUP_IOCTL_LDR_FREE SUP_CTL_CODE_SIZE(7, SUP_IOCTL_LDR_FREE_SIZE) 216 | #define SUP_IOCTL_LDR_FREE_SIZE sizeof(SUPLDRFREE) 217 | #define SUP_IOCTL_LDR_FREE_SIZE_IN sizeof(SUPLDRFREE) 218 | #define SUP_IOCTL_LDR_FREE_SIZE_OUT sizeof(SUPREQHDR) 219 | 220 | typedef struct _SUPLDRFREE 221 | { 222 | /** The header. */ 223 | SUPREQHDR Hdr; 224 | union 225 | { 226 | struct 227 | { 228 | /** Address. */ 229 | RTR0PTR pvImageBase; 230 | } In; 231 | } u; 232 | } SUPLDRFREE, *PSUPLDRFREE; 233 | -------------------------------------------------------------------------------- /Resurgence/include/system/driver/driver.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "../../../../ResurgenceDrv/ResurgenceDrv.h" 9 | 10 | namespace resurgence 11 | { 12 | namespace system 13 | { 14 | enum driver_load_method 15 | { 16 | SCManager, 17 | Turla 18 | }; 19 | 20 | class driver 21 | { 22 | public: 23 | /// 24 | /// Constructor. 25 | /// 26 | /// The driver path. 27 | driver(const std::wstring& path); 28 | 29 | /// 30 | /// Destructor. 31 | /// 32 | ~driver(); 33 | 34 | /// 35 | /// Check if the driver is already loaded on the system. 36 | /// 37 | /// 38 | /// TRUE if loaded, FALSE otherwise. 39 | /// 40 | BOOL is_loaded(); 41 | 42 | /// 43 | /// Loads the driver. 44 | /// 45 | /// The load method. 46 | /// 47 | /// The status code. 48 | /// 49 | NTSTATUS load(driver_load_method method); 50 | 51 | /// 52 | /// Query the OS version. 53 | /// 54 | /// The version info. 55 | /// 56 | /// The status code. 57 | /// 58 | NTSTATUS query_version_info(PVERSION_INFO version); 59 | 60 | // 61 | // Virtual Memory Management 62 | // 63 | 64 | /// 65 | /// Allocate virtual memory. 66 | /// 67 | /// The process id. 68 | /// The allocation base. 69 | /// The allocation size. 70 | /// The allocation flags. 71 | /// The protection flags. 72 | /// 73 | /// The status code. 74 | /// 75 | NTSTATUS allocate_virtual_memory(uint32_t pid, uint8_t** baseAddress, size_t* regionSize, uint32_t allocation, uint32_t protection); 76 | 77 | /// 78 | /// Allocate virtual memory. 79 | /// 80 | /// The process id. 81 | /// The start address. 82 | /// The region size. 83 | /// The new protection. 84 | /// The old protection. 85 | /// 86 | /// The status code. 87 | /// 88 | NTSTATUS protect_virtual_memory(uint32_t pid, uint8_t* baseAddress, size_t regionSize, uint32_t newProtection, uint32_t* oldProtection); 89 | 90 | /// 91 | /// Free virtual memory. 92 | /// 93 | /// The process id. 94 | /// The start address. 95 | /// The region size. 96 | /// The free type. 97 | /// 98 | /// The status code. 99 | /// 100 | NTSTATUS free_virtual_memory(uint32_t pid, uint8_t* baseAddress, size_t regionSize, uint32_t freeType); 101 | 102 | /// 103 | /// Query memory information. 104 | /// 105 | /// The process id. 106 | /// The base address. 107 | /// The returned memory information. 108 | /// 109 | /// The status code. 110 | /// 111 | NTSTATUS query_virtual_memory(uint32_t pid, uint8_t* baseAddress, PMEMORY_BASIC_INFORMATION memoryInfo); 112 | 113 | /// 114 | /// Read virtual memory. 115 | /// 116 | /// The process id. 117 | /// The base address. 118 | /// The buffer. 119 | /// The buffer size. 120 | /// 121 | /// The status code. 122 | /// 123 | NTSTATUS read_virtual_memory(uint32_t pid, const uint8_t* baseAddress, uint8_t* buffer, size_t length); 124 | 125 | /// 126 | /// Write virtual memory. 127 | /// 128 | /// The process id. 129 | /// The base address. 130 | /// The buffer. 131 | /// The buffer size. 132 | /// 133 | /// The status code. 134 | /// 135 | NTSTATUS write_virtual_memory(uint32_t pid, const uint8_t* baseAddress, uint8_t* buffer, size_t length); 136 | 137 | // 138 | // Process/Thread Management 139 | // 140 | 141 | /// 142 | /// Opens a process. 143 | /// 144 | /// The process id. 145 | /// The desired access. 146 | /// The returned handle. 147 | /// 148 | /// The status code. 149 | /// 150 | NTSTATUS open_process(uint32_t pid, uint32_t access, PHANDLE handle); 151 | 152 | /// 153 | /// Opens the process that contains the target thread. 154 | /// 155 | /// The thread id. 156 | /// The desired access. 157 | /// The returned handle. 158 | /// 159 | /// The status code. 160 | /// 161 | NTSTATUS open_process_with_thread(uint32_t tid, uint32_t access, PHANDLE handle); 162 | 163 | /// 164 | /// Opens a thread. 165 | /// 166 | /// The thread id. 167 | /// The desired access. 168 | /// The returned handle. 169 | /// 170 | /// The status code. 171 | /// 172 | NTSTATUS open_thread(uint32_t tid, uint32_t access, PHANDLE handle); 173 | 174 | /// 175 | /// Grants access to a handle. 176 | /// 177 | /// The process id (current process on most cases). 178 | /// The target handle. 179 | /// The desired access. 180 | /// The old access. 181 | /// 182 | /// The status code. 183 | /// 184 | NTSTATUS grant_handle_access(uint32_t pid, HANDLE handle, uint32_t access, uint32_t* oldAccess); 185 | 186 | /// 187 | /// Set process protection. 188 | /// 189 | /// The process id. 190 | /// The protection level (0: None. 1: Light. 2: Full). 191 | /// 192 | /// The status code. 193 | /// 194 | NTSTATUS set_process_protection(uint32_t pid, uint32_t protectionLevel); 195 | 196 | /// 197 | /// Enables or disables DEP. 198 | /// 199 | /// The process id. 200 | /// The DEP state. 201 | /// 202 | /// The status code. 203 | /// 204 | NTSTATUS set_process_dep(uint32_t pid, bool enable); 205 | 206 | /// 207 | /// Injects a module. 208 | /// 209 | /// The process id. 210 | /// The module path. 211 | /// Erase headers. 212 | /// Hide module. 213 | /// The returned module base. 214 | /// 215 | /// The status code. 216 | /// 217 | NTSTATUS inject_module(uint32_t pid, const std::wstring& modulePath, bool eraseHeaders, bool hideModule, uintptr_t* baseAddress); 218 | 219 | /// 220 | /// Maps a module to the process. 221 | /// 222 | /// The process id. 223 | /// The module base. 224 | /// The module size. 225 | /// Erase headers. 226 | /// Hide module. 227 | /// The returned module base. 228 | /// 229 | /// The status code. 230 | /// 231 | NTSTATUS mmap_module(uint32_t pid, const uint8_t* moduleBase, size_t moduleSize, bool eraseHeaders, bool hideModule, uintptr_t* baseAddress); 232 | 233 | 234 | /// 235 | /// Maps a module to the process. 236 | /// 237 | /// The process id. 238 | /// The module path. 239 | /// Erase headers. 240 | /// Hide module. 241 | /// The returned module base. 242 | /// 243 | /// The status code. 244 | /// 245 | NTSTATUS mmap_module(uint32_t pid, const std::wstring& modulePath, bool eraseHeaders, bool hideModule, uintptr_t* baseAddress); 246 | 247 | private: 248 | NTSTATUS open(); 249 | 250 | std::wstring _path; 251 | HANDLE _handle; 252 | }; 253 | } 254 | } -------------------------------------------------------------------------------- /Resurgence/include/system/driver/driver_shellcode.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace resurgence 6 | { 7 | namespace Internal 8 | { 9 | extern uint32_t g_pVulnerableDriverData[17072]; 10 | extern uint8_t g_pLoaderCode[463]; 11 | 12 | #define SHELLCODE_VULNERABLE_DRIVER_SIZE (17072 * 4) 13 | #define SHELLCODE_VULNERABLE_DRIVER ((PBYTE)resurgence::Internal::g_pVulnerableDriverData) 14 | #define SHELLCODE_LOADER ((PBYTE)resurgence::Internal::g_pLoaderCode) 15 | #define SHELLCODE_LOADER_SIZE (463) 16 | 17 | #define BOOTSTRAP_IMAGE_OFFSET 0x200 18 | } 19 | } -------------------------------------------------------------------------------- /Resurgence/include/system/portable_executable.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace resurgence 7 | { 8 | namespace system 9 | { 10 | class process; 11 | 12 | enum platform 13 | { 14 | platform_unknown = 0, 15 | platform_x86, 16 | platform_x64 17 | }; 18 | 19 | #define MAX_SECTION_COUNT 16 20 | 21 | class portable_executable 22 | { 23 | public: 24 | portable_executable(); 25 | portable_executable(process* proc, PIMAGE_DOS_HEADER dosHdr, PIMAGE_NT_HEADERS32 ntHdrs, PIMAGE_SECTION_HEADER secHdr); 26 | portable_executable(process* proc, PIMAGE_DOS_HEADER dosHdr, PIMAGE_NT_HEADERS64 ntHdrs, PIMAGE_SECTION_HEADER secHdr); 27 | 28 | static portable_executable load_from_file(const std::wstring& file); 29 | 30 | const IMAGE_DOS_HEADER* get_dos_header() const; 31 | const IMAGE_NT_HEADERS32* get_nt_headers32() const; 32 | const IMAGE_NT_HEADERS64* get_nt_headers64() const; 33 | IMAGE_DATA_DIRECTORY get_data_directory(int entry) const; 34 | const IMAGE_SECTION_HEADER* get_section_header() const; 35 | 36 | bool is_valid() const; 37 | platform get_platform() const; 38 | 39 | uint16_t get_size_opt_header() const; 40 | uint16_t get_number_of_sections() const; 41 | uint16_t get_file_characteristics() const; 42 | uint16_t get_dll_characteristics() const; 43 | 44 | uint32_t get_base_of_code() const; 45 | uint32_t get_size_of_code() const; 46 | uint32_t get_size_of_image() const; 47 | uint32_t get_size_of_headers() const; 48 | uintptr_t get_entry_point_address() const; 49 | uintptr_t get_image_base() const; 50 | uint32_t get_section_alignment() const; 51 | uint32_t get_file_alignment() const; 52 | uint32_t get_checksum() const; 53 | uint16_t get_subsystem() const; 54 | 55 | private: 56 | static portable_executable load_from_memory(process* proc, const std::uint8_t* base); 57 | 58 | process* _process; 59 | bool _is32Bit; 60 | IMAGE_DOS_HEADER _dosHdr; 61 | IMAGE_NT_HEADERS32 _ntHdr32; 62 | IMAGE_NT_HEADERS64 _ntHdr64; 63 | IMAGE_SECTION_HEADER _secHdr[MAX_SECTION_COUNT]; 64 | }; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Resurgence/include/system/process.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "symbols/symbol_system.hpp" 8 | #include "process_memory.hpp" 9 | #include "process_modules.hpp" 10 | #include "process_threads.hpp" 11 | 12 | #define SYSTEM_IDLE_PROCESS (0) 13 | #define SYSTEM_PROCESS (4) 14 | #define PROCESS_DEFAULT_ACCESS SYNCHRONIZE | PROCESS_VM_READ | PROCESS_QUERY_LIMITED_INFORMATION 15 | #define THREAD_DEFAULT_ACCESS SYNCHRONIZE | THREAD_SET_CONTEXT | THREAD_GET_CONTEXT | \ 16 | THREAD_QUERY_LIMITED_INFORMATION | THREAD_SUSPEND_RESUME | THREAD_TERMINATE 17 | 18 | namespace resurgence 19 | { 20 | namespace system 21 | { 22 | class process_info 23 | { 24 | public: 25 | process_info() 26 | { 27 | RtlZeroMemory(this, sizeof(process_info)); 28 | } 29 | uint32_t pid; 30 | uint32_t parent_pid; 31 | std::wstring name; 32 | std::wstring path; 33 | platform target_platform; 34 | uintptr_t peb_address; 35 | uint32_t wow64peb_address; 36 | bool current_process; 37 | }; 38 | 39 | class process 40 | { 41 | public: 42 | process(); 43 | process(uint32_t pid); 44 | process(const process& rhs); 45 | process& operator=(const process& rhs); 46 | 47 | static std::vector get_processes(); 48 | static process get_current_process(); 49 | static std::vector get_process_by_name(const std::wstring& name); 50 | static bool grant_privilege(uint32_t privilege); 51 | static bool revoke_privilege(uint32_t privilege); 52 | 53 | void ensure_access(uint32_t access) const; 54 | const std::wstring& get_name() const; 55 | const std::wstring& get_path() const; 56 | uintptr_t get_peb_address() const; 57 | uint32_t get_wow64_peb_address() const; 58 | int get_pid() const; 59 | platform get_platform() const; 60 | const misc::safe_process_handle& get_handle() const; 61 | bool is_current_process() const; 62 | bool is_system_idle_process() const; 63 | bool is_system_process() const; 64 | bool is_valid() const; 65 | bool has_exited() const; 66 | bool is_being_debugged(); 67 | bool is_protected(); 68 | 69 | NTSTATUS open(uint32_t access); 70 | void terminate(uint32_t exitCode = 0); 71 | NTSTATUS get_exit_code() const; 72 | std::wstring get_command_line(); 73 | 74 | process_memory* memory() { return &_memory; } 75 | process_modules* modules() { return &_modules; } 76 | process_threads* threads() { return &_threads; } 77 | 78 | symbol_system* symbols() 79 | { 80 | if(!_symbols.is_initialized()) 81 | _symbols.initialize(); 82 | return &_symbols; 83 | } 84 | 85 | private: 86 | void get_process_info(); 87 | 88 | private: 89 | process_info _info; 90 | misc::safe_process_handle _handle; 91 | process_memory _memory; 92 | process_modules _modules; 93 | process_threads _threads; 94 | symbol_system _symbols; 95 | }; 96 | } 97 | } -------------------------------------------------------------------------------- /Resurgence/include/system/process_memory.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace resurgence 6 | { 7 | namespace system 8 | { 9 | class process; 10 | 11 | class process_memory 12 | { 13 | public: 14 | process_memory(process* proc); 15 | 16 | uint8_t* allocate(size_t size, uint32_t allocation, uint32_t protection); 17 | NTSTATUS allocate_ex(uint8_t** address, size_t size, uint32_t allocation, uint32_t protection); 18 | NTSTATUS protect(const uint8_t* address, size_t size, uint32_t protection, uint32_t* oldProtection = nullptr); 19 | NTSTATUS free(const uint8_t* address, size_t size, uint32_t freeType); 20 | NTSTATUS read_bytes(const uint8_t* address, uint8_t* buffer, size_t size); 21 | NTSTATUS write_bytes(const uint8_t* address, uint8_t* buffer, size_t size); 22 | template _Ty read(const uint8_t* address); 23 | template void write(const uint8_t* address, const _Ty& buffer, size_t size = sizeof(_Ty)); 24 | template std::string read_string(_Ty address, size_t length); 25 | template std::wstring read_unicode_string(_Ty address, size_t length); 26 | 27 | private: 28 | friend class process; 29 | process_memory(); 30 | 31 | process* _process; 32 | }; 33 | 34 | template _Ty process_memory::read(const uint8_t* address) 35 | { 36 | _Ty buffer; 37 | read_bytes(address, (uint8_t*)&buffer, sizeof(_Ty)); 38 | return buffer; 39 | } 40 | template void process_memory::write(const uint8_t* address, const _Ty& buffer, size_t size /*= sizeof(_Ty)*/) 41 | { 42 | write_bytes(address, (uint8_t*)&buffer, size); 43 | } 44 | template std::string process_memory::read_string(_Ty address, size_t length) 45 | { 46 | std::string str; 47 | char* buffer = new char[length + 1](); 48 | read_bytes((uint8_t*)address, (uint8_t*)buffer, length); 49 | str = std::string(buffer); 50 | delete[] buffer; 51 | return str; 52 | } 53 | template std::wstring process_memory::read_unicode_string(_Ty address, size_t length) 54 | { 55 | std::wstring str; 56 | wchar_t* buffer = new wchar_t[length + 1](); 57 | read_bytes((uint8_t*)address, (uint8_t*)buffer, length * sizeof(wchar_t)); 58 | str = std::wstring(buffer); 59 | delete[] buffer; 60 | return str; 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Resurgence/include/system/process_modules.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "portable_executable.hpp" 6 | 7 | // 8 | // Injection types 9 | // 10 | #define INJECTION_TYPE_LOADLIBRARY 0x001 11 | #define INJECTION_TYPE_LDRLOADLL 0x002 12 | 13 | // 14 | // Injection flags 15 | // 16 | #define INJECTION_ERASE_HEADERS 0x001 17 | #define INJECTION_HIDE_MODULE 0x002 18 | 19 | namespace resurgence 20 | { 21 | namespace system 22 | { 23 | class process; 24 | 25 | class process_module 26 | { 27 | public: 28 | /// 29 | /// Default ctor. 30 | /// 31 | process_module(); 32 | 33 | /// 34 | /// x64 module constructor. 35 | /// 36 | /// The owner process. 37 | /// The loader table entry. 38 | process_module(process* proc, PLDR_DATA_TABLE_ENTRY entry); 39 | 40 | /// 41 | /// x86 module constructor. 42 | /// 43 | /// The owner process. 44 | /// The loader table entry. 45 | process_module(process* proc, PLDR_DATA_TABLE_ENTRY32 entry); 46 | 47 | /// 48 | /// System module constructor. 49 | /// 50 | /// The owner process. 51 | /// The module information. 52 | process_module(process* proc, PRTL_PROCESS_MODULE_INFORMATION entry); 53 | 54 | /// 55 | /// Gets the module base. 56 | /// 57 | const uint8_t* get_base() const { return _base; } 58 | 59 | /// 60 | /// Gets the module size. 61 | /// 62 | size_t get_size() const { return _size; } 63 | 64 | /// 65 | /// Gets the module name. 66 | /// 67 | const std::wstring& get_name() const { return _name; } 68 | 69 | /// 70 | /// Gets the module path. 71 | /// 72 | const std::wstring& get_path() const { return _path; } 73 | 74 | /// 75 | /// Checks whether the module is valid. 76 | /// 77 | bool is_valid() const { return _base != nullptr; } 78 | 79 | /// 80 | /// Gets the portable executable linked with this module. 81 | /// 82 | const portable_executable& get_pe(); 83 | 84 | /// 85 | /// Get procedure address. 86 | /// 87 | /// The function name. 88 | /// 89 | /// The address, 0 on failure. 90 | /// 91 | uintptr_t get_proc_address(const std::string& name); 92 | 93 | private: 94 | process* _process; 95 | uint8_t* _base; 96 | size_t _size; 97 | std::wstring _name; 98 | std::wstring _path; 99 | portable_executable _pe; 100 | }; 101 | 102 | class process_modules 103 | { 104 | friend class process; 105 | public: 106 | /// 107 | /// Default ctor. 108 | /// 109 | /// The owner process. 110 | process_modules(process* proc); 111 | 112 | /// 113 | /// Get process modules. 114 | /// 115 | /// A vector with all modules loaded by the process. 116 | std::vector get_all_modules(); 117 | 118 | /// 119 | /// Get main module. 120 | /// 121 | /// The main module. 122 | process_module get_main_module(); 123 | 124 | /// 125 | /// Get module by name. 126 | /// 127 | /// The name. 128 | /// 129 | /// The module. 130 | /// 131 | process_module get_module_by_name(const std::wstring& name); 132 | 133 | /// 134 | /// Get the module that contains the target address. 135 | /// 136 | /// The address. 137 | /// 138 | /// The module. 139 | /// 140 | process_module get_module_by_address(const std::uint8_t* address); 141 | 142 | /// 143 | /// Get module by load order. 144 | /// 145 | /// The module number. 146 | /// 147 | /// The module. 148 | /// 149 | process_module get_module_by_load_order(uint32_t i); 150 | 151 | /// 152 | /// Injects a module. 153 | /// 154 | /// The module path. 155 | /// The injection type. 156 | /// The injection flags. 157 | /// The injected module entry. 158 | /// 159 | /// The status code. 160 | /// 161 | NTSTATUS inject_module(const std::wstring& path, uint32_t injectionType, uint32_t flags, process_module* module = nullptr); 162 | 163 | private: 164 | 165 | /// 166 | /// [Internal] Injects a module on a x86 process. 167 | /// 168 | /// The module path. 169 | /// The injection type. 170 | /// The injected module entry. 171 | /// 172 | /// The status code. 173 | /// 174 | NTSTATUS inject_module32(const std::wstring& path, uint32_t injectionType, process_module* module); 175 | 176 | /// 177 | /// [Internal] Injects a module on a x86 process. 178 | /// 179 | /// The module path. 180 | /// The injection type. 181 | /// The injected module entry. 182 | /// 183 | /// The status code. 184 | /// 185 | NTSTATUS inject_module64(const std::wstring& path, uint32_t injectionType, process_module* module); 186 | 187 | process* _process; 188 | }; 189 | } 190 | } 191 | -------------------------------------------------------------------------------- /Resurgence/include/system/process_threads.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace resurgence 7 | { 8 | namespace system 9 | { 10 | class process; 11 | 12 | class process_thread 13 | { 14 | public: 15 | process_thread(process* owner, PSYSTEM_EXTENDED_THREAD_INFORMATION exThread); 16 | 17 | private: 18 | process* _process; 19 | uint32_t _id; 20 | uintptr_t _startAddress; 21 | }; 22 | 23 | class process_threads 24 | { 25 | public: 26 | process_threads(process* proc); 27 | 28 | std::vector get_all_threads(); 29 | 30 | private: 31 | process* _process; 32 | }; 33 | } 34 | } -------------------------------------------------------------------------------- /Resurgence/include/system/symbols/symbol_system.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "../process_modules.hpp" 9 | 10 | typedef struct _SYMBOL_INFOW *PSYMBOL_INFOW; 11 | 12 | namespace resurgence 13 | { 14 | namespace system 15 | { 16 | class process; 17 | 18 | class symbol_info 19 | { 20 | public: 21 | symbol_info(process* proc, PSYMBOL_INFOW info, uintptr_t displacement); 22 | 23 | const std::wstring& get_name() const { return _name; } 24 | uint64_t get_address() const { return _address; } 25 | uint64_t get_displacement() const { return _disp; } 26 | uint64_t get_module_base() const { return _moduleBase; } 27 | const process_module& get_module() const { return _module; } 28 | 29 | private: 30 | void build_name(PSYMBOL_INFOW info, uintptr_t displacement); 31 | 32 | private: 33 | process* _process; 34 | process_module _module; 35 | uint64_t _moduleBase; // The base of the module where the symbol resides 36 | uint64_t _address; // The symbol address 37 | std::wstring _name; // The symbol's name (e.g nt!LdrLoadDll+0x10) 38 | uint64_t _disp; // The symbol's displacement 39 | }; 40 | 41 | class symbol_system 42 | { 43 | public: 44 | symbol_system(process* proc); 45 | ~symbol_system(); 46 | 47 | bool is_initialized(); 48 | void initialize(); 49 | void cleanup(); 50 | 51 | DWORD64 load_module_from_address(uintptr_t address); 52 | symbol_info get_symbol_info_from_address(uintptr_t address); 53 | symbol_info get_symbol_info_from_name(const std::wstring& name); 54 | 55 | private: 56 | process* _process; 57 | bool _initialized; 58 | HANDLE _symbolHandle; 59 | std::vector _loadedModules; 60 | }; 61 | } 62 | } -------------------------------------------------------------------------------- /Resurgence/src/misc/safe_handle.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | namespace resurgence 5 | { 6 | namespace misc 7 | { 8 | namespace detail 9 | { 10 | safe_handle::safe_handle(HANDLE invalidValue) 11 | : _value(invalidValue), 12 | _invalid(invalidValue), 13 | _grantedBits(0) 14 | { 15 | } 16 | safe_handle::safe_handle(HANDLE value, HANDLE invalidValue) 17 | : _value(value), 18 | _invalid(invalidValue) 19 | { 20 | update_access(); 21 | } 22 | safe_handle::safe_handle(const safe_handle& rhs) 23 | : _value(rhs._invalid), 24 | _invalid(rhs._invalid) 25 | { 26 | rhs.duplicate(*this); 27 | update_access(); 28 | } 29 | safe_handle::~safe_handle() 30 | { 31 | if(is_valid()) 32 | close(); 33 | } 34 | safe_handle& safe_handle::operator=(const safe_handle& rhs) 35 | { 36 | rhs.duplicate(*this); 37 | update_access(); 38 | return *this; 39 | } 40 | void safe_handle::duplicate(safe_handle& other) const 41 | { 42 | if(_value == GetCurrentProcess()) 43 | other._value = GetCurrentProcess(); 44 | else if(_value == GetCurrentThread()) 45 | other._value = GetCurrentThread(); 46 | else 47 | DuplicateHandle( 48 | GetCurrentProcess(), _value, 49 | GetCurrentProcess(), &other._value, 50 | 0, 51 | FALSE, 52 | DUPLICATE_SAME_ACCESS); 53 | return; 54 | } 55 | HANDLE safe_handle::get() const 56 | { 57 | return _value; 58 | } 59 | void safe_handle::set(HANDLE value) 60 | { 61 | if(is_valid()) close(); 62 | _value = value; 63 | update_access(); 64 | } 65 | void safe_handle::close() 66 | { 67 | CloseHandle(_value); 68 | } 69 | bool safe_handle::is_valid() const 70 | { 71 | return _value != _invalid; 72 | } 73 | uint32_t safe_handle::access_mask() const 74 | { 75 | return _grantedBits; 76 | } 77 | void safe_handle::update_access() 78 | { 79 | _grantedBits = 0; 80 | 81 | auto basic_info = (POBJECT_BASIC_INFORMATION)native::query_object_information(_value, ObjectBasicInformation); 82 | 83 | if(basic_info) { 84 | _grantedBits = basic_info->GrantedAccess; 85 | free_local_buffer(basic_info); 86 | } 87 | } 88 | bool safe_handle::has_access(uint32_t access) const 89 | { 90 | return (_grantedBits & access) == access; 91 | } 92 | } 93 | safe_process_handle::safe_process_handle() 94 | : safe_handle(NULL) 95 | { 96 | } 97 | safe_process_handle::safe_process_handle(HANDLE value) 98 | : safe_handle(value, NULL) 99 | { 100 | } 101 | safe_process_handle::safe_process_handle(const safe_process_handle& rhs) 102 | : safe_handle(rhs) 103 | { 104 | } 105 | 106 | safe_generic_handle::safe_generic_handle() 107 | : safe_handle(INVALID_HANDLE_VALUE) 108 | { 109 | } 110 | safe_generic_handle::safe_generic_handle(HANDLE value) 111 | : safe_handle(value, INVALID_HANDLE_VALUE) 112 | { 113 | } 114 | safe_generic_handle::safe_generic_handle(const safe_generic_handle& rhs) 115 | : safe_handle(rhs) 116 | { 117 | } 118 | } 119 | } -------------------------------------------------------------------------------- /Resurgence/src/system/portable_executable.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define GET_NT_HEADER_FIELD(field) _is32Bit ? _ntHdr32.field : _ntHdr64.field 6 | 7 | namespace resurgence 8 | { 9 | namespace system 10 | { 11 | portable_executable::portable_executable() 12 | : _process(nullptr), _dosHdr(), _ntHdr32(), _ntHdr64(), _secHdr(), _is32Bit(false) 13 | { 14 | } 15 | portable_executable::portable_executable(process* proc, PIMAGE_DOS_HEADER dosHdr, PIMAGE_NT_HEADERS32 ntHdrs, PIMAGE_SECTION_HEADER secHdr) 16 | : _process(proc), _dosHdr(*dosHdr), _ntHdr32(*ntHdrs), _ntHdr64(), _is32Bit(true) 17 | { 18 | RtlCopyMemory(_secHdr, secHdr, MAX_SECTION_COUNT * sizeof(IMAGE_SECTION_HEADER)); 19 | } 20 | portable_executable::portable_executable(process* proc, PIMAGE_DOS_HEADER dosHdr, PIMAGE_NT_HEADERS64 ntHdrs, PIMAGE_SECTION_HEADER secHdr) 21 | : _process(proc), _dosHdr(*dosHdr), _ntHdr32(), _ntHdr64(*ntHdrs), _is32Bit(false) 22 | { 23 | RtlCopyMemory(_secHdr, secHdr, MAX_SECTION_COUNT * sizeof(IMAGE_SECTION_HEADER)); 24 | } 25 | portable_executable portable_executable::load_from_file(const std::wstring& file) 26 | { 27 | HANDLE fileHandle; 28 | HANDLE fileMapping; 29 | uint8_t* fileBase; 30 | 31 | UNICODE_STRING usFileName; 32 | std::wstring qualifiedPath; 33 | OBJECT_ATTRIBUTES objAttr; 34 | IO_STATUS_BLOCK ioStatus; 35 | NTSTATUS status; 36 | portable_executable pe; 37 | 38 | qualifiedPath = L"\\??\\"; 39 | qualifiedPath.append(file); 40 | 41 | RtlInitUnicodeString(&usFileName, std::data(qualifiedPath)); 42 | InitializeObjectAttributes(&objAttr, &usFileName, NULL, NULL, NULL); 43 | 44 | status = NtCreateFile( 45 | &fileHandle, FILE_GENERIC_READ, 46 | &objAttr, &ioStatus, 47 | NULL, FILE_ATTRIBUTE_NORMAL, 48 | FILE_SHARE_READ | FILE_SHARE_WRITE, 49 | FILE_OPEN, 50 | FILE_SYNCHRONOUS_IO_NONALERT, 51 | NULL, 0); 52 | 53 | if(NT_SUCCESS(status)) { 54 | fileMapping = CreateFileMapping(fileHandle, NULL, PAGE_READONLY, 0, 0, NULL); 55 | if(fileMapping) { 56 | fileBase = (uint8_t*)MapViewOfFile(fileMapping, FILE_MAP_READ, 0, 0, 0); 57 | if(fileBase) { 58 | auto targetProcess = process::get_current_process(); 59 | pe = load_from_memory(&targetProcess, fileBase); 60 | UnmapViewOfFile(fileBase); 61 | } else { 62 | set_last_ntstatus(STATUS_UNSUCCESSFUL); 63 | } 64 | NtClose(fileMapping); 65 | } else { 66 | set_last_ntstatus(STATUS_UNSUCCESSFUL); 67 | } 68 | NtClose(fileHandle); 69 | } 70 | return pe; 71 | } 72 | portable_executable portable_executable::load_from_memory(process* proc, const std::uint8_t* base) 73 | { 74 | portable_executable pe; 75 | PIMAGE_DOS_HEADER dosHdr = nullptr; 76 | PIMAGE_NT_HEADERS32 ntHdrs32 = nullptr; 77 | PIMAGE_NT_HEADERS64 ntHdrs64 = nullptr; 78 | PIMAGE_SECTION_HEADER secHdr = nullptr; 79 | WORD ntHdrsMagic; 80 | 81 | allocate_local_buffer(&dosHdr, sizeof(IMAGE_DOS_HEADER)); 82 | if(!dosHdr) 83 | goto FAIL_3; 84 | 85 | auto status = proc->memory()->read_bytes(base, (uint8_t*)dosHdr, sizeof(IMAGE_DOS_HEADER)); 86 | 87 | if(!NT_SUCCESS(status)) 88 | goto FAIL_2; 89 | 90 | if(dosHdr->e_magic != IMAGE_DOS_SIGNATURE) { 91 | set_last_ntstatus(STATUS_INVALID_IMAGE_NOT_MZ); 92 | goto FAIL_2; 93 | } 94 | 95 | auto ntHdrsBase = PTR_ADD(base, dosHdr->e_lfanew); 96 | auto ntHdrsMagicAddress = PTR_ADD(ntHdrsBase, FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader)); 97 | 98 | status = proc->memory()->read_bytes(ntHdrsMagicAddress, (uint8_t*)&ntHdrsMagic, sizeof(WORD)); 99 | 100 | if(!NT_SUCCESS(status)) 101 | goto FAIL_2; 102 | 103 | // 104 | // 32bit image 105 | // 106 | if(ntHdrsMagic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) { 107 | allocate_local_buffer(&ntHdrs32, sizeof(IMAGE_NT_HEADERS32)); 108 | 109 | if(!ntHdrs32) 110 | goto FAIL_1; 111 | 112 | status = proc->memory()->read_bytes(ntHdrsBase, (uint8_t*)ntHdrs32, sizeof(IMAGE_NT_HEADERS32)); 113 | 114 | if(!NT_SUCCESS(status)) 115 | goto FAIL_1; 116 | 117 | allocate_local_buffer(&secHdr, MAX_SECTION_COUNT * sizeof(IMAGE_SECTION_HEADER)); 118 | 119 | if(!secHdr) 120 | goto FAIL_1; 121 | 122 | RtlZeroMemory(secHdr, MAX_SECTION_COUNT * sizeof(IMAGE_SECTION_HEADER)); 123 | 124 | status = proc->memory()->read_bytes(PTR_ADD(ntHdrsBase, sizeof(IMAGE_NT_HEADERS32)), (uint8_t*)secHdr, sizeof(IMAGE_SECTION_HEADER) * ntHdrs32->FileHeader.NumberOfSections); 125 | 126 | if(!NT_SUCCESS(status)) 127 | goto FAIL_1; 128 | 129 | pe = portable_executable(proc, dosHdr, ntHdrs32, secHdr); 130 | } 131 | // 132 | // 64bit image 133 | // 134 | else { 135 | allocate_local_buffer(&ntHdrs64, sizeof(IMAGE_NT_HEADERS64)); 136 | 137 | if(!ntHdrs64) 138 | goto FAIL_1; 139 | 140 | status = proc->memory()->read_bytes(ntHdrsBase, (uint8_t*)ntHdrs64, sizeof(IMAGE_NT_HEADERS64)); 141 | 142 | if(!NT_SUCCESS(status)) 143 | goto FAIL_1; 144 | 145 | allocate_local_buffer(&secHdr, MAX_SECTION_COUNT * sizeof(IMAGE_SECTION_HEADER)); 146 | 147 | if(!secHdr) 148 | goto FAIL_1; 149 | 150 | RtlZeroMemory(secHdr, MAX_SECTION_COUNT * sizeof(IMAGE_SECTION_HEADER)); 151 | 152 | status = proc->memory()->read_bytes(PTR_ADD(ntHdrsBase, sizeof(IMAGE_NT_HEADERS64)), (uint8_t*)secHdr, sizeof(IMAGE_SECTION_HEADER) * ntHdrs64->FileHeader.NumberOfSections); 153 | 154 | if(!NT_SUCCESS(status)) 155 | goto FAIL_1; 156 | 157 | pe = portable_executable(proc, dosHdr, ntHdrs64, secHdr); 158 | } 159 | 160 | FAIL_1: // Failed after allocating all buffers 161 | if(ntHdrs32) free_local_buffer(ntHdrs32); 162 | if(ntHdrs64) free_local_buffer(ntHdrs64); 163 | if(secHdr) free_local_buffer(secHdr); 164 | FAIL_2: // Failed after allocating only the dos header 165 | free_local_buffer(dosHdr); 166 | FAIL_3: 167 | return pe; 168 | } 169 | const IMAGE_DOS_HEADER* portable_executable::get_dos_header() const 170 | { 171 | return &_dosHdr; 172 | } 173 | const IMAGE_NT_HEADERS32* portable_executable::get_nt_headers32() const 174 | { 175 | return &_ntHdr32; 176 | } 177 | const IMAGE_NT_HEADERS64* portable_executable::get_nt_headers64() const 178 | { 179 | return &_ntHdr64; 180 | } 181 | IMAGE_DATA_DIRECTORY portable_executable::get_data_directory(int entry) const 182 | { 183 | return _is32Bit ? _ntHdr32.OptionalHeader.DataDirectory[entry] : _ntHdr64.OptionalHeader.DataDirectory[entry]; 184 | } 185 | const IMAGE_SECTION_HEADER* portable_executable::get_section_header() const 186 | { 187 | return _secHdr; 188 | } 189 | bool portable_executable::is_valid() const 190 | { 191 | return _dosHdr.e_magic == IMAGE_DOS_SIGNATURE; 192 | } 193 | platform portable_executable::get_platform() const 194 | { 195 | return _is32Bit ? platform_x86 : platform_x64; 196 | } 197 | uint16_t portable_executable::get_size_opt_header() const 198 | { 199 | return GET_NT_HEADER_FIELD(FileHeader.SizeOfOptionalHeader); 200 | } 201 | uint16_t portable_executable::get_number_of_sections() const 202 | { 203 | return GET_NT_HEADER_FIELD(FileHeader.NumberOfSections); 204 | } 205 | uint16_t portable_executable::get_file_characteristics() const 206 | { 207 | return GET_NT_HEADER_FIELD(FileHeader.Characteristics); 208 | } 209 | uint16_t portable_executable::get_dll_characteristics() const 210 | { 211 | return GET_NT_HEADER_FIELD(OptionalHeader.DllCharacteristics); 212 | } 213 | uint32_t portable_executable::get_base_of_code() const 214 | { 215 | return GET_NT_HEADER_FIELD(OptionalHeader.BaseOfCode); 216 | } 217 | uint32_t portable_executable::get_size_of_code() const 218 | { 219 | return GET_NT_HEADER_FIELD(OptionalHeader.SizeOfCode); 220 | } 221 | uint32_t portable_executable::get_size_of_image() const 222 | { 223 | return GET_NT_HEADER_FIELD(OptionalHeader.SizeOfImage); 224 | } 225 | uint32_t portable_executable::get_size_of_headers() const 226 | { 227 | return GET_NT_HEADER_FIELD(OptionalHeader.SizeOfHeaders); 228 | } 229 | uintptr_t portable_executable::get_entry_point_address() const 230 | { 231 | return GET_NT_HEADER_FIELD(OptionalHeader.AddressOfEntryPoint); 232 | } 233 | uintptr_t portable_executable::get_image_base() const 234 | { 235 | return static_cast(GET_NT_HEADER_FIELD(OptionalHeader.ImageBase)); 236 | } 237 | uint32_t portable_executable::get_section_alignment() const 238 | { 239 | return GET_NT_HEADER_FIELD(OptionalHeader.SectionAlignment); 240 | } 241 | uint32_t portable_executable::get_file_alignment() const 242 | { 243 | return GET_NT_HEADER_FIELD(OptionalHeader.FileAlignment); 244 | } 245 | uint32_t portable_executable::get_checksum() const 246 | { 247 | return GET_NT_HEADER_FIELD(OptionalHeader.CheckSum); 248 | } 249 | uint16_t portable_executable::get_subsystem() const 250 | { 251 | return GET_NT_HEADER_FIELD(OptionalHeader.Subsystem); 252 | } 253 | } 254 | } -------------------------------------------------------------------------------- /Resurgence/src/system/process.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | #pragma comment(lib, "Shlwapi.lib") 8 | 9 | namespace resurgence 10 | { 11 | namespace system 12 | { 13 | process::process() 14 | : _handle(nullptr), 15 | _memory(this), 16 | _modules(this), 17 | _threads(this), 18 | _symbols(this) 19 | { 20 | RtlZeroMemory(&_info, sizeof(_info)); 21 | _info.pid = (uint32_t)-1; 22 | } 23 | process::process(uint32_t pid) 24 | : _handle(nullptr), 25 | _memory(this), 26 | _modules(this), 27 | _threads(this), 28 | _symbols(this) 29 | { 30 | RtlZeroMemory(&_info, sizeof(_info)); 31 | 32 | _info.pid = pid; 33 | _info.current_process = GetCurrentProcessId() == pid; 34 | 35 | if(!is_system_idle_process()) { 36 | if(!is_current_process()) { 37 | open(PROCESS_DEFAULT_ACCESS); 38 | } else { 39 | _handle = misc::safe_process_handle(GetCurrentProcess()); 40 | } 41 | } 42 | get_process_info(); 43 | 44 | } 45 | process::process(const process& rhs) 46 | : _memory(this), 47 | _modules(this), 48 | _threads(this), 49 | _symbols(this) 50 | { 51 | _handle = rhs._handle; 52 | _info = rhs._info; 53 | } 54 | process& process::operator=(const process& rhs) 55 | { 56 | _memory = process_memory(this); 57 | _modules = process_modules(this); 58 | _threads = process_threads(this); 59 | _symbols = symbol_system(this); 60 | _handle = rhs._handle; 61 | _info = rhs._info; 62 | return *this; 63 | } 64 | void process::get_process_info() 65 | { 66 | using namespace misc; 67 | 68 | if(is_system_idle_process()) { 69 | _info.target_platform = platform_x64; 70 | _info.parent_pid = 0; 71 | _info.peb_address = 0; 72 | _info.wow64peb_address = 0; 73 | _info.name = L"System Idle Process"; 74 | _info.path = L"N/A"; 75 | } else if(is_system_process()) { 76 | _info.target_platform = platform_x64; 77 | _info.parent_pid = 0; 78 | _info.peb_address = 0; 79 | _info.wow64peb_address = 0; 80 | _info.name = L"System Process"; 81 | native::enumerate_system_modules([&](PRTL_PROCESS_MODULE_INFORMATION info) { 82 | wchar_t processPath[MAX_PATH]; 83 | ZeroMemory(processPath, sizeof(processPath)); 84 | MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (LPCCH)info->FullPathName, 256, processPath, MAX_PATH); 85 | _info.path = native::get_dos_path(processPath); 86 | return STATUS_SUCCESS; 87 | }); 88 | } else { 89 | auto needDispose = false; 90 | auto handle = HANDLE{nullptr}; 91 | 92 | if(!_handle.is_valid()) { 93 | native::open_process(&handle, get_pid(), PROCESS_QUERY_LIMITED_INFORMATION); 94 | needDispose = true; 95 | } else 96 | handle = _handle.get(); 97 | 98 | if(handle) { 99 | PPEB32 peb32; 100 | auto basic_info = (PPROCESS_BASIC_INFORMATION)native::query_process_information(handle, ProcessBasicInformation); 101 | auto fileName = (PUNICODE_STRING)native::query_process_information(handle, ProcessImageFileName); 102 | 103 | _info.target_platform = native::process_is_wow64(handle, &peb32) ? platform_x86 : platform_x64; 104 | _info.parent_pid = static_cast(basic_info->InheritedFromUniqueProcessId); 105 | _info.peb_address = reinterpret_cast(basic_info->PebBaseAddress); 106 | _info.path = native::get_dos_path(std::wstring(fileName->Buffer, fileName->Length / sizeof(wchar_t))); 107 | _info.name = PathFindFileNameW(fileName->Buffer); 108 | 109 | #ifdef _WIN64 110 | if(_info.target_platform == platform_x86) { 111 | _info.wow64peb_address = reinterpret_cast(peb32); 112 | } else { 113 | _info.wow64peb_address = 0; 114 | } 115 | #else 116 | if(_info.target_platform == platform_x86) { 117 | _info.wow64peb_address = reinterpret_cast(peb32); 118 | _info.peb_address = _info.peb_address - PAGE_SIZE; 119 | } else { 120 | _info.wow64peb_address = 0; 121 | _info.peb_address = 0; 122 | } 123 | #endif 124 | 125 | free_local_buffer(basic_info); 126 | free_local_buffer(fileName); 127 | 128 | if(needDispose) 129 | NtClose(handle); 130 | } 131 | } 132 | } 133 | std::vector process::get_processes() 134 | { 135 | std::vector processes; 136 | 137 | native::enumerate_processes([&](PSYSTEM_PROCESS_INFORMATION info) -> NTSTATUS { 138 | processes.push_back(process((uint32_t)info->UniqueProcessId)); 139 | return STATUS_NOT_FOUND; 140 | }); 141 | 142 | return processes; 143 | } 144 | process process::get_current_process() 145 | { 146 | return process(GetCurrentProcessId()); 147 | } 148 | std::vector process::get_process_by_name(const std::wstring& name) 149 | { 150 | std::vector processes; 151 | 152 | native::enumerate_processes([&](PSYSTEM_PROCESS_INFORMATION info) -> NTSTATUS { 153 | if(info->ImageName.Length > 0 && !_wcsicmp(std::data(name), info->ImageName.Buffer)) 154 | processes.emplace_back(static_cast((ULONG_PTR)info->UniqueProcessId)); 155 | return STATUS_NOT_FOUND; 156 | }); 157 | 158 | return processes; 159 | } 160 | bool process::grant_privilege(uint32_t privilege) 161 | { 162 | BOOLEAN enabled; 163 | return NT_SUCCESS(RtlAdjustPrivilege(privilege, TRUE, FALSE, &enabled)); 164 | } 165 | bool process::revoke_privilege(uint32_t privilege) 166 | { 167 | BOOLEAN enabled; 168 | return NT_SUCCESS(RtlAdjustPrivilege(privilege, FALSE, FALSE, &enabled)); 169 | } 170 | 171 | void process::ensure_access(uint32_t access) const 172 | { 173 | if(!_handle.has_access(access)) 174 | throw misc::exception("Handle doesnt have the required access rights"); 175 | } 176 | const std::wstring& process::get_name() const 177 | { 178 | return _info.name; 179 | } 180 | const std::wstring& process::get_path() const 181 | { 182 | return _info.path; 183 | } 184 | uintptr_t process::get_peb_address() const 185 | { 186 | return _info.peb_address; 187 | } 188 | uint32_t process::get_wow64_peb_address() const 189 | { 190 | return _info.wow64peb_address; 191 | } 192 | int process::get_pid() const 193 | { 194 | return _info.pid; 195 | } 196 | platform process::get_platform() const 197 | { 198 | return _info.target_platform; 199 | } 200 | const misc::safe_process_handle& process::get_handle() const 201 | { 202 | return _handle; 203 | } 204 | bool process::is_current_process() const 205 | { 206 | return _info.current_process; 207 | } 208 | bool process::is_system_idle_process() const 209 | { 210 | return get_pid() == SYSTEM_IDLE_PROCESS; 211 | } 212 | bool process::is_system_process() const 213 | { 214 | return get_pid() == SYSTEM_PROCESS; 215 | } 216 | bool process::is_valid() const 217 | { 218 | return _info.pid != (uint32_t)-1; 219 | } 220 | bool process::has_exited() const 221 | { 222 | return WaitForSingleObject(_handle.get(), 0) != WAIT_TIMEOUT; 223 | } 224 | bool process::is_being_debugged() 225 | { 226 | ensure_access(PROCESS_VM_READ); 227 | 228 | return !!memory()->read(PTR_ADD(_info.peb_address, FIELD_OFFSET(PEB, BeingDebugged))); 229 | } 230 | bool process::is_protected() 231 | { 232 | ensure_access(PROCESS_VM_READ); 233 | 234 | std::bitset<8> bitfield(memory()->read(PTR_ADD(_info.peb_address, FIELD_OFFSET(PEB, BitField)))); 235 | 236 | 237 | return bitfield.test(1) || bitfield.test(7); 238 | } 239 | NTSTATUS process::open(uint32_t access) 240 | { 241 | if(is_current_process()) 242 | return STATUS_SUCCESS; 243 | 244 | if(_handle.is_valid()) { 245 | auto handle_info = (POBJECT_BASIC_INFORMATION)native::query_object_information(_handle.get(), ObjectBasicInformation); 246 | 247 | if(handle_info) { 248 | // 249 | // Already has the desired access 250 | // 251 | bool b = 252 | handle_info->GrantedAccess == access || 253 | handle_info->GrantedAccess == PROCESS_ALL_ACCESS; 254 | 255 | free_local_buffer(handle_info); 256 | 257 | if(b) return STATUS_SUCCESS; 258 | } 259 | } 260 | 261 | auto handle = HANDLE{nullptr}; 262 | auto status = native::open_process(&handle, get_pid(), PROCESS_DEFAULT_ACCESS | access); 263 | 264 | if(NT_SUCCESS(status)) { 265 | _handle = misc::safe_process_handle(handle); 266 | } 267 | 268 | return status; 269 | } 270 | void process::terminate(uint32_t exitCode /*= 0*/) 271 | { 272 | ensure_access(PROCESS_TERMINATE); 273 | 274 | native::terminate_process(_handle.get(), exitCode); 275 | } 276 | NTSTATUS process::get_exit_code() const 277 | { 278 | DWORD exitCode = 0; 279 | GetExitCodeProcess(_handle.get(), &exitCode); 280 | return (NTSTATUS)exitCode; 281 | } 282 | std::wstring process::get_command_line() 283 | { 284 | ensure_access(PROCESS_VM_READ); 285 | 286 | if(_info.target_platform == platform_x86) { 287 | 288 | ULONG address; 289 | RTL_USER_PROCESS_PARAMETERS parameters; 290 | 291 | // 292 | // Read ProcessParameters address 293 | // 294 | address = memory()->read( 295 | PTR_ADD(_info.peb_address, 296 | FIELD_OFFSET(PEB, ProcessParameters)) 297 | ); 298 | 299 | parameters = memory()->read((uint8_t*)address); 300 | 301 | return memory()->read_unicode_string(parameters.CommandLine.Buffer, parameters.CommandLine.Length / sizeof(wchar_t)); 302 | } else { 303 | ULONGLONG address; 304 | RTL_USER_PROCESS_PARAMETERS parameters; 305 | 306 | // 307 | // Read ProcessParameters address 308 | // 309 | address = memory()->read( 310 | PTR_ADD(_info.peb_address, 311 | FIELD_OFFSET(PEB, ProcessParameters)) 312 | ); 313 | 314 | parameters = memory()->read((uint8_t*)address); 315 | 316 | return memory()->read_unicode_string(parameters.CommandLine.Buffer, parameters.CommandLine.Length / sizeof(wchar_t)); 317 | } 318 | } 319 | } 320 | } -------------------------------------------------------------------------------- /Resurgence/src/system/process_memory.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace resurgence 8 | { 9 | namespace system 10 | { 11 | process_memory::process_memory(process* proc) 12 | : _process(proc) 13 | { 14 | } 15 | process_memory::process_memory() 16 | : _process(nullptr) 17 | { 18 | 19 | } 20 | uint8_t* process_memory::allocate(size_t size, uint32_t allocation, uint32_t protection) 21 | { 22 | uint8_t* address; 23 | native::allocate_memory(_process->get_handle().get(), (PVOID*)&address, &size, allocation, protection); 24 | return address; 25 | } 26 | NTSTATUS process_memory::allocate_ex(uint8_t** address, size_t size, uint32_t allocation, uint32_t protection) 27 | { 28 | return native::allocate_memory(_process->get_handle().get(), (PVOID*)address, &size, allocation, protection); 29 | } 30 | NTSTATUS process_memory::protect(const uint8_t* address, size_t size, uint32_t protection, uint32_t* oldProtection /*= nullptr*/) 31 | { 32 | uint32_t old; 33 | auto ret = native::protect_memory(_process->get_handle().get(), (PVOID*)&address, &size, protection, &old); 34 | if(oldProtection) 35 | *oldProtection = old; 36 | return ret; 37 | } 38 | NTSTATUS process_memory::free(const uint8_t* address, size_t size, uint32_t freeType) 39 | { 40 | return native::free_memory(_process->get_handle().get(), (PVOID*)&address, size, freeType); 41 | } 42 | NTSTATUS process_memory::read_bytes(const uint8_t* address, uint8_t* buffer, size_t size) 43 | { 44 | return native::read_memory(_process->get_handle().get(), (void*)address, buffer, size); 45 | } 46 | NTSTATUS process_memory::write_bytes(const uint8_t* address, uint8_t* buffer, size_t size) 47 | { 48 | return native::write_memory(_process->get_handle().get(), (void*)address, buffer, size); 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /Resurgence/src/system/process_threads.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | namespace resurgence 7 | { 8 | namespace system 9 | { 10 | process_thread::process_thread(process* owner, PSYSTEM_EXTENDED_THREAD_INFORMATION exThread) 11 | : _process(owner) 12 | { 13 | if(_process->get_platform() == platform_x86) 14 | _startAddress = reinterpret_cast(exThread->Win32StartAddress); 15 | else 16 | _startAddress = reinterpret_cast(exThread->StartAddress); 17 | 18 | _id = reinterpret_cast(exThread->ClientId.UniqueThread); 19 | } 20 | 21 | process_threads::process_threads(process* proc) 22 | : _process(proc) 23 | { 24 | } 25 | 26 | std::vector process_threads::get_all_threads() 27 | { 28 | std::vector threads; 29 | native::enumerate_process_threads(_process->get_pid(), [&](PSYSTEM_EXTENDED_THREAD_INFORMATION entry) { 30 | threads.emplace_back(_process, entry); 31 | return STATUS_NOT_FOUND; 32 | }); 33 | return threads; 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /Resurgence/src/system/symbols/symbol_system.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | #pragma comment(lib, "dbghelp.lib") 10 | 11 | namespace resurgence 12 | { 13 | namespace system 14 | { 15 | ULONG_PTR LastFakeHandle = 0; 16 | 17 | //bool symbol_system::s_Initialized; 18 | //HANDLE symbol_system::s_SymbolHandle; 19 | //std::vector symbol_system::s_LoadedModules; 20 | //std::mutex symbol_system::s_LoadedModulesMutex; 21 | 22 | symbol_info::symbol_info(process* proc, PSYMBOL_INFOW info, uintptr_t displacement) 23 | { 24 | _process = proc; 25 | _module = _process->modules()->get_module_by_address(reinterpret_cast(info->Address)); 26 | if(info->ModBase != 0) { 27 | _moduleBase = info->ModBase; 28 | } else { 29 | _moduleBase = reinterpret_cast(_module.get_base()); 30 | } 31 | _address = info->Address; 32 | _disp = displacement; 33 | build_name(info, displacement); 34 | } 35 | 36 | void symbol_info::build_name(PSYMBOL_INFOW info, uintptr_t displacement) 37 | { 38 | wchar_t buffer[1024]; 39 | auto module = _process->modules()->get_module_by_address(reinterpret_cast(info->Address)); 40 | auto moduleName = module.get_name(); 41 | 42 | if(moduleName.empty()) { 43 | // 44 | // We don't have a module name. 45 | // Return an address; 46 | // 47 | swprintf_s(buffer, L"0x%llX", static_cast(info->Address)); 48 | _name = buffer; 49 | } else { 50 | if(info->NameLen == 0) { 51 | // 52 | // We have a module name but not a symbol name. 53 | // Return module+offset; 54 | // 55 | swprintf_s(buffer, L"%ws+0x%lX", std::data(moduleName), static_cast(info->Address - (uintptr_t)module.get_base())); 56 | _name = buffer; 57 | } else { 58 | // 59 | // We have a module AND symbol name. 60 | // Return module!symbol+diplacement 61 | // 62 | if(displacement == 0) { 63 | swprintf_s(buffer, L"%ws!%s", std::data(moduleName), info->Name); 64 | } else { 65 | swprintf_s(buffer, L"%ws!%s+0x%lX", std::data(moduleName), info->Name, static_cast(displacement)); 66 | } 67 | _name = buffer; 68 | } 69 | } 70 | } 71 | 72 | symbol_system::symbol_system(process* proc) 73 | : _process(proc), _initialized(false), _symbolHandle(nullptr) 74 | { 75 | } 76 | symbol_system::~symbol_system() 77 | { 78 | cleanup(); 79 | } 80 | bool symbol_system::is_initialized() 81 | { 82 | return _initialized; 83 | } 84 | void symbol_system::initialize() 85 | { 86 | if(_initialized) { 87 | cleanup(); 88 | } 89 | bool realHandle = false; 90 | if(!_process->is_system_idle_process()) { 91 | static ACCESS_MASK accesses[] = 92 | { 93 | STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xfff, // pre-Vista full access 94 | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_DUP_HANDLE, 95 | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 96 | MAXIMUM_ALLOWED 97 | }; 98 | 99 | ULONG i; 100 | 101 | // Try to open the process with many different accesses. 102 | // This handle will be re-used when walking stacks, and doing various other things. 103 | for(i = 0; i < sizeof(accesses) / sizeof(ACCESS_MASK); i++) { 104 | if(NT_SUCCESS(native::open_process(&_symbolHandle, _process->get_pid(), accesses[i]))) { 105 | realHandle = true; 106 | break; 107 | } 108 | } 109 | } 110 | 111 | if(!realHandle) { 112 | HANDLE fakeHandle; 113 | 114 | // Just generate a fake handle. 115 | #ifdef _WIN64 116 | fakeHandle = (HANDLE)_InterlockedExchangeAdd64((LONG_PTR*)&LastFakeHandle, 4); 117 | #else 118 | fakeHandle = (HANDLE)_InterlockedExchangeAdd((ULONG_PTR*)&LastFakeHandle, 4); 119 | #endif 120 | // Add one to make sure it isn't divisible by 4 (so it can't be mistaken for a real handle). 121 | _symbolHandle = (HANDLE)((ULONG_PTR)fakeHandle + 1); 122 | } 123 | 124 | SymSetOptions(SYMOPT_DEFERRED_LOADS | SYMOPT_FAVOR_COMPRESSED | SYMOPT_INCLUDE_32BIT_MODULES | SYMOPT_UNDNAME); 125 | _initialized = !!SymInitialize(_symbolHandle, NULL, FALSE); 126 | } 127 | void symbol_system::cleanup() 128 | { 129 | if(!_initialized) return; 130 | 131 | for(auto& module : _loadedModules) { 132 | SymUnloadModule64(_symbolHandle, module); 133 | } 134 | _loadedModules.clear(); 135 | SymCleanup(_symbolHandle); 136 | _initialized = false; 137 | } 138 | DWORD64 symbol_system::load_module_from_address(uintptr_t address) 139 | { 140 | if(!_initialized) return 0; 141 | 142 | auto module = _process->modules()->get_module_by_address(reinterpret_cast(address)); 143 | 144 | if(module.get_base() != 0) { 145 | auto result = SymLoadModuleExW( 146 | _symbolHandle, 147 | NULL, 148 | std::data(module.get_path()), 149 | std::data(module.get_name()), 150 | (DWORD64)module.get_base(), 151 | (DWORD)module.get_size(), 152 | NULL, 153 | 0); 154 | 155 | if(result != 0) { 156 | IMAGEHLP_MODULEW64 info; 157 | info.SizeOfStruct = sizeof(info); 158 | if(SymGetModuleInfoW64(_symbolHandle, result, &info)) { 159 | if(std::find(std::begin(_loadedModules), std::end(_loadedModules), result) != std::end(_loadedModules)) { 160 | _loadedModules.emplace_back(result); 161 | } 162 | } else { 163 | throw misc::win32_exception("SymGetModuleInfoW64 failed", GetLastError()); 164 | } 165 | } 166 | return result; 167 | } 168 | return 0; 169 | } 170 | symbol_info symbol_system::get_symbol_info_from_address(uintptr_t address) 171 | { 172 | DWORD64 displacement = 0; 173 | char buffer[sizeof(SYMBOL_INFOW) + MAX_SYM_NAME * sizeof(WCHAR)]; 174 | ZeroMemory(buffer, sizeof(buffer)); 175 | PSYMBOL_INFOW symbolBuffer = (PSYMBOL_INFOW)buffer; 176 | 177 | symbolBuffer->SizeOfStruct = sizeof(SYMBOL_INFOW); 178 | symbolBuffer->MaxNameLen = MAX_PATH; 179 | 180 | load_module_from_address(address); 181 | if(!SymFromAddrW(_symbolHandle, address, &displacement, symbolBuffer)) 182 | symbolBuffer->Address = address; 183 | 184 | return symbol_info{_process, symbolBuffer, (uintptr_t)displacement}; 185 | } 186 | symbol_info symbol_system::get_symbol_info_from_name(const std::wstring& name) 187 | { 188 | char buffer[sizeof(SYMBOL_INFOW) + MAX_SYM_NAME * sizeof(WCHAR)]; 189 | ZeroMemory(buffer, sizeof(buffer)); 190 | PSYMBOL_INFOW symbolBuffer = (PSYMBOL_INFOW)buffer; 191 | 192 | symbolBuffer->SizeOfStruct = sizeof(SYMBOL_INFOW); 193 | symbolBuffer->MaxNameLen = MAX_PATH; 194 | 195 | SymFromNameW(_symbolHandle, std::data(name), symbolBuffer); 196 | 197 | return symbol_info{_process, symbolBuffer, 0}; 198 | } 199 | } 200 | } -------------------------------------------------------------------------------- /ResurgenceDrv/ResurgenceDrv.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef MAX_PATH 4 | #define MAX_PATH 260 5 | #endif 6 | 7 | #ifndef FIELD_OFFSET 8 | #define FIELD_OFFSET(type, field) ((ULONG)&(((type *)0)->field)) 9 | #endif 10 | 11 | #ifndef FIELD_SIZE 12 | #define FIELD_SIZE(type, field) (sizeof(((type *)0)->field)) 13 | #endif 14 | 15 | #define RDRV_SYMLINK L"Resurgence" 16 | #define RDRV_DEVICE_NAME L"\\Device\\" RDRV_SYMLINK 17 | #define RDRV_DOSDEVICE_NAME L"\\DosDevices\\" RDRV_SYMLINK 18 | #define RDRV_DEV_TYPE 0x8989 19 | 20 | #define VM_OPERATION_ALLOC 0x00 21 | #define VM_OPERATION_FREE 0x01 22 | #define VM_OPERATION_PROTECT 0x02 23 | #define PROTECTION_NONE 0x00 24 | #define PROTECTION_LIGHT 0x01 25 | #define PROTECTION_FULL 0x02 26 | 27 | #define RDRV_CTL_CODE(Function) CTL_CODE(RDRV_DEV_TYPE, Function, METHOD_BUFFERED, FILE_ANY_ACCESS) 28 | 29 | #define RESURGENCE_QUERY_OSVERSION RDRV_CTL_CODE(0x801) 30 | #define RESURGENCE_QUERY_OSVERSION_SIZE sizeof(VERSION_INFO) 31 | 32 | #define RESURGENCE_VM_OPERATION RDRV_CTL_CODE(0x802) 33 | #define RESURGENCE_VM_OPERATION_SIZE sizeof(VM_OPERATION) 34 | 35 | #define RESURGENCE_VM_READ RDRV_CTL_CODE(0x803) 36 | #define RESURGENCE_VM_WRITE RDRV_CTL_CODE(0x804) 37 | #define RESURGENCE_VM_READ_SIZE sizeof(VM_READ_WRITE) 38 | #define RESURGENCE_VM_WRITE_SIZE RESURGENCE_VM_READ_SIZE 39 | 40 | #define RESURGENCE_VM_QUERY RDRV_CTL_CODE(0x805) 41 | #define RESURGENCE_VM_QUERY_SIZE sizeof(VM_QUERY_INFO) 42 | 43 | #define RESURGENCE_GRANT_ACCESS RDRV_CTL_CODE(0x806) 44 | #define RESURGENCE_GRANT_ACCESS_SIZE sizeof(GRANT_ACCESS) 45 | 46 | #define RESURGENCE_PROTECT_PROCESS RDRV_CTL_CODE(0x807) 47 | #define RESURGENCE_PROTECT_PROCESS_SIZE sizeof(PROTECT_PROCESS) 48 | 49 | #define RESURGENCE_OPEN_PROCESS RDRV_CTL_CODE(0x808) 50 | #define RESURGENCE_OPEN_PROCESS_SIZE sizeof(OPEN_PROCESS) 51 | 52 | #define RESURGENCE_OPEN_THREAD RDRV_CTL_CODE(0x809) 53 | #define RESURGENCE_OPEN_THREAD_SIZE sizeof(OPEN_THREAD) 54 | 55 | #define RESURGENCE_SET_DEP_STATE RDRV_CTL_CODE(0x80A) 56 | #define RESURGENCE_SET_DEP_STATE_SIZE sizeof(SET_DEP_STATE) 57 | 58 | #define RESURGENCE_INJECT_MODULE RDRV_CTL_CODE(0x80B) 59 | #define RESURGENCE_INJECT_MODULE_SIZE sizeof(INJECT_MODULE) 60 | 61 | #pragma warning(disable : 4201) 62 | 63 | typedef enum _INJECT_METHOD 64 | { 65 | InjectLdrLoadDll, 66 | InjectManualMap 67 | } INJECT_METHOD; 68 | 69 | typedef struct _VERSION_INFO 70 | { 71 | ULONG MajorVersion; 72 | ULONG MinorVersion; 73 | USHORT ServicePackMajor; 74 | USHORT ServicePackMinor; 75 | ULONG BuildNumber; 76 | ULONG VersionLong; 77 | } VERSION_INFO, *PVERSION_INFO; 78 | 79 | typedef struct _VM_OPERATION 80 | { 81 | union 82 | { 83 | struct 84 | { 85 | ULONG Operation; //Alloc, Free or Protect 86 | ULONG ProcessId; 87 | ULONGLONG BaseAddress; 88 | SIZE_T RegionSize; 89 | ULONG ProtectionFlags; 90 | ULONG AllocationFlags; 91 | ULONG FreeType; 92 | } In; 93 | struct 94 | { 95 | ULONGLONG BaseAddress; 96 | SIZE_T RegionSize; 97 | ULONG OldProtection; 98 | } Out; 99 | }; 100 | } VM_OPERATION, *PVM_OPERATION; 101 | 102 | typedef struct _VM_READ_WRITE 103 | { 104 | ULONG ProcessId; 105 | ULONGLONG TargetAddress; 106 | ULONGLONG Buffer; 107 | ULONGLONG BufferSize; 108 | } VM_READ_WRITE, *PVM_READ_WRITE; 109 | 110 | typedef struct _VM_QUERY_INFO 111 | { 112 | union 113 | { 114 | struct 115 | { 116 | ULONG ProcessId; 117 | ULONGLONG BaseAddress; 118 | } In; 119 | MEMORY_BASIC_INFORMATION Out; 120 | }; 121 | } VM_QUERY_INFO, *PVM_QUERY_INFO; 122 | 123 | typedef struct _GRANT_ACCESS 124 | { 125 | union 126 | { 127 | struct 128 | { 129 | ULONG ProcessId; 130 | ULONGLONG Handle; 131 | ULONG AccessMask; 132 | } In; 133 | struct 134 | { 135 | ULONG OldAccessMask; 136 | } Out; 137 | }; 138 | } GRANT_ACCESS, *PGRANT_ACCESS; 139 | 140 | typedef struct _PROTECT_PROCESS 141 | { 142 | union 143 | { 144 | struct 145 | { 146 | ULONG ProcessId; 147 | ULONG ProtectionLevel; 148 | } In; 149 | }; 150 | } PROTECT_PROCESS, *PPROTECT_PROCESS; 151 | 152 | typedef struct _OPEN_PROCESS 153 | { 154 | union 155 | { 156 | struct 157 | { 158 | ULONG ProcessId; // Any of these can be 0, but not both. 159 | ULONG ThreadId; // If ProcessId is 0, we open the process that contains the ThreadId 160 | ULONG AccessMask; 161 | } In; 162 | struct 163 | { 164 | ULONGLONG Handle; 165 | } Out; 166 | }; 167 | } OPEN_PROCESS, *POPEN_PROCESS; 168 | 169 | typedef struct _OPEN_THREAD 170 | { 171 | union 172 | { 173 | struct 174 | { 175 | ULONG ThreadId; 176 | ULONG AccessMask; 177 | } In; 178 | struct 179 | { 180 | ULONGLONG Handle; 181 | } Out; 182 | }; 183 | } OPEN_THREAD, *POPEN_THREAD; 184 | 185 | typedef struct _SET_DEP_STATE 186 | { 187 | union 188 | { 189 | struct 190 | { 191 | ULONG ProcessId; 192 | BOOLEAN Enabled; 193 | } In; 194 | }; 195 | } SET_DEP_STATE, *PSET_DEP_STATE; 196 | 197 | typedef struct _INJECT_MODULE 198 | { 199 | union 200 | { 201 | struct 202 | { 203 | ULONG ProcessId; 204 | INJECT_METHOD InjectionType; 205 | BOOLEAN ErasePE; 206 | BOOLEAN HideModule; 207 | BOOLEAN CallEntryPoint; 208 | ULONGLONG CustomParameter; 209 | ULONGLONG ModuleBase; 210 | ULONG ModuleSize; 211 | WCHAR ModulePath[MAX_PATH]; 212 | } In; 213 | struct 214 | { 215 | ULONGLONG BaseAddress; 216 | } Out; 217 | }; 218 | } INJECT_MODULE, *PINJECT_MODULE; 219 | 220 | #pragma warning(default : 4201) -------------------------------------------------------------------------------- /ResurgenceDrv/dispatch.c: -------------------------------------------------------------------------------- 1 | #include "dispatch.h" 2 | #include "internal.h" 3 | #include "routines.h" 4 | 5 | #pragma alloc_text(PAGE, RDrvDispatch) 6 | 7 | NTSTATUS RDrvDispatch( 8 | __in PDEVICE_OBJECT DeviceObject, 9 | __in PIRP Irp 10 | ) 11 | { 12 | PIO_STACK_LOCATION ioStack; 13 | ULONG ioControlCode = 0; 14 | 15 | UNREFERENCED_PARAMETER(DeviceObject); 16 | 17 | ioStack = IoGetCurrentIrpStackLocation(Irp); 18 | 19 | Irp->IoStatus.Status = STATUS_SUCCESS; 20 | Irp->IoStatus.Information = 0; 21 | 22 | PVOID ioBuffer = Irp->AssociatedIrp.SystemBuffer; 23 | ULONG inputBufferLength = ioStack->Parameters.DeviceIoControl.InputBufferLength; 24 | ULONG outputBufferLength = ioStack->Parameters.DeviceIoControl.OutputBufferLength; 25 | 26 | if(!g_pDriverContext->Initialized) return (Irp->IoStatus.Status = STATUS_INTERNAL_ERROR); 27 | 28 | switch(ioStack->MajorFunction) { 29 | case IRP_MJ_DEVICE_CONTROL: 30 | { 31 | ioControlCode = ioStack->Parameters.DeviceIoControl.IoControlCode; 32 | switch(ioControlCode) { 33 | case RESURGENCE_QUERY_OSVERSION: 34 | { 35 | if(outputBufferLength == RESURGENCE_QUERY_OSVERSION_SIZE) { 36 | VERSION_INFO info; 37 | Irp->IoStatus.Status = RDrvQueryOSVersion(&info); 38 | if(NT_SUCCESS(Irp->IoStatus.Status)) { 39 | RtlCopyMemory(ioBuffer, &info, RESURGENCE_QUERY_OSVERSION_SIZE); 40 | Irp->IoStatus.Information = RESURGENCE_QUERY_OSVERSION_SIZE; 41 | } 42 | } else { 43 | Irp->IoStatus.Status = STATUS_INFO_LENGTH_MISMATCH; 44 | } 45 | break; 46 | } 47 | case RESURGENCE_VM_OPERATION: 48 | { 49 | if(inputBufferLength == RESURGENCE_VM_OPERATION_SIZE && 50 | outputBufferLength == RESURGENCE_VM_OPERATION_SIZE) { 51 | Irp->IoStatus.Status = RDrvVirtualMemoryOperation((PVM_OPERATION)ioBuffer); 52 | if(NT_SUCCESS(Irp->IoStatus.Status)) { 53 | Irp->IoStatus.Information = RESURGENCE_VM_OPERATION_SIZE; 54 | } 55 | } else { 56 | Irp->IoStatus.Status = STATUS_INFO_LENGTH_MISMATCH; 57 | } 58 | break; 59 | } 60 | case RESURGENCE_VM_READ: 61 | { 62 | if(inputBufferLength == RESURGENCE_VM_READ_SIZE && 63 | outputBufferLength == RESURGENCE_VM_READ_SIZE) { 64 | Irp->IoStatus.Status = RDrvReadWriteVirtualMemory((PVM_READ_WRITE)ioBuffer, FALSE); 65 | if(NT_SUCCESS(Irp->IoStatus.Status)) { 66 | Irp->IoStatus.Information = RESURGENCE_VM_READ_SIZE; 67 | } 68 | } else { 69 | Irp->IoStatus.Status = STATUS_INFO_LENGTH_MISMATCH; 70 | } 71 | break; 72 | } 73 | case RESURGENCE_VM_WRITE: 74 | { 75 | if(inputBufferLength == RESURGENCE_VM_WRITE_SIZE && 76 | outputBufferLength == RESURGENCE_VM_WRITE_SIZE) { 77 | Irp->IoStatus.Status = RDrvReadWriteVirtualMemory((PVM_READ_WRITE)ioBuffer, TRUE); 78 | if(NT_SUCCESS(Irp->IoStatus.Status)) { 79 | Irp->IoStatus.Information = RESURGENCE_VM_WRITE_SIZE; 80 | } 81 | } else { 82 | Irp->IoStatus.Status = STATUS_INFO_LENGTH_MISMATCH; 83 | } 84 | break; 85 | } 86 | case RESURGENCE_VM_QUERY: 87 | { 88 | if(inputBufferLength == RESURGENCE_VM_QUERY_SIZE && 89 | outputBufferLength == RESURGENCE_VM_QUERY_SIZE) { 90 | Irp->IoStatus.Status = RDrvQueyVirtualMemory((PVM_QUERY_INFO)ioBuffer); 91 | if(NT_SUCCESS(Irp->IoStatus.Status)) { 92 | Irp->IoStatus.Information = RESURGENCE_VM_QUERY_SIZE; 93 | } 94 | } else { 95 | Irp->IoStatus.Status = STATUS_INFO_LENGTH_MISMATCH; 96 | } 97 | break; 98 | } 99 | case RESURGENCE_GRANT_ACCESS: 100 | { 101 | if(inputBufferLength == RESURGENCE_GRANT_ACCESS_SIZE && 102 | outputBufferLength == RESURGENCE_GRANT_ACCESS_SIZE) { 103 | Irp->IoStatus.Status = RDrvGrantHandleAccess((PGRANT_ACCESS)ioBuffer); 104 | if(NT_SUCCESS(Irp->IoStatus.Status)) { 105 | Irp->IoStatus.Information = RESURGENCE_VM_QUERY_SIZE; 106 | } 107 | } else { 108 | Irp->IoStatus.Status = STATUS_INFO_LENGTH_MISMATCH; 109 | } 110 | break; 111 | } 112 | case RESURGENCE_PROTECT_PROCESS: 113 | { 114 | if(inputBufferLength == RESURGENCE_PROTECT_PROCESS_SIZE) { 115 | Irp->IoStatus.Status = RDrvProtectProcess((PPROTECT_PROCESS)ioBuffer); 116 | if(NT_SUCCESS(Irp->IoStatus.Status)) { 117 | Irp->IoStatus.Information = RESURGENCE_PROTECT_PROCESS_SIZE; 118 | } 119 | } else { 120 | Irp->IoStatus.Status = STATUS_INFO_LENGTH_MISMATCH; 121 | } 122 | break; 123 | } 124 | case RESURGENCE_OPEN_PROCESS: 125 | { 126 | if(inputBufferLength == RESURGENCE_OPEN_PROCESS_SIZE && 127 | outputBufferLength == RESURGENCE_OPEN_PROCESS_SIZE) { 128 | Irp->IoStatus.Status = RDrvOpenProcess((POPEN_PROCESS)ioBuffer); 129 | if(NT_SUCCESS(Irp->IoStatus.Status)) { 130 | Irp->IoStatus.Information = RESURGENCE_OPEN_PROCESS_SIZE; 131 | } 132 | } else { 133 | Irp->IoStatus.Status = STATUS_INFO_LENGTH_MISMATCH; 134 | } 135 | break; 136 | } 137 | case RESURGENCE_SET_DEP_STATE: 138 | { 139 | if(inputBufferLength == RESURGENCE_SET_DEP_STATE_SIZE) { 140 | Irp->IoStatus.Status = RDrvSetProcessDEP((PSET_DEP_STATE)ioBuffer); 141 | if(NT_SUCCESS(Irp->IoStatus.Status)) { 142 | Irp->IoStatus.Information = RESURGENCE_PROTECT_PROCESS_SIZE; 143 | } 144 | } else { 145 | Irp->IoStatus.Status = STATUS_INFO_LENGTH_MISMATCH; 146 | } 147 | break; 148 | } 149 | case RESURGENCE_INJECT_MODULE: 150 | { 151 | if(inputBufferLength == RESURGENCE_INJECT_MODULE_SIZE && 152 | outputBufferLength == RESURGENCE_INJECT_MODULE_SIZE) { 153 | Irp->IoStatus.Status = RDrvInjectModule((PINJECT_MODULE)ioBuffer); 154 | if(NT_SUCCESS(Irp->IoStatus.Status)) { 155 | Irp->IoStatus.Information = RESURGENCE_INJECT_MODULE_SIZE; 156 | } 157 | } else { 158 | Irp->IoStatus.Status = STATUS_INFO_LENGTH_MISMATCH; 159 | } 160 | break; 161 | } 162 | default: 163 | DPRINT("Unknown IRP_MJ_DEVICE_CONTROL 0x%X", ioControlCode); 164 | Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; 165 | break; 166 | } 167 | break; 168 | } 169 | case IRP_MJ_CREATE: 170 | case IRP_MJ_CLOSE: 171 | Irp->IoStatus.Status = STATUS_SUCCESS; 172 | break; 173 | default: 174 | Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; 175 | break; 176 | } 177 | 178 | IoCompleteRequest(Irp, IO_NO_INCREMENT); 179 | 180 | return Irp->IoStatus.Status; 181 | } 182 | -------------------------------------------------------------------------------- /ResurgenceDrv/dispatch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Internal.h" 4 | 5 | /// 6 | /// The drivers I/O dispatcher 7 | /// 8 | /// 9 | /// The device to which the request was sent. 10 | /// A single driver cna have multiple devices 11 | /// 12 | /// The I/O Request Packet sent by the I/O Manager 13 | /// 14 | NTSTATUS RDrvDispatch( 15 | __in PDEVICE_OBJECT DeviceObject, 16 | __in PIRP Irp 17 | ); 18 | -------------------------------------------------------------------------------- /ResurgenceDrv/driver_entry.c: -------------------------------------------------------------------------------- 1 | #include "internal.h" 2 | #include "dispatch.h" 3 | #include "routines.h" 4 | 5 | PDRIVER_CONTEXT g_pDriverContext = NULL; 6 | PIMAGE_MAP_DATA g_pImageData = NULL; 7 | BOOLEAN g_bLoadedByTDL; 8 | 9 | NTSTATUS DriverEntry( 10 | __in PDRIVER_OBJECT DriverObject, 11 | __in PUNICODE_STRING RegistryPath 12 | ); 13 | 14 | NTSTATUS InitializeDriver( 15 | __in PDRIVER_OBJECT DriverObject, 16 | __in PUNICODE_STRING RegistryPath 17 | ); 18 | 19 | NTSTATUS DriverContextInit( 20 | VOID 21 | ); 22 | 23 | NTSTATUS DriverLoadDynamicData( 24 | VOID 25 | ); 26 | 27 | #pragma alloc_text(INIT, DriverEntry) 28 | #pragma alloc_text(PAGE, InitializeDriver) 29 | #pragma alloc_text(PAGE, DriverContextInit) 30 | #pragma alloc_text(PAGE, DriverLoadDynamicData) 31 | 32 | /// 33 | /// Defines the driver entry point 34 | /// 35 | /// 36 | /// A pointer to a DRIVER_OBJECT structure. This is the driver's driver object. 37 | /// 38 | /// 39 | /// A pointer to a counted Unicode string specifying the path to the driver's registry key. 40 | /// 41 | /// The status code 42 | NTSTATUS DriverEntry( 43 | __in PDRIVER_OBJECT DriverObject, 44 | __in PUNICODE_STRING RegistryPath 45 | ) 46 | { 47 | NTSTATUS status = STATUS_SUCCESS; 48 | UNICODE_STRING drvName; 49 | 50 | DPRINT("DriverEntry called!"); 51 | 52 | UNREFERENCED_PARAMETER(DriverObject); 53 | UNREFERENCED_PARAMETER(RegistryPath); 54 | 55 | if(DriverObject != NULL) { 56 | 57 | // 58 | // Magic matches. It was mapped by the TDL shellcode 59 | // 60 | if(((PIMAGE_MAP_DATA)DriverObject)->Magic == 0xFF00FF00AABBCCDD) { 61 | DPRINT("Creating DriverObject!"); 62 | // 63 | //Extract the image data that is sent as the first parameter to DriverEntry by the TDL shellcode 64 | // 65 | g_pImageData = (PIMAGE_MAP_DATA)DriverObject; 66 | g_bLoadedByTDL = TRUE; 67 | RtlInitUnicodeString(&drvName, L"\\Driver\\" RDRV_DRIVER_NAME); 68 | status = IoCreateDriver(&drvName, &InitializeDriver); 69 | if(!NT_SUCCESS(status)) { 70 | DPRINT("IoCreateDriver failed with status %lX", status); 71 | } 72 | } 73 | // 74 | // Magic is different. It wasnt mapped by TDL. Do regular initialization 75 | // 76 | else { 77 | g_bLoadedByTDL = FALSE; 78 | status = InitializeDriver(DriverObject, RegistryPath); 79 | if(!NT_SUCCESS(status)) { 80 | DPRINT("InitializeDriver failed with status %lX", status); 81 | } 82 | } 83 | } 84 | return status; 85 | } 86 | 87 | NTSTATUS InitializeDriver( 88 | __in PDRIVER_OBJECT DriverObject, 89 | __in PUNICODE_STRING RegistryPath 90 | ) 91 | { 92 | NTSTATUS status = STATUS_SUCCESS; 93 | UNICODE_STRING usDosDeviceName, usDeviceName; 94 | PDEVICE_OBJECT pDevObj = NULL; 95 | 96 | UNREFERENCED_PARAMETER(RegistryPath); 97 | DPRINT("Initializing driver!", status); 98 | 99 | RtlInitUnicodeString(&usDeviceName, RDRV_DEVICE_NAME); 100 | RtlInitUnicodeString(&usDosDeviceName, RDRV_DOSDEVICE_NAME); 101 | 102 | status = IoCreateDevice( 103 | DriverObject, 104 | sizeof(DRIVER_CONTEXT), 105 | &usDeviceName, 106 | RDRV_DEV_TYPE, 107 | FILE_DEVICE_SECURE_OPEN, 108 | FALSE, &pDevObj); 109 | 110 | if(!NT_SUCCESS(status)) { 111 | DPRINT("IoCreateDevice failed with status %lX", status); 112 | return status; 113 | } 114 | 115 | g_pDriverContext = (PDRIVER_CONTEXT)pDevObj->DeviceExtension; 116 | RtlZeroMemory(g_pDriverContext, sizeof(DRIVER_CONTEXT)); 117 | 118 | status = IoCreateSymbolicLink(&usDosDeviceName, &usDeviceName); 119 | 120 | if(!NT_SUCCESS(status)) { 121 | DPRINT("IoCreateSymbolicLink failed with status %lX", status); 122 | return status; 123 | } 124 | 125 | DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = &RDrvDispatch; 126 | DriverObject->MajorFunction[IRP_MJ_CREATE] = &RDrvDispatch; 127 | DriverObject->MajorFunction[IRP_MJ_CLOSE] = &RDrvDispatch; 128 | DriverObject->DriverUnload = NULL; 129 | 130 | if(g_bLoadedByTDL) { 131 | RtlCopyMemory(&g_pDriverContext->ImageData, g_pImageData, sizeof(IMAGE_MAP_DATA)); 132 | ExFreePoolWithTag((PVOID)g_pImageData, 'SldT'); 133 | } else { 134 | g_pDriverContext->ImageData.ImageBase = (ULONG_PTR)DriverObject->DriverStart; 135 | g_pDriverContext->ImageData.SizeOfImage = DriverObject->DriverSize; 136 | } 137 | 138 | status = DriverLoadDynamicData(); 139 | 140 | if(!NT_SUCCESS(status)) { 141 | DPRINT("DriverLoadDynamicData failed with status %lX!", status); 142 | return status; 143 | } 144 | 145 | status = DriverContextInit(); 146 | 147 | if(!NT_SUCCESS(status)) { 148 | DPRINT("DriverContextInit failed with status %lX!", status); 149 | return status; 150 | } 151 | 152 | pDevObj->Flags |= IO_TYPE; 153 | pDevObj->Flags &= ~DO_DEVICE_INITIALIZING; 154 | 155 | DPRINT("Initialization completed!"); 156 | return status; 157 | } 158 | 159 | NTSTATUS DriverContextInit( 160 | VOID 161 | ) 162 | { 163 | ULONG_PTR KernelBase; 164 | NTSTATUS status = RDrvGetKernelInfo(&KernelBase, NULL); 165 | if(!NT_SUCCESS(status)) { 166 | DPRINT("RDrvGetKernelInfo failed with status %lX", status); 167 | return status; 168 | } 169 | 170 | #ifdef _WIN10_ 171 | CONST UCHAR Pattern_RtlInsertInvertedTable[] = "\x48\x89\x5C\x24\x00\x55\x56\x57\x48\x83\xEC\x30\x8B\xF2"; 172 | CONST UCHAR Mask_RtlInsertInvertedTable[] = "xxxx?xxxxxxxxx"; 173 | #endif 174 | PUCHAR pResult; 175 | 176 | status = RDrvFindKernelPattern( 177 | Pattern_RtlInsertInvertedTable, 178 | Mask_RtlInsertInvertedTable, 179 | sizeof(Mask_RtlInsertInvertedTable) - 1, 180 | &pResult); 181 | 182 | if(!NT_SUCCESS(status)) { 183 | DPRINT("Failed to retrieve RtlInsertInvertedFunctionTable address!"); 184 | return status; 185 | } 186 | 187 | g_pDriverContext->RtlInsertInvertedFunctionTable = (tRtlInsertInvertedFunctionTable)pResult; 188 | DPRINT("RtlInsertInvertedFunctionTable: 0x%p", g_pDriverContext->RtlInsertInvertedFunctionTable); 189 | 190 | //g_pDriverContext->RtlInsertInvertedFunctionTable(g_pDriverContext->ImageData.ImageBase, g_pDriverContext->ImageData.SizeOfImage); 191 | 192 | g_pDriverContext->Initialized = TRUE; 193 | 194 | return STATUS_SUCCESS; 195 | } 196 | 197 | NTSTATUS DriverLoadDynamicData( 198 | VOID 199 | ) 200 | { 201 | VERSION_INFO version; 202 | NTSTATUS status = RDrvQueryOSVersion(&version); 203 | 204 | if(!NT_SUCCESS(status)) { 205 | PERROR("RDrvQueryOSVersion", status); 206 | return status; 207 | } 208 | 209 | switch(version.VersionLong) { 210 | case 0x0A000000: //Win10 211 | switch(version.BuildNumber) { 212 | default: 213 | DPRINT("Build %d is not known. Values for build %d will be used instead.", version.BuildNumber, 10586); 214 | case 10586: 215 | { 216 | PDYNAMIC_DATA data = &g_pDriverContext->DynData; 217 | data->TargetBuildNumber = 10586; 218 | data->TargetVersion = version.VersionLong; 219 | data->SSDTIndexes.CreateThreadEx = 0x000000B4; 220 | data->SSDTIndexes.TerminateThread = 0x00000053; 221 | data->SSDTIndexes.QueryPerformanceCounter = 0x00000031; 222 | data->SSDTIndexes.ProtectMemory = 0x00000000; 223 | data->Offsets.ExecuteOptions = 0x000001BF; 224 | data->Offsets.ObjectTable = 0x00000418; 225 | data->Offsets.PreviousMode = 0x00000232; 226 | data->Offsets.Protection = 0x000006B2; 227 | break; 228 | } 229 | } 230 | break; 231 | default: 232 | status = STATUS_NOT_SUPPORTED; 233 | } 234 | 235 | return STATUS_SUCCESS; 236 | } -------------------------------------------------------------------------------- /ResurgenceDrv/imports.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "native_enums.h" 9 | #include "native_structs.h" 10 | #include "kernel_imports.h" 11 | #include "zw_imports.h" 12 | 13 | #define THREAD_CREATE_FLAGS_CREATE_SUSPENDED 0x00000001 14 | #define THREAD_CREATE_FLAGS_SKIP_THREAD_ATTACH 0x00000002 15 | #define THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER 0x00000004 16 | 17 | typedef NTSTATUS(NTAPI* tNtTerminateThread)(__in HANDLE ThreadHandle, __in NTSTATUS ExitStatus); 18 | 19 | typedef NTSTATUS(NTAPI* tNtCreateThreadEx) 20 | ( 21 | __out PHANDLE hThread, 22 | __in ACCESS_MASK DesiredAccess, 23 | __in PVOID ObjectAttributes, 24 | __in HANDLE ProcessHandle, 25 | __in PVOID lpStartAddress, 26 | __in PVOID lpParameter, 27 | __in ULONG Flags, 28 | __in SIZE_T StackZeroBits, 29 | __in SIZE_T SizeOfStackCommit, 30 | __in SIZE_T SizeOfStackReserve, 31 | __out PVOID lpBytesBuffer 32 | ); 33 | 34 | typedef NTSTATUS(NTAPI* tNtQueryPerformanceCounter)( 35 | __out PLARGE_INTEGER PerformanceCounter, 36 | __out_opt PLARGE_INTEGER PerformanceFrequency 37 | ); 38 | 39 | #if defined(_WIN8_) || defined (_WIN7_) 40 | 41 | typedef NTSTATUS(NTAPI* fnNtProtectVirtualMemory) 42 | ( 43 | __in HANDLE ProcessHandle, 44 | __in PVOID* BaseAddress, 45 | __in SIZE_T* NumberOfBytesToProtect, 46 | __in ULONG NewAccessProtection, 47 | __out PULONG OldAccessProtection 48 | ); 49 | 50 | NTSTATUS 51 | NTAPI 52 | ZwProtectVirtualMemory( 53 | __in HANDLE ProcessHandle, 54 | __in PVOID* BaseAddress, 55 | __in SIZE_T* NumberOfBytesToProtect, 56 | __in ULONG NewAccessProtection, 57 | __out PULONG OldAccessProtection 58 | ); 59 | 60 | 61 | #else 62 | NTSYSAPI 63 | NTSTATUS 64 | NTAPI 65 | ZwProtectVirtualMemory( 66 | __in HANDLE ProcessHandle, 67 | __in PVOID* BaseAddress, 68 | __in SIZE_T* NumberOfBytesToProtect, 69 | __in ULONG NewAccessProtection, 70 | __out PULONG OldAccessProtection 71 | ); 72 | 73 | #endif 74 | 75 | NTSTATUS 76 | NTAPI 77 | ZwCreateThreadEx( 78 | __out PHANDLE hThread, 79 | __in ACCESS_MASK DesiredAccess, 80 | __in PVOID ObjectAttributes, 81 | __in HANDLE ProcessHandle, 82 | __in PVOID lpStartAddress, 83 | __in PVOID lpParameter, 84 | __in ULONG Flags, 85 | __in SIZE_T StackZeroBits, 86 | __in SIZE_T SizeOfStackCommit, 87 | __in SIZE_T SizeOfStackReserve, 88 | __in PNT_PROC_THREAD_ATTRIBUTE_LIST AttributeList 89 | ); 90 | 91 | NTSTATUS 92 | NTAPI 93 | ZwTerminateThread( 94 | __in HANDLE ThreadHandle, 95 | __in NTSTATUS ExitStatus 96 | ); 97 | 98 | NTSTATUS 99 | NTAPI 100 | ZwQueryPerformanceCounter( 101 | __out PLARGE_INTEGER PerformanceCounter, 102 | __out_opt PLARGE_INTEGER PerformanceFrequency 103 | ); -------------------------------------------------------------------------------- /ResurgenceDrv/injection.c: -------------------------------------------------------------------------------- 1 | #include "internal.h" 2 | #include "injection.h" 3 | #include "utils.h" 4 | 5 | #pragma alloc_text(PAGE, RDrvBuildWow64InjectStub) 6 | #pragma alloc_text(PAGE, RDrvBuildNativeInjectStub) 7 | #pragma alloc_text(PAGE, RDrvInjectLdrLoadDll) 8 | 9 | 10 | NTSTATUS RDrvBuildWow64InjectStub( 11 | __in ULONG_PTR FnLdrLoadDll, 12 | __in PUNICODE_STRING ModulePath, 13 | __out PINJECTION_BUFFER* Buffer 14 | ) 15 | { 16 | NTSTATUS status = STATUS_SUCCESS; 17 | 18 | if(!FnLdrLoadDll) return STATUS_INVALID_PARAMETER_1; 19 | if(!ModulePath) return STATUS_INVALID_PARAMETER_2; 20 | if(!Buffer) return STATUS_INVALID_PARAMETER_3; 21 | 22 | UCHAR pCodeBuffer[] = 23 | { 24 | 0x55, //push ebp // 0x00 25 | 0x89, 0xE5, //mov ebp,esp // 0x01 26 | 0x68, 0x00, 0x00, 0x00, 0x00, //push pModuleHandle // 0x03 27 | 0x68, 0x00, 0x00, 0x00, 0x00, //push pszModulePath // 0x08 28 | 0x6A, 0x00, //push 0 // 0x0D 29 | 0x6A, 0x00, //push 0 // 0x0F 30 | 0xE8, 0x00, 0x00, 0x00, 0x00, //call LdrLoadDll // 0x11 31 | 0x5D, //pop ebp // 0x16 32 | 0xC2, 0x04, 0x00 //ret 4 // 0x17 33 | }; 34 | 35 | SIZE_T regionSize = sizeof(INJECTION_BUFFER); 36 | PINJECTION_BUFFER buff = NULL; 37 | 38 | status = ZwAllocateVirtualMemory(ZwCurrentProcess(), (PVOID*)&buff, 0, ®ionSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); 39 | if(NT_SUCCESS(status)) { 40 | RtlZeroMemory(buff, regionSize); 41 | RtlCopyMemory(buff, pCodeBuffer, sizeof(pCodeBuffer)); 42 | 43 | buff->ModulePath32.Length = ModulePath->Length; 44 | buff->ModulePath32.MaximumLength = ModulePath->MaximumLength; 45 | buff->ModulePath32.Buffer = (ULONG)(ULONG_PTR)buff->PathBuffer; 46 | 47 | RtlCopyMemory((PVOID)buff->PathBuffer, ModulePath->Buffer, ModulePath->Length); 48 | 49 | *(ULONG*)((PUCHAR)buff->CodeBuffer + 0x04) = (ULONG)(ULONG_PTR)&buff->ModuleHandle; 50 | *(ULONG*)((PUCHAR)buff->CodeBuffer + 0x09) = (ULONG)(ULONG_PTR)&buff->ModulePath32; 51 | *(ULONG*)((PUCHAR)buff->CodeBuffer + 0x12) = (ULONG)(ULONG_PTR)(FnLdrLoadDll - ((ULONG_PTR)buff->CodeBuffer + 0x16)); 52 | 53 | *Buffer = buff; 54 | } else { 55 | PERROR("ZwAllocateVirtualMemory", status); 56 | } 57 | return status; 58 | } 59 | 60 | NTSTATUS RDrvBuildNativeInjectStub( 61 | __in ULONG_PTR FnLdrLoadDll, 62 | __in PUNICODE_STRING ModulePath, 63 | __out PINJECTION_BUFFER* Buffer 64 | ) 65 | { 66 | NTSTATUS status = STATUS_SUCCESS; 67 | 68 | if(!FnLdrLoadDll) return STATUS_INVALID_PARAMETER_1; 69 | if(!ModulePath) return STATUS_INVALID_PARAMETER_2; 70 | if(!Buffer) return STATUS_INVALID_PARAMETER_3; 71 | 72 | UCHAR pCodeBuffer[] = 73 | { 74 | 0x48, 0x83, 0xEC, 0x28, // sub rsp, 0x28 75 | 0x48, 0x31, 0xC9, // xor rcx, rcx 76 | 0x48, 0x31, 0xD2, // xor rdx, rdx 77 | 0x49, 0xB8, 0, 0, 0, 0, 0, 0, 0, 0, // mov r8, ModuleFileName offset +12 78 | 0x49, 0xB9, 0, 0, 0, 0, 0, 0, 0, 0, // mov r9, ModuleHandle offset +20 79 | 0x48, 0xB8, 0, 0, 0, 0, 0, 0, 0, 0, // mov rax, LdrLoadDll offset +32 80 | 0xFF, 0xD0, // call rax 81 | 0x48, 0x83, 0xC4, 0x28, // add rsp, 0x28 82 | 0xC3 // ret 83 | }; 84 | 85 | SIZE_T regionSize = sizeof(INJECTION_BUFFER); 86 | PINJECTION_BUFFER buff = NULL; 87 | 88 | status = ZwAllocateVirtualMemory(ZwCurrentProcess(), (PVOID*)&buff, 0, ®ionSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); 89 | if(NT_SUCCESS(status)) { 90 | RtlZeroMemory(buff, regionSize); 91 | RtlCopyMemory(buff, pCodeBuffer, sizeof(pCodeBuffer)); 92 | 93 | buff->ModulePath64.Length = 0; 94 | buff->ModulePath64.MaximumLength = sizeof(buff->PathBuffer); 95 | buff->ModulePath64.Buffer = buff->PathBuffer; 96 | 97 | RtlUnicodeStringCopy(&buff->ModulePath64, ModulePath); 98 | 99 | *(ULONG_PTR*)((PUCHAR)buff->CodeBuffer + 0x0C) = (ULONG_PTR)&buff->ModulePath64; 100 | *(ULONG_PTR*)((PUCHAR)buff->CodeBuffer + 0x16) = (ULONG_PTR)&buff->ModuleHandle; 101 | *(ULONG_PTR*)((PUCHAR)buff->CodeBuffer + 0x20) = (ULONG_PTR)FnLdrLoadDll; 102 | 103 | *Buffer = buff; 104 | } else { 105 | PERROR("ZwAllocateVirtualMemory", status); 106 | } 107 | return status; 108 | } 109 | 110 | NTSTATUS RDrvInjectLdrLoadDll( 111 | __in PEPROCESS Process, 112 | __in PWCHAR ModulePath, 113 | __out PULONG_PTR ModuleBase 114 | ) 115 | { 116 | NTSTATUS status; 117 | ULONG_PTR fnLdrLoadDll; 118 | BOOLEAN isWow64; 119 | KAPC_STATE apcState; 120 | 121 | DPRINT("Injecting file %ws to process %X", ModulePath, PsGetProcessId(Process)); 122 | 123 | isWow64 = !!PsGetProcessWow64Process(Process); 124 | KeStackAttachProcess(Process, &apcState); 125 | if(isWow64) { 126 | PLDR_DATA_TABLE_ENTRY32 ntdll; 127 | RDrvGetModuleEntry32(Process, L"ntdll.dll", &ntdll); 128 | status = RDrvGetProcAddress((ULONG_PTR)ntdll->DllBase, "LdrLoadDll", &fnLdrLoadDll); 129 | } else { 130 | PLDR_DATA_TABLE_ENTRY ntdll; 131 | RDrvGetModuleEntry(Process, L"ntdll.dll", &ntdll); 132 | status = RDrvGetProcAddress((ULONG_PTR)ntdll->DllBase, "LdrLoadDll", &fnLdrLoadDll); 133 | } 134 | if(fnLdrLoadDll != 0) { 135 | DPRINT("LdrLoadDll found at %p", fnLdrLoadDll); 136 | 137 | UNICODE_STRING szModulePath; 138 | RtlInitUnicodeString(&szModulePath, ModulePath); 139 | 140 | PINJECTION_BUFFER pBuffer = NULL; 141 | status = isWow64 ? 142 | RDrvBuildWow64InjectStub(fnLdrLoadDll, &szModulePath, &pBuffer) : 143 | RDrvBuildNativeInjectStub(fnLdrLoadDll, &szModulePath, &pBuffer); 144 | 145 | DPRINT("Injection stub written to %p", pBuffer); 146 | 147 | if(ModuleBase) 148 | *ModuleBase = 0; 149 | 150 | if(NT_SUCCESS(status)) { 151 | ULONG_PTR exitCode; 152 | status = RDrvCreateUserThread((PVOID)pBuffer, NULL, TRUE, &exitCode); 153 | if(NT_SUCCESS(status)) { 154 | status = (NTSTATUS)exitCode; 155 | if(NT_SUCCESS(status)) { 156 | if(ModuleBase) 157 | *ModuleBase = (ULONG_PTR)pBuffer->ModuleHandle; 158 | } else { 159 | PERROR("LdrLoadDll", status); 160 | } 161 | } else 162 | PERROR("RDrvCreateUserThread", status); 163 | } else 164 | PERROR("RDrvBuildWow64InjectStub/RDrvBuildNativeInjectStub", status); 165 | } else 166 | PERROR("RDrvGetProcAddress", status); 167 | 168 | KeUnstackDetachProcess(&apcState); 169 | 170 | return status; 171 | } 172 | 173 | -------------------------------------------------------------------------------- /ResurgenceDrv/injection.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | NTSTATUS RDrvBuildWow64InjectStub( 4 | __in ULONG_PTR FnLdrLoadDll, 5 | __in PUNICODE_STRING ModulePath, 6 | __out PINJECTION_BUFFER* Buffer 7 | ); 8 | 9 | NTSTATUS RDrvBuildNativeInjectStub( 10 | __in ULONG_PTR FnLdrLoadDll, 11 | __in PUNICODE_STRING ModulePath, 12 | __out PINJECTION_BUFFER* Buffer 13 | ); 14 | 15 | NTSTATUS RDrvInjectLdrLoadDll( 16 | __in PEPROCESS Process, 17 | __in PWCHAR ModulePath, 18 | __out PULONG_PTR ModuleBase 19 | ); 20 | 21 | -------------------------------------------------------------------------------- /ResurgenceDrv/internal.c: -------------------------------------------------------------------------------- 1 | #include "internal.h" 2 | 3 | #pragma alloc_text(PAGE, ExpLookupHandleTableEntry) 4 | 5 | PHANDLE_TABLE_ENTRY ExpLookupHandleTableEntry( 6 | __in PHANDLE_TABLE HandleTable, 7 | __in EXHANDLE ExHandle 8 | ) 9 | { 10 | #ifdef _WIN10_ 11 | ULONG_PTR HandleValue; // rdx@1 12 | ULONG_PTR TableCode; // r8@2 13 | ULONG_PTR TableLevel; // rax@2 14 | ULONG_PTR HandleArray; // rax@3 15 | PHANDLE_TABLE_ENTRY result; // rax@4 16 | 17 | HandleValue = ExHandle.Value & 0xFFFFFFFFFFFFFFFCui64; 18 | if(HandleValue >= HandleTable->NextHandleNeedingPool) { 19 | result = NULL; 20 | } else { 21 | TableCode = HandleTable->TableCode; 22 | TableLevel = HandleTable->TableCode & 3; 23 | if(TableLevel == 1) { 24 | HandleArray = *(ULONG_PTR*)(TableCode + 8 * (HandleValue >> 10) - 1); 25 | return (PHANDLE_TABLE_ENTRY)(HandleArray + 4 * (HandleValue & 0x3FF)); 26 | } 27 | if(TableLevel) { 28 | HandleArray = *(ULONG_PTR*)(*(ULONG_PTR*)(TableCode + 8 * (HandleValue >> 19) - 2) + 8 * ((HandleValue >> 10) & 0x1FF)); 29 | return (PHANDLE_TABLE_ENTRY)(HandleArray + 4 * (HandleValue & 0x3FF)); 30 | } 31 | result = (PHANDLE_TABLE_ENTRY)(TableCode + 4 * HandleValue); 32 | } 33 | return result; 34 | #else 35 | #error "Unsupported" 36 | #endif 37 | } 38 | -------------------------------------------------------------------------------- /ResurgenceDrv/internal.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef _M_IX86 4 | #error "x86 systems are not supported" 5 | #endif 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "imports.h" 13 | #include "utils.h" 14 | #include "ResurgenceDrv.h" 15 | 16 | #define RDRV_DRIVER_NAME L"ResurgenceDrv" 17 | #define RDRV_POOLTAG 'vrDR' 18 | #define IO_TYPE DO_BUFFERED_IO 19 | 20 | #define LOG_TO_FILE 21 | #define _DEBUG 22 | 23 | #ifdef _DEBUG 24 | # ifdef LOG_TO_FILE 25 | # define DPRINT(str, ...) RDrvLogToFile("%ws | %-30s | " str "\r\n", RDRV_DRIVER_NAME, __FUNCTION__, __VA_ARGS__) 26 | # else 27 | # define DPRINT(str, ...) DbgPrint("%ws: " str, RDRV_DRIVER_NAME, __VA_ARGS__) 28 | # endif 29 | #else 30 | # define DPRINT(str, ...) 31 | #endif 32 | 33 | #ifndef PERROR 34 | #define PERROR(f, s) DPRINT(f " failed with status %lX", s) 35 | #endif 36 | 37 | #ifndef PEXCEPTION 38 | #define PEXCEPTION() DPRINT("Exception: %lX", GetExceptionCode()) 39 | #endif 40 | 41 | typedef struct _DYNAMIC_DATA 42 | { 43 | ULONG TargetVersion; 44 | ULONG TargetBuildNumber; 45 | struct 46 | { 47 | ULONG CreateThreadEx; 48 | ULONG TerminateThread; 49 | ULONG QueryPerformanceCounter; 50 | ULONG ProtectMemory; 51 | } SSDTIndexes; 52 | struct 53 | { 54 | ULONG PreviousMode; 55 | ULONG ObjectTable; 56 | ULONG Protection; 57 | ULONG ExecuteOptions; 58 | } Offsets; 59 | } DYNAMIC_DATA, *PDYNAMIC_DATA; 60 | 61 | typedef struct _IMAGE_MAP_DATA 62 | { 63 | ULONG_PTR Magic; 64 | ULONG_PTR ImageBase; 65 | ULONG SizeOfImage; 66 | } IMAGE_MAP_DATA, *PIMAGE_MAP_DATA; 67 | 68 | #ifdef _WIN10_ 69 | typedef void(NTAPI* tRtlInsertInvertedFunctionTable)(ULONG_PTR ImageBase, ULONG ImageSize); 70 | #else 71 | #pragma error "Unsupported build" 72 | #endif 73 | 74 | #define EX_ADDITIONAL_INFO_SIGNATURE (ULONG_PTR)(-2) 75 | #define INJECTION_BUFFER_SIZE 0x100 76 | 77 | #define ExpIsValidObjectEntry(Entry) \ 78 | ( (Entry != NULL) && (Entry->LowValue != 0) && (Entry->HighValue != EX_ADDITIONAL_INFO_SIGNATURE) ) 79 | 80 | typedef struct _DRIVER_CONTEXT 81 | { 82 | BOOLEAN Initialized; 83 | IMAGE_MAP_DATA ImageData; 84 | PVOID KrnlBase; 85 | SIZE_T KrnlSize; 86 | DYNAMIC_DATA DynData; 87 | PSYSTEM_SERVICE_DESCRIPTOR_TABLE SSDT; 88 | // 89 | // Functions 90 | // 91 | tRtlInsertInvertedFunctionTable RtlInsertInvertedFunctionTable; 92 | 93 | } DRIVER_CONTEXT, *PDRIVER_CONTEXT; 94 | 95 | typedef struct _INJECTION_BUFFER 96 | { 97 | UCHAR CodeBuffer[INJECTION_BUFFER_SIZE]; 98 | PULONG_PTR ModuleHandle; 99 | UNICODE_STRING ModulePath64; 100 | UNICODE_STRING32 ModulePath32; 101 | WCHAR PathBuffer[MAX_PATH]; 102 | } INJECTION_BUFFER, *PINJECTION_BUFFER; 103 | 104 | extern PDRIVER_CONTEXT g_pDriverContext; 105 | 106 | PHANDLE_TABLE_ENTRY ExpLookupHandleTableEntry( 107 | __in PHANDLE_TABLE HandleTable, 108 | __in EXHANDLE ExHandle 109 | ); 110 | 111 | FORCEINLINE 112 | BOOLEAN 113 | RemoveEntryListUnsafe32( 114 | _In_ PLIST_ENTRY32 Entry 115 | ) 116 | { 117 | PLIST_ENTRY32 Blink; 118 | PLIST_ENTRY32 Flink; 119 | 120 | Flink = (PLIST_ENTRY32)Entry->Flink; 121 | Blink = (PLIST_ENTRY32)Entry->Blink; 122 | Blink->Flink = (ULONG)(ULONG_PTR)Flink; 123 | Flink->Blink = (ULONG)(ULONG_PTR)Blink; 124 | return (BOOLEAN)(Flink == Blink); 125 | } -------------------------------------------------------------------------------- /ResurgenceDrv/kernel_imports.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | NTKERNELAPI 4 | NTSTATUS 5 | IoCreateDriver( 6 | __in PUNICODE_STRING DriverName, 7 | __in PDRIVER_INITIALIZE InitializationFunction 8 | ); 9 | 10 | NTKERNELAPI 11 | NTSTATUS 12 | NTAPI 13 | MmCopyVirtualMemory( 14 | __in PEPROCESS FromProcess, 15 | __in PVOID FromAddress, 16 | __in PEPROCESS ToProcess, 17 | __out PVOID ToAddress, 18 | __in SIZE_T BufferSize, 19 | __in KPROCESSOR_MODE PreviousMode, 20 | __out PSIZE_T NumberOfBytesCopied 21 | ); 22 | 23 | NTKERNELAPI 24 | PPEB 25 | NTAPI 26 | PsGetProcessPeb( 27 | __in PEPROCESS Process 28 | ); 29 | 30 | NTKERNELAPI 31 | PVOID 32 | NTAPI 33 | PsGetThreadTeb( 34 | __in PETHREAD Thread 35 | ); 36 | 37 | NTKERNELAPI 38 | PVOID 39 | NTAPI 40 | PsGetProcessWow64Process( 41 | __in PEPROCESS Process 42 | ); 43 | 44 | NTKERNELAPI 45 | PVOID 46 | NTAPI 47 | PsGetCurrentProcessWow64Process(); 48 | 49 | NTKERNELAPI 50 | BOOLEAN 51 | NTAPI 52 | KeTestAlertThread( 53 | __in KPROCESSOR_MODE AlertMode 54 | ); 55 | 56 | NTKERNELAPI 57 | BOOLEAN 58 | NTAPI 59 | PsIsProtectedProcess( 60 | __in PEPROCESS Process 61 | ); 62 | 63 | NTKERNELAPI 64 | NTSTATUS 65 | NTAPI 66 | PsLookupProcessThreadByCid( 67 | __in PCLIENT_ID ClientId, 68 | __out_opt PEPROCESS *Process, 69 | __out PETHREAD *Thread 70 | ); 71 | 72 | NTKERNELAPI 73 | PVOID 74 | NTAPI 75 | PsGetThreadWin32Thread( 76 | __in PETHREAD Thread 77 | ); 78 | 79 | typedef VOID(NTAPI *PKNORMAL_ROUTINE) 80 | ( 81 | PVOID NormalContext, 82 | PVOID SystemArgument1, 83 | PVOID SystemArgument2 84 | ); 85 | 86 | typedef VOID(NTAPI* PKKERNEL_ROUTINE) 87 | ( 88 | PRKAPC Apc, 89 | PKNORMAL_ROUTINE *NormalRoutine, 90 | PVOID *NormalContext, 91 | PVOID *SystemArgument1, 92 | PVOID *SystemArgument2 93 | ); 94 | 95 | typedef VOID(NTAPI *PKRUNDOWN_ROUTINE)(PRKAPC Apc); 96 | 97 | NTKERNELAPI 98 | VOID 99 | NTAPI 100 | KeInitializeApc( 101 | __in PKAPC Apc, 102 | __in PKTHREAD Thread, 103 | __in KAPC_ENVIRONMENT ApcStateIndex, 104 | __in PKKERNEL_ROUTINE KernelRoutine, 105 | __in PKRUNDOWN_ROUTINE RundownRoutine, 106 | __in PKNORMAL_ROUTINE NormalRoutine, 107 | __in KPROCESSOR_MODE ApcMode, 108 | __in PVOID NormalContext 109 | ); 110 | 111 | NTKERNELAPI 112 | BOOLEAN 113 | NTAPI 114 | KeInsertQueueApc( 115 | PKAPC Apc, 116 | PVOID SystemArgument1, 117 | PVOID SystemArgument2, 118 | KPRIORITY Increment 119 | ); 120 | 121 | NTSYSAPI 122 | PIMAGE_NT_HEADERS 123 | NTAPI 124 | RtlImageNtHeader( 125 | __in PVOID Base 126 | ); 127 | 128 | NTSYSAPI 129 | PVOID 130 | NTAPI 131 | RtlImageDirectoryEntryToData( 132 | PVOID ImageBase, 133 | BOOLEAN MappedAsImage, 134 | USHORT DirectoryEntry, 135 | PULONG Size 136 | ); -------------------------------------------------------------------------------- /ResurgenceDrv/memory.c: -------------------------------------------------------------------------------- 1 | #include "routines.h" 2 | 3 | #pragma alloc_text(PAGE, RDrvQueyVirtualMemory) 4 | #pragma alloc_text(PAGE, RDrvVirtualMemoryOperation) 5 | #pragma alloc_text(PAGE, RDrvReadWriteVirtualMemory) 6 | 7 | NTSTATUS RDrvQueyVirtualMemory( 8 | __inout PVM_QUERY_INFO Params 9 | ) 10 | { 11 | if(!Params) return STATUS_INVALID_PARAMETER; 12 | 13 | NTSTATUS status; 14 | KAPC_STATE apcState; 15 | BOOLEAN attached = FALSE; 16 | PEPROCESS process = NULL; 17 | MEMORY_BASIC_INFORMATION memoryInfo; 18 | SIZE_T cbNeeded = 0; 19 | 20 | __try { 21 | status = PsLookupProcessByProcessId((HANDLE)Params->In.ProcessId, &process); 22 | if(NT_SUCCESS(status)) { 23 | if(process != PsGetCurrentProcess()) { 24 | KeStackAttachProcess(process, &apcState); 25 | attached = TRUE; 26 | } 27 | status = ZwQueryVirtualMemory( 28 | ZwCurrentProcess(), 29 | (PVOID)Params->In.BaseAddress, 30 | MemoryBasicInformation, &memoryInfo, 31 | sizeof(memoryInfo), &cbNeeded); 32 | if(NT_SUCCESS(status)) { 33 | RtlCopyMemory((PVOID)&Params->Out, (PVOID)&memoryInfo, sizeof(memoryInfo)); 34 | } else { 35 | PERROR("ZwQueryVirtualMemory", status); 36 | } 37 | } else { 38 | PERROR("PsLookupProcessByProcessId", status); 39 | } 40 | } __except(EXCEPTION_EXECUTE_HANDLER) 41 | { 42 | PEXCEPTION(); 43 | status = GetExceptionCode(); 44 | } 45 | if(attached == TRUE) 46 | KeUnstackDetachProcess(&apcState); 47 | if(process != NULL) 48 | ObDereferenceObject(process); 49 | return status; 50 | } 51 | 52 | NTSTATUS RDrvVirtualMemoryOperation( 53 | __inout PVM_OPERATION Params 54 | ) 55 | { 56 | if(!Params) return STATUS_INVALID_PARAMETER; 57 | 58 | NTSTATUS status = STATUS_SUCCESS; 59 | KAPC_STATE apcState; 60 | PEPROCESS process = NULL; 61 | BOOLEAN attached = FALSE; 62 | ULONG proccessId = Params->In.ProcessId; 63 | ULONG_PTR baseAddress = Params->In.BaseAddress; 64 | ULONG allocationFlags = Params->In.AllocationFlags; 65 | ULONG protectionFlags = Params->In.ProtectionFlags; 66 | SIZE_T regionSize = Params->In.RegionSize; 67 | ULONG freeType = Params->In.FreeType; 68 | 69 | __try { 70 | status = PsLookupProcessByProcessId((HANDLE)proccessId, &process); 71 | if(NT_SUCCESS(status)) { 72 | if(process != PsGetCurrentProcess()) { 73 | KeStackAttachProcess(process, &apcState); 74 | attached = TRUE; 75 | } 76 | 77 | switch(Params->In.Operation) { 78 | case VM_OPERATION_ALLOC: 79 | { 80 | status = ZwAllocateVirtualMemory(ZwCurrentProcess(), (PVOID*)&baseAddress, 0, ®ionSize, allocationFlags, protectionFlags); 81 | if(NT_SUCCESS(status)) { 82 | Params->Out.BaseAddress = baseAddress; 83 | Params->Out.RegionSize = regionSize; 84 | } else { 85 | PERROR("ZwAllocateVirtualMemory", status); 86 | } 87 | break; 88 | } 89 | case VM_OPERATION_FREE: 90 | { 91 | status = ZwFreeVirtualMemory(ZwCurrentProcess(), (PVOID*)&baseAddress, ®ionSize, freeType); 92 | if(NT_SUCCESS(status)) { 93 | Params->Out.BaseAddress = baseAddress; 94 | Params->Out.RegionSize = regionSize; 95 | } else { 96 | PERROR("ZwFreeVirtualMemory", status); 97 | } 98 | break; 99 | } 100 | case VM_OPERATION_PROTECT: 101 | { 102 | ULONG oldProt; 103 | status = ZwProtectVirtualMemory(ZwCurrentProcess(), (PVOID*)&baseAddress, ®ionSize, protectionFlags, &oldProt); 104 | if(NT_SUCCESS(status)) { 105 | Params->Out.BaseAddress = baseAddress; 106 | Params->Out.RegionSize = regionSize; 107 | Params->Out.OldProtection = oldProt; 108 | } else { 109 | PERROR("ZwProtectVirtualMemory", status); 110 | } 111 | break; 112 | } 113 | default: 114 | status = STATUS_INVALID_PARAMETER; 115 | break; 116 | } 117 | } else { 118 | PERROR("PsLookupProcessByProcessId", status); 119 | } 120 | } __except(EXCEPTION_EXECUTE_HANDLER) 121 | { 122 | PEXCEPTION(); 123 | status = GetExceptionCode(); 124 | } 125 | if(attached == TRUE) 126 | KeUnstackDetachProcess(&apcState); 127 | if(process != NULL) 128 | ObDereferenceObject(process); 129 | return status; 130 | } 131 | 132 | NTSTATUS RDrvReadWriteVirtualMemory( 133 | __inout PVM_READ_WRITE Params, 134 | __in BOOLEAN Write 135 | ) 136 | { 137 | NTSTATUS status; 138 | PEPROCESS fromProcess; 139 | ULONG_PTR fromAddress; 140 | PEPROCESS toProcess; 141 | ULONG_PTR toAddress; 142 | SIZE_T bytesCopied; 143 | 144 | if(!Params) return STATUS_INVALID_PARAMETER; 145 | 146 | if(Write == TRUE) { 147 | fromAddress = Params->Buffer; 148 | fromProcess = PsGetCurrentProcess(); 149 | toAddress = Params->TargetAddress; 150 | status = PsLookupProcessByProcessId((HANDLE)Params->ProcessId, &toProcess); 151 | } else { 152 | fromAddress = Params->TargetAddress; 153 | status = PsLookupProcessByProcessId((HANDLE)Params->ProcessId, &fromProcess); 154 | toAddress = Params->Buffer; 155 | toProcess = PsGetCurrentProcess(); 156 | } 157 | __try { 158 | if(NT_SUCCESS(status)) { 159 | status = MmCopyVirtualMemory( 160 | fromProcess, (PVOID)fromAddress, 161 | toProcess, (PVOID)toAddress, 162 | Params->BufferSize, 163 | KernelMode, 164 | &bytesCopied); 165 | if(!NT_SUCCESS(status)) 166 | PERROR("MmCopyVirtualMemory", status); 167 | } else { 168 | PERROR("PsLookupProcessByProcessId", status); 169 | } 170 | } __except(EXCEPTION_EXECUTE_HANDLER) 171 | { 172 | PEXCEPTION(); 173 | status = GetExceptionCode(); 174 | } 175 | if(Write == TRUE) { 176 | if(toProcess != NULL) 177 | ObDereferenceObject(toProcess); 178 | } else { 179 | if(fromProcess != NULL) 180 | ObDereferenceObject(fromProcess); 181 | } 182 | return status; 183 | } 184 | 185 | -------------------------------------------------------------------------------- /ResurgenceDrv/mmap.c: -------------------------------------------------------------------------------- 1 | #include "internal.h" 2 | #include "mmap.h" 3 | #include "utils.h" 4 | 5 | #pragma alloc_text(PAGE, RDrvInjectManualMap) 6 | 7 | 8 | NTSTATUS RDrvInjectManualMap( 9 | __in PEPROCESS Process, 10 | __in PVOID ImageBuffer, 11 | __in ULONG ImageSize, 12 | __in BOOLEAN CallEntryPoint, 13 | __in ULONG_PTR CustomArg, 14 | __out PULONG_PTR ModuleBase 15 | ) 16 | { 17 | //NTSTATUS status; 18 | 19 | UNREFERENCED_PARAMETER(Process); 20 | UNREFERENCED_PARAMETER(ImageBuffer); 21 | UNREFERENCED_PARAMETER(ImageSize); 22 | UNREFERENCED_PARAMETER(CallEntryPoint); 23 | UNREFERENCED_PARAMETER(CustomArg); 24 | UNREFERENCED_PARAMETER(ModuleBase); 25 | // 26 | // Can't pass if both are null 27 | // 28 | //if(ImageBuffer == NULL) return STATUS_INVALID_PARAMETER; 29 | // 30 | //if(NT_SUCCESS(status)) { 31 | // 32 | //} else { 33 | // DPRINT("Failed to load the image to the system buffer. Status: %lX", status); 34 | //} 35 | return STATUS_SUCCESS; 36 | } -------------------------------------------------------------------------------- /ResurgenceDrv/mmap.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | NTSTATUS RDrvInjectManualMap( 5 | __in PEPROCESS Process, 6 | __in PVOID ImageBuffer, 7 | __in ULONG ImageSize, 8 | __in BOOLEAN CallEntryPoint, 9 | __in ULONG_PTR CustomArg, 10 | __out PULONG_PTR ModuleBase 11 | ); -------------------------------------------------------------------------------- /ResurgenceDrv/native_enums.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | //http://processhacker.sourceforge.net/doc/ntpsapi_8h_source.html 4 | #define THREAD_CREATE_FLAGS_CREATE_SUSPENDED 0x00000001 5 | #define THREAD_CREATE_FLAGS_SKIP_THREAD_ATTACH 0x00000002 // ? 6 | #define THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER 0x00000004 7 | #define THREAD_CREATE_FLAGS_HAS_SECURITY_DESCRIPTOR 0x00000010 // ? 8 | #define THREAD_CREATE_FLAGS_ACCESS_CHECK_IN_TARGET 0x00000020 // ? 9 | #define THREAD_CREATE_FLAGS_INITIAL_THREAD 0x00000080 10 | 11 | typedef enum _MEMORY_INFORMATION_CLASS_EX 12 | { 13 | MemoryBasicInformationEx = 0, 14 | MemoryWorkingSetInformation = 1, 15 | MemoryMappedFilenameInformation = 2, 16 | MemoryRegionInformation = 3, 17 | MemoryWorkingSetExInformation = 4, 18 | } MEMORY_INFORMATION_CLASS_EX; 19 | 20 | typedef enum _PS_PROTECTED_SIGNER 21 | { 22 | PsProtectedSignerNone = 0, 23 | PsProtectedSignerAuthenticode = 1, 24 | PsProtectedSignerCodeGen = 2, 25 | PsProtectedSignerAntimalware = 3, 26 | PsProtectedSignerLsa = 4, 27 | PsProtectedSignerWindows = 5, 28 | PsProtectedSignerWinTcb = 6, 29 | PsProtectedSignerMax = 7 30 | } PS_PROTECTED_SIGNER; 31 | 32 | typedef enum _PS_PROTECTED_TYPE 33 | { 34 | PsProtectedTypeNone = 0, 35 | PsProtectedTypeProtectedLight = 1, 36 | PsProtectedTypeProtected = 2, 37 | PsProtectedTypeMax = 3 38 | } PS_PROTECTED_TYPE; 39 | 40 | // 41 | // System Information Classes for NtQueryMutant 42 | // 43 | typedef enum _MUTANT_INFORMATION_CLASS 44 | { 45 | MutantBasicInformation, 46 | MutantOwnerInformation 47 | } MUTANT_INFORMATION_CLASS; 48 | 49 | // 50 | // System Information Classes for NtQueryAtom 51 | // 52 | typedef enum _ATOM_INFORMATION_CLASS 53 | { 54 | AtomBasicInformation, 55 | AtomTableInformation, 56 | } ATOM_INFORMATION_CLASS; 57 | 58 | // 59 | // System Information Classes for NtQueryTimer 60 | // 61 | typedef enum _TIMER_INFORMATION_CLASS 62 | { 63 | TimerBasicInformation 64 | } TIMER_INFORMATION_CLASS; 65 | 66 | // 67 | // System Information Classes for NtQuerySemaphore 68 | // 69 | typedef enum _SEMAPHORE_INFORMATION_CLASS 70 | { 71 | SemaphoreBasicInformation 72 | } SEMAPHORE_INFORMATION_CLASS; 73 | 74 | // 75 | // System Information Classes for NtQueryEvent 76 | // 77 | typedef enum _EVENT_INFORMATION_CLASS 78 | { 79 | EventBasicInformation 80 | } EVENT_INFORMATION_CLASS; 81 | 82 | typedef enum _SYSTEM_INFORMATION_CLASS 83 | { 84 | SystemBasicInformation = 0x0, 85 | SystemProcessorInformation = 0x1, 86 | SystemPerformanceInformation = 0x2, 87 | SystemTimeOfDayInformation = 0x3, 88 | SystemPathInformation = 0x4, 89 | SystemProcessInformation = 0x5, 90 | SystemCallCountInformation = 0x6, 91 | SystemDeviceInformation = 0x7, 92 | SystemProcessorPerformanceInformation = 0x8, 93 | SystemFlagsInformation = 0x9, 94 | SystemCallTimeInformation = 0xa, 95 | SystemModuleInformation = 0xb, 96 | SystemLocksInformation = 0xc, 97 | SystemStackTraceInformation = 0xd, 98 | SystemPagedPoolInformation = 0xe, 99 | SystemNonPagedPoolInformation = 0xf, 100 | SystemHandleInformation = 0x10, 101 | SystemObjectInformation = 0x11, 102 | SystemPageFileInformation = 0x12, 103 | SystemVdmInstemulInformation = 0x13, 104 | SystemVdmBopInformation = 0x14, 105 | SystemFileCacheInformation = 0x15, 106 | SystemPoolTagInformation = 0x16, 107 | SystemInterruptInformation = 0x17, 108 | SystemDpcBehaviorInformation = 0x18, 109 | SystemFullMemoryInformation = 0x19, 110 | SystemLoadGdiDriverInformation = 0x1a, 111 | SystemUnloadGdiDriverInformation = 0x1b, 112 | SystemTimeAdjustmentInformation = 0x1c, 113 | SystemSummaryMemoryInformation = 0x1d, 114 | SystemMirrorMemoryInformation = 0x1e, 115 | SystemPerformanceTraceInformation = 0x1f, 116 | SystemObsolete0 = 0x20, 117 | SystemExceptionInformation = 0x21, 118 | SystemCrashDumpStateInformation = 0x22, 119 | SystemKernelDebuggerInformation = 0x23, 120 | SystemContextSwitchInformation = 0x24, 121 | SystemRegistryQuotaInformation = 0x25, 122 | SystemExtendServiceTableInformation = 0x26, 123 | SystemPrioritySeperation = 0x27, 124 | SystemVerifierAddDriverInformation = 0x28, 125 | SystemVerifierRemoveDriverInformation = 0x29, 126 | SystemProcessorIdleInformation = 0x2a, 127 | SystemLegacyDriverInformation = 0x2b, 128 | SystemCurrentTimeZoneInformation = 0x2c, 129 | SystemLookasideInformation = 0x2d, 130 | SystemTimeSlipNotification = 0x2e, 131 | SystemSessionCreate = 0x2f, 132 | SystemSessionDetach = 0x30, 133 | SystemSessionInformation = 0x31, 134 | SystemRangeStartInformation = 0x32, 135 | SystemVerifierInformation = 0x33, 136 | SystemVerifierThunkExtend = 0x34, 137 | SystemSessionProcessInformation = 0x35, 138 | SystemLoadGdiDriverInSystemSpace = 0x36, 139 | SystemNumaProcessorMap = 0x37, 140 | SystemPrefetcherInformation = 0x38, 141 | SystemExtendedProcessInformation = 0x39, 142 | SystemRecommendedSharedDataAlignment = 0x3a, 143 | SystemComPlusPackage = 0x3b, 144 | SystemNumaAvailableMemory = 0x3c, 145 | SystemProcessorPowerInformation = 0x3d, 146 | SystemEmulationBasicInformation = 0x3e, 147 | SystemEmulationProcessorInformation = 0x3f, 148 | SystemExtendedHandleInformation = 0x40, 149 | SystemLostDelayedWriteInformation = 0x41, 150 | SystemBigPoolInformation = 0x42, 151 | SystemSessionPoolTagInformation = 0x43, 152 | SystemSessionMappedViewInformation = 0x44, 153 | SystemHotpatchInformation = 0x45, 154 | SystemObjectSecurityMode = 0x46, 155 | SystemWatchdogTimerHandler = 0x47, 156 | SystemWatchdogTimerInformation = 0x48, 157 | SystemLogicalProcessorInformation = 0x49, 158 | SystemWow64SharedInformationObsolete = 0x4a, 159 | SystemRegisterFirmwareTableInformationHandler = 0x4b, 160 | SystemFirmwareTableInformation = 0x4c, 161 | SystemModuleInformationEx = 0x4d, 162 | SystemVerifierTriageInformation = 0x4e, 163 | SystemSuperfetchInformation = 0x4f, 164 | SystemMemoryListInformation = 0x50, 165 | SystemFileCacheInformationEx = 0x51, 166 | SystemThreadPriorityClientIdInformation = 0x52, 167 | SystemProcessorIdleCycleTimeInformation = 0x53, 168 | SystemVerifierCancellationInformation = 0x54, 169 | SystemProcessorPowerInformationEx = 0x55, 170 | SystemRefTraceInformation = 0x56, 171 | SystemSpecialPoolInformation = 0x57, 172 | SystemProcessIdInformation = 0x58, 173 | SystemErrorPortInformation = 0x59, 174 | SystemBootEnvironmentInformation = 0x5a, 175 | SystemHypervisorInformation = 0x5b, 176 | SystemVerifierInformationEx = 0x5c, 177 | SystemTimeZoneInformation = 0x5d, 178 | SystemImageFileExecutionOptionsInformation = 0x5e, 179 | SystemCoverageInformation = 0x5f, 180 | SystemPrefetchPatchInformation = 0x60, 181 | SystemVerifierFaultsInformation = 0x61, 182 | SystemSystemPartitionInformation = 0x62, 183 | SystemSystemDiskInformation = 0x63, 184 | SystemProcessorPerformanceDistribution = 0x64, 185 | SystemNumaProximityNodeInformation = 0x65, 186 | SystemDynamicTimeZoneInformation = 0x66, 187 | SystemCodeIntegrityInformation = 0x67, 188 | SystemProcessorMicrocodeUpdateInformation = 0x68, 189 | SystemProcessorBrandString = 0x69, 190 | SystemVirtualAddressInformation = 0x6a, 191 | SystemLogicalProcessorAndGroupInformation = 0x6b, 192 | SystemProcessorCycleTimeInformation = 0x6c, 193 | SystemStoreInformation = 0x6d, 194 | SystemRegistryAppendString = 0x6e, 195 | SystemAitSamplingValue = 0x6f, 196 | SystemVhdBootInformation = 0x70, 197 | SystemCpuQuotaInformation = 0x71, 198 | SystemNativeBasicInformation = 0x72, 199 | SystemErrorPortTimeouts = 0x73, 200 | SystemLowPriorityIoInformation = 0x74, 201 | SystemBootEntropyInformation = 0x75, 202 | SystemVerifierCountersInformation = 0x76, 203 | SystemPagedPoolInformationEx = 0x77, 204 | SystemSystemPtesInformationEx = 0x78, 205 | SystemNodeDistanceInformation = 0x79, 206 | SystemAcpiAuditInformation = 0x7a, 207 | SystemBasicPerformanceInformation = 0x7b, 208 | SystemQueryPerformanceCounterInformation = 0x7c, 209 | SystemSessionBigPoolInformation = 0x7d, 210 | SystemBootGraphicsInformation = 0x7e, 211 | SystemScrubPhysicalMemoryInformation = 0x7f, 212 | SystemBadPageInformation = 0x80, 213 | SystemProcessorProfileControlArea = 0x81, 214 | SystemCombinePhysicalMemoryInformation = 0x82, 215 | SystemEntropyInterruptTimingInformation = 0x83, 216 | SystemConsoleInformation = 0x84, 217 | SystemPlatformBinaryInformation = 0x85, 218 | SystemThrottleNotificationInformation = 0x86, 219 | SystemHypervisorProcessorCountInformation = 0x87, 220 | SystemDeviceDataInformation = 0x88, 221 | SystemDeviceDataEnumerationInformation = 0x89, 222 | SystemMemoryTopologyInformation = 0x8a, 223 | SystemMemoryChannelInformation = 0x8b, 224 | SystemBootLogoInformation = 0x8c, 225 | SystemProcessorPerformanceInformationEx = 0x8d, 226 | SystemSpare0 = 0x8e, 227 | SystemSecureBootPolicyInformation = 0x8f, 228 | SystemPageFileInformationEx = 0x90, 229 | SystemSecureBootInformation = 0x91, 230 | SystemEntropyInterruptTimingRawInformation = 0x92, 231 | SystemPortableWorkspaceEfiLauncherInformation = 0x93, 232 | SystemFullProcessInformation = 0x94, 233 | SystemKernelDebuggerInformationEx = 0x95, 234 | SystemBootMetadataInformation = 0x96, 235 | SystemSoftRebootInformation = 0x97, 236 | SystemElamCertificateInformation = 0x98, 237 | SystemOfflineDumpConfigInformation = 0x99, 238 | SystemProcessorFeaturesInformation = 0x9a, 239 | SystemRegistryReconciliationInformation = 0x9b, 240 | MaxSystemInfoClass = 0x9c, 241 | } SYSTEM_INFORMATION_CLASS; 242 | 243 | typedef enum _KAPC_ENVIRONMENT 244 | { 245 | OriginalApcEnvironment, 246 | AttachedApcEnvironment, 247 | CurrentApcEnvironment, 248 | InsertApcEnvironment 249 | } KAPC_ENVIRONMENT, *PKAPC_ENVIRONMENT; 250 | 251 | typedef enum _MI_VAD_TYPE 252 | { 253 | VadNone, 254 | VadDevicePhysicalMemory, 255 | VadImageMap, 256 | VadAwe, 257 | VadWriteWatch, 258 | VadLargePages, 259 | VadRotatePhysical, 260 | VadLargePageSection 261 | } MI_VAD_TYPE, *PMI_VAD_TYPE; 262 | 263 | typedef enum _MMSYSTEM_PTE_POOL_TYPE 264 | { 265 | SystemPteSpace, 266 | NonPagedPoolExpansion, 267 | MaximumPtePoolTypes 268 | } MMSYSTEM_PTE_POOL_TYPE; 269 | 270 | // 271 | // Debug Control Codes for NtSystemDebugcontrol 272 | // 273 | typedef enum _SYSDBG_COMMAND 274 | { 275 | SysDbgQueryModuleInformation = 0, 276 | SysDbgQueryTraceInformation = 1, 277 | SysDbgSetTracepoint = 2, 278 | SysDbgSetSpecialCall = 3, 279 | SysDbgClearSpecialCalls = 4, 280 | SysDbgQuerySpecialCalls = 5, 281 | SysDbgBreakPoint = 6, 282 | SysDbgQueryVersion = 7, 283 | SysDbgReadVirtual = 8, 284 | SysDbgWriteVirtual = 9, 285 | SysDbgReadPhysical = 10, 286 | SysDbgWritePhysical = 11, 287 | SysDbgReadControlSpace = 12, 288 | SysDbgWriteControlSpace = 13, 289 | SysDbgReadIoSpace = 14, 290 | SysDbgWriteIoSpace = 15, 291 | SysDbgReadMsr = 16, 292 | SysDbgWriteMsr = 17, 293 | SysDbgReadBusData = 18, 294 | SysDbgWriteBusData = 19, 295 | SysDbgCheckLowMemory = 20, 296 | SysDbgEnableKernelDebugger = 21, 297 | SysDbgDisableKernelDebugger = 22, 298 | SysDbgGetAutoKdEnable = 23, 299 | SysDbgSetAutoKdEnable = 24, 300 | SysDbgGetPrintBufferSize = 25, 301 | SysDbgSetPrintBufferSize = 26, 302 | SysDbgGetKdUmExceptionEnable = 27, 303 | SysDbgSetKdUmExceptionEnable = 28, 304 | SysDbgGetTriageDump = 29, 305 | SysDbgGetKdBlockEnable = 30, 306 | SysDbgSetKdBlockEnable = 31, 307 | SysDbgRegisterForUmBreakInfo = 32, 308 | SysDbgGetUmBreakPid = 33, 309 | SysDbgClearUmBreakPid = 34, 310 | SysDbgGetUmAttachPid = 35, 311 | SysDbgClearUmAttachPid = 36, 312 | } SYSDBG_COMMAND; 313 | 314 | // 315 | // Shutdown types for NtShutdownSystem 316 | // 317 | typedef enum _SHUTDOWN_ACTION 318 | { 319 | ShutdownNoReboot, 320 | ShutdownReboot, 321 | ShutdownPowerOff 322 | } SHUTDOWN_ACTION; 323 | 324 | // 325 | // I/O Completion Information Class for NtQueryIoCompletionInformation 326 | // 327 | typedef enum _IO_COMPLETION_INFORMATION_CLASS 328 | { 329 | IoCompletionBasicInformation 330 | } IO_COMPLETION_INFORMATION_CLASS; 331 | 332 | // 333 | // Section Information Clasess for NtQuerySection 334 | // 335 | typedef enum _SECTION_INFORMATION_CLASS 336 | { 337 | SectionBasicInformation, 338 | SectionImageInformation, 339 | } SECTION_INFORMATION_CLASS; 340 | 341 | typedef enum _JOBOBJECTINFOCLASS 342 | { 343 | JobObjectBasicAccountingInformation = 1, 344 | JobObjectBasicLimitInformation, 345 | JobObjectBasicProcessIdList, 346 | JobObjectBasicUIRestrictions, 347 | JobObjectSecurityLimitInformation, 348 | JobObjectEndOfJobTimeInformation, 349 | JobObjectAssociateCompletionPortInformation, 350 | JobObjectBasicAndIoAccountingInformation, 351 | JobObjectExtendedLimitInformation, 352 | JobObjectJobSetInformation, 353 | JobObjectGroupInformation, 354 | MaxJobObjectInfoClass 355 | } JOBOBJECTINFOCLASS; 356 | 357 | #define RTL_USER_PROC_CURDIR_CLOSE 0x00000002 358 | #define RTL_USER_PROC_CURDIR_INHERIT 0x00000003 359 | #define RTL_MAX_DRIVE_LETTERS 32 360 | #define RTL_DRIVE_LETTER_VALID (USHORT)0x0001 -------------------------------------------------------------------------------- /ResurgenceDrv/object.c: -------------------------------------------------------------------------------- 1 | #include "routines.h" 2 | #include "internal.h" 3 | 4 | #pragma alloc_text(PAGE, RDrvGrantHandleAccess) 5 | 6 | NTSTATUS RDrvGrantHandleAccess( 7 | __inout PGRANT_ACCESS Params 8 | ) 9 | { 10 | if(!Params) return STATUS_INVALID_PARAMETER; 11 | 12 | NTSTATUS status; 13 | PEPROCESS process = NULL; 14 | 15 | __try { 16 | status = PsLookupProcessByProcessId((HANDLE)Params->In.ProcessId, &process); 17 | 18 | if(NT_SUCCESS(status)) { 19 | PHANDLE_TABLE objTable = *(PHANDLE_TABLE*)((PUCHAR)process + g_pDriverContext->DynData.Offsets.ObjectTable); 20 | EXHANDLE exHandle; exHandle.Value = Params->In.Handle; 21 | PHANDLE_TABLE_ENTRY handleEntry = ExpLookupHandleTableEntry(objTable, exHandle); 22 | if(ExpIsValidObjectEntry(handleEntry)) { 23 | Params->Out.OldAccessMask = handleEntry->GrantedAccessBits; 24 | handleEntry->GrantedAccessBits = Params->In.AccessMask; 25 | } else { 26 | DPRINT("Invalid handle: %p", Params->In.Handle); 27 | status = STATUS_UNSUCCESSFUL; 28 | } 29 | } else { 30 | PERROR("PsLookupProcessByProcessId", status); 31 | } 32 | } __except(EXCEPTION_EXECUTE_HANDLER) 33 | { 34 | PEXCEPTION(); 35 | status = GetExceptionCode(); 36 | } 37 | if(process != NULL) 38 | ObDereferenceObject(process); 39 | return status; 40 | } 41 | -------------------------------------------------------------------------------- /ResurgenceDrv/process.c: -------------------------------------------------------------------------------- 1 | #include "routines.h" 2 | #include "injection.h" 3 | #include "mmap.h" 4 | 5 | #pragma alloc_text(PAGE, RDrvProtectProcess) 6 | #pragma alloc_text(PAGE, RDrvOpenProcess) 7 | #pragma alloc_text(PAGE, RDrvSetProcessDEP) 8 | 9 | NTSTATUS RDrvProtectProcess( 10 | __inout PPROTECT_PROCESS Params 11 | ) 12 | { 13 | if(!Params) return STATUS_INVALID_PARAMETER; 14 | 15 | NTSTATUS status; 16 | PEPROCESS process = NULL; 17 | KAPC_STATE apcState; 18 | __try { 19 | status = PsLookupProcessByProcessId((HANDLE)Params->In.ProcessId, &process); 20 | 21 | if(NT_SUCCESS(status)) { 22 | #ifdef _WIN10_ 23 | PPS_PROTECTION psProtection = (PPS_PROTECTION)((PUCHAR)process + g_pDriverContext->DynData.Offsets.Protection); 24 | if(psProtection != NULL) { 25 | KeStackAttachProcess(process, &apcState); 26 | PPEB peb = PsGetProcessPeb(process); 27 | if(Params->In.ProtectionLevel == PROTECTION_NONE) { 28 | psProtection->Level = 0; 29 | peb->IsProtectedProcess = 0; 30 | peb->IsProtectedProcessLight = 0; 31 | } else if(Params->In.ProtectionLevel == PROTECTION_LIGHT) { 32 | psProtection->Flags.Signer = PsProtectedSignerWinTcb; 33 | psProtection->Flags.Type = PsProtectedTypeProtectedLight; 34 | peb->IsProtectedProcess = 1; 35 | peb->IsProtectedProcessLight = 1; 36 | } else if(Params->In.ProtectionLevel == PROTECTION_FULL) { 37 | psProtection->Flags.Signer = PsProtectedSignerWinTcb; 38 | psProtection->Flags.Type = PsProtectedTypeProtected; 39 | peb->IsProtectedProcess = 1; 40 | peb->IsProtectedProcessLight = 0; 41 | } else { 42 | DPRINT("Invalid ProtectionLevel: %d", Params->In.ProtectionLevel); 43 | status = STATUS_UNSUCCESSFUL; 44 | } 45 | KeUnstackDetachProcess(&apcState); 46 | } else { 47 | DPRINT("PsProtection is invalid"); 48 | status = STATUS_UNSUCCESSFUL; 49 | } 50 | #else 51 | #error "Unsupported" 52 | #endif 53 | } else { 54 | PERROR("PsLookupProcessByProcessId", status); 55 | } 56 | } __except(EXCEPTION_EXECUTE_HANDLER) 57 | { 58 | PEXCEPTION(); 59 | status = GetExceptionCode(); 60 | } 61 | if(process != NULL) 62 | ObDereferenceObject(process); 63 | return status; 64 | } 65 | 66 | NTSTATUS RDrvOpenProcess( 67 | __inout POPEN_PROCESS Params 68 | ) 69 | { 70 | if(!Params) return STATUS_INVALID_PARAMETER; 71 | 72 | NTSTATUS status; 73 | PEPROCESS process = NULL; 74 | PETHREAD thread = NULL; 75 | HANDLE handle = NULL; 76 | CLIENT_ID clientId; 77 | 78 | __try { 79 | if(Params->In.ProcessId != 0) { 80 | status = PsLookupProcessByProcessId((HANDLE)Params->In.ProcessId, &process); 81 | } else if(Params->In.ThreadId != 0) { 82 | clientId.UniqueProcess = 0; 83 | clientId.UniqueThread = (HANDLE)Params->In.ThreadId; 84 | status = PsLookupProcessThreadByCid(&clientId, &process, &thread); 85 | if(NT_SUCCESS(status)) { 86 | ObDereferenceObject(thread); 87 | } 88 | } else { 89 | status = STATUS_INVALID_CID; 90 | } 91 | if(NT_SUCCESS(status)) { 92 | status = ObOpenObjectByPointer(process, 0, NULL, Params->In.AccessMask, *PsProcessType, KernelMode, &handle); 93 | if(NT_SUCCESS(status) && handle != NULL) { 94 | Params->Out.Handle = (ULONG_PTR)handle; 95 | } else { 96 | PERROR("ObOpenObjectByPointer", status); 97 | } 98 | } else { 99 | PERROR("PsLookupProcessByProcessId/ThreadByCid", status); 100 | } 101 | } __except(EXCEPTION_EXECUTE_HANDLER) 102 | { 103 | PEXCEPTION(); 104 | status = GetExceptionCode(); 105 | } 106 | if(process != NULL) 107 | ObDereferenceObject(process); 108 | return status; 109 | } 110 | 111 | NTSTATUS RDrvSetProcessDEP( 112 | __in PSET_DEP_STATE Params 113 | ) 114 | { 115 | if(!Params) return STATUS_INVALID_PARAMETER; 116 | 117 | NTSTATUS status; 118 | PEPROCESS process = NULL; 119 | 120 | __try { 121 | status = PsLookupProcessByProcessId((HANDLE)Params->In.ProcessId, &process); 122 | 123 | if(NT_SUCCESS(status)) { 124 | #ifdef _WIN10_ 125 | PKEXECUTE_OPTIONS executeOptions = (PKEXECUTE_OPTIONS)((PUCHAR)process + g_pDriverContext->DynData.Offsets.ExecuteOptions); 126 | if(Params->In.Enabled == FALSE) { 127 | executeOptions->ExecuteOptions = 0; 128 | 129 | executeOptions->Flags.ExecuteDisable = 1; 130 | executeOptions->Flags.ImageDispatchEnable = 1; 131 | executeOptions->Flags.ExecuteDispatchEnable = 1; 132 | } else { 133 | executeOptions->ExecuteOptions = 0; 134 | 135 | executeOptions->Flags.ExecuteEnable = 1; 136 | executeOptions->Flags.Permanent = 1; 137 | } 138 | #else 139 | #error "Unsupported" 140 | #endif 141 | } else { 142 | PERROR("PsLookupProcessByProcessId", status); 143 | } 144 | } __except(EXCEPTION_EXECUTE_HANDLER) 145 | { 146 | PEXCEPTION(); 147 | status = GetExceptionCode(); 148 | } 149 | if(process != NULL) 150 | ObDereferenceObject(process); 151 | return status; 152 | } 153 | 154 | NTSTATUS RDrvInjectModule( 155 | __inout PINJECT_MODULE Params 156 | ) 157 | { 158 | 159 | NTSTATUS status = STATUS_SUCCESS; 160 | PEPROCESS process = NULL; 161 | KAPC_STATE apcState; 162 | ULONG_PTR base = 0; 163 | SIZE_T pathSize = 0; 164 | 165 | if(!Params) return STATUS_INVALID_PARAMETER; 166 | 167 | RtlStringCbLengthW(Params->In.ModulePath, MAX_PATH, &pathSize); 168 | 169 | // 170 | // Cant continue if ModuleBase and Path are invalid 171 | // 172 | if(!Params->In.ModuleBase && pathSize == 0) return STATUS_INVALID_PARAMETER; 173 | 174 | __try { 175 | status = PsLookupProcessByProcessId((HANDLE)Params->In.ProcessId, &process); 176 | if(NT_SUCCESS(status)) { 177 | 178 | if(Params->In.InjectionType == InjectLdrLoadDll) { 179 | status = RDrvInjectLdrLoadDll(process, Params->In.ModulePath, &base); 180 | } else if(Params->In.InjectionType == InjectManualMap) { 181 | status = STATUS_NOT_IMPLEMENTED; 182 | //PVOID systemBuffer; 183 | //ULONG imageSize; 184 | //if(Params->In.ModuleBase != 0) { 185 | // status = RDrvLoadImageFromMemory(Params->In.ModuleBase, &systemBuffer, &imageSize); 186 | //} else { 187 | // RDrvLoadImageFromFile(Params->In.ModulePath, &systemBuffer, &imageSize); 188 | //} 189 | //status = RDrvInjectManualMap(process, systemBuffer, imageSize, Params->In.ModulePath, Params->In.CallEntryPoint, Params->In.CustomParameter, &base); 190 | } 191 | if(NT_SUCCESS(status)) { 192 | KeStackAttachProcess(process, &apcState); 193 | if(Params->In.ErasePE == TRUE) { 194 | if(!NT_SUCCESS(status = RDrvStripHeaders((PVOID)base))) 195 | PERROR("RDrvStripHeaders", status); 196 | } 197 | if(Params->In.HideModule == TRUE) { 198 | if(!NT_SUCCESS(status = RDrvHideFromLoadedList(process, (PVOID)base))) 199 | PERROR("RDrvHideFromLoadedList", status); 200 | } 201 | KeUnstackDetachProcess(&apcState); 202 | } 203 | 204 | Params->Out.BaseAddress = base; 205 | 206 | } else 207 | PERROR("PsLookupProcessByProcessId", status); 208 | } __except(EXCEPTION_EXECUTE_HANDLER) 209 | { 210 | PEXCEPTION(); 211 | status = GetExceptionCode(); 212 | } 213 | if(process) 214 | ObDereferenceObject(process); 215 | 216 | return status; 217 | } 218 | -------------------------------------------------------------------------------- /ResurgenceDrv/routines.c: -------------------------------------------------------------------------------- 1 | #include "routines.h" 2 | #include "utils.h" 3 | #include "internal.h" 4 | 5 | #pragma alloc_text(PAGE, RDrvQueryOSVersion) 6 | 7 | NTSTATUS RDrvQueryOSVersion( 8 | __out PVERSION_INFO Version 9 | ) 10 | { 11 | NTSTATUS status; 12 | RTL_OSVERSIONINFOEXW versionInfo; 13 | 14 | if(!Version) return STATUS_INVALID_PARAMETER; 15 | 16 | versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); 17 | status = RtlGetVersion((PRTL_OSVERSIONINFOW)&versionInfo); 18 | if(NT_SUCCESS(status)) { 19 | Version->BuildNumber = versionInfo.dwBuildNumber; 20 | Version->MajorVersion = versionInfo.dwMajorVersion; 21 | Version->MinorVersion = versionInfo.dwMinorVersion; 22 | Version->ServicePackMajor = versionInfo.wServicePackMajor; 23 | Version->ServicePackMinor = versionInfo.wServicePackMinor; 24 | Version->VersionLong = 25 | (versionInfo.dwMajorVersion << 24) | 26 | (versionInfo.dwMinorVersion << 16) | 27 | (versionInfo.wServicePackMajor << 8) | 28 | versionInfo.wServicePackMinor; 29 | } else { 30 | PERROR("RtlGetVersion", status); 31 | } 32 | return status; 33 | } -------------------------------------------------------------------------------- /ResurgenceDrv/routines.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "internal.h" 4 | 5 | NTSTATUS RDrvQueryOSVersion( 6 | __out PVERSION_INFO Version 7 | ); 8 | 9 | NTSTATUS RDrvQueyVirtualMemory( 10 | __inout PVM_QUERY_INFO Params 11 | ); 12 | 13 | NTSTATUS RDrvVirtualMemoryOperation( 14 | __inout PVM_OPERATION Params 15 | ); 16 | 17 | NTSTATUS RDrvReadWriteVirtualMemory( 18 | __inout PVM_READ_WRITE Params, 19 | __in BOOLEAN Write 20 | ); 21 | 22 | NTSTATUS RDrvGrantHandleAccess( 23 | __inout PGRANT_ACCESS Params 24 | ); 25 | 26 | NTSTATUS RDrvProtectProcess( 27 | __in PPROTECT_PROCESS Params 28 | ); 29 | 30 | NTSTATUS RDrvOpenProcess( 31 | __inout POPEN_PROCESS Params 32 | ); 33 | 34 | NTSTATUS RDrvSetProcessDEP( 35 | __in PSET_DEP_STATE Params 36 | ); 37 | 38 | NTSTATUS RDrvOpenThread( 39 | __inout POPEN_THREAD Params 40 | ); 41 | 42 | NTSTATUS RDrvInjectModule( 43 | __inout PINJECT_MODULE Params 44 | ); -------------------------------------------------------------------------------- /ResurgenceDrv/thread.c: -------------------------------------------------------------------------------- 1 | #include "routines.h" 2 | 3 | #pragma alloc_text(PAGE, RDrvOpenThread) 4 | 5 | NTSTATUS RDrvOpenThread( 6 | __inout POPEN_THREAD Params 7 | ) 8 | { 9 | if(!Params) return STATUS_INVALID_PARAMETER; 10 | 11 | NTSTATUS status; 12 | PETHREAD thread = NULL; 13 | HANDLE handle = NULL; 14 | 15 | __try { 16 | status = PsLookupThreadByThreadId((HANDLE)Params->In.ThreadId, &thread); 17 | if(NT_SUCCESS(status)) { 18 | status = ObOpenObjectByPointer(thread, 0, NULL, Params->In.AccessMask, *PsThreadType, KernelMode, &handle); 19 | if(NT_SUCCESS(status) && handle != NULL) { 20 | Params->Out.Handle = (ULONG_PTR)handle; 21 | } else { 22 | PERROR("ObOpenObjectByPointer", status); 23 | } 24 | } else { 25 | PERROR("PsLookupThreadByThreadId", status); 26 | } 27 | } __except(EXCEPTION_EXECUTE_HANDLER) 28 | { 29 | PEXCEPTION(); 30 | status = GetExceptionCode(); 31 | } 32 | if(thread != NULL) 33 | ObDereferenceObject(thread); 34 | return status; 35 | } -------------------------------------------------------------------------------- /ResurgenceDrv/utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef struct _INJECTION_BUFFER *PINJECTION_BUFFER; 4 | 5 | NTSTATUS RDrvLogToFile( 6 | __in LPCSTR Format, 7 | __in_opt ... 8 | ); 9 | 10 | NTSTATUS RDrvOpenFile( 11 | __in LPCWSTR FilePath, 12 | __in BOOLEAN Write, 13 | __in BOOLEAN Append, 14 | __out PHANDLE Handle 15 | ); 16 | 17 | NTSTATUS RDrvGetKernelInfo( 18 | __out_opt PULONG_PTR BaseAddress, 19 | __out_opt PSIZE_T Size 20 | ); 21 | 22 | NTSTATUS RDrvFindPattern( 23 | __in ULONG_PTR BaseAddress, 24 | __in SIZE_T Size, 25 | __in PCUCHAR Pattern, 26 | __in PCUCHAR Mask, 27 | __in SIZE_T PatternSize, 28 | __inout PVOID* Result 29 | ); 30 | 31 | NTSTATUS RDrvFindKernelPattern( 32 | __in PCUCHAR Pattern, 33 | __in PCUCHAR Mask, 34 | __in SIZE_T PatternSize, 35 | __inout PVOID* Result 36 | ); 37 | 38 | NTSTATUS RDrvSleep( 39 | __in LONG ms 40 | ); 41 | 42 | NTSTATUS RDrvGetModuleEntry( 43 | __in PEPROCESS Process, 44 | __in LPCWSTR ModuleName, 45 | __out PLDR_DATA_TABLE_ENTRY* LdrEntry 46 | ); 47 | 48 | NTSTATUS RDrvGetModuleEntry32( 49 | __in PEPROCESS Process, 50 | __in LPCWSTR ModuleName, 51 | __out PLDR_DATA_TABLE_ENTRY32* LdrEntry 52 | ); 53 | 54 | NTSTATUS RDrvGetProcAddress( 55 | __in ULONG_PTR ModuleBase, 56 | __in LPCSTR ProcName, 57 | __out PULONG_PTR ProcAddress 58 | ); 59 | 60 | NTSTATUS RDrvCreateUserThread( 61 | __in PVOID pStartAddress, 62 | __in_opt PVOID pArg, 63 | __in BOOLEAN wait, 64 | __out_opt PULONG_PTR pThreadExitCode 65 | ); 66 | 67 | NTSTATUS RDrvStripHeaders( 68 | __in PVOID BaseAddress 69 | ); 70 | 71 | NTSTATUS RDrvHideFromLoadedList( 72 | __in PEPROCESS pProcess, 73 | __in PVOID pBaseAddress 74 | ); 75 | 76 | PIMAGE_NT_HEADERS32 GetWow64NtHeaders( 77 | __in PVOID ImageBase 78 | ); 79 | 80 | PIMAGE_NT_HEADERS64 GetNtHeaders( 81 | __in PVOID ImageBase 82 | ); 83 | 84 | BOOLEAN IsProcessWow64Process( 85 | __in PEPROCESS Process 86 | ); 87 | 88 | PSYSTEM_SERVICE_DESCRIPTOR_TABLE GetSSDTBase( 89 | void 90 | ); 91 | 92 | PVOID GetSSDTEntry( 93 | __in ULONG Index 94 | ); 95 | 96 | NTSTATUS RDrvLoadImageFromFile( 97 | __in PWCHAR ModulePath, 98 | __out PVOID* ImageBase, 99 | __out PULONG ImageSize 100 | ); 101 | 102 | NTSTATUS RDrvLoadImageFromMemory( 103 | __in PVOID UserBuffer, 104 | __out PVOID* ImageBase, 105 | __out PULONG ImageSize 106 | ); 107 | 108 | NTSTATUS RDrvGenerateRandomString( 109 | __in ULONG Length, 110 | __out PWSTR String 111 | ); -------------------------------------------------------------------------------- /ResurgenceDrv/zw_imports.c: -------------------------------------------------------------------------------- 1 | #include "internal.h" 2 | #include "zw_imports.h" 3 | 4 | #if defined(_WIN8_) || defined (_WIN7_) 5 | 6 | NTSTATUS 7 | NTAPI 8 | ZwProtectVirtualMemory( 9 | IN HANDLE ProcessHandle, 10 | IN PVOID* BaseAddress, 11 | IN SIZE_T* NumberOfBytesToProtect, 12 | IN ULONG NewAccessProtection, 13 | OUT PULONG OldAccessProtection 14 | ) 15 | { 16 | NTSTATUS status = STATUS_SUCCESS; 17 | 18 | fnNtProtectVirtualMemory NtProtectVirtualMemory = (fnNtProtectVirtualMemory)(ULONG_PTR)GetSSDTEntry(g_pDriverContext->DynData.SSDTIndexes.ProtectMemory); 19 | if(NtProtectVirtualMemory) { 20 | PUCHAR pPrevMode = (PUCHAR)PsGetCurrentThread() + g_pDriverContext->DynData.Offsets.PreviousMode; 21 | UCHAR prevMode = *pPrevMode; 22 | *pPrevMode = KernelMode; 23 | 24 | status = NtProtectVirtualMemory(ProcessHandle, BaseAddress, NumberOfBytesToProtect, NewAccessProtection, OldAccessProtection); 25 | 26 | *pPrevMode = prevMode; 27 | } else 28 | status = STATUS_NOT_FOUND; 29 | 30 | return status; 31 | } 32 | #endif 33 | 34 | NTSTATUS 35 | NTAPI 36 | ZwCreateThreadEx( 37 | OUT PHANDLE hThread, 38 | IN ACCESS_MASK DesiredAccess, 39 | IN PVOID ObjectAttributes, 40 | IN HANDLE ProcessHandle, 41 | IN PVOID lpStartAddress, 42 | IN PVOID lpParameter, 43 | IN ULONG Flags, 44 | IN SIZE_T StackZeroBits, 45 | IN SIZE_T SizeOfStackCommit, 46 | IN SIZE_T SizeOfStackReserve, 47 | IN PNT_PROC_THREAD_ATTRIBUTE_LIST AttributeList 48 | ) 49 | { 50 | NTSTATUS status = STATUS_SUCCESS; 51 | 52 | tNtCreateThreadEx NtCreateThreadEx = (tNtCreateThreadEx)(ULONG_PTR)GetSSDTEntry(g_pDriverContext->DynData.SSDTIndexes.CreateThreadEx); 53 | if(NtCreateThreadEx) { 54 | // 55 | // If previous mode is UserMode, addresses passed into ZwCreateThreadEx must be in user-mode space 56 | // Switching to KernelMode allows usage of kernel-mode addresses 57 | // 58 | PUCHAR pPrevMode = (PUCHAR)PsGetCurrentThread() + g_pDriverContext->DynData.Offsets.PreviousMode; 59 | UCHAR prevMode = *pPrevMode; 60 | *pPrevMode = KernelMode; 61 | 62 | status = NtCreateThreadEx( 63 | hThread, DesiredAccess, ObjectAttributes, 64 | ProcessHandle, lpStartAddress, lpParameter, 65 | Flags, StackZeroBits, SizeOfStackCommit, 66 | SizeOfStackReserve, AttributeList 67 | ); 68 | 69 | *pPrevMode = prevMode; 70 | } else 71 | status = STATUS_NOT_FOUND; 72 | 73 | return status; 74 | } 75 | 76 | NTSTATUS NTAPI ZwTerminateThread(IN HANDLE ThreadHandle, IN NTSTATUS ExitStatus) 77 | { 78 | NTSTATUS status = STATUS_SUCCESS; 79 | 80 | tNtTerminateThread NtTerminateThread = (tNtTerminateThread)(ULONG_PTR)GetSSDTEntry(g_pDriverContext->DynData.SSDTIndexes.TerminateThread); 81 | if(NtTerminateThread) { 82 | PUCHAR pPrevMode = (PUCHAR)PsGetCurrentThread() + g_pDriverContext->DynData.Offsets.PreviousMode; 83 | UCHAR prevMode = *pPrevMode; 84 | *pPrevMode = KernelMode; 85 | 86 | status = NtTerminateThread(ThreadHandle, ExitStatus); 87 | *pPrevMode = prevMode; 88 | } else 89 | status = STATUS_NOT_FOUND; 90 | 91 | return status; 92 | } 93 | 94 | NTSTATUS 95 | NTAPI 96 | ZwQueryPerformanceCounter( 97 | __out PLARGE_INTEGER PerformanceCounter, 98 | __out_opt PLARGE_INTEGER PerformanceFrequency 99 | ) 100 | { 101 | NTSTATUS status = STATUS_SUCCESS; 102 | 103 | tNtQueryPerformanceCounter NtQueryPerformanceCounter 104 | = (tNtQueryPerformanceCounter)(ULONG_PTR)GetSSDTEntry(g_pDriverContext->DynData.SSDTIndexes.QueryPerformanceCounter); 105 | if(NtQueryPerformanceCounter) { 106 | PUCHAR pPrevMode = (PUCHAR)PsGetCurrentThread() + g_pDriverContext->DynData.Offsets.PreviousMode; 107 | UCHAR prevMode = *pPrevMode; 108 | *pPrevMode = KernelMode; 109 | 110 | status = NtQueryPerformanceCounter(PerformanceCounter, PerformanceFrequency); 111 | 112 | *pPrevMode = prevMode; 113 | } else { 114 | status = STATUS_NOT_FOUND; 115 | } 116 | return status; 117 | } -------------------------------------------------------------------------------- /TestApp/Source.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main(int argc, char** argv) 7 | { 8 | using namespace std; 9 | using namespace resurgence; 10 | 11 | if(!system::process::grant_privilege(SE_DEBUG_PRIVILEGE)) 12 | cout << "[!] Failed to set debug privilege" << endl; 13 | 14 | auto process = system::process::get_process_by_name(L"notepad++.exe").front(); 15 | auto ntoskrnl = process.modules()->get_main_module(); 16 | try { 17 | auto symbol_info = process.symbols()->get_symbol_info_from_address(uintptr_t(ntoskrnl.get_base() + 0x1220)); 18 | 19 | auto& module = symbol_info.get_module(); 20 | 21 | wcout << hex 22 | << "Module Name : " << module.get_name() << endl 23 | << "Module Path : " << module.get_path() << endl 24 | << "Module Base : " << module.get_base() << endl 25 | << "Module Size : " << module.get_size() << endl 26 | << "-----------------------------------------------------" << endl 27 | << "Symbol Name : " << symbol_info.get_name() << endl 28 | << "Symbol Address: " << symbol_info.get_address() << endl 29 | << "Symbol Offset : " << symbol_info.get_displacement() << endl 30 | << "-----------------------------------------------------" << endl; 31 | 32 | } catch(const misc::win32_exception& ex) { 33 | wcout << ex.get_message() << endl; 34 | wcout << "Status: " << ex.get_status() << endl; 35 | } 36 | 37 | process = system::process(SYSTEM_PROCESS); 38 | ntoskrnl = process.modules()->get_main_module(); 39 | try { 40 | auto symbol_info = process.symbols()->get_symbol_info_from_address(ntoskrnl.get_proc_address("KeTestSpinLock")); 41 | 42 | auto& module = symbol_info.get_module(); 43 | 44 | wcout << hex 45 | << "Module Name : " << module.get_name() << endl 46 | << "Module Path : " << module.get_path() << endl 47 | << "Module Base : " << module.get_base() << endl 48 | << "Module Size : " << module.get_size() << endl 49 | << "-----------------------------------------------------" << endl 50 | << "Symbol Name : " << symbol_info.get_name() << endl 51 | << "Symbol Address: " << symbol_info.get_address() << endl 52 | << "Symbol Offset : " << symbol_info.get_displacement() << endl 53 | << "-----------------------------------------------------" << endl; 54 | 55 | } catch(const misc::win32_exception& ex) { 56 | wcout << ex.get_message() << endl; 57 | wcout << "Status: " << ex.get_status() << endl; 58 | } 59 | 60 | ::system("pause"); 61 | return 0; 62 | } -------------------------------------------------------------------------------- /TestApp/TestApp.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ldebug/Resurgence/c4aeb6473884095cbf3bf173d3d35ea7770f5b70/TestApp/TestApp.rc -------------------------------------------------------------------------------- /TestApp/TestApp.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 | {BBC7A05C-0562-40B9-859C-A7E2977C5D79} 23 | TestExe 24 | 10.0.10586.0 25 | TestApp 26 | 27 | 28 | 29 | Application 30 | true 31 | v140 32 | Unicode 33 | 34 | 35 | Application 36 | false 37 | v140 38 | true 39 | Unicode 40 | 41 | 42 | Application 43 | true 44 | v140 45 | Unicode 46 | 47 | 48 | Application 49 | false 50 | v140 51 | true 52 | Unicode 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | $(SolutionDir)bin\$(Platform)\ 74 | $(SolutionDir)build\$(ProjectName)\$(Platform)\$(Configuration)\ 75 | $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)Resurgence\include 76 | $(ProjectName)_d 77 | 78 | 79 | $(SolutionDir)bin\$(Platform)\ 80 | $(SolutionDir)build\$(ProjectName)\$(Platform)\$(Configuration)\ 81 | $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)Resurgence\include 82 | 83 | 84 | $(SolutionDir)bin\$(Platform)\ 85 | $(SolutionDir)build\$(ProjectName)\$(Platform)\$(Configuration)\ 86 | $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)Resurgence\include 87 | $(ProjectName)_d 88 | 89 | 90 | $(SolutionDir)bin\$(Platform)\ 91 | $(SolutionDir)build\$(ProjectName)\$(Platform)\$(Configuration)\ 92 | $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)Resurgence\include 93 | 94 | 95 | 96 | Level3 97 | Disabled 98 | false 99 | 4996; 4302; 4311; 4312 100 | Cdecl 101 | 102 | 103 | $(SolutionDir)bin\$(Platform)\lib\ 104 | kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 105 | RequireAdministrator 106 | true 107 | 108 | 109 | 110 | 111 | Level3 112 | Disabled 113 | false 114 | 4996; 4302; 4311; 4312 115 | Cdecl 116 | 117 | 118 | $(SolutionDir)bin\$(Platform)\lib\ 119 | kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 120 | RequireAdministrator 121 | true 122 | 123 | 124 | 125 | 126 | Level3 127 | MaxSpeed 128 | true 129 | true 130 | false 131 | 4996; 4302; 4311; 4312 132 | Cdecl 133 | 134 | 135 | true 136 | true 137 | UseFastLinkTimeCodeGeneration 138 | $(SolutionDir)bin\$(Platform)\lib\ 139 | kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 140 | RequireAdministrator 141 | DebugFastLink 142 | 143 | 144 | 145 | 146 | Level3 147 | MaxSpeed 148 | true 149 | true 150 | false 151 | 4996; 4302; 4311; 4312 152 | Cdecl 153 | 154 | 155 | true 156 | true 157 | UseFastLinkTimeCodeGeneration 158 | $(SolutionDir)bin\$(Platform)\lib\ 159 | kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 160 | RequireAdministrator 161 | DebugFastLink 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | {6872536e-3320-48d7-91a2-363b8ca39055} 180 | 181 | 182 | 183 | 184 | 185 | -------------------------------------------------------------------------------- /TestApp/resource.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ldebug/Resurgence/c4aeb6473884095cbf3bf173d3d35ea7770f5b70/TestApp/resource.h --------------------------------------------------------------------------------