Bitdefender Hypervisor Memory Introspection
unpacker.c File Reference

This module monitors pages against unpack. More...

#include "unpacker.h"
#include "decoder.h"
#include "hook.h"

Go to the source code of this file.

Data Structures

struct  _UNPACK_PAGE
 

Macros

#define UNPACK_STATE_NONE   0x00
 Initial state. More...
 
#define UNPACK_STATE_DIRTY   0x01
 The page was written. More...
 
#define UNPACK_STATE_EXEC   0x02
 The page contains code that has been fetched for execution. More...
 

Typedefs

typedef struct _UNPACK_PAGE UNPACK_PAGE
 
typedef struct _UNPACK_PAGEPUNPACK_PAGE
 

Functions

static PUNPACK_PAGE IntUnpFindPage (QWORD Cr3, QWORD VirtualAddress)
 Finds a monitored page. More...
 
static INTSTATUS IntUnpUnWatchPageInternal (PUNPACK_PAGE Page)
 Remove monitor from the indicated page. More...
 
static INTSTATUS IntUnpPageExecuteCallback (void *Context, void *Hook, QWORD Address, INTRO_ACTION *Action)
 Handle executions from a monitored page. More...
 
static INTSTATUS IntUnpPageWriteCallback (void *Context, void *Hook, QWORD Address, INTRO_ACTION *Action)
 Handle writes inside a monitored page. More...
 
INTSTATUS IntUnpWatchPage (QWORD Cr3, QWORD VirtualAddress, PFUNC_PageUnpackedCallback UnpackCallback, PFUNC_PageIsWriteValid WriteCheckCallback, void *CallbackContext)
 Monitor a page against unpacking. More...
 
INTSTATUS IntUnpUnWatchPage (QWORD Cr3, QWORD VirtualAddress)
 Stop monitoring the indicated page. More...
 
INTSTATUS IntUnpUnWatchVaSpacePages (QWORD Cr3)
 Stop monitoring all pages belonging to a virtual address space. More...
 
INTSTATUS IntUnpRemovePages (void)
 Stop monitoring all pages. More...
 
void IntUnpUninit (void)
 Uninit the unpacker. This will stop the monitor on all pages. More...
 

Variables

static LIST_HEAD gUnpckPages = LIST_HEAD_INIT(gUnpckPages)
 

Detailed Description

This module monitors pages against unpack.

This module monitors pages against unpack. Note that this is legacy code, and it should be rewritten in a more efficient manner (for example, the unpack monitor should be enabled for an entire module, not on a single page at a time). It should also return a handle to the monitored page/module. NOTE: All pages are kept in a single linked list; this can cause serious performance penalty if many such pages are monitored. If performance is of concern, this module must be optimized. NOTE: Since the monitor functions work directly with a Cr3 and a virtual address, no handles are returned. Make sure that each page is monitored only once, otherwise, when trying to remove a page, only the first match will be removed. Alternatively, rewrite this mechanism to return a handle for each monitored page.

Definition in file unpacker.c.

Macro Definition Documentation

◆ UNPACK_STATE_DIRTY

#define UNPACK_STATE_DIRTY   0x01

The page was written.

Definition at line 27 of file unpacker.c.

Referenced by IntUnpPageExecuteCallback(), and IntUnpPageWriteCallback().

◆ UNPACK_STATE_EXEC

#define UNPACK_STATE_EXEC   0x02

The page contains code that has been fetched for execution.

Definition at line 28 of file unpacker.c.

Referenced by IntUnpPageExecuteCallback().

◆ UNPACK_STATE_NONE

#define UNPACK_STATE_NONE   0x00

Initial state.

Definition at line 26 of file unpacker.c.

Referenced by IntUnpWatchPage().

Typedef Documentation

◆ PUNPACK_PAGE

typedef struct _UNPACK_PAGE * PUNPACK_PAGE

◆ UNPACK_PAGE

typedef struct _UNPACK_PAGE UNPACK_PAGE

One page monitored against unpack.

Function Documentation

◆ IntUnpFindPage()

static PUNPACK_PAGE IntUnpFindPage ( QWORD  Cr3,
QWORD  VirtualAddress 
)
static

Finds a monitored page.

Parameters
[in]Cr3Virtual address space of the monitored page.
[in]VirtualAddressAddress to be found.
Returns
The found page structure, or NULL, if none is found.

Definition at line 54 of file unpacker.c.

◆ IntUnpPageExecuteCallback()

static INTSTATUS IntUnpPageExecuteCallback ( void *  Context,
void *  Hook,
QWORD  Address,
INTRO_ACTION Action 
)
static

Handle executions from a monitored page.

If the page is dirty, this function will decode the current instruction and it will invoke the unpack callback.

