Bagaimana cara menemukan offset dari sistem file ext4?

9

Saya memiliki hard drive yang gagal yang tidak dapat menulis atau membaca sektor pertama dari disk. Itu hanya memberikan I / O kesalahan dan itu semua ada. Ada area lain pada disk yang tampaknya (kebanyakan) baik-baik saja. Saya mencoba me-mount partisi (ext4) dan melihat apakah saya dapat mengakses beberapa file yang ingin saya pulihkan. Karena mountperintah mendukung offsetopsi, saya harus dapat me-mount sistem file meskipun tabel partisi tidak dapat dibaca dan tidak dapat ditulis. Masalahnya adalah bagaimana menemukan offset. Tidak ada alat ext4 yang tampaknya memiliki fitur khusus ini.

Ernest A
sumber
1
Coba testdisk dan photorec yang menyertainya.
jippie
@ jippie butuh testdisk 6 jam untuk memindai seluruh disk dan pada akhirnya tidak menemukan partisi apa pun. Saya pikir strategi terbaik adalah mencoba menemukan lokasi filesystem secara langsung dan memasangnya.
Ernest A
photorec mungkin akan dapat mengambil file Anda dari disk, tetapi nama file dan nama path akan hilang. Jika Anda berhasil me-mount filesystem yang tentu saja merupakan pilihan Anda yang lebih baik, tetapi jika testdisk tidak menemukan, kemungkinan dimulainya filesystem juga rusak.
jippie

Jawaban:

13

Tidak ada standar offset per-se, karena tentu saja Anda dapat memulai partisi di mana pun Anda inginkan. Tapi mari kita asumsikan sejenak bahwa Anda sedang mencari partisi pertama, dan itu dibuat lebih atau kurang menerima default. Kemudian ada dua tempat Anda mungkin menemukannya, dengan asumsi Anda menggunakan tabel partisi DOS tradisional:

  1. Mulai dari (512-byte) sektor 63. Ini adalah tradisi untuk waktu yang sangat lama, dan bekerja sampai seseorang datang dengan 4K disk ...
  2. Mulai dari (512-byte) sektor 2048. Ini adalah tradisi baru, untuk mengakomodasi 4K disk.
  3. Opsi bonus! Memulai di sektor 56. Inilah yang terjadi jika seseorang memindahkan partisi 63-start untuk membuatnya sejajar dengan sektor 4K.

Sekarang, untuk melanjutkan, Anda akan ingin mengambil alat hex-dump favorit Anda, dan belajar sedikit tentang Tata Letak Disk ext4 . Secara khusus, ini dimulai dengan 1024 byte padding, yang diabaikan oleh ext4. Selanjutnya adalah superblok. Anda dapat mengenali superblock dengan memeriksa angka ajaib 0xEF53 pada offset 0x38 (dari awal superblock, atau 0x438 dari awal partisi, atau 1080 dalam desimal.) Nomor ajaibnya adalah little-endian. Jadi sebenarnya disimpan di disk sebagai 0x53EF.

Inilah yang terlihat dengan xxd -a:

0000000: 0000 0000 0000 0000 0000 0000 0000 0000 ................ * 0000400: 0040 5d00 0084 7401 33a0 1200 33db a600 .@]...t.3...3... 0000410: 4963 5300 0000 0000 0200 0000 0200 0000 IcS............. 0000420: 0080 0000 0080 0000 0020 0000 6637 0952 ......... ..f7.R 0000430: 6637 0952 0200 1600 53ef 0100 0100 0000 f7.R....S....... 0000440: 9938 f851 004e ed00 0000 0000 0100 0000 .8.Q.N..........

Perhatikan, bahwa ketika Anda memberikan offset untuk dipasang (atau kalah), Anda harus memberikan offset ke tempat padding dimulai — bukan superblok.

Sekarang, jika ini bukan partisi pertama, atau tidak ada di salah satu dari dua (tiga) tempat yang diharapkan, Anda pada dasarnya bisa mencari angka ajaib 0xEF53. Inilah yang testdisk(disarankan dalam komentar) lakukan untuk Anda.

derobert
sumber
2
KEBERHASILAN!!! Saya harus menulis naskah sendiri. testdisktidak akan menemukannya. Terima kasih atas bantuannya.
Ernest A
Berdasarkan ini, Anda dapat menggunakan sesuatu seperti dd if=/dev/sda skip=$start_sector | xxd -a | grep '[02468]30: .... .... .... .... 53ef'untuk mendapatkan beberapa kemungkinan pertandingan. Mungkin tidak terlalu cepat, tetapi Anda dapat membiarkannya berjalan saat Anda menemukan metode yang lebih baik.
mwfearnley
Lihat jawaban saya di bawah untuk "metode yang lebih baik" sekarang. Catatan: hanya memindai angka ini dalam data acak akan menemukan false positive setiap 65536 sektor (32 MB).
mwfearnley
Terima kasih untuk ini. karena saya perlu membaca lagi untuk kedua kalinya testdisk, saya hanya perlu menambahkan sunting untuk tl;dr:tajuk
Jan-Stefan Janetzky
5

Berdasarkan jawaban @ derobert , saya menulis sebuah program ( inti ) yang akan mem-parsing aliran input dari dddan memindai setiap sektor untuk sesuatu yang tampak seperti awal partisi ext.

Ini akan berfungsi setidaknya secepat yang ddbisa dibaca dari hard disk Anda. Versi singkatnya ada di bawah.

Penggunaan paling sederhana adalah adil sudo dd if=/dev/xxx | ext2scan, meskipun Anda mungkin ingin memodifikasi ddperintah untuk meningkatkan ukuran blok atau memilih wilayah untuk dicari.

#include <unistd.h>
#include <stdio.h>
#include <string.h>

int main() {
  unsigned char const MAGIC[2] = {0x53, 0xef};
  unsigned char const ZEROS[512] = {0};

  long long int sector = 0;

  char buf[4][512];
  int empty1, empty2;

  while (read(STDIN_FILENO, buf[sector&3], 512) > 0) {
    if (!memcmp(buf[sector&3] + 0x38, MAGIC, 2)) {
      printf("Found a possible ext2 partition at sector %lld", sector-2);

      empty1 = !memcmp(buf[(sector-2)&3], ZEROS, 512);
      empty2 = !memcmp(buf[(sector-1)&3], ZEROS, 512);

      if (empty1 && empty2) printf(" (first two sectors are empty :)\n");
    }
    sector++;
  }
}

Catatan: ia tidak hanya akan menemukan awal partisi, tetapi juga superblok di dalamnya.

Dalam kedua kasus, saya akan merekomendasikan menggunakan dumpe2fsuntuk menganalisis hasilnya. Anda dapat membuang awal superblok yang dicurigai ke file (setidaknya enam sektor pertama, menurut tes informal saya), dan jika itu adalah superblok, maka dumpe2fsakan memberi tahu Anda (antara lain) lokasi relatif dari superblok lainnya. .

mwfearnley
sumber
2

Tebak di mana partisi dimulai dan terapkan beberapa kekuatan kasar:

bsz=512 # or 1024, 2048, 4096 higher = faster

for i in {2..10000000}; do
    echo "--->$i<---"
    mount -o offset=$(($bsz*$i)) -t ext4 /dev/whatever /mnt/foo
    if [ $? == 0 ]; then # whahoo!
        echo Eureka
        break
    fi
done

Saya membayangkan ini bisa memakan waktu, tetapi jika Anda sudah menghabiskan 6 jam dengan testdisk, mungkin patut dicoba.

goldilocks
sumber
Hah, itu adalah kekuatan brutal!
derobert
Ini bekerja tetapi lambat; Saya mencoba ini pada gambar multi-partisi yang offset saya tahu, jadi saya bisa memulainya dengan cukup dekat. Melemparkan echo "--->$i<---"barisan karena itu karena kalau tidak, tidak mungkin untuk mengukur kemajuan. Saya pikir Anda bisa meningkat bszmenjadi 4096, yang akan mempercepat.
goldilocks
Anda bisa mempercepatnya banyak jika mengasumsikan tata letak tradisional tempat partisi dimulai pada batas "track" (atau itu silinder?).
derobert
perkiraan saya sangat buruk untuk solusi ini menjadi praktis tetapi dapat bekerja dalam keadaan lain
Ernest A
2

Coba opsi lain (mis., Menggunakan debugfs, dan fsck.ext4):

debugfs:

Anda harus me-mount debugfs terlebih dahulu (bukan harddisk yang gagal itu sendiri):

http://johnsofteng.wordpress.com/2013/11/20/sysfs-procfs-sysctl-debugfs-and-other-similar-kernel-interfaces/

http://afzalkhanlinuxtalk.wordpress.com/2013/08/07/how-to-recover-deleted-file-in-linux/comment-page-1/#comment-8

http://blesseddlo.wordpress.com/2010/10/12/using-debugfs/

(pada dasarnya, adalah menggunakan "debugfs -w" dengan mode tulis-aktif, dan kemudian diikuti oleh "lsdel" untuk mendaftar semua file yang dihapus). atau Anda dapat menggunakannya

dan di sini adalah fsck.ext4:

http://linuxexpresso.wordpress.com/2010/03/31/repair-a-broken-ext4-superblock-in-ubuntu/

Lain adalah "sleuthkit" ("sudo apt-get install sleuthkit") yang memiliki perintah seperti "istat" untuk memberikan info blok tentang inode - dari mana Anda bisa mendapatkan offset dan dengan demikian memblokir konten data dengan mudah.

https://www.ibm.com/developerworks/cn/linux/l-cn-ext4resize/

(BTW, jika blocksize adalah 1024, dari perintah "show_super_stats" debugfs, maka itu mengikuti bahwa blok 1 adalah 1024 byte offset dari awal disk, dan setiap grup blok dapat memiliki beberapa blok juga.)

Peter Teoh
sumber
1

Saya memiliki gambar firmware e-book yang termasuk gambar partisi ext3fs, untuk me-mount dan mengedit saya harus memindai gambar menggunakan alat bgrep untuk menemukan semua posisi nomor ajaib ext3fs 0x53EFdan mencoba me-mount menggunakan offset yang ditemukan.

Berikut ini skrip singkat yang melakukan pemasangan:

#!/bin/sh
FW_IMAGE=$1
MOUNT_POINT=$2

FS_TYPE=ext3
EXTFS_MAGIC_NUM=53ef
MAGIC_OFFSET=1080

OFFSETS=`bgrep $EXTFS_MAGIC_NUM $FW_IMAGE | awk '{print toupper($NF)}'`
for OFFSET in $OFFSETS; do
  OFFSET=`echo "ibase=16; $OFFSET" | bc`
  OFFSET=`expr $OFFSET - $MAGIC_OFFSET`
  sudo mount -t $FS_TYPE -o loop,offset=$OFFSET $FW_IMAGE $MOUNT_POINT 2>/dev/null
  if [ $? -eq 0 ]; then
    echo "Success!  Offset is: $OFFSET."
    break
  fi
done

Script lengkap ada di sini .

talas
sumber