X64dbg
Содержание:
Disassembly speed improvements
There has been quite a big improvement in disassembly and overall GUI speed. The disassembly would reload itself three times, effectively disassembling every visible instruction six times. This has now been reduced to disassembling once. Additionally the GUI would be force-refreshed unnecessarily which should now also be fixed. If you encounter any issues with this, please report an issue. Scrolling in the current view will always force-refresh it.
Reports
- Issue #1188 by cxj98 fixed in 15 minutes;
- Private report, already fixed;
- Found another bug myself and double-verified it should be fully fixed now sorry for the hassle!
- Yet another report, also fixed;
WinProc Conditional Breakpoints
The last thing to get this feature fully working is the possibility to pause the application only when specifics handles and messages are in play. As you can read in the help, x64dbg integrates a very nice and powerful set of expressions to allow this. As shown in the above picture there are three options involved:
- Break on any window: Using this option we stop on the given message regardless the window handle. For this we need the simplest expression:
- Break on current window only: This feature will add an additional condition to the expression in order to stop the execution only when the handle of the specific window is involved, the expression in this case would be:
- Use TranslateMessage: Sometimes the winproc technique will not give the expected results so this other feature goes out of the scope of the previous technique as it relies in the TranslateMessage API to intercept messages and not in the window procedures themselves. Althought the logic is more or less the same.
As seen the function uses the same structure that we saw before, hence the functioning with the expressions will be more of the same with some minor changes depending on the OS platform:
Basic functionality
As I said before, this plugin took as base code to APIInfo, so most of its core functionality is from mrfearless’ code. Apart from that, I wanted to go a little bit further than just make a translation of his code into C++ and so I came up with something more like the kind of features I wanted before. The process of creating your own plugins for x64dbg is explained here and even the documentation and plugin templates for Visual Studio and other several compilers have been created, so I don’t pretend to cover all of that in this post.
Anyway, the functioning of the plugin is pretty straightforward. In the image below it’s found a flowchart of its main backbone functions.

The plugin starts by launching some of the internal analysis algorithms of x64dbg, such as: cfanal, exanal, analx, analadv or anal. Soon after that it goes into API call analysis. The plugin gets the start and end address of the section in which the current is, this in order to loop and make the analysis overall these bytes. For processing each instruction the plugin uses function which has the following definition:
All the values we need are present in the returned structure. In case of calls found, the plugin makes some checks to try to include as many scenarios as it can. Some of these different schemes are:
CALL -> JMP -> API (Indirect Call)


CALL -> POINTER -> API (Indirect Call)


CALL -> API (Direct Call)

The plugin creates and emulates a stack for saving all of the possible functions arguments. These instructions are filtered in the function . The code depends on the platform, for x86 an argument would be any instruction, except for , , , . Once a valid argument is found is saved to the global stack container.
On the other hand x64 platforms differ in this point, so to find if an instruction is a valid candidate it would have to be any of the instructions , , , , . But an additional check has to be made since x64 doesn’t use instructions anymore. The x64 platform uses the registers , , , for a four argument function, including floating points registers , , , and for the rest of arguments it uses the stack . So the check consist of checking if these instructions have any of those, including 32, 16 and 8 bits variants. The stack would be cleared if a function prolog or epilog is found as well as jumps (no jumps among arguments) and internal subs.
Finally, the key is that when a call is found, it will traverse the stack to find the valid arguments for it. Here once again x64 brings some differences to the table, as for the x64 functions calls arguments might have been saved to the registers or stack without any specific order, going against the function arguments definition order. Another hack had to be made, in this case, x64 depends on the registers order as the arguments order, so the scheme would be:
- First argument of the function;
- Second argument of the function;
- Third argument of the function;
- Fourth argument of the function;
- The rest of the arguments of the function including floating points registers XMM0, XMM1, XMM2, XMM3.
With that in consideration, the rest is easy. Taking the same path of APIInfo plugin, xAnalyzer has a folder which should contain all the API definition files as with the following structure:
This is the name of the module on which the API function is located with extension (kernel32.api, shell32.api, etc)
A single entry in any of these files would be like:
In this case, all of these definition files may be customized and populated by each user following the same shown pattern. If you find that a certain API call definition is not being detected by xAnalyzer it might mean that it’s not present in the definition files, so in this case an addition could be made to include any missing function.
To set the API function name comment, as well as its arguments, the plugin read over the definition files to get the correct data. Finally it also uses some of the functions in the SDK of x64dbg such as: , , and to set up the visual aid for the current executable function.
As for now, x64dbg doesn’t allow nested function arguments, even though xAnalyzer does, definition is going to be present, while arguments brackets won’t. xAnalyzer has been made compatible with 64 bits binaries in the latest release and even a couple more features are also coming soon.
And this is all for this post, xAnalyzer x64dbg plugin exposed. For latest relases, info, issues, etc go to the project page.
Work on GleeBug
GleeBug is the planned new debug engine for x64dbg. During the holidays there has been quite a bit of work with regards to memory breakpoints. See the commit log for in-depth information.
GleeBug has been in development for about 1.5 years now. It can currently replace TitanEngine for x64dbg (giving massive performance improvements), but not all features are implemented yet. The main blockers are currently:
- Memory breakpoints
- Extended (XMM, YMM) register support
- Breakpoint memory transparency
For reference, when tracing with TitanEngine, the events/s counter is around 250. When tracing with GleeBug, this counter comes near 30000 events/s in some cases!

InterObfu
An ongoing effort basically sucking all my time has been on a project called InterObfu. It is basically a representation of x86 instructions that allows you to transform instructions. It also allows for extensive wildcard matching of instructions.
The obvious usage is finding a sequence of wildcard instructions in x64dbg, but another application is peephole optimization (for deobfuscation-related applications). The screenshot below shows the progress of various patterns being replaced or removed.

The implementation was particularly interesting because it involves Aho-Corasick and various tricks to make it efficient. You can check out the code on the if you’re interested. Shout out to Matteo for support and discussion on the topic!
Going back
Like a year ago I started having my first contact with x64dbg and due to the simplicity and similarities with my first debugger (OllyDbg I began using it for some debugging sessions, but as an Olly user I couldn’t resist to start missing some of the features that Oleh’s debugger had, and I’m referring in this case to the extra analysis OllyDbg does over API functions calls and their arguments and values. I opened an issue in the project page asking for such a feature.
At the time of opening, the development team and collaborators were not able to get into it, instead I was given a couple choices like APIInfo by mrfearless, and I even found another one StaticAnalysis written by tr4ceflow. Both of them were very close to what I wanted, but still they didn’t fulfil all of my cravings. Like a month ago I came back to x64dbg community just to see how improved the debugger was from my last contact with it and this made me gain some interest in developing and collaborating with the project, and so xAnalyzer came in.
Intercepting Messages
Now that the window procedure is located, any message could be intercepted with a proper conditional expression, but before that, let us check the logic behind this. The structure being processed each time by the window procedure looks like this:
As we can see the structure give us some useful information at this point, most importantly and . According to these fields we could know to which specific control what message is being sent to. Before going any further let us see an example for an specific message () being sent to a given control.

After clicking the OK button we step on the breakpoint and when we inspect the stack arguments we can see something like this

The first as can be seen is the handle corresponding to our control and the second corresponding to the message (0x202).
Offer to show the most needed data to user
We are always complaining the screen being too small to show the entire program and data. Protected programs tend to access non-local data and execute large routines. It is often the case that only a small portion of the screen is displaying useful things, and most of the program’s important states, are hidden in the remote part of memory not shown on the screen. To enlarge the sight of the user, I have introduced many features that can display a non-continuous range of memory, such as watch view, code folding, and recently introduced branch destination previewing. When used properly, they can help concentrate useful information together on the same screen, despite being separated by a large gap in address.
However, there is another thing that makes branch destination preview more success. It displays on mouse over, not on a context menu event. In this way, the tooltip will automatically appear as soon as the user is interested on a particular call instruction. By offering to show the most needed data to user, we save a lot of mouse clicks and keyboard actions. Without branch destination preview, the user would press “Enter”, and have a glimpse at the disassembly, then press “-“ or “*” to go back to the current location. It is far more complicated and less convenient than mouse over. Also, I provided an option to disable it.
By contrast, code folding requires the user to select a range and then click on the checkbox. Code folding has cost me more effort to implement than branch destination preview, but it is less useful. I don’t know how often you fold a section of disassembly, but I think many of you will seldom use it. Duncan added an ability to fold the entire function more easily, but I think that is very misleading (see the comment on #829) and misses the principle 3. That can probably lead to a further decreased usage of code folding. The proper usage of code folding is in a large loop with lots of unexecuted branches. By folding these inactive branches, you can display more active instructions on screen, thus gain a better overview of the operation of the large loop.
Of course, to implement these features, we have to make lots of non-standard controls. That requires quite an effort. But for better user satisfaction, we are continuously working.
DllMain
is the entry point into a dynamic link library, and is optional for each dll file to have one. The plugins, being dll files, can make use of this function by storing the value for later use in other api calls. The code required for creating a DllMain function is relatively straightforward.
Ive included an example of defining the DllMain using C++ (for both 32bit and 64bit), Masm32 for x86 assembly and JWasm / HJWasm for the x64 assembly.
C++:
Assembler x86:
Assembler x64:
Fairly simple for each example, and minimal changes for the 64bit assembler version vs the 32bit, mainly the use of the register instead of .
Apart from all the plugin functions (except from your own internal functions) are required to be exported for the plugin to work.
An exported function is one that has been declared as accessible externally for other external callers to make use of. is ‘seen’ and automatically handled by the operating system when loading a dynamic link library, so we aren’t required to explicitly export it, but the , , and any other callback functions are required to be exported.
Types
There has been quite a lot of progress on the type system in the last few months, but it has now (sort of) come together and you can really start using it. Currently you can get types in the following ways:
- Add them with commands;
- Load them from ;
- Load simple C++ .
If you want to show a structure (as seen below) you first have to load/parse the types and then you can ‘visit’ the type with an (optional) address to lay it over linear memory. Pointers are supported but the VisitType command has to be used with an explicit pointer depth to expand pointers.

This took all my time for the week, which is why this post is very short. The technical details are interesting though. The built-in type system has no/limited support for dynamic types (variable array sizes are not supported). This was needed to keep the structures simple and get started quickly. The GUI however is designed to be more generic and the API is much simpler.
You can directly build the tree and a callback is provided to convert a to a string value to display, which allows for great flexibility. Some possible use cases would be:
- Parse types with clang and show them in the GUI;
- Support Binary Templates;
- Support Kaitai Struct.
In the future I want to add often-used types to a database and ship that with x64dbg. There will (eventually) be a blogpost describing everything in detail, but if you are interested you should come and talk to me on Telegram.
The pluginit exported function
is the first exported function that x64dbg calls after loading the dynamic link libraries ( or ), if isn’t present then the loading of the plugin will fail at this point.
passes a pointer to a structure as the only parameter in the function: . This structure is used to register the plugin with x64dbg and for obtaining a valid plugin handle which is used in future api calls.
The definition for this structure is:
C++:
Assembler x86 and x64:
So we must place valid information back into this structure for x64dbg to validate and recognise our plugin. A number of defines can be used to provide the information required by the structure’s fields: ( — defined by user) and ( — predefined in the SDK — version of the SDK that x64dbg expects). The is a string buffer that contains the name of your plugin. The field is provided to us as a handle that we can save and re-use in future api calls.
Of course we need to declare some of the variables and strings used to pass this information back via the structure, and to store information returned to us ( in and other handles in the call later on). Here’s how to define them:
C++:
Assembler x86:
Assembler x64:
Now that we have setup our variables and strings we are ready to construct our function. Below is a couple of examples of in C++ (for both 32bit and 64bit), Masm32 for x86 assembly and JWasm / HJWasm for the x64 assembly.
C++:
Assembler x86:
Assembler x64:
The coding for each example is simple and again we see minimal changes for the 64bit assembler version vs the 32bit.
In assembler (x86 and x64) you must also add your exported functions to a .def file for them to be visible to external callers when compiling and linking:
Allow permanent highlighting mode
Some people prefer the way IDA handles highlighting. Clicking on a register/immediate will highlight it everywhere else, even if you want to keep the previous highlighting but want to click somewhere else. I personally think this is a bad way of handling highlighting, but an option has been introduced that has similar behaviour. Pull request #1388 had similar functionality, but I rewrote it to be optional and more intuitive.
If you don’t click on a highlightable object it will not change the highlighting so (unlike IDA) you can do your normal operations while keeping the desired highlighting.
Use watch window
When debugging a loop, you might first animate through the loop a few times while watching the registers carefully, and then focus on a particular piece of code where value of interest is in the register. But when the variable is stored in memory, it will have less chance to be noticed. A better way to do it is by using a watch view. You can add the variables in the watch view. In this way you can get informed of all the changes happening on the variable. An additional benefit is that a pointer will appear in the side bar if the variable is pointing to code section. You can easily understand the process of unpacking this way.
TaskThread
For interaction with the GUI, performance is very important. For this purpose jdavidberger has implemented TaskThread. It’s some variadic templates that basically allow you to trigger an arbitrary function from a different thread to then quickly return to the real work.
The actual thread runs in an infinite loop, waiting for the instance to receive a (trigger). Once awake, the specified function is executed and after that the thread is being delayed for a configurable amount of time. This ignores all triggers (except the last one) within the delay time to avoid unnecessary work.
The relevant code:
As an example, here is the declaration and wake of the thread that updates the call stack (an expensive operation in some cases):
Having a different thread handle expensive operations is critial to a responsive interface. Lots of information is rarely looked at (memory map, call stack, SEH information) and can suffer a little delay (100ms) before being updated. This is the same with the current state of the disassembly. When holding F7 to quickly step a little you don’t need perfect accuracy, as long as the disassembly lands on the correct state within reasonable time after releasing the step button.
Reflection
Over the last three weeks there has been lots of instability going on, mostly related to . I expected around a week of instability, but unfortunately people keep finding issues and I cannot say with certainty that all bugs are gone.
The main reason for this being such an issue is that during initial development of the GUI a convenient function called was introduced. This function will call the ‘force refresh’ functions of all individual views (disassembly, dump, stack, registers, sidebar, infobox, arguments, breakpoints, graph, call stack, memory map, etc.). Currently this function is no longer called in performance-critical code (such as the function responsible for updating the GUI to represent the current context) and many implicit update calls now have to be converted to explicit ones, which is a very prone to errors.
Testing all the features every time something changed is extremely time-consuming, which is why x64dbg relies on users willing to be on the bleeding edge to find issues like this. I would like to thank all of you!
Introduction
Have you ever been trying to reverse a specific function in an application, but cannot really find it? For instance, let us assume you want to locate the code that is being called right after a click on a button or a keystroke. With certain applications (Delphi, CBuilder, Visual Basic, etc) it is as easy as dropping the executable inside a decompiler and locating the corresponding events/addresses in a matter of seconds. Sometimes it is not that easy, whether a packer or anti-decompiler technique is involved, or just for the simple reason that the application is not an event-driven one. What can you do in that case to obtain those addresses in a similar approach with the least effort?
Faking the kernel imports
To fake the and exports I wrote a small tool in C#. It expects a module name and a CFF Explorer export table (Ctrl+A, Ctrl+C) as input:
After running this tool, you will get fltmgr.cpp and fltmgr.def, which can be added to an empty DLL in Visual Studio and then compiled to a DLL with fake exports, which perfectly match the ones from your desired driver. You can find the complete source code here, the relevant binaries can be found in the releases.
As a final step, extract the fake and to the same directory as . Loading the file in x64dbg and running to the entry point should look like this:

I got a tweet that linked to an alternative library (with more emulated functions) that you can use.
How this affected the x96dbg.exe loader
In the x64dbg package, a loader is provided as a convenience to the user in order to support Right-Click Context Menu debugging of applications and Desktop shortcuts. However up until recent commits and proper handling of redirection was not present. More information about this issue can be read here in Issue #899.
Due to the fact that x96dbg.exe is a 32-bit application, when a Right Click context menu is invoked to debug a 64-bit application in the System directory, File System Redirection will automatically provide it with the 32-bit version of the application.
This redirection in fact affects the function :
The call to will invoke the FS Redirector and if the file requested is a system resource and is a 64-bit application with an equivalent 32-bit version, Windows will return the 32-bit version of that application. So debugging notepad.exe in will become debugging notepad.exe in which is not what was intended.
Using Windows Messages
Let us take a look at a sample crackme for demonstration purposes. In this case we have a simple executable coded in Visual C++:
If we try to enter a text and click on the button nothing is happening, not a text message, no nothing. At this point we could get creative and start looking for other alternatives to locate the exact location where our serial is processed and yes, we would probably succeed, but what if I tell you that there is an easier way for us to land just after the press of that button? Just like we would with any Delphi, Visual Basic or any other event-driven language? Let us find out how it works.
After loading and executing the file in x64dbg, we go and enter some text and just before pressing the button we go to the tab and refresh the view to obtain a window list of the debuggee. We can then see the button there so we right click over it and select the option to set a message breakpoint on it:

Now we are given a window with some options to choose from in order to set a specific message breakpoint in our button control. In this case the configuration I am going to use is something like this:
We are specifying that the execution is stopping as soon as a (left mouse click is up) message is sent to our button control. Right after our breakpoint is set we click the button in the crackme and soon after that we step in our breakpoint.
At this point we achieved what we wanted. We just stopped the execution right after the button click, on the other hand we are in and our purpose is to be in the main module code. Getting there is as simple as just using a breakpoint in the code section of our executable. You can also use the option (Ctrl+F9).

When trying to resume the execution, the debugger is going to stop the execution once again, but this time right in the middle of the code we were looking for. In this case in the function (the callback in charge of processing the messages being sent to every window control in the main window dialog).

The Fix
Luckily for us, Microsoft provides an easy way to bypass the default behavior of File System Redirection. The fix applied to the x96dbg.exe loader is one function that determines whether FS Redirection is supported, and a structure that facilitates disabling this and re-enabling it once done.
Two conditions need to be met before we can determine whether FS Redirection can be disabled:
- Are we running under WoW64 context? (Meaning is this a 32bit application running under 64-bit Windows) and
- Does this OS support File System Redirection?
Checking for FS Redirection is a simple matter of seeing if the pertinent functions are available:
The structure that encapsulates the calls to these functions is defined like so:
Once we’ve determined that our conditions for FS redirection are met, we can disable it using a simple call to the member function . This must be invoked before we attempt to determine the files architecture and this can be seen here at
With these changes, x96dbg.exe can now properly allow a user to Debug redirected 64-bit applications as intended.
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
is relayed by the bridge to the DBG and eventually received by the running in the command thread. This is done asynchronously (meaning DbgCmdExec will not wait until the command is completed).
is relayed by the bridge to DBG and then directly in . 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 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.
Export functions dispatch
Many Dbg*** functions are exported by the bridge. It then calls exported by DBG to pass information. Some Dbg*** functions have exports directly in DBG.
Understanding the x64dbg plugin architecture
The plugin files for x64dbg, are files that end with the or extension. These correspond to the processor architecture used in each version of x64dbg — 32bit and 64bit. In reality these plugin files ( for 32bit x32dbg and for 64bit x64dbg) are just simple dynamic link libraries ( files).
Each plugin file has to export a number of functions for it to be recognised as a valid and usable plugin. These are:
- — The entry point into the dynamic link library.
- — Starts the initial plugin interface with x64dbg.
and optionally:
- — Provides menu handles to the plugin.
- — For when we are exiting from our plugin (when x64dbg closes down)
- — Optionally a number of callback functions, defined in the plugin SDK and exported by x64dbg for use with plugins — which we will explain further below.
Technically only and are required at a minimum, but it is considered a good practise to include to allow for cleanup of your plugins code, should it be required, and for obtaining menu handles if your plugin will be creating its own menu items.
Use Cases
As seen in this post, this is a very convenient and strong feature in x64dbg and can be used in numerous scenarios. Having the possibility to control on which events to pause a debuggee, even if it is not and event-driven application like a Delphi or Visual Basic, open the doors and give the reverser even more resources to debug. If you want to pause the execution when entering a char in an Edit control in a MASM application just set a messages breakpoint on the control itself with the message WM_KEYUP, simple as that. Same goes for Button clicks, showing windows, etc. There are a whole bunch of messages options to choose from.
Access to features
As mentioned earlier, x64dbg doesn’t support many features in references view. It is because, unlike other views, references view is multi-purposed. The references view can be used as labels view, search result view, or variables view. Because the code in references view doesn’t have the code to do specific task in given context, tasks such as updating automatically can’t be done.
A more general problem exists in other views. In info box below disassembly view, you can see many features are missing, for example, follow in specified dump window. Although the code to accomplish this task already exists, info box has not been updated to use it.
The problem of mixing code for features and container views in the same class has resulted in much code duplication and lack of features in certain views. To solve the problem, x64dbg is moving feature menus into dedicated class files. BreakpointMenu class is the first successful attempt that not only simplifies code, but also brings hardware breakpoint features to other views.
A proposed enhancement to references view is to let code in references view have more insight of current context. I added GuiReferenceAddCommand function to references view. First tried in main window, this function can add a context menu in references view to execute a common task, such as deleting labels. If references view has further information about its context, more tasks can certainly be done. If this information is made visible to all other views in a standard interface, it can be possible to implement tasks that require interaction of references view in other views, such as go to next match. Of course, this will indicate a new enhancement in x64dbg architecture and therefore must be considered carefully.