Hex-Rays' blog

Plugin focus: Symless – Hex Rays

Written by Alex Petrov | Nov 20, 2023

This is a guest entry written by Baptiste Verstraeten from the Thalium Team. His views and opinions are his own and not those of Hex-Rays. Any technical or maintenance issues regarding the code herein should be directed to the author.

The Symless plugin aims to simplify the process of retrieving and defining structures, classes, and virtual tables. Building structures with their fields and managing cross-references is an unavoidable task when reversing a binary that often proves to be very time-consuming. As we will show below, Symless allows automating a large part of this process.

Building a structure

When looking at a piece of code, the analyst may find a new structure being used. IDA has a create new struct type feature in its decompiler view that can be used to recreate the structure in a few clicks. Symless offers an enhanced version of this vanilla feature.

It is presented in the form of a new "propagate structure" shortcut in the register submenu of the disassembly view (accessible via a right-click on a register). Using it on a register containing a reference to our new structure allows us to build it, as illustrated in the following screenshot:

Here, we want to create the CElement class being used in the CElement::GetMarkupPtr class method. We use our "propagate structure" feature on the first use of the rcx register (referencing our structure) to start Symless static analysis from this point. In the displayed popup, a "build new" tab allows to create a new named structure. Two options are available:

  • shifted by: in case rcx contains a shifted structure pointer, specify the shift amount.
  • spread in callees: continue static analysis, and thus structure building, in callees that are given the structure as parameter

Hitting the propagate button starts the analysis. Once completed, the result is as follows:

A basic structural backbone is built using the fields found to be used in the analyzed code. The enhancements from a structure built with the vanilla feature are the following:

  • Accesses made to the structure's fields are typed in the disassembly.
  • Cross-references are placed in the structure, allowing to track the usage of each field.
  • The analysis is not restricted to the current function (by default), fields used in callees are also retrieved.

After defining the structure, the responsibility of assigning meaning to each identified field (by naming and specifying their types) falls upon the analyst.

Completing an existing structure

Adding fields to an existing structure requires frequent navigation between the code view and the structure panel. Symless' goal is to allow the user to complete their structures from the code view.

In the preceding example, we built an incomplete CElement structure from the CElement::GetMarkupPtr function, which only uses two fields from CElement. It is possible to apply Symless on other code samples using CElement to complete this structure.

The best way to rebuild a class is to analyze its constructor (here CElement::CElement), which initializes most of the class fields. The following screenshot illustrates how to start the analysis in CElement::CElement:

In Symless structure builder window, the "from existing" tab enables the selection of a structure for propagation and completion with the gathered information. Once the analysis is completed, the CElement structure looks like this:

We observe that the majority of 'CElement' fields have been successfully retrieved. Existing fields remained unchanged. Symless aims to avoid disruption of existing compositions and user modifications, whenever possible.

Retrieving virtual tables

Symless is also able to identify virtual tables. In the last example, the first field of CElement was typed with the class virtual table (i.e. CElement_vtbl). This virtual table was recreated by Symless and cross-references were added to the virtual methods. This is particularly useful for determining where a specific method is used or for resolving indirect calls.

Symless analysis is automatically applied to the identified virtual methods as well. This enables more cross-references within our structure and provides a deeper understanding of its composition.

Conclusion

Symless offers a more advanced approach to reconstructing structures through static code analysis. It automates various tasks that users typically perform, including defining fields, setting cross-references, and retrieving virtual tables.

The interactive plugin still requires the analyst to specify the location of a structure being used. An automatic version is also available, capable of retrieving multiple structures and classes without any user interaction. More information about this automatic analysis is available in the project’s README.

The Symless plugin is available on Github: https://github.com/thalium/symless