• Stars
    star
    1,146
  • Rank 40,695 (Top 0.9 %)
  • Language
    C++
  • License
    MIT License
  • Created over 8 years ago
  • Updated almost 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Monitoring and controlling kernel API calls with stealth hook using EPT

DdiMon

Introduction

DdiMon is a hypervisor performing inline hooking that is invisible to a guest (ie, any code other than DdiMon) by using extended page table (EPT).

DdiMon is meant to be an educational tool for understanding how to use EPT from a programming perspective for research. To demonstrate it, DdiMon installs the invisible inline hooks on the following device driver interfaces (DDIs) to monitor activities of the Windows built-in kernel patch protection, a.k.a. PatchGuard, and hide certain processes without being detected by PatchGuard.

  • ExQueueWorkItem
  • ExAllocatePoolWithTag
  • ExFreePool
  • ExFreePoolWithTag
  • NtQuerySystemInformation

Those stealth shadow hooks are hidden from guest's read and write memory operations and exposed only on execution of the memory. Therefore, they are neither visible nor overwritable from a guest, while they function as ordinal hooks. It is accomplished by making use of EPT enforcing a guest to see different memory contents from what it would see if EPT is not in use. This technique is often called memory shadowing. For more details, see the Design section below.

Here is a movie demonstrating that shadow hooks allow you to monitor and control DDI calls without being notified by PatchGuard.

DdiMon is implemented on the top of HyperPlatform. See a project page for more details of HyperPlatform:

Installation and Uninstallation

Clone full source code from Github with a below command and compile it on Visual Studio.

$ git clone --recursive https://github.com/tandasat/DdiMon.git

On the x64 platform, you have to enable test signing to install the driver. To do that, open the command prompt with the administrator privilege and type the following command, and then restart the system to activate the change:

>bcdedit /set testsigning on

To install and uninstall the driver, use the 'sc' command. For installation:

>sc create DdiMon type= kernel binPath= C:\Users\user\Desktop\DdiMon.sys
>sc start DdiMon

And for uninstallation:

>sc stop DdiMon
>sc delete DdiMon
>bcdedit /deletevalue testsigning

Note that the system must support the Intel VT-x and EPT technology to successfully install the driver.

To install the driver on a virtual machine on VMware Workstation, see an "Using VMware Workstation" section in the HyperPlatform User Document.

Output

All logs are printed out to DbgView and saved in C:\Windows\DdiMon.log.

Motivation

Despite existence of plenty of academic research projects[1,2,3] and production software[4,5], EPT (a.k.a. SLAT; second-level-address translation) is still underused technology among reverse engineers due to lack of information on how it works and how to control it through programming.

MoRE[6] by Jacob Torrey is a one of very few open source projects demonstrating use of EPT with small amount of code. While we recommend to look into the project for basic comprehension of how EPT can be initialized and used to set up more than 1:1 guest to machine physical memory mapping, MoRE lacks flexibility to extend its code for supporting broader platforms and implementing your own analysis tools.

DdiMon provides a similar sample use of EPT as what MoRE does with a greater range of platform support such as x64 and/or Windows 10. DdiMon, also, can be seen as example extension of HyperPlatform for memory virtualization.

Design

In order to install a shadow hook, DdiMon creates a couple of copies of a page where the address to install a hook belongs to. After DdiMon is initialized, those two pages are accessed when a guest, namely all but ones by the hypervisor (ie, DdiMon), attempts to access to the original page instead. For example, when DdiMon installs a hook onto 0x1234, two copied pages are created: 0xa000 for execution access and 0xb000 for read or write access, and memory access is performed as below after the hook is activated:

               Requested    Accessed
By Hypervisor: 0x1234    -> 0x1234 on all access
By Guest:      0x1234    -> 0xa234 on execution access
                         -> 0xb234 on read or write access

The following explains how it is accomplished.

Default state

DdiMon first configures an EPT entry corresponds to 0x1000-0x1fff to refer to the contents of 0xa000 and to disallow read and write access to the page.

Scenario: Read or Write

  1. With this configuration, any read and write access triggers EPT violation VM-exit. Up on the VM-exit, the EPT entry for 0x1000-0x1fff is modified to refer to the contents of 0xb000, which is copy of 0x1000, and to allow read and write to the page. And then, sets the Monitor Trap Flag (MTF), which works like the Trap Flag of the flag register but not visible to a guest, so that a guest can perform the read or write operation and then interrupted by the hypervisor with MTF VM-exit.

  2. After executing a single instruction, a guest is interrupted by MTF VM-exit. On this VM-exit, the hypervisor clears the MTF and resets the EPT entry to the default state so that subsequent execution is done with the contents of 0xa000.

As a result of this sequence of operations, a guest executed a single instruction reading from or writing to 0xb234.

