-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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