CHDK_DE Vorschauversion  Trunk Rev. 5579
 Alle Datenstrukturen Dateien Funktionen Variablen Typdefinitionen Aufzählungen Aufzählungswerte Makrodefinitionen
finsig_thumb2.c-Dateireferenz
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <time.h>
#include <stdarg.h>
#include <inttypes.h>
#include <capstone.h>
#include "stubs_load.h"
#include "firmware_load_ng.h"
#include "ptp_op_names.h"
+ Include-Abhängigkeitsdiagramm für finsig_thumb2.c:

gehe zum Quellcode dieser Datei

Datenstrukturen

struct  sig_entry_t
 
struct  known_prop_t
 
struct  misc_blob_t
 
struct  misc_val_t
 
struct  sig_rule_s
 
struct  physw_table_entry_t
 
struct  kinfo
 

Makrodefinitionen

#define SEARCH_NEAR_REF_RANGE   1024
 
#define SIG_NEAR_OFFSET_MASK   0x00FF
 
#define SIG_NEAR_COUNT_MASK   0xFF00
 
#define SIG_NEAR_COUNT_SHIFT   8
 
#define SIG_NEAR_REV   0x10000
 
#define SIG_NEAR_INDIRECT   0x20000
 
#define SIG_NEAR_JMP_SUB   0x40000
 
#define SIG_NEAR_AFTER(max_insns, n)
 
#define SIG_NEAR_BEFORE(max_insns, n)   (SIG_NEAR_AFTER(max_insns,n)|SIG_NEAR_REV)
 
#define DONT_EXPORT   0x01
 
#define OPTIONAL   0x02
 
#define UNUSED   0x04
 
#define BAD_MATCH   0x08
 
#define EV_MATCH   0x10
 
#define LIST_ALWAYS   0x20
 
#define ARM_STUB   0x80
 
#define DONT_EXPORT_ILC   0x100
 
#define MAX_SIG_ENTRY   5000
 
#define KNOWN_PROPSET_COUNT   (13-5)
 
#define MISC_BLOB_XTENSA_MAX   5
 
#define MISC_BLOB_TYPE_NONE   0
 
#define MISC_BLOB_TYPE_XTENSA   1
 
#define MISC_BLOB_TYPE_OMAR   2
 
#define MISC_VAL_NO_STUB   1
 
#define MISC_VAL_DEF_CONST   2
 
#define MISC_VAL_OPTIONAL   4
 
#define SIG_NAMED_LAST_MAX_MASK   0x00000FFF
 
#define SIG_NAMED_LAST_MIN_MASK   0x00FFF000
 
#define SIG_NAMED_LAST_MIN_SHIFT   12
 
#define SIG_NAMED_LAST_RANGE(min, max)
 
#define SIG_NAMED_ASIS   0x00000000
 
#define SIG_NAMED_JMP_SUB   0x00000001
 
#define SIG_NAMED_SUB   0x00000002
 
#define SIG_NAMED_INSN   0x00000003
 
#define SIG_NAMED_TYPE_MASK   0x0000000F
 
#define SIG_NAMED_CLEARTHUMB   0x00000010
 
#define SIG_NAMED_FLAG_MASK   0x000000F0
 
#define SIG_NAMED_NTH_MASK   0x00000F00
 
#define SIG_NAMED_NTH_SHIFT   8
 
#define SIG_NAMED_NTH_RANGE_MASK   0x0003F000
 
#define SIG_NAMED_NTH_RANGE_SHIFT   12
 
#define SIG_NAMED_NTH(n, type)   ((SIG_NAMED_NTH_MASK&((n)<<SIG_NAMED_NTH_SHIFT)) | (SIG_NAMED_##type))
 
#define SIG_NAMED_NTH_RANGE(n)   ((SIG_NAMED_NTH_RANGE_MASK&((n)<<SIG_NAMED_NTH_RANGE_SHIFT)))
 
#define SIG_DRY_MIN(min_rel)   (min_rel),0
 
#define SIG_DRY_MAX(max_rel)   0,(max_rel)
 
#define SIG_DRY_RANGE(min_rel, max_rel)   (min_rel),(max_rel)
 
#define MAX_GENERIC_FUNCS   16
 

Typdefinitionen

typedef struct sig_rule_s sig_rule_t
 
typedef int(* sig_match_fn )(firmware *fw, iter_state_t *is, sig_rule_t *rule)
 

Funktionen

void bprintf (char *fmt,...)
 
void add_blankline ()
 
void write_output ()
 
void add_prop_hit (char *name, int id)
 
misc_val_tget_misc_val (const char *name)
 
uint32_t get_misc_val_value (const char *name)
 
void save_misc_val (const char *name, uint32_t base, uint32_t offset, uint32_t ref_adr)
 
void save_misc_val_blobs (const char *name, misc_blob_t *blobs, uint32_t ref_adr)
 
sig_entry_tfind_saved_sig (const char *name)
 
uint32_t get_saved_sig_val (const char *name)
 
void save_sig (firmware *fw, const char *name, uint32_t val)
 
void add_func_name (firmware *fw, char *n, uint32_t eadr, char *suffix)
 
int save_sig_with_j (firmware *fw, char *name, uint32_t adr)
 
int find_next_sig_call (firmware *fw, iter_state_t *is, uint32_t max_offset, const char *name)
 
int is_sig_call (firmware *fw, iter_state_t *is, const char *name)
 
