ext4 파일 시스템의 오프셋을 어떻게 찾습니까?


9

디스크의 첫 번째 섹터를 쓰거나 읽을 수없는 고장난 하드 드라이브가 있습니다. 그것은 단지 I / O 오류를 제공하고 그것이 전부입니다. 디스크에는 (대부분) 잘 보이는 다른 영역이 있습니다. 파티션 (ext4)을 마운트하려고하는데 복구하려는 일부 파일에 액세스 할 수 있는지 확인하십시오. 때문에 mount명령이 지원 offset옵션을, 나는 파티션 테이블을 읽을 수 및 쓸 수없는 경우에도 파일 시스템을 마운트 할 수 있습니다. 문제는 오프셋을 찾는 방법입니다. ext4 도구 중 어느 것도이 특정 기능을 가지고 있지 않습니다.


1
testdisk 와 함께 제공되는 photorec을 사용해보십시오 .
jippie

@jippie 전체 디스크를 검사하는 데 testdisk 6 시간이 걸렸으며 결국에는 파티션을 찾지 못했습니다. 가장 좋은 전략은 파일 시스템의 위치를 ​​직접 찾아 마운트하는 것입니다.
어니스트 A

photorec는 파일을 디스크에서 가져올 수 있지만 파일 이름과 경로 이름은 손실됩니다. 물론 파일 시스템을 마운트하는 것이 더 나은 옵션이지만, testdisk가 파일 시스템을 찾지 못하면 파일 시스템의 시작도 손상 될 가능성이 있습니다.
jippie

답변:


13

당연히 표준 오프셋은 없습니다. 물론 원하는 곳에서 파티션을 시작할 수 있습니다. 그러나 첫 번째 파티션을 찾고 있다고 가정 해 봅시다. 기본 파티션은 어느 정도 허용되는 기본값으로 만들어졌습니다. 전통적인 DOS 파티션 테이블을 사용한다고 가정하면 두 곳을 찾을 수 있습니다.

  1. (512- 바이트) 섹터 63에서 시작. 이것은 매우 오랜 전통으로 누군가가 4K 디스크를 만들 때까지 작동했습니다 ...
  2. (512- 바이트) 섹터 2048에서 시작. 이것은 4K 디스크를 수용하기위한 새로운 전통입니다.
  3. 보너스 옵션! 섹터 56의 사팅 (Sarting). 누군가가 63- 시작 파티션을 4K 섹터에 맞추기 위해 움직이면 이런 일이 일어난다.

이제 계속 진행하려면 좋아하는 16 진수 덤프 도구를 선택하고 ext4 디스크 레이아웃에 대해 조금 배우십시오 . 특히 1024 바이트의 패딩으로 시작하는데, ext4는 무시합니다. 다음은 수퍼 블록입니다. 오프셋 0x38에서 수퍼 블록 시작에서 0xEF53 (파티션 시작에서 0x438, 또는 십진수 1080)을 확인하여 수퍼 블록을 인식 할 수 있습니다 . 따라서 실제로 0x53EF로 디스크에 저장됩니다.

다음과 같이 보입니다 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..........

마운트 할 오프셋 (또는 losetup)을 제공 할 때 수퍼 블록이 아닌 패딩이 시작되는 위치에 오프셋을 제공해야합니다.

이제 첫 번째 파티션이 아니거나 다른 두 지점 중 하나에 있지 않으면 기본적으로 마법 번호 0xEF53을 검색합니다. 이것이 testdisk(의견에서 권장) 당신을 위해하는 것입니다.


2
성공!!! 나는 내 자신의 대본을 작성해야했다. testdisk찾지 못했습니다. 도와 주셔서 감사합니다.
어니스트 A

이를 바탕으로 dd if=/dev/sda skip=$start_sector | xxd -a | grep '[02468]30: .... .... .... .... 53ef'가능한 일치하는 것을 얻는 것과 같은 것을 사용할 수 있습니다 . 아마 빠르지는 않지만 더 나은 방법을 찾는 동안 실행되도록 할 수 있습니다.
mwfearnley

"더 나은 방법"에 대해서는 아래 답변을 참조하십시오. 참고 : 임의의 데이터에서이 숫자를 검색하기 만하면 65536 섹터 (32MB)마다 가양 성이 발견됩니다.
mwfearnley

이것에 감사합니다. 사실 두 번째로 읽어야 할 사실 때문에 testdisk, 나는 단지 tl;dr:헤더에 대한 편집을 추가해야했다
Jan-Stefan Janetzky

5

를 기반으로 @의 derobert의 대답 , 내가 프로그램 (쓴 취지 에서 입력 스트림을 구문 분석) dd뭔가를 각 분야를 스캔을한다는 내선 파티션의 시작처럼 보인다.

최소한 dd하드 디스크에서 읽을 수있는 속도만큼 작동 합니다. 요약 버전은 다음과 같습니다.

가장 간단한 사용법은 블록 크기를 개선하기 위해 명령을 sudo dd if=/dev/xxx | ext2scan수정 dd하거나 검색 할 영역을 선택하는 것입니다.

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

참고 : 파티션의 시작뿐만 아니라 그 안에 수퍼 블록 이 있습니다.

두 경우 모두 dumpe2fs결과를 분석하는 데 사용 하는 것이 좋습니다 . 의심스러운 수퍼 블록의 시작을 파일 (최소한 비공식 테스트에 따라 최소 6 개 섹터)에 덤프 할 수 있으며 수퍼 블록 dumpe2fs인 경우 다른 수퍼 블록의 상대 위치를 알려줍니다 .


2

파티션이 시작되는 위치를 추측하고 무차별 한 힘을가하십시오.

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

시간이 다소 걸릴 수 있지만 이미 testdisk로 6 시간을 보냈다면 시도해 볼 가치가 있습니다.


하아, 그것은 많은 무차별적인 힘입니다!
derobert

작동하지만 느립니다. 오프셋을 알고있는 다중 파티션 이미지에서이를 시도 했으므로 상당히 가깝게 시작할 수 있습니다. echo "--->$i<---"그렇지 않으면 진행 상황을 측정하는 것이 불가능하기 때문에 그 때문에 줄에 던졌습니다 . 나는 당신이 bsz4096으로 증가 할 수 있다고 생각합니다 .
goldilocks

파티션이 "트랙"(또는 실린더입니까?) 경계에서 시작하는 전통적인 레이아웃을 가정하면 속도를 크게 높일 수 있습니다.
derobert

내 추정은이 솔루션이 실용적이지 못했지만 다른 상황에서도 작동 할 수 있음
Ernest A

2

다른 옵션을 시도하십시오 (예 : debugfs 및 fsck.ext4 사용).

debugfs :

먼저 debugfs를 마운트해야합니다 (실패한 하드 디스크 자체는 아님).

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/

(필수적으로 쓰기 가능 모드에서 "debugfs -w"를 사용한 다음 "lsdel"을 사용하여 삭제 된 모든 파일을 나열합니다). 또는 당신은 사용할 수 있습니다

그리고 여기 fsck.ext4가 있습니다 :

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

또 다른 하나는 "sleuthkit"( "sudo apt-get install sleuthkit")으로, inist에 대한 블록 정보를 제공하기 위해 "istat"와 같은 명령을 가지고 있으며 오프셋을 통해 데이터 내용을 쉽게 차단할 수 있습니다.

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

(BTW, debugfs의 "show_super_stats"명령에서 블록 크기가 1024 인 경우, 블록 1은 디스크 시작에서 1024 바이트 오프셋되고 각 블록 그룹에도 여러 블록이있을 수 있습니다.)


1

ext3fs 파티션 이미지가 포함 된 전자 책 펌웨어 이미지를 가지고 있는데, bgrep 도구 를 사용하여 이미지를 스캔하여 ext3fs 매직 넘버의 모든 위치를 찾고 0x53EF찾은 오프셋을 사용하여 마운트하려고 시도한 것을 마운트 하고 편집하기 위해 e-book 펌웨어 이미지가있었습니다 .

다음은 마운트를 수행하는 단축 된 스크립트입니다.

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

여기에 완전한 스크립트가 있습니다 .


0

이것은 테스트되지 않았지만이 SU Q & A에서 논의 된 방법을 사용할 수 있다고 생각합니다 .Linux 및 ext3 / 4의 원시 장치에서 오프셋에서 inode / 파일의 역방향 조회? .

파일의 inode + 디스크 오프셋 + 블록 크기를 사용하여 파일의 오프셋을 결정할 수 있습니다.


1
이 방법으로 파일 시스템이 시작되는 위치를 파악하는 데 어떻게 도움이되는지 알 수 없습니다.
어니스트 A
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.