Skip to content

Instantly share code, notes, and snippets.

@przemoc
Last active February 6, 2018 15:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save przemoc/571086 to your computer and use it in GitHub Desktop.
Save przemoc/571086 to your computer and use it in GitHub Desktop.
/* 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;
}
@przemoc
Copy link
Author

przemoc commented Feb 6, 2018

commit 64d29b98c6e7504bdcc1dac41e21a594761f53af
Author: Przemyslaw Pawelczyk <przemoc@gmail.com>
Date:   2018-02-06 16:08:20 +0100

    vdiwrap.c: Fix canonical location of the source file.

    My old wiki.przemoc.net is not available for many years.

commit 925aca5fc8fdf30effe84af8c6e817fd0e903329
Author: Przemyslaw Pawelczyk <przemoc@gmail.com>
Date:   2018-02-06 16:09:12 +0100

    vdiwrap.c: Relicense to MIT.

commit b6f0e15073b74a4d6b7f71229f8b1d3152bbf2b6
Author: Przemyslaw Pawelczyk <przemoc@gmail.com>
Date:   2018-02-06 16:22:48 +0100

    Add SPDX License Identifier.

    The Software Package Data Exchange (SPDX) is a good initiative, it has
    matured over time and deserves accelerated adoption in open-source.

    https://spdx.org/learn
    https://spdx.org/using-spdx
    https://spdx.org/license-list

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment