More irp implementation

This commit is contained in:
momo5502 2022-04-03 19:10:04 +02:00
parent 01ed54e8a2
commit 42c7f649f9
12 changed files with 271 additions and 4 deletions

View File

@ -1,2 +1,3 @@
add_subdirectory(shared)
add_subdirectory(driver) add_subdirectory(driver)
add_subdirectory(runner) add_subdirectory(runner)

View File

@ -26,4 +26,5 @@ add_custom_command(TARGET driver
target_link_libraries(driver target_link_libraries(driver
vcrtl_driver vcrtl_driver
ia32_doc ia32_doc
shared
) )

View File

@ -3,8 +3,9 @@
#include "logging.hpp" #include "logging.hpp"
#include "exception.hpp" #include "exception.hpp"
#include "string.hpp" #include "string.hpp"
#include "memory.hpp"
#define HELLO_DRV_IOCTL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_NEITHER, FILE_ANY_ACCESS) #include <irp_data.hpp>
namespace namespace
{ {
@ -32,6 +33,19 @@ namespace
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
// TODO: This is vulnerable as fuck. Optimize!
void apply_hook(hook_request* request)
{
const auto address = reinterpret_cast<uint64_t>(request->target_address);
const auto aligned_address = address & (PAGE_SIZE - 1);
const auto offset = address - aligned_address;
uint8_t buffer[PAGE_SIZE * 2]{0};
memory::query_process_physical_page(request->process_id, reinterpret_cast<void*>(address), buffer);
debug_log("Data: %s\n", buffer + offset);
}
_Function_class_(DRIVER_DISPATCH) NTSTATUS io_ctl_handler( _Function_class_(DRIVER_DISPATCH) NTSTATUS io_ctl_handler(
PDEVICE_OBJECT /*device_object*/, const PIRP irp) PDEVICE_OBJECT /*device_object*/, const PIRP irp)
{ {
@ -51,6 +65,9 @@ namespace
case HELLO_DRV_IOCTL: case HELLO_DRV_IOCTL:
debug_log("Hello from the Driver!\n"); debug_log("Hello from the Driver!\n");
break; break;
case HOOK_DRV_IOCTL:
apply_hook(static_cast<hook_request*>(irp_sp->Parameters.DeviceIoControl.Type3InputBuffer));
break;
default: default:
debug_log("Invalid IOCTL Code: 0x%X\n", ioctr_code); debug_log("Invalid IOCTL Code: 0x%X\n", ioctr_code);
irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;

View File

@ -1,6 +1,7 @@
#include "std_include.hpp" #include "std_include.hpp"
#include "memory.hpp" #include "memory.hpp"
#include "string.hpp" #include "string.hpp"
#include "process.hpp"
namespace memory namespace memory
{ {
@ -103,4 +104,15 @@ namespace memory
ExFreePool(memory); ExFreePool(memory);
} }
} }
uint64_t query_process_physical_page(const uint32_t process_id, void* address,
uint8_t buffer[PAGE_SIZE])
{
const auto process_handle = process::find_process_by_id(process_id);
process::scoped_process_attacher attacher{process_handle};
memcpy(buffer, address, PAGE_SIZE);
return get_physical_address(address);
}
} }

View File

@ -27,4 +27,6 @@ namespace memory
_IRQL_requires_max_(DISPATCH_LEVEL) _IRQL_requires_max_(DISPATCH_LEVEL)
void free_non_paged_memory(void* memory); void free_non_paged_memory(void* memory);
uint64_t query_process_physical_page(uint32_t process_id, void* address, uint8_t buffer[PAGE_SIZE]);
} }

View File

@ -4,6 +4,8 @@
extern "C" { extern "C" {
#endif #endif
// ----------------------------------------
NTKERNELAPI NTKERNELAPI
_IRQL_requires_max_(APC_LEVEL) _IRQL_requires_max_(APC_LEVEL)
_IRQL_requires_min_(PASSIVE_LEVEL) _IRQL_requires_min_(PASSIVE_LEVEL)
@ -14,6 +16,7 @@ KeGenericCallDpc(
_In_opt_ PVOID Context _In_opt_ PVOID Context
); );
// ----------------------------------------
NTKERNELAPI NTKERNELAPI
_IRQL_requires_(DISPATCH_LEVEL) _IRQL_requires_(DISPATCH_LEVEL)
@ -23,6 +26,8 @@ KeSignalCallDpcDone(
_In_ PVOID SystemArgument1 _In_ PVOID SystemArgument1
); );
// ----------------------------------------
NTKERNELAPI NTKERNELAPI
_IRQL_requires_(DISPATCH_LEVEL) _IRQL_requires_(DISPATCH_LEVEL)
_IRQL_requires_same_ _IRQL_requires_same_
@ -31,6 +36,8 @@ KeSignalCallDpcSynchronize(
_In_ PVOID SystemArgument2 _In_ PVOID SystemArgument2
); );
// ----------------------------------------
#if (NTDDI_VERSION < NTDDI_WIN8) #if (NTDDI_VERSION < NTDDI_WIN8)
_Must_inspect_result_ _Must_inspect_result_
_IRQL_requires_max_(DISPATCH_LEVEL) _IRQL_requires_max_(DISPATCH_LEVEL)
@ -46,6 +53,8 @@ MmAllocateContiguousNodeMemory(
); );
#endif #endif
// ----------------------------------------
NTSYSAPI NTSYSAPI
VOID VOID
NTAPI NTAPI
@ -53,6 +62,60 @@ RtlCaptureContext(
_Out_ PCONTEXT ContextRecord _Out_ PCONTEXT ContextRecord
); );
// ----------------------------------------
typedef struct _KAPC_STATE
{
LIST_ENTRY ApcListHead[MaximumMode];
struct _KPROCESS* Process;
BOOLEAN KernelApcInProgress;
BOOLEAN KernelApcPending;
BOOLEAN UserApcPending;
} KAPC_STATE, *PKAPC_STATE, *PRKAPC_STATE;
// ----------------------------------------
NTKERNELAPI
VOID
KeStackAttachProcess(
__inout PEPROCESS PROCESS,
__out PRKAPC_STATE ApcState
);
// ----------------------------------------
NTKERNELAPI
VOID
KeUnstackDetachProcess(
__in PRKAPC_STATE ApcState
);
// ----------------------------------------
NTKERNELAPI
NTSTATUS
PsLookupProcessByProcessId(
IN HANDLE ProcessId,
OUT PEPROCESS* Process
);
// ----------------------------------------
NTKERNELAPI
PVOID
PsGetProcessSectionBaseAddress(
__in PEPROCESS Process
);
// ----------------------------------------
NTKERNELAPI
PPEB
NTAPI
PsGetProcessPeb(
IN PEPROCESS Process
);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

88
src/driver/process.cpp Normal file
View File

@ -0,0 +1,88 @@
#include "std_include.hpp"
#include "process.hpp"
#include "type_traits.hpp"
#include "exception.hpp"
namespace process
{
process_handle::process_handle(const PEPROCESS handle)
: handle_(handle)
{
}
process_handle::~process_handle()
{
this->release();
}
process_handle::process_handle(process_handle&& obj) noexcept
: process_handle()
{
this->operator=(std::move(obj));
}
process_handle& process_handle::operator=(process_handle&& obj) noexcept
{
if (this != &obj)
{
this->release();
this->handle_ = obj.handle_;
obj.handle_ = nullptr;
}
return *this;
}
process_handle::operator bool() const
{
return this->handle_ != nullptr;
}
process_handle::operator PEPROCESS() const
{
return this->handle_;
}
bool process_handle::is_alive() const
{
LARGE_INTEGER zero_time{};
zero_time.QuadPart = 0;
return KeWaitForSingleObject(this->handle_, Executive, KernelMode, FALSE, &zero_time) != STATUS_WAIT_0;
}
void process_handle::release()
{
if (this->handle_)
{
ObDereferenceObject(this->handle_);
this->handle_ = nullptr;
}
}
process_handle find_process_by_id(const uint32_t process_id)
{
PEPROCESS process{};
if (PsLookupProcessByProcessId(HANDLE(process_id), &process) != STATUS_SUCCESS)
{
return {};
}
return process_handle{process};
}
scoped_process_attacher::scoped_process_attacher(const process_handle& process)
{
if (!process || !process.is_alive())
{
throw std::runtime_error("Invalid process");
}
KeStackAttachProcess(process, &this->apc_state_);
}
scoped_process_attacher::~scoped_process_attacher()
{
KeUnstackDetachProcess(&this->apc_state_);
}
}

