Fix several OOB reads (#6462)

* Fix OOB read for v810
* Fix heap buffer overflows for jvm
* Fix shadowed len and heap buffer overflow for 6502
* Fix OOB reads for i8080
* 6502_test
* NULL field
* Convert asserts to simple returns.
* Fix tests
This commit is contained in:
Rot127 2026-06-05 18:37:25 +00:00 committed by GitHub
parent 7362637334
commit 14b250b478
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 260 additions and 14 deletions

View file

@ -146,8 +146,8 @@ int disass_6502(ut64 pc, RzAsmOp *op, const ut8 *buf, ut64 len) {
continue;
}
int len = ops[i].len;
switch (len) {
int ops_len = ops[i].len;
switch (ops_len) {
case 1:
rz_asm_op_set_asm(op, ops[i].name);
break;
@ -156,7 +156,7 @@ int disass_6502(ut64 pc, RzAsmOp *op, const ut8 *buf, ut64 len) {
rz_asm_op_setf_asm(op, ops[i].name, buf[1]);
} else {
rz_asm_op_set_asm(op, "truncated");
len = -1;
ops_len = -1;
}
break;
case 3:
@ -164,7 +164,7 @@ int disass_6502(ut64 pc, RzAsmOp *op, const ut8 *buf, ut64 len) {
rz_asm_op_setf_asm(op, ops[i].name, buf[1] + 0x100 * buf[2]);
} else {
rz_asm_op_set_asm(op, "truncated");
len = -1;
ops_len = -1;
}
break;
case 4:
@ -172,14 +172,14 @@ int disass_6502(ut64 pc, RzAsmOp *op, const ut8 *buf, ut64 len) {
rz_asm_op_setf_asm(op, ops[i].name, buf[1] + 0x100 * buf[2] + 0x10000 * buf[3]);
} else {
rz_asm_op_set_asm(op, "truncated");
len = -1;
ops_len = -1;
}
break;
default:
rz_asm_op_set_asm(op, "invalid");
goto beach;
}
return len;
return ops_len;
}
beach:
return snesDisass(1, 1, pc, op, buf, len);

View file

@ -124,6 +124,9 @@ static void arg(char *s, int const cmd, struct arg_t const *arg, int val) {
}
int i8080_disasm(unsigned char const *const code, char *text, int text_sz) {
if (text_sz < 3) {
return -1;
}
int const cmd = code[0];
int const p = code[1] | (code[2] << 8);

View file

@ -60,7 +60,7 @@ static inline ut32 align_upper(JavaVM *jvm) {
static bool decode_lookupswitch(JavaVM *jvm, Bytecode *bytecode) {
ut32 offset = jvm->current + align_upper(jvm);
if ((jvm->size - offset) < 8) {
if (((ssize_t)jvm->size - (ssize_t)offset) < 8) {
return false;
}
ut32 pc_default = rz_read_at_be32(jvm->buffer, offset);
@ -88,8 +88,7 @@ static bool decode_lookupswitch(JavaVM *jvm, Bytecode *bytecode) {
static bool decode_tableswitch(JavaVM *jvm, Bytecode *bytecode) {
ut32 offset = jvm->current + align_upper(jvm) + 1;
if ((jvm->size - offset) < 12) {
rz_warn_if_reached();
if (((ssize_t)jvm->size - (ssize_t)offset) < 12) {
return false;
}
@ -1224,7 +1223,6 @@ static bool decode_instruction(JavaVM *jvm, Bytecode *bytecode) {
case BYTECODE_AA_TABLESWITCH:
strcpy(bytecode->name, "tableswitch");
if (!decode_tableswitch(jvm, bytecode)) {
rz_warn_if_reached();
return false;
}
bytecode->atype = RZ_ANALYSIS_OP_TYPE_CJMP;
@ -1233,7 +1231,6 @@ static bool decode_instruction(JavaVM *jvm, Bytecode *bytecode) {
case BYTECODE_AB_LOOKUPSWITCH:
strcpy(bytecode->name, "lookupswitch");
if (!decode_lookupswitch(jvm, bytecode)) {
rz_warn_if_reached();
return false;
}
bytecode->atype = RZ_ANALYSIS_OP_TYPE_CJMP;

View file

@ -20,6 +20,9 @@ int snesDisass(int M_flag, int X_flag, ut64 pc, RzAsmOp *op, const ut8 *buf, int
rz_asm_op_set_asm(op, s_op->name);
break;
case SNES_OP_16BIT:
if (len < 2) {
return 0;
}
if (*buf % 0x20 == 0x10 || *buf == 0x80) { // relative branch
rz_asm_op_setf_asm(op, s_op->name, (ut32)(pc + 2 + (st8)buf[1]));
} else {
@ -27,6 +30,9 @@ int snesDisass(int M_flag, int X_flag, ut64 pc, RzAsmOp *op, const ut8 *buf, int
}
break;
case SNES_OP_24BIT:
if (len < 3) {
return 0;
}
if (*buf == 0x44 || *buf == 0x54) { // mvp and mvn
rz_asm_op_setf_asm(op, s_op->name, buf[1], buf[2]);
} else if (*buf == 0x82) { // brl
@ -36,19 +42,36 @@ int snesDisass(int M_flag, int X_flag, ut64 pc, RzAsmOp *op, const ut8 *buf, int
}
break;
case SNES_OP_32BIT:
if (len < 4) {
return 0;
}
rz_asm_op_setf_asm(op, s_op->name, buf[1] | buf[2] << 8 | buf[3] << 16);
break;
case SNES_OP_IMM_M:
if (M_flag) {
if (len < 2) {
return 0;
}
rz_asm_op_setf_asm(op, "%s #0x%02x", s_op->name, buf[1]);
} else {
if (len < 1) {
return 0;
}
rz_asm_op_setf_asm(op, "%s #0x%04x", s_op->name, rz_read_le16(buf + 1));
}
break;
case SNES_OP_IMM_X:
if (X_flag) {
if (len < 2) {
rz_asm_op_set_asm(op, "invalid");
break;
}
rz_asm_op_setf_asm(op, "%s #0x%02x", s_op->name, buf[1]);
} else {
if (len < 3) {
rz_asm_op_set_asm(op, "invalid");
break;
}
rz_asm_op_setf_asm(op, "%s #0x%04x", s_op->name, rz_read_le16(buf + 1));
}
break;

View file

@ -266,6 +266,9 @@ static int decode_bit_op(const ut16 instr, struct v810_cmd *cmd) {
ut8 subop;
subop = REG1(instr);
if (subop >= RZ_ARRAY_SIZE(bit_instrs)) {
return 0;
}
snprintf(cmd->instr, V810_INSTR_MAXLEN - 1, "%s", bit_instrs[subop]);
return 2;

View file

@ -448,6 +448,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->cycles = 5;
op->size = 2;
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
if (op->size > len) {
goto oob_read;
}
_6502ILAddr addr;
_6502_il_addr_absolute(&addr, data[1]);
op->il_op = _6502_il_op_slo(&addr);
@ -457,6 +460,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_SHL | RZ_ANALYSIS_OP_TYPE_OR;
op->cycles = 6;
op->size = 2;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_zero_page_reg(&addr, data[1], "x");
@ -467,6 +473,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_SHL | RZ_ANALYSIS_OP_TYPE_OR;
op->cycles = 8;
op->size = 2;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_indirect_x(&addr, data[1]);
@ -477,6 +486,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_SHL | RZ_ANALYSIS_OP_TYPE_OR;
op->cycles = 8;
op->size = 2;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_indirect_y(&addr, data[1]);
@ -487,6 +499,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_SHL | RZ_ANALYSIS_OP_TYPE_OR;
op->cycles = 6;
op->size = 3;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_absolute(&addr, data[1] | data[2] << 8);
@ -497,6 +512,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_SHL | RZ_ANALYSIS_OP_TYPE_OR;
op->cycles = 7;
op->size = 3;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_reg(&addr, data[1] | data[2] << 8, "x");
@ -507,6 +525,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_SHL | RZ_ANALYSIS_OP_TYPE_OR;
op->cycles = 7;
op->size = 3;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_reg(&addr, data[1] | data[2] << 8, "y");
@ -518,6 +539,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_ROL | RZ_ANALYSIS_OP_TYPE_AND;
op->cycles = 5;
op->size = 2;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_absolute(&addr, data[1]);
@ -528,6 +552,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_ROL | RZ_ANALYSIS_OP_TYPE_AND;
op->cycles = 6;
op->size = 2;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_zero_page_reg(&addr, data[1], "x");
@ -538,6 +565,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_ROL | RZ_ANALYSIS_OP_TYPE_AND;
op->cycles = 8;
op->size = 2;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_indirect_x(&addr, data[1]);
@ -548,6 +578,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_ROL | RZ_ANALYSIS_OP_TYPE_AND;
op->cycles = 8;
op->size = 2;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_indirect_y(&addr, data[1]);
@ -558,6 +591,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_ROL | RZ_ANALYSIS_OP_TYPE_AND;
op->cycles = 6;
op->size = 3;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_absolute(&addr, data[1] | data[2] << 8);
@ -568,6 +604,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_ROL | RZ_ANALYSIS_OP_TYPE_AND;
op->cycles = 7;
op->size = 3;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_reg(&addr, data[1] | data[2] << 8, "y");
@ -578,6 +617,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_ROL | RZ_ANALYSIS_OP_TYPE_AND;
op->cycles = 7;
op->size = 3;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_reg(&addr, data[1] | data[2] << 8, "x");
@ -590,6 +632,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_SHR | RZ_ANALYSIS_OP_TYPE_OR;
op->cycles = 5;
op->size = 2;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_absolute(&addr, data[1]);
@ -600,6 +645,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_SHR | RZ_ANALYSIS_OP_TYPE_OR;
op->cycles = 6;
op->size = 2;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_zero_page_reg(&addr, data[1], "x");
@ -610,6 +658,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_SHR | RZ_ANALYSIS_OP_TYPE_OR;
op->cycles = 8;
op->size = 2;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_indirect_x(&addr, data[1]);
@ -620,6 +671,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_SHR | RZ_ANALYSIS_OP_TYPE_OR;
op->cycles = 8;
op->size = 2;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_indirect_y(&addr, data[1]);
@ -630,6 +684,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_SHR | RZ_ANALYSIS_OP_TYPE_OR;
op->cycles = 6;
op->size = 3;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_absolute(&addr, data[1] | data[2] << 8);
@ -640,6 +697,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_SHR | RZ_ANALYSIS_OP_TYPE_OR;
op->cycles = 7;
op->size = 3;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_reg(&addr, data[1] | data[2] << 8, "y");
@ -650,6 +710,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_SHR | RZ_ANALYSIS_OP_TYPE_OR;
op->cycles = 7;
op->size = 3;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_reg(&addr, data[1] | data[2] << 8, "x");
@ -662,6 +725,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_ROR | RZ_ANALYSIS_OP_TYPE_AND;
op->cycles = 5;
op->size = 2;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_absolute(&addr, data[1]);
@ -672,6 +738,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_ROR | RZ_ANALYSIS_OP_TYPE_AND;
op->cycles = 6;
op->size = 2;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_zero_page_reg(&addr, data[1], "x");
@ -682,6 +751,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_ROR | RZ_ANALYSIS_OP_TYPE_AND;
op->cycles = 8;
op->size = 2;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_indirect_x(&addr, data[1]);
@ -692,6 +764,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_ROR | RZ_ANALYSIS_OP_TYPE_AND;
op->cycles = 8;
op->size = 2;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_indirect_y(&addr, data[1]);
@ -702,6 +777,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_ROR | RZ_ANALYSIS_OP_TYPE_AND;
op->cycles = 6;
op->size = 3;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_absolute(&addr, data[1] | data[2] << 8);
@ -712,6 +790,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_ROR | RZ_ANALYSIS_OP_TYPE_AND;
op->cycles = 7;
op->size = 3;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_reg(&addr, data[1] | data[2] << 8, "x");
@ -722,6 +803,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_ROR | RZ_ANALYSIS_OP_TYPE_AND;
op->cycles = 7;
op->size = 3;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_reg(&addr, data[1] | data[2] << 8, "y");
@ -734,6 +818,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_AND;
op->cycles = 3;
op->size = 2;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_absolute(&addr, data[1]);
@ -744,6 +831,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_AND;
op->cycles = 4;
op->size = 2;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_zero_page_reg(&addr, data[1], "y");
@ -754,6 +844,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_AND;
op->cycles = 6;
op->size = 2;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_indirect_x(&addr, data[1]);
@ -764,6 +857,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_AND;
op->cycles = 4;
op->size = 3;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_absolute(&addr, data[1] | data[2] << 8);
@ -776,6 +872,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_LOAD;
op->cycles = 3;
op->size = 2;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_absolute(&addr, data[1]);
@ -786,6 +885,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_LOAD;
op->cycles = 4;
op->size = 2;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_zero_page_reg(&addr, data[1], "y");
@ -796,6 +898,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_LOAD;
op->cycles = 6;
op->size = 2;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_indirect_x(&addr, data[1]);
@ -807,6 +912,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->cycles = 5;
op->failcycles = 6;
op->size = 2;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_indirect_y(&addr, data[1]);
@ -817,6 +925,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_LOAD;
op->cycles = 4;
op->size = 3;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_absolute(&addr, data[1] | data[2] << 8);
@ -828,6 +939,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->cycles = 4;
op->failcycles = 5;
op->size = 3;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_reg(&addr, data[1] | data[2] << 8, "y");
@ -838,6 +952,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_AND | RZ_ANALYSIS_OP_TYPE_OR;
op->cycles = 2;
op->size = 2;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_immediate(&addr, data[1]);
@ -850,6 +967,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_CMP | RZ_ANALYSIS_OP_TYPE_STORE;
op->cycles = 5;
op->size = 2;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_absolute(&addr, data[1]);
@ -860,6 +980,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_CMP | RZ_ANALYSIS_OP_TYPE_STORE;
op->cycles = 6;
op->size = 2;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_zero_page_reg(&addr, data[1], "x");
@ -870,6 +993,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_CMP | RZ_ANALYSIS_OP_TYPE_STORE;
op->cycles = 8;
op->size = 2;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_indirect_x(&addr, data[1]);
@ -880,6 +1006,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_CMP | RZ_ANALYSIS_OP_TYPE_STORE;
op->cycles = 8;
op->size = 2;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_indirect_y(&addr, data[1]);
@ -890,6 +1019,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_CMP | RZ_ANALYSIS_OP_TYPE_STORE;
op->cycles = 6;
op->size = 3;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_absolute(&addr, data[1] | data[2] << 8);
@ -900,6 +1032,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_CMP | RZ_ANALYSIS_OP_TYPE_STORE;
op->cycles = 7;
op->size = 3;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_reg(&addr, data[1] | data[2] << 8, "x");
@ -910,6 +1045,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_CMP | RZ_ANALYSIS_OP_TYPE_STORE;
op->cycles = 7;
op->size = 3;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_reg(&addr, data[1] | data[2] << 8, "y");
@ -922,6 +1060,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_STORE | RZ_ANALYSIS_OP_TYPE_SUB;
op->cycles = 5;
op->size = 2;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_absolute(&addr, data[1]);
@ -932,6 +1073,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_STORE | RZ_ANALYSIS_OP_TYPE_SUB;
op->cycles = 6;
op->size = 2;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_zero_page_reg(&addr, data[1], "x");
@ -942,6 +1086,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_STORE | RZ_ANALYSIS_OP_TYPE_SUB;
op->cycles = 8;
op->size = 2;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_indirect_x(&addr, data[1]);
@ -952,6 +1099,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_STORE | RZ_ANALYSIS_OP_TYPE_SUB;
op->cycles = 8;
op->size = 2;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_indirect_y(&addr, data[1]);
@ -962,6 +1112,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_STORE | RZ_ANALYSIS_OP_TYPE_SUB;
op->cycles = 6;
op->size = 3;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_absolute(&addr, data[1] | data[2] << 8);
@ -972,6 +1125,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_STORE | RZ_ANALYSIS_OP_TYPE_SUB;
op->cycles = 7;
op->size = 3;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_reg(&addr, data[1], "x");
@ -982,6 +1138,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_STORE | RZ_ANALYSIS_OP_TYPE_SUB;
op->cycles = 7;
op->size = 3;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_reg(&addr, data[1], "y");
@ -994,6 +1153,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_AND;
op->cycles = 2;
op->size = 2;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_immediate(&addr, data[1]);
@ -1005,6 +1167,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_AND | RZ_ANALYSIS_OP_TYPE_SHR;
op->cycles = 2;
op->size = 2;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_immediate(&addr, data[1]);
@ -1016,6 +1181,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_AND | RZ_ANALYSIS_OP_TYPE_ROR;
op->cycles = 2;
op->size = 2;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_immediate(&addr, data[1]);
@ -1027,6 +1195,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->type = RZ_ANALYSIS_OP_TYPE_CMP | RZ_ANALYSIS_OP_TYPE_STORE;
op->cycles = 2;
op->size = 2;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_immediate(&addr, data[1]);
@ -1039,6 +1210,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
op->cycles = 4;
op->failcycles = 5;
op->size = 3;
if (op->size > len) {
goto oob_read;
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
_6502_il_addr_reg(&addr, data[1] | data[2] << 8, "y");
@ -1060,6 +1234,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
case 0xf2:
op->type = RZ_ANALYSIS_OP_TYPE_UNK;
op->size = 1;
if (op->size > len) {
goto oob_read;
}
op->eob = true;
// data = NEG(0);
// addrbuf = NEG(0);
@ -1072,6 +1249,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
case 0x93: // sha ($ff),y
op->type = RZ_ANALYSIS_OP_TYPE_STORE;
op->size = 2;
if (op->size > len) {
goto oob_read;
}
op->cycles = 6;
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
@ -1082,6 +1262,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
case 0x9f: // sha $ffff,y
op->type = RZ_ANALYSIS_OP_TYPE_STORE;
op->size = 3;
if (op->size > len) {
goto oob_read;
}
op->cycles = 6;
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
@ -1094,6 +1277,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
case 0x9e: // shx $ffff,y
op->type = RZ_ANALYSIS_OP_TYPE_STORE;
op->size = 3;
if (op->size > len) {
goto oob_read;
}
op->cycles = 5;
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
@ -1105,6 +1291,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
case 0x9c: // shy $ffff,x
op->type = RZ_ANALYSIS_OP_TYPE_STORE;
op->size = 3;
if (op->size > len) {
goto oob_read;
}
op->cycles = 5;
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
@ -1116,6 +1305,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
case 0x9b: // tas $ffff,y
op->type = RZ_ANALYSIS_OP_TYPE_STORE;
op->size = 3;
if (op->size > len) {
goto oob_read;
}
op->cycles = 5;
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
@ -1127,6 +1319,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
case 0x8b: // ane #$ff
op->type = RZ_ANALYSIS_OP_TYPE_AND | RZ_ANALYSIS_OP_TYPE_OR;
op->size = 2;
if (op->size > len) {
goto oob_read;
}
op->cycles = 2;
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
_6502ILAddr addr;
@ -1488,6 +1683,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
case 0xb0: // bcs $ffff
case 0xd0: // bne $ffff
case 0xf0: // beq $ffff
if (len < 2) {
goto oob_read;
}
op->cycles = 3;
op->failcycles = 4;
op->type = RZ_ANALYSIS_OP_TYPE_CJMP;
@ -1510,6 +1708,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
break;
// JSR
case 0x20: // jsr $ffff
if (len < 3) {
goto oob_read;
}
op->cycles = 6;
op->type = RZ_ANALYSIS_OP_TYPE_CALL;
op->jump = (len > 2) ? data[1] | data[2] << 8 : 0;
@ -1525,6 +1726,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
break;
// JMP
case 0x4c: // jmp $ffff
if (len < 3) {
goto oob_read;
}
op->cycles = 3;
op->type = RZ_ANALYSIS_OP_TYPE_JMP;
op->jump = (len > 2) ? data[1] | data[2] << 8 : 0;
@ -1534,6 +1738,9 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
}
break;
case 0x6c: { // jmp ($ffff)
if (len < 3) {
goto oob_read;
}
op->cycles = 5;
op->type = RZ_ANALYSIS_OP_TYPE_UJMP;
ut16 imm = len > 2 ? data[1] | data[2] << 8 : 0;
@ -1810,6 +2017,10 @@ static int _6502_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
break;
}
return op->size;
oob_read:
RZ_FREE(op->mnemonic);
return 0;
}
static char *_6502_get_reg_profile(RzAnalysis *analysis) {
@ -1897,4 +2108,4 @@ RzAnalysisPlugin rz_analysis_plugin_6502 = {
.esil_init = _6502_esil_init,
.il_config = _6502_il_config,
.archinfo = _6502_archinfo,
};
};

View file

@ -13,6 +13,9 @@
#include "i8080/i8080dis.h"
static int i8080_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *data, int len, RzAnalysisOpMask mask) {
if (len < 1) {
return -1;
}
char out[32];
int ilen = i8080_disasm(data, out, len);
op->addr = addr;

View file

@ -244,4 +244,6 @@ d "nop 0x42,x" 3442 0x0 nop
d "nop 0x42,x" 5442 0x0 nop
d "nop 0x42,x" 7442 0x0 nop
d "nop 0x42,x" d442 0x0 nop
d "nop 0x42,x" f442 0x0 nop
d "nop 0x42,x" f442 0x0 nop
d "invalid" ff 0x0
d "invalid" bb 0x0

2
test/db/asm/i8080 Normal file
View file

@ -0,0 +1,2 @@
d "invalid" 00

View file

@ -237,4 +237,5 @@ ad "sastore" 56
ad "sipush 100" 110064
ad "sipush 511" 1101ff
ad "swap" 5f
ad "wide" c4
d "invalid" aa
d "invalid" ab

View file

@ -55,3 +55,4 @@ d "cvt.sw r10, r11" 6af9000c 0x0 (seq (set r11 (fcast_sint 32 rne (float 0 (var
d "subf.s r15, r30" cffb0014 0x0 (seq (set result (-. rne (float 0 (var r30) ) (float 0 (var r15) ))) (set PSW (| (| (| (| (| (<< (ite (! (is_fpos (var result))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x3) false) (<< (ite false (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false)) (<< (ite (&& (! (|| (is_nan (var result)) (is_nan (float 0 (bv 32 0x0) )))) (<. (var result) (float 0 (bv 32 0x0) ))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_fzero (var result)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false)) (<< (ite (|| (is_nan (var result)) (is_inf (var result))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x9) false)) (<< (ite (is_fzero (float 0 (var r15) )) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x7) false))) (set r30 (fbits (var result))))
d "rev r15, r10" 4ff90028 0x0 nop
d "xb r11" 60f90020 0x0 nop
d "invalid" 107c 0x0