/* * 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 **************************************************************** * * GNU General Public License v2, v3 * ***** 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 @ http://wiki.przemoc.net/snippets/c#vdiwrap.c (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; }
/* * This work is hereby released into the Public Domain. * ****************************************************************************** * * xor.c * */ #include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <stdlib.h> #include <sys/stat.h> #define XORBYTE (0x8dUL) #define XORINT (XORBYTE | (XORBYTE << 8) | (XORBYTE << 16) | (XORBYTE << 24)) #ifdef __LP64__ #define XORLONG ((XORINT) | ((XORINT) << 32)) #define LONG2 3 #else #define XORLONG XORINT #define LONG2 2 #endif #define BUFSIZE (2048 << 10) #ifdef WIN32 #define MODE (S_IRUSR | S_IWUSR) #else #define MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH) #define O_BINARY 0 #endif int main(int argc, char *argv[]) { unsigned long *buf; int i, r, fin, fout; fin = open(argv[1], O_RDONLY | O_BINARY); fout = open(argv[2], O_CREAT | O_WRONLY | O_TRUNC | O_BINARY, MODE); buf = malloc((BUFSIZE >> LONG2) * sizeof(long)); while ((r = read(fin, buf, BUFSIZE)) > 0) { for (i = 0; i < ((r + sizeof(long) - 1) >> LONG2); i++) buf[i] ^= XORLONG; write(fout, buf, r); } free(buf); close(fout); close(fin); return 0; }