Bitdefender Hypervisor Memory Introspection
|
This module manages module and exports caches. More...
#include "winumcache.h"
#include "crc32.h"
#include "guests.h"
#include "swapmem.h"
#include "winpe.h"
#include "winummodule.h"
Go to the source code of this file.
Functions | |
static void | IntWinModCacheExportNodeFree (RBNODE *Node) |
RB tree free function. More... | |
static int | IntWinModCacheExportNodeCompare (RBNODE *Left, RBNODE *Right) |
Compares two RB tree nodes, representing cached exports. More... | |
static int | IntWinModCacheExportNodeCompareWithErorr (RBNODE *Node, void *Key) |
Checks if the provided key is inside the given RB tree node. More... | |
static BOOLEAN | IntWinModCacheFixNamePointers (RBNODE *Node, void *Module) |
Fixes the names, lens and hashes inside the given RB node, provided the info inside the module. More... | |
WINUM_CACHE_EXPORT * | IntWinUmCacheGetExportFromRange (WIN_PROCESS_MODULE *Module, QWORD Gva, DWORD Length) |
Tries to find an export in the range [Gva - Length, Gva]. More... | |
WINUM_CACHE_EXPORT * | IntWinUmModCacheExportFind (WIN_PROCESS_MODULE *Module, DWORD Rva, DWORD ErrorRange) |
Tries to find an export in the range [Rva, Rva + ErrorRange]. More... | |
static INTSTATUS | IntWinModCancelExportTransactions (WINUM_MODULE_CACHE *Cache) |
Cancels all pending swap transactions, in any process, for the provided Cache. More... | |
static INTSTATUS | IntWinModHandleExportsInMemory (void *Context, QWORD Cr3, QWORD VirtualAddress, QWORD PhysicalAddress, void *Data, DWORD DataSize, DWORD Flags) |
Called as soon as the exports section of a module is swapped in. More... | |
static BOOLEAN | IntWinUmModMustCacheExports (DWORD NameHash) |
Checks of the exports of a module need to be cached. More... | |
static WINUM_MODULE_CACHE * | IntWinModCacheCreate (WIN_PROCESS_MODULE *Module) |
Creates an exports cache entry for the provided module. More... | |
static INTSTATUS | IntWinUmModCacheFillExports (WIN_PROCESS_MODULE *Module) |
Fills the exports cache of the provided module with each exported symbol. More... | |
static INTSTATUS | IntWinUmModCacheFillHeaders (WIN_PROCESS_MODULE *Module, BYTE *Headers) |
Fills MZ/PE headers information for the provided module. More... | |
static WINUM_MODULE_CACHE * | IntWinUmModCacheFetch (WIN_PROCESS_MODULE *Module) |
Returns the cache associated with the provided module. More... | |
void | IntWinUmModCacheGet (WIN_PROCESS_MODULE *Module) |
Initializes the cache for the provided module. More... | |
static void | IntWinUmCacheRemoveCache (WINUM_MODULE_CACHE *Cache) |
Removes a module cache. More... | |
void | IntWinUmModCacheRelease (WINUM_MODULE_CACHE *Cache) |
Removes a module cache, if it was written (it's dirty). More... | |
INTSTATUS | IntWinUmModCacheSetHeaders (WIN_PROCESS_MODULE *Module, BYTE *Headers) |
Sets the MZ/PE headers in the cache of a given module. More... | |
BOOLEAN | IntWinUmCacheIsExportDirRead (WIN_PROCESS_MODULE *Module) |
Checks if the exports directory of the given module has been read. More... | |
void | IntWinUmCacheUninit (void) |
Uninit the module cache system. This will remove all cache entries. Use this during Introcore uninit. More... | |
Variables | |
const DWORD | gExportedDirsToCache [] |
LIST_HEAD | gWinProcesses |
The list of all the processes inside the guest. More... | |
LIST_HEAD | gWinUmCaches = LIST_HEAD_INIT(gWinUmCaches) |
This module manages module and exports caches.
Whenever a protected module is loaded, we will create a cache entry representing the module. Inside this cache entry, we will store information regarding the headers and the headers themselves. In addition, we will read and parse all the exports of the indicated module. Note that there is a single cache instance allocated for a given protected module, no matter how many times that module has been loaded, and no matter how many processes have loaded that module. When the first instance of a protected module is loaded, the cache is created and the exports read. Instances loaded after this will simply reference the already existing cache entry. The cache entries will be removed during uninit only. An exception to this mechanism are dirty caches. A cache is considered dirty if it was created from a module loaded by a process that was already created when Introcore was activated. In these cases, we cannot trust the contents of that particular cache, so we will mark it Dirty. Dirty caches are NOT re-used - this means that a Dirty cache is local and private to one module only, and it will be removed when that modules is unloaded. Caches created from freshly created process are NOT dirty, and they can be reused by all subsequent loaded modules.
Definition in file winumcache.c.
|
static |
Creates an exports cache entry for the provided module.
[in] | Module | The module for which the exports cache will be created. |
Definition at line 674 of file winumcache.c.
Referenced by IntWinUmModCacheGet().
Compares two RB tree nodes, representing cached exports.
This function will compare the RVAs of the two WINUM_CACHE_EXPORT structures described by Left and Right.
[in] | Left | The left node. |
[in] | Right | The right node. |
Definition at line 71 of file winumcache.c.
Referenced by IntWinUmModCacheFillExports().
|
static |
Checks if the provided key is inside the given RB tree node.
The function checks if the provided key (first DWORD) is inside the given node, with a limit given by the second DWORD in the key argument. The node is a WINUM_CACHE_EXPORT structure, and the Rva field is used for comparison.
[in] | Node | The RB tree node. |
[in] | Key | A tuple containing two DWORDs: the first DWORD is the value to find, while the second DWORD is the limit within the RB tree node. |
Definition at line 103 of file winumcache.c.
Referenced by IntWinUmModCacheExportFind().
|
static |
RB tree free function.
NOTE: Does nothing.
[in,out] | Node | The RB tree node to be freed. |
Definition at line 55 of file winumcache.c.
Referenced by IntWinUmModCacheFillExports().
Fixes the names, lens and hashes inside the given RB node, provided the info inside the module.
Given Module, it will fix the Names, NameLens and NameHashes inside the WINUM_CACHE_EXPORT structure represented by the the Node argument based on the cache belonging to the module. It will also check if the memory related instructions (memcpy, memset, etc.) have been identified in the ntdll module, in which case the MemoryFuncsRead field inside the exports cache will be set.
[in] | Node | The RB tree node, representing a WINUM_CACHE_EXPORT structure. |
[in] | Module | The module from which the cache will be used to fixup the names. |
Definition at line 141 of file winumcache.c.
Referenced by IntWinModHandleExportsInMemory().
|
static |
Cancels all pending swap transactions, in any process, for the provided Cache.
[in] | Cache | The module cache whose transactions we wish to cancel. |
INT_STATUS_SUCCESS | On success. |
Definition at line 318 of file winumcache.c.
Referenced by IntWinModHandleExportsInMemory().
|
static |
Called as soon as the exports section of a module is swapped in.
This function will initialize the cache structure for the exports of the given module. In addition, it will cancel all existing transactions for this module's exports, since they were already read (the exports are read a single time no matter how many instances of the associated module exist). The exports of the given module will be read and stored in a RB tree structure for easy & fast lookup. NOTE: At most WINUMCACHE_MAX_EXPORTS exports will be cached. This means that if a module has more than WINUMCACHE_MAX_EXPORTS exports, only the first WINUMCACHE_MAX_EXPORTS will be cached.
[in] | Context | The context, representing the WIN_PROCESS_MODULE structure whose exports have just been swapped in. |
[in] | Cr3 | The virtual address space. Will usually be the current Cr3. |
[in] | VirtualAddress | The virtual address that of the first page of the exports. |
[in] | PhysicalAddress | Physical address of the first exports page. |
[in] | Data | Exports data buffer. |
[in] | DataSize | The size of the read data. |
[in] | Flags | Unused. |
INT_STATUS_SUCCESS | On success. |
INT_STATUS_INVALID_OBJECT_TYPE | If any malformation of the PE file or exports directory is detected. |
INT_STATUS_INSUFFICIENT_RESOURCES | If a memory alloc fails. |
Definition at line 375 of file winumcache.c.
Referenced by IntWinUmModCacheFillExports().
WINUM_CACHE_EXPORT* IntWinUmCacheGetExportFromRange | ( | WIN_PROCESS_MODULE * | Module, |
QWORD | Gva, | ||
DWORD | Length | ||
) |
Tries to find an export in the range [Gva - Length, Gva].
Given Module, it will try to find a valid export which lies at most Length bytes before the provided Gva.
[in] | Module | The module where the export is searched. |
[in] | Gva | Gva to start the search at. |
[in] | Length | Maximum number of bytes to search backwards to see if an export is found. |
Definition at line 225 of file winumcache.c.
Referenced by IntAlertEptFillFromVictimZone(), IntExceptGetVictimProcess(), IntExceptKernelUserLogWindowsInformation(), IntExceptUserLogWindowsInformation(), IntExceptVerifyExportSig(), and IntSerializeExport().
BOOLEAN IntWinUmCacheIsExportDirRead | ( | WIN_PROCESS_MODULE * | Module | ) |
Checks if the exports directory of the given module has been read.
Definition at line 1063 of file winumcache.c.
Referenced by IntAlertEptFillFromVictimZone().
|
static |
Removes a module cache.
This function will permanently remove the cache entry. Care must be taken to ensure that no modules reference this cache structure (ie, all instances of the module for which this cache was created have unloaded).
[in] | Cache | The cache entry to be removed. |
Definition at line 960 of file winumcache.c.
Referenced by IntWinUmCacheUninit(), and IntWinUmModCacheRelease().
void IntWinUmCacheUninit | ( | void | ) |
Uninit the module cache system. This will remove all cache entries. Use this during Introcore uninit.
Definition at line 1082 of file winumcache.c.
Referenced by IntWinGuestUninit().
WINUM_CACHE_EXPORT* IntWinUmModCacheExportFind | ( | WIN_PROCESS_MODULE * | Module, |
DWORD | Rva, | ||
DWORD | ErrorRange | ||
) |
Tries to find an export in the range [Rva, Rva + ErrorRange].
Given Module, it will try to find a valid export which lies within the [Rva, Rva + ErrorRange] interval.
[in] | Module | The module where the export is searched. |
[in] | Rva | Rva to start the search at. |
[in] | ErrorRange | Maximum interval to search after the provided Rva. |
Definition at line 262 of file winumcache.c.
Referenced by IntWinThrHandleQueueApc(), and IntWinUmCacheGetExportFromRange().
|
static |
Returns the cache associated with the provided module.
This function will iterate the global list of caches, trying to find the cache associated with the provided module. NOTE: Dirty caches (those identified statically) are ignored.
[in] | Module | The module for which we wish to find a cache entry. |
Definition at line 899 of file winumcache.c.
Referenced by IntWinUmModCacheGet().
|
static |
Fills the exports cache of the provided module with each exported symbol.
NOTE: Export sections larger than ONE_MEGABYTE will not be parsed.
[in] | Module | The module whose exports will be read & cached. |
INT_STATUS_SUCCESS | On success. |
INT_STATUS_ALREADY_INITIALIZED_HINT | If the exports of this module have already been cached. |
INT_STATUS_NOT_NEEDED_HINT | If there's no need to cache the exports of this module. |
INT_STATUS_NOT_SUPPORTED | If the exports section exceeds ONE_MEGABYTE in size. |
Definition at line 705 of file winumcache.c.
Referenced by IntWinUmModCacheSetHeaders().
|
static |
Fills MZ/PE headers information for the provided module.
This function will allocate the headers page, it will validate the MZ/PE headers of this module, and it will fill some basic info inside the cache structure (such as IAT/EAT RVA). It will not read the exports.
[in] | Module | The module for which the headers info will be initialized. |
[in] | Headers | A pointer to a buffer containing the MZ/PE if the indicated module. |
INT_STATUS_SUCCESS | On success. |
INT_STATUS_ALREADY_INITIALIZED_HINT | If the headers have already been filled. |
Definition at line 790 of file winumcache.c.
Referenced by IntWinUmModCacheSetHeaders().
void IntWinUmModCacheGet | ( | WIN_PROCESS_MODULE * | Module | ) |
Initializes the cache for the provided module.
If a cache already exists for the indicated module (because an instance of it has already been loaded), it will be used for this module as well. Otherwise, a new cache will be created for this module. If other instances of this module get loaded, they will be able to reuse the same cache structure.
[in] | Module | The module for which the cache is to be created. |
Definition at line 936 of file winumcache.c.
Referenced by IntWinModHandleModulePathInMemory().
void IntWinUmModCacheRelease | ( | WINUM_MODULE_CACHE * | Cache | ) |
Removes a module cache, if it was written (it's dirty).
NOTE: This function gets called when a module is unloaded. However, we will not destroy the cache, unless it is dirty (it has been loaded statically).
[in] | Cache | The cache to be removed if dirty. |
Definition at line 1000 of file winumcache.c.
Referenced by IntWinModRemoveModule().
INTSTATUS IntWinUmModCacheSetHeaders | ( | WIN_PROCESS_MODULE * | Module, |
BYTE * | Headers | ||
) |
Sets the MZ/PE headers in the cache of a given module.
[in] | Module | The module whose headers are to be set. |
[in] | Headers | Buffer containing the MZ/PE headers. |
INT_STATUS_SUCCESS | On success. |
Definition at line 1025 of file winumcache.c.
Referenced by IntWinModHandleModuleHeadersInMemory().
Checks of the exports of a module need to be cached.
[in] | NameHash | The hash of the module to be checked. If the hash is in the gExportedDirsToCache array, its exports will be cached. |
Definition at line 649 of file winumcache.c.
Referenced by IntWinUmModCacheFillExports().
const DWORD gExportedDirsToCache[] |
The list of hashes for libraries we wish to cache.
Definition at line 36 of file winumcache.c.
Referenced by IntWinUmModMustCacheExports().
LIST_HEAD gWinProcesses |
The list of all the processes inside the guest.
Definition at line 11 of file winprocesshp.c.
LIST_HEAD gWinUmCaches = LIST_HEAD_INIT(gWinUmCaches) |
Definition at line 51 of file winumcache.c.