Initial de-grub-ization of r_fs. DOS partition parser

- Implement simple LGPLd DOS partition parser
This commit is contained in:
pancake 2015-01-28 04:20:10 +01:00
parent c544b803f7
commit 5064a640fa
3 changed files with 110 additions and 19 deletions

View File

@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2011-2013 - pancake */
/* radare2 - LGPL - Copyright 2011-2015 - pancake */
#include <r_fs.h>
#include "../config.h"
@ -6,8 +6,8 @@
#include <errno.h>
#include "../../shlr/grub/include/grub/msdos_partition.h"
#ifndef DISABLE_GRUB
#define DISABLE_GRUB 0
#ifndef USE_GRUB
#define USE_GRUB 1
#endif
R_LIB_VERSION(r_fs);
@ -398,20 +398,34 @@ R_API RFSFile *r_fs_slurp(RFS* fs, const char *path) {
// TODO: move into grubfs
#include "../../shlr/grub/include/grubfs.h"
RList *list = NULL;
#if !DISABLE_GRUB
static int parhook (struct grub_disk *disk, struct grub_partition *par, void *closure) {
RFSPartition *p = r_fs_partition_new (r_list_length (list), par->start*512, 512*par->len);
#if USE_GRUB
static int grub_parhook (void *disk, struct grub_partition *par, void *closure) {
RList *list = (RList*)closure;
RFSPartition *p = r_fs_partition_new (
r_list_length (list),
par->start*512, 512*par->len);
p->type = par->msdostype;
r_list_append (list, p);
return 0;
}
#endif
static int fs_parhook (void *disk, void *ptr, void *closure) {
RFSPartition *par = ptr;
RList *list = (RList*)closure;
r_list_append (list, par);
return 0;
}
#include "p/part_dos.c"
static RFSPartitionType partitions[] = {
#if !DISABLE_GRUB
{ "msdos", &grub_msdos_partition_map },
/* LGPL code */
{ "dos", &fs_part_dos, fs_parhook },
#if USE_GRUB
/* WARNING GPL code */
{ "msdos", (void*)&grub_msdos_partition_map, (void*)grub_parhook },
{ "apple", &grub_apple_partition_map },
{ "sun", &grub_sun_partition_map },
{ "sunpc", &grub_sun_pc_partition_map },
@ -437,22 +451,31 @@ R_API int r_fs_partition_get_size () {
}
R_API RList *r_fs_partitions (RFS *fs, const char *ptype, ut64 delta) {
int i;
struct grub_partition_map *gpm = NULL;
int i, cur = -1;
for (i=0; partitions[i].name; i++) {
if (!strcmp (ptype, partitions[i].name)) {
gpm = partitions[i].ptr;
cur = i;
break;
}
}
if (gpm) {
list = r_list_new ();
if (cur != -1) {
void *disk = NULL;
RList *list = r_list_new ();
list->free = (RListFree)r_fs_partition_free;
#if !DISABLE_GRUB
grubfs_bind_io (NULL, 0);
struct grub_disk *disk = grubfs_disk (&fs->iob);
gpm->iterate (disk, parhook, 0);
if (partitions[i].iterate == (void*)&grub_parhook) {
#if USE_GRUB
struct grub_partition_map *gpt = partitions[i].ptr;
grubfs_bind_io (NULL, 0);
disk = (void*)grubfs_disk (&fs->iob);
if (gpt) {
gpt->iterate (disk,
(void*)partitions[i].iterate, list);
}
#endif
} else {
RFSPartitionIterator iterate = partitions[i].ptr;
iterate (fs, partitions[i].iterate, list); //grub_parhook, list);
}
return list;
}
if (ptype && *ptype)

60
libr/fs/p/part_dos.c Normal file
View File

@ -0,0 +1,60 @@
/* radare2 - LGPL - Copyright 2015 - pancake */
/* XXX: maybe this should be implemented in RBin */
/* we need to extract the code section and get offset flags */
typedef struct {
ut8 flag; // 0x80 if active
ut8 start_head;
ut8 start_sector;
ut8 start_cylinder;
ut8 type;
ut8 end_head;
ut8 end_sector;
ut8 end_cylinder;
ut32 start; // sector count (starting from 0)
ut32 length; // in sector
} __attribute__ ((packed)) DOS_ENTRY;
typedef struct {
ut8 code[446]; // code
DOS_ENTRY entries[4];
ut16 aa55; // the signature
} __attribute__ ((packed)) MBR;
static int fs_part_dos(void *disk, void *ptr, void *closure) {
int i;
MBR mbr;
RFS *fs = (RFS*)disk;
RFSPartition *par = NULL;
RFSPartitionIterator iterate = (RFSPartitionIterator)ptr;
RList *list = (RList*)closure;
memset (&mbr, 0, sizeof (mbr));
fs->iob.read_at (fs->iob.io, 0, (ut8*)&mbr, sizeof (mbr));
if (mbr.aa55 != 0xaa55) {
eprintf ("Invalid DOS signature at 0x%x\n",
(int)r_offsetof (MBR, aa55));
return 0;
}
for (i=0; i<4; i++) {
ut64 addr, aend;
DOS_ENTRY *e = &mbr.entries[i];
if (e->type != 0) {
//int is_active = (e->flag == 0x80);
addr = e->start;
addr *= 512;
aend = 0; //e->start;
aend += e->length;
aend *= 512;
par = r_fs_partition_new (i, addr, aend);
par->index = 0;
par->type = e->type;
iterate (disk, par, list);
} else {
// TODO: make deleted entries accessible?
}
}
return 0;
}

View File

@ -23,6 +23,11 @@ typedef struct r_fs_t {
void *ptr;
} RFS;
typedef struct r_fs_partition_plugin_t {
const char *name;
} RFSPartitionPlugin;
typedef struct r_fs_file_t {
char *name;
char *path;
@ -73,9 +78,12 @@ typedef struct r_fs_partition_t {
#define R_FS_FILE_TYPE_SPECIAL 's'
#define R_FS_FILE_TYPE_MOUNT 'm'
typedef int (*RFSPartitionIterator)(void *disk, void *ptr, void *user);
typedef struct r_fs_partition_type_t {
const char *name;
void *ptr;
void *ptr; // grub_msdos_partition_map
RFSPartitionIterator iterate;
//RFSPartitionIterator parhook;
} RFSPartitionType;
#define R_FS_PARTITIONS_LENGTH (int)(sizeof (partitions)/sizeof(RFSPartitionType)-1)