Plugin focus: ComIDA

This is a guest entry written by the Airbus CERT team. Their views and opinions are their own and not those of Hex-Rays. Any technical or maintenance issues regarding the code herein should be directed to the authors.

The ComIDA plugin is focused on finding usage of COM objects inside Windows modules. When a COM object is identified, ComIDA will infer its type to improve the decompilation.

What’s COM?

COM, for Component Object Model, is a powerful client-server model created by Microsoft to easily share features between Windows modules. It is based on a dedicated Hive where server components can register interfaces (objects with methods). Then the client will use the CoCreateInstance, CoGetCallContext, QueryInterface Windows API to retrieve a pointer to the server interface, to use it inside the client code.

It is massively used by many Windows core modules, and very often by malicious code to interact with Windows systems.

ComIDA will list all COM objects

A server component is identified by a unique identifier (GUID). This GUID will be used by the client through the COM API (CoCreateInstance, CoGetCallContext, QueryInterface) to load the appropriate component. This GUID is known at compile time, which is processed as a direct operand value.

ComIDA will get all direct operand values, interpret it as GUID and interact with the HKEY_CLASSES_ROOT hive to check if it corresponds to a well-known COM GUID. If a match is found, it will be listed in the output view, with additional information like where the reference was found, as well as the name and the server module which registered this instance.

You can interactively double click on each match to go directly to the reference:

ComIDA will infer your type

The other feature of ComIDA is, for owners of the Hex-Rays plugin, to automatically infer the type of the output variable from the CoCreateInstance and CoGetCallContext functions, or the QueryInterface method.

This method has a known signature. For example:

HRESULT CoCreateInstance( [in] REFCLSID rclsid, [in] LPUNKNOWN pUnkOuter, [in] DWORD dwClsContext, [in] REFIID riid, [out] LPVOID *ppv );

The 4th argument is the COM GUID of the instance built into the 5th argument.

The variable ppv has a IShellLinkW type, which we can guess from the IShellLinkW GUID in riid. This is exactly what ComIDA do: it will use the Hex-Rays decompiler hook API to automatically set the type of the ppv variable, and lets the Hex-Rays plugin do its magic:

In this example there are two inferred variables, one coming from CoCreateInstance, ppv, and the second coming from the QueryInterface method, v5.

The ComIDA IDA is available on GitHub: https://github.com/airbus-cert/comida