Created
August 27, 2016 00:50
-
-
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
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/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