CHDK_DE Vorschauversion  Trunk Rev. 6014
 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 SIG_STRCALL_ARG_MASK   0x3
 
#define SIG_STRCALL_ARG(arg_num)   (arg_num)
 
#define SIG_STRCALL_TYPE_MASK   0xc
 
#define SIG_STRCALL_TYPE_SHIFT   2
 
#define SIG_STRCALL_CALL_IMM   0
 
#define SIG_STRCALL_JMP_REG   4
 
#define SIG_STRCALL_CALL_REG   8
 
#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 FIND_SIG_CALL_NO_UNK_VENEER   1
 
#define SIG_DRY_MIN(min_rel)   (min_rel)*FW_DRYOS_VER_MUL,0
 
#define SIG_DRY_MAX(max_rel)   0,(max_rel)*FW_DRYOS_VER_MUL+(FW_DRYOS_VER_MUL-1)
 
#define SIG_DRY_RANGE(min_rel, max_rel)
 
#define SIG_DRY_MINP(min_rel, min_patch)   (min_rel)*FW_DRYOS_VER_MUL + (min_patch),0
 
#define SIG_DRY_MAXP(max_rel, max_patch)   0,(max_rel)*FW_DRYOS_VER_MUL + (max_patch)
 
#define SIG_DRY_RANGEP(min_rel, min_patch, max_rel, max_patch)
 
#define SIG_DRY_ANY   0,0
 
#define SIG_NO_D6   1
 
#define SIG_NO_D7   2
 
#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 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)
 
uint32_t save_sig_veneers (firmware *fw, const char *name, uint32_t adr)
 
int save_sig_with_j (firmware *fw, char *name, uint32_t adr)
 
int find_next_sig_call_ex (firmware *fw, iter_state_t *is, uint32_t max_offset, const char *name, uint32_t flags)
 
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)
 
