Architecture of x64dbg

x64dbg has a complex architecture. There are three basic parts, namely DBG, BRIDGE and GUI, but in fact there is a fourth part, EXE. This is the main executable, it compiles into x64dbg.exe.

architecture diagram

Bootstrapping

When the user starts x64dbg, it will follow this initialization path to get x64dbg running:

Debugging

To start debugging, the GUI sends an init command to the DBG. Then the following things start:

Message passing from GUI to DBG

There are four methods to call DBG from GUI. They are commands, directly exported functions, bridge exported functions (messages) and DbgFunctions(). Currently the directly exported functions are frozen and no new ones should be added. The message flows for each way will be described below.

Commands dispatch

DbgCmdExec is relayed by the bridge to the DBG and eventually received by the cmdloop running in the command thread. This is done asynchronously (meaning DbgCmdExec will not wait until the command is completed).

DbgCmdExecDirect is relayed by the bridge to DBG and then directly in cmddirectexec. This will only return after the command is completed.

In both cases the command is parsed and dispatched to various registered command callbacks. A command callback is similar to main() functions. It can receive number of arguments (plus one), and pointer to every argument string.

Commands are registered in the registercommands function. If you want to get a total list of supported commands, or add your own, just go to that file. Make sure to put your command in the correct category and also make sure to add it to the documentation.

Directly exported functions

There are some legacy functions still unconverted to another method, these can be found in exports.h.

Export functions dispatch

Many Dbg*** functions are exported by the bridge. It then calls _dbg_sendmessage exported by DBG to pass information. Some Dbg*** functions have exports directly in DBG.

DbgFunctions

_dbgfunctions.cpp has a function table that is accessible by anyone. The GUI can call functions in DBG through this table directly.

Message flow from DBG to GUI

There are various Gui*** functions exported by the bridge. The control flow is described below:

Important subsystems in GUI

Tables in GUI

There is three-level class architecture to support various tables. The first-level class is AbstractTableView, which only includes some basic functions. The second-level classes are Disassembly, HexDump and StdTable. They all inherit from AbstractTableView. Many basic and common functions are defined here, such as table painting, selection, content presentation and column reordering. The third-level classes inherit from the second-level classes. There are many third-level classes. The most common parent for these tables is StdTable.

Context menu management

There are two styles of context menu management. The traditional one builds actions in setupContextMenu and adds them into a menu object in contextMenuEvent. CPUStack uses this style currently. A newer way to manage context menu is to use MenuBuilder. You can see CPUDisassembly or this blog post for more details. It is the preferred way to manage context menu in newer tables, but it does not support non-table widgets out of the box. We want to convert traditional context menu systems into MenuBuilder to speed up development.

Configuration management

Configurations are stored in the Config() object which uses Utf8Ini in the bridge as its backend. When you want to add a new configuration, you have to modify the following files: Configuration.cpp and the SettingsDialog. If you are adding a color then you have to modify the AppearanceDialog as well. Config() can emit settings change signals.

Important subsystems in DBG

There are many subsystems in DBG. The following subsystems are important if you want to contribute:

threading.h

It includes various locks to prevent race condition. Without it, x64dbg will crash much more often. Don’t forget to acquire the lock when you are accessing a subsystem.

x64dbg.cpp

It registers all commands in x64dbg. The details of command processing is described above.

memory.h , module.h and thread.h, label.h and breakpoint.h, etc

They manages corresponding information of the debuggee.

scriptapi

It is intended to be used by plugins. It provides easy scripting experience for developers. x64dbg does not call any of these functions.

Comments