Чтение вывода dd в переменную сценария оболочки

Будучи очень новым для сценариев оболочки, я собрал следующее для поиска /dev/sdd1по секторам поиска, чтобы найти строку. Как получить данные сектора в $HAYSTACKпеременную?

#!/bin/bash

HAYSTACK=""
START_SEARCH=$1
NEEDLE=$2
START_SECTOR=2048
END_SECTOR=226512895+1
SECTOR_NUMBER=$((START_SEARCH + START_SECTOR))
while [  $SECTOR_NUMBER -lt $END_SECTOR ]; do
    $HAYSTACK=`dd if=/dev/sdd1 skip=$SECTOR_NUMBER count=1 bs=512`
    if [[ "$HAYSTACK" =~ "$NEEDLE" ]]; then
        echo "Match found at sector $SECTOR_NUMBER"
        break
    fi
    let SECTOR_NUMBER=SECTOR_NUMBER+1 
done

Обновить

Цель состоит в том, чтобы не создавать идеальный сценарий для обработки фрагментированных сценариев файлов (я сомневаюсь, что это возможно вообще).

В моем случае неспособность отличить жало с нулями также не является проблемой.

Если бы вы могли расширить предложения труб в ответ, этого было бы более чем достаточно. Благодаря!

Задний план

Мне удалось стереть мою www-папку и пытались восстановить как можно больше моих исходных файлов. У меня есть Scalpel для восстановления файлов php и html. Но версия, которую я мог бы работать с Ubuntu 16.04, - это версия 1.60, которая не поддерживает регулярное выражение в stringser / footer, поэтому я не могу создать хороший шаблон для css, js и json-файлов.

Я помню довольно редкие строки для поиска и поиска файлов, но понятия не имею, где в блоке может быть строка. Решение, которое я придумал, - это сценарий оболочки для чтения блоков из раздела и поиска подстроки, и если найдено совпадение, распечатайте номер LSB и выйдите.

linux,bash,shell,dd,

2

Ответов: 2


  1. Если искомый элемент является текстовой строкой, попробуйте использовать -t параметр headкоманды для печати смещения, где найдена строка. Поскольку пользователю grep -m 1 GRUBне важно, откуда взялись данные, он работает с файлами, блочными устройствами и входящими в него каналами dd.

    Пример с начала жесткого диска:

    sudo strings -t d /dev/sda | grep -m 1 GRUB
    

    Вывод:

        392 GRUB 
    

    Вместо headэтого может быть подключен bashканал, который выводит только первую строку с « GRUB »:

    s=GRUB ; sudo strings -t d /dev/sda7 | grep "$s" | 
    while read a b ; do
        n=${b%%${s}*}
        printf "String %-10.10s found %3i bytes into sector %i
    " 
             ""${b#${n}}"" $(( (a % 512) + ${#n} )) $((a/512 + 1)) 
    done | head -5
    

    Вывод:

    String "GRUB Boot found   7 bytes into sector 17074
    String "GRUB."    found 548 bytes into sector 25702
    String "GRUB."    found 317 bytes into sector 25873
    String "GRUBLAYO" found 269 bytes into sector 25972
    String "GRUB"     found 392 bytes into sector 26457
    

    Оттуда ddможно сделать довольно много. Этот код находит первые 5 экземпляров «GRUB» на моем загрузочном разделе / dev / sda7 :

    strings

    Вывод (номера секторов здесь относятся к началу раздела):

    strings

    Что следует учитывать:

    • Не ddвыполняйте -bastrings -td одноблочные поиски, так grepкак это не сработает, если строка охватывает два блока. Используйте bashсначала, чтобы получить смещение, затем преобразуйте это смещение в блоки (или сектора).

    • $nможет возвращать большие строки, а «игла» может содержать несколько байтов в строку, и в этом случае смещение будет началом большой строки, а не rafind2строкой (или «иглой»). Вышеупомянутый sudo rafind2 -Xs GRUB /dev/sda7 | head -7 код позволяет это и использует 0x856207 - offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF 0x00856207 4752 5542 2042 6f6f 7420 4d65 6e75 006e GRUB Boot Menu.n 0x00856217 6f20 666f 6e74 206c 6f61 6465 6400 6963 o font loaded.ic 0x00856227 6f6e 732f 0069 636f 6e64 6972 0025 733a ons/.icondir.%s: 0x00856237 2564 3a25 6420 6578 7072 6573 7369 6f6e %d:%d expression 0x00856247 2065 7870 6563 7465 6420 696e 2074 expected in t для вычисления скорректированного смещения.

  2. bashМетод « ленивый все-в-одном» . Например, найдите первый экземпляр « GRUB » на / dev / sda7, как и раньше:

    sed

    Вывод:

    strings

    С некоторыми s=GRUB ; sudo rafind2 -Xs "$s" /dev/sda7 | sed -r "s/x1B[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g" | sed -r -n 'h;n;n;s/.{52}//;H;n;n;n;n;g;s/ //p' | while read a b ; do printf "String %-10.10s" found %3i bytes into sector %i " ""${b}" $((a%512)) $((a/512 + 1)) done | head -5 и sedчто выход может быть переработан в том же формате, что и stringsвывод:

    sed

    Первый sedэкземпляр заимствован из ответа jfs на « Программа, передающая STDIN в STDOUT с разбитыми цветовыми кодами? » , Поскольку rafind2выдает нетекстовые цветовые коды.

    Вывод:

    String "GRUB Boot" found   7 bytes into sector 17074
    String "GRUB....L" found  36 bytes into sector 25703
    String "GRUB...LI" found 317 bytes into sector 25873
    String "GRUBLAYO." found 269 bytes into sector 25972
    String "GRUB .Geo" found 392 bytes into sector 26457
    

1

Думали ли вы о таких

cat /dev/sdd1 | od -cv | sed s'/[0-9]* (.*)/1/' | tr -d '
' | sed s'/  F   l/  F   l/'g  > v1
cat /dev/sdd1 | od -cv | sed s'/[0-9]* (.*)/1/' | tr -d '
' | sed s'/  F   l/x F   l/'g  > v2
cmp -lb v1 v2

например, применяя это к файлу .pdf

od -cv phase-2-guidance.pdf  | sed s'/[0-9]* (.*)/1/' | tr -d '
' | sed s'/  F   l/  F   l/'g  > v1
od -cv phase-2-guidance.pdf  | sed s'/[0-9]* (.*)/1/' | tr -d '
' | sed s'/  F   l/  x   l/'g  > v2
cmp -l v1 v2

дает результат

   228 106 F    170 x
 23525 106 F    170 x
 37737 106 F    170 x
 48787 106 F    170 x
 52577 106 F    170 x
 56833 106 F    170 x
 57869 106 F    170 x
118322 106 F    170 x
119342 106 F    170 x

где номерами в первом столбце будут байтовые смещения, где начинается поиск шаблона. Эти байтовые смещения умножаются на четыре, поскольку od использует четыре байта для каждого байта.

Форма одной строки (в оболочке bash) без записи больших временных файлов будет

od -cv phase-2-guidance.pdf  | sed s'/[0-9]* (.*)/1/' | tr -d '
' | sed s'/  F   l/  x   l/'g | cmp -lb - <(od -cv phase-2-guidance.pdf  | sed s'/[0-9]* (.*)/1/' | tr -d '
' | sed s'/  F   l/  F   l/'g )

это позволяет избежать необходимости записывать содержимое / dev / sdd1 в временные файлы.

Вот пример поиска PDF на устройстве USB-накопителя и деления на 4 и 512 для получения номеров блоков

dd if=/dev/disk5s1 bs=512 count=100000 | od -cv | sed s'/[0-9]* (.*)/1/' | tr -d '
'  | cmp -lb - <(dd if=/dev/disk5s1 bs=512 count=100000 | od -cv | sed s'/[0-9]* (.*)/1/' | tr -d '
' | sed s'/P   D   F/x   D   F/'g ) | awk '{print int($1/512/4)}' | head -10

тестирование это дает

100000+0 records in
100000+0 records out
51200000 bytes transferred in 18.784280 secs (2725683 bytes/sec)
100000+0 records in
100000+0 records out
51200000 bytes transferred in 40.915697 secs (1251353 bytes/sec)
cmp: EOF on -
28913
32370
32425
33885
35097
35224
37177
38522
39981
41570

где числа - 512 байтовых номеров блоков. Проверка дает

dd if=/dev/disk5s1 bs=512 skip=35224 count=1 | od -vc | grep P

0000340        001   P   D   F       C   A   R   O        

Вот как выглядит реальный полный пример с диском и ищет последовательность символов в реальном времени и где символы разделены NUL

   dd if=/dev/disk5s1 bs=512 count=100000 | od -cv | sed s'/[0-9]* (.*)/1/' | tr -d '
' | sed s'/l  \0   i  \0   v  \0   e/x  \0   i  \0   v  \0   e/'g | cmp -lb - <(dd if=/dev/disk5s1 bs=512 count=100000 | od -cv | sed s'/[0-9]* (.*)/1/' | tr -d '
' | sed s'/l  \0   i  \0   v  \0   e/l  \0   i  \0   v  \0   e/'g )

Заметка

  • это не касается фрагментации в не последовательные блоки, где это разделяет шаблон. Второе sed, которое выполняет шаблон и замену, может быть заменено специальной программой, которая выполняет некоторое частичное совпадение с образцом и делает замену, если количество совпадающих символов выше некоторого уровня. Это может вернуть ложные срабатывания, но, вероятно, это единственный способ борьбы с фрагментацией.
Linux, Bash, оболочки, дд,
Похожие вопросы
Яндекс.Метрика