Scenario: Execute

At this time, execution is done against contents of 0xa000 without triggering any events unless no other settings is made. In order to monitor execution of 0xa234 (0x1234 from guest's perspective), DdiMon sets a break point (0xcc) to 0xa234 and handles #BP in the hypervisor. Following steps are how DdiMon hooks execution of 0xa234.

  1. On #BP VM-exit, the hypervisor checks if guest's EIP/RIP is 0x1234 first. If so, the hypervisor changes the contents of the register to point to a corresponding hook handler for instrumenting the DDI call.

  2. On VM-enter, a guest executes the hook handler. The hook handler calls an original function, examines parameters, return values and/or a return address, and takes action accordingly.

This is just like a typical inline hooking. Only differences are that it sets 0xcc and changes EIP/RIP from a hypervisor instead of overwriting original code with JMP instructions and that installed hooks are not visible from a guest. An advantage of using 0xcc is that it does not require a target function to have a length to install JMP instructions.

Implementation

The following are a call hierarchy with regard to sequences explained above.

On DriverEntry

DdimonInitialization()
  DdimonpEnumExportedSymbolsCallback()  // Enumerates exports of ntoskrnl
    ShInstallHook()                     // Installs a stealth hook
  ShEnableHooks()                       // Activates installed hooks
    ShEnablePageShadowing()
      ShpEnablePageShadowingForExec()   // Configures an EPT entry as
                                        // explained in "Default state"

On EPT violation VM-exit with read or write

VmmpHandleEptViolation()
  EptHandleEptViolation()
    ShHandleEptViolation()  // Performs actions as explained in the 1 of
                            // "Scenario: Read or Write"

On MTF VM-exit

VmmpHandleMonitorTrap()
  ShHandleMonitorTrapFlag() // Performs actions as explained in the 2 of
                            // "Scenario: Read or Write"

On #BP VM-exit

VmmpHandleException()
  ShHandleBreakpoint()      // Performs actions as explained in the 1 of
                            // "Scenario: Execute"

Implemented Hook Handlers

  • ExQueueWorkItem - The hook handler prints out given parameters when a specified work item routine is not inside any images.

  • ExAllocatePoolWithTag - The hook handler prints out given parameters and a return value of ExAllocatePoolWithTag() when it is called from an address where is not backed by any images.

  • ExFreePool and ExFreePoolWithTag - The hook handlers print out given parameters when they are called from addresses where are not backed by any images.

  • NtQuerySystemInformation - The hook handler takes out an entry for "cmd.exe" from returned process information so that cmd.exe is not listed by process enumeration.

The easiest way to see those logs is installing NoImage.sys.

Logs for activities of NoImage are look like this:

17:59:23.014	INF	#0	    4	   48	System         	84660265: ExFreePoolWithTag(P= 84665000, Tag= nigm)
17:59:23.014	INF	#0	    4	   48	System         	84660283: ExAllocatePoolWithTag(POOL_TYPE= 00000000, NumberOfBytes= 00001000, Tag= nigm) => 8517B000
17:59:23.014	INF	#0	    4	   48	System         	8517B1C3: ExQueueWorkItem({Routine= 8517B1D4, Parameter= 8517B000}, 1)

Caveats

DdiMon is meant to be an educational tool and not robust, production quality software which is able to handle various edge cases. For example, DdiMon does not handle self-modification code since any memory writes on a shadowed page is not reflected to a view for execution. For this reason, researchers are encouraged to use this project as sample code to get familiar with EPT and develop their own tools as needed.

Supported Platforms

  • x86 and x64 Windows 7, 8.1 and 10
  • The system must support the Intel VT-x and EPT technology

License

This software is released under the MIT License, see LICENSE.

More Repositories

1

HyperPlatform

Intel VT-x based hypervisor aiming to provide a thin VM-exit filtering platform on Windows.
C++
1,519
star
2

Hypervisor-101-in-Rust

The materials of "Hypervisor 101 in Rust", a one-day long course, to quickly learn hardware-assisted virtualization technology and its application for high-performance fuzzing on Intel/AMD processors.
Rust
981
star
3

MiniVisorPkg

The research UEFI hypervisor that supports booting an operating system.
C
546
star
4

SimpleSvmHook

SimpleSvmHook is a research purpose hypervisor for Windows on AMD processors.
C++
351
star
5

SimpleSvm

A minimalistic educational hypervisor for Windows on AMD processors.
C++
317
star
6

PgResarch

PatchGuard Research
C++
288
star
7

ExploitCapcom

This is a standalone exploit for a vulnerable feature in Capcom.sys
C++
280
star
8

MemoryMon

Detecting execution of kernel memory where is not backed by any image file
C++
252
star
9

DotNetHooking

Sample use cases of the .NET native code hooking technique
C#
201
star
10

barevisor

A bare minimum hypervisor on AMD and Intel processors for learners.
Rust
189
star
11

scripts_for_RE

Python scripts for reverse engineering.
Python
178
star
12

GuardMon

Hypervisor based tool for monitoring system register accesses.
C++
140
star
13

UefiVarMonitor

The runtime DXE driver monitoring access to the UEFI variables by hooking the runtime service table.
C
136
star
14

SmmExploit

The report and the exploit of CVE-2021-26943, the kernel-to-SMM local privilege escalation vulnerability in ASUS UX360CA BIOS version 303.
133
star
15

hvext

The Windbg extension that implements commands helpful to study Hyper-V on Intel processors.
JavaScript
126
star
16

EopMon

Elevation of privilege detector based on HyperPlatform
C++
117
star
17

Sushi

a Japanese food keeps you sane
C++
117
star
18

findpg

Windbg extension to find PatchGuard pages
C++
116
star
19

UEFI-BIOS-Security

Security Camp 2021 & GCC 2022
111
star
20

WinIoCtlDecoder

IDA Plugin which decodes Windows Device I/O control code into DeviceType, FunctionCode, AccessType and MethodType.
Python
106
star
21

FU_Hypervisor

A hypervisor hiding user-mode memory using EPT
C
104
star
22

WPBT-Builder

The simple UEFI application to create a Windows Platform Binary Table (WPBT) from the UEFI shell.
C
100
star
23

HelloSmm

This is an instruction to run your own SMM code.
C
100
star
24

DebugLogger

A software driver that lets you log kernel-mode debug output into a file on Windows.
C++
97
star
25

Hello-VT-rp

A simple hypervisor demonstrating the use of the Intel VT-rp (redirect protection) technology.
Rust
91
star
26

kraft_dinner

Tool to dump UEFI runtime drivers implementing runtime services for Windows
C
90
star
27

HelloAmdHvPkg

HelloAmdHvPkg is a type-1 research hypervisor for AMD processors.
C
86
star
28

CVE-2023-36427

Report and exploit of CVE-2023-36427
C++
86
star
29

Scavenger

A minifilter driver preserves all modified and deleted files.
C
77
star
30

RemoteWriteMonitor

A tool to help malware analysts tell that the sample is injecting code into other process.
C++
74
star
31

meow

nyā
C++
70
star
32

HelloIommuPkg

The sample DXE runtime driver demonstrating how to program DMA remapping.
C
57
star
33

DumpVTable

Generates a Python script to give public interface names in an ActiveX file to an IDB file.
C++
47
star
34

DrvLoader

A command line tool to load and unload a device driver.
C++
42
star
35

CVE-2022-25949

A years-old exploit of a local EoP vulnerability in Kingsoft Antivirus KWatch Driver version 2009.3.17.77.
C++
35
star
36

cs_driver

A sample project for using Capstone from a driver in Visual Studio 2015
C
34
star
37

CVE-2024-21305

Report and exploit of CVE-2024-21305.
C++
30
star
38

CVE-2014-0816

CVE-2014-0816
C++
24
star
39

tandasat.github.io

HTML
17
star
40

hyperplatform_log_parser

User-mode program parsing logs created by HyperPlatform
C++
17
star
41

ProjectLoadTimeMonitor

The Visual Studio extension that measures load time of each project when a solution file is opened.
C#
16
star
42

recon2024_demo

Provides commands to read from and write to arbitrary kernel-mode memory for users with the Administrator privilege. HVCI compatible. No test signing mode is required.
C++
14
star
43

CheckSDL

A tool evaluates security configurations of a given PE based on SDL without source code
C++
12
star
44

ListWorkItems

Lists work items being queued currently.
C++
12
star
45

DeviceOpener

A command line tool to check if a specified device is accessible.
C++
10
star
46

List-UEFI-Configuration-Tables

List UEFI Configuration Tables
Rust
10
star
47

windbg_init

Windbg Init Script
9
star
48

ScopedResource

Scoped Resource - Generic RAII Wrapper for the Standard Library by Peter Sommerlad and Andrew L. Sandoval
C++
8
star
49

win32_debugout

Shows debug strings on DebubView from an attached process by win32_remote.exe.
C++
8
star
50

ping_vmm

A user-mode program knocking at HyperPlatform's "backdoor"
C++
7
star
51

SecRuntimeSample

A sample usege of SecRuntime.dll on Windows Phone
C++
4
star
52

blog

Ruby
4
star
53

CopyFiles

Copy files onto the IsolatedStorage so that you can download them using IsoStoreSpy.
C#
3
star
54

mylight

Using LED of Samsung Galaxy Ace S5830
Java
2
star
55

tandasat

2
star
56

shared

Manages files that are shared with multiple boxes.
Vim Script
1
star