From 206541d9f0013d198ca12d42135bdb5afa253721 Mon Sep 17 00:00:00 2001 From: opa334 Date: Fri, 12 Jan 2024 15:40:20 +0100 Subject: [PATCH] Update ChOma (yes this sucks) --- .../src/external/include/choma/CSBlob.h | 7 +- .../external/include/choma/CodeDirectory.h | 10 +- .../external/include/choma/MachOByteOrder.h | 2 +- .../external/include/choma/MachOLoadCommand.h | 2 +- .../src/external/include/choma/MemoryStream.h | 2 +- .../src/external/include/choma/PatchFinder.h | 76 +++++++++----- .../include/choma/PatchFinder_arm64.h | 33 ++++++ .../src/external/include/choma/SignOSSL.h | 4 + .../src/external/include/choma/Util.h | 29 +++++- .../src/external/include/choma/arm64.h | 94 ++++++++++++++++++ .../fastPathSign/src/external/lib/libchoma.a | Bin 120096 -> 120160 bytes RootHelper/external/include/choma/CSBlob.h | 7 +- .../external/include/choma/CodeDirectory.h | 10 +- .../external/include/choma/MachOByteOrder.h | 2 +- .../external/include/choma/MachOLoadCommand.h | 2 +- .../external/include/choma/MemoryStream.h | 2 +- .../external/include/choma/PatchFinder.h | 76 +++++++++----- .../include/choma/PatchFinder_arm64.h | 33 ++++++ RootHelper/external/include/choma/SignOSSL.h | 4 + RootHelper/external/include/choma/Util.h | 29 +++++- RootHelper/external/include/choma/arm64.h | 94 ++++++++++++++++++ RootHelper/external/lib/libchoma.a | Bin 92696 -> 120528 bytes 22 files changed, 446 insertions(+), 72 deletions(-) create mode 100644 Exploits/fastPathSign/src/external/include/choma/PatchFinder_arm64.h create mode 100644 Exploits/fastPathSign/src/external/include/choma/arm64.h create mode 100644 RootHelper/external/include/choma/PatchFinder_arm64.h create mode 100644 RootHelper/external/include/choma/arm64.h 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 e69e1860cc810354eee338317d1085e780294d9c..44849e384225f37772a5f52809bcefcc4edc6e35 100644 GIT binary patch delta 41464 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 delta 42189 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 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 99c1d461119d6cf0b05643c5030be04aed43b52d..4ec7fc8dadc586eb7c81bb6ad2974c8298f6fd35 100644 GIT binary patch delta 41413 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 b#nPMwmDafDCrkro8}+ovvp)p0f!h2Z^CESt delta 19274 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 DI5-Yr