initial with rebase

This commit is contained in:
pathtofile
2020-12-12 18:29:21 +11:00
commit 61e4d334b2
23 changed files with 1630 additions and 0 deletions
+29
View File
@@ -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
+66
View File
@@ -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
+7
View File
@@ -0,0 +1,7 @@
.vs/
.vscode/
bin/
*/Win32
*/x64
elam_driver/RC*
ppl_runner.pfx
+126
View File
@@ -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.
+31
View File
@@ -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;
}
+189
View File
@@ -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>
+4
View File
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
</Project>
+23
View File
@@ -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;
}
+16
View File
@@ -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"
}
+183
View File
@@ -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>
+31
View File
@@ -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>
+16
View File
@@ -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>
+158
View File
@@ -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"
+57
View File
@@ -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
+204
View File
@@ -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;
}
+14
View File
@@ -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, ...);
+198
View File
@@ -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>
+33
View File
@@ -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>
+23
View File
@@ -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>
+18
View File
@@ -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);
}
+178
View File
@@ -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;
}
+4
View File
@@ -0,0 +1,4 @@
# Change this:
$password = "password"
signtool.exe sign /fd SHA256 /a /v /ph /f $args[0] /p $password $args[1]