update to ida 7.6, add builds

This commit is contained in:
2021-10-31 21:20:46 +02:00
parent e0e0f2be99
commit b1809fe2d9
1408 changed files with 279193 additions and 302468 deletions

View File

@@ -0,0 +1,316 @@
/*
* Interactive disassembler (IDA)
* Copyright (c) 1990-98 by Ilfak Guilfanov.
* E-mail: ig@datarescue.com
* JVM module.
* Copyright (c) 1995-2006 by Iouri Kharon.
* E-mail: yjh@styx.cabel.net
*
* ALL RIGHTS RESERVED.
*
*/
#include "java.hpp"
static const char badlocvar[] = "Invalid local variable number";
//----------------------------------------------------------------------
uval_t java_t::SearchFM(ushort name, ushort dscr, char *naprN)
{
char buf[(qmax(sizeof(FieldInfo), sizeof(SegInfo))+1+3)&~3];
sval_t pos = curClass.FieldCnt;
uint32 csz = sizeof(FieldInfo);
sval_t napr = *naprN;
if ( napr != 1 )
{
if ( napr != -1 )
INTERNAL("SearchFM");
pos = -(uval_t)curClass.MethodCnt;
csz = sizeof(SegInfo);
}
void *p = buf;
for ( ; pos; pos -= napr )
{
if ( ClassNode.supval(pos, p, sizeof(buf)) != csz )
DESTROYED("SearchFM");
if ( ((_FMid_ *)p)->extflg & EFL_NAMETYPE
|| CmpString(name, ((_FMid_ *)p)->name)
|| CmpString(dscr, ((_FMid_ *)p)->dscr) )
{
continue;
}
if ( napr >= 0 )
return curClass.start_ea + ((FieldInfo *)p)->id.Number;
if ( ((SegInfo *)p)->CodeSize )
*naprN = 0;
return ((SegInfo *)p)->start_ea;
}
return BADADDR;
}
//------------------------------------------------------------------------
void java_t::mark_and_comment(ea_t ea, const char *cmt) const
{
remember_problem(PR_ATTN, ea);
if ( *cmt && (!has_cmt(get_flags(ea)) || ea == curClass.start_ea) )
append_cmt(ea, cmt, false);
}
//------------------------------------------------------------------------
void java_t::TouchArg(const insn_t &insn, const op_t &x, bool isload)
{
const char *p;
switch ( x.type )
{
case o_void: // not operand
break;
case o_cpool: // ConstantPool reference (index)
if ( x.ref )
{
p = x.ref == 1
? "Invalid string in constant pool"
: "Invalid index in constant pool";
goto mark;
}
if ( x.cp_ind )
{
ea_t ea;
char npr = -1;
switch ( (uchar)x.cp_type )
{
case CONSTANT_Fieldref:
npr = 1;
// fallthrough
case CONSTANT_InterfaceMethodref:
case CONSTANT_Methodref:
if ( !(x._subnam | x._name | x._class) )
break;
if ( x._class == curClass.This.Dscr )
{
ea = SearchFM(x._subnam, x._dscr, &npr);
if ( ea == BADADDR )
break;
}
else
{
if ( !insn.xtrn_ip )
break;
ea = insn.xtrn_ip == 0xFFFF
? curClass.start_ea
: curClass.xtrnEA + insn.xtrn_ip;
if ( npr < 0 )
npr = 0;
}
if ( npr <= 0 )
{
insn.add_cref(ea, x.offb, fl_CF);
if ( !npr )
auto_cancel(ea, ea+1);
}
else
{
dref_t type = insn.itype == j_putstatic || insn.itype == j_putfield
? dr_W
: dr_R;
insn.add_dref(ea, x.offb, type);
}
break;
case CONSTANT_Class:
if ( insn.xtrn_ip )
{
ea_t target = insn.xtrn_ip == 0xFFFF
? curClass.start_ea
: curClass.xtrnEA + insn.xtrn_ip;
insn.add_dref(target, x.offb, dr_I);
}
break;
default:
break;
}
}
break;
case o_array: // type!
if ( x.ref )
{
p = "Invalid array type";
goto mark;
}
break;
case o_imm: // const (& #data)
if ( x.ref < 2 )
set_immd(insn.ea);
break;
case o_mem: // local data pool
if ( x.ref )
{
p = badlocvar;
mark:
mark_and_comment(insn.ea, p);
}
else
{
dref_t ref = isload ? dr_R : dr_W;
ea_t adr = curSeg.DataBase + x.addr;
insn.add_dref(adr, x.offb, ref);
if ( (x.dtype == dt_qword || x.dtype == dt_double)
&& get_item_size(adr) <= 1 )
{
insn.add_dref(adr + 1, x.offb, ref);
}
}
break;
case o_near:
if ( x.ref )
{
p = "Invalid jump address";
goto mark;
}
insn.add_cref(
curSeg.start_ea + x.addr,
x.offb,
(Feature & CF_CALL) != 0 ? fl_CN : fl_JN);
break;
default:
warning("%a: %s,%d: bad optype %d", insn.ea, insn.get_canon_mnem(ph), x.n,
x.type);
break;
}
}
//----------------------------------------------------------------------
int java_t::emu(const insn_t &insn)
{
Feature = insn.get_canon_feature(ph);
if ( insn.wid > 1 )
mark_and_comment(insn.ea, "Limited usage instruction");
if ( insn.itype >= j_a_software )
mark_and_comment(insn.ea, "Undocumented instruction");
if ( insn.Op1.type == o_void && insn.Op1.ref )
{
if ( (char)insn.Op1.ref < 0 )
{
mark_and_comment(insn.ea, badlocvar);
}
else
{
dref_t ref = (insn.itype >= j_istore_0) ? dr_W : dr_R;
insn.add_dref(insn.Op1.addr, 0, ref);
if ( (insn.Op1.ref & 2) && get_item_size(insn.Op1.addr) <= 1 )
insn.add_dref(insn.Op1.addr + 1, 0, ref);
}
}
if ( Feature & CF_USE1 )
TouchArg(insn, insn.Op1, true);
if ( Feature & CF_USE2 )
TouchArg(insn, insn.Op2, true);
if ( Feature & CF_USE3 )
TouchArg(insn, insn.Op3, true);
if ( Feature & CF_CHG1 )
TouchArg(insn, insn.Op1, false);
if ( insn.swit ) // tableswitch OR lookupswitch
{
uval_t count, addr, rnum;
if ( insn.swit & 0200 )
mark_and_comment(insn.ea, badlocvar);
if ( insn.swit & 0100 )
mark_and_comment(insn.ea, "Nonzero filler (warning)");
rnum = insn.Op2.value - 1; // for lookupswtitch
for ( addr=insn.Op2.addr, count=insn.Op3.value; count; addr +=4, count-- )
{
uval_t refa;
if ( insn.itype != j_lookupswitch )
{
++rnum;
}
else
{
rnum = get_dword(curSeg.start_ea + addr); // skip pairs
addr += 4;
}
refa = insn.ip + get_dword(curSeg.start_ea + addr);
if ( refa < curSeg.CodeSize )
{
add_cref(insn.ea, (refa += curSeg.start_ea), fl_JN);
if ( !has_cmt(get_flags(refa)) )
{
char str[32];
qsnprintf(str, sizeof(str), "case %" FMT_EA "u", rnum);
set_cmt(refa, str, false);
}
}
}
}
if ( !(Feature&CF_STOP) && (!(Feature&CF_CALL) || func_does_return(insn.ea)) )
add_cref(insn.ea, insn.ea + insn.size, fl_F);
return 1;
}
//----------------------------------------------------------------------
size_t java_t::make_locvar_cmt(qstring *buf, const insn_t &insn)
{
LocVar lv;
if ( curSeg.varNode )
{
const char *p = NULL;
uval_t idx = insn.Op1.addr;
if ( insn.Op1.type == o_mem )
{
if ( !insn.Op1.ref )
{
switch ( insn.itype )
{
case j_ret:
p = "Return";
break;
case j_iinc:
p = "Add 8-bit signed const to";
break;
default:
p = "Push";
if ( insn.get_canon_feature(ph) & CF_CHG1 )
p = "Pop";
break;
}
}
}
else if ( insn.Op1.type == o_void
&& (char)insn.Op1.ref >= 0
&& (int32)(idx -= curSeg.DataBase) >= 0 )
{
p = "Push";
if ( insn.itype >= j_istore_0 )
p = "Pop";
}
if ( p != NULL && netnode(curSeg.varNode).supval(idx,&lv,sizeof(lv)) == sizeof(lv) )
{
if ( fmtName(lv.var.Name, tmp_name, sizeof(tmp_name), fmt_UnqualifiedName) )
return buf->sprnt("%s %s", p, tmp_name).length();
}
}
return 0;
}