01 - Parse and manipulate formats¶
The objective of this tutorial is to provide an overview of LIEF’s API for parsing and manipulating formats.
ELF¶
We’ll start with the
ELF format. To create an ELF.Binary from a file, simply pass its path to the or functions.Note
With the Python API, these functions exhibit the same behavior, but in C++, will return a pointer to a object, whereas will return a object.
import lief
binary = lief.parse("/bin/ls")
Once the ELF file has been parsed, we can access its Header:
binary: lief.ELF.Binary
header = binary.header
To change the entry point and the target architecture (ARCH):
header: lief.ELF.Header
header.entrypoint = 0x123
header.machine_type = lief.ELF.ARCH.AARCH64
Then, write these changes to a new ELF binary:
binary: lief.ELF.Binary
binary.write("ls.modified")
We can also iterate over the Section entries as follows:
binary: lief.ELF.Binary
for section in binary.sections:
print(section.name) # section name
print(section.size) # section size
print(len(section.content)) # Should match the previous print
To modify the content of the .text section:
binary: lief.ELF.Binary
text = binary.get_section(".text")
assert text is not None
text.content = bytes([0x33] * text.size)
PE¶
As with the
ELF section, you can use the or functions to create a PE.Binaryimport lief
binary = lief.parse("C:\\Windows\\explorer.exe")
To access the various PE headers (DosHeader, Header, and OptionalHeader):
binary: lief.PE.Binary
print(binary.dos_header)
print(binary.header)
print(binary.optional_header)
You can also access imported functions in two ways:
Using the abstract layer
Using the PE definition
# Using the abstract layer
binary: lief.PE.Binary
for func in binary.imported_functions:
print(func)
# Using the PE definition
for func in binary.imports:
print(func)
For finer granularity regarding the location of imported functions in libraries, or to access other fields of the PE imports, we can process the imports as follows:
binary: lief.PE.Binary
for imported_library in binary.imports:
print("Library name: " + imported_library.name)
for func in imported_library.entries:
if not func.is_ordinal:
print(func.name)
print(func.iat_address)