0

Following this blog post, I am writing an IDAPython code to traverse the AST generated by the decompiler in order to extract some information. I am providing both my AST, the Python code and the output. The problem is, the effective address is the same for both the current item and its parent which shouldn't be the case.

Python code:

import idaapi


class sample_visitor_t(ctree_visitor_t):
    def __init__(self, log_message_xref_addr):
        self.log_message_xref_addr = log_message_xref_addr
        ctree_visitor_t.__init__(self, CV_PARENTS)
        return

    def visit_expr(self, expr):
        if expr.op != cot_call:
            return 0

        method_name = get_func_name(expr.x.obj_ea)
        if expr.a.size() > 0:
            args = expr.a
            for arg in args:
                if arg.ea == self.log_message_xref_addr:
                    print method_name, hex(expr.ea)
                    pexpr = self.parent_expr()
                    print(hex(pexpr.ea), pexpr.op)

        return 0


def traverse(func_addr, log_message_xref_addr):
    function = get_func(func_addr)
    cfunc = decompile(function)
    visitor = sample_visitor_t(log_message_xref_addr)
    visitor.apply_to(cfunc.body, None)


traverse(0x8F62635C, 0x8F626570)    # emmc_recovery_init = 0x8F62635C

Decompilation:

int emmc_recovery_init()
{
  int v0; // lr@0
  unsigned __int64 v1; // r6@1
  size_t v2; // r0@1
  recovery_message *v3; // r4@1
  uint32_t v4; // r8@2
  int v5; // r0@2
  int v6; // r10@2
  uint8_t v7; // r0@3
  unsigned __int8 v8; // r3@5
  int result; // r0@12
  unsigned int status; // [sp+8h] [bp-28h]@1
  void *v11; // [sp+Ch] [bp-24h]@13

  status = 0;
  LODWORD(v1) = v0;
  v2 = mmc_get_device_blocksize();
  v3 = (recovery_message *)memalign(0x40u, v2);
  if ( !v3 )
LABEL_29:
    panic((void *)v1, "msg");
  v4 = mmc_get_device_blocksize();
  v5 = partition_get_index("misc");
  v6 = v5;
  if ( v5 < 0 )
  {
    dprintf("%s: Partition not found\n", "misc");
  }
  else
  {
    v1 = partition_get_offset(v5);
    v7 = partition_get_lun(v6);
    mmc_set_lun(v7);
    if ( v1 )
    {
      if ( !mmc_read(v1, HIDWORD(v1), v3, v4) )
      {
        v8 = v3->command[0];
        v3->command[31] = 0;
        if ( (unsigned __int8)(v8 - 1) <= 0xFDu )
          dprintf("Recovery command: %d %s\n", 32, v3);
        if ( !strcmp(v3->command, "boot-recovery") )
          boot_into_recovery = 1;
        if ( !strcmp("update-radio", v3->command) )
        {
          if ( !get_boot_info_apps(2u, &status) && status & 1 )
          {
            dprintf("radio update success\n");
            strlcpy(v3->status, "OKAY", 0x20u);
          }
          else
          {
            dprintf("radio update failed\n");
            strlcpy(v3->status, "failed-update", 0x20u);
          }
          boot_into_recovery = 1;
          if ( strcmp("reset-device-info", v3->command) )
          {
LABEL_11:
            if ( strcmp("root-detect", v3->command) )
            {
out:
              free(v3);
              result = 0;
              goto LABEL_13;
            }
LABEL_15:
            set_device_root();
            strlcpy(v3->command, (const unsigned __int8 *)"", 0x20u);
            emmc_set_recovery_msg(v3);
            goto out;
          }
        }
        else if ( strcmp("reset-device-info", v3->command) )
        {
          goto LABEL_11;
        }
        reset_device_info();
        if ( strcmp("root-detect", v3->command) )
          goto out;
        goto LABEL_15;
      }
      dprintf("mmc read failure %s %d\n", "misc", v4);
    }
    else
    {
      dprintf((const unsigned __int8 *)"partition %s doesn't exist\n", "misc");
    }
  }
  if ( v3 )
  {
    free(v3);
    result = -1;
  }
  else
  {
    result = -1;
  }
LABEL_13:
  if ( v11 != _stack_chk_guard )
    goto LABEL_29;
  return result;
}

Output:

_dprintf 0x8f626574L
('0x8f626574L', 72)
  • Note that when lifting assembler code it is very usual to generate several nodes / instructions per instruction since x86 is very bloated (more than 1000 instructions) and an abundance of side effects. – Nordwald Jan 20 '17 at 19:17
  • 72 is if instruction as defined in hexrays.hpp. If I place cursor on the enclosing if statement in the disassembly and press TAB, it takes me to a different address. – Holmes.Sherlock Jan 20 '17 at 19:40

Your Answer

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

Browse other questions tagged or ask your own question.