Virtual Box Disk Image Wrapper for sfdisk
From KnowWiki
The following script allows viewing properties of VirtualBox disks to mount them directly. Simple (and incomplete) syscalls interposition for accessing fixed-size Sun xVM VirtualBox Virtual Disk Images (.vdi files), especially using sfdisk.
Compile:
gcc -fPIC -c -o vdiwrap.o vdiwrap.c && gcc -nostdlib -shared -ldl -o vdiwrap.so vdiwrap.o
Use:
LD_PRELOAD="./vdiwrap.so" sfdisk -qluS image.vdi
/* * Copyright (C) 2009 Przemyslaw Pawelczyk <przemoc@gmail.com> * GNU General Public License v2, v3 */ #define _GNU_SOURCE #define _LARGEFILE64_SOURCE #include <dlfcn.h> #include <stdarg.h> #include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #define LOAD(name) orig_##name = dlsym(RTLD_NEXT, #name) #if __LP64__ # define N(name) name # define O(name) orig_##name # define OFF_T off_t # define STAT stat #else # define N(name) name ## 64 # define O(name) orig_##name ## 64 # define OFF_T off64_t # define STAT stat64 #endif #define OPEN_SIGNATURE const char *__file, int __oflag, ... #define LSEEK_SIGNATURE int __fd, OFF_T __offset, int __whence #define FXSTAT_SIGNATURE int __ver, int __fd, struct STAT *__stat_buf static int vdi_fd = -1; static int vdi_type = 0; static int vdi_offset = 0; static int (*O(open))(OPEN_SIGNATURE); static OFF_T (*O(lseek))(LSEEK_SIGNATURE); static int (*O(__fxstat))(FXSTAT_SIGNATURE); /* Functions' prototypes */ int N(open)(OPEN_SIGNATURE); OFF_T N(lseek)(LSEEK_SIGNATURE); int N(__fxstat)(FXSTAT_SIGNATURE); /* Initialization */ void _init() { LOAD(open); LOAD(lseek); LOAD(__fxstat); } /* Functions' bodies */ int N(open)(OPEN_SIGNATURE) { int result; int namelen; unsigned mode; va_list ap; if (__oflag & O_CREAT) { va_start(ap, __oflag); mode = va_arg(ap, unsigned); result = O(open)(__file, __oflag, mode); va_end(ap); return result; } result = O(open)(__file, __oflag); if (result > 0 && (namelen = strlen(__file)) && !strncasecmp(&__file[namelen - 4], ".vdi", 4)) { O(lseek)(result, 76, SEEK_SET); read(result, &vdi_type, 4); if (vdi_type == 2) { O(lseek)(result, 344, SEEK_SET); read(result, &vdi_offset, 4); O(lseek)(result, vdi_offset, SEEK_SET); vdi_fd = result; dprintf(STDERR_FILENO, "--- VDI data offset == %d bytes ---\n", vdi_offset); } else vdi_fd = -1; } return result; } OFF_T N(lseek)(LSEEK_SIGNATURE) { OFF_T result; if (__fd == vdi_fd && __whence == SEEK_SET) __offset += vdi_offset; result = O(lseek)(__fd, __offset, __whence); if (__fd == vdi_fd && result > 0) result -= vdi_offset; return result; } int N(__fxstat)(FXSTAT_SIGNATURE) { int result = O(__fxstat)(__ver, __fd, __stat_buf); if (__fd == vdi_fd && result == 0) __stat_buf->st_size -= vdi_offset; return result; }