Skip to content

Instantly share code, notes, and snippets.

@pudquick
Created August 27, 2016 00:50
Show Gist options
  • Save pudquick/752445c3425ddb10f45787bd56f448f3 to your computer and use it in GitHub Desktop.
Save pudquick/752445c3425ddb10f45787bd56f448f3 to your computer and use it in GitHub Desktop.
Automatic symbol definition discovery for OS X binaries and their linked shared libraries
#!/usr/bin/python
"""Usage: symfind BINARY_PATH SEARCH_STR
symfind automates the usage of otool and nm to attempt to find out which
binary a symbol is defined in that's used within BINARY_PATH's code.
"""
import subprocess, os.path, sys, getopt
def find_symbol(binary_path, symbol_str):
# Check the binary itself first
symbols_raw = subprocess.check_output(['/usr/bin/nm', '-a', binary_path])
symbols = [x for x in symbols_raw.splitlines() if not ' u ' in x.lower()]
symbols = [x for x in symbols if symbol_str.lower() in x.lower()]
if symbols:
print "\nFOUND:", binary_path
for x in symbols:
print x
# Root linked images
root_images_raw = subprocess.check_output(['/usr/bin/otool', '-L', binary_path])
root_images = [x for x in root_images_raw.splitlines() if x[0] == '\t']
root_images = [x for x in root_images if ' (compatibility version' in x]
root_images = [x.split('\t',1)[-1].split(' (compatibility version', 1)[0] for x in root_images]
# This currently weeds out relative paths #TODO
root_images = [x for x in root_images if os.path.exists(x)]
for image in root_images:
symbols_raw = subprocess.check_output(['/usr/bin/nm', '-a', image])
symbols = [x for x in symbols_raw.splitlines() if not ' u ' in x.lower()]
symbols = [x for x in symbols if symbol_str.lower() in x.lower()]
if symbols:
print "\nFOUND:", image
for x in symbols:
print x
def usage():
print __doc__
sys.exit()
def main():
try:
opts, args = getopt.getopt(sys.argv[1:], "h", ["help"])
except getopt.GetoptError, err:
print str(err)
usage()
for o, a in opts:
usage()
if len(args) != 2:
usage()
binary_path = args[0]
symbol_str = args[1]
if not os.path.exists(binary_path):
usage()
find_symbol(binary_path, symbol_str)
sys.exit(0)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment