📄 filter.c
字号:
request->result = result;
return result;
}
// write request to request queue
BOOLEAN log_request(struct flt_request *request)
{
KIRQL irql, irql2;
ULONG next_head;
char pname_buf[256], *pname;
struct plist_entry *ple;
if (!g_got_log && request->type == TYPE_RESOLVE_PID) // don't log - no log app
return FALSE;
KeAcquireSpinLock(&g_queue.guard, &irql);
next_head = (g_queue.head + 1) % REQUEST_QUEUE_SIZE;
if (next_head == g_queue.tail)
{
// queue overflow: reject one entry from tail
KdPrint(("[tdi_fw] log_request: queue overflow!\n"));
request->log_skipped = g_queue.data[g_queue.tail].log_skipped + 1;
// free process name & sid!
if (g_queue.data[g_queue.tail].pname != NULL)
free(g_queue.data[g_queue.tail].pname);
if (g_queue.data[g_queue.tail].sid_a != NULL)
free(g_queue.data[g_queue.tail].sid_a);
g_queue.tail = (g_queue.tail + 1) % REQUEST_QUEUE_SIZE;
}
else
request->log_skipped = 0;
memcpy(&g_queue.data[g_queue.head], request, sizeof(struct flt_request));
// try to get process name
pname = NULL;
if (request->pid != (ULONG)-1 &&
pid_pname_resolve(request->pid, pname_buf, sizeof(pname_buf)))
{
KdPrint(("[tdi_fw] log_request: pid:%u; pname:%s\n",
request->pid, pname_buf));
// ala strdup()
pname = (char *)malloc_np(strlen(pname_buf) + 1);
if (pname != NULL)
strcpy(pname, pname_buf);
else
KdPrint(("[tdi_fw] log_request: malloc_np!\n"));
}
g_queue.data[g_queue.head].pname = pname;
g_queue.head = next_head;
// don't free sid & attributes
if (request->sid_a != NULL)
request->sid_a = NULL;
KeReleaseSpinLock(&g_queue.guard, irql);
// signal to user app
if (g_queue.event != NULL)
KeSetEvent(g_queue.event, IO_NO_INCREMENT, FALSE);
return TRUE;
}
// read requests from log queue to buffer
ULONG get_request(char *buf, ULONG buf_size)
{
ULONG result = 0;
KIRQL irql;
// sanity check
if (buf_size < sizeof(struct flt_request))
return 0;
KeAcquireSpinLock(&g_queue.guard, &irql);
while (g_queue.head != g_queue.tail)
{
ULONG pname_size, sid_a_size;
if (g_queue.data[g_queue.tail].pname != NULL)
pname_size = strlen(g_queue.data[g_queue.tail].pname) + 1;
else
pname_size = 0;
if (g_queue.data[g_queue.tail].sid_a != NULL)
sid_a_size = g_queue.data[g_queue.tail].sid_a_size;
else
sid_a_size = 0;
if (buf_size < sizeof(struct flt_request) + pname_size + sid_a_size)
break;
memcpy(buf, &g_queue.data[g_queue.tail], sizeof(struct flt_request));
if (g_queue.data[g_queue.tail].pname != NULL)
{
((struct flt_request *)buf)->struct_size += pname_size;
strcpy(buf + sizeof(struct flt_request), g_queue.data[g_queue.tail].pname);
free(g_queue.data[g_queue.tail].pname);
g_queue.data[g_queue.tail].pname = NULL;
}
if (g_queue.data[g_queue.tail].sid_a != NULL)
{
// make sid pointer relative only
SID_AND_ATTRIBUTES *sid_a = g_queue.data[g_queue.tail].sid_a;
sid_a->Sid = (PSID)((char *)(sid_a->Sid) - (char *)sid_a);
// copy sid_a
memcpy(buf + sizeof(struct flt_request) + pname_size, sid_a, sid_a_size);
// free sid_a memory
free(sid_a);
g_queue.data[g_queue.tail].sid_a = NULL;
// increase pname_size and struct size
((struct flt_request *)buf)->struct_size += sid_a_size;
}
result += sizeof(struct flt_request) + pname_size + sid_a_size;
buf += sizeof(struct flt_request) + pname_size + sid_a_size;
buf_size -= sizeof(struct flt_request) + pname_size + sid_a_size;
g_queue.tail = (g_queue.tail + 1) % REQUEST_QUEUE_SIZE;
}
KdPrint(("[tdi_fw] get_request: copied %u bytes\n", result));
KeReleaseSpinLock(&g_queue.guard, irql);
return result;
}
// add rule to rules chain
NTSTATUS add_flt_rule(int chain, const struct flt_rule *rule)
{
NTSTATUS status;
struct flt_rule *new_rule;
KIRQL irql;
// sanity check
if (chain < 0 || chain >= MAX_CHAINS_COUNT)
return STATUS_INVALID_PARAMETER_1;
KeAcquireSpinLock(&g_rules.guard, &irql);
new_rule = (struct flt_rule *)malloc_np(sizeof(struct flt_rule));
if (new_rule == NULL)
{
KdPrint(("[tdi_fw] add_flt_rule: malloc_np\n"));
status = STATUS_INSUFFICIENT_RESOURCES;
goto done;
}
memcpy(new_rule, rule, sizeof(*new_rule));
// append
new_rule->next = NULL;
if (g_rules.chain[chain].tail == NULL)
{
g_rules.chain[chain].head = new_rule;
g_rules.chain[chain].tail = new_rule;
}
else {
g_rules.chain[chain].tail->next = new_rule;
g_rules.chain[chain].tail = new_rule;
}
status = STATUS_SUCCESS;
done:
KeReleaseSpinLock(&g_rules.guard, irql);
return status;
}
// clear rules chain
NTSTATUS clear_flt_chain(int chain)
{
struct flt_rule *rule;
KIRQL irql;
// sanity check
if (chain < 0 || chain >= MAX_CHAINS_COUNT)
return STATUS_INVALID_PARAMETER_1;
/* rules chain */
KeAcquireSpinLock(&g_rules.guard, &irql);
for (rule = g_rules.chain[chain].head; rule != NULL;)
{
struct flt_rule *rule2 = rule->next;
free(rule);
rule = rule2;
}
g_rules.chain[chain].head = NULL;
g_rules.chain[chain].tail = NULL;
if (g_rules.chain[chain].pname != NULL)
{
free(g_rules.chain[chain].pname);
g_rules.chain[chain].pname = NULL;
}
// deactivate chain
g_rules.chain[chain].active = FALSE;
KeReleaseSpinLock(&g_rules.guard, irql);
return STATUS_SUCCESS;
}
// set process name for chain
NTSTATUS set_chain_pname(int chain, char *pname)
{
KIRQL irql;
NTSTATUS status;
// sanity check
if (chain < 0 || chain >= MAX_CHAINS_COUNT)
return STATUS_INVALID_PARAMETER_1;
KdPrint(("[tdi_fw] set_chain_pname: setting name %s for chain %d\n", pname, chain));
KeAcquireSpinLock(&g_rules.guard, &irql);
if (g_rules.chain[chain].pname != NULL)
free(g_rules.chain[chain].pname);
g_rules.chain[chain].pname = (char *)malloc_np(strlen(pname) + 1);
if (g_rules.chain[chain].pname != NULL)
{
// copy pname
strcpy(g_rules.chain[chain].pname, pname);
status = STATUS_SUCCESS;
}
else
status = STATUS_INSUFFICIENT_RESOURCES;
KeReleaseSpinLock(&g_rules.guard, irql);
return status;
}
// set result of process name by pid resolving
NTSTATUS set_pid_pname(ULONG pid, char *pname)
{
KIRQL irql;
int i, chain = 0;
KdPrint(("[tdi_fw] set_pid_pname: setting pname %s for pid %u\n", pname, pid));
KeAcquireSpinLock(&g_rules.guard, &irql);
for (i = 0; i < MAX_CHAINS_COUNT; i++)
if (g_rules.chain[i].pname != NULL &&
_stricmp(pname, g_rules.chain[i].pname) == 0)
{
KdPrint(("[tdi_fw] set_pid_pname: found chain %d\n", i));
chain = i;
break;
}
KeReleaseSpinLock(&g_rules.guard, irql);
return pid_pname_set(pid, pname, chain);
}
// activate rules chain
NTSTATUS activate_flt_chain(int chain)
{
// sanity check
if (chain < 0 || chain >= MAX_CHAINS_COUNT)
return STATUS_INVALID_PARAMETER_1;
g_rules.chain[chain].active = TRUE;
return STATUS_SUCCESS;
}
BOOLEAN default_chain_only(void)
{
int i;
if (!g_rules.chain[0].active)
return FALSE;
for (i = 1; i < MAX_CHAINS_COUNT; i++)
if (g_rules.chain[i].active)
return FALSE;
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -