amfi_utils.h 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. //
  2. // amfi_utils.h
  3. // electra
  4. //
  5. // Created by Jamie on 27/01/2018.
  6. // Copyright © 2018 Electra Team. All rights reserved.
  7. //
  8. #ifndef amfi_utils_h
  9. #define amfi_utils_h
  10. #import <sys/types.h>
  11. #include <stdio.h>
  12. #include <objc/runtime.h>
  13. void getSHA256inplace(const uint8_t* code_dir, uint8_t *out);
  14. uint8_t *getSHA256(const uint8_t* code_dir);
  15. uint8_t *getCodeDirectory(const char* name);
  16. // thx hieplpvip
  17. void inject_trusts(int pathc, const char *paths[]);
  18. // Trust cache types
  19. typedef char hash_t[20];
  20. struct trust_chain {
  21. uint64_t next;
  22. unsigned char uuid[16];
  23. unsigned int count;
  24. } __attribute__((packed));
  25. /*
  26. Note this patch still came from @xerub's KPPless branch, but detailed below is kind of my adventures which I rediscovered most of what he did
  27. So, as said on twitter by @Morpheus______, iOS 11 now uses SHA256 for code signatures, rather than SHA1 like before.
  28. What confuses me though is that I believe the overall CDHash is SHA1, but each subhash is SHA256. In AMFI.kext, the memcmp
  29. used to check between the current hash and the hashes in the cache seem to be this CDHash. So the question is do I really need
  30. to get every hash, or just the main CDHash and insert that one into the trust chain?
  31. If we look at the trust chain code checker (0xFFFFFFF00637B3E8 6+ 11.1.2), it is pretty basic. The trust chain is in the format of
  32. the following (struct from xerub, but I've checked with AMFI that it is the case):
  33. struct trust_mem {
  34. uint64_t next; // +0x00 - the next struct trust_mem
  35. unsigned char uuid[16]; // +0x08 - The uuid of the trust_mem (it doesn't seem important or checked apart from when importing a new trust chain)
  36. unsigned int count; // +0x18 - Number of hashes there are
  37. unsigned char hashes[]; // +0x1C - The hashes
  38. }
  39. The trust chain checker does the following:
  40. - Find the first struct that has a count > 0
  41. - Loop through all the hashes in the struct, comparing with the current hash
  42. - Keeps going through each chain, then when next is 0, it finishes
  43. UPDATE: a) was using an old version of JTool. Now I realised the CDHash is SHA256
  44. b) For launchd (whose hash resides in the AMFI cache), the first byte is used as an index sort of thing, and the next *19* bytes are used for the check
  45. This probably means that only the first 20 bytes of the CDHash are used in the trust cache check
  46. So our execution method is as follows:
  47. - Calculate the CD Hashes for the target resources that we want to play around with
  48. - Create a custom trust chain struct, and insert it into the existing trust chain - only storing the first 20 bytes of each hash
  49. - ??? PROFIT
  50. */
  51. #endif /* amfi_utils_h */