Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: asm() using the incorrect assembler for amd64 architecture #2558

Open
wants to merge 2 commits into
base: dev
Choose a base branch
from
Open
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
104 changes: 64 additions & 40 deletions pwnlib/asm.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,65 @@ def which_binutils(util, check_version=False):
Exception: Could not find 'as' installed for ContextType(arch = 'msp430')
"""
arch = context.arch
machine = platform.machine()
path_dirs = environ["PATH"].split(os.pathsep)

utils = [util]

# hack for homebrew-installed binutils on mac
if platform.system() == 'Darwin':
utils = ['g' + util, util]

if platform.system() == 'Windows':
utils = [util + '.exe']

def get_patterns(prefix, tool):
return [
"%s*linux*-%s" % (prefix, tool),
"%s*-elf-%s" % (prefix, tool),
"%s-none*-%s" % (prefix, tool),
"%s-%s" % (prefix, tool)
]

def search_patterns(patterns):
for pattern in patterns:
for dir in path_dirs:
for res in sorted(glob(path.join(dir, pattern))):
if check_version:
ver = check_binutils_version(res)
return res, ver
return res
return None

for gutil in utils:
if arch == "amd64":
explicit_patterns = ["*86*64*-*-{}".format(gutil)]
else:
explicit_patterns = get_patterns(arch, gutil)

found = search_patterns(explicit_patterns)
if found:
return found

# if host arch equals target, try native command
machine = 'i386' if machine == 'i686' else machine
try:
with context.local(arch=machine):
if context.arch == arch:
for gutil in utils:
for dir in path_dirs:
res = path.join(dir, gutil)
if os.path.exists(res) and os.access(res, os.X_OK):
if check_version:
ver = check_binutils_version(res)
return res, ver
return res
except AttributeError:
log.warn_once("Your local binutils won't be used because architecture %r is not supported." % machine)

# 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'],
Expand All @@ -191,48 +246,17 @@ def which_binutils(util, check_version=False):
'riscv32': ['riscv32', 'riscv64', 'riscv'],
'riscv64': ['riscv64', 'riscv32', 'riscv'],
'loongarch64': ['loongarch64', 'loong64'],
}.get(arch, [])

# If one of the candidate architectures matches the native
# architecture, use that as a last resort.
machine = platform.machine()
machine = 'i386' if machine == 'i686' else machine
try:
with context.local(arch = machine):
if context.arch in arches:
arches.append(None)
except AttributeError:
log.warn_once("Your local binutils won't be used because architecture %r is not supported." % machine)

utils = [util]

# hack for homebrew-installed binutils on mac
if platform.system() == 'Darwin':
utils = ['g'+util, util]

if platform.system() == 'Windows':
utils = [util + '.exe']
}

for arch in arches:
for alias in aliases.get(arch, []):
for gutil in utils:
# e.g. objdump
if arch is None:
patterns = [gutil]

# e.g. aarch64-linux-gnu-objdump, avr-objdump
if arch == "amd64" and alias == "i386":
alias_patterns = ["i*86*-*-{}".format(gutil)]
else:
patterns = ['%s*linux*-%s' % (arch, gutil),
'%s*-elf-%s' % (arch, gutil),
'%s-none*-%s' % (arch, gutil),
'%s-%s' % (arch, gutil)]

for pattern in patterns:
for dir in environ['PATH'].split(os.pathsep):
for res in sorted(glob(path.join(dir, pattern))):
if check_version:
ver = check_binutils_version(res)
return res, ver
return res
alias_patterns = get_patterns(alias, gutil)
found = search_patterns(alias_patterns)
if found:
return found

# No dice!
print_binutils_instructions(util, context)
Expand Down
Loading