uint32_t find_str_arg_call (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, __attribute__((unused)) 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_createtaskstrictly_alt (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_createtask_alt (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_get_current_deltasv (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_fclose_low (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_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_57 (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_init_error_handlers (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_default_assert_handler (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_default_exception_handler (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_default_panic_handler (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_get_task_properties (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 (__attribute__((unused)) firmware *fw, __attribute__((unused)) iter_state_t *is, sig_rule_t *rule)
 
int sig_match_dry_memset (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_dry_memzero (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_dry_memcpy_bytes (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_cam_has_iris_diaphragm (__attribute__((unused)) firmware *fw, __attribute__((unused)) 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_umalloc_strictly (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_dcache_clean_flush_and_disable (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_get_rom_id (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_dcache_flush_and_enable (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_icache_flush_range (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_ui_mem_func_ptr (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_func_ptr_val (firmware *fw, __attribute__((unused)) 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_live_free_cluster_count (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_debug_logging_ptr (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_debug_logging_flag (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_mzrm_sendmsg_ret_adr (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_fw_yuv_layer_buf_52 (firmware *fw, iter_state_t *is, sig_rule_t *rule)
 
int sig_match_fw_yuv_layer_buf_gt52 (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_str_arg_call (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)
 
int 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)
 
int sig_rule_applies (firmware *fw, 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, __attribute__((unused)) uint32_t unused)
 
int process_eventproc_table_call (firmware *fw, iter_state_t *is, __attribute__((unused)) uint32_t unused)
 
int process_createtask_call (firmware *fw, iter_state_t *is, __attribute__((unused)) 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, __attribute__((unused)) 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, __attribute__((unused)) 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 89 der Datei finsig_thumb2.c.

#define BAD_MATCH   0x08

Definiert in Zeile 85 der Datei finsig_thumb2.c.

#define DONT_EXPORT   0x01

Definiert in Zeile 82 der Datei finsig_thumb2.c.

#define DONT_EXPORT_ILC   0x100

Definiert in Zeile 90 der Datei finsig_thumb2.c.

#define EV_MATCH   0x10

Definiert in Zeile 86 der Datei finsig_thumb2.c.

#define FIND_SIG_CALL_NO_UNK_VENEER   1

Definiert in Zeile 908 der Datei finsig_thumb2.c.

#define KNOWN_PROPSET_COUNT   (13-5)

Definiert in Zeile 548 der Datei finsig_thumb2.c.

#define LIST_ALWAYS   0x20

Definiert in Zeile 87 der Datei finsig_thumb2.c.

#define MAX_GENERIC_FUNCS   16

Definiert in Zeile 6106 der Datei finsig_thumb2.c.

#define MAX_SIG_ENTRY   5000

Definiert in Zeile 100 der Datei finsig_thumb2.c.

#define MISC_BLOB_TYPE_NONE   0

Definiert in Zeile 584 der Datei finsig_thumb2.c.

#define MISC_BLOB_TYPE_OMAR   2

Definiert in Zeile 586 der Datei finsig_thumb2.c.

#define MISC_BLOB_TYPE_XTENSA   1

Definiert in Zeile 585 der Datei finsig_thumb2.c.

#define MISC_BLOB_XTENSA_MAX   5

Definiert in Zeile 583 der Datei finsig_thumb2.c.

#define MISC_VAL_DEF_CONST   2

Definiert in Zeile 597 der Datei finsig_thumb2.c.

#define MISC_VAL_NO_STUB   1

Definiert in Zeile 595 der Datei finsig_thumb2.c.

#define MISC_VAL_OPTIONAL   4

Definiert in Zeile 598 der Datei finsig_thumb2.c.

#define OPTIONAL   0x02

Definiert in Zeile 83 der Datei finsig_thumb2.c.

#define SEARCH_NEAR_REF_RANGE   1024

Definiert in Zeile 19 der Datei finsig_thumb2.c.

#define SIG_DRY_ANY   0,0

Definiert in Zeile 998 der Datei finsig_thumb2.c.

#define SIG_DRY_MAX (   max_rel)    0,(max_rel)*FW_DRYOS_VER_MUL+(FW_DRYOS_VER_MUL-1)

Definiert in Zeile 988 der Datei finsig_thumb2.c.

#define SIG_DRY_MAXP (   max_rel,
  max_patch 
)    0,(max_rel)*FW_DRYOS_VER_MUL + (max_patch)

Definiert in Zeile 993 der Datei finsig_thumb2.c.

#define SIG_DRY_MIN (   min_rel)    (min_rel)*FW_DRYOS_VER_MUL,0

Definiert in Zeile 987 der Datei finsig_thumb2.c.

#define SIG_DRY_MINP (   min_rel,
  min_patch 
)    (min_rel)*FW_DRYOS_VER_MUL + (min_patch),0

Definiert in Zeile 992 der Datei finsig_thumb2.c.

#define SIG_DRY_RANGE (   min_rel,
  max_rel 
)
Wert:

Definiert in Zeile 989 der Datei finsig_thumb2.c.

#define SIG_DRY_RANGEP (   min_rel,
  min_patch,
  max_rel,
  max_patch 
)
Wert:
(min_rel)*FW_DRYOS_VER_MUL + (min_patch), \
(max_rel)*FW_DRYOS_VER_MUL + (max_patch)

Definiert in Zeile 994 der Datei finsig_thumb2.c.

#define SIG_NAMED_ASIS   0x00000000

Definiert in Zeile 5238 der Datei finsig_thumb2.c.

#define SIG_NAMED_CLEARTHUMB   0x00000010

Definiert in Zeile 5247 der Datei finsig_thumb2.c.

#define SIG_NAMED_FLAG_MASK   0x000000F0

Definiert in Zeile 5248 der Datei finsig_thumb2.c.

#define SIG_NAMED_INSN   0x00000003

Definiert in Zeile 5244 der Datei finsig_thumb2.c.

#define SIG_NAMED_JMP_SUB   0x00000001

Definiert in Zeile 5240 der Datei finsig_thumb2.c.

#define SIG_NAMED_LAST_MAX_MASK   0x00000FFF

Definiert in Zeile 5210 der Datei finsig_thumb2.c.

#define SIG_NAMED_LAST_MIN_MASK   0x00FFF000

Definiert in Zeile 5211 der Datei finsig_thumb2.c.

#define SIG_NAMED_LAST_MIN_SHIFT   12

Definiert in Zeile 5212 der Datei finsig_thumb2.c.

#define SIG_NAMED_LAST_RANGE (   min,
  max 
)
Wert:

Definiert in Zeile 5213 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 5259 der Datei finsig_thumb2.c.

#define SIG_NAMED_NTH_MASK   0x00000F00

Definiert in Zeile 5250 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 5261 der Datei finsig_thumb2.c.

#define SIG_NAMED_NTH_RANGE_MASK   0x0003F000

Definiert in Zeile 5255 der Datei finsig_thumb2.c.

#define SIG_NAMED_NTH_RANGE_SHIFT   12

Definiert in Zeile 5256 der Datei finsig_thumb2.c.

#define SIG_NAMED_NTH_SHIFT   8

Definiert in Zeile 5251 der Datei finsig_thumb2.c.

#define SIG_NAMED_SUB   0x00000002

Definiert in Zeile 5242 der Datei finsig_thumb2.c.

#define SIG_NAMED_TYPE_MASK   0x0000000F

Definiert in Zeile 5245 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 SIG_NO_D6   1

Definiert in Zeile 1001 der Datei finsig_thumb2.c.

#define SIG_NO_D7   2

Definiert in Zeile 1002 der Datei finsig_thumb2.c.

#define SIG_STRCALL_ARG (   arg_num)    (arg_num)

Definiert in Zeile 32 der Datei finsig_thumb2.c.

#define SIG_STRCALL_ARG_MASK   0x3

Definiert in Zeile 31 der Datei finsig_thumb2.c.

#define SIG_STRCALL_CALL_IMM   0

Definiert in Zeile 35 der Datei finsig_thumb2.c.

#define SIG_STRCALL_CALL_REG   8

Definiert in Zeile 37 der Datei finsig_thumb2.c.

#define SIG_STRCALL_JMP_REG   4

Definiert in Zeile 36 der Datei finsig_thumb2.c.

#define SIG_STRCALL_TYPE_MASK   0xc

Definiert in Zeile 33 der Datei finsig_thumb2.c.

#define SIG_STRCALL_TYPE_SHIFT   2

Definiert in Zeile 34 der Datei finsig_thumb2.c.

#define UNUSED   0x04

Definiert in Zeile 84 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 1005 der Datei finsig_thumb2.c.

typedef struct sig_rule_s sig_rule_t

Definiert in Zeile 1004 der Datei finsig_thumb2.c.

Dokumentation der Funktionen

void add_blankline ( )

Definiert in Zeile 61 der Datei finsig_thumb2.c.

62 {
63  if (strcmp(hdr_buf+hdr_len-2,"\n\n") != 0)
64  {
65  hdr_buf[hdr_len++] = '\n';
66  hdr_buf[hdr_len] = 0;
67  }
68 }
void add_event_proc ( firmware fw,
char *  name,
uint32_t  adr 
)

Definiert in Zeile 5811 der Datei finsig_thumb2.c.

5812 {
5813  // TODO - no ARM eventprocs seen so far, warn
5814  if(!ADR_IS_THUMB(adr)) {
5815  printf("add_event_proc: %s is ARM 0x%08x\n",name,adr);
5816  }
5817  // attempt to disassemble target
5818  if(!fw_disasm_iter_single(fw,adr)) {
5819  printf("add_event_proc: %s disassembly failed at 0x%08x\n",name,adr);
5820  return;
5821  }
5822  // handle functions that immediately jump
5823  // only one level of jump for now, doesn't check for conditionals, but first insn shouldn't be conditional
5824  //uint32_t b_adr=B_target(fw,fw->is->insn);
5825  uint32_t b_adr=get_direct_jump_target(fw,fw->is);
5826  if(b_adr) {
5827  char *buf=malloc(strlen(name)+6);
5828  sprintf(buf,"j_%s_FW",name);
5829  add_func_name(fw,buf,adr,NULL); // this is the orignal named address
5830 // adr=b_adr | fw->is->thumb; // thumb bit from iter state
5831  adr=b_adr; // thumb bit already handled by get_direct...
5832  }
5833  add_func_name(fw,name,adr,"_FW");
5834 }
void add_func_name ( firmware fw,
char *  n,
uint32_t  eadr,
char *  suffix 
)

Definiert in Zeile 807 der Datei finsig_thumb2.c.

808 {
809  int k;
810 
811  char *s = n;
812  int mallocd = 0;
813  if (suffix != 0)
814  {
815  s = malloc(strlen(n) + strlen(suffix) + 1);
816  sprintf(s, "%s%s", n, suffix);
817  mallocd = 1;
818  }
819 
820  // if we end up needed these, can add a flag
821  if(!adr_is_main_fw_code(fw,eadr)) {
822  printf("save_sig: refusing to save %s with out of range address 0x%08x\n",s,eadr);
823  if(mallocd) {
824  free(s);
825  }
826  return;
827  }
828 
829  for (k=0; sig_names[k].name != 0; k++)
830  {
831  if (strcmp(sig_names[k].name, s) == 0)
832  {
833  if (sig_names[k].val == 0) // same name, no address
834  {
835  sig_names[k].val = eadr;
836  sig_names[k].flags |= EV_MATCH;
837  if (mallocd)
838  free(s);
839  return;
840  }
841  else if (sig_names[k].val == eadr) // same name, same address
842  {
843  if (mallocd)
844  free(s);
845  return;
846  }
847  else // same name, different address
848  {
849  printf("add_func_name: duplicate name %s existing 0x%08x != new 0x%08x\n",s, sig_names[k].val, eadr);
850  }
851  }
852  }
853 
857  next_sig_entry++;
859 }
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 6087 der Datei finsig_thumb2.c.

6092 {
6093  if(*match_fn_count >= max_funcs-1) {
6094  printf("add_generic_func_match: ERROR max_funcs %d reached\n",max_funcs);
6095  match_fns[max_funcs-1].adr=0;
6096  match_fns[max_funcs-1].fn=NULL;
6097  return 0;
6098  }
6099  match_fns[*match_fn_count].adr=adr;
6100  match_fns[*match_fn_count].fn=fn;
6101  (*match_fn_count)++;
6102  match_fns[*match_fn_count].adr=0;
6103  match_fns[*match_fn_count].fn=NULL;
6104  return 1;
6105 }
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 6107 der Datei finsig_thumb2.c.

6111 {
6112  uint32_t adr=get_saved_sig_val(name);
6113  if(!adr) {
6114  printf("add_generic_sig_match: missing %s\n",name);
6115  return;
6116  }
6117  add_generic_func_match(match_fns,match_fn_count,MAX_GENERIC_FUNCS,fn,adr);
6118  char veneer[128];
6119  sprintf(veneer,"j_%s",name);
6120  adr=get_saved_sig_val(veneer);
6121  if(adr) {
6122  add_generic_func_match(match_fns,match_fn_count,MAX_GENERIC_FUNCS,fn,adr);
6123  }
6124 }
void add_kinfo ( int  r,
uint32_t  b,
const char *  nm,
uint32_t  adr,
uint32_t  ev,
int  inv 
)

Definiert in Zeile 6682 der Datei finsig_thumb2.c.

6683 {
6684  key_info[kcount].reg = r;
6685  key_info[kcount].bits = b;
6686  strcpy(key_info[kcount].nm, nm);
6687  key_info[kcount].fadr = adr;
6688  key_info[kcount].ev = ev;
6689  key_info[kcount].inv = inv;
6690  kcount++;
6691  kmask[r] |= b;
6692  if ((ev <= 1) && (b < kshutter_min_bits)) kshutter_min_bits = b;
6693 }
uint32_t add_kmval ( firmware fw,
uint32_t  tadr,
__attribute__((unused)) int  tsiz,
int  tlen,
uint32_t  ev,
const char *  name,
uint32_t  xtra 
)

Definiert in Zeile 6695 der Datei finsig_thumb2.c.

6696 {
6697  uint32_t adr=find_physw_table_entry(fw,tadr,tlen,ev);
6698  if(!adr) {
6699  return 0;
6700  }
6702  get_physw_table_entry(fw,adr,&v);
6703 
6704  add_kinfo(v.reg,v.bit|xtra,name,adr,v.ev,(v.no_invert)?0:1);
6705  return v.bit;
6706 }
void add_prop_hit ( char *  name,
int  id 
)

Definiert in Zeile 571 der Datei finsig_thumb2.c.

572 {
573  int n = 0;
574  while (knownprops[n].name) {
575  if (strcmp(knownprops[n].name,name) == 0) {
576  knownprops[n].id = id;
577  break;
578  }
579  n++;
580  }
581 }
void bprintf ( char *  fmt,
  ... 
)

Definiert in Zeile 48 der Datei finsig_thumb2.c.

49 {
50  va_list argp;
51  va_start(argp, fmt);
52 
53  if (out_hdr)
54  hdr_len += vsprintf(hdr_buf+hdr_len,fmt,argp);
55  else
56  out_len += vsprintf(out_buf+out_len,fmt,argp);
57 
58  va_end(argp);
59 }
int compare_func_addresses ( const sig_entry_t **  p1,
const sig_entry_t **  p2 
)

Definiert in Zeile 7003 der Datei finsig_thumb2.c.

7004 {
7005  if ((*p1)->val < (*p2)->val)
7006  return -1;
7007  else if ((*p1)->val > (*p2)->val)
7008  return 1;
7009  return compare_sig_names(p1,p2);
7010 }
int compare_sig_names ( const sig_entry_t **  p1,
const sig_entry_t **  p2 
)

Definiert in Zeile 6988 der Datei finsig_thumb2.c.

6989 {
6990  int rv = strcasecmp((*p1)->name, (*p2)->name); // Case insensitive
6991  if (rv != 0)
6992  return rv;
6993  rv = strcmp((*p1)->name, (*p2)->name); // Case sensitive (if equal with insensitive test)
6994  if (rv != 0)
6995  return rv;
6996  if ((*p1)->val < (*p2)->val)
6997  return -1;
6998  else if ((*p1)->val > (*p2)->val)
6999  return 1;
7000  return 0;
7001 }
void do_km_vals ( firmware fw,
uint32_t  tadr,
int  tsiz,
int  tlen 
)

Definiert in Zeile 6779 der Datei finsig_thumb2.c.

6780 {
6781  uint32_t key_half = add_kmval(fw,tadr,tsiz,tlen,0,"KEY_SHOOT_HALF",0);
6782  add_kmval(fw,tadr,tsiz,tlen,1,"KEY_SHOOT_FULL",key_half);
6783  add_kmval(fw,tadr,tsiz,tlen,1,"KEY_SHOOT_FULL_ONLY",0);
6784 
6785  add_kmval(fw,tadr,tsiz,tlen,0x101,"KEY_PLAYBACK",0);
6786  add_kmval(fw,tadr,tsiz,tlen,0x100,"KEY_POWER",0);
6787 
6788  // mostly copied from finsig_dryos, with < r52 stuff removed
6789  if (fw->dryos_ver == 52) // unclear if this applies any other ver
6790  {
6791  add_kmval(fw,tadr,tsiz,tlen,3,"KEY_ZOOM_IN",0);
6792  add_kmval(fw,tadr,tsiz,tlen,4,"KEY_ZOOM_OUT",0);
6793  add_kmval(fw,tadr,tsiz,tlen,6,"KEY_UP",0);
6794  add_kmval(fw,tadr,tsiz,tlen,7,"KEY_DOWN",0);
6795  add_kmval(fw,tadr,tsiz,tlen,8,"KEY_LEFT",0);
6796  add_kmval(fw,tadr,tsiz,tlen,9,"KEY_RIGHT",0);
6797  add_kmval(fw,tadr,tsiz,tlen,0xA,"KEY_SET",0);
6798  add_kmval(fw,tadr,tsiz,tlen,0xB,"KEY_MENU",0);
6799  add_kmval(fw,tadr,tsiz,tlen,0xC,"KEY_DISPLAY",0);
6800  add_kmval(fw,tadr,tsiz,tlen,0x12,"KEY_HELP",0);
6801  add_kmval(fw,tadr,tsiz,tlen,0x19,"KEY_ERASE",0);
6802  add_kmval(fw,tadr,tsiz,tlen,2,"KEY_VIDEO",0);
6803 // add_kmval(fw,tadr,tsiz,tlen,18,"KEY_SHORTCUT",0);
6804  }
6805  else if (fw->dryos_ver < 54)
6806  {
6807  add_kmval(fw,tadr,tsiz,tlen,2,"KEY_ZOOM_IN",0);
6808  add_kmval(fw,tadr,tsiz,tlen,3,"KEY_ZOOM_OUT",0);
6809  add_kmval(fw,tadr,tsiz,tlen,4,"KEY_UP",0);
6810  add_kmval(fw,tadr,tsiz,tlen,5,"KEY_DOWN",0);
6811  add_kmval(fw,tadr,tsiz,tlen,6,"KEY_LEFT",0);
6812  add_kmval(fw,tadr,tsiz,tlen,7,"KEY_RIGHT",0);
6813  add_kmval(fw,tadr,tsiz,tlen,8,"KEY_SET",0);
6814  add_kmval(fw,tadr,tsiz,tlen,9,"KEY_MENU",0);
6815  add_kmval(fw,tadr,tsiz,tlen,0xA,"KEY_DISPLAY",0);
6816  }
6817  else if (fw->dryos_ver < 55)
6818  {
6819  add_kmval(fw,tadr,tsiz,tlen,3,"KEY_ZOOM_IN",0);
6820  add_kmval(fw,tadr,tsiz,tlen,4,"KEY_ZOOM_OUT",0);
6821  add_kmval(fw,tadr,tsiz,tlen,6,"KEY_UP",0);
6822  add_kmval(fw,tadr,tsiz,tlen,7,"KEY_DOWN",0);
6823  add_kmval(fw,tadr,tsiz,tlen,8,"KEY_LEFT",0);
6824  add_kmval(fw,tadr,tsiz,tlen,9,"KEY_RIGHT",0);
6825  add_kmval(fw,tadr,tsiz,tlen,0xA,"KEY_SET",0);
6826  add_kmval(fw,tadr,tsiz,tlen,0xE,"KEY_MENU",0);
6827  add_kmval(fw,tadr,tsiz,tlen,2,"KEY_VIDEO",0);
6828  add_kmval(fw,tadr,tsiz,tlen,0xD,"KEY_DISPLAY",0);
6829  add_kmval(fw,tadr,tsiz,tlen,0x103,"KEY_WIFI",0);
6830 // framing assist / shortuct
6831 // add_kmval(fw,tadr,tsiz,tlen,0xF,"KEY_",0);
6832  }
6833  else if (fw->dryos_ver < 59)
6834  {
6835  add_kmval(fw,tadr,tsiz,tlen,3,"KEY_ZOOM_IN",0);
6836  add_kmval(fw,tadr,tsiz,tlen,4,"KEY_ZOOM_OUT",0);
6837  add_kmval(fw,tadr,tsiz,tlen,6,"KEY_UP",0);
6838  add_kmval(fw,tadr,tsiz,tlen,7,"KEY_DOWN",0);
6839  add_kmval(fw,tadr,tsiz,tlen,8,"KEY_LEFT",0);
6840  add_kmval(fw,tadr,tsiz,tlen,9,"KEY_RIGHT",0);
6841  add_kmval(fw,tadr,tsiz,tlen,0xA,"KEY_SET",0);
6842  add_kmval(fw,tadr,tsiz,tlen,0x14,"KEY_MENU",0);
6843  add_kmval(fw,tadr,tsiz,tlen,2,"KEY_VIDEO",0);
6844  add_kmval(fw,tadr,tsiz,tlen,0xD,"KEY_DISPLAY",0);
6845  add_kmval(fw,tadr,tsiz,tlen,0x103,"KEY_WIFI",0);
6846 // framing assist, shortcut
6847 // add_kmval(fw,tadr,tsiz,tlen,0xF,"KEY_",0);
6848  }
6849  else
6850  {
6851  add_kmval(fw,tadr,tsiz,tlen,3,"KEY_ZOOM_IN",0);
6852  add_kmval(fw,tadr,tsiz,tlen,4,"KEY_ZOOM_OUT",0);
6853  add_kmval(fw,tadr,tsiz,tlen,6,"KEY_UP",0);
6854  add_kmval(fw,tadr,tsiz,tlen,7,"KEY_DOWN",0);
6855  add_kmval(fw,tadr,tsiz,tlen,8,"KEY_LEFT",0);
6856  add_kmval(fw,tadr,tsiz,tlen,9,"KEY_RIGHT",0);
6857  add_kmval(fw,tadr,tsiz,tlen,0xA,"KEY_SET",0);
6858  add_kmval(fw,tadr,tsiz,tlen,0x15,"KEY_MENU",0);
6859  add_kmval(fw,tadr,tsiz,tlen,2,"KEY_VIDEO",0);
6860  add_kmval(fw,tadr,tsiz,tlen,0xB,"KEY_ERASE",0); // also framing assist etc
6861  add_kmval(fw,tadr,tsiz,tlen,0x103,"KEY_WIFI",0);
6862  }
6863 
6864  bprintf("\n// Keymap values for kbd.c. Additional keys may be present, only common values included here.\n");
6865  bprintf("// WARNING: Key name / function may vary! Values for unknown DryOS versions should not be trusted!\n");
6866  print_kmvals();
6867 }
uint32_t find_call_near_str ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 5023 der Datei finsig_thumb2.c.

5024 {
5025  uint32_t str_adr;
5026  if(rule->param & SIG_NEAR_INDIRECT) {
5027  str_adr = find_str_bytes(fw,rule->ref_name); // indirect string could be in data area
5028  } else {
5029  str_adr = find_str_bytes_main_fw(fw,rule->ref_name); // direct string must be near actual code
5030  }
5031  if(!str_adr) {
5032  printf("find_call_near_str: %s failed to find ref %s\n",rule->name,rule->ref_name);
5033  return 0;
5034  }
5035  uint32_t search_adr = str_adr;
5036  // looking for ref to ptr to string, not ref to string
5037  // TODO only looks for first ptr
5038  if(rule->param & SIG_NEAR_INDIRECT) {
5039  // printf("find_call_near_str: %s str 0x%08x\n",rule->name,str_adr);
5041  if(!search_adr) {
5042  printf("find_call_near_str: %s failed to find indirect ref %s\n",rule->name,rule->ref_name);
5043  return 0;
5044  }
5045  // printf("find_call_near_str: %s indirect 0x%08x\n",rule->name,search_adr);
5046  }
5047  const insn_match_t *insn_match;
5048  if(rule->param & SIG_NEAR_JMP_SUB) {
5049  insn_match = match_b_bl_blximm;
5050  } else {
5051  insn_match = match_bl_blximm;
5052  }
5053 
5054  int max_insns=rule->param&SIG_NEAR_OFFSET_MASK;
5056  //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");
5057  // TODO should handle multiple instances of string
5058  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
5059  while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,search_adr+SEARCH_NEAR_REF_RANGE)) {
5060  // bactrack looking for preceding call
5061  if(rule->param & SIG_NEAR_REV) {
5062  int i;
5063  int n_calls=0;
5064  for(i=1; i<=max_insns; i++) {
5066  if(insn_match_any(fw->is->insn,insn_match)) {
5067  n_calls++;
5068  }
5069  if(n_calls == n) {
5070  return iter_state_adr(fw->is);
5071  }
5072  }
5073  } else {
5074  if(insn_match_find_nth(fw,is,max_insns,n,insn_match)) {
5075  return iter_state_adr(is);
5076  }
5077  }
5078  }
5079  printf("find_call_near_str: no match %s\n",rule->name);
5080  return 0;
5081 }
void find_ctypes ( firmware fw)

Definiert in Zeile 6233 der Datei finsig_thumb2.c.

6234 {
6235  static unsigned char ctypes[] =
6236  {
6237  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x60, 0x60, 0x60, 0x60, 0x20, 0x20,
6238  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
6239  0x48, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
6240  0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
6241  0x10, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 1, 1, 1, 1, 1, 1, 1, 1, 1,
6242  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0x10, 0x10, 0x10, 0x10, 0x10,
6243  0x10, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 2, 2, 2, 2, 2, 2, 2, 2, 2,
6244  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0x10, 0x10, 0x10, 0x10, 0x20
6245  };
6246 
6247  uint32_t ctypes_matches[10];
6248  int match_count = find_bytes_all(fw,ctypes,sizeof(ctypes),fw->base,ctypes_matches,10);
6249  if(!match_count) {
6250  return;
6251  }
6252  if(match_count == 10) {
6253  fprintf(stderr,"WARNING found 10+ ctypes!\n");
6254  }
6255  int i;
6256  int match_i;
6257  uint32_t min_adr = 0xFFFFFFFF;
6258  for(i = 0; i< match_count; i++) {
6259  // ref should easily be in the first 1M
6260  uint32_t maxadr = (fw->rom_code_search_max_adr > fw->base + 0x400000)?fw->base + 0x100000:fw->rom_code_search_max_adr;
6261  uint32_t adr = find_u32_adr_range(fw,ctypes_matches[i],fw->rom_code_search_min_adr,maxadr);
6262  if(adr && adr < min_adr) {
6263  min_adr = adr;
6264  match_i = i;
6265  }
6266  }
6267  if(min_adr == 0xFFFFFFFF) {
6268  fprintf(stderr,"WARNING cytpes pointer not found, defaulting to first\n");
6269  match_i = 0;
6270  }
6271  save_misc_val("ctypes",ctypes_matches[match_i],0,min_adr);
6272 }
void find_exception_handlers ( firmware fw,
iter_state_t is 
)

Definiert in Zeile 6126 der Datei finsig_thumb2.c.

6127 {
6128  uint32_t ex_vec = 0;
6129  // somewhat duplicated from to firmware_load_ng, but it's simple
6130  if (fw->arch_flags & FW_ARCH_FL_VMSA) {
6131  const insn_match_t match_mcr_vbar[]={
6132  // Vector Base Address Register MCR p15, 0, <Rt>, c12, c0, 0 - not present on PMSA
6134  {ARM_INS_ENDING}
6135  };
6136  // reset to main fw start
6137  disasm_iter_init(fw, is, fw->base + fw->main_offs + 12 + fw->thumb_default);
6138  if(!insn_match_find_next(fw,is,4,match_mcr_vbar)) {
6139  return;
6140  }
6141  // back up one
6142  disasm_iter_init(fw, is, adr_hist_get(&is->ah,1));
6143  disasm_iter(fw, is);
6144  // expect ldr to be exception vector address
6145  ex_vec = LDR_PC2val(fw,is->insn);
6146  if(!ex_vec || adr_get_range_type(fw,ex_vec) != ADR_RANGE_ROM) {
6147  return;
6148  }
6149  }
6150  // both d6 and d7 appear to have an ARM instruction in reset, and thumb in the remaining
6151  // which appears contrary to arm documentation (ARM DDI 0406C.c (ID051414)
6152  // On digic 6, Reset appears to be an infinte loop, so must not be expected in any case
6153  disasm_iter_init(fw, is, ex_vec);
6154  disasm_iter(fw, is);
6155 
6156  char *names[]={
6157  "exception_handler_Reset",
6158  "exception_handler_UndefinedInstruction",
6159  "exception_handler_SupervisorCall",
6160  "exception_handler_PrefetchAbort",
6161  "exception_handler_DataAbort",
6162  "exception_handler_NotUsed",
6163  "exception_handler_IRQ",
6164  "exception_handler_FIQ",
6165  };
6166 
6167  uint32_t addr=LDR_PC2val(fw,is->insn);
6168  if(!addr && is->insn->id == ARM_INS_B) {
6169  addr=get_branch_call_insn_target(fw,is);
6170  }
6171  // addr may be 0 (= inf loop at reset vector) but stubs system won't recognize it anyway
6172  if(addr) {
6173  add_func_name(fw,names[0],addr,NULL);
6174  }
6175  disasm_iter_init(fw, is, ADR_SET_THUMB(ex_vec + 4));
6176  int i;
6177  for(i=1; i<8; i++) {
6178  disasm_iter(fw, is);
6179  // all seen so far use a thumb ldr.w pc,...
6180  // "NotUsed" is typically a NOP, which won't get picked up here, but would fall through to IRQ
6181  addr=LDR_PC2val(fw,is->insn);
6182  if(addr) {
6183  add_func_name(fw,names[i],addr,NULL);
6184  }
6185  }
6186 }
void find_generic_funcs ( firmware fw)

Definiert in Zeile 6192 der Datei finsig_thumb2.c.

6192  {
6194 
6195  int match_fn_count=0;
6196 
6197  add_generic_sig_match(match_fns,&match_fn_count,process_reg_eventproc_call,"ExportToEventProcedure_FW");
6198  add_generic_sig_match(match_fns,&match_fn_count,process_reg_eventproc_call,"RegisterEventProcedure_alt1");
6199  add_generic_sig_match(match_fns,&match_fn_count,process_reg_eventproc_call,"RegisterEventProcedure_alt2");
6200  add_generic_sig_match(match_fns,&match_fn_count,process_eventproc_table_call,"RegisterEventProcTable");
6201  add_generic_sig_match(match_fns,&match_fn_count,process_eventproc_table_call,"UnRegisterEventProcTable");
6202  add_generic_sig_match(match_fns,&match_fn_count,process_createtask_call,"CreateTaskStrictly");
6203  if(get_saved_sig_val("CreateTaskStrictly_alt")) {
6204  add_generic_sig_match(match_fns,&match_fn_count,process_createtask_call,"CreateTaskStrictly_alt");
6205  }
6206  add_generic_sig_match(match_fns,&match_fn_count,process_createtask_call,"CreateTask");
6207  if(get_saved_sig_val("CreateTask_alt")) {
6208  add_generic_sig_match(match_fns,&match_fn_count,process_createtask_call,"CreateTask_alt");
6209  }
6210  add_generic_sig_match(match_fns,&match_fn_count,process_eventproc_table_call,"RegisterEventProcTable_alt");
6211  add_generic_sig_match(match_fns,&match_fn_count,process_eventproc_table_call,"UnRegisterEventProcTable_alt");
6212  add_generic_sig_match(match_fns,&match_fn_count,process_add_ptp_handler_call,"add_ptp_handler");
6213 
6214  iter_state_t *is=disasm_iter_new(fw,0);
6215  disasm_iter_init(fw,is,fw->rom_code_search_min_adr | fw->thumb_default); // reset to start of fw
6216  fw_search_insn(fw,is,search_disasm_calls_multi,0,match_fns,0);
6217 
6218  int i;
6219  for(i=0;i<fw->adr_range_count;i++) {
6220  if(fw->adr_ranges[i].type != ADR_RANGE_RAM_CODE) {
6221  continue;
6222  }
6223  disasm_iter_init(fw,is,fw->adr_ranges[i].start | fw->thumb_default); // reset to start of range
6224  // check additional veneers, since regions are small and often need to jump back to ROM
6225  fw_search_insn(fw,is,search_disasm_calls_veneer_multi,0,match_fns,0);
6226  }
6227 
6228  find_exception_handlers(fw,is);
6229 
6230  disasm_iter_free(is);
6231 }
int find_next_sig_call ( firmware fw,
iter_state_t is,
uint32_t  max_offset,
const char *  name 
)

Definiert in Zeile 951 der Datei finsig_thumb2.c.

952 {
953  return find_next_sig_call_ex(fw,is,max_offset,name,0);
954 }
int find_next_sig_call_ex ( firmware fw,
iter_state_t is,
uint32_t  max_offset,
const char *  name,
uint32_t  flags 
)

Definiert in Zeile 911 der Datei finsig_thumb2.c.

912 {
913  uint32_t adr=get_saved_sig_val(name);
914 
915  if(!adr) {
916  printf("find_next_sig_call: missing %s\n",name);
917  return 0;
918  }
919 
920  search_calls_multi_data_t match_fns[12];
921 
922  match_fns[0].adr=adr;
923  match_fns[0].fn=search_calls_multi_end;
924  char veneer[128];
925  int i;
926  for(i = 1; i<11; i++) {
927  // match convention in save_sig_veneers
928  if(i>1) {
929  sprintf(veneer,"j%d_%s",i-1,name);
930  } else {
931  sprintf(veneer,"j_%s",name);
932  }
933  adr=get_saved_sig_val(veneer);
934  if(!adr) {
935  break;
936  } else {
937  match_fns[i].adr=adr;
938  match_fns[i].fn=search_calls_multi_end;
939  }
940  }
941  search_insn_fn search_fn;
942  if(flags & FIND_SIG_CALL_NO_UNK_VENEER) {
943  search_fn = search_disasm_calls_multi;
944  } else {
946  }
947  match_fns[i].adr=0;
948  return fw_search_insn(fw,is,search_fn,0,match_fns,is->adr + max_offset);
949 }
void find_other_stubs_min ( firmware fw)

Definiert in Zeile 7131 der Datei finsig_thumb2.c.

7132 {
7133  int k,k1;
7134 
7135  out_hdr = 1;
7136 
7137  // focus_len_table
7138  if (fw->sv->min_focus_len != 0)
7139  {
7140  int found = 0, pos = 0, len = 0, size = 0;
7141  for (k=0; k<fw->size32; k++)
7142  {
7143  if (fw->buf32[k] == fw->sv->min_focus_len)
7144  {
7145  int mul = 1;
7146  if ((fw->buf32[k+1] == 100) && (fw->buf32[k+2] == 0)) mul = 3;
7147  if ((fw->buf32[k+1] == 100) && (fw->buf32[k+2] != 0)) mul = 2;
7148  if ((fw->buf32[k+1] == 0) && (fw->buf32[k+2] != 0)) mul = 2;
7149  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) ;
7150  if (fw->buf32[k1] == fw->sv->max_focus_len)
7151  {
7152  if ((found == 0) || ((size < mul) && (len < ((k1 - k) / mul) + 1)))
7153  {
7154  found = 1;
7155  pos = k;
7156  len = ((k1 - k) / mul) + 1;
7157  size = mul;
7158  }
7159  }
7160  }
7161  }
7162  if (found == 1)
7163  {
7164  uint32_t adr = fw->base + (pos << 2);
7165  bprintf("// focus_len_table contains zoom focus lengths for use in 'get_focal_length' (main.c).\n");
7166  if (size == 1)
7167  bprintf("// each entry contains 1 int value, which is the the zoom focus length.\n",size);
7168  else
7169  bprintf("// each entry contains %d int value(s), the first is the zoom focus length.\n",size);
7170  bprintf("// there are %d entries in the table - set NUM_FL to %d\n",len,len);
7171  print_other_stubs_min(fw,"focus_len_table",adr,adr);
7172  }
7173  }
7174 }
uint32_t find_physw_table_entry ( firmware fw,
uint32_t  tadr,
int  tcount,
uint32_t  ev 
)

Definiert in Zeile 6608 der Datei finsig_thumb2.c.

6609 {
6610  int i;
6611  for(i=0; i<tcount; i++,tadr += 8) {
6612  if(fw_u32(fw,tadr+4) == ev) {
6613  return tadr;
6614  }
6615  }
6616  return 0;
6617 }
uint32_t find_physw_table_max ( firmware fw,
uint32_t  tadr,
int  max_count 
)

Definiert in Zeile 6619 der Datei finsig_thumb2.c.

6620 {
6621  int i;
6622  for(i=0; i<max_count; i++,tadr += 8) {
6624  get_physw_table_entry(fw,tadr,&v);
6625  if(v.raw_info == 0 || v.raw_info == 0xFFFFFFFF || v.reg > 2) {
6626  return i;
6627  }
6628  // TODO could check that no event numbers (except -1) are repeated
6629  }
6630  return max_count;
6631 }
sig_entry_t* find_saved_sig ( const char *  name)

Definiert in Zeile 726 der Datei finsig_thumb2.c.

727 {
728  int i;
729  for (i=0; sig_names[i].name != 0; i++)
730  {
731  if (strcmp(name,sig_names[i].name) == 0)
732  {
733  return &sig_names[i];
734  }
735  }
736  return NULL;
737 }
uint32_t find_str_arg_call ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 5101 der Datei finsig_thumb2.c.

5102 {
5103  arm_reg reg = ARM_REG_R0 + (rule->param & SIG_STRCALL_ARG_MASK);
5104  int match_type = (rule->param & SIG_STRCALL_TYPE_MASK);
5105  const insn_match_t *match;
5106  if(match_type == SIG_STRCALL_CALL_IMM) {
5107  match = match_bl_blximm;
5108  } else if(match_type == SIG_STRCALL_JMP_REG) {
5109  match = match_bxreg;
5110  } else if(match_type == SIG_STRCALL_CALL_REG) {
5111  match = match_blxreg;
5112  } else {
5113  printf("find_str_arg_call: %s invalid match type %d\n",rule->name,match_type);
5114  return 0;
5115  }
5116 
5117  uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name); // direct string must be near actual code
5118  if(!str_adr) {
5119  printf("find_str_arg_call: %s failed to find ref %s\n",rule->name,rule->ref_name);
5120  return 0;
5121  }
5122 
5123  do {
5124  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
5125  uint32_t call_adr = find_const_ref_match(fw, is, SEARCH_NEAR_REF_RANGE*2, 8, reg, str_adr, match, FIND_CONST_REF_MATCH_ANY);
5126  if(call_adr) {
5127  return call_adr;
5128  }
5129  str_adr = find_next_str_bytes_main_fw(fw,rule->ref_name, str_adr+strlen(rule->ref_name));
5130  } while (str_adr);
5131  printf("find_str_arg_call: no match %s r%d\n",rule->name,reg-ARM_REG_R0);
5132  return 0;
5133 }
misc_val_t* get_misc_val ( const char *  name)

Definiert in Zeile 663 der Datei finsig_thumb2.c.

664 {
666  while(p->name) {
667  if(strcmp(name,p->name) == 0) {
668  return p;
669  }
670  p++;
671  }
672  return NULL;
673 }
uint32_t get_misc_val_value ( const char *  name)

Definiert in Zeile 676 der Datei finsig_thumb2.c.

677 {
678  misc_val_t *p=get_misc_val(name);
679  if(!p) {
680  printf("get_misc_val_value: invalid name %s\n",name);
681  return 0;
682  }
683  return p->val;
684 }
void get_physw_table_entry ( firmware fw,
uint32_t  adr,
physw_table_entry_t vals 
)

Definiert in Zeile 6597 der Datei finsig_thumb2.c.

6598 {
6599  uint32_t info=fw_u32(fw,adr);
6600  vals->raw_info=info;
6601  vals->ev=fw_u32(fw,adr+4);
6602  // taken from finsig_dryos print_physw_raw_vals
6603  vals->reg=(info >>5) & 7;
6604  vals->bit=(1 << (info & 0x1f));
6605  // vals->no_invert=(info >> 16) & 1;
6606  vals->no_invert=((info&0xff0000)==0x10000)?1:0;
6607 }
uint32_t get_saved_sig_val ( const char *  name)

Definiert in Zeile 740 der Datei finsig_thumb2.c.

741 {
742  sig_entry_t *sig=find_saved_sig(name);
743  if(!sig) {
744  // printf("get_saved_sig_val: missing %s\n",name);
745  return 0;
746  }
747  return sig->val;
748 }
int init_disasm_sig_ref ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1018 der Datei finsig_thumb2.c.

1019 {
1020  if(!rule->ref_name) {
1021  printf("init_disasm_sig_ref: %s missing ref_name\n",rule->name);
1022  return 0;
1023  }
1024  uint32_t adr=get_saved_sig_val(rule->ref_name);
1025  if(!adr) {
1026  printf("init_disasm_sig_ref: %s missing %s\n",rule->name,rule->ref_name);
1027  return 0;
1028  }
1029  if(!disasm_iter_init(fw,is,adr)) {
1030  printf("init_disasm_sig_ref: %s bad address 0x%08x for %s\n",rule->name,adr,rule->ref_name);
1031  return 0;
1032  }
1033  return 1;
1034 }
int is_immediate_ret_sub ( firmware fw,
iter_state_t is_init 
)

Definiert in Zeile 5185 der Datei finsig_thumb2.c.

5186 {
5187  fw_disasm_iter_single(fw,is_init->adr | is_init->thumb);
5188  const insn_match_t match_mov_r0_imm[]={
5189  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM_ANY}},
5190 #if CS_API_MAJOR < 4
5191  {MATCH_INS(MOVS, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM_ANY}},
5192 #endif
5193  {ARM_INS_ENDING}
5194  };
5195  // if it's a MOV, check if next is ret
5196  if(insn_match_any(fw->is->insn,match_mov_r0_imm)) {
5197  fw_disasm_iter(fw);
5198  }
5199  if(isRETx(fw->is->insn)) {
5200  return 1;
5201  }
5202  return 0;
5203 }
int is_sig_call ( firmware fw,
iter_state_t is,
const char *  name 
)

Definiert in Zeile 958 der Datei finsig_thumb2.c.

959 {
961  // not a call at all
962  // TODO could check if unknown veneer
963  if(!adr) {
964  return 0;
965  }
966  uint32_t sig_adr=get_saved_sig_val(name);
967  osig* ostub2 = find_sig(fw->sv->stubs,name);
968  if (ostub2 && ostub2->val)
969  sig_adr = ostub2->val;
970  if(!sig_adr) {
971  printf("is_sig_call: missing %s\n",name);
972  return 0;
973  }
974  if(adr == sig_adr) {
975  return 1;
976  }
977  char veneer[128];
978  sprintf(veneer,"j_%s",name);
979  sig_adr=get_saved_sig_val(veneer);
980  if(!sig_adr) {
981  return 0;
982  }
983  return (adr == sig_adr);
984 }
int kinfo_compare ( const kinfo p1,
const kinfo p2 
)

Definiert in Zeile 6708 der Datei finsig_thumb2.c.

6709 {
6710  if (p1->reg > p2->reg)
6711  {
6712  return 1;
6713  }
6714  else if (p1->reg < p2->reg)
6715  {
6716  return -1;
6717  }
6718  if ((p1->ev <= 1) && (p2->ev <= 1)) // output shutter entries in reverse order
6719  {
6720  if (p1->bits > p2->bits)
6721  {
6722  return -1;
6723  }
6724  else if (p1->bits < p2->bits)
6725  {
6726  return 1;
6727  }
6728  }
6729  // if one entry is shutter then compare to min shutter bits
6730  if (p1->ev <= 1)
6731  {
6732  if (kshutter_min_bits > p2->bits)
6733  {
6734  return 1;
6735  }
6736  else if (kshutter_min_bits < p2->bits)
6737  {
6738  return -1;
6739  }
6740  }
6741  if (p2->ev <= 1)
6742  {
6743  if (p1->bits > kshutter_min_bits)
6744  {
6745  return 1;
6746  }
6747  else if (p1->bits < kshutter_min_bits)
6748  {
6749  return -1;
6750  }
6751  }
6752  if (p1->bits > p2->bits)
6753  {
6754  return 1;
6755  }
6756  else if (p1->bits < p2->bits)
6757  {
6758  return -1;
6759  }
6760 
6761  return 0;
6762 }
int main ( int  argc,
char **  argv 
)

Definiert in Zeile 7301 der Datei finsig_thumb2.c.

7302 {
7303  clock_t t1 = clock();
7304 
7305  firmware fw;
7306  memset(&fw,0,sizeof(firmware));
7307  if (argc < 4) {
7308  fprintf(stderr,"finsig_thumb2 <primary> <base> <outputfilename>\n");
7309  exit(1);
7310  }
7311 
7313  int max_find_sig = next_sig_entry;
7314 
7315  fw.sv = new_stub_values();
7316  load_stubs(fw.sv, "stubs_entry_2.S", 1);
7317  load_stubs_min(fw.sv);
7318  load_modemap(fw.sv);
7319  load_platform(fw.sv);
7320 
7321  bprintf("// !!! THIS FILE IS GENERATED. DO NOT EDIT. !!!\n");
7322  bprintf("#include \"stubs_asm.h\"\n\n");
7323 
7324  firmware_load(&fw,argv[1],strtoul(argv[2], NULL, 0),FW_ARCH_ARMv7);
7325  if(!firmware_init_capstone(&fw)) {
7326  exit(1);
7327  }
7329 
7330  out_fp = fopen(argv[3],"w");
7331  if (out_fp == NULL) {
7332  fprintf(stderr,"Error opening output file %s\n",argv[3]);
7333  exit(1);
7334  }
7335 
7336 
7337  // find ctypes - previously separate from regular sig matches to set code search limit
7338  find_ctypes(&fw);
7339 
7341  find_generic_funcs(&fw);
7343 
7344  output_firmware_vals(&fw);
7345 
7346  output_platform_vals(&fw);
7347  output_physw_vals(&fw);
7348  output_modemap(&fw);
7349 
7350  output_propcases(&fw);
7351  output_exmem_types(&fw);
7352 
7353  write_stubs(&fw,max_find_sig);
7354 
7355  write_output();
7356  fclose(out_fp);
7357 
7358  write_func_lists(&fw);
7359 
7360  firmware_unload(&fw);
7361 
7362  clock_t t2 = clock();
7363 
7364  printf("Time to generate stubs %.2f seconds\n",(double)(t2-t1)/(double)CLOCKS_PER_SEC);
7365 
7366  return 0;
7367 }
void output_exmem_types ( firmware fw)

Definiert in Zeile 6551 der Datei finsig_thumb2.c.

6552 {
6553 
6554  misc_val_t *ett=get_misc_val("exmem_types_table");
6555  misc_val_t *etc=get_misc_val("exmem_type_count");
6556  if (ett->val == 0 || etc->val == 0) {
6557  return;
6558  }
6559  bprintf("// EXMEM types:\n");
6560  uint32_t n;
6561  for (n=0; n<etc->val; n++) {
6562  char *extyp = (char*)adr2ptr(fw, fw_u32(fw,ett->val+n*4));
6563  bprintf("// %s %i\n", extyp, n);
6564  }
6565  add_blankline();
6566 }
void output_firmware_vals ( firmware fw)

Definiert in Zeile 6296 der Datei finsig_thumb2.c.

6297 {
6298  bprintf("// Camera info:\n");
6299  bprintf("// Main firmware start: 0x%08x\n",fw->base+fw->main_offs);
6300  if (fw->dryos_ver == 0)
6301  {
6302  bprintf("// Can't find DRYOS version !!!\n\n");
6303  } else {
6304  bprintf("// DRYOS R%d (%s) @ 0x%08x ref @ 0x%08x\n",
6305  fw->dryos_ver,
6306  fw->dryos_ver_str,
6307  fw->dryos_ver_adr,
6308  fw->dryos_ver_ref_adr);
6309  }
6310  if (fw->firmware_ver_str == 0)
6311  {
6312  bprintf("// Can't find firmware version !!!\n\n");
6313  }
6314  else
6315  {
6316  char *c = strrchr(fw->firmware_ver_str,' ') + 1; // points after the last space char
6317  uint32_t j = ptr2adr(fw,(uint8_t *)fw->firmware_ver_str);
6318  uint32_t k = j + c - fw->firmware_ver_str;
6319  if ( (k>=j) && (k<j+32) )
6320  {
6321  bprintf("// %s // Found @ 0x%08x, \"%s\" @ 0x%08x\n",fw->firmware_ver_str,j,c,k);
6322  }
6323  else
6324  {
6325  // no space found in string (shouldn't happen)
6326  bprintf("// %s // Found @ 0x%08x, \"%s\" @ 0x%08x\n",fw->firmware_ver_str,j,fw->firmware_ver_str,j);
6327  }
6328  }
6329  if (fw->arch_flags & FW_ARCH_FL_VMSA) {
6330  bprintf("// VMSA detected, probably digic >= 7\n");
6331  }
6332 
6333  bprintf("\n// Values for makefile.inc\n");
6334  bprintf("// PLATFORMOSVER = %d\n",fw->dryos_ver);
6335  if (fw->arch_flags & FW_ARCH_FL_VMSA) {
6336  bprintf("// DIGIC = 70\n");
6337  } else {
6338  // 6+ exists, but not for known powershot firmware cams
6339  bprintf("// DIGIC = 60\n");
6340  }
6341 
6342  if (fw->memisostart) {
6343  bprintf("// MEMISOSTART = 0x%x\n",fw->memisostart);
6344  } else {
6345  bprintf("// MEMISOSTART not found !!!\n");
6346  }
6347  if (fw->data_init_start)
6348  {
6349  bprintf("// MEMBASEADDR = 0x%x\n",fw->data_start);
6350  }
6351  print_misc_val_makefile("ARAM_HEAP_START");
6352  print_misc_val_makefile("ARAM_HEAP_SIZE");
6353 
6354  bprintf("\n// Detected address ranges:\n");
6355  int i;
6356  for(i=0; i<fw->adr_range_count; i++) {
6357  if(fw->adr_ranges[i].type == ADR_RANGE_ROM) {
6358  bprintf("// %-8s 0x%08x - 0x%08x (%7d bytes)\n",
6359  adr_range_desc_str(&fw->adr_ranges[i]),
6360  fw->adr_ranges[i].start,
6361  fw->adr_ranges[i].start+fw->adr_ranges[i].bytes,
6362  fw->adr_ranges[i].bytes);
6363  } else {
6364  bprintf("// %-8s 0x%08x - 0x%08x copied from 0x%08x (%7d bytes)\n",
6365  adr_range_desc_str(&fw->adr_ranges[i]),
6366  fw->adr_ranges[i].start,
6367  fw->adr_ranges[i].start+fw->adr_ranges[i].bytes,
6368  fw->adr_ranges[i].src_start,
6369  fw->adr_ranges[i].bytes);
6370  }
6371  }
6372  misc_val_t *mv=get_misc_val("zicokick_values");
6373  if(mv->blobs) {
6374  bprintf("\n// Zico Xtensa blobs:\n");
6375  for(i=0;mv->blobs[i].type != MISC_BLOB_TYPE_NONE;i++) {
6376  bprintf("// zico_%d 0x%08x - 0x%08x copied from 0x%08x (%7d bytes)\n",
6377  i,
6378  mv->blobs[i].ram_adr,
6379  mv->blobs[i].ram_adr+mv->blobs[i].size,
6380  mv->blobs[i].rom_adr,
6381  mv->blobs[i].size);
6382  }
6383 
6384  }
6385  mv=get_misc_val("omar_init_values");
6386  if(mv->blobs) {
6387  bprintf("\n// Omar ARM blobs:\n");
6388  for(i=0;mv->blobs[i].type != MISC_BLOB_TYPE_NONE;i++) {
6389  bprintf("// omar_%d 0x%08x - 0x%08x copied from 0x%08x (%7d bytes)\n",
6390  i,
6391  mv->blobs[i].ram_adr,
6392  mv->blobs[i].ram_adr+mv->blobs[i].size,
6393  mv->blobs[i].rom_adr,
6394  mv->blobs[i].size);
6395  }
6396  }
6397  if(fw->dryos_ver_count) {
6398  bprintf("\n// Found DryOS versions:\n");
6399  for(i=0;i<(int)fw->dryos_ver_count;i++) {
6400  bprintf("// 0x%08x %s \"%s\"\n",
6401  fw->dryos_ver_list[i], (fw->dryos_ver_list[i] == fw->dryos_ver_adr) ? "main ":"other",
6402  (char *)adr2ptr(fw,fw->dryos_ver_list[i]));
6403  }
6404  add_blankline();
6405  }
6406  add_blankline();
6407 
6408  // check if CreateTask is in ROM, offer CreateTask_low if it's in RAM
6409  sig_entry_t * ct = find_saved_sig("hook_CreateTask");
6410  if(ct && adr_get_range_type(fw,ct->val) != ADR_RANGE_RAM_CODE) {
6411  bprintf("// CreateTask is not in RAM code\n");
6412  ct->flags |= UNUSED;
6413  sig_entry_t * ctl = find_saved_sig("CreateTask_low");
6414  if(ctl && adr_get_range_type(fw,ctl->val) == ADR_RANGE_RAM_CODE) {
6415  bprintf("// use hook_CreateTask_low instead\n");
6416  ctl->flags &= ~UNUSED;
6417  sig_entry_t * hctl = find_saved_sig("hook_CreateTask_low");
6418  hctl->flags &= ~UNUSED;
6419  }
6420  add_blankline();
6421  }
6422 }
void output_modemap ( firmware fw)

Definiert in Zeile 6934 der Datei finsig_thumb2.c.

6934  {
6935  print_misc_val_comment("canon_mode_list");
6936  bprintf("// Check modemap values from 'platform/CAMERA/shooting.c':\n");
6937  misc_val_t *mv=get_misc_val("canon_mode_list");
6938  if(!mv) {
6939  add_blankline();
6940  return;
6941  }
6942  int i;
6943  uint32_t adr=mv->val;
6944  int bad=0;
6945  for(i=0; i<50; i++,adr+=2) {
6946  uint16_t *pv=(uint16_t*)adr2ptr(fw,adr);
6947  if(!pv) {
6948  break;
6949  }
6950  if(*pv==0xFFFF) {
6951  break;
6952  }
6953  osig *m = find_sig_val(fw->sv->modemap, *pv);
6954  if (!m) {
6955  bprintf("// %5hu 0x%04hx In firmware but not in current modemap",*pv,*pv);
6956  /*
6957  char *s = mode_name(*pv);
6958  if (strcmp(s,"") != 0) {
6959  bprintf(" (%s)",s);
6960  }
6961  */
6962  bprintf("\n");
6963  bad++;
6964  } else {
6965 // bprintf("// %5hu 0x%04hx %s\n", *pv,*pv,m->nm);
6966  m->pct = 100;
6967  }
6968  }
6969  osig *m = fw->sv->modemap;
6970  while (m)
6971  {
6972  if (m->pct != 100) // not matched above?
6973  {
6974  bprintf("// Current modemap entry not found in firmware - %-24s %5d\n",m->nm,m->val);
6975  bad++;
6976  }
6977  m = m->nxt;
6978  }
6979  if (bad == 0)
6980  {
6981  bprintf("// No problems found with modemap table.\n");
6982  }
6983 
6984  add_blankline();
6985 }
void output_physw_vals ( firmware fw)

Definiert in Zeile 6868 der Datei finsig_thumb2.c.

6868  {
6869  print_misc_val_comment("physw_event_table");
6870  uint32_t physw_tbl=get_misc_val_value("physw_event_table");
6871  if(!physw_tbl) {
6872  return;
6873  }
6874  int physw_tbl_len=find_physw_table_max(fw,physw_tbl,50);
6875  write_physw_event_table_dump(fw,physw_tbl,physw_tbl_len);
6876 
6877  bprintf("// Values below go in 'platform_kbd.h':\n");
6878  if (fw->dryos_ver >= 58)
6879  {
6880  // Event ID's have changed in DryOS 58 **********
6881  print_kval(fw,physw_tbl,physw_tbl_len,0x30A,"SD_READONLY","_FLAG");
6882  print_kval(fw,physw_tbl,physw_tbl_len,0x302,"USB","_MASK");
6883  print_kval(fw,physw_tbl,physw_tbl_len,0x305,"BATTCOVER","_FLAG");
6884  print_kval(fw,physw_tbl,physw_tbl_len,0x304,"HOTSHOE","_FLAG");
6885  print_kval(fw,physw_tbl,physw_tbl_len,0x300,"ANALOG_AV","_FLAG");
6886  }
6887  else
6888  {
6889  print_kval(fw,physw_tbl,physw_tbl_len,0x20A,"SD_READONLY","_FLAG");
6890  print_kval(fw,physw_tbl,physw_tbl_len,0x202,"USB","_MASK");
6891  print_kval(fw,physw_tbl,physw_tbl_len,0x205,"BATTCOVER","_FLAG");
6892  print_kval(fw,physw_tbl,physw_tbl_len,0x204,"HOTSHOE","_FLAG");
6893  print_kval(fw,physw_tbl,physw_tbl_len,0x200,"ANALOG_AV","_FLAG");
6894  }
6895  do_km_vals(fw,physw_tbl,2,physw_tbl_len);
6896 
6897  add_blankline();
6898 }
void output_platform_vals ( firmware fw)

Definiert in Zeile 6434 der Datei finsig_thumb2.c.

6434  {
6435  bprintf("// Values below go in 'platform_camera.h':\n");
6436  bprintf("//#define CAM_DRYOS 1\n");
6437  if (fw->dryos_ver >= 39)
6438  bprintf("//#define CAM_DRYOS_2_3_R39 1 // Defined for cameras with DryOS version R39 or higher\n");
6439  if (fw->dryos_ver >= 47)
6440  bprintf("//#define CAM_DRYOS_2_3_R47 1 // Defined for cameras with DryOS version R47 or higher\n");
6441  if (fw->dryos_ver >= 59)
6442  bprintf("//#define CAM_DRYOS_2_3_R59 1 // Defined for cameras with DryOS version R59 or higher\n");
6443 
6444  if(get_misc_val_value("CAM_IS_ILC")) {
6445  bprintf("//#define CAM_ILC 1 // Camera is interchangeable lens\n");
6446  }
6447 
6448  if(get_misc_val_value("CAM_HAS_WIFI")) {
6449  bprintf("//#define CAM_HAS_WIFI 1 // Firmware has wifi support (only define if camera has hardware)\n");
6450  }
6451 
6452 
6453  print_platform_misc_val_undef("CAM_UNCACHED_BIT",0x10000000);
6454 
6455  if(get_misc_val_value("CAM_HAS_ND_FILTER")) {
6456  bprintf("//#define CAM_HAS_ND_FILTER 1 // Camera has ND filter\n");
6457  } else {
6458  bprintf("//#undef CAM_HAS_ND_FILTER // Camera does not have an ND filter\n");
6459  }
6460  if(get_misc_val_value("CAM_HAS_IRIS_DIAPHRAGM")) {
6461  bprintf("// Camera has an iris (CAM_HAS_IRIS_DIAPHRAGM default)\n");
6462  } else {
6463  bprintf("//#undef CAM_HAS_IRIS_DIAPHRAGM // Camera does not have an iris\n");
6464  }
6465 
6466  add_blankline();
6467 }
void output_propcases ( firmware fw)

Definiert in Zeile 6469 der Datei finsig_thumb2.c.

6469  {
6470 
6471  uint32_t used=0;
6473  const uint32_t ps_offset = 6;
6474 
6475  memset(hits, 0, KNOWN_PROPSET_COUNT*sizeof(uint32_t));
6476 
6477  bprintf("// Known propcases\n");
6478 
6479  int n = 0;
6480  while (knownprops[n].name) {
6481  used += knownprops[n].use>0?1:0;
6482  if (knownprops[n].id >= 0)
6483  {
6484  if (knownprops[n].use)
6485  {
6486  if (knownprops[n].id == knownprops[n].id_ps6) hits[6-ps_offset] += 1;
6487  if (knownprops[n].id == knownprops[n].id_ps7) hits[7-ps_offset] += 1;
6488  if (knownprops[n].id == knownprops[n].id_ps8) hits[8-ps_offset] += 1;
6489  if (knownprops[n].id == knownprops[n].id_ps9) hits[9-ps_offset] += 1;
6490  if (knownprops[n].id == knownprops[n].id_ps10) hits[10-ps_offset] += 1;
6491  if (knownprops[n].id == knownprops[n].id_ps11) hits[11-ps_offset] += 1;
6492  if (knownprops[n].id == knownprops[n].id_ps12) hits[12-ps_offset] += 1;
6493  if (knownprops[n].id == knownprops[n].id_ps13) hits[13-ps_offset] += 1;
6494  }
6495  if (knownprops[n].use == 1)
6496  {
6497  bprintf("// #define %s %i\n", knownprops[n].name, knownprops[n].id);
6498  }
6499  else
6500  {
6501  // propcases not used by CHDK, name may be made up
6502  bprintf("// // %s %i\n", knownprops[n].name, knownprops[n].id);
6503  }
6504  }
6505  else
6506  {
6507  bprintf("// %s not found\n", knownprops[n].name);
6508  }
6509  n++;
6510  }
6511 
6512  bprintf("// Guessed propset: ");
6513  int m = 0;
6514  uint32_t fmax = 0;
6515  int okay = 0;
6516  for (n=0; n<KNOWN_PROPSET_COUNT; n++)
6517  {
6518  if (hits[n] == used)
6519  {
6520  if (m) bprintf(", ");
6521  bprintf("%i", n+ps_offset);
6522  if (fw->sv->propset == n+ps_offset) okay = 1; // if the propset equals to (one of) the complete propset matches
6523  m += 1;
6524  }
6525  if (hits[n] > fmax) fmax = hits[n];
6526  }
6527  if (m == 0)
6528  {
6529  bprintf("uncertain (%i of %u match), closest to ",fmax,used);
6530  for (n=0; n<KNOWN_PROPSET_COUNT; n++)
6531  {
6532  if (hits[n] == fmax)
6533  {
6534  if (m) bprintf(", ");
6535  bprintf("%i", n+ps_offset);
6536  if (fw->sv->propset == n+ps_offset) okay = 1; // if the propset equals to (one of) the most complete propset matches
6537  m += 1;
6538  }
6539  }
6540  }
6541  bprintf("\n");
6542  if (!okay && fw->sv->propset>0)
6543  {
6544  // only shown when there's a clear mismatch
6545  bprintf("// Port's propset (%i) may be set incorrectly\n", fw->sv->propset);
6546  }
6547 
6548  add_blankline();
6549 }
void print_kmvals ( )

Definiert in Zeile 6764 der Datei finsig_thumb2.c.

6765 {
6766  qsort(key_info, kcount, sizeof(kinfo), (void*)kinfo_compare);
6767 
6768  bprintf("//KeyMap keymap[] = {\n");
6769 
6770  int k;
6771  for (k=0; k<kcount; k++)
6772  {
6773  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)");
6774  }
6775 
6776  bprintf("// { 0, 0, 0 }\n//};\n");
6777 }
void print_kval ( firmware fw,
uint32_t  tadr,
int  tcount,
uint32_t  ev,
const char *  name,
const char *  sfx 
)

Definiert in Zeile 6649 der Datei finsig_thumb2.c.

6650 {
6651  uint32_t adr=find_physw_table_entry(fw,tadr,tcount,ev);
6652  if(!adr) {
6653  return;
6654  }
6656  get_physw_table_entry(fw,adr,&v);
6657 
6658  char fn[100], rn[100];
6659  strcpy(fn,name); strcat(fn,sfx);
6660  strcpy(rn,name); strcat(rn,"_IDX");
6661 
6662  bprintf("//#define %-20s0x%08x // Found @0x%08x, levent 0x%x%s\n",fn,v.bit,adr,v.ev,v.no_invert?" (non-inverted logic)":"");
6663  bprintf("//#define %-20s%d\n",rn,v.reg);
6664 
6665 }
void print_misc_val_comment ( const char *  name)

Definiert in Zeile 6568 der Datei finsig_thumb2.c.

6569 {
6570  misc_val_t *mv=get_misc_val(name);
6571  if(!mv) {
6572  return;
6573  }
6574  // TODO legitimate 0 values might be possible, if so can add found bit
6575  if(!mv->val) {
6576  bprintf("// %s not found\n",name);
6577  return;
6578  }
6579  bprintf("// %s 0x%08x",name,mv->val);
6580  if(mv->offset) {
6581  bprintf(" (0x%x+0x%x)",mv->base,mv->offset);
6582  }
6583  if(mv->ref_adr) {
6584  bprintf(" Found @0x%08x",mv->ref_adr);
6585  }
6586  bprintf("\n");
6587 }
void print_misc_val_makefile ( const char *  name)

Definiert in Zeile 6274 der Datei finsig_thumb2.c.

6275 {
6276  misc_val_t *mv=get_misc_val(name);
6277  if(!mv) {
6278  return;
6279  }
6280  // TODO legitimate 0 values might be possible, if so can add found bit
6281  if(!mv->val) {
6282  bprintf("// %s not found\n",name);
6283  return;
6284  }
6285  bprintf("// %s = 0x%08x# ",name,mv->val);
6286  if(mv->offset) {
6287  bprintf(" (0x%x+0x%x)",mv->base,mv->offset);
6288  }
6289  if(mv->ref_adr) {
6290  bprintf(" Found @0x%08x",mv->ref_adr);
6291  }
6292  bprintf("\n");
6293 }
void print_other_stubs_min ( firmware fw,
const char *  name,
uint32_t  fadr,
uint32_t  atadr 
)

Definiert in Zeile 7056 der Datei finsig_thumb2.c.

7057 {
7058  osig *o = find_sig(fw->sv->stubs_min,name);
7059  if (o)
7060  {
7061  bprintf("//DEF(%-40s,0x%08x) // Found @0x%08x",name,fadr,atadr);
7062  if (fadr != o->val)
7063  {
7064  bprintf(", ** != ** stubs_min = 0x%08x (%s)",o->val,o->sval);
7065  }
7066  else
7067  {
7068  bprintf(", stubs_min = 0x%08x (%s)",o->val,o->sval);
7069  }
7070  }
7071  else
7072  {
7073  bprintf("DEF(%-40s,0x%08x) // Found @0x%08x",name,fadr,atadr);
7074  }
7075  bprintf("\n");
7076 }
void print_platform_misc_val_undef ( const char *  name,
uint32_t  def 
)

Definiert in Zeile 6425 der Datei finsig_thumb2.c.

6426 {
6427  misc_val_t *mv=get_misc_val(name);
6428  if(mv && mv->val && mv->val != def) {
6429  bprintf("//#undef %s\n",name);
6430  bprintf("//#define %s 0x%08x // Found @0x%08x\n",name,mv->val,mv->ref_adr);
6431  }
6432 }
void print_results ( firmware fw,
sig_entry_t sig 
)

Definiert in Zeile 7178 der Datei finsig_thumb2.c.

7179 {
7180  int i;
7181  int err = 0;
7182  char line[500] = "";
7183 
7184  if (sig->flags & DONT_EXPORT) {
7185  return;
7186  }
7187 
7188  if ((sig->flags & DONT_EXPORT_ILC) && get_misc_val_value("CAM_IS_ILC")) {
7189  return;
7190  }
7191 
7192  // find best match and report results
7193  osig* ostub2 = find_sig(fw->sv->stubs,sig->name);
7194 
7195  if (ostub2 && (sig->val != ostub2->val))
7196  {
7197  if (ostub2->type != TYPE_IGNORE)
7198  {
7199  err = 1;
7200  sig->flags |= BAD_MATCH;
7201  }
7202  }
7203  else
7204  {
7205  if (sig->flags & UNUSED) return;
7206  }
7207 
7208  // write to header (if error) or body buffer (no error)
7209  out_hdr = err;
7210 
7211  char *macro = "NHSTUB";
7212  if (sig->flags & ARM_STUB) {
7213  macro = "NHSTUB2";
7214  }
7215  if (strncmp(sig->name,"task_",5) == 0 ||
7216  strncmp(sig->name,"hook_",5) == 0) macro = " DEF";
7217 
7218  if (!sig->val && !ostub2)
7219  {
7220  if (sig->flags & OPTIONAL) return;
7221  char fmt[51] = "";
7222  sprintf(fmt, "// ERROR: %%s is not found. %%%ds//--- --- ", (int)(34-strlen(sig->name)));
7223  sprintf(line+strlen(line), fmt, sig->name, "");
7224  }
7225  else
7226  {
7227  if (ostub2 || (sig->flags & UNUSED))
7228  sprintf(line+strlen(line),"//%s(%-37s,0x%08x) //%3d ", macro, sig->name, sig->val, 0);
7229  else
7230  sprintf(line+strlen(line),"%s(%-39s,0x%08x) //%3d ", macro, sig->name, sig->val, 0);
7231 
7232  /*
7233  if (matches->fail > 0)
7234  sprintf(line+strlen(line),"%2d%% ", matches->success*100/(matches->success+matches->fail));
7235  else
7236  */
7237  sprintf(line+strlen(line)," ");
7238  }
7239 
7240  if (ostub2)
7241  {
7242  if (ostub2->type == TYPE_IGNORE)
7243  sprintf(line+strlen(line)," Overridden");
7244  else if (sig->val == ostub2->val)
7245  sprintf(line+strlen(line)," == 0x%08x ",ostub2->val);
7246  else {
7247  // if both have same value check if differs only by veneer
7248  if(sig->val && ostub2->val) {
7249  fw_disasm_iter_single(fw,ostub2->val);
7250  if(get_direct_jump_target(fw,fw->is) == sig->val) {
7251  sprintf(line+strlen(line)," <-veneer 0x%08x ",ostub2->val);
7252  } else {
7253  fw_disasm_iter_single(fw,sig->val);
7254  if(get_direct_jump_target(fw,fw->is) == ostub2->val) {
7255  sprintf(line+strlen(line)," veneer-> 0x%08x ",ostub2->val);
7256  } else {
7257  sprintf(line+strlen(line)," *** != 0x%08x ",ostub2->val);
7258  }
7259  }
7260  } else {
7261  sprintf(line+strlen(line)," *** != 0x%08x ",ostub2->val);
7262  }
7263  }
7264  }
7265  else
7266  sprintf(line+strlen(line)," ");
7267 
7268  for (i=strlen(line)-1; i>=0 && line[i]==' '; i--) line[i] = 0;
7269  bprintf("%s\n",line);
7270 
7271  /*
7272  for (i=1;i<count && matches[i].fail==matches[0].fail;i++)
7273  {
7274  if (matches[i].ptr != matches->ptr)
7275  {
7276  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);
7277  }
7278  }
7279  */
7280 }
void print_stubs_min_def ( firmware fw,
misc_val_t sig 
)

Definiert in Zeile 7078 der Datei finsig_thumb2.c.

7079 {
7080  if(sig->flags & MISC_VAL_NO_STUB) {
7081  return;
7082  }
7083  // find best match and report results
7084  osig* ostub2=find_sig(fw->sv->stubs_min,sig->name);
7085  const char *ostub_src = "stubs_min";
7086 
7087  if(!ostub2) {
7088  ostub2=find_sig(fw->sv->stubs,sig->name);
7089  ostub_src="stubs_entry_2";
7090  }
7091 
7092  const char *macro = "DEF";
7093  if(sig->flags & MISC_VAL_DEF_CONST) {
7094  macro="DEF_CONST";
7095  }
7096 
7097  if (ostub2)
7098  {
7099  bprintf("//%s(%-34s,0x%08x)",macro,sig->name,sig->val);
7100  if (sig->val != ostub2->val)
7101  {
7102  bprintf(", ** != ** %s = 0x%08x (%s)",ostub_src,ostub2->val,ostub2->sval);
7103  }
7104  else
7105  {
7106  bprintf(", %s = 0x%08x (%s)",ostub_src,ostub2->val,ostub2->sval);
7107  }
7108  }
7109  else if(sig->base || sig->offset)
7110  {
7111  bprintf("%s(%-34s,0x%08x)",macro,sig->name,sig->val);
7112  if(sig->offset || sig->ref_adr) {
7113  bprintf(" //");
7114  if(sig->offset) {
7115  bprintf(" (0x%x+0x%x)",sig->base,sig->offset);
7116  }
7117  if(sig->ref_adr) {
7118  bprintf(" Found @0x%08x",sig->ref_adr);
7119  }
7120  }
7121  }
7122  else
7123  {
7124  if (sig->flags & MISC_VAL_OPTIONAL) return;
7125  bprintf("// %s not found",sig->name);
7126  }
7127  bprintf("\n");
7128 }
int process_add_ptp_handler_call ( firmware fw,
iter_state_t is,
__attribute__((unused)) uint32_t  unused 
)

Definiert in Zeile 6014 der Datei finsig_thumb2.c.

6014  {
6015  uint32_t regs[4];
6016  // get r0 (opcode) and r1 (handler), backtracking up to 8 instructions
6017  if((get_call_const_args(fw,is,8,regs)&3)==3) {
6018  //uint32_t op=regs[0];
6019  if(!save_ptp_handler_func(fw,regs[0],regs[1])) {
6020  printf("add_ptp_handler op 0x%08x out of range 0x%"PRIx64"\n",regs[0],is->insn->address);
6021  }
6022  return 0;
6023  } else {
6024  // if above failed, check for opcode table
6025  arm_reg ptr_reg = ARM_REG_INVALID;
6026  int i;
6027  // backtrack until we get to ldrh r0, ...
6028  for(i=1; i<6; i++) {
6030  cs_insn *insn=fw->is->insn;
6031  if(insn->id != ARM_INS_LDRH) {
6032  continue;
6033  }
6034  if(insn->detail->arm.operands[0].reg != ARM_REG_R0
6035  || insn->detail->arm.operands[1].mem.base == ARM_REG_PC
6036  // shift isn't set correctly under capstone 3, not required for current cams
6037  /*|| insn->detail->arm.operands[1].shift.value != 3*/) {
6038  continue;
6039  }
6040  ptr_reg = insn->detail->arm.operands[1].mem.base;
6041  //printf("add_ptp_handler ptr_reg %d at 0x%"PRIx64"\n",ptr_reg,insn->address);
6042  break;
6043  }
6044  // didn't find args or anything that looks like table load
6045  if(ptr_reg == ARM_REG_INVALID) {
6046  printf("failed to get add_ptp_handler args at 0x%"PRIx64"\n",is->insn->address);
6047  return 0;
6048  }
6049  uint32_t op_table=0;
6050  // backtrack looking for LDR into ptr_reg
6051  // starting from previous i
6052  for(; i<20; i++) {
6054  cs_insn *insn=fw->is->insn;
6055  if(!isLDR_PC(insn)) {
6056  continue;
6057  }
6058  if((arm_reg)insn->detail->arm.operands[0].reg != ptr_reg) {
6059  continue;
6060  }
6061  // printf("add_ptp_handler LDR PC 0x%08x at 0x%"PRIx64"\n",LDR_PC2val(fw,insn),insn->address);
6062  uint32_t adr=LDR_PC2val(fw,insn);
6063  // check loaded address points to expected value (OC GetStorageIDs)
6064  if(fw_u32(fw,adr) == 0x1004) {
6065  op_table=adr;
6066  }
6067  break;
6068  }
6069  if(!op_table) {
6070  printf("failed to get ptp handler table adr at 0x%"PRIx64"\n",is->insn->address);
6071  return 0;
6072  }
6073  // TODO canon firmware has count in loop that calls add_ptp_handler,
6074  // but for simplicity just checking for valid opcode with hardcoded max
6075  for(i=0; i<64; i++) {
6076  uint32_t op=fw_u32(fw,op_table+i*8);
6077  uint32_t handler=fw_u32(fw,op_table+i*8+4);
6078  // fails on op out of range
6079  if(!save_ptp_handler_func(fw,op,handler)) {
6080  break;
6081  }
6082  }
6083  return 0;
6084  }
6085 }
int process_createtask_call ( firmware fw,
iter_state_t is,
__attribute__((unused)) uint32_t  unused 
)

Definiert in Zeile 5977 der Datei finsig_thumb2.c.

5977  {
5978  //printf("CreateTask call at %"PRIx64"\n",is->insn->address);
5979  uint32_t regs[4];
5980  // get r0 (name) and r3 (entry), backtracking up to 10 instructions
5981  if((get_call_const_args(fw,is,10,regs)&9)==9) {
5982  if(isASCIIstring(fw,regs[0])) {
5983  // TODO
5984  char *buf=malloc(64);
5985  char *nm=(char *)adr2ptr(fw,regs[0]);
5986  sprintf(buf,"task_%s",nm);
5987  //printf("found %s 0x%08x at 0x%"PRIx64"\n",buf,regs[3],is->insn->address);
5988  add_func_name(fw,buf,regs[3],NULL);
5989  } else {
5990  printf("task name name not string at 0x%"PRIx64"\n",is->insn->address);
5991  }
5992  } else {
5993  printf("failed to get CreateTask args at 0x%"PRIx64"\n",is->insn->address);
5994  }
5995  return 0;
5996 }
int process_eventproc_table_call ( firmware fw,
iter_state_t is,
__attribute__((unused)) uint32_t  unused 
)

Definiert in Zeile 5918 der Datei finsig_thumb2.c.

5918  {
5919  uint32_t regs[4];
5920  int foundr0 = 0;
5921  // get r0, backtracking up to 4 instructions
5922  foundr0 = get_call_const_args(fw,is,4,regs) & 1;
5923  if (!foundr0) {
5924  // case 1: table memcpy'd onto stack
5925  uint32_t ca = iter_state_adr(is);
5926  uint32_t sa = adr_hist_get(&is->ah,2);
5927  uint32_t ta = adr_hist_get(&is->ah,8);
5928  disasm_iter_set(fw,is,ta);
5929  int n = 0;
5930  while(++n<=(8-2))
5931  {
5932  disasm_iter(fw,is);
5933  }
5934  fw_disasm_iter_single(fw,sa);
5935  uint32_t adr1 = get_saved_sig_val("j_dry_memcpy");
5936  uint32_t adr2 = get_branch_call_insn_target(fw,fw->is);
5937  if (fw->is->insn->id == ARM_INS_BLX && adr1 == adr2) {
5938  foundr0 = get_call_const_args(fw,is,8-2,regs) & 2;
5939  if (foundr0) {
5940  regs[0] = regs[1];
5941  // printf("eventproc table case1 0x%x found table 0x%x\n",ca,regs[1]);
5942  }
5943  }
5944  // restore iter address
5945  disasm_iter_init(fw,is,ca);
5946  disasm_iter(fw,is);
5947  }
5948  if(foundr0) {
5949  // include tables in RAM data
5950  uint32_t *p=(uint32_t*)adr2ptr_with_data(fw,regs[0]);
5951  //printf("found eventproc table 0x%08x\n",regs[0]);
5952  // if it was a valid address
5953  if(p) {
5954  while(*p) {
5955  uint32_t nm_adr=*p;
5956  if(!isASCIIstring(fw,nm_adr)) {
5957  printf("eventproc name not string tbl 0x%08x 0x%08x\n",regs[0],nm_adr);
5958  break;
5959  }
5960  char *nm=(char *)adr2ptr(fw,nm_adr);
5961  p++;
5962  uint32_t fn=*p;
5963  p++;
5964  //printf("found %s 0x%08x\n",nm,fn);
5965  add_event_proc(fw,nm,fn);
5966  //add_func_name(fw,nm,fn,NULL);
5967  }
5968  } else {
5969  printf("failed to get *EventProcTable arg 0x%08x at 0x%"PRIx64"\n",regs[0],is->insn->address);
5970  }
5971  } else {
5972  printf("failed to get *EventProcTable r0 at 0x%"PRIx64"\n",is->insn->address);
5973  }
5974  return 0;
5975 }
int process_reg_eventproc_call ( firmware fw,
iter_state_t is,
__attribute__((unused)) uint32_t  unused 
)

Definiert in Zeile 5837 der Datei finsig_thumb2.c.

5837  {
5838  uint32_t regs[4];
5839  // get r0, r1, backtracking up to 4 instructions
5840  if((get_call_const_args(fw,is,4,regs)&3)==3) {
5841  // TODO follow ptr to verify code, pick up underlying functions
5842  if(isASCIIstring(fw,regs[0])) {
5843  char *nm=(char *)adr2ptr(fw,regs[0]);
5844  add_event_proc(fw,nm,regs[1]);
5845  //add_func_name(fw,nm,regs[1],NULL);
5846  //printf("eventproc found %s 0x%08x at 0x%"PRIx64"\n",nm,regs[1],is->insn->address);
5847  } else {
5848  printf("eventproc name not string at 0x%"PRIx64"\n",is->insn->address);
5849  }
5850  } else {
5851  // check for special case: one of the 2 arg eventprocs is used in loop to register a table
5852 
5853  // using the existing 'is' iterator
5854  // first, address is backed up
5855  uint64_t adr = is->insn->address;
5856  uint32_t adr_thumb = is->thumb;
5857  uint32_t tbla = 0;
5858  int ar = -1;
5859  int found = 0;
5860  // go back a 10 instructions
5861  disasm_iter_init(fw,is,adr_hist_get(&is->ah,10));
5862  // search for ldr reg, =address where address is higher in ROM (supposed to be the eventproc table)
5863  while(1) {
5864  if (!disasm_iter(fw,is)) break;
5865  if (is->insn->address >= adr) break;
5866  if (is->insn->id == ARM_INS_LDR && is->insn->detail->arm.operands[1].type == ARM_OP_MEM) {
5867  uint32_t u = LDR_PC2val(fw,is->insn);
5868  if ((u<fw->base+fw->size8) && (u>adr) && (!isASCIIstring(fw,u))) {
5869  ar = is->insn->detail->arm.operands[0].reg;
5870  tbla = u;
5871  break;
5872  }
5873  }
5874  }
5875  // search for found register appearing later in an add instruction
5876  while(ar >= 0) {
5877  if (!disasm_iter(fw,is)) break;
5878  if (is->insn->address >= adr) break;
5879  if (is->insn->id == ARM_INS_ADD && is->insn->detail->arm.operands[1].reg == ar) {
5880  found = 1;
5881  //printf("found loop eventproc table at 0x%"PRIx64"\n",is->insn->address);
5882  break;
5883  }
5884  }
5885  if (found) {
5886  // following is taken from process_eventproc_table_call
5887  uint32_t *p=(uint32_t*)adr2ptr_with_data(fw,tbla);
5888  if(p) {
5889  while(*p) {
5890  uint32_t nm_adr=*p;
5891  // NULL name = end of table
5892  if (!nm_adr) break;
5893  if(!isASCIIstring(fw,nm_adr)) {
5894  printf("eventproc name not string tbl2 0x%08x 0x%08x\n",tbla,nm_adr);
5895  break;
5896  }
5897  char *nm=(char *)adr2ptr(fw,nm_adr);
5898  p++;
5899  uint32_t fn=*p;
5900  p++;
5901  add_event_proc(fw,nm,fn);
5902  }
5903  } else {
5904  printf("eventproc tbl2 not table 0x%08x\n",tbla);
5905  }
5906  }
5907  else {
5908  printf("failed to get export/register eventproc args at 0x%"PRIx64"\n",adr);
5909  }
5910  // restore address in 'is' to avoid infinite loop
5911  disasm_iter_init(fw,is,adr | adr_thumb);
5912  disasm_iter(fw,is);
5913  }
5914  return 0; // always keep looking
5915 }
void run_sig_rules ( firmware fw,
sig_rule_t sig_rules 
)

Definiert in Zeile 5792 der Datei finsig_thumb2.c.

5793 {
5794  sig_rule_t *rule=sig_rules;
5795  // for convenience, pass an iter_state to match fns so they don't have to manage
5796  iter_state_t *is=disasm_iter_new(fw,0);
5797  while(rule->match_fn) {
5798  if(!sig_rule_applies(fw,rule)) {
5799  rule++;
5800  continue;
5801  }
5802 // printf("rule: %s ",rule->name);
5803  //int r=rule->match_fn(fw,is,rule);
5804  rule->match_fn(fw,is,rule);
5805 // printf("%d\n",r);
5806  rule++;
5807  }
5808  disasm_iter_free(is);
5809 }
void save_misc_val ( const char *  name,
uint32_t  base,
uint32_t  offset,
uint32_t  ref_adr 
)

Definiert in Zeile 685 der Datei finsig_thumb2.c.

686 {
687  misc_val_t *p=get_misc_val(name);
688  if(!p) {
689  printf("save_misc_val: invalid name %s\n",name);
690  return;
691  }
692  p->val = base + offset;
693  p->base = base;
694  p->offset = offset;
695  p->ref_adr = ref_adr;
696  p->blobs = NULL;
697 }
void save_misc_val_blobs ( const char *  name,
misc_blob_t blobs,
uint32_t  ref_adr 
)

Definiert in Zeile 698 der Datei finsig_thumb2.c.

699 {
700  misc_val_t *p=get_misc_val(name);
701  if(!p) {
702  printf("save_misc_val: invalid name %s\n",name);
703  return;
704  }
705  p->val = p->base = p->offset = 0;
706  p->ref_adr = ref_adr;
707  p->blobs = blobs;
708 }
int save_ptp_handler_func ( firmware fw,
uint32_t  op,
uint32_t  handler 
)

Definiert in Zeile 5998 der Datei finsig_thumb2.c.

5998  {
5999  if((op >= 0x9000 && op < 0x10000) || (op >= 0x1000 && op < 0x2000)) {
6000  char *buf=malloc(64);
6001  const char *nm=get_ptp_op_name(op);
6002  if(nm) {
6003  sprintf(buf,"handle_%s",nm);
6004  } else {
6005  sprintf(buf,"handle_PTP_OC_0x%04x",op);
6006  }
6007  // TODO Canon sometimes uses the same handler for multiple opcodes
6008  add_func_name(fw,buf,handler,NULL);
6009  } else {
6010  return 0;
6011  }
6012  return 1;
6013 }
void save_sig ( firmware fw,
const char *  name,
uint32_t  val 
)

Definiert in Zeile 788 der Datei finsig_thumb2.c.

789 {
790  sig_entry_t *sig = find_saved_sig(name);
791  if (!sig)
792  {
793  printf("save_sig: refusing to save unknown name %s\n",name);
794  return;
795  }
796  // if we end up needed these, can add a flag
797  if(!adr_is_main_fw_code(fw,val)) {
798  printf("save_sig: refusing to save %s with out of range address 0x%08x\n",name,val);
799  return;
800  }
801  if(sig->val && sig->val != val) {
802  printf("save_sig: duplicate name %s existing 0x%08x != new 0x%08x\n",name,sig->val,val);
803  }
804  sig->val = val;
805 }
int save_sig_match_call ( firmware fw,
sig_rule_t rule,
uint32_t  call_adr 
)

Definiert in Zeile 2145 der Datei finsig_thumb2.c.

2146 {
2147  disasm_iter_init(fw,fw->is,call_adr); // reset to a bit before where the string was found
2148  disasm_iter(fw,fw->is);
2149  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,fw->is));
2150 }
uint32_t save_sig_veneers ( firmware fw,
const char *  name,
uint32_t  adr 
)

Definiert in Zeile 862 der Datei finsig_thumb2.c.

863 {
864  // attempt to disassemble target
865  if(!fw_disasm_iter_single(fw,adr)) {
866  printf("save_sig_veneers: %s disassembly failed at 0x%08x\n",name,adr);
867  return 0;
868  }
869  // handle functions that immediately jump
870  // doesn't check for conditionals, but first insn shouldn't be conditional
871  uint32_t b_adr;
872  int v_cnt;
873  for(v_cnt = 0, b_adr = get_direct_jump_target(fw,fw->is);
874  v_cnt < 10 && b_adr;
875  v_cnt++,b_adr = get_direct_jump_target(fw,fw->is)) {
876  char *buf=malloc(strlen(name)+7);
877  if(v_cnt) {
878  sprintf(buf,"j%d_%s",v_cnt,name);
879  } else { // first level is just j_ for backward compatiblity
880  // TODO could check for existing veeners, allowing for different paths
881  sprintf(buf,"j_%s",name);
882  }
883  add_func_name(fw,buf,adr,NULL); // this is the orignal named address
884  adr=b_adr; // thumb bit already handled by get_direct...
885  if(!fw_disasm_iter_single(fw,adr)) {
886  printf("save_sig_veneers: %s disassembly failed at 0x%08x\n",name,adr);
887  return 0;
888  }
889  }
890  return adr;
891 }
int save_sig_with_j ( firmware fw,
char *  name,
uint32_t  adr 
)

Definiert in Zeile 894 der Datei finsig_thumb2.c.

895 {
896  if(!adr) {
897  printf("save_sig_with_j: %s null adr\n",name);
898  return 0;
899  }
900  adr = save_sig_veneers(fw, name, adr);
901  if(adr) {
902  save_sig(fw,name,adr);
903  return 1;
904  }
905  return 0;
906 }
int sig_match__nrflag ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 4444 der Datei finsig_thumb2.c.

4445 {
4446  if(!init_disasm_sig_ref(fw,is,rule)) {
4447  return 0;
4448  }
4449  uint32_t fadr=is->adr;
4450  // find range check on input arg
4451  const insn_match_t match_cmp_b[]={
4452  {MATCH_INS(CMP, 2), {MATCH_OP_REG(R0),MATCH_OP_IMM_ANY}},
4453  {MATCH_INS(B,MATCH_OPCOUNT_IGNORE)}, // blo or blt may be used, so don't include cond
4454  {ARM_INS_ENDING}
4455  };
4456  if(!insn_match_find_next_seq(fw,is,4,match_cmp_b) || is->insn->detail->arm.cc == ARM_CC_AL) {
4457  printf("sig_match__nrflag: no match CMP\n");
4458  return 0;
4459  }
4460  // follow
4462  if(!disasm_iter(fw,is)) {
4463  printf("sig_match__nrflag: disasm failed\n");
4464  return 0;
4465  }
4466  // assume next is base addres
4467  uint32_t adr=LDR_PC2val(fw,is->insn);
4468  if(!adr) {
4469  printf("sig_match__nrflag: no match LDR PC 0x%"PRIx64"\n",is->insn->address);
4470  return 0;
4471  }
4472  arm_reg reg_base = is->insn->detail->arm.operands[0].reg; // reg value was loaded into
4473  if(!disasm_iter(fw,is)) {
4474  printf("sig_match__nrflag: disasm failed\n");
4475  return 0;
4476  }
4477  // firmware may use add/sub to get actual firmware base address
4478  if(isADDx_imm(is->insn) || isSUBx_imm(is->insn)) {
4479  if((arm_reg)is->insn->detail->arm.operands[0].reg != reg_base) {
4480  printf("sig_match__nrflag: no match ADD/SUB\n");
4481  return 0;
4482  }
4483  if(isADDx_imm(is->insn)) {
4484  adr+=is->insn->detail->arm.operands[1].imm;
4485  } else {
4486  adr-=is->insn->detail->arm.operands[1].imm;
4487  }
4488  if(!disasm_iter(fw,is)) {
4489  printf("sig_match__nrflag: disasm failed\n");
4490  return 0;
4491  }
4492  }
4493  if(is->insn->id != ARM_INS_STR || (arm_reg)is->insn->detail->arm.operands[1].reg != reg_base) {
4494  printf("sig_match__nrflag: no match STR\n");
4495  return 0;
4496  }
4497  uint32_t disp = is->insn->detail->arm.operands[1].mem.disp;
4498  save_misc_val(rule->name,adr,disp,fadr);
4499  return 1;
4500 }
int sig_match_add_ptp_handler ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2818 der Datei finsig_thumb2.c.

2819 {
2820  uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2821  if(!str_adr) {
2822  printf("sig_match_add_ptp_handler: failed to find ref %s\n",rule->ref_name);
2823  return 0;
2824  }
2825  // TODO should handle multiple instances of string
2826  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
2827  while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2828  // expect CreateTaskStrictly
2829  if(!find_next_sig_call(fw,is,8,"CreateTaskStrictly")) {
2830  // printf("sig_match_add_ptp_handler: no CreateTaskStrictly\n");
2831  continue;
2832  }
2833  // expect add_ptp_handler is 3rd call after CreateTask
2834  if(!insn_match_find_nth(fw,is,13,3,match_bl_blximm)) {
2835  // printf("sig_match_add_ptp_handler: no match bl\n");
2836  return 0;
2837  }
2838  // sanity check, expect opcode, func, 0
2839  uint32_t regs[4];
2840  if((get_call_const_args(fw,is,5,regs)&7)!=7) {
2841  // printf("sig_match_add_ptp_handler: failed to get args\n");
2842  return 0;
2843  }
2844  if(regs[0] < 0x9000 || regs[0] > 0x10000 || !adr2ptr(fw,regs[1]) || regs[2] != 0) {
2845  // printf("sig_match_add_ptp_handler: bad args 0x%08x 0x%08x 0x%08x\n",regs[0],regs[1],regs[2]);
2846  return 0;
2847  }
2848  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2849  }
2850  return 0;
2851 }
int sig_match_aram_size ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 4304 der Datei finsig_thumb2.c.

4305 {
4306  if(!init_disasm_sig_ref(fw,is,rule)) {
4307  printf("sig_match_aram_size: missing ref\n");
4308  return 0;
4309  }
4310  const insn_match_t match_ldr_r0_sp_cmp[]={
4311  {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0),MATCH_OP_MEM(SP,INVALID,0xc)}},
4312  {MATCH_INS(CMP, 2), {MATCH_OP_REG(R0),MATCH_OP_IMM_ANY}},
4313  {ARM_INS_ENDING}
4314  };
4315  if(!insn_match_find_next_seq(fw,is,15,match_ldr_r0_sp_cmp)) {
4316  printf("sig_match_aram_size: no match LDR\n");
4317  return 0;
4318  }
4319  uint32_t val=is->insn->detail->arm.operands[1].imm;
4320  if(val != 0x22000 && val != 0x32000) {
4321  printf("sig_match_aram_size: unexpected ARAM size 0x%08x\n",val);
4322  }
4323  save_misc_val(rule->name,val,0,(uint32_t)is->insn->address);
4324  return 1;
4325 }
int sig_match_aram_size_gt58 ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 4327 der Datei finsig_thumb2.c.

4328 {
4329  if(!init_disasm_sig_ref(fw,is,rule)) {
4330  printf("sig_match_aram_size: missing ref\n");
4331  return 0;
4332  }
4333  const insn_match_t match_ldrd_r0r1_mov[]={
4334  {MATCH_INS(LDRD, 3), {MATCH_OP_REG(R0),MATCH_OP_REG(R1),MATCH_OP_MEM(SP,INVALID,0x10)}},
4335  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R2),MATCH_OP_IMM_ANY}},
4336  {ARM_INS_ENDING}
4337  };
4338  // d7? variant
4339  const insn_match_t match_ldrd_r2r1_mov[]={
4340  {MATCH_INS(LDRD, 3), {MATCH_OP_REG(R2),MATCH_OP_REG(R1),MATCH_OP_MEM(SP,INVALID,0x10)}},
4341  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R3),MATCH_OP_IMM_ANY}},
4342  {ARM_INS_ENDING}
4343  };
4344  if(!insn_match_find_next_seq(fw,is,15,match_ldrd_r0r1_mov)) {
4345  init_disasm_sig_ref(fw,is,rule); // reset to start
4346  if(!insn_match_find_next_seq(fw,is,15,match_ldrd_r2r1_mov)) {
4347  printf("sig_match_aram_size: no match LDR\n");
4348  }
4349  return 0;
4350  }
4351  uint32_t val=is->insn->detail->arm.operands[1].imm;
4352  if(val != 0x22000 && val != 0x32000) {
4353  printf("sig_match_aram_size: unexpected ARAM size 0x%08x\n",val);
4354  }
4355  save_misc_val(rule->name,val,0,(uint32_t)is->insn->address);
4356  return 1;
4357 }
int sig_match_aram_start ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 4359 der Datei finsig_thumb2.c.

4360 {
4361  if(!init_disasm_sig_ref(fw,is,rule)) {
4362  printf("sig_match_aram_start: missing ref\n");
4363  return 0;
4364  }
4365  if(!find_next_sig_call(fw,is,50,"DebugAssert")) {
4366  printf("sig_aram_start: no match DebugAssert\n");
4367  return 0;
4368  }
4369  const insn_match_t match_cmp_bne_ldr[]={
4370  {MATCH_INS(CMP, 2), {MATCH_OP_REG(R1),MATCH_OP_IMM(0)}},
4373  {ARM_INS_ENDING}
4374  };
4375  if(!insn_match_find_next_seq(fw,is,15,match_cmp_bne_ldr)) {
4376  printf("sig_match_aram_start: no match CMP\n");
4377  return 0;
4378  }
4379  uint32_t adr=LDR_PC2val(fw,is->insn);
4380  if(!adr) {
4381  printf("sig_match_aram_start: no match LDR PC 0x%"PRIx64"\n",is->insn->address);
4382  return 0;
4383  }
4384  // could sanity check that it looks like a RAM address
4385  save_misc_val(rule->name,adr,0,(uint32_t)is->insn->address);
4386  return 1;
4387 }
int sig_match_aram_start2 ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 4389 der Datei finsig_thumb2.c.

4390 {
4391  if (get_misc_val_value("ARAM_HEAP_START"))
4392  return 0;
4393 
4394  if(!init_disasm_sig_ref(fw,is,rule)) {
4395  printf("sig_match_aram_start: missing ref\n");
4396  return 0;
4397  }
4398  if(!find_next_sig_call(fw,is,60,"DebugAssert")) {
4399  printf("sig_aram_start2: no match DebugAssert\n");
4400  return 0;
4401  }
4402  const insn_match_t match_cmp_bne_ldr[]={
4403  {MATCH_INS(CMP, 2), {MATCH_OP_REG(R1),MATCH_OP_IMM(0)}},
4407  {ARM_INS_ENDING}
4408  };
4409  if(!insn_match_find_next_seq(fw,is,15,match_cmp_bne_ldr)) {
4410  printf("sig_match_aram_start2: no match CMP\n");
4411  return 0;
4412  }
4413  uint32_t adr=LDR_PC2val(fw,is->insn);
4414  if(!adr) {
4415  printf("sig_match_aram_start2: no match LDR PC 0x%"PRIx64"\n",is->insn->address);
4416  return 0;
4417  }
4418  // could sanity check that it looks like a RAM address
4419  save_misc_val(rule->name,adr,0,(uint32_t)is->insn->address);
4420  return 1;
4421 }
int sig_match_av_over_sem ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 4577 der Datei finsig_thumb2.c.

4578 {
4579  // don't bother on ND-only cams
4580  if(!get_misc_val_value("CAM_HAS_IRIS_DIAPHRAGM")) {
4581  return 0;
4582  }
4583 
4584  if(!init_disasm_sig_ref(fw,is,rule)) {
4585  return 0;
4586  }
4587  if(!find_next_sig_call(fw,is,30,"TakeSemaphore")) {
4588  printf("sig_match_av_over_sem: no match TakeSemaphore at 0x%"PRIx64"\n",is->insn->address);
4589  return 0;
4590  }
4591 
4592  // rewind 5 ins
4593  disasm_iter_init(fw,is,adr_hist_get(&is->ah,5));
4594  var_ldr_desc_t desc;
4595  if(!find_and_get_var_ldr(fw, is, 3, 4, ARM_REG_R0, &desc)) {
4596  printf("sig_match_av_over_sem: no match ldr at 0x%"PRIx64"\n",is->insn->address);
4597  return 0;
4598  }
4599 
4600  save_misc_val(rule->name,desc.adr_adj,desc.off,(uint32_t)is->insn->address);
4601  return 1;
4602 }
int sig_match_cam_has_iris_diaphragm ( __attribute__((unused)) firmware fw,
__attribute__((unused)) iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3920 der Datei finsig_thumb2.c.

3921 {
3922  uint32_t v;
3923  uint32_t ref=0;get_saved_sig_val(rule->ref_name);
3924  // ILC assumed to have iris
3925  if(get_misc_val_value("CAM_IS_ILC")) {
3926  v=1;
3927  } else {
3928  ref=get_saved_sig_val(rule->ref_name);
3929  v=(ref)?1:0;
3930  }
3931  save_misc_val(rule->name,v,0,ref);
3932  return 1;
3933 }
int sig_match_cam_uncached_bit ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3935 der Datei finsig_thumb2.c.

3936 {
3937  if(!init_disasm_sig_ref(fw,is,rule)) {
3938  return 0;
3939  }
3940  const insn_match_t match_bic_r0[]={
3942  {ARM_INS_ENDING}
3943  };
3944  if(insn_match_find_next(fw,is,4,match_bic_r0)) {
3945  save_misc_val(rule->name,is->insn->detail->arm.operands[2].imm,0,(uint32_t)is->insn->address);
3946  return 1;
3947  }
3948  return 0;
3949 }
int sig_match_canon_menu_active ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 4604 der Datei finsig_thumb2.c.

4605 {
4606  if(!init_disasm_sig_ref(fw,is,rule)) {
4607  return 0;
4608  }
4609  var_ldr_desc_t desc;
4610  if(!find_and_get_var_ldr(fw, is, 2, 4, ARM_REG_R0, &desc)) {
4611  printf("sig_match_canon_menu_active: no match ldr at 0x%"PRIx64"\n",is->insn->address);
4612  return 0;
4613  }
4614  if(!disasm_iter(fw,is)) {
4615  printf("sig_match_canon_menu_active: disasm failed\n");
4616  return 0;
4617  }
4618  if(is->insn->id != ARM_INS_CMP) {
4619  printf("sig_match_canon_menu_active: no match cmp at 0x%"PRIx64"\n",is->insn->address);
4620  return 0;
4621  }
4622  save_misc_val(rule->name,desc.adr_adj,desc.off,(uint32_t)is->insn->address);
4623  return 1;
4624 }
int sig_match_closedir ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2109 der Datei finsig_thumb2.c.

2110 {
2111  uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2112  if(!str_adr) {
2113  printf("sig_match_closedir: %s failed to find ref %s\n",rule->name,rule->ref_name);
2114  return 0;
2115  }
2116  // TODO should handle multiple instances of string
2117  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
2118  while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2119  if(!find_next_sig_call(fw,is,60,"sprintf_FW")) {
2120  continue;
2121  }
2122  if(insn_match_find_nth(fw,is,7,2,match_bl_blximm)) {
2123  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2124  }
2125  }
2126 
2127  uint32_t call_adr = find_call_near_str(fw,is,rule);
2128  if(call_adr) {
2129  disasm_iter_init(fw,is,call_adr); // reset to a bit before where the string was found
2130  const insn_match_t match_closedir[]={
2132  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R0), MATCH_OP_REG_ANY}},
2134  {ARM_INS_ENDING}
2135  };
2136  if(insn_match_seq(fw,is,match_closedir)){
2137  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2138  }
2139  }
2140 
2141  return 0;
2142 }
int sig_match_create_jumptable ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1854 der Datei finsig_thumb2.c.

1855 {
1856  if(!init_disasm_sig_ref(fw,is,rule)) {
1857  return 0;
1858  }
1859  // find second function call
1860  if(!insn_match_find_nth(fw,is,20,2,match_bl_blximm)) {
1861  return 0;
1862  }
1863  // follow
1865  if(!insn_match_find_next(fw,is,15,match_bl_blximm)) {
1866  return 0;
1867  }
1868  // TODO could verify it looks right (version string)
1869  save_sig(fw,"CreateJumptable",get_branch_call_insn_target(fw,is));
1870  return 1;
1871 }
int sig_match_createtask_alt ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1324 der Datei finsig_thumb2.c.

1325 {
1326  // if ref doesn't exist, quietly bail
1327  if(!get_saved_sig_val(rule->ref_name)) {
1328  return 0;
1329  }
1330 
1331  if(!init_disasm_sig_ref(fw,is,rule)) {
1332  return 0;
1333  }
1334  if(!insn_match_find_next(fw,is,6,match_bl_blximm)) {
1335  printf("sig_match_createtask_alt: bl match failed\n");
1336  return 0;
1337  }
1339  uint32_t adr2 = get_saved_sig_val("CreateTask");
1340  // only save IFF not identical to CreateTask
1341  if(adr == adr2) {
1342  // printf("sig_match_createtask_alt: adr == CreateTask\n");
1343  return 0;
1344  }
1345  adr2 = get_saved_sig_val("j_CreateTask");
1346  if(adr == adr2) {
1347  // printf("sig_match_createtask_alt: adr == j_CreateTask\n");
1348  return 0;
1349  }
1350  return save_sig_with_j(fw,rule->name,adr);
1351 }
int sig_match_createtaskstrictly_alt ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1290 der Datei finsig_thumb2.c.

1291 {
1292  uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
1293  if(!str_adr) {
1294  printf("sig_match_createtaskstrictly_alt: %s failed to find ref %s\n",rule->name,rule->ref_name);
1295  return 0;
1296  }
1297 
1298  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
1299  while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
1300  if(is->insn->detail->arm.operands[0].reg == ARM_REG_R0) {
1301  // printf("sig_match_str_r0_call: %s ref str %s ref 0x%"PRIx64"\n",rule->name,rule->ref_name,is->insn->address);
1302  // TODO should check if intervening insn nuke r0
1305  uint32_t adr2 = get_saved_sig_val("CreateTaskStrictly");
1306  // only save IFF not identical to CreateTaskStrictly
1307  if(adr == adr2) {
1308  // printf("sig_match_createtaskstrictly_alt: adr == CreateTaskStrictly\n");
1309  return 0;
1310  }
1311  adr2 = get_saved_sig_val("j_CreateTaskStrictly");
1312  if(adr == adr2) {
1313  // printf("sig_match_createtaskstrictly_alt: adr == j_CreateTaskStrictly\n");
1314  return 0;
1315  }
1316  return save_sig_with_j(fw,rule->name,adr);
1317  }
1318  }
1319  }
1320  return 0;
1321 }
int sig_match_dcache_clean_flush_and_disable ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3990 der Datei finsig_thumb2.c.

