Beispiel #1
0
//----------------------------------------------------------------------
bool create_func_frame(func_t *pfn)	// create frame of newly created function
{
  bool std_vars_func = true;

  if ( pfn != NULL )
  {
    if ( pfn->frame == BADNODE )
    {
      ea_t ea = pfn->startEA;
      int regsize = 0;

      while (ea < pfn->endEA) // check for register pushs
      {
        decode_insn(ea);
        ea += cmd.size;		// считаем кол-во push
        if ( (cmd.itype == OAK_Dsp_push) && (cmd.Op1.type == o_reg) )
            regsize++;
        else
            break;
      }


      ea = pfn->startEA;
      int16 localsize = 0;
      while (ea < pfn->endEA) // check for frame creation
      {
        decode_insn(ea);
        ea += cmd.size;	// Попытка определить команду типа	ADDV	#,SP
        if ( (cmd.itype == OAK_Dsp_addv) && (cmd.Op1.type == o_imm) && (cmd.Op2.type == o_reg) && (cmd.Op2.reg == SP) )
        {
          localsize = (uint16)cmd.Op1.value;
          break;
        }

        // Если встретили команду mov #, rb  --> не надо создавать фрейм такой ф-ции, и объявлять локальные переменные
        if ( (cmd.itype == OAK_Dsp_mov) && (cmd.Op1.type == o_imm) && (cmd.Op2.type == o_reg) && (cmd.Op2.reg == RB) )
        {
          std_vars_func = false;
          break;
        }

      }

      if (std_vars_func)
      {
         pfn->flags |= FUNC_FRAME;
         update_func(pfn);
      }   

      add_frame(pfn, -localsize, (ushort)regsize, 0);

    }
  }
  return 0;
}
Beispiel #2
0
int get_disasm(ea_t addr, char *buf, int bufsz)
{
	char mnem[32];
	char *ptr = buf;

	decode_insn(addr);
	ua_mnem(addr, mnem, sizeof(mnem) - 1);

	qsnprintf(buf, bufsz - 1, "%08x: %-5s ", addr, mnem);
	ptr += strlen(buf);

	for(int opnum = 0; cmd.Operands[opnum].type != o_void; opnum++)
	{
		char op_str[128];

		if(opnum != 0)
			qsnprintf(op_str, sizeof(op_str), ", ");

		ua_outop2(addr, op_str, sizeof(op_str) - 3, opnum);
		tag_remove(op_str, op_str, 0);
		
		qsnprintf(ptr, bufsz - 1 - (ptr - buf), "%s", op_str);
		ptr += strlen(op_str);
	}
	return 0;
}
Beispiel #3
0
//----------------------------------------------------------------------
bool idaapi create_func_frame(func_t *pfn)
{
    if ( pfn != NULL )
    {
        if ( pfn->frame == BADNODE )
        {
            ea_t ea = pfn->startEA;
            if ( ea + 12 < pfn->endEA) // minimum 4 + 4 + 2 + 2 bytes needed
            {
                insn_t insn[4];
                for (int i=0; i<4; i++)
                {
                    decode_insn(ea);
                    insn[i] = cmd;
                    ea += cmd.size;
                }
                if ( insn[0].itype == PIC_movff2 // movff FSR2L,POSTINC1
                        && insn[0].Op1.addr == PIC16_FSR2L && insn[0].Op2.addr == PIC16_POSTINC1
                        && insn[1].itype == PIC_movff2 // movff FSR1L,FSR2L
                        && insn[1].Op1.addr == PIC16_FSR1L && insn[1].Op2.addr == PIC16_FSR2L
                        && insn[2].itype == PIC_movlw  // movlw <size>
                        && insn[3].itype == PIC_addwf3 // addwf FSR1L,f
                        && insn[3].Op1.addr == PIC16_FSR1L && insn[3].Op2.reg == F)
                {
                    setflag((uint32 &)pfn->flags,FUNC_FRAME,1);
                    return add_frame(pfn, insn[2].Op1.value, 0, 0);
                }
            }
        }
    }
    return 0;
}
Beispiel #4
0
// The plugin can be passed an integer argument from the plugins.cfg
// file. This can be useful when you want the one plug-in to do
// something different depending on the hot-key pressed or menu
// item selected.
void IDAP_run(int arg)
{
	msg("%s run()\n", IDAP_name);

	// Disassemble the instruction at the cursor position, store it in
	// the global accessible "cmd" structure.
	// ua_out(get_screen_ea(), false);
	decode_insn( get_screen_ea() );

	// Display information about the first operand
	msg("itype = %u size = %zu\n", cmd.itype, cmd.size );
	for( unsigned int n = 0; n < UA_MAXOP ; ++n )
	{
		if( cmd.Operands[n].type == o_void ) break;
		msg("Operand %u n = %d type = %d reg = %d value = %a addr = %a\n",
			n,
			cmd.Operands[n].n,
			cmd.Operands[n].type,
			cmd.Operands[n].reg,
			cmd.Operands[n].value,
			cmd.Operands[n].addr);
	}

	char calleeName[MAXSTR];
	get_func_name(cmd.Op1.addr, calleeName, sizeof(calleeName));
	msg("Callee Name: \"%s\"", calleeName);

	return;
}
Beispiel #5
0
//----------------------------------------------------------------------
static uval_t find_ret_purged(const func_t *pfn)
{
  uval_t argsize = 0;
  ea_t ea = pfn->startEA;
  while ( ea < pfn->endEA )
  {
    decode_insn(ea);
    if ( cmd.itype == H8500_rtd || cmd.itype == H8500_prtd )
    {
      argsize = cmd.Op1.value;
      break;
    }
    ea = nextthat(ea, pfn->endEA, f_isCode, NULL);
  }

  // could not find any ret instructions
  // but the function ends with a jump
  if ( ea >= pfn->endEA
    && (cmd.itype == H8500_jmp || cmd.itype == H8500_pjmp) )
  {
    ea_t target = calc_mem(cmd.Op1);
    pfn = get_func(target);
    if ( pfn != NULL )
      argsize = pfn->argsize;
  }

  return argsize;
}
Beispiel #6
0
bool idaapi create_func_frame(func_t *pfn) {
    if ( pfn == NULL )
        return 0;

    ea_t ea = pfn->startEA;
    insn_t insn[4];
    int i;

    for (i = 0; i < 4; i++) {
        decode_insn(ea);
        insn[i] = cmd;
        ea += cmd.size;
    }

    i = 0;
    ushort regsize = 0;            // number of saved registers

    // first insn is not either push fp OR st fp, @-sp
    if ( (insn[i].itype != m32r_push || insn[i].Op1.reg != rFP ) &&
        (insn[i].itype != m32r_st || insn[i].Op1.reg != rFP || insn[i].Op2.reg != rSP || insn[i].Op2.specflag1 != fRIAS))
    {
        return 0;
    }

    regsize += 4;
    i++;

    // next insn is push lr OR st lr, @-sp
    if ( (insn[i].itype == m32r_push && insn[i].Op1.reg == rLR ) ||
        (insn[i].itype == m32r_st && insn[i].Op1.reg == rFP && insn[i].Op2.reg == rLR && insn[i].Op2.specflag1 != fRIAS))
    {
        regsize += 4;
        i++;
    }

    // next insn is not addi sp, #imm
    if ( insn[i].itype != m32r_addi || insn[i].Op1.reg != rSP )
        return 0;

    sval_t offset = - (sval_t) insn[i].Op2.value;

    // toggle to the negative sign of the immediate operand of the addi insn
    if ( !is_invsign(insn[i].ea, get_flags_novalue(insn[i].ea), 2) )
      toggle_sign(insn[i].ea, 2);

    i++;

    // next insn is not mv fp, sp
    if ( insn[i].itype != m32r_mv || insn[i].Op1.reg != rFP || insn[i].Op2.reg != rSP )
        return 0;

#if DEBUG
    msg("=> %d bytes\n", - (signed) insn[1].Op2.value);
#endif

    pfn->flags |= (FUNC_FRAME | FUNC_BOTTOMBP);
    //setflag((uint32 &) pfn->flags, FUNC_FRAME | FUNC_BOTTOMBP, 1);
    return add_frame(pfn, offset, regsize, 0);
}
Beispiel #7
0
/*
 * decode_ext()
 *
 *    Decode opcode extensions (if any)
 */
