HyperDbg Documentation
CommunityDownloadResearchTutorialhwdbg
  • HyperDbg
  • Getting Started
    • Quick Start
    • FAQ
    • Build & Install
    • Attach to HyperDbg
      • Attach to a remote machine
      • Attach to local machine
      • Start a new process
      • Attach to a running process
  • Using HyperDbg
    • Prerequisites
      • Operation Modes
      • How to create a condition?
      • How to create an action?
      • Signatures
    • User-mode Debugging
      • Principles
      • Examples
        • basics
        • events
          • Getting Results of a System-call
    • Kernel-mode Debugging
      • Principles
      • Examples
        • beginning
          • Connecting To HyperDbg
          • Configuring Symbol Server/Path
        • basics
          • Setting Breakpoints & Stepping Instructions
          • Displaying & Editing & Searching Memory
          • Showing & Modifying Registers and Flags
          • Switching to a Specific Process or Thread
          • Mapping Data & Create Structures, and Enums From Symbols
        • events
          • Managing Events
          • Hooking Any Function
          • Intercepting All SYSCALLs
          • Monitoring Accesses To Structures
          • Triggering Special Instructions
          • Identifying System Behavior
        • Scripting Language Examples
    • Software Development Kit (SDK)
      • Events
        • Conditions
        • Actions
      • IOCTL
        • Event Registration
  • Commands
    • Debugging Commands
      • ? (evaluate and execute expressions and scripts in debuggee)
      • ~ (display and change the current operating core)
      • a (assemble virtual address)
      • load (load the kernel modules)
      • unload (unload the kernel modules)
      • status (show the debuggee status)
      • events (show and modify active/disabled events)
      • p (step-over)
      • t (step-in)
      • i (instrumentation step-in)
      • gu (step-out or go up)
      • r (read or modify registers)
      • bp (set breakpoint)
      • bl (list breakpoints)
      • be (enable breakpoints)
      • bd (disable breakpoints)
      • bc (clear and remove breakpoints)
      • g (continue debuggee or processing kernel packets)
      • x (examine symbols and find functions and variables address)
      • db, dc, dd, dq (read virtual memory)
      • eb, ed, eq (edit virtual memory)
      • sb, sd, sq (search virtual memory)
      • u, u64, u2, u32 (disassemble virtual address)
      • k, kd, kq (display stack backtrace)
      • dt (display and map virtual memory to structures)
      • struct (make structures, enums, data types from symbols)
      • sleep (wait for specific time in the .script command)
      • pause (break to the debugger and pause processing kernel packets)
      • print (evaluate and print expression in debuggee)
      • lm (view loaded modules)
      • cpu (check cpu supported technologies)
      • rdmsr (read model-specific register)
      • wrmsr (write model-specific register)
      • flush (remove pending kernel buffers and messages)
      • prealloc (reserve pre-allocated pools)
      • preactivate (pre-activate special functionalities)
      • output (create output source for event forwarding)
      • test (test functionalities)
      • settings (configures different options and preferences)
      • exit (exit from the debugger)
    • Meta Commands
      • .help (show the help of commands)
      • .debug (prepare and connect to debugger)
      • .connect (connect to a session)
      • .disconnect (disconnect from a session)
      • .listen (listen on a port and wait for the debugger to connect)
      • .status (show the debugger status)
      • .start (start a new process)
      • .restart (restart the process)
      • .attach (attach to a process)
      • .detach (detach from the process)
      • .switch (show the list and switch between active debugging processes)
      • .kill (terminate the process)
      • .process, .process2 (show the current process and switch to another process)
      • .thread, .thread2 (show the current thread and switch to another thread)
      • .pagein (bring the page into the RAM)
      • .dump (save the virtual memory into a file)
      • .formats (show number formats)
      • .script (run batch script commands)
      • .sympath (set the symbol server)
      • .sym (load pdb symbols)
      • .pe (parse PE file)
      • .logopen (open log file)
      • .logclose (close log file)
      • .cls (clear the screen)
    • Extension Commands
      • !a (assemble physical address)
      • !pte (display page-level address and entries)
      • !db, !dc, !dd, !dq (read physical memory)
      • !eb, !ed, !eq (edit physical memory)
      • !sb, !sd, !sq (search physical memory)
      • !u, !u64, !u2, !u32 (disassemble physical address)
      • !dt (display and map physical memory to structures)
      • !track (track and map function calls and returns to the symbols)
      • !epthook (hidden hook with EPT - stealth breakpoints)
      • !epthook2 (hidden hook with EPT - detours)
      • !monitor (monitor read/write/execute to a range of memory)
      • !syscall, !syscall2 (hook system-calls)
      • !sysret, !sysret2 (hook SYSRET instruction execution)
      • !mode (detect kernel-to-user and user-to-kernel transitions)
      • !cpuid (hook CPUID instruction execution)
      • !msrread (hook RDMSR instruction execution)
      • !msrwrite (hook WRMSR instruction execution)
      • !tsc (hook RDTSC/RDTSCP instruction execution)
      • !pmc (hook RDPMC instruction execution)
      • !vmcall (hook hypercalls)
      • !exception (hook first 32 entries of IDT)
      • !interrupt (hook external device interrupts)
      • !dr (hook access to debug registers)
      • !ioin (hook IN instruction execution)
      • !ioout (hook OUT instruction execution)
      • !hide (enable transparent-mode)
      • !unhide (disable transparent-mode)
      • !measure (measuring and providing details for transparent-mode)
      • !va2pa (convert a virtual address to physical address)
      • !pa2va (convert physical address to virtual address)
      • !dump (save the physical memory into a file)
      • !pcitree (show PCI/PCIe device tree)
      • !pcicam (dump the PCI/PCIe configuration space)
      • !idt (show Interrupt Descriptor Table entries)
      • !apic (dump local APIC entries in XAPIC and X2APIC modes)
      • !ioapic (dump I/O APIC)
    • Scripting Language
      • Assumptions & Evaluations
      • Variables & Assignments
      • Casting & Type-awareness
      • Conditionals & Loops
      • Constants & Functions
      • Debugger Script (DS)
      • Examples
        • view system state (registers, memory, variables)
        • change system state (registers, memory, variables)
        • trace function calls
        • pause the debugger conditionally
        • conditional breakpoints and events
        • patch the normal sequence of execution
        • access to a shared variable from different cores
        • count occurrences of events
      • Functions
        • debugger
          • pause
        • events
          • event_enable
          • event_disable
          • event_clear
          • event_sc
          • event_inject
          • event_inject_error_code
          • flush
        • exports
          • print
          • printf
        • interlocked
          • interlocked_compare_exchange
          • interlocked_decrement
          • interlocked_exchange
          • interlocked_exchange_add
          • interlocked_increment
        • memory
          • check_address
          • eb, ed, eq
          • eb_pa, ed_pa, eq_pa
          • memcpy
          • memcpy_pa
          • memcmp
          • virtual_to_physical
          • physical_to_virtual
        • diassembler
          • disassemble_len
          • disassemble_len32
        • spinlocks
          • spinlock_lock
          • spinlock_lock_custom_wait
          • spinlock_unlock
        • strings
          • strlen
          • wcslen
          • strcmp
          • strncmp
          • wcscmp
          • wcsncmp
    • Commands Map
  • Tips & Tricks
    • Considerations
      • Basic concepts in Intel VT-x
      • VMX root-mode vs VMX non-root mode
      • The "unsafe" behavior
      • Script engine in VMX non-root mode
      • Difference between process and thread switching commands
      • Accessing Invalid Address
      • Transparent Mode
    • Nested-Virtualization Environments
      • Supported Virtual Machines
      • Run HyperDbg on VMware
      • Run HyperDbg on Hyper-V
      • Supporting VMware/Hyper-V
      • VMware backdoor I/O ports
    • Misc
      • Event forwarding
      • Event short-circuiting
      • Event calling stage
      • Instant events
      • Message overflow
      • Customize build
        • Increase Communication Buffer Size
        • Number of EPT Hooks in One Page
        • Change Script Engine Limitations
      • Enable and disable events in Debugger Mode
      • Switch to New Process Layout
  • Contribution
    • Style Guide
      • Coding style
      • Command style
      • Doxygen style
    • Logo & Artworks
  • Design
    • Features
      • VMM (Module)
        • Control over NMIs
        • VMX root-mode compatible message tracing
        • Design of !epthook
        • Design of !epthook2
        • Design of !monitor
        • Design of !syscall & !sysret
        • Design of !exception & !interrupt
    • Debugger Internals
      • Events
      • Conditions
      • Actions
      • Kernel Debugger
        • Design Perspective
        • Connection
  • Links
    • Twitter
    • Telegram
    • Discord
    • Matrix
    • Mastodon
    • YouTube
    • hwdbg (Chip Debugger)
    • Doxygen
    • Contribution