3991 {
3992  if(!init_disasm_sig_ref(fw,is,rule)) {
3993  return 0;
3994  }
3995  if(!find_next_sig_call(fw,is,44,"GetSRAndDisableInterrupt")) {
3996  printf("sig_match_dcache_clean_flush_and_disable: no GetSRAndDisableInterrupt\n");
3997  return 0;
3998  }
3999  if(!insn_match_find_next(fw,is,2,match_bl_blximm)) {
4000  printf("sig_match_dcache_clean_flush_and_disable: no bl\n");
4001  return 0;
4002  }
4003  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
4004 }
int sig_match_dcache_flush_and_enable ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 4045 der Datei finsig_thumb2.c.

4046 {
4047  if(!init_disasm_sig_ref(fw,is,rule)) {
4048  return 0;
4049  }
4050  if(!find_next_sig_call(fw,is,12,"GetSRAndDisableInterrupt")) {
4051  printf("sig_match_dcache_flush_and_enable: no GetSRAndDisableInterrupt\n");
4052  return 0;
4053  }
4054  if(!find_next_sig_call(fw,is,8,"dcache_clean_flush_and_disable")) {
4055  printf("sig_match_dcache_flush_and_enable: no dcache_clean_flush_and_disable\n");
4056  return 0;
4057  }
4058  // some variants have a call in between, others are inline, not dry version specific
4059  // expect SetSR just after sig_match_dcache_flush_and_enable
4060  if(!find_next_sig_call(fw,is,112,"SetSR")) {
4061  printf("sig_match_dcache_flush_and_enable: no SetSR\n");
4062  return 0;
4063  }
4064  // call should be 2 insns before, rewind
4065  disasm_iter_init(fw,is,adr_hist_get(&is->ah,2));
4066  disasm_iter(fw,is);
4068  if(!adr) {
4069  printf("sig_match_dcache_flush_and_enable: no match call\n");
4070  return 0;
4071  }
4072  return save_sig_with_j(fw,rule->name,adr);
4073 }
int sig_match_debug_logging_flag ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 4880 der Datei finsig_thumb2.c.

