mirror of
https://github.com/pathtofile/PPLRunner
synced 2026-06-08 16:41:19 +00:00
initial with rebase
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Setup MsBuild
|
||||
uses: microsoft/setup-msbuild@v1
|
||||
|
||||
- name: Generate Certificate
|
||||
run: powershell.exe -f generate_cert.ps1
|
||||
|
||||
- name: Build Debug
|
||||
run: msbuild.exe /nologo /m /t:Rebuild /p:Configuration=Debug ppl_runner.sln
|
||||
|
||||
- name: Build Release
|
||||
run: msbuild.exe /nologo /m /t:Rebuild /p:Configuration=Release ppl_runner.sln
|
||||
@@ -0,0 +1,66 @@
|
||||
name: Publish Release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
|
||||
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Setup MsBuild
|
||||
uses: microsoft/setup-msbuild@v1
|
||||
|
||||
- name: Generate Certificate
|
||||
run: powershell.exe -f generate_cert.ps1
|
||||
|
||||
- name: Build Release
|
||||
run: msbuild.exe /nologo /m /t:Rebuild /p:Configuration=Release ppl_runner.sln
|
||||
|
||||
- name: Create Release
|
||||
id: create_release
|
||||
uses: actions/create-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ github.ref }}
|
||||
release_name: Release ${{ github.ref }}
|
||||
draft: false
|
||||
prerelease: false
|
||||
|
||||
- name: Upload Build - PPLRunner
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: ./bin/x64/Release/ppl_runner.exe
|
||||
asset_name: ppl_runner.exe
|
||||
asset_content_type: application/octet-stream
|
||||
|
||||
- name: Upload Build - ELAMDriver
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: ./bin/x64/Release/elam_driver.sys
|
||||
asset_name: elam_driver.sys
|
||||
asset_content_type: application/octet-stream
|
||||
|
||||
- name: Upload Cert
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: ./ppl_runner.pfx
|
||||
asset_name: ppl_runner.pfx
|
||||
asset_content_type: application/octet-stream
|
||||
@@ -0,0 +1,7 @@
|
||||
.vs/
|
||||
.vscode/
|
||||
bin/
|
||||
*/Win32
|
||||
*/x64
|
||||
elam_driver/RC*
|
||||
ppl_runner.pfx
|
||||
@@ -0,0 +1,126 @@
|
||||
# PPLRunner
|
||||
|
||||
This project is to enable running 'arbitrary`*`' process as an Anti Malware Protected-Process-Light (PPL), for research purposes.
|
||||
|
||||
(`*` See the [Restrictions](#restrictions) section for more details)
|
||||
|
||||
# Overview
|
||||
System protected process is a security model in Windows designed to protect system and anti-virus processes from
|
||||
tampering or introspection, even by Administrators/SYSTEM.
|
||||
|
||||
Processes started as an Anti Malware 'Protected Process-Light' (PPL) are restricted in what they can do, can only load signed code, but cannot be debugged, inspected, or stopped by non-Protected Processes. Additionally, they can
|
||||
get access to special data, such as the `Microsoft-Windows-Threat-Intelligence` ETW Provider.
|
||||
|
||||
This project creates an Early-Launch Anti Malware (ELAM) driver and usermode service. The service will launch a configurable child process when it starts which will also be marked as PPL.
|
||||
|
||||
The child binary must be signed with the same certificate as the service, along with some other [restrictions](#restrictions), but can otherwise be any binary and commandline arguments you chose.
|
||||
|
||||
Honestly I'm not doing a good job of explaining what ELAM and PPL are, instead I recommend starting here:
|
||||
- Chapter 3, Windows Internals Part 1 (#1 resource for anything Windows honestly)
|
||||
- https://docs.microsoft.com/en-us/windows/win32/services/protecting-anti-malware-services-
|
||||
- https://www.crowdstrike.com/blog/protected-processes-part-3-windows-pki-internals-signing-levels-scenarios-signers-root-keys/
|
||||
- https://googleprojectzero.blogspot.com/2018/10/injecting-code-into-windows-protected.html
|
||||
|
||||
|
||||
# Setup
|
||||
Make sure you have Windows SDKs installed.
|
||||
|
||||
Open `generate_cert.ps1` and `sign_file.ps1`, and change the `$password` variable to something else (they must match each other).
|
||||
|
||||
Run `generate_cert.ps1`. This will generate a `ppl_runner.pfx` with a new private and public certificate.
|
||||
This will be used to sign all binaries used by PPLRunner.
|
||||
|
||||
# Build
|
||||
Build `ppl_runner.sln`. This will produce 3 binaries:
|
||||
### elam_driver.sys
|
||||
The ELAM Kernel Driver that has the certificate information in it.
|
||||
The driver doesn't actually do anything, and won't actually be loaded, it is just used as a vessel for the
|
||||
signing certificate.
|
||||
|
||||
### ppl_runner.exe
|
||||
The Service installer and binary. As a PPL service, when started it will launch a child process,
|
||||
also as PPL, then stop and exit.
|
||||
|
||||
### child_example.exe
|
||||
An example executable that will be signed with the correct certificate by Visual Studio at build time.
|
||||
PPLRunner can run almost any binary, this is just an example that will be automatically signed.
|
||||
|
||||
# Install
|
||||
**NOTE** Only install on a testing machine, not production/your home PC.
|
||||
|
||||
1. Once built, copy `elam_driver.sys` and `ppl_runner.exe` to a folder on the target machine.
|
||||
|
||||
2. Enable test signing by running this from an elevated prompt, then reboot:
|
||||
```bash
|
||||
bcdedit /set testsigning on
|
||||
```
|
||||
|
||||
3. From an elevated command prompt, browse to the folder containing the copied executables and run:
|
||||
```bash
|
||||
ppl_runner.exe install
|
||||
```
|
||||
This should install a service named `ppl_runner`.
|
||||
|
||||
# Configure
|
||||
To sign a binary to run, sign it with the `ppl_runner.pfx` cert, using either the `sign_file.ps1` script,
|
||||
or just running `signtool.exe` yourself. If you don't have `signtool.exe`, it is in the Windows SDKs.
|
||||
|
||||
Create the registry key `HKLM\SOFTWARE\PPL_RUNNER`.
|
||||
Set the default/empty key to be a `REG_SZ`, containing the full path to the binary to execute,
|
||||
and any commandline argument. e.g. from the commandline:
|
||||
```cmd
|
||||
REG.exe ADD HKLM\SOFTWARE\PPL_RUNNER /ve /t REG_SZ /d "C:\path\to\binay --argument 1"
|
||||
```
|
||||
|
||||
# Run
|
||||
To make the service launch the executable, just run from an elevated prompt:
|
||||
```bash
|
||||
net start ppl_runner
|
||||
```
|
||||
As a PPL service, when started ppl_runner will read the registry key, launch the child process,
|
||||
also as PPL, then stop and exit. A successful launch will still say `the service failed to run`,
|
||||
but if you check the return code with `sc query ppl_runner`, it should be 0, i.e. ERROR_SUCCESS.
|
||||
|
||||
# Cleanup/Removal
|
||||
As the service is also Anti Malware PPL, it can only be stopped and deleted by a similarly high-level
|
||||
process. However, we can use PPLRunner to remove itself, simply set the command in the registry key to be:
|
||||
```powershell
|
||||
C:\path\to\ppl_runner.exe remove
|
||||
```
|
||||
And run the Service. i.e. run:
|
||||
```powershell
|
||||
REG.exe ADD HKLM\SOFTWARE\PPL_RUNNER /ve /t REG_SZ /d "C:\path\to\ppl_runner.exe remove"
|
||||
net start ppl_runner
|
||||
```
|
||||
|
||||
# Restrictions
|
||||
- This project only works in `testsigning` mode.
|
||||
- `ppl_runner.exe install` must be re-run after every reboot
|
||||
- The child binary must be signed with the same certificate as the service
|
||||
- Any DLLs the binary loads must also be signed
|
||||
|
||||
|
||||
# Debugging
|
||||
Run Sysinternal's DBGView and log `Win32 Global`, filtering on `*[PPL_RUNNER]*`.
|
||||
This will show all logs from the service and installer.
|
||||
|
||||
|
||||
# Example uses
|
||||
TBD - Sealighter blog
|
||||
|
||||
# Similar Projects
|
||||
[James Forshaw](https://twitter.com/tiraniddo) created an awesome project to [inject code into existing PPL processes](https://googleprojectzero.blogspot.com/2018/10/injecting-code-into-windows-protected.html).
|
||||
|
||||
# Futher Reading and Thanks
|
||||
Following [Alex Ionescu](https://twitter.com/aionescu) is probably the best way to learn more about ELAM and PPL.
|
||||
Possibly start with this:
|
||||
https://www.crowdstrike.com/blog/protected-processes-part-3-windows-pki-internals-signing-levels-scenarios-signers-root-keys/
|
||||
|
||||
|
||||
Following [Matt Graeber](https://twitter.com/mattifestation) and [James Forshaw](https://twitter.com/tiraniddo) is another great way.
|
||||
|
||||
Massive thanks to Matt for the
|
||||
[powershell script](https://gist.github.com/mattifestation/660d7e17e43e8f32c38d820115274d2e
|
||||
) to get the 'To-Be-Signed' hash from a certificate.
|
||||
|
||||
James has [written](https://googleprojectzero.blogspot.com/2017/08/bypassing-virtualbox-process-hardening.html) a [lot](https://googleprojectzero.blogspot.com/2018/10/injecting-code-into-windows-protected.html) about PPL and its flaws.
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
This is an example Process that can be run by the ppl_runner service
|
||||
|
||||
Visual Studio will build and sing the binary, so it can be run the the service as PPL
|
||||
*/
|
||||
|
||||
#include <Windows.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void log_msg(WCHAR* format, ...)
|
||||
{
|
||||
WCHAR log_msg[1024];
|
||||
|
||||
va_list arg_ptr;
|
||||
va_start(arg_ptr, format);
|
||||
int ret = _vsnwprintf_s(log_msg, 1024, 1024, format, arg_ptr);
|
||||
va_end(arg_ptr);
|
||||
OutputDebugString(log_msg);
|
||||
wprintf(log_msg);
|
||||
}
|
||||
|
||||
DWORD main(int argc, char** argv)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(argc);
|
||||
UNREFERENCED_PARAMETER(argv);
|
||||
for (DWORD i = 0; i < 100; i++) {
|
||||
log_msg(L"[PPL_RUNNER] Inside Child Runner: %02d\n", i);
|
||||
Sleep(3000);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" 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>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{3F506F07-052D-4792-9867-885D28201AFC}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>ppl_runner</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.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>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<UseOfMfc>Static</UseOfMfc>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<UseOfMfc>Static</UseOfMfc>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<UseOfMfc>Static</UseOfMfc>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<UseOfMfc>Static</UseOfMfc>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
<OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
<OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>powershell -ep bypass -f "$(SolutionDir)sign_file.ps1" "$(SolutionDir)ppl_runner.pfx" "$(TargetDir)$(TargetFileName)"</Command>
|
||||
</PostBuildEvent>
|
||||
<PostBuildEvent>
|
||||
<Message>Sign</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>powershell -ep bypass -f "$(SolutionDir)sign_file.ps1" "$(SolutionDir)ppl_runner.pfx" "$(TargetDir)$(TargetFileName)"</Command>
|
||||
</PostBuildEvent>
|
||||
<PostBuildEvent>
|
||||
<Message>Sign</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>powershell -ep bypass -f "$(SolutionDir)sign_file.ps1" "$(SolutionDir)ppl_runner.pfx" "$(TargetDir)$(TargetFileName)"</Command>
|
||||
</PostBuildEvent>
|
||||
<PostBuildEvent>
|
||||
<Message>Sign</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>powershell -ep bypass -f "$(SolutionDir)sign_file.ps1" "$(SolutionDir)ppl_runner.pfx" "$(TargetDir)$(TargetFileName)"</Command>
|
||||
</PostBuildEvent>
|
||||
<PostBuildEvent>
|
||||
<Message>Sign</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="child_example.c" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="child_example.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup />
|
||||
</Project>
|
||||
@@ -0,0 +1,23 @@
|
||||
#include <ntddk.h>
|
||||
#include <wdf.h>
|
||||
#include <windowsx.h>
|
||||
|
||||
DRIVER_INITIALIZE DriverEntry;
|
||||
|
||||
#ifdef ALLOC_PRAGMA
|
||||
#pragma alloc_text(INIT, DriverEntry)
|
||||
#endif // ALLOC_PRAGMA
|
||||
|
||||
NTSTATUS
|
||||
DriverEntry(
|
||||
_In_ PDRIVER_OBJECT DriverObject,
|
||||
_In_ PUNICODE_STRING RegistryPath
|
||||
)
|
||||
{
|
||||
// We don't need our driver to do anything
|
||||
UNREFERENCED_PARAMETER(DriverObject);
|
||||
UNREFERENCED_PARAMETER(RegistryPath);
|
||||
DbgPrint("[PPL_RUNNER] DriverEntry\n");
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#include <windows.h>
|
||||
#include <ntverp.h>
|
||||
|
||||
#define VER_FILETYPE VFT_DRV
|
||||
#define VER_FILESUBTYPE VFT2_DRV_SYSTEM
|
||||
#define VER_FILEDESCRIPTION_STR "PPL_RUNNER Driver"
|
||||
#define VER_INTERNALNAME_STR "elam_driver.sys"
|
||||
|
||||
#include "common.ver"
|
||||
MicrosoftElamCertificateInfo MSElamCertInfoID
|
||||
{
|
||||
1,
|
||||
L"36C968D145A9DE42AB3B93AC1FDA96CE19D122593C72A8082C698E02AE7F888D\0",
|
||||
0x800C,
|
||||
L"\0"
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{D246CB84-E7A9-4CCF-A32C-EEB23910D7BD}</ProjectGuid>
|
||||
<RootNamespace>$(MSBuildProjectName)</RootNamespace>
|
||||
<KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR>
|
||||
<Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
|
||||
<Platform Condition="'$(Platform)' == ''">Win32</Platform>
|
||||
<SampleGuid>{015D536C-9F60-4228-AD44-42A90A1AD014}</SampleGuid>
|
||||
<ProjectName>elam_driver</ProjectName>
|
||||
<WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<TargetVersion>Windows10</TargetVersion>
|
||||
<UseDebugLibraries>False</UseDebugLibraries>
|
||||
<DriverTargetPlatform>Desktop</DriverTargetPlatform>
|
||||
<DriverType>KMDF</DriverType>
|
||||
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
|
||||
<ConfigurationType>Driver</ConfigurationType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<TargetVersion>Windows10</TargetVersion>
|
||||
<UseDebugLibraries>True</UseDebugLibraries>
|
||||
<DriverTargetPlatform>Desktop</DriverTargetPlatform>
|
||||
<DriverType>KMDF</DriverType>
|
||||
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
|
||||
<ConfigurationType>Driver</ConfigurationType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<TargetVersion>Windows10</TargetVersion>
|
||||
<UseDebugLibraries>False</UseDebugLibraries>
|
||||
<DriverTargetPlatform>Desktop</DriverTargetPlatform>
|
||||
<DriverType>KMDF</DriverType>
|
||||
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
|
||||
<ConfigurationType>Driver</ConfigurationType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<TargetVersion>Windows10</TargetVersion>
|
||||
<UseDebugLibraries>True</UseDebugLibraries>
|
||||
<DriverTargetPlatform>Desktop</DriverTargetPlatform>
|
||||
<DriverType>KMDF</DriverType>
|
||||
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
|
||||
<ConfigurationType>Driver</ConfigurationType>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<PropertyGroup>
|
||||
<OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
|
||||
</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')" />
|
||||
</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')" />
|
||||
</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')" />
|
||||
</ImportGroup>
|
||||
<ItemGroup Label="WrappedTaskItems" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
<TargetName>$(ProjectName)</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
<TargetName>$(ProjectName)</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
<TargetName>$(ProjectName)</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
<TargetName>$(ProjectName)</TargetName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<ExceptionHandling>
|
||||
</ExceptionHandling>
|
||||
</ClCompile>
|
||||
<DriverSign>
|
||||
<FileDigestAlgorithm>
|
||||
</FileDigestAlgorithm>
|
||||
</DriverSign>
|
||||
<PostBuildEvent>
|
||||
<Command>powershell -ep bypass -f "$(SolutionDir)sign_file.ps1" "$(SolutionDir)ppl_runner.pfx" "$(TargetDir)$(TargetFileName)"</Command>
|
||||
</PostBuildEvent>
|
||||
<PostBuildEvent>
|
||||
<Message>Sign</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<ExceptionHandling>
|
||||
</ExceptionHandling>
|
||||
</ClCompile>
|
||||
<DriverSign>
|
||||
<FileDigestAlgorithm>
|
||||
</FileDigestAlgorithm>
|
||||
</DriverSign>
|
||||
<PostBuildEvent>
|
||||
<Command>powershell -ep bypass -f "$(SolutionDir)sign_file.ps1" "$(SolutionDir)ppl_runner.pfx" "$(TargetDir)$(TargetFileName)"</Command>
|
||||
</PostBuildEvent>
|
||||
<PostBuildEvent>
|
||||
<Message>Sign</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<ExceptionHandling>
|
||||
</ExceptionHandling>
|
||||
</ClCompile>
|
||||
<DriverSign>
|
||||
<FileDigestAlgorithm>
|
||||
</FileDigestAlgorithm>
|
||||
</DriverSign>
|
||||
<PostBuildEvent>
|
||||
<Command>powershell -ep bypass -f "$(SolutionDir)sign_file.ps1" "$(SolutionDir)ppl_runner.pfx" "$(TargetDir)$(TargetFileName)"</Command>
|
||||
</PostBuildEvent>
|
||||
<PostBuildEvent>
|
||||
<Message>Sign</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<ExceptionHandling>
|
||||
</ExceptionHandling>
|
||||
</ClCompile>
|
||||
<DriverSign>
|
||||
<FileDigestAlgorithm>
|
||||
</FileDigestAlgorithm>
|
||||
</DriverSign>
|
||||
<PostBuildEvent>
|
||||
<Command>powershell -ep bypass -f "$(SolutionDir)sign_file.ps1" "$(SolutionDir)ppl_runner.pfx" "$(TargetDir)$(TargetFileName)"</Command>
|
||||
</PostBuildEvent>
|
||||
<PostBuildEvent>
|
||||
<Message>Sign</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="elam_driver.c" />
|
||||
<ResourceCompile Include="elam_driver.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Inf Exclude="@(Inf)" Include="*.inf" />
|
||||
<FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Exclude="@(None)" Include="*.txt;*.htm;*.html" />
|
||||
<None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" />
|
||||
<None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
</Project>
|
||||
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions>
|
||||
<UniqueIdentifier>{00E51A05-37B6-4ADF-8287-9A1E383D471E}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
<UniqueIdentifier>{60767E85-74A5-45F0-8193-CE3A252910F0}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions>
|
||||
<UniqueIdentifier>{84579BC5-14A3-4B25-870C-590B67752AFC}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Driver Files">
|
||||
<Extensions>inf;inv;inx;mof;mc;</Extensions>
|
||||
<UniqueIdentifier>{0ACF3248-3C68-463F-8976-4323BC0957D6}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="elam_driver.rc">
|
||||
<Filter>Resource Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="elam_driver.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
<SignMode>Off</SignMode>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<SignMode>Off</SignMode>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<SignMode>Off</SignMode>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<SignMode>Off</SignMode>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,158 @@
|
||||
$password = "password"
|
||||
|
||||
# This is very, very graciouslly taken from Matt G!
|
||||
# https://gist.github.com/mattifestation/660d7e17e43e8f32c38d820115274d2e
|
||||
filter Get-TBSHash {
|
||||
[OutputType([String])]
|
||||
param (
|
||||
[Parameter(Mandatory, ValueFromPipeline)]
|
||||
[Security.Cryptography.X509Certificates.X509Certificate2]
|
||||
$Certificate
|
||||
)
|
||||
|
||||
Add-Type -TypeDefinition @'
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
namespace Crypto {
|
||||
public struct CRYPT_DATA_BLOB
|
||||
{
|
||||
public uint cbData;
|
||||
public IntPtr pbData;
|
||||
}
|
||||
public struct CRYPT_OBJID_BLOB
|
||||
{
|
||||
public uint cbData;
|
||||
public IntPtr pbData;
|
||||
}
|
||||
public struct CRYPT_ALGORITHM_IDENTIFIER
|
||||
{
|
||||
public string pszObjId;
|
||||
public CRYPT_OBJID_BLOB Parameters;
|
||||
}
|
||||
public struct CRYPT_BIT_BLOB
|
||||
{
|
||||
public uint cbData;
|
||||
public IntPtr pbData;
|
||||
public uint cUnusedBits;
|
||||
}
|
||||
public struct CERT_SIGNED_CONTENT_INFO
|
||||
{
|
||||
public CRYPT_DATA_BLOB ToBeSigned;
|
||||
public CRYPT_ALGORITHM_IDENTIFIER SignatureAlgorithm;
|
||||
public CRYPT_BIT_BLOB Signature;
|
||||
}
|
||||
public class NativeMethods {
|
||||
[DllImport("crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
public static extern bool CryptDecodeObject(uint dwCertEncodingType, IntPtr lpszStructType, [In] byte[] pbEncoded, uint cbEncoded, uint dwFlags, [Out] IntPtr pvStructInto, ref uint pcbStructInfo);
|
||||
}
|
||||
}
|
||||
'@
|
||||
|
||||
$HashOIDs = @{
|
||||
'1.2.840.113549.1.1.4' = 'MD5'
|
||||
'1.2.840.113549.1.1.5' = 'SHA1'
|
||||
'1.3.14.3.2.29' = 'SHA1'
|
||||
'1.2.840.113549.1.1.11' = 'SHA256'
|
||||
'1.2.840.113549.1.1.12' = 'SHA384'
|
||||
'1.2.840.113549.1.1.13' = 'SHA512'
|
||||
}
|
||||
|
||||
$CertBytes = $Certificate.RawData
|
||||
|
||||
$X509_PKCS7_ENCODING = 65537
|
||||
$X509_CERT = 1
|
||||
$CRYPT_DECODE_TO_BE_SIGNED_FLAG = 2
|
||||
$ErrorMoreData = 234
|
||||
|
||||
$TBSData = [IntPtr]::Zero
|
||||
[UInt32] $TBSDataSize = 0
|
||||
|
||||
$Success = [Crypto.NativeMethods]::CryptDecodeObject(
|
||||
$X509_PKCS7_ENCODING,
|
||||
[IntPtr] $X509_CERT,
|
||||
$CertBytes,
|
||||
$CertBytes.Length,
|
||||
$CRYPT_DECODE_TO_BE_SIGNED_FLAG,
|
||||
$TBSData,
|
||||
[ref] $TBSDataSize
|
||||
); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()
|
||||
|
||||
if((-not $Success) -and ($LastError -ne $ErrorMoreData))
|
||||
{
|
||||
throw "[CryptDecodeObject] Error: $(([ComponentModel.Win32Exception] $LastError).Message)"
|
||||
}
|
||||
|
||||
$TBSData = [Runtime.InteropServices.Marshal]::AllocHGlobal($TBSDataSize)
|
||||
|
||||
$Success = [Crypto.NativeMethods]::CryptDecodeObject(
|
||||
$X509_PKCS7_ENCODING,
|
||||
[IntPtr] $X509_CERT,
|
||||
$CertBytes,
|
||||
$CertBytes.Length,
|
||||
$CRYPT_DECODE_TO_BE_SIGNED_FLAG,
|
||||
$TBSData,
|
||||
[ref] $TBSDataSize
|
||||
); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()
|
||||
|
||||
if((-not $Success))
|
||||
{
|
||||
throw "[CryptDecodeObject] Error: $(([ComponentModel.Win32Exception] $LastError).Message)"
|
||||
}
|
||||
|
||||
$SignedContentInfo = [System.Runtime.InteropServices.Marshal]::PtrToStructure($TBSData, [Type][Crypto.CERT_SIGNED_CONTENT_INFO])
|
||||
|
||||
$TBSBytes = New-Object Byte[]($SignedContentInfo.ToBeSigned.cbData)
|
||||
[Runtime.InteropServices.Marshal]::Copy($SignedContentInfo.ToBeSigned.pbData, $TBSBytes, 0, $TBSBytes.Length)
|
||||
|
||||
[Runtime.InteropServices.Marshal]::FreeHGlobal($TBSData)
|
||||
|
||||
$HashAlgorithmStr = $HashOIDs[$SignedContentInfo.SignatureAlgorithm.pszObjId]
|
||||
|
||||
if (-not $HashAlgorithmStr) { throw 'Hash algorithm is not supported or it could not be retrieved.' }
|
||||
|
||||
$HashAlgorithm = [Security.Cryptography.HashAlgorithm]::Create($HashAlgorithmStr)
|
||||
|
||||
$TBSHashBytes = $HashAlgorithm.ComputeHash($TBSBytes)
|
||||
|
||||
($TBSHashBytes | % { $_.ToString('X2') }) -join ''
|
||||
}
|
||||
|
||||
# Generate new Certificate
|
||||
$certFolder = "Cert:\CurrentUser\My"
|
||||
$cert = New-SelfSignedCertificate -certstorelocation $certFolder -HashAlgorithm SHA256 -Subject "CN=ppl_runner" -TextExtension @("2.5.29.37={text}1.3.6.1.4.1.311.61.4.1,1.3.6.1.5.5.7.3.3")
|
||||
$certLocation = "$certFolder\"+$cert.Thumbprint
|
||||
# Use the awesome 'Get-TBSHash' from above
|
||||
$hash = Get-TBSHash $cert
|
||||
|
||||
# Write Hash to update in resource
|
||||
Write-Host "SHA256 Hash: $hash"
|
||||
|
||||
# Export from store using the password
|
||||
$passwordSecure = ConvertTo-SecureString -String $password -Force -AsPlainText
|
||||
$outputFilename = "ppl_runner.pfx"
|
||||
Export-PfxCertificate -cert $cert -FilePath $outputFilename -Password $passwordSecure
|
||||
|
||||
# Delete Certificate from store
|
||||
Remove-Item $certLocation
|
||||
$cert = $null
|
||||
|
||||
# Update Driver Resource with hash
|
||||
Write-Output @"
|
||||
#include <windows.h>
|
||||
#include <ntverp.h>
|
||||
|
||||
#define VER_FILETYPE VFT_DRV
|
||||
#define VER_FILESUBTYPE VFT2_DRV_SYSTEM
|
||||
#define VER_FILEDESCRIPTION_STR "ppl_runner Driver"
|
||||
#define VER_INTERNALNAME_STR "elam_driver.sys"
|
||||
|
||||
#include "common.ver"
|
||||
MicrosoftElamCertificateInfo MSElamCertInfoID
|
||||
{
|
||||
1,
|
||||
L"$hash\0",
|
||||
0x800C,
|
||||
L"\0"
|
||||
}
|
||||
"@ | Set-Content -Path ".\elam_driver\elam_driver.rc"
|
||||
Write-Host "Written Cert and key to $outputFilename"
|
||||
@@ -0,0 +1,57 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29806.167
|
||||
MinimumVisualStudioVersion = 12.0
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "elam_driver", "elam_driver\elam_driver.vcxproj", "{D246CB84-E7A9-4CCF-A32C-EEB23910D7BD}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ppl_runner", "ppl_runner\ppl_runner.vcxproj", "{9B632795-1BF2-44C7-8F23-BA24FB0DC0FF}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{D246CB84-E7A9-4CCF-A32C-EEB23910D7BD} = {D246CB84-E7A9-4CCF-A32C-EEB23910D7BD}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "child_example", "child_example\child_example.vcxproj", "{3F506F07-052D-4792-9867-885D28201AFC}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{9B632795-1BF2-44C7-8F23-BA24FB0DC0FF} = {9B632795-1BF2-44C7-8F23-BA24FB0DC0FF}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{D246CB84-E7A9-4CCF-A32C-EEB23910D7BD}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{D246CB84-E7A9-4CCF-A32C-EEB23910D7BD}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{D246CB84-E7A9-4CCF-A32C-EEB23910D7BD}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{D246CB84-E7A9-4CCF-A32C-EEB23910D7BD}.Debug|x64.Build.0 = Debug|x64
|
||||
{D246CB84-E7A9-4CCF-A32C-EEB23910D7BD}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{D246CB84-E7A9-4CCF-A32C-EEB23910D7BD}.Release|Win32.Build.0 = Release|Win32
|
||||
{D246CB84-E7A9-4CCF-A32C-EEB23910D7BD}.Release|x64.ActiveCfg = Release|x64
|
||||
{D246CB84-E7A9-4CCF-A32C-EEB23910D7BD}.Release|x64.Build.0 = Release|x64
|
||||
{9B632795-1BF2-44C7-8F23-BA24FB0DC0FF}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{9B632795-1BF2-44C7-8F23-BA24FB0DC0FF}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{9B632795-1BF2-44C7-8F23-BA24FB0DC0FF}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{9B632795-1BF2-44C7-8F23-BA24FB0DC0FF}.Debug|x64.Build.0 = Debug|x64
|
||||
{9B632795-1BF2-44C7-8F23-BA24FB0DC0FF}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{9B632795-1BF2-44C7-8F23-BA24FB0DC0FF}.Release|Win32.Build.0 = Release|Win32
|
||||
{9B632795-1BF2-44C7-8F23-BA24FB0DC0FF}.Release|x64.ActiveCfg = Release|x64
|
||||
{9B632795-1BF2-44C7-8F23-BA24FB0DC0FF}.Release|x64.Build.0 = Release|x64
|
||||
{3F506F07-052D-4792-9867-885D28201AFC}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{3F506F07-052D-4792-9867-885D28201AFC}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{3F506F07-052D-4792-9867-885D28201AFC}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{3F506F07-052D-4792-9867-885D28201AFC}.Debug|x64.Build.0 = Debug|x64
|
||||
{3F506F07-052D-4792-9867-885D28201AFC}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{3F506F07-052D-4792-9867-885D28201AFC}.Release|Win32.Build.0 = Release|Win32
|
||||
{3F506F07-052D-4792-9867-885D28201AFC}.Release|x64.ActiveCfg = Release|x64
|
||||
{3F506F07-052D-4792-9867-885D28201AFC}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {048C4861-AD36-499B-8649-83666EA2E677}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
ppl_runner
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <Windows.h>
|
||||
#include "ppl_runner.h"
|
||||
|
||||
|
||||
DWORD install_elam_cert()
|
||||
{
|
||||
DWORD retval = 0;
|
||||
HANDLE fileHandle = NULL;
|
||||
WCHAR driverName[] = DRIVER_NAME;
|
||||
|
||||
log_message(L"[PPL_RUNNER] install_elam_cert: Opening driver file: %s\n", driverName);
|
||||
fileHandle = CreateFile(driverName,
|
||||
FILE_READ_DATA,
|
||||
FILE_SHARE_READ,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL
|
||||
);
|
||||
if (fileHandle == INVALID_HANDLE_VALUE) {
|
||||
retval = GetLastError();
|
||||
log_message(L"[PPL_RUNNER] install_elam_cert: CreateFile Error: %d\n", retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
if (InstallELAMCertificateInfo(fileHandle) == FALSE) {
|
||||
retval = GetLastError();
|
||||
log_message(L"[PPL_RUNNER] install_elam_cert: install_elam_certificateInfo Error: %d\n", retval);
|
||||
return retval;
|
||||
}
|
||||
log_message(L"[PPL_RUNNER] install_elam_cert: Installed ELAM driver cert\n");
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
DWORD install_service()
|
||||
{
|
||||
DWORD retval = 0;
|
||||
SERVICE_LAUNCH_PROTECTED_INFO info;
|
||||
SC_HANDLE hService;
|
||||
SC_HANDLE hSCManager;
|
||||
|
||||
DWORD SCManagerAccess = SC_MANAGER_ALL_ACCESS;
|
||||
hSCManager = OpenSCManager(NULL, NULL, SCManagerAccess);
|
||||
if (hSCManager == NULL) {
|
||||
retval = GetLastError();
|
||||
log_message(L"[PPL_RUNNER] install_service: OpenSCManager Error: %d\n", retval);
|
||||
return retval;
|
||||
|
||||
}
|
||||
|
||||
// Get full path to ourselves with 'service' argv
|
||||
WCHAR serviceCMD[MAX_BUF_SIZE] = { 0 };
|
||||
GetModuleFileName(NULL, serviceCMD, MAX_BUF_SIZE);
|
||||
DWORD serviceCMDLen = lstrlenW(serviceCMD);
|
||||
wcscpy_s(serviceCMD + serviceCMDLen, MAX_BUF_SIZE - serviceCMDLen, L" service");
|
||||
|
||||
// Add PPL option
|
||||
info.dwLaunchProtected = SERVICE_LAUNCH_PROTECTED_ANTIMALWARE_LIGHT;
|
||||
hService = CreateService(
|
||||
hSCManager,
|
||||
SERVICE_NAME,
|
||||
SERVICE_NAME,
|
||||
SCManagerAccess,
|
||||
SERVICE_WIN32_OWN_PROCESS,
|
||||
SERVICE_DEMAND_START,
|
||||
SERVICE_ERROR_NORMAL,
|
||||
serviceCMD,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL, /* ServiceAccount */
|
||||
NULL
|
||||
);
|
||||
|
||||
if (hService == NULL) {
|
||||
retval = GetLastError();
|
||||
if (retval == ERROR_SERVICE_EXISTS) {
|
||||
log_message(L"[PPL_RUNNER] install_service: CreateService Error: Service '%s' Already Exists\n", SERVICE_NAME);
|
||||
log_message(L"[PPL_RUNNER] install_service: Run 'net start %s' to start the service\n", SERVICE_NAME);
|
||||
}
|
||||
else {
|
||||
log_message(L"[PPL_RUNNER] install_service: CreateService Error: %d\n", retval);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
// Mark service as protected
|
||||
if (ChangeServiceConfig2(hService, SERVICE_CONFIG_LAUNCH_PROTECTED, &info) == FALSE) {
|
||||
retval = GetLastError();
|
||||
log_message(L"[PPL_RUNNER] install_service: ChangeServiceConfig2 Error: %d\n", retval);
|
||||
return retval;
|
||||
}
|
||||
log_message(L"[PPL_RUNNER] install_service: install_service: Created Service: %s\n", serviceCMD);
|
||||
log_message(L"[PPL_RUNNER] install_service: Run 'net start %s' to start the service\n", SERVICE_NAME);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
DWORD remove_service() {
|
||||
DWORD retval = 0;
|
||||
SC_HANDLE hSCManager;
|
||||
SC_HANDLE hService;
|
||||
SERVICE_STATUS_PROCESS ssp;
|
||||
DWORD dwBytesNeeded;
|
||||
log_message(L"[PPL_RUNNER] remove_service: Stopping and Deleting Service %s...\n", SERVICE_NAME);
|
||||
|
||||
// Get Handle to Service Manager and Service
|
||||
hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
|
||||
if (hSCManager == NULL) {
|
||||
retval = GetLastError();
|
||||
log_message(L"[PPL_RUNNER] remove_service: OpenSCManager Error: %d\n", retval);
|
||||
return retval;
|
||||
|
||||
}
|
||||
hService = OpenService(hSCManager, SERVICE_NAME, SERVICE_ALL_ACCESS);
|
||||
if (hService == NULL) {
|
||||
retval = GetLastError();
|
||||
log_message(L"[PPL_RUNNER] remove_service: OpenService Error: %d\n", retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
// Get status of service
|
||||
if (!QueryServiceStatusEx(
|
||||
hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp, sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded)) {
|
||||
retval = GetLastError();
|
||||
log_message(L"[PPL_RUNNER] remove_service: QueryServiceStatusEx1 Error: %d\n", retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
if (ssp.dwCurrentState != SERVICE_STOPPED) {
|
||||
// Send a stop code to the service.
|
||||
if (!ControlService(hService, SERVICE_CONTROL_STOP, (LPSERVICE_STATUS)&ssp)) {
|
||||
retval = GetLastError();
|
||||
log_message(L"[PPL_RUNNER] remove_service: ControlService(Stop) Error: %d\n", retval);
|
||||
return retval;
|
||||
}
|
||||
if (ssp.dwCurrentState != SERVICE_STOPPED) {
|
||||
// Wait for service to die
|
||||
Sleep(3000);
|
||||
if (!QueryServiceStatusEx(
|
||||
hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp, sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded)) {
|
||||
retval = GetLastError();
|
||||
log_message(L"[PPL_RUNNER] remove_service: QueryServiceStatusEx2 Error: %d\n", retval);
|
||||
return retval;
|
||||
}
|
||||
if (ssp.dwCurrentState != SERVICE_STOPPED) {
|
||||
retval = ssp.dwCurrentState;
|
||||
log_message(L"[PPL_RUNNER] remove_service: Waited but service stull not stopped: %d\n", retval);
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Service stopped, now remove it
|
||||
if (!DeleteService(hService)) {
|
||||
retval = GetLastError();
|
||||
log_message(L"[PPL_RUNNER] remove_service: DeleteService Error: %d\n", retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
log_message(L"[PPL_RUNNER] remove_service: Deleted Service %s\n", SERVICE_NAME);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
DWORD main(INT argc, CHAR** argv)
|
||||
{
|
||||
DWORD retval = 0;
|
||||
log_message(L"[PPL_RUNNER] main: Start\n");
|
||||
|
||||
if (argc != 2) {
|
||||
log_message(L"[PPL_RUNNER] usage: ppl_runner.exe <install|service|remove>\n");
|
||||
retval = 1;
|
||||
}
|
||||
else if (strcmp(argv[1], "install") == 0) {
|
||||
log_message(L"[PPL_RUNNER] setting up ELAM stuff...\n");
|
||||
retval = install_elam_cert();
|
||||
if (retval == 0) {
|
||||
log_message(L"[PPL_RUNNER] Installing Service...\n");
|
||||
retval = install_service();
|
||||
}
|
||||
}
|
||||
else if (strcmp(argv[1], "service") == 0) {
|
||||
log_message(L"[PPL_RUNNER] Starting as a service...\n");
|
||||
retval = service_entry();
|
||||
}
|
||||
else if (strcmp(argv[1], "remove") == 0) {
|
||||
log_message(L"[PPL_RUNNER] Removing Service...\n");
|
||||
retval = remove_service();
|
||||
}
|
||||
else {
|
||||
log_message(L"[PPL_RUNNER] invalid commandline option\n");
|
||||
retval = 1;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
// These are the globals params that can be changed
|
||||
#define SERVICE_NAME L"ppl_runner"
|
||||
#define DRIVER_NAME L"elam_driver.sys"
|
||||
#define CMD_REGKEY L"SOFTWARE\\PPL_RUNNER"
|
||||
#define MAX_BUF_SIZE 1024
|
||||
|
||||
|
||||
VOID WINAPI ServiceMain(DWORD argc, LPTSTR* argv);
|
||||
VOID WINAPI service_ctrl_handler(DWORD);
|
||||
DWORD service_entry();
|
||||
|
||||
VOID log_message(WCHAR* format, ...);
|
||||
@@ -0,0 +1,198 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" 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>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{9B632795-1BF2-44C7-8F23-BA24FB0DC0FF}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>elaminstaller</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.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>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<UseOfMfc>Static</UseOfMfc>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<UseOfMfc>Static</UseOfMfc>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<UseOfMfc>Static</UseOfMfc>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<UseOfMfc>Static</UseOfMfc>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
<OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
<OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>Advapi32.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>powershell -ep bypass -f "$(SolutionDir)sign_file.ps1" "$(SolutionDir)ppl_runner.pfx" "$(TargetDir)$(TargetFileName)"</Command>
|
||||
</PostBuildEvent>
|
||||
<PostBuildEvent>
|
||||
<Message>Sign</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>Advapi32.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>powershell -ep bypass -f "$(SolutionDir)sign_file.ps1" "$(SolutionDir)ppl_runner.pfx" "$(TargetDir)$(TargetFileName)"</Command>
|
||||
</PostBuildEvent>
|
||||
<PostBuildEvent>
|
||||
<Message>Sign</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>Advapi32.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>powershell -ep bypass -f "$(SolutionDir)sign_file.ps1" "$(SolutionDir)ppl_runner.pfx" "$(TargetDir)$(TargetFileName)"</Command>
|
||||
</PostBuildEvent>
|
||||
<PostBuildEvent>
|
||||
<Message>Sign</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>Advapi32.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>powershell -ep bypass -f "$(SolutionDir)sign_file.ps1" "$(SolutionDir)ppl_runner.pfx" "$(TargetDir)$(TargetFileName)"</Command>
|
||||
</PostBuildEvent>
|
||||
<PostBuildEvent>
|
||||
<Message>Sign</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ppl_runner.c" />
|
||||
<ClCompile Include="ppl_runner_common.c" />
|
||||
<ClCompile Include="ppl_runner_service.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ppl_runner.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ppl_runner.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ppl_runner_service.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ppl_runner_common.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ppl_runner.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
<LocalDebuggerCommandArguments>install-service</LocalDebuggerCommandArguments>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
<LocalDebuggerCommandArguments>install-service</LocalDebuggerCommandArguments>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
<LocalDebuggerCommandArguments>install-service</LocalDebuggerCommandArguments>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
<LocalDebuggerCommandArguments>install-service</LocalDebuggerCommandArguments>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
Common Code and helper functions for ppl_runner
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <Windows.h>
|
||||
#include "ppl_runner.h"
|
||||
|
||||
VOID log_message(WCHAR* format, ...)
|
||||
{
|
||||
WCHAR message[MAX_BUF_SIZE];
|
||||
|
||||
va_list arg_ptr;
|
||||
va_start(arg_ptr, format);
|
||||
int ret = _vsnwprintf_s(message, MAX_BUF_SIZE, MAX_BUF_SIZE, format, arg_ptr);
|
||||
va_end(arg_ptr);
|
||||
OutputDebugString(message);
|
||||
wprintf(message);
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
ppl_runner Service
|
||||
Code for the Service that gets run
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <Windows.h>
|
||||
#include "ppl_runner.h"
|
||||
|
||||
SERVICE_STATUS g_ServiceStatus = { 0 };
|
||||
SERVICE_STATUS_HANDLE g_StatusHandle = NULL;
|
||||
|
||||
DWORD start_child_process()
|
||||
{
|
||||
DWORD retval = 0;
|
||||
WCHAR childCMD[MAX_BUF_SIZE] = { 0 };
|
||||
DWORD dataSize = MAX_BUF_SIZE;
|
||||
log_message(L"[PPL_RUNNER] start_child_process: Starting");
|
||||
|
||||
// Get Command to run from registry
|
||||
log_message(L"[PPL_RUNNER] start_child_process: Looking for command in RegKey: HKLM\\%s\n", CMD_REGKEY);
|
||||
|
||||
retval = RegGetValue(HKEY_LOCAL_MACHINE, CMD_REGKEY, NULL, RRF_RT_REG_SZ, NULL, &childCMD, &dataSize);
|
||||
if (retval != ERROR_SUCCESS) {
|
||||
log_message(L"[PPL_RUNNER] start_child_process: RegGetValue Error: %d\n", retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
// Create Attribute List
|
||||
STARTUPINFOEXW StartupInfoEx = { 0 };
|
||||
SIZE_T AttributeListSize = 0;
|
||||
StartupInfoEx.StartupInfo.cb = sizeof(StartupInfoEx);
|
||||
InitializeProcThreadAttributeList(NULL, 1, 0, &AttributeListSize);
|
||||
if (AttributeListSize == 0) {
|
||||
retval = GetLastError();
|
||||
log_message(L"[PPL_RUNNER] start_child_process: InitializeProcThreadAttributeList1 Error: %d\n", retval);
|
||||
return retval;
|
||||
}
|
||||
StartupInfoEx.lpAttributeList =
|
||||
(LPPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), 0, AttributeListSize);
|
||||
if (InitializeProcThreadAttributeList(StartupInfoEx.lpAttributeList, 1, 0, &AttributeListSize) == FALSE) {
|
||||
retval = GetLastError();
|
||||
log_message(L"[PPL_RUNNER] start_child_process: InitializeProcThreadAttributeList2 Error: %d\n", retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
// Set ProtectionLevel to be the same, i.e. PPL
|
||||
DWORD ProtectionLevel = PROTECTION_LEVEL_SAME;
|
||||
if (UpdateProcThreadAttribute(StartupInfoEx.lpAttributeList,
|
||||
0,
|
||||
PROC_THREAD_ATTRIBUTE_PROTECTION_LEVEL,
|
||||
&ProtectionLevel,
|
||||
sizeof(ProtectionLevel),
|
||||
NULL,
|
||||
NULL) == FALSE)
|
||||
{
|
||||
retval = GetLastError();
|
||||
log_message(L"[PPL_RUNNER] start_child_process: UpdateProcThreadAttribute Error: %d\n", retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
// Start Process (hopefully)
|
||||
PROCESS_INFORMATION ProcessInformation = { 0 };
|
||||
log_message(L"[PPL_RUNNER] start_child_process: Creating Process: '%s'\n", childCMD);
|
||||
if (CreateProcess(NULL,
|
||||
childCMD,
|
||||
NULL,
|
||||
NULL,
|
||||
FALSE,
|
||||
EXTENDED_STARTUPINFO_PRESENT | CREATE_PROTECTED_PROCESS,
|
||||
NULL,
|
||||
NULL,
|
||||
(LPSTARTUPINFOW)&StartupInfoEx,
|
||||
&ProcessInformation) == FALSE)
|
||||
{
|
||||
retval = GetLastError();
|
||||
if (retval == ERROR_INVALID_IMAGE_HASH) {
|
||||
log_message(L"[PPL_RUNNER] start_child_process: CreateProcess Error: Invalid Certificate\n");
|
||||
}
|
||||
else {
|
||||
log_message(L"[PPL_RUNNER] start_child_process: CreateProcess Error: %d\n", retval);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
// Don't wait on process handle, we're setting our child free into the wild
|
||||
// This is to prevent any possible deadlocks
|
||||
|
||||
log_message(L"[PPL_RUNNER] start_child_process finished");
|
||||
return retval;
|
||||
}
|
||||
|
||||
VOID WINAPI ServiceMain(DWORD argc, LPTSTR* argv)
|
||||
{
|
||||
DWORD retval = 0;
|
||||
log_message(L"[PPL_RUNNER] ServiceMain: Starting\n");
|
||||
|
||||
// Register our service control handler with the SCM
|
||||
g_StatusHandle = RegisterServiceCtrlHandler(SERVICE_NAME, service_ctrl_handler);
|
||||
if (g_StatusHandle == NULL)
|
||||
{
|
||||
retval = GetLastError();
|
||||
log_message(L"[PPL_RUNNER] ServiceMain: Registerservice_ctrl_handler Error: %d\n", retval);
|
||||
return;
|
||||
}
|
||||
ZeroMemory(&g_ServiceStatus, sizeof(g_ServiceStatus));
|
||||
g_ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
|
||||
|
||||
// Start Child Process
|
||||
retval = start_child_process();
|
||||
|
||||
// Tell the service controller we are stopped
|
||||
// So we can be run again
|
||||
g_ServiceStatus.dwControlsAccepted = 0;
|
||||
g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
|
||||
g_ServiceStatus.dwWin32ExitCode = retval;
|
||||
g_ServiceStatus.dwServiceSpecificExitCode = retval;
|
||||
g_ServiceStatus.dwCheckPoint = 0;
|
||||
if (SetServiceStatus(g_StatusHandle, &g_ServiceStatus) == FALSE)
|
||||
{
|
||||
retval = GetLastError();
|
||||
log_message(L"[PPL_RUNNER] ServiceMain: SetServiceStatus(Stopped) Error: %d\n", retval);
|
||||
return;
|
||||
}
|
||||
|
||||
log_message(L"[PPL_RUNNER] ServiceMain: Finished");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
VOID WINAPI service_ctrl_handler(DWORD ctrlCode)
|
||||
{
|
||||
// It should be very unlikley for this function to be called,
|
||||
// as our service only lives long enough to launch the child process
|
||||
DWORD retval = 0;
|
||||
|
||||
log_message(L"[PPL_RUNNER] Starting service_ctrl_handler");
|
||||
switch (ctrlCode)
|
||||
{
|
||||
case SERVICE_CONTROL_STOP:
|
||||
if (g_ServiceStatus.dwCurrentState != SERVICE_RUNNING)
|
||||
break;
|
||||
|
||||
g_ServiceStatus.dwControlsAccepted = 0;
|
||||
g_ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
|
||||
g_ServiceStatus.dwWin32ExitCode = 0;
|
||||
g_ServiceStatus.dwCheckPoint = 4;
|
||||
if (SetServiceStatus(g_StatusHandle, &g_ServiceStatus) == FALSE)
|
||||
{
|
||||
retval = GetLastError();
|
||||
log_message(L"[PPL_RUNNER] ServiceMain: SetServiceStatus(StopPending) Error: %d\n", retval);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DWORD service_entry()
|
||||
{
|
||||
// Basic boilerplate service setup
|
||||
DWORD retval = 0;
|
||||
SERVICE_TABLE_ENTRY serviceTable[] =
|
||||
{
|
||||
{SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION)ServiceMain},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
if (StartServiceCtrlDispatcher(serviceTable) == FALSE)
|
||||
{
|
||||
retval = GetLastError();
|
||||
log_message(L"[PPL_RUNNER] service_entry: StartServiceCtrlDispatcher error: %d\n", retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
# Change this:
|
||||
$password = "password"
|
||||
|
||||
signtool.exe sign /fd SHA256 /a /v /ph /f $args[0] /p $password $args[1]
|
||||
Reference in New Issue
Block a user