CHDK_DE Vorschauversion  Trunk Rev. 6014
 Alle Datenstrukturen Dateien Funktionen Variablen Typdefinitionen Aufzählungen Aufzählungswerte Makrodefinitionen
firmware_load_ng.h-Dateireferenz
+ Dieser Graph zeigt, welche Datei direkt oder indirekt diese Datei enthält:

gehe zum Quellcode dieser Datei

Datenstrukturen

struct  bufrange
 
struct  adr_hist_t
 
struct  iter_state_t
 
struct  adr_range_t
 
struct  firmware
 
struct  tbx_info_t
 
struct  search_calls_multi_data_t
 
struct  var_ldr_desc_t
 
struct  simple_func_desc_t
 
struct  op_match_t
 
struct  insn_match_t
 

Makrodefinitionen

#define MIN(a, b)   ((a) < (b) ? (a) : (b))
 
#define MAX(a, b)   ((a) > (b) ? (a) : (b))
 
#define FW_ARCH_ARMv5   1
 
#define FW_ARCH_ARMv7   2
 
#define FW_ARCH_FL_VMSA   1
 
#define ADR_SET_THUMB(x)   ((x)|1)
 
#define ADR_CLEAR_THUMB(x)   ((x)&~1)
 
#define ADR_IS_THUMB(x)   ((x)&1)
 
#define ADR_ALIGN4(x)   ((x)&~0x3)
 
#define ADR_ALIGN2(x)   ((x)&~0x1)
 
#define ADR_IS_ALIGN4(x)   (((x)&0x3)==0)
 
#define ADR_RANGE_INVALID   0
 
#define ADR_RANGE_ROM   1
 
#define ADR_RANGE_RAM_CODE   2
 
#define ADR_RANGE_INIT_DATA   3
 
#define ADR_RANGE_FL_NONE   0
 
#define ADR_RANGE_FL_TCM   1
 
#define ADR_RANGE_FL_EVEC   2
 
#define ADR_HIST_SIZE   64
 
#define FW_MAX_ADR_RANGES   10
 
#define FW_MAX_DRYOS_VERS   10
 
#define FW_DRYOS_VER_MUL   100
 
#define IS_INSN_ID_MOVx(insn_id)   ((insn_id) == ARM_INS_MOV || (insn_id) == ARM_INS_MOVS || (insn_id) == ARM_INS_MOVW)
 
#define IS_INSN_ID_SUBx(insn_id)   ((insn_id) == ARM_INS_SUB || (insn_id) == ARM_INS_SUBW || (insn_id) == ARM_INS_SUBS)
 
#define MATCH_SIMPLE_FUNC_NONE   0x0
 
#define MATCH_SIMPLE_FUNC_NULLSUB   0x1
 
#define MATCH_SIMPLE_FUNC_IMM   0x2
 
#define MATCH_SIMPLE_FUNC_ANY   0x3
 
#define MATCH_OP_FL_IMM   0x0001
 
#define MATCH_OP_FL_LAST   0x0002
 
#define MATCH_OP_ANY   {ARM_OP_INVALID,ARM_REG_INVALID, 0, 0, ARM_REG_INVALID}
 
#define MATCH_OP_REST_ANY   {ARM_OP_INVALID,ARM_REG_INVALID, MATCH_OP_FL_LAST, 0, ARM_REG_INVALID}
 
#define MATCH_OP_REG_ANY   {ARM_OP_REG, ARM_REG_INVALID, 0, 0, ARM_REG_INVALID}
 
#define MATCH_OP_REG(r)   {ARM_OP_REG, ARM_REG_##r, 0, 0, ARM_REG_INVALID}
 
#define MATCH_OP_REG_RANGE(r1, r2)   {ARM_OP_REG, ARM_REG_##r1, 0, 0, ARM_REG_##r2}
 
#define MATCH_OP_IMM_ANY   {ARM_OP_IMM, ARM_REG_INVALID, 0, 0, ARM_REG_INVALID}
 
#define MATCH_OP_IMM(imm)   {ARM_OP_IMM, ARM_REG_INVALID, MATCH_OP_FL_IMM, (imm), ARM_REG_INVALID}
 
#define MATCH_OP_PIMM_ANY   {ARM_OP_PIMM, ARM_REG_INVALID, 0, 0, ARM_REG_INVALID}
 
#define MATCH_OP_PIMM(imm)   {ARM_OP_PIMM, ARM_REG_INVALID, MATCH_OP_FL_IMM, (imm), ARM_REG_INVALID}
 
#define MATCH_OP_CIMM_ANY   {ARM_OP_CIMM, ARM_REG_INVALID, 0, 0, ARM_REG_INVALID}
 
#define MATCH_OP_CIMM(imm)   {ARM_OP_CIMM, ARM_REG_INVALID, MATCH_OP_FL_IMM, (imm), ARM_REG_INVALID}
 
#define MATCH_OP_MEM_ANY   {ARM_OP_MEM, ARM_REG_INVALID, 0, 0, ARM_REG_INVALID}
 
#define MATCH_OP_MEM(rb, ri, imm)   {ARM_OP_MEM, ARM_REG_##rb, MATCH_OP_FL_IMM, (imm), ARM_REG_##ri}
 
#define MATCH_OP_MEM_BASE(r)   {ARM_OP_MEM, ARM_REG_##r, 0, 0, ARM_REG_INVALID}
 
#define MATCH_OP_MEM_REGS(rb, ri)   {ARM_OP_MEM, ARM_REG_##rb, 0, 0, ARM_REG_##ri}
 
#define MATCH_MAX_OPS   16
 
#define MATCH_OPCOUNT_ANY   -1
 
#define MATCH_OPCOUNT_IGNORE   -2
 
#define MATCH_INS(ins, opcount)   ARM_INS_##ins,(opcount),ARM_CC_INVALID
 
#define MATCH_INS_CC(ins, cc, opcount)   ARM_INS_##ins,(opcount),ARM_CC_##cc
 
#define FIND_CONST_REF_MATCH_ANY   0
 
#define FIND_CONST_REF_MATCH_SEQ   1
 
#define iter_state_adr(is)   ((uint32_t)is->insn->address | is->thumb)
 

Typdefinitionen

typedef struct bufrange BufRange
 
typedef uint32_t(* search_insn_fn )(firmware *fw, iter_state_t *is, uint32_t v1, void *udata)
 
typedef int(* search_calls_multi_fn )(firmware *fw, iter_state_t *is, uint32_t adr)
 
typedef int(* search_bytes_fn )(firmware *, int k)
 

Funktionen

uint8_t * adr2ptr (firmware *fw, uint32_t adr)
 
uint8_t * adr2ptr_with_data (firmware *fw, uint32_t adr)
 
const char * adr_range_type_str (int type)
 
const char * adr_range_desc_str (adr_range_t *r)
 
uint32_t ptr2adr (firmware *fw, uint8_t *ptr)
 
adr_range_tadr_get_range (firmware *fw, uint32_t adr)
 
int adr_get_range_type (firmware *fw, uint32_t adr)
 
int adr_is_var (firmware *fw, uint32_t adr)
 
int adr_is_main_fw_code (firmware *fw, uint32_t adr)
 
int find_Nth_str (firmware *fw, char *str, int N)
 
int find_str (firmware *fw, char *str)
 
uint32_t find_next_bytes_range (firmware *fw, const void *bytes, size_t len, uint32_t start_adr, uint32_t max_adr)
 
int find_bytes_all (firmware *fw, const void *bytes, size_t len, uint32_t adr, uint32_t *result, int maxmatch)
 
uint32_t find_next_str_bytes (firmware *fw, const char *str, uint32_t adr)
 
uint32_t find_next_str_bytes_main_fw (firmware *fw, const char *str, uint32_t adr)
 
uint32_t find_next_substr_bytes (firmware *fw, const char *str, uint32_t adr)
 
uint32_t find_str_bytes_main_fw (firmware *fw, const char *str)
 
uint32_t find_str_bytes (firmware *fw, const char *str)
 
int isASCIIstring (firmware *fw, uint32_t adr)
 
uint32_t find_u32_adr_range (firmware *fw, uint32_t val, uint32_t start, uint32_t maxadr)
 
uint32_t find_u32_adr (firmware *fw, uint32_t val, uint32_t start)
 
uint32_t fw_u32 (firmware *fw, uint32_t adr)
 
int fw_memcmp (firmware *fw, uint32_t adr, const void *cmp, size_t n)
 
void adr_hist_reset (adr_hist_t *ah)
 
int adr_hist_index (adr_hist_t *ah, int i)
 
void adr_hist_add (adr_hist_t *ah, uint32_t adr)
 
uint32_t adr_hist_get (adr_hist_t *ah, int i)
 
int isARM (cs_insn *insn)
 
int isLDR_PC (cs_insn *insn)
 
int isLDR_PC_PC (cs_insn *insn)
 
uint32_tLDR_PC2valptr_thumb (firmware *fw, cs_insn *insn)
 
uint32_tLDR_PC2valptr_arm (firmware *fw, cs_insn *insn)
 
uint32_tLDR_PC2valptr (firmware *fw, cs_insn *insn)
 
uint32_t LDR_PC2adr (firmware *fw, cs_insn *insn)
 
int isSUBW_PC (cs_insn *insn)
 
int isADDW_PC (cs_insn *insn)
 
int isADD_PC (cs_insn *insn)
 
int isSUB_PC (cs_insn *insn)
 
int isRETx (cs_insn *insn)
 
int isPUSH_LR (cs_insn *insn)
 
int isPOP_LR (cs_insn *insn)
 
int isPOP_PC (cs_insn *insn)
 
int isADDx_imm (cs_insn *insn)
 
int isSUBx_imm (cs_insn *insn)
 
int isADRx (cs_insn *insn)
 
uint32_t ADRx2adr (firmware *fw, cs_insn *insn)
 
uint32_t ADR2adr (firmware *fw, cs_insn *insn)
 
uint32_tADR2valptr (firmware *fw, cs_insn *insn)
 
uint32_t LDR_PC2val (firmware *fw, cs_insn *insn)
 
uint32_t B_target (firmware *fw, cs_insn *insn)
 
uint32_t CBx_target (firmware *fw, cs_insn *insn)
 
uint32_t BLXimm_target (firmware *fw, cs_insn *insn)
 
uint32_t BL_target (firmware *fw, cs_insn *insn)
 
uint32_t B_BL_target (firmware *fw, cs_insn *insn)
 
uint32_t B_BL_BLXimm_target (firmware *fw, cs_insn *insn)
 
uint32_t BX_PC_target (__attribute__((unused)) firmware *fw, cs_insn *insn)
 
int get_TBx_PC_info (firmware *fw, iter_state_t *is, tbx_info_t *ti)
 
iter_state_tdisasm_iter_new (firmware *fw, uint32_t adr)
 
void disasm_iter_free (iter_state_t *is)
 
int disasm_iter_set (firmware *fw, iter_state_t *is, uint32_t adr)
 
int disasm_iter_init (firmware *fw, iter_state_t *is, uint32_t adr)
 
int disasm_iter (firmware *fw, iter_state_t *is)
 
int fw_disasm_iter_start (firmware *fw, uint32_t adr)
 
int fw_disasm_iter (firmware *fw)
 
int fw_disasm_iter_single (firmware *fw, uint32_t adr)
 
uint32_t fw_search_insn (firmware *fw, iter_state_t *is, search_insn_fn f, uint32_t v1, void *udata, uint32_t adr_end)
 
uint32_t search_disasm_const_ref (firmware *fw, iter_state_t *is, uint32_t val, void *unused)
 
uint32_t search_disasm_str_ref (firmware *fw, iter_state_t *is, uint32_t val, void *str)
 
uint32_t search_disasm_calls (firmware *fw, iter_state_t *is, uint32_t val, void *unused)
 
int search_calls_multi_end (firmware *fw, iter_state_t *is, uint32_t adr)
 
uint32_t search_disasm_calls_multi (firmware *fw, iter_state_t *is, uint32_t unused, void *userdata)
 
uint32_t search_disasm_calls_veneer_multi (firmware *fw, iter_state_t *is, uint32_t unused, void *userdata)
 
int get_call_const_args (firmware *fw, iter_state_t *is_init, int max_backtrack, uint32_t *res)
 
uint32_t get_direct_jump_target (firmware *fw, iter_state_t *is_init)
 
uint32_t get_branch_call_insn_target (firmware *fw, iter_state_t *is)
 
int find_and_get_var_ldr (firmware *fw, iter_state_t *is, int max_search_insns, int max_seq_insns, arm_reg match_val_reg, var_ldr_desc_t *result)
 
int check_simple_func (firmware *fw, uint32_t adr, int match_ftype, simple_func_desc_t *info)
 
uint32_t find_last_call_from_func (firmware *fw, iter_state_t *is, int min_insns, int max_insns)
 
int insn_match (cs_insn *insn, const insn_match_t *match)
 
int insn_match_any (cs_insn *insn, const insn_match_t *match)
 
