99 list = gHandlers.
Flink;
100 while (list != &gHandlers)
107 (0 == memcmp(Instruction, hnd->
Instruction, Length)))
117 ERROR(
"[ERROR] HpAllocWithTag failed!\n");
157 ERROR(
"[ERROR] IntSlackAlloc failed: 0x%08x\n", status);
166 ERROR(
"[ERROR] IntMemClkCloakRegion failed: 0x%08x\n", status);
221 QWORD secid, seqstart, seqoffset;
223 PBYTE pSectionBuffer = NULL;
263 ERROR(
"[ERROR] The section seems to point outside the kernel image!\n");
265 goto cleanup_and_exit;
277 if (0 != memcmp(pSec->
Name,
".text", 5) && 0 != memcmp(pSec->
Name,
"KVASCODE", 8))
284 memcpy(secname, pSec->
Name, 8);
286 if (0 == memcmp(pSec->
Name,
"KVASCODE", 8))
290 memcpy(&secid, pSec->
Name, 8);
304 TRACE(
"[SWAPGS] Parsing section '%s', virtual-size 0x%08x...\n", secname, pSec->
Misc.
VirtualSize);
308 while (i < pSec->Misc.VirtualSize)
316 ndstatus = NdDecodeEx(&instrux, pSectionBuffer + offset, pSec->
Misc.
VirtualSize - i, ND_CODE_64, ND_DATA_64);
317 if (!ND_SUCCESS(ndstatus))
324 !ND_IS_OP_REG(&instrux.Operands[0], ND_REG_GPR, 8, NDR_RSP))
359 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
360 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
363 LOG(
"[SWAPGS] Found vulnerable sequence at 0x%016llx, offset 0x%llx, context " 364 "%02x %02x %02x %02x %02x %02x %02x %02x\n",
366 pSectionBuffer[seqoffset + 0],
367 pSectionBuffer[seqoffset + 1],
368 pSectionBuffer[seqoffset + 2],
369 pSectionBuffer[seqoffset + 3],
370 pSectionBuffer[seqoffset + 4],
371 pSectionBuffer[seqoffset + 5],
372 pSectionBuffer[seqoffset + 6],
373 pSectionBuffer[seqoffset + 7]
380 ERROR(
"[ERROR] Failed installing a handler!\n");
382 goto cleanup_and_exit;
389 ERROR(
"[ERROR] HpAllocWithTag failed!\n");
391 goto cleanup_and_exit;
397 gadget->
Gla = target;
398 gadget->
Length = instrux.Length;
402 reloffs = (
DWORD)(handler->
Slack - target - 5);
406 call[1] = (reloffs >> 0) & 0xFF;
407 call[2] = (reloffs >> 8) & 0xFF;
408 call[3] = (reloffs >> 16) & 0xFF;
409 call[4] = (reloffs >> 24) & 0xFF;
413 pSectionBuffer + offset,
414 call, NULL, &gadget->
Cloak);
417 ERROR(
"[ERROR] IntMemClkCloakRegion failed: 0x%08x\n", status);
418 goto cleanup_and_exit;
429 TRACE(
"[SWAPGS] Patched %d instructions in section '%s'!\n", count, secname);
457 list = gGadgets.
Flink;
458 while (list != &gGadgets)
465 if (NULL != gadget->
Cloak)
469 gadget->
Cloak = NULL;
477 list = gHandlers.
Flink;
478 while (list != &gHandlers)
484 if (NULL != handler->
Cloak)
488 handler->
Cloak = NULL;
510 list = gGadgets.
Flink;
511 while (list != &gGadgets)
517 if (NULL != gadget->
Cloak)
521 gadget->
Cloak = NULL;
548 list = gHandlers.
Flink;
549 while (list != &gHandlers)
557 WARNING(
"[WARNING] Found %s ptr 0x%016llx in SWAPGS handler: slack addr 0x%016llx, size %x\n",
562 *Gadget = handler->
Slack;
592 list = gGadgets.
Flink;
593 while (list != &gGadgets)
599 if (Ptr > gadget->
Gla && Ptr < gadget->Gla + gadget->
Length)
#define IMAGE_SCN_MEM_EXECUTE
#define CONTAINING_RECORD(List, Type, Member)
struct _IMAGE_FILE_HEADER IMAGE_FILE_HEADER
WINDOWS_GUEST * gWinGuest
Global variable holding the state of a Windows guest.
#define INT_STATUS_SUCCESS
LIST_HEAD gGadgets
List of all the hooked gadgets.
DWORD KernelSize
The size of the kernel.
struct _LIST_ENTRY * Flink
A conditional jump was found.
struct _SWAPGS_HANDLER SWAPGS_HANDLER
#define INT_SUCCESS(Status)
INTSTATUS IntResumeVcpus(void)
Resumes the VCPUs previously paused with IntPauseVcpus.
LIST_HEAD gHandlers
List of all distinct handlers.
INTSTATUS IntSwapgsStartMitigation(void)
Scan the kernel for vulnerable SWAPGS gadgets, and mitigate CVE-2019-1125, when such gadgets are foun...
QWORD Gla
Linear address of the instrumented SWAPGS gadget.
#define INT_STATUS_NOT_NEEDED_HINT
A GS based addressing instruction was found. This is where we start instrumenting.
#define HpAllocWithTag(Len, Tag)
BOOLEAN IntSwapgsIsPtrInHandler(QWORD Ptr, THS_PTR_TYPE Type, QWORD *Gadget)
Check if a pointer points inside a SWAPGS handler.
int INTSTATUS
The status data type.
enum _SWAPGS_SSTATE SWAPGS_SSTATE
BYTE Handler[32]
Handler code.
QWORD IntSwapgsRelocatePtrIfNeeded(QWORD Ptr)
Relocate a pointer if it points inside a SWAPGS gadget, and make it point inside the installed handle...
INTSTATUS IntPauseVcpus(void)
Pauses all the guest VCPUs.
void * Cloak
Cloak handle to the handler.
Will write the contents of the patched data inside the guest.
INTSTATUS IntSlackAlloc(QWORD ModuleBase, BOOLEAN Pageable, DWORD Size, QWORD *Buffer, QWORD SecHint)
Allocate slack inside the guest.
BOOLEAN KptiActive
True if KPTI is enabled on this guest, False if it is not.
BYTE Instruction[16]
The instruction that has been replaced by a jump.
void IntSwapgsUninit(void)
Uninit the SWAPGS mitigation.
SWAPGS_HANDLER * Handler
SWAPGS handler.
static BOOLEAN RemoveEntryList(LIST_ENTRY *Entry)
BOOLEAN Guest64
True if this is a 64-bit guest, False if it is a 32-bit guest.
QWORD Current
The currently used options.
LIST_ENTRY Link
List entry element.
LIST_ENTRY Link
List entry element.
BOOLEAN gMitigated
TRUE if we mitigated the SWAPGS issue.
#define HpFreeAndNullWithTag(Add, Tag)
#define INT_STATUS_INVALID_INTERNAL_STATE
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.
QWORD KernelVa
The guest virtual address at which the kernel image.
INTSTATUS IntIcFlushAddress(PINS_CACHE Cache, QWORD Gva, QWORD Cr3)
Flush entries cached from a given address.
union _IMAGE_SECTION_HEADER::@214 Misc
No state, just started scanning.
static void InsertTailList(LIST_ENTRY *ListHead, LIST_ENTRY *Entry)
BYTE HandlerLength
Handler code length.
void * InstructionCache
The currently used instructions cache.
struct _SWAPGS_GADGET SWAPGS_GADGET
QWORD Section
NT section of the handler.
Measures the instruction search done for the SWAPGS protection.
GUEST_STATE gGuest
The current guest state.
static SWAPGS_HANDLER * IntSwapgsInstallHandler(QWORD Section, BYTE Instruction[16], BYTE Length)
Install a handler for a given instruction.
THS_PTR_TYPE
The type of pointer to be checked.
#define IMAGE_SCN_MEM_DISCARDABLE
The SWAPGS instruction was found.
#define LIST_HEAD_INIT(Name)
BYTE * KernelBuffer
A buffer containing the entire kernel image.
#define INTRO_OPT_PROT_KM_SWAPGS
Enable SWAPGS (CVE-2019-1125) mitigation.
void IntSwapgsDisable(void)
Disable SWAPGS mitigations. Must be used only for PrepareUninit.
#define INT_STATUS_NOT_SUPPORTED
INTSTATUS IntMemClkUncloakRegion(void *CloakHandle, DWORD Options)
Removes a cloak region, making the original memory contents available again to the guest...
UINT8 Name[IMAGE_SIZEOF_SHORT_NAME]
BYTE Length
Length of the instrumented SWAPS gadget.
QWORD Slack
Slack address where the handler has been allocated.
BYTE InstructionLength
Length of the replaced instruction.
#define IMAGE_SCN_MEM_NOT_PAGED
void * Cloak
Cloak handle.
INTRO_PROT_OPTIONS CoreOptions
The activation and protection options for this guest.
UINT16 SizeOfOptionalHeader
#define INT_STATUS_INSUFFICIENT_RESOURCES