Skip to content

Commit 545791e

Browse files
committed
fix: implemented the same pattern for all architectures
1 parent 362c2d3 commit 545791e

File tree

1 file changed

+56
-62
lines changed

1 file changed

+56
-62
lines changed

pwnlib/asm.py

+56-62
Original file line numberDiff line numberDiff line change
@@ -178,40 +178,64 @@ def which_binutils(util, check_version=False):
178178
"""
179179
arch = context.arch
180180
machine = platform.machine()
181+
path_dirs = environ["PATH"].split(os.pathsep)
181182

182-
if arch == "amd64":
183-
pattern = "*86*64*-*-{}".format(util)
184-
185-
for dir in environ["PATH"].split(os.pathsep):
186-
for res in sorted(glob(path.join(dir, pattern))):
187-
if check_version:
188-
ver = check_binutils_version(res)
189-
return res, ver
190-
return res
191-
192-
# if target is native, try native command (e.g. "as")
193-
if machine in ("x86_64", "amd64"):
194-
for dir in environ["PATH"].split(os.pathsep):
195-
res = path.join(dir, util)
196-
if os.path.exists(res) and os.access(res, os.X_OK):
183+
utils = [util]
184+
185+
# hack for homebrew-installed binutils on mac
186+
if platform.system() == 'Darwin':
187+
utils = ['g' + util, util]
188+
189+
if platform.system() == 'Windows':
190+
utils = [util + '.exe']
191+
192+
def get_patterns(prefix, tool):
193+
return [
194+
"%s*linux*-%s" % (prefix, tool),
195+
"%s*-elf-%s" % (prefix, tool),
196+
"%s-none*-%s" % (prefix, tool),
197+
"%s-%s" % (prefix, tool)
198+
]
199+
200+
def search_patterns(patterns):
201+
for pattern in patterns:
202+
for dir in path_dirs:
203+
for res in sorted(glob(path.join(dir, pattern))):
197204
if check_version:
198205
ver = check_binutils_version(res)
199206
return res, ver
200207
return res
208+
return None
209+
210+
for gutil in utils:
211+
if arch == "amd64":
212+
explicit_patterns = ["*86*64*-*-{}".format(gutil)]
213+
else:
214+
explicit_patterns = get_patterns(arch, gutil)
201215

202-
pattern = "i*86*-*-{}".format(util)
203-
for dir in environ["PATH"].split(os.pathsep):
204-
for res in sorted(glob(path.join(dir, pattern))):
205-
if check_version:
206-
ver = check_binutils_version(res)
207-
return res, ver
208-
return res
216+
found = search_patterns(explicit_patterns)
217+
if found:
218+
return found
209219

210-
print_binutils_instructions(util, context)
220+
# if host arch equals target, try native command
221+
machine = 'i386' if machine == 'i686' else machine
222+
try:
223+
with context.local(arch=machine):
224+
if context.arch == arch:
225+
for gutil in utils:
226+
for dir in path_dirs:
227+
res = path.join(dir, gutil)
228+
if os.path.exists(res) and os.access(res, os.X_OK):
229+
if check_version:
230+
ver = check_binutils_version(res)
231+
return res, ver
232+
return res
233+
except AttributeError:
234+
log.warn_once("Your local binutils won't be used because architecture %r is not supported." % machine)
211235

212236
# Fix up pwntools vs Debian triplet naming, and account
213237
# for 'thumb' being its own pwntools architecture.
214-
arches = [arch] + {
238+
aliases = {
215239
'thumb': ['arm', 'aarch64'],
216240
'i386': ['x86_64', 'amd64'],
217241
'i686': ['x86_64', 'amd64'],
@@ -222,47 +246,17 @@ def which_binutils(util, check_version=False):
222246
'riscv32': ['riscv32', 'riscv64', 'riscv'],
223247
'riscv64': ['riscv64', 'riscv32', 'riscv'],
224248
'loongarch64': ['loongarch64', 'loong64'],
225-
}.get(arch, [])
226-
227-
# If one of the candidate architectures matches the native
228-
# architecture, use that as a last resort.
229-
machine = 'i386' if machine == 'i686' else machine
230-
try:
231-
with context.local(arch = machine):
232-
if context.arch in arches:
233-
arches.append(None)
234-
except AttributeError:
235-
log.warn_once("Your local binutils won't be used because architecture %r is not supported." % machine)
236-
237-
utils = [util]
238-
239-
# hack for homebrew-installed binutils on mac
240-
if platform.system() == 'Darwin':
241-
utils = ['g'+util, util]
242-
243-
if platform.system() == 'Windows':
244-
utils = [util + '.exe']
249+
}
245250

246-
for arch in arches:
251+
for alias in aliases.get(arch, []):
247252
for gutil in utils:
248-
# e.g. objdump
249-
if arch is None:
250-
patterns = [gutil]
251-
252-
# e.g. aarch64-linux-gnu-objdump, avr-objdump
253+
if arch == "amd64" and alias == "i386":
254+
alias_patterns = ["i*86*-*-{}".format(gutil)]
253255
else:
254-
patterns = ['%s*linux*-%s' % (arch, gutil),
255-
'%s*-elf-%s' % (arch, gutil),
256-
'%s-none*-%s' % (arch, gutil),
257-
'%s-%s' % (arch, gutil)]
258-
259-
for pattern in patterns:
260-
for dir in environ['PATH'].split(os.pathsep):
261-
for res in sorted(glob(path.join(dir, pattern))):
262-
if check_version:
263-
ver = check_binutils_version(res)
264-
return res, ver
265-
return res
256+
alias_patterns = get_patterns(alias, gutil)
257+
found = search_patterns(alias_patterns)
258+
if found:
259+
return found
266260

267261
# No dice!
268262
print_binutils_instructions(util, context)

0 commit comments

Comments
 (0)