int insn_match_find_next (firmware *fw, iter_state_t *is, int max_insns, const insn_match_t *match)
 
int insn_match_find_nth (firmware *fw, iter_state_t *is, int max_insns, int num_to_match, const insn_match_t *match)
 
int insn_match_seq (firmware *fw, iter_state_t *is, const insn_match_t *match)
 
int insn_match_find_next_seq (firmware *fw, iter_state_t *is, int max_insns, const insn_match_t *match)
 
int find_const_ref_match (firmware *fw, iter_state_t *is, int max_search_bytes, int max_gap_insns, arm_reg match_reg, uint32_t val, const insn_match_t *match, int match_type)
 
int find_const_ref_call (firmware *fw, iter_state_t *is, int max_search_bytes, int max_gap_insns, arm_reg match_reg, uint32_t val)
 
int fw_search_bytes (firmware *fw, search_bytes_fn func)
 
void fw_add_adr_range (firmware *fw, uint32_t start, uint32_t end, uint32_t src_start, int type, int flags)
 
void firmware_load (firmware *fw, const char *filename, uint32_t base_adr, int fw_arch)
 
int firmware_init_capstone (firmware *fw)
 
void firmware_init_data_ranges (firmware *fw)
 
void firmware_unload (firmware *fw)
 

Variablen

const insn_match_t match_b []
 
const insn_match_t match_bl []
 
const insn_match_t match_b_bl []
 
const insn_match_t match_b_bl_blximm []
 
const insn_match_t match_bl_blximm []
 
const insn_match_t match_bxlr []
 
const insn_match_t match_bxreg []
 
const insn_match_t match_blxreg []
 
const insn_match_t match_ldr_pc []
 

Makro-Dokumentation

#define ADR_ALIGN2 (   x)    ((x)&~0x1)

Definiert in Zeile 21 der Datei firmware_load_ng.h.

#define ADR_ALIGN4 (   x)    ((x)&~0x3)

Definiert in Zeile 20 der Datei firmware_load_ng.h.

#define ADR_CLEAR_THUMB (   x)    ((x)&~1)

Definiert in Zeile 17 der Datei firmware_load_ng.h.

#define ADR_HIST_SIZE   64

Definiert in Zeile 45 der Datei firmware_load_ng.h.

#define ADR_IS_ALIGN4 (   x)    (((x)&0x3)==0)

Definiert in Zeile 23 der Datei firmware_load_ng.h.

#define ADR_IS_THUMB (   x)    ((x)&1)

Definiert in Zeile 18 der Datei firmware_load_ng.h.

#define ADR_RANGE_FL_EVEC   2

Definiert in Zeile 33 der Datei firmware_load_ng.h.

#define ADR_RANGE_FL_NONE   0

Definiert in Zeile 31 der Datei firmware_load_ng.h.

#define ADR_RANGE_FL_TCM   1

Definiert in Zeile 32 der Datei firmware_load_ng.h.

#define ADR_RANGE_INIT_DATA   3

Definiert in Zeile 29 der Datei firmware_load_ng.h.

#define ADR_RANGE_INVALID   0

Definiert in Zeile 26 der Datei firmware_load_ng.h.

#define ADR_RANGE_RAM_CODE   2

Definiert in Zeile 28 der Datei firmware_load_ng.h.

#define ADR_RANGE_ROM   1

Definiert in Zeile 27 der Datei firmware_load_ng.h.

#define ADR_SET_THUMB (   x)    ((x)|1)

Definiert in Zeile 16 der Datei firmware_load_ng.h.

#define FIND_CONST_REF_MATCH_ANY   0

Definiert in Zeile 650 der Datei firmware_load_ng.h.

#define FIND_CONST_REF_MATCH_SEQ   1

Definiert in Zeile 651 der Datei firmware_load_ng.h.

#define FW_ARCH_ARMv5   1

Definiert in Zeile 8 der Datei firmware_load_ng.h.

#define FW_ARCH_ARMv7   2

Definiert in Zeile 10 der Datei firmware_load_ng.h.

#define FW_ARCH_FL_VMSA   1

Definiert in Zeile 13 der Datei firmware_load_ng.h.

#define FW_DRYOS_VER_MUL   100

Definiert in Zeile 84 der Datei firmware_load_ng.h.

#define FW_MAX_ADR_RANGES   10

Definiert in Zeile 79 der Datei firmware_load_ng.h.

#define FW_MAX_DRYOS_VERS   10

Definiert in Zeile 81 der Datei firmware_load_ng.h.

#define IS_INSN_ID_MOVx (   insn_id)    ((insn_id) == ARM_INS_MOV || (insn_id) == ARM_INS_MOVS || (insn_id) == ARM_INS_MOVW)

Definiert in Zeile 242 der Datei firmware_load_ng.h.

#define IS_INSN_ID_SUBx (   insn_id)    ((insn_id) == ARM_INS_SUB || (insn_id) == ARM_INS_SUBW || (insn_id) == ARM_INS_SUBS)

Definiert in Zeile 244 der Datei firmware_load_ng.h.

#define iter_state_adr (   is)    ((uint32_t)is->insn->address | is->thumb)

Definiert in Zeile 710 der Datei firmware_load_ng.h.

#define MATCH_INS (   ins,
  opcount 
)    ARM_INS_##ins,(opcount),ARM_CC_INVALID

Definiert in Zeile 593 der Datei firmware_load_ng.h.

#define MATCH_INS_CC (   ins,
  cc,
  opcount 
)    ARM_INS_##ins,(opcount),ARM_CC_##cc

Definiert in Zeile 594 der Datei firmware_load_ng.h.

#define MATCH_MAX_OPS   16

Definiert in Zeile 588 der Datei firmware_load_ng.h.

#define MATCH_OP_ANY   {ARM_OP_INVALID,ARM_REG_INVALID, 0, 0, ARM_REG_INVALID}

Definiert in Zeile 572 der Datei firmware_load_ng.h.

#define MATCH_OP_CIMM (   imm)    {ARM_OP_CIMM, ARM_REG_INVALID, MATCH_OP_FL_IMM, (imm), ARM_REG_INVALID}

Definiert in Zeile 582 der Datei firmware_load_ng.h.

#define MATCH_OP_CIMM_ANY   {ARM_OP_CIMM, ARM_REG_INVALID, 0, 0, ARM_REG_INVALID}

Definiert in Zeile 581 der Datei firmware_load_ng.h.

#define MATCH_OP_FL_IMM   0x0001

Definiert in Zeile 568 der Datei firmware_load_ng.h.

#define MATCH_OP_FL_LAST   0x0002

Definiert in Zeile 569 der Datei firmware_load_ng.h.

#define MATCH_OP_IMM (   imm)    {ARM_OP_IMM, ARM_REG_INVALID, MATCH_OP_FL_IMM, (imm), ARM_REG_INVALID}

Definiert in Zeile 578 der Datei firmware_load_ng.h.

#define MATCH_OP_IMM_ANY   {ARM_OP_IMM, ARM_REG_INVALID, 0, 0, ARM_REG_INVALID}

Definiert in Zeile 577 der Datei firmware_load_ng.h.

#define MATCH_OP_MEM (   rb,
  ri,
  imm 
)    {ARM_OP_MEM, ARM_REG_##rb, MATCH_OP_FL_IMM, (imm), ARM_REG_##ri}

Definiert in Zeile 584 der Datei firmware_load_ng.h.

#define MATCH_OP_MEM_ANY   {ARM_OP_MEM, ARM_REG_INVALID, 0, 0, ARM_REG_INVALID}

Definiert in Zeile 583 der Datei firmware_load_ng.h.

#define MATCH_OP_MEM_BASE (   r)    {ARM_OP_MEM, ARM_REG_##r, 0, 0, ARM_REG_INVALID}

Definiert in Zeile 585 der Datei firmware_load_ng.h.

#define MATCH_OP_MEM_REGS (   rb,
  ri 
)    {ARM_OP_MEM, ARM_REG_##rb, 0, 0, ARM_REG_##ri}

Definiert in Zeile 586 der Datei firmware_load_ng.h.

#define MATCH_OP_PIMM (   imm)    {ARM_OP_PIMM, ARM_REG_INVALID, MATCH_OP_FL_IMM, (imm), ARM_REG_INVALID}

Definiert in Zeile 580 der Datei firmware_load_ng.h.

#define MATCH_OP_PIMM_ANY   {ARM_OP_PIMM, ARM_REG_INVALID, 0, 0, ARM_REG_INVALID}

Definiert in Zeile 579 der Datei firmware_load_ng.h.

#define MATCH_OP_REG (   r)    {ARM_OP_REG, ARM_REG_##r, 0, 0, ARM_REG_INVALID}

Definiert in Zeile 575 der Datei firmware_load_ng.h.

#define MATCH_OP_REG_ANY   {ARM_OP_REG, ARM_REG_INVALID, 0, 0, ARM_REG_INVALID}

Definiert in Zeile 574 der Datei firmware_load_ng.h.

#define MATCH_OP_REG_RANGE (   r1,
  r2 
)    {ARM_OP_REG, ARM_REG_##r1, 0, 0, ARM_REG_##r2}

Definiert in Zeile 576 der Datei firmware_load_ng.h.

#define MATCH_OP_REST_ANY   {ARM_OP_INVALID,ARM_REG_INVALID, MATCH_OP_FL_LAST, 0, ARM_REG_INVALID}

Definiert in Zeile 573 der Datei firmware_load_ng.h.

#define MATCH_OPCOUNT_ANY   -1

Definiert in Zeile 590 der Datei firmware_load_ng.h.

#define MATCH_OPCOUNT_IGNORE   -2

Definiert in Zeile 591 der Datei firmware_load_ng.h.

#define MATCH_SIMPLE_FUNC_ANY   0x3

Definiert in Zeile 540 der Datei firmware_load_ng.h.

#define MATCH_SIMPLE_FUNC_IMM   0x2

Definiert in Zeile 537 der Datei firmware_load_ng.h.

#define MATCH_SIMPLE_FUNC_NONE   0x0

Definiert in Zeile 533 der Datei firmware_load_ng.h.

#define MATCH_SIMPLE_FUNC_NULLSUB   0x1

Definiert in Zeile 535 der Datei firmware_load_ng.h.

#define MAX (   a,
 
)    ((a) > (b) ? (a) : (b))

Definiert in Zeile 5 der Datei firmware_load_ng.h.

#define MIN (   a,
 
)    ((a) < (b) ? (a) : (b))

Definiert in Zeile 4 der Datei firmware_load_ng.h.

Dokumentation der benutzerdefinierten Typen

typedef struct bufrange BufRange
typedef int(* search_bytes_fn)(firmware *, int k)

Definiert in Zeile 690 der Datei firmware_load_ng.h.

typedef int(* search_calls_multi_fn)(firmware *fw, iter_state_t *is, uint32_t adr)

Definiert in Zeile 438 der Datei firmware_load_ng.h.

typedef uint32_t(* search_insn_fn)(firmware *fw, iter_state_t *is, uint32_t v1, void *udata)

Definiert in Zeile 411 der Datei firmware_load_ng.h.

Dokumentation der Funktionen

uint32_t ADR2adr ( firmware fw,
cs_insn *  insn 
)
uint8_t* adr2ptr ( firmware fw,
uint32_t  adr 
)

Definiert in Zeile 174 der Datei firmware_load.c.

175 {
176  if ((fw->dryos_ver >= 51) && (fw->alt_base) && (adr >= fw->alt_base))
177  {
178  return ((char*)fw->buf) + (adr - fw->alt_base);
179  }
180  if ((fw->dryos_ver >= 50) && (adr < fw->base))
181  {
182  adr = (adr - fw->base2) + fw->base_copied;
183  }
184  return ((char*)fw->buf) + (adr - fw->base);
185 }
uint8_t* adr2ptr_with_data ( firmware fw,
uint32_t  adr 
)

Definiert in Zeile 293 der Datei firmware_load_ng.c.

294 {
295  adr_range_t *r=adr_get_range(fw,adr);
296  if(!r) {
297  return NULL;
298  }
299  switch(r->type) {
300  case ADR_RANGE_RAM_CODE:
301  case ADR_RANGE_INIT_DATA:
302  case ADR_RANGE_ROM:
303  return (r->buf)+(adr - r->start);
304  default:
305  return NULL;
306  }
307 }
uint32_t* ADR2valptr ( firmware fw,
cs_insn *  insn 
)

Definiert in Zeile 748 der Datei firmware_load_ng.c.

749 {
750  uint32_t adr=ADR2adr(fw,insn);
751  return (uint32_t *)adr2ptr(fw,adr);
752 }
adr_range_t* adr_get_range ( firmware fw,
uint32_t  adr 
)

Definiert in Zeile 249 der Datei firmware_load_ng.c.

250 {
251  int i;
252  adr_range_t *r=fw->adr_ranges;
253  for(i=0;i<fw->adr_range_count;i++) {
254  if(adr >= r->start && adr < r->start + r->bytes) {
255  return r;
256  }
257  r++;
258  }
259  return NULL;
260 }
int adr_get_range_type ( firmware fw,
uint32_t  adr 
)

