@@ -529,6 +529,29 @@ static size_t exclude(const std::vector<Exclude> &excludes, intptr_t addr)
529529 return 0 ;
530530}
531531
532+ /*
533+ * Next instruction.
534+ */
535+ static size_t nextInstr (const std::vector<intptr_t > &disasm, intptr_t addr)
536+ {
537+ ssize_t max = (ssize_t )disasm.size () - 1 ;
538+ if (disasm.size () == 0 || addr > disasm[max])
539+ return INT32_MAX;
540+ ssize_t lo = 0 , hi = max;
541+ while (lo <= hi)
542+ {
543+ ssize_t mid = (lo + hi) / 2 ;
544+ intptr_t i = disasm[mid];
545+ if (addr < i)
546+ hi = mid-1 ;
547+ else if (addr > i)
548+ lo = mid+1 ;
549+ else
550+ return 0 ;
551+ }
552+ return disasm[lo] - addr;
553+ }
554+
532555/*
533556 * Metadata.
534557 */
@@ -651,6 +674,8 @@ enum Option
651674 OPTION_SYNTAX,
652675 OPTION_TRAP,
653676 OPTION_TRAP_ALL,
677+ OPTION_USE_DISASM,
678+ OPTION_USE_TARGETS,
654679 OPTION_VERSION,
655680};
656681
@@ -725,6 +750,8 @@ int main_2(int argc, char **argv)
725750 {" syntax" , req_arg, nullptr , OPTION_SYNTAX},
726751 {" trap" , req_arg, nullptr , OPTION_TRAP},
727752 {" trap-all" , no_arg, nullptr , OPTION_TRAP_ALL},
753+ {" use-disasm" , req_arg, nullptr , OPTION_USE_DISASM},
754+ {" use-targets" , req_arg, nullptr , OPTION_USE_TARGETS},
728755 {" version" , no_arg, nullptr , OPTION_VERSION},
729756 {nullptr , no_arg, nullptr , 0 }
730757 };
@@ -741,6 +768,10 @@ int main_2(int argc, char **argv)
741768 std::vector<std::string> option_patch;
742769 std::vector<ActionEntry> option_actions;
743770 std::vector<std::string> option_exclude;
771+ std::string option_use_disasm (" " );
772+ std::string option_use_targets (" " );
773+ std::string option_use_funcs (" " );
774+
744775 int option_sync = 64 , option_threshold = 2 ;
745776 bool option_CFR = false ;
746777 srand (0xe9e9e9e9 );
@@ -898,6 +929,12 @@ int main_2(int argc, char **argv)
898929 case OPTION_TRAP_ALL:
899930 option_trap_all = true ;
900931 break ;
932+ case OPTION_USE_DISASM:
933+ option_use_disasm = optarg;
934+ break ;
935+ case OPTION_USE_TARGETS:
936+ option_use_targets = optarg;
937+ break ;
901938 case OPTION_VERSION:
902939 puts (" E9Tool " STRING (VERSION));
903940 return EXIT_SUCCESS;
@@ -1252,6 +1289,13 @@ int main_2(int argc, char **argv)
12521289 /*
12531290 * Disassemble the ELF file.
12541291 */
1292+ std::vector<intptr_t > disasm;
1293+ bool use_disasm = false ;
1294+ if (option_use_disasm != " " )
1295+ {
1296+ parseAddrs (option_use_disasm.c_str (), disasm);
1297+ use_disasm = true ;
1298+ }
12551299 initDisassembler ();
12561300 std::vector<Instr> Is;
12571301 std::vector<Desync> desyncs;
@@ -1279,6 +1323,7 @@ int main_2(int argc, char **argv)
12791323 while (true )
12801324 {
12811325 size_t skip = exclude (excludes, address);
1326+ skip += (use_disasm? nextInstr (disasm, address + skip): 0 );
12821327 if (skip > 0 )
12831328 {
12841329 address += skip;
@@ -1296,7 +1341,7 @@ int main_2(int argc, char **argv)
12961341 I.first = first;
12971342 first = false ;
12981343
1299- int score = suspiciousness (bytes, I.size );
1344+ int score = (use_disasm? 0 : suspiciousness (bytes, I.size ) );
13001345 if (option_debug && !I.data )
13011346 {
13021347 InstrInfo J;
@@ -1311,6 +1356,11 @@ int main_2(int argc, char **argv)
13111356 (score >= option_threshold? " <data?>" : " " ));
13121357 }
13131358
1359+ if (I.data && use_disasm)
1360+ error (" failed to decode instruction at address 0x%lx; "
1361+ " the \" %s\" disassmebly file may be inaccurate" ,
1362+ I.address , option_use_disasm.c_str ());
1363+
13141364 if (I.data || score >= option_threshold)
13151365 {
13161366 // Data has been detected in the code segment. We attempt to
@@ -1352,13 +1402,20 @@ int main_2(int argc, char **argv)
13521402 section, section_addr, section_addr + section_size,
13531403 section_addr, section_addr + (code - start));
13541404 }
1405+ disasm.clear ();
13551406 Is.shrink_to_fit ();
13561407 notifyPlugins (out, &elf, Is, EVENT_DISASSEMBLY_COMPLETE);
13571408 size_t count = Is.size ();
13581409
13591410 // Step (1a): CFG Analysis (if necessary).
13601411 if (option_targets)
1361- buildTargets (&elf, Is.data (), Is.size (), elf.targets );
1412+ {
1413+ if (option_use_targets != " " )
1414+ parseTargets (option_use_targets.c_str (), Is.data (), Is.size (),
1415+ elf.targets );
1416+ else
1417+ buildTargets (&elf, Is.data (), Is.size (), elf.targets );
1418+ }
13621419 if (option_bbs)
13631420 buildBBs (&elf, Is.data (), Is.size (), elf.targets , elf.bbs );
13641421 if (option_fs)
0 commit comments