├── .gitignore ├── CheatDriver ├── .gitignore ├── CheatController │ ├── CheatController.cpp │ ├── CheatController.vcxproj │ └── CheatController.vcxproj.filters ├── CheatDriver.sln └── CheatDriver │ ├── CheatDriver.cpp │ ├── CheatDriver.h │ ├── CheatDriver.inf │ ├── CheatDriver.vcxproj │ ├── CheatDriver.vcxproj.filters │ ├── CheatDriver_Common.h │ ├── CheatDriver_Globals.h │ ├── CheatDriver_Hooks.cpp │ ├── CheatDriver_Hooks.h │ ├── CheatDriver_Modules.cpp │ ├── CheatDriver_Modules.h │ ├── CheatDriver_ReadWrite.cpp │ └── CheatDriver_Utils.cpp ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Linker output 11 | *.ilk 12 | *.map 13 | *.exp 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.a 22 | *.la 23 | *.lo 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.i*86 36 | *.x86_64 37 | *.hex 38 | 39 | # Debug files 40 | *.dSYM/ 41 | *.su 42 | *.idb 43 | *.pdb 44 | 45 | # Kernel Module Compile Results 46 | *.mod* 47 | *.cmd 48 | .tmp_versions/ 49 | modules.order 50 | Module.symvers 51 | Mkfile.old 52 | dkms.conf 53 | -------------------------------------------------------------------------------- /CheatDriver/.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Ww][Ii][Nn]32/ 27 | [Aa][Rr][Mm]/ 28 | [Aa][Rr][Mm]64/ 29 | bld/ 30 | [Bb]in/ 31 | [Oo]bj/ 32 | [Ll]og/ 33 | [Ll]ogs/ 34 | 35 | # Visual Studio 2015/2017 cache/options directory 36 | .vs/ 37 | # Uncomment if you have tasks that create the project's static files in wwwroot 38 | #wwwroot/ 39 | 40 | # Visual Studio 2017 auto generated files 41 | Generated\ Files/ 42 | 43 | # MSTest test Results 44 | [Tt]est[Rr]esult*/ 45 | [Bb]uild[Ll]og.* 46 | 47 | # NUnit 48 | *.VisualState.xml 49 | TestResult.xml 50 | nunit-*.xml 51 | 52 | # Build Results of an ATL Project 53 | [Dd]ebugPS/ 54 | [Rr]eleasePS/ 55 | dlldata.c 56 | 57 | # Benchmark Results 58 | BenchmarkDotNet.Artifacts/ 59 | 60 | # .NET Core 61 | project.lock.json 62 | project.fragment.lock.json 63 | artifacts/ 64 | 65 | # ASP.NET Scaffolding 66 | ScaffoldingReadMe.txt 67 | 68 | # StyleCop 69 | StyleCopReport.xml 70 | 71 | # Files built by Visual Studio 72 | *_i.c 73 | *_p.c 74 | *_h.h 75 | *.ilk 76 | *.meta 77 | *.obj 78 | *.iobj 79 | *.pch 80 | *.pdb 81 | *.ipdb 82 | *.pgc 83 | *.pgd 84 | *.rsp 85 | *.sbr 86 | *.tlb 87 | *.tli 88 | *.tlh 89 | *.tmp 90 | *.tmp_proj 91 | *_wpftmp.csproj 92 | *.log 93 | *.tlog 94 | *.vspscc 95 | *.vssscc 96 | .builds 97 | *.pidb 98 | *.svclog 99 | *.scc 100 | 101 | # Chutzpah Test files 102 | _Chutzpah* 103 | 104 | # Visual C++ cache files 105 | ipch/ 106 | *.aps 107 | *.ncb 108 | *.opendb 109 | *.opensdf 110 | *.sdf 111 | *.cachefile 112 | *.VC.db 113 | *.VC.VC.opendb 114 | 115 | # Visual Studio profiler 116 | *.psess 117 | *.vsp 118 | *.vspx 119 | *.sap 120 | 121 | # Visual Studio Trace Files 122 | *.e2e 123 | 124 | # TFS 2012 Local Workspace 125 | $tf/ 126 | 127 | # Guidance Automation Toolkit 128 | *.gpState 129 | 130 | # ReSharper is a .NET coding add-in 131 | _ReSharper*/ 132 | *.[Rr]e[Ss]harper 133 | *.DotSettings.user 134 | 135 | # TeamCity is a build add-in 136 | _TeamCity* 137 | 138 | # DotCover is a Code Coverage Tool 139 | *.dotCover 140 | 141 | # AxoCover is a Code Coverage Tool 142 | .axoCover/* 143 | !.axoCover/settings.json 144 | 145 | # Coverlet is a free, cross platform Code Coverage Tool 146 | coverage*.json 147 | coverage*.xml 148 | coverage*.info 149 | 150 | # Visual Studio code coverage results 151 | *.coverage 152 | *.coveragexml 153 | 154 | # NCrunch 155 | _NCrunch_* 156 | .*crunch*.local.xml 157 | nCrunchTemp_* 158 | 159 | # MightyMoose 160 | *.mm.* 161 | AutoTest.Net/ 162 | 163 | # Web workbench (sass) 164 | .sass-cache/ 165 | 166 | # Installshield output folder 167 | [Ee]xpress/ 168 | 169 | # DocProject is a documentation generator add-in 170 | DocProject/buildhelp/ 171 | DocProject/Help/*.HxT 172 | DocProject/Help/*.HxC 173 | DocProject/Help/*.hhc 174 | DocProject/Help/*.hhk 175 | DocProject/Help/*.hhp 176 | DocProject/Help/Html2 177 | DocProject/Help/html 178 | 179 | # Click-Once directory 180 | publish/ 181 | 182 | # Publish Web Output 183 | *.[Pp]ublish.xml 184 | *.azurePubxml 185 | # Note: Comment the next line if you want to checkin your web deploy settings, 186 | # but database connection strings (with potential passwords) will be unencrypted 187 | *.pubxml 188 | *.publishproj 189 | 190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 191 | # checkin your Azure Web App publish settings, but sensitive information contained 192 | # in these scripts will be unencrypted 193 | PublishScripts/ 194 | 195 | # NuGet Packages 196 | *.nupkg 197 | # NuGet Symbol Packages 198 | *.snupkg 199 | # The packages folder can be ignored because of Package Restore 200 | **/[Pp]ackages/* 201 | # except build/, which is used as an MSBuild target. 202 | !**/[Pp]ackages/build/ 203 | # Uncomment if necessary however generally it will be regenerated when needed 204 | #!**/[Pp]ackages/repositories.config 205 | # NuGet v3's project.json files produces more ignorable files 206 | *.nuget.props 207 | *.nuget.targets 208 | 209 | # Microsoft Azure Build Output 210 | csx/ 211 | *.build.csdef 212 | 213 | # Microsoft Azure Emulator 214 | ecf/ 215 | rcf/ 216 | 217 | # Windows Store app package directories and files 218 | AppPackages/ 219 | BundleArtifacts/ 220 | Package.StoreAssociation.xml 221 | _pkginfo.txt 222 | *.appx 223 | *.appxbundle 224 | *.appxupload 225 | 226 | # Visual Studio cache files 227 | # files ending in .cache can be ignored 228 | *.[Cc]ache 229 | # but keep track of directories ending in .cache 230 | !?*.[Cc]ache/ 231 | 232 | # Others 233 | ClientBin/ 234 | ~$* 235 | *~ 236 | *.dbmdl 237 | *.dbproj.schemaview 238 | *.jfm 239 | *.pfx 240 | *.publishsettings 241 | orleans.codegen.cs 242 | 243 | # Including strong name files can present a security risk 244 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 245 | #*.snk 246 | 247 | # Since there are multiple workflows, uncomment next line to ignore bower_components 248 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 249 | #bower_components/ 250 | 251 | # RIA/Silverlight projects 252 | Generated_Code/ 253 | 254 | # Backup & report files from converting an old project file 255 | # to a newer Visual Studio version. Backup files are not needed, 256 | # because we have git ;-) 257 | _UpgradeReport_Files/ 258 | Backup*/ 259 | UpgradeLog*.XML 260 | UpgradeLog*.htm 261 | ServiceFabricBackup/ 262 | *.rptproj.bak 263 | 264 | # SQL Server files 265 | *.mdf 266 | *.ldf 267 | *.ndf 268 | 269 | # Business Intelligence projects 270 | *.rdl.data 271 | *.bim.layout 272 | *.bim_*.settings 273 | *.rptproj.rsuser 274 | *- [Bb]ackup.rdl 275 | *- [Bb]ackup ([0-9]).rdl 276 | *- [Bb]ackup ([0-9][0-9]).rdl 277 | 278 | # Microsoft Fakes 279 | FakesAssemblies/ 280 | 281 | # GhostDoc plugin setting file 282 | *.GhostDoc.xml 283 | 284 | # Node.js Tools for Visual Studio 285 | .ntvs_analysis.dat 286 | node_modules/ 287 | 288 | # Visual Studio 6 build log 289 | *.plg 290 | 291 | # Visual Studio 6 workspace options file 292 | *.opt 293 | 294 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 295 | *.vbw 296 | 297 | # Visual Studio 6 auto-generated project file (contains which files were open etc.) 298 | *.vbp 299 | 300 | # Visual Studio 6 workspace and project file (working project files containing files to include in project) 301 | *.dsw 302 | *.dsp 303 | 304 | # Visual Studio 6 technical files 305 | *.ncb 306 | *.aps 307 | 308 | # Visual Studio LightSwitch build output 309 | **/*.HTMLClient/GeneratedArtifacts 310 | **/*.DesktopClient/GeneratedArtifacts 311 | **/*.DesktopClient/ModelManifest.xml 312 | **/*.Server/GeneratedArtifacts 313 | **/*.Server/ModelManifest.xml 314 | _Pvt_Extensions 315 | 316 | # Paket dependency manager 317 | .paket/paket.exe 318 | paket-files/ 319 | 320 | # FAKE - F# Make 321 | .fake/ 322 | 323 | # CodeRush personal settings 324 | .cr/personal 325 | 326 | # Python Tools for Visual Studio (PTVS) 327 | __pycache__/ 328 | *.pyc 329 | 330 | # Cake - Uncomment if you are using it 331 | # tools/** 332 | # !tools/packages.config 333 | 334 | # Tabs Studio 335 | *.tss 336 | 337 | # Telerik's JustMock configuration file 338 | *.jmconfig 339 | 340 | # BizTalk build output 341 | *.btp.cs 342 | *.btm.cs 343 | *.odx.cs 344 | *.xsd.cs 345 | 346 | # OpenCover UI analysis results 347 | OpenCover/ 348 | 349 | # Azure Stream Analytics local run output 350 | ASALocalRun/ 351 | 352 | # MSBuild Binary and Structured Log 353 | *.binlog 354 | 355 | # NVidia Nsight GPU debugger configuration file 356 | *.nvuser 357 | 358 | # MFractors (Xamarin productivity tool) working folder 359 | .mfractor/ 360 | 361 | # Local History for Visual Studio 362 | .localhistory/ 363 | 364 | # Visual Studio History (VSHistory) files 365 | .vshistory/ 366 | 367 | # BeatPulse healthcheck temp database 368 | healthchecksdb 369 | 370 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 371 | MigrationBackup/ 372 | 373 | # Ionide (cross platform F# VS Code tools) working folder 374 | .ionide/ 375 | 376 | # Fody - auto-generated XML schema 377 | FodyWeavers.xsd 378 | 379 | # VS Code files for those working on multiple tools 380 | .vscode/* 381 | !.vscode/settings.json 382 | !.vscode/tasks.json 383 | !.vscode/launch.json 384 | !.vscode/extensions.json 385 | *.code-workspace 386 | 387 | # Local History for Visual Studio Code 388 | .history/ 389 | 390 | # Windows Installer files from build outputs 391 | *.cab 392 | *.msi 393 | *.msix 394 | *.msm 395 | *.msp 396 | 397 | # JetBrains Rider 398 | *.sln.iml -------------------------------------------------------------------------------- /CheatDriver/CheatController/CheatController.cpp: -------------------------------------------------------------------------------- 1 | // CheatController.cpp : This file contains the 'main' function. Program execution begins and ends there. 2 | // certmgr /add CheatDriver.cer /s /r localMachine root 3 | //bcdedit / set testsigning on 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "../CheatDriver/CheatDriver_Common.h" 11 | 12 | #define LOG_ERROR(FormatString, ...) 13 | #define LOG_INFO(FormatString, ...) 14 | #define LOG_INFO_FAILURE(FormatString, ...) 15 | #define LOG_PASSED(FormatString, ...) 16 | 17 | WCHAR DriverPath[MAX_PATH]; 18 | SC_HANDLE TcScmHandle = NULL; 19 | UCHAR JUMP_RAX[] = "\x48\xB8\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xE0"; 20 | UCHAR JUMP_WITH_R14[] = "\x56\x48\xB8\x00\x00\x00\x00\x00\x00\x00\x00\x8f\x00\x90\x90"; 21 | 22 | void PrintHeader() 23 | { 24 | printf(" <\\ _\n" 25 | " \\\\ _ / {\n" 26 | " _ \\\\ _- -_\n" 27 | " /{ / `\\ _- - -_\n" 28 | " _~ = ( @ \\ - - -_\n" 29 | " _- - ~-_ \\( =\\ \\ - -_\n" 30 | " _~ - ~_ | 1 :\\ \\ _-~-_ - -_\n" 31 | " _- - ~ |V: \\ \\ _-~ ~-_- -_\n" 32 | " _-~ - / | : \\ \\ ~-_- -_\n" 33 | " _-~ - _.._ { | : _-`` ~- _-_\n" 34 | " _-~ -__..--~ ~-_ { : \\:}\n" 35 | "=~__.--~~ ~-_\\ : /\n" 36 | " \\ : /__\n" 37 | " //`Y'--\\\\ = IOCTL\n" 38 | " <+ \\\\\n" 39 | " \\\\ WWW\n" 40 | " MMM\n"); 41 | } 42 | 43 | BOOL TcGetServiceState( 44 | _In_ SC_HANDLE ServiceHandle, 45 | _Out_ DWORD* State 46 | ) 47 | { 48 | SERVICE_STATUS_PROCESS ServiceStatus; 49 | DWORD BytesNeeded; 50 | 51 | *State = 0; 52 | 53 | BOOL Result = QueryServiceStatusEx( 54 | ServiceHandle, 55 | SC_STATUS_PROCESS_INFO, 56 | (LPBYTE)&ServiceStatus, 57 | sizeof(ServiceStatus), 58 | &BytesNeeded 59 | ); 60 | 61 | if (Result == FALSE) 62 | { 63 | printf("TcGetServiceState: QueryServiceStatusEx failed, last error 0x%x\n", GetLastError()); 64 | return FALSE; 65 | } 66 | 67 | *State = ServiceStatus.dwCurrentState; 68 | 69 | return TRUE; 70 | } 71 | 72 | BOOL TcWaitForServiceState( 73 | _In_ SC_HANDLE ServiceHandle, 74 | _In_ DWORD State 75 | ) 76 | { 77 | for (;;) 78 | { 79 | //printf("TcWaitForServiceState: Waiting for service %p to enter state %u...\n", (DWORD_PTR)ServiceHandle, State); 80 | 81 | DWORD ServiceState; 82 | BOOL Result = TcGetServiceState(ServiceHandle, &ServiceState); 83 | 84 | if (Result == FALSE) 85 | { 86 | printf("TcWaitForServiceState: failed to get state\n"); 87 | return FALSE; 88 | } 89 | 90 | if (ServiceState == State) 91 | { 92 | break; 93 | } 94 | 95 | Sleep(1000); 96 | } 97 | //printf("TcWaitForServiceState: Success service %p in state %u...\n", (DWORD_PTR)ServiceHandle, State); 98 | return TRUE; 99 | } 100 | 101 | BOOL TcDeleteService() 102 | { 103 | BOOL ReturnValue = FALSE; 104 | 105 | 106 | LOG_INFO(L"TcDeleteService: Entering\n"); 107 | 108 | // 109 | // Open the service so we can delete it 110 | // 111 | 112 | SC_HANDLE ServiceHandle = OpenService( 113 | TcScmHandle, 114 | (LPCWSTR)CD_DRIVER_NAME, 115 | SERVICE_ALL_ACCESS 116 | ); 117 | 118 | DWORD LastError = GetLastError(); 119 | 120 | if (ServiceHandle == NULL) 121 | { 122 | if (LastError == ERROR_SERVICE_DOES_NOT_EXIST) 123 | { 124 | ReturnValue = TRUE; 125 | } 126 | else 127 | { 128 | LOG_INFO_FAILURE(L"TcDeleteService: OpenService failed, last error 0x%x\n", LastError); 129 | } 130 | 131 | goto Cleanup; 132 | } 133 | 134 | // 135 | // Delete the service 136 | // 137 | 138 | if (!DeleteService(ServiceHandle)) 139 | { 140 | LastError = GetLastError(); 141 | 142 | if (LastError != ERROR_SERVICE_MARKED_FOR_DELETE) 143 | { 144 | LOG_INFO_FAILURE(L"TcDeleteService: DeleteService failed, last error 0x%x", LastError); 145 | goto Cleanup; 146 | } 147 | } 148 | 149 | ReturnValue = TRUE; 150 | 151 | Cleanup: 152 | 153 | if (ServiceHandle) 154 | { 155 | CloseServiceHandle(ServiceHandle); 156 | } 157 | 158 | LOG_INFO(L"TcDeleteService: Exiting"); 159 | 160 | return ReturnValue; 161 | } 162 | 163 | BOOL TcCreateService() 164 | { 165 | BOOL ReturnValue = FALSE; 166 | 167 | printf("TcCreateService: Entering\n"); 168 | 169 | // 170 | // Create the service 171 | // 172 | printf("Trying to install the service %ws\n", DriverPath); 173 | 174 | SC_HANDLE ServiceHandle = CreateServiceW( 175 | TcScmHandle, // handle to SC manager 176 | CD_DRIVER_NAME, // name of service 177 | CD_DRIVER_NAME, // display name 178 | SERVICE_ALL_ACCESS, // access mask 179 | SERVICE_KERNEL_DRIVER, // service type 180 | SERVICE_DEMAND_START, // start type 181 | SERVICE_ERROR_NORMAL, // error control 182 | DriverPath, // full path to driver 183 | NULL, // load ordering 184 | NULL, // tag id 185 | NULL, // dependency 186 | NULL, // account name 187 | NULL // password 188 | ); 189 | 190 | DWORD LastError = GetLastError(); 191 | 192 | if (ServiceHandle == NULL && LastError != ERROR_SERVICE_EXISTS) 193 | { 194 | printf("CreateService failed, last error 0x%x\n", LastError); 195 | goto Cleanup; 196 | } 197 | 198 | ReturnValue = TRUE; 199 | 200 | Cleanup: 201 | 202 | if (ServiceHandle) 203 | { 204 | CloseServiceHandle(ServiceHandle); 205 | } 206 | 207 | printf("TcCreateService: Exiting\n"); 208 | 209 | return ReturnValue; 210 | } 211 | 212 | BOOL TcStopService() 213 | { 214 | BOOL ReturnValue = FALSE; 215 | 216 | printf("TcStopService: Entering\n"); 217 | 218 | // 219 | // Open the service so we can stop it 220 | // 221 | 222 | SC_HANDLE ServiceHandle = OpenService( 223 | TcScmHandle, 224 | (LPCWSTR)CD_DRIVER_NAME, 225 | SERVICE_ALL_ACCESS 226 | ); 227 | 228 | DWORD LastError = GetLastError(); 229 | 230 | if (ServiceHandle == NULL) 231 | { 232 | if (LastError == ERROR_SERVICE_DOES_NOT_EXIST) 233 | { 234 | ReturnValue = TRUE; 235 | } 236 | else 237 | { 238 | printf("TcStopService: OpenService failed, last error 0x%x\n", LastError); 239 | } 240 | 241 | goto Cleanup; 242 | } 243 | 244 | // 245 | // Stop the service 246 | // 247 | 248 | SERVICE_STATUS ServiceStatus; 249 | 250 | if (FALSE == ControlService(ServiceHandle, SERVICE_CONTROL_STOP, &ServiceStatus)) 251 | { 252 | LastError = GetLastError(); 253 | 254 | if (LastError != ERROR_SERVICE_NOT_ACTIVE) 255 | { 256 | printf("TcStopService: ControlService failed, last error 0x%x\n", LastError); 257 | goto Cleanup; 258 | } 259 | } 260 | 261 | if (FALSE == TcWaitForServiceState(ServiceHandle, SERVICE_STOPPED)) 262 | { 263 | goto Cleanup; 264 | } 265 | 266 | ReturnValue = TRUE; 267 | 268 | Cleanup: 269 | 270 | if (ServiceHandle) 271 | { 272 | CloseServiceHandle(ServiceHandle); 273 | } 274 | 275 | printf("TcStopService: Exiting\n"); 276 | 277 | return ReturnValue; 278 | } 279 | 280 | BOOL TcStartService() 281 | { 282 | BOOL ReturnValue = FALSE; 283 | printf("TcStartService: Entering\n"); 284 | // 285 | // Open the service. The function assumes that 286 | // TdCreateService has been called before this one 287 | // and the service is already installed. 288 | // 289 | 290 | SC_HANDLE ServiceHandle = OpenServiceW( 291 | TcScmHandle, 292 | CD_DRIVER_NAME, 293 | SERVICE_ALL_ACCESS 294 | ); 295 | 296 | if (ServiceHandle == NULL) 297 | { 298 | printf("TcStartService: OpenService failed, last error 0x%x\n", GetLastError()); 299 | goto Cleanup; 300 | } 301 | 302 | // 303 | // Start the service 304 | // 305 | 306 | if (!StartService(ServiceHandle, 0, NULL)) 307 | { 308 | if (GetLastError() != ERROR_SERVICE_ALREADY_RUNNING) 309 | { 310 | printf("TcStartService: StartService failed, last error 0x%x\n", GetLastError()); 311 | goto Cleanup; 312 | } 313 | } 314 | 315 | if (FALSE == TcWaitForServiceState(ServiceHandle, SERVICE_RUNNING)) 316 | { 317 | goto Cleanup; 318 | } 319 | 320 | ReturnValue = TRUE; 321 | 322 | Cleanup: 323 | 324 | if (ServiceHandle) 325 | { 326 | CloseServiceHandle(ServiceHandle); 327 | } 328 | 329 | return ReturnValue; 330 | } 331 | 332 | BOOL TcUnloadDriver() 333 | { 334 | BOOL ReturnValue = FALSE; 335 | 336 | printf("TcUnloadDriver: Entering\n"); 337 | 338 | 339 | // 340 | // Unload the driver. 341 | // 342 | 343 | ReturnValue = TcStopService(); 344 | 345 | if (ReturnValue == FALSE) 346 | { 347 | printf("TcStopService failed\n"); 348 | goto Cleanup; 349 | } 350 | 351 | // 352 | // Delete the service. 353 | // 354 | 355 | ReturnValue = TcDeleteService(); 356 | 357 | if (ReturnValue == FALSE) 358 | { 359 | printf("TcDeleteService failed\n"); 360 | goto Cleanup; 361 | } 362 | 363 | ReturnValue = TRUE; 364 | 365 | Cleanup: 366 | 367 | printf("TcUnloadDriver: Exiting\n"); 368 | 369 | return ReturnValue; 370 | } 371 | 372 | BOOL TcLoadDriver() 373 | { 374 | BOOL ReturnValue = FALSE; 375 | 376 | printf("TcLoadDriver: Entering\n"); 377 | 378 | // 379 | // First, uninstall and unload the driver. 380 | // 381 | 382 | ReturnValue = TcUnloadDriver(); 383 | 384 | if (ReturnValue != TRUE) 385 | { 386 | printf("TcUnloadDriver failed\n"); 387 | goto Cleanup; 388 | } 389 | 390 | ReturnValue = TcCreateService(); 391 | 392 | if (ReturnValue == FALSE) 393 | { 394 | printf("TcCreateService failed\n"); 395 | goto Cleanup; 396 | } 397 | 398 | // 399 | // Load the driver. 400 | // 401 | 402 | ReturnValue = TcStartService(); 403 | 404 | if (ReturnValue == FALSE) 405 | { 406 | printf("TcStartService failed\n"); 407 | goto Cleanup; 408 | } 409 | 410 | 411 | ReturnValue = TRUE; 412 | 413 | Cleanup: 414 | 415 | printf("TcLoadDriver: Exiting\n"); 416 | return ReturnValue; 417 | } 418 | 419 | BOOL TcInstallDriver() 420 | { 421 | BOOL bRC = TRUE; 422 | 423 | printf("TcInstallDriver: Entering\n"); 424 | BOOL Result = TcLoadDriver(); 425 | 426 | if (Result != TRUE) 427 | { 428 | LOG_ERROR(L"TcLoadDriver failed, exiting\n"); 429 | bRC = FALSE; 430 | goto Cleanup; 431 | } 432 | 433 | Cleanup: 434 | 435 | printf("TcInstallDriver: Exiting\n"); 436 | return bRC; 437 | } 438 | 439 | BOOL Init() { 440 | BOOL ReturnValue = FALSE; 441 | // Create Serivice 442 | if (TcScmHandle == NULL) 443 | { 444 | TcScmHandle = OpenSCManager( 445 | NULL, 446 | NULL, 447 | SC_MANAGER_ALL_ACCESS 448 | ); 449 | 450 | if (TcScmHandle == NULL) 451 | { 452 | printf("OpenSCManager failed, last error 0x%x\n", GetLastError()); 453 | goto Cleanup; 454 | } 455 | } 456 | 457 | // Get Driver Path 458 | GetCurrentDirectoryW(ARRAYSIZE(DriverPath), DriverPath); 459 | wcsncat_s(DriverPath, L"\\CheatDriver.sys", 460 | ARRAYSIZE(DriverPath) - wcsnlen_s(DriverPath, ARRAYSIZE(DriverPath))); 461 | printf("DriverPath %ws\n", DriverPath); 462 | ReturnValue = TRUE; 463 | 464 | Cleanup: 465 | return ReturnValue; 466 | } 467 | 468 | int wmain( 469 | _In_ int argc, 470 | _In_ LPCWSTR argv[] 471 | ) 472 | { 473 | HANDLE deviceHandle; 474 | ULONG status; 475 | ULONG bytesReturned; 476 | CHAR input[MAX_PATH]; 477 | PVOID outputBuffer; 478 | ULONG outputBufferSize = 0x10000; 479 | HANDLE procHandle; 480 | DEVICE_NAME_STRUCT newName = { }; 481 | PCD_MODULE_OUTPUT_STRUCT pModuleOutput; 482 | PCD_MODULE_STRUCT ModuleInfo; 483 | PCD_HOOKS_OUTPUT_STRUCT pHookOutput; 484 | PCD_HOOK_STRUCT HookInfo; 485 | CD_HOOK_STRUCT newHook = { }; 486 | DWORD retVal = 0; 487 | memcpy(newName.deviceName, CD_DEVICE_NAME, wcslen(CD_DEVICE_NAME) * sizeof(wchar_t)); 488 | memcpy(newName.symbolicName, CD_SYMBOLIC_LINK_NAME, wcslen(CD_SYMBOLIC_LINK_NAME) * sizeof(wchar_t)); 489 | 490 | // allocate a big output buffer...this is a shortcut but tell nobody... 491 | outputBuffer = malloc(outputBufferSize); 492 | if (outputBuffer == NULL) 493 | { 494 | return -1; 495 | } 496 | 497 | if (argc > 0) 498 | { 499 | const wchar_t* arg = argv[1]; 500 | if (!Init()) 501 | { 502 | printf("Init Fail!\n"); 503 | return 1; 504 | } 505 | if (0 == wcscmp(arg, L"-load")) 506 | { 507 | PrintHeader(); 508 | printf("Loading driver ...\n"); 509 | TcInstallDriver(); 510 | } 511 | } 512 | // Open the target device 513 | deviceHandle = CreateFileW(CD_WIN32_LINK_NAME, 514 | GENERIC_READ | GENERIC_WRITE, 515 | 0, 516 | 0, 517 | OPEN_EXISTING, 518 | FILE_FLAG_OVERLAPPED, 519 | 0); 520 | 521 | if (deviceHandle == INVALID_HANDLE_VALUE) 522 | { 523 | status = GetLastError(); 524 | printf("CreateFile Error 0x%x\n", status); 525 | return 1; 526 | } 527 | printf("CreateFile 0x%x\n", deviceHandle); 528 | while (1) 529 | { 530 | memset(outputBuffer, 0, outputBufferSize); 531 | memset(input, 0, MAX_PATH); 532 | DWORD32 moduleid = 0; 533 | 534 | printf("\n>>>> Cheat Console:\n\n"); 535 | printf("\t1 List Modules\n"); 536 | printf("\t2 Select Module\n"); 537 | printf("\t3 List Hooks\n"); 538 | printf("\t4 Place Hook (Inserts Into list, TODO: set hook)\n"); 539 | printf("\t5 Kernel Memory Read (TODO)\n"); 540 | printf("\t6 Kernel Memory Write (TODO)\n"); 541 | printf("\t7 Get Trampoline Func Address (TODO)\n"); 542 | printf("\n\t0 Exit\n"); 543 | printf("\n\tSelection: "); 544 | 545 | StringCchGetsA(input, MAX_PATH - 1); 546 | 547 | switch (input[0]) 548 | { 549 | case '0': 550 | { 551 | CloseHandle(deviceHandle); 552 | return 0; 553 | } 554 | case '1': 555 | { 556 | RtlZeroMemory(outputBuffer, outputBufferSize); 557 | status = DeviceIoControl(deviceHandle, 558 | (DWORD)IOCTL_CHEATDRIVER_LISTMODULES, 559 | NULL, 560 | 0, 561 | outputBuffer, 562 | outputBufferSize, 563 | &bytesReturned, 564 | 0); 565 | 566 | printf("Bytes sent from Kernel: 0x%X with status 0x%X\n", bytesReturned, status); 567 | pModuleOutput = (PCD_MODULE_OUTPUT_STRUCT)outputBuffer; 568 | printf("Number of modules: 0x%X, Bytes: 0x%X\n", pModuleOutput->NumberOfModules, pModuleOutput->ModuleListSizeInBytes); 569 | for (unsigned int i = 0; i < pModuleOutput->NumberOfModules; i++) 570 | { 571 | ModuleInfo = (PCD_MODULE_STRUCT)(pModuleOutput->Modules + (i * pModuleOutput->ModuleListSizeInBytes)); 572 | printf("|%d\t|\t0x%X\t|\t%s\n", ModuleInfo->ModuleID, ModuleInfo->BaseAddr, ModuleInfo->ModuleName); 573 | } 574 | break; 575 | } 576 | case '2': 577 | { 578 | printf("\n\tEnter Module ID: "); 579 | StringCchGetsA(input, MAX_PATH - 1); 580 | DWORD32 moduleSelection = 0; 581 | int nSize = sscanf_s(input, "%d", &moduleSelection); 582 | printf("\n\tSelected %d", moduleSelection); 583 | memcpy(outputBuffer, &moduleSelection, sizeof(DWORD32)); 584 | status = DeviceIoControl(deviceHandle, 585 | (DWORD)IOCTL_CHEATDRIVER_SELECT, 586 | outputBuffer, 587 | sizeof(DWORD32), 588 | outputBuffer, 589 | outputBufferSize, 590 | &bytesReturned, 591 | 0); 592 | 593 | printf("Bytes sent from Kernel: 0x%X with status 0x%X\n", bytesReturned, status); 594 | ModuleInfo = (PCD_MODULE_STRUCT)outputBuffer; 595 | printf("SELECTED: |%d\t|\t0x%X\t|\t%s\n", ModuleInfo->ModuleID, ModuleInfo->BaseAddr, ModuleInfo->ModuleName); 596 | break; 597 | } 598 | case '3': 599 | { 600 | RtlZeroMemory(outputBuffer, outputBufferSize); 601 | status = DeviceIoControl(deviceHandle, 602 | (DWORD)IOCTL_CHEATDRIVER_LISTHOOKS, 603 | NULL, 604 | 0, 605 | outputBuffer, 606 | outputBufferSize, 607 | &bytesReturned, 608 | 0); 609 | 610 | printf("Bytes sent from Kernel: 0x%X with status 0x%X\n", bytesReturned, status); 611 | pHookOutput = (PCD_HOOKS_OUTPUT_STRUCT)outputBuffer; 612 | printf("Number of hooks: 0x%X, Bytes: 0x%X\n", pHookOutput->NumberOfHooks, pHookOutput->HooksListSizeInBytes); 613 | for (unsigned int i = 0; i < pHookOutput->NumberOfHooks; i++) 614 | { 615 | HookInfo = (PCD_HOOK_STRUCT)(pHookOutput->Hooks + (i * pHookOutput->HooksListSizeInBytes)); 616 | printf("|%d\t|\t0x%X\t|\t%d\n", 617 | HookInfo->ModuleID, HookInfo->Hook.EntryAddr, HookInfo->Hook.HookStatus); 618 | } 619 | break; 620 | } 621 | case '4': 622 | { 623 | // This is a test 624 | newHook.Hook.EntryAddr = 0x1234; 625 | newHook.Hook.JumpAddr = 0x4567; 626 | newHook.Hook.ReturnAddr = 0x9123; 627 | newHook.Hook.IsCustomHook = TRUE; 628 | memcpy(newHook.Hook.CustomHookBuffer, JUMP_RAX, sizeof(JUMP_RAX)); 629 | newHook.Hook.CustomHookLen = sizeof(JUMP_RAX); 630 | 631 | memcpy(outputBuffer, &newHook, sizeof(newHook)); 632 | status = DeviceIoControl(deviceHandle, 633 | (DWORD)IOCTL_CHEATDRIVER_PLACEHOOK, 634 | outputBuffer, 635 | sizeof(newHook), 636 | outputBuffer, 637 | outputBufferSize, 638 | &bytesReturned, 639 | 0); 640 | if (status == STATUS_SUCCESS) 641 | { 642 | printf("Handle successfully transfered."); 643 | } 644 | break; 645 | } 646 | case '5': 647 | { 648 | // TODO 649 | break; 650 | } 651 | case '6': 652 | { 653 | // TODO 654 | break; 655 | } 656 | 657 | } 658 | } 659 | 660 | } -------------------------------------------------------------------------------- /CheatDriver/CheatController/CheatController.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | Win32Proj 24 | {8cdc3255-3903-4f66-bfd3-fd04ca844807} 25 | CheatController 26 | 10.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v142 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | v142 39 | true 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | v142 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | v142 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | 76 | 77 | false 78 | 79 | 80 | true 81 | 82 | 83 | false 84 | 85 | 86 | 87 | Level3 88 | true 89 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 90 | true 91 | 92 | 93 | Console 94 | true 95 | 96 | 97 | 98 | 99 | Level3 100 | true 101 | true 102 | true 103 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 104 | true 105 | 106 | 107 | Console 108 | true 109 | true 110 | true 111 | 112 | 113 | 114 | 115 | Level3 116 | true 117 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 118 | true 119 | 120 | 121 | Console 122 | true 123 | 124 | 125 | 126 | 127 | Level3 128 | true 129 | true 130 | true 131 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 132 | true 133 | 134 | 135 | Console 136 | true 137 | true 138 | true 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | -------------------------------------------------------------------------------- /CheatDriver/CheatController/CheatController.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /CheatDriver/CheatDriver.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.32228.343 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CheatDriver", "CheatDriver\CheatDriver.vcxproj", "{D73F86ED-1846-4626-9053-4715375FFB52}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CheatController", "CheatController\CheatController.vcxproj", "{8CDC3255-3903-4F66-BFD3-FD04CA844807}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|ARM = Debug|ARM 13 | Debug|ARM64 = Debug|ARM64 14 | Debug|x64 = Debug|x64 15 | Debug|x86 = Debug|x86 16 | Release|ARM = Release|ARM 17 | Release|ARM64 = Release|ARM64 18 | Release|x64 = Release|x64 19 | Release|x86 = Release|x86 20 | EndGlobalSection 21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 22 | {D73F86ED-1846-4626-9053-4715375FFB52}.Debug|ARM.ActiveCfg = Debug|ARM 23 | {D73F86ED-1846-4626-9053-4715375FFB52}.Debug|ARM.Build.0 = Debug|ARM 24 | {D73F86ED-1846-4626-9053-4715375FFB52}.Debug|ARM.Deploy.0 = Debug|ARM 25 | {D73F86ED-1846-4626-9053-4715375FFB52}.Debug|ARM64.ActiveCfg = Debug|ARM64 26 | {D73F86ED-1846-4626-9053-4715375FFB52}.Debug|ARM64.Build.0 = Debug|ARM64 27 | {D73F86ED-1846-4626-9053-4715375FFB52}.Debug|ARM64.Deploy.0 = Debug|ARM64 28 | {D73F86ED-1846-4626-9053-4715375FFB52}.Debug|x64.ActiveCfg = Debug|x64 29 | {D73F86ED-1846-4626-9053-4715375FFB52}.Debug|x64.Build.0 = Debug|x64 30 | {D73F86ED-1846-4626-9053-4715375FFB52}.Debug|x64.Deploy.0 = Debug|x64 31 | {D73F86ED-1846-4626-9053-4715375FFB52}.Debug|x86.ActiveCfg = Debug|Win32 32 | {D73F86ED-1846-4626-9053-4715375FFB52}.Debug|x86.Build.0 = Debug|Win32 33 | {D73F86ED-1846-4626-9053-4715375FFB52}.Debug|x86.Deploy.0 = Debug|Win32 34 | {D73F86ED-1846-4626-9053-4715375FFB52}.Release|ARM.ActiveCfg = Release|ARM 35 | {D73F86ED-1846-4626-9053-4715375FFB52}.Release|ARM.Build.0 = Release|ARM 36 | {D73F86ED-1846-4626-9053-4715375FFB52}.Release|ARM.Deploy.0 = Release|ARM 37 | {D73F86ED-1846-4626-9053-4715375FFB52}.Release|ARM64.ActiveCfg = Release|ARM64 38 | {D73F86ED-1846-4626-9053-4715375FFB52}.Release|ARM64.Build.0 = Release|ARM64 39 | {D73F86ED-1846-4626-9053-4715375FFB52}.Release|ARM64.Deploy.0 = Release|ARM64 40 | {D73F86ED-1846-4626-9053-4715375FFB52}.Release|x64.ActiveCfg = Release|x64 41 | {D73F86ED-1846-4626-9053-4715375FFB52}.Release|x64.Build.0 = Release|x64 42 | {D73F86ED-1846-4626-9053-4715375FFB52}.Release|x64.Deploy.0 = Release|x64 43 | {D73F86ED-1846-4626-9053-4715375FFB52}.Release|x86.ActiveCfg = Release|Win32 44 | {D73F86ED-1846-4626-9053-4715375FFB52}.Release|x86.Build.0 = Release|Win32 45 | {D73F86ED-1846-4626-9053-4715375FFB52}.Release|x86.Deploy.0 = Release|Win32 46 | {8CDC3255-3903-4F66-BFD3-FD04CA844807}.Debug|ARM.ActiveCfg = Debug|Win32 47 | {8CDC3255-3903-4F66-BFD3-FD04CA844807}.Debug|ARM64.ActiveCfg = Debug|Win32 48 | {8CDC3255-3903-4F66-BFD3-FD04CA844807}.Debug|x64.ActiveCfg = Release|x64 49 | {8CDC3255-3903-4F66-BFD3-FD04CA844807}.Debug|x64.Build.0 = Release|x64 50 | {8CDC3255-3903-4F66-BFD3-FD04CA844807}.Debug|x86.ActiveCfg = Debug|Win32 51 | {8CDC3255-3903-4F66-BFD3-FD04CA844807}.Debug|x86.Build.0 = Debug|Win32 52 | {8CDC3255-3903-4F66-BFD3-FD04CA844807}.Release|ARM.ActiveCfg = Release|Win32 53 | {8CDC3255-3903-4F66-BFD3-FD04CA844807}.Release|ARM64.ActiveCfg = Release|Win32 54 | {8CDC3255-3903-4F66-BFD3-FD04CA844807}.Release|x64.ActiveCfg = Release|x64 55 | {8CDC3255-3903-4F66-BFD3-FD04CA844807}.Release|x64.Build.0 = Release|x64 56 | {8CDC3255-3903-4F66-BFD3-FD04CA844807}.Release|x86.ActiveCfg = Release|Win32 57 | {8CDC3255-3903-4F66-BFD3-FD04CA844807}.Release|x86.Build.0 = Release|Win32 58 | EndGlobalSection 59 | GlobalSection(SolutionProperties) = preSolution 60 | HideSolutionNode = FALSE 61 | EndGlobalSection 62 | GlobalSection(ExtensibilityGlobals) = postSolution 63 | SolutionGuid = {D41EDDCC-D1BF-4C9E-A276-5F641EBBFE12} 64 | EndGlobalSection 65 | EndGlobal 66 | -------------------------------------------------------------------------------- /CheatDriver/CheatDriver/CheatDriver.cpp: -------------------------------------------------------------------------------- 1 | #include "CheatDriver.h" 2 | #include "CheatDriver_Globals.h" 3 | #include "CheatDriver_Hooks.h" 4 | #include "CheatDriver_Modules.h" 5 | #include "CheatDriver_Common.h" 6 | #include 7 | 8 | extern "C" 9 | { 10 | 11 | #ifdef ALLOC_PRAGMA 12 | #pragma alloc_text (INIT, DriverEntry) 13 | #endif 14 | 15 | Globals_Struct Globals; 16 | 17 | void DeleteAllDevices() 18 | { 19 | PDEVICE_OBJECT currentDevice; 20 | PDEVICE_OBJECT previousDevice; 21 | 22 | currentDevice = Globals.DriverObject->DeviceObject; 23 | while (currentDevice != NULL) 24 | { 25 | KDebugLog("Removing Device at 0x%p\n", currentDevice); 26 | previousDevice = currentDevice; 27 | currentDevice = currentDevice->NextDevice; 28 | IoDeleteDevice(previousDevice); 29 | } 30 | 31 | } 32 | 33 | NTSTATUS RegisterDevice(const wchar_t* deviceName, const wchar_t* linkName) 34 | { 35 | NTSTATUS ntStatus = STATUS_SUCCESS; 36 | UNICODE_STRING devName; 37 | UNICODE_STRING lnkName; 38 | PDEVICE_OBJECT deviceObject; 39 | 40 | if (wcslen(deviceName) >= 255 41 | || wcslen(linkName) >= 255) 42 | { 43 | return STATUS_INVALID_PARAMETER; 44 | } 45 | //TODO: string validation 46 | RtlInitUnicodeString(&devName, deviceName); 47 | RtlInitUnicodeString(&lnkName, linkName); 48 | 49 | // Create the device object and device extension 50 | ntStatus = IoCreateDeviceSecure( 51 | Globals.DriverObject, 52 | 0, 53 | &devName, 54 | FILE_DEVICE_CHEATDRIVER, 55 | FILE_DEVICE_SECURE_OPEN, 56 | FALSE, 57 | &SDDL_DEVOBJ_SYS_ALL_ADM_ALL, 58 | &guidProto, 59 | &deviceObject); 60 | 61 | if (ntStatus == STATUS_SUCCESS) 62 | { 63 | // Create a symbolic link to allow USER applications to access it. 64 | ntStatus = IoCreateSymbolicLink(&lnkName, &devName); 65 | if (ntStatus == STATUS_SUCCESS) 66 | { 67 | // Tell the I/O Manger to do BUFFERED IO 68 | deviceObject->Flags |= DO_BUFFERED_IO; 69 | deviceObject->Flags &= ~DO_DEVICE_INITIALIZING; 70 | RtlZeroMemory(Globals.DeviceName.deviceName, sizeof(Globals.DeviceName.deviceName)); 71 | RtlZeroMemory(Globals.DeviceName.symbolicName, sizeof(Globals.DeviceName.symbolicName)); 72 | RtlCopyMemory(Globals.DeviceName.deviceName, deviceName, wcslen(deviceName) * sizeof(wchar_t)); 73 | RtlCopyMemory(Globals.DeviceName.symbolicName, linkName, wcslen(linkName) * sizeof(wchar_t)); 74 | } 75 | else 76 | { 77 | KDebugLog("IoCreateSymbolicLink Failed. ntStatus= 0x%X\n", ntStatus); 78 | IoDeleteDevice(deviceObject); 79 | } 80 | } 81 | else 82 | { 83 | KDebugLog("IoCreateDevice Failed. ntSTatus = 0x%X\n", ntStatus); 84 | } 85 | return ntStatus; 86 | } 87 | 88 | NTSTATUS 89 | DriverEntry( 90 | IN PDRIVER_OBJECT DriverObject, 91 | IN PUNICODE_STRING RegistryPath) 92 | { 93 | NTSTATUS NtStatus = STATUS_UNSUCCESSFUL; 94 | UNREFERENCED_PARAMETER(RegistryPath); 95 | BOOLEAN DeviceRegistered = FALSE; 96 | 97 | // Init Globals 98 | RtlZeroMemory(&Globals, sizeof(Globals)); 99 | RtlCopyMemory(Globals.DeviceName.deviceName, CD_DEVICE_NAME, sizeof(CD_DEVICE_NAME)); 100 | RtlCopyMemory(Globals.DeviceName.symbolicName, CD_SYMBOLIC_LINK_NAME, sizeof(CD_SYMBOLIC_LINK_NAME)); 101 | RtlCopyMemory(Globals.DeviceName.win32LinkName, CD_WIN32_LINK_NAME, sizeof(CD_WIN32_LINK_NAME)); 102 | 103 | Globals.DriverObject = DriverObject; 104 | DriverObject->DriverUnload = DriverUnload; 105 | DriverObject->MajorFunction[IRP_MJ_CREATE] = IrpCreate; 106 | DriverObject->MajorFunction[IRP_MJ_CLOSE] = IrpClose; 107 | DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IrpDeviceControl; 108 | 109 | KdPrint(("kdPrint Hello World\n")); 110 | KdPrint(("DeviceObject = 0x%p\n", DriverObject->DeviceObject)); 111 | NtStatus = RegisterDevice(Globals.DeviceName.deviceName, Globals.DeviceName.symbolicName); 112 | if (NtStatus != STATUS_SUCCESS) 113 | { 114 | goto Cleanup; 115 | } 116 | DeviceRegistered = TRUE; 117 | NtStatus = Module_Startup(); 118 | if (!NT_SUCCESS(NtStatus)) 119 | { 120 | goto Cleanup; 121 | } 122 | NtStatus = Hooks_Startup(); 123 | if (!NT_SUCCESS(NtStatus)) 124 | { 125 | goto Cleanup; 126 | } 127 | KDebugLog("DeviceObject = 0x%p\n", DriverObject->DeviceObject); 128 | Cleanup: 129 | if (!NT_SUCCESS(NtStatus)) 130 | { 131 | // Do clean up 132 | if (TRUE == DeviceRegistered) 133 | { 134 | DeleteAllDevices(); 135 | } 136 | } 137 | return NtStatus; 138 | } 139 | 140 | // Functions 141 | // Lookup process by PID 142 | // Get baseaddress of Driver 143 | // Read 144 | // Write 145 | // Scan for pattern 146 | // Place Hook 147 | 148 | void 149 | DriverUnload( 150 | IN PDRIVER_OBJECT DriverObject) 151 | { 152 | UNREFERENCED_PARAMETER(DriverObject); 153 | UNICODE_STRING symbolicName; 154 | NTSTATUS ntStatus; 155 | LARGE_INTEGER wait; 156 | 157 | wait.HighPart = 0; 158 | wait.LowPart = 1000; 159 | RtlInitUnicodeString(&symbolicName, Globals.DeviceName.symbolicName); 160 | if (symbolicName.Length > 1) 161 | { 162 | KeDelayExecutionThread(KernelMode, false, &wait); 163 | KDebugLog("Deleting Symbolic Link: %wZ\n", symbolicName); 164 | ntStatus = IoDeleteSymbolicLink(&symbolicName); 165 | KDebugLog("DeleteSymbolicLink code = 0x%X\n", ntStatus); 166 | } 167 | // Clean up module list 168 | Module_Cleanup(); 169 | Hooks_Cleanup(); 170 | DeleteAllDevices(); 171 | KdPrint(("YOU DIED!\n")); 172 | } 173 | 174 | NTSTATUS 175 | IrpCreate( 176 | IN PDEVICE_OBJECT DeviceObject, 177 | IN PIRP Irp) 178 | { 179 | UNREFERENCED_PARAMETER(DeviceObject); 180 | 181 | // Ensure the device can only be opened once at a time 182 | if (Globals.HandleOpen) 183 | { 184 | Irp->IoStatus.Status = STATUS_ACCESS_DENIED; 185 | } 186 | else 187 | { 188 | Irp->IoStatus.Status = STATUS_SUCCESS; 189 | Globals.HandleOpen = TRUE; 190 | } 191 | Irp->IoStatus.Information = 0; 192 | KdPrint(("IrpCreate\n")); 193 | // Complete the request 194 | IoCompleteRequest(Irp, IO_NO_INCREMENT); 195 | 196 | return Irp->IoStatus.Status; 197 | } 198 | 199 | NTSTATUS 200 | IrpClose( 201 | IN PDEVICE_OBJECT DeviceObject, 202 | IN PIRP Irp) 203 | { 204 | UNREFERENCED_PARAMETER(DeviceObject); 205 | 206 | Globals.HandleOpen = FALSE; 207 | Irp->IoStatus.Status = STATUS_SUCCESS; 208 | Irp->IoStatus.Information = 0; 209 | KdPrint(("IrpClose\n")); 210 | // Complete the request 211 | IoCompleteRequest(Irp, IO_NO_INCREMENT); 212 | 213 | return STATUS_SUCCESS; 214 | } 215 | 216 | NTSTATUS 217 | IrpDeviceControl( 218 | IN PDEVICE_OBJECT DeviceObject, 219 | IN PIRP Irp) 220 | { 221 | UNREFERENCED_PARAMETER(DeviceObject); 222 | 223 | NTSTATUS NtStatus = STATUS_UNSUCCESSFUL; 224 | PIO_STACK_LOCATION IrpStackLocation = IoGetCurrentIrpStackLocation(Irp); 225 | ULONG DataReturned = 0; 226 | ULONG IoctlCommand = 0; 227 | ULONG OutLen = 0; 228 | ULONG InLen = 0; 229 | PCHAR Buffer = NULL; 230 | ULONG nSize = 0; 231 | DWORD32 targetModule = 0; 232 | 233 | IoctlCommand = IrpStackLocation->Parameters.DeviceIoControl.IoControlCode; 234 | OutLen = IrpStackLocation->Parameters.DeviceIoControl.OutputBufferLength; 235 | InLen = IrpStackLocation->Parameters.DeviceIoControl.InputBufferLength; 236 | Buffer = (PCHAR)Irp->AssociatedIrp.SystemBuffer; 237 | switch (IoctlCommand) 238 | { 239 | case IOCTL_CHEATDRIVER_READ: 240 | break; 241 | case IOCTL_CHEATDRIVER_WRITE: 242 | break; 243 | case IOCTL_CHEATDRIVER_SELECT: 244 | KdPrint(("IOCTL_CHEATDRIVER_SELECT\n")); 245 | targetModule = *(DWORD32*)(Buffer); 246 | NtStatus = SelectModule(targetModule, Buffer, OutLen, &DataReturned); 247 | break; 248 | case IOCTL_CHEATDRIVER_PLACEHOOK: 249 | if (NULL == Buffer) 250 | { 251 | NtStatus = STATUS_INVALID_PARAMETER; 252 | break; 253 | } 254 | KdPrint(("IOCTL_CHEATDRIVER_PLACEHOOK\n")); 255 | NtStatus = InsertHook(Buffer, OutLen, &DataReturned); 256 | break; 257 | case IOCTL_CHEATDRIVER_LISTMODULES: 258 | if (NULL == Buffer) 259 | { 260 | NtStatus = STATUS_INVALID_PARAMETER; 261 | break; 262 | } 263 | KdPrint(("IOCTL_CHEATDRIVER_LISTMODULES\n")); 264 | NtStatus = FillModuleListBuffer(Buffer, OutLen, &DataReturned); 265 | break; 266 | case IOCTL_CHEATDRIVER_LISTHOOKS: 267 | if (NULL == Buffer) 268 | { 269 | NtStatus = STATUS_INVALID_PARAMETER; 270 | break; 271 | } 272 | KdPrint(("IOCTL_CHEATDRIVER_LISTHOOKS\n")); 273 | NtStatus = FillHooksList(Buffer, OutLen, &DataReturned); 274 | break; 275 | default: 276 | NtStatus = STATUS_INVALID_PARAMETER; 277 | break; 278 | } 279 | 280 | Cleanup: 281 | Irp->IoStatus.Status = NtStatus; 282 | if (STATUS_SUCCESS == NtStatus) 283 | { 284 | Irp->IoStatus.Information = DataReturned; 285 | } 286 | Irp->IoStatus.Information = DataReturned; 287 | IoCompleteRequest(Irp, IO_NO_INCREMENT); 288 | return NtStatus; 289 | } 290 | 291 | } // End extern "C" -------------------------------------------------------------------------------- /CheatDriver/CheatDriver/CheatDriver.h: -------------------------------------------------------------------------------- 1 | #ifndef _CHEATDRIVER_H_ 2 | #define _CHEATDRIVER_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" 6 | { 7 | #endif 8 | 9 | #include "ntifs.h" 10 | 11 | #pragma pack ( push, 8 ) 12 | 13 | 14 | NTSTATUS 15 | DriverEntry( 16 | IN PDRIVER_OBJECT DriverObject, 17 | IN PUNICODE_STRING RegistryPath); 18 | 19 | void 20 | DriverUnload( 21 | IN PDRIVER_OBJECT DriverObject ); 22 | 23 | NTSTATUS 24 | IrpCreate( 25 | IN PDEVICE_OBJECT DeviceObject, 26 | IN PIRP Irp); 27 | 28 | NTSTATUS 29 | IrpClose( 30 | IN PDEVICE_OBJECT DeviceObject, 31 | IN PIRP Irp); 32 | 33 | NTSTATUS 34 | IrpDeviceControl( 35 | IN PDEVICE_OBJECT DeviceObject, 36 | IN PIRP Irp); 37 | 38 | #pragma pack ( pop ) 39 | 40 | #ifdef __cplusplus 41 | }; 42 | #endif 43 | 44 | #endif /* _CHEATDRIVER_H_ */ 45 | -------------------------------------------------------------------------------- /CheatDriver/CheatDriver/CheatDriver.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; CheatDriver.inf 3 | ; 4 | 5 | [Version] 6 | Signature="$WINDOWS NT$" 7 | Class=USBDevice 8 | ClassGuid={88BAE032-5A81-49f0-BC3D-A4FF138216D6} 9 | Provider=%ManufacturerName% 10 | CatalogFile=CheatDriver.cat 11 | DriverVer= 12 | PnpLockDown=1 13 | 14 | [DestinationDirs] 15 | DefaultDestDir = 12 16 | CheatDriver_Device_CoInstaller_CopyFiles = 11 17 | 18 | [SourceDisksNames] 19 | 1 = %DiskName%,,,"" 20 | 21 | [SourceDisksFiles] 22 | CheatDriver.sys = 1,, 23 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1 ; make sure the number matches with SourceDisksNames 24 | 25 | ;***************************************** 26 | ; Install Section 27 | ;***************************************** 28 | 29 | [Manufacturer] 30 | %ManufacturerName%=Standard,NT$ARCH$ 31 | 32 | [Standard.NT$ARCH$] 33 | %CheatDriver.DeviceDesc%=CheatDriver_Device, USB\VID_vvvv&PID_pppp 34 | 35 | [CheatDriver_Device.NT] 36 | CopyFiles=Drivers_Dir 37 | 38 | [Drivers_Dir] 39 | CheatDriver.sys 40 | 41 | [CheatDriver_Device.NT.HW] 42 | AddReg=CheatDriver_AddReg 43 | 44 | [CheatDriver_AddReg] 45 | ; By default, USBDevice class uses iProduct descriptor to name the device in 46 | ; Device Manager on Windows 8 and higher. 47 | ; Uncomment for this device to use %DeviceName% on Windows 8 and higher: 48 | ;HKR,,FriendlyName,,%CheatDriver.DeviceDesc% 49 | 50 | ;-------------- Service installation 51 | [CheatDriver_Device.NT.Services] 52 | AddService = CheatDriver,%SPSVCINST_ASSOCSERVICE%, CheatDriver_Service_Inst 53 | 54 | ; -------------- CheatDriver driver install sections 55 | [CheatDriver_Service_Inst] 56 | DisplayName = %CheatDriver.SVCDESC% 57 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 58 | StartType = 3 ; SERVICE_DEMAND_START 59 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 60 | ServiceBinary = %12%\CheatDriver.sys 61 | 62 | ; 63 | ;--- CheatDriver_Device Coinstaller installation ------ 64 | ; 65 | 66 | [CheatDriver_Device.NT.CoInstallers] 67 | AddReg=CheatDriver_Device_CoInstaller_AddReg 68 | CopyFiles=CheatDriver_Device_CoInstaller_CopyFiles 69 | 70 | [CheatDriver_Device_CoInstaller_AddReg] 71 | HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller" 72 | 73 | [CheatDriver_Device_CoInstaller_CopyFiles] 74 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll 75 | 76 | [CheatDriver_Device.NT.Wdf] 77 | KmdfService = CheatDriver, CheatDriver_wdfsect 78 | [CheatDriver_wdfsect] 79 | KmdfLibraryVersion = $KMDFVERSION$ 80 | 81 | [Strings] 82 | SPSVCINST_ASSOCSERVICE= 0x00000002 83 | ManufacturerName="" ;TODO: Replace with your manufacturer name 84 | ClassName="Universal Serial Bus devices" 85 | DiskName = "CheatDriver Installation Disk" 86 | CheatDriver.DeviceDesc = "CheatDriver Device" 87 | CheatDriver.SVCDESC = "CheatDriver Service" 88 | REG_MULTI_SZ = 0x00010000 89 | -------------------------------------------------------------------------------- /CheatDriver/CheatDriver/CheatDriver.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 | Debug 22 | ARM 23 | 24 | 25 | Release 26 | ARM 27 | 28 | 29 | Debug 30 | ARM64 31 | 32 | 33 | Release 34 | ARM64 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | {D73F86ED-1846-4626-9053-4715375FFB52} 59 | {8c0e3d8b-df43-455b-815a-4a0e72973bc6} 60 | v4.5 61 | 12.0 62 | Debug 63 | Win32 64 | CheatDriver 65 | 66 | 67 | WindowsKernelModeDriver10.0 68 | Driver 69 | KMDF 70 | Universal 71 | 72 | 73 | WindowsKernelModeDriver10.0 74 | Driver 75 | KMDF 76 | Universal 77 | 78 | 79 | WindowsKernelModeDriver10.0 80 | Driver 81 | KMDF 82 | Desktop 83 | 84 | 85 | WindowsKernelModeDriver10.0 86 | Driver 87 | KMDF 88 | Universal 89 | 90 | 91 | WindowsKernelModeDriver10.0 92 | Driver 93 | KMDF 94 | Universal 95 | 96 | 97 | WindowsKernelModeDriver10.0 98 | Driver 99 | KMDF 100 | Universal 101 | 102 | 103 | WindowsKernelModeDriver10.0 104 | Driver 105 | KMDF 106 | Universal 107 | 108 | 109 | WindowsKernelModeDriver10.0 110 | Driver 111 | KMDF 112 | Universal 113 | 114 | 115 | 116 | Windows10 117 | true 118 | 119 | 120 | Windows10 121 | false 122 | 123 | 124 | Windows10 125 | true 126 | 127 | 128 | Windows10 129 | false 130 | 131 | 132 | Windows10 133 | true 134 | false 135 | 136 | 137 | Windows10 138 | false 139 | 140 | 141 | Windows10 142 | true 143 | 144 | 145 | Windows10 146 | false 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | DbgengKernelDebugger 158 | 159 | 160 | DbgengKernelDebugger 161 | 162 | 163 | DbgengKernelDebugger 164 | 165 | 166 | DbgengKernelDebugger 167 | 168 | 169 | DbgengKernelDebugger 170 | 171 | 172 | DbgengKernelDebugger 173 | 174 | 175 | DbgengKernelDebugger 176 | 177 | 178 | DbgengKernelDebugger 179 | 180 | 181 | 182 | true 183 | true 184 | trace.h 185 | true 186 | 187 | 188 | sha256 189 | 190 | 191 | %(AdditionalDependencies);usbdex.lib;ntstrsafe.lib 192 | 193 | 194 | 195 | 196 | true 197 | true 198 | trace.h 199 | true 200 | 201 | 202 | sha256 203 | 204 | 205 | %(AdditionalDependencies);usbdex.lib;ntstrsafe.lib 206 | 207 | 208 | 209 | 210 | false 211 | true 212 | trace.h 213 | true 214 | false 215 | 216 | 217 | sha256 218 | 219 | 220 | %(AdditionalDependencies);usbdex.lib;ntstrsafe.lib;Wdmsec.lib 221 | 222 | 223 | 224 | 225 | true 226 | true 227 | trace.h 228 | true 229 | 230 | 231 | sha256 232 | 233 | 234 | %(AdditionalDependencies);usbdex.lib;ntstrsafe.lib 235 | 236 | 237 | 238 | 239 | true 240 | true 241 | trace.h 242 | true 243 | 244 | 245 | sha256 246 | 247 | 248 | %(AdditionalDependencies);usbdex.lib;ntstrsafe.lib 249 | 250 | 251 | 252 | 253 | true 254 | true 255 | trace.h 256 | true 257 | 258 | 259 | sha256 260 | 261 | 262 | %(AdditionalDependencies);usbdex.lib;ntstrsafe.lib 263 | 264 | 265 | 266 | 267 | true 268 | true 269 | trace.h 270 | true 271 | 272 | 273 | sha256 274 | 275 | 276 | %(AdditionalDependencies);usbdex.lib;ntstrsafe.lib 277 | 278 | 279 | 280 | 281 | true 282 | true 283 | trace.h 284 | true 285 | 286 | 287 | sha256 288 | 289 | 290 | %(AdditionalDependencies);usbdex.lib;ntstrsafe.lib 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | -------------------------------------------------------------------------------- /CheatDriver/CheatDriver/CheatDriver.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;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 | {8E41214B-6785-4CFE-B992-037D68949A14} 18 | inf;inv;inx;mof;mc; 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | Driver Files 27 | 28 | 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 | 47 | 48 | Source Files 49 | 50 | 51 | Source Files 52 | 53 | 54 | Source Files 55 | 56 | 57 | Source Files 58 | 59 | 60 | Source Files 61 | 62 | 63 | -------------------------------------------------------------------------------- /CheatDriver/CheatDriver/CheatDriver_Common.h: -------------------------------------------------------------------------------- 1 | #ifndef _CHEATDRIVER_COMMON_H_ 2 | #define _CHEATDRIVER_COMMON_H_ 3 | 4 | #pragma pack ( push, 8 ) 5 | 6 | #define FILE_DEVICE_CHEATDRIVER 0x00001337 7 | #define CD_SYMBOLIC_LINK_NAME L"\\DosDevices\\Global\\CheatDriver" 8 | #define CD_DEVICE_NAME L"\\Device\\CheatDriver" 9 | #define CD_WIN32_LINK_NAME L"\\??\\CheatDriver" 10 | #define CD_DRIVER_NAME L"CheatDriver" 11 | 12 | //{88BAE032-5A81-49f0-BC3D-A4FF138216D6} 13 | //static const GUID guidProto = { 0x88BAE032, 0x5A81, 0x49f0, { 0xBC, 0x3D, 0xA4, 0xFF, 0x13, 0x82, 0x16, 0xD6 } }; 14 | static const GUID guidProto = { 0xb1133a4, 0xf98e, 0x4029, { 0xac, 0x56, 0xd, 0x1f, 0x35, 0xe, 0xa0, 0xda } }; 15 | 16 | // User requests to read at a specific address of N size chunked buffer 17 | #define IOCTL_CHEATDRIVER_READ \ 18 | (ULONG) CTL_CODE(FILE_DEVICE_CHEATDRIVER, 0x101, METHOD_BUFFERED, \ 19 | FILE_WRITE_ACCESS) 20 | // User sends a buffer to be written at a specific address 21 | // of N size chunked buffer 22 | #define IOCTL_CHEATDRIVER_WRITE \ 23 | (ULONG) CTL_CODE(FILE_DEVICE_CHEATDRIVER, 0x102, METHOD_BUFFERED, \ 24 | FILE_WRITE_ACCESS) 25 | // User selects module to add from list of loaded modules 26 | #define IOCTL_CHEATDRIVER_SELECT \ 27 | (ULONG) CTL_CODE(FILE_DEVICE_CHEATDRIVER, 0x103, METHOD_BUFFERED, \ 28 | FILE_WRITE_ACCESS) 29 | // User sends driver a hook to place 30 | #define IOCTL_CHEATDRIVER_PLACEHOOK \ 31 | (ULONG) CTL_CODE(FILE_DEVICE_CHEATDRIVER, 0x104, METHOD_BUFFERED, \ 32 | FILE_WRITE_ACCESS) 33 | // User asks to list current loaded modules 34 | #define IOCTL_CHEATDRIVER_LISTMODULES \ 35 | (ULONG) CTL_CODE(FILE_DEVICE_CHEATDRIVER, 0x105, METHOD_BUFFERED, \ 36 | FILE_WRITE_ACCESS) 37 | // User asks to list current module hooks 38 | #define IOCTL_CHEATDRIVER_LISTHOOKS \ 39 | (ULONG) CTL_CODE(FILE_DEVICE_CHEATDRIVER, 0x106, METHOD_BUFFERED, \ 40 | FILE_WRITE_ACCESS) 41 | 42 | typedef struct _DEVICE_NAME_STRUCT { 43 | wchar_t symbolicName[255]; 44 | wchar_t deviceName[255]; 45 | wchar_t win32LinkName[255]; 46 | }DEVICE_NAME_STRUCT, * PDEVICE_NAME_STRUCT; 47 | 48 | typedef enum 49 | { 50 | CD_Hook_None = 0, 51 | CD_Hook_Success = 1, 52 | CD_Hook_Fail = 2 53 | } CdHookStatus; 54 | 55 | typedef struct _CD_HOOK_OFFSET_STRUCT { 56 | DWORD64 EntryAddr; // start of func 57 | DWORD64 ReturnAddr; // return address 58 | DWORD64 JumpAddr; 59 | CdHookStatus HookStatus; // if established 60 | BOOLEAN IsCustomHook; 61 | UCHAR CustomHookBuffer[256]; // Assembly data to write 62 | DWORD32 CustomHookLen; 63 | DWORD32 CustomHookAddrOffset; // Offset of custom hookbuffer 64 | } CD_HOOK_OFFSET_STRUCT, * PCD_HOOK_OFFSET_STRUCT; 65 | 66 | typedef struct _CD_HOOK_STRUCT { 67 | DWORD32 ModuleID; 68 | CD_HOOK_OFFSET_STRUCT Hook; 69 | } CD_HOOK_STRUCT, * PCD_HOOK_STRUCT; 70 | 71 | // List of hooks defined by user 72 | typedef struct _CD_HOOK_LIST { 73 | LIST_ENTRY ListEntry; 74 | CD_HOOK_STRUCT HookInfo; 75 | } CD_HOOK_LIST, * PCD_HOOK_LIST; 76 | 77 | typedef struct _CD_MODULE_STRUCT { 78 | DWORD32 ModuleNameLen; 79 | UCHAR ModuleName[256]; 80 | DWORD32 ModuleID; 81 | DWORD64 BaseAddr; 82 | } CD_MODULE_STRUCT, * PCD_MODULE_STRUCT; 83 | 84 | typedef struct _CD_MODULE_LIST { 85 | LIST_ENTRY ListEntry; 86 | CD_MODULE_STRUCT module; 87 | }CD_MODULE_LIST, * PCD_MODULE_LIST; 88 | 89 | typedef struct _CD_MODULE_OUTPUT_STRUCT { 90 | DWORD32 ModuleListSizeInBytes; 91 | DWORD32 NumberOfModules; 92 | UCHAR Modules[1]; // array length is determined by NumberOfModules * ModuleListSize 93 | } CD_MODULE_OUTPUT_STRUCT, * PCD_MODULE_OUTPUT_STRUCT; 94 | 95 | typedef struct _CD_HOOKS_OUTPUT_STRUCT { 96 | DWORD32 HooksListSizeInBytes; 97 | DWORD32 NumberOfHooks; 98 | UCHAR Hooks[1]; // array length is determined by NumberOfHooks * HooksListSizeInBytes 99 | } CD_HOOKS_OUTPUT_STRUCT, * PCD_HOOKS_OUTPUT_STRUCT; 100 | 101 | typedef struct _CD_READ_INPUT { 102 | DWORD64 ReadAddr; 103 | DWORD64 BufferSize; 104 | } CD_READ_INPUT, * PCD_READ_INPUT; 105 | 106 | typedef struct _CD_READ_OUTPUT { 107 | DWORD64 ReadAddr; 108 | DWORD32 BufferSize; 109 | DWORD32 NumChunks; 110 | DWORD32 DataLen; 111 | UCHAR Data[256]; 112 | }; 113 | 114 | typedef struct _CD_WRITE_INPUT { 115 | DWORD64 WriteAddr; 116 | DWORD32 BufferSize; 117 | DWORD32 NumChunks; 118 | DWORD32 DataLen; 119 | UCHAR Data[256]; 120 | }; 121 | 122 | 123 | #pragma pack ( pop ) 124 | 125 | #endif //_CHEATDRIVER_COMMON_H_ 126 | -------------------------------------------------------------------------------- /CheatDriver/CheatDriver/CheatDriver_Globals.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | #pragma pack ( push, 8 ) 5 | #ifdef __cplusplus 6 | extern "C" 7 | { 8 | #endif 9 | 10 | #include "ntifs.h" 11 | #include "CheatDriver_Common.h" 12 | 13 | #ifdef DBG 14 | #define KDebugLog( fmt, ... ) \ 15 | DbgPrint("%s:%u: " fmt, __FILE__, __LINE__, ##__VA_ARGS__) 16 | #else 17 | #define KDebugLog( fmt, ... ) 18 | #endif 19 | 20 | typedef struct _Globals 21 | { 22 | BOOLEAN HandleOpen; 23 | PDRIVER_OBJECT DriverObject; 24 | DEVICE_NAME_STRUCT DeviceName; 25 | KGUARDED_MUTEX ModulesMutex; 26 | KGUARDED_MUTEX HooksMutex; 27 | CD_MODULE_STRUCT SelectedModule; 28 | ULONG ModulesNum; 29 | ULONG HooksNum; 30 | } Globals_Struct, * pGlobals_Struct; 31 | 32 | extern Globals_Struct Globals; 33 | 34 | #ifdef __cplusplus 35 | }; 36 | #endif 37 | #pragma pack ( pop ) 38 | -------------------------------------------------------------------------------- /CheatDriver/CheatDriver/CheatDriver_Hooks.cpp: -------------------------------------------------------------------------------- 1 | #include "CheatDriver_Hooks.h" 2 | #include "CheatDriver_Common.h" 3 | #include "CheatDriver_Globals.h" 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #pragma data_seg("NONPAGE") 11 | 12 | extern "C" 13 | { 14 | LIST_ENTRY gbHooksListHead; 15 | UCHAR JUMP_RAX[] = "\x48\xB8\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xE0"; 16 | UCHAR JUMP_WITH_R14[] = "\x56\x48\xB8\x00\x00\x00\x00\x00\x00\x00\x00\x8f\x00\x90\x90"; 17 | 18 | 19 | NTSTATUS 20 | Hooks_Startup() 21 | { 22 | NTSTATUS Status = STATUS_SUCCESS; 23 | KeInitializeGuardedMutex(&Globals.HooksMutex); 24 | InitializeListHead(&gbHooksListHead); 25 | return Status; 26 | } 27 | 28 | NTSTATUS 29 | Hooks_Cleanup() 30 | { 31 | KeAcquireGuardedMutex(&(Globals.HooksMutex)); 32 | // Empty the list of protected processes 33 | while (!IsListEmpty(&gbHooksListHead)) 34 | { 35 | PCD_HOOK_LIST pEntry = (PCD_HOOK_LIST)gbHooksListHead.Flink; 36 | // Remove the item from the list 37 | RemoveEntryList(&pEntry->ListEntry); 38 | // Free memory 39 | ExFreePoolWithTag(pEntry, 0x414141); 40 | } 41 | Globals.HooksNum = 0; 42 | KeReleaseGuardedMutex(&(Globals.HooksMutex)); 43 | return STATUS_SUCCESS; 44 | } 45 | 46 | NTSTATUS 47 | FillHooksList(void* buffer, DWORD32 buffersize, PULONG pBytesWritten) 48 | { 49 | NTSTATUS Status = STATUS_SUCCESS; 50 | PCD_HOOK_STRUCT pHookContent = NULL; 51 | PCD_HOOKS_OUTPUT_STRUCT outputStruct = NULL; 52 | DWORD32 neededBufferSize = sizeof(CD_HOOKS_OUTPUT_STRUCT); 53 | int i = 0; 54 | 55 | KeAcquireGuardedMutex(&(Globals.HooksMutex)); 56 | neededBufferSize = sizeof(CD_HOOKS_OUTPUT_STRUCT) - sizeof(UCHAR) 57 | + ((Globals.HooksNum) * sizeof(CD_HOOK_STRUCT)); 58 | if (neededBufferSize > buffersize) 59 | { 60 | KeReleaseGuardedMutex(&(Globals.HooksMutex)); 61 | *pBytesWritten = neededBufferSize; 62 | Status = STATUS_INVALID_BUFFER_SIZE; 63 | goto Cleanup; 64 | } 65 | outputStruct = (PCD_HOOKS_OUTPUT_STRUCT)ExAllocatePoolWithTag( 66 | NonPagedPool, neededBufferSize, 0x414141); 67 | if (outputStruct == NULL) 68 | { 69 | KeReleaseGuardedMutex(&(Globals.HooksMutex)); 70 | Status = STATUS_INSUFFICIENT_RESOURCES; 71 | goto Cleanup; 72 | } 73 | RtlZeroMemory(outputStruct, neededBufferSize); 74 | outputStruct->HooksListSizeInBytes = sizeof(CD_HOOK_STRUCT); 75 | outputStruct->NumberOfHooks = Globals.HooksNum; 76 | // Loop through list and append 77 | 78 | for (LIST_ENTRY* pEntry = gbHooksListHead.Flink; pEntry != &gbHooksListHead; pEntry = pEntry->Flink) 79 | { 80 | PCD_HOOK_LIST pCurrentEntry = (PCD_HOOK_LIST)pEntry; 81 | pHookContent = (PCD_HOOK_STRUCT)(outputStruct->Hooks + (i * outputStruct->HooksListSizeInBytes)); 82 | RtlCopyBytes(pHookContent, &pCurrentEntry->HookInfo, sizeof(CD_HOOK_STRUCT)); 83 | i++; 84 | } 85 | KeReleaseGuardedMutex(&(Globals.HooksMutex)); 86 | RtlCopyBytes(buffer, outputStruct, neededBufferSize); 87 | *pBytesWritten = neededBufferSize; 88 | Status = STATUS_SUCCESS; 89 | Cleanup: 90 | if (NULL != outputStruct) 91 | { 92 | ExFreePoolWithTag(outputStruct, 0x414141); 93 | } 94 | return Status; 95 | } 96 | 97 | NTSTATUS 98 | InsertHook(void* buffer, DWORD32 buffersize, PULONG pBytesWritten) 99 | { 100 | NTSTATUS Status = STATUS_SUCCESS; 101 | PCD_HOOK_LIST pNewEntry = NULL; 102 | PCD_HOOK_STRUCT pUserHookContent = NULL; 103 | if (buffersize < sizeof(CD_HOOK_STRUCT)) 104 | { 105 | Status = STATUS_INVALID_PARAMETER; 106 | goto Cleanup; 107 | } 108 | pNewEntry = (PCD_HOOK_LIST)ExAllocatePoolWithTag( 109 | NonPagedPool, sizeof(CD_HOOK_LIST), 0x414141); 110 | if (NULL == pNewEntry) 111 | { 112 | Status = STATUS_INSUFFICIENT_RESOURCES; 113 | goto Cleanup; 114 | } 115 | RtlCopyMemory(&pNewEntry->HookInfo, buffer, sizeof(CD_HOOK_STRUCT)); 116 | pNewEntry->HookInfo.ModuleID = Globals.SelectedModule.ModuleID; 117 | KeAcquireGuardedMutex(&(Globals.HooksMutex)); 118 | Globals.HooksNum++; 119 | // TODO: Call to Set Hook 120 | // SetHook(&(pNewEntry->HookInfo)); 121 | InsertHeadList(&gbHooksListHead, &pNewEntry->ListEntry); 122 | KeReleaseGuardedMutex(&(Globals.HooksMutex)); 123 | 124 | Cleanup: 125 | return Status; 126 | } 127 | 128 | NTSTATUS SetHook(PCD_HOOK_STRUCT hookEntry) 129 | { 130 | NTSTATUS Status = STATUS_SUCCESS; 131 | PVOID64 OriginalAddress = (PVOID64)(hookEntry->Hook.EntryAddr); 132 | PVOID64 JmpToAddress = (PVOID64)(hookEntry->Hook.JumpAddr); // Destination 133 | DWORD32 AddrOffset = hookEntry->Hook.CustomHookAddrOffset; 134 | PUCHAR HookBuffer = hookEntry->Hook.CustomHookBuffer; 135 | DWORD32 HookLen = hookEntry->Hook.CustomHookLen; 136 | 137 | if (NULL == hookEntry) 138 | { 139 | Status = STATUS_INVALID_PARAMETER; 140 | goto Cleanup; 141 | } 142 | KIRQL tempIRQL = disableWP(); 143 | RtlCopyMemory(HookBuffer + AddrOffset, &JmpToAddress, sizeof(PVOID64)); 144 | RtlCopyMemory((PVOID64)OriginalAddress, HookBuffer, HookLen); 145 | enableWP(tempIRQL); 146 | Cleanup: 147 | return Status; 148 | } 149 | 150 | KIRQL disableWP() 151 | { 152 | KIRQL tempirql = KeRaiseIrqlToDpcLevel(); 153 | ULONG64 cr0 = __readcr0(); 154 | cr0 &= 0xfffffffffffeffff; 155 | __writecr0(cr0); 156 | _disable(); 157 | return tempirql; 158 | } 159 | 160 | void enableWP(KIRQL tempirql) 161 | { 162 | ULONG64 cr0 = __readcr0(); 163 | cr0 |= 0x10000; 164 | _enable(); 165 | __writecr0(cr0); 166 | KeLowerIrql(tempirql); 167 | } 168 | 169 | #pragma optimize("", off) 170 | void HookedIoctl() 171 | { 172 | 173 | int a1 = 1; 174 | int a2 = 1; 175 | int a3 = 1; // 32 free bytes 176 | int a4 = 1; 177 | // DOSTUFF(); 178 | int a5 = 1; 179 | int a6 = 1; // 32 free bytes 180 | int a7 = 1; 181 | int a8 = 1; 182 | } 183 | #pragma optimize("", on) 184 | 185 | 186 | } -------------------------------------------------------------------------------- /CheatDriver/CheatDriver/CheatDriver_Hooks.h: -------------------------------------------------------------------------------- 1 | #ifndef _CHEATDRIVER_HOOKS_H_ 2 | #define _CHEATDRIVER_HOOKS_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" 6 | { 7 | #endif 8 | 9 | #include "ntifs.h" 10 | #include "CheatDriver_Common.h" 11 | 12 | #pragma pack ( push, 8 ) 13 | NTSTATUS 14 | Hooks_Startup(); 15 | NTSTATUS 16 | Hooks_Cleanup(); 17 | 18 | NTSTATUS 19 | FillHooksList(void* buffer, DWORD32 buffersize, PULONG pBytesWritten); 20 | NTSTATUS 21 | InsertHook(void* buffer, DWORD32 buffersize, PULONG pBytesWritten); 22 | 23 | // TODO 24 | void HookedIoctl(); 25 | 26 | KIRQL disableWP(); 27 | 28 | void enableWP(KIRQL tempirql); 29 | 30 | NTSTATUS SetHook(PCD_HOOK_STRUCT hookEntry); 31 | 32 | #pragma pack ( pop ) 33 | 34 | #ifdef __cplusplus 35 | }; 36 | #endif 37 | 38 | #endif /* _CHEATDRIVER_HOOKS_H_ */ 39 | -------------------------------------------------------------------------------- /CheatDriver/CheatDriver/CheatDriver_Modules.cpp: -------------------------------------------------------------------------------- 1 | #include "CheatDriver_Modules.h" 2 | #include "CheatDriver_Common.h" 3 | #include "CheatDriver_Globals.h" 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #pragma data_seg("NONPAGE") 10 | 11 | extern "C" 12 | { 13 | 14 | LIST_ENTRY gbModuleListHead; 15 | 16 | NTSTATUS 17 | Module_Startup() 18 | { 19 | NTSTATUS Status = STATUS_SUCCESS; 20 | KeInitializeGuardedMutex(&(Globals.ModulesMutex)); 21 | InitializeListHead(&gbModuleListHead); 22 | return Status; 23 | } 24 | NTSTATUS 25 | Module_Cleanup() 26 | { 27 | KeAcquireGuardedMutex(&(Globals.ModulesMutex)); 28 | // Empty the list of protected processes 29 | while (!IsListEmpty(&gbModuleListHead)) 30 | { 31 | PCD_MODULE_LIST pEntry = (PCD_MODULE_LIST)gbModuleListHead.Flink; 32 | // Remove the item from the books 33 | RemoveEntryList(&pEntry->ListEntry); 34 | // Free memory 35 | ExFreePoolWithTag(pEntry, 0x414141); 36 | } 37 | Globals.ModulesNum = 0; 38 | KeReleaseGuardedMutex(&(Globals.ModulesMutex)); 39 | return STATUS_SUCCESS; 40 | } 41 | 42 | 43 | NTSTATUS FillModuleListBuffer( 44 | void* buffer, DWORD32 buffersize, PULONG pBytesWritten) 45 | { 46 | NTSTATUS Status = STATUS_SUCCESS; 47 | PCD_MODULE_STRUCT pModuleContent = NULL; 48 | PCD_MODULE_OUTPUT_STRUCT outputStruct = NULL; 49 | DWORD32 alertCount = 0; 50 | DWORD32 neededBufferSize = sizeof(CD_MODULE_OUTPUT_STRUCT); 51 | int i = 0; 52 | 53 | Status = FillModulesList(); 54 | if (!NT_SUCCESS(Status)) 55 | { 56 | goto Cleanup; 57 | } 58 | KeAcquireGuardedMutex(&(Globals.ModulesMutex)); 59 | neededBufferSize = sizeof(CD_MODULE_OUTPUT_STRUCT) - sizeof(UCHAR) 60 | + ((Globals.ModulesNum) * sizeof(CD_MODULE_STRUCT)); 61 | 62 | if (neededBufferSize > buffersize) 63 | { 64 | KeReleaseGuardedMutex(&(Globals.ModulesMutex)); 65 | *pBytesWritten = neededBufferSize; 66 | Status = STATUS_INVALID_BUFFER_SIZE; 67 | goto Cleanup; 68 | } 69 | outputStruct = (PCD_MODULE_OUTPUT_STRUCT)ExAllocatePoolWithTag( 70 | NonPagedPool, neededBufferSize, 0x414141); 71 | if (outputStruct == NULL) 72 | { 73 | KeReleaseGuardedMutex(&(Globals.ModulesMutex)); 74 | Status = STATUS_INSUFFICIENT_RESOURCES; 75 | goto Cleanup; 76 | } 77 | RtlZeroMemory(outputStruct, neededBufferSize); 78 | outputStruct->ModuleListSizeInBytes = sizeof(CD_MODULE_STRUCT); 79 | outputStruct->NumberOfModules = Globals.ModulesNum; 80 | // Loop through list and append 81 | for (LIST_ENTRY* pEntry = gbModuleListHead.Flink; pEntry != &gbModuleListHead; pEntry = pEntry->Flink) 82 | { 83 | PCD_MODULE_LIST pCurrentEntry = (PCD_MODULE_LIST)pEntry; 84 | // KDebugLog("Baseaddr: %0x%X\n", (DWORD64)(pCurrentEntry->module.BaseAddr)); 85 | // KDebugLog("Name: %s\n", pCurrentEntry->module.ModuleName); 86 | pModuleContent = (PCD_MODULE_STRUCT)(outputStruct->Modules + (i * outputStruct->ModuleListSizeInBytes)); 87 | RtlCopyBytes(pModuleContent, &pCurrentEntry->module, sizeof(CD_MODULE_STRUCT)); 88 | i++; 89 | } 90 | KeReleaseGuardedMutex(&(Globals.ModulesMutex)); 91 | RtlCopyBytes(buffer, outputStruct, neededBufferSize); 92 | *pBytesWritten = neededBufferSize; 93 | Status = STATUS_SUCCESS; 94 | Cleanup: 95 | if (NULL != outputStruct) 96 | { 97 | ExFreePoolWithTag(outputStruct, 0x414141); 98 | } 99 | return Status; 100 | } 101 | 102 | NTSTATUS FillModulesList() 103 | { 104 | NTSTATUS Status = STATUS_SUCCESS; 105 | ULONG nSize = 0; 106 | PRTL_PROCESS_MODULES moduleArray; 107 | PCD_MODULE_LIST pCurrentHead = NULL; 108 | 109 | moduleArray = GetModuleList(&nSize); 110 | if (!moduleArray) 111 | { 112 | goto Cleanup; 113 | } 114 | // Clear the list 115 | Module_Cleanup(); 116 | InitializeListHead(&gbModuleListHead); 117 | // Fill the list 118 | KeAcquireGuardedMutex(&(Globals.ModulesMutex)); 119 | PRTL_PROCESS_MODULE_INFORMATION moduleInfo = moduleArray->Modules; 120 | for (int i = 0; i < moduleArray->NumberOfModules; ++i) 121 | { 122 | PCD_MODULE_LIST pNewEntry = NULL; 123 | pNewEntry = (PCD_MODULE_LIST)ExAllocatePoolWithTag( 124 | NonPagedPool, sizeof(CD_MODULE_LIST), 0x414141); 125 | if (NULL == pNewEntry) 126 | { 127 | Status = STATUS_INSUFFICIENT_RESOURCES; 128 | KeReleaseGuardedMutex(&(Globals.ModulesMutex)); 129 | goto Cleanup; 130 | } 131 | PVOID kernelImageBase = moduleInfo[i].ImageBase; 132 | PCHAR kernelImage = (PCHAR)moduleInfo[i].FullPathName; 133 | 134 | RtlCopyMemory(pNewEntry->module.ModuleName, kernelImage, 256); 135 | pNewEntry->module.BaseAddr = (DWORD64)kernelImageBase; 136 | pNewEntry->module.ModuleID = (DWORD32)Globals.ModulesNum; 137 | Globals.ModulesNum++; 138 | InsertHeadList(&gbModuleListHead, &pNewEntry->ListEntry); 139 | } 140 | KeReleaseGuardedMutex(&(Globals.ModulesMutex)); 141 | Cleanup: 142 | if (moduleArray) 143 | { 144 | ExFreePoolWithTag(moduleArray, 0x414141); 145 | } 146 | return Status; 147 | } 148 | 149 | 150 | PRTL_PROCESS_MODULES GetModuleList( 151 | OUT PULONG nSize 152 | ) 153 | { 154 | NTSTATUS status = STATUS_SUCCESS; 155 | PVOID buffer = NULL; 156 | UNICODE_STRING funcName; 157 | KdPrint(("Entering GetModuleList\n")); 158 | // Get ZwQuerySystemInformation Function 159 | RtlUnicodeStringInit(&funcName, L"ZwQuerySystemInformation"); 160 | FUNC_ZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation = (FUNC_ZWQUERYSYSTEMINFORMATION)MmGetSystemRoutineAddress(&funcName); 161 | if (NULL == ZwQuerySystemInformation) 162 | { 163 | status = STATUS_NOT_FOUND; 164 | goto Cleanup; 165 | } 166 | KdPrint(("Entering ZwQuerySystemInformation\n")); 167 | status = ZwQuerySystemInformation(SystemModuleInformation, NULL, 0, nSize); 168 | if (status == STATUS_INFO_LENGTH_MISMATCH) 169 | { 170 | buffer = ExAllocatePoolWithTag(NonPagedPool, *nSize, 0x414141); 171 | status = ZwQuerySystemInformation(SystemModuleInformation, buffer, *nSize, NULL); 172 | if (NT_SUCCESS(status)) 173 | { 174 | return (PRTL_PROCESS_MODULES)buffer; 175 | } 176 | } 177 | 178 | Cleanup: 179 | return (PRTL_PROCESS_MODULES)0; 180 | } 181 | 182 | NTSTATUS SelectModule( 183 | DWORD32 moduleID, void* buffer, DWORD32 buffersize, PULONG pBytesWritten) 184 | { 185 | NTSTATUS Status = STATUS_SUCCESS; 186 | DWORD32 neededBufferSize = sizeof(CD_MODULE_STRUCT); 187 | KeAcquireGuardedMutex(&(Globals.ModulesMutex)); 188 | for (LIST_ENTRY* pEntry = gbModuleListHead.Flink; pEntry != &gbModuleListHead; pEntry = pEntry->Flink) 189 | { 190 | PCD_MODULE_LIST pCurrentEntry = (PCD_MODULE_LIST)pEntry; 191 | if (pCurrentEntry->module.ModuleID == moduleID) 192 | { 193 | Globals.SelectedModule.BaseAddr = pCurrentEntry->module.BaseAddr; 194 | Globals.SelectedModule.ModuleID = pCurrentEntry->module.ModuleID; 195 | RtlCopyMemory(&(Globals.SelectedModule.ModuleName), pCurrentEntry->module.ModuleName, 256); 196 | Globals.SelectedModule.ModuleNameLen = pCurrentEntry->module.ModuleNameLen; 197 | break; 198 | } 199 | } 200 | KeReleaseGuardedMutex(&(Globals.ModulesMutex)); 201 | RtlCopyBytes(buffer, &(Globals.SelectedModule), neededBufferSize); 202 | *pBytesWritten = neededBufferSize; 203 | return Status; 204 | } 205 | 206 | 207 | } -------------------------------------------------------------------------------- /CheatDriver/CheatDriver/CheatDriver_Modules.h: -------------------------------------------------------------------------------- 1 | #ifndef _CHEATDRIVER_MODULES_H_ 2 | #define _CHEATDRIVER_MODULES_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" 6 | { 7 | #endif 8 | 9 | #include "ntifs.h" 10 | 11 | #pragma pack ( push, 8 ) 12 | 13 | typedef enum _SYSTEM_INFORMATION_CLASS 14 | { 15 | SystemBasicInformation = 0, 16 | SystemProcessorInformation = 1, 17 | SystemPerformanceInformation = 2, 18 | SystemTimeOfDayInformation = 3, 19 | SystemPathInformation = 4, 20 | SystemProcessInformation = 5, 21 | SystemCallCountInformation = 6, 22 | SystemDeviceInformation = 7, 23 | SystemProcessorPerformanceInformation = 8, 24 | SystemFlagsInformation = 9, 25 | SystemCallTimeInformation = 10, 26 | SystemModuleInformation = 11, 27 | SystemLocksInformation = 12, 28 | SystemStackTraceInformation = 13, 29 | SystemPagedPoolInformation = 14, 30 | SystemNonPagedPoolInformation = 15, 31 | SystemHandleInformation = 16, 32 | SystemObjectInformation = 17, 33 | SystemPageFileInformation = 18, 34 | SystemVdmInstemulInformation = 19, 35 | SystemVdmBopInformation = 20, 36 | SystemFileCacheInformation = 21, 37 | SystemPoolTagInformation = 22, 38 | SystemInterruptInformation = 23, 39 | SystemDpcBehaviorInformation = 24, 40 | SystemFullMemoryInformation = 25, 41 | SystemLoadGdiDriverInformation = 26, 42 | SystemUnloadGdiDriverInformation = 27, 43 | SystemTimeAdjustmentInformation = 28, 44 | SystemSummaryMemoryInformation = 29, 45 | SystemMirrorMemoryInformation = 30, 46 | SystemPerformanceTraceInformation = 31, 47 | SystemObsolete0 = 32, 48 | SystemExceptionInformation = 33, 49 | SystemCrashDumpStateInformation = 34, 50 | SystemKernelDebuggerInformation = 35, 51 | SystemContextSwitchInformation = 36, 52 | SystemRegistryQuotaInformation = 37, 53 | SystemExtendServiceTableInformation = 38, 54 | SystemPrioritySeperation = 39, 55 | SystemVerifierAddDriverInformation = 40, 56 | SystemVerifierRemoveDriverInformation = 41, 57 | SystemProcessorIdleInformation = 42, 58 | SystemLegacyDriverInformation = 43, 59 | SystemCurrentTimeZoneInformation = 44, 60 | SystemLookasideInformation = 45, 61 | SystemTimeSlipNotification = 46, 62 | SystemSessionCreate = 47, 63 | SystemSessionDetach = 48, 64 | SystemSessionInformation = 49, 65 | SystemRangeStartInformation = 50, 66 | SystemVerifierInformation = 51, 67 | SystemVerifierThunkExtend = 52, 68 | SystemSessionProcessInformation = 53, 69 | SystemLoadGdiDriverInSystemSpace = 54, 70 | SystemNumaProcessorMap = 55, 71 | SystemPrefetcherInformation = 56, 72 | SystemExtendedProcessInformation = 57, 73 | SystemRecommendedSharedDataAlignment = 58, 74 | SystemComPlusPackage = 59, 75 | SystemNumaAvailableMemory = 60, 76 | SystemProcessorPowerInformation = 61, 77 | SystemEmulationBasicInformation = 62, 78 | SystemEmulationProcessorInformation = 63, 79 | SystemExtendedHandleInformation = 64, 80 | SystemLostDelayedWriteInformation = 65, 81 | SystemBigPoolInformation = 66, 82 | SystemSessionPoolTagInformation = 67, 83 | SystemSessionMappedViewInformation = 68, 84 | SystemHotpatchInformation = 69, 85 | SystemObjectSecurityMode = 70, 86 | SystemWatchdogTimerHandler = 71, 87 | SystemWatchdogTimerInformation = 72, 88 | SystemLogicalProcessorInformation = 73, 89 | SystemWow64SharedInformation = 74, 90 | SystemRegisterFirmwareTableInformationHandler = 75, 91 | SystemFirmwareTableInformation = 76, 92 | SystemModuleInformationEx = 77, 93 | SystemVerifierTriageInformation = 78, 94 | SystemSuperfetchInformation = 79, 95 | SystemMemoryListInformation = 80, 96 | SystemFileCacheInformationEx = 81, 97 | MaxSystemInfoClass = 82 // MaxSystemInfoClass should always be the last enum 98 | 99 | } SYSTEM_INFORMATION_CLASS; 100 | 101 | typedef NTSTATUS(__stdcall* FUNC_ZWQUERYSYSTEMINFORMATION)( 102 | IN ULONG aSystemInformationClass, 103 | IN OUT PVOID aSystemInformation, 104 | IN ULONG aSystemInformationLength, 105 | OPTIONAL OUT PULONG aReturnLength); 106 | 107 | typedef struct _RTL_PROCESS_MODULE_INFORMATION 108 | { 109 | HANDLE Section; 110 | PVOID MappedBase; 111 | PVOID ImageBase; 112 | ULONG ImageSize; 113 | ULONG Flags; 114 | USHORT LoadOrderIndex; 115 | USHORT InitOrderIndex; 116 | USHORT LoadCount; 117 | USHORT OffsetToFileName; 118 | UCHAR FullPathName[256]; 119 | } RTL_PROCESS_MODULE_INFORMATION, * PRTL_PROCESS_MODULE_INFORMATION; 120 | 121 | typedef struct _RTL_PROCESS_MODULES 122 | { 123 | ULONG NumberOfModules; 124 | RTL_PROCESS_MODULE_INFORMATION Modules[1]; 125 | } RTL_PROCESS_MODULES, * PRTL_PROCESS_MODULES; 126 | 127 | // List Modules 128 | NTSTATUS FillModuleListBuffer( 129 | void* buffer, DWORD32 buffersize, PULONG pBytesWritten); 130 | NTSTATUS FillModulesList(); 131 | 132 | PRTL_PROCESS_MODULES GetModuleList( 133 | OUT PULONG nSize 134 | ); 135 | 136 | NTSTATUS 137 | Module_Startup(); 138 | 139 | NTSTATUS Module_Cleanup(); 140 | 141 | // Select Module 142 | NTSTATUS SelectModule( 143 | DWORD32 moduleID, void* buffer, DWORD32 buffersize, PULONG pBytesWritten); 144 | 145 | #pragma pack ( pop ) 146 | 147 | #ifdef __cplusplus 148 | }; 149 | #endif 150 | 151 | #endif /* _CHEATDRIVER_MODULES_H_ */ 152 | -------------------------------------------------------------------------------- /CheatDriver/CheatDriver/CheatDriver_ReadWrite.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malware-unicorn/pteroioctl-hook/890a6a7848d1f3eba4ff6b0e6b94c4515d021fda/CheatDriver/CheatDriver/CheatDriver_ReadWrite.cpp -------------------------------------------------------------------------------- /CheatDriver/CheatDriver/CheatDriver_Utils.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malware-unicorn/pteroioctl-hook/890a6a7848d1f3eba4ff6b0e6b94c4515d021fda/CheatDriver/CheatDriver/CheatDriver_Utils.cpp -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 malwareunicorn 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pteroioctl-hook 2 | A driver to implement IOCTL hooking 3 | 4 | Warning: In progress 5 | 6 | ``` 7 | <\ _ 8 | \\ _/{ 9 | _ \\ _- -_ 10 | /{ / `\ _- - -_ 11 | _~ = ( @ \ - - -_ 12 | _- - ~-_ \( =\ \ - -_ 13 | _~ - ~_ | 1 :\ \ _-~-_ - -_ 14 | _- - ~ |V: \ \ _-~ ~-_- -_ 15 | _-~ - / | : \ \ ~-_- -_ 16 | _-~ - _.._ { | : _-`` ~- _-_ 17 | _-~ -__..--~ ~-_ { : \:} 18 | =~__.--~~ ~-_\ : / 19 | \ : /__ 20 | //`Y'--\\ = IOCTL 21 | <+ \\ 22 | \\ WWW 23 | MMM 24 | ``` 25 | 26 | ### Loading 27 | ``` 28 | CheatController.exe -load 29 | ``` 30 | 31 | ### Options 32 | ``` 33 | >>>> Cheat Console: 34 | 35 | 1 List Modules 36 | 2 Select Module 37 | 3 List Hooks 38 | 4 Place Hook (Inserts Into list, TODO: set hook) 39 | 5 Kernel Memory Read (TODO) 40 | 6 Kernel Memory Write (TODO) 41 | 42 | 0 Exit 43 | ``` 44 | 45 | ## Features 46 | 1) Search for existing modules 47 | 2) Select module by ID 48 | 3) List Hooks 49 | 4) Add a new hook to the selected module (TODO: Implment control for hook) 50 | 5) TODO: read memory 51 | 6) TODO: write memory 52 | 53 | ## Testing 54 | Tested on Windows 10 build 17763.rs5 with TestSigning On 55 | ``` 56 | bcdedit /set testsigning on 57 | ``` 58 | Adding cert command 59 | ``` 60 | certmgr.exe /add CheatDriver.cer /s /r localMachine root 61 | ``` 62 | 63 | ## Customizing Hooks 64 | Uses a generic hook structure to instrument a jmp 65 | ``` 66 | typedef struct _CD_HOOK_OFFSET_STRUCT { 67 | DWORD64 EntryAddr; // start of func 68 | DWORD64 ReturnAddr; // return address 69 | DWORD64 JumpAddr; 70 | CdHookStatus HookStatus; // if established 71 | BOOLEAN IsCustomHook; 72 | UCHAR CustomHookBuffer[256]; // Assembly data to write 73 | DWORD32 CustomHookLen; 74 | DWORD32 CustomHookAddrOffset; // Offset of custom hookbuffer 75 | } CD_HOOK_OFFSET_STRUCT, * PCD_HOOK_OFFSET_STRUCT; 76 | ``` 77 | 78 | Example Usage: 79 | ``` 80 | CD_HOOK_STRUCT newHook = { }; 81 | UCHAR JUMP_RAX[] = "\x48\xB8\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xE0"; 82 | 83 | // This is a test, address are dummy addresses 84 | newHook.Hook.EntryAddr = 0x1234; // This should be physical address not an offset 85 | newHook.Hook.JumpAddr = 0x4567; // This should be physical address not an offset 86 | newHook.Hook.ReturnAddr = 0x9123; // This should be physical address not an offset 87 | newHook.Hook.IsCustomHook = TRUE; 88 | memcpy(newHook.Hook.CustomHookBuffer, JUMP_RAX, sizeof(JUMP_RAX)); 89 | newHook.Hook.CustomHookLen = sizeof(JUMP_RAX); 90 | newHook.Hook.CustomHookAddrOffset = 2; 91 | ``` 92 | 93 | --------------------------------------------------------------------------------