Powered by GitBook
On this page
  • What was the problem?
  • Regular Events
  • Big Events
  • Enable or Disable Events
  • Clearing Events
  • Pools & Preallocations
  • Event Regular Buffers
  • Event Big Buffers
  • Safe Event Buffers
  • Regular Safe Event Buffers
  • Big Safe Event Buffers
  • Instant Events For EPT Hooks
  • Memory Monitor Hooks
  • EPT Hooks (Hidden Breakpoints)
  • EPT Hooks (Detours Hooks)
  • Changing Design Constants
  • Instant Event Errors
Edit on GitHub
  1. Tips & Tricks
  2. Misc

Instant events

The instant event mechanism in HyperDbg

PreviousEvent calling stageNextMessage overflow

Last updated 1 year ago

Starting from v0.7 HyperDbg supports the "instant event" mechanism. This mechanism is mainly introduced to fix a fundamental problem of immediately applying events in the .

Instant events addressed this issue by providing two types of events, regular events, and big events.

Through the implementation of the instant event mechanism, our aim was to make the design complexities transparent to the user by preallocating buffers and considering some pre-defined limitations. Nevertheless, if you encounter errors or limitations, this documentation is here to assist you in resolving them. If clarification is needed, feel free to ask or engage in .

What was the problem?

If you've previously used HyperDbg, you've probably noticed that events (e.g., EPT hooks, syscall hooks, memory monitors, etc.) continue the debugger for a short time and then break the debugger again. Thus, the target process might find a chance to continue its execution and you'll lose the current context (registers, memory). This was a fundamental problem in HyperDbg and the instant event mechanism solves this issue.

