NOTE: these are just some selected examples that can be illustrated as side-by-side differences. There are many other improvements and new features that are not mentioned on this page.
Magic divisions in 64-bit code
In the past the Decompiler was able to recognize magic divisions in 32-bit code. We now support magic divisions in 64-bit code too.
Please note that the code on the left is completely illegible; the assembler code is probably easier to work with in this case.
However, the code on the right is very neat.
JFYI, below is the class hierarchy for this example:
The new version knows about ObjC blocks and can represent them correctly in the output. See Edit, Other, Objective-C submenu in IDA, it contains the necessary actions to analyze the blocks.
Yet another optimization rule that lifts common code from 'if' branches. We made it even more aggressive.
mywcscpy();if ( a3 <0 ) v4 =-a3;
if ( a3 >=0 ){mywcscpy();}else{mywcscpy(); v4 = -a3;}
Added forced stack variables
Sometimes compilers reuse the same stack slot for different purposes. Many our users asked us to add a feature to handle this situation. The new decompiler addresses this issue by adding a command to force creation of a new variable at the specified point. Currently we support only aliasable stack variables because this is the most common case.
In the sample above the slot of the p_data_format variable is reused. Initially it holds a pointer to an integer (data_format) and then it holds a simple integer (errcode). Previous versions of the decompiler could not handle this situation nicely and the output would necessarily have casts and quite difficult to read. The two different uses of the slot would be represented just by one variable. You can see it in the left listing.
The new version produces clean code and displays two variables. Naturally it happens after applying the force new variable command.
data_format =*p_data_format;if ( *p_data_format <0|| data_format >13 ) { errcode =2;SetError(&this->status,&errcode,"format not one of accepted types"); }
data_format =*p_data_format;if ( *p_data_format <0 || data_format >13 ){ p_data_format = (int*)2;SetError(&this->status, (errcode_t *)&p_data_format, "format not one of accepted types");}
Added support for virtual calls
Well, these listings require no comments, the new version apparently wins!