Changelog

0.12.0 - Not Released Yet

ELF
  • Clcanny improved (see #507 and #509) the reconstruction of the dynamic symbol table by sorting local symbols and non-exported symbols. It fixes the following warning when parsing a modified binary with readelf

    Warning: local symbol 29 found at index >= .dynsym's sh_info value of 1
    
MachO
  • LucaMoroSyn added the support for the LC_FILESET_ENTRY. This command is usually found in kernel cache files

  • LIEF::MachO::Binary::get_symbol now returns a pointer (instead of a reference). If the symbol can’t be found, it returns a nullptr.

  • Add API to select a Binary from a FatBinary by its achitecture. See: lief.MachO.FatBinary.take().

    fat = lief.MachO.parse("/bin/ls")
    fit = fat.take(lief.MachO.CPU_TYPES.x86_64)
    
  • Handle the 0x0D binding opcode (see: #524)

  • xhochy fixed performances issues in the Mach-O parser (see #579)

DEX
Abstraction
  • Abtract binary imagebase for PE, ELF and Mach-O (lief.Binary.imagebase)

  • Add lief.Binary.offset_to_virtual_addres()

  • Add PE imports/exports as abstracted symbols

Compilation
  • Enable to use a pre-compiled version of spdlog. This feature aims at improving compilation time when developing on LIEF.

    One can provide path to spdlog install through:

    $ python ./setup.py --spdlog-dir=path/to/lib/cmake/spdlog [...]
    # or
    $ cmake -DLIEF_EXTERNAL_SPDLOG=ON -Dspdlog_DIR=path/to/lib/cmake/spdlog ...
    

0.11.X - Patch Releases

0.11.5 - May 22, 2021

  • Remove usage of not in public headers (b8e825b)

ELF
PE
MachO

0.11.4 - March 09, 2021

PE
  • Fix missing bound check when computing the authentihash

0.11.3 - March 03, 2021

PE
  • Add sanity check on the signature’s length that could lead to a std::bad_alloc exception

0.11.2 - February 24, 2021

PE
  • Fix regression in the behavior of the PE section’s name. One can now access the full section’s name (with trailing bytes) through lief.PE.Section.fullname (see: #551)

0.11.1 - February 22, 2021

PE

0.11.0 - January 19, 2021

ELF
  • mkomet updated enums related to Android (see: 9dd641d)

  • aeflores added MIPS relocations support in the ELF parser

  • Fix extend() on a ELF section (cf. issue #477)

  • Fix issue when exporting symbols on empty-gnu-hash ELF binary (1381f9a)

  • Fix reconstruction issue when the binary is prelinked (cf. issue #466)

  • Add DF_1_PIE flag

  • Fix parsing issue of the .eh_frame section when the base address is not 0.

  • JanuszL enhanced the algorithm that computes the string table. It moves from a N^2 algorithm to a Nlog(N) (1e0c4e8).

  • Fix .eh_frame parsing issue (b57f323)

  • aeflores fixed parsing issue in ELF relocations (6c53646)

  • Add PT_GNU_PROPERTY enum

  • Bug fix in the symbols table reconstruction (ELF)

PE
  • Enhance PE Authenticode. See PE Authenticode

  • get_imphash() can now generate the same value as pefile and Virus Total (#299)

    pe = lief.parse("example.exe")
    vt_imphash = lief.PE.get_imphash(pe, lief.PE.IMPHASH_MODE.PEFILE)
    lief_imphash = lief.PE.get_imphash(pe, lief.PE.IMPHASH_MODE.DEFAULT)
    
  • Remove the padding entry (0) from the rich header

  • items now returns a dictionary whose values are bytes (instead of str object). This change is related to utf-16 support.

  • kohnakagawa fixed wrong enums values: c031250, 6ee808a, cd05f34

  • kohnakagawa fixed a bug in the PE resources parser (a7254d1)

  • Handle PE forwarded exports (issue #307)

Mach-O
  • Add API to access either LC_CODE_SIGNATURE or DYLIB_CODE_SIGN_DRS (issue #476)

  • Fix issue when parsing twice a Mach-O file (issue #479)

Dependencies
  • Replace easyloggingpp with spdlog 1.8.1

  • Upgrade frozen to 1.0.0

  • Upgrade json to 3.7.3

  • Upgrade pybind11 to 2.6.0

  • Upgrade mbedtls to 2.16.6

Documentation
  • aguinet updated the bin2lib tutorial with the support of the new glibc versions (7884e57)

  • Global update and enable to build the documentation out-of-tree

  • Changing the theme

Misc
  • Add Python 3.9 support

  • FindLIEF.cmake deprecates LIEF_ROOT. You should use LIEF_DIR instead.

Logging

We changed the logging interface. The following log levels have been removed:

  • LOG_GLOBAL

  • LOG_FATAL

  • LOG_VERBOSE

  • LOG_UNKNOWN

We also moved from an class-interface based to functions.

Example:

lief.logging.disable()
lief.logging.enable()
lief.logging.set_level(lief.logging.LOGGING_LEVEL.INFO)

See: lief.logging.set_level()

Note

The log functions now output on stderr instead of stdout

0.10.1 - November 29, 2019

  • Fix regression in parsing Python bytes

  • Add Python API to demangle strings: lief.demangle

0.10.0 - November 24, 2019

ELF
  • Add build support for ELF notes

  • Add coredump support (9fc3a8a)

  • Enable to bind a relocation with a symbol (a9f3cb8)

    Example
    relocation = "..."
    
    symbol = lief.ELF.Symbol()
    symbol.name = "printf123"
    relocation.symbol = symbol
    
  • Add constructors (67d924a)

  • Expose ELF destructors (957384c)

  • Add remove_static_symbol (c677970)

  • Add support for static relocation writing (d1b98d6)

  • Expose function to get strings located in the .rodata section (02f4851)

  • Export ELF ABI version (8d7ec26)

PE
  • Improve PE Authenticode parsing (535623d)

  • Fix alignment issue when removing a PE section (04dddd3)

  • Parse PE debug data directory as a list of debug entries (by 1orenz0 - fcc75dd)

  • Add support to parse POGO debug entries (by 1orenz0 - 3537440)

Mach-O
  • Enhance Mach-O modifications by exposing an API to:

    • Add load commands

    • Add sections

    • Add segments

    See: 406115c

  • Enable write() on FAT Mach-O (1659531)

  • Introduce Mach-O Build Version command (6f96723)

  • Enable to remove Mach-O symbols (616d739)

  • Add support for adding LC_UNIXTHREAD commands in a MachO (by nezetic - 64d2597)

Abstract Layer
  • Expose remove_section() in the abstract layer (918438c)

  • Expose write() in the abstract layer (af4d48e)

  • Expose API to list functions found in a binary (b5a0846)

Android
  • Add partial support for Android 9 (bce9ebe)

Misc
  • lkollar added support for Python 3.8 in CI (Linux & OSX only)

  • Update Pybind11 dependency to v2.4.3

  • Enhance Python install (see: Since 0.10.0)

  • Thanks to lkollar, Linux CI now produces manylinux1-compliant wheels

Many thanks to the contributors: recvfrom, pbrunet, mackncheesiest, wisk, nezetic, lkollar, jbremer, DaLynX, 1orenz0, breadchris, 0xbf00, unratito, strazzere, aguinetqb, mingwandroid, serge-sans-paille-qb, yrp604, majin42, KOLANICH

0.9.0 - June 11, 2018

LIEF 0.9 comes with new formats related to Android: OAT, DEX, VDEX and ART. It also fixes bugs and thanks to yd0b0N, ELF parser now supports big and little endian binaries. We also completed the JSON serialization of LIEF objects.

MachO
PE
ELF
  • Add support for .note.android.ident section: d13db18

  • Enable to add unlimited number of dynamic entries: a40da3e

  • Add support for PPC relocations: 08b5141

  • Endianness support: e794ac1

  • Use frozen for some internal std::map (If C++14 is supported by the compiler)

0.8.3

  • [Mach-O] Fix typo on comparison operator - abbc264

0.8.2

  • [ELF] Increase the upper limit of relocation number - 077bc32

0.8.1 - October 18, 2017

  • Fix an alignment issue in the ELF builder. See 8db199c

  • Add assertion on the setuptools version: 62e5825

0.8.0 - October 16, 2017

LIEF 0.8.0 mainly improves the MachO parser and the ELF builder. It comes with Dockerfiles for CentOS and Android.

LibFuzzer has also been integrated in the project to enhance the parsers

Abstract Layer
ELF
  • DT_FLAGS and DT_FLAGS_1 are now parsed into DynamicEntryFlags - 754b8af

  • Handle relocations of object files (.o) - 483b8dc

  • Global enhancement of the ELF builder:

    One can now add multiple Section or Segment into an ELF:

    elf = lief.parse("/bin/cat")
    
    for i in range(3):
      segment = Segment()
      segment.type = SEGMENT_TYPES.LOAD
      segment.content = [i & 0xFF] * 0x1000
      elf += segment
    
    
    for i in range(3):
      section = Section("lief_{:02d}".format(i))
      section.content = [i & 0xFF] * 0x1000
      elf += section
    
    elf.write("foo")
    
    $ readelf -l ./foo
    PHDR 0x0000000000000040 0x0000000000000040 0x0000000000000040
     0x00000000000061f8 0x00000000000061f8 R E 0x8
    INTERP 0x0000000000006238 0x0000000000006238 0x0000000000006238
     0x000000000000001c 0x000000000000001c R 0x1
     [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
    LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
     0x000000000000d6d4 0x000000000000d6d4 R E 0x200000
    LOAD 0x000000000000da90 0x000000000020da90 0x000000000020da90
     0x0000000000000630 0x00000000000007d0 RW 0x200000
    LOAD 0x000000000000f000 0x000000000040f000 0x000000000040f000
     0x0000000000001000 0x0000000000001000 0x1000
    LOAD 0x0000000000010000 0x0000000000810000 0x0000000000810000
     0x0000000000001000 0x0000000000001000 0x1000
    LOAD 0x0000000000011000 0x0000000001011000 0x0000000001011000
     0x0000000000001000 0x0000000000001000 0x1000
    ....
    
    $ readelf -S ./foo
    ...
    [27] lief_00 PROGBITS 0000000002012000 00012000
     0000000000001000 0000000000000000 0 0 4096
    [28] lief_01 PROGBITS 0000000004013000 00013000
     0000000000001000 0000000000000000 0 0 4096
    [29] lief_02 PROGBITS 0000000008014000 00014000
     0000000000001000 0000000000000000 0 0 4096
    

    Warning

    There are issues with executables statically linked with libraries that use TLS

    See: #98

    One can now add multiple entries in the dynamic table:

    elf = lief.parse("/bin/cat")
    
    elf.add_library("libfoo.so")
    elf.add(DynamicEntryRunPath("$ORIGIN"))
    elf.add(DynamicEntry(DYNAMIC_TAGS.INIT, 123))
    elf.add(DynamicSharedObject("libbar.so"))
    
    elf.write("foo")
    
    $ readelf -d foo
     0x0000000000000001 (NEEDED) Shared library: [libfoo.so]
     0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
     0x000000000000000c (INIT) 0x7b
     0x000000000000000c (INIT) 0x3600
     ...
     0x000000000000001d (RUNPATH) Bibliothèque runpath:[$ORIGIN]
     0x000000000000000e (SONAME) Bibliothèque soname: [libbar.so]
    

    See b94900c, 1e410e6 for details.

  • b2d3694 enables modification of the ELF interpreter without length restriction

    elf = lief.parse("/bin/cat")
    elf.interpreter = "/a/very/long/path/to/another/interpreter"
    elf.write("foo")
    
    $ readelf -l foo
    Program Headers:
    Type Offset VirtAddr PhysAddr
     FileSiz MemSiz Flags Align
    PHDR 0x0000000000000040 0x0000000000000040 0x0000000000000040
     0x00000000000011f8 0x00000000000011f8 R E 0x8
    INTERP 0x000000000000a000 0x000000000040a000 0x000000000040a000
     0x0000000000001000 0x0000000000001000 R 0x1
     [Requesting program interpreter: /a/very/long/path/to/another/interpreter]
    ....
    
  • Enhancement of the dynamic symbols counting - 985d124

  • Enable editing ELF’s notes:

    elf = lief.parse("/bin/ls")
    build_id = elf[NOTE_TYPES.BUILD_ID]
    build_id.description = [0xFF] * 20
    elf.write("foo")
    
    $ readelf -n foo
    Displaying notes found in: .note.gnu.build-id
    Owner Data size Description
    GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring)
     Build ID: ffffffffffffffffffffffffffffffffffffffff
    

    See commit 3be9dd0 for more details

PE
  • Add get_imphash() and resolve_ordinals() functions - a89bc6d, dfa8e98

  • Parse the Load Config Table into LoadConfiguration (up to Windows 10 SDK 15002 with hotpatch_table_offset)

    from lief import to_json
    import json
    pe = lief.parse("some.exe")
    loadconfig = to_json(pe.load_configuration)) # Using the lief.to_json function
    pprint(json.loads(to_json(loadconfig)))
    
    {'characteristics': 248,
     'code_integrity': {'catalog': 0,
                        'catalog_offset': 0,
                        'flags': 0,
                        'reserved': 0},
     'critical_section_default_timeout': 0,
     'csd_version': 0,
     'editlist': 0,
     ...
     'guard_cf_check_function_pointer': 5368782848,
     'guard_cf_dispatch_function_pointer': 5368782864,
     'guard_cf_function_count': 15,
     'guard_cf_function_table': 5368778752,
     'guard_flags': 66816,
     'guard_long_jump_target_count': 0,
     'guard_long_jump_target_table': 0,
     'guard_rf_failure_routine': 5368713280,
     'guard_rf_failure_routine_function_pointer': 5368782880,
     ...
    

    For details, see commit: 0234e3b

MachO

Fix enums conflicts(#32) - 66b4cd4

Fix most of the memory leaks: 88dafa8, d9b1436, 554fa15, 3602643

ELF
  • Bug Fix when counting dynamic symbols from the GnuHash Table - 9036a24

PE
  • Fix nullptr dereference in resources - e90fe1b

  • Handle encoding issues in the Python API - 8c7ceaf

  • Sanitize DLL names

MachO
  • Fix #87, #92

  • Fix memory leaks and some performance issues: #94

In the C++ API get_XXX() getters have been renamed into XXX() (e.g. get_header() becomes header()) - a4c69f7, e805669

Abstract
ELF
PE
MachO
Logging

Add an API to configure the logger - 4600c2b

Example:

from lief import Logger
Logger.disable()
Logger.enable()
Logger.set_level(lief.LOGGING_LEVEL.INFO)

See: lief.Logger

References
  • recomposer, bearparser, IAT_patcher, PEframe, Manalyze, MachOView, elf-dissector

0.7.0 - July 3, 2017

Abstract Layer
  • Add bitness (32bits / 64bits) - 78d1adb

  • Add object type (Library, executable etc) - 78d1adb

  • Add mode Thumbs, 16bits etc - 78d1adb

  • Add endianness - 7ea08f7, #29

ELF
PE
  • Parse PE Overlay - e0634c1

  • Enable PE Hooking - 24f6b72

  • Parse and rebuilt dos stub - 3f06397

  • Add a resources manager to provide an enhanced API over the resources - 8473c8e

  • Serialize PE objects into JSON - 673f5a3, #18

  • Parse Rich Header - 0893bd9, #15

ELF
  • Bug fix when a GNU hash has empty buckets - 21a6c30

PE
  • Bug fix in the signature parser: #30, 4af0256

  • Bug fix in the resources parser: Infinite loop - a569cc1

  • Add more out-of-bounds checks on relocations and exports - 9364f64

  • Use min(SizeOfRawData, VirtualSize) for the section’s size and truncate the size to the file size - 61bf14b

MachO
  • Bug fix when a binary hasn’t a LC_MAIN command - 957501f

Abstract Layer
ELF
Notes
Hash Tables
PE
Dos Stub
Rich Header
Overlay
Imports
Resources
MachO
UUID
Main Command
Dylinker
References
  • elfsteem, pelook, PortEx, elfsharp, metasm, amoco, Goblin

Tutorials
Integration
  • ek0: #24

  • ACSC-CyberLab: #33, #34, #37, #39

  • Hyrum Anderson who pointed bugs in the PE parser

  • My collegues for the feedbacks and suggestions (Adrien, SebK, Pierrick)

0.6.1 - April 6, 2017

ELF
PE
Integration

0.6.0 - March 30, 2017

First public release