This commit is contained in:
lhodges1 2023-08-18 15:33:13 +10:00
parent a7522bdbb8
commit 50240f4033
22 changed files with 318 additions and 12 deletions

30
ac.sln
View file

@ -7,28 +7,39 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "user", "user\user.vcxproj",
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "driver", "driver\driver.vcxproj", "{0AE83EC6-DDEA-4EDE-B1B2-1B2AB1E8BB54}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "service", "service\service.csproj", "{6228E9DD-E1EA-45D8-8054-A00FC2D63414}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|ARM64 = Debug|ARM64
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|ARM64 = Release|ARM64
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{3C8194C7-9F20-4FF8-8C4C-B26C3D053611}.Debug|Any CPU.ActiveCfg = Debug|x64
{3C8194C7-9F20-4FF8-8C4C-B26C3D053611}.Debug|Any CPU.Build.0 = Debug|x64
{3C8194C7-9F20-4FF8-8C4C-B26C3D053611}.Debug|ARM64.ActiveCfg = Debug|x64
{3C8194C7-9F20-4FF8-8C4C-B26C3D053611}.Debug|ARM64.Build.0 = Debug|x64
{3C8194C7-9F20-4FF8-8C4C-B26C3D053611}.Debug|x64.ActiveCfg = Debug|x64
{3C8194C7-9F20-4FF8-8C4C-B26C3D053611}.Debug|x64.Build.0 = Debug|x64
{3C8194C7-9F20-4FF8-8C4C-B26C3D053611}.Debug|x86.ActiveCfg = Debug|Win32
{3C8194C7-9F20-4FF8-8C4C-B26C3D053611}.Debug|x86.Build.0 = Debug|Win32
{3C8194C7-9F20-4FF8-8C4C-B26C3D053611}.Release|Any CPU.ActiveCfg = Release|x64
{3C8194C7-9F20-4FF8-8C4C-B26C3D053611}.Release|Any CPU.Build.0 = Release|x64
{3C8194C7-9F20-4FF8-8C4C-B26C3D053611}.Release|ARM64.ActiveCfg = Release|x64
{3C8194C7-9F20-4FF8-8C4C-B26C3D053611}.Release|ARM64.Build.0 = Release|x64
{3C8194C7-9F20-4FF8-8C4C-B26C3D053611}.Release|x64.ActiveCfg = Release|x64
{3C8194C7-9F20-4FF8-8C4C-B26C3D053611}.Release|x64.Build.0 = Release|x64
{3C8194C7-9F20-4FF8-8C4C-B26C3D053611}.Release|x86.ActiveCfg = Release|Win32
{3C8194C7-9F20-4FF8-8C4C-B26C3D053611}.Release|x86.Build.0 = Release|Win32
{0AE83EC6-DDEA-4EDE-B1B2-1B2AB1E8BB54}.Debug|Any CPU.ActiveCfg = Debug|x64
{0AE83EC6-DDEA-4EDE-B1B2-1B2AB1E8BB54}.Debug|Any CPU.Build.0 = Debug|x64
{0AE83EC6-DDEA-4EDE-B1B2-1B2AB1E8BB54}.Debug|Any CPU.Deploy.0 = Debug|x64
{0AE83EC6-DDEA-4EDE-B1B2-1B2AB1E8BB54}.Debug|ARM64.ActiveCfg = Debug|ARM64
{0AE83EC6-DDEA-4EDE-B1B2-1B2AB1E8BB54}.Debug|ARM64.Build.0 = Debug|ARM64
{0AE83EC6-DDEA-4EDE-B1B2-1B2AB1E8BB54}.Debug|ARM64.Deploy.0 = Debug|ARM64
@ -38,6 +49,9 @@ Global
{0AE83EC6-DDEA-4EDE-B1B2-1B2AB1E8BB54}.Debug|x86.ActiveCfg = Debug|x64
{0AE83EC6-DDEA-4EDE-B1B2-1B2AB1E8BB54}.Debug|x86.Build.0 = Debug|x64
{0AE83EC6-DDEA-4EDE-B1B2-1B2AB1E8BB54}.Debug|x86.Deploy.0 = Debug|x64
{0AE83EC6-DDEA-4EDE-B1B2-1B2AB1E8BB54}.Release|Any CPU.ActiveCfg = Release|x64
{0AE83EC6-DDEA-4EDE-B1B2-1B2AB1E8BB54}.Release|Any CPU.Build.0 = Release|x64
{0AE83EC6-DDEA-4EDE-B1B2-1B2AB1E8BB54}.Release|Any CPU.Deploy.0 = Release|x64
{0AE83EC6-DDEA-4EDE-B1B2-1B2AB1E8BB54}.Release|ARM64.ActiveCfg = Release|ARM64
{0AE83EC6-DDEA-4EDE-B1B2-1B2AB1E8BB54}.Release|ARM64.Build.0 = Release|ARM64
{0AE83EC6-DDEA-4EDE-B1B2-1B2AB1E8BB54}.Release|ARM64.Deploy.0 = Release|ARM64
@ -47,6 +61,22 @@ Global
{0AE83EC6-DDEA-4EDE-B1B2-1B2AB1E8BB54}.Release|x86.ActiveCfg = Release|x64
{0AE83EC6-DDEA-4EDE-B1B2-1B2AB1E8BB54}.Release|x86.Build.0 = Release|x64
{0AE83EC6-DDEA-4EDE-B1B2-1B2AB1E8BB54}.Release|x86.Deploy.0 = Release|x64
{6228E9DD-E1EA-45D8-8054-A00FC2D63414}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6228E9DD-E1EA-45D8-8054-A00FC2D63414}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6228E9DD-E1EA-45D8-8054-A00FC2D63414}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{6228E9DD-E1EA-45D8-8054-A00FC2D63414}.Debug|ARM64.Build.0 = Debug|Any CPU
{6228E9DD-E1EA-45D8-8054-A00FC2D63414}.Debug|x64.ActiveCfg = Debug|Any CPU
{6228E9DD-E1EA-45D8-8054-A00FC2D63414}.Debug|x64.Build.0 = Debug|Any CPU
{6228E9DD-E1EA-45D8-8054-A00FC2D63414}.Debug|x86.ActiveCfg = Debug|Any CPU
{6228E9DD-E1EA-45D8-8054-A00FC2D63414}.Debug|x86.Build.0 = Debug|Any CPU
{6228E9DD-E1EA-45D8-8054-A00FC2D63414}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6228E9DD-E1EA-45D8-8054-A00FC2D63414}.Release|Any CPU.Build.0 = Release|Any CPU
{6228E9DD-E1EA-45D8-8054-A00FC2D63414}.Release|ARM64.ActiveCfg = Release|Any CPU
{6228E9DD-E1EA-45D8-8054-A00FC2D63414}.Release|ARM64.Build.0 = Release|Any CPU
{6228E9DD-E1EA-45D8-8054-A00FC2D63414}.Release|x64.ActiveCfg = Release|Any CPU
{6228E9DD-E1EA-45D8-8054-A00FC2D63414}.Release|x64.Build.0 = Release|Any CPU
{6228E9DD-E1EA-45D8-8054-A00FC2D63414}.Release|x86.ActiveCfg = Release|Any CPU
{6228E9DD-E1EA-45D8-8054-A00FC2D63414}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

