Как извлечь только сырое содержимое раздела ELF?

Я попробовал следующее, но полученный файл все еще является ELF, а не чисто содержимым раздела.

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

Я просто хочу содержимое раздела. Есть ли какая-либо утилита, которая может сделать это? Есть идеи?

5 ответов

Решение

Скорее не элегантный хакер objdump а также 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

objdump -h производит предсказуемый вывод, который содержит смещение раздела в файле elf. Я сделал awk генерировать dd Команда для оболочки, так как dd не поддерживает шестнадцатеричные числа. И покормил команду оболочкой.

Раньше я делал все это вручную, без каких-либо сценариев, так как это редко требовалось.

Использовать -O binary Выходной формат:

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

Только что подтверждено avr-objcopy и изображение AVR ELF .text раздел.

Обратите внимание, что если, как указывает Тим ​​ниже, в вашем разделе нет флага ALLOC, возможно, вам придется добавить --set-section-flags .text=alloc чтобы иметь возможность извлечь его.

objcopy --dump-section

Введенный в Binutils 2.25, и достигает аналогичного эффекта -O binary --only-section,

Использование:

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

https://sourceware.org/binutils/docs-2.25/binutils/objcopy.html документирует это как:

--dump-section sectionname = имя файла

Поместите содержимое раздела с именем sectionname в имя файла, перезаписав любое содержимое, которое могло быть там ранее. Эта опция является обратной к --add-section. Эта опция похожа на опцию --only-section, за исключением того, что она не создает отформатированный файл, она просто выгружает содержимое в виде необработанных двоичных данных без применения каких-либо перемещений. Опция может быть указана более одного раза.

Минимальный работоспособный пример

как:

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

Собрать и извлечь:

as -o a.o a.S
objcopy --dump-section .data=data.bin a.o
objcopy --dump-section .text=text.bin a.o
hd data.bin
hd text.bin

Выход:

00000000  12 34 56 78                                       |.4Vx|
00000004
00000000  9a bc de f0                                       |....|
00000004

Протестировано в Ubuntu 18.04 amd64, Binutils 2.30.

Вот еще один снимок проблемы, который использует толькоreadelf,bashи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

Как видите, я использую это для извлечения разделов symtab и strtab, потому что иначе их извлечь невозможно (например, с помощьюobjcopyи не может быть установлен выделяемым).

Сбросить все разделы в отдельные файлы.

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
Другие вопросы по тегам