diff --git a/VDM/main.cpp b/VDM/main.cpp index 4d36468..67cc8df 100644 --- a/VDM/main.cpp +++ b/VDM/main.cpp @@ -2,10 +2,10 @@ int __cdecl main(int argc, char** argv) { - const auto [drv_handle, drv_key] = vdm::load_drv(); - if (!drv_handle || drv_key.empty()) + const auto [drv_handle, drv_key, load_status] = vdm::load_drv(); + if (drv_handle == INVALID_HANDLE_VALUE || load_status != STATUS_SUCCESS) { - std::printf("[!] unable to load vulnerable driver...\n"); + std::printf("[!] unable to load vulnerable driver... reason -> 0x%x\n", load_status); return -1; } @@ -46,9 +46,11 @@ int __cdecl main(int argc, char** argv) ); std::printf("[+] kernel MZ -> 0x%x\n", mz_bytes); - if (!vdm::unload_drv(drv_handle, drv_key)) + auto unload_result = vdm::unload_drv(drv_handle, drv_key); + + if (unload_result != STATUS_SUCCESS) { - std::printf("[!] unable to unload vulnerable driver...\n"); + std::printf("[!] unable to unload vulnerable driver... reason -> 0x%x\n", unload_result); return -1; } diff --git a/VDM/util/loadup.hpp b/VDM/util/loadup.hpp index c2f2890..bab26cd 100644 --- a/VDM/util/loadup.hpp +++ b/VDM/util/loadup.hpp @@ -29,6 +29,7 @@ #include #include #include +#include #pragma comment(lib, "ntdll.lib") extern "C" NTSTATUS NtLoadDriver(PUNICODE_STRING); @@ -172,7 +173,7 @@ namespace driver } } - __forceinline auto load(const std::string& drv_path, const std::string& service_name) -> bool + __forceinline auto load(const std::string& drv_path, const std::string& service_name) -> NTSTATUS { if (!util::enable_privilege(L"SeLoadDriverPrivilege")) return false; @@ -189,10 +190,10 @@ namespace driver RtlInitAnsiString(&driver_rep_path_cstr, reg_path.c_str()); RtlAnsiStringToUnicodeString(&driver_reg_path_unicode, &driver_rep_path_cstr, true); - return ERROR_SUCCESS == NtLoadDriver(&driver_reg_path_unicode); + return NtLoadDriver(&driver_reg_path_unicode); } - __forceinline auto load(const std::vector& drv_buffer) -> std::tuple + __forceinline auto load(const std::vector& drv_buffer) -> std::pair { static const auto random_file_name = [](std::size_t length) -> std::string { @@ -220,13 +221,13 @@ namespace driver return { load(file_path, service_name), service_name }; } - __forceinline auto load(const std::uint8_t* buffer, const std::size_t size) -> std::tuple + __forceinline auto load(const std::uint8_t* buffer, const std::size_t size) -> std::pair { std::vector image(buffer, buffer + size); return load(image); } - __forceinline auto unload(const std::string& service_name) -> bool + __forceinline auto unload(const std::string& service_name) -> NTSTATUS { std::string reg_path("\\Registry\\Machine\\System\\CurrentControlSet\\Services\\"); reg_path += service_name; @@ -235,22 +236,25 @@ namespace driver UNICODE_STRING driver_reg_path_unicode; RtlInitAnsiString(&driver_rep_path_cstr, reg_path.c_str()); - RtlAnsiStringToUnicodeString(&driver_reg_path_unicode, &driver_rep_path_cstr, true); + RtlAnsiStringToUnicodeString( + &driver_reg_path_unicode, &driver_rep_path_cstr, true); - const bool unload_drv = STATUS_SUCCESS == NtUnloadDriver(&driver_reg_path_unicode); - const auto image_path = std::filesystem::temp_directory_path().string() + service_name; - const bool delete_reg = util::delete_service_entry(service_name); + const bool unload_result = + NtUnloadDriver(&driver_reg_path_unicode); + util::delete_service_entry(service_name); // sometimes you cannot delete the driver off disk because there are still handles open // to the driver, this means the driver is still loaded into the kernel... try { - std::filesystem::remove(image_path); + std::filesystem::remove( + std::filesystem::temp_directory_path() + .string() + service_name); } catch (std::exception& e) { - return false; + return STATUS_ABANDONED; } - return delete_reg && unload_drv; + return unload_result; } } \ No newline at end of file diff --git a/VDM/vdm/vdm.hpp b/VDM/vdm/vdm.hpp index d7d66b4..ac3ba6c 100644 --- a/VDM/vdm/vdm.hpp +++ b/VDM/vdm/vdm.hpp @@ -23,7 +23,7 @@ typedef struct _gdrv_t namespace vdm { inline HANDLE drv_handle; - __forceinline auto load_drv() -> std::pair + __forceinline auto load_drv() -> std::tuple { const auto [result, key] = driver::load( @@ -31,8 +31,8 @@ namespace vdm sizeof(vdm::raw_driver) ); - if (!result) - return { {}, {} }; + if (result != STATUS_SUCCESS) + return { {}, {}, result }; vdm::drv_handle = CreateFile( "\\\\.\\GIO", @@ -44,12 +44,15 @@ namespace vdm NULL ); - return { vdm::drv_handle, key }; + return { vdm::drv_handle, key, result }; } - __forceinline bool unload_drv(HANDLE drv_handle, std::string drv_key) + __forceinline auto unload_drv(HANDLE drv_handle, std::string drv_key) -> NTSTATUS { - return CloseHandle(drv_handle) && driver::unload(drv_key); + if (!CloseHandle(drv_handle)) + return STATUS_FAIL_CHECK; + + return driver::unload(drv_key); } __forceinline bool read_phys(void* addr, void* buffer, std::size_t size)