mirror of
https://github.com/donnaskiez/ac.git
synced 2024-11-21 22:24:08 +01:00
fix sig scan
This commit is contained in:
parent
114a894d97
commit
b7d3fdc14c
5 changed files with 176 additions and 45 deletions
|
@ -21,5 +21,28 @@ namespace service
|
|||
[FieldOffset(0)]
|
||||
public fixed char ModuleName[512];
|
||||
}
|
||||
|
||||
public struct PROCESS_THREAD_START_FAILURE
|
||||
{
|
||||
public int ReportCode;
|
||||
public long ThreadId;
|
||||
public UInt64 StartAddress;
|
||||
}
|
||||
|
||||
public struct PAGE_PROTECTION_FAILURE
|
||||
{
|
||||
public int ReportCode;
|
||||
public UInt64 PageBaseAddress;
|
||||
public long AllocationProtection;
|
||||
public long AllocationState;
|
||||
public long AllocationType;
|
||||
}
|
||||
|
||||
public struct PATTERN_SCAN_FAILURE
|
||||
{
|
||||
public int ReportCode;
|
||||
public int SignatureId;
|
||||
public UInt64 Address;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,11 @@ namespace service
|
|||
private NamedPipeServerStream _pipeServer;
|
||||
private byte[] _buffer;
|
||||
|
||||
private const int REPORT_CODE_MODULE_VERIFICATION = 10;
|
||||
private const int REPORT_CODE_START_ADDRESS_VERIFICATION = 20;
|
||||
private const int REPORT_PAGE_PROTECTION_VERIFICATION = 30;
|
||||
private const int REPORT_PATTERN_SCAN_FAILURE = 40;
|
||||
|
||||
public Worker(ILogger<Worker> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
|
@ -63,19 +68,55 @@ namespace service
|
|||
|
||||
switch (reportCode)
|
||||
{
|
||||
case 10:
|
||||
var packet = BytesToStructure<MODULE_VERIFICATION_CHECKSUM_FAILURE>();
|
||||
case REPORT_CODE_MODULE_VERIFICATION:
|
||||
|
||||
var checksumFailurePacket = BytesToStructure<MODULE_VERIFICATION_CHECKSUM_FAILURE>();
|
||||
|
||||
unsafe
|
||||
{
|
||||
_logger.LogInformation("Report code: {0}, Base address: {1}, Size: {2}, Name: ",
|
||||
packet.ReportCode,
|
||||
packet.ModuleBaseAddress,
|
||||
packet.ModuleSize);
|
||||
checksumFailurePacket.ReportCode,
|
||||
checksumFailurePacket.ModuleBaseAddress,
|
||||
checksumFailurePacket.ModuleSize);
|
||||
}
|
||||
|
||||
goto end;
|
||||
|
||||
case REPORT_CODE_START_ADDRESS_VERIFICATION:
|
||||
|
||||
var startAddressFailurePacket = BytesToStructure<PROCESS_THREAD_START_FAILURE>();
|
||||
|
||||
_logger.LogInformation("Report code: {0}, Thread Id: {1}, Start Address: {2}",
|
||||
startAddressFailurePacket.ReportCode,
|
||||
startAddressFailurePacket.ThreadId,
|
||||
startAddressFailurePacket.StartAddress);
|
||||
|
||||
goto end;
|
||||
|
||||
case REPORT_PAGE_PROTECTION_VERIFICATION:
|
||||
|
||||
var pageProtectionFailure = BytesToStructure<PAGE_PROTECTION_FAILURE>();
|
||||
|
||||
_logger.LogInformation("Report code: {0}, page base address: {1}, allocation protection {2}, allocation state: {3}, allocation type: {4}",
|
||||
pageProtectionFailure.ReportCode,
|
||||
pageProtectionFailure.PageBaseAddress,
|
||||
pageProtectionFailure.AllocationProtection,
|
||||
pageProtectionFailure.AllocationState,
|
||||
pageProtectionFailure.AllocationType);
|
||||
|
||||
goto end;
|
||||
|
||||
case REPORT_PATTERN_SCAN_FAILURE:
|
||||
|
||||
var patternScanFailure = BytesToStructure<PATTERN_SCAN_FAILURE>();
|
||||
|
||||
_logger.LogInformation("Report code: {0}, signature id: {1}, Address: {2}",
|
||||
patternScanFailure.ReportCode,
|
||||
patternScanFailure.SignatureId,
|
||||
patternScanFailure.Address);
|
||||
|
||||
goto end;
|
||||
|
||||
default:
|
||||
_logger.LogError("Invalid report code received");
|
||||
goto end;
|
||||
|
|
|
@ -27,6 +27,7 @@ DWORD WINAPI Init(HINSTANCE hinstDLL)
|
|||
usermode::UManager umanager( thread_pool, report_interface );
|
||||
//kernelmode::KManager kmanager( L"DonnaAC", thread_pool);
|
||||
umanager.ValidateProcessModules();
|
||||
umanager.ValidateProcessMemory();
|
||||
|
||||
while ( !GetAsyncKeyState( VK_DELETE ) )
|
||||
{
|
||||
|
|
|
@ -8,24 +8,24 @@
|
|||
#include <TlHelp32.h>
|
||||
|
||||
#define REPORT_BUFFER_SIZE 1024
|
||||
#define MAX_SIGNATURE_SIZE 256
|
||||
|
||||
#define REPORT_CODE_MODULE_VERIFICATION 10
|
||||
#define REPORT_CODE_START_ADDRESS_VERIFICATION 20
|
||||
#define REPORT_PAGE_PROTECTION_VERIFICATION 30
|
||||
#define REPORT_PATTERN_SCAN_FAILURE 40
|
||||
|
||||
namespace global
|
||||
{
|
||||
struct TestReport
|
||||
{
|
||||
UINT64 value1;
|
||||
UINT64 value2;
|
||||
};
|
||||
|
||||
class Report
|
||||
{
|
||||
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 );
|
||||
|
||||
template <typename T>
|
||||
|
@ -48,6 +48,29 @@ namespace global
|
|||
UINT64 module_size;
|
||||
std::string module_name;
|
||||
};
|
||||
|
||||
struct PROCESS_THREAD_START_FAILURE
|
||||
{
|
||||
INT report_code;
|
||||
LONG thread_id;
|
||||
UINT64 start_address;
|
||||
};
|
||||
|
||||
struct PAGE_PROTECTION_FAILURE
|
||||
{
|
||||
INT report_code;
|
||||
UINT64 page_base_address;
|
||||
LONG allocation_protection;
|
||||
LONG allocation_state;
|
||||
LONG allocation_type;
|
||||
};
|
||||
|
||||
struct PATTERN_SCAN_FAILURE
|
||||
{
|
||||
INT report_code;
|
||||
INT signature_id;
|
||||
UINT64 address;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,9 +4,13 @@
|
|||
#include "../um/imports.h"
|
||||
#include "memory.h"
|
||||
|
||||
#include "../report.h"
|
||||
|
||||
#include <ImageHlp.h>
|
||||
#include <iostream>
|
||||
|
||||
const static char MASK_BYTE = '\x00';
|
||||
|
||||
usermode::Process::Process( std::shared_ptr<global::Report> ReportInterface )
|
||||
{
|
||||
this->process_handle = GetCurrentProcess();
|
||||
|
@ -17,31 +21,13 @@ usermode::Process::Process( std::shared_ptr<global::Report> ReportInterface )
|
|||
}
|
||||
|
||||
void usermode::Process::ValidateProcessThreads()
|
||||
{
|
||||
bool result = false;
|
||||
std::vector<UINT64> threads = GetProcessThreadsStartAddresses();
|
||||
|
||||
for ( int i = 0; i < threads.size(); i++ )
|
||||
{
|
||||
if ( CheckIfAddressLiesWithinValidProcessModule( threads[ i ], &result ) )
|
||||
{
|
||||
if ( result == false )
|
||||
{
|
||||
//REPORT
|
||||
LOG_ERROR( "thread start address nto from process module OMG" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<UINT64> usermode::Process::GetProcessThreadsStartAddresses()
|
||||
{
|
||||
HANDLE thread_snapshot_handle = INVALID_HANDLE_VALUE;
|
||||
THREADENTRY32 thread_entry;
|
||||
NTSTATUS status;
|
||||
HANDLE thread_handle;
|
||||
UINT64 start_address;
|
||||
std::vector<UINT64> start_addresses;
|
||||
bool result;
|
||||
|
||||
pNtQueryInformationThread NtQueryInfo =
|
||||
( pNtQueryInformationThread )this->function_imports->ImportMap["NtQueryInformationThread"];
|
||||
|
@ -52,7 +38,7 @@ std::vector<UINT64> usermode::Process::GetProcessThreadsStartAddresses()
|
|||
if ( thread_snapshot_handle == INVALID_HANDLE_VALUE )
|
||||
{
|
||||
LOG_ERROR( "thread snapshot handle invalid with error 0x%x", GetLastError() );
|
||||
return {};
|
||||
return;
|
||||
}
|
||||
|
||||
thread_entry.dwSize = sizeof( THREADENTRY32 );
|
||||
|
@ -61,7 +47,7 @@ std::vector<UINT64> usermode::Process::GetProcessThreadsStartAddresses()
|
|||
{
|
||||
LOG_ERROR( "Thread32First failed with status 0x%x", GetLastError() );
|
||||
CloseHandle( thread_snapshot_handle );
|
||||
return {};
|
||||
return;
|
||||
}
|
||||
|
||||
do
|
||||
|
@ -88,11 +74,19 @@ std::vector<UINT64> usermode::Process::GetProcessThreadsStartAddresses()
|
|||
continue;
|
||||
}
|
||||
|
||||
start_addresses.push_back( start_address );
|
||||
if ( CheckIfAddressLiesWithinValidProcessModule( start_address, &result ) )
|
||||
{
|
||||
if ( result == false )
|
||||
{
|
||||
global::report_structures::PROCESS_THREAD_START_FAILURE report;
|
||||
report.report_code = REPORT_CODE_START_ADDRESS_VERIFICATION;
|
||||
report.start_address = start_address;
|
||||
report.thread_id = thread_entry.th32ThreadID;
|
||||
this->report_interface->ReportViolation( &report );
|
||||
}
|
||||
}
|
||||
|
||||
} while ( Thread32Next( thread_snapshot_handle, &thread_entry ) );
|
||||
|
||||
return start_addresses;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -231,31 +225,73 @@ bool usermode::Process::GetProcessBaseAddress( UINT64* Result )
|
|||
void usermode::Process::ScanProcessMemory()
|
||||
{
|
||||
MEMORY_BASIC_INFORMATION memory_info = { 0 };
|
||||
UINT64 base_address;
|
||||
UINT64 address;
|
||||
|
||||
if ( !GetProcessBaseAddress( &base_address ) )
|
||||
if ( !GetProcessBaseAddress( &address) )
|
||||
{
|
||||
LOG_ERROR( "Failed to get process base address with status 0x%x", GetLastError() );
|
||||
return;
|
||||
}
|
||||
|
||||
while ( VirtualQueryEx(
|
||||
this->process_handle,
|
||||
( PVOID )base_address,
|
||||
&memory_info,
|
||||
sizeof( MEMORY_BASIC_INFORMATION ))
|
||||
)
|
||||
this->process_handle,
|
||||
( PVOID )address,
|
||||
&memory_info,
|
||||
sizeof( MEMORY_BASIC_INFORMATION )))
|
||||
{
|
||||
this->CheckPageProtection( &memory_info );
|
||||
this->PatternScanRegion(base_address, &memory_info);
|
||||
this->PatternScanRegion(address, &memory_info);
|
||||
|
||||
base_address += memory_info.RegionSize;
|
||||
address += memory_info.RegionSize;
|
||||
}
|
||||
}
|
||||
|
||||
void usermode::Process::PatternScanRegion( UINT64 Address, MEMORY_BASIC_INFORMATION* Page )
|
||||
{
|
||||
/* todo: stream signatures from server */
|
||||
//char buf[] = "\x85\xc0\x74\x00\xb9\x00\x00\x00\x00\xcd";
|
||||
char buf[] = "\x55\x8B\xEC\xFF\x75\x00\xD9\x45\x00\x51\xD9\x1C\x00\xE8\x00\x00\x00\x00\x5D\xC2\x00\x00\xCC\xCC\xCC\xCC\xCC\xCC\xCC";
|
||||
std::vector<char> signature;
|
||||
|
||||
for ( int i = 0; i < 10; i++ )
|
||||
signature.push_back( buf[ i ] );
|
||||
|
||||
/* skip free or reserved pages */
|
||||
if ( Page->State == MEM_RESERVE || Page->State == MEM_FREE )
|
||||
return;
|
||||
|
||||
char* base = ( char* )Address;
|
||||
|
||||
for ( unsigned int i = 0; i < Page->RegionSize; i++ )
|
||||
{
|
||||
for ( unsigned j = 0; j < signature.size(); j++ )
|
||||
{
|
||||
char current_byte = *( base + i );
|
||||
char current_sig_byte = signature[j];
|
||||
|
||||
/* if we've found the signature, report */
|
||||
if ( j + 1 == signature.size())
|
||||
{
|
||||
global::report_structures::PATTERN_SCAN_FAILURE report;
|
||||
report.report_code = REPORT_PATTERN_SCAN_FAILURE;
|
||||
report.address = (UINT64)base + i;
|
||||
report.signature_id = 1; /* this will be taken from the vector in future */
|
||||
this->report_interface->ReportViolation( &report );
|
||||
|
||||
/*
|
||||
* for now return, however when we stream the signatures we iterate over
|
||||
* each signature for every page
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
/* else, continue searching */
|
||||
if ( current_byte != current_sig_byte && current_sig_byte != MASK_BYTE )
|
||||
break;
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void usermode::Process::CheckPageProtection( MEMORY_BASIC_INFORMATION* Page )
|
||||
|
@ -270,7 +306,14 @@ void usermode::Process::CheckPageProtection( MEMORY_BASIC_INFORMATION* Page )
|
|||
Page->AllocationProtect & PAGE_EXECUTE_WRITECOPY
|
||||
)
|
||||
{
|
||||
// report area or smth
|
||||
//Not etirely sure about this check, needs to be looked into further.
|
||||
global::report_structures::PAGE_PROTECTION_FAILURE report;
|
||||
report.report_code = REPORT_PAGE_PROTECTION_VERIFICATION;
|
||||
report.page_base_address = (UINT64)Page->AllocationBase;
|
||||
report.allocation_protection = Page->AllocationProtect;
|
||||
report.allocation_state = Page->State;
|
||||
report.allocation_type = Page->Type;
|
||||
this->report_interface->ReportViolation( &report );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue