├── Kernel-Bridge ├── Exports.def ├── API │ ├── CppSupport.h │ ├── Importer.h │ ├── Signatures.h │ ├── Stopwatch.h │ ├── Importer.cpp │ ├── Signatures.cpp │ ├── KernelShells.h │ ├── RAII.h │ ├── OSVersion.h │ ├── CPU.h │ ├── Hypervisor.h │ ├── Stopwatch.cpp │ ├── SectionsUtils.h │ ├── OSVersion.cpp │ ├── PteUtils.h │ ├── KernelShells.cpp │ ├── Callable.h │ ├── IO.h │ ├── PsCallbacks.h │ ├── FilesAPI.h │ ├── ObCallbacks.h │ ├── SectionsUtils.cpp │ ├── CommPort.h │ ├── PsCallbacks.cpp │ ├── CPU.cpp │ ├── FilesAPI.cpp │ ├── ObCallbacks.cpp │ ├── LinkedList.h │ ├── IO.cpp │ ├── CommPort.cpp │ ├── VMM.asm │ ├── CppSupport.cpp │ └── ProcessesUtils.h ├── Kernel-Bridge │ ├── IOCTLs.h │ ├── IOCTLHandlers.h │ ├── LoadableModules.h │ ├── DriverEvents.h │ ├── FilterCallbacks.h │ ├── DriverEvents.cpp │ └── LoadableModules.cpp ├── Kernel-Bridge.rc ├── Kernel-Bridge.inf └── Kernel-Bridge.vcxproj.filters ├── Kernel-Tests ├── pch.cpp ├── pch.h ├── resource.h ├── Kernel-Tests.h └── Kernel-Tests.vcxproj.filters ├── User-Bridge ├── Main.cpp ├── API │ ├── DriversUtils.h │ ├── PEUtils │ │ ├── PELoader.h │ │ ├── PEAnalyzer.h │ │ └── PELoader.cpp │ ├── CommPort.cpp │ ├── CommPort.h │ ├── SymParser.h │ ├── Flt-Bridge.h │ ├── DriversUtils.cpp │ └── Rtl-Bridge.cpp ├── Exports.def └── User-Bridge.vcxproj.filters ├── .gitmodules ├── LoadableModule ├── Exports.def ├── Main.cpp ├── LoadableModule.vcxproj.filters └── LoadableModule.vcxproj ├── Kernel-Toolkit └── Kernel-Toolkit │ ├── Main.cpp │ ├── ObjectsStorage.h │ ├── MainWindow.h │ ├── ObjectsStorage.cpp │ ├── Kernel-Toolkit.pro │ └── MainWindow.cpp ├── x32-debug.ddf ├── x32-release.ddf ├── x64-debug.ddf ├── x64-release.ddf ├── .github └── FUNDING.yml ├── CommonTypes └── Interrupts.h ├── SharedTypes ├── FltTypes.h └── WdkTypes.h ├── MakeBundle.bat ├── README.md ├── Kernel-Bridge.sln └── .gitignore /Kernel-Bridge/Exports.def: -------------------------------------------------------------------------------- 1 | NAME Kernel-Bridge 2 | EXPORTS 3 | DriverEntry -------------------------------------------------------------------------------- /Kernel-Tests/pch.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HoShiMin/Kernel-Bridge/HEAD/Kernel-Tests/pch.cpp -------------------------------------------------------------------------------- /Kernel-Tests/pch.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HoShiMin/Kernel-Bridge/HEAD/Kernel-Tests/pch.h -------------------------------------------------------------------------------- /User-Bridge/Main.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HoShiMin/Kernel-Bridge/HEAD/User-Bridge/Main.cpp -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "HookLib"] 2 | path = HookLib 3 | url = https://github.com/HoShiMin/HookLib.git 4 | -------------------------------------------------------------------------------- /Kernel-Tests/resource.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HoShiMin/Kernel-Bridge/HEAD/Kernel-Tests/resource.h -------------------------------------------------------------------------------- /LoadableModule/Exports.def: -------------------------------------------------------------------------------- 1 | NAME LoadableModule 2 | EXPORTS 3 | OnLoad 4 | OnUnload 5 | OnDeviceControl -------------------------------------------------------------------------------- /Kernel-Bridge/API/CppSupport.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | extern "C" int __crt_init(); 4 | extern "C" void __crt_deinit(); -------------------------------------------------------------------------------- /Kernel-Bridge/API/Importer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace Importer { 4 | // Get address of function from ntoskrnl.exe and FltMgr.dll: 5 | _IRQL_requires_max_(PASSIVE_LEVEL) 6 | PVOID NTAPI GetKernelProcAddress(LPCWSTR SystemRoutineName); 7 | } -------------------------------------------------------------------------------- /Kernel-Bridge/API/Signatures.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // pattern = "\x11\x22\x00\x33\x00\x00\x44" 4 | // mask = "..?.??." 5 | // finds 0x11 0x22 ?? 0x33 ?? ?? 0x44, where ?? is any byte. 6 | 7 | void* find_signature(void* memory, size_t size, const char* pattern, const char* mask); -------------------------------------------------------------------------------- /Kernel-Toolkit/Kernel-Toolkit/Main.cpp: -------------------------------------------------------------------------------- 1 | #include "MainWindow.h" 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | int main(int argc, char *argv[]) 8 | { 9 | QApplication a(argc, argv); 10 | MainWindow w; 11 | w.show(); 12 | return a.exec(); 13 | } 14 | -------------------------------------------------------------------------------- /Kernel-Bridge/Kernel-Bridge/IOCTLs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define IOCTL(Code, Method) (CTL_CODE(0x8000, (Code), Method, FILE_ANY_ACCESS)) 4 | #define EXTRACT_CTL_CODE(Ioctl) ((unsigned short)(((Ioctl) & 0b0011111111111100) >> 2)) 5 | #define EXTRACT_CTL_METHOD(Ioctl) ((unsigned short)((Ioctl) & 0b11)) 6 | 7 | #define CTL_BASE (0x800) -------------------------------------------------------------------------------- /Kernel-Bridge/Kernel-Bridge.rc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #define VER_FILETYPE VFT_DRV 6 | #define VER_FILESUBTYPE VFT2_DRV_SYSTEM 7 | #define VER_FILEDESCRIPTION_STR "Kernel-Bridge Filter Driver" 8 | #define VER_INTERNALNAME_STR "Kernel-Bridge.sys" 9 | 10 | #include "common.ver" 11 | -------------------------------------------------------------------------------- /Kernel-Bridge/API/Stopwatch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class Stopwatch 4 | { 5 | protected: 6 | unsigned long long m_begin, m_end; 7 | unsigned long long m_freq; 8 | 9 | public: 10 | Stopwatch(); 11 | Stopwatch(bool init); 12 | 13 | void reset(); 14 | 15 | void start(); 16 | float stop(); 17 | 18 | float delta(); 19 | }; -------------------------------------------------------------------------------- /Kernel-Bridge/Kernel-Bridge/IOCTLHandlers.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef struct _IOCTL_INFO { 4 | PVOID InputBuffer; 5 | PVOID OutputBuffer; 6 | ULONG InputBufferSize; 7 | ULONG OutputBufferSize; 8 | ULONG ControlCode; 9 | } IOCTL_INFO, *PIOCTL_INFO; 10 | 11 | NTSTATUS FASTCALL DispatchIOCTL(IN PIOCTL_INFO RequestInfo, OUT PSIZE_T ResponseLength); -------------------------------------------------------------------------------- /Kernel-Bridge/API/Importer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "Importer.h" 3 | 4 | namespace Importer { 5 | _IRQL_requires_max_(PASSIVE_LEVEL) 6 | PVOID NTAPI GetKernelProcAddress(LPCWSTR SystemRoutineName) { 7 | UNICODE_STRING Name; 8 | RtlInitUnicodeString(&Name, SystemRoutineName); 9 | return MmGetSystemRoutineAddress(&Name); 10 | } 11 | } -------------------------------------------------------------------------------- /x32-debug.ddf: -------------------------------------------------------------------------------- 1 | .OPTION EXPLICIT 2 | .Set CabinetFileCountThreshold=0 3 | .Set FolderFileCountThreshold=0 4 | .Set FolderSizeThreshold=0 5 | .Set MaxCabinetSize=0 6 | .Set MaxDiskFileCount=0 7 | .Set MaxDiskSize=0 8 | .Set CompressionType=MSZIP 9 | .Set Cabinet=on 10 | .Set Compress=on 11 | .Set CabinetNameTemplate=Kernel-Bridge.cab 12 | .Set DiskDirectoryTemplate=../Debug 13 | .Set DestinationDir=Kernel-Bridge 14 | ../Debug/Kernel-Bridge.sys 15 | ../Debug/Kernel-Bridge.inf -------------------------------------------------------------------------------- /x32-release.ddf: -------------------------------------------------------------------------------- 1 | .OPTION EXPLICIT 2 | .Set CabinetFileCountThreshold=0 3 | .Set FolderFileCountThreshold=0 4 | .Set FolderSizeThreshold=0 5 | .Set MaxCabinetSize=0 6 | .Set MaxDiskFileCount=0 7 | .Set MaxDiskSize=0 8 | .Set CompressionType=MSZIP 9 | .Set Cabinet=on 10 | .Set Compress=on 11 | .Set CabinetNameTemplate=Kernel-Bridge.cab 12 | .Set DiskDirectoryTemplate=../Release 13 | .Set DestinationDir=Kernel-Bridge 14 | ../Release/Kernel-Bridge.sys 15 | ../Release/Kernel-Bridge.inf -------------------------------------------------------------------------------- /x64-debug.ddf: -------------------------------------------------------------------------------- 1 | .OPTION EXPLICIT 2 | .Set CabinetFileCountThreshold=0 3 | .Set FolderFileCountThreshold=0 4 | .Set FolderSizeThreshold=0 5 | .Set MaxCabinetSize=0 6 | .Set MaxDiskFileCount=0 7 | .Set MaxDiskSize=0 8 | .Set CompressionType=MSZIP 9 | .Set Cabinet=on 10 | .Set Compress=on 11 | .Set CabinetNameTemplate=Kernel-Bridge.cab 12 | .Set DiskDirectoryTemplate=../x64/Debug 13 | .Set DestinationDir=Kernel-Bridge 14 | ../x64/Debug/Kernel-Bridge.sys 15 | ../x64/Debug/Kernel-Bridge.inf -------------------------------------------------------------------------------- /x64-release.ddf: -------------------------------------------------------------------------------- 1 | .OPTION EXPLICIT 2 | .Set CabinetFileCountThreshold=0 3 | .Set FolderFileCountThreshold=0 4 | .Set FolderSizeThreshold=0 5 | .Set MaxCabinetSize=0 6 | .Set MaxDiskFileCount=0 7 | .Set MaxDiskSize=0 8 | .Set CompressionType=MSZIP 9 | .Set Cabinet=on 10 | .Set Compress=on 11 | .Set CabinetNameTemplate=Kernel-Bridge.cab 12 | .Set DiskDirectoryTemplate=../x64/Release 13 | .Set DestinationDir=Kernel-Bridge 14 | ../x64/Release/Kernel-Bridge.sys 15 | ../x64/Release/Kernel-Bridge.inf -------------------------------------------------------------------------------- /Kernel-Bridge/API/Signatures.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void* find_signature(void* memory, size_t size, const char* pattern, const char* mask) 4 | { 5 | size_t sig_length = strlen(mask); 6 | if (sig_length > size) return nullptr; 7 | 8 | for (size_t i = 0; i < size - sig_length; i++) 9 | { 10 | bool found = true; 11 | for (size_t j = 0; j < sig_length; j++) 12 | found &= mask[j] == '?' || pattern[j] == *((char*)memory + i + j); 13 | 14 | if (found) 15 | return (char*)memory + i; 16 | } 17 | return nullptr; 18 | } -------------------------------------------------------------------------------- /Kernel-Bridge/API/KernelShells.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace KernelShells { 4 | using _GetKernelProcAddress = PVOID(NTAPI*)(LPCWSTR RoutineName); 5 | using _ShellCode = ULONG(NTAPI*)( 6 | _GetKernelProcAddress GetKernelProcAddress, 7 | OPTIONAL IN OUT PVOID Argument 8 | ); 9 | 10 | // Executes specified user- or kernel-shell into SEH-section and FPU-saved context, 11 | // Returns -1 (0xFFFFFFFF) if exception catched: 12 | _IRQL_requires_max_(APC_LEVEL) 13 | ULONG ExecuteShellCode( 14 | _ShellCode Shell, 15 | OPTIONAL IN OUT PVOID Argument 16 | ); 17 | } -------------------------------------------------------------------------------- /Kernel-Bridge/API/RAII.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template 4 | using ObjectDestructor = void (*)(T); 5 | 6 | template 7 | class Object final { 8 | private: 9 | T _Object; 10 | ObjectDestructor _Destructor; 11 | public: 12 | Object(const Object&) = delete; 13 | Object(Object&&) = delete; 14 | Object& operator = (const Object&) = delete; 15 | Object& operator = (Object&&) = delete; 16 | 17 | Object(T ObjectPtr, ObjectDestructor Destructor) 18 | : _Object(ObjectPtr), _Destructor(Destructor) {} 19 | ~Object() { 20 | if (_Destructor) _Destructor(_Object); 21 | } 22 | T Get() const { return _Object; } 23 | }; -------------------------------------------------------------------------------- /Kernel-Bridge/API/OSVersion.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class OSVersion final { 4 | private: 5 | using _OSVersion = struct { 6 | ULONG Major; 7 | ULONG Minor; 8 | }; 9 | static BOOLEAN Initialized; 10 | static _OSVersion Version; 11 | static VOID Initialize(); 12 | public: 13 | static BOOLEAN IsGreaterThan(ULONG Major, ULONG Minor); 14 | static BOOLEAN IsWindowsXPOrGreater(); 15 | static BOOLEAN IsWindowsXP64OrGreater(); 16 | static BOOLEAN IsWindowsVistaOrGreater(); 17 | static BOOLEAN IsWindows7OrGreater(); 18 | static BOOLEAN IsWindows8OrGreater(); 19 | static BOOLEAN IsWindows81OrGreater(); 20 | static BOOLEAN IsWindows10OrGreater(); 21 | }; -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: ['https://money.yandex.ru/to/41001834174823'] 13 | -------------------------------------------------------------------------------- /Kernel-Bridge/Kernel-Bridge/LoadableModules.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace LoadableModules { 4 | using _OnLoad = NTSTATUS(NTAPI*)(PVOID hModule, LPCWSTR Name); 5 | using _OnUnload = NTSTATUS(NTAPI*)(); 6 | using _OnDeviceControl = NTSTATUS(NTAPI*)(ULONG CtlCode, PVOID Argument); 7 | 8 | NTSTATUS LoadModule( 9 | PVOID hModule, 10 | LPCWSTR ModuleName, 11 | OPTIONAL _OnLoad OnLoad = NULL, 12 | OPTIONAL _OnUnload OnUnload = NULL, 13 | OPTIONAL _OnDeviceControl OnDeviceControl = NULL 14 | ); 15 | 16 | NTSTATUS CallModule(PVOID hModule, ULONG CtlCode, OPTIONAL PVOID Argument = NULL); 17 | 18 | NTSTATUS UnloadModule(PVOID hModule); 19 | 20 | PVOID GetModuleHandle(LPCWSTR ModuleName); 21 | } -------------------------------------------------------------------------------- /Kernel-Toolkit/Kernel-Toolkit/ObjectsStorage.h: -------------------------------------------------------------------------------- 1 | #ifndef OBJECTSSTORAGE_H 2 | #define OBJECTSSTORAGE_H 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | class ObjectsStorage { 13 | private: 14 | std::list ReferencedObjects; 15 | std::list Handles; 16 | std::list AllocatedMemory; 17 | std::list Mappings; 18 | public: 19 | ObjectsStorage(); 20 | ~ObjectsStorage(); 21 | void AddReferencedObject(WdkTypes::PVOID Object); 22 | void AddHandle(WdkTypes::HANDLE Handle); 23 | void AddAllocatedMemory(WdkTypes::PVOID BaseAddress); 24 | void AddMapping(const Mdl::MAPPING_INFO& Mapping); 25 | }; 26 | 27 | #endif // OBJECTSSTORAGE_H 28 | -------------------------------------------------------------------------------- /LoadableModule/Main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | NTSTATUS NTAPI OnLoad(PVOID hModule, LPCWSTR ModuleName) 4 | { 5 | DbgPrint("[LOADABLE]: OnLoad %ws 0x%p\r\n", ModuleName, hModule); 6 | return STATUS_SUCCESS; 7 | } 8 | 9 | NTSTATUS NTAPI OnUnload() 10 | { 11 | DbgPrint("[LOADABLE]: OnUnload\r\n"); 12 | return STATUS_SUCCESS; 13 | } 14 | 15 | NTSTATUS NTAPI OnDeviceControl(ULONG CtlCode, OPTIONAL PVOID Argument) 16 | { 17 | DbgPrint("[LOADABLE]: OnDeviceControl: 0x%X, 0x%p\r\n", CtlCode, Argument); 18 | return STATUS_SUCCESS; 19 | } 20 | 21 | extern "C" NTSTATUS NTAPI DriverEntry( 22 | _In_ PDRIVER_OBJECT DriverObject, 23 | _In_ PUNICODE_STRING RegistryPath 24 | ) { 25 | UNREFERENCED_PARAMETER(DriverObject); 26 | UNREFERENCED_PARAMETER(RegistryPath); 27 | return STATUS_SUCCESS; 28 | } -------------------------------------------------------------------------------- /Kernel-Bridge/API/CPU.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace CPU { 4 | void CLI(); 5 | void STI(); 6 | void HLT(); 7 | 8 | void CPUID(unsigned int FunctionIdEax, int Regs[4]); 9 | void CPUIDEX(unsigned int FunctionIdEax, unsigned int SubfunctionIdEcx, int Regs[4]); 10 | 11 | unsigned long long RDMSR(unsigned long Index); 12 | void WRMSR(unsigned long Index, unsigned long long Value); 13 | 14 | unsigned long long RDPMC(unsigned long Counter); 15 | unsigned long long RDTSC(); 16 | unsigned long long RDTSCP(unsigned int* TscAux); 17 | bool IsRdtscpPresent(); 18 | 19 | void DisableWriteProtection(); 20 | void EnableWriteProtection(); 21 | 22 | bool IsSmepPresent(); 23 | bool IsSmapPresent(); 24 | void DisableSmep(); 25 | void EnableSmep(); 26 | void DisableSmap(); 27 | void EnableSmap(); 28 | } -------------------------------------------------------------------------------- /Kernel-Bridge/API/Hypervisor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // For the Hyper-V only: 4 | extern "C" unsigned long long __fastcall __hyperv_vmcall( 5 | unsigned long long Rcx, 6 | unsigned long long Rdx, 7 | unsigned long long R8, 8 | unsigned long long R9 9 | ); 10 | 11 | extern "C" unsigned long long __fastcall __kb_vmcall( 12 | unsigned long long Rcx, 13 | unsigned long long Rdx, 14 | unsigned long long R8, 15 | unsigned long long R9 16 | ); 17 | 18 | namespace Hypervisor 19 | { 20 | bool IsVirtualized(); 21 | bool Virtualize(); 22 | bool Devirtualize(); 23 | 24 | bool InterceptPage( 25 | unsigned long long Pa, 26 | unsigned long long ReadPa, 27 | unsigned long long WritePa, 28 | unsigned long long ExecutePa, 29 | unsigned long long ExecuteReadPa, 30 | unsigned long long ExecuteWritePa 31 | ); 32 | 33 | bool DeinterceptPage(unsigned long long Pa); 34 | } -------------------------------------------------------------------------------- /Kernel-Bridge/API/Stopwatch.cpp: -------------------------------------------------------------------------------- 1 | #include "Stopwatch.h" 2 | 3 | #include 4 | 5 | Stopwatch::Stopwatch() 6 | : m_begin(0) 7 | , m_end(0) 8 | , m_freq(0) 9 | { 10 | KeQueryPerformanceCounter(reinterpret_cast(&m_freq)); 11 | } 12 | 13 | Stopwatch::Stopwatch(bool init) 14 | : m_begin(0) 15 | , m_end(0) 16 | , m_freq(0) 17 | { 18 | if (init) 19 | { 20 | start(); 21 | } 22 | } 23 | 24 | void Stopwatch::reset() 25 | { 26 | m_begin = 0; 27 | m_end = 0; 28 | KeQueryPerformanceCounter(reinterpret_cast(&m_freq)); 29 | } 30 | 31 | void Stopwatch::start() 32 | { 33 | m_begin = KeQueryPerformanceCounter(reinterpret_cast(&m_freq)).QuadPart; 34 | m_end = m_begin; 35 | } 36 | 37 | float Stopwatch::stop() 38 | { 39 | m_end = KeQueryPerformanceCounter(NULL).QuadPart; 40 | return delta(); 41 | } 42 | 43 | float Stopwatch::delta() 44 | { 45 | return static_cast(m_end - m_begin) / m_freq; 46 | } -------------------------------------------------------------------------------- /Kernel-Bridge/Kernel-Bridge/DriverEvents.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | VOID OnDriverLoad( 4 | PDRIVER_OBJECT DriverObject, 5 | PDEVICE_OBJECT DeviceObject, 6 | PFLT_FILTER FilterHandle, 7 | PUNICODE_STRING RegistryPath 8 | ); 9 | 10 | VOID OnDriverUnload( 11 | PDRIVER_OBJECT DriverObject, 12 | PDEVICE_OBJECT DeviceObject 13 | ); 14 | 15 | VOID OnFilterUnload( 16 | PDEVICE_OBJECT DeviceObject, 17 | PFLT_FILTER FilterHandle, 18 | FLT_FILTER_UNLOAD_FLAGS Flags 19 | ); 20 | 21 | VOID OnDriverCreate( 22 | PDEVICE_OBJECT DeviceObject, 23 | PFLT_FILTER FilterHandle, 24 | PIRP Irp, 25 | PIO_STACK_LOCATION IrpStack 26 | ); 27 | 28 | VOID OnDriverCleanup( 29 | PDEVICE_OBJECT DeviceObject, 30 | PFLT_FILTER FilterHandle, 31 | PIRP Irp, 32 | PIO_STACK_LOCATION IrpStack 33 | ); 34 | 35 | VOID OnDriverClose( 36 | PDEVICE_OBJECT DeviceObject, 37 | PFLT_FILTER FilterHandle, 38 | PIRP Irp, 39 | PIO_STACK_LOCATION IrpStack 40 | ); 41 | 42 | VOID OnSystemSleep(); 43 | VOID OnSystemWake(); -------------------------------------------------------------------------------- /Kernel-Bridge/API/SectionsUtils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace Sections { 4 | NTSTATUS CreateSection( 5 | OUT PHANDLE hSection, 6 | OPTIONAL LPCWSTR Name, 7 | UINT64 MaximumSize, 8 | ACCESS_MASK DesiredAccess, 9 | ULONG SecObjFlags, 10 | ULONG SecPageProtection, 11 | ULONG AllocationAttributes, 12 | OPTIONAL HANDLE hFile 13 | ); 14 | 15 | NTSTATUS OpenSection( 16 | OUT PHANDLE hSection, 17 | LPCWSTR Name, 18 | ACCESS_MASK DesiredAccess, 19 | ULONG SecObjFlags 20 | ); 21 | 22 | NTSTATUS MapViewOfSection( 23 | HANDLE hSection, 24 | HANDLE hProcess, 25 | IN OUT PVOID* BaseAddress, 26 | SIZE_T CommitSize, 27 | IN OUT OPTIONAL UINT64* SectionOffset, 28 | IN OUT SIZE_T* ViewSize, 29 | SECTION_INHERIT InheritDisposition = ViewUnmap, 30 | ULONG AllocationType = MEM_RESERVE, 31 | ULONG Win32Protect = PAGE_READWRITE 32 | ); 33 | 34 | NTSTATUS UnmapViewOfSection(HANDLE hProcess, PVOID BaseAddress); 35 | } -------------------------------------------------------------------------------- /Kernel-Bridge/Kernel-Bridge/FilterCallbacks.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace Communication { 4 | NTSTATUS StartServer(PFLT_FILTER FilterHandle); 5 | VOID StopServer(); 6 | } 7 | 8 | namespace KbCallbacks { 9 | // Handles callbacks: 10 | NTSTATUS StartObHandlesFilter(); 11 | VOID StopObHandlesFilter(); 12 | 13 | // Processes callbacks: 14 | NTSTATUS StartPsProcessFilter(); 15 | VOID StopPsProcessFilter(); 16 | 17 | // Threads callbacks: 18 | NTSTATUS StartPsThreadFilter(); 19 | VOID StopPsThreadFilter(); 20 | 21 | // Images callbacks: 22 | NTSTATUS StartPsImageFilter(); 23 | VOID StopPsImageFilter(); 24 | } 25 | 26 | EXTERN_C_START 27 | 28 | FLT_PREOP_CALLBACK_STATUS 29 | FilterPreOperation( 30 | _Inout_ PFLT_CALLBACK_DATA Data, 31 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 32 | _Flt_CompletionContext_Outptr_ PVOID* CompletionContext 33 | ); 34 | 35 | FLT_POSTOP_CALLBACK_STATUS 36 | FilterPostOperation( 37 | _Inout_ PFLT_CALLBACK_DATA Data, 38 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 39 | _In_opt_ PVOID CompletionContext, 40 | _In_ FLT_POST_OPERATION_FLAGS Flags 41 | ); 42 | 43 | EXTERN_C_END -------------------------------------------------------------------------------- /User-Bridge/API/DriversUtils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define IOCTL(Code, Method) (CTL_CODE(0x8000, (Code), Method, FILE_ANY_ACCESS)) 4 | #define EXTRACT_CTL_CODE(Ioctl) ((unsigned short)(((Ioctl) & 0b0011111111111100) >> 2)) 5 | #define EXTRACT_CTL_METHOD(Ioctl) ((unsigned short)((Ioctl) & 0b11)) 6 | 7 | #define CTL_BASE (0x800) 8 | 9 | BOOL InstallDriver(LPCWSTR FilePath, LPCWSTR DriverName, DWORD DriverType = SERVICE_KERNEL_DRIVER); 10 | BOOL InstallMinifilter(LPCWSTR FilePath, LPCWSTR DriverName, LPCWSTR Altitude); 11 | BOOL DeleteDriver(LPCWSTR DriverName); 12 | 13 | HANDLE OpenDevice(LPCWSTR DeviceName); 14 | 15 | BOOL SendIOCTL( 16 | IN HANDLE hDevice, 17 | IN DWORD Ioctl, 18 | IN PVOID InputBuffer, 19 | IN ULONG InputBufferSize, 20 | IN PVOID OutputBuffer, 21 | IN ULONG OutputBufferSize, 22 | OPTIONAL OUT PDWORD BytesReturned = NULL, 23 | OPTIONAL IN DWORD Method = METHOD_NEITHER 24 | ); 25 | 26 | BOOL SendRawIOCTL( 27 | IN HANDLE hDevice, 28 | IN DWORD Ioctl, 29 | IN PVOID InputBuffer, 30 | IN ULONG InputBufferSize, 31 | IN PVOID OutputBuffer, 32 | IN ULONG OutputBufferSize, 33 | OPTIONAL OUT PDWORD BytesReturned = NULL 34 | ); 35 | -------------------------------------------------------------------------------- /Kernel-Bridge/API/OSVersion.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "OSVersion.h" 3 | 4 | BOOLEAN OSVersion::Initialized = FALSE; 5 | OSVersion::_OSVersion OSVersion::Version = {}; 6 | 7 | _IRQL_requires_max_(PASSIVE_LEVEL) 8 | VOID OSVersion::Initialize() { 9 | if (Initialized) return; 10 | PsGetVersion(&Version.Major, &Version.Minor, NULL, NULL); 11 | Initialized = TRUE; 12 | } 13 | 14 | BOOLEAN OSVersion::IsGreaterThan(ULONG Major, ULONG Minor) { 15 | if (!Initialized) Initialize(); 16 | return (Version.Major > Major) || (Version.Major == Major && Version.Minor >= Minor); 17 | } 18 | 19 | BOOLEAN OSVersion::IsWindowsXPOrGreater() { 20 | return IsGreaterThan(5, 1); 21 | } 22 | 23 | BOOLEAN OSVersion::IsWindowsXP64OrGreater() { 24 | return IsGreaterThan(5, 2); 25 | } 26 | 27 | BOOLEAN OSVersion::IsWindowsVistaOrGreater() { 28 | return IsGreaterThan(6, 0); 29 | } 30 | 31 | BOOLEAN OSVersion::IsWindows7OrGreater() { 32 | return IsGreaterThan(6, 1); 33 | } 34 | 35 | BOOLEAN OSVersion::IsWindows8OrGreater() { 36 | return IsGreaterThan(6, 2); 37 | } 38 | 39 | BOOLEAN OSVersion::IsWindows81OrGreater() { 40 | return IsGreaterThan(6, 3); 41 | } 42 | 43 | BOOLEAN OSVersion::IsWindows10OrGreater() { 44 | return IsGreaterThan(10, 0); 45 | } -------------------------------------------------------------------------------- /Kernel-Toolkit/Kernel-Toolkit/MainWindow.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINWINDOW_H 2 | #define MAINWINDOW_H 3 | 4 | #include 5 | #include "ObjectsStorage.h" 6 | 7 | namespace Ui { 8 | class MainWindow; 9 | } 10 | 11 | class MainWindow : public QMainWindow 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | explicit MainWindow(QWidget *parent = nullptr); 17 | ~MainWindow(); 18 | 19 | private slots: 20 | void on_EnableBeeperButton_clicked(); 21 | 22 | void on_FreqSlider_valueChanged(int value); 23 | 24 | void on_FreqEdit_editingFinished(); 25 | 26 | void on_ReadPortButton_clicked(); 27 | 28 | void on_WritePortButton_clicked(); 29 | 30 | void on_CliButton_clicked(); 31 | 32 | void on_StiButton_clicked(); 33 | 34 | void on_HltButton_clicked(); 35 | 36 | void on_RdmsrButton_clicked(); 37 | 38 | void on_WrmsrButton_clicked(); 39 | 40 | void on_RdpmcButton_clicked(); 41 | 42 | private: 43 | Ui::MainWindow *ui; 44 | ObjectsStorage objectsStorage; 45 | bool isHex(const QString& string); 46 | int getInt(const QString& string); 47 | long long getInt64(const QString& string); 48 | unsigned int getUInt(const QString& string); 49 | unsigned long long getUInt64(const QString& string); 50 | }; 51 | 52 | #endif // MAINWINDOW_H 53 | -------------------------------------------------------------------------------- /Kernel-Toolkit/Kernel-Toolkit/ObjectsStorage.cpp: -------------------------------------------------------------------------------- 1 | #include "ObjectsStorage.h" 2 | 3 | ObjectsStorage::ObjectsStorage() : ReferencedObjects(), Handles(), AllocatedMemory(), Mappings() 4 | { 5 | 6 | } 7 | 8 | ObjectsStorage::~ObjectsStorage() 9 | { 10 | using namespace VirtualMemory; 11 | using namespace Mdl; 12 | using namespace Processes::Descriptors; 13 | for (const auto& Entry : ReferencedObjects) { 14 | if (Entry) KbDereferenceObject(Entry); 15 | } 16 | for (const auto& Entry : Handles) { 17 | if (Entry) KbCloseHandle(Entry); 18 | } 19 | for (const auto& Entry : AllocatedMemory) { 20 | if (Entry) KbFreeKernelMemory(Entry); 21 | } 22 | for (const auto& Entry : Mappings) { 23 | KbUnmapMemory(const_cast(&Entry)); 24 | } 25 | } 26 | 27 | void ObjectsStorage::AddReferencedObject(WdkTypes::PVOID Object) 28 | { 29 | ReferencedObjects.emplace_back(Object); 30 | } 31 | 32 | void ObjectsStorage::AddHandle(WdkTypes::HANDLE Handle) 33 | { 34 | Handles.emplace_back(Handle); 35 | } 36 | 37 | void ObjectsStorage::AddAllocatedMemory(WdkTypes::PVOID BaseAddress) 38 | { 39 | AllocatedMemory.emplace_back(BaseAddress); 40 | } 41 | 42 | void ObjectsStorage::AddMapping(const Mdl::MAPPING_INFO& Mapping) 43 | { 44 | Mappings.emplace_back(Mapping); 45 | } 46 | -------------------------------------------------------------------------------- /Kernel-Bridge/API/PteUtils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace Pte 4 | { 5 | struct PAGE_TABLES_INFO { 6 | PML4E* Pml4e; 7 | PDPE* Pdpe; 8 | PDE* Pde; 9 | PTE* Pte; 10 | enum PAGE_TYPE { 11 | ptUnknown, 12 | pt32NonPaePage4Kb, // PDE -> PTE -> PA 13 | pt32NonPaePage4Mb, // PDE -> PA 14 | pt32PaePage4Kb, // PDPE -> PDE -> PTE -> PA 15 | pt32PaePage2Mb, // PDPE -> PDE -> PA 16 | pt64Page4Kb, // PML4E -> PDPE -> PDE -> PTE -> PA 17 | pt64Page2Mb, // PML4E -> PDPE -> PDE -> PA 18 | pt64Page1Gb // PML4E -> PDPE -> PA 19 | } Type; 20 | }; 21 | 22 | _IRQL_requires_max_(APC_LEVEL) 23 | BOOLEAN GetPageTables(PVOID Address, OUT PAGE_TABLES_INFO* Info); 24 | 25 | _IRQL_requires_max_(APC_LEVEL) 26 | BOOLEAN TriggerCopyOnWrite(OPTIONAL PEPROCESS Process, PVOID Address, OPTIONAL OUT PULONG PageSize = NULL); 27 | 28 | _IRQL_requires_max_(APC_LEVEL) 29 | BOOLEAN IsPagePresent(PVOID Address, OPTIONAL OUT PULONG PageSize); 30 | 31 | _IRQL_requires_max_(APC_LEVEL) 32 | BOOLEAN IsProcessPagePresent(OPTIONAL PEPROCESS Process, PVOID Address, OPTIONAL OUT PULONG PageSize); 33 | 34 | _IRQL_requires_max_(APC_LEVEL) 35 | BOOLEAN IsMemoryRangePresent(OPTIONAL PEPROCESS Process, PVOID Address, SIZE_T Size); 36 | } -------------------------------------------------------------------------------- /LoadableModule/LoadableModule.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {8E41214B-6785-4CFE-B992-037D68949A14} 18 | inf;inv;inx;mof;mc; 19 | 20 | 21 | 22 | 23 | Source Files 24 | 25 | 26 | 27 | 28 | Resource Files 29 | 30 | 31 | -------------------------------------------------------------------------------- /Kernel-Bridge/API/KernelShells.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "KernelShells.h" 4 | 5 | #include "Importer.h" 6 | #include "MemoryUtils.h" 7 | #include "CPU.h" 8 | 9 | namespace KernelShells { 10 | _IRQL_requires_max_(APC_LEVEL) 11 | ULONG ExecuteShellCode( 12 | _ShellCode Shell, 13 | OPTIONAL IN OUT PVOID Argument 14 | ) { 15 | static volatile LONG EnteringsCount = 0; 16 | InterlockedIncrement(&EnteringsCount); 17 | 18 | ULONG Result = 0; 19 | 20 | KFLOATING_SAVE FpuState = {}; 21 | BOOLEAN FpuSaved = KeSaveFloatingPointState(&FpuState) == STATUS_SUCCESS; 22 | 23 | KAFFINITY PreviousAffinity = KeQueryActiveProcessors(); 24 | KeSetSystemAffinityThread(1); // Executing on 1st core of 1st processor 25 | 26 | if (CPU::IsSmepPresent()) CPU::DisableSmep(); 27 | 28 | __try { 29 | Result = Shell(Importer::GetKernelProcAddress, Argument); 30 | } __except (EXCEPTION_EXECUTE_HANDLER) { 31 | Result = static_cast(-1); 32 | } 33 | 34 | InterlockedDecrement(&EnteringsCount); 35 | if (!InterlockedCompareExchange(&EnteringsCount, 0, 0) && CPU::IsSmepPresent()) CPU::EnableSmep(); 36 | 37 | KeSetSystemAffinityThread(PreviousAffinity); 38 | 39 | if (FpuSaved) KeRestoreFloatingPointState(&FpuState); 40 | 41 | return Result; 42 | } 43 | 44 | } -------------------------------------------------------------------------------- /User-Bridge/API/PEUtils/PELoader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | using ImportNameCallback = PVOID(*)(LPCSTR LibName, LPCSTR FunctionName); 4 | using ImportOrdinalCallback = PVOID(*)(LPCSTR LibName, WORD Ordinal); 5 | using EntryPoint = BOOL(WINAPI*)(HMODULE hModule, DWORD dwReason, LPCONTEXT lpContext); 6 | 7 | class PELoader 8 | { 9 | private: 10 | PBYTE m_hModule; 11 | ULONG m_deployedSize; 12 | 13 | SIZE_T m_originalImageBase; 14 | SIZE_T m_previousLoadDelta; 15 | 16 | PIMAGE_DOS_HEADER m_dosHeader; 17 | PIMAGE_NT_HEADERS m_ntHeaders; 18 | PIMAGE_OPTIONAL_HEADER m_optionalHeader; 19 | 20 | void fillImports(ImportNameCallback importNameCallback, ImportOrdinalCallback importOrdinalCallback); 21 | public: 22 | PELoader(HMODULE rawModule, ImportNameCallback importNameCallback, ImportOrdinalCallback importOrdinalCallback); 23 | ~PELoader() { if (m_hModule) VirtualFree(m_hModule, 0, MEM_RELEASE); }; 24 | 25 | void relocate(HMODULE Base); 26 | 27 | HMODULE get() const 28 | { 29 | return reinterpret_cast(m_hModule); 30 | } 31 | 32 | ULONG getDeployedSize() const 33 | { 34 | return m_deployedSize; 35 | } 36 | EntryPoint getEntryPoint() const { 37 | return reinterpret_cast(m_hModule + m_optionalHeader->AddressOfEntryPoint); 38 | } 39 | EntryPoint getBaseRelativeEntryPoint(HMODULE base) const { 40 | return reinterpret_cast(reinterpret_cast(base) + m_optionalHeader->AddressOfEntryPoint); 41 | } 42 | }; -------------------------------------------------------------------------------- /Kernel-Bridge/API/Callable.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace Callable 4 | { 5 | // Calls a callback in a system thread: 6 | bool CallInSystemContext(bool(*Callback)(void* Arg), void* Arg = nullptr, bool Wait = true); 7 | 8 | // Calls a callback on each CPU in a context of current thread: 9 | bool ForEachCpu(bool(*Callback)(void* Arg, unsigned int ProcessorNumber), void* Arg = nullptr); 10 | 11 | // Queues DPC to each CPU: 12 | void DpcOnEachCpu(void(*Callback)(void* Arg), void* Arg = nullptr); 13 | 14 | // Queues DPC to specified CPU and returns immediately: 15 | void QueueDpc(bool(*Callback)(void* Arg), void* Arg = nullptr, unsigned char ProcessorNumber = 0); 16 | 17 | // Queues DPC to specified CPU and waits until it done: 18 | void QueueWaitDpc(bool(*Callback)(void* Arg), void* Arg = nullptr, unsigned char ProcessorNumber = 0); 19 | 20 | // Queues threaded DPC to specified CPU and returns immediately: 21 | void QueueThreadedDpc(bool(*Callback)(void* Arg), void* Arg = nullptr, unsigned char ProcessorNumber = 0); 22 | 23 | // Queues treaded DPC to specified CPU and waits until it done: 24 | void QueueWaitThreadedDpc(bool(*Callback)(void* Arg), void* Arg = nullptr, unsigned char ProcessorNumber = 0); 25 | 26 | // Stops all CPUs except the current and raises IRQL of the current thread: 27 | _IRQL_raises_(DISPATCH_LEVEL) 28 | [[nodiscard]] void* StopMachine(); 29 | 30 | // Resumes all stopped CPUs and restores IRQL of the current thread: 31 | _IRQL_restores_ 32 | void ResumeMachine(void* StopMachineData); 33 | } -------------------------------------------------------------------------------- /User-Bridge/API/CommPort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #pragma comment(lib, "FltLib.lib") 5 | 6 | #include "CommPort.h" 7 | 8 | CommPort::CommPort() : hPort(NULL), Connected(FALSE) {} 9 | 10 | CommPort::~CommPort() { 11 | Disconnect(); 12 | } 13 | 14 | HRESULT CommPort::Connect(LPCWSTR PortName, PVOID Context, WORD SizeOfContext) { 15 | HRESULT Status = FilterConnectCommunicationPort( 16 | PortName, 17 | 0, 18 | Context, 19 | SizeOfContext, 20 | NULL, 21 | &hPort 22 | ); 23 | Connected = Status == S_OK; 24 | return Status; 25 | } 26 | 27 | VOID CommPort::Disconnect() { 28 | if (hPort) CloseHandle(hPort); 29 | } 30 | 31 | HRESULT CommPort::Send( 32 | IN PVOID Input, 33 | DWORD InputSize, 34 | OUT PVOID Output, 35 | DWORD OutputSize, 36 | OUT OPTIONAL PULONG ReturnLength 37 | ) { 38 | DWORD Returned = 0; 39 | HRESULT Status = FilterSendMessage(hPort, Input, InputSize, Output, OutputSize, &Returned); 40 | if (ReturnLength) *ReturnLength = Returned; 41 | return Status; 42 | } 43 | 44 | HRESULT CommPort::Recv(_Out_ CommPortPacket& ReceivedMessage) { 45 | return FilterGetMessage( 46 | hPort, 47 | static_cast(ReceivedMessage.GetHeader()), 48 | ReceivedMessage.GetSize(), 49 | NULL 50 | ); 51 | } 52 | 53 | HRESULT CommPort::Reply(_In_ CommPortPacket& ReplyMessage) { 54 | return FilterReplyMessage(hPort, static_cast(ReplyMessage.GetHeader()), ReplyMessage.GetSize()); 55 | } 56 | -------------------------------------------------------------------------------- /Kernel-Toolkit/Kernel-Toolkit/Kernel-Toolkit.pro: -------------------------------------------------------------------------------- 1 | QT += core gui widgets 2 | 3 | TARGET = Kernel-Toolkit 4 | TEMPLATE = app 5 | 6 | DEFINES += QT_DEPRECATED_WARNINGS 7 | 8 | CONFIG += c++17 static static-runtime 9 | QMAKE_LFLAGS_RELEASE += -static -static-runtime 10 | 11 | INCLUDEPATH += \ 12 | ../../SharedTypes \ 13 | ../../User-Bridge/API/ \ 14 | ../../User-Bridge/API/PEUtils/ 15 | 16 | LIBS += \ 17 | -lAdvapi32 18 | 19 | SOURCES += \ 20 | ObjectsStorage.cpp \ 21 | MainWindow.cpp \ 22 | Main.cpp \ 23 | ../../User-Bridge/API/PEUtils/PEAnalyzer.cpp \ 24 | ../../User-Bridge/API/PEUtils/PELoader.cpp \ 25 | ../../User-Bridge/API/CommPort.cpp \ 26 | ../../User-Bridge/API/DriversUtils.cpp \ 27 | ../../User-Bridge/API/Rtl-Bridge.cpp \ 28 | ../../User-Bridge/API/User-Bridge.cpp 29 | 30 | HEADERS += \ 31 | ObjectsStorage.h \ 32 | MainWindow.h \ 33 | ../../SharedTypes/CtlTypes.h \ 34 | ../../SharedTypes/FltTypes.h \ 35 | ../../SharedTypes/WdkTypes.h \ 36 | ../../User-Bridge/API/PEUtils/PEAnalyzer.h \ 37 | ../../User-Bridge/API/PEUtils/PELoader.h \ 38 | ../../User-Bridge/API/CommPort.h \ 39 | ../../User-Bridge/API/DriversUtils.h \ 40 | ../../User-Bridge/API/Flt-Bridge.h \ 41 | ../../User-Bridge/API/Rtl-Bridge.h \ 42 | ../../User-Bridge/API/User-Bridge.h 43 | 44 | FORMS += \ 45 | MainWindow.ui 46 | 47 | # Default rules for deployment. 48 | qnx: target.path = /tmp/$${TARGET}/bin 49 | else: unix:!android: target.path = /opt/$${TARGET}/bin 50 | !isEmpty(target.path): INSTALLS += target 51 | 52 | DISTFILES += 53 | 54 | RESOURCES += 55 | -------------------------------------------------------------------------------- /Kernel-Bridge/API/IO.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace IO { 4 | namespace IOPL { 5 | void RaiseIopl(); 6 | void ResetIopl(); 7 | } 8 | 9 | namespace Beeper { 10 | void SetBeeperRegime(); // Call this once before using beeper 11 | void StartBeeper(); // Enable beeper with setted frequency 12 | void StopBeeper(); // Disable beeper 13 | void SetBeeperIn(); // Reset voltage from beeper membrane 14 | void SetBeeperOut(); // Set voltage to beeper membrane 15 | void SetBeeperDivider(unsigned short Divider); // 1193182 Hz / Divider 16 | void SetBeeperFrequency(unsigned short Frequency); 17 | } 18 | 19 | namespace RW { 20 | unsigned char ReadPortByte(unsigned short PortNumber); 21 | unsigned short ReadPortWord(unsigned short PortNumber); 22 | unsigned long ReadPortDword(unsigned short PortNumber); 23 | void ReadPortByteString(unsigned short PortNumber, unsigned char* Buffer, unsigned long Count); 24 | void ReadPortWordString(unsigned short PortNumber, unsigned short* Buffer, unsigned long Count); 25 | void ReadPortDwordString(unsigned short PortNumber, unsigned long* Buffer, unsigned long Count); 26 | void WritePortByte(unsigned short PortNumber, unsigned char Data); 27 | void WritePortWord(unsigned short PortNumber, unsigned short Data); 28 | void WritePortDword(unsigned short PortNumber, unsigned long Data); 29 | void WritePortByteString(unsigned short PortNumber, unsigned char* Buffer, unsigned long Count); 30 | void WritePortWordString(unsigned short PortNumber, unsigned short* Buffer, unsigned long Count); 31 | void WritePortDwordString(unsigned short PortNumber, unsigned long* Buffer, unsigned long Count); 32 | } 33 | } -------------------------------------------------------------------------------- /Kernel-Bridge/API/PsCallbacks.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class PsProcessCallback { 4 | private: 5 | PCREATE_PROCESS_NOTIFY_ROUTINE Callback; 6 | public: 7 | PsProcessCallback(const PsProcessCallback&) = delete; 8 | PsProcessCallback(PsProcessCallback&&) = delete; 9 | PsProcessCallback& operator = (const PsProcessCallback&) = delete; 10 | PsProcessCallback& operator = (PsProcessCallback&&) = delete; 11 | 12 | PsProcessCallback(); 13 | PsProcessCallback(PCREATE_PROCESS_NOTIFY_ROUTINE NotifyCallback); 14 | ~PsProcessCallback(); 15 | 16 | NTSTATUS SetupCallback(PCREATE_PROCESS_NOTIFY_ROUTINE NotifyCallback); 17 | VOID RemoveCallback(); 18 | }; 19 | 20 | class PsThreadCallback { 21 | private: 22 | PCREATE_THREAD_NOTIFY_ROUTINE Callback; 23 | public: 24 | PsThreadCallback(const PsThreadCallback&) = delete; 25 | PsThreadCallback(PsThreadCallback&&) = delete; 26 | PsThreadCallback& operator = (const PsThreadCallback&) = delete; 27 | PsThreadCallback& operator = (PsThreadCallback&&) = delete; 28 | 29 | PsThreadCallback(); 30 | PsThreadCallback(PCREATE_THREAD_NOTIFY_ROUTINE NotifyCallback); 31 | ~PsThreadCallback(); 32 | 33 | NTSTATUS SetupCallback(PCREATE_THREAD_NOTIFY_ROUTINE NotifyCallback); 34 | VOID RemoveCallback(); 35 | }; 36 | 37 | class PsImageCallback { 38 | private: 39 | PLOAD_IMAGE_NOTIFY_ROUTINE Callback; 40 | public: 41 | PsImageCallback(const PsImageCallback&) = delete; 42 | PsImageCallback(PsImageCallback&&) = delete; 43 | PsImageCallback& operator = (const PsImageCallback&) = delete; 44 | PsImageCallback& operator = (PsImageCallback&&) = delete; 45 | 46 | PsImageCallback(); 47 | PsImageCallback(PLOAD_IMAGE_NOTIFY_ROUTINE NotifyCallback); 48 | ~PsImageCallback(); 49 | 50 | NTSTATUS SetupCallback(PLOAD_IMAGE_NOTIFY_ROUTINE NotifyCallback); 51 | VOID RemoveCallback(); 52 | }; -------------------------------------------------------------------------------- /Kernel-Bridge/API/FilesAPI.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class File final { 4 | private: 5 | HANDLE _hFile; 6 | public: 7 | File(const File&) = delete; // Copy constructor 8 | File(File&&) = delete; // Move constructor 9 | File& operator = (const File&) = delete; // Copy-assignment operator 10 | File& operator = (File&&) = delete; // Move-assignment operator 11 | 12 | explicit File(HANDLE hFile) : _hFile(hFile) {}; 13 | ~File() { Close(); } 14 | NTSTATUS Close() { 15 | const NTSTATUS Status = _hFile ? ZwClose(_hFile) : STATUS_SUCCESS; 16 | _hFile = NULL; 17 | return Status; 18 | }; 19 | HANDLE Get() const { 20 | return _hFile; 21 | } 22 | }; 23 | 24 | class FilesAPI final { 25 | private: 26 | HANDLE hFile; 27 | NTSTATUS CreationStatus; 28 | public: 29 | enum CREATE_FILE_TYPE { 30 | fCreateEmpty, 31 | fOpenExisting, 32 | fOpenOrCreate 33 | }; 34 | 35 | FilesAPI( 36 | LPCWSTR FilePath, 37 | CREATE_FILE_TYPE Type, 38 | ACCESS_MASK AccessMask, 39 | ULONG ShareAccess 40 | ); 41 | ~FilesAPI() { Close(); } 42 | 43 | NTSTATUS GetCreationStatus() const { return CreationStatus; } 44 | 45 | NTSTATUS Read(OUT PVOID Buffer, ULONG Size, OPTIONAL UINT64 Offset = 0) const; 46 | NTSTATUS Write(IN PVOID Buffer, ULONG Size, OPTIONAL UINT64 Offset = 0) const; 47 | NTSTATUS Close(); 48 | 49 | static NTSTATUS CreateDir(LPCWSTR DirPath); 50 | static NTSTATUS DeleteFile(LPCWSTR FilePath); 51 | static NTSTATUS RenameFile(LPCWSTR OriginalFile, LPCWSTR NewName); 52 | static NTSTATUS MoveFile(LPCWSTR OriginalFile, LPCWSTR Destination); 53 | static NTSTATUS CopyFile(LPCWSTR OriginalFile, LPCWSTR Destination); 54 | static SIZE_T GetFileSize(LPCWSTR FilePath); 55 | static BOOLEAN IsFileExists(LPCWSTR FilePath); 56 | static BOOLEAN IsDirExists(LPCWSTR DirPath); 57 | }; -------------------------------------------------------------------------------- /CommonTypes/Interrupts.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | enum class INTERRUPT_VECTOR 4 | { 5 | DivideError = 0, // #DE, DIV and IDIV instructions 6 | Debug = 1, // #DB, any code or data reference 7 | NmiInterrupt = 2, // Non-maskable interrupt 8 | Breakpoint = 3, // #BP, INT3 instruction 9 | Overflow = 4, // #OF, INT0 instruction 10 | BoundRangeExceeded = 5, // #BR, BOUND instruction 11 | InvalidOpcode = 6, // #UD, UD instruction or reserved opcode 12 | DeviceNotAvailable = 7, // #NM, No math coprocoessor (floating point or WAIT/FWAIT instruction) 13 | DoubleFault = 8, // #DF, Any instruction that can generate an exception, an NMI or an INTR 14 | CoProcessorSegmentOverrun = 9, // #MF, Floating-point instruction 15 | InvalidTss = 10, // #TS, Task switch or TSS access 16 | SegmentNotPresent = 11, // #NP, Loading segment register or accessing system segments 17 | StackSegmentFault = 12, // #SS, Stack operations and SS register loads 18 | GeneralProtection = 13, // #GP, Any memory reference and other protection checks 19 | PageFault = 14, // #PF, Any memory reference 20 | Reserved = 15, 21 | FloatingPointError = 16, // #MF, Floating-point or WAIT/FWAIT instruction 22 | AlignmentCheck = 17, // #AC, Any data reference in memory 23 | MachineCheck = 18, // #MC, Error codes (if any) and source are model-dependent 24 | SimdFloatingPointException = 19, // #XM, SIMD floating-point instruction 25 | VirtualizationException = 20, // #VE, EPT violations 26 | ControlProtectionException = 21, // #CP, The RET, IRET, RSTORSSP, SETSSBSY, and ENDBRANCH (whet CET is enabled) instructions 27 | // 22..31 are reserved 28 | // 32..255 are maskable interrupts (external interrupt from INTR pin or INTn instruction 29 | }; -------------------------------------------------------------------------------- /SharedTypes/FltTypes.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | enum KbFltTypes { 4 | KbObCallbacks, 5 | KbPsProcess, 6 | KbPsThread, 7 | KbPsImage, 8 | KbFltPreCreate, 9 | KbFltPostCreate, 10 | KbFltPreRead, 11 | KbFltPostRead, 12 | KbFltPreWrite, 13 | KbFltPostWrite, 14 | KbFltPreDeviceControl, 15 | KbFltPostDeviceControl, 16 | KbFltPreInternalDeviceControl, 17 | KbFltPostInternalDeviceControl, 18 | KbFltPreFileSystemControl, 19 | KbFltPostFileSystemControl, 20 | KbFltNone 21 | }; 22 | 23 | DECLARE_STRUCT(KB_FLT_CONTEXT, { 24 | KbFltTypes Type; 25 | WdkTypes::CLIENT_ID Client; 26 | }); 27 | 28 | DECLARE_STRUCT(KB_FLT_OB_CALLBACK_INFO, { 29 | WdkTypes::CLIENT_ID Client; 30 | WdkTypes::CLIENT_ID Target; 31 | ACCESS_MASK CreateDesiredAccess; 32 | ACCESS_MASK DuplicateDesiredAccess; 33 | ACCESS_MASK CreateResultAccess; 34 | ACCESS_MASK DuplicateResultAccess; 35 | }); 36 | 37 | DECLARE_STRUCT(KB_FLT_PS_PROCESS_INFO, { 38 | UINT64 ParentId; 39 | UINT64 ProcessId; 40 | BOOLEAN Created; 41 | }); 42 | 43 | DECLARE_STRUCT(KB_FLT_PS_THREAD_INFO, { 44 | UINT64 ProcessId; 45 | UINT64 ThreadId; 46 | BOOLEAN Created; 47 | }); 48 | 49 | DECLARE_STRUCT(KB_FLT_PS_IMAGE_INFO, { 50 | UINT64 ProcessId; 51 | WdkTypes::PVOID BaseAddress; 52 | UINT64 ImageSize; 53 | WCHAR FullImageName[384]; // Fixed size! Enough for paths. 54 | }); 55 | 56 | DECLARE_STRUCT(KB_FLT_CREATE_INFO, { 57 | UINT64 ProcessId; 58 | UINT64 ThreadId; 59 | ACCESS_MASK AccessMask; 60 | WdkTypes::NTSTATUS Status; 61 | WCHAR Path[384]; // Fixed size! Enough for paths. 62 | }); 63 | 64 | DECLARE_STRUCT(KB_FLT_READ_WRITE_INFO, { 65 | UINT64 ProcessId; 66 | UINT64 ThreadId; 67 | WdkTypes::PMDL LockedMdl; 68 | ULONG Size; 69 | WdkTypes::NTSTATUS Status; 70 | WCHAR Path[384]; 71 | }); 72 | 73 | DECLARE_STRUCT(KB_FLT_DEVICE_CONTROL_INFO, { 74 | UINT64 ProcessId; 75 | UINT64 ThreadId; 76 | WdkTypes::PMDL InputLockedMdl; 77 | WdkTypes::PMDL OutputLockedMdl; 78 | ULONG InputSize; 79 | ULONG OutputSize; 80 | ULONG Ioctl; 81 | WdkTypes::NTSTATUS Status; 82 | WCHAR Path[384]; 83 | }); -------------------------------------------------------------------------------- /Kernel-Bridge/API/ObCallbacks.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class ObCallbacks final { 4 | private: 5 | using _ObRegisterCallbacks = NTSTATUS(NTAPI*)( 6 | POB_CALLBACK_REGISTRATION CallbackRegistration, 7 | PVOID* RegistrationHandle 8 | ); 9 | using _ObUnRegisterCallbacks = NTSTATUS(NTAPI*)( 10 | PVOID RegistrationHandle 11 | ); 12 | 13 | PVOID RegistrationHandle; 14 | _ObRegisterCallbacks DynObRegisterCallbacks; 15 | _ObUnRegisterCallbacks DynObUnRegisterCallbacks; 16 | 17 | public: 18 | ObCallbacks(const ObCallbacks&) = delete; 19 | ObCallbacks(ObCallbacks&&) = delete; 20 | ObCallbacks& operator = (const ObCallbacks&) = delete; 21 | ObCallbacks& operator = (ObCallbacks&&) = delete; 22 | 23 | enum ObCallbackType { 24 | ctAll, 25 | ctProcesses, 26 | ctThreads, 27 | ctMaxValue // Same as ctAll 28 | }; 29 | 30 | ObCallbacks(); 31 | ObCallbacks( 32 | OPTIONAL OB_PREOP_CALLBACK_STATUS(NTAPI *PreCallback)( 33 | PVOID RegistrationContext, 34 | POB_PRE_OPERATION_INFORMATION OperationInformation 35 | ), 36 | OPTIONAL VOID (NTAPI *PostCallback)( 37 | PVOID RegistrationContext, 38 | POB_POST_OPERATION_INFORMATION OperationInformation 39 | ) = NULL, 40 | OPTIONAL PVOID RegistrationContext = NULL, 41 | ObCallbackType ObjectType = ObCallbackType::ctAll, 42 | OB_OPERATION OperationType = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE 43 | ); 44 | ~ObCallbacks(); 45 | 46 | NTSTATUS SetupCallbacks( 47 | OPTIONAL OB_PREOP_CALLBACK_STATUS(NTAPI *PreCallback)( 48 | PVOID RegistrationContext, 49 | POB_PRE_OPERATION_INFORMATION OperationInformation 50 | ), 51 | OPTIONAL VOID (NTAPI *PostCallback)( 52 | PVOID RegistrationContext, 53 | POB_POST_OPERATION_INFORMATION OperationInformation 54 | ) = NULL, 55 | OPTIONAL PVOID RegistrationContext = NULL, 56 | ObCallbackType ObjectType = ObCallbackType::ctAll, 57 | OB_OPERATION OperationType = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE 58 | ); 59 | VOID RemoveCallbacks(); 60 | }; -------------------------------------------------------------------------------- /Kernel-Tests/Kernel-Tests.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class KernelTests { 4 | private: 5 | std::wstring TestName; 6 | protected: 7 | bool Passed; 8 | public: 9 | virtual bool RunTest() { 10 | std::wcout << L"Null test" << std::endl; 11 | return true; 12 | } 13 | 14 | KernelTests(LPCWSTR Name) : TestName(Name), Passed(false) { 15 | } 16 | 17 | ~KernelTests() = default; 18 | 19 | void Log(LPCWSTR Text) { 20 | std::wcout << L"\t[ " << TestName << L" ]: " << Text << std::endl; 21 | } 22 | 23 | void PrintStatus() { 24 | if (!Passed) std::wcout << std::endl; 25 | std::wcout << L"[ " << (Passed ? L"PASSED" : L"FAILED") << L" ] " << TestName << std::endl; 26 | } 27 | }; 28 | 29 | class BeeperTest : public KernelTests { 30 | public: 31 | BeeperTest(LPCWSTR Name) : KernelTests(Name) { Passed = RunTest(); PrintStatus(); } 32 | bool RunTest() override; 33 | }; 34 | 35 | class IoplTest : KernelTests { 36 | public: 37 | IoplTest(LPCWSTR Name) : KernelTests(Name) { Passed = RunTest(); PrintStatus(); } 38 | bool RunTest() override; 39 | }; 40 | 41 | class VirtualMemoryTest : KernelTests { 42 | public: 43 | VirtualMemoryTest(LPCWSTR Name) : KernelTests(Name) { Passed = RunTest(); PrintStatus(); } 44 | bool RunTest() override; 45 | }; 46 | 47 | class MdlTest : KernelTests { 48 | public: 49 | MdlTest(LPCWSTR Name) : KernelTests(Name) { Passed = RunTest(); PrintStatus(); } 50 | bool RunTest() override; 51 | }; 52 | 53 | class PhysicalMemoryTest : KernelTests { 54 | public: 55 | PhysicalMemoryTest(LPCWSTR Name) : KernelTests(Name) { Passed = RunTest(); PrintStatus(); } 56 | bool RunTest() override; 57 | }; 58 | 59 | class ProcessesTest : KernelTests { 60 | public: 61 | ProcessesTest(LPCWSTR Name) : KernelTests(Name) { Passed = RunTest(); PrintStatus(); } 62 | bool RunTest() override; 63 | }; 64 | 65 | class ShellTest : KernelTests { 66 | public: 67 | ShellTest(LPCWSTR Name) : KernelTests(Name) { Passed = RunTest(); PrintStatus(); } 68 | bool RunTest() override; 69 | }; 70 | 71 | class StuffTest : KernelTests { 72 | public: 73 | StuffTest(LPCWSTR Name) : KernelTests(Name) { Passed = RunTest(); PrintStatus(); } 74 | bool RunTest() override; 75 | }; -------------------------------------------------------------------------------- /MakeBundle.bat: -------------------------------------------------------------------------------- 1 | if not exist ".\Bundle" mkdir ".\Bundle" 2 | if not exist ".\Bundle\i386" mkdir ".\Bundle\i386" 3 | if not exist ".\Bundle\i386\Debug" mkdir ".\Bundle\i386\Debug" 4 | if not exist ".\Bundle\i386\Release" mkdir ".\Bundle\i386\Release" 5 | if not exist ".\Bundle\x64" mkdir ".\Bundle\x64" 6 | if not exist ".\Bundle\x64\Debug" mkdir ".\Bundle\x64\Debug" 7 | if not exist ".\Bundle\x64\Release" mkdir ".\Bundle\x64\Release" 8 | 9 | copy /Y /B ".\Debug\User-Bridge.pdb" ".\Bundle\i386\Debug\User-Bridge.pdb" 10 | copy /Y /B ".\Debug\User-Bridge.lib" ".\Bundle\i386\Debug\User-Bridge.lib" 11 | copy /Y /B ".\Debug\User-Bridge.dll" ".\Bundle\i386\Debug\User-Bridge.dll" 12 | copy /Y /B ".\Debug\Kernel-Bridge.sys" ".\Bundle\i386\Debug\Kernel-Bridge.sys" 13 | copy /Y /B ".\Debug\Kernel-Bridge.pdb" ".\Bundle\i386\Debug\Kernel-Bridge.pdb" 14 | copy /Y /B ".\Debug\Kernel-Bridge.inf" ".\Bundle\i386\Debug\Kernel-Bridge.inf" 15 | 16 | copy /Y /B ".\Release\User-Bridge.pdb" ".\Bundle\i386\Release\User-Bridge.pdb" 17 | copy /Y /B ".\Release\User-Bridge.lib" ".\Bundle\i386\Release\User-Bridge.lib" 18 | copy /Y /B ".\Release\User-Bridge.dll" ".\Bundle\i386\Release\User-Bridge.dll" 19 | copy /Y /B ".\Release\Kernel-Bridge.sys" ".\Bundle\i386\Release\Kernel-Bridge.sys" 20 | copy /Y /B ".\Release\Kernel-Bridge.pdb" ".\Bundle\i386\Release\Kernel-Bridge.pdb" 21 | copy /Y /B ".\Release\Kernel-Bridge.inf" ".\Bundle\i386\Release\Kernel-Bridge.inf" 22 | 23 | copy /Y /B ".\x64\Debug\User-Bridge.pdb" ".\Bundle\x64\Debug\User-Bridge.pdb" 24 | copy /Y /B ".\x64\Debug\User-Bridge.lib" ".\Bundle\x64\Debug\User-Bridge.lib" 25 | copy /Y /B ".\x64\Debug\User-Bridge.dll" ".\Bundle\x64\Debug\User-Bridge.dll" 26 | copy /Y /B ".\x64\Debug\Kernel-Bridge.sys" ".\Bundle\x64\Debug\Kernel-Bridge.sys" 27 | copy /Y /B ".\x64\Debug\Kernel-Bridge.pdb" ".\Bundle\x64\Debug\Kernel-Bridge.pdb" 28 | copy /Y /B ".\x64\Debug\Kernel-Bridge.inf" ".\Bundle\x64\Debug\Kernel-Bridge.inf" 29 | 30 | copy /Y /B ".\x64\Release\User-Bridge.pdb" ".\Bundle\x64\Release\User-Bridge.pdb" 31 | copy /Y /B ".\x64\Release\User-Bridge.lib" ".\Bundle\x64\Release\User-Bridge.lib" 32 | copy /Y /B ".\x64\Release\User-Bridge.dll" ".\Bundle\x64\Release\User-Bridge.dll" 33 | copy /Y /B ".\x64\Release\Kernel-Bridge.sys" ".\Bundle\x64\Release\Kernel-Bridge.sys" 34 | copy /Y /B ".\x64\Release\Kernel-Bridge.pdb" ".\Bundle\x64\Release\Kernel-Bridge.pdb" 35 | copy /Y /B ".\x64\Release\Kernel-Bridge.inf" ".\Bundle\x64\Release\Kernel-Bridge.inf" -------------------------------------------------------------------------------- /Kernel-Bridge/API/SectionsUtils.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace Sections { 4 | NTSTATUS CreateSection( 5 | OUT PHANDLE hSection, 6 | OPTIONAL LPCWSTR Name, 7 | UINT64 MaximumSize, 8 | ACCESS_MASK DesiredAccess, 9 | ULONG SecObjFlags, 10 | ULONG SecPageProtection, 11 | ULONG AllocationAttributes, 12 | OPTIONAL HANDLE hFile 13 | ) { 14 | UNICODE_STRING SecName = {}; 15 | if (Name) RtlInitUnicodeString(&SecName, Name); 16 | 17 | OBJECT_ATTRIBUTES Attributes = {}; 18 | 19 | InitializeObjectAttributes(&Attributes, Name ? &SecName : NULL, SecObjFlags, NULL, NULL); 20 | 21 | return ZwCreateSection( 22 | hSection, 23 | DesiredAccess, 24 | &Attributes, 25 | reinterpret_cast(&MaximumSize), 26 | SecPageProtection, 27 | AllocationAttributes, 28 | hFile 29 | ); 30 | } 31 | 32 | NTSTATUS OpenSection( 33 | OUT PHANDLE hSection, 34 | LPCWSTR Name, 35 | ACCESS_MASK DesiredAccess, 36 | ULONG SecObjFlags 37 | ) { 38 | if (!Name) return STATUS_INVALID_PARAMETER; 39 | 40 | UNICODE_STRING SecName = {}; 41 | RtlInitUnicodeString(&SecName, Name); 42 | 43 | OBJECT_ATTRIBUTES Attributes = {}; 44 | InitializeObjectAttributes(&Attributes, &SecName, SecObjFlags, NULL, NULL); 45 | 46 | return ZwOpenSection(hSection, DesiredAccess, &Attributes); 47 | } 48 | 49 | NTSTATUS MapViewOfSection( 50 | HANDLE hSection, 51 | HANDLE hProcess, 52 | IN OUT PVOID* BaseAddress, 53 | SIZE_T CommitSize, 54 | IN OUT OPTIONAL UINT64* SectionOffset, 55 | IN OUT SIZE_T* ViewSize, 56 | SECTION_INHERIT InheritDisposition, 57 | ULONG AllocationType, 58 | ULONG Win32Protect 59 | ) { 60 | return ZwMapViewOfSection( 61 | hSection, 62 | hProcess, 63 | BaseAddress, 64 | NULL, 65 | CommitSize, 66 | reinterpret_cast(SectionOffset), 67 | ViewSize, 68 | InheritDisposition, 69 | AllocationType, 70 | Win32Protect 71 | ); 72 | } 73 | 74 | NTSTATUS UnmapViewOfSection(HANDLE hProcess, PVOID BaseAddress) { 75 | return ZwUnmapViewOfSection(hProcess, BaseAddress); 76 | } 77 | } -------------------------------------------------------------------------------- /Kernel-Tests/Kernel-Tests.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Header Files 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | 32 | 33 | Source Files 34 | 35 | 36 | Source Files 37 | 38 | 39 | Source Files 40 | 41 | 42 | Source Files 43 | 44 | 45 | Source Files 46 | 47 | 48 | Source Files 49 | 50 | 51 | Source Files 52 | 53 | 54 | Source Files 55 | 56 | 57 | Source Files 58 | 59 | 60 | Source Files 61 | 62 | 63 | -------------------------------------------------------------------------------- /Kernel-Bridge/API/CommPort.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class CommPort { 4 | public: 5 | using CLIENT_INFO = struct { 6 | CommPort* ServerInstance; 7 | PFLT_PORT ClientPort; 8 | PVOID ConnectionContext; 9 | ULONG SizeOfContext; 10 | }; 11 | 12 | class ClientsList : public EResource, public LinkedList { 13 | public: 14 | ClientsList() : EResource(), LinkedList() {} 15 | ~ClientsList() = default; 16 | }; 17 | 18 | using CLIENT_REQUEST = struct { 19 | IN PVOID InputBuffer; 20 | ULONG InputSize; 21 | OUT PVOID OutputBuffer; 22 | ULONG OutputSize; 23 | }; 24 | 25 | using _OnMessage = NTSTATUS(NTAPI*)(CLIENT_INFO& Client, CLIENT_REQUEST& Request, OUT PULONG ReturnLength); 26 | 27 | private: 28 | PFLT_FILTER ParentFilter; 29 | 30 | using SERVER_COOKIE = struct { 31 | CommPort* ServerInstance; 32 | PVOID UserCookie; 33 | }; 34 | SERVER_COOKIE ServerCookie; 35 | 36 | PFLT_PORT ServerPort; 37 | 38 | ClientsList Clients; 39 | 40 | _OnMessage OnMessageCallback; 41 | 42 | static NTSTATUS OnConnectInternal( 43 | IN PFLT_PORT ClientPort, 44 | IN PVOID ServerPortCookie, 45 | IN PVOID ConnectionContext, 46 | IN ULONG SizeOfContext, 47 | OUT PVOID *ConnectionPortCookie 48 | ); 49 | 50 | static VOID OnDisconnectInternal( 51 | IN PVOID ConnectionCookie 52 | ); 53 | 54 | static NTSTATUS OnMessageInternal( 55 | IN PVOID PortCookie, 56 | IN PVOID InputBuffer OPTIONAL, 57 | IN ULONG InputBufferLength, 58 | OUT PVOID OutputBuffer OPTIONAL, 59 | IN ULONG OutputBufferLength, 60 | OUT PULONG ReturnOutputBufferLength 61 | ); 62 | 63 | public: 64 | CommPort(); 65 | ~CommPort(); 66 | 67 | CommPort(const CommPort&) = delete; 68 | CommPort(CommPort&&) = delete; 69 | CommPort& operator = (const CommPort&) = delete; 70 | CommPort& operator = (CommPort&&) = delete; 71 | 72 | NTSTATUS StartServer( 73 | PFLT_FILTER Filter, 74 | LPCWSTR PortName, 75 | _OnMessage OnMessage, 76 | LONG MaxConnections = 128, 77 | OPTIONAL PVOID Cookie = NULL 78 | ); 79 | 80 | VOID StopServer(); 81 | 82 | ClientsList& GetClients() { return Clients; } 83 | 84 | NTSTATUS Send( 85 | PFLT_PORT Client, 86 | IN PVOID Buffer, 87 | ULONG Size, 88 | OUT PVOID Response = NULL, 89 | ULONG ResponseSize = 0, 90 | ULONG Timeout = 0 91 | ); 92 | }; -------------------------------------------------------------------------------- /Kernel-Bridge/API/PsCallbacks.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "PsCallbacks.h" 4 | 5 | PsProcessCallback::PsProcessCallback() : Callback(NULL) {} 6 | 7 | PsProcessCallback::PsProcessCallback(PCREATE_PROCESS_NOTIFY_ROUTINE NotifyCallback) : PsProcessCallback() { 8 | SetupCallback(NotifyCallback); 9 | } 10 | 11 | PsProcessCallback::~PsProcessCallback() { 12 | RemoveCallback(); 13 | } 14 | 15 | NTSTATUS PsProcessCallback::SetupCallback(PCREATE_PROCESS_NOTIFY_ROUTINE NotifyCallback) { 16 | if (!NotifyCallback) return STATUS_INVALID_PARAMETER; 17 | if (Callback) RemoveCallback(); 18 | 19 | NTSTATUS Status = PsSetCreateProcessNotifyRoutine(NotifyCallback, FALSE); 20 | if (NT_SUCCESS(Status)) Callback = NotifyCallback; 21 | return Status; 22 | } 23 | 24 | VOID PsProcessCallback::RemoveCallback() { 25 | if (!Callback) return; 26 | PsSetCreateProcessNotifyRoutine(Callback, TRUE); 27 | Callback = NULL; 28 | } 29 | 30 | 31 | 32 | PsThreadCallback::PsThreadCallback() : Callback(NULL) {} 33 | 34 | PsThreadCallback::PsThreadCallback(PCREATE_THREAD_NOTIFY_ROUTINE NotifyCallback) : PsThreadCallback() { 35 | SetupCallback(NotifyCallback); 36 | } 37 | 38 | PsThreadCallback::~PsThreadCallback() { 39 | RemoveCallback(); 40 | } 41 | 42 | NTSTATUS PsThreadCallback::SetupCallback(PCREATE_THREAD_NOTIFY_ROUTINE NotifyCallback) { 43 | if (!NotifyCallback) return STATUS_INVALID_PARAMETER; 44 | if (Callback) RemoveCallback(); 45 | 46 | NTSTATUS Status = PsSetCreateThreadNotifyRoutine(NotifyCallback); 47 | if (NT_SUCCESS(Status)) Callback = NotifyCallback; 48 | return Status; 49 | } 50 | 51 | VOID PsThreadCallback::RemoveCallback() { 52 | if (!Callback) return; 53 | PsRemoveCreateThreadNotifyRoutine(Callback); 54 | Callback = NULL; 55 | } 56 | 57 | 58 | 59 | PsImageCallback::PsImageCallback() : Callback(NULL) {} 60 | 61 | PsImageCallback::PsImageCallback(PLOAD_IMAGE_NOTIFY_ROUTINE NotifyCallback) : PsImageCallback() { 62 | SetupCallback(NotifyCallback); 63 | } 64 | 65 | PsImageCallback::~PsImageCallback() { 66 | RemoveCallback(); 67 | } 68 | 69 | NTSTATUS PsImageCallback::SetupCallback(PLOAD_IMAGE_NOTIFY_ROUTINE NotifyCallback) { 70 | if (!NotifyCallback) return STATUS_INVALID_PARAMETER; 71 | if (Callback) RemoveCallback(); 72 | 73 | NTSTATUS Status = PsSetLoadImageNotifyRoutine(NotifyCallback); 74 | if (NT_SUCCESS(Status)) Callback = NotifyCallback; 75 | return Status; 76 | } 77 | 78 | VOID PsImageCallback::RemoveCallback() { 79 | if (!Callback) return; 80 | PsRemoveLoadImageNotifyRoutine(Callback); 81 | Callback = NULL; 82 | } -------------------------------------------------------------------------------- /User-Bridge/API/CommPort.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class CommPortPacket { 4 | public: 5 | CommPortPacket() = default; 6 | ~CommPortPacket() = default; 7 | virtual PVOID GetHeader() = 0; 8 | virtual PVOID GetData() = 0; 9 | virtual ULONG GetSize() const = 0; 10 | }; 11 | 12 | template 13 | class MessagePacket : public CommPortPacket { 14 | private: 15 | struct { 16 | FILTER_MESSAGE_HEADER Header; 17 | T Data; 18 | } Packet; 19 | public: 20 | MessagePacket() : Packet({}) {} 21 | ~MessagePacket() {} 22 | 23 | PVOID GetHeader() override { return static_cast(&Packet.Header); } 24 | PVOID GetData() override { return static_cast(&Packet.Data); } 25 | ULONG GetSize() const override { return sizeof(Packet); } 26 | 27 | ULONG GetReplyLength() const { return Packet.Header.ReplyLength; } 28 | ULONGLONG GetMessageId() const { return Packet.Header.MessageId; } 29 | }; 30 | 31 | template 32 | class ReplyPacket : public CommPortPacket { 33 | private: 34 | struct { 35 | FILTER_REPLY_HEADER Header; 36 | T Data; 37 | } Packet; 38 | public: 39 | ReplyPacket() : CommPortPacket(), Packet({}) {} 40 | ReplyPacket(CommPortPacket& Message, ULONG Status) : ReplyPacket() { 41 | SetMessageId(static_cast(Message.GetHeader())->MessageId); 42 | SetReplyStatus(Status); 43 | } 44 | ReplyPacket(CommPortPacket& Message, ULONG Status, const T& Data) : ReplyPacket(Message, Status) { 45 | SetData(Data); 46 | } 47 | ~ReplyPacket() {} 48 | 49 | PVOID GetData() override { return static_cast(&Packet.Data); } 50 | PVOID GetHeader() override { return static_cast(&Packet.Header); } 51 | ULONG GetSize() const override { return sizeof(Packet); } 52 | 53 | VOID SetData(const T& Data) { Packet.Data = Data; } 54 | VOID SetReplyStatus(NTSTATUS Status) { Packet.Header.Status = Status; } 55 | VOID SetMessageId(ULONGLONG MessageId) { Packet.Header.MessageId = MessageId; } 56 | }; 57 | 58 | class CommPort { 59 | private: 60 | HANDLE hPort; 61 | BOOL Connected; 62 | public: 63 | CommPort(); 64 | ~CommPort(); 65 | 66 | HRESULT Connect(LPCWSTR PortName, PVOID Context, WORD SizeOfContext); 67 | VOID Disconnect(); 68 | 69 | HRESULT Send( 70 | IN PVOID Input, 71 | DWORD InputSize, 72 | OUT PVOID Output, 73 | DWORD OutputSize, 74 | OUT OPTIONAL PULONG ReturnLength = NULL 75 | ); 76 | HRESULT Recv(_Out_ CommPortPacket& ReceivedMessage); 77 | HRESULT Reply(_In_ CommPortPacket& ReplyMessage); 78 | }; -------------------------------------------------------------------------------- /User-Bridge/API/SymParser.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class SymParser { 4 | private: 5 | // From cvconst.h: 6 | enum BasicType { 7 | btNoType = 0, 8 | btVoid = 1, 9 | btChar = 2, 10 | btWChar = 3, 11 | btInt = 6, 12 | btUInt = 7, 13 | btFloat = 8, 14 | btBCD = 9, 15 | btBool = 10, 16 | btLong = 13, 17 | btULong = 14, 18 | btCurrency = 25, 19 | btDate = 26, 20 | btVariant = 27, 21 | btComplex = 28, 22 | btBit = 29, 23 | btBSTR = 30, 24 | btHresult = 31 25 | }; 26 | 27 | BOOL Initialized; 28 | HANDLE hProcess; 29 | DWORD64 ModuleBase; 30 | LPCWSTR DefaultSymbolsPath = L"srv*C:\\Symbols*https://msdl.microsoft.com/download/symbols"; 31 | 32 | std::wstring GetSymName(ULONG Index, OPTIONAL OUT PBOOL Status = NULL); 33 | std::wstring GetSymTypeName(ULONG Index, OPTIONAL OUT PUINT64 BaseTypeSize = NULL, OPTIONAL OUT PBOOL Status = NULL); 34 | UINT64 GetSymSize(ULONG Index, OPTIONAL OUT PBOOL Status = NULL); 35 | ULONG GetSymOffset(ULONG Index, OPTIONAL OUT PBOOL Status = NULL); 36 | ULONG GetSymAddressOffset(ULONG Index, OPTIONAL OUT PBOOL Status = NULL); 37 | ULONG GetSymBitPosition(ULONG Index, OPTIONAL OUT PBOOL Status = NULL); 38 | ULONG GetSymTypeId(ULONG Index, OPTIONAL OUT PBOOL Status = NULL); 39 | ULONG GetSymArrayTypeId(ULONG Index, OPTIONAL OUT PBOOL Status = NULL); 40 | enum SymTagEnum GetSymTag(ULONG Index, OPTIONAL OUT PBOOL Status = NULL); 41 | enum BasicType GetSymType(ULONG Index, OPTIONAL OUT PBOOL Status = NULL); 42 | enum BasicType GetSymBaseType(ULONG Index, OPTIONAL OUT PBOOL Status = NULL); 43 | public: 44 | using SYM_CHILD_ENTRY = struct { 45 | std::wstring Name; 46 | std::wstring TypeName; 47 | UINT64 ElementsCount; 48 | UINT64 Size; 49 | ULONG Offset; 50 | BOOL IsBitField; 51 | ULONG BitPosition; 52 | }; 53 | using SYM_INFO = struct { 54 | std::wstring Name; 55 | UINT64 Size; 56 | ULONG Offset; 57 | std::vector Entries; 58 | }; 59 | 60 | SymParser(OPTIONAL LPCWSTR SymbolsPath = NULL); 61 | ~SymParser(); 62 | 63 | BOOL IsInitialized() const { return Initialized; } 64 | 65 | // Load symbols for specified module (*.exe/*.dll/*.sys etc.): 66 | BOOL LoadModule(LPCWSTR ModulePath, OPTIONAL DWORD64 ImageBase = NULL, OPTIONAL DWORD ImageSize = 0); 67 | 68 | BOOL DumpSymbol(LPCWSTR SymbolName, OUT SYM_INFO& SymInfo); 69 | }; -------------------------------------------------------------------------------- /User-Bridge/Exports.def: -------------------------------------------------------------------------------- 1 | LIBRARY User-Bridge 2 | EXPORTS 3 | KbLoadAsDriver 4 | KbLoadAsFilter 5 | KbUnload 6 | KbGetDriverApiVersion 7 | KbGetUserApiVersion 8 | KbGetHandlesCount 9 | 10 | KbSetBeeperRegime 11 | KbStartBeeper 12 | KbStopBeeper 13 | KbSetBeeperIn 14 | KbSetBeeperOut 15 | KbSetBeeperDivider 16 | KbSetBeeperFrequency 17 | 18 | KbReadPortByte 19 | KbReadPortWord 20 | KbReadPortDword 21 | KbReadPortByteString 22 | KbReadPortWordString 23 | KbReadPortDwordString 24 | KbWritePortByte 25 | KbWritePortWord 26 | KbWritePortDword 27 | KbWritePortByteString 28 | KbWritePortWordString 29 | KbWritePortDwordString 30 | 31 | KbRaiseIopl 32 | KbResetIopl 33 | 34 | KbCli 35 | KbSti 36 | KbHlt 37 | 38 | KbReadMsr 39 | KbWriteMsr 40 | 41 | KbCpuid 42 | KbCpuidEx 43 | 44 | KbReadPmc 45 | KbReadTsc 46 | KbReadTscp 47 | 48 | KbAllocKernelMemory 49 | KbFreeKernelMemory 50 | KbAllocNonCachedMemory 51 | KbFreeNonCachedMemory 52 | KbCopyMoveMemory 53 | KbFillMemory 54 | KbEqualMemory 55 | 56 | KbAllocateMdl 57 | KbProbeAndLockPages 58 | KbMapMdl 59 | KbProtectMappedMemory 60 | KbUnmapMdl 61 | KbUnlockPages 62 | KbFreeMdl 63 | KbMapMemory 64 | KbUnmapMemory 65 | 66 | KbAllocPhysicalMemory 67 | KbFreePhysicalMemory 68 | KbMapPhysicalMemory 69 | KbUnmapPhysicalMemory 70 | KbGetPhysicalAddress 71 | KbGetVirtualForPhysical 72 | KbReadPhysicalMemory 73 | KbWritePhysicalMemory 74 | KbReadDmiMemory 75 | 76 | KbGetEprocess 77 | KbGetEthread 78 | KbOpenProcess 79 | KbOpenProcessByPointer 80 | KbOpenThread 81 | KbOpenThreadByPointer 82 | KbDereferenceObject 83 | KbCloseHandle 84 | KbQueryInformationProcess 85 | KbSetInformationProcess 86 | KbQueryInformationThread 87 | KbSetInformationThread 88 | KbCreateUserThread 89 | KbCreateSystemThread 90 | KbSuspendProcess 91 | KbResumeProcess 92 | KbGetThreadContext 93 | KbSetThreadContext 94 | KbAllocUserMemory 95 | KbFreeUserMemory 96 | KbSecureVirtualMemory 97 | KbUnsecureVirtualMemory 98 | KbReadProcessMemory 99 | KbWriteProcessMemory 100 | KbGetProcessCr3Cr4 101 | KbQueueUserApc 102 | 103 | KbCreateSection 104 | KbOpenSection 105 | KbMapViewOfSection 106 | KbUnmapViewOfSection 107 | 108 | KbExecuteShellCode 109 | 110 | KbCreateDriver 111 | KbLoadModule 112 | KbUnloadModule 113 | KbGetModuleHandle 114 | KbCallModule 115 | 116 | KbRtlMapDriverMemory 117 | KbRtlMapDriverFile 118 | KbRtlLoadModuleMemory 119 | KbRtlLoadModuleFile 120 | 121 | KbVmmEnable 122 | KbVmmDisable 123 | KbVmmInterceptPage 124 | KbVmmDeinterceptPage 125 | 126 | KbGetKernelProcAddress 127 | KbStallExecutionProcessor 128 | KbBugCheck 129 | KbFindSignature -------------------------------------------------------------------------------- /User-Bridge/API/Flt-Bridge.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* 4 | Depends on: 5 | - Windows.h 6 | - fltUser.h 7 | - functional 8 | - WdkTypes.h 9 | - FltTypes.h 10 | - CommPort.h 11 | */ 12 | 13 | template 14 | class CommPortListener { 15 | public: 16 | using _Callback = std::function& Message)>; 17 | private: 18 | CommPort Port; 19 | HANDLE hThread; 20 | _Callback Callback; 21 | 22 | HRESULT ConnectStatus; 23 | HANDLE hSubscriptionEvent; 24 | 25 | static bool CallCallbackSafe(CommPortListener* Self, MessagePacket& Message) { 26 | if (Self->Callback) { 27 | __try { 28 | Self->Callback(Self->Port, Message); 29 | } __except (EXCEPTION_EXECUTE_HANDLER) { 30 | return false; 31 | } 32 | } 33 | return true; 34 | } 35 | 36 | static VOID WINAPI ListenerThread(CommPortListener* Self) { 37 | KB_FLT_CONTEXT Context = {}; 38 | Context.Type = PacketType; 39 | Context.Client.ProcessId = GetCurrentProcessId(); 40 | Context.Client.ThreadId = GetCurrentThreadId(); 41 | 42 | static LPCWSTR PortName = L"\\Kernel-Bridge"; 43 | Self->ConnectStatus = Self->Port.Connect(PortName, &Context, sizeof(Context)); 44 | SetEvent(Self->hSubscriptionEvent); 45 | if (!SUCCEEDED(Self->ConnectStatus)) ExitThread(0); 46 | 47 | HRESULT Status; 48 | do { 49 | MessagePacket Message; 50 | Status = Self->Port.Recv(*reinterpret_cast(&Message)); 51 | if (SUCCEEDED(Status)) { 52 | CallCallbackSafe(Self, Message); 53 | } 54 | } while (SUCCEEDED(Status)); 55 | ExitThread(0); 56 | } 57 | public: 58 | CommPortListener() : Port(), hThread(NULL), Callback(NULL), ConnectStatus(ERROR_SUCCESS) { 59 | hSubscriptionEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 60 | } 61 | ~CommPortListener() { 62 | Unsubscribe(); 63 | CloseHandle(hSubscriptionEvent); 64 | } 65 | 66 | BOOL Subscribe(_Callback Listener) { 67 | if (hThread != NULL || !Listener) return FALSE; 68 | Callback = Listener; 69 | hThread = CreateThread(NULL, 0, reinterpret_cast(ListenerThread), this, 0, NULL); 70 | if (!hThread) return FALSE; 71 | WaitForSingleObject(hSubscriptionEvent, INFINITE); 72 | if (!SUCCEEDED(ConnectStatus)) { 73 | CloseHandle(hThread); 74 | hThread = NULL; 75 | return FALSE; 76 | } 77 | ResetEvent(hSubscriptionEvent); 78 | 79 | return SUCCEEDED(ConnectStatus); 80 | } 81 | 82 | VOID Unsubscribe() { 83 | if (!hThread) return; 84 | Port.Disconnect(); 85 | WaitForSingleObject(hThread, INFINITE); 86 | CloseHandle(hThread); 87 | hThread = NULL; 88 | } 89 | }; -------------------------------------------------------------------------------- /Kernel-Bridge/API/CPU.cpp: -------------------------------------------------------------------------------- 1 | extern "C" void _enable(); 2 | extern "C" void _disable(); 3 | extern "C" void __halt(); 4 | extern "C" unsigned long long __readmsr(unsigned long Index); 5 | extern "C" void __writemsr(unsigned long Index, unsigned long long Value); 6 | extern "C" void __cpuid(int Info[4], int FunctionIdEax); 7 | extern "C" void __cpuidex(int Info[4], int FunctionIdEx, int SubfunctionIdEcx); 8 | extern "C" unsigned long long __readpmc(unsigned long Counter); 9 | extern "C" unsigned long long __rdtsc(); 10 | extern "C" unsigned long long __rdtscp(unsigned int* TscAux); 11 | #ifdef _AMD64_ 12 | extern "C" unsigned long long __readcr0(); 13 | extern "C" void __writecr0(unsigned long long Value); 14 | extern "C" unsigned long long __readcr4(); 15 | extern "C" void __writecr4(unsigned long long Value); 16 | #elif _X86_ 17 | extern "C" unsigned long __readcr0(); 18 | extern "C" void __writecr0(unsigned long Value); 19 | extern "C" unsigned long __readcr4(); 20 | extern "C" void __writecr4(unsigned long Value); 21 | #endif 22 | 23 | namespace CPU { 24 | void CLI() { 25 | _disable(); 26 | } 27 | 28 | void STI() { 29 | _enable(); 30 | } 31 | 32 | void HLT() { 33 | __halt(); 34 | } 35 | 36 | void CPUID(unsigned int FunctionIdEax, int Regs[4]) { 37 | __cpuid(Regs, FunctionIdEax); 38 | } 39 | 40 | void CPUIDEX(unsigned int FunctionIdEax, unsigned int SubfunctionIdEcx, int Regs[4]) { 41 | __cpuidex(Regs, FunctionIdEax, SubfunctionIdEcx); 42 | } 43 | 44 | unsigned long long RDMSR(unsigned long Index) { 45 | return __readmsr(Index); 46 | } 47 | 48 | void WRMSR(unsigned long Index, unsigned long long Value) { 49 | __writemsr(Index, Value); 50 | } 51 | 52 | unsigned long long RDPMC(unsigned long Counter) { 53 | return __readpmc(Counter); 54 | } 55 | 56 | unsigned long long RDTSC() { 57 | return __rdtsc(); 58 | } 59 | 60 | unsigned long long RDTSCP(unsigned int* TscAux) { 61 | return __rdtscp(TscAux); 62 | } 63 | 64 | bool IsRdtscpPresent() { 65 | int regs[4]; 66 | __cpuid(regs, 0x80000001); 67 | return (regs[3] & (1 << 27)) != 0; 68 | } 69 | 70 | void DisableWriteProtection() { 71 | __writecr0(__readcr0() & ~(1 << 16)); 72 | } 73 | 74 | void EnableWriteProtection() { 75 | __writecr0(__readcr0() | (1 << 16)); 76 | } 77 | 78 | bool IsSmepPresent() { 79 | int regs[4]; 80 | __cpuidex(regs, 7, 0); 81 | return (regs[1] & (1 << 7)) != 0; 82 | } 83 | 84 | bool IsSmapPresent() { 85 | int regs[4]; 86 | __cpuidex(regs, 7, 0); 87 | return (regs[1] & (1 << 20)) != 0; 88 | } 89 | 90 | void DisableSmep() { 91 | __writecr4(__readcr4() & ~(1 << 20)); 92 | } 93 | 94 | void EnableSmep() { 95 | __writecr4(__readcr4() | (1 << 20)); 96 | } 97 | 98 | void DisableSmap() { 99 | __writecr4(__readcr4() & ~(1 << 21)); 100 | } 101 | 102 | void EnableSmap() { 103 | __writecr4(__readcr4() | (1 << 21)); 104 | } 105 | } -------------------------------------------------------------------------------- /User-Bridge/User-Bridge.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {edd61105-dcb8-4c04-b050-5d8d1b91ae6b} 6 | 7 | 8 | {62eb9047-d1c0-4981-a9b7-b578b342fcda} 9 | 10 | 11 | {9e1ef5e3-399c-452c-8091-9142deb2d845} 12 | 13 | 14 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 15 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 16 | 17 | 18 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 19 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 20 | 21 | 22 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 23 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 24 | 25 | 26 | {3d4daa8d-6ad7-4f20-99ef-5bf36c120bb7} 27 | 28 | 29 | 30 | 31 | API 32 | 33 | 34 | API 35 | 36 | 37 | SharedTypes 38 | 39 | 40 | API\PEUtils 41 | 42 | 43 | API\PEUtils 44 | 45 | 46 | API 47 | 48 | 49 | API 50 | 51 | 52 | SharedTypes 53 | 54 | 55 | SharedTypes 56 | 57 | 58 | API 59 | 60 | 61 | 62 | 63 | API 64 | 65 | 66 | API 67 | 68 | 69 | Main\Source Files 70 | 71 | 72 | API\PEUtils 73 | 74 | 75 | API\PEUtils 76 | 77 | 78 | API 79 | 80 | 81 | API 82 | 83 | 84 | 85 | 86 | Main 87 | 88 | 89 | -------------------------------------------------------------------------------- /Kernel-Bridge/API/FilesAPI.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "FilesAPI.h" 3 | 4 | FilesAPI::FilesAPI( 5 | LPCWSTR FilePath, 6 | CREATE_FILE_TYPE Type, 7 | ACCESS_MASK AccessMask, 8 | ULONG ShareAccess 9 | ) : hFile(NULL) { 10 | 11 | UNICODE_STRING Path; 12 | RtlInitUnicodeString(&Path, FilePath); 13 | 14 | OBJECT_ATTRIBUTES ObjectAttributes; 15 | InitializeObjectAttributes( 16 | &ObjectAttributes, 17 | &Path, 18 | OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, 19 | NULL, 20 | NULL 21 | ); 22 | 23 | IO_STATUS_BLOCK IoStatusBlock = {}; 24 | LARGE_INTEGER AllocationSize = {}; 25 | 26 | ULONG CreateDisposition = FILE_OVERWRITE; 27 | switch (Type) { 28 | case fCreateEmpty: 29 | CreateDisposition = FILE_OVERWRITE_IF; 30 | break; 31 | case fOpenExisting: 32 | CreateDisposition = FILE_OPEN; 33 | break; 34 | case fOpenOrCreate: 35 | CreateDisposition = FILE_OPEN_IF; 36 | break; 37 | } 38 | 39 | CreationStatus = ZwCreateFile( 40 | &hFile, 41 | AccessMask, 42 | &ObjectAttributes, 43 | &IoStatusBlock, 44 | &AllocationSize, 45 | FILE_ATTRIBUTE_NORMAL, 46 | ShareAccess, 47 | CreateDisposition, 48 | FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, 49 | NULL, 50 | 0 51 | ); 52 | } 53 | 54 | NTSTATUS FilesAPI::Read(OUT PVOID Buffer, ULONG Size, OPTIONAL UINT64 Offset) const { 55 | IO_STATUS_BLOCK IoStatusBlock = {}; 56 | return ZwReadFile(hFile, NULL, NULL, NULL, &IoStatusBlock, Buffer, Size, reinterpret_cast(&Offset), NULL); 57 | } 58 | 59 | NTSTATUS FilesAPI::Write(IN PVOID Buffer, ULONG Size, OPTIONAL UINT64 Offset) const { 60 | IO_STATUS_BLOCK IoStatusBlock = {}; 61 | return ZwWriteFile(hFile, NULL, NULL, NULL, &IoStatusBlock, Buffer, Size, reinterpret_cast(&Offset), NULL); 62 | } 63 | 64 | NTSTATUS FilesAPI::Close() { 65 | NTSTATUS Status = hFile ? ZwClose(hFile) : STATUS_SUCCESS; 66 | hFile = NULL; 67 | return Status; 68 | } 69 | 70 | 71 | NTSTATUS FilesAPI::CreateDir(LPCWSTR DirPath) { 72 | UNICODE_STRING Path; 73 | RtlInitUnicodeString(&Path, DirPath); 74 | 75 | OBJECT_ATTRIBUTES ObjectAttributes; 76 | InitializeObjectAttributes( 77 | &ObjectAttributes, 78 | &Path, 79 | OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, 80 | NULL, 81 | NULL 82 | ); 83 | 84 | IO_STATUS_BLOCK IoStatusBlock = {}; 85 | LARGE_INTEGER AllocationSize = {}; 86 | 87 | HANDLE hDir = NULL; 88 | NTSTATUS Status = ZwCreateFile( 89 | &hDir, 90 | SYNCHRONIZE, 91 | &ObjectAttributes, 92 | &IoStatusBlock, 93 | &AllocationSize, 94 | FILE_ATTRIBUTE_NORMAL, 95 | 0, // Non-shared access 96 | FILE_CREATE, 97 | FILE_DIRECTORY_FILE, 98 | NULL, 99 | 0 100 | ); 101 | if (NT_SUCCESS(Status) && hDir) ZwClose(hDir); 102 | return Status; 103 | } 104 | 105 | NTSTATUS FilesAPI::DeleteFile(LPCWSTR FilePath) { 106 | UNICODE_STRING Path; 107 | RtlInitUnicodeString(&Path, FilePath); 108 | 109 | OBJECT_ATTRIBUTES ObjectAttributes; 110 | InitializeObjectAttributes( 111 | &ObjectAttributes, 112 | &Path, 113 | OBJ_CASE_INSENSITIVE, 114 | NULL, 115 | NULL 116 | ); 117 | 118 | return ZwDeleteFile(&ObjectAttributes); 119 | } -------------------------------------------------------------------------------- /Kernel-Bridge/API/ObCallbacks.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "ObCallbacks.h" 4 | #include "Importer.h" 5 | 6 | ObCallbacks::ObCallbacks() : RegistrationHandle(NULL) { 7 | // For the WinXP support we should import them dynamically: 8 | DynObRegisterCallbacks = static_cast<_ObRegisterCallbacks>( 9 | Importer::GetKernelProcAddress(L"ObRegisterCallbacks") 10 | ); 11 | DynObUnRegisterCallbacks = static_cast<_ObUnRegisterCallbacks>( 12 | Importer::GetKernelProcAddress(L"ObUnRegisterCallbacks") 13 | ); 14 | } 15 | 16 | ObCallbacks::ObCallbacks( 17 | OPTIONAL OB_PREOP_CALLBACK_STATUS(NTAPI *PreCallback)( 18 | PVOID RegistrationContext, 19 | POB_PRE_OPERATION_INFORMATION OperationInformation 20 | ), 21 | OPTIONAL VOID (NTAPI *PostCallback)( 22 | PVOID RegistrationContext, 23 | POB_POST_OPERATION_INFORMATION OperationInformation 24 | ), 25 | OPTIONAL PVOID RegistrationContext, 26 | ObCallbackType CallbackType, 27 | OB_OPERATION OperationType 28 | ) : ObCallbacks() { 29 | SetupCallbacks(PreCallback, PostCallback, RegistrationContext, CallbackType, OperationType); 30 | } 31 | 32 | ObCallbacks::~ObCallbacks() { 33 | RemoveCallbacks(); 34 | } 35 | 36 | NTSTATUS ObCallbacks::SetupCallbacks( 37 | OPTIONAL OB_PREOP_CALLBACK_STATUS(NTAPI *PreCallback)( 38 | PVOID RegistrationContext, 39 | POB_PRE_OPERATION_INFORMATION OperationInformation 40 | ), 41 | OPTIONAL VOID (NTAPI *PostCallback)( 42 | PVOID RegistrationContext, 43 | POB_POST_OPERATION_INFORMATION OperationInformation 44 | ), 45 | OPTIONAL PVOID RegistrationContext, 46 | ObCallbackType CallbackType, 47 | OB_OPERATION OperationType 48 | ) { 49 | if (RegistrationHandle) RemoveCallbacks(); 50 | 51 | if (!DynObRegisterCallbacks || !DynObUnRegisterCallbacks) 52 | return STATUS_NOT_SUPPORTED; 53 | 54 | if ((CallbackType == (ctProcesses | ctThreads)) || (CallbackType == ctMaxValue)) 55 | CallbackType = ctAll; 56 | 57 | if (!PreCallback && !PostCallback) 58 | return STATUS_INVALID_PARAMETER; 59 | 60 | OB_OPERATION_REGISTRATION Operations[ctMaxValue - 1] = {}; 61 | 62 | Operations[ctProcesses - 1].ObjectType = PsProcessType; 63 | Operations[ctProcesses - 1].Operations = OperationType; 64 | Operations[ctProcesses - 1].PreOperation = PreCallback; 65 | Operations[ctProcesses - 1].PostOperation = PostCallback; 66 | 67 | Operations[ctThreads - 1].ObjectType = PsThreadType; 68 | Operations[ctThreads - 1].Operations = OperationType; 69 | Operations[ctThreads - 1].PreOperation = PreCallback; 70 | Operations[ctThreads - 1].PostOperation = PostCallback; 71 | 72 | OB_CALLBACK_REGISTRATION Registration = {}; 73 | Registration.Version = OB_FLT_REGISTRATION_VERSION; 74 | Registration.OperationRegistrationCount = CallbackType == ctAll 75 | ? sizeof(Operations) / sizeof(*Operations) 76 | : 1; 77 | RtlInitUnicodeString(&Registration.Altitude, L"389020"); 78 | Registration.RegistrationContext = RegistrationContext; 79 | Registration.OperationRegistration = CallbackType == ctAll 80 | ? reinterpret_cast(&Operations) 81 | : reinterpret_cast(&Operations[CallbackType - 1]); 82 | 83 | return DynObRegisterCallbacks(&Registration, &RegistrationHandle); 84 | } 85 | 86 | VOID ObCallbacks::RemoveCallbacks() { 87 | if (RegistrationHandle) 88 | DynObUnRegisterCallbacks(RegistrationHandle); 89 | RegistrationHandle = NULL; 90 | } -------------------------------------------------------------------------------- /Kernel-Bridge/Kernel-Bridge/DriverEvents.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "FilterCallbacks.h" 4 | #include "../API/Hypervisor.h" 5 | 6 | volatile LONG KbHandlesCount = 0; 7 | 8 | VOID OnDriverLoad( 9 | PDRIVER_OBJECT DriverObject, 10 | PDEVICE_OBJECT DeviceObject, 11 | PFLT_FILTER FilterHandle, 12 | PUNICODE_STRING RegistryPath 13 | ) { 14 | NTSTATUS Status = STATUS_UNSUCCESSFUL; 15 | UNREFERENCED_PARAMETER(DriverObject); 16 | UNREFERENCED_PARAMETER(DeviceObject); 17 | UNREFERENCED_PARAMETER(RegistryPath); 18 | 19 | if (FilterHandle) { 20 | Communication::StartServer(FilterHandle); 21 | Status = KbCallbacks::StartObHandlesFilter(); 22 | KdPrint(("[Kernel-Bridge]: ObHandlesFilter status: 0x%X\r\n", Status)); 23 | Status = KbCallbacks::StartPsProcessFilter(); 24 | KdPrint(("[Kernel-Bridge]: PsProcessFilter status: 0x%X\r\n", Status)); 25 | Status = KbCallbacks::StartPsThreadFilter(); 26 | KdPrint(("[Kernel-Bridge]: PsThreadFilter status: 0x%X\r\n", Status)); 27 | Status = KbCallbacks::StartPsImageFilter(); 28 | KdPrint(("[Kernel-Bridge]: PsImageFilter status: 0x%X\r\n", Status)); 29 | } 30 | } 31 | 32 | VOID OnDriverUnload( 33 | PDRIVER_OBJECT DriverObject, 34 | PDEVICE_OBJECT DeviceObject 35 | ) { 36 | UNREFERENCED_PARAMETER(DriverObject); 37 | UNREFERENCED_PARAMETER(DeviceObject); 38 | Hypervisor::Devirtualize(); // Devirtualize processor if it is in virtualized state 39 | } 40 | 41 | VOID OnFilterUnload( 42 | PDEVICE_OBJECT DeviceObject, 43 | PFLT_FILTER FilterHandle, 44 | FLT_FILTER_UNLOAD_FLAGS Flags 45 | ) { 46 | UNREFERENCED_PARAMETER(DeviceObject); 47 | UNREFERENCED_PARAMETER(FilterHandle); 48 | UNREFERENCED_PARAMETER(Flags); 49 | 50 | KbCallbacks::StopObHandlesFilter(); 51 | KbCallbacks::StopPsProcessFilter(); 52 | KbCallbacks::StopPsThreadFilter(); 53 | KbCallbacks::StopPsImageFilter(); 54 | 55 | Communication::StopServer(); 56 | } 57 | 58 | VOID OnDriverCreate( 59 | PDEVICE_OBJECT DeviceObject, 60 | PFLT_FILTER FilterHandle, 61 | PIRP Irp, 62 | PIO_STACK_LOCATION IrpStack 63 | ) { 64 | UNREFERENCED_PARAMETER(DeviceObject); 65 | UNREFERENCED_PARAMETER(FilterHandle); 66 | UNREFERENCED_PARAMETER(Irp); 67 | UNREFERENCED_PARAMETER(IrpStack); 68 | InterlockedIncrement(&KbHandlesCount); 69 | } 70 | 71 | VOID OnDriverCleanup( 72 | PDEVICE_OBJECT DeviceObject, 73 | PFLT_FILTER FilterHandle, 74 | PIRP Irp, 75 | PIO_STACK_LOCATION IrpStack 76 | ) { 77 | UNREFERENCED_PARAMETER(DeviceObject); 78 | UNREFERENCED_PARAMETER(FilterHandle); 79 | UNREFERENCED_PARAMETER(Irp); 80 | UNREFERENCED_PARAMETER(IrpStack); 81 | } 82 | 83 | VOID OnDriverClose( 84 | PDEVICE_OBJECT DeviceObject, 85 | PFLT_FILTER FilterHandle, 86 | PIRP Irp, 87 | PIO_STACK_LOCATION IrpStack 88 | ) { 89 | UNREFERENCED_PARAMETER(DeviceObject); 90 | UNREFERENCED_PARAMETER(FilterHandle); 91 | UNREFERENCED_PARAMETER(Irp); 92 | UNREFERENCED_PARAMETER(IrpStack); 93 | InterlockedDecrement(&KbHandlesCount); 94 | } 95 | 96 | namespace HypervisorManagement { 97 | static bool NeedToRevirtualizeOnWake = false; 98 | } 99 | 100 | VOID OnSystemSleep() 101 | { 102 | using namespace HypervisorManagement; 103 | if (Hypervisor::IsVirtualized()) { 104 | NeedToRevirtualizeOnWake = true; 105 | Hypervisor::Devirtualize(); 106 | } 107 | else { 108 | NeedToRevirtualizeOnWake = false; 109 | } 110 | } 111 | 112 | VOID OnSystemWake() 113 | { 114 | using namespace HypervisorManagement; 115 | if (NeedToRevirtualizeOnWake) 116 | Hypervisor::Virtualize(); 117 | } 118 | -------------------------------------------------------------------------------- /Kernel-Bridge/Kernel-Bridge.inf: -------------------------------------------------------------------------------- 1 | [Version] 2 | Signature = "$Windows NT$" 3 | Class = "ActivityMonitor" ; This is determined by the work this filter driver does 4 | ClassGuid = {b86dff51-a31e-4bac-b3cf-e8cfe75c9fc2} ; This value is determined by the Load Order Group value 5 | Provider = %ManufacturerName% 6 | DriverVer = 08/12/2018,1.0.0.1 7 | CatalogFile = Kernel-Bridge.cat 8 | PnpLockdown = 1 9 | 10 | [DestinationDirs] 11 | DefaultDestDir = 12 12 | MiniFilter.NTX86.DriverFiles = 12 ; %windir%\system32\drivers 13 | MiniFilter.NTAMD64.DriverFiles = 12 ; %windir%\system32\drivers 14 | 15 | [DefaultInstall.NTX86] 16 | OptionDesc = %ServiceDescription% 17 | CopyFiles = MiniFilter.NTX86.CopyDriverFiles 18 | 19 | [DefaultInstall.NTAMD64] 20 | OptionDesc = %ServiceDescription% 21 | CopyFiles = MiniFilter.NTAMD64.CopyDriverFiles 22 | 23 | [DefaultInstall.NTX86.Services] 24 | AddService = %ServiceName%,,MiniFilter.NTX86.Service 25 | 26 | [DefaultInstall.NTAMD64.Services] 27 | AddService = %ServiceName%,,MiniFilter.NTAMD64.Service 28 | 29 | [DefaultUninstall.NTX86] 30 | DelFiles = MiniFilter.NTX86.DelDriverFiles 31 | LegacyUninstall = 1 32 | 33 | [DefaultUninstall.NTAMD64] 34 | DelFiles = MiniFilter.NTAMD64.DelDriverFiles 35 | LegacyUninstall = 1 36 | 37 | [DefaultUninstall.NTX86.Services] 38 | DelService = %ServiceName%,0x200 ; Ensure service is stopped before deleting 39 | 40 | [DefaultUninstall.NTAMD64.Services] 41 | DelService = %ServiceName%,0x200 ; Ensure service is stopped before deleting 42 | 43 | [MiniFilter.NTX86.Service] 44 | DisplayName = %ServiceName% 45 | Description = %ServiceDescription% 46 | ServiceBinary = %12%\%DriverName%.sys ;%windir%\system32\drivers\ 47 | Dependencies = "FltMgr" 48 | ServiceType = 2 ; SERVICE_FILE_SYSTEM_DRIVER 49 | StartType = 3 ; SERVICE_DEMAND_START 50 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 51 | LoadOrderGroup = "FSFilter Activity Monitor" 52 | AddReg = MiniFilter.NTX86.AddRegistry 53 | 54 | [MiniFilter.NTAMD64.Service] 55 | DisplayName = %ServiceName% 56 | Description = %ServiceDescription% 57 | ServiceBinary = %12%\%DriverName%.sys ;%windir%\system32\drivers\ 58 | Dependencies = "FltMgr" 59 | ServiceType = 2 ; SERVICE_FILE_SYSTEM_DRIVER 60 | StartType = 3 ; SERVICE_DEMAND_START 61 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 62 | LoadOrderGroup = "FSFilter Activity Monitor" 63 | AddReg = MiniFilter.NTAMD64.AddRegistry 64 | 65 | [MiniFilter.NTX86.AddRegistry] 66 | HKR,,"DebugFlags",0x00010001,0x0 67 | HKR,,"SupportedFeatures",0x00010001,0x3 68 | HKR,"Instances","DefaultInstance",0x00000000,%DefaultInstance% 69 | HKR,"Instances\"%Instance1.Name%,"Altitude",0x00000000,%Instance1.Altitude% 70 | HKR,"Instances\"%Instance1.Name%,"Flags",0x00010001,%Instance1.Flags% 71 | 72 | [MiniFilter.NTAMD64.AddRegistry] 73 | HKR,,"DebugFlags",0x00010001,0x0 74 | HKR,,"SupportedFeatures",0x00010001,0x3 75 | HKR,"Instances","DefaultInstance",0x00000000,%DefaultInstance% 76 | HKR,"Instances\"%Instance1.Name%,"Altitude",0x00000000,%Instance1.Altitude% 77 | HKR,"Instances\"%Instance1.Name%,"Flags",0x00010001,%Instance1.Flags% 78 | 79 | [MiniFilter.NTX86.CopyDriverFiles] 80 | %DriverName%.sys 81 | 82 | [MiniFilter.NTAMD64.CopyDriverFiles] 83 | %DriverName%.sys 84 | 85 | [MiniFilter.NTX86.DelDriverFiles] 86 | %DriverName%.sys 87 | 88 | [MiniFilter.NTAMD64.DelDriverFiles] 89 | %DriverName%.sys 90 | 91 | [SourceDisksFiles] 92 | Kernel-Bridge.sys = 1,, 93 | 94 | [SourceDisksNames] 95 | 1 = %DiskId1%,,, 96 | 97 | [Strings] 98 | ManufacturerName = "Kernel-Bridge Inc." 99 | ServiceDescription = "Kernel-Bridge Driver" 100 | ServiceName = "Kernel-Bridge" 101 | DriverName = "Kernel-Bridge" 102 | DiskId1 = "Kernel-Bridge Device Installation Disk" 103 | 104 | DefaultInstance = "Kernel-Bridge Instance" 105 | Instance1.Name = "Kernel-Bridge Instance" 106 | ; Altitude values: https://msdn.microsoft.com/en-us/windows/hardware/drivers/ifs/load-order-groups-and-altitudes-for-minifilter-drivers 107 | Instance1.Altitude = "260000" 108 | Instance1.Flags = 0x0 ; Allow all attachments 109 | -------------------------------------------------------------------------------- /User-Bridge/API/PEUtils/PEAnalyzer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | /* 8 | RAW or Offset - offset from the beginning of file 9 | RVA - offset in the loaded module (in memory) 10 | VA = ImageBase + RVA - real address of something in memory of the module 11 | RVA -> Offset: SectionRAW + (RVA - SectionRVA) 12 | ^- In section's header 13 | */ 14 | 15 | constexpr int SEC_NAME_SIZE = 8; 16 | 17 | struct SECTION_INFO 18 | { 19 | DWORD offsetInMemory; 20 | DWORD offsetInFile; 21 | DWORD sizeInMemory; 22 | DWORD sizeOnDisk; 23 | DWORD characteristics; 24 | WORD numberOfRelocs; 25 | CHAR name[SEC_NAME_SIZE + 1]; 26 | }; 27 | 28 | typedef std::vector SECTIONS_SET; 29 | 30 | struct RELOC_INFO 31 | { 32 | DWORD rva; // Page RVA + Offset 33 | BYTE relocType; 34 | }; 35 | 36 | typedef std::vector RELOCS_SET; 37 | 38 | struct IMPORT_INFO 39 | { 40 | PVOID oft; // OFT = OriginalFirstThunk 41 | PVOID ft; // FT = FirstThunk, адрес в IAT (реальный адрес в памяти) 42 | bool isOrdinalImport; 43 | SIZE_T ordinal; 44 | WORD hint; 45 | std::string name; 46 | }; 47 | 48 | typedef std::vector IMPORTS_SET; 49 | typedef std::unordered_map IMPORTS_MAP; // LibName -> imports 50 | 51 | struct DELAYED_IMPORT_INFO 52 | { 53 | DWORD attributes; 54 | HMODULE hModule; 55 | std::string dllName; 56 | IMPORTS_SET imports; 57 | }; 58 | 59 | typedef std::vector DELAYED_IMPORTS_SET; 60 | 61 | struct EXPORT_INFO 62 | { 63 | PVOID va; 64 | DWORD rva; 65 | DWORD ordinal; 66 | bool ordinalExport; 67 | std::string name; 68 | }; 69 | 70 | typedef std::vector EXPORTS_SET; 71 | 72 | struct EXPORTS_INFO 73 | { 74 | DWORD timeStamp; 75 | DWORD numberOfNames; 76 | DWORD numberOfFunctions; 77 | std::string name; 78 | EXPORTS_SET exports; 79 | }; 80 | 81 | class PEAnalyzer 82 | { 83 | private: 84 | bool m_isRawModule; 85 | bool m_areValidPeSignatures; 86 | 87 | PIMAGE_DOS_HEADER m_dosHeader; 88 | PIMAGE_NT_HEADERS m_ntHeaders; 89 | PIMAGE_OPTIONAL_HEADER m_optionalHeader; 90 | 91 | ULONG m_imageSize; 92 | 93 | PVOID m_localBase; 94 | 95 | PVOID m_imageBase; 96 | PVOID m_entryPoint; 97 | 98 | BOOL m_needToAlign; 99 | DWORD m_fileAlignment; 100 | DWORD m_sectionAlignment; 101 | 102 | SECTIONS_SET m_sections; 103 | RELOCS_SET m_relocs; 104 | IMPORTS_MAP m_imports; 105 | DELAYED_IMPORTS_SET m_delayedImports; 106 | EXPORTS_INFO m_exports; 107 | 108 | bool validatePeSignatures(); 109 | 110 | void fillSectionsInfo(); 111 | void fillRelocsInfo(); 112 | void fillImportsInfo(); 113 | void fillDelayedImportsInfo(); 114 | void fillExportsInfo(); 115 | 116 | void fillImportsSet(__in PIMAGE_THUNK_DATA thunk, __in PIMAGE_THUNK_DATA originalThunk, __out IMPORTS_SET& importsSet); 117 | 118 | public: 119 | PEAnalyzer(); 120 | PEAnalyzer(HMODULE hModule, bool isRawModule); 121 | ~PEAnalyzer(); 122 | 123 | bool load(HMODULE hModule, bool isRawModule); 124 | 125 | void clear(); 126 | 127 | [[nodiscard]] const SECTIONS_SET& getSectionsInfo() const { return m_sections; } 128 | [[nodiscard]] const RELOCS_SET& getRelocsInfo() const { return m_relocs; } 129 | [[nodiscard]] const IMPORTS_MAP& getImportsInfo() const { return m_imports; } 130 | [[nodiscard]] const DELAYED_IMPORTS_SET& getDelayedImports() const { return m_delayedImports; } 131 | [[nodiscard]] const EXPORTS_INFO& getExportsInfo() const { return m_exports; } 132 | 133 | [[nodiscard]] ULONG getImageSize() const { return m_imageSize; } 134 | [[nodiscard]] PVOID getImageBase() const { return m_imageBase; } 135 | [[nodiscard]] PVOID getLocalBase() const { return m_localBase; } 136 | [[nodiscard]] PVOID getEntryPoint() const { return m_entryPoint; } 137 | 138 | [[nodiscard]] PIMAGE_DOS_HEADER getDosHeader() const { return m_dosHeader; } 139 | [[nodiscard]] PIMAGE_NT_HEADERS getNtHeaders() const { return m_ntHeaders; } 140 | [[nodiscard]] PIMAGE_OPTIONAL_HEADER getOptionalHeader() const { return m_optionalHeader; } 141 | 142 | [[nodiscard]] bool isValidPe() const { return m_areValidPeSignatures; }; 143 | 144 | [[nodiscard]] SIZE_T rvaToOffset(SIZE_T rva) const; 145 | }; -------------------------------------------------------------------------------- /Kernel-Bridge/API/LinkedList.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* 4 | Depends on: 5 | - wdm.h 6 | */ 7 | 8 | template 9 | class LinkedList { 10 | private: 11 | using _Entry = struct { 12 | LIST_ENTRY ChainEntry; 13 | PVOID EntryObject; 14 | T Value; 15 | }; 16 | public: 17 | class ListEntry { 18 | private: 19 | _Entry Entry; 20 | public: 21 | ListEntry(const T& Value) : Entry({}) { 22 | InitializeListHead(&Entry.ChainEntry); 23 | Entry.EntryObject = this; 24 | Entry.Value = Value; 25 | } 26 | 27 | ~ListEntry() = default; 28 | 29 | PLIST_ENTRY GetChainEntry() { return &Entry.ChainEntry; } 30 | T* GetValue() { return &Entry.Value; } 31 | ListEntry* GetInstance() { return static_cast(Entry.EntryObject); } 32 | _Entry* GetEntry() { return &Entry; } 33 | }; 34 | 35 | class ListIterator { 36 | private: 37 | PLIST_ENTRY ListHead; 38 | _Entry* Current; 39 | public: 40 | ListIterator() : Current(NULL) {} 41 | ListIterator(PLIST_ENTRY Head, ListEntry* Entry) : ListHead(Head), Current(Entry->GetEntry()) {} 42 | ~ListIterator() = default; 43 | 44 | ListEntry* GetEntry() { return static_cast(Current->EntryObject); } 45 | 46 | ListIterator& operator ++ () { 47 | Current = Current->ChainEntry.Flink != ListHead 48 | ? reinterpret_cast<_Entry*>(Current->ChainEntry.Flink) 49 | : NULL; 50 | return *this; 51 | } 52 | 53 | ListIterator& operator -- () { 54 | Current = Current->ChainEntry.Flink != ListHead 55 | ? reinterpret_cast<_Entry*>(Current->ChainEntry.Blink) 56 | : NULL; 57 | return *this; 58 | } 59 | 60 | T& operator * () { return Current->Value; } 61 | 62 | bool operator == (const ListIterator& Iterator) const { 63 | return !Iterator.Current || !Current 64 | ? Iterator.Current == Current 65 | : Iterator.Current->EntryObject == Current->EntryObject; 66 | } 67 | 68 | bool operator != (const ListIterator& Iterator) const { 69 | return !Iterator.Current || !Current 70 | ? Iterator.Current != Current 71 | : Iterator.Current->EntryObject != Current->EntryObject; 72 | } 73 | }; 74 | private: 75 | __declspec(align(MEMORY_ALLOCATION_ALIGNMENT)) KSPIN_LOCK SpinLock; 76 | __declspec(align(MEMORY_ALLOCATION_ALIGNMENT)) LIST_ENTRY Head; 77 | 78 | ListIterator Finalizer; 79 | public: 80 | LinkedList(const LinkedList&) = delete; 81 | LinkedList(LinkedList&&) = delete; 82 | LinkedList& operator = (const LinkedList&) = delete; 83 | LinkedList& operator = (LinkedList&&) = delete; 84 | 85 | LinkedList() : Head({}), Finalizer() { 86 | KeInitializeSpinLock(&SpinLock); 87 | InitializeListHead(&Head); 88 | } 89 | 90 | ~LinkedList() { 91 | Clear(); 92 | } 93 | 94 | void Clear() { 95 | if (IsEmpty()) return; 96 | ListIterator it = begin(); 97 | while (it != end()) { 98 | auto Entry = it.GetEntry(); 99 | ++it; 100 | Remove(Entry); 101 | } 102 | } 103 | 104 | void InterlockedInsertTail(const T& Value) { 105 | auto Entry = new ListEntry(Value); 106 | ExInterlockedInsertTailList(&Head, Entry->GetChainEntry(), &SpinLock); 107 | } 108 | 109 | void InterlockedInsertHead(const T& Value) { 110 | auto Entry = new ListEntry(Value); 111 | ExInterlockedInsertHeadList(&Head, Entry->GetChainEntry(), &SpinLock); 112 | } 113 | 114 | void InterlockedRemoveHead() { 115 | auto Entry = ExInterlockedRemoveHeadList(&Head, &SpinLock); 116 | delete Entry; 117 | } 118 | 119 | ListEntry* InsertTail(const T& Value) { 120 | auto Entry = new ListEntry(Value); 121 | InsertTailList(&Head, Entry->GetChainEntry()); 122 | return Entry; 123 | } 124 | 125 | ListEntry* InsertHead(const T& Value) { 126 | auto Entry = new ListEntry(Value); 127 | InsertTailList(&Head, Entry->GetChainEntry()); 128 | return Entry; 129 | } 130 | 131 | void Remove(ListEntry* Entry) { 132 | RemoveEntryList(Entry->GetChainEntry()); 133 | delete Entry->GetInstance(); 134 | } 135 | 136 | void RemoveHead() { 137 | RemoveHeadList(&Head); 138 | } 139 | 140 | void RemoveTail() { 141 | RemoveTailList(&Head); 142 | } 143 | 144 | bool IsEmpty() const { 145 | return IsListEmpty(&Head); 146 | } 147 | 148 | ListIterator begin() { 149 | return ListIterator(&Head, static_cast((reinterpret_cast<_Entry*>(Head.Flink))->EntryObject)); 150 | } 151 | 152 | ListIterator end() { 153 | return Finalizer; 154 | } 155 | }; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The Kernel-Bridge Framework 2 | The "Kernel-Bridge" project is a C++20-ready Windows kernel driver template, development framework and 3 | kernel-mode API and wrappers. 4 | 5 | [Precompiled and signed binaries with the SecureBoot support](https://github.com/HoShiMin/Kernel-Bridge/releases) 6 | [Delphi bindings](https://github.com/diversenok/Kernel-Bridge-Delphi-Connector) 7 | 8 | ### ✔ Capabilities: 9 | * Hypervisor (both Intel VT-x/EPT and AMD-V/RVI) with the Hyper-V support 10 | * Extremely fast hypervisor-based memory interceptions and hiding (+ support of Write-only pages), VT-x only 11 | * Support of [HookLib](https://github.com/HoShiMin/HookLib) and [Zydis](https://github.com/zyantific/zydis) 12 | * IO-ports (+ 'in/out/cli/sti' usermode forwarding by IOPL) 13 | * System beeper 14 | * MSRs, CPUID, TSC and performance counters (RDPMC) 15 | * DMI/SMBIOS memory reading 16 | * Physical memory (allocations, RW, mappings) 17 | * Kernel memory management (allocations, mappings, transitions) 18 | * Usermode memory management (allocations in processes etc.) 19 | * Direct UM->KM and KM->UM memory transitions 20 | * Direct PTE-based memory management 21 | * Direct MDL management 22 | * Obtaining processes/threads handles from kernel 23 | * Reading and writing memory of another processes 24 | * Suspending/resuming/termination processes 25 | * Creating kernel and usermode threads 26 | * Memory mappings between usermode and kernel 27 | * Remote code execution (APCs delivery) 28 | * Execution of custom usermode shellcodes 29 | * Unsigned drivers mapping 30 | * Processes, threads, handles and modules usermode callbacks (`ObRegisterCallbacks` & `PsSet***NotifyRoutine`) 31 | * Minifilter with usermode callbacks 32 | * PDB parsing 33 | * Signatures and patterns scanning 34 | * Sections management (to map `\\Device\PhysicalMemory` and more) 35 | * Python binding 36 | 37 | ### ➰ In development and plans: 38 | * Qt-based GUI for the kernel-hacking and memory researching framework 39 | * Kernel WinSock support 40 | * Extensions for the RTL: hooks, injections, disassembling 41 | * Kernel loadable modules with SEH support 42 | 43 | Driver template has full support of C++ static and global initializers and all of C++20 features (without C++ exceptions). All of API modules are easy-to-use and have no external dependiencies, so you can include them to your own C++ drivers. All of API functions are grouped into a logical categories into namespaces, so you can quickly find all functions you want. 44 | 45 | ### 💦 Driver template has: 46 | * Support of METHOD_BUFFERED, METHOD_IN/OUT_DIRECT and METHOD_NEITHER 47 | * Minifilter loading and filtering routines templates 48 | * SAL-annotations and self-documented API 49 | * Ready-to-use IOCTLs handling routine 50 | * Out-of-box STL support 51 | * Static Driver Verifier tests passing 52 | 53 | ### 💨 Building and using: 54 | Download [Microsoft Visual Studio Community](https://visualstudio.microsoft.com/downloads/) and [Windows Driver Kit](https://docs.microsoft.com/en-us/windows-hardware/drivers/download-the-wdk). 55 | For driver testing use [VMware Player](https://my.vmware.com/en/web/vmware/free#desktop_end_user_computing/vmware_workstation_player/14_0). 56 | For load an unsigned drivers you should to enable Test-mode of Windows and disable signs checkings: 57 | ``` 58 | - Disable signatures checkings (allow to install unsigned drivers): 59 | bcdedit.exe /set loadoptions DISABLE_INTEGRITY_CHECKS 60 | bcdedit.exe /set TESTSIGNING ON 61 | 62 | - Enable signatures checkings (deny to install unsigned drivers): 63 | bcdedit.exe /set loadoptions ENABLE_INTEGRITY_CHECKS 64 | bcdedit.exe /set TESTSIGNING OFF 65 | 66 | - Enable support of kernel debugger (WinDbg and Kernel Debugger from WDK): 67 | bcdedit.exe /debug on - enable support of kernel debugging 68 | bcdedit.exe /debug off - disable it 69 | ``` 70 | 71 | #### Communication with usermode apps: 72 | For communication with usermode you should use "User-Bridge" wrappers as standalone \*.cpp/\*.h modules or as \*.dll. 73 | All required headers are `WdkTypes.h`, `CtlTypes.h` and `User-Bridge.h`. For using an extended features like minifilter callbacks, you should also use `FltTypes.h`, `CommPort.h` and `Flt-Bridge.h`. Some of ready-to-use RTL-functions (like an unsigned drivers mapping) you can find in `Rtl-Bridge.h`. 74 | 75 | #### Files hierarchy: 76 | `/User-Bridge/API/` - usermode API and wrappers for all functions of KB 77 | `/Kernel-Bridge/API/` - standalone kernel API for using in C++ drivers 78 | `/Kernel-Bridge/Kernel-Bridge/` - driver template files 79 | `/SharedTypes/` - shared types headers required for UM and KM modules 80 | `/CommonTypes/` - common user- and kernelmode headers and types 81 | `/Python-Bridge/` - Python binding 82 | `/Kernel-Tests/` - unit-tests for UM and KM modules and common functions 83 | 84 | #### Example (using of KbReadProcessMemory): 85 | ```cpp 86 | #include 87 | 88 | #include "WdkTypes.h" 89 | #include "CtlTypes.h" 90 | #include "User-Bridge.h" 91 | 92 | using namespace Processes::MemoryManagement; 93 | 94 | ... 95 | 96 | // Loading as minifilter (it allows to use extended features): 97 | KbLoader::KbLoadAsFilter(L"N:\\Folder\\Kernel-Bridge.sys", L"260000"); 98 | 99 | constexpr int Size = 64; 100 | UCHAR Buffer[Size] = {}; 101 | 102 | BOOL Status = KbReadProcessMemory( 103 | ProcessId, 104 | 0x7FFF0000, // Desired address in context of ProcessId 105 | &Buffer, 106 | Size 107 | ); 108 | 109 | KbLoader::KbUnload(); 110 | ``` 111 | -------------------------------------------------------------------------------- /Kernel-Bridge/API/IO.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifdef _X86_ 4 | // For compatibility with C++17, because contains deprecated language statements: 5 | extern "C" unsigned char __inbyte(unsigned short PortNumber); 6 | extern "C" unsigned short __inword(unsigned short PortNumber); 7 | extern "C" unsigned long __indword(unsigned short PortNumber); 8 | extern "C" void __inbytestring(unsigned short PortNumber, unsigned char* Buffer, unsigned long Count); 9 | extern "C" void __inwordstring(unsigned short PortNumber, unsigned short* Buffer, unsigned long Count); 10 | extern "C" void __indwordstring(unsigned short PortNumber, unsigned long* Buffer, unsigned long Count); 11 | extern "C" void __outbyte(unsigned short PortNumber, unsigned char Data); 12 | extern "C" void __outword(unsigned short PortNumber, unsigned short Data); 13 | extern "C" void __outdword(unsigned short PortNumber, unsigned long Data); 14 | extern "C" void __outbytestring(unsigned short PortNumber, unsigned char* Buffer, unsigned long Count); 15 | extern "C" void __outwordstring(unsigned short PortNumber, unsigned short* Buffer, unsigned long Count); 16 | extern "C" void __outdwordstring(unsigned short PortNumber, unsigned long* Buffer, unsigned long Count); 17 | #endif 18 | 19 | namespace IO { 20 | namespace IOPL { 21 | constexpr unsigned int IoplAccessMask = 0x3000; 22 | 23 | #ifdef _AMD64_ 24 | PKTRAP_FRAME GetTrapFrame() { 25 | return reinterpret_cast( 26 | reinterpret_cast(IoGetInitialStack()) - sizeof(KTRAP_FRAME) 27 | ); 28 | } 29 | 30 | void RaiseIopl() { 31 | GetTrapFrame()->EFlags |= IoplAccessMask; 32 | } 33 | 34 | void ResetIopl() { 35 | GetTrapFrame()->EFlags &= ~IoplAccessMask; 36 | } 37 | #elif _X86_ 38 | // Offsets from: https://www.geoffchappell.com/studies/windows/km/ntoskrnl/structs/ktrap_frame.htm 39 | constexpr unsigned char KTrapFrame32Size = 0x8C; 40 | constexpr unsigned char EFlagsOffsetInKTrapFrame32 = 0x70; 41 | 42 | PVOID GetTrapFrame() { 43 | return reinterpret_cast( 44 | reinterpret_cast(IoGetInitialStack()) - KTrapFrame32Size 45 | ); 46 | } 47 | 48 | PULONG GetEFlagsPtr(PVOID KTrapFramePtr) { 49 | return reinterpret_cast( 50 | reinterpret_cast(KTrapFramePtr) + EFlagsOffsetInKTrapFrame32 51 | ); 52 | } 53 | 54 | void RaiseIopl() { 55 | *GetEFlagsPtr(GetTrapFrame()) |= IoplAccessMask; 56 | } 57 | 58 | void ResetIopl() { 59 | *GetEFlagsPtr(GetTrapFrame()) &= ~IoplAccessMask; 60 | } 61 | #endif 62 | } 63 | 64 | namespace Beeper { 65 | void SetBeeperRegime() { 66 | __outbyte(0x43, 0xB6); 67 | } 68 | 69 | void StartBeeper() { 70 | __outbyte(0x61, __inbyte(0x61) | 3); 71 | } 72 | 73 | void StopBeeper() { 74 | __outbyte(0x61, __inbyte(0x61) & 252); 75 | } 76 | 77 | void SetBeeperIn() { 78 | __outbyte(0x61, __inbyte(0x61) & 253); 79 | } 80 | 81 | void SetBeeperOut() { 82 | __outbyte(0x61, __inbyte(0x61) | 2); 83 | } 84 | 85 | void SetBeeperDivider(unsigned short Divider) { 86 | __outbyte(0x42, static_cast(Divider)); 87 | __outbyte(0x42, static_cast(Divider >> 8)); 88 | } 89 | 90 | void SetBeeperFrequency(unsigned short Frequency) { 91 | if (!Frequency) Frequency = 1; 92 | SetBeeperDivider(static_cast(1193182 / static_cast(Frequency))); 93 | } 94 | } 95 | 96 | namespace RW { 97 | unsigned char ReadPortByte(unsigned short PortNumber) { 98 | return __inbyte(PortNumber); 99 | } 100 | 101 | unsigned short ReadPortWord(unsigned short PortNumber) { 102 | return __inword(PortNumber); 103 | } 104 | 105 | unsigned long ReadPortDword(unsigned short PortNumber) { 106 | return __indword(PortNumber); 107 | } 108 | 109 | void ReadPortByteString(unsigned short PortNumber, unsigned char* Buffer, unsigned long Count) { 110 | return __inbytestring(PortNumber, Buffer, Count); 111 | } 112 | 113 | void ReadPortWordString(unsigned short PortNumber, unsigned short* Buffer, unsigned long Count) { 114 | return __inwordstring(PortNumber, Buffer, Count); 115 | } 116 | 117 | void ReadPortDwordString(unsigned short PortNumber, unsigned long* Buffer, unsigned long Count) { 118 | return __indwordstring(PortNumber, Buffer, Count); 119 | } 120 | 121 | void WritePortByte(unsigned short PortNumber, unsigned char Data) { 122 | __outbyte(PortNumber, Data); 123 | } 124 | 125 | void WritePortWord(unsigned short PortNumber, unsigned short Data) { 126 | __outword(PortNumber, Data); 127 | } 128 | 129 | void WritePortDword(unsigned short PortNumber, unsigned long Data) { 130 | __outdword(PortNumber, Data); 131 | } 132 | 133 | void WritePortByteString(unsigned short PortNumber, unsigned char* Buffer, unsigned long Count) { 134 | __outbytestring(PortNumber, Buffer, Count); 135 | } 136 | 137 | void WritePortWordString(unsigned short PortNumber, unsigned short* Buffer, unsigned long Count) { 138 | __outwordstring(PortNumber, Buffer, Count); 139 | } 140 | 141 | void WritePortDwordString(unsigned short PortNumber, unsigned long* Buffer, unsigned long Count) { 142 | __outdwordstring(PortNumber, Buffer, Count); 143 | } 144 | } 145 | } -------------------------------------------------------------------------------- /Kernel-Bridge/API/CommPort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "MemoryUtils.h" 4 | 5 | #include "Locks.h" 6 | #include "LinkedList.h" 7 | #include "CommPort.h" 8 | 9 | CommPort::CommPort() 10 | : ParentFilter(NULL), ServerCookie({}), ServerPort(NULL), Clients(), OnMessageCallback(NULL) {} 11 | 12 | CommPort::~CommPort() { 13 | StopServer(); 14 | } 15 | 16 | 17 | 18 | NTSTATUS CommPort::StartServer( 19 | PFLT_FILTER Filter, 20 | LPCWSTR PortName, 21 | _OnMessage OnMessage, 22 | LONG MaxConnections, 23 | OPTIONAL PVOID Cookie 24 | ) { 25 | if (ServerPort) StopServer(); 26 | 27 | ParentFilter = Filter; 28 | OnMessageCallback = OnMessage; 29 | 30 | ServerCookie.ServerInstance = this; 31 | ServerCookie.UserCookie = Cookie; 32 | 33 | UNICODE_STRING Name = {}; 34 | RtlInitUnicodeString(&Name, PortName); 35 | 36 | PSECURITY_DESCRIPTOR SecurityDescriptor = NULL; 37 | NTSTATUS Status = FltBuildDefaultSecurityDescriptor(&SecurityDescriptor, FLT_PORT_ALL_ACCESS); 38 | if (!NT_SUCCESS(Status)) { 39 | KdPrint(("[Kernel-Bridge]: Create security descriptor failure (0x%X)\r\n", Status)); 40 | return Status; 41 | } 42 | 43 | OBJECT_ATTRIBUTES ObjectAttributes = {}; 44 | InitializeObjectAttributes(&ObjectAttributes, &Name, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, SecurityDescriptor); 45 | 46 | Status = FltCreateCommunicationPort( 47 | ParentFilter, 48 | &ServerPort, 49 | &ObjectAttributes, 50 | &ServerCookie, 51 | OnConnectInternal, 52 | OnDisconnectInternal, 53 | OnMessageInternal, 54 | MaxConnections 55 | ); 56 | 57 | FltFreeSecurityDescriptor(SecurityDescriptor); 58 | 59 | if (NT_SUCCESS(Status)) 60 | KdPrint(("[Kernel-Bridge]: Comm.Port created!\r\n")); 61 | else 62 | KdPrint(("[Kernel-Bridge]: Comm.Port failure: 0x%X\r\n", Status)); 63 | 64 | return Status; 65 | } 66 | 67 | VOID CommPort::StopServer() { 68 | if (ServerPort) FltCloseCommunicationPort(ServerPort); 69 | // Disconnecting all connected clients: 70 | Clients.LockExclusive(); 71 | for (auto& Client : Clients) { 72 | FltCloseClientPort(ParentFilter, &Client.ClientPort); 73 | } 74 | Clients.Unlock(); 75 | } 76 | 77 | 78 | 79 | NTSTATUS CommPort::OnConnectInternal( 80 | IN PFLT_PORT ClientPort, 81 | IN PVOID ServerPortCookie, 82 | IN PVOID ConnectionContext, 83 | IN ULONG SizeOfContext, 84 | OUT PVOID *ConnectionPortCookie 85 | ) { 86 | KdPrint(("[Kernel-Bridge]: Comm.Port OnConnect\r\n")); 87 | 88 | auto ServerCookie = static_cast(ServerPortCookie); 89 | 90 | CLIENT_INFO Client = {}; 91 | Client.ServerInstance = ServerCookie->ServerInstance; 92 | Client.ClientPort = ClientPort; 93 | 94 | if (ConnectionContext && SizeOfContext) { 95 | PVOID ContextBuffer = VirtualMemory::AllocFromPool(SizeOfContext); 96 | RtlCopyMemory(ContextBuffer, ConnectionContext, SizeOfContext); 97 | Client.ConnectionContext = ContextBuffer; 98 | Client.SizeOfContext = SizeOfContext; 99 | } 100 | 101 | // Add 'Client' to clients list: 102 | auto ServerInstance = static_cast(ServerCookie->ServerInstance); 103 | ServerInstance->Clients.LockExclusive(); 104 | *ConnectionPortCookie = static_cast(ServerInstance->Clients.InsertTail(Client)); 105 | ServerInstance->Clients.Unlock(); 106 | 107 | return STATUS_SUCCESS; 108 | } 109 | 110 | VOID CommPort::OnDisconnectInternal( 111 | IN PVOID ConnectionContext 112 | ) { 113 | KdPrint(("[Kernel-Bridge]: Comm.Port OnDisconnect\r\n")); 114 | 115 | // Free client-specific info: 116 | auto ClientEntry = static_cast(ConnectionContext); 117 | if (ClientEntry->GetValue()->ClientPort) 118 | FltCloseClientPort(ClientEntry->GetValue()->ServerInstance->ParentFilter, &ClientEntry->GetValue()->ClientPort); 119 | if (ClientEntry->GetValue()->ConnectionContext && ClientEntry->GetValue()->SizeOfContext) { 120 | VirtualMemory::FreePoolMemory(ClientEntry->GetValue()->ConnectionContext); 121 | } 122 | 123 | // Unlink client from clients list: 124 | CommPort* ServerInstance = ClientEntry->GetValue()->ServerInstance; 125 | ServerInstance->Clients.LockExclusive(); 126 | ServerInstance->Clients.Remove(ClientEntry); 127 | ServerInstance->Clients.Unlock(); 128 | } 129 | 130 | NTSTATUS CommPort::OnMessageInternal( 131 | IN PVOID PortCookie, 132 | IN PVOID InputBuffer OPTIONAL, 133 | IN ULONG InputBufferLength, 134 | OUT PVOID OutputBuffer OPTIONAL, 135 | IN ULONG OutputBufferLength, 136 | OUT PULONG ReturnOutputBufferLength 137 | ) { 138 | auto ClientEntry = static_cast(PortCookie); 139 | _OnMessage Handler = ClientEntry->GetValue()->ServerInstance->OnMessageCallback; 140 | if (Handler) { 141 | CLIENT_REQUEST Request = {}; 142 | Request.InputBuffer = InputBuffer; 143 | Request.InputSize = InputBufferLength; 144 | Request.OutputBuffer = OutputBuffer; 145 | Request.OutputSize = OutputBufferLength; 146 | return Handler(*ClientEntry->GetValue(), Request, ReturnOutputBufferLength); 147 | } 148 | return STATUS_SUCCESS; 149 | } 150 | 151 | NTSTATUS CommPort::Send( 152 | PFLT_PORT Client, 153 | IN PVOID Buffer, 154 | ULONG Size, 155 | OUT PVOID Response, 156 | ULONG ResponseSize, 157 | ULONG MsecTimeout 158 | ) { 159 | if (MsecTimeout == 0xFFFFFFFF) // Infinite wait: 160 | return FltSendMessage(ParentFilter, &Client, Buffer, Size, Response, &ResponseSize, NULL); 161 | 162 | LARGE_INTEGER _Timeout; // In 100-ns units 163 | _Timeout.QuadPart = - static_cast(MsecTimeout) * 10 * 1000; // Relative time is negative! 164 | return FltSendMessage(ParentFilter, &Client, Buffer, Size, Response, &ResponseSize, &_Timeout); 165 | } -------------------------------------------------------------------------------- /User-Bridge/API/PEUtils/PELoader.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "PEAnalyzer.h" 3 | #include "PELoader.h" 4 | 5 | #include 6 | 7 | PELoader::PELoader( 8 | HMODULE rawModule, 9 | ImportNameCallback importNameCallback, 10 | ImportOrdinalCallback importOrdinalCallback) 11 | { 12 | PEAnalyzer pe(rawModule, true); 13 | 14 | m_deployedSize = pe.getImageSize(); 15 | m_hModule = static_cast(VirtualAlloc(NULL, m_deployedSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE)); 16 | if (!m_hModule) 17 | throw std::runtime_error("Unable to allocate memory"); 18 | 19 | // Copying of headers: 20 | CopyMemory(m_hModule, rawModule, pe.getOptionalHeader()->SizeOfHeaders); 21 | 22 | // Copying of sections: 23 | for (const auto& sec : pe.getSectionsInfo()) 24 | { 25 | CopyMemory( 26 | m_hModule + sec.offsetInMemory, 27 | reinterpret_cast(rawModule) + sec.offsetInFile, 28 | sec.sizeOnDisk 29 | ); 30 | } 31 | 32 | m_dosHeader = reinterpret_cast(m_hModule); 33 | m_ntHeaders = reinterpret_cast(m_hModule + m_dosHeader->e_lfanew); 34 | m_optionalHeader = static_cast(&m_ntHeaders->OptionalHeader); 35 | 36 | m_originalImageBase = m_optionalHeader->ImageBase; 37 | 38 | // Filling imports and exports: 39 | fillImports(importNameCallback, importOrdinalCallback); 40 | 41 | // Relocating to current memory block: 42 | m_previousLoadDelta = 0; 43 | relocate(reinterpret_cast(m_hModule)); 44 | } 45 | 46 | void PELoader::fillImports( 47 | ImportNameCallback importNameCallback, 48 | ImportOrdinalCallback importOrdinalCallback) 49 | { 50 | auto importDir = reinterpret_cast( 51 | &m_optionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] 52 | ); 53 | 54 | if (importDir->Size == 0) return; 55 | 56 | auto imports = reinterpret_cast(m_hModule + importDir->VirtualAddress); 57 | while (imports->FirstThunk) 58 | { 59 | LPCSTR libName = reinterpret_cast(m_hModule + imports->Name); 60 | auto thunk = reinterpret_cast(m_hModule + imports->FirstThunk); 61 | auto originalThunk = reinterpret_cast(m_hModule + imports->OriginalFirstThunk); 62 | 63 | while (thunk->u1.AddressOfData) 64 | { 65 | auto namedImport = reinterpret_cast(m_hModule + originalThunk->u1.AddressOfData); 66 | 67 | const SIZE_T OrdinalPresentMask = (SIZE_T)0x80 << (SIZE_T)((sizeof(SIZE_T) - 1) * 8); 68 | const SIZE_T OrdinalMask = OrdinalPresentMask - 1; 69 | 70 | if ((thunk->u1.Function & OrdinalMask) == OrdinalMask) 71 | { 72 | thunk->u1.Function = reinterpret_cast( 73 | importOrdinalCallback(libName, static_cast(thunk->u1.Function & OrdinalMask)) 74 | ); 75 | } 76 | else 77 | { 78 | thunk->u1.Function = reinterpret_cast( 79 | importNameCallback(libName, namedImport->Name) 80 | ); 81 | } 82 | 83 | ++thunk; 84 | ++originalThunk; 85 | } 86 | 87 | ++imports; 88 | } 89 | } 90 | 91 | void PELoader::relocate(HMODULE base) 92 | { 93 | // Check whether we have (or have no) relocs: 94 | if (m_ntHeaders->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) return; 95 | 96 | auto relocsDir = static_cast( 97 | &m_optionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC] 98 | ); 99 | 100 | if (relocsDir->Size == 0) return; 101 | 102 | m_optionalHeader->ImageBase = reinterpret_cast(base); 103 | SIZE_T loadDelta = reinterpret_cast(base) - m_originalImageBase; 104 | 105 | auto relocs = reinterpret_cast(m_hModule + relocsDir->VirtualAddress); 106 | auto relocsFinalAddress = reinterpret_cast(reinterpret_cast(relocs) + relocsDir->Size); 107 | while (relocs < relocsFinalAddress) 108 | { 109 | DWORD relocsRva = relocs->VirtualAddress; 110 | 111 | DWORD relocsCount = (relocs->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD); 112 | PWORD relocEntry = reinterpret_cast(reinterpret_cast(relocs) + sizeof(IMAGE_BASE_RELOCATION)); 113 | 114 | for (unsigned int i = 0; i < relocsCount; ++i, ++relocEntry) 115 | { 116 | WORD reloc = *relocEntry; 117 | 118 | constexpr DWORD relocsOffsetMask = 0b0000111111111111; // Lower 12 bits 119 | DWORD relocRva = relocsRva + (reloc & relocsOffsetMask); 120 | BYTE type = static_cast(reloc >> 12); 121 | 122 | PVOID relocAddress = reinterpret_cast(m_hModule + relocRva); 123 | 124 | switch (type) { 125 | case IMAGE_REL_BASED_HIGH: { 126 | *static_cast(relocAddress) += HIWORD(loadDelta) - HIWORD(m_previousLoadDelta); 127 | break; 128 | } 129 | case IMAGE_REL_BASED_LOW: { 130 | *static_cast(relocAddress) += LOWORD(loadDelta) - LOWORD(m_previousLoadDelta); 131 | break; 132 | } 133 | case IMAGE_REL_BASED_HIGHLOW: { 134 | *static_cast(relocAddress) += loadDelta - m_previousLoadDelta; 135 | break; 136 | } 137 | case IMAGE_REL_BASED_DIR64: { 138 | *static_cast(relocAddress) += loadDelta - m_previousLoadDelta; 139 | break; 140 | } 141 | case IMAGE_REL_BASED_ABSOLUTE: 142 | case IMAGE_REL_BASED_HIGHADJ: 143 | break; 144 | } 145 | } 146 | 147 | relocs = reinterpret_cast(reinterpret_cast(relocs) + relocs->SizeOfBlock); 148 | } 149 | 150 | m_previousLoadDelta = loadDelta; 151 | } -------------------------------------------------------------------------------- /Kernel-Bridge.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30114.128 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Kernel-Bridge", "Kernel-Bridge\Kernel-Bridge.vcxproj", "{9AF3F0D6-AFE5-4A4B-A50C-667126FFF1F6}" 7 | ProjectSection(ProjectDependencies) = postProject 8 | {88A23124-5640-35A0-B890-311D7A67A7D2} = {88A23124-5640-35A0-B890-311D7A67A7D2} 9 | {9379F9BC-7829-45D8-B339-90F6504FDF2B} = {9379F9BC-7829-45D8-B339-90F6504FDF2B} 10 | EndProjectSection 11 | EndProject 12 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "User-Bridge", "User-Bridge\User-Bridge.vcxproj", "{09805AB7-6E91-46A3-B501-A420E56458AB}" 13 | EndProject 14 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Kernel-Tests", "Kernel-Tests\Kernel-Tests.vcxproj", "{95F62D20-4D68-475B-8B69-D1EB3585F3F3}" 15 | EndProject 16 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HookLib", "HookLib\HookLib\HookLib.vcxproj", "{9379F9BC-7829-45D8-B339-90F6504FDF2B}" 17 | ProjectSection(ProjectDependencies) = postProject 18 | {88A23124-5640-35A0-B890-311D7A67A7D2} = {88A23124-5640-35A0-B890-311D7A67A7D2} 19 | EndProjectSection 20 | EndProject 21 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Zydis", "HookLib\HookLib\Zydis\msvc\zydis\Zydis.vcxproj", "{88A23124-5640-35A0-B890-311D7A67A7D2}" 22 | EndProject 23 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LoadableModule", "LoadableModule\LoadableModule.vcxproj", "{E52B479E-B60F-4254-98BA-31A18C4B1F70}" 24 | EndProject 25 | Global 26 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 27 | Debug|x64 = Debug|x64 28 | Debug|x86 = Debug|x86 29 | Release|x64 = Release|x64 30 | Release|x86 = Release|x86 31 | EndGlobalSection 32 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 33 | {9AF3F0D6-AFE5-4A4B-A50C-667126FFF1F6}.Debug|x64.ActiveCfg = Debug|x64 34 | {9AF3F0D6-AFE5-4A4B-A50C-667126FFF1F6}.Debug|x64.Build.0 = Debug|x64 35 | {9AF3F0D6-AFE5-4A4B-A50C-667126FFF1F6}.Debug|x86.ActiveCfg = Debug|Win32 36 | {9AF3F0D6-AFE5-4A4B-A50C-667126FFF1F6}.Debug|x86.Build.0 = Debug|Win32 37 | {9AF3F0D6-AFE5-4A4B-A50C-667126FFF1F6}.Debug|x86.Deploy.0 = Debug|Win32 38 | {9AF3F0D6-AFE5-4A4B-A50C-667126FFF1F6}.Release|x64.ActiveCfg = Release|x64 39 | {9AF3F0D6-AFE5-4A4B-A50C-667126FFF1F6}.Release|x64.Build.0 = Release|x64 40 | {9AF3F0D6-AFE5-4A4B-A50C-667126FFF1F6}.Release|x86.ActiveCfg = Release|Win32 41 | {9AF3F0D6-AFE5-4A4B-A50C-667126FFF1F6}.Release|x86.Build.0 = Release|Win32 42 | {09805AB7-6E91-46A3-B501-A420E56458AB}.Debug|x64.ActiveCfg = Debug|x64 43 | {09805AB7-6E91-46A3-B501-A420E56458AB}.Debug|x64.Build.0 = Debug|x64 44 | {09805AB7-6E91-46A3-B501-A420E56458AB}.Debug|x86.ActiveCfg = Debug|Win32 45 | {09805AB7-6E91-46A3-B501-A420E56458AB}.Debug|x86.Build.0 = Debug|Win32 46 | {09805AB7-6E91-46A3-B501-A420E56458AB}.Release|x64.ActiveCfg = Release|x64 47 | {09805AB7-6E91-46A3-B501-A420E56458AB}.Release|x64.Build.0 = Release|x64 48 | {09805AB7-6E91-46A3-B501-A420E56458AB}.Release|x86.ActiveCfg = Release|Win32 49 | {09805AB7-6E91-46A3-B501-A420E56458AB}.Release|x86.Build.0 = Release|Win32 50 | {95F62D20-4D68-475B-8B69-D1EB3585F3F3}.Debug|x64.ActiveCfg = Debug|x64 51 | {95F62D20-4D68-475B-8B69-D1EB3585F3F3}.Debug|x64.Build.0 = Debug|x64 52 | {95F62D20-4D68-475B-8B69-D1EB3585F3F3}.Debug|x86.ActiveCfg = Debug|Win32 53 | {95F62D20-4D68-475B-8B69-D1EB3585F3F3}.Debug|x86.Build.0 = Debug|Win32 54 | {95F62D20-4D68-475B-8B69-D1EB3585F3F3}.Release|x64.ActiveCfg = Release|x64 55 | {95F62D20-4D68-475B-8B69-D1EB3585F3F3}.Release|x64.Build.0 = Release|x64 56 | {95F62D20-4D68-475B-8B69-D1EB3585F3F3}.Release|x86.ActiveCfg = Release|Win32 57 | {95F62D20-4D68-475B-8B69-D1EB3585F3F3}.Release|x86.Build.0 = Release|Win32 58 | {9379F9BC-7829-45D8-B339-90F6504FDF2B}.Debug|x64.ActiveCfg = Debug Kernel|x64 59 | {9379F9BC-7829-45D8-B339-90F6504FDF2B}.Debug|x64.Build.0 = Debug Kernel|x64 60 | {9379F9BC-7829-45D8-B339-90F6504FDF2B}.Debug|x86.ActiveCfg = Debug Kernel|Win32 61 | {9379F9BC-7829-45D8-B339-90F6504FDF2B}.Debug|x86.Build.0 = Debug Kernel|Win32 62 | {9379F9BC-7829-45D8-B339-90F6504FDF2B}.Release|x64.ActiveCfg = Release Kernel|x64 63 | {9379F9BC-7829-45D8-B339-90F6504FDF2B}.Release|x64.Build.0 = Release Kernel|x64 64 | {9379F9BC-7829-45D8-B339-90F6504FDF2B}.Release|x86.ActiveCfg = Release Kernel|Win32 65 | {9379F9BC-7829-45D8-B339-90F6504FDF2B}.Release|x86.Build.0 = Release Kernel|Win32 66 | {88A23124-5640-35A0-B890-311D7A67A7D2}.Debug|x64.ActiveCfg = Debug Kernel|x64 67 | {88A23124-5640-35A0-B890-311D7A67A7D2}.Debug|x64.Build.0 = Debug Kernel|x64 68 | {88A23124-5640-35A0-B890-311D7A67A7D2}.Debug|x86.ActiveCfg = Debug Kernel|Win32 69 | {88A23124-5640-35A0-B890-311D7A67A7D2}.Debug|x86.Build.0 = Debug Kernel|Win32 70 | {88A23124-5640-35A0-B890-311D7A67A7D2}.Debug|x86.Deploy.0 = Debug Kernel|Win32 71 | {88A23124-5640-35A0-B890-311D7A67A7D2}.Release|x64.ActiveCfg = Release Kernel|x64 72 | {88A23124-5640-35A0-B890-311D7A67A7D2}.Release|x64.Build.0 = Release Kernel|x64 73 | {88A23124-5640-35A0-B890-311D7A67A7D2}.Release|x86.ActiveCfg = Release Kernel|Win32 74 | {88A23124-5640-35A0-B890-311D7A67A7D2}.Release|x86.Build.0 = Release Kernel|Win32 75 | {E52B479E-B60F-4254-98BA-31A18C4B1F70}.Debug|x64.ActiveCfg = Debug|x64 76 | {E52B479E-B60F-4254-98BA-31A18C4B1F70}.Debug|x64.Build.0 = Debug|x64 77 | {E52B479E-B60F-4254-98BA-31A18C4B1F70}.Debug|x64.Deploy.0 = Debug|x64 78 | {E52B479E-B60F-4254-98BA-31A18C4B1F70}.Debug|x86.ActiveCfg = Debug|Win32 79 | {E52B479E-B60F-4254-98BA-31A18C4B1F70}.Debug|x86.Build.0 = Debug|Win32 80 | {E52B479E-B60F-4254-98BA-31A18C4B1F70}.Debug|x86.Deploy.0 = Debug|Win32 81 | {E52B479E-B60F-4254-98BA-31A18C4B1F70}.Release|x64.ActiveCfg = Release|x64 82 | {E52B479E-B60F-4254-98BA-31A18C4B1F70}.Release|x64.Build.0 = Release|x64 83 | {E52B479E-B60F-4254-98BA-31A18C4B1F70}.Release|x64.Deploy.0 = Release|x64 84 | {E52B479E-B60F-4254-98BA-31A18C4B1F70}.Release|x86.ActiveCfg = Release|Win32 85 | {E52B479E-B60F-4254-98BA-31A18C4B1F70}.Release|x86.Build.0 = Release|Win32 86 | {E52B479E-B60F-4254-98BA-31A18C4B1F70}.Release|x86.Deploy.0 = Release|Win32 87 | EndGlobalSection 88 | GlobalSection(SolutionProperties) = preSolution 89 | HideSolutionNode = FALSE 90 | EndGlobalSection 91 | GlobalSection(ExtensibilityGlobals) = postSolution 92 | SolutionGuid = {37EC3B5E-9924-4461-B0C3-E334C16528EB} 93 | EndGlobalSection 94 | EndGlobal 95 | -------------------------------------------------------------------------------- /User-Bridge/API/DriversUtils.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "DriversUtils.h" 4 | 5 | BOOL InstallDriver(LPCWSTR FilePath, LPCWSTR DriverName, DWORD DriverType) 6 | { 7 | SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE); 8 | 9 | if (hSCManager == NULL) return FALSE; 10 | 11 | SC_HANDLE hService = CreateService( 12 | hSCManager, DriverName, DriverName, 13 | SERVICE_ALL_ACCESS, DriverType, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, FilePath, 14 | NULL, NULL, NULL, NULL, NULL 15 | ); 16 | 17 | if (hService == NULL) { 18 | CloseServiceHandle(hSCManager); 19 | return FALSE; 20 | } 21 | 22 | LPCWSTR Arguments = NULL; 23 | BOOL Status = StartService(hService, 0, &Arguments); 24 | 25 | CloseServiceHandle(hService); 26 | CloseServiceHandle(hSCManager); 27 | 28 | return Status; 29 | } 30 | 31 | BOOL SetupFilterInstance(LPCWSTR DriverName, LPCWSTR InstanceName, LPCWSTR Altitude, DWORD Flags, BOOL SetAsDefaultInstance) 32 | { 33 | WCHAR PathBuffer[MAX_PATH] = {}; 34 | wcscpy_s(PathBuffer, MAX_PATH, L"System\\CurrentControlSet\\Services\\"); 35 | wcscat_s(PathBuffer, MAX_PATH, DriverName); 36 | 37 | // Registering an instance with specified flags and altitude: 38 | HKEY hKey = NULL; 39 | LSTATUS RegStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, PathBuffer, 0, KEY_ALL_ACCESS, &hKey); 40 | if (RegStatus != ERROR_SUCCESS) return FALSE; 41 | 42 | HKEY hInstancesKey = NULL; 43 | DWORD Disposition = 0; 44 | RegStatus = RegCreateKeyEx(hKey, L"Instances", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hInstancesKey, &Disposition); 45 | RegCloseKey(hKey); 46 | if (RegStatus != ERROR_SUCCESS) return FALSE; 47 | 48 | if (SetAsDefaultInstance) { 49 | RegStatus = RegSetValueEx( 50 | hInstancesKey, 51 | L"DefaultInstance", 52 | 0, 53 | REG_SZ, 54 | reinterpret_cast(InstanceName), 55 | (static_cast(wcsnlen_s(InstanceName, MAX_PATH)) + 1) * sizeof(WCHAR) 56 | ); 57 | 58 | if (RegStatus != ERROR_SUCCESS) { 59 | RegCloseKey(hInstancesKey); 60 | return FALSE; 61 | } 62 | } 63 | 64 | HKEY hInstanceKey = NULL; 65 | RegStatus = RegCreateKeyEx(hInstancesKey, InstanceName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hInstanceKey, &Disposition); 66 | if (RegStatus != ERROR_SUCCESS) { 67 | RegCloseKey(hInstancesKey); 68 | return FALSE; 69 | } 70 | RegCloseKey(hInstancesKey); 71 | 72 | RegStatus = RegSetValueEx( 73 | hInstanceKey, 74 | L"Altitude", 75 | 0, 76 | REG_SZ, 77 | reinterpret_cast(Altitude), 78 | (static_cast(wcsnlen_s(Altitude, MAX_PATH)) + 1) * sizeof(WCHAR) 79 | ); 80 | 81 | if (RegStatus != ERROR_SUCCESS) { 82 | RegCloseKey(hInstanceKey); 83 | return FALSE; 84 | } 85 | 86 | RegStatus = RegSetValueEx( 87 | hInstanceKey, 88 | L"Flags", 89 | 0, 90 | REG_DWORD, 91 | reinterpret_cast(&Flags), 92 | sizeof(Flags) 93 | ); 94 | 95 | RegCloseKey(hInstanceKey); 96 | 97 | return RegStatus == ERROR_SUCCESS; 98 | } 99 | 100 | BOOL InstallMinifilter(LPCWSTR FilePath, LPCWSTR DriverName, LPCWSTR Altitude) 101 | { 102 | SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE); 103 | 104 | if (hSCManager == NULL) return FALSE; 105 | 106 | SC_HANDLE hService = CreateService( 107 | hSCManager, DriverName, DriverName, 108 | SERVICE_ALL_ACCESS, SERVICE_FILE_SYSTEM_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, 109 | FilePath, 110 | L"FSFilter Activity Monitor", 111 | NULL, 112 | NULL, 113 | NULL, 114 | NULL 115 | ); 116 | 117 | CloseServiceHandle(hSCManager); 118 | 119 | if (hService == NULL) return FALSE; 120 | 121 | if (!SetupFilterInstance(DriverName, L"DefInst", Altitude, 0, TRUE)) { 122 | CloseServiceHandle(hService); 123 | return FALSE; 124 | } 125 | 126 | LPCWSTR Arguments = NULL; 127 | BOOL Status = StartService(hService, 0, &Arguments); 128 | 129 | CloseServiceHandle(hService); 130 | 131 | return Status; 132 | } 133 | 134 | BOOL DeleteDriver(LPCWSTR DriverName) 135 | { 136 | SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE); 137 | if (hSCManager == NULL) return FALSE; 138 | 139 | SC_HANDLE hService = OpenService(hSCManager, DriverName, SERVICE_ALL_ACCESS); 140 | if (hService == NULL) { 141 | CloseServiceHandle(hSCManager); 142 | return FALSE; 143 | } 144 | 145 | SERVICE_STATUS ServiceStatus; 146 | ControlService(hService, SERVICE_CONTROL_STOP, &ServiceStatus); 147 | BOOL Status = DeleteService(hService); 148 | 149 | CloseServiceHandle(hService); 150 | CloseServiceHandle(hSCManager); 151 | 152 | return Status; 153 | } 154 | 155 | HANDLE OpenDevice(LPCWSTR NativeDeviceName) 156 | { 157 | return CreateFile( 158 | NativeDeviceName, 159 | 0, 160 | FILE_SHARE_READ | FILE_SHARE_WRITE, 161 | NULL, 162 | OPEN_EXISTING, 163 | FILE_ATTRIBUTE_SYSTEM, 164 | NULL 165 | ); 166 | } 167 | 168 | BOOL SendIOCTL( 169 | IN HANDLE hDevice, 170 | IN DWORD Ioctl, 171 | IN PVOID InputBuffer, 172 | IN ULONG InputBufferSize, 173 | IN PVOID OutputBuffer, 174 | IN ULONG OutputBufferSize, 175 | OPTIONAL OUT PDWORD BytesReturned, 176 | OPTIONAL IN DWORD Method 177 | ) { 178 | DWORD RawIoctl = CTL_CODE(0x8000, Ioctl, Method, FILE_ANY_ACCESS); 179 | DWORD Returned = 0; 180 | BOOL Status = DeviceIoControl(hDevice, RawIoctl, InputBuffer, InputBufferSize, OutputBuffer, OutputBufferSize, &Returned, NULL); 181 | if (BytesReturned) *BytesReturned = Returned; 182 | return Status; 183 | } 184 | 185 | BOOL SendRawIOCTL( 186 | IN HANDLE hDevice, 187 | IN DWORD Ioctl, 188 | IN PVOID InputBuffer, 189 | IN ULONG InputBufferSize, 190 | IN PVOID OutputBuffer, 191 | IN ULONG OutputBufferSize, 192 | OPTIONAL OUT PDWORD BytesReturned 193 | ) { 194 | DWORD Returned = 0; 195 | BOOL Status = DeviceIoControl(hDevice, Ioctl, InputBuffer, InputBufferSize, OutputBuffer, OutputBufferSize, &Returned, NULL); 196 | if (BytesReturned) *BytesReturned = Returned; 197 | return Status; 198 | } 199 | -------------------------------------------------------------------------------- /Kernel-Bridge/API/VMM.asm: -------------------------------------------------------------------------------- 1 | .CODE 2 | 3 | EXTERN SvmVmexitHandler: PROC 4 | EXTERN VmxVmexitHandler: PROC 5 | 6 | ; Store LDTR: 7 | _sldt PROC PUBLIC 8 | sldt WORD PTR [rcx] 9 | ret 10 | _sldt ENDP 11 | 12 | ; Store TR: 13 | _str PROC PUBLIC 14 | str WORD PTR [rcx] 15 | ret 16 | _str ENDP 17 | 18 | __invd PROC PUBLIC 19 | invd 20 | ret 21 | __invd ENDP 22 | 23 | ; VMX-only: 24 | __hyperv_vmcall PROC PUBLIC 25 | ; RCX - HYPERCALL_INPUT_VALUE 26 | ; RDX - Input parameters GPA when the Fast flag is 0, otherwise input parameter 27 | ; R8 - Output parameters GPA when the Fast flag is 0, otherwise output parameter 28 | ; XMM0..XMM5 can be used in hypervisors with XMM Fast input support 29 | vmcall 30 | 31 | ; RAX - HYPERCALL_RESULT_VALUE 32 | ret 33 | __hyperv_vmcall ENDP 34 | 35 | ; VMX-only: 36 | __kb_vmcall PROC PUBLIC 37 | ; RCX, RDX, R8, R9 - args 38 | ; RAX - result 39 | push r10 40 | mov r10, 01EE7C0DEh 41 | vmcall 42 | pop r10 43 | ret 44 | __kb_vmcall ENDP 45 | 46 | GPR_CONTEXT_ENTRIES equ 15 ; rax, rbx, rcx, rdx, rsi, rdi, rbp, r8..r15 47 | GPR_CONTEXT_SIZE equ GPR_CONTEXT_ENTRIES * sizeof(QWORD) 48 | XMM_CONTEXT_ENTRIES equ 6 ; xmm0..xmm5 49 | XMM_CONTEXT_SIZE equ XMM_CONTEXT_ENTRIES * sizeof(OWORD) 50 | 51 | CPUID_VMM_SHUTDOWN equ 01EE7C0DEh 52 | 53 | ; Without RSP saving: 54 | PUSHAQ MACRO 55 | sub rsp, GPR_CONTEXT_SIZE 56 | mov [rsp + 0 * sizeof(QWORD)], rax 57 | mov [rsp + 1 * sizeof(QWORD)], rbx 58 | mov [rsp + 2 * sizeof(QWORD)], rcx 59 | mov [rsp + 3 * sizeof(QWORD)], rdx 60 | mov [rsp + 4 * sizeof(QWORD)], rsi 61 | mov [rsp + 5 * sizeof(QWORD)], rdi 62 | mov [rsp + 6 * sizeof(QWORD)], rbp 63 | mov [rsp + 7 * sizeof(QWORD)], r8 64 | mov [rsp + 8 * sizeof(QWORD)], r9 65 | mov [rsp + 9 * sizeof(QWORD)], r10 66 | mov [rsp + 10 * sizeof(QWORD)], r11 67 | mov [rsp + 11 * sizeof(QWORD)], r12 68 | mov [rsp + 12 * sizeof(QWORD)], r13 69 | mov [rsp + 13 * sizeof(QWORD)], r14 70 | mov [rsp + 14 * sizeof(QWORD)], r15 71 | ENDM 72 | 73 | ; Without RSP restoring: 74 | POPAQ MACRO 75 | mov rax, [rsp + 0 * sizeof(QWORD)] 76 | mov rbx, [rsp + 1 * sizeof(QWORD)] 77 | mov rcx, [rsp + 2 * sizeof(QWORD)] 78 | mov rdx, [rsp + 3 * sizeof(QWORD)] 79 | mov rsi, [rsp + 4 * sizeof(QWORD)] 80 | mov rdi, [rsp + 5 * sizeof(QWORD)] 81 | mov rbp, [rsp + 6 * sizeof(QWORD)] 82 | mov r8 , [rsp + 7 * sizeof(QWORD)] 83 | mov r9 , [rsp + 8 * sizeof(QWORD)] 84 | mov r10, [rsp + 9 * sizeof(QWORD)] 85 | mov r11, [rsp + 10 * sizeof(QWORD)] 86 | mov r12, [rsp + 11 * sizeof(QWORD)] 87 | mov r13, [rsp + 12 * sizeof(QWORD)] 88 | mov r14, [rsp + 13 * sizeof(QWORD)] 89 | mov r15, [rsp + 14 * sizeof(QWORD)] 90 | add rsp, GPR_CONTEXT_SIZE 91 | ENDM 92 | 93 | PUSHAXMM MACRO 94 | sub rsp, XMM_CONTEXT_SIZE 95 | movaps [rsp + 0 * sizeof(OWORD)], xmm0 96 | movaps [rsp + 1 * sizeof(OWORD)], xmm1 97 | movaps [rsp + 2 * sizeof(OWORD)], xmm2 98 | movaps [rsp + 3 * sizeof(OWORD)], xmm3 99 | movaps [rsp + 4 * sizeof(OWORD)], xmm4 100 | movaps [rsp + 5 * sizeof(OWORD)], xmm5 101 | ENDM 102 | 103 | POPAXMM MACRO 104 | movaps xmm0, [rsp + 0 * sizeof(OWORD)] 105 | movaps xmm1, [rsp + 1 * sizeof(OWORD)] 106 | movaps xmm2, [rsp + 2 * sizeof(OWORD)] 107 | movaps xmm3, [rsp + 3 * sizeof(OWORD)] 108 | movaps xmm4, [rsp + 4 * sizeof(OWORD)] 109 | movaps xmm5, [rsp + 5 * sizeof(OWORD)] 110 | add rsp, XMM_CONTEXT_SIZE 111 | ENDM 112 | 113 | PROLOGUE MACRO 114 | push rbp 115 | mov rbp, rsp 116 | sub rsp, 32 117 | mov [rsp + 0 * sizeof(QWORD)], rcx 118 | mov [rsp + 1 * sizeof(QWORD)], rdx 119 | mov [rsp + 2 * sizeof(QWORD)], r8 120 | mov [rsp + 3 * sizeof(QWORD)], r9 121 | ENDM 122 | 123 | EPILOGUE MACRO 124 | mov rcx, [rsp + 0 * sizeof(QWORD)] 125 | mov rdx, [rsp + 1 * sizeof(QWORD)] 126 | mov r8 , [rsp + 2 * sizeof(QWORD)] 127 | mov r9 , [rsp + 3 * sizeof(QWORD)] 128 | add rsp, 32 129 | pop rbp 130 | ret 131 | ENDM 132 | 133 | ; SvmVmmRun(INITIAL_VMM_STACK_LAYOUT* VmmStack): 134 | SvmVmmRun PROC PUBLIC 135 | ; RCX - VmmStack pointer 136 | mov rsp, rcx ; Switch to the VMM stack 137 | 138 | ; RSP -> INITIAL_VMM_STACK_LAYOUT: 139 | ; RSP + 0 -> PVOID GuestVmcbPa 140 | ; RSP + 8 -> PVOID HostVmcbPa 141 | ; RSP + 16 -> PRIVATE_VM_DATA* Private 142 | 143 | VmmLoop: 144 | mov rax, [rsp] ; RAX -> GuestVmcbPa 145 | 146 | vmload rax ; Load previously saved guest state 147 | vmrun rax 148 | 149 | ; Registers restored by the host's values: 150 | ; RAX, RSP, RIP 151 | ; GDTR, IDTR 152 | ; EFER 153 | ; CR0, CR3, CR4, DR7, CPL = 0 154 | ; ES.sel, CS.sel, SS.sel, DS.sel 155 | 156 | ; #VMEXIT occured, save the guest state to the guest VMCB: 157 | vmsave rax ; RAX was restored to host's state (RAX -> GuestVmcbPa) 158 | 159 | ; On #VMEXIT we have the guest context, so save it to the stack: 160 | PUSHAQ 161 | mov rcx, [rsp + GPR_CONTEXT_SIZE + 16] ; RCX -> PRIVATE_VM_DATA* Private 162 | mov rdx, rsp ; RDX -> Guest context 163 | 164 | PUSHAXMM 165 | sub rsp, 32 ; Homing space for the x64 call convention 166 | call SvmVmexitHandler ; VMM_STATUS SvmVmexitHandler(PRIVATE_VM_DATA* Private, GUEST_CONTEXT* Context) 167 | add rsp, 32 168 | POPAXMM 169 | 170 | test al, al ; if (!SvmVmexitHandler(...)) break; 171 | jz VmmExit 172 | 173 | POPAQ 174 | jmp VmmLoop 175 | 176 | VmmExit: 177 | POPAQ 178 | 179 | ; Exiting the virtual state: 180 | ; This context is setted up in the SvmVmexitHandler: 181 | ; RBX -> Guest's RIP 182 | ; RCX -> Guest's RSP 183 | ; EDX:EAX -> Address of the PRIVATE_VM_DATA to free 184 | 185 | mov rsp, rcx 186 | mov ecx, CPUID_VMM_SHUTDOWN ; Signature that says about the VM shutdown 187 | jmp rbx 188 | SvmVmmRun ENDP 189 | 190 | 191 | __invept PROC PUBLIC 192 | ; RCX - INVEPT_TYPE 193 | ; RDX - INVEPT_DESCRIPTOR 194 | invept rcx, OWORD PTR [rdx] 195 | ret 196 | __invept ENDP 197 | 198 | __invvpid PROC PUBLIC 199 | ; RCX - INVVPID_TYPE 200 | ; RDX - INVVPID_DESCRIPTOR 201 | invvpid rcx, OWORD PTR [rdx] 202 | ret 203 | __invvpid ENDP 204 | 205 | VmxVmmRun PROC PUBLIC 206 | PUSHAQ 207 | mov rcx, [rsp + GPR_CONTEXT_SIZE + 16] 208 | mov rdx, rsp 209 | 210 | PUSHAXMM 211 | sub rsp, 32 ; Homing space for the x64 call convention 212 | call VmxVmexitHandler ; VMM_STATUS VmxVmexitHandler(PRIVATE_VM_DATA* Private, GUEST_CONTEXT* Context) 213 | add rsp, 32 214 | POPAXMM 215 | 216 | test al, al ; if (!SvmVmexitHandler(...)) break; 217 | jz VmmExit 218 | 219 | POPAQ 220 | vmresume 221 | 222 | VmmExit: 223 | POPAQ 224 | 225 | ; Exiting the virtual state: 226 | ; This context is setted up in the SvmVmexitHandler: 227 | ; RBX -> Guest's RIP 228 | ; RCX -> Guest's RSP 229 | ; EDX:EAX -> Address of the PRIVATE_VM_DATA to free 230 | 231 | mov rsp, rcx 232 | mov ecx, CPUID_VMM_SHUTDOWN ; Signature that says about the VM shutdown 233 | jmp rbx 234 | VmxVmmRun ENDP 235 | 236 | END -------------------------------------------------------------------------------- /Kernel-Toolkit/Kernel-Toolkit/MainWindow.cpp: -------------------------------------------------------------------------------- 1 | #include "MainWindow.h" 2 | #include "ui_MainWindow.h" 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow), objectsStorage() 9 | { 10 | ui->setupUi(this); 11 | BOOL Status = KbLoader::KbLoadAsFilter(L"C:\\Temp\\Kernel-Bridge\\Kernel-Bridge.sys", L"260000"); 12 | if (!Status) { 13 | QMessageBox msg; 14 | msg.critical(ui->MainForm, "Error!", "Unable to load driver!\r\nEnsure to run it as Administrator!"); 15 | } 16 | } 17 | 18 | MainWindow::~MainWindow() 19 | { 20 | KbLoader::KbUnload(); 21 | delete ui; 22 | } 23 | 24 | bool MainWindow::isHex(const QString& string) { 25 | return string.startsWith("0x") || string.startsWith("$"); 26 | } 27 | 28 | int MainWindow::getInt(const QString& string) { 29 | bool Status = false; 30 | return isHex(string) ? string.toInt(&Status, 16) : string.toInt(); 31 | } 32 | 33 | long long MainWindow::getInt64(const QString& string) { 34 | bool Status = false; 35 | return isHex(string) ? string.toLongLong(&Status, 16) : string.toLongLong(); 36 | } 37 | 38 | unsigned int MainWindow::getUInt(const QString& string) { 39 | bool Status = false; 40 | return isHex(string) ? string.toUInt(&Status, 16) : string.toUInt(); 41 | } 42 | 43 | unsigned long long MainWindow::getUInt64(const QString& string) { 44 | bool Status = false; 45 | return isHex(string) ? string.toULongLong(&Status, 16) : string.toULongLong(); 46 | } 47 | 48 | void MainWindow::on_EnableBeeperButton_clicked() 49 | { 50 | static BOOL Enabled = FALSE; 51 | Enabled = !Enabled; 52 | 53 | if (Enabled) { 54 | IO::Beeper::KbSetBeeperRegime(); 55 | unsigned short Frequency = ui->FreqEdit->text().toUShort(); 56 | if (Frequency <= 0) Frequency = 1; 57 | if (Frequency > 20000) Frequency = 20000; 58 | IO::Beeper::KbSetBeeperFrequency(Frequency); 59 | IO::Beeper::KbStartBeeper(); 60 | ui->EnableBeeperButton->setText("Disable beeper"); 61 | } else { 62 | IO::Beeper::KbStopBeeper(); 63 | ui->EnableBeeperButton->setText("Enable beeper"); 64 | } 65 | } 66 | 67 | void MainWindow::on_FreqSlider_valueChanged(int value) 68 | { 69 | ui->FreqEdit->setText(QString::number(value)); 70 | ui->FreqEdit->editingFinished(); 71 | } 72 | 73 | void MainWindow::on_FreqEdit_editingFinished() 74 | { 75 | unsigned short Frequency = ui->FreqEdit->text().toUShort(); 76 | if (Frequency <= 0) Frequency = 1; 77 | if (Frequency > 20000) Frequency = 20000; 78 | ui->FreqEdit->setText(QString::number(Frequency)); 79 | IO::Beeper::KbSetBeeperFrequency(Frequency); 80 | } 81 | 82 | void MainWindow::on_ReadPortButton_clicked() 83 | { 84 | unsigned int Value = 0; 85 | unsigned int PortNumber = getUInt(ui->PortNumberEdit->text()); 86 | 87 | if (PortNumber > 255) { 88 | QMessageBox msgBox; 89 | msgBox.critical(ui->MainForm, "Error!", "Port number must be in [0..255] interval!"); 90 | return; 91 | } 92 | 93 | unsigned char CheckedPortNumber = static_cast(PortNumber); 94 | 95 | BOOL Status = FALSE; 96 | if (ui->ByteRadioButton->isChecked()) { 97 | unsigned char CharValue = 0; 98 | Status = IO::RW::KbReadPortByte(CheckedPortNumber, &CharValue); 99 | Value = CharValue; 100 | } else if (ui->WordRadioButton->isChecked()) { 101 | unsigned short WordValue = 0; 102 | Status = IO::RW::KbReadPortWord(CheckedPortNumber, &WordValue); 103 | Value = WordValue; 104 | } else if (ui->DwordRadioButton->isChecked()) { 105 | unsigned long DwordValue = 0; 106 | Status = IO::RW::KbReadPortDword(CheckedPortNumber, &DwordValue); 107 | Value = DwordValue; 108 | } 109 | 110 | if (!Status) { 111 | QMessageBox msgBox; 112 | msgBox.critical(ui->MainForm, "Error!", "Error in read port!"); 113 | } 114 | 115 | ui->PortValueEdit->setText(QString::number(Value)); 116 | } 117 | 118 | void MainWindow::on_WritePortButton_clicked() 119 | { 120 | unsigned int Value = getUInt(ui->PortValueEdit->text()); 121 | unsigned int PortNumber = getUInt(ui->PortNumberEdit->text()); 122 | 123 | if (Value > 255 || PortNumber > 255) { 124 | QMessageBox msgBox; 125 | msgBox.critical(ui->MainForm, "Error!", "Port number and value must be in [0..255] interval!"); 126 | return; 127 | } 128 | 129 | unsigned char CheckedPortNumber = static_cast(PortNumber); 130 | 131 | BOOL Status = FALSE; 132 | if (ui->ByteRadioButton->isChecked()) { 133 | Status = IO::RW::KbWritePortByte(CheckedPortNumber, static_cast(Value)); 134 | } else if (ui->WordRadioButton->isChecked()) { 135 | Status = IO::RW::KbWritePortWord(CheckedPortNumber, static_cast(Value)); 136 | } else if (ui->DwordRadioButton->isChecked()) { 137 | Status = IO::RW::KbWritePortDword(CheckedPortNumber, static_cast(Value)); 138 | } 139 | 140 | if (!Status) { 141 | QMessageBox msgBox; 142 | msgBox.critical(ui->MainForm, "Error!", "Error in write port!"); 143 | } 144 | } 145 | 146 | void MainWindow::on_CliButton_clicked() 147 | { 148 | CPU::KbCli(); 149 | } 150 | 151 | void MainWindow::on_StiButton_clicked() 152 | { 153 | CPU::KbSti(); 154 | static int counter = 0; 155 | counter++; 156 | ui->FreqEdit->setText(QString::number(counter)); 157 | } 158 | 159 | void MainWindow::on_HltButton_clicked() 160 | { 161 | CPU::KbHlt(); 162 | } 163 | 164 | void MainWindow::on_RdmsrButton_clicked() 165 | { 166 | unsigned int MsrIndex = getUInt(ui->MsrPmcIndexEdit->text()); 167 | unsigned long long Value = 0; 168 | BOOL Status = FALSE; 169 | 170 | Status = CPU::KbReadMsr(MsrIndex, &Value); 171 | 172 | if (!Status) { 173 | QMessageBox msgBox; 174 | msgBox.critical(ui->MainForm, "Error!", "Error in read MSR!"); 175 | return; 176 | } 177 | 178 | ui->MsrPmcValueEdit->setText("0x" + QString::number(Value, 16).toUpper()); 179 | } 180 | 181 | void MainWindow::on_WrmsrButton_clicked() 182 | { 183 | unsigned int MsrIndex = getUInt(ui->MsrPmcIndexEdit->text()); 184 | unsigned long long Value = getUInt64(ui->MsrPmcValueEdit->text()); 185 | BOOL Status = FALSE; 186 | 187 | Status = CPU::KbWriteMsr(MsrIndex, Value); 188 | 189 | if (!Status) { 190 | QMessageBox msgBox; 191 | msgBox.critical(ui->MainForm, "Error!", "Error in write MSR!"); 192 | return; 193 | } 194 | } 195 | 196 | void MainWindow::on_RdpmcButton_clicked() 197 | { 198 | unsigned int PmcIndex = getUInt(ui->MsrPmcIndexEdit->text()); 199 | unsigned long long Value = 0; 200 | BOOL Status = FALSE; 201 | 202 | Status = CPU::KbReadPmc(PmcIndex, &Value); 203 | 204 | if (!Status) { 205 | QMessageBox msgBox; 206 | msgBox.critical(ui->MainForm, "Error!", "Error in read PMC!"); 207 | return; 208 | } 209 | 210 | ui->MsrPmcValueEdit->setText("0x" + QString::number(Value, 16).toUpper()); 211 | } 212 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Dd]ebugKernel/ 19 | [Rr]elease/ 20 | [Rr]eleaseKernel/ 21 | [Rr]eleases/ 22 | x64/ 23 | x86/ 24 | bld/ 25 | [Bb]in/ 26 | [Oo]bj/ 27 | [Ll]og/ 28 | 29 | # Visual Studio 2015/2017 cache/options directory 30 | .vs/ 31 | # Uncomment if you have tasks that create the project's static files in wwwroot 32 | #wwwroot/ 33 | 34 | # Visual Studio 2017 auto generated files 35 | Generated\ Files/ 36 | 37 | # MSTest test Results 38 | [Tt]est[Rr]esult*/ 39 | [Bb]uild[Ll]og.* 40 | 41 | # NUNIT 42 | *.VisualState.xml 43 | TestResult.xml 44 | 45 | # Build Results of an ATL Project 46 | [Dd]ebugPS/ 47 | [Rr]eleasePS/ 48 | dlldata.c 49 | 50 | # Benchmark Results 51 | BenchmarkDotNet.Artifacts/ 52 | 53 | # .NET Core 54 | project.lock.json 55 | project.fragment.lock.json 56 | artifacts/ 57 | **/Properties/launchSettings.json 58 | 59 | # StyleCop 60 | StyleCopReport.xml 61 | 62 | # Files built by Visual Studio 63 | *_i.c 64 | *_p.c 65 | *_i.h 66 | *.ilk 67 | *.meta 68 | *.obj 69 | *.iobj 70 | *.pch 71 | *.pdb 72 | *.ipdb 73 | *.pgc 74 | *.pgd 75 | *.rsp 76 | *.sbr 77 | *.tlb 78 | *.tli 79 | *.tlh 80 | *.tmp 81 | *.tmp_proj 82 | *.log 83 | *.vspscc 84 | *.vssscc 85 | .builds 86 | *.pidb 87 | *.svclog 88 | *.scc 89 | 90 | # Chutzpah Test files 91 | _Chutzpah* 92 | 93 | # Visual C++ cache files 94 | ipch/ 95 | *.aps 96 | *.ncb 97 | *.opendb 98 | *.opensdf 99 | *.sdf 100 | *.cachefile 101 | *.VC.db 102 | *.VC.VC.opendb 103 | 104 | # Visual Studio profiler 105 | *.psess 106 | *.vsp 107 | *.vspx 108 | *.sap 109 | 110 | # Visual Studio Trace Files 111 | *.e2e 112 | 113 | # TFS 2012 Local Workspace 114 | $tf/ 115 | 116 | # Guidance Automation Toolkit 117 | *.gpState 118 | 119 | # ReSharper is a .NET coding add-in 120 | _ReSharper*/ 121 | *.[Rr]e[Ss]harper 122 | *.DotSettings.user 123 | 124 | # JustCode is a .NET coding add-in 125 | .JustCode 126 | 127 | # TeamCity is a build add-in 128 | _TeamCity* 129 | 130 | # DotCover is a Code Coverage Tool 131 | *.dotCover 132 | 133 | # AxoCover is a Code Coverage Tool 134 | .axoCover/* 135 | !.axoCover/settings.json 136 | 137 | # Visual Studio code coverage results 138 | *.coverage 139 | *.coveragexml 140 | 141 | # NCrunch 142 | _NCrunch_* 143 | .*crunch*.local.xml 144 | nCrunchTemp_* 145 | 146 | # MightyMoose 147 | *.mm.* 148 | AutoTest.Net/ 149 | 150 | # Web workbench (sass) 151 | .sass-cache/ 152 | 153 | # Installshield output folder 154 | [Ee]xpress/ 155 | 156 | # DocProject is a documentation generator add-in 157 | DocProject/buildhelp/ 158 | DocProject/Help/*.HxT 159 | DocProject/Help/*.HxC 160 | DocProject/Help/*.hhc 161 | DocProject/Help/*.hhk 162 | DocProject/Help/*.hhp 163 | DocProject/Help/Html2 164 | DocProject/Help/html 165 | 166 | # Click-Once directory 167 | publish/ 168 | 169 | # Publish Web Output 170 | *.[Pp]ublish.xml 171 | *.azurePubxml 172 | # Note: Comment the next line if you want to checkin your web deploy settings, 173 | # but database connection strings (with potential passwords) will be unencrypted 174 | *.pubxml 175 | *.publishproj 176 | 177 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 178 | # checkin your Azure Web App publish settings, but sensitive information contained 179 | # in these scripts will be unencrypted 180 | PublishScripts/ 181 | 182 | # NuGet Packages 183 | *.nupkg 184 | # The packages folder can be ignored because of Package Restore 185 | **/[Pp]ackages/* 186 | # except build/, which is used as an MSBuild target. 187 | !**/[Pp]ackages/build/ 188 | # Uncomment if necessary however generally it will be regenerated when needed 189 | #!**/[Pp]ackages/repositories.config 190 | # NuGet v3's project.json files produces more ignorable files 191 | *.nuget.props 192 | *.nuget.targets 193 | 194 | # Microsoft Azure Build Output 195 | csx/ 196 | *.build.csdef 197 | 198 | # Microsoft Azure Emulator 199 | ecf/ 200 | rcf/ 201 | 202 | # Windows Store app package directories and files 203 | AppPackages/ 204 | BundleArtifacts/ 205 | Package.StoreAssociation.xml 206 | _pkginfo.txt 207 | *.appx 208 | 209 | # Visual Studio cache files 210 | # files ending in .cache can be ignored 211 | *.[Cc]ache 212 | # but keep track of directories ending in .cache 213 | !*.[Cc]ache/ 214 | 215 | # Others 216 | ClientBin/ 217 | ~$* 218 | *~ 219 | *.dbmdl 220 | *.dbproj.schemaview 221 | *.jfm 222 | *.pfx 223 | *.publishsettings 224 | orleans.codegen.cs 225 | 226 | # Including strong name files can present a security risk 227 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 228 | #*.snk 229 | 230 | # Since there are multiple workflows, uncomment next line to ignore bower_components 231 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 232 | #bower_components/ 233 | 234 | # RIA/Silverlight projects 235 | Generated_Code/ 236 | 237 | # Backup & report files from converting an old project file 238 | # to a newer Visual Studio version. Backup files are not needed, 239 | # because we have git ;-) 240 | _UpgradeReport_Files/ 241 | Backup*/ 242 | UpgradeLog*.XML 243 | UpgradeLog*.htm 244 | ServiceFabricBackup/ 245 | *.rptproj.bak 246 | 247 | # SQL Server files 248 | *.mdf 249 | *.ldf 250 | *.ndf 251 | 252 | # Business Intelligence projects 253 | *.rdl.data 254 | *.bim.layout 255 | *.bim_*.settings 256 | *.rptproj.rsuser 257 | 258 | # Microsoft Fakes 259 | FakesAssemblies/ 260 | 261 | # GhostDoc plugin setting file 262 | *.GhostDoc.xml 263 | 264 | # Node.js Tools for Visual Studio 265 | .ntvs_analysis.dat 266 | node_modules/ 267 | 268 | # Visual Studio 6 build log 269 | *.plg 270 | 271 | # Visual Studio 6 workspace options file 272 | *.opt 273 | 274 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 275 | *.vbw 276 | 277 | # Visual Studio LightSwitch build output 278 | **/*.HTMLClient/GeneratedArtifacts 279 | **/*.DesktopClient/GeneratedArtifacts 280 | **/*.DesktopClient/ModelManifest.xml 281 | **/*.Server/GeneratedArtifacts 282 | **/*.Server/ModelManifest.xml 283 | _Pvt_Extensions 284 | 285 | # Paket dependency manager 286 | .paket/paket.exe 287 | paket-files/ 288 | 289 | # FAKE - F# Make 290 | .fake/ 291 | 292 | # JetBrains Rider 293 | .idea/ 294 | *.sln.iml 295 | 296 | # CodeRush 297 | .cr/ 298 | 299 | # Python Tools for Visual Studio (PTVS) 300 | __pycache__/ 301 | *.pyc 302 | 303 | # Cake - Uncomment if you are using it 304 | # tools/** 305 | # !tools/packages.config 306 | 307 | # Tabs Studio 308 | *.tss 309 | 310 | # Telerik's JustMock configuration file 311 | *.jmconfig 312 | 313 | # BizTalk build output 314 | *.btp.cs 315 | *.btm.cs 316 | *.odx.cs 317 | *.xsd.cs 318 | 319 | # OpenCover UI analysis results 320 | OpenCover/ 321 | 322 | # Azure Stream Analytics local run output 323 | ASALocalRun/ 324 | 325 | # MSBuild Binary and Structured Log 326 | *.binlog 327 | 328 | # NVidia Nsight GPU debugger configuration file 329 | *.nvuser 330 | 331 | # MFractors (Xamarin productivity tool) working folder 332 | .mfractor/ 333 | Kernel-Bridge/setup.inf 334 | Kernel-Bridge/setup.rpt 335 | -------------------------------------------------------------------------------- /Kernel-Bridge/API/CppSupport.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | using _PVFV = void (__cdecl *)(void); // PVFV = Pointer to Void Func(Void) 6 | using _PIFV = int (__cdecl *)(void); // PIFV = Pointer to Int Func(Void) 7 | 8 | constexpr int max_destructors_count = 64; 9 | static _PVFV onexitarray[max_destructors_count] = {}; 10 | static _PVFV *onexitbegin = nullptr, *onexitend = nullptr; 11 | 12 | // C initializers: 13 | #pragma section(".CRT$XIA", long, read) 14 | __declspec(allocate(".CRT$XIA")) _PIFV __xi_a[] = { 0 }; 15 | #pragma section(".CRT$XIZ", long, read) 16 | __declspec(allocate(".CRT$XIZ")) _PIFV __xi_z[] = { 0 }; 17 | 18 | // C++ initializers: 19 | #pragma section(".CRT$XCA", long, read) 20 | __declspec(allocate(".CRT$XCA")) _PVFV __xc_a[] = { 0 }; 21 | #pragma section(".CRT$XCZ", long, read) 22 | __declspec(allocate(".CRT$XCZ")) _PVFV __xc_z[] = { 0 }; 23 | 24 | // C pre-terminators: 25 | #pragma section(".CRT$XPA", long, read) 26 | __declspec(allocate(".CRT$XPA")) _PVFV __xp_a[] = { 0 }; 27 | #pragma section(".CRT$XPZ", long, read) 28 | __declspec(allocate(".CRT$XPZ")) _PVFV __xp_z[] = { 0 }; 29 | 30 | // C terminators: 31 | #pragma section(".CRT$XTA", long, read) 32 | __declspec(allocate(".CRT$XTA")) _PVFV __xt_a[] = { 0 }; 33 | #pragma section(".CRT$XTZ", long, read) 34 | __declspec(allocate(".CRT$XTZ")) _PVFV __xt_z[] = { 0 }; 35 | 36 | #pragma data_seg() 37 | 38 | #pragma comment(linker, "/merge:.CRT=.rdata") 39 | 40 | extern "C" int _fltused = 0; 41 | 42 | extern "C" int __cdecl __init_on_exit_array() 43 | { 44 | onexitend = onexitbegin = onexitarray; 45 | *onexitbegin = 0; 46 | return 0; 47 | } 48 | 49 | extern "C" int __cdecl atexit(_PVFV fn) 50 | { 51 | // ToDo: replace with dynamically allocated list of destructors! 52 | if (onexitend > &onexitarray[max_destructors_count - 1]) 53 | return 1; // Not enough space 54 | *onexitend = fn; 55 | onexitend++; 56 | return 0; 57 | } 58 | 59 | int __cdecl _purecall() 60 | { 61 | // It's abnormal execution, so we should detect it: 62 | __debugbreak(); 63 | return 0; 64 | } 65 | 66 | static void execute_pvfv_array(_PVFV* begin, _PVFV* end) 67 | { 68 | _PVFV* fn = begin; 69 | while (fn != end) 70 | { 71 | if (*fn) (**fn)(); 72 | ++fn; 73 | } 74 | } 75 | 76 | static int execute_pifv_array(_PIFV* begin, _PIFV* end) 77 | { 78 | _PIFV* fn = begin; 79 | while (fn != end) 80 | { 81 | if (*fn) 82 | { 83 | int result = (**begin)(); 84 | if (result) return result; 85 | } 86 | ++fn; 87 | } 88 | return 0; 89 | } 90 | 91 | extern "C" int __crt_init() 92 | { 93 | __init_on_exit_array(); 94 | int result = execute_pifv_array(__xi_a, __xi_z); 95 | if (result) return result; 96 | execute_pvfv_array(__xc_a, __xc_z); 97 | return 0; 98 | } 99 | 100 | extern "C" void __crt_deinit() 101 | { 102 | if (onexitbegin) 103 | { 104 | while (--onexitend >= onexitbegin) 105 | { 106 | if (*onexitend != 0)(**onexitend)(); 107 | } 108 | } 109 | execute_pvfv_array(__xp_a, __xp_z); 110 | execute_pvfv_array(__xt_a, __xt_z); 111 | } 112 | 113 | constexpr unsigned long CrtPoolTag = 'TRC_'; 114 | 115 | void* __cdecl operator new(size_t Size) 116 | { 117 | void* Pointer = ExAllocatePoolWithTag(NonPagedPool, Size, CrtPoolTag); 118 | if (Pointer) RtlZeroMemory(Pointer, Size); 119 | return Pointer; 120 | } 121 | 122 | void* __cdecl operator new(size_t Size, POOL_TYPE PoolType) 123 | { 124 | void* Pointer = ExAllocatePoolWithTag(PoolType, Size, CrtPoolTag); 125 | if (Pointer) RtlZeroMemory(Pointer, Size); 126 | return Pointer; 127 | } 128 | 129 | void* __cdecl operator new[](size_t Size) 130 | { 131 | void* Pointer = ExAllocatePoolWithTag(NonPagedPool, Size, CrtPoolTag); 132 | if (Pointer) RtlZeroMemory(Pointer, Size); 133 | return Pointer; 134 | } 135 | 136 | void* __cdecl operator new[](size_t Size, POOL_TYPE PoolType) 137 | { 138 | void* Pointer = ExAllocatePoolWithTag(PoolType, Size, CrtPoolTag); 139 | if (Pointer) RtlZeroMemory(Pointer, Size); 140 | return Pointer; 141 | } 142 | 143 | void __cdecl operator delete(void* Pointer) 144 | { 145 | if (!Pointer) return; 146 | ExFreePoolWithTag(Pointer, CrtPoolTag); 147 | } 148 | 149 | void __cdecl operator delete(void* Pointer, size_t Size) 150 | { 151 | UNREFERENCED_PARAMETER(Size); 152 | if (!Pointer) return; 153 | ExFreePoolWithTag(Pointer, CrtPoolTag); 154 | } 155 | 156 | void __cdecl operator delete[](void* Pointer) 157 | { 158 | if (!Pointer) return; 159 | ExFreePoolWithTag(Pointer, CrtPoolTag); 160 | } 161 | 162 | void __cdecl operator delete[](void* Pointer, size_t Size) 163 | { 164 | UNREFERENCED_PARAMETER(Size); 165 | if (!Pointer) return; 166 | ExFreePoolWithTag(Pointer, CrtPoolTag); 167 | } 168 | 169 | 170 | [[noreturn]] 171 | static void RaiseException(ULONG BugCheckCode) 172 | { 173 | KdBreakPoint(); 174 | KeBugCheck(BugCheckCode); 175 | } 176 | 177 | [[noreturn]] 178 | void __cdecl _invalid_parameter_noinfo_noreturn() 179 | { 180 | RaiseException(DRIVER_INVALID_CRUNTIME_PARAMETER); 181 | } 182 | 183 | namespace std 184 | { 185 | [[noreturn]] 186 | void __cdecl _Xbad_alloc() 187 | { 188 | RaiseException(INSTALL_MORE_MEMORY); 189 | } 190 | 191 | [[noreturn]] 192 | void __cdecl _Xinvalid_argument(_In_z_ const char*) 193 | { 194 | RaiseException(DRIVER_INVALID_CRUNTIME_PARAMETER); 195 | } 196 | 197 | [[noreturn]] 198 | void __cdecl _Xlength_error(_In_z_ const char*) 199 | { 200 | RaiseException(KMODE_EXCEPTION_NOT_HANDLED); 201 | } 202 | 203 | [[noreturn]] 204 | void __cdecl _Xout_of_range(_In_z_ const char*) 205 | { 206 | RaiseException(DRIVER_OVERRAN_STACK_BUFFER); 207 | } 208 | 209 | [[noreturn]] 210 | void __cdecl _Xoverflow_error(_In_z_ const char*) 211 | { 212 | RaiseException(DRIVER_OVERRAN_STACK_BUFFER); 213 | } 214 | 215 | [[noreturn]] 216 | void __cdecl _Xruntime_error(_In_z_ const char*) 217 | { 218 | RaiseException(KMODE_EXCEPTION_NOT_HANDLED); 219 | } 220 | 221 | [[noreturn]] 222 | void __cdecl RaiseHandler(const std::exception&) 223 | { 224 | RaiseException(KMODE_EXCEPTION_NOT_HANDLED); 225 | } 226 | 227 | _Prhand _Raise_handler = &RaiseHandler; 228 | } 229 | 230 | [[noreturn]] 231 | void __cdecl _invoke_watson( 232 | wchar_t const* const expression, 233 | wchar_t const* const function_name, 234 | wchar_t const* const file_name, 235 | unsigned int const line_number, 236 | uintptr_t const reserved) 237 | { 238 | UNREFERENCED_PARAMETER(expression); 239 | UNREFERENCED_PARAMETER(function_name); 240 | UNREFERENCED_PARAMETER(file_name); 241 | UNREFERENCED_PARAMETER(line_number); 242 | UNREFERENCED_PARAMETER(reserved); 243 | 244 | KdBreakPoint(); 245 | RaiseException(KMODE_EXCEPTION_NOT_HANDLED); 246 | } 247 | 248 | // For and support: 249 | #ifdef _AMD64_ 250 | #pragma function(ceilf) 251 | _Check_return_ float __cdecl ceilf(_In_ float _X) 252 | { 253 | int v = static_cast(_X); 254 | return static_cast(_X > static_cast(v) ? v + 1 : v); 255 | } 256 | #else 257 | #pragma function(ceil) 258 | _Check_return_ double __cdecl ceil(_In_ double _X) 259 | { 260 | int v = static_cast(_X); 261 | return static_cast(_X > static_cast(v) ? v + 1 : v); 262 | } 263 | #endif -------------------------------------------------------------------------------- /Kernel-Bridge/Kernel-Bridge/LoadableModules.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "../API/Locks.h" 6 | #include "../API/StringsAPI.h" 7 | #include "../API/LinkedList.h" 8 | #include "../API/MemoryUtils.h" 9 | 10 | #include "LoadableModules.h" 11 | 12 | //#pragma section(".storage",execute,nopage) 13 | // 14 | //static constexpr unsigned int STORAGE_SIZE = 640 * 1024; 15 | //__declspec(allocate(".storage")) unsigned char Storage[STORAGE_SIZE] = {}; 16 | 17 | class ModulesStorage { 18 | private: 19 | using MODULE_INFO = struct { 20 | WideString ModuleName; 21 | PVOID hModule; 22 | OPTIONAL LoadableModules::_OnUnload OnUnload; 23 | OPTIONAL LoadableModules::_OnDeviceControl OnDeviceControl; 24 | Atomic32 Refcount; 25 | PRKEVENT CompletionEvent; 26 | volatile bool Unloading; 27 | }; 28 | 29 | FastMutex Lock; 30 | LinkedList Modules; 31 | 32 | public: 33 | ModulesStorage() : Lock(), Modules() {} 34 | ~ModulesStorage() { 35 | Lock.Lock(); 36 | if (Modules.IsEmpty()) { 37 | Lock.Unlock(); 38 | return; 39 | } 40 | 41 | LinkedList::ListIterator it = Modules.begin(); 42 | while (it != Modules.end()) { 43 | auto Entry = it.GetEntry(); 44 | ++it; 45 | auto Module = Entry->GetValue(); 46 | 47 | if (!Module->Unloading) { 48 | Module->Unloading = true; 49 | KeWaitForSingleObject(Module->CompletionEvent, Executive, KernelMode, FALSE, NULL); 50 | if (Module->OnUnload) Module->OnUnload(); 51 | VirtualMemory::FreePoolMemory(Module->hModule); 52 | Modules.Remove(Entry); 53 | } 54 | } 55 | Lock.Unlock(); 56 | } 57 | 58 | NTSTATUS Load( 59 | PVOID hModule, 60 | LPCWSTR ModuleName, 61 | OPTIONAL LoadableModules::_OnLoad OnLoad = NULL, 62 | OPTIONAL LoadableModules::_OnUnload OnUnload = NULL, 63 | OPTIONAL LoadableModules::_OnDeviceControl OnDeviceControl = NULL 64 | ) { 65 | if (!hModule || !ModuleName) return STATUS_INVALID_PARAMETER; 66 | 67 | WideString Name(ModuleName); 68 | Name.Trim().ToLowerCase(); 69 | if (!Name.GetLength()) return STATUS_INVALID_PARAMETER; 70 | 71 | BOOLEAN AlreadyLoaded = FALSE; 72 | Lock.Lock(); 73 | for (auto& Module : Modules) { 74 | AlreadyLoaded = Module.hModule == hModule || Module.ModuleName == Name; 75 | if (AlreadyLoaded) break; 76 | } 77 | Lock.Unlock(); 78 | 79 | if (AlreadyLoaded) 80 | return STATUS_ALREADY_COMPLETE; 81 | 82 | NTSTATUS Status = OnLoad ? OnLoad(hModule, ModuleName) : STATUS_SUCCESS; 83 | 84 | if (Status == STATUS_SUCCESS) { 85 | Lock.Lock(); 86 | MODULE_INFO Module = {}; 87 | Module.ModuleName = Name; 88 | Module.hModule = hModule; 89 | Module.OnUnload = OnUnload; 90 | Module.OnDeviceControl = OnDeviceControl; 91 | Module.CompletionEvent = new KEVENT; 92 | KeInitializeEvent(Module.CompletionEvent, NotificationEvent, TRUE); 93 | Modules.InsertTail(Module); 94 | Lock.Unlock(); 95 | } 96 | 97 | return Status; 98 | } 99 | 100 | NTSTATUS Call(PVOID hModule, ULONG CtlCode, OPTIONAL PVOID Argument = NULL) { 101 | if (!hModule) return STATUS_INVALID_PARAMETER; 102 | 103 | NTSTATUS Status = STATUS_NOT_FOUND; 104 | 105 | MODULE_INFO* TargetModule = NULL; 106 | 107 | Lock.Lock(); 108 | if (Modules.IsEmpty()) { 109 | Lock.Unlock(); 110 | return STATUS_NOT_FOUND; 111 | } 112 | 113 | for (auto& Module : Modules) { 114 | if (Module.hModule != hModule) continue; 115 | 116 | if (Module.Unloading) { 117 | Status = STATUS_NOT_FOUND; 118 | break; 119 | } 120 | 121 | if (!Module.OnDeviceControl) { 122 | Status = STATUS_NOT_IMPLEMENTED; 123 | break; 124 | } 125 | 126 | // Referencing module: 127 | if (Module.Refcount.Get() == 0) 128 | KeClearEvent(Module.CompletionEvent); 129 | Module.Refcount++; 130 | 131 | TargetModule = &Module; 132 | break; 133 | } 134 | Lock.Unlock(); 135 | 136 | if (!TargetModule) return Status; 137 | 138 | Status = TargetModule->OnDeviceControl(CtlCode, Argument); 139 | 140 | TargetModule->Refcount--; 141 | if (TargetModule->Refcount.Get() == 0) 142 | KeSetEvent(TargetModule->CompletionEvent, LOW_REALTIME_PRIORITY, FALSE); 143 | 144 | return Status; 145 | } 146 | 147 | NTSTATUS Unload(PVOID hModule) { 148 | if (!hModule) return STATUS_INVALID_PARAMETER; 149 | 150 | LinkedList::ListEntry* TargetEntry = NULL; 151 | 152 | Lock.Lock(); 153 | if (Modules.IsEmpty()) { 154 | Lock.Unlock(); 155 | return STATUS_NOT_FOUND; 156 | } 157 | 158 | LinkedList::ListIterator it = Modules.begin(); 159 | while (it != Modules.end()) { 160 | auto Entry = it.GetEntry(); 161 | ++it; 162 | auto Module = Entry->GetValue(); 163 | 164 | if (Module->hModule != hModule) continue; 165 | if (Module->Unloading) break; 166 | 167 | Module->Unloading = true; 168 | TargetEntry = Entry; 169 | break; 170 | } 171 | Lock.Unlock(); 172 | 173 | if (!TargetEntry) return STATUS_NOT_FOUND; 174 | 175 | MODULE_INFO* TargetModule = TargetEntry->GetValue(); 176 | 177 | KeWaitForSingleObject(TargetModule->CompletionEvent, Executive, KernelMode, FALSE, NULL); 178 | if (TargetModule->OnUnload) TargetModule->OnUnload(); 179 | 180 | Lock.Lock(); 181 | Modules.Remove(TargetEntry); 182 | delete TargetModule->CompletionEvent; 183 | Lock.Unlock(); 184 | 185 | VirtualMemory::FreePoolMemory(hModule); 186 | return STATUS_SUCCESS; 187 | } 188 | 189 | PVOID GetModuleHandle(LPCWSTR ModuleName) { 190 | WideString Name(ModuleName); 191 | Name.Trim().ToLowerCase(); 192 | if (!Name.GetLength()) return NULL; 193 | 194 | PVOID hModule = NULL; 195 | Lock.Lock(); 196 | for (auto& Module : Modules) { 197 | if (Module.ModuleName == Name) hModule = Module.hModule; 198 | if (hModule) break; 199 | } 200 | Lock.Unlock(); 201 | return hModule; 202 | } 203 | }; 204 | 205 | namespace LoadableModules { 206 | static ModulesStorage Modules; 207 | 208 | NTSTATUS LoadModule( 209 | PVOID hModule, 210 | LPCWSTR ModuleName, 211 | OPTIONAL _OnLoad OnLoad, 212 | OPTIONAL _OnUnload OnUnload, 213 | OPTIONAL _OnDeviceControl OnDeviceControl 214 | ) { 215 | return Modules.Load(hModule, ModuleName, OnLoad, OnUnload, OnDeviceControl); 216 | } 217 | 218 | NTSTATUS CallModule(PVOID hModule, ULONG CtlCode, OPTIONAL PVOID Argument) { 219 | return Modules.Call(hModule, CtlCode, Argument); 220 | } 221 | 222 | NTSTATUS UnloadModule(PVOID hModule) { 223 | return Modules.Unload(hModule); 224 | } 225 | 226 | PVOID GetModuleHandle(LPCWSTR ModuleName) { 227 | return Modules.GetModuleHandle(ModuleName); 228 | } 229 | } -------------------------------------------------------------------------------- /User-Bridge/API/Rtl-Bridge.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // User-Bridge types: 4 | #include 5 | #include 6 | #include 7 | #include "Rtl-Bridge.h" 8 | 9 | // PEUtils modules: 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | namespace KbRtl { 16 | 17 | static PVOID GetKernelProcAddress(LPCSTR FunctionName) 18 | { 19 | // Converting ANSI-name to Unicode-name: 20 | ULONG SymbolsCount = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, FunctionName, -1, NULL, 0); 21 | std::wstring WideName(SymbolsCount, static_cast(0x0000)); 22 | MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, FunctionName, -1, const_cast(WideName.c_str()), SymbolsCount - 1); 23 | 24 | // Getting the actual kernel address: 25 | WdkTypes::PVOID KernelAddress = NULL; 26 | BOOL Status = Stuff::KbGetKernelProcAddress(WideName.c_str(), &KernelAddress); 27 | return Status ? reinterpret_cast(KernelAddress) : NULL; 28 | } 29 | 30 | class FileReader { 31 | private: 32 | PVOID Memory; 33 | ULONG Size; 34 | public: 35 | FileReader() : Memory(NULL) { 36 | 37 | } 38 | ~FileReader() { 39 | Free(); 40 | } 41 | 42 | BOOL Load(LPCWSTR Path) { 43 | HANDLE hFile = CreateFile(Path, FILE_READ_ACCESS, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 44 | if (hFile == INVALID_HANDLE_VALUE) return FALSE; 45 | 46 | Size = GetFileSize(hFile, NULL); 47 | if (!Size) { 48 | CloseHandle(hFile); 49 | return FALSE; 50 | } 51 | 52 | Memory = VirtualAlloc(NULL, Size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); 53 | ULONG BytesRead = 0; 54 | if (!Memory || !ReadFile(hFile, Memory, Size, &BytesRead, NULL) || BytesRead != Size) { 55 | if (Memory) VirtualFree(Memory, 0, MEM_RELEASE); 56 | CloseHandle(hFile); 57 | Memory = NULL; 58 | Size = 0; 59 | return FALSE; 60 | } 61 | 62 | CloseHandle(hFile); 63 | return TRUE; 64 | } 65 | 66 | VOID Free() { 67 | if (Memory) VirtualFree(Memory, 0, MEM_RELEASE); 68 | Memory = NULL; 69 | Size = 0; 70 | } 71 | 72 | PVOID GetMemory() { return Memory; } 73 | ULONG GetSize() const { return Size; } 74 | }; 75 | 76 | KbLdrStatus WINAPI KbRtlMapDriverMemory(PVOID DriverImage, LPCWSTR DriverName) 77 | { 78 | try { 79 | PELoader Loader( 80 | static_cast(DriverImage), 81 | [](LPCSTR LibName, LPCSTR FunctionName) -> PVOID { 82 | PVOID Address = GetKernelProcAddress(FunctionName); 83 | if (!Address) throw KbLdrImportNotResolved; 84 | return Address; 85 | }, 86 | [](LPCSTR LibName, WORD Ordinal) -> PVOID { 87 | throw KbLdrOrdinalImportNotSupported; 88 | } 89 | ); 90 | 91 | WdkTypes::PVOID KImageAddress = NULL; 92 | BOOL Status = VirtualMemory::KbAllocKernelMemory(Loader.getDeployedSize(), TRUE, &KImageAddress); 93 | if (!Status) throw KbLdrKernelMemoryNotAllocated; 94 | 95 | Loader.relocate(reinterpret_cast(KImageAddress)); 96 | 97 | Status = VirtualMemory::KbCopyMoveMemory( 98 | KImageAddress, 99 | reinterpret_cast(Loader.get()), 100 | Loader.getDeployedSize(), 101 | FALSE 102 | ); 103 | 104 | if (!Status) { 105 | VirtualMemory::KbFreeKernelMemory(KImageAddress); 106 | return KbLdrTransitionFailure; 107 | } 108 | 109 | return LoadableModules::KbCreateDriver( 110 | DriverName, 111 | reinterpret_cast( 112 | Loader.getBaseRelativeEntryPoint(reinterpret_cast(KImageAddress)) 113 | ) 114 | ) ? KbLdrSuccess : KbLdrCreationFailure; 115 | } 116 | catch (KbLdrStatus Status) { 117 | return Status; 118 | } 119 | } 120 | 121 | KbLdrStatus WINAPI KbRtlMapDriverFile(LPCWSTR DriverPath, LPCWSTR DriverName) 122 | { 123 | FileReader Reader; 124 | if (!Reader.Load(DriverPath)) return KbLdrCreationFailure; 125 | return KbRtlMapDriverMemory(Reader.GetMemory(), DriverName); 126 | } 127 | 128 | KbLdrStatus WINAPI KbRtlLoadModuleMemory(PVOID DriverImage, LPCWSTR ModuleName, OUT WdkTypes::HMODULE* ImageBase) 129 | { 130 | try { 131 | PELoader Loader( 132 | static_cast(DriverImage), 133 | [](LPCSTR LibName, LPCSTR FunctionName) -> PVOID { 134 | PVOID Address = GetKernelProcAddress(FunctionName); 135 | if (!Address) throw KbLdrImportNotResolved; 136 | return Address; 137 | }, 138 | [](LPCSTR LibName, WORD Ordinal) -> PVOID { 139 | throw KbLdrOrdinalImportNotSupported; 140 | } 141 | ); 142 | 143 | PEAnalyzer Module(Loader.get(), FALSE); 144 | 145 | WdkTypes::HMODULE hModule = NULL; 146 | BOOL Status = VirtualMemory::KbAllocKernelMemory(Loader.getDeployedSize(), TRUE, &hModule); 147 | if (!Status) throw KbLdrKernelMemoryNotAllocated; 148 | 149 | Loader.relocate(reinterpret_cast(hModule)); 150 | 151 | Status = VirtualMemory::KbCopyMoveMemory( 152 | hModule, 153 | reinterpret_cast(Loader.get()), 154 | Loader.getDeployedSize(), 155 | FALSE 156 | ); 157 | 158 | if (!Status) { 159 | VirtualMemory::KbFreeKernelMemory(hModule); 160 | return KbLdrTransitionFailure; 161 | } 162 | 163 | WdkTypes::PVOID ModuleBase = reinterpret_cast(Module.getImageBase()); 164 | WdkTypes::PVOID OnLoad = NULL, OnUnload = NULL, OnDeviceControl = NULL; 165 | const auto& Exports = Module.getExportsInfo(); 166 | for (const auto& Export : Exports.exports) { 167 | WdkTypes::PVOID VA = hModule + static_cast(Export.rva); 168 | if (Export.name == "OnLoad") { 169 | OnLoad = VA; 170 | } else if (Export.name == "OnUnload") { 171 | OnUnload = VA; 172 | } else if (Export.name == "OnDeviceControl") { 173 | OnDeviceControl = VA; 174 | } 175 | } 176 | 177 | Status = LoadableModules::KbLoadModule( 178 | hModule, 179 | ModuleName, 180 | OnLoad, 181 | OnUnload, 182 | OnDeviceControl 183 | ); 184 | 185 | if (!Status) { 186 | VirtualMemory::KbFreeKernelMemory(hModule); 187 | return KbLdrCreationFailure; 188 | } 189 | 190 | *ImageBase = hModule; 191 | return KbLdrSuccess; 192 | } 193 | catch (KbLdrStatus Status) { 194 | return Status; 195 | } 196 | } 197 | 198 | KbLdrStatus WINAPI KbRtlLoadModuleFile(LPCWSTR ModulePath, LPCWSTR ModuleName, OUT WdkTypes::HMODULE* hModule) 199 | { 200 | FileReader Reader; 201 | if (!Reader.Load(ModulePath)) return KbLdrCreationFailure; 202 | return KbRtlLoadModuleMemory(Reader.GetMemory(), ModuleName, hModule); 203 | } 204 | } -------------------------------------------------------------------------------- /LoadableModule/LoadableModule.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {E52B479E-B60F-4254-98BA-31A18C4B1F70} 23 | {dd38f7fc-d7bd-488b-9242-7d8754cde80d} 24 | v4.5 25 | 12.0 26 | Debug 27 | Win32 28 | LoadableModule 29 | 10.0.19041.0 30 | LoadableModule 31 | 32 | 33 | 34 | Windows7 35 | true 36 | WindowsKernelModeDriver10.0 37 | WDM 38 | Desktop 39 | <_NT_TARGET_VERSION>0x0601 40 | false 41 | false 42 | Driver 43 | 44 | 45 | Windows7 46 | false 47 | WindowsKernelModeDriver10.0 48 | WDM 49 | Desktop 50 | <_NT_TARGET_VERSION>0x0601 51 | false 52 | false 53 | Driver 54 | 55 | 56 | Windows7 57 | true 58 | WindowsKernelModeDriver10.0 59 | WDM 60 | Desktop 61 | <_NT_TARGET_VERSION>0x0601 62 | false 63 | false 64 | Driver 65 | 66 | 67 | Windows7 68 | false 69 | WindowsKernelModeDriver10.0 70 | WDM 71 | Desktop 72 | <_NT_TARGET_VERSION>0x0601 73 | false 74 | false 75 | Driver 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | DbgengKernelDebugger 87 | false 88 | 89 | 90 | DbgengKernelDebugger 91 | false 92 | 93 | 94 | DbgengKernelDebugger 95 | false 96 | 97 | 98 | DbgengKernelDebugger 99 | false 100 | 101 | 102 | 103 | GsDriverEntry@8 104 | 105 | 106 | 107 | 108 | Exports.def 109 | 110 | 111 | 112 | stdcpplatest 113 | 114 | 115 | 116 | 117 | GsDriverEntry@8 118 | 119 | 120 | 121 | 122 | Exports.def 123 | 124 | 125 | 126 | stdcpplatest 127 | 128 | 129 | 130 | 131 | GsDriverEntry 132 | 133 | 134 | 135 | 136 | Exports.def 137 | 138 | 139 | 140 | stdcpplatest 141 | 142 | 143 | 144 | 145 | GsDriverEntry 146 | 147 | 148 | 149 | 150 | Exports.def 151 | 152 | 153 | 154 | stdcpplatest 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | -------------------------------------------------------------------------------- /Kernel-Bridge/Kernel-Bridge.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {b5d010f1-cdbf-4439-bcf3-8d6e1cd4b642} 6 | 7 | 8 | {8E41214B-6785-4CFE-B992-037D68949A14} 9 | inf;inv;inx;mof;mc; 10 | 11 | 12 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 13 | h;hpp;hxx;hm;inl;inc;xsd 14 | 15 | 16 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 17 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 18 | 19 | 20 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 21 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 22 | 23 | 24 | {0a643a2f-5347-4505-81cf-4a8180227028} 25 | 26 | 27 | {54118567-cea9-4a10-9867-9e055b1c1cb4} 28 | 29 | 30 | {d3a9dfce-6a9f-4eef-a3ea-0a30ace51980} 31 | 32 | 33 | {1540d3f3-c5f5-44c0-a3bb-2246da568195} 34 | 35 | 36 | {1d6d5ce4-f4f5-467c-ab9f-d21fbbac9bcd} 37 | 38 | 39 | 40 | 41 | Main\Driver Files 42 | 43 | 44 | 45 | 46 | Main\Resource Files 47 | 48 | 49 | 50 | 51 | Main\Source Files 52 | 53 | 54 | Kernel-Bridge 55 | 56 | 57 | API 58 | 59 | 60 | API 61 | 62 | 63 | API 64 | 65 | 66 | API 67 | 68 | 69 | API 70 | 71 | 72 | API 73 | 74 | 75 | Kernel-Bridge 76 | 77 | 78 | API 79 | 80 | 81 | API 82 | 83 | 84 | Kernel-Bridge 85 | 86 | 87 | API 88 | 89 | 90 | API 91 | 92 | 93 | API 94 | 95 | 96 | Kernel-Bridge 97 | 98 | 99 | API 100 | 101 | 102 | API 103 | 104 | 105 | API 106 | 107 | 108 | API 109 | 110 | 111 | API 112 | 113 | 114 | API 115 | 116 | 117 | 118 | 119 | Kernel-Bridge 120 | 121 | 122 | Kernel-Bridge 123 | 124 | 125 | API 126 | 127 | 128 | API 129 | 130 | 131 | API 132 | 133 | 134 | API 135 | 136 | 137 | API 138 | 139 | 140 | API 141 | 142 | 143 | API 144 | 145 | 146 | API 147 | 148 | 149 | Kernel-Bridge 150 | 151 | 152 | SharedTypes 153 | 154 | 155 | API 156 | 157 | 158 | API 159 | 160 | 161 | API 162 | 163 | 164 | Kernel-Bridge 165 | 166 | 167 | API 168 | 169 | 170 | SharedTypes 171 | 172 | 173 | SharedTypes 174 | 175 | 176 | API 177 | 178 | 179 | API 180 | 181 | 182 | API 183 | 184 | 185 | Kernel-Bridge 186 | 187 | 188 | API 189 | 190 | 191 | API 192 | 193 | 194 | API 195 | 196 | 197 | CommonTypes 198 | 199 | 200 | CommonTypes 201 | 202 | 203 | API 204 | 205 | 206 | CommonTypes 207 | 208 | 209 | CommonTypes 210 | 211 | 212 | CommonTypes 213 | 214 | 215 | CommonTypes 216 | 217 | 218 | CommonTypes 219 | 220 | 221 | CommonTypes 222 | 223 | 224 | CommonTypes 225 | 226 | 227 | API 228 | 229 | 230 | HookLib 231 | 232 | 233 | API 234 | 235 | 236 | 237 | 238 | Main 239 | 240 | 241 | 242 | 243 | API 244 | 245 | 246 | -------------------------------------------------------------------------------- /Kernel-Bridge/API/ProcessesUtils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace Processes { 4 | namespace Descriptors { 5 | // Queried PEPROCESS must be dereferenced by ObDereferenceObject: 6 | _IRQL_requires_max_(APC_LEVEL) 7 | PEPROCESS GetEPROCESS(HANDLE ProcessId); 8 | 9 | // Queried PETHREAD must be dereferenced by ObDereferenceObject: 10 | _IRQL_requires_max_(APC_LEVEL) 11 | PETHREAD GetETHREAD(HANDLE ThreadId); 12 | 13 | // Queried hProcess must be closed by ZwClose: 14 | _IRQL_requires_max_(PASSIVE_LEVEL) 15 | NTSTATUS OpenProcess( 16 | HANDLE ProcessId, 17 | OUT PHANDLE hProcess, 18 | ACCESS_MASK AccessMask = PROCESS_ALL_ACCESS, 19 | ULONG Attributes = OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE 20 | ); 21 | 22 | _IRQL_requires_max_(PASSIVE_LEVEL) 23 | NTSTATUS OpenProcessByPointer( 24 | PEPROCESS Process, 25 | OUT PHANDLE hProcess, 26 | ACCESS_MASK AccessMask = PROCESS_ALL_ACCESS, 27 | ULONG Attributes = OBJ_KERNEL_HANDLE, 28 | KPROCESSOR_MODE ProcessorMode = KernelMode 29 | ); 30 | 31 | // Queried hThread must be closed by ZwClose: 32 | _IRQL_requires_max_(PASSIVE_LEVEL) 33 | NTSTATUS OpenThread( 34 | HANDLE ThreadId, 35 | OUT PHANDLE hThread, 36 | ACCESS_MASK AccessMask = THREAD_ALL_ACCESS, 37 | ULONG Attributes = OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE 38 | ); 39 | 40 | _IRQL_requires_max_(PASSIVE_LEVEL) 41 | NTSTATUS OpenThreadByPointer( 42 | PETHREAD Thread, 43 | OUT PHANDLE hThread, 44 | ACCESS_MASK AccessMask = THREAD_ALL_ACCESS, 45 | ULONG Attributes = OBJ_KERNEL_HANDLE, 46 | KPROCESSOR_MODE ProcessorMode = KernelMode 47 | ); 48 | 49 | // It doesn't requires dereference! 50 | inline PEPROCESS ThreadToProcess(PETHREAD Thread) { return IoThreadToProcess(Thread); }; 51 | } 52 | 53 | namespace AddressSpace { 54 | // These functions switches your thread's address space 55 | // to address space of target process, so you can 56 | // access usermode memory of another process you want. 57 | 58 | // !!! NOTICE !!! 59 | // After switching of address space your own usermode memory 60 | // and usermode handles becomes INVALID in context of another process! 61 | 62 | _IRQL_requires_max_(APC_LEVEL) 63 | BOOLEAN AttachToProcessByPid(HANDLE ProcessId, OUT PKAPC_STATE ApcState); 64 | 65 | _IRQL_requires_max_(APC_LEVEL) 66 | BOOLEAN AttachToProcess(PEPROCESS Process, OUT PKAPC_STATE ApcState); 67 | 68 | _IRQL_requires_max_(APC_LEVEL) 69 | VOID DetachFromProcess(IN PKAPC_STATE ApcState); 70 | } 71 | 72 | namespace Terminator { 73 | _IRQL_requires_max_(PASSIVE_LEVEL) 74 | NTSTATUS TerminateProcessByPid(HANDLE ProcessId, NTSTATUS ExitStatus); 75 | 76 | _IRQL_requires_max_(PASSIVE_LEVEL) 77 | NTSTATUS TerminateProcess(HANDLE hProcess, NTSTATUS ExitStatus); 78 | } 79 | 80 | namespace Threads { 81 | _IRQL_requires_max_(APC_LEVEL) 82 | NTSTATUS GetContextThread( 83 | IN PETHREAD Thread, 84 | OUT PCONTEXT Context, 85 | IN KPROCESSOR_MODE PreviousMode 86 | ); 87 | 88 | _IRQL_requires_max_(APC_LEVEL) 89 | NTSTATUS SetContextThread( 90 | IN PETHREAD Thread, 91 | IN PCONTEXT Context, 92 | IN KPROCESSOR_MODE PreviousMode 93 | ); 94 | 95 | _IRQL_requires_max_(APC_LEVEL) 96 | NTSTATUS SuspendProcess(IN PEPROCESS Process); 97 | 98 | _IRQL_requires_max_(APC_LEVEL) 99 | NTSTATUS ResumeProcess(IN PEPROCESS Process); 100 | 101 | using _UserThreadRoutine = NTSTATUS (NTAPI*)(PVOID Argument); 102 | 103 | _IRQL_requires_max_(PASSIVE_LEVEL) 104 | NTSTATUS CreateUserThread( 105 | HANDLE hProcess, 106 | IN _UserThreadRoutine StartAddress, 107 | IN PVOID Argument, 108 | BOOLEAN CreateSuspended, 109 | OUT PHANDLE hThread, 110 | OUT PCLIENT_ID ClientId 111 | ); 112 | 113 | _IRQL_requires_max_(PASSIVE_LEVEL) 114 | NTSTATUS CreateSystemThread( 115 | OPTIONAL HANDLE hProcess, 116 | PKSTART_ROUTINE StartAddress, 117 | PVOID Argument, 118 | OUT PHANDLE hThread, 119 | OUT PCLIENT_ID ClientId 120 | ); 121 | 122 | _IRQL_requires_max_(PASSIVE_LEVEL) 123 | NTSTATUS CreateSystemThread( 124 | PKSTART_ROUTINE StartAddress, 125 | PVOID Argument, 126 | OUT PHANDLE hThread 127 | ); 128 | 129 | _IRQL_requires_max_(PASSIVE_LEVEL) 130 | NTSTATUS QueryInformationThread( 131 | HANDLE hThread, 132 | THREADINFOCLASS ThreadInformationClass, 133 | OUT PVOID ThreadInformation, 134 | ULONG ThreadInformationLength, 135 | OUT PULONG ReturnLength 136 | ); 137 | 138 | _IRQL_requires_max_(PASSIVE_LEVEL) 139 | NTSTATUS SetInformationThread( 140 | HANDLE hThread, 141 | THREADINFOCLASS ThreadInformationClass, 142 | IN PVOID ThreadInformation, 143 | ULONG ThreadInformationLength 144 | ); 145 | } 146 | 147 | namespace Information { 148 | _IRQL_requires_max_(PASSIVE_LEVEL) 149 | NTSTATUS QueryInformationProcess( 150 | HANDLE hProcess, 151 | PROCESSINFOCLASS ProcessInformationClass, 152 | OUT PVOID ProcessInformation, 153 | ULONG ProcessInformationLength, 154 | OUT PULONG ReturnLength 155 | ); 156 | 157 | _IRQL_requires_max_(PASSIVE_LEVEL) 158 | NTSTATUS SetInformationProcess( 159 | HANDLE hProcess, 160 | PROCESSINFOCLASS ProcessInformationClass, 161 | IN PVOID ProcessInformation, 162 | ULONG ProcessInformationLength 163 | ); 164 | 165 | _IRQL_requires_max_(PASSIVE_LEVEL) 166 | BOOLEAN Is32BitProcess(HANDLE hProcess = ZwCurrentProcess()); 167 | } 168 | 169 | namespace MemoryManagement { 170 | _IRQL_requires_max_(PASSIVE_LEVEL) 171 | NTSTATUS AllocateVirtualMemory(HANDLE hProcess, SIZE_T Size, ULONG Protect, IN OUT PVOID* BaseAddress); 172 | 173 | _IRQL_requires_max_(PASSIVE_LEVEL) 174 | PVOID AllocateVirtualMemory(HANDLE hProcess, SIZE_T Size, ULONG Protect); 175 | 176 | _IRQL_requires_max_(PASSIVE_LEVEL) 177 | NTSTATUS FreeVirtualMemory(HANDLE hProcess, PVOID BaseAddress); 178 | 179 | _IRQL_requires_max_(APC_LEVEL) 180 | NTSTATUS ReadProcessMemory( 181 | PEPROCESS Process, 182 | IN PVOID BaseAddress, // In the target process or kernel address 183 | OUT PVOID Buffer, // User or kernel address in the current process 184 | ULONG Size 185 | ); 186 | 187 | _IRQL_requires_max_(APC_LEVEL) 188 | NTSTATUS WriteProcessMemory( 189 | PEPROCESS Process, 190 | OUT PVOID BaseAddress, // In the target process or kernel address 191 | IN PVOID Buffer, // User or kernel address in the current process 192 | ULONG Size 193 | ); 194 | } 195 | 196 | namespace Apc { 197 | enum KAPC_ENVIRONMENT { 198 | OriginalApcEnvironment, 199 | AttachedApcEnvironment, 200 | CurrentApcEnvironment, 201 | InsertApcEnvironment 202 | }; 203 | 204 | using PKRUNDOWN_ROUTINE = VOID(NTAPI*)(PRKAPC Apc); 205 | 206 | using PKNORMAL_ROUTINE = VOID(NTAPI*)( 207 | PVOID NormalContext, 208 | PVOID SyatemArgument1, 209 | PVOID SystemArgument2 210 | ); 211 | using PKKERNEL_ROUTINE = VOID(NTAPI*)( 212 | PRKAPC Apc, 213 | PKNORMAL_ROUTINE NormalRoutine, 214 | PVOID NormalContext, 215 | PVOID SystemArgument1, 216 | PVOID SystemArgument2 217 | ); 218 | 219 | using _KeInitializeApc = VOID(NTAPI*)( 220 | IN PRKAPC Apc, 221 | IN PRKTHREAD Thread, 222 | IN KAPC_ENVIRONMENT Environment, 223 | IN PKKERNEL_ROUTINE KernelRoutine, 224 | IN PKRUNDOWN_ROUTINE RundownRoutine OPTIONAL, 225 | IN PKNORMAL_ROUTINE NormalRoutine OPTIONAL, 226 | IN KPROCESSOR_MODE ApcMode OPTIONAL, 227 | IN PVOID NormalContext OPTIONAL 228 | ); 229 | 230 | using _KeInsertQueueApc = BOOLEAN(NTAPI*)( 231 | PRKAPC Apc, 232 | PVOID SystemArgument1, 233 | PVOID SystemArgument2, 234 | KPRIORITY PriorityBoost 235 | ); 236 | 237 | using _KeTestAlertThread = BOOLEAN(NTAPI*)(KPROCESSOR_MODE AlertMode); 238 | 239 | _IRQL_requires_max_(APC_LEVEL) 240 | NTSTATUS QueueUserApc(PETHREAD Thread, PKNORMAL_ROUTINE NormalRoutine, PVOID Argument); 241 | } 242 | } -------------------------------------------------------------------------------- /SharedTypes/WdkTypes.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define DECLARE_STRUCT(Name, Fields) \ 4 | using Name = struct Fields; \ 5 | using P##Name = Name* 6 | 7 | // Direct WDK types port for use in usermode: 8 | namespace WdkTypes { 9 | enum KPROCESSOR_MODE { 10 | KernelMode, 11 | UserMode, 12 | MaximumMode 13 | }; 14 | 15 | enum LOCK_OPERATION { 16 | IoReadAccess, 17 | IoWriteAccess, 18 | IoModifyAccess 19 | }; 20 | 21 | enum MEMORY_CACHING_TYPE_ORIG { 22 | MmFrameBufferCached = 2 23 | }; 24 | 25 | enum MEMORY_CACHING_TYPE { 26 | MmNonCached = FALSE, 27 | MmCached = TRUE, 28 | MmWriteCombined = MmFrameBufferCached, 29 | MmHardwareCoherentCached, 30 | MmNonCachedUnordered, // IA64 31 | MmUSWCCached, 32 | MmMaximumCacheType, 33 | MmNotMapped = -1 34 | }; 35 | 36 | enum SECTION_INHERIT { 37 | ViewShare = 1, 38 | ViewUnmap = 2 39 | }; 40 | 41 | // Using universal x64 types for compatibility with x32 and x64: 42 | using NTSTATUS = unsigned int; 43 | using HANDLE = unsigned long long; 44 | using PVOID = unsigned long long; 45 | using PVOID64 = unsigned long long; 46 | using PEPROCESS = PVOID; 47 | using PETHREAD = PVOID; 48 | using PMDL = PVOID; 49 | using HMODULE = PVOID; 50 | using LPCWSTR = PVOID; 51 | using LPWSTR = PVOID; 52 | using LPCSTR = PVOID; 53 | using LPSTR = PVOID; 54 | using PBYTE = PVOID; 55 | using PSHORT = PVOID; 56 | using PULONG = PVOID; 57 | using PDWORD = PVOID; 58 | using PUINT64 = PVOID; 59 | 60 | using CLIENT_ID = struct { 61 | UINT64 ProcessId; 62 | UINT64 ThreadId; 63 | }; 64 | } 65 | 66 | namespace ObjFlags { 67 | enum ObjFlags { 68 | _OBJ_INHERIT = 0x00000002L, 69 | _OBJ_PERMANENT = 0x00000010L, 70 | _OBJ_EXCLUSIVE = 0x00000020L, 71 | _OBJ_CASE_INSENSITIVE = 0x00000040L, 72 | _OBJ_OPENIF = 0x00000080L, 73 | _OBJ_OPENLINK = 0x00000100L, 74 | _OBJ_KERNEL_HANDLE = 0x00000200L, 75 | _OBJ_FORCE_ACCESS_CHECK = 0x00000400L, 76 | _OBJ_IGNORE_IMPERSONATED_DEVICEMAP = 0x00000800L, 77 | _OBJ_DONT_REPARSE = 0x00001000L, 78 | _OBJ_VALID_ATTRIBUTES = 0x00001FF2L, 79 | }; 80 | } 81 | 82 | namespace NtTypes { 83 | enum PROCESSINFOCLASS { 84 | ProcessBasicInformation, // 0, q: PROCESS_BASIC_INFORMATION, PROCESS_EXTENDED_BASIC_INFORMATION 85 | ProcessQuotaLimits, // qs: QUOTA_LIMITS, QUOTA_LIMITS_EX 86 | ProcessIoCounters, // q: IO_COUNTERS 87 | ProcessVmCounters, // q: VM_COUNTERS, VM_COUNTERS_EX, VM_COUNTERS_EX2 88 | ProcessTimes, // q: KERNEL_USER_TIMES 89 | ProcessBasePriority, // s: KPRIORITY 90 | ProcessRaisePriority, // s: ULONG 91 | ProcessDebugPort, // q: HANDLE 92 | ProcessExceptionPort, // s: HANDLE 93 | ProcessAccessToken, // s: PROCESS_ACCESS_TOKEN 94 | ProcessLdtInformation, // 10, qs: PROCESS_LDT_INFORMATION 95 | ProcessLdtSize, // s: PROCESS_LDT_SIZE 96 | ProcessDefaultHardErrorMode, // qs: ULONG 97 | ProcessIoPortHandlers, // (kernel-mode only) 98 | ProcessPooledUsageAndLimits, // q: POOLED_USAGE_AND_LIMITS 99 | ProcessWorkingSetWatch, // q: PROCESS_WS_WATCH_INFORMATION[]; s: void 100 | ProcessUserModeIOPL, 101 | ProcessEnableAlignmentFaultFixup, // s: BOOLEAN 102 | ProcessPriorityClass, // qs: PROCESS_PRIORITY_CLASS 103 | ProcessWx86Information, 104 | ProcessHandleCount, // 20, q: ULONG, PROCESS_HANDLE_INFORMATION 105 | ProcessAffinityMask, // s: KAFFINITY 106 | ProcessPriorityBoost, // qs: ULONG 107 | ProcessDeviceMap, // qs: PROCESS_DEVICEMAP_INFORMATION, PROCESS_DEVICEMAP_INFORMATION_EX 108 | ProcessSessionInformation, // q: PROCESS_SESSION_INFORMATION 109 | ProcessForegroundInformation, // s: PROCESS_FOREGROUND_BACKGROUND 110 | ProcessWow64Information, // q: ULONG_PTR 111 | ProcessImageFileName, // q: UNICODE_STRING 112 | ProcessLUIDDeviceMapsEnabled, // q: ULONG 113 | ProcessBreakOnTermination, // qs: ULONG 114 | ProcessDebugObjectHandle, // 30, q: HANDLE 115 | ProcessDebugFlags, // qs: ULONG 116 | ProcessHandleTracing, // q: PROCESS_HANDLE_TRACING_QUERY; s: size 0 disables, otherwise enables 117 | ProcessIoPriority, // qs: ULONG 118 | ProcessExecuteFlags, // qs: ULONG 119 | ProcessResourceManagement, 120 | ProcessCookie, // q: ULONG 121 | ProcessImageInformation, // q: SECTION_IMAGE_INFORMATION 122 | ProcessCycleTime, // q: PROCESS_CYCLE_TIME_INFORMATION // since VISTA 123 | ProcessPagePriority, // q: ULONG 124 | ProcessInstrumentationCallback, // 40 125 | ProcessThreadStackAllocation, // s: PROCESS_STACK_ALLOCATION_INFORMATION, PROCESS_STACK_ALLOCATION_INFORMATION_EX 126 | ProcessWorkingSetWatchEx, // q: PROCESS_WS_WATCH_INFORMATION_EX[] 127 | ProcessImageFileNameWin32, // q: UNICODE_STRING 128 | ProcessImageFileMapping, // q: HANDLE (input) 129 | ProcessAffinityUpdateMode, // qs: PROCESS_AFFINITY_UPDATE_MODE 130 | ProcessMemoryAllocationMode, // qs: PROCESS_MEMORY_ALLOCATION_MODE 131 | ProcessGroupInformation, // q: USHORT[] 132 | ProcessTokenVirtualizationEnabled, // s: ULONG 133 | ProcessConsoleHostProcess, // q: ULONG_PTR 134 | ProcessWindowInformation, // 50, q: PROCESS_WINDOW_INFORMATION 135 | ProcessHandleInformation, // q: PROCESS_HANDLE_SNAPSHOT_INFORMATION // since WIN8 136 | ProcessMitigationPolicy, // s: PROCESS_MITIGATION_POLICY_INFORMATION 137 | ProcessDynamicFunctionTableInformation, 138 | ProcessHandleCheckingMode, 139 | ProcessKeepAliveCount, // q: PROCESS_KEEPALIVE_COUNT_INFORMATION 140 | ProcessRevokeFileHandles, // s: PROCESS_REVOKE_FILE_HANDLES_INFORMATION 141 | ProcessWorkingSetControl, // s: PROCESS_WORKING_SET_CONTROL 142 | ProcessHandleTable, // since WINBLUE 143 | ProcessCheckStackExtentsMode, 144 | ProcessCommandLineInformation, // 60, q: UNICODE_STRING 145 | ProcessProtectionInformation, // q: PS_PROTECTION 146 | ProcessMemoryExhaustion, // PROCESS_MEMORY_EXHAUSTION_INFO // since THRESHOLD 147 | ProcessFaultInformation, // PROCESS_FAULT_INFORMATION 148 | ProcessTelemetryIdInformation, // PROCESS_TELEMETRY_ID_INFORMATION 149 | ProcessCommitReleaseInformation, // PROCESS_COMMIT_RELEASE_INFORMATION 150 | ProcessDefaultCpuSetsInformation, 151 | ProcessAllowedCpuSetsInformation, 152 | ProcessReserved1Information, 153 | ProcessReserved2Information, 154 | ProcessSubsystemProcess, // 70 155 | ProcessJobMemoryInformation, // PROCESS_JOB_MEMORY_INFO 156 | MaxProcessInfoClass 157 | }; 158 | 159 | enum THREADINFOCLASS { 160 | ThreadBasicInformation, // q: THREAD_BASIC_INFORMATION 161 | ThreadTimes, // q: KERNEL_USER_TIMES 162 | ThreadPriority, // s: KPRIORITY 163 | ThreadBasePriority, // s: LONG 164 | ThreadAffinityMask, // s: KAFFINITY 165 | ThreadImpersonationToken, // s: HANDLE 166 | ThreadDescriptorTableEntry, // q: DESCRIPTOR_TABLE_ENTRY (or WOW64_DESCRIPTOR_TABLE_ENTRY) 167 | ThreadEnableAlignmentFaultFixup, // s: BOOLEAN 168 | ThreadEventPair, 169 | ThreadQuerySetWin32StartAddress, // q: PVOID 170 | ThreadZeroTlsCell, // 10 171 | ThreadPerformanceCount, // q: LARGE_INTEGER 172 | ThreadAmILastThread, // q: ULONG 173 | ThreadIdealProcessor, // s: ULONG 174 | ThreadPriorityBoost, // qs: ULONG 175 | ThreadSetTlsArrayAddress, 176 | ThreadIsIoPending, // q: ULONG 177 | ThreadHideFromDebugger, // s: void 178 | ThreadBreakOnTermination, // qs: ULONG 179 | ThreadSwitchLegacyState, 180 | ThreadIsTerminated, // 20, q: ULONG 181 | ThreadLastSystemCall, // q: THREAD_LAST_SYSCALL_INFORMATION 182 | ThreadIoPriority, // qs: ULONG 183 | ThreadCycleTime, // q: THREAD_CYCLE_TIME_INFORMATION 184 | ThreadPagePriority, // q: ULONG 185 | ThreadActualBasePriority, 186 | ThreadTebInformation, // q: THREAD_TEB_INFORMATION (requires THREAD_GET_CONTEXT + THREAD_SET_CONTEXT) 187 | ThreadCSwitchMon, 188 | ThreadCSwitchPmu, 189 | ThreadWow64Context, // q: WOW64_CONTEXT 190 | ThreadGroupInformation, // 30, q: GROUP_AFFINITY 191 | ThreadUmsInformation, 192 | ThreadCounterProfiling, 193 | ThreadIdealProcessorEx, // q: PROCESSOR_NUMBER 194 | ThreadCpuAccountingInformation, // since WIN8 195 | ThreadSuspendCount, // since WINBLUE 196 | ThreadHeterogeneousCpuPolicy, // KHETERO_CPU_POLICY // since THRESHOLD 197 | ThreadContainerId, 198 | ThreadNameInformation, 199 | ThreadProperty, 200 | ThreadSelectedCpuSets, 201 | ThreadSystemThreadInformation, 202 | MaxThreadInfoClass 203 | }; 204 | } --------------------------------------------------------------------------------