Bitdefender Hypervisor Memory Introspection
winapi.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 Bitdefender
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 #include "winapi.h"
6 #include "decoder.h"
7 #include "drivers.h"
8 #include "guests.h"
9 #include "introcpu.h"
10 #include "memcloak.h"
11 #include "winhkhnd.h"
12 #include "winpe.h"
13 #include "crc32.h"
14 
15 
16 static INTSTATUS
18  _In_ WIN_UNEXPORTED_FUNCTION *Patterns,
19  _In_ QWORD ModuleBase,
20  _In_ BOOLEAN IgnoreSectionHint,
21  _Out_ DWORD *FunctionRva
22  )
42 {
44 
45  for (DWORD i = 0; i < Patterns->PatternsCount; ++i)
46  {
47  WIN_UNEXPORTED_FUNCTION_PATTERN *pPattern = &Patterns->Patterns[i];
48 
49  if (ModuleBase == gGuest.KernelVa)
50  {
53  pPattern,
54  IgnoreSectionHint,
55  FunctionRva);
56  }
57  else
58  {
59  status = IntPeFindFunctionByPattern(ModuleBase,
60  pPattern,
61  IgnoreSectionHint,
62  FunctionRva);
63  }
64 
65  if (INT_SUCCESS(status))
66  {
67  break;
68  }
69  }
70 
71  return status;
72 }
73 
74 
75 static INTSTATUS
77  _In_ API_HOOK_DESCRIPTOR *HookDescriptor
78  )
92 {
94  PAPI_HOOK_HANDLER pHandler = NULL;
95  DWORD functionRva = 0;
96  QWORD functionRip = 0;
97  QWORD moduleBase = 0;
98  DWORD i = 0;
99 
100  if (NULL == HookDescriptor)
101  {
103  }
104 
105  if (0 == wstrcasecmp(u"ntoskrnl.exe", HookDescriptor->ModuleName))
106  {
107  moduleBase = gGuest.KernelVa;
108  }
109  else
110  {
111  KERNEL_DRIVER *pDriver = IntDriverFindByName(HookDescriptor->ModuleName);
112  if (NULL == pDriver)
113  {
114  ERROR("[ERROR] IntDriverFindByName failed for %s: 0x%x\n",
115  utf16_for_log(HookDescriptor->ModuleName), status);
116  return status;
117  }
118 
119  moduleBase = pDriver->BaseVa;
120  }
121 
122  if (HookDescriptor->Exported)
123  {
124  // Function exported, parse the exports and get the RVA.
125  if (moduleBase == gGuest.KernelVa)
126  {
127  QWORD functionGva;
128 
129  status = IntPeFindKernelExport(HookDescriptor->FunctionName, &functionGva);
130 
131  functionRva = (DWORD)(functionGva - gGuest.KernelVa);
132  }
133  else
134  {
135  status = IntPeFindExportByName(moduleBase, NULL, HookDescriptor->FunctionName, &functionRva);
136  }
137  }
138  else
139  {
140  if (NULL == HookDescriptor->Patterns)
141  {
142  TRACE("[INFO] No patterns given for %s, we won't hook\n", HookDescriptor->FunctionName);
144  }
145 
146  status = IntWinApiFindFunctionRva(HookDescriptor->Patterns,
147  moduleBase,
148  FALSE,
149  &functionRva);
150 
151  // If we failed to find any pattern for the given routine, retry the search ignoring
152  // OS version or section hint restrictions.
153  if (!INT_SUCCESS(status))
154  {
155  WARNING("[WARNING] Failed to find '%s', will try again, ignoring section hint\n",
156  HookDescriptor->FunctionName);
157  status = IntWinApiFindFunctionRva(HookDescriptor->Patterns,
158  moduleBase,
159  TRUE,
160  &functionRva);
161  }
162  }
163  if (!INT_SUCCESS(status))
164  {
165  ERROR("[ERROR] Function '%s' not found inside module '%s': 0x%08x\n",
166  HookDescriptor->FunctionName, utf16_for_log(HookDescriptor->ModuleName), status);
167  return status;
168  }
169 
170  functionRip = functionRva + moduleBase;
171 
172  TRACE("[DETOUR] Found function '%s' @ 0x%016llx inside module '%s'\n",
173  HookDescriptor->FunctionName, functionRip, utf16_for_log(HookDescriptor->ModuleName));
174 
175  // Find a proper handler for this function.
176  pHandler = NULL;
177 
178  for (i = 0; i < HookDescriptor->HandlersCount; i++)
179  {
180  pHandler = &HookDescriptor->Handlers[i];
181 
182  if ((gGuest.OSVersion >= pHandler->MinVersion) && (gGuest.OSVersion <= pHandler->MaxVersion))
183  {
184  break;
185  }
186 
187  pHandler = NULL;
188  }
189 
190  if (NULL != pHandler)
191  {
192  status = IntDetSetHook(functionRip, moduleBase, HookDescriptor, pHandler);
193  if (!INT_SUCCESS(status))
194  {
195  ERROR("[ERROR] IntDetSetHook failed: 0x%08x\n", status);
196  }
197  }
198  else
199  {
200  ERROR("[DETOUR] Valid handler not found for %s!\n", HookDescriptor->FunctionName);
201  status = INT_STATUS_NOT_FOUND;
202  }
203 
204  return status;
205 }
206 
207 
208 INTSTATUS
210  void
211  )
217 {
218  INTSTATUS status = INT_STATUS_SUCCESS, failStatus;
219  API_HOOK_DESCRIPTOR *pDescrs = NULL;
220  size_t count = 0;
221  BOOLEAN shouldFail;
222 
223  if (gGuest.Guest64)
224  {
225  pDescrs = gHookableApisX64;
226  count = gHookableApisX64Size;
227  }
228  else
229  {
230  pDescrs = gHookableApisX86;
231  count = gHookableApisX86Size;
232  }
233 
234  TRACE("[DETOUR] Establishing API hooks...\n");
235 
236  shouldFail = FALSE;
237  failStatus = INT_STATUS_NOT_FOUND;
238 
239  for (size_t i = 0; i < count; i++)
240  {
241  if ((gGuest.OSVersion < pDescrs[i].MinVersion) || (gGuest.OSVersion > pDescrs[i].MaxVersion))
242  {
243  LOG("[DETOUR] API function hook on %s is not enabled for this OS: %d - %d/%d\n",
244  pDescrs[i].FunctionName, pDescrs[i].MinVersion, pDescrs[i].MaxVersion, gGuest.OSVersion);
245  continue;
246  }
247 
248  status = IntWinApiHook(&pDescrs[i]);
249  if (!INT_SUCCESS(status))
250  {
251  if (!pDescrs[i].NotCritical)
252  {
253  ERROR("[ERROR] Failed to hook Critical API %s, will search the others and abort!\n",
254  pDescrs[i].FunctionName);
255  shouldFail = TRUE;
256  failStatus = status;
257  }
258  else
259  {
260  WARNING("[WARNING] Failed to hook non Critical API %s, will ignore\n", pDescrs[i].FunctionName);
261  }
262  }
263 
264  if (NULL != pDescrs[i].Patterns)
265  {
266  HpFreeAndNullWithTag(&pDescrs[i].Patterns, IC_TAG_CAMI);
267  }
268  }
269 
270  if (shouldFail)
271  {
272  if ((failStatus == INT_STATUS_PAGE_NOT_PRESENT) || (failStatus == INT_STATUS_NO_MAPPING_STRUCTURES))
273  {
274  // This allows us to retry initialization.
276  }
277  else
278  {
279  // No way we can init, we didn't find all the functions.
281 
283  }
284 
285  return failStatus;
286  }
287 
288  TRACE("[DETOUR] Done establishing API hooks!\n");
289 
291 
292  return INT_STATUS_SUCCESS;
293 }
294 
295 
296 void
298  void
299  )
304 {
305  const API_HOOK_DESCRIPTOR *pDescrs = NULL;
306  size_t count = 0;
307 
308  if (gGuest.Guest64)
309  {
310  pDescrs = gHookableApisX64;
311  count = gHookableApisX64Size;
312  }
313  else
314  {
315  pDescrs = gHookableApisX86;
316  count = gHookableApisX86Size;
317  }
318 
319  for (size_t i = 0; i < count; i++)
320  {
321  // Most of the detours can't be disabled, ever, because we'd lose quite a bit of the guest's state.
322  if (pDescrs[i].EnableFlags == DETOUR_ENABLE_ALWAYS)
323  {
324  continue;
325  }
326 
327  if ((0 == (pDescrs[i].EnableFlags & gGuest.CoreOptions.Current)) ||
328  (0 != (pDescrs[i].DisableFlags & gGuest.CoreOptions.Current)))
329  {
330  TRACE("[DETOUR] Disabling detour on function '%s' according to new options: %llx!\n",
331  pDescrs[i].FunctionName, gGuest.CoreOptions.Current);
332 
333  IntDetDisableDetour(pDescrs[i].Tag);
334  }
335  else
336  {
337  TRACE("[DETOUR] Enabling detour on function '%s' according to new options: %llx!\n",
338  pDescrs[i].FunctionName, gGuest.CoreOptions.Current);
339 
340  IntDetEnableDetour(pDescrs[i].Tag);
341  }
342  }
343 }
344 
345 
346 INTSTATUS
348  _In_ QWORD NewHandler,
349  _Out_ void **Cloak,
350  _Out_opt_ QWORD *OldHandler,
351  _Out_opt_ DWORD *ReplacedCodeLen,
352  _Out_writes_to_(38, *ReplacedCodeLen) BYTE *ReplacedCode
353  )
386 {
387  INTSTATUS status;
388  QWORD vehnd;
389  DWORD codelen, iidx;
390  INSTRUX ix;
391 
393 #define MIN_CODE_LEN 24
394  BYTE newcode[64], oldcode[64];
395 
396  vehnd = 0;
397 
398  // Note: interrupt 20 should not be called in any way, so it's safe to hook it like this, without employing
399  // thread safeness and without using single instructions.
400 
401  // Get the INT 20 entry.
402  status = IntIdtGetEntry(IG_CURRENT_VCPU, 20, &vehnd);
403  if (!INT_SUCCESS(status))
404  {
405  ERROR("[ERROR] IntIdtGetEntry failed: 0x%08x\n", status);
406  goto cleanup_and_exit;
407  }
408 
409  LOG("[VECORE] Original #VE handler at %llx...\n", vehnd);
410 
411  // Special handling for older Windows versions, where the #VE handler was considered an unexpected exception.
412  status = IntDecDecodeInstruction(IG_CS_TYPE_64B, vehnd, &ix);
413  if (!INT_SUCCESS(status))
414  {
415  ERROR("[ERROR] IntDecDecodeInstruction failed: 0x%08x\n", status);
416  goto cleanup_and_exit;
417  }
418 
419  // If the first instruction of the IDT handler is a "PUSH 0x14", this means we have an older Windows version on
420  // out hand, a version which is not aware of the VirtualizationException.
421  // These versions are: 7, 8, 8.1, TH1, TH2, RS1 and RS2
422  // On these, there are 2 cases:
423  // KPTI on - "PUSH 0x14/JMP KiIsrThunkShadow"
424  // KPTI off - "PUSH 0x14/PUSH rbp/JMP KiUnexpectedInterrupt"
425  // We search the JMP, which directs us to the effective handler.
426  if (ix.Instruction == ND_INS_PUSH && ix.Operands[0].Type == ND_OP_IMM && ix.Operands[0].Info.Immediate.Imm == 0x14)
427  {
428  for (iidx = 0; iidx < 4; iidx++)
429  {
430  vehnd += ix.Length;
431 
432  status = IntDecDecodeInstruction(IG_CS_TYPE_64B, vehnd, &ix);
433  if (!INT_SUCCESS(status))
434  {
435  ERROR("[ERROR] IntDecDecodeInstruction failed: 0x%08x\n", status);
436  goto cleanup_and_exit;
437  }
438 
439  if (ix.Instruction == ND_INS_JMPNR)
440  {
441  vehnd = vehnd + ix.Length + ix.Operands[0].Info.RelativeOffset.Rel;
442  LOG("[VECORE] KiIsrThunkShadow identified, the handler is at 0x%016llx\n", vehnd);
443  break;
444  }
445  }
446 
447  if (iidx == 4)
448  {
449  ERROR("[ERROR] JMP to the main ISR handler not found!\n");
450  status = INT_STATUS_NOT_FOUND;
451  goto cleanup_and_exit;
452  }
453 
454  iidx = 0;
455  }
456 
457  // If this is with KPTI, search for the real handler, as the IDT entry points to the shadow.
458  if (gGuest.KptiActive)
459  {
460  DWORD i = 0;
461  BOOLEAN bMovcr3 = FALSE;
462 
463  LOG("[VECORE] KPTI enabled, %llx is the shadow handler, searching for the original handler...\n", vehnd);
464 
465  while (i < 128)
466  {
467  // We only work on 64 bit.
468  status = IntDecDecodeInstruction(IG_CS_TYPE_64B, vehnd + i, &ix);
469  if (!INT_SUCCESS(status))
470  {
471  ERROR("[ERROR] IntDecDecodeInstruction failed: 0x%08x\n", status);
472  goto cleanup_and_exit;
473  }
474 
475  if ((ix.Instruction == ND_INS_MOV_CR) && ND_IS_OP_REG(&ix.Operands[0], ND_REG_CR, 8, NDR_CR3))
476  {
477  bMovcr3 = TRUE;
478  }
479 
480  if ((ix.Instruction == ND_INS_JMPNR) && (bMovcr3))
481  {
482  vehnd = vehnd + i + ix.Length + ix.Operands[0].Info.RelativeOffset.Rel;
483  break;
484  }
485 
486  i += ix.Length;
487  }
488  }
489 
490  LOG("[VECORE] Found the real #VE handler at %llx...\n", vehnd);
491 
492  LOG("[VECORE] The new #VE handler will be at %llx...\n", NewHandler);
493 
494  // Read the old code.
495  status = IntKernVirtMemRead(vehnd, sizeof(oldcode), oldcode, NULL);
496  if (!INT_SUCCESS(status))
497  {
498  ERROR("[ERROR] IntKernVirtMemRead failed: 0x%08x\n", status);
499  goto cleanup_and_exit;
500  }
501 
502  codelen = 0;
503  while (codelen < MIN_CODE_LEN)
504  {
505  INSTRUX instrux;
506  NDSTATUS ndstat;
507 
508  ndstat = NdDecodeEx(&instrux, oldcode + codelen, sizeof(oldcode) - codelen, ND_CODE_64, ND_DATA_64);
509  if (!ND_SUCCESS(ndstat))
510  {
511  ERROR("[ERROR] NdDecodeEx failed: 0x%08x\n", ndstat);
513  }
514 
515  codelen += instrux.Length;
516  }
517 
518  // Hook the original #VE handler and make it point to our handler.
519  // The sequence is: PUSH 2 byte chunks from the new VE handler, than ret to it.
520  iidx = 0;
521 
522  // IMPORTANT: In order to mitigate RSB Spectre, we will first do a relative CALL, in order to make sure the RET
523  // misprediction goes to some code controlled by us. This is basically a retpoline of sorts.
524 
525  // CALL $+4
526  newcode[iidx++] = 0xE8;
527  newcode[iidx++] = 0x03;
528  newcode[iidx++] = 0x00;
529  newcode[iidx++] = 0x00;
530  newcode[iidx++] = 0x00;
531 
532  // LFENCE
533  newcode[iidx++] = 0x0F;
534  newcode[iidx++] = 0xAE;
535  newcode[iidx++] = 0xE8;
536 
537  // MOV dword [rsp], NewHandle low
538  newcode[iidx++] = 0xC7;
539  newcode[iidx++] = 0x04;
540  newcode[iidx++] = 0x24;
541  newcode[iidx++] = (NewHandler >> 0) & 0xFF;
542  newcode[iidx++] = (NewHandler >> 8) & 0xFF;
543  newcode[iidx++] = (NewHandler >> 16) & 0xFF;
544  newcode[iidx++] = (NewHandler >> 24) & 0xFF;
545 
546  // MOV dword [rsp + 4], NewHandle high
547  newcode[iidx++] = 0xC7;
548  newcode[iidx++] = 0x44;
549  newcode[iidx++] = 0x24;
550  newcode[iidx++] = 0x04;
551  newcode[iidx++] = (NewHandler >> 32) & 0xFF;
552  newcode[iidx++] = (NewHandler >> 40) & 0xFF;
553  newcode[iidx++] = (NewHandler >> 48) & 0xFF;
554  newcode[iidx++] = (NewHandler >> 56) & 0xFF;
555 
556  newcode[iidx++] = 0xC3;
557 
558  // Fill in the gap with NOPs.
559  for (DWORD i = iidx; i < codelen; i++)
560  {
561  newcode[i] = 0x90;
562  }
563 
564  status = IntMemClkCloakRegion(vehnd, 0, codelen, MEMCLOAK_OPT_APPLY_PATCH, oldcode, newcode, NULL, Cloak);
565  if (!INT_SUCCESS(status))
566  {
567  ERROR("[ERROR] IntMemClkCloakRegion failed: 0x%08x\n", status);
568  goto cleanup_and_exit;
569  }
570 
571  if (NULL != OldHandler)
572  {
573  *OldHandler = vehnd;
574  }
575 
576  if (NULL != ReplacedCodeLen)
577  {
578  *ReplacedCodeLen = codelen;
579  }
580 
581  if (NULL != ReplacedCode)
582  {
583  memcpy(ReplacedCode, oldcode, codelen);
584  }
585 
586  status = INT_STATUS_SUCCESS;
587 
588 cleanup_and_exit:
589 
590  return status;
591 }
592 
593 
594 INTSTATUS
596  _In_ WIN_UNEXPORTED_FUNCTION *Function,
597  _In_ DWORD ArgumentsCount,
598  _In_ const DWORD *Arguments
599  )
610 {
611  API_HOOK_DESCRIPTOR *pDescrs;
612  size_t count;
613 
614  if (NULL == Function)
615  {
617  }
618 
619  if (gGuest.Guest64)
620  {
621  pDescrs = gHookableApisX64;
622  count = gHookableApisX64Size;
623  }
624  else
625  {
626  pDescrs = gHookableApisX86;
627  count = gHookableApisX86Size;
628  }
629 
630  for (size_t i = 0; i < count; i++)
631  {
632  DWORD crc32 = Crc32String(pDescrs[i].FunctionName, INITIAL_CRC_VALUE);
633  if ((crc32 == Function->NameHash) &&
634  (gGuest.OSVersion >= pDescrs[i].MinVersion) && (gGuest.OSVersion <= pDescrs[i].MaxVersion))
635  {
636  pDescrs[i].Patterns = Function;
637  if (0 != ArgumentsCount) // If no arguments are given, leave the default ones.
638  {
639  pDescrs[i].Arguments.Argc = MIN(ArgumentsCount, ARRAYSIZE(pDescrs[i].Arguments.Argv));
640  memcpy(pDescrs[i].Arguments.Argv, Arguments,
641  sizeof(pDescrs[i].Arguments.Argv[0]) * pDescrs[i].Arguments.Argc);
642  }
643 
644  return INT_STATUS_SUCCESS;
645  }
646  }
647 
648  return INT_STATUS_NOT_FOUND;
649 }
650 
#define INT_STATUS_PAGE_NOT_PRESENT
Indicates that a virtual address is not present.
Definition: introstatus.h:438
#define DETOUR_ENABLE_ALWAYS
Can be used as the API_HOOK_DESCRIPTOR.EnableFlags to always enable the detour.
Definition: detours.h:425
#define _Out_
Definition: intro_sal.h:22
_Bool BOOLEAN
Definition: intro_types.h:58
INTSTATUS IntDetEnableDetour(DETOUR_TAG Tag)
Enables a detour based on its tag.
Definition: detours.c:359
void IntGuestSetIntroErrorState(INTRO_ERROR_STATE State, INTRO_ERROR_CONTEXT *Context)
Updates the value of the gErrorState and the value of the gErrorStateContext.
Definition: guests.c:88
#define IC_TAG_CAMI
Live update allocations.
Definition: memtags.h:122
static INTSTATUS IntWinApiHook(API_HOOK_DESCRIPTOR *HookDescriptor)
Will hook one function from a module as described by the HookDescriptor.
Definition: winapi.c:76
Windows detour descriptors.
DWORD Argc
The number of valid entries inside the Argv array.
Definition: detours.h:110
uint8_t BYTE
Definition: intro_types.h:47
WINDOWS_GUEST * gWinGuest
Global variable holding the state of a Windows guest.
Definition: winguest.c:35
INTSTATUS IntIdtGetEntry(DWORD CpuNumber, DWORD Entry, QWORD *Handler)
Get the handler of an interrupt from the IDT.
Definition: introcpu.c:145
#define _In_
Definition: intro_sal.h:21
INTSTATUS IntPeFindKernelExport(const char *Name, QWORD *ExportGva)
Find an export inside the NT kernel image.
Definition: winpe.c:1723
#define INT_STATUS_SUCCESS
Definition: introstatus.h:54
DWORD MaxVersion
The maximum version of the OS for which this handler works.
Definition: detours.h:288
A critical API function was not found inside the guest kernel.
Definition: intro_types.h:2276
INTSTATUS IntPeFindFunctionByPattern(QWORD ImageBase, WIN_UNEXPORTED_FUNCTION_PATTERN *Pattern, BOOLEAN IgnoreSectionHint, DWORD *Rva)
Find a function using a pattern.
Definition: winpe.c:3118
Described a detour handler.
Definition: detours.h:279
INTSTATUS IntPeFindExportByName(QWORD ImageBase, BYTE *ImageBaseBuffer, CHAR *Name, DWORD *ExportRva)
Find the export name a Rva lies in.
Definition: winpe.c:1758
DWORD MinVersion
The minimum version of the OS for which this handler works.
Definition: detours.h:284
QWORD BaseVa
The guest virtual address of the kernel module that owns this driver object.
Definition: drivers.h:41
INTSTATUS IntWinApiUpdateHookDescriptor(WIN_UNEXPORTED_FUNCTION *Function, DWORD ArgumentsCount, const DWORD *Arguments)
Update a hook descriptor with corresponding function patterns and argument list from CAMI...
Definition: winapi.c:595
#define INT_SUCCESS(Status)
Definition: introstatus.h:42
A critical structure was not found inside the guest kernel.
Definition: intro_types.h:2278
#define ARRAYSIZE(A)
Definition: introdefs.h:101
#define INT_STATUS_NOT_NEEDED_HINT
Definition: introstatus.h:317
#define ERROR(fmt,...)
Definition: glue.h:62
INTSTATUS IntPeFindFunctionByPatternInBuffer(BYTE *Buffer, DWORD BufferSize, WIN_UNEXPORTED_FUNCTION_PATTERN *Pattern, BOOLEAN IgnoreSectionHint, DWORD *Rva)
Find a function using a pattern.
Definition: winpe.c:3012
int INTSTATUS
The status data type.
Definition: introstatus.h:24
DWORD OSVersion
Os version.
Definition: guests.h:277
#define INT_STATUS_NOT_FOUND
Definition: introstatus.h:284
const size_t gHookableApisX86Size
The number of functions to be hooked for 32-bit Windows guests.
Definition: winhkhnd.c:1584
QWORD DisableFlags
Core activation and protection flags that will cause introcore to skip this hook. ...
Definition: detours.h:363
#define MIN(a, b)
Definition: introdefs.h:146
Will write the contents of the patched data inside the guest.
Definition: memcloak.h:54
Describes a pattern for a kernel function that is not exported.
Definition: winguest.h:84
DWORD MaxVersion
The maximum OS version for which this hook should be applied.
Definition: detours.h:341
#define LOG(fmt,...)
Definition: glue.h:61
Describes a kernel driver.
Definition: drivers.h:30
KERNEL_DRIVER * IntDriverFindByName(const void *Name)
Searches for a driver by its name.
Definition: drivers.c:266
BOOLEAN KptiActive
True if KPTI is enabled on this guest, False if it is not.
Definition: guests.h:287
DETOUR_ARGS Arguments
Encoding of the arguments needed by introcore from the hooked function.
Definition: detours.h:375
#define _Out_opt_
Definition: intro_sal.h:30
#define INITIAL_CRC_VALUE
Definition: introdefs.h:221
#define IG_CURRENT_VCPU
For APIs that take a VCPU number as a parameter, this can be used to specify that the current VCPU sh...
Definition: glueiface.h:324
DWORD Argv[DET_ARGS_MAX]
Argument encoding. See DET_ARG_REGS and DET_ARG_ON_STACK.
Definition: detours.h:111
#define INT_STATUS_UNSUCCESSFUL
Definition: introstatus.h:335
const size_t gHookableApisX64Size
The number of functions to be hooked for 64-bit Windows guests.
Definition: winhkhnd.c:4526
BOOLEAN Guest64
True if this is a 64-bit guest, False if it is a 32-bit guest.
Definition: guests.h:286
unsigned long long QWORD
Definition: intro_types.h:53
QWORD Current
The currently used options.
Definition: guests.h:232
#define TRUE
Definition: intro_types.h:30
INTSTATUS IntDetSetHook(QWORD FunctionAddress, QWORD ModuleBase, API_HOOK_DESCRIPTOR *Descriptor, API_HOOK_HANDLER *Handler)
Will inject code inside the guest.
Definition: detours.c:985
#define HpFreeAndNullWithTag(Add, Tag)
Definition: glue.h:517
#define TRACE(fmt,...)
Definition: glue.h:58
INTSTATUS IntMemClkCloakRegion(QWORD VirtualAddress, QWORD Cr3, DWORD Size, DWORD Options, PBYTE OriginalData, PBYTE PatchedData, PFUNC_IntMemCloakWriteHandle WriteHandler, void **CloakHandle)
Hides a memory zone from the guest.
Definition: memcloak.c:548
QWORD KernelVa
The guest virtual address at which the kernel image.
Definition: guests.h:279
#define WARNING(fmt,...)
Definition: glue.h:60
Describes a function that is not exported.
Definition: winguest.h:99
DWORD MinVersion
The minimum OS version for which this hook should be applied.
Definition: detours.h:337
INTSTATUS IntDetDisableDetour(DETOUR_TAG Tag)
Disables a detour based on its tag.
Definition: detours.c:322
#define MIN_CODE_LEN
uint32_t DWORD
Definition: intro_types.h:49
DWORD KernelBufferSize
The size of the KernelBuffer.
Definition: winguest.h:838
INTSTATUS IntWinApiHookAll(void)
Iterates through all hookable APIs and sets requested hooks.
Definition: winapi.c:209
GUEST_STATE gGuest
The current guest state.
Definition: guests.c:48
WIN_UNEXPORTED_FUNCTION * Patterns
Array of code patterns used to find this function.
Definition: detours.h:373
INTSTATUS IntWinApiHookVeHandler(QWORD NewHandler, void **Cloak, QWORD *OldHandler, DWORD *ReplacedCodeLen, BYTE *ReplacedCode)
Hooks the #VE handler.
Definition: winapi.c:347
void IntWinApiUpdateHooks(void)
Iterate through all hookable APIs and enable or disable them according to the current Introcore optio...
Definition: winapi.c:297
int wstrcasecmp(const WCHAR *buf1, const WCHAR *buf2)
Definition: introcrt.c:98
INTSTATUS IntKernVirtMemRead(QWORD KernelGva, DWORD Length, void *Buffer, DWORD *RetLength)
Reads data from a guest kernel virtual memory range.
Definition: introcore.c:674
#define INT_STATUS_NO_MAPPING_STRUCTURES
Indicates that not all mapping structures of a virtual address are present.
Definition: introstatus.h:434
BYTE * KernelBuffer
A buffer containing the entire kernel image.
Definition: winguest.h:837
char * utf16_for_log(const WCHAR *WString)
Converts a UTF-16 to a UTF-8 string to be used inside logging macros.
Definition: introcore.c:2845
#define INT_STATUS_NOT_SUPPORTED
Definition: introstatus.h:287
API_HOOK_DESCRIPTOR gHookableApisX86[]
The functions to be hooked for 32-bit Windows guests.
Definition: winhkhnd.c:61
DWORD Crc32String(const char *String, DWORD InitialCrc)
Computes the CRC for a NULL-terminated utf-8 string.
Definition: crc32.c:200
64-bit selector.
Definition: glueiface.h:188
#define _Out_writes_to_(expr, expr2)
Definition: intro_sal.h:29
BOOLEAN DisableOnReturn
Set to True if after returning from this event handler, introcore must be unloaded.
Definition: guests.h:324
static INTSTATUS IntWinApiFindFunctionRva(WIN_UNEXPORTED_FUNCTION *Patterns, QWORD ModuleBase, BOOLEAN IgnoreSectionHint, DWORD *FunctionRva)
Searches for a function in a module, based on the given patterns.
Definition: winapi.c:17
#define INT_STATUS_INVALID_PARAMETER
Definition: introstatus.h:59
API_HOOK_DESCRIPTOR gHookableApisX64[]
The functions to be hooked for 64-bit Windows guests.
Definition: winhkhnd.c:1590
#define INT_STATUS_INVALID_PARAMETER_2
Definition: introstatus.h:65
INTRO_PROT_OPTIONS CoreOptions
The activation and protection options for this guest.
Definition: guests.h:267
INTSTATUS IntDecDecodeInstruction(IG_CS_TYPE CsType, QWORD Gva, void *Instrux)
Decode an instruction from the provided guest linear address.
Definition: decoder.c:180
Describes a function to be hooked.
Definition: detours.h:325
#define FALSE
Definition: intro_types.h:34