22 #define REG_GPRV(ctx, reg) (*((&(ctx)->Rax) + (reg))) 23 #define REG_GPRP(ctx, reg) ((&(ctx)->Rax) + (reg)) 41 #define IS_ACCESS_IN_KERNEL_WIN(is64, gla, size) IS_KERNEL_POINTER_WIN((is64), (gla)) && \ 42 IS_KERNEL_POINTER_WIN((is64), (gla) + (size)-1) 43 #define IS_ACCESS_IN_KERNEL_LIX(gla, size) IS_KERNEL_POINTER_LIX((gla)) && \ 51 IS_KERNEL_POINTER_LIX((gla) + (size)-1) 67 #define GET_SIGN(sz, x) ((sz) == 1 ? ((x)&0x80) >> 7 : \ 68 (sz) == 2 ? ((x)&0x8000) >> 15 : \ 69 (sz) == 4 ? ((x)&0x80000000) >> 31 : (x) >> 63) 92 BYTE pfArr[16] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
95 Dst = ND_TRIM(Size, Dst);
96 Src1 = ND_TRIM(Size, Src1);
97 Src2 = ND_TRIM(Size, Src2);
100 if ((pfArr[Dst & 0xF] + pfArr[(Dst >> 4) & 0xF]) % 2 == 0)
138 if ((
FM_SUB == FlagsMode) && (Src1 < Src2))
142 else if ((
FM_ADD == FlagsMode) && (Dst < Src1))
164 else if (
FM_ADD == FlagsMode)
204 BYTE defData, defCode;
205 BYTE code[16] = { 0 };
214 partialFetch =
FALSE;
218 defData = ND_DATA_64;
219 defCode = ND_CODE_64;
223 defData = ND_DATA_32;
224 defCode = ND_CODE_32;
228 defData = ND_DATA_16;
229 defCode = ND_CODE_16;
236 if ((Gva &
PAGE_MASK) != ((Gva + ND_MAX_INSTRUCTION_LENGTH) & PAGE_MASK))
246 goto cleanup_and_leave;
249 memcpy(code, p, size);
261 memcpy(&code[size], p, 16 - size);
262 fetchedBytes += 16 - size;
275 goto cleanup_and_leave;
284 ndstatus = NdDecodeEx(Instrux, code, fetchedBytes, defCode, defData);
285 if ((ND_STATUS_BUFFER_TOO_SMALL == ndstatus) && (partialFetch))
288 goto cleanup_and_leave;
290 else if (!ND_SUCCESS(ndstatus))
293 goto cleanup_and_leave;
310 _In_ size_t BufferSize,
331 BYTE defData, defCode;
350 defData = ND_DATA_64;
351 defCode = ND_CODE_64;
355 defData = ND_DATA_32;
356 defCode = ND_CODE_32;
360 defData = ND_DATA_16;
361 defCode = ND_CODE_16;
368 ndstatus = NdDecodeEx(Instrux, Buffer, BufferSize, defCode, defData);
369 if (!ND_SUCCESS(ndstatus))
372 goto cleanup_and_leave;
388 _Out_ INSTRUX *Instrux
417 if (NULL == Segments)
422 ERROR(
"[ERROR] IntGetSegs failed: 0x%08x\n", status);
433 ERROR(
"[ERROR] IntGetCurrentMode failed: 0x%08x\n", status);
440 ERROR(
"[ERROR] Unsupported CS type: %d\n", csType);
453 _Out_ PINSTRUX Instrux,
491 if (NULL == Registers)
507 ERROR(
"[ERROR] IntGetCurrentMode failed: 0x%08x\n", status);
516 rip = Registers->Rip;
528 ERROR(
"[ERROR] IntGetSegs failed: 0x%08x\n", status);
532 ring = (segs.
SsAr >> 5) & 3;
534 rip = segs.
CsBase + Registers->Rip;
537 cr3 = Registers->Cr3;
555 TRACE(
"[INFO] The page containing the RIP has been swapped out; will retry the instruction.\n");
560 ERROR(
"[ERROR] IntDecDecodeInstructionAt failed: 0x%08x\n", status);
565 if ((0 != (Registers->Cr0 &
CR0_PE)) &&
566 (0 != (Registers->Cr0 &
CR0_PG)) &&
612 WARNING(
"[WARNING] IntIcAddInstruction failed: 0x%08x\n", status);
617 WARNING(
"[WARNING] Cannot cache %s, RIP 0x%016llx, CR3 0x%016llx, as no valid process exists!\n",
618 Instrux->Mnemonic, rip, cr3);
627 else if (NULL != Added)
632 if (NULL != CacheHit)
639 if (NULL != CacheHit)
655 _In_ PINSTRUX Instrux,
656 _In_ PND_OPERAND Operand,
679 accessSize = Operand->Size;
681 if ((0 == accessSize) || (ND_SIZE_UNKNOWN == accessSize))
685 if ((ND_INS_XSAVE == Instrux->Instruction) || (ND_INS_XSAVEC == Instrux->Instruction) ||
686 (ND_INS_XSAVEOPT == Instrux->Instruction) || (ND_INS_XSAVES == Instrux->Instruction) ||
687 (ND_INS_XRSTOR == Instrux->Instruction) || (ND_INS_XRSTORS == Instrux->Instruction))
695 ERROR(
"[ERROR] IntQueryGuestInfo failed: 0x%08x\n", status);
700 if ((ND_INS_FXSAVE == Instrux->Instruction) || (ND_INS_FXRSTOR == Instrux->Instruction))
707 if ((ND_INS_BNDLDX == Instrux->Instruction) || (ND_INS_BNDSTX == Instrux->Instruction))
714 accessSize = (Instrux->DefCode == ND_CODE_64) ? 32 : 16;
717 else if (ND_SIZE_CACHE_LINE == accessSize)
724 *AccessSize = accessSize;
732 _In_ PINSTRUX Instrux,
775 for (i = 0; i < Instrux->OperandsCount; i++)
779 if ((ND_OP_MEM == Instrux->Operands[i].Type) && !!(Instrux->Operands[i].Access.Access & AccessType))
791 _In_ PINSTRUX Instrux,
792 _In_ PND_OPERAND Operand,
815 if (NULL == Registers)
820 ERROR(
"[ERROR] IntGetGprs failed: 0x%08x\n", status);
824 Registers = &gprRegs;
829 if (pOp->Type != ND_OP_MEM)
835 if (pOp->Info.Memory.IsVsib)
837 ERROR(
"[ERROR] VSIB is not supported! Use IntDecComputeVsibLinearAddresses.\n");
845 ERROR(
"[ERROR] IntGetSegs failed with status: 0x%x\n", status);
849 if (pOp->Info.Memory.HasSeg)
851 switch (pOp->Info.Memory.Seg)
882 if (pOp->Info.Memory.IsDirect)
884 gla += pOp->Info.Memory.Disp;
890 if (pOp->Info.Memory.HasBase)
893 QWORD base = ((
PQWORD)&Registers->Rax)[pOp->Info.Memory.Base];
895 base &= ND_SIZE_TO_MASK(pOp->Info.Memory.BaseSize);
901 if (pOp->Info.Memory.HasIndex)
904 QWORD index = ((
PQWORD)&Registers->Rax)[pOp->Info.Memory.Index];
906 index &= ND_SIZE_TO_MASK(pOp->Info.Memory.IndexSize);
908 gla += index * pOp->Info.Memory.Scale;
912 if (pOp->Info.Memory.HasDisp)
914 if (pOp->Info.Memory.HasCompDisp)
916 gla += pOp->Info.Memory.Disp * pOp->Info.Memory.CompDispSize;
920 gla += pOp->Info.Memory.Disp;
925 if (pOp->Info.Memory.IsRipRel)
927 gla += Registers->Rip + Instrux->Length;
931 if (pOp->Info.Memory.IsBitbase)
933 QWORD bitbase, op1size, op2size;
935 if ((Instrux->Operands[1].Type != ND_OP_REG) || (Instrux->Operands[1].Info.Register.Type != ND_REG_GPR))
940 op1size = Instrux->Operands[0].Size;
941 op2size = Instrux->Operands[1].Size;
943 bitbase = ND_SIGN_EX(op2size, ((
QWORD *)&Registers->Rax)[Instrux->Operands[1].Info.Register.Reg]);
945 if (bitbase & (1ULL << 63))
947 gla -= ((~bitbase >> 3) & ~(op1size - 1)) + op1size;
951 gla += (bitbase >> 3) & ~(op1size - 1);
957 if (pOp->Info.Memory.IsStack)
959 if (pOp->Access.Write || pOp->Access.CondWrite)
966 *LinearAddress = gla;
974 _In_ PINSTRUX Instrux,
975 _In_ PND_OPERAND Operand,
1010 if (NULL == Registers)
1015 ERROR(
"[ERROR] IntGetGprs failed: 0x%08x\n", status);
1019 Registers = &gprRegs;
1024 if ((pOp->Type != ND_OP_MEM) || !pOp->Info.Memory.IsVsib)
1033 ERROR(
"[ERROR] IntGetSegs failed with status: 0x%x\n", status);
1038 status =
IntDecGetSseRegValue(XsaveArea, pOp->Info.Memory.Index, pOp->Info.Memory.IndexSize, &indexValue);
1043 ERROR(
"[ERROR] IntDecGetSseRegValue failed: 0x%08x\n", status);
1049 if (indexValue.
Size >
sizeof(vsibindex))
1051 ERROR(
"[ERROR] The index value is too large: %u bytes!\n", indexValue.
Size);
1057 if (pOp->Info.Memory.HasSeg)
1059 switch (pOp->Info.Memory.Seg)
1062 baseseg = segRegs.
EsBase;
1065 baseseg = segRegs.
CsBase;
1068 baseseg = segRegs.
SsBase;
1071 baseseg = segRegs.
DsBase;
1074 baseseg = segRegs.
FsBase;
1077 baseseg = segRegs.
GsBase;
1089 for (i = 0; i < Operand->Info.Memory.Vsib.ElemCount; i++)
1091 QWORD gla = baseseg;
1094 if (pOp->Info.Memory.HasBase)
1097 QWORD base = ((
PQWORD)&Registers->Rax)[pOp->Info.Memory.Base];
1099 base &= ND_SIZE_TO_MASK(pOp->Info.Memory.BaseSize);
1105 if (pOp->Info.Memory.HasIndex)
1110 if (pOp->Info.Memory.Vsib.IndexSize == 4)
1112 index = vsibindex.dindexes[i];
1116 index = vsibindex.qindexes[i];
1119 gla += index * pOp->Info.Memory.Scale;
1123 if (pOp->Info.Memory.HasDisp)
1125 if (pOp->Info.Memory.HasCompDisp)
1127 gla += pOp->Info.Memory.Disp * pOp->Info.Memory.CompDispSize;
1131 gla += pOp->Info.Memory.Disp;
1136 if (pOp->Info.Memory.IsRipRel)
1138 gla += Registers->Rip + Instrux->Length;
1141 LinearAddresses[i] = gla;
1150 _In_ PINSTRUX Instrux,
1168 if (NULL == Instrux)
1173 if (NULL == LinearAddress)
1181 while (i < Instrux->OperandsCount)
1183 if ((Instrux->Operands[i].Type == ND_OP_MEM) && (Instrux->Operands[i].Access.Read ||
1184 Instrux->Operands[i].Access.CondRead))
1192 if (i >= Instrux->OperandsCount)
1203 _In_ PINSTRUX Instrux,
1221 if (NULL == Instrux)
1226 if (NULL == LinearAddress)
1234 while (i < Instrux->OperandsCount)
1236 if ((Instrux->Operands[i].Type == ND_OP_MEM) && (Instrux->Operands[i].Access.Write ||
1237 Instrux->Operands[i].Access.CondWrite))
1245 if (i >= Instrux->OperandsCount)
1256 _In_ PINSTRUX Instrux,
1288 if (NULL == Registers)
1293 ERROR(
"[ERROR] IntGetGprs failed: 0x%08x\n", status);
1300 pOp = &Instrux->Operands[OperandIndex];
1302 if (pOp->Type == ND_OP_MEM)
1308 ERROR(
"[ERROR] IntDecComputeLinearAddress failed: 0x%08x\n", status);
1316 ERROR(
"[ERROR] IntVirtMemSafeWrite failed: 0x%08x\n", status);
1321 if (pOp->Info.Memory.IsStack)
1323 Registers->Rsp -= pOp->Size;
1327 else if (pOp->Type == ND_OP_REG)
1329 if (pOp->Info.Register.Type == ND_REG_GPR)
1333 if ((pOp->Size == ND_SIZE_8BIT) && (ND_ENCM_LEGACY == Instrux->EncMode) && (!Instrux->HasRex) &&
1334 (pOp->Info.Register.Reg >= NDR_RSP))
1336 dst = (
PBYTE) & ((
PQWORD)&Registers->Rax)[pOp->Info.Register.Reg - 4] + 1;
1340 dst = (
PBYTE) & ((
PQWORD)&Registers->Rax)[pOp->Info.Register.Reg];
1343 switch (OpValue->Size)
1346 *dst = OpValue->Value.ByteValues[0];
1349 *((
PWORD)dst) = OpValue->Value.WordValues[0];
1352 *((
PDWORD)dst) = OpValue->Value.DwordValues[0];
1353 *((
PDWORD)(dst + 4)) = 0;
1356 *((
PQWORD)dst) = OpValue->Value.QwordValues[0];
1364 else if (pOp->Info.Register.Type == ND_REG_SSE)
1369 ERROR(
"[ERROR] IntDecSetSseRegValue failed for register %d with size %d: 0x%08x\n",
1370 pOp->Info.Register.Reg, OpValue->Size, status);
1376 ERROR(
"[ERROR] Unsupported register type: %d\n", pOp->Info.Register.Type);
1382 ERROR(
"[ERROR] Unsupported operand type: %d\n", pOp->Type);
1386 if (commitRegs && Commit)
1391 ERROR(
"[ERROR] IntSetGprs failed: 0x%08x\n", status);
1402 _In_ PINSTRUX Instrux,
1430 QWORD opValue[4] = {0xbdbdbad, 0xbdbdbad, 0xbdbdbad, 0xbdbdbad};
1435 if (OperandIndex >= Instrux->OperandsCount)
1440 pOp = &Instrux->Operands[OperandIndex];
1441 opSize = (
BYTE)pOp->Size;
1443 if (opSize >
sizeof(opValue) || 0 == opSize)
1449 if (NULL == Registers)
1454 ERROR(
"[ERROR] IntGetGprs failed: 0x%08x\n", status);
1461 if ((ND_OP_REG == pOp->Type) && (ND_REG_GPR == pOp->Info.Register.Type))
1466 if ((ND_SIZE_8BIT == pOp->Size) && (pOp->Info.Register.Reg >= NDR_RSP) &&
1467 !Instrux->HasRex && (ND_ENCM_LEGACY == Instrux->EncMode))
1469 gprIndex = pOp->Info.Register.Reg - 4;
1471 opValue[0] = ((
PQWORD)&Registers->Rax)[gprIndex];
1472 opValue[0] = (opValue[0] >> 8) & 0xFF;
1476 gprIndex = pOp->Info.Register.Reg;
1478 opValue[0] = ((
PQWORD)&Registers->Rax)[gprIndex];
1481 else if (ND_OP_REG == pOp->Type && ND_REG_SSE == pOp->Info.Register.Type)
1483 status =
IntDecGetSseRegValue(NULL, pOp->Info.Register.Reg, pOp->Info.Register.Size, WrittenValue);
1486 ERROR(
"[ERROR] IntDecGetSseRegValue failed for instruction %s with status: 0x%x\n",
1487 Instrux->Mnemonic, status);
1490 WrittenValue->Size = (
BYTE)Instrux->Operands[OperandIndex].Size;
1493 else if (ND_OP_IMM == pOp->Type)
1495 opValue[0] = pOp->Info.Immediate.Imm;
1497 else if (ND_OP_MEM == pOp->Type)
1499 if (NULL == MemoryValue)
1502 DWORD retLength = 0;
1507 ERROR(
"[ERROR] IntDecComputeLinearAddress failed: 0x%08x\n", status);
1512 status =
IntVirtMemRead(guestVa, opSize, Registers->Cr3, &opValue, &retLength);
1515 WARNING(
"[WARNING] IntVirtMemRead failed for %llx: 0x%x\n", guestVa, status);
1518 if (retLength != (
DWORD)opSize)
1520 WARNING(
"[WARNING] IntVirtMemRead completed with no errors, but the returned size " 1521 "(%d) is not the expected size (%d\n",
1530 opValue[0] = *MemoryValue;
1533 opValue[0] = *(
PWORD)MemoryValue;
1536 opValue[0] = *(
PDWORD)MemoryValue;
1539 opValue[0] = *(
PQWORD)MemoryValue;
1542 memcpy(opValue, MemoryValue, opSize);
1550 ERROR(
"[ERROR] Unsupported operand type %d\n", pOp->Type);
1556 memcpy(WrittenValue->Value.QwordValues, opValue, opSize);
1560 WrittenValue->Value.QwordValues[0] = ND_TRIM(opSize, opValue[0]);
1563 WrittenValue->Size = opSize;
1571 _In_ PINSTRUX Instrux,
1599 if (NULL == Instrux)
1610 if (Instrux->EncMode != ND_ENCM_LEGACY && Instrux->EncMode != ND_ENCM_VEX)
1612 ERROR(
"[ERROR] Unsupported encoding: %02d\n", Instrux->EncMode);
1621 ERROR(
"[ERROR] RIP is not in kernel: 0x%016llx\n", regs->
Rip);
1636 if (ND_ACCESS_READ != (Instrux->MemoryAccess & ND_ACCESS_READ))
1638 ERROR(
"[ERROR] Access is not read: 0x%02x\n", Instrux->MemoryAccess);
1645 ERROR(
"[ERROR] IntGetCurrentRing failed: 0x%08x\n", status);
1652 ERROR(
"[ERROR] Ring is not 0: %d\n", ring);
1656 if (SrcValueBuffer != NULL)
1665 switch (Instrux->Instruction)
1670 DWORD dstSize = Instrux->Operands[0].Size;
1677 ERROR(
"[ERROR] IntGetValueFromOperand failed: 0x%08x\n", status);
1684 finalValue.
Size = dstSize;
1700 ERROR(
"[ERROR] IntGetValueFromOperand failed: 0x%08x\n", status);
1708 ERROR(
"[ERROR] IntGetValueFromOperand failed: 0x%08x\n", status);
1712 if (ND_INS_AND == Instrux->Instruction)
1716 else if (ND_INS_OR == Instrux->Instruction)
1720 else if (ND_INS_XOR == Instrux->Instruction)
1726 ERROR(
"[ERROR] Someone forgot to add a case here? Instruction: %s\n", Instrux->Mnemonic);
1748 DWORD dstSize = Instrux->Operands[0].Size;
1755 ERROR(
"[ERROR] IntGetValueFromOperand failed: 0x%08x\n", status);
1763 finalValue.
Size = dstSize;
1768 case ND_INS_VMOVDQU:
1775 ERROR(
"[ERROR] IntGetValueFromOperand failed: 0x%08x\n", status);
1780 if (ND_ENCM_VEX == Instrux->EncMode)
1784 ND_OPERAND_SIZE maxvl;
1788 ERROR(
"[ERROR] IntDecGetMaxvl failed: 0x%08x\n", status);
1795 finalValue.
Size = maxvl;
1806 ERROR(
"[ERROR] Unsupported instruction: %s!\n", Instrux->Mnemonic);
1821 ERROR(
"[ERROR] IntDecEmulatePageWalk failed for 0x%016llx: 0x%08x\n", gla, status);
1826 regs->
Rip += Instrux->Length;
1830 ERROR(
"[ERROR] IntSetGprs failed: 0x%08x\n", status);
1838 ERROR(
"[ERROR] IntSetValueForOperand failed: 0x%08x\n", status);
1841 regs->
Rip -= Instrux->Length;
1845 ERROR(
"[ERROR] IntSetGprs failed: 0x%08x\n", status);
1862 _In_ PINSTRUX Instrux,
1897 if (NULL == Instrux)
1902 if (NULL == WrittenValue)
1908 if (NULL == Registers)
1913 ERROR(
"[ERROR] IntGetGprs failed: 0x%08x\n", status);
1921 switch (Instrux->Instruction)
1932 WARNING(
"[WARNING] IntGetValueFromOperand failed for instruction %s with status: 0x%x\n",
1933 Instrux->Mnemonic, status);
1944 WARNING(
"[WARNING] IntGetValueFromOperand failed for instruction %s with status: 0x%x\n",
1945 Instrux->Mnemonic, status);
1949 bComputeResult =
TRUE;
1954 if (ND_OP_MEM == Instrux->Operands[1].Type)
1960 WARNING(
"[WARNING] IntGetValueFromOperand failed for instruction %s with status: 0x%x\n",
1961 Instrux->Mnemonic, status);
1971 WARNING(
"[WARNING] IntGetValueFromOperand failed for instruction %s with status: 0x%x\n",
1972 Instrux->Mnemonic, status);
1979 case ND_INS_CMPXCHG:
1988 WARNING(
"[WARNING] IntGetValueFromOperand failed for CMPXCHG (destination operand) with status: 0x%x\n",
2001 WARNING(
"[WARNING] IntGetValueFromOperand failed for CMPXCHG (source operand) with status: 0x%x\n",
2009 writtenValue = value2;
2014 case ND_INS_CMPXCHG8B:
2023 value1.
Value.
QwordValues[0] = ((Registers->Rdx & 0xFFFFFFFF) << 32) | (Registers->Rax & 0xFFFFFFFF);
2029 WARNING(
"[WARNING] IntGetValueFromOperand failed for CMPXCHG8B with status: 0x%x\n", status);
2037 writtenValue.
Value.
QwordValues[0] = ((Registers->Rcx & 0xFFFFFFFF) << 32) | (Registers->Rbx & 0xFFFFFFFF);
2042 writtenValue = value2;
2045 writtenValue.
Size = 8;
2049 case ND_INS_CMPXCHG16B:
2064 WARNING(
"[WARNING] IntGetValueFromOperand failed for CMPXCHG16B with status: 0x%x\n", status);
2072 WrittenValue->Value.QwordValues[0] = Registers->Rcx;
2073 WrittenValue->Value.QwordValues[1] = Registers->Rbx;
2078 WrittenValue->Value.QwordValues[0] = destinationValue.
Value.
QwordValues[0];
2079 WrittenValue->Value.QwordValues[1] = destinationValue.
Value.
QwordValues[1];
2083 WrittenValue->Size = 16;
2109 WARNING(
"[WARNING] IntGetValueFromOperand failed for instruction %s with status: 0x%x\n",
2110 Instrux->Mnemonic, status);
2117 WARNING(
"[WARNING] IntGetValueFromOperand failed for instruction %s with status: 0x%x\n",
2118 Instrux->Mnemonic, status);
2122 bComputeResult =
TRUE;
2127 if (ND_OP_MEM == Instrux->Operands[1].Type)
2133 WARNING(
"[WARNING] IntGetValueFromOperand failed for instruction %s with status: 0x%x\n",
2134 Instrux->Mnemonic, status);
2144 WARNING(
"[WARNING] IntGetValueFromOperand failed for instruction %s with status: 0x%x\n",
2145 Instrux->Mnemonic, status);
2152 WARNING(
"[WARNING] IntGetValueFromOperand failed for instruction %s with status: 0x%x\n",
2153 Instrux->Mnemonic, status);
2157 bComputeResult =
TRUE;
2165 if (3 == Instrux->ExpOperandsCount)
2170 WARNING(
"[WARNING] IntGetValueFromOperand failed for instruction %s with status: 0x%x\n",
2171 Instrux->Mnemonic, status);
2178 WARNING(
"[WARNING] IntGetValueFromOperand failed for instruction %s with status: 0x%x\n",
2179 Instrux->Mnemonic, status);
2188 WARNING(
"[WARNING] IntGetValueFromOperand failed for instruction %s with status: 0x%x\n",
2189 Instrux->Mnemonic, status);
2196 WARNING(
"[WARNING] IntGetValueFromOperand failed for instruction %s with status: 0x%x\n",
2197 Instrux->Mnemonic, status);
2202 bComputeResult =
TRUE;
2211 WARNING(
"[WARNING] IntGetValueFromOperand failed for instruction %s with status: 0x%x\n",
2212 Instrux->Mnemonic, status);
2217 bComputeResult =
TRUE;
2225 WARNING(
"[WARNING] IntGetValueFromOperand failed for instruction %s with status: 0x%x\n",
2226 Instrux->Mnemonic, status);
2238 WARNING(
"[WARNING] IntGetValueFromOperand failed for instruction %s with status: 0x%x\n",
2239 Instrux->Mnemonic, status);
2254 ERROR(
"[ERROR] IntDecComputeLinearAddress failed for %s, operand 0: 0x%x\n", Instrux->Mnemonic, status);
2259 writtenValue.
Size = (
BYTE)Instrux->Operands[0].Size;
2278 ERROR(
"[ERROR] IntGetValueFromOperand failed for MOVUPS with status: 0x%x\n", status);
2292 WARNING(
"[WARNING] IntGetValueFromOperand failed for instruction %s with status: 0x%x\n",
2293 Instrux->Mnemonic, status);
2308 WARNING(
"[WARNING] IntGetValueFromOperand failed for instruction %s with status: 0x%x\n",
2309 Instrux->Mnemonic, status);
2315 WARNING(
"[WARNING] IntGetValueFromOperand failed for instruction %s with status: 0x%x\n",
2316 Instrux->Mnemonic, status);
2321 WrittenValue->Value.QwordValues[0] = destinationValue.
Value.
QwordValues[0];
2322 WrittenValue->Size = 16;
2332 WARNING(
"[WARNING] IntGetValueFromOperand failed for instruction %s with status: 0x%x\n",
2333 Instrux->Mnemonic, status);
2346 WARNING(
"[WARNING] IntGetValueFromOperand failed for instruction %s with status: 0x%x\n",
2347 Instrux->Mnemonic, status);
2353 WARNING(
"[WARNING] IntGetValueFromOperand failed for instruction %s with status: 0x%x\n",
2354 Instrux->Mnemonic, status);
2364 WrittenValue->Size = 16;
2370 WARNING(
"[WARNING] Unsupported instruction: %s\n", Instrux->Mnemonic);
2379 opSize = (
BYTE)Instrux->Operands[0].Size;
2381 switch (Instrux->Instruction)
2385 writtenValue.Value.QwordValues[0] = ND_SIGN_EX(value1.Size, value1.Value.QwordValues[0]);
2391 writtenValue.Value.QwordValues[0] = value1.Value.QwordValues[0] + value2.Value.QwordValues[0];
2396 writtenValue.Value.QwordValues[0] = value1.Value.QwordValues[0] - value2.Value.QwordValues[0];
2400 writtenValue.Value.QwordValues[0] = value1.Value.QwordValues[0] +
2401 value2.Value.QwordValues[0] +
2406 writtenValue.Value.QwordValues[0] = value1.Value.QwordValues[0] -
2407 (value2.Value.QwordValues[0] +
2412 writtenValue.Value.QwordValues[0] = value1.Value.QwordValues[0] * value2.Value.QwordValues[0];
2417 INT64 signedValue1 = (
INT64)value1.Value.QwordValues[0];
2418 INT64 signedValue2 = (
INT64)value2.Value.QwordValues[0];
2420 writtenValue.Value.QwordValues[0] = (
QWORD)(signedValue1 * signedValue2);
2425 if (value2.Value.QwordValues[0] != 0)
2427 writtenValue.Value.QwordValues[0] = value1.Value.QwordValues[0] / value2.Value.QwordValues[0];
2431 writtenValue.Value.QwordValues[0] = 0;
2437 INT64 signedValue1 = (
INT64)value1.Value.QwordValues[0];
2438 INT64 signedValue2 = (
INT64)value2.Value.QwordValues[0];
2440 if (signedValue2 != 0)
2442 writtenValue.Value.QwordValues[0] = (
QWORD)(signedValue1 / signedValue2);
2446 writtenValue.Value.QwordValues[0] = 0;
2452 writtenValue.Value.QwordValues[0] = value1.Value.QwordValues[0] & value2.Value.QwordValues[0];
2456 writtenValue.Value.QwordValues[0] = value1.Value.QwordValues[0] | value2.Value.QwordValues[0];
2460 writtenValue.Value.QwordValues[0] = value1.Value.QwordValues[0] ^ value2.Value.QwordValues[0];
2469 if (ND_SIZE_8BIT == opSize)
2471 count = (
DWORD)((value2.Value.QwordValues[0] & 0x1F) % 9);
2473 else if (ND_SIZE_16BIT == opSize)
2475 count = (
DWORD)((value2.Value.QwordValues[0] & 0x1F) % 17);
2477 else if (ND_SIZE_32BIT == opSize)
2479 count = (
DWORD)(value2.Value.QwordValues[0] & 0x1F);
2481 else if (ND_SIZE_64BIT == opSize)
2483 count = (
DWORD)(value2.Value.QwordValues[0] & 0x3F);
2490 BYTE tempCf = ND_MSB(opSize, value1.Value.QwordValues[0]);
2492 value1.Value.QwordValues[0] = (value1.Value.QwordValues[0] << 1) + cf;
2499 writtenValue = value1;
2509 if (ND_SIZE_8BIT == opSize)
2511 count = (
DWORD)((value2.Value.QwordValues[0] & 0x1F) % 9);
2513 else if (ND_SIZE_16BIT == opSize)
2515 count = (
DWORD)((value2.Value.QwordValues[0] & 0x1F) % 17);
2517 else if (ND_SIZE_32BIT == opSize)
2519 count = (
DWORD)(value2.Value.QwordValues[0] & 0x1F);
2521 else if (ND_SIZE_64BIT == opSize)
2523 count = (
DWORD)(value2.Value.QwordValues[0] & 0x3F);
2530 BYTE tempCf = ND_LSB(opSize, value1.Value.QwordValues[0]);
2532 value1.Value.QwordValues[0] = (value1.Value.QwordValues[0] >> 1) + ((
QWORD)cf << ((opSize * 8) - 1));
2539 writtenValue = value1;
2545 writtenValue.Value.QwordValues[0] = (value1.Value.QwordValues[0] << value2.Value.QwordValues[0]) |
2546 (value1.Value.QwordValues[0] >> ((opSize * 8ull) -
2547 value2.Value.QwordValues[0]));
2552 writtenValue.Value.QwordValues[0] = (value1.Value.QwordValues[0] >> value2.Value.QwordValues[0]) |
2553 (value1.Value.QwordValues[0] << ((opSize * 8ull) -
2554 value2.Value.QwordValues[0]));
2559 writtenValue.Value.QwordValues[0] = (value1.Value.QwordValues[0] | (1ULL << (value2.Value.QwordValues[0] %
2565 writtenValue.Value.QwordValues[0] = (value1.Value.QwordValues[0] & ~(1ULL << (value2.Value.QwordValues[0] %
2571 writtenValue.Value.QwordValues[0] = (value1.Value.QwordValues[0] ^ (1ULL << (value2.Value.QwordValues[0] %
2578 WARNING(
"[WARNING] Unsupported instruction: %s\n", Instrux->Mnemonic);
2582 writtenValue.Size = opSize;
2585 *WrittenValue = writtenValue;
2594 _In_ PINSTRUX Instrux
2615 if (NULL == Instrux)
2623 ERROR(
"[ERROR] IntGetGprs failed: 0x%08x\n", status);
2627 if (ND_INS_PUSH == Instrux->Instruction)
2632 ERROR(
"[ERROR] IntGetValueFromOperand failed: 0x%08x\n", status);
2639 ERROR(
"[ERROR] IntSetValueForOperand failed: 0x%08x\n", status);
2643 else if (ND_INS_MOV == Instrux->Instruction)
2648 ERROR(
"[ERROR] IntGetValueFromOperand failed: 0x%08x\n", status);
2655 ERROR(
"[ERROR] IntSetValueForOperand failed: 0x%08x\n", status);
2666 regs.
Rip += Instrux->Length;
2671 ERROR(
"[ERROR] IntSetGprs failed: 0x%08x\n", status);
2744 QWORD gpa = 0, gla = 0, oldval = 0, newval = 0, actval = 0;
2745 DWORD pto = 0, size = 0;
2752 if (NULL == NewValue)
2762 if (instrux->Operands[0].Type != ND_OP_MEM)
2764 ERROR(
"[ERROR] First operand is not memory for PT instruction, type is %d!\n", instrux->Operands[0].Type);
2768 if (instrux->Operands[0].Size > 8)
2770 ERROR(
"[ERROR] First operand is greater than 8 bytes in size, size is %d!\n", instrux->Operands[0].Size);
2778 size = instrux->Operands[0].Size;
2782 ERROR(
"[ERROR] Access spans outside the page: offset 0x%x, size %d!\n", pto, size);
2790 ERROR(
"[ERROR] IntGpaCacheFetchAndAdd failed for GPA 0x%016llx, GLA 0x%016llx: 0x%08x\n", gpa, gla, status);
2801 oldval = (size == 8) ? *((
QWORD *)(pPage + pto))
2802 : (size == 4) ? *((
DWORD *)(pPage + pto))
2803 : (size == 2) ? *((
WORD *)(pPage + pto))
2804 : *((
BYTE *)(pPage + pto));
2808 switch (instrux->Instruction)
2817 ERROR(
"[ERROR] IntGetValueFromOperand failed: 0x%08x\n", status);
2818 goto cleanup_and_exit;
2827 if (actval != oldval)
2829 goto _retry_emulation;
2842 ERROR(
"[ERROR] IntGetValueFromOperand failed: 0x%08x\n", status);
2843 goto cleanup_and_exit;
2855 ERROR(
"[ERROR] IntSetValueForOperand failed: 0x%08x\n", status);
2856 goto cleanup_and_exit;
2866 if (actval != oldval)
2868 goto _retry_emulation;
2875 case ND_INS_CMPXCHG:
2883 ERROR(
"[ERROR] IntGetValueFromOperand failed: 0x%08x\n", status);
2884 goto cleanup_and_exit;
2889 rax = ND_TRIM(size, shRegs.
Rax);
2908 if ((src.
Size == 4) && (ND_CODE_64 == instrux->DefCode))
2914 memcpy(&shRegs.
Rax, &actval, src.
Size);
2921 case ND_INS_CMPXCHG8B:
2926 edx_eax = ((shRegs.
Rdx & 0xFFFFFFFF) << 32) | (shRegs.
Rax & 0xFFFFFFFF);
2929 newval = ((shRegs.
Rcx & 0xFFFFFFFF) << 32) | (shRegs.
Rbx & 0xFFFFFFFF);
2933 if (actval == edx_eax)
2945 shRegs.
Rdx = (actval >> 32) & 0xFFFFFFFF;
2946 shRegs.
Rax = (actval & 0xFFFFFFFF);
2963 ERROR(
"[ERROR] IntGetValueFromOperand failed: 0x%08x\n", status);
2964 goto cleanup_and_exit;
2984 if (actval != oldval)
2986 goto _retry_emulation;
3003 ERROR(
"[ERROR] IntDecComputeLinearAddress failed: 0x%08x\n", status);
3004 goto cleanup_and_exit;
3010 TRACE(
"[PTEMU] GLA mismatch: 0x%016llx - 0x%016llx, will not emulate.\n", btgla,
gVcpu->
Gla);
3012 goto cleanup_and_exit;
3019 ERROR(
"[ERROR] IntGetValueFromOperand failed: 0x%08x\n", status);
3020 goto cleanup_and_exit;
3024 if (instrux->Operands[1].Type == ND_OP_IMM)
3033 goto cleanup_and_exit;
3053 : (ND_INS_BTR == instrux->Instruction) ? (dst.
Value.
QwordValues[0] & ~mask)
3063 if (actval != oldval)
3065 goto _retry_emulation;
3074 char text[ND_MIN_BUF_SIZE];
3076 NdToText(instrux, shRegs.
Rip, ND_MIN_BUF_SIZE, text);
3078 ERROR(
"[ERROR] Instruction 0x%016llx:'%s' not supported, writing at GLA %llx, GPA %llx.\n",
3079 shRegs.
Rip, text, gla, gpa);
3081 goto cleanup_and_exit;
3089 shRegs.
Rip += instrux->Length;
3094 ERROR(
"[ERROR] IntSetGprs failed: 0x%08x\n", status);
3111 _In_ PINSTRUX Instrux,
3131 if (NULL == Instrux)
3143 for (i = 0; i < Instrux->OperandsCount; i++)
3146 if ((Instrux->Operands[i].Type == ND_OP_MEM) && (!Instrux->Operands[i].Info.Memory.IsShadowStack))
3149 count += Instrux->Operands[i].Info.Memory.IsVsib ? Instrux->Operands[i].Info.Memory.Vsib.ElemCount : 1;
3161 _In_ PINSTRUX Instrux,
3189 if (NULL == Instrux)
3194 if (NULL == Registers)
3212 for (i = 0; i < Instrux->OperandsCount; i++)
3214 if (Instrux->Operands[i].Type == ND_OP_MEM)
3216 if (Instrux->Operands[i].Info.Memory.IsShadowStack)
3221 if (count >= *Count)
3227 if (Instrux->Operands[i].Info.Memory.IsVsib)
3230 QWORD vsibglas[16] = { 0 }, j = 0;
3232 if (Instrux->Operands[i].Info.Memory.Vsib.ElemCount > 16)
3234 ERROR(
"[ERROR] Too many VSIB elements accessed: %d\n",
3235 Instrux->Operands[i].Info.Memory.Vsib.ElemCount);
3240 Registers, XsaveArea, vsibglas);
3243 ERROR(
"[ERROR] IntDecComputeVsibLinearAddresses failed: 0x%08x\n", status);
3247 for (j = 0; j < Instrux->Operands[i].Info.Memory.Vsib.ElemCount; j++)
3249 if (count >= *Count)
3254 Gla[count].Access = Instrux->Operands[i].Access.Access;
3255 Gla[count].Size = Instrux->Operands[i].Info.Memory.Vsib.ElemSize;
3256 Gla[count].Gla = vsibglas[j];
3266 ERROR(
"[ERROR] IntDecComputeLinearAddress failed at op %d: 0x%08x", i, status);
3273 ERROR(
"[ERROR] IntDecDecodeOperandSize failed: 0x%08x\n", status);
3277 Gla[count].Access = Instrux->Operands[i].Access.Access;
3326 if (NULL == XsaveArea)
3332 ERROR(
"[ERROR] IntGetXsaveArea failed: 0x%08x\n", status);
3358 if (ND_SIZE_64BIT == Size)
3361 if (Reg >= ND_MAX_MMX_REGS)
3364 goto cleanup_and_exit;
3369 memcpy(&xsave->
Mm0 + Reg, Value->Value.QwordValues, ND_SIZE_64BIT);
3373 memcpy(Value->Value.QwordValues, &xsave->
Mm0 + Reg, ND_SIZE_64BIT);
3379 if (Reg >= ND_MAX_SSE_REGS)
3382 goto cleanup_and_exit;
3389 goto cleanup_and_exit;
3393 if (ND_SIZE_128BIT <= Size)
3400 memcpy(&xsave->
Xmm0 + Reg, Value->Value.QwordValues, ND_SIZE_128BIT);
3404 memcpy(Value->Value.QwordValues, &xsave->
Xmm0 + Reg, ND_SIZE_128BIT);
3413 if (0 != cpuidregs[1])
3417 memcpy((
PBYTE)xsave + cpuidregs[1] + (Reg - 16) * 64ull,
3418 Value->Value.QwordValues,
3423 memcpy(Value->Value.QwordValues,
3424 (
PBYTE)xsave + cpuidregs[1] + (Reg - 16) * 64ull,
3431 goto cleanup_and_exit;
3437 if (ND_SIZE_256BIT <= Size)
3444 if (0 != cpuidregs[1])
3448 memcpy((
PBYTE)xsave + cpuidregs[1] + Reg * 16ull, Value->Value.ByteValues + 16, ND_SIZE_128BIT);
3452 memcpy(Value->Value.ByteValues + 16, (
PBYTE)xsave + cpuidregs[1] + Reg * 16ull, ND_SIZE_128BIT);
3458 goto cleanup_and_exit;
3466 if (0 != cpuidregs[1])
3470 memcpy((
PBYTE)xsave + cpuidregs[1] + (Reg - 16) * 64ull + 16,
3471 Value->Value.ByteValues + 16, ND_SIZE_128BIT);
3475 memcpy(Value->Value.ByteValues + 16,
3476 (
PBYTE)xsave + cpuidregs[1] + (Reg - 16) * 64ull + 16, ND_SIZE_128BIT);
3482 goto cleanup_and_exit;
3488 if (ND_SIZE_512BIT <= Size)
3495 if (0 != cpuidregs[1])
3499 memcpy((
PBYTE)xsave + cpuidregs[1] + Reg * 32ull, Value->Value.ByteValues + 32, ND_SIZE_256BIT);
3503 memcpy(Value->Value.ByteValues + 32, (
PBYTE)xsave + cpuidregs[1] + Reg * 32ull, ND_SIZE_256BIT);
3509 goto cleanup_and_exit;
3517 if (0 != cpuidregs[1])
3521 memcpy((
PBYTE)xsave + cpuidregs[1] + (Reg - 16) * 64ull + 32,
3522 Value->Value.ByteValues + 32, ND_SIZE_256BIT);
3526 memcpy(Value->Value.ByteValues + 32,
3527 (
PBYTE)xsave + cpuidregs[1] + (Reg - 16) * 64ull + 32, ND_SIZE_256BIT);
3533 goto cleanup_and_exit;
3546 ERROR(
"IntSetXsaveArea failed: 0x%08x\n", status);
3551 if (xsave != XsaveArea)
3637 ERROR(
"[ERROR] IntTranslateVirtualAddressEx failed: 0x%08x\n", status);
3650 ERROR(
"[ERROR] IntPhysMemMap failed for 0x%016llx: 0x%08x\n", tr.
MappingsTrace[i], status);
3673 _Out_ ND_OPERAND_SIZE *Maxvl
3695 *Maxvl = ND_SIZE_512BIT;
3701 *Maxvl = ND_SIZE_256BIT;
3707 *Maxvl = ND_SIZE_128BIT;
#define INT_STATUS_PAGE_NOT_PRESENT
Indicates that a virtual address is not present.
#define DEC_OPT_NO_CACHE
Flag used to hint the instruction decoder to not use the instruction cache.
INTSTATUS IntVirtMemUnmap(void **HostPtr)
Unmaps a memory range previously mapped with IntVirtMemMap.
static INTSTATUS IntDecComputeVsibLinearAddresses(PINSTRUX Instrux, PND_OPERAND Operand, PIG_ARCH_REGS Registers, PIG_XSAVE_AREA XsaveArea, QWORD *LinearAddresses)
Decode VSIB addresses from the given instruction.
INTSTATUS IntDecEmulatePTWrite(QWORD *NewValue)
Emulate a page-table write.
Describes an XSAVE area format.
static int16_t _InterlockedCompareExchange16(int16_t volatile *Destination, int16_t Exchange, int16_t Comparand)
INTSTATUS IntGetXcr0(DWORD CpuNumber, QWORD *Xcr0Value)
Get the value of the guest XCR0 register.
LIX_TASK_OBJECT * IntLixTaskFindByCr3(QWORD Cr3)
Finds the Linux process having the provided Cr3.
BYTE ByteValues[ND_MAX_REGISTER_SIZE]
INTSTATUS IntIcLookupInstruction(PINS_CACHE Cache, PINSTRUX Instrux, QWORD Gva, QWORD Cr3)
Lookup an instruction inside the cache.
IG_ARCH_REGS Regs
The current state of the guest registers.
DWORD Index
The VCPU number.
#define XCR0_AVX_512_STATE
#define INT_STATUS_SUCCESS
INTSTATUS IntDecDecodeInstructionAtRipWithCache(void *Cache, DWORD CpuNumber, PIG_ARCH_REGS Registers, PINSTRUX Instrux, DWORD Options, BOOLEAN *CacheHit, BOOLEAN *Added)
Decode an instruction using the cache.
#define PAGE_REMAINING(addr)
#define INT_STATUS_DISASM_ERROR
Indicates a decoder error.
INTSTATUS IntGetGprs(DWORD CpuNumber, PIG_ARCH_REGS Regs)
Get the current guest GPR state.
#define IS_ACCESS_IN_KERNEL_LIX(gla, size)
Checks if a memory access is done inside the Linux kernel virtual address space.
Describes a memory address, as used in an instruction.
#define INT_SUCCESS(Status)
Holds segment register state.
INTSTATUS IntDecDecodeDestinationLinearAddressFromInstruction(PINSTRUX Instrux, PIG_ARCH_REGS Registers, QWORD *LinearAddress)
Decode the destination memory linear address.
#define PAGE_COUNT_4K(addr, bytes)
int INTSTATUS
The status data type.
#define DEC_GET_FLAG(eflags, flag)
Gets the value of the indicated flag.
INTSTATUS IntDecEmulateRead(PINSTRUX Instrux, BYTE *SrcValueBuffer)
Emulate a read access.
#define INT_STATUS_NOT_FOUND
INTSTATUS IntQueryGuestInfo(DWORD InfoClass, void *InfoParam, void *Buffer, DWORD BufferLength)
static INTSTATUS IntDecDecodeOperandSize(PINSTRUX Instrux, PND_OPERAND Operand, PIG_ARCH_REGS Registers, DWORD *AccessSize)
Decode the size of the given operand.
#define IntFreeXsaveArea(xa)
Frees an XSAVE area.
INTRO_GUEST_TYPE OSType
The type of the guest.
static INTSTATUS IntGetValueFromOperand(PINSTRUX Instrux, DWORD OperandIndex, PIG_ARCH_REGS Registers, PBYTE MemoryValue, OPERAND_VALUE *WrittenValue)
Get the value of an instruction operand.
INSTRUX Instruction
The current instruction, pointed by the guest RIP.
#define _Out_writes_(expr)
#define INT_STATUS_OPERATION_NOT_IMPLEMENTED
INTSTATUS IntDecDecodeSourceLinearAddressFromInstruction(PINSTRUX Instrux, PIG_ARCH_REGS Registers, QWORD *LinearAddress)
Decode the source memory linear address.
INTSTATUS IntDecGetSseRegValue(PIG_XSAVE_AREA XsaveArea, DWORD Reg, DWORD Size, OPERAND_VALUE *Value)
Get the value of a vector register. Wrapper over IntDecGetSetSseRegValue.
INTSTATUS IntDecEmulatePageWalk(QWORD Gla, QWORD Cr3, DWORD Flags)
DWORD AccessSize
The size of the memory access. Valid only for EPT exits.
IG_CS_TYPE
The type of the code segment.
INTSTATUS IntDecComputeLinearAddress(PINSTRUX Instrux, PND_OPERAND Operand, PIG_ARCH_REGS Registers, QWORD *LinearAddress)
Given an instruction and a memory operand, it will compute the guest linear address encoded by that o...
INTSTATUS IntDecDecodeInstructionFromBuffer(PBYTE Buffer, size_t BufferSize, IG_CS_TYPE CsType, void *Instrux)
Decode an instruction from the provided buffer.
DWORD MappingsCount
The number of entries inside the MappingsTrace and MappingsEntries arrays.
INTSTATUS IntGetCurrentMode(DWORD CpuNumber, DWORD *Mode)
Read the current CS type.
INTSTATUS IntGpaCacheRelease(PGPA_CACHE Cache, QWORD Gpa)
Release a previously used cached entry.
static int8_t _InterlockedCompareExchange8(int8_t volatile *Destination, int8_t Exchange, int8_t Comparand)
TIMER_FRIENDLY void IntDumpInstruction(INSTRUX *Instruction, QWORD Rip)
This function dumps a given instruction (textual disassembly).
INTSTATUS IntDecGetMaxvl(ND_OPERAND_SIZE *Maxvl)
Computes the maximum vector length, given the enabled states inside the XCR0 register.
Describes an operand value.
#define IS_KERNEL_POINTER_LIX(p)
QWORD QwordValues[ND_MAX_REGISTER_SIZE/8]
#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...
BOOLEAN PaeEnabled
True if Physical Address Extension is enabled.
INTSTATUS IntDecSetSseRegValue(PIG_XSAVE_AREA XsaveArea, DWORD Reg, DWORD Size, OPERAND_VALUE *Value, BOOLEAN Commit)
Sets the value of a vector register. Wrapper over IntDecGetSetSseRegValue.
__noreturn void IntBugCheck(void)
#define INT_STATUS_UNSUCCESSFUL
BOOLEAN Guest64
True if this is a 64-bit guest, False if it is a 32-bit guest.
static QWORD IntDecAtomicStore(void *Address, DWORD Size, QWORD New, QWORD Old)
Atomically store a value in memory.
void * GpaCache
The currently used GPA cache.
#define INT_STATUS_INVALID_PARAMETER_4
union _OPERAND_VALUE::@22 Value
The actual operand value.
#define IS_KERNEL_POINTER_WIN(is64, p)
Checks if a guest virtual address resides inside the Windows kernel address space.
QWORD Gpa
The accessed guest physical address. Valid only for EPT exits.
INTSTATUS IntDecDecodeAccessSize(PINSTRUX Instrux, PIG_ARCH_REGS Registers, QWORD Gla, BYTE AccessType, DWORD *AccessSize)
Decode the memory access size of a given instruction.
PWIN_PROCESS_OBJECT IntWinProcFindObjectByCr3(QWORD Cr3)
Finds a process by its kernel CR3.
#define INT_STATUS_INVALID_PARAMETER_5
static void __cpuidex(int32_t info[4], int32_t level, int32_t ecx)
INTSTATUS IntTranslateVirtualAddressEx(QWORD Gva, QWORD Cr3, DWORD Flags, VA_TRANSLATION *Translation)
Translates a guest virtual address to a guest physical address.
INTSTATUS IntDecGetAccessedMem(PINSTRUX Instrux, PIG_ARCH_REGS Registers, PIG_XSAVE_AREA XsaveArea, MEMADDR *Gla, DWORD *Count)
Decode each accessed address by an instruction.
DWORD Size
The operand size.
INTSTATUS IntVirtMemSafeWrite(QWORD Cr3, QWORD VirtualAddress, DWORD Size, void *Buffer, DWORD Ring)
Safely modify guest memory.
INTSTATUS IntSetXsaveArea(DWORD CpuNumber, XSAVE_AREA *XsaveArea)
Sets the contents of the guest XSAVE area.
enum @251 INT_FLAGS_MODE
Describes the flags affected by an instruction.
#define UNREFERENCED_PARAMETER(P)
INTSTATUS IntDecDecodeInstructionAtRip(DWORD CpuNumber, IG_ARCH_REGS *Registers, IG_SEG_REGS *Segments, INSTRUX *Instrux)
Decode an instruction at current RIP on the provided VCPU.
#define INT_STATUS_DATA_BUFFER_TOO_SMALL
#define _In_reads_bytes_(expr)
DWORD DwordValues[ND_MAX_REGISTER_SIZE/4]
INTSTATUS IntSetGprs(DWORD CpuNumber, PIG_ARCH_REGS Regs)
Sets the values of the guest GPRs.
__must_check INTSTATUS IntVirtMemMap(QWORD Gva, DWORD Length, QWORD Cr3, DWORD Flags, void **HostPtr)
Maps a guest virtual memory range inside Introcore virtual address space.
INTSTATUS IntDecDecodeInstruction(IG_CS_TYPE CsType, QWORD Gva, void *Instrux)
Decode an instruction from the provided guest linear address.
INTSTATUS IntDecGetAccessedMemCount(PINSTRUX Instrux, DWORD *Count)
Decode the number of memory locations accessed by an instruction.
GUEST_STATE gGuest
The current guest state.
INTSTATUS IntVirtMemRead(QWORD Gva, DWORD Length, QWORD Cr3, void *Buffer, DWORD *RetLength)
Reads data from a guest virtual memory range.
#define _When_(expr, arg)
static int64_t _InterlockedCompareExchange64(int64_t volatile *Destination, int64_t Exchange, int64_t Comparand)
INTSTATUS IntIcAddInstruction(PINS_CACHE Cache, PINSTRUX Instruction, QWORD Gva, QWORD Cr3, BOOLEAN Global)
Adds an instruction to the cache.
Get the size of the guest XSAVE area for a VCPU.
QWORD MappingsTrace[MAX_TRANSLATION_DEPTH]
Contains the physical address of each entry within the translation tables.
INTSTATUS IntGpaCacheFindAndAdd(PGPA_CACHE Cache, QWORD Gpa, void **Hva)
Search for an entry in the GPA cache, and add it, if it wasn't found.
#define INT_STATUS_NO_MAPPING_STRUCTURES
Indicates that not all mapping structures of a virtual address are present.
#define GET_SIGN(sz, x)
Get the sign bit of a value.
__must_check INTSTATUS IntPhysMemMap(QWORD PhysAddress, DWORD Length, DWORD Flags, void **HostPtr)
Maps a guest physical address inside Introcore VA space.
Encapsulates information about a virtual to physical memory translation.
#define INT_STATUS_INVALID_PARAMETER_1
#define INT_STATUS_NOT_SUPPORTED
VCPU_STATE * gVcpu
The state of the current VCPU.
IG_XSAVE_AREA * XsaveArea
The contents of the XSAVE area.
static INTSTATUS IntSetValueForOperand(PINSTRUX Instrux, DWORD OperandIndex, PIG_ARCH_REGS Registers, OPERAND_VALUE *OpValue, BOOLEAN Commit)
Set the value of an instruction operand.
INTSTATUS IntGetSegs(DWORD CpuNumber, PIG_SEG_REGS Regs)
Read the guest segment registers.
INTSTATUS IntGetCurrentRing(DWORD CpuNumber, DWORD *Ring)
Read the current protection level.
#define _Out_writes_to_(expr, expr2)
unsigned long long * PQWORD
static INTSTATUS IntDecGetSetSseRegValue(PIG_XSAVE_AREA XsaveArea, DWORD Reg, DWORD Size, OPERAND_VALUE *Value, BOOLEAN Set, BOOLEAN Commit)
Gets or sets the value of a vector register.
#define IS_ACCESS_IN_KERNEL_WIN(is64, gla, size)
Checks if a memory access is done inside the Windows kernel virtual address space.
INTSTATUS IntPhysMemUnmap(void **HostPtr)
Unmaps an address previously mapped with IntPhysMemMap.
#define INT_STATUS_INVALID_PARAMETER_2
QWORD Gla
The accessed guest virtual address. Valid only for EPT exits.
static void IntDecSetFlags(QWORD Dst, QWORD Src1, QWORD Src2, DWORD Size, PIG_ARCH_REGS Regs, DWORD FlagsMode)
Sets the flags according to the result of an operation.
static int32_t _InterlockedCompareExchange(int32_t volatile *Destination, int32_t Exchange, int32_t Comparand)
INTSTATUS IntGetXsaveArea(DWORD CpuNumber, XSAVE_AREA *XsaveArea)
Get the contents of the guest XSAVE area.
INTSTATUS IntDecGetWrittenValueFromInstruction(PINSTRUX Instrux, PIG_ARCH_REGS Registers, PBYTE MemoryValue, OPERAND_VALUE *WrittenValue)
Decode a written value from a memory write instruction.
#define INT_STATUS_INVALID_PARAMETER_3
INTSTATUS IntDecEmulateInstruction(DWORD CpuNumber, PINSTRUX Instrux)
Emulate a MOV or a PUSH instruction.