def test_header(self): WallpaperCropper2 = lief.parse( get_sample("OAT/OAT_064_AArch64_WallpaperCropper2.oat")) header = WallpaperCropper2.header self.assertEqual(header.magic, [111, 97, 116, 10]) self.assertEqual(header.version, 64) self.assertEqual(header.checksum, 3369241059) self.assertEqual(header.instruction_set, lief.OAT.INSTRUCTION_SETS.ARM_64) self.assertEqual(header.nb_dex_files, 3) self.assertEqual(header.oat_dex_files_offset, 0) self.assertEqual(header.executable_offset, 3846144) self.assertEqual(header.i2i_bridge_offset, 0) self.assertEqual(header.i2c_code_bridge_offset, 0) self.assertEqual(header.jni_dlsym_lookup_offset, 0) self.assertEqual(header.quick_generic_jni_trampoline_offset, 0) self.assertEqual(header.quick_imt_conflict_trampoline_offset, 0) self.assertEqual(header.quick_resolution_trampoline_offset, 0) self.assertEqual(header.quick_to_interpreter_bridge_offset, 0) self.assertEqual(header.image_patch_delta, 0) self.assertEqual(header.image_file_location_oat_checksum, 285056181) self.assertEqual(header.image_file_location_oat_data_begin, 1897058304)
def test_header(self): emode = lief.parse( get_sample("OAT/OAT_124_AArch64_EngineeringMode.oat")) header = emode.header self.assertEqual(header.magic, [111, 97, 116, 10]) self.assertEqual(header.version, 124) self.assertEqual(header.checksum, 2299270308) self.assertEqual(header.instruction_set, lief.OAT.INSTRUCTION_SETS.ARM_64) self.assertEqual(header.nb_dex_files, 1) self.assertEqual(header.oat_dex_files_offset, 0) self.assertEqual(header.executable_offset, 65536) self.assertEqual(header.i2i_bridge_offset, 0) self.assertEqual(header.i2c_code_bridge_offset, 0) self.assertEqual(header.jni_dlsym_lookup_offset, 0) self.assertEqual(header.quick_generic_jni_trampoline_offset, 0) self.assertEqual(header.quick_imt_conflict_trampoline_offset, 0) self.assertEqual(header.quick_resolution_trampoline_offset, 0) self.assertEqual(header.quick_to_interpreter_bridge_offset, 0) self.assertEqual(header.image_patch_delta, 0) self.assertEqual(header.image_file_location_oat_checksum, 1759409278) self.assertEqual(header.image_file_location_oat_data_begin, 1893093376)
def test_gcc(self): sample_path = get_sample('ELF/ELF64_x86-64_binary_gcc.bin') stub = lief.parse(os.path.join(CURRENT_DIRECTORY, "hello_lief.bin")) output = os.path.join(self.tmp_dir, "gcc.replace_segment") target = lief.parse(sample_path) if not lief.ELF.SEGMENT_TYPES.NOTE in target: self.logger.error("Note not found!") return segment = stub.segments[0] original_va = segment.virtual_address segment.virtual_address = 0 segment = target.replace(segment, target[lief.ELF.SEGMENT_TYPES.NOTE]) new_ep = (stub.header.entrypoint - original_va) + segment.virtual_address target.header.entrypoint = new_ep target.write(output) st = os.stat(output) os.chmod(output, st.st_mode | stat.S_IEXEC) p = Popen(output, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) stdout, _ = p.communicate() self.logger.debug(stdout.decode("utf8")) self.assertIsNotNone( re.search(r'LIEF is Working', stdout.decode("utf8")))
def test_header(self): pm = lief.parse(get_sample("OAT/OAT_079_AArch64_pm.oat")) header = pm.header self.assertEqual(header.magic, [111, 97, 116, 10]) self.assertEqual(header.version, 79) self.assertEqual(header.checksum, 2466303069) self.assertEqual(header.instruction_set, lief.OAT.INSTRUCTION_SETS.ARM_64) self.assertEqual(header.nb_dex_files, 1) self.assertEqual(header.oat_dex_files_offset, 0) self.assertEqual(header.executable_offset, 73728) self.assertEqual(header.i2i_bridge_offset, 0) self.assertEqual(header.i2c_code_bridge_offset, 0) self.assertEqual(header.jni_dlsym_lookup_offset, 0) self.assertEqual(header.quick_generic_jni_trampoline_offset, 0) self.assertEqual(header.quick_imt_conflict_trampoline_offset, 0) self.assertEqual(header.quick_resolution_trampoline_offset, 0) self.assertEqual(header.quick_to_interpreter_bridge_offset, 0) self.assertEqual(header.image_patch_delta, 0) self.assertEqual(header.image_file_location_oat_checksum, 3334846204) self.assertEqual(header.image_file_location_oat_data_begin, 1893416960)
def test_code_view_pdb(self): path = get_sample('PE/PE64_x86-64_binary_ConsoleApplication1.exe') sample = lief.parse(path) self.assertTrue(sample.has_debug) debug_code_view = list(filter(lambda deb: deb.has_code_view, sample.debug)) self.assertTrue(len(debug_code_view) == 1) debug = debug_code_view[0] code_view = debug.code_view self.assertEqual(code_view.cv_signature, lief.PE.CODE_VIEW_SIGNATURES.PDB_70) self.assertEqual(code_view.signature, [245, 217, 227, 182, 71, 113, 1, 79, 162, 3, 170, 71, 124, 74, 186, 84]) self.assertEqual(code_view.age, 1) self.assertEqual(code_view.filename, r"c:\users\romain\documents\visual studio 2015\Projects\HelloWorld\x64\Release\ConsoleApplication1.pdb") json_view = json.loads(lief.to_json(debug)) self.assertDictEqual(json_view, { 'addressof_rawdata': 8996, 'characteristics': 0, 'code_view': { 'age': 1, 'cv_signature': 'PDB_70', 'filename': 'c:\\users\\romain\\documents\\visual studio 2015\\Projects\\HelloWorld\\x64\\Release\\ConsoleApplication1.pdb', 'signature': [245, 217, 227, 182, 71, 113, 1, 79, 162, 3, 170, 71, 124, 74, 186, 84] }, 'major_version': 0, 'minor_version': 0, 'pointerto_rawdata': 5412, 'sizeof_data': 125, 'timestamp': 1459952944, 'type': 'CODEVIEW' })
def test_gcc(self): sample_path = get_sample('ELF/ELF64_x86-64_binary_gcc.bin') output = os.path.join(self.tmp_dir, "gcc.section") gcc = lief.parse(sample_path) for i in range(10): section = Section(".test.{:d}".format(i), lief.ELF.SECTION_TYPES.PROGBITS) section.type = lief.ELF.SECTION_TYPES.PROGBITS section += lief.ELF.SECTION_FLAGS.EXECINSTR section += lief.ELF.SECTION_FLAGS.WRITE section.content = STUB.segments[ 0].content # First LOAD segment which holds payload if i % 2 == 0: section = gcc.add(section, loaded=True) gcc.header.entrypoint = section.virtual_address + STUB.header.entrypoint else: section = gcc.add(section, loaded=False) gcc.write(output) st = os.stat(output) os.chmod(output, st.st_mode | stat.S_IEXEC) p = Popen(output, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) stdout, _ = p.communicate() self.logger.debug(stdout.decode("utf8")) self.assertIsNotNone( re.search(r'LIEF is Working', stdout.decode("utf8")))
def test_notes(self): systemd_resolve = lief.parse( get_sample('ELF/ELF64_x86-64_binary_systemd-resolve.bin')) notes = systemd_resolve.notes self.assertEqual(len(notes), 3) n1 = notes[0] n2 = notes[1] n3 = notes[2] self.assertEqual(n1.name, "GNU") self.assertEqual(n2.name, "GNU") self.assertEqual(n3.name, "GNU") self.assertEqual(n1.type, lief.ELF.NOTE_TYPES.ABI_TAG) self.assertEqual(n2.type, lief.ELF.NOTE_TYPES.BUILD_ID) self.assertEqual(n3.type, lief.ELF.NOTE_TYPES.GOLD_VERSION) self.assertEqual(n1.abi, lief.ELF.NOTE_ABIS.LINUX) self.assertEqual(n1.version, (2, 6, 32)) self.assertEqual(list(n2.description), [ 0x7e, 0x68, 0x6c, 0x7d, 0x79, 0x9b, 0xa4, 0xcd, 0x32, 0xa2, 0x34, 0xe8, 0x4f, 0xd7, 0x45, 0x98, 0x21, 0x32, 0x9d, 0xc8 ]) self.assertEqual("".join(map(chr, n3.description)), "gold 1.12")
def test_simple(self): sample_path = get_sample('ELF/ELF64_x86-64_binary_ls.bin') stub = lief.parse(os.path.join(CURRENT_DIRECTORY, "hello_lief.bin")) output = os.path.join(self.tmp_dir, "ls.segment") target = lief.parse(sample_path) for i in range(4): segment = stub.segments[0] original_va = segment.virtual_address segment.virtual_address = 0 segment = target.add(segment) new_ep = (stub.header.entrypoint - original_va) + segment.virtual_address target.header.entrypoint = new_ep target.write(output) st = os.stat(output) os.chmod(output, st.st_mode | stat.S_IEXEC) p = Popen(output, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) stdout, _ = p.communicate() self.logger.debug(stdout.decode("utf8")) self.assertIsNotNone( re.search(r'LIEF is Working', stdout.decode("utf8")))
def test_lazy_bind(self): target = lief.parse( get_sample('MachO/MachO64_x86-64_binary_lazy-bind-LLVM.bin')) self.assertTrue(target.has_dyld_info) bindings = list( target.dyld_info.bindings)[1:] # Skip the 1st one (Standard one) self.assertEqual(len(bindings), 3) self.assertEqual(bindings[0].binding_class, lief.MachO.BINDING_CLASS.LAZY) self.assertEqual(bindings[0].binding_type, lief.MachO.BIND_TYPES.POINTER) self.assertEqual(bindings[0].address, 0x100001010) self.assertEqual(bindings[0].symbol.name, "_foo") self.assertEqual(bindings[0].segment.name, "__DATA") self.assertEqual(bindings[0].library.name, "libfoo.dylib") self.assertEqual(bindings[1].binding_class, lief.MachO.BINDING_CLASS.LAZY) self.assertEqual(bindings[1].binding_type, lief.MachO.BIND_TYPES.POINTER) self.assertEqual(bindings[1].address, 0x100001018) self.assertEqual(bindings[1].symbol.name, "_bar") self.assertEqual(bindings[1].segment.name, "__DATA") self.assertEqual(bindings[1].library.name, "libbar.dylib") self.assertEqual(bindings[2].binding_class, lief.MachO.BINDING_CLASS.LAZY) self.assertEqual(bindings[2].binding_type, lief.MachO.BIND_TYPES.POINTER) self.assertEqual(bindings[2].address, 0x100001020) self.assertEqual(bindings[2].symbol.name, "_malloc") self.assertEqual(bindings[2].segment.name, "__DATA") self.assertEqual(bindings[2].library.name, "/usr/lib/libSystem.B.dylib")
def test_exports_trie(self): target = lief.parse( get_sample('MachO/MachO64_x86-64_binary_exports-trie-LLVM.bin')) self.assertTrue(target.has_dyld_info) exports = target.dyld_info.exports self.assertEqual(len(exports), 6) self.assertEqual(exports[0].address, 0) self.assertEqual(exports[0].symbol.name, "_malloc") self.assertEqual(exports[1].address, 0) self.assertEqual(exports[1].symbol.name, "_myfree") self.assertEqual(exports[2].address, 0xf70) self.assertEqual(exports[2].symbol.name, "_myWeak") self.assertEqual(exports[3].address, 0x1018) self.assertEqual(exports[3].symbol.name, "_myTLV") self.assertEqual(exports[4].address, 0x12345678) self.assertEqual(exports[4].symbol.name, "_myAbs") self.assertEqual(exports[5].address, 0xf60) self.assertEqual(exports[5].symbol.name, "_foo")
def test_core_write(self): core = lief.parse(get_sample('ELF/ELF64_x86-64_core_hello.core')) note = core.notes[1] self.assertEqual(note.type_core, lief.ELF.NOTE_TYPES_CORE.PRSTATUS) details = note.details details[lief.ELF.CorePrStatus.REGISTERS.X86_64_RIP] = 0xBADC0DE note = core.notes[5] self.assertEqual(note.type_core, lief.ELF.NOTE_TYPES_CORE.AUXV) details = note.details details[lief.ELF.CoreAuxv.TYPES.ENTRY] = 0xBADC0DE note = core.notes[4] self.assertEqual(note.type_core, lief.ELF.NOTE_TYPES_CORE.SIGINFO) orig_siginfo_len = len(note.description) details = note.details details.sigerrno = 0xCC # Cannot re-open a file on Windows, so handle it by hand with tempfile.NamedTemporaryFile(prefix="", suffix=".core", delete=False) as f: tmpfilename = f.name core.write(tmpfilename) try: with open(tmpfilename, 'rb') as f: core_new = lief.parse(f.name) self.assertIsNotNone(core_new) note = core_new.notes[1] self.assertEqual(note.type_core, lief.ELF.NOTE_TYPES_CORE.PRSTATUS) details = note.details self.assertEqual( details[lief.ELF.CorePrStatus.REGISTERS.X86_64_RIP], 0xBADC0DE) note = core_new.notes[5] self.assertEqual(note.type_core, lief.ELF.NOTE_TYPES_CORE.AUXV) details = note.details self.assertEqual(details[lief.ELF.CoreAuxv.TYPES.ENTRY], 0xBADC0DE) note = core_new.notes[4] self.assertEqual(note.type_core, lief.ELF.NOTE_TYPES_CORE.SIGINFO) self.assertEqual(len(note.description), orig_siginfo_len) details = note.details self.assertEqual(details.sigerrno, 0xCC) finally: try: os.remove(tmpfilename) except OSError: pass
def test_header(self): CallDeviceId = lief.parse( get_sample("OAT/OAT_138_AArch64_android.uid.systemui.oat")) header = CallDeviceId.header self.assertEqual(header.magic, [111, 97, 116, 10]) self.assertEqual(header.version, 138) self.assertEqual(header.checksum, 0x5c64d148) self.assertEqual(header.instruction_set, lief.OAT.INSTRUCTION_SETS.ARM_64) self.assertEqual(header.nb_dex_files, 1) self.assertEqual(header.oat_dex_files_offset, 3289146) self.assertEqual(header.executable_offset, 0x324000) self.assertEqual(header.i2i_bridge_offset, 0) self.assertEqual(header.i2c_code_bridge_offset, 0) self.assertEqual(header.jni_dlsym_lookup_offset, 0) self.assertEqual(header.quick_generic_jni_trampoline_offset, 0) self.assertEqual(header.quick_imt_conflict_trampoline_offset, 0) self.assertEqual(header.quick_resolution_trampoline_offset, 0) self.assertEqual(header.quick_to_interpreter_bridge_offset, 0) self.assertEqual(header.image_patch_delta, 0) self.assertEqual(header.image_file_location_oat_checksum, 0x8eb74f9a) self.assertEqual(header.image_file_location_oat_data_begin, 0x71242000)
def setUp(self): self.logger = logging.getLogger(__name__) self.input = lief.parse(get_sample("ELF/ELF32_x86_binary_all.bin")) _, output = tempfile.mkstemp(prefix="all_bis") self.input.write(output) self.output = lief.parse(output)
def test_header(self): CallDeviceId = lief.parse( get_sample("OAT/OAT_131_x86_CallDeviceId.oat")) header = CallDeviceId.header self.assertEqual(header.magic, [111, 97, 116, 10]) self.assertEqual(header.version, 131) self.assertEqual(header.checksum, 0x8e82f9b5) self.assertEqual(header.instruction_set, lief.OAT.INSTRUCTION_SETS.X86) self.assertEqual(header.nb_dex_files, 1) self.assertEqual(header.oat_dex_files_offset, 1484) self.assertEqual(header.executable_offset, 0x1000) self.assertEqual(header.i2i_bridge_offset, 0) self.assertEqual(header.i2c_code_bridge_offset, 0) self.assertEqual(header.jni_dlsym_lookup_offset, 0) self.assertEqual(header.quick_generic_jni_trampoline_offset, 0) self.assertEqual(header.quick_imt_conflict_trampoline_offset, 0) self.assertEqual(header.quick_resolution_trampoline_offset, 0) self.assertEqual(header.quick_to_interpreter_bridge_offset, 0) self.assertEqual(header.image_patch_delta, 15335424) self.assertEqual(header.image_file_location_oat_checksum, 0xdacfe293) self.assertEqual(header.image_file_location_oat_data_begin, 0x716a9000)
def test_gnuhash(self): ls = lief.parse(get_sample('ELF/ELF64_x86-64_binary_ls.bin')) gnu_hash = ls.gnu_hash self.assertEqual(gnu_hash.nb_buckets, 33) self.assertEqual(gnu_hash.symbol_index, 109) self.assertEqual(gnu_hash.shift2, 7) bloom_filters = gnu_hash.bloom_filters self.assertEqual(len(bloom_filters), 2) self.assertIn(0x3FAE01120C48A1A6, bloom_filters) self.assertIn(0x900004A81310D428, bloom_filters) buckets = gnu_hash.buckets self.assertEqual(len(buckets), 33) buckets_test = [ 109, 110, 0, 0, 0, 0, 0, 111, 113, 114, 0, 0, 0, 115, 0, 116, 0, 0, 117, 118, 119, 0, 120, 0, 0, 121, 123, 124, 126, 128, 129, 130, 0 ] self.assertEqual(buckets_test, buckets) hash_values = gnu_hash.hash_values hash_values_test = [ 0x60E0C78D, 0xF54162E5, 0x7FFD8E4E, 0x1C8BF239, 0xEEFD3EB, 0x1C8C1D29, 0x1C5871D9, 0x5B7F3E03, 0x759A6A7F, 0xEF18DB9, 0xBA53E4D, 0x9789A097, 0x9E7650BC, 0xD39AD3D, 0x12F7C433, 0xEB01FAB6, 0xECD54543, 0xAD3C9892, 0x72632CCF, 0x12F7A2B3, 0x7C92E3BB, 0x7C96F087 ] self.assertEqual(hash_values, hash_values_test)
def test_freebl(self): libfreebl3_path = get_sample('ELF/ELF64_x86-64_library_libfreebl3.so') output_ls = os.path.join(self.tmp_dir, "ls.new") output_libfreebl3 = os.path.join(self.tmp_dir, "libfreebl3.so") libfreebl3 = lief.parse(libfreebl3_path) ls = lief.parse("/usr/bin/ls") ls[lief.ELF.DYNAMIC_TAGS.FLAGS_1].remove(lief.ELF.DYNAMIC_FLAGS_1.PIE) ls.add_library("libfreebl3.so") ls += lief.ELF.DynamicEntryRunPath("$ORIGIN") libfreebl3 += lief.ELF.DynamicEntryRunPath("$ORIGIN") ls.write(output_ls) libfreebl3.write(output_libfreebl3) st = os.stat(output_ls) os.chmod(output_ls, st.st_mode | stat.S_IEXEC) st = os.stat(output_libfreebl3) os.chmod(output_libfreebl3, st.st_mode | stat.S_IEXEC) p = Popen([output_ls, "--version"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) stdout, _ = p.communicate() self.logger.debug(stdout.decode("utf8")) self.assertIsNotNone( re.search(r'ls \(GNU coreutils\) ', stdout.decode("utf8"))) self.assertEqual(p.returncode, 0)
def test_issue_689(): """ https://github.com/lief-project/LIEF/issues/689 """ path = utils.get_sample( "PE/res/07e7d2848b6f9f626e9c7dc06de13c3d1f31ab31ce55226931d6e4d426178be6.neut" ) pe = lief.parse(path) assert pe is not None file_info = pe.resources_manager.version.string_file_info assert len(file_info.langcode_items) == 1 item = file_info.langcode_items[0] assert len(item.items) == 12 assert item.items["SpecialBuild"] == b"" assert item.items["ProductVersion"] == b"1, 0, 0, 0" assert item.items["PrivateBuild"] == b"" assert item.items["OriginalFilename"] == b"DSignTool" assert item.items[ "ProductName"] == b"\xe6\x95\xb0\xe5\xad\x97\xe7\xad\xbe\xe5\x90\x8d\xe5\xb7\xa5\xe5\x85\xb7(\xe5\x91\xbd\xe4\xbb\xa4\xe8\xa1\x8c)" assert item.items["LegalTrademarks"] == b"" assert item.items["InternalName"] == b"CSignTool" assert item.items["FileVersion"] == b"1, 9, 0, 0" assert item.items["LegalCopyright"] == b"Copyright ? 2012" assert item.items[ "FileDescription"] == b"\xe6\x95\xb0\xe5\xad\x97\xe7\xad\xbe\xe5\x90\x8d\xe5\xb7\xa5\xe5\x85\xb7(\xe5\x91\xbd\xe4\xbb\xa4\xe8\xa1\x8c)" assert item.items[ "CompanyName"] == b"\xe4\xb8\x8a\xe6\xb5\xb7\xe5\x9f\x9f\xe8\x81\x94\xe8\xbd\xaf\xe4\xbb\xb6\xe6\x8a\x80\xe6\x9c\xaf\xe6\x9c\x89\xe9\x99\x90\xe5\x85\xac\xe5\x8f\xb8" assert item.items["Comments"] == b""
def test_lazy_bind(): target = lief.parse(get_sample('MachO/MachO64_x86-64_binary_lazy-bind-LLVM.bin')) assert target.has_dyld_info bindings = list(target.dyld_info.bindings)[1:] # Skip the 1st one (Standard one) assert len(bindings) == 3 assert bindings[0].binding_class == lief.MachO.BINDING_CLASS.LAZY assert bindings[0].binding_type == lief.MachO.BIND_TYPES.POINTER assert bindings[0].address == 0x100001010 assert bindings[0].symbol.name == "_foo" assert bindings[0].segment.name == "__DATA" assert bindings[0].library.name == "libfoo.dylib" assert bindings[1].binding_class == lief.MachO.BINDING_CLASS.LAZY assert bindings[1].binding_type == lief.MachO.BIND_TYPES.POINTER assert bindings[1].address == 0x100001018 assert bindings[1].symbol.name == "_bar" assert bindings[1].segment.name == "__DATA" assert bindings[1].library.name == "libbar.dylib" assert bindings[2].binding_class == lief.MachO.BINDING_CLASS.LAZY assert bindings[2].binding_type == lief.MachO.BIND_TYPES.POINTER assert bindings[2].address == 0x100001020 assert bindings[2].symbol.name == "_malloc" assert bindings[2].segment.name == "__DATA" assert bindings[2].library.name == "/usr/lib/libSystem.B.dylib"
def test_dex_files(self): WallpaperCropper2 = lief.parse( get_sample("OAT/OAT_064_AArch64_WallpaperCropper2.oat")) dex_files = WallpaperCropper2.dex_files self.assertEqual(len(dex_files), WallpaperCropper2.header.nb_dex_files) # Dex File 0 dex = dex_files[0] self.assertEqual(dex.name, "classes.dex") self.assertEqual( dex.location, "/system/priv-app/WallpaperCropper2/WallpaperCropper2.apk") self.assertEqual(len(dex.raw(deoptimize=False)), dex.header.file_size) # Dex File 1 dex = dex_files[1] #self.assertEqual(dex.name, "classes2.dex") self.assertEqual( dex.location, "/system/priv-app/WallpaperCropper2/WallpaperCropper2.apk:classes2.dex" ) self.assertEqual(len(dex.raw(deoptimize=False)), dex.header.file_size) # Dex File 2 dex = dex_files[2] #self.assertEqual(dex.name, "classes3.dex") self.assertEqual( dex.location, "/system/priv-app/WallpaperCropper2/WallpaperCropper2.apk:classes3.dex" ) self.assertEqual(len(dex.raw(deoptimize=False)), dex.header.file_size)
def test_data_in_code(self): binary = lief.parse( get_sample('MachO/MachO32_ARM_binary_data-in-code-LLVM.bin')) self.assertTrue(binary.has_data_in_code) dcode = binary.data_in_code self.assertEqual(dcode.data_offset, 0x11c) self.assertEqual(dcode.data_size, 0x20) self.assertEqual(len(dcode.entries), 4) self.assertEqual(dcode.entries[0].type, lief.MachO.DataCodeEntry.TYPES.DATA) self.assertEqual(dcode.entries[0].offset, 0) self.assertEqual(dcode.entries[0].length, 4) self.assertEqual(dcode.entries[1].type, lief.MachO.DataCodeEntry.TYPES.JUMP_TABLE_32) self.assertEqual(dcode.entries[1].offset, 4) self.assertEqual(dcode.entries[1].length, 4) self.assertEqual(dcode.entries[2].type, lief.MachO.DataCodeEntry.TYPES.JUMP_TABLE_16) self.assertEqual(dcode.entries[2].offset, 8) self.assertEqual(dcode.entries[2].length, 2) self.assertEqual(dcode.entries[3].type, lief.MachO.DataCodeEntry.TYPES.JUMP_TABLE_8) self.assertEqual(dcode.entries[3].offset, 10) self.assertEqual(dcode.entries[3].length, 1)
def test_oat_methods(self): oat_file = get_sample("OAT/OAT_124_x86-64_CallDeviceId.oat") vdex_file = get_sample("VDEX/VDEX_06_x86-64_CallDeviceId.vdex") CallDeviceId = lief.OAT.parse(oat_file, vdex_file) self.assertEqual(len(CallDeviceId.methods), 1) self.assertTrue( all(m.is_dex2dex_optimized for m in CallDeviceId.methods)) # OAT Method 0 # ============ method = CallDeviceId.methods[0] self.assertEqual(method.name, "getIMEI") self.assertEqual( method.oat_class, CallDeviceId.get_class("Lre/android/art/CallDeviceId;"))
def test_dynamic_flags(self): sample = "ELF/ELF32_ARM_binary_ls.bin" ls = lief.parse(get_sample(sample)) d_flags = ls.get(lief.ELF.DYNAMIC_TAGS.FLAGS) d_flags_1 = ls.get(lief.ELF.DYNAMIC_TAGS.FLAGS_1) self.assertIn(lief.ELF.DYNAMIC_FLAGS.BIND_NOW, d_flags) self.assertIn(lief.ELF.DYNAMIC_FLAGS_1.NOW, d_flags_1)
def test_dyld_environment(self): binary = lief.parse( get_sample('MachO/MachO64_x86-64_binary_safaridriver.bin')) self.assertTrue(binary.has_dyld_environment) self.assertEqual( binary.dyld_environment.value, "DYLD_VERSIONED_FRAMEWORK_PATH=/System/Library/StagedFrameworks/Safari" )
def test_thread_cmd(self): micromacho = lief.parse( get_sample('MachO/MachO32_x86_binary_micromacho.bin')) self.assertTrue(micromacho.has_thread_command) self.assertEqual(micromacho.thread_command.pc, 0x68) self.assertEqual(micromacho.thread_command.flavor, 1) self.assertEqual(micromacho.thread_command.count, 16) self.assertEqual(micromacho.entrypoint, 0x68)
def test_thread_cmd(): micromacho = lief.parse( get_sample('MachO/MachO32_x86_binary_micromacho.bin')) assert micromacho.has_thread_command assert micromacho.thread_command.pc == 0x68 assert micromacho.thread_command.flavor == 1 assert micromacho.thread_command.count == 16 assert micromacho.entrypoint == 0x68
def test_segment_split_info(self): binary = lief.parse( get_sample('MachO/FAT_MachO_x86_x86-64_library_libdyld.dylib')) self.assertTrue(binary.has_segment_split_info) ssi = binary.segment_split_info self.assertEqual(ssi.data_offset, 32852) self.assertEqual(ssi.data_size, 292)
def test_segment_split_info(): binary = lief.parse( get_sample('MachO/FAT_MachO_x86_x86-64_library_libdyld.dylib')) assert binary.has_segment_split_info ssi = binary.segment_split_info assert ssi.data_offset == 32852 assert ssi.data_size == 292
def patch(tmp_path: str, bin_path: pathlib.Path) -> str: original = lief.parse(bin_path.as_posix()) shellcode_path = None output = f"{tmp_path}/{bin_path.name}" cpu = original.header.cpu_type if cpu == lief.MachO.CPU_TYPES.ARM64: shellcode_path = pathlib.Path( get_sample("MachO/shellcode-stub/lief_hello_darwin_arm64.bin")) elif cpu == lief.MachO.CPU_TYPES.x86_64: shellcode_path = pathlib.Path( get_sample("MachO/shellcode-stub/lief_hello_darwin_x86_64.bin")) else: print(f"Unsupported architecture {cpu!s} for {bin_path}") sys.exit(1) shellcode = lief.parse(shellcode_path.as_posix()) #lief.logging.set_level(lief.logging.LOGGING_LEVEL.DEBUG) __TEXT = shellcode.get_segment("__TEXT") __STEXT = lief.MachO.SegmentCommand("__STEXT", list(__TEXT.content)) __STEXT = original.add(__STEXT) print(__STEXT) __STEXT.init_protection = __TEXT.init_protection __STEXT.max_protection = __TEXT.max_protection __DATA = shellcode.get_segment("__DATA") __SDATA = lief.MachO.SegmentCommand("__SDATA", list(__DATA.content)) __SDATA = original.add(__SDATA) __SDATA.init_protection = __DATA.init_protection __SDATA.max_protection = __DATA.max_protection shellcode_ep = shellcode.entrypoint - shellcode.imagebase new_ep = shellcode_ep + __STEXT.virtual_address - original.imagebase print(f"New entrypoint: 0x{new_ep:x}") original.main_command.entrypoint = new_ep print(original.main_command) print(f"Written in {output}") original.write(output) return output
def test_id(tmp_path): original = lief.parse(get_sample('MachO/MachO64_x86-64_binary_id.bin')) output = f"{tmp_path}/test_id.bin" original.write(output) modified = lief.parse(output) checked, err = lief.MachO.check_layout(modified) assert checked, err
def test_ms_spc_nested_signature(self): sig = lief.PE.Signature.parse(get_sample("pkcs7/cert0.p7b")) attr = sig.signers[0].get_attribute(lief.PE.SIG_ATTRIBUTE_TYPES.MS_SPC_NESTED_SIGN) nested_sig = attr.signature self.assertEqual(nested_sig.version, 1) self.assertEqual(nested_sig.digest_algorithm, lief.PE.ALGORITHMS.SHA_256) content_info = nested_sig.content_info self.assertEqual(content_info.content_type, "1.3.6.1.4.1.311.2.1.4") self.assertEqual(content_info.digest_algorithm, lief.PE.ALGORITHMS.SHA_256) self.assertEqual(content_info.digest, from_hex("90:a4:df:36:26:df:d9:8d:6b:3b:1d:42:74:5b:94:54:c5:e2:30:2e:d2:f8:23:70:16:3f:1e:e6:dd:7d:8c:91")) certs = nested_sig.certificates self.assertEqual(len(certs), 3) nvidia_cert, self_signed_ca, signer_cert = certs self.assertEqual(nvidia_cert.issuer, "C=US, O=Symantec Corporation, OU=Symantec Trust Network, CN=Symantec Class 3 SHA256 Code Signing CA - G2") self.assertEqual(nvidia_cert.subject, "C=US, ST=California, L=Santa Clara, O=NVIDIA Corporation, OU=IT-MIS, CN=NVIDIA Corporation") self.assertEqual(nvidia_cert.serial_number, from_hex("62:E7:45:E9:21:65:21:3C:97:1F:5C:49:0A:EA:12:A5")) self.assertEqual(self_signed_ca.issuer, "C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2008 VeriSign, Inc. - For authorized use only, CN=VeriSign Universal Root Certification Authority") self.assertEqual(self_signed_ca.subject, "C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2008 VeriSign, Inc. - For authorized use only, CN=VeriSign Universal Root Certification Authority") self.assertEqual(self_signed_ca.serial_number, from_hex("40:1A:C4:64:21:B3:13:21:03:0E:BB:E4:12:1A:C5:1D")) self.assertEqual(signer_cert.issuer, "C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2008 VeriSign, Inc. - For authorized use only, CN=VeriSign Universal Root Certification Authority") self.assertEqual(signer_cert.subject, "C=US, O=Symantec Corporation, OU=Symantec Trust Network, CN=Symantec Class 3 SHA256 Code Signing CA - G2") self.assertEqual(signer_cert.serial_number, from_hex("7C:1B:35:35:4A:E7:DB:74:E7:41:5F:11:69:CA:6B:A8")) # Check self-signed self.assertEqual(self_signed_ca.verify(self_signed_ca), lief.PE.x509.VERIFICATION_FLAGS.OK) self.assertEqual(signer_cert.is_trusted_by([self_signed_ca]), lief.PE.x509.VERIFICATION_FLAGS.OK) self.assertEqual(self_signed_ca.verify(signer_cert), lief.PE.x509.VERIFICATION_FLAGS.OK) self.assertEqual(signer_cert.verify(nvidia_cert), lief.PE.x509.VERIFICATION_FLAGS.BADCERT_EXPIRED) ca_bundles = lief.PE.x509.parse(get_sample("pkcs7/windows-ca-bundle.pem")) self.assertEqual(self_signed_ca.is_trusted_by(ca_bundles), lief.PE.x509.VERIFICATION_FLAGS.OK) self.assertEqual(int(nvidia_cert.is_trusted_by(ca_bundles)), \ lief.PE.x509.VERIFICATION_FLAGS.BADCERT_NOT_TRUSTED | lief.PE.x509.VERIFICATION_FLAGS.BADCERT_EXPIRED) self.assertEqual(nested_sig.check(), lief.PE.Signature.VERIFICATION_FLAGS.OK) signer = nested_sig.signers[0]
def get_infos(uuids, fraction=0.3): """Get info from different backtraces Args: uuids (List[str]): crash uuids fraction (float): the fraction of all the uuids to look in Returns: dict: info about the different backtraces """ def handler(json, data): jd = json['json_dump'] if 'threads' in jd and 'crashedThread' in json: thread_nb = json['crashedThread'] if thread_nb is not None: frames = jd['threads'][thread_nb]['frames'] data['cpu_name'] = json['cpu_name'] data['os'] = json['os_pretty_version'] functions = [] for frame in frames: if 'function' in frame: functions.append(frame['function']) bt = tuple(functions) data['cycles'] = __cycles_detection(functions) data['functions'] = bt if 'crash_info' in jd: data['address'] = jd['crash_info']['address'] base = {'cycles': [], 'functions': None, 'address': '', 'cpu_name': '', 'os': ''} info = {} queries = [] for uuid in utils.get_sample(uuids, fraction): data = base.copy() info[uuid] = data queries.append(Query(socorro.ProcessedCrash.URL, params={'crash_id': uuid}, handler=handler, handlerdata=data)) socorro.ProcessedCrash(queries=queries).wait() return info
def setup_feature_matrix(unlabeled_file_references, soft_labeled_path, labeled_file_references, feature_list, soft_labeled_sample_size, unlabeled_sample_size, labeled_sample_size, class_sampling, num_labels, alpha_labeled=0.95, alpha_unlabeled=0.95, alpha_soft_labeled=hcs_soft_label_alphas, class_labels=hcs_soft_labels, ignore_labels=[6], normalize_data=True): ''' Reads files with unlabeled and labeled information, and creates the feature matrix with the features specified in the feature list Parameters ---------- unlabeled_file_references -- paths to txt files with raw unlabeled data labeled_file_references -- paths to arff files with labeled data soft_labeled_path -- paths txt soft-labeled files. This path should contain a directory per label feature_list -- list with the indices of the selected features (1 based) sample_size -- size of sampling over unlabeled data (-1 means use all data) class_sampling -- if sampling is required, sample the same number of points per class Returns ------- Matrix with features as columns, and individuals (cells) as rows. The matrix contains an additional column for the labeling, if present, or -1 otherwise. ''' # [TODO] parametrize this: #alpha_labeled, alpha_unlabeled = 0.95, 0.95 #alpha_soft_labeled = {1: 0.95, 5: 0.95} alpha_vector = [] summary = {'nl': 0, 'nsu': 0, 'nsi': 0, 'nu': 0} labeled_data = [read_arff_file(input_file, feature_list, ignore_labels=ignore_labels) for input_file in labeled_file_references] labeled_points = np.concatenate(labeled_data) labeled_points = get_sample(labeled_points, labeled_sample_size) # ??? ___("%i labeled points:\n\t%s" % (len(labeled_points), labeled_points[:, -1])) summary['nl'] = len(labeled_points) alpha_vector += [alpha_labeled] * len(labeled_points) soft_labeled_points = None if soft_labeled_path: soft_labeled_data = {label_key: [] for label_key in class_labels.keys()} soft_labeled_file_references = get_files(soft_labeled_path) uninf_label_key = 'bPEGI-29' soft_labeled_data_uninf = [] for input_file in soft_labeled_file_references: label_key = parentdir(input_file) #soft_labeled_data[label_key] += [read_hcs_file(input_file, feature_list, soft_label=class_labels[label_key])] if label_key == uninf_label_key: soft_labeled_data_uninf += [read_hcs_file(input_file, feature_list, soft_label=class_labels[label_key])] else: soft_labeled_data[label_key] += [read_hcs_file(input_file, feature_list, soft_label=class_labels[label_key])] # Sample unlabeled data uniformly over classes if class_sampling: class_sample_size = {class_label: soft_labeled_sample_size / len(class_labels) if class_sampling else -1 for class_label in class_labels.keys()} summary['nsu'] = class_sample_size[uninf_label_key] soft_labeled_data = [get_sample(np.concatenate(soft_labeled_data_uninf), class_sample_size[uninf_label_key])] + \ [get_sample(np.concatenate(soft_labeled_set), class_sample_size[soft_labeled_set_name]) for soft_labeled_set_name, soft_labeled_set in soft_labeled_data.iteritems() if len(soft_labeled_set) > 0] #soft_labeled_data = [get_sample(np.concatenate(soft_labeled_set), class_sample_size[soft_labeled_set_name]) # for soft_labeled_set_name, soft_labeled_set in soft_labeled_data.iteritems()] else: summary['nsu'] = len(soft_labeled_data_uninf) soft_labeled_data = np.concatenate([soft_labeled_data_uninf, np.concatenate(soft_labeled_data.values())]) #soft_labeled_data = np.concatenate(soft_labeled_data.values()) summary['nsi'] = len(soft_labeled_data) - summary['nsu'] soft_labeled_points = np.concatenate(soft_labeled_data) soft_labeled_alphas = [alpha_soft_labeled[label] for label in soft_labeled_points[:, -1]] ___("%i soft labeled points:\n\t%s" % (len(soft_labeled_points), soft_labeled_points[:, -1])) alpha_vector += soft_labeled_alphas unlabeled_data = [read_hcs_file(input_file, feature_list) for input_file in unlabeled_file_references] unlabeled_points = np.concatenate(unlabeled_data) unlabeled_points = get_sample(unlabeled_points, unlabeled_sample_size) # ??? ___("%i unlabeled points:\n\t%s" % (len(unlabeled_points), unlabeled_points[:, -1])) summary['nu'] = len(unlabeled_points) alpha_vector += [alpha_unlabeled] * len(unlabeled_points) if soft_labeled_points is None: soft_labeled_points = [] M = np.concatenate([labeled_points, unlabeled_points]) else: M = np.concatenate([labeled_points, soft_labeled_points, unlabeled_points]) initial_labels = get_label_matrix(M[:, -1], class_labels, summary, alpha_soft_labeled[1], alpha_soft_labeled[2]) M = M[:, :-1] if normalize_data: # M = np.column_stack([normalize(M), initial_labels]) scores = np.array([1.3275, 1.1739, 1.0605, 0.9868]) weights = np.max(scores) / scores M = normalize(M, weights) return (M, initial_labels, alpha_vector, len(labeled_points), len(soft_labeled_points))
def setup_validation_matrix(labeled_file_references, soft_labeled_path, feature_list, labeled_sample_size, unlabeled_sample_size, class_sampling, alpha_labeled, alpha_unlabeled, alpha_soft_labeled, class_labels=hcs_soft_labels, ignore_labels=[6], normalize_data=True): alpha_vector = [] summary = {'nl': 0, 'nsu': 0, 'nsi': 0, 'nu': 0} # read labeled data validation_data = [read_arff_file(input_file, feature_list, ignore_labels=ignore_labels) for input_file in labeled_file_references] validation_points = np.concatenate(validation_data) np.random.shuffle(validation_points) # split labeled data in labeled points... labeled_points = validation_points[:labeled_sample_size] summary['nl'] = len(labeled_points) # ...and (virtually) unlabeled points unlabeled_points = validation_points[labeled_sample_size:labeled_sample_size + unlabeled_sample_size] summary['nu'] = len(unlabeled_points) expected_labels = unlabeled_points[:, -1].copy() unlabeled_points[:, -1] = -1 soft_labeled_sample_size = len(unlabeled_points) alpha_vector += [alpha_labeled] * len(labeled_points) #read soft-labeled data soft_labeled_points = None if soft_labeled_path: soft_labeled_data = {label_key: [] for label_key in class_labels.keys()} soft_labeled_file_references = get_files(soft_labeled_path) uninf_label_key = 'bPEGI-29' soft_labeled_data_uninf = [] for input_file in soft_labeled_file_references: label_key = parentdir(input_file) if label_key == uninf_label_key: soft_labeled_data_uninf += [read_hcs_file(input_file, feature_list, soft_label=class_labels[label_key])] else: soft_labeled_data[label_key] += [read_hcs_file(input_file, feature_list, soft_label=class_labels[label_key])] # Sample unlabeled data uniformly over classes if class_sampling: class_sample_boundaries = np.rint(np.linspace(0, soft_labeled_sample_size, len(class_labels) + 1)) class_sample_sizes = class_sample_boundaries[1:] - class_sample_boundaries[:-1] i = iter(class_sample_sizes) class_sample_size = {class_label: int(i.next()) for class_label in class_labels.keys()} #soft_labeled_data = [get_sample(np.concatenate(soft_labeled_set), class_sample_size[soft_labeled_set_name]) # for soft_labeled_set_name, soft_labeled_set in soft_labeled_data.iteritems()] summary['nsu'] = class_sample_size[uninf_label_key] soft_labeled_data = [get_sample(np.concatenate(soft_labeled_data_uninf), class_sample_size[uninf_label_key])] + \ [get_sample(np.concatenate(soft_labeled_set), class_sample_size[soft_labeled_set_name]) for soft_labeled_set_name, soft_labeled_set in soft_labeled_data.iteritems() if len(soft_labeled_set) > 0] else: summary['nsu'] = len(soft_labeled_data_uninf) soft_labeled_data = np.concatenate([soft_labeled_data_uninf, np.concatenate(soft_labeled_data.values())]) summary['nsi'] = sum([len(_data) for _data in soft_labeled_data]) - summary['nsu'] soft_labeled_points = np.concatenate(soft_labeled_data) soft_labeled_alphas = [alpha_soft_labeled[label] for label in soft_labeled_points[:, -1]] alpha_vector += soft_labeled_alphas alpha_vector += [alpha_unlabeled] * len(unlabeled_points) if soft_labeled_points is None: soft_labeled_points = [] M = np.concatenate([labeled_points, unlabeled_points]) else: M = np.concatenate([labeled_points, soft_labeled_points, unlabeled_points]) '''must check consistent ordering ''' #set_printoptions(edgeitems=55000, linewidth=180) initial_labels = get_label_matrix(M[:, -1], class_labels, summary, alpha_soft_labeled[1], alpha_soft_labeled[2]) M = M[:, :-1] if normalize_data: # M = np.column_stack([normalize(M), initial_labels]) # 4,3,2,1,92,53,54 scores = np.array([1.3384, 1.0987, 1.0309, 0.9315, 0.9133, 0.9064, 0.8906]) weights = scores / np.max(scores) M = normalize(M, weights) return (M, initial_labels, alpha_vector, len(labeled_points), len(soft_labeled_points), expected_labels)