Definiert in Zeile 263 der Datei firmware_load_ng.c.

264 {
265  adr_range_t *r=adr_get_range(fw,adr);
266  if(!r) {
267  return ADR_RANGE_INVALID;
268  }
269  return r->type;
270 }
void adr_hist_add ( adr_hist_t ah,
uint32_t  adr 
)

Definiert in Zeile 456 der Datei firmware_load_ng.c.

457 {
458  ah->cur=adr_hist_index(ah,1);
459  ah->adrs[ah->cur]=adr;
460  if(ah->count < ADR_HIST_SIZE) {
461  ah->count++;
462  }
463 }
uint32_t adr_hist_get ( adr_hist_t ah,
int  i 
)

Definiert in Zeile 467 der Datei firmware_load_ng.c.

468 {
469  if(!ah->count || i > ah->count) {
470  return 0;
471  }
472  return ah->adrs[adr_hist_index(ah,-i)];
473 }
int adr_hist_index ( adr_hist_t ah,
int  i 
)

Definiert in Zeile 446 der Datei firmware_load_ng.c.

447 {
448  int r=(ah->cur+i)%ADR_HIST_SIZE;
449  if(r < 0) {
450  return ADR_HIST_SIZE + r;
451  }
452  return r;
453 }
void adr_hist_reset ( adr_hist_t ah)

Definiert in Zeile 437 der Datei firmware_load_ng.c.

438 {
439  ah->cur=0;
440  ah->count=0;
441  // memset shouldn't be needed
442  // memset(ah->adrs,0,ADR_HIST_SIZE*4);
443 }
int adr_is_main_fw_code ( firmware fw,
uint32_t  adr 
)

Definiert in Zeile 355 der Datei firmware_load_ng.c.

356 {
357  int adr_type = adr_get_range_type(fw,adr);
358  if(adr_type == ADR_RANGE_RAM_CODE) {
359  return 1;
360  }
361  if(adr_type != ADR_RANGE_ROM) {
362  return 0;
363  }
364  if(adr < fw->rom_code_search_min_adr || adr > fw->rom_code_search_max_adr) {
365  return 0;
366  }
367  return 1;
368 }
int adr_is_var ( firmware fw,
uint32_t  adr 
)

Definiert in Zeile 349 der Datei firmware_load_ng.c.

350 {
351  return (adr > fw->data_start && adr < fw->memisostart);
352 }
const char* adr_range_desc_str ( adr_range_t r)

Definiert in Zeile 327 der Datei firmware_load_ng.c.

328 {
329  switch(r->type) {
330  case ADR_RANGE_INVALID:
331  return "(invalid)";
332  case ADR_RANGE_ROM:
333  return "ROM";
334  case ADR_RANGE_RAM_CODE:
335  if(r->flags & ADR_RANGE_FL_EVEC) {
336  return "EVEC";
337  } else if(r->flags & ADR_RANGE_FL_TCM) {
338  return "TCM code";
339  }
340  return "RAM code";
341  case ADR_RANGE_INIT_DATA:
342  return "RAM data";
343  default:
344  return "(unknown)";
345  }
346 }
const char* adr_range_type_str ( int  type)

Definiert in Zeile 310 der Datei firmware_load_ng.c.

311 {
312  switch(type) {
313  case ADR_RANGE_INVALID:
314  return "(invalid)";
315  case ADR_RANGE_ROM:
316  return "ROM";
317  case ADR_RANGE_RAM_CODE:
318  return "RAM code";
319  case ADR_RANGE_INIT_DATA:
320  return "RAM data";
321  default:
322  return "(unknown)";
323  }
324 }
uint32_t ADRx2adr ( firmware fw,
cs_insn *  insn 
)
uint32_t B_BL_BLXimm_target ( firmware fw,
cs_insn *  insn 
)
uint32_t B_BL_target ( firmware fw,
cs_insn *  insn 
)
uint32_t B_target ( firmware fw,
cs_insn *  insn 
)
uint32_t BL_target ( firmware fw,
cs_insn *  insn 
)
uint32_t BLXimm_target ( firmware fw,
cs_insn *  insn 
)
uint32_t BX_PC_target ( __attribute__((unused)) firmware fw,
cs_insn *  insn 
)

Definiert in Zeile 833 der Datei firmware_load_ng.c.

834 {
835  if(insn->id == ARM_INS_BX
836  && insn->detail->arm.operands[0].type == ARM_OP_REG
837  && insn->detail->arm.operands[0].reg == ARM_REG_PC) {
838  if(insn->size == 2) { // thumb
839  // per arms docs, thumb bx pc from unaligned address is "undefined"
840  // assume non-instruction
841  if((insn->address & 2) == 2) {
842  return 0;
843  }
844  return (uint32_t)(insn->address) + 4;
845  } else {
846  return (uint32_t)(insn->address) + 8;
847  }
848  }
849  return 0;
850 }
uint32_t CBx_target ( firmware fw,
cs_insn *  insn 
)
int check_simple_func ( firmware fw,
uint32_t  adr,
int  match_ftype,
simple_func_desc_t info 
)

Definiert in Zeile 1728 der Datei firmware_load_ng.c.

1729 {
1730  const insn_match_t match_mov_r0_imm[]={
1731  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM_ANY}},
1732 #if CS_API_MAJOR < 4
1733  {MATCH_INS(MOVS, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM_ANY}},
1734 #endif
1735  {ARM_INS_ENDING}
1736  };
1737 
1738  int found = 0;
1739  int found_val = 0;
1740  if(info) {
1741  info->ftype = MATCH_SIMPLE_FUNC_NONE;
1742  info->retval = 0;
1743  }
1744  if(!fw_disasm_iter_single(fw,adr)) {
1745  //fprintf(stderr,"check_simple_func: disasm_iter_single failed 0x%x\n",adr);
1746  return 0;
1747  }
1748  if(match_ftype & MATCH_SIMPLE_FUNC_IMM) {
1749  // check mov r0, #imm
1750  if(insn_match_any(fw->is->insn,match_mov_r0_imm)) {
1751  found_val = fw->is->insn->detail->arm.operands[1].imm;
1752  found = MATCH_SIMPLE_FUNC_IMM;
1753  // fprintf(stderr,"check_simple_func: found IMM\n");
1754  if(!fw_disasm_iter(fw)) {
1755  //fprintf(stderr,"check_simple_func: disasm_iter failed 0x%x\n",adr);
1756  return 0;
1757  }
1758  }
1759  }
1760  if(!isRETx(fw->is->insn)) {
1761  // fprintf(stderr,"check_simple_func: no ret\n");
1762  return 0;
1763  }
1764  // no previous found, check if ret alone
1765  if(!found && (match_ftype & MATCH_SIMPLE_FUNC_NULLSUB)) {
1766  found = MATCH_SIMPLE_FUNC_NULLSUB;
1767  // fprintf(stderr,"check_simple_func: found nullsub\n");
1768  }
1769  if(found) {
1770  if(info) {
1771  info->ftype = found;
1772  info->retval = found_val;
1773  }
1774  }
1775  return found;
1776 }
int disasm_iter ( firmware fw,
iter_state_t is 
)
void disasm_iter_free ( iter_state_t is)

Definiert in Zeile 963 der Datei firmware_load_ng.c.

964 {
965  cs_free(is->insn,1);
966  free(is);
967  return;
968 }
int disasm_iter_init ( firmware fw,
iter_state_t is,
uint32_t  adr 
)
iter_state_t* disasm_iter_new ( firmware fw,
uint32_t  adr 
)

Definiert in Zeile 952 der Datei firmware_load_ng.c.

953 {
955  // it doesn't currently appear to matter which handle is used to allocate
956  // only used for overridable malloc functions and error reporting
957  is->insn=cs_malloc(fw->cs_handle_arm);
958  disasm_iter_init(fw,is,adr);
959  return is;
960 }
int disasm_iter_set ( firmware fw,
iter_state_t is,
uint32_t  adr 
)

Definiert in Zeile 972 der Datei firmware_load_ng.c.

973 {
974  // set handle based on thumb bit to allow disassembly
975  if(ADR_IS_THUMB(adr)) {
976  is->cs_handle=fw->cs_handle_thumb;
977  is->thumb=1;
978  is->insn_min_size=2;
979  adr=ADR_CLEAR_THUMB(adr);// ADR used for iteration must not contain thumb bit
980  } else {
981  is->cs_handle=fw->cs_handle_arm;
982  is->thumb=0;
983  is->insn_min_size=4;
984  if(!ADR_IS_ALIGN4(adr)) {
985  fprintf(stderr,"disasm_iter_set: unaligned ARM address 0x%08x\n",adr);
986  is->code=NULL;
987  is->size=0;
988  is->adr=0;
989  return 0;
990  }
991  }
992  uint8_t *p=adr2ptr(fw,adr);
993  if(!p) {
994 // TODO invalid currently allowed, for new
995 // fprintf(stderr,"disasm_iter_set: bad address 0x%08x\n",adr);
996  is->code=NULL; // make first iter fail
997  is->size=0;
998  is->adr=0;
999  return 0;
1000  }
1001  // TODO should maybe mark is.insn invalid?
1002  is->code=p;
1003  is->size=fw->size8 - (p-fw->buf8);
1004  is->adr=adr;
1005  return 1;
1006 }
int find_and_get_var_ldr ( firmware fw,
iter_state_t is,
int  max_search_insns,
int  max_seq_insns,
arm_reg  match_val_reg,
var_ldr_desc_t result 
)

Definiert in Zeile 1557 der Datei firmware_load_ng.c.

1564 {
1565  if(!insn_match_find_next(fw,is,max_search_insns,match_ldr_pc)) {
1566  // printf("find_and_get_var_ldr: LDR PC not found\n");
1567  return 0;
1568  }
1569  var_ldr_desc_t r;
1570  memset(&r,0,sizeof(r));
1571  r.reg_base=is->insn->detail->arm.operands[0].reg;
1572  r.adr_base=LDR_PC2val(fw,is->insn);
1573  int seq_count=1;
1574 
1575  while(seq_count < max_seq_insns) {
1576  // disassembly failed, no match (could ignore..)
1577  if(!disasm_iter(fw,is)) {
1578  return 0;
1579  }
1580  // assume first encountered LDR x,[pc] is the one to use
1581  // give up if we encounter another. Don't know beforehand which reg is base
1582  // NOTE: backward search would allow matching base that eventually ends up in desired reg
1583  if(isLDR_PC(is->insn)) {
1584  // printf("find_and_get_var_ldr: second ldr pc\n");
1585  return 0;
1586  }
1587  seq_count++;
1588  // firmware may use add/sub to get actual firmware base address
1589  if(isADDx_imm(is->insn) || isSUBx_imm(is->insn)) {
1590  if((arm_reg)is->insn->detail->arm.operands[0].reg != r.reg_base) {
1591  continue;
1592  }
1593  if(isADDx_imm(is->insn)) {
1594  r.adj=is->insn->detail->arm.operands[1].imm;
1595  } else {
1596  r.adj=-is->insn->detail->arm.operands[1].imm;
1597  }
1598  if(!disasm_iter(fw,is)) {
1599  return 0;
1600  }
1601  seq_count++;
1602  } else {
1603  r.adj=0;
1604  }
1605  // try to bail out if base reg trashed
1606  // BL, BLX etc will trash r0-r3, B, BX go somewhere else
1607  // only break on unconditional - optimistic, could produce incorrect results
1608  // can't account for branches into searched code
1609  if((r.reg_base >= ARM_REG_R0 && r.reg_base <= ARM_REG_R3)
1610  && (is->insn->id == ARM_INS_BL || is->insn->id == ARM_INS_BLX
1611  || is->insn->id == ARM_INS_B || is->insn->id == ARM_INS_BX)
1612  && is->insn->detail->arm.cc == ARM_CC_AL) {
1613  // printf("find_and_get_var_ldr: bail B*\n");
1614  return 0;
1615  }
1616  if(is->insn->id != ARM_INS_LDR || (arm_reg)is->insn->detail->arm.operands[1].reg != r.reg_base) {
1617  // other operation on with base reg as first operand, give up
1618  // simplistic, many other things could affect reg
1619  if(is->insn->detail->arm.operands[0].type == ARM_OP_REG && (arm_reg)is->insn->detail->arm.operands[0].reg == r.reg_base) {
1620  // printf("find_and_get_var_ldr: bail mod base\n");
1621  return 0;
1622  }
1623  continue;
1624  }
1625  r.reg_val = is->insn->detail->arm.operands[0].reg;
1626  if(match_val_reg != ARM_REG_INVALID && (r.reg_val != match_val_reg)) {
1627  continue;
1628  }
1629  r.off = is->insn->detail->arm.operands[1].mem.disp;
1630  r.adr_adj = r.adr_base + r.adj;
1631  r.adr_final = r.adr_adj + r.off;
1632  memcpy(result,&r,sizeof(r));
1633  return 1;
1634  }
1635  return 0;
1636 }
int find_bytes_all ( firmware fw,
const void *  bytes,
size_t  len,
uint32_t  adr,
uint32_t result,
int  maxmatch 
)