4881 {
4882  if(!find_str_arg_call(fw,is,rule)) {
4883  printf("sig_match_debug_logging_flag: no match call\n");
4884  return 0;
4885  }
4886  if(!insn_match_find_next(fw,is,8,match_ldr_pc)) {
4887  printf("sig_match_debug_logging_flag: no match ldr pc 0x%"PRIx64"\n",is->insn->address);
4888  return 0;
4889  }
4890  uint32_t adr = LDR_PC2val(fw,is->insn);
4891  if(!disasm_iter(fw,is)) {
4892  printf("sig_match_debug_logging_flag: disasm failed\n");
4893  return 0;
4894  }
4895  arm_reg base_reg = (arm_reg)is->insn->detail->arm.operands[1].reg;
4896  uint32_t ref_adr = (uint32_t)is->insn->address;
4897  if (fw->arch_flags & FW_ARCH_FL_VMSA) {
4898  if(is->insn->id != ARM_INS_LDRB) {
4899  printf("sig_match_debug_logging_flag: no match ldrb 0x%"PRIx64"\n",is->insn->address);
4900  return 0;
4901  }
4902  } else {
4903  if(is->insn->id != ARM_INS_LDR) {
4904  printf("sig_match_debug_logging_flag: no match ldr 0x%"PRIx64"\n",is->insn->address);
4905  return 0;
4906  }
4907  }
4908  if((arm_reg)is->insn->detail->arm.operands[1].reg != base_reg) {
4909  printf("sig_match_debug_logging_flag: no match reg 0x%"PRIx64"\n",is->insn->address);
4910  return 0;
4911  }
4912  int disp = (arm_reg)is->insn->detail->arm.operands[1].mem.disp;
4913  if(!disasm_iter(fw,is)) {
4914  printf("sig_match_debug_logging_flag: disasm failed\n");
4915  return 0;
4916  }
4917  if(is->insn->id != ARM_INS_LSL) {
4918  printf("sig_match_debug_logging_flag: no match lsl\n");
4919  return 0;
4920  }
4921  save_misc_val(rule->name,adr + disp,disp,ref_adr);
4922  return 1;
4923 }
int sig_match_debug_logging_ptr ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 4840 der Datei finsig_thumb2.c.

4841 {
4842  uint32_t call_adr = find_str_arg_call(fw,is,rule);
4843  if(!call_adr) {
4844  printf("sig_match_debug_logging_ptr: no match call\n");
4845  return 0;
4846  }
4847  // is should be pointing at bx instruction, get the register being called
4848  arm_reg call_reg = is->insn->detail->arm.operands[0].reg;
4849 
4850  // backtrack until we find ldr into reg
4851  int i;
4852  for(i=1; i<10; i++) {
4854  cs_insn *insn=fw->is->insn;
4855  if((arm_reg)insn->detail->arm.operands[0].reg != call_reg || insn->id == ARM_INS_CMP ) {
4856  continue;
4857  }
4858  // LDR into target reg
4859  if(insn->id == ARM_INS_LDR && insn->detail->arm.operands[1].type == ARM_OP_MEM) {
4860  arm_reg base_reg = (arm_reg)insn->detail->arm.operands[1].reg;
4861  int disp = insn->detail->arm.operands[1].mem.disp;
4862  i++;
4863  // backtrack one more (assume no gap)
4865  uint32_t adr = LDR_PC2val(fw,fw->is->insn);
4866  if(!adr || (arm_reg)fw->is->insn->detail->arm.operands[0].reg != base_reg) {
4867  printf("sig_match_debug_logging_ptr: no match ldr2 0x%x 0x%"PRIx64"\n",adr,fw->is->insn->address);
4868  return 0;
4869  }
4870  save_misc_val(rule->name,adr + disp,disp,(uint32_t)fw->is->insn->address);
4871  return 1;
4872  }
4873  printf("sig_match_debug_logging_ptr: reg clobbered 0x%"PRIx64"\n",fw->is->insn->address);
4874  return 0;
4875  }
4876  printf("sig_match_debug_logging_ptr: no match ldr 0x%"PRIx64"\n",fw->is->insn->address);
4877  return 0;
4878 }
int sig_match_default_assert_handler ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3550 der Datei finsig_thumb2.c.

3551 {
3552  if(!init_disasm_sig_ref(fw,is,rule)) {
3553  return 0;
3554  }
3555  if(!find_next_sig_call(fw,is,14,"set_assert_handler")) {
3556  printf("sig_match_default_assert_handler: no match set_assert_handler\n");
3557  return 0;
3558  }
3559  // expect func r0
3560  uint32_t regs[4];
3561  if((get_call_const_args(fw,is,1,regs)&0x1)!=0x1) {
3562  printf("sig_match_default_assert_handler: no match arg\n");
3563  return 0;
3564  }
3565  return save_sig_with_j(fw,rule->name,regs[0]);
3566 }
int sig_match_default_exception_handler ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3568 der Datei finsig_thumb2.c.

3569 {
3570  if(!init_disasm_sig_ref(fw,is,rule)) {
3571  return 0;
3572  }
3573  if(!find_next_sig_call(fw,is,20,"set_exception_handler")) {
3574  printf("sig_match_default_exception_handler: no match set_exception_handler\n");
3575  return 0;
3576  }
3577  // expect func in r0
3578  uint32_t regs[4];
3579  if((get_call_const_args(fw,is,1,regs)&0x1)!=0x1) {
3580  printf("sig_match_default_exception_handler: no match arg\n");
3581  return 0;
3582  }
3583  return save_sig_with_j(fw,rule->name,regs[0]);
3584 }
int sig_match_default_panic_handler ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3586 der Datei finsig_thumb2.c.

3587 {
3588  if(!init_disasm_sig_ref(fw,is,rule)) {
3589  return 0;
3590  }
3591  if(!find_next_sig_call(fw,is,28,"set_panic_handler")) {
3592  printf("sig_match_default_panic_handler: no match set_panic_handler\n");
3593  return 0;
3594  }
3595  // expect func in r0
3596  uint32_t regs[4];
3597  if((get_call_const_args(fw,is,1,regs)&0x1)!=0x1) {
3598  printf("sig_match_default_panic_handler: no match arg\n");
3599  return 0;
3600  }
3601  return save_sig_with_j(fw,rule->name,regs[0]);
3602 }
int sig_match_deletedirectory_fut ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2891 der Datei finsig_thumb2.c.

2892 {
2893  uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2894  if(!str_adr) {
2895  printf("sig_match_deletedirectory_fut: failed to find ref %s\n",rule->ref_name);
2896  return 0;
2897  }
2898  // TODO using larger than default "near" range, needed for sx710
2899  // not looking for ref to string, just code near where the actual string is
2900  disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - 2048) | fw->thumb_default); // reset to a bit before where the string was found
2901  uint32_t end_adr = ADR_ALIGN4(str_adr) + 2048;
2902  while(find_next_sig_call(fw,is,end_adr - (uint32_t)is->adr,"DeleteFile_Fut")) {
2903  if(!insn_match_find_next(fw,is,6,match_bl_blximm)) {
2904  // printf("sig_match_deletedirectory_fut: no match bl strcpy\n");
2905  continue;
2906  }
2907  if(!is_sig_call(fw,is,"strcpy")) {
2908  // printf("sig_match_deletedirectory_fut: bl not strcpy at 0x%"PRIx64"\n",is->insn->address);
2909  continue;
2910  }
2911  if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
2912  // printf("sig_match_deletedirectory_fut: no match bl strrchr at 0x%"PRIx64"\n",is->insn->address);
2913  continue;
2914  }
2915  if(!is_sig_call(fw,is,"strrchr")) {
2916  // printf("sig_match_deletedirectory_fut: bl not strrchr at 0x%"PRIx64"\n",is->insn->address);
2917  continue;
2918  }
2919  // verify that arg1 to strrch is /
2920  uint32_t regs[4];
2921  if((get_call_const_args(fw,is,2,regs)&0x2)!=0x2) {
2922  // printf("sig_match_deletedirectory_fut: failed to get strrchr r1 at 0x%"PRIx64"\n",is->insn->address);
2923  continue;
2924  }
2925  if(regs[1] != '/') {
2926  // printf("sig_match_deletedirectory_fut: strrchr r1 not '/' at 0x%"PRIx64"\n",is->insn->address);
2927  continue;
2928  }
2929  if(!insn_match_find_next(fw,is,5,match_bl_blximm)) {
2930  // printf("sig_match_deletedirectory_fut: no match bl at 0x%"PRIx64"\n",is->insn->address);
2931  continue;
2932  }
2933  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2934  }
2935  return 0;
2936 }
int sig_match_deletefile_fut ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2071 der Datei finsig_thumb2.c.

2072 {
2073  uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2074  if(!str_adr) {
2075  printf("sig_match_deletefile_fut: %s failed to find ref %s\n",rule->name,rule->ref_name);
2076  return 0;
2077  }
2078  // TODO should handle multiple instances of string
2079  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
2080  while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2081  // next call should be DeleteFile_Fut
2082  if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
2083  continue;
2084  }
2085  // follow
2087  if(!fw_disasm_iter_single(fw,adr)) {
2088  printf("sig_match_deletefile_fut: disasm failed\n");
2089  return 0;
2090  }
2091  const insn_match_t match_mov_r1[]={
2092  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R1), MATCH_OP_IMM_ANY}},
2093 #if CS_API_MAJOR < 4
2094  {MATCH_INS(MOVS, 2), {MATCH_OP_REG(R1), MATCH_OP_IMM_ANY}},
2095 #endif
2096  {ARM_INS_ENDING}
2097  };
2098 
2099  if(!insn_match_any(fw->is->insn,match_mov_r1)){
2100  continue;
2101  }
2102  return save_sig_with_j(fw,rule->name,adr);
2103  }
2104  return 0;
2105 }
int sig_match_disable_hdmi_power ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3650 der Datei finsig_thumb2.c.

3651 {
3652  if(!init_disasm_sig_ref(fw,is,rule)) {
3653  return 0;
3654  }
3655  if(!find_next_sig_call(fw,is,24,"EnableHDMIPower")) {
3656  printf("sig_match_disable_hdmi_power: no match EnableHDMIPower\n");
3657  return 0;
3658  }
3659  if(!find_next_sig_call(fw,is,22,"ClearEventFlag")) {
3660  printf("sig_match_disable_hdmi_power: no match ClearEventFlag\n");
3661  return 0;
3662  }
3663  const insn_match_t match_seq[]={
3665  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM(1)}},
3667  {ARM_INS_ENDING}
3668  };
3669  if(!insn_match_find_next_seq(fw,is,12,match_seq)) {
3670  printf("sig_match_disable_hdmi_power: no match seq bl movs pop 0x%"PRIx64"\n",is->insn->address);
3671  return 0;
3672  }
3673  // bl matched above should be func
3674  disasm_iter_init(fw,is,adr_hist_get(&is->ah,2));
3675  if (!disasm_iter(fw,is)) {
3676  return 0;
3677  }
3678  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3679 }
int sig_match_displaybusyonscreen_52 ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2980 der Datei finsig_thumb2.c.

2981 {
2982  if (fw->dryos_ver != 52) {
2983  return 0;
2984  }
2985  uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2986  if(!str_adr) {
2987  printf("sig_match_displaybusyonscreen: failed to find ref %s\n",rule->ref_name);
2988  return 0;
2989  }
2990  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
2991  while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2992  if(!insn_match_find_next(fw,is,3,match_bl_blximm)) {
2993  // printf("sig_match_displaybusyonscreen: no match bl at 0x%"PRIx64"\n",is->insn->address);
2994  continue;
2995  }
2996  if(!is_sig_call(fw,is,"LogCameraEvent")) {
2997  // printf("sig_match_displaybusyonscreen: not LogCameraEvent at 0x%"PRIx64"\n",is->insn->address);
2998  continue;
2999  }
3000  if(!find_next_sig_call(fw,is,4,"GUISrv_StartGUISystem_FW")) {
3001  // printf("sig_match_displaybusyonscreen: no match GUISrv_StartGUISystem_FW\n");
3002  continue;
3003  }
3004  if(!insn_match_find_nth(fw,is,5,2,match_bl_blximm)) {
3005  // printf("sig_match_displaybusyonscreen: no match bl 0x%"PRIx64"\n",is->insn->address);
3006  continue;
3007  }
3008  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3009  }
3010  return 0;
3011 }
int sig_match_dry_memcpy_bytes ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3894 der Datei finsig_thumb2.c.

3895 {
3896  if(!init_disasm_sig_ref(fw,is,rule)) {
3897  return 0;
3898  }
3899  if(!insn_match_find_next(fw,is,7,match_bl_blximm)) {
3900  printf("sig_match_dry_memcpy_bytes: no bl 1\n");
3901  return 0;
3902  }
3903  // follow
3905  // expect tail call to dry_memcpy_bytes
3906  const insn_match_t match_end[]={
3909  {ARM_INS_ENDING}
3910  };
3911 
3912  if(!insn_match_find_next_seq(fw,is,20,match_end)) {
3913  printf("sig_match_dry_memcpy_bytes: no match end\n");
3914  return 0;
3915  }
3916  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3917 }
int sig_match_dry_memset ( 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  return 0;
3829  }
3830  if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
3831  printf("sig_match_dry_memset: no bl 1\n");
3832  return 0;
3833  }
3834  // follow
3836  if(!insn_match_find_nth(fw,is,12,3,match_bl_blximm)) {
3837  printf("sig_match_dry_memset: no match bl 2\n");
3838  return 0;
3839  }
3840  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3841 }
int sig_match_dry_memzero ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3843 der Datei finsig_thumb2.c.

3844 {
3845  if(!init_disasm_sig_ref(fw,is,rule)) {
3846  return 0;
3847  }
3848  if(!insn_match_find_next(fw,is,3,match_bl_blximm)) {
3849  printf("sig_match_dry_memset: no bl 1\n");
3850  return 0;
3851  }
3852  // follow
3854  if(!insn_match_find_next(fw,is,7,match_bl_blximm)) {
3855  printf("sig_match_dry_memset: no match bl 2\n");
3856  return 0;
3857  }
3858  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3859 }
int sig_match_enable_hdmi_power ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3625 der Datei finsig_thumb2.c.

3626 {
3627  if(!init_disasm_sig_ref(fw,is,rule)) {
3628  return 0;
3629  }
3630  if(!find_next_sig_call(fw,is,14,"CreateEventFlagStrictly")) {
3631  printf("sig_match_enable_hdmi_power: no match CreateEventFlagStrictly\n");
3632  return 0;
3633  }
3634  const insn_match_t match_seq[]={
3637  {ARM_INS_ENDING}
3638  };
3639  if(!insn_match_find_next_seq(fw,is,4,match_seq)) {
3640  printf("sig_match_enable_hdmi_power: no match bl seq cbnz 0x%"PRIx64"\n",is->insn->address);
3641  return 0;
3642  }
3643  // function should be next call
3644  if (!disasm_iter(fw,is)) {
3645  return 0;
3646  }
3647  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3648 }
int sig_match_evp_table_veneer ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1261 der Datei finsig_thumb2.c.

1262 {
1263  uint32_t ref_adr = get_saved_sig_val(rule->ref_name);
1264  int prevb = 0;
1265  uint32_t cadr;
1266  // following should probably be done using fw_search_insn
1267  // both veneers consist of a single b instruction, always preceded by another b instruction
1268  disasm_iter_init(fw,is,ref_adr); // start at our known function
1269  while (is->adr < (ref_adr+0x800)) {
1270  cadr = is->adr;
1271  if (!disasm_iter(fw,is)) {
1272  disasm_iter_set(fw,is,(is->adr+2) | fw->thumb_default);
1273  }
1274  else {
1275  if (is->insn->id == ARM_INS_B) {
1276  uint32_t b_adr = get_branch_call_insn_target(fw,is);
1277  if (prevb && (b_adr == ref_adr)) {
1278  // this doesn't use _with_j since we want identify the veneer
1279  add_func_name(fw,rule->name,cadr | is->thumb,NULL);
1280  return 1;
1281  }
1282  prevb = 1;
1283  }
1284  }
1285  }
1286  return 0;
1287 }
int sig_match_exec_evp ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2328 der Datei finsig_thumb2.c.

2329 {
2330  uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2331  if(!str_adr) {
2332  printf("sig_match_exec_evp: failed to find ref %s\n",rule->ref_name);
2333  return 0;
2334  }
2335  // TODO should handle multiple instances of string
2336  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
2337  while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2338  // search backwards for push {r0,...}
2339  int i;
2340  for(i=1; i<=18; i++) {
2341  if(!fw_disasm_iter_single(fw,adr_hist_get(&is->ah,i))) {
2342  break;
2343  }
2344  if(fw->is->insn->id == ARM_INS_PUSH && fw->is->insn->detail->arm.operands[0].reg == ARM_REG_R0) {
2345  // push should be start of func
2346  uint32_t adr=(uint32_t)(fw->is->insn->address) | is->thumb;
2347  // search forward in original iter_state for DebugAssert. If found, in the wrong ExecuteEventProcedure
2348  if(find_next_sig_call(fw,is,28,"DebugAssert")) {
2349  break;
2350  }
2351  return save_sig_with_j(fw,rule->name,adr);
2352  }
2353  }
2354  }
2355  return 0;
2356 }
int sig_match_exmem_vars ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3199 der Datei finsig_thumb2.c.

3200 {
3201  uint32_t adr[2], fnd[2];
3202  if(!init_disasm_sig_ref(fw,is,rule)) {
3203  printf("sig_match_exmem_vars: missing ref\n");
3204  return 0;
3205  }
3206  // expect first LDR pc
3207  if(!insn_match_find_next(fw,is,15,match_ldr_pc)) {
3208  printf("sig_match_exmem_vars: match LDR PC failed\n");
3209  return 0;
3210  }
3211  adr[0]=LDR_PC2val(fw,is->insn);
3212  fnd[0]=(uint32_t)is->insn->address;
3213  if(!insn_match_find_next(fw,is,5,match_ldr_pc)) {
3214  printf("sig_match_exmem_vars: 2nd match LDR PC failed\n");
3215  return 0;
3216  }
3217  adr[1]=LDR_PC2val(fw,is->insn);
3218  fnd[1]=(uint32_t)is->insn->address;
3219  //printf("sig_match_exmem_vars: %x, %x\n",adr[0], adr[1]);
3220  int n;
3221  for (n=0; n<2; n++) {
3222  if (adr[n] < fw->data_start+fw->data_len) {
3223  uint32_t ladr = adr[n]-fw->data_start+fw->data_init_start;
3224  save_misc_val("exmem_types_table",ladr,0,fnd[n]);
3225  int m;
3226  int exm_typ_cnt = 0;
3227  for (m=0; m<42; m++) {
3228  if ( (fw_u32(fw,ladr+m*4)!=0) && isASCIIstring(fw, fw_u32(fw,ladr+m*4)) )
3229  {
3230  char *extyp = (char*)adr2ptr(fw, fw_u32(fw,ladr+m*4));
3231  if ( strncmp(extyp,"EXMEM",5)==0 )
3232  {
3233  exm_typ_cnt++;
3234  }
3235  }
3236  else
3237  {
3238  break;
3239  }
3240  }
3241  save_misc_val("exmem_type_count",exm_typ_cnt,0,ladr);
3242  }
3243  else if (adr[n] < fw->memisostart) {
3244  save_misc_val("exmem_alloc_table",adr[n],0,fnd[n]);
3245  }
3246  }
3247  return 1;
3248 }
int sig_match_fclose_low ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1598 der Datei finsig_thumb2.c.

1599 {
1600  if(!init_disasm_sig_ref(fw,is,rule)) {
1601  // printf("sig_match_fclose_low: missing ref\n");
1602  return 0;
1603  }
1604  if(!find_next_sig_call(fw,is,24,"strlen")) {
1605  // printf("sig_match_fclose_low: no strlen\n");
1606  return 0;
1607  }
1608  if(!find_next_sig_call(fw,is,26,"malloc")) {
1609  // printf("sig_match_fclose_low: no malloc\n");
1610  return 0;
1611  }
1612  if(!find_next_sig_call(fw,is,14,"strcpy")) {
1613  // printf("sig_match_fclose_low: no strcpy\n");
1614  return 0;
1615  }
1616 
1617  if(!insn_match_find_nth(fw,is,12,3,match_bl_blximm)) {
1618  // printf("sig_match_fclose_low: no bl\n");
1619  return 0;
1620  }
1621  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1622 }
int sig_match_fgets_fut ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2358 der Datei finsig_thumb2.c.

2359 {
2360  if(!init_disasm_sig_ref(fw,is,rule)) {
2361  return 0;
2362  }
2363  if(!find_next_sig_call(fw,is,16,"Fopen_Fut_FW")) {
2364  return 0;
2365  }
2366  disasm_iter(fw,is);
2367  disasm_iter(fw,is);
2368  if (B_target(fw,is->insn) && (is->insn->detail->arm.cc == ARM_CC_NE)) {
2370  } else {
2371  if (B_target(fw,is->insn) && (is->insn->detail->arm.cc == ARM_CC_NE)) {
2373  }
2374  }
2375  if(!insn_match_find_nth(fw,is,20,1,match_bl_blximm)) {
2376  return 0;
2377  }
2378  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2379 }
int sig_match_file_counter_init ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 4626 der Datei finsig_thumb2.c.

