123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- //
- // amfi_utils.c
- // electra
- //
- // Created by Jamie on 27/01/2018.
- // Copyright © 2018 Electra Team. All rights reserved.
- //
- #include "amfi_utils.h"
- #include "kutils.h"
- #include "kmem.h"
- #include "patchfinder64.h"
- #include <stdlib.h>
- #include <mach-o/loader.h>
- #include <CommonCrypto/CommonDigest.h>
- uint32_t swap_uint32_electra( uint32_t val ) {
- val = ((val << 8) & 0xFF00FF00 ) | ((val >> 8) & 0xFF00FF );
- return (val << 16) | (val >> 16);
- }
- void getSHA256inplace(const uint8_t* code_dir, uint8_t *out) {
- if (code_dir == NULL) {
- printf("NULL passed to getSHA256inplace!\n");
- return;
- }
- uint32_t* code_dir_int = (uint32_t*)code_dir;
-
- uint32_t realsize = 0;
- for (int j = 0; j < 10; j++) {
- if (swap_uint32_electra(code_dir_int[j]) == 0xfade0c02) {
- realsize = swap_uint32_electra(code_dir_int[j+1]);
- code_dir += 4*j;
- }
- }
-
- CC_SHA256(code_dir, realsize, out);
- }
- uint8_t *getSHA256(const uint8_t* code_dir) {
- uint8_t *out = malloc(CC_SHA256_DIGEST_LENGTH);
- getSHA256inplace(code_dir, out);
- return out;
- }
- uint8_t *getCodeDirectory(const char* name) {
- // Assuming it is a macho
-
- FILE* fd = fopen(name, "r");
-
- uint32_t magic;
- fread(&magic, sizeof(magic), 1, fd);
- fseek(fd, 0, SEEK_SET);
-
- long off;
- int ncmds;
-
- if (magic == MH_MAGIC_64) {
- struct mach_header_64 mh64;
- fread(&mh64, sizeof(mh64), 1, fd);
- off = sizeof(mh64);
- ncmds = mh64.ncmds;
- } else if (magic == MH_MAGIC) {
- struct mach_header mh;
- fread(&mh, sizeof(mh), 1, fd);
- off = sizeof(mh);
- ncmds = mh.ncmds;
- } else {
- printf("%s is not a macho! (or has foreign endianness?) (magic: %x)\n", name, magic);
- return NULL;
- }
-
- for (int i = 0; i < ncmds; i++) {
- struct load_command cmd;
- fseek(fd, off, SEEK_SET);
- fread(&cmd, sizeof(struct load_command), 1, fd);
- if (cmd.cmd == LC_CODE_SIGNATURE) {
- uint32_t off_cs;
- fread(&off_cs, sizeof(uint32_t), 1, fd);
- uint32_t size_cs;
- fread(&size_cs, sizeof(uint32_t), 1, fd);
-
- uint8_t *cd = malloc(size_cs);
- fseek(fd, off_cs, SEEK_SET);
- fread(cd, size_cs, 1, fd);
- return cd;
- } else {
- off += cmd.cmdsize;
- }
- }
- return NULL;
- }
- void inject_trusts(int pathc, const char *paths[]) {
- static uint64_t tc = 0;
- if (tc == 0) tc = find_trustcache_electra();
-
- struct trust_chain fake_chain;
- fake_chain.next = rk64_electra(tc);
- *(uint64_t *)&fake_chain.uuid[0] = 0xabadbabeabadbabe;
- *(uint64_t *)&fake_chain.uuid[8] = 0xabadbabeabadbabe;
-
- int cnt = 0;
- uint8_t hash[CC_SHA256_DIGEST_LENGTH];
- hash_t *allhash = malloc(sizeof(hash_t) * pathc);
- for (int i = 0; i != pathc; ++i) {
- uint8_t *cd = getCodeDirectory(paths[i]);
- if (cd != NULL) {
- getSHA256inplace(cd, hash);
- memmove(allhash[cnt], hash, sizeof(hash_t));
- ++cnt;
- }
- }
-
- fake_chain.count = cnt;
-
- size_t length = (sizeof(fake_chain) + cnt * sizeof(hash_t) + 0xFFFF) & ~0xFFFF;
- uint64_t kernel_trust = kalloc(length);
-
- kwrite_electra(kernel_trust, &fake_chain, sizeof(fake_chain));
- kwrite_electra(kernel_trust + sizeof(fake_chain), allhash, cnt * sizeof(hash_t));
- wk64_electra(tc, kernel_trust);
- }
|