Definiert in Zeile 174 der Datei firmware_load_ng.c.

175 {
176  int i;
177  for(i=0,adr=find_next_bytes_range(fw,bytes,len,0,0); adr && (i < max); adr=find_next_bytes_range(fw,bytes,len,adr+len,0),i++) {
178  result[i] = adr;
179  }
180  return i;
181 }
int find_const_ref_call ( firmware fw,
iter_state_t is,
int  max_search_bytes,
int  max_gap_insns,
arm_reg  match_reg,
uint32_t  val 
)

Definiert in Zeile 1701 der Datei firmware_load_ng.c.

1708 {
1709  return find_const_ref_match(fw,is,max_search_bytes,max_gap_insns,match_reg,val,match_bl_blximm,FIND_CONST_REF_MATCH_ANY);
1710 }
int find_const_ref_match ( firmware fw,
iter_state_t is,
int  max_search_bytes,
int  max_gap_insns,
arm_reg  match_reg,
uint32_t  val,
const insn_match_t match,
int  match_type 
)

Definiert in Zeile 1644 der Datei firmware_load_ng.c.

1652 {
1653  if(match_reg < ARM_REG_R0 || match_reg > ARM_REG_R3) {
1654  fprintf(stderr,"find_const_ref_match: invalid match_reg %d\n",match_reg);
1655  return 0;
1656  }
1657  if(max_gap_insns >= ADR_HIST_SIZE) {
1658  fprintf(stderr,"find_const_ref_match: invalid max_gap_insns %d\n",max_gap_insns);
1659  return 0;
1660  }
1661  int (*match_fn)(firmware *fw, iter_state_t *is, int max_insns, const insn_match_t *match);
1662  if(match_type == FIND_CONST_REF_MATCH_SEQ) {
1663  match_fn = insn_match_find_next_seq;
1664  } else if(match_type == FIND_CONST_REF_MATCH_ANY){
1665  match_fn = insn_match_find_next;
1666  } else {
1667  fprintf(stderr,"find_const_ref_match: invalid match_type %d\n",match_type);
1668  return 0;
1669  }
1670  // search for a ref to constant
1671  while(fw_search_insn(fw,is,search_disasm_const_ref,val,NULL,(uint32_t)(is->adr+max_search_bytes))) {
1672  //printf("find_const_ref_match: match str 0x%"PRIx64"\n",is->adr);
1673  uint32_t next_adr = (uint32_t)is->adr;
1674  // search for next bl / blx
1675  // could search include b for tail calls, but hard to distinguish
1676  if(match_fn(fw,is,max_gap_insns,match)) {
1677  uint32_t reg_num = match_reg - ARM_REG_R0;
1678  uint32_t reg_bit = 1 << reg_num;
1679  uint32_t regs[4];
1680  //printf("find_const_ref_match: match insn 0x%"PRIx64"\n",reg_num,is->adr);
1681  // backtrack to find out if const ref ends up in desired reg
1682  if((get_call_const_args(fw,is,max_gap_insns,regs)&reg_bit)==reg_bit) {
1683  //printf("find_const_ref_match: match reg r%d 0x%"PRIx64"\n",reg_num,is->adr);
1684  if(regs[reg_num] == val) {
1685  return iter_state_adr(is);
1686  }
1687  }
1688  }
1689  // not matched, restore is and advance one instruction
1690  disasm_iter_init(fw,is,next_adr | is->thumb);
1691  }
1692  return 0;
1693 }
uint32_t find_last_call_from_func ( firmware fw,
iter_state_t is,
int  min_insns,
int  max_insns 
)

Definiert in Zeile 1787 der Datei firmware_load_ng.c.

1788 {
1789  int push_found=0;
1790  uint32_t last_adr=0;
1791  int count;
1792  for(count=0; count < max_insns; count++) {
1793  if(!disasm_iter(fw,is)) {
1794  fprintf(stderr,"find_last_call_from_func: disasm failed 0x%"PRIx64"\n",is->adr);
1795  return 0;
1796  }
1797  // TODO could match push regs with pop
1798  if(isPUSH_LR(is->insn)) {
1799  // already found a PUSH LR, probably in new function
1800  if(push_found) {
1801  //printf("find_last_call_from_func: second push pc 0x%"PRIx64"\n",is->adr);
1802  return 0;
1803  }
1804  push_found=1;
1805  continue;
1806  }
1807  // ignore everything before push (could be some mov/ldr, shouldn't be any calls)
1808  // TODO may want to allow starting in the middle of a function
1809  if(!push_found) {
1810  continue;
1811  }
1812  // found a potential call, store
1813  if(insn_match_any(is->insn,match_bl_blximm) && count >= min_insns) {
1814  //printf("find_last_call_from_func: found call 0x%"PRIx64"\n",is->adr);
1815  last_adr=get_branch_call_insn_target(fw,is);
1816  continue;
1817  }
1818  // found pop PC, can only be stored call if present
1819  if(isPOP_PC(is->insn)) {
1820  // printf("find_last_call_from_func: found pop PC 0x%"PRIx64"\n",is->adr);
1821  if(last_adr) {
1822  return last_adr;
1823  }
1824  // no call found, or not found within min
1825  return 0;
1826  }
1827  // found pop LR, check if next is allowed tail sequence followed by unconditional B
1828  if(isPOP_LR(is->insn)) {
1829  // hit func end with less than min, no match
1830  if(count < min_insns) {
1831  // printf("find_last_call_from_func: pop before min 0x%"PRIx64"\n",is->adr);
1832  return 0;
1833  }
1834  if(!disasm_iter(fw,is)) {
1835  fprintf(stderr,"find_last_call_from_func: disasm failed 0x%"PRIx64"\n",is->adr);
1836  return 0;
1837  }
1838  // allow instructions likely to appear between pop and tail call
1839  // MOV or LDR to r0-r3
1840  // others are possible e.g arithmetic or LDR r4,=const; LDR r0,[r4, #offset]
1841  const insn_match_t match_tail[]={
1843 // MOVS unlikely to be valid, though possible if followed by additional conditional instructions
1844 // in any case, want to match capstone 4 behavior
1845 #if CS_API_MAJOR < 4
1847 #endif
1848 
1850  {ARM_INS_ENDING}
1851  };
1852  while(insn_match_any(is->insn,match_tail) && count < max_insns) {
1853  if(!disasm_iter(fw,is)) {
1854  fprintf(stderr,"find_last_call_from_func: disasm failed 0x%"PRIx64"\n",is->adr);
1855  return 0;
1856  }
1857  count++;
1858  }
1859  if(is->insn->id == ARM_INS_B && is->insn->detail->arm.cc == ARM_CC_AL) {
1860  return get_branch_call_insn_target(fw,is);
1861  }
1862  // don't go more than one insn after pop (could be more, but uncommon)
1863  // printf("find_last_call_from_func: more than one insn after pop 0x%"PRIx64"\n",is->adr);
1864  return 0;
1865  }
1866  // found another kind of ret, give up
1867  if(isRETx(is->insn)) {
1868  // printf("find_last_call_from_func: other ret 0x%"PRIx64"\n",is->adr);
1869  return 0;
1870  }
1871  }
1872  // printf("find_last_call_from_func: no match in range 0x%"PRIx64"\n",is->adr);
1873  return 0;
1874 }
uint32_t find_next_bytes_range ( firmware fw,
const void *  bytes,
size_t  len,
uint32_t  start_adr,
uint32_t  max_adr 
)

Definiert in Zeile 132 der Datei firmware_load_ng.c.

133 {
134  if(!start_adr) {
135  start_adr = fw->base;
136  }
137  if(start_adr < fw->base || start_adr >= fw->base + fw->size8) {
138  fprintf(stderr,"find_next_bytes_range invalid start_adr 0x%08x\n",start_adr);
139  return 0;
140  }
141  if(!max_adr) {
142  max_adr = fw->base + fw->size8-1;
143  }
144  if(max_adr < fw->base || max_adr >= fw->base + fw->size8) {
145  fprintf(stderr,"find_next_bytes_range invalid max_adr 0x%08x\n",max_adr);
146  return 0;
147  }
148  int end_k = (max_adr - fw->base);
149  BufRange *p = getBufRangeForIndex(fw,(start_adr - fw->base)/4);
150  if(!p) {
151  return 0;
152  }
153  int k = start_adr - fw->base;
154 
155  while (k < end_k)
156  {
157  for (; k < (p->off + p->len)*4; k++)
158  {
159  if (memcmp(fw->buf8+k,bytes,len) == 0) {
160  return fw->base+k;
161  }
162  }
163  p = p->next;
164  if(!p) {
165  break;
166  }
167  k = p->off*4;
168  }
169  return 0;
170 }
uint32_t find_next_str_bytes ( firmware fw,
const char *  str,
uint32_t  adr 
)

Definiert in Zeile 215 der Datei firmware_load_ng.c.

216 {
217  // +1 to include the null in memcmp
218  return find_next_bytes_range(fw,str,strlen(str)+1,adr,0);
219 }
uint32_t find_next_str_bytes_main_fw ( firmware fw,
const char *  str,
uint32_t  adr 
)

Definiert in Zeile 196 der Datei firmware_load_ng.c.

197 {
198  // max is end of fw code + 4096, assuming it fits in fw
199  // while early code could technically load from base - 1k, unlikely
200  uint32_t max_adr;
201  if(fw->base + fw->size8 - 4096 > fw->rom_code_search_max_adr) {
202  max_adr = fw->rom_code_search_max_adr + 4096;
203  } else {
204  max_adr = fw->base + fw->size8;
205  }
206  return find_next_bytes_range(fw,str,strlen(str)+1,adr,max_adr);
207 }
uint32_t find_next_substr_bytes ( firmware fw,
const char *  str,
uint32_t  adr 
)

Definiert in Zeile 183 der Datei firmware_load_ng.c.

184 {
185  //fprintf(stderr,"find_next_substr_bytes 0x%08x\n",adr);
186  // strlen excludes null
187  return find_next_bytes_range(fw,str,strlen(str),adr,0);
188 }
int find_Nth_str ( firmware fw,
char *  str,
int  N 
)

Definiert in Zeile 642 der Datei firmware_load.c.

643 {
644  int nlen = strlen(str);
645  uint32_t nm0 = *((uint32_t*)str);
646  uint32_t *p;
647  int j;
648 
649  BufRange *br = fw->br;
650  while (br)
651  {
652  for (p = br->p, j = 0; j < br->len - nlen/4; j++, p++)
653  {
654  if ((nm0 == *p) && ((nlen<=4) || (memcmp(p+1,str+4,nlen-4) == 0)) )
655  {
656  if (--N == 0)
657  return j+br->off;
658  }
659  }
660  br = br->next;
661  }
662 
663  return -1;
664 }
int find_str ( firmware fw,
char *  str 
)

Definiert in Zeile 666 der Datei firmware_load.c.

667 {
668  return find_Nth_str(fw, str, 1);
669 }
uint32_t find_str_bytes ( firmware fw,
const char *  str 
)

Definiert in Zeile 223 der Datei firmware_load_ng.c.

224 {
225  return find_next_str_bytes(fw,str,fw->base);
226 }
uint32_t find_str_bytes_main_fw ( firmware fw,
const char *  str 
)

Definiert in Zeile 210 der Datei firmware_load_ng.c.

211 {
213 }
uint32_t find_u32_adr ( firmware fw,
uint32_t  val,
uint32_t  start 
)

Definiert in Zeile 405 der Datei firmware_load_ng.c.

406 {
407  return find_u32_adr_range(fw,val,start, fw->base + (fw->size8 -4));
408 }
uint32_t find_u32_adr_range ( firmware fw,
uint32_t  val,
uint32_t  start,
uint32_t  maxadr 
)

Definiert in Zeile 373 der Datei firmware_load_ng.c.

374 {
375  // TODO
376  if(start == 0) {
377  start=fw->base;
378  }
379  if(start & 3) {
380  fprintf(stderr,"find_u32_adr unaligned start 0x%08x\n",start);
381  return 0;
382  }
383  uint32_t *p=(uint32_t *)adr2ptr(fw,start);
384  if(!p) {
385  fprintf(stderr,"find_u32_adr bad start 0x%08x\n",start);
386  return 0;
387  }
388  uint32_t *p_end;
389  if(maxadr) {
390  p_end = (uint32_t *)adr2ptr(fw,maxadr);
391  } else {
392  p_end = fw->buf32 + fw->size32 - 1;
393  }
394  // TODO should use buf ranges
395  while(p<=p_end) {
396  if(*p==val) {
397  return ptr2adr(fw,(uint8_t *)p);
398  }
399  p++;
400  }
401  return 0;
402 }
int firmware_init_capstone ( firmware fw)

Definiert in Zeile 2396 der Datei firmware_load_ng.c.

