mirror of
https://github.com/donnaskiez/ac.git
synced 2024-11-21 22:24:08 +01:00
coupley more reports
This commit is contained in:
parent
3a45a9fe04
commit
f7dd6ae97f
7 changed files with 236 additions and 75 deletions
58
driver/hw.c
58
driver/hw.c
|
@ -1,6 +1,8 @@
|
|||
#include "hw.h"
|
||||
|
||||
#include "modules.h"
|
||||
#include "crypt.h"
|
||||
#include "imports.h"
|
||||
|
||||
#define PCI_VENDOR_ID_OFFSET 0x00
|
||||
#define PCI_DEVICE_ID_OFFSET 0x02
|
||||
|
@ -67,11 +69,11 @@ QueryPciDeviceConfigurationSpace(_In_ PDEVICE_OBJECT DeviceObject,
|
|||
_Out_opt_ PVOID Buffer,
|
||||
_In_ UINT32 BufferLength)
|
||||
{
|
||||
NTSTATUS status = STATUS_UNSUCCESSFUL;
|
||||
KEVENT event = {0};
|
||||
IO_STATUS_BLOCK io = {0};
|
||||
PIRP irp = NULL;
|
||||
PIO_STACK_LOCATION io_stack_location = NULL;
|
||||
NTSTATUS status = STATUS_UNSUCCESSFUL;
|
||||
KEVENT event = {0};
|
||||
IO_STATUS_BLOCK io = {0};
|
||||
PIRP irp = NULL;
|
||||
PIO_STACK_LOCATION packet = NULL;
|
||||
|
||||
if (BufferLength == 0)
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
|
@ -90,13 +92,12 @@ QueryPciDeviceConfigurationSpace(_In_ PDEVICE_OBJECT DeviceObject,
|
|||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
io_stack_location = IoGetNextIrpStackLocation(irp);
|
||||
io_stack_location->MinorFunction = IRP_MN_READ_CONFIG;
|
||||
io_stack_location->Parameters.ReadWriteConfig.WhichSpace =
|
||||
PCI_WHICHSPACE_CONFIG;
|
||||
io_stack_location->Parameters.ReadWriteConfig.Offset = Offset;
|
||||
io_stack_location->Parameters.ReadWriteConfig.Buffer = Buffer;
|
||||
io_stack_location->Parameters.ReadWriteConfig.Length = BufferLength;
|
||||
packet = IoGetNextIrpStackLocation(irp);
|
||||
packet->MinorFunction = IRP_MN_READ_CONFIG;
|
||||
packet->Parameters.ReadWriteConfig.WhichSpace = PCI_WHICHSPACE_CONFIG;
|
||||
packet->Parameters.ReadWriteConfig.Offset = Offset;
|
||||
packet->Parameters.ReadWriteConfig.Buffer = Buffer;
|
||||
packet->Parameters.ReadWriteConfig.Length = BufferLength;
|
||||
|
||||
status = IoCallDriver(DeviceObject, irp);
|
||||
|
||||
|
@ -255,6 +256,38 @@ IsPciConfigurationSpaceFlagged(_In_ PPCI_COMMON_HEADER Configuration)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
ReportBlacklistedPcieDevice(_In_ PDEVICE_OBJECT DeviceObject,
|
||||
_In_ PPCI_COMMON_HEADER Header)
|
||||
{
|
||||
NTSTATUS status = STATUS_UNSUCCESSFUL;
|
||||
UINT32 packet_size = CryptRequestRequiredBufferLength(
|
||||
sizeof(BLACKLISTED_PCIE_DEVICE_REPORT));
|
||||
|
||||
PBLACKLISTED_PCIE_DEVICE_REPORT report =
|
||||
ImpExAllocatePool2(POOL_FLAG_NON_PAGED, packet_size, REPORT_POOL_TAG);
|
||||
|
||||
if (!report)
|
||||
return;
|
||||
|
||||
INIT_REPORT_PACKET(report, REPORT_BLACKLISTED_PCIE_DEVICE, 0);
|
||||
|
||||
report->device_object = (UINT64)DeviceObject;
|
||||
report->device_id = Header->DeviceID;
|
||||
report->vendor_id = Header->VendorID;
|
||||
|
||||
status = CryptEncryptBuffer(report, packet_size);
|
||||
|
||||
if (!NT_SUCCESS(status)) {
|
||||
DEBUG_ERROR("CryptEncryptBuffer: %lx", status);
|
||||
ImpExFreePoolWithTag(report, packet_size);
|
||||
return;
|
||||
}
|
||||
|
||||
IrpQueueSchedulePacket(report, packet_size);
|
||||
}
|
||||
|
||||
STATIC
|
||||
NTSTATUS
|
||||
PciDeviceQueryCallback(_In_ PDEVICE_OBJECT DeviceObject, _In_opt_ PVOID Context)
|
||||
|
@ -283,6 +316,7 @@ PciDeviceQueryCallback(_In_ PDEVICE_OBJECT DeviceObject, _In_opt_ PVOID Context)
|
|||
DeviceObject,
|
||||
header.DeviceID,
|
||||
header.VendorID);
|
||||
ReportBlacklistedPcieDevice(DeviceObject, &header);
|
||||
}
|
||||
|
||||
return status;
|
||||
|
|
|
@ -1609,7 +1609,7 @@ end:
|
|||
*/
|
||||
STATIC
|
||||
VOID
|
||||
ReportInvalidSystemModule(_In_ PRTL_MODULE_EXTENDED_INFO Module)
|
||||
ReportModifiedSystemImage(_In_ PRTL_MODULE_EXTENDED_INFO Module)
|
||||
{
|
||||
NTSTATUS status = STATUS_UNSUCCESSFUL;
|
||||
UINT32 packet_size = CryptRequestRequiredBufferLength(
|
||||
|
@ -1684,7 +1684,7 @@ ValidateSystemModule(_In_ PRTL_MODULE_EXTENDED_INFO Module)
|
|||
else {
|
||||
DEBUG_WARNING("**!!** Module: %s text regions are NOT valid **!!**",
|
||||
Module->FullPathName);
|
||||
ReportInvalidSystemModule(Module);
|
||||
ReportModifiedSystemImage(Module);
|
||||
}
|
||||
|
||||
end:
|
||||
|
@ -1693,6 +1693,39 @@ end:
|
|||
ExFreePoolWithTag(hash, POOL_TAG_INTEGRITY);
|
||||
}
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
ReportModifiedSelfDriverImage(_In_ PRTL_MODULE_EXTENDED_INFO Module)
|
||||
{
|
||||
NTSTATUS status = STATUS_UNSUCCESSFUL;
|
||||
UINT32 packet_size = CryptRequestRequiredBufferLength(
|
||||
sizeof(DRIVER_SELF_INTEGRITY_CHECK_REPORT));
|
||||
|
||||
PDRIVER_SELF_INTEGRITY_CHECK_REPORT report =
|
||||
ImpExAllocatePool2(POOL_FLAG_NON_PAGED, packet_size, REPORT_POOL_TAG);
|
||||
|
||||
if (!report)
|
||||
return;
|
||||
|
||||
INIT_REPORT_PACKET(report, REPORT_SELF_DRIVER_PATCHED, 0);
|
||||
|
||||
report->image_base = Module->ImageBase;
|
||||
report->image_size = Module->ImageSize;
|
||||
|
||||
RtlCopyMemory(
|
||||
report->path_name, Module->FullPathName, sizeof(report->path_name));
|
||||
|
||||
status = CryptEncryptBuffer(report, packet_size);
|
||||
|
||||
if (!NT_SUCCESS(status)) {
|
||||
DEBUG_ERROR("CryptEncryptBuffer: %lx", status);
|
||||
ImpExFreePoolWithTag(report, packet_size);
|
||||
return;
|
||||
}
|
||||
|
||||
IrpQueueSchedulePacket(report, packet_size);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ValidateOurDriverImage()
|
||||
{
|
||||
|
@ -1750,10 +1783,13 @@ ValidateOurDriverImage()
|
|||
* module error and stop the users game session ? since module .text
|
||||
* section error would be a large red flag
|
||||
*/
|
||||
if (CompareHashes(memory_hash, entry->text_hash, SHA_256_HASH_LENGTH))
|
||||
if (CompareHashes(memory_hash, entry->text_hash, SHA_256_HASH_LENGTH)) {
|
||||
DEBUG_VERBOSE("Driver image is valid. Integrity check complete");
|
||||
else
|
||||
}
|
||||
else {
|
||||
DEBUG_WARNING("**!!** Driver image is NOT valid. **!!**");
|
||||
ReportModifiedSelfDriverImage(module_info);
|
||||
}
|
||||
|
||||
end:
|
||||
|
||||
|
@ -2312,7 +2348,7 @@ end:
|
|||
* the right direction.
|
||||
*/
|
||||
NTSTATUS
|
||||
InitialiseHeartbeatConfiguration(_Inout_ PHEARTBEAT_CONFIGURATION Configuration)
|
||||
InitialiseHeartbeatConfiguration(_Out_ PHEARTBEAT_CONFIGURATION Configuration)
|
||||
{
|
||||
NTSTATUS status = STATUS_UNSUCCESSFUL;
|
||||
|
||||
|
|
|
@ -123,7 +123,7 @@ FindWinLogonProcess(_In_ PPROCESS_LIST_ENTRY Entry, _In_opt_ PVOID Context);
|
|||
|
||||
NTSTATUS
|
||||
InitialiseHeartbeatConfiguration(
|
||||
_Inout_ PHEARTBEAT_CONFIGURATION Configuration);
|
||||
_Out_ PHEARTBEAT_CONFIGURATION Configuration);
|
||||
|
||||
VOID
|
||||
FreeHeartbeatConfiguration(_Inout_ PHEARTBEAT_CONFIGURATION Configuration);
|
||||
|
|
12
driver/io.c
12
driver/io.c
|
@ -337,12 +337,12 @@ IrpQueueCompletePacket(_In_ PVOID Buffer, _In_ ULONG BufferSize)
|
|||
}
|
||||
|
||||
/*
|
||||
* Not only does this allow reporting threads to continue execution once the
|
||||
* report is scheduled (which in some cases such as handle reporting is very
|
||||
* important for performance reasons), but it allows us to safely report from
|
||||
* within a region guarded by a mutex as we use a spinlock here (for performance
|
||||
* reasons, we dont need certain time critical threads being slept whilst we
|
||||
* wait).
|
||||
* Due to the fact that many reporting structures are holding a mutex when
|
||||
* scheduling a report packet, we need an alternative queueing option from DPCs
|
||||
* and spinlocks. Here we will use an array of work items (
|
||||
*
|
||||
* Hmm this is an interesting issue. Not sure how we shall resolve this, for now
|
||||
* this works well enough.
|
||||
*/
|
||||
VOID
|
||||
IrpQueueSchedulePacket(_In_ PVOID Buffer, _In_ UINT32 BufferLength)
|
||||
|
|
|
@ -13,7 +13,9 @@
|
|||
#define REPORT_DPC_STACKWALK 120
|
||||
#define REPORT_DATA_TABLE_ROUTINE 130
|
||||
#define REPORT_INVALID_PROCESS_MODULE 140
|
||||
#define REPORT_PATCHED_SYSTEM_MODULE 150
|
||||
#define REPORT_PATCHED_SYSTEM_MODULE 150
|
||||
#define REPORT_SELF_DRIVER_PATCHED 160
|
||||
#define REPORT_BLACKLISTED_PCIE_DEVICE 170
|
||||
|
||||
#define REPORT_SUBTYPE_NO_BACKING_MODULE 0x0
|
||||
#define REPORT_SUBTYPE_INVALID_DISPATCH 0x1
|
||||
|
@ -198,4 +200,20 @@ typedef struct _SYSTEM_MODULE_INTEGRITY_CHECK_REPORT {
|
|||
|
||||
} SYSTEM_MODULE_INTEGRITY_CHECK_REPORT, *PSYSTEM_MODULE_INTEGRITY_CHECK_REPORT;
|
||||
|
||||
typedef struct _DRIVER_SELF_INTEGRITY_CHECK_REPORT {
|
||||
REPORT_PACKET_HEADER header;
|
||||
UINT64 image_base;
|
||||
UINT32 image_size;
|
||||
CHAR path_name[0x100];
|
||||
|
||||
} DRIVER_SELF_INTEGRITY_CHECK_REPORT, *PDRIVER_SELF_INTEGRITY_CHECK_REPORT;
|
||||
|
||||
typedef struct _BLACKLISTED_PCIE_DEVICE_REPORT {
|
||||
REPORT_PACKET_HEADER header;
|
||||
UINT64 device_object;
|
||||
UINT16 device_id;
|
||||
UINT16 vendor_id;
|
||||
|
||||
} BLACKLISTED_PCIE_DEVICE_REPORT, *PBLACKLISTED_PCIE_DEVICE_REPORT;
|
||||
|
||||
#endif
|
|
@ -5,50 +5,64 @@
|
|||
|
||||
#include "crypt/crypt.h"
|
||||
|
||||
void helper::generate_rand_seed() { srand(time(0)); }
|
||||
|
||||
int helper::generate_rand_int(int max) { return std::rand() % max; }
|
||||
|
||||
void helper::sleep_thread(int seconds) {
|
||||
std::this_thread::sleep_for(std::chrono::seconds(seconds));
|
||||
void
|
||||
helper::generate_rand_seed()
|
||||
{
|
||||
srand(time(0));
|
||||
}
|
||||
|
||||
int helper::get_report_id_from_buffer(void *buffer) {
|
||||
kernel_interface::report_header *header =
|
||||
reinterpret_cast<kernel_interface::report_header *>(
|
||||
(uint64_t)buffer + sizeof(kernel_interface::report_header));
|
||||
return header->report_code;
|
||||
int
|
||||
helper::generate_rand_int(int max)
|
||||
{
|
||||
return std::rand() % max;
|
||||
}
|
||||
|
||||
kernel_interface::report_id helper::get_kernel_report_type(void *buffer) {
|
||||
switch (helper::get_report_id_from_buffer(buffer)) {
|
||||
case kernel_interface::report_id::report_nmi_callback_failure:
|
||||
return kernel_interface::report_id::report_nmi_callback_failure;
|
||||
void
|
||||
helper::sleep_thread(int seconds)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::seconds(seconds));
|
||||
}
|
||||
|
||||
case kernel_interface::report_id::report_module_validation_failure:
|
||||
return kernel_interface::report_id::report_module_validation_failure;
|
||||
int
|
||||
helper::get_report_id_from_buffer(void* buffer)
|
||||
{
|
||||
kernel_interface::report_header* header =
|
||||
reinterpret_cast<kernel_interface::report_header*>(
|
||||
(uint64_t)buffer + sizeof(kernel_interface::report_header));
|
||||
return header->report_code;
|
||||
}
|
||||
|
||||
case kernel_interface::report_id::report_illegal_handle_operation:
|
||||
return kernel_interface::report_id::report_illegal_handle_operation;
|
||||
kernel_interface::report_id
|
||||
helper::get_kernel_report_type(void* buffer)
|
||||
{
|
||||
switch (helper::get_report_id_from_buffer(buffer)) {
|
||||
case kernel_interface::report_id::report_nmi_callback_failure:
|
||||
return kernel_interface::report_id::report_nmi_callback_failure;
|
||||
|
||||
case kernel_interface::report_id::report_invalid_process_allocation:
|
||||
return kernel_interface::report_id::report_invalid_process_allocation;
|
||||
case kernel_interface::report_id::report_module_validation_failure:
|
||||
return kernel_interface::report_id::report_module_validation_failure;
|
||||
|
||||
case kernel_interface::report_id::report_hidden_system_thread:
|
||||
return kernel_interface::report_id::report_hidden_system_thread;
|
||||
case kernel_interface::report_id::report_illegal_handle_operation:
|
||||
return kernel_interface::report_id::report_illegal_handle_operation;
|
||||
|
||||
case kernel_interface::report_id::report_illegal_attach_process:
|
||||
return kernel_interface::report_id::report_illegal_attach_process;
|
||||
case kernel_interface::report_id::report_invalid_process_allocation:
|
||||
return kernel_interface::report_id::report_invalid_process_allocation;
|
||||
|
||||
case kernel_interface::report_id::report_apc_stackwalk:
|
||||
return kernel_interface::report_id::report_apc_stackwalk;
|
||||
case kernel_interface::report_id::report_hidden_system_thread:
|
||||
return kernel_interface::report_id::report_hidden_system_thread;
|
||||
|
||||
case kernel_interface::report_id::report_dpc_stackwalk:
|
||||
return kernel_interface::report_id::report_dpc_stackwalk;
|
||||
case kernel_interface::report_id::report_illegal_attach_process:
|
||||
return kernel_interface::report_id::report_illegal_attach_process;
|
||||
|
||||
case kernel_interface::report_id::report_data_table_routine:
|
||||
return kernel_interface::report_id::report_data_table_routine;
|
||||
}
|
||||
case kernel_interface::report_id::report_apc_stackwalk:
|
||||
return kernel_interface::report_id::report_apc_stackwalk;
|
||||
|
||||
case kernel_interface::report_id::report_dpc_stackwalk:
|
||||
return kernel_interface::report_id::report_dpc_stackwalk;
|
||||
|
||||
case kernel_interface::report_id::report_data_table_routine:
|
||||
return kernel_interface::report_id::report_data_table_routine;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -156,6 +170,37 @@ print_report_packet(void* buffer)
|
|||
LOG_INFO("********************************");
|
||||
break;
|
||||
}
|
||||
case kernel_interface::report_id::report_patched_system_module: {
|
||||
kernel_interface::system_module_integrity_check_report* r11 =
|
||||
reinterpret_cast<
|
||||
kernel_interface::system_module_integrity_check_report*>(
|
||||
buffer);
|
||||
LOG_INFO("image_base: %llx", r11->image_base);
|
||||
LOG_INFO("image_size: %lx", r11->image_size);
|
||||
LOG_INFO("path_name: %s", r11->path_name);
|
||||
LOG_INFO("********************************");
|
||||
break;
|
||||
}
|
||||
case kernel_interface::report_id::report_self_driver_patched: {
|
||||
kernel_interface::driver_self_integrity_check_report* r12 =
|
||||
reinterpret_cast<
|
||||
kernel_interface::driver_self_integrity_check_report*>(buffer);
|
||||
LOG_INFO("image_base: %llx", r12->image_base);
|
||||
LOG_INFO("image_size: %lx", r12->image_size);
|
||||
LOG_INFO("path_name: %s", r12->path_name);
|
||||
LOG_INFO("********************************");
|
||||
break;
|
||||
}
|
||||
case kernel_interface::report_id::report_blacklisted_pcie_device: {
|
||||
kernel_interface::blacklisted_pcie_device_report* r13 =
|
||||
reinterpret_cast<kernel_interface::blacklisted_pcie_device_report*>(
|
||||
buffer);
|
||||
LOG_INFO("device_object: %llx", r13->device_object);
|
||||
LOG_INFO("device_id: %x", r13->device_id);
|
||||
LOG_INFO("vendor_id: %x", r13->vendor_id);
|
||||
LOG_INFO("********************************");
|
||||
break;
|
||||
}
|
||||
default: LOG_INFO("Invalid report type."); break;
|
||||
}
|
||||
}
|
||||
|
@ -172,28 +217,32 @@ print_heartbeat_packet(void* buffer)
|
|||
LOG_INFO("********************************");
|
||||
}
|
||||
|
||||
void helper::print_kernel_report(void *buffer) {
|
||||
uint32_t size = crypt::get_padded_packet_size(
|
||||
sizeof(kernel_interface::open_handle_failure_report));
|
||||
crypt::decrypt_packet(buffer, size);
|
||||
void
|
||||
helper::print_kernel_report(void* buffer)
|
||||
{
|
||||
uint32_t size = crypt::get_padded_packet_size(
|
||||
sizeof(kernel_interface::open_handle_failure_report));
|
||||
crypt::decrypt_packet(buffer, size);
|
||||
|
||||
kernel_interface::packet_header *header =
|
||||
reinterpret_cast<kernel_interface::packet_header *>(buffer);
|
||||
kernel_interface::packet_header* header =
|
||||
reinterpret_cast<kernel_interface::packet_header*>(buffer);
|
||||
|
||||
LOG_INFO("packet type: %lx", header->packet_type);
|
||||
LOG_INFO("packet type: %lx", header->packet_type);
|
||||
|
||||
switch (header->packet_type)
|
||||
{
|
||||
case 0: print_report_packet(buffer); break;
|
||||
case 1: print_heartbeat_packet(buffer); break;
|
||||
}
|
||||
|
||||
switch (header->packet_type) {
|
||||
case 0: print_report_packet(buffer); break;
|
||||
case 1: print_heartbeat_packet(buffer); break;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned __int64 helper::seconds_to_nanoseconds(int seconds) {
|
||||
return ABSOLUTE(SECONDS(seconds));
|
||||
unsigned __int64
|
||||
helper::seconds_to_nanoseconds(int seconds)
|
||||
{
|
||||
return ABSOLUTE(SECONDS(seconds));
|
||||
}
|
||||
|
||||
unsigned __int32 helper::seconds_to_milliseconds(int seconds) {
|
||||
return seconds * 1000;
|
||||
unsigned __int32
|
||||
helper::seconds_to_milliseconds(int seconds)
|
||||
{
|
||||
return seconds * 1000;
|
||||
}
|
|
@ -22,7 +22,10 @@ enum report_id {
|
|||
report_apc_stackwalk = 110,
|
||||
report_dpc_stackwalk = 120,
|
||||
report_data_table_routine = 130,
|
||||
report_invalid_process_module = 140
|
||||
report_invalid_process_module = 140,
|
||||
report_patched_system_module = 150,
|
||||
report_self_driver_patched = 160,
|
||||
report_blacklisted_pcie_device = 170
|
||||
};
|
||||
|
||||
#define AES_256_BLOCK_SIZE 16
|
||||
|
@ -126,6 +129,20 @@ struct process_module_validation_report {
|
|||
wchar_t module_path[MODULE_PATH_LEN];
|
||||
};
|
||||
|
||||
struct system_module_integrity_check_report {
|
||||
report_header header;
|
||||
uint64_t image_base;
|
||||
uint32_t image_size;
|
||||
char path_name[0x100];
|
||||
};
|
||||
|
||||
struct driver_self_integrity_check_report {
|
||||
report_header header;
|
||||
uint64_t image_base;
|
||||
uint32_t image_size;
|
||||
char path_name[0x100];
|
||||
};
|
||||
|
||||
struct heartbeat_packet {
|
||||
heartbeat_header header;
|
||||
uint32_t heartbeat_count;
|
||||
|
@ -134,6 +151,13 @@ struct heartbeat_packet {
|
|||
uint32_t total_heartbeats_completed;
|
||||
};
|
||||
|
||||
struct blacklisted_pcie_device_report {
|
||||
report_header header;
|
||||
uint64_t device_object;
|
||||
uint16_t device_id;
|
||||
uint16_t vendor_id;
|
||||
};
|
||||
|
||||
enum apc_operation { operation_stackwalk = 0x1 };
|
||||
|
||||
// clang-format off
|
||||
|
|
Loading…
Reference in a new issue