Use the anchors to create initial file borders in the binary address space.
(self)
| 455 | self._src_file_names = anchor_files + list(set(self._src_file_names) - set(anchor_files)) |
| 456 | |
| 457 | def locateFileBoundaries(self): |
| 458 | """Use the anchors to create initial file borders in the binary address space.""" |
| 459 | self.logger.info("Zooming-in to define the tentative borders for each source file in the binary address space") |
| 460 | # Split the matched anchor functions to their respective files |
| 461 | file_to_anchor_mapping = defaultdict(list) |
| 462 | for path in self._src_file_names: |
| 463 | for src_ctx in self._src_file_mappings[path]: |
| 464 | if src_ctx.index in self._matched_anchors_ea: |
| 465 | file_to_anchor_mapping[path].append(src_ctx) |
| 466 | |
| 467 | # construct the list of minimal bound and maximal bound for each file |
| 468 | # this could be tricky since not all of our files are going to have anchor functions - including the first and the last file |
| 469 | all_bin_functions = self.disas.functions() |
| 470 | file_min_bound = [] |
| 471 | file_max_bound = [] |
| 472 | file_lower_gap = [] |
| 473 | file_upper_gap = [] |
| 474 | first_anchor_index = None |
| 475 | last_anchor_index = None |
| 476 | overall_min_bin_anchor_index = None |
| 477 | overall_max_bin_anchor_index = None |
| 478 | # 1st round, basic estimates using only the anchors (files without anchors are placed artificially at the end) |
| 479 | for file_index, file_name in enumerate(self._src_file_names): |
| 480 | # return back to this file after the initial round |
| 481 | if len(file_to_anchor_mapping[file_name]) == 0: |
| 482 | break |
| 483 | if first_anchor_index is None: |
| 484 | first_anchor_index = file_index |
| 485 | last_anchor_index = file_index |
| 486 | # else, we have an anchor, and we can have basic bounds for now |
| 487 | min_anchor = min(self._matched_anchors_ea[x.index] for x in file_to_anchor_mapping[file_name]) |
| 488 | max_anchor = max(self._matched_anchors_ea[x.index] for x in file_to_anchor_mapping[file_name]) |
| 489 | min_anchor_bin_index = all_bin_functions.index(min_anchor) |
| 490 | max_anchor_bin_index = all_bin_functions.index(max_anchor) |
| 491 | if overall_min_bin_anchor_index is None: |
| 492 | overall_min_bin_anchor_index = min_anchor_bin_index |
| 493 | overall_max_bin_anchor_index = max_anchor_bin_index |
| 494 | else: |
| 495 | overall_min_bin_anchor_index = min(overall_min_bin_anchor_index, min_anchor_bin_index) |
| 496 | overall_max_bin_anchor_index = max(overall_max_bin_anchor_index, max_anchor_bin_index) |
| 497 | base_leftover_size = len(self._src_file_mappings[file_name]) - (max_anchor_bin_index - min_anchor_bin_index + 1) |
| 498 | file_min_bound.append(min_anchor_bin_index - base_leftover_size) |
| 499 | file_max_bound.append(max_anchor_bin_index + base_leftover_size) |
| 500 | file_lower_gap.append(base_leftover_size) |
| 501 | file_upper_gap.append(base_leftover_size) |
| 502 | # create rough lower bounds to all files |
| 503 | additional_lower_bounds = [] |
| 504 | prev_hard_limit = -1 |
| 505 | for file_index in range(first_anchor_index, last_anchor_index + 1): |
| 506 | additional_lower_bounds = additional_lower_bounds + [prev_hard_limit] |
| 507 | prev_hard_limit = file_max_bound[file_index] - file_upper_gap[file_index] + 1 |
| 508 | # create the same kind of upper bounds to all files, going from top to bottom |
| 509 | additional_upper_bounds = [] |
| 510 | prev_hard_limit = len(all_bin_functions) |
| 511 | for file_index in range(last_anchor_index, first_anchor_index - 1, -1): |
| 512 | additional_upper_bounds = [prev_hard_limit] + additional_upper_bounds |
| 513 | prev_hard_limit = file_min_bound[file_index] + file_lower_gap[file_index] - 1 |
| 514 | # Now preform the full scan again, with all of the information we gathered in previous phases |
no test coverage detected