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)) {