Hey, guys! I've started writing the kernel framework for easy development of drivers.
It includes:
* Usigned drivers mapping
* Remote code execution
* Read/write/allocate memory of another processes without handles
* API for memory, processes and threads manipulations
* IO ports, MSRs and more CPU-specific functions
* Creating user and system threads
* Full support of C++17 (without C++ exceptions)
* Ready-to-use IOCTL dispatcher and minifilter template
* Usermode wrapper and *.dll with all supported functions
* Usermode callbacks for handles, processes/threads creation, modules loading (ObRegisterCallbacks and PsSet***NotifyRoutine usermode filters)
Files hierarchy:
Kernel API: /Kernel-Bridge/API
Usermode API: /User-Bridge/API & /SharedTypes/
All of supported functions you can see in "SharedTypes/CtlTypes.h".
GitHub link: https://github.com/HoShiMin/Kernel-Bridge
Samples:
Reading process memory:
It includes:
* Usigned drivers mapping
* Remote code execution
* Read/write/allocate memory of another processes without handles
* API for memory, processes and threads manipulations
* IO ports, MSRs and more CPU-specific functions
* Creating user and system threads
* Full support of C++17 (without C++ exceptions)
* Ready-to-use IOCTL dispatcher and minifilter template
* Usermode wrapper and *.dll with all supported functions
* Usermode callbacks for handles, processes/threads creation, modules loading (ObRegisterCallbacks and PsSet***NotifyRoutine usermode filters)
Files hierarchy:
Kernel API: /Kernel-Bridge/API
Usermode API: /User-Bridge/API & /SharedTypes/
All of supported functions you can see in "SharedTypes/CtlTypes.h".
GitHub link: https://github.com/HoShiMin/Kernel-Bridge
Samples:
Reading process memory:
Code: Select all
Unsigned drivers loading:
#include <Windows.h>
#include "WdkTypes.h"
#include "CtlTypes.h"
#include "User-Bridge.h"
...
// Loading as minifilter with specified altitude to use extended features:
KbLoader::KbLoadAsFilter(L"N:\\Folder\\Kernel-Bridge.sys", L"260000");
constexpr int Size = 64;
UCHAR Buffer[Size] = {};
using namespace Processes::MemoryManagement;
BOOL Status = KbReadProcessMemory(
ProcessId,
0x7FFF0000, // Desired address in context of ProcessId
&Buffer,
Size
);
if (Status) printf("All good!\r\n");
...
KbLoader::KbUnload();
Code: Select all
Remote code execution through an APC delivery:
#include "WdkTypes.h"
#include "CtlTypes.h"
#include "User-Bridge.h"
#include "Rtl-Bridge.h"
...
// Read *.sys from disk:
PVOID SysImage = VirtualAlloc(...);
ReadFile(hSysImage, SysImage, ...);
// Load unsigned driver:
KbRtl::KbMapDriver(SysImage, L"\\Driver\\YourDriverName");
Code: Select all
Execution custom usermode shells in Ring0:
#include "CtlTypes.h"
#include "User-Bridge.h"
...
using namespace Processes::Apc;
// Delivery APC to the current NON-ALERTABLE (!) thread:
KbQueueUserApc(
GetCurrentThreadId(),
[](PVOID Argument) -> VOID {
printf(
"APC delivered to non-alertable thread %i with arg %lli\r\n",
GetCurrentThreadId(),
reinterpret_cast<UINT64>(Argument)
);
},
reinterpret_cast<PVOID>(0x12345)
);
Code: Select all
Usermode Ps*** and Ob*** callbacks:
#include "CtlTypes.h"
#include "User-Bridge.h"
using namespace KernelShells;
...
ULONG Result = 0;
KbExecuteShellCode(
[](
_GetKernelProcAddress GetKernelProcAddress,
OPTIONAL IN OUT PVOID Argument
) -> ULONG {
using _KeStallExecutionProcessor = VOID(NTAPI*)(ULONG);
auto Stall = static_cast<_KeStallExecutionProcessor>(
GetKernelProcAddress(L"KeStallExecutionProcessor")
);
Stall(1000 * 1000); // Stall CPU for 1 second
return 1337;
},
NULL,
&Result
);
Code: Select all
#include <Windows.h>
#include <fltUser.h>
#include "CommPort.h"
#include "WdkTypes.h"
#include "FltTypes.h"
#include "Flt-Bridge.h"
...
// ObRegisterCallbacks notifier:
CommPortListener<KB_FLT_OB_CALLBACK_INFO, KbObCallbacks> ObCallbacks;
// Prevent to open our process with PROCESS_VM_READ rights:
Status = ObCallbacks.Subscribe([](CommPort& Port, MessagePacket<KB_FLT_OB_CALLBACK_INFO>& Message) -> VOID {
auto Data = static_cast<PKB_FLT_OB_CALLBACK_INFO>(Message.GetData());
if (Data->Target.ProcessId == GetCurrentProcessId()) {
Data->CreateResultAccess &= ~PROCESS_VM_READ;
Data->DuplicateResultAccess &= ~PROCESS_VM_READ;
}
ReplyPacket<KB_FLT_OB_CALLBACK_INFO> Reply(Message, ERROR_SUCCESS, *Data);
Port.Reply(Reply); // Reply info to driver
});
// Ps***-callbacks:
CommPortListener<KB_FLT_PS_IMAGE_INFO, KbPsImage> ProcessCallbacks;
Status = ProcessCallbacks.Subscribe([](CommPort& Port, MessagePacket<KB_FLT_PS_IMAGE_INFO>& Message) -> VOID {
auto Data = static_cast<PKB_FLT_PS_IMAGE_INFO>(Message.GetData());
printf("[PID: %i | Base: 0x%I64X | Size: %ull]: %ws\r\n", (int)Data->ProcessId, Data->BaseAddress, (int)Data->ImageSize, Data->FullImageName);
});