diff --git a/librz/analysis/fcn.c b/librz/analysis/fcn.c index bd541772fc..557870e1d2 100644 --- a/librz/analysis/fcn.c +++ b/librz/analysis/fcn.c @@ -792,6 +792,11 @@ static RzAnalysisBBEndCause run_basic_block_analysis(RzAnalysisTaskItem *item, R ut64 from_addr = analysis->coreb.numGet(analysis->coreb.core, handle); handle = rz_str_replace(handle, ".from", ".catch", 0); ut64 handle_addr = analysis->coreb.numGet(analysis->coreb.core, handle); + handle = rz_str_replace(handle, ".catch", ".filter", 0); + ut64 filter_addr = analysis->coreb.numGet(analysis->coreb.core, handle); + if (filter_addr) { + rz_analysis_xrefs_set(analysis, op.addr, filter_addr, RZ_ANALYSIS_REF_TYPE_CALL); + } bb->jump = at + oplen; if (from_addr != bb->addr) { bb->fail = handle_addr; @@ -799,8 +804,9 @@ static RzAnalysisBBEndCause run_basic_block_analysis(RzAnalysisTaskItem *item, R if (bb->size == 0) { rz_analysis_function_remove_block(fcn, bb); } + rz_analysis_block_update_hash(bb); rz_analysis_block_unref(bb); - bb = fcn_append_basic_block(analysis, fcn, addr); + bb = fcn_append_basic_block(analysis, fcn, bb->jump); if (!bb) { gotoBeach(RZ_ANALYSIS_RET_ERROR); } @@ -1455,11 +1461,14 @@ static RzAnalysisBBEndCause run_basic_block_analysis(RzAnalysisTaskItem *item, R beach: rz_analysis_op_fini(&op); RZ_FREE(last_reg_mov_lea_name); - if (bb && bb->size == 0) { - rz_analysis_function_remove_block(fcn, bb); + if (bb) { + if (bb->size) { + rz_analysis_block_update_hash(bb); + } else { + rz_analysis_function_remove_block(fcn, bb); + } + rz_analysis_block_unref(bb); } - rz_analysis_block_update_hash(bb); - rz_analysis_block_unref(bb); free(movbasereg); return ret; } diff --git a/librz/bin/p/bin_pe64.c b/librz/bin/p/bin_pe64.c index d37dfe0cfc..8f30384c72 100644 --- a/librz/bin/p/bin_pe64.c +++ b/librz/bin/p/bin_pe64.c @@ -363,7 +363,6 @@ static RzList *trycatch(RzBinFile *bf) { ut64 baseAddr = bf->o->opts.baseaddr; int i; ut64 offset; - ut32 c_handler = 0; struct PE_(rz_bin_pe_obj_t) *bin = bf->o->bin_obj; PE_(image_data_directory) *expdir = &bin->optional_header->DataDirectory[PE_IMAGE_DIRECTORY_ENTRY_EXCEPTION]; @@ -434,22 +433,8 @@ static RzList *trycatch(RzBinFile *bf) { if (!rz_io_read_at_mapped(io, exceptionDataOff, (ut8 *)&handler, sizeof(handler))) { continue; } - if (c_handler && c_handler != handler) { - continue; - } exceptionDataOff += sizeof(ut32); - if (!c_handler) { - ut32 magic, rva_to_fcninfo; - if (rz_io_read_at_mapped(io, exceptionDataOff, (ut8 *)&rva_to_fcninfo, sizeof(rva_to_fcninfo)) && - rz_io_read_at_mapped(io, baseAddr + rva_to_fcninfo, (ut8 *)&magic, sizeof(magic))) { - if (magic >= 0x19930520 && magic <= 0x19930522) { - // __CxxFrameHandler3 or __GSHandlerCheck_EH - continue; - } - } - } - PE64_SCOPE_TABLE tbl; if (!rz_io_read_at_mapped(io, exceptionDataOff, (ut8 *)&tbl, sizeof(tbl))) { continue; @@ -469,7 +454,8 @@ static RzList *trycatch(RzBinFile *bf) { } if (!scope.JumpTarget) { // scope.HandlerAddress == __finally block - continue; + scope.JumpTarget = scope.HandlerAddress; + scope.HandlerAddress = 1; } ut64 handlerAddr = scope.HandlerAddress == 1 ? 0 : scope.HandlerAddress + baseAddr; RzBinTrycatch *tc = rz_bin_trycatch_new( @@ -478,7 +464,6 @@ static RzList *trycatch(RzBinFile *bf) { scope.EndAddress + baseAddr, scope.JumpTarget + baseAddr, handlerAddr); - c_handler = handler; rz_list_append(tclist, tc); scopeRecOff += sizeof(PE64_SCOPE_RECORD); } diff --git a/librz/core/cbin.c b/librz/core/cbin.c index f5162ccc37..1c6f000740 100644 --- a/librz/core/cbin.c +++ b/librz/core/cbin.c @@ -4039,9 +4039,12 @@ static int bin_trycatch(RzCore *core, PJ *pj, int mode) { int idx = 0; // FIXME: json mode rz_list_foreach (trycatch, iter, tc) { - rz_cons_printf("f try.%d.%" PFMT64x ".from @ 0x%08" PFMT64x "\n", idx, tc->source, tc->from); - rz_cons_printf("f try.%d.%" PFMT64x ".to @ 0x%08" PFMT64x "\n", idx, tc->source, tc->to); - rz_cons_printf("f try.%d.%" PFMT64x ".catch @ 0x%08" PFMT64x "\n", idx, tc->source, tc->handler); + rz_cons_printf("f+ try.%d.%" PFMT64x ".from @ 0x%08" PFMT64x "\n", idx, tc->source, tc->from); + rz_cons_printf("f+ try.%d.%" PFMT64x ".to @ 0x%08" PFMT64x "\n", idx, tc->source, tc->to); + rz_cons_printf("f+ try.%d.%" PFMT64x ".catch @ 0x%08" PFMT64x "\n", idx, tc->source, tc->handler); + if (tc->filter) { + rz_cons_printf("f+ try.%d.%" PFMT64x ".filter @ 0x%08" PFMT64x "\n", idx, tc->source, tc->filter); + } idx++; } return true; diff --git a/test/db/formats/pe/seh_x64 b/test/db/formats/pe/seh_x64 index b299c68c7e..914c8ffa77 100644 --- a/test/db/formats/pe/seh_x64 +++ b/test/db/formats/pe/seh_x64 @@ -9,26 +9,31 @@ NAME=PE: seh_x64.exe - Get trycatchs FILE=bins/pe/seh_x64.exe CMDS=iw EXPECT=<