Igor’s Tip of the Week #138: Pointer math in the decompiler

While working with decompiled code and retyping variables (or sometimes when they get typed by the decompiler automatically), you might be puzzled by the discrepancies between pseudocode and disassembly.

Consider the following example:

We see that X22 is accessed with offset 0x10 (16) in the disassembly but 2 in the pseudocode. Is there a bug in the decompiler?

In fact, there is no bug. The difference is explained by the C/C++pointer/array referencing rules: the array indexing operation advances the pointer value by value of index multiplied by the element size. In this case, the type of v4 is _QWORD* which means that elements are _QWORDs (64-bit or 8-byte integers). Thus, 2*8=16(0x10) which matches the assembly code.

To confirm what’s really going on, you can do “Reset pointer type” on the variable so that it reverts to the generic integer variable and the decompiler is forced to use raw byte offsets:

See also:

Igor’s Tip of the Week #117: Reset pointer type

Igor’s tip of the week #42: Renaming and retyping in the decompiler

Igor’s Tip of the Week #118: Structure creation in the decompiler

Article Link: Igor’s Tip of the Week #138: Pointer math in the decompiler – Hex Rays