1

While using IDA Python for extract ARM instructions, I noticed that some instructions are not extracted completely. For example, conditional instructions such as BCS or BCC are printed as B. For analyzing, it is necessary we have the instructions completely.

Here's the code I used:

import idautils
import idc
import idaapi
for seg_ea in Segments():
 for head in Heads(seg_ea, SegEnd(seg_ea)):
  if isCode(GetFlags(head)):
   disasm= GetMnem(head)

Is there any way to correct this problem?

2

I was able to reproduce your problem on IDA 6.95 but it seems like this bug was fixed in IDA 7 since it works for me just fine. The solution below will be relevant to IDA 6.95 though it would probably be valid to earlier versions of IDA Pro.

Let's start by describing the deadlock we're facing with:
The problematic function, GetMnem, is declared in IDA 6.95\Python\idc.py:L2280 and looks like this:

def GetMnem(ea):
    """
    Get instruction mnemonics

    @param ea: linear address of instruction

    @return: "" - no instruction at the specified location

    @note: this function may not return exactly the same mnemonics
    as you see on the screen.
    """
    res = ida_ua.ua_mnem(ea)

    if not res:
        return ""
    else:
        return res

Pay attention to the following disclaimer in the function:

@note: this function may not return exactly the same mnemonics as you see on the screen.

Seems like our problems fits the disclaimer -- we don't see the same mnemonics as we see on the screen.

As you can see, GetMnem is basically a wrapper to another function -- ua_mnem which is declared in IDA 6.95\Python\ida_ua.py:L319:

def ua_mnem(*args):
  """
  ua_mnem(ea) -> char const *
  """
  return _ida_ua.ua_mnem(*args)

Well, seems like ua_mnem is a wrapper to another function which is located in IDA 6.95\python\lib\python2.7\lib-dynload\ida_64\_ida_ua.pyd. A pyd file is actually a DLL file and should not be easy-peasy to reverse. Therefore, we can't see, nor edit, the source code so we can't fix the problem.

Here comes the workaround: instead of using GetMnem you can simply mimic it by using GetDisasm and split the line to get only the instruction:

import idautils
import idc
import idaapi
for seg_ea in Segments():
 for head in Heads(seg_ea, SegEnd(seg_ea)):
  if isCode(GetFlags(head)):
    mnem = GetMnem(head)
    if (mnem[0]=='B'):
        mnem = GetDisasm(head).split()[0]
    print mnem

In this case we check whether the mnemonics is a branch instruction (begins with "B") and if so, we use the mnemonics from GetDisasm and not from GetMnem. Of course you would need to test this solution better and maybe handle some specific cases.

  • _ida_ua.ua_mnem is just a direct wrapper of the underlying IDA API from ida_ua.hpp in the SDK. – Igor Skochinsky Oct 5 '17 at 9:53

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.