2397 {
2398  if (cs_open(CS_ARCH_ARM, CS_MODE_ARM, &fw->cs_handle_arm) != CS_ERR_OK) {
2399  fprintf(stderr,"cs_open ARM failed\n");
2400  return 0;
2401  }
2402  cs_option(fw->cs_handle_arm, CS_OPT_DETAIL, CS_OPT_ON);
2403  if (cs_open(CS_ARCH_ARM, CS_MODE_THUMB, &fw->cs_handle_thumb) != CS_ERR_OK) {
2404  fprintf(stderr,"cs_open thumb failed\n");
2405  return 0;
2406  }
2407  cs_option(fw->cs_handle_thumb, CS_OPT_DETAIL, CS_OPT_ON);
2408  fw->is=disasm_iter_new(fw,0);
2409  do_blx_check(fw);
2410  return 1;
2411 }
void firmware_init_data_ranges ( firmware fw)

highest known first copied ram code 0x01900000

Definiert in Zeile 2553 der Datei firmware_load_ng.c.

2554 {
2555 //TODO maybe should return status
2556  uint32_t src_start, dst_start, dst_end;
2557  uint32_t data_found_copy = 0;
2558 
2559  // start at fw start + 12 (32 bit jump, gaonisoy)
2560  iter_state_t *is=disasm_iter_new(fw, fw->base + fw->main_offs + 12 + fw->thumb_default);
2561 
2562  fw->data_init_start=0;
2563  fw->data_start=0;
2564  fw->data_len=0;
2565 
2566  fw->memisostart=0;
2567 
2568  int base2_found=0;
2569  int base3_found=0;
2570 
2571  // TODO pre-d6 ROMs have a lot more stuff before first copy
2572  int max_search=100;
2573  while(find_startup_copy(fw,is,max_search,&src_start,&dst_start,&dst_end)) {
2574  // all known copied code is 3f1000 or higher, guess data
2575  if(dst_start < 0x100000) {
2576  // fprintf(stderr, "data? @0x%"PRIx64" 0x%08x-0x%08x from 0x%08x\n",is->adr,dst_start,dst_end,src_start);
2577  if(fw->data_init_start) {
2578  fprintf(stderr,"firmware_init_data_ranges: data already found, unexpected start 0x%08x src 0x%08x end 0x%08x\n",
2579  dst_start,src_start,dst_end);
2580  continue;
2581  }
2582 
2583  // not a known value, warn
2584  if(dst_start != 0x1900 && dst_start != 0x8000) {
2585  fprintf(stderr,"firmware_init_data_ranges: guess unknown ROM data_start 0x%08x src 0x%08x end 0x%08x\n",
2586  dst_start,src_start,dst_end);
2587  }
2588  fw->data_init_start=src_start;
2589  fw->data_start=dst_start;
2590  fw->data_len=dst_end-dst_start;
2591  fw_add_adr_range(fw,dst_start,dst_end,src_start, ADR_RANGE_INIT_DATA, ADR_RANGE_FL_NONE);
2592  data_found_copy=is->adr;
2593  } else if(dst_start < 0x08000000) {
2594  // fprintf(stderr,"code1? @0x%"PRIx64" 0x%08x-0x%08x from 0x%08x\n",is->adr,dst_start,dst_end,src_start);
2595  if(base2_found) {
2596  fprintf(stderr,"firmware_init_data_ranges: base2 already found, unexpected start 0x%08x src 0x%08x end 0x%08x\n",
2597  dst_start,src_start,dst_end);
2598  continue;
2599  }
2600  base2_found=1;
2601  // known values
2602  if( dst_start != 0x003f1000 &&
2603  dst_start != 0x00431000 &&
2604  dst_start != 0x00471000 &&
2605  dst_start != 0x00685000 &&
2606  dst_start != 0x00671000 &&
2607  dst_start != 0x006b1000 &&
2608  dst_start != 0x010c1000 &&
2609  dst_start != 0x010e1000 &&
2610  dst_start != 0x01900000) {
2611  fprintf(stderr,"firmware_init_data_ranges: guess unknown base2 0x%08x src 0x%08x end 0x%08x\n",
2612  dst_start,src_start,dst_end);
2613  }
2614  fw_add_adr_range(fw,dst_start,dst_end,src_start,ADR_RANGE_RAM_CODE, ADR_RANGE_FL_NONE);
2615  } else { // know < ROM based on match, assume second copied code
2616  // fprintf(stderr, "code2? @0x%"PRIx64" 0x%08x-0x%08x from 0x%08x\n",is->adr,dst_start,dst_end,src_start);
2617  if(base3_found) {
2618  fprintf(stderr,"firmware_init_data_ranges: base3 already found, unexpected start 0x%08x src 0x%08x end 0x%08x\n",
2619  dst_start,src_start,dst_end);
2620  continue;
2621  }
2622  base3_found=1;
2623  if(dst_start != 0xbfe10800 && // known digic 6 value (g5x)
2624  dst_start != 0xdffc4900) { // known digic 7 value (m5)
2625  fprintf(stderr,"firmware_init_data_ranges: guess unknown base3 0x%08x src 0x%08x end 0x%08x\n",
2626  dst_start,src_start,dst_end);
2627  }
2628  fw_add_adr_range(fw,dst_start,dst_end,src_start,ADR_RANGE_RAM_CODE, ADR_RANGE_FL_TCM);
2629  }
2630  if(fw->data_start && base2_found && base3_found) {
2631  break;
2632  }
2633  // after first, shorter search range in between copies
2634  max_search=16;
2635  }
2636 
2637  // look for BSS init after last found copy
2638  if(data_found_copy) {
2639  int count=0;
2640  uint32_t *eptr=NULL;
2641  uint32_t *dptr=NULL;
2642  disasm_iter_init(fw,is,(data_found_copy-4) | fw->thumb_default);
2643  while(disasm_iter(fw,is) && count < 20) {
2644  uint32_t *pv=LDR_PC2valptr(fw,is->insn);
2645  // not an LDR pc, reset;
2646  if(!pv) {
2647  //dptr=eptr=NULL;
2648  } else if(!dptr) {
2649  // TODO older firmwares use reg with ending value from DATA copy
2650  // should be equal to end pointer of data
2651  if(*pv == fw->data_start + fw->data_len) {
2652  dptr=pv;
2653  }
2654  } else if(!eptr) {
2655  if(*pv < fw->base) {
2656  if(*pv != fw->data_start + fw->data_len) {
2657  eptr=pv;
2658  }
2659  } else { // dest end address in ROM, reset
2660  eptr=dptr=NULL;
2661  }
2662  }
2663  if(dptr && eptr) {
2664  // fprintf(stderr, "bss? @0x%"PRIx64" 0x%08x-0x%08x\n",is->adr,*dptr,*eptr);
2665  fw->memisostart=*eptr;
2666  break;
2667  }
2668  count++;
2669  }
2670  }
2671 
2672  find_exception_vec(fw,is);
2673 
2674  // if data found, adjust default code search range
2675  // TODO could use copied code regions too, but after data on known firmwares
2676  if(fw->data_start) {
2678  }
2679  // if dryos version string found, use as search limit
2680  if(fw->dryos_ver_adr) {
2681  if(fw->dryos_ver_adr < fw->rom_code_search_max_adr) {
2683  }
2684  }
2685  disasm_iter_free(is);
2686 }
void firmware_load ( firmware fw,
const char *  filename,
uint32_t  base_adr,
int  fw_arch 
)

Definiert in Zeile 2267 der Datei firmware_load_ng.c.

2268 {
2269  FILE *f = fopen(filename, "rb");
2270  if (f == NULL)
2271  {
2272  fprintf(stderr,"Error opening %s\n",filename);
2273  exit(1);
2274  }
2275  fseek(f,0,SEEK_END);
2276  fw->size8 = ftell(f);
2277  fseek(f,0,SEEK_SET);
2278  // dumps should be an integral number of 32 bit words
2279  // ensures accessing as 32 bit ints safe
2280  if(fw->size8&3) {
2281  fprintf(stderr,"WARNING: dump size %d is not divisible by 4, truncating\n",fw->size8);
2282  fw->size8 &= ~3;
2283  }
2284 
2285  // adjust to ensure base_adr + size doesn't overflow
2286  if((int)(0xFFFFFFFF - base_adr) < fw->size8) {
2287  fprintf(stderr,"adjusted dump size 0x%08x->",fw->size8);
2288  fw->size8 = 0xFFFFFFFC - base_adr;
2289  fprintf(stderr,"0x%08x\n",fw->size8);
2290  }
2291 
2292  fw->arch=fw_arch;
2293  fw->size32=fw->size8/4;
2294 
2295  fw->base = base_adr;
2296 
2297  fw->buf8 = malloc(fw->size8);
2298  if(!fw->buf8) {
2299  fprintf(stderr,"malloc %d failed\n",fw->size8);
2300  exit(1);
2301  }
2302  fread(fw->buf8, 1, fw->size8, f);
2303  fclose(f);
2304  findRanges(fw);
2305 
2306  fw->adr_range_count=0;
2307  // add ROM
2309 
2310  fw->main_offs = 0;
2311  int k = find_str(fw, "gaonisoy");
2312  // assume firmware start is 32 bit jump over goanisoy
2313  if(k == -1) {
2314  // suppress warning on vxworks, main firmware start is always offset 0
2315  if(find_str(fw,"VxWorks") == -1) {
2316  fprintf(stderr,"WARNING gaonisoy string not found, assuming code start offset 0\n");
2317  }
2318  } else if (k != 1) {
2319  // check at 0x20004 - note doesn't just use offset of first gaonisoy, because could be ref'd in romstarter
2320  if(fw_memcmp(fw,fw->base+0x20004,"gaonisoy",8) == 0) {
2321  fw->main_offs = 0x20000;
2322  } else if (fw_memcmp(fw,fw->base+0x10004,"gaonisoy",8) == 0) { // newer armv5 firmwares base ff81000 start at ff820000
2323  fw->main_offs = 0x10000;
2324  } else {
2325  fprintf(stderr,"WARNING code start offset not found, assuming 0\n");
2326  }
2327  }
2328 
2329  fw->rom_code_search_min_adr = fw->base + fw->main_offs; // 0 if not found
2330  fw->rom_code_search_max_adr=fw->base+fw->size8 - 4; // default == end of fw, may be adjusted by firmware_init_data_ranges
2331 
2332  find_dryos_vers(fw);
2333 
2334  fw->firmware_ver_str = 0;
2335  k = find_str(fw, "Firmware Ver ");
2336  if (k != -1)
2337  {
2338  fw->firmware_ver_str = (char *)fw->buf8 + k*4;
2339  }
2340  // set expected instruction set
2341  if(fw->arch==FW_ARCH_ARMv5) {
2342  fw->thumb_default = 0;
2343  } else if(fw->arch==FW_ARCH_ARMv7) {
2344  fw->thumb_default = 1;
2345  } else {
2346  fprintf(stderr,"firmware_init_capstone: invalid arch\n");
2347  }
2348 }
void firmware_unload ( firmware fw)

Definiert in Zeile 2689 der Datei firmware_load_ng.c.

2690 {
2691  if(!fw) {
2692  return;
2693  }
2694  if(fw->is) {
2695  disasm_iter_free(fw->is);
2696  }
2697  if(fw->cs_handle_arm) {
2698  cs_close(&fw->cs_handle_arm);
2699  }
2700  if(fw->cs_handle_thumb) {
2701  cs_close(&fw->cs_handle_thumb);
2702  }
2703  free(fw->buf8);
2704  memset(fw,0,sizeof(firmware));
2705 }
void fw_add_adr_range ( firmware fw,
uint32_t  start,
uint32_t  end,
uint32_t  src_start,
int  type,
int  flags 
)

Definiert in Zeile 2164 der Datei firmware_load_ng.c.

2165 {
2166  if(fw->adr_range_count == FW_MAX_ADR_RANGES) {
2167  fprintf(stderr,"fw_add_adr_range: FW_MAX_ADR_RANGES hit\n");
2168  return;
2169  }
2170  if(src_start < fw->base) {
2171  fprintf(stderr,"fw_add_adr_range: src_start 0x%08x < base 0x%08x\n",src_start,fw->base);
2172  return;
2173  }
2174  if(src_start >= fw->base+fw->size8) {
2175  fprintf(stderr,"fw_add_adr_range: src_start 0x%08x outside dump end 0x%08x\n",src_start,fw->base+fw->size8);
2176  return;
2177  }
2178  if(end <= start) {
2179  fprintf(stderr,"fw_add_adr_range: end 0x%08x <= start 0x%08x\n",end,start);
2180  return;
2181  }
2182  uint32_t len=end-start;
2183  if(len > 0xFFFFFFFF - src_start) {
2184  fprintf(stderr,"fw_add_adr_range: range too long %d\n",len);
2185  return;
2186  }
2187  if(len > fw->size8 - (start - fw->base)) {
2188  fprintf(stderr,"fw_add_adr_range: range outside of dump %d\n",len);
2189  return;
2190  }
2191  adr_range_t *r=&fw->adr_ranges[fw->adr_range_count];
2192  // TODO some firmware copies (i.e. g5x code 2) may end on non-word aligned address even though copy is words
2193  r->start=start;
2194  r->src_start=src_start;
2195  r->bytes=len;
2196  r->type=type;
2197  r->flags=flags;
2198  r->buf=fw->buf8 + (r->src_start - fw->base);
2199 
2200  fw->adr_range_count++;
2201 }
int fw_disasm_iter ( firmware fw)

