40 { .
String =
"/lib/x86_64-linux-gnu/", .Length =
CSTRLEN(
"/lib/x86_64-linux-gnu/") },
41 { .String =
"/usr/lib/", .Length =
CSTRLEN(
"/usr/lib/") },
42 { .String =
"/usr/bin/", .Length =
CSTRLEN(
"/usr/bin/") },
43 { .String =
"/usr/", .Length =
CSTRLEN(
"/usr/") },
44 { .String =
"/bin/", .Length =
CSTRLEN(
"/bin/") },
45 { .String =
"/sbin/", .Length =
CSTRLEN(
"/sbin/") },
46 { .String =
"/lib/", .Length =
CSTRLEN(
"/lib/") },
57 #define for_each_dentry(_var_name) list_for_each(gLixDentryCache, DENTRY_PATH, _var_name) 73 for (
DWORD index = 0; index <
ARRAYSIZE(gLixDentryCacheStrings); index++)
75 if (memcmp(gLixDentryCacheStrings[index].String, Path, gLixDentryCacheStrings[index].
Length) == 0)
127 if (pExtDentry->Length == Length && 0 == strcmp(pExtDentry->Path, Path))
129 LOG(
"[LIX-FILES] Update cache for path '%s' with length %d from %llx to %llx\n",
130 pExtDentry->Path, pExtDentry->Length, pExtDentry->Gva, DentryGva);
132 pExtDentry->Gva = DentryGva;
134 return pExtDentry->Path;
140 ERROR(
"[ERROR] The length (0x%x) of the 'd_entry' path exceed the our internal buffer\n", Length);
151 if (NULL == pDentry->
Path)
158 pDentry->
Gva = DentryGva;
160 memcpy(pDentry->
Path, Path, Length);
166 return pDentry->
Path;
184 if (pDentry->Gva == DentryGva)
212 ERROR(
"[ERROR] IntKernVirtMemFetchQword failed with status: 0x%08x\n", status);
218 ERROR(
"[ERROR] The value of the dentry is not a linux-kernel pointer!\n");
256 if (FileName == NULL)
264 ERROR(
"[ERROR] IntKernVirtMemRead failed for GVA 0x%016llx: 0x%08x\n",
265 Dentry +
LIX_FIELD(Dentry, Name), status);
271 ERROR(
"[ERROR] Invalid q_str {%llx; %d} dentry %llx\n", qstr.
Name, qstr.
Length, Dentry);
278 if (NULL == fileName)
286 ERROR(
"[ERROR] IntKernVirtMemRead failed for GVA 0x%016llx: 0x%08x\n", qstr.
Name, status);
291 *FileName = fileName;
295 *NameLength = readLen;
325 ERROR(
"[ERROR] IntKernVirtMemRead failed for GVA 0x%016llx: 0x%08x\n",
326 DentryGva +
LIX_FIELD(Dentry, Name), status);
332 ERROR(
"[ERROR] Invalid q_str length in dentry %llx: %d)\n", DentryGva, qstr.
Length);
339 ERROR(
"[ERROR] IntKernVirtMemRead failed for GVA 0x%016llx: 0x%08x\n", qstr.
Name, status);
343 *(Name + qstr.
Length) = 0;
376 QWORD cacheDentryGva = 0;
377 QWORD crtDentryGva = 0;
378 QWORD parentDentry = 0;
379 QWORD prevHashList = 0;
380 DWORD fileNameLength = 0;
381 DWORD dentryLevel = 0;
400 ERROR(
"[ERROR] IntLixFileGetDentry failed for file %llx: 0x%08x\n", FileStructGva, status);
407 ERROR(
"[ERROR] IntKernVirtMemFetchQword failed for GVA 0x%016llx: 0x%08x\n",
408 crtDentryGva +
LIX_FIELD(Dentry, Parent), status);
415 ERROR(
"[ERROR] IntKernVirtMemFetchQword failed for GVA 0x%016llx: 0x%08x\n",
416 crtDentryGva +
LIX_FIELD(Dentry, HashList) +
sizeof(
QWORD), status);
420 if (!prevHashList && crtDentryGva == parentDentry)
438 ERROR(
"[ERROR] IntLixFileReadDentry failed for dentry @ 0x%016llx : %08x", crtDentryGva, status);
446 index -= fileNameLength;
447 memcpy(
gLixPath + index, tmpOutput, fileNameLength);
455 ERROR(
"[ERROR] IntKernVirtMemFetchQword failed for GVA 0x%016llx: 0x%08x\n",
456 crtDentryGva +
LIX_FIELD(Dentry, Parent), status);
465 cacheDentryGva = crtDentryGva;
469 QWORD dentryParentGva = 0;
470 DWORD crtNameLength = 0;
481 ERROR(
"[ERROR] IntLixFileReadDentry failed for dentry @ 0x%016llx : %08x", crtDentryGva, status);
488 ERROR(
"[ERROR] IntKernVirtMemFetchQword failed for GVA 0x%016llx: 0x%08x\n",
489 crtDentryGva +
LIX_FIELD(Dentry, Parent), status);
494 index -= crtNameLength;
497 ERROR(
"[ERROR] Path for file 0x%llx is too big\n", FileStructGva);
501 memcpy(
gLixPath + index, tmpOutput, crtNameLength);
502 if (dentryParentGva != crtDentryGva)
518 ERROR(
"[ERROR] Got to a invalid parent %llx in dentry %llx!\n", dentryParentGva, crtDentryGva);
521 else if (dentryParentGva == crtDentryGva)
526 crtDentryGva = dentryParentGva;
534 sizeof(
gLixPath) - index - fileNameLength - 1,
540 INT32 size = index - pDentry->
Length +
sizeof(char);
544 ERROR(
"[ERROR] The length (0x%08x) of the 'd_entry' path underflows the our buffer (0x%08x)\n",
550 index -= pDentry->
Length - 1;
557 *Length =
sizeof(
gLixPath) - index - 1;
593 if (NULL == FileName)
601 ERROR(
"[ERROR] IntLixFileGetDentry failed for file %llx: 0x%08x\n", FileStruct, status);
#define for_each_dentry(_var_name)
#define LIX_MAX_DENTRY_DEPTH
The maximum entries to be parsed.
struct _DENTRY_STRING * PDENTRY_STRING
char * String
The path (string).
#define INT_STATUS_SUCCESS
Describes a path that will be cached.
INTSTATUS IntLixDentryGetName(QWORD Dentry, char **FileName, DWORD *NameLength)
Gets the file-name that corresponds to the provided Dentry (guest virtual address).
#define INT_SUCCESS(Status)
INTSTATUS IntLixFileGetPath(QWORD FileStructGva, char **Path, DWORD *Length)
Gets the path that corresponds to the provided FileStructGva (guest virtual address of the 'struct fi...
#define HpAllocWithTag(Len, Tag)
int INTSTATUS
The status data type.
char * Path
The content of the path (string).
static INTSTATUS IntLixFileReadDentry(QWORD DentryGva, char *Name, DWORD *Length)
Reads the name and the length form 'struct dentry'.
static char gLixPath[PAGE_SIZE]
#define IS_KERNEL_POINTER_LIX(p)
INTSTATUS IntKernVirtMemFetchQword(QWORD GuestVirtualAddress, QWORD *Data)
Reads 8 bytes from the guest kernel memory.
LIST_ENTRY Link
///< List entry element.
static BOOLEAN RemoveEntryList(LIST_ENTRY *Entry)
struct _DENTRY_PATH DENTRY_PATH
Describes an entry from dentry-cache.
static BOOLEAN IntLixFileCachePathIsValid(char *Path)
Verify if the provided path starts with at least one entry from gLixDentryCacheStrings.
#define LIX_FIELD(Structure, Field)
Macro used to access fields inside the LIX_OPAQUE_FIELDS structure.
#define HpFreeAndNullWithTag(Add, Tag)
static LIST_HEAD gLixDentryCache
A list that contains the cached entries.
void IntLixFilesCacheUninit(void)
Removes and frees the entries of the dentry-cache.
static void InsertTailList(LIST_ENTRY *ListHead, LIST_ENTRY *Entry)
DWORD Length
The length of the string.
INTSTATUS IntLixGetFileName(QWORD FileStruct, char **FileName, DWORD *NameLength, QWORD *DentryGva)
Gets the file-name that corresponds to the provided FileStruct (guest virtual address).
#define LIX_MAX_PATH
The maximum length of a dentry-path.
QWORD Name
A pointer to the string.
CHAR * IntLixFileCacheCreateDentryPath(char *Path, DWORD Length, QWORD DentryGva)
Creates a new cache entry and returns the path string from the newly created entry.
INTSTATUS IntLixFileGetDentry(QWORD File, QWORD *Dentry)
Reads the value of the dentry field of the 'struct file'.
DENTRY_PATH * IntLixFileCacheFindDentry(QWORD DentryGva)
Search for an entry that has the provided DentryGva in the gLixDentryCache array. ...
struct _DENTRY_STRING DENTRY_STRING
Describes a path that will be cached.
INTSTATUS IntKernVirtMemRead(QWORD KernelGva, DWORD Length, void *Buffer, DWORD *RetLength)
Reads data from a guest kernel virtual memory range.
struct _DENTRY_PATH * PDENTRY_PATH
#define LIST_HEAD_INIT(Name)
#define INT_STATUS_INVALID_PARAMETER_1
#define INT_STATUS_NOT_SUPPORTED
static DENTRY_STRING gLixDentryCacheStrings[]
An array that contains the paths that will be cached.
Describes a string used for paths by the linux kernel (quick string).
DWORD Length
The length of the path.
Describes an entry from dentry-cache.
#define INT_STATUS_INVALID_PARAMETER_2
QWORD Gva
The guest virtual address of the 'struct dentry'.
#define INT_STATUS_INVALID_DATA_SIZE
#define INT_STATUS_INSUFFICIENT_RESOURCES
DWORD Length
The length of the path.