learn.c
来自「臭氧层主动防御系统驱动源代码!臭氧层主动防御系统驱动源代码!」· C语言 代码 · 共 1,415 行 · 第 1/2 页
C
1,415 行
/*
* FilterDllOperation()
*
* Description:
* Convert DLL operations (such as OP_READ, OP_WRITE) into their ASCII representation.
*
* Parameters:
* OperationType - operation type.
*
* Returns:
* Pointer to an ASCII string.
*/
PCHAR
FilterDllOperation(UCHAR OperationType)
{
return "load";
}
/*
* FilterServiceOperation()
*
* Description:
* Convert service operations (such as OP_START, OP_WRITE) into their ASCII representation.
*
* Parameters:
* OperationType - operation type.
*
* Returns:
* Pointer to an ASCII string.
*/
PCHAR
FilterServiceOperation(UCHAR OperationType)
{
if (IS_BIT_SET(OperationType, OP_SERVICE_START))
return "start";
if (IS_BIT_SET(OperationType, OP_SERVICE_STOP))
return "stop";
if (IS_BIT_SET(OperationType, OP_SERVICE_CREATE))
return "create";
if (IS_BIT_SET(OperationType, OP_SERVICE_DELETE))
return "delete";
LOG(LOG_SS_LEARN, LOG_PRIORITY_DEBUG, ("FilterServiceOperation: invalid operation type %d\n", OperationType));
return "all";
}
/*
* FilterTimeOperation()
*
* Description:
* Convert time operations (such as OP_TIME_CHANGE) into their ASCII representation.
*
* Parameters:
* OperationType - operation type.
*
* Returns:
* Pointer to an ASCII string.
*/
PCHAR
FilterTimeOperation(UCHAR OperationType)
{
if (IS_BIT_SET(OperationType, OP_TIME_CHANGE))
return "change";
LOG(LOG_SS_LEARN, LOG_PRIORITY_DEBUG, ("FilterTimeOperation: invalid operation type %d\n", OperationType));
return "all";
}
/*
* FilterTokenOperation()
*
* Description:
* Convert token operations (such as OP_TOKEN_MODIFY) into their ASCII representation.
*
* Parameters:
* OperationType - operation type.
*
* Returns:
* Pointer to an ASCII string.
*/
PCHAR
FilterTokenOperation(UCHAR OperationType)
{
if (IS_BIT_SET(OperationType, OP_TOKEN_MODIFY))
return "modify";
LOG(LOG_SS_LEARN, LOG_PRIORITY_DEBUG, ("FilterTokenOperation: invalid operation type %d\n", OperationType));
return "all";
}
/*
* FilterSyscallOperation()
*
* Description:
* This function is never supposed to be called.
*
* Parameters:
* OperationType - operation type.
*
* Returns:
* An error.
*/
PCHAR
FilterSyscallOperation(UCHAR OperationType)
{
LOG(LOG_SS_LEARN, LOG_PRIORITY_DEBUG, ("FilterSyscallOperation: this function is not supposed to be called.\n"));
return "error";
}
typedef PCHAR (*fpFilterObject) (PCHAR path);
typedef PCHAR (*fpFilterOperation) (UCHAR OperationType);
/* in C++ these would be member methods */
struct
{
PCHAR Prefix;
fpFilterObject FilterObjectProc;
fpFilterOperation FilterOperationProc;
} RuleTypeData[] =
{
{ "file", FilterFilePath, FilterOperation },
{ "directory", FilterFilePath, FilterDirectoryOperation },
{ "mailslot", FilterMailslotPath, FilterSimpleOperation },
{ "namedpipe", FilterNamedpipePath, FilterSimpleOperation },
{ "registry", FilterRegistryPath, FilterOperation },
{ "section", FilterBaseNamedObjectsPath, FilterOperation },
{ "dll", FilterDll, FilterDllOperation },
{ "event", FilterBaseNamedObjectsPath, FilterCreateOpenOperation },
{ "semaphore", FilterBaseNamedObjectsPath, FilterCreateOpenOperation },
{ "job", FilterBaseNamedObjectsPath, FilterCreateOpenOperation },
{ "mutex", FilterBaseNamedObjectsPath, FilterCreateOpenOperation },
{ "port", FilterPath, FilterPortOperation },
{ "symlink", FilterPath, FilterCreateOpenOperation },
{ "timer", FilterBaseNamedObjectsPath, FilterCreateOpenOperation },
{ "process", FilterFilePath, FilterProcessOperation },
{ "driver", FilterFilePath, FilterDriverOperation },
{ "dirobj", FilterPath, FilterCreateOpenOperation },
{ "atom", FilterPath, FilterAtomOperation },
{ "network", FilterPath, FilterNetworkOperation },
{ "service", FilterPath, FilterServiceOperation },
{ "time", FilterPath, FilterTimeOperation },
{ "token", FilterPath, FilterTokenOperation },
{ "syscall", FilterPath, FilterSyscallOperation },
};
/*
* DecodeAction()
*
* Description:
* .
*
* Parameters:
* .
*
* Returns:
* .
*/
PCHAR
DecodeAction(UCHAR ActionType)
{
switch (ActionType)
{
case ACTION_ASK:
case ACTION_ASK_DEFAULT:
return "ask";
case ACTION_PERMIT:
case ACTION_ASK_PERMIT:
case ACTION_PERMIT_DEFAULT:
return "permit";
case ACTION_DENY:
case ACTION_ASK_DENY:
case ACTION_DENY_DEFAULT:
return "deny";
case ACTION_LOG:
case ACTION_ASK_LOG:
case ACTION_LOG_DEFAULT:
return "log";
case ACTION_QUIETDENY:
case ACTION_QUIETDENY_DEFAULT:
return "quietdeny";
case ACTION_TERMINATE:
case ACTION_ASK_TERMINATE:
return "log";
default:
return "unknown";
}
}
/*
* CreateRule()
*
* Description:
* Generate an ASCII rule for rule 'r' of type RuleType.
*
* Parameters:
* RuleType - rule type.
* r - rule itself.
* buffer - output buffer.
*
* Returns:
* TRUE if a rule was created, FALSE otherwise.
*/
BOOLEAN
CreateRule(RULE_TYPE RuleType, PPOLICY_RULE r, PCHAR buffer)
{
PCHAR name;
ASSERT(r);
ASSERT(buffer);
if (r->MatchType != MATCH_ALL)
{
name = RuleTypeData[ RuleType ].FilterObjectProc(r->Name);
/* if name is NULL there is no need to remember this rule */
if (name == NULL)
return FALSE;
if (strlen(name) > MAX_PATH)
{
LOG(LOG_SS_LEARN, LOG_PRIORITY_DEBUG, ("CreateRule: name '%s' is too long\n", name));
return FALSE;
}
}
/*
* construct the "objecttype_operation: " part first
*/
strcpy(buffer, RuleTypeData[ RuleType ].Prefix);
strcat(buffer, "_");
strcat(buffer, RuleTypeData[ RuleType ].FilterOperationProc(r->OperationType));
strcat(buffer, ": ");
/*
* now construct the action part
*/
if (r->MatchType != MATCH_ALL)
{
strcat(buffer, "name ");
if (r->MatchType == MATCH_WILDCARD)
strcat(buffer, "match \"");
else
strcat(buffer, "eq \"");
strcat(buffer, name);
strcat(buffer, "\" then ");
}
strcat(buffer, DecodeAction(r->ActionType));
/* add optional rule clause */
if (r->RuleNumber != 0)
{
CHAR rule[16];
sprintf(rule, " [rule %d]", r->RuleNumber);
strcat(buffer, rule);
}
return TRUE;
}
/*
* CreateServiceRule()
*
* Description:
* .
*
* Parameters:
* .
*
* Returns:
* .
*/
BOOLEAN
CreateServiceRule(PPOLICY_RULE r, PCHAR buffer)
{
strcpy(buffer, "service_");
strcat(buffer, r->Name + 2);
strcat(buffer, ": permit");
return TRUE;
}
BOOLEAN WriteRule(PCHAR rule);
BOOLEAN WritePolicyFile(PCHAR buffer);
/*
* FlushPolicy()
*
* Description:
* .
*
* Parameters:
* .
*
* Returns:
* Nothing.
*/
void
FlushPolicy()
{
PPOLICY_RULE r;
KIRQL irql;
char buffer[MAX_PATH*2];
UCHAR i;
BOOLEAN ValidRule;
// cannot write to files while holding spinlock (irql != PASSIVE_LEVEL)
// KeAcquireSpinLock(&NewPolicy.SpinLock, &irql);
sprintf(buffer, "\r\n# %S Default Process Policy\r\n", ProcessToMonitor);
WriteRule(buffer);
sprintf(buffer, "policy_default: %s\r\n", DecodeAction(NewPolicy.DefaultPolicyAction));
WriteRule(buffer);
if (! IS_OVERFLOW_PROTECTION_ON(NewPolicy))
WriteRule("protection_overflow: off");
if (! IS_USERLAND_PROTECTION_ON(NewPolicy))
WriteRule("protection_userland: off");
if (! IS_EXTENSION_PROTECTION_ON(NewPolicy))
WriteRule("protection_extension: off");
if (! IS_DEBUGGING_PROTECTION_ON(NewPolicy))
WriteRule("protection_debugging: off");
if (! IS_VDM_PROTECTION_ON(NewPolicy))
WriteRule("protection_dos16: off");
// KdPrint(("%s process\n", IsGuiThread ? "GUI" : "NON GUI"));
for (i = 0; i < RULE_LASTONE; i++)
{
r = NewPolicy.RuleList[i];
if (r)
{
WritePolicyFile("\r\n\r\n# ");
WritePolicyFile(RuleTypeData[i].Prefix);
WritePolicyFile(" related operations\r\n\r\n");
}
while (r)
{
if (i != RULE_SYSCALL)
ValidRule = CreateRule(i, r, buffer);
else
ValidRule = CreateServiceRule(r, buffer);
if (ValidRule == TRUE)
WriteRule(buffer);
r = (PPOLICY_RULE) r->Next;
}
}
// KeReleaseSpinLock(&NewPolicy.SpinLock, irql);
}
/*
* ShutdownLearningMode()
*
* Description:
* .
*
* Parameters:
* .
*
* Returns:
* Nothing.
*/
BOOLEAN
ShutdownLearningMode()
{
UNICODE_STRING pathname;
OBJECT_ATTRIBUTES oa;
IO_STATUS_BLOCK isb;
WCHAR PolicyPath[MAX_PATH];
/* now open a file where the new policy will be written, possibly clobbering the old policy */
//XXX should really copy an existing policy to a .bak file
// _snwprintf(PolicyPath, MAX_PATH, L"\\??\\c:\\policy\\%s.policy", ProcessToMonitor);
_snwprintf(PolicyPath, MAX_PATH, L"\\??\\%s\\policy\\%s.policy", OzoneInstallPath, ProcessToMonitor);
PolicyPath[MAX_PATH - 1] = 0;
LOG(LOG_SS_LEARN, LOG_PRIORITY_DEBUG, ("ShutdownLearningMode: Writing policy to %S\n", PolicyPath));
RtlInitUnicodeString(&pathname, PolicyPath);
InitializeObjectAttributes(&oa, &pathname, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
if (!NT_SUCCESS(ZwCreateFile(&hFile, GENERIC_WRITE, &oa, &isb,
NULL, 0, 0, FILE_SUPERSEDE,
FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0)))
{
LOG(LOG_SS_LEARN, LOG_PRIORITY_DEBUG, ("ShutdownLearningMode: Failed to open file %S\n", pathname.Buffer));
return FALSE;
}
offset = 0;
FlushPolicy();
PolicyDelete(&NewPolicy);
ZwClose(hFile);
hFile = 0;
return TRUE;
}
/*
* WritePolicyFile()
*
* Description:
* .
*
* Parameters:
* .
*
* Returns:
* Nothing.
*/
BOOLEAN
WritePolicyFile(PCHAR buffer)
{
int len = strlen(buffer);
IO_STATUS_BLOCK isb;
if (!NT_SUCCESS(ZwWriteFile(hFile, NULL, NULL, NULL, &isb, (PVOID) buffer, len, (PLARGE_INTEGER) &offset, NULL)))
{
LOG(LOG_SS_LEARN, LOG_PRIORITY_DEBUG, ("WritePolicyFile(): ZwReadFile failed\n"));
return FALSE;
}
if (isb.Information != len)
{
LOG(LOG_SS_LEARN, LOG_PRIORITY_DEBUG, ("WritePolicyFile(): Asked to write %d bytes. Wrote only %d\n", len, isb.Information));
}
offset += isb.Information;
return TRUE;
}
/*
* WriteRule()
*
* Description:
* .
*
* Parameters:
* .
*
* Returns:
* Nothing.
*/
BOOLEAN
WriteRule(PCHAR rule)
{
BOOLEAN ret, ret2;
ret = WritePolicyFile(rule);
ret2 = WritePolicyFile("\r\n");
return ret && ret2;
}
/*
* RememberRule()
*
* Description:
* Create a new rule.
*
* Parameters:
* RuleType - rule type.
* ObjectName - name of an object associated with the current rule.
* OperationType - operation type.
*
* Returns:
* TRUE to indicate success, FALSE if failed.
*/
BOOLEAN
RememberRule(RULE_TYPE RuleType, PCHAR ObjectName, UCHAR OperationType)
{
PPOLICY_RULE rule = NewPolicy.RuleList[RuleType];
KIRQL irql;
int len = 0;
if (ObjectName)
len = strlen(ObjectName);
KeAcquireSpinLock(&NewPolicy.SpinLock, &irql);
/*
* don't save duplicate rules
*/
while (rule != NULL)
{
if ( (rule->MatchType == MATCH_ALL) ||
(rule->MatchType == MATCH_SINGLE && len == rule->NameLength && _stricmp(ObjectName, rule->Name) == 0) ||
(rule->MatchType == MATCH_WILDCARD && WildcardMatch(ObjectName, rule->Name) == WILDCARD_MATCH) )
{
rule->OperationType |= OperationType;
KeReleaseSpinLock(&NewPolicy.SpinLock, irql);
return TRUE;
}
rule = (PPOLICY_RULE) rule->Next;
}
rule = ExAllocatePoolWithTag(NonPagedPool, sizeof(POLICY_RULE) + len, _POOL_TAG);
if (rule == NULL)
{
LOG(LOG_SS_LEARN, LOG_PRIORITY_DEBUG, ("RememberRule: out of memory\n"));
return FALSE;
}
RtlZeroMemory(rule, sizeof(POLICY_RULE));
rule->ActionType = ACTION_PERMIT;
rule->OperationType = OperationType;
if (ObjectName)
{
rule->NameLength = (USHORT) len;
strcpy(rule->Name, ObjectName);
rule->MatchType = MATCH_SINGLE;
}
else
{
rule->MatchType = MATCH_ALL;
}
rule->Next = NewPolicy.RuleList[RuleType];
NewPolicy.RuleList[RuleType] = rule;
KeReleaseSpinLock(&NewPolicy.SpinLock, irql);
return TRUE;
}
/*
* DetermineThreadType()
*
* Description:
* Determine whether a thread is GUI enabled or not. Done by checking which
* system call table the thread is using.
*
* Parameters:
* None.
*
* Returns:
* Nothing.
*/
void
DetermineThreadType()
{
if (ThreadServiceTableOffset == 0)
return;
if (* (PULONG) ((PCHAR) PsGetCurrentThread() + ThreadServiceTableOffset) != (ULONG) &KeServiceDescriptorTable[0])
IsGuiThread = TRUE;
}
/*
* AddRule()
*
* Description:
* Create a new rule for a particular rule type, operation type and object.
*
* Parameters:
* RuleType - rule type.
* str - optional character object name.
* OperationType - operation taking place.
*
* Returns:
* Nothing.
*/
BOOLEAN
AddRule(RULE_TYPE RuleType, PCHAR str, UCHAR OperationType)
{
PWSTR filename;
filename = wcsrchr(GetCurrentProcessName(), L'\\');
if (filename == NULL)
filename = GetCurrentProcessName();
else
++filename;
if (_wcsicmp(filename, ProcessToMonitor) != 0)
return TRUE;
// DetermineThreadType();
return RememberRule(RuleType, str, OperationType);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?