Bitdefender Hypervisor Memory Introspection
lixfastread.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 Bitdefender
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 #include "introcore.h"
6 #include "guests.h"
7 #include "introstatus.h"
8 #include "lixguest.h"
9 
10 static QWORD gMappedGva = 0;
11 
12 static BYTE *gMapping1 = NULL;
13 static BYTE *gMapping2 = NULL;
14 
15 
18  _In_ QWORD Gva
19  )
31 {
32  INTSTATUS status;
33 
35  {
37  }
38 
39  if (!IS_KERNEL_POINTER_LIX(Gva))
40  {
41  // We allow only kernel memory.
43  }
44 
45  status = IntVirtMemMap(Gva, PAGE_REMAINING(Gva), gGuest.Mm.SystemCr3, 0, &gMapping1);
46  if (!INT_SUCCESS(status))
47  {
48  ERROR("[ERROR] IntVirtMemMap failed for %llx: %08x\n", Gva, status);
49 
50  gMapping1 = NULL;
51 
52  return status;
53  }
54 
55  gMappedGva = Gva;
56 
57  return INT_STATUS_SUCCESS;
58 }
59 
60 
61 void
63  void
64  )
68 {
69  if (NULL != gMapping1)
70  {
72  }
73 
74  if (NULL != gMapping2)
75  {
77  }
78 
79  gMappedGva = 0;
80 
81  gMapping1 = gMapping2 = NULL;
82 }
83 
84 
87  _In_ QWORD Gva,
88  _In_ DWORD Offset,
89  _In_ DWORD Size,
90  _Out_ void *Buffer
91  )
106 {
107  QWORD gva;
108 
109  if (NULL == gMapping1)
110  {
112  }
113 
114  if (gMappedGva != Gva)
115  {
117  }
118 
119  if (PAGE_COUNT(gMappedGva, Offset + Size) > 2)
120  {
122  }
123 
124  if (NULL == Buffer)
125  {
127  }
128 
129  gva = gMappedGva + Offset;
130 
131  if (PAGE_COUNT(gMappedGva, (QWORD)Offset + Size) > 1)
132  {
133  DWORD remaining = Size;
134 
135  if (NULL == gMapping2)
136  {
137  INTSTATUS status;
138  QWORD secondPage;
139 
140  secondPage = (gMappedGva + PAGE_SIZE) & PAGE_MASK;
141 
142  status = IntVirtMemMap(secondPage, PAGE_SIZE, gGuest.Mm.SystemCr3, 0, &gMapping2);
143  if (!INT_SUCCESS(status))
144  {
145  ERROR("[ERROR] IntVirtMemMap failed for 0x%llx with status 0x%08x", secondPage, status);
146 
147  gMapping2 = NULL;
148 
149  return status;
150  }
151  }
152 
154  {
155  DWORD toRead = PAGE_REMAINING(gva);
156 
157  memcpy(Buffer, gMapping1 + Offset, toRead);
158 
159  remaining -= toRead;
160  }
161 
162  memcpy((BYTE *)Buffer + (Size - remaining), gMapping2 + ((gva + Size - remaining) & PAGE_OFFSET), remaining);
163  }
164  else
165  {
166  // The whole it's in the first page
167  memcpy(Buffer, gMapping1 + Offset, Size);
168  }
169 
170  return INT_STATUS_SUCCESS;
171 }
void IntLixFsrUninitMap(void)
Uninitialize the fast read mechanism.
Definition: lixfastread.c:62
#define _Out_
Definition: intro_sal.h:22
INTSTATUS IntVirtMemUnmap(void **HostPtr)
Unmaps a memory range previously mapped with IntVirtMemMap.
Definition: introcore.c:2234
uint8_t BYTE
Definition: intro_types.h:47
#define _In_
Definition: intro_sal.h:21
QWORD SystemCr3
The Cr3 used to map the kernel.
Definition: guests.h:211
#define INT_STATUS_SUCCESS
Definition: introstatus.h:54
#define PAGE_REMAINING(addr)
Definition: pgtable.h:163
static BYTE * gMapping2
The mapping point of the second page mapped.
Definition: lixfastread.c:13
#define INT_SUCCESS(Status)
Definition: introstatus.h:42
#define PAGE_OFFSET
Definition: pgtable.h:32
#define ERROR(fmt,...)
Definition: glue.h:62
int INTSTATUS
The status data type.
Definition: introstatus.h:24
#define PAGE_COUNT(addr, bytes)
Definition: pgtable.h:189
#define PAGE_FRAME_NUMBER(addr)
Definition: pgtable.h:181
#define INT_STATUS_ALREADY_INITIALIZED
Definition: introstatus.h:263
#define IS_KERNEL_POINTER_LIX(p)
Definition: lixguest.h:11
#define INT_STATUS_NOT_INITIALIZED
Definition: introstatus.h:266
unsigned long long QWORD
Definition: intro_types.h:53
INTSTATUS IntLixFsrInitMap(QWORD Gva)
Initialize the fast read mechanism.
Definition: lixfastread.c:17
#define PAGE_SIZE
Definition: common.h:70
uint32_t DWORD
Definition: intro_types.h:49
__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.
Definition: introcore.c:2134
MM Mm
Guest memory information, such as paging mode, system Cr3 value, etc.
Definition: guests.h:374
GUEST_STATE gGuest
The current guest state.
Definition: guests.c:50
static BYTE * gMapping1
The mapping point of the first page mapped.
Definition: lixfastread.c:12
#define INT_STATUS_INVALID_PARAMETER_1
Definition: introstatus.h:62
static QWORD gMappedGva
The guest virtual address that is currently mapped.
Definition: lixfastread.c:10
INTSTATUS IntLixFsrRead(QWORD Gva, DWORD Offset, DWORD Size, void *Buffer)
Performs a read from a previously mapped guest virtual address.
Definition: lixfastread.c:86
#define INT_STATUS_INVALID_PARAMETER_MIX
Definition: introstatus.h:98
#define PAGE_MASK
Definition: pgtable.h:35
Status values returned by most functions that can signal different success or failure states...
#define INT_STATUS_INVALID_PARAMETER_3
Definition: introstatus.h:68