int init_disasm_sig_ref (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_near_str (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_str_r0_call (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_reg_evp (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_reg_evp_table (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_reg_evp_alt2 (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_unreg_evp_table (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_evp_table_veneer (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_get_nd_value (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_get_current_exp (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_get_current_nd_value (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_imager_active_callback (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_imager_active (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_screenlock_helper (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_screenunlock (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_log_camera_event (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_physw_misc (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_kbd_read_keys (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_get_kbd_state (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_get_dial_hw_position (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_create_jumptable (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_take_semaphore_strict (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_get_semaphore_value (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_stat (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_open (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_open_gt_57 (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_close_gt_57 (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_umalloc (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_ufree (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_deletefile_fut (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
uint32_t find_call_near_str (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_closedir (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int save_sig_match_call (firmware *fw, sig_rule_t *rule, uint32_t call_adr)
 
int sig_match_readfastdir (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_strrchr (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_time (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_strncpy (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_strncmp (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_strtolx (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_exec_evp (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_fgets_fut (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_log (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_pow_dry_52 (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_pow_dry_gt_52 (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_sqrt (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_get_drive_cluster_size (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_mktime_ext (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_rec2pb (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_get_parameter_data (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_prepdir_x (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_prepdir_1 (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_prepdir_0 (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_mkdir (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_add_ptp_handler (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_qsort (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_deletedirectory_fut (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_set_control_event (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_displaybusyonscreen_52 (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_undisplaybusyonscreen_52 (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_try_take_sem_dry_gt_58 (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_wait_all_eventflag_strict (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_get_num_posted_messages (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_set_hp_timer_after_now (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_transfer_src_overlay (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_exmem_vars (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_zicokick_52 (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_zicokick_gt52 (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_zicokick_copy (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_zicokick_values (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_init_ex_drivers (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_omar_init (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_enable_hdmi_power (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_disable_hdmi_power (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_levent_table (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_flash_param_table (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_jpeg_count_str (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_misc_flag_named (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_cam_has_iris_diaphragm (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_cam_uncached_bit (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_physw_event_table (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_uiprop_count (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_get_canon_mode_list (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_zoom_busy (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_focus_busy (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_aram_size (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_aram_size_gt58 (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_aram_start (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_aram_start2 (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match__nrflag (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_var_struct_get (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_av_over_sem (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_canon_menu_active (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_file_counter_init (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_file_counter_var (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_palette_vars (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_rom_ptr_get (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_prop_string (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int is_immediate_ret_sub (firmware *fw, iter_state_t *is_init)
 
int sig_match_named_last (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
void sig_match_named_save_sig (firmware *fw, const char *name, uint32_t adr, uint32_t flags)
 
int sig_match_named (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
void run_sig_rules (firmware *fw, sig_rule_t *sig_rules)
 
void add_event_proc (firmware *fw, char *name, uint32_t adr)
 
int process_reg_eventproc_call (firmware *fw, iter_state_t *is, uint32_t unused)
 
int process_eventproc_table_call (firmware *fw, iter_state_t *is, uint32_t unused)
 
int process_createtask_call (firmware *fw, iter_state_t *is, uint32_t unused)
 
int save_ptp_handler_func (firmware *fw, uint32_t op, uint32_t handler)
 
int process_add_ptp_handler_call (firmware *fw, iter_state_t *is, uint32_t unused)
 
int add_generic_func_match (search_calls_multi_data_t *match_fns, int *match_fn_count, int max_funcs, search_calls_multi_fn fn, uint32_t adr)
 
void add_generic_sig_match (search_calls_multi_data_t *match_fns, int *match_fn_count, search_calls_multi_fn fn, const char *name)
 
void find_exception_handlers (firmware *fw, iter_state_t *is)
 
void find_generic_funcs (firmware *fw)
 
void find_ctypes (firmware *fw)
 
void print_misc_val_makefile (const char *name)
 
void output_firmware_vals (firmware *fw)
 
void print_platform_misc_val_undef (const char *name, uint32_t def)
 
void output_platform_vals (firmware *fw)
 
void output_propcases (firmware *fw)
 
void output_exmem_types (firmware *fw)
 
void print_misc_val_comment (const char *name)
 
void get_physw_table_entry (firmware *fw, uint32_t adr, physw_table_entry_t *vals)
 
uint32_t find_physw_table_entry (firmware *fw, uint32_t tadr, int tcount, uint32_t ev)
 
uint32_t find_physw_table_max (firmware *fw, uint32_t tadr, int max_count)
 
void write_physw_event_table_dump (firmware *fw, uint32_t tadr, int tcount)
 
void print_kval (firmware *fw, uint32_t tadr, int tcount, uint32_t ev, const char *name, const char *sfx)
 
void add_kinfo (int r, uint32_t b, const char *nm, uint32_t adr, uint32_t ev, int inv)
 
uint32_t add_kmval (firmware *fw, uint32_t tadr, int tsiz, int tlen, uint32_t ev, const char *name, uint32_t xtra)
 
int kinfo_compare (const kinfo *p1, const kinfo *p2)
 
void print_kmvals ()
 
void do_km_vals (firmware *fw, uint32_t tadr, int tsiz, int tlen)
 
void output_physw_vals (firmware *fw)
 
void output_modemap (firmware *fw)
 
int compare_sig_names (const sig_entry_t **p1, const sig_entry_t **p2)
 
int compare_func_addresses (const sig_entry_t **p1, const sig_entry_t **p2)
 
void write_funcs (firmware *fw, char *filename, sig_entry_t *fns[], int(*compare)(const sig_entry_t **p1, const sig_entry_t **p2))
 
void write_func_lists (firmware *fw)
 
void print_other_stubs_min (firmware *fw, const char *name, uint32_t fadr, uint32_t atadr)
 
void print_stubs_min_def (firmware *fw, misc_val_t *sig)
 
void find_other_stubs_min (firmware *fw)
 
void print_results (firmware *fw, sig_entry_t *sig)
 
void write_stubs (firmware *fw, int max_find_func)
 
int main (int argc, char **argv)
 

Variablen

char out_buf [32 *1024] = ""
 
int out_len = 0
 
char hdr_buf [32 *1024] = ""
 
int hdr_len = 0
 
int out_hdr = 1
 
FILEout_fp
 
int next_sig_entry = 0
 
sig_entry_t sig_names [MAX_SIG_ENTRY]
 
known_prop_t knownprops []
 
misc_val_t misc_vals []
 
static const insn_match_t match_open_mov_call []
 
sig_rule_t sig_rules_initial []
 
sig_rule_t sig_rules_main []
 
int kmask [3]
 
kinfo key_info [100]
 
int kcount = 0
 
uint32_t kshutter_min_bits = 0xFFFFFFFF
 

Makro-Dokumentation

#define ARM_STUB   0x80

Definiert in Zeile 81 der Datei finsig_thumb2.c.

#define BAD_MATCH   0x08

Definiert in Zeile 77 der Datei finsig_thumb2.c.

#define DONT_EXPORT   0x01

Definiert in Zeile 74 der Datei finsig_thumb2.c.

#define DONT_EXPORT_ILC   0x100

Definiert in Zeile 82 der Datei finsig_thumb2.c.

#define EV_MATCH   0x10

Definiert in Zeile 78 der Datei finsig_thumb2.c.

#define KNOWN_PROPSET_COUNT   (13-5)

Definiert in Zeile 469 der Datei finsig_thumb2.c.

#define LIST_ALWAYS   0x20

Definiert in Zeile 79 der Datei finsig_thumb2.c.

#define MAX_GENERIC_FUNCS   16

Definiert in Zeile 5183 der Datei finsig_thumb2.c.

#define MAX_SIG_ENTRY   5000

Definiert in Zeile 92 der Datei finsig_thumb2.c.

#define MISC_BLOB_TYPE_NONE   0

Definiert in Zeile 505 der Datei finsig_thumb2.c.

#define MISC_BLOB_TYPE_OMAR   2

Definiert in Zeile 507 der Datei finsig_thumb2.c.

#define MISC_BLOB_TYPE_XTENSA   1

Definiert in Zeile 506 der Datei finsig_thumb2.c.

#define MISC_BLOB_XTENSA_MAX   5

Definiert in Zeile 504 der Datei finsig_thumb2.c.

#define MISC_VAL_DEF_CONST   2

Definiert in Zeile 518 der Datei finsig_thumb2.c.

#define MISC_VAL_NO_STUB   1

Definiert in Zeile 516 der Datei finsig_thumb2.c.

#define MISC_VAL_OPTIONAL   4

Definiert in Zeile 519 der Datei finsig_thumb2.c.

#define OPTIONAL   0x02

Definiert in Zeile 75 der Datei finsig_thumb2.c.

#define SEARCH_NEAR_REF_RANGE   1024

Definiert in Zeile 19 der Datei finsig_thumb2.c.

#define SIG_DRY_MAX (   max_rel)    0,(max_rel)

Definiert in Zeile 4542 der Datei finsig_thumb2.c.

#define SIG_DRY_MIN (   min_rel)    (min_rel),0

Definiert in Zeile 4541 der Datei finsig_thumb2.c.

#define SIG_DRY_RANGE (   min_rel,
  max_rel 
)    (min_rel),(max_rel)

Definiert in Zeile 4543 der Datei finsig_thumb2.c.

#define SIG_NAMED_ASIS   0x00000000

Definiert in Zeile 4413 der Datei finsig_thumb2.c.

#define SIG_NAMED_CLEARTHUMB   0x00000010

Definiert in Zeile 4422 der Datei finsig_thumb2.c.

#define SIG_NAMED_FLAG_MASK   0x000000F0

Definiert in Zeile 4423 der Datei finsig_thumb2.c.

#define SIG_NAMED_INSN   0x00000003

Definiert in Zeile 4419 der Datei finsig_thumb2.c.

#define SIG_NAMED_JMP_SUB   0x00000001

Definiert in Zeile 4415 der Datei finsig_thumb2.c.

#define SIG_NAMED_LAST_MAX_MASK   0x00000FFF

Definiert in Zeile 4385 der Datei finsig_thumb2.c.

#define SIG_NAMED_LAST_MIN_MASK   0x00FFF000

Definiert in Zeile 4386 der Datei finsig_thumb2.c.

#define SIG_NAMED_LAST_MIN_SHIFT   12

Definiert in Zeile 4387 der Datei finsig_thumb2.c.

#define SIG_NAMED_LAST_RANGE (   min,
  max 
)
Wert:

Definiert in Zeile 4388 der Datei finsig_thumb2.c.

#define SIG_NAMED_NTH (   n,
  type 
)    ((SIG_NAMED_NTH_MASK&((n)<<SIG_NAMED_NTH_SHIFT)) | (SIG_NAMED_##type))

Definiert in Zeile 4434 der Datei finsig_thumb2.c.

#define SIG_NAMED_NTH_MASK   0x00000F00

Definiert in Zeile 4425 der Datei finsig_thumb2.c.

#define SIG_NAMED_NTH_RANGE (   n)    ((SIG_NAMED_NTH_RANGE_MASK&((n)<<SIG_NAMED_NTH_RANGE_SHIFT)))

Definiert in Zeile 4436 der Datei finsig_thumb2.c.

#define SIG_NAMED_NTH_RANGE_MASK   0x0003F000

Definiert in Zeile 4430 der Datei finsig_thumb2.c.

#define SIG_NAMED_NTH_RANGE_SHIFT   12

Definiert in Zeile 4431 der Datei finsig_thumb2.c.

#define SIG_NAMED_NTH_SHIFT   8

Definiert in Zeile 4426 der Datei finsig_thumb2.c.

#define SIG_NAMED_SUB   0x00000002

Definiert in Zeile 4417 der Datei finsig_thumb2.c.

#define SIG_NAMED_TYPE_MASK   0x0000000F

Definiert in Zeile 4420 der Datei finsig_thumb2.c.

#define SIG_NEAR_AFTER (   max_insns,
  n 
)
Wert:

Definiert in Zeile 27 der Datei finsig_thumb2.c.

#define SIG_NEAR_BEFORE (   max_insns,
  n 
)    (SIG_NEAR_AFTER(max_insns,n)|SIG_NEAR_REV)

Definiert in Zeile 29 der Datei finsig_thumb2.c.

#define SIG_NEAR_COUNT_MASK   0xFF00

Definiert in Zeile 22 der Datei finsig_thumb2.c.

#define SIG_NEAR_COUNT_SHIFT   8

Definiert in Zeile 23 der Datei finsig_thumb2.c.

#define SIG_NEAR_INDIRECT   0x20000

Definiert in Zeile 25 der Datei finsig_thumb2.c.

#define SIG_NEAR_JMP_SUB   0x40000

Definiert in Zeile 26 der Datei finsig_thumb2.c.

#define SIG_NEAR_OFFSET_MASK   0x00FF

Definiert in Zeile 21 der Datei finsig_thumb2.c.

#define SIG_NEAR_REV   0x10000

Definiert in Zeile 24 der Datei finsig_thumb2.c.

#define UNUSED   0x04

Definiert in Zeile 76 der Datei finsig_thumb2.c.

Dokumentation der benutzerdefinierten Typen

typedef int(* sig_match_fn)(firmware *fw, iter_state_t *is, sig_rule_t *rule)

Definiert in Zeile 858 der Datei finsig_thumb2.c.

typedef struct sig_rule_s sig_rule_t

Definiert in Zeile 857 der Datei finsig_thumb2.c.

Dokumentation der Funktionen

void add_blankline ( )

Definiert in Zeile 53 der Datei finsig_thumb2.c.

54 {
55  if (strcmp(hdr_buf+hdr_len-2,"\n\n") != 0)
56  {
57  hdr_buf[hdr_len++] = '\n';
58  hdr_buf[hdr_len] = 0;
59  }
60 }
void add_event_proc ( firmware fw,
char *  name,
uint32_t  adr 
)

Definiert in Zeile 4888 der Datei finsig_thumb2.c.

4889 {
4890  // TODO - no ARM eventprocs seen so far, warn
4891  if(!ADR_IS_THUMB(adr)) {
4892  printf("add_event_proc: %s is ARM 0x%08x\n",name,adr);
4893  }
4894  // attempt to disassemble target
4895  if(!fw_disasm_iter_single(fw,adr)) {
4896  printf("add_event_proc: %s disassembly failed at 0x%08x\n",name,adr);
4897  return;
4898  }
4899  // handle functions that immediately jump
4900  // only one level of jump for now, doesn't check for conditionals, but first insn shouldn't be conditional
4901  //uint32_t b_adr=B_target(fw,fw->is->insn);
4902  uint32_t b_adr=get_direct_jump_target(fw,fw->is);
4903  if(b_adr) {
4904  char *buf=malloc(strlen(name)+6);
4905  sprintf(buf,"j_%s_FW",name);
4906  add_func_name(fw,buf,adr,NULL); // this is the orignal named address
4907 // adr=b_adr | fw->is->thumb; // thumb bit from iter state
4908  adr=b_adr; // thumb bit already handled by get_direct...
4909  }
4910  add_func_name(fw,name,adr,"_FW");
4911 }
void add_func_name ( firmware fw,
char *  n,
uint32_t  eadr,
char *  suffix 
)

Definiert in Zeile 718 der Datei finsig_thumb2.c.

719 {
720  int k;
721 
722  char *s = n;
723  int mallocd = 0;
724  if (suffix != 0)
725  {
726  s = malloc(strlen(n) + strlen(suffix) + 1);
727  sprintf(s, "%s%s", n, suffix);
728  mallocd = 1;
729  }
730 
731  // if we end up needed these, can add a flag
732  if(!adr_is_main_fw_code(fw,eadr)) {
733  printf("save_sig: refusing to save %s with out of range address 0x%08x\n",s,eadr);
734  if(mallocd) {
735  free(s);
736  }
737  return;
738  }
739 
740  for (k=0; sig_names[k].name != 0; k++)
741  {
742  if (strcmp(sig_names[k].name, s) == 0)
743  {
744  if (sig_names[k].val == 0) // same name, no address
745  {
746  sig_names[k].val = eadr;
747  sig_names[k].flags |= EV_MATCH;
748  if (mallocd)
749  free(s);
750  return;
751  }
752  else if (sig_names[k].val == eadr) // same name, same address
753  {
754  if (mallocd)
755  free(s);
756  return;
757  }
758  else // same name, different address
759  {
760  printf("add_func_name: duplicate name %s existing 0x%08x != new 0x%08x\n",s, sig_names[k].val, eadr);
761  }
762  }
763  }
764 
768  next_sig_entry++;
770 }
int add_generic_func_match ( search_calls_multi_data_t match_fns,
int *  match_fn_count,
int  max_funcs,
search_calls_multi_fn  fn,
uint32_t  adr 
)

Definiert in Zeile 5164 der Datei finsig_thumb2.c.

5169 {
5170  if(*match_fn_count >= max_funcs-1) {
5171  printf("add_generic_func_match: ERROR max_funcs %d reached\n",max_funcs);
5172  match_fns[max_funcs-1].adr=0;
5173  match_fns[max_funcs-1].fn=NULL;
5174  return 0;
5175  }
5176  match_fns[*match_fn_count].adr=adr;
5177  match_fns[*match_fn_count].fn=fn;
5178  (*match_fn_count)++;
5179  match_fns[*match_fn_count].adr=0;
5180  match_fns[*match_fn_count].fn=NULL;
5181  return 1;
5182 }
void add_generic_sig_match ( search_calls_multi_data_t match_fns,
int *  match_fn_count,
search_calls_multi_fn  fn,
const char *  name 
)

Definiert in Zeile 5184 der Datei finsig_thumb2.c.

5188 {
5189  uint32_t adr=get_saved_sig_val(name);
5190  if(!adr) {
5191  printf("add_generic_sig_match: missing %s\n",name);
5192  return;
5193  }
5194  add_generic_func_match(match_fns,match_fn_count,MAX_GENERIC_FUNCS,fn,adr);
5195  char veneer[128];
5196  sprintf(veneer,"j_%s",name);
5197  adr=get_saved_sig_val(veneer);
5198  if(adr) {
5199  add_generic_func_match(match_fns,match_fn_count,MAX_GENERIC_FUNCS,fn,adr);
5200  }
5201 }
void add_kinfo ( int  r,
uint32_t  b,
const char *  nm,
uint32_t  adr,
uint32_t  ev,
int  inv 
)

Definiert in Zeile 5755 der Datei finsig_thumb2.c.

5756 {
5757  key_info[kcount].reg = r;
5758  key_info[kcount].bits = b;
5759  strcpy(key_info[kcount].nm, nm);
5760  key_info[kcount].fadr = adr;
5761  key_info[kcount].ev = ev;
5762  key_info[kcount].inv = inv;
5763  kcount++;
5764  kmask[r] |= b;
5765  if ((ev <= 1) && (b < kshutter_min_bits)) kshutter_min_bits = b;
5766 }
uint32_t add_kmval ( firmware fw,
uint32_t  tadr,
int  tsiz,
int  tlen,
uint32_t  ev,
const char *  name,
uint32_t  xtra 
)

Definiert in Zeile 5768 der Datei finsig_thumb2.c.

5769 {
5770  uint32_t adr=find_physw_table_entry(fw,tadr,tlen,ev);
5771  if(!adr) {
5772  return 0;
5773  }
5775  get_physw_table_entry(fw,adr,&v);
5776 
5777  add_kinfo(v.reg,v.bit|xtra,name,adr,v.ev,(v.no_invert)?0:1);
5778  return v.bit;
5779 }
void add_prop_hit ( char *  name,
int  id 
)

Definiert in Zeile 492 der Datei finsig_thumb2.c.

493 {
494  int n = 0;
495  while (knownprops[n].name) {
496  if (strcmp(knownprops[n].name,name) == 0) {
497  knownprops[n].id = id;
498  break;
499  }
500  n++;
501  }
502 }
void bprintf ( char *  fmt,
  ... 
)

Definiert in Zeile 40 der Datei finsig_thumb2.c.

41 {
42  va_list argp;
43  va_start(argp, fmt);
44 
45  if (out_hdr)
46  hdr_len += vsprintf(hdr_buf+hdr_len,fmt,argp);
47  else
48  out_len += vsprintf(out_buf+out_len,fmt,argp);
49 
50  va_end(argp);
51 }
int compare_func_addresses ( const sig_entry_t **  p1,
const sig_entry_t **  p2 
)

Definiert in Zeile 6076 der Datei finsig_thumb2.c.

6077 {
6078  if ((*p1)->val < (*p2)->val)
6079  return -1;
6080  else if ((*p1)->val > (*p2)->val)
6081  return 1;
6082  return compare_sig_names(p1,p2);
6083 }
int compare_sig_names ( const sig_entry_t **  p1,
const sig_entry_t **  p2 
)

Definiert in Zeile 6061 der Datei finsig_thumb2.c.

6062 {
6063  int rv = strcasecmp((*p1)->name, (*p2)->name); // Case insensitive
6064  if (rv != 0)
6065  return rv;
6066  rv = strcmp((*p1)->name, (*p2)->name); // Case sensitive (if equal with insensitive test)
6067  if (rv != 0)
6068  return rv;
6069  if ((*p1)->val < (*p2)->val)
6070  return -1;
6071  else if ((*p1)->val > (*p2)->val)
6072  return 1;
6073  return 0;
6074 }
void do_km_vals ( firmware fw,
uint32_t  tadr,
int  tsiz,
int  tlen 
)

Definiert in Zeile 5852 der Datei finsig_thumb2.c.

5853 {
5854  uint32_t key_half = add_kmval(fw,tadr,tsiz,tlen,0,"KEY_SHOOT_HALF",0);
5855  add_kmval(fw,tadr,tsiz,tlen,1,"KEY_SHOOT_FULL",key_half);
5856  add_kmval(fw,tadr,tsiz,tlen,1,"KEY_SHOOT_FULL_ONLY",0);
5857 
5858  add_kmval(fw,tadr,tsiz,tlen,0x101,"KEY_PLAYBACK",0);
5859  add_kmval(fw,tadr,tsiz,tlen,0x100,"KEY_POWER",0);
5860 
5861  // mostly copied from finsig_dryos, with < r52 stuff removed
5862  if (fw->dryos_ver == 52) // unclear if this applies any other ver
5863  {
5864  add_kmval(fw,tadr,tsiz,tlen,3,"KEY_ZOOM_IN",0);
5865  add_kmval(fw,tadr,tsiz,tlen,4,"KEY_ZOOM_OUT",0);
5866  add_kmval(fw,tadr,tsiz,tlen,6,"KEY_UP",0);
5867  add_kmval(fw,tadr,tsiz,tlen,7,"KEY_DOWN",0);
5868  add_kmval(fw,tadr,tsiz,tlen,8,"KEY_LEFT",0);
5869  add_kmval(fw,tadr,tsiz,tlen,9,"KEY_RIGHT",0);
5870  add_kmval(fw,tadr,tsiz,tlen,0xA,"KEY_SET",0);
5871  add_kmval(fw,tadr,tsiz,tlen,0xB,"KEY_MENU",0);
5872  add_kmval(fw,tadr,tsiz,tlen,0xC,"KEY_DISPLAY",0);
5873  add_kmval(fw,tadr,tsiz,tlen,0x12,"KEY_HELP",0);
5874  add_kmval(fw,tadr,tsiz,tlen,0x19,"KEY_ERASE",0);
5875  add_kmval(fw,tadr,tsiz,tlen,2,"KEY_VIDEO",0);
5876 // add_kmval(fw,tadr,tsiz,tlen,18,"KEY_SHORTCUT",0);
5877  }
5878  else if (fw->dryos_ver < 54)
5879  {
5880  add_kmval(fw,tadr,tsiz,tlen,2,"KEY_ZOOM_IN",0);
5881  add_kmval(fw,tadr,tsiz,tlen,3,"KEY_ZOOM_OUT",0);
5882  add_kmval(fw,tadr,tsiz,tlen,4,"KEY_UP",0);
5883  add_kmval(fw,tadr,tsiz,tlen,5,"KEY_DOWN",0);
5884  add_kmval(fw,tadr,tsiz,tlen,6,"KEY_LEFT",0);
5885  add_kmval(fw,tadr,tsiz,tlen,7,"KEY_RIGHT",0);
5886  add_kmval(fw,tadr,tsiz,tlen,8,"KEY_SET",0);
5887  add_kmval(fw,tadr,tsiz,tlen,9,"KEY_MENU",0);
5888  add_kmval(fw,tadr,tsiz,tlen,0xA,"KEY_DISPLAY",0);
5889  }
5890  else if (fw->dryos_ver < 55)
5891  {
5892  add_kmval(fw,tadr,tsiz,tlen,3,"KEY_ZOOM_IN",0);
5893  add_kmval(fw,tadr,tsiz,tlen,4,"KEY_ZOOM_OUT",0);
5894  add_kmval(fw,tadr,tsiz,tlen,6,"KEY_UP",0);
5895  add_kmval(fw,tadr,tsiz,tlen,7,"KEY_DOWN",0);
5896  add_kmval(fw,tadr,tsiz,tlen,8,"KEY_LEFT",0);
5897  add_kmval(fw,tadr,tsiz,tlen,9,"KEY_RIGHT",0);
5898  add_kmval(fw,tadr,tsiz,tlen,0xA,"KEY_SET",0);
5899  add_kmval(fw,tadr,tsiz,tlen,0xE,"KEY_MENU",0);
5900  add_kmval(fw,tadr,tsiz,tlen,2,"KEY_VIDEO",0);
5901  add_kmval(fw,tadr,tsiz,tlen,0xD,"KEY_DISPLAY",0);
5902  add_kmval(fw,tadr,tsiz,tlen,0x103,"KEY_WIFI",0);
5903 // framing assist / shortuct
5904 // add_kmval(fw,tadr,tsiz,tlen,0xF,"KEY_",0);
5905  }
5906  else if (fw->dryos_ver < 59)
5907  {
5908  add_kmval(fw,tadr,tsiz,tlen,3,"KEY_ZOOM_IN",0);
5909  add_kmval(fw,tadr,tsiz,tlen,4,"KEY_ZOOM_OUT",0);
5910  add_kmval(fw,tadr,tsiz,tlen,6,"KEY_UP",0);
5911  add_kmval(fw,tadr,tsiz,tlen,7,"KEY_DOWN",0);
5912  add_kmval(fw,tadr,tsiz,tlen,8,"KEY_LEFT",0);
5913  add_kmval(fw,tadr,tsiz,tlen,9,"KEY_RIGHT",0);
5914  add_kmval(fw,tadr,tsiz,tlen,0xA,"KEY_SET",0);
5915  add_kmval(fw,tadr,tsiz,tlen,0x14,"KEY_MENU",0);
5916  add_kmval(fw,tadr,tsiz,tlen,2,"KEY_VIDEO",0);
5917  add_kmval(fw,tadr,tsiz,tlen,0xD,"KEY_DISPLAY",0);
5918  add_kmval(fw,tadr,tsiz,tlen,0x103,"KEY_WIFI",0);
5919 // framing assist, shortcut
5920 // add_kmval(fw,tadr,tsiz,tlen,0xF,"KEY_",0);
5921  }
5922  else
5923  {
5924  add_kmval(fw,tadr,tsiz,tlen,3,"KEY_ZOOM_IN",0);
5925  add_kmval(fw,tadr,tsiz,tlen,4,"KEY_ZOOM_OUT",0);
5926  add_kmval(fw,tadr,tsiz,tlen,6,"KEY_UP",0);
5927  add_kmval(fw,tadr,tsiz,tlen,7,"KEY_DOWN",0);
5928  add_kmval(fw,tadr,tsiz,tlen,8,"KEY_LEFT",0);
5929  add_kmval(fw,tadr,tsiz,tlen,9,"KEY_RIGHT",0);
5930  add_kmval(fw,tadr,tsiz,tlen,0xA,"KEY_SET",0);
5931  add_kmval(fw,tadr,tsiz,tlen,0x15,"KEY_MENU",0);
5932  add_kmval(fw,tadr,tsiz,tlen,2,"KEY_VIDEO",0);
5933  add_kmval(fw,tadr,tsiz,tlen,0xB,"KEY_ERASE",0); // also framing assist etc
5934  add_kmval(fw,tadr,tsiz,tlen,0x103,"KEY_WIFI",0);
5935  }
5936 
5937  bprintf("\n// Keymap values for kbd.c. Additional keys may be present, only common values included here.\n");
5938  bprintf("// WARNING: Key name / function may vary! Values for unknown DryOS versions should not be trusted!\n");
5939  print_kmvals();
5940 }
uint32_t find_call_near_str ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 4244 der Datei finsig_thumb2.c.

4245 {
4246  uint32_t str_adr;
4247  if(rule->param & SIG_NEAR_INDIRECT) {
4248  str_adr = find_str_bytes(fw,rule->ref_name); // indirect string could be in data area
4249  } else {
4250  str_adr = find_str_bytes_main_fw(fw,rule->ref_name); // direct string must be near actual code
4251  }
4252  if(!str_adr) {
4253  printf("find_call_near_str: %s failed to find ref %s\n",rule->name,rule->ref_name);
4254  return 0;
4255  }
4256  uint32_t search_adr = str_adr;
4257  // looking for ref to ptr to string, not ref to string
4258  // TODO only looks for first ptr
4259  if(rule->param & SIG_NEAR_INDIRECT) {
4260  // printf("find_call_near_str: %s str 0x%08x\n",rule->name,str_adr);
4262  if(!search_adr) {
4263  printf("find_call_near_str: %s failed to find indirect ref %s\n",rule->name,rule->ref_name);
4264  return 0;
4265  }
4266  // printf("find_call_near_str: %s indirect 0x%08x\n",rule->name,search_adr);
4267  }
4268  const insn_match_t *insn_match;
4269  if(rule->param & SIG_NEAR_JMP_SUB) {
4270  insn_match = match_b_bl_blximm;
4271  } else {
4272  insn_match = match_bl_blximm;
4273  }
4274 
4275  int max_insns=rule->param&SIG_NEAR_OFFSET_MASK;
4277  //printf("find_call_near_str: %s max_insns %d n %d %s\n",rule->name,max_insns,n,(rule->param & SIG_NEAR_REV)?"rev":"fwd");
4278  // TODO should handle multiple instances of string
4279  disasm_iter_init(fw,is,(ADR_ALIGN4(search_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default); // reset to a bit before where the string was found
4280  while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,search_adr+SEARCH_NEAR_REF_RANGE)) {
4281  // bactrack looking for preceding call
4282  if(rule->param & SIG_NEAR_REV) {
4283  int i;
4284  int n_calls=0;
4285  for(i=1; i<=max_insns; i++) {
4287  if(insn_match_any(fw->is->insn,insn_match)) {
4288  n_calls++;
4289  }
4290  if(n_calls == n) {
4291  return iter_state_adr(fw->is);
4292  }
4293  }
4294  } else {
4295  if(insn_match_find_nth(fw,is,max_insns,n,insn_match)) {
4296  return iter_state_adr(is);
4297  }
4298  }
4299  }
4300  printf("find_call_near_str: no match %s\n",rule->name);
4301  return 0;
4302 }
void find_ctypes ( firmware fw)

Definiert in Zeile 5310 der Datei finsig_thumb2.c.

5311 {
5312  static unsigned char ctypes[] =
5313  {
5314  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x60, 0x60, 0x60, 0x60, 0x20, 0x20,
5315  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
5316  0x48, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
5317  0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
5318  0x10, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5319  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0x10, 0x10, 0x10, 0x10, 0x10,
5320  0x10, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 2, 2, 2, 2, 2, 2, 2, 2, 2,
5321  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0x10, 0x10, 0x10, 0x10, 0x20
5322  };
5323 
5324  uint32_t ctypes_matches[10];
5325  int match_count = find_bytes_all(fw,ctypes,sizeof(ctypes),fw->base,ctypes_matches,10);
5326  if(!match_count) {
5327  return;
5328  }
5329  if(match_count == 10) {
5330  fprintf(stderr,"WARNING found 10+ ctypes!\n");
5331  }
5332  int i;
5333  int match_i;
5334  uint32_t min_adr = 0xFFFFFFFF;
5335  for(i = 0; i< match_count; i++) {
5336  // ref should easily be in the first 1M
5337  uint32_t maxadr = (fw->rom_code_search_max_adr > fw->base + 0x400000)?fw->base + 0x100000:fw->rom_code_search_max_adr;
5338  uint32_t adr = find_u32_adr_range(fw,ctypes_matches[i],fw->rom_code_search_min_adr,maxadr);
5339  if(adr && adr < min_adr) {
5340  min_adr = adr;
5341  match_i = i;
5342  }
5343  }
5344  if(min_adr == 0xFFFFFFFF) {
5345  fprintf(stderr,"WARNING cytpes pointer not found, defaulting to first\n");
5346  match_i = 0;
5347  }
5348  save_misc_val("ctypes",ctypes_matches[match_i],0,min_adr);
5349 }
void find_exception_handlers ( firmware fw,
iter_state_t is 
)

Definiert in Zeile 5203 der Datei finsig_thumb2.c.

5204 {
5205  uint32_t ex_vec = 0;
5206  // somewhat duplicated from to firmware_load_ng, but it's simple
5207  if (fw->arch_flags & FW_ARCH_FL_VMSA) {
5208  const insn_match_t match_mcr_vbar[]={
5209  // Vector Base Address Register MCR p15, 0, <Rt>, c12, c0, 0 - not present on PMSA
5211  {ARM_INS_ENDING}
5212  };
5213  // reset to main fw start
5214  disasm_iter_init(fw, is, fw->base + fw->main_offs + 12 + fw->thumb_default);
5215  if(!insn_match_find_next(fw,is,4,match_mcr_vbar)) {
5216  return;
5217  }
5218  // back up one
5219  disasm_iter_init(fw, is, adr_hist_get(&is->ah,1));
5220  disasm_iter(fw, is);
5221  // expect ldr to be exception vector address
5222  ex_vec = LDR_PC2val(fw,is->insn);
5223  if(!ex_vec || adr_get_range_type(fw,ex_vec) != ADR_RANGE_ROM) {
5224  return;
5225  }
5226  }
5227  // both d6 and d7 appear to have an ARM instruction in reset, and thumb in the remaining
5228  // which appears contrary to arm documentation (ARM DDI 0406C.c (ID051414)
5229  // On digic 6, Reset appears to be an infinte loop, so must not be expected in any case
5230  disasm_iter_init(fw, is, ex_vec);
5231  disasm_iter(fw, is);
5232 
5233  char *names[]={
5234  "exception_handler_Reset",
5235  "exception_handler_UndefinedInstruction",
5236  "exception_handler_SupervisorCall",
5237  "exception_handler_PrefetchAbort",
5238  "exception_handler_DataAbort",
5239  "exception_handler_NotUsed",
5240  "exception_handler_IRQ",
5241  "exception_handler_FIQ",
5242  };
5243 
5244  uint32_t addr=LDR_PC2val(fw,is->insn);
5245  if(!addr && is->insn->id == ARM_INS_B) {
5246  addr=get_branch_call_insn_target(fw,is);
5247  }
5248  // addr may be 0 (= inf loop at reset vector) but stubs system won't recognize it anyway
5249  if(addr) {
5250  add_func_name(fw,names[0],addr,NULL);
5251  }
5252  disasm_iter_init(fw, is, ADR_SET_THUMB(ex_vec + 4));
5253  int i;
5254  for(i=1; i<8; i++) {
5255  disasm_iter(fw, is);
5256  // all seen so far use a thumb ldr.w pc,...
5257  // "NotUsed" is typically a NOP, which won't get picked up here, but would fall through to IRQ
5258  addr=LDR_PC2val(fw,is->insn);
5259  if(addr) {
5260  add_func_name(fw,names[i],addr,NULL);
5261  }
5262  }
5263 }
void find_generic_funcs ( firmware fw)

Definiert in Zeile 5269 der Datei finsig_thumb2.c.

5269  {
5271 
5272  int match_fn_count=0;
5273 
5274  add_generic_sig_match(match_fns,&match_fn_count,process_reg_eventproc_call,"ExportToEventProcedure_FW");
5275  add_generic_sig_match(match_fns,&match_fn_count,process_reg_eventproc_call,"RegisterEventProcedure_alt1");
5276  add_generic_sig_match(match_fns,&match_fn_count,process_reg_eventproc_call,"RegisterEventProcedure_alt2");
5277  add_generic_sig_match(match_fns,&match_fn_count,process_eventproc_table_call,"RegisterEventProcTable");
5278  add_generic_sig_match(match_fns,&match_fn_count,process_eventproc_table_call,"UnRegisterEventProcTable");
5279  add_generic_sig_match(match_fns,&match_fn_count,process_createtask_call,"CreateTaskStrictly");
5280  if(get_saved_sig_val("CreateTaskStrictly_alt")) {
5281  add_generic_sig_match(match_fns,&match_fn_count,process_createtask_call,"CreateTaskStrictly_alt");
5282  }
5283  add_generic_sig_match(match_fns,&match_fn_count,process_createtask_call,"CreateTask");
5284  if(get_saved_sig_val("CreateTask_alt")) {
5285  add_generic_sig_match(match_fns,&match_fn_count,process_createtask_call,"CreateTask_alt");
5286  }
5287  add_generic_sig_match(match_fns,&match_fn_count,process_eventproc_table_call,"RegisterEventProcTable_alt");
5288  add_generic_sig_match(match_fns,&match_fn_count,process_eventproc_table_call,"UnRegisterEventProcTable_alt");
5289  add_generic_sig_match(match_fns,&match_fn_count,process_add_ptp_handler_call,"add_ptp_handler");
5290 
5291  iter_state_t *is=disasm_iter_new(fw,0);
5292  disasm_iter_init(fw,is,fw->rom_code_search_min_adr | fw->thumb_default); // reset to start of fw
5293  fw_search_insn(fw,is,search_disasm_calls_multi,0,match_fns,0);
5294 
5295  // currently only finds SD1stInit task on a couple cams
5296  int i;
5297  for(i=0;i<fw->adr_range_count;i++) {
5298  if(fw->adr_ranges[i].type != ADR_RANGE_RAM_CODE) {
5299  continue;
5300  }
5301  disasm_iter_init(fw,is,fw->adr_ranges[i].start | fw->thumb_default); // reset to start of range
5302  fw_search_insn(fw,is,search_disasm_calls_multi,0,match_fns,0);
5303  }
5304 
5305  find_exception_handlers(fw,is);
5306 
5307  disasm_iter_free(is);
5308 }
int find_next_sig_call ( firmware fw,
iter_state_t is,
uint32_t  max_offset,
const char *  name 
)

Definiert in Zeile 802 der Datei finsig_thumb2.c.

803 {
804  uint32_t adr=get_saved_sig_val(name);
805 
806  if(!adr) {
807  printf("find_next_sig_call: missing %s\n",name);
808  return 0;
809  }
810 
811  search_calls_multi_data_t match_fns[3];
812 
813  match_fns[0].adr=adr;
814  match_fns[0].fn=search_calls_multi_end;
815  char veneer[128];
816  sprintf(veneer,"j_%s",name);
817  adr=get_saved_sig_val(veneer);
818  if(!adr) {
819  match_fns[1].adr=0;
820  } else {
821  match_fns[1].adr=adr;
822  match_fns[1].fn=search_calls_multi_end;
823  match_fns[2].adr=0;
824  }
825  return fw_search_insn(fw,is,search_disasm_calls_multi,0,match_fns,is->adr + max_offset);
826 }
void find_other_stubs_min ( firmware fw)

Definiert in Zeile 6198 der Datei finsig_thumb2.c.

6199 {
6200  int k,k1;
6201 
6202  out_hdr = 1;
6203 
6204  // focus_len_table
6205  if (fw->sv->min_focus_len != 0)
6206  {
6207  int found = 0, pos = 0, len = 0, size = 0;
6208  for (k=0; k<fw->size32; k++)
6209  {
6210  if (fw->buf32[k] == fw->sv->min_focus_len)
6211  {
6212  int mul = 1;
6213  if ((fw->buf32[k+1] == 100) && (fw->buf32[k+2] == 0)) mul = 3;
6214  if ((fw->buf32[k+1] == 100) && (fw->buf32[k+2] != 0)) mul = 2;
6215  if ((fw->buf32[k+1] == 0) && (fw->buf32[k+2] != 0)) mul = 2;
6216  for (k1 = k + mul; (k1 < fw->size32) && (fw->buf32[k1] > fw->buf32[k1-mul]) && (fw->buf32[k1] > fw->sv->min_focus_len) && (fw->buf32[k1] < fw->sv->max_focus_len); k1 += mul) ;
6217  if (fw->buf32[k1] == fw->sv->max_focus_len)
6218  {
6219  if ((found == 0) || ((size < mul) && (len < ((k1 - k) / mul) + 1)))
6220  {
6221  found = 1;
6222  pos = k;
6223  len = ((k1 - k) / mul) + 1;
6224  size = mul;
6225  }
6226  }
6227  }
6228  }
6229  if (found == 1)
6230  {
6231  uint32_t adr = fw->base + (pos << 2);
6232  bprintf("// focus_len_table contains zoom focus lengths for use in 'get_focal_length' (main.c).\n");
6233  if (size == 1)
6234  bprintf("// each entry contains 1 int value, which is the the zoom focus length.\n",size);
6235  else
6236  bprintf("// each entry contains %d int value(s), the first is the zoom focus length.\n",size);
6237  bprintf("// there are %d entries in the table - set NUM_FL to %d\n",len,len);
6238  print_other_stubs_min(fw,"focus_len_table",adr,adr);
6239  }
6240  }
6241 }
uint32_t find_physw_table_entry ( firmware fw,
uint32_t  tadr,
int  tcount,
uint32_t  ev 
)

Definiert in Zeile 5681 der Datei finsig_thumb2.c.

5682 {
5683  int i;
5684  for(i=0; i<tcount; i++,tadr += 8) {
5685  if(fw_u32(fw,tadr+4) == ev) {
5686  return tadr;
5687  }
5688  }
5689  return 0;
5690 }
uint32_t find_physw_table_max ( firmware fw,
uint32_t  tadr,
int  max_count 
)

Definiert in Zeile 5692 der Datei finsig_thumb2.c.

5693 {
5694  int i;
5695  for(i=0; i<max_count; i++,tadr += 8) {
5697  get_physw_table_entry(fw,tadr,&v);
5698  if(v.raw_info == 0 || v.raw_info == 0xFFFFFFFF || v.reg > 2) {
5699  return i;
5700  }
5701  // TODO could check that no event numbers (except -1) are repeated
5702  }
5703  return max_count;
5704 }
sig_entry_t* find_saved_sig ( const char *  name)

Definiert in Zeile 637 der Datei finsig_thumb2.c.

638 {
639  int i;
640  for (i=0; sig_names[i].name != 0; i++)
641  {
642  if (strcmp(name,sig_names[i].name) == 0)
643  {
644  return &sig_names[i];
645  }
646  }
647  return NULL;
648 }
misc_val_t* get_misc_val ( const char *  name)

Definiert in Zeile 574 der Datei finsig_thumb2.c.

575 {
577  while(p->name) {
578  if(strcmp(name,p->name) == 0) {
579  return p;
580  }
581  p++;
582  }
583  return NULL;
584 }
uint32_t get_misc_val_value ( const char *  name)

Definiert in Zeile 587 der Datei finsig_thumb2.c.

588 {
589  misc_val_t *p=get_misc_val(name);
590  if(!p) {
591  printf("get_misc_val_value: invalid name %s\n",name);
592  return 0;
593  }
594  return p->val;
595 }
void get_physw_table_entry ( firmware fw,
uint32_t  adr,
physw_table_entry_t vals 
)

Definiert in Zeile 5670 der Datei finsig_thumb2.c.

5671 {
5672  uint32_t info=fw_u32(fw,adr);
5673  vals->raw_info=info;
5674  vals->ev=fw_u32(fw,adr+4);
5675  // taken from finsig_dryos print_physw_raw_vals
5676  vals->reg=(info >>5) & 7;
5677  vals->bit=(1 << (info & 0x1f));
5678  // vals->no_invert=(info >> 16) & 1;
5679  vals->no_invert=((info&0xff0000)==0x10000)?1:0;
5680 }
uint32_t get_saved_sig_val ( const char *  name)

Definiert in Zeile 651 der Datei finsig_thumb2.c.

652 {
653  sig_entry_t *sig=find_saved_sig(name);
654  if(!sig) {
655  // printf("get_saved_sig_val: missing %s\n",name);
656  return 0;
657  }
658  return sig->val;
659 }
int init_disasm_sig_ref ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 894 der Datei finsig_thumb2.c.

895 {
896  if(!rule->ref_name) {
897  printf("init_disasm_sig_ref: %s missing ref_name\n",rule->name);
898  return 0;
899  }
901  if(!adr) {
902  printf("init_disasm_sig_ref: %s missing %s\n",rule->name,rule->ref_name);
903  return 0;
904  }
905  if(!disasm_iter_init(fw,is,adr)) {
906  printf("init_disasm_sig_ref: %s bad address 0x%08x for %s\n",rule->name,adr,rule->ref_name);
907  return 0;
908  }
909  return 1;
910 }
int is_immediate_ret_sub ( firmware fw,
iter_state_t is_init 
)

Definiert in Zeile 4359 der Datei finsig_thumb2.c.

4360 {
4361  fw_disasm_iter_single(fw,is_init->adr | is_init->thumb);
4362  const insn_match_t match_mov_r0_imm[]={
4363  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM_ANY}},
4364 #if CS_API_MAJOR < 4
4365  {MATCH_INS(MOVS, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM_ANY}},
4366 #endif
4367  {ARM_INS_ENDING}
4368  };
4369  // if it's a MOV, check if next is ret
4370  if(insn_match_any(fw->is->insn,match_mov_r0_imm)) {
4371  fw_disasm_iter(fw);
4372  }
4373  if(isRETx(fw->is->insn)) {
4374  return 1;
4375  }
4376  return 0;
4377 }
int is_sig_call ( firmware fw,
iter_state_t is,
const char *  name 
)

Definiert in Zeile 829 der Datei finsig_thumb2.c.

830 {
832  // not a call at all
833  // TODO could check if unknown veneer
834  if(!adr) {
835  return 0;
836  }
837  uint32_t sig_adr=get_saved_sig_val(name);
838  osig* ostub2 = find_sig(fw->sv->stubs,name);
839  if (ostub2 && ostub2->val)
840  sig_adr = ostub2->val;
841  if(!sig_adr) {
842  printf("is_sig_call: missing %s\n",name);
843  return 0;
844  }
845  if(adr == sig_adr) {
846  return 1;
847  }
848  char veneer[128];
849  sprintf(veneer,"j_%s",name);
850  sig_adr=get_saved_sig_val(veneer);
851  if(!sig_adr) {
852  return 0;
853  }
854  return (adr == sig_adr);
855 }
int kinfo_compare ( const kinfo p1,
const kinfo p2 
)

Definiert in Zeile 5781 der Datei finsig_thumb2.c.

5782 {
5783  if (p1->reg > p2->reg)
5784  {
5785  return 1;
5786  }
5787  else if (p1->reg < p2->reg)
5788  {
5789  return -1;
5790  }
5791  if ((p1->ev <= 1) && (p2->ev <= 1)) // output shutter entries in reverse order
5792  {
5793  if (p1->bits > p2->bits)
5794  {
5795  return -1;
5796  }
5797  else if (p1->bits < p2->bits)
5798  {
5799  return 1;
5800  }
5801  }
5802  // if one entry is shutter then compare to min shutter bits
5803  if (p1->ev <= 1)
5804  {
5805  if (kshutter_min_bits > p2->bits)
5806  {
5807  return 1;
5808  }
5809  else if (kshutter_min_bits < p2->bits)
5810  {
5811  return -1;
5812  }
5813  }
5814  if (p2->ev <= 1)
5815  {
5816  if (p1->bits > kshutter_min_bits)
5817  {
5818  return 1;
5819  }
5820  else if (p1->bits < kshutter_min_bits)
5821  {
5822  return -1;
5823  }
5824  }
5825  if (p1->bits > p2->bits)
5826  {
5827  return 1;
5828  }
5829  else if (p1->bits < p2->bits)
5830  {
5831  return -1;
5832  }
5833 
5834  return 0;
5835 }
int main ( int  argc,
char **  argv 
)

Definiert in Zeile 6368 der Datei finsig_thumb2.c.

6369 {
6370  clock_t t1 = clock();
6371 
6372  firmware fw;
6373  memset(&fw,0,sizeof(firmware));
6374  if (argc < 4) {
6375  fprintf(stderr,"finsig_thumb2 <primary> <base> <outputfilename>\n");
6376  exit(1);
6377  }
6378 
6380  int max_find_sig = next_sig_entry;
6381 
6382  fw.sv = new_stub_values();
6383  load_stubs(fw.sv, "stubs_entry_2.S", 1);
6384  load_stubs_min(fw.sv);
6385  load_modemap(fw.sv);
6386  load_platform(fw.sv);
6387 
6388  bprintf("// !!! THIS FILE IS GENERATED. DO NOT EDIT. !!!\n");
6389  bprintf("#include \"stubs_asm.h\"\n\n");
6390 
6391  firmware_load(&fw,argv[1],strtoul(argv[2], NULL, 0),FW_ARCH_ARMv7);
6392  if(!firmware_init_capstone(&fw)) {
6393  exit(1);
6394  }
6396 
6397  out_fp = fopen(argv[3],"w");
6398  if (out_fp == NULL) {
6399  fprintf(stderr,"Error opening output file %s\n",argv[3]);
6400  exit(1);
6401  }
6402 
6403 
6404  // find ctypes - previously separate from regular sig matches to set code search limit
6405  find_ctypes(&fw);
6406 
6408  find_generic_funcs(&fw);
6410 
6411  output_firmware_vals(&fw);
6412 
6413  output_platform_vals(&fw);
6414  output_physw_vals(&fw);
6415  output_modemap(&fw);
6416 
6417  output_propcases(&fw);
6418  output_exmem_types(&fw);
6419 
6420  write_stubs(&fw,max_find_sig);
6421 
6422  write_output();
6423  fclose(out_fp);
6424 
6425  write_func_lists(&fw);
6426 
6427  firmware_unload(&fw);
6428 
6429  clock_t t2 = clock();
6430 
6431  printf("Time to generate stubs %.2f seconds\n",(double)(t2-t1)/(double)CLOCKS_PER_SEC);
6432 
6433  return 0;
6434 }
void output_exmem_types ( firmware fw)

Definiert in Zeile 5624 der Datei finsig_thumb2.c.

5625 {
5626 
5627  misc_val_t *ett=get_misc_val("exmem_types_table");
5628  misc_val_t *etc=get_misc_val("exmem_type_count");
5629  if (ett->val == 0 || etc->val == 0) {
5630  return;
5631  }
5632  bprintf("// EXMEM types:\n");
5633  int n;
5634  for (n=0; n<etc->val; n++) {
5635  char *extyp = (char*)adr2ptr(fw, fw_u32(fw,ett->val+n*4));
5636  bprintf("// %s %i\n", extyp, n);
5637  }
5638  add_blankline();
5639 }
void output_firmware_vals ( firmware fw)

Definiert in Zeile 5373 der Datei finsig_thumb2.c.

5374 {
5375  bprintf("// Camera info:\n");
5376  bprintf("// Main firmware start: 0x%08x\n",fw->base+fw->main_offs);
5377  if (fw->dryos_ver == 0)
5378  {
5379  bprintf("// Can't find DRYOS version !!!\n\n");
5380  } else {
5381  bprintf("// DRYOS R%d (%s) @ 0x%08x ref @ 0x%08x\n",
5382  fw->dryos_ver,
5383  fw->dryos_ver_str,
5384  fw->dryos_ver_adr,
5385  fw->dryos_ver_ref_adr);
5386  }
5387  if (fw->firmware_ver_str == 0)
5388  {
5389  bprintf("// Can't find firmware version !!!\n\n");
5390  }
5391  else
5392  {
5393  char *c = strrchr(fw->firmware_ver_str,' ') + 1; // points after the last space char
5394  uint32_t j = ptr2adr(fw,(uint8_t *)fw->firmware_ver_str);
5395  uint32_t k = j + c - fw->firmware_ver_str;
5396  if ( (k>=j) && (k<j+32) )
5397  {
5398  bprintf("// %s // Found @ 0x%08x, \"%s\" @ 0x%08x\n",fw->firmware_ver_str,j,c,k);
5399  }
5400  else
5401  {
5402  // no space found in string (shouldn't happen)
5403  bprintf("// %s // Found @ 0x%08x, \"%s\" @ 0x%08x\n",fw->firmware_ver_str,j,fw->firmware_ver_str,j);
5404  }
5405  }
5406  if (fw->arch_flags & FW_ARCH_FL_VMSA) {
5407  bprintf("// VMSA detected, probably digic >= 7\n");
5408  }
5409 
5410  bprintf("\n// Values for makefile.inc\n");
5411  bprintf("// PLATFORMOSVER = %d\n",fw->dryos_ver);
5412  if (fw->arch_flags & FW_ARCH_FL_VMSA) {
5413  bprintf("// DIGIC = 70\n");
5414  } else {
5415  // 6+ exists, but not for known powershot firmware cams
5416  bprintf("// DIGIC = 60\n");
5417  }
5418 
5419  if (fw->memisostart) {
5420  bprintf("// MEMISOSTART = 0x%x\n",fw->memisostart);
5421  } else {
5422  bprintf("// MEMISOSTART not found !!!\n");
5423  }
5424  if (fw->data_init_start)
5425  {
5426  bprintf("// MEMBASEADDR = 0x%x\n",fw->data_start);
5427  }
5428  print_misc_val_makefile("ARAM_HEAP_START");
5429  print_misc_val_makefile("ARAM_HEAP_SIZE");
5430 
5431  bprintf("\n// Detected address ranges:\n");
5432  int i;
5433  for(i=0; i<fw->adr_range_count; i++) {
5434  if(fw->adr_ranges[i].type == ADR_RANGE_ROM) {
5435  bprintf("// %-8s 0x%08x - 0x%08x (%7d bytes)\n",
5436  adr_range_desc_str(&fw->adr_ranges[i]),
5437  fw->adr_ranges[i].start,
5438  fw->adr_ranges[i].start+fw->adr_ranges[i].bytes,
5439  fw->adr_ranges[i].bytes);
5440  } else {
5441  bprintf("// %-8s 0x%08x - 0x%08x copied from 0x%08x (%7d bytes)\n",
5442  adr_range_desc_str(&fw->adr_ranges[i]),
5443  fw->adr_ranges[i].start,
5444  fw->adr_ranges[i].start+fw->adr_ranges[i].bytes,
5445  fw->adr_ranges[i].src_start,
5446  fw->adr_ranges[i].bytes);
5447  }
5448  }
5449  misc_val_t *mv=get_misc_val("zicokick_values");
5450  if(mv->blobs) {
5451  bprintf("\n// Zico Xtensa blobs:\n");
5452  for(i=0;mv->blobs[i].type != MISC_BLOB_TYPE_NONE;i++) {
5453  bprintf("// zico_%d 0x%08x - 0x%08x copied from 0x%08x (%7d bytes)\n",
5454  i,
5455  mv->blobs[i].ram_adr,
5456  mv->blobs[i].ram_adr+mv->blobs[i].size,
5457  mv->blobs[i].rom_adr,
5458  mv->blobs[i].size);
5459  }
5460 
5461  }
5462  mv=get_misc_val("omar_init_values");
5463  if(mv->blobs) {
5464  bprintf("\n// Omar ARM blobs:\n");
5465  for(i=0;mv->blobs[i].type != MISC_BLOB_TYPE_NONE;i++) {
5466  bprintf("// omar_%d 0x%08x - 0x%08x copied from 0x%08x (%7d bytes)\n",
5467  i,
5468  mv->blobs[i].ram_adr,
5469  mv->blobs[i].ram_adr+mv->blobs[i].size,
5470  mv->blobs[i].rom_adr,
5471  mv->blobs[i].size);
5472  }
5473  }
5474  if(fw->dryos_ver_count) {
5475  bprintf("\n// Found DryOS versions:\n");
5476  for(i=0;i<fw->dryos_ver_count;i++) {
5477  bprintf("// 0x%08x %s \"%s\"\n",
5478  fw->dryos_ver_list[i], (fw->dryos_ver_list[i] == fw->dryos_ver_adr) ? "main ":"other",
5479  (char *)adr2ptr(fw,fw->dryos_ver_list[i]));
5480  }
5481  add_blankline();
5482  }
5483  add_blankline();
5484 
5485  // check if CreateTask is in ROM, offer CreateTask_low if it's in RAM
5486  sig_entry_t * ct = find_saved_sig("hook_CreateTask");
5487  if(ct && adr_get_range_type(fw,ct->val) != ADR_RANGE_RAM_CODE) {
5488  bprintf("// CreateTask is not in RAM code\n");
5489  ct->flags |= UNUSED;
5490  sig_entry_t * ctl = find_saved_sig("CreateTask_low");
5491  if(ctl && adr_get_range_type(fw,ctl->val) == ADR_RANGE_RAM_CODE) {
5492  bprintf("// use hook_CreateTask_low instead\n");
5493  ctl->flags &= ~UNUSED;
5494  sig_entry_t * hctl = find_saved_sig("hook_CreateTask_low");
5495  hctl->flags &= ~UNUSED;
5496  }
5497  add_blankline();
5498  }
5499 }
void output_modemap ( firmware fw)

Definiert in Zeile 6007 der Datei finsig_thumb2.c.

6007  {
6008  print_misc_val_comment("canon_mode_list");
6009  bprintf("// Check modemap values from 'platform/CAMERA/shooting.c':\n");
6010  misc_val_t *mv=get_misc_val("canon_mode_list");
6011  if(!mv) {
6012  add_blankline();
6013  return;
6014  }
6015  int i;
6016  uint32_t adr=mv->val;
6017  int bad=0;
6018  for(i=0; i<50; i++,adr+=2) {
6019  uint16_t *pv=(uint16_t*)adr2ptr(fw,adr);
6020  if(!pv) {
6021  break;
6022  }
6023  if(*pv==0xFFFF) {
6024  break;
6025  }
6026  osig *m = find_sig_val(fw->sv->modemap, *pv);
6027  if (!m) {
6028  bprintf("// %5hu 0x%04hx In firmware but not in current modemap",*pv,*pv);
6029  /*
6030  char *s = mode_name(*pv);
6031  if (strcmp(s,"") != 0) {
6032  bprintf(" (%s)",s);
6033  }
6034  */
6035  bprintf("\n");
6036  bad++;
6037  } else {
6038 // bprintf("// %5hu 0x%04hx %s\n", *pv,*pv,m->nm);
6039  m->pct = 100;
6040  }
6041  }
6042  osig *m = fw->sv->modemap;
6043  while (m)
6044  {
6045  if (m->pct != 100) // not matched above?
6046  {
6047  bprintf("// Current modemap entry not found in firmware - %-24s %5d\n",m->nm,m->val);
6048  bad++;
6049  }
6050  m = m->nxt;
6051  }
6052  if (bad == 0)
6053  {
6054  bprintf("// No problems found with modemap table.\n");
6055  }
6056 
6057  add_blankline();
6058 }
void output_physw_vals ( firmware fw)

Definiert in Zeile 5941 der Datei finsig_thumb2.c.

5941  {
5942  print_misc_val_comment("physw_event_table");
5943  uint32_t physw_tbl=get_misc_val_value("physw_event_table");
5944  if(!physw_tbl) {
5945  return;
5946  }
5947  int physw_tbl_len=find_physw_table_max(fw,physw_tbl,50);
5948  write_physw_event_table_dump(fw,physw_tbl,physw_tbl_len);
5949 
5950  bprintf("// Values below go in 'platform_kbd.h':\n");
5951  if (fw->dryos_ver >= 58)
5952  {
5953  // Event ID's have changed in DryOS 58 **********
5954  print_kval(fw,physw_tbl,physw_tbl_len,0x30A,"SD_READONLY","_FLAG");
5955  print_kval(fw,physw_tbl,physw_tbl_len,0x302,"USB","_MASK");
5956  print_kval(fw,physw_tbl,physw_tbl_len,0x305,"BATTCOVER","_FLAG");
5957  print_kval(fw,physw_tbl,physw_tbl_len,0x304,"HOTSHOE","_FLAG");
5958  print_kval(fw,physw_tbl,physw_tbl_len,0x300,"ANALOG_AV","_FLAG");
5959  }
5960  else
5961  {
5962  print_kval(fw,physw_tbl,physw_tbl_len,0x20A,"SD_READONLY","_FLAG");
5963  print_kval(fw,physw_tbl,physw_tbl_len,0x202,"USB","_MASK");
5964  print_kval(fw,physw_tbl,physw_tbl_len,0x205,"BATTCOVER","_FLAG");
5965  print_kval(fw,physw_tbl,physw_tbl_len,0x204,"HOTSHOE","_FLAG");
5966  print_kval(fw,physw_tbl,physw_tbl_len,0x200,"ANALOG_AV","_FLAG");
5967  }
5968  do_km_vals(fw,physw_tbl,2,physw_tbl_len);
5969 
5970  add_blankline();
5971 }
void output_platform_vals ( firmware fw)

Definiert in Zeile 5511 der Datei finsig_thumb2.c.

5511  {
5512  bprintf("// Values below go in 'platform_camera.h':\n");
5513  bprintf("//#define CAM_DRYOS 1\n");
5514  if (fw->dryos_ver >= 39)
5515  bprintf("//#define CAM_DRYOS_2_3_R39 1 // Defined for cameras with DryOS version R39 or higher\n");
5516  if (fw->dryos_ver >= 47)
5517  bprintf("//#define CAM_DRYOS_2_3_R47 1 // Defined for cameras with DryOS version R47 or higher\n");
5518  if (fw->dryos_ver >= 59)
5519  bprintf("//#define CAM_DRYOS_2_3_R59 1 // Defined for cameras with DryOS version R59 or higher\n");
5520 
5521  if(get_misc_val_value("CAM_IS_ILC")) {
5522  bprintf("//#define CAM_ILC 1 // Camera is interchangeable lens\n");
5523  }
5524 
5525 
5526  print_platform_misc_val_undef("CAM_UNCACHED_BIT",0x10000000);
5527 
5528  if(get_misc_val_value("CAM_HAS_ND_FILTER")) {
5529  bprintf("//#define CAM_HAS_ND_FILTER 1 // Camera has ND filter\n");
5530  } else {
5531  bprintf("//#undef CAM_HAS_ND_FILTER // Camera does not have an ND filter\n");
5532  }
5533  if(get_misc_val_value("CAM_HAS_IRIS_DIAPHRAGM")) {
5534  bprintf("// Camera has an iris (CAM_HAS_IRIS_DIAPHRAGM default)\n");
5535  } else {
5536  bprintf("//#undef CAM_HAS_IRIS_DIAPHRAGM // Camera does not have an iris\n");
5537  }
5538 
5539  add_blankline();
5540 }
void output_propcases ( firmware fw)

Definiert in Zeile 5542 der Datei finsig_thumb2.c.

5542  {
5543 
5544  uint32_t used=0;
5546  const uint32_t ps_offset = 6;
5547 
5548  memset(hits, 0, KNOWN_PROPSET_COUNT*sizeof(uint32_t));
5549 
5550  bprintf("// Known propcases\n");
5551 
5552  int n = 0;
5553  while (knownprops[n].name) {
5554  used += knownprops[n].use>0?1:0;
5555  if (knownprops[n].id >= 0)
5556  {
5557  if (knownprops[n].use)
5558  {
5559  if (knownprops[n].id == knownprops[n].id_ps6) hits[6-ps_offset] += 1;
5560  if (knownprops[n].id == knownprops[n].id_ps7) hits[7-ps_offset] += 1;
5561  if (knownprops[n].id == knownprops[n].id_ps8) hits[8-ps_offset] += 1;
5562  if (knownprops[n].id == knownprops[n].id_ps9) hits[9-ps_offset] += 1;
5563  if (knownprops[n].id == knownprops[n].id_ps10) hits[10-ps_offset] += 1;
5564  if (knownprops[n].id == knownprops[n].id_ps11) hits[11-ps_offset] += 1;
5565  if (knownprops[n].id == knownprops[n].id_ps12) hits[12-ps_offset] += 1;
5566  if (knownprops[n].id == knownprops[n].id_ps13) hits[13-ps_offset] += 1;
5567  }
5568  if (knownprops[n].use == 1)
5569  {
5570  bprintf("// #define %s %i\n", knownprops[n].name, knownprops[n].id);
5571  }
5572  else
5573  {
5574  // propcases not used by CHDK, name may be made up
5575  bprintf("// // %s %i\n", knownprops[n].name, knownprops[n].id);
5576  }
5577  }
5578  else
5579  {
5580  bprintf("// %s not found\n", knownprops[n].name);
5581  }
5582  n++;
5583  }
5584 
5585  bprintf("// Guessed propset: ");
5586  int m = 0;
5587  int fmax = 0;
5588  int okay = 0;
5589  for (n=0; n<KNOWN_PROPSET_COUNT; n++)
5590  {
5591  if (hits[n] == used)
5592  {
5593  if (m) bprintf(", ");
5594  bprintf("%i", n+ps_offset);
5595  if (fw->sv->propset == n+ps_offset) okay = 1; // if the propset equals to (one of) the complete propset matches
5596  m += 1;
5597  }
5598  if (hits[n] > fmax) fmax = hits[n];
5599  }
5600  if (m == 0)
5601  {
5602  bprintf("uncertain (%i of %u match), closest to ",fmax,used);
5603  for (n=0; n<KNOWN_PROPSET_COUNT; n++)
5604  {
5605  if (hits[n] == fmax)
5606  {
5607  if (m) bprintf(", ");
5608  bprintf("%i", n+ps_offset);
5609  if (fw->sv->propset == n+ps_offset) okay = 1; // if the propset equals to (one of) the most complete propset matches
5610  m += 1;
5611  }
5612  }
5613  }
5614  bprintf("\n");
5615  if (!okay && fw->sv->propset>0)
5616  {
5617  // only shown when there's a clear mismatch
5618  bprintf("// Port's propset (%i) may be set incorrectly\n", fw->sv->propset);
5619  }
5620 
5621  add_blankline();
5622 }
void print_kmvals ( )

Definiert in Zeile 5837 der Datei finsig_thumb2.c.

5838 {
5839  qsort(key_info, kcount, sizeof(kinfo), (void*)kinfo_compare);
5840 
5841  bprintf("//KeyMap keymap[] = {\n");
5842 
5843  int k;
5844  for (k=0; k<kcount; k++)
5845  {
5846  bprintf("// { %d, %-20s,0x%08x }, // Found @0x%08x, levent 0x%02x%s\n",key_info[k].reg,key_info[k].nm,key_info[k].bits,key_info[k].fadr,key_info[k].ev,(key_info[k].inv==0)?"":" (uses inverted logic in physw_status)");
5847  }
5848 
5849  bprintf("// { 0, 0, 0 }\n//};\n");
5850 }
void print_kval ( firmware fw,
uint32_t  tadr,
int  tcount,
uint32_t  ev,
const char *  name,
const char *  sfx 
)

Definiert in Zeile 5722 der Datei finsig_thumb2.c.

5723 {
5724  uint32_t adr=find_physw_table_entry(fw,tadr,tcount,ev);
5725  if(!adr) {
5726  return;
5727  }
5729  get_physw_table_entry(fw,adr,&v);
5730 
5731  char fn[100], rn[100];
5732  strcpy(fn,name); strcat(fn,sfx);
5733  strcpy(rn,name); strcat(rn,"_IDX");
5734 
5735  bprintf("//#define %-20s0x%08x // Found @0x%08x, levent 0x%x%s\n",fn,v.bit,adr,v.ev,v.no_invert?" (non-inverted logic)":"");
5736  bprintf("//#define %-20s%d\n",rn,v.reg);
5737 
5738 }
void print_misc_val_comment ( const char *  name)

Definiert in Zeile 5641 der Datei finsig_thumb2.c.

5642 {
5643  misc_val_t *mv=get_misc_val(name);
5644  if(!mv) {
5645  return;
5646  }
5647  // TODO legitimate 0 values might be possible, if so can add found bit
5648  if(!mv->val) {
5649  bprintf("// %s not found\n",name);
5650  return;
5651  }
5652  bprintf("// %s 0x%08x",name,mv->val);
5653  if(mv->offset) {
5654  bprintf(" (0x%x+0x%x)",mv->base,mv->offset);
5655  }
5656  if(mv->ref_adr) {
5657  bprintf(" Found @0x%08x",mv->ref_adr);
5658  }
5659  bprintf("\n");
5660 }
void print_misc_val_makefile ( const char *  name)

Definiert in Zeile 5351 der Datei finsig_thumb2.c.

5352 {
5353  misc_val_t *mv=get_misc_val(name);
5354  if(!mv) {
5355  return;
5356  }
5357  // TODO legitimate 0 values might be possible, if so can add found bit
5358  if(!mv->val) {
5359  bprintf("// %s not found\n",name);
5360  return;
5361  }
5362  bprintf("// %s = 0x%08x# ",name,mv->val);
5363  if(mv->offset) {
5364  bprintf(" (0x%x+0x%x)",mv->base,mv->offset);
5365  }
5366  if(mv->ref_adr) {
5367  bprintf(" Found @0x%08x",mv->ref_adr);
5368  }
5369  bprintf("\n");
5370 }
void print_other_stubs_min ( firmware fw,
const char *  name,
uint32_t  fadr,
uint32_t  atadr 
)

Definiert in Zeile 6129 der Datei finsig_thumb2.c.

6130 {
6131  osig *o = find_sig(fw->sv->stubs_min,name);
6132  if (o)
6133  {
6134  bprintf("//DEF(%-40s,0x%08x) // Found @0x%08x",name,fadr,atadr);
6135  if (fadr != o->val)
6136  {
6137  bprintf(", ** != ** stubs_min = 0x%08x (%s)",o->val,o->sval);
6138  }
6139  else
6140  {
6141  bprintf(", stubs_min = 0x%08x (%s)",o->val,o->sval);
6142  }
6143  }
6144  else
6145  {
6146  bprintf("DEF(%-40s,0x%08x) // Found @0x%08x",name,fadr,atadr);
6147  }
6148  bprintf("\n");
6149 }
void print_platform_misc_val_undef ( const char *  name,
uint32_t  def 
)

Definiert in Zeile 5502 der Datei finsig_thumb2.c.

5503 {
5504  misc_val_t *mv=get_misc_val(name);
5505  if(mv && mv->val && mv->val != def) {
5506  bprintf("//#undef %s\n",name);
5507  bprintf("//#define %s 0x%08x // Found @0x%08x\n",name,mv->val,mv->ref_adr);
5508  }
5509 }
void print_results ( firmware fw,
sig_entry_t sig 
)

Definiert in Zeile 6245 der Datei finsig_thumb2.c.

6246 {
6247  int i;
6248  int err = 0;
6249  char line[500] = "";
6250 
6251  if (sig->flags & DONT_EXPORT) {
6252  return;
6253  }
6254 
6255  if ((sig->flags & DONT_EXPORT_ILC) && get_misc_val_value("CAM_IS_ILC")) {
6256  return;
6257  }
6258 
6259  // find best match and report results
6260  osig* ostub2 = find_sig(fw->sv->stubs,sig->name);
6261 
6262  if (ostub2 && (sig->val != ostub2->val))
6263  {
6264  if (ostub2->type != TYPE_IGNORE)
6265  {
6266  err = 1;
6267  sig->flags |= BAD_MATCH;
6268  }
6269  }
6270  else
6271  {
6272  if (sig->flags & UNUSED) return;
6273  }
6274 
6275  // write to header (if error) or body buffer (no error)
6276  out_hdr = err;
6277 
6278  char *macro = "NHSTUB";
6279  if (sig->flags & ARM_STUB) {
6280  macro = "NHSTUB2";
6281  }
6282  if (strncmp(sig->name,"task_",5) == 0 ||
6283  strncmp(sig->name,"hook_",5) == 0) macro = " DEF";
6284 
6285  if (!sig->val && !ostub2)
6286  {
6287  if (sig->flags & OPTIONAL) return;
6288  char fmt[51] = "";
6289  sprintf(fmt, "// ERROR: %%s is not found. %%%ds//--- --- ", (int)(34-strlen(sig->name)));
6290  sprintf(line+strlen(line), fmt, sig->name, "");
6291  }
6292  else
6293  {
6294  if (ostub2 || (sig->flags & UNUSED))
6295  sprintf(line+strlen(line),"//%s(%-37s,0x%08x) //%3d ", macro, sig->name, sig->val, 0);
6296  else
6297  sprintf(line+strlen(line),"%s(%-39s,0x%08x) //%3d ", macro, sig->name, sig->val, 0);
6298 
6299  /*
6300  if (matches->fail > 0)
6301  sprintf(line+strlen(line),"%2d%% ", matches->success*100/(matches->success+matches->fail));
6302  else
6303  */
6304  sprintf(line+strlen(line)," ");
6305  }
6306 
6307  if (ostub2)
6308  {
6309  if (ostub2->type == TYPE_IGNORE)
6310  sprintf(line+strlen(line)," Overridden");
6311  else if (sig->val == ostub2->val)
6312  sprintf(line+strlen(line)," == 0x%08x ",ostub2->val);
6313  else {
6314  // if both have same value check if differs only by veneer
6315  if(sig->val && ostub2->val) {
6316  fw_disasm_iter_single(fw,ostub2->val);
6317  if(get_direct_jump_target(fw,fw->is) == sig->val) {
6318  sprintf(line+strlen(line)," <-veneer 0x%08x ",ostub2->val);
6319  } else {
6320  fw_disasm_iter_single(fw,sig->val);
6321  if(get_direct_jump_target(fw,fw->is) == ostub2->val) {
6322  sprintf(line+strlen(line)," veneer-> 0x%08x ",ostub2->val);
6323  } else {
6324  sprintf(line+strlen(line)," *** != 0x%08x ",ostub2->val);
6325  }
6326  }
6327  } else {
6328  sprintf(line+strlen(line)," *** != 0x%08x ",ostub2->val);
6329  }
6330  }
6331  }
6332  else
6333  sprintf(line+strlen(line)," ");
6334 
6335  for (i=strlen(line)-1; i>=0 && line[i]==' '; i--) line[i] = 0;
6336  bprintf("%s\n",line);
6337 
6338  /*
6339  for (i=1;i<count && matches[i].fail==matches[0].fail;i++)
6340  {
6341  if (matches[i].ptr != matches->ptr)
6342  {
6343  bprintf("// ALT: %s(%s, 0x%x) // %d %d/%d\n", macro, curr_name, matches[i].ptr, matches[i].sig, matches[i].success, matches[i].fail);
6344  }
6345  }
6346  */
6347 }
void print_stubs_min_def ( firmware fw,
misc_val_t sig 
)

Definiert in Zeile 6151 der Datei finsig_thumb2.c.

6152 {
6153  if(sig->flags & MISC_VAL_NO_STUB) {
6154  return;
6155  }
6156  // find best match and report results
6157  osig* ostub2=find_sig(fw->sv->stubs_min,sig->name);
6158 
6159  const char *macro = "DEF";
6160  if(sig->flags & MISC_VAL_DEF_CONST) {
6161  macro="DEF_CONST";
6162  }
6163 
6164  if (ostub2)
6165  {
6166  bprintf("//%s(%-34s,0x%08x)",macro,sig->name,sig->val);
6167  if (sig->val != ostub2->val)
6168  {
6169  bprintf(", ** != ** stubs_min = 0x%08x (%s)",ostub2->val,ostub2->sval);
6170  }
6171  else
6172  {
6173  bprintf(", stubs_min = 0x%08x (%s)",ostub2->val,ostub2->sval);
6174  }
6175  }
6176  else if(sig->base || sig->offset)
6177  {
6178  bprintf("%s(%-34s,0x%08x)",macro,sig->name,sig->val);
6179  if(sig->offset || sig->ref_adr) {
6180  bprintf(" //");
6181  if(sig->offset) {
6182  bprintf(" (0x%x+0x%x)",sig->base,sig->offset);
6183  }
6184  if(sig->ref_adr) {
6185  bprintf(" Found @0x%08x",sig->ref_adr);
6186  }
6187  }
6188  }
6189  else
6190  {
6191  if (sig->flags & MISC_VAL_OPTIONAL) return;
6192  bprintf("// %s not found",sig->name);
6193  }
6194  bprintf("\n");
6195 }
int process_add_ptp_handler_call ( firmware fw,
iter_state_t is,
uint32_t  unused 
)

Definiert in Zeile 5091 der Datei finsig_thumb2.c.

5091  {
5092  uint32_t regs[4];
5093  // get r0 (opcode) and r1 (handler), backtracking up to 8 instructions
5094  if((get_call_const_args(fw,is,8,regs)&3)==3) {
5095  //uint32_t op=regs[0];
5096  if(!save_ptp_handler_func(fw,regs[0],regs[1])) {
5097  printf("add_ptp_handler op 0x%08x out of range 0x%"PRIx64"\n",regs[0],is->insn->address);
5098  }
5099  return 0;
5100  } else {
5101  // if above failed, check for opcode table
5102  arm_reg ptr_reg = ARM_REG_INVALID;
5103  int i;
5104  // backtrack until we get to ldrh r0, ...
5105  for(i=1; i<6; i++) {
5107  cs_insn *insn=fw->is->insn;
5108  if(insn->id != ARM_INS_LDRH) {
5109  continue;
5110  }
5111  if(insn->detail->arm.operands[0].reg != ARM_REG_R0
5112  || insn->detail->arm.operands[1].mem.base == ARM_REG_PC
5113  // shift isn't set correctly under capstone 3, not required for current cams
5114  /*|| insn->detail->arm.operands[1].shift.value != 3*/) {
5115  continue;
5116  }
5117  ptr_reg = insn->detail->arm.operands[1].mem.base;
5118  //printf("add_ptp_handler ptr_reg %d at 0x%"PRIx64"\n",ptr_reg,insn->address);
5119  break;
5120  }
5121  // didn't find args or anything that looks like table load
5122  if(ptr_reg == ARM_REG_INVALID) {
5123  printf("failed to get add_ptp_handler args at 0x%"PRIx64"\n",is->insn->address);
5124  return 0;
5125  }
5126  uint32_t op_table=0;
5127  // backtrack looking for LDR into ptr_reg
5128  // starting from previous i
5129  for(; i<20; i++) {
5131  cs_insn *insn=fw->is->insn;
5132  if(!isLDR_PC(insn)) {
5133  continue;
5134  }
5135  if(insn->detail->arm.operands[0].reg != ptr_reg) {
5136  continue;
5137  }
5138  // printf("add_ptp_handler LDR PC 0x%08x at 0x%"PRIx64"\n",LDR_PC2val(fw,insn),insn->address);
5139  uint32_t adr=LDR_PC2val(fw,insn);
5140  // check loaded address points to expected value (OC GetStorageIDs)
5141  if(fw_u32(fw,adr) == 0x1004) {
5142  op_table=adr;
5143  }
5144  break;
5145  }
5146  if(!op_table) {
5147  printf("failed to get ptp handler table adr at 0x%"PRIx64"\n",is->insn->address);
5148  return 0;
5149  }
5150  // TODO canon firmware has count in loop that calls add_ptp_handler,
5151  // but for simplicity just checking for valid opcode with hardcoded max
5152  for(i=0; i<64; i++) {
5153  uint32_t op=fw_u32(fw,op_table+i*8);
5154  uint32_t handler=fw_u32(fw,op_table+i*8+4);
5155  // fails on op out of range
5156  if(!save_ptp_handler_func(fw,op,handler)) {
5157  break;
5158  }
5159  }
5160  return 0;
5161  }
5162 }
int process_createtask_call ( firmware fw,
iter_state_t is,
uint32_t  unused 
)

Definiert in Zeile 5054 der Datei finsig_thumb2.c.

5054  {
5055  //printf("CreateTask call at %"PRIx64"\n",is->insn->address);
5056  uint32_t regs[4];
5057  // get r0 (name) and r3 (entry), backtracking up to 10 instructions
5058  if((get_call_const_args(fw,is,10,regs)&9)==9) {
5059  if(isASCIIstring(fw,regs[0])) {
5060  // TODO
5061  char *buf=malloc(64);
5062  char *nm=(char *)adr2ptr(fw,regs[0]);
5063  sprintf(buf,"task_%s",nm);
5064  //printf("found %s 0x%08x at 0x%"PRIx64"\n",buf,regs[3],is->insn->address);
5065  add_func_name(fw,buf,regs[3],NULL);
5066  } else {
5067  printf("task name name not string at 0x%"PRIx64"\n",is->insn->address);
5068  }
5069  } else {
5070  printf("failed to get CreateTask args at 0x%"PRIx64"\n",is->insn->address);
5071  }
5072  return 0;
5073 }
int process_eventproc_table_call ( firmware fw,
iter_state_t is,
uint32_t  unused 
)

Definiert in Zeile 4995 der Datei finsig_thumb2.c.

4995  {
4996  uint32_t regs[4];
4997  int foundr0 = 0;
4998  // get r0, backtracking up to 4 instructions
4999  foundr0 = get_call_const_args(fw,is,4,regs) & 1;
5000  if (!foundr0) {
5001  // case 1: table memcpy'd onto stack
5002  uint32_t ca = iter_state_adr(is);
5003  uint32_t sa = adr_hist_get(&is->ah,2);
5004  uint32_t ta = adr_hist_get(&is->ah,8);
5005  disasm_iter_set(fw,is,ta);
5006  int n = 0;
5007  while(++n<=(8-2))
5008  {
5009  disasm_iter(fw,is);
5010  }
5011  fw_disasm_iter_single(fw,sa);
5012  uint32_t adr1 = get_saved_sig_val("j_dry_memcpy");
5013  uint32_t adr2 = get_branch_call_insn_target(fw,fw->is);
5014  if (fw->is->insn->id == ARM_INS_BLX && adr1 == adr2) {
5015  foundr0 = get_call_const_args(fw,is,8-2,regs) & 2;
5016  if (foundr0) {
5017  regs[0] = regs[1];
5018  // printf("eventproc table case1 0x%x found table 0x%x\n",ca,regs[1]);
5019  }
5020  }
5021  // restore iter address
5022  disasm_iter_init(fw,is,ca);
5023  disasm_iter(fw,is);
5024  }
5025  if(foundr0) {
5026  // include tables in RAM data
5027  uint32_t *p=(uint32_t*)adr2ptr_with_data(fw,regs[0]);
5028  //printf("found eventproc table 0x%08x\n",regs[0]);
5029  // if it was a valid address
5030  if(p) {
5031  while(*p) {
5032  uint32_t nm_adr=*p;
5033  if(!isASCIIstring(fw,nm_adr)) {
5034  printf("eventproc name not string tbl 0x%08x 0x%08x\n",regs[0],nm_adr);
5035  break;
5036  }
5037  char *nm=(char *)adr2ptr(fw,nm_adr);
5038  p++;
5039  uint32_t fn=*p;
5040  p++;
5041  //printf("found %s 0x%08x\n",nm,fn);
5042  add_event_proc(fw,nm,fn);
5043  //add_func_name(fw,nm,fn,NULL);
5044  }
5045  } else {
5046  printf("failed to get *EventProcTable arg 0x%08x at 0x%"PRIx64"\n",regs[0],is->insn->address);
5047  }
5048  } else {
5049  printf("failed to get *EventProcTable r0 at 0x%"PRIx64"\n",is->insn->address);
5050  }
5051  return 0;
5052 }
int process_reg_eventproc_call ( firmware fw,
iter_state_t is,
uint32_t  unused 
)

Definiert in Zeile 4914 der Datei finsig_thumb2.c.

4914  {
4915  uint32_t regs[4];
4916  // get r0, r1, backtracking up to 4 instructions
4917  if((get_call_const_args(fw,is,4,regs)&3)==3) {
4918  // TODO follow ptr to verify code, pick up underlying functions
4919  if(isASCIIstring(fw,regs[0])) {
4920  char *nm=(char *)adr2ptr(fw,regs[0]);
4921  add_event_proc(fw,nm,regs[1]);
4922  //add_func_name(fw,nm,regs[1],NULL);
4923  //printf("eventproc found %s 0x%08x at 0x%"PRIx64"\n",nm,regs[1],is->insn->address);
4924  } else {
4925  printf("eventproc name not string at 0x%"PRIx64"\n",is->insn->address);
4926  }
4927  } else {
4928  // check for special case: one of the 2 arg eventprocs is used in loop to register a table
4929 
4930  // using the existing 'is' iterator
4931  // first, address is backed up
4932  uint64_t adr = is->insn->address;
4933  uint32_t adr_thumb = is->thumb;
4934  uint32_t tbla = 0;
4935  int ar = -1;
4936  int found = 0;
4937  // go back a 10 instructions
4938  disasm_iter_init(fw,is,adr_hist_get(&is->ah,10));
4939  // search for ldr reg, =address where address is higher in ROM (supposed to be the eventproc table)
4940  while(1) {
4941  if (!disasm_iter(fw,is)) break;
4942  if (is->insn->address >= adr) break;
4943  if (is->insn->id == ARM_INS_LDR && is->insn->detail->arm.operands[1].type == ARM_OP_MEM) {
4944  uint32_t u = LDR_PC2val(fw,is->insn);
4945  if ((u<fw->base+fw->size8) && (u>adr) && (!isASCIIstring(fw,u))) {
4946  ar = is->insn->detail->arm.operands[0].reg;
4947  tbla = u;
4948  break;
4949  }
4950  }
4951  }
4952  // search for found register appearing later in an add instruction
4953  while(ar >= 0) {
4954  if (!disasm_iter(fw,is)) break;
4955  if (is->insn->address >= adr) break;
4956  if (is->insn->id == ARM_INS_ADD && is->insn->detail->arm.operands[1].reg == ar) {
4957  found = 1;
4958  //printf("found loop eventproc table at 0x%"PRIx64"\n",is->insn->address);
4959  break;
4960  }
4961  }
4962  if (found) {
4963  // following is taken from process_eventproc_table_call
4964  uint32_t *p=(uint32_t*)adr2ptr_with_data(fw,tbla);
4965  if(p) {
4966  while(*p) {
4967  uint32_t nm_adr=*p;
4968  // NULL name = end of table
4969  if (!nm_adr) break;
4970  if(!isASCIIstring(fw,nm_adr)) {
4971  printf("eventproc name not string tbl2 0x%08x 0x%08x\n",tbla,nm_adr);
4972  break;
4973  }
4974  char *nm=(char *)adr2ptr(fw,nm_adr);
4975  p++;
4976  uint32_t fn=*p;
4977  p++;
4978  add_event_proc(fw,nm,fn);
4979  }
4980  } else {
4981  printf("eventproc tbl2 not table 0x%08x\n",tbla);
4982  }
4983  }
4984  else {
4985  printf("failed to get export/register eventproc args at 0x%"PRIx64"\n",adr);
4986  }
4987  // restore address in 'is' to avoid infinite loop
4988  disasm_iter_init(fw,is,adr | adr_thumb);
4989  disasm_iter(fw,is);
4990  }
4991  return 0; // always keep looking
4992 }
void run_sig_rules ( firmware fw,
sig_rule_t sig_rules 
)

Definiert in Zeile 4868 der Datei finsig_thumb2.c.

4869 {
4870  sig_rule_t *rule=sig_rules;
4871  // for convenience, pass an iter_state to match fns so they don't have to manage
4872  iter_state_t *is=disasm_iter_new(fw,0);
4873  while(rule->match_fn) {
4874  if((rule->dryos_min && fw->dryos_ver < rule->dryos_min)
4875  || (rule->dryos_max && fw->dryos_ver > rule->dryos_max)) {
4876  rule++;
4877  continue;
4878  }
4879 // printf("rule: %s ",rule->name);
4880  //int r=rule->match_fn(fw,is,rule);
4881  rule->match_fn(fw,is,rule);
4882 // printf("%d\n",r);
4883  rule++;
4884  }
4885  disasm_iter_free(is);
4886 }
void save_misc_val ( const char *  name,
uint32_t  base,
uint32_t  offset,
uint32_t  ref_adr 
)

Definiert in Zeile 596 der Datei finsig_thumb2.c.

597 {
598  misc_val_t *p=get_misc_val(name);
599  if(!p) {
600  printf("save_misc_val: invalid name %s\n",name);
601  return;
602  }
603  p->val = base + offset;
604  p->base = base;
605  p->offset = offset;
606  p->ref_adr = ref_adr;
607  p->blobs = NULL;
608 }
void save_misc_val_blobs ( const char *  name,
misc_blob_t blobs,
uint32_t  ref_adr 
)

Definiert in Zeile 609 der Datei finsig_thumb2.c.

610 {
611  misc_val_t *p=get_misc_val(name);
612  if(!p) {
613  printf("save_misc_val: invalid name %s\n",name);
614  return;
615  }
616  p->val = p->base = p->offset = 0;
617  p->ref_adr = ref_adr;
618  p->blobs = blobs;
619 }
int save_ptp_handler_func ( firmware fw,
uint32_t  op,
uint32_t  handler 
)

Definiert in Zeile 5075 der Datei finsig_thumb2.c.

5075  {
5076  if((op >= 0x9000 && op < 0x10000) || (op >= 0x1000 && op < 0x2000)) {
5077  char *buf=malloc(64);
5078  const char *nm=get_ptp_op_name(op);
5079  if(nm) {
5080  sprintf(buf,"handle_%s",nm);
5081  } else {
5082  sprintf(buf,"handle_PTP_OC_0x%04x",op);
5083  }
5084  // TODO Canon sometimes uses the same handler for multiple opcodes
5085  add_func_name(fw,buf,handler,NULL);
5086  } else {
5087  return 0;
5088  }
5089  return 1;
5090 }
void save_sig ( firmware fw,
const char *  name,
uint32_t  val 
)

Definiert in Zeile 699 der Datei finsig_thumb2.c.

700 {
701  sig_entry_t *sig = find_saved_sig(name);
702  if (!sig)
703  {
704  printf("save_sig: refusing to save unknown name %s\n",name);
705  return;
706  }
707  // if we end up needed these, can add a flag
708  if(!adr_is_main_fw_code(fw,val)) {
709  printf("save_sig: refusing to save %s with out of range address 0x%08x\n",name,val);
710  return;
711  }
712  if(sig->val && sig->val != val) {
713  printf("save_sig: duplicate name %s existing 0x%08x != new 0x%08x\n",name,sig->val,val);
714  }
715  sig->val = val;
716 }
int save_sig_match_call ( firmware fw,
sig_rule_t rule,
uint32_t  call_adr 
)

Definiert in Zeile 1950 der Datei finsig_thumb2.c.

1951 {
1952  disasm_iter_init(fw,fw->is,call_adr); // reset to a bit before where the string was found
1953  disasm_iter(fw,fw->is);
1954  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,fw->is));
1955 }
int save_sig_with_j ( firmware fw,
char *  name,
uint32_t  adr 
)

Definiert in Zeile 773 der Datei finsig_thumb2.c.

774 {
775  if(!adr) {
776  printf("save_sig_with_j: %s null adr\n",name);
777  return 0;
778  }
779  // attempt to disassemble target
780  if(!fw_disasm_iter_single(fw,adr)) {
781  printf("save_sig_with_j: %s disassembly failed at 0x%08x\n",name,adr);
782  return 0;
783  }
784  // handle functions that immediately jump
785  // only one level of jump for now, doesn't check for conditionals, but first insn shouldn't be conditional
786  //uint32_t b_adr=B_target(fw,fw->is->insn);
787  uint32_t b_adr=get_direct_jump_target(fw,fw->is);
788  if(b_adr) {
789  char *buf=malloc(strlen(name)+6);
790  sprintf(buf,"j_%s",name);
791  add_func_name(fw,buf,adr,NULL); // this is the orignal named address
792 // adr=b_adr | fw->is->thumb; // thumb bit from iter state
793  adr=b_adr; // thumb bit already handled by get_direct...
794  }
795  save_sig(fw,name,adr);
796  return 1;
797 }
int sig_match__nrflag ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3921 der Datei finsig_thumb2.c.

3922 {
3923  if(!init_disasm_sig_ref(fw,is,rule)) {
3924  return 0;
3925  }
3926  uint32_t fadr=is->adr;
3927  // find range check on input arg
3928  const insn_match_t match_cmp_b[]={
3929  {MATCH_INS(CMP, 2), {MATCH_OP_REG(R0),MATCH_OP_IMM_ANY}},
3930  {MATCH_INS(B,MATCH_OPCOUNT_IGNORE)}, // blo or blt may be used, so don't include cond
3931  {ARM_INS_ENDING}
3932  };
3933  if(!insn_match_find_next_seq(fw,is,4,match_cmp_b) || is->insn->detail->arm.cc == ARM_CC_AL) {
3934  printf("sig_match__nrflag: no match CMP\n");
3935  return 0;
3936  }
3937  // follow
3939  if(!disasm_iter(fw,is)) {
3940  printf("sig_match__nrflag: disasm failed\n");
3941  return 0;
3942  }
3943  // assume next is base addres
3944  uint32_t adr=LDR_PC2val(fw,is->insn);
3945  if(!adr) {
3946  printf("sig_match__nrflag: no match LDR PC 0x%"PRIx64"\n",is->insn->address);
3947  return 0;
3948  }
3949  arm_reg reg_base = is->insn->detail->arm.operands[0].reg; // reg value was loaded into
3950  if(!disasm_iter(fw,is)) {
3951  printf("sig_match__nrflag: disasm failed\n");
3952  return 0;
3953  }
3954  // firmware may use add/sub to get actual firmware base address
3955  if(isADDx_imm(is->insn) || isSUBx_imm(is->insn)) {
3956  if(is->insn->detail->arm.operands[0].reg != reg_base) {
3957  printf("sig_match__nrflag: no match ADD/SUB\n");
3958  return 0;
3959  }
3960  if(isADDx_imm(is->insn)) {
3961  adr+=is->insn->detail->arm.operands[1].imm;
3962  } else {
3963  adr-=is->insn->detail->arm.operands[1].imm;
3964  }
3965  if(!disasm_iter(fw,is)) {
3966  printf("sig_match__nrflag: disasm failed\n");
3967  return 0;
3968  }
3969  }
3970  if(is->insn->id != ARM_INS_STR || is->insn->detail->arm.operands[1].reg != reg_base) {
3971  printf("sig_match__nrflag: no match STR\n");
3972  return 0;
3973  }
3974  uint32_t disp = is->insn->detail->arm.operands[1].mem.disp;
3975  save_misc_val(rule->name,adr,disp,fadr);
3976  return 1;
3977 }
int sig_match_add_ptp_handler ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2623 der Datei finsig_thumb2.c.

2624 {
2625  uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2626  if(!str_adr) {
2627  printf("sig_match_add_ptp_handler: failed to find ref %s\n",rule->ref_name);
2628  return 0;
2629  }
2630  // TODO should handle multiple instances of string
2631  disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default); // reset to a bit before where the string was found
2632  while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2633  // expect CreateTaskStrictly
2634  if(!find_next_sig_call(fw,is,8,"CreateTaskStrictly")) {
2635  // printf("sig_match_add_ptp_handler: no CreateTaskStrictly\n");
2636  continue;
2637  }
2638  // expect add_ptp_handler is 3rd call after CreateTask
2639  if(!insn_match_find_nth(fw,is,13,3,match_bl_blximm)) {
2640  // printf("sig_match_add_ptp_handler: no match bl\n");
2641  return 0;
2642  }
2643  // sanity check, expect opcode, func, 0
2644  uint32_t regs[4];
2645  if((get_call_const_args(fw,is,5,regs)&7)!=7) {
2646  // printf("sig_match_add_ptp_handler: failed to get args\n");
2647  return 0;
2648  }
2649  if(regs[0] < 0x9000 || regs[0] > 0x10000 || !adr2ptr(fw,regs[1]) || regs[2] != 0) {
2650  // printf("sig_match_add_ptp_handler: bad args 0x%08x 0x%08x 0x%08x\n",regs[0],regs[1],regs[2]);
2651  return 0;
2652  }
2653  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2654  }
2655  return 0;
2656 }
int sig_match_aram_size ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3802 der Datei finsig_thumb2.c.

3803 {
3804  if(!init_disasm_sig_ref(fw,is,rule)) {
3805  printf("sig_match_aram_size: missing ref\n");
3806  return 0;
3807  }
3808  const insn_match_t match_ldr_r0_sp_cmp[]={
3809  {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0),MATCH_OP_MEM(SP,INVALID,0xc)}},
3810  {MATCH_INS(CMP, 2), {MATCH_OP_REG(R0),MATCH_OP_IMM_ANY}},
3811  {ARM_INS_ENDING}
3812  };
3813  if(!insn_match_find_next_seq(fw,is,15,match_ldr_r0_sp_cmp)) {
3814  printf("sig_match_aram_size: no match LDR\n");
3815  return 0;
3816  }
3817  uint32_t val=is->insn->detail->arm.operands[1].imm;
3818  if(val != 0x22000 && val != 0x32000) {
3819  printf("sig_match_aram_size: unexpected ARAM size 0x%08x\n",val);
3820  }
3821  save_misc_val(rule->name,val,0,(uint32_t)is->insn->address);
3822  return 1;
3823 }
int sig_match_aram_size_gt58 ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3825 der Datei finsig_thumb2.c.

3826 {
3827  if(!init_disasm_sig_ref(fw,is,rule)) {
3828  printf("sig_match_aram_size: missing ref\n");
3829  return 0;
3830  }
3831  const insn_match_t match_ldrd_r0r1_mov[]={
3832  {MATCH_INS(LDRD, 3), {MATCH_OP_REG(R0),MATCH_OP_REG(R1),MATCH_OP_MEM(SP,INVALID,0x10)}},
3833  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R2),MATCH_OP_IMM_ANY}},
3834  {ARM_INS_ENDING}
3835  };
3836  // d7? variant
3837  const insn_match_t match_ldrd_r2r1_mov[]={
3838  {MATCH_INS(LDRD, 3), {MATCH_OP_REG(R2),MATCH_OP_REG(R1),MATCH_OP_MEM(SP,INVALID,0x10)}},
3839  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R3),MATCH_OP_IMM_ANY}},
3840  {ARM_INS_ENDING}
3841  };
3842  if(!insn_match_find_next_seq(fw,is,15,match_ldrd_r0r1_mov)) {
3843  init_disasm_sig_ref(fw,is,rule); // reset to start
3844  if(!insn_match_find_next_seq(fw,is,15,match_ldrd_r2r1_mov)) {
3845  printf("sig_match_aram_size: no match LDR\n");
3846  }
3847  return 0;
3848  }
3849  uint32_t val=is->insn->detail->arm.operands[1].imm;
3850  if(val != 0x22000 && val != 0x32000) {
3851  printf("sig_match_aram_size: unexpected ARAM size 0x%08x\n",val);
3852  }
3853  save_misc_val(rule->name,val,0,(uint32_t)is->insn->address);
3854  return 1;
3855 }
int sig_match_aram_start ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3857 der Datei finsig_thumb2.c.

3858 {
3859  if(!init_disasm_sig_ref(fw,is,rule)) {
3860  printf("sig_match_aram_start: missing ref\n");
3861  return 0;
3862  }
3863  if(!find_next_sig_call(fw,is,50,"DebugAssert")) {
3864  printf("sig_aram_start: no match DebugAssert\n");
3865  return 0;
3866  }
3867  const insn_match_t match_cmp_bne_ldr[]={
3868  {MATCH_INS(CMP, 2), {MATCH_OP_REG(R1),MATCH_OP_IMM(0)}},
3871  {ARM_INS_ENDING}
3872  };
3873  if(!insn_match_find_next_seq(fw,is,15,match_cmp_bne_ldr)) {
3874  printf("sig_match_aram_start: no match CMP\n");
3875  return 0;
3876  }
3877  uint32_t adr=LDR_PC2val(fw,is->insn);
3878  if(!adr) {
3879  printf("sig_match_aram_start: no match LDR PC 0x%"PRIx64"\n",is->insn->address);
3880  return 0;
3881  }
3882  // could sanity check that it looks like a RAM address
3883  save_misc_val(rule->name,adr,0,(uint32_t)is->insn->address);
3884  return 1;
3885 }
int sig_match_aram_start2 ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3887 der Datei finsig_thumb2.c.

3888 {
3889  if (get_misc_val_value("ARAM_HEAP_START"))
3890  return 0;
3891 
3892  if(!init_disasm_sig_ref(fw,is,rule)) {
3893  printf("sig_match_aram_start: missing ref\n");
3894  return 0;
3895  }
3896  if(!find_next_sig_call(fw,is,60,"DebugAssert")) {
3897  printf("sig_aram_start2: no match DebugAssert\n");
3898  return 0;
3899  }
3900  const insn_match_t match_cmp_bne_ldr[]={
3901  {MATCH_INS(CMP, 2), {MATCH_OP_REG(R1),MATCH_OP_IMM(0)}},
3905  {ARM_INS_ENDING}
3906  };
3907  if(!insn_match_find_next_seq(fw,is,15,match_cmp_bne_ldr)) {
3908  printf("sig_match_aram_start2: no match CMP\n");
3909  return 0;
3910  }
3911  uint32_t adr=LDR_PC2val(fw,is->insn);
3912  if(!adr) {
3913  printf("sig_match_aram_start2: no match LDR PC 0x%"PRIx64"\n",is->insn->address);
3914  return 0;
3915  }
3916  // could sanity check that it looks like a RAM address
3917  save_misc_val(rule->name,adr,0,(uint32_t)is->insn->address);
3918  return 1;
3919 }
int sig_match_av_over_sem ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 4006 der Datei finsig_thumb2.c.

4007 {
4008  // don't bother on ND-only cams
4009  if(!get_misc_val_value("CAM_HAS_IRIS_DIAPHRAGM")) {
4010  return 0;
4011  }
4012 
4013  if(!init_disasm_sig_ref(fw,is,rule)) {
4014  return 0;
4015  }
4016  if(!find_next_sig_call(fw,is,30,"TakeSemaphore")) {
4017  printf("sig_match_av_over_sem: no match TakeSemaphore at 0x%"PRIx64"\n",is->insn->address);
4018  return 0;
4019  }
4020 
4021  // rewind 5 ins
4022  disasm_iter_init(fw,is,adr_hist_get(&is->ah,5));
4023  var_ldr_desc_t desc;
4024  if(!find_and_get_var_ldr(fw, is, 3, 4, ARM_REG_R0, &desc)) {
4025  printf("sig_match_av_over_sem: no match ldr at 0x%"PRIx64"\n",is->insn->address);
4026  return 0;
4027  }
4028 
4029  save_misc_val(rule->name,desc.adr_adj,desc.off,(uint32_t)is->insn->address);
4030  return 1;
4031 }
int sig_match_cam_has_iris_diaphragm ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3543 der Datei finsig_thumb2.c.

3544 {
3545  uint32_t v;
3546  uint32_t ref=0;get_saved_sig_val(rule->ref_name);
3547  // ILC assumed to have iris
3548  if(get_misc_val_value("CAM_IS_ILC")) {
3549  v=1;
3550  } else {
3551  ref=get_saved_sig_val(rule->ref_name);
3552  v=(ref)?1:0;
3553  }
3554  save_misc_val(rule->name,v,0,ref);
3555  return 1;
3556 }
int sig_match_cam_uncached_bit ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3558 der Datei finsig_thumb2.c.

3559 {
3560  if(!init_disasm_sig_ref(fw,is,rule)) {
3561  return 0;
3562  }
3563  const insn_match_t match_bic_r0[]={
3565  {ARM_INS_ENDING}
3566  };
3567  if(insn_match_find_next(fw,is,4,match_bic_r0)) {
3568  save_misc_val(rule->name,is->insn->detail->arm.operands[2].imm,0,(uint32_t)is->insn->address);
3569  return 1;
3570  }
3571  return 0;
3572 }
int sig_match_canon_menu_active ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 4033 der Datei finsig_thumb2.c.

4034 {
4035  if(!init_disasm_sig_ref(fw,is,rule)) {
4036  return 0;
4037  }
4038  var_ldr_desc_t desc;
4039  if(!find_and_get_var_ldr(fw, is, 2, 4, ARM_REG_R0, &desc)) {
4040  printf("sig_match_canon_menu_active: no match ldr at 0x%"PRIx64"\n",is->insn->address);
4041  return 0;
4042  }
4043  if(!disasm_iter(fw,is)) {
4044  printf("sig_match_canon_menu_active: disasm failed\n");
4045  return 0;
4046  }
4047  if(is->insn->id != ARM_INS_CMP) {
4048  printf("sig_match_canon_menu_active: no match cmp at 0x%"PRIx64"\n",is->insn->address);
4049  return 0;
4050  }
4051  save_misc_val(rule->name,desc.adr_adj,desc.off,(uint32_t)is->insn->address);
4052  return 1;
4053 }
int sig_match_close_gt_57 ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1807 der Datei finsig_thumb2.c.

1808 {
1809  if(!init_disasm_sig_ref(fw,is,rule)) {
1810  return 0;
1811  }
1812  if(!find_next_sig_call(fw,is,34,"TakeSemaphoreStrictly")) {
1813  return 0;
1814  }
1815  // looking for next call
1816  // this should be equivalent to previous versions Close, without the extra semaphore wrapper
1817  if(!insn_match_find_next(fw,is,3,match_bl_blximm)) {
1818  return 0;
1819  }
1820  // follow
1822  // first call
1823  if(!insn_match_find_next(fw,is,3,match_bl_blximm)) {
1824  return 0;
1825  }
1826  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1827 }
int sig_match_closedir ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1914 der Datei finsig_thumb2.c.

1915 {
1916  uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
1917  if(!str_adr) {
1918  printf("sig_match_closedir: %s failed to find ref %s\n",rule->name,rule->ref_name);
1919  return 0;
1920  }
1921  // TODO should handle multiple instances of string
1922  disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default); // reset to a bit before where the string was found
1923  while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
1924  if(!find_next_sig_call(fw,is,60,"sprintf_FW")) {
1925  continue;
1926  }
1927  if(insn_match_find_nth(fw,is,7,2,match_bl_blximm)) {
1928  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1929  }
1930  }
1931 
1932  uint32_t call_adr = find_call_near_str(fw,is,rule);
1933  if(call_adr) {
1934  disasm_iter_init(fw,is,call_adr); // reset to a bit before where the string was found
1935  const insn_match_t match_closedir[]={
1937  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R0), MATCH_OP_REG_ANY}},
1939  {ARM_INS_ENDING}
1940  };
1941  if(insn_match_seq(fw,is,match_closedir)){
1942  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1943  }
1944  }
1945 
1946  return 0;
1947 }
int sig_match_create_jumptable ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1611 der Datei finsig_thumb2.c.

1612 {
1613  if(!init_disasm_sig_ref(fw,is,rule)) {
1614  return 0;
1615  }
1616  // find second function call
1617  if(!insn_match_find_nth(fw,is,20,2,match_bl_blximm)) {
1618  return 0;
1619  }
1620  // follow
1622  if(!insn_match_find_next(fw,is,15,match_bl_blximm)) {
1623  return 0;
1624  }
1625  // TODO could verify it looks right (version string)
1626  save_sig(fw,"CreateJumptable",get_branch_call_insn_target(fw,is));
1627  return 1;
1628 }
int sig_match_deletedirectory_fut ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2696 der Datei finsig_thumb2.c.

2697 {
2698  uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2699  if(!str_adr) {
2700  printf("sig_match_deletedirectory_fut: failed to find ref %s\n",rule->ref_name);
2701  return 0;
2702  }
2703  // TODO using larger than default "near" range, needed for sx710
2704  // not looking for ref to string, just code near where the actual string is
2705  disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - 2048) | fw->thumb_default); // reset to a bit before where the string was found
2706  uint32_t end_adr = ADR_ALIGN4(str_adr) + 2048;
2707  while(find_next_sig_call(fw,is,end_adr - (uint32_t)is->adr,"DeleteFile_Fut")) {
2708  if(!insn_match_find_next(fw,is,6,match_bl_blximm)) {
2709  // printf("sig_match_deletedirectory_fut: no match bl strcpy\n");
2710  continue;
2711  }
2712  if(!is_sig_call(fw,is,"strcpy")) {
2713  // printf("sig_match_deletedirectory_fut: bl not strcpy at 0x%"PRIx64"\n",is->insn->address);
2714  continue;
2715  }
2716  if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
2717  // printf("sig_match_deletedirectory_fut: no match bl strrchr at 0x%"PRIx64"\n",is->insn->address);
2718  continue;
2719  }
2720  if(!is_sig_call(fw,is,"strrchr")) {
2721  // printf("sig_match_deletedirectory_fut: bl not strrchr at 0x%"PRIx64"\n",is->insn->address);
2722  continue;
2723  }
2724  // verify that arg1 to strrch is /
2725  uint32_t regs[4];
2726  if((get_call_const_args(fw,is,2,regs)&0x2)!=0x2) {
2727  // printf("sig_match_deletedirectory_fut: failed to get strrchr r1 at 0x%"PRIx64"\n",is->insn->address);
2728  continue;
2729  }
2730  if(regs[1] != '/') {
2731  // printf("sig_match_deletedirectory_fut: strrchr r1 not '/' at 0x%"PRIx64"\n",is->insn->address);
2732  continue;
2733  }
2734  if(!insn_match_find_next(fw,is,5,match_bl_blximm)) {
2735  // printf("sig_match_deletedirectory_fut: no match bl at 0x%"PRIx64"\n",is->insn->address);
2736  continue;
2737  }
2738  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2739  }
2740  return 0;
2741 }
int sig_match_deletefile_fut ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1876 der Datei finsig_thumb2.c.

1877 {
1878  uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
1879  if(!str_adr) {
1880  printf("sig_match_deletefile_fut: %s failed to find ref %s\n",rule->name,rule->ref_name);
1881  return 0;
1882  }
1883  // TODO should handle multiple instances of string
1884  disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default); // reset to a bit before where the string was found
1885  while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
1886  // next call should be DeleteFile_Fut
1887  if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
1888  continue;
1889  }
1890  // follow
1892  if(!fw_disasm_iter_single(fw,adr)) {
1893  printf("sig_match_deletefile_fut: disasm failed\n");
1894  return 0;
1895  }
1896  const insn_match_t match_mov_r1[]={
1897  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R1), MATCH_OP_IMM_ANY}},
1898 #if CS_API_MAJOR < 4
1899  {MATCH_INS(MOVS, 2), {MATCH_OP_REG(R1), MATCH_OP_IMM_ANY}},
1900 #endif
1901  {ARM_INS_ENDING}
1902  };
1903 
1904  if(!insn_match_any(fw->is->insn,match_mov_r1)){
1905  continue;
1906  }
1907  return save_sig_with_j(fw,rule->name,adr);
1908  }
1909  return 0;
1910 }
int sig_match_disable_hdmi_power ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3368 der Datei finsig_thumb2.c.

3369 {
3370  if(!init_disasm_sig_ref(fw,is,rule)) {
3371  return 0;
3372  }
3373  if(!find_next_sig_call(fw,is,24,"EnableHDMIPower")) {
3374  printf("sig_match_disable_hdmi_power: no match EnableHDMIPower\n");
3375  return 0;
3376  }
3377  if(!find_next_sig_call(fw,is,22,"ClearEventFlag")) {
3378  printf("sig_match_disable_hdmi_power: no match ClearEventFlag\n");
3379  return 0;
3380  }
3381  const insn_match_t match_seq[]={
3383  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM(1)}},
3385  {ARM_INS_ENDING}
3386  };
3387  if(!insn_match_find_next_seq(fw,is,12,match_seq)) {
3388  printf("sig_match_disable_hdmi_power: no match seq bl movs pop 0x%"PRIx64"\n",is->insn->address);
3389  return 0;
3390  }
3391  // bl matched above should be func
3392  disasm_iter_init(fw,is,adr_hist_get(&is->ah,2));
3393  if (!disasm_iter(fw,is)) {
3394  return 0;
3395  }
3396  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3397 }
int sig_match_displaybusyonscreen_52 ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2785 der Datei finsig_thumb2.c.

2786 {
2787  if (fw->dryos_ver != 52) {
2788  return 0;
2789  }
2790  uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2791  if(!str_adr) {
2792  printf("sig_match_displaybusyonscreen: failed to find ref %s\n",rule->ref_name);
2793  return 0;
2794  }
2795  disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default); // reset to a bit before where the string was found
2796  while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2797  if(!insn_match_find_next(fw,is,3,match_bl_blximm)) {
2798  // printf("sig_match_displaybusyonscreen: no match bl at 0x%"PRIx64"\n",is->insn->address);
2799  continue;
2800  }
2801  if(!is_sig_call(fw,is,"LogCameraEvent")) {
2802  // printf("sig_match_displaybusyonscreen: not LogCameraEvent at 0x%"PRIx64"\n",is->insn->address);
2803  continue;
2804  }
2805  if(!find_next_sig_call(fw,is,4,"GUISrv_StartGUISystem_FW")) {
2806  // printf("sig_match_displaybusyonscreen: no match GUISrv_StartGUISystem_FW\n");
2807  continue;
2808  }
2809  if(!insn_match_find_nth(fw,is,5,2,match_bl_blximm)) {
2810  // printf("sig_match_displaybusyonscreen: no match bl 0x%"PRIx64"\n",is->insn->address);
2811  continue;
2812  }
2813  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2814  }
2815  return 0;
2816 }
int sig_match_enable_hdmi_power ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3343 der Datei finsig_thumb2.c.

3344 {
3345  if(!init_disasm_sig_ref(fw,is,rule)) {
3346  return 0;
3347  }
3348  if(!find_next_sig_call(fw,is,14,"CreateEventFlagStrictly")) {
3349  printf("sig_match_enable_hdmi_power: no match CreateEventFlagStrictly\n");
3350  return 0;
3351  }
3352  const insn_match_t match_seq[]={
3355  {ARM_INS_ENDING}
3356  };
3357  if(!insn_match_find_next_seq(fw,is,4,match_seq)) {
3358  printf("sig_match_enable_hdmi_power: no match bl seq cbnz 0x%"PRIx64"\n",is->insn->address);
3359  return 0;
3360  }
3361  // function should be next call
3362  if (!disasm_iter(fw,is)) {
3363  return 0;
3364  }
3365  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3366 }
int sig_match_evp_table_veneer ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1136 der Datei finsig_thumb2.c.

1137 {
1138  uint32_t ref_adr = get_saved_sig_val(rule->ref_name);
1139  int prevb = 0;
1140  uint32_t cadr;
1141  // following should probably be done using fw_search_insn
1142  // both veneers consist of a single b instruction, always preceded by another b instruction
1143  disasm_iter_init(fw,is,ref_adr); // start at our known function
1144  while (is->adr < (ref_adr+0x800)) {
1145  cadr = is->adr;
1146  if (!disasm_iter(fw,is)) {
1147  disasm_iter_set(fw,is,(is->adr+2) | fw->thumb_default);
1148  }
1149  else {
1150  if (is->insn->id == ARM_INS_B) {
1151  uint32_t b_adr = get_branch_call_insn_target(fw,is);
1152  if (prevb && (b_adr == ref_adr)) {
1153  // this doesn't use _with_j since we want identify the veneer
1154  add_func_name(fw,rule->name,cadr | is->thumb,NULL);
1155  return 1;
1156  }
1157  prevb = 1;
1158  }
1159  }
1160  }
1161  return 0;
1162 }
int sig_match_exec_evp ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2133 der Datei finsig_thumb2.c.

2134 {
2135  uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2136  if(!str_adr) {
2137  printf("sig_match_exec_evp: failed to find ref %s\n",rule->ref_name);
2138  return 0;
2139  }
2140  // TODO should handle multiple instances of string
2141  disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default); // reset to a bit before where the string was found
2142  while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2143  // search backwards for push {r0,...}
2144  int i;
2145  for(i=1; i<=18; i++) {
2146  if(!fw_disasm_iter_single(fw,adr_hist_get(&is->ah,i))) {
2147  break;
2148  }
2149  if(fw->is->insn->id == ARM_INS_PUSH && fw->is->insn->detail->arm.operands[0].reg == ARM_REG_R0) {
2150  // push should be start of func
2151  uint32_t adr=(uint32_t)(fw->is->insn->address) | is->thumb;
2152  // search forward in original iter_state for DebugAssert. If found, in the wrong ExecuteEventProcedure
2153  if(find_next_sig_call(fw,is,28,"DebugAssert")) {
2154  break;
2155  }
2156  return save_sig_with_j(fw,rule->name,adr);
2157  }
2158  }
2159  }
2160  return 0;
2161 }
int sig_match_exmem_vars ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3004 der Datei finsig_thumb2.c.

3005 {
3006  uint32_t adr[2], fnd[2];
3007  if(!init_disasm_sig_ref(fw,is,rule)) {
3008  printf("sig_match_exmem_vars: missing ref\n");
3009  return 0;
3010  }
3011  // expect first LDR pc
3012  if(!insn_match_find_next(fw,is,15,match_ldr_pc)) {
3013  printf("sig_match_exmem_vars: match LDR PC failed\n");
3014  return 0;
3015  }
3016  adr[0]=LDR_PC2val(fw,is->insn);
3017  fnd[0]=(uint32_t)is->insn->address;
3018  if(!insn_match_find_next(fw,is,5,match_ldr_pc)) {
3019  printf("sig_match_exmem_vars: 2nd match LDR PC failed\n");
3020  return 0;
3021  }
3022  adr[1]=LDR_PC2val(fw,is->insn);
3023  fnd[1]=(uint32_t)is->insn->address;
3024  //printf("sig_match_exmem_vars: %x, %x\n",adr[0], adr[1]);
3025  int n;
3026  for (n=0; n<2; n++) {
3027  if (adr[n] < fw->data_start+fw->data_len) {
3028  uint32_t ladr = adr[n]-fw->data_start+fw->data_init_start;
3029  save_misc_val("exmem_types_table",ladr,0,fnd[n]);
3030  int m;
3031  int exm_typ_cnt = 0;
3032  for (m=0; m<42; m++) {
3033  if ( (fw_u32(fw,ladr+m*4)!=0) && isASCIIstring(fw, fw_u32(fw,ladr+m*4)) )
3034  {
3035  char *extyp = (char*)adr2ptr(fw, fw_u32(fw,ladr+m*4));
3036  if ( strncmp(extyp,"EXMEM",5)==0 )
3037  {
3038  exm_typ_cnt++;
3039  }
3040  }
3041  else
3042  {
3043  break;
3044  }
3045  }
3046  save_misc_val("exmem_type_count",exm_typ_cnt,0,ladr);
3047  }
3048  else if (adr[n] < fw->memisostart) {
3049  save_misc_val("exmem_alloc_table",adr[n],0,fnd[n]);
3050  }
3051  }
3052  return 1;
3053 }
int sig_match_fgets_fut ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2163 der Datei finsig_thumb2.c.

2164 {
2165  if(!init_disasm_sig_ref(fw,is,rule)) {
2166  return 0;
2167  }
2168  if(!find_next_sig_call(fw,is,16,"Fopen_Fut_FW")) {
2169  return 0;
2170  }
2171  disasm_iter(fw,is);
2172  disasm_iter(fw,is);
2173  if (B_target(fw,is->insn) && (is->insn->detail->arm.cc == ARM_CC_NE)) {
2175  } else {
2176  if (B_target(fw,is->insn) && (is->insn->detail->arm.cc == ARM_CC_NE)) {
2178  }
2179  }
2180  if(!insn_match_find_nth(fw,is,20,1,match_bl_blximm)) {
2181  return 0;
2182  }
2183  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2184 }
int sig_match_file_counter_init ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 4055 der Datei finsig_thumb2.c.

4056 {
4057  if(!init_disasm_sig_ref(fw,is,rule)) {
4058  return 0;
4059  }
4060  // find first call
4061  if(!insn_match_find_next(fw,is,3,match_bl_blximm)) {
4062  // printf("sig_match_file_counter_init: bl match 1 failed at 0x%"PRIx64"\n",is->insn->address);
4063  return 0;
4064  }
4065  // some cameras (dry 58+?) have a nullsub before the function of interest
4067  if(!insn_match_find_next(fw,is,3,match_bl_blximm)) {
4068  // printf("sig_match_file_counter_init: bl match 1a failed at 0x%"PRIx64"\n",is->insn->address);
4069  return 0;
4070  }
4071  }
4072  // follow
4074  if(!insn_match_find_next(fw,is,3,match_bl_blximm)) {
4075  // printf("sig_match_file_counter_init: bl match 2 failed at 0x%"PRIx64"\n",is->insn->address);
4076  return 0;
4077  }
4078  uint32_t fadr = get_branch_call_insn_target(fw,is);
4079  // follow
4080  disasm_iter_init(fw,is,fadr);
4081  if(!disasm_iter(fw,is)) {
4082  // printf("sig_match_file_counter_init: disasm failed\n");
4083  return 0;
4084  }
4085  // sanity check
4086  if(!isLDR_PC(is->insn)) {
4087  // printf("sig_match_file_counter_init: no match LDR PC at 0x%"PRIx64"\n",is->insn->address);
4088  return 0;
4089  }
4090  // function we're looking for
4091  return save_sig_with_j(fw,rule->name,fadr);
4092 }
int sig_match_file_counter_var ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 4093 der Datei finsig_thumb2.c.

4094 {
4095  if(!init_disasm_sig_ref(fw,is,rule)) {
4096  return 0;
4097  }
4098  uint32_t adr=LDR_PC2val(fw,is->insn);
4099  if(!adr) {
4100  // printf("sig_match_file_counter_var: no match LDR PC 0x%"PRIx64"\n",is->insn->address);
4101  return 0;
4102  }
4103  if(is->insn->detail->arm.operands[0].reg != ARM_REG_R0) {
4104  // printf("sig_match_file_counter_var: not R0 0x%"PRIx64"\n",is->insn->address);
4105  return 0;
4106  }
4107  if(!adr_is_var(fw,adr)) {
4108  // printf("sig_match_file_counter_var: not a data address 0x%08x at 0x%"PRIx64"\n",adr,is->insn->address);
4109  return 0;
4110  }
4111  save_misc_val(rule->name,adr,0,(uint32_t)is->insn->address);
4112  return 1;
4113 }
int sig_match_flash_param_table ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3440 der Datei finsig_thumb2.c.

3441 {
3442  if(!init_disasm_sig_ref(fw,is,rule)) {
3443  return 0;
3444  }
3445  // expect 3 asserts
3446  if(!insn_match_find_next(fw,is,14,match_bl_blximm)) {
3447  // printf("sig_match_flash_param_table: no match bl 1\n");
3448  return 0;
3449  }
3450  if(!is_sig_call(fw,is,"DebugAssert")) {
3451  // printf("sig_match_flash_param_table: bl 1 not DebugAssert at 0x%"PRIx64"\n",is->insn->address);
3452  return 0;
3453  }
3454  if(!insn_match_find_next(fw,is,7,match_bl_blximm)) {
3455  // printf("sig_match_flash_param_table: no match bl 2\n");
3456  return 0;
3457  }
3458  if(!is_sig_call(fw,is,"DebugAssert")) {
3459  // printf("sig_match_flash_param_table: bl 2 not DebugAssert at 0x%"PRIx64"\n",is->insn->address);
3460  return 0;
3461  }
3462  if(!insn_match_find_next(fw,is,8,match_bl_blximm)) {
3463  // printf("sig_match_flash_param_table: no match bl 3\n");
3464  return 0;
3465  }
3466  if(!is_sig_call(fw,is,"DebugAssert")) {
3467  // printf("sig_match_flash_param_table: bl 3 not DebugAssert at 0x%"PRIx64"\n",is->insn->address);
3468  return 0;
3469  }
3470  // expect AcquireRecursiveLockStrictly, func
3471  if(!insn_match_find_nth(fw,is,14,2,match_bl_blximm)) {
3472  // printf("sig_match_flash_param_table: no match sub 1\n");
3473  return 0;
3474  }
3475  // follow
3477 
3478  // first call
3479  if(!insn_match_find_next(fw,is,8,match_bl_blximm)) {
3480  // printf("sig_match_flash_param_table: no match sub 1 bl\n");
3481  return 0;
3482  }
3483 
3484  // follow
3486  // first instruction should load address
3487  disasm_iter(fw,is);
3488  uint32_t adr=LDR_PC2val(fw,is->insn);
3489  if(!adr) {
3490  // printf("sig_match_flash_param_table: no match LDR PC 0x%"PRIx64"\n",is->insn->address);
3491  return 0;
3492  }
3493  save_misc_val(rule->name,adr,0,(uint32_t)is->insn->address);
3494  return 1;
3495 }
int sig_match_focus_busy ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3752 der Datei finsig_thumb2.c.

3753 {
3754  if(!init_disasm_sig_ref(fw,is,rule)) {
3755  return 0;
3756  }
3757  // look for first TakeSemaphore
3758  if(!find_next_sig_call(fw,is,40,"TakeSemaphore")) {
3759  // printf("sig_match_focus_busy: no match TakeSemaphore\n");
3760  return 0;
3761  }
3762  // next call
3763  if(!insn_match_find_next(fw,is,5,match_bl_blximm)) {
3764  // printf("sig_match_focus_busy: no match bl\n");
3765  return 0;
3766  }
3767  // follow
3769  // get base address from first LDR PC
3770  if(!insn_match_find_next(fw,is,5,match_ldr_pc)) {
3771  // printf("sig_match_focus_busy: match LDR PC failed\n");
3772  return 0;
3773  }
3774  uint32_t base=LDR_PC2val(fw,is->insn);
3775  arm_reg rb=is->insn->detail->arm.operands[0].reg;
3776 
3777  // look for first TakeSemaphoreStrictly
3778  if(!find_next_sig_call(fw,is,50,"TakeSemaphoreStrictly")) {
3779  // printf("sig_match_focus_busy: no match TakeSemaphoreStrictly\n");
3780  return 0;
3781  }
3782  const insn_match_t match_ldr[]={
3783  {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM_ANY}},
3784  {MATCH_INS(CBZ, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM_ANY}},
3785  {ARM_INS_ENDING}
3786  };
3787  if(!insn_match_find_next_seq(fw,is,10,match_ldr)) {
3788  // printf("sig_match_focus_busy: no match LDR\n");
3789  return 0;
3790  }
3791  // rewind to LDR
3792  disasm_iter_init(fw,is,adr_hist_get(&is->ah,1));
3793  disasm_iter(fw,is);
3794  // check LDR
3795  if(is->insn->detail->arm.operands[1].mem.base != rb) {
3796  // printf("sig_match_focus_busy: no match LDR base\n");
3797  return 0;
3798  }
3799  save_misc_val(rule->name,base,is->insn->detail->arm.operands[1].mem.disp,(uint32_t)is->insn->address);
3800  return 1;
3801 }
int sig_match_get_canon_mode_list ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3622 der Datei finsig_thumb2.c.

3623 {
3624  uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
3625  if(!str_adr) {
3626  printf("sig_match_get_canon_mode_list: failed to find ref %s\n",rule->ref_name);
3627  return 0;
3628  }
3629  uint32_t adr=0;
3630  // TODO should handle multiple instances of string
3631  disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default); // reset to a bit before where the string was found
3632  while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
3633  // printf("sig_match_get_canon_mode_list: str match 0x%"PRIx64"\n",is->insn->address);
3634  if(!find_next_sig_call(fw,is,4,"LogCameraEvent")) {
3635  // printf("sig_match_get_canon_mode_list: no LogCameraEvent\n");
3636  continue;
3637  }
3638  // some cameras have a mov and an extra call
3639  if(!disasm_iter(fw,is)) {
3640  // printf("sig_match_get_canon_mode_list: disasm failed\n");
3641  return 0;
3642  }
3643  const insn_match_t match_mov_r0_1[]={
3644 #if CS_API_MAJOR < 4
3645  {MATCH_INS(MOVS, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM(1)}},
3646 #endif
3647  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM(1)}},
3648  {ARM_INS_ENDING}
3649  };
3650  if(insn_match_any(is->insn,match_mov_r0_1)) {
3651  if(!insn_match_find_nth(fw,is,2,2,match_bl_blximm)) {
3652  // printf("sig_match_get_canon_mode_list: no match bl 1x\n");
3653  continue;
3654  }
3655  } else {
3656  if(!insn_match_any(is->insn,match_bl_blximm)) {
3657  // printf("sig_match_get_canon_mode_list: no match bl 1\n");
3658  continue;
3659  }
3660  }
3661  // found something to follow, break
3662  adr=get_branch_call_insn_target(fw,is);
3663  break;
3664  }
3665  if(!adr) {
3666  return 0;
3667  }
3668  // printf("sig_match_get_canon_mode_list: sub 1 0x%08x\n",adr);
3669  disasm_iter_init(fw,is,adr);
3670  if(!find_next_sig_call(fw,is,40,"TakeSemaphoreStrictly")) {
3671  // printf("sig_match_get_canon_mode_list: no TakeSemaphoreStrictly\n");
3672  return 0;
3673  }
3674  // match second call
3675  if(!insn_match_find_nth(fw,is,12,2,match_b_bl_blximm)) {
3676  // printf("sig_match_get_canon_mode_list: no match bl 2\n");
3677  return 0;
3678  }
3679  // follow
3681  const insn_match_t match_loop[]={
3686  {ARM_INS_ENDING}
3687  };
3688  if(!insn_match_find_next_seq(fw,is,64,match_loop)) {
3689  // printf("sig_match_get_canon_mode_list: match 1 failed\n");
3690  return 0;
3691  }
3692  if(!insn_match_find_next(fw,is,2,match_bl_blximm)) {
3693  // printf("sig_match_get_canon_mode_list: no match bl 3\n");
3694  return 0;
3695  }
3696  // should be func
3697  adr=get_branch_call_insn_target(fw,is);
3698  // sanity check
3699  disasm_iter_init(fw,is,adr);
3700  const insn_match_t match_ldr_r0_ret[]={
3701  {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM_BASE(PC)}},
3702  {MATCH_INS(BX, 1), {MATCH_OP_REG(LR)}},
3703  {ARM_INS_ENDING}
3704  };
3705  if(!insn_match_find_next_seq(fw,is,1,match_ldr_r0_ret)) {
3706  // printf("sig_match_get_canon_mode_list: match 2 failed\n");
3707  return 0;
3708  }
3709  return save_sig_with_j(fw,rule->name,adr);
3710 }
int sig_match_get_current_exp ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1200 der Datei finsig_thumb2.c.

1201 {
1202  if(!init_disasm_sig_ref(fw,is,rule)) {
1203  return 0;
1204  }
1205  if(!insn_match_find_next(fw,is,2,match_bl_blximm)) {
1206  printf("sig_match_get_current_exp: bl match 1 failed\n");
1207  return 0;
1208  }
1209  // follow
1211  if(!insn_match_find_next(fw,is,6,match_bl_blximm)) {
1212  printf("sig_match_get_current_exp: bl match 2 failed\n");
1213  return 0;
1214  }
1215  // follow
1217  if(!insn_match_find_next(fw,is,6,match_bl_blximm)) {
1218  printf("sig_match_get_current_exp: bl match 3 failed\n");
1219  return 0;
1220  }
1221  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1222 }
int sig_match_get_current_nd_value ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1224 der Datei finsig_thumb2.c.

1225 {
1226  // this match is only valid for cameras with both ND and Iris
1227  if(!get_misc_val_value("CAM_HAS_ND_FILTER") || !get_misc_val_value("CAM_HAS_IRIS_DIAPHRAGM")) {
1228  return 0;
1229  }
1230  if(!init_disasm_sig_ref(fw,is,rule)) {
1231  return 0;
1232  }
1233  if(!find_next_sig_call(fw,is,36,"GetCurrentShutterSpeed_FW")) {
1234  printf("sig_match_get_current_nd_value: no match GetCurrentShutterSpeed_FW\n");
1235  return 0;
1236  }
1237  // bl <func we want>
1238  // strh r0, [rN,8]
1239  const insn_match_t match_bl_strh[]={
1241  {MATCH_INS(STRH,2), {MATCH_OP_REG(R0), MATCH_OP_MEM(INVALID,INVALID,0x8)}},
1242  {ARM_INS_ENDING}
1243  };
1244  if(!insn_match_find_next_seq(fw,is,10,match_bl_strh)) {
1245  printf("sig_match_get_current_nd_value: match failed\n");
1246  return 0;
1247  }
1248  // rewind one for call
1249  disasm_iter_init(fw,is,adr_hist_get(&is->ah,1));
1250  disasm_iter(fw,is);
1251  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1252 }
int sig_match_get_dial_hw_position ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1571 der Datei finsig_thumb2.c.

1572 {
1573  if(!init_disasm_sig_ref(fw,is,rule)) {
1574  return 0;
1575  }
1576  uint32_t adr = find_last_call_from_func(fw,is,18,50);
1577  if(!adr) {
1578  // printf("sig_match_get_dial_hw_position: no match call 1 at 0x%"PRIx64"\n",is->insn->address);
1579  return 0;
1580  }
1581  // follow
1582  disasm_iter_init(fw,is,adr);
1583  adr = find_last_call_from_func(fw,is,16,32);
1584  if(!adr) {
1585  // printf("sig_match_get_dial_hw_position: no match call 2 at 0x%"PRIx64"\n",is->insn->address);
1586  return 0;
1587  }
1588  // follow
1589  disasm_iter_init(fw,is,adr);
1590  // find next function call
1591  if(!insn_match_find_next(fw,is,30,match_bl_blximm)) {
1592  // printf("sig_match_get_dial_hw_position: no match call 3 at 0x%"PRIx64"\n",is->insn->address);
1593  return 0;
1594  }
1595  uint32_t fadr = get_branch_call_insn_target(fw,is);
1596  // rewind and match instructions for sanity check
1597  disasm_iter_init(fw,is,adr_hist_get(&is->ah,4));
1598  const insn_match_t match_hw_dial_call[]={
1600  {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0),MATCH_OP_MEM_BASE(PC)}},
1602  {ARM_INS_ENDING}
1603  };
1604  if(!insn_match_find_next(fw,is,4,match_hw_dial_call)) {
1605  // printf("sig_match_get_dial_hw_position: no match seq 0x%"PRIx64"\n",is->insn->address);
1606  return 0;
1607  }
1608  return save_sig_with_j(fw,rule->name,fadr);
1609 }
int sig_match_get_drive_cluster_size ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2334 der Datei finsig_thumb2.c.

2335 {
2336  if(!init_disasm_sig_ref(fw,is,rule)) {
2337  return 0;
2338  }
2339  // only handle first match, don't expect multiple refs to string
2340  if(fw_search_insn(fw,is,search_disasm_str_ref,0,"A/OpLogErr.txt",(uint32_t)is->adr+260)) {
2341  // find first call after string ref
2342  if(!insn_match_find_next(fw,is,3,match_bl_blximm)) {
2343  // printf("sig_match_get_drive_cluster_size: bl not found\n");
2344  return 0;
2345  }
2346  // follow
2348  // find second call
2349  if(!insn_match_find_nth(fw,is,13,2,match_bl_blximm)) {
2350  // printf("sig_match_get_drive_cluster_size: call 1 not found\n");
2351  return 0;
2352  }
2353  // follow
2355  disasm_iter(fw,is);
2356  if (B_target(fw, is->insn))
2358  // find next call
2359  if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
2360  // printf("sig_match_get_drive_cluster_size: call 2 not found\n");
2361  return 0;
2362  }
2363  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2364  }
2365  return 0;
2366 }
int sig_match_get_kbd_state ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1547 der Datei finsig_thumb2.c.

1548 {
1549  if(!init_disasm_sig_ref(fw,is,rule)) {
1550  return 0;
1551  }
1552  // instructions that zero out physw_status
1553  insn_match_t match[]={
1554  {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM_BASE(PC)}},
1556  {ARM_INS_ENDING}
1557  };
1558 
1559  if(!insn_match_find_next_seq(fw,is,11,match)) {
1560  return 0;
1561  }
1562  save_sig_with_j(fw,"GetKbdState",get_branch_call_insn_target(fw,is));
1563  // look for kbd_read_keys_r2
1564  if(!insn_match_find_next(fw,is,5,match_b_bl_blximm)) {
1565  return 0;
1566  }
1567  save_sig_with_j(fw,"kbd_read_keys_r2",get_branch_call_insn_target(fw,is));
1568  return 1;
1569 }
int sig_match_get_nd_value ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1164 der Datei finsig_thumb2.c.

1165 {
1166  // this match is only valid for cameras with both ND and Iris
1167  if(!get_misc_val_value("CAM_HAS_ND_FILTER") || !get_misc_val_value("CAM_HAS_IRIS_DIAPHRAGM")) {
1168  return 0;
1169  }
1170 
1171  if(!init_disasm_sig_ref(fw,is,rule)) {
1172  return 0;
1173  }
1174  if(!find_next_sig_call(fw,is,16,"ClearEventFlag")) {
1175  printf("sig_match_get_nd_value: no match ClearEventFlag\n");
1176  return 0;
1177  }
1178  if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
1179  printf("sig_match_get_nd_value: bl match 1 failed\n");
1180  return 0;
1181  }
1182  // follow
1184  disasm_iter(fw,is);
1185  if (B_target(fw,is->insn))
1187  // first call should be either get_nd_value or GetUsableAvRange
1188  if(!insn_match_find_next(fw,is,5,match_bl_blximm)) {
1189  printf("sig_match_get_nd_value: bl match 2 failed\n");
1190  return 0;
1191  }
1193  if(addr == get_saved_sig_val("GetUsableAvRange")) {
1194  printf("sig_match_get_nd_value: found GetUsableAvRange, iris or ND only?\n");
1195  return 0;
1196  }
1197  return save_sig_with_j(fw,rule->name,addr);
1198 }
int sig_match_get_num_posted_messages ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2893 der Datei finsig_thumb2.c.

2894 {
2895  if(!init_disasm_sig_ref(fw,is,rule)) {
2896  return 0;
2897  }
2898  if(!find_next_sig_call(fw,is,50,"TakeSemaphore")) {
2899  printf("sig_match_get_num_posted_messages: failed to find TakeSemaphore\n");
2900  return 0;
2901  }
2902  // find next call
2903  if(!insn_match_find_next(fw,is,5,match_bl_blximm)) {
2904  printf("sig_match_get_num_posted_messages: no match bl 0x%"PRIx64"\n",is->insn->address);
2905  return 0;
2906  }
2907  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2908 }
int sig_match_get_parameter_data ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2475 der Datei finsig_thumb2.c.

2476 {
2477  if(!init_disasm_sig_ref(fw,is,rule)) {
2478  return 0;
2479  }
2480  const insn_match_t match_cmp_bhs[]={
2483  {ARM_INS_ENDING}
2484  };
2485  if(!insn_match_find_next_seq(fw,is,4,match_cmp_bhs)) {
2486  // printf("sig_match_get_parameter_data: no match cmp, bhs\n");
2487  return 0;
2488  }
2489  // follow
2491  if(!insn_match_find_next(fw,is,1,match_b)) {
2492  // printf("sig_match_get_parameter_data: no match b\n");
2493  return 0;
2494  }
2495  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2496 }
int sig_match_get_semaphore_value ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1694 der Datei finsig_thumb2.c.

1695 {
1696  uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
1697  if(!str_adr) {
1698  printf("sig_get_semaphore_value: failed to find ref %s\n",rule->ref_name);
1699  return 0;
1700  }
1701 
1702  disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default); // reset to a bit before where the string was found
1703  // assume first / only ref
1705  // printf("sig_get_semaphore_value: failed to find code ref to %s\n",rule->ref_name);
1706  return 0;
1707  }
1708  // search backwards for func call
1709  uint32_t fadr=0;
1710  int i;
1711  for(i=1; i<=5; i++) {
1712  if(!fw_disasm_iter_single(fw,adr_hist_get(&is->ah,i))) {
1713  // printf("sig_get_semaphore_value: disasm failed\n");
1714  return 0;
1715  }
1717  fadr=get_branch_call_insn_target(fw,fw->is);
1718  break;
1719  }
1720  }
1721  if(!fadr) {
1722  // printf("sig_get_semaphore_value: failed to find bl 1\n");
1723  return 0;
1724  }
1725  // follow
1726  disasm_iter_init(fw,is,fadr);
1727  // look for first call
1728  if(!insn_match_find_next(fw,is,9,match_bl_blximm)) {
1729  // printf("sig_get_semaphore_value: failed to find bl 2\n");
1730  return 0;
1731  }
1732  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1733 }
int sig_match_imager_active ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1280 der Datei finsig_thumb2.c.

1281 {
1282  if(!init_disasm_sig_ref(fw,is,rule)) {
1283  return 0;
1284  }
1285 
1286  const insn_match_t match_ldr_mov_str_pop[]={
1288  {MATCH_INS(MOV,2), {MATCH_OP_REG_ANY, MATCH_OP_IMM(1)}},
1291  {ARM_INS_ENDING}
1292  };
1293 
1294  int backtrack=3;
1295  if(!insn_match_find_next_seq(fw,is,10,match_ldr_mov_str_pop)) {
1296  // re-init and try reverse mov/ldr order
1297  init_disasm_sig_ref(fw,is,rule);
1298  const insn_match_t match_mov_ldr_str_pop[]={
1299  {MATCH_INS(MOV,2), {MATCH_OP_REG_ANY, MATCH_OP_IMM(1)}},
1303  {ARM_INS_ENDING}
1304  };
1305  if(!insn_match_find_next_seq(fw,is,10,match_mov_ldr_str_pop)) {
1306  printf("sig_match_imager_active: match failed\n");
1307  return 0;
1308  }
1309  backtrack=2;
1310  }
1311  // rewind to LDR
1312  disasm_iter_init(fw,is,adr_hist_get(&is->ah,backtrack));
1313  disasm_iter(fw,is);
1314  uint32_t base=LDR_PC2val(fw,is->insn);
1315  uint32_t reg=is->insn->detail->arm.operands[0].reg;
1316 // printf("base 0x%08x @0x%08x\n",base,(uint32_t)is->insn->address);
1317  // skip mov if after LDR
1318  if(backtrack == 3) {
1319  disasm_iter(fw,is);
1320  }
1321  disasm_iter(fw,is);
1322  // sanity check base is the same as LDR'd to
1323  if(is->insn->detail->arm.operands[1].mem.base != reg) {
1324  printf("sig_match_imager_active: reg mismatch\n");
1325  return 0;
1326  }
1327  uint32_t off=is->insn->detail->arm.operands[1].mem.disp;
1328 // printf("off 0x%08x @0x%08x\n",off,(uint32_t)is->insn->address);
1329  save_misc_val("imager_active",base,off,(uint32_t)is->insn->address);
1330  return 1;
1331 }
int sig_match_imager_active_callback ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1254 der Datei finsig_thumb2.c.

1255 {
1256  if(!init_disasm_sig_ref(fw,is,rule)) {
1257  return 0;
1258  }
1259  const insn_match_t match_ldr_bl_mov_pop[]={
1260  {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM_BASE(PC)}},
1262  {MATCH_INS(MOV,2), {MATCH_OP_REG(R0), MATCH_OP_IMM(0)}},
1264  {ARM_INS_ENDING}
1265  };
1266 
1267  if(!insn_match_find_next_seq(fw,is,28,match_ldr_bl_mov_pop)) {
1268  printf("sig_match_imager_active_callback: match failed\n");
1269  return 0;
1270  }
1271  // rewind to LDR r0,...
1272  disasm_iter_init(fw,is,adr_hist_get(&is->ah,3));
1273  // get LDR value
1274  disasm_iter(fw,is);
1275  uint32_t f1=LDR_PC2val(fw,is->insn);
1276 // printf("f1 0x%08x\n",f1);
1277  // thumb bit should be set correctly
1278  return save_sig_with_j(fw,rule->name,f1);
1279 }
int sig_match_init_ex_drivers ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3244 der Datei finsig_thumb2.c.

3245 {
3246  if(!init_disasm_sig_ref(fw,is,rule)) {
3247  return 0;
3248  }
3249  int i;
3250  int b_count;
3251  // search forward 32 instructions or 14 calls
3252  for(i=0, b_count = 0; i < 32 && b_count < 14; i++) {
3253  if (!disasm_iter(fw,is)) {
3254  printf("sig_match_init_ex_drivers: disasm failed 1\n");
3255  return 0;
3256  }
3257  uint32_t b_tgt = get_branch_call_insn_target(fw,is);
3258  if(!b_tgt) {
3259  continue;
3260  }
3261  b_count++;
3262  uint64_t next_adr = is->adr | is->thumb;
3263  disasm_iter_init(fw,is,b_tgt);
3264  if (!disasm_iter(fw,is)) {
3265  printf("sig_match_init_ex_drivers: disasm failed 2\n");
3266  return 0;
3267  }
3268  // expect the function we're looking for to start with a push
3269  if(is->insn->id == ARM_INS_PUSH) {
3270  if(find_next_sig_call(fw,is,30,"DebugAssert")) {
3271  uint32_t regs[4];
3272  if((get_call_const_args(fw,is,5,regs)&0x2)==0x2) {
3273  const char *str=(char *)adr2ptr(fw,regs[1]);
3274  if(str && strcmp(str,"InitExDrivers.c") == 0) {
3275  return save_sig_with_j(fw,rule->name,b_tgt);
3276  }
3277  }
3278  }
3279  }
3280  disasm_iter_init(fw,is,next_adr);
3281  }
3282  return 0;
3283 }
int sig_match_jpeg_count_str ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3496 der Datei finsig_thumb2.c.

3497 {
3498  uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
3499  if(!str_adr) {
3500  printf("sig_match_jpeg_count_str: failed to find ref %s\n",rule->ref_name);
3501  return 0;
3502  }
3503  // TODO should handle multiple instances of string
3504  disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default); // reset to a bit before where the string was found
3505  while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
3506  // printf("sig_match_jpeg_count_str: str match 0x%"PRIx64"\n",is->insn->address);
3507  if(!insn_match_find_next(fw,is,3,match_bl_blximm)) {
3508  // printf("sig_match_jpeg_count_str: no match bl\n");
3509  continue;
3510  }
3511  if(!is_sig_call(fw,is,"sprintf_FW")) {
3512  // printf("sig_match_jpeg_count_str: not sprintf_FW at 0x%"PRIx64"\n",is->insn->address);
3513  continue;
3514  }
3515  // expect ptr in r0, str in r1
3516  uint32_t regs[4];
3517  if((get_call_const_args(fw,is,5,regs)&0x3)!=0x3) {
3518  // printf("sig_match_jpeg_count_str: failed to get sprintf args 0x%"PRIx64"\n",is->insn->address);
3519  continue;
3520  }
3521  if(regs[1] != str_adr) {
3522  // printf("sig_match_jpeg_count_str: expected r1 == 0x%08x not 0x%08x at 0x%"PRIx64"\n",str_adr, regs[1],is->insn->address);
3523  return 0;
3524  }
3525  if(!adr_is_var(fw,regs[0])) {
3526  // printf("sig_match_jpeg_count_str: r0 == 0x%08x not var ptr at 0x%"PRIx64"\n",regs[0],is->insn->address);
3527  return 0;
3528  }
3529  save_misc_val(rule->name,regs[0],0,(uint32_t)is->insn->address);
3530  return 1;
3531  }
3532  return 0;
3533 }
int sig_match_kbd_read_keys ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1523 der Datei finsig_thumb2.c.

1524 {
1525  if(!init_disasm_sig_ref(fw,is,rule)) {
1526  return 0;
1527  }
1528  // look for kbd_read_keys
1529  if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
1530  return 0;
1531  }
1532  save_sig(fw,"kbd_read_keys",get_branch_call_insn_target(fw,is));
1533  if(!disasm_iter(fw,is)) {
1534  printf("sig_match_kbd_read_keys: disasm failed\n");
1535  return 0;
1536  }
1538  if(physw_status) {
1539  save_misc_val("physw_status",physw_status,0,(uint32_t)is->insn->address);
1540  save_sig(fw,"kbd_p1_f_cont",(uint32_t)(is->insn->address) | is->thumb);
1541  return 1;
1542  }
1543  return 0;
1544 }
int sig_match_levent_table ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3399 der Datei finsig_thumb2.c.

3400 {
3401  if(!init_disasm_sig_ref(fw,is,rule)) {
3402  return 0;
3403  }
3404  if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
3405  // printf("sig_match_levent_table: no match bl 0x%"PRIx64"\n",is->insn->address);
3406  return 0;
3407  }
3408  // follow
3410 
3411  // find first call of next function
3412  if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
3413  // printf("sig_match_levent_table: no match bl 0x%"PRIx64"\n",is->insn->address);
3414  return 0;
3415  }
3416 
3417  // follow
3419 
3420  // first instruction should load address
3421  disasm_iter(fw,is);
3422  uint32_t adr=LDR_PC2val(fw,is->insn);
3423  if(!adr) {
3424  // printf("sig_match_levent_table: no match LDR PC 0x%"PRIx64"\n",is->insn->address);
3425  return 0;
3426  }
3427  uint32_t *p=(uint32_t *)adr2ptr(fw,adr);
3428  if(!p) {
3429  printf("sig_match_levent_table: 0x%08x not a ROM adr 0x%"PRIx64"\n",adr,is->insn->address);
3430  return 0;
3431  }
3432  if(*(p+1) != 0x800) {
3433  printf("sig_match_levent_table: expected 0x800 not 0x%x at 0x%08x ref 0x%"PRIx64"\n",*(p+1),adr,is->insn->address);
3434  return 0;
3435  }
3436  // TODO saving the function might be useful for analysis
3437  save_misc_val(rule->name,adr,0,(uint32_t)is->insn->address);
3438  return 1;
3439 }
int sig_match_log ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2186 der Datei finsig_thumb2.c.

2187 {
2188  if(!init_disasm_sig_ref(fw,is,rule)) {
2189  return 0;
2190  }
2191  const insn_match_t match_pop6[]={
2192  {MATCH_INS(POP, 6), {MATCH_OP_REST_ANY}},
2193  {ARM_INS_ENDING}
2194  };
2195  // skip forward through 3x pop {r4, r5, r6, r7, r8, lr}
2196  if(!insn_match_find_nth(fw,is,38,3,match_pop6)) {
2197  return 0;
2198  }
2199  // third call
2200  if(!insn_match_find_nth(fw,is,24,3,match_bl_blximm)) {
2201  return 0;
2202  }
2203  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2204 }
int sig_match_log_camera_event ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1407 der Datei finsig_thumb2.c.

1408 {
1409  if(!init_disasm_sig_ref(fw,is,rule)) {
1410  return 0;
1411  }
1412  if(!insn_match_find_next(fw,is,6,match_bl_blximm)) {
1413  // printf("sig_match_log_camera_event: bl match failed\n");
1414  return 0;
1415  }
1416  uint32_t regs[4];
1417  if((get_call_const_args(fw,is,4,regs)&3)!=3) {
1418  // printf("sig_match_log_camera_event: get args failed\n");
1419  return 0;
1420  }
1421  if(regs[0] != 0x60) {
1422  // printf("sig_match_log_camera_event: bad r0 0x%x\n",regs[0]);
1423  return 0;
1424  }
1425  const char *str=(char *)adr2ptr(fw,regs[1]);
1426  if(!str || strcmp(str,"_SImage") != 0) {
1427  // printf("sig_match_log_camera_event: bad r1 0x%x\n",regs[1]);
1428  return 0;
1429  }
1430  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1431 }
int sig_match_misc_flag_named ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3536 der Datei finsig_thumb2.c.

3537 {
3538  uint32_t ref=get_saved_sig_val(rule->ref_name);
3539  save_misc_val(rule->name,(ref)?1:0,0,ref);
3540  return 1;
3541 }
int sig_match_mkdir ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2592 der Datei finsig_thumb2.c.

2593 {
2594  if(!init_disasm_sig_ref(fw,is,rule)) {
2595  return 0;
2596  }
2597  const insn_match_t match[]={
2599  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R0), MATCH_OP_REG(SP)}},
2600  {MATCH_INS(LDR, 2), {MATCH_OP_REG(R1), MATCH_OP_MEM_BASE(SP)}},
2602  {ARM_INS_ENDING}
2603  };
2604  if(insn_match_find_next_seq(fw,is,148,match)) {
2605  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2606  }
2607 
2608  init_disasm_sig_ref(fw,is,rule);
2609  const insn_match_t match2[]={
2610  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R1), MATCH_OP_REG_ANY}},
2612  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R0), MATCH_OP_REG(SP)}},
2614  {ARM_INS_ENDING}
2615  };
2616  if(!insn_match_find_next_seq(fw,is,148,match2)) {
2617  //printf("sig_match_mkdir: no match\n");
2618  return 0;
2619  }
2620  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2621 }
int sig_match_mktime_ext ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2368 der Datei finsig_thumb2.c.

2369 {
2370  uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2371  if(!str_adr) {
2372  printf("sig_match_mktime_ext: failed to find ref %s\n",rule->ref_name);
2373  return 0;
2374  }
2375  // TODO should handle multiple instances of string
2376  disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default); // reset to a bit before where the string was found
2377  while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2378  // expect sscanf after str
2379  if(!find_next_sig_call(fw,is,12,"sscanf_FW")) {
2380  // printf("sig_match_mktime_ext: no sscanf\n");
2381  return 0;
2382  }
2383  // find next call
2384  if(!insn_match_find_next(fw,is,22,match_bl_blximm)) {
2385  // printf("sig_match_mktime_ext: no call\n");
2386  return 0;
2387  }
2388  // follow
2390  if(!disasm_iter(fw,is)) {
2391  printf("sig_match_mktime_ext: disasm failed\n");
2392  return 0;
2393  }
2394  uint32_t j_tgt=get_direct_jump_target(fw,is);
2395  // veneer?
2396  if(j_tgt) {
2397  // follow
2398  disasm_iter_init(fw,is,j_tgt);
2399  if(!disasm_iter(fw,is)) {
2400  printf("sig_match_mktime_ext: disasm failed\n");
2401  return 0;
2402  }
2403  }
2404  const insn_match_t match_pop4[]={
2405  {MATCH_INS(POP, 4), {MATCH_OP_REST_ANY}},
2406  {MATCH_INS(POP, 6), {MATCH_OP_REST_ANY}},
2407  {ARM_INS_ENDING}
2408  };
2409 
2410  // find pop
2411  if(!insn_match_find_next(fw,is,54,match_pop4)) {
2412  // printf("sig_match_mktime_ext: no pop\n");
2413  return 0;
2414  }
2415  if(!insn_match_find_next(fw,is,1,match_b)) {
2416  // printf("sig_match_mktime_ext: no b\n");
2417  return 0;
2418  }
2419  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2420  }
2421  return 0;
2422 }
int sig_match_named ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 4448 der Datei finsig_thumb2.c.

4449 {
4450  uint32_t ref_adr = get_saved_sig_val(rule->ref_name);
4451  if(!ref_adr) {
4452  printf("sig_match_named: missing %s\n",rule->ref_name);
4453  return 0;
4454  }
4455  uint32_t sig_type = rule->param & SIG_NAMED_TYPE_MASK;
4456  uint32_t sig_flags = rule->param & SIG_NAMED_FLAG_MASK;
4459  if(!sig_nth) {
4460  sig_nth=1;
4461  }
4462  if(!sig_nth_range) {
4463  sig_nth_range=5;
4464  }
4465  // no offset, just save match as is
4466  // TODO might want to validate anyway
4467  if(sig_type == SIG_NAMED_ASIS) {
4468  sig_match_named_save_sig(fw,rule->name,ref_adr,sig_flags);
4469  return 1;
4470  }
4471  const insn_match_t *insn_match;
4472  if(sig_type == SIG_NAMED_JMP_SUB) {
4473  insn_match = match_b_bl_blximm;
4474  } else if(sig_type == SIG_NAMED_SUB) {
4475  insn_match = match_bl_blximm;
4476  } else if(sig_type == SIG_NAMED_INSN) {
4477  insn_match = NULL;
4478  } else {
4479  printf("sig_match_named: %s invalid type %d\n",rule->ref_name,sig_type);
4480  return 0;
4481  }
4482 
4483  disasm_iter_init(fw,is,ref_adr);
4484  // TODO for eventprocs, may just want to use the original
4485  if(is_immediate_ret_sub(fw,is)) {
4486  printf("sig_match_named: immediate return %s\n",rule->name);
4487  return 0;
4488  }
4489  if(sig_type == SIG_NAMED_INSN) {
4490  int i;
4491  // iter starts on the address given to init
4492  for(i=0;i<=sig_nth;i++) {
4493  if(!disasm_iter(fw,is)) {
4494  printf("sig_match_named: disasm failed %s 0x%08x\n",rule->name,(uint32_t)is->insn->address);
4495  return 0;
4496  }
4497  }
4498  sig_match_named_save_sig(fw,rule->name,iter_state_adr(is),sig_flags);
4499  return 1;
4500  }
4501 
4502  // initial 15 is hard coded
4503  if(insn_match_find_nth(fw,is,15 + sig_nth_range*sig_nth,sig_nth,insn_match)) {
4504  uint32_t adr = B_BL_BLXimm_target(fw,is->insn);
4505  if(adr) {
4506  // BLX, set thumb bit
4507  if(is->insn->id == ARM_INS_BLX) {
4508  // curently not thumb, set in target
4509  if(!is->thumb) {
4510  adr=ADR_SET_THUMB(adr);
4511  }
4512  } else {
4513  // preserve current state
4514  adr |= is->thumb;
4515  }
4516  disasm_iter_set(fw,is,adr);
4517  if(disasm_iter(fw,is)) {
4518  // TODO only checks one level
4519  uint32_t j_adr=get_direct_jump_target(fw,is);
4520  if(j_adr) {
4521  char *buf=malloc(strlen(rule->name)+3);
4522  // add j_ for cross referencing
4523  sprintf(buf,"j_%s",rule->name);
4524  add_func_name(fw,buf,adr,NULL); // add the previous address as j_...
4525  adr=j_adr;
4526  }
4527  } else {
4528  printf("sig_match_named: disasm failed in j_ check at %s 0x%08x\n",rule->name,adr);
4529  }
4530  sig_match_named_save_sig(fw,rule->name,adr,sig_flags);
4531  return 1;
4532  } else {
4533  printf("sig_match_named: %s invalid branch target 0x%08x\n",rule->ref_name,adr);
4534  }
4535  } else {
4536  printf("sig_match_named: %s branch not found 0x%08x\n",rule->ref_name,ref_adr);
4537  }
4538  return 0;
4539 }
int sig_match_named_last ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 4391 der Datei finsig_thumb2.c.

4392 {
4393  uint32_t ref_adr = get_saved_sig_val(rule->ref_name);
4395  int max = (rule->param&SIG_NAMED_LAST_MAX_MASK);
4396  if(!ref_adr) {
4397  printf("sig_match_named_last: %s missing %s\n",rule->name,rule->ref_name);
4398  return 0;
4399  }
4400  disasm_iter_init(fw,is,ref_adr);
4401  if(is_immediate_ret_sub(fw,is)) {
4402  printf("sig_match_named_last: immediate return %s\n",rule->name);
4403  return 0;
4404  }
4405  uint32_t fadr = find_last_call_from_func(fw,is,min,max);
4406  if(fadr) {
4407  return save_sig_with_j(fw,rule->name,fadr);
4408  }
4409  return 0;
4410 }
void sig_match_named_save_sig ( firmware fw,
const char *  name,
uint32_t  adr,
uint32_t  flags 
)

Definiert in Zeile 4438 der Datei finsig_thumb2.c.

4439 {
4440  if(flags & SIG_NAMED_CLEARTHUMB) {
4441  adr = ADR_CLEAR_THUMB(adr);
4442  }
4443  save_sig(fw,name,adr);
4444 }
int sig_match_near_str ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 4305 der Datei finsig_thumb2.c.

4306 {
4307  if (!get_saved_sig_val(rule->name))
4308  {
4309  uint32_t call_adr = find_call_near_str(fw,is,rule);
4310  if(call_adr) {
4311  return save_sig_match_call(fw, rule, call_adr);
4312  }
4313  }
4314  return 0;
4315 }
int sig_match_omar_init ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3285 der Datei finsig_thumb2.c.

3286 {
3287  // not present on digic 7
3288  if (fw->arch_flags & FW_ARCH_FL_VMSA) {
3289  return 0;
3290  }
3291  if(!init_disasm_sig_ref(fw,is,rule)) {
3292  return 0;
3293  }
3294  uint32_t fadr = find_last_call_from_func(fw,is,20,42);
3295  if(!fadr) {
3296  printf("sig_match_omar_init: no match call\n");
3297  return 0;
3298  }
3299  // follow
3300  disasm_iter_init(fw,is,fadr);
3301  if(!find_next_sig_call(fw,is,44,"dry_memcpy")) {
3302  printf("sig_match_omar_init: no match dry_memcpy\n");
3303  return 0;
3304  }
3305  uint32_t regs[4];
3306  // expect dry_memcpy(stack ptr,rom ptr, 0x18)
3307  if((get_call_const_args(fw,is,5,regs)&0x6)!=0x6) {
3308  printf("sig_match_omar_init: no match dry_memcpy args 1\n");
3309  return 0;
3310  }
3311  if(regs[2] != 0x18 || !adr2ptr(fw,regs[1])) {
3312  printf("sig_match_omar_init: no match dry_memcpy args 2\n");
3313  return 0;
3314  }
3315  uint32_t dadr = regs[1];
3316  save_misc_val("omar_init_data",dadr,0,(uint32_t)is->insn->address);
3317  misc_blob_t *blobs=malloc(3*sizeof(misc_blob_t));
3318  int i;
3319  for(i = 0; i<2; i++) {
3320  uint32_t dst = fw_u32(fw,dadr + i*12);
3321  uint32_t src = fw_u32(fw,dadr + i*12 + 4);
3322  uint32_t bsize = fw_u32(fw,dadr + i*12 + 8);
3323  if(src && dst && bsize) {
3324  blobs[i].type = MISC_BLOB_TYPE_OMAR;
3325  blobs[i].rom_adr = src;
3326  blobs[i].ram_adr = dst;
3327  blobs[i].size = bsize;
3328  } else {
3329  printf("sig_match_omar_init: invalid blobs\n");
3330  free(blobs);
3331  blobs = NULL;
3332  break;
3333  }
3334  }
3335  if(blobs) {
3336  blobs[2].type = MISC_BLOB_TYPE_NONE;
3337  save_misc_val_blobs("omar_init_values",blobs,0);
3338  }
3339 
3340  return save_sig_with_j(fw,rule->name,fadr);
3341 }
int sig_match_open ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1771 der Datei finsig_thumb2.c.

1772 {
1773  if(!init_disasm_sig_ref(fw,is,rule)) {
1774  return 0;
1775  }
1777  return 0;
1778  }
1779  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1780 }
int sig_match_open_gt_57 ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1783 der Datei finsig_thumb2.c.

1784 {
1785  if(!init_disasm_sig_ref(fw,is,rule)) {
1786  return 0;
1787  }
1788  if(!find_next_sig_call(fw,is,38,"TakeSemaphoreStrictly")) {
1789  return 0;
1790  }
1791  // looking for next call
1792  // this should be equivalent to previous versions Open, without the extra semaphore wrapper
1793  if(!insn_match_find_next(fw,is,5,match_bl_blximm)) {
1794  return 0;
1795  }
1796  // follow
1798  // match same pattern as normal
1800  return 0;
1801  }
1802  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1803 }
int sig_match_palette_vars ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 4115 der Datei finsig_thumb2.c.

4116 {
4117  if(!init_disasm_sig_ref(fw,is,rule)) {
4118  return 0;
4119  }
4120  if(!find_next_sig_call(fw,is,70,"transfer_src_overlay")) {
4121  printf("sig_match_palette_vars: no match transfer_src_overlay\n");
4122  return 0;
4123  }
4124  uint32_t fadr=0;
4125  int i;
4126  // search backwards for call before transfer_src_overlay
4127  for(i=1; i<=6; i++) {
4128  if(!fw_disasm_iter_single(fw,adr_hist_get(&is->ah,i))) {
4129  printf("sig_match_palette_vars: disasm failed\n");
4130  return 0;
4131  }
4132  fadr=get_branch_call_insn_target(fw,fw->is);
4133  if(fadr) {
4134  break;
4135  }
4136  }
4137  if(!fadr) {
4138  printf("sig_match_palette_vars: no match bl 1 0x%"PRIx64"\n",fw->is->insn->address);
4139  return 0;
4140  }
4141  // follow
4142  disasm_iter_init(fw,is,fadr);
4143  // find first func call
4144  if(!insn_match_find_next(fw,is,3,match_bl)) {
4145  printf("sig_match_palette_vars: no match bl 2 0x%"PRIx64"\n",is->insn->address);
4146  return 0;
4147  }
4148  // follow
4150 
4151  if(!insn_match_find_next(fw,is,3,match_ldr_pc)) {
4152  printf("sig_match_palette_vars: no match ldr pc 0x%"PRIx64"\n",is->insn->address);
4153  return 0;
4154  }
4155 
4156  uint32_t pal_base=LDR_PC2val(fw,is->insn);
4157  if(!pal_base || !adr_is_var(fw,pal_base)) {
4158  printf("sig_match_palette_vars: bad LDR PC 0x%"PRIx64"\n",is->insn->address);
4159  return 0;
4160  }
4161  // palette_control is at the start of struct, save register
4162  arm_reg ptr_reg = is->insn->detail->arm.operands[0].reg;
4163 
4164  save_misc_val(rule->name,pal_base,0,(uint32_t)is->insn->address);
4165 
4166  int found=0;
4167  // find LDR Rn [ptr_reg +x]
4168  for(i=0; i<3; i++) {
4169  if(!disasm_iter(fw,is)) {
4170  printf("sig_match_palette_vars: disasm failed\n");
4171  return 0;
4172  }
4173  if (is->insn->id == ARM_INS_LDR && is->insn->detail->arm.operands[1].mem.base == ptr_reg) {
4174  save_misc_val("active_palette_buffer",
4175  pal_base,
4176  is->insn->detail->arm.operands[1].mem.disp,
4177  (uint32_t)is->insn->address);
4178  found=1;
4179  break;
4180  }
4181  }
4182  if(!found) {
4183  printf("sig_match_palette_vars: no match active_palette_buffer 0x%"PRIx64"\n",is->insn->address);
4184  return 0;
4185  }
4186 
4187  if(!find_next_sig_call(fw,is,20,"PTM_RestoreUIProperty_FW")) {
4188  printf("sig_match_palette_vars: no match PTM_RestoreUIProperty_FW\n");
4189  return 0;
4190  }
4191  // find LDR Rn [ptr_reg +x]
4192  for(i=0; i<6; i++) {
4193  if(!disasm_iter(fw,is)) {
4194  printf("sig_match_palette_vars: disasm failed\n");
4195  return 0;
4196  }
4197  if (is->insn->id == ARM_INS_LDR && is->insn->detail->arm.operands[1].mem.base == ptr_reg) {
4198  save_misc_val("palette_buffer_ptr",
4199  pal_base,
4200  is->insn->detail->arm.operands[1].mem.disp,
4201  (uint32_t)is->insn->address);
4202  return 1;
4203  }
4204  }
4205  printf("sig_match_palette_vars: no match palette_buffer_ptr 0x%"PRIx64"\n",is->insn->address);
4206  return 0;
4207 }
int sig_match_physw_event_table ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3574 der Datei finsig_thumb2.c.

3575 {
3576  if(!init_disasm_sig_ref(fw,is,rule)) {
3577  return 0;
3578  }
3579  // expect first LDR pc
3580  if(!insn_match_find_next(fw,is,5,match_ldr_pc)) {
3581  printf("sig_match_physw_event_table: match LDR PC failed\n");
3582  return 0;
3583  }
3584  uint32_t adr=LDR_PC2val(fw,is->insn);
3585  if(!adr) {
3586  printf("sig_match_physw_event_table: no match LDR PC 0x%"PRIx64"\n",is->insn->address);
3587  return 0;
3588  }
3589  if(!adr2ptr(fw,adr)) {
3590  printf("sig_match_physw_event_table: adr not ROM 0x%08x at 0x%"PRIx64"\n",adr,is->insn->address);
3591  return 0;
3592  }
3593  save_misc_val(rule->name,adr,0,(uint32_t)is->insn->address);
3594  return 1;
3595 }
int sig_match_physw_misc ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1434 der Datei finsig_thumb2.c.

1435 {
1436  if(!init_disasm_sig_ref(fw,is,rule)) {
1437  osig* ostub2 = find_sig(fw->sv->stubs,rule->ref_name);
1438  if (ostub2 && ostub2->val)
1439  {
1440  disasm_iter_init(fw,is,ostub2->val);
1441  }
1442  else
1443  {
1444  return 0;
1445  }
1446  }
1447  int i;
1448  uint32_t physw_run=0;
1449  for(i=0; i<3; i++) {
1450  if(!disasm_iter(fw,is)) {
1451  printf("sig_match_physw_misc: disasm failed\n");
1452  return 0;
1453  }
1454  physw_run=LDR_PC2val(fw,is->insn);
1455  if(physw_run) {
1456  if(adr_is_var(fw,physw_run)) {
1457  save_misc_val("physw_run",physw_run,0,(uint32_t)is->insn->address);
1458  break;
1459  } else {
1460  printf("sig_match_physw_misc: adr not data? 0x%08x\n",physw_run);
1461  return 0;
1462  }
1463  }
1464  }
1465  if(!physw_run) {
1466  return 0;
1467  }
1468 
1469  // look for physw_sleep_delay, offset from physw_run, loaded before SleepTask
1470  if(!insn_match_find_next(fw,is,7,match_bl_blximm)) {
1471  return 0;
1472  }
1473  uint32_t sleeptask=get_saved_sig_val("SleepTask");
1474  if(!sleeptask) {
1475  printf("sig_match_physw_misc: missing SleepTask\n");
1476  return 0;
1477  }
1479 
1480  // call wasn't direct, check for veneer
1481  if(f != sleeptask) {
1482  fw_disasm_iter_single(fw,f);
1483  uint32_t f2=get_direct_jump_target(fw,fw->is);
1484  if(f2 != sleeptask) {
1485  return 0;
1486  }
1487  // sleeptask veneer is useful for xref
1488  // re-adding existing won't hurt
1489  save_sig_with_j(fw,"SleepTask",f);
1490  }
1491  // rewind 1 for r0
1492  disasm_iter_init(fw,is,adr_hist_get(&is->ah,1));
1493  if(!disasm_iter(fw,is)) {
1494  printf("sig_match_physw_misc: disasm failed\n");
1495  return 0;
1496  }
1497  // TODO could check base is same reg physw_run was loaded into
1498  if(is->insn->id != ARM_INS_LDR
1499  || is->insn->detail->arm.operands[0].reg != ARM_REG_R0) {
1500  return 0;
1501  }
1502  save_misc_val("physw_sleep_delay",physw_run,is->insn->detail->arm.operands[1].mem.disp,(uint32_t)is->insn->address);
1503  // skip over sleeptask to next insn
1504  if(!disasm_iter(fw,is)) {
1505  printf("sig_match_physw_misc: disasm failed\n");
1506  return 0;
1507  }
1508 
1509  // look for kbd_p1_f
1510  if(!insn_match_find_next(fw,is,2,match_bl_blximm)) {
1511  return 0;
1512  }
1513  save_sig(fw,"kbd_p1_f",get_branch_call_insn_target(fw,is));
1514 
1515  // look for kbd_p2_f
1516  if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
1517  return 0;
1518  }
1519  save_sig(fw,"kbd_p2_f",get_branch_call_insn_target(fw,is));
1520  return 1;
1521 }
int sig_match_pow_dry_52 ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2207 der Datei finsig_thumb2.c.

2208 {
2209  if (fw->dryos_ver != 52) {
2210  return 0;
2211  }
2212  if(!init_disasm_sig_ref(fw,is,rule)) {
2213  return 0;
2214  }
2215  const insn_match_t match_ldrd_r0_r1[]={
2217  {ARM_INS_ENDING}
2218  };
2219  // skip forward to first ldrd r0, r1, [r...]
2220  if(!insn_match_find_next(fw,is,50,match_ldrd_r0_r1)) {
2221  return 0;
2222  }
2223  // prevent false positive
2224  if(is->insn->detail->arm.operands[2].mem.base == ARM_REG_SP) {
2225  return 0;
2226  }
2227  if(!disasm_iter(fw,is)) {
2228  printf("sig_match_pow: disasm failed\n");
2229  return 0;
2230  }
2232  if(!adr) {
2233  return 0;
2234  }
2235  return save_sig_with_j(fw,rule->name,adr);
2236 }
int sig_match_pow_dry_gt_52 ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2239 der Datei finsig_thumb2.c.

2240 {
2241  if (fw->dryos_ver <= 52) {
2242  return 0;
2243  }
2244  if(!init_disasm_sig_ref(fw,is,rule)) {
2245  return 0;
2246  }
2247  const insn_match_t match1a[]={
2248  {MATCH_INS(LDRSH, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM(SP,INVALID,0x12)}},
2249  {MATCH_INS(LDRD, 3), {MATCH_OP_REG(R2), MATCH_OP_REG(R3), MATCH_OP_MEM(SP,INVALID,0x20)}},
2250  {MATCH_INS(STR, 2), {MATCH_OP_REG_ANY, MATCH_OP_MEM(SP,INVALID,0)}},
2252  {ARM_INS_ENDING}
2253  };
2254  const insn_match_t match1b[]={
2255  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R2), MATCH_OP_REG(R7)}},
2256  {MATCH_INS(LDRSH, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM(SP,INVALID,0x12)}},
2257  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R3), MATCH_OP_REG(R6)}},
2258  {MATCH_INS(STR, 2), {MATCH_OP_REG_ANY, MATCH_OP_MEM(SP,INVALID,0)}},
2260  {ARM_INS_ENDING}
2261  };
2262  const insn_match_t* match1[]={ match1a, match1b };
2263  int idx;
2264  for (idx = 0; idx < 2; idx += 1)
2265  {
2266  // match above sequence
2267  if(insn_match_find_next_seq(fw,is,50,match1[idx]))
2268  break;
2269  init_disasm_sig_ref(fw,is,rule);
2270  }
2271  // check for match
2272  if (idx >= 2)
2273  return 0;
2274  // match above sequence
2276  if(!adr) {
2277  return 0;
2278  }
2279  // follow bl
2280  disasm_iter_init(fw,is,adr);
2281  const insn_match_t match2a[]={
2283  {MATCH_INS(BLX, 1), {MATCH_OP_IMM_ANY}},
2284  {ARM_INS_ENDING}
2285  };
2286  const insn_match_t match2b[]={
2287  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R2), MATCH_OP_REG(R0)}},
2288  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R3), MATCH_OP_REG(R1)}},
2289  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R4), MATCH_OP_IMM(0x40000000)}},
2290  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM(0)}},
2291  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R1), MATCH_OP_REG(R4)}},
2292  {MATCH_INS(BL, 1), {MATCH_OP_IMM_ANY}},
2293  {ARM_INS_ENDING}
2294  };
2295  const insn_match_t* match2[]={ match2a, match2b };
2296  // match above sequence
2297  if(!insn_match_find_next_seq(fw,is,15,match2[idx])) {
2298  return 0;
2299  }
2300  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2301 }
int sig_match_prepdir_0 ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2555 der Datei finsig_thumb2.c.

2556 {
2557  if(!init_disasm_sig_ref(fw,is,rule)) {
2558  return 0;
2559  }
2560  uint32_t ref_pdx=get_saved_sig_val("PrepareDirectory_x");
2561  if(!ref_pdx) {
2562  printf("sig_match_prepdir_0: missing PrepareDirectory_x\n");
2563  return 0;
2564  }
2565  // skip over, assume validated previously
2566  disasm_iter(fw,is);
2567  disasm_iter(fw,is);
2568  // this should be the start address of our function
2569  uint32_t adr=(uint32_t)is->adr|is->thumb;
2570  const insn_match_t match_mov_r1_1[]={
2571  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R1), MATCH_OP_IMM(0)}},
2572 #if CS_API_MAJOR < 4
2573  {MATCH_INS(MOVS, 2), {MATCH_OP_REG(R1), MATCH_OP_IMM(0)}},
2574 #endif
2575  {ARM_INS_ENDING}
2576  };
2577  if(!insn_match_find_next(fw,is,1,match_mov_r1_1)) {
2578  //printf("sig_match_prepdir_0: no match mov\n");
2579  return 0;
2580  }
2581  if(!insn_match_find_next(fw,is,1,match_b)) {
2582  //printf("sig_match_prepdir_0: no match b\n");
2583  return 0;
2584  }
2586  if(pdx != ref_pdx) {
2587  //printf("sig_match_prepdir_0: target 0x%08x != 0x%08x\n",pdx,ref_pdx);
2588  return 0;
2589  }
2590  return save_sig_with_j(fw,rule->name,adr);
2591 }
int sig_match_prepdir_1 ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2527 der Datei finsig_thumb2.c.

2528 {
2529  uint32_t call_adr = find_call_near_str(fw,is,rule);
2530  if(call_adr) {
2531  disasm_iter_init(fw,is,call_adr);
2532  disasm_iter(fw,is);
2533  disasm_iter(fw,is);
2534  if (!CBx_target(fw,is->insn))
2535  {
2536  rule->param = SIG_NEAR_BEFORE(20,5);
2537  call_adr = find_call_near_str(fw,is,rule);
2538  if(!call_adr) {
2539  return 0;
2540  }
2541  disasm_iter_init(fw,is,call_adr);
2542  disasm_iter(fw,is);
2543  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2544  }
2545  }
2546 
2547  rule->param = SIG_NEAR_BEFORE(7,2);
2548  call_adr = find_call_near_str(fw,is,rule);
2549  if(!call_adr) {
2550  return 0;
2551  }
2552  return save_sig_match_call(fw, rule, call_adr);
2553 }
int sig_match_prepdir_x ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2501 der Datei finsig_thumb2.c.

2502 {
2503  if(!init_disasm_sig_ref(fw,is,rule)) {
2504  return 0;
2505  }
2506  const insn_match_t match_mov_r1_1[]={
2507  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R1), MATCH_OP_IMM(1)}},
2508 #if CS_API_MAJOR < 4
2509  {MATCH_INS(MOVS, 2), {MATCH_OP_REG(R1), MATCH_OP_IMM(1)}},
2510 #endif
2511  {ARM_INS_ENDING}
2512  };
2513  if(!insn_match_find_next(fw,is,1,match_mov_r1_1)) {
2514  //printf("sig_match_prepdir_x: no match mov\n");
2515  return 0;
2516  }
2517  if(!insn_match_find_next(fw,is,1,match_b)) {
2518  //printf("sig_match_prepdir_x: no match b\n");
2519  return 0;
2520  }
2521  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2522 }
int sig_match_prop_string ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 4318 der Datei finsig_thumb2.c.