4627 {
4628  if(!init_disasm_sig_ref(fw,is,rule)) {
4629  return 0;
4630  }
4631  // find first call
4632  if(!insn_match_find_next(fw,is,3,match_bl_blximm)) {
4633  // printf("sig_match_file_counter_init: bl match 1 failed at 0x%"PRIx64"\n",is->insn->address);
4634  return 0;
4635  }
4636  // some cameras (dry 58+?) have a nullsub before the function of interest
4638  if(!insn_match_find_next(fw,is,3,match_bl_blximm)) {
4639  // printf("sig_match_file_counter_init: bl match 1a failed at 0x%"PRIx64"\n",is->insn->address);
4640  return 0;
4641  }
4642  }
4643  // follow
4645  if(!insn_match_find_next(fw,is,3,match_bl_blximm)) {
4646  // printf("sig_match_file_counter_init: bl match 2 failed at 0x%"PRIx64"\n",is->insn->address);
4647  return 0;
4648  }
4649  uint32_t fadr = get_branch_call_insn_target(fw,is);
4650  // follow
4651  disasm_iter_init(fw,is,fadr);
4652  if(!disasm_iter(fw,is)) {
4653  // printf("sig_match_file_counter_init: disasm failed\n");
4654  return 0;
4655  }
4656  // sanity check
4657  if(!isLDR_PC(is->insn)) {
4658  // printf("sig_match_file_counter_init: no match LDR PC at 0x%"PRIx64"\n",is->insn->address);
4659  return 0;
4660  }
4661  // function we're looking for
4662  return save_sig_with_j(fw,rule->name,fadr);
4663 }
int sig_match_file_counter_var ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 4664 der Datei finsig_thumb2.c.

4665 {
4666  if(!init_disasm_sig_ref(fw,is,rule)) {
4667  return 0;
4668  }
4669  uint32_t adr=LDR_PC2val(fw,is->insn);
4670  if(!adr) {
4671  // printf("sig_match_file_counter_var: no match LDR PC 0x%"PRIx64"\n",is->insn->address);
4672  return 0;
4673  }
4674  if(is->insn->detail->arm.operands[0].reg != ARM_REG_R0) {
4675  // printf("sig_match_file_counter_var: not R0 0x%"PRIx64"\n",is->insn->address);
4676  return 0;
4677  }
4678  if(!adr_is_var(fw,adr)) {
4679  // printf("sig_match_file_counter_var: not a data address 0x%08x at 0x%"PRIx64"\n",adr,is->insn->address);
4680  return 0;
4681  }
4682  save_misc_val(rule->name,adr,0,(uint32_t)is->insn->address);
4683  return 1;
4684 }
int sig_match_flash_param_table ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3722 der Datei finsig_thumb2.c.

3723 {
3724  if(!init_disasm_sig_ref(fw,is,rule)) {
3725  return 0;
3726  }
3727  // expect 3 asserts
3728  if(!insn_match_find_next(fw,is,14,match_bl_blximm)) {
3729  // printf("sig_match_flash_param_table: no match bl 1\n");
3730  return 0;
3731  }
3732  if(!is_sig_call(fw,is,"DebugAssert")) {
3733  // printf("sig_match_flash_param_table: bl 1 not DebugAssert at 0x%"PRIx64"\n",is->insn->address);
3734  return 0;
3735  }
3736  if(!insn_match_find_next(fw,is,7,match_bl_blximm)) {
3737  // printf("sig_match_flash_param_table: no match bl 2\n");
3738  return 0;
3739  }
3740  if(!is_sig_call(fw,is,"DebugAssert")) {
3741  // printf("sig_match_flash_param_table: bl 2 not DebugAssert at 0x%"PRIx64"\n",is->insn->address);
3742  return 0;
3743  }
3744  if(!insn_match_find_next(fw,is,8,match_bl_blximm)) {
3745  // printf("sig_match_flash_param_table: no match bl 3\n");
3746  return 0;
3747  }
3748  if(!is_sig_call(fw,is,"DebugAssert")) {
3749  // printf("sig_match_flash_param_table: bl 3 not DebugAssert at 0x%"PRIx64"\n",is->insn->address);
3750  return 0;
3751  }
3752  // expect AcquireRecursiveLockStrictly, func
3753  if(!insn_match_find_nth(fw,is,14,2,match_bl_blximm)) {
3754  // printf("sig_match_flash_param_table: no match sub 1\n");
3755  return 0;
3756  }
3757  // follow
3759 
3760  // first call
3761  if(!insn_match_find_next(fw,is,8,match_bl_blximm)) {
3762  // printf("sig_match_flash_param_table: no match sub 1 bl\n");
3763  return 0;
3764  }
3765 
3766  // follow
3768  // first instruction should load address
3769  disasm_iter(fw,is);
3770  uint32_t adr=LDR_PC2val(fw,is->insn);
3771  if(!adr) {
3772  // printf("sig_match_flash_param_table: no match LDR PC 0x%"PRIx64"\n",is->insn->address);
3773  return 0;
3774  }
3775  save_misc_val(rule->name,adr,0,(uint32_t)is->insn->address);
3776  return 1;
3777 }
int sig_match_focus_busy ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 4254 der Datei finsig_thumb2.c.

4255 {
4256  if(!init_disasm_sig_ref(fw,is,rule)) {
4257  return 0;
4258  }
4259  // look for first TakeSemaphore
4260  if(!find_next_sig_call(fw,is,40,"TakeSemaphore")) {
4261  // printf("sig_match_focus_busy: no match TakeSemaphore\n");
4262  return 0;
4263  }
4264  // next call
4265  if(!insn_match_find_next(fw,is,5,match_bl_blximm)) {
4266  // printf("sig_match_focus_busy: no match bl\n");
4267  return 0;
4268  }
4269  // follow
4271  // get base address from first LDR PC
4272  if(!insn_match_find_next(fw,is,5,match_ldr_pc)) {
4273  // printf("sig_match_focus_busy: match LDR PC failed\n");
4274  return 0;
4275  }
4276  uint32_t base=LDR_PC2val(fw,is->insn);
4277  arm_reg rb=is->insn->detail->arm.operands[0].reg;
4278 
4279  // look for first TakeSemaphoreStrictly
4280  if(!find_next_sig_call(fw,is,50,"TakeSemaphoreStrictly")) {
4281  // printf("sig_match_focus_busy: no match TakeSemaphoreStrictly\n");
4282  return 0;
4283  }
4284  const insn_match_t match_ldr[]={
4285  {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM_ANY}},
4286  {MATCH_INS(CBZ, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM_ANY}},
4287  {ARM_INS_ENDING}
4288  };
4289  if(!insn_match_find_next_seq(fw,is,10,match_ldr)) {
4290  // printf("sig_match_focus_busy: no match LDR\n");
4291  return 0;
4292  }
4293  // rewind to LDR
4294  disasm_iter_init(fw,is,adr_hist_get(&is->ah,1));
4295  disasm_iter(fw,is);
4296  // check LDR
4297  if(is->insn->detail->arm.operands[1].mem.base != rb) {
4298  // printf("sig_match_focus_busy: no match LDR base\n");
4299  return 0;
4300  }
4301  save_misc_val(rule->name,base,is->insn->detail->arm.operands[1].mem.disp,(uint32_t)is->insn->address);
4302  return 1;
4303 }
int sig_match_func_ptr_val ( firmware fw,
__attribute__((unused)) iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 4563 der Datei finsig_thumb2.c.

4564 {
4565  uint32_t adr = get_misc_val_value(rule->ref_name);
4566  if(!adr) {
4567  return 0;
4568  }
4569  uint32_t *vp = (uint32_t *)adr2ptr_with_data(fw,adr);
4570  if(!vp) {
4571  return 0;
4572  }
4573  return save_sig_with_j(fw,rule->name,*vp);
4574 }
int sig_match_fw_yuv_layer_buf_52 ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 4939 der Datei finsig_thumb2.c.

4940 {
4941  if(!init_disasm_sig_ref(fw,is,rule)) {
4942  return 0;
4943  }
4944  // code may have an unconditional branch which find_next_sig_call thinks is a veneer
4945  if(!find_next_sig_call_ex(fw,is,54,"get_displaytype",FIND_SIG_CALL_NO_UNK_VENEER)) {
4946  printf("sig_match_fw_yuv_layer_buf_52: no match get_displaytype\n");
4947  return 0;
4948  }
4949  printf("match get_displaytype 0x%"PRIx64"\n",is->insn->address);
4950  if(!insn_match_find_nth(fw,is,14,2,match_bl_blximm)) {
4951  printf("sig_match_fw_yuv_layer_buf_52: no match call\n");
4952  return 0;
4953  }
4954  printf("match 0x%"PRIx64"\n",is->insn->address);
4955  uint32_t regs[4];
4956  // get r1, backtracking up to 8 instructions
4957  if ((get_call_const_args(fw,is,8,regs)&2)!=2) {
4958  printf("sig_match_fw_yuv_layer_buf_52: no match const arg\n");
4959  return 0;
4960  }
4961  save_misc_val(rule->name,regs[1],0,(uint32_t)fw->is->insn->address); // fw is has backtracked address
4962  return 0;
4963 }
int sig_match_fw_yuv_layer_buf_gt52 ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 4965 der Datei finsig_thumb2.c.

4966 {
4967  if(!init_disasm_sig_ref(fw,is,rule)) {
4968  return 0;
4969  }
4970  if(!find_next_sig_call(fw,is,170,"DebugAssert")) {
4971  printf("sig_match_fw_yuv_layer_buf: no match DebugAssert\n");
4972  return 0;
4973  }
4974  if(!insn_match_find_next(fw,is,12,match_bl_blximm)) {
4975  printf("sig_match_fw_yuv_layer_buf: no match call\n");
4976  return 0;
4977  }
4978  uint32_t regs[4];
4979  // get r1, backtracking up to 8 instructions
4980  if ((get_call_const_args(fw,is,8,regs)&2)!=2) {
4981  printf("sig_match_fw_yuv_layer_buf: no match const arg\n");
4982  return 0;
4983  }
4984  save_misc_val(rule->name,regs[1],0,(uint32_t)fw->is->insn->address); // fw is has backtracked address
4985  return 0;
4986 }
int sig_match_get_canon_mode_list ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 4124 der Datei finsig_thumb2.c.

4125 {
4126  uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
4127  if(!str_adr) {
4128  printf("sig_match_get_canon_mode_list: failed to find ref %s\n",rule->ref_name);
4129  return 0;
4130  }
4131  uint32_t adr=0;
4132  // TODO should handle multiple instances of string
4133  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
4134  while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
4135  // printf("sig_match_get_canon_mode_list: str match 0x%"PRIx64"\n",is->insn->address);
4136  if(!find_next_sig_call(fw,is,4,"LogCameraEvent")) {
4137  // printf("sig_match_get_canon_mode_list: no LogCameraEvent\n");
4138  continue;
4139  }
4140  // some cameras have a mov and an extra call
4141  if(!disasm_iter(fw,is)) {
4142  // printf("sig_match_get_canon_mode_list: disasm failed\n");
4143  return 0;
4144  }
4145  const insn_match_t match_mov_r0_1[]={
4146 #if CS_API_MAJOR < 4
4147  {MATCH_INS(MOVS, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM(1)}},
4148 #endif
4149  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM(1)}},
4150  {ARM_INS_ENDING}
4151  };
4152  if(insn_match_any(is->insn,match_mov_r0_1)) {
4153  if(!insn_match_find_nth(fw,is,2,2,match_bl_blximm)) {
4154  // printf("sig_match_get_canon_mode_list: no match bl 1x\n");
4155  continue;
4156  }
4157  } else {
4158  if(!insn_match_any(is->insn,match_bl_blximm)) {
4159  // printf("sig_match_get_canon_mode_list: no match bl 1\n");
4160  continue;
4161  }
4162  }
4163  // found something to follow, break
4164  adr=get_branch_call_insn_target(fw,is);
4165  break;
4166  }
4167  if(!adr) {
4168  return 0;
4169  }
4170  // printf("sig_match_get_canon_mode_list: sub 1 0x%08x\n",adr);
4171  disasm_iter_init(fw,is,adr);
4172  if(!find_next_sig_call(fw,is,40,"TakeSemaphoreStrictly")) {
4173  // printf("sig_match_get_canon_mode_list: no TakeSemaphoreStrictly\n");
4174  return 0;
4175  }
4176  // match second call
4177  if(!insn_match_find_nth(fw,is,12,2,match_b_bl_blximm)) {
4178  // printf("sig_match_get_canon_mode_list: no match bl 2\n");
4179  return 0;
4180  }
4181  // follow
4183  const insn_match_t match_loop[]={
4188  {ARM_INS_ENDING}
4189  };
4190  if(!insn_match_find_next_seq(fw,is,64,match_loop)) {
4191  // printf("sig_match_get_canon_mode_list: match 1 failed\n");
4192  return 0;
4193  }
4194  if(!insn_match_find_next(fw,is,2,match_bl_blximm)) {
4195  // printf("sig_match_get_canon_mode_list: no match bl 3\n");
4196  return 0;
4197  }
4198  // should be func
4199  adr=get_branch_call_insn_target(fw,is);
4200  // sanity check
4201  disasm_iter_init(fw,is,adr);
4202  const insn_match_t match_ldr_r0_ret[]={
4203  {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM_BASE(PC)}},
4204  {MATCH_INS(BX, 1), {MATCH_OP_REG(LR)}},
4205  {ARM_INS_ENDING}
4206  };
4207  if(!insn_match_find_next_seq(fw,is,1,match_ldr_r0_ret)) {
4208  // printf("sig_match_get_canon_mode_list: match 2 failed\n");
4209  return 0;
4210  }
4211  return save_sig_with_j(fw,rule->name,adr);
4212 }
int sig_match_get_current_deltasv ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1444 der Datei finsig_thumb2.c.

1445 {
1446  if(!init_disasm_sig_ref(fw,is,rule)) {
1447  return 0;
1448  }
1449  if(!find_next_sig_call(fw,is,36,"GetCurrentShutterSpeed_FW")) {
1450  printf("sig_match_get_current_deltasv: no match GetCurrentShutterSpeed_FW\n");
1451  return 0;
1452  }
1453  // bl <func we want>
1454  // strh r0, [rN,4]
1455  const insn_match_t match_bl_strh[]={
1457  {MATCH_INS(STRH,2), {MATCH_OP_REG(R0), MATCH_OP_MEM(INVALID,INVALID,0x4)}},
1458  {ARM_INS_ENDING}
1459  };
1460  if(!insn_match_find_next_seq(fw,is,8,match_bl_strh)) {
1461  printf("sig_match_get_current_deltasv: match failed\n");
1462  return 0;
1463  }
1464  // rewind one for call
1465  disasm_iter_init(fw,is,adr_hist_get(&is->ah,1));
1466  disasm_iter(fw,is);
1467  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1468 }
int sig_match_get_current_exp ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1390 der Datei finsig_thumb2.c.

1391 {
1392  if(!init_disasm_sig_ref(fw,is,rule)) {
1393  return 0;
1394  }
1395  if(!insn_match_find_next(fw,is,2,match_bl_blximm)) {
1396  printf("sig_match_get_current_exp: bl match 1 failed\n");
1397  return 0;
1398  }
1399  // follow
1401  if(!insn_match_find_next(fw,is,6,match_bl_blximm)) {
1402  printf("sig_match_get_current_exp: bl match 2 failed\n");
1403  return 0;
1404  }
1405  // follow
1407  if(!insn_match_find_next(fw,is,6,match_bl_blximm)) {
1408  printf("sig_match_get_current_exp: bl match 3 failed\n");
1409  return 0;
1410  }
1411  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1412 }
int sig_match_get_current_nd_value ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1414 der Datei finsig_thumb2.c.

1415 {
1416  // this match is only valid for cameras with both ND and Iris
1417  if(!get_misc_val_value("CAM_HAS_ND_FILTER") || !get_misc_val_value("CAM_HAS_IRIS_DIAPHRAGM")) {
1418  return 0;
1419  }
1420  if(!init_disasm_sig_ref(fw,is,rule)) {
1421  return 0;
1422  }
1423  if(!find_next_sig_call(fw,is,36,"GetCurrentShutterSpeed_FW")) {
1424  printf("sig_match_get_current_nd_value: no match GetCurrentShutterSpeed_FW\n");
1425  return 0;
1426  }
1427  // bl <func we want>
1428  // strh r0, [rN,8]
1429  const insn_match_t match_bl_strh[]={
1431  {MATCH_INS(STRH,2), {MATCH_OP_REG(R0), MATCH_OP_MEM(INVALID,INVALID,0x8)}},
1432  {ARM_INS_ENDING}
1433  };
1434  if(!insn_match_find_next_seq(fw,is,10,match_bl_strh)) {
1435  printf("sig_match_get_current_nd_value: match failed\n");
1436  return 0;
1437  }
1438  // rewind one for call
1439  disasm_iter_init(fw,is,adr_hist_get(&is->ah,1));
1440  disasm_iter(fw,is);
1441  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1442 }
int sig_match_get_dial_hw_position ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1814 der Datei finsig_thumb2.c.

1815 {
1816  if(!init_disasm_sig_ref(fw,is,rule)) {
1817  return 0;
1818  }
1819  uint32_t adr = find_last_call_from_func(fw,is,18,50);
1820  if(!adr) {
1821  // printf("sig_match_get_dial_hw_position: no match call 1 at 0x%"PRIx64"\n",is->insn->address);
1822  return 0;
1823  }
1824  // follow
1825  disasm_iter_init(fw,is,adr);
1826  adr = find_last_call_from_func(fw,is,16,32);
1827  if(!adr) {
1828  // printf("sig_match_get_dial_hw_position: no match call 2 at 0x%"PRIx64"\n",is->insn->address);
1829  return 0;
1830  }
1831  // follow
1832  disasm_iter_init(fw,is,adr);
1833  // find next function call
1834  if(!insn_match_find_next(fw,is,30,match_bl_blximm)) {
1835  // printf("sig_match_get_dial_hw_position: no match call 3 at 0x%"PRIx64"\n",is->insn->address);
1836  return 0;
1837  }
1838  uint32_t fadr = get_branch_call_insn_target(fw,is);
1839  // rewind and match instructions for sanity check
1840  disasm_iter_init(fw,is,adr_hist_get(&is->ah,4));
1841  const insn_match_t match_hw_dial_call[]={
1843  {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0),MATCH_OP_MEM_BASE(PC)}},
1845  {ARM_INS_ENDING}
1846  };
1847  if(!insn_match_find_next(fw,is,4,match_hw_dial_call)) {
1848  // printf("sig_match_get_dial_hw_position: no match seq 0x%"PRIx64"\n",is->insn->address);
1849  return 0;
1850  }
1851  return save_sig_with_j(fw,rule->name,fadr);
1852 }
int sig_match_get_drive_cluster_size ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2529 der Datei finsig_thumb2.c.

2530 {
2531  if(!init_disasm_sig_ref(fw,is,rule)) {
2532  return 0;
2533  }
2534  // only handle first match, don't expect multiple refs to string
2535  if(fw_search_insn(fw,is,search_disasm_str_ref,0,"A/OpLogErr.txt",(uint32_t)is->adr+260)) {
2536  // find first call after string ref
2537  if(!insn_match_find_next(fw,is,3,match_bl_blximm)) {
2538  // printf("sig_match_get_drive_cluster_size: bl not found\n");
2539  return 0;
2540  }
2541  // follow
2543  // find second call
2544  if(!insn_match_find_nth(fw,is,13,2,match_bl_blximm)) {
2545  // printf("sig_match_get_drive_cluster_size: call 1 not found\n");
2546  return 0;
2547  }
2548  // follow
2550  disasm_iter(fw,is);
2551  if (B_target(fw, is->insn))
2553  // find next call
2554  if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
2555  // printf("sig_match_get_drive_cluster_size: call 2 not found\n");
2556  return 0;
2557  }
2558  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2559  }
2560  return 0;
2561 }
int sig_match_get_kbd_state ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1790 der Datei finsig_thumb2.c.

1791 {
1792  if(!init_disasm_sig_ref(fw,is,rule)) {
1793  return 0;
1794  }
1795  // instructions that zero out physw_status
1796  insn_match_t match[]={
1797  {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM_BASE(PC)}},
1799  {ARM_INS_ENDING}
1800  };
1801 
1802  if(!insn_match_find_next_seq(fw,is,11,match)) {
1803  return 0;
1804  }
1805  save_sig_with_j(fw,"GetKbdState",get_branch_call_insn_target(fw,is));
1806  // look for kbd_read_keys_r2
1807  if(!insn_match_find_next(fw,is,5,match_b_bl_blximm)) {
1808  return 0;
1809  }
1810  save_sig_with_j(fw,"kbd_read_keys_r2",get_branch_call_insn_target(fw,is));
1811  return 1;
1812 }
int sig_match_get_nd_value ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1354 der Datei finsig_thumb2.c.

1355 {
1356  // this match is only valid for cameras with both ND and Iris
1357  if(!get_misc_val_value("CAM_HAS_ND_FILTER") || !get_misc_val_value("CAM_HAS_IRIS_DIAPHRAGM")) {
1358  return 0;
1359  }
1360 
1361  if(!init_disasm_sig_ref(fw,is,rule)) {
1362  return 0;
1363  }
1364  if(!find_next_sig_call(fw,is,16,"ClearEventFlag")) {
1365  printf("sig_match_get_nd_value: no match ClearEventFlag\n");
1366  return 0;
1367  }
1368  if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
1369  printf("sig_match_get_nd_value: bl match 1 failed\n");
1370  return 0;
1371  }
1372  // follow
1374  disasm_iter(fw,is);
1375  if (B_target(fw,is->insn))
1377  // first call should be either get_nd_value or GetUsableAvRange
1378  if(!insn_match_find_next(fw,is,5,match_bl_blximm)) {
1379  printf("sig_match_get_nd_value: bl match 2 failed\n");
1380  return 0;
1381  }
1383  if(addr == get_saved_sig_val("GetUsableAvRange")) {
1384  printf("sig_match_get_nd_value: found GetUsableAvRange, iris or ND only?\n");
1385  return 0;
1386  }
1387  return save_sig_with_j(fw,rule->name,addr);
1388 }
int sig_match_get_num_posted_messages ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3088 der Datei finsig_thumb2.c.

3089 {
3090  if(!init_disasm_sig_ref(fw,is,rule)) {
3091  return 0;
3092  }
3093  if(!find_next_sig_call(fw,is,50,"TakeSemaphore")) {
3094  printf("sig_match_get_num_posted_messages: failed to find TakeSemaphore\n");
3095  return 0;
3096  }
3097  // find next call
3098  if(!insn_match_find_next(fw,is,5,match_bl_blximm)) {
3099  printf("sig_match_get_num_posted_messages: no match bl 0x%"PRIx64"\n",is->insn->address);
3100  return 0;
3101  }
3102  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3103 }
int sig_match_get_parameter_data ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2670 der Datei finsig_thumb2.c.

2671 {
2672  if(!init_disasm_sig_ref(fw,is,rule)) {
2673  return 0;
2674  }
2675  const insn_match_t match_cmp_bhs[]={
2678  {ARM_INS_ENDING}
2679  };
2680  if(!insn_match_find_next_seq(fw,is,4,match_cmp_bhs)) {
2681  // printf("sig_match_get_parameter_data: no match cmp, bhs\n");
2682  return 0;
2683  }
2684  // follow
2686  if(!insn_match_find_next(fw,is,1,match_b)) {
2687  // printf("sig_match_get_parameter_data: no match b\n");
2688  return 0;
2689  }
2690  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2691 }
int sig_match_get_rom_id ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 4006 der Datei finsig_thumb2.c.

4007 {
4008  if(!init_disasm_sig_ref(fw,is,rule)) {
4009  return 0;
4010  }
4011  // two variants, overlapping dryos versions
4012  if(!disasm_iter(fw,is)) {
4013  printf("sig_match_get_rom_id: disasm failed\n");
4014  return 0;
4015  }
4016  if(is->insn->id == ARM_INS_MOV) {
4017  if(!disasm_iter(fw,is)) {
4018  printf("sig_match_get_rom_id: disasm failed\n");
4019  return 0;
4020  }
4021  if(is->insn->id != ARM_INS_B) {
4022  printf("sig_match_get_rom_id: no b\n");
4023  return 0;
4024  }
4025  } else if(is->insn->id == ARM_INS_PUSH) {
4026  const insn_match_t match_seq[]={
4028  {MATCH_INS(BL, 1), {MATCH_OP_IMM_ANY}},
4032  {ARM_INS_ENDING}
4033  };
4034  if(!insn_match_find_next_seq(fw,is,1,match_seq)) {
4035  printf("sig_match_get_rom_id: no seq\n");
4036  return 0;
4037  }
4038  } else {
4039  printf("sig_match_get_rom_id: no match first insn\n");
4040  return 0;
4041  }
4042  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
4043 }
int sig_match_get_semaphore_value ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1937 der Datei finsig_thumb2.c.

1938 {
1939  uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
1940  if(!str_adr) {
1941  printf("sig_get_semaphore_value: failed to find ref %s\n",rule->ref_name);
1942  return 0;
1943  }
1944 
1945  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
1946  // assume first / only ref
1948  // printf("sig_get_semaphore_value: failed to find code ref to %s\n",rule->ref_name);
1949  return 0;
1950  }
1951  // search backwards for func call
1952  uint32_t fadr=0;
1953  int i;
1954  for(i=1; i<=5; i++) {
1955  if(!fw_disasm_iter_single(fw,adr_hist_get(&is->ah,i))) {
1956  // printf("sig_get_semaphore_value: disasm failed\n");
1957  return 0;
1958  }
1960  fadr=get_branch_call_insn_target(fw,fw->is);
1961  break;
1962  }
1963  }
1964  if(!fadr) {
1965  // printf("sig_get_semaphore_value: failed to find bl 1\n");
1966  return 0;
1967  }
1968  // follow
1969  disasm_iter_init(fw,is,fadr);
1970  // look for first call
1971  if(!insn_match_find_next(fw,is,9,match_bl_blximm)) {
1972  // printf("sig_get_semaphore_value: failed to find bl 2\n");
1973  return 0;
1974  }
1975  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1976 }
int sig_match_get_task_properties ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3604 der Datei finsig_thumb2.c.

3605 {
3606  if(!init_disasm_sig_ref(fw,is,rule)) {
3607  return 0;
3608  }
3609  if(fw_search_insn(fw,is,search_disasm_str_ref,0,"Occured Time %s\n",(uint32_t)is->adr+170)) {
3610  // expect printf function follow by call
3611  if(!find_next_sig_call(fw,is,16,"dry_error_printf")) {
3612  printf("get_task_properties: no match dry_error_printf 0x%"PRIx64"\n",is->insn->address);
3613  return 0;
3614  }
3615  if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
3616  printf("sig_match_get_task_properties: no match bl 0x%"PRIx64"\n",is->insn->address);
3617  return 0;
3618  }
3619  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3620  }
3621  printf("sig_match_get_task_properties: no match 'Occured Time' 0x%"PRIx64"\n",is->insn->address);
3622  return 0;
3623 }
int sig_match_icache_flush_range ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 4423 der Datei finsig_thumb2.c.

4424 {
4425  if(!init_disasm_sig_ref(fw,is,rule)) {
4426  printf("sig_match_icache_flush_range: missing ref\n");
4427  return 0;
4428  }
4429  if(!find_next_sig_call(fw,is,60,"DebugAssert")) {
4430  printf("sig_icache_flush_range: no match DebugAssert\n");
4431  return 0;
4432  }
4433  if(!find_next_sig_call(fw,is,44,"dcache_flush_range")) {
4434  printf("sig_icache_flush_range: no match DebugAssert\n");
4435  return 0;
4436  }
4437  if(!insn_match_find_next(fw,is,5,match_bl_blximm)) {
4438  printf("sig_icache_flush_range: bl match failed at 0x%"PRIx64"\n",is->insn->address);
4439  return 0;
4440  }
4441  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
4442 }
int sig_match_imager_active ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1497 der Datei finsig_thumb2.c.

1498 {
1499  if(!init_disasm_sig_ref(fw,is,rule)) {
1500  return 0;
1501  }
1502 
1503  const insn_match_t match_ldr_mov_str_pop[]={
1505  {MATCH_INS(MOV,2), {MATCH_OP_REG_ANY, MATCH_OP_IMM(1)}},
1508  {ARM_INS_ENDING}
1509  };
1510 
1511  int backtrack=3;
1512  if(!insn_match_find_next_seq(fw,is,10,match_ldr_mov_str_pop)) {
1513  // re-init and try reverse mov/ldr order
1514  init_disasm_sig_ref(fw,is,rule);
1515  const insn_match_t match_mov_ldr_str_pop[]={
1516  {MATCH_INS(MOV,2), {MATCH_OP_REG_ANY, MATCH_OP_IMM(1)}},
1520  {ARM_INS_ENDING}
1521  };
1522  if(!insn_match_find_next_seq(fw,is,10,match_mov_ldr_str_pop)) {
1523  printf("sig_match_imager_active: match failed\n");
1524  return 0;
1525  }
1526  backtrack=2;
1527  }
1528  // rewind to LDR
1529  disasm_iter_init(fw,is,adr_hist_get(&is->ah,backtrack));
1530  disasm_iter(fw,is);
1531  uint32_t base=LDR_PC2val(fw,is->insn);
1532  uint32_t reg=is->insn->detail->arm.operands[0].reg;
1533 // printf("base 0x%08x @0x%08x\n",base,(uint32_t)is->insn->address);
1534  // skip mov if after LDR
1535  if(backtrack == 3) {
1536  disasm_iter(fw,is);
1537  }
1538  disasm_iter(fw,is);
1539  // sanity check base is the same as LDR'd to
1540  if(is->insn->detail->arm.operands[1].mem.base != reg) {
1541  printf("sig_match_imager_active: reg mismatch\n");
1542  return 0;
1543  }
1544  uint32_t off=is->insn->detail->arm.operands[1].mem.disp;
1545 // printf("off 0x%08x @0x%08x\n",off,(uint32_t)is->insn->address);
1546  save_misc_val("imager_active",base,off,(uint32_t)is->insn->address);
1547  return 1;
1548 }
int sig_match_imager_active_callback ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1471 der Datei finsig_thumb2.c.

1472 {
1473  if(!init_disasm_sig_ref(fw,is,rule)) {
1474  return 0;
1475  }
1476  const insn_match_t match_ldr_bl_mov_pop[]={
1477  {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM_BASE(PC)}},
1479  {MATCH_INS(MOV,2), {MATCH_OP_REG(R0), MATCH_OP_IMM(0)}},
1481  {ARM_INS_ENDING}
1482  };
1483 
1484  if(!insn_match_find_next_seq(fw,is,28,match_ldr_bl_mov_pop)) {
1485  printf("sig_match_imager_active_callback: match failed\n");
1486  return 0;
1487  }
1488  // rewind to LDR r0,...
1489  disasm_iter_init(fw,is,adr_hist_get(&is->ah,3));
1490  // get LDR value
1491  disasm_iter(fw,is);
1492  uint32_t f1=LDR_PC2val(fw,is->insn);
1493 // printf("f1 0x%08x\n",f1);
1494  // thumb bit should be set correctly
1495  return save_sig_with_j(fw,rule->name,f1);
1496 }
int sig_match_init_error_handlers ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3534 der Datei finsig_thumb2.c.

3535 {
3536  if(!init_disasm_sig_ref(fw,is,rule)) {
3537  return 0;
3538  }
3539  if(!find_next_sig_call(fw,is,64,"init_ex_drivers")) {
3540  printf("sig_match_init_error_handlers: no match init_ex_drivers\n");
3541  return 0;
3542  }
3543  if(!insn_match_find_nth(fw,is,4,2,match_bl_blximm)) {
3544  printf("sig_match_init_error_handlers: no match bl\n");
3545  return 0;
3546  }
3547  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3548 }
int sig_match_init_ex_drivers ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3439 der Datei finsig_thumb2.c.

3440 {
3441  if(!init_disasm_sig_ref(fw,is,rule)) {
3442  return 0;
3443  }
3444  int i;
3445  int b_count;
3446  // search forward 32 instructions or 14 calls
3447  for(i=0, b_count = 0; i < 32 && b_count < 14; i++) {
3448  if (!disasm_iter(fw,is)) {
3449  printf("sig_match_init_ex_drivers: disasm failed 1\n");
3450  return 0;
3451  }
3452  uint32_t b_tgt = get_branch_call_insn_target(fw,is);
3453  if(!b_tgt) {
3454  continue;
3455  }
3456  b_count++;
3457  uint64_t next_adr = is->adr | is->thumb;
3458  disasm_iter_init(fw,is,b_tgt);
3459  if (!disasm_iter(fw,is)) {
3460  printf("sig_match_init_ex_drivers: disasm failed 2\n");
3461  return 0;
3462  }
3463  // expect the function we're looking for to start with a push
3464  if(is->insn->id == ARM_INS_PUSH) {
3465  if(find_next_sig_call(fw,is,30,"DebugAssert")) {
3466  uint32_t regs[4];
3467  if((get_call_const_args(fw,is,5,regs)&0x2)==0x2) {
3468  const char *str=(char *)adr2ptr(fw,regs[1]);
3469  if(str && strcmp(str,"InitExDrivers.c") == 0) {
3470  return save_sig_with_j(fw,rule->name,b_tgt);
3471  }
3472  }
3473  }
3474  }
3475  disasm_iter_init(fw,is,next_adr);
3476  }
3477  return 0;
3478 }
int sig_match_jpeg_count_str ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3778 der Datei finsig_thumb2.c.

