Subject: Re: Now I've really done it: I have no more mbr
To: None <current-users@NetBSD.org>
From: Peter Seebach <seebs@plethora.net>
List: current-users
Date: 08/19/2003 04:04:28
In message <20030819081510.GH17972@apb.cequrux.com>, Alan Barrett writes:
>*BSD disklabels have magic numbers that should be easy to find. I am
>sure I've seen references to a program that searches a disk for labels,
>but I can't remember where.
It's been posted to this list before.
Since it's only 3K:
/*
* Copyright (c) 1997 David Brownlee (abs@mono.org). Licence at end of file.
* Attempt to find ffs filesystems in the event of a lost disklabel.
*
* This program itself will not modify any data on a disk, but using
* disklabel and fsck _can_ cause loss of data - you have been warned!
*
* Compile with 'cc -Wall -O -o ffs_find ffs_find.c'.
*
* To use, run 'ffs_find /dev/rXXNc' (eg rsd0c, rsd1c, or rwd0c etc), note the
* possible filesystems, disklabel appropriately and try to fsck.
* (May want to use /dev/rXXNd on i386).
*
* It reports possible filesystems by checking for two 'superblock like'
* blocks fs.fs_sblkno blocks apart.
*
* Caveats:
* It can find false positives. (It should check more rigorously).
* It assumes 512 byte blocks.
* It assumes the first & second superblocks of a filesystem are intact,
* and at offsets of fs.fs_sblkno and fs.fs_sblkno*2 respectively.
* The 'trick' with sbplus is not particularly palatable,
*
* Comments/suggestions welcome!
*/
#include <stdio.h>
#include <string.h>
#include <sys/param.h>
#include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h>
#define BLOCKSIZE 512
#define SB_SIZE (((sizeof(struct fs)+BLOCKSIZE-1)/BLOCKSIZE)*BLOCKSIZE)
typedef struct
{
struct fs data;
char pad[BLOCKSIZE-1];
}fsplus;
int main(int argc,char **argv)
{
FILE *fds;
fsplus sblock;
int blockno = 0;
int size = 0;
int last = 0;
if( argc!=2 )
{
fputs("Usage: ffs_find special\n",stderr);
exit(3);
}
if( (fds=fopen(argv[1],"r"))==0 )
{
perror(argv[1]);
exit(3);
}
if( fread(&sblock.data,SB_SIZE,1,fds)==0 )
{
fputs("Unable to read start of partition.\n",stderr);
exit(3);
}
last=0;
do {
if( sblock.data.fs_magic == FS_MAGIC )
{
printf("%d\n",blockno);
fflush(stdout);
if( last && last==blockno-sblock.data.fs_sblkno )
{
size=sblock.data.fs_size*(sblock.data.fs_fsize/BLOCKSIZE);
printf("Possible filesystem at offset %u, size %u (%uMB).\n",
last-sblock.data.fs_sblkno,size,
size/(1024*1024/BLOCKSIZE));
/*
* Do not skip to end of possible filesystem, as may be
* false positive
*/
}
last=blockno;
}
memmove(&sblock.data,(char *)&sblock.data+BLOCKSIZE,
sizeof(sblock.data)-BLOCKSIZE);
++blockno;
}while(fread((char *)&sblock.data+SB_SIZE-BLOCKSIZE,BLOCKSIZE,1,fds));
return(0);
}
/*
* Copyright (c) 1997 David Brownlee (abs@mono.org). All rights reserved.
*
* This program is free software.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/