By employing instant events, now HyperDbg guarantees to keep debuggee in a halt state (in ); thus, nothing will change during its execution and the context is preserved.

The implementation of this mechanism involves broadcasting events to the halted cores (in the VMX root-mode), and as you might know, allocating memory is not possible in the VMX-root mode as paging is not working. Because of that, HyperDbg is not able to allocate memory to store the details of each event in the debugger, and as a result, we use a couple of pre-allocated pools to use them to store the event details on the VMX root-mode.

Two types of events refer to the size of the buffer needed for each event.

Regular Events

Regular events are those events that need a small number of bytes for the pre-allocated buffer and once you start HyperDbg, it allocates a tens of events. HyperDbg will store buffers (for and event ) with small sizes in these events.

Big Events

Big events are those events that need a bigger number of bytes (size). For example, the buffer or the buffer is bigger than normal events. In these cases, HyperDbg needs to allocate bigger buffers for the debuggee to use in the VMX-root mode. By default, HyperDbg won't allocate any buffers for big events, because these events are not regularly used, thus, to save memory HyperDbg won't allocate them.

Enable or Disable Events

/**
 * @brief Enable or disable the instant event mechanism
 * @details for more information: https://docs.hyperdbg.org/tips-and-tricks/misc/instant-events
 *
 */
#define EnableInstantEventMechanism TRUE

Clearing Events

As a result of the instant events, clearing and terminating events are also applied immediately. However, once you clear an event or all events, HyperDbg just disables the event(s). Immediately after you continue the debuggee, HyperDbg tries to process the clear operation and removes the effect of the event in the system.

Pools & Preallocations

Event Regular Buffers

By default, HyperDbg allocates a couple of buffers for storing events. If you continue the debugger after applying events, then HyperDbg re-allocates more buffers to replace previously used buffers but if you want to apply many events instantly, you need to tell HyperDbg beforehand to allocate more buffers for your events.

The following command is used to tell HyperDbg to allocate buffers to store regular events.

 prealloc regular-event 10

In the above example, HyperDbg preallocates 10 buffers for 10 regular events.

Event Big Buffers

prealloc big-event 12

In the above example, HyperDbg preallocates 12 buffers for 12 big events. Usually, you need to use the regular events and if HyperDbg shows an error and indicates that the size of the buffer is too big and it's not able to store the action buffer, then you can use a big event.