4319 {
4320  uint32_t call_adr = find_call_near_str(fw, is, rule);
4321 
4322  if (call_adr == 0)
4323  return 0;
4324 
4325  // initialize to found address
4326  disasm_iter_init(fw,is,call_adr);
4327  disasm_iter(fw,is);
4328 
4329  uint32_t myreg;
4330 
4331  if (is_sig_call(fw,is,"GetPropertyCase")) {
4332  // looking for r0
4333  myreg = 0;
4334  }
4335  else {
4336  // semaphore version of GetPropertyCase, looking for r1
4337  myreg = 1;
4338  }
4339 
4340  // re-init 'is' to current address minus at least 8 insts
4341  const int hl = 8;
4342  disasm_iter_init(fw,is,call_adr - hl*4);
4343  // history needs to be made
4344  while (is->adr < call_adr) {
4345  if (!disasm_iter(fw,is))
4346  disasm_iter_init(fw,is,(is->adr | is->thumb)+2);
4347  }
4348  uint32_t regs[4];
4349  // get r0 or r1, backtracking up to 8 instructions
4350  if ((get_call_const_args(fw,is,hl,regs)&(1<<myreg))==(1<<myreg)) {
4351  add_prop_hit(rule->name,(int)regs[myreg]);
4352  return 1;
4353  }
4354  return 0;
4355 }
int sig_match_qsort ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2657 der Datei finsig_thumb2.c.

