Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to Inject a PT_NOTE Segment into an ELF Binary Without Original PT_NOTE? #981

Open
ZhangZhuoSJTU opened this issue Oct 21, 2023 · 3 comments
Assignees

Comments

@ZhangZhuoSJTU
Copy link

ZhangZhuoSJTU commented Oct 21, 2023

Hello!

I'm currently working with ELF binaries and have a specific requirement to inject a PT_NOTE segment into binaries that originally do not have this segment. I've been going through the LIEF documentation and examples, but I haven't found a straightforward method to achieve this.

Details:

  • Binary Type: ELF
  • LIEF Version: 0.13.2-2d9855fc
  • Platform: Ubuntu 22.04

What I've tried:

    # Create and add the PT_NOTE segment
    new_segment = lief.ELF.Segment()
    new_segment.type = lief.ELF.SEGMENT_TYPES.NOTE
    binary.add(new_segment)

    # Write the modified binary to the output path
    binary.write(output_path)

But the resultant binary merely has a newly added LOAD segment, instead of a NOTE one.

Any guidance or pointers would be greatly appreciated.

Best

@romainthomas
Copy link
Member

Could you share the binary because on a simple ls it's working:

import lief

ls = lief.ELF.parse("/bin/ls")
segment = lief.ELF.Segment()
segment.type = lief.ELF.SEGMENT_TYPES.NOTE

s = ls.add(segment)
print(s)

ls.write("./out.elf")

@jochenjagers
Copy link

I can confirm this issue when working with elf files created by IAR linker ilinkarm
The print(binary) shows the newly added segment or note. But after writing and reloading the elf file the new parts are gone.
But readelf -l output.elf shows a new LOAD segment. (output at the end)
And file size has increased from 15kb to 267kb.
Used elf file is here: input.zip

import lief
binary = lief.parse('input.elf')

# add a segment of type NODE
segment = lief.ELF.Segment()
segment.type = lief.ELF.SEGMENT_TYPES.NOTE
binary.add(segment)
print(binary)
binary.write("output1.elf")

# load the written file again
binary = lief.parse('output1.elf')
# add a build_id Note
note = lief.ELF.Note(name='build_id', type=lief.ELF.NOTE_TYPES.BUILD_ID, description=[0x30])
binary.add(note)
print(binary)
binary.write("output2.elf")

binary = lief.parse('output2.elf')
print(binary)

Output is

Header
======
Magic:                           7f 45 4c 46 
Class:                           CLASS32
Endianness:                      LSB
Version:                         CURRENT
OS/ABI:                          SYSTEMV
ABI Version:                     0
Machine type:                    ARM
File type:                       EXECUTABLE
Object file version:             CURRENT
Entry Point:                     0x800044d


Program header offset:           0x1054
Section header offset:           272308
Processor Flag:                  83886080 EABI_VER5
Header size:                     52
Size of program header:          32
Number of program header:        2
Size of section header:          40
Number of section headers:       12
Section Name Table idx:          11

Sections
========
                    NULL           0         0         0         0                                                      
A0                  PROGBITS       8000000   40        54        2.21602   ALLOC EXECINSTR               LOAD           
P1 ro               PROGBITS       8000040   477       94        6.4433    ALLOC EXECINSTR               LOAD           
P2 rw               NOBITS         20000000  50        0         2.53321   WRITE ALLOC                                  
P2 zi               NOBITS         20000050  50        0         2.53321   WRITE ALLOC                                  
P2 ui               NOBITS         200000a0  3f000     0         0         WRITE ALLOC                                  
.iar.debug_frame    PROGBITS       0         12        50b       2.32441                                                
.iar.debug_line     PROGBITS       0         5d        51d       4.04571                                                
.comment            PROGBITS       0         2fbf      57a       5.4317                                                 
.iar.rtmodel        PROGBITS       0         7f        3539      5.31734                                                
.ARM.attributes     ARM_ATTRIBUTES 0         2c        35b8      4.32592                                                
.shstrtab           STRTAB         0         6e        35e4      4.5433                                                 

Segments
========
LOAD              r-x       54        8000000   8000000   4b7       4b7       4         
Sections in this segment :
        A0
        P1 ro

LOAD              r--       1054      8001000   8001000   160       160       1000      

NOTE              ---       3f000     1003f000  1003f000  0         0         1000      


Dynamic entries
===============

Dynamic symbols
===============

Static symbols
==============

Symbol versions
===============

Symbol versions definition
==========================

Symbol version requirement
==========================

Dynamic relocations
===================

.plt.got relocations
====================



Header
======
Magic:                           7f 45 4c 46 
Class:                           CLASS32
Endianness:                      LSB
Version:                         CURRENT
OS/ABI:                          SYSTEMV
ABI Version:                     0
Machine type:                    ARM
File type:                       EXECUTABLE
Object file version:             CURRENT
Entry Point:                     0x800044d
Program header offset:           0x1054
Section header offset:           272308
Processor Flag:                  83886080 EABI_VER5
Header size:                     52
Size of program header:          32
Number of program header:        2
Size of section header:          40
Number of section headers:       12
Section Name Table idx:          11

