LIEF icon indicating copy to clipboard operation
LIEF copied to clipboard

Support patching libraries without relying on sections

Open kkroo opened this issue 4 years ago • 0 comments

Is your feature request related to a problem? Please describe. This is a duplicate report of the issue encountered in #378. Opening a ticket to track progress

I tried to use LIEF in python to add Frida to an armeabi-v7a Android lib. It seems to work but when I save the file using the write() function, the shared library is not added to the created file.

LIEF fails because the library misses some sections like .text, .dynsym, ... LIEF is able to parse libraries with such layout but it can't be rebuilt or modified.

How to reproduce libcronet.61.0.3163.128.so.zip

Original lib:

l = lief.parse('libcronet.61.0.3163.128.so')
>>> print(l)
Header
======
Magic:                           7f 45 4c 46
Class                            CLASS32
Endianness:                      LSB
Version:                         CURRENT
OS/ABI:                          SYSTEMV
ABI Version:                     0
Machine type:                    ARM
File type:                       DYNAMIC
Object file version:             CURRENT
Entry Point:                     0x0
Program header offset:           0x52
Section header offset:           2781536
Processor Flag                   83886592 SOFT_FLOAT EABI_VER5
Header size:                     52
Size of program header :         32
Number of program header:        8
Size of section header:          40
Number of section headers:       4
Section Name Table idx:          3

Sections
========
                    NULL           0         0         0         -0
.dynstr             STRTAB         1418      bb7       1418      4.44089   ALLOC                         LOAD
.dynamic            DYNAMIC        2a659c    118       2a559c    2.43791   WRITE ALLOC                   LOAD DYNAMIC GNU_RELRO
.shstrtab           STRTAB         0         103       2a705c    3.53617

Segments
========
PHDR              r--       34        34        34        100       100       4

LOAD              r-x       0         0         0         2994fe    2994fe    1000
Sections in this segment :
	.dynstr

LOAD              rw-       299790    29a790    29a790    d7f0      115b1     1000
Sections in this segment :
	.dynamic

DYNAMIC           rw-       2a559c    2a659c    2a659c    118       118       4
Sections in this segment :
	.dynamic

NULL              ---       0         0         0         0         0         0

GNU_STACK         rw-       0         0         0         0         0         0

ARM_UNWIND        r--       1f4d10    1f4d10    1f4d10    1cfd0     1cfd0     4

GNU_RELRO         rw-       299790    29a790    29a790    c870      c870      10
Sections in this segment :
	.dynamic


Dynamic entries
===============
PLTGOT              2a6ce4
PLTRELSZ            620
JMPREL              160f8
PLTREL              11
REL                 2b78
RELSZ               13580
RELENT              8
RELCOUNT            26aa
SYMTAB              158
SYMENT              10
STRTAB              1418
STRSZ               bb7
HASH                1fd0
NEEDED              51        libc.so
NEEDED              200       libdl.so
NEEDED              e2        libm.so
NEEDED              bad       liblog.so
SONAME              59        libcronet.61.0.3163.128.so
FINI_ARRAY          2a6590    [0x17080, 0x0]
FINI_ARRAYSZ        8
INIT_ARRAY          2a6598    [0x0]
INIT_ARRAYSZ        4
FLAGS               8          BIND_NOW
FLAGS_1             1          NOW
NULL                0
VERDEF              2afc
VERDEFNUM           1
NULL                0
NULL                0
NULL                0
NULL                0
NULL                0
NULL                0
NULL                0
NULL                0
...

After adding Frida:

>>> l.add_library('libgadget.so')
<_pylief.ELF.DynamicEntryLibrary object at 0x1094080f0>
>>> print(l)
Header
======
Magic:                           7f 45 4c 46
Class                            CLASS32
Endianness:                      LSB
Version:                         CURRENT
OS/ABI:                          SYSTEMV
ABI Version:                     0
Machine type:                    ARM
File type:                       DYNAMIC
Object file version:             CURRENT
Entry Point:                     0x0
Program header offset:           0x52
Section header offset:           2781536
Processor Flag                   83886592 SOFT_FLOAT EABI_VER5
Header size:                     52
Size of program header :         32
Number of program header:        8
Size of section header:          40
Number of section headers:       4
Section Name Table idx:          3

Sections
========
                    NULL           0         0         0         -0
.dynstr             STRTAB         1418      bb7       1418      4.44089   ALLOC                         LOAD
.dynamic            DYNAMIC        2a659c    118       2a559c    2.43791   WRITE ALLOC                   LOAD DYNAMIC GNU_RELRO
.shstrtab           STRTAB         0         103       2a705c    3.53617

Segments
========
PHDR              r--       34        34        34        100       100       4

