LIEF v0.13.0 is eventually out! The full changelog is available here, but for those who would like an highlight on the main changes here they are.
LIEF is now able to parse a Mach-O file from an in-memory pointer:
1uintptr_t mhdr = ...; // Absolute address to an in-memory Mach-O file
2auto macho = LIEF::MachO::Parser::parse_from_memory(mhdr);
This feature can be handy on iOS to access the in-memory content of the binary.
Firstly because some parts of the application code are encrypted (thanks to the LC_ENCRYPTION_INFO
commands).
Secondly, it can be used on protected code that fills the __data
segment
with clear (original) strings (c.f. Gotta Catch ‘Em All: Frida & jailbreak detection).
This feature could also be used in pair with _dyld_get_image_header
, once we are
injected into the targeted process:
1size_t count = _dyld_image_count();
2for (size_t i = 0; i < count; ++i) {
3 llvm::StringRef Name = _dyld_get_image_name(i);
4 if (Name.contains("MyApp.app/Target")) {
5 auto* mhdr = _dyld_get_image_header(i);
6 auto macho = MachO::Parser::parse_from_memory((uintptr_t)mhdr);
7 }
8}
It might also work to access the dyld shared cache libraries but this aspect does not have been heavily tested.
The ELF format is – by far – the most tricky format especially when it comes dealing with sections and segments. These ELF structures are two different ways of slicing the binary data:
LIEF implements a mechanism to deal with this dual representation so that if the user
updates the .text
section, the changes are also committed in the associated segment (if any).
It turns out that in some scenarios1, we might want to NOT commit the changes we are doing
on the sections. The lief.ELF.Section.as_frame()
function can be used to make the section “frame only”.
All the attributes of the section will be committed in the final ELF binary but
LIEF won’t consider this section to write the content in the binary.
One can use – for instance – this function to corrupt sections attributes:
1elf = lief.parse("/bin/ls")
2text = elf.get_section(".text").as_frame()
3text.offset = 0xffffff
4elf.write("ls.modified")
As the .text
section is set as “framed”, its 0xffffff
offset is not considered
for changing its content. Thus this code does not update anything:
1text.content = ...
Since the ELF loader only relies on segment, this modification does not affect the execution of the modified binary.
As announced in the previous v0.12.0 release, the LIEF’s code base is now free
from exceptions and RTTI. This means that the core library can be compiled in
an -fno-exceptions
context.
The Python build process is now compliant with the PEP 621
pyproject.toml
requirement. You can find out this file, along with config-default.toml
,
in the api/python
directory. The config-default.toml
file can be used to tweak
the compilation of the bindings. This is essentially an interface over the LIEF’s cmake option.
Lastly, the setup.py
file used for compiling the binding has moved from the root directory
to api/python
.
On top of that, the Python bindings also stubgen interfaces (.pyi
) which are
handy for type checking and code completion (cf. issues/650).
Some features like the Rust bindings are not released yet they still require some ongoing work. I also really do hope to be able to work on enhancing the PE format modification in the next release but this will be balanced with the spare time I have to work on it :)
Thank you for using LIEF!