3779 {
3780  uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
3781  if(!str_adr) {
3782  printf("sig_match_jpeg_count_str: failed to find ref %s\n",rule->ref_name);
3783  return 0;
3784  }
3785  // TODO should handle multiple instances of string
3786  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
3787  while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
3788  // printf("sig_match_jpeg_count_str: str match 0x%"PRIx64"\n",is->insn->address);
3789  if(!insn_match_find_next(fw,is,3,match_bl_blximm)) {
3790  // printf("sig_match_jpeg_count_str: no match bl\n");
3791  continue;
3792  }
3793  if(!is_sig_call(fw,is,"sprintf_FW")) {
3794  // printf("sig_match_jpeg_count_str: not sprintf_FW at 0x%"PRIx64"\n",is->insn->address);
3795  continue;
3796  }
3797  // expect ptr in r0, str in r1
3798  uint32_t regs[4];
3799  if((get_call_const_args(fw,is,5,regs)&0x3)!=0x3) {
3800  // printf("sig_match_jpeg_count_str: failed to get sprintf args 0x%"PRIx64"\n",is->insn->address);
3801  continue;
3802  }
3803  if(regs[1] != str_adr) {
3804  // printf("sig_match_jpeg_count_str: expected r1 == 0x%08x not 0x%08x at 0x%"PRIx64"\n",str_adr, regs[1],is->insn->address);
3805  return 0;
3806  }
3807  if(!adr_is_var(fw,regs[0])) {
3808  // printf("sig_match_jpeg_count_str: r0 == 0x%08x not var ptr at 0x%"PRIx64"\n",regs[0],is->insn->address);
3809  return 0;
3810  }
3811  save_misc_val(rule->name,regs[0],0,(uint32_t)is->insn->address);
3812  return 1;
3813  }
3814  return 0;
3815 }
int sig_match_kbd_read_keys ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1766 der Datei finsig_thumb2.c.

1767 {
1768  if(!init_disasm_sig_ref(fw,is,rule)) {
1769  return 0;
1770  }
1771  // look for kbd_read_keys
1772  if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
1773  return 0;
1774  }
1775  save_sig(fw,"kbd_read_keys",get_branch_call_insn_target(fw,is));
1776  if(!disasm_iter(fw,is)) {
1777  printf("sig_match_kbd_read_keys: disasm failed\n");
1778  return 0;
1779  }
1781  if(physw_status) {
1782  save_misc_val("physw_status",physw_status,0,(uint32_t)is->insn->address);
1783  save_sig(fw,"kbd_p1_f_cont",(uint32_t)(is->insn->address) | is->thumb);
1784  return 1;
1785  }
1786  return 0;
1787 }
int sig_match_levent_table ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3681 der Datei finsig_thumb2.c.

3682 {
3683  if(!init_disasm_sig_ref(fw,is,rule)) {
3684  return 0;
3685  }
3686  if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
3687  // printf("sig_match_levent_table: no match bl 0x%"PRIx64"\n",is->insn->address);
3688  return 0;
3689  }
3690  // follow
3692 
3693  // find first call of next function
3694  if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
3695  // printf("sig_match_levent_table: no match bl 0x%"PRIx64"\n",is->insn->address);
3696  return 0;
3697  }
3698 
3699  // follow
3701 
3702  // first instruction should load address
3703  disasm_iter(fw,is);
3704  uint32_t adr=LDR_PC2val(fw,is->insn);
3705  if(!adr) {
3706  // printf("sig_match_levent_table: no match LDR PC 0x%"PRIx64"\n",is->insn->address);
3707  return 0;
3708  }
3709  uint32_t *p=(uint32_t *)adr2ptr(fw,adr);
3710  if(!p) {
3711  printf("sig_match_levent_table: 0x%08x not a ROM adr 0x%"PRIx64"\n",adr,is->insn->address);
3712  return 0;
3713  }
3714  if(*(p+1) != 0x800) {
3715  printf("sig_match_levent_table: expected 0x800 not 0x%x at 0x%08x ref 0x%"PRIx64"\n",*(p+1),adr,is->insn->address);
3716  return 0;
3717  }
3718  // TODO saving the function might be useful for analysis
3719  save_misc_val(rule->name,adr,0,(uint32_t)is->insn->address);
3720  return 1;
3721 }
int sig_match_live_free_cluster_count ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 4780 der Datei finsig_thumb2.c.

4781 {
4782  if(!init_disasm_sig_ref(fw,is,rule)) {
4783  return 0;
4784  }
4785 
4786  // find third function call
4787  if(!insn_match_find_nth(fw,is,22,3,match_bl_blximm)) {
4788  printf("sig_match_live_free_cluster_count: no match bl1 0x%"PRIx64"\n",is->insn->address);
4789  return 0;
4790  }
4791  // follow
4793 
4794  if(!find_next_sig_call(fw,is,20,"get_fstype")) {
4795  printf("sig_match_live_free_cluster_count: no get_fstype 0x%"PRIx64"\n",is->insn->address);
4796  return 0;
4797  }
4798 
4799  // find second function call
4800  if(!insn_match_find_nth(fw,is,12,2,match_bl_blximm)) {
4801  printf("sig_match_live_free_cluster_count: no match bl2 0x%"PRIx64"\n",is->insn->address);
4802  return 0;
4803  }
4804 
4805  // follow
4807 
4808  // find second LDR [pc ..]
4809  if(!insn_match_find_next(fw,is,3,match_ldr_pc)) {
4810  printf("sig_match_live_free_cluster_count: no match ldr1 0x%"PRIx64"\n",is->insn->address);
4811  return 0;
4812  }
4813 
4814  if(!insn_match_find_next(fw,is,3,match_ldr_pc)) {
4815  printf("sig_match_live_free_cluster_count: no match ldr2 0x%"PRIx64"\n",is->insn->address);
4816  return 0;
4817  }
4818  uint32_t base = LDR_PC2val(fw,is->insn);
4819 
4820  if(!find_next_sig_call(fw,is,16,"takesemaphore_low")) {
4821  printf("sig_match_live_free_cluster_count: no takesemaphore_low 0x%"PRIx64"\n",is->insn->address);
4822  return 0;
4823  }
4824  const insn_match_t match_ldr_ldrd[]={
4825  {MATCH_INS(LDR, 2), {MATCH_OP_REG_ANY, MATCH_OP_ANY}},
4827  {ARM_INS_ENDING}
4828  };
4829 
4830  if(!insn_match_find_next_seq(fw,is,50,match_ldr_ldrd)) {
4831  printf("sig_match_live_free_cluster_count: no match ldrd 0x%"PRIx64"\n",is->insn->address);
4832  return 0;
4833  }
4834  // +4 because var is 2nd word of ldrd load
4835  save_misc_val(rule->name,base,is->insn->detail->arm.operands[2].mem.disp + 4,(uint32_t)is->insn->address);
4836  return 1;
4837 
4838 }
int sig_match_log ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2381 der Datei finsig_thumb2.c.

2382 {
2383  if(!init_disasm_sig_ref(fw,is,rule)) {
2384  return 0;
2385  }
2386  const insn_match_t match_pop6[]={
2387  {MATCH_INS(POP, 6), {MATCH_OP_REST_ANY}},
2388  {ARM_INS_ENDING}
2389  };
2390  // skip forward through 3x pop {r4, r5, r6, r7, r8, lr}
2391  if(!insn_match_find_nth(fw,is,38,3,match_pop6)) {
2392  return 0;
2393  }
2394  // third call
2395  if(!insn_match_find_nth(fw,is,24,3,match_bl_blximm)) {
2396  return 0;
2397  }
2398  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2399 }
int sig_match_log_camera_event ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1650 der Datei finsig_thumb2.c.

1651 {
1652  if(!init_disasm_sig_ref(fw,is,rule)) {
1653  return 0;
1654  }
1655  if(!insn_match_find_next(fw,is,6,match_bl_blximm)) {
1656  // printf("sig_match_log_camera_event: bl match failed\n");
1657  return 0;
1658  }
1659  uint32_t regs[4];
1660  if((get_call_const_args(fw,is,4,regs)&3)!=3) {
1661  // printf("sig_match_log_camera_event: get args failed\n");
1662  return 0;
1663  }
1664  if(regs[0] != 0x60) {
1665  // printf("sig_match_log_camera_event: bad r0 0x%x\n",regs[0]);
1666  return 0;
1667  }
1668  const char *str=(char *)adr2ptr(fw,regs[1]);
1669  if(!str || strcmp(str,"_SImage") != 0) {
1670  // printf("sig_match_log_camera_event: bad r1 0x%x\n",regs[1]);
1671  return 0;
1672  }
1673  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1674 }
int sig_match_misc_flag_named ( __attribute__((unused)) firmware fw,
__attribute__((unused)) iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3818 der Datei finsig_thumb2.c.

3819 {
3820  uint32_t ref=get_saved_sig_val(rule->ref_name);
3821  save_misc_val(rule->name,(ref)?1:0,0,ref);
3822  return 1;
3823 }
int sig_match_mkdir ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2787 der Datei finsig_thumb2.c.

2788 {
2789  if(!init_disasm_sig_ref(fw,is,rule)) {
2790  return 0;
2791  }
2792  const insn_match_t match[]={
2794  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R0), MATCH_OP_REG(SP)}},
2795  {MATCH_INS(LDR, 2), {MATCH_OP_REG(R1), MATCH_OP_MEM_BASE(SP)}},
2797  {ARM_INS_ENDING}
2798  };
2799  if(insn_match_find_next_seq(fw,is,148,match)) {
2800  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2801  }
2802 
2803  init_disasm_sig_ref(fw,is,rule);
2804  const insn_match_t match2[]={
2805  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R1), MATCH_OP_REG_ANY}},
2807  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R0), MATCH_OP_REG(SP)}},
2809  {ARM_INS_ENDING}
2810  };
2811  if(!insn_match_find_next_seq(fw,is,148,match2)) {
2812  //printf("sig_match_mkdir: no match\n");
2813  return 0;
2814  }
2815  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2816 }
int sig_match_mktime_ext ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2563 der Datei finsig_thumb2.c.

2564 {
2565  uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2566  if(!str_adr) {
2567  printf("sig_match_mktime_ext: failed to find ref %s\n",rule->ref_name);
2568  return 0;
2569  }
2570  // TODO should handle multiple instances of string
2571  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
2572  while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2573  // expect sscanf after str
2574  if(!find_next_sig_call(fw,is,12,"sscanf_FW")) {
2575  // printf("sig_match_mktime_ext: no sscanf\n");
2576  return 0;
2577  }
2578  // find next call
2579  if(!insn_match_find_next(fw,is,22,match_bl_blximm)) {
2580  // printf("sig_match_mktime_ext: no call\n");
2581  return 0;
2582  }
2583  // follow
2585  if(!disasm_iter(fw,is)) {
2586  printf("sig_match_mktime_ext: disasm failed\n");
2587  return 0;
2588  }
2589  uint32_t j_tgt=get_direct_jump_target(fw,is);
2590  // veneer?
2591  if(j_tgt) {
2592  // follow
2593  disasm_iter_init(fw,is,j_tgt);
2594  if(!disasm_iter(fw,is)) {
2595  printf("sig_match_mktime_ext: disasm failed\n");
2596  return 0;
2597  }
2598  }
2599  const insn_match_t match_pop4[]={
2600  {MATCH_INS(POP, 4), {MATCH_OP_REST_ANY}},
2601  {MATCH_INS(POP, 6), {MATCH_OP_REST_ANY}},
2602  {ARM_INS_ENDING}
2603  };
2604 
2605  // find pop
2606  if(!insn_match_find_next(fw,is,54,match_pop4)) {
2607  // printf("sig_match_mktime_ext: no pop\n");
2608  return 0;
2609  }
2610  if(!insn_match_find_next(fw,is,1,match_b)) {
2611  // printf("sig_match_mktime_ext: no b\n");
2612  return 0;
2613  }
2614  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2615  }
2616  return 0;
2617 }
int sig_match_mzrm_sendmsg_ret_adr ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 4924 der Datei finsig_thumb2.c.

4925 {
4926  if(!find_str_arg_call(fw,is,rule)) {
4927  printf("sig_match_mzrm_sendmsg_ret_adr: no match call\n");
4928  return 0;
4929  }
4930  if(!disasm_iter(fw,is)) {
4931  printf("sig_match_mzrm_sendmsg_ret_adr: disasm failed\n");
4932  return 0;
4933  }
4934  // address after blx, thumb bit set for current state
4935  save_misc_val(rule->name,(uint32_t)is->insn->address | is->thumb,0,0);
4936  return 1;
4937 }
int sig_match_named ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 5278 der Datei finsig_thumb2.c.

5279 {
5280  uint32_t ref_adr = get_saved_sig_val(rule->ref_name);
5281  if(!ref_adr) {
5282  printf("sig_match_named: missing %s\n",rule->ref_name);
5283  return 0;
5284  }
5285  uint32_t sig_type = rule->param & SIG_NAMED_TYPE_MASK;
5286  uint32_t sig_flags = rule->param & SIG_NAMED_FLAG_MASK;
5289  if(!sig_nth) {
5290  sig_nth=1;
5291  }
5292  if(!sig_nth_range) {
5293  sig_nth_range=5;
5294  }
5295  // no offset, just save match as is
5296  // TODO might want to validate anyway
5297  if(sig_type == SIG_NAMED_ASIS) {
5298  return sig_match_named_save_sig(fw,rule->name,ref_adr,sig_flags);
5299  }
5300  const insn_match_t *insn_match;
5301  if(sig_type == SIG_NAMED_JMP_SUB) {
5302  insn_match = match_b_bl_blximm;
5303  } else if(sig_type == SIG_NAMED_SUB) {
5304  insn_match = match_bl_blximm;
5305  } else if(sig_type == SIG_NAMED_INSN) {
5306  insn_match = NULL;
5307  } else {
5308  printf("sig_match_named: %s invalid type %d\n",rule->ref_name,sig_type);
5309  return 0;
5310  }
5311 
5312  disasm_iter_init(fw,is,ref_adr);
5313  // TODO for eventprocs, may just want to use the original
5314  if(is_immediate_ret_sub(fw,is)) {
5315  printf("sig_match_named: immediate return %s\n",rule->name);
5316  return 0;
5317  }
5318  if(sig_type == SIG_NAMED_INSN) {
5319  uint32_t i;
5320  // iter starts on the address given to init
5321  for(i=0;i<=sig_nth;i++) {
5322  if(!disasm_iter(fw,is)) {
5323  printf("sig_match_named: disasm failed %s 0x%08x\n",rule->name,(uint32_t)is->insn->address);
5324  return 0;
5325  }
5326  }
5327  return sig_match_named_save_sig(fw,rule->name,iter_state_adr(is),sig_flags);
5328  }
5329 
5330  // initial 15 is hard coded
5331  if(insn_match_find_nth(fw,is,15 + sig_nth_range*sig_nth,sig_nth,insn_match)) {
5332  uint32_t adr = B_BL_BLXimm_target(fw,is->insn);
5333  if(adr) {
5334  // BLX, set thumb bit
5335  if(is->insn->id == ARM_INS_BLX) {
5336  // curently not thumb, set in target
5337  if(!is->thumb) {
5338  adr=ADR_SET_THUMB(adr);
5339  }
5340  } else {
5341  // preserve current state
5342  adr |= is->thumb;
5343  }
5344  return sig_match_named_save_sig(fw,rule->name,adr,sig_flags);
5345  } else {
5346  printf("sig_match_named: %s invalid branch target 0x%08x\n",rule->ref_name,adr);
5347  }
5348  } else {
5349  printf("sig_match_named: %s branch not found 0x%08x\n",rule->ref_name,ref_adr);
5350  }
5351  return 0;
5352 }
int sig_match_named_last ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 5216 der Datei finsig_thumb2.c.

5217 {
5218  uint32_t ref_adr = get_saved_sig_val(rule->ref_name);
5220  int max = (rule->param&SIG_NAMED_LAST_MAX_MASK);
5221  if(!ref_adr) {
5222  printf("sig_match_named_last: %s missing %s\n",rule->name,rule->ref_name);
5223  return 0;
5224  }
5225  disasm_iter_init(fw,is,ref_adr);
5226  if(is_immediate_ret_sub(fw,is)) {
5227  printf("sig_match_named_last: immediate return %s\n",rule->name);
5228  return 0;
5229  }
5230  uint32_t fadr = find_last_call_from_func(fw,is,min,max);
5231  if(fadr) {
5232  return save_sig_with_j(fw,rule->name,fadr);
5233  }
5234  return 0;
5235 }
int sig_match_named_save_sig ( firmware fw,
const char *  name,
uint32_t  adr,
uint32_t  flags 
)

Definiert in Zeile 5263 der Datei finsig_thumb2.c.

5264 {
5265  adr = save_sig_veneers(fw, name, adr);
5266  if(adr) {
5267  if(flags & SIG_NAMED_CLEARTHUMB) {
5268  adr = ADR_CLEAR_THUMB(adr);
5269  }
5270  save_sig(fw,name,adr);
5271  return 1;
5272  }
5273  return 0;
5274 }
int sig_match_near_str ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 5084 der Datei finsig_thumb2.c.

5085 {
5086  if (!get_saved_sig_val(rule->name))
5087  {
5088  uint32_t call_adr = find_call_near_str(fw,is,rule);
5089  if(call_adr) {
5090  return save_sig_match_call(fw, rule, call_adr);
5091  }
5092  }
5093  return 0;
5094 }
int sig_match_omar_init ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3480 der Datei finsig_thumb2.c.

3481 {
3482  if(!init_disasm_sig_ref(fw,is,rule)) {
3483  return 0;
3484  }
3485  uint32_t fadr = find_last_call_from_func(fw,is,20,42);
3486  if(!fadr) {
3487  printf("sig_match_omar_init: no match call\n");
3488  return 0;
3489  }
3490  // follow
3491  disasm_iter_init(fw,is,fadr);
3492  if(!find_next_sig_call(fw,is,44,"dry_memcpy")) {
3493  printf("sig_match_omar_init: no match dry_memcpy\n");
3494  return 0;
3495  }
3496  uint32_t regs[4];
3497  // expect dry_memcpy(stack ptr,rom ptr, 0x18)
3498  if((get_call_const_args(fw,is,5,regs)&0x6)!=0x6) {
3499  printf("sig_match_omar_init: no match dry_memcpy args 1\n");
3500  return 0;
3501  }
3502  if(regs[2] != 0x18 || !adr2ptr(fw,regs[1])) {
3503  printf("sig_match_omar_init: no match dry_memcpy args 2\n");
3504  return 0;
3505  }
3506  uint32_t dadr = regs[1];
3507  save_misc_val("omar_init_data",dadr,0,(uint32_t)is->insn->address);
3508  misc_blob_t *blobs=malloc(3*sizeof(misc_blob_t));
3509  int i;
3510  for(i = 0; i<2; i++) {
3511  uint32_t dst = fw_u32(fw,dadr + i*12);
3512  uint32_t src = fw_u32(fw,dadr + i*12 + 4);
3513  uint32_t bsize = fw_u32(fw,dadr + i*12 + 8);
3514  if(src && dst && bsize) {
3515  blobs[i].type = MISC_BLOB_TYPE_OMAR;
3516  blobs[i].rom_adr = src;
3517  blobs[i].ram_adr = dst;
3518  blobs[i].size = bsize;
3519  } else {
3520  printf("sig_match_omar_init: invalid blobs\n");
3521  free(blobs);
3522  blobs = NULL;
3523  break;
3524  }
3525  }
3526  if(blobs) {
3527  blobs[2].type = MISC_BLOB_TYPE_NONE;
3528  save_misc_val_blobs("omar_init_values",blobs,0);
3529  }
3530 
3531  return save_sig_with_j(fw,rule->name,fadr);
3532 }
int sig_match_open ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2014 der Datei finsig_thumb2.c.

2015 {
2016  if(!init_disasm_sig_ref(fw,is,rule)) {
2017  return 0;
2018  }
2020  return 0;
2021  }
2022  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2023 }
int sig_match_palette_vars ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 4686 der Datei finsig_thumb2.c.

4687 {
4688  if(!init_disasm_sig_ref(fw,is,rule)) {
4689  return 0;
4690  }
4691  if(!find_next_sig_call(fw,is,70,"transfer_src_overlay")) {
4692  printf("sig_match_palette_vars: no match transfer_src_overlay\n");
4693  return 0;
4694  }
4695  uint32_t fadr=0;
4696  int i;
4697  // search backwards for call before transfer_src_overlay
4698  for(i=1; i<=6; i++) {
4699  if(!fw_disasm_iter_single(fw,adr_hist_get(&is->ah,i))) {
4700  printf("sig_match_palette_vars: disasm failed\n");
4701  return 0;
4702  }
4703  fadr=get_branch_call_insn_target(fw,fw->is);
4704  if(fadr) {
4705  break;
4706  }
4707  }
4708  if(!fadr) {
4709  printf("sig_match_palette_vars: no match bl 1 0x%"PRIx64"\n",fw->is->insn->address);
4710  return 0;
4711  }
4712  // follow
4713  disasm_iter_init(fw,is,fadr);
4714  // find first func call
4715  if(!insn_match_find_next(fw,is,3,match_bl)) {
4716  printf("sig_match_palette_vars: no match bl 2 0x%"PRIx64"\n",is->insn->address);
4717  return 0;
4718  }
4719  // follow
4721 
4722  if(!insn_match_find_next(fw,is,3,match_ldr_pc)) {
4723  printf("sig_match_palette_vars: no match ldr pc 0x%"PRIx64"\n",is->insn->address);
4724  return 0;
4725  }
4726 
4727  uint32_t pal_base=LDR_PC2val(fw,is->insn);
4728  if(!pal_base || !adr_is_var(fw,pal_base)) {
4729  printf("sig_match_palette_vars: bad LDR PC 0x%"PRIx64"\n",is->insn->address);
4730  return 0;
4731  }
4732  // palette_control is at the start of struct, save register
4733  arm_reg ptr_reg = is->insn->detail->arm.operands[0].reg;
4734 
4735  save_misc_val(rule->name,pal_base,0,(uint32_t)is->insn->address);
4736 
4737  int found=0;
4738  // find LDR Rn [ptr_reg +x]
4739  for(i=0; i<3; i++) {
4740  if(!disasm_iter(fw,is)) {
4741  printf("sig_match_palette_vars: disasm failed\n");
4742  return 0;
4743  }
4744  if (is->insn->id == ARM_INS_LDR && is->insn->detail->arm.operands[1].mem.base == ptr_reg) {
4745  save_misc_val("active_palette_buffer",
4746  pal_base,
4747  is->insn->detail->arm.operands[1].mem.disp,
4748  (uint32_t)is->insn->address);
4749  found=1;
4750  break;
4751  }
4752  }
4753  if(!found) {
4754  printf("sig_match_palette_vars: no match active_palette_buffer 0x%"PRIx64"\n",is->insn->address);
4755  return 0;
4756  }
4757 
4758  if(!find_next_sig_call(fw,is,20,"PTM_RestoreUIProperty_FW")) {
4759  printf("sig_match_palette_vars: no match PTM_RestoreUIProperty_FW\n");
4760  return 0;
4761  }
4762  // find LDR Rn [ptr_reg +x]
4763  for(i=0; i<6; i++) {
4764  if(!disasm_iter(fw,is)) {
4765  printf("sig_match_palette_vars: disasm failed\n");
4766  return 0;
4767  }
4768  if (is->insn->id == ARM_INS_LDR && is->insn->detail->arm.operands[1].mem.base == ptr_reg) {
4769  save_misc_val("palette_buffer_ptr",
4770  pal_base,
4771  is->insn->detail->arm.operands[1].mem.disp,
4772  (uint32_t)is->insn->address);
4773  return 1;
4774  }
4775  }
4776  printf("sig_match_palette_vars: no match palette_buffer_ptr 0x%"PRIx64"\n",is->insn->address);
4777  return 0;
4778 }
int sig_match_physw_event_table ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 4076 der Datei finsig_thumb2.c.

4077 {
4078  if(!init_disasm_sig_ref(fw,is,rule)) {
4079  return 0;
4080  }
4081  // expect first LDR pc
4082  if(!insn_match_find_next(fw,is,5,match_ldr_pc)) {
4083  printf("sig_match_physw_event_table: match LDR PC failed\n");
4084  return 0;
4085  }
4086  uint32_t adr=LDR_PC2val(fw,is->insn);
4087  if(!adr) {
4088  printf("sig_match_physw_event_table: no match LDR PC 0x%"PRIx64"\n",is->insn->address);
4089  return 0;
4090  }
4091  if(!adr2ptr(fw,adr)) {
4092  printf("sig_match_physw_event_table: adr not ROM 0x%08x at 0x%"PRIx64"\n",adr,is->insn->address);
4093  return 0;
4094  }
4095  save_misc_val(rule->name,adr,0,(uint32_t)is->insn->address);
4096  return 1;
4097 }
int sig_match_physw_misc ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1677 der Datei finsig_thumb2.c.

1678 {
1679  if(!init_disasm_sig_ref(fw,is,rule)) {
1680  osig* ostub2 = find_sig(fw->sv->stubs,rule->ref_name);
1681  if (ostub2 && ostub2->val)
1682  {
1683  disasm_iter_init(fw,is,ostub2->val);
1684  }
1685  else
1686  {
1687  return 0;
1688  }
1689  }
1690  int i;
1691  uint32_t physw_run=0;
1692  for(i=0; i<3; i++) {
1693  if(!disasm_iter(fw,is)) {
1694  printf("sig_match_physw_misc: disasm failed\n");
1695  return 0;
1696  }
1697  physw_run=LDR_PC2val(fw,is->insn);
1698  if(physw_run) {
1699  if(adr_is_var(fw,physw_run)) {
1700  save_misc_val("physw_run",physw_run,0,(uint32_t)is->insn->address);
1701  break;
1702  } else {
1703  printf("sig_match_physw_misc: adr not data? 0x%08x\n",physw_run);
1704  return 0;
1705  }
1706  }
1707  }
1708  if(!physw_run) {
1709  return 0;
1710  }
1711 
1712  // look for physw_sleep_delay, offset from physw_run, loaded before SleepTask
1713  if(!insn_match_find_next(fw,is,7,match_bl_blximm)) {
1714  return 0;
1715  }
1716  uint32_t sleeptask=get_saved_sig_val("SleepTask");
1717  if(!sleeptask) {
1718  printf("sig_match_physw_misc: missing SleepTask\n");
1719  return 0;
1720  }
1722 
1723  // call wasn't direct, check for veneer
1724  if(f != sleeptask) {
1725  fw_disasm_iter_single(fw,f);
1726  uint32_t f2=get_direct_jump_target(fw,fw->is);
1727  if(f2 != sleeptask) {
1728  return 0;
1729  }
1730  // sleeptask veneer is useful for xref
1731  // re-adding existing won't hurt
1732  save_sig_with_j(fw,"SleepTask",f);
1733  }
1734  // rewind 1 for r0
1735  disasm_iter_init(fw,is,adr_hist_get(&is->ah,1));
1736  if(!disasm_iter(fw,is)) {
1737  printf("sig_match_physw_misc: disasm failed\n");
1738  return 0;
1739  }
1740  // TODO could check base is same reg physw_run was loaded into
1741  if(is->insn->id != ARM_INS_LDR
1742  || is->insn->detail->arm.operands[0].reg != ARM_REG_R0) {
1743  return 0;
1744  }
1745  save_misc_val("physw_sleep_delay",physw_run,is->insn->detail->arm.operands[1].mem.disp,(uint32_t)is->insn->address);
1746  // skip over sleeptask to next insn
1747  if(!disasm_iter(fw,is)) {
1748  printf("sig_match_physw_misc: disasm failed\n");
1749  return 0;
1750  }
1751 
1752  // look for kbd_p1_f
1753  if(!insn_match_find_next(fw,is,2,match_bl_blximm)) {
1754  return 0;
1755  }
1756  save_sig(fw,"kbd_p1_f",get_branch_call_insn_target(fw,is));
1757 
1758  // look for kbd_p2_f
1759  if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
1760  return 0;
1761  }
1762  save_sig(fw,"kbd_p2_f",get_branch_call_insn_target(fw,is));
1763  return 1;
1764 }
int sig_match_pow_dry_52 ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2402 der Datei finsig_thumb2.c.

2403 {
2404  if (fw->dryos_ver != 52) {
2405  return 0;
2406  }
2407  if(!init_disasm_sig_ref(fw,is,rule)) {
2408  return 0;
2409  }
2410  const insn_match_t match_ldrd_r0_r1[]={
2412  {ARM_INS_ENDING}
2413  };
2414  // skip forward to first ldrd r0, r1, [r...]
2415  if(!insn_match_find_next(fw,is,50,match_ldrd_r0_r1)) {
2416  return 0;
2417  }
2418  // prevent false positive
2419  if(is->insn->detail->arm.operands[2].mem.base == ARM_REG_SP) {
2420  return 0;
2421  }
2422  if(!disasm_iter(fw,is)) {
2423  printf("sig_match_pow: disasm failed\n");
2424  return 0;
2425  }
2427  if(!adr) {
2428  return 0;
2429  }
2430  return save_sig_with_j(fw,rule->name,adr);
2431 }
int sig_match_pow_dry_gt_52 ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2434 der Datei finsig_thumb2.c.

2435 {
2436  if (fw->dryos_ver <= 52) {
2437  return 0;
2438  }
2439  if(!init_disasm_sig_ref(fw,is,rule)) {
2440  return 0;
2441  }
2442  const insn_match_t match1a[]={
2443  {MATCH_INS(LDRSH, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM(SP,INVALID,0x12)}},
2444  {MATCH_INS(LDRD, 3), {MATCH_OP_REG(R2), MATCH_OP_REG(R3), MATCH_OP_MEM(SP,INVALID,0x20)}},
2445  {MATCH_INS(STR, 2), {MATCH_OP_REG_ANY, MATCH_OP_MEM(SP,INVALID,0)}},
2447  {ARM_INS_ENDING}
2448  };
2449  const insn_match_t match1b[]={
2450  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R2), MATCH_OP_REG(R7)}},
2451  {MATCH_INS(LDRSH, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM(SP,INVALID,0x12)}},
2452  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R3), MATCH_OP_REG(R6)}},
2453  {MATCH_INS(STR, 2), {MATCH_OP_REG_ANY, MATCH_OP_MEM(SP,INVALID,0)}},
2455  {ARM_INS_ENDING}
2456  };
2457  const insn_match_t* match1[]={ match1a, match1b };
2458  int idx;
2459  for (idx = 0; idx < 2; idx += 1)
2460  {
2461  // match above sequence
2462  if(insn_match_find_next_seq(fw,is,50,match1[idx]))
2463  break;
2464  init_disasm_sig_ref(fw,is,rule);
2465  }
2466  // check for match
2467  if (idx >= 2)
2468  return 0;
2469  // match above sequence
2471  if(!adr) {
2472  return 0;
2473  }
2474  // follow bl
2475  disasm_iter_init(fw,is,adr);
2476  const insn_match_t match2a[]={
2478  {MATCH_INS(BLX, 1), {MATCH_OP_IMM_ANY}},
2479  {ARM_INS_ENDING}
2480  };
2481  const insn_match_t match2b[]={
2482  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R2), MATCH_OP_REG(R0)}},
2483  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R3), MATCH_OP_REG(R1)}},
2484  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R4), MATCH_OP_IMM(0x40000000)}},
2485  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM(0)}},
2486  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R1), MATCH_OP_REG(R4)}},
2487  {MATCH_INS(BL, 1), {MATCH_OP_IMM_ANY}},
2488  {ARM_INS_ENDING}
2489  };
2490  const insn_match_t* match2[]={ match2a, match2b };
2491  // match above sequence
2492  if(!insn_match_find_next_seq(fw,is,15,match2[idx])) {
2493  return 0;
2494  }
2495  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2496 }
int sig_match_prepdir_0 ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2750 der Datei finsig_thumb2.c.