LOAD              r-x       0         0         0         2994fe    2994fe    1000
Sections in this segment :
	.dynstr

LOAD              rw-       299790    29a790    29a790    d7f0      115b1     1000
Sections in this segment :
	.dynamic

DYNAMIC           rw-       2a559c    2a659c    2a659c    118       118       4
Sections in this segment :
	.dynamic

NULL              ---       0         0         0         0         0         0

GNU_STACK         rw-       0         0         0         0         0         0

ARM_UNWIND        r--       1f4d10    1f4d10    1f4d10    1cfd0     1cfd0     4

GNU_RELRO         rw-       299790    29a790    29a790    c870      c870      10
Sections in this segment :
	.dynamic


Dynamic entries
===============
PLTGOT              2a6ce4
PLTRELSZ            620
JMPREL              160f8
PLTREL              11
REL                 2b78
RELSZ               13580
RELENT              8
RELCOUNT            26aa
SYMTAB              158
SYMENT              10
STRTAB              1418
STRSZ               bb7
HASH                1fd0
NEEDED              0         libgadget.so
NEEDED              51        libc.so
NEEDED              200       libdl.so
NEEDED              e2        libm.so
NEEDED              bad       liblog.so
SONAME              59        libcronet.61.0.3163.128.so
FINI_ARRAY          2a6590    [0x17080, 0x0]
FINI_ARRAYSZ        8
INIT_ARRAY          2a6598    [0x0]
INIT_ARRAYSZ        4
FLAGS               8          BIND_NOW
FLAGS_1             1          NOW
NULL                0
VERDEF              2afc
VERDEFNUM           1
NULL                0
NULL                0
NULL                0
NULL                0
NULL                0
NULL                0
NULL                0
NULL                0
....
>>> l.write('libcronet.61.0.3163.128.injected.so')

Reading back patched file:

>>> l = lief.parse('libcronet.61.0.3163.128.injected.so')
>>> print(l)
Header
======
Magic:                           7f 45 4c 46
Class                            CLASS32
Endianness:                      LSB
Version:                         CURRENT
OS/ABI:                          SYSTEMV
ABI Version:                     0
Machine type:                    ARM
File type:                       DYNAMIC
Object file version:             CURRENT
Entry Point:                     0x0
Program header offset:           0x52
Section header offset:           2781536
Processor Flag                   83886592 SOFT_FLOAT EABI_VER5
Header size:                     52
Size of program header :         32
Number of program header:        8
Size of section header:          40
Number of section headers:       4
Section Name Table idx:          3

Sections
========
                    NULL           0         0         0         -0
.dynstr             STRTAB         1418      bb7       1418      4.44089   ALLOC                         LOAD
.dynamic            DYNAMIC        2a659c    118       2a559c    2.43791   WRITE ALLOC                   LOAD DYNAMIC GNU_RELRO
.shstrtab           STRTAB         0         1c        2a705c    3.65505

Segments
========
PHDR              r--       34        34        34        100       100       4

LOAD              r-x       0         0         0         2994fe    2994fe    1000
Sections in this segment :
	.dynstr

LOAD              rw-       299790    29a790    29a790    d7f0      115b1     1000
Sections in this segment :
	.dynamic

DYNAMIC           rw-       2a559c    2a659c    2a659c    118       118       4
Sections in this segment :
	.dynamic

NULL              ---       0         0         0         0         0         0

GNU_STACK         rw-       0         0         0         0         0         0

ARM_UNWIND        r--       1f4d10    1f4d10    1f4d10    1cfd0     1cfd0     4

GNU_RELRO         rw-       299790    29a790    29a790    c870      c870      10
Sections in this segment :
	.dynamic


Dynamic entries
===============
PLTGOT              2a6ce4
PLTRELSZ            620
JMPREL              160f8
PLTREL              11
REL                 2b78
RELSZ               13580
RELENT              8
RELCOUNT            26aa
SYMTAB              158
SYMENT              10
STRTAB              1418
STRSZ               bb7
HASH                1fd0
NEEDED              51        libc.so
NEEDED              200       libdl.so
NEEDED              e2        libm.so
NEEDED              bad       liblog.so
SONAME              59        libcronet.61.0.3163.128.so
FINI_ARRAY          2a6590    [0x17080, 0x0]
FINI_ARRAYSZ        8
INIT_ARRAY          2a6598    [0x0]
INIT_ARRAYSZ        4
FLAGS               8          BIND_NOW
FLAGS_1             1          NOW
NULL                0
VERDEF              2afc
VERDEFNUM           1
NULL                0
NULL                0
NULL                0
NULL                0
NULL                0
NULL                0
NULL                0
NULL                0

kkroo avatar Apr 12 '20 05:04 kkroo