3

Given a disassembly line in IDA Pro such as

.text:0040255B      call    sub_407C10

Am I right to assume that analyzing the belonging address using

idautils.XrefsFrom(0x0040255B)

always returns an xref of type 'Code_Far_Call' (xref.type 16) or 'Code_Near_Call' (xref.type 17) and not an xref of type "Code_Near_Jump" or "Code_Far_Jump"?

In other words, can function call destination addresses always be identified by checking if the xref.type is of type 16 or 17 and then taking the value in xref.to?

Of course in addition to the Call/Jump xref, the above statement always returns an xref of type 21 (the ordinary control flow).

A list of possible xref types can be found here: https://code.google.com/p/idapython/source/browse/trunk/python/idautils.py

What is the difference between a Code_Far_Call xref and a Code_Near_Call xref anyway?

Thanks for your help!

1

This depends a bit on your compiler, Actually, as you seem to be using a 32 bit OS, i wouldn't expect any far calls.

Near calls and Far calls are relicts from 16-bit area, where a call within the same 64 kbyte segment, that only changes IP, but not CS, was named a near call, and a call to anywhere in the address space, that changes CS and IP, was named a far call. Correspondingly, there were two different instructions ret and retf to return from the subroutine, that would pop just IP, or CS and IP from the stack.

With the introduction of protected mode, and 32 bit segments, management of segment registers became the responsibility of the operating system, and user mode programs stopped fiddling with them. So you shouldn't see any far calls, or retf instructions, anymore - unless you're disassembling the parts of the operating system that handle task switching, possibly.

You might see the occasional jump to a function, however (ref type 19), depending on your compiler. If the compiler optimizes tail recursion, it will replace the last "call self / ret" instruction with a "jmp self" instruction, and if parameter types match, it might replace a "call someotherfunction / ret" with "jmp someotherfunction" as well. I've seen this a lot in ARM code, and 64 bit Intel code, but can't remember seeing it in 32 bit compiled Intel code at the moment. However, i haven't worked with 32 bit Intel assembly much, recently, so there might be some newer compilers that do this without me noticing.

  • Ok, so there are (less common) call instructions whose xref.type is "Code_Near_Jump" or "Code_Far_Jump". Do you know if these cases are covered by the idaapi.is_call_insn(), that is, would is_call_insn() return True on a call instruction that has an associated xref of type "Code_Near_Jump" or "Code_Far_Jump"? – langlauf.io Mar 6 '15 at 20:15
  • 1
    You'd have to consult documentation to be sure, but no, i don't think the Code_*_Jump instructions would make is_call_insn return true. After all, they're exactly the same jmp instructions that implement control structures like loops and conditions, and the compiler uses them based on the observation that a call to something that ends in ret, which is itself followed by another ret, can be optimized to a jmp. – Guntram Blohm supports Monica Mar 7 '15 at 9:26
  • Visual Studio 2008 is able to generate such tail recursion code (In my case it was an function without any explicit variables - that may be an edge case) – user45891 Mar 7 '15 at 15:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.