@@ -30,7 +30,6 @@ PANDAENDCOMMENT */
3030#include < memory>
3131#include < set>
3232#include < vector>
33- #include < utility>
3433
3534#include < capstone/capstone.h>
3635#if defined(TARGET_I386)
@@ -82,8 +81,6 @@ bool old_capstone=false; // Should we use fallback instruction group detection l
8281// callstack_instr arguments
8382static bool verbose = false ;
8483static bool include_binary_info = false ;
85- static std::string no_osi_msg = " OSI is not enabled" ;
86- static std::vector<char > no_osi_msg_vector (no_osi_msg.begin(), no_osi_msg.end());
8784
8885enum instr_type {
8986 INSTR_UNKNOWN = 0 ,
@@ -382,12 +379,15 @@ void before_block_exec(CPUState *cpu, TranslationBlock *tb) {
382379 if (need_to_check) {
383380 std::vector<stack_entry> &v = callstacks[cur_stackid];
384381 std::vector<target_ulong> &w = function_stacks[cur_stackid];
385-
386382 if (v.empty ()) {
387383 return ;
388384 }
389385
390- std::map<target_ulong, std::vector<char >> &binary_info_stack = binary_info_stacks[cur_stackid];
386+ std::map<target_ulong, std::vector<char >> *binary_info_stack = nullptr ;
387+
388+ if (include_binary_info) {
389+ binary_info_stack = &binary_info_stacks[cur_stackid];
390+ }
391391
392392 // Search up to 10 down
393393 for (int i = v.size () - 1 ; i > ((int )(v.size () - 10 )) && i >= 0 ; i--) {
@@ -397,8 +397,10 @@ void before_block_exec(CPUState *cpu, TranslationBlock *tb) {
397397
398398 PPP_RUN_CB (on_ret, cpu, w[i]);
399399
400- for (std::vector<stack_entry>::iterator it = v.begin () + i; it != v.end (); ++it) {
401- binary_info_stack.erase (it->pc );
400+ if (include_binary_info) {
401+ for (std::vector<stack_entry>::iterator it = v.begin () + i; it != v.end (); ++it) {
402+ binary_info_stack->erase (it->pc );
403+ }
402404 }
403405
404406 v.erase (v.begin () + i, v.end ());
@@ -412,38 +414,22 @@ void before_block_exec(CPUState *cpu, TranslationBlock *tb) {
412414
413415std::vector<char > getLib (CPUState* cpu, target_ulong pc) {
414416
415- target_ulong end_addr;
416-
417417 std::shared_ptr<OsiProc> proc (get_current_process (cpu), free_osiproc);
418418
419- std::shared_ptr<GArray> mappings (get_mappings (cpu, proc.get ()),
420- [](GArray *a) {
421- if (a != nullptr ) {
422- g_array_free (a, true );
423- }
424- });
425-
426- if (nullptr != mappings) {
427- for (uint32_t i = 0 ; i < mappings->len ; i++) {
428- OsiModule *osimodule = &g_array_index (mappings.get (), OsiModule, i);
429- end_addr = osimodule->base + (osimodule->size - 1 );
430-
431- if (pc >= osimodule->base && pc < end_addr) {
432- if (nullptr != osimodule->file ) {
433- std::size_t len = strlen (osimodule->file );
434- std::vector<char > lib_str_buf (len + 1 );
435- std::snprintf (lib_str_buf.data (), lib_str_buf.size (), " %s" , osimodule->file );
436- return lib_str_buf;
437- } else if (nullptr != osimodule->name ) {
438- std::size_t len = strlen (osimodule->name );
439- std::vector<char > lib_str_buf (len + 1 );
440- std::snprintf (lib_str_buf.data (), lib_str_buf.size (), " %s" , osimodule->name );
441- return lib_str_buf;
442- } else {
443- return std::vector<char >(1 , ' \0 ' );
444- }
445- }
446- }
419+ OsiModule *module = get_mapping_by_addr (cpu, proc.get (), pc);
420+
421+ if (nullptr != module ) {
422+ const char *lib = " " ;
423+ if (nullptr != module ->file ) {
424+ lib = module ->file ;
425+ } else if (nullptr != module ->name ) {
426+ lib = module ->name ;
427+ }
428+ std::size_t len = strlen (lib);
429+ std::vector<char > lib_str_buf (len + 1 );
430+ std::snprintf (lib_str_buf.data (), lib_str_buf.size (), " %s" , lib);
431+ free_osimodule (module );
432+ return lib_str_buf;
447433 }
448434
449435 return std::vector<char >(1 , ' \0 ' );
@@ -464,8 +450,9 @@ void after_block_exec(CPUState* cpu, TranslationBlock *tb, uint8_t exitCode) {
464450 if (tb_type == INSTR_CALL) {
465451 stack_entry se = {tb->pc + tb->size , tb_type};
466452 callstacks[curStackid].push_back (se);
467- binary_info_stacks[curStackid][se.pc ] =
468- include_binary_info ? getLib (cpu, se.pc ) : no_osi_msg_vector;
453+ if (include_binary_info) {
454+ binary_info_stacks[curStackid][se.pc ] = getLib (cpu, se.pc );
455+ }
469456
470457 // Also track the function that gets called
471458 // This retrieves the pc in an architecture-neutral way
@@ -494,6 +481,7 @@ void after_block_exec(CPUState* cpu, TranslationBlock *tb, uint8_t exitCode) {
494481 }
495482}
496483
484+
497485static uint32_t get_callers_priv (target_ulong callers[], uint32_t n,
498486 CPUState* cpu, stackid stackid) {
499487 std::vector<stack_entry> &v = callstacks[stackid];
@@ -511,13 +499,26 @@ uint32_t get_callers(target_ulong callers[], uint32_t n, CPUState* cpu) {
511499}
512500
513501uint32_t get_binaries (char **libs, uint32_t n, CPUState *cpu) {
514- stackid stack_id = get_stackid (cpu);
515- std::vector<stack_entry> &call_stack = callstacks[stack_id];
516- std::map<target_ulong, std::vector<char >> &binary_info_stack = binary_info_stacks[stack_id];
517-
518- n = std::min ((uint32_t ) call_stack.size (), n);
519- for (uint32_t i = 0 ; i < n; ++i) {
520- libs[i] = binary_info_stack[call_stack[call_stack.size () - 1 - i].pc ].data ();
502+ static bool warning_shown = false ;
503+ for (uint32_t i=0 ; i<n; libs[i++] = nullptr );
504+ if (include_binary_info) {
505+ stackid stack_id = get_stackid (cpu);
506+ std::vector<stack_entry> &call_stack = callstacks[stack_id];
507+ std::map<target_ulong, std::vector<char >> &binary_info_stack = binary_info_stacks[stack_id];
508+
509+ n = std::min ((uint32_t ) call_stack.size (), n);
510+ for (uint32_t i = 0 ; i < n; ++i) {
511+ libs[i] = binary_info_stack[call_stack[call_stack.size () - 1 - i].pc ].data ();
512+ }
513+ } else {
514+ if (!warning_shown) {
515+ fprintf (stderr, " WARNING: callstack_instr: get_binaries called "
516+ " but binary tracking not enabled. %s\n " ,
517+ (nullptr == panda_get_plugin_by_name (" osi" ) ?
518+ " OSI plugin not loaded." : " " ));
519+ warning_shown = true ;
520+ }
521+ n = 0 ;
521522 }
522523
523524 return n;
@@ -541,6 +542,7 @@ Panda__CallStack *pandalog_callstack_create() {
541542 return cs;
542543}
543544
545+
544546/* *
545547 * @brief Frees a pandalog entry containing callstack information.
546548 */
@@ -549,6 +551,7 @@ void pandalog_callstack_free(Panda__CallStack *cs) {
549551 free (cs);
550552}
551553
554+
552555/* *
553556 * @brief Fills preallocated buffer \p functions with up to \p n function addresses.
554557 */
@@ -623,6 +626,7 @@ bool setup_osi() {
623626#endif
624627}
625628
629+
626630bool init_plugin (void *self) {
627631
628632 // get arguments to this plugin
@@ -742,11 +746,13 @@ bool init_plugin(void *self) {
742746 printf (" callstack_instr: using heuristic stack_type\n " );
743747 }
744748
745- include_binary_info = setup_ok && (nullptr != panda_get_plugin_by_name (" osi" ));
746-
747749 return setup_ok;
748750}
749751
752+ void callstack_enable_binary_tracking () {
753+ include_binary_info = (nullptr != panda_get_plugin_by_name (" osi" ));
754+ }
755+
750756void uninit_plugin (void *self) {
751757 // nothing to do
752758}
0 commit comments