2658 {
2659  if(!init_disasm_sig_ref(fw,is,rule)) {
2660  return 0;
2661  }
2662  if(!find_next_sig_call(fw,is,90,"DebugAssert")) {
2663  // printf("sig_match_qsort: no DebugAssert\n");
2664  return 0;
2665  }
2666  if(!insn_match_find_nth(fw,is,38,3,match_bl_blximm)) {
2667  // printf("sig_match_qsort: no match bl\n");
2668  return 0;
2669  }
2670  // follow
2672  // if call in first 4 insn, follow again (newer cams have an extra sub)
2673  if(insn_match_find_next(fw,is,4,match_bl_blximm)) {
2675  }
2676  if(!insn_match_find_next(fw,is,14,match_bl_blximm)) {
2677  // printf("sig_match_qsort: no match bl (qsort)\n");
2678  return 0;
2679  }
2680  // sanity check, expect r1-r3 to be const
2681  uint32_t regs[4];
2682  if((get_call_const_args(fw,is,5,regs)&0xe)!=0xe) {
2683  // printf("sig_match_qsort: failed to get args\n");
2684  return 0;
2685  }
2686  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2687 }
int sig_match_readfastdir ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1957 der Datei finsig_thumb2.c.

1958 {
1959  uint32_t str_adr;
1960  str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
1961  if(!str_adr) {
1962  printf("sig_match_readfastdir: %s failed to find re