diff --git a/CHANGELOG.md b/CHANGELOG.md index 656fc298..3c51998e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -112,6 +112,7 @@ The table below shows which release corresponds to each branch, and what date th - [#2629][2629] Add `terminate()` method to process class that sends SIGTERM - [#2643][2643] Refactor getdents.py, add support for SYS_getdents64 - [#2647][2647] packing: Add `overlap` to overlap structures easily +- [#2669][2669] asm: try native binutils before fallback architectures [2675]: https://github.com/Gallopsled/pwntools/pull/2675 [2652]: https://github.com/Gallopsled/pwntools/pull/2652 @@ -148,8 +149,9 @@ The table below shows which release corresponds to each branch, and what date th [2641]: https://github.com/Gallopsled/pwntools/pull/2641 [2646]: https://github.com/Gallopsled/pwntools/pull/2646 [2629]: https://github.com/Gallopsled/pwntools/pull/2629 -[2638]: https://github.com/Gallopsled/pwntools/pull/2643 +[2643]: https://github.com/Gallopsled/pwntools/pull/2643 [2647]: https://github.com/Gallopsled/pwntools/pull/2647 +[2669]: https://github.com/Gallopsled/pwntools/pull/2669 ## 4.15.0 (`stable`) diff --git a/pwnlib/asm.py b/pwnlib/asm.py index f56995e6..6a73c44e 100644 --- a/pwnlib/asm.py +++ b/pwnlib/asm.py @@ -188,31 +188,37 @@ def which_binutils(util, check_version=False): # Fix up pwntools vs Debian triplet naming, and account # for 'thumb' being its own pwntools architecture. - arches = [arch] + { + aliases = { 'thumb': ['arm', 'aarch64'], - 'i386': ['x86_64', 'amd64'], 'i686': ['x86_64', 'amd64'], - 'amd64': ['x86_64', 'i386'], + 'amd64': ['x86_64'], + 'loongarch64': ['loong64'], + }.get(arch, []) + + # Some binutils can support multiple architectures. Try them as fallbacks. + fallback_arches = { + 'i386': ['x86_64', 'amd64'], + 'amd64': ['i386'], 'arm': ['aarch64'], 'mips': ['mipsel'], 'mipsel': ['mips'], - 'mips64': ['mips', 'mipsel'], - 'mips64el': ['mipsel', 'mips'], + 'mips64': ['mips64el', 'mips', 'mipsel'], + 'mips64el': ['mips64', 'mipsel', 'mips'], 'powerpc64': ['powerpc'], 'sparc64': ['sparc'], 'riscv32': ['riscv64', 'riscv'], 'riscv64': ['riscv32', 'riscv'], - 'loongarch64': ['loong64'], }.get(arch, []) + arches = [arch] + aliases + fallback_arches # If one of the candidate architectures matches the native - # architecture, use that as a last resort. + # architecture, use that as a last resort before trying fallbacks. machine = platform.machine() machine = 'i386' if machine == 'i686' else machine try: with context.local(arch = machine): if context.arch in arches: - arches.append(None) + arches = [arch] + aliases + [None] + fallback_arches except AttributeError: log.warn_once("Your local binutils won't be used because architecture %r is not supported." % machine) @@ -225,6 +231,8 @@ def which_binutils(util, check_version=False): if platform.system() == 'Windows': utils = [util + '.exe'] + # Try the explicit tools for the target architecture first, + # then the native one optionally, then fallbacks. for arch in arches: for gutil in utils: # e.g. objdump