Fixing coverity issues and a potential buffer overflow in bb->op_bytes

This commit is contained in:
Adam Pridgen 2014-01-06 19:02:52 -06:00 committed by pancake
parent 3e3092ac09
commit efcad51646
4 changed files with 57 additions and 262 deletions

View File

@ -28,8 +28,8 @@ ut64 extract_unknown_op(ut64 ranal2_op_type);
ut64 extract_bin_op(ut64 ranal2_op_type);
static void r_anal_ex_perform_pre_anal(RAnal *anal, RAnalState *state, ut64 addr) {
if (anal->cur && anal->cur->pre_anal) {
static void r_anal_ex_perform_pre_anal(RAnal *anal, RAnalState *state, ut64 addr) {
if (anal->cur && anal->cur->pre_anal) {
anal->cur->pre_anal (anal, state, addr);
}
}
@ -77,9 +77,9 @@ static void r_anal_ex_perform_post_anal(RAnal *anal, RAnalState *state, ut64 add
}
static void r_anal_ex_perform_revisit_bb_cb(RAnal *anal, RAnalState *state, ut64 addr) {
if (anal->cur && anal->cur->revisit_bb_anal) {
anal->cur->revisit_bb_anal (anal, state, addr);
}
if (anal->cur && anal->cur->revisit_bb_anal) {
anal->cur->revisit_bb_anal (anal, state, addr);
}
}
R_API int r_anal_ex_bb_address_comparator(RAnalBlock *a, RAnalBlock *b){
@ -122,7 +122,7 @@ R_API RAnalOp * r_anal_ex_get_op(RAnal *anal, RAnalState *state, ut64 addr) {
const ut8 * data;
// current_op set in a prior stage
if (current_op) return current_op;
IFDBG eprintf("[==] r_anal_ex_get_op: Parsing op @ 0x%04x\n", addr);
IFDBG eprintf("[==] r_anal_ex_get_op: Parsing op @ 0x%04"PFMT64x"\n", addr);
if (anal->cur == NULL ||
(anal->cur->op_from_buffer == NULL && anal->cur->op == NULL) ) {
@ -152,11 +152,11 @@ R_API RAnalOp * r_anal_ex_get_op(RAnal *anal, RAnalState *state, ut64 addr) {
R_API RAnalBlock * r_anal_ex_get_bb(RAnal *anal, RAnalState *state, ut64 addr) {
RAnalBlock *current_bb = state->current_bb;
RAnalOp *op = state->current_op;
static ut64 test = 0;
static ut64 test = 0;
// current_bb set before in a pre-analysis stage.
if (current_bb) return current_bb;
IFDBG eprintf("[==] r_anal_ex_get_bb: Parsing op @ 0x%04x\n", addr);
IFDBG eprintf("[==] r_anal_ex_get_bb: Parsing op @ 0x%04"PFMT64x"\n", addr);
if (r_anal_state_addr_is_valid(state, addr) && op == NULL)
op = r_anal_ex_get_op(anal, state, addr);
@ -168,14 +168,19 @@ R_API RAnalBlock * r_anal_ex_get_bb(RAnal *anal, RAnalState *state, ut64 addr) {
if (op->eob) current_bb->type |= R_ANAL_BB_TYPE_LAST;
if (current_bb->op_bytes == NULL) {
current_bb->op_sz = state->current_op->size;
current_bb->op_bytes = malloc(current_bb->op_sz);
if (current_bb->op_bytes) {
memcpy(current_bb->op_bytes, r_anal_state_get_buf_by_addr(state, addr), current_bb->op_sz);
}
}
state->current_bb = current_bb;
// this can be overridden in a post_bb_anal_cb
state->next_addr = addr + current_bb->op_sz;
current_bb->op_sz = state->current_op->size;
memcpy(current_bb->op_bytes, r_anal_state_get_buf_by_addr(state, addr), current_bb->op_sz);
state->current_bb = current_bb;
// this can be overridden in a post_bb_anal_cb
state->next_addr = addr + current_bb->op_sz;
current_bb->op_sz = state->current_op->size;
test += current_bb->op_sz;
IFDBG eprintf("[==] r_anal_ex_get_bb: op size @ 0x%04x seen 0x%04x\n", state->current_op->size, test);
test += current_bb->op_sz;
IFDBG eprintf("[==] r_anal_ex_get_bb: op size @ 0x%04x seen 0x%04"PFMT64x"\n", state->current_op->size, test);
return current_bb;
}
@ -216,15 +221,15 @@ R_API RList * r_anal_ex_analysis_driver( RAnal *anal, RAnalState *state, ut64 ad
*past_bb = NULL;
RAnalOp * pcurrent_op = state->current_op;
ut64 backup_addr = state->current_addr;
state->current_addr = addr;
ut64 backup_addr = state->current_addr;
state->current_addr = addr;
RList *bb_list = r_anal_bb_list_new ();
if (state->done)
return bb_list;
state->current_bb_head = NULL;
state->current_bb_head = NULL;
state->current_bb = NULL;
state->current_op = NULL;
@ -237,13 +242,13 @@ R_API RList * r_anal_ex_analysis_driver( RAnal *anal, RAnalState *state, ut64 ad
state->current_bb = r_anal_state_search_bb (state, state->current_addr);
// check state for bb
if (state->current_bb) {
// TODO something special should happen here.
r_anal_ex_perform_revisit_bb_cb (anal, state, state->current_addr);
bytes_consumed += state->current_bb->op_sz;
if (state->current_bb) {
// TODO something special should happen here.
r_anal_ex_perform_revisit_bb_cb (anal, state, state->current_addr);
bytes_consumed += state->current_bb->op_sz;
if ( state->done) break;
continue;
continue;
}
r_anal_ex_perform_pre_anal_op_cb (anal, state, state->current_addr);
@ -261,7 +266,7 @@ R_API RList * r_anal_ex_analysis_driver( RAnal *anal, RAnalState *state, ut64 ad
r_anal_ex_get_bb (anal, state, state->current_addr);
if ( state->current_bb_head == NULL ) {
if ( state->current_bb_head == NULL ) {
state->current_bb_head = state->current_bb;
state->current_bb_head->type |= R_ANAL_BB_TYPE_HEAD;
}
@ -273,8 +278,8 @@ R_API RList * r_anal_ex_analysis_driver( RAnal *anal, RAnalState *state, ut64 ad
past_bb = state->current_bb;
r_anal_state_insert_bb (state, state->current_bb);
r_list_append (bb_list, state->current_bb);
r_anal_state_insert_bb (state, state->current_bb);
r_list_append (bb_list, state->current_bb);
r_anal_ex_perform_post_anal_bb_cb (anal, state, state->current_addr);
@ -283,12 +288,12 @@ R_API RList * r_anal_ex_analysis_driver( RAnal *anal, RAnalState *state, ut64 ad
}
bytes_consumed += state->current_bb->op_sz;
state->current_addr = state->next_addr;
state->current_addr = state->next_addr;
r_anal_op_free (state->current_op);
state->current_op = NULL;
state->current_bb = NULL;
IFDBG eprintf ("[=*=] Bytes consumed overall: %d locally: %d of %d\n", state->bytes_consumed, bytes_consumed, len);
IFDBG eprintf ("[=*=] Bytes consumed overall: %"PFMT64d" locally: %"PFMT64d" of %"PFMT64d"\n", state->bytes_consumed, bytes_consumed, len);
}
@ -296,8 +301,8 @@ R_API RList * r_anal_ex_analysis_driver( RAnal *anal, RAnalState *state, ut64 ad
r_anal_ex_perform_post_anal (anal, state, addr);
state->current_op = pcurrent_op;
state->current_bb = pcurrent_bb;
state->current_bb_head = pcurrent_head;
state->current_addr = backup_addr;
state->current_bb_head = pcurrent_head;
state->current_addr = backup_addr;
return bb_list;
}

View File

@ -29,7 +29,8 @@ R_API void r_anal_bb_free(RAnalBlock *bb) {
free (bb->fingerprint);
if (bb->diff)
r_anal_diff_free (bb->diff);
if (bb->op_bytes)
free(bb->op_bytes);
if (bb->switch_op) {
r_anal_switch_op_free(bb->switch_op);
}

View File

@ -70,12 +70,12 @@ static int check_addr_less_start (RBinJavaField *method, ut64 addr) {
static int java_revisit_bb_anal_recursive_descent(RAnal *anal, RAnalState *state, ut64 addr) {
RAnalBlock *current_head = state && state->current_bb_head ? state->current_bb_head : NULL;
RAnalBlock *current_head = state && state->current_bb_head ? state->current_bb_head : NULL;
if (current_head && state->current_bb &&
state->current_bb->type & R_ANAL_BB_TYPE_TAIL) {
r_anal_ex_update_bb_cfg_head_tail (current_head, current_head, state->current_bb);
// XXX should i do this instead -> r_anal_ex_perform_post_anal_bb_cb (anal, state, addr+offset);
state->done = 1;
state->done = 1;
}
return R_ANAL_RET_END;
}
@ -166,7 +166,8 @@ static int handle_bb_cf_recursive_descent (RAnal *anal, RAnalState *state) {
// visited some other time
if (r_anal_state_search_bb (state, bb->jump) == NULL) {
jmp_list = r_anal_ex_perform_analysis ( anal, state, bb->jump );
bb->jumpbb = (RAnalBlock *) r_list_get_n(jmp_list, 0);
if (jmp_list)
bb->jumpbb = (RAnalBlock *) r_list_get_n(jmp_list, 0);
} else {
bb->jumpbb = r_anal_state_search_bb (state, bb->jump);
}
@ -187,7 +188,8 @@ static int handle_bb_cf_recursive_descent (RAnal *anal, RAnalState *state) {
// visited some other time
if (r_anal_state_search_bb (state, bb->jump) == NULL) {
jmp_list = r_anal_ex_perform_analysis ( anal, state, bb->jump );
bb->jumpbb = (RAnalBlock *) r_list_get_n(jmp_list, 0);
if (jmp_list)
bb->jumpbb = (RAnalBlock *) r_list_get_n(jmp_list, 0);
} else {
bb->jumpbb = r_anal_state_search_bb (state, bb->jump);
}
@ -200,7 +202,8 @@ static int handle_bb_cf_recursive_descent (RAnal *anal, RAnalState *state) {
if (r_anal_state_search_bb (state, bb->fail) == NULL) {
jmp_list = r_anal_ex_perform_analysis ( anal, state, bb->fail );
bb->jumpbb = (RAnalBlock *) r_list_get_n(jmp_list, 0);
if (jmp_list)
bb->jumpbb = (RAnalBlock *) r_list_get_n(jmp_list, 0);
} else {
bb->jumpbb = r_anal_state_search_bb (state, bb->jump);
}
@ -229,6 +232,8 @@ static int handle_bb_cf_recursive_descent (RAnal *anal, RAnalState *state) {
if (caseop) {
if (r_anal_state_addr_is_valid(state, caseop->jump) ) {
jmp_list = r_anal_ex_perform_analysis ( anal, state, caseop->jump );
if (jmp_list)
caseop->jumpbb = (RAnalBlock *) r_list_get_n(jmp_list, 0);
if (state->done == 1) {
IFDBG eprintf(" Looks like this jmp (bb @ 0x%04"PFMT64x") found a return.\n", addr);
state->done = 0;
@ -454,6 +459,7 @@ static int analyze_from_code_attr (RAnal *anal, RAnalFunction *fcn, const RBinJa
static int analyze_method(RAnal *anal, RAnalFunction *fcn, RAnalState *state) {
ut64 bytes_consumed = 0;
RList *bbs = NULL;
int result = R_ANAL_RET_ERROR;
// deallocate niceties
r_list_free(fcn->bbs);
@ -462,9 +468,10 @@ static int analyze_method(RAnal *anal, RAnalFunction *fcn, RAnalState *state) {
IFDBG eprintf("analyze_method: Parsing fcn %s @ 0x%08"PFMT64x", %d bytes\n", fcn->name, fcn->addr, fcn->size);
state->current_fcn = fcn;
r_anal_ex_perform_analysis (anal, state, fcn->addr);
bytes_consumed = state->bytes_consumed;
IFDBG eprintf("analyze_method: Completed Parsing fcn %s @ 0x%08"PFMT64x", consumed %d"PFMT64d" bytes\n", fcn->name, fcn->addr, bytes_consumed);
// Not a resource leak. Basic blocks should be stored in the state->fcn
bbs = r_anal_ex_perform_analysis (anal, state, fcn->addr);
bytes_consumed = state->bytes_consumed;
IFDBG eprintf("analyze_method: Completed Parsing fcn %s @ 0x%08"PFMT64x", consumed %"PFMT64d" bytes\n", fcn->name, fcn->addr, bytes_consumed);
return state->anal_ret_val;
}
@ -476,7 +483,7 @@ static int java_analyze_fns_from_buffer( RAnal *anal, ut64 start, ut64 end, int
ut64 offset = 0;
ut64 buf_len = end - start;
ut8 analyze_all = 0,
*buffer = NULL;
*buffer = NULL;
if (end == UT64_MAX) {
//analyze_all = 1;
@ -719,223 +726,4 @@ struct r_lib_struct_t radare_plugin = {
//.data = &r_anal_plugin_java
.data = &r_anal_plugin_java_ls
};
#endif
/*
static void r_anal_ex_handle_bb_cases(RAnal *anal, RAnalState *state, RAnalBlock *bb, RAnalOp *op);
static void r_anal_ex_handle_control_flow(RAnal *anal, RAnalState *state, RAnalBlock* current_bb);
static void r_anal_ex_handle_binary_jump(RAnal *anal, RAnalState *state, RAnalBlock* current_bb);
static void r_anal_ex_handle_case_jump(RAnal *anal, RAnalState *state, RAnalBlock* current_bb);
static void r_anal_ex_handle_call(RAnal *anal, RAnalState *state, RAnalBlock* current_bb);
static void r_anal_ex_handle_jump(RAnal *anal, RAnalState *state, RAnalBlock* current_bb, ut64 jump_to);
R_API void r_anal_ex_handle_binary_jump(RAnal *anal, RAnalState *state, RAnalBlock* current_bb) {
r_anal_ex_handle_jump( anal, state, current_bb, current_bb->jump );
r_anal_ex_handle_jump( anal, state, current_bb, current_bb->fail );
}
R_API void r_anal_ex_handle_case_jump(RAnal *anal, RAnalState *state, RAnalBlock* current_bb ) {
// TODO parse switch caseops
// for each caseop in the bb->switch_op {
// ut64 jmp_addr = caseop->jump
// r_anal_ex_handle_jump( anal, state, current_bb, jumpaddr );
// if ( jmp_list ){
// i = 0
// // merge results
// // TODO jmp_list[i]->prev = current_bb
// // TODO jmp_list[i]->next = jmp_list[i+1]
// }
// }
}
R_API void r_anal_ex_handle_jump(RAnal *anal, RAnalState *state, RAnalBlock* current_bb, ut64 jump_to) {
RList * jmp_list = recursive_descent_jmp( anal, state, current_bb, jump_to );
if ( jmp_list ){
r_anal_state_merge_bb_list (state, jmp_list);
}
}
R_API void r_anal_ex_handle_call(RAnal *anal, RAnalState *state, RAnalBlock* current_bb) {
RList * caller_list = recursive_descent_jmp( anal, state, current_bb, 0/*jump_to* / );
if ( caller_list ){
// TODO merge results
// TODO set current_bb->jumpbb = jmp_list[0]
// TODO jmp_list[0]->prev = current_bb
}
}
R_API void r_anal_ex_handle_control_flow(RAnal *anal, RAnalState *state, RAnalBlock* current_bb ) {
if ( current_bb->type | R_ANAL_BB_TYPE_JMP )
r_anal_ex_handle_binary_jump(anal, state, current_bb);
else if ( current_bb->type | R_ANAL_BB_TYPE_SWITCH )
r_anal_ex_handle_case_jump(anal, state, current_bb);
else if ( current_bb->type | R_ANAL_BB_TYPE_CALL )
r_anal_ex_handle_call(anal, state, current_bb);
}
R_API RList * recursive_descent_jmp( RAnal *anal, RAnalState *state, RAnalBlock *current_bb, ut64 jmp_addr ) {
ut64 jmp_len = 0;
RList *jmp_list = NULL;
// jmp and recurse through the bb
// step 1, check jump to see if it is valid
if (jmp_addr > state->end && jmp_addr < state->start) {
current_bb->type |= R_ANAL_BB_TYPE_FOOT;
// Done Processing?
} else {
jmp_list = recursive_descent ( anal, state, jmp_addr );
}
return jmp_list;
}
/*
static void r_anal_ex_handle_bb_cases(RAnal *anal, RAnalState *state, RAnalBlock *bb, RAnalOp *op){
if (bb->type2 & R_ANAL_EX_ILL_OP) {
if (anal->cur && anal->cur->bb_ill_op) {
anal->cur->bb_ill_op (anal, state, bb, op);
return;
}
}
if (bb->type2 & R_ANAL_EX_COND_OP) {
if (anal->cur && anal->cur->bb_cond_op) {
anal->cur->bb_cond_op (anal, state, bb, op);
}
}
if (bb->type2 & R_ANAL_EX_UNK_OP) {
if (anal->cur && anal->cur->bb_unknown_op) {
anal->cur->bb_unknown_op (anal, state, bb, op);
}
}
if (bb->type2 & R_ANAL_EX_NULL_OP) {
if (anal->cur && anal->cur->bb_null_op) {
anal->cur->bb_null_op (anal, state, bb, op);
}
}
if (bb->type2 & R_ANAL_EX_NOP_OP) {
if (anal->cur && anal->cur->bb_nop_op) {
anal->cur->bb_nop_op (anal, state, bb, op);
}
}
if (bb->type2 & R_ANAL_EX_REP_OP) {
if (anal->cur && anal->cur->bb_rep_op) {
anal->cur->bb_rep_op (anal, state, bb, op);
}
}
if (bb->type2 & R_ANAL_EX_STORE_OP) {
if (anal->cur && anal->cur->bb_store_op) {
anal->cur->bb_store_op (anal, state, bb, op);
}
}
if (bb->type2 & R_ANAL_EX_LOAD_OP) {
if (anal->cur && anal->cur->bb_load_op) {
anal->cur->bb_load_op (anal, state, bb, op);
}
}
if (bb->type2 & R_ANAL_EX_REG_OP) {
if (anal->cur && anal->cur->bb_reg_op) {
anal->cur->bb_reg_op (anal, state, bb, op);
}
}
if (bb->type2 & R_ANAL_EX_OBJ_OP) {
if (anal->cur && anal->cur->bb_obj_op) {
anal->cur->bb_obj_op (anal, state, bb, op);
}
}
if (bb->type2 & R_ANAL_EX_STACK_OP) {
if (anal->cur && anal->cur->bb_stack_op) {
anal->cur->bb_stack_op (anal, state, bb, op);
}
}
if (bb->type2 & R_ANAL_EX_BIN_OP) {
if (anal->cur && anal->cur->bb_bin_op) {
anal->cur->bb_bin_op (anal, state, bb, op);
}
}
if (bb->type2 & R_ANAL_EX_CODE_OP) {
if (anal->cur && anal->cur->bb_code_op) {
anal->cur->bb_code_op (anal, state, bb, op);
}
}
if (bb->type2 & R_ANAL_EX_DATA_OP) {
if (anal->cur && anal->cur->bb_data_op) {
anal->cur->bb_data_op (anal, state, bb, op);
}
}
}
static void r_anal_ex_handle_fn_cases(RAnal *anal, RAnalState *state, RAnalBlock *bb, RAnalOp *op){
if (bb->type2 & R_ANAL_EX_ILL_OP) {
if (anal->cur && anal->cur->bb_ill_op) {
anal->cur->bb_ill_op (anal, state, bb, op);
return;
}
}
if (bb->type2 & R_ANAL_EX_COND_OP) {
if (anal->cur && anal->cur->bb_cond_op) {
anal->cur->bb_cond_op (anal, state, bb, op);
}
}
if (bb->type2 & R_ANAL_EX_UNK_OP) {
if (anal->cur && anal->cur->bb_unknown_op) {
anal->cur->bb_unknown_op (anal, state, bb, op);
}
}
if (bb->type2 & R_ANAL_EX_NULL_OP) {
if (anal->cur && anal->cur->bb_null_op) {
anal->cur->bb_null_op (anal, state, bb, op);
}
}
if (bb->type2 & R_ANAL_EX_NOP_OP) {
if (anal->cur && anal->cur->bb_nop_op) {
anal->cur->bb_nop_op (anal, state, bb, op);
}
}
if (bb->type2 & R_ANAL_EX_REP_OP) {
if (anal->cur && anal->cur->bb_rep_op) {
anal->cur->bb_rep_op (anal, state, bb, op);
}
}
if (bb->type2 & R_ANAL_EX_STORE_OP) {
if (anal->cur && anal->cur->bb_store_op) {
anal->cur->bb_store_op (anal, state, bb, op);
}
}
if (bb->type2 & R_ANAL_EX_LOAD_OP) {
if (anal->cur && anal->cur->bb_load_op) {
anal->cur->bb_load_op (anal, state, bb, op);
}
}
if (bb->type2 & R_ANAL_EX_REG_OP) {
if (anal->cur && anal->cur->bb_reg_op) {
anal->cur->bb_reg_op (anal, state, bb, op);
}
}
if (bb->type2 & R_ANAL_EX_OBJ_OP) {
if (anal->cur && anal->cur->bb_obj_op) {
anal->cur->bb_obj_op (anal, state, bb, op);
}
}
if (bb->type2 & R_ANAL_EX_STACK_OP) {
if (anal->cur && anal->cur->bb_stack_op) {
anal->cur->bb_stack_op (anal, state, bb, op);
}
}
if (bb->type2 & R_ANAL_EX_BIN_OP) {
if (anal->cur && anal->cur->bb_bin_op) {
anal->cur->bb_bin_op (anal, state, bb, op);
}
}
if (bb->type2 & R_ANAL_EX_CODE_OP) {
if (anal->cur && anal->cur->bb_code_op) {
anal->cur->bb_code_op (anal, state, bb, op);
}
}
if (bb->type2 & R_ANAL_EX_DATA_OP) {
if (anal->cur && anal->cur->bb_data_op) {
anal->cur->bb_data_op (anal, state, bb, op);
}
}
}
*/
#endif

View File

@ -514,6 +514,7 @@ typedef struct r_anal_case_obj_t {
ut32 cond; // TODO: treat like a regular condition
ut64 bb_ref_to;
ut64 bb_ref_from;
struct r_anal_bb_t *jumpbb;
} RAnalCaseOp;
@ -640,7 +641,7 @@ typedef struct r_anal_bb_t {
#endif
RAnalCond *cond;
RAnalSwitchOp *switch_op;
ut8 op_bytes[30];
ut8 *op_bytes;
ut8 op_sz;
struct r_anal_bb_t *head;
struct r_anal_bb_t *tail;