This source file includes following definitions.
- bprintf
- add_blankline
- write_output
- add_prop_hit
- get_misc_val
- get_misc_val_value
- save_misc_val
- save_misc_val_blobs
- find_saved_sig_index
- find_saved_sig
- get_saved_sig_val
- find_saved_sig_index_by_adr
- find_saved_sig_by_val
- save_sig
- add_func_name
- save_sig_veneers
- save_sig_with_j
- find_next_sig_call_ex
- find_next_sig_call
- is_sig_call
- init_disasm_sig_ref
- sig_match_str_r0_call
- sig_match_reg_evp
- sig_match_reg_evp_table
- sig_match_reg_evp_alt2
- sig_match_unreg_evp_table
- sig_match_evp_table_veneer
- sig_match_createtaskstrictly_alt
- sig_match_createtask_alt
- sig_match_get_nd_value
- sig_match_get_current_exp
- sig_match_get_current_nd_value
- sig_match_get_current_deltasv
- sig_match_imager_active_callback
- sig_match_imager_active
- sig_match_screenlock_helper
- sig_match_fclose_low
- sig_match_screenunlock
- sig_match_log_camera_event
- sig_match_physw_misc
- sig_match_kbd_read_keys
- sig_match_get_kbd_state
- sig_match_get_dial_hw_position
- sig_match_create_jumptable
- sig_match_take_semaphore_strict
- sig_match_get_semaphore_value
- sig_match_stat
- sig_match_open
- sig_match_umalloc
- sig_match_ufree
- sig_match_deletefile_fut
- sig_match_closedir
- save_sig_match_call
- sig_match_readfastdir
- sig_match_strrchr
- sig_match_time
- sig_match_strncpy
- sig_match_strncmp
- sig_match_strtolx
- sig_match_exec_evp
- sig_match_fgets_fut
- sig_match_log
- sig_match_pow_dry_52
- sig_match_pow_dry_gt_52
- sig_match_sqrt
- sig_match_get_drive_cluster_size
- sig_match_mktime_ext
- sig_match_rec2pb
- sig_match_get_parameter_data
- sig_match_prepdir_x
- sig_match_prepdir_1
- sig_match_prepdir_0
- sig_match_mkdir
- sig_match_add_ptp_handler
- sig_match_qsort
- sig_match_deletedirectory_fut
- sig_match_set_control_event
- sig_match_displaybusyonscreen_52
- sig_match_undisplaybusyonscreen_52
- sig_match_try_take_sem_dry_gt_57
- sig_match_wait_all_eventflag_strict
- sig_match_get_num_posted_messages
- sig_match_set_hp_timer_after_now
- sig_match_transfer_src_overlay
- sig_match_exmem_vars
- sig_match_zicokick_52
- sig_match_zicokick_gt52
- sig_match_zicokick_copy
- sig_match_zicokick_values
- sig_match_init_ex_drivers
- sig_match_omar_init
- sig_match_init_error_handlers
- sig_match_default_assert_handler
- sig_match_default_exception_handler
- sig_match_default_panic_handler
- sig_match_get_task_properties
- sig_match_enable_hdmi_power
- sig_match_disable_hdmi_power
- sig_match_levent_table
- sig_match_flash_param_table
- sig_match_jpeg_count_str
- sig_match_misc_flag_named
- sig_match_dry_memset
- sig_match_dry_memzero
- sig_match_dry_memzero
- sig_match_dry_memcpy_bytes
- sig_match_cam_has_iris_diaphragm
- sig_match_cam_uncached_bit
- sig_match_umalloc_strictly
- sig_match_dcache_clean_flush_and_disable
- sig_match_get_rom_id
- sig_match_dcache_flush_and_enable
- sig_match_physw_event_table
- sig_match_uiprop_count
- sig_match_get_canon_mode_list
- sig_match_zoom_busy
- sig_match_focus_busy
- sig_match_aram_size
- sig_match_aram_size_gt58
- sig_match_aram_start
- sig_match_aram_start2
- sig_match_icache_flush_range
- sig_match__nrflag
- sig_match_var_struct_get
- sig_match_ui_mem_func_ptr
- sig_match_func_ptr_val
- sig_match_av_over_sem
- sig_match_canon_menu_active
- sig_match_file_counter_init
- sig_match_file_counter_var
- sig_match_palette_vars
- sig_match_live_free_cluster_count
- sig_match_debug_logging_ptr
- sig_match_debug_logging_flag
- sig_match_mzrm_sendmsg_ret_adr
- sig_match_fw_yuv_layer_buf_52
- sig_match_fw_yuv_layer_buf_gt52
- sig_match_rom_ptr_get
- find_call_near_str
- sig_match_near_str
- find_str_arg_call
- sig_match_str_arg_call
- sig_match_prop_string
- is_immediate_ret_sub
- sig_match_named_last
- sig_match_named_save_sig
- sig_match_named
- sig_rule_applies
- run_sig_rules
- add_event_proc
- process_reg_eventproc_call
- process_eventproc_table_call
- process_createtask_call
- save_ptp_handler_func
- process_add_ptp_handler_call
- add_generic_func_match
- add_generic_sig_match
- find_exception_handlers
- find_generic_funcs
- find_ctypes
- print_misc_val_makefile
- output_firmware_vals
- print_platform_misc_val_undef
- output_platform_vals
- output_propcases
- output_exmem_types
- print_misc_val_comment
- get_physw_table_entry
- find_physw_table_entry
- find_physw_table_max
- write_physw_event_table_dump
- print_kval
- add_kinfo
- add_kmval
- kinfo_compare
- print_kmvals
- do_km_vals
- output_physw_vals
- output_modemap
- compare_sig_names
- compare_func_addresses
- write_funcs
- write_func_lists
- print_other_stubs_min
- print_stubs_min_def
- find_other_stubs_min
- print_results
- write_stubs
- main
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <stdint.h>
4 #include <string.h>
5 #include <time.h>
6 #include <stdarg.h>
7
8 #include <inttypes.h>
9
10 #include <capstone.h>
11
12
13 #include "stubs_load.h"
14 #include "firmware_load_ng.h"
15 #include "ptp_op_names.h"
16
17
18
19 #define SEARCH_NEAR_REF_RANGE 1024
20
21 #define SIG_NEAR_OFFSET_MASK 0x00FF
22 #define SIG_NEAR_COUNT_MASK 0xFF00
23 #define SIG_NEAR_COUNT_SHIFT 8
24 #define SIG_NEAR_REV 0x10000
25 #define SIG_NEAR_INDIRECT 0x20000
26 #define SIG_NEAR_JMP_SUB 0x40000
27 #define SIG_NEAR_AFTER(max_insns,n) (((max_insns)&SIG_NEAR_OFFSET_MASK) \
28 | (((n)<<SIG_NEAR_COUNT_SHIFT)&SIG_NEAR_COUNT_MASK))
29 #define SIG_NEAR_BEFORE(max_insns,n) (SIG_NEAR_AFTER(max_insns,n)|SIG_NEAR_REV)
30
31 #define SIG_STRCALL_ARG_MASK 0x3
32 #define SIG_STRCALL_ARG(arg_num) (arg_num)
33 #define SIG_STRCALL_TYPE_MASK 0xc
34 #define SIG_STRCALL_TYPE_SHIFT 2
35 #define SIG_STRCALL_CALL_IMM 0
36 #define SIG_STRCALL_JMP_REG 4
37 #define SIG_STRCALL_CALL_REG 8
38
39
40 char out_buf[32*1024] = "";
41 int out_len = 0;
42 char hdr_buf[32*1024] = "";
43 int hdr_len = 0;
44 int out_hdr = 1;
45
46 FILE *out_fp;
47
48 void bprintf(char *fmt, ...)
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 }
60
61 void add_blankline()
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 }
69
70 void write_output()
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 }
79
80
81
82 #define DONT_EXPORT 0x01
83 #define OPTIONAL 0x02
84 #define UNUSED 0x04
85 #define BAD_MATCH 0x08
86 #define EV_MATCH 0x10
87 #define LIST_ALWAYS 0x20
88
89 #define ARM_STUB 0x80
90 #define DONT_EXPORT_ILC 0x100
91
92 typedef struct {
93 char *name;
94 int flags;
95 uint32_t val;
96 } sig_entry_t;
97
98 int next_sig_entry = 0;
99
100 #define MAX_SIG_ENTRY 5000
101
102 sig_entry_t sig_names[MAX_SIG_ENTRY] =
103 {
104
105 { "ExportToEventProcedure_FW", UNUSED|DONT_EXPORT },
106 { "RegisterEventProcedure", UNUSED|DONT_EXPORT },
107 { "RegisterEventProcedure_alt1", UNUSED|DONT_EXPORT },
108 { "RegisterEventProcedure_alt2", UNUSED|DONT_EXPORT },
109 { "RegisterEventProcTable", UNUSED|DONT_EXPORT },
110 { "UnRegisterEventProcTable", UNUSED|DONT_EXPORT },
111 { "UnRegisterEventProcedure", UNUSED|DONT_EXPORT },
112 { "PrepareDirectory_1", UNUSED|DONT_EXPORT },
113 { "PrepareDirectory_x", UNUSED|DONT_EXPORT },
114 { "PrepareDirectory_0", UNUSED|DONT_EXPORT },
115 { "CreateTaskStrictly", UNUSED|DONT_EXPORT },
116 { "CreateTaskStrictly_alt", UNUSED|DONT_EXPORT },
117 { "CreateTask_alt", UNUSED|DONT_EXPORT },
118 { "CreateTask_low", UNUSED | OPTIONAL },
119 { "CreateJumptable", UNUSED },
120 { "_uartr_req", UNUSED },
121 { "StartRecModeMenu", UNUSED },
122 { "LogCameraEvent", UNUSED|DONT_EXPORT },
123 { "getImageDirName", UNUSED|DONT_EXPORT },
124
125 { "AllocateMemory", UNUSED|LIST_ALWAYS },
126 { "AllocateUncacheableMemory" },
127 { "Close" },
128 { "CreateBinarySemaphore" },
129 { "CreateCountingSemaphore", UNUSED|LIST_ALWAYS },
130 { "CreateTask" },
131 { "DebugAssert", OPTIONAL|LIST_ALWAYS },
132 { "DeleteDirectory_Fut" },
133 { "DeleteFile_Fut" },
134 { "DeleteSemaphore", },
135 { "DoAELock" },
136 { "DoAFLock" },
137 { "EnterToCompensationEVF" },
138 { "ExecuteEventProcedure", ARM_STUB },
139 { "ExitFromCompensationEVF" },
140 { "ExitTask" },
141 { "ExpCtrlTool_StartContiAE" },
142 { "ExpCtrlTool_StopContiAE" },
143 { "Fclose_Fut" },
144 { "Feof_Fut" },
145 { "Fflush_Fut" },
146 { "Fgets_Fut" },
147 { "Fopen_Fut" },
148 { "Fread_Fut" },
149 { "FreeMemory", UNUSED|LIST_ALWAYS },
150 { "FreeUncacheableMemory" },
151 { "Fseek_Fut" },
152 { "Fwrite_Fut" },
153 { "GetBatteryTemperature" },
154 { "GetCCDTemperature" },
155
156 { "GetCurrentAvValue" },
157 { "GetCurrentShutterSpeed" },
158 { "GetUsableMaxAv", OPTIONAL },
159 { "GetUsableMinAv", OPTIONAL },
160 { "GetUsableAvRange", UNUSED |OPTIONAL },
161 { "get_nd_value", OPTIONAL },
162 { "get_current_exp", UNUSED | OPTIONAL },
163 { "get_current_nd_value", OPTIONAL },
164 { "get_current_deltasv", },
165 { "GetCurrentDriveBaseSvValue", },
166 { "GetDrive_ClusterSize" },
167 { "GetDrive_FreeClusters", UNUSED },
168 { "GetDrive_TotalClusters" },
169 { "GetFocusLensSubjectDistance" },
170 { "GetFocusLensSubjectDistanceFromLens" },
171 { "GetImageFolder", OPTIONAL },
172 { "GetKbdState" },
173 { "GetMemInfo" },
174 { "GetOpticalTemperature" },
175 { "GetParameterData" },
176 { "GetPropertyCase" },
177 { "GetSystemTime" },
178 { "GetVRAMHPixelsSize" },
179 { "GetVRAMVPixelsSize" },
180 { "GetZoomLensCurrentPoint" },
181 { "GetZoomLensCurrentPosition" },
182 { "GiveSemaphore", OPTIONAL|LIST_ALWAYS },
183 { "IsStrobeChargeCompleted" },
184 { "LEDDrive", OPTIONAL },
185 { "LocalTime" },
186 { "LockMainPower" },
187 { "Lseek", UNUSED|LIST_ALWAYS },
188 { "MakeDirectory_Fut" },
189 { "MakeSDCardBootable", OPTIONAL },
190 { "MoveFocusLensToDistance" },
191 { "MoveIrisWithAv", OPTIONAL },
192 { "MoveZoomLensWithPoint", DONT_EXPORT_ILC},
193 { "NewTaskShell", UNUSED },
194 { "Open" },
195 { "PB2Rec" },
196 { "PT_MoveDigitalZoomToWide", OPTIONAL | DONT_EXPORT_ILC},
197 { "PT_MoveOpticalZoomAt", OPTIONAL | DONT_EXPORT_ILC },
198 { "MoveOpticalZoomAt", OPTIONAL | DONT_EXPORT_ILC },
199 { "PT_PlaySound" },
200 { "PostLogicalEventForNotPowerType" },
201 { "PostLogicalEventToUI" },
202 { "PutInNdFilter", OPTIONAL },
203 { "PutOutNdFilter", OPTIONAL },
204 { "Read" },
205 { "ReadFastDir" },
206 { "Rec2PB" },
207 { "Remove", OPTIONAL|UNUSED },
208 { "RenameFile_Fut" },
209 { "Restart" },
210 { "screenlock_helper", UNUSED|DONT_EXPORT },
211 { "ScreenLock" },
212 { "ScreenUnlock" },
213 { "SetAE_ShutterSpeed" },
214 { "SetAutoShutdownTime" },
215 { "SetCurrentCaptureModeType" },
216 { "SetDate" },
217 { "SetFileAttributes" },
218 { "SetFileTimeStamp" },
219 { "SetLogicalEventActive" },
220 { "SetParameterData" },
221 { "SetPropertyCase" },
222 { "SetScriptMode" },
223 { "SleepTask" },
224 { "TakeSemaphore" },
225 { "TurnOffBackLight" },
226 { "TurnOnBackLight" },
227 { "TurnOnDisplay" },
228 { "TurnOffDisplay" },
229 { "UIFS_WriteFirmInfoToFile", OPTIONAL|UNUSED},
230 { "UnlockAE" },
231 { "UnlockAF" },
232 { "UnlockMainPower" },
233 { "UnsetZoomForMovie", OPTIONAL | DONT_EXPORT_ILC },
234
235 { "VbattGet" },
236 { "Write" },
237 { "WriteSDCard" },
238
239 { "_log" },
240 { "_log10" },
241 { "_pow" },
242 { "_sqrt" },
243 { "add_ptp_handler" },
244 { "apex2us" },
245 { "close" },
246 { "displaybusyonscreen", OPTIONAL },
247 { "err_init_task", OPTIONAL },
248 { "exmem_alloc", OPTIONAL },
249 { "exmem_free", OPTIONAL|UNUSED },
250 { "exmem_ualloc" },
251 { "exmem_ufree" },
252 { "free" },
253
254 { "kbd_p1_f" },
255 { "kbd_p1_f_cont" },
256 { "kbd_p2_f" },
257 { "kbd_read_keys" },
258 { "kbd_read_keys_r2" },
259
260 { "kbd_pwr_off", OPTIONAL },
261 { "kbd_pwr_on", OPTIONAL },
262 { "lseek" },
263 { "malloc" },
264 { "memcmp" },
265 { "memcpy" },
266 { "memset" },
267
268
269 { "mktime_ext" },
270 { "open" },
271 { "OpenFastDir" },
272 { "closedir" },
273 { "get_fstype", OPTIONAL|LIST_ALWAYS },
274 { "qsort" },
275 { "rand" },
276 { "read", UNUSED|OPTIONAL },
277 { "realloc", OPTIONAL|LIST_ALWAYS },
278 { "reboot_fw_update" },
279 { "set_control_event" },
280 { "srand" },
281 { "stat" },
282 { "strcat" },
283 { "strchr" },
284 { "strcmp" },
285 { "strcpy" },
286 { "strftime" },
287 { "strlen" },
288 { "strncmp" },
289 { "strncpy" },
290 { "strrchr" },
291 { "strtol" },
292 { "strtolx" },
293 { "strstr", UNUSED|OPTIONAL},
294
295 { "task_CaptSeq" },
296 { "task_DvlpSeqTask", OPTIONAL },
297 { "task_ExpDrv" },
298 { "task_FileWrite", OPTIONAL },
299 { "task_InitFileModules" },
300 { "task_MovieRecord" },
301 { "task_PhySw", OPTIONAL },
302 { "task_RotaryEncoder", OPTIONAL },
303 { "task_TouchPanel", OPTIONAL },
304 { "task_TricInitTask", OPTIONAL },
305
306 { "hook_CreateTask" },
307 { "hook_CreateTask_low", UNUSED},
308
309 { "time" },
310 { "vsprintf" },
311 { "write", UNUSED|OPTIONAL },
312 { "undisplaybusyonscreen", OPTIONAL },
313
314 { "EngDrvIn", OPTIONAL|UNUSED|LIST_ALWAYS },
315 { "EngDrvOut", OPTIONAL|UNUSED|LIST_ALWAYS },
316 { "EngDrvRead" },
317 { "EngDrvBits", OPTIONAL|UNUSED|LIST_ALWAYS },
318
319 { "PTM_GetCurrentItem" },
320 { "PTM_SetCurrentItem", UNUSED|LIST_ALWAYS },
321 { "PTM_NextItem", OPTIONAL|UNUSED|LIST_ALWAYS },
322 { "PTM_PrevItem", OPTIONAL|UNUSED|LIST_ALWAYS },
323 { "PTM_SetPropertyEnable", OPTIONAL|UNUSED|LIST_ALWAYS },
324
325 { "DisableISDriveError", OPTIONAL },
326
327
328 { "_GetSystemTime", OPTIONAL|UNUSED|LIST_ALWAYS },
329 { "SetTimerAfter", OPTIONAL|UNUSED|LIST_ALWAYS },
330 { "SetTimerWhen", OPTIONAL|UNUSED|LIST_ALWAYS },
331 { "CancelTimer", OPTIONAL|UNUSED|LIST_ALWAYS },
332 { "CancelHPTimer" },
333 { "SetHPTimerAfterTimeout", OPTIONAL|UNUSED|LIST_ALWAYS },
334 { "SetHPTimerAfterNow" },
335 { "CreateTaskStrictly", OPTIONAL|UNUSED|LIST_ALWAYS },
336 { "CreateMessageQueue", OPTIONAL|UNUSED|LIST_ALWAYS },
337 { "CreateRecursiveLock", OPTIONAL|UNUSED|LIST_ALWAYS },
338 { "GetSemaphoreValue", OPTIONAL|UNUSED|LIST_ALWAYS },
339 { "TryTakeSemaphore", OPTIONAL|UNUSED|LIST_ALWAYS },
340 { "CreateMessageQueueStrictly", OPTIONAL|UNUSED|LIST_ALWAYS },
341 { "CreateEventFlagStrictly", OPTIONAL|UNUSED|LIST_ALWAYS },
342 { "CreateBinarySemaphoreStrictly", OPTIONAL|UNUSED|LIST_ALWAYS },
343 { "CreateCountingSemaphoreStrictly", OPTIONAL|UNUSED|LIST_ALWAYS },
344 { "CreateRecursiveLockStrictly", OPTIONAL|UNUSED|LIST_ALWAYS },
345 { "TakeSemaphoreStrictly", OPTIONAL|UNUSED|LIST_ALWAYS },
346 { "ReceiveMessageQueueStrictly", OPTIONAL|UNUSED|LIST_ALWAYS },
347 { "PostMessageQueueStrictly", OPTIONAL|UNUSED|LIST_ALWAYS },
348 { "WaitForAnyEventFlagStrictly", OPTIONAL|UNUSED|LIST_ALWAYS },
349 { "WaitForAllEventFlagStrictly", OPTIONAL|UNUSED|LIST_ALWAYS },
350 { "AcquireRecursiveLockStrictly", OPTIONAL|UNUSED|LIST_ALWAYS },
351 { "DeleteMessageQueue", OPTIONAL|UNUSED|LIST_ALWAYS },
352 { "PostMessageQueue", OPTIONAL|UNUSED|LIST_ALWAYS },
353 { "ReceiveMessageQueue", OPTIONAL|UNUSED|LIST_ALWAYS },
354 { "TryReceiveMessageQueue", OPTIONAL|UNUSED|LIST_ALWAYS },
355 { "TryPostMessageQueue", OPTIONAL|UNUSED|LIST_ALWAYS },
356 { "GetNumberOfPostedMessages", OPTIONAL|UNUSED|LIST_ALWAYS },
357 { "DeleteRecursiveLock", OPTIONAL|UNUSED|LIST_ALWAYS },
358 { "AcquireRecursiveLock", OPTIONAL|UNUSED|LIST_ALWAYS },
359 { "ReleaseRecursiveLock", OPTIONAL|UNUSED|LIST_ALWAYS },
360 { "WaitForAnyEventFlag", OPTIONAL|UNUSED|LIST_ALWAYS },
361 { "WaitForAllEventFlag", OPTIONAL|UNUSED|LIST_ALWAYS },
362 { "ClearEventFlag", OPTIONAL|UNUSED|LIST_ALWAYS },
363 { "SetEventFlag", OPTIONAL|LIST_ALWAYS },
364 { "GetEventFlagValue", OPTIONAL|UNUSED|LIST_ALWAYS },
365 { "CreateEventFlag", OPTIONAL|UNUSED|LIST_ALWAYS },
366 { "DeleteEventFlag", OPTIONAL|UNUSED|LIST_ALWAYS },
367 { "CheckAnyEventFlag", OPTIONAL|UNUSED|LIST_ALWAYS },
368 { "CheckAllEventFlag", OPTIONAL|UNUSED|LIST_ALWAYS },
369 { "RegisterInterruptHandler", OPTIONAL|UNUSED|LIST_ALWAYS },
370 { "UnregisterInterruptHandler", OPTIONAL|UNUSED|LIST_ALWAYS },
371 { "GetSRAndDisableInterrupt", OPTIONAL|UNUSED|LIST_ALWAYS },
372 { "SetSR", OPTIONAL|UNUSED|LIST_ALWAYS },
373 { "EnableInterrupt", OPTIONAL|UNUSED|LIST_ALWAYS },
374 { "_divmod_signed_int", OPTIONAL|UNUSED|LIST_ALWAYS},
375 { "_divmod_unsigned_int", OPTIONAL|UNUSED|LIST_ALWAYS},
376 { "_dflt", OPTIONAL|UNUSED|LIST_ALWAYS},
377 { "_dfltu", OPTIONAL|UNUSED|LIST_ALWAYS},
378 { "_dfix", OPTIONAL|UNUSED|LIST_ALWAYS},
379 { "_dfixu", OPTIONAL|UNUSED|LIST_ALWAYS},
380 { "_dmul", OPTIONAL|UNUSED|LIST_ALWAYS},
381 { "_ddiv", OPTIONAL|UNUSED|LIST_ALWAYS},
382 { "_dadd", OPTIONAL|UNUSED|LIST_ALWAYS},
383 { "_dsub", OPTIONAL|UNUSED|LIST_ALWAYS},
384 { "_drsb", OPTIONAL|UNUSED|LIST_ALWAYS},
385 { "_dcmp", OPTIONAL|UNUSED|LIST_ALWAYS},
386 { "_dcmp_reverse", OPTIONAL|UNUSED|LIST_ALWAYS},
387 { "_safe_sqrt", OPTIONAL|UNUSED|LIST_ALWAYS},
388 { "_scalbn", OPTIONAL|UNUSED|LIST_ALWAYS},
389 { "_fflt", OPTIONAL|UNUSED|LIST_ALWAYS},
390 { "_ffltu", OPTIONAL|UNUSED|LIST_ALWAYS},
391 { "_ffix", OPTIONAL|UNUSED|LIST_ALWAYS},
392 { "_ffixu", OPTIONAL|UNUSED|LIST_ALWAYS},
393 { "_fmul", OPTIONAL|UNUSED|LIST_ALWAYS},
394 { "_fdiv", OPTIONAL|UNUSED|LIST_ALWAYS},
395 { "_f2d", OPTIONAL|UNUSED|LIST_ALWAYS},
396 { "DisplayBusyOnScreen", OPTIONAL|UNUSED|LIST_ALWAYS},
397 { "UndisplayBusyOnScreen", OPTIONAL|UNUSED|LIST_ALWAYS},
398 { "CreateDialogBox", OPTIONAL|UNUSED|LIST_ALWAYS},
399 { "DisplayDialogBox", OPTIONAL|UNUSED|LIST_ALWAYS},
400 { "add_ui_to_dialog", OPTIONAL|UNUSED|LIST_ALWAYS},
401 { "get_string_by_id", OPTIONAL|UNUSED|LIST_ALWAYS},
402 { "malloc_strictly", OPTIONAL|UNUSED|LIST_ALWAYS },
403 { "GetCurrentMachineTime", OPTIONAL|UNUSED|LIST_ALWAYS },
404 { "HwOcReadICAPCounter", OPTIONAL|UNUSED|LIST_ALWAYS },
405 { "transfer_src_overlay_helper",UNUSED},
406 { "transfer_src_overlay" },
407 { "GraphicSystemCoreFinish_helper", OPTIONAL|UNUSED },
408 { "GraphicSystemCoreFinish", OPTIONAL|UNUSED },
409 { "mzrm_createmsg", OPTIONAL|UNUSED },
410 { "mzrm_sendmsg", OPTIONAL|UNUSED },
411 { "zicokick_start", OPTIONAL|UNUSED },
412 { "zicokick_copy", OPTIONAL|UNUSED },
413 { "init_ex_drivers", OPTIONAL|UNUSED },
414 { "omar_init", OPTIONAL|UNUSED },
415 { "init_error_handlers", OPTIONAL|UNUSED },
416 { "set_assert_handler", OPTIONAL|UNUSED },
417 { "set_exception_handler", OPTIONAL|UNUSED },
418 { "set_panic_handler", OPTIONAL|UNUSED },
419 { "default_assert_handler", OPTIONAL|UNUSED },
420 { "default_exception_handler", OPTIONAL|UNUSED },
421 { "default_panic_handler", OPTIONAL|UNUSED },
422 { "get_self_task_errno_pointer", OPTIONAL|UNUSED },
423 { "get_self_task_id", OPTIONAL|UNUSED },
424 { "get_task_properties", OPTIONAL|UNUSED },
425 { "dry_error_printf", OPTIONAL|UNUSED },
426 { "heap_alloc", OPTIONAL|UNUSED },
427 { "heap_free", OPTIONAL|UNUSED },
428 { "umalloc_strictly", OPTIONAL|UNUSED },
429 { "GetRomID", OPTIONAL|UNUSED },
430 { "init_task_error", OPTIONAL|UNUSED },
431 { "dry_panic", OPTIONAL|UNUSED },
432 { "dry_panic_low", OPTIONAL|UNUSED },
433 { "dry_con_printf", OPTIONAL|UNUSED },
434 { "cameracon_set_state", UNUSED },
435 { "cameracon_get_state", UNUSED },
436
437 { "createsemaphore_low", OPTIONAL|UNUSED },
438
439 { "givesemaphore_low", OPTIONAL|UNUSED},
440 { "takesemaphore_low", OPTIONAL|UNUSED },
441 { "bzero" },
442 { "memset32" },
443 { "dry_memset", OPTIONAL|UNUSED },
444 { "dry_memzero", OPTIONAL|UNUSED },
445 { "dry_memcpy_bytes", OPTIONAL|UNUSED },
446 { "dry_memmove_bytes", OPTIONAL|UNUSED },
447 { "get_dial_hw_position", OPTIONAL },
448
449
450
451 { "dcache_flush_and_enable", OPTIONAL|UNUSED },
452 { "dcache_clean_flush_and_disable", OPTIONAL|UNUSED },
453 { "dcache_flush_range", OPTIONAL|UNUSED },
454 { "dcache_clean_range", OPTIONAL|UNUSED },
455
456 { "icache_flush_range", OPTIONAL|UNUSED },
457 { "data_synchronization_barrier", OPTIONAL|UNUSED },
458
459
460 { "GetSDProtect", UNUSED },
461 { "DispCon_ShowBitmapColorBar", UNUSED },
462 { "ResetZoomLens", OPTIONAL|UNUSED },
463 { "ResetFocusLens", OPTIONAL|UNUSED },
464 { "NR_GetDarkSubType", OPTIONAL|UNUSED },
465 { "NR_SetDarkSubType", OPTIONAL|UNUSED },
466 { "SavePaletteData", OPTIONAL|UNUSED },
467 { "GUISrv_StartGUISystem", OPTIONAL|UNUSED|LIST_ALWAYS },
468 { "get_resource_pointer", OPTIONAL|UNUSED|LIST_ALWAYS },
469 { "CalcLog10", OPTIONAL|UNUSED|LIST_ALWAYS },
470 { "CalcSqrt", OPTIONAL|UNUSED },
471 { "dry_memcpy", OPTIONAL|UNUSED },
472 { "get_playrec_mode", OPTIONAL|UNUSED },
473 { "DebugAssert2", OPTIONAL|UNUSED },
474 { "get_canon_mode_list", OPTIONAL|UNUSED },
475 { "taskcreate_LowConsole", OPTIONAL|UNUSED },
476 { "ImagerActivate", OPTIONAL|UNUSED },
477 { "imager_active_callback", OPTIONAL|UNUSED },
478 { "file_counter_var_init", OPTIONAL|UNUSED },
479 { "get_displaytype", OPTIONAL|UNUSED },
480
481 { "Close_low", OPTIONAL|UNUSED },
482 { "Open_low", OPTIONAL|UNUSED },
483
484
485 { "fclose_low", OPTIONAL|UNUSED },
486
487
488 { "fgets_low", OPTIONAL|UNUSED },
489 { "fopen_low", OPTIONAL|UNUSED },
490 { "fut_prepare", OPTIONAL|UNUSED },
491 { "fut_finish", OPTIONAL|UNUSED },
492 { "fut_flush", OPTIONAL|UNUSED },
493 { "fread_low", OPTIONAL|UNUSED },
494 { "fseek_low", OPTIONAL|UNUSED },
495 { "fwrite_low", OPTIONAL|UNUSED },
496
497 { "MFOn", OPTIONAL },
498 { "MFOff", OPTIONAL },
499 { "PT_MFOn", OPTIONAL },
500 { "PT_MFOff", OPTIONAL },
501 { "SS_MFOn", OPTIONAL },
502 { "SS_MFOff", OPTIONAL },
503
504 { "GetAdChValue", OPTIONAL },
505
506
507 { "EnableHDMIPower", OPTIONAL },
508 { "DisableHDMIPower", OPTIONAL },
509
510 { "SetVideoOutType", OPTIONAL },
511 { "GetVideoOutType", OPTIONAL },
512
513 { "is_movie_recording", OPTIONAL|UNUSED },
514 { "IsWirelessConnect", OPTIONAL },
515
516 { "ui_malloc", OPTIONAL|UNUSED },
517 { "ui_malloc_default", OPTIONAL|UNUSED },
518 { "ui_free", OPTIONAL|UNUSED },
519 { "ui_free_default", OPTIONAL|UNUSED },
520
521
522 { "pvm_get_largest_free_block_size_ptr", OPTIONAL|UNUSED },
523 { "pvm_get_largest_free_block_size", OPTIONAL|UNUSED },
524 { "pvm_malloc", OPTIONAL|UNUSED },
525 { "pvm_free", OPTIONAL|UNUSED },
526 { "pvm_init_pool", OPTIONAL|UNUSED },
527
528 { "fw_yuv_layer_buf_helper", UNUSED},
529
530 {0,0,0},
531 };
532
533 typedef struct {
534 char* name;
535 int id;
536 int use;
537
538 int id_ps6;
539 int id_ps7;
540 int id_ps8;
541 int id_ps9;
542 int id_ps10;
543 int id_ps11;
544 int id_ps12;
545 int id_ps13;
546 } known_prop_t;
547
548 #define KNOWN_PROPSET_COUNT (13-5)
549
550 known_prop_t knownprops[] =
551 {
552 {"PROPCASE_AFSTEP" , -1, 2, 13, 13, 13, 13, 13, 13, 13, 13},
553 {"PROPCASE_FOCUS_STATE" , -1, 1, 18, 18, 18, 18, 18, 18, 18, 18},
554 {"PROPCASE_AV" , -1, 1, 23, 23, 23, 23, 23, 23, 23, 23},
555 {"PROPCASE_BV" , -1, 1, 34, 38, 35, 38, 40, 40, 40, 40},
556 {"PROPCASE_DELTA_DIGITALGAIN" , -1, 2, 77, 82, 79, 82, 84, 85, 85, 84},
557 {"PROPCASE_DELTA_SV" , -1, 1, 79, 84, 81, 84, 86, 87, 87, 86},
558 {"PROPCASE_DELTA_ND" , -1, 2, 80, 85, 82, 85, 87, 88, 88, 87},
559 {"PROPCASE_FELOCK" , -1, 2,114,120,117,120, 122, 123, 123, 122},
560 {"PROPCASE_FLASH_ADJUST_MODE" , -1, 1,121,127,124,127, 129, 130, 130, 129},
561 {"PROPCASE_FLASH_FIRE" , -1, 1,122,128,125,128, 130, 131, 131, 130},
562 {"PROPCASE_HSCAPTURE" , -1, 2,138,144,141,144, 146, 147, 147, 146},
563 {"PROPCASE_EV_CORRECTION_2" , -1, 1,210,216,213,216, 218, 219, 220, 218},
564 {"PROPCASE_ORIENTATION_SENSOR" , -1, 1,222,228,225,228, 230, 231, 232, 230},
565 {"PROPCASE_SV_MARKET" , -1, 1,249,255,252,255, 257, 259, 260, 258},
566 {"PROPCASE_SVFIX" , -1, 0, 0, 0, 0, 0, 0, 0, 0, 259},
567 {"PROPCASE_TV" , -1, 1,265,272,269,272, 274, 276, 277, 275},
568 {0,}
569 };
570
571 void add_prop_hit(char *name, int id)
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 }
582
583 #define MISC_BLOB_XTENSA_MAX 5
584 #define MISC_BLOB_TYPE_NONE 0
585 #define MISC_BLOB_TYPE_XTENSA 1
586 #define MISC_BLOB_TYPE_OMAR 2
587 typedef struct {
588 int type;
589 uint32_t rom_adr;
590 uint32_t ram_adr;
591 uint32_t size;
592 } misc_blob_t;
593
594
595 #define MISC_VAL_NO_STUB 1
596
597 #define MISC_VAL_DEF_CONST 2
598 #define MISC_VAL_OPTIONAL 4
599
600 typedef struct {
601 char *name;
602 int flags;
603 uint32_t val;
604
605 uint32_t base;
606 uint32_t offset;
607 uint32_t ref_adr;
608 misc_blob_t *blobs;
609 } misc_val_t;
610
611 misc_val_t misc_vals[]={
612
613 { "ctypes", },
614 { "physw_run", },
615 { "physw_sleep_delay", },
616 { "physw_status", },
617 { "fileio_semaphore", },
618 { "levent_table", },
619 { "FlashParamsTable", },
620 { "playrec_mode", },
621 { "jpeg_count_str", },
622 { "zoom_busy", },
623 { "focus_busy", },
624 { "imager_active", },
625 { "canon_menu_active", },
626 { "file_counter_var", },
627 { "cameracon_state", },
628 { "_nrflag", MISC_VAL_OPTIONAL},
629 { "av_override_semaphore",MISC_VAL_OPTIONAL},
630 { "active_bitmap_buffer",MISC_VAL_OPTIONAL},
631 { "displaytype", MISC_VAL_OPTIONAL},
632 { "bitmap_buffer", MISC_VAL_OPTIONAL},
633 { "palette_control", MISC_VAL_OPTIONAL},
634 { "palette_buffer_ptr", MISC_VAL_OPTIONAL},
635 { "active_palette_buffer",MISC_VAL_OPTIONAL},
636 { "live_free_cluster_count",MISC_VAL_OPTIONAL},
637 { "CAM_UNCACHED_BIT", MISC_VAL_NO_STUB},
638 { "physw_event_table", MISC_VAL_NO_STUB},
639 { "uiprop_count", MISC_VAL_DEF_CONST},
640 { "canon_mode_list", MISC_VAL_NO_STUB},
641 { "ARAM_HEAP_START", MISC_VAL_NO_STUB},
642 { "ARAM_HEAP_SIZE", MISC_VAL_NO_STUB},
643 { "zicokick_values", MISC_VAL_NO_STUB},
644 { "omar_init_data", MISC_VAL_NO_STUB},
645 { "omar_init_values", MISC_VAL_NO_STUB},
646 { "CAM_HAS_ND_FILTER", MISC_VAL_NO_STUB},
647 { "CAM_IS_ILC", MISC_VAL_NO_STUB},
648 { "CAM_HAS_IRIS_DIAPHRAGM",MISC_VAL_NO_STUB},
649 { "CAM_HAS_WIFI", MISC_VAL_NO_STUB},
650 { "exmem_alloc_table", },
651 { "exmem_types_table", },
652 { "exmem_type_count", MISC_VAL_DEF_CONST},
653 { "ui_malloc_ptr", MISC_VAL_NO_STUB},
654 { "ui_free_ptr", MISC_VAL_NO_STUB},
655 { "debug_logging_ptr", },
656 { "debug_logging_flag", },
657 { "mzrm_sendmsg_ret_adr", },
658 { "fw_yuv_layer_buf", MISC_VAL_DEF_CONST},
659
660 {0,0,0},
661 };
662
663 misc_val_t *get_misc_val(const char *name)
664 {
665 misc_val_t *p=misc_vals;
666 while(p->name) {
667 if(strcmp(name,p->name) == 0) {
668 return p;
669 }
670 p++;
671 }
672 return NULL;
673 }
674
675
676 uint32_t get_misc_val_value(const char *name)
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 }
685 void save_misc_val(const char *name, uint32_t base, uint32_t offset, uint32_t ref_adr)
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 }
698 void save_misc_val_blobs(const char *name, misc_blob_t *blobs, uint32_t ref_adr)
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 }
709
710
711 #if 0
712 int find_saved_sig_index(const char *name)
713 {
714 int i;
715 for (i=0; sig_names[i].name != 0; i++)
716 {
717 if (strcmp(name,sig_names[i].name) == 0)
718 {
719 return i;
720 }
721 }
722 return -1;
723 }
724 #endif
725
726 sig_entry_t * find_saved_sig(const char *name)
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 }
738
739
740 uint32_t get_saved_sig_val(const char *name)
741 {
742 sig_entry_t *sig=find_saved_sig(name);
743 if(!sig) {
744
745 return 0;
746 }
747 return sig->val;
748 }
749
750
751
752 #if 0
753 int find_saved_sig_index_by_adr(uint32_t adr)
754 {
755 if(!adr) {
756 return -1;
757 }
758 int i;
759 for (i=0; sig_names[i].name != 0; i++)
760 {
761 if (sig_names[i].val == adr)
762 {
763 return i;
764 }
765 }
766 return -1;
767 }
768 #endif
769 #if 0
770 sig_entry_t* find_saved_sig_by_val(uint32_t val)
771 {
772 if(!val) {
773 return NULL;
774 }
775 int i;
776 for (i=0; sig_names[i].name != 0; i++)
777 {
778 if (sig_names[i].val == val)
779 {
780 return &sig_names[i];
781 }
782 }
783 return NULL;
784 }
785 #endif
786
787
788 void save_sig(firmware *fw, const char *name, uint32_t val)
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
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 }
806
807 void add_func_name(firmware *fw, char *n, uint32_t eadr, char *suffix)
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
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)
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)
842 {
843 if (mallocd)
844 free(s);
845 return;
846 }
847 else
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
854 sig_names[next_sig_entry].name = s;
855 sig_names[next_sig_entry].flags = OPTIONAL|UNUSED;
856 sig_names[next_sig_entry].val = eadr;
857 next_sig_entry++;
858 sig_names[next_sig_entry].name = 0;
859 }
860
861
862 uint32_t save_sig_veneers(firmware *fw, const char *name, uint32_t adr)
863 {
864
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
870
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 {
880
881 sprintf(buf,"j_%s",name);
882 }
883 add_func_name(fw,buf,adr,NULL);
884 adr=b_adr;
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 }
892
893
894 int save_sig_with_j(firmware *fw, char *name, uint32_t adr)
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 }
907
908 #define FIND_SIG_CALL_NO_UNK_VENEER 1
909
910
911 int find_next_sig_call_ex(firmware *fw, iter_state_t *is, uint32_t max_offset, const char *name, uint32_t flags)
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
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 {
945 search_fn = search_disasm_calls_veneer_multi;
946 }
947 match_fns[i].adr=0;
948 return fw_search_insn(fw,is,search_fn,0,match_fns,is->adr + max_offset);
949 }
950
951 int find_next_sig_call(firmware *fw, iter_state_t *is, uint32_t max_offset, const char *name)
952 {
953 return find_next_sig_call_ex(fw,is,max_offset,name,0);
954 }
955
956
957
958 int is_sig_call(firmware *fw, iter_state_t *is, const char *name)
959 {
960 uint32_t adr=get_branch_call_insn_target(fw,is);
961
962
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 }
985
986
987 #define SIG_DRY_MIN(min_rel) (min_rel)*FW_DRYOS_VER_MUL,0
988 #define SIG_DRY_MAX(max_rel) 0,(max_rel)*FW_DRYOS_VER_MUL+(FW_DRYOS_VER_MUL-1)
989 #define SIG_DRY_RANGE(min_rel,max_rel) (min_rel)*FW_DRYOS_VER_MUL,\
990 (max_rel)*FW_DRYOS_VER_MUL+(FW_DRYOS_VER_MUL-1)
991
992 #define SIG_DRY_MINP(min_rel,min_patch) (min_rel)*FW_DRYOS_VER_MUL + (min_patch),0
993 #define SIG_DRY_MAXP(max_rel,max_patch) 0,(max_rel)*FW_DRYOS_VER_MUL + (max_patch)
994 #define SIG_DRY_RANGEP(min_rel,min_patch,max_rel,max_patch) \
995 (min_rel)*FW_DRYOS_VER_MUL + (min_patch), \
996 (max_rel)*FW_DRYOS_VER_MUL + (max_patch)
997
998 #define SIG_DRY_ANY 0,0
999
1000
1001 #define SIG_NO_D6 1
1002 #define SIG_NO_D7 2
1003
1004 typedef struct sig_rule_s sig_rule_t;
1005 typedef int (*sig_match_fn)(firmware *fw, iter_state_t *is, sig_rule_t *rule);
1006
1007 struct sig_rule_s {
1008 sig_match_fn match_fn;
1009 char *name;
1010 char *ref_name;
1011 int param;
1012 int dryos_min;
1013 int dryos_max;
1014 unsigned flags;
1015 };
1016
1017
1018 int init_disasm_sig_ref(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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 }
1035
1036 int sig_match_near_str(firmware *fw, iter_state_t *is, sig_rule_t *rule);
1037 uint32_t find_str_arg_call(firmware *fw, iter_state_t *is, sig_rule_t *rule);
1038
1039
1040
1041
1042
1043 int sig_match_str_r0_call(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
1052
1053
1054 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
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
1058
1059 if(insn_match_find_next(fw,is,4,match_b_bl_blximm)) {
1060 uint32_t adr=get_branch_call_insn_target(fw,is);
1061
1062 return save_sig_with_j(fw,rule->name,adr);
1063 }
1064 }
1065 }
1066 return 0;
1067 }
1068
1069
1070 int sig_match_reg_evp(firmware *fw, iter_state_t *is, __attribute__ ((unused))sig_rule_t *rule)
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}},
1075 {MATCH_INS(B, MATCH_OPCOUNT_IGNORE)},
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
1086 uint32_t reg_evp=0;
1087
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
1092 save_sig(fw,"RegisterEventProcedure",reg_evp);
1093 }
1094 return (reg_evp != 0);
1095 }
1096
1097
1098
1099 int sig_match_reg_evp_table(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1100 {
1101
1102 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
1103 if(!str_adr) {
1104 printf("sig_match_reg_evp_table: failed to find %s\n",rule->ref_name);
1105 return 0;
1106 }
1107
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);
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
1121 save_sig(fw,"RegisterEventProcedure_alt1",reg_evp_alt1);
1122
1123 uint32_t regs[4];
1124
1125
1126 if((get_call_const_args(fw,is,4,regs)&3)==3) {
1127
1128 if(regs[0]==str_adr) {
1129 dd_enable_p=regs[1];
1130
1131 add_func_name(fw,"DispDev_EnableEventProc",dd_enable_p,NULL);
1132 break;
1133 }
1134 }
1135 }
1136
1137 if(dd_enable_p) {
1138 disasm_iter_init(fw,is,dd_enable_p);
1139 if(insn_match_find_next(fw,is,4,match_b_bl)) {
1140
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
1145 save_sig(fw,"RegisterEventProcTable",reg_evp_tbl);
1146 }
1147 }
1148 }
1149 return (reg_evp_tbl != 0);
1150 }
1151
1152
1153 int sig_match_reg_evp_alt2(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1154 {
1155 uint32_t reg_evp_alt2=0;
1156
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
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);
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
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
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
1185
1186 }
1187 break;
1188 }
1189 }
1190 }
1191 return (reg_evp_alt2 != 0);
1192 }
1193
1194
1195 int sig_match_unreg_evp_table(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
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);
1208 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
1209
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
1218
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
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
1235 disasm_iter_init(fw,is,mecha_unreg);
1236
1237 if(!insn_match_find_next(fw,is,7,match_b_bl)) {
1238 return 0;
1239 }
1240
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 }
1258
1259
1260
1261 int sig_match_evp_table_veneer(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1262 {
1263 uint32_t ref_adr = get_saved_sig_val(rule->ref_name);
1264 int prevb = 0;
1265 uint32_t cadr;
1266
1267
1268 disasm_iter_init(fw,is,ref_adr);
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
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 }
1288
1289
1290 int sig_match_createtaskstrictly_alt(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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);
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
1302
1303 if(insn_match_find_next(fw,is,4,match_b_bl_blximm)) {
1304 uint32_t adr=get_branch_call_insn_target(fw,is);
1305 uint32_t adr2 = get_saved_sig_val("CreateTaskStrictly");
1306
1307 if(adr == adr2) {
1308
1309 return 0;
1310 }
1311 adr2 = get_saved_sig_val("j_CreateTaskStrictly");
1312 if(adr == adr2) {
1313
1314 return 0;
1315 }
1316 return save_sig_with_j(fw,rule->name,adr);
1317 }
1318 }
1319 }
1320 return 0;
1321 }
1322
1323
1324 int sig_match_createtask_alt(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1325 {
1326
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 }
1338 uint32_t adr = get_branch_call_insn_target(fw,is);
1339 uint32_t adr2 = get_saved_sig_val("CreateTask");
1340
1341 if(adr == adr2) {
1342
1343 return 0;
1344 }
1345 adr2 = get_saved_sig_val("j_CreateTask");
1346 if(adr == adr2) {
1347
1348 return 0;
1349 }
1350 return save_sig_with_j(fw,rule->name,adr);
1351 }
1352
1353
1354 int sig_match_get_nd_value(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1355 {
1356
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
1373 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
1374 disasm_iter(fw,is);
1375 if (B_target(fw,is->insn))
1376 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
1377
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 }
1382 uint32_t addr=get_branch_call_insn_target(fw,is);
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 }
1389
1390 int sig_match_get_current_exp(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
1400 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
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
1406 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
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 }
1413
1414 int sig_match_get_current_nd_value(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1415 {
1416
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
1428
1429 const insn_match_t match_bl_strh[]={
1430 {MATCH_INS(BL,MATCH_OPCOUNT_IGNORE)},
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
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 }
1443
1444 int sig_match_get_current_deltasv(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
1454
1455 const insn_match_t match_bl_strh[]={
1456 {MATCH_INS(BL,MATCH_OPCOUNT_IGNORE)},
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
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 }
1469
1470
1471 int sig_match_imager_active_callback(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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)}},
1478 {MATCH_INS(BL, MATCH_OPCOUNT_IGNORE)},
1479 {MATCH_INS(MOV,2), {MATCH_OP_REG(R0), MATCH_OP_IMM(0)}},
1480 {MATCH_INS(POP, MATCH_OPCOUNT_IGNORE)},
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
1489 disasm_iter_init(fw,is,adr_hist_get(&is->ah,3));
1490
1491 disasm_iter(fw,is);
1492 uint32_t f1=LDR_PC2val(fw,is->insn);
1493
1494
1495 return save_sig_with_j(fw,rule->name,f1);
1496 }
1497 int sig_match_imager_active(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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[]={
1504 {MATCH_INS(LDR, 2), {MATCH_OP_REG_ANY, MATCH_OP_MEM_BASE(PC)}},
1505 {MATCH_INS(MOV,2), {MATCH_OP_REG_ANY, MATCH_OP_IMM(1)}},
1506 {MATCH_INS(STR, 2), {MATCH_OP_REG_ANY, MATCH_OP_MEM_ANY}},
1507 {MATCH_INS(POP, MATCH_OPCOUNT_IGNORE)},
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
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)}},
1517 {MATCH_INS(LDR, 2), {MATCH_OP_REG_ANY, MATCH_OP_MEM_BASE(PC)}},
1518 {MATCH_INS(STR, 2), {MATCH_OP_REG_ANY, MATCH_OP_MEM_ANY}},
1519 {MATCH_INS(POP, MATCH_OPCOUNT_IGNORE)},
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
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
1534
1535 if(backtrack == 3) {
1536 disasm_iter(fw,is);
1537 }
1538 disasm_iter(fw,is);
1539
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
1546 save_misc_val("imager_active",base,off,(uint32_t)is->insn->address);
1547 return 1;
1548 }
1549
1550 int sig_match_screenlock_helper(firmware *fw, iter_state_t *is, sig_rule_t *rule) {
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
1556
1557 const insn_match_t match_cmp_bne_bl[]={
1558 {MATCH_INS(CMP, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM(0)}},
1559 {MATCH_INS_CC(B,NE,MATCH_OPCOUNT_IGNORE)},
1560 {MATCH_INS(BL,MATCH_OPCOUNT_IGNORE)},
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)}},
1566 {MATCH_INS_CC(B,AL,MATCH_OPCOUNT_IGNORE)},
1567 {ARM_INS_ENDING}
1568 };
1569
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
1575
1576
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
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 }
1597
1598 int sig_match_fclose_low(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1599 {
1600 if(!init_disasm_sig_ref(fw,is,rule)) {
1601
1602 return 0;
1603 }
1604 if(!find_next_sig_call(fw,is,24,"strlen")) {
1605
1606 return 0;
1607 }
1608 if(!find_next_sig_call(fw,is,26,"malloc")) {
1609
1610 return 0;
1611 }
1612 if(!find_next_sig_call(fw,is,14,"strcpy")) {
1613
1614 return 0;
1615 }
1616
1617 if(!insn_match_find_nth(fw,is,12,3,match_bl_blximm)) {
1618
1619 return 0;
1620 }
1621 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1622 }
1623
1624 int sig_match_screenunlock(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1625 {
1626 if(!init_disasm_sig_ref(fw,is,rule)) {
1627 return 0;
1628 }
1629
1630 if(!find_next_sig_call(fw,is,14,"ScreenLock")) {
1631
1632 return 0;
1633 }
1634
1635
1636 const insn_match_t match_end[]={
1637 {MATCH_INS(POP, MATCH_OPCOUNT_IGNORE)},
1638 {MATCH_INS_CC(B,AL,MATCH_OPCOUNT_IGNORE)},
1639 {ARM_INS_ENDING}
1640 };
1641 if(!insn_match_find_next_seq(fw,is,38,match_end)) {
1642
1643 return 0;
1644 }
1645
1646 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1647 }
1648
1649
1650 int sig_match_log_camera_event(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
1657 return 0;
1658 }
1659 uint32_t regs[4];
1660 if((get_call_const_args(fw,is,4,regs)&3)!=3) {
1661
1662 return 0;
1663 }
1664 if(regs[0] != 0x60) {
1665
1666 return 0;
1667 }
1668 const char *str=(char *)adr2ptr(fw,regs[1]);
1669 if(!str || strcmp(str,"_SImage") != 0) {
1670
1671 return 0;
1672 }
1673 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1674 }
1675
1676
1677 int sig_match_physw_misc(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
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 }
1721 uint32_t f=get_branch_call_insn_target(fw,is);
1722
1723
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
1731
1732 save_sig_with_j(fw,"SleepTask",f);
1733 }
1734
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
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
1747 if(!disasm_iter(fw,is)) {
1748 printf("sig_match_physw_misc: disasm failed\n");
1749 return 0;
1750 }
1751
1752
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
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 }
1765
1766 int sig_match_kbd_read_keys(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1767 {
1768 if(!init_disasm_sig_ref(fw,is,rule)) {
1769 return 0;
1770 }
1771
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 }
1780 uint32_t physw_status=LDR_PC2val(fw,is->insn);
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 }
1788
1789
1790 int sig_match_get_kbd_state(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1791 {
1792 if(!init_disasm_sig_ref(fw,is,rule)) {
1793 return 0;
1794 }
1795
1796 insn_match_t match[]={
1797 {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM_BASE(PC)}},
1798 {MATCH_INS(BL, MATCH_OPCOUNT_IGNORE)},
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
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 }
1813
1814 int sig_match_get_dial_hw_position(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
1822 return 0;
1823 }
1824
1825 disasm_iter_init(fw,is,adr);
1826 adr = find_last_call_from_func(fw,is,16,32);
1827 if(!adr) {
1828
1829 return 0;
1830 }
1831
1832 disasm_iter_init(fw,is,adr);
1833
1834 if(!insn_match_find_next(fw,is,30,match_bl_blximm)) {
1835
1836 return 0;
1837 }
1838 uint32_t fadr = get_branch_call_insn_target(fw,is);
1839
1840 disasm_iter_init(fw,is,adr_hist_get(&is->ah,4));
1841 const insn_match_t match_hw_dial_call[]={
1842 {MATCH_INS(ADD,MATCH_OPCOUNT_ANY), {MATCH_OP_REG(R0)}},
1843 {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0),MATCH_OP_MEM_BASE(PC)}},
1844 {MATCH_INS(BL,MATCH_OPCOUNT_IGNORE)},
1845 {ARM_INS_ENDING}
1846 };
1847 if(!insn_match_find_next(fw,is,4,match_hw_dial_call)) {
1848
1849 return 0;
1850 }
1851 return save_sig_with_j(fw,rule->name,fadr);
1852 }
1853
1854 int sig_match_create_jumptable(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1855 {
1856 if(!init_disasm_sig_ref(fw,is,rule)) {
1857 return 0;
1858 }
1859
1860 if(!insn_match_find_nth(fw,is,20,2,match_bl_blximm)) {
1861 return 0;
1862 }
1863
1864 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
1865 if(!insn_match_find_next(fw,is,15,match_bl_blximm)) {
1866 return 0;
1867 }
1868
1869 save_sig(fw,"CreateJumptable",get_branch_call_insn_target(fw,is));
1870 return 1;
1871 }
1872
1873
1874 int sig_match_take_semaphore_strict(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1875 {
1876 if(!init_disasm_sig_ref(fw,is,rule)) {
1877 return 0;
1878 }
1879
1880 if(!insn_match_find_next(fw,is,6,match_bl_blximm)) {
1881 return 0;
1882 }
1883
1884 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
1885
1886 if(!insn_match_find_nth(fw,is,10,2,match_bl_blximm)) {
1887 return 0;
1888 }
1889
1890 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
1891
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
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
1906 for(i=1; i<7; i++) {
1907 fw_disasm_iter_single(fw,adr_hist_get(&is->ah,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
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 }
1936
1937 int sig_match_get_semaphore_value(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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);
1946
1947 if(!fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
1948
1949 return 0;
1950 }
1951
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
1957 return 0;
1958 }
1959 if(insn_match_any(fw->is->insn,match_bl_blximm)){
1960 fadr=get_branch_call_insn_target(fw,fw->is);
1961 break;
1962 }
1963 }
1964 if(!fadr) {
1965
1966 return 0;
1967 }
1968
1969 disasm_iter_init(fw,is,fadr);
1970
1971 if(!insn_match_find_next(fw,is,9,match_bl_blximm)) {
1972
1973 return 0;
1974 }
1975 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1976 }
1977
1978 int sig_match_stat(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
1987 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
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)) {
1991 uint32_t adr=get_branch_call_insn_target(fw,is);
1992
1993 if(is_sig_call(fw,is,"Fopen_Fut_FW")) {
1994 continue;
1995 }
1996
1997 return save_sig_with_j(fw,rule->name,adr);
1998 }
1999 }
2000 }
2001 return 0;
2002 }
2003 static const insn_match_t match_open_mov_call[]={
2004
2005 {MATCH_INS(MOV, 2), {MATCH_OP_REG_ANY, MATCH_OP_REG_ANY}},
2006 {MATCH_INS(MOV, 2), {MATCH_OP_REG_ANY, MATCH_OP_REG_ANY}},
2007 {MATCH_INS(MOV, 2), {MATCH_OP_REG_ANY, MATCH_OP_REG_ANY}},
2008 {MATCH_INS(BL, MATCH_OPCOUNT_IGNORE)},
2009 {ARM_INS_ENDING}
2010 };
2011
2012
2013
2014 int sig_match_open(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2015 {
2016 if(!init_disasm_sig_ref(fw,is,rule)) {
2017 return 0;
2018 }
2019 if(!insn_match_find_next_seq(fw,is,48,match_open_mov_call)) {
2020 return 0;
2021 }
2022 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2023 }
2024
2025
2026 int sig_match_umalloc(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2027 {
2028 if(!init_disasm_sig_ref(fw,is,rule)) {
2029 return 0;
2030 }
2031
2032 if(!insn_match_find_nth(fw,is,15,3,match_bl_blximm)) {
2033 return 0;
2034 }
2035
2036 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
2037
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 }
2043
2044
2045 int sig_match_ufree(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2046 {
2047 if(!init_disasm_sig_ref(fw,is,rule)) {
2048 return 0;
2049 }
2050
2051 if(!find_next_sig_call(fw,is,60,"strcpy_FW")) {
2052 return 0;
2053 }
2054
2055 if(!insn_match_find_nth(fw,is,12,3,match_bl_blximm)) {
2056 return 0;
2057 }
2058
2059 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
2060
2061 if(!find_next_sig_call(fw,is,40,"Close_FW")) {
2062 return 0;
2063 }
2064
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 }
2070
2071 int sig_match_deletefile_fut(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
2079 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
2080 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2081
2082 if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
2083 continue;
2084 }
2085
2086 uint32_t adr=get_branch_call_insn_target(fw,is);
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 }
2106
2107 uint32_t find_call_near_str(firmware *fw, iter_state_t *is, sig_rule_t *rule);
2108
2109 int sig_match_closedir(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
2117 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
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);
2130 const insn_match_t match_closedir[]={
2131 {MATCH_INS(BL,MATCH_OPCOUNT_IGNORE)},
2132 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R0), MATCH_OP_REG_ANY}},
2133 {MATCH_INS(BL,MATCH_OPCOUNT_IGNORE)},
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 }
2143
2144
2145 int save_sig_match_call(firmware* fw, sig_rule_t *rule, uint32_t call_adr)
2146 {
2147 disasm_iter_init(fw,fw->is,call_adr);
2148 disasm_iter(fw,fw->is);
2149 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,fw->is));
2150 }
2151
2152 int sig_match_readfastdir(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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);
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
2173 fw_disasm_iter_single(fw,adr_hist_get(&is->ah,2));
2174 if(insn_match_any(fw->is->insn,match_bl_blximm)) {
2175 uint32_t call_adr = iter_state_adr(fw->is);
2176 fw_disasm_iter_single(fw,adr_hist_get(&is->ah,1));
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
2184 fw_disasm_iter_single(fw,adr_hist_get(&is->ah,i));
2185 if(insn_match_any(fw->is->insn,match_bl_blximm)) {
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 }
2200
2201 int sig_match_strrchr(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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);
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 }
2220
2221 int sig_match_time(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
2230 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
2231 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2232
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
2242 disasm_iter_init(fw,is,fadr);
2243
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 }
2249
2250 int sig_match_strncpy(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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 }
2263
2264 int sig_match_strncmp(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
2272 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
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
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 }
2287
2288 int sig_match_strtolx(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
2297 if(!insn_match_find_next(fw,is,6,match_bl_blximm)) {
2298 return 0;
2299 }
2300 uint32_t adr=get_branch_call_insn_target(fw,is);
2301 if(!adr) {
2302 return 0;
2303 }
2304
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
2311
2312
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 }
2326
2327
2328 int sig_match_exec_evp(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
2336 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
2337 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2338
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
2346 uint32_t adr=(uint32_t)(fw->is->insn->address) | is->thumb;
2347
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 }
2357
2358 int sig_match_fgets_fut(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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)) {
2369 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
2370 } else {
2371 if (B_target(fw,is->insn) && (is->insn->detail->arm.cc == ARM_CC_NE)) {
2372 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
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 }
2380
2381 int sig_match_log(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
2391 if(!insn_match_find_nth(fw,is,38,3,match_pop6)) {
2392 return 0;
2393 }
2394
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 }
2400
2401
2402 int sig_match_pow_dry_52(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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[]={
2411 {MATCH_INS(LDRD, 3), {MATCH_OP_REG(R0), MATCH_OP_REG(R1), MATCH_OP_ANY}},
2412 {ARM_INS_ENDING}
2413 };
2414
2415 if(!insn_match_find_next(fw,is,50,match_ldrd_r0_r1)) {
2416 return 0;
2417 }
2418
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 }
2426 uint32_t adr=get_branch_call_insn_target(fw,is);
2427 if(!adr) {
2428 return 0;
2429 }
2430 return save_sig_with_j(fw,rule->name,adr);
2431 }
2432
2433
2434 int sig_match_pow_dry_gt_52(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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)}},
2446 {MATCH_INS(BL, MATCH_OPCOUNT_IGNORE)},
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)}},
2454 {MATCH_INS(BL, MATCH_OPCOUNT_IGNORE)},
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
2462 if(insn_match_find_next_seq(fw,is,50,match1[idx]))
2463 break;
2464 init_disasm_sig_ref(fw,is,rule);
2465 }
2466
2467 if (idx >= 2)
2468 return 0;
2469
2470 uint32_t adr=get_branch_call_insn_target(fw,is);
2471 if(!adr) {
2472 return 0;
2473 }
2474
2475 disasm_iter_init(fw,is,adr);
2476 const insn_match_t match2a[]={
2477 {MATCH_INS(LDRD,3), {MATCH_OP_REG(R0), MATCH_OP_REG(R1), MATCH_OP_MEM_ANY}},
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
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 }
2497
2498 int sig_match_sqrt(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2499 {
2500 if(!init_disasm_sig_ref(fw,is,rule)) {
2501 return 0;
2502 }
2503
2504 if(!insn_match_find_nth(fw,is,12,3,match_bl_blximm)) {
2505 return 0;
2506 }
2507
2508 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
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
2515 if(j_tgt) {
2516
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
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 }
2529 int sig_match_get_drive_cluster_size(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2530 {
2531 if(!init_disasm_sig_ref(fw,is,rule)) {
2532 return 0;
2533 }
2534
2535 if(fw_search_insn(fw,is,search_disasm_str_ref,0,"A/OpLogErr.txt",(uint32_t)is->adr+260)) {
2536
2537 if(!insn_match_find_next(fw,is,3,match_bl_blximm)) {
2538
2539 return 0;
2540 }
2541
2542 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
2543
2544 if(!insn_match_find_nth(fw,is,13,2,match_bl_blximm)) {
2545
2546 return 0;
2547 }
2548
2549 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
2550 disasm_iter(fw,is);
2551 if (B_target(fw, is->insn))
2552 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
2553
2554 if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
2555
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 }
2562
2563 int sig_match_mktime_ext(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
2571 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
2572 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2573
2574 if(!find_next_sig_call(fw,is,12,"sscanf_FW")) {
2575
2576 return 0;
2577 }
2578
2579 if(!insn_match_find_next(fw,is,22,match_bl_blximm)) {
2580
2581 return 0;
2582 }
2583
2584 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
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
2591 if(j_tgt) {
2592
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
2606 if(!insn_match_find_next(fw,is,54,match_pop4)) {
2607
2608 return 0;
2609 }
2610 if(!insn_match_find_next(fw,is,1,match_b)) {
2611
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 }
2618
2619
2620 int sig_match_rec2pb(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
2628 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
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
2637 continue;
2638 }
2639
2640 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
2641 if(!insn_match_find_next(fw,is,3,match_b_bl_blximm)) {
2642
2643
2644 return 0;
2645 }
2646 uint32_t adr = iter_state_adr(is);
2647
2648 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
2649 if(!find_next_sig_call(fw,is,16,"LogCameraEvent")) {
2650
2651 return 0;
2652 }
2653 uint32_t regs[4];
2654 if((get_call_const_args(fw,is,4,regs)&3)!=3) {
2655
2656 return 0;
2657 }
2658
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
2663 return 0;
2664 }
2665 }
2666 return 0;
2667 }
2668
2669
2670 int sig_match_get_parameter_data(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2671 {
2672 if(!init_disasm_sig_ref(fw,is,rule)) {
2673 return 0;
2674 }
2675 const insn_match_t match_cmp_bhs[]={
2676 {MATCH_INS(CMP, 2), {MATCH_OP_REG_ANY, MATCH_OP_IMM_ANY}},
2677 {MATCH_INS_CC(B,HS,MATCH_OPCOUNT_IGNORE)},
2678 {ARM_INS_ENDING}
2679 };
2680 if(!insn_match_find_next_seq(fw,is,4,match_cmp_bhs)) {
2681
2682 return 0;
2683 }
2684
2685 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
2686 if(!insn_match_find_next(fw,is,1,match_b)) {
2687
2688 return 0;
2689 }
2690 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2691 }
2692
2693
2694
2695
2696 int sig_match_prepdir_x(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
2710 return 0;
2711 }
2712 if(!insn_match_find_next(fw,is,1,match_b)) {
2713
2714 return 0;
2715 }
2716 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2717 }
2718
2719
2720
2721
2722 int sig_match_prepdir_1(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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 }
2749
2750 int sig_match_prepdir_0(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
2761 disasm_iter(fw,is);
2762 disasm_iter(fw,is);
2763
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
2774 return 0;
2775 }
2776 if(!insn_match_find_next(fw,is,1,match_b)) {
2777
2778 return 0;
2779 }
2780 uint32_t pdx=get_branch_call_insn_target(fw,is);
2781 if(pdx != ref_pdx) {
2782
2783 return 0;
2784 }
2785 return save_sig_with_j(fw,rule->name,adr);
2786 }
2787 int sig_match_mkdir(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2788 {
2789 if(!init_disasm_sig_ref(fw,is,rule)) {
2790 return 0;
2791 }
2792 const insn_match_t match[]={
2793 {MATCH_INS(STRB,2), {MATCH_OP_REG_ANY, MATCH_OP_MEM_ANY}},
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)}},
2796 {MATCH_INS(BL, MATCH_OPCOUNT_IGNORE)},
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}},
2806 {MATCH_INS(STRB,2), {MATCH_OP_REG_ANY, MATCH_OP_MEM_ANY}},
2807 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R0), MATCH_OP_REG(SP)}},
2808 {MATCH_INS(BL, MATCH_OPCOUNT_IGNORE)},
2809 {ARM_INS_ENDING}
2810 };
2811 if(!insn_match_find_next_seq(fw,is,148,match2)) {
2812
2813 return 0;
2814 }
2815 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2816 }
2817
2818 int sig_match_add_ptp_handler(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
2826 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
2827 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2828
2829 if(!find_next_sig_call(fw,is,8,"CreateTaskStrictly")) {
2830
2831 continue;
2832 }
2833
2834 if(!insn_match_find_nth(fw,is,13,3,match_bl_blximm)) {
2835
2836 return 0;
2837 }
2838
2839 uint32_t regs[4];
2840 if((get_call_const_args(fw,is,5,regs)&7)!=7) {
2841
2842 return 0;
2843 }
2844 if(regs[0] < 0x9000 || regs[0] > 0x10000 || !adr2ptr(fw,regs[1]) || regs[2] != 0) {
2845
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 }
2852 int sig_match_qsort(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
2859 return 0;
2860 }
2861 if(!insn_match_find_nth(fw,is,38,3,match_bl_blximm)) {
2862
2863 return 0;
2864 }
2865
2866 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
2867
2868 if(insn_match_find_next(fw,is,4,match_bl_blximm)) {
2869 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
2870 }
2871 if(!insn_match_find_next(fw,is,14,match_bl_blximm)) {
2872
2873 return 0;
2874 }
2875
2876 uint32_t regs[4];
2877 if((get_call_const_args(fw,is,5,regs)&0xe)!=0xe) {
2878
2879 return 0;
2880 }
2881 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2882 }
2883
2884
2885
2886
2887
2888
2889
2890
2891 int sig_match_deletedirectory_fut(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
2899
2900 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - 2048) | fw->thumb_default);
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
2905 continue;
2906 }
2907 if(!is_sig_call(fw,is,"strcpy")) {
2908
2909 continue;
2910 }
2911 if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
2912
2913 continue;
2914 }
2915 if(!is_sig_call(fw,is,"strrchr")) {
2916
2917 continue;
2918 }
2919
2920 uint32_t regs[4];
2921 if((get_call_const_args(fw,is,2,regs)&0x2)!=0x2) {
2922
2923 continue;
2924 }
2925 if(regs[1] != '/') {
2926
2927 continue;
2928 }
2929 if(!insn_match_find_next(fw,is,5,match_bl_blximm)) {
2930
2931 continue;
2932 }
2933 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2934 }
2935 return 0;
2936 }
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947 int sig_match_set_control_event(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2948 {
2949 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2950 if(!str_adr) {
2951
2952
2953 return 0;
2954 }
2955 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
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
2959 continue;
2960 }
2961 if(!is_sig_call(fw,is,"LogCameraEvent")) {
2962
2963 continue;
2964 }
2965 const insn_match_t match_seq[]={
2966 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R0), MATCH_OP_REG_ANY,}},
2967 {MATCH_INS(BL, MATCH_OPCOUNT_IGNORE)},
2968 {MATCH_INS(BL, MATCH_OPCOUNT_IGNORE)},
2969 {ARM_INS_ENDING}
2970 };
2971 if(!insn_match_find_next_seq(fw,is,1,match_seq)) {
2972
2973 continue;
2974 }
2975 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2976 }
2977 return 0;
2978 }
2979
2980 int sig_match_displaybusyonscreen_52(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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);
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
2994 continue;
2995 }
2996 if(!is_sig_call(fw,is,"LogCameraEvent")) {
2997
2998 continue;
2999 }
3000 if(!find_next_sig_call(fw,is,4,"GUISrv_StartGUISystem_FW")) {
3001
3002 continue;
3003 }
3004 if(!insn_match_find_nth(fw,is,5,2,match_bl_blximm)) {
3005
3006 continue;
3007 }
3008 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3009 }
3010 return 0;
3011 }
3012
3013 int sig_match_undisplaybusyonscreen_52(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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);
3024 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
3025
3026 if(!find_next_sig_call(fw,is,24,"displaybusyonscreen")) {
3027
3028 continue;
3029 }
3030 if(!find_next_sig_call(fw,is,12,"GUISrv_StartGUISystem_FW")) {
3031
3032 continue;
3033 }
3034 if(!insn_match_find_nth(fw,is,6,3,match_bl_blximm)) {
3035
3036 continue;
3037 }
3038 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3039 }
3040 return 0;
3041 }
3042
3043 int sig_match_try_take_sem_dry_gt_57(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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 }
3062
3063 int sig_match_wait_all_eventflag_strict(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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 }
3087
3088 int sig_match_get_num_posted_messages(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
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 }
3104
3105 int sig_match_set_hp_timer_after_now(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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);
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
3116 continue;
3117 }
3118
3119 if(!insn_match_find_nth(fw,is,13,3,match_bl_blximm)) {
3120
3121 continue;
3122 }
3123
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
3128
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
3136 continue;
3137 }
3138
3139 if(regs[0] != 70000) {
3140
3141 continue;
3142 }
3143 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3144 }
3145 return 0;
3146 }
3147 int sig_match_transfer_src_overlay(firmware *fw, iter_state_t *is, sig_rule_t *rule) {
3148 if(!init_disasm_sig_ref(fw,is,rule)) {
3149 return 0;
3150 }
3151
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
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
3167 uint32_t fadr = get_branch_call_insn_target(fw,is);
3168
3169
3170 save_misc_val("active_bitmap_buffer",desc.adr_adj,desc.off,(uint32_t)is->insn->address);
3171
3172
3173
3174
3175 const insn_match_t bm_buf_match[]={
3176 {MATCH_INS(LDR, 2), {MATCH_OP_REG_ANY, MATCH_OP_MEM_ANY}},
3177 {MATCH_INS(ADD, 3), {MATCH_OP_REG(R0), MATCH_OP_REG_ANY, MATCH_OP_IMM_ANY}},
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
3186
3187
3188
3189 }
3190
3191
3192
3193
3194
3195 return save_sig_with_j(fw,rule->name,fadr);
3196 }
3197
3198
3199 int sig_match_exmem_vars(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
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
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 }
3249
3250
3251 int sig_match_zicokick_52(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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);
3259
3260
3261 if(!fw_search_insn(fw,is,search_disasm_str_ref,0,rule->ref_name,(uint32_t)is->adr+SEARCH_NEAR_REF_RANGE)) {
3262 printf("sig_match_zicokick_52: failed to find insn ref %s\n",rule->ref_name);
3263 return 0;
3264 }
3265
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
3275 uint32_t adr=(uint32_t)(fw->is->insn->address) | is->thumb;
3276
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 }
3286
3287 int sig_match_zicokick_gt52(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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);
3295
3296
3297 if(!fw_search_insn(fw,is,search_disasm_str_ref,0,rule->ref_name,(uint32_t)is->adr+SEARCH_NEAR_REF_RANGE)) {
3298 printf("sig_match_zicokick_gt52: failed to find insn ref %s\n",rule->ref_name);
3299 return 0;
3300 }
3301 int i;
3302
3303
3304
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 }
3323 int sig_match_zicokick_copy(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3324 {
3325 if(!init_disasm_sig_ref(fw,is,rule)) {
3326 return 0;
3327 }
3328
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)}},
3335 {MATCH_INS(BL,MATCH_OPCOUNT_IGNORE)},
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
3343 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3344 }
3345
3346 int sig_match_zicokick_values(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3347 {
3348 if(!init_disasm_sig_ref(fw,is,rule)) {
3349 return 0;
3350 }
3351
3352 #if 0
3353
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
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
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
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 }
3438
3439 int sig_match_init_ex_drivers(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3440 {
3441 if(!init_disasm_sig_ref(fw,is,rule)) {
3442 return 0;
3443 }
3444 int i;
3445 int b_count;
3446
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
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 }
3479
3480 int sig_match_omar_init(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
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
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 }
3533
3534 int sig_match_init_error_handlers(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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 }
3549
3550 int sig_match_default_assert_handler(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
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 }
3567
3568 int sig_match_default_exception_handler(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
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 }
3585
3586 int sig_match_default_panic_handler(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
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 }
3603
3604 int sig_match_get_task_properties(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
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 }
3624
3625 int sig_match_enable_hdmi_power(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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[]={
3635 {MATCH_INS(BL, MATCH_OPCOUNT_IGNORE)},
3636 {MATCH_INS(CBNZ, MATCH_OPCOUNT_IGNORE)},
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
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 }
3649
3650 int sig_match_disable_hdmi_power(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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[]={
3664 {MATCH_INS(BL, MATCH_OPCOUNT_IGNORE)},
3665 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM(1)}},
3666 {MATCH_INS(POP, MATCH_OPCOUNT_IGNORE)},
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
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 }
3680
3681 int sig_match_levent_table(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
3688 return 0;
3689 }
3690
3691 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
3692
3693
3694 if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
3695
3696 return 0;
3697 }
3698
3699
3700 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
3701
3702
3703 disasm_iter(fw,is);
3704 uint32_t adr=LDR_PC2val(fw,is->insn);
3705 if(!adr) {
3706
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
3719 save_misc_val(rule->name,adr,0,(uint32_t)is->insn->address);
3720 return 1;
3721 }
3722 int sig_match_flash_param_table(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3723 {
3724 if(!init_disasm_sig_ref(fw,is,rule)) {
3725 return 0;
3726 }
3727
3728 if(!insn_match_find_next(fw,is,14,match_bl_blximm)) {
3729
3730 return 0;
3731 }
3732 if(!is_sig_call(fw,is,"DebugAssert")) {
3733
3734 return 0;
3735 }
3736 if(!insn_match_find_next(fw,is,7,match_bl_blximm)) {
3737
3738 return 0;
3739 }
3740 if(!is_sig_call(fw,is,"DebugAssert")) {
3741
3742 return 0;
3743 }
3744 if(!insn_match_find_next(fw,is,8,match_bl_blximm)) {
3745
3746 return 0;
3747 }
3748 if(!is_sig_call(fw,is,"DebugAssert")) {
3749
3750 return 0;
3751 }
3752
3753 if(!insn_match_find_nth(fw,is,14,2,match_bl_blximm)) {
3754
3755 return 0;
3756 }
3757
3758 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
3759
3760
3761 if(!insn_match_find_next(fw,is,8,match_bl_blximm)) {
3762
3763 return 0;
3764 }
3765
3766
3767 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
3768
3769 disasm_iter(fw,is);
3770 uint32_t adr=LDR_PC2val(fw,is->insn);
3771 if(!adr) {
3772
3773 return 0;
3774 }
3775 save_misc_val(rule->name,adr,0,(uint32_t)is->insn->address);
3776 return 1;
3777 }
3778 int sig_match_jpeg_count_str(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
3786 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
3787 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
3788
3789 if(!insn_match_find_next(fw,is,3,match_bl_blximm)) {
3790
3791 continue;
3792 }
3793 if(!is_sig_call(fw,is,"sprintf_FW")) {
3794
3795 continue;
3796 }
3797
3798 uint32_t regs[4];
3799 if((get_call_const_args(fw,is,5,regs)&0x3)!=0x3) {
3800
3801 continue;
3802 }
3803 if(regs[1] != str_adr) {
3804
3805 return 0;
3806 }
3807 if(!adr_is_var(fw,regs[0])) {
3808
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 }
3816
3817
3818 int sig_match_misc_flag_named(__attribute__ ((unused))firmware *fw, __attribute__ ((unused))iter_state_t *is, sig_rule_t *rule)
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 }
3824
3825 int sig_match_dry_memset(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
3835 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
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 }
3842
3843 int sig_match_dry_memzero(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
3853 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
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 }
3860
3861 #if 0
3862
3863 int sig_match_dry_memzero(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3864 {
3865 if(!init_disasm_sig_ref(fw,is,rule)) {
3866 return 0;
3867 }
3868 const insn_match_t match_start[]={
3869 {MATCH_INS(AND, 3), {MATCH_OP_REG(R3), MATCH_OP_REG(R2), MATCH_OP_IMM(0xff)}},
3870 {MATCH_INS(ORR, 3), {MATCH_OP_REG(R2), MATCH_OP_REG(R3), MATCH_OP_REG(R3)}},
3871 {MATCH_INS(ORR, 3), {MATCH_OP_REG(R2), MATCH_OP_REG(R2), MATCH_OP_REG(R2)}},
3872 {MATCH_INS(B, 1), {MATCH_OP_IMM_ANY}},
3873 {ARM_INS_ENDING}
3874 };
3875 if(!insn_match_find_next_seq(fw,is,1,match_start)) {
3876 printf("sig_match_dry_memzero: no match start\n");
3877 return 0;
3878 }
3879
3880 uint32_t adr = get_branch_call_insn_target(fw,is) - 4;
3881 disasm_iter_init(fw,is,adr);
3882 const insn_match_t match_mov_r2_0[]={
3883 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R2), MATCH_OP_IMM(0x0)}},
3884 {ARM_INS_ENDING}
3885 };
3886 if(!insn_match_find_next(fw,is,1,match_mov_r2_0)) {
3887 printf("sig_match_dry_memzero: no match mov\n");
3888 return 0;
3889 }
3890 return save_sig_with_j(fw,rule->name,adr);
3891 }
3892 #endif
3893
3894 int sig_match_dry_memcpy_bytes(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
3904 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
3905
3906 const insn_match_t match_end[]={
3907 {MATCH_INS(POP, MATCH_OPCOUNT_IGNORE)},
3908 {MATCH_INS_CC(B,AL,MATCH_OPCOUNT_IGNORE)},
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 }
3918
3919
3920 int sig_match_cam_has_iris_diaphragm(__attribute__ ((unused))firmware *fw, __attribute__ ((unused))iter_state_t *is, sig_rule_t *rule)
3921 {
3922 uint32_t v;
3923 uint32_t ref=0;get_saved_sig_val(rule->ref_name);
3924
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 }
3934
3935 int sig_match_cam_uncached_bit(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3936 {
3937 if(!init_disasm_sig_ref(fw,is,rule)) {
3938 return 0;
3939 }
3940 const insn_match_t match_bic_r0[]={
3941 {MATCH_INS(BIC, 3), {MATCH_OP_REG(R0), MATCH_OP_REG(R0), MATCH_OP_IMM_ANY}},
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 }
3950
3951 int sig_match_umalloc_strictly(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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);
3960 if(!fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
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
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
3982 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
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 }
3989
3990 int sig_match_dcache_clean_flush_and_disable(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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 }
4005
4006 int sig_match_get_rom_id(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4007 {
4008 if(!init_disasm_sig_ref(fw,is,rule)) {
4009 return 0;
4010 }
4011
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[]={
4027 {MATCH_INS(MOV, 2), {MATCH_OP_REG_ANY, MATCH_OP_REG_ANY}},
4028 {MATCH_INS(BL, 1), {MATCH_OP_IMM_ANY}},
4029 {MATCH_INS(MOV, 2), {MATCH_OP_REG_ANY, MATCH_OP_REG_ANY}},
4030 {MATCH_INS(POP, MATCH_OPCOUNT_IGNORE)},
4031 {MATCH_INS(B, MATCH_OPCOUNT_IGNORE)},
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 }
4044
4045 int sig_match_dcache_flush_and_enable(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
4059
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
4065 disasm_iter_init(fw,is,adr_hist_get(&is->ah,2));
4066 disasm_iter(fw,is);
4067 uint32_t adr = get_branch_call_insn_target(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 }
4074
4075
4076 int sig_match_physw_event_table(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4077 {
4078 if(!init_disasm_sig_ref(fw,is,rule)) {
4079 return 0;
4080 }
4081
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 }
4098 int sig_match_uiprop_count(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
4105 return 0;
4106 }
4107 if(!find_next_sig_call(fw,is,14,"DebugAssert")) {
4108
4109 return 0;
4110 }
4111 const insn_match_t match_bic_cmp[]={
4112 {MATCH_INS(BIC, 3), {MATCH_OP_REG_ANY, MATCH_OP_REG_ANY, MATCH_OP_IMM(0x8000)}},
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
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 }
4123
4124 int sig_match_get_canon_mode_list(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
4133 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
4134 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
4135
4136 if(!find_next_sig_call(fw,is,4,"LogCameraEvent")) {
4137
4138 continue;
4139 }
4140
4141 if(!disasm_iter(fw,is)) {
4142
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
4155 continue;
4156 }
4157 } else {
4158 if(!insn_match_any(is->insn,match_bl_blximm)) {
4159
4160 continue;
4161 }
4162 }
4163
4164 adr=get_branch_call_insn_target(fw,is);
4165 break;
4166 }
4167 if(!adr) {
4168 return 0;
4169 }
4170
4171 disasm_iter_init(fw,is,adr);
4172 if(!find_next_sig_call(fw,is,40,"TakeSemaphoreStrictly")) {
4173
4174 return 0;
4175 }
4176
4177 if(!insn_match_find_nth(fw,is,12,2,match_b_bl_blximm)) {
4178
4179 return 0;
4180 }
4181
4182 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
4183 const insn_match_t match_loop[]={
4184 {MATCH_INS(ADD, 3), {MATCH_OP_REG_ANY, MATCH_OP_REG_ANY, MATCH_OP_IMM(1)}},
4185 {MATCH_INS(UXTH, 2), {MATCH_OP_REG_ANY, MATCH_OP_REG_ANY}},
4186 {MATCH_INS(CMP, 2), {MATCH_OP_REG_ANY, MATCH_OP_IMM_ANY}},
4187 {MATCH_INS_CC(B,LO,MATCH_OPCOUNT_IGNORE)},
4188 {ARM_INS_ENDING}
4189 };
4190 if(!insn_match_find_next_seq(fw,is,64,match_loop)) {
4191
4192 return 0;
4193 }
4194 if(!insn_match_find_next(fw,is,2,match_bl_blximm)) {
4195
4196 return 0;
4197 }
4198
4199 adr=get_branch_call_insn_target(fw,is);
4200
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
4209 return 0;
4210 }
4211 return save_sig_with_j(fw,rule->name,adr);
4212 }
4213
4214 int sig_match_zoom_busy(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4215 {
4216 if(!init_disasm_sig_ref(fw,is,rule)) {
4217 return 0;
4218 }
4219
4220 if(!insn_match_find_next(fw,is,5,match_bl_blximm)) {
4221
4222 return 0;
4223 }
4224
4225 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
4226
4227 if(!insn_match_find_next(fw,is,5,match_ldr_pc)) {
4228
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
4235 if(!find_next_sig_call(fw,is,40,"TakeSemaphoreStrictly")) {
4236
4237 return 0;
4238 }
4239 if(!disasm_iter(fw,is)) {
4240
4241 return 0;
4242 }
4243
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
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 }
4253
4254 int sig_match_focus_busy(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4255 {
4256 if(!init_disasm_sig_ref(fw,is,rule)) {
4257 return 0;
4258 }
4259
4260 if(!find_next_sig_call(fw,is,40,"TakeSemaphore")) {
4261
4262 return 0;
4263 }
4264
4265 if(!insn_match_find_next(fw,is,5,match_bl_blximm)) {
4266
4267 return 0;
4268 }
4269
4270 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
4271
4272 if(!insn_match_find_next(fw,is,5,match_ldr_pc)) {
4273
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
4280 if(!find_next_sig_call(fw,is,50,"TakeSemaphoreStrictly")) {
4281
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
4291 return 0;
4292 }
4293
4294 disasm_iter_init(fw,is,adr_hist_get(&is->ah,1));
4295 disasm_iter(fw,is);
4296
4297 if(is->insn->detail->arm.operands[1].mem.base != rb) {
4298
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 }
4304 int sig_match_aram_size(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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 }
4326
4327 int sig_match_aram_size_gt58(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
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);
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 }
4358
4359 int sig_match_aram_start(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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)}},
4371 {MATCH_INS_CC(B,NE,MATCH_OPCOUNT_IGNORE)},
4372 {MATCH_INS(LDR, 2), {MATCH_OP_REG_ANY,MATCH_OP_MEM_BASE(PC)}},
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
4385 save_misc_val(rule->name,adr,0,(uint32_t)is->insn->address);
4386 return 1;
4387 }
4388
4389 int sig_match_aram_start2(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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)}},
4404 {MATCH_INS_CC(B,NE,MATCH_OPCOUNT_IGNORE)},
4405 {MATCH_INS(LDR, 2), {MATCH_OP_REG_ANY,MATCH_OP_MEM_BASE(SP)}},
4406 {MATCH_INS(LDR, 2), {MATCH_OP_REG_ANY,MATCH_OP_MEM_BASE(PC)}},
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
4419 save_misc_val(rule->name,adr,0,(uint32_t)is->insn->address);
4420 return 1;
4421 }
4422
4423 int sig_match_icache_flush_range(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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 }
4443
4444 int sig_match__nrflag(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4445 {
4446 if(!init_disasm_sig_ref(fw,is,rule)) {
4447 return 0;
4448 }
4449 uint32_t fadr=is->adr;
4450
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)},
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
4461 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
4462 if(!disasm_iter(fw,is)) {
4463 printf("sig_match__nrflag: disasm failed\n");
4464 return 0;
4465 }
4466
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;
4473 if(!disasm_iter(fw,is)) {
4474 printf("sig_match__nrflag: disasm failed\n");
4475 return 0;
4476 }
4477
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 }
4501
4502
4503
4504
4505 int sig_match_var_struct_get(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
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 }
4528
4529
4530
4531
4532
4533 int sig_match_ui_mem_func_ptr(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
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 }
4561
4562
4563 int sig_match_func_ptr_val(firmware *fw, __attribute__ ((unused))iter_state_t *is, sig_rule_t *rule)
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 }
4575
4576
4577 int sig_match_av_over_sem(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4578 {
4579
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
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 }
4603
4604 int sig_match_canon_menu_active(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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 }
4625
4626 int sig_match_file_counter_init(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4627 {
4628 if(!init_disasm_sig_ref(fw,is,rule)) {
4629 return 0;
4630 }
4631
4632 if(!insn_match_find_next(fw,is,3,match_bl_blximm)) {
4633
4634 return 0;
4635 }
4636
4637 if(check_simple_func(fw,get_branch_call_insn_target(fw,is),MATCH_SIMPLE_FUNC_NULLSUB,NULL)) {
4638 if(!insn_match_find_next(fw,is,3,match_bl_blximm)) {
4639
4640 return 0;
4641 }
4642 }
4643
4644 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
4645 if(!insn_match_find_next(fw,is,3,match_bl_blximm)) {
4646
4647 return 0;
4648 }
4649 uint32_t fadr = get_branch_call_insn_target(fw,is);
4650
4651 disasm_iter_init(fw,is,fadr);
4652 if(!disasm_iter(fw,is)) {
4653
4654 return 0;
4655 }
4656
4657 if(!isLDR_PC(is->insn)) {
4658
4659 return 0;
4660 }
4661
4662 return save_sig_with_j(fw,rule->name,fadr);
4663 }
4664 int sig_match_file_counter_var(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
4672 return 0;
4673 }
4674 if(is->insn->detail->arm.operands[0].reg != ARM_REG_R0) {
4675
4676 return 0;
4677 }
4678 if(!adr_is_var(fw,adr)) {
4679
4680 return 0;
4681 }
4682 save_misc_val(rule->name,adr,0,(uint32_t)is->insn->address);
4683 return 1;
4684 }
4685
4686 int sig_match_palette_vars(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
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
4713 disasm_iter_init(fw,is,fadr);
4714
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
4720 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
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
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
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
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 }
4779
4780 int sig_match_live_free_cluster_count(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4781 {
4782 if(!init_disasm_sig_ref(fw,is,rule)) {
4783 return 0;
4784 }
4785
4786
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
4792 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
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
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
4806 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
4807
4808
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}},
4826 {MATCH_INS(LDRD, 3), {MATCH_OP_REG_ANY, 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
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 }
4839
4840 int sig_match_debug_logging_ptr(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
4848 arm_reg call_reg = is->insn->detail->arm.operands[0].reg;
4849
4850
4851 int i;
4852 for(i=1; i<10; i++) {
4853 fw_disasm_iter_single(fw,adr_hist_get(&is->ah,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
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
4864 fw_disasm_iter_single(fw,adr_hist_get(&is->ah,i));
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 }
4879
4880 int sig_match_debug_logging_flag(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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 }
4924 int sig_match_mzrm_sendmsg_ret_adr(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
4935 save_misc_val(rule->name,(uint32_t)is->insn->address | is->thumb,0,0);
4936 return 1;
4937 }
4938
4939 int sig_match_fw_yuv_layer_buf_52(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4940 {
4941 if(!init_disasm_sig_ref(fw,is,rule)) {
4942 return 0;
4943 }
4944
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
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);
4962 return 0;
4963 }
4964
4965 int sig_match_fw_yuv_layer_buf_gt52(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
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);
4985 return 0;
4986 }
4987
4988 int sig_match_rom_ptr_get(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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
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 }
5019
5020
5021
5022
5023 uint32_t find_call_near_str(firmware *fw, iter_state_t *is, sig_rule_t *rule)
5024 {
5025 uint32_t str_adr;
5026 if(rule->param & SIG_NEAR_INDIRECT) {
5027 str_adr = find_str_bytes(fw,rule->ref_name);
5028 } else {
5029 str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
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
5037
5038 if(rule->param & SIG_NEAR_INDIRECT) {
5039
5040 search_adr=find_u32_adr_range(fw,str_adr,fw->rom_code_search_min_adr,fw->rom_code_search_max_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
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;
5055 int n=(rule->param&SIG_NEAR_COUNT_MASK)>>SIG_NEAR_COUNT_SHIFT;
5056
5057
5058 disasm_iter_init(fw,is,(ADR_ALIGN4(search_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
5059 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,search_adr+SEARCH_NEAR_REF_RANGE)) {
5060
5061 if(rule->param & SIG_NEAR_REV) {
5062 int i;
5063 int n_calls=0;
5064 for(i=1; i<=max_insns; i++) {
5065 fw_disasm_iter_single(fw,adr_hist_get(&is->ah,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 }
5082
5083
5084 int sig_match_near_str(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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 }
5095
5096
5097
5098
5099
5100
5101 uint32_t find_str_arg_call(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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);
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);
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 }
5134
5135 int sig_match_str_arg_call(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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 }
5143
5144 int sig_match_prop_string(firmware *fw, iter_state_t *is, sig_rule_t *rule)
5145 {
5146 uint32_t call_adr = find_call_near_str(fw, is, rule);
5147
5148 if (call_adr == 0)
5149 return 0;
5150
5151
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
5159 myreg = 0;
5160 }
5161 else {
5162
5163 myreg = 1;
5164 }
5165
5166
5167 const int hl = 8;
5168 disasm_iter_init(fw,is,call_adr - hl*4);
5169
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
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 }
5182
5183
5184
5185 int is_immediate_ret_sub(firmware *fw,iter_state_t *is_init)
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
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 }
5204
5205
5206
5207
5208
5209
5210 #define SIG_NAMED_LAST_MAX_MASK 0x00000FFF
5211 #define SIG_NAMED_LAST_MIN_MASK 0x00FFF000
5212 #define SIG_NAMED_LAST_MIN_SHIFT 12
5213 #define SIG_NAMED_LAST_RANGE(min,max) ((SIG_NAMED_LAST_MIN_MASK&((min)<<SIG_NAMED_LAST_MIN_SHIFT)) \
5214 | (SIG_NAMED_LAST_MAX_MASK&(max)))
5215
5216 int sig_match_named_last(firmware *fw, iter_state_t *is, sig_rule_t *rule)
5217 {
5218 uint32_t ref_adr = get_saved_sig_val(rule->ref_name);
5219 int min = (rule->param&SIG_NAMED_LAST_MIN_MASK)>>SIG_NAMED_LAST_MIN_SHIFT;
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 }
5236
5237
5238 #define SIG_NAMED_ASIS 0x00000000
5239
5240 #define SIG_NAMED_JMP_SUB 0x00000001
5241
5242 #define SIG_NAMED_SUB 0x00000002
5243
5244 #define SIG_NAMED_INSN 0x00000003
5245 #define SIG_NAMED_TYPE_MASK 0x0000000F
5246
5247 #define SIG_NAMED_CLEARTHUMB 0x00000010
5248 #define SIG_NAMED_FLAG_MASK 0x000000F0
5249
5250 #define SIG_NAMED_NTH_MASK 0x00000F00
5251 #define SIG_NAMED_NTH_SHIFT 8
5252
5253
5254
5255 #define SIG_NAMED_NTH_RANGE_MASK 0x0003F000
5256 #define SIG_NAMED_NTH_RANGE_SHIFT 12
5257
5258
5259 #define SIG_NAMED_NTH(n,type) ((SIG_NAMED_NTH_MASK&((n)<<SIG_NAMED_NTH_SHIFT)) | (SIG_NAMED_##type))
5260
5261 #define SIG_NAMED_NTH_RANGE(n) ((SIG_NAMED_NTH_RANGE_MASK&((n)<<SIG_NAMED_NTH_RANGE_SHIFT)))
5262
5263 int sig_match_named_save_sig(firmware *fw,const char *name, uint32_t adr, uint32_t flags)
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 }
5275
5276
5277
5278 int sig_match_named(firmware *fw, iter_state_t *is, sig_rule_t *rule)
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;
5287 uint32_t sig_nth = (rule->param & SIG_NAMED_NTH_MASK)>>SIG_NAMED_NTH_SHIFT;
5288 uint32_t sig_nth_range = (rule->param & SIG_NAMED_NTH_RANGE_MASK)>>SIG_NAMED_NTH_RANGE_SHIFT;
5289 if(!sig_nth) {
5290 sig_nth=1;
5291 }
5292 if(!sig_nth_range) {
5293 sig_nth_range=5;
5294 }
5295
5296
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
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
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
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
5335 if(is->insn->id == ARM_INS_BLX) {
5336
5337 if(!is->thumb) {
5338 adr=ADR_SET_THUMB(adr);
5339 }
5340 } else {
5341
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 }
5353
5354
5355
5356
5357 sig_rule_t sig_rules_initial[]={
5358
5359
5360 {sig_match_str_r0_call, "ExportToEventProcedure_FW","ExportToEventProcedure"},
5361 {sig_match_reg_evp, "RegisterEventProcedure",},
5362 {sig_match_reg_evp_table, "RegisterEventProcTable","DispDev_EnableEventProc"},
5363 {sig_match_reg_evp_alt2, "RegisterEventProcedure_alt2","EngApp.Delete"},
5364 {sig_match_unreg_evp_table,"UnRegisterEventProcTable","MechaUnRegisterEventProcedure"},
5365 {sig_match_evp_table_veneer,"RegisterEventProcTable_alt","RegisterEventProcTable"},
5366 {sig_match_evp_table_veneer,"UnRegisterEventProcTable_alt","UnRegisterEventProcTable"},
5367 {sig_match_str_r0_call,"CreateTaskStrictly", "LowConsole",},
5368 {sig_match_str_r0_call,"CreateTask", "EvShel",},
5369 {sig_match_named, "CreateTask_low", "CreateTask", (SIG_NAMED_NTH(2,SUB)|SIG_NAMED_NTH_RANGE(10)), SIG_DRY_MAX(52)},
5370 {sig_match_named, "CreateTask_low", "CreateTask", (SIG_NAMED_NTH(3,SUB)|SIG_NAMED_NTH_RANGE(10)), SIG_DRY_MIN(54)},
5371 {sig_match_createtaskstrictly_alt,"CreateTaskStrictly_alt","HdmiCecTask",0, SIG_DRY_MIN(58)},
5372 {sig_match_createtask_alt,"CreateTask_alt", "CreateTaskStrictly_alt",0, SIG_DRY_MIN(58)},
5373 {sig_match_near_str, "dry_memcpy", "EP Slot%d", SIG_NEAR_BEFORE(4,1)},
5374 {sig_match_add_ptp_handler,"add_ptp_handler", "PTPtoFAPI_EventProcTask_Try",},
5375 {NULL},
5376 };
5377
5378
5379
5380
5381 sig_rule_t sig_rules_main[]={
5382
5383 {sig_match_named, "SetParameterData", "PTM_BackupUIProperty_FW", 0, SIG_DRY_MIN(58)},
5384 {sig_match_named, "ExitTask", "ExitTask_FW",},
5385 {sig_match_named, "EngDrvRead", "EngDrvRead_FW", SIG_NAMED_JMP_SUB},
5386 {sig_match_named, "CalcLog10", "CalcLog10_FW", SIG_NAMED_JMP_SUB},
5387 {sig_match_named, "CalcSqrt", "CalcSqrt_FW", SIG_NAMED_JMP_SUB},
5388 {sig_match_named, "Close", "Close_FW",},
5389 {sig_match_named, "Close_low", "Close", SIG_NAMED_NTH(3,SUB),SIG_DRY_MIN(58)},
5390 {sig_match_named, "close", "Close", SIG_NAMED_SUB, SIG_DRY_MAX(57)},
5391 {sig_match_named, "close", "Close_low", SIG_NAMED_SUB, SIG_DRY_MIN(58)},
5392 {sig_match_named, "DoAELock", "SS.DoAELock_FW", SIG_NAMED_JMP_SUB},
5393 {sig_match_named, "DoAFLock", "SS.DoAFLock_FW", SIG_NAMED_JMP_SUB},
5394 {sig_match_named, "Fclose_Fut", "Fclose_Fut_FW",},
5395 {sig_match_named, "Fopen_Fut", "Fopen_Fut_FW",},
5396 {sig_match_named, "Fread_Fut", "Fread_Fut_FW",},
5397 {sig_match_named, "Fseek_Fut", "Fseek_Fut_FW",},
5398 {sig_match_named, "Fwrite_Fut", "Fwrite_Fut_FW",},
5399 {sig_match_named, "fopen_low", "Fopen_Fut", SIG_NAMED_NTH(3,SUB)},
5400 {sig_match_named, "fut_prepare", "Fopen_Fut", SIG_NAMED_NTH(1,SUB)},
5401 {sig_match_named, "fut_finish", "Fopen_Fut", SIG_NAMED_NTH(4,SUB)},
5402
5403
5404
5405 {sig_match_named, "fread_low", "Fread_Fut", SIG_NAMED_NTH(2,SUB)},
5406 {sig_match_named, "fseek_low", "Fseek_Fut", SIG_NAMED_NTH(2,SUB)},
5407 {sig_match_named, "fwrite_low", "Fwrite_Fut", SIG_NAMED_NTH(2,SUB)},
5408
5409 {sig_match_named, "GetAdChValue", "GetAdChValue_FW",},
5410 {sig_match_named, "GetCurrentAvValue", "GetCurrentAvValue_FW",},
5411 {sig_match_named, "GetCurrentShutterSpeed", "GetCurrentShutterSpeed_FW",},
5412 {sig_match_named, "GetBatteryTemperature", "GetBatteryTemperature_FW",},
5413 {sig_match_named, "GetCCDTemperature", "GetCCDTemperature_FW",},
5414 {sig_match_named, "GetFocusLensSubjectDistance","GetFocusLensSubjectDistance_FW",SIG_NAMED_JMP_SUB},
5415 {sig_match_named, "GetOpticalTemperature", "GetOpticalTemperature_FW",},
5416 {sig_match_named, "GetPropertyCase", "GetPropertyCase_FW", SIG_NAMED_SUB},
5417 {sig_match_named, "GetSystemTime", "GetSystemTime_FW",},
5418 {sig_match_named, "_GetSystemTime", "GetSystemTime", SIG_NAMED_SUB},
5419
5420 {sig_match_named, "GetSRAndDisableInterrupt", "_GetSystemTime", SIG_NAMED_SUB, SIG_DRY_ANY, SIG_NO_D7},
5421 {sig_match_named, "GetSRAndDisableInterrupt", "_GetSystemTime", SIG_NAMED_NTH(2,SUB),SIG_DRY_ANY, SIG_NO_D6},
5422 {sig_match_named, "SetSR", "_GetSystemTime", SIG_NAMED_NTH(2,SUB),SIG_DRY_ANY, SIG_NO_D7},
5423 {sig_match_named, "SetSR", "_GetSystemTime", SIG_NAMED_NTH(3,SUB),SIG_DRY_ANY, SIG_NO_D6},
5424 {sig_match_named, "GetUsableMaxAv", "GetUsableMaxAv_FW",},
5425 {sig_match_named, "GetUsableMinAv", "GetUsableMinAv_FW",},
5426
5427 {sig_match_named, "GetUsableAvRange", "GetUsableMinAv", SIG_NAMED_SUB},
5428 {sig_match_named, "GetVRAMHPixelsSize", "GetVRAMHPixelsSize_FW",},
5429 {sig_match_named, "GetVRAMVPixelsSize", "GetVRAMVPixelsSize_FW",},
5430 {sig_match_named, "GetZoomLensCurrentPoint", "GetZoomLensCurrentPoint_FW",},
5431 {sig_match_named, "GetZoomLensCurrentPosition","GetZoomLensCurrentPosition_FW",},
5432 {sig_match_named, "GiveSemaphore", "GiveSemaphore_FW",},
5433 {sig_match_named, "IsStrobeChargeCompleted", "EF.IsChargeFull_FW",},
5434 {sig_match_named, "Read", "Read_FW",},
5435 {sig_match_named, "LEDDrive", "LEDDrive_FW",},
5436 {sig_match_named, "LockMainPower", "LockMainPower_FW",},
5437 {sig_match_named, "MoveFocusLensToDistance", "MoveFocusLensToDistance_FW",},
5438 {sig_match_named, "MoveIrisWithAv", "MoveIrisWithAv_FW",},
5439 {sig_match_named, "MoveZoomLensWithPoint", "MoveZoomLensWithPoint_FW",},
5440 {sig_match_named, "Open", "Open_FW",},
5441 {sig_match_named, "Open_low", "Open", SIG_NAMED_NTH(3,SUB),SIG_DRY_MIN(58)},
5442 {sig_match_named, "PostLogicalEventForNotPowerType", "PostLogicalEventForNotPowerType_FW",},
5443 {sig_match_named, "PostLogicalEventToUI", "PostLogicalEventToUI_FW",},
5444 {sig_match_named, "PT_MFOn", "SS.MFOn_FW", SIG_NAMED_JMP_SUB},
5445 {sig_match_named, "PT_MFOff", "SS.MFOff_FW", SIG_NAMED_JMP_SUB},
5446 {sig_match_named, "PT_MoveDigitalZoomToWide", "SS.MoveDigitalZoomToWide_FW", SIG_NAMED_JMP_SUB},
5447 {sig_match_named, "PT_MoveOpticalZoomAt", "SS.MoveOpticalZoomAt_FW",},
5448 {sig_match_named, "PutInNdFilter", "PutInNdFilter_FW",},
5449 {sig_match_named, "PutOutNdFilter", "PutOutNdFilter_FW",},
5450 {sig_match_named, "SetAE_ShutterSpeed", "SetAE_ShutterSpeed_FW",},
5451 {sig_match_named, "SetAutoShutdownTime", "SetAutoShutdownTime_FW",},
5452 {sig_match_named, "SetCurrentCaptureModeType","SetCurrentCaptureModeType_FW",},
5453 {sig_match_named, "SetDate", "SetDate_FW",},
5454 {sig_match_named, "SetLogicalEventActive", "UiEvnt_SetLogicalEventActive_FW",},
5455 {sig_match_named, "SetScriptMode", "SetScriptMode_FW",},
5456 {sig_match_named, "SleepTask", "SleepTask_FW",},
5457 {sig_match_named, "SetPropertyCase", "SetPropertyCase_FW", SIG_NAMED_SUB},
5458 {sig_match_named, "TakeSemaphore", "TakeSemaphore_FW",},
5459 {sig_match_named, "TurnOnDisplay", "DispCon_TurnOnDisplay_FW",SIG_NAMED_SUB},
5460 {sig_match_named, "TurnOffDisplay", "DispCon_TurnOffDisplay_FW",SIG_NAMED_SUB},
5461 {sig_match_named, "TurnOnBackLight", "DispCon_TurnOnBackLight_FW",SIG_NAMED_SUB, SIG_DRY_MAX(57)},
5462 {sig_match_named, "TurnOffBackLight", "DispCon_TurnOffBackLight_FW",SIG_NAMED_SUB,SIG_DRY_MAX(57)},
5463 {sig_match_named, "UIFS_WriteFirmInfoToFile", "UIFS_WriteFirmInfoToFile_FW",},
5464 {sig_match_named, "UnlockAE", "SS.UnlockAE_FW", SIG_NAMED_JMP_SUB},
5465 {sig_match_named, "UnlockAF", "SS.UnlockAF_FW", SIG_NAMED_JMP_SUB},
5466 {sig_match_named, "UnlockMainPower", "UnlockMainPower_FW",},
5467 {sig_match_named, "UnRegisterEventProcedure", "UnRegisterEventProcTable", SIG_NAMED_SUB},
5468
5469 {sig_match_named, "VbattGet", "VbattGet_FW",},
5470 {sig_match_named, "Write", "Write_FW",},
5471 {sig_match_named, "bzero", "exec_FW", SIG_NAMED_SUB},
5472 {sig_match_named, "exmem_free", "ExMem.FreeCacheable_FW",SIG_NAMED_JMP_SUB, SIG_DRY_MAX(58)},
5473 {sig_match_named, "exmem_alloc", "ExMem.AllocCacheable_FW",SIG_NAMED_JMP_SUB,SIG_DRY_MAX(58)},
5474 {sig_match_named, "exmem_ufree", "ExMem.FreeUncacheable_FW",SIG_NAMED_JMP_SUB, SIG_DRY_MAX(58)},
5475 {sig_match_named, "exmem_ualloc", "ExMem.AllocUncacheable_FW",SIG_NAMED_JMP_SUB,SIG_DRY_MAX(58)},
5476 {sig_match_named, "free", "FreeMemory_FW", SIG_NAMED_JMP_SUB},
5477 {sig_match_named, "heap_free", "free", SIG_NAMED_NTH(2,SUB)},
5478 {sig_match_named, "lseek", "Lseek_FW",},
5479 {sig_match_named, "_log10", "CalcLog10", SIG_NAMED_NTH(2,SUB)},
5480 {sig_match_named, "malloc", "AllocateMemory_FW", SIG_NAMED_JMP_SUB},
5481 {sig_match_named, "heap_alloc", "malloc", SIG_NAMED_NTH(2,SUB)},
5482 {sig_match_named, "memcmp", "memcmp_FW",},
5483 {sig_match_named, "memcpy", "memcpy_FW",},
5484 {sig_match_named, "memset", "memset_FW",},
5485 {sig_match_named, "strcmp", "strcmp_FW",},
5486 {sig_match_named, "strcpy", "strcpy_FW",},
5487 {sig_match_named, "strlen", "strlen_FW",},
5488 {sig_match_named, "task_CaptSeq", "task_CaptSeqTask",},
5489 {sig_match_named, "task_ExpDrv", "task_ExpDrvTask",},
5490 {sig_match_named, "task_FileWrite", "task_FileWriteTask",},
5491
5492
5493 {sig_match_named, "vsprintf", "sprintf_FW", SIG_NAMED_SUB},
5494 {sig_match_named, "PTM_GetCurrentItem", "PTM_GetCurrentItem_FW",},
5495 {sig_match_named, "DisableISDriveError", "DisableISDriveError_FW",},
5496 {sig_match_named, "hook_CreateTask", "CreateTask", SIG_NAMED_CLEARTHUMB},
5497
5498 {sig_match_named, "hook_CreateTask_low", "CreateTask_low", SIG_NAMED_CLEARTHUMB},
5499 {sig_match_named, "malloc_strictly", "task_EvShel", SIG_NAMED_NTH(2,SUB)},
5500 {sig_match_named, "DebugAssert2", "malloc_strictly", SIG_NAMED_NTH(3,SUB)},
5501
5502
5503 {sig_match_named, "AcquireRecursiveLockStrictly","PTM_AllReset_FW", SIG_NAMED_SUB},
5504 {sig_match_named, "CheckAllEventFlag", "ChargeStrobeForFA_FW", SIG_NAMED_SUB},
5505 {sig_match_named, "ClearEventFlag", "GetAEIntegralValueWithFix_FW",SIG_NAMED_SUB},
5506 {sig_match_named, "CheckAnyEventFlag", "task_SynchTask", SIG_NAMED_NTH(2,SUB)},
5507 {sig_match_named, "taskcreate_LowConsole", "task_EvShel", SIG_NAMED_SUB},
5508 {sig_match_named, "CreateMessageQueueStrictly","taskcreate_LowConsole",SIG_NAMED_SUB},
5509 {sig_match_named, "CreateBinarySemaphoreStrictly","taskcreate_LowConsole",SIG_NAMED_NTH(2,SUB)},
5510 {sig_match_named, "PostMessageQueue", "GetCh_FW", SIG_NAMED_NTH(2,SUB)},
5511 {sig_match_named, "CreateEventFlagStrictly", "InitializeDigicon_FW", SIG_NAMED_SUB},
5512 {sig_match_named, "WaitForAnyEventFlag", "task_DPOFTask", SIG_NAMED_SUB},
5513 {sig_match_named, "GetEventFlagValue", "task_DPOFTask", SIG_NAMED_NTH(2,SUB)},
5514 {sig_match_named, "CreateBinarySemaphore", "task_UartLog", SIG_NAMED_SUB},
5515 {sig_match_named, "PostMessageQueueStrictly", "EF.IsChargeFull_FW", SIG_NAMED_SUB},
5516 {sig_match_named, "SetEventFlag", "StopStrobeChargeForFA_FW",SIG_NAMED_SUB},
5517 {sig_match_named, "TryReceiveMessageQueue", "task_DvlpSeqTask", SIG_NAMED_NTH(3,SUB)},
5518
5519 {sig_match_named, "TakeSemaphore", "task_Bye", SIG_NAMED_SUB},
5520 {sig_match_named_last,"GiveSemaphore", "TurnOnVideoOutMode_FW",SIG_NAMED_LAST_RANGE(10,24)},
5521
5522 {sig_match_named, "givesemaphore_low", "GiveSemaphore", SIG_NAMED_SUB, SIG_DRY_MAX(52)},
5523 {sig_match_named, "givesemaphore_low", "GiveSemaphore", SIG_NAMED_NTH(2,SUB),SIG_DRY_MIN(53)},
5524
5525
5526 {sig_match_named, "ReleaseRecursiveLock", "StartWDT_FW", SIG_NAMED_NTH(2,SUB)},
5527 {sig_match_named, "MoveOpticalZoomAt", "SS.MoveOpticalZoomAt_FW",SIG_NAMED_SUB},
5528 {sig_match_named, "SetVideoOutType", "SetVideoOutType_FW", SIG_NAMED_SUB},
5529 {sig_match_named, "GetVideoOutType", "GetVideoOutType_FW"},
5530 {sig_match_named, "is_movie_recording", "UIFS_StopMovieRecord_FW",SIG_NAMED_SUB},
5531 {sig_match_named, "dry_con_printf", "ShowCameraLogInfo_FW", SIG_NAMED_SUB},
5532 {sig_match_named, "ui_malloc", "CreateController_FW", SIG_NAMED_SUB},
5533 {sig_match_ui_mem_func_ptr,"ui_malloc_ptr", "ui_malloc", },
5534 {sig_match_func_ptr_val, "ui_malloc_default", "ui_malloc_ptr", },
5535 {sig_match_named, "pvm_malloc", "ui_malloc_default", SIG_NAMED_NTH(2,SUB)},
5536 {sig_match_named, "pvm_get_largest_free_block_size_ptr","ui_malloc_default",SIG_NAMED_NTH(3,SUB)},
5537 {sig_match_named, "pvm_get_largest_free_block_size","pvm_get_largest_free_block_size_ptr",SIG_NAMED_SUB},
5538 {sig_match_named, "ui_free", "CreateController_FW", SIG_NAMED_NTH(3,SUB)},
5539 {sig_match_ui_mem_func_ptr,"ui_free_ptr", "ui_free",},
5540 {sig_match_func_ptr_val, "ui_free_default", "ui_free_ptr", },
5541 {sig_match_named_last,"pvm_free", "ui_free_default", SIG_NAMED_LAST_RANGE(11,16)},
5542 {sig_match_near_str,"pvm_init_pool", "\n%ld-byte from heap\n",SIG_NEAR_BEFORE(14,3)},
5543
5544 {sig_match_near_str,"cameracon_set_state", "AC:ChkCom2PB", SIG_NEAR_BEFORE(4,1),},
5545 {sig_match_near_str,"cameracon_get_state", "DlvrUSBCnct", SIG_NEAR_AFTER(5,2)},
5546 {sig_match_near_str,"IsWirelessConnect", "WiFiDisconnect", SIG_NEAR_BEFORE(6,1),SIG_DRY_MAX(52)},
5547 {sig_match_near_str,"IsWirelessConnect", "USBDisconnect", SIG_NEAR_BEFORE(6,1),SIG_DRY_MIN(54)},
5548 {sig_match_var_struct_get,"cameracon_state", "cameracon_get_state",},
5549 {sig_match_str_arg_call,"strstr", "AUTPLAY", SIG_STRCALL_ARG(1)},
5550 {sig_match_named_last,"strchr", "strstr", SIG_NAMED_LAST_RANGE(14,22)},
5551 {sig_match_near_str,"init_task_error", "USER_MEM size checking",SIG_NEAR_AFTER(3,1)},
5552 {sig_match_named_last,"dry_panic", "init_task_error", SIG_NAMED_LAST_RANGE(4,12)},
5553 {sig_match_named, "dry_panic_low", "dry_panic", SIG_NAMED_NTH(3,SUB),SIG_DRY_ANY, SIG_NO_D6},
5554
5555 {sig_match_near_str,"data_synchronization_barrier","ER DlphCntInv", SIG_NEAR_AFTER(3,2),SIG_DRY_MAXP(58,8), SIG_NO_D7},
5556
5557 {sig_match_near_str,"bzero", "Canon Degital Camera",SIG_NEAR_AFTER(8,2)|SIG_NEAR_INDIRECT},
5558
5559
5560 {sig_match_named, "GetCurrentDriveBaseSvValue","GetCurrentDriveBaseSvValue_FW",SIG_NAMED_NTH(1,SUB)},
5561 {sig_match_near_str,"GetCurrentDriveBaseSvValue","IsExecutePreConti", SIG_NEAR_AFTER(7,2)},
5562 {sig_match_named, "memset32", "bzero", SIG_NAMED_NTH(1,INSN)},
5563 {sig_match_dry_memset,"dry_memset", "ClearDefectTurnTable_FW",0, SIG_DRY_MIN(53)},
5564 {sig_match_near_str,"dry_memset", "[xWiSE] generateRandom Err.\n",SIG_NEAR_BEFORE(8,2),SIG_DRY_MAX(52)},
5565 {sig_match_dry_memzero,"dry_memzero", "SetDefaultRecParameter_FW"},
5566 {sig_match_dry_memcpy_bytes,"dry_memcpy_bytes", "SaveDefectAdjTable_FW",},
5567 {sig_match_near_str,"dry_memmove_bytes", "NoOperation BulkOut!Remain.Length = %lu",SIG_NEAR_AFTER(18,3)},
5568 {sig_match_misc_flag_named,"CAM_IS_ILC", "task_EFLensComTask",},
5569 {sig_match_misc_flag_named,"CAM_HAS_ND_FILTER", "task_Nd",},
5570 {sig_match_misc_flag_named,"CAM_HAS_WIFI", "task_ComWireless",},
5571 {sig_match_cam_has_iris_diaphragm,"CAM_HAS_IRIS_DIAPHRAGM","task_IrisEvent",},
5572 {sig_match_near_str,"ImagerActivate", "Fail ImagerActivate(ErrorCode:%x)\r",SIG_NEAR_BEFORE(6,1)},
5573 {sig_match_screenlock_helper,"screenlock_helper","UIFS_DisplayFirmUpdateView_FW"},
5574 {sig_match_named, "ScreenLock", "screenlock_helper",SIG_NAMED_SUB},
5575 {sig_match_fclose_low,"fclose_low", "Fclose_Fut"},
5576 {sig_match_named, "fut_flush", "fclose_low", SIG_NAMED_NTH(1,SUB)},
5577
5578 {sig_match_screenunlock,"ScreenUnlock", "screenlock_helper", 0,SIG_DRY_MAX(55)},
5579 {sig_match_near_str,"ScreenUnlock", "PB._ErrorRef", SIG_NEAR_AFTER(8,2)|SIG_NEAR_JMP_SUB,SIG_DRY_RANGE(57,58)},
5580 {sig_match_near_str,"ScreenUnlock", "PB._ErrorRef:SI", SIG_NEAR_AFTER(8,2)|SIG_NEAR_JMP_SUB,SIG_DRY_MIN(59)},
5581 {sig_match_log_camera_event,"LogCameraEvent", "task_StartupImage",},
5582 {sig_match_physw_misc, "physw_misc", "task_PhySw"},
5583 {sig_match_kbd_read_keys, "kbd_read_keys", "kbd_p1_f"},
5584 {sig_match_get_kbd_state, "GetKbdState", "kbd_read_keys"},
5585 {sig_match_create_jumptable, "CreateJumptable", "InitializeAdjustmentSystem_FW"},
5586
5587 {sig_match_take_semaphore_strict, "TakeSemaphoreStrictly","Fopen_Fut"},
5588 {sig_match_near_str,"dry_error_printf", "\nSystem Panic: Module = %d, Panic = %d\n",SIG_NEAR_AFTER(2,1)},
5589
5590 {sig_match_get_semaphore_value,"GetSemaphoreValue","\tRaw[%i]", 0, SIG_DRY_MAXP(58,8)},
5591 {sig_match_get_semaphore_value,"GetSemaphoreValue","BlankRaw(%d)", 0, SIG_DRY_MINP(58,9)},
5592 {sig_match_stat, "stat", "A/uartr.req"},
5593 {sig_match_open, "open", "Open_FW", 0, SIG_DRY_MAX(57)},
5594 {sig_match_open, "open", "Open_low", 0, SIG_DRY_MIN(58)},
5595 {sig_match_named, "get_self_task_errno_pointer","open", SIG_NAMED_NTH(2,SUB)},
5596 {sig_match_named, "get_self_task_id", "get_self_task_errno_pointer",SIG_NAMED_SUB},
5597 {sig_match_umalloc, "AllocateUncacheableMemory","Fopen_Fut_FW"},
5598 {sig_match_named, "dcache_flush_range", "AllocateUncacheableMemory",SIG_NAMED_NTH(2,SUB)},
5599 {sig_match_ufree, "FreeUncacheableMemory", "Fclose_Fut_FW"},
5600 {sig_match_cam_uncached_bit,"CAM_UNCACHED_BIT", "FreeUncacheableMemory"},
5601 {sig_match_umalloc_strictly,"umalloc_strictly", "DPOFTask"},
5602 {sig_match_dcache_clean_flush_and_disable,"dcache_clean_flush_and_disable", "MemoryChecker_FW"},
5603 {sig_match_get_rom_id,"GetRomID", "GetRomID_FW",},
5604 {sig_match_dcache_flush_and_enable,"dcache_flush_and_enable", "GetRomID",0, SIG_DRY_ANY, SIG_NO_D7},
5605 {sig_match_deletefile_fut,"DeleteFile_Fut", "Get Err TempPath"},
5606 {sig_match_near_str,"createsemaphore_low", "termLock", SIG_NEAR_AFTER(3,1)},
5607
5608
5609 {sig_match_named,"takesemaphore_low", "malloc", SIG_NAMED_SUB},
5610
5611 {sig_match_near_str,"AcquireRecursiveLock", "not executed\n",SIG_NEAR_BEFORE(20,3),SIG_DRY_ANY, SIG_NO_D7},
5612 {sig_match_near_str,"AcquireRecursiveLock", "COCOA: ERR: QIF AcquireRecursiveLock QifPushmqif failure!!",SIG_NEAR_BEFORE(10,1),SIG_DRY_ANY, SIG_NO_D6},
5613 {sig_match_near_str,"CreateCountingSemaphoreStrictly","DvlpSeqTask", SIG_NEAR_BEFORE(18,3)},
5614 {sig_match_near_str,"CreateMessageQueue", "CreateMessageQueue:%ld",SIG_NEAR_BEFORE(7,1)},
5615 {sig_match_near_str,"CreateEventFlag", "CreateEventFlag:%ld", SIG_NEAR_BEFORE(7,1),SIG_DRY_MAX(57)},
5616 {sig_match_near_str,"CreateEventFlag", "CreateEventFlag:%ld", SIG_NEAR_BEFORE(9,1),SIG_DRY_MIN(58)},
5617 {sig_match_near_str,"CreateRecursiveLock", "WdtInt", SIG_NEAR_BEFORE(9,1)},
5618 {sig_match_near_str,"CreateRecursiveLockStrictly","LoadedScript", SIG_NEAR_AFTER(6,2)},
5619 {sig_match_near_str,"DeleteMessageQueue", "DeleteMessageQueue(%d) is FAILURE",SIG_NEAR_BEFORE(10,1)},
5620 {sig_match_near_str,"DeleteEventFlag", "DeleteEventFlag(%d) is FAILURE",SIG_NEAR_BEFORE(10,1)},
5621 {sig_match_near_str,"ReceiveMessageQueue", "ReceiveMessageQue:%d", SIG_NEAR_BEFORE(9,1)},
5622 {sig_match_near_str,"RegisterInterruptHandler", "WdtInt", SIG_NEAR_AFTER(3,1)},
5623 {sig_match_near_str,"TryPostMessageQueue", "TryPostMessageQueue(%d)\n",SIG_NEAR_BEFORE(9,1),SIG_DRY_MAX(52)},
5624
5625 {sig_match_near_str,"TryPostMessageQueue", "[CWS]TryPostMessageQueue(%d) Failed\n",SIG_NEAR_BEFORE(9,1)},
5626 {sig_match_near_str,"TryTakeSemaphore", "FileScheduleTask", SIG_NEAR_AFTER(10,2),SIG_DRY_MAX(57)},
5627 {sig_match_try_take_sem_dry_gt_57,"TryTakeSemaphore","task_ImageStoreTask",0,SIG_DRY_MIN(58)},
5628
5629 {sig_match_named, "takesemaphore_low", "TryTakeSemaphore", SIG_NAMED_SUB},
5630 {sig_match_near_str,"WaitForAllEventFlag", "Error WaitEvent PREPARE_TESTREC_EXECUTED.", SIG_NEAR_BEFORE(5,1)},
5631 {sig_match_near_str,"WaitForAnyEventFlagStrictly","_imageSensorTask", SIG_NEAR_AFTER(10,2)},
5632 {sig_match_wait_all_eventflag_strict,"WaitForAllEventFlagStrictly","EF.StartInternalMainFlash_FW"},
5633 {sig_match_near_str,"DeleteSemaphore", "DeleteSemaphore passed",SIG_NEAR_BEFORE(3,1)},
5634 {sig_match_get_num_posted_messages,"GetNumberOfPostedMessages","task_CtgTotalTask"},
5635 {sig_match_near_str,"LocalTime", "%Y-%m-%dT%H:%M:%S", SIG_NEAR_BEFORE(5,1),SIG_DRY_MAX(58)},
5636 {sig_match_near_str,"LocalTime", "%Y.%m.%d %H:%M:%S", SIG_NEAR_BEFORE(5,1)},
5637 {sig_match_near_str,"strftime", "%Y/%m/%d %H:%M:%S", SIG_NEAR_AFTER(3,1)},
5638 {sig_match_near_str,"OpenFastDir", "OpenFastDir_ERROR\n", SIG_NEAR_BEFORE(5,1)},
5639 {sig_match_readfastdir,"ReadFastDir", "ReadFast_ERROR\n", SIG_NEAR_BEFORE(24,1)},
5640 {sig_match_near_str,"PT_PlaySound", "BufAccBeep", SIG_NEAR_AFTER(7,2)|SIG_NEAR_JMP_SUB,SIG_DRY_MAX(58)},
5641
5642 {sig_match_near_str,"PT_PlaySound", "PB._PMenuCBR", SIG_NEAR_BEFORE(7,3),SIG_DRY_MIN(59)},
5643 {sig_match_closedir,"closedir", "ReadFast_ERROR\n", SIG_NEAR_AFTER(1,1)},
5644 {sig_match_strrchr,"strrchr", "ReadFast_ERROR\n", SIG_NEAR_AFTER(9,2)},
5645 {sig_match_strrchr,"strrchr", "ReadFast_ERROR\n", SIG_NEAR_BEFORE(18,4)},
5646 {sig_match_time, "time", "<UseAreaSize> DataWidth : %d , DataHeight : %d\r\n",},
5647 {sig_match_near_str,"strcat", "String can't be displayed; no more space in buffer",SIG_NEAR_AFTER(5,2),SIG_DRY_MAX(52)},
5648 {sig_match_near_str,"strcat", "/api/getimagelist", SIG_NEAR_AFTER(4,1),SIG_DRY_MIN(53)},
5649
5650 {sig_match_strncpy, "strncpy", "UnRegisterEventProcedure",},
5651 {sig_match_strncmp, "strncmp", "EXFAT ",},
5652 {sig_match_strtolx, "strtolx", "CheckSumAll_FW",},
5653 {sig_match_near_str,"strtol", "prio <task ID> <priority>\n",SIG_NEAR_AFTER(7,1)},
5654 {sig_match_exec_evp,"ExecuteEventProcedure", "Can not Execute "},
5655 {sig_match_fgets_fut,"Fgets_Fut", "CheckSumAll_FW",},
5656 {sig_match_named, "fgets_low", "Fgets_Fut", SIG_NAMED_NTH(2,SUB)},
5657 {sig_match_log, "_log", "_log10",},
5658 {sig_match_pow_dry_52,"_pow", "GetDefectTvAdj_FW", 0, SIG_DRY_MAX(52)},
5659 {sig_match_pow_dry_gt_52,"_pow", "GetDefectTvAdj_FW", 0, SIG_DRY_RANGEP(53,0,59,3)},
5660 {sig_match_sqrt, "_sqrt", "CalcSqrt",},
5661 {sig_match_named, "get_fstype", "OpenFastDir", SIG_NAMED_NTH(2,SUB)},
5662 {sig_match_near_str,"GetMemInfo", " -- refusing to print malloc information.\n",SIG_NEAR_AFTER(7,2)},
5663 {sig_match_get_drive_cluster_size,"GetDrive_ClusterSize","OpLog.WriteToSD_FW",},
5664 {sig_match_mktime_ext,"mktime_ext", "%04d%02d%02dT%02d%02d%02d.%01d",},
5665 {sig_match_near_str,"PB2Rec", "AC:ActionP2R Fail", SIG_NEAR_BEFORE(6,1)},
5666 {sig_match_rec2pb, "Rec2PB", "_EnrySRec",},
5667
5668 {sig_match_get_parameter_data,"GetParameterData","PTM_RestoreUIProperty_FW",},
5669 {sig_match_prepdir_1,"PrepareDirectory_1", "<OpenFileWithDir> PrepareDirectory NG\r\n",SIG_NEAR_BEFORE(7,1)},
5670 {sig_match_prepdir_x,"PrepareDirectory_x", "PrepareDirectory_1",},
5671 {sig_match_prepdir_0,"PrepareDirectory_0", "PrepareDirectory_1",},
5672 {sig_match_mkdir, "MakeDirectory_Fut", "PrepareDirectory_x",},
5673
5674
5675 {sig_match_qsort, "qsort", "task_MetaCtg",},
5676 {sig_match_deletedirectory_fut,"DeleteDirectory_Fut","RedEyeController.c",},
5677 {sig_match_set_control_event,"set_control_event","LogicalEvent:0x%04x:adr:%p,Para:%ld",},
5678
5679 {sig_match_set_control_event,"set_control_event","LogicalEvent:0x%08x:adr:%p,Para:%ld",},
5680 {sig_match_displaybusyonscreen_52,"displaybusyonscreen","_PBBusyScrn", 0, SIG_DRY_MAX(52)},
5681 {sig_match_undisplaybusyonscreen_52,"undisplaybusyonscreen","_PBBusyScrn",0, SIG_DRY_MAX(52)},
5682 {sig_match_near_str,"srand", "Canon Degital Camera",SIG_NEAR_AFTER(14,4)|SIG_NEAR_INDIRECT},
5683 {sig_match_near_str,"rand", "Canon Degital Camera",SIG_NEAR_AFTER(15,5)|SIG_NEAR_INDIRECT},
5684 {sig_match_set_hp_timer_after_now,"SetHPTimerAfterNow","MechaNC.c",},
5685 {sig_match_levent_table,"levent_table", "ShowLogicalEventName_FW",},
5686 {sig_match_flash_param_table,"FlashParamsTable","GetParameterData",},
5687 {sig_match_named, "get_playrec_mode", "task_SsStartupTask", SIG_NAMED_SUB},
5688 {sig_match_var_struct_get,"playrec_mode", "get_playrec_mode",},
5689 {sig_match_jpeg_count_str,"jpeg_count_str", "9999",},
5690 {sig_match_physw_event_table,"physw_event_table","kbd_read_keys_r2",},
5691 {sig_match_uiprop_count,"uiprop_count", "PTM_SetCurrentItem_FW",},
5692 {sig_match_get_canon_mode_list,"get_canon_mode_list","AC:PTM_Init",},
5693 {sig_match_rom_ptr_get,"canon_mode_list", "get_canon_mode_list",},
5694 {sig_match_zoom_busy,"zoom_busy", "ResetZoomLens_FW",},
5695 {sig_match_focus_busy,"focus_busy", "MoveFocusLensToTerminate_FW",},
5696 {sig_match_aram_size,"ARAM_HEAP_SIZE", "AdditionAgentRAM_FW", 0, SIG_DRY_MAX(58)},
5697 {sig_match_aram_size_gt58,"ARAM_HEAP_SIZE", "AdditionAgentRAM_FW", 0, SIG_DRY_MIN(59)},
5698 {sig_match_aram_start,"ARAM_HEAP_START", "AdditionAgentRAM_FW",},
5699 {sig_match_aram_start2,"ARAM_HEAP_START", "AdditionAgentRAM_FW",},
5700 {sig_match_icache_flush_range,"icache_flush_range","AdditionAgentRAM_FW",},
5701 {sig_match__nrflag,"_nrflag", "NRTBL.SetDarkSubType_FW",},
5702 {sig_match_near_str,"transfer_src_overlay_helper","Window_EmergencyRefreshPhysicalScreen",SIG_NEAR_BEFORE(6,1)},
5703 {sig_match_transfer_src_overlay,"transfer_src_overlay","transfer_src_overlay_helper",},
5704 {sig_match_named,"GraphicSystemCoreFinish_helper","transfer_src_overlay",SIG_NAMED_NTH(3,SUB),SIG_DRY_MAX(52)},
5705 {sig_match_named,"GraphicSystemCoreFinish_helper","transfer_src_overlay",SIG_NAMED_NTH(4,SUB),SIG_DRY_RANGE(53,57)},
5706 {sig_match_named,"GraphicSystemCoreFinish_helper","transfer_src_overlay",SIG_NAMED_NTH(5,SUB),SIG_DRY_MIN(58)},
5707
5708
5709 {sig_match_named_last,"fw_yuv_layer_buf_helper","transfer_src_overlay",SIG_NAMED_LAST_RANGE(60,85)},
5710 {sig_match_named,"GraphicSystemCoreFinish","GraphicSystemCoreFinish_helper",SIG_NAMED_SUB},
5711 {sig_match_named,"mzrm_createmsg","GraphicSystemCoreFinish",SIG_NAMED_SUB},
5712 {sig_match_named_last,"mzrm_sendmsg","GraphicSystemCoreFinish",SIG_NAMED_LAST_RANGE(10,16)},
5713 {sig_match_zicokick_52,"zicokick_start", "ZicoKick Start\n",0,SIG_DRY_MAX(52)},
5714 {sig_match_zicokick_gt52,"zicokick_start", "ZicoKick Start\n",0,SIG_DRY_MIN(53)},
5715 {sig_match_zicokick_copy,"zicokick_copy", "zicokick_start"},
5716 {sig_match_zicokick_values,"zicokick_values", "zicokick_start"},
5717 {sig_match_named_last,"dcache_clean_range", "zicokick_start", SIG_NAMED_LAST_RANGE(40,58)},
5718 {sig_match_init_ex_drivers,"init_ex_drivers", "task_Startup"},
5719 {sig_match_omar_init,"omar_init", "init_ex_drivers", 0, SIG_DRY_ANY, SIG_NO_D7},
5720 {sig_match_init_error_handlers,"init_error_handlers","task_Startup"},
5721 {sig_match_named, "set_assert_handler", "init_error_handlers", SIG_NAMED_NTH(2,SUB)},
5722 {sig_match_named, "set_exception_handler", "init_error_handlers", SIG_NAMED_NTH(3,SUB)},
5723 {sig_match_named, "set_panic_handler", "init_error_handlers", SIG_NAMED_NTH(4,JMP_SUB)},
5724 {sig_match_default_assert_handler,"default_assert_handler","init_error_handlers"},
5725 {sig_match_default_exception_handler,"default_exception_handler","init_error_handlers"},
5726 {sig_match_default_panic_handler,"default_panic_handler","init_error_handlers"},
5727 {sig_match_get_task_properties,"get_task_properties","default_assert_handler"},
5728 {sig_match_enable_hdmi_power,"EnableHDMIPower", "HecHdmiCecPhysicalCheckForScript_FW"},
5729 {sig_match_disable_hdmi_power,"DisableHDMIPower","HecHdmiCecPhysicalCheckForScript_FW"},
5730 {sig_match_get_nd_value,"get_nd_value", "PutInNdFilter",},
5731 {sig_match_get_current_exp,"get_current_exp","ShowCurrentExp_FW",},
5732 {sig_match_get_current_nd_value,"get_current_nd_value","get_current_exp",},
5733 {sig_match_get_current_deltasv,"get_current_deltasv","get_current_exp",},
5734 {sig_match_imager_active_callback,"imager_active_callback","ImagerActivate",},
5735 {sig_match_imager_active,"imager_active","imager_active_callback",},
5736 {sig_match_get_dial_hw_position,"get_dial_hw_position","kbd_p1_f",},
5737 {sig_match_near_str,"get_displaytype","DisplayType : %d\r\n",SIG_NEAR_BEFORE(5,1)},
5738 {sig_match_prop_string,"PROPCASE_AFSTEP", "\n\rError : GetAFStepResult",SIG_NEAR_BEFORE(7,1)},
5739 {sig_match_prop_string,"PROPCASE_FOCUS_STATE", "\n\rError : GetAFResult",SIG_NEAR_BEFORE(7,1)},
5740 {sig_match_prop_string,"PROPCASE_AV", "\n\rError : GetAvResult",SIG_NEAR_BEFORE(7,1)},
5741 {sig_match_prop_string,"PROPCASE_BV", "\n\rError : GetBvResult",SIG_NEAR_BEFORE(7,1)},
5742 {sig_match_prop_string,"PROPCASE_DELTA_DIGITALGAIN", "\n\rError : GetDeltaDigitalResult",SIG_NEAR_BEFORE(7,1)},
5743 {sig_match_prop_string,"PROPCASE_DELTA_SV", "\n\rError : GetDeltaGainResult",SIG_NEAR_BEFORE(7,1)},
5744 {sig_match_prop_string,"PROPCASE_DELTA_ND", "\n\rError : GetDeltaNdResult",SIG_NEAR_BEFORE(7,1)},
5745 {sig_match_prop_string,"PROPCASE_EV_CORRECTION_2", "\n\rError : GetRealExposureCompensationResult",SIG_NEAR_BEFORE(7,1)},
5746 {sig_match_prop_string,"PROPCASE_ORIENTATION_SENSOR", "\n\rError : GetRotationAngleResult",SIG_NEAR_BEFORE(7,1)},
5747 {sig_match_prop_string,"PROPCASE_SV_MARKET", "\n\rError : GetSvResult",SIG_NEAR_BEFORE(7,1)},
5748 {sig_match_prop_string,"PROPCASE_SVFIX", "\n\rError : GetSvFixResult",SIG_NEAR_BEFORE(7,1)},
5749 {sig_match_prop_string,"PROPCASE_TV", "\n\rError : GetTvResult",SIG_NEAR_BEFORE(7,1)},
5750 {sig_match_prop_string,"PROPCASE_HSCAPTURE", "GetPropertyFromCase Error [HSCapture]",SIG_NEAR_BEFORE(7,1)},
5751 {sig_match_prop_string,"PROPCASE_FLASH_FIRE", "FlashDecision",SIG_NEAR_BEFORE(7,1)},
5752 {sig_match_prop_string,"PROPCASE_FELOCK", "GetPropertyFromCurrentCase Error [FELock]",SIG_NEAR_BEFORE(7,1)},
5753 {sig_match_prop_string,"PROPCASE_FLASH_ADJUST_MODE", "GetPropertyFromCurrentCase Error [FlashAdjust]",SIG_NEAR_BEFORE(7,1)},
5754 {sig_match_exmem_vars,"exmem_types_table", "ExMem.View_FW"},
5755 {sig_match_av_over_sem,"av_override_semaphore", "MoveIrisWithAv_FW"},
5756 {sig_match_canon_menu_active,"canon_menu_active", "StartRecModeMenu_FW"},
5757 {sig_match_file_counter_init,"file_counter_var_init","task_InitFileModules",},
5758 {sig_match_file_counter_var,"file_counter_var","file_counter_var_init",},
5759 {sig_match_var_struct_get,"displaytype", "get_displaytype",},
5760 {sig_match_palette_vars,"palette_control", "transfer_src_overlay_helper",0, SIG_DRY_MAX(58)},
5761 {sig_match_live_free_cluster_count,"live_free_cluster_count","Close",0, SIG_DRY_MAX(57)},
5762 {sig_match_live_free_cluster_count,"live_free_cluster_count","Close_low",0, SIG_DRY_MIN(58)},
5763 {sig_match_debug_logging_ptr,"debug_logging_ptr","[GRYP]T: Terminate(Pri): Completed.\n",SIG_STRCALL_ARG(0)|SIG_STRCALL_JMP_REG},
5764 {sig_match_debug_logging_flag,"debug_logging_flag","[GRYP]E: Terminate(Pri): Event flag delete error.[0x%08x]\n",SIG_STRCALL_ARG(0)|SIG_STRCALL_CALL_REG},
5765 {sig_match_mzrm_sendmsg_ret_adr,"mzrm_sendmsg_ret_adr","SendMsg : %d\n", SIG_STRCALL_ARG(0)|SIG_STRCALL_CALL_REG},
5766 {sig_match_fw_yuv_layer_buf_52,"fw_yuv_layer_buf","fw_yuv_layer_buf_helper",0,SIG_DRY_MAX(52)},
5767 {sig_match_fw_yuv_layer_buf_gt52,"fw_yuv_layer_buf","fw_yuv_layer_buf_helper",0,SIG_DRY_MIN(54)},
5768 {NULL},
5769 };
5770
5771 int sig_rule_applies(firmware *fw, sig_rule_t *rule)
5772 {
5773
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
5778 if(!rule->flags) {
5779 return 1;
5780 }
5781
5782 if((rule->flags & SIG_NO_D7) && (fw->arch_flags & FW_ARCH_FL_VMSA)) {
5783 return 0;
5784 }
5785
5786 if((rule->flags & SIG_NO_D6) && !(fw->arch_flags & FW_ARCH_FL_VMSA)) {
5787 return 0;
5788 }
5789 return 1;
5790 }
5791
5792 void run_sig_rules(firmware *fw, sig_rule_t *sig_rules)
5793 {
5794 sig_rule_t *rule=sig_rules;
5795
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
5803
5804 rule->match_fn(fw,is,rule);
5805
5806 rule++;
5807 }
5808 disasm_iter_free(is);
5809 }
5810
5811 void add_event_proc(firmware *fw, char *name, uint32_t adr)
5812 {
5813
5814 if(!ADR_IS_THUMB(adr)) {
5815 printf("add_event_proc: %s is ARM 0x%08x\n",name,adr);
5816 }
5817
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
5823
5824
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);
5830
5831 adr=b_adr;
5832 }
5833 add_func_name(fw,name,adr,"_FW");
5834 }
5835
5836
5837 int process_reg_eventproc_call(firmware *fw, iter_state_t *is, __attribute__ ((unused))uint32_t unused) {
5838 uint32_t regs[4];
5839
5840 if((get_call_const_args(fw,is,4,regs)&3)==3) {
5841
5842 if(isASCIIstring(fw,regs[0])) {
5843 char *nm=(char *)adr2ptr(fw,regs[0]);
5844 add_event_proc(fw,nm,regs[1]);
5845
5846
5847 } else {
5848 printf("eventproc name not string at 0x%"PRIx64"\n",is->insn->address);
5849 }
5850 } else {
5851
5852
5853
5854
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
5861 disasm_iter_init(fw,is,adr_hist_get(&is->ah,10));
5862
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
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
5882 break;
5883 }
5884 }
5885 if (found) {
5886
5887 uint32_t *p=(uint32_t*)adr2ptr_with_data(fw,tbla);
5888 if(p) {
5889 while(*p) {
5890 uint32_t nm_adr=*p;
5891
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
5911 disasm_iter_init(fw,is,adr | adr_thumb);
5912 disasm_iter(fw,is);
5913 }
5914 return 0;
5915 }
5916
5917
5918 int process_eventproc_table_call(firmware *fw, iter_state_t *is, __attribute__ ((unused))uint32_t unused) {
5919 uint32_t regs[4];
5920 int foundr0 = 0;
5921
5922 foundr0 = get_call_const_args(fw,is,4,regs) & 1;
5923 if (!foundr0) {
5924
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
5942 }
5943 }
5944
5945 disasm_iter_init(fw,is,ca);
5946 disasm_iter(fw,is);
5947 }
5948 if(foundr0) {
5949
5950 uint32_t *p=(uint32_t*)adr2ptr_with_data(fw,regs[0]);
5951
5952
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
5965 add_event_proc(fw,nm,fn);
5966
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 }
5976
5977 int process_createtask_call(firmware *fw, iter_state_t *is, __attribute__ ((unused))uint32_t unused) {
5978
5979 uint32_t regs[4];
5980
5981 if((get_call_const_args(fw,is,10,regs)&9)==9) {
5982 if(isASCIIstring(fw,regs[0])) {
5983
5984 char *buf=malloc(64);
5985 char *nm=(char *)adr2ptr(fw,regs[0]);
5986 sprintf(buf,"task_%s",nm);
5987
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 }
5997
5998 int save_ptp_handler_func(firmware *fw,uint32_t op,uint32_t handler) {
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
6008 add_func_name(fw,buf,handler,NULL);
6009 } else {
6010 return 0;
6011 }
6012 return 1;
6013 }
6014 int process_add_ptp_handler_call(firmware *fw, iter_state_t *is, __attribute__ ((unused))uint32_t unused) {
6015 uint32_t regs[4];
6016
6017 if((get_call_const_args(fw,is,8,regs)&3)==3) {
6018
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
6025 arm_reg ptr_reg = ARM_REG_INVALID;
6026 int i;
6027
6028 for(i=1; i<6; i++) {
6029 fw_disasm_iter_single(fw,adr_hist_get(&is->ah,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
6037 ) {
6038 continue;
6039 }
6040 ptr_reg = insn->detail->arm.operands[1].mem.base;
6041
6042 break;
6043 }
6044
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
6051
6052 for(; i<20; i++) {
6053 fw_disasm_iter_single(fw,adr_hist_get(&is->ah,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
6062 uint32_t adr=LDR_PC2val(fw,insn);
6063
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
6074
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
6079 if(!save_ptp_handler_func(fw,op,handler)) {
6080 break;
6081 }
6082 }
6083 return 0;
6084 }
6085 }
6086
6087 int add_generic_func_match(search_calls_multi_data_t *match_fns,
6088 int *match_fn_count,
6089 int max_funcs,
6090 search_calls_multi_fn fn,
6091 uint32_t adr)
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 }
6106 #define MAX_GENERIC_FUNCS 16
6107 void add_generic_sig_match(search_calls_multi_data_t *match_fns,
6108 int *match_fn_count,
6109 search_calls_multi_fn fn,
6110 const char *name)
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 }
6125
6126 void find_exception_handlers(firmware *fw, iter_state_t *is)
6127 {
6128 uint32_t ex_vec = 0;
6129
6130 if (fw->arch_flags & FW_ARCH_FL_VMSA) {
6131 const insn_match_t match_mcr_vbar[]={
6132
6133 {MATCH_INS(MCR, 6), {MATCH_OP_PIMM(15),MATCH_OP_IMM(0),MATCH_OP_REG_ANY,MATCH_OP_CIMM(12),MATCH_OP_CIMM(0),MATCH_OP_IMM(0)}},
6134 {ARM_INS_ENDING}
6135 };
6136
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
6142 disasm_iter_init(fw, is, adr_hist_get(&is->ah,1));
6143 disasm_iter(fw, is);
6144
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
6151
6152
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
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
6180
6181 addr=LDR_PC2val(fw,is->insn);
6182 if(addr) {
6183 add_func_name(fw,names[i],addr,NULL);
6184 }
6185 }
6186 }
6187
6188
6189
6190
6191
6192 void find_generic_funcs(firmware *fw) {
6193 search_calls_multi_data_t match_fns[MAX_GENERIC_FUNCS];
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);
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);
6224
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 }
6232
6233 void find_ctypes(firmware *fw)
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
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 }
6273
6274 void print_misc_val_makefile(const char *name)
6275 {
6276 misc_val_t *mv=get_misc_val(name);
6277 if(!mv) {
6278 return;
6279 }
6280
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 }
6294
6295
6296 void output_firmware_vals(firmware *fw)
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;
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
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
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
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 }
6423
6424
6425 void print_platform_misc_val_undef(const char *name, uint32_t def)
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 }
6433
6434 void output_platform_vals(firmware *fw) {
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 }
6468
6469 void output_propcases(firmware *fw) {
6470
6471 uint32_t used=0;
6472 uint32_t hits[KNOWN_PROPSET_COUNT];
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
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;
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;
6537 m += 1;
6538 }
6539 }
6540 }
6541 bprintf("\n");
6542 if (!okay && fw->sv->propset>0)
6543 {
6544
6545 bprintf("// Port's propset (%i) may be set incorrectly\n", fw->sv->propset);
6546 }
6547
6548 add_blankline();
6549 }
6550
6551 void output_exmem_types(firmware *fw)
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 }
6567
6568 void print_misc_val_comment(const char *name)
6569 {
6570 misc_val_t *mv=get_misc_val(name);
6571 if(!mv) {
6572 return;
6573 }
6574
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 }
6588
6589 typedef struct {
6590 int reg;
6591 uint32_t bit;
6592 uint32_t ev;
6593 uint32_t raw_info;
6594 int no_invert;
6595 } physw_table_entry_t;
6596
6597 void get_physw_table_entry(firmware *fw, uint32_t adr, physw_table_entry_t *vals)
6598 {
6599 uint32_t info=fw_u32(fw,adr);
6600 vals->raw_info=info;
6601 vals->ev=fw_u32(fw,adr+4);
6602
6603 vals->reg=(info >>5) & 7;
6604 vals->bit=(1 << (info & 0x1f));
6605
6606 vals->no_invert=((info&0xff0000)==0x10000)?1:0;
6607 }
6608 uint32_t find_physw_table_entry(firmware *fw, uint32_t tadr, int tcount, uint32_t ev)
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 }
6618
6619 uint32_t find_physw_table_max(firmware *fw, uint32_t tadr, int max_count)
6620 {
6621 int i;
6622 for(i=0; i<max_count; i++,tadr += 8) {
6623 physw_table_entry_t v;
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
6629 }
6630 return max_count;
6631 }
6632 void write_physw_event_table_dump(firmware *fw, uint32_t tadr, int tcount)
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;
6641 physw_table_entry_t v;
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 }
6649 void print_kval(firmware *fw, uint32_t tadr, int tcount, uint32_t ev, const char *name, const char *sfx)
6650 {
6651 uint32_t adr=find_physw_table_entry(fw,tadr,tcount,ev);
6652 if(!adr) {
6653 return;
6654 }
6655 physw_table_entry_t v;
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 }
6666
6667
6668 typedef struct {
6669 int reg;
6670 uint32_t bits;
6671 char nm[32];
6672 uint32_t fadr;
6673 uint32_t ev;
6674 int inv;
6675 } kinfo;
6676
6677 int kmask[3];
6678 kinfo key_info[100];
6679 int kcount = 0;
6680 uint32_t kshutter_min_bits = 0xFFFFFFFF;
6681
6682 void add_kinfo(int r, uint32_t b, const char *nm, uint32_t adr, uint32_t ev, int inv)
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 }
6694
6695 uint32_t add_kmval(firmware *fw, uint32_t tadr, __attribute__ ((unused))int tsiz, int tlen, uint32_t ev, const char *name, uint32_t xtra)
6696 {
6697 uint32_t adr=find_physw_table_entry(fw,tadr,tlen,ev);
6698 if(!adr) {
6699 return 0;
6700 }
6701 physw_table_entry_t v;
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 }
6707
6708 int kinfo_compare(const kinfo *p1, const kinfo *p2)
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))
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
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 }
6763
6764 void print_kmvals()
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 }
6778
6779 void do_km_vals(firmware *fw, uint32_t tadr,int tsiz,int tlen)
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
6789 if (fw->dryos_ver == 52)
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
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
6831
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
6847
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);
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 }
6868 void output_physw_vals(firmware *fw) {
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
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 }
6899
6900
6901
6902
6903
6904
6905
6906
6907
6908
6909
6910
6911
6912
6913
6914
6915
6916
6917
6918
6919
6920
6921
6922
6923
6924
6925
6926
6927
6928
6929
6930
6931
6932
6933
6934 void output_modemap(firmware *fw) {
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
6958
6959
6960
6961
6962 bprintf("\n");
6963 bad++;
6964 } else {
6965
6966 m->pct = 100;
6967 }
6968 }
6969 osig *m = fw->sv->modemap;
6970 while (m)
6971 {
6972 if (m->pct != 100)
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 }
6986
6987
6988 int compare_sig_names(const sig_entry_t **p1, const sig_entry_t **p2)
6989 {
6990 int rv = strcasecmp((*p1)->name, (*p2)->name);
6991 if (rv != 0)
6992 return rv;
6993 rv = strcmp((*p1)->name, (*p2)->name);
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 }
7002
7003 int compare_func_addresses(const sig_entry_t **p1, const sig_entry_t **p2)
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 }
7011
7012 void write_funcs(firmware *fw, char *filename, sig_entry_t *fns[], int (*compare)(const sig_entry_t **p1, const sig_entry_t **p2))
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
7039 fprintf(out_fp, "0,%s,(NOT FOUND)\n", fns[k]->name);
7040 }
7041 #endif
7042 }
7043 fclose(out_fp);
7044 }
7045
7046 void write_func_lists(firmware *fw) {
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 }
7055
7056 void print_other_stubs_min(firmware *fw, const char *name, uint32_t fadr, uint32_t atadr)
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 }
7077
7078 void print_stubs_min_def(firmware *fw, misc_val_t *sig)
7079 {
7080 if(sig->flags & MISC_VAL_NO_STUB) {
7081 return;
7082 }
7083
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 }
7129
7130
7131 void find_other_stubs_min(firmware *fw)
7132 {
7133 int k,k1;
7134
7135 out_hdr = 1;
7136
7137
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 }
7175
7176
7177
7178 void print_results(firmware *fw, sig_entry_t *sig)
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
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
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
7234
7235
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
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
7273
7274
7275
7276
7277
7278
7279
7280 }
7281
7282 void write_stubs(firmware *fw,int max_find_func) {
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
7291 find_other_stubs_min(fw);
7292
7293 add_blankline();
7294
7295 for (k = 0; k < max_find_func; k++)
7296 {
7297 print_results(fw,&sig_names[k]);
7298 }
7299 }
7300
7301 int main(int argc, char **argv)
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
7312 for (next_sig_entry = 0; sig_names[next_sig_entry].name != 0; next_sig_entry++);
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 }
7328 firmware_init_data_ranges(&fw);
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
7338 find_ctypes(&fw);
7339
7340 run_sig_rules(&fw,sig_rules_initial);
7341 find_generic_funcs(&fw);
7342 run_sig_rules(&fw,sig_rules_main);
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 }