27
service/Program.cs Normal file
View file

@ -0,0 +1,27 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Serilog;
namespace service
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseWindowsService()
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<Worker>();
})
.UseSerilog((context, configuration) =>
{
var config = context.Configuration;
configuration.ReadFrom.Configuration(config);
});
}
}

View file

@ -0,0 +1,11 @@
{
"profiles": {
"service": {
"commandName": "Project",
"dotnetRunMessages": true,
"environmentVariables": {
"DOTNET_ENVIRONMENT": "Development"
}
}
}
}

57
service/Worker.cs Normal file
View file

@ -0,0 +1,57 @@
using System;
using System.Collections.Generic;
using System.IO.Pipes;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Serilog;
namespace service
{
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
private NamedPipeServerStream _pipeServer;
private int _threadId;
private byte[] _buffer;
public Worker(ILogger<Worker> logger)
{
_logger = logger;
_buffer = new byte[1024];
_pipeServer = new NamedPipeServerStream("DonnaACPipe", PipeDirection.InOut, 1);
_threadId = Thread.CurrentThread.ManagedThreadId;
}
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
int bytesRead = 0;
int offset = 0;
_logger.LogInformation("Windows service starting, waiting for client to connect");
while (!stoppingToken.IsCancellationRequested)
{
_pipeServer.WaitForConnection();
_logger.LogInformation("Client connected to the pipe server");
try
{
while ((bytesRead = _pipeServer.Read(_buffer, offset, unchecked((int)_pipeServer.Length))) > 0)
{
offset += bytesRead;
}
}
catch (Exception ex)
{
_logger.LogError("Reading buffer from pipe failed with status: {1}", ex.Message);
}
}
}
}
}
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously

View file

@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}

21
service/appsettings.json Normal file
View file

@ -0,0 +1,21 @@
{
"AllowedHosts": "*",
"Serilog": {
"MinimumLevel": "Debug",
"Override": {
"Microsoft.AspNetCore": "Warning"
},
"WriteTo": [
{
"Name": "Console"
},
{
"Name": "File",
"Args": {
"path": "bin/logs.txt",
"rollingInterval": "Day"
}
}
]
}
}

20
service/service.csproj Normal file
View file

@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk.Worker">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>dotnet-service-ab667d6f-8728-45a8-a87c-ae511852674a</UserSecretsId>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="2.1.1" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="7.0.1" />
<PackageReference Include="Serilog" Version="3.0.1" />
<PackageReference Include="Serilog.AspNetCore" Version="7.0.0" />
<PackageReference Include="Serilog.Extensions.Hosting" Version="7.0.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="7.0.0" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
</ItemGroup>
</Project>

42
user/client.cpp Normal file
View file

@ -0,0 +1,42 @@
#include "client.h"
#include "common.h"
global::Client::Client( LPTSTR PipeName )
{
this->pipe_name = PipeName;
this->pipe_handle = CreateFile(
this->pipe_name,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL
);
if ( this->pipe_handle == INVALID_HANDLE_VALUE )
{
LOG_ERROR( "CreateFile failed with status 0x%x", GetLastError() );
return;
}
}
void global::Client::WriteToPipe( TestReport* Report )
{
DWORD bytes_written;
WriteFile(
this->pipe_handle,
Report,
sizeof( TestReport ),
&bytes_written,
NULL
);
if ( bytes_written == 0 )
{
LOG_ERROR( "WriteFile failed with status code 0x%x", GetLastError() );
return;
}
}

21
user/client.h Normal file
View file

@ -0,0 +1,21 @@
#ifndef CLIENT_H
#define CLIENT_H
#include <Windows.h>
#include "report.h"
namespace global
{
class Client
{
HANDLE pipe_handle;
LPTSTR pipe_name;
public:
Client(LPTSTR PipeName);
void WriteToPipe( TestReport* Report );
};
}
#endif

View file

@ -1,6 +1,7 @@
#include "driver.h"
kernelmode::Driver::Driver(LPCWSTR DriverName)
kernelmode::Driver::Driver(LPCWSTR DriverName, std::shared_ptr<global::Report> ReportInterface )
{
this->driver_name = DriverName;
this->report_interface = ReportInterface;
}

View file

@ -4,6 +4,7 @@
#include <Windows.h>
#include "../threadpool.h"
#include "../report.h"
namespace kernelmode
{
@ -11,11 +12,12 @@ namespace kernelmode
{
HANDLE driver_handle;
LPCWSTR driver_name;
std::shared_ptr<global::Report> report_interface;
public:
std::shared_ptr<global::ThreadPool> thread_pool;
Driver(LPCWSTR DriverName);
Driver(LPCWSTR DriverName, std::shared_ptr<global::Report> ReportInterface );
};
}

View file

@ -1,7 +1,7 @@
#include "kmanager.h"
kernelmode::KManager::KManager( LPCWSTR DriverName, std::shared_ptr<global::ThreadPool> ThreadPool )
kernelmode::KManager::KManager( LPCWSTR DriverName, std::shared_ptr<global::ThreadPool> ThreadPool, std::shared_ptr<global::Report> ReportInterface)
{
this->driver_interface = std::make_unique<Driver>(DriverName);
this->driver_interface = std::make_unique<Driver>(DriverName, ReportInterface);
this->thread_pool = ThreadPool;
}

View file

@ -3,7 +3,9 @@
#include <windows.h>
#include "../report.h"
#include "..\threadpool.h"
#include "driver.h"
namespace kernelmode
@ -13,7 +15,7 @@ namespace kernelmode
std::unique_ptr<Driver> driver_interface;
std::shared_ptr<global::ThreadPool> thread_pool;
public:
KManager( LPCWSTR DriverName, std::shared_ptr<global::ThreadPool> ThreadPool );
KManager( LPCWSTR DriverName, std::shared_ptr<global::ThreadPool> ThreadPool, std::shared_ptr<global::Report> ReportInterface);
};
}

View file

@ -5,6 +5,7 @@
#include "common.h"
#include "threadpool.h"
#include "report.h"
#include "../user/um/umanager.h"
#include "../user/km/kmanager.h"
@ -18,9 +19,12 @@ DWORD WINAPI Init(HINSTANCE hinstDLL)
std::this_thread::sleep_for( std::chrono::seconds( 1 ) );
std::shared_ptr<global::ThreadPool> thread_pool = std::make_shared<global::ThreadPool>( 4 );
LPTSTR pipe_name = (LPTSTR)L"DonnaACPipe";
usermode::UManager umanager( thread_pool );
std::shared_ptr<global::ThreadPool> thread_pool = std::make_shared<global::ThreadPool>( 4 );
std::shared_ptr<global::Report> report_interface = std::make_shared<global::Report>( thread_pool, pipe_name );
usermode::UManager umanager( thread_pool, report_interface );
//kernelmode::KManager kmanager( L"DonnaAC", thread_pool);
umanager.ValidateProcessModules();

