Driver: Provide svchost.exe service names to UI

This commit is contained in:
Nodir Temirkhodjaev 2022-02-03 20:25:43 +03:00
parent f73b6ef030
commit caf754c7a0
8 changed files with 86 additions and 58 deletions

View File

@ -80,7 +80,7 @@ FORT_API PFORT_CONF_ADDR_GROUP fort_conf_addr_group_ref(const PFORT_CONF conf, i
const UINT32 *addr_group_offsets = (const UINT32 *) (conf->data + conf->addr_groups_off);
const char *addr_group_data = (const char *) addr_group_offsets;
return (PFORT_CONF_ADDR_GROUP)(addr_group_data + addr_group_offsets[addr_group_index]);
return (PFORT_CONF_ADDR_GROUP) (addr_group_data + addr_group_offsets[addr_group_index]);
}
static BOOL fort_conf_ip_included_check(const PFORT_CONF_ADDR_LIST addr_list,
@ -122,7 +122,7 @@ FORT_API BOOL fort_conf_ip_included(const PFORT_CONF conf,
return ip_included && !ip_excluded;
}
FORT_API BOOL fort_conf_app_exe_equal(PFORT_APP_ENTRY app_entry, const char *path, UINT32 path_len)
FORT_API BOOL fort_conf_app_exe_equal(PFORT_APP_ENTRY app_entry, const PVOID path, UINT32 path_len)
{
const char *app_path = (const char *) (app_entry + 1);
const UINT32 app_path_len = app_entry->path_len;
@ -134,7 +134,7 @@ FORT_API BOOL fort_conf_app_exe_equal(PFORT_APP_ENTRY app_entry, const char *pat
}
FORT_API FORT_APP_FLAGS fort_conf_app_exe_find(
const PFORT_CONF conf, const char *path, UINT32 path_len)
const PFORT_CONF conf, const PVOID path, UINT32 path_len)
{
FORT_APP_FLAGS app_flags;
UINT16 count = conf->exe_apps_n;
@ -193,7 +193,7 @@ static FORT_APP_FLAGS fort_conf_app_prefix_find(
do {
const int mid = (low + high) / 2;
const UINT32 app_off = app_offsets[mid];
const PFORT_APP_ENTRY app_entry = (PFORT_APP_ENTRY)(app_entries + app_off);
const PFORT_APP_ENTRY app_entry = (PFORT_APP_ENTRY) (app_entries + app_off);
const int res = fort_conf_app_prefix_cmp(app_entry, path, path_len);
if (res < 0)
@ -238,7 +238,7 @@ static FORT_APP_FLAGS fort_conf_app_wild_find(const PFORT_CONF conf, const char
return app_flags;
}
FORT_API FORT_APP_FLAGS fort_conf_app_find(const PFORT_CONF conf, const char *path, UINT32 path_len,
FORT_API FORT_APP_FLAGS fort_conf_app_find(const PFORT_CONF conf, const PVOID path, UINT32 path_len,
fort_conf_app_exe_find_func *exe_find_func)
{
FORT_APP_FLAGS app_flags;

View File

@ -15,7 +15,7 @@
#define FORT_CONF_STR_DATA_SIZE(size) \
((((size) + (FORT_CONF_STR_ALIGN - 1)) & ~(FORT_CONF_STR_ALIGN - 1)))
#define FORT_CONF_APP_ENTRY_SIZE(len) \
(sizeof(FORT_APP_ENTRY) + (len) + sizeof(wchar_t)) /* include terminating zero */
(sizeof(FORT_APP_ENTRY) + (len) + sizeof(WCHAR)) /* include terminating zero */
typedef struct fort_conf_flags
{
@ -203,7 +203,7 @@ typedef struct fort_conf_io
(FORT_CONF_ADDR_LIST_OFF + FORT_CONF_IP_ARR_SIZE(ip_n) + FORT_CONF_IP_RANGE_SIZE(pair_n))
typedef FORT_APP_FLAGS fort_conf_app_exe_find_func(
const PFORT_CONF conf, const char *path, UINT32 path_len);
const PFORT_CONF conf, const PVOID path, UINT32 path_len);
typedef BOOL fort_conf_zones_ip_included_func(void *ctx, UINT32 zones_mask, UINT32 remote_ip);
@ -220,10 +220,11 @@ FORT_API BOOL fort_conf_ip_inlist(UINT32 ip, const PFORT_CONF_ADDR_LIST addr_lis
FORT_API PFORT_CONF_ADDR_GROUP fort_conf_addr_group_ref(
const PFORT_CONF conf, int addr_group_index);
#define fort_conf_addr_group_include_list_ref(addr_group) ((PFORT_CONF_ADDR_LIST)(addr_group)->data)
#define fort_conf_addr_group_include_list_ref(addr_group) \
((PFORT_CONF_ADDR_LIST) (addr_group)->data)
#define fort_conf_addr_group_exclude_list_ref(addr_group) \
((PFORT_CONF_ADDR_LIST)((addr_group)->data + (addr_group)->exclude_off))
((PFORT_CONF_ADDR_LIST) ((addr_group)->data + (addr_group)->exclude_off))
FORT_API BOOL fort_conf_ip_included(const PFORT_CONF conf,
fort_conf_zones_ip_included_func zone_func, void *ctx, UINT32 remote_ip,
@ -235,12 +236,12 @@ FORT_API BOOL fort_conf_ip_included(const PFORT_CONF conf,
#define fort_conf_ip_inet_included(conf, zone_func, ctx, remote_ip) \
fort_conf_ip_included((conf), (zone_func), (ctx), (remote_ip), 1)
FORT_API BOOL fort_conf_app_exe_equal(PFORT_APP_ENTRY app_entry, const char *path, UINT32 path_len);
FORT_API BOOL fort_conf_app_exe_equal(PFORT_APP_ENTRY app_entry, const PVOID path, UINT32 path_len);
FORT_API FORT_APP_FLAGS fort_conf_app_exe_find(
const PFORT_CONF conf, const char *path, UINT32 path_len);
const PFORT_CONF conf, const PVOID path, UINT32 path_len);
FORT_API FORT_APP_FLAGS fort_conf_app_find(const PFORT_CONF conf, const char *path, UINT32 path_len,
FORT_API FORT_APP_FLAGS fort_conf_app_find(const PFORT_CONF conf, const PVOID path, UINT32 path_len,
fort_conf_app_exe_find_func *exe_find_func);
FORT_API BOOL fort_conf_app_blocked(

View File

@ -53,7 +53,7 @@ FORT_API UCHAR fort_device_flag(PFORT_DEVICE_CONF device_conf, UCHAR flag)
}
static PFORT_CONF_EXE_NODE fort_conf_ref_exe_find_node(
PFORT_CONF_REF conf_ref, const char *path, UINT32 path_len, tommy_key_t path_hash)
PFORT_CONF_REF conf_ref, const PVOID path, UINT32 path_len, tommy_key_t path_hash)
{
PFORT_CONF_EXE_NODE node =
(PFORT_CONF_EXE_NODE) tommy_hashdyn_bucket(&conf_ref->exe_map, path_hash);
@ -70,7 +70,7 @@ static PFORT_CONF_EXE_NODE fort_conf_ref_exe_find_node(
return NULL;
}
FORT_API FORT_APP_FLAGS fort_conf_exe_find(const PFORT_CONF conf, const char *path, UINT32 path_len)
FORT_API FORT_APP_FLAGS fort_conf_exe_find(const PFORT_CONF conf, const PVOID path, UINT32 path_len)
{
PFORT_CONF_REF conf_ref = (PFORT_CONF_REF) ((char *) conf - offsetof(FORT_CONF_REF, conf));
const tommy_key_t path_hash = (tommy_key_t) tommy_hash_u64(0, path, path_len);
@ -88,7 +88,7 @@ FORT_API FORT_APP_FLAGS fort_conf_exe_find(const PFORT_CONF conf, const char *pa
return app_flags;
}
static NTSTATUS fort_conf_ref_exe_add_path_locked(PFORT_CONF_REF conf_ref, const char *path,
static NTSTATUS fort_conf_ref_exe_add_path_locked(PFORT_CONF_REF conf_ref, const PVOID path,
UINT32 path_len, tommy_key_t path_hash, FORT_APP_FLAGS flags)
{
const PFORT_CONF_EXE_NODE node =
@ -148,7 +148,7 @@ static NTSTATUS fort_conf_ref_exe_add_path_locked(PFORT_CONF_REF conf_ref, const
}
FORT_API NTSTATUS fort_conf_ref_exe_add_path(
PFORT_CONF_REF conf_ref, const char *path, UINT32 path_len, FORT_APP_FLAGS flags)
PFORT_CONF_REF conf_ref, const PVOID path, UINT32 path_len, FORT_APP_FLAGS flags)
{
const tommy_key_t path_hash = (tommy_key_t) tommy_hash_u64(0, path, path_len);
NTSTATUS status;
@ -163,7 +163,7 @@ FORT_API NTSTATUS fort_conf_ref_exe_add_path(
FORT_API NTSTATUS fort_conf_ref_exe_add_entry(
PFORT_CONF_REF conf_ref, const PFORT_APP_ENTRY entry, BOOL locked)
{
const char *path = (const char *) (entry + 1);
const PVOID path = (const PVOID)(entry + 1);
const UINT32 path_len = entry->path_len;
const FORT_APP_FLAGS flags = entry->flags;
@ -191,7 +191,7 @@ static void fort_conf_ref_exe_fill(PFORT_CONF_REF conf_ref, const PFORT_CONF con
}
}
static void fort_conf_ref_exe_del_path(PFORT_CONF_REF conf_ref, const char *path, UINT32 path_len)
static void fort_conf_ref_exe_del_path(PFORT_CONF_REF conf_ref, const PVOID path, UINT32 path_len)
{
const tommy_key_t path_hash = (tommy_key_t) tommy_hash_u64(0, path, path_len);
@ -223,7 +223,7 @@ static void fort_conf_ref_exe_del_path(PFORT_CONF_REF conf_ref, const char *path
FORT_API void fort_conf_ref_exe_del_entry(PFORT_CONF_REF conf_ref, const PFORT_APP_ENTRY entry)
{
const char *path = (const char *) (entry + 1);
const PVOID path = (const PVOID)(entry + 1);
const UINT32 path_len = entry->path_len;
fort_conf_ref_exe_del_path(conf_ref, path, path_len);

View File

@ -51,10 +51,10 @@ FORT_API UCHAR fort_device_flag_set(PFORT_DEVICE_CONF device_conf, UCHAR flag, B
FORT_API UCHAR fort_device_flag(PFORT_DEVICE_CONF device_conf, UCHAR flag);
FORT_API FORT_APP_FLAGS fort_conf_exe_find(
const PFORT_CONF conf, const char *path, UINT32 path_len);
const PFORT_CONF conf, const PVOID path, UINT32 path_len);
FORT_API NTSTATUS fort_conf_ref_exe_add_path(
PFORT_CONF_REF conf_ref, const char *path, UINT32 path_len, FORT_APP_FLAGS flags);
PFORT_CONF_REF conf_ref, const PVOID path, UINT32 path_len, FORT_APP_FLAGS flags);
FORT_API NTSTATUS fort_conf_ref_exe_add_entry(
PFORT_CONF_REF conf_ref, const PFORT_APP_ENTRY entry, BOOL locked);

View File

@ -7,6 +7,7 @@
#include "common/fortprov.h"
#include "fortdev.h"
#include "fortps.h"
static void fort_callout_classify_block(FWPS_CLASSIFY_OUT0 *classifyOut)
{
@ -40,7 +41,7 @@ static BOOL fort_callout_classify_v4_blocked_log_stat(const FWPS_INCOMING_VALUES
FWPS_CLASSIFY_OUT0 *classifyOut, int flagsField, int localIpField, int remoteIpField,
int localPortField, int remotePortField, int ipProtoField, BOOL inbound,
UINT32 classify_flags, UINT32 remote_ip, FORT_CONF_FLAGS conf_flags, UINT32 process_id,
UINT32 path_len, PVOID path, PFORT_CONF_REF conf_ref, INT8 *block_reason, BOOL blocked,
PCUNICODE_STRING path, PFORT_CONF_REF conf_ref, INT8 *block_reason, BOOL blocked,
FORT_APP_FLAGS app_flags, PIRP *irp, ULONG_PTR *info)
{
const UINT64 flow_id = inMetaValues->flowHandle;
@ -64,7 +65,8 @@ static BOOL fort_callout_classify_v4_blocked_log_stat(const FWPS_INCOMING_VALUES
LOG("Classify v4: Flow assoc. error: %x\n", status);
} else if (is_new_proc) {
fort_buffer_proc_new_write(&fort_device()->buffer, process_id, path_len, path, irp, info);
fort_buffer_proc_new_write(
&fort_device()->buffer, process_id, path->Length, path->Buffer, irp, info);
}
return FALSE;
@ -75,11 +77,11 @@ static BOOL fort_callout_classify_v4_blocked_log(const FWPS_INCOMING_VALUES0 *in
FWPS_CLASSIFY_OUT0 *classifyOut, int flagsField, int localIpField, int remoteIpField,
int localPortField, int remotePortField, int ipProtoField, BOOL inbound,
UINT32 classify_flags, UINT32 remote_ip, FORT_CONF_FLAGS conf_flags, UINT32 process_id,
UINT32 path_len, PVOID path, PFORT_CONF_REF conf_ref, INT8 *block_reason, BOOL blocked,
PIRP *irp, ULONG_PTR *info)
PCUNICODE_STRING path, PFORT_CONF_REF conf_ref, INT8 *block_reason, BOOL blocked, PIRP *irp,
ULONG_PTR *info)
{
FORT_APP_FLAGS app_flags =
fort_conf_app_find(&conf_ref->conf, path, path_len, fort_conf_exe_find);
fort_conf_app_find(&conf_ref->conf, path->Buffer, path->Length, fort_conf_exe_find);
if (!blocked /* collect traffic, when Filter Disabled */
|| (app_flags.v == 0 && conf_flags.allow_all_new) /* collect new Blocked Programs */
@ -88,8 +90,8 @@ static BOOL fort_callout_classify_v4_blocked_log(const FWPS_INCOMING_VALUES0 *in
&& fort_callout_classify_v4_blocked_log_stat(inFixedValues, inMetaValues, filter,
classifyOut, flagsField, localIpField, remoteIpField, localPortField,
remotePortField, ipProtoField, inbound, classify_flags, remote_ip,
conf_flags, process_id, path_len, path, conf_ref, block_reason, blocked,
app_flags, irp, info))
conf_flags, process_id, path, conf_ref, block_reason, blocked, app_flags,
irp, info))
return TRUE; /* blocked */
blocked = FALSE; /* allow */
@ -101,9 +103,10 @@ static BOOL fort_callout_classify_v4_blocked_log(const FWPS_INCOMING_VALUES0 *in
app_flags.alerted = 1;
app_flags.is_new = 1;
if (NT_SUCCESS(fort_conf_ref_exe_add_path(conf_ref, path, path_len, app_flags))) {
fort_buffer_blocked_write(
&fort_device()->buffer, blocked, process_id, path_len, path, irp, info);
if (NT_SUCCESS(
fort_conf_ref_exe_add_path(conf_ref, path->Buffer, path->Length, app_flags))) {
fort_buffer_blocked_write(&fort_device()->buffer, blocked, process_id, path->Length,
path->Buffer, irp, info);
}
}
@ -115,7 +118,7 @@ static BOOL fort_callout_classify_v4_blocked(const FWPS_INCOMING_VALUES0 *inFixe
FWPS_CLASSIFY_OUT0 *classifyOut, int flagsField, int localIpField, int remoteIpField,
int localPortField, int remotePortField, int ipProtoField, BOOL inbound,
UINT32 classify_flags, UINT32 remote_ip, FORT_CONF_FLAGS conf_flags, UINT32 process_id,
UINT32 path_len, PVOID path, PFORT_CONF_REF conf_ref, INT8 *block_reason, PIRP *irp,
PUNICODE_STRING path, PFORT_CONF_REF conf_ref, INT8 *block_reason, PIRP *irp,
ULONG_PTR *info)
{
BOOL blocked = TRUE;
@ -147,7 +150,7 @@ static BOOL fort_callout_classify_v4_blocked(const FWPS_INCOMING_VALUES0 *inFixe
return fort_callout_classify_v4_blocked_log(inFixedValues, inMetaValues, filter, classifyOut,
flagsField, localIpField, remoteIpField, localPortField, remotePortField, ipProtoField,
inbound, classify_flags, remote_ip, conf_flags, process_id, path_len, path, conf_ref,
inbound, classify_flags, remote_ip, conf_flags, process_id, path, conf_ref,
block_reason, blocked, irp, info);
}
@ -161,15 +164,23 @@ static void fort_callout_classify_v4_check(const FWPS_INCOMING_VALUES0 *inFixedV
const FORT_CONF_FLAGS conf_flags = conf_ref->conf.flags;
const UINT32 process_id = (UINT32) inMetaValues->processId;
const UINT32 path_len =
inMetaValues->processPath->size - sizeof(WCHAR); /* chop terminating zero */
const PVOID path = inMetaValues->processPath->data;
UNICODE_STRING path;
PFORT_PSNAME ps_name =
fort_pstree_acquire_proc_name(&fort_device()->ps_tree, process_id, &path);
if (ps_name == NULL) {
const UINT16 path_len = (UINT16) (inMetaValues->processPath->size
- sizeof(WCHAR)); /* chop terminating zero */
path.Length = path_len;
path.MaximumLength = path_len;
path.Buffer = (PWSTR) inMetaValues->processPath->data;
}
INT8 block_reason = FORT_BLOCK_REASON_UNKNOWN;
const BOOL blocked = fort_callout_classify_v4_blocked(inFixedValues, inMetaValues, filter,
classifyOut, flagsField, localIpField, remoteIpField, localPortField, remotePortField,
ipProtoField, inbound, classify_flags, remote_ip, conf_flags, process_id, path_len,
path, conf_ref, &block_reason, irp, info);
ipProtoField, inbound, classify_flags, remote_ip, conf_flags, process_id, &path,
conf_ref, &block_reason, irp, info);
if (blocked) {
/* Log the blocked connection */
@ -181,8 +192,8 @@ static void fort_callout_classify_v4_check(const FWPS_INCOMING_VALUES0 *inFixedV
(IPPROTO) inFixedValues->incomingValue[ipProtoField].value.uint8;
fort_buffer_blocked_ip_write(&fort_device()->buffer, inbound, block_reason, ip_proto,
local_port, remote_port, local_ip, remote_ip, process_id, path_len, path, irp,
info);
local_port, remote_port, local_ip, remote_ip, process_id, path.Length,
path.Buffer, irp, info);
}
/* Block the connection */
@ -196,6 +207,10 @@ static void fort_callout_classify_v4_check(const FWPS_INCOMING_VALUES0 *inFixedV
fort_callout_classify_permit(filter, classifyOut);
}
}
if (ps_name != NULL) {
fort_pstree_release_proc_name(&fort_device()->ps_tree, ps_name);
}
}
static void fort_callout_classify_v4(const FWPS_INCOMING_VALUES0 *inFixedValues,

View File

@ -15,6 +15,13 @@
#define FORT_PSNAME_DATA_OFF offsetof(FORT_PSNAME, data)
struct fort_psname
{
UINT8 refcount;
UINT8 size;
WCHAR data[1];
};
/* Synchronize with tommy_hashdyn_node! */
typedef struct fort_psnode
{
@ -152,8 +159,9 @@ static PFORT_PSNAME fort_pstree_add_name(
UNICODE_STRING svchostPrefix;
RtlInitUnicodeString(&svchostPrefix, FORT_SVCHOST_PREFIX);
const int size = FORT_PSNAME_DATA_OFF + svchostPrefix.Length + serviceName.Length;
PFORT_PSNAME ps_name = fort_pool_malloc(&ps_tree->pool_list, size);
const UINT16 size = svchostPrefix.Length + serviceName.Length;
PFORT_PSNAME ps_name = fort_pool_malloc(&ps_tree->pool_list,
FORT_PSNAME_DATA_OFF + size + sizeof(WCHAR)); /* include terminating zero */
if (ps_name != NULL) {
ps_name->refcount = 1;
@ -161,12 +169,14 @@ static PFORT_PSNAME fort_pstree_add_name(
PCHAR data = (PCHAR) &ps_name->data;
RtlCopyMemory(data, svchostPrefix.Buffer, svchostPrefix.Length);
data += svchostPrefix.Length;
UNICODE_STRING destString = { .Length = serviceName.Length,
.MaximumLength = serviceName.Length,
.Buffer = (PWSTR) data };
RtlDowncaseUnicodeString(&destString, &serviceName, FALSE);
UNICODE_STRING nameString;
nameString.Length = serviceName.Length;
nameString.MaximumLength = serviceName.Length;
nameString.Buffer = (PWSTR) (data + svchostPrefix.Length);
RtlDowncaseUnicodeString(&nameString, &serviceName, FALSE);
*(PWSTR) (data + size) = L'\0';
}
return ps_name;
@ -344,7 +354,8 @@ FORT_API void fort_pstree_close(PFORT_PSTREE ps_tree)
KeReleaseInStackQueuedSpinLock(&lock_queue);
}
FORT_API PFORT_PSNAME fort_pstree_acquire_proc_name(PFORT_PSTREE ps_tree, DWORD processId)
FORT_API PFORT_PSNAME fort_pstree_acquire_proc_name(
PFORT_PSTREE ps_tree, DWORD processId, PUNICODE_STRING path)
{
PFORT_PSNAME ps_name = NULL;
@ -355,6 +366,10 @@ FORT_API PFORT_PSNAME fort_pstree_acquire_proc_name(PFORT_PSTREE ps_tree, DWORD
if (proc != NULL && proc->ps_name != NULL) {
ps_name = proc->ps_name;
++ps_name->refcount;
path->Length = ps_name->size;
path->MaximumLength = ps_name->size;
path->Buffer = ps_name->data;
}
}
KeReleaseInStackQueuedSpinLock(&lock_queue);

View File

@ -19,12 +19,8 @@ typedef struct fort_pstree
KSPIN_LOCK lock;
} FORT_PSTREE, *PFORT_PSTREE;
typedef struct fort_psname
{
UINT8 refcount;
UINT8 size;
WCHAR data[1];
} FORT_PSNAME, *PFORT_PSNAME;
struct fort_psname;
typedef struct fort_psname FORT_PSNAME, *PFORT_PSNAME;
#if defined(__cplusplus)
extern "C" {
@ -34,7 +30,8 @@ FORT_API void fort_pstree_open(PFORT_PSTREE ps_tree);
FORT_API void fort_pstree_close(PFORT_PSTREE ps_tree);
FORT_API PFORT_PSNAME fort_pstree_acquire_proc_name(PFORT_PSTREE ps_tree, DWORD processId);
FORT_API PFORT_PSNAME fort_pstree_acquire_proc_name(
PFORT_PSTREE ps_tree, DWORD processId, PUNICODE_STRING path);
FORT_API void fort_pstree_release_proc_name(PFORT_PSTREE ps_tree, PFORT_PSNAME ps_name);

View File

@ -205,11 +205,11 @@ quint16 confAppFind(const void *drvConf, const QString &kernelPath)
{
const PFORT_CONF conf = (const PFORT_CONF) drvConf;
const QString kernelPathLower = kernelPath.toLower();
const quint32 len = quint32(kernelPathLower.size()) * sizeof(wchar_t);
const wchar_t *p = (const wchar_t *) kernelPathLower.utf16();
const quint32 len = quint32(kernelPathLower.size()) * sizeof(WCHAR);
const WCHAR *p = (PCWCHAR) kernelPathLower.utf16();
const FORT_APP_FLAGS app_flags =
fort_conf_app_find(conf, (const char *) p, len, fort_conf_app_exe_find);
fort_conf_app_find(conf, (const PVOID) p, len, fort_conf_app_exe_find);
return app_flags.v;
}