Parameters
[in]ContextThe context - a monitored page.
[in]HookGPA hook handle.
[in]AddressGuest physical address that has just been executed.
[out]ActionDesired action.
Return values
INT_STATUS_SUCCESSOn success.

Definition at line 132 of file unpacker.c.

Referenced by IntUnpPageWriteCallback().

◆ IntUnpPageWriteCallback()

static INTSTATUS IntUnpPageWriteCallback ( void *  Context,
void *  Hook,
QWORD  Address,
INTRO_ACTION Action 
)
static

Handle writes inside a monitored page.

When the page is written, the write callback will be called, in order to check the write. If the callback returns false, it means that the write is not legitimate, the page will be marked as being dirty, and the execute hook will be set on it. If it returns true, the write callback will be kept, and no execute callback will be set.

Parameters
[in]ContextThe context - a monitored page.
[in]HookGPA hook handle.
[in]AddressGuest physical address that has just been executed.
[out]ActionDesired action.
Return values
INT_STATUS_SUCCESSOn success.

Definition at line 218 of file unpacker.c.

Referenced by IntUnpWatchPage().

◆ IntUnpRemovePages()

INTSTATUS IntUnpRemovePages ( void  )

Stop monitoring all pages.

Return values
INT_STATUS_SUCCESSOn success.

Definition at line 474 of file unpacker.c.

Referenced by IntUnpUninit().

◆ IntUnpUninit()

void IntUnpUninit ( void  )

Uninit the unpacker. This will stop the monitor on all pages.

Definition at line 505 of file unpacker.c.

Referenced by IntGuestUninit().

◆ IntUnpUnWatchPage()

INTSTATUS IntUnpUnWatchPage ( QWORD  Cr3,
QWORD  VirtualAddress 
)

Stop monitoring the indicated page.

Parameters
[in]Cr3The virtual address space.
[in]VirtualAddressThe address to stop monitoring against unpack.
Return values
INT_STATUS_SUCCESSOn success.

Definition at line 396 of file unpacker.c.

◆ IntUnpUnWatchPageInternal()

static INTSTATUS IntUnpUnWatchPageInternal ( PUNPACK_PAGE  Page)
static

Remove monitor from the indicated page.

Parameters
[in]PageThe monitored page.
Return values
INT_STATUS_SUCCESSOn success.
INT_STATUS_INVALID_PARAMETERIf an invalid parameter is supplied.

Definition at line 86 of file unpacker.c.

Referenced by IntUnpPageExecuteCallback(), IntUnpRemovePages(), IntUnpUnWatchPage(), IntUnpUnWatchVaSpacePages(), and IntUnpWatchPage().

◆ IntUnpUnWatchVaSpacePages()

INTSTATUS IntUnpUnWatchVaSpacePages ( QWORD  Cr3)

Stop monitoring all pages belonging to a virtual address space.

Parameters
[in]Cr3The virtual address space to stop monitoring against unpack.
Return values
INT_STATUS_SUCCESSOn success.

Definition at line 438 of file unpacker.c.

Referenced by IntWinModulesChangeProtectionFlags(), and IntWinModUnHookModule().

◆ IntUnpWatchPage()

INTSTATUS IntUnpWatchPage ( QWORD  Cr3,
QWORD  VirtualAddress,
PFUNC_PageUnpackedCallback  UnpackCallback,
PFUNC_PageIsWriteValid  WriteCheckCallback,
void *  CallbackContext 
)

Monitor a page against unpacking.

This function starts to monitor the indicated page against unpacking. The algorithm is fairly simple:

  1. Place a write hook on the indicated page;
  2. On each write inside the page, call the write check callback; if the write check callback returns true (valid write), do nothing; otherwise, mark the page dirty and increment the write count;
  3. Once the write count reaches a threshold (32), remove the write hook and place an execute hook on the page;
  4. When the page is executed, call the unpack callback, to indicate that the page has been unpacked.
Parameters
[in]Cr3Virtual address space.
[in]VirtualAddressThe virtual address of the page to be monitored.
[in]UnpackCallbackCalled when the page is deemed to be "unpacked".
[in]WriteCheckCallbackCalled on each write, to validate it. Some writes may be valid (for example, the writes made by the loader inside the IAT).
[in]CallbackContextOptional context to be passed to the unpack & write callbacks.
Return values
INT_STATUS_SUCCESSOn success.
INT_STATUS_INSUFFICIENT_RESOURCESIf a memory alloc fails.

Definition at line 316 of file unpacker.c.

Referenced by IntWinModHookPoly().

Variable Documentation

◆ gUnpckPages

LIST_HEAD gUnpckPages = LIST_HEAD_INIT(gUnpckPages)
static

Definition at line 49 of file unpacker.c.