static int
decode_ext(struct ud *u, uint16_t ptr)
{
  uint8_t idx = 0;
  if ((ptr & 0x8000) == 0) {
    return decode_insn(u, ptr); 
  }
  u->le = &ud_lookup_table_list[(~0x8000 & ptr)];
  if (u->le->type == UD_TAB__OPC_3DNOW) {
    return decode_3dnow(u);
  }

  switch (u->le->type) {
    case UD_TAB__OPC_MOD:
      /* !11 = 0, 11 = 1 */
      idx = (MODRM_MOD(modrm(u)) + 1) / 4;
      break;
      /* disassembly mode/operand size/address size based tables.
       * 16 = 0,, 32 = 1, 64 = 2
       */
    case UD_TAB__OPC_MODE:
      idx = u->dis_mode / 32;
      break;
    case UD_TAB__OPC_OSIZE:
      idx = eff_opr_mode(u->dis_mode, REX_W(u->pfx_rex), u->pfx_opr) / 32;
      break;
    case UD_TAB__OPC_ASIZE:
      idx = eff_adr_mode(u->dis_mode, u->pfx_adr) / 32;
      break;
    case UD_TAB__OPC_X87:
      idx = modrm(u) - 0xC0;
      break;
    case UD_TAB__OPC_VENDOR:
      if (u->vendor == UD_VENDOR_ANY) {
        /* choose a valid entry */
        idx = (u->le->table[idx] != 0) ? 0 : 1;
      } else if (u->vendor == UD_VENDOR_AMD) {
        idx = 0;
      } else {
        idx = 1;
      }
      break;
    case UD_TAB__OPC_RM:
      idx = MODRM_RM(modrm(u));
      break;
    case UD_TAB__OPC_REG:
      idx = MODRM_REG(modrm(u));
      break;
    case UD_TAB__OPC_SSE:
      return decode_ssepfx(u);
    default:
      assert(!"not reached");
      break;
  }

  return decode_ext(u, u->le->table[idx]);
}
Beispiel #8
0
//----------------------------------------------------------------------
int is_align_insn(ea_t ea)
{
  if ( !decode_insn(ea) ) return 0;
  switch ( cmd.itype )
  {
    case OAK_Dsp_nop:
      break;
    default:
      return 0;
  }
  return cmd.size;
}
Beispiel #9
0
//----------------------------------------------------------------------
int idaapi is_align_insn(ea_t ea)
{
  if ( !decode_insn(ea) ) return 0;
  switch ( cmd.itype )
  {
    case DSP56_nop:
      break;
    default:
      return 0;
  }
  return cmd.size;
}
Beispiel #10
0
//----------------------------------------------------------------------
int is_align_insn(ea_t ea)
{
  decode_insn(ea);
  switch ( cmd.itype ) {
    case AVR_mov:
      if ( cmd.Op1.reg == cmd.Op2.reg ) break;
    default:
      return 0;
    case AVR_nop:
      break;
  }
  return cmd.size;
}
int idaapi is_align_insn(ea_t ea)
{
    if (!decode_insn(ea)) return 0;

    switch (cmd.itype)
    {
    case M8B_NOP:
    case M8B_XPAGE:
        return cmd.size;
    default:
        return 0;
    }
}
Beispiel #12
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);
}
Beispiel #13
0
//----------------------------------------------------------------------
bool create_func_frame(func_t *pfn)	// create frame of newly created function
{
  if ( pfn != NULL )
  {
    if ( pfn->frame == BADNODE )
    {
      ea_t ea = pfn->startEA;
      ushort regsize = 0;
      while (ea < pfn->endEA) // check for register pushs
      {
        decode_insn(ea);
        ea += cmd.size;		// считаем кол-во push
        if ( ((cmd.itype == TMS320C3X_PUSH) || (cmd.itype == TMS320C3X_PUSHF)) && (cmd.Op1.type == o_reg) )
            regsize++;
        else	// варианты манипуляции с sp типа:	LDI	SP,AR3	ADDI	#0001,SP игнорируем
	    if 	( ((cmd.Op1.type == o_reg) && (cmd.Op1.reg == sp)) || ((cmd.Op2.type == o_reg) && (cmd.Op2.reg == sp)) )
		continue;
	    else
		break;
      }

      ea = pfn->startEA;
      int localsize = 0;
      while (ea < pfn->endEA) // check for frame creation
      {
        decode_insn(ea);
        ea += cmd.size;	// Попытка определить команду типа	ADDI	#0001,SP
        if ( (cmd.itype == TMS320C3X_ADDI) && (cmd.Op1.type == o_imm) && (cmd.Op2.type == o_reg) && (cmd.Op2.reg == sp) )
        {
          localsize = (int)cmd.Op1.value;
          break;
        }
      }
      add_frame(pfn, localsize, regsize, 0);
    }
  }
  return 0;
}
Beispiel #14
0
//----------------------------------------------------------------------
bool create_func_frame(func_t *pfn)
{
  if ( pfn != NULL )
  {
    if ( pfn->frame == BADNODE )
    {
      ea_t ea = pfn->startEA;
      int regsize = 0;
      while (ea < pfn->endEA) // check for register pushs
      {
        if ( !decode_insn(ea) )
          break;
        if (cmd.itype != TMS320C54_pshm )
          break;
        if ( cmd.Op1.type != o_mem && cmd.Op1.type != o_mmr )
          break;
        if ( get_mapped_register(cmd.Op1.addr) == rnone )
          break;
        regsize++;
        ea += cmd.size;
      }
      int localsize = 0;
      while (ea < pfn->endEA) // check for frame creation
      {
        if (cmd.itype == TMS320C54_frame && cmd.Op1.type == o_imm)
        {
          localsize = -(int)cmd.Op1.value;
          break;
        }
        ea += cmd.size;
        if ( !decode_insn(ea) )
          break;
      }
      add_frame(pfn, localsize+regsize, 0, 0);
    }
  }
  return 0;
}
Beispiel #15
0
//----------------------------------------------------------------------
//      Is the instruction created only for alignment purposes?
//      returns: number of bytes in the instruction
int is_align_insn(ea_t ea)
{

  if ( !decode_insn(ea) ) return 0;

  switch ( cmd.itype )
  {
    case TMS320C3X_NOP:
      break;
    default:
      return 0;
  }

  return cmd.size;
}
Beispiel #16
0
//----------------------------------------------------------------------
int idaapi is_align_insn(ea_t ea)
{
  if ( !decode_insn(ea) ) return 0;
  switch ( cmd.itype )
  {
    case H8_nop:
      break;
    case H8_mov:
    case H8_or:
      if ( cmd.Op1.type == cmd.Op2.type && cmd.Op1.reg == cmd.Op2.reg ) break;
    default:
      return 0;
  }
  return cmd.size;
}
Beispiel #17
0
/*
 * decode_3dnow()
 *
 *    Decoding 3dnow is a little tricky because of its strange opcode
 *    structure. The final opcode disambiguation depends on the last
 *    byte that comes after the operands have been decoded. Fortunately,
 *    all 3dnow instructions have the same set of operand types. So we
 *    go ahead and decode the instruction by picking an arbitrarily chosen
 *    valid entry in the table, decode the operands, and read the final
 *    byte to resolve the menmonic.
 */
static __inline int
decode_3dnow(struct ud* u)
{
  uint16_t ptr;
  assert(u->le->type == UD_TAB__OPC_3DNOW);
  assert(u->le->table[0xc] != 0);
  decode_insn(u, u->le->table[0xc]);
  inp_next(u); 
  if (u->error) {
    return -1;
  }
  ptr = u->le->table[inp_curr(u)]; 
  assert((ptr & 0x8000) == 0);
  u->mnemonic = ud_itab[ptr].mnemonic;
  return 0;
}
Beispiel #18
0
char get_byte_with_optimization(ea_t ea)
{
	switch (patchdiff_cpu)
	{
	case CPU_X8632:
	case CPU_X8664:
		return x86_get_byte(ea);
	case CPU_PPC:
		return ppc_get_byte(ea);
	default:
		{
			decode_insn(ea);
			return (char)cmd.itype;
		}
	}
}
Beispiel #19
0
//----------------------------------------------------------------------
bool idaapi create_func_frame(func_t *pfn)
{
  int code = 0;
  if ( pfn->frame == BADNODE )
  {
    size_t regs = 0;
    ea_t ea = pfn->startEA;
    bool bpused = false;
    while ( ea < pfn->endEA )                 // skip all pushregs
    {                                         // (must test that ea is lower
                                              // than pfn->endEA)
      decode_insn(ea);
      ea += cmd.size;
      switch ( cmd.itype )
      {
        case H8_nop:
          continue;
        case H8_push:
          regs += get_dtyp_size(cmd.Op1.dtyp);
          continue;
        case H8_stm:
          if ( !issp(cmd.Op2.reg) ) break;
          regs += cmd.Op1.nregs * get_dtyp_size(cmd.Op1.dtyp);
          continue;
        case H8_mov:  // mov.l er6, sp
          if ( cmd.Op1.type == o_reg && issp(cmd.Op1.reg)
            && cmd.Op2.type == o_reg && isbp(cmd.Op2.reg) )
              bpused = true;
          break;
        default:
          break;
      }
      break;
    }
    uint32 frsize  = 0;
    uint32 argsize = 0;
    if ( frsize != 0 || argsize != 0 || regs != 0 || bpused )
    {
      setflag((uint32 &)pfn->flags,FUNC_FRAME,bpused);
      return add_frame(pfn, frsize, (ushort)regs, argsize);
    }
  }
  return code;
}
Beispiel #20
0
static void decode(struct ptxed_decoder *decoder,
		   struct pt_image_section_cache *iscache,
		   const struct ptxed_options *options,
		   struct ptxed_stats *stats)
{
	if (!decoder) {
		printf("[internal error]\n");
		return;
	}