46
src/driver/process.hpp Normal file
View File

@ -0,0 +1,46 @@
#pragma once
namespace process
{
class process_handle
{
public:
process_handle() = default;
process_handle(PEPROCESS handle);
~process_handle();
process_handle(process_handle&& obj) noexcept;
process_handle& operator=(process_handle&& obj) noexcept;
process_handle(const process_handle&) = delete;
process_handle& operator=(const process_handle&) = delete;
operator bool() const;
operator PEPROCESS() const;
bool is_alive() const;
private:
PEPROCESS handle_{nullptr};
void release();
};
process_handle find_process_by_id(uint32_t process_id);
class scoped_process_attacher
{
public:
scoped_process_attacher(const process_handle& process);
~scoped_process_attacher();
scoped_process_attacher(scoped_process_attacher&& obj) noexcept = delete;
scoped_process_attacher& operator=(scoped_process_attacher&& obj) noexcept = delete;
scoped_process_attacher(const scoped_process_attacher&) = delete;
scoped_process_attacher& operator=(const scoped_process_attacher&) = delete;
private:
KAPC_STATE apc_state_{};
};
}

View File

@ -13,3 +13,7 @@ target_precompile_headers(runner
set_property(TARGET runner APPEND_STRING PROPERTY LINK_FLAGS " /MANIFESTUAC:\"level='requireAdministrator'\"") set_property(TARGET runner APPEND_STRING PROPERTY LINK_FLAGS " /MANIFESTUAC:\"level='requireAdministrator'\"")
add_dependencies(runner driver) add_dependencies(runner driver)
target_link_libraries(runner
shared
)

View File

@ -3,9 +3,9 @@
#include "driver.hpp" #include "driver.hpp"
#include "driver_device.hpp" #include "driver_device.hpp"
#pragma comment(lib, "Shlwapi.lib") #include <irp_data.hpp>
#define HELLO_DRV_IOCTL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_NEITHER, FILE_ANY_ACCESS) #pragma comment(lib, "Shlwapi.lib")
BOOL send_ioctl(HANDLE device, DWORD ioctl_code) BOOL send_ioctl(HANDLE device, DWORD ioctl_code)
{ {
@ -53,6 +53,17 @@ void unsafe_main(const int /*argc*/, char* /*argv*/[])
(void)driver_device.send(HELLO_DRV_IOCTL, input); (void)driver_device.send(HELLO_DRV_IOCTL, input);
MessageBoxA(0, "Service started!", 0, 0); MessageBoxA(0, "Service started!", 0, 0);
hook_request hook_request{};
hook_request.process_id = GetCurrentProcessId();
hook_request.target_address = "My Message!";
input.assign(reinterpret_cast<uint8_t*>(&hook_request),
reinterpret_cast<uint8_t*>(&hook_request) + sizeof(hook_request));
(void)driver_device.send(HOOK_DRV_IOCTL, input);
MessageBoxA(0, "Press ok to exit!", 0, 0);
} }
int main(const int argc, char* argv[]) int main(const int argc, char* argv[])
@ -69,7 +80,7 @@ int main(const int argc, char* argv[])
} }
catch (...) catch (...)
{ {
printf("An unknown error occurd!\n"); printf("An unknown error occured!\n");
return 1; return 1;
} }
} }

View File

@ -0,0 +1,8 @@
file(GLOB shared_sources ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
file(GLOB shared_headers ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp)
add_library(shared INTERFACE
${shared_headers}
)
target_include_directories(shared INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})

14
src/shared/irp_data.hpp Normal file
View File

@ -0,0 +1,14 @@
#pragma once
#define HELLO_DRV_IOCTL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_NEITHER, FILE_ANY_ACCESS)
#define HOOK_DRV_IOCTL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_NEITHER, FILE_ANY_ACCESS)
static_assert(sizeof(void*) == 8);
struct hook_request
{
uint32_t process_id{};
const void* target_address{};
const void* source_data{};
uint64_t source_data_size{};
};