Last active
December 19, 2021 18:06
-
-
Save countingpine/0fd04b99058ebc910fefc910606ae6d0 to your computer and use it in GitHub Desktop.
ext2scan: scan for ext2/ext3/ext4 partitions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* ext2scan: | |
* Scans an input stream, sector by sector, for something that looks like an ext{2,3,4} partition. | |
* It does this by looking for a magic WORD, 0xEF53, at a known offset into the sector. | |
* For random data, this will occur by chance around once per 32MB of data, so we also | |
* check whether the first two sectors are all zeros, which is commonly true for ext partitions. | |
* | |
* Compile with: | |
* gcc ./ext2scan.c -o ./ext2scan | |
* | |
* Example usage: | |
* dd if=/dev/sda [skip=$START_SECTOR] | ./ext2scan [$START_SECTOR] | |
* | |
* Or for more speed, use a larger block size: | |
* dd if=/dev/sda bs=1M [iflag=skip_bytes skip=$(($START_SECTOR*512))] | ./ext2scan [$START_SECTOR] | |
* | |
* References: | |
* - http://unix.stackexchange.com/questions/103919/how-do-i-find-the-offset-of-an-ext4-filesystem | |
* - http://uranus.chrysocome.net/explore2fs/es2fs.htm | |
*/ | |
#include <unistd.h> | |
#include <stdio.h> | |
#include <string.h> | |
int main(int arg_c, char **arg_v) { | |
unsigned char const MAGIC[2] = {0x53, 0xef}; | |
unsigned char const ZEROS[512] = {0}; | |
char buf[4][512]; | |
int empty1, empty2; | |
long long int sector = 0; | |
long long int offset = 0; | |
if (arg_c == 2) sscanf(arg_v[1], "%lld", &offset); | |
while (read(STDIN_FILENO, buf[sector&3], 512) > 0) { | |
if (!memcmp(buf[sector&3] + 0x38, MAGIC, 2)) { | |
printf("Found a possible ext partition at sector %lld", offset+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"); | |
else if (empty1) printf(" (first sector only is empty)\n"); | |
else if (empty2) printf(" (second sector only is empty)\n"); | |
else printf(" (first two sectors are non-empty)\n"); | |
} | |
sector++; | |
} | |
} | |
@futpib What does "gdisk
ed it" mean? (more comments at your modified gist, thanks!)
@jsarenik I edited my comment. Hope it helps.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This helped me so much! I had an MBR partition table and a couple of NTFS partitions created over my originally GPT + ext4 hard drive, so I had to find out the original first sector, and no valid superblock could be found by
fsck.ext
when I tried probable values (like the default suggested bygdisk
, 1024, 2048, etc.).Running this gave me a lot of potential backup superblocks to search through, so I had to read up on ext4 superblocks to narrow this set down.
I ended up modifying this to check that superblock creator OS is Linux. This gave me, in just a few seconds of scanning, a bunch of backup superblocks backups exactly (no false positives whatsoever). I derived the proper first sector of the file system from that, created a partition starting at this sector using
gdisk
, got a proper partition size fromdumpe2fs -o superblock=XXX
, recreated the partition withgdisk
using the discovered partition length, and could successfully runfsck.ext4
on it afterwards. My data is back! (Well, most of it).Here is the forked version I used https://gist.github.com/futpib/cfb04a9843b8f176d5c2ed3364fc8527. Hope it helps someone! Note that it prints superblock backup offsets in 4096 byte sectors, not in 512 byte sectors like the original.