Safe Event Buffers

Regular Safe Event Buffers

prealloc regular-safe-buffer 10

After that, you'll be able to use the events with the $buffer parameter.

!epthook nt!ExAllocatePoolWithTag buffer 100 script { ... }

Big Safe Event Buffers

prealloc big-safe-buffer 10

After that, you'll be able to use the events with the $buffer parameter. (Note the size of the buffer is bigger than the regular events)

!epthook nt!ExAllocatePoolWithTag buffer 2000 script { ... }

Instant Events For EPT Hooks

Memory Monitor Hooks

 prealloc regular-event 15

Then, we preallocate buffers for this specific EPT monitor event.

prealloc monitor 15

EPT Hooks (Hidden Breakpoints)

 prealloc regular-event 15

Then, we preallocate buffers for this specific EPT hook event.

prealloc epthook 15

EPT Hooks (Detours Hooks)

 prealloc regular-event 15

Then, we preallocate buffers for this specific event EPT hook event.

prealloc epthook2 15

Changing Design Constants

Here are a couple of design constants and their descriptions. If you want to customize HyperDbg (and compile it), you can change the following constants.

The following constant shows the maximum number of packets that can be delivered to the user-mode. For example, if you want to clear tens of events and HyperDbg shows an error message indicating that the user-mode priority buffers are full, you can increase the following constant to fix the problem.

#define MaximumPacketsCapacityPriority 50

The following constant shows the maximum number of EPT hooks that HyperDbg allocates pre-allocated buffers for them. If you want to apply more EPT hooks without continuing the debuggee, you can increase the following constant.

#define MAXIMUM_NUMBER_OF_INITIAL_PREALLOCATED_EPT_HOOKS 5
#define MAXIMUM_REGULAR_INSTANT_EVENTS 20
#define MAXIMUM_BIG_INSTANT_EVENTS 0
#define REGULAR_INSTANT_EVENT_CONDITIONAL_BUFFER sizeof(DEBUGGER_EVENT) + 100
#define BIG_INSTANT_EVENT_CONDITIONAL_BUFFER sizeof(DEBUGGER_EVENT) + PAGE_SIZE 
#define REGULAR_INSTANT_EVENT_ACTION_BUFFER sizeof(DEBUGGER_EVENT_ACTION) + (PAGE_SIZE * 2)
#define BIG_INSTANT_EVENT_ACTION_BUFFER sizeof(DEBUGGER_EVENT_ACTION) + MaxSerialPacketSize
#define REGULAR_INSTANT_EVENT_REQUESTED_SAFE_BUFFER PAGE_SIZE
#define BIG_INSTANT_EVENT_REQUESTED_SAFE_BUFFER MaxSerialPacketSize

Instant Event Errors

HyperDbg cannot allocate an infinite amount of preallocated buffers and because of this limitation, there are multiple errors related to instant events. Here these errors are described as well as the situations where these errors happen in HyperDbg and how you can fix them.

0xc0000040

0xc0000041

0xc0000042

This error happens regularly and it means that HyperDbg didn't allocate enough preallocated buffer to store your event. Usually, this error happens when you apply many events (for example many EPT hooks on different functions) without continuing the debuggee for some time.

0: kHyperDbg> prealloc regular-event 50
the requested pools are allocated and reserved

0: kHyperDbg> prealloc epthook 50
the requested pools are allocated and reserved

0xc0000043

0: kHyperDbg> prealloc big-event 5
the requested pools are allocated and reserved

The above command tells HyperDbg to reserve big pools for 5 events.

0xc0000044

0xc0000045

This error is the same as (0xc0000042) and it states HyperDbg didn't allocate enough preallocated buffer to store your action. Usually, this error happens when you apply many events (for example many EPT hooks on different functions) without continuing the debuggee for some time.

0: kHyperDbg> prealloc regular-event 50
the requested pools are allocated and reserved

0: kHyperDbg> prealloc epthook 50
the requested pools are allocated and reserved

0xc0000046

0: kHyperDbg> prealloc big-event 5
the requested pools are allocated and reserved

The above command tells HyperDbg to reserve big pools for 5 events.

0xc0000047

0xc0000048

0xc0000049

The following command allocates safe buffers for three events.

