Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
03c1387
Add automatic CI linting to GitHub actions
sam-f0 Feb 6, 2025
761f095
Add command aliases
sam-f0 Feb 6, 2025
90118e4
LLDB version check before executing commands
Feb 6, 2025
29d658a
Fixed the error handling in print_memory_address. Added process check…
Feb 6, 2025
44bbf24
Fix some eggregious formatting
sam-f0 Feb 6, 2025
542de8b
Modified colours and symbols for print_message function.
Feb 6, 2025
b6535ee
Implemented the xinfo command
Feb 6, 2025
96bc304
Check valid address range on `xinfo` command
Feb 6, 2025
74f6432
User can order context sections with list in the output_order setting.
Feb 6, 2025
64cbe04
Order context sections
Feb 6, 2025
bea42fa
Checksec command
Feb 6, 2025
65f7a5b
Scan command.
Feb 6, 2025
38695bd
Improved is_code function.
Feb 6, 2025
afc518e
Dereference command
Feb 6, 2025
71787f4
Added target to is_code call in dereference_util.py
Feb 6, 2025
37bc11a
Fixed LLDB version bug on Mac
Feb 6, 2025
e912a23
Fix py313 post release
sam-f0 Feb 6, 2025
690b02f
Bugfix/fixing xcode terminal issues
Feb 6, 2025
edcc931
Bugfix/handle dirty memory regions
Feb 6, 2025
4b84022
Feature/improve display code
Feb 6, 2025
3f7867c
Missing version
sam-f0 Feb 6, 2025
3c6d685
Fix CI
sam-f0 Feb 6, 2025
ead00d5
Refactor output utilities
Feb 6, 2025
0c6b5d4
Move command functions
Feb 6, 2025
99d57f2
Seperate data and output
Feb 6, 2025
db33981
Code changes from test branch
Feb 6, 2025
6824faa
Bugfix/colouring instructions
Feb 6, 2025
60a2399
Added a setting to truncate output lines to fit terminal width.
Feb 6, 2025
c856bfd
Formatting cleanup
sam-f0 Feb 6, 2025
6d34d1a
Handle missing inode info gracefully
sam-f0 Feb 6, 2025
cd4ac7e
Switch to using shutil.get_terminal_size() for compatibility
sam-f0 Feb 7, 2025
2a20ebe
Add feature for heap enumeration (#91)
f0alex Jul 7, 2025
a614039
Merge branch 'main' into feature/beta-2.0-release
Aug 8, 2025
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
88 changes: 88 additions & 0 deletions .github/workflows/style.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
name: F0 style checking
run-name: Running style checks on ${{ github.ref_name }} following push by ${{ github.actor }}

on: push
jobs:
Check-isort:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: python-isort
uses: isort/isort-action@v1.1.1
with:
configuration: "--check-only --profile black --diff --verbose"
# Check-mypy:
# runs-on: ubuntu-latest
# steps:
# - name: Checkout
# uses: actions/checkout@v3
# - name: python-mypy
# uses: jpetrucciani/mypy-check@master
# with:
# path: '.'
# mypy_flags: '--config-file .mypy.ini'
Check-black:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: python-black
uses: psf/black@stable
with:
options: "--check --line-length=120"
src: "."
Check-flake8:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set up Python environment
uses: actions/setup-python@v4
with:
python-version: "3.11"
- name: flake8 Lint
uses: py-actions/flake8@v2.3.0
with:
max-line-length: "120"
path: "."
ignore: "E203,W503"
# Check-pydocstyle:
# runs-on: ubuntu-latest
# steps:
# - name: Checkout
# uses: actions/checkout@v3
# - name: pydocstyle
# uses: foundryzero/pydocstyle-action@v1.2.6
# with:
# path: "."

# Check-pylint:
# runs-on: ubuntu-latest
# steps:
# - name: Checkout
# uses: actions/checkout@v3
# - name: pylint
# uses: foundryzero/pylint-action@v1.0.6
# with:
# match: "binder_trace/**/*.py"
# requirements_file: "binder_trace/requirements.txt"

Check-tox:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']

steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install tox tox-gh-actions
- name: Test with tox
run: tox
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
__pycache__/
__pycache__/
.venv/
3 changes: 3 additions & 0 deletions .isort.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[settings]
line_length = 120
profile = black
8 changes: 8 additions & 0 deletions .mypy.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Global options:

[mypy]
follow_imports = silent
ignore_missing_imports = True
show_column_numbers = True
pretty = True
strict = True
2 changes: 2 additions & 0 deletions .pydocstyle
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[pydocstyle]
match = (?!test_).*\.py
2 changes: 2 additions & 0 deletions .pylintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[FORMAT]
max-line-length=120
29 changes: 15 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,20 +59,21 @@ Settings are stored in a file `.llef` located in your home directory formatted a

##### Available Settings

| Setting | Type | Description |
| ------------------ | ------- | -------------------------------------------------- |
| color_output | Boolean | Enable/disable color terminal output |
| register_coloring | Boolean | Enable/disable register coloring |
| show_legend | Boolean | Enable/disable legend output |
| show_registers | Boolean | Enable/disable registers output |
| show_stack | Boolean | Enable/disable stack output |
| show_code | Boolean | Enable/disable code output |
| show_threads | Boolean | Enable/disable threads output |
| show_trace | Boolean | Enable/disable trace output |
| force_arch | String | Force register display architecture (experimental) |
| rebase_addresses | Boolean | Enable/disable address rebase output |
| rebase_offset | Int | Set the rebase offset (default 0x100000) |
| show_all_registers | Boolean | Enable/disable extended register output |
| Setting | Type | Description |
| ----------------------- | ------- | -------------------------------------------------- |
| color_output | Boolean | Enable/disable color terminal output |
| register_coloring | Boolean | Enable/disable register coloring |
| show_legend | Boolean | Enable/disable legend output |
| show_registers | Boolean | Enable/disable registers output |
| show_stack | Boolean | Enable/disable stack output |
| show_code | Boolean | Enable/disable code output |
| show_threads | Boolean | Enable/disable threads output |
| show_trace | Boolean | Enable/disable trace output |
| force_arch | String | Force register display architecture (experimental) |
| rebase_addresses | Boolean | Enable/disable address rebase output |
| rebase_offset | Int | Set the rebase offset (default 0x100000) |
| show_all_registers | Boolean | Enable/disable extended register output |
| enable_darwin_heap_scan | Boolean | Enable/disable more accurate heap scanning for Darwin-based platforms. Uses the Darwin malloc introspection API, executing code in the address space of the target application using LLDB's evaluation engine. |

#### llefcolorsettings
Allows setting LLEF GUI colors:
Expand Down
8 changes: 5 additions & 3 deletions arch/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Arch module __init__.py"""

from typing import Type

from lldb import SBTarget
Expand All @@ -7,10 +8,11 @@
from arch.arm import Arm
from arch.base_arch import BaseArch
from arch.i386 import I386
from arch.x86_64 import X86_64
from arch.ppc import PPC
from arch.x86_64 import X86_64
from common.constants import MSG_TYPE
from common.util import extract_arch_from_triple, print_message
from common.output_util import print_message
from common.util import extract_arch_from_triple

# macOS devices running arm chips identify as arm64.
# aarch64 and arm64 backends have been merged, so alias arm64 to aarch64.
Expand All @@ -23,7 +25,7 @@
"aarch64": Aarch64,
"arm64": Aarch64,
"arm64e": Aarch64,
"powerpc": PPC
"powerpc": PPC,
}


Expand Down
4 changes: 1 addition & 3 deletions arch/aarch64.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,4 @@ class Aarch64(BaseArch):
"m": 0xF,
}

flag_registers = [
FlagRegister("cpsr", _cpsr_register_bit_masks)
]
flag_registers = [FlagRegister("cpsr", _cpsr_register_bit_masks)]
4 changes: 1 addition & 3 deletions arch/arm.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,4 @@ class Arm(BaseArch):
"t": 0x20,
}

flag_registers = [
FlagRegister("cpsr", _cpsr_register_bit_masks)
]
flag_registers = [FlagRegister("cpsr", _cpsr_register_bit_masks)]
1 change: 1 addition & 0 deletions arch/base_arch.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
@dataclass
class FlagRegister:
"""FlagRegister dataclass to store register name / bitmask associations"""

name: str
bit_masks: Dict[str, int]

Expand Down
3 changes: 2 additions & 1 deletion arch/i386.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""i386 architecture definition."""

from arch.base_arch import BaseArch, FlagRegister


Expand Down Expand Up @@ -47,5 +48,5 @@ class I386(BaseArch):

flag_registers = [
FlagRegister("eflags", _eflags_register_bit_masks),
FlagRegister("rflags", _eflags_register_bit_masks)
FlagRegister("rflags", _eflags_register_bit_masks),
]
5 changes: 3 additions & 2 deletions arch/ppc.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""PowerPC architecture definition."""

from arch.base_arch import BaseArch, FlagRegister


Expand Down Expand Up @@ -42,10 +43,10 @@ class PPC(BaseArch):
"cr0_lt": 0x80000000,
"cr0_gt": 0x40000000,
"cr0_eq": 0x20000000,
"cr0_so": 0x10000000
"cr0_so": 0x10000000,
}

flag_registers = [
FlagRegister("cr", _cr_register_bit_masks),
FlagRegister("xer", _xer_register_bit_masks)
FlagRegister("xer", _xer_register_bit_masks),
]
3 changes: 2 additions & 1 deletion arch/x86_64.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""x86_64 architecture definition."""

from arch.base_arch import BaseArch, FlagRegister


Expand Down Expand Up @@ -51,5 +52,5 @@ class X86_64(BaseArch):
# rflags and eflags bit masks are identical for the lower 32-bits
flag_registers = [
FlagRegister("rflags", _eflag_register_bit_masks),
FlagRegister("eflags", _eflag_register_bit_masks)
FlagRegister("eflags", _eflag_register_bit_masks),
]
11 changes: 8 additions & 3 deletions commands/base_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
class BaseCommand(ABC):
"""An abstract base class for all commands."""

alias_set = {}

@abstractmethod
def __init__(self) -> None:
pass
Expand Down Expand Up @@ -52,8 +54,11 @@ def lldb_self_register(cls, debugger: SBDebugger, module_name: str) -> None:
if cls.container is not None:
command = f"command script add -c {module_name}.{cls.__name__} {cls.container.container_verb} {cls.program}"
else:
command = (
f"command script add -c {module_name}.{cls.__name__} {cls.program}"
)
command = f"command script add -c {module_name}.{cls.__name__} {cls.program}"

debugger.HandleCommand(command)

# If alias_set exists, then load it into LLDB.
for alias, arguments in cls.alias_set.items():
alias_command = f"command alias {alias} {cls.program} {arguments}"
debugger.HandleCommand(alias_command)
5 changes: 4 additions & 1 deletion commands/base_container.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Base container definition."""

from abc import ABC, abstractmethod

from lldb import SBDebugger
Expand All @@ -25,5 +26,7 @@ def get_long_help() -> str:
@classmethod
def lldb_self_register(cls, debugger: SBDebugger, _: str) -> None:
"""Automatically register a container."""
container_command = f'command container add -h "{cls.get_long_help()}" -H "{cls.get_short_help()}" {cls.container_verb}'
container_command = (
f'command container add -h "{cls.get_long_help()}" -H "{cls.get_short_help()}" {cls.container_verb}'
)
debugger.HandleCommand(container_command)
5 changes: 3 additions & 2 deletions commands/base_settings.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
"""Base settings command class."""

import argparse
import shlex
from typing import Any, Dict
from abc import ABC, abstractmethod
from typing import Any, Dict

from lldb import SBCommandReturnObject, SBDebugger, SBExecutionContext

from commands.base_command import BaseCommand
from common.util import output_line
from common.output_util import output_line


class BaseSettingsCommand(BaseCommand, ABC):
Expand Down
Loading