Does ‘return’ come back?

We all know that call invokes a function and ret returns to the caller. Alas, nothing is certain in the binary world. The ret instruction is quite often used for short jumps within a function. Among many other improvements in IDA v5.1 there will be a special logic to recognize and mark such pseudo-returns. I was surprised to see this graph and post it here for your amusement:

Please note the underlined ret and be prepared for unusual cross-references in your scripts

12 Responses to Does ‘return’ come back?

This example is flow-sensitive, though: what does IDA do if the path leading to the node consisting of a single jump pushes a different return-to address onto the stack? Does it aggregate them into multiple outgoing edges from the “returning” block?
Anyway, keep up the good work.

In fact, there are some Binary code obsfucators have been using this kind of trick to fool IDA and prevent manual analysis:
.text:00010EB5 mov [esp+8], eax
.text:00010EB9 push ecx
.text:00010EBA mov eax, [esp]
.text:00010EBD mov [esp+8], eax ; DATA XREF: .text:00010AF2o
.text:00010EE8 retn
So I think maybe multi code xref or data xref should be added to ret.Additionaly I think IDA could try to backtrace the stack top to automatic resolve some these tricks.
There aren’t any GUI command to add data xref or code xref in IDA now.Maybe it’s better to expose them to the user than SDK/script only.When I use the SDK function to add code xref IDA wouldn’t add automatic comments to some indirect jump or call such as call [edx], I had to add the comment manually, would IDA support automatic comments to manual added xrefs in 5.1?
Additionaly more and more obsfucators using unconditonal jump such as:
w造
.text:00011276 push eax
.text:00011277 push [esp+0Ch+var_C]
.text:0001127A mov eax, [esp+0]
.text:0001127D mov [esp+10h+var_C], eax
.text:00011281 jmp loc_11332
loc_11332: ; CODE XREF: sub_11276+Bo
.text:00011208 push edi
.text:00011209 mov eax, esp
.text:0001120B jmp loc_113FB
to split one node into mutiple nodes, maybe IDA graph could reassemble them together when the jump target is one-indegree node.
I think these kind of trick would be used in more and more software to protect themselves from being analyzed within one or two years.

Alas, this is a standard trick. Borland’s Delphi routinely uses it in all applications.
To tell the truth we do not try to fight against code obfuscation in IDA. There are unlimited number of potential obfuscation methods. Implementing something limited but practical would mean that a slightly new method would render the existing defenses useless and require constant modification and improvement of the analysis methods. Antivirus companies address this by creating virus signatures and updating them real time. We have to note that their task is simpler in a sense: given a new obfuscation method, flag the executable as suspicious and inform the user. IDA can not do that, you guys always want to have more information
A much better approach is to write small plugins to handle obfuscated code. Be it random jumps, useless computations, or something else, it is much easier to attack one particular obfuscation method than try to write a generic plugin.

hume,
You can add xrefs from the user interface, no need to write a plugin or script. For that, open the xrefs window and press Ins.
Writing a script is really easy. Here is an oneliner:
AddCodeXref(here, there, fl_CF|XREF_USER);
would add an xref from here to there.
If you want IDA to support a new feature, please send your suggestions to Datarescue (with your key file). I don’t promise that we will implement everything you ask but will consider your suggestions. Thanks.

While you’re in there messing with exit paths…
I’d love to see IDA recognize other function terminators. On Windows, for example:
cxxhandler
ExitProcess
ExitThread
I frequently see these preventing IDA from being able to tag a chunk of code as a function.
Might be nice if I could tag a called function as “will never come back, terminates this function”.

It is automatic, no need to activate anything. Take a function ending with ExitProcess and you will see that IDA sets the ‘noreturn’ attribute for it. The attribute is visible in the function header like this: