# HyperDbg

A hypervisor-assisted debugger designed for analyzing, fuzzing and reversing

## What is it?

HyperDbg debugger is an open-source, user-mode, and kernel-mode debugger focusing on using hardware technologies to provide new features to the debuggers’ world.

![](/files/-M3VfBggK7pI3iFdgD6l)

It is designed on top of Windows by virtualizing an already running system using Intel VT-x and Intel PT. This debugger aims not to use any APIs and software debugging mechanisms, but instead, it uses Second Layer Page Table (a.k.a. Extended Page Table or EPT) extensively to monitor both kernel and user executions.

HyperDbg comes with features like hidden hooks, which is as fast as old inline hooks also stealth. It mimics hardware debug registers for (read & write) to a specific location, but this time entirely invisible for both Windows kernel and the programs, and of course without any limitation in size or count!

Using TLB-splitting, and having features such as measuring code coverage and monitoring all mov(s) to/from memory by a function, makes HyperDbg a unique debugger.

Although it has novel features, HyperDbg tries to be as stealthy as possible. It doesn’t use any debugging APIs to debug Windows or any application, so classic anti-debugging methods won’t detect it. Also, it resists the exploitation of time delta methods (e.g., RDTSC/RDTSCP) to detect hypervisors' presence, therefore making it much harder for applications, packers, protectors, malware, anti-cheat engines, etc. to discover the debugger.


# Quick Start

A brief overview of how to start with HyperDbg

## Starting with HyperDbg

First of all, you should know about different [**Operation Modes**](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes) and [**Prerequisites** ](https://docs.hyperdbg.org/using-hyperdbg/prerequisites)in HyperDbg.

* [**VMI Mode**](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#vmi-mode)
* [**Debugger Mode**](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#debugger-mode)
* [**Transparent Mode**](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#transparent-mode)

If you want to learn how to use HyperDbg along with practical and real-world examples visit the following tutorial.

* [**OpenSecurityTraining2's Reversing with HyperDbg (Dbg3301)**](https://ost2.fyi/Dbg3301) **\[**[**YouTube**](https://www.youtube.com/playlist?list=PLUFkSN0XLZ-kF1f143wlw8ujlH2A45nZY)**]**

If you want to build HyperDbg, follow the steps in the links below; you can also download compiled binaries instead of building HyperDbg.

* [**Transparent Mode**](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#transparent-mode)
* [**Build & Install**](https://docs.hyperdbg.org/getting-started/build-and-install)
* [**Download Releases**](https://github.com/HyperDbg/HyperDbg/releases)

After that, you need to attach to an instance of HyperDbg.

* [**Local Debugging (VMI Mode)**](https://docs.hyperdbg.org/getting-started/attach-to-hyperdbg/local-debugging)
* [**Debug a Physical Machine (Debugger Mode)**](https://docs.hyperdbg.org/getting-started/attach-to-hyperdbg/debug#physical-machine)
* [**Debug a VMware Workstation Guest (Debugger Mode)**](https://docs.hyperdbg.org/getting-started/attach-to-hyperdbg/debug#vmware-workstation)
* [**Connect to a Remote Machine (VMI Mode)**](https://docs.hyperdbg.org/getting-started/attach-to-hyperdbg/debug#connect-to-debuggee-vmi-mode)
* [**Start a new process (VMI Mode and Debugger Mode)**](https://docs.hyperdbg.org/getting-started/attach-to-hyperdbg/start-process)
* [**Attach to a running process (VMI Mode)**](https://docs.hyperdbg.org/getting-started/attach-to-hyperdbg/attach-process)

Finally, you can see many examples provided in the following link to use HyperDbg.

**User-mode Debugging examples:**

{% content-ref url="/pages/nnQbl2iryNwFGYJqxmyp" %}
[Examples](/using-hyperdbg/kernel-mode-debugging/examples)
{% endcontent-ref %}

**Kernel-mode Debugging examples:**

{% content-ref url="/pages/-MlPA6jTvKp6q6tiYZf2" %}
[Examples](/using-hyperdbg/user-mode-debugging/examples)
{% endcontent-ref %}

**Script engine examples:**

{% embed url="<https://docs.hyperdbg.org/commands/scripting-language/examples>" %}

***Done!** You successfully used HyperDbg Debugger.*

## List of HyperDbg Commands

* [**Debugging Commands**](https://docs.hyperdbg.org/commands/debugging-commands)
* [**Meta Commands**](https://docs.hyperdbg.org/commands/meta-commands)
* [**Extension Commands**](https://docs.hyperdbg.org/commands/extension-commands)

## Scripting Language

* [**Assumptions & Evaluations**](https://docs.hyperdbg.org/commands/scripting-language/assumptions-and-evaluations)
* [**Conditionals & Loops**](https://docs.hyperdbg.org/commands/scripting-language/conditionals-and-loops)
* [**Variables & Assignments**](https://docs.hyperdbg.org/commands/scripting-language/variables-and-assignments)
* [**Script Functions**](https://docs.hyperdbg.org/commands/scripting-language/functions)
* [**Script Examples**](https://docs.hyperdbg.org/commands/scripting-language/examples)
* [**List of Script Functions**](https://docs.hyperdbg.org/commands/scripting-language/functions)

## **More advanced topics...**

If you want to see more advanced topics about HyperDbg.

* [**How to create an action?**](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/how-to-create-an-action)
* [**How to create a condition?**](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/how-to-create-a-condition)

## Things to consider when using HyperDbg

* [**Basic Concepts in Intel VT-x**](https://docs.hyperdbg.org/tips-and-tricks/considerations/basic-concepts-in-intel-vt-x)
* [**VMX root-mode vs VMX non-root mode**](https://docs.hyperdbg.org/tips-and-tricks/considerations/vmx-root-mode-vs-vmx-non-root-mode)
* [**The "unsafe" behavior**](https://docs.hyperdbg.org/tips-and-tricks/considerations/the-unsafe-behavior)
* [**Script engine in VMX non-root mode**](https://docs.hyperdbg.org/tips-and-tricks/considerations/script-engine-in-vmx-non-root-mode)
* [**Difference between process and thread switching commands**](https://docs.hyperdbg.org/tips-and-tricks/considerations/difference-between-process-and-thread-switching-commands)
* [**Transparent Mode**](https://docs.hyperdbg.org/tips-and-tricks/considerations/transparent-mode)

## Miscellaneous topics...

* [**Event Forwarding Mechanism**](https://docs.hyperdbg.org/tips-and-tricks/misc/event-forwarding)
* [**Event short-circuiting Mechanism**](https://docs.hyperdbg.org/tips-and-tricks/misc/event-short-circuiting)
* [**Event calling stages**](https://docs.hyperdbg.org/tips-and-tricks/misc/event-calling-stage)
* [**Instant events**](https://docs.hyperdbg.org/tips-and-tricks/misc/instant-events)
* [**Message Overflow**](https://docs.hyperdbg.org/tips-and-tricks/misc/message-overflow)
* [**Switch to New Process Layout**](https://docs.hyperdbg.org/tips-and-tricks/misc/switch-to-new-process-layout)
* [**Customize Build**](https://docs.hyperdbg.org/tips-and-tricks/misc/customize-build)
* [**Enable and Disable Events in Debugger Mode**](https://docs.hyperdbg.org/tips-and-tricks/misc/enable-and-disable-events-in-debugger-mode)

## HyperDbg Research and Design Internals

* [**HyperDbg Research**](https://research.hyperdbg.org/)
* [**Kernel Debugger Design**](https://research.hyperdbg.org/debugger/kernel-debugger-design.html)
* [**Academic Paper (Reinventing Hardware-Assisted Debugging)**](https://arxiv.org/abs/2207.05676)
* [**VM-exit Transparency in HyperDbg**](https://research.hyperdbg.org/debugger/transparency.html)
* [**Awesome Resources About HyperDbg**](https://github.com/HyperDbg/awesome)
* [**Command Map (HyperDbg to Native Debuggers)**](https://hyperdbg.github.io/commands-map/)
* [**Logo & Graphics**](https://github.com/HyperDbg/graphics)
* [**Scripts**](https://github.com/HyperDbg/scripts)

## If you want to participate in HyperDbg

* [**Coding Style**](https://docs.hyperdbg.org/contribution/style-guide/coding-style)
* [**Command Style**](https://docs.hyperdbg.org/contribution/style-guide/command-style)
* [**Doxygen Style**](https://docs.hyperdbg.org/contribution/style-guide/doxygen-style)
* [**Logo & Artworks**](https://docs.hyperdbg.org/style-guide/logo)

You can also follow the [**contribution guide**](https://github.com/HyperDbg/HyperDbg/blob/master/CONTRIBUTING.md).

## Software Development Kit (SDK)

{% embed url="<https://docs.hyperdbg.org/using-hyperdbg/sdk>" %}

## **Any other questions**

If you have any other questions, then it's probably addressed in the [**FAQ**](https://docs.hyperdbg.org/getting-started/faq) section. If your question remains unanswered or your problem is unsolved, you can create an [**issue**](https://github.com/HyperDbg/HyperDbg/issues).


# FAQ

Frequently Asked Questions (FAQ)

## What is HyperDbg?

HyperDbg is an open-source, hypervisor-assisted [debugger](https://en.wikipedia.org/wiki/Debugger). You can use HyperDbg to debug both user-mode and kernel-mode applications.

## Why do we need HyperDbg?

HyperDbg gives you unique abilities to use modern processor features that will assist you in your reverse engineering journey.

You can see a list of these features [here](https://github.com/HyperDbg/HyperDbg#unique-features).

## How can I learn HyperDbg?

The **OpenSecurityTraining2's "Reversing with HyperDbg (Dbg3301)**" tutorial series, available on [**OST2's website**](https://ost2.fyi/Dbg3301) (*preferred*) and [**YouTube**](https://www.youtube.com/playlist?list=PLUFkSN0XLZ-kF1f143wlw8ujlH2A45nZY) is the recommended way to get started with and learn HyperDbg. It guides you through the initial steps of using HyperDbg, covering essential concepts, principles, and debugging functionalities, along with practical examples and numerous reverse engineering methods that are unique to HyperDbg.

## Who uses HyperDbg?

Programmers, security researchers, malware analyzers, and fuzzer programmers.

## What makes HyperDbg different from classic debuggers?

HyperDbg has a unique architecture. The principles of designing HyperDbg are making an OS-independent debugger and leveraging modern processor features to bring new reverse engineering methods; thus, the features you see in HyperDbg are not available in other debuggers.

## What's the difference between HyperDbg and Windbg?

HyperDbg has a completely different architecture. Windbg operates on ring 0 (kernel) while HyperDbg is running on ring -1 (hypervisor); thus, HyperDbg provides unique features that are not available on Windbg (OS-Level).

Besides that, HyperDbg is not just a simple debugger. It comes up with modern reverse engineering methods by using vt-x and other modern processor facilities to ease reverse engineering, analyzing, and fuzzing.

## Is it only for a special processor? Or can I run it on AMD or ARM processors?

The current version of HyperDbg only supports Intel x64 processors. You cannot run it on an AMD processor or an ARM processor. This is mainly because HyperDbg heavily uses VT-x which is an Intel-based technology, but future versions will support other processors as well.

## What generation of Intel Processors supports HyperDbg?

Your processor should at least support Intel Extended Page Table (A.K.A. EPT), which is introduced on Nehalem Microarchitecture, but most of the functionalities are working on Intel's 4th or later generation; so, the previous processors might have undefined behaviors with some of the functionalities of HyperDbg. Even though most of the functionalities are supported on the 4th generation of Intel Processors but still some minor functionalities need newer processors. It's recommended to use a Skylake (6th generation) processor or newer processors to support all functionalities.

## Can I use it on Linux, FreeBSD or macOS?

No, the current version is only limited to Windows; however, one of our top priorities is to port HyperDbg on Linux, but currently, it's only usable on Windows.

## Should I have a separate machine to use HyperDbg?

Of course not! The only problem with not having a separate machine is that you can only operate on [VMI mode](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#vmi-mode), and you can't pause (halt) the system with breakpoints or for stepping. You can also use VMware Workstation to debug in [debugger mode](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#debugger-mode) with all of the features, including stepping and pausing the debuggee.

## Can I use it on a nested-virtualization environment (VMware, VirtualBox, Hyper-V)?

The current versions of HyperDbg are only tested on VMware Workstation Player (free for non-commercial use) and VMware Workstation Pro, but in future versions, we will support all the virtualization platforms with nested-virtualization.

## How can I start reading about HyperDbg internals? How does it work? Can I contribute to HyperDbg?

The source for reading about hypervisors and HyperDbg internals is [Hypervisor From Scratch](https://rayanfam.com/tutorials/) tutorials.

For contribution, you can follow the [contribution guide](https://github.com/HyperDbg/HyperDbg/blob/master/CONTRIBUTING.md).

You can visit [here ](https://docs.hyperdbg.org/design)to know more about HyperDbg [design ](https://docs.hyperdbg.org/design)internals.


# Build & Install

This document helps you to build and install HyperDbg

## Download & Install

In order to use HyperDbg, you have two options. You can download the [**latest compiled binaries**](https://github.com/HyperDbg/HyperDbg/releases/latest), or manually download the source code and compile the binaries from the source code.

If you download compiled binary files, you can skip the **Build & Compile** section and move to the next section, otherwise, to **build** HyperDbg, you need to install the following software.

**Visual Studio Community, Enterprise, or Professional 2026**

* You can download it at: \[[https://www.visualstudio.com/downloads](https://www.visualstudio.com/downloads/)]

**Windows Software Development Kit (Windows SDK)**

* You can download it at: \[<https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/>]

**Windows Driver Kit (WDK)**

* You can download it at: \[<https://developer.microsoft.com/en-us/windows/hardware/windows-driver-kit>]

{% hint style="warning" %}
HyperDbg is currently compiled with the latest version of **SDK** and **WDK**. If you encounter any problems compiling with previous versions of **SDK**, or **WDK**, you have to update it before compiling HyperDbg.
{% endhint %}

### Build & Compile

First, clone the project using **git** or download precompiled binaries from [here](https://github.com/HyperDbg/HyperDbg/releases).

```
git clone --recursive https://github.com/HyperDbg/HyperDbg.git
```

Open the visual studio and **build** the solution.

After building, you need to disable driver signature enforcement. It is because the current versions of **HyperDbg** are not digitally signed.

For this purpose, you can **Disable Driver Signature Enforcement**.

## Starting with HyperDbg

The rest of this article focuses on the process of installing and setting up HyperDbg. If you prefer a visual guide, you can watch a corresponding video instead of reading through this section.

{% hint style="warning" %}
If, after watching this video and following all the steps, HyperDbg still doesn’t run (for example, if VBS shows as "***Enabled but not running***") or is still "***Running***", you can [manually disable VBS](https://docs.hyperdbg.org/getting-started/build-and-install#disable-vbs-hvci-and-device-guard).
{% endhint %}

{% embed url="<https://www.youtube.com/watch?v=MDZ9zYfqo50>" %}
Starting with HyperDbg
{% endembed %}

## Choosing Environment

You can run HyperDbg on your physical machine in the [VMI Mode](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#vmi-mode) (local debugging), but you can't pause or step through the instruction in this execution mode. If you want to thoroughly use HyperDbg as a debugger (not as a system-log generator), you should use it with a virtual machine in the [Debugger Mode](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#vmi-mode).

HyperDbg works best with VMware Workstation Pro/Player, or VMware ESXi. VMware Workstation Pro is free to download and use.

You can download VMware Workstation at: \[<https://www.vmware.com/products/desktop-hypervisor/workstation-and-fusion>]

## Running HyperDbg

Running HyperDbg has multiple stages. First, you should make sure to enable Intel **VT-x** from the BIOS. Next, you have to disable **Driver Signature Enforcement (DSE)** and turn off **Virtualization Based Security (VBS)**. Then you can run HyperDbg.

{% hint style="success" %}
If you've attempted all the provided instructions without success, we encourage you to initiate a '[discussion](https://github.com/orgs/HyperDbg/discussions)' or ask in one of HyperDbg groups ([Telegram](https://t.me/HyperDbg), [Discord](https://discord.gg/anSPsGUtzN), or [Matrix](https://matrix.to/#/#hyperdbg-discussion:matrix.org)). Outline your issue comprehensively, and we'll be more than happy to assist you in getting started with HyperDbg :)
{% endhint %}

If you want to use HyperDbg on your own computer (**host**), for example for local kernel debugging, you need to disable **Driver Signature Enforcement (DSE**) on your local machine. Disabling DSE allows you to use HyperDbg (load drivers) on your own computer.

But if you want to debug a different computer (a **Guest Virtual Machine**), you don't need to disable it on your own computer (**host**). Instead, you only need to make the necessary changes on the guest machine itself.

In short:

* Disable Driver Signature Enforcement on your own computer (**host**) if you want to run HyperDbg on it for local kernel debugging.
* When debugging a remote guest machine, make the required changes on the guest machine, without disabling Driver Signature Enforcement (DSE) on your own host computer.

Remember, when attaching to a **guest** virtual machine, HyperDbg **does not** load any **drivers** or **hypervisors** on your **host** machine. Instead, it functions as a simple application that connects to the **guest** machine through the serial port and allows you to control it. In other words, HyperDbg acts as a simple bridge between your host machine and the target guest machine. It establishes a connection through the serial port without making any modifications or loading additional software on your host machine. Instead, the drivers and hypervisor will be loaded on the target guest machine.

On the rest of this page, you'll read a detailed explanation of performing the above stages.

### Check for VMX support

This check should be done in the **HOST** machine.

Please note that HyperDbg is currently available only for [Intel](https://docs.hyperdbg.org/getting-started/faq#is-it-only-for-a-special-processor-or-can-i-run-it-on-amd-or-arm-processors) processors.

If you've ever run HyperDbg and encountered the below error, it means that **VT-x** is disabled from your BIOS.

![Disabled VT-x From BIOS](/files/P99tYRIe2NBfAEFyvX46)

Enabling **VT-x** from BIOS is vendor-specific. Usually, if you press \[**F2**], or \[**Delete**], or \[**ESC**] during the boot time, you'll enter the BIOS, and there should be an option to **Support Virtualization** or something like that. You should enable it from BIOS, and after that, you're good to go.

### Disable Driver Signature Enforcement

The next step is disabling **Driver Signature Enforcement (DSE)**.

HyperDbg's driver is **NOT** digitally signed.

In order to disable **driver signature enforcement**, we have plenty of options. However, we recommend the **first option**, which is **attaching WinDbg at the boot time**. It's because this way, PatchGuard will not start, and some of HyperDbg's commands like the '[!syscall](https://docs.hyperdbg.org/commands/extension-commands/syscall)' or the '[!sysret](https://docs.hyperdbg.org/commands/extension-commands/sysret)', which are PatchGuard detectable, will be usable. Alternatively, you can use [EfiGuard](https://github.com/Mattiwatti/EfiGuard) to use bypass both PatchGuard and DSE without using WinDbg.

If you use other options, please keep in mind that you should be cautious as PatchGuard will start and detect some of the modifications that might be problematic.

Disabling **DSE** can be done in three ways (you have to choose one of them):

* Attaching WinDbg at the boot time (**Recommended**)
* Temporarily Disable DSE
* Using [EfiGuard](https://github.com/Mattiwatti/EfiGuard)

#### Disable DSE by Attaching WinDbg

To debug a target Virtual Machine (VM), you need to perform actions on both the **guest** and the **host**. In other words, **WinDbg** is running on the host machine, and you're using it to connect and debug the guest machine. This allows you to analyze and troubleshoot issues within the target VM by using WinDbg (like regular kernel mode debugging by using WinDbg) and when WinDbg attaches to the target VM, it disables both the **Driver Signature Enforcement (DSE)** and if it's connected from the very first start of the Windows boot, it disables **PatchGuard** initialization.

HyperDbg won't import (or need) anything from WinDbg. We only need it to disable **DSE** and **PatchGuard**.

If you choose this option, you can use **kdnet.exe** from Windows SDK, please read [this documentation](https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/setting-up-a-network-debugging-connection-automatically) in order to understand how you can use **kdnet**. After that, performing the actions described [here](https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/setting-up-a-network-debugging-connection-automatically), you'll get a key that can be used on a remote machine to debug this machine using WinDbg, so, run the KDNET in your guest machine and get the keys and use the keys in the host machine.

![Kdnet.exe](/files/R1PWzeaLr0vHbv4J8jUR)

When you load the HyperDbg's driver, you can close the **WinDbg**, and everything is handled in HyperDbg, and no need for WinDbg anymore. We want WinDbg to avoid starting PatchGuard and let us load our unsigned driver.

If your computer has the secure boot enabled, you'll see the following error.

![Kdnet.exe (secure boot)](/files/AsCzI80Gk6Pkpp3PbEZW)

You can disable secure boot from the BIOS. Most of the time, you should change the **secure boot** option to "**Other OSes**" that are not Windows, alternatively you [disable secure boot in VMware](https://www.youtube.com/watch?v=y3o_-AKkf-s\&ab_channel=HowToBasic).

That's it all. We're good to go to the next section.

#### Temporarily Disable DSE

If you couldn't disable the DSE and PatchGuard by using the first option, you can perform this option. The following actions should be done in the **guest** if you want to debug a Virtual Machine (VM).

This is the simplest way to disable driver signature enforcement on Windows 10, and 11 but bear in mind that this method will temporarily disable driver signature enforcement.

After you restart, your computer driver signature enforcement will automatically turn itself on.

To disable driver signature enforcement, do the following:

1. Press and hold the **Shift** key on your keyboard and click the **Restart** button.
2. Choose to **Troubleshoot > Advanced options > Startup Settings** and click the **Restart** button.
3. When your computer restarts, you’ll see a list of options. Press **F7** on your keyboard to select **Disable driver signature enforcement**.
4. Your computer will now restart, and you’ll be able to install unsigned drivers.

Keep in mind that this method only temporarily disables driver signature enforcement, and after a restart, you have to re-disable it again, and also it won't disable the PatchGuard, so, some of the commands that are not PatchGuard compatible **won't** work when you use this method.

#### Using EfiGuard

You can use [EfiGuard](https://github.com/Mattiwatti/EfiGuard) to disable both Driver Signature Enforcement (**DSE**) and PatchGuard. This way, you don't need to use WinDbg.

For more information, please visit the main [repo](https://github.com/Mattiwatti/EfiGuard), or if you want to use it on VMware, you can visit [here](https://muffsec.com/blog/how-to-use-efiguard-to-disable-patchguard/) or this [demo](https://www.youtube.com/watch?v=EJGuJp2fqpM\&ab_channel=ScriptDaddy).

### Disable VBS, HVCI, and Device Guard

The last step before running HyperDbg is disabling **Virtualization Based Security (VBS)**.

Please note that to utilize HyperDbg in a nested-virtualization setup like VMware Workstation, ensure that VBS, Hyper-V is disabled on **both** the **host** and the **guest** machine. Although VMware Workstation and Hyper-V have become compatible, as of the document's current version, VMware Workstation's nested-virtualization feature is not supported when Hyper-V is enabled. Therefore, even if you are running two virtual machines, the **primary host** and the target **guest** debuggee must have Hyper-V disabled.

**HyperDbg** and **VBS** are both hypervisors running on ring -1. These hypervisors are not compatible, and you should disable VBS (and its sub-components like HVCI, Device Guard, etc.).

To check whether VBS is running on your system, type **System Information** on the start menu and click on the **System Information** app. After that, check whether the VBS is **running** or not like the below picture.

![VBS running](/files/9J8xq7g9CzaB0WfhXZnk)

If you see "**Enabled but not running**" or "**Not enabled**", you're good to go to the next step.

In some versions of Windows, VBS may still show as "**Enabled but not running*****"***, yet HyperDbg will not run. In this case, follow the steps in the rest of this article.

![Enabled but not running](/files/Ugzxx6giIVuehnfB8dN7) ![Not enabled](/files/OZhsf8VaA21wqzVbH0Ye)

If the VBS is still enabled, you can disable it by typing "**Core isolation**" on the start menu and turning off "**Memory integrity**".

![Turn off core isolation](/files/bFnGNgqh9p5X1SG5lOoX)

If your system supports '**Firmware protection**' you need to also **disable** it.

<figure><img src="/files/kBIJBTELH1pT0ouf5zR4" alt="Turn off firmware protection"><figcaption><p>Turn off firmware protection</p></figcaption></figure>

If the **Firmware protection** option is disabled and shows the message *“**This setting is managed by your administrator**,”* you can follow [this instruction](https://docs.hyperdbg.org/getting-started/build-and-install#disabling-system-guard). After making this change, close and reopen **Windows Security** to check whether the update takes effect or not.

After that, go to "**Turn Windows features on or off**", and disable "**Virtual Machine Platform**" and "**Windows Hypervisor Platform**".

<figure><img src="/files/zAmNtPoBfCo3bvY5wDSW" alt=""><figcaption><p>Disabling Windows Features</p></figcaption></figure>

The above steps are enough to disable the VBS for older system but if you still have problems, you could follow the rest of this guide. After that, you should restart your computer so that VBS will be disabled on the next start. Once the computer started, check the **System Information** app again to see whether **Virtualization-based security** is disabled or not.

**Done!** The rest of this section describes other methods for disabling VBS, you don't need to follow it if you successfully disabled **VBS**, but if not, please follow the rest of this article.

### Manually Disable Virtualization-Based Security

If the above method didn't work for you, open **Local Group Policy Editor (gpedit.msc)** and navigate to the following path:

```
Local Computer Policy\Computer Configuration\Administrative Templates\System\Device Guard
```

Click on **Turn on Virtualization Based Security**.

![](/files/M7neRKnUknvDYtCCEf0V)

Then choose the '**Disabled**' option and click '**OK**'.

![](/files/0q0BNLz1UyKI5IavDhOm)

There are also other options to disable **VBS** as described [here](https://beebom.com/how-disable-virtualization-based-security-vbs-windows-11/).

After that, you should restart your computer and recheck **System Information** to see if it's still running or not. If it is still running then check the next step.

### Disable Hypervisor Launch Type

If HyperDbg still fails to run because VBS is enabled ("**running**"), execute the following command in Command Prompt with administrator privileges.

```
bcdedit /set hypervisorlaunchtype off
```

Now you need to follow the next step to disable **system guard**.

### Disabling System Guard

To **disable** the system guard, you need to create a **DWORD** registry value called "**Enabled**" at `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\DeviceGuard\Scenarios\SystemGuard`, or simply copy and paste the following script into a `.reg` file and run it as administrator or you can even download it from [here](https://github.com/HyperDbg/starting-hyperdbg-scripts/blob/main/device-guard/disable-system-guard.reg) and run it.

```reg
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\DeviceGuard\Scenarios\SystemGuard]
"Enabled"=dword:00000000
```

Later when you are no longer using HyperDbg and wish to re-enable it, you can apply [this](https://github.com/HyperDbg/starting-hyperdbg-scripts/blob/main/device-guard/enable-system-guard.reg) registry file.

Now, restart your computer again, then check **System Information** to verify whether VBS is still running. If VBS is still enabled and running, your system may have additional protections implemented by your device manufacturer. In that case, review your BIOS (UEFI firmware) settings for any vendor-specific security features, or consider reaching out to the HyperDbg community groups ([Telegram](https://t.me/HyperDbg), [Discord](https://discord.gg/anSPsGUtzN), or [Matrix](https://matrix.to/#/#hyperdbg-discussion:matrix.org)) for assistance.

## Run & Test

Congratulations, you're ready to run HyperDbg.

From now on, you can either,

* [**Attach to a remote machine**](https://docs.hyperdbg.org/getting-started/attach-to-hyperdbg/debug)
* [**Attach to the local machine**](https://docs.hyperdbg.org/getting-started/attach-to-hyperdbg/local-debugging)

or visit [Quick Start](https://docs.hyperdbg.org/getting-started/quick-start) to start using **HyperDbg**.

## Next Step

The **OpenSecurityTraining2's "Reversing with HyperDbg (Dbg3301)**" tutorial series, available on [**OST2's website**](https://ost2.fyi/Dbg3301) (*preferred*) and [**YouTube**](https://www.youtube.com/playlist?list=PLUFkSN0XLZ-kF1f143wlw8ujlH2A45nZY) is the recommended way to get started with and learn HyperDbg. It guides you through the initial steps of using HyperDbg, covering essential concepts, principles, and debugging functionalities, along with practical examples and numerous reverse engineering methods that are unique to HyperDbg.


# Attach to HyperDbg


# Attach to a remote machine

Remote debugging in VMI Mode and Debugger Mode

If you have access to a remote physical machine or a nested virtualization environment like (VMware Workstation, VirtualBox, Hyper-V, etc.), you can **operate** in both [**VMI Mode**](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#vmi-mode) and [**Debugger Mode**](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#debugger-mode).

In **VMI Mode**, you can't break the kernel mode and step through the kernel instructions; still, you can step and break user-mode applications. This mode needs a network connection (TCP).

In **Debugger Mode**, you can break the kernel mode and step through the kernel instructions. It needs a serial (cable or virtual device) to connect to the target machine.

{% hint style="success" %}
If you've attempted all the provided instructions without success, we encourage you to initiate a '[discussion](https://github.com/orgs/HyperDbg/discussions)'. Outline your issue comprehensively, and we'll be more than happy to assist you in getting started with HyperDbg :)
{% endhint %}

## Downloading VMware

HyperDbg works best with VMware Workstation Player/Pro.

You can download VMware Workstation Player (Free Non-commercial License) at: \[<https://www.vmware.com/products/workstation-player/workstation-player-evaluation.html>]

After that, you should install your desired operating system (Windows 10, or 11) on your VMware as a guest. Once you have finished installing your virtual machine, you can continue the rest of this article.

Here is a quick video that describes how to set up HyperDbg with VMware Workstation Pro/Player.

{% embed url="<https://www.youtube.com/watch?v=MDZ9zYfqo50>" %}
Getting Started with HyperDbg
{% endembed %}

## Connect to Debuggee (Debugger Mode)

For connecting in debugger mode, first, you need to provide a serial device.

### **Physical Machine (Host)**

In order to connect to a physical machine in debugger mode, you need a physical serial port. After that, connect your target machine (debuggee) to another machine.

Debuggee needs to support Intel VMX and Intel EPT; however, the debugger does not need to support any special CPU feature and can be run on any machine, including a machine with an AMD processor.

If you want to have a kernel debug connection, first, you should run the following command in a debugger (host). As you can see, you can change the `com3`to your COM port that is connected to the debuggee. You can see connected COM ports on the device manager.

```
HyperDbg> .debug remote serial 115200 com3
```

If you want to use a named pipe instead of a COM port, you can execute the following command in the debugger (Host).

```
HyperDbg> .debug remote namedpipe \\.\pipe\HyperDbgPipe
```

After you tell the debugger to listen on a COM port or a named pipe, now you can run the following command in the debuggee.

```
HyperDbg> .debug prepare serial 115200 com2
```

### **VMware Workstation Player or Pro (Guest)**

In order to run HyperDbg on a VMware Workstation machine, first, turn off your guest machine then, you need to enable **Nested Virtualization**. Open your virtual machine and click on Edit **virtual machine settings**.

You can use both VMware Workstation pro as well as VMware Workstation Player (Free for non-commercial use).

![Editing VM Settings](/files/eKHEP77BLqAoRoIuJRWH)

After that, click on **Virtualize Intel VT-x/EPT or AMD-V/RVI** and **Virtualize IOMMU (IO memory management unit)**.

![Enabling Nested-Virtualization](/files/5hefW0kJF8g5HA47gJ4V)

{% hint style="danger" %}
Please be aware that if you encounter an error indicating that 'nested virtualization is not supported' when attempting to launch the virtual machine at a later time, it could be due to the presence of VBS or Hyper-V running on the host system. It's important to note that VMware Workstation does not offer support for nested virtualization while Hyper-V is active. In order to address this, you must first disable Hyper-V, following the instructions provided [here](https://docs.hyperdbg.org/getting-started/build-and-install).
{% endhint %}

Okay, let's continue to the next step. You should create a serial port here. Click on **Add...** then choose **Serial Port** and click on **Finish**.

![Adding a serial device](/files/ufY5y12j2nA2ARaI75Ee)

Now, click on **Use named pipe:** and add a name for your named pipe.

Your name should start with `\\.\pipe\` . For example, choose `\\.\pipe\HyperDbgDebug`.

Make sure to enable **Yield CPU on poll**.

![Change serial device configuration](/files/ufruutEDiICfWsHZ90V4)

Now it's time to create a kernel debug connection. First of all, run the following command on the host (debugger). You should change the named pipe address to whatever name you chose on the previous part.

```
HyperDbg> .debug remote namedpipe \\.\pipe\HyperDbgPipe
```

After you tell the debugger to listen on a COM port or a named pipe, now you can run the following command in the debuggee (guest).

```
HyperDbg> .debug prepare serial 115200 com2
```

Most of the time, if the serial port is the only serial device that you add to the virtual machine, then the name of the connected port is `com2`. However, you can see the exact name of the COM port on the guest's device manager.

{% hint style="info" %}
If you see an error for driver signature enforcement, please visit [here](https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/beginning/connecting-to-hyperdbg#driver-signature-enforcement-error).
{% endhint %}

Please note that HyperDbg differs from WinDbg as it requires installation in both the target virtual machine and the host. Unlike WinDbg, which only needs to be installed on the host.

To use HyperDbg, the debugger should be started and listening on the host before connecting to it from the guest. Therefore, it is important to execute the commands on the debugger (**host**) first, and then connect to it from the debuggee (**guest**).

**Done!** You successfully connected to the HyperDbg.

The rest of this section is for special cases like if you want to connect HyperDbg from two VMs (without running HyperDbg on the Host), possible errors that you might encounter during the setup, and solutions.

### **VMware Workstation (Two VMs)**

To run HyperDbg on two different guest virtual machines (rather than running it on the host), you can use the following instructions.

First of all, use the instructions provided [above](https://docs.hyperdbg.org/getting-started/attach-to-hyperdbg/debug#vmware-workstation), to create a serial port on both the **debugger** VM and the **debuggee** VM.

#### Serial Port Configuration – Debugger

To configure the **debugger** VM, follow these steps:

1. Enable the option 'Used named pipe' and assign a custom name to the named pipe, such as `\.\pipe\HyperDbgDebug`.
2. Select 'This end is the **server**' and 'The other end is an application.'
3. Ensure that 'Yield CPU on poll' is enabled.

<figure><img src="/files/p7nNiYIYfui7uwvnzn8F" alt=""><figcaption></figcaption></figure>

#### Serial Port Configuration – Debuggee

To configure the **debuggee** VM, follow these steps:

1. Enable the option 'Used named pipe' and use the same name you previously selected for the debugger (e.g., `\.\pipe\HyperDbgDebug`).
2. Select 'This end is the **client**' and 'The other end is an application.'
3. Ensure that 'Yield CPU on poll' is enabled.

<figure><img src="/files/eIv8rRifgVbr9n5Ws7xT" alt=""><figcaption></figcaption></figure>

Once you've done configuring the serial ports, the next step is attaching to HyperDbg. Follow the steps outlined in the next section to establish a connection between the two VMs.

#### Connecting from VMs

On the **debugger** side, open HyperDbg and run the following command to listen on the serial port (ensure to replace "**COM2**" with the specific COM port assigned to your connection, most of the time it is **COM1**, **COM2**, or **COM3**):

```
HyperDbg> .debug remote serial 115200 com2
```

On the **debuggee** side, run the following command.

```
HyperDbg> .debug prepare serial 115200 com2
```

Note that there is a possibility that the COM port assigned to the debuggee and the debugger could be different. For instance, the debugger may be configured to use **COM2**, while the debuggee could be using **COM1**. It is important to take note of this potential difference and ensure that you consider the correct COM port assignments for both the debugger and the debuggee.

**Done!** You can use HyperDbg and control your debuggee from the debugger.

## Connect to Debuggee (VMI Mode)

If you want to run HyperDbg in VMI Mode, you can follow the below steps.

First, make sure you have access to the remote machine by pinging its IP address and checking firewall rules. After that, run the following command in **debuggee (guest)**.

```
HyperDbg> listen
listening on 50000 ...
```

The default port for **HyperDbg** is `50000`, but if you want to choose another port, then add an argument as the port to the listen (e.g. `45000`).

```
HyperDbg> listen 45000
listening on 45000 ...
```

Now, go to your **debugger (host)** system and run the following command. Make sure to change the IP address and port.

```
HyperDbg> .connect 192.168.1.10 50000
connected to 192.168.1.10:50000
```

After that, you see a connected message with an IP address of the debugger (host) in debuggee (guest).

```
HyperDbg> listen
listening on 50000 ...
connected to : 127.0.0.1:52830
```

You can see the state of the debugger by using the '[.status](https://docs.hyperdbg.org/commands/meta-commands/.status)' command.

{% hint style="warning" %}
**Important note:** To utilize HyperDbg in a nested-virtualization setup like VMware Workstation, ensure that Hyper-V it is disabled on **both** the **host** and the **guest** machine. Although VMware Workstation and Hyper-V have become compatible, as of the document's current version, VMware Workstation's nested-virtualization feature is not supported when Hyper-V is enabled. Therefore, even if you are running two virtual machines, the **primary host** must have Hyper-V disabled. For more instructions, please visit [here](https://docs.hyperdbg.org/getting-started/build-and-install).
{% endhint %}

## Disable VBS, and Hyper-V on Host

If you see the error "**Virtualized Intel VT-x/EPT is not supported on this platform.**", you can perform the following instructions to solve it.

<figure><img src="/files/Brw7ibZHFkUWi7iKWMGF" alt="" width="375"><figcaption></figcaption></figure>

First, make sure the VBS, HVCI, or Hyper-V is disabled in the Host as described [here](https://docs.hyperdbg.org/getting-started/build-and-install). If it didn't solve the problem, you can run the following command (as administrator) and restart your computer to disable hypervisor auto-launch.

```
bcdedit /set hypervisorlaunchtype off
```

Once you're done with using HyperDbg, if you want to re-enable Hyper-V, you can run the following command (as administrator) and restart your computer.

```
bcdedit /set hypervisorlaunchtype auto
```

## Next Step

The **OpenSecurityTraining2's "Reversing with HyperDbg (Dbg3301)**" tutorial series, available on [**OST2's website**](https://ost2.fyi/Dbg3301) (*preferred*) and [**YouTube**](https://www.youtube.com/playlist?list=PLUFkSN0XLZ-kF1f143wlw8ujlH2A45nZY) is the recommended way to get started with and learn HyperDbg. It guides you through the initial steps of using HyperDbg, covering essential concepts, principles, and debugging functionalities, along with practical examples and numerous reverse engineering methods that are unique to HyperDbg.


# Attach to local machine

Local debugging in VMI Mode

If you want to debug your local machine without any remote physical machine or nested virtualization (like VMware Workstation, VirtualBox, Hyper-V, etc.), you should use **local debugging**.

Generally, you can use most of the features of **HyperDbg.** Still, you should be cautious because if you unintentionally change any operating system's kernel structure that you did not suppose to, then a BSOD will happen.

Some features like a break to the debugger and step kernel-mode instructions are not possible in local debugging; however, you can use these features for user-mode apps without any limitation. Of course, you can use almost all the kernel-mode features.

For **local debugging**, you can run `.connect local` the command to connect to the local debugger.

```
HyperDbg> .connect local
local debugging (vmi-mode)
```

You can then use the '[load](https://docs.hyperdbg.org/commands/debugging-commands/load)' command to load your module (for instance, **vmm** module).

```
HyperDbg> load vmm
loading the vmm driver
current processor vendor is : GenuineIntel
virtualization technology is vt-x
vmx operation is supported by your processor
vmm module is running...
```

**When you connect to the local debugger, you are operating in** [**VMI Mode**](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#vmi-mode)**.**

## Next Step

The **OpenSecurityTraining2's "Reversing with HyperDbg (Dbg3301)**" tutorial series, available on [**OST2's website**](https://ost2.fyi/Dbg3301) (*preferred*) and [**YouTube**](https://www.youtube.com/playlist?list=PLUFkSN0XLZ-kF1f143wlw8ujlH2A45nZY) is the recommended way to get started with and learn HyperDbg. It guides you through the initial steps of using HyperDbg, covering essential concepts, principles, and debugging functionalities, along with practical examples and numerous reverse engineering methods that are unique to HyperDbg.


# Start a new process

Starting a process from entrypoint

Starting to debug a user-mode process from the start **entrypoint** of the module is one of the essential tasks that debuggers can do, and HyperDbg is no exception.

In HyperDbg, starting a process is possible in [VMI Mode](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#vmi-mode) and [Debugger Mode](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#debugger-mode).

HyperDbg won't use any Windows API for intercepting and pausing threads, and everything is done at the hypervisor level.

{% hint style="danger" %}
The user-mode debugger is still in the beta version and not stable. We decided to exclude it from this release and release it in future versions. If you want to test the user-mode debugger in **VMI Mode**, you should build HyperDbg with special instructions. Please follow the instruction [here](https://docs.hyperdbg.org/getting-started/build-and-install#activating-user-mode-debugger).

In contrast with the kernel debugger, the user debugger is still very basic and needs a lot of tests and improvements. We **highly recommend** not to run the user debugger in your bare metal system. Instead, run it on a [supported virtual machine](https://docs.hyperdbg.org/tips-and-tricks/nested-virtualization-environments/supported-virtual-machines) so you won't end up with a Blue Screen of Death (BSOD) in your primary device. Please keep reporting the issues to improve the user debugger.
{% endhint %}

First, you need to either [connect to the local debugger](https://docs.hyperdbg.org/getting-started/attach-to-hyperdbg/local-debugging) or a [remote debugger over a serial port](https://docs.hyperdbg.org/getting-started/attach-to-hyperdbg/debug).

After that, you should use the "[.start](https://docs.hyperdbg.org/commands/meta-commands/.start)" command to run the process from the path in the target machine.

```
HyperDbg> .start path c:\Windows\system32\notepad.exe
```

You can also specify the parameters of the target executable.

```
HyperDbg> .start path c:\Windows\system32\notepad.exe c:\myfolder\myfile.txt
```

HyperDbg will run the process and put a breakpoint on the entrypoint of the process. Once the process reaches the entrypoint (loading module is finished), the debugger is paused again and gives the control back to the user or kernel debugger.

![Starting an EXE and running until entrypoint](/files/jHLMPiqeXy1Xtrd5FvM7)

If you're using a **kernel debugger**, everything (including the operating system) is halted, and you can debug the process normally.

If you're using the **user debugger**, the thread is paused and waits for the commands from the debugger.

For example, we used the '[t](https://docs.hyperdbg.org/commands/debugging-commands/t)' command to step through the instructions.

After running the '[g](https://docs.hyperdbg.org/commands/debugging-commands/g)' command, the target process is continued normally.

![Continue the target process](/files/83FzxhDI0S4Bkupfoov4)

If you want to pause the debuggee again, you can use the '[pause](https://docs.hyperdbg.org/commands/debugging-commands/pause)' command or press **CTRL+C**.

Note that pausing the target thread is only possible in user debugger, **not** kernel debugger. Also, you should keep interacting with the process to force the process to run its codes in user-mode so HyperDbg will intercept more threads.

![Pausing the target process](/files/0zDsoerHkOqcmagNFti2)

At last, when we finished our debugging procedure, we can use the '[.detach](https://docs.hyperdbg.org/commands/meta-commands/.detach)' command to detach from the target process. Detaching from the process only makes sense in the user debugger.

![Detaching from the process](/files/wBCE9ZeZ7KDxN0Hf9KDF)

In this article, we've learned how to start a process and halt at the entrypoint. You might want to **attach** to an already running process. For this purpose, please read the article [**here**](https://docs.hyperdbg.org/getting-started/attach-to-hyperdbg/attach-process).


# Attach to a running process

Attaching to an already running process

Attaching to an already running process is crucial for debugging. HyperDbg implemented attaching in [VMI Mode](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#vmi-mode). If you want to use this mechanism in [Debugger Mode](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#debugger-mode), you can use the '[.process](https://docs.hyperdbg.org/commands/meta-commands/.process)' and the '[.thread](https://docs.hyperdbg.org/commands/meta-commands/.thread)' commands.

{% hint style="danger" %}
The user-mode debugger is still in the beta version and not stable. We decided to exclude it from this release and release it in future versions. If you want to test the user-mode debugger in **VMI Mode**, you should build HyperDbg with special instructions. Please follow the instruction [here](https://docs.hyperdbg.org/getting-started/build-and-install#activating-user-mode-debugger).

In contrast with the kernel debugger, the user debugger is still very basic and needs a lot of tests and improvements. We **highly recommend** not to run the user debugger in your bare metal system. Instead, run it on a [supported virtual machine](https://docs.hyperdbg.org/tips-and-tricks/nested-virtualization-environments/supported-virtual-machines) so you won't end up with a Blue Screen of Death (BSOD) in your primary device. Please keep reporting the issues to improve the user debugger.
{% endhint %}

Please make sure to read the user debugger's [**principles**](https://docs.hyperdbg.org/using-hyperdbg/user-mode-debugging/principles) before using the '[.attach](https://docs.hyperdbg.org/commands/meta-commands/.attach)' command.

After [connecting to the debuggee in VMI Mode (local debugging)](https://docs.hyperdbg.org/getting-started/attach-to-hyperdbg/local-debugging), you can run the following command to start the "[**Thread Interception**](https://docs.hyperdbg.org/using-hyperdbg/user-mode-debugging/principles#what-to-know)" phase.

```
HyperDbg> .attach pid 1ac0
```

The process Id should be in **hex** format. We chose "**mspaint**" for debugging.

![Attaching to the target process](/files/3RQMCO99TBmD75e8VcOx)

After intercepting the user mode running threads, we can now step through the instructions.

Note that all the intercepted threads are halted when running a single-step command.

![Stepping through the instructions](/files/9bxWDvq4DPByZiuxU2GP)

Next, if you run the '[g](https://docs.hyperdbg.org/commands/debugging-commands/g)' command, HyperDbg will normally continue the target debuggee process.

![Continuing the target process](/files/JBhe7tt0UVf0CYPoThuv)

If you want to pause the debuggee and intercept the user running threads again, you can either use the '[pause](https://docs.hyperdbg.org/commands/debugging-commands/pause)' command or press **CTRL+C**.

Note that you should keep interacting with the process to force the process to run its codes in user-mode so HyperDbg will intercept more threads.

![Pausing the target process](/files/0zDsoerHkOqcmagNFti2)

Finally, we can detach from the target process by using the '[.detach](https://docs.hyperdbg.org/commands/meta-commands/.detach)' command.

![Detaching from the target process](/files/ItVhu2JTOBXKCKFjse28)

In this article, we've learned how to use the user debugger to attach to the target process. Please read the article [**here**](https://docs.hyperdbg.org/getting-started/attach-to-hyperdbg/start-process) if you want to start a process and debug it from the **entrypoint**.


# Prerequisites

This document contains essential notes that you should know before starting with HyperDbg

In HyperDbg, there is a fundamental term called "**event**". Each time you use HyperDbg, you set a special event; for instance, imagine you want to intercept system-calls. You should set up an event that will be triggered in the case of a syscall execution, or when you set a hidden hook event on a particular function.

Whenever these events are triggered, HyperDbg performs specific actions that are configured by you.

#### What are HyperDbg's actions?

HyperDbg has three types of actions. These actions are **Break**, **Script**, **Custom Codes**.

**Break** is exactly like classic-debuggers, where all of the cores are paused and won't run any instruction without the debugger's permission. (This feature is not available in local debugging).

**Script** is a feature that helps you view the parameters, registers, and memory without breaking into the debugger and running your custom script. You can use it when you want to analyze your target, and it creates the logs or run codes in the kernel.

It's much faster than exiting to the debugger and continues from there as all of these logging mechanisms are done in the kernel, and you see the messages in user-mode.

**Custom Codes** gives you the ability to run your custom assembly codes whenever a special event is triggered; this option is fast and powerful as you can customize the HyperDbg based on your needs.

#### What are the conditions?

Each event will be triggered only in two situations. First, you set a particular condition for the event (**conditionally**), so each time the event is triggered, and the condition is met, then your selected action is performed.

The second situation is when you didn't put any conditions (**unconditionally**), so it will be triggered when that event happens, and there is no condition check.


# Operation Modes

Different Modes of Operation in HyperDbg

In **HyperDbg**, we operate in **three** different operation modes.

The first and the basic mode of operation for **local** and **remote debugging** is **VMI Mode**. The second mode is **Debugger Mode,** and the third mode is **Transparent Mode**.

## VMI Mode

If you want to use **HyperDbg**, you should operate at least in **VMI Mode** or **Virtual Machine Introspection Mode**. In both local debugging and remote debugging, **VMI Mode** should be enabled.

**VMI Mode** offers a conventional debugging experience by providing access to all HyperDbg features (including debugging, halting, and stepping **user-mode** applications), with the only exceptions being breaking to the debugger and step instructions in **kernel-mode**. It also allows for using scripts and custom codes in both user-mode and kernel-mode for local or remote debugging.

Based on **HyperDbg** [actions](https://docs.hyperdbg.org/using-hyperdbg/prerequisites), only **break to the debugger** for **kernel-mode** (not user mode) is not available in this mode, and you can use scripts and custom codes in both user-mode and kernel-mode.

You can use this mode in both **local debugging** and **remote debugging**.

## Debugger Mode

If you want to use **HyperDbg** to the kernel and halt the system to step in and step out through the kernel instructions, then you should use this mode of operation.

It is obvious that you can't use this mode for **local debugging,** and you should provide a system with a **serial cable** or **virtual serial** device to enable it.

If you are not trying to break and halt the system for stepping and instrumenting instructions, then use **VMI Mode** instead. It is because, in **VMI Mode,** the connection is over TCP, which is substantially faster than using a serial device.

## Transparent Mode

**Transparent Mode** is an entirely different concept.

If you enable this mode, then **HyperDbg** tries to make itself transparent from anti-debugging and anti-hypervisor methods and not reveal the hypervisor's presence on timing and microarchitectural attacks; however, it won't guarantee 100% transparency, but it makes it substantially harder for the anti-debugging methods.

To enable this mode, you should use the '[!hide](https://docs.hyperdbg.org/commands/extension-commands/hide)' and '[!unhide](https://docs.hyperdbg.org/commands/extension-commands/unhide)' commands.

You can use **Transparent Mode** in both **VMI Mode** and **Debugger Mode**.


# How to create a condition?

This document helps you to create a condition for events

HyperDbg supports the creation of conditional events. Each event has one [condition ](https://docs.hyperdbg.org/design/debugger-internals/conditions)and can have multiple [actions](https://docs.hyperdbg.org/design/debugger-internals/actions).

An unconditional event is an event that all its actions will be executed without any condition. This document is a brief on how to create a conditional event.

Each command in HyperDbg that is tagged as an "**event**" in the document follows the same structure described [here](https://docs.hyperdbg.org/design/debugger-internals/events). At the time you execute a command, you can add a `condition { xx xx xx xx }` where `xx` is the assembly (hex) of what you want to be executed in the case of that event.

Starting from **v0.10**, HyperDbg supports direct assembly code in the condition section. You can add `asm condition { asm1; asm2; asm3; asm4}` where you can add any assembly code to be executed in the case of that event.

For example, let's imagine we want to create a condition for a command like "**!epthook**".

When you execute the command like :

```c
HyperDbg> !epthook fffff801deadbeef
```

then it is unconditional, but when you execute a command like this:

```c
HyperDbg> !epthook fffff801deadbeef condition { 90 90 90 90 }
```

or a command like this:

```
HyperDbg> !epthook fffff801deadbeef asm condition { nop; nop; nop; nop; }
```

then it is a conditional command.

{% hint style="success" %}
Note that you can use all of the events in the same way (instead of **!epthook**). For example, you can use **!syscall, !sysret, !epthook2, !ioin,** etc.
{% endhint %}

### Parameters to Conditions

```cpp
typedef UINT64
DebuggerCheckForCondition(PGUEST_REGS Regs, PVOID Context);
```

Conditions will be executed like the above function so that you can expect a pointer to target debuggee's general-purpose registers on `rcx` and a **Context** in `rdx`.

The structure for general-purpose registers is :

```cpp
typedef struct _GUEST_REGS
{
    ULONG64 rax; // 0x00
    ULONG64 rcx; // 0x08
    ULONG64 rdx; // 0x10
    ULONG64 rbx; // 0x18
    ULONG64 rsp; // 0x20 
    ULONG64 rbp; // 0x28
    ULONG64 rsi; // 0x30
    ULONG64 rdi; // 0x38
    ULONG64 r8;  // 0x40
    ULONG64 r9;  // 0x48
    ULONG64 r10; // 0x50
    ULONG64 r11; // 0x58
    ULONG64 r12; // 0x60
    ULONG64 r13; // 0x68
    ULONG64 r14; // 0x70
    ULONG64 r15; // 0x78
    
} GUEST_REGS, *PGUEST_REGS;
```

The `Context` is a special variable that shows an essential parameter of an event. This value is different for each event. You should check the documentation of that command for more information about the `Context`. For example, `Context` for **!syscall** command is the syscall-number or for the **!epthook2** command is the physical address of where the hidden hook triggered.

## Example 1

Imagine we want to check for the name of the process, so only if the name contains the "**svchost.exe**" then triggers the event's action(s).

We all know that you can search for the name of the process in its `_EPROCESS`.

![](/files/6vJcKsZst30Yv6Qd9lps)

For example, **ImageFileName** in **\_EPROCESS** contains the 15 characters of the process name. It is not where Windows shows the name in Task Manager but checking this value is enough.

The following assembly code gets the current `_KTHREAD` from `_KPCR`. From there, we can find the address of `_KPROCESS`, and this structure is located at the start address of `_EPROCESS`.

As you can see from the above picture, **ImageFileName** is located at `+0x450` after the `_EPROCESS`.

So our final assembly code is like this :

![](/files/CkoGrfJWxFnpjEqbEM1m)

{% hint style="warning" %}
The offsets of `_EPROCESS`and other structures might change in the different versions of Windows.
{% endhint %}

Now we should assemble the above code into its hex representation in the assembly. For example, you can use an [online assembler](http://defuse.ca/online-x86-assembler.htm).

Keep in mind that if you return with `rax=0` or `null` then it means **false**, and if you return anything other than zero (for example `rax=1`) then it means **true**.

If you return true, then all the actions of that event will be executed, and if you return **false**, then **HyperDbg** ignores the actions of that event.

The final result of the assembler is :

```c
0:  65 48 8b 04 25 88 01    mov    rax,QWORD PTR gs:0x188
7:  00 00
9:  48 8b 80 b8 00 00 00    mov    rax,QWORD PTR [rax+0xb8]
10: 48 8b 80 50 04 00 00    mov    rax,QWORD PTR [rax+0x450]
17: 48 b9 73 76 63 68 6f    movabs rcx,0x2e74736f68637673
1e: 73 74 2e
21: 48 39 c8                cmp    rax,rcx
24: 74 05                   je     2b <ReturnTrue>
26: 48 31 c0                xor    rax,rax
29: eb 07                   jmp    32 <Return>
000000000000002b <ReturnTrue>:
2b: 48 c7 c0 01 00 00 00    mov    rax,0x1
0000000000000032 <Return>:
32: c3                      ret
```

Now you can call the command with the following arguments :

```c
HyperDbg> !epthook fffff801deadbeef condition {65488B042588010000488B80B8000000488B805004000048B9737663686F73742E4839C874054831C0EB0748C7C001000000C3}
```

or

```c
HyperDbg> !syscall condition {65488B042588010000488B80B8000000488B805004000048B9737663686F73742E4839C874054831C0EB0748C7C001000000C3}
```

We automatically add a `0xc3` or `ret` the opcode to the end of the condition assembly, and in the case if you forget to return the control of the processor back to the **HyperDbg**, then there is no problem. Make sure to not jump to another address without returning back to the **HyperDbg**. Otherwise, it causes a crash on your system.

## Example 2

Sometimes we need to read the registers and decide based on them. For example, let's imagine we want to hook `ExAllocatePoolWithTag` and if the size of the requested buffer is `xx` then perform the actions.

This function (`ExAllocatePoolWithTag`) is defined like this :

```cpp
PVOID ExAllocatePoolWithTag(
  POOL_TYPE                                      PoolType,
  SIZE_T                                         NumberOfBytes,
  ULONG                                          Tag
);
```

It's obvious that based on the x64 fastcall calling convention in Windows, `PoolType` is on `rcx`, `NumberOfBytes` is on `rdx` and `Tag` is on `r8`. We need to check for `rdx`.

Note that `rdx` is not the same as the `rdx` that you receive in the function, instead we pass a structure containing all the general-purpose register, you can read them or even modify them, and if you modify them, then the operating system will continue with new values in these registers.

For general-purpose registers, we pass a pointer to the following structure as the first argument on `rcx`.

```cpp
typedef struct _GUEST_REGS
{
    ULONG64 rax; // 0x00
    ULONG64 rcx; // 0x08
    ULONG64 rdx; // 0x10
    ULONG64 rbx; // 0x18
    ULONG64 rsp; // 0x20 
    ULONG64 rbp; // 0x28
    ULONG64 rsi; // 0x30
    ULONG64 rdi; // 0x38
    ULONG64 r8;  // 0x40
    ULONG64 r9;  // 0x48
    ULONG64 r10; // 0x50
    ULONG64 r11; // 0x58
    ULONG64 r12; // 0x60
    ULONG64 r13; // 0x68
    ULONG64 r14; // 0x70
    ULONG64 r15; // 0x78
} GUEST_REGS, *PGUEST_REGS;
```

{% hint style="info" %}
If you want to change or examine other registers like XMM registers, floating-point registers, or other registers, you can change and examine them directly.
{% endhint %}

In the following example, we want to check `NumberOfBytes (rdx)` with `0x1000` and if the requested size is **0x1000**, then the actions should be performed.

```cpp
mov rbx , [rcx+0x10]  ; rbx now conains the rdx of the guest [target debuggee]
cmp rbx, 0x1000       ; compare rbx with 0x1000
je ReturnTrue

xor rax,rax
jmp Return

ReturnTrue :
mov rax, 0x1

Return:
ret
```

After using assembler to convert the above code to hex representation of assembly, the final command will be like this :

```cpp
HyperDbg> !epthook2 fffff800`4ed6f010 condition {488B59104881FB0010000074054831C0EB0748C7C001000000C3}
```

One important note is that if you want to create a condition for **!syscall** command, which is common, then you should know that the syscall calling convention is fastcall (`rcx`, `rdx`, `r8`, `r9` and stack), so if your target user-mode application is x64, then you can expect the exact arguments from user-mode to kernel-mode. Still, if your user-mode application is x86, then Windows might change some of the arguments that contain addresses to new addresses.

## Example 3

Now, let's run the above code by using the assembly code directly without converting them to hexadecimal by using HyperDbg's [assembler](https://www.keystone-engine.org/):

```wasm
HyperDbg> !epthook2 fffff800`4ed6f010 asm condition {
		mov rbx , [rcx+0x10];
		cmp rbx, 0x1000;
		je ReturnTrue;

		xor rax,rax;
		jmp Return;

		ReturnTrue:
		mov rax, 0x1;

		Return:
		ret;
}
```

The above code uses the internal assembler of HyperDbg.

{% hint style="danger" %}
Accessing random memory in **custom code** and **condition code** in vmx root-mode is considered "[unsafe](https://docs.hyperdbg.org/tips-and-tricks/considerations/the-unsafe-behavior)". You have some limitations on accessing memory on some special events.
{% endhint %}


# How to create an action?

This document helps you to create an action for events

[Actions ](https://docs.hyperdbg.org/design/debugger-internals/actions)are an essential part of the [events](https://docs.hyperdbg.org/design/debugger-internals/events).

Each event consists of zero or multiple actions. An event with zero actions is treated as a disabled event.

There are three types of actions in HyperDbg as described [here](https://docs.hyperdbg.org/using-hyperdbg/prerequisites).

You can have multiple "**Custom Codes**", "**Script**", and "**Break**".

This document is a brief of how to create actions for an event.

#### Pre-Allocated Buffers

There are many limitations when your script is running in vmx-root. To address these limitations, HyperDbg employs pre-allocated buffers.

**Pre-allocated buffers** are a buffer that HyperDbg previously allocated from the non-paged pool resource of the system as it is dedicated to being used within the events.

You can use these buffers safely from vmx-root to save your temporary variables or needed data. Keep in mind that there is only one pre-allocated buffer for an event, so if you want to access it from different cores, you should consider using spinlock functions to avoid concurrency.

### Break

Break to the debugger, works exactly like classic debuggers like Windbg.

If you simply use the command without any extra parameters, it will be treated like classic debuggers, and HyperDbg gives the system control to the debugger.

### Script

Custom vmx-root mode compatible [script engine](https://docs.hyperdbg.org/commands/scripting-language) is another feature for HyperDbg.

You can use scripts within events by specifying your script within `script {` and `}` in the event's command.

Note that when the event is triggered, you can modify memory and registers, and when each event is triggered, it has its own set of registers, context, and memory layout. You should keep in mind that each event might be triggered simultaneously within different cores.

A pointer to the pre-allocated buffer for the target event is available in the `$buffer` pseudo-register.

There are different examples of using the script engine effectively within events [here](https://docs.hyperdbg.org/commands/scripting-language/examples).

### Custom Codes

**Run custom code** lets you run your custom assembly codes whenever a special event is triggered; this option is fast and powerful as you can customize the HyperDbg based on your needs.

{% hint style="danger" %}
Accessing random memory in **custom code** and **condition code** is considered "[unsafe](https://docs.hyperdbg.org/tips-and-tricks/considerations/the-unsafe-behavior)". You have some limitations on accessing memory on some special events.
{% endhint %}

### Run custom code without a safe buffer

Each command in HyperDbg that is tagged as "**event**" in the document follows the same structure described [here](https://docs.hyperdbg.org/design/debugger-internals/events). At the time you execute a command, you can add a `code { xx xx xx xx }` where `xx` is the assembly (hex) of what you want to be executed in the case of that event.

Starting from **v0.10**, HyperDbg supports direct assembly code in the code sections. You can add `asm code { asm1; asm2; asm3; asm4}` where you can add any assembly code to be executed in the case of that event.

Generally, the assembly `code` in the code block will be called in the following form.

```c
typedef PVOID
DebuggerRunCustomCodeFunc(PVOID PreAllocatedBufferAddress, PGUEST_REGS Regs, PVOID Context);
```

As it called in the fastcall calling convention, **PreAllocatedBufferAddress** will be on `rcx`, **Regs** will be on `rdx` and **Context** is on `r8`.

**PreAllocatedBufferAddress** is the address of a non-paged safe buffer, which is passed to the function on `rcx`. (more about it later).

**Regs**, for general-purpose registers, we pass a pointer to the following structure as the second argument on `rdx`.

```cpp
typedef struct _GUEST_REGS
{
    ULONG64 rax; // 0x00
    ULONG64 rcx; // 0x08
    ULONG64 rdx; // 0x10
    ULONG64 rbx; // 0x18
    ULONG64 rsp; // 0x20 
    ULONG64 rbp; // 0x28
    ULONG64 rsi; // 0x30
    ULONG64 rdi; // 0x38
    ULONG64 r8;  // 0x40
    ULONG64 r9;  // 0x48
    ULONG64 r10; // 0x50
    ULONG64 r11; // 0x58
    ULONG64 r12; // 0x60
    ULONG64 r13; // 0x68
    ULONG64 r14; // 0x70
    ULONG64 r15; // 0x78
} GUEST_REGS, *PGUEST_REGS;
```

The **Context** is a special variable that shows an essential parameter of the event. This value is different for each event. You should check the documentation of that command for more information about the `Context`. For example, `Context` for **!syscall** command is the syscall-number or for the **!epthook2** command is the physical address of where the hidden hook triggered. Context is passed to the custom code as the third argument on `r8` .

{% hint style="warning" %}
**PreAllocatedBufferAddress (rcx)** is always *NULL* in **Run custom code without a safe buffer**, and it's used in **Run custom code with a safe buffer**.
{% endhint %}

As an example, we want to find the *TAG* (**ExAllocatePoolWithTag**). If the tag is a special value, then we want to change it to a new value.

As you know, ExAllocatePoolWithTag in Windows is defined as:

```c
PVOID ExAllocatePoolWithTag(
  POOL_TYPE                                      PoolType,
  SIZE_T                                         NumberOfBytes,
  ULONG                                          Tag
);
```

Based on the x64 calling convention, the parameters are passed as **rcx**, **rdx**, **r8**, **r9,** and stack and *Tag* is on **r8**.

As you know, if you want to change a register in the target OS, you have to find the register in *Regs* and change it from there. Based on `_GUEST_REGS`, **r8** is on **0x40** from the top of this structure.

Take a look at the following assembly code. It first checks whether the *Tag* (**r8**) is **HDBG**, and if it's **HDBG**, then we change it to **HDB2**.

<figure><img src="/files/dTFBWA4YVHrL8rzyjZ1X" alt=""><figcaption></figcaption></figure>

When we convert the above code to assembly, then we have the following code :

```c
0:  48 8b 5a 40             mov    rbx,QWORD PTR [rdx+0x40]
4:  48 81 fb 48 44 42 47    cmp    rbx,0x47424448
b:  74 02                   je     f <ChangeIt>
d:  eb 08                   jmp    17 <Return>
000000000000000f <ChangeIt>:
f:  48 c7 42 40 48 44 42    mov    QWORD PTR [rdx+0x40],0x32424448
16: 32
0000000000000017 <Return>:
17: c3                      ret
```

Imagine, the **ExAllocatePoolWithTag** is located at ``fffff800`4ed6f010``. We can hook and change the Tag using the following command.

```c
HyperDbg> !epthook2 fffff800`4ed6f010 code {488B5A404881FB484442477402EB0848C7424048444232C3}
```

### Run custom code using assembler

Instead of using hexadecimal codes, you can directly use HyperDbg's [assembler](https://www.keystone-engine.org/). The following command is the same as the above command but uses HyperDbg's internal assembler.

<pre class="language-wasm"><code class="lang-wasm"><strong>HyperDbg> !epthook2 fffff800`4ed6f010 asm code {
</strong>		mov    rbx, QWORD PTR [rdx+0x40];
		cmp    rbx, 0x47424448;
		
		je     ChangeIt;
		jmp    Return;
		
		ChangeIt:
		mov    QWORD PTR [rdx+0x40], 0x32424448;
		
		Return:
		ret;
}
</code></pre>

### Run custom code with a safe buffer

The difference between "**Run custom code without a safe buffer**" and "**Run custom code with a safe buffer**" is that you have an extra parameter, called `buffer xx` where `xx` is the hex length of the buffer.

{% hint style="danger" %} The **PreAllocatedBufferAddress** is just one buffer. You have to know how many cores you have. If there are two or more cores that might use the buffer simultaneously, you have to use a special location (offset from the top of the buffer) for each core to avoid race conditions and unintended behavior. {% endhint %}

You can use the buffer which is available in `rcx`.


# Signatures

Different signatures in HyperDbg

There are a few signatures in HyperDbg that demonstrate basic debugging details from the debuggee. In this document, we'll talk about these signatures and their meanings.

### Local Debugging (VMI Mode)

If you're not connected to any instance of **HyperDbg**, or if you're debugging the **local** computer in [VMI Mode](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#vmi-mode), then you'll see the following signature.

```
HyperDbg> 
```

### Kernel Debugging (Debugger Mode)

When you're connected to a remote debuggee in [Debugger Mode](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#debugger-mode) by using the '[.debug](https://docs.hyperdbg.org/commands/meta-commands/.debug)' command, you'll see the `kHyperDbg` signature. The first number is the current operating **core** number. For example, the following signature shows that we're running our commands in core `0x2`. Note that the core number is in **hex** format.

```
2: kHyperDbg> 
```

### User Debugging (VMI Mode)

User-mode debugging has two different signatures, the first signature is for 32-bit module debugging, and the second signature is for 64-bit module debugging.

#### Debugging a 32-bit Module

The signature for 32-bit debugging is `u86HyperDbg` while the first number shows the active **Process Id** and the second number is the **Thread Id**. For example, the following signature is a 32-bit debugging for a process with Process Id equal to `0x228c` and Thread Id equal to `0x13fc`. The Process Id and the Thread Id are in **hex** format.

For a **paused** thread:

```
228c:13fc (paused) u86HyperDbg>
```

For a **running** thread:

```
228c:13fc (running) u86HyperDbg>
```

#### Debugging a 64-bit Module

The signature for 64-bit debugging is `u64HyperDbg` . The numbers are exactly like 32-bit debugging. The first number shows the active **Process ID**, and the second number is the **Thread ID**. For example, the following signature is a 64-bit debugging for Process Id equal to `0x2300` and Thread Id equal to `0x1620`. The Process ID and the Thread ID are in **hex** format.

For a **paused** thread:

```
2300:1620 (paused) u64HyperDbg>
```

For a **running** thread:

```
2300:1620 (running) u64HyperDbg>
```

### Remote Debugging (VMI Mode)

If you're connected to a remote machine using '[.listen](https://docs.hyperdbg.org/commands/meta-commands/.listen)', and '[.connect](https://docs.hyperdbg.org/commands/meta-commands/.connect)' commands, the signature starts with the **IP** of the debuggee and the **port** of the connection to the debuggee. For example, in the following signature, we're connected to a debuggee with an IP address equal to `192.168.1.10`, and the port address for the connection `50000`. The IP address and the port number are in **decimal** format.

```
[192.168.1.10:50000] HyperDbg> 
```


# User-mode Debugging

{% hint style="danger" %}
The user-mode debugger is still in the beta version and not stable. We decided to exclude it from this release and release it in future versions. If you want to test the user-mode debugger in **VMI Mode**, you should build HyperDbg with special instructions. Please follow the instruction [here](https://docs.hyperdbg.org/getting-started/build-and-install#activating-user-mode-debugger).

In contrast with the kernel debugger, the user debugger is still very basic and needs a lot of tests and improvements. We **highly recommend** not to run the user debugger in your bare metal system. Instead, run it on a [supported virtual machine](https://docs.hyperdbg.org/tips-and-tricks/nested-virtualization-environments/supported-virtual-machines) so you won't end up with a Blue Screen of Death (BSOD) in your primary device. Please keep reporting the issues to improve the user debugger.
{% endhint %}


# Principles

Principles of designing a standalone user-mode debugger

HyperDbg is a unique debugger. The intention of creating this tool was, of course, not just debugging. Regardless of debugging components, it also aims to bring a framework to use the innovative feature of processors for debugging and analyzing binaries. Here we discuss some of the principles of the user debugger.

{% hint style="danger" %}
In contrast with the kernel debugger, the user debugger is still very basic and needs a lot of tests and improvements. We **highly recommend** not to run the user debugger in your bare metal system. Instead, run it on a [supported virtual machine](https://docs.hyperdbg.org/tips-and-tricks/nested-virtualization-environments/supported-virtual-machines) so you won't end up with a Blue Screen of Death (BSOD) in your primary device. Please keep reporting the issues to improve the user debugger.
{% endhint %}

### Design Goals

In the user debugger, we aimed to make a lightweight debugger that integrates the different subsystems of the HyperDbg into a fast, reliable user-mode debugging tool.

There is no need to use kernel debugging facilities to debug a user-mode application when the entire debugging module runs on user mode. The user doesn't care what is running on the kernel side and just needs to debug the user mode side of the binary. That's why HyperDbg is armed with a user debugger.

Although, the user debugger is primarily designed to use in the user-mode application. Still, it can change the kernel mode and monitor kernel events.

### What makes it different?

HyperDbg didn't use any debugging API in the debugging process. Everything is handled at the hypervisor level. This brings a huge benefit as even Windows is unaware that the process is under debugging.

Moreover, all of the magical features of HyperDbg are integrated into the user debugger. You can debug a user-mode process with the capabilities of HyperDbg debugger.

Additionally, you can simultaneously debug multiple processes with kernel-mode debugging facilities on a single debugging session.

### What to know?

The user debugger works in the [VMI Mode](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#vmi-mode).

Whenever you start a new process or attach to the target process, HyperDbg starts the "**Thread Interception**" phase.

During this phase, HyperDbg will intercept every thread that tries to run an instruction from the user-mode (Not kernel mode). Thus, some threads might remain in kernel mode without returning to the user mode and be left unintercepted.

The "**Thread Interception**" phase continues as long as you run step-in or a step-over instruction or ultimately continue the process.

After that, the new threads or those threads that return from the kernel won't be caught by HyperDbg, and you need to pause the process again to intercept these threads.

It's recommended to keep interacting with the target process to make as many threads running to intercept them in the user debugger.

The user debugger can only step through the user-mode instructions. You can't step through the kernel-mode instructions.


# Examples


# basics


# events


# Getting Results of a System-call

Intercepting a SYSCALL and SYSRET result

One of the exciting features of HyperDbg is its ability to trace and trigger events in the case of both SYSCALLs and SYSRETs. It's a straightforward task to intercept, monitor, or change syscall parameters; however, it's a bit challenging when it comes to SYSRETs.

In this example, we're going to create an automated script to intercept both system calls and then intercept the result of the system call when it returns from the kernel to the user mode.

Based on our Windows internals knowledge, we know that a thread might be either in user-mode or in the kernel mode, so if we intercept a thread turns to the kernel, by executing the SYSCALL instruction, we can expect that the target thread will perform an SYSRET after finishing its execution in the kernel.

It's clear that if we save the Thread Id of our target thread from the syscall event, we can check it later in the SYSRET event.

There is another problem here. Two threads might simultaneously trigger the same syscall; thus, we need to synchronize somehow. To overcome this issue, we use spinlocks.

First, we create two global variables, one to hold the spinlocks' lock, and the second global variable stores the Thread Id that executed our target system call.

```clike
? .thread_id = 0;
? .thread_id_lock = 0;
```

Next, in the SYSRET event, we check whether the current thread is stored at the `.thread_id` global variable or not. If it is stored, then it's the thread that we want to see its results, and if not, there is no interest for interception. At last, we set the `.thread_id` to `0` to indicate that we finish investigating this thread.

```clike
!sysret script {

	if (.thread_id == $tid) {
		
		printf("[%llx] result of syscall: %llx\n", $tid, @rax);
		
		//
		// Reset the thread id holder
		//
		.thread_id = 0;
	}
}
```

As the next step, we check for the **Process Id** and the **syscall number**. If the process is our target process and the system call number stored at the **RAX** register is our target system call, then we keep the Thread Id into the `.thread_id` variable.

There might be two or more threads that execute the system call. We only intercept one of them and ignore another one if both of them execute the same syscall at once. The check is performed in the critical section between spinlocks to avoid two threads serving the same check simultaneously.

```clike
!syscall script { 
	
	if ($pid == $arg1 && @rax == $arg2) {
		
		spinlock_lock(&.thread_id_lock);
		
		if (.thread_id == 0) {
			
			//
			// Save the thread id for the SYSRET event
			//
			.thread_id = $tid;
			
			//
			// Show the parameters
			//
			printf("[%llx] syscall num: %llx, arg1: %llx, arg2: %llx, arg3: %llx, arg4: %llx\n", $tid, @rax, @rcx, @rdx, @r8, @r9);
			
		}
		
		spinlock_unlock(&.thread_id_lock);
	}
}
```

As you might have noticed, we run the SYSRET event before running the syscall event. The reason for it came from the fact that if we set the SYSCALL event before the SYSRET event, a syscall might set the `.thread_id` to a Thread Id. As we're not configuring the SYSRET event yet, the thread might finish its execution (run SYSRET) before configuring the SYSCALL event, and thus, it never works properly.

All in all, putting everything together makes the following script, we'll create a file named `c:\users\sina\desktop\script.ds`.

```clike
? .thread_id = 0;
? .thread_id_lock = 0;

!sysret script {

	if (.thread_id == $tid) {
		
		printf("[%llx] result of syscall: %llx\n", $tid, @rax);
		
		//
		// Reset the thread id holder
		//
		.thread_id = 0;
	}
}

!syscall script { 
	
	if ($pid == $arg1 && @rax == $arg2) {
		
		spinlock_lock(&.thread_id_lock);
		
		if (.thread_id == 0) {
			
			//
			// Save the thread id for the SYSRET event
			//
			.thread_id = $tid;
			
			//
			// Show the parameters
			//
			printf("[%llx] syscall num: %llx, arg1: %llx, arg2: %llx, arg3: %llx, arg4: %llx\n", $tid, @rax, @rcx, @rdx, @r8, @r9);
			
		}
		
		spinlock_unlock(&.thread_id_lock);
	}
}
```

After that, we run our script by using the below command.

```
? .script c:\users\sina\desktop\script.ds 1240 55
```

You can see the results in the following picture.

![](/files/7dzVmELQSx1bhuIjd09O)


# Kernel-mode Debugging

Principles of the kernel-mode debugger


# Principles

Principles of designing a fast and reliable kernel-mode debugger

The central part of the HyperDbg debugger is its kernel-mode debugger called **kHyperDbg**.

It's almost two decades that kernel debuggers like WinDbg and GDB didn't change significantly. The HyperDbg contributors try to make a move toward advancing the kernel debugging and kernel debuggers.

Moreover, we think kernel mode is not the best playground for a kernel-debugger. A debugger who wants to debug the kernel mode should be more privileged in terms of hardware layers (rings).

In addition, a debugger is not allowed to manipulate the operating system's structures to make facilities for the debugging. Instead, we need a completely separate layer to monitor and change these structures without interfering with the operating system. The best place for reaching these goals is hypervisors.

The HyperDbg is a hypervisor-level debugger designed to pursue these needs.

### Design Goals

We aimed to make a powerful and fast debugger to bring new creative features into your debugging and analyzing journey.

The complexity of new binaries that run on kernel mode of operating systems and its importance on security and reliability of the systems needs a debugger that follows these needs with new features.

Likewise, the speed of the debugger combined with a powerful script engine makes you able to change the flow of the applications and even the operating system by using simple scripts.

### What makes it different?

Tens of distinctive characteristics and the fact that HyperDbg is tremendously faster in creating logs and checking for conditions based on its unique script engine design.

Furthermore, changing and monitoring the memory brings thousands of features that a researcher or a programmer can use to analyze and research binary modules.

Similarly, features like stepping from user mode to kernel mode or kernel mode to user mode are only available in the HyperDbg debugger. These are practical features and approaches that ease the binary analysis procedure.

HyperDbg is transparent by its nature. However, we tried to make it even more transparent by implementing the [Transparent Mode](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#transparent-mode). Although, it won't guarantee 100% of transparency. Still, it makes it substantially harder for the anti-debugging and anti-hypervisor methods to detect the debugger's presence.

### What to know?

The kernel debugger works on both VMI Mode and Debugger Mode.

The difference between running in the [VMI Mode](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#vmi-mode) and the [Debugger Mode](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#debugger-mode) is that you can't halt (pause) the debugger to step through the instruction or use the "[break](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/how-to-create-an-action#break)" actions in the VMI Mode.

In the Debugger Mode, HyperDbg sends the buffer and messages immediately, but these messages will be buffered first and delivered at a suitable time in the VMI Mode.

Unlike WinDbg, some of the commands are implemented from user mode and will continue the debuggee for some time, and you'll lose the contexts (registers, memory). You need to consider that as described in the command's documentation.

You need to follow some safety rules in accessing memory and avoid "[unsafe behavior](https://docs.hyperdbg.org/tips-and-tricks/considerations/the-unsafe-behavior)" in using HyperDbg.


# Examples


# beginning


# Connecting To HyperDbg

Connecting & Debugging Using HyperDbg

This article only describes the **Debugger Mode** of the HyperDbg in the VMware Workstation Player (free for non-commercial use) and Pro.

You might want to :

* [Attach to a local machine](https://docs.hyperdbg.org/getting-started/attach-to-hyperdbg/local-debugging)
* [Connect to a physical machine](https://docs.hyperdbg.org/getting-started/attach-to-hyperdbg/debug#physical-machine)
* [Connect to VMI Mode](https://docs.hyperdbg.org/getting-started/attach-to-hyperdbg/debug#connect-to-debuggee-vmi-mode)

In order to run HyperDbg on a VMware Workstation machine, first, turn off your guest machine then, you need to enable **Nested Virtualization**. Open your virtual machine and click on Edit **virtual machine settings**.

![Editing VM Settings](/files/eKHEP77BLqAoRoIuJRWH)

After that, click on **Virtualize Intel VT-x/EPT or AMD-V/RVI** and **Virtualize IOMMU (IO memory management unit)**.

![Enabling Nested-Virtualization](/files/5hefW0kJF8g5HA47gJ4V)

Next, click on **Add...** then choose **Serial Port** and click on **Finish**.

![Adding a serial device](/files/ufY5y12j2nA2ARaI75Ee)

Now, click on **Use named pipe:** and add a name for your named pipe.

Your name should start with `\\.\pipe\` . For example, choose `\\.\pipe\HyperDbgDebug`.

Make sure to enable **Yield CPU on poll**.

![Change serial device configuration](/files/ufruutEDiICfWsHZ90V4)

Now it's time to create a kernel debug connection. First of all, run the following command on the host (debugger). You should change the named pipe address to whatever name you chose on the previous part.

```
HyperDbg> .debug remote namedpipe \\.\pipe\HyperDbgPipe
```

![Waiting for a remote connection (Host)](/files/QLg3NMzWFRmvsL6B8dsE)

After you tell the debugger to listen on a COM port or a named pipe, now you can run the following command in the debuggee (guest).

```
HyperDbg> .debug prepare serial 115200 com2
```

![Preparing to connect debugger (Guest)](/files/w7UgE5E4vxtpwt8Wagdn)

Most of the time, if the serial port is the only serial device that you add to the virtual machine, then the name of the connected port is `com2`. However, you can see the exact name of the COM port on the guest's device manager.

After running the above command in guest, now you should see that the debuggee is connected to the debugger.

{% hint style="info" %}
If you see an error for driver signature enforcement, please visit [here](https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/beginning/connecting-to-hyperdbg#driver-signature-enforcement-error).
{% endhint %}

You can press **CTRL+C** to pause the debuggee and step through the kernel codes using the ['p' command](https://docs.hyperdbg.org/commands/debugging-commands/p) and the ['t' command](https://docs.hyperdbg.org/commands/debugging-commands/t), and if you want to continue the normal execution of the debuggee, you can use the ['g' command](https://docs.hyperdbg.org/commands/debugging-commands/g).

![Step and Continue Debuggee](/files/Kh0RjzPmIx8FBAx4eSaI)

## Driver Signature Enforcement Error

If you are using an unsigned version of HyperDbg driver, you should turn off the **Driver Signature Enforcement**.

![Driver Signature Enforcement Error](/files/Kheb1tDxI8x4S9Vm8xbm)

For disabling Driver Signature Enforcement, you can visit [here](https://docs.hyperdbg.org/getting-started/build-and-install#disable-driver-signature-enforcement).


# Configuring Symbol Server/Path

Configuring symbol server and path

After you connect to HyperDbg, it's highly recommended to configure the symbol server to have a better debugging experience.

For this purpose, first, we have to configure the symbol server address or local symbol path using the '[.sympath](https://docs.hyperdbg.org/commands/meta-commands/.sympath)' command. After that, we can use the '[.sym](https://docs.hyperdbg.org/commands/meta-commands/.sym)' command to load or download symbols.

Firstly, we need a symbol path. We often set a local symbol path combined with a remote symbol server (e.g., Microsoft Symbol Server). For example, the following path is used:

`SRV*c:\symbols*https://msdl.microsoft.com/download/symbols`

In the above path, first, it checks if the symbol exists in `c:\symbols`. If not, then it checks `https://msdl.microsoft.com/download/symbols`.

All the path strings should start with `SRV*`.

Now, the following command sets the symbol path to `SRV*c:\symbols*https://msdl.microsoft.com/download/symbols`.

```
HyperDbg> .sympath SRV*c:\Symbols*https://msdl.microsoft.com/download/symbols
```

And the following command shows the current symbol server.

```
HyperDbg> .sympath
current SymbolServer is : SRV*c:\Symbols*https://msdl.microsoft.com/download/symbols
```

The next step is to update the symbol table.

Use the following command to update the symbol table and all the symbols from the local symbol path (and **NOT download** them).

```c
HyperDbg> .sym reload
symbol table updated successfully
```

If you want to load all the symbols from the local symbol path and, if not available then, download them from the remote symbol server (e.g., Microsoft Symbol Server), use the following command.

```c
HyperDbg> .sym download
downloading symbol 'ntkrnlmp.pdb'...    downloaded
downloading symbol 'kd.pdb'...  downloaded
downloading symbol 'mcupdate_GenuineIntel.pdb'...       downloaded
downloading symbol 'clfs.pdb'...        downloaded
downloading symbol 'tm.pdb'...  downloaded
downloading symbol 'pshed.pdb'...       downloaded
downloading symbol 'bootvid.pdb'...     downloaded
downloading symbol 'fltMgr.pdb'...      downloaded
downloading symbol 'msrpc.pdb'...       downloaded
downloading symbol 'ksecdd.pdb'...      downloaded
downloading symbol 'clipsp.pdb'...      downloaded
downloading symbol 'cmimcext.pdb'...    downloaded
downloading symbol 'WerKernel.pdb'...   downloaded
downloading symbol 'ntosext.pdb'...     downloaded
downloading symbol 'ci.pdb'...  downloaded
downloading symbol 'cng.pdb'... downloaded
downloading symbol 'Wdf01000.pdb'...    downloaded
downloading symbol 'wdfldr.pdb'...      downloaded
downloading symbol 'wpprecorder.pdb'... downloaded
downloading symbol 'SleepStudyHelper.pdb'...    downloaded
downloading symbol 'acpiex.pdb'...      downloaded
downloading symbol 'mssecflt.pdb'...    downloaded
downloading symbol 'SgrmAgent.pdb'...   downloaded
downloading symbol 'acpi.pdb'...        downloaded
downloading symbol 'wmilib.pdb'...      downloaded
downloading symbol 'intelpep.pdb'...    downloaded
downloading symbol 'WindowsTrustedRT.pdb'...

...
```

After that, each time you load HyperDbg in both local debugging ([VMI Mode](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#vmi-mode)) and remote serial debugging ([Debugger Mode](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#debugger-mode)), HyperDbg loads the previously downloaded modules from the path (it **won't** download symbols from the remote server without your permission, you should use `.sym download` to download the symbols from the Internet. However, local symbols are automatically loaded).

When you finish configuring symbols, you can use the function names, variables, and object names in the debugger commands.


# basics


# Setting Breakpoints & Stepping Instructions

Set breakpoint, Step-over, and Step-in

In HyperDbg, we have multiple options to set a breakpoint.

One of the ways of setting breakpoints is [hooking](https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/events/hooking-any-function). Another way is using the ['bp' command](https://docs.hyperdbg.org/commands/debugging-commands/bp). In this article, we describe the second method.

Assume that `ObRegisterCallbacks` is located at ``fffff805`5cbac610``.

This function creates callbacks for thread, process, and other objects' [tasks ](https://rayanfam.com/topics/reversing-windows-internals-part1/)like creation, opening, etc. You can see more information at [MSDN](https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-obregistercallbacks).

Many game anti-cheat solutions use this function to monitor processes to prevent game cheater to cheat on games.

In order to bypass this mechanism, we use the following command in HyperDbg to set a breakpoint on this function.

```
0: kHyperDbg> bp nt!ObRegisterCallbacks
```

or,

```
0: kHyperDbg> bp fffff805`5cbac610
```

Then, we will run our game and see if the breakpoint is triggered or not.

If the breakpoint is triggered, then the system is halted and we are able to control the debuggee.

After that, we can use the ['p' command](https://docs.hyperdbg.org/commands/debugging-commands/p) to step-over the instructions.

```
0: kHyperDbg> p 
fffff805`5cbac610    48 81 EC 50 01 00 00                sub rsp, 0x150
```

You can also add a number to run multiple instructions.

```
0: kHyperDbg> p 3
fffff805`5cbac610    48 81 EC 50 01 00 00                sub rsp, 0x150
fffff805`5cbac617    48 8D AC 24 80 00 00 00             lea rbp, ss:[rsp+0x80]
fffff805`5cbac620    C6 45 AB 00                         mov byte ptr ss:[rbp-0x55], 0x00
```

If you want to step-in, you can use the ['t' command](https://docs.hyperdbg.org/commands/debugging-commands/t).

```
0: kHyperDbg> t
fffff805`5cbac610    48 81 EC 50 01 00 00                sub rsp, 0x150
```


# Displaying & Editing & Searching Memory

Using d\*, e\*, and s\* commands

One of the debugger's essential tasks is displaying or editing memory, and HyperDbg is not an exception.

You can display, edit, and search both physical and virtual addresses using the following commands.

## Displaying Memory

The following command is used when we want to read the content of memory at ``fffff800`3ad6f010`` with the length of `0x50` from the memory layout view of the process (`4` a.k.a. system process) in a hex byte format.

```diff
HyperDbg> db fffff800`3ad6f010 l 50 pid 4
fffff800`3ad6f010  48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 57  H.\$.H.l$.H.t$.W
fffff800`3ad6f020  41 56 41 57 48 83 EC 30 65 48 8B 04 25 20 00 00  AVAWH..0eH.. ..
fffff800`3ad6f030  00 33 DB 44 0F B7 3D C5 3F 20 00 41 8B E8 48 8B  .3.D..=.? .A..H.
fffff800`3ad6f040  F2 89 5C 24 68 8B F9 4C 8B 88 C0 00 00 00 45 0F  ..\$h..L......E.
fffff800`3ad6f050  B7 B1 92 00 00 00 41 8B C6 44 8B C8 89 5C 24 20  ......A..D...\$
```

The following example shows the content of memory at ``fffff800`3ad6f010`` from current process layout in a Double-word value (4 bytes) and ASCII characters format.

```diff
HyperDbg> dc fffff800`3ad6f010
fffff800`3ad6f010  245C8948 6C894808 89481024 57182474  H.\$.H.l$.H.t$.W
fffff800`3ad6f020  57415641 30EC8348 048B4865 00002025  AVAWH..0eH.. ..
fffff800`3ad6f030  44DB3300 C53DB70F 4100203F 8B48E88B  .3.D..=.? .A..H.
fffff800`3ad6f040  245C89F2 4CF98B68 00C0888B 0F450000  ..\$h..L......E.
fffff800`3ad6f050  0092B1B7 8B410000 C88B44C6 20245C89  ......A..D...\$
fffff800`3ad6f060  48C58B44 CF8BD68B CC3693E8 C08548FF  D..H......6..H..
fffff800`3ad6f070  0038840F 8B480000 6C8B48D8 8B485824  ..8...H..H.l$XH.
fffff800`3ad6f080  5C8B48C3 8B485024 48602474 4130C483  .H.\$PH.t$`H..0A
```

The following example shows the content of memory at ``fffff800`3ad6f010`` from current process layout in a Double-word values (4 bytes) format with the length of `0x10`.

```diff
HyperDbg> dd fffff800`3ad6f010 l 10
fffff800`3ad6f010  245C8948 6C894808 89481024 57182474
```

The following example shows the content of memory at ``fffff800`3ad6f010`` from current process layout in a Quad-word values (8 bytes) format.

```diff
HyperDbg> dq fffff800`3ad6f010
fffff800`3ad6f010  6C894808`245C8948 57182474`89481024
fffff800`3ad6f020  30EC8348`57415641 00002025`048B4865
fffff800`3ad6f030  C53DB70F`44DB3300 8B48E88B`4100203F
fffff800`3ad6f040  4CF98B68`245C89F2 0F450000`00C0888B
fffff800`3ad6f050  8B410000`0092B1B7 20245C89`C88B44C6
fffff800`3ad6f060  CF8BD68B`48C58B44 C08548FF`CC3693E8
fffff800`3ad6f070  8B480000`0038840F 8B485824`6C8B48D8
fffff800`3ad6f080  8B485024`5C8B48C3 4130C483`48602474
```

## Editing Memory

The following command is used when we want to edit the content of memory at ``fffff800`3ad6f010`` in a hex byte form and change it to `0x90 0x90 0x90` (modify **three** bytes).

```diff
HyperDbg> eb fffff800`3ad6f010 90 90 90
```

The following example is used when we want to edit the contents of memory at ``fffff800`3ad6f010`` in Double-word values (4 bytes), change it to `245C8948` .

```diff
HyperDbg> ed fffff800`3ad6f010 245C8948
```

The following example is used when we want to edit the contents of memory at ``fffff800`3ad6f010`` in Quad-word values (8 bytes), change it to ``88889898`85858686`` and``92929393`97979898`` (16 bytes).

```diff
HyperDbg> eq fffff800`3ad6f010 88889898`85858686 92929393`97979898
```

## Searching Memory

The following command is used to search for `4156415748` starting from ``fffff807`7356f010`` to ``fffff807`7356f010+ffff``.

```diff
HyperDbg> sb fffff807`7356f010 l ffff 41 56 41 57 48
```

The following example is used when we want to search for `f0cc8549` from `7FF62C9016AD` to `7FF62C9016AD+fff` in a different process (process id = `1dd0`).

```diff
HyperDbg> sd 7FF62C9016AD pid 1dd0 l fff f0cc8549
```

The following example is used when we want to search for ``0f450000`00c0888b`` ``8b410000`0092b1b7`` from ``fffff807`7356f010`` to ``fffff807`7356f010+100``.

```diff
HyperDbg> sq fffff807`7356f010 l 100 0f450000`00c0888b 8b410000`0092b1b7
```

{% hint style="info" %}
If you want to perform the above actions on physical addresses, you can add **`!`** to any of the above commands.
{% endhint %}


# Showing & Modifying Registers and Flags

Using the 'r' command

You can view and modify registers only in Debugger Mode. It's possible to use the '[r](https://docs.hyperdbg.org/commands/debugging-commands/r)' command. HyperDbg supports a wide list of registers and also supports viewing and modifying each flag separately.

A list of supported registers is available [here](https://docs.hyperdbg.org/commands/scripting-language/assumptions-and-evaluations#registers).

If you want to read all the registers, use the following command.

```clike
0: kHyperDbg> r
RAX=ffff948cc1902d40 RBX=ffff948cbfefb520 RCX=0000000000000022
RDX=0000000000000000 RSI=0000000000000000 RDI=ffff948cc00c30e0
RIP=fffff80168d91312 RSP=ffff930548474688 RBP=0000000000000002
R8=0000000000000000  R9=0000000000000000  R10=0000000048564653
R11=0000564d43414c4c R12=4e4f485950455256 R13=0000000000000000
R14=ffff948cc00c30e0 R15=ffff948cc19bfe10 IOPL=00
OF 0  DF 0  IF 1  SF  0
ZF 1  PF 1  CF 0  AXF 0
CS 0010 SS 0018 DS 002b ES 002b FS 0053 GS 002b
RFLAGS=0000000000040246
```

If you want to read a special register, use its name after the '[r](https://docs.hyperdbg.org/commands/debugging-commands/r)' command.

```clike
0: kHyperDbg> r @rax
rax=ffff948cc1902d40

0: kHyperDbg> r @rip
rip=fffff80168d91312
```

Also, you can modify the value of a register by using '=' and setting it to a **hex** value.

```clike
0: kHyperDbg> r @rax = 55

0: kHyperDbg> r @rax
rax=0000000000000055
```

It's also possible to modify each flag of the **RFLAGS**.

```clike
0: kHyperDbg> r @cf
cf=0000000000000000

0: kHyperDbg> r @cf = 1

0: kHyperDbg> r @cf
cf=0000000000000001
```


# Switching to a Specific Process or Thread

Using the '.process', and the '.thread' commands

Switching to new processes/threads is useful when debugging a particular process or a user-mode application. These switchings are possible through the '[.process](https://docs.hyperdbg.org/commands/meta-commands/.process)' and '[.thread](https://docs.hyperdbg.org/commands/meta-commands/.thread)' commands.

In HyperDbg, there are different implementations of these switchings. You can read more about these differences [here](https://docs.hyperdbg.org/tips-and-tricks/considerations/difference-between-process-and-thread-switching-commands).

In this example, we walk through a C code to show how to use these commands.

Imagine we compiled the following program. It's an infinite loop that prints a counter every **1000000000** times.

```clike
#include <Windows.h>
#include <conio.h>
#include <iostream>

int main() {

	bool Test = true;
	UINT64 Counter = 0;

	while (Test) {

		if (Counter % 1000000000 == 0) {
			printf("Thread is running (%lld)...\n", Counter);
		}
		Counter++;
	}

	printf("Thread is closed!\n");
	_getch();
}
```

After compiling and running the above code, we use the command shown in the picture to view the list of processes and other information about the processes running in the system.

```
3: kHyperDbg> .process list
```

![View process list](/files/D9mqgmz5LwK8YuLEGUZL)

We find our target program which its name is "**Test.exe**". Then, we see a list of running threads based on this process. For this purpose, we used the process object address (`nt!_EPROCESS`).

```
3: kHyperDbg> .thread list process ffff948cc16c3080
```

![View list of threads of a process](/files/hH5ikizLTIXtGGWdwqNR)

Now, we can switch to the target thread and continue the debuggee. Whenever the system reaches the target thread, it will be halted again and run new commands.

Note that it's a 32-bit program, so we use the '[u2](https://docs.hyperdbg.org/commands/debugging-commands/u)', which is the 32-bit version of the disassembler in this case.

```
3: kHyperDbg> .thread tid b10
```

![Switch to a new thread](/files/AN2bVm5gb0OMeJHWSafE)

After analyzing the program, we find the jumps in the assembly code. You can also see the calls that are probably a link to the `printf` function.

```
2: kHyperDbg> u2 00e249f6
```

![Disassemble the target thread](/files/R9MEl5GuVScXBvrKiTLo)

Then, we step through the instructions to better understand how this program works.

![Step through the instructions](/files/NZCK8PIsOzdNL9soimXw)

After some investigation, we can conclude that the guilty jump is located at `0xe24a31`, so we'll modify the memory and patch it by using nop instructions(0x90).

```
2: kHyperDbg> eb 00e24a31 90 90
```

![Patch the program's execution flow](/files/m2aRkb6W1g29dsTgrXEH)

If we continue the debuggee again, you can see that the patched program jumps out of the infinite loop and show the '**thread is closed!**' message.

![The result of patched program](/files/VCTeta7vSuZoYGHeKV5m)

It was a simple example of how to use thread and process switching commands in HyperDbg. You can think about different approaches that you can use to change the program's execution flow (like changing the RFLAGS, etc.) or analyze any other programs.


# Mapping Data & Create Structures, and Enums From Symbols

Using the 'dt' and the 'struct' commands

In this example, we'll see how to change the process name of the **notepad.exe** in the Task Manager by utilizing the '[dt](https://docs.hyperdbg.org/commands/debugging-commands/dt)' and the '[struct](https://docs.hyperdbg.org/commands/debugging-commands/struct)' commands of the HyperDbg.

From our previous Windows internals knowledge, we know that the process name is available in the `SeAuditProcessCreationInfo` field of the process's `_EPROCESS`.

Note that there is an `ImageFileName` field in the `_EPROCESS`. However, it's not what we're looking for as it's not the field shown in the Task Manager.

After looking at the `_EPROCESS`, we see that the `SeAuditProcessCreationInfo` is of the `_SE_AUDIT_PROCESS_CREATION_INFO` type. Let's see this structure recursively to see how Windows stores the process name.

```clike
HyperDbg> struct _SE_AUDIT_PROCESS_CREATION_INFO
typedef struct _SE_AUDIT_PROCESS_CREATION_INFO
{
  /* 0x0000 */ struct _OBJECT_NAME_INFORMATION* ImageFileName;
} SE_AUDIT_PROCESS_CREATION_INFO, *PSE_AUDIT_PROCESS_CREATION_INFO; /* size: 0x0008 */


HyperDbg> struct _OBJECT_NAME_INFORMATION
typedef struct _OBJECT_NAME_INFORMATION
{
  /* 0x0000 */ struct _UNICODE_STRING Name;
} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION; /* size: 0x0010 */


HyperDbg> struct _UNICODE_STRING
typedef struct _UNICODE_STRING
{
  /* 0x0000 */ uint16_t Length;
  /* 0x0002 */ uint16_t MaximumLength;
  /* 0x0004 */ long Padding_0;
  /* 0x0008 */ wchar_t* Buffer;
} UNICODE_STRING, *PUNICODE_STRING; /* size: 0x0010 */
```

As you can see, we've reached a `_UNICODE_STRING` structure, and this is where Windows stores the process name. Now let's open **notepad.exe**.

![](/files/o8T26bLr33GxnlgeUVmh)

As demonstrated, the Process ID is **5616** in decimal. We can convert it to the hex format by using the '[.formats](https://docs.hyperdbg.org/commands/meta-commands/.formats)' command by adding a **0n** prefix which indicates that the value is in decimal format.

```clike
1: kHyperDbg> .format 0n5616
evaluate expression:
Hex :        00000000`000015f0
Decimal :    5616
Octal :      12760
Binary :     00000000 00000000 00000000 00000000 00000000 00000000 00010101 11110000
Char :       ........
Time :       04/19/22 - 12:53AM
Float :      0.00 +3e-320 2.774673E-320
Double :     2.77467266704444059e-320
```

Now, we need to find the `_EPROCESS` of our target process. It's possible by using the '[.process](https://docs.hyperdbg.org/commands/meta-commands/.process)' command.

```clike
1: kHyperDbg> .process list

...

PROCESS ffff948cc1517080
        Process Id: 23d0        DirBase (Kernel Cr3): 00000000127c0002  Image: dllhost.exe

PROCESS ffff948cc2393080
        Process Id: 15f0        DirBase (Kernel Cr3): 0000000190649002  Image: notepad.exe

PROCESS ffff948cc06f6080
        Process Id: 0fc4        DirBase (Kernel Cr3): 000000002902c002  Image: Taskmgr.exe
...
```

After that, we'll map the `_EPROCESS` of the **notepad.exe** to find the location of `SeAuditProcessCreationInfo`. As is evident, it's located at `+0x05c0` from the start of the `_EPROCESS`.

```clike
1: kHyperDbg> dt nt!_EPROCESS ffff948cc2393080
 _EPROCESS

...

  +0x05b7 uint8_t PriorityClass : 0x2
  +0x05b8 void* SecurityPort : (null)
  +0x05c0 _SE_AUDIT_PROCESS_CREATION_INFO SeAuditProcessCreationInfo : ffff948c`c25fa2a0
  +0x05c8 _LIST_ENTRY JobLinks : _LIST_ENTRY [ 00000000`00000000 - 00000000`00000000 ]
...
```

Now, we'll map it to `_SE_AUDIT_PROCESS_CREATION_INFO` to find the `ImageFileName`.

![](/files/AydmdQUdMS7YqElhIDou)

Before that, we want to convert the **notepad.exe** to **HyperDbg.exe**. For this purpose, we need to convert "**HyperDbg.exe**" to the hex format and add **00** to each character because this field is in Unicode format.

![](/files/DZ0C2qAb8GJf4fQr8eUH)

We read the pointer located at `_EPROCESS+0x05c0` and modify the **notepad.exe** in the target `_UNCODE_STRING` by using the '[eb](https://docs.hyperdbg.org/commands/debugging-commands/e)' command.

![](/files/eNSqQsPPcwbvcyf8MJYm)

It's time to continue the debuggee and see the results.

![](/files/vSK7qdbmoFTgZWNQXDhl)

As it might be seen, it's changed to '**HyperDbg.ex**' because we didn't update the `Length` field of the `_UNICODE_STRING`. Changing this value is left as an exercise for the reader.

That's it. In this example, we saw how we could use the structure mapping commands in HyperDbg to change the process name in the Task Manager.


# events


# Managing Events

Enable, Disable, and remove events

Each time you use a command like [!syscall](https://docs.hyperdbg.org/commands/extension-commands/syscall), [!epthook](https://docs.hyperdbg.org/commands/extension-commands/epthook), [bp](https://docs.hyperdbg.org/commands/debugging-commands/bp), [!monitor](https://docs.hyperdbg.org/commands/extension-commands/monitor), etc., you create an event.

After that, you can disable or re-enable the event or completely clear the event. This article demonstrates how to manage events in HyperDbg.

The following command shows the list of active/disabled events.

```diff
HyperDbg> events
0       (enabled)           !syscall 80
1       (disabled)          !sysret 80
2       (enabled)           !msrwrite 80 code {90}
3       (enabled)           !cpuid
```

The following command disables an event with event number `1` and then we see the list of all events.

```diff
HyperDbg> event d 1

HyperDbg> events
0       (enabled)           !syscall 80
1       (disabled)          !sysret 80
2       (enabled)           !msrwrite 80 code {90}
3       (enabled)           !cpuid
```

The following command enables all of the events and commands.

```
HyperDbg> event e all

HyperDbg> events
0       (enabled)           !syscall 80
1       (enabled)           !sysret 80
2       (enabled)           !msrwrite 80 code {90}
3       (enabled)           !cpuid
```

The following command clears an event with event number `1`.

```
HyperDbg> event c 1

HyperDbg> events
0       (enabled)           !syscall 80
2       (enabled)           !msrwrite 80 code {90}
3       (enabled)           !cpuid
```

The following command clears and turns off every enabled and disabled event and commands.

```
HyperDbg> event c 1
```


# Hooking Any Function

Description about hooking options in HyperDbg

Hooking is a powerful feature of HyperDbg. You can hook all user-mode and kernel-mode functions and expect a fast in-line hook or unlimited EPT hooks.

Currently, hooking functions is possible through the [!epthook](https://docs.hyperdbg.org/commands/extension-commands/epthook) and [!epthook2](https://docs.hyperdbg.org/commands/extension-commands/epthook2).

**!epthook2** is generally a faster hook; however, it has some limitations that are mentioned [here](https://docs.hyperdbg.org/commands/extension-commands/epthook2#remarks).

Assume that `ExAllocatePoolWithTag` is located at ``fffff805`5cdb2030``.

As you can see on [MSDN](https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-exallocatepoolwithtag), this function is defined like this :

```c
PVOID ExAllocatePoolWithTag(
  __drv_strictTypeMatch(__drv_typeExpr)POOL_TYPE PoolType,
  SIZE_T                                         NumberOfBytes,
  ULONG                                          Tag
);
```

Another thing is that the above function is called with **Fastcall** calling convention, and the parameters are passed in the following order `rcx`, `rdx`, `r8`, `r9`, and the rest of them are located on the stack. So, we have two options here to create a log from the parameters of this function. For example, we want to create a log from the **Tags** which is on `r8`.

```c
HyperDbg> !epthook fffff805`5cdb2030 script { print(@r8); }
```

If we want to use **!epthook2**, then the following command is used :

```c
HyperDbg> !epthook2 fffff805`5cdb2030 script { print(@r8); }
```


# Intercepting All SYSCALLs

Getting System-Calls

In HyperDbg, you are able to [intercept all syscalls](https://docs.hyperdbg.org/design/features/vmm-module/design-of-syscall-and-sysret) or a specific syscall.

For this purpose, you have to use the [!syscall](https://docs.hyperdbg.org/commands/extension-commands/syscall) command. You can also use the [!sysret](https://docs.hyperdbg.org/commands/extension-commands/sysret) too.

There is a list of syscalls available [here](https://j00ru.vexillium.org/syscalls/nt/64/). You can find win32k syscalls [here](https://j00ru.vexillium.org/syscalls/win32k/64/).

For example, in **Windows 10 2004**, the syscall number for **NtCreateFile** is **0x55**.

We want to intercept all the times that a process with pid `2f4c` in our system tries to open a file, so we use the following command.

```c
HyperDbg> !syscall 55 pid 2f4c
```

We might even want to monitor all processes. For example, we want to intercept whenever any process uses **NtFreezeRegistry** (syscall number **0xee**).

```c
HyperDbg> !syscall ee
```


# Monitoring Accesses To Structures

Finding the writers and reader of memory

Have you ever tried to discover what functions read or write on a portion of memory?

**Hardware Debug Registers** have limitations, we only have four debug registers and these debug registers have a limitation on size (4, 2, 1).

Imagine the `nt!_EPROCESS` of a process is located at `0xffff83811f265040` and at the current version of Windows, the size of the `nt!_EPROCESS` is **0xa40**. We can conclude that this structure starts from `0xffff83811f265040` to `0xffff83811f265040 + 0xa40 = 0xffff83811f265a80`.

If we want to break on any read/write to this structure, we use the following command.

```c
HyperDbg> !monitor rw 0xffff83811f265040 0xffff83811f265a80
```

If we want to create a log from RIP(s) that tries to write on `nt!_EPROCESS` of that special process.

```c
HyperDbg> !monitor w 0xffff83811f265040 0xffff83811f265a80 script { print($ip); }
```

If we want to monitor RIP(s) for reading (not writing), we use the following command.

```c
HyperDbg> !monitor r 0xffff83811f265040 0xffff83811f265a80 script { print($ip); }
```


# Triggering Special Instructions

A description about hooking RDTSC, RDTSCP, I/O IN & OUT, RDPMC, etc.

There are special instructions in x86 and AMD64 processors that might be configured to cause vm-exits when executed; thus, we can intercept them.

For example, we might be interested in the execution of I/O instructions (IN & OUT). We can monitor memory-mapped I/O using the [!monitor](https://docs.hyperdbg.org/commands/extension-commands/monitor) command, but for I/O mapped devices, we can use [!ioin](https://docs.hyperdbg.org/commands/extension-commands/ioin) and [!ioout](https://docs.hyperdbg.org/commands/extension-commands/ioout) commands.

{% hint style="danger" %}
Do not try to monitor all I/O ports or the I/O port for the serial device connected to the debugger if you are operating on **Debugger Mode**.
{% endhint %}

Using these commands, we can monitor I/O ports. For example, let's say we want to monitor the I/O port `0x3f8` for `IN`instruction.

```c
HyperDbg> !ioin 0x3f8
```

If we want to monitor port `0x3f8` for `OUT` instruction, we use the following command.

```c
HyperDbg> !ioout 0x3f8
```

Let's intercept another instruction.

We know that **CPUID** is an important instruction that tries to get processor features to see if a processor supports a special feature or not.

For example, we want to intercept all the CPUIDs that a process with process ID **0x490** tries to execute.

```c
HyperDbg> !cpuid pid 490
```

You can also break on the execution of other instructions like:

* **RDTSC** and **RDTSCP** using [!tsc](https://docs.hyperdbg.org/commands/extension-commands/tsc) command
* **RDPMC** using [!pmc](https://docs.hyperdbg.org/commands/extension-commands/pmc) command
* **VMCALL**s using [!vmcall](https://docs.hyperdbg.org/commands/extension-commands/vmcall) command


# Identifying System Behavior

Intercepting Exceptions, Interrupts, and MSRs

In order to detect system behavior, we have 3 factors for this example. The first factor is intercepting the first 32 entries of IDT (Interrupt Descriptor Table). We use the [!exception](https://docs.hyperdbg.org/commands/extension-commands/exception) command for this purpose.

For instance, if we want to break on **division-by-zero** on process id **0x490**.

```c
HyperDbg> !exception 0x0 pid 490
```

If we want to monitor external-interrupts (IDT index from **0x21** to **0xff**), we use the [!interrupt](https://docs.hyperdbg.org/commands/extension-commands/interrupt) command.

Imagine we want to break on entry **0x25** of IDT.

```c
HyperDbg> !interrupt 0x25
```

The last factor is the system-wide monitoring of the execution of RDMSR and WRMSR. We use the [!msrread](https://docs.hyperdbg.org/commands/extension-commands/msrread) and the [!msrwrite](https://docs.hyperdbg.org/commands/extension-commands/msrwrite) commands.

For example, MSR **0xc0000082 (LSTAR)** is one of the MSRs used by malware and rootkits.

If we want to break on RDMSR to MSR **0xc0000082**.

```c
HyperDbg> !msrread 0xc0000082
```

If we want to break on WRMSR to MSR **0xc0000082**.

```c
HyperDbg> !msrwrite 0xc0000082
```


# Software Development Kit (SDK)

Explaining HyperDbg SDK


# Events

Details of event management


# Conditions

### Creating a Condition

You can create a buffer that holds a few bytes that will do anything you want. For example, you might want to check if the current thread is a special thread or check the privilege level of the requesting user or whatever you can do anything you want in your assembly code then at the end of the code, you can decide whether the actions of this event should be executed or not.

This is done by using `RAX`register. If you zero the `RAX`register, then return (`ret`), it means that you don't want the event actions to be executed (or in other words, you returned `FALSE`).

For example, you might decide to run `XOR RAX, RAX` at the end of your assembly code. This way, the event action will never be executed because RAX is zero, which means `FALSE`.

Or you can use `MOV RAX, 1` at the end of the code, the **RAX** is non-zero, which means that the event's actions should be executed.

By the way, it depends on your code and the condition of your code.

The following code shows how to create a condition buffer at the kernel.

```c
    //
    // Create condition buffer
    //
    char CondtionBuffer[8];
    CondtionBuffer[0] = 0x90; //nop
    CondtionBuffer[1] = 0x48; //xor rax, rax
    CondtionBuffer[2] = 0x31;
    CondtionBuffer[3] = 0xc0;
    CondtionBuffer[4] = 0x48; // inc rax
    CondtionBuffer[5] = 0xff;
    CondtionBuffer[6] = 0xc0;
    CondtionBuffer[7] = 0xc3; // ret
```

{% hint style="warning" %}
Don't forget to put a **0xc3** or **ret instruction** at the end of your condition buffer. This way, you give the program's execution back to the debugger, and HyperDbg can continue normally. Otherwise, the HyperDbg won't get a chance to get back the execution and cause a crash.
{% endhint %}

### Adding the condition to the event

Adding condition buffer to the event is done when you are creating the event using `DebuggerCreateEvent`, you have to specify both a pointer to the buffer and the size of the buffer.

Look at the following example,

```c
    //
    // Create event based on condition buffer
    //
    PDEBUGGER_EVENT Event1 = DebuggerCreateEvent(
        TRUE,
        DEBUGGER_EVENT_APPLY_TO_ALL_CORES,
        DEBUGGER_EVENT_APPLY_TO_ALL_PROCESSES,
        HIDDEN_HOOK_READ,
        0x85858585,
        sizeof(CondtionBuffer),
        CondtionBuffer);
```

In the above example, `CondtionBuffer` is the pointer to the buffer that holds the assembly bytes and `sizeof(CondtionBuffer)` shows the size of the buffer.

{% hint style="info" %}
Each event can only have one condition.
{% endhint %}

The condition buffer function is called in the following form:

```c
typedef UINT64
DebuggerCheckForCondition(PGUEST_REGS Regs, PVOID Context);
```

The above function is called where `Regs` is in `RCX` and `Context` is in `RDX`.

`Regs` is the registers of the guest, you can directly modify them, and it will be applied to the guest in the normal execution, and you can also read these registers in this structure and the `Context` is event-specific, check each event's documentation to see what is in the `Context`.

The `Regs` or `RCX` is a pointer to the following structure.

```c
typedef struct _GUEST_REGS
{
    ULONG64 rax; // 0x00
    ULONG64 rcx; // 0x08
    ULONG64 rdx; // 0x10
    ULONG64 rbx; // 0x18
    ULONG64 rsp; // 0x20 
    ULONG64 rbp; // 0x28
    ULONG64 rsi; // 0x30
    ULONG64 rdi; // 0x38
    ULONG64 r8;  // 0x40
    ULONG64 r9;  // 0x48
    ULONG64 r10; // 0x50
    ULONG64 r11; // 0x58
    ULONG64 r12; // 0x60
    ULONG64 r13; // 0x68
    ULONG64 r14; // 0x70
    ULONG64 r15; // 0x78
} GUEST_REGS, *PGUEST_REGS;
```

{% hint style="success" %}
You can read other registers (non-general purpose registers) directly and modify them. We're not changing them or using them in debugger and hypervisor routines, so reading and changing them will directly apply to the guests' registers and apply to normal execution.
{% endhint %}


# Actions

Actions are defined in the following enumerations:

```
typedef enum _DEBUGGER_EVENT_ACTION_TYPE_ENUM {
  BREAK_TO_DEBUGGER,
  RUN_SCRIPT,
  RUN_CUSTOM_CODE
​
} DEBUGGER_EVENT_ACTION_TYPE_ENUM;

```

Script-engine is a different project in HyperDbg's solution. There is a file, called "**ScriptEngineCommon.h**". This file contains the HyperDbg script execution engine's implementation in both user-mode and kernel-mode, and it executes the scripts that were previously interpreted in user-mode.

In order to call the execution engine, you should call `ScriptEngineExecute` function.

If you want to interpret a script, you should call `ScriptEngineParseWrapper` which is a wrapper for `ScriptEngineParse`. This function gives a stack (memory) that can be executed in both user-mode and kernel-mode.

By using the following structure, `ScriptBufferSize` and `ScriptBufferPointer` we pass the script buffer to the kernel.

```c
typedef struct _DEBUGGER_GENERAL_ACTION {
  UINT64 EventTag;
  DEBUGGER_EVENT_ACTION_TYPE_ENUM ActionType;
  BOOLEAN ImmediateMessagePassing;
  UINT32 PreAllocatedBuffer;

  UINT32 CustomCodeBufferSize;
  UINT32 ScriptBufferSize;
  UINT32 ScriptBufferPointer;

} DEBUGGER_GENERAL_ACTION, *PDEBUGGER_GENERAL_ACTION;
```

Read [Scripting Language](https://docs.hyperdbg.org/commands/scripting-language) for more information and examples about script-engine and read [here ](https://docs.hyperdbg.org/design/script-engine)for more information about the script engine's design and internals.

### Custom Code

Running custom codes gives you a fast and reliable way to execute your codes in the case of triggering events without breaking the whole system, so it's super fast.

When you use `code { }` in your events, then you are using custom codes.

This powerful feature can optionally give you a non-paged pool buffer with your specific size and gives the address of the buffer to your assembly code in `RCX`. You can safely use this buffer in your assembly code, and if you want, HyperDbg will safely transfer this buffer to user mode for you.

First, you should create a buffer of bytes that performs your task. For example, the following code is some `nops` that a custom buffer provides to the debugger. You can change it to whatever assembly bytes that you want without any limitation in size.

```c
    char CustomCodeBuffer[8];
    CustomCodeBuffer[0] = 0x90; //nop
    CustomCodeBuffer[1] = 0x90; //nop
    CustomCodeBuffer[2] = 0x90; //nop
    CustomCodeBuffer[3] = 0x90; //nop
    CustomCodeBuffer[4] = 0x90; //nop
    CustomCodeBuffer[5] = 0x90; //nop
    CustomCodeBuffer[6] = 0x90; //nop
    CustomCodeBuffer[7] = 0xc3; //ret
```

{% hint style="warning" %}
Don't forget to put a **0xc3** or **ret instruction** at the end of your custom code buffer. This way, you give the program's execution back to the debugger, and HyperDbg can continue normally. Otherwise, the HyperDbg won't get a chance to get back the execution and cause a crash.
{% endhint %}

You should fill the following structure, which gives the details of your custom code to the debugger.

```c
typedef struct _DEBUGGER_EVENT_REQUEST_CUSTOM_CODE {
  UINT32 CustomCodeBufferSize;
  PVOID CustomCodeBufferAddress;
  UINT32 OptionalRequestedBufferSize;

} DEBUGGER_EVENT_REQUEST_CUSTOM_CODE, *PDEBUGGER_EVENT_REQUEST_CUSTOM_CODE;
```

For example, the following code shows that we use `CustomCodeBuffer`as the custom assembly code, and also, we set the size of the buffer. `OptionalRequestedBufferSize`is used to request a non-paged pool buffer. If this field is zero, then it means that you don't need a non-paged buffer, but if it's not zero, then HyperDbg will allocate a non-paged pool for you and pass the address of the buffer each time as the `RCX` to you assembly code.

```c
    //
    // Add action for RUN_CUSTOM_CODE
    //

    DEBUGGER_EVENT_REQUEST_CUSTOM_CODE CustomCode = {0};

    CustomCode.CustomCodeBufferSize        = sizeof(CustomCodeBuffer);
    CustomCode.CustomCodeBufferAddress     = CustomCodeBuffer;
    CustomCode.OptionalRequestedBufferSize = 0x100;
```

Finally, you have to register the action to the event using `DebuggerAddActionToEvent`.

Here's the prototype of **DebuggerAddActionToEvent**.

```c
BOOLEAN
DebuggerAddActionToEvent(PDEBUGGER_EVENT Event, DEBUGGER_EVENT_ACTION_TYPE_ENUM ActionType, BOOLEAN SendTheResultsImmediately, PDEBUGGER_EVENT_REQUEST_CUSTOM_CODE InTheCaseOfCustomCode, PDEBUGGER_EVENT_ACTION_RUN_SCRIPT_CONFIGURATION InTheCaseOfRunScript)
```

**Event** is the event in which you want to register this action on it.

**ActionType** is the type of action (described above).

**SendTheResultsImmediately** this field shows whether the buffer should be sent immediately to the user-mode or not.

It is because HyperDbg holds a queue of messages to be delivered to user mode. When the queue has multiple messages (the queue is full), it sends all of them in an IRP packet to the user mode (IRP Pending). This makes the HyperDbg messaging more efficient as we're not going to send each message separately in one IRP packet.

If you set this field to `TRUE`, the buffer will be delivered to the user -ode immediately, and if you set it to `FALSE`, then the buffers will be accumulated and delivered when the queue has multiple messages.

You should set it to `FALSE` in most cases, but if you need immediate results the choose `TRUE` and it makes your computer substantially slower in high rates of data delivery but at low rates `TRUE`makes more sense.

**InTheCaseOfCustomCode :** you should fill it as described above.

**InTheCaseOfRunScript :** is used for script engine, should be null in custom code.

The following example shows how to use the `DebuggerAddActionToEvent`.

```c
    DebuggerAddActionToEvent(Event1, RUN_CUSTOM_CODE, TRUE, &CustomCode, NULL);
```

{% hint style="danger" %}
Please note that **DebuggerAddActionToEvent** should not be called in vmx-root mode.
{% endhint %}

### How to send buffers back to user-mode?

If you didn't request a safe buffer or even request a safe buffer, then your assembly will be called in the following form.

```c
typedef PVOID
DebuggerRunCustomCodeFunc(PVOID PreAllocatedBufferAddress, PGUEST_REGS Regs, PVOID Context);
```

If you request a safe non-paged pool buffer, then your assembly will be called in the following form, and as we're calling it with **fastcall** calling convention, then you can expect buffer address in `RCX`.

```c
ReturnBufferToUsermodeAddress = Func(Action->RequestedBuffer.RequstBufferAddress, Regs, Context);
```

Otherwise, `RCX` is null (in the case, you didn't need a safe buffer).

```c
Func(NULL, Regs, Context);
```

In the above calls, `RDX`is the structure of the guest's general-purpose registers, you can modify them directly, and these registers will apply to the guest when it wants to continue its normal execution.

`R8` (Context) is an optional parameter that describes the state, and it's different for each event. You have to check each event's documentation to see what it is in that event.

The following structure shows the state of registers in `Regs` parameter. You can modify or read the general-purpose registers based on this structure as a pointer to this structure is available in `RDX`.

```c
typedef struct _GUEST_REGS
{
    ULONG64 rax; // 0x00
    ULONG64 rcx;
    ULONG64 rdx; // 0x10
    ULONG64 rbx;
    ULONG64 rsp; // 0x20 
    ULONG64 rbp;
    ULONG64 rsi; // 0x30
    ULONG64 rdi;
    ULONG64 r8; // 0x40
    ULONG64 r9;
    ULONG64 r10; // 0x50
    ULONG64 r11;
    ULONG64 r12; // 0x60
    ULONG64 r13;
    ULONG64 r14; // 0x70
    ULONG64 r15;
} GUEST_REGS, *PGUEST_REGS;
```

{% hint style="success" %}
You can read other registers (non-general purpose registers) directly and modify them. We're not changing them or using them in debugger and hypervisor routines, so reading and changing them will directly apply to the guests' registers and apply to normal execution.
{% endhint %}


# IOCTL


# Event Registration

How to programmatically activate an event using IOCTLs?

In order to send an IOCTL and enable an event programmatically, you should fill the following structure. This structure is used for tracing works in user mode and sending it to the kernel-mode. Keep in mind that this structure is not what we save for events in kernel-mode.

After sending this structure to the kernel, if it's valid, then the kernel creates a disabled event and is waiting for an action to be received then it activates the event.

```c
/**
 * @brief Each command is like the following struct, it also used for
 * tracing works in user mode and sending it to the kernel mode
 * @details THIS IS NOT WHAT HYPERDBG SAVES FOR EVENTS IN KERNEL MODE
 */
typedef struct _DEBUGGER_GENERAL_EVENT_DETAIL {

  LIST_ENTRY
  CommandsEventList; // Linked-list of commands list (used for tracing purpose
                     // in user mode)

  time_t CreationTime; // Date of creating this event

  UINT32 CoreId; // determines the core index to apply this event to, if it's
                 // 0xffffffff means that we have to apply it to all cores

  UINT32 ProcessId; // determines the process id to apply this to
                    // only that 0xffffffff means that we have to
                    // apply it to all processes

  BOOLEAN IsEnabled;

  BOOLEAN HasCustomOutput; // Shows whether this event has a custom output
                           // source or not

  UINT64
  OutputSourceTags
      [DebuggerOutputSourceMaximumRemoteSourceForSingleEvent]; // tags of
                                                               // multiple
                                                               // sources which
                                                               // can be used to
                                                               // send the event
                                                               // results of
                                                               // scripts to
                                                               // remote sources

  UINT32 CountOfActions;

  UINT64 Tag; // is same as operation code
  DEBUGGER_EVENT_TYPE_ENUM EventType;

  UINT64 OptionalParam1;
  UINT64 OptionalParam2;
  UINT64 OptionalParam3;
  UINT64 OptionalParam4;

  PVOID CommandStringBuffer;

  UINT32 ConditionBufferSize;

} DEBUGGER_GENERAL_EVENT_DETAIL, *PDEBUGGER_GENERAL_EVENT_DETAIL;
```

Based on your request, you can select one of the following actions from`DEBUGGER_EVENT_TYPE_ENUM` enum. This enum will be updated in future versions, but if you want to simulate a special command, check the command's manual to see what's the command's type.

```c
typedef enum _VMM_EVENT_TYPE_ENUM
{

    HIDDEN_HOOK_READ_AND_WRITE_AND_EXECUTE,
    HIDDEN_HOOK_READ_AND_WRITE,
    HIDDEN_HOOK_READ_AND_EXECUTE,
    HIDDEN_HOOK_WRITE_AND_EXECUTE,
    HIDDEN_HOOK_READ,
    HIDDEN_HOOK_WRITE,
    HIDDEN_HOOK_EXECUTE,

    HIDDEN_HOOK_EXEC_DETOURS,
    HIDDEN_HOOK_EXEC_CC,

    SYSCALL_HOOK_EFER_SYSCALL,
    SYSCALL_HOOK_EFER_SYSRET,

    CPUID_INSTRUCTION_EXECUTION,

    RDMSR_INSTRUCTION_EXECUTION,
    WRMSR_INSTRUCTION_EXECUTION,

    IN_INSTRUCTION_EXECUTION,
    OUT_INSTRUCTION_EXECUTION,

    EXCEPTION_OCCURRED,
    EXTERNAL_INTERRUPT_OCCURRED,

    DEBUG_REGISTERS_ACCESSED,

    TSC_INSTRUCTION_EXECUTION,
    PMC_INSTRUCTION_EXECUTION,

    VMCALL_INSTRUCTION_EXECUTION,

    CONTROL_REGISTER_MODIFIED,
    CONTROL_REGISTER_READ,

} VMM_EVENT_TYPE_ENUM;
```

If you want to use the debugger features, you should connect the `CommandsEventList` to the list of user-mode commands.

**OptionalParamX** is different in the case of each command. For example, in **!epthook2**, you should send the address of where you want to hook to the kernel as **OptionalParam1**. You have to check each command's manual to see what are its specific **OptionalParam**(s).

**Tag** is an ID that you can use later in action.

**IsEnabled** has a user-mode usage to trace whether the event is enabled or not.

**CommandStringBuffer** is the string of the command. You can ignore it.

If your event contains a condition buffer (`ConditionBufferSize != 0`), you can set the size of `ConditionBufferSize` and append the buffer to the end of the above structure, and when you send the buffer to the kernel, you should send the `sizeof(DEBUGGER_GENERAL_EVENT_DETAIL)+ ConditionBufferSize (if any)`.

Finally, you can send it to the kernel by using the following function.

```c
/**
 * @brief Register the event to the kernel
 */
BOOLEAN
SendEventToKernel(PDEBUGGER_GENERAL_EVENT_DETAIL Event,
                  UINT32 EventBufferLength);
```

If you want to send it directly using IOCTL, you can use the following IOCTL :

```c
#define IOCTL_DEBUGGER_REGISTER_EVENT                                          \
  CTL_CODE(FILE_DEVICE_UNKNOWN, 0x806, METHOD_BUFFERED, FILE_ANY_ACCESS)
```

After sending the above event to the kernel, you should chain an action or multiple actions to the event.

You should fill the following structure to send a "**Break**", "**Script**", and "**Custom Code**" to the kernel. For example, you can append the custom code buffer after this structure and send them together to the kernel.

Also, **EventTag** is the unique ID that we sent previously in the event.

```c
//
// Each event can have multiple actions
// THIS STRUCTURE IS ONLY USED IN USER MODE
// WE USE SEPARATE STRUCTURE FOR ACTIONS IN
// KERNEL MODE
//
typedef struct _DEBUGGER_GENERAL_ACTION {
  UINT64 EventTag;
  DEBUGGER_EVENT_ACTION_TYPE_ENUM ActionType;
  UINT32 PreAllocatedBuffer;
  UINT32 CustomCodeBufferSize;

} DEBUGGER_GENERAL_ACTION, *PDEBUGGER_GENERAL_ACTION;
```

You can send the action to the kernel using the following function. Make sure to send the `sizeof(DEBUGGER_GENERAL_ACTION)+ Size of Custom code (if any)` to the following function.

```c
/**
 * @brief Register the action to the event
 */
BOOLEAN
RegisterActionToEvent(PDEBUGGER_GENERAL_ACTION Action,
                      UINT32 ActionsBufferLength);
```

If you want to register the action to the event directly using `DeviceIoControl`, you can use the following IOCTL.

```c
#define IOCTL_DEBUGGER_ADD_ACTION_TO_EVENT                                     \
  CTL_CODE(FILE_DEVICE_UNKNOWN, 0x807, METHOD_BUFFERED, FILE_ANY_ACCESS)
```


# Debugging Commands


# ? (evaluate and execute expressions and scripts in debuggee)

Description of the '?' command in HyperDbg.

### Command <a href="#command" id="command"></a>

> ?

### Syntax <a href="#syntax" id="syntax"></a>

> ? \[Expression (string)]

### Description <a href="#description" id="description"></a>

Evaluates and executes an expression in the remote debuggee or in the user debugger.

{% hint style="success" %}
You can write multiline scripts by putting the scripts between two curly brackets.

For example,

`? {`

`printf("first line");`

`printf("second line");`

`printf("third line");`

`}`
{% endhint %}

### Parameters <a href="#parameters" id="parameters"></a>

**\[Expression (string)]**

The expression is based on HyperDbg's [scripting language](https://web.archive.org/web/20210228003007/https://docs.hyperdbg.org/commands/scripting-language/assumptions-and-evaluations).

### Examples <a href="#examples" id="examples"></a>

The following command shows the `@rax` register along with the process name and process ID in the debuggee by calling the [printf](https://docs.hyperdbg.org/commands/scripting-language/functions/exports/printf) function.

```clike
0: kHyperDbg> ? printf("The RAX register is: %llx at Process Name: %s (pid: %x)", @rax, $pname, $pid);
```

You can use register assignment within scripts (You can change the value of registers).

```clike
0: kHyperDbg> ? @rax = 0x55;	        // change the RAX register value

0: kHyperDbg> ? @cr0 = @cr0 | 0x4;        // set the third bit of CR0 register

0: kHyperDbg> ? @zf = 1;   	        // set the Zero Flag

0: kHyperDbg> ? @ebx = @ecx + 10 + @ax;   // set the value of EBX register
```

HyperDbg supports [conditional statements](https://docs.hyperdbg.org/commands/scripting-language/conditionals-and-loops) like **if**, **elsif**, and **else**. You can use any expressions, registers, pseudo-registers, variables, or results of functions in the **if**, **elsif** statements.

```clike
0: kHyperDbg> ? {
    if (@rax == 55) {
    	     printf("rax is equal to 0x55");
    }
}

0: kHyperDbg> ? {
    if (poi(@rcx + 0x10) == ffff7080deadbeef && @rdx != 55 || $pid == 4) {
    	     printf("condition is met\n");
    }
}

0: kHyperDbg> ? {
    if (check_address(@r11) == 1) { 
    	     printf("address is valid.\n");
    }
    else
    {
	     printf("address is invalid.\n");
    }
}
```

For loops and nested loops are supported.

```clike
0: kHyperDbg> ? {
for (i = 0; i < 10 ; i++) {
       for (j = 0; j < 10; j++) {
       	  printf("%d, %d\n", i, j); 
       }
    }
 }
```

If you want to change memory, you can use [eq, ed, eb](https://docs.hyperdbg.org/commands/scripting-language/functions/memory/eb-ed-eq) functions.

```css
0: kHyperDbg> ? {

	if (eq(@r11, 0x12345678deadbeef) == 1) { 
	    printf("changes are applied.\n");
	}
	else {
            printf("changes are NOT applied.\n");
	}
}
```

There are many [functions](https://docs.hyperdbg.org/commands/scripting-language/functions) and [examples](https://docs.hyperdbg.org/commands/scripting-language/examples) available for HyperDbg’s script engine.

### Arguments <a href="#examples" id="examples"></a>

Arguments to the script are passed to the script by using the `$arg0`, `$arg1`, `$arg2`, ..., `$arg100`, ..., `$arg1000` and so on. HyperDbg uses the ‘**.ds**’ extension for the script files.

The first argument (`$arg0`) is the script's **.ds** file path. Arguments can be both an expression, a constant, or a string. Constants are considered in hex format if no prefix is specified.

#### Example

```clike
? { 
      printf("First argument is : %llx\n", $arg1);
      printf("Result of rax + rbx is : %llx\n", $arg2);
}
```

We run the above script by using the “[.script](https://docs.hyperdbg.org/commands/meta-commands/.script)” command.

```clike
0: kHyperDbg> .script "C:\path to script\script.ds" 55 @rax+@rbx
```

### IOCTL <a href="#ioctl" id="ioctl"></a>

To run a script on the target process (thread) in the user debugger or in the target debuggee in the kernel debugger, you need to use the following function in `libhyperdbg`:

```clike
BOOLEAN
hyperdbg_u_run_script(CHAR * Expr, BOOLEAN ShowErrorMessageIfAny);
```

### Remarks <a href="#remarks" id="remarks"></a>

Other aliases for this command are '**eval**' and '**evaluate**'.

You can check the definition and examples of [script engine functions](https://docs.hyperdbg.org/commands/scripting-language/functions), as well as [examples for using scripts](https://docs.hyperdbg.org/commands/scripting-language/examples).

To use this command, you must either be in [debugger mode](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#debugger-mode), or in [VMI mode](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#vmi-mode) with the user debugger attached to a thread. Otherwise, the command runs in test mode (register and system state are not valid in the test mode since you are not connected to any debuggee).

This command is guaranteed to keep debuggee in a halt state (in Debugger Mode); thus, nothing will change during its execution.

### Requirements <a href="#requirements" id="requirements"></a>

None

### Related <a href="#related" id="related"></a>

None


# \~ (display and change the current operating core)

Description of the '\~' command in HyperDbg.

### Command

> \~

### Syntax

> \~
>
> \~ \[CoreNumber (hex)]

### Description

Shows or changes the current operating core. This command can only be used in **Debugger Mode**.

### Parameters

**\[CoreNumber (hex)] (optional)**

Target core number (starts from zero).

{% hint style="success" %}
If you don't specify any parameters to the '\~' command, it shows the current operating core.
{% endhint %}

### Examples

The following command shows the current operating core.

```diff
0: kHyperDbg> ~
current processor : 0x2
```

The following commands display and then change the current operating core to `0x1`.

```
0: kHyperDbg> ~
current processor : 0x2

0: kHyperDbg> ~ 1
current operating core changed to 0x1
fffff801`633f157f    C3                                  ret

0: kHyperDbg> ~
current processor : 0x1
```

### IOCTL

This command works over serial by sending the serial packets to the remote computer.

First of all, you should fill the following structure, set the `NewCore` to your target core, and leave the `Result`.

```c
typedef struct _DEBUGGEE_CHANGE_CORE_PACKET {

UINT32 NewCore; 
UINT32 Result;

} DEBUGGEE_CHANGE_CORE_PACKET, *PDEBUGGEE_CHANGE_CORE_PACKET;
```

After that, send the above structure to the debuggee when debuggee is paused and waiting for new command on **vmx-root** mode.

You should send the above structure with `DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_MODE_CHANGE_CORE` as `RequestedAction` and `DEBUGGER_REMOTE_PACKET_TYPE_DEBUGGER_TO_DEBUGGEE_EXECUTE_ON_VMX_ROOT` as `PacketType`.

In return, the debuggee sends the above structure with the following type.

```c
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_CHANGING_CORE
```

In the returned structure, the `Result` is filled by the kernel.

If the `Result` is `DEBUGEER_OPERATION_WAS_SUCCESSFULL`, then the operation was successful, and you should wait for a new pause packet from debuggee. Otherwise, the returned result is an error (e.g., the core number is invalid), and the current operating core is not changed.

The following function is responsible for changing the core in the debugger.

```c
BOOLEAN KdSendSwitchCorePacketToDebuggee(UINT32 NewCore);
```

### Remarks

If the current core is equal to the target core, then it will not be changed.

Another alias for the '**\~**' command is '**core**'.

This command is guaranteed to keep debuggee in a halt state (in Debugger Mode); thus, nothing will change during its execution.

### Requirements

None

### Related

None


# a (assemble virtual address)

Description of the 'a' command in HyperDbg.

### Command

> a

### Syntax

> a \[Address (hex)] \[asm {AsmCmd1; AsmCmd2}] \[pid ProcessId (hex)]

### Description

Assembles (shows HEX byte codes) or puts the resulting instruction codes into the (virtual) memory.

### Parameters

**\[Address (hex)] (optional)**

The **virtual** address of where we want to start putting resulting codes into its memory.

{% hint style="info" %}
If the **Address** is empty, you can use it to only assemble instructions without modifying the memory.
{% endhint %}

**\[asm {AsmCmd1; AsmCmd2}]**

The target assembly codes.

**\[pid ProcessId (hex)] (optional)**

The Process ID that's in the hex format is what we want to put the memory to its context (**cr3**).

{% hint style="info" %}
If you don't specify the **pid**, then the default **pid** is the current process (HyperDbg) process layout of memory.
{% endhint %}

### Examples

If you just want to view the result of assembly (byte codes in HEX) without modifying the memory, the following command can be used.

```
HyperDbg> a { nop; xor rax, rax; nop }
warning, no start address provided to calculate relative asm commands

generated assembly: 5 bytes, 3 statements ==>>  nop; xor rax, rax; nop  = 90 48 31 c0 90
```

The following command is used when we want to assemble assembly codes and put the resulting bytes into the target memory at ``fffff800`3ad6f010`` .

```diff
HyperDbg> a fffff800`3ad6f010 { nop; nop; nop }
generated assembly: 3 bytes, 3 statements ==>>  nop; nop; nop  = 90 90 90
successfully assembled at 0xfffff8003ad6f010 address
```

The following command is used when we want to assemble assembly codes and put the resulting bytes into the target memory at `nt!ExAllocatePoolWithTag` .

```diff
2: kHyperDbg> a nt!ExAllocatePoolWithTag { nop; nop; nop }
generated assembly: 3 bytes, 3 statements ==>>  nop; nop; nop  = 90 90 90
successfully assembled at 0xfffff804136acc80 address
```

The following command is used when we want to assemble assembly codes and put the resulting bytes into the target memory at `nt!ExAllocatePoolWithTag+5` .

```diff
2: kHyperDbg> a nt!ExAllocatePoolWithTag+5 { nop; nop; nop }
generated assembly: 3 bytes, 3 statements ==>>  nop; nop; nop  = 90 90 90
successfully assembled at 0xfffff804136acc85 address
```

You can also write multiple lines of assembly codes and use function names in your assembly:

```
2: kHyperDbg> a nt!ExAllocatePoolWithTag {
>       add DWORD PTR [<nt!ExAllocatePoolWithTag+10+@rax>], 99;
>       nop;
>       nop
>       }
generated assembly: 12 bytes, 3 statements ==>>         add DWORD PTR [0xfffff804138cecd4], 99; nop;    nop      = 81 05 4a 20 22 00 99 00 00 00 90 90
successfully assembled at 0xfffff804136acc80 address
```

### SDK

To assemble a buffer, you need to use the following function in `libhyperdbg`:

```clike
BOOLEAN
hyperdbg_u_assemble(const CHAR * assembly_code, UINT64 start_address, PVOID buffer_to_store_assembled_data, UINT32 buffer_size);
```

To get the length of the assembly code, you need to use the following function in `libhyperdbg`:

```clike
BOOLEAN
hyperdbg_u_assemble_get_length(const CHAR * assembly_code, UINT64 start_address, UINT32 * length);
```

### Remarks

* By default, HyperDbg converts addresses to the object names (if the symbol for that address is available). If you want to see the address in hex format, you can turn `addressconversion` to **off** using the '[settings](https://docs.hyperdbg.org/commands/debugging-commands/settings)' command.
* To view the byte code of an assembly snippet, you can use the following command (`StartAddress` is useful when dealing with relative instructions like **JMP**).

```
 a {jmp <nt!ExAllocatePoolWithTag+10>} [StartAddress]
```

{% hint style="success" %}
HyperDbg uses [**keystone**](https://github.com/keystone-engine/keystone) as its core assembler.
{% endhint %}

This command is guaranteed to keep debuggee in a halt state (in Debugger Mode); thus, nothing will change during its execution.

### Requirements

None

### Related

[Keystone](https://www.keystone-engine.org/)

[!a (assemble physical address)](https://docs.hyperdbg.org/commands/extension-commands/a)

[u, u64, u2, u32 (disassemble virtual address)](https://docs.hyperdbg.org/commands/debugging-commands/u)

[!u, !u64, !u2, !u32 (disassemble physical address)](https://docs.hyperdbg.org/commands/extension-commands/u)


# load (load modules)

Description of the 'load' command in HyperDbg.

### Command

> load

### Syntax

> load \[ModuleName (string)]

### Description

Loads the HyperDbg's drivers and kernel modules into the target system.

### Parameters

**\[ModuleName (string)]**

The name of the module that you want to load.

## Modules

| Module Name | Description                                   |
| ----------- | --------------------------------------------- |
| all         | Loading all available modules                 |
| kd          | Kernel module (parent module for all modules) |
| vmm         | Hypervisor-related capabilities               |
| trace       | Tracing (Intel LBR, Intel PT) capabilities    |

{% hint style="info" %}
Most of the debugging functions are implemented on top of '**vmm**' module. If you load any of the above modules (**vmm**, **trace**, etc.), the **kd** module will be loaded automatically.
{% endhint %}

**KD**: This module contains certain debugging commands and is also the parent of all modules (manages and loads all other modules)

**VMM**: This module contains commands related to the debugger and all hypervisor-related capabilities.

**Trace**: This module contains commands for tracing functions such as Intel Processor Trace (PT) and Last Branch Record (LBR).

### Examples

The following example loads `vmm` module.

```
HyperDbg> load vmm
```

The following example loads `trace` module.

```
HyperDbg> load trace
```

The following example loads `all` modules.

```
HyperDbg> load all
```

The following example loads `kd` module.

```
HyperDbg> load kd
```

### SDK

To load the HyperDbg drivers on the local machine, you need to use the following function in `libhyperdbg` (depending on the module you want to load):

```c
INT

//
// All Modules
//
INT
hyperdbg_u_load_all_modules();

//
// VMM Module
//
INT
hyperdbg_u_load_vmm();

//
// KD (Kernel Debugger) Module
//
INT
hyperdbg_u_load_kd_module();

//
// HyperTrace Module
//
INT
hyperdbg_u_load_hypertrace_module();
```

Make sure to install drivers before loading the driver.

```c
INT
hyperdbg_u_install_kd_driver();
```

### Remarks

The application that requests to load the kernel modules should have `SeDebugPrivilege` to obtain a handle, otherwise an `ACCESS_DENIED` is thrown.

This 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.

### Requirements

* Intel VT-x is required to be enabled to load the `vmm` module.
* For the `vmm` module, Intel Extended Page Table (a.k.a. SLAT) should be present in the processor. If you have a Nehalem (2008) processor or a newer processor, then it supports this feature.
* Intel PT and Intel LBR are required for loading the `trace` module.

### Related

[unload (unload the kernel modules)](https://docs.hyperdbg.org/commands/debugging-commands/unload)


# unload (unload modules)

Description of the 'unload' command in HyperDbg.

### Command

> unload

### Syntax

> unload \[remove] \[ModuleName (string)]

### Description

Unloads the HyperDbg drivers and kernel modules from the target system.

### Parameters

**\[remove] (optional)**

If you want to remove the installed driver. (See **Remarks** for more information)

**\[ModuleName (string)]**

The name of the module that you want to unload.

## Modules

| Module Name | Description                                   |
| ----------- | --------------------------------------------- |
| all         | Loading all available modules                 |
| kd          | Kernel module (parent module for all modules) |
| vmm         | Hypervisor-related capabilities               |
| trace       | Tracing (Intel LBR, Intel PT) capabilities    |

### Examples

The following example unloads `vmm` module.

```
HyperDbg> unload vmm
```

The following example unloads `all` modules.

```
HyperDbg> unload all
```

The following example unloads `vmm` module and removes all drivers.

```
HyperDbg> unload remove vmm
```

The following example unloads `all` modules and removes all drivers.

```
HyperDbg> unload remove all
```

The following example unloads `trace` module.

```
HyperDbg> unload trace
```

The following example unloads `kd` module.

```
HyperDbg> unload kd
```

### SDK

To unload the HyperDbg driver on the local machine, you need to use the following functions in `libhyperdbg` (depending on the module you want to load):

```c
//
// All Modules
//
INT
hyperdbg_u_unload_all_modules();

//
// VMM Module
//
INT
hyperdbg_u_unload_vmm();

//
// KD (Kernel Debugger) Module
//
INT
hyperdbg_u_unload_kd();

//
// HyperTrace Module
//
INT
hyperdbg_u_unload_hypertrace_module();
```

Later you can stop and uninstall (remove) the driver using the following SDK function:

```c
INT
hyperdbg_u_stop_kd_driver();

INT
hyperdbg_u_uninstall_kd_driver();
```

### Remarks

This 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.

### Requirements

None

### Related

[load (load the kernel modules)](https://docs.hyperdbg.org/commands/debugging-commands/load)


# status (show the debuggee status)

Description of the 'status' command in HyperDbg.

### Command

> status

### Syntax

> status

### Description

Shows the connection status of the **HyperDbg**'s Connection.

### Parameters

None

### Examples

The following example shows the status of the **debuggee**.

```
HyperDbg (192.168.1.10:50000)> status
local debugging ('vmi mode')
```

### IOCTL

None

### Remarks

In **HyperDbg**, 'status' and '[.status](https://docs.hyperdbg.org/commands/meta-commands/.status)' commands are different if you connected to a remote debugger, but if you try to debug your system locally, then these commands are the same.

If you execute the '[.status](https://docs.hyperdbg.org/commands/meta-commands/.status)' command, it shows the current debugger's status (the debuggee's IP address). If you execute the '**status**' command, it will be executed in the debuggee and shows the debuggee's state (not debugger).

This 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.

### Requirements

None

### Related

[.status (show the debugger status)](https://docs.hyperdbg.org/commands/meta-commands/.status)


# events (show and modify active/disabled events)

Description of the 'event' command in HyperDbg.

### Command

> events

### Syntax

> events
>
> events \[e|d|c all|EventNumber (hex)]
>
> events \[sc State (on|off)]

### Description

Shows a list of active/disabled events and commands or disables or clears the event(s). This command is also able to change the '[short-circuiting](https://docs.hyperdbg.org/tips-and-tricks/misc/event-short-circuiting)' state of the corresponding execution of the event.

### Parameters

**\[e|d|c all|EventNumber (hex)] (optional)**

Type of action can be one of the `e`, `d`, or `c`.

**e** : enables the target event

**d** : disables the target event

**c** : clears and removes the target event

Specifies the target event (you can see the list of events and their unique event numbers by running the '**events**' command), you can specify `all` to apply your action to all active/disabled events.

{% hint style="success" %}
If you don't specify any parameters to the '**events**' command, it shows a list of events and their unique event numbers.
{% endhint %}

### Examples

The following command shows the list of active/disabled events.

```diff
HyperDbg> events
0       (enabled)           !syscall 80
1       (disabled)          !sysret 80
2       (enabled)           !msrwrite 80 code {90}
3       (enabled)           !cpuid
```

The following command disables an event with event number `1` and then we see the list of all events.

```diff
HyperDbg> events d 1

HyperDbg> events
0       (enabled)           !syscall 80
1       (disabled)          !sysret 80
2       (enabled)           !msrwrite 80 code {90}
3       (enabled)           !cpuid
```

The following command enables all of the events and commands.

```
HyperDbg> events e all

HyperDbg> events
0       (enabled)           !syscall 80
1       (enabled)           !sysret 80
2       (enabled)           !msrwrite 80 code {90}
3       (enabled)           !cpuid
```

The following command clears an event with event number `1`.

```
HyperDbg> events c 1

HyperDbg> events
0       (enabled)           !syscall 80
2       (enabled)           !msrwrite 80 code {90}
3       (enabled)           !cpuid
```

The following command clears and turns off every enabled and disabled event and commands.

```
0: kHyperDbg> events c all
```

The following function short-circuits the corresponding execution of the event. It **only** applies to the current execution of the event and will reset to the default short-circuiting state in the next execution of the event.

```
0: kHyperDbg> events sc on
```

### IOCTL

This function works by calling **DeviceIoControl** with `IOCTL = IOCTL_DEBUGGER_MODIFY_EVENTS`, you have to send it in the following structure.

```c
typedef struct _DEBUGGER_MODIFY_EVENTS {

  UINT64 Tag;          // Tag of the target event that we want to modify
  UINT64 KernelStatus; // Kernel put the status in this field
  DEBUGGER_MODIFY_EVENTS_TYPE
  TypeOfAction; // Determines what's the action (enable | disable | clear)

} DEBUGGER_MODIFY_EVENTS, *PDEBUGGER_MODIFY_EVENTS;
```

Where `Tag` is the tag of the event that you want to modify, you should leave `KernelStatus` as it will be filled by the kernel and shows whether the request was successful or not.

{% hint style="warning" %}
Keep in mind, `Tag` is not the same as event number, tags start from **DebuggerEventTagStartSeed** (by default **0x1000000**); thus, you can add this value to form a `Tag` from event number.
{% endhint %}

`TypeOfAction` shows what type of action you want the kernel to perform (**enable**, **disable, or clear**). It can be one of the following values.

```c
typedef enum _DEBUGGER_MODIFY_EVENTS_TYPE {
  DEBUGGER_MODIFY_EVENTS_ENABLE,
  DEBUGGER_MODIFY_EVENTS_DISABLE,
  DEBUGGER_MODIFY_EVENTS_CLEAR
} DEBUGGER_MODIFY_EVENTS_TYPE;
```

If you want to apply the action to all the events/commands, then you should fill the `Tag` with the following constant.

```c
#define DEBUGGER_MODIFY_EVENTS_APPLY_TO_ALL_TAG 0xffffffffffffffff
```

When the request is finished, the kernel fills the user-mode buffer with one of the following values, which indicates whether the request was successful or there was an error.

In the case of success :

```c
#define DEBUGEER_OPERATION_WAS_SUCCESSFULL 0xFFFFFFFF
```

In the case of error :

```c
#define DEBUGGER_ERROR_DEBUGGER_MODIFY_EVENTS_INVALID_TAG 0xc000000e
#define DEBUGGER_ERROR_DEBUGGER_MODIFY_EVENTS_INVALID_TYPE_OF_ACTION 0xc000000f
```

For event short-circuiting, you should send the following structure to the kernel.

```clike
typedef struct _DEBUGGER_SHORT_CIRCUITING_EVENT
{
    UINT64  KernelStatus;      // Kernel put the status in this field
    BOOLEAN IsShortCircuiting; // Determines whether to perform short circuting (on | off)

} DEBUGGER_SHORT_CIRCUITING_EVENT, *PDEBUGGER_SHORT_CIRCUITING_EVENT;
```

The above structure should be sent to the debugger by the following `RequestedAction`,

`DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_SET_SHORT_CIRCUITING_STATE`.

### Remarks

{% hint style="danger" %}
**Important note**

If you are operating in [Debugger Mode](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#debugger-mode), you can enable, disable, clear events or change short-circuiting state while the debuggee is in a halt state and the context (memory and registers) remains untouched. 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.
{% endhint %}

### Requirements

None

### Related

[Event short-circuiting](https://docs.hyperdbg.org/tips-and-tricks/misc/event-short-circuiting)


# p (step-over)

Description of the 'p' command in HyperDbg.

### Command

> p
>
> pr

### Syntax

> p
>
> p \[Count (hex)]
>
> pr
>
> pr \[Count (hex)]

### Description

Executes a single instruction (step-over) and optionally displays the resulting values of all registers and flags.

### Parameters

**\[Count (hex)] (optional)**

Count of step(s), or how many times perform the stepping operation. If you don't set this argument, then by default, the **Count** is `1`.

### Examples

If you want to step-over one instruction.

```
0: kHyperDbg> p
fffff801`68d91267    41 5B                               pop r11
```

If you want to step-over one instruction and view the registers.

```c
0: kHyperDbg> pr
fffff801`68d91269    41 5A                               pop r10
RAX=0000000000000000 RBX=ffff948cbf6599d0 RCX=0000000000000024
RDX=0000000000000000 RSI=0000000000000000 RDI=ffff948cc266d670
RIP=fffff80168d91269 RSP=ffff9305492df6a8 RBP=0000000000000002
R8=0000000000000000  R9=0000000000000000  R10=0000000048564653
R11=0000000000000000 R12=0000000000000000 R13=0000000000000000
R14=ffff948cc266d670 R15=ffff948cc058e6b0 IOPL=00
OF 0  DF 0  IF 0  SF  0
ZF 1  PF 1  CF 0  AXF 0
CS 0010 SS 0018 DS 002b ES 002b FS 0053 GS 002b
RFLAGS=0000000000040046
```

If you want to step-over for `5` instructions.

```c
0: kHyperDbg> p 5
fffff801`68d9126b    9D                                  popfq
fffff801`68d9126c    C3                                  ret
fffff801`63a12948    6A D1                               push 0xFFFFFFFFFFFFFFD1
fffff801`63a1294a    E9 B1 00 00 00                      jmp 0xFFFFF80163A12A00
fffff801`63a12b00    F6 44 24 10 01                      test byte ptr ss:[rsp+0x10], 0x01
```

### SDK

To step-over the instruction, you need to use the following function in `libhyperdbg`:

```clike
BOOLEAN
hyperdbg_u_stepping_step_over();
```

### Remarks

This command will set a **trap flag** in debuggee and continue all the cores. After executing one instruction, it halts the debuggee again.

If the target instruction is a call instruction, it configures the first hardware debug register breakpoint to the instruction after that call. After that, it continues the debuggee and waits for the call to be returned and the next instruction (after the call) to be executed.

All cores and threads (except the currently executing thread) find a chance to be executed between each step in this type of stepping.

If you load symbols and you don't want to see function names, you can turn **addressconversion** off in the '[settings](https://docs.hyperdbg.org/commands/debugging-commands/settings)' command.

### Requirements

None

### Related

[t (step-in)](https://docs.hyperdbg.org/commands/debugging-commands/t)

[i (instrumentation step-in)](https://docs.hyperdbg.org/commands/debugging-commands/i)

[gu (step-out or go up)](https://docs.hyperdbg.org/commands/debugging-commands/gu)


# t (step-in)

Description of the 't' command in HyperDbg.

### Command

> t
>
> tr

### Syntax

> t
>
> t \[Count (hex)]
>
> tr
>
> tr \[Count (hex)]

### Description

Executes a single instruction (step-in) and optionally displays the resulting values of all registers and flags.

{% hint style="success" %}
The difference between this command and the '[i](https://docs.hyperdbg.org/commands/debugging-commands/i)' command is that, in the '[i](https://docs.hyperdbg.org/commands/debugging-commands/i)' command, no other cores and other threads find a chance to be executed during the stepping process; the system is fully halted, and only the current core will execute just one instruction and halts again. However, in this command, all the threads and cores are continued until an instruction in the target thread is executed. This command won't follow the execution between different rings.
{% endhint %}

### Parameters

**\[Count (hex)] (optional)**

Count of step(s), or how many times perform the stepping operation. If you don't set this argument, then by default, the **Count** is `1`.

### Examples

If you want to step-in one instruction.

```
0: kHyperDbg> t
fffff801`68d91267    41 5B                               pop r11
```

If you want to step-in one instruction and view the registers.

```c
0: kHyperDbg> tr
fffff801`68d91269    41 5A                               pop r10
RAX=0000000000000000 RBX=ffff948cbf6599d0 RCX=0000000000000024
RDX=0000000000000000 RSI=0000000000000000 RDI=ffff948cc266d670
RIP=fffff80168d91269 RSP=ffff9305492df6a8 RBP=0000000000000002
R8=0000000000000000  R9=0000000000000000  R10=0000000048564653
R11=0000000000000000 R12=0000000000000000 R13=0000000000000000
R14=ffff948cc266d670 R15=ffff948cc058e6b0 IOPL=00
OF 0  DF 0  IF 0  SF  0
ZF 1  PF 1  CF 0  AXF 0
CS 0010 SS 0018 DS 002b ES 002b FS 0053 GS 002b
RFLAGS=0000000000040046
```

If you want to step-in for `5` instructions.

```c
0: kHyperDbg> t 5
fffff801`68d9126b    9D                                  popfq
fffff801`68d9126c    C3                                  ret
fffff801`63a12948    6A D1                               push 0xFFFFFFFFFFFFFFD1
fffff801`63a1294a    E9 B1 00 00 00                      jmp 0xFFFFF80163A12A00
fffff801`63a12b00    F6 44 24 10 01                      test byte ptr ss:[rsp+0x10], 0x01
```

### SDK

To step through the instruction (regular step-in), you need to use the following function in `libhyperdbg`:

```clike
BOOLEAN
hyperdbg_u_stepping_regular_step_in();
```

### Remarks

This command will set a **trap flag** in debuggee and continue all the cores. After executing one instruction, it halts the debuggee again.

If the currently executing instruction is a **call** instruction, it will follow and enter the call instruction.

All cores and threads (except the currently executing thread) find a chance to be executed between each step in this type of stepping.

If you load symbols and you don't want to see function names, you can turn **addressconversion** off in the '[settings](https://docs.hyperdbg.org/commands/debugging-commands/settings)' command.

### Requirements

None

### Related

[p (step-over)](https://docs.hyperdbg.org/commands/debugging-commands/p)

[i (instrumentation step-in)](https://docs.hyperdbg.org/commands/debugging-commands/i)

[gu (step-out or go up)](https://docs.hyperdbg.org/commands/debugging-commands/gu)


# i (instrumentation step-in)

Description of the 'i' command in HyperDbg.

### Command

> i
>
> ir

### Syntax

> i
>
> i \[Count (hex)]
>
> ir
>
> ir \[Count (hex)]

### Description

Executes a single instruction (step-in) and optionally displays the resulting values of all registers and flags. This command only works in the [Debugger Mode](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#debugger-mode).

{% hint style="success" %}
The difference between this command and the '[t](https://docs.hyperdbg.org/commands/debugging-commands/t)' command is that no other cores and other threads find a chance to be executed during the stepping process; the system is fully halted, and only the current core will execute just one instruction and halts again.
{% endhint %}

{% hint style="info" %}
This command gives you the ability to follow system-calls (SYSCALLs) and all the exceptions (including **page-faults**) from user-mode to kernel-mode and from kernel-mode to user-mode. For example, in the middle of executing one instruction in user-mode, a page-fault might happen, then if you use this command, the next instruction is in the kernel-mode **page-fault** handler. Another example, you can follow a *syscall* from user-mode, then the next instruction is in kernel-mode **syscall handler**, and this way, you can trace the execution between different rings.
{% endhint %}

### Parameters

**\[Count (hex)] (optional)**

Count of step(s), or how many times perform the stepping operation. If you don't set this argument, then by default, the **Count** is `1`.

### Examples

If you want to instrumentation step-in one instruction.

```
0: kHyperDbg> i
fffff801`68d91267    41 5B                               pop r11
```

If you want to instrumentation step-in one instruction and view the registers.

```c
0: kHyperDbg> ir
fffff801`68d91269    41 5A                               pop r10
RAX=0000000000000000 RBX=ffff948cbf6599d0 RCX=0000000000000024
RDX=0000000000000000 RSI=0000000000000000 RDI=ffff948cc266d670
RIP=fffff80168d91269 RSP=ffff9305492df6a8 RBP=0000000000000002
R8=0000000000000000  R9=0000000000000000  R10=0000000048564653
R11=0000000000000000 R12=0000000000000000 R13=0000000000000000
R14=ffff948cc266d670 R15=ffff948cc058e6b0 IOPL=00
OF 0  DF 0  IF 0  SF  0
ZF 1  PF 1  CF 0  AXF 0
CS 0010 SS 0018 DS 002b ES 002b FS 0053 GS 002b
RFLAGS=0000000000040046
```

If you want to instrumentation step-in for `5` instructions.

```c
0: kHyperDbg> i 5
fffff801`68d9126b    9D                                  popfq
fffff801`68d9126c    C3                                  ret
fffff801`63a12948    6A D1                               push 0xFFFFFFFFFFFFFFD1
fffff801`63a1294a    E9 B1 00 00 00                      jmp 0xFFFFF80163A12A00
fffff801`63a12b00    F6 44 24 10 01                      test byte ptr ss:[rsp+0x10], 0x01
```

### SDK

To step through the instruction (instrumentation step-in), you need to use the following function in `libhyperdbg`:

```clike
BOOLEAN
hyperdbg_u_stepping_instrumentation_step_in();
```

### Remarks

This command will set a **Monitor Trap Flag** in debuggee and continue just the current executing core. After executing one instruction, it halts the debuggee again.

If the currently executing instruction is a **call** instruction, it will follow and enter the call instruction.

HyperDbg guarantees that all cores and threads won't find a chance to be executed between each step in this type of stepping.

If you load symbols and you don't want to see function names, you can turn **addressconversion** off in the '[settings](https://docs.hyperdbg.org/commands/debugging-commands/settings)' command.

### Requirements

None

### Related

[p (step-over)](https://docs.hyperdbg.org/commands/debugging-commands/p)

[t (step-in)](https://docs.hyperdbg.org/commands/debugging-commands/t)

[gu (step-out or go up)](https://docs.hyperdbg.org/commands/debugging-commands/gu)


# gu (step-out or go up)

Description of the 'gu' command in HyperDbg.

### Command

> gu

### Syntax

> gu
>
> gu \[Count (hex)]

### Description

Executes instructions one by one until one **RET** instruction is executed (step-out or go up).

### Parameters

**\[Count (hex)] (optional)**

The number of **instructions** to perform the instrumentation (The execution might not meet a RET instruction if not enough number is specified).

### Examples

If you want to step-out or go up from the current function.

```
4: kHyperDbg> gu
ntkrnlmp!KiSystemServiceCopyEnd+0x25:
fffff802`2d045fe5    0F 1F 00                            nop dword ptr ds:[rax], eax
```

### SDK

To step-out or go up in the target debuggee, you need to use the following function in `libhyperdbg`:

```clike
BOOLEAN
hyperdbg_u_stepping_step_over_for_gu(BOOLEAN last_instruction);
```

### Remarks

Starting from **v0.6**, this command was added to the HyperDbg debugger.

This command is the same as the '[p (step-over)](https://docs.hyperdbg.org/commands/debugging-commands/p)' except it checks whether the instruction is equal to **RET** or not.

All cores and threads (except the currently executing thread) find a chance to be executed between each step in this command.

### Requirements

None

### Related

[k, kd, kq (display stack backtrace)](https://docs.hyperdbg.org/commands/debugging-commands/k)

[p (step-over)](https://docs.hyperdbg.org/commands/debugging-commands/p)

[t (step-in)](https://docs.hyperdbg.org/commands/debugging-commands/t)

[i (instrumentation step-in)](https://docs.hyperdbg.org/commands/debugging-commands/i)


# r (read or modify registers)

Description of the 'r' command in HyperDbg.

### Command

> r

### Syntax

> r
>
> r \[Register (string)] \[= Expr (string)]

### Description

Reads or modifies registers when the debuggee is paused.

### Parameters

**\[Register (string)] (optional)**

The register that needs to be read or modified.

**\[= Expr (string)] (optional)**

The value or the expression that needs to be evaluated and modify the target register.

{% hint style="info" %}
If you don't specify any parameters to the 'r' command, it shows all general-purpose + segment registers.
{% endhint %}

{% hint style="success" %}
The first parameter to this command is a register (not an expression). If you want to evaluate and see the result of registers as an expression (e.g., `rax+rbx+rcx`) then you can use the '[.formats](https://docs.hyperdbg.org/commands/meta-commands/.formats)' command.
{% endhint %}

### Examples

If you want to see all general purpose and segment registers.

```bash
0: kHyperDbg> r
RAX=ffff948cc1ba4780 RBX=ffff948cc02f19e0 RCX=0000000000000024
RDX=0000000000000000 RSI=0000000000000000 RDI=ffff948cc23403a0
RIP=fffff80168d91262 RSP=ffff9305483f3698 RBP=0000000000000002
R8=0000000000000000  R9=0000000000000000  R10=0000000048564653
R11=0000564d43414c4c R12=4e4f485950455256 R13=0000000000000000
R14=ffff948cc23403a0 R15=ffff948cc05556b0 IOPL=00
OF 0  DF 0  IF 1  SF  0
ZF 1  PF 1  CF 0  AXF 0
CS=0010 SS=0018 DS=002b ES=002b FS=0053 GS=002b
RFLAGS=0000000000040246
```

If you want to see one special register (e.g., `rax`).

```
0: kHyperDbg> r rax
rax=ffff948cc1ba4780
```

If you want to see one special register (e.g., `cs`).

```
0: kHyperDbg> r cs
cs=0000000000000010
```

If you want to change a register to a constant hex value.

```
0: kHyperDbg> r rax = 10
```

If you want to change a register to a new value which is the result of an expression.

```
0: kHyperDbg> r rcx = rax + rdx + 10
```

### SDK

To read all registers in the target debuggee, you need to use the following function in `libhyperdbg`:

```clike
BOOLEAN
hyperdbg_u_read_all_registers(GUEST_REGS * guest_registers, GUEST_EXTRA_REGISTERS * extra_registers);
```

To read a single register in the target debuggee, you need to use the following function in `libhyperdbg`:

```clike
BOOLEAN
hyperdbg_u_read_target_register(REGS_ENUM register_id, UINT64 * target_register);
```

To write (modify) a single register in the target debuggee, you need to use the following function in `libhyperdbg`:

```clike
BOOLEAN
hyperdbg_u_write_target_register(REGS_ENUM register_id, UINT64 value);
```

If you want to read all registers (based on current text messaging callback or std output), you can use the following function:

```clike
BOOLEAN
hyperdbg_u_show_all_registers();
```

If you want to read a single register (based on current text messaging callback or std output), you can use the following function:

```clike
BOOLEAN
hyperdbg_u_show_target_register(REGS_ENUM register_id);
```

### Remarks

This command is guaranteed to keep debuggee in a halt state (in Debugger Mode); thus, nothing will change during its execution.

### Requirements

None

### Related

None


# bp (set breakpoint)

Description of the 'bp' command in HyperDbg.

### Command

> bp

### Syntax

> bp \[Address (hex)] \[pid ProcessId (hex)] \[tid ThreadId (hex)] \[core CoreId (hex)]

### Description

Puts a breakpoint (**0xcc**) on the target function in user-mode and kernel-mode.

{% hint style="danger" %}
In **HyperDbg**, the 'bp' breakpoints are **NOT** [events](https://docs.hyperdbg.org/design/debugger-internals/events). If you want to use breakpoint in an event-like form (e.g., if you want to create logs using script-engine), you should use [!epthook](https://docs.hyperdbg.org/commands/extension-commands/epthook) command instead.
{% endhint %}

### Parameters

**\[Address (hex)]**

The **Virtual** address of where we want to put a breakpoint.

**\[pid ProcessId (hex)] \[tid ThreadId (hex)] \[core CoreId (hex)] (optional)**

Optional value to trigger breakpoint in just one special process or one special thread, or one special core. Add `pid xx` to your command or `tid yy` or `core zz`; thus, the command will be executed if the process id is equal to `xx` or the thread id is equal to `yy` or the core is equal to `zz` . If you don't specify these options, then by default, you receive breakpoints on all conditions. See the **Remarks** section for more information about **pid**.

### Context

As the **Context**, HyperDbg sends the **virtual** address of where the breakpoint is triggered (`RIP` of the triggered breakpoint).

### Examples

If you want to put breakpoints on `nt!ExAllocatePoolWithTag`, `nt!ExAllocatePoolWithTag+5`,`nt!ExAllocatePoolWithTag+@rax+5`, `fffff801639b1035`, `fffff801639b103a`, and `fffff801639b103f`, you can use the following commands.

```
0: kHyperDbg> bp nt!ExAllocatePoolWithTag
```

```
0: kHyperDbg> bp nt!ExAllocatePoolWithTag+5
```

```
0: kHyperDbg> bp nt!ExAllocatePoolWithTag+@rax+5
```

```
0: kHyperDbg> bp fffff801`639b1035
```

```
0: kHyperDbg> bp fffff801`639b103a
```

```
0: kHyperDbg> bp fffff801`639b103f
```

After that, you can see a list of active breakpoints using the '[bl](https://docs.hyperdbg.org/commands/debugging-commands/bl)' command.

```
HyperDbg> bl
id   address           status
--   ---------------   --------
01   fffff801639b1030  enabled
02   fffff801639b1035  enabled
03   fffff801639b1040  enabled
04   fffff801639b1035  enabled
05   fffff801639b103a  enabled
06  fffff801639b103f  enabled
```

### SDK

To set the breakpoint, you need to use the following function in `libhyperdbg`:

```clike
VOID
hyperdbg_u_set_breakpoint(UINT64 address, UINT32 pid, UINT32 tid, UINT32 core_number);
```

### Remarks

In this command, `pid xx` does not mean that we will change the layout to a new process, it means that the address should be available in the current process layout but will be triggered only on the process with process id equal to `xx`, you can use the '[.process](https://docs.hyperdbg.org/commands/meta-commands/.process)' command to switch to a new process if you want to put a breakpoint on the layout of another process.

This command is guaranteed to keep debuggee in a halt state (in Debugger Mode); thus, nothing will change during its execution.

### Requirements

None

### Related

[!epthook (hidden hook with EPT - stealth breakpoints)](https://docs.hyperdbg.org/commands/extension-commands/epthook)

[bl (list breakpoints)](https://docs.hyperdbg.org/commands/debugging-commands/bl)

[be (enable breakpoints)](https://docs.hyperdbg.org/commands/debugging-commands/be)

[bd (disable breakpoints)](https://docs.hyperdbg.org/commands/debugging-commands/bd)

[bc (clear and remove breakpoints)](https://docs.hyperdbg.org/commands/debugging-commands/bc)


# bl (list breakpoints)

Description of the 'bl' command in HyperDbg.

### Command

> bl

### Syntax

> bl

### Description

Lists all the enabled/disabled breakpoints.

### Parameters

None

### Examples

The following command shows how you can use the 'bl' command.

```
0: kHyperDbg> bl
id   address           status
--   ---------------   --------
01   fffff801639b1030  enabled
02   fffff801639b1035  enabled
03   fffff801639b103a  enabled
04   fffff801639b103f  enabled
```

### IOCTL

This command works over serial by sending the serial packets to the remote computer.

First of all, you should fill the following structure, set the `BreakpointId` to your special breakpoint id, which is derived from the 'bl' command.

```c
typedef struct _DEBUGGEE_BP_LIST_OR_MODIFY_PACKET {

  UINT64 BreakpointId;
  DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST Request;
  UINT32 Result;

} DEBUGGEE_BP_LIST_OR_MODIFY_PACKET, *PDEBUGGEE_BP_LIST_OR_MODIFY_PACKET;
```

In the request field, choose one of the actions from the following enum.

```c
typedef enum _DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST {

  DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST_LIST_BREAKPOINTS,
  DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST_ENABLE,
  DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST_DISABLE,
  DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST_CLEAR,

} DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST;
```

In the case of `Request`:

* If you want to list all the active breakpoint, then choose `DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST_LIST_BREAKPOINTS`.
* If you want to enable a breakpoint, then choose `DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST_ENABLE`.
* If you want to disable a breakpoint, then choose `DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST_DISABLE`.
* If you want to clear and remove a breakpoint, then choose `DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST_CLEAR`.

Note that if you want to list breakpoints, there is no need to fill `BreakpointId`and HyperDbg will ignore it.

The next step is sending the above structure to the debuggee when debuggee is paused and waiting for new command on **vmx-root** mode.

You should send the above structure with `DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_LIST_OR_MODIFY_BREAKPOINTS` as `RequestedAction` and `DEBUGGER_REMOTE_PACKET_TYPE_DEBUGGER_TO_DEBUGGEE_EXECUTE_ON_VMX_ROOT` as `PacketType`.

In return, the debuggee sends the above structure with the following type.

```c
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_LIST_OR_MODIFY_BREAKPOINTS
```

In the returned structure, the `Result` is filled by the kernel.

If the `Result` is `DEBUGEER_OPERATION_WAS_SUCCESSFULL`, then the operation was successful. Otherwise, the returned result is an error.

The following function is responsible for sending list/modify breakpoint buffers in the debugger.

```c
BOOLEAN KdSendListOrModifyPacketToDebuggee(PDEBUGGEE_BP_LIST_OR_MODIFY_PACKET ListOrModifyPacket);
```

HyperDbg will send a list of all active breakpoints and their **status** including **pid**, **tid**, and **core** as message strings to the debugger.

### Remarks

This command is guaranteed to keep debuggee in a halt state (in Debugger Mode); thus, nothing will change during its execution.

### Requirements

None

### Related

[bp (set breakpoint)](https://docs.hyperdbg.org/commands/debugging-commands/bp)

[be (enable breakpoints)](https://docs.hyperdbg.org/commands/debugging-commands/be)

[bd (disable breakpoints)](https://docs.hyperdbg.org/commands/debugging-commands/bd)

[bc (clear and remove breakpoints)](https://docs.hyperdbg.org/commands/debugging-commands/bc)


# be (enable breakpoints)

Description of the 'be' command in HyperDbg.

### Command

> be

### Syntax

> be \[BreakpointId (hex)]

### Description

Enables a previously disabled breakpoint (**0xcc**).

### Parameters

**\[BreakpointId (hex)]**

The **breakpoint id** of the target breakpoint. You can see a list of breakpoints and breakpoint ids using the '[bl](https://docs.hyperdbg.org/commands/debugging-commands/bl)' command.

### Examples

Imagine we have the following active breakpoints.

```
0: kHyperDbg> bl
id   address           status
--   ---------------   --------
01   fffff801639b1030  enabled
02   fffff801639b1035  disabled
03   fffff801639b103a  enabled
04   fffff801639b103f  enabled
```

After executing the following command, it's now enabled.

```
0: kHyperDbg> be 2
```

If you see the list of active breakpoints again, you can see that it's enabled.

```
0: kHyperDbg> bl
id   address           status
--   ---------------   --------
01   fffff801639b1030  enabled
02   fffff801639b1035  enabled
03   fffff801639b103a  enabled
04   fffff801639b103f  enabled
```

### IOCTL

This command works over serial by sending the serial packets to the remote computer.

First of all, you should fill the following structure, set the `BreakpointId` to your special breakpoint id, which is derived from the '[bl](https://docs.hyperdbg.org/commands/debugging-commands/bl)' command.

```c
typedef struct _DEBUGGEE_BP_LIST_OR_MODIFY_PACKET {

  UINT64 BreakpointId;
  DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST Request;
  UINT32 Result;

} DEBUGGEE_BP_LIST_OR_MODIFY_PACKET, *PDEBUGGEE_BP_LIST_OR_MODIFY_PACKET;
```

In the request field, choose one of the actions from the following enum.

```c
typedef enum _DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST {

  DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST_LIST_BREAKPOINTS,
  DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST_ENABLE,
  DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST_DISABLE,
  DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST_CLEAR,

} DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST;
```

In the case of `Request`:

* If you want to list all the active breakpoint, then choose `DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST_LIST_BREAKPOINTS`.
* If you want to enable a breakpoint, then choose `DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST_ENABLE`.
* If you want to disable a breakpoint, then choose `DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST_DISABLE`.
* If you want to clear and remove a breakpoint, then choose `DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST_CLEAR`.

Note that if you want to list breakpoints, there is no need to fill `BreakpointId`and HyperDbg will ignore it.

The next step is sending the above structure to the debuggee when debuggee is paused and waiting for new command on **vmx-root** mode.

You should send the above structure with `DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_LIST_OR_MODIFY_BREAKPOINTS` as `RequestedAction` and `DEBUGGER_REMOTE_PACKET_TYPE_DEBUGGER_TO_DEBUGGEE_EXECUTE_ON_VMX_ROOT` as `PacketType`.

In return, the debuggee sends the above structure with the following type.

```c
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_LIST_OR_MODIFY_BREAKPOINTS
```

In the returned structure, the `Result` is filled by the kernel.

If the `Result` is `DEBUGEER_OPERATION_WAS_SUCCESSFULL`, then the operation was successful. Otherwise, the returned result is an error.

The following function is responsible for sending list/modify breakpoint buffers in the debugger.

```c
BOOLEAN KdSendListOrModifyPacketToDebuggee(PDEBUGGEE_BP_LIST_OR_MODIFY_PACKET ListOrModifyPacket);
```

### Remarks

This command is guaranteed to keep debuggee in a halt state (in Debugger Mode); thus, nothing will change during its execution.

### Requirements

None

### Related

[bp (set breakpoint)](https://docs.hyperdbg.org/commands/debugging-commands/bp)

[bl (list breakpoints)](https://docs.hyperdbg.org/commands/debugging-commands/bl)

[bd (disable breakpoints)](https://docs.hyperdbg.org/commands/debugging-commands/bd)

[bc (clear and remove breakpoints)](https://docs.hyperdbg.org/commands/debugging-commands/bc)


# bd (disable breakpoints)

Description of the 'bd' command in HyperDbg.

### Command

> bd

### Syntax

> bd \[BreakpointId (hex)]

### Description

Disables a previously enabled breakpoint (**0xcc**).

### Parameters

**\[BreakpointId (hex)]**

The **breakpoint id** of the target breakpoint. You can see a list of breakpoints and breakpoint ids using the '[bl](https://docs.hyperdbg.org/commands/debugging-commands/bl)' command.

### Examples

Imagine we have the following active breakpoints.

```
0: kHyperDbg> bl
id   address           status
--   ---------------   --------
01   fffff801639b1030  enabled
02   fffff801639b1035  enabled
03   fffff801639b103a  enabled
04   fffff801639b103f  enabled
```

After executing the following command, it's now disabled.

```
0: kHyperDbg> bd 2
```

If you see the list of active breakpoints again, you can see that it's disabled.

```
0: kHyperDbg> bl
id   address           status
--   ---------------   --------
01   fffff801639b1030  enabled
02   fffff801639b1035  disabled
03   fffff801639b103a  enabled
04   fffff801639b103f  enabled
```

### IOCTL

This command works over serial by sending the serial packets to the remote computer.

First of all, you should fill the following structure, set the `BreakpointId` to your special breakpoint id, which is derived from the '[bl](https://docs.hyperdbg.org/commands/debugging-commands/bl)' command.

```c
typedef struct _DEBUGGEE_BP_LIST_OR_MODIFY_PACKET {

  UINT64 BreakpointId;
  DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST Request;
  UINT32 Result;

} DEBUGGEE_BP_LIST_OR_MODIFY_PACKET, *PDEBUGGEE_BP_LIST_OR_MODIFY_PACKET;
```

In the request field, choose one of the actions from the following enum.

```c
typedef enum _DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST {

  DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST_LIST_BREAKPOINTS,
  DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST_ENABLE,
  DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST_DISABLE,
  DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST_CLEAR,

} DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST;
```

In the case of `Request`:

* If you want to list all the active breakpoint, then choose `DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST_LIST_BREAKPOINTS`.
* If you want to enable a breakpoint, then choose `DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST_ENABLE`.
* If you want to disable a breakpoint, then choose `DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST_DISABLE`.
* If you want to clear and remove a breakpoint, then choose `DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST_CLEAR`.

Note that if you want to list breakpoints, there is no need to fill `BreakpointId`and HyperDbg will ignore it.

The next step is sending the above structure to the debuggee when debuggee is paused and waiting for new command on **vmx-root** mode.

You should send the above structure with `DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_LIST_OR_MODIFY_BREAKPOINTS` as `RequestedAction` and `DEBUGGER_REMOTE_PACKET_TYPE_DEBUGGER_TO_DEBUGGEE_EXECUTE_ON_VMX_ROOT` as `PacketType`.

In return, the debuggee sends the above structure with the following type.

```c
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_LIST_OR_MODIFY_BREAKPOINTS
```

In the returned structure, the `Result` is filled by the kernel.

If the `Result` is `DEBUGEER_OPERATION_WAS_SUCCESSFULL`, then the operation was successful. Otherwise, the returned result is an error.

The following function is responsible for sending list/modify breakpoint buffers in the debugger.

```c
BOOLEAN KdSendListOrModifyPacketToDebuggee(PDEBUGGEE_BP_LIST_OR_MODIFY_PACKET ListOrModifyPacket);
```

### Remarks

This command is guaranteed to keep debuggee in a halt state (in Debugger Mode); thus, nothing will change during its execution.

### Requirements

None

### Related

[bp (set breakpoint)](https://docs.hyperdbg.org/commands/debugging-commands/bp)

[bl (list breakpoints)](https://docs.hyperdbg.org/commands/debugging-commands/bl)

[be (enable breakpoints)](https://docs.hyperdbg.org/commands/debugging-commands/be)

[bc (clear and remove breakpoints)](https://docs.hyperdbg.org/commands/debugging-commands/bc)


# bc (clear and remove breakpoints)

Description of the 'bc' command in HyperDbg.

### Command

> bc

### Syntax

> bc \[BreakpointId (hex)]

### Description

Clears and removes a breakpoint (**0xcc**).

### Parameters

**\[BreakpointId (hex)]**

The **breakpoint id** of the target breakpoint. You can see a list of breakpoints and breakpoint ids using the '[bl](https://docs.hyperdbg.org/commands/debugging-commands/bl)' command.

### Examples

Imagine we have the following active breakpoints.

```
0: kHyperDbg> bl
id   address           status
--   ---------------   --------
01   fffff801639b1030  enabled
02   fffff801639b1035  enabled
03   fffff801639b103a  enabled
04   fffff801639b103f  enabled
```

After executing the following command, it's now removed.

```
0: kHyperDbg> bc 2
```

If you see the list of active breakpoints again, you can see that it's removed.

```
0: kHyperDbg> bl
id   address           status
--   ---------------   --------
01   fffff801639b1030  enabled
03   fffff801639b103a  enabled
04   fffff801639b103f  enabled
```

### IOCTL

This command works over serial by sending the serial packets to the remote computer.

First of all, you should fill the following structure, set the `BreakpointId` to your special breakpoint id, which is derived from the '[bl](https://docs.hyperdbg.org/commands/debugging-commands/bl)' command.

```c
typedef struct _DEBUGGEE_BP_LIST_OR_MODIFY_PACKET {

  UINT64 BreakpointId;
  DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST Request;
  UINT32 Result;

} DEBUGGEE_BP_LIST_OR_MODIFY_PACKET, *PDEBUGGEE_BP_LIST_OR_MODIFY_PACKET;
```

In the request field, choose one of the actions from the following enum.

```c
typedef enum _DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST {

  DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST_LIST_BREAKPOINTS,
  DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST_ENABLE,
  DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST_DISABLE,
  DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST_CLEAR,

} DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST;
```

In the case of `Request`:

* If you want to list all the active breakpoint, then choose `DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST_LIST_BREAKPOINTS`.
* If you want to enable a breakpoint, then choose `DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST_ENABLE`.
* If you want to disable a breakpoint, then choose `DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST_DISABLE`.
* If you want to clear and remove a breakpoint, then choose `DEBUGGEE_BREAKPOINT_MODIFICATION_REQUEST_CLEAR`.

Note that if you want to list breakpoints, there is no need to fill `BreakpointId`and HyperDbg will ignore it.

The next step is sending the above structure to the debuggee when debuggee is paused and waiting for new command on **vmx-root** mode.

You should send the above structure with `DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_LIST_OR_MODIFY_BREAKPOINTS` as `RequestedAction` and `DEBUGGER_REMOTE_PACKET_TYPE_DEBUGGER_TO_DEBUGGEE_EXECUTE_ON_VMX_ROOT` as `PacketType`.

In return, the debuggee sends the above structure with the following type.

```c
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_LIST_OR_MODIFY_BREAKPOINTS
```

In the returned structure, the `Result` is filled by the kernel.

If the `Result` is `DEBUGEER_OPERATION_WAS_SUCCESSFULL`, then the operation was successful. Otherwise, the returned result is an error.

The following function is responsible for sending list/modify breakpoint buffers in the debugger.

```c
BOOLEAN KdSendListOrModifyPacketToDebuggee(PDEBUGGEE_BP_LIST_OR_MODIFY_PACKET ListOrModifyPacket);
```

### Remarks

This command is guaranteed to keep debuggee in a halt state (in Debugger Mode); thus, nothing will change during its execution.

### Requirements

None

### Related

[bp (set breakpoint)](https://docs.hyperdbg.org/commands/debugging-commands/bp)

[bl (list breakpoints)](https://docs.hyperdbg.org/commands/debugging-commands/bl)

[be (enable breakpoints)](https://docs.hyperdbg.org/commands/debugging-commands/be)

[bd (disable breakpoints)](https://docs.hyperdbg.org/commands/debugging-commands/bd)


# g (continue debuggee or processing kernel packets)

Description of the 'g' command in HyperDbg.

### Command

> g

### Syntax

> g

### Description

When the **HyperDbg** debugger is paused by [pause command](https://docs.hyperdbg.org/commands/debugging-commands/pause) or CTRL+C or CTRL+BREAK, you can continue debugging using this command. You can use this command in both **local** and **remote** debugging.

### Parameters

None

### SDK

To continue the debuggee, you need to use the following function in `libhyperdbg`:

```clike
VOID
hyperdbg_u_continue_debuggee();
```

### Remarks

In remote debugging, [pause command](https://docs.hyperdbg.org/commands/debugging-commands/pause) or CTRL+C or CTRL+BREAK causes the target system to pause completely, and the target system halts.

In local debugging, [pause command](https://docs.hyperdbg.org/commands/debugging-commands/pause) or CTRL+C or CTRL+BREAK causes the debugger to stop processing kernel and vmx packets (they won't stop working, we ignore the messages). Also, we don't save messages, so when you pause the debugger, then the logs from the events are ignored, and you can't process them in the future.

### Requirements

None

### Related

[pause (break to the debugger and pause processing kernel packets)](https://docs.hyperdbg.org/commands/debugging-commands/pause)


# x (examine symbols and find functions and variables address)

Description of the 'x' command in HyperDbg.

### Command

> x

### Syntax

> x \[Module!Symbol (wildcard string)]

### Description

Finds the functions or variables address in the memory based on symbols.

### Parameters

**\[Module!Symbol (wildcard string)]**

Specifies a function or a variable name or a pattern that the symbol must contain. The ***Symbol*** can contain a variety of wildcard characters and specifiers. (For more information about the syntax, see **Remarks**)

### Examples

In the following example, we searched for the address of the `ExAllocatePoolWithTag` function in the `nt` module.

```
HyperDbg> x nt!ExAllocatePoolWithTag
fffff803`1dbb1030  nt!ExAllocatePoolWithTag
```

In the following example, we searched for the address of functions (and names) which, starts with `ExAllocatePoo` in the `nt` module.

```
0: kHyperDbg> x nt!ExAllocatePoo*
fffff803`1dbb1030  nt!ExAllocatePoolWithTag
fffff803`1d4421d0  nt!ExAllocatePoolWithQuotaTag
fffff803`1d44fde0  nt!ExAllocatePoolWithTagPriority
fffff803`1d522500  nt!ExAllocatePool
fffff803`1dbb1340  nt!ExAllocatePool3
fffff803`1dbb1280  nt!ExAllocatePool2
fffff803`1d7ad3d0  nt!ExAllocatePoolWithQuota
fffff803`1d45c5c0  nt!ExAllocatePoolEx
fffff803`1dbe9d84  nt!ExAllocatePoolSanityChecks
fffff803`1d4a1070  nt!ExAllocatePoolMm
```

### IOCTL

None

### Remarks

{% hint style="info" %}
The default module is **`nt`**. If you don't specify the module name, then **`nt`** is selected.
{% endhint %}

These are some examples of wildcard characters supported by this command.

| Value         | Meaning                                                                                                                                               |
| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| **foo**       | Looks for a global symbol (functions, variables) named "**foo**".                                                                                     |
| **foo?**      | Looks for a global symbol that starts with "**foo**" and contains one extra character afterward, such as "**fool**" and "**foot**".                   |
| **foo!bar\*** | Looks for a global symbol in "**foo**" that starts with "**bar**" and contains extra characters afterward, such as "**foo!bar1**" and "**foo!bar2**". |

### Requirements

None

### Related

None


# db, dc, dd, dq (read virtual memory)

Description of 'db, dc, dd, dq' commands in HyperDbg.

### Command

> db : read memory as Byte values and ASCII characters
>
> dc : read memory as Double-word values (4 bytes) and ASCII characters
>
> dd : read memory as Double-word values (4 bytes)
>
> dq : read memory as Quad-word values (8 bytes)

### Syntax

> db \[Address (hex)] \[l Length (hex)] \[pid ProcessId (hex)]
>
> dc \[Address (hex)] \[l Length (hex)] \[pid ProcessId (hex)]
>
> dd \[Address (hex)] \[l Length (hex)] \[pid ProcessId (hex)]
>
> dq \[Address (hex)] \[l Length (hex)] \[pid ProcessId (hex)]

### Description

Shows the **virtual** address memory content in hex form.

### Parameters

**\[Address (hex)]**

The **virtual** address of where we want to read its memory.

**\[l Length (hex)] (optional)**

The length (byte) in hex format.

**\[pid ProcessId (hex)] (optional)**

The Process ID in hex format that we want to see the memory from its context (**cr3**).

{% hint style="info" %}
If you don't specify the **pid**, then the default **pid** is the current process (HyperDbg) process layout of memory.
{% endhint %}

{% hint style="danger" %}
In the [Debugger Mode](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#debugger-mode), the **pid** (parameter) is ignored. If you want to view another process memory, use the '[.process](https://docs.hyperdbg.org/commands/meta-commands/.process)' command to switch to another process memory layout.
{% endhint %}

### Examples

The following command is used when we want to read the content of memory at `nt!Kd_DEFAULT_Mask` with length of `0x50`from the memory layout view of process (`4` a.k.a. system process) in a hex byte format.

```diff
HyperDbg> db Kd_DEFAULT_Mask l 50 pid 4
fffff801`63cf49ec  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
fffff801`63cf49fc  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
fffff801`63cf4a0c  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
fffff801`63cf4a1c  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
fffff801`63cf4a2c  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
```

The following command is used when we want to read the content of memory at `nt!Kd_DEFAULT_Mask+@rax+10` with length of `0x30`from the memory layout view of process (`4` a.k.a. system process) in a hex byte format.

Note that `@rax` is **0x10** in this case.

```diff
HyperDbg> db Kd_DEFAULT_Mask+@rax+10 l 30 pid 4
fffff801`63cf4a0c  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
fffff801`63cf4a1c  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
fffff801`63cf4a2c  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
```

The following command is used when we want to read the content of memory at ``fffff800`3ad6f010`` with length of `0x50` from the memory layout view of process (`4` a.k.a. system process) in a hex byte format.

```diff
HyperDbg> db fffff800`3ad6f010 l 50 pid 4
fffff800`3ad6f010  48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 57  H.\$.H.l$.H.t$.W
fffff800`3ad6f020  41 56 41 57 48 83 EC 30 65 48 8B 04 25 20 00 00  AVAWH..0eH.. ..
fffff800`3ad6f030  00 33 DB 44 0F B7 3D C5 3F 20 00 41 8B E8 48 8B  .3.D..=.? .A..H.
fffff800`3ad6f040  F2 89 5C 24 68 8B F9 4C 8B 88 C0 00 00 00 45 0F  ..\$h..L......E.
fffff800`3ad6f050  B7 B1 92 00 00 00 41 8B C6 44 8B C8 89 5C 24 20  ......A..D...\$
```

The following example shows the content of memory at ``fffff800`3ad6f010`` from current process layout in a Double-word value (4 bytes) and ASCII characters format.

```diff
HyperDbg> dc fffff800`3ad6f010
fffff800`3ad6f010  245C8948 6C894808 89481024 57182474  H.\$.H.l$.H.t$.W
fffff800`3ad6f020  57415641 30EC8348 048B4865 00002025  AVAWH..0eH.. ..
fffff800`3ad6f030  44DB3300 C53DB70F 4100203F 8B48E88B  .3.D..=.? .A..H.
fffff800`3ad6f040  245C89F2 4CF98B68 00C0888B 0F450000  ..\$h..L......E.
fffff800`3ad6f050  0092B1B7 8B410000 C88B44C6 20245C89  ......A..D...\$
fffff800`3ad6f060  48C58B44 CF8BD68B CC3693E8 C08548FF  D..H......6..H..
fffff800`3ad6f070  0038840F 8B480000 6C8B48D8 8B485824  ..8...H..H.l$XH.
fffff800`3ad6f080  5C8B48C3 8B485024 48602474 4130C483  .H.\$PH.t$`H..0A
```

The following example shows the content of memory at ``fffff800`3ad6f010`` from current process layout in a Double-word values (4 bytes) format with the length of `0x10`.

```diff
HyperDbg> dd fffff800`3ad6f010 l 10
fffff800`3ad6f010  245C8948 6C894808 89481024 57182474
```

The following example shows the content of memory at ``fffff800`3ad6f010`` from current process layout in a Quad-word values (8 bytes) format.

```diff
0: kHyperDbg> dq fffff800`3ad6f010
fffff800`3ad6f010  6C894808`245C8948 57182474`89481024
fffff800`3ad6f020  30EC8348`57415641 00002025`048B4865
fffff800`3ad6f030  C53DB70F`44DB3300 8B48E88B`4100203F
fffff800`3ad6f040  4CF98B68`245C89F2 0F450000`00C0888B
fffff800`3ad6f050  8B410000`0092B1B7 20245C89`C88B44C6
fffff800`3ad6f060  CF8BD68B`48C58B44 C08548FF`CC3693E8
fffff800`3ad6f070  8B480000`0038840F 8B485824`6C8B48D8
fffff800`3ad6f080  8B485024`5C8B48C3 4130C483`48602474
```

### SDK

To read the memory in the target debuggee, you need to use the following function in `libhyperdbg`:

```clike
VOID
hyperdbg_u_show_memory_or_disassemble(DEBUGGER_SHOW_MEMORY_STYLE   style,
                                      UINT64                       address,
                                      DEBUGGER_READ_MEMORY_TYPE    memory_type,
                                      DEBUGGER_READ_READING_TYPE   reading_type,
                                      UINT32                       pid,
                                      UINT32                       size,
                                      PDEBUGGER_DT_COMMAND_OPTIONS dt_details);
```

### Remarks

* If you don't specify the length, the default length for HyperDbg is 0x80 Bytes.

{% hint style="warning" %}
Please note that you should specify a space between 'l' and the length in HyperDbg. For example, 'l10' is invalid, but 'l 10' is valid. (It's opposed to windbg).
{% endhint %}

This command is guaranteed to keep debuggee in a halt state (in Debugger Mode); thus, nothing will change during its execution.

### Requirements

None

### Related

[!db, !dc, !dd, !dq (read physical memory)](https://docs.hyperdbg.org/commands/extension-commands/d)

[dl (traverse through linked list using virtual address)](https://docs.hyperdbg.org/commands/debugging-commands/dl)

[dt (display and map virtual memory to structures)](https://docs.hyperdbg.org/commands/debugging-commands/dt)


# eb, ed, eq (edit virtual memory)

Description of 'eb, ed, eq' commands in HyperDbg.

### Command

> eb : edit memory as Byte values
>
> ed : edit memory as Double-word values (4 bytes)
>
> eq : edit memory as Quad-word values (8 bytes)

### Syntax

> eb \[Address (hex)] \[Contents (hex)] \[pid ProcessId (hex)]
>
> ed \[Address (hex)] \[Contents (hex)] \[pid ProcessId (hex)]
>
> eq \[Address (hex)] \[Contents (hex)] \[pid ProcessId (hex)]

### Description

Edits the **virtual** address memory contents.

### Parameters

**\[Address (hex)]**

The **virtual** address of where we want to edit its memory.

**\[Contents (hex)]**

The new contents in hex format (it could be an array).

**\[pid ProcessId (hex)] (optional)**

The process ID in the hex format that we want to see the memory from its context (**cr3**).

{% hint style="info" %}
If you don't specify the `pid`, then the default `pid` is the current process (**HyperDbg**) process layout of memory.
{% endhint %}

{% hint style="danger" %}
In the [Debugger Mode](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#debugger-mode), the **pid** (parameter) is ignored. If you want to view another process memory, use the '[.process](https://docs.hyperdbg.org/commands/meta-commands/.process)' command to switch to another process memory layout.
{% endhint %}

### Examples

The following command is used when we want to edit the content of memory at `nt!Kd_DEFAULT_Mask` in a hex byte form and change it to `0xff 0xff 0xff 0xff`(modify **four** bytes).

```diff
HyperDbg> eb nt!Kd_DEFAULT_Mask ff ff ff ff
```

The following command is used when we want to edit the content of memory at `nt!Kd_DEFAULT_Mask+@rax+10` in a hex byte form and change it to `0xff 0xff 0xff 0xff`(modify **four** bytes).

```diff
HyperDbg> eb nt!Kd_DEFAULT_Mask+@rax+10 ff ff ff ff
```

The following command is used when we want to edit the content of memory at ``fffff800`3ad6f010`` in a hex byte form and change it to `0x90 0x90 0x90` (modify **three** bytes).

```diff
HyperDbg> eb fffff800`3ad6f010 90 90 90
```

The following example is used when we want to edit the contents of memory at ``fffff800`3ad6f010`` in Double-word values (4 bytes), change it to `245C8948` .

```diff
HyperDbg> ed fffff800`3ad6f010 245C8948
```

The following example is used when we want to edit the contents of memory at ``fffff800`3ad6f010`` in Quad-word values (8 bytes), change it to ``88889898`85858686`` and``92929393`97979898`` (16 bytes).

```diff
0: kHyperDbg> eq fffff800`3ad6f010 88889898`85858686 92929393`97979898
```

### SDK

To write the memory in the target debuggee, you need to use the following function in `libhyperdbg`:

```clike
BOOLEAN
hyperdbg_u_write_memory(PVOID                     destination_address,
                        DEBUGGER_EDIT_MEMORY_TYPE memory_type,
                        UINT32                    process_id,
                        PVOID                     source_address,
                        UINT32                    number_of_bytes);
```

### Remarks

* You can change as many bytes as you need in **byte**, **dword**, and **qword** formats; just add new values to the end of the command.

If you change the memory address that you previously set a breakpoint using the '[bp](https://docs.hyperdbg.org/commands/debugging-commands/bp)' command, the previous value is replaced when you remove the breakpoint.

This command is guaranteed to keep debuggee in a halt state (in Debugger Mode); thus, nothing will change during its execution.

### Requirements

None

### Related

[!eb, !ed, !eq (edit physical memory)](https://docs.hyperdbg.org/commands/extension-commands/e)


# sb, sd, sq (search virtual memory)

Description of 'sb, sd, sq' commands in HyperDbg.

### Command

> sb : search virtual memory as Byte values
>
> sd : search virtual memory as Double-word values (4 bytes)
>
> sq : search virtual memory as Quad-word values (8 bytes)

### Syntax

> sb \[StartAddress (hex)] \[l Length (hex)] \[BytePattern (hex)] \[pid ProcessId (hex)]
>
> sd \[StartAddress (hex)] \[l Length (hex)] \[BytePattern (hex)] \[pid ProcessId (hex)]
>
> sq \[StartAddress (hex)] \[l Length (hex)] \[BytePattern (hex)] \[pid ProcessId (hex)]

### Description

Searches the **virtual** memory for a special byte(s).

### Parameters

**\[StartAddress (hex)]**

The **virtual** address of where we want to start searching from its address.

**\[l Length (hex)]**

Length of the searching area.

**\[BytePattern (hex)]**

Search for these bytes (pattern).

**\[pid ProcessId (hex)] (optional)**

The Process ID in the hex format that we want to see the memory from its context (**cr3**).

{% hint style="info" %}
If you don't specify the **pid**, then the default **pid** is the current process (**HyperDbg**) process layout of memory.
{% endhint %}

### Examples

The following command is used to search for `4156415748` starting from `nt!ExAllocatePoolWithTag` to `nt!ExAllocatePoolWithTag+ffff`.

```diff
HyperDbg> sb nt!ExAllocatePoolWithTag l ffff 41 56 41 57 48 
```

The following command is used to search for `4156415748` starting from `nt!ExAllocatePoolWithTag+100` to `nt!ExAllocatePoolWithTag+100+ffff`.

```diff
HyperDbg> sb nt!ExAllocatePoolWithTag+100 l ffff 41 56 41 57 48 
```

The following command is used to search for `4156415748` starting from ``fffff807`7356f010`` to ``fffff807`7356f010+ffff``.

```diff
HyperDbg> sb fffff807`7356f010 l ffff 41 56 41 57 48 
```

The following example is used when we want to search for `f0cc8549` from `7FF62C9016AD` to `7FF62C9016AD+fff` in a different process (process id = `1dd0`) .

```diff
HyperDbg> sd 7FF62C9016AD pid 1dd0 l fff f0cc8549 
```

The following example is used when we want to search for ``0f450000`00c0888b`` ``8b410000`0092b1b7`` from ``fffff807`7356f010`` to ``fffff807`7356f010+100``.

```diff
HyperDbg> sq fffff807`7356f010 l 100 0f450000`00c0888b 8b410000`0092b1b7
```

### IOCTL

This function works by calling **DeviceIoControl** with `IOCTL = IOCTL_DEBUGGER_SEARCH_MEMORY`, you have to send it in the following structure.

```c
typedef struct _DEBUGGER_SEARCH_MEMORY {

  UINT64 Address;                            // Target address to start searching
  UINT64 Length;                             // Length of bytes to search
  UINT32 ProcessId;                          // specifies the process id
  DEBUGGER_SEARCH_MEMORY_TYPE MemoryType;    // Type of memory
  DEBUGGER_SEARCH_MEMORY_BYTE_SIZE ByteSize; // Modification size
  UINT32 CountOf64Chunks;
  UINT32 FinalStructureSize;

} DEBUGGER_SEARCH_MEMORY, *PDEBUGGER_SEARCH_MEMORY;
```

The `Address` is where we want to start searching from its memory, and it can be both a **physical** address or a **virtual** address.

`ProcessId` is the process that we want to modify based on its memory layout (**cr3**), it can't be `null` or zero.

`MemoryType` shows whether the `Address` is a **physical** address or a **virtual** address.

You can see its values in the following enum :

```c
typedef enum _DEBUGGER_SEARCH_MEMORY_TYPE {
  SEARCH_PHYSICAL_MEMORY,
  SEARCH_VIRTUAL_MEMORY
} DEBUGGER_SEARCH_MEMORY_TYPE;
```

`ByteSize` shows whether we want to search the target Address in a **byte**, **dword**, or **qword** format.

```c
typedef enum _DEBUGGER_SEARCH_MEMORY_BYTE_SIZE {
  SEARCH_BYTE,
  SEARCH_DWORD,
  SEARCH_QWORD
} DEBUGGER_SEARCH_MEMORY_BYTE_SIZE;
```

The above structure is added on top of an array of 64-bit values, which is the new content to the memory.

For example, if you want to search in the memory address of the target for`0x90 0x90` then you should provide an array of `0x0000000000000090` and `0x0000000000000090` and append it to the end of the above structure. The count of these chunks is stored at `CountOf64Chunks` in the above structure and the final buffer that will be sent into the kernel has a size of `FinalStructureSize` bytes.

Also, you should provide a buffer (size = `MaximumSearchResults * sizeof(UINT64)`) as the output buffer, so the kernel-mode module will fill this buffer with a 64-bit array or addresses that match our search results.

You can read the result buffer as an `UINT64` array, and if you encounter a null entry, then it means there is no other result.

### Remarks

* You can search for as many bytes as you need in **byte**, **dword**, and **qword** formats; just add the multiple byte(s) values to the end of the command.

This command is guaranteed to keep debuggee in a halt state (in Debugger Mode); thus, nothing will change during its execution.

### Requirements

None

### Related

None


# u, u64, u2, u32 (disassemble virtual address)

Description of 'u, u64, u2, u32' commands in HyperDbg.

### Command

> u
>
> u64
>
> u2
>
> u32

### Syntax

> u \[Address (hex)] \[l Length (hex)] \[pid ProcessId (hex)]
>
> u64 \[Address (hex)] \[l Length (hex)] \[pid ProcessId (hex)]
>
> u2 \[Address (hex)] \[l Length (hex)] \[pid ProcessId (hex)]
>
> u32 \[Address (hex)] \[l Length (hex)] \[pid ProcessId (hex)]

{% hint style="info" %}
**u** and **u64** disassemble as x64 while **u2** and **u32** disassemble as x86. **u** and **u64** are the same commands while **u2** and **u32** are the same.
{% endhint %}

### Description

Shows the assembly regarding memory content at the **virtual** address hex form.

### Parameters

**\[Address (hex)]**

The **virtual** address of where we want to start to disassemble its memory.

**\[l Length (hex)] (optional)**

The length (byte) in hex format.

**\[pid ProcessId (hex)] (optional)**

The Process ID that's in the hex format is what we want to see the memory from its context (**cr3**).

{% hint style="info" %}
If you don't specify the **pid**, then the default **pid** is the current process (HyperDbg) process layout of memory.
{% endhint %}

### Examples

The following command is used when we want to disassemble the content of memory (x64) at ``fffff800`3ad6f010`` with length of `0x50` bytes from the memory layout view of process (`4` a.k.a. system process).

```diff
HyperDbg> u fffff800`3ad6f010 l 50 pid 4
fffff800`3ad6f010 48 89 5C 24 08                      mov qword ptr ss:[rsp+0x08], rbx
fffff800`3ad6f015 48 89 6C 24 10                      mov qword ptr ss:[rsp+0x10], rbp
fffff800`3ad6f01a 48 89 74 24 18                      mov qword ptr ss:[rsp+0x18], rsi
fffff800`3ad6f01f 57                                  push rdi
fffff800`3ad6f020 41 56                               push r14
fffff800`3ad6f022 41 57                               push r15
fffff800`3ad6f024 48 83 EC 30                         sub rsp, 0x30
fffff800`3ad6f028 65 48 8B 04 25 20 00 00 00          mov rax, qword ptr gs:[0x0000000000000020]
fffff800`3ad6f031 33 DB                               xor ebx, ebx
fffff800`3ad6f033 44 0F B7 3D C5 3F 20 00             movzx r15d, word ptr ds:[0xFFFFF8003AF73000]
fffff800`3ad6f03b 41 8B E8                            mov ebp, r8d
fffff800`3ad6f03e 48 8B F2                            mov rsi, rdx
fffff800`3ad6f041 89 5C 24 68                         mov dword ptr ss:[rsp+0x68], ebx
fffff800`3ad6f045 8B F9                               mov edi, ecx
fffff800`3ad6f047 4C 8B 88 C0 00 00 00                mov r9, qword ptr ds:[rax+0xC0]
fffff800`3ad6f04e 45 0F B7 B1 92 00 00 00             movzx r14d, word ptr ds:[r9+0x92]
fffff800`3ad6f056 41 8B C6                            mov eax, r14d
fffff800`3ad6f059 44 8B C8                            mov r9d, eax
fffff800`3ad6f05c 89 5C 24 20                         mov dword ptr ss:[rsp+0x20], ebx
```

The following example shows the assembly content (x64) of memory at `nt!ExAllocatePoolWithTag` from current process memory layout.

```diff
HyperDbg> u nt!ExAllocatePoolWithTag
nt!ExAllocatePoolWithTag:
fffff801`639b1030    48 89 5C 24 08                      mov qword ptr ss:[rsp+0x08], rbx
fffff801`639b1035    48 89 6C 24 10                      mov qword ptr ss:[rsp+0x10], rbp
fffff801`639b103a    48 89 74 24 18                      mov qword ptr ss:[rsp+0x18], rsi
fffff801`639b103f    57                                  push rdi
fffff801`639b1040    41 56                               push r14
fffff801`639b1042    41 57                               push r15
fffff801`639b1044    48 83 EC 30                         sub rsp, 0x30
fffff801`639b1048    65 48 8B 04 25 20 00 00 00          mov rax, qword ptr gs:[0x0000000000000020]
fffff801`639b1051    45 8B F0                            mov r14d, r8d
fffff801`639b1054    44 0F B7 3D A4 8F 34 00             movzx r15d, word ptr ds:[0xFFFFF80163CFA000]
fffff801`639b105c    48 8B EA                            mov rbp, rdx
fffff801`639b105f    8B F1                               mov esi, ecx
fffff801`639b1061    4C 8B 88 C0 00 00 00                mov r9, qword ptr ds:[rax+0xC0]
fffff801`639b1068    41 0F B7 B9 92 00 00 00             movzx edi, word ptr ds:[r9+0x92]
```

The following example shows the assembly content (x64) of memory at `nt!ExAllocatePoolWithTag+5` from current process memory layout.

```diff
HyperDbg> u nt!ExAllocatePoolWithTag+5
nt!ExAllocatePoolWithTag+0x5:
fffff801`639b1035    48 89 6C 24 10                      mov qword ptr ss:[rsp+0x10], rbp
fffff801`639b103a    48 89 74 24 18                      mov qword ptr ss:[rsp+0x18], rsi
fffff801`639b103f    57                                  push rdi
fffff801`639b1040    41 56                               push r14
fffff801`639b1042    41 57                               push r15
fffff801`639b1044    48 83 EC 30                         sub rsp, 0x30
fffff801`639b1048    65 48 8B 04 25 20 00 00 00          mov rax, qword ptr gs:[0x0000000000000020]
fffff801`639b1051    45 8B F0                            mov r14d, r8d
fffff801`639b1054    44 0F B7 3D A4 8F 34 00             movzx r15d, word ptr ds:[0xFFFFF80163CFA000]
fffff801`639b105c    48 8B EA                            mov rbp, rdx
fffff801`639b105f    8B F1                               mov esi, ecx
fffff801`639b1061    4C 8B 88 C0 00 00 00                mov r9, qword ptr ds:[rax+0xC0]
fffff801`639b1068    41 0F B7 B9 92 00 00 00             movzx edi, word ptr ds:[r9+0x92]
fffff801`639b1070    0F BA EF 1F                         bts edi, 0x1F
```

The following example shows the assembly content (x64) of memory at ``fffff800`3ad6f010`` from current process memory layout.

```diff
HyperDbg> u fffff800`3ad6f010
fffff800`3ad6f010 48 89 5C 24 08                      mov qword ptr ss:[rsp+0x08], rbx
fffff800`3ad6f015 48 89 6C 24 10                      mov qword ptr ss:[rsp+0x10], rbp
fffff800`3ad6f01a 48 89 74 24 18                      mov qword ptr ss:[rsp+0x18], rsi
fffff800`3ad6f01f 57                                  push rdi
fffff800`3ad6f020 41 56                               push r14
fffff800`3ad6f022 41 57                               push r15
fffff800`3ad6f024 48 83 EC 30                         sub rsp, 0x30
fffff800`3ad6f028 65 48 8B 04 25 20 00 00 00          mov rax, qword ptr gs:[0x0000000000000020]
fffff800`3ad6f031 33 DB                               xor ebx, ebx
fffff800`3ad6f033 44 0F B7 3D C5 3F 20 00             movzx r15d, word ptr ds:[0xFFFFF8003AF73000]
fffff800`3ad6f03b 41 8B E8                            mov ebp, r8d
fffff800`3ad6f03e 48 8B F2                            mov rsi, rdx
fffff800`3ad6f041 89 5C 24 68                         mov dword ptr ss:[rsp+0x68], ebx
fffff800`3ad6f045 8B F9                               mov edi, ecx
fffff800`3ad6f047 4C 8B 88 C0 00 00 00                mov r9, qword ptr ds:[rax+0xC0]
```

### IOCTL

This function works by calling **DeviceIoControl** with `IOCTL = IOCTL_DEBUGGER_READ_MEMORY` , you have to send it in the following structure.

```c
typedef struct _DEBUGGER_READ_MEMORY {

    UINT32 Pid; // Read from cr3 of what process
    UINT64 Address;
    UINT32 Size;
    DEBUGGER_READ_MEMORY_TYPE MemoryType;
    DEBUGGER_READ_READING_TYPE ReadingType;

} DEBUGGER_READ_MEMORY, * PDEBUGGER_READ_MEMORY;
```

Where `Pid` is the process id, `Address` is the target location address and `size` is the length of the byte that you need to read.

`MemoryType`is either **virtual** or **physical**.

```c
typedef enum _DEBUGGER_READ_MEMORY_TYPE { DEBUGGER_READ_PHYSICAL_ADDRESS, DEBUGGER_READ_VIRTUAL_ADDRESS } DEBUGGER_READ_MEMORY_TYPE;
```

`ReadingType` is either from the **kernel** or from the **vmx root**. Currently, only the reading from the kernel is implemented.

```c
typedef enum _DEBUGGER_READ_READING_TYPE { READ_FROM_KERNEL, READ_FROM_VMX_ROOT } DEBUGGER_READ_READING_TYPE;
```

If you don't want to read from the kernel directly, use the following **HyperDbg Routine**.

```c
void HyperDbgReadMemoryAndDisassemble(DEBUGGER_SHOW_MEMORY_STYLE Style, UINT64 Address,
                        DEBUGGER_READ_MEMORY_TYPE MemoryType,
                        DEBUGGER_READ_READING_TYPE ReadingType, UINT32 Pid,
                        UINT Size);
```

The above function fills the IOCTL structure and shows the memory content. It is also able to disassemble the memory. You can specify one of the following `styles` to show the memory.

```c
typedef enum _DEBUGGER_SHOW_MEMORY_STYLE { DEBUGGER_SHOW_COMMAND_DISASSEMBLE64, DEBUGGER_SHOW_COMMAND_DISASSEMBLE32, DEBUGGER_SHOW_COMMAND_DB, DEBUGGER_SHOW_COMMAND_DC, DEBUGGER_SHOW_COMMAND_DQ, DEBUGGER_SHOW_COMMAND_DD } DEBUGGER_SHOW_MEMORY_STYLE;
```

For disassembling, use the `DEBUGGER_SHOW_COMMAND_DISASSEMBLE64` as the `Style` for x64 disassembling, and for disassembling x86, use the `DEBUGGER_SHOW_COMMAND_DISASSEMBLE32`.

In the debugger mode, HyperDbg uses the exact same structure, you should send the above structure over serial to the debuggee which is paused in **vmx-root** mode.

You should send the above structure with `DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_READ_MEMORY` as `RequestedAction` and `DEBUGGER_REMOTE_PACKET_TYPE_DEBUGGER_TO_DEBUGGEE_EXECUTE_ON_VMX_ROOT` as `PacketType`.

In return, the debuggee sends the above structure with the following type.

```c
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_READING_MEMORY
```

The following function is responsible for sending reading memory in the debugger.

```c
BOOLEAN KdSendReadMemoryPacketToDebuggee(PDEBUGGER_READ_MEMORY ReadMem);
```

### Remarks

* If you don't specify the length, the default length for HyperDbg is 0x40 Bytes.
* By default, HyperDbg converts addresses to the object names (if the symbol for that address is available). If you want to see the address in hex format, you can turn `addressconversion` to **off** using the '[settings](https://docs.hyperdbg.org/commands/debugging-commands/settings)' command.
* If you've ever seen any object name with two additions like `ExAllocatePoolWithTag+0x8f+0x2`, it means that the address is outside the function size that we've parsed from the symbol PDB files. Compilers often put some junk codes at the end of functions to create an alignment, and HyperDbg will notify you about these situations with two additions. Also, if the function is from a stripped symbol (or, in other words, the function size is not available), we set the function size to a maximum length of `0xffff`.

{% hint style="warning" %}
Please note that you should specify a space between 'l' and the length for HyperDbg. For example, 'l10' is invalid, but 'l 10' is valid. (It's opposed to windbg).
{% endhint %}

{% hint style="success" %}
HyperDbg uses [Zydis](https://zydis.re/) as its core disassembler.
{% endhint %}

This command is guaranteed to keep debuggee in a halt state (in Debugger Mode); thus, nothing will change during its execution.

### Requirements

None

### Related

[Zydis](https://zydis.re/)

[!u (disassemble physical address)](https://docs.hyperdbg.org/commands/extension-commands/u)

[a (assemble virtual address)](https://docs.hyperdbg.org/commands/debugging-commands/a)

[!a (assemble physical address)](https://docs.hyperdbg.org/commands/extension-commands/a)


# k, kd, kq (display stack backtrace)

Description of 'k, kd, kq' commands in HyperDbg.

### Command

> k : show stack backtrace (only calls)
>
> kd : show stack backtrace (calls along with parameters in stack) in 32-bit format
>
> kq : show stack backtrace (calls along with parameters in stack) in 64-bit format

### Syntax

> k
>
> kd
>
> kq
>
> k \[base StackAddress (hex)] \[l Length (hex)]
>
> kd \[base StackAddress (hex)] \[l Length (hex)]
>
> kq \[base StackAddress (hex)] \[l Length (hex)]

### Description

Displays stack backtrace and optionally shows the parameters in the stack.

### Parameters

**\[base StackAddress (hex)] (optional)**

If you want to specify any address other than the current `rsp` or `esp` register, you should set the base address by using this parameter.

**\[l Length (hex)] (optional)**

The length (byte) in hex format.

### Examples

The following command shows the callstack of the current thread.

```diff
2: kHyperDbg> k
[$+020]   fffff80168da7c86    (from <fffff80168da7c86>)
[$+050]   fffff80168dafab6    (from <fffff80168dafab6>)
[$+080]   fffff801678940aa    (from <fffff801678940aa>)
[$+150]   fffff8016362af7c    (from nt!ObpReferenceObjectByHandleWithTag+0x22c <fffff8016362af7c>)
[$+190]   fffff80163252f50    (from nt!IofCallDriver+0x50 <fffff80163252f50>)
[$+1d0]   fffff801635fd513    (from nt!IopSynchronousServiceTail+0x1a3 <fffff801635fd513>)
```

The following command shows the callstack of the current thread along with stack parameters.

```diff
2: kHyperDbg> kq
[$+000]      0000000000000000
[$+008]      0000000000000000
[$+010]      fffff80168daeb50 (addr <fffff80168daeb50>)
[$+018]      0000000000040246
[$+020]   fffff80168da7c86    (from <fffff80168da7c86>)
[$+028]      0000000000000000
[$+030]      ffff948cb9a02340 (addr <ffff948cb9a02340>)
[$+038]      0000000100000000
...
[$+150]   fffff8016362af7c    (from nt!ObpReferenceObjectByHandleWithTag+0x22c <fffff8016362af7c>)
[$+158]      0000000000000001
...
[$+188]      ffff948cc291cae0 (addr <ffff948cc291cae0>)
[$+190]   fffff80163252f50    (from nt!IofCallDriver+0x50 <fffff80163252f50>)
[$+198]      ffff948cbc327760 (addr <ffff948cbc327760>)
[$+1a0]      ffff948cc0314a80 (addr <ffff948cc0314a80>)
[$+1a8]      ffff930520206f49
[$+1b0]      0000000000000001
[$+1b8]      ffff948cbc327760 (addr <ffff948cbc327760>)
[$+1c0]      ffff948cc0314b98 (addr <ffff948cc0314b98>)
[$+1c8]      ffff948cc291cae0 (addr <ffff948cc291cae0>)
[$+1d0]   fffff801635fd513    (from nt!IopSynchronousServiceTail+0x1a3 <fffff801635fd513>)
..
[$+1f8]      0000000000000001
```

The following command shows the calls along with parameters (the base address is `@rbx-10`).

```diff
2: kHyperDbg> kq base @rbx-10
[$+000]      8d0ac9a500000000
[$+008]      0000000000000edc
[$+010]      0000200000000000
[$+018]      0000000000000000
[$+020]      0000000000000000
[$+028]      0000006700000000
[$+030]      5754444e02060000
[$+038]      fa3ced7b5a3515ff
[$+040]      0000000000000000
[$+048]      00000206c1f30004
[$+050]      ffff948cc06a9790 (addr <ffff948cc06a9790>)
```

The following command shows the callstack of the current thread in a 32-bit environment.

```diff
0: kHyperDbg> k
[$+004]   00a42274    (from <00a42274>)
[$+008]   7559fa27    (from <7559fa27>)
[$+018]   770775f2    (from <770775f2>)
[$+074]   770775bf    (from <770775bf>)
```

The following command shows the callstack of the current thread along with parameters in a 32-bit environment.

```diff
0: kHyperDbg> kd
[$+000]      010ffa18 (addr <010ffa18>)
[$+004]   00a42274    (from <00a42274>)
[$+008]   7559fa27    (from <7559fa27>)
[$+00c]      00f00000 (addr <00f00000>)
[$+010]      7559fa10 (addr <7559fa10>)
[$+014]      010ffa74 (addr <010ffa74>)
[$+018]   770775f2    (from <770775f2>)
[$+01c]      00f00000 (addr <00f00000>)
[$+020]      ba49f40e
[$+024]      00000000
[$+028]      00000000
[$+02c]      00f00000 (addr <00f00000>)
[$+030]      00000000
[$+034]      00000000
```

### IOCTL

This command works over serial by sending the serial packets to the remote computer.

First of all, you should fill the following structure, set the `Is32Bit`to your target execution context, set the `Size` and count of frames `FrameCount`, the base address (setting `NULL` as based address indicates that debuggee needs the current `rsp` register as the base address).

After allocating the below structure, you should also allocate as many frames structure (`DEBUGGER_SINGLE_CALLSTACK_FRAME`) that you want to read from the stack (`FrameCount * sizeof(DEBUGGER_SINGLE_CALLSTACK_FRAME)`).

```c
typedef struct _DEBUGGER_CALLSTACK_REQUEST
{
    BOOLEAN                           Is32Bit;
    UINT32                            KernelStatus;
    DEBUGGER_CALLSTACK_DISPLAY_METHOD DisplayMethod;
    UINT32                            Size;
    UINT32                            FrameCount;
    UINT64                            BaseAddress;
    UINT64                            BufferSize;

    //
    // Here is the size of stack frames
    //

} DEBUGGER_CALLSTACK_REQUEST, *PDEBUGGER_CALLSTACK_REQUEST;
```

The following structure shows the different fields of the frame structure.

```clike
typedef struct _DEBUGGER_SINGLE_CALLSTACK_FRAME
{
    BOOLEAN IsStackAddressValid;
    BOOLEAN IsValidAddress;
    BOOLEAN IsExecutable;
    UINT64  Value;
    BYTE    InstructionBytesOnRip[MAXIMUM_CALL_INSTR_SIZE];

} DEBUGGER_SINGLE_CALLSTACK_FRAME, *PDEBUGGER_SINGLE_CALLSTACK_FRAME;
```

The `DisplayMethod` can be selected from the below enum:

```clike
typedef enum _DEBUGGER_CALLSTACK_DISPLAY_METHOD
{
    DEBUGGER_CALLSTACK_DISPLAY_METHOD_WITHOUT_PARAMS,
    DEBUGGER_CALLSTACK_DISPLAY_METHOD_WITH_PARAMS,

} DEBUGGER_CALLSTACK_DISPLAY_METHOD;
```

The next step is sending the above structure to the debuggee when debuggee is paused and waiting for new command on **vmx-root** mode.

You should send the above structure with `DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_MODE_CALLSTACK` as `RequestedAction` and `DEBUGGER_REMOTE_PACKET_TYPE_DEBUGGER_TO_DEBUGGEE_EXECUTE_ON_VMX_ROOT` as `PacketType`.

In return, the debuggee sends the above structure with the following type.

```c
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_CALLSTACK
```

In the returned structure, the `KernelStatus` and frames structures are filled by the kernel.

If the `KernelStatus` is `DEBUGEER_OPERATION_WAS_SUCCESSFULL`, then the operation was successful. Otherwise, the returned result is an error.

The following function is responsible for sending interpreting frames in the debugger.

```clike
VOID
CallstackShowFrames(PDEBUGGER_SINGLE_CALLSTACK_FRAME  CallstackFrames,
                    UINT32                            FrameCount,
                    DEBUGGER_CALLSTACK_DISPLAY_METHOD DisplayMethod,
                    BOOLEAN                           Is32Bit);
```

### Remarks

* If you don't specify the length, the default length for HyperDbg is `0x100` Bytes for 32-bit contexts and `0x200` for 64-bit contexts.
* HyperDbg automatically switches between 32-bit and 64-bit environments based on the debuggee's execution context.

{% hint style="warning" %}
Please note that you should specify a space between 'l' and the length in HyperDbg. For example, 'l100' is invalid, but 'l 100' is valid. (It's opposed to windbg).
{% endhint %}

This command is guaranteed to keep debuggee in a halt state (in Debugger Mode); thus, nothing will change during its execution.

### Requirements

None

### Related

[gu (step-out or go up)](https://docs.hyperdbg.org/commands/debugging-commands/gu)


# dt (display and map virtual memory to structures)

Description of the 'dt' command in HyperDbg.

### Command

> dt

### Syntax

> dt \[Module!SymbolName (string)] \[AddressExpression (string)] \[pid ProcessId (hex)] \[padding Padding (yesno)] \[offset Offset (yesno)] \[bitfield Bitfield (yesno)] \[native Native (yesno)] \[decl Declaration (yesno)] \[def Definitions (yesno)] \[func Functions (yesno)] \[pragma Pragma (yesno)] \[prefix Prefix (string)] \[suffix Suffix (string)] \[inline Expansion (string)] \[output FileName (string)]

### Description

Displays data structures in an offset format, maps virtual address to a structure and shows the different fields and their values.

{% hint style="success" %}
You can use the '[**struct**](https://docs.hyperdbg.org/commands/debugging-commands/struct)' command to make **C** (header) code structures, enums, and data types from the symbols.
{% endhint %}

### Parameters

**\[Module!SymbolName (string)]**

Module name combined with the symbol name (separated by a `!` sign).

**\[AddressExpression (string)] (optional)**

Address or an expression that evaluates as a virtual address. If you leave this argument empty, the symbol data is shown without mapping to data.

**\[pid ProcessId (hex)] (optional)**

The Process ID (in the hex format) that we want to see the memory from its context (**cr3**).

**\[padding Padding (yesno)] (optional)**

Create padding members. (default: **yes**)

**\[offset Offset (yesno)] (optional)**

Show offsets. (default: **yes**)

**\[bitfield Bitfield (yesno)] (optional)**

Allow bitfields in the union. (default: **no**)

**\[native Native (yesno)] (optional)**

Use types from stdint.h instead of native types. (default: **no**)

**\[decl Declaration (yesno)] (optional)**

Print declarations. (default: **yes**)

**\[def Definitions (yesno)] (optional)**

Print definitions. (default: **yes**)

**\[func Functions (yesno)] (optional)**

Print functions. (default: **no**)

**\[pragma Pragma (yesno)] (optional)**

Print #pragma pack directives. (default: **yes**)

**\[prefix Prefix (string)] (optional)**

Prefix for all symbols.

**\[suffix Suffix (string)] (optional)**

Suffix for all symbols.

**\[inline Expansion (string)] (optional)**

Specifies expansion of nested structures/unions. (default: **unnamed**)

**none**: only the top-most type is printed.

**unnamed**: unnamed types are nested.

**all**: all types are nested.

**\[output FileName (string)] (optional)**

Specifies the output file if the user wants to save the printed data.

{% hint style="info" %}
If you don't specify the **pid**, then the default **pid** is the current process (**HyperDbg**) process layout of memory.
{% endhint %}

{% hint style="danger" %}
In the [Debugger Mode](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#debugger-mode), the **pid** (parameter) is ignored. If you want to view another process memory, use the '[.process](https://docs.hyperdbg.org/commands/meta-commands/.process)' command to switch to another process memory layout.
{% endhint %}

### Examples

The following command is used to show the `nt!_EPROCESS` in an offset format.

```clike
HyperDbg> dt nt!_EPROCESS
 _EPROCESS
  +0x0000 _KPROCESS Pcb
  +0x0438 _EX_PUSH_LOCK ProcessLock
  +0x0440 void* UniqueProcessId
  +0x0448 _LIST_ENTRY ActiveProcessLinks
  +0x0458 _EX_RUNDOWN_REF RundownProtect
  +0x0460 uint32_t Flags2
  +0x0460 uint32_t JobNotReallyActive, Pos 0, 1 Bit
  +0x0460 uint32_t AccountingFolded, Pos 1, 1 Bit
  +0x0460 uint32_t NewProcessReported, Pos 2, 1 Bit
  +0x0460 uint32_t ExitProcessReported, Pos 3, 1 Bit
  +0x0460 uint32_t ReportCommitChanges, Pos 4, 1 Bit
  +0x0460 uint32_t LastReportMemory, Pos 5, 1 Bit
  +0x0460 uint32_t ForceWakeCharge, Pos 6, 1 Bit
  +0x0460 uint32_t CrossSessionCreate, Pos 7, 1 Bit
  +0x0460 uint32_t NeedsHandleRundown, Pos 8, 1 Bit
  +0x0460 uint32_t RefTraceEnabled, Pos 9, 1 Bit
  +0x0460 uint32_t PicoCreated, Pos 10, 1 Bit
  +0x0460 uint32_t EmptyJobEvaluated, Pos 11, 1 Bit
  +0x0460 uint32_t DefaultPagePriority, Pos 12, 3 Bit
  +0x0460 uint32_t PrimaryTokenFrozen, Pos 15, 1 Bit
  +0x0460 uint32_t ProcessVerifierTarget, Pos 16, 1 Bit
  +0x0460 uint32_t RestrictSetThreadContext, Pos 17, 1 Bit
  +0x0460 uint32_t AffinityPermanent, Pos 18, 1 Bit
  +0x0460 uint32_t AffinityUpdateEnable, Pos 19, 1 Bit
  +0x0460 uint32_t PropagateNode, Pos 20, 1 Bit
  ...
```

The following command is used to map the virtual address at `ffff948cc0b41080` to the `nt!_EPROCESS` structure.

```clike
1: kHyperDbg> dt nt!_EPROCESS ffff948cc0b41080
 _EPROCESS
  +0x0000 _KPROCESS Pcb : _KPROCESS
  +0x0438 _EX_PUSH_LOCK ProcessLock : (null)
  +0x0440 void* UniqueProcessId : 00000000`00002240
  +0x0448 _LIST_ENTRY ActiveProcessLinks : _LIST_ENTRY [ ffff948c`bfbd0708 - ffff948c`c1424508 ]
  +0x0458 _EX_RUNDOWN_REF RundownProtect : (null)
  +0x0460 uint32_t Flags2 : 0x200d094
  +0x0460 uint32_t JobNotReallyActive, Pos 0, 1 Bit : 0y0
  +0x0460 uint32_t AccountingFolded, Pos 1, 1 Bit : 0y0
  +0x0460 uint32_t NewProcessReported, Pos 2, 1 Bit : 0y1
  +0x0460 uint32_t ExitProcessReported, Pos 3, 1 Bit : 0y0
  +0x0460 uint32_t ReportCommitChanges, Pos 4, 1 Bit : 0y1
  +0x0460 uint32_t LastReportMemory, Pos 5, 1 Bit : 0y0
  +0x0460 uint32_t ForceWakeCharge, Pos 6, 1 Bit : 0y0
  +0x0460 uint32_t CrossSessionCreate, Pos 7, 1 Bit : 0y1
  +0x0460 uint32_t NeedsHandleRundown, Pos 8, 1 Bit : 0y0
  +0x0460 uint32_t RefTraceEnabled, Pos 9, 1 Bit : 0y0
  +0x0460 uint32_t PicoCreated, Pos 10, 1 Bit : 0y0
  +0x0460 uint32_t EmptyJobEvaluated, Pos 11, 1 Bit : 0y0
  +0x0460 uint32_t DefaultPagePriority, Pos 12, 3 Bit : 0y101 (0x5)
  +0x0460 uint32_t PrimaryTokenFrozen, Pos 15, 1 Bit : 0y1
  +0x0460 uint32_t ProcessVerifierTarget, Pos 16, 1 Bit : 0y0
  +0x0460 uint32_t RestrictSetThreadContext, Pos 17, 1 Bit : 0y0
  +0x0460 uint32_t AffinityPermanent, Pos 18, 1 Bit : 0y0
  +0x0460 uint32_t AffinityUpdateEnable, Pos 19, 1 Bit : 0y0
  +0x0460 uint32_t PropagateNode, Pos 20, 1 Bit : 0y0
  +0x0460 uint32_t ExplicitAffinity, Pos 21, 1 Bit : 0y0
  +0x0460 uint32_t ProcessExecutionState, Pos 22, 2 Bit : 0y00 (0x0)
  +0x0460 uint32_t EnableReadVmLogging, Pos 24, 1 Bit : 0y0
  +0x0460 uint32_t EnableWriteVmLogging, Pos 25, 1 Bit : 0y1
  +0x0460 uint32_t FatalAccessTerminationRequested, Pos 26, 1 Bit : 0y0
  +0x0460 uint32_t DisableSystemAllowedCpuSet, Pos 27, 1 Bit : 0y0
  +0x0460 uint32_t ProcessStateChangeRequest, Pos 28, 2 Bit : 0y00 (0x0)
  +0x0460 uint32_t ProcessStateChangeInProgress, Pos 30, 1 Bit : 0y0
  +0x0460 uint32_t InPrivate, Pos 31, 1 Bit : 0y0
  +0x0464 uint32_t Flags : 0x144d0c01
  +0x0464 uint32_t CreateReported, Pos 0, 1 Bit : 0y1
  +0x0464 uint32_t NoDebugInherit, Pos 1, 1 Bit : 0y0
  +0x0464 uint32_t ProcessExiting, Pos 2, 1 Bit : 0y0
  +0x0464 uint32_t ProcessDelete, Pos 3, 1 Bit : 0y0
  +0x0464 uint32_t ManageExecutableMemoryWrites, Pos 4, 1 Bit : 0y0
  ...
```

You can also use expressions to map to the structures.

```clike
1: kHyperDbg> dt nt!_EPROCESS @rcx+10
 _EPROCESS
  +0x0000 _KPROCESS Pcb : _KPROCESS
  +0x0438 _EX_PUSH_LOCK ProcessLock : (null)
  +0x0440 void* UniqueProcessId : 00000000`00002240
  +0x0448 _LIST_ENTRY ActiveProcessLinks : _LIST_ENTRY [ ffff948c`bfbd0708 - ffff948c`c1424508 ]
  +0x0458 _EX_RUNDOWN_REF RundownProtect : (null)
  +0x0460 uint32_t Flags2 : 0x200d094
  +0x0460 uint32_t JobNotReallyActive, Pos 0, 1 Bit : 0y0
  +0x0460 uint32_t AccountingFolded, Pos 1, 1 Bit : 0y0
  +0x0460 uint32_t NewProcessReported, Pos 2, 1 Bit : 0y1
  +0x0460 uint32_t ExitProcessReported, Pos 3, 1 Bit : 0y0
  +0x0460 uint32_t ReportCommitChanges, Pos 4, 1 Bit : 0y1
  +0x0460 uint32_t LastReportMemory, Pos 5, 1 Bit : 0y0
  +0x0460 uint32_t ForceWakeCharge, Pos 6, 1 Bit : 0y0
  +0x0460 uint32_t CrossSessionCreate, Pos 7, 1 Bit : 0y1
  +0x0460 uint32_t NeedsHandleRundown, Pos 8, 1 Bit : 0y0
  +0x0460 uint32_t RefTraceEnabled, Pos 9, 1 Bit : 0y0
  +0x0460 uint32_t PicoCreated, Pos 10, 1 Bit : 0y0
  +0x0460 uint32_t EmptyJobEvaluated, Pos 11, 1 Bit : 0y0
  +0x0460 uint32_t DefaultPagePriority, Pos 12, 3 Bit : 0y101 (0x5)
  +0x0460 uint32_t PrimaryTokenFrozen, Pos 15, 1 Bit : 0y1
  +0x0460 uint32_t ProcessVerifierTarget, Pos 16, 1 Bit : 0y0
  +0x0460 uint32_t RestrictSetThreadContext, Pos 17, 1 Bit : 0y0
  +0x0460 uint32_t AffinityPermanent, Pos 18, 1 Bit : 0y0
  +0x0460 uint32_t AffinityUpdateEnable, Pos 19, 1 Bit : 0y0
  +0x0460 uint32_t PropagateNode, Pos 20, 1 Bit : 0y0
  +0x0460 uint32_t ExplicitAffinity, Pos 21, 1 Bit : 0y0
  +0x0460 uint32_t ProcessExecutionState, Pos 22, 2 Bit : 0y00 (0x0)
  +0x0460 uint32_t EnableReadVmLogging, Pos 24, 1 Bit : 0y0
  +0x0460 uint32_t EnableWriteVmLogging, Pos 25, 1 Bit : 0y1
  +0x0460 uint32_t FatalAccessTerminationRequested, Pos 26, 1 Bit : 0y0
  +0x0460 uint32_t DisableSystemAllowedCpuSet, Pos 27, 1 Bit : 0y0
  +0x0460 uint32_t ProcessStateChangeRequest, Pos 28, 2 Bit : 0y00 (0x0)
  +0x0460 uint32_t ProcessStateChangeInProgress, Pos 30, 1 Bit : 0y0
  +0x0460 uint32_t InPrivate, Pos 31, 1 Bit : 0y0
  +0x0464 uint32_t Flags : 0x144d0c01
  +0x0464 uint32_t CreateReported, Pos 0, 1 Bit : 0y1
  +0x0464 uint32_t NoDebugInherit, Pos 1, 1 Bit : 0y0
  +0x0464 uint32_t ProcessExiting, Pos 2, 1 Bit : 0y0
  +0x0464 uint32_t ProcessDelete, Pos 3, 1 Bit : 0y0
  +0x0464 uint32_t ManageExecutableMemoryWrites, Pos 4, 1 Bit : 0y0
  ...
```

The following command is used to show all structures by inlining each structure in an offset format.

```c
HyperDbg> dt nt!_SID inline all
 _SID
  +0x0000 unsigned char Revision
  +0x0001 unsigned char SubAuthorityCount
 _SID_IDENTIFIER_AUTHORITY
  +0x0002 unsigned char Value[6]
 IdentifierAuthority
  +0x0008 unsigned long SubAuthority[1]
```

### IOCTL

The **IOCTL** for this command is implemented like [db, dc, dd, dq (read virtual memory)](https://docs.hyperdbg.org/commands/debugging-commands/d) commands to read data from memory.

### Remarks

{% hint style="info" %}
For implementing this command, [**pdbex**](https://github.com/wbenny/pdbex) is integrated into HyperDbg.
{% endhint %}

This command is guaranteed to keep debuggee in a halt state (in Debugger Mode); thus, nothing will change during its execution.

### Requirements

None

### Related

[!dt (display and map physical memory to structures)](https://docs.hyperdbg.org/commands/extension-commands/dt)

[db, dc, dd, dq (read virtual memory)](https://docs.hyperdbg.org/commands/debugging-commands/d)

[dl (traverse through linked list using virtual address)](https://docs.hyperdbg.org/commands/debugging-commands/dl)

[struct (make structures, enums, data types from symbols)](https://docs.hyperdbg.org/commands/debugging-commands/struct)

[Mapping Data & Create Structures, and Enums From Symbols](https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/basics/mapping-data-and-create-structures-and-enums-from-symbols)


# dl (traverse through linked list using virtual address)

Description of the 'dl' command in HyperDbg.

### Command

> dl

### Syntax

> dl \[Address (hex)] \[o Offset (hex)] \[l Count (hex)] \[pid ProcessId (hex)]

### Description

Walks a linked list starting at the specified **virtual** address and shows each node.

### Parameters

**\[Address (hex)]**

The **virtual** address of the head of the linked list.

**\[o Offset (hex)] (optional)**

The offset (in bytes) within each node structure where the pointer to the next node is stored. (default: **0**)

**\[l Count (hex)] (optional)**

The maximum number of nodes to walk. (default: **100**)

**\[pid ProcessId (hex)] (optional)**

The Process ID (in the hex format) that we want to read memory from its context (**cr3**).

{% hint style="info" %}
If you don't specify the **pid**, then the default **pid** is the current process (**HyperDbg**) process layout of memory.
{% endhint %}

{% hint style="danger" %}
In the [Debugger Mode](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#debugger-mode), the **pid** (parameter) is ignored. If you want to view another process memory, use the '[.process](https://docs.hyperdbg.org/commands/meta-commands/.process)' command to switch to another process memory layout.
{% endhint %}

### Examples

The following command walks the `nt!PsActiveProcessHead` linked list from its virtual address.

```diff
0: kHyperDbg> dl nt!PsActiveProcessHead
walking linked list (virtual address) from fffff805c4305880 (offset = 0)

00: fffff805c4305880
01: ffffa88b8e6a4218
02: ffffa88b8e763258
03: ffffa88b9221b218
04: ffffa88b92a21258
05: ffffa88b92d20318
06: ffffa88b92d37258
07: ffffa88b92d64258
08: ffffa88b92daa258
09: ffffa88b92d16258
0a: ffffa88b92edf418
0b: ffffa88b92f0d318
0c: ffffa88b929c9258

...

(list is circular, returned to head)
```

The following command walks the linked list starting at `@rax` with an offset of `8` bytes to the next pointer.

```diff
0: kHyperDbg> dl @rax o 8
walking linked list (virtual address) from ffffa88b8e6a4000 (offset = 8)

00: ffffa88b8e6a4000
01: ffffa88b8e763000
02: ffffa88b9221b000
...

(list is circular, returned to head)
```

The following command walks the linked list at `fffff8077356f010` with an offset of `8`, a maximum of `0x20` nodes, from the memory layout of process `4`.

```diff
0: kHyperDbg> dl fffff8077356f010 o 8 l 20 pid 4
walking linked list (virtual address) from fffff8077356f010 (offset = 8)

00: fffff8077356f010
01: ffffa88b8e6a4218
02: ffffa88b8e763258
...

(stopped after 20 nodes; use 'l Count' to see more)
```

### SDK

To walk a linked list in the target debuggee, you need to use the following function in `libhyperdbg`:

```clike
VOID
hyperdbg_u_show_memory_linked_list(UINT64                    target_address,
                                   DEBUGGER_READ_MEMORY_TYPE memory_type,
                                   UINT32                    pid,
                                   UINT64                    offset,
                                   UINT64                    max_nodes);
```

### Remarks

* If you don't specify the **offset**, the default offset is `0`, meaning the next-pointer is at the very start of the node.
* If you don't specify the **count**, HyperDbg walks at most `0x100` nodes by default.
* For circular lists (e.g., Windows `LIST_ENTRY`-based lists), HyperDbg automatically detects when the walk returns to the head and stops.

{% hint style="warning" %}
Please note that you should specify a space between 'o' and the offset and between 'l' and the count in HyperDbg. For example, 'o8' is invalid, but 'o 8' is valid.
{% endhint %}

This command is guaranteed to keep debuggee in a halt state (in Debugger Mode); thus, nothing will change during its execution.

### Requirements

None

### Related

[!dl (traverse through linked list using physical address)](https://docs.hyperdbg.org/commands/extension-commands/dl)

[db, dc, dd, dq (read virtual memory)](https://docs.hyperdbg.org/commands/debugging-commands/d)

[dt (display and map virtual memory to structures)](https://docs.hyperdbg.org/commands/debugging-commands/dt)


# struct (make structures, enums, data types from symbols)

Description of the 'struct' command in HyperDbg.

### Command

> struct

### Syntax

> struct \[Module!SymbolName (string)] \[padding Padding (yesno)] \[offset Offset (yesno)] \[bitfield Bitfield (yesno)] \[native Native (yesno)] \[decl Declaration (yesno)] \[def Definitions (yesno)] \[func Functions (yesno)] \[pragma Pragma (yesno)] \[prefix Prefix (string)] \[suffix Suffix (string)] \[inline Expansion (string)] \[output FileName (string)]

### Description

Displays structures, enums, and data types in a **C** (header) format.

{% hint style="info" %}
You can use this command to create **C** (header) files from **all** of the symbols (structures, enums, data types) in the modules by using `module!*`. See [examples](https://docs.hyperdbg.org/commands/debugging-commands/struct#examples) for more information.
{% endhint %}

### Parameters

**\[Module!SymbolName (string)]**

Module name combined with the symbol name (separated by a `!` sign).

**\[padding Padding (yesno)] (optional)**

Create padding members. (default: **yes**)

**\[offset Offset (yesno)] (optional)**

Show offsets. (default: **yes**)

**\[bitfield Bitfield (yesno)] (optional)**

Allow bitfields in the union. (default: **no**)

**\[native Native (yesno)] (optional)**

Use types from stdint.h instead of native types. (default: **no**)

**\[decl Declaration (yesno)] (optional)**

Print declarations. (default: **yes**)

**\[def Definitions (yesno)] (optional)**

Print definitions. (default: **yes**)

**\[func Functions (yesno)] (optional)**

Print functions. (default: **no**)

**\[pragma Pragma (yesno)] (optional)**

Print #pragma pack directives. (default: **yes**)

**\[prefix Prefix (string)] (optional)**

Prefix for all symbols.

**\[suffix Suffix (string)] (optional)**

Suffix for all symbols.

**\[inline Expansion (string)] (optional)**

Specifies expansion of nested structures/unions. (default: **unnamed**)

**none**: only the top-most type is printed.

**unnamed**: unnamed types are nested.

**all**: all types are nested.

**\[output FileName (string)] (optional)**

Specifies the output file if the user wants to save the printed data.

### Examples

The following command is used to convert `nt!_TOKEN` into a C format code.

```clike
1: kHyperDbg> struct nt!_TOKEN
typedef struct _TOKEN
{
  /* 0x0000 */ struct _TOKEN_SOURCE TokenSource;
  /* 0x0010 */ struct _LUID TokenId;
  /* 0x0018 */ struct _LUID AuthenticationId;
  /* 0x0020 */ struct _LUID ParentTokenId;
  /* 0x0028 */ union _LARGE_INTEGER ExpirationTime;
  /* 0x0030 */ struct _ERESOURCE* TokenLock;
  /* 0x0038 */ struct _LUID ModifiedId;
  /* 0x0040 */ struct _SEP_TOKEN_PRIVILEGES Privileges;
  /* 0x0058 */ struct _SEP_AUDIT_POLICY AuditPolicy;
  /* 0x0077 */ char Padding_0;
  /* 0x0078 */ uint32_t SessionId;
  /* 0x007c */ uint32_t UserAndGroupCount;
  /* 0x0080 */ uint32_t RestrictedSidCount;
  /* 0x0084 */ uint32_t VariableLength;
  /* 0x0088 */ uint32_t DynamicCharged;
  /* 0x008c */ uint32_t DynamicAvailable;
  /* 0x0090 */ uint32_t DefaultOwnerIndex;
  /* 0x0094 */ long Padding_1;
  /* 0x0098 */ struct _SID_AND_ATTRIBUTES* UserAndGroups;
  /* 0x00a0 */ struct _SID_AND_ATTRIBUTES* RestrictedSids;
  /* 0x00a8 */ void* PrimaryGroup;
  /* 0x00b0 */ uint32_t* DynamicPart;
  /* 0x00b8 */ struct _ACL* DefaultDacl;
  /* 0x00c0 */ enum _TOKEN_TYPE TokenType;
  /* 0x00c4 */ enum _SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
  /* 0x00c8 */ uint32_t TokenFlags;
  /* 0x00cc */ uint8_t TokenInUse;
  /* 0x00cd */ char Padding_2[3];
  /* 0x00d0 */ uint32_t IntegrityLevelIndex;
  /* 0x00d4 */ uint32_t MandatoryPolicy;
  /* 0x00d8 */ struct _SEP_LOGON_SESSION_REFERENCES* LogonSession;
  /* 0x00e0 */ struct _LUID OriginatingLogonSession;
  /* 0x00e8 */ struct _SID_AND_ATTRIBUTES_HASH SidHash;
  /* 0x01f8 */ struct _SID_AND_ATTRIBUTES_HASH RestrictedSidHash;
  /* 0x0308 */ struct _AUTHZBASEP_SECURITY_ATTRIBUTES_INFORMATION* pSecurityAttributes;
  /* 0x0310 */ void* Package;
  /* 0x0318 */ struct _SID_AND_ATTRIBUTES* Capabilities;
  /* 0x0320 */ uint32_t CapabilityCount;
  /* 0x0324 */ long Padding_3;
  /* 0x0328 */ struct _SID_AND_ATTRIBUTES_HASH CapabilitiesHash;
  /* 0x0438 */ struct _SEP_LOWBOX_NUMBER_ENTRY* LowboxNumberEntry;
  /* 0x0440 */ struct _SEP_CACHED_HANDLES_ENTRY* LowboxHandlesEntry;
  /* 0x0448 */ struct _AUTHZBASEP_CLAIM_ATTRIBUTES_COLLECTION* pClaimAttributes;
  /* 0x0450 */ void* TrustLevelSid;
  /* 0x0458 */ struct _TOKEN* TrustLinkedToken;
  /* 0x0460 */ void* IntegrityLevelSidValue;
  /* 0x0468 */ struct _SEP_SID_VALUES_BLOCK* TokenSidValues;
  /* 0x0470 */ struct _SEP_LUID_TO_INDEX_MAP_ENTRY* IndexEntry;
  /* 0x0478 */ struct _SEP_TOKEN_DIAG_TRACK_ENTRY* DiagnosticInfo;
  /* 0x0480 */ struct _SEP_CACHED_HANDLES_ENTRY* BnoIsolationHandlesEntry;
  /* 0x0488 */ void* SessionObject;
  /* 0x0490 */ uint64_t VariablePart;
} TOKEN, *PTOKEN; /* size: 0x0498 */
```

You can also use this command to rebuild enums.

```clike
HyperDbg> struct nt!POWER_ACTION
enum POWER_ACTION
{
  PowerActionNone = 0,
  PowerActionReserved = 1,
  PowerActionSleep = 2,
  PowerActionHibernate = 3,
  PowerActionShutdown = 4,
  PowerActionShutdownReset = 5,
  PowerActionShutdownOff = 6,
  PowerActionWarmEject = 7,
  PowerActionDisplayOff = 8,
};
```

It's possible to dump all of the structures, enums, and data types into a header file.

```
1: kHyperDbg> struct nt!* output NtHeader.h
```

The following command is used to inline each structure into the parent structure.

```clike
HyperDbg> struct nt!_SID inline all
typedef struct _SID
{
  /* 0x0000 */ unsigned char Revision;
  /* 0x0001 */ unsigned char SubAuthorityCount;
  struct _SID_IDENTIFIER_AUTHORITY
  {
    /* 0x0002 */ unsigned char Value[6];
  } /* size: 0x0006 */ IdentifierAuthority;
  /* 0x0008 */ unsigned long SubAuthority[1];
} SID, *PSID; /* size: 0x000c */
```

The following command is used to recursively dump the `nt!_TOKEN` structure and its sub-structures.

```clike
1: kHyperDbg> struct nt!_TOKEN def yes
#include <pshpack1.h>
typedef struct _LUID
{
  /* 0x0000 */ unsigned long LowPart;
  /* 0x0004 */ long HighPart;
} LUID, *PLUID; /* size: 0x0008 */

typedef struct _TOKEN_SOURCE
{
  /* 0x0000 */ char SourceName[8];
  /* 0x0008 */ struct _LUID SourceIdentifier;
} TOKEN_SOURCE, *PTOKEN_SOURCE; /* size: 0x0010 */

typedef union _LARGE_INTEGER
{
  union
  {
    struct
    {
      /* 0x0000 */ unsigned long LowPart;
      /* 0x0004 */ long HighPart;
    }; /* size: 0x0008 */
    struct
    {
      /* 0x0000 */ unsigned long LowPart;
      /* 0x0004 */ long HighPart;
    } /* size: 0x0008 */ u;
    /* 0x0000 */ __int64 QuadPart;
  }; /* size: 0x0008 */
} LARGE_INTEGER, *PLARGE_INTEGER; /* size: 0x0008 */

typedef struct _SEP_TOKEN_PRIVILEGES
{
  /* 0x0000 */ unsigned __int64 Present;
  /* 0x0008 */ unsigned __int64 Enabled;
  /* 0x0010 */ unsigned __int64 EnabledByDefault;
} SEP_TOKEN_PRIVILEGES, *PSEP_TOKEN_PRIVILEGES; /* size: 0x0018 */

typedef struct _TOKEN_AUDIT_POLICY
{
  /* 0x0000 */ unsigned char PerUserPolicy[30];
} TOKEN_AUDIT_POLICY, *PTOKEN_AUDIT_POLICY; /* size: 0x001e */

typedef struct _SEP_AUDIT_POLICY
{
  /* 0x0000 */ struct _TOKEN_AUDIT_POLICY AdtTokenPolicy;
  /* 0x001e */ unsigned char PolicySetStatus;
} SEP_AUDIT_POLICY, *PSEP_AUDIT_POLICY; /* size: 0x001f */

typedef enum _TOKEN_TYPE
{
  TokenPrimary = 1,
  TokenImpersonation = 2,
} TOKEN_TYPE, *PTOKEN_TYPE;

typedef enum _SECURITY_IMPERSONATION_LEVEL
{
  SecurityAnonymous = 0,
  SecurityIdentification = 1,
  SecurityImpersonation = 2,
  SecurityDelegation = 3,
} SECURITY_IMPERSONATION_LEVEL, *PSECURITY_IMPERSONATION_LEVEL;

typedef struct _SID_AND_ATTRIBUTES_HASH
{
  /* 0x0000 */ unsigned long SidCount;
  /* 0x0004 */ long Padding_0;
  /* 0x0008 */ struct _SID_AND_ATTRIBUTES* SidAttr;
  /* 0x0010 */ unsigned __int64 Hash[32];
} SID_AND_ATTRIBUTES_HASH, *PSID_AND_ATTRIBUTES_HASH; /* size: 0x0110 */

typedef struct _TOKEN
{
  /* 0x0000 */ struct _TOKEN_SOURCE TokenSource;
  /* 0x0010 */ struct _LUID TokenId;
  /* 0x0018 */ struct _LUID AuthenticationId;
  /* 0x0020 */ struct _LUID ParentTokenId;
  /* 0x0028 */ union _LARGE_INTEGER ExpirationTime;
  /* 0x0030 */ struct _ERESOURCE* TokenLock;
  /* 0x0038 */ struct _LUID ModifiedId;
  /* 0x0040 */ struct _SEP_TOKEN_PRIVILEGES Privileges;
  /* 0x0058 */ struct _SEP_AUDIT_POLICY AuditPolicy;
  /* 0x0077 */ char Padding_1;
  /* 0x0078 */ unsigned long SessionId;
  /* 0x007c */ unsigned long UserAndGroupCount;
  /* 0x0080 */ unsigned long RestrictedSidCount;
  /* 0x0084 */ unsigned long VariableLength;
  /* 0x0088 */ unsigned long DynamicCharged;
  /* 0x008c */ unsigned long DynamicAvailable;
  /* 0x0090 */ unsigned long DefaultOwnerIndex;
  /* 0x0094 */ long Padding_2;
  /* 0x0098 */ struct _SID_AND_ATTRIBUTES* UserAndGroups;
  /* 0x00a0 */ struct _SID_AND_ATTRIBUTES* RestrictedSids;
  /* 0x00a8 */ void* PrimaryGroup;
  /* 0x00b0 */ unsigned long* DynamicPart;
  /* 0x00b8 */ struct _ACL* DefaultDacl;
  /* 0x00c0 */ enum _TOKEN_TYPE TokenType;
  /* 0x00c4 */ enum _SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
  /* 0x00c8 */ unsigned long TokenFlags;
  /* 0x00cc */ unsigned char TokenInUse;
  /* 0x00cd */ char Padding_3[3];
  /* 0x00d0 */ unsigned long IntegrityLevelIndex;
  /* 0x00d4 */ unsigned long MandatoryPolicy;
  /* 0x00d8 */ struct _SEP_LOGON_SESSION_REFERENCES* LogonSession;
  /* 0x00e0 */ struct _LUID OriginatingLogonSession;
  /* 0x00e8 */ struct _SID_AND_ATTRIBUTES_HASH SidHash;
  /* 0x01f8 */ struct _SID_AND_ATTRIBUTES_HASH RestrictedSidHash;
  /* 0x0308 */ struct _AUTHZBASEP_SECURITY_ATTRIBUTES_INFORMATION* pSecurityAttributes;
  /* 0x0310 */ void* Package;
  /* 0x0318 */ struct _SID_AND_ATTRIBUTES* Capabilities;
  /* 0x0320 */ unsigned long CapabilityCount;
  /* 0x0324 */ long Padding_4;
  /* 0x0328 */ struct _SID_AND_ATTRIBUTES_HASH CapabilitiesHash;
  /* 0x0438 */ struct _SEP_LOWBOX_NUMBER_ENTRY* LowboxNumberEntry;
  /* 0x0440 */ struct _SEP_CACHED_HANDLES_ENTRY* LowboxHandlesEntry;
  /* 0x0448 */ struct _AUTHZBASEP_CLAIM_ATTRIBUTES_COLLECTION* pClaimAttributes;
  /* 0x0450 */ void* TrustLevelSid;
  /* 0x0458 */ struct _TOKEN* TrustLinkedToken;
  /* 0x0460 */ void* IntegrityLevelSidValue;
  /* 0x0468 */ struct _SEP_SID_VALUES_BLOCK* TokenSidValues;
  /* 0x0470 */ struct _SEP_LUID_TO_INDEX_MAP_ENTRY* IndexEntry;
  /* 0x0478 */ struct _SEP_TOKEN_DIAG_TRACK_ENTRY* DiagnosticInfo;
  /* 0x0480 */ struct _SEP_CACHED_HANDLES_ENTRY* BnoIsolationHandlesEntry;
  /* 0x0488 */ void* SessionObject;
  /* 0x0490 */ unsigned __int64 VariablePart;
} TOKEN, *PTOKEN; /* size: 0x0498 */

#include <poppack.h>
```

### IOCTL

None

### Remarks

{% hint style="info" %}
For implementing this command, [**pdbex**](https://github.com/wbenny/pdbex) is integrated into HyperDbg.
{% endhint %}

This command is guaranteed to keep debuggee in a halt state (in Debugger Mode); thus, nothing will change during its execution.

### Requirements

None

### Related

[dt (display and map virtual memory to structures)](https://docs.hyperdbg.org/commands/debugging-commands/dt)

[!dt (display and map physical memory to structures)](https://docs.hyperdbg.org/commands/extension-commands/dt)

[Mapping Data & Create Structures, and Enums From Symbols](https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/basics/mapping-data-and-create-structures-and-enums-from-symbols)


# sleep (wait for specific time in the .script command)

Description of the 'sleep' command in HyperDbg.

### Command

> sleep

### Syntax

> sleep \[MillisecondsTime (hex)]

### Description

Waits for the specified time (in milliseconds).

### Parameters

**\[MillisecondsTime (hex)]**

The time that debugger should wait, in milliseconds.

### IOCTL

None

### Remarks

This command is used in batch script files when we want to gather information for a specific time and then execute the [**pause** ](https://docs.hyperdbg.org/commands/debugging-commands/pause)command or the [**unload** ](https://docs.hyperdbg.org/commands/debugging-commands/unload)command to stop the debugger.

### Requirements

None

### Related

[pause (break to the debugger and pause processing kernel packets)](https://docs.hyperdbg.org/commands/debugging-commands/pause)

[unload (unload the kernel modules)](https://docs.hyperdbg.org/commands/debugging-commands/unload)

[.script (run batch script commands)](https://docs.hyperdbg.org/commands/meta-commands/.script)


# pause (break to the debugger and pause processing kernel packets)

Description of the 'pause' command in HyperDbg.

### Command

> pause

### Syntax

> pause

### Description

On the remote system, this command halts the system and gives control of the remote system to the debugger. In local debugging, this command stops processing kernel and vmx packets and ignores them.

{% hint style="info" %}
You can unpause using the [g command](https://docs.hyperdbg.org/commands/debugging-commands/g).
{% endhint %}

### Parameters

None

### SDK

To pause the debuggee, you need to use the following function in `libhyperdbg`:

```clike
VOID
hyperdbg_u_pause_debuggee();
```

### Remarks

In remote debugging, pause command or CTRL+C or CTRL+BREAK causes the target system to pause completely, and the target system halts.

In local debugging, pause command or CTRL+C or CTRL+BREAK causes the debugger to stop processing kernel and vmx packets (they won't stop working, we ignore the messages). Also, we don't save messages, so when you pause the debugger, then the logs from the events are ignored, and you can't process them in the future.

Most of the time, this command is used in scripts after the '[sleep](https://docs.hyperdbg.org/commands/debugging-commands/sleep)' command to block further messages caused by triggering events.

### Requirements

None

### Related

[.script (run batch script commands)](https://docs.hyperdbg.org/commands/meta-commands/.script)

[g (continue debugging or processing kernel packets)](https://docs.hyperdbg.org/commands/debugging-commands/g)

[settings (configures different options and preferences)](https://docs.hyperdbg.org/commands/debugging-commands/settings)


# print (evaluate and print expression in debuggee)

Description of the 'print' command in HyperDbg.

### Command

> print

### Syntax

> print \[Expression (string)]

### Description

Shows the result of an expression that will be executed in the remote debuggee.

### Parameters

**\[Expression (string)]**

The expression is based on HyperDbg's [scripting language](https://docs.hyperdbg.org/commands/scripting-language/assumptions-and-evaluations).

### Examples

The following command shows the `@rax` register in the debuggee.

```diff
0: kHyperDbg> print @rax
```

The following command shows the data as an 8-byte hex, pointed by the `@rcx` register.

```diff
0: kHyperDbg> print dq(@rcx)
```

The following command shows the value pointed by `$proc+@rdx` which **$proc** is equivalent to current `_EPROCESS` added to the **rdx** register.

```diff
0: kHyperDbg> print $proc+@rdx
```

The following command shows the value of an address, which first, **rax** register is added with **0xa0** constant then a dereference occurs and the target is shown as a QWORD hex.

```diff
0: kHyperDbg> print poi(@rax+a0)
```

### IOCTL

For using this command, you use the same SDK function as the '[.formats](https://docs.hyperdbg.org/commands/meta-commands/.formats#ioctl)' command.

### Remarks

This command is exactly like `print(expr);` in script engine, except that HyperDbg automatically adds `print(` and `);`.

This command is guaranteed to keep debuggee in a halt state (in Debugger Mode); thus, nothing will change during its execution.

### Requirements

None

### Related

None


# lm (view loaded modules)

Description of the 'lm' command in HyperDbg.

### Command

> lm

### Syntax

> lm \[m Name (string)] \[pid ProcessId (hex)] \[Filter (string)]

### Description

Shows the loaded modules' base address, size, name, full path.

### Parameters

**\[m Name (string)] (optional)**

The name or a part of the name that will be searched through all the modules and only those which match will be shown. The search is case-insensitive.

**\[pid ProcessId (hex)] (optional)**

The Process Id of the target process in which the user-mode modules are shown. The process id only makes sense in user-mode modules, and this parameter will be ignored for kernel-mode modules.

{% hint style="info" %}
By default, when you didn't use the **pid** parameter, if you are attached to a process in the user-mode debugger, this command shows the user-mode modules of the debuggee process; otherwise, it shows the user-mode modules of the process of HyperDbg.
{% endhint %}

**\[Filter (string)] (optional)**

Can be one of these values :

**km**: only shows the kernel-mode modules.

**um**: only shows the user-mode modules.

### Examples

The following command shows all the user-mode and kernel-mode modules.

```cpp
HyperDbg> lm
user mode
start                   entrypoint              path

....
00007ffd885e0000        00007ffd885f5600        C:\Windows\System32\ADVAPI32.dll
00007ffd86fc0000        00007ffd86fc7850        C:\Windows\System32\msvcrt.dll
00007ffd87df0000        00007ffd87e0cd20        C:\Windows\System32\sechost.dll
00007ffd86e60000        00007ffd86ebdfb0        C:\Windows\System32\RPCRT4.dll
00007ffd88cb0000        00007ffd88cba7a0        C:\Windows\System32\SHLWAPI.dll
00007ffd886a0000        00007ffd886b4300        C:\Windows\System32\WS2_32.dll
...

==============================================================================

kernel mode
start                   size    name                            path

fffff801`63000000       1046000 ntoskrnl.exe                    \SystemRoot\system32\ntoskrnl.exe
fffff801`5fa40000       6000    hal.dll                         \SystemRoot\system32\hal.dll
fffff801`5fab0000       49000   kdnet.dll                       \SystemRoot\system32\kdnet.dll
fffff801`5fa50000       5c000   kd_02_8086.dll                  \SystemRoot\system32\kd_02_8086.dll
...
```

This command only shows the **user-mode** modules.

```clike
HyperDbg> lm um
user mode
start                   entrypoint              path

...
00007ffd88d50000        0000000000000000        C:\Windows\SYSTEM32\ntdll.dll
00007ffd88860000        00007ffd888770d0        C:\Windows\System32\KERNEL32.DLL
00007ffd865f0000        00007ffd865f92c0        C:\Windows\System32\KERNELBASE.dll
00007ffd83d90000        00007ffd83da0880        C:\Windows\SYSTEM32\apphelp.dll
...
```

The following command shows the **user-mode** modules of the process with process id equal to **1240** that contains "***kernel***" in their path.

```clike
HyperDbg> lm um m kernel pid 1240
user mode
start                   entrypoint              path

00007ffd88860000        00007ffd888770d0        C:\Windows\System32\KERNEL32.DLL
00007ffd865f0000        00007ffd865f92c0        C:\Windows\System32\KERNELBASE.dll

```

The following example shows the **kernel-mode** modules that contain "***nt*****"** in their path or name.

```c
HyperDbg> lm km m nt
kernel mode
start                   size    name                            path

fffff801`63000000       1046000 ntoskrnl.exe                    \SystemRoot\system32\ntoskrnl.exe
fffff801`5f7b0000       28f000  mcupdate_GenuineIntel.dll       \SystemRoot\system32\mcupdate_GenuineIntel.dll
fffff801`65330000       c000    ntosext.sys                     \SystemRoot\System32\drivers\ntosext.sys
fffff801`656a0000       1a000   SgrmAgent.sys                   \SystemRoot\system32\drivers\SgrmAgent.sys
fffff801`657c0000       6b000   intelpep.sys                    \SystemRoot\System32\drivers\intelpep.sys
fffff801`65850000       b000    IntelTA.sys                     \SystemRoot\System32\drivers\IntelTA.sys
fffff801`658a0000       b000    intelide.sys                    \SystemRoot\System32\drivers\intelide.sys
fffff801`65b80000       1e000   mountmgr.sys                    \SystemRoot\System32\drivers\mountmgr.sys
fffff801`65e10000       2d9000  Ntfs.sys                        \SystemRoot\System32\Drivers\Ntfs.sys
fffff801`66640000       7f000   fwpkclnt.sys                    \SystemRoot\System32\drivers\fwpkclnt.sys
fffff801`67c10000       b000    vmgencounter.sys                \SystemRoot\System32\drivers\vmgencounter.sys
fffff801`67c50000       40000   intelppm.sys                    \SystemRoot\System32\drivers\intelppm.sys

```

### IOCTL

For getting the information about user-mode modules, you should use **DeviceIoControl** with `IOCTL = IOCTL_GET_USER_MODE_MODULE_DETAILS`, you have to send it in the following structure.

```clike
typedef struct _USERMODE_LOADED_MODULE_DETAILS
{
    UINT32  ProcessId;
    BOOLEAN OnlyCountModules;
    UINT32  ModulesCount;
    UINT32  Result;

    //
    // Here is a list of USERMODE_LOADED_MODULE_SYMBOLS (appended)
    //

} USERMODE_LOADED_MODULE_DETAILS, *PUSERMODE_LOADED_MODULE_DETAILS;
```

First, you need to fill the `ProcessId` and set the `OnlyCountModules` to **TRUE**. After that send the IOCTL and if the `Result` field of the above structure was equal to `DEBUGEER_OPERATION_WAS_SUCCESSFULL`, then you can see the number of modules at the `ModulesCount` field.

After that, you need to send the above IOCTL one more time. First, you need to allocate a buffer with the size of `ModulesCount * sizeof(USERMODE_LOADED_MODULE_SYMBOLS) + sizeof(USERMODE_LOADED_MODULE_DETAILS)`, fill the `ProcessId` and set the `OnlyCountModules` to **FALSE**.

```clike
typedef struct _USERMODE_LOADED_MODULE_SYMBOLS
{
    UINT64  BaseAddress;
    UINT64  Entrypoint;
    wchar_t FilePath[MAX_PATH];

} USERMODE_LOADED_MODULE_SYMBOLS, *PUSERMODE_LOADED_MODULE_SYMBOLS;
```

When the above structure is returned, at the bottom of the `USERMODE_LOADED_MODULE_DETAILS` is filled with an array of `USERMODE_LOADED_MODULE_SYMBOLS`. This array contains information about the module's `BaseAddress`, `Entrypoint`, and the `FilePath`.

Getting modules information for the kernel-mode modules is done by calling **NtQuerySystemInformation** and does not gets the address from the kernel, so it doesn't have any IOCTL.

### Remarks

This 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.

### Requirements

None

### Related

None


# cpu (check cpu supported technologies)

Description of the 'cpu' command in HyperDbg.

### Command

> cpu

### Syntax

> cpu

### Description

Shows the currently supported technologies on the processor based on the details provided by `cpuid` instruction.

### Parameters

None

### Examples

The following examples show a sample of `cpu` results.

```
HyperDbg> cpu

vendor : GenuineIntel
brand : Intel(R) Core(TM) i7-6820HQ CPU @ 2.70GHz

3DNOW not supported
3DNOWEXT not supported
ABM not supported
ADX supported
AES supported
AVX supported
AVX2 supported
AVX512CD not supported
AVX512ER not supported
                                ...
```

### IOCTL

This function is completely a user-mode function. There is no kernel IOCTL for it.

### Remarks

If you didn't attach to any remote sessions, it would show the current system's details.

This 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.

### Requirements

None

### Related

None


# ucpuid (execute CPUID instruction in debuggee)

Description of the 'ucpuid' command in HyperDbg.

### Command

> ucpuid

### Syntax

> ucpuid \[Function (hex)] \[SubFunction (hex)]

### Description

Executes the **CPUID** instruction on the target debuggee and displays the structured results.

{% hint style="info" %}
This command executes CPUID in the **target debuggee** (not the debugger). In local debugging mode, the debuggee and the debugger are the same machine, so the results reflect the local processor.
{% endhint %}

### Parameters

**\[Function (hex)]**

The CPUID leaf (i.e., the value placed in `EAX` before executing the `CPUID` instruction).

**\[SubFunction (hex)] (optional)**

The CPUID sub-leaf (i.e., the value placed in `ECX` before executing the `CPUID` instruction). If not specified, defaults to `0`.

{% hint style="info" %}
Use `ucpuid 0` to see the maximum supported basic CPUID leaf.

Use `ucpuid 0x80000000` to see the maximum supported extended CPUID leaf.
{% endhint %}

### Examples

The following example shows the result of `CPUID` with `EAX=0` (vendor and maximum basic leaf).

```c
1: kHyperDbg> ucpuid 0
  *******************************************************
  *               LEAF 0 HAS NO SUBLEAVES               *
  *       ANY SUBLEAF YOU ENTER WILL DEFAULT TO 0       *
  *      AND THE PROCESSOR RETURNS UNDEFINED VALUES     *
  *******************************************************

  Vendor : GenuineIntel
  Maximum supported basic leaf : 22
```

The following example shows the result of `CPUID` with `EAX=0x80000000` (maximum supported extended leaf).

```c
1: kHyperDbg> ucpuid 0x80000000
==== CPUID.(EAX=80000000H) Extended Function Information ====

  *******************************************************
  *           LEAF 0x80000000 HAS NO SUBLEAVES          *
  *       ANY SUBLEAF YOU ENTER WILL DEFAULT TO 0       *
  *      AND THE PROCESSOR RETURNS UNDEFINED VALUES     *
  *******************************************************

-- EAX --

  MaxExtendedFunctions = 0x80000008 (2147483656)

-- EBX --

  Reserved = 0x00000000

-- ECX --

  Reserved = 0x00000000

-- EDX --

  Reserved = 0x00000000
```

The following example shows the result of `CPUID` with `EAX=1` (version and feature information).

```c
1: kHyperDbg> ucpuid 0x1
==== CPUID.(EAX=01H) Version / Additional / Feature Information ====

  *******************************************************
  *               LEAF 1 HAS NO SUBLEAVES               *
  *       ANY SUBLEAF YOU ENTER WILL DEFAULT TO 0       *
  *      AND THE PROCESSOR RETURNS UNDEFINED VALUES     *
  *******************************************************

-- EAX: Version Information --

  SteppingId       = 2
  Model            = 5
  FamilyId         = 6
  ProcessorType    = 0
  ExtendedModelId  = 10
  ExtendedFamilyId = 0

-- EBX: Additional Information --

  BrandIndex        = 0
  ClflushLineSize   = 8 (cache line = 64 bytes)
  MaxAddressableIds = 8
  InitialApicId     = 1

-- ECX: Feature Information --

  SSE3                  = TRUE
  PCLMULQDQ             = TRUE
  DTES64                = FALSE
  MONITOR/MWAIT         = FALSE
  CPL Qualified DS      = FALSE
  VMX                   = TRUE
  SMX                   = FALSE
  EIST (SpeedStep)      = FALSE
  TM2                   = FALSE
  SSSE3                 = TRUE
  L1 Context ID         = FALSE
  Silicon Debug         = FALSE
  FMA                   = TRUE
  CMPXCHG16B            = TRUE
  xTPR Update Control   = FALSE
  PDCM                  = FALSE
  PCID                  = TRUE
  DCA                   = FALSE
  SSE4.1                = TRUE
  SSE4.2                = TRUE
  x2APIC                = TRUE
  MOVBE                 = TRUE
  POPCNT                = TRUE
  TSC-Deadline          = TRUE
  AESNI                 = TRUE
  XSAVE/XRSTOR          = TRUE
  OSXSAVE               = TRUE
  AVX                   = TRUE
  F16C                  = TRUE
  RDRAND                = TRUE

-- EDX: Feature Information --

  FPU                   = TRUE
  VME                   = TRUE
  DE                    = TRUE
  PSE                   = TRUE
  TSC                   = TRUE
  MSR (RDMSR/WRMSR)     = TRUE
  PAE                   = TRUE
  MCE                   = TRUE
  CX8 (CMPXCHG8B)       = TRUE
  APIC On-Chip          = TRUE
  SEP (SYSENTER/EXIT)   = TRUE
  MTRR                  = TRUE
  PGE                   = TRUE
  MCA                   = TRUE
  CMOV                  = TRUE
  PAT                   = TRUE
  PSE-36                = TRUE
  PSN                   = FALSE
  CLFSH                 = TRUE
  DS (Debug Store)      = FALSE
  ACPI (Thermal/Clock)  = FALSE
  MMX                   = TRUE
  FXSR (FXSAVE/FXRSTOR) = TRUE
  SSE                   = TRUE
  SSE2                  = TRUE
  SS (Self Snoop)       = TRUE
  HTT                   = TRUE
  TM (Thermal Monitor)  = FALSE
  PBE                   = FALSE
```

The following example uses a sub-leaf. For example, `CPUID` leaf `4` with sub-leaf `2`.

```c
1: kHyperDbg> ucpuid 4 2
==== CPUID.(EAX=04H) Deterministic Cache Parameters ====

  *******************************************************
  *             Max NumberOfSubLeaves = 3               *
  *******************************************************

---- CPUID.(EAX=04H, ECX=2) ----

-- EAX --

  CacheTypeField                   = 3 (Unified Cache)
  CacheLevel                       = 2
  SelfInitializingCacheLevel       = TRUE
  FullyAssociativeCache            = FALSE
  MaxAddressableIds(LogicalProcs)  (raw) = 0 -> actual = 1 (raw + 1)
  MaxAddressableIds(Cores)         (raw) = 7 -> actual = 8 (raw + 1)

-- EBX --

  SystemCoherencyLineSize          (raw) = 63 -> actual = 64 bytes (raw + 1)
  PhysicalLinePartitions           (raw) = 0 -> actual = 1 (raw + 1)
  WaysOfAssociativity              (raw) = 3 -> actual = 4 (raw + 1)

-- ECX --

  NumberOfSets                     (raw) = 1023 -> actual = 1024 (raw + 1)

-- EDX --

  WriteBackInvalidate              = FALSE
  CacheInclusiveness               = FALSE
  ComplexCacheIndexing             = FALSE (direct mapped)

-- Cache Size --

  Cache Size (per spec formula)    = 262144 bytes (256 KB, 0 MB)
```

### SDK

To execute the CPUID instruction in the target debuggee, use the following function in `libhyperdbg`:

```c
BOOLEAN
hyperdbg_u_request_cpuid(UINT32 FunctionId, UINT32 SubFunctionId);
```

### Remarks

Starting from HyperDbg **v0.23**, this command is available.

This command is guaranteed to keep debuggee in a halt state (in Debugger Mode); thus, nothing will change during its execution.

### Requirements

None

### Related

[cpu (check cpu supported technologies)](https://docs.hyperdbg.org/commands/debugging-commands/cpu)

[!cpuid (hook CPUID instruction execution)](https://docs.hyperdbg.org/commands/extension-commands/cpuid)


# rdmsr (read model-specific register)

Description of the 'rdmsr' command in HyperDbg.

### Command

> rdmsr

### Syntax

> rdmsr \[Msr (hex)] \[core CoreNumber (hex)]

### Description

Reads the model-specific register using '**rdmsr**' instruction.

### Parameters

**\[Msr (hex)]**

The index of MSR (`ECX` Register for '**rdmsr**' instruction).

**\[core CoreNumber (hex)] (optional)**

The core that we want to read the '**rdmsr**' from it.

{% hint style="success" %}
If you don't specify the 'core' by default, it shows the MSR for all cores.
{% endhint %}

### Examples

The following command shows the MSR register for `c0000082` using `rdmsr` command.

```diff
HyperDbg> rdmsr c0000082
core : 0x0 - msr[c0000082] = fffff807`73553180
core : 0x1 - msr[c0000082] = fffff807`73553180
core : 0x2 - msr[c0000082] = fffff807`73553180
core : 0x3 - msr[c0000082] = fffff807`73553180
```

The following example shows the MSR `c0000082` for core `2`.

```diff
HyperDbg> rdmsr c0000082 core 2
core : 0x2 - msr[c0000082] = fffff807`73553180
```

### IOCTL

This function works by calling **DeviceIoControl** with `IOCTL = IOCTL_DEBUGGER_READ_OR_WRITE_MSR`, you have to send it in the following structure.

```c
typedef struct _DEBUGGER_READ_AND_WRITE_ON_MSR {

  UINT64 Msr; // It's actually a 32-Bit value but let's not mess with a register
  UINT32 CoreNumber; // specifies the core to execute wrmsr or read the msr
                     // (DEBUGGER_READ_AND_WRITE_ON_MSR_APPLY_ALL_CORES mean all the cores)
  DEBUGGER_MSR_ACTION_TYPE
  ActionType; // Detects whether user needs wrmsr or rdmsr
  UINT64 Value;

} DEBUGGER_READ_AND_WRITE_ON_MSR, *PDEBUGGER_READ_AND_WRITE_ON_MSR;
```

Where `Msr` is `ecx` value for 'rdmsr' or 'wrmsr' instruction, `CoreNumber` is the target core that you want to read or write on it and `ActionType` shows whether it's an 'rdmsr' or 'wrmsr'.

```c
typedef enum _DEBUGGER_MSR_ACTION_TYPE { DEBUGGER_MSR_READ, DEBUGGER_MSR_WRITE } DEBUGGER_MSR_ACTION_TYPE;
```

{% hint style="info" %}
If you want to execute '**wrmsr**' or '**rdmsr**', you should set CoreNumber to `DEBUGGER_READ_AND_WRITE_ON_MSR_APPLY_ALL_CORES`.
{% endhint %}

```c
#define DEBUGGER_READ_AND_WRITE_ON_MSR_APPLY_ALL_CORES 0xffffffff
```

### Remarks

This 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.

### Requirements

None

### Related

[wrmsr (write model-specific register)](https://docs.hyperdbg.org/commands/debugging-commands/wrmsr)


# wrmsr (write model-specific register)

Description of the 'wrmsr' command in HyperDbg.

### Command

> wrmsr

### Syntax

> wrmsr \[Msr (hex)] \[Value (hex)] \[core CoreNumber (hex)]

### Description

Writes to the model-specific register using the '**wrmsr**' instruction.

### Parameters

**\[Msr (hex)]**

The index of MSR (`ECX` Register for '**wrmsr**' instruction).

**\[Value (hex)]**

The value to write on MSR (`EDX:EAX` for '**wrmsr**' instruction).

**\[core CoreNumber (hex)] (optional)**

The core that we want to write the MSR on it.

{% hint style="success" %}
If you don't specify the 'core' by default, it will be applied to all the cores.
{% endhint %}

### Examples

The following command shows how we can change the MSR register `c0000082` to ``fffff807`73553180`` using `wrmsr` command.

```diff
HyperDbg> wrmsr c0000082 fffff807`73553180
```

The following command shows how we can change the MSR register `c0000082` to the result of evaluating `nt!ExAllocatePoolWithTag+10` using `wrmsr` command.

```diff
HyperDbg> wrmsr c0000082 nt!ExAllocatePoolWithTag+10
```

The following command shows how we can change the MSR register `c0000082` to ``fffff807`73553180`` using `wrmsr` command for core `2`.

```diff
HyperDbg> wrmsr c0000082 fffff807`73553180 core 2
```

### IOCTL

This function works by calling **DeviceIoControl** with `IOCTL = IOCTL_DEBUGGER_READ_OR_WRITE_MSR`, you have to send it in the following structure.

```c
typedef struct _DEBUGGER_READ_AND_WRITE_ON_MSR {

  UINT64 Msr; // It's actually a 32-Bit value but let's not mess with a register
  UINT32 CoreNumber; // specifies the core to execute wrmsr or read the msr
                     // (DEBUGGER_READ_AND_WRITE_ON_MSR_APPLY_ALL_CORES mean all the cores)
  DEBUGGER_MSR_ACTION_TYPE
  ActionType; // Detects whether user needs wrmsr or rdmsr
  UINT64 Value;

} DEBUGGER_READ_AND_WRITE_ON_MSR, *PDEBUGGER_READ_AND_WRITE_ON_MSR;
```

Where `Msr` is `ecx` value for 'rdmsr' or 'wrmsr' instruction, `CoreNumber` is the target core that you want to read or write on it and `ActionType` shows whether it's an 'rdmsr' or 'wrmsr'.

```c
typedef enum _DEBUGGER_MSR_ACTION_TYPE { DEBUGGER_MSR_READ, DEBUGGER_MSR_WRITE } DEBUGGER_MSR_ACTION_TYPE;
```

{% hint style="info" %}
If you want to execute 'wrmsr' or 'rdmsr', you should set CoreNumber to `DEBUGGER_READ_AND_WRITE_ON_MSR_APPLY_ALL_CORES`.
{% endhint %}

```c
#define DEBUGGER_READ_AND_WRITE_ON_MSR_APPLY_ALL_CORES 0xffffffff
```

### Remarks

This 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.

### Requirements

None

### Related

[rdmsr (read model-specific register)](https://docs.hyperdbg.org/commands/debugging-commands/rdmsr)


# flush (remove pending kernel buffers and messages)

Description of the 'flush' command in HyperDbg.

### Command

> flush

### Syntax

> flush

### Description

This command removes all the possible pending buffers and messages from **all the commands (not just the command that you disabled or removed)** that are stored to be received by the user-mode from the kernel-mode, and when you press '[g](https://docs.hyperdbg.org/commands/debugging-commands/g)', you no longer see any results from previous commands; however, some commands might continue generating new messages, and those new messages won't be removed.

### Parameters

None

### IOCTL

This function works by calling **DeviceIoControl** with `IOCTL = IOCTL_DEBUGGER__FLUSH_LOGGING_BUFFERS`, you have to send it in the following structure.

```c
typedef struct _DEBUGGER_FLUSH_LOGGING_BUFFERS {

  UINT32 KernelStatus;
  UINT32 CountOfMessagesThatSetAsReadFromVmxRoot;
  UINT32 CountOfMessagesThatSetAsReadFromVmxNonRoot;

} DEBUGGER_FLUSH_LOGGING_BUFFERS, *PDEBUGGER_FLUSH_LOGGING_BUFFERS;
```

You don't need to fill anything from the above structure. The kernel will fill the structure, and if the `KernelStatus` was equal to `DEBUGEER_OPERATION_WAS_SUCCESSFULL`, then you can see the count of messages that are deleted from the vmx-root buffer from `CountOfMessagesThatSetAsReadFromVmxRoot` and vmx non-root buffer from `CountOfMessagesThatSetAsReadFromVmxNonRoot`.

In the debugger-mode, HyperDbg uses the exact same structure, you should send the above structure over serial to the debuggee which is paused in **vmx-root** mode.

You should send the above structure with `DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_MODE_FLUSH_BUFFERS` as `RequestedAction` and `DEBUGGER_REMOTE_PACKET_TYPE_DEBUGGER_TO_DEBUGGEE_EXECUTE_ON_VMX_ROOT` as `PacketType`.

In return, the debuggee sends the above structure with the following type.

```c
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_FLUSH
```

In the returned structure, the `KernelStatus` is filled by the kernel.

If the `KernelStatus` is `DEBUGEER_OPERATION_WAS_SUCCESSFULL`, then the operation was successful. Otherwise, the returned result is an error.

The following function is responsible for sending flushing buffers in the debugger.

```c
BOOLEAN KdSendFlushPacketToDebuggee();
```

### Remarks

You can configure **autoflush** mode in [settings](https://docs.hyperdbg.org/commands/debugging-commands/settings). This way, **HyperDbg** removes the pending messages automatically when you **disable** or **clear** an event.

This command is guaranteed to keep debuggee in a halt state (in Debugger Mode); thus, nothing will change during its execution.

### Requirements

None

### Related

[settings (configures different options and preferences)](https://docs.hyperdbg.org/commands/debugging-commands/settings)


# prealloc (reserve pre-allocated pools)

Description of the 'prealloc' command in HyperDbg.

### Command

> prealloc

### Syntax

> prealloc \[Type (string)] \[Count (hex)]

### Description

Reserves a specified number of pre-allocated pools. This command is mainly used to assist in the pre-allocation of pools for [**instant events**](https://docs.hyperdbg.org/tips-and-tricks/misc/instant-events).

In some cases, you need to reserve multiple pools to be used in vmx-root mode. This command will allocate these pools in **PASSIVE\_LEVEL**.

{% hint style="info" %}
HyperDbg tries to minimize the request for this command by allocating pools whenever your system is in **PASSIVE\_LEVEL**.
{% endhint %}

### Parameters

**\[Type (string)]**

The type of pool(s) to be reserved.

| Type                    |                                                                                                                                                                                                                                |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **thread-interception** | Used for storing details of processes with thousands of threads                                                                                                                                                                |
| **monitor**             | **!monitor** command's extra pages                                                                                                                                                                                             |
| **epthook**             | **!epthook** command's extra pages                                                                                                                                                                                             |
| **epthook2**            | **!epthook2** command's extra pages                                                                                                                                                                                            |
| **regular-event**       | Regular [instant events](https://docs.hyperdbg.org/tips-and-tricks/misc/instant-events)                                                                                                                                        |
| **big-event**           | Big [instant events](https://docs.hyperdbg.org/tips-and-tricks/misc/instant-events)                                                                                                                                            |
| **regular-safe-buffer** | Regular event safe buffers ([$buffer](https://docs.hyperdbg.org/commands/scripting-language/assumptions-and-evaluations#pseudo-registers)) for [instant events](https://docs.hyperdbg.org/tips-and-tricks/misc/instant-events) |
| **big-safe-buffer**     | Big event safe buffers ([$buffer](https://docs.hyperdbg.org/commands/scripting-language/assumptions-and-evaluations#pseudo-registers)) for [instant events](https://docs.hyperdbg.org/tips-and-tricks/misc/instant-events)     |

**\[Count (hex)]**

Number of pool(s) to be allocated and reserved.

### Examples

Imagine we want to pre-allocate and reserve **0x10** number of pools for the '[!monitor](https://docs.hyperdbg.org/commands/extension-commands/monitor)' command. If we're operating in the [Debugger Mode](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#debugger-mode), first we need to reserve and allocate pools for a [regular event](https://docs.hyperdbg.org/tips-and-tricks/misc/instant-events), then we need to allocate the same amount of pools for the memory **monitor** EPT hooks.

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

0: kHyperDbg> prealloc monitor 10
the requested pools are allocated and reserved
```

Again if we want to pre-allocate and reserve **0x10** number of pools for the '[!epthook](https://docs.hyperdbg.org/commands/extension-commands/epthook)' command. If we're operating in the [Debugger Mode](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#debugger-mode), first we need to reserve and allocate pools for a [regular event](https://docs.hyperdbg.org/tips-and-tricks/misc/instant-events), then we need to allocate the same amount of pools for the memory **epthook** EPT hooks.

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

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

Assume we need to pre-allocate and [reserve a safe buffer](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/how-to-create-an-action#pre-allocated-buffers) for an event in the [Debugger Mode](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#debugger-mode). We can use the following command.

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

### IOCTL

This function works by calling **DeviceIoControl** with `IOCTL = IOCTL_RESERVE_PRE_ALLOCATED_POOLS`, you have to send it in the following structure.

```c
typedef struct _DEBUGGER_PREALLOC_COMMAND
{
    DEBUGGER_PREALLOC_COMMAND_TYPE Type;
    UINT64                         Count;
    UINT32                         KernelStatus;

} DEBUGGER_PREALLOC_COMMAND, *PDEBUGGER_PREALLOC_COMMAND;
```

You should only fill the **Type** and **Count** of the above structure when the IOCTL returns from the kernel, other parts of this structure are filled with appropriate **KernelStatus**.

The **Type** can be from the following enum:

```
typedef enum _DEBUGGER_PREALLOC_COMMAND_TYPE
{
    DEBUGGER_PREALLOC_COMMAND_TYPE_MONITOR,
    DEBUGGER_PREALLOC_COMMAND_TYPE_THREAD_INTERCEPTION,
} DEBUGGER_PREALLOC_COMMAND_TYPE;
```

### Remarks

This 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.

### Requirements

None

### Related

None


# preactivate (pre-activate special functionalities)

Description of the 'preactivate' command in HyperDbg.

### Command

> preactivate

### Syntax

> preactivate \[Type (string)]

### Description

Initializes and pre-activates a specified functionality. This command is mainly used to optimize the overall performance of HyperDbg to avoid unnecessary operations.

{% hint style="info" %}
This command is only used in the [Debugger Mode](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#debugger-mode). In the [VMI Mode](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#vmi-mode), the initialization is done automatically.
{% endhint %}

### Parameters

**\[Type (string)]**

The type of functionality to be initialized.

| Type     |                                                                                                                     |
| -------- | ------------------------------------------------------------------------------------------------------------------- |
| **mode** | Used for initialization of the '[!mode](https://docs.hyperdbg.org/commands/extension-commands/mode)' event command. |

### Examples

If you use the '[!mode](https://docs.hyperdbg.org/commands/extension-commands/mode)' command in the [Debugger Mode](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#debugger-mode), only for the first time, the following error will be shown.

```
0: kHyperDbg> !mode u pid 1c0 
err, for performance reasons, the '!mode' event command cannot be directly initialized in the Debugger Mode. You can use the 'preactivate mode' command to preactivate this mechanism after that, you can use the '!mode' event (c000004e)
```

To solve this issue, the following command can be used:

```
0: kHyperDbg> preactivate mode
the requested service is activated successfully!
fffff807`9b9f8e62    0F 01 C1
```

Once you pre-activate the above functionality, it remains active until the next load of the debugger.

### IOCTL

This function works by calling **DeviceIoControl** with `IOCTL = IOCTL_PREACTIVATE_FUNCTIONALITY`, you have to send it in the following structure.

```c
typedef struct _DEBUGGER_PREACTIVATE_COMMAND
{
    DEBUGGER_PREACTIVATE_COMMAND_TYPE Type;
    UINT32                            KernelStatus;

} DEBUGGER_PREACTIVATE_COMMAND, *PDEBUGGER_PREACTIVATE_COMMAND;

```

You should only fill in the **Type** of the above structure when the IOCTL returns from the kernel; other parts of this structure are filled with the appropriate **KernelStatus**.

The **Type** can be from the following enum:

```
typedef enum _DEBUGGER_PREACTIVATE_COMMAND_TYPE
{
    DEBUGGER_PREACTIVATE_COMMAND_TYPE_MODE,

} DEBUGGER_PREACTIVATE_COMMAND_TYPE;
```

### Remarks

This 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.

### Requirements

None

### Related

None


# output (create output source for event forwarding)

Description of the 'output' command in HyperDbg.

### Command

> output

### Syntax

> output
>
> output \[create Name (string)] \[file|namedpipe|tcp|module Address (string)]
>
> output \[open|close Name (string)]

### Description

Create, open, or close a source output for event forwarding.

You can read more about **event forwarding** [here](https://docs.hyperdbg.org/tips-and-tricks/misc/event-forwarding).

Examples of using this mechanism in different programming languages are available here:

{% embed url="<https://github.com/HyperDbg/event-forwarding-examples>" %}

### Parameters

**\[create Name (string)]**

The name of the instance output to be created.

**\[file|namedpipe|tcp|module Address (string)]**

Type and address of the target resource.

**\[open|close Name (string)]**

The action of this command or whether this command tries to open an output source or close it combined with its name.

{% hint style="success" %}
If you don't specify any parameters to the '**output**' command, it shows a list of output sources and their status.
{% endhint %}

### Examples

The following command creates an output source, which is a `file` and the results of the command (script) will be saved into the `c:\users\sina\desktop\output.txt`.

```diff
HyperDbg> output create MyOutputName1 file c:\users\sina\desktop\output.txt
```

The following command creates an output source, which is a `tcp` and the results of the command (script) will be sent into the `192.168.1.10:8080`.

```diff
HyperDbg> output create MyOutputName2 tcp 192.168.1.10:8080
```

The following command creates an output source, which is a `namedpipe` and the results of the command (script) will be sent into the `\\.\Pipe\HyperDbgOutput`.

```diff
HyperDbg> output create MyOutputName3 namedpipe \\.\Pipe\HyperDbgOutput
```

You cannot use the above resources until you **open** them using the following command. This command opens an output source (named "**MyOutputName1**") that was previously created by the output's **create** parameter.

```diff
HyperDbg> output open MyOutputName1
```

When you finished using an output source, you can **close** it using the following command. Once you close an output source, you cannot use it anymore, and also, you **CANNOT** open it again, but once again, you can **create** a new source with the same address but with a different **name**.

```diff
HyperDbg> output close MyOutputName1
```

After creating and opening the output source, you can use its name in all HyperDbg events. You should pass `output {MyOutputName1}` when you are creating an event, for example [!syscall](https://docs.hyperdbg.org/commands/extension-commands/syscall) is an event so that you can use it like this :

```diff
HyperDbg> !syscall script { print(@rax); } output {MyOutputName1}
```

It is also possible to send the results to several output sources. You should separate the output names with `,` .

For example :

```diff
HyperDbg> !syscall script { print(@rax); } output {MyOutputName1 , MyOutputName2 , MyOutputName3}
```

You can specify up to `5` output sources in the default build of HyperDbg, but if you need more output sources for a single event, then you should compile HyperDbg with different configurations as described on [Customize Build](https://docs.hyperdbg.org/tips-and-tricks/misc/customize-build) and change the `DebuggerOutputSourceMaximumRemoteSourceForSingleEvent`.

Starting from v0.10, HyperDbg supports modules (DLLs) as functions that directly load DLLs and have the ability to forward events to functions. Note that, DLLs should be compiled into 64-bit binaries (32-bit binaries are not supported). Examples of DLLs are available in [Rust](https://github.com/HyperDbg/event-forwarding-examples/tree/main/Rust/module) and [C++](https://github.com/HyperDbg/event-forwarding-examples/tree/main/C%2B%2B/module).

Generally, DLLs (in all low-level languages) should export a function with the name `hyperdbg_event_forwarding` with the first parameter as a pointer to the buffer message and the second parameter as an integer with the size that will be called by HyperDbg's event forwarding module once an event is triggered. The following example is the definition of the function in C/C++ (You can do the same in Rust, GO, etc.).

```cpp
hyperdbg_event_forwarding(const char* buffer_message, unsigned int buffer_length);
```

After compiling the above function and exporting the above function (e.g., by using `__declspec(dllexport)`), you can open a `module` using the following command:

```
output create MyOutputName1 module C:\module\event_forwarding_module.dll
```

and after that, open it using the following command:

```
output open MyOutputName1
```

and then (same as above examples) you can pass the events using the following event:

```c
!epthook nt!ExAllocatePoolWithTag script {
	printf("Pool allocation called!");
} output { MyOutputName1 }
```

In case, you want to see a list of sources, you can use the '**output**' command without any parameter.

```
HyperDbg> output
1  file        not opened       MyOutputName1
2  file        opened           MyOutputName2
3  file        not opened       MyOutputName3
```

### IOCTL

None

### Remarks

You can use this command to forward the scripts' results from all the [events](https://docs.hyperdbg.org/design/debugger-internals/events).

{% hint style="danger" %}
You **cannot** use event forwarding in the immediate messaging mode in events (`imm no`).
{% endhint %}

### Requirements

None

### Related

[Event Forwarding](https://docs.hyperdbg.org/tips-and-tricks/misc/event-forwarding)


# test (test functionalities)

Description of the 'test' command in HyperDbg.

### Command

> test

### Syntax

> test \[Task (string)]

### Description

Tests the functionalities of HyperDbg in the running system.

### Parameters

**\[Task (string)]**

Different options are used mostly for debugging the internal mechanisms of HyperDbg.

<table><thead><tr><th>Option</th><th>Description</th><th data-hidden></th></tr></thead><tbody><tr><td><strong>query</strong></td><td>Shows the state of each core (e.g., halted or not)</td><td></td></tr><tr><td><strong>pool</strong></td><td>Shows the state of memory pool allocation and pre-allocation</td><td></td></tr><tr><td><strong>breakpoint</strong></td><td>Turns the interception of breakpoints (#BP) ON/OFF.</td><td></td></tr><tr><td><strong>trap</strong></td><td>Turns the interception of debug breaks (#DB) ON/OFF.</td><td></td></tr><tr><td><strong>trap-status</strong></td><td>Shows the state of simultaneously debugging threads that HyperDbg sets the trap flag on them</td><td></td></tr></tbody></table>

### Examples

The following command shows how to check all the test-cases.

```cpp
HyperDbg> test
```

The following command shows the '**lock**' state of each core.

```
0: kHyperDbg> test query
================================================ Debugging Lock Info ================================================
(04:32:04.709 - core : 0 - vmx-root? yes)        [+] Information (KdQuerySystemState:1603) | Core : 0 is locked
(04:32:04.709 - core : 0 - vmx-root? yes)        [+] Information (KdQuerySystemState:1603) | Core : 1 is locked
(04:32:04.709 - core : 0 - vmx-root? yes)        [+] Information (KdQuerySystemState:1603) | Core : 2 is locked
(04:32:04.709 - core : 0 - vmx-root? yes)        [+] Information (KdQuerySystemState:1603) | Core : 3 is locked
(04:32:04.709 - core : 0 - vmx-root? yes)        [+] Information (KdQuerySystemState:1603) | Core : 4 is locked
(04:32:04.709 - core : 0 - vmx-root? yes)        [+] Information (KdQuerySystemState:1603) | Core : 5 is locked

================================================ NMI Receiver State =======+=========================================
(04:32:04.709 - core : 0 - vmx-root? yes)        [+] Information (KdQuerySystemState:1625) | Core : 0 - not called from an NMI handler (through the immediate VM-exit mechanism)
(04:32:04.709 - core : 0 - vmx-root? yes)        [+] Information (KdQuerySystemState:1625) | Core : 1 - not called from an NMI handler (through the immediate VM-exit mechanism)
(04:32:04.709 - core : 0 - vmx-root? yes)        [+] Information (KdQuerySystemState:1625) | Core : 2 - not called from an NMI handler (through the immediate VM-exit mechanism)
(04:32:04.709 - core : 0 - vmx-root? yes)        [+] Information (KdQuerySystemState:1625) | Core : 3 - not called from an NMI handler (through the immediate VM-exit mechanism)
(04:32:04.709 - core : 0 - vmx-root? yes)        [+] Information (KdQuerySystemState:1625) | Core : 4 - not called from an NMI handler (through the immediate VM-exit mechanism)
(04:32:04.709 - core : 0 - vmx-root? yes)        [+] Information (KdQuerySystemState:1625) | Core : 5 - not called from an NMI handler (through the immediate VM-exit mechanism)
```

The following command shows the state of pool allocation.

```
0: kHyperDbg> test pool
(04:32:04.709 - core : 0 - vmx-root? yes)        [+] Information (PoolManagerShowPreAllocatedPools:218) | Pool details, Pool intention: 4 | Pool address: ffffc1059fdd1cc0 | Pool state: free | Should be freed: false | Already freed: false

(04:32:04.709 - core : 0 - vmx-root? yes)        [+] Information (PoolManagerShowPreAllocatedPools:218) | Pool details, Pool intention: 4 | Pool address: ffffc1059fdd1f00 | Pool state: free | Should be freed: false | Already freed: false

(04:32:04.709 - core : 0 - vmx-root? yes)        [+] Information (PoolManagerShowPreAllocatedPools:218) | Pool details, Pool intention: 4 | Pool address: ffffc1059fdd1b40 | Pool state: free | Should be freed: false | Already freed: false
...
```

The following command is used to turn OFF/ON the breakpoint (#BP) interception.

```
0: kHyperDbg> test breakpoint on
breakpoint interception (#BP) is activated

0: kHyperDbg> test breakpoint off
breakpoint interception (#BP) is deactivated
from now, the breakpoints will be re-injected into the guest debuggee
```

The following command is used to turn OFF/ON the debug break (#DB) interception.

```
0: kHyperDbg> test trap on
debug break interception (#DB) is activated

4: kHyperDbg> test trap off
debug break interception (#DB) is deactivated
from now, the debug breaks will be re-injected into the guest debuggee
```

The following command shows the state of simultaneously debugging threads that HyperDbg sets the trap flag on them.

```
0: kHyperDbg> test trap-status
(01:14:17.385 - core : 0 - vmx-root? yes)        [+] Information (KdQueryRflagTrapState:1568) | Number of valid entries: 0x0
(Please be aware that only top 0x0 items are considered valid. There could be other items present in the array, but they are not valid.)
(01:14:17.385 - core : 0 - vmx-root? yes)        [+] Information (KdQueryRflagTrapState:1575) | g_TrapFlagState.ThreadInformation[0].ProcessId = 0 | ThreadId = 0
(01:14:17.385 - core : 0 - vmx-root? yes)        [+] Information (KdQueryRflagTrapState:1575) | g_TrapFlagState.ThreadInformation[1].ProcessId = 0 | ThreadId = 0
(01:14:17.385 - core : 0 - vmx-root? yes)        [+] Information (KdQueryRflagTrapState:1575) | g_TrapFlagState.ThreadInformation[2].ProcessId = 0 | ThreadId = 0
(01:14:17.385 - core : 0 - vmx-root? yes)        [+] Information (KdQueryRflagTrapState:1575) | g_TrapFlagState.ThreadInformation[3].ProcessId = 0 | ThreadId = 0
(01:14:17.385 - core : 0 - vmx-root? yes)        [+] Information (KdQueryRflagTrapState:1575) | g_TrapFlagState.ThreadInformation[4].ProcessId = 0 | ThreadId = 0
(01:14:17.385 - core : 0 - vmx-root? yes)        [+] Information (KdQueryRflagTrapState:1575) | g_TrapFlagState.ThreadInformation[5].ProcessId = 0 | ThreadId = 0
(01:14:17.385 - core : 0 - vmx-root? yes)        [+] Information (KdQueryRflagTrapState:1575) | g_TrapFlagState.ThreadInformation[6].ProcessId = 0 | ThreadId = 0
```

### IOCTL

None

### Remarks

Each time the connection to the debugger is restarted, the **breakpoint interception** and **debug break interception** are activated.

### Requirements

None

### Related

None


# settings (configures different options and preferences)

Description of the 'settings' command in HyperDbg.

### Command

> settings

### Syntax

> settings \[OptionName (string)]
>
> settings \[OptionName (string)] \[Value (hex)]
>
> settings \[OptionName (string)] \[Value (string)]
>
> settings \[OptionName (string)] \[on|off]

### Description

This command queries or changes the value of options and preferences.

### Parameters

**\[OptionName (string)]**

Name of the option.

**\[Value (hex)]**

Target value (hex) to modify the option.

**\[Value (string)]**

Target value (string) to modify the option.

**\[on|off]**

On or off value to modify the option.

{% hint style="success" %}
Each option has its own value; for example, some options might be on or off, and others might be custom numbers or names.
{% endhint %}

### Options

| Options               | Values               | Default Value |
| --------------------- | -------------------- | ------------- |
| **autoflush**         | on \| off            | off           |
| **autounpause**       | on \| off            | on            |
| **syntax**            | intel \| att \| masm | intel         |
| **addressconversion** | on \| off            | on            |

**autoflush :** if you turn **autoflush** on, after each disabling or clearing an event using the '[events](https://docs.hyperdbg.org/commands/debugging-commands/events)' command, all the possible pending buffers and messages from **all the commands (not just the command that you disabled or removed)** that are stored to be received by the user-mode from the kernel-mode and when you press '[g](https://docs.hyperdbg.org/commands/debugging-commands/g)', you no longer see any results from previous commands; however, some commands might continue generating new messages, and those new messages won't be removed.

You can also perform the **autoflush** manually by running the '[flush](https://docs.hyperdbg.org/commands/debugging-commands/flush)' command.

**autounpause** : if you turn **autounpause** on, then if you press CTRL+C or run the '[pause](https://docs.hyperdbg.org/commands/debugging-commands/pause)' command to break to the debugger, every new event will automatically turn off your break, and you'll start receiving events and messages from the kernel-mode buffers. However, if you turn it off, then you won't receive kernel buffers and messages when you invoke a new event as the debugger will remain in the paused state (for example, paused because of '[pause](https://docs.hyperdbg.org/commands/debugging-commands/pause)' command or CTRL+C), in this case, you can resume receiving messages from the kernel-mode buffer by running '[g](https://docs.hyperdbg.org/commands/debugging-commands/g)' command.

**syntax** : specifies the syntax of disassembler for '[!u and !u2](https://docs.hyperdbg.org/commands/extension-commands/u)' commands.

**addressconversion** : if you turn **addressconversion** on, then in the case of disassembling memory, it converts addresses to object names (if the symbol is available for that address). Otherwise, it shows the address in hex format. This option also affects showing function names in stepping through the instructions.

### Examples

The following command shows the state of `autounpause` option.

```diff
HyperDbg> settings autounpause
auto-unpause is enabled
```

The following command turns **`autounpause`** on.

```diff
HyperDbg> settings autounpause on
set auto-unpause to enabled
```

The following command turns **`autounpause`** off.

```
HyperDbg> settings autounpause off
set auto-unpause to disabled
```

The following command shows the different **syntax** used in the disassembler. You can choose your favorite **syntax** to show in '[!u and !u2' ](https://docs.hyperdbg.org/commands/extension-commands/u)commands.

```c
HyperDbg> settings syntax intel
set syntax to intel


HyperDbg >u fffff804`2d16f010
fffff804`2d16f010 48 89 5C 24 08                      mov qword ptr ss:[rsp+0x08], rbx
fffff804`2d16f015 48 89 6C 24 10                      mov qword ptr ss:[rsp+0x10], rbp
fffff804`2d16f01a 48 89 74 24 18                      mov qword ptr ss:[rsp+0x18], rsi
fffff804`2d16f01f 57                                  push rdi
fffff804`2d16f020 41 56                               push r14
fffff804`2d16f022 41 57                               push r15
fffff804`2d16f024 48 83 EC 30                         sub rsp, 0x30
fffff804`2d16f028 65 48 8B 04 25 20 00 00 00          mov rax, qword ptr gs:[0x0000000000000020]
fffff804`2d16f031 33 DB                               xor ebx, ebx
fffff804`2d16f033 44 0F B7 3D C5 3F 20 00             movzx r15d, word ptr ds:[0xFFFFF8042D373000]
fffff804`2d16f03b 41 8B E8                            mov ebp, r8d
fffff804`2d16f03e 48 8B F2                            mov rsi, rdx
fffff804`2d16f041 89 5C 24 68                         mov dword ptr ss:[rsp+0x68], ebx
fffff804`2d16f045 8B F9                               mov edi, ecx
fffff804`2d16f047 4C 8B 88 C0 00 00 00                mov r9, qword ptr ds:[rax+0xC0]


HyperDbg> settings syntax att
set syntax to at&t

HyperDbg> u fffff804`2d16f010
fffff804`2d16f010 48 89 5C 24 08                      movq %rbx, %ss:0x08(%rsp)
fffff804`2d16f015 48 89 6C 24 10                      movq %rbp, %ss:0x10(%rsp)
fffff804`2d16f01a 48 89 74 24 18                      movq %rsi, %ss:0x18(%rsp)
fffff804`2d16f01f 57                                  push %rdi
fffff804`2d16f020 41 56                               push %r14
fffff804`2d16f022 41 57                               push %r15
fffff804`2d16f024 48 83 EC 30                         sub $0x30, %rsp
fffff804`2d16f028 65 48 8B 04 25 20 00 00 00          movq %gs:0x0000000000000020, %rax
fffff804`2d16f031 33 DB                               xor %ebx, %ebx
fffff804`2d16f033 44 0F B7 3D C5 3F 20 00             movzxw %ds:0xFFFFF8042D373000, %r15d
fffff804`2d16f03b 41 8B E8                            mov %r8d, %ebp
fffff804`2d16f03e 48 8B F2                            mov %rdx, %rsi
fffff804`2d16f041 89 5C 24 68                         movl %ebx, %ss:0x68(%rsp)
fffff804`2d16f045 8B F9                               mov %ecx, %edi
fffff804`2d16f047 4C 8B 88 C0 00 00 00                movq %ds:0xC0(%rax), %r9


HyperDbg> settings syntax masm
set syntax to masm

HyperDbg >u fffff804`2d16f010
fffff804`2d16f010 48 89 5C 24 08                      mov qword ptr ss:[rsp+8h], rbx
fffff804`2d16f015 48 89 6C 24 10                      mov qword ptr ss:[rsp+10h], rbp
fffff804`2d16f01a 48 89 74 24 18                      mov qword ptr ss:[rsp+18h], rsi
fffff804`2d16f01f 57                                  push rdi
fffff804`2d16f020 41 56                               push r14
fffff804`2d16f022 41 57                               push r15
fffff804`2d16f024 48 83 EC 30                         sub rsp, 30h
fffff804`2d16f028 65 48 8B 04 25 20 00 00 00          mov rax, qword ptr gs:[$+20h]
fffff804`2d16f031 33 DB                               xor ebx, ebx
fffff804`2d16f033 44 0F B7 3D C5 3F 20 00             movzx r15d, word ptr ds:[$+203FCDh]
fffff804`2d16f03b 41 8B E8                            mov ebp, r8d
fffff804`2d16f03e 48 8B F2                            mov rsi, rdx
fffff804`2d16f041 89 5C 24 68                         mov dword ptr ss:[rsp+68h], ebx
fffff804`2d16f045 8B F9                               mov edi, ecx
fffff804`2d16f047 4C 8B 88 C0 00 00 00                mov r9, qword ptr ds:[rax+C0h]
```

### IOCTL

None

### Remarks

**autounpause** and **autoflush** do not change anything in [debugger mode](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#debugger-mode). It is because the buffers are not accumulated and passed instantly in this mode; thus, there is nothing to flush.

### Requirements

None

### Related

None


# exit (exit from the debugger)

Description of the 'exit' command in HyperDbg.

### Command

> exit

### Syntax

> exit

### Description

Unloads the kernel modules and closes the debugger.

### Parameters

None

### Examples

None

### IOCTL

Performs an `unload` before exiting the debugger, please visit [unload ](https://docs.hyperdbg.org/commands/debugging-commands/unload)for more information.

### Remarks

None

### Requirements

None

### Related

[unload (unload the kernel modules)](https://docs.hyperdbg.org/commands/debugging-commands/unload)


# Meta Commands


# .help (show the help of commands)

Description of the '.help' command in HyperDbg.

### Command

> .help

### Syntax

> .help \[Command (string)]

### Description

Shows the help and example(s) of using a specific command.

### Parameters

**\[Command (string)]**

The target command.

### Examples

The following command shows the help of `!epthook2` command.

```
HyperDbg> .help !epthook2
```

### IOCTL

None

### Remarks

You can use `.hh` and `help` too, these are aliases for `.help`.

### Requirements

None

### Related

None


# .debug (prepare and connect to debugger)

Description of the '.debug' command in HyperDbg.

### Command

> .debug

### Syntax

> .debug \[remote] \[serial|namedpipe] \[pause] \[Baudrate (decimal)] \[Address (string)]
>
> .debug \[prepare] \[serial] \[Baudrate (decimal)] \[Address (string)]
>
> .debug \[close]

### Description

This command prepares debuggee for a remote connection or connects to a remote debuggee.

{% hint style="warning" %}
Please note that you should first wait for reconnecting on the **debugger,** then connect to it in the **debuggee.**
{% endhint %}

### Parameters

**\[remote]**

If you specify `remote` then it means that you want to connect to a debuggee.

**\[prepare]**

If you specify `prepare` then it means that you want to prepare the current machine to be debugged as debuggee.

**\[close]**

`close` means to close all the connections to the debuggee.

**\[serial|namedpipe]**

If you want to use a serial port as the connection, you should choose `serial`, and if you want to connect to a named pipe, then you should specify `namedpipe`. Please note that `namedpipe` cannot be used in debuggee, and it can be used only in the debugger.

**\[pause]**

In the case of choosing `remote` , specifies whether the debuggee should be paused after connection or not. In case you don't specify this argument, it means the debuggee won't be paused (halted) upon connection.

**\[serial]**

In the case of choosing `prepare`, only `serial` is supported as the type of connection.

**\[Baudrate (Decimal)]**

This value shows the baud rate of the device. (See [Remarks](https://docs.hyperdbg.org/commands/meta-commands/.debug#remarks) for more information)

**\[Address (string)]**

COM port address or named pipe address. (See [Remarks](https://docs.hyperdbg.org/commands/meta-commands/.debug#remarks) for more information)

### Examples

If you want to have a kernel debug connection, first, you should run the following command in a debugger (host). As you can see, you can change the `com3`to your COM port that is connected to the debuggee.

```
HyperDbg> .debug remote serial 115200 com3
```

If you want to use a named pipe instead of a COM port, you can execute the following command in the debugger (Host).

```
HyperDbg> .debug remote namedpipe \\.\pipe\HyperDbgPipe
```

Or if you want to immediately pause debuggee upon connection, you can execute the following command in the debugger (Host). Note that, a `pause` is added to the above command.

```
HyperDbg> .debug remote pause namedpipe \\.\pipe\HyperDbgPipe
```

After you tell the debugger to listen on a COM port or a named pipe, now you can run the following command in the debuggee.

```
HyperDbg> .debug prepare serial 115200 com2
```

If you want to disconnect from the debuggee, then you should run the following command.

```
HyperDbg> .debug close
```

### SDK

To connect to the target debuggee using the named pipe, you need to use the following function in `libhyperdbg`:

```clike
BOOLEAN
hyperdbg_u_connect_remote_debugger_using_named_pipe(const CHAR * named_pipe, BOOLEAN pause_after_connection);
```

To connect to the target debuggee using the COM port, you need to use the following function in `libhyperdbg`:

```clike
BOOLEAN
hyperdbg_u_connect_remote_debugger_using_com_port(const CHAR * port_name, DWORD baudrate, BOOLEAN pause_after_connection);
```

Once you run the above functions in the **debugger**, you can run the following function in the **debuggee**:

```clike
BOOLEAN
hyperdbg_u_connect_current_debugger_using_com_port(const CHAR * port_name, DWORD baudrate);
```

To disconnect from the current debuggee, you need to use the following function in `libhyperdbg`:

```clike
BOOLEAN
hyperdbg_u_debug_close_remote_debugger();
```

### Remarks

1. The following values are valid baud rates for serial connections.

| Baud rate  |
| ---------- |
| **110**    |
| **300**    |
| **600**    |
| **1200**   |
| **2400**   |
| **4800**   |
| **9600**   |
| **14400**  |
| **19200**  |
| **38400**  |
| **56000**  |
| **57600**  |
| **115200** |
| **128000** |
| **256000** |

The following COM ports are valid for debugging.

| COM Port |
| -------- |
| **com1** |
| **com2** |
| **com3** |
| **com4** |

### Requirements

None

### Related

[Attach to a remote machine](https://docs.hyperdbg.org/getting-started/attach-to-hyperdbg/attach-to-remote-machine)


# .connect (connect to a session)

Description of the '.connect' command in HyperDbg.

### Command

> .connect

### Syntax

> .connect \[local]
>
> .connect \[Ip (string)] \[Port (decimal)]

### Description

Connects to a remote computer session or connects to a local debugger.

{% hint style="success" %}
If you don't specify the port, then **HyperDbg** uses the default port, which is **50000**; however, you can [change the default port](https://docs.hyperdbg.org/tips-and-tricks/misc/customize-build) if you compile the **HyperDbg**.
{% endhint %}

### Parameters

**\[local]**

The local debugging system.

**\[Ip (string)]**

The IP Address of the remote system.

**\[Port (decimal)] (optional)**

The port address that the remote debugger listens on.

### Examples

The following example connects to the current system for **local debugging**.

```
HyperDbg> .connect local
```

The following command connects to a remote system (**192.168.1.5**) which the **HyperDbg** debugger listens on its **50000** (by default) port.

```
HyperDbg> .connect 192.168.1.5
```

The following command connects to a remote system (**192.168.1.5**) which the HyperDbg debugger listens on its **50001** port.

```
HyperDbg> .connect 192.168.1.5 50001
```

### SDK

To connect to the local debugger in the [VMI Mode](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#vmi-mode), you need to use the following function in `libhyperdbg`:

```clike
VOID
hyperdbg_u_connect_local_debugger();
```

To connect to the remote debugger in the [VMI Mode](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#vmi-mode), you need to use the following function in `libhyperdbg`:

```clike
BOOLEAN
hyperdbg_u_connect_remote_debugger(const CHAR * ip, const CHAR * port);
```

### Remarks

1. In order to be able to load modules and run commands, you have to connect to a remote system or debug your current system.

### Requirements

None

### Related

[.disconnect (disconnect from a session)](https://docs.hyperdbg.org/commands/meta-commands/.disconnect)


# .disconnect (disconnect from a session)

Description of the '.disconnect' command in HyperDbg.

### Command

> .disconnect

### Syntax

> .disconnect

### Description

Disconnects from the current session.

### Parameters

None

### Examples

None

### IOCTL

None

### Remarks

This function disconnects from a session and will not unload the kernel modules.

### Requirements

None

### Related

[.connect (connect to a session)](https://docs.hyperdbg.org/commands/meta-commands/.connect)


# .listen (listen on a port and wait for the debugger to connect)

Description of the '.listen' command in HyperDbg.

### Command

> .listen

### Syntax

> .listen \[Port (decimal)]

### Description

Listens for the debugger to connect to **this computer** (works as a **guest** debuggee server).

{% hint style="success" %}
If you don't specify the port, then **HyperDbg** uses the default port, which is **50000**; however, you can [change the default port](https://docs.hyperdbg.org/tips-and-tricks/misc/customize-build) if you compile the **HyperDbg**.
{% endhint %}

### Parameters

**\[Port (decimal)] (optional)**

The port address that the remote debugger listens on.

### Examples

The following command enables a server and listens on a port (by default **50000**), and waits for a debugger to connect to it.

```
HyperDbg> .listen
```

The following command enables a server and listens on port **50001**, and waits for a debugger to connect to it.

```
HyperDbg> .listen 50001
```

### IOCTL

None

### Remarks

This command provides a target debuggee server (guest server), and the host (debugger) will connect to this server by using the '[.connect](https://docs.hyperdbg.org/commands/meta-commands/.connect)' command.

### Requirements

None

### Related

[.connect (connect to a session)](https://docs.hyperdbg.org/commands/meta-commands/.connect)


# .status (show the debugger status)

Description of the '.status' command in HyperDbg.

### Command

> .status

### Syntax

> .status

### Description

Shows the connection status of the **HyperDbg**'s Connection.

### Parameters

None

### Examples

The following example shows the status of remote debugging.

```
HyperDbg (192.168.1.10:50000)> .status
remote debugging ('vmi mode'), ip : 192.168.1.10:50000
```

### IOCTL

None

### Remarks

In **HyperDbg**, '[status](https://docs.hyperdbg.org/commands/debugging-commands/status)' and '.status' commands are different if you connected to a remote debugger, but if you try to debug your system locally, then these commands are the same.

If you execute the '.status' command, it shows the current debugger's status (the debuggee's IP address). If you execute the '[status](https://docs.hyperdbg.org/commands/debugging-commands/status)' command, it will be executed in the debuggee and shows the debuggee's state (not debugger).

### Requirements

None

### Related

[status (show the debuggee status)](https://docs.hyperdbg.org/commands/debugging-commands/status)


# .start (start a new process)

Description of the '.start' command in HyperDbg.

### Command

> .start

### Syntax

> .start \[path Path (string)] \[Parameters (string)]

### Description

Starts a program with the specific parameters and breaks when the PE file reaches the entrypoint.

{% hint style="danger" %}
The user-mode debugger is still in the beta version and not stable. We decided to exclude it from this release and release it in future versions. If you want to test the user-mode debugger in **VMI Mode**, you should build HyperDbg with special instructions. Please follow the instruction [here](https://docs.hyperdbg.org/getting-started/build-and-install#activating-user-mode-debugger).

In contrast with the kernel debugger, the user debugger is still very basic and needs a lot of tests and improvements. We **highly recommend** not to run the user debugger in your bare metal system. Instead, run it on a [supported virtual machine](https://docs.hyperdbg.org/tips-and-tricks/nested-virtualization-environments/supported-virtual-machines) so you won't end up with a Blue Screen of Death (BSOD) in your primary device. Please keep reporting the issues to improve the user debugger.
{% endhint %}

{% hint style="info" %}
This command won't use any Windows API for intercepting and pausing threads, and everything is done at the hypervisor level.
{% endhint %}

### Parameters

**\[path Path (string)]**

The target file path

**\[Parameters (string)] (optional)**

The parameter(s) to the file

### Examples

Imagine we want to start a program without parameters.

```
0: kHyperDbg> .start path C:\file\my_file.exe
```

If your file path contains a space character, you should write the path between two quotes; otherwise, it will be interpreted as parameters.

```
0: kHyperDbg> .start path "C:\my files\my file.exe"
```

If you want to pass parameters to your target file. Imagine we want to pass `-m 1 -o out.txt` parameters to our exe file.

```
0: kHyperDbg> .start path "C:\my files\my file.exe" -m 1 -o out.txt
```

### SDK

To start a process in the target debuggee, you need to use the following function in `libhyperdbg`:

```clike
BOOLEAN
hyperdbg_u_start_process(const WCHAR * path);
```

To start a process in the target debuggee with custom arguments, you need to use the following function in `libhyperdbg`:

```clike
BOOLEAN
hyperdbg_u_start_process_with_args(const WCHAR * path, const WCHAR * arguments);
```

### Remarks

This 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.

### Requirements

None

### Related

[.restart (restart the process)](https://docs.hyperdbg.org/commands/meta-commands/.restart)

[.attach (attach to a process)](https://docs.hyperdbg.org/commands/meta-commands/.attach)

[.detach (detach from the process)](https://docs.hyperdbg.org/commands/meta-commands/.detach)

[.switch (show the list and switch between active debugging threads)](https://docs.hyperdbg.org/commands/meta-commands/.switch)

[.kill (terminate the process)](https://docs.hyperdbg.org/commands/meta-commands/.kill)

[.pagein (bring the page into the RAM)](https://docs.hyperdbg.org/commands/meta-commands/.pagein)


# .restart (restart the process)

Description of the '.restart' command in HyperDbg.

### Command

> .restart

### Syntax

> .restart

### Description

Restarts a program (the previously started program using the '[.start](https://docs.hyperdbg.org/commands/meta-commands/.start)' command) with the specific parameters and breaks when the PE file reaches the entrypoint.

### Parameters

None

### Examples

Imagine we want to restart a program that we previously started using the '[.start](https://docs.hyperdbg.org/commands/meta-commands/.start)' command.

```
0: kHyperDbg> .restart 
```

### IOCTL

The IOCTL description is the same as the '[.start](https://docs.hyperdbg.org/commands/meta-commands/.start)' command.

### Remarks

This 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.

### Requirements

None

### Related

[.start (start a new process)](https://docs.hyperdbg.org/commands/meta-commands/.start)

[.attach (attach to a process)](https://docs.hyperdbg.org/commands/meta-commands/.attach)

[.detach (detach from the process)](https://docs.hyperdbg.org/commands/meta-commands/.detach)

[.switch (show the list and switch between active debugging threads)](https://docs.hyperdbg.org/commands/meta-commands/.switch)

[.kill (terminate the process)](https://docs.hyperdbg.org/commands/meta-commands/.kill)


# .attach (attach to a process)

Description of the '.attach' command in HyperDbg.

### Command

> .attach

### Syntax

> .attach \[pid ProcessId (hex)]

### Description

Attaches to a running program and pauses the target process. HyperDbg tries to intercept the threads running in **user mode** (not kernel mode) when you attach to the target process.

It means that you should keep interacting with the target process to get threads. When you run the first command to the target thread, intercepting threads will be ignored, and HyperDbg won't intercept new threads.

{% hint style="danger" %}
The user-mode debugger is still in the beta version and not stable. We decided to exclude it from this release and release it in future versions. If you want to test the user-mode debugger in **VMI Mode**, you should build HyperDbg with special instructions. Please follow the instruction [here](https://docs.hyperdbg.org/getting-started/build-and-install#activating-user-mode-debugger).

In contrast with the kernel debugger, the user debugger is still very basic and needs a lot of tests and improvements. We **highly recommend** not to run the user debugger in your bare metal system. Instead, run it on a [supported virtual machine](https://docs.hyperdbg.org/tips-and-tricks/nested-virtualization-environments/supported-virtual-machines) so you won't end up with a Blue Screen of Death (BSOD) in your primary device. Please keep reporting the issues to improve the user debugger.
{% endhint %}

{% hint style="info" %}
This command won't use any Windows API for intercepting and pausing threads, and everything is done at the hypervisor level.
{% endhint %}

### Parameters

**\[pid ProcessId (hex)]**

The target process id.

### Examples

Imagine we want to attach to a running program with process id equal to `12c0`.

```
HyperDbg> .attach pid 12c0
```

### IOCTL

This function works by calling **DeviceIoControl** with `IOCTL = IOCTL_DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS`. You have to send it in the following structure.

```c
typedef struct _DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS
{
    BOOLEAN                                              IsStartingNewProcess;
    UINT32                                               ProcessId;
    UINT32                                               ThreadId;
    BOOLEAN                                              Is32Bit;
    BOOLEAN                                              IsPaused; // used in switching to threads
    DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_TYPE Action;
    UINT32                                               CountOfActiveDebuggingThreadsAndProcesses; // used in showing the list of active threads/processes
    UINT64                                               Token;
    UINT64                                               Result;

} DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS, *PDEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS;
```

First, you should fill the **ProcessId** set the **IsStartingNewProcess** to `FALSE` and **Action** to `DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_ATTACH` in the above structure, when the IOCTL returns from the kernel, other parts are filled with appropriate data from the process.

After getting the results from the kernel and if the **Result** is equal to `DEBUGGER_OPERATION_WAS_SUCCESSFULL` the pausing phase of the process is started.

The **Action** can be from the following enum:

```
typedef enum _DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_TYPE
{
    DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_ATTACH,
    DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_DETACH,
    DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_REMOVE_HOOKS,
    DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_KILL_PROCESS,
    DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_PAUSE_PROCESS,
    DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_SWITCH_BY_PROCESS_OR_THREAD,
    DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_QUERY_COUNT_OF_ACTIVE_DEBUGGING_THREADS,

} DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_TYPE;
```

### Remarks

This command is logically designed to be used in [**VMI Mode**](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#vmi-mode). You can use the '[.process](https://docs.hyperdbg.org/commands/meta-commands/.process)' and the '[.thread](https://docs.hyperdbg.org/commands/meta-commands/.thread)' commands in [**Debugger Mode**](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#debugger-mode).

### Requirements

None

### Related

[.start (start a new process)](https://docs.hyperdbg.org/commands/meta-commands/.start)

[.restart (restart the process)](https://docs.hyperdbg.org/commands/meta-commands/.restart)

[.detach (detach from the process)](https://docs.hyperdbg.org/commands/meta-commands/.detach)

[.switch (show the list and switch between active debugging threads)](https://docs.hyperdbg.org/commands/meta-commands/.switch)

[.kill (terminate the process)](https://docs.hyperdbg.org/commands/meta-commands/.kill)


# .detach (detach from the process)

Description of the '.detach' command in HyperDbg.

### Command

> .detach

### Syntax

> .detach

### Description

Detaches from the currently active process.

### Parameters

None

### Examples

Imagine we want to detach from the currently active process (a previously started program using the '[.start](https://docs.hyperdbg.org/commands/meta-commands/.start)' command or a process attached by using the '.[attach](https://docs.hyperdbg.org/commands/meta-commands/.attach)' command).

```
1b08:1290 u64HyperDbg> .detach
```

### IOCTL

The IOCTL description is the same as the '[.start](https://docs.hyperdbg.org/commands/meta-commands/.start)' command, but instead of **Action**, you should send `DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_DETACH`, only set the **ProcessId** to the target Process ID.

### Remarks

If you want to detach from a process, the process must not be in a paused state. Thus, you should remove all the break events or continue the process before detaching from it. HyperDbg will automatically continue the target process before detaching.

This command is logically designed to be used in [**VMI Mode**](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#vmi-mode). You can use the '[.process](https://docs.hyperdbg.org/commands/meta-commands/.process)' and the '[.thread](https://docs.hyperdbg.org/commands/meta-commands/.thread)' commands in [**Debugger Mode**](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#debugger-mode).

### Requirements

None

### Related

[.start (start a new process)](https://docs.hyperdbg.org/commands/meta-commands/.start)

[.restart (restart the process)](https://docs.hyperdbg.org/commands/meta-commands/.restart)

[.attach (attach to a process)](https://docs.hyperdbg.org/commands/meta-commands/.attach)

[.switch (show the list and switch between active debugging threads)](https://docs.hyperdbg.org/commands/meta-commands/.switch)

[.kill (terminate the process)](https://docs.hyperdbg.org/commands/meta-commands/.kill)


# .switch (show the list and switch between active debugging processes)

Description of the '.switch' command in HyperDbg.

### Command

> .switch

### Syntax

> .switch
>
> .switch \[pid ProcessId (hex)]
>
> .switch \[tid ThreadId (hex)]

### Description

Shows a list of active debugging processes and threads or switches between different active debugging threads and processes. This command displays the list of intercepted threads that you can switch to these processes or threads. It **won't** show all of the threads of the target process.

{% hint style="success" %}
If you don't specify any parameters to this command, it shows the list of threads and processes.
{% endhint %}

{% hint style="info" %}
This command won't use any Windows API for intercepting and pausing threads, and everything is done at the hypervisor level.
{% endhint %}

### Parameters

**\[pid ProcessId (hex)]**

The target Process Id to switch.

**\[tid ThreadId (hex)]**

The target Thread Id to switch.

### Examples

The following command shows the list of active debugging threads/processes.

```
1b08:2050 u64HyperDbg> .switch
1a78 (process)
           2020 (thread) | # blkd exec attempts: 19a784
*1b08 (process)
           1380 (thread) | # blkd exec attempts: 207cac
           1ed4 (thread) | # blkd exec attempts: 2012c1
        -> 2050 (thread) | # blkd exec attempts: 1d788d
```

We'll use the following command to switch to thread id `0x2020`.

```
1b08:2050 u64HyperDbg> .switch tid 2020
switched to thread id: 2020
```

As you can see, the arrow in the list of active debugging threads is changed.

```
1a78:2020 u86HyperDbg> .switch
*1a78 (process)
        -> 2020 (thread) | # blkd exec attempts: 147b38
1b08 (process)
           1380 (thread) | # blkd exec attempts: 13a8e6
           1ed4 (thread) | # blkd exec attempts: 29d783
           2050 (thread) | # blkd exec attempts: 1ab7d6
```

It is also possible to switch by using process id.

```
1a78:428 u86HyperDbg> .switch pid 1b08
switched to process id: 1b08
```

Again, the active debugging process (thread) is changed.

```
1b08:1380 u64HyperDbg> .switch
1a78 (process)
           2020 (thread) | # blkd exec attempts: 11a224
           0428 (thread) | # blkd exec attempts: 19a51a
           0940 (thread) | # blkd exec attempts: 1136fa
           13e4 (thread) | # blkd exec attempts: 1d0144
*1b08 (process)
        -> 1380 (thread) | # blkd exec attempts: 5789a1
           1ed4 (thread) | # blkd exec attempts: 4582b4
           2050 (thread) | # blkd exec attempts: 5f61ab
```

### IOCTL

This function works by calling **DeviceIoControl** with `IOCTL = IOCTL_DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS`. You have to send it in the following structure.

```c
typedef struct _DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS
{
    BOOLEAN                                              IsStartingNewProcess;
    UINT32                                               ProcessId;
    UINT32                                               ThreadId;
    BOOLEAN                                              Is32Bit;
    BOOLEAN                                              IsPaused; // used in switching to threads
    DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_TYPE Action;
    UINT32                                               CountOfActiveDebuggingThreadsAndProcesses; // used in showing the list of active threads/processes
    UINT64                                               Token;
    UINT64                                               Result;

} DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS, *PDEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS;
```

First, you should set the **Action** to `DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_QUERY_COUNT_OF_ACTIVE_DEBUGGING_THREADS` in the above structure, when the IOCTL returns from the kernel, **CountOfActiveDebuggingThreadsAndProcesses** is filled with appropriate data from the process.

After getting the results from the kernel and if the **Result** is equal to `DEBUGGER_OPERATION_WAS_SUCCESSFULL` you should pass a new **IOCTL** to the kernel again.

The new IOCTL is equal to `IOCTL_GET_DETAIL_OF_ACTIVE_THREADS_AND_PROCESSES`. There is no need for the input buffer, but for the output buffer, you should allocate a memory with the size of the following structure multiplied by the count of threads/processes returned from the previous IOCTL.

```
typedef struct _USERMODE_DEBUGGING_THREAD_OR_PROCESS_STATE_DETAILS
{
    UINT32  ProcessId;
    UINT32  ThreadId;
    BOOLEAN IsProcess;

} USERMODE_DEBUGGING_THREAD_OR_PROCESS_STATE_DETAILS, *PUSERMODE_DEBUGGING_THREAD_OR_PROCESS_STATE_DETAILS;
```

The **Action** can be from the following enum:

```
typedef enum _DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_TYPE
{
    DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_ATTACH,
    DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_DETACH,
    DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_REMOVE_HOOKS,
    DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_KILL_PROCESS,
    DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_PAUSE_PROCESS,
    DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_SWITCH_BY_PROCESS_OR_THREAD,
    DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_QUERY_COUNT_OF_ACTIVE_DEBUGGING_THREADS,

} DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_TYPE;
```

### Remarks

The `blkd exec attempts` shows the number of times the operating system (e.g., Windows kernel) attempted to execute user-mode code in this thread (context is switched to this thread), and HyperDbg's user debugger blocked the execution of the user-mode code at the hypervisor level.

This command is logically designed to be used in [**VMI Mode**](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#vmi-mode). You can use the '[.process](https://docs.hyperdbg.org/commands/meta-commands/.process)' and the '[.thread](https://docs.hyperdbg.org/commands/meta-commands/.thread)' commands in [**Debugger Mode**](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#debugger-mode).

### Requirements

None

### Related

[.start (start a new process)](https://docs.hyperdbg.org/commands/meta-commands/.start)

[.restart (restart the process)](https://docs.hyperdbg.org/commands/meta-commands/.restart)

[.attach (attach to a process)](https://docs.hyperdbg.org/commands/meta-commands/.attach)

[.detach (detach from the process)](https://docs.hyperdbg.org/commands/meta-commands/.detach)

[.kill (terminate the process)](https://docs.hyperdbg.org/commands/meta-commands/.kill)




---

[Next Page](/llms-full.txt/1)