Sections
========
                    NULL           0         0         0         0                                                      
A0                  PROGBITS       8000000   40        54        2.21602   ALLOC EXECINSTR               LOAD           
P1 ro               PROGBITS       8000040   477       94        6.4433    ALLOC EXECINSTR               LOAD           
P2 rw               NOBITS         20000000  50        0         2.17224   WRITE ALLOC                                  
P2 zi               NOBITS         20000050  50        0         2.17224   WRITE ALLOC                                  
P2 ui               NOBITS         200000a0  3f000     0         0.588113  WRITE ALLOC                                  
.iar.debug_frame    PROGBITS       0         12        50b       2.32441                                                
.iar.debug_line     PROGBITS       0         5d        51d       4.04571                                                
.comment            PROGBITS       0         2fbf      57a       5.45332                                                
.iar.rtmodel        PROGBITS       0         7f        3539      5.31734                                                
.ARM.attributes     ARM_ATTRIBUTES 0         2c        35b8      4.32592                                                
.shstrtab           STRTAB         0         6e        35e4      4.49171                                                

Segments
========
LOAD              r-x       54        8000000   8000000   4b7       4b7       4         
Sections in this segment :
        A0
        P1 ro

LOAD              r--       1054      8001000   8001000   160       160       1000      


Dynamic entries
===============

Dynamic symbols
===============

Static symbols
==============

Symbol versions
===============

Symbol versions definition
==========================

Symbol version requirement
==========================

Dynamic relocations
===================

.plt.got relocations
====================

Notes
=====
Note #0
-------
Name:                            build_id
Type:                            BUILD_ID
Description:                     [30]
ID Hash:                         30




Header
======
Magic:                           7f 45 4c 46 
Class:                           CLASS32
Endianness:                      LSB
Version:                         CURRENT
OS/ABI:                          SYSTEMV
ABI Version:                     0
Machine type:                    ARM
File type:                       EXECUTABLE
Object file version:             CURRENT
Entry Point:                     0x800044d
Program header offset:           0x1054
Section header offset:           272308
Processor Flag:                  83886080 EABI_VER5
Header size:                     52
Size of program header:          32
Number of program header:        2
Size of section header:          40
Number of section headers:       12
Section Name Table idx:          11

Sections
========
                    NULL           0         0         0         0                                                      
A0                  PROGBITS       8000000   40        54        2.21602   ALLOC EXECINSTR               LOAD           
P1 ro               PROGBITS       8000040   477       94        6.4433    ALLOC EXECINSTR               LOAD           
P2 rw               NOBITS         20000000  50        0         2.17224   WRITE ALLOC                                  
P2 zi               NOBITS         20000050  50        0         2.17224   WRITE ALLOC                                  
P2 ui               NOBITS         200000a0  3f000     0         0.588113  WRITE ALLOC                                  
.iar.debug_frame    PROGBITS       0         12        50b       2.32441                                                
.iar.debug_line     PROGBITS       0         5d        51d       4.04571                                                
.comment            PROGBITS       0         2fbf      57a       5.45332                                                
.iar.rtmodel        PROGBITS       0         7f        3539      5.31734                                                
.ARM.attributes     ARM_ATTRIBUTES 0         2c        35b8      4.32592                                                
.shstrtab           STRTAB         0         6e        35e4      4.49171                                                

Segments
========
LOAD              r-x       54        8000000   8000000   4b7       4b7       4         
Sections in this segment :
        A0
        P1 ro

LOAD              r--       1054      8001000   8001000   160       160       1000      


Dynamic entries
===============

Dynamic symbols
===============

Static symbols
==============

Symbol versions
===============

Symbol versions definition
==========================

Symbol version requirement
==========================

Dynamic relocations
===================

.plt.got relocations
====================
> readelf -l input.elf 
Elf file type is EXEC (Executable file)
Entry point 0x800044d
There is 1 program header, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000054 0x08000000 0x08000000 0x004b7 0x004b7 R E 0x4

 Section to Segment mapping:
  Segment Sections...
   00     A0 P1 ro
> readelf -l output1.elf 
Elf file type is EXEC (Executable file)
Entry point 0x800044d
There are 2 program headers, starting at offset 4180

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000054 0x08000000 0x08000000 0x004b7 0x004b7 R E 0x4
  LOAD           0x001054 0x08001000 0x08001000 0x00160 0x00160 R   0x1000

 Section to Segment mapping:
  Segment Sections...
   00     A0 P1 ro 
   01    

@romainthomas
Copy link
Member

Thank you for these details. Right now, LIEF assumes that at least one PT_NOTE segment is present in the original binary. I'll see how to relax this condition.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants