39 DWORD modNameAlignment;
42 char instr[ND_MIN_BUF_SIZE];
44 pDriver = Originator->Original.Driver;
45 pRetDriver = Originator->Return.Driver;
51 if (Originator->Instruction)
53 NDSTATUS ndstatus = NdToText(Originator->Instruction, Originator->Original.Rip,
sizeof(instr), instr);
54 if (!ND_SUCCESS(ndstatus))
68 ret = snprintf(l, rem,
", RIP %0*llx",
gGuest.
WordSize * 2, Originator->Original.Rip);
70 if (ret < 0 || ret >= rem)
72 ERROR(
"[ERROR] snprintf error: %d, size %d\n", ret, rem);
80 if (Originator->Original.Section[0] != 0)
82 ret = snprintf(l, rem,
" (%s)", Originator->Original.Section);
84 if (ret < 0 || ret >= rem)
86 ERROR(
"[ERROR] snprintf error: %d, size %d\n", ret, rem);
97 ret = snprintf(l, rem,
", Instr: %s", instr);
99 if (ret < 0 || ret >= rem)
101 ERROR(
"[ERROR] snprintf error: %d, size %d\n", ret, rem);
110 ret = snprintf(l, rem,
", IsInjection: %s %s",
111 (Originator->Injection.User || Originator->Injection.Kernel) ?
"yes" :
"no",
112 Originator->Injection.User ?
"(user-mode)" :
113 Originator->Injection.Kernel ?
"(kernel-mode)" :
"");
115 if (ret < 0 || ret >= rem)
117 ERROR(
"[ERROR] snprintf error: %d, size %d\n", ret, rem);
127 if (Originator->Return.Driver && Originator->Original.Rip != Originator->Return.Rip)
136 ret = snprintf(l, rem,
", RIP %0*llx",
gGuest.
WordSize * 2, Originator->Return.Rip);
138 if (ret < 0 || ret >= rem)
140 ERROR(
"[ERROR] snprintf error: %d, size %d\n", ret, rem);
148 if (Originator->Return.Section[0] != 0)
150 ret = snprintf(l, rem,
"(%s)", Originator->Return.Section);
152 if (ret < 0 || ret >= rem)
154 ERROR(
"[ERROR] snprintf error: %d, size %d\n", ret, rem);
166 if (Originator->Process.Process != NULL)
204 if (ret < 0 || ret >= rem)
206 ERROR(
"[ERROR] snprintf error: %d, size %d\n", ret, rem);
214 if (Victim->Object.Library.Export == NULL)
220 pExport = Victim->Object.Library.Export;
225 ret = snprintf(l, rem,
", Exports (%u) : [", pExport->
NumberOfOffsets);
226 if (ret < 0 || ret >= rem)
228 ERROR(
"[ERROR] snprintf error: %d, size %d\n", ret, rem);
240 ret = snprintf(l, rem,
"'%s'", pExport->
Names[export]);
244 ret = snprintf(l, rem,
"'%s',", pExport->
Names[export]);
247 if (ret < 0 || ret >= rem)
249 ERROR(
"[ERROR] snprintf error: %d, size %d\n", ret, rem);
259 ret = snprintf(l, rem,
"], Delta: +%02x, ",
260 (
DWORD)(Victim->Ept.Gva - Victim->Object.Library.WinMod->VirtualBase - pExport->
Rva));
261 if (ret < 0 || ret >= rem)
263 ERROR(
"[ERROR] snprintf error: %d, size %d\n", ret, rem);
272 ret = snprintf(l, rem,
", Address: (%0*llx, %0*llx)",
275 if (ret < 0 || ret >= rem)
277 ERROR(
"[ERROR] snprintf error: %d, size %d\n", ret, rem);
285 ret = snprintf(l, rem,
", WriteInfo: (%u, %016llx -> %016llx)",
286 Victim->WriteInfo.AccessSize,
287 Victim->WriteInfo.OldValue[0],
288 Victim->WriteInfo.NewValue[0]);
289 if (ret < 0 || ret >= rem)
291 ERROR(
"[ERROR] snprintf error: %d, size %d\n", ret, rem);
299 if (Victim->ZoneFlags)
301 ret = snprintf(l, rem,
", Flags:%s%s%s%s%s (0x%llx)",
307 (
unsigned long long)Victim->ZoneFlags);
308 if (ret < 0 || ret >= rem)
310 ERROR(
"[ERROR] snprintf error: %d, size %d\n", ret, rem);
327 ret = snprintf(l, rem,
"^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^%sROOTKIT (kernel-user mode) ",
328 Victim->Object.Library.WinMod->Subsystem->Process->BetaDetections ?
" (B) " :
" ");
329 if (ret < 0 || ret >= rem)
331 ERROR(
"[ERROR] snprintf error: %d, size %d\n", ret, rem);
342 ret = snprintf(l, rem,
"(no sig)");
345 ret = snprintf(l, rem,
"(no exc)");
348 ret = snprintf(l, rem,
"(extra)");
351 ret = snprintf(l, rem,
"(error)");
354 ret = snprintf(l, rem,
"(value)");
357 ret = snprintf(l, rem,
"(export)");
360 ret = snprintf(l, rem,
"(value code)");
363 ret = snprintf(l, rem,
"(idt)");
366 ret = snprintf(l, rem,
"(version os)");
369 ret = snprintf(l, rem,
"(version intro)");
372 ret = snprintf(l, rem,
"(process creation)");
375 ret = snprintf(l, rem,
"(unknown)");
378 ret = snprintf(l, rem,
"(%d)", Reason);
382 if (ret < 0 || ret >= rem)
384 ERROR(
"[ERROR] snprintf error: %d, size %d\n", ret, rem);
392 snprintf(l, rem,
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
396 for (
DWORD t = 0; t < Originator->StackTrace.NumberOfTraces; t++)
398 if (NULL != Originator->StackTrace.Traces[t].ReturnModule)
400 LOG(
"[STACK TRACE] [at 0x%016llx] returning to [%s at 0x%016llx]\n",
401 Originator->StackTrace.Traces[t].CurrentRip,
403 Originator->StackTrace.Traces[t].ReturnAddress);
407 LOG(
"[STACK TRACE] [at 0x%016llx]\n", Originator->StackTrace.Traces[t].CurrentRip);
539 Exception->Victim.NameHash == Victim->Object.NameHash)
571 return (Exception->Victim.ProcessHash == Victim->Object.Library.WinMod->Subsystem->Process->NameHash);
575 WARNING(
"[WARNING] Not supported for Linux guest!\n");
597 switch (Exception->Type)
626 LOG(
"[ERROR] This is a corruption in the update/exception. Type = %d!\n", Exception->Type);
665 if ((Originator->Injection.User || Originator->Injection.Kernel) &&
673 if ((!Originator->Injection.User && !Originator->Injection.Kernel) &&
712 (Originator->Original.Driver != NULL))
723 (Victim->WriteInfo.OldValue[0] == 0))
734 match = 0 == memcmp(Originator->Return.Section,
"INIT", 4);
738 match = 0 == memcmp(Originator->Return.Section,
"init", 4);
746 match = 0 == memcmp(Originator->Original.Section,
"INIT", 4);
750 match = 0 == memcmp(Originator->Original.Section,
"init", 4);
754 else if (Originator->IsEntryPoint)
759 else if (Victim->WriteInfo.OldValue[0] == 0)
809 if (NULL == Originator)
829 !memcmp(Victim->WriteInfo.OldValue, Victim->WriteInfo.NewValue,
830 MIN(Victim->WriteInfo.AccessSize,
sizeof(Victim->WriteInfo.NewValue)))))
838 if (Originator->Injection.User)
842 hash = Originator->Process.WinProc->NameHash;
846 hash = Originator->Process.LixProc->CommHash;
856 if (Originator->Injection.Kernel)
858 hash = Originator->Return.NameHash;
862 hash = Originator->Original.NameHash;
878 goto _match_ex_alert;
881 if (!Originator->Injection.User &&
885 goto _match_ex_alert;
888 if (pEx->Originator.NameHash > hash)
892 else if (pEx->Originator.NameHash != hash)
905 if (!Originator->Injection.User && Originator->Original.NameHash ==
INITIAL_CRC_VALUE)
930 if (Originator->Injection.Kernel &&
931 Originator->Original.Driver &&
932 Originator->Return.Driver &&
933 Originator->Original.Rip == Originator->Return.Rip)
962 if (pEx->Originator.NameHash > hash)
966 else if (pEx->Originator.NameHash != hash)
987 goto _beta_exceptions;
992 if (!Originator->Injection.User && Originator->Return.NameHash !=
INITIAL_CRC_VALUE)
1011 if (pEx->Originator.NameHash > Originator->Return.NameHash)
1015 else if (pEx->Originator.NameHash != Originator->Return.NameHash)
1048 if (!Originator->Injection.User &&
1057 if (!Originator->Injection.User && pEx->Originator.NameHash != Originator->Return.NameHash)
1064 if (!Originator->Injection.User && pEx->Originator.NameHash != Originator->Original.NameHash)
1069 if (Originator->Injection.User)
1073 if (pEx->Originator.NameHash != Originator->Process.WinProc->NameHash)
1080 if (pEx->Originator.NameHash != Originator->Process.LixProc->CommHash)
#define EXCEPTION_NO_INSTRUCTION
enum _INTRO_ACTION_REASON INTRO_ACTION_REASON
The reason for which an INTRO_ACTION was taken.
#define INT_STATUS_EXCEPTION_NOT_MATCHED
An internal error occurred (no memory, pages not present, etc.).
int IntExceptPrintWinProcInfo(WIN_PROCESS_OBJECT *Process, char *Header, char *Line, int MaxLength, DWORD NameAlignment)
Print the data from the provided WIN_PROCESS_OBJECT.
LIST_HEAD KernelUserExceptions[EXCEPTION_TABLE_SIZE]
Array of linked lists used for kernel-user mode exceptions.
Describe a kernel-user mode exception.
void IntExceptKernelUserLogInformation(EXCEPTION_VICTIM_ZONE *Victim, EXCEPTION_KM_ORIGINATOR *Originator, INTRO_ACTION Action, INTRO_ACTION_REASON Reason)
Print the information about a kernel-user mode violation and dumps the code-blocks.
The name can be any string.
#define ZONE_LIB_RESOURCES
Used for the resources section (usually .rsrc inside a driver or dll).
DWORD NumberOfOffsets
Number of symbols pointing to the exported RVA.
The exception will take into consideration the return driver/dll.
The modified object is inside an EPT hook.
#define INT_STATUS_EXCEPTION_CHECKS_OK
int IntExceptPrintWinModInfo(WIN_PROCESS_MODULE *Module, char *Header, char *Line, int MaxLength, DWORD NameAlignment)
Print the data from the provided WIN_PROCESS_MODULE.
The exception is valid only for read violation.
The exception is valid only if the write comes due to an injection from user-mode.
static void IntExceptKernelUserLogWindowsInformation(EXCEPTION_VICTIM_ZONE *Victim, EXCEPTION_KM_ORIGINATOR *Originator, INTRO_ACTION Action, INTRO_ACTION_REASON Reason)
Print the information about a kernel-user mode violation (windows guest).
Describes a user-mode originator.
The name can be any string.
INTSTATUS IntExceptMatchException(void *Victim, void *Originator, void *Exception, EXCEPTION_TYPE ExceptionType, INTRO_ACTION *Action, INTRO_ACTION_REASON *Reason)
This function tries to find a exception for the current violation..
int INTSTATUS
The status data type.
The exception will match only for the init phase of a driver/process.
Describes a kernel-mode originator.
The modified object is any with the modified name.
INTRO_GUEST_TYPE OSType
The type of the guest.
The exception is valid only for write violation.
Describes a kernel driver.
#define ZONE_INTEGRITY
Used for integrity zone.
static __inline BOOLEAN IntExceptKernelUserMatchObjectType(EXCEPTION_VICTIM_ZONE *Victim, KUM_EXCEPTION *Exception)
Checks if the zone-type of the current exception matches the object-type of the victim.
LIST_HEAD KernelUserAlertExceptions
Linked list used for kernel-user mode exceptions that are added from alert.
#define ZONE_LIB_CODE
Used for a generic code zone.
#define INITIAL_CRC_VALUE
EXCEPTIONS * Exceptions
The exceptions that are currently loaded.
The modified object is inside an integrity hook.
static __inline BOOLEAN IntExceptKernelUserMatchArch(KUM_EXCEPTION *Exception)
Checks if the architecture-flags of the current exception match the architecture-flags of the origina...
#define ZONE_EXECUTE
Used for execute violation.
The exception is valid only for execute violation.
BOOLEAN Guest64
True if this is a 64-bit guest, False if it is a 32-bit guest.
INTSTATUS IntExceptKernelUserVerifyExtra(EXCEPTION_VICTIM_ZONE *Victim, EXCEPTION_UM_ORIGINATOR *Originator, UM_EXCEPTION *Exception)
This function is used as an extra step in exception mechanism.
The name is the operating system kernel name.
#define INT_STATUS_INVALID_PARAMETER_4
The exception is valid only if the write comes due to an injection from kernel-mode.
INTSTATUS IntExceptKernelUser(EXCEPTION_VICTIM_ZONE *Victim, EXCEPTION_KM_ORIGINATOR *Originator, INTRO_ACTION *Action, INTRO_ACTION_REASON *Reason)
This function iterates through exception lists and tries to find an exception that matches the origin...
#define for_each_kum_exception(_ex_head, _var_name)
static __inline BOOLEAN IntExceptKernelUserMatchProcessHash(EXCEPTION_VICTIM_ZONE *Victim, KUM_EXCEPTION *Exception)
Checks if the exception process name-hash of the current exception matches the process name-hash of t...
BYTE WordSize
Guest word size. Will be 4 for 32-bit guests and 8 for 64-bit guests.
LIST_HEAD KernelUserFeedbackExceptions
Linked list used for kernel-user mode exceptions that have the feedback flag.
char gExcLogLine[2 *ONE_KILOBYTE]
The exception log line.
The exception will take into consideration the return driver.
#define ZONE_LIB_EXPORTS
Used for the exports of a dll, driver, etc.
The modified object is inside the process module's EAT.
Describes the modified zone.
#define UNREFERENCED_PARAMETER(P)
INTSTATUS IntExceptKernelUserMatchVictim(EXCEPTION_VICTIM_ZONE *Victim, EXCEPTION_KM_ORIGINATOR *Originator, KUM_EXCEPTION *Exception)
This function checks if the exception matches the originator and the modified zone.
The name can be any string.
The modified object is inside the process module's IAT.
Describe a user-mode exception.
DWORD Rva
The RVA of this export.
enum _INTRO_ACTION INTRO_ACTION
Event actions.
int IntExceptPrintWinKmModInfo(KERNEL_DRIVER *Module, char *Header, char *Line, int MaxLength, DWORD NameAlignment)
Print the information about the provided KERNEL_DRIVER (windows guest).
static __inline BOOLEAN IntExceptKernelUserMatchNameHash(EXCEPTION_VICTIM_ZONE *Victim, KUM_EXCEPTION *Exception)
Checks if the exception name-hash of the current exception matches the name-hash of the victim...
The action was allowed, but it has the BETA flag (Introcore is in log-only mode). ...
GUEST_STATE gGuest
The current guest state.
static __inline BOOLEAN IntExceptKernelUserMatchZoneFlags(EXCEPTION_VICTIM_ZONE *Victim, KUM_EXCEPTION *Exception)
Checks if the zone-flags of the current exception match the zone flags of the victim.
LIST_HEAD NoNameKernelUserExceptions
Linked list used for kernel-user mode exceptions that don't have a valid originator (-)...
#define EXCEPTION_TABLE_ID(H)
#define ZONE_READ
Used for read violation.
WINUM_CACHE_EXPORT * IntWinUmCacheGetExportFromRange(WIN_PROCESS_MODULE *Module, QWORD Gva, DWORD Length)
Tries to find an export in the range [Gva - Length, Gva].
The action was blocked because no exception signature matched.
PCHAR Names[MAX_OFFSETS_PER_NAME]
The names pointing to this RVA. Each name will point inside the Names structure inside WINUM_CACHE_EX...
void IntExceptDumpSignatures(void *Originator, EXCEPTION_VICTIM_ZONE *Victim, BOOLEAN KernelMode, BOOLEAN ReturnDrv)
Dump code blocks from the originator's RIP.
LIST_HEAD GenericKernelUserExceptions
Linked list used for kernel-user mode exceptions that have a generic originator(*).
char * utf16_for_log(const WCHAR *WString)
Converts a UTF-16 to a UTF-8 string to be used inside logging macros.
int IntExceptPrintLixTaskInfo(const LIX_TASK_OBJECT *Task, char *Header, char *Line, int MaxLength, DWORD NameAlignment)
Print the information about the provided LIX_TASK_OBJECT.
#define INT_STATUS_INVALID_PARAMETER_1
#define INT_STATUS_NOT_SUPPORTED
Kernel-User mode exception.
The action was blocked because there was no exception for it.
#define ZONE_LIB_IMPORTS
Used for the imports of a dll, driver, etc.
The original RIP is outside a driver and it returns into a driver (which is the originator name)...
The exception is valid only on 32 bit systems/process.
#define EXPORT_NAME_UNKNOWN
#define ZONE_WRITE
Used for write violation.
#define INT_STATUS_INVALID_PARAMETER_2
#define INT_STATUS_EXCEPTION_ALLOW
The exception (and signature, where's the case) matched, but the extra checks failed.
#define INT_STATUS_INVALID_PARAMETER_3
The modified object is inside the process modules.