0: kHyperDbg> prealloc regular-safe-buffer 3
the requested pools are allocated and reserved

0xc000004a

The following command allocates a big safe buffer for one event.

0: kHyperDbg> prealloc big-safe-buffer 1
the requested pools are allocated and reserved

0xc000004b

0xc000004c

0xc000004f

This error typically occurs when attempting to clear a substantial number of events while the debugger is paused in Debugger Mode, and the user hasn't resumed the debuggee for an extended period. When this error happens, the targeted event(s) become disabled but are not completely removed. This is due to HyperDbg's inability to clear them during the subsequent run, as the user-mode priority buffers are already filled to capacity. Since these unserviced events remained in the queue, HyperDbg cannot eliminate them. To resolve this issue, you can continue the debuggee and wait until all queued events are cleared (usually 2 to 10 seconds). Afterward, pause the debuggee once more and request the removal of new events.

If you want to extend this capacity, you can refer to the "Changing Design Constants" on this page.

If you don't want to encounter these limitations, you can disable the instant event mechanism by using the following and HyperDbg. If you disable this mechanism, then the context (registers and memory) will be lost (changed) when you're applying events.

Events are also able to call the '' function directly from the scripts to remove other events or even the current event.

As explained earlier, it's not possible to allocate buffers in the VMX-root mode. HyperDbg tries to allocate buffers whenever possible but if you're applying a large number of events all of them without continuing the debuggee, the '' command is designed to make HyperDbg able to support these scenarios.

Note that, the '' command will continue the debuggee for some time (in ). This means that you lose the current context (registers & memory) after executing this command. So, you need to use this command before applying events.

If you have a very long or buffer, then you can use the big events instead.

By default, instant events won't support preallocated safe buffers that are accessible as $buffer but you can preallocate two types of buffers (big event-peallocation) and (regular event-preallocation) buffers.

If you need a small buffer (explained later in the section), then you can use the following command. You can also specify the number of events that you need a regular safe buffer for them.

If you need a bigger buffer (explained later in the section), then you can use the following command. You can also specify the number of events that you need a big safe buffer for them.

EPT hooks need extra pre-allocated buffers. If you want to use EPT hook events (, , and ), then you need to preallocate buffers for them.

By default, if you use EPT hooks and continue the debuggee after applying events, HyperDbg tries to re-allocate more buffers for the next EPT hooks but if you want to apply all of them without continuing the debuggee, then you need to use the '' command.

Please note that EPT hooks are events, so first you need to preallocate event buffers (explained ) and EPT hook buffers.

If you want to use , you can preallocate buffers for them. For example, assume that we want to apply fifteen '' events, first, we allocate 15 events buffer.

If you want to use , you can preallocate buffers for them. For example, assume that we want to apply fifteen '' events, first, we allocate 15 events buffer.

If you want to use , you can preallocate buffers for them. For example, assume that we want to apply fifteen '' events, first, we allocate 15 events buffer.

The following constant shows the maximum number of regular events that you can apply immediately without continuing the debuggee. If you want to apply tens of events without using the '' command, you can increase the value of this constant.

The following constant shows the maximum number of big events that you can apply immediately without continuing the debuggee. If you want to apply tens of events without using the '' command, you can increase the value of this constant.

The following constant shows the maximum number of bytes to store the details of a regular event. If you're using a very big buffer, you can increase this constant.

The following constant shows the maximum number of bytes to store the details of a big event. If you're using a very big buffer, you can increase this constant.

The following constant shows the maximum number of bytes that an action ( and ) can be for the regular event. If you want to apply bigger scripts or custom codes, you can increase this constant.

The following constant shows the maximum number of bytes that an action ( and ) can be for the big event. If you want to apply bigger scripts or custom codes, you can increase this constant.

The following constant shows the maximum number of bytes allocated for the safe pre-allocated buffer of the regular events. This is mainly used if you pass the buffer parameter to events. By default, HyperDbg won't allocate safe buffers and you need to use the '' command to allocate them. You can increase the size of these buffers by changing this constant.

The following constant shows the maximum number of bytes allocated for the safe pre-allocated buffer of the regular events. This is mainly used if you pass the buffer parameter to events. By default, HyperDbg won't allocate safe buffers and you need to use the '' command to allocate them. You can increase the size of these buffers by changing this constant.

