Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion capa/loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,18 @@ def get_extractor(

logger.debug("idalib: opening database...")
idapro.enable_console_messages(False)

# `-R` (load resources) is only valid when loading a new input file.
# if an IDA database already exists, open it without `-R`.
# ref: https://github.com/mandiant/capa/issues/2950
has_existing_database = any(
input_path.with_name(input_path.name + ext).exists()
for ext in (".ida", ".i64", ".id0")
)
open_database_args = "-Olumina:host=0.0.0.0 -Osecondary_lumina:host=0.0.0.0"
if not has_existing_database:
open_database_args += " -R"
Comment on lines +399 to +408
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This logic for determining the IDA database arguments is duplicated in tests/fixtures.py. To improve maintainability and avoid future inconsistencies, consider extracting this logic into a shared helper function.

For example, you could create a function in this module or a more specific IDA helper module:

IDA_DB_EXTENSIONS = (".ida", ".i64", ".id0")
IDA_LUMINA_ARGS = "-Olumina:host=0.0.0.0 -Osecondary_lumina:host=0.0.0.0"

def get_ida_open_database_args(input_path: Path) -> str:
    """
    Get the arguments for opening an IDA database, conditionally adding the `-R` flag.
    `-R` (load resources) is only valid when loading a new input file.
    If an IDA database already exists, we open it without `-R`.
    """
    # ref: https://github.com/mandiant/capa/issues/2950
    has_existing_database = any(
        input_path.with_name(input_path.name + ext).exists()
        for ext in IDA_DB_EXTENSIONS
    )
    open_database_args = IDA_LUMINA_ARGS
    if not has_existing_database:
        open_database_args += " -R"
    return open_database_args

You could then call this function here and in tests/fixtures.py to avoid the code duplication. Using constants for the extensions and arguments would also improve readability.


with console.status("analyzing program...", spinner="dots"):
# we set the primary and secondary Lumina servers to 0.0.0.0 to disable Lumina,
# which sometimes provides bad names, including overwriting names from debug info.
Expand All @@ -408,7 +420,7 @@ def get_extractor(
# -1 - Generic errors (database already open, auto-analysis failed, etc.)
# -2 - User cancelled operation
ret = idapro.open_database(
str(input_path), run_auto_analysis=True, args="-Olumina:host=0.0.0.0 -Osecondary_lumina:host=0.0.0.0 -R"
str(input_path), run_auto_analysis=True, args=open_database_args
)
if ret != 0:
raise RuntimeError("failed to analyze input file")
Expand Down
13 changes: 12 additions & 1 deletion tests/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,17 @@ def get_idalib_extractor(path: Path):

idapro.enable_console_messages(False)

# `-R` (load resources) is only valid when loading a new input file.
# if an IDA database already exists, open it without `-R`.
# ref: https://github.com/mandiant/capa/issues/2950
has_existing_database = any(
path.with_name(path.name + ext).exists()
for ext in (".ida", ".i64", ".id0")
)
open_database_args = "-Olumina:host=0.0.0.0 -Osecondary_lumina:host=0.0.0.0"
if not has_existing_database:
open_database_args += " -R"
Comment on lines +224 to +233
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This logic is a duplicate of the code in capa/loader.py. As mentioned in my other comment, this should be extracted into a shared helper function to improve maintainability.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test code seems to be duplicated from the source, so I followed the same approach.


# we set the primary and secondary Lumina servers to 0.0.0.0 to disable Lumina,
# which sometimes provides bad names, including overwriting names from debug info.
#
Expand All @@ -233,7 +244,7 @@ def get_idalib_extractor(path: Path):
# -1 - Generic errors (database already open, auto-analysis failed, etc.)
# -2 - User cancelled operation
ret = idapro.open_database(
str(path), run_auto_analysis=True, args="-Olumina:host=0.0.0.0 -Osecondary_lumina:host=0.0.0.0 -R"
str(path), run_auto_analysis=True, args=open_database_args
)
if ret != 0:
raise RuntimeError("failed to analyze input file")
Expand Down
Loading