def test_add_command(tmp_path): bin_path = pathlib.Path(get_sample('MachO/MachO64_x86-64_binary_id.bin')) original = lief.parse(bin_path.as_posix()) output = f"{tmp_path}/test_add_command.id.bin" LIB_NAME = "/usr/lib/libSystem.B.dylib" dylib_1 = lief.MachO.DylibCommand.lazy_load_dylib(LIB_NAME) dylib_2 = lief.MachO.DylibCommand.weak_lib(LIB_NAME) original.add(dylib_1) original.add(dylib_2, 0) original.remove_signature() original.write(output) new = lief.parse(output) checked, err = lief.MachO.check_layout(new) assert checked, err assert len([l for l in new.libraries if l.name == LIB_NAME]) > 0 if is_osx(): assert run_program(bin_path.as_posix()) stdout = run_program(output) print(stdout) assert re.search(r'uid=', stdout) is not None
def compile(output, extra_flags=None): if not is_osx(): return extra_flags = extra_flags if extra_flags else [] with tempfile.NamedTemporaryFile(prefix="libexample_", suffix=".c", delete=False) as ftmp: with open(ftmp.name, 'w') as f: f.write(LIBRARY_CODE) COMPILER = "/usr/bin/clang" CC_FLAGS = ['-fPIC', '-shared'] extra_flags = [] if extra_flags is None else extra_flags cmd = [COMPILER] + extra_flags + CC_FLAGS + ['-o', output] + [ftmp.name] print("Compile 'libexample' with: {}".format(" ".join(cmd))) with Popen(cmd, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) as proc: output = proc.stdout.read() print(output) return output return None
def load(config): """Returns a dictonary (key=path, value=weight) loaded from data file.""" xdg_aj_home = os.path.join( os.path.expanduser('~'), '.local', 'share', 'autojump') if is_osx() and os.path.exists(xdg_aj_home): migrate_osx_xdg_data(config) if os.path.exists(config['data_path']): # example: u'10.0\t/home/user\n' -> ['10.0', u'/home/user'] parse = lambda line: line.strip().split('\t') correct_length = lambda x: len(x) == 2 # example: ['10.0', u'/home/user'] -> (u'/home/user', 10.0) tupleize = lambda x: (x[1], float(x[0])) try: with open( config['data_path'], 'r', encoding='utf-8', errors='replace') as f: return dict( imap( tupleize, ifilter(correct_length, imap(parse, f)))) except (IOError, EOFError): return load_backup(config) return {}
def test_id(self): original = lief.parse(get_sample("MachO/MachO64_x86-64_binary_id.bin")) _, output = tempfile.mkstemp(prefix="lief_id_remove_cmd") # Extend UUID uuid_cmd = original[lief.MachO.LOAD_COMMAND_TYPES.UUID] original_size = uuid_cmd.size original.extend(uuid_cmd, 0x100) # Extend __LINKEDIT (last one) original_linkedit_size = original.get_segment("__LINKEDIT").file_size original.extend_segment(original.get_segment("__LINKEDIT"), 0x30000) original.remove_signature() original.write(output) new = lief.parse(output) self.assertEqual( new.get_segment("__LINKEDIT").file_size, original_linkedit_size + 0x30000) self.assertEqual(new[lief.MachO.LOAD_COMMAND_TYPES.UUID].size, original_size + 0x100) if is_osx() and not is_aarch64(): stdout = run_program(output) self.logger.debug(stdout) self.assertIsNotNone(re.search(r'uid=', stdout))
def test_bin2lib(tmp_path): file_path = "MachO/mbedtls_selftest_arm64.bin" if is_aarch64( ) else "MachO/mbedtls_selftest_x86_64.bin" bin_path = pathlib.Path(get_sample(file_path)) original = lief.parse(bin_path.as_posix()) output = f"{tmp_path}/libtest.dylib" header: lief.MachO.Header = original.header header.file_type = lief.MachO.FILE_TYPES.DYLIB # Create LC_ID_DYLIB command original.add(lief.MachO.DylibCommand.id_dylib(output, 0, 1, 2)) # Create a new export :) ADDR = 0x10000D782 if header.cpu_type == lief.MachO.CPU_TYPES.x86_64 else 0x10004F3F4 assert original.add_exported_function(ADDR, "_lief_test_export") original.write(output) new = lief.parse(output) checked, err = lief.MachO.check_layout(new) assert checked, err if is_osx(): sign(output) print(f"Loading {output}") lib = ctypes.cdll.LoadLibrary(output) assert lib assert lib.lief_test_export
def test_add_section_ssh(tmp_path): bin_path = pathlib.Path(get_sample("MachO/MachO64_x86-64_binary_sshd.bin")) original = lief.parse(bin_path.as_posix()) output = f"{tmp_path}/test_add_section_sshd.sshd.bin" page_size = original.page_size # Add 3 section into __TEXT __text = original.get_segment("__TEXT") for i in range(3): section = lief.MachO.Section(f"__text_{i}") section.content = [0xC3] * 0x100 original.add_section(__text, section) assert original.virtual_size % page_size == 0 assert __text.virtual_size % page_size == 0 original.remove_signature() original.write(output) new = lief.parse(output) checked, err = lief.MachO.check_layout(new) assert checked, err if is_osx(): assert run_program(bin_path.as_posix(), args=["--help"]) stdout = run_program(output, args=["--help"]) print(stdout) assert re.search(r'OpenSSH_6.9p1, LibreSSL 2.1.8', stdout) is not None
def test_remove_cmd(tmp_path): bin_path = pathlib.Path(get_sample('MachO/MachO64_x86-64_binary_id.bin')) original = lief.parse(bin_path.as_posix()) output = f"{tmp_path}/test_remove_cmd.id.bin" uuid_cmd = original[lief.MachO.LOAD_COMMAND_TYPES.UUID] original.remove(uuid_cmd) original.remove_command(len(original.commands) - 1) original.write(output) new = lief.parse(output) checked, err = lief.MachO.check_layout(new) assert checked, err assert lief.MachO.LOAD_COMMAND_TYPES.UUID not in new assert lief.MachO.LOAD_COMMAND_TYPES.CODE_SIGNATURE not in new if is_osx(): assert run_program(bin_path.as_posix()) stdout = run_program(output) print(stdout) assert re.search(r'uid=', stdout) is not None
def test_rm_symbols(tmp_path): bin_path = pathlib.Path( get_sample("MachO/MachO64_x86-64_binary_sym2remove.bin")) original = lief.parse(bin_path.as_posix()) output = f"{tmp_path}/{bin_path.name}" for s in ["__ZL6BANNER", "_remove_me"]: assert original.can_remove_symbol(s) original.remove_symbol(s) original.write(output) new = lief.parse(output) checked, err = lief.MachO.check_layout(new) assert checked, err assert new.get_symbol("__ZL6BANNER") is None assert new.get_symbol("_remove_me") is None if is_osx(): assert run_program(bin_path.as_posix()) stdout = run_program(output) print(stdout) assert re.search(r'Hello World', stdout) is not None
def test_unexport(tmp_path): bin_path = pathlib.Path( get_sample("MachO/MachO64_x86-64_binary_sym2remove.bin")) original = lief.parse(bin_path.as_posix()) output = f"{tmp_path}/{bin_path.name}" exported = {s.name for s in original.symbols if s.has_export_info} assert "_remove_me" in exported original.unexport("_remove_me") original.write(output) new = lief.parse(output) exported = {s.name for s in new.symbols if s.has_export_info} assert "_remove_me" not in exported checked, err = lief.MachO.check_layout(new) assert checked, err if is_osx(): assert run_program(bin_path.as_posix()) stdout = run_program(output) print(stdout) assert re.search(r'Hello World', stdout) is not None
def test_objc_x86_64(tmp_path): bin_path = pathlib.Path(get_sample("MachO/test_objc_x86_64.macho")) original = lief.parse(bin_path.as_posix()) output = f"{tmp_path}/{bin_path.name}" for i in range(50): segment = lief.MachO.SegmentCommand(f"__LIEF_{i}", [i] * (0x457 + i)) segment = original.add(segment) # Extend the symbols table for i in range(10): sym = f"_foooo_{i}" original.add_exported_function(original.imagebase + i * 8, sym) sym = f"_foooo2_{i}" original.add_local_symbol(original.entrypoint + i * 8, sym) functions = original.function_starts.functions functions *= 2 sorted(functions) original.function_starts.functions = functions original.write(output) new = lief.parse(output) checked, err = lief.MachO.check_layout(new) assert checked, err if is_osx(): assert run_program(bin_path.as_posix()) stdout = run_program(output) print(stdout) assert re.search(r'Printing Process Completed', stdout) is not None
def test_unexport(self): original = lief.parse(get_sample('MachO/MachO64_x86-64_binary_sym2remove.bin')) _, output = tempfile.mkstemp(prefix="lief_sym_remove_") original.unexport("_remove_me") original.write(output) if is_osx(): stdout = run_program(output) self.logger.debug(stdout) self.assertIsNotNone(re.search(r'Hello World', stdout))
def test_ssh(tmp_path): bin_path = pathlib.Path(get_sample("MachO/MachO64_x86-64_binary_sshd.bin")) output = patch(tmp_path, bin_path) new = lief.parse(output) checked, err = lief.MachO.check_layout(new) assert checked, err if is_osx(): stdout = run_program(output, args=["--help"]) print(stdout) assert re.search(r'LIEF says hello :\)', stdout) is not None
def test_ssh(self): original = lief.parse(get_sample('MachO/MachO64_x86-64_binary_sshd.bin')) _, output = tempfile.mkstemp(prefix="lief_ssh_") original.add_library(self.library_path) original.write(output) if is_osx() and is_x86_64(): stdout = run_program(output, ["--help"]) self.logger.debug(stdout) self.assertIsNotNone(re.search(r'CTOR CALLED', stdout))
def test_nm(self): original = lief.parse(get_sample('MachO/MachO64_x86-64_binary_nm.bin')) _, output = tempfile.mkstemp(prefix="lief_nm_") # Add segment without section segment = lief.MachO.SegmentCommand("__LIEF", [0x60] * 0x100) segment = original.add(segment) original.write(output) if is_osx(): stdout = run_program(output, ["-version"]) self.logger.debug(stdout) self.assertIsNotNone(re.search(r'Default target:', stdout))
def test_id(self): original = lief.parse(get_sample('MachO/MachO64_x86-64_binary_id.bin')) _, output = tempfile.mkstemp(prefix="lief_id_") # Add 50 sections for i in range(50): section = lief.MachO.Section("__lief_{:d}".format(i), [0x90] * 0x100) original.add_section(section) original.write(output) if is_osx(): stdout = run_program(output) self.logger.debug(stdout) self.assertIsNotNone(re.search(r'uid=', stdout))
def test_all(self): original = lief.parse(get_sample('MachO/MachO64_x86-64_binary_all.bin')) _, output = tempfile.mkstemp(prefix="lief_all_") # Add segment with sections segment = lief.MachO.SegmentCommand("__LIEF_2") for i in range(5): section = lief.MachO.Section("__lief_2_{:d}".format(i), [i] * 0x100) segment.add_section(section) segment = original.add(segment) original.write(output) if is_osx(): stdout = run_program(output) self.logger.debug(stdout) self.assertIsNotNone(re.search(r'Hello World: 1', stdout))
def test_all(tmp_path): bin_path = pathlib.Path(get_sample("MachO/FAT_MachO_x86-x86-64-binary_fatall.bin")) original = lief.MachO.parse(bin_path.as_posix()) output = f"{tmp_path}/{bin_path.name}" assert len(original) == 2 original.write(output) new = lief.MachO.parse(output) checked, err = lief.MachO.check_layout(new) assert checked, err if is_osx(): stdout = run_program(output) print(stdout) assert re.search(r'Hello World', stdout) is not None
def test_rm_symbol(self): original = lief.parse(get_sample('MachO/MachO64_x86-64_binary_sym2remove.bin')) _, output = tempfile.mkstemp(prefix="lief_sym_remove_") for s in ["__ZL6BANNER", "_remove_me"]: self.assertTrue(original.can_remove_symbol(s)) original.remove_symbol(s) original.write(output) new = lief.parse(output) ok, err = lief.MachO.check_layout(new) self.assertTrue(ok, err) if is_osx(): stdout = run_program(output) self.logger.debug(stdout) self.assertIsNotNone(re.search(r'Hello World', stdout))
def test_id(self): original = lief.parse(get_sample('MachO/MachO64_x86-64_binary_id.bin')) _, output = tempfile.mkstemp(prefix="lief_id_remove_cmd") uuid_cmd = original[lief.MachO.LOAD_COMMAND_TYPES.UUID] original.remove(uuid_cmd) original.remove_command(len(original.commands) - 1) original.write(output) new = lief.parse(output) self.assertFalse(lief.MachO.LOAD_COMMAND_TYPES.UUID in new) self.assertFalse(lief.MachO.LOAD_COMMAND_TYPES.CODE_SIGNATURE in new) if is_osx(): stdout = run_program(output) self.logger.debug(stdout) self.assertIsNotNone(re.search(r'uid=', stdout))
def test_ssh(self): original = lief.parse(get_sample('MachO/MachO64_x86-64_binary_sshd.bin')) _, output = tempfile.mkstemp(prefix="lief_ssh_") # Add 3 section into __TEXT __text = original.get_segment("__TEXT") for i in range(3): section = lief.MachO.Section("__text_{:d}".format(i)) section.content = [0xC3] * 0x100 original.add_section(__text, section) original.remove_signature() original.write(output) if is_osx(): print(output) stdout = run_program(output, ["--help"]) self.logger.debug(stdout) self.assertIsNotNone(re.search(r'OpenSSH_6.9p1, LibreSSL 2.1.8', stdout))
def test_all(self): sample = None if is_apple_m1(): sample = get_sample('MachO/MachO64_Aarch64_binary_all.bin') if is_x86_64(): sample = get_sample('MachO/MachO64_x86-64_binary_all.bin') original = lief.parse(sample) _, output = tempfile.mkstemp(prefix="lief_all_") original.add_library(self.library_path) original.write(output) if is_osx(): stdout = run_program(output) self.logger.debug(stdout) self.assertIsNotNone(re.search(r'CTOR CALLED', stdout))
def test_add_segment_nm(tmp_path): bin_path = pathlib.Path(get_sample("MachO/MachO64_x86-64_binary_nm.bin")) original = lief.parse(bin_path.as_posix()) output = f"{tmp_path}/test_add_segment_nm.nm.bin" # Add segment without section segment = lief.MachO.SegmentCommand("__LIEF", [0x60] * 0x100) segment = original.add(segment) original.write(output) new = lief.parse(output) checked, err = lief.MachO.check_layout(new) assert checked, err if is_osx(): assert run_program(bin_path.as_posix()) stdout = run_program(output, ["-version"]) print(stdout) assert re.search(r'Default target:', stdout) is not None
def migrate_osx_xdg_data(config): """ Older versions incorrectly used Linux XDG_DATA_HOME paths on OS X. This migrates autojump files from ~/.local/share/autojump to ~/Library/autojump """ assert is_osx(), "This function should only be run on OS X." xdg_data_home = os.path.join(os.path.expanduser('~'), '.local', 'share') xdg_aj_home = os.path.join(xdg_data_home, 'autojump') data_path = os.path.join(xdg_aj_home, 'autojump.txt'), backup_path = os.path.join(xdg_aj_home, 'autojump.txt.bak'), if os.path.exists(data_path): move_file(data_path, config['data_path']) if os.path.exists(backup_path): move_file(backup_path, config['backup_path']) # cleanup shutil.rmtree(xdg_aj_home) if len(os.listdir(xdg_data_home)) == 0: shutil.rmtree(xdg_data_home)
def test_remove_section_with_segment_name(tmp_path): bin_path = pathlib.Path(get_sample("MachO/MachO64_x86-64_binary_section_to_remove.bin")) original = lief.parse(bin_path.as_posix()) output = f"{tmp_path}/{bin_path.name}" original.remove_section("__DATA", "__to_remove") original.write(output) new = lief.parse(output) checked, err = lief.MachO.check_layout(new) assert checked, err assert new.get_section("__DATA", "__to_remove") is None if is_osx(): assert run_program(bin_path.as_posix()) stdout = run_program(output) print(stdout) assert re.search(r'Hello World', stdout) is not None
def test_all(self): original = lief.parse(get_sample('MachO/MachO64_x86-64_binary_all.bin')) _, output = tempfile.mkstemp(prefix="lief_all_") section = lief.MachO.Section("__shell", self.shellcode) section.alignment = 2 section += lief.MachO.SECTION_FLAGS.SOME_INSTRUCTIONS section += lief.MachO.SECTION_FLAGS.PURE_INSTRUCTIONS section = original.add_section(section) __TEXT = original.get_segment("__TEXT") original.main_command.entrypoint = section.virtual_address - __TEXT.virtual_address original.write(output) if is_osx(): stdout = run_program(output) self.logger.debug(stdout) self.assertIsNotNone(re.search(r'Hello World!', stdout))
def test_add_section_id(tmp_path): bin_path = pathlib.Path(get_sample("MachO/MachO64_x86-64_binary_id.bin")) original = lief.parse(bin_path.as_posix()) output = f"{tmp_path}/test_add_section_id.id.bin" # Add 50 sections for i in range(50): section = lief.MachO.Section(f"__lief_{i}", [0x90] * 0x100) original.add_section(section) original.write(output) new = lief.parse(output) checked, err = lief.MachO.check_layout(new) assert checked, err if is_osx(): assert run_program(bin_path.as_posix()) stdout = run_program(output) print(stdout) assert re.search(r'uid=', stdout) is not None
def test_id(self): original = lief.parse(get_sample('MachO/MachO64_x86-64_binary_id.bin')) _, output = tempfile.mkstemp(prefix="lief_id_add_cmd") LIB_NAME = "/usr/lib/libSystem.B.dylib" dylib_1 = lief.MachO.DylibCommand.lazy_load_dylib(LIB_NAME) dylib_2 = lief.MachO.DylibCommand.weak_lib(LIB_NAME) original.add(dylib_1) original.add(dylib_2, 0) original.remove_signature() original.write(output) new = lief.parse(output) self.assertTrue(len([l for l in new.libraries if l.name == LIB_NAME])) if is_osx(): stdout = run_program(output) self.logger.debug(stdout) self.assertIsNotNone(re.search(r'uid=', stdout))
def compile(output, extra_flags=None): if not is_osx(): return logger = logging.getLogger(__name__) extra_flags = extra_flags if extra_flags else [] _, srcpath = tempfile.mkstemp(prefix="libexample_", suffix=".c") with open(srcpath, 'w') as f: f.write(TestLibraryInjection.LIBRARY_CODE) COMPILER = "/usr/bin/clang" CC_FLAGS = ['-fPIC', '-shared'] + extra_flags cmd = [COMPILER, '-o', output] + CC_FLAGS + [srcpath] logger.debug("Compile 'libexample' with: {}".format(" ".join(cmd))) p = Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) stdout, _ = p.communicate() logger.debug(stdout) return output
def test_add_segment_all(tmp_path): bin_path = pathlib.Path(get_sample("MachO/MachO64_x86-64_binary_all.bin")) original = lief.parse(bin_path.as_posix()) output = f"{tmp_path}/test_add_segment_all.all.bin" # Add segment with sections segment = lief.MachO.SegmentCommand("__LIEF_2") for i in range(5): section = lief.MachO.Section(f"__lief_2_{i}", [i] * 0x100) segment.add_section(section) segment = original.add(segment) original.write(output) new = lief.parse(output) checked, err = lief.MachO.check_layout(new) assert checked, err if is_osx(): assert run_program(bin_path.as_posix()) stdout = run_program(output) print(stdout) assert re.search(r'Hello World: 1', stdout) is not None
def test_ssh_segments(tmp_path): bin_path = pathlib.Path(get_sample("MachO/MachO64_x86-64_binary_sshd.bin")) original = lief.parse(bin_path.as_posix()) output = f"{tmp_path}/ssh_with_segments.bin" # Add segment with sections for i in range(10): segment = lief.MachO.SegmentCommand(f"__LIEF_{i}", [i] * (0x457 + i)) segment = original.add(segment) original.write(output) new = lief.parse(output) checked, err = lief.MachO.check_layout(new) assert checked, err assert len(new.segments) == len(original.segments) if is_osx(): assert run_program(bin_path.as_posix(), args=["--help"]) stdout = run_program(output, args=["--help"]) print(stdout) assert re.search(r'OpenSSH_6.9p1, LibreSSL 2.1.8', stdout) is not None
def test_break(tmp_path): FILES = [ "MachO/mbedtls_selftest_arm64.bin", "MachO/mbedtls_selftest_x86_64.bin" ] def swap(target: lief.MachO.Binary, lhs: str, rhs: str): lhs_sec = target.get_section(lhs) if lhs_sec is None: print(f"Can't find section '{lhs_sec}'") return rhs_sec = target.get_section(rhs) if rhs_sec is None: print(f"Can't find section '{rhs_sec}'") return tmp = lhs_sec.name rhs_sec.name = tmp def shuffle(target: lief.MachO.Binary, name: str): section = target.get_section(name) if section is None: return print(f"[+] Shuffling '{name}'") section_content = list(section.content) random.shuffle(section_content) section.content = section_content def corrupt_function_starts(bin: lief.MachO.Binary, break_alignment: bool = False): fstart = bin[lief.MachO.LOAD_COMMAND_TYPES.FUNCTION_STARTS] if fstart is None: return fstart.functions = [f + 5 for f in fstart.functions] def process_exports(bin: lief.MachO.Binary, sym: lief.MachO.Symbol): #print(sym.export_info.address) original_name = sym.export_info.symbol.name name = list(original_name) random.shuffle(name) new_name = "_" + "".join(name) address = sym.export_info.address bin.add_local_symbol(address, new_name) def process_imports(bin: lief.MachO.Binary, sym: lief.MachO.Symbol): original_name = sym.binding_info.symbol.name name = list(original_name) random.shuffle(name) new_name = "_" + "".join(name) address = sym.binding_info.address - bin.imagebase bin.add_local_symbol(address, new_name) def process_local_symbol(bin: lief.MachO.Binary, sym: lief.MachO.Symbol): original_name = sym.name name = list(sym.name) random.shuffle(name) sym.name = "_" + "".join(name) sym.type = 0xf sym.description = 0x300 sym.numberof_sections = 1 sym.value += 2 def process_symbols(bin: lief.MachO.Binary): exports = [] imports = [] for sym in bin.symbols: if sym.has_export_info: #print(f"[EXPORT]: {sym.name}") exports.append(sym) elif sym.has_binding_info: #print(f"[IMPORT]: {sym.name}") imports.append(sym) else: # "classical" symbol process_local_symbol(bin, sym) for sym in exports: process_exports(bin, sym) for sym in imports: process_imports(bin, sym) def fake_objc(bin: lief.MachO.Binary): segment = lief.MachO.SegmentCommand("__DATA_LIEF") __objc_classlist = lief.MachO.Section( "__objc_classlist", [random.randint(0, 255) for _ in range(0x100)]) __objc_imageinfo = lief.MachO.Section( "__objc_imageinfo", [random.randint(0, 255) for _ in range(0x100)]) __objc_const = lief.MachO.Section( "__objc_const", [random.randint(0, 255) for _ in range(0x100)]) __objc_classrefs = lief.MachO.Section( "__objc_classrefs", [random.randint(0, 255) for _ in range(0x100)]) __objc_classlist = segment.add_section(__objc_classlist) __objc_imageinfo = segment.add_section(__objc_imageinfo) __objc_const = segment.add_section(__objc_const) __objc_classrefs = segment.add_section(__objc_classrefs) objc_section = [ __objc_classlist, __objc_imageinfo, __objc_const, __objc_classrefs ] section: lief.MachO.Section for section in objc_section: section.type = lief.MachO.SECTION_TYPES.REGULAR section.flags = lief.MachO.SECTION_FLAGS.NO_DEAD_STRIP section.alignment = 0x3 __data_lief: lief.MachO.SegmentCommand = bin.add(segment) __data_lief.init_protection = 3 __data_lief.max_protection = 3 for file in FILES: bin_path = pathlib.Path(get_sample(file)) original = lief.parse(bin_path.as_posix()) output = f"{tmp_path}/{bin_path.name}" SWAP_LIST = [ ("__text", "__stubs"), ("__cstring", "__unwind_info"), ] for (lhs, rhs) in SWAP_LIST: swap(original, lhs, rhs) process_symbols(original) fake_objc(original) corrupt_function_starts(original) original.write(output) new = lief.parse(output) checked, err = lief.MachO.check_layout(new) assert checked, err should_run = (original.header.cpu_type == lief.MachO.CPU_TYPES.x86_64 and is_osx()) or \ (original.header.cpu_type == lief.MachO.CPU_TYPES.ARM64 and is_apple_m1()) if should_run: assert run_program(bin_path.as_posix()) stdout = run_program(output) print(stdout) assert re.search(r'All tests PASS', stdout) is not None
CC_FLAGS = ['-fPIC', '-shared'] extra_flags = [] if extra_flags is None else extra_flags cmd = [COMPILER] + extra_flags + CC_FLAGS + ['-o', output] + [ftmp.name] print("Compile 'libexample' with: {}".format(" ".join(cmd))) with Popen(cmd, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) as proc: output = proc.stdout.read() print(output) return output return None @pytest.mark.skipif(not is_osx(), reason="requires OSX") def test_ssh(tmp_path): bin_path = pathlib.Path(get_sample("MachO/MachO64_x86-64_binary_sshd.bin")) original = lief.parse(bin_path.as_posix()) output = f"{tmp_path}/sshd_injected.bin" library_path = f"{tmp_path}/libexample.dylib" compile(library_path, extra_flags=["-arch", "x86_64"]) original.add_library(library_path) original.remove_signature() original.write(output) new = lief.parse(output) checked, err = lief.MachO.check_layout(new) assert checked, err