Advertisement
Guest User

Untitled

a guest
Sep 26th, 2021
637
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.20 KB | None | 0 0
  1. #include <assert.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4.  
  5. #include <unicorn/unicorn.h>
  6.  
  7. unsigned char buf[0x100000];
  8. FILE* binary;
  9.  
  10. uint64_t exgcd(uint64_t a, uint64_t b, uint64_t* x, uint64_t* y) {
  11.   if (b == 0) {
  12.     *x = 1;
  13.     *y = 0;
  14.     return a;
  15.   }
  16.   uint64_t r = exgcd(b, a % b, x, y);
  17.   uint64_t t = *y;
  18.   *y = *x - (a / b) * (*y);
  19.   *x = t;
  20.   return r;
  21. }
  22.  
  23. void do_emulation(FILE* fp,
  24.                   uint64_t start,
  25.                   uint64_t end,
  26.                   uint64_t r12,
  27.                   uint64_t r13,
  28.                   uint64_t* x,
  29.                   uint64_t* y) {
  30.   uc_engine* uc;
  31.   uint64_t size = end - start;
  32.   uint64_t rsp = 0x280000, rbp = 0x2c0000;
  33.  
  34.   assert(uc_open(UC_ARCH_X86, UC_MODE_64, &uc) == UC_ERR_OK);
  35.   assert(uc_mem_map(uc, 0x1000, 0x100000, UC_PROT_ALL) == UC_ERR_OK);
  36.   assert(uc_mem_map(uc, 0x200000, 0x100000, UC_PROT_ALL) == UC_ERR_OK);
  37.   assert(fseek(fp, start, SEEK_SET) == 0);
  38.   assert(fread(buf, size, 1, fp) == 1);
  39.   assert(uc_mem_write(uc, start, buf, size) == UC_ERR_OK);
  40.   assert(uc_reg_write(uc, UC_X86_REG_RSP, &rsp) == UC_ERR_OK);
  41.   assert(uc_reg_write(uc, UC_X86_REG_RBP, &rbp) == UC_ERR_OK);
  42.   assert(uc_reg_write(uc, UC_X86_REG_R12, &r12) == UC_ERR_OK);
  43.   assert(uc_reg_write(uc, UC_X86_REG_R13, &r13) == UC_ERR_OK);
  44.   assert(uc_emu_start(uc, start, end, 0, 0) == UC_ERR_OK);
  45.   assert(uc_reg_read(uc, UC_X86_REG_R12, x) == UC_ERR_OK);
  46.   assert(uc_reg_read(uc, UC_X86_REG_R13, y) == UC_ERR_OK);
  47.   uc_close(uc);
  48. }
  49.  
  50. void solve(uint64_t start,
  51.            uint64_t middle,
  52.            uint64_t end,
  53.            uint64_t x,
  54.            uint64_t y,
  55.            uint64_t* ox,
  56.            uint64_t* oy) {
  57.   uint64_t z, w, s, t;
  58.   uint32_t a, b;
  59.   do_emulation(binary, middle, end, x ^ y, 0, &z, &w);
  60.   do_emulation(binary, start, middle, 1, 0, &s, &t);
  61.   printf("z=%lx w=%lx s=%lx t=%lx\n", z, w, s, t);
  62.   b = (w ^ y) - t;
  63.   uint64_t m, n;
  64.   assert(exgcd(0x100000001, s, &m, &n) == 1);
  65.   a = ((x ^ w) * n) % 0x100000001;
  66.   if (n & (1UL << 63)) {
  67.     a -= 1;
  68.   }
  69.   printf("n=%lx a=%x b=%x\n", n, a, b);
  70.   *ox = a;
  71.   *oy = b;
  72. }
  73.  
  74. void decrypt(uint32_t xx, uint32_t yy, uint32_t* a, uint32_t* b) {
  75.   uint64_t x = xx, y = yy;
  76.   solve(0x83A25, 0x84C19, 0x92756, x, y, &x, &y);
  77.   solve(0x75467, 0x76695, 0x83A25, x, y, &x, &y);
  78.   solve(0x66ED9, 0x680D2, 0x75467, x, y, &x, &y);
  79.   solve(0x58191, 0x5938A, 0x66ED9, x, y, &x, &y);
  80.   solve(0x4949C, 0x4A68D, 0x58191, x, y, &x, &y);
  81.   solve(0x3AF70, 0x3C19B, 0x4949C, x, y, &x, &y);
  82.   solve(0x2CA30, 0x2DC24, 0x3AF70, x, y, &x, &y);
  83.   solve(0x1E4DE, 0x1F70E, 0x2CA30, x, y, &x, &y);
  84.   solve(0xF7AD, 0x109DB, 0x1E4DE, x, y, &x, &y);
  85.   solve(0x11F4, 0x241A, 0xF7AD, x, y, &x, &y);
  86.   *a = x;
  87.   *b = y;
  88. }
  89.  
  90. int main() {
  91.   uint32_t x[] = {0xc94dac3e, 0xb2d4f81d, 0xd9c808c2, 0x483a21f1,
  92.                   0x4e9d5687, 0xa3c64916, 0xa7459ba4, 0x6ff8306e};
  93.   uint32_t *a, *b;
  94.   char plain[33];
  95.   int i;
  96.   assert((binary = fopen("./chall", "rb")) != NULL);
  97.   for (i = 0; i < 4; i++) {
  98.     a = (uint32_t*)(plain + 8 * i + 4);
  99.     b = (uint32_t*)(plain + 8 * i);
  100.     decrypt(x[i * 2 + 1], x[i * 2], a, b);
  101.   }
  102.   fclose(binary);
  103.   plain[32] = '\0';
  104.   printf("flag{%s}\n", plain);
  105.   return 0;
  106. }
  107.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement