Add materials for final part of series, part 3

This commit is contained in:
aliz
2019-09-19 16:09:43 +08:00
parent 80a9c34e0d
commit ca714e6c58
13 changed files with 1176 additions and 0 deletions
+307
View File
@@ -0,0 +1,307 @@
#include "pch.h"
#include <windows.h>
#include <psapi.h>
#include <tlhelp32.h>
#include <iostream>
#include <vector>
#include <map>
#include "..\driver\public.h"
#include "findPFNDatabase.h"
class statistics {
public:
statistics()
{
scannedPages = ignoredPagesNX = scannedProcesses = modifiedPages = 0;
}
unsigned int scannedPages;
unsigned int ignoredPagesNX;
unsigned int scannedProcesses;
unsigned int modifiedPages;
};
class modifiedPage {
public:
modifiedPage(DWORD newProcessID, wchar_t* newModuleName, void* newPageBase, BYTE newSectionName[8], unsigned long long newSectionOffset);
unsigned long processID;
std::wstring moduleName;
unsigned long long pageBase;
std::wstring sectionName;
unsigned long long sectionOffset;
};
modifiedPage::modifiedPage(DWORD newProcessID, wchar_t* newModuleName, void* newPageBase, BYTE newSectionName[8], unsigned long long newSectionOffset)
: processID(newProcessID), moduleName(newModuleName), pageBase((unsigned long long)newPageBase), sectionName(L""), sectionOffset(newSectionOffset)
{
wchar_t sectionNameCleaned[9];
memset(sectionNameCleaned, 0, 9 * sizeof(wchar_t));
wsprintf(sectionNameCleaned, L"%.8s", newSectionName);
sectionName.append(sectionNameCleaned);
}
BOOL EnableDebugPrivilege(BOOL bEnable)
{
HANDLE hToken = nullptr;
LUID luid;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) return FALSE;
if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) return FALSE;
TOKEN_PRIVILEGES tokenPriv;
tokenPriv.PrivilegeCount = 1;
tokenPriv.Privileges[0].Luid = luid;
tokenPriv.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : 0;
if (!AdjustTokenPrivileges(hToken, FALSE, &tokenPriv, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) return FALSE;
return TRUE;
}
int scanProcess(HANDLE driverHnd, DWORD targetPID, HANDLE toScanHandle, std::vector<modifiedPage> *resultsOut, statistics* stats)
{
DWORD cbNeeded;
int s = EnumProcessModules(toScanHandle, NULL, 0, &cbNeeded);
if (s == 0)
{
printf("Couldn't call EnumProcessModules to get buffer size, gle %d\n", GetLastError());
return -1;
}
HMODULE* moduleList = (HMODULE*)malloc(cbNeeded);
memset(moduleList, 0, cbNeeded);
s = EnumProcessModules(toScanHandle, moduleList, cbNeeded, &cbNeeded);
if (s == 0)
{
// This'll happen sometimes if there's a module loaded between our calls.
// TODO: we can retry in this case.
printf("Couldn't call EnumProcessModules to get modules, gle %d.\n", GetLastError());
return -1;
}
for (HMODULE* thisModPtr = &moduleList[0]; thisModPtr < &moduleList[cbNeeded / sizeof(HMODULE)]; thisModPtr++)
{
HMODULE thisModule = *thisModPtr;
TCHAR szModName[MAX_PATH];
memset(szModName, 0, MAX_PATH * sizeof(TCHAR));
if (GetModuleFileNameEx(toScanHandle, thisModule, szModName, sizeof(szModName) / sizeof(TCHAR)) == 0)
{
printf("GetModuleFileNameEx failed, GLE %d\n", GetLastError());
continue;
}
IMAGE_DOS_HEADER mz;
SIZE_T bytesRead;
if (!ReadProcessMemory(toScanHandle, thisModule, &mz, sizeof(IMAGE_DOS_HEADER), &bytesRead))
{
printf("Can't read module MZ header\n");
return -1;
}
if (mz.e_magic != IMAGE_DOS_SIGNATURE)
{
printf("MZ header not found\n");
continue;
}
IMAGE_NT_HEADERS pe;
unsigned long long peAddress = (((unsigned long long)thisModule) + mz.e_lfanew);
if (!ReadProcessMemory(toScanHandle, (void*)peAddress, &pe, sizeof(IMAGE_NT_HEADERS), &bytesRead))
{
printf("Can't read module PE header\n");
return -1;
}
if (pe.Signature != IMAGE_NT_SIGNATURE)
{
printf("PE header not found\n");
continue;
}
IMAGE_SECTION_HEADER* sect;
unsigned long long firstSectionAddress = peAddress + FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader) + sizeof(IMAGE_OPTIONAL_HEADER);
sect = (IMAGE_SECTION_HEADER*)malloc(sizeof(IMAGE_SECTION_HEADER) * pe.FileHeader.NumberOfSections);
if (!ReadProcessMemory(toScanHandle, (LPCVOID)(firstSectionAddress), sect, sizeof(IMAGE_SECTION_HEADER) * pe.FileHeader.NumberOfSections, &bytesRead))
{
printf("Can't read first section of module\n");
return -1;
}
for (unsigned long sectionIndex = 0; sectionIndex < pe.FileHeader.NumberOfSections; sectionIndex++)
{
IMAGE_SECTION_HEADER* thisSection = &sect[sectionIndex];
unsigned long long relocatedSectionBase = thisSection->VirtualAddress + (unsigned long long)thisModule;
// We are interested only in executable sections.
// TODO: check that discardable pages are zero'ed out?
// TODO: check that non-executable pages haven't been made executable?
if ((thisSection->Characteristics & IMAGE_SCN_MEM_EXECUTE) == 0)
{
stats->ignoredPagesNX += (thisSection->SizeOfRawData / 0x1000);
// printf("%ls!%s (at %p) is not executable, skipping\n", szModName, thisSection->Name, relocatedSectionBase);
continue;
}
//printf("scanning %ls!%s (at %p), size 0x%08lx\n", szModName, thisSection->Name, relocatedSectionBase, thisSection->SizeOfRawData);
int dirtyPages = 0;
int errorPages = 0;
getPageInfoRequest req;
req.pageToCheck = relocatedSectionBase;
// Work out how many pages we will check
req.numberOfPagesToCheck = thisSection->Misc.VirtualSize / 0x1000;
if (thisSection->Misc.VirtualSize % 0x1000 != 0)
req.numberOfPagesToCheck++;
req.targetPID = targetPID;
getPageInfoResponse* resp = (getPageInfoResponse*)malloc(sizeof(getPageInfoRequest) * req.numberOfPagesToCheck);
memset(resp, 0x00, sizeof(getPageInfoResponse) * req.numberOfPagesToCheck);
DWORD bytesRet;
s = DeviceIoControl(driverHnd, IOCTL_DRIVER_QUERY_VA, &req, sizeof(req), resp, sizeof(getPageInfoResponse) * req.numberOfPagesToCheck, &bytesRet, NULL);
if (s == 0)
{
errorPages++;
printf("DeviceIoControl failed, GLE %d\n", GetLastError());
return -1;
}
stats->scannedPages += req.numberOfPagesToCheck;
for (unsigned int n = 0; n < req.numberOfPagesToCheck; n++)
{
unsigned long long pageAddress = relocatedSectionBase + (n * 0x1000);
if (!resp[n].isValid)
{
printf("Page at 0x%016llx (%ls!%s) not valid (maybe it's paged out?) 0x%08lx\n", pageAddress, szModName, thisSection->Name, thisSection->Characteristics);
errorPages++;
continue;
}
if (resp[n].isDirty)
{
dirtyPages++;
resultsOut->push_back(modifiedPage(targetPID, (wchar_t*)szModName, (void*)pageAddress, thisSection->Name, (pageAddress - relocatedSectionBase)));
stats->modifiedPages++;
}
}
// if (dirtyPages == 0)
// printf("Module %ls: OK\n", szModName);
// else
// printf("Module %ls: detected %d dirty pages!\n", szModName, dirtyPages);
}
}
return 0;
}
int setPFNDatabase(HANDLE driverHnd, unsigned long long PFNDatabaseStart)
{
setPFNDatabaseRequest req;
req.offsetToMmPfnDatabaseInNtDllFromExAllocatePoolWithTag = PFNDatabaseStart;
DWORD bytesRet;
int s = DeviceIoControl(driverHnd, IOCTL_DRIVER_SET_PFN_DATABASE, &req, sizeof(req), NULL, 0, &bytesRet, NULL);
if (s == 0)
{
printf("Failed to set PFN database to 0x%016llx: GLE %d\n", PFNDatabaseStart, GetLastError());
return -1;
}
return 0;
}
int main()
{
EnableDebugPrivilege(TRUE);
HANDLE driverHnd = CreateFile(L"\\\\.\\cowspot", GENERIC_ALL, 0, NULL, OPEN_EXISTING, 0, NULL);
if (driverHnd == INVALID_HANDLE_VALUE)
{
printf("Couldn't open driver device '%ls', gle %d\n", DOS_DEVICE_NAME, GetLastError());
return -1;
}
if (setPFNDatabase(driverHnd, findPFNDatabase()) != 0)
return -1;
HANDLE snapshotHnd = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
if (snapshotHnd == INVALID_HANDLE_VALUE)
{
printf("CreateToolhelp32Snapshot failed, GLE %d\n", GetLastError());
return -1;
}
PROCESSENTRY32 proc;
memset(&proc, 0, sizeof(PROCESSENTRY32));
proc.dwSize = sizeof(PROCESSENTRY32);
if (!Process32First(snapshotHnd, &proc))
{
printf("Process32First failed, GLE %d\n", GetLastError());
return -1;
}
statistics stat;
std::vector<modifiedPage> results;
unsigned long start = GetTickCount();
while (Process32Next(snapshotHnd, &proc))
{
HANDLE toScanHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, proc.th32ProcessID);
if (toScanHandle == NULL)
{
printf("Couldn't open target process with PID %d ('%ls'), gle %d\n", proc.th32ProcessID, proc.szExeFile, GetLastError());
continue;
}
stat.scannedProcesses++;
if (scanProcess(driverHnd, proc.th32ProcessID, toScanHandle, &results, &stat) != 0)
printf("Failed to scan process '%ls'\n", proc.szExeFile);
// else
// printf("Scanned process '%ls'\n", proc.szExeFile);
CloseHandle(toScanHandle);
}
CloseHandle(snapshotHnd);
unsigned long end = GetTickCount();
printf("Scan took %dms\n", (end - start));
// Print some stats and the results.
printf("Scanned %d pages, ignored %d NX pages (total %d). Found %d modified pages.\n", stat.scannedPages, stat.ignoredPagesNX, stat.ignoredPagesNX + stat.scannedPages, stat.modifiedPages);
for (unsigned int n = 0; n < results.size(); n++)
{
modifiedPage thisModifiedPage = results[n];
printf("PID %04d module '%ls', section %S, offset 0x%08llux\n", thisModifiedPage.processID, thisModifiedPage.moduleName.c_str(), thisModifiedPage.sectionName.c_str(), thisModifiedPage.sectionOffset);
/*
HANDLE toScanHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, thisModifiedPage.processID);
if (toScanHandle == NULL)
{
printf("Couldn't open target process with PID %d ('%ls'), gle %d\n", proc.th32ProcessID, proc.szExeFile, GetLastError());
continue;
}
SIZE_T bytesRead;
unsigned char* pageContents[0x2000];
memset(pageContents, 0, 0x2000);
if (!ReadProcessMemory(toScanHandle, (LPCVOID)thisModifiedPage.pageBase, pageContents, 0x2000, &bytesRead))
{
printf("ReadProcessMemory failed\n");
continue;
}
for (unsigned int n = 0; n < 0x2001; n++)
{
printf("0x%02hhx ", (unsigned)pageContents[n]);
if (n % 0x10 == 0)
printf("\n0x%08lx: ", n);
}
CloseHandle(toScanHandle);*/
}
return 0;
}
+182
View File
@@ -0,0 +1,182 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.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">
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{BBBF57E1-3EC9-4C5C-8305-AD434ED61842}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>UI</RootNamespace>
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<SpectreMitigation>false</SpectreMitigation>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<SpectreMitigation>false</SpectreMitigation>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<SpectreMitigation>false</SpectreMitigation>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<SpectreMitigation>false</SpectreMitigation>
</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 Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>$(VSInstallDir)\DIA SDK\Include;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>$(VSInstallDir)\DIA SDK\Include;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>$(VSInstallDir)\DIA SDK\Include;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>$(VSInstallDir)\DIA SDK\Include;$(IncludePath)</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="findPFNDatabase.h" />
<ClInclude Include="pch.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="findPFNDatabase.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="UI.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
+106
View File
@@ -0,0 +1,106 @@
#include "pch.h"
#include <stdio.h>
#include <windows.h>
#include <dia2.h>
#include <string>
unsigned long findSymbol(IDiaSymbol* g_pGlobalSymbol, const wchar_t* symbolName);
unsigned long long findPFNDatabase()
{
IDiaDataSource *g_pDiaDataSource;
IDiaSession *g_pDiaSession;
IDiaSymbol *g_pGlobalSymbol;
// Assemble the path to ntoskrnl.exe. It'll be in System32.
wchar_t systemDir[MAX_PATH];
GetSystemDirectory(systemDir, MAX_PATH);
std::wstring exeFilename(L"");
exeFilename.append(systemDir);
exeFilename.append(L"\\ntoskrnl.exe");
// Assemble the symbol path. We use the current directory as a cache path.
wchar_t curPath[MAX_PATH];
GetCurrentDirectory(MAX_PATH, curPath);
std::wstring symPath(L"");
symPath.append(L"symsrv*symsrv.dll*");
symPath.append(curPath);
symPath.append(L"*http://msdl.microsoft.com/download/symbols");
HRESULT hr = CoInitialize(NULL);
hr = CoCreateInstance(__uuidof(DiaSource), NULL, CLSCTX_INPROC_SERVER, __uuidof(IDiaDataSource), (void **)&g_pDiaDataSource);
if (FAILED(hr))
{
printf("CoCreateInstance failed for UUID of IDiaDataSource - HRESULT is %08X\n", hr);
if (hr == REGDB_E_CLASSNOTREG)
printf("This means the DIA class is not registered. You may need to register it via regsvr32.\n");
return false;
}
printf("Loading PDBs..\n");
hr = g_pDiaDataSource->loadDataForExe(exeFilename.c_str(), symPath.c_str(), NULL);
if (FAILED(hr))
{
printf("loadDataForExe failed for file '%ls' - HRESULT is %08X\n", exeFilename.c_str(), hr);
if (hr == E_PDB_NOT_FOUND)
printf("This is E_PDB_NOT_FOUND. Check that you have internet connectivity, and the correct symbol server configured.\n");
return false;
}
printf("Loading PDBs complete.\n");
hr = (g_pDiaDataSource)->openSession(&g_pDiaSession);
if (FAILED(hr))
{
printf("openSession failed - HRESULT is %08X\n", hr);
return false;
}
g_pDiaSession->put_loadAddress(0x0);
hr = (g_pDiaSession)->get_globalScope(&g_pGlobalSymbol);
if (hr != S_OK)
{
printf("get_globalScope failed\n");
return false;
}
// Now we can resolve the symbols we want.
unsigned long long MmPFNDatabase = findSymbol(g_pGlobalSymbol, L"MmPfnDatabase");
unsigned long long ExAllocatePoolWithTag = findSymbol(g_pGlobalSymbol, L"ExAllocatePoolWithTag");
if (MmPFNDatabase == 0)
printf("Unable to resolve MmPFNDatabase");
if (ExAllocatePoolWithTag == 0)
printf("Unable to resolve ExAllocatePoolWithTag");
if (MmPFNDatabase == 0 || ExAllocatePoolWithTag == 0)
return false;
return ExAllocatePoolWithTag - MmPFNDatabase;
}
unsigned long findSymbol(IDiaSymbol* g_pGlobalSymbol, const wchar_t* symbolName)
{
IDiaEnumSymbols *pEnumSymbols;
if (FAILED(g_pGlobalSymbol->findChildren(SymTagPublicSymbol, symbolName, nsNone, &pEnumSymbols)))
return false;
IDiaSymbol *pCompiland;
unsigned long celt;
if (FAILED(pEnumSymbols->Next(1, &pCompiland, &celt)) || (celt != 1))
return false;
unsigned long symRVA;
pCompiland->get_relativeVirtualAddress(&symRVA);
pCompiland->Release();
pEnumSymbols->Release();
return symRVA;
}
+1
View File
@@ -0,0 +1 @@
unsigned long long findPFNDatabase();
+1
View File
@@ -0,0 +1 @@
#include "pch.h"
BIN
View File
Binary file not shown.
+20
View File
@@ -3,6 +3,10 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28010.2046
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "driver", "driver\driver.vcxproj", "{65A559E4-6946-4252-BFBE-C3B5D1B8108C}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UI", "UI\UI.vcxproj", "{BBBF57E1-3EC9-4C5C-8305-AD434ED61842}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "inject", "inject\inject.vcxproj", "{35928C18-5D5D-4BC6-88CE-E5BBE00C0446}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "inject_simple", "inject_simple\inject_simple.vcxproj", "{5C90611E-0874-4618-9C3D-B1385C83FBDF}"
@@ -17,6 +21,22 @@ Global
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{65A559E4-6946-4252-BFBE-C3B5D1B8108C}.Debug|x64.ActiveCfg = Debug|x64
{65A559E4-6946-4252-BFBE-C3B5D1B8108C}.Debug|x64.Build.0 = Debug|x64
{65A559E4-6946-4252-BFBE-C3B5D1B8108C}.Debug|x64.Deploy.0 = Debug|x64
{65A559E4-6946-4252-BFBE-C3B5D1B8108C}.Debug|x86.ActiveCfg = Debug|x64
{65A559E4-6946-4252-BFBE-C3B5D1B8108C}.Release|x64.ActiveCfg = Release|x64
{65A559E4-6946-4252-BFBE-C3B5D1B8108C}.Release|x64.Build.0 = Release|x64
{65A559E4-6946-4252-BFBE-C3B5D1B8108C}.Release|x64.Deploy.0 = Release|x64
{65A559E4-6946-4252-BFBE-C3B5D1B8108C}.Release|x86.ActiveCfg = Release|x64
{BBBF57E1-3EC9-4C5C-8305-AD434ED61842}.Debug|x64.ActiveCfg = Debug|x64
{BBBF57E1-3EC9-4C5C-8305-AD434ED61842}.Debug|x64.Build.0 = Debug|x64
{BBBF57E1-3EC9-4C5C-8305-AD434ED61842}.Debug|x86.ActiveCfg = Debug|Win32
{BBBF57E1-3EC9-4C5C-8305-AD434ED61842}.Debug|x86.Build.0 = Debug|Win32
{BBBF57E1-3EC9-4C5C-8305-AD434ED61842}.Release|x64.ActiveCfg = Release|x64
{BBBF57E1-3EC9-4C5C-8305-AD434ED61842}.Release|x64.Build.0 = Release|x64
{BBBF57E1-3EC9-4C5C-8305-AD434ED61842}.Release|x86.ActiveCfg = Release|Win32
{BBBF57E1-3EC9-4C5C-8305-AD434ED61842}.Release|x86.Build.0 = Release|Win32
{35928C18-5D5D-4BC6-88CE-E5BBE00C0446}.Debug|x64.ActiveCfg = Debug|x64
{35928C18-5D5D-4BC6-88CE-E5BBE00C0446}.Debug|x64.Build.0 = Debug|x64
{35928C18-5D5D-4BC6-88CE-E5BBE00C0446}.Debug|x86.ActiveCfg = Debug|Win32
Binary file not shown.
+395
View File
@@ -0,0 +1,395 @@
#include <Ntifs.h>
#include <Ntddk.h>
//#include <aux_klib.h>
#include "driver.h"
#include "public.h"
_Use_decl_annotations_ DRIVER_INITIALIZE DriverEntry;
_Use_decl_annotations_ DRIVER_UNLOAD DriverUnload;
_Dispatch_type_(IRP_MJ_CREATE) DRIVER_DISPATCH irp_mj_create;
_Dispatch_type_(IRP_MJ_CLOSE) DRIVER_DISPATCH irp_mj_close;
_Dispatch_type_(IRP_MJ_DEVICE_CONTROL) DRIVER_DISPATCH irp_mj_device_control;
NTSTATUS queryVA(getPageInfoRequest* params, getPageInfoResponse* response);
NTSTATUS queryVAFromIRP(PIRP Irp);
NTSTATUS setPFNDatabase(setPFNDatabaseRequest* req);
NTSTATUS setPFNDatabaseFromIRP(PIRP Irp);
int isTableEntryValid(unsigned long long entry);
unsigned long long getChildTableFromTableEntry(unsigned long long entry);
__drv_requiresIRQL(APC_LEVEL) NTSTATUS readMemoryFromPhysical(unsigned long long address, char* errMsg, void* tableOut);
privateInfo prv;
// TODO: Get PFN structure info via PDBs instead of hardcoding it here.
struct PFN
{
// 0x00
unsigned long long padding1;
// 0x08
unsigned long long PTEAddress;
// 0x10
unsigned long long OriginalPte;
// 0x18
unsigned long long u2;
// 0x20 - u3
unsigned short referenceCount;
unsigned char e1;
unsigned char e3;
unsigned long e4; // or e2
// 0x28
unsigned long long u4;
};
_Use_decl_annotations_ NTSTATUS DriverEntry(_In_ struct _DRIVER_OBJECT *DriverObject, _In_ PUNICODE_STRING RegistryPath)
{
NTSTATUS s;
UNICODE_STRING deviceName;
UNICODE_STRING DOSDeviceName;
UNREFERENCED_PARAMETER(RegistryPath);
DriverObject->DriverUnload = DriverUnload;
DriverObject->MajorFunction[IRP_MJ_CREATE] = irp_mj_create;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = irp_mj_close;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = irp_mj_device_control;
// Initialise our 'private' data, shared throughout the driver
memset(&prv, 0, sizeof(privateInfo));
// Create our device and the DOS symlink to it, as usual
RtlInitUnicodeString(&deviceName, DEVICE_NAME);
s = IoCreateDevice(DriverObject, 0, &deviceName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &prv.deviceObject);
if (!NT_SUCCESS(s))
{
DbgPrint("Failed IoCreateDevice: 0x%08lx\n", s);
return s;
}
RtlInitUnicodeString(&DOSDeviceName, DOS_DEVICE_NAME);
s = IoCreateSymbolicLink(&DOSDeviceName, &deviceName);
if (!NT_SUCCESS(s))
{
IoDeleteDevice(prv.deviceObject);
DbgPrint("Failed IoCreateSymbolicLink: 0x%08lx\n", s);
return s;
}
return STATUS_SUCCESS;
}
VOID DriverUnload(_In_ struct _DRIVER_OBJECT *DriverObject)
{
UNICODE_STRING DOSDeviceName;
UNREFERENCED_PARAMETER(DriverObject);
RtlInitUnicodeString(&DOSDeviceName, DOS_DEVICE_NAME);
IoDeleteSymbolicLink(&DOSDeviceName);
IoDeleteDevice(prv.deviceObject);
}
_Use_decl_annotations_ NTSTATUS irp_mj_create(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
UNREFERENCED_PARAMETER(DeviceObject);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
_Use_decl_annotations_ NTSTATUS irp_mj_close(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
UNREFERENCED_PARAMETER(DeviceObject);
// FIXME: Make sure all pending requests on this handle are complete
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS setPFNDatabaseFromIRP(PIRP Irp)
{
PIO_STACK_LOCATION irpStack;
setPFNDatabaseRequest inputBuffer;
int bytesReturned;
NTSTATUS s;
bytesReturned = 0;
irpStack = IoGetCurrentIrpStackLocation(Irp);
if (irpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(setPFNDatabaseRequest))
{
s = STATUS_BUFFER_TOO_SMALL;
goto out;
}
memcpy(&inputBuffer, Irp->AssociatedIrp.SystemBuffer, sizeof(setPFNDatabaseRequest));
s = setPFNDatabase(&inputBuffer);
out:
Irp->IoStatus.Status = s;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return s;
}
_Use_decl_annotations_ NTSTATUS irp_mj_device_control(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PIO_STACK_LOCATION irpStack;
unsigned long functionCode;
UNREFERENCED_PARAMETER(DeviceObject);
irpStack = IoGetCurrentIrpStackLocation(Irp);
functionCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
switch (functionCode)
{
case IOCTL_DRIVER_QUERY_VA:
return queryVAFromIRP(Irp);
case IOCTL_DRIVER_SET_PFN_DATABASE:
return setPFNDatabaseFromIRP(Irp);
default:
DbgPrint("IRP_MJ_DEVICE_CONTROL: Unrecognised function code 0x%08lx\n", functionCode);
}
Irp->IoStatus.Status = STATUS_ILLEGAL_FUNCTION;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS setPFNDatabase(setPFNDatabaseRequest* req)
{
PVOID MmPfnDatabaseUnsafe;
unsigned long long MmPfnDatabase;
MM_COPY_ADDRESS src;
SIZE_T bytesRead;
NTSTATUS s;
int didExcept;
unsigned long numberOfPFNs = 0x2000; // FIXME
// Since we don't know the base address of ntdll (and don't want to call any undocumented stuff to get it), we accept an offset to MmPfnDatabase
// from an exported entry (ExAllocatePoolWithTag). Since this comes from userspace, we still need to santise it as best we can. We can't make it
// foolproof but we can do some basic checks. Since we only ever read the PFN database via MmCopyMemory, it should be safe for userspace to give
// us a bad address, anyway.
MmPfnDatabaseUnsafe = (PVOID)( ((unsigned long long)ExAllocatePoolWithTag) - req->offsetToMmPfnDatabaseInNtDllFromExAllocatePoolWithTag );
// We now have a pointer to MmPfnDatabase, which is itself a pointer to the first PFN. We should try to read it, and find the PFN DB base.
src.VirtualAddress = MmPfnDatabaseUnsafe;
#pragma warning( push )
#pragma warning( disable : 6001 ) // VS things 'MmPfnDatabase' can be uninitialized in this call. It cannot.
s = MmCopyMemory(&MmPfnDatabase, src, sizeof(PVOID), MM_COPY_MEMORY_VIRTUAL, &bytesRead);
#pragma warning( pop )
if (!NT_SUCCESS(s))
{
DbgPrint("Cannot read MmPfnDatabase pointer %p as provided by userspace\n", MmPfnDatabaseUnsafe);
return s;
}
if (bytesRead != sizeof(PVOID))
{
DbgPrint("Short read of read MmPfnDatabase pointer %p as provided by userspace (read %llu of %llu bytes)\n", MmPfnDatabaseUnsafe, bytesRead, sizeof(PVOID));
return STATUS_ACCESS_VIOLATION;
}
// Now we have the PFN database pointer, and we can do some basic checks on it.
// It should be aligned on a 4K boundary (I think?). This is totally from observation
// and may be incorrect.
if ((MmPfnDatabase & 0x0000000000000fff) != 0)
{
DbgPrint("Dereferenced MmPfnDatabase pointer is not correctly aligned?\n");
return STATUS_BAD_DATA;
}
// This should not be in a user-space buffer
__try
{
ProbeForRead((PVOID)MmPfnDatabase, sizeof(struct PFN) * numberOfPFNs, 1);
didExcept = FALSE;
}
#pragma warning( push )
#pragma warning( disable : 6320 ) // "warning C6320: Exception-filter expression is the constant EXCEPTION_EXECUTE_HANDLER. This might mask exceptions that were not intended to be handled."
__except (EXCEPTION_EXECUTE_HANDLER)
#pragma warning( pop )
{
didExcept = TRUE;
}
if (!didExcept)
{
DbgPrint("Dereferenced MmPfnDatabase pointer is in userspace\n");
return STATUS_BAD_DATA;
}
// TODO: more checks. We're giving userspace the ability to give kernel space a pointer here
// so we should be as careful as we possibly can be.
// OK, all our checks passed!
prv.PFNDatabase = MmPfnDatabase;
DbgPrint("MmPfnDatabase is 0x%016llx\n", prv.PFNDatabase);
return STATUS_SUCCESS;
}
NTSTATUS queryVAFromIRP(PIRP Irp)
{
PIO_STACK_LOCATION irpStack;
getPageInfoRequest inputBuffer;
getPageInfoResponse* outputBuffer;
int bytesReturned;
NTSTATUS s;
bytesReturned = 0;
irpStack = IoGetCurrentIrpStackLocation(Irp);
if (irpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(getPageInfoRequest))
{
s = STATUS_BUFFER_TOO_SMALL;
goto out;
}
memcpy(&inputBuffer, Irp->AssociatedIrp.SystemBuffer, sizeof(getPageInfoRequest));
if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(getPageInfoResponse) * inputBuffer.numberOfPagesToCheck)
{
s = STATUS_BUFFER_TOO_SMALL;
goto out;
}
outputBuffer = (getPageInfoResponse*)Irp->AssociatedIrp.SystemBuffer;
memset(outputBuffer, 0, sizeof(getPageInfoResponse) * inputBuffer.numberOfPagesToCheck);
s = queryVA(&inputBuffer, outputBuffer);
if (NT_SUCCESS(s))
bytesReturned = sizeof(getPageInfoResponse) * inputBuffer.numberOfPagesToCheck;
out:
Irp->IoStatus.Status = s;
Irp->IoStatus.Information = bytesReturned;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return s;
}
NTSTATUS queryVA(getPageInfoRequest* params, getPageInfoResponse* response)
{
PMDL mdl;
PPFN_NUMBER pfnArray;
unsigned int pfnArrayCount;
unsigned int pfnIdx;
struct PFN* MmPfnDatabase = (struct PFN*)prv.PFNDatabase;
struct PFN ourPFN;
unsigned long long pte;
KAPC_STATE state;
PEPROCESS eprocess;
NTSTATUS s;
MM_COPY_ADDRESS srcAddress;
PHYSICAL_ADDRESS phys;
SIZE_T numRead;
UNREFERENCED_PARAMETER(response);
if (params->numberOfPagesToCheck == 0)
{
DbgPrint("Asked to scan 0 pages\n");
return STATUS_INVALID_PARAMETER;
}
mdl = IoAllocateMdl((PVOID)params->pageToCheck, 0x1000 * params->numberOfPagesToCheck, FALSE, FALSE, NULL);
if (!mdl)
{
return STATUS_NO_MEMORY;
}
s = PsLookupProcessByProcessId((HANDLE)params->targetPID, &eprocess);
if (!NT_SUCCESS(s))
{
IoFreeMdl(mdl);
DbgPrint("PsLookupProcesByProcessId failed for PID 0x%04lx: 0x%08lx\n", params->targetPID, s);
return s;
}
KeStackAttachProcess(eprocess, &state);
__try
{
MmProbeAndLockPages(mdl, UserMode, IoReadAccess);
}
#pragma warning( push )
#pragma warning( disable : 6320 ) // "warning C6320: Exception-filter expression is the constant EXCEPTION_EXECUTE_HANDLER. This might mask exceptions that were not intended to be handled."
__except (EXCEPTION_EXECUTE_HANDLER)
#pragma warning( pop )
{
s = STATUS_BAD_DATA;
goto out;
}
pfnArray = MmGetMdlPfnArray(mdl);
pfnArrayCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(mdl), MmGetMdlByteCount(mdl));
// Read the PTE from the PFN database using MmCopyMemory, in case we have the pfn database base address wrong.
// MmCopyMemory won't let me read us the memory by VA - not 100% sure why but I suspect because it is checked
// against the PFN table and no mapping is found (?) - so we just translate to physical address and read that
// instead.
for (pfnIdx = 0; pfnIdx < pfnArrayCount; pfnIdx++)
{
phys = MmGetPhysicalAddress(&MmPfnDatabase[pfnArray[pfnIdx]]);
srcAddress.PhysicalAddress.QuadPart = phys.QuadPart;
#pragma warning( push )
#pragma warning( disable : 6001 ) // VS things 'ourPFN' can be uninitialized in this call. It cannot.
s = MmCopyMemory(&ourPFN, srcAddress, sizeof(struct PFN), MM_COPY_MEMORY_PHYSICAL, &numRead);
#pragma warning( pop )
if (!NT_SUCCESS(s) || numRead != sizeof(struct PFN))
{
DbgPrint("Failed to read PFN from PFN database at %p (%p[0x%16llx]): NTSTATUS 0x%08lx, transferred %llu of %llu bytes\n", srcAddress.VirtualAddress, MmPfnDatabase, pfnArray[pfnIdx], s, numRead, sizeof(struct PFN));
if (NT_SUCCESS(s))
s = STATUS_PARTIAL_COPY;
goto out;
}
pte = ourPFN.PTEAddress;
// DbgPrint("VA 0x%016llx PFN %p\n", params->pageToCheck, &MmPfnDatabase[pfn[0]]);
response[pfnIdx].isValid = TRUE; // TODO
response[pfnIdx].isDirty = (ourPFN.e1 >> 4) & 0x01;
}
s = STATUS_SUCCESS;
out:
MmUnlockPages(mdl);
IoFreeMdl(mdl);
KeUnstackDetachProcess(&state);
return s;
}
__drv_requiresIRQL(APC_LEVEL)
NTSTATUS readMemoryFromPhysical(unsigned long long address, char* errMsg, void* tableOut)
{
NTSTATUS s;
MM_COPY_ADDRESS srcAddress;
SIZE_T numRead;
SIZE_T bytesToRead = 0x200 * sizeof(unsigned long long);
srcAddress.PhysicalAddress.QuadPart = address;
s = MmCopyMemory(tableOut, srcAddress, bytesToRead, MM_COPY_MEMORY_PHYSICAL, &numRead);
if (!NT_SUCCESS(s) || numRead != bytesToRead)
{
DbgPrint("Failed to MmCopyMemory table '%s' from physical location 0x%08llx: 0x%08lx (read 0x%08llx of 0x%08llx bytes)\n", errMsg, srcAddress.PhysicalAddress.QuadPart, s, numRead, bytesToRead);
return STATUS_UNSUCCESSFUL;
}
return STATUS_SUCCESS;
}
unsigned long long getChildTableFromTableEntry(unsigned long long entry)
{
// TODO/FIXME: We should honour the size of the child table pointer here, which is set as
// M-12 (M being set in the sillicon I think). Bit 63 is XD, and 62-52 is ignored, but 51
// through M is reserved by the sillicon so we should ignore it..
return ((unsigned long long)((entry & ~(0xfff0'0000'0000'0FFF)) ));
}
int isTableEntryValid(unsigned long long entry)
{
return (entry & 0x01) != 0;
}
+10
View File
@@ -0,0 +1,10 @@
#pragma once
struct privateInfo
{
PDEVICE_OBJECT deviceObject;
unsigned long long PFNDatabase;
}; typedef struct privateInfo privateInfo;
extern privateInfo prv;
+32
View File
@@ -0,0 +1,32 @@
;
; driver.inf
;
[Version]
Signature="$WINDOWS NT$"
Class=System
ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318}
Provider=%ManufacturerName%
DriverVer=1
CatalogFile=driver.cat
[DestinationDirs]
DefaultDestDir = 12
[SourceDisksNames]
1 = %DiskName%,,,""
[SourceDisksFiles]
[Manufacturer]
%ManufacturerName%=Standard,NT$ARCH$
[Standard.NT$ARCH$]
[Strings]
ManufacturerName="<Your manufacturer name>" ;TODO: Replace with your manufacturer name
ClassName=""
DiskName="driver Source Disk"
+95
View File
@@ -0,0 +1,95 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<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>{65A559E4-6946-4252-BFBE-C3B5D1B8108C}</ProjectGuid>
<TemplateGuid>{dd38f7fc-d7bd-488b-9242-7d8754cde80d}</TemplateGuid>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
<Configuration>Debug</Configuration>
<Platform Condition="'$(Platform)' == ''">Win32</Platform>
<RootNamespace>driver</RootNamespace>
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>WDM</DriverType>
<SpectreMitigation>false</SpectreMitigation>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>WDM</DriverType>
<SpectreMitigation>false</SpectreMitigation>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<Inf2CatUseLocalTime>true</Inf2CatUseLocalTime>
<RunCodeAnalysis>true</RunCodeAnalysis>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<IncludePath>$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<Inf2CatUseLocalTime>true</Inf2CatUseLocalTime>
<RunCodeAnalysis>true</RunCodeAnalysis>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<IncludePath>$(IncludePath)</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Link>
<AdditionalDependencies>Aux_klib.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<ClCompile>
<EnablePREfast>true</EnablePREfast>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Link>
<AdditionalDependencies>Aux_klib.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<ClCompile>
<EnablePREfast>true</EnablePREfast>
<PreprocessorDefinitions>_PFT_SHOULD_CHECK_RETURN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<Inf Include="driver.inf" />
</ItemGroup>
<ItemGroup>
<FilesToPackage Include="$(TargetPath)" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="driver.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="driver.h" />
<ClInclude Include="public.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
+27
View File
@@ -0,0 +1,27 @@
#pragma once
#define DOS_DEVICE_NAME L"\\DosDevices\\cowspot"
#define DEVICE_NAME L"\\Device\\cowspot"
struct getPageInfoResponse
{
unsigned char isValid;
unsigned char isDirty;
}; typedef struct getPageInfoResponse getPageInfoResponse;
struct getPageInfoRequest
{
unsigned long targetPID;
unsigned long numberOfPagesToCheck;
unsigned long long pageToCheck;
}; typedef struct getPageInfoRequest getPageInfoRequest;
#define IOCTL_DRIVER_QUERY_VA CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
struct setPFNDatabaseRequest
{
unsigned long long offsetToMmPfnDatabaseInNtDllFromExAllocatePoolWithTag;
}; typedef struct setPFNDatabaseRequest setPFNDatabaseRequest;
#define IOCTL_DRIVER_SET_PFN_DATABASE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)