This commit is contained in:
lhodges1 2023-08-18 18:39:21 +10:00
parent 5afcec8926
commit 114a894d97
6 changed files with 94 additions and 32 deletions

25
service/Types.cs Normal file
View file

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace service
{
namespace Types
{
[StructLayout(LayoutKind.Explicit)]
public unsafe struct MODULE_VERIFICATION_CHECKSUM_FAILURE
{
[FieldOffset(0)]
public int ReportCode;
[FieldOffset(0)]
public UInt64 ModuleBaseAddress;
[FieldOffset(0)]
public UInt64 ModuleSize;
[FieldOffset(0)]
public fixed char ModuleName[512];
}
}
}

View file

@ -9,31 +9,27 @@ using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Serilog;
using System.Runtime.CompilerServices;
using service.Types;
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
#pragma warning disable CS8600
#pragma warning disable CS8603
namespace service
{
public struct TestReport
{
public UInt64 Num1;
public UInt64 Num2;
}
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
private NamedPipeServerStream _pipeServer;
private int _threadId;
private byte[] _buffer;
private Mutex _mutex;
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)
{
_logger.LogInformation("Windows service starting, waiting for client to connect");
@ -61,15 +57,37 @@ namespace service
private async Task TranslatePipeBuffer()
{
var packet = BytesToStructure<TestReport>();
int reportCode = BitConverter.ToInt32(_buffer, 0);
_logger.LogInformation("Report received with code: {0}", reportCode);
switch (reportCode)
{
case 10:
var packet = BytesToStructure<MODULE_VERIFICATION_CHECKSUM_FAILURE>();
unsafe
{
_logger.LogInformation("Report code: {0}, Base address: {1}, Size: {2}, Name: ",
packet.ReportCode,
packet.ModuleBaseAddress,
packet.ModuleSize);
}
goto end;
default:
_logger.LogError("Invalid report code received");
goto end;
}
end:
Array.Clear(_buffer, 0, _buffer.Length);
_logger.LogInformation("Num1: {0}, Num2: {1}", packet.Num1, packet.Num2);
}
private T BytesToStructure<T>()
{
int size = Marshal.SizeOf(typeof(T));
IntPtr ptr = Marshal.AllocHGlobal(size);
try
@ -84,4 +102,6 @@ namespace service
}
}
}
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
#pragma warning restore CS8600
#pragma warning restore CS8603

View file

@ -5,6 +5,7 @@
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>dotnet-service-ab667d6f-8728-45a8-a87c-ae511852674a</UserSecretsId>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>

View file

@ -6,20 +6,4 @@ global::Report::Report( std::shared_ptr<global::ThreadPool> ThreadPool, LPTSTR P
{
this->thread_pool = ThreadPool;
this->client = std::make_shared<global::Client>( PipeName );
//test report
TestReport report;
report.value1 = 10;
report.value2 = 1337;
this->ReportViolation( &report );
}
void global::Report::ReportViolation( TestReport* Report )
{
byte buffer[ 1024 ];
int size = sizeof( TestReport );
memcpy( buffer, Report, size );
LOG_INFO( "sending report over pipe" );
this->thread_pool->QueueJob( [ this, buffer, size ]() {this->client->WriteToPipe( (PVOID)buffer, size ); } );
}

View file

@ -5,6 +5,11 @@
#include "threadpool.h"
#include "client.h"
#include <TlHelp32.h>
#define REPORT_BUFFER_SIZE 1024
#define REPORT_CODE_MODULE_VERIFICATION 10
namespace global
{
@ -18,10 +23,32 @@ namespace global
{
std::shared_ptr<global::ThreadPool> thread_pool;
std::shared_ptr<global::Client> client;
std::mutex mutex;
byte buffer[ REPORT_BUFFER_SIZE ];
public:
Report( std::shared_ptr<global::ThreadPool> ThreadPool, LPTSTR PipeName );
void ReportViolation( TestReport* Report );
template <typename T>
void ReportViolation( T* Report )
{
mutex.lock();
memcpy( this->buffer, Report, sizeof( T ) );
this->client->WriteToPipe( buffer, sizeof(T) );
RtlZeroMemory( this->buffer, REPORT_BUFFER_SIZE );
mutex.unlock();
}
};
namespace report_structures
{
struct MODULE_VERIFICATION_CHECKSUM_FAILURE
{
INT report_code;
UINT64 module_base_address;
UINT64 module_size;
std::string module_name;
};
}
}
#endif

View file

@ -327,8 +327,13 @@ void usermode::Process::VerifyLoadedModuleChecksums(bool Init)
/* compare the current checksum to the previously calculated checksum */
if ( this->in_memory_module_checksums[ index ] != in_memory_check_sum )
{
LOG_INFO( "checksum changed!!!" );
/* if the checksum has changed do we store the new one or the old one? */
global::report_structures::MODULE_VERIFICATION_CHECKSUM_FAILURE report;
report.report_code = REPORT_CODE_MODULE_VERIFICATION;
report.module_base_address = (UINT64)module_entry.modBaseAddr;
report.module_size = module_entry.modBaseSize;
std::wstring wstr( module_entry.szModule );
report.module_name = std::string( wstr.begin(), wstr.end() );
this->report_interface->ReportViolation( &report );
}
//store the new checksums in a temp vector