+
Skip to content

AngrDB Load Fails with KeyError During Relocation Process #5630

@aoi127

Description

@aoi127

Description

AngrDB fails to load a previously saved database due to a memory buffer overflow during the relocation process. The error occurs when perform_relocations=True (default) is used during the loading phase, even though the original project was saved with perform_relocations=False.

Steps to reproduce the bug

Script to reproduce:

import angr
from angr.angrdb import AngrDB
import os

# Use any ELF binary, particularly kernel modules
ko_file = "/path/to/your/binary.ko"  # Replace with actual binary path

load_options = {
    'auto_load_libs': False,
    'main_opts': {
        'base_addr': 0x0,
        'backend': 'elf',
    },
    'perform_relocations': False,  # Key: disable relocations during save
}

db_dir = '/tmp/angr_db/'
os.makedirs(db_dir, exist_ok=True)
db_path = os.path.join(db_dir, 'test.adb')

# Step 1: Create project with perform_relocations=False
proj = angr.Project(thing=ko_file, load_options=load_options)
proj.analyses.CFGFast(normalize=True)

# Step 2: Save to AngrDB
angrdb = AngrDB(project=proj)
angrdb.dump(db_path, kbs=[proj.kb])

# Step 3: Attempt to load (this fails)
db = AngrDB()
proj = db.load(db_path)  # KeyError: 1105312

Binary used: The issue occurs with aarch64 kernel modules (.ko files), but likely affects other ELF binaries as well.

Environment

angr environment report

angr environment report
=============================
Date: 2025-08-21 11:17:10.714541
Running in virtual environment at .venv
Platform: linux-x86_64
Python version: 3.13.5 (main, Jun 26 2025, 21:20:04) [Clang 20.1.4 ]
######## angr #########
Python found it in .venv/lib/python3.13/site-packages/angr/__init__.py
Pip version 9.2.170

Error Log:

Creating project took 30.720 seconds
Saving angrdb took 7.215 seconds
Traceback (most recent call last):
  File ".venv/lib/python3.13/site-packages/cle/memory.py", line 126, in pack
    return struct.pack_into(fmt, backer, addr - start, *data)
           ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
struct.error: pack_into requires a buffer of at least 820 bytes for packing 8 bytes at offset 812 (actual buffer size is 816)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File ".venv/lib/python3.13/site-packages/angr/angrdb/db.py", line 42, in open_db
    yield Session
  File ".venv/lib/python3.13/site-packages/angr/angrdb/db.py", line 184, in load
    loader = LoaderSerializer.load(session)
  File ".venv/lib/python3.13/site-packages/angr/angrdb/serializers/loader.py", line 157, in load
    loader = cle.Loader(BytesIO(main_object.content), main_opts=load_args[main_object])
  File ".venv/lib/python3.13/site-packages/cle/loader.py", line 185, in __init__
    self.initial_load_objects = self._internal_load(
                                ~~~~~~~~~~~~~~~~~~~^
        main_binary, *preload_libs, *force_load_libs, preloading=(main_binary, *preload_libs)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File ".venv/lib/python3.13/site-packages/cle/loader.py", line 940, in _internal_load
    obj.relocate()
    ~~~~~~~~~~~~^^
  File ".venv/lib/python3.13/site-packages/cle/backends/backend.py", line 388, in relocate
    reloc.relocate()
    ~~~~~~~~~~~~~~^^
  File ".venv/lib/python3.13/site-packages/cle/backends/relocation.py", line 137, in relocate
    self.owner.memory.pack_word(self.dest_addr, self.value)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".venv/lib/python3.13/site-packages/cle/memory.py", line 145, in pack_word
    return self.pack(addr, self._arch.struct_fmt(size=size, signed=signed, endness=endness), data)
           ~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".venv/lib/python3.13/site-packages/cle/memory.py", line 130, in pack
    raise KeyError(addr)  # pylint: disable=raise-missing-from
    ^^^^^^^^^^^^^^^^^^^^
KeyError: 1105312

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "tests/test_angr_db.py", line 50, in <module>
    proj = db.load(db_path)
  File ".venv/lib/python3.13/site-packages/angr/angrdb/db.py", line 175, in load
    with self.open_db(db_str) as Session, self.session_scope(Session) as session:
         ~~~~~~~~~~~~^^^^^^^^
  File "/usr/lib/python3.13/contextlib.py", line 162, in __exit__
    self.gen.throw(value)
    ~~~~~~~~~~~~~~^^^^^^^
  File ".venv/lib/python3.13/site-packages/angr/angrdb/db.py", line 46, in open_db
    raise AngrDBError from ex
angr.errors.AngrDBError

Additional context

Root Cause Analysis:

The issue stems from inconsistency between save and load behavior:

  1. During Save: Project created with perform_relocations=False, so relocations are not performed and memory layout is preserved as-is.

  2. During Load: cle.Loader constructor defaults to perform_relocations=True (see cle/loader.py:77), attempting to perform relocations on binary data that was saved without relocations.

Call Chain:

db.load() 
→ LoaderSerializer.load(session) 
→ cle.Loader(BytesIO(main_object.content), main_opts=load_args[main_object]) 
→ obj.relocate()

Technical Details:

The LoaderSerializer.load() method at angr/angrdb/serializers/loader.py:157 doesn't preserve the original perform_relocations setting:

loader = cle.Loader(BytesIO(main_object.content), main_opts=load_args[main_object])

The main_opts doesn't include the original perform_relocations=False setting, causing the loader to default to perform_relocations=True and attempt relocations on data that wasn't designed for it.

Impact:

This prevents using AngrDB for projects requiring perform_relocations=False, which is common for:

  • Kernel modules analysis
  • Embedded binaries
  • Cases requiring precise memory layout preservation

Suggested Fix:

The AngrDB serialization should preserve and restore the original loader options, particularly the perform_relocations setting. This could be implemented by:

  1. Storing the complete loader configuration in the database
  2. Restoring all original loader options during deserialization
  3. Adding explicit handling for the perform_relocations parameter in LoaderSerializer

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething is brokenneeds-triageIssue has yet to be looked at by a maintainer

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载