Fix #5472 - ds on call and jmp (#5785)

This commit is contained in:
saucec0de 2016-09-18 21:41:15 +02:00 committed by radare
parent f9b70631b2
commit 6ccc045526
3 changed files with 46 additions and 19 deletions

View File

@ -1978,8 +1978,13 @@ static void anop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len, csh
op->jump = UT64_MAX;
op->ptr = INSOP (0).mem.disp;
op->disp = INSOP (0).mem.disp;
op->reg = NULL;
op->ireg = NULL;
if (INSOP (0).mem.index == X86_REG_INVALID) {
op->ireg = NULL;
if (INSOP (0).mem.base != X86_REG_INVALID) {
op->reg = cs_reg_name (*handle, INSOP (0).mem.base);
op->type = R_ANAL_OP_TYPE_IRCALL;
}
} else {
op->ireg = cs_reg_name (*handle, INSOP (0).mem.index);
op->scale = INSOP(0).mem.scale;
@ -1989,6 +1994,11 @@ static void anop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len, csh
op->refptr = 8;
}
break;
case X86_OP_REG:
op->reg = cs_reg_name (*handle, INSOP (0).reg);
op->type = R_ANAL_OP_TYPE_RCALL;
op->ptr = UT64_MAX;
break;
default:
op->type = R_ANAL_OP_TYPE_UCALL;
op->jump = UT64_MAX;
@ -2008,8 +2018,13 @@ static void anop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len, csh
op->type = R_ANAL_OP_TYPE_MJMP;
op->ptr = INSOP (0).mem.disp;
op->disp = INSOP (0).mem.disp;
op->reg = NULL;
op->ireg = NULL;
if (INSOP (0).mem.index == X86_REG_INVALID) {
op->ireg = NULL;
if (INSOP (0).mem.base != X86_REG_INVALID) {
op->reg = cs_reg_name (*handle, INSOP (0).mem.base);
op->type = R_ANAL_OP_TYPE_IRJMP;
}
} else {
op->ireg = cs_reg_name (*handle, INSOP (0).mem.index);
op->scale = INSOP (0).mem.scale;
@ -2022,7 +2037,7 @@ static void anop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len, csh
case X86_OP_REG:
{
op->reg = cs_reg_name (gop.handle, INSOP(0).reg);
op->type = R_ANAL_OP_TYPE_UJMP;
op->type = R_ANAL_OP_TYPE_RJMP;
op->ptr = UT64_MAX;
}
break;

View File

@ -682,18 +682,8 @@ R_API int r_debug_step_soft(RDebug *dbg) {
next[1] = op.fail;
br = 2;
break;
case R_ANAL_OP_TYPE_MJMP:
if (!op.ireg) {
next[0] = op.jump;
} else {
r = r_debug_reg_get (dbg,op.ireg);
if (dbg->iob.read_at (dbg->iob.io,
r*op.scale + op.disp, (ut8*)&memval, 8) <0 ) {
next[0] = op.addr + op.size;
} else {
next[0] = (dbg->bits == R_SYS_BITS_32) ? memval.r32[0] : memval.r64;
}
}
case R_ANAL_OP_TYPE_UJMP:
next[0] = op.addr + op.size;
br = 1;
break;
case R_ANAL_OP_TYPE_CALL:
@ -701,7 +691,24 @@ R_API int r_debug_step_soft(RDebug *dbg) {
next[0] = op.jump;
br = 1;
break;
case R_ANAL_OP_TYPE_RJMP:
case R_ANAL_OP_TYPE_RCALL:
r = r_debug_reg_get (dbg,op.reg);
next[0] = r;
br = 1;
break;
case R_ANAL_OP_TYPE_IRCALL:
case R_ANAL_OP_TYPE_IRJMP:
r = r_debug_reg_get (dbg,op.reg);
if (dbg->iob.read_at (dbg->iob.io, r, (ut8*)&memval, 8) <0 ) {
next[0] = op.addr + op.size;
} else {
next[0] = (dbg->bits == R_SYS_BITS_32) ? memval.r32[0] : memval.r64;
}
br = 1;
break;
case R_ANAL_OP_TYPE_UCALL:
case R_ANAL_OP_TYPE_MJMP:
if (op.ireg) {
r = r_debug_reg_get (dbg,op.ireg);
} else {
@ -860,10 +867,7 @@ R_API int r_debug_step_over(RDebug *dbg, int steps) {
ins_size = op.fail;
}
// Skip over all the subroutine calls
if (op.type == R_ANAL_OP_TYPE_CALL ||
op.type == R_ANAL_OP_TYPE_CCALL ||
op.type == R_ANAL_OP_TYPE_UCALL ||
op.type == R_ANAL_OP_TYPE_UCCALL) {
if (op.type & R_ANAL_OP_TYPE_CALL == R_ANAL_OP_TYPE_CALL) {
if (!r_debug_continue_until (dbg, ins_size)) {
eprintf ("Could not step over call @ 0x%"PFMT64x"\n", pc);
return steps_taken;

View File

@ -362,13 +362,21 @@ typedef enum {
//TODO: MOVE TO PREFIX .. it is used by anal_ex.. must be updated
R_ANAL_OP_TYPE_REP = 0x40000000, /* repeats next instruction N times */
R_ANAL_OP_TYPE_MEM = 0x20000000, // TODO must be moved to prefix?
R_ANAL_OP_TYPE_REG = 0x10000000, // operand is a register
R_ANAL_OP_TYPE_IND = 0x08000000, // operand is indirect
R_ANAL_OP_TYPE_NULL = 0,
R_ANAL_OP_TYPE_JMP = 1, /* mandatory jump */
R_ANAL_OP_TYPE_RJMP = R_ANAL_OP_TYPE_REG | R_ANAL_OP_TYPE_JMP,
R_ANAL_OP_TYPE_IJMP = R_ANAL_OP_TYPE_IND | R_ANAL_OP_TYPE_JMP,
R_ANAL_OP_TYPE_IRJMP = R_ANAL_OP_TYPE_IND | R_ANAL_OP_TYPE_REG | R_ANAL_OP_TYPE_JMP,
R_ANAL_OP_TYPE_UJMP = 2, /* unknown jump (register or so) */
R_ANAL_OP_TYPE_CJMP = R_ANAL_OP_TYPE_COND | R_ANAL_OP_TYPE_JMP, /* conditional jump */
R_ANAL_OP_TYPE_MJMP = R_ANAL_OP_TYPE_MEM | R_ANAL_OP_TYPE_JMP, /* conditional jump */
R_ANAL_OP_TYPE_UCJMP = R_ANAL_OP_TYPE_COND | R_ANAL_OP_TYPE_UJMP, /* conditional unknown jump */
R_ANAL_OP_TYPE_CALL = 3, /* call to subroutine (branch+link) */
R_ANAL_OP_TYPE_RCALL = R_ANAL_OP_TYPE_REG | R_ANAL_OP_TYPE_CALL,
R_ANAL_OP_TYPE_ICALL = R_ANAL_OP_TYPE_IND | R_ANAL_OP_TYPE_CALL,
R_ANAL_OP_TYPE_IRCALL= R_ANAL_OP_TYPE_IND | R_ANAL_OP_TYPE_REG | R_ANAL_OP_TYPE_CALL,
R_ANAL_OP_TYPE_UCALL = 4, /* unknown call (register or so) */
R_ANAL_OP_TYPE_CCALL = R_ANAL_OP_TYPE_COND | R_ANAL_OP_TYPE_CALL, /* conditional call to subroutine */
R_ANAL_OP_TYPE_UCCALL= R_ANAL_OP_TYPE_COND | R_ANAL_OP_TYPE_UCALL, /* conditional unknown call */