amfi_utils.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. //
  2. // amfi_utils.c
  3. // electra
  4. //
  5. // Created by Jamie on 27/01/2018.
  6. // Copyright © 2018 Electra Team. All rights reserved.
  7. //
  8. #include "amfi_utils.h"
  9. #include "kutils.h"
  10. #include "kmem.h"
  11. #include "patchfinder64.h"
  12. #include <stdlib.h>
  13. #include <mach-o/loader.h>
  14. #include <CommonCrypto/CommonDigest.h>
  15. uint32_t swap_uint32_electra( uint32_t val ) {
  16. val = ((val << 8) & 0xFF00FF00 ) | ((val >> 8) & 0xFF00FF );
  17. return (val << 16) | (val >> 16);
  18. }
  19. void getSHA256inplace(const uint8_t* code_dir, uint8_t *out) {
  20. if (code_dir == NULL) {
  21. printf("NULL passed to getSHA256inplace!\n");
  22. return;
  23. }
  24. uint32_t* code_dir_int = (uint32_t*)code_dir;
  25. uint32_t realsize = 0;
  26. for (int j = 0; j < 10; j++) {
  27. if (swap_uint32_electra(code_dir_int[j]) == 0xfade0c02) {
  28. realsize = swap_uint32_electra(code_dir_int[j+1]);
  29. code_dir += 4*j;
  30. }
  31. }
  32. CC_SHA256(code_dir, realsize, out);
  33. }
  34. uint8_t *getSHA256(const uint8_t* code_dir) {
  35. uint8_t *out = malloc(CC_SHA256_DIGEST_LENGTH);
  36. getSHA256inplace(code_dir, out);
  37. return out;
  38. }
  39. uint8_t *getCodeDirectory(const char* name) {
  40. // Assuming it is a macho
  41. FILE* fd = fopen(name, "r");
  42. uint32_t magic;
  43. fread(&magic, sizeof(magic), 1, fd);
  44. fseek(fd, 0, SEEK_SET);
  45. long off;
  46. int ncmds;
  47. if (magic == MH_MAGIC_64) {
  48. struct mach_header_64 mh64;
  49. fread(&mh64, sizeof(mh64), 1, fd);
  50. off = sizeof(mh64);
  51. ncmds = mh64.ncmds;
  52. } else if (magic == MH_MAGIC) {
  53. struct mach_header mh;
  54. fread(&mh, sizeof(mh), 1, fd);
  55. off = sizeof(mh);
  56. ncmds = mh.ncmds;
  57. } else {
  58. printf("%s is not a macho! (or has foreign endianness?) (magic: %x)\n", name, magic);
  59. return NULL;
  60. }
  61. for (int i = 0; i < ncmds; i++) {
  62. struct load_command cmd;
  63. fseek(fd, off, SEEK_SET);
  64. fread(&cmd, sizeof(struct load_command), 1, fd);
  65. if (cmd.cmd == LC_CODE_SIGNATURE) {
  66. uint32_t off_cs;
  67. fread(&off_cs, sizeof(uint32_t), 1, fd);
  68. uint32_t size_cs;
  69. fread(&size_cs, sizeof(uint32_t), 1, fd);
  70. uint8_t *cd = malloc(size_cs);
  71. fseek(fd, off_cs, SEEK_SET);
  72. fread(cd, size_cs, 1, fd);
  73. return cd;
  74. } else {
  75. off += cmd.cmdsize;
  76. }
  77. }
  78. return NULL;
  79. }
  80. void inject_trusts(int pathc, const char *paths[]) {
  81. static uint64_t tc = 0;
  82. if (tc == 0) tc = find_trustcache_electra();
  83. struct trust_chain fake_chain;
  84. fake_chain.next = rk64_electra(tc);
  85. *(uint64_t *)&fake_chain.uuid[0] = 0xabadbabeabadbabe;
  86. *(uint64_t *)&fake_chain.uuid[8] = 0xabadbabeabadbabe;
  87. int cnt = 0;
  88. uint8_t hash[CC_SHA256_DIGEST_LENGTH];
  89. hash_t *allhash = malloc(sizeof(hash_t) * pathc);
  90. for (int i = 0; i != pathc; ++i) {
  91. uint8_t *cd = getCodeDirectory(paths[i]);
  92. if (cd != NULL) {
  93. getSHA256inplace(cd, hash);
  94. memmove(allhash[cnt], hash, sizeof(hash_t));
  95. ++cnt;
  96. }
  97. }
  98. fake_chain.count = cnt;
  99. size_t length = (sizeof(fake_chain) + cnt * sizeof(hash_t) + 0xFFFF) & ~0xFFFF;
  100. uint64_t kernel_trust = kalloc(length);
  101. kwrite_electra(kernel_trust, &fake_chain, sizeof(fake_chain));
  102. kwrite_electra(kernel_trust + sizeof(fake_chain), allhash, cnt * sizeof(hash_t));
  103. wk64_electra(tc, kernel_trust);
  104. }