📄 rescuept.c
字号:
* The boot code contains message strings ("Invalid system disk") * but these are often localized ("Ongeldige diskette "). * After these messages one finds two or three filenames. * (MSDOS 6.2: "\r\nNon-System disk or disk error\r\n" * "Replace and press any key when ready\r\n", "IO SYS", "MSDOS SYS") * (W95: "IO SYS", "MSDOS SYS", "WINBOOT SYS") * In all cases the sector seems to end with 0, 0, 55, aa. * * Random collection of messages (closed by \0377 or 0): * "\r\nInvalid system disk" * "\r\nOngeldige diskette " * "\r\nDisk I/O error" * "\r\nI/O-fout " * "\r\nReplace the disk, and then press any key\r\n" * "\r\nVervang de diskette en druk op een toets\r\n" * This seems to suggest that the localized strings have the same length. * * "Non-System disk or disk error" * "Replace and press any key when ready" * "Disk Boot failure" * * "BOOT: Couldn't find NTLDR" * "I/O error reading disk" * "Please insert another disk" */struct fat32_boot_fsinfo { uint32 signature1; /* 41 61 52 52 */ uchar unknown1[480]; uint32 signature2; /* 61 41 72 72 0x61417272L */ uint32 free_clusters; /* Free cluster count. -1 if unknown */ uint32 next_cluster; /* Most recently allocated cluster. * Unused under Linux. */ uchar unknown2[14]; uchar signature[2]; /* 510-511: aa55 */};struct msdos_dir_entry { uchar name[8],ext[3]; /* name and extension */ uchar attr; /* attribute bits */ uchar lcase; /* Case for base and extension */ uchar ctime_ms; /* Creation time, milliseconds */ uint16 ctime; /* Creation time */ uint16 cdate; /* Creation date */ uint16 adate; /* Last access date */ uint16 starthi; /* High 16 bits of cluster in FAT32 */ uint16 time,date,start;/* time, date and first cluster */ uint32 size; /* file size (in bytes) */};/* New swap space */struct swap_header_v1 { char bootbits[1024]; /* Space for disklabel etc. */ unsigned int version; unsigned int last_page; unsigned int nr_badpages; unsigned int padding[125]; unsigned int badpages[1];};struct unixware_slice { unsigned short slice_type; unsigned short slice_flags; unsigned int start; unsigned int size;};struct bsd_disklabel { uchar d_magic[4]; uchar d_stuff1[4]; uchar d_typename[16]; /* type name, e.g. "eagle" */ uchar d_packname[16]; /* pack identifier */ uint32 d_secsize; /* # of bytes per sector */ uint32 d_nsectors; /* # of data sectors per track */ uint32 d_ntracks; /* # of tracks per cylinder */ uint32 d_ncylinders; /* # of data cylinders per unit */ uint32 d_secpercyl; /* # of data sectors per cylinder */ uint32 d_secperunit; /* # of data sectors per unit */ uchar d_stuff2[68]; uchar d_magic2[4]; /* the magic number (again) */ uint16 d_checksum; /* xor of data incl. partitions */ /* filesystem and partition information: */ uint16 d_npartitions; /* number of partitions in following */ uint32 d_bbsize; /* size of boot area at sn0, bytes */ uint32 d_sbsize; /* max size of fs superblock, bytes */ struct bsd_partition { /* the partition table */ uint32 p_size; /* number of sectors in partition */ uint32 p_offset; /* starting sector */ uchar p_stuff[8]; } d_partitions[16]; /* 16 is for openbsd */};intmain(int argc, char **argv){ int i,j,fd; long size; int pagesize, pagesecs; unsigned char *bp; struct ext2_super_block *e2bp; struct fat16_boot_sector *fat16bs; struct fat32_boot_sector *fat32bs; progname = argv[0]; if (argc != 2) { fprintf(stderr, "call: %s device\n", progname); exit(1); } device = argv[1]; fd = open(device, O_RDONLY); if (fd < 0) { perror(device); fprintf(stderr, "%s: could not open %s\n", progname, device); exit(1); } if (ioctl(fd, BLKGETSIZE, &size)) { struct stat s; perror("BLKGETSIZE"); fprintf(stderr, "%s: could not get device size\n", progname); if (stat(device, &s)) { fprintf(stderr, "and also stat fails. Aborting.\n"); exit(1); } size = s.st_size / 512; } pagesize = getpagesize(); if (pagesize <= 0) pagesize = 4096; else if (pagesize > MAXPAGESZ) { fprintf(stderr, "%s: ridiculous pagesize %d\n", progname, pagesize); exit(1); } pagesecs = pagesize/512; printf("# partition table of %s\n", device); printf("# total size %d sectors\n", size); printf("unit: sectors\n"); for(i=0; i<size; i++) { if (i/BUFSECS != bufstart) { int len, secno; bufstart = i/BUFSECS; secno = bufstart*BUFSECS; len = BUFSECS; if (size - secno < len) len = size - secno; len = (len / 2)*2; /* avoid reading the last (odd) sector */ read_sectors(fd, buf, secno, len); } j = i % BUFSECS; bp = buf + 512 * j; if (bp[510] == 0x55 && bp[511] == 0xAA) { char *cp = bp+512-2-64; int j; if (i==0) continue; /* the MBR is supposed to be broken */ /* Unfortunately one finds extended partition table sectors that look just like a fat boot sector, except that the partition table bytes have been overwritten */ /* typical FAT32 end: "nd then press ...", followed by IO.SYS and MSDOS.SYS and WINBOOT.SYS directory entries. typical extd part tab end: 2 entries, 32 nul bytes */ for(j=0; j<32; j++) if (cp[32+j]) goto nonzero; addepts(i, bp); if (i > 0) { j = create_extended_partition(fd, i, size); if (j && j > i) i = j; /* skip */ } continue; nonzero: fat16bs = (struct fat16_boot_sector *) bp; if (fat16bs->s.media == 0xf8 && fat16bs->m.extd_signature == 0x29 && !strncmp(fat16bs->m.fs_name, "FAT", 3)) { int lth; lth = fat16bs->s.sectors[0] + fat16bs->s.sectors[1]*256; if (lth) { outmsg("small fat partition", i, i+lth, 0x1); addpart(i, lth, 0x1); } else { lth = fat16bs->s.total_sect; outmsg("fat partition", i, i+lth, 0x6); addpart(i, lth, 0x6); } i = i+lth-1; /* skip */ continue; } fat32bs = (struct fat32_boot_sector *) bp; if (fat32bs->s.media == 0xf8 && fat32bs->m.extd_signature == 0x29 && !strncmp(fat32bs->m.fs_name, "FAT32 ", 8)) { int lth = fat32bs->s.total_sect; outmsg("fat32 partition", i, i+lth, 0xb); /* or 0xc */ addpart(i, lth, 0xb); i = i+lth-1; /* skip */ continue; } } if (!strncmp(bp+502, "SWAP-SPACE", 10)) { char *last; int ct; int ss = i-pagesecs+1; int es; char buf2[MAXPAGESZ]; read_sectors(fd, buf2, ss, pagesecs); for (last = buf2+pagesize-10-1; last > buf2; last--) if (*last) break; for (ct = 7; ct >= 0; ct--) if (*last & (1<<ct)) break; es = ((last - buf2)*8 + ct + 1)*pagesecs + ss; if (es <= size) { outmsg("old swap space", ss, es, 0x82); addpart(ss, es-ss, 0x82); i = es-1; /* skip */ continue; } } if (!strncmp(bp+502, "SWAPSPACE2", 10)) { int ss = i-pagesecs+1; int es, lth; char buf2[MAXPAGESZ]; struct swap_header_v1 *p; read_sectors(fd, buf2, ss, pagesecs); p = (struct swap_header_v1 *) buf2; lth = (p->last_page + 1)* pagesecs; es = ss + lth; if (es <= size) { outmsg("new swap space", ss, es, 0x82); addpart(ss, lth, 0x82); i = es-1; /* skip */ continue; } } e2bp = (struct ext2_super_block *) bp; if (e2bp->s_magic == EXT2_SUPER_MAGIC && is_time(e2bp->s_mtime) && is_time(e2bp->s_wtime) && is_ztime(e2bp->s_lastcheck) && e2bp->s_log_block_size <= 10 /* at most 1 MB blocks */) { char buf[512]; struct ext2_super_block *bp2; int ss, sz, es, gsz, j; ss = i-2; sz = (e2bp->s_blocks_count << (e2bp->s_log_block_size + 1)); gsz = (e2bp->s_blocks_per_group << (e2bp->s_log_block_size + 1)); if (e2bp->s_block_group_nr > 0) ss -= gsz * e2bp->s_block_group_nr; es = ss + sz; if (ss > 0 && es > i && es <= size) { if (e2bp->s_block_group_nr == 0) { outmsg("ext2 partition", ss, es, 0x83); addpart(ss, es-ss, 0x83); i = es-1; /* skip */ continue; } /* maybe we jumped into the middle of a partially obliterated ext2 partition? */ printf("# sector %d looks like an ext2 superblock copy #%d;\n" "# in a partition covering sectors %d-%d\n", i, e2bp->s_block_group_nr, ss, es-1); for (j=1; j<=e2bp->s_block_group_nr; j++) { read_sectors(fd, buf, i-j*gsz, 1); bp2 = (struct ext2_super_block *) buf; if (bp2->s_magic != EXT2_SUPER_MAGIC || bp2->s_block_group_nr != e2bp->s_block_group_nr - j) break; } if (j == 1) printf("# however, sector %d doesnt look like a sb.\n", i-gsz); else if (j <= e2bp->s_block_group_nr) printf("# also the preceding %d block groups seem OK\n" "# but before that things seem to be wrong.\n", j-1); else { printf("# found all preceding superblocks OK\n" "# Warning: overlapping partitions?\n"); outmsg("ext2 partition", ss, es, 0x83); addpart(ss, es-ss, 0x83); i = es-1; /* skip */ continue; } } } if (bp[4] == 0x0d && bp[5] == 0x60 && bp[6] == 0x5e && bp[7] == 0xca && /* CA5E600D */ bp[156] == 0xee && bp[157] == 0xde && bp[158] == 0x0d && bp[159] == 0x60) /* 600DDEEE */ { int ss, es; struct unixware_slice *u; printf("# Unixware partition seen\n"); u = (struct unixware_slice *)(bp + 216); if (u->slice_type == 5 /* entire disk */ && (u->slice_flags & 0x200)) /* valid */ { ss = u->start; es = u->start + u->size; outmsg("Unixware ptn", ss, es, 0x63); addpart(ss, es-ss, 0x63); i = es-1; continue; } else printf("# Unrecognized details\n"); } /* bsd disk magic 0x82564557UL */ if (bp[0] == 0x57 && bp[1] == 0x45 && bp[2] == 0x56 && bp[3] == 0x82) { int ss, es, npts, j; struct bsd_disklabel *l; struct bsd_partition *p; printf("# BSD magic seen in sector %d\n", i); l = (struct bsd_disklabel *) bp; if (l->d_magic2[0] != 0x57 || l->d_magic2[1] != 0x45 || l->d_magic2[2] != 0x56 || l->d_magic2[3] != 0x82) printf("# 2nd magic bad - ignored this sector\n"); else if ((npts = l->d_npartitions) > 16) printf("# strange number (%d) of subpartitions - " "ignored this sector\n", npts); else { for (j=0; j<npts; j++) { p = &(l->d_partitions[j]); if (p->p_size) printf("# part %c: size %9d, start %9d\n", 'a'+j, p->p_size, p->p_offset); } ss = l->d_partitions[2].p_offset; es = ss + l->d_partitions[2].p_size; if (ss != i-1) printf("# strange start of whole disk - " "ignored this sector\n"); else { /* FreeBSD 0xa5, OpenBSD 0xa6, NetBSD 0xa9, BSDI 0xb7 */ /* How to distinguish? */ outmsg("BSD partition", ss, es, 0xa5); addpart(ss, es-ss, 0xa5); i = es-1; continue; } } } } outparts(); exit(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -