├── .gitignore ├── Trashcomm ├── Communication.cpp ├── Trashcomm.vcxproj ├── Trashcomm.vcxproj.filters └── Trashcomm.vcxproj.user ├── Trashvisor.sln └── Trashvisor ├── ArchUtils.c ├── ArchUtils.h ├── ControlCallbacks.c ├── ControlCallbacks.h ├── Ept.c ├── Ept.h ├── Extern.h ├── Intrinsics.asm ├── Shared.h ├── Trashvisor.c ├── Trashvisor.inf ├── Trashvisor.vcxproj ├── Trashvisor.vcxproj.filters ├── Trashvisor.vcxproj.user ├── Vmcs.c ├── Vmcs.h ├── VmxAsm.asm ├── VmxCore.c ├── VmxCore.h ├── VmxHost.c ├── VmxHost.h ├── VmxHostExitHandlers.c ├── VmxUtils.c └── VmxUtils.h /.gitignore: -------------------------------------------------------------------------------- 1 | *x64* 2 | *x86* 3 | .vs/* 4 | *.exe 5 | *.sys 6 | -------------------------------------------------------------------------------- /Trashcomm/Communication.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../Trashvisor/Shared.h" 3 | #include 4 | #include 5 | #include 6 | 7 | DWORD 8 | GetPidByName ( 9 | const wchar_t* ProcessName 10 | ) 11 | { 12 | auto Snapshot = CreateToolhelp32Snapshot( 13 | TH32CS_SNAPPROCESS, 14 | NULL 15 | ); 16 | 17 | PROCESSENTRY32 ProcEntry; 18 | ProcEntry.dwSize = sizeof(ProcEntry); 19 | Process32First(Snapshot, &ProcEntry); 20 | 21 | do 22 | { 23 | if (lstrcmpW(ProcEntry.szExeFile, ProcessName) == 0) 24 | { 25 | return ProcEntry.th32ProcessID; 26 | } 27 | } while (Process32Next(Snapshot, &ProcEntry)); 28 | 29 | return -1; 30 | } 31 | 32 | UINT64 33 | AddEptHook ( 34 | ) 35 | { 36 | // Search through all processes 37 | auto Pid = GetPidByName(L"minigamz.exe"); 38 | //auto Pid = GetPidByName(L"Project1.exe"); 39 | 40 | if (Pid == -1) 41 | { 42 | std::cout << "Could not find pid for name" << std::endl; 43 | return 0; 44 | } 45 | 46 | INFO_IOCTL_EPT_HOOK_INFO EptHookInfo; 47 | EptHookInfo.ProcessId = Pid; 48 | 49 | std::cout << "Pid: " << Pid << std::endl; 50 | 51 | auto ProcessHandle = OpenProcess( 52 | PROCESS_ALL_ACCESS, 53 | FALSE, 54 | Pid 55 | ); 56 | 57 | if (ProcessHandle == NULL) 58 | { 59 | std::cout << "Could not open process" << std::endl; 60 | return 0; 61 | } 62 | 63 | DWORD SizeNeeded; 64 | HMODULE Modules[50]; 65 | 66 | auto AcquiredModules = EnumProcessModules( 67 | ProcessHandle, 68 | Modules, 69 | sizeof Modules, 70 | &SizeNeeded 71 | ); 72 | 73 | if (!AcquiredModules) 74 | { 75 | std::cout << "Could not acquire modules" << std::endl; 76 | return 0; 77 | } 78 | 79 | if (SizeNeeded > sizeof Modules) 80 | { 81 | std::cout << "Size needed: " << SizeNeeded << std::endl; 82 | return 0; 83 | } 84 | 85 | auto AcquiredCount = SizeNeeded / sizeof HMODULE; 86 | std::cout << "Successfully acquired " << AcquiredCount << " modules" << std::endl; 87 | 88 | UINT64 ModuleAddress = 0; 89 | 90 | for (int i = 0; i < AcquiredCount; i++) 91 | { 92 | const auto& Module = Modules[i]; 93 | PCHAR ImageStart = 0; 94 | 95 | RtlCopyMemory( 96 | &ImageStart, 97 | &Module, 98 | sizeof Module 99 | ); 100 | 101 | std::cout << "Module at: 0x" << std::hex << reinterpret_cast(ImageStart) << std::endl; 102 | 103 | CHAR Buffer[4]; 104 | SIZE_T SizeRead = 0; 105 | 106 | auto ReadSuccess = ReadProcessMemory( 107 | ProcessHandle, 108 | ImageStart + 0x1000, 109 | Buffer, 110 | sizeof Buffer, 111 | &SizeRead 112 | ); 113 | 114 | if (!ReadSuccess) 115 | { 116 | std::cout << "ReadProcessMemory failed with: 0x" << std::hex << GetLastError() << std::endl; 117 | return 0; 118 | } 119 | 120 | if (RtlCompareMemory(Buffer, "\x22\x05\x93\x19", 4) == 4) 121 | //if (RtlCompareMemory(Buffer, "\x48\x83\xEC\x28", 4) == 4) 122 | { 123 | std::cout << "Found minigamz.exe module at 0x" << std::hex << reinterpret_cast(Module) << std::endl; 124 | 125 | RtlCopyMemory( 126 | &ModuleAddress, 127 | &Module, 128 | sizeof ModuleAddress 129 | ); 130 | 131 | break; 132 | } 133 | } 134 | 135 | if (ModuleAddress == 0) 136 | { 137 | std::cout << "Could not find minigamz.exe module" << std::endl; 138 | return 0; 139 | } 140 | 141 | PCHAR pModuleAddress = 0; 142 | 143 | ModuleAddress = (ModuleAddress + 0x5000) & ~0xfffULL; 144 | //ModuleAddress = (ModuleAddress + 0x1F23) & ~0xfffULL; 145 | 146 | std::cout << "Aligned address: 0x" << std::hex << ModuleAddress << std::endl; 147 | 148 | RtlCopyMemory( 149 | &pModuleAddress, 150 | &ModuleAddress, 151 | sizeof pModuleAddress 152 | ); 153 | 154 | SIZE_T BytesRead = 0; 155 | 156 | auto ReadSuccess = ReadProcessMemory( 157 | ProcessHandle, 158 | pModuleAddress, 159 | EptHookInfo.ModifiedPage, 160 | sizeof EptHookInfo.ModifiedPage, 161 | &BytesRead 162 | ); 163 | 164 | 165 | if (!ReadSuccess) 166 | { 167 | std::cout << "ReadProcessMemory failed on page: 0x" << std::hex << pModuleAddress << std::endl; 168 | return 0; 169 | } 170 | 171 | std::cout << "Modified page value 1: 0x" << std::hex << ((int)EptHookInfo.ModifiedPage[0] & 0xff) << std::endl; 172 | 173 | EptHookInfo.ModifiedPage[0x9ca] = 0; 174 | EptHookInfo.ModifiedPage[0x9cb] = 0; 175 | EptHookInfo.ModifiedPage[0x9cc] = 0; 176 | EptHookInfo.ModifiedPage[0x9cd] = 0; 177 | 178 | EptHookInfo.ModifiedPage[0x9d1] = 0; 179 | EptHookInfo.ModifiedPage[0x9d2] = 0; 180 | EptHookInfo.ModifiedPage[0x9d3] = 0; 181 | EptHookInfo.ModifiedPage[0x9d4] = 0; 182 | 183 | //EptHookInfo.ModifiedPage[0xf48] = 0x44; 184 | 185 | RtlCopyMemory( 186 | &EptHookInfo.VirtualAddress, 187 | &pModuleAddress, 188 | sizeof EptHookInfo.VirtualAddress 189 | ); 190 | 191 | auto DeviceHandle = CreateFileW( 192 | WIN32_DEVICE_NAME, 193 | GENERIC_READ | GENERIC_WRITE, 194 | 0, 195 | nullptr, 196 | OPEN_EXISTING, 197 | FILE_ATTRIBUTE_NORMAL, 198 | nullptr 199 | ); 200 | 201 | if (DeviceHandle == INVALID_HANDLE_VALUE) 202 | { 203 | std::cout << "Could not open a handle to " << WIN32_DEVICE_NAME << std::endl; 204 | return 0; 205 | } 206 | 207 | DWORD BytesReturned = 0; 208 | 209 | Sleep(1000); 210 | 211 | auto IoCtrlStatus = DeviceIoControl( 212 | DeviceHandle, 213 | IOCTL_ADD_EPT_HOOK, 214 | &EptHookInfo, 215 | sizeof EptHookInfo, 216 | nullptr, 217 | 0, 218 | &BytesReturned, 219 | nullptr 220 | ); 221 | 222 | if (!IoCtrlStatus) 223 | { 224 | std::cout << "DeviceIoControl failed with error: 0x" << std::hex << GetLastError() << std::endl; 225 | return 0; 226 | } 227 | 228 | return 1; 229 | } 230 | 231 | UINT64 232 | AddEptHook2 ( 233 | ) 234 | { 235 | // Search through all processes 236 | auto Pid = GetPidByName(L"minigamz.exe"); 237 | //auto Pid = GetPidByName(L"Project1.exe"); 238 | 239 | if (Pid == -1) 240 | { 241 | std::cout << "Could not find pid for name" << std::endl; 242 | return 0; 243 | } 244 | 245 | INFO_IOCTL_EPT_HOOK_INFO EptHookInfo; 246 | EptHookInfo.ProcessId = Pid; 247 | 248 | std::cout << "Pid: " << Pid << std::endl; 249 | 250 | auto ProcessHandle = OpenProcess( 251 | PROCESS_ALL_ACCESS, 252 | FALSE, 253 | Pid 254 | ); 255 | 256 | if (ProcessHandle == NULL) 257 | { 258 | std::cout << "Could not open process" << std::endl; 259 | return 0; 260 | } 261 | 262 | DWORD SizeNeeded; 263 | HMODULE Modules[50]; 264 | 265 | auto AcquiredModules = EnumProcessModules( 266 | ProcessHandle, 267 | Modules, 268 | sizeof Modules, 269 | &SizeNeeded 270 | ); 271 | 272 | if (!AcquiredModules) 273 | { 274 | std::cout << "Could not acquire modules" << std::endl; 275 | return 0; 276 | } 277 | 278 | if (SizeNeeded > sizeof Modules) 279 | { 280 | std::cout << "Size needed: " << SizeNeeded << std::endl; 281 | return 0; 282 | } 283 | 284 | auto AcquiredCount = SizeNeeded / sizeof HMODULE; 285 | std::cout << "Successfully acquired " << AcquiredCount << " modules" << std::endl; 286 | 287 | UINT64 ModuleAddress = 0; 288 | 289 | for (int i = 0; i < AcquiredCount; i++) 290 | { 291 | const auto& Module = Modules[i]; 292 | PCHAR ImageStart = 0; 293 | 294 | RtlCopyMemory( 295 | &ImageStart, 296 | &Module, 297 | sizeof Module 298 | ); 299 | 300 | std::cout << "Module at: 0x" << std::hex << reinterpret_cast(ImageStart) << std::endl; 301 | 302 | CHAR Buffer[4]; 303 | SIZE_T SizeRead = 0; 304 | 305 | auto ReadSuccess = ReadProcessMemory( 306 | ProcessHandle, 307 | ImageStart + 0x1000, 308 | Buffer, 309 | sizeof Buffer, 310 | &SizeRead 311 | ); 312 | 313 | if (!ReadSuccess) 314 | { 315 | std::cout << "ReadProcessMemory failed with: 0x" << std::hex << GetLastError() << std::endl; 316 | return 0; 317 | } 318 | 319 | if (RtlCompareMemory(Buffer, "\x22\x05\x93\x19", 4) == 4) 320 | //if (RtlCompareMemory(Buffer, "\x48\x83\xEC\x28", 4) == 4) 321 | { 322 | std::cout << "Found minigamz.exe module at 0x" << std::hex << reinterpret_cast(Module) << std::endl; 323 | 324 | RtlCopyMemory( 325 | &ModuleAddress, 326 | &Module, 327 | sizeof ModuleAddress 328 | ); 329 | 330 | break; 331 | } 332 | } 333 | 334 | if (ModuleAddress == 0) 335 | { 336 | std::cout << "Could not find minigamz.exe module" << std::endl; 337 | return 0; 338 | } 339 | 340 | PCHAR pModuleAddress = 0; 341 | 342 | ModuleAddress = (ModuleAddress + 0x902b) & ~0xfffULL; 343 | //ModuleAddress = (ModuleAddress + 0x45000) & ~0xfffULL; 344 | 345 | std::cout << "Aligned address: 0x" << std::hex << ModuleAddress << std::endl; 346 | 347 | RtlCopyMemory( 348 | &pModuleAddress, 349 | &ModuleAddress, 350 | sizeof pModuleAddress 351 | ); 352 | 353 | SIZE_T BytesRead = 0; 354 | 355 | auto ReadSuccess = ReadProcessMemory( 356 | ProcessHandle, 357 | pModuleAddress, 358 | EptHookInfo.OriginalPage, 359 | sizeof EptHookInfo.OriginalPage, 360 | &BytesRead 361 | ); 362 | 363 | RtlCopyMemory( 364 | EptHookInfo.ModifiedPage, 365 | EptHookInfo.OriginalPage, 366 | 0x1000 367 | ); 368 | 369 | if (!ReadSuccess) 370 | { 371 | std::cout << "ReadProcessMemory failed on page: 0x" << std::hex << pModuleAddress << std::endl; 372 | return 0; 373 | } 374 | 375 | std::cout << "Modified page value 1: 0x" << std::hex << ((int)EptHookInfo.ModifiedPage[0x2b] & 0xff) << std::endl; 376 | 377 | 378 | EptHookInfo.ModifiedPage[0x2b] = 0xeb; 379 | EptHookInfo.ModifiedPage[0x2c] = 0x29; 380 | EptHookInfo.ModifiedPage[0x2d] = 0xcc; 381 | EptHookInfo.ModifiedPage[0x2e] = 0xcc; 382 | EptHookInfo.ModifiedPage[0x2f] = 0xcc; 383 | EptHookInfo.ModifiedPage[0x30] = 0xcc; 384 | 385 | EptHookInfo.ModifiedPage[0x5a] = 0x10; 386 | 387 | //EptHookInfo.ModifiedPage[0x4] = 0; 388 | 389 | RtlCopyMemory( 390 | &EptHookInfo.VirtualAddress, 391 | &pModuleAddress, 392 | sizeof EptHookInfo.VirtualAddress 393 | ); 394 | 395 | auto DeviceHandle = CreateFileW( 396 | WIN32_DEVICE_NAME, 397 | GENERIC_READ | GENERIC_WRITE, 398 | 0, 399 | nullptr, 400 | OPEN_EXISTING, 401 | FILE_ATTRIBUTE_NORMAL, 402 | nullptr 403 | ); 404 | 405 | if (DeviceHandle == INVALID_HANDLE_VALUE) 406 | { 407 | std::cout << "Could not open a handle to " << WIN32_DEVICE_NAME << std::endl; 408 | return 0; 409 | } 410 | 411 | DWORD BytesReturned = 0; 412 | 413 | Sleep(1000); 414 | 415 | auto IoCtrlStatus = DeviceIoControl( 416 | DeviceHandle, 417 | IOCTL_ADD_EPT_HOOK, 418 | &EptHookInfo, 419 | sizeof EptHookInfo, 420 | nullptr, 421 | 0, 422 | &BytesReturned, 423 | nullptr 424 | ); 425 | 426 | if (!IoCtrlStatus) 427 | { 428 | std::cout << "DeviceIoControl failed with error: 0x" << std::hex << GetLastError() << std::endl; 429 | return 0; 430 | } 431 | 432 | CHAR Buff[0x10]; 433 | /*ReadProcessMemory( 434 | ProcessHandle, 435 | pModuleAddress, 436 | Buff, 437 | sizeof Buff, 438 | &BytesRead 439 | ); 440 | 441 | std::cout << "Buff: "; 442 | 443 | for (int i = 0; i < 0x10; i++) 444 | { 445 | std::cout << ((int)Buff[i] & 0xff) << " "; 446 | } 447 | std::cout << std::endl; 448 | */ 449 | return 1; 450 | } 451 | 452 | UINT64 453 | TestHook ( 454 | ) 455 | { 456 | // Search through all processes 457 | auto Pid = GetPidByName(L"Project1.exe"); 458 | 459 | if (Pid == -1) 460 | { 461 | std::cout << "Could not find pid for name" << std::endl; 462 | return 0; 463 | } 464 | 465 | INFO_IOCTL_EPT_HOOK_INFO EptHookInfo; 466 | EptHookInfo.ProcessId = Pid; 467 | 468 | std::cout << "Pid: " << Pid << std::endl; 469 | 470 | auto ProcessHandle = OpenProcess( 471 | PROCESS_ALL_ACCESS, 472 | FALSE, 473 | Pid 474 | ); 475 | 476 | if (ProcessHandle == NULL) 477 | { 478 | std::cout << "Could not open process" << std::endl; 479 | return 0; 480 | } 481 | 482 | DWORD SizeNeeded; 483 | HMODULE Modules[50]; 484 | 485 | auto AcquiredModules = EnumProcessModules( 486 | ProcessHandle, 487 | Modules, 488 | sizeof Modules, 489 | &SizeNeeded 490 | ); 491 | 492 | if (!AcquiredModules) 493 | { 494 | std::cout << "Could not acquire modules" << std::endl; 495 | return 0; 496 | } 497 | 498 | if (SizeNeeded > sizeof Modules) 499 | { 500 | std::cout << "Size needed: " << SizeNeeded << std::endl; 501 | return 0; 502 | } 503 | 504 | auto AcquiredCount = SizeNeeded / sizeof HMODULE; 505 | std::cout << "Successfully acquired " << AcquiredCount << " modules" << std::endl; 506 | 507 | UINT64 ModuleAddress = 0; 508 | 509 | for (int i = 0; i < AcquiredCount; i++) 510 | { 511 | const auto& Module = Modules[i]; 512 | PCHAR ImageStart = 0; 513 | 514 | RtlCopyMemory( 515 | &ImageStart, 516 | &Module, 517 | sizeof Module 518 | ); 519 | 520 | std::cout << "Module at: 0x" << std::hex << reinterpret_cast(ImageStart) << std::endl; 521 | 522 | CHAR Buffer[4]; 523 | SIZE_T SizeRead = 0; 524 | 525 | auto ReadSuccess = ReadProcessMemory( 526 | ProcessHandle, 527 | ImageStart + 0x1000, 528 | Buffer, 529 | sizeof Buffer, 530 | &SizeRead 531 | ); 532 | 533 | if (!ReadSuccess) 534 | { 535 | std::cout << "ReadProcessMemory failed with: 0x" << std::hex << GetLastError() << std::endl; 536 | return 0; 537 | } 538 | 539 | if (RtlCompareMemory(Buffer, "\x48\x83\xEC\x28", 4) == 4) 540 | { 541 | std::cout << "Found minigamz.exe module at 0x" << std::hex << reinterpret_cast(Module) << std::endl; 542 | 543 | RtlCopyMemory( 544 | &ModuleAddress, 545 | &Module, 546 | sizeof ModuleAddress 547 | ); 548 | 549 | break; 550 | } 551 | } 552 | 553 | if (ModuleAddress == 0) 554 | { 555 | std::cout << "Could not find minigamz.exe module" << std::endl; 556 | return 0; 557 | } 558 | 559 | PCHAR pModuleAddress = 0; 560 | 561 | ModuleAddress = (ModuleAddress + 0x4F000) & ~0xfffULL; 562 | 563 | std::cout << "Aligned address: 0x" << std::hex << ModuleAddress << std::endl; 564 | 565 | RtlCopyMemory( 566 | &pModuleAddress, 567 | &ModuleAddress, 568 | sizeof pModuleAddress 569 | ); 570 | 571 | SIZE_T BytesRead = 0; 572 | 573 | auto ReadSuccess = ReadProcessMemory( 574 | ProcessHandle, 575 | pModuleAddress, 576 | EptHookInfo.OriginalPage, 577 | sizeof EptHookInfo.OriginalPage, 578 | &BytesRead 579 | ); 580 | 581 | RtlCopyMemory( 582 | EptHookInfo.ModifiedPage, 583 | EptHookInfo.OriginalPage, 584 | 0x1000 585 | ); 586 | 587 | if (!ReadSuccess) 588 | { 589 | std::cout << "ReadProcessMemory failed on page: 0x" << std::hex << pModuleAddress << std::endl; 590 | return 0; 591 | } 592 | 593 | EptHookInfo.ModifiedPage[0x3] = 0x90; 594 | 595 | RtlCopyMemory( 596 | &EptHookInfo.VirtualAddress, 597 | &pModuleAddress, 598 | sizeof EptHookInfo.VirtualAddress 599 | ); 600 | 601 | auto DeviceHandle = CreateFileW( 602 | WIN32_DEVICE_NAME, 603 | GENERIC_READ | GENERIC_WRITE, 604 | 0, 605 | nullptr, 606 | OPEN_EXISTING, 607 | FILE_ATTRIBUTE_NORMAL, 608 | nullptr 609 | ); 610 | 611 | if (DeviceHandle == INVALID_HANDLE_VALUE) 612 | { 613 | std::cout << "Could not open a handle to " << WIN32_DEVICE_NAME << std::endl; 614 | return 0; 615 | } 616 | 617 | DWORD BytesReturned = 0; 618 | 619 | Sleep(1000); 620 | 621 | auto IoCtrlStatus = DeviceIoControl( 622 | DeviceHandle, 623 | IOCTL_ADD_EPT_HOOK, 624 | &EptHookInfo, 625 | sizeof EptHookInfo, 626 | nullptr, 627 | 0, 628 | &BytesReturned, 629 | nullptr 630 | ); 631 | 632 | if (!IoCtrlStatus) 633 | { 634 | std::cout << "DeviceIoControl failed with error: 0x" << std::hex << GetLastError() << std::endl; 635 | return 0; 636 | } 637 | 638 | return 1; 639 | } 640 | 641 | int 642 | main ( 643 | int Argc, 644 | char* Argv[] 645 | ) 646 | { 647 | 648 | //AddEptHook(); 649 | //AddEptHook2(); 650 | TestHook(); 651 | 652 | /* 653 | auto Handle = CreateFileW( 654 | WIN32_DEVICE_NAME, 655 | GENERIC_READ | GENERIC_WRITE, 656 | 0, 657 | nullptr, 658 | OPEN_EXISTING, 659 | FILE_ATTRIBUTE_NORMAL, 660 | nullptr 661 | ); 662 | 663 | if (Handle == INVALID_HANDLE_VALUE) 664 | { 665 | std::cout << "Handle sucked. Error: " << "0x" << std::hex << GetLastError() << std::endl; 666 | return -1; 667 | } 668 | 669 | INFO_IOCTL_CPUID_PROCESS InfoIoctl; 670 | 671 | RtlZeroMemory( 672 | &InfoIoctl, 673 | sizeof(InfoIoctl) 674 | ); 675 | 676 | auto FilePath = L"\\DosDevices\\C:\\Users\\trashcan\\Desktop\\Log.txt"; 677 | auto ProcName = L"Project1.exe"; 678 | wmemcpy(InfoIoctl.FilePath, FilePath, std::char_traits::length(FilePath)); 679 | wmemcpy(InfoIoctl.ProcessName, ProcName, std::char_traits::length(ProcName)); 680 | InfoIoctl.LogCount = 100; 681 | 682 | DWORD BytesReturned; 683 | 684 | auto Status = DeviceIoControl( 685 | Handle, 686 | IOCTL_LOG_CPUID_PROCESS, 687 | &InfoIoctl, 688 | sizeof(InfoIoctl), 689 | nullptr, 690 | 0, 691 | &BytesReturned, 692 | nullptr 693 | ); 694 | 695 | if (!Status) 696 | { 697 | std::cout << "DeviceIoControl failed. Error: " << "0x" << std::hex << GetLastError() << std::endl; 698 | return -1; 699 | } 700 | 701 | */ 702 | return 0; 703 | } -------------------------------------------------------------------------------- /Trashcomm/Trashcomm.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 | {AB166D21-9500-481A-BE0B-EB3F9A2BA6BB} 24 | Trashcomm 25 | 10.0 26 | 27 | 28 | 29 | Application 30 | true 31 | v142 32 | Unicode 33 | 34 | 35 | Application 36 | false 37 | v142 38 | true 39 | Unicode 40 | 41 | 42 | Application 43 | true 44 | v142 45 | Unicode 46 | 47 | 48 | Application 49 | false 50 | v142 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 | true 74 | 75 | 76 | true 77 | 78 | 79 | false 80 | 81 | 82 | false 83 | 84 | 85 | 86 | Level3 87 | true 88 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 89 | true 90 | MultiThreadedDebug 91 | 92 | 93 | Console 94 | true 95 | 96 | 97 | 98 | 99 | Level3 100 | true 101 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 102 | true 103 | 104 | 105 | Console 106 | true 107 | 108 | 109 | 110 | 111 | Level3 112 | true 113 | true 114 | true 115 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 116 | true 117 | 118 | 119 | Console 120 | true 121 | true 122 | true 123 | 124 | 125 | 126 | 127 | Level3 128 | true 129 | true 130 | true 131 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 132 | true 133 | MultiThreadedDebug 134 | 135 | 136 | Console 137 | true 138 | true 139 | true 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /Trashcomm/Trashcomm.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Trashcomm/Trashcomm.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /Trashvisor.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29613.14 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Trashvisor", "Trashvisor\Trashvisor.vcxproj", "{EE58D4F9-2778-4215-9BDE-7CDF1CFD4614}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Trashcomm", "Trashcomm\Trashcomm.vcxproj", "{AB166D21-9500-481A-BE0B-EB3F9A2BA6BB}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|x64 = Debug|x64 13 | Debug|x86 = Debug|x86 14 | Release|x64 = Release|x64 15 | Release|x86 = Release|x86 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {EE58D4F9-2778-4215-9BDE-7CDF1CFD4614}.Debug|x64.ActiveCfg = Debug|x64 19 | {EE58D4F9-2778-4215-9BDE-7CDF1CFD4614}.Debug|x64.Build.0 = Debug|x64 20 | {EE58D4F9-2778-4215-9BDE-7CDF1CFD4614}.Debug|x64.Deploy.0 = Debug|x64 21 | {EE58D4F9-2778-4215-9BDE-7CDF1CFD4614}.Debug|x86.ActiveCfg = Debug|Win32 22 | {EE58D4F9-2778-4215-9BDE-7CDF1CFD4614}.Debug|x86.Build.0 = Debug|Win32 23 | {EE58D4F9-2778-4215-9BDE-7CDF1CFD4614}.Debug|x86.Deploy.0 = Debug|Win32 24 | {EE58D4F9-2778-4215-9BDE-7CDF1CFD4614}.Release|x64.ActiveCfg = Release|x64 25 | {EE58D4F9-2778-4215-9BDE-7CDF1CFD4614}.Release|x64.Build.0 = Release|x64 26 | {EE58D4F9-2778-4215-9BDE-7CDF1CFD4614}.Release|x64.Deploy.0 = Release|x64 27 | {EE58D4F9-2778-4215-9BDE-7CDF1CFD4614}.Release|x86.ActiveCfg = Release|Win32 28 | {EE58D4F9-2778-4215-9BDE-7CDF1CFD4614}.Release|x86.Build.0 = Release|Win32 29 | {EE58D4F9-2778-4215-9BDE-7CDF1CFD4614}.Release|x86.Deploy.0 = Release|Win32 30 | {AB166D21-9500-481A-BE0B-EB3F9A2BA6BB}.Debug|x64.ActiveCfg = Debug|x64 31 | {AB166D21-9500-481A-BE0B-EB3F9A2BA6BB}.Debug|x64.Build.0 = Debug|x64 32 | {AB166D21-9500-481A-BE0B-EB3F9A2BA6BB}.Debug|x86.ActiveCfg = Debug|Win32 33 | {AB166D21-9500-481A-BE0B-EB3F9A2BA6BB}.Debug|x86.Build.0 = Debug|Win32 34 | {AB166D21-9500-481A-BE0B-EB3F9A2BA6BB}.Release|x64.ActiveCfg = Release|x64 35 | {AB166D21-9500-481A-BE0B-EB3F9A2BA6BB}.Release|x64.Build.0 = Release|x64 36 | {AB166D21-9500-481A-BE0B-EB3F9A2BA6BB}.Release|x86.ActiveCfg = Release|Win32 37 | {AB166D21-9500-481A-BE0B-EB3F9A2BA6BB}.Release|x86.Build.0 = Release|Win32 38 | EndGlobalSection 39 | GlobalSection(SolutionProperties) = preSolution 40 | HideSolutionNode = FALSE 41 | EndGlobalSection 42 | GlobalSection(ExtensibilityGlobals) = postSolution 43 | SolutionGuid = {95E7F0CC-0F17-4FA9-B69B-902C23D21431} 44 | EndGlobalSection 45 | EndGlobal 46 | -------------------------------------------------------------------------------- /Trashvisor/ArchUtils.c: -------------------------------------------------------------------------------- 1 | #include "ArchUtils.h" 2 | 3 | BOOLEAN 4 | IsVmxSupported ( 5 | ) 6 | { 7 | BOOLEAN bStatus = TRUE; 8 | 9 | int CpuIdInfo[4]; 10 | __cpuid(CpuIdInfo, 1); 11 | 12 | if (!(CpuIdInfo[3] & (1 << 5))) 13 | { 14 | KdPrintError("Cpuid: Vmx not supported.\n"); 15 | bStatus = FALSE; 16 | goto Exit; 17 | } 18 | 19 | IA32_FEATURE_CONTROL_REGISTER FeatureControlMsr; 20 | FeatureControlMsr.Flags = ReadMsr(IA32_FEATURE_CONTROL); 21 | 22 | if (!FeatureControlMsr.EnableVmxOutsideSmx) 23 | { 24 | KdPrintError("Vmx not enabled outside of SMX.\n"); 25 | bStatus = FALSE; 26 | goto Exit; 27 | } 28 | 29 | if (!FeatureControlMsr.LockBit) 30 | { 31 | KdPrintError("Lock bit not set.\n"); 32 | bStatus = FALSE; 33 | goto Exit; 34 | } 35 | 36 | Exit: 37 | return bStatus; 38 | } 39 | 40 | _Use_decl_annotations_ 41 | VOID 42 | KdPrintError ( 43 | LPCSTR ErrorMessage, 44 | ... 45 | ) 46 | { 47 | va_list ArgumentList; 48 | va_start(ArgumentList, ErrorMessage); 49 | 50 | vDbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, ErrorMessage, ArgumentList); 51 | 52 | va_end(ArgumentList); 53 | } 54 | 55 | _Use_decl_annotations_ 56 | ULONGLONG 57 | ReadMsr ( 58 | ULONG Msr 59 | ) 60 | { 61 | return __readmsr(Msr); 62 | } 63 | 64 | _Use_decl_annotations_ 65 | SEGMENT_DESCRIPTOR_32 66 | GetSegmentDescriptor ( 67 | _In_ UINT16 Selector, 68 | _In_ UINT64 GdtrBase 69 | ) 70 | { 71 | SEGMENT_DESCRIPTOR_32 Descriptor = *(PSEGMENT_DESCRIPTOR_32)(GdtrBase + (Selector & ~0b111)); 72 | return Descriptor; 73 | } 74 | 75 | _Use_decl_annotations_ 76 | SEGMENT_DESCRIPTOR_64 77 | GetSysSegmentDescriptor ( 78 | _In_ UINT16 Selector, 79 | _In_ UINT64 GdtrBase 80 | ) 81 | { 82 | SEGMENT_DESCRIPTOR_64 Descriptor = *(PSEGMENT_DESCRIPTOR_64)(GdtrBase + (Selector & ~0b111)); 83 | return Descriptor; 84 | } 85 | 86 | _Use_decl_annotations_ 87 | UINT32 88 | GetSegmentBase ( 89 | _In_ SEGMENT_DESCRIPTOR_32 Segment 90 | ) 91 | { 92 | return Segment.BaseAddressHigh << 24 93 | | Segment.BaseAddressMiddle << 16 94 | | Segment.BaseAddressLow; 95 | } 96 | 97 | _Use_decl_annotations_ 98 | ULONG64 99 | GetSysSegmentBase ( 100 | _In_ SEGMENT_DESCRIPTOR_64 SysSegment 101 | ) 102 | { 103 | ULONG64 BaseAddress = SysSegment.BaseAddressUpper; 104 | BaseAddress <<= 32; 105 | 106 | BaseAddress |= (SysSegment.BaseAddressHigh << 24); 107 | BaseAddress |= (SysSegment.BaseAddressMiddle << 16); 108 | BaseAddress |= SysSegment.BaseAddressLow; 109 | 110 | return BaseAddress; 111 | } 112 | -------------------------------------------------------------------------------- /Trashvisor/ArchUtils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Extern.h" 3 | #include "Shared.h" 4 | #include 5 | 6 | typedef struct _SEGMENT_SETUP 7 | { 8 | UINT64 BaseAddress; 9 | UINT32 SegmentLimit; 10 | UINT32 AccessRights; 11 | } SEGMENT_SETUP, *PSEGMENT_SETUP; 12 | 13 | BOOLEAN 14 | IsVmxSupported ( 15 | ); 16 | 17 | VOID 18 | KdPrintError ( 19 | _In_ LPCSTR Message, 20 | _In_ ... 21 | ); 22 | 23 | ULONGLONG 24 | ReadMsr ( 25 | _In_ ULONG Msr 26 | ); 27 | 28 | UINT16 29 | _str ( 30 | ); 31 | 32 | UINT16 33 | _sldt ( 34 | ); 35 | 36 | VOID 37 | _cli ( 38 | ); 39 | 40 | VOID 41 | _sti ( 42 | ); 43 | 44 | SEGMENT_DESCRIPTOR_32 45 | GetSegmentDescriptor ( 46 | _In_ UINT16 Selector, 47 | _In_ UINT64 GdtrBase 48 | ); 49 | 50 | SEGMENT_DESCRIPTOR_64 51 | GetSysSegmentDescriptor ( 52 | _In_ UINT16 Seledctor, 53 | _In_ UINT64 GdtrBase 54 | ); 55 | 56 | UINT32 57 | GetSegmentBase ( 58 | _In_ SEGMENT_DESCRIPTOR_32 SegmentDescriptor 59 | ); 60 | 61 | UINT64 62 | GetSysSegmentBase ( 63 | _In_ SEGMENT_DESCRIPTOR_64 SysSegment 64 | ); 65 | 66 | VOID 67 | HypervisorBreak ( 68 | ); 69 | 70 | typedef struct _PEB_LDR_DATA 71 | { 72 | UINT32 Length; 73 | UCHAR Initialised; 74 | PVOID SsHandle; 75 | LIST_ENTRY InLoadOrderModuleList; 76 | LIST_ENTRY InMemOrderModuleList; 77 | LIST_ENTRY InInitOrderModuleList; 78 | PVOID EntryInProgress; 79 | UCHAR ShutDownInProgress; 80 | PVOID ShutDownThreadId; 81 | } PEB_LDR_DATA, * PPEB_LDR_DATA; 82 | 83 | typedef struct _LDR_MODULE 84 | { 85 | LIST_ENTRY InLoadOrderModuleList; 86 | LIST_ENTRY InMemOrderModuleList; 87 | LIST_ENTRY InInitializationOrderModuleList; 88 | PVOID BaseAddress; 89 | PVOID EntryPoint; 90 | ULONG SizeOfImage; 91 | UNICODE_STRING FullDllName; 92 | UNICODE_STRING BaseDllName; 93 | ULONG Flags; 94 | SHORT LoadCount; 95 | SHORT TlsIndex; 96 | LIST_ENTRY HashTableEntry; 97 | ULONG TimeDateStamp; 98 | } LDR_MODULE, *PLDR_MODULE; 99 | 100 | typedef enum _KAPC_ENVIRONMENT 101 | { 102 | OriginalApcEnvironment, 103 | AttachedApcEnvironment, 104 | CurrentApcEnvironment 105 | } KAPC_ENVIRONMENT, *PKAPC_ENVIRONMENT; 106 | 107 | typedef enum _SYSTEM_INFORMATION_CLASS 108 | { 109 | SystemBasicInformation, // q: SYSTEM_BASIC_INFORMATION 110 | SystemProcessorInformation, // q: SYSTEM_PROCESSOR_INFORMATION 111 | SystemPerformanceInformation, // q: SYSTEM_PERFORMANCE_INFORMATION 112 | SystemTimeOfDayInformation, // q: SYSTEM_TIMEOFDAY_INFORMATION 113 | SystemPathInformation, // not implemented 114 | SystemProcessInformation, // q: SYSTEM_PROCESS_INFORMATION 115 | SystemCallCountInformation, // q: SYSTEM_CALL_COUNT_INFORMATION 116 | SystemDeviceInformation, // q: SYSTEM_DEVICE_INFORMATION 117 | SystemProcessorPerformanceInformation, // q: SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION 118 | SystemFlagsInformation, // q: SYSTEM_FLAGS_INFORMATION 119 | SystemCallTimeInformation, // not implemented // SYSTEM_CALL_TIME_INFORMATION // 10 120 | SystemModuleInformation, // q: RTL_PROCESS_MODULES 121 | SystemLocksInformation, // q: RTL_PROCESS_LOCKS 122 | SystemStackTraceInformation, // q: RTL_PROCESS_BACKTRACES 123 | SystemPagedPoolInformation, // not implemented 124 | SystemNonPagedPoolInformation, // not implemented 125 | SystemHandleInformation, // q: SYSTEM_HANDLE_INFORMATION 126 | SystemObjectInformation, // q: SYSTEM_OBJECTTYPE_INFORMATION mixed with SYSTEM_OBJECT_INFORMATION 127 | SystemPageFileInformation, // q: SYSTEM_PAGEFILE_INFORMATION 128 | SystemVdmInstemulInformation, // q: SYSTEM_VDM_INSTEMUL_INFO 129 | SystemVdmBopInformation, // not implemented // 20 130 | SystemFileCacheInformation, // q: SYSTEM_FILECACHE_INFORMATION; s (requires SeIncreaseQuotaPrivilege) (info for WorkingSetTypeSystemCache) 131 | SystemPoolTagInformation, // q: SYSTEM_POOLTAG_INFORMATION 132 | SystemInterruptInformation, // q: SYSTEM_INTERRUPT_INFORMATION 133 | SystemDpcBehaviorInformation, // q: SYSTEM_DPC_BEHAVIOR_INFORMATION; s: SYSTEM_DPC_BEHAVIOR_INFORMATION (requires SeLoadDriverPrivilege) 134 | SystemFullMemoryInformation, // not implemented // SYSTEM_MEMORY_USAGE_INFORMATION 135 | SystemLoadGdiDriverInformation, // s (kernel-mode only) 136 | SystemUnloadGdiDriverInformation, // s (kernel-mode only) 137 | SystemTimeAdjustmentInformation, // q: SYSTEM_QUERY_TIME_ADJUST_INFORMATION; s: SYSTEM_SET_TIME_ADJUST_INFORMATION (requires SeSystemtimePrivilege) 138 | SystemSummaryMemoryInformation, // not implemented // SYSTEM_MEMORY_USAGE_INFORMATION 139 | SystemMirrorMemoryInformation, // s (requires license value "Kernel-MemoryMirroringSupported") (requires SeShutdownPrivilege) // 30 140 | SystemPerformanceTraceInformation, // q; s: (type depends on EVENT_TRACE_INFORMATION_CLASS) 141 | SystemObsolete0, // not implemented 142 | SystemExceptionInformation, // q: SYSTEM_EXCEPTION_INFORMATION 143 | SystemCrashDumpStateInformation, // s: SYSTEM_CRASH_DUMP_STATE_INFORMATION (requires SeDebugPrivilege) 144 | SystemKernelDebuggerInformation, // q: SYSTEM_KERNEL_DEBUGGER_INFORMATION 145 | SystemContextSwitchInformation, // q: SYSTEM_CONTEXT_SWITCH_INFORMATION 146 | SystemRegistryQuotaInformation, // q: SYSTEM_REGISTRY_QUOTA_INFORMATION; s (requires SeIncreaseQuotaPrivilege) 147 | SystemExtendServiceTableInformation, // s (requires SeLoadDriverPrivilege) // loads win32k only 148 | SystemPrioritySeperation, // s (requires SeTcbPrivilege) 149 | SystemVerifierAddDriverInformation, // s (requires SeDebugPrivilege) // 40 150 | SystemVerifierRemoveDriverInformation, // s (requires SeDebugPrivilege) 151 | SystemProcessorIdleInformation, // q: SYSTEM_PROCESSOR_IDLE_INFORMATION 152 | SystemLegacyDriverInformation, // q: SYSTEM_LEGACY_DRIVER_INFORMATION 153 | SystemCurrentTimeZoneInformation, // q; s: RTL_TIME_ZONE_INFORMATION 154 | SystemLookasideInformation, // q: SYSTEM_LOOKASIDE_INFORMATION 155 | SystemTimeSlipNotification, // s (requires SeSystemtimePrivilege) 156 | SystemSessionCreate, // not implemented 157 | SystemSessionDetach, // not implemented 158 | SystemSessionInformation, // not implemented (SYSTEM_SESSION_INFORMATION) 159 | SystemRangeStartInformation, // q: SYSTEM_RANGE_START_INFORMATION // 50 160 | SystemVerifierInformation, // q: SYSTEM_VERIFIER_INFORMATION; s (requires SeDebugPrivilege) 161 | SystemVerifierThunkExtend, // s (kernel-mode only) 162 | SystemSessionProcessInformation, // q: SYSTEM_SESSION_PROCESS_INFORMATION 163 | SystemLoadGdiDriverInSystemSpace, // s (kernel-mode only) (same as SystemLoadGdiDriverInformation) 164 | SystemNumaProcessorMap, // q 165 | SystemPrefetcherInformation, // q: PREFETCHER_INFORMATION; s: PREFETCHER_INFORMATION // PfSnQueryPrefetcherInformation 166 | SystemExtendedProcessInformation, // q: SYSTEM_PROCESS_INFORMATION 167 | SystemRecommendedSharedDataAlignment, // q 168 | SystemComPlusPackage, // q; s 169 | SystemNumaAvailableMemory, // 60 170 | SystemProcessorPowerInformation, // q: SYSTEM_PROCESSOR_POWER_INFORMATION 171 | SystemEmulationBasicInformation, 172 | SystemEmulationProcessorInformation, 173 | SystemExtendedHandleInformation, // q: SYSTEM_HANDLE_INFORMATION_EX 174 | SystemLostDelayedWriteInformation, // q: ULONG 175 | SystemBigPoolInformation, // q: SYSTEM_BIGPOOL_INFORMATION 176 | SystemSessionPoolTagInformation, // q: SYSTEM_SESSION_POOLTAG_INFORMATION 177 | SystemSessionMappedViewInformation, // q: SYSTEM_SESSION_MAPPED_VIEW_INFORMATION 178 | SystemHotpatchInformation, // q; s: SYSTEM_HOTPATCH_CODE_INFORMATION 179 | SystemObjectSecurityMode, // q: ULONG // 70 180 | SystemWatchdogTimerHandler, // s (kernel-mode only) 181 | SystemWatchdogTimerInformation, // q (kernel-mode only); s (kernel-mode only) 182 | SystemLogicalProcessorInformation, // q: SYSTEM_LOGICAL_PROCESSOR_INFORMATION 183 | SystemWow64SharedInformationObsolete, // not implemented 184 | SystemRegisterFirmwareTableInformationHandler, // s: SYSTEM_FIRMWARE_TABLE_HANDLER // (kernel-mode only) 185 | SystemFirmwareTableInformation, // SYSTEM_FIRMWARE_TABLE_INFORMATION 186 | SystemModuleInformationEx, // q: RTL_PROCESS_MODULE_INFORMATION_EX 187 | SystemVerifierTriageInformation, // not implemented 188 | SystemSuperfetchInformation, // q; s: SUPERFETCH_INFORMATION // PfQuerySuperfetchInformation 189 | SystemMemoryListInformation, // q: SYSTEM_MEMORY_LIST_INFORMATION; s: SYSTEM_MEMORY_LIST_COMMAND (requires SeProfileSingleProcessPrivilege) // 80 190 | SystemFileCacheInformationEx, // q: SYSTEM_FILECACHE_INFORMATION; s (requires SeIncreaseQuotaPrivilege) (same as SystemFileCacheInformation) 191 | SystemThreadPriorityClientIdInformation, // s: SYSTEM_THREAD_CID_PRIORITY_INFORMATION (requires SeIncreaseBasePriorityPrivilege) 192 | SystemProcessorIdleCycleTimeInformation, // q: SYSTEM_PROCESSOR_IDLE_CYCLE_TIME_INFORMATION[] 193 | SystemVerifierCancellationInformation, // SYSTEM_VERIFIER_CANCELLATION_INFORMATION // name:wow64:whNT32QuerySystemVerifierCancellationInformation 194 | SystemProcessorPowerInformationEx, // not implemented 195 | SystemRefTraceInformation, // q; s: SYSTEM_REF_TRACE_INFORMATION // ObQueryRefTraceInformation 196 | SystemSpecialPoolInformation, // q; s: SYSTEM_SPECIAL_POOL_INFORMATION (requires SeDebugPrivilege) // MmSpecialPoolTag, then MmSpecialPoolCatchOverruns != 0 197 | SystemProcessIdInformation, // q: SYSTEM_PROCESS_ID_INFORMATION 198 | SystemErrorPortInformation, // s (requires SeTcbPrivilege) 199 | SystemBootEnvironmentInformation, // q: SYSTEM_BOOT_ENVIRONMENT_INFORMATION // 90 200 | SystemHypervisorInformation, // q; s (kernel-mode only) 201 | SystemVerifierInformationEx, // q; s: SYSTEM_VERIFIER_INFORMATION_EX 202 | SystemTimeZoneInformation, // s (requires SeTimeZonePrivilege) 203 | SystemImageFileExecutionOptionsInformation, // s: SYSTEM_IMAGE_FILE_EXECUTION_OPTIONS_INFORMATION (requires SeTcbPrivilege) 204 | SystemCoverageInformation, // q; s // name:wow64:whNT32QuerySystemCoverageInformation; ExpCovQueryInformation 205 | SystemPrefetchPatchInformation, // SYSTEM_PREFETCH_PATCH_INFORMATION 206 | SystemVerifierFaultsInformation, // s: SYSTEM_VERIFIER_FAULTS_INFORMATION (requires SeDebugPrivilege) 207 | SystemSystemPartitionInformation, // q: SYSTEM_SYSTEM_PARTITION_INFORMATION 208 | SystemSystemDiskInformation, // q: SYSTEM_SYSTEM_DISK_INFORMATION 209 | SystemProcessorPerformanceDistribution, // q: SYSTEM_PROCESSOR_PERFORMANCE_DISTRIBUTION // 100 210 | SystemNumaProximityNodeInformation, 211 | SystemDynamicTimeZoneInformation, // q; s (requires SeTimeZonePrivilege) 212 | SystemCodeIntegrityInformation, // q: SYSTEM_CODEINTEGRITY_INFORMATION // SeCodeIntegrityQueryInformation 213 | SystemProcessorMicrocodeUpdateInformation, // s: SYSTEM_PROCESSOR_MICROCODE_UPDATE_INFORMATION 214 | SystemProcessorBrandString, // q // HaliQuerySystemInformation -> HalpGetProcessorBrandString, info class 23 215 | SystemVirtualAddressInformation, // q: SYSTEM_VA_LIST_INFORMATION[]; s: SYSTEM_VA_LIST_INFORMATION[] (requires SeIncreaseQuotaPrivilege) // MmQuerySystemVaInformation 216 | SystemLogicalProcessorAndGroupInformation, // q: SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX // since WIN7 // KeQueryLogicalProcessorRelationship 217 | SystemProcessorCycleTimeInformation, // q: SYSTEM_PROCESSOR_CYCLE_TIME_INFORMATION[] 218 | SystemStoreInformation, // q; s: SYSTEM_STORE_INFORMATION // SmQueryStoreInformation 219 | SystemRegistryAppendString, // s: SYSTEM_REGISTRY_APPEND_STRING_PARAMETERS // 110 220 | SystemAitSamplingValue, // s: ULONG (requires SeProfileSingleProcessPrivilege) 221 | SystemVhdBootInformation, // q: SYSTEM_VHD_BOOT_INFORMATION 222 | SystemCpuQuotaInformation, // q; s // PsQueryCpuQuotaInformation 223 | SystemNativeBasicInformation, // not implemented 224 | SystemErrorPortTimeouts, // SYSTEM_ERROR_PORT_TIMEOUTS 225 | SystemLowPriorityIoInformation, // q: SYSTEM_LOW_PRIORITY_IO_INFORMATION 226 | SystemTpmBootEntropyInformation, // q: TPM_BOOT_ENTROPY_NT_RESULT // ExQueryTpmBootEntropyInformation 227 | SystemVerifierCountersInformation, // q: SYSTEM_VERIFIER_COUNTERS_INFORMATION 228 | SystemPagedPoolInformationEx, // q: SYSTEM_FILECACHE_INFORMATION; s (requires SeIncreaseQuotaPrivilege) (info for WorkingSetTypePagedPool) 229 | SystemSystemPtesInformationEx, // q: SYSTEM_FILECACHE_INFORMATION; s (requires SeIncreaseQuotaPrivilege) (info for WorkingSetTypeSystemPtes) // 120 230 | SystemNodeDistanceInformation, 231 | SystemAcpiAuditInformation, // q: SYSTEM_ACPI_AUDIT_INFORMATION // HaliQuerySystemInformation -> HalpAuditQueryResults, info class 26 232 | SystemBasicPerformanceInformation, // q: SYSTEM_BASIC_PERFORMANCE_INFORMATION // name:wow64:whNtQuerySystemInformation_SystemBasicPerformanceInformation 233 | SystemQueryPerformanceCounterInformation, // q: SYSTEM_QUERY_PERFORMANCE_COUNTER_INFORMATION // since WIN7 SP1 234 | SystemSessionBigPoolInformation, // q: SYSTEM_SESSION_POOLTAG_INFORMATION // since WIN8 235 | SystemBootGraphicsInformation, // q; s: SYSTEM_BOOT_GRAPHICS_INFORMATION (kernel-mode only) 236 | SystemScrubPhysicalMemoryInformation, // q; s: MEMORY_SCRUB_INFORMATION 237 | SystemBadPageInformation, 238 | SystemProcessorProfileControlArea, // q; s: SYSTEM_PROCESSOR_PROFILE_CONTROL_AREA 239 | SystemCombinePhysicalMemoryInformation, // s: MEMORY_COMBINE_INFORMATION, MEMORY_COMBINE_INFORMATION_EX, MEMORY_COMBINE_INFORMATION_EX2 // 130 240 | SystemEntropyInterruptTimingInformation, 241 | SystemConsoleInformation, // q: SYSTEM_CONSOLE_INFORMATION 242 | SystemPlatformBinaryInformation, // q: SYSTEM_PLATFORM_BINARY_INFORMATION 243 | SystemPolicyInformation, // SYSTEM_POLICY_INFORMATION 244 | SystemHypervisorProcessorCountInformation, // q: SYSTEM_HYPERVISOR_PROCESSOR_COUNT_INFORMATION 245 | SystemDeviceDataInformation, // q: SYSTEM_DEVICE_DATA_INFORMATION 246 | SystemDeviceDataEnumerationInformation, // q: SYSTEM_DEVICE_DATA_INFORMATION 247 | SystemMemoryTopologyInformation, // q: SYSTEM_MEMORY_TOPOLOGY_INFORMATION 248 | SystemMemoryChannelInformation, // q: SYSTEM_MEMORY_CHANNEL_INFORMATION 249 | SystemBootLogoInformation, // q: SYSTEM_BOOT_LOGO_INFORMATION // 140 250 | SystemProcessorPerformanceInformationEx, // q: SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION_EX // since WINBLUE 251 | SystemCriticalProcessErrorLogInformation, 252 | SystemSecureBootPolicyInformation, // q: SYSTEM_SECUREBOOT_POLICY_INFORMATION 253 | SystemPageFileInformationEx, // q: SYSTEM_PAGEFILE_INFORMATION_EX 254 | SystemSecureBootInformation, // q: SYSTEM_SECUREBOOT_INFORMATION 255 | SystemEntropyInterruptTimingRawInformation, 256 | SystemPortableWorkspaceEfiLauncherInformation, // q: SYSTEM_PORTABLE_WORKSPACE_EFI_LAUNCHER_INFORMATION 257 | SystemFullProcessInformation, // q: SYSTEM_PROCESS_INFORMATION with SYSTEM_PROCESS_INFORMATION_EXTENSION (requires admin) 258 | SystemKernelDebuggerInformationEx, // q: SYSTEM_KERNEL_DEBUGGER_INFORMATION_EX 259 | SystemBootMetadataInformation, // 150 260 | SystemSoftRebootInformation, // q: ULONG 261 | SystemElamCertificateInformation, // s: SYSTEM_ELAM_CERTIFICATE_INFORMATION 262 | SystemOfflineDumpConfigInformation, 263 | SystemProcessorFeaturesInformation, // q: SYSTEM_PROCESSOR_FEATURES_INFORMATION 264 | SystemRegistryReconciliationInformation, // s: NULL (requires admin) (flushes registry hives) 265 | SystemEdidInformation, 266 | SystemManufacturingInformation, // q: SYSTEM_MANUFACTURING_INFORMATION // since THRESHOLD 267 | SystemEnergyEstimationConfigInformation, // q: SYSTEM_ENERGY_ESTIMATION_CONFIG_INFORMATION 268 | SystemHypervisorDetailInformation, // q: SYSTEM_HYPERVISOR_DETAIL_INFORMATION 269 | SystemProcessorCycleStatsInformation, // q: SYSTEM_PROCESSOR_CYCLE_STATS_INFORMATION // 160 270 | SystemVmGenerationCountInformation, 271 | SystemTrustedPlatformModuleInformation, // q: SYSTEM_TPM_INFORMATION 272 | SystemKernelDebuggerFlags, // SYSTEM_KERNEL_DEBUGGER_FLAGS 273 | SystemCodeIntegrityPolicyInformation, // q: SYSTEM_CODEINTEGRITYPOLICY_INFORMATION 274 | SystemIsolatedUserModeInformation, // q: SYSTEM_ISOLATED_USER_MODE_INFORMATION 275 | SystemHardwareSecurityTestInterfaceResultsInformation, 276 | SystemSingleModuleInformation, // q: SYSTEM_SINGLE_MODULE_INFORMATION 277 | SystemAllowedCpuSetsInformation, 278 | SystemVsmProtectionInformation, // q: SYSTEM_VSM_PROTECTION_INFORMATION (previously SystemDmaProtectionInformation) 279 | SystemInterruptCpuSetsInformation, // q: SYSTEM_INTERRUPT_CPU_SET_INFORMATION // 170 280 | SystemSecureBootPolicyFullInformation, // q: SYSTEM_SECUREBOOT_POLICY_FULL_INFORMATION 281 | SystemCodeIntegrityPolicyFullInformation, 282 | SystemAffinitizedInterruptProcessorInformation, 283 | SystemRootSiloInformation, // q: SYSTEM_ROOT_SILO_INFORMATION 284 | SystemCpuSetInformation, // q: SYSTEM_CPU_SET_INFORMATION // since THRESHOLD2 285 | SystemCpuSetTagInformation, // q: SYSTEM_CPU_SET_TAG_INFORMATION 286 | SystemWin32WerStartCallout, 287 | SystemSecureKernelProfileInformation, // q: SYSTEM_SECURE_KERNEL_HYPERGUARD_PROFILE_INFORMATION 288 | SystemCodeIntegrityPlatformManifestInformation, // q: SYSTEM_SECUREBOOT_PLATFORM_MANIFEST_INFORMATION // since REDSTONE 289 | SystemInterruptSteeringInformation, // SYSTEM_INTERRUPT_STEERING_INFORMATION_INPUT // 180 290 | SystemSupportedProcessorArchitectures, 291 | SystemMemoryUsageInformation, // q: SYSTEM_MEMORY_USAGE_INFORMATION 292 | SystemCodeIntegrityCertificateInformation, // q: SYSTEM_CODEINTEGRITY_CERTIFICATE_INFORMATION 293 | SystemPhysicalMemoryInformation, // q: SYSTEM_PHYSICAL_MEMORY_INFORMATION // since REDSTONE2 294 | SystemControlFlowTransition, 295 | SystemKernelDebuggingAllowed, // s: ULONG 296 | SystemActivityModerationExeState, // SYSTEM_ACTIVITY_MODERATION_EXE_STATE 297 | SystemActivityModerationUserSettings, // SYSTEM_ACTIVITY_MODERATION_USER_SETTINGS 298 | SystemCodeIntegrityPoliciesFullInformation, 299 | SystemCodeIntegrityUnlockInformation, // SYSTEM_CODEINTEGRITY_UNLOCK_INFORMATION // 190 300 | SystemIntegrityQuotaInformation, 301 | SystemFlushInformation, // q: SYSTEM_FLUSH_INFORMATION 302 | SystemProcessorIdleMaskInformation, // q: ULONG_PTR // since REDSTONE3 303 | SystemSecureDumpEncryptionInformation, 304 | SystemWriteConstraintInformation, // SYSTEM_WRITE_CONSTRAINT_INFORMATION 305 | SystemKernelVaShadowInformation, // SYSTEM_KERNEL_VA_SHADOW_INFORMATION 306 | SystemHypervisorSharedPageInformation, // SYSTEM_HYPERVISOR_SHARED_PAGE_INFORMATION // since REDSTONE4 307 | SystemFirmwareBootPerformanceInformation, 308 | SystemCodeIntegrityVerificationInformation, // SYSTEM_CODEINTEGRITYVERIFICATION_INFORMATION 309 | SystemFirmwarePartitionInformation, // SYSTEM_FIRMWARE_PARTITION_INFORMATION // 200 310 | SystemSpeculationControlInformation, // SYSTEM_SPECULATION_CONTROL_INFORMATION // (CVE-2017-5715) REDSTONE3 and above. 311 | SystemDmaGuardPolicyInformation, // SYSTEM_DMA_GUARD_POLICY_INFORMATION 312 | SystemEnclaveLaunchControlInformation, // SYSTEM_ENCLAVE_LAUNCH_CONTROL_INFORMATION 313 | SystemWorkloadAllowedCpuSetsInformation, // SYSTEM_WORKLOAD_ALLOWED_CPU_SET_INFORMATION // since REDSTONE5 314 | SystemCodeIntegrityUnlockModeInformation, 315 | SystemLeapSecondInformation, // SYSTEM_LEAP_SECOND_INFORMATION 316 | SystemFlags2Information, // q: SYSTEM_FLAGS_INFORMATION 317 | SystemSecurityModelInformation, // SYSTEM_SECURITY_MODEL_INFORMATION // since 19H1 318 | SystemCodeIntegritySyntheticCacheInformation, 319 | SystemFeatureConfigurationInformation, // SYSTEM_FEATURE_CONFIGURATION_INFORMATION // since 20H1 // 210 320 | SystemFeatureConfigurationSectionInformation, // SYSTEM_FEATURE_CONFIGURATION_SECTIONS_INFORMATION 321 | SystemFeatureUsageSubscriptionInformation, 322 | SystemSecureSpeculationControlInformation, // SECURE_SPECULATION_CONTROL_INFORMATION 323 | // SystemSpacesBootInformation = 214, 324 | // SystemFwRamdiskInformation = 215, 325 | // SystemWheaIpmiHardwareInformation = 216, 326 | // SystemDifSetRuleClassInformation = 217, 327 | // SystemDifClearRuleClassInformation = 218, 328 | // SystemDifApplyPluginVerificationOnDriver = 219, 329 | // SystemDifRemovePluginVerificationOnDriver = 220, 330 | // SystemShadowStackInformation = 221, // SYSTEM_SHADOW_STACK_INFORMATION 331 | // SystemBuildVersionInformation = 222, // SYSTEM_BUILD_VERSION_INFORMATION 332 | // SystemPoolLimitInformation = 233, 333 | // SystemCodeIntegrityAddDynamicStore = 234, 334 | // SystemCodeIntegrityClearDynamicStores = 235. 335 | // SystemDifPoolTrackingInformation = 236 336 | MaxSystemInfoClass 337 | } SYSTEM_INFORMATION_CLASS; 338 | 339 | typedef enum _KTHREAD_STATE 340 | { 341 | Initialized, 342 | Ready, 343 | Running, 344 | Standby, 345 | Terminated, 346 | Waiting, 347 | Transition, 348 | DeferredReady, 349 | GateWaitObsolete, 350 | WaitingForProcessInSwap, 351 | MaximumThreadState 352 | } KTHREAD_STATE, *PKTHREAD_STATE; 353 | 354 | typedef struct _SYSTEM_THREAD_INFORMATION 355 | { 356 | LARGE_INTEGER KernelTime; 357 | LARGE_INTEGER UserTime; 358 | LARGE_INTEGER CreateTime; 359 | ULONG WaitTime; 360 | PVOID StartAddress; 361 | CLIENT_ID ClientId; 362 | KPRIORITY Priority; 363 | LONG BasePriority; 364 | ULONG ContextSwitches; 365 | KTHREAD_STATE ThreadState; 366 | KWAIT_REASON WaitReason; 367 | } SYSTEM_THREAD_INFORMATION, *PSYSTEM_THREAD_INFORMATION; 368 | 369 | typedef struct _SYSTEM_PROCESS_INFORMATION 370 | { 371 | ULONG NextEntryOffset; 372 | ULONG NumberOfThreads; 373 | LARGE_INTEGER WorkingSetPrivateSize; // since VISTA 374 | ULONG HardFaultCount; // since WIN7 375 | ULONG NumberOfThreadsHighWatermark; // since WIN7 376 | ULONGLONG CycleTime; // since WIN7 377 | LARGE_INTEGER CreateTime; 378 | LARGE_INTEGER UserTime; 379 | LARGE_INTEGER KernelTime; 380 | UNICODE_STRING ImageName; 381 | KPRIORITY BasePriority; 382 | HANDLE UniqueProcessId; 383 | HANDLE InheritedFromUniqueProcessId; 384 | ULONG HandleCount; 385 | ULONG SessionId; 386 | ULONG_PTR UniqueProcessKey; // since VISTA (requires SystemExtendedProcessInformation) 387 | SIZE_T PeakVirtualSize; 388 | SIZE_T VirtualSize; 389 | ULONG PageFaultCount; 390 | SIZE_T PeakWorkingSetSize; 391 | SIZE_T WorkingSetSize; 392 | SIZE_T QuotaPeakPagedPoolUsage; 393 | SIZE_T QuotaPagedPoolUsage; 394 | SIZE_T QuotaPeakNonPagedPoolUsage; 395 | SIZE_T QuotaNonPagedPoolUsage; 396 | SIZE_T PagefileUsage; 397 | SIZE_T PeakPagefileUsage; 398 | SIZE_T PrivatePageCount; 399 | LARGE_INTEGER ReadOperationCount; 400 | LARGE_INTEGER WriteOperationCount; 401 | LARGE_INTEGER OtherOperationCount; 402 | LARGE_INTEGER ReadTransferCount; 403 | LARGE_INTEGER WriteTransferCount; 404 | LARGE_INTEGER OtherTransferCount; 405 | SYSTEM_THREAD_INFORMATION Threads[1]; // SystemProcessInformation 406 | // SYSTEM_EXTENDED_THREAD_INFORMATION Threads[1]; // SystemExtendedProcessinformation 407 | // SYSTEM_EXTENDED_THREAD_INFORMATION + SYSTEM_PROCESS_INFORMATION_EXTENSION // SystemFullProcessInformation 408 | } SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION; 409 | 410 | NTSYSAPI 411 | NTSTATUS 412 | NTAPI 413 | ZwQuerySystemInformation ( 414 | _In_ SYSTEM_INFORMATION_CLASS SystemInformationClass, 415 | _Inout_ PVOID SystemInformation, 416 | _In_ ULONG SystemInformationLength, 417 | _Out_opt_ PULONG ReturnLength 418 | ); 419 | 420 | NTSYSAPI 421 | PIMAGE_NT_HEADERS 422 | RtlImageNtHeader ( 423 | _In_ PVOID BaseAddress 424 | ); 425 | 426 | NTSYSAPI 427 | VOID 428 | KeInitializeApc ( 429 | _In_ PKAPC pAPC, 430 | _In_ PKTHREAD pThread, 431 | _In_ KAPC_ENVIRONMENT TargetEnvironment, 432 | _In_ PVOID KernelRoutine, 433 | _In_ PVOID NormalRoutine, 434 | _In_ KPROCESSOR_MODE ApcMode, 435 | _In_ PVOID pNormalContext 436 | ); 437 | 438 | NTSYSAPI 439 | KeInsertQueueApc ( 440 | _In_ PKAPC pAPC, 441 | _In_ PVOID SystemArgument1, 442 | _In_ PVOID SystemArgument2, 443 | _In_ KPRIORITY Increment 444 | ); 445 | -------------------------------------------------------------------------------- /Trashvisor/ControlCallbacks.c: -------------------------------------------------------------------------------- 1 | #include "ControlCallbacks.h" 2 | #include "VmxUtils.h" 3 | #include "Ept.h" 4 | 5 | #define USER_DIRECTORY_TABLE_BASE_OFFSET 0x280 6 | #define DIRECTORY_TABLE_BASE_OFFSET 0x28 7 | #define PPEB_OFFSET 0x3f8 8 | 9 | KGUARDED_MUTEX CallbacksMutex = { 0 }; 10 | PCPUID_LOGGING_INFO pCpuidLoggingInfo = NULL; 11 | WCHAR ProcessName[MAX_PATH_LENGTH]; 12 | 13 | VOID 14 | CpuidLoggingProcessCallback ( 15 | PEPROCESS Eproc, 16 | HANDLE ProcessId, 17 | PPS_CREATE_NOTIFY_INFO pCreateInfo 18 | ) 19 | { 20 | if (pCpuidLoggingInfo == NULL) 21 | return; 22 | 23 | if (pCreateInfo == NULL) 24 | { 25 | if (ProcessId != pCpuidLoggingInfo->ProcessId) 26 | return; 27 | 28 | __debugbreak(); 29 | 30 | for (int i = 0; i < pCpuidLoggingInfo->CurrentDataLine; i++) 31 | { 32 | CPUID_DATA_LINE DataLine = pCpuidLoggingInfo->LoggingData[i]; 33 | 34 | CHAR Buffer[sizeof(CPUID_DATA_LINE)]; 35 | 36 | RtlCopyMemory( 37 | Buffer, 38 | &DataLine, 39 | sizeof(CPUID_DATA_LINE) 40 | ); 41 | 42 | IO_STATUS_BLOCK IoStatusBlock; 43 | 44 | NTSTATUS Status = ZwWriteFile( 45 | pCpuidLoggingInfo->FileHandle, 46 | NULL, 47 | NULL, 48 | NULL, 49 | &IoStatusBlock, 50 | Buffer, 51 | sizeof(CPUID_DATA_LINE), 52 | NULL, 53 | NULL 54 | ); 55 | 56 | if (!NT_SUCCESS(Status)) 57 | { 58 | KdPrintError("Write failed.\n"); 59 | } 60 | } 61 | 62 | ZwClose(pCpuidLoggingInfo->FileHandle); 63 | 64 | ExFreePoolWithTag(pCpuidLoggingInfo, 'DICP'); 65 | 66 | pCpuidLoggingInfo = NULL; 67 | 68 | return; 69 | } 70 | 71 | PCHAR pKproc = (PCHAR)Eproc; 72 | PCHAR pEproc = (PCHAR)Eproc; 73 | 74 | PWCHAR Found = wcsstr( 75 | pCreateInfo->CommandLine->Buffer, 76 | ProcessName 77 | ); 78 | 79 | if (Found != NULL) 80 | { 81 | // Get UserDirectoryTableBase, introduced post-meltdown 82 | // DirectoryTableBase is the Kernel Cr3 83 | CR3 Cr3ToTrack; 84 | Cr3ToTrack.Flags = *(PULONG64)(pKproc + USER_DIRECTORY_TABLE_BASE_OFFSET); 85 | 86 | CR3 KernelCr3; 87 | KernelCr3.Flags = *(PULONG64)(pKproc + DIRECTORY_TABLE_BASE_OFFSET); 88 | 89 | PLIST_ENTRY Current = (PLIST_ENTRY)(pEproc + 0x488); 90 | 91 | pCpuidLoggingInfo->ProcessId = ProcessId; 92 | pCpuidLoggingInfo->UserCr3 = Cr3ToTrack; 93 | pCpuidLoggingInfo->KernelCr3 = KernelCr3; 94 | 95 | pCpuidLoggingInfo->pPeb = (PPEB) * (PUINT64)(pEproc + PPEB_OFFSET); 96 | 97 | KdPrintError("Tracking CR3: 0x%llx\n", Cr3ToTrack.Flags); 98 | } 99 | } 100 | 101 | NTSTATUS 102 | CtrlLogCpuidForProcess ( 103 | PDEVICE_OBJECT pDeviceObject, 104 | PIRP pIrp 105 | ) 106 | { 107 | NTSTATUS Status = STATUS_SUCCESS; 108 | 109 | PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp); 110 | 111 | PINFO_IOCTL_CPUID_PROCESS pIoctlInfo = 112 | (PINFO_IOCTL_CPUID_PROCESS)pIrp->AssociatedIrp.SystemBuffer; 113 | 114 | UINT32 InputLength = pIrpStack->Parameters.DeviceIoControl.InputBufferLength; 115 | 116 | // Verify length 117 | if (sizeof(INFO_IOCTL_CPUID_PROCESS) > InputLength) 118 | { 119 | Status = STATUS_BUFFER_OVERFLOW; 120 | goto Exit; 121 | } 122 | 123 | // Verify parameters 124 | if (wcslen(pIoctlInfo->ProcessName) > MAX_PATH_LENGTH) 125 | { 126 | Status = STATUS_INVALID_PARAMETER; 127 | goto Exit; 128 | } 129 | 130 | if (wcslen(pIoctlInfo->FilePath) > MAX_PATH_LENGTH || 131 | sizeof(pIoctlInfo->FilePath) != sizeof(ProcessName)) 132 | { 133 | Status = STATUS_INVALID_PARAMETER; 134 | goto Exit; 135 | } 136 | 137 | KdPrintError( 138 | "Received: Process name => %S\nFile path => %S\n", 139 | pIoctlInfo->ProcessName, 140 | pIoctlInfo->FilePath 141 | ); 142 | 143 | memcpy(ProcessName, pIoctlInfo->ProcessName, sizeof(ProcessName)); 144 | 145 | // Next stage of validation/creation 146 | // Attempt to create a file with the name 147 | HANDLE FileHandle; 148 | 149 | OBJECT_ATTRIBUTES Oa; 150 | UNICODE_STRING FilePath; 151 | 152 | RtlInitUnicodeString(&FilePath, pIoctlInfo->FilePath); 153 | 154 | InitializeObjectAttributes( 155 | &Oa, 156 | &FilePath, 157 | OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, 158 | NULL, 159 | NULL 160 | ); 161 | 162 | IO_STATUS_BLOCK IoStatusBlock; 163 | 164 | __debugbreak(); 165 | 166 | if (pCpuidLoggingInfo != NULL) 167 | { 168 | ZwClose(pCpuidLoggingInfo->FileHandle); 169 | 170 | ExFreePoolWithTag(pCpuidLoggingInfo, 'DICP'); 171 | } 172 | 173 | pCpuidLoggingInfo = ExAllocatePoolWithTag(NonPagedPoolNx, 174 | FIELD_OFFSET(CPUID_LOGGING_INFO, LoggingData[pIoctlInfo->LogCount]), 175 | 'DICP'); 176 | 177 | if (pCpuidLoggingInfo == NULL) 178 | { 179 | KdPrintError("CtrlLogCpuidForProcess: ExAllocatePoolWithTag could not allocate memory.\n"); 180 | goto Exit; 181 | } 182 | 183 | pCpuidLoggingInfo->MaxLogCount = pIoctlInfo->LogCount; 184 | pCpuidLoggingInfo->CurrentDataLine = 0; 185 | 186 | Status = ZwCreateFile( 187 | &FileHandle, 188 | FILE_WRITE_DATA | FILE_READ_ACCESS, 189 | &Oa, 190 | &IoStatusBlock, 191 | NULL, 192 | FILE_ATTRIBUTE_NORMAL, 193 | 0, 194 | FILE_OVERWRITE_IF, 195 | FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_ALERT, 196 | NULL, 197 | 0 198 | ); 199 | 200 | if (!NT_SUCCESS(Status)) 201 | { 202 | KdPrintError( 203 | "CtrlLogCpuidProcess: ZwCreateFile failed with: 0x%x\n", 204 | Status 205 | ); 206 | 207 | goto Exit; 208 | } 209 | 210 | pCpuidLoggingInfo->FileHandle = FileHandle; 211 | 212 | Status = PsSetCreateProcessNotifyRoutineEx2( 213 | PsCreateProcessNotifySubsystems, 214 | CpuidLoggingProcessCallback, 215 | FALSE 216 | ); 217 | 218 | if (!NT_SUCCESS(Status)) 219 | { 220 | __debugbreak(); 221 | KdPrintError( 222 | "CtrlLogCpuidProcess: PsSetCreateProcessNotifyRoutineEx2 failed with: 0x%x\n", 223 | Status 224 | ); 225 | } 226 | 227 | Exit: 228 | return Status; 229 | } 230 | 231 | NTSTATUS 232 | CtrlAddEptHook ( 233 | PDEVICE_OBJECT pDeviceObject, 234 | PIRP pIrp 235 | ) 236 | { 237 | //__debugbreak(); 238 | 239 | NTSTATUS Status = STATUS_SUCCESS; 240 | 241 | PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp); 242 | PINFO_IOCTL_EPT_HOOK_INFO pEptHookInfo = pIrp->AssociatedIrp.SystemBuffer; 243 | ULONG64 BufferLength = pIrpStack->Parameters.DeviceIoControl.InputBufferLength; 244 | PSYSTEM_PROCESS_INFORMATION pSystemProcessInfo = NULL; 245 | PSYSTEM_PROCESS_INFORMATION CurrentEntry = NULL; 246 | 247 | if (BufferLength < sizeof(INFO_IOCTL_EPT_HOOK_INFO)) 248 | { 249 | Status = STATUS_BUFFER_OVERFLOW; 250 | goto Exit; 251 | } 252 | 253 | ULONG ProcessInfoSize = 0; 254 | 255 | Status = ZwQuerySystemInformation( 256 | SystemProcessInformation, 257 | pSystemProcessInfo, 258 | 0, 259 | &ProcessInfoSize 260 | ); 261 | 262 | // Force length mismatch to get the required size 263 | if (Status != STATUS_INFO_LENGTH_MISMATCH) 264 | { 265 | KdPrintError( 266 | "CtrlAddEptHook: ZwQuerySystemInformation failed with status 0x%x.\n", 267 | Status 268 | ); 269 | goto Exit; 270 | } 271 | 272 | pSystemProcessInfo = ExAllocatePoolWithTag( 273 | NonPagedPoolNx, 274 | 2 * ProcessInfoSize, 275 | 'OFNI' 276 | ); 277 | 278 | Status = ZwQuerySystemInformation( 279 | SystemProcessInformation, 280 | pSystemProcessInfo, 281 | 2 * ProcessInfoSize, 282 | NULL 283 | ); 284 | 285 | if (!NT_SUCCESS(Status)) 286 | { 287 | KdPrintError( 288 | "CtrlAddEptHook: ZwQuerySystemInformation failed with status 0x%x.\n", 289 | Status 290 | ); 291 | goto Exit; 292 | } 293 | 294 | CurrentEntry = pSystemProcessInfo; 295 | PCHAR pTargetEproc = NULL; 296 | 297 | while (TRUE) 298 | { 299 | if (CurrentEntry->UniqueProcessId == 0) 300 | { 301 | CurrentEntry = (PSYSTEM_PROCESS_INFORMATION) 302 | ((PCHAR)CurrentEntry + CurrentEntry->NextEntryOffset); 303 | continue; 304 | } 305 | 306 | HANDLE ProcessHandle; 307 | CLIENT_ID ClientId = { CurrentEntry->UniqueProcessId, NULL }; 308 | OBJECT_ATTRIBUTES ObjectAttributes; 309 | 310 | InitializeObjectAttributes( 311 | &ObjectAttributes, 312 | NULL, 313 | OBJ_KERNEL_HANDLE, 314 | NULL, 315 | NULL 316 | ); 317 | 318 | Status = ZwOpenProcess( 319 | &ProcessHandle, 320 | PROCESS_ALL_ACCESS, 321 | &ObjectAttributes, 322 | &ClientId 323 | ); 324 | 325 | if (!NT_SUCCESS(Status)) 326 | { 327 | KdPrintError( 328 | "CtrlAddEptHook: ZwOpenProcess failed with status 0x%x.\n", 329 | Status 330 | ); 331 | goto Exit; 332 | } 333 | 334 | PEPROCESS pEprocess; 335 | 336 | Status = ObReferenceObjectByHandle( 337 | ProcessHandle, 338 | PROCESS_ALL_ACCESS, 339 | *PsProcessType, 340 | KernelMode, 341 | &pEprocess, 342 | NULL 343 | ); 344 | 345 | if (!NT_SUCCESS(Status)) 346 | { 347 | KdPrintError( 348 | "CtrlAddEptHook: ObReferenceObjectByHandle failed with status 0x%x.\n", 349 | Status 350 | ); 351 | goto Exit; 352 | } 353 | 354 | PCHAR pProcessId = (PCHAR)pEprocess + 0x2e8; 355 | 356 | UINT64 Pid; 357 | 358 | RtlCopyMemory( 359 | &Pid, 360 | pProcessId, 361 | sizeof(Pid) 362 | ); 363 | 364 | if (Pid == pEptHookInfo->ProcessId) 365 | { 366 | KdPrintError("Found pid!\n"); 367 | //__debugbreak(); 368 | pTargetEproc = (PCHAR)pEprocess; 369 | break; 370 | } 371 | 372 | if (CurrentEntry->NextEntryOffset == 0) 373 | break; 374 | 375 | CurrentEntry = (PSYSTEM_PROCESS_INFORMATION) 376 | ((PCHAR)CurrentEntry + CurrentEntry->NextEntryOffset); 377 | } 378 | 379 | if (pTargetEproc == NULL) 380 | { 381 | KdPrintError("Could not find target pid.\n"); 382 | goto Exit; 383 | } 384 | 385 | UINT64 Dtb = *(PUINT64)(pTargetEproc + 0x28); 386 | UINT64 StoredCr3 = __readcr3(); 387 | 388 | //HypervisorBreak(); 389 | 390 | KAPC_STATE ApcState; 391 | KeStackAttachProcess((PRKPROCESS)pTargetEproc, &ApcState); 392 | 393 | /* 394 | _cli(); 395 | __writecr3(Dtb); 396 | */ 397 | 398 | EptCreateHook( 399 | pEptHookInfo->VirtualAddress, 400 | pEptHookInfo->ModifiedPage, 401 | pEptHookInfo->OriginalPage, 402 | pTargetEproc 403 | ); 404 | 405 | KeUnstackDetachProcess(&ApcState); 406 | 407 | /* 408 | __writecr3(StoredCr3); 409 | _sti(); 410 | */ 411 | 412 | Exit: 413 | return Status; 414 | } -------------------------------------------------------------------------------- /Trashvisor/ControlCallbacks.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Extern.h" 3 | #include "Shared.h" 4 | #include "ArchUtils.h" 5 | 6 | #define MAX_MODULE_LENGTH 30 7 | 8 | typedef struct _CPUID_DATA_LINE 9 | { 10 | UINT32 CpuidRax; 11 | UINT64 CpuidModuleRva; 12 | WCHAR ModuleName[MAX_MODULE_LENGTH]; 13 | } CPUID_DATA_LINE, *PCPUID_DATA_LINE; 14 | 15 | typedef struct _CPUID_LOGGING_INFO 16 | { 17 | HANDLE FileHandle; 18 | HANDLE ProcessId; 19 | CR3 UserCr3; 20 | CR3 KernelCr3; 21 | PPEB pPeb; 22 | UINT32 CurrentDataLine; 23 | UINT32 MaxLogCount; 24 | CPUID_DATA_LINE LoggingData[0]; 25 | } CPUID_LOGGING_INFO, *PCPUID_LOGGING_INFO; 26 | 27 | extern KGUARDED_MUTEX CallbacksMutex; 28 | extern PCPUID_LOGGING_INFO pCpuidLoggingInfo; 29 | 30 | NTSTATUS 31 | CtrlLogCpuidForProcess ( 32 | PDEVICE_OBJECT pDeviceObject, 33 | PIRP pIrp 34 | ); 35 | 36 | NTSTATUS 37 | CtrlAddEptHook ( 38 | PDEVICE_OBJECT pDeviceObject, 39 | PIRP pIrp 40 | ); -------------------------------------------------------------------------------- /Trashvisor/Ept.c: -------------------------------------------------------------------------------- 1 | #include "Ept.h" 2 | #include "VmxUtils.h" 3 | 4 | BOOLEAN 5 | IsEptSupported ( 6 | ) 7 | { 8 | IA32_VMX_EPT_VPID_CAP_REGISTER EptVpidCapRegister; 9 | IA32_MTRR_DEF_TYPE_REGISTER MtrrDefTypeRegister; 10 | 11 | EptVpidCapRegister.Flags = ReadMsr(IA32_VMX_EPT_VPID_CAP); 12 | MtrrDefTypeRegister.Flags = ReadMsr(IA32_MTRR_DEF_TYPE); 13 | 14 | if (!EptVpidCapRegister.ExecuteOnlyPages 15 | || !EptVpidCapRegister.PageWalkLength4 16 | || !EptVpidCapRegister.MemoryTypeWriteBack) 17 | { 18 | KdPrintError("VmxEpt capabilities not supported.\n"); 19 | return FALSE; 20 | } 21 | 22 | return TRUE; 23 | } 24 | 25 | _Use_decl_annotations_ 26 | VOID 27 | SetupContextEptInformation ( 28 | ) 29 | { 30 | IA32_MTRR_CAPABILITIES_REGISTER MtrrCapRegister; 31 | IA32_MTRR_PHYSBASE_REGISTER MtrrPhysBase; 32 | IA32_MTRR_PHYSMASK_REGISTER MtrrPhysMask; 33 | 34 | MtrrCapRegister.Flags = ReadMsr(IA32_MTRR_CAPABILITIES); 35 | 36 | for (int i = 0; i < MtrrCapRegister.VariableRangeCount; i++) 37 | { 38 | MtrrPhysBase.Flags = ReadMsr(IA32_MTRR_PHYSBASE0 + i * 2); 39 | MtrrPhysMask.Flags = ReadMsr(IA32_MTRR_PHYSMASK0 + i * 2); 40 | 41 | if (!MtrrPhysMask.Valid) 42 | continue; 43 | 44 | UINT64 Mask = MtrrPhysMask.PageFrameNumber; 45 | 46 | UINT64 BeginAddress = MtrrPhysBase.PageFrameNumber << 12; 47 | UINT64 EndAddress = BeginAddress + (Mask << 12) - 1; 48 | 49 | pGlobalVmmContext->EptMtrrDescriptors[i].BeginAddress = BeginAddress; 50 | pGlobalVmmContext->EptMtrrDescriptors[i].EndAddress = EndAddress; 51 | pGlobalVmmContext->EptMtrrDescriptors[i].MemoryType = MtrrPhysBase.Type; 52 | } 53 | } 54 | 55 | PEPT_REGION 56 | GenerateEptTables ( 57 | ) 58 | { 59 | PHYSICAL_ADDRESS PA; 60 | PA.QuadPart = MAXULONG64; 61 | 62 | //__debugbreak(); 63 | 64 | PEPT_REGION pEptRegion = MmAllocateContiguousMemory(sizeof(EPT_REGION), PA); 65 | 66 | if (pEptRegion == NULL) 67 | { 68 | KdPrintError("GenerateEptTables: MmAllocateContiguousMemory failed.\n"); 69 | goto Exit; 70 | } 71 | 72 | RtlZeroMemory( 73 | pEptRegion, 74 | sizeof(EPT_REGION) 75 | ); 76 | 77 | InitializeListHead(&pEptRegion->SplitList); 78 | InitializeListHead(&pEptRegion->HookList); 79 | 80 | pEptRegion->Pml4[0].Flags = 0; 81 | pEptRegion->Pml4[0].PageFrameNumber = 82 | MmGetPhysicalAddress(&pEptRegion->Pdpt[0]).QuadPart / PAGE_SIZE; 83 | pEptRegion->Pml4[0].ReadAccess = 1; 84 | pEptRegion->Pml4[0].WriteAccess = 1; 85 | pEptRegion->Pml4[0].ExecuteAccess = 1; 86 | 87 | for (int i = 0; i < PDPT_ENTRY_COUNT; i++) 88 | { 89 | pEptRegion->Pdpt[i].Flags = 0; 90 | pEptRegion->Pdpt[i].PageFrameNumber = 91 | MmGetPhysicalAddress(&pEptRegion->Pdt[i][0]).QuadPart / PAGE_SIZE; 92 | pEptRegion->Pdpt[i].ReadAccess = 1; 93 | pEptRegion->Pdpt[i].WriteAccess = 1; 94 | pEptRegion->Pdpt[i].ExecuteAccess = 1; 95 | } 96 | 97 | IA32_MTRR_CAPABILITIES_REGISTER MtrrCapRegister; 98 | 99 | MtrrCapRegister.Flags = ReadMsr(IA32_MTRR_CAPABILITIES); 100 | 101 | for (int i = 0; i < PDPT_ENTRY_COUNT; i++) 102 | { 103 | for (int j = 0; j < PDT_ENTRY_COUNT; j++) 104 | { 105 | PEPDE pEpde = &pEptRegion->Pdt[i][j]; 106 | pEpde->Flags = 0; 107 | pEpde->PageFrameNumber = i * PDT_ENTRY_COUNT + j; 108 | pEpde->ReadAccess = 1; 109 | pEpde->WriteAccess = 1; 110 | pEpde->ExecuteAccess = 1; 111 | pEpde->LargePage = 1; 112 | 113 | if (i == 0 && j == 0) 114 | { 115 | pEpde->MemoryType = MEMORY_TYPE_UNCACHEABLE; 116 | continue; 117 | } 118 | 119 | pEpde->MemoryType = MEMORY_TYPE_WRITE_BACK; 120 | 121 | for (int k = 0; k < MtrrCapRegister.VariableRangeCount; k++) 122 | { 123 | EPT_MTRR_DESCRIPTOR EptMtrrDescriptor = pGlobalVmmContext->EptMtrrDescriptors[k]; 124 | 125 | if (pEpde->PageFrameNumber >= EptMtrrDescriptor.BeginAddress 126 | && pEpde->PageFrameNumber + LARGE_PAGE_SIZE - 1 <= EptMtrrDescriptor.EndAddress) 127 | { 128 | pEpde->MemoryType = EptMtrrDescriptor.MemoryType; 129 | break; 130 | } 131 | } 132 | } 133 | } 134 | 135 | Exit: 136 | return pEptRegion; 137 | } 138 | 139 | BOOLEAN 140 | SetupEptp ( 141 | ) 142 | { 143 | //__debugbreak(); 144 | BOOLEAN Status = TRUE; 145 | 146 | EPT_POINTER EptPointer; 147 | EptPointer.Flags = 0; 148 | 149 | PEPT_REGION pEptRegion = GenerateEptTables(); 150 | 151 | if (pEptRegion == NULL) 152 | { 153 | KdPrintError("SetupEptp failed.\n"); 154 | Status = FALSE; 155 | goto Exit; 156 | } 157 | 158 | EptPointer.PageFrameNumber = 159 | MmGetPhysicalAddress(&pEptRegion->Pml4[0]).QuadPart / PAGE_SIZE; 160 | EptPointer.PageWalkLength = 3; 161 | EptPointer.MemoryType = MEMORY_TYPE_WRITE_BACK; 162 | 163 | pGlobalVmmContext->EptPointer.Flags = EptPointer.Flags; 164 | pGlobalVmmContext->pEptRegion = pEptRegion; 165 | /* 166 | pLocalVmmContext->EptPointer.Flags = EptPointer.Flags; 167 | pLocalVmmContext->pEptRegion = pEptRegion; 168 | */ 169 | 170 | Exit: 171 | return Status; 172 | } 173 | 174 | _Use_decl_annotations_ 175 | BOOLEAN 176 | Split2MBPage ( 177 | UINT64 VirtualAddress 178 | ) 179 | { 180 | UINT32 PdptIndex = GET_PDPT_INDEX(VirtualAddress); 181 | UINT32 PdtIndex = GET_PDT_INDEX(VirtualAddress); 182 | BOOLEAN Status = TRUE; 183 | 184 | PEPT_REGION pEptRegion = pGlobalVmmContext->pEptRegion; 185 | 186 | PEPDE pEpde = &pEptRegion->Pdt[PdptIndex][PdtIndex]; 187 | 188 | if (!pEpde->LargePage) 189 | { 190 | //__debugbreak(); 191 | KdPrintError("Already split page.\n"); 192 | goto Exit; 193 | } 194 | 195 | PHYSICAL_ADDRESS PhysAddress; 196 | PhysAddress.QuadPart = MAXULONG64; 197 | 198 | PEPT_SPLIT_LARGE_PAGE pSplitPage = 199 | MmAllocateContiguousMemory(sizeof(EPT_SPLIT_LARGE_PAGE), PhysAddress); 200 | 201 | if (pSplitPage == NULL) 202 | { 203 | KdPrintError("Split2MBPage: Could not allocate memory.\n"); 204 | Status = FALSE; 205 | goto Exit; 206 | } 207 | 208 | RtlZeroMemory( 209 | pSplitPage, 210 | sizeof(EPT_SPLIT_LARGE_PAGE) 211 | ); 212 | 213 | pSplitPage->Epde = *pEpde; 214 | 215 | pEpde->LargePage = 0; 216 | 217 | UINT64 FrameOffset = pEpde->PageFrameNumber * (LARGE_PAGE_SIZE / PAGE_SIZE); 218 | 219 | for (int i = 0; i < PT_ENTRY_SPLIT_COUNT; i++) 220 | { 221 | pSplitPage->Pte[i].ReadAccess = 1; 222 | pSplitPage->Pte[i].WriteAccess = 1; 223 | pSplitPage->Pte[i].ExecuteAccess = 1; 224 | pSplitPage->Pte[i].PageFrameNumber = i + FrameOffset; 225 | } 226 | 227 | EPDE NewEpde; 228 | NewEpde.Flags = 0; 229 | 230 | NewEpde.ReadAccess = 1; 231 | NewEpde.WriteAccess = 1; 232 | NewEpde.ExecuteAccess = 1; 233 | NewEpde.PageFrameNumber = 234 | MmGetPhysicalAddress(&pSplitPage->Pte[0]).QuadPart / PAGE_SIZE; 235 | 236 | RtlCopyMemory( 237 | pEpde, 238 | &NewEpde, 239 | sizeof(NewEpde) 240 | ); 241 | 242 | InsertHeadList( 243 | &pGlobalVmmContext->pEptRegion->SplitList, 244 | &pSplitPage->SplitListEntry 245 | ); 246 | 247 | Exit: 248 | return Status; 249 | } 250 | 251 | _Use_decl_annotations_ 252 | BOOLEAN 253 | EptCreateHook ( 254 | UINT64 VirtualAddress, 255 | PCHAR FakePage, 256 | PCHAR OriginalPage, 257 | PEPROCESS pTargetEproc 258 | ) 259 | { 260 | BOOLEAN Status = TRUE; 261 | 262 | //Page in virtual address 263 | __writecr4(__readcr4() & ~CR4_SMAP_ENABLE_FLAG); 264 | volatile INT32 PageReader; 265 | PageReader = *(PINT32)VirtualAddress; 266 | __writecr4(__readcr4() | CR4_SMAP_ENABLE_FLAG); 267 | 268 | UINT64 PhysicalAddress = MmGetPhysicalAddress((PVOID)VirtualAddress).QuadPart; 269 | 270 | KdPrintError("Installing hook for physical address => 0x%llx\n", PhysicalAddress); 271 | 272 | //__debugbreak(); 273 | UINT32 PdptIndex = GET_PDPT_INDEX(PhysicalAddress); 274 | UINT32 PdtIndex = GET_PDT_INDEX(PhysicalAddress); 275 | UINT32 PtIndex = 0; 276 | 277 | EPT_INVEPT_DESCRIPTOR InvEptDescriptor; 278 | InvEptDescriptor.Reserved = 0; 279 | 280 | PEPT_HOOKED_ENTRY pEptHookedEntry = ExAllocatePoolWithTag( 281 | NonPagedPool, 282 | sizeof(EPT_HOOKED_ENTRY), 283 | 'ETPE' 284 | ); 285 | 286 | if (pEptHookedEntry == NULL) 287 | { 288 | KdPrintError("EptCreateHook: ExAllocatePoolWithTag failed to allocate memory.\n"); 289 | Status = FALSE; 290 | goto Exit; 291 | } 292 | 293 | PEPDE pEpde = &pGlobalVmmContext->pEptRegion->Pdt[PdptIndex][PdtIndex]; 294 | PEPDE_SPLIT pEpdte = (PEPDE_SPLIT)pEpde; 295 | 296 | if (pEpde->LargePage) 297 | { 298 | if (!Split2MBPage(PhysicalAddress)) 299 | { 300 | Status = FALSE; 301 | goto Exit; 302 | } 303 | } 304 | 305 | PtIndex = GET_PT_INDEX(PhysicalAddress); 306 | 307 | PHYSICAL_ADDRESS PhysAddr; 308 | PhysAddr.QuadPart = pEpdte->PageFrameNumber * PAGE_SIZE; 309 | 310 | PEPTE pPageTable = MmGetVirtualForPhysical(PhysAddr); 311 | PEPTE pOriginalEntry = &pPageTable[PtIndex]; 312 | 313 | pEptHookedEntry->VirtBaseAddress = VirtualAddress; 314 | pEptHookedEntry->PhysBaseAddress = PhysicalAddress; 315 | 316 | pEptHookedEntry->pPte = pOriginalEntry; 317 | pEptHookedEntry->OriginalEntry = *pOriginalEntry; 318 | 319 | pEptHookedEntry->ExecuteOnlyEntry.Flags = pOriginalEntry->Flags; 320 | pEptHookedEntry->ExecuteOnlyEntry.ExecuteAccess = 1; 321 | pEptHookedEntry->ExecuteOnlyEntry.ReadAccess = 0; 322 | pEptHookedEntry->ExecuteOnlyEntry.WriteAccess = 0; 323 | 324 | pEptHookedEntry->NoExecuteEntry.Flags = pOriginalEntry->Flags; 325 | pEptHookedEntry->NoExecuteEntry.ExecuteAccess = 0; 326 | pEptHookedEntry->NoExecuteEntry.ReadAccess = 1; 327 | pEptHookedEntry->NoExecuteEntry.WriteAccess = 1; 328 | 329 | pEptHookedEntry->ExecuteOnlyEntry.PageFrameNumber = 330 | MmGetPhysicalAddress(pEptHookedEntry->FakePage).QuadPart / PAGE_SIZE; 331 | 332 | RtlCopyMemory( 333 | pEptHookedEntry->FakePage, 334 | FakePage, 335 | PAGE_SIZE 336 | ); 337 | 338 | RtlCopyMemory( 339 | pEptHookedEntry->OriginalPage, 340 | OriginalPage, 341 | PAGE_SIZE 342 | ); 343 | 344 | PCHAR pEprocBytes = (PCHAR)pTargetEproc; 345 | 346 | pEptHookedEntry->ProcessKernelCr3.Flags = *(PUINT64)(pEprocBytes + 0x28); 347 | 348 | InsertHeadList( 349 | &pGlobalVmmContext->pEptRegion->HookList, 350 | &pEptHookedEntry->EptHookedListEntry 351 | ); 352 | 353 | *pOriginalEntry = pEptHookedEntry->NoExecuteEntry; 354 | InvEptDescriptor.EptPointer = pGlobalVmmContext->EptPointer.Flags; 355 | 356 | //_invept(InveptAllContext, &InvEptDescriptor); 357 | 358 | Exit: 359 | return Status; 360 | } 361 | -------------------------------------------------------------------------------- /Trashvisor/Ept.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "ArchUtils.h" 3 | 4 | #define PML4_ENTRY_COUNT (1 << 9) 5 | #define PDPT_ENTRY_COUNT (1 << 9) 6 | #define PDT_ENTRY_COUNT (1 << 9) 7 | #define PT_ENTRY_SPLIT_COUNT (1 << 9) 8 | #define PT_ENTRY_COUNT (1 << 12) 9 | 10 | #define LARGE_PAGE_SIZE 0x200000 11 | 12 | typedef struct _GLOBAL_VMM_CONTEXT *PGLOBAL_VMM_CONTEXT; 13 | typedef struct _LOCAL_VMM_CONTEXT *PLOCAL_VMM_CONTEXT; 14 | 15 | typedef EPDE_2MB *PEPDE; 16 | typedef EPDE *PEPDE_SPLIT; 17 | typedef EPTE *PEPTE; 18 | 19 | extern PGLOBAL_VMM_CONTEXT pGlobalVmmContext; 20 | 21 | #define GET_PML4_INDEX(Address) (Address >> 39) & 0x1ff 22 | #define GET_PDPT_INDEX(Address) (Address >> 30) & 0x1ff 23 | #define GET_PDT_INDEX(Address) (Address >> 21) & 0x1ff 24 | #define GET_PT_INDEX(Address) (Address >> 12) & 0x1ff 25 | #define GET_PTE_INDEX(Address) (Address) & 0x1ff 26 | 27 | typedef struct _EPT_REGION 28 | { 29 | DECLSPEC_ALIGN(PAGE_SIZE) EPT_PML4 Pml4[PML4_ENTRY_COUNT]; 30 | DECLSPEC_ALIGN(PAGE_SIZE) EPDPTE Pdpt[PDPT_ENTRY_COUNT]; 31 | DECLSPEC_ALIGN(PAGE_SIZE) EPDE_2MB Pdt[PDPT_ENTRY_COUNT][PDT_ENTRY_COUNT]; 32 | 33 | LIST_ENTRY SplitList; 34 | LIST_ENTRY HookList; 35 | } EPT_REGION, *PEPT_REGION; 36 | 37 | typedef struct _EPT_SPLIT_LARGE_PAGE 38 | { 39 | DECLSPEC_ALIGN(PAGE_SIZE) EPTE Pte[PT_ENTRY_SPLIT_COUNT]; 40 | EPDE_2MB Epde; 41 | LIST_ENTRY SplitListEntry; 42 | } EPT_SPLIT_LARGE_PAGE, *PEPT_SPLIT_LARGE_PAGE; 43 | 44 | typedef struct _EPT_HOOKED_ENTRY 45 | { 46 | DECLSPEC_ALIGN(PAGE_SIZE) CHAR OriginalPage[PAGE_SIZE]; 47 | DECLSPEC_ALIGN(PAGE_SIZE) CHAR FakePage[PAGE_SIZE]; 48 | LIST_ENTRY EptHookedListEntry; 49 | UINT64 PhysBaseAddress; 50 | UINT64 VirtBaseAddress; 51 | CR3 ProcessKernelCr3; 52 | 53 | PEPTE pPte; 54 | EPTE OriginalEntry; 55 | EPTE ExecuteOnlyEntry; 56 | EPTE NoExecuteEntry; 57 | } EPT_HOOKED_ENTRY, *PEPT_HOOKED_ENTRY; 58 | 59 | typedef struct _EPT_MTRR_DESCRIPTOR 60 | { 61 | UINT64 BeginAddress; 62 | UINT64 EndAddress; 63 | UINT8 MemoryType; 64 | } EPT_MTRR_DESCRIPTOR, *PEPT_MTRR_DESCRIPTOR; 65 | 66 | typedef struct _EPT_INVEPT_DESCRIPTOR 67 | { 68 | UINT64 EptPointer; 69 | UINT64 Reserved; 70 | } EPT_INVEPT_DESCRIPTOR, *PEPT_INVEPT_DESCRIPTOR; 71 | 72 | BOOLEAN 73 | IsEptSupported ( 74 | ); 75 | 76 | VOID 77 | SetupContextEptInformation ( 78 | ); 79 | 80 | PEPT_REGION 81 | GenerateEptTables ( 82 | ); 83 | 84 | BOOLEAN 85 | SetupEptp ( 86 | ); 87 | 88 | BOOLEAN 89 | EptCreateHook ( 90 | _In_ UINT64 VirtualAddress, 91 | _In_ PCHAR FakePage, 92 | _In_ PCHAR OriginalPage, 93 | _In_ PEPROCESS pTargetEproc 94 | ); 95 | 96 | VOID 97 | _invept ( 98 | UINT64 InvEptType, 99 | PEPT_INVEPT_DESCRIPTOR pInvEptDescriptor 100 | ); 101 | -------------------------------------------------------------------------------- /Trashvisor/Extern.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | //#include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | NTSYSAPI 9 | NTSTATUS 10 | KeGenericCallDpc ( 11 | _In_ PKDEFERRED_ROUTINE Routine, 12 | _In_ PVOID pContext 13 | ); 14 | 15 | NTSYSAPI 16 | VOID 17 | KeSignalCallDpcDone ( 18 | _In_ PVOID SystemArgument1 19 | ); 20 | 21 | NTSYSAPI 22 | LOGICAL 23 | KeSignalCallDpcSynchronize ( 24 | _In_ PVOID SystemArgument2 25 | ); 26 | 27 | NTSYSAPI 28 | VOID 29 | RtlCaptureContext( 30 | _Out_ PCONTEXT ContextRecord 31 | ); 32 | -------------------------------------------------------------------------------- /Trashvisor/Intrinsics.asm: -------------------------------------------------------------------------------- 1 | .code 2 | 3 | _str PROC 4 | str ax 5 | ret 6 | _str ENDP 7 | 8 | _sldt PROC 9 | sldt ax 10 | ret 11 | _sldt ENDP 12 | 13 | _cli PROC 14 | cli 15 | ret 16 | _cli ENDP 17 | 18 | _sti PROC 19 | sti 20 | ret 21 | _sti ENDP 22 | 23 | _invept PROC 24 | invept rcx, OWORD PTR [rdx] 25 | ret 26 | _invept ENDP 27 | 28 | HypervisorBreak PROC 29 | pushfq 30 | cli 31 | x: 32 | jmp x 33 | popfq 34 | ret 35 | HypervisorBreak ENDP 36 | 37 | END -------------------------------------------------------------------------------- /Trashvisor/Shared.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define MAX_PATH_LENGTH 256 4 | 5 | #define NT_DEVICE_NAME L"\\Device\\Trash" 6 | #define DOS_DEVICE_NAME L"\\DosDevices\\Trash" 7 | #define WIN32_DEVICE_NAME L"\\\\.\\Trash" 8 | 9 | #define CODE_LOG_CPUID_PROCESS 0x800 10 | #define CODE_LOG_EPT_HOOK 0x801 11 | 12 | #define IOCTL_LOG_CPUID_PROCESS CTL_CODE(FILE_DEVICE_UNKNOWN, CODE_LOG_CPUID_PROCESS, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) 13 | #define IOCTL_ADD_EPT_HOOK CTL_CODE(FILE_DEVICE_UNKNOWN, CODE_LOG_EPT_HOOK, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) 14 | 15 | typedef struct _INFO_IOCTL_CPUID_PROCESS 16 | { 17 | WCHAR ProcessName[MAX_PATH_LENGTH]; 18 | WCHAR FilePath[MAX_PATH_LENGTH]; 19 | 20 | UINT32 LogCount; 21 | } INFO_IOCTL_CPUID_PROCESS, *PINFO_IOCTL_CPUID_PROCESS; 22 | 23 | typedef struct _INFO_IOCTL_EPT_HOOK_INFO 24 | { 25 | CHAR OriginalPage[0x1000]; 26 | CHAR ModifiedPage[0x1000]; 27 | UINT64 VirtualAddress; 28 | UINT64 ProcessId; 29 | } INFO_IOCTL_EPT_HOOK_INFO, *PINFO_IOCTL_EPT_HOOK_INFO; 30 | -------------------------------------------------------------------------------- /Trashvisor/Trashvisor.c: -------------------------------------------------------------------------------- 1 | #include "ArchUtils.h" 2 | #include "VmxCore.h" 3 | #include "ControlCallbacks.h" 4 | 5 | _Dispatch_type_(IRP_MJ_CREATE) DRIVER_DISPATCH DriverDeviceCreate; 6 | _Dispatch_type_(IRP_MJ_CLOSE) DRIVER_DISPATCH DriverDeviceClose; 7 | _Dispatch_type_(IRP_MJ_DEVICE_CONTROL) DRIVER_DISPATCH DriverDeviceCtrl; 8 | 9 | DRIVER_UNLOAD DriverUnload; 10 | 11 | PGLOBAL_VMM_CONTEXT pGlobalVmmContext; 12 | 13 | NTSTATUS 14 | DriverEntry ( 15 | _In_ PDRIVER_OBJECT pDriverObject, 16 | _In_ PUNICODE_STRING RegistryPath 17 | ) 18 | { 19 | UNREFERENCED_PARAMETER(RegistryPath); 20 | 21 | NTSTATUS Status = STATUS_SUCCESS; 22 | 23 | UNICODE_STRING NtDeviceName; 24 | UNICODE_STRING DosDeviceLinkName; 25 | 26 | KeInitializeGuardedMutex(&CallbacksMutex); 27 | 28 | pDriverObject->MajorFunction[IRP_MJ_CREATE] = DriverDeviceCreate; 29 | pDriverObject->MajorFunction[IRP_MJ_CLOSE] = DriverDeviceClose; 30 | pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DriverDeviceCtrl; 31 | pDriverObject->DriverUnload = DriverUnload; 32 | 33 | if (!IsVmxSupported() || !IsEptSupported()) 34 | { 35 | Status = STATUS_UNSUCCESSFUL; 36 | goto Exit; 37 | } 38 | 39 | pGlobalVmmContext = AllocateGlobalVmmContext(); 40 | 41 | if (pGlobalVmmContext == NULL) 42 | { 43 | Status = STATUS_UNSUCCESSFUL; 44 | goto Exit; 45 | } 46 | 47 | SetupContextEptInformation(pGlobalVmmContext); 48 | 49 | if (!SetupEptp()) 50 | { 51 | KdPrintError("VmxInitialiseProcessor: SetupEptp failed for processor %u.\n", 52 | KeGetCurrentProcessorNumber()); 53 | goto Exit; 54 | } 55 | 56 | KeGenericCallDpc( 57 | VmxBroadcastInit, 58 | pGlobalVmmContext 59 | ); 60 | 61 | if (pGlobalVmmContext->ActivatedProcessorCount != 62 | pGlobalVmmContext->LogicalProcessorCount) 63 | { 64 | Status = STATUS_UNSUCCESSFUL; 65 | goto Exit; 66 | } 67 | 68 | KdPrintError("Successfully hypervised!\n"); 69 | 70 | RtlInitUnicodeString(&NtDeviceName, NT_DEVICE_NAME); 71 | 72 | PDEVICE_OBJECT pTvDevice; 73 | 74 | Status = IoCreateDevice( 75 | pDriverObject, 76 | 0, 77 | &NtDeviceName, 78 | FILE_DEVICE_UNKNOWN, 79 | FILE_DEVICE_SECURE_OPEN, 80 | FALSE, 81 | &pTvDevice 82 | ); 83 | 84 | if (!NT_SUCCESS(Status)) 85 | { 86 | KdPrintError("Failed to create device. Error code: %d\n", 87 | Status 88 | ); 89 | 90 | goto Exit; 91 | } 92 | 93 | RtlInitUnicodeString(&DosDeviceLinkName, DOS_DEVICE_NAME); 94 | 95 | Status = IoCreateSymbolicLink(&DosDeviceLinkName, &NtDeviceName); 96 | 97 | if (!NT_SUCCESS(Status)) 98 | { 99 | KdPrintError("Failed to create symbolic link. Error code: %d.\n", 100 | Status 101 | ); 102 | 103 | goto Exit; 104 | } 105 | 106 | Exit: 107 | return Status; 108 | } 109 | 110 | _Use_decl_annotations_ 111 | NTSTATUS 112 | DriverDeviceCreate ( 113 | PDEVICE_OBJECT pDeviceObject, 114 | PIRP pIrp 115 | ) 116 | { 117 | UNREFERENCED_PARAMETER(pDeviceObject); 118 | 119 | pIrp->IoStatus.Status = STATUS_SUCCESS; 120 | pIrp->IoStatus.Information = 0; 121 | IoCompleteRequest(pIrp, IO_NO_INCREMENT); 122 | 123 | return STATUS_SUCCESS; 124 | } 125 | 126 | _Use_decl_annotations_ 127 | NTSTATUS 128 | DriverDeviceClose ( 129 | PDEVICE_OBJECT pDeviceObject, 130 | PIRP pIrp 131 | ) 132 | { 133 | UNREFERENCED_PARAMETER(pDeviceObject); 134 | 135 | pIrp->IoStatus.Status = STATUS_SUCCESS; 136 | pIrp->IoStatus.Information = 0; 137 | IoCompleteRequest(pIrp, IO_NO_INCREMENT); 138 | 139 | return STATUS_SUCCESS; 140 | } 141 | 142 | _Use_decl_annotations_ 143 | NTSTATUS 144 | DriverDeviceCtrl ( 145 | PDEVICE_OBJECT pDeviceObject, 146 | PIRP pIrp 147 | ) 148 | { 149 | PIO_STACK_LOCATION pIrpStack; 150 | ULONG Ioctl; 151 | NTSTATUS Status = STATUS_SUCCESS; 152 | 153 | pIrpStack = IoGetCurrentIrpStackLocation(pIrp); 154 | Ioctl = pIrpStack->Parameters.DeviceIoControl.IoControlCode; 155 | 156 | //__debugbreak(); 157 | 158 | switch (Ioctl) 159 | { 160 | case IOCTL_LOG_CPUID_PROCESS: 161 | Status = CtrlLogCpuidForProcess(pDeviceObject, pIrp); 162 | break; 163 | case IOCTL_ADD_EPT_HOOK: 164 | Status = CtrlAddEptHook(pDeviceObject, pIrp); 165 | break; 166 | default: 167 | KdPrintError("DriverDeviceCtrl: Uknown case.\n"); 168 | Status = STATUS_UNSUCCESSFUL; 169 | break; 170 | } 171 | 172 | pIrp->IoStatus.Status = Status; 173 | pIrp->IoStatus.Information = 0; 174 | 175 | IoCompleteRequest(pIrp, IO_NO_INCREMENT); 176 | 177 | return Status; 178 | } 179 | 180 | VOID 181 | DriverUnload ( 182 | _In_ PDRIVER_OBJECT pDriverObject 183 | ) 184 | { 185 | KeGenericCallDpc( 186 | VmxBroadcastTeardown, 187 | pGlobalVmmContext 188 | ); 189 | } 190 | -------------------------------------------------------------------------------- /Trashvisor/Trashvisor.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; Trashvisor.inf 3 | ; 4 | 5 | [Version] 6 | Signature="$WINDOWS NT$" 7 | Class=System 8 | ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318} 9 | Provider=%ManufacturerName% 10 | DriverVer= 11 | CatalogFile=Trashvisor.cat 12 | 13 | [DestinationDirs] 14 | DefaultDestDir = 12 15 | 16 | 17 | [SourceDisksNames] 18 | 1 = %DiskName%,,,"" 19 | 20 | [SourceDisksFiles] 21 | 22 | 23 | [Manufacturer] 24 | %ManufacturerName%=Standard,NT$ARCH$ 25 | 26 | [Standard.NT$ARCH$] 27 | 28 | 29 | [Strings] 30 | ManufacturerName="" ;TODO: Replace with your manufacturer name 31 | ClassName="" 32 | DiskName="Trashvisor Source Disk" 33 | -------------------------------------------------------------------------------- /Trashvisor/Trashvisor.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 | {EE58D4F9-2778-4215-9BDE-7CDF1CFD4614} 39 | {dd38f7fc-d7bd-488b-9242-7d8754cde80d} 40 | v4.5 41 | 12.0 42 | Debug 43 | Win32 44 | Trashvisor 45 | 46 | 47 | 48 | Windows10 49 | true 50 | WindowsKernelModeDriver10.0 51 | Driver 52 | WDM 53 | 54 | 55 | Windows10 56 | false 57 | WindowsKernelModeDriver10.0 58 | Driver 59 | WDM 60 | 61 | 62 | Windows10 63 | true 64 | WindowsKernelModeDriver10.0 65 | Driver 66 | WDM 67 | 68 | 69 | Windows10 70 | false 71 | WindowsKernelModeDriver10.0 72 | Driver 73 | WDM 74 | 75 | 76 | Windows10 77 | true 78 | WindowsKernelModeDriver10.0 79 | Driver 80 | WDM 81 | 82 | 83 | Windows10 84 | false 85 | WindowsKernelModeDriver10.0 86 | Driver 87 | WDM 88 | 89 | 90 | Windows10 91 | true 92 | WindowsKernelModeDriver10.0 93 | Driver 94 | WDM 95 | 96 | 97 | Windows10 98 | false 99 | WindowsKernelModeDriver10.0 100 | Driver 101 | WDM 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | DbgengKernelDebugger 114 | 115 | 116 | DbgengKernelDebugger 117 | 118 | 119 | DbgengKernelDebugger 120 | true 121 | true 122 | AllRules.ruleset 123 | 124 | 125 | DbgengKernelDebugger 126 | true 127 | 128 | 129 | DbgengKernelDebugger 130 | 131 | 132 | DbgengKernelDebugger 133 | 134 | 135 | DbgengKernelDebugger 136 | 137 | 138 | DbgengKernelDebugger 139 | 140 | 141 | 142 | false 143 | 144 | 145 | 146 | 147 | false 148 | true 149 | Level1 150 | 151 | 152 | /INTEGRITYCHECK %(AdditionalOptions) 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | -------------------------------------------------------------------------------- /Trashvisor/Trashvisor.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 | Driver Files 24 | 25 | 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | Source Files 38 | 39 | 40 | Source Files 41 | 42 | 43 | Source Files 44 | 45 | 46 | Source Files 47 | 48 | 49 | Source Files 50 | 51 | 52 | Source Files 53 | 54 | 55 | 56 | 57 | Header Files 58 | 59 | 60 | Header Files 61 | 62 | 63 | Header Files 64 | 65 | 66 | Header Files 67 | 68 | 69 | Header Files 70 | 71 | 72 | Header Files 73 | 74 | 75 | Header Files 76 | 77 | 78 | Header Files 79 | 80 | 81 | Header Files 82 | 83 | 84 | 85 | 86 | Source Files 87 | 88 | 89 | Source Files 90 | 91 | 92 | -------------------------------------------------------------------------------- /Trashvisor/Trashvisor.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /Trashvisor/Vmcs.c: -------------------------------------------------------------------------------- 1 | #include "Vmcs.h" 2 | 3 | _Use_decl_annotations_ 4 | VOID 5 | SetupVmcs ( 6 | PLOCAL_VMM_CONTEXT pLocalVmmContext, 7 | ULONG_PTR GuestRip, 8 | ULONG_PTR GuestRsp 9 | ) 10 | { 11 | IA32_VMX_BASIC_REGISTER BasicRegister; 12 | BasicRegister.Flags = ReadMsr(IA32_VMX_BASIC); 13 | 14 | BOOLEAN UseTrueControls = FALSE; 15 | 16 | if (BasicRegister.VmxControls) 17 | UseTrueControls = TRUE; 18 | 19 | SetupVmcsExecutionCtls(pLocalVmmContext, UseTrueControls); 20 | SetupVmcsVmEntryCtls(pLocalVmmContext, UseTrueControls); 21 | SetupVmcsVmExitCtls(pLocalVmmContext, UseTrueControls); 22 | 23 | SetupVmcsHostState(pLocalVmmContext); 24 | SetupVmcsGuestState(pLocalVmmContext, GuestRip, GuestRsp); 25 | } 26 | 27 | _Use_decl_annotations_ 28 | VOID 29 | SetupVmcsGuestState ( 30 | PLOCAL_VMM_CONTEXT pLocalVmmContext, 31 | ULONG_PTR GuestRip, 32 | ULONG_PTR GuestRsp 33 | ) 34 | { 35 | PCONTEXT pContext = &pLocalVmmContext->RegisterContext; 36 | PMISC_CONTEXT pMiscContext = &pLocalVmmContext->MiscRegisterContext; 37 | 38 | __vmx_vmwrite(VMCS_GUEST_CR0, pMiscContext->Cr0.Flags); 39 | __vmx_vmwrite(VMCS_GUEST_CR3, pMiscContext->Cr3.Flags); 40 | __vmx_vmwrite(VMCS_GUEST_CR4, pMiscContext->Cr4.Flags); 41 | __vmx_vmwrite(VMCS_GUEST_DR7, pMiscContext->Dr7.Flags); 42 | 43 | __vmx_vmwrite(VMCS_GUEST_RSP, GuestRsp); 44 | __vmx_vmwrite(VMCS_GUEST_RIP, GuestRip); 45 | __vmx_vmwrite(VMCS_GUEST_RFLAGS, __readeflags()); 46 | 47 | SEGMENT_SETUP Setup; 48 | 49 | GetSegmentSetup(&Setup, pContext->SegCs, pMiscContext->Gdtr.BaseAddress); 50 | __vmx_vmwrite(VMCS_GUEST_CS_SELECTOR, pContext->SegCs); 51 | __vmx_vmwrite(VMCS_GUEST_CS_BASE, Setup.BaseAddress); 52 | __vmx_vmwrite(VMCS_GUEST_CS_LIMIT, Setup.SegmentLimit); 53 | __vmx_vmwrite(VMCS_GUEST_CS_ACCESS_RIGHTS, Setup.AccessRights); 54 | 55 | GetSegmentSetup(&Setup, pContext->SegDs, pMiscContext->Gdtr.BaseAddress); 56 | __vmx_vmwrite(VMCS_GUEST_DS_SELECTOR, pContext->SegDs); 57 | __vmx_vmwrite(VMCS_GUEST_DS_BASE, Setup.BaseAddress); 58 | __vmx_vmwrite(VMCS_GUEST_DS_LIMIT, Setup.SegmentLimit); 59 | __vmx_vmwrite(VMCS_GUEST_DS_ACCESS_RIGHTS, Setup.AccessRights); 60 | 61 | GetSegmentSetup(&Setup, pContext->SegEs, pMiscContext->Gdtr.BaseAddress); 62 | __vmx_vmwrite(VMCS_GUEST_ES_SELECTOR, pContext->SegEs); 63 | __vmx_vmwrite(VMCS_GUEST_ES_BASE, Setup.BaseAddress); 64 | __vmx_vmwrite(VMCS_GUEST_ES_LIMIT, Setup.SegmentLimit); 65 | __vmx_vmwrite(VMCS_GUEST_ES_ACCESS_RIGHTS, Setup.AccessRights); 66 | 67 | GetSegmentSetup(&Setup, pContext->SegFs, pMiscContext->Gdtr.BaseAddress); 68 | __vmx_vmwrite(VMCS_GUEST_FS_SELECTOR, pContext->SegFs); 69 | __vmx_vmwrite(VMCS_GUEST_FS_BASE, ReadMsr(IA32_FS_BASE)); 70 | __vmx_vmwrite(VMCS_GUEST_FS_LIMIT, Setup.SegmentLimit); 71 | __vmx_vmwrite(VMCS_GUEST_FS_ACCESS_RIGHTS, Setup.AccessRights); 72 | 73 | GetSegmentSetup(&Setup, pContext->SegGs, pMiscContext->Gdtr.BaseAddress); 74 | __vmx_vmwrite(VMCS_GUEST_GS_SELECTOR, pContext->SegGs); 75 | __vmx_vmwrite(VMCS_GUEST_GS_BASE, ReadMsr(IA32_GS_BASE)); 76 | __vmx_vmwrite(VMCS_GUEST_GS_LIMIT, Setup.SegmentLimit); 77 | __vmx_vmwrite(VMCS_GUEST_GS_ACCESS_RIGHTS, Setup.AccessRights); 78 | 79 | GetSegmentSetup(&Setup, pContext->SegSs, pMiscContext->Gdtr.BaseAddress); 80 | __vmx_vmwrite(VMCS_GUEST_SS_SELECTOR, pContext->SegSs); 81 | __vmx_vmwrite(VMCS_GUEST_SS_BASE, Setup.BaseAddress); 82 | __vmx_vmwrite(VMCS_GUEST_SS_LIMIT, Setup.SegmentLimit); 83 | __vmx_vmwrite(VMCS_GUEST_SS_ACCESS_RIGHTS, Setup.AccessRights); 84 | 85 | GetSysSegmentSetup(&Setup, pMiscContext->Tr.Flags, pMiscContext->Gdtr.BaseAddress); 86 | __vmx_vmwrite(VMCS_GUEST_TR_SELECTOR, pMiscContext->Tr.Flags); 87 | __vmx_vmwrite(VMCS_GUEST_TR_BASE, Setup.BaseAddress); 88 | __vmx_vmwrite(VMCS_GUEST_TR_LIMIT, Setup.SegmentLimit); 89 | __vmx_vmwrite(VMCS_GUEST_TR_ACCESS_RIGHTS, Setup.AccessRights); 90 | 91 | GetSysSegmentSetup(&Setup, pMiscContext->Ldtr.Flags, pMiscContext->Gdtr.BaseAddress); 92 | __vmx_vmwrite(VMCS_GUEST_LDTR_SELECTOR, pMiscContext->Ldtr.Flags); 93 | __vmx_vmwrite(VMCS_GUEST_LDTR_BASE, Setup.BaseAddress); 94 | __vmx_vmwrite(VMCS_GUEST_LDTR_LIMIT, Setup.SegmentLimit); 95 | __vmx_vmwrite(VMCS_GUEST_LDTR_ACCESS_RIGHTS, Setup.AccessRights); 96 | 97 | __vmx_vmwrite(VMCS_GUEST_GDTR_BASE, pMiscContext->Gdtr.BaseAddress); 98 | __vmx_vmwrite(VMCS_GUEST_GDTR_LIMIT, pMiscContext->Gdtr.Limit); 99 | 100 | __vmx_vmwrite(VMCS_GUEST_IDTR_BASE, pMiscContext->Idtr.BaseAddress); 101 | __vmx_vmwrite(VMCS_GUEST_IDTR_LIMIT, pMiscContext->Idtr.Limit); 102 | 103 | __vmx_vmwrite(VMCS_GUEST_ACTIVITY_STATE, 0); 104 | __vmx_vmwrite(VMCS_GUEST_INTERRUPT_STATUS, 0); 105 | __vmx_vmwrite(VMCS_GUEST_PENDING_DEBUG_EXCEPTIONS, 0); 106 | __vmx_vmwrite(VMCS_GUEST_VMCS_LINK_POINTER, ~0ULL); 107 | } 108 | 109 | _Use_decl_annotations_ 110 | VOID 111 | SetupVmcsHostState ( 112 | PLOCAL_VMM_CONTEXT pLocalVmmContext 113 | ) 114 | { 115 | PCONTEXT pContext = &pLocalVmmContext->RegisterContext; 116 | PMISC_CONTEXT pMiscContext = &pLocalVmmContext->MiscRegisterContext; 117 | 118 | __vmx_vmwrite(VMCS_HOST_CR0, pMiscContext->Cr0.Flags); 119 | 120 | KdPrintError("Writing to host cr3: 0x%llx\n", pLocalVmmContext->pGlobalVmmContext->SystemCr3.Flags); 121 | 122 | __vmx_vmwrite(VMCS_HOST_CR3, pLocalVmmContext->pGlobalVmmContext->SystemCr3.Flags); 123 | __vmx_vmwrite(VMCS_HOST_CR4, pMiscContext->Cr4.Flags); 124 | 125 | __vmx_vmwrite(VMCS_HOST_RSP, &pLocalVmmContext->StackTop); 126 | __vmx_vmwrite(VMCS_HOST_RIP, VmxVmExitHandlerStub); 127 | 128 | #define MASK_OFF_RPL(x) (x & ~3) 129 | __vmx_vmwrite(VMCS_HOST_CS_SELECTOR, MASK_OFF_RPL(pContext->SegCs)); 130 | __vmx_vmwrite(VMCS_HOST_DS_SELECTOR, MASK_OFF_RPL(pContext->SegDs)); 131 | __vmx_vmwrite(VMCS_HOST_ES_SELECTOR, MASK_OFF_RPL(pContext->SegEs)); 132 | __vmx_vmwrite(VMCS_HOST_FS_SELECTOR, MASK_OFF_RPL(pContext->SegFs)); 133 | __vmx_vmwrite(VMCS_HOST_GS_SELECTOR, MASK_OFF_RPL(pContext->SegGs)); 134 | __vmx_vmwrite(VMCS_HOST_SS_SELECTOR, MASK_OFF_RPL(pContext->SegSs)); 135 | __vmx_vmwrite(VMCS_HOST_TR_SELECTOR, MASK_OFF_RPL(pMiscContext->Tr.Flags)); 136 | 137 | SEGMENT_DESCRIPTOR_64 TssDescriptor = GetSysSegmentDescriptor( 138 | pMiscContext->Tr.Flags, 139 | pMiscContext->Gdtr.BaseAddress 140 | ); 141 | 142 | __vmx_vmwrite(VMCS_HOST_FS_BASE, ReadMsr(IA32_FS_BASE)); 143 | __vmx_vmwrite(VMCS_HOST_GS_BASE, ReadMsr(IA32_GS_BASE)); 144 | __vmx_vmwrite(VMCS_HOST_TR_BASE, GetSysSegmentBase(TssDescriptor)); 145 | __vmx_vmwrite(VMCS_HOST_GDTR_BASE, pMiscContext->Gdtr.BaseAddress); 146 | __vmx_vmwrite(VMCS_HOST_IDTR_BASE, pMiscContext->Idtr.BaseAddress); 147 | } 148 | 149 | _Use_decl_annotations_ 150 | VOID 151 | SetupVmcsExecutionCtls ( 152 | PLOCAL_VMM_CONTEXT pLocalVmmContext, 153 | BOOLEAN UseTrue 154 | ) 155 | { 156 | IA32_VMX_PINBASED_CTLS_REGISTER PinBasedRegister; 157 | IA32_VMX_PROCBASED_CTLS_REGISTER ProcBasedRegister; 158 | IA32_VMX_PROCBASED_CTLS2_REGISTER ProcBased2Register; 159 | 160 | if (UseTrue) 161 | { 162 | ProcBasedRegister.Flags = ReadMsr(IA32_VMX_TRUE_PROCBASED_CTLS); 163 | PinBasedRegister.Flags = ReadMsr(IA32_VMX_TRUE_PINBASED_CTLS); 164 | } 165 | else 166 | { 167 | ProcBasedRegister.Flags = ReadMsr(IA32_VMX_PROCBASED_CTLS); 168 | PinBasedRegister.Flags = ReadMsr(IA32_VMX_PINBASED_CTLS); 169 | } 170 | 171 | ProcBased2Register.Flags = ReadMsr(IA32_VMX_PROCBASED_CTLS2); 172 | 173 | ULONG32 PinBasedCtlsDesired = 0; 174 | ULONG32 ProcBasedCtlsDesired = IA32_VMX_PROCBASED_CTLS_USE_MSR_BITMAPS_FLAG 175 | | IA32_VMX_PROCBASED_CTLS_ACTIVATE_SECONDARY_CONTROLS_FLAG; 176 | 177 | ULONG32 ProcBasedCtls2Desired = IA32_VMX_PROCBASED_CTLS2_ENABLE_XSAVES_FLAG 178 | | IA32_VMX_PROCBASED_CTLS2_ENABLE_RDTSCP_FLAG 179 | | IA32_VMX_PROCBASED_CTLS2_ENABLE_INVPCID_FLAG 180 | | IA32_VMX_PROCBASED_CTLS2_ENABLE_EPT_FLAG; 181 | 182 | __vmx_vmwrite(VMCS_CTRL_PIN_BASED_VM_EXECUTION_CONTROLS, 183 | EnforceRequiredBits(PinBasedRegister.Flags, PinBasedCtlsDesired)); 184 | 185 | __vmx_vmwrite(VMCS_CTRL_PROCESSOR_BASED_VM_EXECUTION_CONTROLS, 186 | EnforceRequiredBits(ProcBasedRegister.Flags, ProcBasedCtlsDesired)); 187 | 188 | __vmx_vmwrite(VMCS_CTRL_SECONDARY_PROCESSOR_BASED_VM_EXECUTION_CONTROLS, 189 | EnforceRequiredBits(ProcBased2Register.Flags, ProcBasedCtls2Desired)); 190 | 191 | __vmx_vmwrite(VMCS_CTRL_EXCEPTION_BITMAP, 0); 192 | __vmx_vmwrite(VMCS_CTRL_PAGEFAULT_ERROR_CODE_MASK, 0); 193 | __vmx_vmwrite(VMCS_CTRL_PAGEFAULT_ERROR_CODE_MATCH, 0); 194 | 195 | __vmx_vmwrite(VMCS_CTRL_CR3_TARGET_COUNT, 0); 196 | 197 | __vmx_vmwrite(VMCS_CTRL_CR0_GUEST_HOST_MASK, 0); 198 | __vmx_vmwrite(VMCS_CTRL_CR4_GUEST_HOST_MASK, 0); 199 | __vmx_vmwrite(VMCS_CTRL_CR0_READ_SHADOW, pLocalVmmContext->MiscRegisterContext.Cr0.Flags); 200 | __vmx_vmwrite(VMCS_CTRL_CR4_READ_SHADOW, pLocalVmmContext->MiscRegisterContext.Cr4.Flags); 201 | 202 | __vmx_vmwrite(VMCS_CTRL_MSR_BITMAP_ADDRESS, pLocalVmmContext->PhysMsrBitmap); 203 | 204 | __vmx_vmwrite(VMCS_CTRL_EPT_POINTER, pGlobalVmmContext->EptPointer.Flags); 205 | } 206 | 207 | _Use_decl_annotations_ 208 | VOID 209 | SetupVmcsVmExitCtls ( 210 | PLOCAL_VMM_CONTEXT pLocalVmmContext, 211 | BOOLEAN UseTrue 212 | ) 213 | { 214 | IA32_VMX_EXIT_CTLS_REGISTER ExitCtlsRegister; 215 | 216 | if (UseTrue) 217 | ExitCtlsRegister.Flags = ReadMsr(IA32_VMX_TRUE_EXIT_CTLS); 218 | else 219 | ExitCtlsRegister.Flags = ReadMsr(IA32_VMX_EXIT_CTLS); 220 | 221 | ULONG32 ExitCtlsDesired = IA32_VMX_EXIT_CTLS_HOST_ADDRESS_SPACE_SIZE_FLAG; 222 | 223 | __vmx_vmwrite(VMCS_CTRL_VMEXIT_CONTROLS, 224 | EnforceRequiredBits(ExitCtlsRegister.Flags, ExitCtlsDesired)); 225 | 226 | __vmx_vmwrite(VMCS_CTRL_VMEXIT_MSR_STORE_COUNT, 0); 227 | __vmx_vmwrite(VMCS_CTRL_VMEXIT_MSR_LOAD_COUNT, 0); 228 | } 229 | 230 | _Use_decl_annotations_ 231 | VOID 232 | SetupVmcsVmEntryCtls ( 233 | PLOCAL_VMM_CONTEXT pLocalVmmContext, 234 | BOOLEAN UseTrue 235 | ) 236 | { 237 | IA32_VMX_ENTRY_CTLS_REGISTER EntryCtlsRegister; 238 | 239 | if (UseTrue) 240 | EntryCtlsRegister.Flags = ReadMsr(IA32_VMX_TRUE_ENTRY_CTLS); 241 | else 242 | EntryCtlsRegister.Flags = ReadMsr(IA32_VMX_ENTRY_CTLS); 243 | 244 | ULONG32 EntryCtlsDesired = IA32_VMX_ENTRY_CTLS_IA32E_MODE_GUEST_FLAG; 245 | 246 | __vmx_vmwrite(VMCS_CTRL_VMENTRY_CONTROLS, 247 | EnforceRequiredBits(EntryCtlsRegister.Flags, EntryCtlsDesired)); 248 | 249 | __vmx_vmwrite(VMCS_CTRL_VMENTRY_MSR_LOAD_COUNT, 0); 250 | __vmx_vmwrite(VMCS_CTRL_VMENTRY_INTERRUPTION_INFORMATION_FIELD, 0); 251 | __vmx_vmwrite(VMCS_CTRL_VMENTRY_EXCEPTION_ERROR_CODE, 0); 252 | } 253 | -------------------------------------------------------------------------------- /Trashvisor/Vmcs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Extern.h" 3 | #include "ArchUtils.h" 4 | #include "VmxHost.h" 5 | 6 | VOID 7 | SetupVmcs ( 8 | _In_ PLOCAL_VMM_CONTEXT pLocalVmmContext, 9 | _In_ ULONG_PTR GuestRip, 10 | _In_ ULONG_PTR GuestRsp 11 | ); 12 | 13 | VOID 14 | SetupVmcsGuestState ( 15 | _In_ PLOCAL_VMM_CONTEXT pLocalVmmContext, 16 | _In_ ULONG_PTR GuestRip, 17 | _In_ ULONG_PTR GuestRsp 18 | ); 19 | 20 | VOID 21 | SetupVmcsHostState ( 22 | _In_ PLOCAL_VMM_CONTEXT pLocalVmmContext 23 | ); 24 | 25 | VOID 26 | SetupVmcsExecutionCtls ( 27 | _In_ PLOCAL_VMM_CONTEXT pLocalVmmContext, 28 | _In_ BOOLEAN UseTrue 29 | ); 30 | 31 | VOID 32 | SetupVmcsVmExitCtls ( 33 | _In_ PLOCAL_VMM_CONTEXT pLocalVmmContext, 34 | _In_ BOOLEAN UseTrue 35 | ); 36 | 37 | VOID 38 | SetupVmcsVmEntryCtls ( 39 | _In_ PLOCAL_VMM_CONTEXT pLocalVmmContext, 40 | _In_ BOOLEAN UseTrue 41 | ); 42 | -------------------------------------------------------------------------------- /Trashvisor/VmxAsm.asm: -------------------------------------------------------------------------------- 1 | SaveState MACRO 2 | push r15 3 | push r14 4 | push r13 5 | push r12 6 | push r11 7 | push r10 8 | push r9 9 | push r8 10 | push rdi 11 | push rsi 12 | push rbp 13 | sub rsp, 8 ; placeholder 14 | push rbx 15 | push rdx 16 | push rcx 17 | push rax 18 | ENDM 19 | 20 | RestoreState MACRO 21 | pop rax 22 | pop rcx 23 | pop rdx 24 | pop rbx 25 | add rsp, 8 26 | pop rbp 27 | pop rsi 28 | pop rdi 29 | pop r8 30 | pop r9 31 | pop r10 32 | pop r11 33 | pop r12 34 | pop r13 35 | pop r14 36 | pop r15 37 | ENDM 38 | 39 | extern VmxInitialiseProcessor:proc 40 | extern VmxVmExitHandler:proc 41 | extern GetVmxInstructionError:proc 42 | 43 | .code 44 | 45 | VmxInitialiseProcessorStub PROC 46 | pushfq 47 | SaveState 48 | 49 | mov rdx, GuestEntry 50 | mov r8, rsp 51 | 52 | sub rsp, 20h 53 | call VmxInitialiseProcessor 54 | add rsp, 20h 55 | 56 | RestoreState 57 | popfq 58 | 59 | mov rax, 0 60 | ret 61 | 62 | GuestEntry: 63 | ;int 3 64 | 65 | RestoreState 66 | popfq 67 | 68 | mov rax, 1 69 | ret 70 | VmxInitialiseProcessorStub ENDP 71 | 72 | VmxVmExitHandlerStub PROC 73 | SaveState 74 | 75 | mov rcx, rsp 76 | 77 | sub rsp, 20h 78 | call VmxVmExitHandler 79 | add rsp, 20h 80 | 81 | RestoreState 82 | vmresume 83 | 84 | call GetVmxInstructionError 85 | 86 | ret 87 | VmxVmExitHandlerStub ENDP 88 | 89 | END -------------------------------------------------------------------------------- /Trashvisor/VmxCore.c: -------------------------------------------------------------------------------- 1 | #include "VmxUtils.h" 2 | #include "VmxCore.h" 3 | #include "ArchUtils.h" 4 | 5 | _Use_decl_annotations_ 6 | VOID 7 | NTAPI 8 | VmxBroadcastInit ( 9 | struct _KDPC* pDpc, 10 | PVOID DeferredContext, 11 | PVOID SystemArgument1, 12 | PVOID SystemArgument2 13 | ) 14 | { 15 | PGLOBAL_VMM_CONTEXT pGlobalVmmContext = (PGLOBAL_VMM_CONTEXT)DeferredContext; 16 | 17 | PLOCAL_VMM_CONTEXT pLocalVmmContext = RetrieveLocalContext( 18 | KeGetCurrentProcessorNumberEx(NULL), 19 | pGlobalVmmContext 20 | ); 21 | 22 | ASSERT(pLocalVmmContext != NULL); 23 | 24 | // VmxInitialiseProcessor will set to FALSE if unsuccessful 25 | pLocalVmmContext->VmxActivated = TRUE; 26 | 27 | if (!VmxInitialiseProcessorStub(pLocalVmmContext)) 28 | KdPrintError("VmxBroadcastInit: Failed.\n"); 29 | 30 | if (pLocalVmmContext->VmxActivated) 31 | _InterlockedIncrement(&pGlobalVmmContext->ActivatedProcessorCount); 32 | 33 | KdPrintError("Logical processor %u successfully launched.\n", 34 | KeGetCurrentProcessorNumberEx(NULL) 35 | ); 36 | 37 | KeSignalCallDpcSynchronize(SystemArgument2); 38 | KeSignalCallDpcDone(SystemArgument1); 39 | } 40 | 41 | _Use_decl_annotations_ 42 | VOID 43 | VmxInitialiseProcessor ( 44 | PLOCAL_VMM_CONTEXT pLocalVmmContext, 45 | ULONG_PTR GuestRip, 46 | ULONG_PTR GuestRsp 47 | ) 48 | { 49 | if (!EnableVmx(pLocalVmmContext)) 50 | { 51 | KdPrintError("VmxInitialiseProcessor failed for processor %u.\n", 52 | KeGetCurrentProcessorNumber()); 53 | goto Exit; 54 | } 55 | 56 | /* 57 | if (!SetupEptp(pLocalVmmContext)) 58 | { 59 | KdPrintError("VmxInitialiseProcessor: SetupEptp failed for processor %u.\n", 60 | KeGetCurrentProcessorNumber()); 61 | goto Exit; 62 | } 63 | */ 64 | 65 | CaptureState(pLocalVmmContext); 66 | 67 | SetupVmcs(pLocalVmmContext, GuestRip, GuestRsp); 68 | 69 | __vmx_vmlaunch(); 70 | 71 | SIZE_T Error; 72 | __vmx_vmread(VMCS_VM_INSTRUCTION_ERROR, &Error); 73 | 74 | KdPrintError("Vmlaunch failed with: %d\n", Error); 75 | 76 | Exit: 77 | pLocalVmmContext->VmxActivated = FALSE; 78 | } 79 | 80 | _Use_decl_annotations_ 81 | VOID 82 | NTAPI 83 | VmxBroadcastTeardown ( 84 | struct _KDPC* pDpc, 85 | PVOID DeferredContext, 86 | PVOID SystemArgument1, 87 | PVOID SystemArgument2 88 | ) 89 | { 90 | // This should be done using a magic value + a forced vmexit 91 | // Maybe just use a value with cpuid and magic constants in the GP registers 92 | } 93 | -------------------------------------------------------------------------------- /Trashvisor/VmxCore.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "VmxUtils.h" 3 | #include "Vmcs.h" 4 | 5 | VOID 6 | NTAPI 7 | VmxBroadcastInit ( 8 | _In_ struct _KDPC* pDpc, 9 | _In_opt_ PVOID DeferredContext, 10 | _In_opt_ PVOID SystemArgument1, 11 | _In_opt_ PVOID SystemArgument2 12 | ); 13 | 14 | BOOLEAN 15 | VmxInitialiseProcessorStub ( 16 | _In_ PLOCAL_VMM_CONTEXT pLocalVmmContext 17 | ); 18 | 19 | VOID 20 | VmxInitialiseProcessor ( 21 | _In_ PLOCAL_VMM_CONTEXT pLocalVmmContext, 22 | _In_ ULONG_PTR GuestRip, 23 | _In_ ULONG_PTR GuestRsp 24 | ); 25 | 26 | VOID 27 | NTAPI 28 | VmxBroadcastTeardown ( 29 | _In_ struct _KDPC* pDpc, 30 | _In_opt_ PVOID DeferredContext, 31 | _In_opt_ PVOID SystemArgument1, 32 | _In_opt_ PVOID SystemArgument2 33 | ); 34 | -------------------------------------------------------------------------------- /Trashvisor/VmxHost.c: -------------------------------------------------------------------------------- 1 | #include "VmxHost.h" 2 | #include "ControlCallbacks.h" 3 | 4 | VOID 5 | VmxSetupHostContext ( 6 | _In_ PVMM_EXIT_CONTEXT pExitContext, 7 | _In_ PVMM_GUEST_CONTEXT pGPContext 8 | ) 9 | { 10 | __vmx_vmread(VMCS_GUEST_RSP, &pGPContext->Rsp); 11 | __vmx_vmread(VMCS_GUEST_CR3, &pExitContext->GuestCr3.Flags); 12 | __vmx_vmread(VMCS_GUEST_RIP, &pExitContext->GuestRip); 13 | __vmx_vmread(VMCS_GUEST_PHYSICAL_ADDRESS, &pExitContext->GuestPhysicalAddress); 14 | __vmx_vmread(VMCS_VMEXIT_INSTRUCTION_LENGTH, &pExitContext->InstructionLength); 15 | __vmx_vmread(VMCS_EXIT_REASON, &pExitContext->ExitReason.Flags); 16 | 17 | pExitContext->IncrementRip = FALSE; 18 | } 19 | 20 | VOID 21 | VmxHandleExitReason( 22 | _In_ PVMM_EXIT_CONTEXT pExitContext, 23 | _In_ PVMM_GUEST_CONTEXT pGPContext 24 | ) 25 | { 26 | switch (pExitContext->ExitReason.ExitReason) 27 | { 28 | case VMX_EXIT_REASON_EXECUTE_CPUID: 29 | { 30 | pExitContext->IncrementRip = TRUE; 31 | ExitHandleCpuid(pExitContext, pGPContext); 32 | break; 33 | } 34 | case VMX_EXIT_REASON_EXECUTE_RDMSR: 35 | { 36 | pExitContext->IncrementRip = TRUE; 37 | ExitHandleRdMsr(pExitContext, pGPContext); 38 | break; 39 | } 40 | case VMX_EXIT_REASON_EXECUTE_WRMSR: 41 | { 42 | pExitContext->IncrementRip = TRUE; 43 | ExitHandleWrMsr(pExitContext, pGPContext); 44 | break; 45 | } 46 | case VMX_EXIT_REASON_EXECUTE_INVEPT: 47 | { 48 | pExitContext->IncrementRip = TRUE; 49 | ExitHandleInvept(pExitContext, pGPContext); 50 | break; 51 | } 52 | case VMX_EXIT_REASON_EPT_VIOLATION: 53 | { 54 | //__debugbreak(); 55 | ExitHandleEptViolation(pExitContext, pGPContext); 56 | //__debugbreak(); 57 | break; 58 | } 59 | case VMX_EXIT_REASON_EXECUTE_VMCLEAR: 60 | // Implement shutting down later. 61 | // Remember... the fucking vmcs is cleared... theres no vmresuming... 62 | case VMX_EXIT_REASON_EXECUTE_VMXOFF: 63 | case VMX_EXIT_REASON_EXECUTE_XSETBV: 64 | case VMX_EXIT_REASON_EXECUTE_GETSEC: 65 | case VMX_EXIT_REASON_EXECUTE_INVD: 66 | default: 67 | __debugbreak(); 68 | } 69 | } 70 | 71 | VOID 72 | HostIncrementRip( 73 | PVMM_EXIT_CONTEXT pExitContext 74 | ) 75 | { 76 | if (pExitContext->IncrementRip == FALSE) 77 | return; 78 | 79 | UINT64 NewRip = pExitContext->GuestRip + pExitContext->InstructionLength; 80 | 81 | __vmx_vmwrite(VMCS_GUEST_RIP, NewRip); 82 | } 83 | 84 | _Use_decl_annotations_ 85 | VOID 86 | VmxVmExitHandler ( 87 | ULONG64 HostStackAddress 88 | ) 89 | { 90 | VMM_EXIT_CONTEXT ExitContext = { 0 }; 91 | 92 | PVMM_GUEST_CONTEXT pGPContext = (PVMM_GUEST_CONTEXT)HostStackAddress; 93 | 94 | VmxSetupHostContext(&ExitContext, pGPContext); 95 | 96 | VmxHandleExitReason(&ExitContext, pGPContext); 97 | 98 | HostIncrementRip(&ExitContext); 99 | } 100 | -------------------------------------------------------------------------------- /Trashvisor/VmxHost.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "VmxCore.h" 3 | #include "ArchUtils.h" 4 | #include "VmxUtils.h" 5 | 6 | typedef union _VMX_EXIT_REASON 7 | { 8 | struct 9 | { 10 | ULONG32 ExitReason : 16; 11 | ULONG32 Always0 : 1; 12 | ULONG32 Reserved1 : 10; 13 | ULONG32 Enclave : 1; 14 | ULONG32 PendingMTF : 1; 15 | ULONG32 ExitFromRoot : 1; 16 | ULONG32 Reserved2 : 1; 17 | ULONG32 VmEntryFailure : 1; 18 | }; 19 | 20 | UINT32 Flags; 21 | } VMX_EXIT_REASON; 22 | 23 | typedef struct _VMM_EXIT_CONTEXT 24 | { 25 | VMX_EXIT_REASON ExitReason; 26 | CR3 GuestCr3; 27 | UINT64 GuestRip; 28 | UINT64 GuestPhysicalAddress; 29 | UINT32 InstructionLength; 30 | BOOLEAN IncrementRip; 31 | } VMM_EXIT_CONTEXT, *PVMM_EXIT_CONTEXT; 32 | 33 | VOID 34 | VmxVmExitHandlerStub ( 35 | ); 36 | 37 | VOID 38 | VmxVmExitHandler ( 39 | _In_ ULONG64 HostStackAddress 40 | ); 41 | 42 | VOID 43 | ExitHandleCpuid ( 44 | _In_ PVMM_EXIT_CONTEXT pExitContext, 45 | _In_ PVMM_GUEST_CONTEXT pGPContext 46 | ); 47 | 48 | VOID 49 | ExitHandleInvept ( 50 | _In_ PVMM_EXIT_CONTEXT pExitContext, 51 | _In_ PVMM_GUEST_CONTEXT pGPContext 52 | ); 53 | 54 | VOID 55 | ExitHandleEptViolation ( 56 | _In_ PVMM_EXIT_CONTEXT pExitContext, 57 | _In_ PVMM_GUEST_CONTEXT pGPContext 58 | ); 59 | 60 | VOID 61 | ExitHandleRdMsr ( 62 | _In_ PVMM_EXIT_CONTEXT pExitContext, 63 | _In_ PVMM_GUEST_CONTEXT pGPContext 64 | ); 65 | 66 | VOID 67 | ExitHandleWrMsr ( 68 | _In_ PVMM_EXIT_CONTEXT pExitContext, 69 | _In_ PVMM_GUEST_CONTEXT pGPContext 70 | ); 71 | -------------------------------------------------------------------------------- /Trashvisor/VmxHostExitHandlers.c: -------------------------------------------------------------------------------- 1 | #include "VmxHost.h" 2 | #include "ControlCallbacks.h" 3 | #include "Ept.h" 4 | 5 | _Use_decl_annotations_ 6 | VOID 7 | ExitHandleCpuid ( 8 | PVMM_EXIT_CONTEXT pExitContext, 9 | PVMM_GUEST_CONTEXT pGPContext 10 | ) 11 | { 12 | pExitContext->IncrementRip = TRUE; 13 | 14 | UINT64 StoredRax = pGPContext->Rax; 15 | 16 | int Cpuid[4]; 17 | 18 | __cpuid(Cpuid, pGPContext->Rax); 19 | 20 | pGPContext->Rax = Cpuid[0]; 21 | pGPContext->Rbx = Cpuid[1]; 22 | pGPContext->Rcx = Cpuid[2]; 23 | pGPContext->Rdx = Cpuid[3]; 24 | 25 | if (pCpuidLoggingInfo == NULL) 26 | return; 27 | 28 | if (pExitContext->GuestCr3.Flags == pCpuidLoggingInfo->UserCr3.Flags) 29 | { 30 | __writecr3(pCpuidLoggingInfo->KernelCr3.Flags); 31 | 32 | KdPrintError( 33 | "Cpuid called for process with RAX: 0x%llx\n", 34 | StoredRax 35 | ); 36 | 37 | PCHAR pPeb = (PCHAR)pCpuidLoggingInfo->pPeb; 38 | 39 | // Disable SMAP 40 | CR4 Cr4; 41 | Cr4.Flags = __readcr4(); 42 | Cr4.SmapEnable = 0; 43 | __writecr4(Cr4.Flags); 44 | 45 | PPEB_LDR_DATA pLdrData = *(PUINT64)(pPeb + 0x18); 46 | 47 | PLIST_ENTRY FirstLink = &(pLdrData->InMemOrderModuleList); 48 | PLIST_ENTRY CurrLink = FirstLink; 49 | 50 | CPUID_DATA_LINE DataLine; 51 | 52 | do 53 | { 54 | PLDR_MODULE pCurrentModule = CONTAINING_RECORD(CurrLink->Flink, LDR_MODULE, InMemOrderModuleList.Flink); 55 | 56 | PIMAGE_NT_HEADERS NtHeader = RtlImageNtHeader(pCurrentModule->BaseAddress); 57 | 58 | UINT32 Size = NtHeader->OptionalHeader.SizeOfImage; 59 | 60 | UINT_PTR BeginAddress = pCurrentModule->BaseAddress; 61 | UINT_PTR EndAddress = BeginAddress + Size; 62 | 63 | if (pExitContext->GuestRip >= BeginAddress && pExitContext->GuestRip <= EndAddress) 64 | { 65 | DataLine.CpuidRax = StoredRax; 66 | DataLine.CpuidModuleRva = pExitContext->GuestRip - BeginAddress; 67 | 68 | RtlCopyMemory( 69 | DataLine.ModuleName, 70 | pCurrentModule->BaseDllName.Buffer, 71 | pCurrentModule->BaseDllName.Length 72 | ); 73 | 74 | KdPrintError("Found cpuid call with RVA: 0x%x in: %wZ\n", 75 | pExitContext->GuestRip - BeginAddress, 76 | pCurrentModule->BaseDllName); 77 | 78 | if (pCpuidLoggingInfo->CurrentDataLine < pCpuidLoggingInfo->MaxLogCount) 79 | pCpuidLoggingInfo->LoggingData[pCpuidLoggingInfo->CurrentDataLine++] = DataLine; 80 | else 81 | KdPrintError("Adjust the max logging count!.\n"); 82 | 83 | break; 84 | } 85 | 86 | CurrLink = CurrLink->Flink; 87 | 88 | } while (CurrLink->Flink != FirstLink); 89 | 90 | Cr4.SmapEnable = 1; 91 | __writecr4(Cr4.Flags); 92 | 93 | // Could rewrite cr3 but no point 94 | } 95 | } 96 | 97 | _Use_decl_annotations_ 98 | VOID 99 | ExitHandleInvept ( 100 | PVMM_EXIT_CONTEXT pExitContext, 101 | PVMM_GUEST_CONTEXT pGPContext 102 | ) 103 | { 104 | _invept(pGPContext->Rcx, pGPContext->Rdx); 105 | } 106 | 107 | _Use_decl_annotations_ 108 | VOID 109 | ExitHandleEptViolation ( 110 | PVMM_EXIT_CONTEXT pExitContext, 111 | PVMM_GUEST_CONTEXT pGPContext 112 | ) 113 | { 114 | __debugbreak(); 115 | 116 | // Page align guest-rip 117 | UINT64 PhysicalAddress = pExitContext->GuestPhysicalAddress & ~0xfffULL; 118 | 119 | PEPT_HOOKED_ENTRY pHookedEntry = CONTAINING_RECORD(pGlobalVmmContext->pEptRegion->HookList.Flink, EPT_HOOKED_ENTRY, EptHookedListEntry); 120 | 121 | PEPT_HOOKED_ENTRY pCurrEntry = pHookedEntry; 122 | 123 | KdPrintError("Ept violation: Physical address => 0x%llx Guest ip => 0x%llx.\n", PhysicalAddress, pExitContext->GuestRip); 124 | 125 | INT32 Found = 0; 126 | do 127 | { 128 | KdPrintError("CurrEntry PhysBase => 0x%llx\n", pCurrEntry->PhysBaseAddress); 129 | 130 | if (pCurrEntry->PhysBaseAddress == PhysicalAddress) 131 | { 132 | EPTE CurrentPte = *pCurrEntry->pPte; 133 | 134 | // If we enabled X, then R/W are 0. So toggle. 135 | if (CurrentPte.ExecuteAccess) 136 | { 137 | //__debugbreak(); 138 | *pCurrEntry->pPte = pCurrEntry->NoExecuteEntry; 139 | KdPrintError("Replaced with R/W entry\n"); 140 | } 141 | // If we have no X, then swap in the fake executable page. 142 | else if (!CurrentPte.ExecuteAccess) 143 | { 144 | //__debugbreak(); 145 | 146 | /* SMC IS NOT SO EASY TO SUPPORT 147 | * because im doing some slat stuff, and im playing around with smc on the page which im hooking, 148 | * everything works fine until i write to said page, then my hook doesnt hit anymore and i think its because the physical address of the page changes, 149 | * which is super weird to me cos its just some usermode page. 150 | 151 | * oh i guess after thinking about it a bit more, images are just section objects and the text section is probably marked cow 152 | * (since its not originally writeable) so that they can point to the same physical frame if multiple processes are spawned? 153 | * 154 | * to support it i guess i'd need to actually trap on accesses to the original pte, lol 155 | */ 156 | 157 | /* 158 | // Reflect writes to the page -- Account for self-modifying code 159 | CHAR CurrentPage[PAGE_SIZE]; 160 | 161 | // Disable SMAP 162 | CR4 Cr4; 163 | Cr4.Flags = __readcr4(); 164 | Cr4.SmapEnable = 0; 165 | __writecr4(Cr4.Flags); 166 | 167 | PHYSICAL_ADDRESS PA; 168 | PA.QuadPart = PhysicalAddress; 169 | 170 | // Swap in the kernel's DTB so we can access the user mode address space. 171 | __writecr3(pCurrEntry->ProcessKernelCr3.Flags); 172 | 173 | PVOID VirtualAddress = (PVOID)pCurrEntry->VirtBaseAddress; 174 | 175 | if (VirtualAddress == NULL) 176 | { 177 | KdPrintError("VirtualAddress for physical address 0x%llx was 0\n", PhysicalAddress); 178 | //__debugbreak(); 179 | } 180 | 181 | RtlCopyMemory( 182 | CurrentPage, 183 | VirtualAddress, 184 | PAGE_SIZE 185 | ); 186 | 187 | // Re-enable SMAP 188 | Cr4.SmapEnable = 1; 189 | __writecr4(Cr4.Flags); 190 | 191 | // Find any differences between the original page and current page 192 | for (int i = 0; i < PAGE_SIZE; i++) 193 | { 194 | if (CurrentPage[i] != pCurrEntry->OriginalPage[i]) 195 | { 196 | // Reflect changes to the X page 197 | pCurrEntry->FakePage[i] = CurrentPage[i]; 198 | } 199 | } 200 | */ 201 | *pCurrEntry->pPte = pCurrEntry->ExecuteOnlyEntry; 202 | KdPrintError("Replaced with X entry\n"); 203 | } 204 | 205 | Found = 1; 206 | break; 207 | } 208 | 209 | pCurrEntry = CONTAINING_RECORD(pCurrEntry->EptHookedListEntry.Flink, EPT_HOOKED_ENTRY, EptHookedListEntry); 210 | } while (pCurrEntry != pHookedEntry); 211 | 212 | if (!Found) 213 | KdPrintError("Could not find entry for 0x%llx\n", PhysicalAddress); 214 | } 215 | 216 | _Use_decl_annotations_ 217 | VOID 218 | ExitHandleRdMsr ( 219 | PVMM_EXIT_CONTEXT pExitContext, 220 | PVMM_GUEST_CONTEXT pGPContext 221 | ) 222 | { 223 | ULONG64 Value = __readmsr(pGPContext->Rcx); 224 | pGPContext->Rax = (Value) & 0xFFFFFFFF; 225 | pGPContext->Rdx = (Value >> 32) & 0xFFFFFFFF; 226 | } 227 | 228 | VOID 229 | ExitHandleWrMsr ( 230 | PVMM_EXIT_CONTEXT pExitContext, 231 | PVMM_GUEST_CONTEXT pGPContext 232 | ) 233 | { 234 | ULONG64 Value = pGPContext->Rdx; 235 | Value <<= 32; 236 | Value |= pGPContext->Rax; 237 | __writemsr(pGPContext->Rcx, Value); 238 | } 239 | -------------------------------------------------------------------------------- /Trashvisor/VmxUtils.c: -------------------------------------------------------------------------------- 1 | #include "VmxUtils.h" 2 | #include "ArchUtils.h" 3 | #include "VmxHost.h" 4 | 5 | _Must_inspect_result_ 6 | PGLOBAL_VMM_CONTEXT 7 | AllocateGlobalVmmContext ( 8 | ) 9 | { 10 | PHYSICAL_ADDRESS HighestAcceptableAddress; 11 | HighestAcceptableAddress.QuadPart = MAXULONG64; 12 | 13 | PGLOBAL_VMM_CONTEXT pGlobalVmmContext = (PGLOBAL_VMM_CONTEXT)ExAllocatePoolWithTag( 14 | NonPagedPoolNx, 15 | sizeof(GLOBAL_VMM_CONTEXT), 16 | 'MMVG' 17 | ); 18 | 19 | if (pGlobalVmmContext == NULL) 20 | { 21 | KdPrintError("ALlocateGlobalVmmContext: Could not allocate pGlobalVmmContext memory.\n"); 22 | goto Exit; 23 | } 24 | 25 | pGlobalVmmContext->LogicalProcessorCount = KeQueryActiveProcessorCountEx(ALL_PROCESSOR_GROUPS); 26 | pGlobalVmmContext->ActivatedProcessorCount = 0; 27 | 28 | ASSERT(pGlobalVmmContext->LogicalProcessorCount > 0); 29 | 30 | PLOCAL_VMM_CONTEXT* ppLocalVmmContexts = (PLOCAL_VMM_CONTEXT*)ExAllocatePoolWithTag( 31 | NonPagedPoolNx, 32 | sizeof(PLOCAL_VMM_CONTEXT) * pGlobalVmmContext->LogicalProcessorCount, 33 | 'VMLP' 34 | ); 35 | 36 | if (ppLocalVmmContexts == NULL) 37 | { 38 | KdPrintError("AllocateGlobalVmmContext: Could not allocate ppLocalVmmContext memory.\n"); 39 | goto Exit; 40 | } 41 | 42 | pGlobalVmmContext->ppLocalVmmContexts = ppLocalVmmContexts; 43 | 44 | for (ULONG i = 0u; i < pGlobalVmmContext->LogicalProcessorCount; i++) 45 | { 46 | PLOCAL_VMM_CONTEXT pCurrentVmmContext = AllocateLocalVmmContext(pGlobalVmmContext); 47 | 48 | if (pCurrentVmmContext == NULL) 49 | goto Exit; 50 | 51 | ppLocalVmmContexts[i] = pCurrentVmmContext; 52 | } 53 | 54 | pGlobalVmmContext->SystemCr3.Flags = __readcr3(); 55 | 56 | Exit: 57 | return pGlobalVmmContext; 58 | } 59 | 60 | _Use_decl_annotations_ 61 | PLOCAL_VMM_CONTEXT 62 | AllocateLocalVmmContext ( 63 | PGLOBAL_VMM_CONTEXT pGlobalVmmContext 64 | ) 65 | { 66 | PHYSICAL_ADDRESS HighestPhysicalAddress; 67 | HighestPhysicalAddress.QuadPart = MAXULONG64; 68 | 69 | PLOCAL_VMM_CONTEXT pLocalVmmContext = (PLOCAL_VMM_CONTEXT)MmAllocateContiguousMemory( 70 | sizeof(LOCAL_VMM_CONTEXT), 71 | HighestPhysicalAddress 72 | ); 73 | 74 | if (pLocalVmmContext == NULL) 75 | { 76 | KdPrintError("AllocateLocalVmmContext: Allocate failed.\n"); 77 | goto Exit; 78 | } 79 | 80 | RtlZeroMemory( 81 | pLocalVmmContext, 82 | sizeof(LOCAL_VMM_CONTEXT) 83 | ); 84 | 85 | pLocalVmmContext->pVmcs = AllocateVmcs(); 86 | 87 | if (pLocalVmmContext->pVmcs == NULL) 88 | goto Exit; 89 | 90 | pLocalVmmContext->pVmxOn = AllocateVmxOn(); 91 | 92 | if (pLocalVmmContext->pVmxOn == NULL) 93 | goto Exit; 94 | 95 | pLocalVmmContext->PhysVmcs = (PVOID)MmGetPhysicalAddress(pLocalVmmContext->pVmcs).QuadPart; 96 | pLocalVmmContext->PhysVmxOn = (PVOID)MmGetPhysicalAddress(pLocalVmmContext->pVmxOn).QuadPart; 97 | pLocalVmmContext->PhysMsrBitmap = (PVOID)MmGetPhysicalAddress(pLocalVmmContext->MsrBitmap).QuadPart; 98 | 99 | pLocalVmmContext->pGlobalVmmContext = pGlobalVmmContext; 100 | 101 | Exit: 102 | return pLocalVmmContext; 103 | } 104 | 105 | _Use_decl_annotations_ 106 | PVMCS 107 | AllocateVmcs ( 108 | ) 109 | { 110 | PHYSICAL_ADDRESS HighestPhysicalAddress; 111 | HighestPhysicalAddress.QuadPart = MAXULONG64; 112 | 113 | PVMCS pVmcs = (PVMCS)MmAllocateContiguousMemory( 114 | sizeof(VMCS), 115 | HighestPhysicalAddress 116 | ); 117 | 118 | if (pVmcs == NULL) 119 | { 120 | KdPrintError("AllocateVmcs: Allocate failed.\n"); 121 | goto Exit; 122 | } 123 | 124 | RtlZeroMemory( 125 | pVmcs, 126 | sizeof(VMCS) 127 | ); 128 | 129 | IA32_VMX_BASIC_REGISTER VmxBasicMsr; 130 | VmxBasicMsr.Flags = ReadMsr(IA32_VMX_BASIC); 131 | 132 | pVmcs->ShadowVmcsIndicator = 0; 133 | pVmcs->RevisionId = VmxBasicMsr.VmcsRevisionId; 134 | 135 | Exit: 136 | return pVmcs; 137 | } 138 | 139 | _Use_decl_annotations_ 140 | PVMXON 141 | AllocateVmxOn ( 142 | ) 143 | { 144 | PHYSICAL_ADDRESS HighestPhysicalAddress; 145 | HighestPhysicalAddress.QuadPart = MAXULONG64; 146 | 147 | PVMXON pVmxOn = (PVMXON)MmAllocateContiguousMemory( 148 | sizeof(VMXON), 149 | HighestPhysicalAddress 150 | ); 151 | 152 | if (pVmxOn == NULL) 153 | { 154 | KdPrintError("AllocateVmxOn: Allocate failed.\n"); 155 | goto Exit; 156 | } 157 | 158 | RtlZeroMemory( 159 | pVmxOn, 160 | sizeof(VMXON) 161 | ); 162 | 163 | IA32_VMX_BASIC_REGISTER VmxBasicMsr; 164 | VmxBasicMsr.Flags = ReadMsr(IA32_VMX_BASIC); 165 | 166 | pVmxOn->RevisionId = VmxBasicMsr.VmcsRevisionId; 167 | 168 | Exit: 169 | return pVmxOn; 170 | } 171 | 172 | _Use_decl_annotations_ 173 | PLOCAL_VMM_CONTEXT 174 | RetrieveLocalContext( 175 | ULONG ProcessorNumber, 176 | PGLOBAL_VMM_CONTEXT pGlobalVmmContext 177 | ) 178 | { 179 | ASSERT(ProcessorNumber < pGlobalVmmContext->LogicalProcessorCount); 180 | 181 | return pGlobalVmmContext->ppLocalVmmContexts[ProcessorNumber]; 182 | } 183 | 184 | _Use_decl_annotations_ 185 | VOID 186 | CaptureMiscContext ( 187 | PMISC_CONTEXT pMiscContext 188 | ) 189 | { 190 | pMiscContext->Cr0.Flags = __readcr0(); 191 | pMiscContext->Cr3.Flags = __readcr3(); 192 | pMiscContext->Cr4.Flags = __readcr4(); 193 | pMiscContext->Cr4.OsXsave = 1; 194 | 195 | pMiscContext->Dr7.Flags = __readdr(7); 196 | 197 | _sgdt(&pMiscContext->Gdtr.Limit); 198 | __sidt(&pMiscContext->Idtr.Limit); 199 | 200 | pMiscContext->Tr.Flags = _str(); 201 | pMiscContext->Ldtr.Flags = _sldt(); 202 | } 203 | 204 | _Use_decl_annotations_ 205 | BOOLEAN 206 | EnableVmx ( 207 | _In_ PLOCAL_VMM_CONTEXT pLocalVmmContext 208 | ) 209 | { 210 | BOOLEAN bStatus = TRUE; 211 | 212 | ULONGLONG Cr0Fixed0 = ReadMsr(IA32_VMX_CR0_FIXED0); 213 | ULONGLONG Cr0Fixed1 = ReadMsr(IA32_VMX_CR0_FIXED1); 214 | ULONGLONG Cr4Fixed0 = ReadMsr(IA32_VMX_CR4_FIXED0); 215 | ULONGLONG Cr4Fixed1 = ReadMsr(IA32_VMX_CR4_FIXED1); 216 | 217 | CR0 Cr0; 218 | CR4 Cr4; 219 | 220 | Cr0.Flags = __readcr0(); 221 | Cr4.Flags = __readcr4(); 222 | 223 | Cr0.Flags |= Cr0Fixed0; 224 | Cr0.Flags &= Cr0Fixed1; 225 | 226 | Cr4.Flags |= Cr4Fixed0; 227 | Cr4.Flags &= Cr4Fixed1; 228 | 229 | Cr4.VmxEnable = 1; 230 | 231 | __writecr0(Cr0.Flags); 232 | __writecr4(Cr4.Flags); 233 | 234 | if (__vmx_on(&pLocalVmmContext->PhysVmxOn)) 235 | { 236 | KdPrintError("EnableVmx: VmxOn failed.\n"); 237 | bStatus = FALSE; 238 | goto Exit; 239 | } 240 | 241 | if (__vmx_vmclear(&pLocalVmmContext->PhysVmcs)) 242 | { 243 | KdPrintError("EnableVmx: VmxVmClear failed.\n"); 244 | bStatus = FALSE; 245 | goto Exit; 246 | } 247 | 248 | if (__vmx_vmptrld(&pLocalVmmContext->PhysVmcs)) 249 | { 250 | KdPrintError("EnableVmx: VmxVmPtrLd failed.\n"); 251 | bStatus = FALSE; 252 | goto Exit; 253 | } 254 | 255 | Exit: 256 | return bStatus; 257 | } 258 | 259 | _Use_decl_annotations_ 260 | VOID 261 | CaptureState ( 262 | PLOCAL_VMM_CONTEXT pLocalVmmContext 263 | ) 264 | { 265 | CaptureMiscContext(&pLocalVmmContext->MiscRegisterContext); 266 | RtlCaptureContext(&pLocalVmmContext->RegisterContext); 267 | } 268 | 269 | _Use_decl_annotations_ 270 | VOID 271 | GetSegmentSetup ( 272 | PSEGMENT_SETUP pSegmentSetup, 273 | UINT16 Selector, 274 | UINT64 GdtrBase 275 | ) 276 | { 277 | SEGMENT_DESCRIPTOR_32 SegmentDesc = GetSegmentDescriptor(Selector, GdtrBase); 278 | 279 | pSegmentSetup->BaseAddress = GetSegmentBase(SegmentDesc); 280 | pSegmentSetup->SegmentLimit = GetSegmentLimit(Selector); 281 | pSegmentSetup->AccessRights = GetAccessRights(SegmentDesc); 282 | } 283 | 284 | _Use_decl_annotations_ 285 | VOID 286 | GetSysSegmentSetup ( 287 | PSEGMENT_SETUP pSegmentSetup, 288 | UINT16 Selector, 289 | UINT64 GdtrBase 290 | ) 291 | { 292 | SEGMENT_DESCRIPTOR_64 SegmentDesc = GetSysSegmentDescriptor(Selector, GdtrBase); 293 | 294 | pSegmentSetup->BaseAddress = GetSysSegmentBase(SegmentDesc); 295 | pSegmentSetup->SegmentLimit = GetSegmentLimit(Selector); 296 | pSegmentSetup->AccessRights = GetSysAccessRights(SegmentDesc); 297 | } 298 | 299 | _Use_decl_annotations_ 300 | UINT32 301 | GetAccessRights ( 302 | SEGMENT_DESCRIPTOR_32 SegmentDesc 303 | ) 304 | { 305 | VMCS_ACCESS_RIGHTS AccessRights; 306 | AccessRights.Flags = 0; 307 | 308 | AccessRights.SegmentType = SegmentDesc.Type; 309 | AccessRights.S = SegmentDesc.DescriptorType; 310 | AccessRights.DPL = SegmentDesc.DescriptorPrivilegeLevel; 311 | AccessRights.P = SegmentDesc.Present; 312 | AccessRights.Reserved1 = 0; 313 | AccessRights.AVL = SegmentDesc.System; 314 | AccessRights.L = SegmentDesc.LongMode; 315 | AccessRights.DB = SegmentDesc.DefaultBig; 316 | AccessRights.G = SegmentDesc.Granularity; 317 | AccessRights.Unusable = !AccessRights.P; 318 | 319 | return AccessRights.Flags; 320 | } 321 | 322 | _Use_decl_annotations_ 323 | UINT32 324 | GetSysAccessRights ( 325 | SEGMENT_DESCRIPTOR_64 SegmentDesc 326 | ) 327 | { 328 | VMCS_ACCESS_RIGHTS AccessRights; 329 | AccessRights.Flags = 0; 330 | 331 | AccessRights.SegmentType = SegmentDesc.Type; 332 | AccessRights.S = SegmentDesc.DescriptorType; 333 | AccessRights.DPL = SegmentDesc.DescriptorPrivilegeLevel; 334 | AccessRights.P = SegmentDesc.Present; 335 | AccessRights.Reserved1 = 0; 336 | AccessRights.AVL = SegmentDesc.System; 337 | AccessRights.L = SegmentDesc.LongMode; 338 | AccessRights.DB = SegmentDesc.DefaultBig; 339 | AccessRights.G = SegmentDesc.Granularity; 340 | AccessRights.Unusable = !AccessRights.P; 341 | 342 | return AccessRights.Flags; 343 | } 344 | 345 | _Use_decl_annotations_ 346 | ULONG32 347 | EnforceRequiredBits ( 348 | ULONG64 RequiredBits, 349 | ULONG32 BitsToSet 350 | ) 351 | { 352 | UINT32 Required0Bits = (RequiredBits & 0xFFFFFFFF); 353 | UINT32 Allowed1Bits = ((RequiredBits >> 32) & 0xFFFFFFFF); 354 | 355 | if ((BitsToSet & Allowed1Bits) != BitsToSet) 356 | KdPrintError("Bits to set: %u\n Allowed bits: %u\n", BitsToSet, Allowed1Bits); 357 | 358 | BitsToSet |= Required0Bits; 359 | BitsToSet &= Allowed1Bits; 360 | 361 | return BitsToSet; 362 | } 363 | 364 | VOID 365 | GetVmxInstructionError ( 366 | ) 367 | { 368 | SIZE_T Error; 369 | __vmx_vmread(VMCS_VM_INSTRUCTION_ERROR, &Error); 370 | 371 | __debugbreak(); 372 | } 373 | -------------------------------------------------------------------------------- /Trashvisor/VmxUtils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Ept.h" 3 | 4 | typedef VMXON* PVMXON; 5 | typedef struct _LOCAL_VMM_CONTEXT* PLOCAL_VMM_CONTEXT; 6 | 7 | typedef struct _MISC_CONTEXT 8 | { 9 | CR0 Cr0; 10 | CR3 Cr3; 11 | CR4 Cr4; 12 | DR7 Dr7; 13 | 14 | SEGMENT_DESCRIPTOR_REGISTER_64 Gdtr; 15 | SEGMENT_DESCRIPTOR_REGISTER_64 Idtr; 16 | 17 | SEGMENT_SELECTOR Tr; 18 | SEGMENT_SELECTOR Ldtr; 19 | } MISC_CONTEXT, *PMISC_CONTEXT; 20 | 21 | typedef struct _GLOBAL_VMM_CONTEXT 22 | { 23 | PLOCAL_VMM_CONTEXT* ppLocalVmmContexts; 24 | ULONG LogicalProcessorCount; 25 | ULONG ActivatedProcessorCount; 26 | CR3 SystemCr3; 27 | PEPT_REGION pEptRegion; 28 | EPT_POINTER EptPointer; 29 | EPT_MTRR_DESCRIPTOR EptMtrrDescriptors[8]; 30 | } GLOBAL_VMM_CONTEXT, *PGLOBAL_VMM_CONTEXT; 31 | 32 | typedef struct _VMM_GUEST_CONTEXT 33 | { 34 | ULONG64 Rax; 35 | ULONG64 Rcx; 36 | ULONG64 Rdx; 37 | ULONG64 Rbx; 38 | 39 | ULONG64 Rsp; 40 | ULONG64 Rbp; 41 | ULONG64 Rsi; 42 | ULONG64 Rdi; 43 | 44 | ULONG64 R8; 45 | ULONG64 R9; 46 | ULONG64 R10; 47 | ULONG64 R11; 48 | ULONG64 R12; 49 | ULONG64 R13; 50 | ULONG64 R14; 51 | ULONG64 R15; 52 | } VMM_GUEST_CONTEXT, *PVMM_GUEST_CONTEXT; 53 | 54 | typedef struct _LOCAL_VMM_CONTEXT 55 | { 56 | BOOLEAN VmxActivated; 57 | 58 | CONTEXT RegisterContext; 59 | MISC_CONTEXT MiscRegisterContext; 60 | 61 | //PEPT_REGION pEptRegion; 62 | //EPT_POINTER EptPointer; 63 | 64 | PVMXON pVmxOn; 65 | PVMCS pVmcs; 66 | PVOID PhysVmxOn; 67 | PVOID PhysVmcs; 68 | 69 | DECLSPEC_ALIGN(PAGE_SIZE) CHAR MsrBitmap[4096]; 70 | PVOID PhysMsrBitmap; 71 | 72 | PGLOBAL_VMM_CONTEXT pGlobalVmmContext; 73 | 74 | DECLSPEC_ALIGN(PAGE_SIZE) CHAR HostStack[0x1000 * 0xA]; 75 | UINT_PTR StackTop; 76 | } LOCAL_VMM_CONTEXT, *PLOCAL_VMM_CONTEXT; 77 | 78 | typedef union _VMCS_ACCESS_RIGHTS 79 | { 80 | struct 81 | { 82 | UINT32 SegmentType : 4; 83 | UINT32 S : 1; 84 | UINT32 DPL : 2; 85 | UINT32 P : 1; 86 | UINT32 Reserved1 : 4; 87 | UINT32 AVL : 1; 88 | UINT32 L : 1; 89 | UINT32 DB : 1; 90 | UINT32 G : 1; 91 | UINT32 Unusable : 1; 92 | }; 93 | 94 | struct 95 | { 96 | UINT16 FlagsLowerWord; 97 | UINT16 FlagsHigherWord; 98 | }; 99 | 100 | UINT32 Flags; 101 | } VMCS_ACCESS_RIGHTS, *PVMCS_ACCESS_RIGHTS; 102 | 103 | _Must_inspect_result_ 104 | PGLOBAL_VMM_CONTEXT 105 | AllocateGlobalVmmContext ( 106 | ); 107 | 108 | _Must_inspect_result_ 109 | PLOCAL_VMM_CONTEXT 110 | AllocateLocalVmmContext ( 111 | _In_ PGLOBAL_VMM_CONTEXT pGlobalVmmContext 112 | ); 113 | 114 | _Must_inspect_result_ 115 | PVMCS 116 | AllocateVmcs ( 117 | ); 118 | 119 | _Must_inspect_result_ 120 | PVMXON 121 | AllocateVmxOn ( 122 | ); 123 | 124 | _Must_inspect_result_ 125 | PLOCAL_VMM_CONTEXT 126 | RetrieveLocalContext ( 127 | _In_ ULONG ProcessorNumber, 128 | _In_ PGLOBAL_VMM_CONTEXT pGlobalVmmContext 129 | ); 130 | 131 | VOID 132 | CaptureState ( 133 | _In_ PLOCAL_VMM_CONTEXT pLocalVmmContext 134 | ); 135 | 136 | VOID 137 | CaptureMiscContext ( 138 | _In_ PMISC_CONTEXT pMiscContext 139 | ); 140 | 141 | BOOLEAN 142 | EnableVmx ( 143 | _In_ PLOCAL_VMM_CONTEXT pLocalVmmContext 144 | ); 145 | 146 | VOID 147 | GetSegmentSetup ( 148 | _Out_ PSEGMENT_SETUP pSegmentSetup, 149 | _In_ UINT16 Selector, 150 | _In_ UINT64 GdtrBase 151 | ); 152 | 153 | VOID 154 | GetSysSegmentSetup ( 155 | _Out_ PSEGMENT_SETUP pSegmentSetup, 156 | _In_ UINT16 Selector, 157 | _In_ UINT64 GdtrBase 158 | ); 159 | 160 | UINT32 161 | GetAccessRights ( 162 | _In_ SEGMENT_DESCRIPTOR_32 SegmentDesc 163 | ); 164 | 165 | UINT32 166 | GetSysAccessRights( 167 | _In_ SEGMENT_DESCRIPTOR_64 SegmentDesc 168 | ); 169 | 170 | ULONG32 171 | EnforceRequiredBits( 172 | _In_ ULONG64 RequiredBits, 173 | _In_ ULONG32 BitsToSet 174 | ); 175 | --------------------------------------------------------------------------------