How to extract only the raw contents of an ELF section?
Asked Answered
R

5

45

I've tried the following, but the resulting file is still an ELF and not purely the section content.

$ objcopy --only-section=<name> <infile> <outfile>

I just want the contents of the section. Is there any utility that can do this? Any ideas?

Roundtheclock answered 13/10, 2010 at 15:0 Comment(1)
objcopy should work.Vescuso
R
18

Rather inelegant hack around objdump and dd:

IN_F=/bin/echo
OUT_F=./tmp1.bin
SECTION=.text

objdump -h $IN_F |
  grep $SECTION |
  awk '{print "dd if='$IN_F' of='$OUT_F' bs=1 count=$[0x" $3 "] skip=$[0x" $6 "]"}' |
  bash

The objdump -h produces predictable output which contains section offset in the elf file. I made the awk to generate a dd command for the shell, since dd doesn't support hexadecimal numbers. And fed the command to shell.

In past I did all that manually, without making any scripts, since it is rarely needed.

Roley answered 13/10, 2010 at 15:56 Comment(3)
That would sound funny coming from me, but why not the straight-forward proper solution from @ndim???Roley
If the file produced by the other solution is 0 bytes, just add --set-section-flags .sectionname=alloc on the command line.Delia
good idea but it does not work for me.. see my answer which is similarAlderete
N
75

Use the -O binary output format:

objcopy -O binary --only-section=.text foobar.elf foobar.text

Just verified with avr-objcopy and an AVR ELF image's .text section.

Note that if, as Tim points out below, your section doesn't have the ALLOC flag, you may have to add --set-section-flags .text=alloc to be able to extract it.

Nuzzle answered 13/10, 2010 at 15:4 Comment(5)
When I add this, the resulting <outfile> is empty. It contains neither the ELF section header nor the section content. The command I used in the question does not produce an empty file.Roundtheclock
The following works for me: objcopy -O binary -j .text /usr/bin/lpr mylprtextAustreng
This neat trick doesn't work for all sections. objcopy will not copy out sections that are flagged neither loaded ("load") nor allocated ("alloc"). A comment in the source claims that "The contents of such a section are not meaningful in the binary format."Turbofan
Strangely enough, but objcopy prints: Unable to recognise the format of the input file `elf.img', when objdump prints sections normally.Mohun
This alongside with the --set-section-flags allowed me to dump .ARM.attributes into a file. Wouldn't touch the awk script in the other answer with a stick ;) +1.Delia
D
39

objcopy --dump-section

Introduced in Binutils 2.25, and achieves a similar effect to -O binary --only-section.

Usage:

objcopy --dump-section .text=output.bin input.o

https://sourceware.org/binutils/docs-2.25/binutils/objcopy.html documents it as:

--dump-section sectionname=filename

Place the contents of section named sectionname into the file filename, overwriting any contents that may have been there previously. This option is the inverse of --add-section. This option is similar to the --only-section option except that it does not create a formatted file, it just dumps the contents as raw binary data, without applying any relocations. The option can be specified more than once.

Minimal runnable example

main.S

.data
    .byte 0x12, 0x34, 0x56, 0x78
.text
    .byte 0x9A, 0xBC, 0xDE, 0xF0

Assemble:

as -o main.o main.S

Extract data:

objcopy --dump-section .data=data.bin main.o
hd data.bin

Output:

00000000  12 34 56 78                                       |.4Vx|
00000004

Extract text:

objcopy --dump-section .text=text.bin main.o
hd text.bin

Output:

00000000  9a bc de f0                                       |....|
00000004

Tested in Ubuntu 18.04 amd64, Binutils 2.30.

Drowsy answered 4/9, 2015 at 13:32 Comment(1)
This should be the best answer.Rioux
R
18

Rather inelegant hack around objdump and dd:

IN_F=/bin/echo
OUT_F=./tmp1.bin
SECTION=.text

objdump -h $IN_F |
  grep $SECTION |
  awk '{print "dd if='$IN_F' of='$OUT_F' bs=1 count=$[0x" $3 "] skip=$[0x" $6 "]"}' |
  bash

The objdump -h produces predictable output which contains section offset in the elf file. I made the awk to generate a dd command for the shell, since dd doesn't support hexadecimal numbers. And fed the command to shell.

In past I did all that manually, without making any scripts, since it is rarely needed.

Roley answered 13/10, 2010 at 15:56 Comment(3)
That would sound funny coming from me, but why not the straight-forward proper solution from @ndim???Roley
If the file produced by the other solution is 0 bytes, just add --set-section-flags .sectionname=alloc on the command line.Delia
good idea but it does not work for me.. see my answer which is similarAlderete
A
0

Dump all sections in separate files.

readelf -a filename|grep "NULL\|LOAD"| (x=0;while read a;do echo "$x $a"|awk '{print "dd if=143 of=filename.section."$1" bs=1 skip=$((" $3")) count=$(("$6"))"}';let x=x+1;done)|bash
Alderete answered 5/6, 2019 at 17:51 Comment(0)
F
0

Here is another shot at the problem that uses only readelf, bash and dd.

#!/bin/bash

sections="\.symtab|\.strtab"

if [ "$#" -ne 1 ]; then
  echo "Usage $0 [INPUT ELF FILE]"
  exit 1
fi

readelf -S "$1" | while IFS= read -r line; do
    pattern="\[[[:digit:]]+\].*(${sections}) +[[:alpha:]]+ +[[:xdigit:]]+ +([[:xdigit:]]+) +([[:xdigit:]]+)"
    if [[ ${line} =~ $pattern ]]; then
      sec=${BASH_REMATCH[1]}
      off=${BASH_REMATCH[2]}
      len=${BASH_REMATCH[3]}
       dd if="$1" of="$1${sec}.raw" bs=1 skip=$(("0x$off")) count=$(("0x$len"))
    fi
done

As you can see, I am using this to extract the symtab and strtab sections because they are impossible to extract otherwise (e.g., with objcopy and cannot be set allocatable).

Foul answered 14/12, 2022 at 11:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.