Definiert in Zeile 1055 der Datei firmware_load_ng.c.

1056 {
1057  return disasm_iter(fw,fw->is);
1058 }
int fw_disasm_iter_single ( firmware fw,
uint32_t  adr 
)

Definiert in Zeile 1062 der Datei firmware_load_ng.c.

1063 {
1064  fw_disasm_iter_start(fw,adr);
1065  return fw_disasm_iter(fw);
1066 }
int fw_disasm_iter_start ( firmware fw,
uint32_t  adr 
)

Definiert in Zeile 1049 der Datei firmware_load_ng.c.

1050 {
1051  return disasm_iter_init(fw,fw->is,adr);
1052 }
int fw_memcmp ( firmware fw,
uint32_t  adr,
const void *  cmp,
size_t  n 
)

Definiert in Zeile 422 der Datei firmware_load_ng.c.

423 {
424  uint32_t *p=(uint32_t *)adr2ptr(fw,adr);
425  if(!p) {
426  return 1;
427  }
428  if(n >= fw->size8 - (adr - fw->base)) {
429  return 1;
430  }
431  return memcmp(p,cmp,n);
432 }
int fw_search_bytes ( firmware fw,
search_bytes_fn  func 
)

Definiert in Zeile 2145 der Datei firmware_load_ng.c.

2146 {
2147  BufRange *p = fw->br;
2148  while (p)
2149  {
2150  int k;
2151  for (k = p->off*4; k < (p->off + p->len)*4; k++)
2152  {
2153  if (func(fw,k))
2154  return 1;
2155  }
2156  p = p->next;
2157  }
2158  return 0;
2159 }
uint32_t fw_search_insn ( firmware fw,
iter_state_t is,
search_insn_fn  f,
uint32_t  v1,
void *  udata,
uint32_t  adr_end 
)

Definiert in Zeile 1096 der Datei firmware_load_ng.c.

1097 {
1098  uint32_t adr_start=is->adr;
1099  adr_range_t *r_start=adr_get_range(fw,adr_start);
1100  if(!r_start) {
1101  fprintf(stderr,"fw_search_insn: invalid start address 0x%08x\n",adr_start);
1102  return 0;
1103  }
1104 
1105  // default to end of start range
1106  if(!adr_end) {
1107  if(r_start->type == ADR_RANGE_ROM) {
1108  adr_end = fw->rom_code_search_max_adr;
1109  } else {
1110  adr_end=r_start->start + r_start->bytes - is->insn_min_size;
1111  }
1112  }
1113  adr_range_t *r_end=adr_get_range(fw,adr_end);
1114 
1115  if(!r_end) {
1116  fprintf(stderr,"fw_search_insn: invalid end address 0x%08x\n",adr_end);
1117  return 0;
1118  }
1119  // ignore thumb bit on end adr
1120  adr_end=ADR_CLEAR_THUMB(adr_end);
1121 
1122  if((r_start != r_end) || (adr_end < adr_start)) {
1123  fprintf(stderr,"fw_search_insn: invalid address range 0x%08x 0x%08x\n",adr_start,adr_end);
1124  return 0;
1125  }
1126 
1127  uint32_t adr=adr_start;
1128  // don't bother with buf ranges for RAM code
1129  if(r_start->type != ADR_RANGE_ROM) {
1130  while(adr < adr_end) {
1131  if(disasm_iter(fw,is)) {
1132  uint32_t r=f(fw,is,v1,udata);
1133  if(r) {
1134  return r;
1135  }
1136  adr=(uint32_t)is->adr; // adr was updated by iter or called sub
1137  } else {
1138  // disassembly failed
1139  // increment by minimum instruction size and re-init
1140  adr=adr+is->insn_min_size;
1141  if(!disasm_iter_init(fw,is,adr|is->thumb)) {
1142  fprintf(stderr,"fw_search_insn: disasm_iter_init failed\n");
1143  return 0;
1144  }
1145  }
1146  }
1147  return 0;
1148  }
1149  BufRange *br=fw->br;
1150  // TODO might want to (optionally?) turn off details? For now, caller can set, doesn't seem to help perf much
1151  // TODO when searching ROM, could skip over RAM copied areas (currently just limit default range)
1152  while(br && adr < adr_end) {
1153  uint32_t *p_adr=(uint32_t *)adr2ptr(fw,(uint32_t)adr);
1154  uint32_t *br_end = br->p + br->len;
1155  uint32_t adr_chunk_end = ptr2adr(fw,(uint8_t*)br_end);
1156  if(adr_end < adr_chunk_end) {
1157  adr_chunk_end = adr_end;
1158  }
1159  // address is before start of current range, adjust
1160  if(p_adr < br->p) {
1161  adr=ptr2adr(fw,(uint8_t *)br->p);
1162  if(!disasm_iter_init(fw,is,(uint32_t)adr | is->thumb)) {
1163  return 0;
1164  }
1165  p_adr=(uint32_t *)adr2ptr(fw,(uint32_t)adr);
1166  }
1167  //printf("br:0x%08x-0x%08x\n",ptr2adr(fw,(uint8_t *)br->p),ptr2adr(fw,(uint8_t *)(br->p+br->len)));
1168  while(adr < adr_chunk_end) {
1169  if(disasm_iter(fw,is)) {
1170  uint32_t r=f(fw,is,v1,udata);
1171  if(r) {
1172  return r;
1173  }
1174  adr=(uint32_t)is->adr; // adr was updated by iter or called sub
1175  } else {
1176  // disassembly failed. cs_disarm_iter does not update address
1177  // increment by half word and re-init
1178  adr=adr+is->insn_min_size;
1179  if(!disasm_iter_init(fw,is,adr|is->thumb)) {
1180  fprintf(stderr,"fw_search_insn: disasm_iter_init failed\n");
1181  return 0;
1182  }
1183  }
1184  }
1185  // next range
1186  br=br->next;
1187  }
1188  return 0;
1189 }
uint32_t fw_u32 ( firmware fw,
uint32_t  adr 
)

Definiert in Zeile 411 der Datei firmware_load_ng.c.

412 {
413  uint32_t *p=(uint32_t *)adr2ptr(fw,adr);
414  if(!p) {
415  fprintf(stderr,"fw_u32 bad adr 0x%08x\n",adr);
416  return 0;
417  }
418  return *p;
419 }
uint32_t get_branch_call_insn_target ( firmware fw,
iter_state_t is 
)

Definiert in Zeile 1502 der Datei firmware_load_ng.c.

1503 {
1504  uint32_t adr=B_BL_target(fw,is->insn);
1505  if(adr) {
1506  return (adr | is->thumb);
1507  }
1508  // CBx only exists in thumb
1509  if(is->thumb) {
1510  adr=CBx_target(fw,is->insn);
1511  if(adr) {
1512  return ADR_SET_THUMB(adr);
1513  }
1514  }
1515 
1516  adr=BLXimm_target(fw,is->insn);
1517  if(adr) {
1518  if(is->thumb) {
1519  return adr;
1520  } else {
1521  return adr | is->thumb;
1522  }
1523  }
1524 
1525  adr=LDR_PC_PC_target(fw,is->insn);
1526  if(adr) {
1527  return adr;
1528  }
1529  adr=BX_PC_target(fw,is->insn);
1530  if(adr) {
1531  // bx swaps mode
1532  if(is->thumb) {
1533  return ADR_CLEAR_THUMB(adr);
1534  } else {
1535  return ADR_SET_THUMB(adr);
1536  }
1537  }
1538  return 0;
1539 }
int get_call_const_args ( firmware fw,
iter_state_t is_init,
int  max_backtrack,
uint32_t res 
)

Definiert in Zeile 1315 der Datei firmware_load_ng.c.

1316 {
1317  int i;
1318  /*
1319  static int dbg_count=0;
1320  if(is_init->insn->address==...) {
1321  dbg_count=1;
1322  } else {
1323  dbg_count=0;
1324  }
1325  */
1326 
1327  // init regs to zero (to support adds etc)
1328  for (i=0;i<4;i++) {
1329  res[i]=0;
1330  }
1331 
1332  // count includes current instruction (i.e. BL of call)
1333  if(is_init->ah.count <= 1) {
1334  return 0;
1335  }
1336  if(is_init->ah.count - 1 < max_backtrack) {
1337  /*
1338  if(dbg_count > 0) {
1339  printf("max_backtrack %d hist count %d\n",max_backtrack,is_init->ah.count);
1340  }
1341  */
1342  max_backtrack = is_init->ah.count-1;
1343  }
1344  uint32_t found_bits=0; // registers with known const values
1345  uint32_t known_bits=0; // registers with some value
1346 
1347  for(i=1;i<=max_backtrack && known_bits !=0xf;i++) {
1348  // TODO going backwards and calling start each time inefficient
1349  // forward could also find multi-instruction constants in some cases (e.g mov + add, movw + movt)
1350  fw_disasm_iter_single(fw,adr_hist_get(&is_init->ah,i)); // thumb state comes from hist
1351  /*
1352  if(dbg_count > 0) {
1353  printf("backtrack %d:%d ",dbg_count,i);
1354  printf("%"PRIx64" %s %s\n",fw->is->insn->address,fw->is->insn->mnemonic, fw->is->insn->op_str);
1355  }
1356  */
1357  arm_insn insn_id = fw->is->insn->id;
1358  // BL, BLX etc will trash r0-r3
1359  // only break on unconditional - optimistic, could produce incorrect results
1360  if((insn_id == ARM_INS_BL || insn_id == ARM_INS_BLX
1361  // B/BX could mean execution goes somewhere totally different, but in practice it often just skipping over a word of data...
1362  /*|| insn_id == ARM_INS_B || insn_id == ARM_INS_BX*/)
1363  && fw->is->insn->detail->arm.cc == ARM_CC_AL) {
1364  break;
1365  }
1366 
1367  // if the first op isn't REG, continue
1368  // TODO lots of instructions could affect reg even if not first op
1369  if(fw->is->insn->detail->arm.operands[0].type != ARM_OP_REG) {
1370  continue;
1371  }
1372  arm_reg rd = fw->is->insn->detail->arm.operands[0].reg;
1373  // capstone arm.h regs enum R0-R12 are ordered
1374  // enum has entries before R0
1375  if(rd < ARM_REG_R0 || rd > ARM_REG_R3) {
1376  continue;
1377  }
1378 
1379  int rd_i = rd - ARM_REG_R0;
1380  uint32_t rd_bit = 1 << rd_i;
1381  // if we don't already have something for this reg
1382  if(!(known_bits & rd_bit)) {
1383  // know something has been done to this reg
1384  // note doesn't account for conditionals
1385  known_bits |=rd_bit;
1386  // is it an LDR
1387  uint32_t *pv=LDR_PC2valptr(fw,fw->is->insn);
1388  if(pv) {
1389  res[rd_i] += *pv;
1390 // if(dbg_count) printf("found ldr r%d,=0x%08x\n",rd_i,res[rd_i]);
1391  found_bits |=rd_bit;
1392  continue;
1393  }
1394  uint32_t v=ADRx2adr(fw,fw->is->insn); // assumes ADR doesn't generate 0, probably safe
1395  if(v) {
1396  res[rd_i] += v;
1397 // if(dbg_count) printf("found adrx r%d,0x%08x\n",rd_i,res[rd_i]);
1398  found_bits |=rd_bit;
1399  continue;
1400  }
1401  // immediate MOV note MOVT combinations, not accounted for, some handled ADDs below
1402  if( IS_INSN_ID_MOVx(insn_id)
1403  && fw->is->insn->detail->arm.operands[1].type == ARM_OP_IMM) {
1404  res[rd_i] += fw->is->insn->detail->arm.operands[1].imm;
1405 // if(dbg_count) printf("found move r%d,#0x%08x\n",rd_i,res[rd_i]);
1406  found_bits |=rd_bit;
1407  } else if(isADDx_imm(fw->is->insn)) {
1408  res[rd_i] += fw->is->insn->detail->arm.operands[1].imm;
1409 // if(dbg_count) printf("found add r%d,#0x%08x\n",rd_i,res[rd_i]);
1410  // pretend reg is not known
1411  known_bits ^=rd_bit;
1412  // do not set found bit here
1413  } else if(isSUBx_imm(fw->is->insn)) {
1414  res[rd_i] = (int)(res[rd_i]) - fw->is->insn->detail->arm.operands[1].imm;
1415 // if(dbg_count) printf("found add r%d,#0x%08x\n",rd_i,res[rd_i]);
1416  // pretend reg is not known
1417  known_bits ^=rd_bit;
1418  // do not set found bit here
1419  }/* else {
1420  }
1421  */
1422  }
1423  }
1424 // if(dbg_count) printf("get_call_const_args found 0x%08x\n",found_bits);
1425  return found_bits;
1426 }
uint32_t get_direct_jump_target ( firmware fw,
iter_state_t is_init 
)

Definiert in Zeile 1441 der Datei firmware_load_ng.c.

1442 {
1443  uint32_t adr=B_target(fw,is_init->insn);
1444  // B ... return with thumb set to current mode
1445  if(adr) {
1446  return (adr | is_init->thumb);
1447  }
1448  adr=LDR_PC_PC_target(fw,is_init->insn);
1449  // LDR pc #... thumb is set in the loaded address
1450  if(adr) {
1451  return adr;
1452  }
1453  // BX PC
1454  adr=BX_PC_target(fw,is_init->insn);
1455  if(adr) {
1456  // bx swaps mode
1457  if(is_init->thumb) {
1458  return ADR_CLEAR_THUMB(adr);
1459  } else {
1460  return ADR_SET_THUMB(adr);
1461  }
1462  }
1463  // an immediate move to ip (R12), candidate for multi-instruction veneer
1464  if((is_init->insn->id == ARM_INS_MOV || is_init->insn->id == ARM_INS_MOVW)
1465  && is_init->insn->detail->arm.operands[0].reg == ARM_REG_IP
1466  && is_init->insn->detail->arm.operands[1].type == ARM_OP_IMM) {
1467  adr = is_init->insn->detail->arm.operands[1].imm;
1468  // iter in default state, starting from is_init
1469  if(!fw_disasm_iter_single(fw,is_init->adr | is_init->thumb)) {
1470  fprintf(stderr,"get_direct_jump_target: disasm single failed at 0x%"PRIx64"\n",fw->is->insn->address);
1471  return 0;
1472  }
1473  // check for MOVT ip, #x
1474  if(!(fw->is->insn->id == ARM_INS_MOVT
1475  && fw->is->insn->detail->arm.operands[0].reg == ARM_REG_IP
1476  && fw->is->insn->detail->arm.operands[1].type == ARM_OP_IMM)) {
1477 // doesn't match second two insn veneer, not really an error
1478 // fprintf(stderr,"get_direct_jump_target: not 2 insn ip veneer 0x%"PRIx64"\n",fw->is->insn->address);
1479  return 0;
1480  }
1481  // thumb set in loaded adr
1482  adr = (fw->is->insn->detail->arm.operands[1].imm << 16) | (adr&0xFFFF);
1483  if(!fw_disasm_iter(fw)) {
1484  fprintf(stderr,"get_direct_jump_target: disasm 2 failed at 0x%"PRIx64"\n",fw->is->insn->address);
1485  return 0;
1486  }
1487  // BX ip ?
1488  if(fw->is->insn->id == ARM_INS_BX
1489  && fw->is->insn->detail->arm.operands[0].type == ARM_OP_REG
1490  && fw->is->insn->detail->arm.operands[0].reg == ARM_REG_IP) {
1491  return adr;
1492  }
1493  }
1494  return 0;
1495 }
int get_TBx_PC_info ( firmware fw,
iter_state_t is,
tbx_info_t ti 
)

Definiert in Zeile 855 der Datei firmware_load_ng.c.

856 {
857  if(!(is->insn->id == ARM_INS_TBH || is->insn->id == ARM_INS_TBB) || is->insn->detail->arm.operands[0].mem.base != ARM_REG_PC) {
858  return 0;
859  }
860  ti->start=(uint32_t)is->adr; // after current instruction
861  ti->first_target=0;
862  ti->bytes=(is->insn->id == ARM_INS_TBH)?2:1;
863 
864  uint32_t max_adr;
865  // max possible (assuming jumptable is contiguous)
866  if(ti->bytes==1) {
867  max_adr=ti->start+(2*255);
868  } else {
869  max_adr=ti->start+(2*65535);
870  }
871  arm_reg i_reg=is->insn->detail->arm.operands[0].mem.index;
872  // backtrack looking for
873  // cmp index reg,#imm
874  // ...
875  // bhs ...
876  int max_backtrack = 8;
877  if(is->ah.count - 1 < max_backtrack) {
878  max_backtrack = is->ah.count-1;
879  }
880 
881  int max_count=0;
882  int found_bhs=0;
883  int i;
884  for(i=1;i<=max_backtrack;i++) {
885  fw_disasm_iter_single(fw,adr_hist_get(&is->ah,i)); // thumb state comes from hist
886  if(fw->is->insn->id == ARM_INS_B && fw->is->insn->detail->arm.cc == ARM_CC_HS) {
887  found_bhs=1;
888  continue;
889  }
890  // TODO lots of other ways condition code or reg could be changed in between
891  if(found_bhs && fw->is->insn->id == ARM_INS_CMP) {
892  // cmp with correct operands, assume number of jumptable entries
893  if((arm_reg)fw->is->insn->detail->arm.operands[0].reg == i_reg
894  || fw->is->insn->detail->arm.operands[1].type == ARM_OP_IMM) {
895  max_count = fw->is->insn->detail->arm.operands[1].imm;
896  }
897  // otherwise, give up
898  break;
899  }
900  }
901  if(max_count) {
902  max_adr = ti->start+max_count*ti->bytes;
903  //printf("get_TBx_PC_info: max_count %d start 0x%08x max_adr=0x%08x\n",max_count,ti->start,max_adr);
904  }
905  uint32_t adr=ti->start;
906  while(adr < max_adr) {
907  uint8_t *p=adr2ptr(fw,adr);
908  if(!p) {
909  fprintf(stderr,"get_TBx_PC_info: jumptable outside of valid address range at 0x%08x\n",adr);
910  return 0;
911  }
912  uint16_t off;
913  if(ti->bytes==1) {
914  off=(uint16_t)*p;
915  } else {
916  off=*(uint16_t *)p;
917  }
918 
919  // 0, probably padding at the end (could probably break here)
920  // note shouldn't be padding on tbh, since aligned for thumb
921  if(!off) {
922  break;
923  }
924  uint32_t target = ti->start+2*off;
925  // may indicate non-jumptable entry, if count not found, so don't increment adr
926  if(target <= adr) {
927  fprintf(stderr,"get_TBx_PC_info: jumptable target 0x%08x inside jumptable %d at 0x%08x\n",target,off,adr);
928  break;
929  }
930  if(!ti->first_target || target < ti->first_target) {
931  ti->first_target=target;
932  if(target < max_adr) {
933  max_adr=target; // assume jump table ends at/before first target
934  }
935  }
936  adr+=ti->bytes;
937  }
938  // if found count, assume it's right
939  if(max_count) {
940  ti->count=max_count;
941  } else {
942  // otherwise, use final address
943  ti->count=(adr-ti->start)/ti->bytes;
944  }
945  return 1;
946 }
int insn_match ( cs_insn *  insn,
const insn_match_t match 
)

Definiert in Zeile 1980 der Datei firmware_load_ng.c.

1981 {
1982  // specific instruction ID requested, check
1983  if(match->id != ARM_INS_INVALID && insn->id != match->id) {
1984  return 0;
1985  }
1986  // condition code requested, check
1987  if(match->cc != ARM_CC_INVALID && insn->detail->arm.cc != match->cc) {
1988  return 0;
1989  }
1990  // no op checks, done
1991  if(match->op_count == MATCH_OPCOUNT_IGNORE) {
1992  return 1;
1993  }
1994  // operand count requested, check
1995  if(match->op_count >= 0 && insn->detail->arm.op_count != match->op_count) {
1996  return 0;
1997  }
1998  int i;
1999  // operands
2000  for(i=0; i<MATCH_MAX_OPS && i < insn->detail->arm.op_count; i++) {
2001  // specific type requested?
2002  if(match->operands[i].type != ARM_OP_INVALID && insn->detail->arm.operands[i].type != match->operands[i].type) {
2003  return 0;
2004  }
2005  // specific registers requested?
2006  if(match->operands[i].reg1 != ARM_REG_INVALID) {
2007  if(insn->detail->arm.operands[i].type == ARM_OP_REG) {
2008  // range requested
2009  if(match->operands[i].reg2 != ARM_REG_INVALID) {
2010  if(!reg_in_range((arm_reg)insn->detail->arm.operands[i].reg,
2011  match->operands[i].reg1, match->operands[i].reg2)) {
2012  return 0;
2013  }
2014  } else if((arm_reg)insn->detail->arm.operands[i].reg != match->operands[i].reg1) {
2015  return 0;
2016  }
2017  } else if(insn->detail->arm.operands[i].type == ARM_OP_MEM) {
2018  if(insn->detail->arm.operands[i].mem.base != match->operands[i].reg1) {
2019  return 0;
2020  }
2021  } else {
2022  fprintf(stderr,"insn_match: reg1 match requested on operand not reg or mem %d\n",
2023  insn->detail->arm.operands[i].type);
2024  }
2025  }
2026  if(match->operands[i].reg2 != ARM_REG_INVALID) {
2027  if(insn->detail->arm.operands[i].type == ARM_OP_MEM) {
2028  if(insn->detail->arm.operands[i].mem.index != match->operands[i].reg2) {
2029  return 0;
2030  }
2031  } else if(insn->detail->arm.operands[i].type != ARM_OP_REG) { // reg handled above
2032  fprintf(stderr,"insn_match: reg2 match requested on operand not reg or mem %d\n",
2033  insn->detail->arm.operands[i].type);
2034  }
2035  }
2036  if(match->operands[i].flags & MATCH_OP_FL_IMM) {
2037  if(insn->detail->arm.operands[i].type == ARM_OP_IMM
2038  || insn->detail->arm.operands[i].type == ARM_OP_PIMM
2039  || insn->detail->arm.operands[i].type == ARM_OP_CIMM) {
2040  if(insn->detail->arm.operands[i].imm != match->operands[i].imm) {
2041  return 0;
2042  }
2043  } else if(insn->detail->arm.operands[i].type == ARM_OP_MEM) {
2044  if(insn->detail->arm.operands[i].mem.disp != match->operands[i].imm) {
2045  return 0;
2046  }
2047  } else {
2048  fprintf(stderr,"insn_match: imm match requested on operand not imm or mem %d\n",
2049  insn->detail->arm.operands[i].type);
2050  }
2051  }
2052  if(match->operands[i].flags & MATCH_OP_FL_LAST) {
2053  break;
2054  }
2055  }
2056  return 1;
2057 }
int insn_match_any ( cs_insn *  insn,
const insn_match_t match 
)

Definiert in Zeile 2060 der Datei firmware_load_ng.c.

2061 {
2062  const insn_match_t *m;
2063  // check matches
2064  for(m=match;m->id != ARM_INS_ENDING;m++) {
2065  if(insn_match(insn,m)) {
2066  return 1;
2067  }
2068  }
2069  return 0;
2070 }
int insn_match_find_next ( firmware fw,
iter_state_t is,
int  max_insns,
const insn_match_t match 
)

Definiert in Zeile 2073 der Datei firmware_load_ng.c.

2074 {
2075  int i=0;
2076  while(i < max_insns) {
2077  // disassembly failed, no match (could ignore..)
2078  if(!disasm_iter(fw,is)) {
2079  return 0;
2080  }
2081  // printf("%"PRIx64" insn_match_find_next %s %s\n",is->insn->address,is->insn->mnemonic,is->insn->op_str);
2082  if(insn_match_any(is->insn,match)) {
2083  return 1;
2084  }
2085  i++;
2086  }
2087  // limit hit
2088  return 0;
2089 }
int insn_match_find_next_seq ( firmware fw,
iter_state_t is,
int  max_insns,
const insn_match_t match 
)

Definiert in Zeile 2120 der Datei firmware_load_ng.c.

2121 {
2122  int count=0;
2123  while(count < max_insns) {
2124  const insn_match_t *m=match;
2125  //printf("%"PRIx64" insn_match_find_next_seq %s %s\n",is->insn->address,is->insn->mnemonic,is->insn->op_str);
2126  while(m->id != ARM_INS_ENDING && disasm_iter(fw,is) && insn_match(is->insn,m)) {
2127  m++;
2128  count++;
2129  }
2130  if(m->id == ARM_INS_ENDING) {
2131  return 1;
2132  }
2133  // non-matching
2134  count++;
2135  }
2136  return 0;
2137 }
int insn_match_find_nth ( firmware fw,
iter_state_t is,
int  max_insns,
int  num_to_match,
const insn_match_t match 
)

Definiert in Zeile 2092 der Datei firmware_load_ng.c.