2751 {
2752  if(!init_disasm_sig_ref(fw,is,rule)) {
2753  return 0;
2754  }
2755  uint32_t ref_pdx=get_saved_sig_val("PrepareDirectory_x");
2756  if(!ref_pdx) {
2757  printf("sig_match_prepdir_0: missing PrepareDirectory_x\n");
2758  return 0;
2759  }
2760  // skip over, assume validated previously
2761  disasm_iter(fw,is);
2762  disasm_iter(fw,is);
2763  // this should be the start address of our function
2764  uint32_t adr=(uint32_t)is->adr|is->thumb;
2765  const insn_match_t match_mov_r1_1[]={
2766  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R1), MATCH_OP_IMM(0)}},
2767 #if CS_API_MAJOR < 4
2768  {MATCH_INS(MOVS, 2), {MATCH_OP_REG(R1), MATCH_OP_IMM(0)}},
2769 #endif
2770  {ARM_INS_ENDING}
2771  };
2772  if(!insn_match_find_next(fw,is,1,match_mov_r1_1)) {
2773  //printf("sig_match_prepdir_0: no match mov\n");
2774  return 0;
2775  }
2776  if(!insn_match_find_next(fw,is,1,match_b)) {
2777  //printf("sig_match_prepdir_0: no match b\n");
2778  return 0;
2779  }
2781  if(pdx != ref_pdx) {
2782  //printf("sig_match_prepdir_0: target 0x%08x != 0x%08x\n",pdx,ref_pdx);
2783  return 0;
2784  }
2785  return save_sig_with_j(fw,rule->name,adr);
2786 }
int sig_match_prepdir_1 ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2722 der Datei finsig_thumb2.c.

2723 {
2724  uint32_t call_adr = find_call_near_str(fw,is,rule);
2725  if(call_adr) {
2726  disasm_iter_init(fw,is,call_adr);
2727  disasm_iter(fw,is);
2728  disasm_iter(fw,is);
2729  if (!CBx_target(fw,is->insn))
2730  {
2731  rule->param = SIG_NEAR_BEFORE(20,5);
2732  call_adr = find_call_near_str(fw,is,rule);
2733  if(!call_adr) {
2734  return 0;
2735  }
2736  disasm_iter_init(fw,is,call_adr);
2737  disasm_iter(fw,is);
2738  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2739  }
2740  }
2741 
2742  rule->param = SIG_NEAR_BEFORE(7,2);
2743  call_adr = find_call_near_str(fw,is,rule);
2744  if(!call_adr) {
2745  return 0;
2746  }
2747  return save_sig_match_call(fw, rule, call_adr);
2748 }
int sig_match_prepdir_x ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2696 der Datei finsig_thumb2.c.

2697 {
2698  if(!init_disasm_sig_ref(fw,is,rule)) {
2699  return 0;
2700  }
2701  const insn_match_t match_mov_r1_1[]={
2702  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R1), MATCH_OP_IMM(1)}},
2703 #if CS_API_MAJOR < 4
2704  {MATCH_INS(MOVS, 2), {MATCH_OP_REG(R1), MATCH_OP_IMM(1)}},
2705 #endif
2706  {ARM_INS_ENDING}
2707  };
2708  if(!insn_match_find_next(fw,is,1,match_mov_r1_1)) {
2709  //printf("sig_match_prepdir_x: no match mov\n");
2710  return 0;
2711  }
2712  if(!insn_match_find_next(fw,is,1,match_b)) {
2713  //printf("sig_match_prepdir_x: no match b\n");
2714  return 0;
2715  }
2716  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2717 }
int sig_match_prop_string ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 5144 der Datei finsig_thumb2.c.

5145 {
5146  uint32_t call_adr = find_call_near_str(fw, is, rule);
5147 
5148  if (call_adr == 0)
5149  return 0;
5150 
5151  // initialize to found address
5152  disasm_iter_init(fw,is,call_adr);
5153  disasm_iter(fw,is);
5154 
5155  uint32_t myreg;
5156 
5157  if (is_sig_call(fw,is,"GetPropertyCase")) {
5158  // looking for r0
5159  myreg = 0;
5160  }
5161  else {
5162  // semaphore version of GetPropertyCase, looking for r1
5163  myreg = 1;
5164  }
5165 
5166  // re-init 'is' to current address minus at least 8 insts
5167  const int hl = 8;
5168  disasm_iter_init(fw,is,call_adr - hl*4);
5169  // history needs to be made
5170  while (is->adr < call_adr) {
5171  if (!disasm_iter(fw,is))
5172  disasm_iter_init(fw,is,(is->adr | is->thumb)+2);
5173  }
5174  uint32_t regs[4];
5175  // get r0 or r1, backtracking up to 8 instructions
5176  if ((get_call_const_args(fw,is,hl,regs)&(1<<myreg))==(1<<myreg)) {
5177  add_prop_hit(rule->name,(int)regs[myreg]);
5178  return 1;
5179  }
5180  return 0;
5181 }
int sig_match_qsort ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2852 der Datei finsig_thumb2.c.

2853 {
2854  if(!init_disasm_sig_ref(fw,is,rule)) {
2855  return 0;
2856  }
2857  if(!find_next_sig_call(fw,is,90,"DebugAssert")) {
2858  // printf("sig_match_qsort: no DebugAssert\n");
2859  return 0;
2860  }
2861  if(!insn_match_find_nth(fw,is,38,3,match_bl_blximm)) {
2862  // printf("sig_match_qsort: no match bl\n");
2863  return 0;
2864  }
2865  // follow
2867  // if call in first 4 insn, follow again (newer cams have an extra sub)
2868  if(insn_match_find_next(fw,is,4,match_bl_blximm)) {
2870  }
2871  if(!insn_match_find_next(fw,is,14,match_bl_blximm)) {
2872  // printf("sig_match_qsort: no match bl (qsort)\n");
2873  return 0;
2874  }
2875  // sanity check, expect r1-r3 to be const
2876  uint32_t regs[4];
2877  if((get_call_const_args(fw,is,5,regs)&0xe)!=0xe) {
2878  // printf("sig_match_qsort: failed to get args\n");
2879  return 0;
2880  }
2881  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2882 }
int sig_match_readfastdir ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2152 der Datei finsig_thumb2.c.

2153 {
2154  uint32_t str_adr;
2155  str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2156  if(!str_adr) {
2157  printf("sig_match_readfastdir: %s failed to find ref %s\n",rule->name,rule->ref_name);
2158  return 0;
2159  }
2160  const insn_match_t match_cbnz_r0[]={
2161  {MATCH_INS(CBNZ, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM_ANY}},
2162  {ARM_INS_ENDING}
2163  };
2164  const insn_match_t match_cbz_r0[]={
2165  {MATCH_INS(CBZ, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM_ANY}},
2166  {ARM_INS_ENDING}
2167  };
2168  int max_insns=rule->param&SIG_NEAR_OFFSET_MASK;
2169  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
2170  while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2171  uint32_t ref_adr = iter_state_adr(is);
2172  // Check for bl followed by cbnz in previous 2 instructions
2175  uint32_t call_adr = iter_state_adr(fw->is);
2177  if(insn_match_any(fw->is->insn,match_cbnz_r0)) {
2178  return save_sig_match_call(fw, rule, call_adr);
2179  }
2180  }
2181  int i;
2182  for(i=3; i<=max_insns; i++) {
2183  // Check for bl followed by cbz branching to ref_adr
2186  uint32_t call_adr = iter_state_adr(fw->is);
2187  fw_disasm_iter_single(fw,adr_hist_get(&is->ah,i-1));
2188  if(insn_match_any(fw->is->insn,match_cbz_r0)) {
2189  uint32_t b_adr = get_branch_call_insn_target(fw,fw->is);
2190  if (ref_adr == b_adr) {
2191  return save_sig_match_call(fw, rule, call_adr);
2192  }
2193  }
2194  }
2195  }
2196  }
2197  printf("sig_match_readfastdir: no match %s\n",rule->name);
2198  return 0;
2199 }
int sig_match_rec2pb ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2620 der Datei finsig_thumb2.c.

2621 {
2622  uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2623  if(!str_adr) {
2624  printf("sig_match_mktime_ext: failed to find ref %s\n",rule->ref_name);
2625  return 0;
2626  }
2627  // TODO should handle multiple instances of string
2628  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
2629  while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2630  const insn_match_t match_ldr_cbnz_r0[]={
2631  {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM_ANY}},
2632  {MATCH_INS(CBNZ, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM_ANY}},
2633  {ARM_INS_ENDING}
2634  };
2635  if(!insn_match_find_next_seq(fw,is,10,match_ldr_cbnz_r0)) {
2636  // printf("sig_match_rec2pb: no cbnz\n");
2637  continue;
2638  }
2639  // follow
2641  if(!insn_match_find_next(fw,is,3,match_b_bl_blximm)) {
2642  // printf("sig_match_rec2pb: no call\n");
2643  // followed branch, doesn't make sense to keep searching
2644  return 0;
2645  }
2646  uint32_t adr = iter_state_adr(is);
2647  // follow for sanity check
2649  if(!find_next_sig_call(fw,is,16,"LogCameraEvent")) {
2650  // printf("sig_match_rec2pb: no LogCameraEvent call\n");
2651  return 0;
2652  }
2653  uint32_t regs[4];
2654  if((get_call_const_args(fw,is,4,regs)&3)!=3) {
2655  // printf("sig_match_rec2pb: failed to get args\n");
2656  return 0;
2657  }
2658  // sanity check starts with LogCameraEvent with expected number and string
2659  if(regs[0]==0x60 && adr2ptr(fw,regs[1]) && (strcmp((const char *)adr2ptr(fw,regs[1]),"AC:Rec2PB")==0)) {
2660  return save_sig_with_j(fw,rule->name,adr);
2661  } else {
2662  // printf("sig_match_rec2pb: bad args\n");
2663  return 0;
2664  }
2665  }
2666  return 0;
2667 }
int sig_match_reg_evp ( firmware fw,
iter_state_t is,
__attribute__((unused)) sig_rule_t rule 
)

Definiert in Zeile 1070 der Datei finsig_thumb2.c.

1071 {
1072  const insn_match_t reg_evp_match[]={
1073  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R2), MATCH_OP_REG(R1)}},
1074  {MATCH_INS(LDR, 2), {MATCH_OP_REG(R1), MATCH_OP_MEM_ANY}},
1076  {ARM_INS_ENDING}
1077  };
1078 
1079  uint32_t e_to_evp=get_saved_sig_val("ExportToEventProcedure_FW");
1080  if(!e_to_evp) {
1081  printf("sig_match_reg_evp: failed to find ExportToEventProcedure, giving up\n");
1082  return 0;
1083  }
1084 
1085  //look for the underlying RegisterEventProcedure function (not currently used)
1086  uint32_t reg_evp=0;
1087  // start at identified Export..
1088  disasm_iter_init(fw,is,e_to_evp);
1089  if(insn_match_seq(fw,is,reg_evp_match)) {
1090  reg_evp=ADR_SET_THUMB(is->insn->detail->arm.operands[0].imm);
1091  //printf("RegisterEventProcedure found 0x%08x at %"PRIx64"\n",reg_evp,is->insn->address);
1092  save_sig(fw,"RegisterEventProcedure",reg_evp);
1093  }
1094  return (reg_evp != 0);
1095 }
int sig_match_reg_evp_alt2 ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1153 der Datei finsig_thumb2.c.

1154 {
1155  uint32_t reg_evp_alt2=0;
1156  // TODO could make this a param for different fw variants
1157  uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
1158  if(!str_adr) {
1159  printf("sig_match_reg_evp_alt2: failed to find %s\n",rule->ref_name);
1160  return 0;
1161  }
1162  //printf("sig_match_reg_evp_alt2: EngApp.Delete 0x%08x\n",str_adr);
1163  uint32_t reg_evp_alt1=get_saved_sig_val("RegisterEventProcedure_alt1");
1164 
1165  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
1166  while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
1167  if(is->insn->detail->arm.operands[0].reg != ARM_REG_R0) {
1168  continue;
1169  }
1170  if(!insn_match_find_next(fw,is,3,match_b_bl)) {
1171  continue;
1172  }
1173  uint32_t regs[4];
1174  // sanity check, constants in r0, r1 and r0 was the original thing we were looking for
1175  if((get_call_const_args(fw,is,4,regs)&3)==3) {
1176  if(regs[0]==str_adr) {
1177  reg_evp_alt2=ADR_SET_THUMB(is->insn->detail->arm.operands[0].imm);
1178  // TODO could keep looking
1179  if(reg_evp_alt2 == reg_evp_alt1) {
1180  printf("RegisterEventProcedure_alt2 == _alt1 at %"PRIx64"\n",is->insn->address);
1181  reg_evp_alt2=0;
1182  } else {
1183  save_sig(fw,"RegisterEventProcedure_alt2",reg_evp_alt2);
1184  // printf("RegisterEventProcedure_alt2 found 0x%08x at %"PRIx64"\n",reg_evp_alt2,is->insn->address);
1185  // TODO could follow alt2 and make sure it matches expected mov r2,0, bl register..
1186  }
1187  break;
1188  }
1189  }
1190  }
1191  return (reg_evp_alt2 != 0);
1192 }
int sig_match_reg_evp_table ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1099 der Datei finsig_thumb2.c.

1100 {
1101  // ref to find RegisterEventProcTable
1102  uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name); // note this string may appear more than once, assuming want first
1103  if(!str_adr) {
1104  printf("sig_match_reg_evp_table: failed to find %s\n",rule->ref_name);
1105  return 0;
1106  }
1107  //printf("sig_match_reg_evp_table: DispDev_EnableEventProc 0x%08x\n",str_adr);
1108  uint32_t reg_evp_alt1=0;
1109  uint32_t reg_evp_tbl=0;
1110  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
1111  uint32_t dd_enable_p=0;
1112  while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
1113  if(is->insn->detail->arm.operands[0].reg != ARM_REG_R0) {
1114  continue;
1115  }
1116  if(!insn_match_find_next(fw,is,2,match_b_bl)) {
1117  continue;
1118  }
1119  reg_evp_alt1=ADR_SET_THUMB(is->insn->detail->arm.operands[0].imm);
1120  //printf("RegisterEventProcedure_alt1 found 0x%08x at %"PRIx64"\n",reg_evp_alt1,is->insn->address);
1121  save_sig(fw,"RegisterEventProcedure_alt1",reg_evp_alt1);
1122 
1123  uint32_t regs[4];
1124 
1125  // get r0 and r1, backtracking up to 4 instructions
1126  if((get_call_const_args(fw,is,4,regs)&3)==3) {
1127  // sanity check, arg0 was the original thing we were looking for
1128  if(regs[0]==str_adr) {
1129  dd_enable_p=regs[1]; // constant value should already have correct ARM/THUMB bit
1130  //printf("DispDev_EnableEventProc found 0x%08x at %"PRIx64"\n",dd_enable_p,is->insn->address);
1131  add_func_name(fw,"DispDev_EnableEventProc",dd_enable_p,NULL);
1132  break;
1133  }
1134  }
1135  }
1136  // found candidate function
1137  if(dd_enable_p) {
1138  disasm_iter_init(fw,is,dd_enable_p); // start at found func
1139  if(insn_match_find_next(fw,is,4,match_b_bl)) { // find the first bl
1140  // sanity check, make sure we get a const in r0
1141  uint32_t regs[4];
1142  if(get_call_const_args(fw,is,4,regs)&1) {
1143  reg_evp_tbl=ADR_SET_THUMB(is->insn->detail->arm.operands[0].imm);
1144  // printf("RegisterEventProcTable found 0x%08x at %"PRIx64"\n",reg_evp_tbl,is->insn->address);
1145  save_sig(fw,"RegisterEventProcTable",reg_evp_tbl);
1146  }
1147  }
1148  }
1149  return (reg_evp_tbl != 0);
1150 }
int sig_match_rom_ptr_get ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 4988 der Datei finsig_thumb2.c.

4989 {
4990  if(!init_disasm_sig_ref(fw,is,rule)) {
4991  return 0;
4992  }
4993  uint32_t fadr=is->adr;
4994  if(!disasm_iter(fw,is)) {
4995  printf("sig_match_rom_ptr_get: disasm failed\n");
4996  return 0;
4997  }
4998  uint32_t adr=LDR_PC2val(fw,is->insn);
4999  if(!adr) {
5000  printf("sig_match_rom_ptr_get: no match LDR PC 0x%"PRIx64"\n",is->insn->address);
5001  return 0;
5002  }
5003  if(is->insn->detail->arm.operands[0].reg != ARM_REG_R0) {
5004  printf("sig_match_rom_ptr_get: not R0\n");
5005  return 0;
5006  }
5007  if(!disasm_iter(fw,is)) {
5008  printf("sig_match_rom_ptr_get: disasm failed\n");
5009  return 0;
5010  }
5011  // TODO could check for other RET type instructions
5012  if(!insn_match(is->insn,match_bxlr)) {
5013  printf("sig_match_rom_ptr_get: no match BX LR\n");
5014  return 0;
5015  }
5016  save_misc_val(rule->name,adr,0,fadr);
5017  return 1;
5018 }
int sig_match_screenlock_helper ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1550 der Datei finsig_thumb2.c.

1550  {
1551  if(!init_disasm_sig_ref(fw,is,rule)) {
1552  return 0;
1553  }
1554  uint32_t init_adr = (uint32_t)is->adr | is->thumb;
1555  // match specific instruction sequence instead of first call because g3x, g5x have different code
1556  // not by dryos rev, sx710 has same code as earlier cams
1557  const insn_match_t match_cmp_bne_bl[]={
1558  {MATCH_INS(CMP, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM(0)}},
1561  {ARM_INS_ENDING}
1562  };
1563  const insn_match_t match_ldrpc_mov_b[]={
1564  {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM_BASE(PC)}},
1565  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R1), MATCH_OP_IMM(0)}},
1567  {ARM_INS_ENDING}
1568  };
1569  // match first seq, this is the func we want
1570  if(insn_match_find_next_seq(fw,is,6,match_cmp_bne_bl)) {
1571  return save_sig_with_j(fw,rule->name,init_adr);
1572 
1573  }
1574  // try alternate match on newer cameras (around r57, but some variation)
1575  // this version puts a pointer to the function used in normal match in r0, 0 in R1, and jumps
1576  // go back to start
1577  disasm_iter_init(fw,is,init_adr);
1578  if(!insn_match_find_next_seq(fw,is,1,match_ldrpc_mov_b)) {
1579  printf("sig_match_screenlock_helper: match 2 failed 0x%"PRIx64"\n",is->insn->address);
1580  return 0;
1581  }
1582  disasm_iter_init(fw,is,init_adr);
1583  disasm_iter(fw,is);
1584  uint32_t adr = LDR_PC2val(fw,is->insn);
1585  if(!adr) {
1586  printf("sig_match_screenlock_helper: no match LDR PC 0x%"PRIx64"\n",is->insn->address);
1587  return 0;
1588  }
1589  disasm_iter_init(fw,is,adr);
1590  // retry original match on pointer
1591  if(!insn_match_find_next_seq(fw,is,6,match_cmp_bne_bl)) {
1592  printf("sig_match_screenlock_helper: match failed 0x%8x\n",init_adr);
1593  return 0;
1594  }
1595  return save_sig_with_j(fw,rule->name,adr);
1596 }
int sig_match_screenunlock ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1624 der Datei finsig_thumb2.c.

1625 {
1626  if(!init_disasm_sig_ref(fw,is,rule)) {
1627  return 0;
1628  }
1629  // look for ScreenLock call to verify right version of UIFS_DisplayFirmUpdateView
1630  if(!find_next_sig_call(fw,is,14,"ScreenLock")) {
1631  // printf("sig_match_screenunlock: no ScreenLock\n");
1632  return 0;
1633  }
1634 
1635  // expect tail call to ScreenUnlock
1636  const insn_match_t match_end[]={
1639  {ARM_INS_ENDING}
1640  };
1641  if(!insn_match_find_next_seq(fw,is,38,match_end)) {
1642  // printf("sig_match_screenunlock: match failed\n");
1643  return 0;
1644  }
1645  // TODO would be nice to have some validation
1646  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1647 }
int sig_match_set_control_event ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2947 der Datei finsig_thumb2.c.

2948 {
2949  uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2950  if(!str_adr) {
2951  // not logged, two different ref strings so failing one is normal
2952  // printf("sig_match_set_control_event: failed to find ref %s\n",rule->ref_name);
2953  return 0;
2954  }
2955  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
2956  while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2957  if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
2958  // printf("sig_match_set_control_event: no match bl at 0x%"PRIx64"\n",is->insn->address);
2959  continue;
2960  }
2961  if(!is_sig_call(fw,is,"LogCameraEvent")) {
2962  // printf("sig_match_set_control_event: not LogCameraEvent at 0x%"PRIx64"\n",is->insn->address);
2963  continue;
2964  }
2965  const insn_match_t match_seq[]={
2966  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R0), MATCH_OP_REG_ANY,}},
2969  {ARM_INS_ENDING}
2970  };
2971  if(!insn_match_find_next_seq(fw,is,1,match_seq)) {
2972  // printf("sig_match_set_control_event: no match seq\n");
2973  continue;
2974  }
2975  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2976  }
2977  return 0;
2978 }
int sig_match_set_hp_timer_after_now ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3105 der Datei finsig_thumb2.c.

3106 {
3107  uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
3108  if(!str_adr) {
3109  printf("sig_match_set_hp_timer_after_now: failed to find ref %s\n",rule->ref_name);
3110  return 0;
3111  }
3112  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
3113  while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
3114  if(!find_next_sig_call(fw,is,20,"ClearEventFlag")) {
3115  // printf("sig_match_set_hp_timer_after_now: failed to find ClearEventFlag\n");
3116  continue;
3117  }
3118  // find 3rd call
3119  if(!insn_match_find_nth(fw,is,13,3,match_bl_blximm)) {
3120  // printf("sig_match_set_hp_timer_after_now: no match bl 0x%"PRIx64"\n",is->insn->address);
3121  continue;
3122  }
3123  // check call args, expect r0 = 70000
3124  uint32_t regs[4];
3125  uint32_t found_regs = get_call_const_args(fw,is,6,regs);
3126  if((found_regs&0x1)!=0x1) {
3127  // some cameras load r0 through a base reg, try alternate match
3128  // r3 == 3 and r2 or r1 found and in ROM
3129  if((found_regs & 0x8) && regs[3] == 4) {
3130  if((found_regs & 0x2 && regs[1] > fw->rom_code_search_min_adr)
3131  || (found_regs & 0x4 && regs[2] > fw->rom_code_search_min_adr)) {
3132  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3133  }
3134  }
3135  // printf("sig_match_set_hp_timer_after_now: failed to match args 0x%"PRIx64"\n",is->insn->address);
3136  continue;
3137  }
3138  // r1, r2 should be func pointers but may involve reg-reg moves that get_call_const_args doesn't track
3139  if(regs[0] != 70000) {
3140  // printf("sig_match_set_hp_timer_after_now: args mismatch 0x%08x 0x%08x 0x%"PRIx64"\n",regs[0],regs[1],is->insn->address);
3141  continue;
3142  }
3143  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3144  }
3145  return 0;
3146 }
int sig_match_sqrt ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2498 der Datei finsig_thumb2.c.

2499 {
2500  if(!init_disasm_sig_ref(fw,is,rule)) {
2501  return 0;
2502  }
2503  // third call
2504  if(!insn_match_find_nth(fw,is,12,3,match_bl_blximm)) {
2505  return 0;
2506  }
2507  // follow
2509  if(!disasm_iter(fw,is)) {
2510  printf("sig_match_sqrt: disasm failed\n");
2511  return 0;
2512  }
2513  uint32_t j_tgt=get_direct_jump_target(fw,is);
2514  // veneer?
2515  if(j_tgt) {
2516  // follow
2517  disasm_iter_init(fw,is,j_tgt);
2518  if(!disasm_iter(fw,is)) {
2519  printf("sig_match_sqrt: disasm failed\n");
2520  return 0;
2521  }
2522  }
2523  // second call/branch (seems to be bhs)
2524  if(!insn_match_find_nth(fw,is,12,2,match_b_bl_blximm)) {
2525  return 0;
2526  }
2527  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2528 }
int sig_match_stat ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1978 der Datei finsig_thumb2.c.

1979 {
1980  uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
1981  if(!str_adr) {
1982  printf("sig_match_stat: %s failed to find ref %s\n",rule->name,rule->ref_name);
1983  return 0;
1984  }
1985 
1986  // TODO should handle multiple instances of string
1987  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
1988  while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
1989  if(is->insn->detail->arm.operands[0].reg == ARM_REG_R0) {
1990  if(insn_match_find_next(fw,is,2,match_bl_blximm)) {
1992  // same string ref'd by Fopen
1993  if(is_sig_call(fw,is,"Fopen_Fut_FW")) {
1994  continue;
1995  }
1996  // TODO could check r1 not a const
1997  return save_sig_with_j(fw,rule->name,adr);
1998  }
1999  }
2000  }
2001  return 0;
2002 }
int sig_match_str_arg_call ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 5135 der Datei finsig_thumb2.c.

5136 {
5137  uint32_t call_adr = find_str_arg_call(fw,is,rule);
5138  if(call_adr) {
5139  return save_sig_match_call(fw, rule, call_adr);
5140  }
5141  return 0;
5142 }
int sig_match_str_r0_call ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1043 der Datei finsig_thumb2.c.

1044 {
1045  uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
1046  if(!str_adr) {
1047  printf("sig_match_str_r0_call: %s failed to find ref %s\n",rule->name,rule->ref_name);
1048  return 0;
1049  }
1050 
1051 // printf("sig_match_str_r0_call: %s ref str %s 0x%08x\n",rule->name,rule->ref_name,str_adr);
1052 
1053  // TODO should handle multiple instances of string
1054  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
1055  while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
1056  if(is->insn->detail->arm.operands[0].reg == ARM_REG_R0) {
1057  // printf("sig_match_str_r0_call: %s ref str %s ref 0x%"PRIx64"\n",rule->name,rule->ref_name,is->insn->address);
1058  // TODO should check if intervening insn nuke r0
1061  // printf("sig_match_str_r0_call: thumb %s call 0x%08x\n",rule->name,adr);
1062  return save_sig_with_j(fw,rule->name,adr);
1063  }
1064  }
1065  }
1066  return 0;
1067 }
int sig_match_strncmp ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2264 der Datei finsig_thumb2.c.

2265 {
2266  uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2267  if(!str_adr) {
2268  printf("sig_match_strncmp: failed to find ref %s\n",rule->ref_name);
2269  return 0;
2270  }
2271  // TODO should handle multiple instances of string
2272  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
2273  while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2274  if(!insn_match_find_next(fw,is,3,match_bl_blximm)) {
2275  continue;
2276  }
2277  uint32_t regs[4];
2278  if((get_call_const_args(fw,is,4,regs)&6)==6) {
2279  // sanity check we got the right string
2280  if(regs[1]==str_adr && regs[2] == strlen(rule->ref_name)) {
2281  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2282  }
2283  }
2284  }
2285  return 0;
2286 }
int sig_match_strncpy ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2250 der Datei finsig_thumb2.c.

2251 {
2252  if(!init_disasm_sig_ref(fw,is,rule)) {
2253  return 0;
2254  }
2255  if(!find_next_sig_call(fw,is,60,"strcpy_FW")) {
2256  return 0;
2257  }
2258  if(!insn_match_find_next(fw,is,6,match_bl_blximm)) {
2259  return 0;
2260  }
2261  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2262 }
int sig_match_strrchr ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2201 der Datei finsig_thumb2.c.

2202 {
2203  uint32_t sig_adr=get_saved_sig_val(rule->name);
2204  if (sig_adr == 0)
2205  {
2206  uint32_t call_adr = find_call_near_str(fw,is,rule);
2207  if(call_adr) {
2208  disasm_iter_init(fw,is,call_adr-4); // reset to a bit before where the string was found
2209  const insn_match_t match_mov_r1_imm[]={
2210  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R1), MATCH_OP_IMM_ANY}},
2211  {ARM_INS_ENDING}
2212  };
2213  if(insn_match_find_next(fw,is,2,match_mov_r1_imm)){
2214  return save_sig_match_call(fw, rule, call_adr);
2215  }
2216  }
2217  }
2218  return 0;
2219 }
int sig_match_strtolx ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2288 der Datei finsig_thumb2.c.

2289 {
2290  if(!init_disasm_sig_ref(fw,is,rule)) {
2291  return 0;
2292  }
2293  if(!find_next_sig_call(fw,is,130,"strncpy")) {
2294  return 0;
2295  }
2296  // find first call after strncpy
2297  if(!insn_match_find_next(fw,is,6,match_bl_blximm)) {
2298  return 0;
2299  }
2301  if(!adr) {
2302  return 0;
2303  }
2304  // follow
2305  disasm_iter_init(fw,is,adr);
2306  if(!disasm_iter(fw,is)) {
2307  printf("sig_match_strtolx: disasm failed\n");
2308  return 0;
2309  }
2310  // expect
2311  // mov r3, #0
2312  // b ...
2313  const insn_match_t match_mov_r3_imm[]={
2314  {MATCH_INS(MOV, 2), {MATCH_OP_REG(R3), MATCH_OP_IMM_ANY}},
2315  {ARM_INS_ENDING}
2316  };
2317  if(!insn_match(is->insn,match_mov_r3_imm)){
2318  return 0;
2319  }
2320  if(!disasm_iter(fw,is)) {
2321  printf("sig_match_strtolx: disasm failed\n");
2322  return 0;
2323  }
2324  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2325 }
int sig_match_take_semaphore_strict ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1874 der Datei finsig_thumb2.c.

1875 {
1876  if(!init_disasm_sig_ref(fw,is,rule)) {
1877  return 0;
1878  }
1879  // find first function call
1880  if(!insn_match_find_next(fw,is,6,match_bl_blximm)) {
1881  return 0;
1882  }
1883  // follow
1885  // find second call
1886  if(!insn_match_find_nth(fw,is,10,2,match_bl_blximm)) {
1887  return 0;
1888  }
1889  // follow
1891  // skip two calls, next should be DebugAssert
1892  if(!insn_match_find_nth(fw,is,20,3,match_bl_blximm)) {
1893  return 0;
1894  }
1895  save_sig_with_j(fw,"DebugAssert",get_branch_call_insn_target(fw,is));
1896 
1897  // next should be TakeSemaphoreStrictly
1898  if(!insn_match_find_next(fw,is,7,match_bl_blximm)) {
1899  return 0;
1900  }
1901  save_sig_with_j(fw,"TakeSemaphoreStrictly",get_branch_call_insn_target(fw,is));
1902  arm_reg ptr_reg = ARM_REG_INVALID;
1903  uint32_t sem_adr=0;
1904  int i;
1905  // iterate backwards looking for the value put in r0
1906  for(i=1; i<7; i++) {
1908  cs_insn *insn=fw->is->insn;
1909  if(insn->id != ARM_INS_LDR) {
1910  continue;
1911  }
1912  if(ptr_reg == ARM_REG_INVALID
1913  && insn->detail->arm.operands[0].reg == ARM_REG_R0
1914  && insn->detail->arm.operands[1].mem.base != ARM_REG_PC) {
1915  ptr_reg = insn->detail->arm.operands[1].mem.base;
1916  continue;
1917  }
1918  if(ptr_reg == ARM_REG_INVALID || !isLDR_PC(insn) || (arm_reg)insn->detail->arm.operands[0].reg != ptr_reg) {
1919  continue;
1920  }
1921  sem_adr=LDR_PC2val(fw,insn);
1922  if(sem_adr) {
1923  break;
1924  }
1925  }
1926  if(!sem_adr) {
1927  return 0;
1928  }
1929  save_misc_val("fileio_semaphore",sem_adr,0,(uint32_t)is->insn->address);
1930  // look for next call: GetDrive_FreeClusters
1931  if(!insn_match_find_next(fw,is,10,match_bl_blximm)) {
1932  return 0;
1933  }
1934  return save_sig_with_j(fw,"GetDrive_FreeClusters",get_branch_call_insn_target(fw,is));
1935 }
int sig_match_time ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2221 der Datei finsig_thumb2.c.

2222 {
2223  uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2224  if(!str_adr) {
2225  printf("sig_match_time: %s failed to find ref %s\n",rule->name,rule->ref_name);
2226  return 0;
2227  }
2228  uint32_t fadr=0;
2229  // TODO should handle multiple instances of string
2230  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
2231  while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2232  // find second func after str ref
2233  if(insn_match_find_nth(fw,is,6,2,match_bl_blximm)) {
2234  fadr=get_branch_call_insn_target(fw,is);
2235  break;
2236  }
2237  }
2238  if(!fadr) {
2239  return 0;
2240  }
2241  // follow found func
2242  disasm_iter_init(fw,is,fadr);
2243  // find second call
2244  if(insn_match_find_nth(fw,is,11,2,match_bl_blximm)) {
2245  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2246  }
2247  return 0;
2248 }
int sig_match_transfer_src_overlay ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3147 der Datei finsig_thumb2.c.

3147  {
3148  if(!init_disasm_sig_ref(fw,is,rule)) {
3149  return 0;
3150  }
3151  // skip to debugassert
3152  if(!find_next_sig_call(fw,is,32,"DebugAssert")) {
3153  printf("sig_match_transfer_src_overlay: no match DebugAssert\n");
3154  return 0;
3155  }
3156  var_ldr_desc_t desc;
3157  if(!find_and_get_var_ldr(fw, is, 20,4, ARM_REG_R0, &desc)) {
3158  printf("sig_match_transfer_src_overlay: no match ldr\n");
3159  return 0;
3160  }
3161  // following should be call
3162  if(!insn_match_find_next(fw,is,1,match_bl_blximm)) {
3163  printf("sig_match_transfer_src_overlay: no match bl 0x%"PRIx64"\n",is->insn->address);
3164  return 0;
3165  }
3166  // main sig value
3167  uint32_t fadr = get_branch_call_insn_target(fw,is);
3168  // adding active_bitmap_buffer here
3169  // note 4 bytes after value used on many ports, but the value normally sent to transfer_src_overlay
3170  save_misc_val("active_bitmap_buffer",desc.adr_adj,desc.off,(uint32_t)is->insn->address);
3171  // pick up bitmap_buffer
3172  // expect
3173  // ldr rx,[reg bitmap buffer]
3174  // add r0, <reg from bitmap buffer>, const
3175  const insn_match_t bm_buf_match[]={
3178  {ARM_INS_ENDING}
3179  };
3180  if(insn_match_find_next_seq(fw,is,1,bm_buf_match)) {
3181  if((arm_reg)is->insn->detail->arm.operands[1].reg == desc.reg_base) {
3182  save_misc_val("bitmap_buffer",desc.adr_adj,is->insn->detail->arm.operands[2].imm,(uint32_t)is->insn->address);
3183  }
3184  /*
3185  else {
3186  printf("sig_match_transfer_src_overlay: no match bitmap_buffer add 0x%"PRIx64"\n",is->insn->address);
3187  }
3188  */
3189  }
3190  /*
3191  else {
3192  printf("sig_match_transfer_src_overlay: no match bitmap_buffer seq 0x%"PRIx64"\n",is->insn->address);
3193  }
3194  */
3195  return save_sig_with_j(fw,rule->name,fadr);
3196 }
int sig_match_try_take_sem_dry_gt_57 ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3043 der Datei finsig_thumb2.c.

3044 {
3045  if(!init_disasm_sig_ref(fw,is,rule)) {
3046  return 0;
3047  }
3048  if(!find_next_sig_call(fw,is,24,"ReceiveMessageQueue")) {
3049  printf("sig_match_try_take_sem_dry_gt_57: failed to find ReceiveMessageQueue\n");
3050  return 0;
3051  }
3052  if(!find_next_sig_call(fw,is,60,"bzero")) {
3053  printf("sig_match_try_take_sem_dry_gt_57: failed to find bzero\n");
3054  return 0;
3055  }
3056  if(insn_match_find_next(fw,is,3,match_bl_blximm)) {
3057  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3058  }
3059  printf("sig_match_try_take_sem_dry_gt_57: no match\n");
3060  return 0;
3061 }
int sig_match_ufree ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2045 der Datei finsig_thumb2.c.

2046 {
2047  if(!init_disasm_sig_ref(fw,is,rule)) {
2048  return 0;
2049  }
2050  // find the first call to strcpy
2051  if(!find_next_sig_call(fw,is,60,"strcpy_FW")) {
2052  return 0;
2053  }
2054  // find 3rd call
2055  if(!insn_match_find_nth(fw,is,12,3,match_bl_blximm)) {
2056  return 0;
2057  }
2058  // follow
2060  // Look for Close call
2061  if(!find_next_sig_call(fw,is,40,"Close_FW")) {
2062  return 0;
2063  }
2064  // next call should be FreeUncacheableMemory
2065  if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
2066  return 0;
2067  }
2068  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2069 }
int sig_match_ui_mem_func_ptr ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 4533 der Datei finsig_thumb2.c.

4534 {
4535  if(!init_disasm_sig_ref(fw,is,rule)) {
4536  return 0;
4537  }
4538  uint32_t fadr=is->adr;
4539  var_ldr_desc_t desc;
4540  if(!find_and_get_var_ldr(fw, is, 1, 4, ARM_REG_R1, &desc)) {
4541  printf("sig_match_var_struct_get: no match ldr\n");
4542  return 0;
4543  }
4544  if(!disasm_iter(fw,is)) {
4545  printf("sig_match_var_struct_get: disasm failed\n");
4546  return 0;
4547  }
4548  const insn_match_t match_bx_r1[]={
4549  {MATCH_INS(BX, 1), {MATCH_OP_REG(R1),}},
4550  {ARM_INS_ENDING}
4551  };
4552 
4553  // TODO could check for other RET type instructions
4554  if(!insn_match(is->insn,match_bx_r1)) {
4555  printf("sig_match_var_struct_get: no match BX R1\n");
4556  return 0;
4557  }
4558  save_misc_val(rule->name,desc.adr_adj,desc.off,fadr);
4559  return 1;
4560 }
int sig_match_uiprop_count ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 4098 der Datei finsig_thumb2.c.

4099 {
4100  if(!init_disasm_sig_ref(fw,is,rule)) {
4101  return 0;
4102  }
4103  if(!find_next_sig_call(fw,is,38,"DebugAssert")) {
4104  // printf("sig_match_uiprop_count: no DebugAssert 1\n");
4105  return 0;
4106  }
4107  if(!find_next_sig_call(fw,is,14,"DebugAssert")) {
4108  // printf("sig_match_uiprop_count: no DebugAssert 2\n");
4109  return 0;
4110  }
4111  const insn_match_t match_bic_cmp[]={
4113  {MATCH_INS(CMP, 2), {MATCH_OP_REG_ANY, MATCH_OP_ANY}},
4114  {ARM_INS_ENDING}
4115  };
4116  if(!insn_match_find_next_seq(fw,is,3,match_bic_cmp)) {
4117  // printf("sig_match_uiprop_count: no bic,cmp\n");
4118  return 0;
4119  }
4120  save_misc_val(rule->name,is->insn->detail->arm.operands[1].imm,0,(uint32_t)is->insn->address);
4121  return 1;
4122 }
int sig_match_umalloc ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 2026 der Datei finsig_thumb2.c.

2027 {
2028  if(!init_disasm_sig_ref(fw,is,rule)) {
2029  return 0;
2030  }
2031  // looking for 3rd call
2032  if(!insn_match_find_nth(fw,is,15,3,match_bl_blximm)) {
2033  return 0;
2034  }
2035  //follow
2037  // looking for 3rd call again
2038  if(!insn_match_find_nth(fw,is,14,3,match_bl_blximm)) {
2039  return 0;
2040  }
2041  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2042 }
int sig_match_umalloc_strictly ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3951 der Datei finsig_thumb2.c.

3952 {
3953  uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
3954  if(!str_adr) {
3955  printf("sig_umalloc_strictly: %s failed to find ref %s\n",rule->name,rule->ref_name);
3956  return 0;
3957  }
3958 
3959  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
3961  printf("sig_match_umalloc_strictly: faild to find ref insn\n");
3962  return 0;
3963  }
3964  if(is->insn->detail->arm.operands[0].reg != ARM_REG_R0) {
3965  printf("sig_match_umalloc_strictly: reg mismatch\n");
3966  return 0;
3967  }
3968  if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
3969  printf("sig_match_umalloc_strictly: no bl 1\n");
3970  return 0;
3971  }
3972  if(!is_sig_call(fw,is,"CreateTaskStrictly")) {
3973  printf("sig_match_umalloc_strictly: no CreateTaskStrictly\n");
3974  return 0;
3975  }
3976  // b included because usually tail call
3977  if(!insn_match_find_next(fw,is,6,match_b_bl_blximm)) {
3978  printf("sig_match_umalloc_strictly: no bl 1\n");
3979  return 0;
3980  }
3981  // follow
3983  if(!insn_match_find_next(fw,is,10,match_bl_blximm)) {
3984  printf("sig_match_umalloc_strictly: no bl 2\n");
3985  return 0;
3986  }
3987  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3988 }
int sig_match_undisplaybusyonscreen_52 ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3013 der Datei finsig_thumb2.c.

3014 {
3015  if (fw->dryos_ver != 52) {
3016  return 0;
3017  }
3018  uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
3019  if(!str_adr) {
3020  printf("sig_match_undisplaybusyonscreen: failed to find ref %s\n",rule->ref_name);
3021  return 0;
3022  }
3023  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
3024  while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
3025  // assume same function display* was found in, skip to that
3026  if(!find_next_sig_call(fw,is,24,"displaybusyonscreen")) {
3027  // printf("sig_match_undisplaybusyonscreen: no match displaybusyonscreen\n");
3028  continue;
3029  }
3030  if(!find_next_sig_call(fw,is,12,"GUISrv_StartGUISystem_FW")) {
3031  // printf("sig_match_undisplaybusyonscreen: no match GUISrv_StartGUISystem_FW\n");
3032  continue;
3033  }
3034  if(!insn_match_find_nth(fw,is,6,3,match_bl_blximm)) {
3035  // printf("sig_match_undisplaybusyonscreen: no match bl 0x%"PRIx64"\n",is->insn->address);
3036  continue;
3037  }
3038  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3039  }
3040  return 0;
3041 }
int sig_match_unreg_evp_table ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 1195 der Datei finsig_thumb2.c.

1196 {
1197  uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
1198  if(!str_adr) {
1199  printf("sig_match_unreg_evp_table: failed to find %s\n",rule->ref_name);
1200  return 0;
1201  }
1202  // for checks
1203  uint32_t reg_evp_alt1=get_saved_sig_val("RegisterEventProcedure_alt1");
1204  uint32_t reg_evp_alt2=get_saved_sig_val("RegisterEventProcedure_alt2");
1205 
1206  uint32_t mecha_unreg=0;
1207  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
1208  while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
1209  //printf("sig_match_unreg_evp_table: found ref 0x%"PRIx64"\n",is->insn->address);
1210  if(is->insn->detail->arm.operands[0].reg != ARM_REG_R0) {
1211  continue;
1212  }
1213  if(!insn_match_find_next(fw,is,3,match_b_bl)) {
1214  continue;
1215  }
1216  uint32_t reg_call=get_branch_call_insn_target(fw,is);
1217  // wasn't a registration call (could be unreg)
1218  // TODO could check veneers
1219  if(!reg_call || (reg_call != reg_evp_alt1 && reg_call != reg_evp_alt2)) {
1220  continue;
1221  }
1222  uint32_t regs[4];
1223  if((get_call_const_args(fw,is,4,regs)&3)==3) {
1224  // sanity check we got the right string
1225  if(regs[0]==str_adr) {
1226  mecha_unreg=ADR_SET_THUMB(regs[1]);
1227  break;
1228  }
1229  }
1230  }
1231  if(!mecha_unreg) {
1232  return 0;
1233  }
1234  // follow
1235  disasm_iter_init(fw,is,mecha_unreg);
1236  // find first func call
1237  if(!insn_match_find_next(fw,is,7,match_b_bl)) {
1238  return 0;
1239  }
1240  // now find next ldr pc. Could follow above func, but this way picks up veneer on many fw
1241  const insn_match_t match_ldr_r0[]={
1242  {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM_BASE(PC)}},
1243  {ARM_INS_ENDING}
1244  };
1245  if(!insn_match_find_next(fw,is,18,match_ldr_r0)) {
1246  return 0;
1247  }
1248  uint32_t tbl=LDR_PC2val(fw,is->insn);
1249  if(!tbl) {
1250  return 0;
1251  }
1252  if(!disasm_iter(fw,is)) {
1253  printf("sig_match_unreg_evp_table: disasm failed\n");
1254  return 0;
1255  }
1256  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1257 }
int sig_match_var_struct_get ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 4505 der Datei finsig_thumb2.c.

4506 {
4507  if(!init_disasm_sig_ref(fw,is,rule)) {
4508  return 0;
4509  }
4510  uint32_t fadr=is->adr;
4511  var_ldr_desc_t desc;
4512  if(!find_and_get_var_ldr(fw, is, 1, 4, ARM_REG_R0, &desc)) {
4513  printf("sig_match_var_struct_get: no match ldr\n");
4514  return 0;
4515  }
4516  if(!disasm_iter(fw,is)) {
4517  printf("sig_match_var_struct_get: disasm failed\n");
4518  return 0;
4519  }
4520  // TODO could check for other RET type instructions
4521  if(!insn_match(is->insn,match_bxlr)) {
4522  printf("sig_match_var_struct_get: no match BX LR\n");
4523  return 0;
4524  }
4525  save_misc_val(rule->name,desc.adr_adj,desc.off,fadr);
4526  return 1;
4527 }
int sig_match_wait_all_eventflag_strict ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3063 der Datei finsig_thumb2.c.

3064 {
3065  if(!init_disasm_sig_ref(fw,is,rule)) {
3066  return 0;
3067  }
3068  uint32_t str_adr = find_str_bytes_main_fw(fw,"EFTool.c");
3069  if(!str_adr) {
3070  printf("sig_match_wait_all_eventflag_strict: failed to find ref EFTool.c\n");
3071  return 0;
3072  }
3073  if(!find_next_sig_call(fw,is,60,"SleepTask")) {
3074  printf("sig_match_wait_all_eventflag_strict: failed to find SleepTask\n");
3075  return 0;
3076  }
3077 
3078  while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,is->adr + 60)) {
3079  if(!insn_match_find_next(fw,is,6,match_bl_blximm)) {
3080  printf("sig_match_wait_all_eventflag_strict: no match bl 0x%"PRIx64"\n",is->insn->address);
3081  return 0;
3082  }
3083  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3084  }
3085  return 0;
3086 }
int sig_match_zicokick_52 ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3251 der Datei finsig_thumb2.c.

3252 {
3253  uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
3254  if(!str_adr) {
3255  printf("sig_match_zicokick_52: failed to find ref %s\n",rule->ref_name);
3256  return 0;
3257  }
3258  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
3259 
3260  // search for string ref
3262  printf("sig_match_zicokick_52: failed to find insn ref %s\n",rule->ref_name);
3263  return 0;
3264  }
3265  // check preceding instruction
3266  if(!fw_disasm_iter_single(fw,adr_hist_get(&is->ah,1))) {
3267  printf("sig_match_zicokick_52: disasm failed\n");
3268  return 0;
3269  }
3270  if (!(isLDR_PC(fw->is->insn) && fw->is->insn->detail->arm.operands[0].reg == ARM_REG_R0)) {
3271  printf("sig_match_zicokick_52: match ldr r0 failed\n");
3272  return 0;
3273  }
3274  // save backtracked address
3275  uint32_t adr=(uint32_t)(fw->is->insn->address) | is->thumb;
3276  // step forward one from string ref
3277  if(!disasm_iter(fw,is)) {
3278  printf("sig_match_zicokick_52: disasm failed\n");
3279  return 0;
3280  }
3281  if (is->insn->id == ARM_INS_PUSH && is->insn->detail->arm.operands[0].reg == ARM_REG_R4) {
3282  return save_sig_with_j(fw,rule->name,adr);
3283  }
3284  return 0;
3285 }
int sig_match_zicokick_copy ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3323 der Datei finsig_thumb2.c.

3324 {
3325  if(!init_disasm_sig_ref(fw,is,rule)) {
3326  return 0;
3327  }
3328  // TODO could be less strict on regs, 5 LDRs in a row is rare
3329  const insn_match_t match_ldrs_bl[]={
3330  {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM_BASE(PC)}},
3331  {MATCH_INS(LDR, 2), {MATCH_OP_REG(R1), MATCH_OP_MEM_BASE(PC)}},
3332  {MATCH_INS(LDR, 2), {MATCH_OP_REG(R2), MATCH_OP_MEM_BASE(R0)}},
3333  {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM_BASE(PC)}},
3334  {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM_BASE(R0)}},
3336  {ARM_INS_ENDING}
3337  };
3338  if(!insn_match_find_next_seq(fw,is,30,match_ldrs_bl)) {
3339  printf("sig_match_zicokick_copy no match ldr\n");
3340  return 0;
3341  }
3342  // TODO could sanity check bl target
3343  return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3344 }
int sig_match_zicokick_gt52 ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3287 der Datei finsig_thumb2.c.

3288 {
3289  uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
3290  if(!str_adr) {
3291  printf("sig_match_zicokick_gt52: failed to find ref %s\n",rule->ref_name);
3292  return 0;
3293  }
3294  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
3295 
3296  // search for string ref
3298  printf("sig_match_zicokick_gt52: failed to find insn ref %s\n",rule->ref_name);
3299  return 0;
3300  }
3301  int i;
3302  // search backward for
3303  // ldr r0,...
3304  // push r4,...
3305  for(i=1; i<=8; i++) {
3306  if (!fw_disasm_iter_single(fw,adr_hist_get(&is->ah,i))) {
3307  printf("sig_match_zicokick_gt52: disasm failed\n");
3308  return 0;
3309  }
3310  if (fw->is->insn->id == ARM_INS_PUSH && fw->is->insn->detail->arm.operands[0].reg == ARM_REG_R4) {
3311  if (!fw_disasm_iter_single(fw,adr_hist_get(&is->ah,i+1))) {
3312  printf("sig_match_zicokick_gt52: disasm failed\n");
3313  return 0;
3314  }
3315  if (isLDR_PC(fw->is->insn) && fw->is->insn->detail->arm.operands[0].reg == ARM_REG_R0) {
3316  return save_sig_with_j(fw,rule->name,(uint32_t)(fw->is->insn->address) | is->thumb);
3317  }
3318  return 0;
3319  }
3320  }
3321  return 0;
3322 }
int sig_match_zicokick_values ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 3346 der Datei finsig_thumb2.c.

3347 {
3348  if(!init_disasm_sig_ref(fw,is,rule)) {
3349  return 0;
3350  }
3351 // get_call_const_args doesn't currently handle ldr sequence
3352 #if 0
3353  // first call is further from function start
3354  if(!find_next_sig_call(fw,is,64,"zicokick_copy")) {
3355  printf("sig_match_zicokick_values: no zicokick_copy 1\n");
3356  return 0;
3357  }
3358  while(1) {
3359  uint32_t regs[4];
3360  if((get_call_const_args(fw,is,7,regs)&0x7)==0x7) {
3361  printf("xtensa blob @ 0x%08x, loads to 0x%08x, size 0x%08x\n",regs[1],regs[0],regs[2]);
3362  } else {
3363  printf("sig_match_zicokick_values: failed to get regs\n");
3364  }
3365  if(!find_next_sig_call(fw,is,8,"zicokick_copy")) {
3366  break;
3367  }
3368  }
3369  return 1;
3370 #endif
3371  int i;
3372  uint32_t uv[3] = {0,0,0};
3373  int uvi = 0;
3374  misc_blob_t *blobs=malloc((MISC_BLOB_XTENSA_MAX + 1)*sizeof(misc_blob_t));
3375  int n_blobs = 0;
3376 
3377  for(i=1; i<=64; i++) {
3378  if (!disasm_iter(fw,is)) {
3379  free(blobs);
3380  return 0;
3381  }
3382  if (is->insn->id == ARM_INS_LDR && is->insn->detail->arm.operands[1].type == ARM_OP_MEM) {
3383  uint32_t u = LDR_PC2val(fw,is->insn);
3384  if ((u<fw->base+fw->size8) && (u>fw->rom_code_search_max_adr)) {
3385  // address outside the main fw
3386  if (uvi<3) {
3387  uv[uvi] = u;
3388  uvi++;
3389  }
3390  }
3391  }
3392  else if (is->insn->id == ARM_INS_BL) {
3393  if (uvi==3) {
3394  // func call, all 3 addresses are in collection
3395  uint32_t bsize, bloadedto, badr, u;
3396  int j;
3397  badr = MAX(MAX(uv[0],uv[1]),uv[2]);
3398  for (j=0; j<3; j++) {
3399  if (uv[j]!=badr) {
3400  u = fw_u32(fw, uv[j]);
3401  if (u<1024*1024*2) {
3402  bsize = u;
3403  }
3404  else {
3405  bloadedto = u;
3406  }
3407  }
3408  }
3409  if (bsize) {
3410  if(n_blobs == MISC_BLOB_XTENSA_MAX) {
3411  printf("sig_match_zicokick_values: ignoring xtensa blobs > %d\n",MISC_BLOB_XTENSA_MAX);
3412  blobs[n_blobs].type = MISC_BLOB_TYPE_NONE;
3413  break;
3414  }
3415  // printf("xtensa blob @ 0x%08x, loads to 0x%08x, size 0x%08x\n",badr,bloadedto,bsize);
3416  blobs[n_blobs].type = MISC_BLOB_TYPE_XTENSA;
3417  blobs[n_blobs].rom_adr = badr;
3418  blobs[n_blobs].ram_adr = bloadedto;
3419  blobs[n_blobs].size = bsize;
3420  n_blobs++;
3421  }
3422  }
3423  uvi = 0;
3424  }
3425  else if (is->insn->id == ARM_INS_POP) {
3426  break;
3427  }
3428  }
3429  if(n_blobs > 0) {
3430  blobs[n_blobs].type = MISC_BLOB_TYPE_NONE;
3431  save_misc_val_blobs("zicokick_values",blobs,0);
3432  return 1;
3433  } else {
3434  free(blobs);
3435  return 0;
3436  }
3437 }
int sig_match_zoom_busy ( firmware fw,
iter_state_t is,
sig_rule_t rule 
)

Definiert in Zeile 4214 der Datei finsig_thumb2.c.

4215 {
4216  if(!init_disasm_sig_ref(fw,is,rule)) {
4217  return 0;
4218  }
4219  // first call
4220  if(!insn_match_find_next(fw,is,5,match_bl_blximm)) {
4221  // printf("sig_match_zoom_busy: no match bl\n");
4222  return 0;
4223  }
4224  // follow
4226  // get base address from first LDR PC
4227  if(!insn_match_find_next(fw,is,5,match_ldr_pc)) {
4228  // printf("sig_match_zoom_busy: match LDR PC failed\n");
4229  return 0;
4230  }
4231  uint32_t base=LDR_PC2val(fw,is->insn);
4232  arm_reg rb=is->insn->detail->arm.operands[0].reg;
4233 
4234  // look for first TakeSemaphoreStrictly
4235  if(!find_next_sig_call(fw,is,40,"TakeSemaphoreStrictly")) {
4236  // printf("sig_match_zoom_busy: no match TakeSemaphoreStrictly\n");
4237  return 0;
4238  }
4239  if(!disasm_iter(fw,is)) {
4240  // printf("sig_match_zoom_busy: disasm failed\n");
4241  return 0;
4242  }
4243  // assume next instruction is ldr
4244  if(is->insn->id != ARM_INS_LDR
4245  || is->insn->detail->arm.operands[0].reg != ARM_REG_R0
4246  || is->insn->detail->arm.operands[1].mem.base != rb) {
4247  // printf("sig_match_zoom_busy: no match LDR\n");
4248  return 0;
4249  }
4250  save_misc_val(rule->name,base,is->insn->detail->arm.operands[1].mem.disp,(uint32_t)is->insn->address);
4251  return 1;
4252 }
int sig_rule_applies ( firmware fw,
sig_rule_t rule 
)

Definiert in Zeile 5771 der Datei finsig_thumb2.c.

5772 {
5773  // dryos version
5774  if((rule->dryos_min && fw->dryos_ver_full < rule->dryos_min) || (rule->dryos_max && fw->dryos_ver_full > rule->dryos_max)) {
5775  return 0;
5776  }
5777  // empty flags == all
5778  if(!rule->flags) {
5779  return 1;
5780  }
5781  // digic 7 excluded, VMSA
5782  if((rule->flags & SIG_NO_D7) && (fw->arch_flags & FW_ARCH_FL_VMSA)) {
5783  return 0;
5784  }
5785  // digic 6 excluded, not VMSA
5786  if((rule->flags & SIG_NO_D6) && !(fw->arch_flags & FW_ARCH_FL_VMSA)) {
5787  return 0;
5788  }
5789  return 1;
5790 }
void write_func_lists ( firmware fw)

Definiert in Zeile 7046 der Datei finsig_thumb2.c.

7046  {
7047  sig_entry_t *fns[MAX_SIG_ENTRY];
7048  int k;
7049  for (k=0; k<next_sig_entry; k++)
7050  fns[k] = &sig_names[k];
7051 
7052  write_funcs(fw, "funcs_by_name.csv", fns, compare_sig_names);
7053  write_funcs(fw, "funcs_by_address.csv", fns, compare_func_addresses);
7054 }
void write_funcs ( firmware fw,
char *  filename,
sig_entry_t fns[],
int(*)(const sig_entry_t **p1, const sig_entry_t **p2)  compare 
)

Definiert in Zeile 7012 der Datei finsig_thumb2.c.

7013 {
7014  int k;
7015 
7016  qsort(fns, next_sig_entry, sizeof(sig_entry_t*), (void*)compare);
7017 
7018  FILE *out_fp = fopen(filename, "w");
7019  for (k=0; k<next_sig_entry; k++)
7020  {
7021  if (strncmp(fns[k]->name,"hook_",5) == 0) {
7022  continue;
7023  }
7024  if (fns[k]->val != 0)
7025  {
7026  if (fns[k]->flags & BAD_MATCH)
7027  {
7028  osig* ostub2 = find_sig(fw->sv->stubs,fns[k]->name);
7029  if (ostub2 && ostub2->val)
7030  fprintf(out_fp, "0x%08x,%s,(stubs_entry_2.s)\n", ostub2->val, fns[k]->name);
7031  }
7032  else
7033  fprintf(out_fp, "0x%08x,%s\n", fns[k]->val, fns[k]->name);
7034  }
7035 #ifdef LIST_IMPORTANT_FUNCTIONS
7036  else if (fns[k]->flags & LIST_ALWAYS)
7037  {
7038  // helps development by listing important functions even when not found
7039  fprintf(out_fp, "0,%s,(NOT FOUND)\n", fns[k]->name);
7040  }
7041 #endif
7042  }
7043  fclose(out_fp);
7044 }
void write_output ( )

Definiert in Zeile 70 der Datei finsig_thumb2.c.

71 {
72  add_blankline();
73  if (out_fp)
74  {
75  fprintf(out_fp,"%s",hdr_buf);
76  fprintf(out_fp,"%s",out_buf);
77  }
78 }
void write_physw_event_table_dump ( firmware fw,
uint32_t  tadr,
int  tcount 
)

Definiert in Zeile 6632 der Datei finsig_thumb2.c.

6633 {
6634  FILE *f=fopen("physw_bits.txt","w");
6635  if(!f) {
6636  return;
6637  }
6638  fprintf(f,"physw_event_table dump (%d entries printed, may not all be valid)\n",tcount);
6639  fprintf(f,"address info event index bit non-inverted\n");
6640  int i;
6642 
6643  for(i=0; i<tcount; i++,tadr += 8) {
6644  get_physw_table_entry(fw,tadr,&v);
6645  fprintf(f,"0x%08x 0x%08x 0x%08x %-5d 0x%08x %d\n",tadr,v.raw_info,v.ev,v.reg,v.bit,v.no_invert);
6646  }
6647  fclose(f);
6648 }
void write_stubs ( firmware fw,
int  max_find_func 
)

Definiert in Zeile 7282 der Datei finsig_thumb2.c.

7282  {
7283  int k;
7284  bprintf("// Values below can be overridden in 'stubs_min.S':\n");
7285  misc_val_t *stub_min=misc_vals;
7286  while(stub_min->name) {
7287  print_stubs_min_def(fw,stub_min);
7288  stub_min++;
7289  }
7290 
7292 
7293  add_blankline();
7294 
7295  for (k = 0; k < max_find_func; k++)
7296  {
7297  print_results(fw,&sig_names[k]);
7298  }
7299 }

Variablen-Dokumentation

char hdr_buf[32 *1024] = ""

Definiert in Zeile 42 der Datei finsig_thumb2.c.

int hdr_len = 0

Definiert in Zeile 43 der Datei finsig_thumb2.c.

int kcount = 0

Definiert in Zeile 6679 der Datei finsig_thumb2.c.

kinfo key_info[100]

Definiert in Zeile 6678 der Datei finsig_thumb2.c.

int kmask[3]

Definiert in Zeile 6677 der Datei finsig_thumb2.c.

known_prop_t knownprops[]
Initialisierung:
=
{
{"PROPCASE_AFSTEP" , -1, 2, 13, 13, 13, 13, 13, 13, 13, 13},
{"PROPCASE_FOCUS_STATE" , -1, 1, 18, 18, 18, 18, 18, 18, 18, 18},
{"PROPCASE_AV" , -1, 1, 23, 23, 23, 23, 23, 23, 23, 23},
{"PROPCASE_BV" , -1, 1, 34, 38, 35, 38, 40, 40, 40, 40},
{"PROPCASE_DELTA_DIGITALGAIN" , -1, 2, 77, 82, 79, 82, 84, 85, 85, 84},
{"PROPCASE_DELTA_SV" , -1, 1, 79, 84, 81, 84, 86, 87, 87, 86},
{"PROPCASE_DELTA_ND" , -1, 2, 80, 85, 82, 85, 87, 88, 88, 87},
{"PROPCASE_FELOCK" , -1, 2,114,120,117,120, 122, 123, 123, 122},
{"PROPCASE_FLASH_ADJUST_MODE" , -1, 1,121,127,124,127, 129, 130, 130, 129},
{"PROPCASE_FLASH_FIRE" , -1, 1,122,128,125,128, 130, 131, 131, 130},
{"PROPCASE_HSCAPTURE" , -1, 2,138,144,141,144, 146, 147, 147, 146},
{"PROPCASE_EV_CORRECTION_2" , -1, 1,210,216,213,216, 218, 219, 220, 218},
{"PROPCASE_ORIENTATION_SENSOR" , -1, 1,222,228,225,228, 230, 231, 232, 230},
{"PROPCASE_SV_MARKET" , -1, 1,249,255,252,255, 257, 259, 260, 258},
{"PROPCASE_SVFIX" , -1, 0, 0, 0, 0, 0, 0, 0, 0, 259},
{"PROPCASE_TV" , -1, 1,265,272,269,272, 274, 276, 277, 275},
{0,}
}

Definiert in Zeile 550 der Datei finsig_thumb2.c.

uint32_t kshutter_min_bits = 0xFFFFFFFF

Definiert in Zeile 6680 der Datei finsig_thumb2.c.

const insn_match_t match_open_mov_call[]
static
Initialisierung:

Definiert in Zeile 2003 der Datei finsig_thumb2.c.

misc_val_t misc_vals[]

Definiert in Zeile 611 der Datei finsig_thumb2.c.

int next_sig_entry = 0

Definiert in Zeile 98 der Datei finsig_thumb2.c.

char out_buf[32 *1024] = ""

Definiert in Zeile 40 der Datei finsig_thumb2.c.

FILE* out_fp

Definiert in Zeile 46 der Datei finsig_thumb2.c.

int out_hdr = 1

Definiert in Zeile 44 der Datei finsig_thumb2.c.

int out_len = 0

Definiert in Zeile 41 der Datei finsig_thumb2.c.

Definiert in Zeile 102 der Datei finsig_thumb2.c.

sig_rule_t sig_rules_initial[]
Initialisierung:
={
{sig_match_str_r0_call, "ExportToEventProcedure_FW","ExportToEventProcedure"},
{sig_match_reg_evp, "RegisterEventProcedure",},
{sig_match_reg_evp_table, "RegisterEventProcTable","DispDev_EnableEventProc"},
{sig_match_reg_evp_alt2, "RegisterEventProcedure_alt2","EngApp.Delete"},
{sig_match_unreg_evp_table,"UnRegisterEventProcTable","MechaUnRegisterEventProcedure"},
{sig_match_evp_table_veneer,"RegisterEventProcTable_alt","RegisterEventProcTable"},
{sig_match_evp_table_veneer,"UnRegisterEventProcTable_alt","UnRegisterEventProcTable"},
{sig_match_str_r0_call,"CreateTaskStrictly", "LowConsole",},
{sig_match_str_r0_call,"CreateTask", "EvShel",},
{sig_match_named, "CreateTask_low", "CreateTask", (SIG_NAMED_NTH(2,SUB)|SIG_NAMED_NTH_RANGE(10)), SIG_DRY_MAX(52)},
{sig_match_named, "CreateTask_low", "CreateTask", (SIG_NAMED_NTH(3,SUB)|SIG_NAMED_NTH_RANGE(10)), SIG_DRY_MIN(54)},
{sig_match_createtaskstrictly_alt,"CreateTaskStrictly_alt","HdmiCecTask",0, SIG_DRY_MIN(58)},
{sig_match_createtask_alt,"CreateTask_alt", "CreateTaskStrictly_alt",0, SIG_DRY_MIN(58)},
{sig_match_near_str, "dry_memcpy", "EP Slot%d", SIG_NEAR_BEFORE(4,1)},
{sig_match_add_ptp_handler,"add_ptp_handler", "PTPtoFAPI_EventProcTask_Try",},
{NULL},
}

Definiert in Zeile 5357 der Datei finsig_thumb2.c.

sig_rule_t sig_rules_main[]

Definiert in Zeile 5381 der Datei finsig_thumb2.c.