Skip to content

Instantly share code, notes, and snippets.

@hbcbh1999
Forked from moyix/check_for_ffast_math.py
Created September 27, 2022 03:09
Show Gist options
  • Save hbcbh1999/05473bc2138a712ba9a840cd9ab06b53 to your computer and use it in GitHub Desktop.
Save hbcbh1999/05473bc2138a712ba9a840cd9ab06b53 to your computer and use it in GitHub Desktop.
Hacky script to check for the set_fast_math constructor in an executable/shared library using objdump
#!/usr/bin/env python
import subprocess
import re
import sys
def get_init_array(filename):
# Call objdump -s -j .init_array <filename> to get the contents of the .init_array section
try:
objdump_output = subprocess.check_output(['objdump', '-s', '-j', '.init_array', filename], stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
return []
objdump_output = objdump_output.decode('utf-8')
objdump_output = objdump_output.split('\n')
found_contents = False
constructors = []
for line in objdump_output:
if line.startswith("Contents of section .init_array:"):
found_contents = True
continue
if found_contents:
if not line.strip():
break
line_re = re.compile(r'^ *[0-9a-f]+ (([0-9a-f]+) ([0-9a-f]+)) ?(([0-9a-f]+) ([0-9a-f]+))?')
m = line_re.match(line)
if not m: continue
addr = m.group(1).replace(' ', '')
addr = int.from_bytes(bytes.fromhex(addr), 'little')
constructors.append(addr)
try:
addr = m.group(4)
if not addr: continue
addr = addr.replace(' ', '')
addr = int.from_bytes(bytes.fromhex(addr), 'little')
constructors.append(addr)
except IndexError:
pass
return constructors
def check_for_ffast_math(filename, addr):
# Call objdump to disassemble filename at addr
objdump_process = subprocess.Popen(
['objdump', f'--start-address={hex(addr)}', '-d', filename],
stdout=subprocess.PIPE
)
found_stmxcsr, found_8040, found_rdmxcsr = False, False, False
for line in iter(lambda: objdump_process.stdout.readline(), b""):
line = line.decode('utf-8')
if "stmxcsr" in line:
found_stmxcsr = True
if "0x8040" in line:
found_8040 = True
if "ldmxcsr" in line:
found_rdmxcsr = True
if "retq" in line:
objdump_process.kill()
break
return found_stmxcsr and found_8040 and found_rdmxcsr
for filename in sys.argv[1:]:
print(f"{filename} ", end="", flush=True)
constructors = get_init_array(filename)
i = len(constructors)
print(f"({i} constructor{'s'[:i^1]}) ", end="", flush=True)
for addr in constructors:
if check_for_ffast_math(filename, addr):
print(f"contains ffast-math constructor at {hex(addr)}")
break
else:
print("is clean")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment