Làm cách nào để tìm phần bù của hệ thống tập tin ext4?


9

Tôi có một ổ cứng bị lỗi không thể ghi hoặc đọc các cung đầu tiên của đĩa. Nó chỉ đưa ra lỗi I / O và đó là tất cả. Có những khu vực khác trên đĩa có vẻ (hầu hết) tốt. Tôi đang cố gắn kết một phân vùng (ext4) và xem liệu tôi có thể truy cập một số tệp mà tôi muốn khôi phục không. Vì mountlệnh hỗ trợ một offsettùy chọn, tôi sẽ có thể gắn kết hệ thống tập tin mặc dù bảng phân vùng không thể đọc được và không thể đọc được. Vấn đề là làm thế nào để tìm ra sự bù đắp. Không có công cụ ext4 nào có vẻ có tính năng đặc biệt này.


1
Hãy thử testdisk và photorec đi kèm.
jippie

@jippie mất 6 giờ để kiểm tra toàn bộ đĩa và cuối cùng nó không tìm thấy phân vùng nào. Tôi nghĩ rằng chiến lược tốt nhất là cố gắng tìm vị trí của hệ thống tập tin trực tiếp và gắn kết nó.
Ernest A

photorec có thể sẽ lấy các tệp của bạn ra khỏi đĩa, nhưng tên tệp và tên đường dẫn sẽ bị mất. Nếu bạn quản lý để gắn kết hệ thống tệp tất nhiên là tùy chọn tốt hơn của bạn, nhưng nếu testdisk không tìm thấy bất kỳ, thì rất có thể sự khởi đầu của hệ thống tệp cũng bị hỏng.
jippie

Câu trả lời:


13

Không có độ lệch chuẩn cho mỗi lần, vì tất nhiên bạn có thể bắt đầu phân vùng bất cứ nơi nào bạn muốn. Nhưng hãy giả sử rằng bạn đang tìm phân vùng đầu tiên và nó được tạo ra ít nhiều chấp nhận mặc định. Sau đó, có hai nơi bạn có thể tìm thấy nó, giả sử bạn đang sử dụng bảng phân vùng DOS truyền thống:

  1. Bắt đầu từ (512 byte) sector 63. Đây là truyền thống trong một thời gian rất dài và hoạt động cho đến khi ai đó nghĩ ra đĩa 4K ...
  2. Bắt đầu từ (512 byte) sector 2048. Đây là truyền thống mới, để chứa các đĩa 4K.
  3. Một lựa chọn tiền thưởng! Bắt đầu tại khu vực 56. Đây là những gì xảy ra nếu ai đó di chuyển phân vùng 63 bắt đầu để làm cho nó phù hợp với khu vực 4K.

Bây giờ, để tiếp tục, bạn sẽ muốn chọn công cụ kết xuất hex yêu thích của mình và tìm hiểu một chút về Bố cục đĩa ext4 . Cụ thể, nó bắt đầu với 1024 byte đệm, mà ext4 bỏ qua. Tiếp đến là siêu khối. Bạn có thể nhận ra siêu khối bằng cách kiểm tra số ma thuật 0xEF53 ở độ lệch 0x38 (từ bắt đầu siêu khối hoặc 0x438 từ bắt đầu phân vùng hoặc 1080 theo số thập phân.) Số ma thuật là số ít về cuối. Vì vậy, nó thực sự được lưu trữ trên đĩa dưới dạng 0x53EF.

Đây là những gì trông giống như 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..........

Lưu ý rằng khi bạn cung cấp phần bù cho giá trị gắn kết (hoặc losetup), bạn phải cung cấp phần bù cho vị trí phần đệm bắt đầu không phải là siêu khối.

Bây giờ, nếu nó không phải là phân vùng đầu tiên, hoặc nếu không thì không thuộc một trong hai (ba) điểm mong đợi, về cơ bản bạn có thể tìm kiếm số ma thuật 0xEF53. Đây là những gì testdisk(được đề nghị trong một bình luận) làm cho bạn.


2
SỰ THÀNH CÔNG!!! Tôi đã phải viết kịch bản của riêng tôi. testdisksẽ không tìm thấy nó. Cảm ơn tất cả các bạn đã giúp đỡ.
Ernest A

Dựa trên điều này, bạn có thể sử dụng một cái gì đó như dd if=/dev/sda skip=$start_sector | xxd -a | grep '[02468]30: .... .... .... .... 53ef'để có được một số trận đấu có thể xảy ra. Có lẽ không nhanh lắm, nhưng bạn có thể để nó chạy trong khi bạn tìm thấy một phương pháp tốt hơn.
mwfearnley

Xem câu trả lời của tôi dưới đây cho "phương pháp tốt hơn" bây giờ. Lưu ý: chỉ cần quét số này trong dữ liệu ngẫu nhiên sẽ tìm thấy dương tính giả sau mỗi 65536 cung (32 MB).
mwfearnley

