Last active
February 6, 2018 15:24
-
-
Save przemoc/571086 to your computer and use it in GitHub Desktop.
This file contains 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
/* SPDX-License-Identifier: MIT */ | |
/* | |
* Copyright (C) 2009 Przemyslaw Pawelczyk <przemoc@gmail.com> | |
* | |
***** Description ************************************************************ | |
* | |
* Simple (and incomplete) syscalls interposition for accessing fixed-size Sun | |
* xVM VirtualBox Virtual Disk Images (.vdi files), especially using sfdisk. | |
* | |
***** License **************************************************************** | |
* | |
* MIT License | |
* | |
***** Tested on ************************************************************** | |
* | |
* - Debian 5.0.3 (x64) w/ util-linux 2.13.1.1-1 | |
* - Slackware 12.1 w/ util-linux-ng 2.13.1 | |
* - Ubuntu 8.10 (x64) w/ util-linux-ng 2.14 | |
* - Ubuntu 9.10 (x64) w/ util-linux-ng 2.16 | |
* | |
***** Compilation ************************************************************ | |
* | |
* $ gcc -fPIC -c -o vdiwrap.o vdiwrap.c && | |
* gcc -nostdlib -shared -ldl -o vdiwrap.so vdiwrap.o | |
* | |
***** Usage ****************************************************************** | |
* | |
* # LD_PRELOAD="./vdiwrap.so" sfdisk -qluS image.vdi | |
* | |
****************************************************************************** | |
* | |
* vdiwrap.c @ https://gist.github.com/przemoc/571086 (version 0.2b) | |
* | |
*/ | |
#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; | |
} |
Author
przemoc
commented
Feb 6, 2018
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment