diff --git a/Exploits/fastPathSign/src/external/include/choma/CSBlob.h b/Exploits/fastPathSign/src/external/include/choma/CSBlob.h index f779929..0eee4d1 100644 --- a/Exploits/fastPathSign/src/external/include/choma/CSBlob.h +++ b/Exploits/fastPathSign/src/external/include/choma/CSBlob.h @@ -31,7 +31,7 @@ typedef struct __GenericBlob { } CS_GenericBlob; // CMS blob magic types -enum { +typedef enum { CSMAGIC_REQUIREMENT = 0xfade0c00, CSMAGIC_REQUIREMENTS = 0xfade0c01, CSMAGIC_CODEDIRECTORY = 0xfade0c02, @@ -44,7 +44,7 @@ enum { CSMAGIC_EMBEDDED_LAUNCH_CONSTRAINT = 0xfade8181, } CS_BlobMagic; -enum { +typedef enum { CSSLOT_CODEDIRECTORY = 0, CSSLOT_INFOSLOT = 1, CSSLOT_REQUIREMENTS = 2, @@ -90,8 +90,6 @@ CS_SuperBlob *macho_read_code_signature(MachO *macho); int macho_replace_code_signature(MachO *macho, CS_SuperBlob *superblob); -int update_load_commands(MachO *macho, CS_SuperBlob *superblob, uint64_t originalSize); - CS_DecodedBlob *csd_blob_init(uint32_t type, CS_GenericBlob *blobData); int csd_blob_read(CS_DecodedBlob *blob, uint64_t offset, size_t size, void *outBuf); int csd_blob_write(CS_DecodedBlob *blob, uint64_t offset, size_t size, const void *inBuf); @@ -104,6 +102,7 @@ uint32_t csd_blob_get_type(CS_DecodedBlob *blob); void csd_blob_set_type(CS_DecodedBlob *blob, uint32_t type); void csd_blob_free(CS_DecodedBlob *blob); +CS_DecodedSuperBlob *csd_superblob_init(void); CS_DecodedSuperBlob *csd_superblob_decode(CS_SuperBlob *superblob); CS_SuperBlob *csd_superblob_encode(CS_DecodedSuperBlob *decodedSuperblob); CS_DecodedBlob *csd_superblob_find_blob(CS_DecodedSuperBlob *superblob, uint32_t type, uint32_t *indexOut); diff --git a/Exploits/fastPathSign/src/external/include/choma/CodeDirectory.h b/Exploits/fastPathSign/src/external/include/choma/CodeDirectory.h index 66eb553..36cca20 100644 --- a/Exploits/fastPathSign/src/external/include/choma/CodeDirectory.h +++ b/Exploits/fastPathSign/src/external/include/choma/CodeDirectory.h @@ -12,7 +12,6 @@ #include "MachOLoadCommand.h" #include "MemoryStream.h" - // Code directory blob header typedef struct __CodeDirectory { uint32_t magic; @@ -26,12 +25,15 @@ typedef struct __CodeDirectory { uint32_t codeLimit; uint8_t hashSize; uint8_t hashType; - uint8_t spare1; + uint8_t platform; uint8_t pageSize; uint32_t spare2; + + /* Version 0x20100 */ uint32_t scatterOffset; uint32_t teamOffset; -} CS_CodeDirectory; +} CS_CodeDirectory +__attribute__ ((aligned(1))); enum CS_HashType { CS_HASHTYPE_SHA160_160 = 1, @@ -40,7 +42,7 @@ enum CS_HashType { CS_HASHTYPE_SHA384_384 = 4, }; -char *csd_code_directory_copy_identity(CS_DecodedBlob *codeDirBlob, uint32_t *offsetOut); +char *csd_code_directory_copy_identifier(CS_DecodedBlob *codeDirBlob, uint32_t *offsetOut); char *csd_code_directory_copy_team_id(CS_DecodedBlob *codeDirBlob, uint32_t *offsetOut); int csd_code_directory_set_team_id(CS_DecodedBlob *codeDirBlob, char *newTeamID); uint32_t csd_code_directory_get_flags(CS_DecodedBlob *codeDirBlob); diff --git a/Exploits/fastPathSign/src/external/include/choma/MachOByteOrder.h b/Exploits/fastPathSign/src/external/include/choma/MachOByteOrder.h index f1b0a7b..510df98 100644 --- a/Exploits/fastPathSign/src/external/include/choma/MachOByteOrder.h +++ b/Exploits/fastPathSign/src/external/include/choma/MachOByteOrder.h @@ -131,7 +131,7 @@ applier(cd, codeLimit); \ applier(cd, hashSize); \ applier(cd, hashType); \ - applier(cd, spare1); \ + applier(cd, platform); \ applier(cd, pageSize); \ applier(cd, spare2); \ applier(cd, scatterOffset); \ diff --git a/Exploits/fastPathSign/src/external/include/choma/MachOLoadCommand.h b/Exploits/fastPathSign/src/external/include/choma/MachOLoadCommand.h index d07ccbd..ae5514a 100644 --- a/Exploits/fastPathSign/src/external/include/choma/MachOLoadCommand.h +++ b/Exploits/fastPathSign/src/external/include/choma/MachOLoadCommand.h @@ -3,9 +3,9 @@ #include #include "MachO.h" -#include "CSBlob.h" #include "FileStream.h" #include "MachOByteOrder.h" +#include "CSBlob.h" // Convert load command to load command name char *load_command_to_string(int loadCommand); diff --git a/Exploits/fastPathSign/src/external/include/choma/MemoryStream.h b/Exploits/fastPathSign/src/external/include/choma/MemoryStream.h index b6326fb..ba00102 100644 --- a/Exploits/fastPathSign/src/external/include/choma/MemoryStream.h +++ b/Exploits/fastPathSign/src/external/include/choma/MemoryStream.h @@ -55,6 +55,6 @@ int memory_stream_expand(MemoryStream *stream, size_t expandAtStart, size_t expa void memory_stream_free(MemoryStream *stream); int memory_stream_copy_data(MemoryStream *originStream, uint64_t originOffset, MemoryStream *targetStream, uint64_t targetOffset, size_t size); -int memory_stream_find_memory(MemoryStream *stream, uint64_t searchOffset, size_t searchSize, void *bytes, void *mask, size_t nbytes, uint16_t alignment, uint64_t *foundOffsetOut); +int memory_stream_find_memory(MemoryStream *stream, uint64_t searchStartOffset, uint64_t searchEndOffset, void *bytes, void *mask, size_t nbytes, uint16_t alignment, uint64_t *foundOffsetOut); #endif // MEMORY_STREAM_H \ No newline at end of file diff --git a/Exploits/fastPathSign/src/external/include/choma/PatchFinder.h b/Exploits/fastPathSign/src/external/include/choma/PatchFinder.h index d15b0f4..84cc117 100644 --- a/Exploits/fastPathSign/src/external/include/choma/PatchFinder.h +++ b/Exploits/fastPathSign/src/external/include/choma/PatchFinder.h @@ -1,11 +1,16 @@ +#ifndef PATCHFINDER_H +#define PATCHFINDER_H + #include #include "MachO.h" -#define METRIC_TYPE_PATTERN 1 -#define METRIC_TYPE_STRING_XREF 2 -#define METRIC_TYPE_FUNCTION_XREF 3 +enum { + PF_METRIC_TYPE_PATTERN, + PF_METRIC_TYPE_STRING, + PF_METRIC_TYPE_XREF, +}; -typedef struct PFSection { +typedef struct s_PFSection { MachO *macho; uint64_t fileoff; uint64_t vmaddr; @@ -14,34 +19,57 @@ typedef struct PFSection { bool ownsCache; } PFSection; -PFSection *pf_section_init_from_macho(MachO *macho, const char *filesetEntryId, const char *segName, const char *sectName); -int pf_section_read_at_relative_offset(PFSection *section, uint64_t rel, size_t size, void *outBuf); -int pf_section_read_at_address(PFSection *section, uint64_t vmaddr, void *outBuf, size_t size); -uint32_t pf_section_read32(PFSection *section, uint64_t vmaddr); -int pf_section_set_cached(PFSection *section, bool cached); -void pf_section_free(PFSection *section); +PFSection *pfsec_init_from_macho(MachO *macho, const char *filesetEntryId, const char *segName, const char *sectName); +int pfsec_read_reloff(PFSection *section, uint64_t rel, size_t size, void *outBuf); +uint32_t pfsec_read32_reloff(PFSection *section, uint64_t rel); +int pfsec_read_at_address(PFSection *section, uint64_t vmaddr, void *outBuf, size_t size); +uint32_t pfsec_read32(PFSection *section, uint64_t vmaddr); +uint64_t pfsec_read64(PFSection *section, uint64_t vmaddr); +int pfsec_read_string(PFSection *section, uint64_t vmaddr, char **outString); +int pfsec_set_cached(PFSection *section, bool cached); +uint64_t pfsec_find_prev_inst(PFSection *section, uint64_t startAddr, uint32_t searchCount, uint32_t inst, uint32_t mask); +uint64_t pfsec_find_next_inst(PFSection *section, uint64_t startAddr, uint32_t searchCount, uint32_t inst, uint32_t mask); +uint64_t pfsec_find_function_start(PFSection *section, uint64_t midAddr); +void pfsec_free(PFSection *section); -typedef struct MetricShared { +typedef struct s_MetricShared { uint32_t type; } MetricShared; - -typedef enum { - BYTE_PATTERN_ALIGN_8_BIT, - BYTE_PATTERN_ALIGN_16_BIT, - BYTE_PATTERN_ALIGN_32_BIT, - BYTE_PATTERN_ALIGN_64_BIT, -} BytePatternAlignment; - -typedef struct BytePatternMetric { +typedef struct s_PFPatternMetric { MetricShared shared; void *bytes; void *mask; size_t nbytes; - BytePatternAlignment alignment; -} BytePatternMetric; + uint16_t alignment; +} PFPatternMetric; -BytePatternMetric *pf_create_byte_pattern_metric(void *bytes, void *mask, size_t nbytes, BytePatternAlignment alignment); -void pf_section_run_metric(PFSection *section, void *metric, void (^matchBlock)(uint64_t vmaddr, bool *stop)); +typedef struct s_PFStringMetric { + MetricShared shared; + + char *string; +} PFStringMetric; + +typedef enum { + XREF_TYPE_MASK_CALL = (1 << 0), + XREF_TYPE_MASK_REFERENCE = (1 << 1), + XREF_TYPE_MASK_ALL = (XREF_TYPE_MASK_CALL | XREF_TYPE_MASK_REFERENCE), +} PFXrefTypeMask; + +typedef struct s_PFXrefMetric { + MetricShared shared; + + uint64_t address; + PFXrefTypeMask typeMask; +} PFXrefMetric; + +PFPatternMetric *pfmetric_pattern_init(void *bytes, void *mask, size_t nbytes, uint16_t alignment); +PFStringMetric *pfmetric_string_init(const char *string); +PFXrefMetric *pfmetric_xref_init(uint64_t address, PFXrefTypeMask types); +void pfmetric_free(void *metric); + +void pfmetric_run_in_range(PFSection *section, uint64_t startAddr, uint64_t endAddr, void *metric, void (^matchBlock)(uint64_t vmaddr, bool *stop)); +void pfmetric_run(PFSection *section, void *metric, void (^matchBlock)(uint64_t vmaddr, bool *stop)); +#endif \ No newline at end of file diff --git a/Exploits/fastPathSign/src/external/include/choma/PatchFinder_arm64.h b/Exploits/fastPathSign/src/external/include/choma/PatchFinder_arm64.h new file mode 100644 index 0000000..c487bd6 --- /dev/null +++ b/Exploits/fastPathSign/src/external/include/choma/PatchFinder_arm64.h @@ -0,0 +1,33 @@ +#ifndef PATCHFINDER_ARM64_H +#define PATCHFINDER_ARM64_H + +#include "PatchFinder.h" + +typedef enum { + ARM64_XREF_TYPE_B = 0, + ARM64_XREF_TYPE_BL = 1, + ARM64_XREF_TYPE_ADR = 2, + ARM64_XREF_TYPE_ADRP_ADD = 3, + ARM64_XREF_TYPE_ADRP_LDR = 4, + ARM64_XREF_TYPE_ADRP_STR = 5, +} Arm64XrefType; + +typedef enum { + ARM64_XREF_TYPE_MASK_B = (1 << ARM64_XREF_TYPE_B), + ARM64_XREF_TYPE_MASK_BL = (1 << ARM64_XREF_TYPE_BL), + ARM64_XREF_TYPE_MASK_CALL = (ARM64_XREF_TYPE_MASK_B | ARM64_XREF_TYPE_MASK_BL), + + ARM64_XREF_TYPE_MASK_ADR = (1 << ARM64_XREF_TYPE_ADR), + ARM64_XREF_TYPE_MASK_ADRP_ADD = (1 << ARM64_XREF_TYPE_ADRP_ADD), + ARM64_XREF_TYPE_MASK_ADRP_LDR = (1 << ARM64_XREF_TYPE_ADRP_LDR), + ARM64_XREF_TYPE_MASK_ADRP_STR = (1 << ARM64_XREF_TYPE_ADRP_STR), + ARM64_XREF_TYPE_MASK_REFERENCE = (ARM64_XREF_TYPE_MASK_ADR | ARM64_XREF_TYPE_MASK_ADRP_ADD | ARM64_XREF_TYPE_MASK_ADRP_LDR | ARM64_XREF_TYPE_MASK_ADRP_STR), + + ARM64_XREF_TYPE_ALL = (ARM64_XREF_TYPE_MASK_CALL | ARM64_XREF_TYPE_MASK_REFERENCE), +} Arm64XrefTypeMask; + +uint64_t pfsec_arm64_resolve_adrp_ldr_str_add_reference(PFSection *section, uint64_t adrpAddr, uint64_t ldrStrAddAddr); +uint64_t pfsec_arm64_resolve_adrp_ldr_str_add_reference_auto(PFSection *section, uint64_t ldrStrAddAddr); +uint64_t pfsec_arm64_resolve_stub(PFSection *section, uint64_t stubAddr); +void pfsec_arm64_enumerate_xrefs(PFSection *section, Arm64XrefTypeMask types, void (^xrefBlock)(Arm64XrefType type, uint64_t source, uint64_t target, bool *stop)); +#endif \ No newline at end of file diff --git a/Exploits/fastPathSign/src/external/include/choma/SignOSSL.h b/Exploits/fastPathSign/src/external/include/choma/SignOSSL.h index 00afe5f..f1be620 100644 --- a/Exploits/fastPathSign/src/external/include/choma/SignOSSL.h +++ b/Exploits/fastPathSign/src/external/include/choma/SignOSSL.h @@ -1,6 +1,8 @@ #ifndef SIGN_OSSL_H #define SIGN_OSSL_H +#ifndef DISABLE_SIGNING + #include #include #include @@ -11,6 +13,8 @@ unsigned char *signWithRSA(unsigned char *inputData, size_t inputDataLength, unsigned char *key, size_t key_len, size_t *outputDataLength); +#endif + #endif // SIGN_OSSL_H // 0xA422 \ No newline at end of file diff --git a/Exploits/fastPathSign/src/external/include/choma/Util.h b/Exploits/fastPathSign/src/external/include/choma/Util.h index 4bbda41..e4ccf64 100644 --- a/Exploits/fastPathSign/src/external/include/choma/Util.h +++ b/Exploits/fastPathSign/src/external/include/choma/Util.h @@ -1,7 +1,34 @@ +#ifndef UTIL_H +#define UTIL_H + #include #include +#include +typedef struct s_optional_uint64 { + bool isSet; + uint64_t value; +} optional_uint64_t; +#define OPT_UINT64_IS_SET(x) (x.isSet) +#define OPT_UINT64_GET_VAL(x) (x.value) +#define OPT_UINT64_NONE (optional_uint64_t){.isSet = false, .value = 0} +#define OPT_UINT64(x) (optional_uint64_t){.isSet = true, .value = x} + + +typedef struct s_optional_bool { + bool isSet; + bool value; +} optional_bool; +#define OPT_BOOL_IS_SET(x) (x.isSet) +#define OPT_BOOL_GET_VAL(x) (x.value) +#define OPT_BOOL_NONE (optional_bool){.isSet = false, .value = false} +#define OPT_BOOL(x) (optional_bool){.isSet = true, .value = x} + +int64_t sxt64(int64_t value, uint8_t bits); int memcmp_masked(const void *str1, const void *str2, unsigned char* mask, size_t n); uint64_t align_to_size(int size, int alignment); int count_digits(int64_t num); -void print_hash(uint8_t *hash, size_t size); \ No newline at end of file +void print_hash(uint8_t *hash, size_t size); +void enumerate_range(uint64_t start, uint64_t end, uint16_t alignment, size_t nbytes, bool (^enumerator)(uint64_t cur)); + +#endif \ No newline at end of file diff --git a/Exploits/fastPathSign/src/external/include/choma/arm64.h b/Exploits/fastPathSign/src/external/include/choma/arm64.h new file mode 100644 index 0000000..9affc1d --- /dev/null +++ b/Exploits/fastPathSign/src/external/include/choma/arm64.h @@ -0,0 +1,94 @@ +#ifndef ARM64_H +#define ARM64_H + +#include "Util.h" + +typedef enum { + // registers + ARM64_REG_TYPE_X, + ARM64_REG_TYPE_W, + + // vector shit + ARM64_REG_TYPE_Q, + ARM64_REG_TYPE_D, + ARM64_REG_TYPE_S, + ARM64_REG_TYPE_H, + ARM64_REG_TYPE_B, +} arm64_register_type; + +enum { + ARM64_REG_MASK_ANY_FLAG = (1 << 0), + ARM64_REG_MASK_X_W = (1 << 1), + ARM64_REG_MASK_VECTOR = (1 << 2), + ARM64_REG_MASK_ALL = (ARM64_REG_MASK_X_W | ARM64_REG_MASK_VECTOR), + + ARM64_REG_MASK_ANY_X_W = (ARM64_REG_MASK_X_W | ARM64_REG_MASK_ANY_FLAG), + ARM64_REG_MASK_ANY_VECTOR = (ARM64_REG_MASK_VECTOR | ARM64_REG_MASK_ANY_FLAG), + ARM64_REG_MASK_ANY_ALL = (ARM64_REG_MASK_ALL | ARM64_REG_MASK_ANY_FLAG), +}; + +typedef enum { + LDR_STR_TYPE_ANY, // NOTE: "ANY" will inevitably also match STUR and LDUR instructions + LDR_STR_TYPE_POST_INDEX, + LDR_STR_TYPE_PRE_INDEX, + LDR_STR_TYPE_UNSIGNED, +} arm64_ldr_str_type; + +typedef struct s_arm64_register { + uint8_t mask; + arm64_register_type type; + uint8_t num; +} arm64_register; + +#define ARM64_REG(type_, num_) (arm64_register){.mask = ARM64_REG_MASK_ALL, .type = type_, .num = num_} +#define ARM64_REG_X(x) ARM64_REG(ARM64_REG_TYPE_X, x) +#define ARM64_REG_W(x) ARM64_REG(ARM64_REG_TYPE_W, x) +#define ARM64_REG_Q(x) ARM64_REG(ARM64_REG_TYPE_Q, x) +#define ARM64_REG_S(x) ARM64_REG(ARM64_REG_TYPE_S, x) +#define ARM64_REG_H(x) ARM64_REG(ARM64_REG_TYPE_H, x) +#define ARM64_REG_B(x) ARM64_REG(ARM64_REG_TYPE_B, x) +#define ARM64_REG_ANY (arm64_register){.mask = ARM64_REG_MASK_ANY_ALL, .type = 0, .num = 0} +#define ARM64_REG_ANY_X_W (arm64_register){.mask = ARM64_REG_MASK_ANY_X_W, .type = 0, .num = 0} +#define ARM64_REG_ANY_VECTOR (arm64_register){.mask = ARM64_REG_MASK_ANY_VECTOR, .type = 0, .num = 0} +#define ARM64_REG_GET_TYPE(x) (x.type) +#define ARM64_REG_IS_X(x) (x.type == ARM64_REG_TYPE_X) +#define ARM64_REG_IS_W(x) (x.type == ARM64_REG_TYPE_W) +#define ARM64_REG_IS_VECTOR(x) (x.type == ARM64_REG_TYPE_Q || x.type == ARM64_REG_TYPE_D || x.type == ARM64_REG_TYPE_S || x.type == ARM64_REG_TYPE_H || x.type == ARM64_REG_TYPE_B) +#define ARM64_REG_GET_NUM(x) (x.num & 0x1f) +#define ARM64_REG_IS_ANY(x) (x.mask == ARM64_REG_MASK_ANY_ALL) +#define ARM64_REG_IS_ANY_X_W(x) (x.mask == ARM64_REG_MASK_ANY_X_W) +#define ARM64_REG_IS_ANY_VECTOR(x) (x.mask == ARM64_REG_MASK_ANY_VECTOR) +uint8_t arm64_reg_type_get_width(arm64_register_type type); +const char *arm64_reg_type_get_string(arm64_register_type type); +const char *arm64_reg_get_type_string(arm64_register reg); + +#define ARM64_REG_NUM_SP 31 + +typedef struct s_arm64_cond { + bool isSet; + uint8_t value; +} arm64_cond; +#define ARM64_COND(x) (arm64_cond){.isSet = true, .value = x} +#define ARM64_COND_ANY (arm64_cond){.isSet = false, .value = 0} +#define ARM64_COND_GET_VAL(x) (x.value & 0xf) +#define ARM64_COND_IS_SET(x) x.isSet + +int arm64_gen_b_l(optional_bool optIsBl, optional_uint64_t optOrigin, optional_uint64_t optTarget, uint32_t *bytesOut, uint32_t *maskOut); +int arm64_dec_b_l(uint32_t inst, uint64_t origin, uint64_t *targetOut, bool *isBlOut); +int arm64_gen_b_c_cond(optional_bool optIsBc, optional_uint64_t optOrigin, optional_uint64_t optTarget, arm64_cond optCond, uint32_t *bytesOut, uint32_t *maskOut); +int arm64_dec_b_c_cond(uint32_t inst, uint64_t origin, uint64_t *targetOut, arm64_cond *condOut, bool *isBcOut); +int arm64_gen_adr_p(optional_bool optIsAdrp, optional_uint64_t optOrigin, optional_uint64_t optTarget, arm64_register reg, uint32_t *bytesOut, uint32_t *maskOut); +int arm64_dec_adr_p(uint32_t inst, uint64_t origin, uint64_t *targetOut, arm64_register *registerOut, bool *isAdrpOut); +int arm64_gen_mov_imm(char type, arm64_register destinationReg, optional_uint64_t optImm, optional_uint64_t optShift, uint32_t *bytesOut, uint32_t *maskOut); +int arm64_dec_mov_imm(uint32_t inst, arm64_register *destinationRegOut, uint64_t *immOut, uint64_t *shiftOut, char *typeOut); +int arm64_gen_add_imm(arm64_register destinationReg, arm64_register sourceReg, optional_uint64_t optImm, uint32_t *bytesOut, uint32_t *maskOut); +int arm64_dec_add_imm(uint32_t inst, arm64_register *destinationRegOut, arm64_register *sourceRegOut, uint16_t *immOut); +int arm64_gen_ldr_imm(char type, arm64_ldr_str_type instType, arm64_register destinationReg, arm64_register addrReg, optional_uint64_t optImm, uint32_t *bytesOut, uint32_t *maskOut); +int arm64_dec_ldr_imm(uint32_t inst, arm64_register *destinationReg, arm64_register *addrReg, uint64_t *immOut, char *typeOut, arm64_ldr_str_type *instTypeOut); +int arm64_gen_str_imm(char type, arm64_ldr_str_type instType, arm64_register sourceReg, arm64_register addrReg, optional_uint64_t optImm, uint32_t *bytesOut, uint32_t *maskOut); +int arm64_dec_str_imm(uint32_t inst, arm64_register *sourceRegOut, arm64_register *addrRegOut, uint64_t *immOut, char *typeOut, arm64_ldr_str_type *instTypeOut); +int arm64_gen_ldr_lit(arm64_register destinationReg, optional_uint64_t optImm, uint32_t *bytesOut, uint32_t *maskOut); +int arm64_dec_ldr_lit(uint32_t inst, arm64_register *destinationReg, int64_t *immOut); +int arm64_gen_cb_n_z(optional_bool isCbnz, arm64_register reg, optional_uint64_t optTarget, uint32_t *bytesOut, uint32_t *maskOut); +int arm64_dec_cb_n_z(uint32_t inst, uint64_t origin, bool *isCbnzOut, arm64_register *regOut, uint64_t *targetOut); +#endif \ No newline at end of file diff --git a/Exploits/fastPathSign/src/external/lib/libchoma.a b/Exploits/fastPathSign/src/external/lib/libchoma.a index e69e186..44849e3 100644 Binary files a/Exploits/fastPathSign/src/external/lib/libchoma.a and b/Exploits/fastPathSign/src/external/lib/libchoma.a differ diff --git a/RootHelper/external/include/choma/CSBlob.h b/RootHelper/external/include/choma/CSBlob.h index f779929..0eee4d1 100644 --- a/RootHelper/external/include/choma/CSBlob.h +++ b/RootHelper/external/include/choma/CSBlob.h @@ -31,7 +31,7 @@ typedef struct __GenericBlob { } CS_GenericBlob; // CMS blob magic types -enum { +typedef enum { CSMAGIC_REQUIREMENT = 0xfade0c00, CSMAGIC_REQUIREMENTS = 0xfade0c01, CSMAGIC_CODEDIRECTORY = 0xfade0c02, @@ -44,7 +44,7 @@ enum { CSMAGIC_EMBEDDED_LAUNCH_CONSTRAINT = 0xfade8181, } CS_BlobMagic; -enum { +typedef enum { CSSLOT_CODEDIRECTORY = 0, CSSLOT_INFOSLOT = 1, CSSLOT_REQUIREMENTS = 2, @@ -90,8 +90,6 @@ CS_SuperBlob *macho_read_code_signature(MachO *macho); int macho_replace_code_signature(MachO *macho, CS_SuperBlob *superblob); -int update_load_commands(MachO *macho, CS_SuperBlob *superblob, uint64_t originalSize); - CS_DecodedBlob *csd_blob_init(uint32_t type, CS_GenericBlob *blobData); int csd_blob_read(CS_DecodedBlob *blob, uint64_t offset, size_t size, void *outBuf); int csd_blob_write(CS_DecodedBlob *blob, uint64_t offset, size_t size, const void *inBuf); @@ -104,6 +102,7 @@ uint32_t csd_blob_get_type(CS_DecodedBlob *blob); void csd_blob_set_type(CS_DecodedBlob *blob, uint32_t type); void csd_blob_free(CS_DecodedBlob *blob); +CS_DecodedSuperBlob *csd_superblob_init(void); CS_DecodedSuperBlob *csd_superblob_decode(CS_SuperBlob *superblob); CS_SuperBlob *csd_superblob_encode(CS_DecodedSuperBlob *decodedSuperblob); CS_DecodedBlob *csd_superblob_find_blob(CS_DecodedSuperBlob *superblob, uint32_t type, uint32_t *indexOut); diff --git a/RootHelper/external/include/choma/CodeDirectory.h b/RootHelper/external/include/choma/CodeDirectory.h index 66eb553..36cca20 100644 --- a/RootHelper/external/include/choma/CodeDirectory.h +++ b/RootHelper/external/include/choma/CodeDirectory.h @@ -12,7 +12,6 @@ #include "MachOLoadCommand.h" #include "MemoryStream.h" - // Code directory blob header typedef struct __CodeDirectory { uint32_t magic; @@ -26,12 +25,15 @@ typedef struct __CodeDirectory { uint32_t codeLimit; uint8_t hashSize; uint8_t hashType; - uint8_t spare1; + uint8_t platform; uint8_t pageSize; uint32_t spare2; + + /* Version 0x20100 */ uint32_t scatterOffset; uint32_t teamOffset; -} CS_CodeDirectory; +} CS_CodeDirectory +__attribute__ ((aligned(1))); enum CS_HashType { CS_HASHTYPE_SHA160_160 = 1, @@ -40,7 +42,7 @@ enum CS_HashType { CS_HASHTYPE_SHA384_384 = 4, }; -char *csd_code_directory_copy_identity(CS_DecodedBlob *codeDirBlob, uint32_t *offsetOut); +char *csd_code_directory_copy_identifier(CS_DecodedBlob *codeDirBlob, uint32_t *offsetOut); char *csd_code_directory_copy_team_id(CS_DecodedBlob *codeDirBlob, uint32_t *offsetOut); int csd_code_directory_set_team_id(CS_DecodedBlob *codeDirBlob, char *newTeamID); uint32_t csd_code_directory_get_flags(CS_DecodedBlob *codeDirBlob); diff --git a/RootHelper/external/include/choma/MachOByteOrder.h b/RootHelper/external/include/choma/MachOByteOrder.h index f1b0a7b..510df98 100644 --- a/RootHelper/external/include/choma/MachOByteOrder.h +++ b/RootHelper/external/include/choma/MachOByteOrder.h @@ -131,7 +131,7 @@ applier(cd, codeLimit); \ applier(cd, hashSize); \ applier(cd, hashType); \ - applier(cd, spare1); \ + applier(cd, platform); \ applier(cd, pageSize); \ applier(cd, spare2); \ applier(cd, scatterOffset); \ diff --git a/RootHelper/external/include/choma/MachOLoadCommand.h b/RootHelper/external/include/choma/MachOLoadCommand.h index d07ccbd..ae5514a 100644 --- a/RootHelper/external/include/choma/MachOLoadCommand.h +++ b/RootHelper/external/include/choma/MachOLoadCommand.h @@ -3,9 +3,9 @@ #include #include "MachO.h" -#include "CSBlob.h" #include "FileStream.h" #include "MachOByteOrder.h" +#include "CSBlob.h" // Convert load command to load command name char *load_command_to_string(int loadCommand); diff --git a/RootHelper/external/include/choma/MemoryStream.h b/RootHelper/external/include/choma/MemoryStream.h index b6326fb..ba00102 100644 --- a/RootHelper/external/include/choma/MemoryStream.h +++ b/RootHelper/external/include/choma/MemoryStream.h @@ -55,6 +55,6 @@ int memory_stream_expand(MemoryStream *stream, size_t expandAtStart, size_t expa void memory_stream_free(MemoryStream *stream); int memory_stream_copy_data(MemoryStream *originStream, uint64_t originOffset, MemoryStream *targetStream, uint64_t targetOffset, size_t size); -int memory_stream_find_memory(MemoryStream *stream, uint64_t searchOffset, size_t searchSize, void *bytes, void *mask, size_t nbytes, uint16_t alignment, uint64_t *foundOffsetOut); +int memory_stream_find_memory(MemoryStream *stream, uint64_t searchStartOffset, uint64_t searchEndOffset, void *bytes, void *mask, size_t nbytes, uint16_t alignment, uint64_t *foundOffsetOut); #endif // MEMORY_STREAM_H \ No newline at end of file diff --git a/RootHelper/external/include/choma/PatchFinder.h b/RootHelper/external/include/choma/PatchFinder.h index d15b0f4..84cc117 100644 --- a/RootHelper/external/include/choma/PatchFinder.h +++ b/RootHelper/external/include/choma/PatchFinder.h @@ -1,11 +1,16 @@ +#ifndef PATCHFINDER_H +#define PATCHFINDER_H + #include #include "MachO.h" -#define METRIC_TYPE_PATTERN 1 -#define METRIC_TYPE_STRING_XREF 2 -#define METRIC_TYPE_FUNCTION_XREF 3 +enum { + PF_METRIC_TYPE_PATTERN, + PF_METRIC_TYPE_STRING, + PF_METRIC_TYPE_XREF, +}; -typedef struct PFSection { +typedef struct s_PFSection { MachO *macho; uint64_t fileoff; uint64_t vmaddr; @@ -14,34 +19,57 @@ typedef struct PFSection { bool ownsCache; } PFSection; -PFSection *pf_section_init_from_macho(MachO *macho, const char *filesetEntryId, const char *segName, const char *sectName); -int pf_section_read_at_relative_offset(PFSection *section, uint64_t rel, size_t size, void *outBuf); -int pf_section_read_at_address(PFSection *section, uint64_t vmaddr, void *outBuf, size_t size); -uint32_t pf_section_read32(PFSection *section, uint64_t vmaddr); -int pf_section_set_cached(PFSection *section, bool cached); -void pf_section_free(PFSection *section); +PFSection *pfsec_init_from_macho(MachO *macho, const char *filesetEntryId, const char *segName, const char *sectName); +int pfsec_read_reloff(PFSection *section, uint64_t rel, size_t size, void *outBuf); +uint32_t pfsec_read32_reloff(PFSection *section, uint64_t rel); +int pfsec_read_at_address(PFSection *section, uint64_t vmaddr, void *outBuf, size_t size); +uint32_t pfsec_read32(PFSection *section, uint64_t vmaddr); +uint64_t pfsec_read64(PFSection *section, uint64_t vmaddr); +int pfsec_read_string(PFSection *section, uint64_t vmaddr, char **outString); +int pfsec_set_cached(PFSection *section, bool cached); +uint64_t pfsec_find_prev_inst(PFSection *section, uint64_t startAddr, uint32_t searchCount, uint32_t inst, uint32_t mask); +uint64_t pfsec_find_next_inst(PFSection *section, uint64_t startAddr, uint32_t searchCount, uint32_t inst, uint32_t mask); +uint64_t pfsec_find_function_start(PFSection *section, uint64_t midAddr); +void pfsec_free(PFSection *section); -typedef struct MetricShared { +typedef struct s_MetricShared { uint32_t type; } MetricShared; - -typedef enum { - BYTE_PATTERN_ALIGN_8_BIT, - BYTE_PATTERN_ALIGN_16_BIT, - BYTE_PATTERN_ALIGN_32_BIT, - BYTE_PATTERN_ALIGN_64_BIT, -} BytePatternAlignment; - -typedef struct BytePatternMetric { +typedef struct s_PFPatternMetric { MetricShared shared; void *bytes; void *mask; size_t nbytes; - BytePatternAlignment alignment; -} BytePatternMetric; + uint16_t alignment; +} PFPatternMetric; -BytePatternMetric *pf_create_byte_pattern_metric(void *bytes, void *mask, size_t nbytes, BytePatternAlignment alignment); -void pf_section_run_metric(PFSection *section, void *metric, void (^matchBlock)(uint64_t vmaddr, bool *stop)); +typedef struct s_PFStringMetric { + MetricShared shared; + + char *string; +} PFStringMetric; + +typedef enum { + XREF_TYPE_MASK_CALL = (1 << 0), + XREF_TYPE_MASK_REFERENCE = (1 << 1), + XREF_TYPE_MASK_ALL = (XREF_TYPE_MASK_CALL | XREF_TYPE_MASK_REFERENCE), +} PFXrefTypeMask; + +typedef struct s_PFXrefMetric { + MetricShared shared; + + uint64_t address; + PFXrefTypeMask typeMask; +} PFXrefMetric; + +PFPatternMetric *pfmetric_pattern_init(void *bytes, void *mask, size_t nbytes, uint16_t alignment); +PFStringMetric *pfmetric_string_init(const char *string); +PFXrefMetric *pfmetric_xref_init(uint64_t address, PFXrefTypeMask types); +void pfmetric_free(void *metric); + +void pfmetric_run_in_range(PFSection *section, uint64_t startAddr, uint64_t endAddr, void *metric, void (^matchBlock)(uint64_t vmaddr, bool *stop)); +void pfmetric_run(PFSection *section, void *metric, void (^matchBlock)(uint64_t vmaddr, bool *stop)); +#endif \ No newline at end of file diff --git a/RootHelper/external/include/choma/PatchFinder_arm64.h b/RootHelper/external/include/choma/PatchFinder_arm64.h new file mode 100644 index 0000000..c487bd6 --- /dev/null +++ b/RootHelper/external/include/choma/PatchFinder_arm64.h @@ -0,0 +1,33 @@ +#ifndef PATCHFINDER_ARM64_H +#define PATCHFINDER_ARM64_H + +#include "PatchFinder.h" + +typedef enum { + ARM64_XREF_TYPE_B = 0, + ARM64_XREF_TYPE_BL = 1, + ARM64_XREF_TYPE_ADR = 2, + ARM64_XREF_TYPE_ADRP_ADD = 3, + ARM64_XREF_TYPE_ADRP_LDR = 4, + ARM64_XREF_TYPE_ADRP_STR = 5, +} Arm64XrefType; + +typedef enum { + ARM64_XREF_TYPE_MASK_B = (1 << ARM64_XREF_TYPE_B), + ARM64_XREF_TYPE_MASK_BL = (1 << ARM64_XREF_TYPE_BL), + ARM64_XREF_TYPE_MASK_CALL = (ARM64_XREF_TYPE_MASK_B | ARM64_XREF_TYPE_MASK_BL), + + ARM64_XREF_TYPE_MASK_ADR = (1 << ARM64_XREF_TYPE_ADR), + ARM64_XREF_TYPE_MASK_ADRP_ADD = (1 << ARM64_XREF_TYPE_ADRP_ADD), + ARM64_XREF_TYPE_MASK_ADRP_LDR = (1 << ARM64_XREF_TYPE_ADRP_LDR), + ARM64_XREF_TYPE_MASK_ADRP_STR = (1 << ARM64_XREF_TYPE_ADRP_STR), + ARM64_XREF_TYPE_MASK_REFERENCE = (ARM64_XREF_TYPE_MASK_ADR | ARM64_XREF_TYPE_MASK_ADRP_ADD | ARM64_XREF_TYPE_MASK_ADRP_LDR | ARM64_XREF_TYPE_MASK_ADRP_STR), + + ARM64_XREF_TYPE_ALL = (ARM64_XREF_TYPE_MASK_CALL | ARM64_XREF_TYPE_MASK_REFERENCE), +} Arm64XrefTypeMask; + +uint64_t pfsec_arm64_resolve_adrp_ldr_str_add_reference(PFSection *section, uint64_t adrpAddr, uint64_t ldrStrAddAddr); +uint64_t pfsec_arm64_resolve_adrp_ldr_str_add_reference_auto(PFSection *section, uint64_t ldrStrAddAddr); +uint64_t pfsec_arm64_resolve_stub(PFSection *section, uint64_t stubAddr); +void pfsec_arm64_enumerate_xrefs(PFSection *section, Arm64XrefTypeMask types, void (^xrefBlock)(Arm64XrefType type, uint64_t source, uint64_t target, bool *stop)); +#endif \ No newline at end of file diff --git a/RootHelper/external/include/choma/SignOSSL.h b/RootHelper/external/include/choma/SignOSSL.h index 00afe5f..f1be620 100644 --- a/RootHelper/external/include/choma/SignOSSL.h +++ b/RootHelper/external/include/choma/SignOSSL.h @@ -1,6 +1,8 @@ #ifndef SIGN_OSSL_H #define SIGN_OSSL_H +#ifndef DISABLE_SIGNING + #include #include #include @@ -11,6 +13,8 @@ unsigned char *signWithRSA(unsigned char *inputData, size_t inputDataLength, unsigned char *key, size_t key_len, size_t *outputDataLength); +#endif + #endif // SIGN_OSSL_H // 0xA422 \ No newline at end of file diff --git a/RootHelper/external/include/choma/Util.h b/RootHelper/external/include/choma/Util.h index 4bbda41..e4ccf64 100644 --- a/RootHelper/external/include/choma/Util.h +++ b/RootHelper/external/include/choma/Util.h @@ -1,7 +1,34 @@ +#ifndef UTIL_H +#define UTIL_H + #include #include +#include +typedef struct s_optional_uint64 { + bool isSet; + uint64_t value; +} optional_uint64_t; +#define OPT_UINT64_IS_SET(x) (x.isSet) +#define OPT_UINT64_GET_VAL(x) (x.value) +#define OPT_UINT64_NONE (optional_uint64_t){.isSet = false, .value = 0} +#define OPT_UINT64(x) (optional_uint64_t){.isSet = true, .value = x} + + +typedef struct s_optional_bool { + bool isSet; + bool value; +} optional_bool; +#define OPT_BOOL_IS_SET(x) (x.isSet) +#define OPT_BOOL_GET_VAL(x) (x.value) +#define OPT_BOOL_NONE (optional_bool){.isSet = false, .value = false} +#define OPT_BOOL(x) (optional_bool){.isSet = true, .value = x} + +int64_t sxt64(int64_t value, uint8_t bits); int memcmp_masked(const void *str1, const void *str2, unsigned char* mask, size_t n); uint64_t align_to_size(int size, int alignment); int count_digits(int64_t num); -void print_hash(uint8_t *hash, size_t size); \ No newline at end of file +void print_hash(uint8_t *hash, size_t size); +void enumerate_range(uint64_t start, uint64_t end, uint16_t alignment, size_t nbytes, bool (^enumerator)(uint64_t cur)); + +#endif \ No newline at end of file diff --git a/RootHelper/external/include/choma/arm64.h b/RootHelper/external/include/choma/arm64.h new file mode 100644 index 0000000..9affc1d --- /dev/null +++ b/RootHelper/external/include/choma/arm64.h @@ -0,0 +1,94 @@ +#ifndef ARM64_H +#define ARM64_H + +#include "Util.h" + +typedef enum { + // registers + ARM64_REG_TYPE_X, + ARM64_REG_TYPE_W, + + // vector shit + ARM64_REG_TYPE_Q, + ARM64_REG_TYPE_D, + ARM64_REG_TYPE_S, + ARM64_REG_TYPE_H, + ARM64_REG_TYPE_B, +} arm64_register_type; + +enum { + ARM64_REG_MASK_ANY_FLAG = (1 << 0), + ARM64_REG_MASK_X_W = (1 << 1), + ARM64_REG_MASK_VECTOR = (1 << 2), + ARM64_REG_MASK_ALL = (ARM64_REG_MASK_X_W | ARM64_REG_MASK_VECTOR), + + ARM64_REG_MASK_ANY_X_W = (ARM64_REG_MASK_X_W | ARM64_REG_MASK_ANY_FLAG), + ARM64_REG_MASK_ANY_VECTOR = (ARM64_REG_MASK_VECTOR | ARM64_REG_MASK_ANY_FLAG), + ARM64_REG_MASK_ANY_ALL = (ARM64_REG_MASK_ALL | ARM64_REG_MASK_ANY_FLAG), +}; + +typedef enum { + LDR_STR_TYPE_ANY, // NOTE: "ANY" will inevitably also match STUR and LDUR instructions + LDR_STR_TYPE_POST_INDEX, + LDR_STR_TYPE_PRE_INDEX, + LDR_STR_TYPE_UNSIGNED, +} arm64_ldr_str_type; + +typedef struct s_arm64_register { + uint8_t mask; + arm64_register_type type; + uint8_t num; +} arm64_register; + +#define ARM64_REG(type_, num_) (arm64_register){.mask = ARM64_REG_MASK_ALL, .type = type_, .num = num_} +#define ARM64_REG_X(x) ARM64_REG(ARM64_REG_TYPE_X, x) +#define ARM64_REG_W(x) ARM64_REG(ARM64_REG_TYPE_W, x) +#define ARM64_REG_Q(x) ARM64_REG(ARM64_REG_TYPE_Q, x) +#define ARM64_REG_S(x) ARM64_REG(ARM64_REG_TYPE_S, x) +#define ARM64_REG_H(x) ARM64_REG(ARM64_REG_TYPE_H, x) +#define ARM64_REG_B(x) ARM64_REG(ARM64_REG_TYPE_B, x) +#define ARM64_REG_ANY (arm64_register){.mask = ARM64_REG_MASK_ANY_ALL, .type = 0, .num = 0} +#define ARM64_REG_ANY_X_W (arm64_register){.mask = ARM64_REG_MASK_ANY_X_W, .type = 0, .num = 0} +#define ARM64_REG_ANY_VECTOR (arm64_register){.mask = ARM64_REG_MASK_ANY_VECTOR, .type = 0, .num = 0} +#define ARM64_REG_GET_TYPE(x) (x.type) +#define ARM64_REG_IS_X(x) (x.type == ARM64_REG_TYPE_X) +#define ARM64_REG_IS_W(x) (x.type == ARM64_REG_TYPE_W) +#define ARM64_REG_IS_VECTOR(x) (x.type == ARM64_REG_TYPE_Q || x.type == ARM64_REG_TYPE_D || x.type == ARM64_REG_TYPE_S || x.type == ARM64_REG_TYPE_H || x.type == ARM64_REG_TYPE_B) +#define ARM64_REG_GET_NUM(x) (x.num & 0x1f) +#define ARM64_REG_IS_ANY(x) (x.mask == ARM64_REG_MASK_ANY_ALL) +#define ARM64_REG_IS_ANY_X_W(x) (x.mask == ARM64_REG_MASK_ANY_X_W) +#define ARM64_REG_IS_ANY_VECTOR(x) (x.mask == ARM64_REG_MASK_ANY_VECTOR) +uint8_t arm64_reg_type_get_width(arm64_register_type type); +const char *arm64_reg_type_get_string(arm64_register_type type); +const char *arm64_reg_get_type_string(arm64_register reg); + +#define ARM64_REG_NUM_SP 31 + +typedef struct s_arm64_cond { + bool isSet; + uint8_t value; +} arm64_cond; +#define ARM64_COND(x) (arm64_cond){.isSet = true, .value = x} +#define ARM64_COND_ANY (arm64_cond){.isSet = false, .value = 0} +#define ARM64_COND_GET_VAL(x) (x.value & 0xf) +#define ARM64_COND_IS_SET(x) x.isSet + +int arm64_gen_b_l(optional_bool optIsBl, optional_uint64_t optOrigin, optional_uint64_t optTarget, uint32_t *bytesOut, uint32_t *maskOut); +int arm64_dec_b_l(uint32_t inst, uint64_t origin, uint64_t *targetOut, bool *isBlOut); +int arm64_gen_b_c_cond(optional_bool optIsBc, optional_uint64_t optOrigin, optional_uint64_t optTarget, arm64_cond optCond, uint32_t *bytesOut, uint32_t *maskOut); +int arm64_dec_b_c_cond(uint32_t inst, uint64_t origin, uint64_t *targetOut, arm64_cond *condOut, bool *isBcOut); +int arm64_gen_adr_p(optional_bool optIsAdrp, optional_uint64_t optOrigin, optional_uint64_t optTarget, arm64_register reg, uint32_t *bytesOut, uint32_t *maskOut); +int arm64_dec_adr_p(uint32_t inst, uint64_t origin, uint64_t *targetOut, arm64_register *registerOut, bool *isAdrpOut); +int arm64_gen_mov_imm(char type, arm64_register destinationReg, optional_uint64_t optImm, optional_uint64_t optShift, uint32_t *bytesOut, uint32_t *maskOut); +int arm64_dec_mov_imm(uint32_t inst, arm64_register *destinationRegOut, uint64_t *immOut, uint64_t *shiftOut, char *typeOut); +int arm64_gen_add_imm(arm64_register destinationReg, arm64_register sourceReg, optional_uint64_t optImm, uint32_t *bytesOut, uint32_t *maskOut); +int arm64_dec_add_imm(uint32_t inst, arm64_register *destinationRegOut, arm64_register *sourceRegOut, uint16_t *immOut); +int arm64_gen_ldr_imm(char type, arm64_ldr_str_type instType, arm64_register destinationReg, arm64_register addrReg, optional_uint64_t optImm, uint32_t *bytesOut, uint32_t *maskOut); +int arm64_dec_ldr_imm(uint32_t inst, arm64_register *destinationReg, arm64_register *addrReg, uint64_t *immOut, char *typeOut, arm64_ldr_str_type *instTypeOut); +int arm64_gen_str_imm(char type, arm64_ldr_str_type instType, arm64_register sourceReg, arm64_register addrReg, optional_uint64_t optImm, uint32_t *bytesOut, uint32_t *maskOut); +int arm64_dec_str_imm(uint32_t inst, arm64_register *sourceRegOut, arm64_register *addrRegOut, uint64_t *immOut, char *typeOut, arm64_ldr_str_type *instTypeOut); +int arm64_gen_ldr_lit(arm64_register destinationReg, optional_uint64_t optImm, uint32_t *bytesOut, uint32_t *maskOut); +int arm64_dec_ldr_lit(uint32_t inst, arm64_register *destinationReg, int64_t *immOut); +int arm64_gen_cb_n_z(optional_bool isCbnz, arm64_register reg, optional_uint64_t optTarget, uint32_t *bytesOut, uint32_t *maskOut); +int arm64_dec_cb_n_z(uint32_t inst, uint64_t origin, bool *isCbnzOut, arm64_register *regOut, uint64_t *targetOut); +#endif \ No newline at end of file diff --git a/RootHelper/external/lib/libchoma.a b/RootHelper/external/lib/libchoma.a index 99c1d46..4ec7fc8 100644 Binary files a/RootHelper/external/lib/libchoma.a and b/RootHelper/external/lib/libchoma.a differ