cám ơn vì cái này. do thực tế phải mất một giây để đọc testdisk, tôi mới phải thêm một chỉnh sửa cho tl;dr:tiêu đề
Jan-Stefan Janetzky

5

Dựa trên câu trả lời của @ derobert , tôi đã viết một chương trình ( ý chính ) sẽ phân tích luồng đầu vào từ đó ddvà quét từng khu vực để tìm thứ gì đó giống như bắt đầu phân vùng mở rộng.

Nó sẽ hoạt động ít nhất là nhanh như ddcó thể đọc từ đĩa cứng của bạn. Một phiên bản rút gọn dưới đây.

Cách sử dụng đơn giản nhất chỉ là sudo dd if=/dev/xxx | ext2scan, mặc dù bạn có thể muốn sửa đổi ddlệnh để cải thiện kích thước khối hoặc chọn một khu vực để tìm kiếm.

#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++;
  }
}

Lưu ý: nó sẽ không chỉ tìm thấy sự bắt đầu của các phân vùng, mà còn cả các siêu khóa trong chúng.

Trong cả hai trường hợp, tôi khuyên bạn nên sử dụng dumpe2fsđể phân tích kết quả. Bạn có thể đổ phần bắt đầu của siêu khối bị nghi ngờ vào một tệp (ít nhất là sáu lĩnh vực đầu tiên, theo thử nghiệm không chính thức của tôi) và nếu đó là siêu khối, thì dumpe2fssẽ cho bạn biết (trong số những thứ khác) vị trí tương đối của các siêu khóa khác .


2

Đoán xem nơi phân vùng bắt đầu và áp dụng một số lực lượng vũ phu:

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

Tôi tưởng tượng điều này có thể mất một chút thời gian, nhưng nếu bạn đã dành 6 giờ với testdisk, có lẽ nó đáng để thử.


Hah, đó là rất nhiều lực lượng vũ phu!
derobert

Nó hoạt động nhưng nó chậm; Tôi đã thử điều này trên một hình ảnh đa phân vùng mà tôi biết, vì vậy tôi có thể bắt đầu nó khá gần. Bị ném vào echo "--->$i<---"dòng vì điều đó vì nếu không thì không thể đánh giá tiến trình. Tôi nghĩ bạn có thể tăng bszlên 4096, điều này sẽ tăng tốc mọi thứ.
goldilocks

Bạn có thể tăng tốc nó lên rất nhiều nếu bạn giả sử bố cục truyền thống nơi các phân vùng bắt đầu trên một ranh giới "theo dõi" (hoặc là hình trụ?).
derobert

ước tính của tôi là kém cho giải pháp này là thực tế nhưng có thể hoạt động trong các trường hợp khác
Ernest A

2

Hãy thử tùy chọn khác nhau (ví dụ: sử dụng debugfs và fsck.ext4):

gỡ lỗi:

Bạn phải gắn debugfs trước (không phải bản thân ổ cứng bị lỗi):

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-delatted-file-in-linux/comment-page-1/#comment-8

http://blisheddlo.wordpress.com/2010/10/12/USE-debugfs/

(về cơ bản, là sử dụng "debugfs -w" với chế độ kích hoạt ghi, và sau đó là "lsdel" để liệt kê tất cả các tệp đã bị xóa). Ngoài ra, bạn có thể sử dụng

và đây là fsck.ext4:

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

Một cái khác là "sleuthkit" ("sudo apt-get install sleuthkit") có lệnh như "istat" để cung cấp thông tin khối về các nút - từ đó bạn có thể lấy phần bù và do đó dễ dàng chặn nội dung dữ liệu.

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

(BTW, nếu kích thước khối là 1024, từ lệnh "show_super_stats" của debugfs, thì khối 1 sẽ được bù 1024 byte từ đầu đĩa và mỗi nhóm khối cũng có thể có một số khối.)


1

Tôi đã có một hình ảnh phần mềm sách điện tử bao gồm hình ảnh phân vùng ext3fs, để gắn kết và chỉnh sửa rằng tôi phải quét hình ảnh bằng công cụ bgrep để tìm tất cả các vị trí của số ma thuật ext3fs0x53EF và cố gắng gắn kết bằng cách sử dụng offset.

Đây là một đoạn mã rút gọn thực hiện việc gắn kết:

#!/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

Kịch bản hoàn chỉnh nằm ở đây .


0

Điều này chưa được kiểm tra nhưng tôi nghĩ bạn có thể sử dụng phương pháp được thảo luận trong SU Q & A này có tiêu đề: Tra cứu ngược inode / file từ offset trong thiết bị thô trên linux và ext3 / 4? .

Có vẻ như bạn có thể sử dụng inode của tệp + đĩa bù + kích thước khối để xác định độ lệch của tệp.


1
tôi không thấy phương pháp này có thể giúp tôi tìm ra hệ thống tập tin bắt đầu từ đâu.
Ernest A
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.