def mach_o_change(path, what, value):
def do_macho(file, bits, endian):<EOL><INDENT>cputype, cpusubtype, filetype, ncmds, sizeofcmds, flags = read_data(file, endian, <NUM_LIT:6>)<EOL>if bits == <NUM_LIT:64>:<EOL><INDENT>read_data(file, endian)<EOL><DEDENT>for n in range(ncmds):<EOL><INDENT>where = file.tell()<EOL>cmd, cmdsize = read_data(file, endian, <NUM_LIT:2>)<EOL>if cmd == LC_LOAD_DYLIB:<EOL><INDENT>name_offset = read_data(file, endian)<EOL>file.seek(where + name_offset, os.SEEK_SET)<EOL>load = file.read(cmdsize - name_offset).decode()<EOL>load = load[:load.index('<STR_LIT>')]<EOL>if load == what:<EOL><INDENT>file.seek(where + name_offset, os.SEEK_SET)<EOL>file.write(value.encode() + '<STR_LIT>'.encode())<EOL><DEDENT><DEDENT>file.seek(where + cmdsize, os.SEEK_SET)<EOL><DEDENT><DEDENT>def do_file(file, offset=<NUM_LIT:0>, size=maxint):<EOL><INDENT>file = fileview(file, offset, size)<EOL>magic = read_data(file, BIG_ENDIAN)<EOL>if magic == FAT_MAGIC:<EOL><INDENT>nfat_arch = read_data(file, BIG_ENDIAN)<EOL>for n in range(nfat_arch):<EOL><INDENT>cputype, cpusubtype, offset, size, align = read_data(file, BIG_ENDIAN, <NUM_LIT:5>)<EOL>do_file(file, offset, size)<EOL><DEDENT><DEDENT>elif magic == MH_MAGIC:<EOL><INDENT>do_macho(file, <NUM_LIT:32>, BIG_ENDIAN)<EOL><DEDENT>elif magic == MH_CIGAM:<EOL><INDENT>do_macho(file, <NUM_LIT:32>, LITTLE_ENDIAN)<EOL><DEDENT>elif magic == MH_MAGIC_64:<EOL><INDENT>do_macho(file, <NUM_LIT:64>, BIG_ENDIAN)<EOL><DEDENT>elif magic == MH_CIGAM_64:<EOL><INDENT>do_macho(file, <NUM_LIT:64>, LITTLE_ENDIAN)<EOL><DEDENT><DEDENT>assert(len(what) >= len(value))<EOL>do_file(open(path, '<STR_LIT>'))<EOL>
Replace a given name (what) in any LC_LOAD_DYLIB command found in
the given binary with a new name (value), provided it's shorter.