├── README.md ├── Usermode ├── UM.sln └── UM │ ├── Driver.h │ ├── Source.cpp │ ├── UM.vcxproj │ ├── UM.vcxproj.filters │ └── UM.vcxproj.user ├── cache.h ├── cleaning.h ├── crt.h ├── definitions.h ├── encrypt.h ├── entry.cpp ├── ia32.h ├── imports.h ├── interface.h ├── km.vcxproj ├── km.vcxproj.filters ├── km.vcxproj.user └── utils.h /README.md: -------------------------------------------------------------------------------- 1 | # NtUserUpdateWindowTrackingInfo 2 | 3 | bake wake up, interpreter released a quad chained data ptr. 4 | -------------------------------------------------------------------------------- /Usermode/UM.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.1.32319.34 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UM", "UM\UM.vcxproj", "{1FF848D1-8369-40D4-BF33-A6EA276412CB}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {1FF848D1-8369-40D4-BF33-A6EA276412CB}.Debug|x64.ActiveCfg = Debug|x64 17 | {1FF848D1-8369-40D4-BF33-A6EA276412CB}.Debug|x64.Build.0 = Debug|x64 18 | {1FF848D1-8369-40D4-BF33-A6EA276412CB}.Debug|x86.ActiveCfg = Debug|Win32 19 | {1FF848D1-8369-40D4-BF33-A6EA276412CB}.Debug|x86.Build.0 = Debug|Win32 20 | {1FF848D1-8369-40D4-BF33-A6EA276412CB}.Release|x64.ActiveCfg = Release|x64 21 | {1FF848D1-8369-40D4-BF33-A6EA276412CB}.Release|x64.Build.0 = Release|x64 22 | {1FF848D1-8369-40D4-BF33-A6EA276412CB}.Release|x86.ActiveCfg = Release|Win32 23 | {1FF848D1-8369-40D4-BF33-A6EA276412CB}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {54BBBBF3-4FF9-43E7-B2AF-E8D6EB0A9505} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /Usermode/UM/Driver.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | class kinterface_t 4 | { 5 | private: 6 | 7 | typedef __int64( __fastcall *function_address_t )( void * );; 8 | function_address_t function_address = ( function_address_t ) NULL; 9 | typedef enum _request_codes 10 | { 11 | request_free = 0x109, 12 | request_base = 0x119, 13 | request_read = 0x129, 14 | request_write = 0x139, 15 | request_allocate = 0x149, 16 | request_expose = 0x159, 17 | request_swap = 0x169, 18 | request_pattern = 0x179, 19 | request_success = 0x91a, 20 | request_unique = 0x92b, 21 | request_unload = 0x93c, 22 | }request_codes, *prequest_codes; 23 | 24 | typedef struct _unload_request 25 | { 26 | bool *buffer; 27 | }unload_request, *punload_request; 28 | 29 | typedef struct _read_request 30 | { 31 | uint32_t pid; 32 | uintptr_t address; 33 | void *buffer; 34 | size_t size; 35 | } read_request, *pread_request; 36 | 37 | typedef struct _write_request 38 | { 39 | uint32_t pid; 40 | uintptr_t address; 41 | void *buffer; 42 | size_t size; 43 | } write_request, *pwrite_request; 44 | 45 | typedef struct _base_request 46 | { 47 | uint32_t pid; 48 | uintptr_t handle; 49 | WCHAR name[260]; 50 | } base_request, *pbase_request; 51 | 52 | typedef struct _swap_request 53 | { 54 | uint32_t pid; 55 | uintptr_t dst; 56 | uintptr_t src; 57 | uintptr_t old; 58 | }swap_request, *pswap_request; 59 | 60 | typedef struct _free_request 61 | { 62 | void *address; 63 | uintptr_t mdl; 64 | }free_request, *pfree_request; 65 | 66 | typedef struct _allocate_request 67 | { 68 | void *address; 69 | uintptr_t mdl; 70 | size_t size; 71 | }allocate_request, *pallocate_request; 72 | 73 | typedef struct _expose_request 74 | { 75 | void *address; 76 | size_t size; 77 | uint32_t pid; 78 | }expose_request, *pexpose_request; 79 | 80 | typedef struct _pattern_request 81 | { 82 | int pid; 83 | uintptr_t base; 84 | char signature[260]; 85 | uintptr_t address; 86 | }pattern_request, *ppattern_request; 87 | 88 | typedef struct _request_data 89 | { 90 | uint32_t unique; 91 | request_codes code; 92 | void *data; 93 | }request_data, *prequest_data; 94 | 95 | uint32_t set_pid; 96 | 97 | public: 98 | HMODULE ensure_dll_load( ) 99 | { 100 | #define LOAD_DLL(str) LoadLibrary((str)) 101 | 102 | LOAD_DLL( L"user32.dll" ); 103 | 104 | #undef LOAD_DLL 105 | return LoadLibrary( ( L"win32u.dll" ) ); 106 | } 107 | inline auto initialize( ) -> bool 108 | { 109 | 110 | LoadLibrary( L"user32.dll" ); 111 | 112 | const auto win32k = LoadLibrary( L"win32u.dll" ); 113 | 114 | *( void ** ) &function_address = GetProcAddress( win32k, "NtUserUpdateWindowTrackingInfo" ); 115 | 116 | return true; 117 | } 118 | 119 | inline auto send_cmd( void *data, request_codes code ) -> bool 120 | { 121 | if ( !data || !code ) 122 | { 123 | return false; 124 | } 125 | 126 | request_data request { 0 }; 127 | 128 | request.unique = request_unique; 129 | request.data = data; 130 | request.code = code; 131 | 132 | const auto result = function_address( &request ); 133 | 134 | if ( result != request_success ) 135 | { 136 | return false; 137 | } 138 | 139 | return true; 140 | } 141 | 142 | inline auto get_module_base( const std::string module_name ) -> const std::uintptr_t 143 | { 144 | base_request data { 0 }; 145 | 146 | data.pid = set_pid; 147 | data.handle = 0; 148 | 149 | std::wstring wstr { std::wstring( module_name.begin( ), module_name.end( ) ) }; 150 | 151 | memset( data.name, 0, sizeof( WCHAR ) * 260 ); 152 | wcscpy( data.name, wstr.c_str( ) ); 153 | 154 | send_cmd( &data, request_base ); 155 | 156 | return data.handle; 157 | } 158 | 159 | inline auto free_virtual_memory( void *address, uintptr_t mdl ) -> bool 160 | { 161 | free_request data { 0 }; 162 | 163 | data.mdl = mdl; 164 | data.address = address; 165 | 166 | return send_cmd( &data, request_free ); 167 | } 168 | 169 | inline auto find_signature( const std::uintptr_t base, const std::string signature ) -> std::uintptr_t 170 | { 171 | pattern_request data { 0 }; 172 | 173 | data.pid = set_pid; 174 | data.base = base; 175 | data.address = 0; 176 | 177 | memset( data.signature, 0, sizeof( char ) * 260 ); 178 | strcpy( data.signature, signature.c_str( ) ); 179 | 180 | send_cmd( &data, request_pattern ); 181 | 182 | return data.address; 183 | } 184 | 185 | inline auto swap_virtual_pointer( std::uintptr_t src, std::uintptr_t dst ) -> std::uintptr_t 186 | { 187 | swap_request data { 0 }; 188 | 189 | data.pid = set_pid; 190 | data.src = src; 191 | data.dst = dst; 192 | data.old = 0; 193 | 194 | send_cmd( &data, request_swap ); 195 | 196 | return data.old; 197 | } 198 | 199 | inline auto read_virtual_memory( const std::uintptr_t address, void *buffer, const std::size_t size ) -> bool 200 | { 201 | read_request data { 0 }; 202 | 203 | data.pid = set_pid; 204 | data.address = address; 205 | data.buffer = buffer; 206 | data.size = size; 207 | 208 | return send_cmd( &data, request_read ); 209 | } 210 | 211 | template 212 | inline auto read_virtual_memory( const std::uintptr_t address ) -> t 213 | { 214 | t response { }; 215 | this->read_virtual_memory( address, &response, sizeof( t ) ); 216 | return response; 217 | } 218 | 219 | inline auto write_virtual_memory( const std::uintptr_t address, void *buffer, const std::size_t size ) -> bool 220 | { 221 | write_request data { 0 }; 222 | 223 | data.pid = set_pid; 224 | data.address = address; 225 | data.buffer = buffer; 226 | data.size = size; 227 | 228 | return send_cmd( &data, request_write ); 229 | } 230 | 231 | template 232 | inline auto write_virtual_memory( const std::uintptr_t address, t value ) -> bool 233 | { 234 | return write_virtual_memory( address, &value, sizeof( t ) ); 235 | } 236 | 237 | inline auto allocate_kernel_memory( const std::size_t size, std::uintptr_t *mdl ) -> void * 238 | { 239 | allocate_request data { 0 }; 240 | 241 | data.size = size; 242 | data.address = 0; 243 | data.mdl = 0; 244 | 245 | send_cmd( &data, request_allocate ); 246 | 247 | *mdl = data.mdl; 248 | 249 | return data.address; 250 | } 251 | 252 | inline auto expose_kernel_memory( void *kernel_address, const std::size_t size ) -> bool 253 | { 254 | expose_request data { 0 }; 255 | 256 | data.pid = set_pid; 257 | data.address = kernel_address; 258 | data.size = size; 259 | 260 | return send_cmd( &data, request_expose ); 261 | } 262 | 263 | template 264 | inline auto read_virtual_memorychain( uintptr_t address, std::vector chain ) -> t 265 | { 266 | uintptr_t current = address; 267 | for ( int i = 0; i < chain.size( ) - 1; i++ ) 268 | { 269 | current = this->read_virtual_memory( current + chain[i] ); 270 | } 271 | return this->read_virtual_memory( current + chain[chain.size( ) - 1] ); 272 | }; 273 | 274 | 275 | inline auto init( uint32_t process_id ) -> bool 276 | { 277 | if ( !process_id ) 278 | return false; 279 | 280 | set_pid = process_id; 281 | 282 | return true; 283 | } 284 | 285 | inline auto unload( ) -> bool 286 | { 287 | unload_request data { 0 }; 288 | 289 | bool buffer = false; 290 | 291 | data.buffer = &buffer; 292 | 293 | const auto result = send_cmd( &data, request_unload ); 294 | 295 | if ( !result || !buffer ) 296 | { 297 | return false; 298 | } 299 | 300 | return true; 301 | } 302 | }; 303 | 304 | static kinterface_t *kernel = new kinterface_t( ); -------------------------------------------------------------------------------- /Usermode/UM/Source.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "Driver.h" 8 | 9 | 10 | void main( ) 11 | { 12 | // call this as soon as ur app starts 13 | kernel->initialize( ); 14 | 15 | int PID = 4940; 16 | 17 | if ( !kernel->init( PID ) ) 18 | { 19 | MessageBoxA( 0, "Driver did not attach!", 0, 0 ); 20 | } 21 | 22 | kernel->read_virtual_memory( 0 ); // bsod most likely 23 | 24 | } -------------------------------------------------------------------------------- /Usermode/UM/UM.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 | 16.0 23 | Win32Proj 24 | {1ff848d1-8369-40d4-bf33-a6ea276412cb} 25 | UM 26 | 10.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v143 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | v143 39 | true 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | v143 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | v143 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | 76 | 77 | false 78 | 79 | 80 | true 81 | 82 | 83 | false 84 | UM 85 | 86 | 87 | 88 | Level3 89 | true 90 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 91 | true 92 | 93 | 94 | Console 95 | true 96 | 97 | 98 | 99 | 100 | Level3 101 | true 102 | true 103 | true 104 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 105 | true 106 | 107 | 108 | Console 109 | true 110 | true 111 | true 112 | 113 | 114 | 115 | 116 | Level3 117 | true 118 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 119 | true 120 | 121 | 122 | Console 123 | true 124 | 125 | 126 | 127 | 128 | Level3 129 | true 130 | true 131 | true 132 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 133 | true 134 | stdcpp17 135 | 4996 136 | 137 | 138 | Console 139 | true 140 | true 141 | true 142 | 143 | 144 | 145 | 146 | CppCode 147 | false 148 | 149 | 150 | 151 | 152 | 153 | 154 | -------------------------------------------------------------------------------- /Usermode/UM/UM.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;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 | {6f9bb923-e0a7-4328-a7c7-54c20f6c5cd6} 18 | 19 | 20 | 21 | 22 | Source Files 23 | 24 | 25 | 26 | 27 | Header Files\Driver 28 | 29 | 30 | -------------------------------------------------------------------------------- /Usermode/UM/UM.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /cache.h: -------------------------------------------------------------------------------- 1 | namespace cache 2 | { 3 | __int64( __fastcall *o_qword_address )( void * ) = nullptr; 4 | __int64( __fastcall *o_function_qword_1 )( void * ) = nullptr; 5 | __int64( __fastcall *o_function_qword_2 )( void * ) = nullptr; 6 | 7 | uintptr_t qword_address = 0; 8 | uintptr_t function_qword_1 = 0; 9 | uintptr_t function_qword_2 = 0; 10 | } -------------------------------------------------------------------------------- /cleaning.h: -------------------------------------------------------------------------------- 1 | namespace clean 2 | { 3 | bool null_pfn( PMDL mdl ) 4 | { 5 | PPFN_NUMBER mdl_pages = MmGetMdlPfnArray( mdl ); 6 | if ( !mdl_pages ) { return false; } 7 | 8 | ULONG mdl_page_count = ADDRESS_AND_SIZE_TO_SPAN_PAGES( MmGetMdlVirtualAddress( mdl ), MmGetMdlByteCount( mdl ) ); 9 | 10 | ULONG null_pfn = 0x0; 11 | 12 | MM_COPY_ADDRESS source_address = { 0 }; 13 | source_address.VirtualAddress = &null_pfn; 14 | 15 | for ( ULONG i = 0; i < mdl_page_count; i++ ) 16 | { 17 | size_t bytes = 0; 18 | mm_copy_memory( &mdl_pages[i], source_address, sizeof( ULONG ), MM_COPY_MEMORY_VIRTUAL, &bytes ); 19 | } 20 | 21 | return true; 22 | } 23 | } -------------------------------------------------------------------------------- /crt.h: -------------------------------------------------------------------------------- 1 | namespace crt 2 | { 3 | template 4 | __forceinline int strlen( t str ) { 5 | if ( !str ) 6 | { 7 | return 0; 8 | } 9 | 10 | t buffer = str; 11 | 12 | while ( *buffer ) 13 | { 14 | *buffer++; 15 | } 16 | 17 | return ( int )( buffer - str ); 18 | } 19 | 20 | bool strcmp( const char *src, const char *dst ) 21 | { 22 | if ( !src || !dst ) 23 | { 24 | return true; 25 | } 26 | 27 | const auto src_sz = crt::strlen( src ); 28 | const auto dst_sz = crt::strlen( dst ); 29 | 30 | if ( src_sz != dst_sz ) 31 | { 32 | return true; 33 | } 34 | 35 | for ( int i = 0; i < src_sz; i++ ) 36 | { 37 | if ( src[i] != dst[i] ) 38 | { 39 | return true; 40 | } 41 | } 42 | 43 | return false; 44 | } 45 | } 46 | 47 | -------------------------------------------------------------------------------- /definitions.h: -------------------------------------------------------------------------------- 1 | #define PFN_TO_PAGE(pfn) ( pfn << 12 ) 2 | #define dereference(ptr) (const uintptr_t)(ptr + *( int * )( ( BYTE * )ptr + 3 ) + 7) 3 | #define in_range(x,a,b) (x >= a && x <= b) 4 | #define get_bits( x ) (in_range((x&(~0x20)),'A','F') ? ((x&(~0x20)) - 'A' + 0xA) : (in_range(x,'0','9') ? x - '0' : 0)) 5 | #define get_byte( x ) (get_bits(x[0]) << 4 | get_bits(x[1])) 6 | #define size_align(Size) ((Size + 0xFFF) & 0xFFFFFFFFFFFFF000) 7 | #define to_lower_i(Char) ((Char >= 'A' && Char <= 'Z') ? (Char + 32) : Char) 8 | #define to_lower_c(Char) ((Char >= (char*)'A' && Char <= (char*)'Z') ? (Char + 32) : Char) 9 | 10 | typedef unsigned int uint32_t; 11 | 12 | typedef struct _RTL_PROCESS_MODULE_INFORMATION 13 | { 14 | HANDLE Section; 15 | PVOID MappedBase; 16 | PVOID ImageBase; 17 | ULONG ImageSize; 18 | ULONG Flags; 19 | USHORT LoadOrderIndex; 20 | USHORT InitOrderIndex; 21 | USHORT LoadCount; 22 | USHORT OffsetToFileName; 23 | UCHAR FullPathName[256]; 24 | } RTL_PROCESS_MODULE_INFORMATION, *PRTL_PROCESS_MODULE_INFORMATION; 25 | 26 | typedef struct _RTL_PROCESS_MODULES 27 | { 28 | ULONG NumberOfModules; 29 | RTL_PROCESS_MODULE_INFORMATION Modules[1]; 30 | } RTL_PROCESS_MODULES, *PRTL_PROCESS_MODULES; 31 | 32 | typedef struct _LDR_DATA_TABLE_ENTRY 33 | { 34 | LIST_ENTRY InLoadOrderLinks; 35 | LIST_ENTRY InMemoryOrderLinks; 36 | LIST_ENTRY InInitializationOrderLinks; 37 | PVOID DllBase; 38 | PVOID EntryPoint; 39 | ULONG SizeOfImage; 40 | UNICODE_STRING FullDllName; 41 | UNICODE_STRING BaseDllName; 42 | ULONG Flags; 43 | WORD LoadCount; 44 | WORD TlsIndex; 45 | union 46 | { 47 | LIST_ENTRY HashLinks; 48 | struct 49 | { 50 | PVOID SectionPointer; 51 | ULONG CheckSum; 52 | }; 53 | }; 54 | union 55 | { 56 | ULONG TimeDateStamp; 57 | PVOID LoadedImports; 58 | }; 59 | VOID *EntryPointActivationContext; 60 | PVOID PatchInformation; 61 | LIST_ENTRY ForwarderLinks; 62 | LIST_ENTRY ServiceTagLinks; 63 | LIST_ENTRY StaticLinks; 64 | } LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY; 65 | 66 | typedef struct _RTL_CRITICAL_SECTION 67 | { 68 | VOID *DebugInfo; 69 | LONG LockCount; 70 | LONG RecursionCount; 71 | PVOID OwningThread; 72 | PVOID LockSemaphore; 73 | ULONG SpinCount; 74 | } RTL_CRITICAL_SECTION, *PRTL_CRITICAL_SECTION; 75 | 76 | typedef struct _PEB_LDR_DATA 77 | { 78 | ULONG Length; 79 | UCHAR Initialized; 80 | PVOID SsHandle; 81 | LIST_ENTRY InLoadOrderModuleList; 82 | LIST_ENTRY InMemoryOrderModuleList; 83 | LIST_ENTRY InInitializationOrderModuleList; 84 | PVOID EntryInProgress; 85 | } PEB_LDR_DATA, *PPEB_LDR_DATA; 86 | 87 | typedef struct _PEB 88 | { 89 | UCHAR InheritedAddressSpace; 90 | UCHAR ReadImageFileExecOptions; 91 | UCHAR BeingDebugged; 92 | UCHAR BitField; 93 | ULONG ImageUsesLargePages : 1; 94 | ULONG IsProtectedProcess : 1; 95 | ULONG IsLegacyProcess : 1; 96 | ULONG IsImageDynamicallyRelocated : 1; 97 | ULONG SpareBits : 4; 98 | PVOID Mutant; 99 | PVOID ImageBaseAddress; 100 | PPEB_LDR_DATA Ldr; 101 | VOID *ProcessParameters; 102 | PVOID SubSystemData; 103 | PVOID ProcessHeap; 104 | PRTL_CRITICAL_SECTION FastPebLock; 105 | PVOID AtlThunkSListPtr; 106 | PVOID IFEOKey; 107 | ULONG CrossProcessFlags; 108 | ULONG ProcessInJob : 1; 109 | ULONG ProcessInitializing : 1; 110 | ULONG ReservedBits0 : 30; 111 | union 112 | { 113 | PVOID KernelCallbackTable; 114 | PVOID UserSharedInfoPtr; 115 | }; 116 | ULONG SystemReserved[1]; 117 | ULONG SpareUlong; 118 | VOID *FreeList; 119 | ULONG TlsExpansionCounter; 120 | PVOID TlsBitmap; 121 | ULONG TlsBitmapBits[2]; 122 | PVOID ReadOnlySharedMemoryBase; 123 | PVOID HotpatchInformation; 124 | VOID **ReadOnlyStaticServerData; 125 | PVOID AnsiCodePageData; 126 | PVOID OemCodePageData; 127 | PVOID UnicodeCaseTableData; 128 | ULONG NumberOfProcessors; 129 | ULONG NtGlobalFlag; 130 | LARGE_INTEGER CriticalSectionTimeout; 131 | ULONG HeapSegmentReserve; 132 | ULONG HeapSegmentCommit; 133 | ULONG HeapDeCommitTotalFreeThreshold; 134 | ULONG HeapDeCommitFreeBlockThreshold; 135 | ULONG NumberOfHeaps; 136 | ULONG MaximumNumberOfHeaps; 137 | VOID **ProcessHeaps; 138 | PVOID GdiSharedHandleTable; 139 | PVOID ProcessStarterHelper; 140 | ULONG GdiDCAttributeList; 141 | PRTL_CRITICAL_SECTION LoaderLock; 142 | ULONG OSMajorVersion; 143 | ULONG OSMinorVersion; 144 | WORD OSBuildNumber; 145 | WORD OSCSDVersion; 146 | ULONG OSPlatformId; 147 | ULONG ImageSubsystem; 148 | ULONG ImageSubsystemMajorVersion; 149 | ULONG ImageSubsystemMinorVersion; 150 | ULONG ImageProcessAffinityMask; 151 | ULONG GdiHandleBuffer[34]; 152 | PVOID PostProcessInitRoutine; 153 | PVOID TlsExpansionBitmap; 154 | ULONG TlsExpansionBitmapBits[32]; 155 | ULONG SessionId; 156 | ULARGE_INTEGER AppCompatFlags; 157 | ULARGE_INTEGER AppCompatFlagsUser; 158 | PVOID pShimData; 159 | PVOID AppCompatInfo; 160 | UNICODE_STRING CSDVersion; 161 | VOID *ActivationContextData; 162 | VOID *ProcessAssemblyStorageMap; 163 | VOID *SystemDefaultActivationContextData; 164 | VOID *SystemAssemblyStorageMap; 165 | ULONG MinimumStackCommit; 166 | VOID *FlsCallback; 167 | LIST_ENTRY FlsListHead; 168 | PVOID FlsBitmap; 169 | ULONG FlsBitmapBits[4]; 170 | ULONG FlsHighIndex; 171 | PVOID WerRegistrationData; 172 | PVOID WerShipAssertPtr; 173 | } PEB, *PPEB; 174 | 175 | typedef enum _SYSTEM_INFORMATION_CLASS 176 | { 177 | SystemBasicInformation, 178 | SystemProcessorInformation, 179 | SystemPerformanceInformation, 180 | SystemTimeOfDayInformation, 181 | SystemPathInformation, 182 | SystemProcessInformation, 183 | SystemCallCountInformation, 184 | SystemDeviceInformation, 185 | SystemProcessorPerformanceInformation, 186 | SystemFlagsInformation, 187 | SystemCallTimeInformation, 188 | SystemModuleInformation, 189 | SystemLocksInformation, 190 | SystemStackTraceInformation, 191 | SystemPagedPoolInformation, 192 | SystemNonPagedPoolInformation, 193 | SystemHandleInformation, 194 | SystemObjectInformation, 195 | SystemPageFileInformation, 196 | SystemVdmInstemulInformation, 197 | SystemVdmBopInformation, 198 | SystemFileCacheInformation, 199 | SystemPoolTagInformation, 200 | SystemInterruptInformation, 201 | SystemDpcBehaviorInformation, 202 | SystemFullMemoryInformation, 203 | SystemLoadGdiDriverInformation, 204 | SystemUnloadGdiDriverInformation, 205 | SystemTimeAdjustmentInformation, 206 | SystemSummaryMemoryInformation, 207 | SystemNextEventIdInformation, 208 | SystemEventIdsInformation, 209 | SystemCrashDumpInformation, 210 | SystemExceptionInformation, 211 | SystemCrashDumpStateInformation, 212 | SystemKernelDebuggerInformation, 213 | SystemContextSwitchInformation, 214 | SystemRegistryQuotaInformation, 215 | SystemExtendServiceTableInformation, 216 | SystemPrioritySeperation, 217 | SystemPlugPlayBusInformation, 218 | SystemDockInformation, 219 | SystemProcessorSpeedInformation, 220 | SystemCurrentTimeZoneInformation, 221 | SystemLookasideInformation 222 | } SYSTEM_INFORMATION_CLASS, *PSYSTEM_INFORMATION_CLASS; 223 | 224 | typedef struct _PAGE_INFORMATION 225 | { 226 | PML4E_64 *PML4E; 227 | PDPTE_64 *PDPTE; 228 | PDE_64 *PDE; 229 | PTE_64 *PTE; 230 | }PAGE_INFORMATION, *PPAGE_INFORMATION; 231 | 232 | typedef struct _MDL_INFORMATION 233 | { 234 | MDL *mdl; 235 | uintptr_t va; 236 | }MDL_INFORMATION, *PMDL_INFORMATION; 237 | 238 | typedef union _VIRTUAL_ADDRESS 239 | { 240 | PVOID value; 241 | struct 242 | { 243 | ULONG64 offset : 12; 244 | ULONG64 pt_index : 9; 245 | ULONG64 pd_index : 9; 246 | ULONG64 pdpt_index : 9; 247 | ULONG64 pml4_index : 9; 248 | ULONG64 reserved : 16; 249 | }; 250 | } VIRTUAL_ADDRESS, *PVIRTUAL_ADDRESS; 251 | 252 | extern "C" 253 | { 254 | NTKERNELAPI NTSTATUS NTAPI ZwQuerySystemInformation( 255 | _In_ SYSTEM_INFORMATION_CLASS SystemInformationClass, 256 | _Inout_ PVOID SystemInformation, 257 | _In_ ULONG SystemInformationLength, 258 | _Out_opt_ PULONG ReturnLength 259 | ); 260 | 261 | NTSTATUS NTAPI MmCopyVirtualMemory( 262 | PEPROCESS SourceProcess, 263 | PVOID SourceAddress, 264 | PEPROCESS TargetProcess, 265 | PVOID TargetAddress, 266 | SIZE_T BufferSize, 267 | KPROCESSOR_MODE PreviousMode, 268 | PSIZE_T ReturnSize 269 | ); 270 | 271 | NTSTATUS ZwAllocateVirtualMemory( 272 | _In_ HANDLE ProcessHandle, 273 | _Inout_ PVOID *BaseAddress, 274 | _In_ ULONG_PTR ZeroBits, 275 | _Inout_ PSIZE_T RegionSize, 276 | _In_ ULONG AllocationType, 277 | _In_ ULONG Protect 278 | ); 279 | 280 | NTKERNELAPI 281 | PPEB 282 | PsGetProcessPeb( 283 | IN PEPROCESS Process 284 | ); 285 | 286 | NTKERNELAPI 287 | PVOID NTAPI RtlFindExportedRoutineByName( 288 | _In_ PVOID ImageBase, 289 | _In_ PCCH RoutineName 290 | ); 291 | } -------------------------------------------------------------------------------- /encrypt.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /*____________________________________________________________________________________________________________ 4 | Original Author: skadro 5 | Github: https://github.com/skadro-official 6 | License: See end of file 7 | skCrypter 8 | Compile-time, Usermode + Kernelmode, safe and lightweight string crypter library for C++11+ 9 | *Not removing this part is appreciated* 10 | ____________________________________________________________________________________________________________*/ 11 | 12 | #ifdef _KERNEL_MODE 13 | namespace std 14 | { 15 | // STRUCT TEMPLATE remove_reference 16 | template 17 | struct remove_reference { 18 | using type = _Ty; 19 | }; 20 | 21 | template 22 | struct remove_reference<_Ty &> { 23 | using type = _Ty; 24 | }; 25 | 26 | template 27 | struct remove_reference<_Ty &&> { 28 | using type = _Ty; 29 | }; 30 | 31 | template 32 | using remove_reference_t = typename remove_reference<_Ty>::type; 33 | 34 | // STRUCT TEMPLATE remove_const 35 | template 36 | struct remove_const { // remove top-level const qualifier 37 | using type = _Ty; 38 | }; 39 | 40 | template 41 | struct remove_const { 42 | using type = _Ty; 43 | }; 44 | 45 | template 46 | using remove_const_t = typename remove_const<_Ty>::type; 47 | } 48 | #else 49 | #include 50 | #endif 51 | 52 | namespace skc 53 | { 54 | template 55 | using clean_type = typename std::remove_const_t>; 56 | 57 | template 58 | class skCrypter 59 | { 60 | public: 61 | __forceinline constexpr skCrypter( T *data ) 62 | { 63 | crypt( data ); 64 | } 65 | 66 | __forceinline T *get( ) 67 | { 68 | return _storage; 69 | } 70 | 71 | __forceinline int size( ) // (w)char count 72 | { 73 | return _size; 74 | } 75 | 76 | __forceinline char key( ) 77 | { 78 | return _key1; 79 | } 80 | 81 | __forceinline T *encrypt( ) 82 | { 83 | if ( !isEncrypted( ) ) 84 | crypt( _storage ); 85 | 86 | return _storage; 87 | } 88 | 89 | __forceinline T *decrypt( ) 90 | { 91 | if ( isEncrypted( ) ) 92 | crypt( _storage ); 93 | 94 | return _storage; 95 | } 96 | 97 | __forceinline bool isEncrypted( ) 98 | { 99 | return _storage[_size - 1] != 0; 100 | } 101 | 102 | __forceinline void clear( ) // set full storage to 0 103 | { 104 | for ( int i = 0; i < _size; i++ ) 105 | { 106 | _storage[i] = 0; 107 | } 108 | } 109 | 110 | __forceinline operator T *( ) 111 | { 112 | decrypt( ); 113 | 114 | return _storage; 115 | } 116 | 117 | private: 118 | __forceinline constexpr void crypt( T *data ) 119 | { 120 | for ( int i = 0; i < _size; i++ ) 121 | { 122 | _storage[i] = data[i] ^ ( _key1 + i % ( 1 + _key2 ) ); 123 | } 124 | } 125 | 126 | T _storage[_size] {}; 127 | }; 128 | } 129 | 130 | #define e(str) skCrypt_key(str, __TIME__[4], __TIME__[7]) 131 | #define skCrypt_key(str, key1, key2) []() { \ 132 | constexpr static auto crypted = skc::skCrypter \ 133 | >((skc::clean_type*)str); \ 134 | return crypted; }() 135 | -------------------------------------------------------------------------------- /entry.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "imports.h" 10 | #include "ia32.h" 11 | #include "definitions.h" 12 | #include "encrypt.h" 13 | #include "crt.h" 14 | #include "utils.h" 15 | #include "interface.h" 16 | #include "cache.h" 17 | #include "cleaning.h" 18 | 19 | __int64 __fastcall communication_handler( void *a1 ) 20 | { 21 | if ( !a1 || ex_get_previous_mode( ) != UserMode || reinterpret_cast< request_data * >( a1 )->unique != request_unique ) 22 | { 23 | return cache::o_function_qword_2( a1 ); 24 | } 25 | 26 | const auto request = reinterpret_cast< request_data * >( a1 ); 27 | 28 | switch ( request->code ) 29 | { 30 | case request_base: 31 | { 32 | base_request data { 0 }; 33 | 34 | if ( !utils::safe_copy( &data, request->data, sizeof( base_request ) ) ) 35 | { 36 | return 0; 37 | } 38 | 39 | if ( !data.name || !data.pid ) 40 | { 41 | return 0; 42 | } 43 | 44 | const auto base = utils::get_module_handle( data.pid, data.name ); 45 | 46 | if ( !base ) 47 | { 48 | return 0; 49 | } 50 | 51 | reinterpret_cast< base_request * > ( request->data )->handle = base; 52 | 53 | return request_success; 54 | } 55 | case request_write: 56 | { 57 | write_request data { 0 }; 58 | 59 | if ( !utils::safe_copy( &data, request->data, sizeof( write_request ) ) ) 60 | { 61 | return 0; 62 | } 63 | 64 | if ( !data.address || !data.pid || !data.buffer || !data.size ) 65 | { 66 | return 0; 67 | } 68 | 69 | PEPROCESS process; 70 | if ( ps_lookup_process_by_process_id( ( HANDLE )data.pid, &process ) == STATUS_SUCCESS ) 71 | { 72 | size_t bytes = 0; 73 | if ( MmCopyVirtualMemory( io_get_current_process( ), ( void * )reinterpret_cast< write_request * > ( request->data )->buffer, process, ( void * )data.address, data.size, KernelMode, &bytes ) != STATUS_SUCCESS || bytes != data.size ) 74 | { 75 | ObDereferenceObject( process ); 76 | return 0; 77 | } 78 | 79 | ObDereferenceObject( process ); 80 | } 81 | else 82 | { 83 | return 0; 84 | } 85 | 86 | return request_success; 87 | } 88 | case request_read: 89 | { 90 | read_request data { 0 }; 91 | 92 | if ( !utils::safe_copy( &data, request->data, sizeof( read_request ) ) ) 93 | { 94 | return 0; 95 | } 96 | 97 | if ( data.address >= 0x7FFFFFFFFFFF || data.address <= 0 || !data.address || !data.pid || !data.buffer || !data.size ) 98 | { 99 | return 0; 100 | } 101 | 102 | PEPROCESS process; 103 | if ( ps_lookup_process_by_process_id( ( HANDLE )data.pid, &process ) == STATUS_SUCCESS ) 104 | { 105 | size_t bytes = 0; 106 | if ( MmCopyVirtualMemory( process, ( void * )data.address, io_get_current_process( ), reinterpret_cast< write_request * > ( request->data )->buffer, data.size, KernelMode, &bytes ) != STATUS_SUCCESS || bytes != data.size ) 107 | { 108 | ObDereferenceObject( process ); 109 | return 0; 110 | } 111 | 112 | ObDereferenceObject( process ); 113 | } 114 | else 115 | { 116 | return 0; 117 | } 118 | 119 | return request_success; 120 | } 121 | case request_pattern: 122 | { 123 | pattern_request data { 0 }; 124 | 125 | if ( !utils::safe_copy( &data, request->data, sizeof( pattern_request ) ) ) 126 | { 127 | return 0; 128 | } 129 | 130 | PEPROCESS process; 131 | if ( ps_lookup_process_by_process_id( ( HANDLE )data.pid, &process ) == STATUS_SUCCESS ) 132 | { 133 | const auto o_process = utils::swap_process( ( uintptr_t )process ); 134 | 135 | if ( !o_process ) 136 | { 137 | utils::swap_process( ( uintptr_t )o_process ); 138 | 139 | ObDereferenceObject( process ); 140 | 141 | return 0; 142 | } 143 | 144 | const auto address = utils::find_pattern( data.base, data.signature ); 145 | 146 | utils::swap_process( o_process ); 147 | 148 | ObDereferenceObject( process ); 149 | 150 | if ( !address ) 151 | { 152 | return 0; 153 | } 154 | 155 | reinterpret_cast< pattern_request * > ( request->data )->address = address; 156 | } 157 | else 158 | { 159 | return 0; 160 | } 161 | 162 | return request_success; 163 | } 164 | case request_swap: 165 | { 166 | swap_request data { 0 }; 167 | 168 | if ( !utils::safe_copy( &data, request->data, sizeof( allocate_request ) ) ) 169 | { 170 | return 0; 171 | } 172 | 173 | if ( !data.src || !data.dst || !data.pid ) 174 | { 175 | return 0; 176 | } 177 | 178 | PEPROCESS process; 179 | if ( ps_lookup_process_by_process_id( ( HANDLE )data.pid, &process ) == STATUS_SUCCESS ) 180 | { 181 | const auto o_process = utils::swap_process( ( uintptr_t )process ); 182 | 183 | if ( !o_process ) 184 | { 185 | utils::swap_process( ( uintptr_t )o_process ); 186 | 187 | ObDereferenceObject( process ); 188 | 189 | return 0; 190 | } 191 | 192 | uintptr_t old = 0; 193 | 194 | *( void ** )&old = InterlockedExchangePointer( ( void ** )data.src, ( void * )data.dst ); 195 | 196 | utils::swap_process( ( uintptr_t )o_process ); 197 | 198 | ObDereferenceObject( process ); 199 | 200 | if ( !old ) 201 | { 202 | return 0; 203 | } 204 | 205 | reinterpret_cast< swap_request * > ( request->data )->old = old; 206 | 207 | return request_success; 208 | } 209 | 210 | return 0; 211 | } 212 | case request_allocate: 213 | { 214 | allocate_request data { 0 }; 215 | 216 | if ( !utils::safe_copy( &data, request->data, sizeof( allocate_request ) ) ) 217 | { 218 | return 0; 219 | } 220 | 221 | uintptr_t mdl = 0; 222 | const auto address = utils::allocate_kernel_memory( data.size, &mdl ); 223 | 224 | if ( !address ) 225 | { 226 | return 0; 227 | } 228 | 229 | if ( !mdl || !address ) 230 | { 231 | return 0; 232 | } 233 | 234 | reinterpret_cast< allocate_request * >( request->data )->mdl = mdl; 235 | reinterpret_cast< allocate_request * >( request->data )->address = address; 236 | 237 | return request_success; 238 | } 239 | case request_free: 240 | { 241 | free_request data { 0 }; 242 | 243 | if ( !utils::safe_copy( &data, request->data, sizeof( free_request ) ) ) 244 | { 245 | return 0; 246 | } 247 | 248 | if ( !data.mdl || !data.address ) 249 | { 250 | return 0; 251 | } 252 | 253 | MDL_INFORMATION mdl = { ( MDL * )data.mdl, ( uintptr_t )data.address }; 254 | 255 | utils::free_mdl_memory( mdl ); 256 | 257 | return request_success; 258 | } 259 | case request_expose: 260 | { 261 | expose_request data { 0 }; 262 | 263 | if ( !utils::safe_copy( &data, request->data, sizeof( expose_request ) ) ) 264 | { 265 | return 0; 266 | } 267 | 268 | if ( !data.pid || !data.address || !data.size ) 269 | { 270 | return 0; 271 | } 272 | 273 | if ( !utils::expose_kernel_memory( data.pid, (uintptr_t)data.address, data.size ) ) 274 | { 275 | return 0; 276 | } 277 | 278 | return request_success; 279 | } 280 | case request_unload: 281 | { 282 | *reinterpret_cast< unload_request * > ( request->data )->buffer = true; 283 | InterlockedExchangePointer( ( void ** ) dereference( cache::qword_address ), ( void * ) cache::o_qword_address ); 284 | InterlockedExchangePointer( ( void ** ) dereference( cache::function_qword_1 ), ( void * ) cache::o_function_qword_1 ); 285 | InterlockedExchangePointer( ( void ** ) dereference( cache::function_qword_2 ), ( void * ) cache::o_function_qword_2 ); 286 | return request_success; 287 | } 288 | } 289 | 290 | return 0; 291 | } 292 | 293 | NTSTATUS DriverEntry( const uintptr_t mdl, imports_t _imports ) 294 | { 295 | imports = _imports; 296 | const auto win32k = utils::get_kernel_module( e( "win32k.sys" ) ); 297 | 298 | cache::qword_address = utils::find_pattern( win32k, e( "\x48\x8B\x05\x95\xCD\x05\x00" ), e( "xxxxxxx" ) ); 299 | 300 | cache::function_qword_1 = utils::find_pattern( win32k, e( "\x48\x8B\x05\x11\xD7\x05\x00" ), e( "xxxxxxx" ) ); 301 | 302 | cache::function_qword_2 = utils::find_pattern( win32k, e( "\x48\x8B\x05\xA1\xD6\x05\x00" ), e( "xxxxxxx" ) ); 303 | 304 | *( void ** ) &cache::o_qword_address = InterlockedExchangePointer( ( void ** ) dereference( cache::qword_address ), ( void * ) utils::find_pattern( win32k, e( "\x48\x83\xEC\x28\x48\x8B\x05\x11\xD7" ), e( "xxxxxxxxx" ) ) ); 305 | 306 | *( void ** ) &cache::o_function_qword_1 = InterlockedExchangePointer( ( void ** ) dereference( cache::function_qword_1 ), ( void * ) utils::find_pattern( win32k, e( "\x48\x83\xEC\x28\x48\x8B\x05\xA1\xD6" ), e( "xxxxxxxxx" ) ) ); 307 | 308 | *( void ** ) &cache::o_function_qword_2 = InterlockedExchangePointer( ( void ** ) dereference( cache::function_qword_2 ), ( void * ) communication_handler ); 309 | 310 | if ( mdl ) 311 | { 312 | clean::null_pfn( reinterpret_cast< PMDL > ( mdl ) ); 313 | } 314 | 315 | return STATUS_SUCCESS; 316 | } -------------------------------------------------------------------------------- /imports.h: -------------------------------------------------------------------------------- 1 | struct imports_t 2 | { 3 | uintptr_t ps_lookup_process_by_process_id; 4 | uintptr_t io_get_current_process; 5 | uintptr_t mm_get_virtual_for_physical; 6 | uintptr_t mm_unmap_locked_pages; 7 | uintptr_t mm_free_pages_from_mdl; 8 | uintptr_t mm_map_locked_pages_specify_cache; 9 | uintptr_t mm_protect_mdl_system_address; 10 | uintptr_t mm_allocate_pages_for_mdl; 11 | uintptr_t mm_copy_memory; 12 | uintptr_t ex_get_previous_mode; 13 | }; 14 | 15 | imports_t imports; 16 | 17 | NTSTATUS ps_lookup_process_by_process_id( HANDLE ProcessId, PEPROCESS* Process ) 18 | { 19 | return reinterpret_cast< NTSTATUS( * )( HANDLE, PEPROCESS * ) > ( imports.ps_lookup_process_by_process_id )( ProcessId, Process ); 20 | } 21 | 22 | PEPROCESS io_get_current_process( ) 23 | { 24 | return reinterpret_cast< PEPROCESS( * )( ) > ( imports.io_get_current_process )( ); 25 | } 26 | 27 | PVOID mm_get_virtual_for_physical( PHYSICAL_ADDRESS PhysicalAddress ) 28 | { 29 | return reinterpret_cast< PVOID( * )( PHYSICAL_ADDRESS ) > ( imports.mm_get_virtual_for_physical )( PhysicalAddress ); 30 | } 31 | 32 | void mm_unmap_locked_pages( PVOID BaseAddress, PMDL MemoryDescriptorList ) 33 | { 34 | return reinterpret_cast< void( * )( PVOID, PMDL ) > ( imports.mm_unmap_locked_pages )( BaseAddress, MemoryDescriptorList ); 35 | } 36 | 37 | void mm_free_pages_from_mdl( PMDL MemoryDescriptorList ) 38 | { 39 | return reinterpret_cast< void( * )( PMDL ) > ( imports.mm_free_pages_from_mdl )( MemoryDescriptorList ); 40 | } 41 | 42 | PVOID mm_map_locked_pages_specify_cache( PMDL MemoryDescriptorList, KPROCESSOR_MODE AccessMode, MEMORY_CACHING_TYPE CacheType, PVOID RequestedAddress, ULONG BugCheckOnFailure, ULONG Priority ) 43 | { 44 | return reinterpret_cast< PVOID( * )( PMDL, KPROCESSOR_MODE, MEMORY_CACHING_TYPE, PVOID, ULONG, ULONG ) > ( imports.mm_map_locked_pages_specify_cache )( MemoryDescriptorList, AccessMode, CacheType, RequestedAddress, BugCheckOnFailure, Priority ); 45 | } 46 | 47 | NTSTATUS mm_protect_mdl_system_address( PMDL MemoryDescriptorList, ULONG NewProtect ) 48 | { 49 | return reinterpret_cast< NTSTATUS( * )( PMDL, ULONG ) > ( imports.mm_protect_mdl_system_address )( MemoryDescriptorList, NewProtect ); 50 | } 51 | 52 | PMDL mm_allocate_pages_for_mdl( PHYSICAL_ADDRESS LowAddress, PHYSICAL_ADDRESS HighAddress, PHYSICAL_ADDRESS SkipBytes, SIZE_T TotalBytes ) 53 | { 54 | return reinterpret_cast< PMDL( * )( PHYSICAL_ADDRESS, PHYSICAL_ADDRESS, PHYSICAL_ADDRESS, SIZE_T ) > ( imports.mm_allocate_pages_for_mdl )( LowAddress, HighAddress, SkipBytes, TotalBytes ); 55 | } 56 | 57 | NTSTATUS mm_copy_memory( PVOID TargetAddress, MM_COPY_ADDRESS SourceAddress, SIZE_T NumberOfBytes, ULONG Flags, PSIZE_T NumberOfBytesTransferred ) 58 | { 59 | return reinterpret_cast< NTSTATUS( * )( PVOID, MM_COPY_ADDRESS, SIZE_T, ULONG, PSIZE_T ) > ( imports.mm_allocate_pages_for_mdl )( TargetAddress, SourceAddress, NumberOfBytes, Flags, NumberOfBytesTransferred ); 60 | } 61 | 62 | KPROCESSOR_MODE ex_get_previous_mode( ) 63 | { 64 | return reinterpret_cast< KPROCESSOR_MODE( * )( ) >( imports.ex_get_previous_mode )( ); 65 | } -------------------------------------------------------------------------------- /interface.h: -------------------------------------------------------------------------------- 1 | typedef enum _request_codes 2 | { 3 | request_free = 0x109, 4 | request_base = 0x119, 5 | request_read = 0x129, 6 | request_write = 0x139, 7 | request_allocate = 0x149, 8 | request_expose = 0x159, 9 | request_swap = 0x169, 10 | request_pattern = 0x179, 11 | request_success = 0x91a, 12 | request_unique = 0x92b, 13 | request_unload = 0x93c, 14 | }request_codes, *prequest_codes; 15 | 16 | typedef struct _unload_request 17 | { 18 | bool *buffer; 19 | }unload_request, *punload_request; 20 | 21 | typedef struct _read_request { 22 | uint32_t pid; 23 | uintptr_t address; 24 | void *buffer; 25 | size_t size; 26 | } read_request, *pread_request; 27 | 28 | typedef struct _write_request { 29 | uint32_t pid; 30 | uintptr_t address; 31 | void *buffer; 32 | size_t size; 33 | } write_request, *pwrite_request; 34 | 35 | typedef struct _base_request { 36 | uint32_t pid; 37 | uintptr_t handle; 38 | WCHAR name[260]; 39 | } base_request, *pbase_request; 40 | 41 | typedef struct _swap_request 42 | { 43 | uint32_t pid; 44 | uintptr_t dst; 45 | uintptr_t src; 46 | uintptr_t old; 47 | }swap_request, *pswap_request; 48 | 49 | typedef struct _free_request 50 | { 51 | void *address; 52 | uintptr_t mdl; 53 | }free_request, *pfree_request; 54 | 55 | typedef struct _allocate_request 56 | { 57 | void *address; 58 | uintptr_t mdl; 59 | size_t size; 60 | }allocate_request, *pallocate_request; 61 | 62 | typedef struct _expose_request 63 | { 64 | void *address; 65 | size_t size; 66 | uint32_t pid; 67 | }expose_request, *pexpose_request; 68 | 69 | typedef struct _pattern_request 70 | { 71 | int pid; 72 | uintptr_t base; 73 | char signature[260]; 74 | uintptr_t address; 75 | }pattern_request, *ppattern_request; 76 | 77 | typedef struct _request_data 78 | { 79 | uint32_t unique; 80 | request_codes code; 81 | void *data; 82 | }request_data, *prequest_data; -------------------------------------------------------------------------------- /km.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 | 16.0 23 | Win32Proj 24 | {4c4c54e5-c199-4146-b5d7-fddc9fe74066} 25 | km 26 | 10.0 27 | kernel mode 28 | 29 | 30 | 31 | Application 32 | true 33 | v143 34 | Unicode 35 | 36 | 37 | Application 38 | false 39 | v143 40 | true 41 | Unicode 42 | 43 | 44 | Application 45 | true 46 | v143 47 | Unicode 48 | 49 | 50 | Driver 51 | false 52 | WindowsKernelModeDriver10.0 53 | true 54 | NotSet 55 | Windows10 56 | Universal 57 | KMDF 58 | 1 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | true 80 | 81 | 82 | false 83 | 84 | 85 | true 86 | 87 | 88 | false 89 | ..\builds 90 | ..\builds\logs 91 | kernel 92 | false 93 | 94 | 95 | 96 | Level3 97 | true 98 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 99 | true 100 | 101 | 102 | Console 103 | true 104 | 105 | 106 | 107 | 108 | Level3 109 | true 110 | true 111 | true 112 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 113 | true 114 | 115 | 116 | Console 117 | true 118 | true 119 | true 120 | 121 | 122 | 123 | 124 | Level3 125 | true 126 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 127 | true 128 | 129 | 130 | Console 131 | true 132 | 133 | 134 | 135 | 136 | TurnOffAllWarnings 137 | false 138 | true 139 | false 140 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 141 | false 142 | stdcpp20 143 | Default 144 | MaxSpeed 145 | AnySuitable 146 | true 147 | true 148 | Size 149 | true 150 | None 151 | true 152 | false 153 | false 154 | true 155 | 156 | 157 | Native 158 | true 159 | true 160 | false 161 | false 162 | $(SUBSYSTEM_NATVER) 163 | Driver 164 | DriverEntry 165 | 166 | 167 | true 168 | %(AdditionalDependencies) 169 | false 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | -------------------------------------------------------------------------------- /km.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /km.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Off 5 | 6 | -------------------------------------------------------------------------------- /utils.h: -------------------------------------------------------------------------------- 1 | namespace utils 2 | { 3 | uintptr_t swap_process( uintptr_t new_process ) 4 | { 5 | auto current_thread = ( uintptr_t )KeGetCurrentThread( ); 6 | 7 | auto apc_state = *( uintptr_t * )( current_thread + 0x98 ); 8 | auto old_process = *( uintptr_t * )( apc_state + 0x20 ); 9 | *( uintptr_t * )( apc_state + 0x20 ) = new_process; 10 | 11 | auto dir_table_base = *( uintptr_t * )( new_process + 0x28 ); 12 | __writecr3( dir_table_base ); 13 | 14 | return old_process; 15 | } 16 | 17 | uintptr_t resolve_relative_address( uintptr_t instruction, ULONG offset_offset, ULONG instruction_size ) 18 | { 19 | auto instr = instruction; 20 | 21 | const auto rip_offset = *( PLONG )( instr + offset_offset ); 22 | 23 | const auto resolved_addr = instr + instruction_size + rip_offset; 24 | 25 | return resolved_addr; 26 | } 27 | 28 | void *get_system_information( SYSTEM_INFORMATION_CLASS information_class ) 29 | { 30 | unsigned long size = 32; 31 | char buffer[32]; 32 | 33 | ZwQuerySystemInformation( information_class, buffer, size, &size ); 34 | 35 | void *info = ExAllocatePoolZero( NonPagedPool, size, 7265746172 ); 36 | 37 | if ( !info ) 38 | return nullptr; 39 | 40 | if ( !NT_SUCCESS( ZwQuerySystemInformation( information_class, info, size, &size ) ) ) 41 | { 42 | ExFreePool( info ); 43 | return nullptr; 44 | } 45 | 46 | return info; 47 | } 48 | 49 | uintptr_t get_kernel_module( const char *name ) 50 | { 51 | const auto to_lower = []( char *string ) -> const char * 52 | { 53 | for ( char *pointer = string; *pointer != '\0'; ++pointer ) 54 | { 55 | *pointer = ( char )( short )tolower( *pointer ); 56 | } 57 | 58 | return string; 59 | }; 60 | 61 | const PRTL_PROCESS_MODULES info = ( PRTL_PROCESS_MODULES )get_system_information( SystemModuleInformation ); 62 | 63 | if ( !info ) 64 | return NULL; 65 | 66 | for ( size_t i = 0; i < info->NumberOfModules; ++i ) 67 | { 68 | const auto &mod = info->Modules[i]; 69 | 70 | if ( crt::strcmp( to_lower_c( ( char * )mod.FullPathName + mod.OffsetToFileName ), name ) == 0 ) 71 | { 72 | const void *address = mod.ImageBase; 73 | ExFreePool( info ); 74 | return ( uintptr_t )address; 75 | } 76 | } 77 | 78 | ExFreePool( info ); 79 | return NULL; 80 | } 81 | 82 | auto get_kernel_export( const char *module_name, LPCSTR export_name ) -> uintptr_t 83 | { 84 | return reinterpret_cast< uintptr_t > ( RtlFindExportedRoutineByName( reinterpret_cast< void * > ( utils::get_kernel_module( module_name ) ), export_name ) ); 85 | } 86 | 87 | void sleep( int ms ) 88 | { 89 | LARGE_INTEGER time; 90 | time.QuadPart = -( ms ) * 10 * 1000; 91 | KeDelayExecutionThread( KernelMode, TRUE, &time ); 92 | } 93 | 94 | uintptr_t find_pattern( uintptr_t base, size_t range, const char *pattern, const char *mask ) 95 | { 96 | const auto check_mask = []( const char *base, const char *pattern, const char *mask ) -> bool 97 | { 98 | for ( ; *mask; ++base, ++pattern, ++mask ) 99 | { 100 | if ( *mask == 'x' && *base != *pattern ) 101 | { 102 | return false; 103 | } 104 | } 105 | 106 | return true; 107 | }; 108 | 109 | range = range - crt::strlen( mask ); 110 | 111 | for ( size_t i = 0; i < range; ++i ) 112 | { 113 | if ( check_mask( ( const char * )base + i, pattern, mask ) ) 114 | { 115 | return base + i; 116 | } 117 | } 118 | 119 | return NULL; 120 | } 121 | 122 | uintptr_t find_pattern( uintptr_t base, const char *pattern, const char *mask ) 123 | { 124 | const PIMAGE_NT_HEADERS headers = ( PIMAGE_NT_HEADERS )( base + ( ( PIMAGE_DOS_HEADER )base )->e_lfanew ); 125 | const PIMAGE_SECTION_HEADER sections = IMAGE_FIRST_SECTION( headers ); 126 | 127 | for ( size_t i = 0; i < headers->FileHeader.NumberOfSections; i++ ) 128 | { 129 | const PIMAGE_SECTION_HEADER section = §ions[i]; 130 | 131 | if ( section->Characteristics & IMAGE_SCN_MEM_EXECUTE ) 132 | { 133 | const auto match = find_pattern( base + section->VirtualAddress, section->Misc.VirtualSize, pattern, mask ); 134 | 135 | if ( match ) 136 | { 137 | return match; 138 | } 139 | } 140 | } 141 | 142 | return 0; 143 | } 144 | 145 | uintptr_t find_pattern( uintptr_t module_base, const char* pattern ) 146 | { 147 | auto pattern_ = pattern; 148 | uintptr_t first_match = 0; 149 | 150 | if ( !module_base ) 151 | { 152 | return 0; 153 | } 154 | 155 | const auto nt = reinterpret_cast< IMAGE_NT_HEADERS * >( module_base + reinterpret_cast< IMAGE_DOS_HEADER * >( module_base )->e_lfanew ); 156 | 157 | for ( uintptr_t current = module_base; current < module_base + nt->OptionalHeader.SizeOfImage; current++ ) 158 | { 159 | if ( !*pattern_ ) 160 | { 161 | return first_match; 162 | } 163 | 164 | if ( *( BYTE * )pattern_ == '\?' || *( BYTE * )current == get_byte( pattern_ ) ) 165 | { 166 | if ( !first_match ) 167 | first_match = current; 168 | 169 | if ( !pattern_[2] ) 170 | return first_match; 171 | 172 | if ( *( WORD * )pattern_ == '\?\?' || *( BYTE * )pattern_ != '\?' ) 173 | pattern_ += 3; 174 | 175 | else 176 | pattern_ += 2; 177 | } 178 | else 179 | { 180 | pattern_ = pattern; 181 | first_match = 0; 182 | } 183 | } 184 | 185 | return 0; 186 | } 187 | 188 | uintptr_t get_module_handle( uintptr_t pid, LPCWSTR module_name ) 189 | { 190 | PEPROCESS target_proc; 191 | uintptr_t base = 0; 192 | if ( !NT_SUCCESS( ps_lookup_process_by_process_id( ( HANDLE )pid, &target_proc ) ) ) 193 | return 0; 194 | 195 | const auto o_process = swap_process( ( uintptr_t )target_proc ); 196 | 197 | PPEB peb = PsGetProcessPeb( target_proc ); 198 | if ( !peb ) 199 | goto end; 200 | 201 | if ( !peb->Ldr || !peb->Ldr->Initialized ) 202 | goto end; 203 | 204 | 205 | UNICODE_STRING module_name_unicode; 206 | RtlInitUnicodeString( &module_name_unicode, module_name ); 207 | for ( PLIST_ENTRY list = peb->Ldr->InLoadOrderModuleList.Flink; 208 | list != &peb->Ldr->InLoadOrderModuleList; 209 | list = list->Flink ) { 210 | PLDR_DATA_TABLE_ENTRY entry = CONTAINING_RECORD( list, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks ); 211 | if ( RtlCompareUnicodeString( &entry->BaseDllName, &module_name_unicode, TRUE ) == 0 ) { 212 | base = ( uintptr_t )entry->DllBase; 213 | goto end; 214 | } 215 | } 216 | 217 | end: 218 | 219 | swap_process( ( uintptr_t )o_process ); 220 | 221 | ObDereferenceObject( target_proc ); 222 | 223 | return base; 224 | } 225 | 226 | bool safe_copy( void* dst, void *src, size_t size ) 227 | { 228 | SIZE_T bytes = 0; 229 | 230 | if ( MmCopyVirtualMemory( io_get_current_process( ), src, io_get_current_process( ), dst, size, KernelMode, &bytes ) == STATUS_SUCCESS && bytes == size ) 231 | { 232 | return true; 233 | } 234 | 235 | return false; 236 | } 237 | 238 | MEMORY_BASIC_INFORMATION query_virtual_memory( void* address ) 239 | { 240 | MEMORY_BASIC_INFORMATION mbi; 241 | ZwQueryVirtualMemory( ( HANDLE )-1, address, MemoryBasicInformation, &mbi, sizeof( MEMORY_BASIC_INFORMATION ), 0 ); 242 | return mbi; 243 | } 244 | 245 | PAGE_INFORMATION get_page_information( void *va, CR3 cr3 ) 246 | { 247 | ADDRESS_TRANSLATION_HELPER helper; 248 | UINT32 level; 249 | PML4E_64 *pml4, *pml4e; 250 | PDPTE_64 *pdpt, *pdpte; 251 | PDE_64 *pd, *pde; 252 | PTE_64 *pt, *pte; 253 | 254 | PAGE_INFORMATION info; 255 | 256 | helper.AsUInt64 = ( uintptr_t )va; 257 | 258 | PHYSICAL_ADDRESS pa; 259 | 260 | pa.QuadPart = cr3.AddressOfPageDirectory << PAGE_SHIFT; 261 | 262 | pml4 = ( PML4E_64 * )mm_get_virtual_for_physical( pa ); 263 | 264 | pml4e = &pml4[helper.AsIndex.Pml4]; 265 | 266 | info.PML4E = pml4e; 267 | 268 | if ( pml4e->Present == FALSE ) 269 | { 270 | info.PTE = nullptr; 271 | info.PDE = nullptr; 272 | info.PDPTE = nullptr; 273 | 274 | goto end; 275 | } 276 | 277 | pa.QuadPart = pml4e->PageFrameNumber << PAGE_SHIFT; 278 | 279 | pdpt = ( PDPTE_64 * )mm_get_virtual_for_physical( pa ); 280 | 281 | pdpte = &pdpt[helper.AsIndex.Pdpt]; 282 | 283 | info.PDPTE = pdpte; 284 | 285 | if ( ( pdpte->Present == FALSE ) || ( pdpte->LargePage != FALSE ) ) 286 | { 287 | info.PTE = nullptr; 288 | info.PDE = nullptr; 289 | 290 | goto end; 291 | } 292 | 293 | pa.QuadPart = pdpte->PageFrameNumber << PAGE_SHIFT; 294 | 295 | pd = ( PDE_64 * )mm_get_virtual_for_physical( pa ); 296 | 297 | pde = &pd[helper.AsIndex.Pd]; 298 | 299 | info.PDE = pde; 300 | 301 | if ( ( pde->Present == FALSE ) || ( pde->LargePage != FALSE ) ) 302 | { 303 | info.PTE = nullptr; 304 | 305 | goto end; 306 | } 307 | 308 | pa.QuadPart = pde->PageFrameNumber << PAGE_SHIFT; 309 | 310 | pt = ( PTE_64 * )mm_get_virtual_for_physical( pa ); 311 | 312 | pte = &pt[helper.AsIndex.Pt]; 313 | 314 | info.PTE = pte; 315 | 316 | return info; 317 | 318 | end: 319 | return info; 320 | } 321 | 322 | MDL_INFORMATION allocate_mdl_memory( size_t size ) 323 | { 324 | MDL_INFORMATION memory; 325 | 326 | PHYSICAL_ADDRESS lower, higher; 327 | lower.QuadPart = 0; 328 | higher.QuadPart = 0xffff'ffff'ffff'ffffULL; 329 | 330 | const auto pages = ( size / PAGE_SIZE ) + 1; 331 | 332 | const auto mdl = mm_allocate_pages_for_mdl( lower, higher, lower, pages * ( uintptr_t )0x1000 ); 333 | 334 | if ( !mdl ) 335 | { 336 | return { 0, 0 }; 337 | } 338 | 339 | const auto mapping_start_address = mm_map_locked_pages_specify_cache( mdl, KernelMode, MmCached, NULL, FALSE, NormalPagePriority ); 340 | 341 | if ( !mapping_start_address ) 342 | { 343 | return { 0, 0 }; 344 | } 345 | 346 | if ( !NT_SUCCESS( mm_protect_mdl_system_address( mdl, PAGE_EXECUTE_READWRITE ) ) ) 347 | { 348 | return { 0, 0 }; 349 | } 350 | 351 | memory.mdl = mdl; 352 | memory.va = reinterpret_cast ( mapping_start_address ); 353 | 354 | return memory; 355 | } 356 | 357 | void free_mdl_memory( MDL_INFORMATION &memory ) 358 | { 359 | mm_unmap_locked_pages( reinterpret_cast< void * >( memory.va ), memory.mdl ); 360 | mm_free_pages_from_mdl( memory.mdl ); 361 | ExFreePool( memory.mdl ); 362 | } 363 | 364 | void* allocate_kernel_memory( const size_t _size, uintptr_t* mdl ) 365 | { 366 | const auto size = size_align( _size ); 367 | 368 | auto memory = allocate_mdl_memory( size ); 369 | 370 | while ( memory.va % 0x10000 != 0 ) 371 | { 372 | free_mdl_memory( memory ); 373 | memory = allocate_mdl_memory( size ); 374 | } 375 | 376 | *mdl = (uintptr_t)memory.mdl; 377 | return (void*)memory.va; 378 | } 379 | 380 | bool expose_kernel_memory( const int pid, const uintptr_t kernel_address, const size_t size ) 381 | { 382 | PEPROCESS process; 383 | if ( ps_lookup_process_by_process_id( ( HANDLE )pid, &process ) == STATUS_SUCCESS ) 384 | { 385 | const auto o_process = utils::swap_process( ( uintptr_t )process ); 386 | 387 | CR3 cr3 { }; 388 | cr3.Flags = __readcr3( ); 389 | 390 | for ( uintptr_t address = kernel_address; address <= kernel_address + size; address += 0x1000 ) 391 | { 392 | const auto page_information = utils::get_page_information( ( void * )address, cr3 ); 393 | 394 | page_information.PDE->Supervisor = 1; 395 | page_information.PDPTE->Supervisor = 1; 396 | page_information.PML4E->Supervisor = 1; 397 | 398 | if ( !page_information.PDE || ( page_information.PTE && !page_information.PTE->Present ) ) 399 | { 400 | 401 | } 402 | else 403 | { 404 | page_information.PTE->Supervisor = 1; 405 | } 406 | } 407 | 408 | utils::swap_process( ( uintptr_t )o_process ); 409 | } 410 | else 411 | { 412 | return false; 413 | } 414 | 415 | return true; 416 | } 417 | } --------------------------------------------------------------------------------