from strongarm.macho import CPU_TYPE, MachoAnalyzer, MachoParser def find_selector_implementations(binary): print(f"Analyzing Mach-O slice built for {CPU_TYPE(binary.cpu_type).name}") analyzer = MachoAnalyzer(binary) desired_selector = "URLSession:didReceiveChallenge:completionHandler:" implementations = analyzer.get_imps_for_sel(desired_selector) for imp_function in implementations: instruction_size = 4 instruction_count = int( (imp_function.end_address - imp_function.start_address) / instruction_size) print( f"Found implementation of @selector({desired_selector}) at [{hex(imp_function.start_address)}" f" - {hex(imp_function.end_address)}] ({instruction_count} instructions)" ) parser = MachoParser("./tests/bin/TestBinary4") binary_64 = parser.get_arm64_slice() binary_32 = parser.get_armv7_slice() for binary in [binary_64, binary_32]: # equivalent to parser.slices find_selector_implementations(binary)
# this script expects paths in the form of: /Users/philliptennen/apps/Stride/saved/ # extract app name app_name = [component for component in folder.split("/")][-3] paths = [os.path.join(folder, app_name)] frameworks_folder = os.path.join(folder, "Frameworks") for framework_name in os.listdir(frameworks_folder): if ".framework" not in framework_name: continue binary_name = framework_name.split(".framework")[0] binary_path = os.path.join(frameworks_folder, framework_name, binary_name) paths.append(binary_path) i = 0 for path in paths: parser = MachoParser(path) binary = parser.get_arm64_slice() load_commands = binary.load_dylib_commands for cmd in load_commands: dylib_name_addr = binary.get_virtual_base( ) + cmd.binary_offset + cmd.dylib.name.offset dylib_name = binary.read_string_at_address(dylib_name_addr) print(f"{path} loads {dylib_name}") i += 1 print(i) end = time() print(end - start)
def setup_method(self) -> None: parser = MachoParser(TestCodeSignParser.TARGET_PATH) self.binary = parser.get_arm64_slice() assert self.binary self.codesign_parser = CodesignParser(self.binary)