Exemple #1
0
/*
#<pydoc>
def set_switch_info_ex(ea, switch_info_ex):
    """
    Saves the switch information in the database
    Please refer to the SDK sample 'uiswitch'
    @return: Boolean
    """
    pass
#</pydoc>
*/
bool py_set_switch_info_ex(ea_t ea, PyObject *py_swi)
{
  switch_info_ex_t *swi = switch_info_ex_t_get_clink(py_swi);
  if ( swi == NULL )
    return false;

  set_switch_info_ex(ea, swi);
  return true;
}
Exemple #2
0
// check and create a flat 32 bit jump table -- the most common case
static void check_and_create_flat32(
        jump_table_type_t /*jtt*/,
        switch_info_ex_t &si)
{
  // check the table contents
  ea_t table = si.jumps;
  segment_t *s = getseg(table);
  if ( s == NULL )
    return;
  size_t maxsize = size_t(s->endEA - table);
  int size = si.ncases;
  if ( size > maxsize )
    size = (int)maxsize;

  int i;
  insn_t saved = cmd;
  for ( i=0; i < size; i++ )
  {
    ea_t ea = table + 4*i;
    flags_t F = getFlags(ea);
    if ( !hasValue(F) )
      break;
    if ( i && (has_any_name(F) || hasRef(F)) )
      break;
    ea_t target = segm_adjust_ea(getseg(table), si.elbase + get_long(ea));
    if ( !isLoaded(target) )
      break;
    flags_t F2 = get_flags_novalue(target);
    if ( isTail(F2) || isData(F2) )
      break;
    if ( !isCode(F2) && !decode_insn(target) )
      break;
  }
  cmd = saved;
  size = i;
  // create the table
  for ( i=0; i < size; i++ )
  {
    ea_t ea = table + 4*i;
    doDwrd(ea, 4);
    op_offset(ea, 0, REF_OFF32, BADADDR, si.elbase);
    ea_t target = si.elbase + segm_adjust_diff(getseg(table), get_long(ea));
    ua_add_cref(0, target, fl_JN);
  }
  si.flags  |= SWI_J32;
  if ( si.defjump != BADADDR )
    si.flags |= SWI_DEFAULT;
  si.ncases  = (uint16)size;
  si.startea = cmd.ea;
  set_switch_info_ex(cmd.ea, &si);
}
Exemple #3
0
//---------------------------------------------------------------------------
// The main function - called when the user selects the menu item
static bool idaapi callback(void *)
{
  // Calculate the default values to display in the form
  ea_t screen_ea = get_screen_ea();
  segment_t *s = getseg(screen_ea);
  if ( s == NULL || !isCode(get_flags_novalue(screen_ea)) )
  {
    warning("AUTOHIDE NONE\nThe cursor must be on the table jump instruction");
    return false;
  }
  ea_t startea = screen_ea;
  while ( true )
  {
    ea_t prev = prev_not_tail(startea);
    if ( !is_switch_insn(prev) )
      break;
    startea = prev;
  }
  ea_t jumps = get_first_dref_from(screen_ea);
  uval_t jelsize = s->abytes();
  uval_t jtsize = 0;
  if ( jumps != BADADDR )
  {
    decode_insn(screen_ea);
    jtsize = guess_table_size(jumps);
  }
  uval_t shift = 0;
  uval_t elbase = 0;
  char input[MAXSTR];
  input[0] = '\0';
  ea_t defea = BADADDR;
  uval_t lowcase = 0;
  ushort jflags = 0;
  ushort vflags = 0;
  ea_t vtable = BADADDR;
  ea_t vtsize = 0;
  ea_t velsize = s->abytes();
  reg_info_t ri;
  ri.size = 0;
  // If switch information is present in the database, use it for defaults
  switch_info_ex_t si;
  if ( get_switch_info_ex(screen_ea, &si, sizeof(si)) > 0 )
  {
    jumps = si.jumps;
    jtsize = si.ncases;
    startea = si.startea;
    elbase = si.elbase;
    jelsize = si.get_jtable_element_size();
    shift = si.get_shift();
    defea = (si.flags & SWI_DEFAULT) ? si.defjump : BADADDR;
    if ( si.regnum != -1 )
      get_reg_name(si.regnum, get_dtyp_size(si.regdtyp), input, sizeof(input));
    if ( si.flags & SWI_SIGNED )
      jflags |= 2;
    if ( si.flags2 & SWI2_SUBTRACT )
      jflags |= 4;
    if ( si.flags & SWI_SPARSE )
    {
      jflags |= 1;
      vtable = si.values;
      vtsize = jtsize;
      velsize = si.get_vtable_element_size();
      if ( si.flags2 & SWI2_INDIRECT )
      {
        vflags |= 1;
        jtsize = si.jcases;
      }
      if ( si.flags & SWI_JMP_INV )
        vflags |= 2;
    }
    else
    {
      lowcase = si.lowcase;
    }
  }
  // Now display the form and let the user edit the attributes
  while ( AskUsingForm_c(main_form, &jumps, &jtsize, &jelsize, &shift, &elbase,
                         &startea, input, &lowcase, &defea, &jflags) )
  {
    if ( !check_table(jumps, jelsize, jtsize) )
      continue;
    if ( shift > 3 )
    {
      warning("AUTOHIDE NONE\nInvalid shift value (allowed values are 0..3)");
      continue;
    }
    if ( !isCode(get_flags_novalue(startea)) )
    {
      warning("AUTOHIDE NONE\nInvalid switch idiom start %a (must be an instruction", startea);
      continue;
    }
    ri.reg = -1;
    if ( input[0] != '\0' && !parse_reg_name(input, &ri) )
    {
      warning("AUTOHIDE NONE\nUnknown input register: %s", input);
      continue;
    }
    if ( defea != BADADDR && !isCode(get_flags_novalue(defea)) )
    {
      warning("AUTOHIDE NONE\nInvalid default jump %a (must be an instruction", defea);
      continue;
    }
    if ( jflags & 1 ) // value table is present
    {
      bool vok = false;
      while ( AskUsingForm_c(value_form, &vflags, &vtable, &vtsize, &velsize) )
      {
        if ( (vflags & 1) == 0 )
          vtsize = jtsize;
        if ( check_table(vtable, velsize, vtsize) )
        {
          vok = true;
          break;
        }
      }
      if ( !vok )
        break;
    }
    // ok, got and validated all params -- fill the structure
    si.flags = SWI_EXTENDED;
    si.flags2 = 0;
    if ( jflags & 2 )
      si.flags |= SWI_SIGNED;
    if ( jflags & 4 )
      si.flags2 |= SWI2_SUBTRACT;
    si.jumps = jumps;
    si.ncases = ushort(jtsize);
    si.startea = startea;
    si.elbase = elbase;
    if ( elbase != 0 )
      si.flags |= SWI_ELBASE;
    si.set_jtable_element_size((int)jelsize);
    si.set_shift((int)shift);
    if ( defea != BADADDR )
    {
      si.flags |= SWI_DEFAULT;
      si.defjump = defea;
    }
    if ( ri.reg != -1 )
      si.set_expr(ri.reg, get_dtyp_by_size(ri.size));
    if ( jflags & 1 ) // value table is present
    {
      si.flags |= SWI_SPARSE;
      si.values = vtable;
      si.set_vtable_element_size((int)velsize);
      if ( (vflags & 1) != 0 )
      {
        si.flags2 |= SWI2_INDIRECT;
        si.jcases = (int)jtsize;
        si.ncases = (ushort)vtsize;
      }
      if ( (vflags & 2) != 0 )
        si.flags |= SWI_JMP_INV;
    }
    else
    {
      si.lowcase = lowcase;
    }
    // ready, store it
    set_switch_info_ex(screen_ea, &si);
    create_switch_table(screen_ea, &si);
    setFlbits(screen_ea, FF_JUMP);
    create_insn(screen_ea);
    info("AUTOHIDE REGISTRY\nSwitch information has been stored");
    break;
  }
  return true;
}