Audit a stack history for invalid code. @param DetectionSource - The filter we are checking the stack of. @param SourceProcessId - The source of the audit. @param SourcePath - The source path. @param TargetPath - The target path. @param StackHistory - A variable-length array of stack return history. @param StackHistorySize - Size of the StackHistory array. */
| 45 | @param StackHistorySize - Size of the StackHistory array. |
| 46 | */ |
| 47 | VOID |
| 48 | DetectionLogic::AuditUserStackWalk ( |
| 49 | _In_ DETECTION_SOURCE DetectionSource, |
| 50 | _In_ HANDLE SourceProcessId, |
| 51 | _In_ PUNICODE_STRING SourcePath, |
| 52 | _In_ PUNICODE_STRING TargetPath, |
| 53 | _In_ STACK_RETURN_INFO StackHistory[], |
| 54 | _In_ ULONG StackHistorySize |
| 55 | ) |
| 56 | { |
| 57 | ULONG i; |
| 58 | BOOLEAN stackViolation; |
| 59 | PVOID firstViolatingAddress; |
| 60 | |
| 61 | stackViolation = FALSE; |
| 62 | firstViolatingAddress = NULL; |
| 63 | |
| 64 | // |
| 65 | // Check if any of the stack returns are to unmapped code. |
| 66 | // |
| 67 | for (i = 0; i < StackHistorySize; i++) |
| 68 | { |
| 69 | if (StackHistory[i].MemoryInModule == FALSE && |
| 70 | StackHistory[i].ExecutableMemory && |
| 71 | StackHistory[i].RawAddress != 0x0 && |
| 72 | RCAST<ULONG64>(StackHistory[i].RawAddress) < MmUserProbeAddress) |
| 73 | { |
| 74 | DBGPRINT("DetectionLogic!AuditUserStackWalk: Alert pid 0x%X, Violate 0x%llx, Source %i", PsGetCurrentProcessId(), StackHistory[i].RawAddress, DetectionSource); |
| 75 | stackViolation = TRUE; |
| 76 | firstViolatingAddress = StackHistory[i].RawAddress; |
| 77 | break; |
| 78 | } |
| 79 | } |
| 80 | |
| 81 | if (stackViolation == FALSE) |
| 82 | { |
| 83 | return; |
| 84 | } |
| 85 | |
| 86 | // |
| 87 | // Push the alert. |
| 88 | // |
| 89 | this->PushStackViolationAlert(DetectionSource, firstViolatingAddress, SourceProcessId, SourcePath, TargetPath, StackHistory, StackHistorySize); |
| 90 | } |
| 91 | |
| 92 | /** |
| 93 | Create and push a stack violation alert. |
no test coverage detected