	switch (decoder->type) {
	case pdt_insn_decoder:
		decode_insn(decoder->variant.insn, options, stats);
		break;

	case pdt_block_decoder:
		decode_block(decoder->variant.block, iscache, options, stats);
		break;
	}
}
Beispiel #21
0
//----------------------------------------------------------------------
int idaapi is_align_insn(ea_t ea)
{
  if ( !decode_insn(ea) ) return 0;
  switch ( cmd.itype )
  {
    case H8500_nop:
      break;
    case H8500_mov_g:         // B/W Move data
    case H8500_mov_e:         // B   Move data
    case H8500_mov_i:         // W   Move data
    case H8500_mov_f:         // B/W Move data
    case H8500_mov_l:         // B/W Move data
    case H8500_mov_s:         // B/W Move data
    case H8500_or:
    case H8500_and:
      if ( cmd.Op1.type == cmd.Op2.type && cmd.Op1.reg == cmd.Op2.reg ) break;
    default:
      return 0;
  }
  return cmd.size;
}
Beispiel #22
0
//----------------------------------------------------------------------
static void setup_far_func(func_t *pfn)
{
  if ( (pfn->flags & FUNC_FAR) == 0 )
  {
    ea_t ea1 = pfn->startEA;
    ea_t ea2 = pfn->endEA;
    while ( ea1 < ea2 )
    {
      if ( isCode(get_flags_novalue(ea1)) )
      {
        decode_insn(ea1);
        if ( is_far_ending() )
        {
          pfn->flags |= FUNC_FAR;
          update_func(pfn);
          break;
        }
      }
      ea1 = next_head(ea1, ea2);
    }
  }
}
Beispiel #23
0
static bool check_for_table_jump(void)
{
  ea_t base = BADADDR, table = BADADDR, defea = BADADDR;
  int size = 0, elsize = 0;

  int i;
  bool ok = false;
  insn_t saved = cmd;
  for ( i=0; !ok && i < qnumber(patterns); i++ )
  {
    ok = patterns[i](&base, &table, &defea, &size, &elsize);
    cmd = saved;
  }
  if ( !ok ) return false;

  if ( table != BADADDR ) table = toEA(cmd.cs, table);
  if ( base  != BADADDR ) base  = toEA(cmd.cs, base);
  if ( defea != BADADDR ) defea = toEA(cmd.cs, defea);

  // check the table contents
  int oldsize = size;
  segment_t *s = getseg(table);
  if ( s == NULL ) return false;
  int maxsize = int(s->endEA - table);
  if ( size > maxsize ) size = maxsize;

  for ( i=0; i < size; i++ )
  {
    ea_t ea = table+i*elsize;
    flags_t F = getFlags(ea);
    if ( !hasValue(F)
      || (i && (has_any_name(F) || hasRef(F))) ) break;
    int el = elsize == 1 ? get_byte(ea) : get_word(ea);
    flags_t F2 = get_flags_novalue(base+el);
    if ( isTail(F2)
      || isData(F2)
      || (!isCode(F2) && !decode_insn(base+el)) ) break;
  }
  cmd = saved;
  size = i;
  if ( size != oldsize )
    msg("Warning: jpt_%04a calculated size of %d forced to %d!\n",
                                      cmd.ip, oldsize, size);

  // create the table
  if ( size == 0 ) return false;
  for ( i=0; i < size; i++ )
  {
    ea_t ea = table + i*elsize;
    (elsize == 1 ? doByte : doWord)(ea, elsize);
    op_offset(ea, 0, elsize == 1 ? REF_OFF8 : REF_OFF16, BADADDR, base);
    ua_add_cref(0, base + (elsize==1?get_byte(ea):get_word(ea)), fl_JN);
  }
  char buf[MAXSTR];
  qsnprintf(buf, sizeof(buf), "def_%a", cmd.ip);
//  set_name(defea, buf, SN_NOWARN|SN_LOCAL);         // temporary kernel bug workaround
  set_name(defea, buf, SN_NOWARN);
  qsnprintf(buf, sizeof(buf), "jpt_%a", cmd.ip);
  set_name(table, buf, SN_NOWARN);
  return true;
}
Beispiel #24
0
void struct_trace(ea_t addr)
{
	strace_t *trace;
	decode_insn(addr);
	
	for(int opnum = 0; cmd.Operands[opnum].type != o_void; opnum++)
	{
		op_t *op = &cmd.Operands[opnum];
		char *opname = NULL;
		unsigned int val = 0;

		switch(opnum)
		{
		case 0:
			opname = "dst";
			break;
		case 1:
			opname = "src";
			break;
		case 2:
			opname = "aux";
			break;
		}

		switch(op->type)
		{
		case o_displ:
			// if operand if is a register deref'd
			// get absolute value 
			// check if it points to beginning of structures
			val = general[op->reg] + op->addr;
			break;
		case o_phrase:
			val = general[op->phrase];
			break;
		}

		for(trace = strace; trace; trace = trace->next)
		{
			if(val >= trace->base && val <= trace->base + trace->size)
			{
				char name[256];
//				char cmt[512];
				struc_t *sptr = trace->sptr;
				member_t *mptr = get_member(sptr, val - trace->base);
				
				if(!mptr)
				{				
					char *mtype; 
					switch(get_dtyp_size(op->dtyp))
					{
					case 1:
						mtype = "_byte";
						break;
					case 2:
						mtype = "_word";
						break;
					case 4:
						mtype = "_dword";
						break;
					case 8: 
						mtype = "_qword";
						break;
					default:
						mtype = "_offset";
						break;
					}

					qsnprintf(name, 256, "%s_%d", mtype, val - trace->base);
					//msg("%s\n", name);
					//qsnprintf(name, 256, "offset_%d", val - trace->base);
					if(struct_member_add(sptr, name, val - trace->base, 0, NULL, get_dtyp_size(op->dtyp)) < 0)
					{
						trace = trace->next;
						continue;
					}
					mptr = get_member(sptr, val - trace->base);

				}
				//get_member_fullname(mptr->id, name, sizeof(name) -1);
				//append_cmt(addr, name, true);

				tid_t path[2];
				path[0] = sptr->id;
				path[1] = mptr->id;
				op_stroff(addr, opnum, path, 2, 0);
			}
		}

	}


	return;
}
Beispiel #25
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;
}
int idaapi emu()
{
    char szLabel[MAXSTR];
    insn_t saved;
    segment_t* pSegment;
    ea_t ea, length, offset;
    flags_t flags;
    uint32 dwFeature, i;

    dwFeature = cmd.get_canon_feature();
    fFlow = !(dwFeature & CF_STOP);

    if (dwFeature & CF_USE1) op_emu(cmd.Op1, 1);
    if (dwFeature & CF_USE2) op_emu(cmd.Op2, 1);

    if (dwFeature & CF_CHG1) op_emu(cmd.Op1, 0);
    if (dwFeature & CF_CHG2) op_emu(cmd.Op2, 0);

    saved = cmd;
    switch (cmd.itype)
    {
    case M8B_MOV:
        if (!cmd.Op1.is_reg(rPSP))
            break;
    case M8B_SWAP:
        if (cmd.itype == M8B_SWAP && !cmd.Op2.is_reg(rDSP))
            break;

        for (i = 0; i < 5; ++i)
        {
            ea = decode_prev_insn(cmd.ea);
            if (ea == BADADDR) break;
            if (cmd.itype == M8B_MOV && cmd.Op1.is_reg(rA) && cmd.Op2.type == o_imm)
            {
                ea = toRAM(cmd.Op2.value);
                if (ea != BADADDR)
                {
                    qsnprintf(szLabel, sizeof(szLabel), "%s_%0.2X", cmd.itype == M8B_MOV ? "psp" : "dsp", cmd.Op2.value);
                    ua_add_dref(cmd.Op2.offb, ea, dr_O);
                    set_name(ea, szLabel, SN_NOWARN);
                }
                break;
            }
        }
        break;
    case M8B_JACC:
        pSegment = getseg(cmd.ea);
        if (!pSegment) break;
        length = pSegment->endEA - cmd.ea;
        if (length > 256) length = 256;
        for (offset = 2; offset < length; offset += 2)
        {
            ea = toROM(saved.Op1.addr + offset);
            if (ea == BADADDR) break;
            flags = getFlags(ea);
            if (!hasValue(flags) || (has_any_name(flags) || hasRef(flags)) || !create_insn(ea)) break;
            switch (cmd.itype)
            {
            case M8B_JMP:
            case M8B_RET:
            case M8B_RETI:
            case M8B_IPRET:
                add_cref(saved.ea, ea, fl_JN);
                break;
            default:
                offset = length;
            }
        }
        break;
    case M8B_IORD:
    case M8B_IOWR:
    case M8B_IOWX:
        for (i = 0; i < 5; ++i)
        {
            ea = (saved.itype == M8B_IORD) ? decode_insn(cmd.ea + cmd.size) : decode_prev_insn(cmd.ea);
            if (ea == BADADDR) break;
            if (cmd.Op1.is_reg(rA) && cmd.Op2.type == o_imm)
            {
                qsnprintf(szLabel, sizeof(szLabel), "[A=%0.2Xh] ", cmd.Op2.value);
                if (get_portbits_sym(szLabel + qstrlen(szLabel), saved.Op1.addr, cmd.Op2.value))
                    set_cmt(saved.ea, szLabel, false);
                break;
            }
        }
    }
    cmd = saved;

    if ((cmd.ea & 0xFF) == 0xFF)
    {
        switch (cmd.itype)
        {
        case M8B_RET:
        case M8B_RETI:
        case M8B_XPAGE:
            break;
        default:
            QueueMark(Q_noValid, cmd.ea);
        }
    }

    if (fFlow) ua_add_cref(0, cmd.ea + cmd.size, fl_F);

    return 1;
}
Beispiel #27
0
// Analyze an instruction
static ea_t next_insn(ea_t ea) {
    if ( decode_insn(ea) == 0 )
        return 0;
    ea += cmd.size;
    return ea;
}
Beispiel #28
0
static int idaapi hook_ui(void *user_data, int notification_code, va_list va)
{
	switch (notification_code)
	{
	case ui_notification_t::ui_get_custom_viewer_hint:
	{
		TCustomControl *viewer = va_arg(va, TCustomControl *);
		place_t *place = va_arg(va, place_t *);
		int *important_lines = va_arg(va, int *);
		qstring &hint = *va_arg(va, qstring *);

		if (place == NULL)
			return 0;

		int x, y;
		if (get_custom_viewer_place(viewer, true, &x, &y) == NULL)
			return 0;

		char buf[MAXSTR];
		const char *line = get_custom_viewer_curline(viewer, true);
		tag_remove(line, buf, sizeof(buf));
		if (x >= (int)strlen(buf))
			return 0;

		idaplace_t &pl = *(idaplace_t *)place;
		if (decode_insn(pl.ea) && dbg_started)
		{
			insn_t _cmd = cmd;

			int flags = calc_default_idaplace_flags();
			linearray_t ln(&flags);

			for (int i = 0; i < qnumber(_cmd.Operands); i++)
			{
				op_t op = _cmd.Operands[i];

				if (op.type != o_void)
				{
					switch (op.type)
					{
					case o_mem:
					case o_near:
					{
						idaplace_t here;
						here.ea = op.addr;
						here.lnnum = 0;

						ln.set_place(&here);

						hint.cat_sprnt((COLSTR(SCOLOR_INV"OPERAND#%d (ADDRESS: $%a)\n", SCOLOR_DREF)), op.n, op.addr);
						(*important_lines)++;

						int n = qmin(ln.get_linecnt(), 10);		   // how many lines for this address?
						(*important_lines) += n;
						for (int j = 0; j < n; ++j)
						{
							hint.cat_sprnt("%s\n", ln.down());
						}
					} break;
					case o_phrase:
					case o_reg:
					{
						regval_t reg;
						int reg_idx = idp_to_dbg_reg(op.reg);

						const char *reg_name = dbg->registers(reg_idx).name;
						if (get_reg_val(reg_name, &reg))
						{
							idaplace_t here;
							here.ea = (uint32)reg.ival;
							here.lnnum = 0;

							ln.set_place(&here);

							hint.cat_sprnt((COLSTR(SCOLOR_INV"OPERAND#%d (REGISTER: %s)\n", SCOLOR_DREF)), op.n, reg_name);
							(*important_lines)++;

							int n = qmin(ln.get_linecnt(), 10);		   // how many lines for this address?
							(*important_lines) += n;
							for (int j = 0; j < n; ++j)
							{
								hint.cat_sprnt("%s\n", ln.down());
							}
						}
					} break;
					case o_displ:
					{
						regval_t main_reg, add_reg;
						int main_reg_idx = idp_to_dbg_reg(op.reg);
						int add_reg_idx = idp_to_dbg_reg(op.specflag1 & 0xF);

						main_reg.ival = 0;
						add_reg.ival = 0;
						if (op.specflag2 & 0x10)
						{
							get_reg_val(dbg->registers(add_reg_idx).name, &add_reg);
							if (op.specflag1 & 0x10)
								add_reg.ival &= 0xFFFF;
						}

						if (main_reg_idx != R_PC)
							get_reg_val(dbg->registers(main_reg_idx).name, &main_reg);

						idaplace_t here;
						ea_t addr = (uint32)main_reg.ival + op.addr + (uint32)add_reg.ival; // TODO: displacements with PC and other regs unk_123(pc, d0.l); unk_111(d0, d2.w)
						here.ea = addr;
						here.lnnum = 0;

						ln.set_place(&here);

						hint.cat_sprnt((COLSTR(SCOLOR_INV"OPERAND#%d (DISPLACEMENT: [$%s%X($%X", SCOLOR_DREF)),
							op.n,
							((int)op.addr < 0) ? "-" : "", ((int)op.addr < 0) ? -(int)op.addr : op.addr,
							(uint32)main_reg.ival
							);

						if (op.specflag2 & 0x10)
							hint.cat_sprnt((COLSTR(",$%X", SCOLOR_DREF)), (uint32)add_reg.ival);

						hint.cat_sprnt((COLSTR(")])\n", SCOLOR_DREF)));

						(*important_lines)++;

						int n = qmin(ln.get_linecnt(), 10);		   // how many lines for this address?
						(*important_lines) += n;
						for (int j = 0; j < n; ++j)
						{
							hint.cat_sprnt("%s\n", ln.down());
						}
					} break;
					}
				}
			}

			return 1;
		}
	}
	default:
		return 0;
	}
}
Beispiel #29
0
int pt_insn_next(struct pt_insn_decoder *decoder, struct pt_insn *uinsn,
		 size_t size)
{
	struct pt_insn insn, *pinsn;
	int errcode, status;

	if (!uinsn || !decoder)
		return -pte_invalid;

	pinsn = size == sizeof(insn) ? uinsn : &insn;

	/* Zero-initialize the instruction in case of error returns. */
	memset(pinsn, 0, sizeof(*pinsn));

	/* We process events three times:
	 * - once based on the current IP.
	 * - once based on the instruction at that IP.
	 * - once based on the next IP.
	 *
	 * Between the first and second round of event processing, we decode
	 * the instruction and fill in @insn.
	 *
	 * This is necessary to attribute events to the correct instruction.
	 */
	errcode = process_events_before(decoder, pinsn);
	if (errcode < 0)
		goto err;

	/* If tracing is disabled at this point, we should be at the end
	 * of the trace - otherwise there should have been a re-enable
	 * event.
	 */
	if (!decoder->enabled) {
		struct pt_event event;

		/* Any query should give us an end of stream, error. */
		errcode = pt_qry_event(&decoder->query, &event, sizeof(event));
		if (errcode != -pte_eos)
			errcode = -pte_no_enable;

		goto err;
	}

	errcode = decode_insn(pinsn, decoder);
	if (errcode < 0)
		goto err;

	/* After decoding the instruction, we must not change the IP in this
	 * iteration - postpone processing of events that would to the next
	 * iteration.
	 */
	decoder->event_may_change_ip = 0;

	errcode = process_events_after(decoder, pinsn);
	if (errcode < 0)
		goto err;

	/* We return the decoder status for this instruction. */
	status = pt_insn_status(decoder);

	/* If event processing disabled tracing, we're done for this
	 * iteration - we will process the re-enable event on the next.
	 *
	 * Otherwise, we determine the next instruction and peek ahead.
	 *
	 * This may indicate an event already in this instruction.
	 */
	if (decoder->enabled) {
		/* Proceed errors are signaled one instruction too early. */
		errcode = proceed(decoder);
		if (errcode < 0)
			goto err;

		/* Peek errors are ignored.  We will run into them again
		 * in the next iteration.
		 */
		(void) process_events_peek(decoder, pinsn);
	}

	errcode = insn_to_user(uinsn, size, pinsn);
	if (errcode < 0)
		return errcode;

	/* We're done with this instruction.  Now we may change the IP again. */
	decoder->event_may_change_ip = 1;

	return status;

err:
	/* We provide the (incomplete) instruction also in case of errors.
	 *
	 * For decode or post-decode event-processing errors, the IP or
	 * other fields are already valid and may help diagnose the error.
	 */
	(void) insn_to_user(uinsn, size, pinsn);

	return errcode;
}
Beispiel #30
0
int dline_add(dline_t * dl, ea_t ea, char options)
{
	char buf[256];
	char tmp[256];
	char dis[256];
	char addr[30];
	char * dll;
	int len;
	flags_t f;

	buf[0] = '\0';

	f = getFlags(ea);
	generate_disasm_line(ea, dis, sizeof(dis));

	decode_insn(ea);
	init_output_buffer(buf, sizeof(buf));

	// Adds block label
	if (has_dummy_name(f))
	{
		get_nice_colored_name(ea,tmp,sizeof(tmp),GNCN_NOSEG|GNCN_NOFUNC);
		out_snprintf("%s", tmp);
		out_line(":\n", COLOR_DATNAME);
	}

	if (options)
	{
		qsnprintf(addr, sizeof(addr), "%a", ea);
		out_snprintf("%s ", addr);
	}

	out_insert(get_output_ptr(), dis);
	term_output_buffer();

	len = strlen(buf);

	if (dl->available < (len+3))
	{
		dll = (char *)qrealloc(dl->lines, sizeof(char*) * (dl->num+len+256));
		if (!dll) return -1;

		dl->available = len+256;
		dl->lines = dll;
	}

	if (dl->num)
	{
		dl->lines[dl->num] = '\n';
		dl->num++;
	}

	memcpy(&dl->lines[dl->num], buf, len);

	dl->available -= len+1;
	dl->num += len;

	dl->lines[dl->num] = '\0';

	return 0;
}