2093 {
2094  int i=0;
2095  int num_matched=0;
2096  while(i < max_insns) {
2097  // disassembly failed, no match (could ignore..)
2098  if(!disasm_iter(fw,is)) {
2099  return 0;
2100  }
2101  // printf("%"PRIx64" insn_match_find_next %s %s\n",is->insn->address,is->insn->mnemonic,is->insn->op_str);
2102 
2103  const insn_match_t *m;
2104  // check matches
2105  for(m=match;m->id != ARM_INS_ENDING;m++) {
2106  if(insn_match(is->insn,m)) {
2107  num_matched++;
2108  }
2109  }
2110  if(num_matched == num_to_match) {
2111  return 1;
2112  }
2113  i++;
2114  }
2115  // limit hit
2116  return 0;
2117 }
int insn_match_seq ( firmware fw,
iter_state_t is,
const insn_match_t match 
)

Definiert in Zeile 1927 der Datei firmware_load_ng.c.

1928 {
1929  //printf("%"PRIx64" insn_match_seq %s %s\n",is->insn->address,is->insn->mnemonic,is->insn->op_str);
1930  while(match->id != ARM_INS_ENDING && disasm_iter(fw,is) && insn_match(is->insn,match)) {
1931  //printf("%"PRIx64" insn_match_seq next %s %s\n",is->insn->address,is->insn->mnemonic,is->insn->op_str);
1932  match++;
1933  }
1934  return (match->id == ARM_INS_ENDING);
1935 }
int isADD_PC ( cs_insn *  insn)

Definiert in Zeile 538 der Datei firmware_load_ng.c.

539 {
540  return (insn->id == ARM_INS_ADD
541  && insn->detail->arm.op_count == 3
542  && insn->detail->arm.operands[0].reg != ARM_REG_PC
543  && insn->detail->arm.operands[1].type == ARM_OP_REG
544  && insn->detail->arm.operands[1].reg == ARM_REG_PC
545  && insn->detail->arm.operands[2].type == ARM_OP_IMM);
546 }
int isADDW_PC ( cs_insn *  insn)

Definiert in Zeile 526 der Datei firmware_load_ng.c.

527 {
528  return(insn->id == ARM_INS_ADDW
529  && insn->detail->arm.op_count == 3
530  && insn->detail->arm.operands[0].type == ARM_OP_REG
531  && insn->detail->arm.operands[0].reg != ARM_REG_PC
532  && insn->detail->arm.operands[1].type == ARM_OP_REG
533  && insn->detail->arm.operands[1].reg == ARM_REG_PC
534  && insn->detail->arm.operands[2].type == ARM_OP_IMM);
535 }
int isADDx_imm ( cs_insn *  insn)

Definiert in Zeile 642 der Datei firmware_load_ng.c.

643 {
644  return ((insn->id == ARM_INS_ADD || insn->id == ARM_INS_ADDW) && insn->detail->arm.operands[1].type == ARM_OP_IMM);
645 }
int isADRx ( cs_insn *  insn)

Definiert in Zeile 653 der Datei firmware_load_ng.c.

654 {
655  return ((insn->id == ARM_INS_ADR)
656  || isSUBW_PC(insn)
657  || isADDW_PC(insn)
658  || (isARM(insn) && (isADD_PC(insn) || isSUB_PC(insn))));
659 }
int isARM ( cs_insn *  insn)

Definiert in Zeile 478 der Datei firmware_load_ng.c.

479 {
480  int i;
481  for(i=0;i<insn->detail->groups_count;i++) {
482  if(insn->detail->groups[i] == ARM_GRP_ARM) {
483  return 1;
484  }
485  }
486  return 0;
487 }
int isASCIIstring ( firmware fw,
uint32_t  adr 
)

Definiert in Zeile 618 der Datei firmware_load.c.

619 {
620  if (idx_valid(fw, adr2idx(fw, adr)))
621  {
622  unsigned char *p = (unsigned char*)adr2ptr(fw, adr);
623  int i;
624  for (i = 0; (i < 100) && (p[i] != 0); i++)
625  {
626  if (!((p[i] == '\r') || (p[i] == '\n') || (p[i] == '\t') || ((p[i] >= 0x20) && (p[i] <= 0x7f))))
627  {
628  return 0;
629  }
630  }
631  if ((i >= 2) && (p[i] == 0))
632  return 1;
633  }
634  return 0;
635 }
int isLDR_PC ( cs_insn *  insn)

Definiert in Zeile 492 der Datei firmware_load_ng.c.

493 {
494  return insn->id == ARM_INS_LDR
495  && insn->detail->arm.op_count == 2
496  && insn->detail->arm.operands[0].type == ARM_OP_REG
497  && insn->detail->arm.operands[1].type == ARM_OP_MEM
498  && insn->detail->arm.operands[1].mem.base == ARM_REG_PC;
499 
500 }
int isLDR_PC_PC ( cs_insn *  insn)

Definiert in Zeile 505 der Datei firmware_load_ng.c.

506 {
507  if(!isLDR_PC(insn)) {
508  return 0;
509  }
510  return (insn->detail->arm.operands[0].reg == ARM_REG_PC);
511 }
int isPOP_LR ( cs_insn *  insn)

Definiert in Zeile 610 der Datei firmware_load_ng.c.

611 {
612  if(insn->id != ARM_INS_POP) {
613  return 0;
614  }
615  int i;
616  for(i=0; i < insn->detail->arm.op_count; i++) {
617  if(insn->detail->arm.operands[i].type == ARM_OP_REG
618  && insn->detail->arm.operands[i].reg == ARM_REG_LR) {
619  return 1;
620  }
621  }
622  return 0;
623 }
int isPOP_PC ( cs_insn *  insn)

Definiert in Zeile 626 der Datei firmware_load_ng.c.

627 {
628  if(insn->id != ARM_INS_POP) {
629  return 0;
630  }
631  int i;
632  for(i=0; i < insn->detail->arm.op_count; i++) {
633  if(insn->detail->arm.operands[i].type == ARM_OP_REG
634  && insn->detail->arm.operands[i].reg == ARM_REG_PC) {
635  return 1;
636  }
637  }
638  return 0;
639 }
int isPUSH_LR ( cs_insn *  insn)

Definiert in Zeile 594 der Datei firmware_load_ng.c.

595 {
596  if(insn->id != ARM_INS_PUSH) {
597  return 0;
598  }
599  int i;
600  for(i=0; i < insn->detail->arm.op_count; i++) {
601  if(insn->detail->arm.operands[i].type == ARM_OP_REG
602  && insn->detail->arm.operands[i].reg == ARM_REG_LR) {
603  return 1;
604  }
605  }
606  return 0;
607 }
int isRETx ( cs_insn *  insn)

Definiert in Zeile 560 der Datei firmware_load_ng.c.

561 {
562  // BX LR
563  if(insn->id == ARM_INS_BX
564  && insn->detail->arm.op_count == 1
565  && insn->detail->arm.operands[0].type == ARM_OP_REG
566  && insn->detail->arm.operands[0].reg == ARM_REG_LR) {
567  return 1;
568  }
569 
570  // TODO LDR pc, [sp], imm is somewhat common, but could also be function pointer call
571 
572  // POP. capstone translates LDMFD SP!,... in arm code to pop
573  if(insn->id == ARM_INS_POP) {
574  int i;
575  for(i=0; i < insn->detail->arm.op_count; i++) {
576  if(insn->detail->arm.operands[i].type == ARM_OP_REG
577  && insn->detail->arm.operands[i].reg == ARM_REG_PC) {
578  return 1;
579  }
580  }
581  }
582  // MOV PC, LR (some tools translate this to RET)
583  if(insn->id == ARM_INS_MOV
584  && insn->detail->arm.operands[0].type == ARM_OP_REG
585  && insn->detail->arm.operands[0].reg == ARM_REG_PC
586  && insn->detail->arm.operands[1].type == ARM_OP_REG
587  && insn->detail->arm.operands[1].reg == ARM_REG_LR) {
588  return 1;
589  }
590  return 0;
591 }
int isSUB_PC ( cs_insn *  insn)

Definiert in Zeile 549 der Datei firmware_load_ng.c.

550 {
551  return (insn->id == ARM_INS_SUB
552  && insn->detail->arm.op_count == 3
553  && insn->detail->arm.operands[0].reg != ARM_REG_PC
554  && insn->detail->arm.operands[1].type == ARM_OP_REG
555  && insn->detail->arm.operands[1].reg == ARM_REG_PC
556  && insn->detail->arm.operands[2].type == ARM_OP_IMM);
557 }
int isSUBW_PC ( cs_insn *  insn)

Definiert in Zeile 514 der Datei firmware_load_ng.c.

515 {
516  return(insn->id == ARM_INS_SUBW
517  && insn->detail->arm.op_count == 3
518  && insn->detail->arm.operands[0].type == ARM_OP_REG
519  && insn->detail->arm.operands[0].reg != ARM_REG_PC
520  && insn->detail->arm.operands[1].type == ARM_OP_REG
521  && insn->detail->arm.operands[1].reg == ARM_REG_PC
522  && insn->detail->arm.operands[2].type == ARM_OP_IMM);
523 }
int isSUBx_imm ( cs_insn *  insn)

Definiert in Zeile 647 der Datei firmware_load_ng.c.

648 {
649  return (IS_INSN_ID_SUBx(insn->id) && insn->detail->arm.operands[1].type == ARM_OP_IMM);
650 }
uint32_t LDR_PC2adr ( firmware fw,
cs_insn *  insn 
)
uint32_t LDR_PC2val ( firmware fw,
cs_insn *  insn 
)

Definiert in Zeile 755 der Datei firmware_load_ng.c.

756 {
757  uint32_t *p=LDR_PC2valptr(fw,insn);
758  if(p) {
759  return *p;
760  }
761  return 0;
762 }
uint32_t* LDR_PC2valptr ( firmware fw,
cs_insn *  insn 
)

Definiert in Zeile 686 der Datei firmware_load_ng.c.

687 {
688  if(isARM(insn)) {
689  return LDR_PC2valptr_arm(fw,insn);
690  } else {
691  return LDR_PC2valptr_thumb(fw,insn);
692  }
693 }
uint32_t* LDR_PC2valptr_arm ( firmware fw,
cs_insn *  insn 
)

Definiert in Zeile 674 der Datei firmware_load_ng.c.

675 {
676  if(!isLDR_PC(insn)) {
677  return NULL;
678  }
679  uint32_t adr;
680  // TODO NOTE doesn't do anything with scale (which can supposedly be neg?),
681  // appears correct for examples seen so far
682  adr=insn->address+8+insn->detail->arm.operands[1].mem.disp;
683  return (uint32_t *)adr2ptr(fw,adr);
684 }
uint32_t* LDR_PC2valptr_thumb ( firmware fw,
cs_insn *  insn 
)

Definiert in Zeile 662 der Datei firmware_load_ng.c.

663 {
664  if(!isLDR_PC(insn)) {
665  return NULL;
666  }
667  uint32_t adr;
668  // TODO NOTE doesn't do anything with scale (which can supposedly be neg?),
669  // appears correct for examples seen so far
670  adr=(insn->address&~3)+4+insn->detail->arm.operands[1].mem.disp;
671  return (uint32_t *)adr2ptr(fw,adr);
672 }
uint32_t ptr2adr ( firmware fw,
uint8_t *  ptr 
)

Definiert in Zeile 272 der Datei firmware_load_ng.c.

273 {
274  // TODO handle copied, or maybe another func to convert?
275  return (ptr-fw->buf8)+fw->base;
276 }
int search_calls_multi_end ( firmware fw,
iter_state_t is,
uint32_t  adr 
)
uint32_t search_disasm_calls ( firmware fw,
iter_state_t is,
uint32_t  val,
void *  unused 
)
uint32_t search_disasm_calls_multi ( firmware fw,
iter_state_t is,
uint32_t  unused,
void *  userdata 
)
uint32_t search_disasm_calls_veneer_multi ( firmware fw,
iter_state_t is,
uint32_t  unused,
void *  userdata 
)
uint32_t search_disasm_const_ref ( firmware fw,
iter_state_t is,
uint32_t  val,
void *  unused 
)
uint32_t search_disasm_str_ref ( firmware fw,
iter_state_t is,
uint32_t  val,
void *  str 
)

Variablen-Dokumentation

const insn_match_t match_b[]

Definiert in Zeile 1879 der Datei firmware_load_ng.c.

const insn_match_t match_b_bl[]

Definiert in Zeile 1887 der Datei firmware_load_ng.c.

const insn_match_t match_b_bl_blximm[]

Definiert in Zeile 1893 der Datei firmware_load_ng.c.

const insn_match_t match_bl[]

Definiert in Zeile 1883 der Datei firmware_load_ng.c.

const insn_match_t match_bl_blximm[]

Definiert in Zeile 1900 der Datei firmware_load_ng.c.

const insn_match_t match_blxreg[]

Definiert in Zeile 1916 der Datei firmware_load_ng.c.

const insn_match_t match_bxlr[]

Definiert in Zeile 1906 der Datei firmware_load_ng.c.

const insn_match_t match_bxreg[]

Definiert in Zeile 1911 der Datei firmware_load_ng.c.

const insn_match_t match_ldr_pc[]

Definiert in Zeile 1921 der Datei firmware_load_ng.c.