commit e2b3fca40363df704bf0254dfbafe62f9fafdc73 Author: not-wlan Date: Sat Dec 30 22:44:44 2017 +0100 initial diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9c455c3 --- /dev/null +++ b/.gitignore @@ -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 diff --git a/Neues Textdokument.txt b/Neues Textdokument.txt new file mode 100644 index 0000000..e69de29 diff --git a/capcom.sln b/capcom.sln new file mode 100644 index 0000000..ed01be4 --- /dev/null +++ b/capcom.sln @@ -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 diff --git a/capcom/capcom.cpp b/capcom/capcom.cpp new file mode 100644 index 0000000..761a6f8 --- /dev/null +++ b/capcom/capcom.cpp @@ -0,0 +1,64 @@ +#include "capcom.hpp" +#include +#pragma intrinsic(_disable) +#pragma intrinsic(_enable) + +namespace capcom +{ + std::unique_ptr 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(&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(payload_function); + const auto payload = std::make_unique(); + 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; + } +} diff --git a/capcom/capcom.hpp b/capcom/capcom.hpp new file mode 100644 index 0000000..a5ff58d --- /dev/null +++ b/capcom/capcom.hpp @@ -0,0 +1,22 @@ +#pragma once +#include +#include + +#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; + using driver_handle = std::shared_ptr>; + + unsigned long capcom_run(const driver_handle device, user_function payload); + + uintptr_t get_system_routine(const driver_handle device, const std::wstring& name); +} diff --git a/capcom/capcom.vcxproj b/capcom/capcom.vcxproj new file mode 100644 index 0000000..f836776 --- /dev/null +++ b/capcom/capcom.vcxproj @@ -0,0 +1,117 @@ + + + + + Debug + x64 + + + LibRelease + x64 + + + Release + x64 + + + + 15.0 + {329B6895-3CAB-43A7-AA43-6BDFF5072110} + capcom + 10.0.16299.0 + + + + StaticLibrary + true + v141 + MultiByte + + + StaticLibrary + false + v141 + true + MultiByte + + + StaticLibrary + false + v141 + true + MultiByte + + + + + + + + + + + + + + + + + + + + + Level3 + Disabled + true + true + stdcpp17 + + + + + Level3 + MaxSpeed + true + true + true + true + stdcpp17 + + + true + true + C:\Program Files (x86)\Windows Kits\10\Lib\10.0.16299.0\km\x64;%(AdditionalLibraryDirectories) + + + + + Level3 + MaxSpeed + true + true + true + true + stdcpp17 + C:\Program Files (x86)\Windows Kits\10\Include\10.0.16299.0\km;%(AdditionalIncludeDirectories) + + + true + true + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/capcom/capcom.vcxproj.filters b/capcom/capcom.vcxproj.filters new file mode 100644 index 0000000..96f24f1 --- /dev/null +++ b/capcom/capcom.vcxproj.filters @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/capcom/kernel.cpp b/capcom/kernel.cpp new file mode 100644 index 0000000..0cee5cc --- /dev/null +++ b/capcom/kernel.cpp @@ -0,0 +1,7 @@ +#include "kernel.hpp" + +namespace kernel +{ + + +} \ No newline at end of file diff --git a/capcom/kernel.hpp b/capcom/kernel.hpp new file mode 100644 index 0000000..6aa2bc5 --- /dev/null +++ b/capcom/kernel.hpp @@ -0,0 +1,11 @@ +#pragma once +#define WIN32_NO_STATUS +#include +#include +#undef WIN32_NO_STATUS +#include + +namespace kernel +{ + using MmGetSystemRoutineAddressFn = PVOID(NTAPI*)(PUNICODE_STRING); +} \ No newline at end of file diff --git a/capcom/main.cpp b/capcom/main.cpp new file mode 100644 index 0000000..aca1984 --- /dev/null +++ b/capcom/main.cpp @@ -0,0 +1,33 @@ +#define RELEASE +#include + +#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; +} diff --git a/capcom/process.cpp b/capcom/process.cpp new file mode 100644 index 0000000..6efef9e --- /dev/null +++ b/capcom/process.cpp @@ -0,0 +1,119 @@ +#include "process.hpp" +#include +#pragma intrinsic(_disable) +#pragma intrinsic(_enable) +#include + +#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(MmGetSystemRoutineAddress(&usPsLookupProcessByProcessId)); + ObDereferenceObject = static_cast(MmGetSystemRoutineAddress(&usObDereferenceObject)); + PsProcessType = static_cast(MmGetSystemRoutineAddress(&usPsProcessType)); + ObOpenObjectByPointer = static_cast(MmGetSystemRoutineAddress(&usObOpenObjectByPointer)); + ZwTerminateProcess = static_cast(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); + } +} diff --git a/capcom/process.hpp b/capcom/process.hpp new file mode 100644 index 0000000..9fe8d24 --- /dev/null +++ b/capcom/process.hpp @@ -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); +} + diff --git a/drvmap/drv_image.cpp b/drvmap/drv_image.cpp new file mode 100644 index 0000000..58b0e8c --- /dev/null +++ b/drvmap/drv_image.cpp @@ -0,0 +1,221 @@ +#include "drv_image.hpp" + +#include + +#include + + +namespace drvmap +{ + drv_image::drv_image(std::vector& image) : m_image(std::move(image)) + { + m_dos_header = reinterpret_cast(m_image.data()); + assert(m_dos_header->e_magic == IMAGE_DOS_SIGNATURE); + m_nt_headers = reinterpret_cast((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((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", §ion.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(relocation_base + IMR_RELOFFSET(data)); + *raw_address += static_cast(HIWORD(image_base_delta)); + break; + } + case IMAGE_REL_BASED_LOW: + { + const auto raw_address = reinterpret_cast(relocation_base + IMR_RELOFFSET(data)); + *raw_address += static_cast(LOWORD(image_base_delta)); + break; + } + case IMAGE_REL_BASED_HIGHLOW: + { + const auto raw_address = reinterpret_cast(relocation_base + IMR_RELOFFSET(data)); + *raw_address += static_cast(image_base_delta); + break; + } + case IMAGE_REL_BASED_DIR64: + { + auto UNALIGNED raw_address = reinterpret_cast(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(static_cast(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(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(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(relocation_data); + } + + } + + template + __forceinline T* ptr_add(void* base, uintptr_t offset) + { + return (T*)(uintptr_t)base + offset; + } + + + + void drv_image::fix_imports(const std::function get_module, const std::function get_function, const std::function get_function_ord){ + + ULONG size; + auto import_descriptors = static_cast(::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(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(import_descriptors->OriginalFirstThunk); + } + else + { + image_thunk_data = get_rva(import_descriptors->FirstThunk); + } + + auto image_func_data = get_rva(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(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(*(DWORD*)image_thunk_data); + const auto name_of_import = static_cast(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(); + } +} diff --git a/drvmap/drv_image.hpp b/drvmap/drv_image.hpp new file mode 100644 index 0000000..fe5f065 --- /dev/null +++ b/drvmap/drv_image.hpp @@ -0,0 +1,42 @@ +#pragma once +#include +#define WIN32_NO_STATUS +#include +#include +#undef WIN32_NO_STATUS +#include + +#include +#include +#include + +#pragma comment(lib, "Dbghelp.lib") +namespace drvmap +{ + class drv_image + { + std::vector m_image; + std::vector 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& 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 + __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 get_module, const std::function get_function, const std::function get_function_ord ); + void add_cookie(uintptr_t base); + void* data(); + }; +} diff --git a/drvmap/drvmap.vcxproj b/drvmap/drvmap.vcxproj new file mode 100644 index 0000000..5f670f9 --- /dev/null +++ b/drvmap/drvmap.vcxproj @@ -0,0 +1,150 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {14564628-1966-4822-8EC7-3BC613DE4FFE} + drvmap + 10.0.16299.0 + + + + Application + true + v141 + MultiByte + + + Application + false + v141 + true + MultiByte + + + Application + true + v141 + MultiByte + + + Application + false + v141 + true + MultiByte + + + + + + + + + + + + + + + + + + + + + + + Level3 + MaxSpeed + true + true + true + true + stdcpplatest + D:\Dev\asmjit\src\asmjit;C:\Users\Jan\source\repos\capcom\capcom;%(AdditionalIncludeDirectories) + + + true + true + NotSet + D:\Dev\asmjit\build\MinSizeRel;C:\Users\Jan\source\repos\capcom\x64\Release;%(AdditionalLibraryDirectories) + + + + + Level3 + Disabled + true + true + stdcpplatest + C:\Users\Jan\source\repos\capcom\capcom;%(AdditionalIncludeDirectories) + + + NotSet + C:\Users\Jan\source\repos\capcom\x64\Debug;%(AdditionalLibraryDirectories) + + + + + Level3 + Disabled + true + true + stdcpplatest + C:\Users\Jan\source\repos\capcom\capcom;%(AdditionalIncludeDirectories) + + + NotSet + C:\Users\Jan\source\repos\capcom\x64\Debug;%(AdditionalLibraryDirectories) + + + + + Level3 + MaxSpeed + true + true + true + true + stdcpplatest + C:\Users\Jan\source\repos\capcom\capcom;%(AdditionalIncludeDirectories) + + + true + true + NotSet + C:\Users\Jan\source\repos\capcom\x64\Release;%(AdditionalLibraryDirectories) + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/drvmap/drvmap.vcxproj.filters b/drvmap/drvmap.vcxproj.filters new file mode 100644 index 0000000..25c0376 --- /dev/null +++ b/drvmap/drvmap.vcxproj.filters @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/drvmap/main.cpp b/drvmap/main.cpp new file mode 100644 index 0000000..4823dfc --- /dev/null +++ b/drvmap/main.cpp @@ -0,0 +1,225 @@ +#include +#include +#include "drv_image.hpp" +#include "util.hpp" +#include "capcom.hpp" +#include "structs.hpp" +#include +#include +#include +#include + +#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 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(data.data()); + for (unsigned i = 0; i < modules->NumberOfModules; ++i) + { + const auto& driver = modules->Modules[i]; + const auto image_base = reinterpret_cast(driver.ImageBase); + std::string base_name = reinterpret_cast((uintptr_t)driver.FullPathName + driver.OffsetToFileName); + const auto offset = base_name.find_last_of("."); + + if (kmodule == base_name) + return reinterpret_cast(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(driver.ImageBase); + } + + return 0; +} + +std::pair allocate_kernel_memory(const capcom::driver_handle capcom, size_t size) +{ + using namespace drvmap::structs; + uintptr_t image_section; + + static auto ExAllocatePoolWithTag = reinterpret_cast(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(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(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(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(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 \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 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(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(RtlCopyMemoryPtr); + _RtlCopyMemory(target, source, size); + _disable(); + }); + + printf("calling entry point at 0x%I64X\n", entry_point); + + static auto PsCreateSystemThread = reinterpret_cast(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; +} \ No newline at end of file diff --git a/drvmap/structs.hpp b/drvmap/structs.hpp new file mode 100644 index 0000000..5691fcc --- /dev/null +++ b/drvmap/structs.hpp @@ -0,0 +1,134 @@ +#pragma once +#include +#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); +} diff --git a/drvmap/util.cpp b/drvmap/util.cpp new file mode 100644 index 0000000..e22fa16 --- /dev/null +++ b/drvmap/util.cpp @@ -0,0 +1,19 @@ +#include "util.hpp" +#include +#include + +namespace drvmap::util +{ + void open_binary_file(const std::string & file, std::vector& 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(file_size)); + data.insert(data.begin(), std::istream_iterator(file_stream), std::istream_iterator()); + } +} diff --git a/drvmap/util.hpp b/drvmap/util.hpp new file mode 100644 index 0000000..66d3f19 --- /dev/null +++ b/drvmap/util.hpp @@ -0,0 +1,8 @@ +#pragma once +#include +#include + +namespace drvmap::util +{ + void open_binary_file(const std::string & file, std::vector& data); +} \ No newline at end of file