12
user/report.cpp Normal file
View file

@ -0,0 +1,12 @@
#include "report.h"
global::Report::Report( std::shared_ptr<global::ThreadPool> ThreadPool, LPTSTR PipeName )
{
this->thread_pool = ThreadPool;
this->client = std::make_unique<global::Client>( PipeName );
}
void global::Report::ReportViolation( TestReport* Report )
{
this->thread_pool->QueueJob( [ this, Report ]() {this->client->WriteToPipe( Report ); } );
}

27
user/report.h Normal file
View file

@ -0,0 +1,27 @@
#ifndef REPORT_H
#define REPORT_H
#include <Windows.h>
#include "threadpool.h"
#include "client.h"
struct TestReport
{
UINT64 value1;
UINT64 value2;
};
namespace global
{
class Report
{
std::shared_ptr<global::ThreadPool> thread_pool;
std::unique_ptr<global::Client> client;
public:
Report( std::shared_ptr<global::ThreadPool> ThreadPool, LPTSTR PipeName );
void ReportViolation( TestReport* Report );
};
}
#endif

View file

@ -7,12 +7,13 @@
#include <ImageHlp.h>
#include <iostream>
usermode::Process::Process()
usermode::Process::Process( std::shared_ptr<global::Report> ReportInterface )
{
this->process_handle = GetCurrentProcess();
this->process_id = GetCurrentProcessId();
this->function_imports = std::make_unique<Imports>();
this->VerifyLoadedModuleChecksums( true );
this->report_interface = ReportInterface;
}
void usermode::Process::ValidateProcessThreads()

View file

@ -6,6 +6,7 @@
#include <TlHelp32.h>
#include <string>
#include "../report.h"
#include "../threadpool.h"
#include "../um/imports.h"
@ -26,6 +27,7 @@ namespace usermode
std::mutex mutex;
std::unique_ptr<Imports> function_imports;
std::vector<DWORD> in_memory_module_checksums;
std::shared_ptr<global::Report> report_interface;
HANDLE GetHandleToProcessGivenName( std::string ProcessName );
std::vector<UINT64> GetProcessThreadsStartAddresses();
@ -36,7 +38,7 @@ namespace usermode
public:
Process();
Process( std::shared_ptr<global::Report> ReportInterface );
void ValidateProcessThreads();
void ScanProcessMemory();

View file

@ -6,10 +6,10 @@
#include <TlHelp32.h>
usermode::UManager::UManager( std::shared_ptr<global::ThreadPool> ThreadPool )
usermode::UManager::UManager( std::shared_ptr<global::ThreadPool> ThreadPool, std::shared_ptr<global::Report> ReportInterface )
{
this->thread_pool = ThreadPool;
this->process = std::make_unique<Process>();
this->process = std::make_unique<Process>(ReportInterface);
}
usermode::UManager::~UManager()

View file

@ -8,6 +8,8 @@
#include <thread>
#include <vector>
#include "../report.h"
#include "process.h"
namespace usermode
@ -23,7 +25,7 @@ namespace usermode
std::shared_ptr<global::ThreadPool> thread_pool;
public:
UManager( std::shared_ptr<global::ThreadPool> ThreadPool );
UManager( std::shared_ptr<global::ThreadPool> ThreadPool, std::shared_ptr<global::Report> ReportInterface );
~UManager();
void ValidateProcessThreads();

View file

@ -129,6 +129,7 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="client.cpp" />
<ClCompile Include="km\driver.cpp" />
<ClCompile Include="km\kmanager.cpp" />
<ClCompile Include="main.cpp" />
@ -136,11 +137,14 @@
<ClCompile Include="um\process.cpp" />
<ClCompile Include="threadpool.cpp" />
<ClCompile Include="um\umanager.cpp" />
<ClCompile Include="report.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="client.h" />
<ClInclude Include="common.h" />
<ClInclude Include="km\driver.h" />
<ClInclude Include="km\kmanager.h" />
<ClInclude Include="report.h" />
<ClInclude Include="um\imports.h" />
<ClInclude Include="um\process.h" />
<ClInclude Include="threadpool.h" />

View file

@ -36,6 +36,12 @@
<ClCompile Include="km\driver.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="report.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="client.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="common.h">
@ -59,5 +65,11 @@
<ClInclude Include="km\driver.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="report.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="client.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>