Please note that the '' command will continue the debuggee for some time (in Debugger Mode). This means that you lose the current context (registers & memory) after executing this command. So, you need to keep in mind that in case of errors, first run the '' command and once you have enough buffers for your events, then apply all of your events instantly.

This error states that in some situations like applying '' or '', specifying the target process id is not possible, because HyperDbg cannot find the structures of the target process and perform the context switching. You need to use the '' or the '' command to switch to the target process memory layout, then apply your hooks.

This error states that the that you specified for the target event cannot be stored in the memory as there is not enough pre-allocated space for the target buffer. In order to fix that, you need to customize and rebuild HyperDbg. Please refer to the "Changing Design Constants" on this page.

In order to fix that, you have two options. You can either continue HyperDbg by running '' and after some time press CTRL+C and pause the debugger again, so HyperDbg finds a chance to reallocate new preallocated pools for your events.

If you don't want to continue HyperDbg, before applying events, you can use the '' command to allocate as many preallocated pools as you need and after that, you can pause HyperDbg and apply your events.

For example, assume that you want to apply '' for 0x50 number of functions. If you apply all of them without continuing the debuggee, you'll encounter this error but if you run the following commands beforehand, events can be applied without any problem.

This error states that the is big and cannot be stored in the pre-allocated pools. Usually, it happens if you are passing a long buffer of to the event. In order to solve that, you can run the following command and HyperDbg will allocate a bigger buffer for your event and conditions.

This error indicates that the system doesn't have enough resources (RAM) to allocate the target action in the .

In order to fix that, you have two options. You can either continue HyperDbg by running '' and after some time press CTRL+C and pause the debugger again, so HyperDbg finds a chance to reallocate new preallocated pools for your actions.

If you don't want to continue HyperDbg, before applying events, you can use the '' command to allocate as many preallocated pools as you need and after that, you can pause HyperDbg and apply your actions.

For example, assume that you want to apply '' for 0x50 number of functions. If you apply all of them without continuing the debuggee, you'll encounter this error but if you run the following commands beforehand, events can be applied without any problem.

This error is the same as (0xc0000043). It states that the or the buffer is big and cannot be stored in the pre-allocated pools. Usually, it happens if you are passing a long or a long buffer of assemblies to the event. In order to solve that, you can run the following command and HyperDbg will allocate a bigger buffer for your event and conditions.

This error states that your or the buffer is so big that HyperDbg cannot store it. In order to fix that, you need to customize and rebuild HyperDbg. Please refer to the "Changing Design Constants" on this page.

This error states that you specified a pre-allocated buffer that is bigger than the stack of HyperDbg to send/receive it. You need to specify a small safe buffer or you need to customize and rebuild HyperDbg to allocate bigger stacks for the communication. This error happens on both the and the .

By default, HyperDbg won't allocate requested buffers () for instant events. If you need a safe buffer, you need to tell HyperDbg before applying the event.

After running the above command, you can use the safe buffer () on your events.

This error means that your requested buffer is big and cannot fit into the preallocated buffers. In order to solve that, you can tell HyperDbg to allocate bigger safe buffers for you before applying the event by using the following command.

This error states that you specified a very big buffer and HyperDbg cannot store it in the memory. In order to fix that, you need to customize and rebuild HyperDbg. Please refer to the "Changing Design Constants" on this page.

This error indicates that the system doesn't have enough resources (RAM) to allocate the safe buffers () in the .

Debugger Mode
questions
discussions
Debugger Mode
scripts
custom code
script
custom code
constant
compiling
event_clear
prealloc
prealloc
Debugger Mode
script
custom code
pseudo-registers
Changing Design Constants
Changing Design Constants
!epthook
!epthook2
!monitor
prealloc
above
memory monitor hooks
!monitor
classic hidden hooks
!epthook
detours EPT hooks
!epthook2
prealloc
prealloc
condition
condition
script
custom codes
script
custom codes
prealloc
prealloc
prealloc
prealloc
!epthook
!monitor
.process
.thread
conditional buffer
g
prealloc
!epthook
conditional buffer
conditions
VMI Mode
g
prealloc
!epthook
script
custom code
script
custom code
script
custom code
Debugger Mode
VMI Mode
safe
$buffer
$buffer
safe
safe
$buffer
VMI Mode