We’ve covered the usage of symbolic constants (enums) in the disassembly. but they are also useful in the pseudocode view.
If a number has been converted to a symbolic constant in the disassembly and it is present in unchanged form in pseudocode, the decompiler will use it in the output. For example, consider this call:
.text:00405D72 push 1 ; nShowCmd .text:00405D74 cmovnb eax, [esp+114h+lpParameters] .text:00405D79 push 0 ; lpDirectory .text:00405D7B push eax ; lpParameters .text:00405D7C push offset File ; "explorer.exe" .text:00405D81 push 0 ; lpOperation .text:00405D83 push 0 ; hwnd .text:00405D85 call ShellExecuteW
Initially, it is decompiled like this:
ShellExecuteW(0, 0, L"explorer.exe", v136, 0, 1);
However, we can look up that nShowCmd’s value 1 corresponds to the constant SW_NORMAL
, and apply it to the disassembly:
After refreshing the pseudocode, the constant appears there as well:
ShellExecuteW(0, 0, L"explorer.exe", v136, 0, SW_NORMAL);
In fact, you can do the same directly in the pseudocode, using the context menu or the same shortcut (M):
Note that there is no automatic propagation of the constants applied in pseudocode to disassembly. In fact, sometines it’s not possible to map a number you see in the pseudocode to the same number in the disassembly.
Consider this example from a Windows driver’s initialization routine (DriverEntry
):
We know that indexes into the MajorFunction array correspond to the major IRP codes (IRP_MJ_xxx
), so we can convert numerical indexes to the corresponding constants:
and the pseudocode becomes:
DriverObject->DriverStartIo = (PDRIVER_STARTIO)sub_1C0001840; DriverObject->DriverUnload = (PDRIVER_UNLOAD)sub_1C0001910; DriverObject->MajorFunction[IRP_MJ_CREATE] = (PDRIVER_DISPATCH)&sub_1C0001510; DriverObject->MajorFunction[IRP_MJ_CLOSE] = (PDRIVER_DISPATCH)&sub_1C00011B0; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = (PDRIVER_DISPATCH)&sub_1C0001290; DriverObject->MajorFunction[IRP_MJ_CLEANUP] = (PDRIVER_DISPATCH)&sub_1C0001070;
However, if we check the corresponding disassembly (e.g by using Tab or synchronizing pseudocode and IDA View), we can see that the array indexes are not present as such in the instruction operands:
Another common situation where you can use symbolic constants in pseudocode but not disassembly is swich cases.
See also:
Igor’s tip of the week #99: Enums
Decompiler Manual: Hex-Rays interactive operation: Set Number Representation