Skip to content

Unexpected behavior of get_view_of_file when using progress_func #4116

Closed

Description

@jprokos26

Version and Platform (required):

  • Headless (on 3.3.4012-dev)
  • OS: MacOS
  • OS Version: 13.1
  • CPU Architecture: M1

Bug Description:

  1. When supplying a .bndb file along with progress_func BinaryNinja is unable to open the .bndb but when progress_func is not supplied it opens fine:
>>> bv_path
PosixPath('libc.so.6.bndb')
>>> open_view(bv_path, progress_func=lambda p,t: print(p,t))
0 1000000
1 1
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/Applications/Binary Ninja.app/Contents/Resources/python/binaryninja/__init__.py", line 360, in open_view
    bv = BinaryViewType.get_view_of_file_with_options(*args, **kwargs)
  File "/Applications/Binary Ninja.app/Contents/Resources/python/binaryninja/binaryview.py", line 1033, in get_view_of_file_with_options
    return BinaryViewType.load(filename, update_analysis, progress_func, options)
  File "/Applications/Binary Ninja.app/Contents/Resources/python/binaryninja/binaryview.py", line 1199, in load
    return BinaryViewType.load_raw_view_with_options(raw_view, *args, **kwargs)
  File "/Applications/Binary Ninja.app/Contents/Resources/python/binaryninja/binaryview.py", line 1147, in load_raw_view_with_options
    raise Exception(f"Unable to open_existing_database with filename {raw_view.file.filename}")
Exception: Unable to open_existing_database with filename libc.so.6.bndb
>>> open_view(bv_path)
<BinaryView: 'libc.so.6.bndb', len 0x227ed8>
>>> path
PosixPath('libc.so.6')
>>> open_view(path, progress_func=lambda p,t: print(p,t))
<BinaryView: 'libc.so.6', len 0x227ed8>
  1. Additionally, when supplying a callable progress_func when using open_view the progress_func is only updated when supplying a .bndb file and never gets called otherwise. Specifically in get_view_of_file:
		is_database = filename.endswith(".bndb")
		if is_database:
			f = open(filename, 'rb')
			if f is None or f.read(len(sqlite)) != sqlite:
				return None
			f.close()
			view = filemetadata.FileMetadata().open_existing_database(filename, progress_func)
		else:
			view = BinaryView.open(filename)

From the docs it would be expected that progress_func is called on any valid filename not just .bndb files:
progress_func (callback) – optional function to be called with the current progress and total count

Steps To Reproduce:

  1. Use progress_func in any context.

Expected Behavior:
Progress bar to be called

Screenshots:
N/A

Additional Information:
For the second example I am unsure if this is a bug or intended behavior; if the latter then this is a DOCS issue not a BUG.

Activity

  1. plafosse commented on Mar 21, 2023

    @plafosse
    Member

    Ok this one had me confused for a bit too. So the progress function should be returning a bool True to continue and False to stop loading. As your example returns None BinaryNinja cancels its loading. Change your code to

    >>> def progress(x, y):
    ...  print(x,y)
    ...  return True
    ... 
    >>> load("foo.bndb", progress_func=progress)
    <BinaryView: 'foo.bndb', start 0x4fb80000, len 0x5064>
  2. plafosse commented on Mar 21, 2023

    @plafosse
    Member

    On think I noticed I can fix though which might have helped you out is I'm adding a LogInfo to indicate that loading has been cancelled. This would have probably clued you into the problem. Additionally the documentation should be improved to state this.

  3. added
    State: WontfixIssue will probably never be fixed
    Impact: LowIssue is a papercut or has a good, supported workaround
    Effort: TrivialIssues require < 1 day of work
    and removed
    State: WontfixIssue will probably never be fixed
    on Mar 21, 2023
  4. added this to the Braize milestone on Mar 21, 2023
  5. jprokos26 commented on Mar 21, 2023

    @jprokos26
    ContributorAuthor

    @plafosse Great, I can see the progress function when supplying a Callable that returns true.

    With regards to the second issue, the progress_func still is not called when supplying a non-bndb file to open_view:

    (Pdb) print(path, bv_path)
    libc.so.6 libc.so.6.bndb
    (Pdb) open_view(bv_path, progress_func=self.progress)
    515382 1000000...
    <BinaryView: 'libc.so.6.bndb', len 0x227ed8>
    (Pdb) open_view(path, progress_func=self.progress)
    <BinaryView: 'libc.so.6.bndb', len 0x227ed8>
    

    Should I open a new PR for this issue?

  6. plafosse commented on Mar 21, 2023

    @plafosse
    Member

    So... oddly enough the API for opening a non-bndb doesn't have a way of accepting a progress_function. This would actually require a considerable refactor to accomplish. We could make this happen but only after this issue is addressed #2604

  7. jprokos26 commented on Mar 22, 2023

    @jprokos26
    ContributorAuthor

    Got it, thanks for the clarification!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Effort: TrivialIssues require < 1 day of workImpact: LowIssue is a papercut or has a good, supported workaround

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions