This commit is contained in:
not-wlan
2017-12-30 22:44:44 +01:00
commit e2b3fca403
20 changed files with 1657 additions and 0 deletions
+322
View File
@@ -0,0 +1,322 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
**/Properties/launchSettings.json
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# TypeScript v1 declaration files
typings/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush
.cr/
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
View File
+115
View File
@@ -0,0 +1,115 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27130.2010
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "capcom", "capcom\capcom.vcxproj", "{329B6895-3CAB-43A7-AA43-6BDFF5072110}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "prockill", "prockill\prockill.vcxproj", "{36523E04-13B5-429F-B78B-9C475D932D02}"
ProjectSection(ProjectDependencies) = postProject
{329B6895-3CAB-43A7-AA43-6BDFF5072110} = {329B6895-3CAB-43A7-AA43-6BDFF5072110}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "eprocess", "eprocess\eprocess.vcxproj", "{D550C05B-50E7-4778-A2E8-B2987A27CB65}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "drvmap", "drvmap\drvmap.vcxproj", "{14564628-1966-4822-8EC7-3BC613DE4FFE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
Debug|ARM64 = Debug|ARM64
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
LibRelease|ARM = LibRelease|ARM
LibRelease|ARM64 = LibRelease|ARM64
LibRelease|x64 = LibRelease|x64
LibRelease|x86 = LibRelease|x86
Release|ARM = Release|ARM
Release|ARM64 = Release|ARM64
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{329B6895-3CAB-43A7-AA43-6BDFF5072110}.Debug|ARM.ActiveCfg = Debug|x64
{329B6895-3CAB-43A7-AA43-6BDFF5072110}.Debug|ARM64.ActiveCfg = Debug|x64
{329B6895-3CAB-43A7-AA43-6BDFF5072110}.Debug|x64.ActiveCfg = Debug|x64
{329B6895-3CAB-43A7-AA43-6BDFF5072110}.Debug|x64.Build.0 = Debug|x64
{329B6895-3CAB-43A7-AA43-6BDFF5072110}.Debug|x86.ActiveCfg = Debug|x64
{329B6895-3CAB-43A7-AA43-6BDFF5072110}.LibRelease|ARM.ActiveCfg = LibRelease|x64
{329B6895-3CAB-43A7-AA43-6BDFF5072110}.LibRelease|ARM64.ActiveCfg = LibRelease|x64
{329B6895-3CAB-43A7-AA43-6BDFF5072110}.LibRelease|x64.ActiveCfg = Release|x64
{329B6895-3CAB-43A7-AA43-6BDFF5072110}.LibRelease|x64.Build.0 = Release|x64
{329B6895-3CAB-43A7-AA43-6BDFF5072110}.LibRelease|x86.ActiveCfg = LibRelease|x64
{329B6895-3CAB-43A7-AA43-6BDFF5072110}.Release|ARM.ActiveCfg = Release|x64
{329B6895-3CAB-43A7-AA43-6BDFF5072110}.Release|ARM64.ActiveCfg = Release|x64
{329B6895-3CAB-43A7-AA43-6BDFF5072110}.Release|x64.ActiveCfg = Release|x64
{329B6895-3CAB-43A7-AA43-6BDFF5072110}.Release|x64.Build.0 = Release|x64
{329B6895-3CAB-43A7-AA43-6BDFF5072110}.Release|x86.ActiveCfg = Release|x64
{36523E04-13B5-429F-B78B-9C475D932D02}.Debug|ARM.ActiveCfg = Debug|Win32
{36523E04-13B5-429F-B78B-9C475D932D02}.Debug|ARM64.ActiveCfg = Debug|Win32
{36523E04-13B5-429F-B78B-9C475D932D02}.Debug|x64.ActiveCfg = Debug|x64
{36523E04-13B5-429F-B78B-9C475D932D02}.Debug|x64.Build.0 = Debug|x64
{36523E04-13B5-429F-B78B-9C475D932D02}.Debug|x86.ActiveCfg = Debug|Win32
{36523E04-13B5-429F-B78B-9C475D932D02}.Debug|x86.Build.0 = Debug|Win32
{36523E04-13B5-429F-B78B-9C475D932D02}.LibRelease|ARM.ActiveCfg = Release|Win32
{36523E04-13B5-429F-B78B-9C475D932D02}.LibRelease|ARM.Build.0 = Release|Win32
{36523E04-13B5-429F-B78B-9C475D932D02}.LibRelease|ARM64.ActiveCfg = Release|Win32
{36523E04-13B5-429F-B78B-9C475D932D02}.LibRelease|ARM64.Build.0 = Release|Win32
{36523E04-13B5-429F-B78B-9C475D932D02}.LibRelease|x64.ActiveCfg = Release|x64
{36523E04-13B5-429F-B78B-9C475D932D02}.LibRelease|x64.Build.0 = Release|x64
{36523E04-13B5-429F-B78B-9C475D932D02}.LibRelease|x86.ActiveCfg = Release|Win32
{36523E04-13B5-429F-B78B-9C475D932D02}.LibRelease|x86.Build.0 = Release|Win32
{36523E04-13B5-429F-B78B-9C475D932D02}.Release|ARM.ActiveCfg = Release|Win32
{36523E04-13B5-429F-B78B-9C475D932D02}.Release|ARM64.ActiveCfg = Release|Win32
{36523E04-13B5-429F-B78B-9C475D932D02}.Release|x64.ActiveCfg = Release|x64
{36523E04-13B5-429F-B78B-9C475D932D02}.Release|x64.Build.0 = Release|x64
{36523E04-13B5-429F-B78B-9C475D932D02}.Release|x86.ActiveCfg = Release|Win32
{36523E04-13B5-429F-B78B-9C475D932D02}.Release|x86.Build.0 = Release|Win32
{D550C05B-50E7-4778-A2E8-B2987A27CB65}.Debug|ARM.ActiveCfg = Debug|Win32
{D550C05B-50E7-4778-A2E8-B2987A27CB65}.Debug|ARM64.ActiveCfg = Debug|Win32
{D550C05B-50E7-4778-A2E8-B2987A27CB65}.Debug|x64.ActiveCfg = Debug|x64
{D550C05B-50E7-4778-A2E8-B2987A27CB65}.Debug|x64.Build.0 = Debug|x64
{D550C05B-50E7-4778-A2E8-B2987A27CB65}.Debug|x86.ActiveCfg = Debug|Win32
{D550C05B-50E7-4778-A2E8-B2987A27CB65}.Debug|x86.Build.0 = Debug|Win32
{D550C05B-50E7-4778-A2E8-B2987A27CB65}.LibRelease|ARM.ActiveCfg = Release|Win32
{D550C05B-50E7-4778-A2E8-B2987A27CB65}.LibRelease|ARM.Build.0 = Release|Win32
{D550C05B-50E7-4778-A2E8-B2987A27CB65}.LibRelease|ARM64.ActiveCfg = Release|Win32
{D550C05B-50E7-4778-A2E8-B2987A27CB65}.LibRelease|ARM64.Build.0 = Release|Win32
{D550C05B-50E7-4778-A2E8-B2987A27CB65}.LibRelease|x64.ActiveCfg = Release|x64
{D550C05B-50E7-4778-A2E8-B2987A27CB65}.LibRelease|x64.Build.0 = Release|x64
{D550C05B-50E7-4778-A2E8-B2987A27CB65}.LibRelease|x86.ActiveCfg = Release|Win32
{D550C05B-50E7-4778-A2E8-B2987A27CB65}.LibRelease|x86.Build.0 = Release|Win32
{D550C05B-50E7-4778-A2E8-B2987A27CB65}.Release|ARM.ActiveCfg = Release|Win32
{D550C05B-50E7-4778-A2E8-B2987A27CB65}.Release|ARM64.ActiveCfg = Release|Win32
{D550C05B-50E7-4778-A2E8-B2987A27CB65}.Release|x64.ActiveCfg = Release|x64
{D550C05B-50E7-4778-A2E8-B2987A27CB65}.Release|x64.Build.0 = Release|x64
{D550C05B-50E7-4778-A2E8-B2987A27CB65}.Release|x86.ActiveCfg = Release|Win32
{D550C05B-50E7-4778-A2E8-B2987A27CB65}.Release|x86.Build.0 = Release|Win32
{14564628-1966-4822-8EC7-3BC613DE4FFE}.Debug|ARM.ActiveCfg = Debug|Win32
{14564628-1966-4822-8EC7-3BC613DE4FFE}.Debug|ARM64.ActiveCfg = Debug|Win32
{14564628-1966-4822-8EC7-3BC613DE4FFE}.Debug|x64.ActiveCfg = Debug|x64
{14564628-1966-4822-8EC7-3BC613DE4FFE}.Debug|x64.Build.0 = Debug|x64
{14564628-1966-4822-8EC7-3BC613DE4FFE}.Debug|x86.ActiveCfg = Debug|Win32
{14564628-1966-4822-8EC7-3BC613DE4FFE}.Debug|x86.Build.0 = Debug|Win32
{14564628-1966-4822-8EC7-3BC613DE4FFE}.LibRelease|ARM.ActiveCfg = Release|x64
{14564628-1966-4822-8EC7-3BC613DE4FFE}.LibRelease|ARM.Build.0 = Release|x64
{14564628-1966-4822-8EC7-3BC613DE4FFE}.LibRelease|ARM64.ActiveCfg = Release|x64
{14564628-1966-4822-8EC7-3BC613DE4FFE}.LibRelease|ARM64.Build.0 = Release|x64
{14564628-1966-4822-8EC7-3BC613DE4FFE}.LibRelease|x64.ActiveCfg = Release|x64
{14564628-1966-4822-8EC7-3BC613DE4FFE}.LibRelease|x64.Build.0 = Release|x64
{14564628-1966-4822-8EC7-3BC613DE4FFE}.LibRelease|x86.ActiveCfg = Release|Win32
{14564628-1966-4822-8EC7-3BC613DE4FFE}.LibRelease|x86.Build.0 = Release|Win32
{14564628-1966-4822-8EC7-3BC613DE4FFE}.Release|ARM.ActiveCfg = Release|Win32
{14564628-1966-4822-8EC7-3BC613DE4FFE}.Release|ARM64.ActiveCfg = Release|Win32
{14564628-1966-4822-8EC7-3BC613DE4FFE}.Release|x64.ActiveCfg = Release|x64
{14564628-1966-4822-8EC7-3BC613DE4FFE}.Release|x64.Build.0 = Release|x64
{14564628-1966-4822-8EC7-3BC613DE4FFE}.Release|x86.ActiveCfg = Release|Win32
{14564628-1966-4822-8EC7-3BC613DE4FFE}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {36BE0B50-DC95-4036-A876-BAA6DF0FB403}
EndGlobalSection
EndGlobal
+64
View File
@@ -0,0 +1,64 @@
#include "capcom.hpp"
#include <intrin.h>
#pragma intrinsic(_disable)
#pragma intrinsic(_enable)
namespace capcom
{
std::unique_ptr<user_function> g_user_function = nullptr;
void capcom_dispatcher(const kernel::MmGetSystemRoutineAddressFn mm_get_system_routine_address)
{
(*g_user_function)(mm_get_system_routine_address);
}
#pragma pack(push, 1)
struct capcom_payload
{
void* operator new(const std::size_t sz) {
return VirtualAlloc(nullptr, sz, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
}
void operator delete(void* ptr, const std::size_t sz) {
VirtualFree(ptr, 0, MEM_RELEASE);
}
auto get() const noexcept -> void* { return const_cast<void**>(&payload_ptr); }
private:
void* payload_ptr = movabs_rax;
uint8_t movabs_rax[2] = { 0x48, 0xB8 };
void* function_ptr = &capcom_dispatcher;
uint8_t jmp_rax[2] = { 0xFF, 0xE0 };
};
#pragma pack(pop)
unsigned long capcom_run(const driver_handle device, user_function payload_function)
{
g_user_function = std::make_unique<user_function>(payload_function);
const auto payload = std::make_unique<capcom_payload>();
DWORD output_buffer;
DWORD bytes_returned;
if (DeviceIoControl(device.get(), ioctl_x64, payload->get(), 8, &output_buffer, 4, &bytes_returned, nullptr))
return 0;
return GetLastError();
}
uintptr_t get_system_routine(const driver_handle device, const std::wstring& name)
{
UNICODE_STRING routine_name;
RtlInitUnicodeString(&routine_name, name.c_str());
uintptr_t result = 0;
const auto kernel_result = capcom_run(device, [&routine_name, &result](auto mm_get_routine) {
_enable();
result = (uintptr_t)(mm_get_routine(&routine_name));
_disable();
});
//RtlFreeUnicodeString(&routine_name);
if (kernel_result != 0)
result = 0;
return result;
}
}
+22
View File
@@ -0,0 +1,22 @@
#pragma once
#include <functional>
#include <memory>
#include "kernel.hpp"
//Links against ntdll for RtlInitUnicodeString implementation
#pragma comment(lib, "ntdll.lib")
namespace capcom
{
constexpr auto device_name = "\\\\.\\Htsysm72FB";
constexpr auto ioctl_x86 = 0xAA012044u;
constexpr auto ioctl_x64 = 0xAA013044u;
using user_function = std::function<void(kernel::MmGetSystemRoutineAddressFn)>;
using driver_handle = std::shared_ptr<std::remove_pointer_t<HANDLE>>;
unsigned long capcom_run(const driver_handle device, user_function payload);
uintptr_t get_system_routine(const driver_handle device, const std::wstring& name);
}
+117
View File
@@ -0,0 +1,117 @@
<?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|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="LibRelease|x64">
<Configuration>LibRelease</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>{329B6895-3CAB-43A7-AA43-6BDFF5072110}</ProjectGuid>
<RootNamespace>capcom</RootNamespace>
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='LibRelease|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
</ImportGroup>
<ImportGroup Label="Shared">
</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>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='LibRelease|x64'" 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 />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>C:\Program Files (x86)\Windows Kits\10\Lib\10.0.16299.0\km\x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='LibRelease|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard>
<AdditionalIncludeDirectories>C:\Program Files (x86)\Windows Kits\10\Include\10.0.16299.0\km;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="capcom.cpp" />
<ClCompile Include="kernel.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="process.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="capcom.hpp" />
<ClInclude Include="kernel.hpp" />
<ClInclude Include="process.hpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
</ImportGroup>
</Project>
+14
View File
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="main.cpp" />
<ClCompile Include="capcom.cpp" />
<ClCompile Include="process.cpp" />
<ClCompile Include="kernel.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="capcom.hpp" />
<ClInclude Include="process.hpp" />
<ClInclude Include="kernel.hpp" />
</ItemGroup>
</Project>
+7
View File
@@ -0,0 +1,7 @@
#include "kernel.hpp"
namespace kernel
{
}
+11
View File
@@ -0,0 +1,11 @@
#pragma once
#define WIN32_NO_STATUS
#include <Windows.h>
#include <Winternl.h>
#undef WIN32_NO_STATUS
#include <string>
namespace kernel
{
using MmGetSystemRoutineAddressFn = PVOID(NTAPI*)(PUNICODE_STRING);
}
+33
View File
@@ -0,0 +1,33 @@
#define RELEASE
#include <iostream>
#include "capcom.hpp"
#include "process.hpp"
int main()
{
const capcom::driver_handle capcom(CreateFile(capcom::device_name, FILE_ALL_ACCESS, FILE_SHARE_READ, nullptr, FILE_OPEN, FILE_ATTRIBUTE_NORMAL, nullptr), CloseHandle);
if(capcom.get() == INVALID_HANDLE_VALUE)
{
printf("CreateFileA failed! Error: %u\n", GetLastError());
return 0;
}
auto system_handle = INVALID_HANDLE_VALUE;
const auto result = capcom::capcom_run(capcom, [&system_handle](auto mm_get_routine) {
kernel::process::open_process(mm_get_routine, HANDLE(4), MAXIMUM_ALLOWED, &system_handle);
});
if(result == 0) {
printf("success!\n");
printf("acquired handle: 0x%p\n", system_handle);
printf("pid of handle: %d\n", GetProcessId(system_handle));
} else {
printf("failure! %d\n", result);
}
std::cin.get();
return 0;
}
+119
View File
@@ -0,0 +1,119 @@
#include "process.hpp"
#include <intrin.h>
#pragma intrinsic(_disable)
#pragma intrinsic(_enable)
#include <ntstatus.h>
#pragma comment(lib, "ntdll.lib")
namespace kernel::process
{
static bool g_initialized;
decltype(PsLookupProcessByProcessId) PsLookupProcessByProcessId = nullptr;
decltype(PsProcessType) PsProcessType = nullptr;
decltype(ObDereferenceObject) ObDereferenceObject = nullptr;
decltype(ObOpenObjectByPointer) ObOpenObjectByPointer = nullptr;
decltype(ZwTerminateProcess) ZwTerminateProcess = nullptr;
void get_system_routines(MmGetSystemRoutineAddressFn MmGetSystemRoutineAddress)
{
UNICODE_STRING
usPsLookupProcessByProcessId,
usObDereferenceObject,
usPsProcessType,
usObOpenObjectByPointer,
usZwTerminateProcess;
RtlInitUnicodeString(&usPsLookupProcessByProcessId, L"PsLookupProcessByProcessId");
RtlInitUnicodeString(&usObDereferenceObject, L"ObDereferenceObject");
RtlInitUnicodeString(&usPsProcessType, L"PsProcessType");
RtlInitUnicodeString(&usObOpenObjectByPointer, L"ObOpenObjectByPointer");
RtlInitUnicodeString(&usZwTerminateProcess, L"ZwTerminateProcess");
// MmGetSystemRoutineAddress can only be called at IRQL PASSIVE_LEVEL, and the Capcom driver uses _disable()
_enable();
PsLookupProcessByProcessId = static_cast<decltype(PsLookupProcessByProcessId)>(MmGetSystemRoutineAddress(&usPsLookupProcessByProcessId));
ObDereferenceObject = static_cast<decltype(ObDereferenceObject)>(MmGetSystemRoutineAddress(&usObDereferenceObject));
PsProcessType = static_cast<decltype(PsProcessType)>(MmGetSystemRoutineAddress(&usPsProcessType));
ObOpenObjectByPointer = static_cast<decltype(ObOpenObjectByPointer)>(MmGetSystemRoutineAddress(&usObOpenObjectByPointer));
ZwTerminateProcess = static_cast<decltype(ZwTerminateProcess)>(MmGetSystemRoutineAddress(&usZwTerminateProcess));
// Disable Interrupts again before returning to execution
_disable();
g_initialized = true;
}
void kill_process(MmGetSystemRoutineAddressFn MmGetSystemRoutineAddress, HANDLE ProcessId, PNTSTATUS Result)
{
if (Result == nullptr) // || ProcessId == nullptr || ProcessId == INVALID_HANDLE_VALUE)
return;
*Result = STATUS_SUCCESS;
PEPROCESS eprocess = { nullptr };
if (!g_initialized) {
get_system_routines(MmGetSystemRoutineAddress);
}
if(ZwTerminateProcess == nullptr)
{
*Result = -1;
return;
}
*Result = PsLookupProcessByProcessId(ProcessId, &eprocess);
if(!NT_SUCCESS(*Result))
return;
HANDLE process_handle;
*Result = ObOpenObjectByPointer(eprocess, NULL, nullptr, MAXIMUM_ALLOWED, *PsProcessType, 0/*KernelMode*/, &process_handle);
if(NT_SUCCESS(*Result))
{
_enable();
*Result = ZwTerminateProcess(process_handle, 0);
_disable();
}
}
void open_process(MmGetSystemRoutineAddressFn MmGetSystemRoutineAddress, HANDLE ProcessId, ACCESS_MASK Access, PHANDLE ReturnedHandle)
{
NTSTATUS status = 0;
PEPROCESS process = nullptr;
HANDLE handle = nullptr;
if (!g_initialized) {
get_system_routines(MmGetSystemRoutineAddress);
}
__try {
if (ProcessId != nullptr) {
status = PsLookupProcessByProcessId(ProcessId, &process);
}
if (status >= 0) {
status = ObOpenObjectByPointer(
process,
0,
nullptr,
Access,
*PsProcessType,
0/*KernelMode*/,
&handle);
if (status >= 0) {
*ReturnedHandle = handle;
}
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
}
if (process != nullptr)
ObDereferenceObject(process);
}
}
+21
View File
@@ -0,0 +1,21 @@
#pragma once
#include "kernel.hpp"
namespace kernel::process
{
using PEPROCESS = struct _EPROCESS*;
using PACCESS_STATE = struct _ACCESS_STATE*;
using POBJECT_TYPE = struct _OBJECT_TYPE*;
using KPROCESSOR_MODE = CCHAR;
extern POBJECT_TYPE* PsProcessType;
extern NTSTATUS(NTAPI* PsLookupProcessByProcessId)(HANDLE, PEPROCESS*);
extern VOID(NTAPI* ObDereferenceObject)(PVOID);
extern NTSTATUS(NTAPI* ObOpenObjectByPointer)(PVOID, ULONG, PACCESS_STATE, ACCESS_MASK, POBJECT_TYPE, KPROCESSOR_MODE, PHANDLE);
extern NTSTATUS(NTAPI* ZwTerminateProcess)(HANDLE, NTSTATUS);
void open_process(MmGetSystemRoutineAddressFn MmGetSystemRoutineAddress, HANDLE ProcessId, ACCESS_MASK Access, PHANDLE ReturnedHandle);
void kill_process(MmGetSystemRoutineAddressFn MmGetSystemRoutineAddress, HANDLE ProcessId, PNTSTATUS Result);
}
+221
View File
@@ -0,0 +1,221 @@
#include "drv_image.hpp"
#include <cassert>
#include <fstream>
namespace drvmap
{
drv_image::drv_image(std::vector<uint8_t>& image) : m_image(std::move(image))
{
m_dos_header = reinterpret_cast<PIMAGE_DOS_HEADER>(m_image.data());
assert(m_dos_header->e_magic == IMAGE_DOS_SIGNATURE);
m_nt_headers = reinterpret_cast<PIMAGE_NT_HEADERS64>((uintptr_t)m_dos_header + m_dos_header->e_lfanew);
assert(m_nt_headers->Signature == IMAGE_NT_SIGNATURE);
assert(m_nt_headers->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC);
m_section_header = reinterpret_cast<IMAGE_SECTION_HEADER*>((uintptr_t)(&m_nt_headers->OptionalHeader) + m_nt_headers->FileHeader.SizeOfOptionalHeader);
}
size_t drv_image::size() const
{
return m_nt_headers->OptionalHeader.SizeOfImage;
}
uintptr_t drv_image::entry_point() const
{
return m_nt_headers->OptionalHeader.AddressOfEntryPoint;
}
void drv_image::map()
{
m_image_mapped.clear();
m_image_mapped.resize(m_nt_headers->OptionalHeader.SizeOfImage);
std::copy_n(m_image.begin(), m_nt_headers->OptionalHeader.SizeOfHeaders, m_image_mapped.begin());
for (size_t i = 0; i < m_nt_headers->FileHeader.NumberOfSections; ++i)
{
const auto& section = m_section_header[i];
const auto target = (uintptr_t)m_image_mapped.data() + section.VirtualAddress;
const auto source = (uintptr_t)m_dos_header + section.PointerToRawData;
std::copy_n(m_image.begin() + section.PointerToRawData, section.SizeOfRawData, m_image_mapped.begin() + section.VirtualAddress);
printf("copying [%s] 0x%p -> 0x%p [0x%04X]\n", &section.Name[0], (void*)source, (void*)target, section.SizeOfRawData);
}
//m_dos_header = (PIMAGE_DOS_HEADER)m_image_mapped.data();
//m_nt_headers = (PIMAGE_NT_HEADERS64)((uintptr_t)m_dos_header + m_dos_header->e_lfanew);
}
bool drv_image::process_relocation(uintptr_t image_base_delta, uint16_t data, uint8_t* relocation_base) const
{
#define IMR_RELOFFSET(x) (x & 0xFFF)
switch (data >> 12 & 0xF)
{
case IMAGE_REL_BASED_HIGH:
{
const auto raw_address = reinterpret_cast<int16_t*>(relocation_base + IMR_RELOFFSET(data));
*raw_address += static_cast<unsigned long>(HIWORD(image_base_delta));
break;
}
case IMAGE_REL_BASED_LOW:
{
const auto raw_address = reinterpret_cast<int16_t*>(relocation_base + IMR_RELOFFSET(data));
*raw_address += static_cast<unsigned long>(LOWORD(image_base_delta));
break;
}
case IMAGE_REL_BASED_HIGHLOW:
{
const auto raw_address = reinterpret_cast<size_t*>(relocation_base + IMR_RELOFFSET(data));
*raw_address += static_cast<size_t>(image_base_delta);
break;
}
case IMAGE_REL_BASED_DIR64:
{
auto UNALIGNED raw_address = reinterpret_cast<DWORD_PTR UNALIGNED*>(relocation_base + IMR_RELOFFSET(data));
*raw_address += image_base_delta;
break;
}
case IMAGE_REL_BASED_ABSOLUTE: // No action required
case IMAGE_REL_BASED_HIGHADJ: // no action required
{
break;
}
default:
{
throw std::runtime_error("gay relocation!");
return false;
}
}
#undef IMR_RELOFFSET
return true;
}
void drv_image::relocate(uintptr_t base) const
{
if (m_nt_headers->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED)
return;
ULONG total_count_bytes;
const auto nt_headers = ImageNtHeader((void*)m_image_mapped.data());
auto relocation_directory = (PIMAGE_BASE_RELOCATION)::ImageDirectoryEntryToData(nt_headers, TRUE, IMAGE_DIRECTORY_ENTRY_BASERELOC, &total_count_bytes);
auto image_base_delta = static_cast<uintptr_t>(static_cast<uintptr_t>(base) - (nt_headers->OptionalHeader.ImageBase));
auto relocation_size = total_count_bytes;
if (relocation_size == 0) {
printf("no relocations but flag isn't set. weird.\n");
return;
}
assert(relocation_directory != nullptr);
void * relocation_end = reinterpret_cast<uint8_t*>(relocation_directory) + relocation_size;
while (relocation_directory < relocation_end)
{
auto relocation_base = ::ImageRvaToVa(nt_headers, (void*)m_image_mapped.data(), relocation_directory->VirtualAddress, nullptr);
auto num_relocs = (relocation_directory->SizeOfBlock - 8) >> 1;
auto relocation_data = reinterpret_cast<PWORD>(relocation_directory + 1);
for (unsigned long i = 0; i < num_relocs; ++i, ++relocation_data)
{
if (process_relocation(image_base_delta, *relocation_data, (uint8_t*)relocation_base) == FALSE)
{
printf("failed to relocate!");
return;
}
}
relocation_directory = reinterpret_cast<PIMAGE_BASE_RELOCATION>(relocation_data);
}
}
template<typename T>
__forceinline T* ptr_add(void* base, uintptr_t offset)
{
return (T*)(uintptr_t)base + offset;
}
void drv_image::fix_imports(const std::function<uintptr_t(std::string_view)> get_module, const std::function<uintptr_t(uintptr_t, const char*)> get_function, const std::function<uintptr_t(uintptr_t, uint16_t)> get_function_ord){
ULONG size;
auto import_descriptors = static_cast<PIMAGE_IMPORT_DESCRIPTOR>(::ImageDirectoryEntryToData(m_image.data(), FALSE, IMAGE_DIRECTORY_ENTRY_IMPORT, &size));
if (import_descriptors == nullptr) {
printf("no imports!\n");
return;
}
for (; import_descriptors->Name; import_descriptors++)
{
IMAGE_THUNK_DATA *image_thunk_data;
const auto module_name = get_rva<char>(import_descriptors->Name);
const auto module_base = get_module(module_name);
assert(module_base != 0);
printf("processing module: %s [0x%I64X]\n", module_name, module_base);
if (import_descriptors->OriginalFirstThunk)
{
image_thunk_data = get_rva<IMAGE_THUNK_DATA>(import_descriptors->OriginalFirstThunk);
}
else
{
image_thunk_data = get_rva<IMAGE_THUNK_DATA>(import_descriptors->FirstThunk);
}
auto image_func_data = get_rva<IMAGE_THUNK_DATA64>(import_descriptors->FirstThunk);
assert(image_thunk_data != nullptr);
assert(image_func_data != nullptr);
for (; image_thunk_data->u1.AddressOfData; image_thunk_data++, image_func_data++)
{
uintptr_t function_address = 0;
const auto ordinal = (image_thunk_data->u1.Ordinal & IMAGE_ORDINAL_FLAG64) != 0;
if(ordinal)
{
auto import_ordinal = static_cast<uint16_t>(image_thunk_data->u1.Ordinal & 0xffff);
function_address = get_function_ord(module_base, import_ordinal);
printf("function: %hu [0x%I64X]\n", import_ordinal, function_address);
} else
{
const auto image_import_by_name = get_rva<IMAGE_IMPORT_BY_NAME>(*(DWORD*)image_thunk_data);
const auto name_of_import = static_cast<char*>(image_import_by_name->Name);
function_address = get_function(module_base, name_of_import);
printf("function: %s [0x%I64X]\n", name_of_import, function_address);
}
assert(function_address != 0);
image_func_data->u1.Function = function_address;
}
}
}
void drv_image::add_cookie(uintptr_t base)
{
//TODO
}
void* drv_image::data()
{
return m_image_mapped.data();
}
}
+42
View File
@@ -0,0 +1,42 @@
#pragma once
#include <vector>
#define WIN32_NO_STATUS
#include <Windows.h>
#include <Winternl.h>
#undef WIN32_NO_STATUS
#include <ntstatus.h>
#include <functional>
#include <DbgHelp.h>
#include <variant>
#pragma comment(lib, "Dbghelp.lib")
namespace drvmap
{
class drv_image
{
std::vector<uint8_t> m_image;
std::vector<uint8_t> m_image_mapped;
PIMAGE_DOS_HEADER m_dos_header = nullptr;
PIMAGE_NT_HEADERS64 m_nt_headers = nullptr;
PIMAGE_SECTION_HEADER m_section_header = nullptr;
public:
explicit drv_image(std::vector<uint8_t>& image);
size_t size() const;
uintptr_t entry_point() const;
void map();
bool process_relocation(size_t image_base_delta, uint16_t data, uint8_t* relocation_base) const;
void relocate(uintptr_t base) const;
template<typename T>
__forceinline T* get_rva(const unsigned long offset)
{
return (T*)::ImageRvaToVa(m_nt_headers, m_image.data(), offset, nullptr);
}
void fix_imports(const std::function<uintptr_t(std::string_view)> get_module, const std::function<uintptr_t(uintptr_t, const char*)> get_function, const std::function<uintptr_t(uintptr_t, uint16_t)> get_function_ord );
void add_cookie(uintptr_t base);
void* data();
};
}
+150
View File
@@ -0,0 +1,150 @@
<?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>{14564628-1966-4822-8EC7-3BC613DE4FFE}</ProjectGuid>
<RootNamespace>drvmap</RootNamespace>
<WindowsTargetPlatformVersion>10.0.16299.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>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</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)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpplatest</LanguageStandard>
<AdditionalIncludeDirectories>D:\Dev\asmjit\src\asmjit;C:\Users\Jan\source\repos\capcom\capcom;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<SubSystem>NotSet</SubSystem>
<AdditionalLibraryDirectories>D:\Dev\asmjit\build\MinSizeRel;C:\Users\Jan\source\repos\capcom\x64\Release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpplatest</LanguageStandard>
<AdditionalIncludeDirectories>C:\Users\Jan\source\repos\capcom\capcom;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>NotSet</SubSystem>
<AdditionalLibraryDirectories>C:\Users\Jan\source\repos\capcom\x64\Debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpplatest</LanguageStandard>
<AdditionalIncludeDirectories>C:\Users\Jan\source\repos\capcom\capcom;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>NotSet</SubSystem>
<AdditionalLibraryDirectories>C:\Users\Jan\source\repos\capcom\x64\Debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpplatest</LanguageStandard>
<AdditionalIncludeDirectories>C:\Users\Jan\source\repos\capcom\capcom;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<SubSystem>NotSet</SubSystem>
<AdditionalLibraryDirectories>C:\Users\Jan\source\repos\capcom\x64\Release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="drv_image.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="util.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="drv_image.hpp" />
<ClInclude Include="structs.hpp" />
<ClInclude Include="util.hpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
+13
View File
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="main.cpp" />
<ClCompile Include="util.cpp" />
<ClCompile Include="drv_image.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="util.hpp" />
<ClInclude Include="drv_image.hpp" />
<ClInclude Include="structs.hpp" />
</ItemGroup>
</Project>
+225
View File
@@ -0,0 +1,225 @@
#include <cstdio>
#include <string>
#include "drv_image.hpp"
#include "util.hpp"
#include "capcom.hpp"
#include "structs.hpp"
#include <intrin.h>
#include <cassert>
#include <locale>
#include <variant>
#pragma intrinsic(_disable)
#pragma intrinsic(_enable)
#pragma comment(lib, "capcom.lib")
constexpr auto page_size = 0x1000u;
constexpr auto pool_tag = 'naJ?';
#pragma pack(push, 1)
typedef struct dispatch_object
{
WCHAR name[20] = { 0 };
drvmap::structs::PDRIVER_INITIALIZE init = { nullptr };
} *p_dispatch_object;
#pragma pack(pop)
uintptr_t get_kernel_module(const capcom::driver_handle capcom, const std::string_view kmodule)
{
NTSTATUS status = 0x0;
ULONG bytes = 0;
std::vector<uint8_t> data;
unsigned long required = 0;
while ((status = NtQuerySystemInformation((SYSTEM_INFORMATION_CLASS)11, data.data(), (ULONG)data.size(), &required)) == STATUS_INFO_LENGTH_MISMATCH) {
data.resize(required);
}
if (!NT_SUCCESS(status))
{
printf("NtQuerySystemInformation failed! Error: 0x%04X\n", status);
return 0;
}
const auto modules = reinterpret_cast<drvmap::structs::PRTL_PROCESS_MODULES>(data.data());
for (unsigned i = 0; i < modules->NumberOfModules; ++i)
{
const auto& driver = modules->Modules[i];
const auto image_base = reinterpret_cast<uintptr_t>(driver.ImageBase);
std::string base_name = reinterpret_cast<char*>((uintptr_t)driver.FullPathName + driver.OffsetToFileName);
const auto offset = base_name.find_last_of(".");
if (kmodule == base_name)
return reinterpret_cast<uintptr_t>(driver.ImageBase);
if (offset != base_name.npos)
base_name = base_name.erase(offset, base_name.size() - offset);
#ifdef DEBUG
printf("driver: %s\n", base_name.c_str());
#endif
if (kmodule == base_name)
return reinterpret_cast<uintptr_t>(driver.ImageBase);
}
return 0;
}
std::pair<size_t, uintptr_t> allocate_kernel_memory(const capcom::driver_handle capcom, size_t size)
{
using namespace drvmap::structs;
uintptr_t image_section;
static auto ExAllocatePoolWithTag = reinterpret_cast<ExAllocatePoolWithTagFn>(capcom::get_system_routine(capcom, L"ExAllocatePoolWithTag"));
assert(ExAllocatePoolWithTag != nullptr);
if (size % page_size == 0)
{
printf("buffer size is page aligned. won't resize\n");
}
else
{
printf("buffer is not page aligned, resizing [0x%I64X] -> ", size);
size = ((size / page_size) + 1) * page_size;
printf("[0x%I64X]\n", size);
}
capcom::capcom_run(capcom, [&size, &image_section](auto mm_get_routine) {
_enable();
image_section = (uintptr_t)ExAllocatePoolWithTag(NonPagedPool, size, pool_tag);
_disable();
});
assert(image_section != 0);
return std::make_pair(size, image_section);
}
uintptr_t get_export(const capcom::driver_handle capcom, uintptr_t base, const char* name)
{
using namespace drvmap::structs;
static auto RtlFindExportedRoutineByName = reinterpret_cast<RtlFindExportedRoutineByNameFn>(capcom::get_system_routine(capcom, L"RtlFindExportedRoutineByName"));
assert(RtlFindExportedRoutineByName != nullptr);
uintptr_t address = 0;
capcom::capcom_run(capcom, [&address, &name, &base](auto mm_get_routine)
{
_enable();
address = reinterpret_cast<uintptr_t>(RtlFindExportedRoutineByName((void*)base, name));
_disable();
});
assert(address != 0);
return address;
}
uintptr_t get_export(const capcom::driver_handle capcom, uintptr_t base, uint16_t ordinal)
{
using namespace drvmap::structs;
static auto RtlFindExportedRoutineByName = reinterpret_cast<RtlFindExportedRoutineByNameFn>(capcom::get_system_routine(capcom, L"RtlFindExportedRoutineByName"));
assert(RtlFindExportedRoutineByName != nullptr);
const auto id = MAKEINTRESOURCEA(ordinal);
uintptr_t address = 0;
capcom::capcom_run(capcom, [&id, &base, &address](auto mm_get_routine)
{
_enable();
address = reinterpret_cast<uintptr_t>(RtlFindExportedRoutineByName((void*)base, id));
_disable();
});
assert(address != 0);
return address;
}
int __stdcall main(const int argc, char** argv)
{
if (argc != 2)
{
printf("usage: drvmap.exe <driver>\n");
return 0;
}
const capcom::driver_handle capcom(CreateFile(capcom::device_name, FILE_ALL_ACCESS, FILE_SHARE_READ, nullptr, FILE_OPEN, FILE_ATTRIBUTE_NORMAL, nullptr), CloseHandle);
if (capcom.get() == INVALID_HANDLE_VALUE)
{
printf("CreateFileA failed! error: %u\n", GetLastError());
return 0;
}
std::vector<uint8_t> driver_image;
drvmap::util::open_binary_file(argv[1], driver_image);
drvmap::drv_image driver(driver_image);
const auto kernel_memory = allocate_kernel_memory(capcom, driver.size());
printf("allocated 0x%llX bytes at 0x%I64X\n", driver.size(), kernel_memory.second);
driver.fix_imports([&capcom](std::string_view name)
{
return get_kernel_module(capcom, name);
}, [&capcom](uintptr_t base, const char* name)
{
return get_export(capcom, base, name);
}, [&capcom](uintptr_t base, uint16_t name)
{
return get_export(capcom, base, name);
});
driver.map();
driver.relocate(kernel_memory.second);
auto RtlCopyMemoryPtr = capcom::get_system_routine(capcom, L"RtlCopyMemory");
assert(RtlCopyMemoryPtr != 0);
using RtlCopyMemoryFn = void(*)(VOID UNALIGNED*, const VOID UNALIGNED*, SIZE_T);
const auto size = driver.size();
const auto source = driver.data();
const auto target = reinterpret_cast<void*>(kernel_memory.second);
const auto entry_point = kernel_memory.second + driver.entry_point();
auto status = STATUS_SUCCESS;
capcom::capcom_run(capcom, [&RtlCopyMemoryPtr, &target, &size, &source](auto routine)
{
_enable();
auto _RtlCopyMemory = reinterpret_cast<RtlCopyMemoryFn>(RtlCopyMemoryPtr);
_RtlCopyMemory(target, source, size);
_disable();
});
printf("calling entry point at 0x%I64X\n", entry_point);
static auto PsCreateSystemThread = reinterpret_cast<drvmap::structs::PsCreateSystemThreadFn>(capcom::get_system_routine(capcom, L"PsCreateSystemThread"));
assert(PsCreateSystemThread != nullptr);
static auto ZwClose = (drvmap::structs::ZwCloseFn)(capcom::get_system_routine(capcom, L"ZwClose"));
assert(ZwClose != nullptr);
HANDLE handle;
OBJECT_ATTRIBUTES obAttr = { 0 };
InitializeObjectAttributes(&obAttr, nullptr, OBJ_KERNEL_HANDLE, nullptr, nullptr);
capcom::capcom_run(capcom, [&status, &handle, &obAttr, &entry_point](auto routine)
{
_enable();
using namespace drvmap::structs;
status = PsCreateSystemThread(&handle, GENERIC_READ, &obAttr, nullptr, nullptr, (void(*)(void*))entry_point, nullptr);
if(NT_SUCCESS(status))
{
ZwClose(handle);
}
_disable();
});
if(NT_SUCCESS(status))
{
printf("successfully created driver object!\n");
} else
{
printf("creating of driver object failed! 0x%I32X\n", status);
}
return 0;
}
+134
View File
@@ -0,0 +1,134 @@
#pragma once
#include <Windows.h>
#define MDL_MAPPED_TO_SYSTEM_VA 0x0001
#define MDL_PAGES_LOCKED 0x0002
#define MDL_SOURCE_IS_NONPAGED_POOL 0x0004
#define MDL_ALLOCATED_FIXED_SIZE 0x0008
#define MDL_PARTIAL 0x0010
#define MDL_PARTIAL_HAS_BEEN_MAPPED 0x0020
#define MDL_IO_PAGE_READ 0x0040
#define MDL_WRITE_OPERATION 0x0080
#define MDL_LOCKED_PAGE_TABLES 0x0100
#define MDL_PARENT_MAPPED_SYSTEM_VA MDL_LOCKED_PAGE_TABLES
#define MDL_FREE_EXTRA_PTES 0x0200
#define MDL_DESCRIBES_AWE 0x0400
#define MDL_IO_SPACE 0x0800
#define MDL_NETWORK_HEADER 0x1000
#define MDL_MAPPING_CAN_FAIL 0x2000
#define MDL_PAGE_CONTENTS_INVARIANT 0x4000
#define MDL_ALLOCATED_MUST_SUCCEED MDL_PAGE_CONTENTS_INVARIANT
#define MDL_INTERNAL 0x8000
#define MDL_MAPPING_FLAGS (MDL_MAPPED_TO_SYSTEM_VA | \
MDL_PAGES_LOCKED | \
MDL_SOURCE_IS_NONPAGED_POOL | \
MDL_PARTIAL_HAS_BEEN_MAPPED | \
MDL_PARENT_MAPPED_SYSTEM_VA | \
MDL_SYSTEM_VA | \
MDL_IO_SPACE )
namespace drvmap::structs
{
using PHYSICAL_ADDRESS = LARGE_INTEGER;
using KPROCESSOR_MODE = CCHAR;
typedef enum _MEMORY_CACHING_TYPE {
MmNonCached = 0,
MmCached = 1,
MmWriteCombined = 2,
MmHardwareCoherentCached = 3,
MmNonCachedUnordered = 4,
MmUSWCCached = 5,
MmMaximumCacheType = 6
} MEMORY_CACHING_TYPE;
typedef enum _MM_PAGE_PRIORITY {
LowPagePriority,
NormalPagePriority = 16,
HighPagePriority = 32
} MM_PAGE_PRIORITY;
typedef enum _MODE {
KernelMode,
UserMode,
MaximumMode
} MODE;
typedef enum _POOL_TYPE {
NonPagedPool,
NonPagedPoolExecute = NonPagedPool,
PagedPool,
NonPagedPoolMustSucceed = NonPagedPool + 2,
DontUseThisType,
NonPagedPoolCacheAligned = NonPagedPool + 4,
PagedPoolCacheAligned,
NonPagedPoolCacheAlignedMustS = NonPagedPool + 6,
MaxPoolType,
NonPagedPoolBase = 0,
NonPagedPoolBaseMustSucceed = NonPagedPoolBase + 2,
NonPagedPoolBaseCacheAligned = NonPagedPoolBase + 4,
NonPagedPoolBaseCacheAlignedMustS = NonPagedPoolBase + 6,
NonPagedPoolSession = 32,
PagedPoolSession = NonPagedPoolSession + 1,
NonPagedPoolMustSucceedSession = PagedPoolSession + 1,
DontUseThisTypeSession = NonPagedPoolMustSucceedSession + 1,
NonPagedPoolCacheAlignedSession = DontUseThisTypeSession + 1,
PagedPoolCacheAlignedSession = NonPagedPoolCacheAlignedSession + 1,
NonPagedPoolCacheAlignedMustSSession = PagedPoolCacheAlignedSession + 1,
NonPagedPoolNx = 512,
NonPagedPoolNxCacheAligned = NonPagedPoolNx + 4,
NonPagedPoolSessionNx = NonPagedPoolNx + 32
} POOL_TYPE;
typedef struct _MDL {
_MDL* Next;
SHORT Size;
SHORT MdlFlags;
SHORT AllocationProcessorNumber;
SHORT Reserved;
PVOID Process; // EPROCESS
PVOID MappedSystemVa;
PVOID StartVa;
UINT32 ByteCount;
UINT32 ByteOffset;
} MDL, *PMDL;
typedef struct _RTL_PROCESS_MODULE_INFORMATION
{
HANDLE Section;
PVOID MappedBase;
PVOID ImageBase;
ULONG ImageSize;
ULONG Flags;
USHORT LoadOrderIndex;
USHORT InitOrderIndex;
USHORT LoadCount;
USHORT OffsetToFileName;
UCHAR FullPathName[256];
} RTL_PROCESS_MODULE_INFORMATION, *PRTL_PROCESS_MODULE_INFORMATION;
typedef struct _RTL_PROCESS_MODULES
{
ULONG NumberOfModules;
RTL_PROCESS_MODULE_INFORMATION Modules[1];
} RTL_PROCESS_MODULES, *PRTL_PROCESS_MODULES;
using POBJECT_TYPE = struct _OBJECT_TYPE*;
using MmAllocatePagesForMdlFn = PMDL(*)(PHYSICAL_ADDRESS, PHYSICAL_ADDRESS, PHYSICAL_ADDRESS, SIZE_T);
using MmMapLockedPagesSpecifyCacheFn = PVOID(*)(PVOID, KPROCESSOR_MODE, MEMORY_CACHING_TYPE, PVOID, ULONG, MM_PAGE_PRIORITY);
using DRIVER_INITIALIZE = NTSTATUS(__stdcall)(
struct _DRIVER_OBJECT *,
PUNICODE_STRING
);
typedef DRIVER_INITIALIZE *PDRIVER_INITIALIZE;
using PCLIENT_ID = CLIENT_ID * ;
using KSTART_ROUTINE = VOID(PVOID);
typedef KSTART_ROUTINE *PKSTART_ROUTINE;
using PsCreateSystemThreadFn = NTSTATUS(*)(PHANDLE, ULONG, POBJECT_ATTRIBUTES, HANDLE, PCLIENT_ID, PKSTART_ROUTINE, PVOID);
using ExAllocatePoolWithTagFn = PVOID(*)(POOL_TYPE, SIZE_T, ULONG);
using RtlFindExportedRoutineByNameFn = void*(__fastcall*)(void *, const char *);
using IoCreateDriverFn = NTSTATUS(NTAPI*)(PUNICODE_STRING, PDRIVER_INITIALIZE);
using ZwCloseFn = NTSTATUS(NTAPI*)(HANDLE);
using ObReferenceObjectByHandleFn = NTSTATUS (NTAPI*)(HANDLE, ACCESS_MASK, POBJECT_TYPE, KPROCESSOR_MODE, PVOID*,PVOID);
}
+19
View File
@@ -0,0 +1,19 @@
#include "util.hpp"
#include <iterator>
#include <fstream>
namespace drvmap::util
{
void open_binary_file(const std::string & file, std::vector<uint8_t>& data)
{
std::ifstream file_stream(file, std::ios::binary);
file_stream.unsetf(std::ios::skipws);
file_stream.seekg(0, std::ios::end);
const auto file_size = file_stream.tellg();
file_stream.seekg(0, std::ios::beg);
data.reserve(static_cast<uint32_t>(file_size));
data.insert(data.begin(), std::istream_iterator<uint8_t>(file_stream), std::istream_iterator<uint8_t>());
}
}
+8
View File
@@ -0,0 +1,8 @@
#pragma once
#include <string>
#include <vector>
namespace drvmap::util
{
void open_binary_file(const std::string & file, std::vector<uint8_t>& data);
}