mirror of https://github.com/opa334/TrollStore.git
Update ChOma (yes this sucks)
This commit is contained in:
parent
2587c320d0
commit
206541d9f0
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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); \
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
|
||||
#include <mach-o/loader.h>
|
||||
#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);
|
||||
|
|
|
@ -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
|
|
@ -1,11 +1,16 @@
|
|||
#ifndef PATCHFINDER_H
|
||||
#define PATCHFINDER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#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
|
|
@ -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
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef SIGN_OSSL_H
|
||||
#define SIGN_OSSL_H
|
||||
|
||||
#ifndef DISABLE_SIGNING
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -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
|
|
@ -1,7 +1,34 @@
|
|||
#ifndef UTIL_H
|
||||
#define UTIL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
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);
|
||||
void enumerate_range(uint64_t start, uint64_t end, uint16_t alignment, size_t nbytes, bool (^enumerator)(uint64_t cur));
|
||||
|
||||
#endif
|
|
@ -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
|
Binary file not shown.
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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); \
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
|
||||
#include <mach-o/loader.h>
|
||||
#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);
|
||||
|
|
|
@ -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
|
|
@ -1,11 +1,16 @@
|
|||
#ifndef PATCHFINDER_H
|
||||
#define PATCHFINDER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#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
|
|
@ -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
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef SIGN_OSSL_H
|
||||
#define SIGN_OSSL_H
|
||||
|
||||
#ifndef DISABLE_SIGNING
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -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
|
|
@ -1,7 +1,34 @@
|
|||
#ifndef UTIL_H
|
||||
#define UTIL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
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);
|
||||
void enumerate_range(uint64_t start, uint64_t end, uint16_t alignment, size_t nbytes, bool (^enumerator)(uint64_t cur));
|
||||
|
||||
#endif
|
|
@ -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
|
Binary file not shown.
Loading…
Reference in New Issue