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_with_j
- 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_get_nd_value
- sig_match_get_current_exp
- sig_match_get_current_nd_value
- sig_match_imager_active_callback
- sig_match_imager_active
- sig_match_screenlock_helper
- 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_open_gt_57
- sig_match_close_gt_57
- 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_58
- 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_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_cam_has_iris_diaphragm
- sig_match_cam_uncached_bit
- 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__nrflag
- sig_match_var_struct_get
- 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_rom_ptr_get
- find_call_near_str
- sig_match_near_str
- sig_match_prop_string
- is_immediate_ret_sub
- sig_match_named_last
- sig_match_named_save_sig
- sig_match_named
- 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
32 char out_buf[32*1024] = "";
33 int out_len = 0;
34 char hdr_buf[32*1024] = "";
35 int hdr_len = 0;
36 int out_hdr = 1;
37
38 FILE *out_fp;
39
40 void bprintf(char *fmt, ...)
41 {
42 va_list argp;
43 va_start(argp, fmt);
44
45 if (out_hdr)
46 hdr_len += vsprintf(hdr_buf+hdr_len,fmt,argp);
47 else
48 out_len += vsprintf(out_buf+out_len,fmt,argp);
49
50 va_end(argp);
51 }
52
53 void add_blankline()
54 {
55 if (strcmp(hdr_buf+hdr_len-2,"\n\n") != 0)
56 {
57 hdr_buf[hdr_len++] = '\n';
58 hdr_buf[hdr_len] = 0;
59 }
60 }
61
62 void write_output()
63 {
64 add_blankline();
65 if (out_fp)
66 {
67 fprintf(out_fp,"%s",hdr_buf);
68 fprintf(out_fp,"%s",out_buf);
69 }
70 }
71
72
73
74 #define DONT_EXPORT 0x01
75 #define OPTIONAL 0x02
76 #define UNUSED 0x04
77 #define BAD_MATCH 0x08
78 #define EV_MATCH 0x10
79 #define LIST_ALWAYS 0x20
80
81 #define ARM_STUB 0x80
82 #define DONT_EXPORT_ILC 0x100
83
84 typedef struct {
85 char *name;
86 int flags;
87 uint32_t val;
88 } sig_entry_t;
89
90 int next_sig_entry = 0;
91
92 #define MAX_SIG_ENTRY 5000
93
94 sig_entry_t sig_names[MAX_SIG_ENTRY] =
95 {
96
97 { "ExportToEventProcedure_FW", UNUSED|DONT_EXPORT },
98 { "RegisterEventProcedure", UNUSED|DONT_EXPORT },
99 { "RegisterEventProcedure_alt1", UNUSED|DONT_EXPORT },
100 { "RegisterEventProcedure_alt2", UNUSED|DONT_EXPORT },
101 { "RegisterEventProcTable", UNUSED|DONT_EXPORT },
102 { "UnRegisterEventProcTable", UNUSED|DONT_EXPORT },
103 { "UnRegisterEventProcedure", UNUSED|DONT_EXPORT },
104 { "PrepareDirectory_1", UNUSED|DONT_EXPORT },
105 { "PrepareDirectory_x", UNUSED|DONT_EXPORT },
106 { "PrepareDirectory_0", UNUSED|DONT_EXPORT },
107 { "CreateTaskStrictly", UNUSED|DONT_EXPORT },
108 { "CreateTaskStrictly_alt", UNUSED|DONT_EXPORT },
109 { "CreateTask_alt", UNUSED|DONT_EXPORT },
110 { "CreateTask_low", UNUSED | OPTIONAL },
111 { "CreateJumptable", UNUSED },
112 { "_uartr_req", UNUSED },
113 { "StartRecModeMenu", UNUSED },
114 { "LogCameraEvent", UNUSED|DONT_EXPORT },
115 { "getImageDirName", UNUSED|DONT_EXPORT },
116
117 { "AllocateMemory", UNUSED|LIST_ALWAYS },
118 { "AllocateUncacheableMemory" },
119 { "Close" },
120 { "CreateBinarySemaphore" },
121 { "CreateCountingSemaphore", UNUSED|LIST_ALWAYS },
122 { "CreateTask" },
123 { "DebugAssert", OPTIONAL|LIST_ALWAYS },
124 { "DeleteDirectory_Fut" },
125 { "DeleteFile_Fut" },
126 { "DeleteSemaphore", UNUSED|LIST_ALWAYS },
127 { "DoAELock" },
128 { "DoAFLock" },
129 { "EnterToCompensationEVF" },
130 { "ExecuteEventProcedure", ARM_STUB },
131 { "ExitFromCompensationEVF" },
132 { "ExitTask" },
133 { "ExpCtrlTool_StartContiAE" },
134 { "ExpCtrlTool_StopContiAE" },
135 { "Fclose_Fut" },
136 { "Feof_Fut" },
137 { "Fflush_Fut" },
138 { "Fgets_Fut" },
139 { "Fopen_Fut" },
140 { "Fread_Fut" },
141 { "FreeMemory", UNUSED|LIST_ALWAYS },
142 { "FreeUncacheableMemory" },
143 { "Fseek_Fut" },
144 { "Fwrite_Fut" },
145 { "GetBatteryTemperature" },
146 { "GetCCDTemperature" },
147
148 { "GetCurrentAvValue" },
149 { "GetCurrentShutterSpeed" },
150 { "GetUsableMaxAv", OPTIONAL },
151 { "GetUsableMinAv", OPTIONAL },
152 { "GetUsableAvRange", UNUSED |OPTIONAL },
153 { "get_nd_value", OPTIONAL },
154 { "get_current_exp", UNUSED | OPTIONAL },
155 { "get_current_nd_value", OPTIONAL },
156 { "GetDrive_ClusterSize" },
157 { "GetDrive_FreeClusters" },
158 { "GetDrive_TotalClusters" },
159 { "GetFocusLensSubjectDistance" },
160 { "GetFocusLensSubjectDistanceFromLens" },
161 { "GetImageFolder", OPTIONAL },
162 { "GetKbdState" },
163 { "GetMemInfo" },
164 { "GetOpticalTemperature" },
165 { "GetParameterData" },
166 { "GetPropertyCase" },
167 { "GetSystemTime" },
168 { "GetVRAMHPixelsSize" },
169 { "GetVRAMVPixelsSize" },
170 { "GetZoomLensCurrentPoint" },
171 { "GetZoomLensCurrentPosition" },
172 { "GiveSemaphore", OPTIONAL|LIST_ALWAYS },
173 { "IsStrobeChargeCompleted" },
174 { "LEDDrive", OPTIONAL },
175 { "LocalTime" },
176 { "LockMainPower" },
177 { "Lseek", UNUSED|LIST_ALWAYS },
178 { "MakeDirectory_Fut" },
179 { "MakeSDCardBootable", OPTIONAL },
180 { "MoveFocusLensToDistance" },
181 { "MoveIrisWithAv", OPTIONAL },
182 { "MoveZoomLensWithPoint", DONT_EXPORT_ILC},
183 { "NewTaskShell", UNUSED },
184 { "Open" },
185 { "PB2Rec" },
186 { "PT_MoveDigitalZoomToWide", OPTIONAL | DONT_EXPORT_ILC},
187 { "PT_MoveOpticalZoomAt", OPTIONAL | DONT_EXPORT_ILC },
188 { "MoveOpticalZoomAt", OPTIONAL | DONT_EXPORT_ILC },
189 { "PT_PlaySound" },
190 { "PostLogicalEventForNotPowerType" },
191 { "PostLogicalEventToUI" },
192 { "PutInNdFilter", OPTIONAL },
193 { "PutOutNdFilter", OPTIONAL },
194 { "Read" },
195 { "ReadFastDir" },
196 { "Rec2PB" },
197 { "Remove", OPTIONAL|UNUSED },
198 { "RenameFile_Fut" },
199 { "Restart" },
200 { "screenlock_helper", UNUSED|DONT_EXPORT },
201 { "ScreenLock" },
202 { "ScreenUnlock" },
203 { "SetAE_ShutterSpeed" },
204 { "SetAutoShutdownTime" },
205 { "SetCurrentCaptureModeType" },
206 { "SetDate" },
207 { "SetFileAttributes" },
208 { "SetFileTimeStamp" },
209 { "SetLogicalEventActive" },
210 { "SetParameterData" },
211 { "SetPropertyCase" },
212 { "SetScriptMode" },
213 { "SleepTask" },
214 { "TakeSemaphore" },
215 { "TurnOffBackLight" },
216 { "TurnOnBackLight" },
217 { "TurnOnDisplay" },
218 { "TurnOffDisplay" },
219 { "UIFS_WriteFirmInfoToFile", OPTIONAL|UNUSED},
220 { "UnlockAE" },
221 { "UnlockAF" },
222 { "UnlockMainPower" },
223 { "UnsetZoomForMovie", OPTIONAL | DONT_EXPORT_ILC },
224
225 { "VbattGet" },
226 { "Write" },
227 { "WriteSDCard" },
228
229 { "_log" },
230 { "_log10" },
231 { "_pow" },
232 { "_sqrt" },
233 { "add_ptp_handler" },
234 { "apex2us" },
235 { "close" },
236 { "displaybusyonscreen", OPTIONAL },
237 { "err_init_task", OPTIONAL },
238 { "exmem_alloc", OPTIONAL },
239 { "exmem_free", OPTIONAL|UNUSED },
240 { "exmem_ualloc" },
241 { "exmem_ufree" },
242 { "free" },
243
244 { "kbd_p1_f" },
245 { "kbd_p1_f_cont" },
246 { "kbd_p2_f" },
247 { "kbd_read_keys" },
248 { "kbd_read_keys_r2" },
249
250 { "kbd_pwr_off", OPTIONAL },
251 { "kbd_pwr_on", OPTIONAL },
252 { "lseek" },
253 { "malloc" },
254 { "memcmp" },
255 { "memcpy" },
256 { "memset" },
257
258
259 { "mktime_ext" },
260 { "open" },
261 { "OpenFastDir" },
262 { "closedir" },
263 { "get_fstype", OPTIONAL|LIST_ALWAYS },
264 { "qsort" },
265 { "rand" },
266 { "read", UNUSED|OPTIONAL },
267 { "realloc", OPTIONAL|LIST_ALWAYS },
268 { "reboot_fw_update" },
269 { "set_control_event" },
270 { "srand" },
271 { "stat" },
272 { "strcat" },
273 { "strchr" },
274 { "strcmp" },
275 { "strcpy" },
276 { "strftime" },
277 { "strlen" },
278 { "strncmp" },
279 { "strncpy" },
280 { "strrchr" },
281 { "strtol" },
282 { "strtolx" },
283
284 { "task_CaptSeq" },
285 { "task_DvlpSeqTask", OPTIONAL },
286 { "task_ExpDrv" },
287 { "task_FileWrite", OPTIONAL },
288 { "task_InitFileModules" },
289 { "task_MovieRecord" },
290 { "task_PhySw", OPTIONAL },
291 { "task_RotaryEncoder", OPTIONAL },
292 { "task_TouchPanel", OPTIONAL },
293 { "task_TricInitTask", OPTIONAL },
294
295 { "hook_CreateTask" },
296 { "hook_CreateTask_low", UNUSED},
297
298 { "time" },
299 { "vsprintf" },
300 { "write", UNUSED|OPTIONAL },
301 { "undisplaybusyonscreen", OPTIONAL },
302
303 { "EngDrvIn", OPTIONAL|UNUSED|LIST_ALWAYS },
304 { "EngDrvOut", OPTIONAL|UNUSED|LIST_ALWAYS },
305 { "EngDrvRead" },
306 { "EngDrvBits", OPTIONAL|UNUSED|LIST_ALWAYS },
307
308 { "PTM_GetCurrentItem" },
309 { "PTM_SetCurrentItem", UNUSED|LIST_ALWAYS },
310 { "PTM_NextItem", OPTIONAL|UNUSED|LIST_ALWAYS },
311 { "PTM_PrevItem", OPTIONAL|UNUSED|LIST_ALWAYS },
312 { "PTM_SetPropertyEnable", OPTIONAL|UNUSED|LIST_ALWAYS },
313
314 { "DisableISDriveError", OPTIONAL },
315
316
317 { "_GetSystemTime", OPTIONAL|UNUSED|LIST_ALWAYS },
318 { "SetTimerAfter", OPTIONAL|UNUSED|LIST_ALWAYS },
319 { "SetTimerWhen", OPTIONAL|UNUSED|LIST_ALWAYS },
320 { "CancelTimer", OPTIONAL|UNUSED|LIST_ALWAYS },
321 { "CancelHPTimer" },
322 { "SetHPTimerAfterTimeout", OPTIONAL|UNUSED|LIST_ALWAYS },
323 { "SetHPTimerAfterNow" },
324 { "CreateTaskStrictly", OPTIONAL|UNUSED|LIST_ALWAYS },
325 { "CreateMessageQueue", OPTIONAL|UNUSED|LIST_ALWAYS },
326 { "CreateRecursiveLock", OPTIONAL|UNUSED|LIST_ALWAYS },
327 { "GetSemaphoreValue", OPTIONAL|UNUSED|LIST_ALWAYS },
328 { "TryTakeSemaphore", OPTIONAL|UNUSED|LIST_ALWAYS },
329 { "CreateMessageQueueStrictly", OPTIONAL|UNUSED|LIST_ALWAYS },
330 { "CreateEventFlagStrictly", OPTIONAL|UNUSED|LIST_ALWAYS },
331 { "CreateBinarySemaphoreStrictly", OPTIONAL|UNUSED|LIST_ALWAYS },
332 { "CreateCountingSemaphoreStrictly", OPTIONAL|UNUSED|LIST_ALWAYS },
333 { "CreateRecursiveLockStrictly", OPTIONAL|UNUSED|LIST_ALWAYS },
334 { "TakeSemaphoreStrictly", OPTIONAL|UNUSED|LIST_ALWAYS },
335 { "ReceiveMessageQueueStrictly", OPTIONAL|UNUSED|LIST_ALWAYS },
336 { "PostMessageQueueStrictly", OPTIONAL|UNUSED|LIST_ALWAYS },
337 { "WaitForAnyEventFlagStrictly", OPTIONAL|UNUSED|LIST_ALWAYS },
338 { "WaitForAllEventFlagStrictly", OPTIONAL|UNUSED|LIST_ALWAYS },
339 { "AcquireRecursiveLockStrictly", OPTIONAL|UNUSED|LIST_ALWAYS },
340 { "DeleteMessageQueue", OPTIONAL|UNUSED|LIST_ALWAYS },
341 { "PostMessageQueue", OPTIONAL|UNUSED|LIST_ALWAYS },
342 { "ReceiveMessageQueue", OPTIONAL|UNUSED|LIST_ALWAYS },
343 { "TryReceiveMessageQueue", OPTIONAL|UNUSED|LIST_ALWAYS },
344 { "TryPostMessageQueue", OPTIONAL|UNUSED|LIST_ALWAYS },
345 { "GetNumberOfPostedMessages", OPTIONAL|UNUSED|LIST_ALWAYS },
346 { "DeleteRecursiveLock", OPTIONAL|UNUSED|LIST_ALWAYS },
347 { "AcquireRecursiveLock", OPTIONAL|UNUSED|LIST_ALWAYS },
348 { "ReleaseRecursiveLock", OPTIONAL|UNUSED|LIST_ALWAYS },
349 { "WaitForAnyEventFlag", OPTIONAL|UNUSED|LIST_ALWAYS },
350 { "WaitForAllEventFlag", OPTIONAL|UNUSED|LIST_ALWAYS },
351 { "ClearEventFlag", OPTIONAL|UNUSED|LIST_ALWAYS },
352 { "SetEventFlag", OPTIONAL|LIST_ALWAYS },
353 { "GetEventFlagValue", OPTIONAL|UNUSED|LIST_ALWAYS },
354 { "CreateEventFlag", OPTIONAL|UNUSED|LIST_ALWAYS },
355 { "DeleteEventFlag", OPTIONAL|UNUSED|LIST_ALWAYS },
356 { "CheckAnyEventFlag", OPTIONAL|UNUSED|LIST_ALWAYS },
357 { "CheckAllEventFlag", OPTIONAL|UNUSED|LIST_ALWAYS },
358 { "RegisterInterruptHandler", OPTIONAL|UNUSED|LIST_ALWAYS },
359 { "UnregisterInterruptHandler", OPTIONAL|UNUSED|LIST_ALWAYS },
360 { "GetSRAndDisableInterrupt", OPTIONAL|UNUSED|LIST_ALWAYS },
361 { "SetSR", OPTIONAL|UNUSED|LIST_ALWAYS },
362 { "EnableInterrupt", OPTIONAL|UNUSED|LIST_ALWAYS },
363 { "_divmod_signed_int", OPTIONAL|UNUSED|LIST_ALWAYS},
364 { "_divmod_unsigned_int", OPTIONAL|UNUSED|LIST_ALWAYS},
365 { "_dflt", OPTIONAL|UNUSED|LIST_ALWAYS},
366 { "_dfltu", OPTIONAL|UNUSED|LIST_ALWAYS},
367 { "_dfix", OPTIONAL|UNUSED|LIST_ALWAYS},
368 { "_dfixu", OPTIONAL|UNUSED|LIST_ALWAYS},
369 { "_dmul", OPTIONAL|UNUSED|LIST_ALWAYS},
370 { "_ddiv", OPTIONAL|UNUSED|LIST_ALWAYS},
371 { "_dadd", OPTIONAL|UNUSED|LIST_ALWAYS},
372 { "_dsub", OPTIONAL|UNUSED|LIST_ALWAYS},
373 { "_drsb", OPTIONAL|UNUSED|LIST_ALWAYS},
374 { "_dcmp", OPTIONAL|UNUSED|LIST_ALWAYS},
375 { "_dcmp_reverse", OPTIONAL|UNUSED|LIST_ALWAYS},
376 { "_safe_sqrt", OPTIONAL|UNUSED|LIST_ALWAYS},
377 { "_scalbn", OPTIONAL|UNUSED|LIST_ALWAYS},
378 { "_fflt", OPTIONAL|UNUSED|LIST_ALWAYS},
379 { "_ffltu", OPTIONAL|UNUSED|LIST_ALWAYS},
380 { "_ffix", OPTIONAL|UNUSED|LIST_ALWAYS},
381 { "_ffixu", OPTIONAL|UNUSED|LIST_ALWAYS},
382 { "_fmul", OPTIONAL|UNUSED|LIST_ALWAYS},
383 { "_fdiv", OPTIONAL|UNUSED|LIST_ALWAYS},
384 { "_f2d", OPTIONAL|UNUSED|LIST_ALWAYS},
385 { "DisplayBusyOnScreen", OPTIONAL|UNUSED|LIST_ALWAYS},
386 { "UndisplayBusyOnScreen", OPTIONAL|UNUSED|LIST_ALWAYS},
387 { "CreateDialogBox", OPTIONAL|UNUSED|LIST_ALWAYS},
388 { "DisplayDialogBox", OPTIONAL|UNUSED|LIST_ALWAYS},
389 { "add_ui_to_dialog", OPTIONAL|UNUSED|LIST_ALWAYS},
390 { "get_string_by_id", OPTIONAL|UNUSED|LIST_ALWAYS},
391 { "malloc_strictly", OPTIONAL|UNUSED|LIST_ALWAYS },
392 { "GetCurrentMachineTime", OPTIONAL|UNUSED|LIST_ALWAYS },
393 { "HwOcReadICAPCounter", OPTIONAL|UNUSED|LIST_ALWAYS },
394 { "transfer_src_overlay_helper",UNUSED},
395 { "transfer_src_overlay" },
396 { "GraphicSystemCoreFinish_helper", OPTIONAL|UNUSED },
397 { "GraphicSystemCoreFinish", OPTIONAL|UNUSED },
398 { "mzrm_createmsg", OPTIONAL|UNUSED },
399 { "mzrm_sendmsg", OPTIONAL|UNUSED },
400 { "zicokick_start", OPTIONAL|UNUSED },
401 { "zicokick_copy", OPTIONAL|UNUSED },
402 { "init_ex_drivers", OPTIONAL|UNUSED },
403 { "omar_init", OPTIONAL|UNUSED },
404
405 { "createsemaphore_low", OPTIONAL|UNUSED },
406
407 { "givesemaphore_low", OPTIONAL|UNUSED},
408 { "takesemaphore_low", OPTIONAL|UNUSED },
409 { "bzero" },
410 { "memset32" },
411 { "get_dial_hw_position", OPTIONAL },
412
413
414 { "GetSDProtect", UNUSED },
415 { "DispCon_ShowBitmapColorBar", UNUSED },
416 { "ResetZoomLens", OPTIONAL|UNUSED },
417 { "ResetFocusLens", OPTIONAL|UNUSED },
418 { "NR_GetDarkSubType", OPTIONAL|UNUSED },
419 { "NR_SetDarkSubType", OPTIONAL|UNUSED },
420 { "SavePaletteData", OPTIONAL|UNUSED },
421 { "GUISrv_StartGUISystem", OPTIONAL|UNUSED|LIST_ALWAYS },
422 { "get_resource_pointer", OPTIONAL|UNUSED|LIST_ALWAYS },
423 { "CalcLog10", OPTIONAL|UNUSED|LIST_ALWAYS },
424 { "CalcSqrt", OPTIONAL|UNUSED },
425 { "dry_memcpy", OPTIONAL|UNUSED },
426 { "get_playrec_mode", OPTIONAL|UNUSED },
427 { "DebugAssert2", OPTIONAL|UNUSED },
428 { "get_canon_mode_list", OPTIONAL|UNUSED },
429 { "taskcreate_LowConsole", OPTIONAL|UNUSED },
430 { "ImagerActivate", OPTIONAL|UNUSED },
431 { "imager_active_callback", OPTIONAL|UNUSED },
432 { "file_counter_var_init", OPTIONAL|UNUSED },
433 { "get_displaytype", OPTIONAL|UNUSED },
434
435 { "MFOn", OPTIONAL },
436 { "MFOff", OPTIONAL },
437 { "PT_MFOn", OPTIONAL },
438 { "PT_MFOff", OPTIONAL },
439 { "SS_MFOn", OPTIONAL },
440 { "SS_MFOff", OPTIONAL },
441
442 { "GetAdChValue", OPTIONAL },
443
444
445 { "EnableHDMIPower", OPTIONAL },
446 { "DisableHDMIPower", OPTIONAL },
447
448 { "SetVideoOutType", OPTIONAL },
449 { "GetVideoOutType", OPTIONAL },
450
451 {0,0,0},
452 };
453
454 typedef struct {
455 char* name;
456 int id;
457 int use;
458
459 int id_ps6;
460 int id_ps7;
461 int id_ps8;
462 int id_ps9;
463 int id_ps10;
464 int id_ps11;
465 int id_ps12;
466 int id_ps13;
467 } known_prop_t;
468
469 #define KNOWN_PROPSET_COUNT (13-5)
470
471 known_prop_t knownprops[] =
472 {
473 {"PROPCASE_AFSTEP" , -1, 2, 13, 13, 13, 13, 13, 13, 13, 13},
474 {"PROPCASE_FOCUS_STATE" , -1, 1, 18, 18, 18, 18, 18, 18, 18, 18},
475 {"PROPCASE_AV" , -1, 1, 23, 23, 23, 23, 23, 23, 23, 23},
476 {"PROPCASE_BV" , -1, 1, 34, 38, 35, 38, 40, 40, 40, 40},
477 {"PROPCASE_DELTA_DIGITALGAIN" , -1, 2, 77, 82, 79, 82, 84, 85, 85, 84},
478 {"PROPCASE_DELTA_SV" , -1, 1, 79, 84, 81, 84, 86, 87, 87, 86},
479 {"PROPCASE_DELTA_ND" , -1, 2, 80, 85, 82, 85, 87, 88, 88, 87},
480 {"PROPCASE_FELOCK" , -1, 2,114,120,117,120, 122, 123, 123, 122},
481 {"PROPCASE_FLASH_ADJUST_MODE" , -1, 1,121,127,124,127, 129, 130, 130, 129},
482 {"PROPCASE_FLASH_FIRE" , -1, 1,122,128,125,128, 130, 131, 131, 130},
483 {"PROPCASE_HSCAPTURE" , -1, 2,138,144,141,144, 146, 147, 147, 146},
484 {"PROPCASE_EV_CORRECTION_2" , -1, 1,210,216,213,216, 218, 219, 220, 218},
485 {"PROPCASE_ORIENTATION_SENSOR" , -1, 1,222,228,225,228, 230, 231, 232, 230},
486 {"PROPCASE_SV_MARKET" , -1, 1,249,255,252,255, 257, 259, 260, 258},
487 {"PROPCASE_SVFIX" , -1, 0, 0, 0, 0, 0, 0, 0, 0, 259},
488 {"PROPCASE_TV" , -1, 1,265,272,269,272, 274, 276, 277, 275},
489 {0,}
490 };
491
492 void add_prop_hit(char *name, int id)
493 {
494 int n = 0;
495 while (knownprops[n].name) {
496 if (strcmp(knownprops[n].name,name) == 0) {
497 knownprops[n].id = id;
498 break;
499 }
500 n++;
501 }
502 }
503
504 #define MISC_BLOB_XTENSA_MAX 5
505 #define MISC_BLOB_TYPE_NONE 0
506 #define MISC_BLOB_TYPE_XTENSA 1
507 #define MISC_BLOB_TYPE_OMAR 2
508 typedef struct {
509 int type;
510 uint32_t rom_adr;
511 uint32_t ram_adr;
512 uint32_t size;
513 } misc_blob_t;
514
515
516 #define MISC_VAL_NO_STUB 1
517
518 #define MISC_VAL_DEF_CONST 2
519 #define MISC_VAL_OPTIONAL 4
520
521 typedef struct {
522 char *name;
523 int flags;
524 uint32_t val;
525
526 uint32_t base;
527 uint32_t offset;
528 uint32_t ref_adr;
529 misc_blob_t *blobs;
530 } misc_val_t;
531
532 misc_val_t misc_vals[]={
533
534 { "ctypes", },
535 { "physw_run", },
536 { "physw_sleep_delay", },
537 { "physw_status", },
538 { "fileio_semaphore", },
539 { "levent_table", },
540 { "FlashParamsTable", },
541 { "playrec_mode", },
542 { "jpeg_count_str", },
543 { "zoom_busy", },
544 { "focus_busy", },
545 { "imager_active", },
546 { "canon_menu_active", },
547 { "file_counter_var", },
548 { "_nrflag", MISC_VAL_OPTIONAL},
549 { "av_override_semaphore",MISC_VAL_OPTIONAL},
550 { "active_bitmap_buffer",MISC_VAL_OPTIONAL},
551 { "displaytype", MISC_VAL_OPTIONAL},
552 { "bitmap_buffer", MISC_VAL_OPTIONAL},
553 { "palette_control", MISC_VAL_OPTIONAL},
554 { "palette_buffer_ptr", MISC_VAL_OPTIONAL},
555 { "active_palette_buffer",MISC_VAL_OPTIONAL},
556 { "CAM_UNCACHED_BIT", MISC_VAL_NO_STUB},
557 { "physw_event_table", MISC_VAL_NO_STUB},
558 { "uiprop_count", MISC_VAL_DEF_CONST},
559 { "canon_mode_list", MISC_VAL_NO_STUB},
560 { "ARAM_HEAP_START", MISC_VAL_NO_STUB},
561 { "ARAM_HEAP_SIZE", MISC_VAL_NO_STUB},
562 { "zicokick_values", MISC_VAL_NO_STUB},
563 { "omar_init_data", MISC_VAL_NO_STUB},
564 { "omar_init_values", MISC_VAL_NO_STUB},
565 { "CAM_HAS_ND_FILTER", MISC_VAL_NO_STUB},
566 { "CAM_IS_ILC", MISC_VAL_NO_STUB},
567 { "CAM_HAS_IRIS_DIAPHRAGM",MISC_VAL_NO_STUB},
568 { "exmem_alloc_table", },
569 { "exmem_types_table", },
570 { "exmem_type_count", MISC_VAL_DEF_CONST},
571 {0,0,0},
572 };
573
574 misc_val_t *get_misc_val(const char *name)
575 {
576 misc_val_t *p=misc_vals;
577 while(p->name) {
578 if(strcmp(name,p->name) == 0) {
579 return p;
580 }
581 p++;
582 }
583 return NULL;
584 }
585
586
587 uint32_t get_misc_val_value(const char *name)
588 {
589 misc_val_t *p=get_misc_val(name);
590 if(!p) {
591 printf("get_misc_val_value: invalid name %s\n",name);
592 return 0;
593 }
594 return p->val;
595 }
596 void save_misc_val(const char *name, uint32_t base, uint32_t offset, uint32_t ref_adr)
597 {
598 misc_val_t *p=get_misc_val(name);
599 if(!p) {
600 printf("save_misc_val: invalid name %s\n",name);
601 return;
602 }
603 p->val = base + offset;
604 p->base = base;
605 p->offset = offset;
606 p->ref_adr = ref_adr;
607 p->blobs = NULL;
608 }
609 void save_misc_val_blobs(const char *name, misc_blob_t *blobs, uint32_t ref_adr)
610 {
611 misc_val_t *p=get_misc_val(name);
612 if(!p) {
613 printf("save_misc_val: invalid name %s\n",name);
614 return;
615 }
616 p->val = p->base = p->offset = 0;
617 p->ref_adr = ref_adr;
618 p->blobs = blobs;
619 }
620
621
622 #if 0
623 int find_saved_sig_index(const char *name)
624 {
625 int i;
626 for (i=0; sig_names[i].name != 0; i++)
627 {
628 if (strcmp(name,sig_names[i].name) == 0)
629 {
630 return i;
631 }
632 }
633 return -1;
634 }
635 #endif
636
637 sig_entry_t * find_saved_sig(const char *name)
638 {
639 int i;
640 for (i=0; sig_names[i].name != 0; i++)
641 {
642 if (strcmp(name,sig_names[i].name) == 0)
643 {
644 return &sig_names[i];
645 }
646 }
647 return NULL;
648 }
649
650
651 uint32_t get_saved_sig_val(const char *name)
652 {
653 sig_entry_t *sig=find_saved_sig(name);
654 if(!sig) {
655
656 return 0;
657 }
658 return sig->val;
659 }
660
661
662
663 #if 0
664 int find_saved_sig_index_by_adr(uint32_t adr)
665 {
666 if(!adr) {
667 return -1;
668 }
669 int i;
670 for (i=0; sig_names[i].name != 0; i++)
671 {
672 if (sig_names[i].val == adr)
673 {
674 return i;
675 }
676 }
677 return -1;
678 }
679 #endif
680 #if 0
681 sig_entry_t* find_saved_sig_by_val(uint32_t val)
682 {
683 if(!val) {
684 return NULL;
685 }
686 int i;
687 for (i=0; sig_names[i].name != 0; i++)
688 {
689 if (sig_names[i].val == val)
690 {
691 return &sig_names[i];
692 }
693 }
694 return NULL;
695 }
696 #endif
697
698
699 void save_sig(firmware *fw, const char *name, uint32_t val)
700 {
701 sig_entry_t *sig = find_saved_sig(name);
702 if (!sig)
703 {
704 printf("save_sig: refusing to save unknown name %s\n",name);
705 return;
706 }
707
708 if(!adr_is_main_fw_code(fw,val)) {
709 printf("save_sig: refusing to save %s with out of range address 0x%08x\n",name,val);
710 return;
711 }
712 if(sig->val && sig->val != val) {
713 printf("save_sig: duplicate name %s existing 0x%08x != new 0x%08x\n",name,sig->val,val);
714 }
715 sig->val = val;
716 }
717
718 void add_func_name(firmware *fw, char *n, uint32_t eadr, char *suffix)
719 {
720 int k;
721
722 char *s = n;
723 int mallocd = 0;
724 if (suffix != 0)
725 {
726 s = malloc(strlen(n) + strlen(suffix) + 1);
727 sprintf(s, "%s%s", n, suffix);
728 mallocd = 1;
729 }
730
731
732 if(!adr_is_main_fw_code(fw,eadr)) {
733 printf("save_sig: refusing to save %s with out of range address 0x%08x\n",s,eadr);
734 if(mallocd) {
735 free(s);
736 }
737 return;
738 }
739
740 for (k=0; sig_names[k].name != 0; k++)
741 {
742 if (strcmp(sig_names[k].name, s) == 0)
743 {
744 if (sig_names[k].val == 0)
745 {
746 sig_names[k].val = eadr;
747 sig_names[k].flags |= EV_MATCH;
748 if (mallocd)
749 free(s);
750 return;
751 }
752 else if (sig_names[k].val == eadr)
753 {
754 if (mallocd)
755 free(s);
756 return;
757 }
758 else
759 {
760 printf("add_func_name: duplicate name %s existing 0x%08x != new 0x%08x\n",s, sig_names[k].val, eadr);
761 }
762 }
763 }
764
765 sig_names[next_sig_entry].name = s;
766 sig_names[next_sig_entry].flags = OPTIONAL|UNUSED;
767 sig_names[next_sig_entry].val = eadr;
768 next_sig_entry++;
769 sig_names[next_sig_entry].name = 0;
770 }
771
772
773 int save_sig_with_j(firmware *fw, char *name, uint32_t adr)
774 {
775 if(!adr) {
776 printf("save_sig_with_j: %s null adr\n",name);
777 return 0;
778 }
779
780 if(!fw_disasm_iter_single(fw,adr)) {
781 printf("save_sig_with_j: %s disassembly failed at 0x%08x\n",name,adr);
782 return 0;
783 }
784
785
786
787 uint32_t b_adr=get_direct_jump_target(fw,fw->is);
788 if(b_adr) {
789 char *buf=malloc(strlen(name)+6);
790 sprintf(buf,"j_%s",name);
791 add_func_name(fw,buf,adr,NULL);
792
793 adr=b_adr;
794 }
795 save_sig(fw,name,adr);
796 return 1;
797 }
798
799
800
801
802 int find_next_sig_call(firmware *fw, iter_state_t *is, uint32_t max_offset, const char *name)
803 {
804 uint32_t adr=get_saved_sig_val(name);
805
806 if(!adr) {
807 printf("find_next_sig_call: missing %s\n",name);
808 return 0;
809 }
810
811 search_calls_multi_data_t match_fns[3];
812
813 match_fns[0].adr=adr;
814 match_fns[0].fn=search_calls_multi_end;
815 char veneer[128];
816 sprintf(veneer,"j_%s",name);
817 adr=get_saved_sig_val(veneer);
818 if(!adr) {
819 match_fns[1].adr=0;
820 } else {
821 match_fns[1].adr=adr;
822 match_fns[1].fn=search_calls_multi_end;
823 match_fns[2].adr=0;
824 }
825 return fw_search_insn(fw,is,search_disasm_calls_multi,0,match_fns,is->adr + max_offset);
826 }
827
828
829 int is_sig_call(firmware *fw, iter_state_t *is, const char *name)
830 {
831 uint32_t adr=get_branch_call_insn_target(fw,is);
832
833
834 if(!adr) {
835 return 0;
836 }
837 uint32_t sig_adr=get_saved_sig_val(name);
838 osig* ostub2 = find_sig(fw->sv->stubs,name);
839 if (ostub2 && ostub2->val)
840 sig_adr = ostub2->val;
841 if(!sig_adr) {
842 printf("is_sig_call: missing %s\n",name);
843 return 0;
844 }
845 if(adr == sig_adr) {
846 return 1;
847 }
848 char veneer[128];
849 sprintf(veneer,"j_%s",name);
850 sig_adr=get_saved_sig_val(veneer);
851 if(!sig_adr) {
852 return 0;
853 }
854 return (adr == sig_adr);
855 }
856
857 typedef struct sig_rule_s sig_rule_t;
858 typedef int (*sig_match_fn)(firmware *fw, iter_state_t *is, sig_rule_t *rule);
859
860 struct sig_rule_s {
861 sig_match_fn match_fn;
862 char *name;
863 char *ref_name;
864 int param;
865 int dryos_min;
866 int dryos_max;
867
868
869
870
871
872
873
874
875 };
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894 int init_disasm_sig_ref(firmware *fw, iter_state_t *is, sig_rule_t *rule)
895 {
896 if(!rule->ref_name) {
897 printf("init_disasm_sig_ref: %s missing ref_name\n",rule->name);
898 return 0;
899 }
900 uint32_t adr=get_saved_sig_val(rule->ref_name);
901 if(!adr) {
902 printf("init_disasm_sig_ref: %s missing %s\n",rule->name,rule->ref_name);
903 return 0;
904 }
905 if(!disasm_iter_init(fw,is,adr)) {
906 printf("init_disasm_sig_ref: %s bad address 0x%08x for %s\n",rule->name,adr,rule->ref_name);
907 return 0;
908 }
909 return 1;
910 }
911
912 int sig_match_near_str(firmware *fw, iter_state_t *is, sig_rule_t *rule);
913
914
915
916
917
918 int sig_match_str_r0_call(firmware *fw, iter_state_t *is, sig_rule_t *rule)
919 {
920 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
921 if(!str_adr) {
922 printf("sig_match_str_r0_call: %s failed to find ref %s\n",rule->name,rule->ref_name);
923 return 0;
924 }
925
926
927
928
929 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
930 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
931 if(is->insn->detail->arm.operands[0].reg == ARM_REG_R0) {
932
933
934 if(insn_match_find_next(fw,is,4,match_b_bl_blximm)) {
935 uint32_t adr=get_branch_call_insn_target(fw,is);
936
937 return save_sig_with_j(fw,rule->name,adr);
938 }
939 }
940 }
941 return 0;
942 }
943
944
945 int sig_match_reg_evp(firmware *fw, iter_state_t *is, sig_rule_t *rule)
946 {
947 const insn_match_t reg_evp_match[]={
948 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R2), MATCH_OP_REG(R1)}},
949 {MATCH_INS(LDR, 2), {MATCH_OP_REG(R1), MATCH_OP_MEM_ANY}},
950 {MATCH_INS(B, MATCH_OPCOUNT_IGNORE)},
951 {ARM_INS_ENDING}
952 };
953
954 uint32_t e_to_evp=get_saved_sig_val("ExportToEventProcedure_FW");
955 if(!e_to_evp) {
956 printf("sig_match_reg_evp: failed to find ExportToEventProcedure, giving up\n");
957 return 0;
958 }
959
960
961 uint32_t reg_evp=0;
962
963 disasm_iter_init(fw,is,e_to_evp);
964 if(insn_match_seq(fw,is,reg_evp_match)) {
965 reg_evp=ADR_SET_THUMB(is->insn->detail->arm.operands[0].imm);
966
967 save_sig(fw,"RegisterEventProcedure",reg_evp);
968 }
969 return (reg_evp != 0);
970 }
971
972
973
974 int sig_match_reg_evp_table(firmware *fw, iter_state_t *is, sig_rule_t *rule)
975 {
976
977 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
978 if(!str_adr) {
979 printf("sig_match_reg_evp_table: failed to find %s\n",rule->ref_name);
980 return 0;
981 }
982
983 uint32_t reg_evp_alt1=0;
984 uint32_t reg_evp_tbl=0;
985 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
986 uint32_t dd_enable_p=0;
987 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
988 if(is->insn->detail->arm.operands[0].reg != ARM_REG_R0) {
989 continue;
990 }
991 if(!insn_match_find_next(fw,is,2,match_b_bl)) {
992 continue;
993 }
994 reg_evp_alt1=ADR_SET_THUMB(is->insn->detail->arm.operands[0].imm);
995
996 save_sig(fw,"RegisterEventProcedure_alt1",reg_evp_alt1);
997
998 uint32_t regs[4];
999
1000
1001 if((get_call_const_args(fw,is,4,regs)&3)==3) {
1002
1003 if(regs[0]==str_adr) {
1004 dd_enable_p=regs[1];
1005
1006 add_func_name(fw,"DispDev_EnableEventProc",dd_enable_p,NULL);
1007 break;
1008 }
1009 }
1010 }
1011
1012 if(dd_enable_p) {
1013 disasm_iter_init(fw,is,dd_enable_p);
1014 if(insn_match_find_next(fw,is,4,match_b_bl)) {
1015
1016 uint32_t regs[4];
1017 if(get_call_const_args(fw,is,4,regs)&1) {
1018 reg_evp_tbl=ADR_SET_THUMB(is->insn->detail->arm.operands[0].imm);
1019
1020 save_sig(fw,"RegisterEventProcTable",reg_evp_tbl);
1021 }
1022 }
1023 }
1024 return (reg_evp_tbl != 0);
1025 }
1026
1027
1028 int sig_match_reg_evp_alt2(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1029 {
1030 uint32_t reg_evp_alt2=0;
1031
1032 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
1033 if(!str_adr) {
1034 printf("sig_match_reg_evp_alt2: failed to find %s\n",rule->ref_name);
1035 return 0;
1036 }
1037
1038 uint32_t reg_evp_alt1=get_saved_sig_val("RegisterEventProcedure_alt1");
1039
1040 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
1041 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
1042 if(is->insn->detail->arm.operands[0].reg != ARM_REG_R0) {
1043 continue;
1044 }
1045 if(!insn_match_find_next(fw,is,3,match_b_bl)) {
1046 continue;
1047 }
1048 uint32_t regs[4];
1049
1050 if((get_call_const_args(fw,is,4,regs)&3)==3) {
1051 if(regs[0]==str_adr) {
1052 reg_evp_alt2=ADR_SET_THUMB(is->insn->detail->arm.operands[0].imm);
1053
1054 if(reg_evp_alt2 == reg_evp_alt1) {
1055 printf("RegisterEventProcedure_alt2 == _alt1 at %"PRIx64"\n",is->insn->address);
1056 reg_evp_alt2=0;
1057 } else {
1058 save_sig(fw,"RegisterEventProcedure_alt2",reg_evp_alt2);
1059
1060
1061 }
1062 break;
1063 }
1064 }
1065 }
1066 return (reg_evp_alt2 != 0);
1067 }
1068
1069
1070 int sig_match_unreg_evp_table(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1071 {
1072 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
1073 if(!str_adr) {
1074 printf("sig_match_unreg_evp_table: failed to find %s\n",rule->ref_name);
1075 return 0;
1076 }
1077
1078 uint32_t reg_evp_alt1=get_saved_sig_val("RegisterEventProcedure_alt1");
1079 uint32_t reg_evp_alt2=get_saved_sig_val("RegisterEventProcedure_alt2");
1080
1081 uint32_t mecha_unreg=0;
1082 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
1083 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
1084
1085 if(is->insn->detail->arm.operands[0].reg != ARM_REG_R0) {
1086 continue;
1087 }
1088 if(!insn_match_find_next(fw,is,3,match_b_bl)) {
1089 continue;
1090 }
1091 uint32_t reg_call=get_branch_call_insn_target(fw,is);
1092
1093
1094 if(!reg_call || (reg_call != reg_evp_alt1 && reg_call != reg_evp_alt2)) {
1095 continue;
1096 }
1097 uint32_t regs[4];
1098 if((get_call_const_args(fw,is,4,regs)&3)==3) {
1099
1100 if(regs[0]==str_adr) {
1101 mecha_unreg=ADR_SET_THUMB(regs[1]);
1102 break;
1103 }
1104 }
1105 }
1106 if(!mecha_unreg) {
1107 return 0;
1108 }
1109
1110 disasm_iter_init(fw,is,mecha_unreg);
1111
1112 if(!insn_match_find_next(fw,is,7,match_b_bl)) {
1113 return 0;
1114 }
1115
1116 const insn_match_t match_ldr_r0[]={
1117 {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM_BASE(PC)}},
1118 {ARM_INS_ENDING}
1119 };
1120 if(!insn_match_find_next(fw,is,18,match_ldr_r0)) {
1121 return 0;
1122 }
1123 uint32_t tbl=LDR_PC2val(fw,is->insn);
1124 if(!tbl) {
1125 return 0;
1126 }
1127 if(!disasm_iter(fw,is)) {
1128 printf("sig_match_unreg_evp_table: disasm failed\n");
1129 return 0;
1130 }
1131 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1132 }
1133
1134
1135
1136 int sig_match_evp_table_veneer(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1137 {
1138 uint32_t ref_adr = get_saved_sig_val(rule->ref_name);
1139 int prevb = 0;
1140 uint32_t cadr;
1141
1142
1143 disasm_iter_init(fw,is,ref_adr);
1144 while (is->adr < (ref_adr+0x800)) {
1145 cadr = is->adr;
1146 if (!disasm_iter(fw,is)) {
1147 disasm_iter_set(fw,is,(is->adr+2) | fw->thumb_default);
1148 }
1149 else {
1150 if (is->insn->id == ARM_INS_B) {
1151 uint32_t b_adr = get_branch_call_insn_target(fw,is);
1152 if (prevb && (b_adr == ref_adr)) {
1153
1154 add_func_name(fw,rule->name,cadr | is->thumb,NULL);
1155 return 1;
1156 }
1157 prevb = 1;
1158 }
1159 }
1160 }
1161 return 0;
1162 }
1163
1164 int sig_match_get_nd_value(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1165 {
1166
1167 if(!get_misc_val_value("CAM_HAS_ND_FILTER") || !get_misc_val_value("CAM_HAS_IRIS_DIAPHRAGM")) {
1168 return 0;
1169 }
1170
1171 if(!init_disasm_sig_ref(fw,is,rule)) {
1172 return 0;
1173 }
1174 if(!find_next_sig_call(fw,is,16,"ClearEventFlag")) {
1175 printf("sig_match_get_nd_value: no match ClearEventFlag\n");
1176 return 0;
1177 }
1178 if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
1179 printf("sig_match_get_nd_value: bl match 1 failed\n");
1180 return 0;
1181 }
1182
1183 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
1184 disasm_iter(fw,is);
1185 if (B_target(fw,is->insn))
1186 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
1187
1188 if(!insn_match_find_next(fw,is,5,match_bl_blximm)) {
1189 printf("sig_match_get_nd_value: bl match 2 failed\n");
1190 return 0;
1191 }
1192 uint32_t addr=get_branch_call_insn_target(fw,is);
1193 if(addr == get_saved_sig_val("GetUsableAvRange")) {
1194 printf("sig_match_get_nd_value: found GetUsableAvRange, iris or ND only?\n");
1195 return 0;
1196 }
1197 return save_sig_with_j(fw,rule->name,addr);
1198 }
1199
1200 int sig_match_get_current_exp(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1201 {
1202 if(!init_disasm_sig_ref(fw,is,rule)) {
1203 return 0;
1204 }
1205 if(!insn_match_find_next(fw,is,2,match_bl_blximm)) {
1206 printf("sig_match_get_current_exp: bl match 1 failed\n");
1207 return 0;
1208 }
1209
1210 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
1211 if(!insn_match_find_next(fw,is,6,match_bl_blximm)) {
1212 printf("sig_match_get_current_exp: bl match 2 failed\n");
1213 return 0;
1214 }
1215
1216 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
1217 if(!insn_match_find_next(fw,is,6,match_bl_blximm)) {
1218 printf("sig_match_get_current_exp: bl match 3 failed\n");
1219 return 0;
1220 }
1221 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1222 }
1223
1224 int sig_match_get_current_nd_value(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1225 {
1226
1227 if(!get_misc_val_value("CAM_HAS_ND_FILTER") || !get_misc_val_value("CAM_HAS_IRIS_DIAPHRAGM")) {
1228 return 0;
1229 }
1230 if(!init_disasm_sig_ref(fw,is,rule)) {
1231 return 0;
1232 }
1233 if(!find_next_sig_call(fw,is,36,"GetCurrentShutterSpeed_FW")) {
1234 printf("sig_match_get_current_nd_value: no match GetCurrentShutterSpeed_FW\n");
1235 return 0;
1236 }
1237
1238
1239 const insn_match_t match_bl_strh[]={
1240 {MATCH_INS(BL,MATCH_OPCOUNT_IGNORE)},
1241 {MATCH_INS(STRH,2), {MATCH_OP_REG(R0), MATCH_OP_MEM(INVALID,INVALID,0x8)}},
1242 {ARM_INS_ENDING}
1243 };
1244 if(!insn_match_find_next_seq(fw,is,10,match_bl_strh)) {
1245 printf("sig_match_get_current_nd_value: match failed\n");
1246 return 0;
1247 }
1248
1249 disasm_iter_init(fw,is,adr_hist_get(&is->ah,1));
1250 disasm_iter(fw,is);
1251 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1252 }
1253
1254 int sig_match_imager_active_callback(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1255 {
1256 if(!init_disasm_sig_ref(fw,is,rule)) {
1257 return 0;
1258 }
1259 const insn_match_t match_ldr_bl_mov_pop[]={
1260 {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM_BASE(PC)}},
1261 {MATCH_INS(BL, MATCH_OPCOUNT_IGNORE)},
1262 {MATCH_INS(MOV,2), {MATCH_OP_REG(R0), MATCH_OP_IMM(0)}},
1263 {MATCH_INS(POP, MATCH_OPCOUNT_IGNORE)},
1264 {ARM_INS_ENDING}
1265 };
1266
1267 if(!insn_match_find_next_seq(fw,is,28,match_ldr_bl_mov_pop)) {
1268 printf("sig_match_imager_active_callback: match failed\n");
1269 return 0;
1270 }
1271
1272 disasm_iter_init(fw,is,adr_hist_get(&is->ah,3));
1273
1274 disasm_iter(fw,is);
1275 uint32_t f1=LDR_PC2val(fw,is->insn);
1276
1277
1278 return save_sig_with_j(fw,rule->name,f1);
1279 }
1280 int sig_match_imager_active(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1281 {
1282 if(!init_disasm_sig_ref(fw,is,rule)) {
1283 return 0;
1284 }
1285
1286 const insn_match_t match_ldr_mov_str_pop[]={
1287 {MATCH_INS(LDR, 2), {MATCH_OP_REG_ANY, MATCH_OP_MEM_BASE(PC)}},
1288 {MATCH_INS(MOV,2), {MATCH_OP_REG_ANY, MATCH_OP_IMM(1)}},
1289 {MATCH_INS(STR, 2), {MATCH_OP_REG_ANY, MATCH_OP_MEM_ANY}},
1290 {MATCH_INS(POP, MATCH_OPCOUNT_IGNORE)},
1291 {ARM_INS_ENDING}
1292 };
1293
1294 int backtrack=3;
1295 if(!insn_match_find_next_seq(fw,is,10,match_ldr_mov_str_pop)) {
1296
1297 init_disasm_sig_ref(fw,is,rule);
1298 const insn_match_t match_mov_ldr_str_pop[]={
1299 {MATCH_INS(MOV,2), {MATCH_OP_REG_ANY, MATCH_OP_IMM(1)}},
1300 {MATCH_INS(LDR, 2), {MATCH_OP_REG_ANY, MATCH_OP_MEM_BASE(PC)}},
1301 {MATCH_INS(STR, 2), {MATCH_OP_REG_ANY, MATCH_OP_MEM_ANY}},
1302 {MATCH_INS(POP, MATCH_OPCOUNT_IGNORE)},
1303 {ARM_INS_ENDING}
1304 };
1305 if(!insn_match_find_next_seq(fw,is,10,match_mov_ldr_str_pop)) {
1306 printf("sig_match_imager_active: match failed\n");
1307 return 0;
1308 }
1309 backtrack=2;
1310 }
1311
1312 disasm_iter_init(fw,is,adr_hist_get(&is->ah,backtrack));
1313 disasm_iter(fw,is);
1314 uint32_t base=LDR_PC2val(fw,is->insn);
1315 uint32_t reg=is->insn->detail->arm.operands[0].reg;
1316
1317
1318 if(backtrack == 3) {
1319 disasm_iter(fw,is);
1320 }
1321 disasm_iter(fw,is);
1322
1323 if(is->insn->detail->arm.operands[1].mem.base != reg) {
1324 printf("sig_match_imager_active: reg mismatch\n");
1325 return 0;
1326 }
1327 uint32_t off=is->insn->detail->arm.operands[1].mem.disp;
1328
1329 save_misc_val("imager_active",base,off,(uint32_t)is->insn->address);
1330 return 1;
1331 }
1332
1333 int sig_match_screenlock_helper(firmware *fw, iter_state_t *is, sig_rule_t *rule) {
1334 if(!init_disasm_sig_ref(fw,is,rule)) {
1335 return 0;
1336 }
1337 uint32_t init_adr = (uint32_t)is->adr | is->thumb;
1338
1339
1340 const insn_match_t match_cmp_bne_bl[]={
1341 {MATCH_INS(CMP, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM(0)}},
1342 {MATCH_INS_CC(B,NE,MATCH_OPCOUNT_IGNORE)},
1343 {MATCH_INS(BL,MATCH_OPCOUNT_IGNORE)},
1344 {ARM_INS_ENDING}
1345 };
1346 const insn_match_t match_ldrpc_mov_b[]={
1347 {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM_BASE(PC)}},
1348 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R1), MATCH_OP_IMM(0)}},
1349 {MATCH_INS_CC(B,AL,MATCH_OPCOUNT_IGNORE)},
1350 {ARM_INS_ENDING}
1351 };
1352
1353 if(insn_match_find_next_seq(fw,is,6,match_cmp_bne_bl)) {
1354 return save_sig_with_j(fw,rule->name,init_adr);
1355
1356 }
1357
1358
1359
1360 disasm_iter_init(fw,is,init_adr);
1361 if(!insn_match_find_next_seq(fw,is,1,match_ldrpc_mov_b)) {
1362 printf("sig_match_screenlock_helper: match 2 failed 0x%"PRIx64"\n",is->insn->address);
1363 return 0;
1364 }
1365 disasm_iter_init(fw,is,init_adr);
1366 disasm_iter(fw,is);
1367 uint32_t adr = LDR_PC2val(fw,is->insn);
1368 if(!adr) {
1369 printf("sig_match_screenlock_helper: no match LDR PC 0x%"PRIx64"\n",is->insn->address);
1370 return 0;
1371 }
1372 disasm_iter_init(fw,is,adr);
1373
1374 if(!insn_match_find_next_seq(fw,is,6,match_cmp_bne_bl)) {
1375 printf("sig_match_screenlock_helper: match failed 0x%8x\n",init_adr);
1376 return 0;
1377 }
1378 return save_sig_with_j(fw,rule->name,adr);
1379 }
1380
1381 int sig_match_screenunlock(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1382 {
1383 if(!init_disasm_sig_ref(fw,is,rule)) {
1384 return 0;
1385 }
1386
1387 if(!find_next_sig_call(fw,is,14,"ScreenLock")) {
1388
1389 return 0;
1390 }
1391
1392
1393 const insn_match_t match_end[]={
1394 {MATCH_INS(POP, MATCH_OPCOUNT_IGNORE)},
1395 {MATCH_INS_CC(B,AL,MATCH_OPCOUNT_IGNORE)},
1396 {ARM_INS_ENDING}
1397 };
1398 if(!insn_match_find_next_seq(fw,is,38,match_end)) {
1399
1400 return 0;
1401 }
1402
1403 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1404 }
1405
1406
1407 int sig_match_log_camera_event(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1408 {
1409 if(!init_disasm_sig_ref(fw,is,rule)) {
1410 return 0;
1411 }
1412 if(!insn_match_find_next(fw,is,6,match_bl_blximm)) {
1413
1414 return 0;
1415 }
1416 uint32_t regs[4];
1417 if((get_call_const_args(fw,is,4,regs)&3)!=3) {
1418
1419 return 0;
1420 }
1421 if(regs[0] != 0x60) {
1422
1423 return 0;
1424 }
1425 const char *str=(char *)adr2ptr(fw,regs[1]);
1426 if(!str || strcmp(str,"_SImage") != 0) {
1427
1428 return 0;
1429 }
1430 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1431 }
1432
1433
1434 int sig_match_physw_misc(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1435 {
1436 if(!init_disasm_sig_ref(fw,is,rule)) {
1437 osig* ostub2 = find_sig(fw->sv->stubs,rule->ref_name);
1438 if (ostub2 && ostub2->val)
1439 {
1440 disasm_iter_init(fw,is,ostub2->val);
1441 }
1442 else
1443 {
1444 return 0;
1445 }
1446 }
1447 int i;
1448 uint32_t physw_run=0;
1449 for(i=0; i<3; i++) {
1450 if(!disasm_iter(fw,is)) {
1451 printf("sig_match_physw_misc: disasm failed\n");
1452 return 0;
1453 }
1454 physw_run=LDR_PC2val(fw,is->insn);
1455 if(physw_run) {
1456 if(adr_is_var(fw,physw_run)) {
1457 save_misc_val("physw_run",physw_run,0,(uint32_t)is->insn->address);
1458 break;
1459 } else {
1460 printf("sig_match_physw_misc: adr not data? 0x%08x\n",physw_run);
1461 return 0;
1462 }
1463 }
1464 }
1465 if(!physw_run) {
1466 return 0;
1467 }
1468
1469
1470 if(!insn_match_find_next(fw,is,7,match_bl_blximm)) {
1471 return 0;
1472 }
1473 uint32_t sleeptask=get_saved_sig_val("SleepTask");
1474 if(!sleeptask) {
1475 printf("sig_match_physw_misc: missing SleepTask\n");
1476 return 0;
1477 }
1478 uint32_t f=get_branch_call_insn_target(fw,is);
1479
1480
1481 if(f != sleeptask) {
1482 fw_disasm_iter_single(fw,f);
1483 uint32_t f2=get_direct_jump_target(fw,fw->is);
1484 if(f2 != sleeptask) {
1485 return 0;
1486 }
1487
1488
1489 save_sig_with_j(fw,"SleepTask",f);
1490 }
1491
1492 disasm_iter_init(fw,is,adr_hist_get(&is->ah,1));
1493 if(!disasm_iter(fw,is)) {
1494 printf("sig_match_physw_misc: disasm failed\n");
1495 return 0;
1496 }
1497
1498 if(is->insn->id != ARM_INS_LDR
1499 || is->insn->detail->arm.operands[0].reg != ARM_REG_R0) {
1500 return 0;
1501 }
1502 save_misc_val("physw_sleep_delay",physw_run,is->insn->detail->arm.operands[1].mem.disp,(uint32_t)is->insn->address);
1503
1504 if(!disasm_iter(fw,is)) {
1505 printf("sig_match_physw_misc: disasm failed\n");
1506 return 0;
1507 }
1508
1509
1510 if(!insn_match_find_next(fw,is,2,match_bl_blximm)) {
1511 return 0;
1512 }
1513 save_sig(fw,"kbd_p1_f",get_branch_call_insn_target(fw,is));
1514
1515
1516 if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
1517 return 0;
1518 }
1519 save_sig(fw,"kbd_p2_f",get_branch_call_insn_target(fw,is));
1520 return 1;
1521 }
1522
1523 int sig_match_kbd_read_keys(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1524 {
1525 if(!init_disasm_sig_ref(fw,is,rule)) {
1526 return 0;
1527 }
1528
1529 if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
1530 return 0;
1531 }
1532 save_sig(fw,"kbd_read_keys",get_branch_call_insn_target(fw,is));
1533 if(!disasm_iter(fw,is)) {
1534 printf("sig_match_kbd_read_keys: disasm failed\n");
1535 return 0;
1536 }
1537 uint32_t physw_status=LDR_PC2val(fw,is->insn);
1538 if(physw_status) {
1539 save_misc_val("physw_status",physw_status,0,(uint32_t)is->insn->address);
1540 save_sig(fw,"kbd_p1_f_cont",(uint32_t)(is->insn->address) | is->thumb);
1541 return 1;
1542 }
1543 return 0;
1544 }
1545
1546
1547 int sig_match_get_kbd_state(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1548 {
1549 if(!init_disasm_sig_ref(fw,is,rule)) {
1550 return 0;
1551 }
1552
1553 insn_match_t match[]={
1554 {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM_BASE(PC)}},
1555 {MATCH_INS(BL, MATCH_OPCOUNT_IGNORE)},
1556 {ARM_INS_ENDING}
1557 };
1558
1559 if(!insn_match_find_next_seq(fw,is,11,match)) {
1560 return 0;
1561 }
1562 save_sig_with_j(fw,"GetKbdState",get_branch_call_insn_target(fw,is));
1563
1564 if(!insn_match_find_next(fw,is,5,match_b_bl_blximm)) {
1565 return 0;
1566 }
1567 save_sig_with_j(fw,"kbd_read_keys_r2",get_branch_call_insn_target(fw,is));
1568 return 1;
1569 }
1570
1571 int sig_match_get_dial_hw_position(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1572 {
1573 if(!init_disasm_sig_ref(fw,is,rule)) {
1574 return 0;
1575 }
1576 uint32_t adr = find_last_call_from_func(fw,is,18,50);
1577 if(!adr) {
1578
1579 return 0;
1580 }
1581
1582 disasm_iter_init(fw,is,adr);
1583 adr = find_last_call_from_func(fw,is,16,32);
1584 if(!adr) {
1585
1586 return 0;
1587 }
1588
1589 disasm_iter_init(fw,is,adr);
1590
1591 if(!insn_match_find_next(fw,is,30,match_bl_blximm)) {
1592
1593 return 0;
1594 }
1595 uint32_t fadr = get_branch_call_insn_target(fw,is);
1596
1597 disasm_iter_init(fw,is,adr_hist_get(&is->ah,4));
1598 const insn_match_t match_hw_dial_call[]={
1599 {MATCH_INS(ADD,MATCH_OPCOUNT_ANY), {MATCH_OP_REG(R0)}},
1600 {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0),MATCH_OP_MEM_BASE(PC)}},
1601 {MATCH_INS(BL,MATCH_OPCOUNT_IGNORE)},
1602 {ARM_INS_ENDING}
1603 };
1604 if(!insn_match_find_next(fw,is,4,match_hw_dial_call)) {
1605
1606 return 0;
1607 }
1608 return save_sig_with_j(fw,rule->name,fadr);
1609 }
1610
1611 int sig_match_create_jumptable(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1612 {
1613 if(!init_disasm_sig_ref(fw,is,rule)) {
1614 return 0;
1615 }
1616
1617 if(!insn_match_find_nth(fw,is,20,2,match_bl_blximm)) {
1618 return 0;
1619 }
1620
1621 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
1622 if(!insn_match_find_next(fw,is,15,match_bl_blximm)) {
1623 return 0;
1624 }
1625
1626 save_sig(fw,"CreateJumptable",get_branch_call_insn_target(fw,is));
1627 return 1;
1628 }
1629
1630
1631 int sig_match_take_semaphore_strict(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1632 {
1633 if(!init_disasm_sig_ref(fw,is,rule)) {
1634 return 0;
1635 }
1636
1637 if(!insn_match_find_next(fw,is,6,match_bl_blximm)) {
1638 return 0;
1639 }
1640
1641 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
1642
1643 if(!insn_match_find_nth(fw,is,10,2,match_bl_blximm)) {
1644 return 0;
1645 }
1646
1647 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
1648
1649 if(!insn_match_find_nth(fw,is,20,3,match_bl_blximm)) {
1650 return 0;
1651 }
1652 save_sig_with_j(fw,"DebugAssert",get_branch_call_insn_target(fw,is));
1653
1654
1655 if(!insn_match_find_next(fw,is,7,match_bl_blximm)) {
1656 return 0;
1657 }
1658 save_sig_with_j(fw,"TakeSemaphoreStrictly",get_branch_call_insn_target(fw,is));
1659 arm_reg ptr_reg = ARM_REG_INVALID;
1660 uint32_t sem_adr=0;
1661 int i;
1662
1663 for(i=1; i<7; i++) {
1664 fw_disasm_iter_single(fw,adr_hist_get(&is->ah,i));
1665 cs_insn *insn=fw->is->insn;
1666 if(insn->id != ARM_INS_LDR) {
1667 continue;
1668 }
1669 if(ptr_reg == ARM_REG_INVALID
1670 && insn->detail->arm.operands[0].reg == ARM_REG_R0
1671 && insn->detail->arm.operands[1].mem.base != ARM_REG_PC) {
1672 ptr_reg = insn->detail->arm.operands[1].mem.base;
1673 continue;
1674 }
1675 if(ptr_reg == ARM_REG_INVALID || !isLDR_PC(insn) || (arm_reg)insn->detail->arm.operands[0].reg != ptr_reg) {
1676 continue;
1677 }
1678 sem_adr=LDR_PC2val(fw,insn);
1679 if(sem_adr) {
1680 break;
1681 }
1682 }
1683 if(!sem_adr) {
1684 return 0;
1685 }
1686 save_misc_val("fileio_semaphore",sem_adr,0,(uint32_t)is->insn->address);
1687
1688 if(!insn_match_find_next(fw,is,10,match_bl_blximm)) {
1689 return 0;
1690 }
1691 return save_sig_with_j(fw,"GetDrive_FreeClusters",get_branch_call_insn_target(fw,is));
1692 }
1693
1694 int sig_match_get_semaphore_value(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1695 {
1696 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
1697 if(!str_adr) {
1698 printf("sig_get_semaphore_value: failed to find ref %s\n",rule->ref_name);
1699 return 0;
1700 }
1701
1702 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
1703
1704 if(!fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
1705
1706 return 0;
1707 }
1708
1709 uint32_t fadr=0;
1710 int i;
1711 for(i=1; i<=5; i++) {
1712 if(!fw_disasm_iter_single(fw,adr_hist_get(&is->ah,i))) {
1713
1714 return 0;
1715 }
1716 if(insn_match_any(fw->is->insn,match_bl_blximm)){
1717 fadr=get_branch_call_insn_target(fw,fw->is);
1718 break;
1719 }
1720 }
1721 if(!fadr) {
1722
1723 return 0;
1724 }
1725
1726 disasm_iter_init(fw,is,fadr);
1727
1728 if(!insn_match_find_next(fw,is,9,match_bl_blximm)) {
1729
1730 return 0;
1731 }
1732 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1733 }
1734
1735 int sig_match_stat(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1736 {
1737 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
1738 if(!str_adr) {
1739 printf("sig_match_stat: %s failed to find ref %s\n",rule->name,rule->ref_name);
1740 return 0;
1741 }
1742
1743
1744 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
1745 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
1746 if(is->insn->detail->arm.operands[0].reg == ARM_REG_R0) {
1747 if(insn_match_find_next(fw,is,2,match_bl_blximm)) {
1748 uint32_t adr=get_branch_call_insn_target(fw,is);
1749
1750 if(is_sig_call(fw,is,"Fopen_Fut_FW")) {
1751 continue;
1752 }
1753
1754 return save_sig_with_j(fw,rule->name,adr);
1755 }
1756 }
1757 }
1758 return 0;
1759 }
1760 static const insn_match_t match_open_mov_call[]={
1761
1762 {MATCH_INS(MOV, 2), {MATCH_OP_REG_ANY, MATCH_OP_REG_ANY}},
1763 {MATCH_INS(MOV, 2), {MATCH_OP_REG_ANY, MATCH_OP_REG_ANY}},
1764 {MATCH_INS(MOV, 2), {MATCH_OP_REG_ANY, MATCH_OP_REG_ANY}},
1765 {MATCH_INS(BL, MATCH_OPCOUNT_IGNORE)},
1766 {ARM_INS_ENDING}
1767 };
1768
1769
1770
1771 int sig_match_open(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1772 {
1773 if(!init_disasm_sig_ref(fw,is,rule)) {
1774 return 0;
1775 }
1776 if(!insn_match_find_next_seq(fw,is,48,match_open_mov_call)) {
1777 return 0;
1778 }
1779 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1780 }
1781
1782
1783 int sig_match_open_gt_57(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1784 {
1785 if(!init_disasm_sig_ref(fw,is,rule)) {
1786 return 0;
1787 }
1788 if(!find_next_sig_call(fw,is,38,"TakeSemaphoreStrictly")) {
1789 return 0;
1790 }
1791
1792
1793 if(!insn_match_find_next(fw,is,5,match_bl_blximm)) {
1794 return 0;
1795 }
1796
1797 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
1798
1799 if(!insn_match_find_next_seq(fw,is,48,match_open_mov_call)) {
1800 return 0;
1801 }
1802 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1803 }
1804
1805
1806
1807 int sig_match_close_gt_57(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1808 {
1809 if(!init_disasm_sig_ref(fw,is,rule)) {
1810 return 0;
1811 }
1812 if(!find_next_sig_call(fw,is,34,"TakeSemaphoreStrictly")) {
1813 return 0;
1814 }
1815
1816
1817 if(!insn_match_find_next(fw,is,3,match_bl_blximm)) {
1818 return 0;
1819 }
1820
1821 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
1822
1823 if(!insn_match_find_next(fw,is,3,match_bl_blximm)) {
1824 return 0;
1825 }
1826 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1827 }
1828
1829
1830
1831 int sig_match_umalloc(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1832 {
1833 if(!init_disasm_sig_ref(fw,is,rule)) {
1834 return 0;
1835 }
1836
1837 if(!insn_match_find_nth(fw,is,15,3,match_bl_blximm)) {
1838 return 0;
1839 }
1840
1841 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
1842
1843 if(!insn_match_find_nth(fw,is,14,3,match_bl_blximm)) {
1844 return 0;
1845 }
1846 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1847 }
1848
1849
1850 int sig_match_ufree(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1851 {
1852 if(!init_disasm_sig_ref(fw,is,rule)) {
1853 return 0;
1854 }
1855
1856 if(!find_next_sig_call(fw,is,60,"strcpy_FW")) {
1857 return 0;
1858 }
1859
1860 if(!insn_match_find_nth(fw,is,12,3,match_bl_blximm)) {
1861 return 0;
1862 }
1863
1864 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
1865
1866 if(!find_next_sig_call(fw,is,40,"Close_FW")) {
1867 return 0;
1868 }
1869
1870 if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
1871 return 0;
1872 }
1873 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1874 }
1875
1876 int sig_match_deletefile_fut(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1877 {
1878 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
1879 if(!str_adr) {
1880 printf("sig_match_deletefile_fut: %s failed to find ref %s\n",rule->name,rule->ref_name);
1881 return 0;
1882 }
1883
1884 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
1885 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
1886
1887 if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
1888 continue;
1889 }
1890
1891 uint32_t adr=get_branch_call_insn_target(fw,is);
1892 if(!fw_disasm_iter_single(fw,adr)) {
1893 printf("sig_match_deletefile_fut: disasm failed\n");
1894 return 0;
1895 }
1896 const insn_match_t match_mov_r1[]={
1897 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R1), MATCH_OP_IMM_ANY}},
1898 #if CS_API_MAJOR < 4
1899 {MATCH_INS(MOVS, 2), {MATCH_OP_REG(R1), MATCH_OP_IMM_ANY}},
1900 #endif
1901 {ARM_INS_ENDING}
1902 };
1903
1904 if(!insn_match_any(fw->is->insn,match_mov_r1)){
1905 continue;
1906 }
1907 return save_sig_with_j(fw,rule->name,adr);
1908 }
1909 return 0;
1910 }
1911
1912 uint32_t find_call_near_str(firmware *fw, iter_state_t *is, sig_rule_t *rule);
1913
1914 int sig_match_closedir(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1915 {
1916 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
1917 if(!str_adr) {
1918 printf("sig_match_closedir: %s failed to find ref %s\n",rule->name,rule->ref_name);
1919 return 0;
1920 }
1921
1922 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
1923 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
1924 if(!find_next_sig_call(fw,is,60,"sprintf_FW")) {
1925 continue;
1926 }
1927 if(insn_match_find_nth(fw,is,7,2,match_bl_blximm)) {
1928 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1929 }
1930 }
1931
1932 uint32_t call_adr = find_call_near_str(fw,is,rule);
1933 if(call_adr) {
1934 disasm_iter_init(fw,is,call_adr);
1935 const insn_match_t match_closedir[]={
1936 {MATCH_INS(BL,MATCH_OPCOUNT_IGNORE)},
1937 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R0), MATCH_OP_REG_ANY}},
1938 {MATCH_INS(BL,MATCH_OPCOUNT_IGNORE)},
1939 {ARM_INS_ENDING}
1940 };
1941 if(insn_match_seq(fw,is,match_closedir)){
1942 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1943 }
1944 }
1945
1946 return 0;
1947 }
1948
1949
1950 int save_sig_match_call(firmware* fw, sig_rule_t *rule, uint32_t call_adr)
1951 {
1952 disasm_iter_init(fw,fw->is,call_adr);
1953 disasm_iter(fw,fw->is);
1954 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,fw->is));
1955 }
1956
1957 int sig_match_readfastdir(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1958 {
1959 uint32_t str_adr;
1960 str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
1961 if(!str_adr) {
1962 printf("sig_match_readfastdir: %s failed to find ref %s\n",rule->name,rule->ref_name);
1963 return 0;
1964 }
1965 const insn_match_t match_cbnz_r0[]={
1966 {MATCH_INS(CBNZ, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM_ANY}},
1967 {ARM_INS_ENDING}
1968 };
1969 const insn_match_t match_cbz_r0[]={
1970 {MATCH_INS(CBZ, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM_ANY}},
1971 {ARM_INS_ENDING}
1972 };
1973 int max_insns=rule->param&SIG_NEAR_OFFSET_MASK;
1974 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
1975 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
1976 uint32_t ref_adr = iter_state_adr(is);
1977
1978 fw_disasm_iter_single(fw,adr_hist_get(&is->ah,2));
1979 if(insn_match_any(fw->is->insn,match_bl_blximm)) {
1980 uint32_t call_adr = iter_state_adr(fw->is);
1981 fw_disasm_iter_single(fw,adr_hist_get(&is->ah,1));
1982 if(insn_match_any(fw->is->insn,match_cbnz_r0)) {
1983 return save_sig_match_call(fw, rule, call_adr);
1984 }
1985 }
1986 int i;
1987 for(i=3; i<=max_insns; i++) {
1988
1989 fw_disasm_iter_single(fw,adr_hist_get(&is->ah,i));
1990 if(insn_match_any(fw->is->insn,match_bl_blximm)) {
1991 uint32_t call_adr = iter_state_adr(fw->is);
1992 fw_disasm_iter_single(fw,adr_hist_get(&is->ah,i-1));
1993 if(insn_match_any(fw->is->insn,match_cbz_r0)) {
1994 uint32_t b_adr = get_branch_call_insn_target(fw,fw->is);
1995 if (ref_adr == b_adr) {
1996 return save_sig_match_call(fw, rule, call_adr);
1997 }
1998 }
1999 }
2000 }
2001 }
2002 printf("sig_match_readfastdir: no match %s\n",rule->name);
2003 return 0;
2004 }
2005
2006 int sig_match_strrchr(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2007 {
2008 uint32_t sig_adr=get_saved_sig_val(rule->name);
2009 if (sig_adr == 0)
2010 {
2011 uint32_t call_adr = find_call_near_str(fw,is,rule);
2012 if(call_adr) {
2013 disasm_iter_init(fw,is,call_adr-4);
2014 const insn_match_t match_mov_r1_imm[]={
2015 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R1), MATCH_OP_IMM_ANY}},
2016 {ARM_INS_ENDING}
2017 };
2018 if(insn_match_find_next(fw,is,2,match_mov_r1_imm)){
2019 return save_sig_match_call(fw, rule, call_adr);
2020 }
2021 }
2022 }
2023 return 0;
2024 }
2025
2026 int sig_match_time(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2027 {
2028 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2029 if(!str_adr) {
2030 printf("sig_match_time: %s failed to find ref %s\n",rule->name,rule->ref_name);
2031 return 0;
2032 }
2033 uint32_t fadr=0;
2034
2035 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
2036 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2037
2038 if(insn_match_find_nth(fw,is,6,2,match_bl_blximm)) {
2039 fadr=get_branch_call_insn_target(fw,is);
2040 break;
2041 }
2042 }
2043 if(!fadr) {
2044 return 0;
2045 }
2046
2047 disasm_iter_init(fw,is,fadr);
2048
2049 if(insn_match_find_nth(fw,is,11,2,match_bl_blximm)) {
2050 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2051 }
2052 return 0;
2053 }
2054
2055 int sig_match_strncpy(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2056 {
2057 if(!init_disasm_sig_ref(fw,is,rule)) {
2058 return 0;
2059 }
2060 if(!find_next_sig_call(fw,is,60,"strcpy_FW")) {
2061 return 0;
2062 }
2063 if(!insn_match_find_next(fw,is,6,match_bl_blximm)) {
2064 return 0;
2065 }
2066 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2067 }
2068
2069 int sig_match_strncmp(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2070 {
2071 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2072 if(!str_adr) {
2073 printf("sig_match_strncmp: failed to find ref %s\n",rule->ref_name);
2074 return 0;
2075 }
2076
2077 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
2078 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2079 if(!insn_match_find_next(fw,is,3,match_bl_blximm)) {
2080 continue;
2081 }
2082 uint32_t regs[4];
2083 if((get_call_const_args(fw,is,4,regs)&6)==6) {
2084
2085 if(regs[1]==str_adr && regs[2] == strlen(rule->ref_name)) {
2086 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2087 }
2088 }
2089 }
2090 return 0;
2091 }
2092
2093 int sig_match_strtolx(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2094 {
2095 if(!init_disasm_sig_ref(fw,is,rule)) {
2096 return 0;
2097 }
2098 if(!find_next_sig_call(fw,is,130,"strncpy")) {
2099 return 0;
2100 }
2101
2102 if(!insn_match_find_next(fw,is,6,match_bl_blximm)) {
2103 return 0;
2104 }
2105 uint32_t adr=get_branch_call_insn_target(fw,is);
2106 if(!adr) {
2107 return 0;
2108 }
2109
2110 disasm_iter_init(fw,is,adr);
2111 if(!disasm_iter(fw,is)) {
2112 printf("sig_match_strtolx: disasm failed\n");
2113 return 0;
2114 }
2115
2116
2117
2118 const insn_match_t match_mov_r3_imm[]={
2119 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R3), MATCH_OP_IMM_ANY}},
2120 {ARM_INS_ENDING}
2121 };
2122 if(!insn_match(is->insn,match_mov_r3_imm)){
2123 return 0;
2124 }
2125 if(!disasm_iter(fw,is)) {
2126 printf("sig_match_strtolx: disasm failed\n");
2127 return 0;
2128 }
2129 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2130 }
2131
2132
2133 int sig_match_exec_evp(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2134 {
2135 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2136 if(!str_adr) {
2137 printf("sig_match_exec_evp: failed to find ref %s\n",rule->ref_name);
2138 return 0;
2139 }
2140
2141 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
2142 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2143
2144 int i;
2145 for(i=1; i<=18; i++) {
2146 if(!fw_disasm_iter_single(fw,adr_hist_get(&is->ah,i))) {
2147 break;
2148 }
2149 if(fw->is->insn->id == ARM_INS_PUSH && fw->is->insn->detail->arm.operands[0].reg == ARM_REG_R0) {
2150
2151 uint32_t adr=(uint32_t)(fw->is->insn->address) | is->thumb;
2152
2153 if(find_next_sig_call(fw,is,28,"DebugAssert")) {
2154 break;
2155 }
2156 return save_sig_with_j(fw,rule->name,adr);
2157 }
2158 }
2159 }
2160 return 0;
2161 }
2162
2163 int sig_match_fgets_fut(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2164 {
2165 if(!init_disasm_sig_ref(fw,is,rule)) {
2166 return 0;
2167 }
2168 if(!find_next_sig_call(fw,is,16,"Fopen_Fut_FW")) {
2169 return 0;
2170 }
2171 disasm_iter(fw,is);
2172 disasm_iter(fw,is);
2173 if (B_target(fw,is->insn) && (is->insn->detail->arm.cc == ARM_CC_NE)) {
2174 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
2175 } else {
2176 if (B_target(fw,is->insn) && (is->insn->detail->arm.cc == ARM_CC_NE)) {
2177 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
2178 }
2179 }
2180 if(!insn_match_find_nth(fw,is,20,1,match_bl_blximm)) {
2181 return 0;
2182 }
2183 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2184 }
2185
2186 int sig_match_log(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2187 {
2188 if(!init_disasm_sig_ref(fw,is,rule)) {
2189 return 0;
2190 }
2191 const insn_match_t match_pop6[]={
2192 {MATCH_INS(POP, 6), {MATCH_OP_REST_ANY}},
2193 {ARM_INS_ENDING}
2194 };
2195
2196 if(!insn_match_find_nth(fw,is,38,3,match_pop6)) {
2197 return 0;
2198 }
2199
2200 if(!insn_match_find_nth(fw,is,24,3,match_bl_blximm)) {
2201 return 0;
2202 }
2203 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2204 }
2205
2206
2207 int sig_match_pow_dry_52(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2208 {
2209 if (fw->dryos_ver != 52) {
2210 return 0;
2211 }
2212 if(!init_disasm_sig_ref(fw,is,rule)) {
2213 return 0;
2214 }
2215 const insn_match_t match_ldrd_r0_r1[]={
2216 {MATCH_INS(LDRD, 3), {MATCH_OP_REG(R0), MATCH_OP_REG(R1), MATCH_OP_ANY}},
2217 {ARM_INS_ENDING}
2218 };
2219
2220 if(!insn_match_find_next(fw,is,50,match_ldrd_r0_r1)) {
2221 return 0;
2222 }
2223
2224 if(is->insn->detail->arm.operands[2].mem.base == ARM_REG_SP) {
2225 return 0;
2226 }
2227 if(!disasm_iter(fw,is)) {
2228 printf("sig_match_pow: disasm failed\n");
2229 return 0;
2230 }
2231 uint32_t adr=get_branch_call_insn_target(fw,is);
2232 if(!adr) {
2233 return 0;
2234 }
2235 return save_sig_with_j(fw,rule->name,adr);
2236 }
2237
2238
2239 int sig_match_pow_dry_gt_52(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2240 {
2241 if (fw->dryos_ver <= 52) {
2242 return 0;
2243 }
2244 if(!init_disasm_sig_ref(fw,is,rule)) {
2245 return 0;
2246 }
2247 const insn_match_t match1a[]={
2248 {MATCH_INS(LDRSH, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM(SP,INVALID,0x12)}},
2249 {MATCH_INS(LDRD, 3), {MATCH_OP_REG(R2), MATCH_OP_REG(R3), MATCH_OP_MEM(SP,INVALID,0x20)}},
2250 {MATCH_INS(STR, 2), {MATCH_OP_REG_ANY, MATCH_OP_MEM(SP,INVALID,0)}},
2251 {MATCH_INS(BL, MATCH_OPCOUNT_IGNORE)},
2252 {ARM_INS_ENDING}
2253 };
2254 const insn_match_t match1b[]={
2255 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R2), MATCH_OP_REG(R7)}},
2256 {MATCH_INS(LDRSH, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM(SP,INVALID,0x12)}},
2257 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R3), MATCH_OP_REG(R6)}},
2258 {MATCH_INS(STR, 2), {MATCH_OP_REG_ANY, MATCH_OP_MEM(SP,INVALID,0)}},
2259 {MATCH_INS(BL, MATCH_OPCOUNT_IGNORE)},
2260 {ARM_INS_ENDING}
2261 };
2262 const insn_match_t* match1[]={ match1a, match1b };
2263 int idx;
2264 for (idx = 0; idx < 2; idx += 1)
2265 {
2266
2267 if(insn_match_find_next_seq(fw,is,50,match1[idx]))
2268 break;
2269 init_disasm_sig_ref(fw,is,rule);
2270 }
2271
2272 if (idx >= 2)
2273 return 0;
2274
2275 uint32_t adr=get_branch_call_insn_target(fw,is);
2276 if(!adr) {
2277 return 0;
2278 }
2279
2280 disasm_iter_init(fw,is,adr);
2281 const insn_match_t match2a[]={
2282 {MATCH_INS(LDRD,3), {MATCH_OP_REG(R0), MATCH_OP_REG(R1), MATCH_OP_MEM_ANY}},
2283 {MATCH_INS(BLX, 1), {MATCH_OP_IMM_ANY}},
2284 {ARM_INS_ENDING}
2285 };
2286 const insn_match_t match2b[]={
2287 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R2), MATCH_OP_REG(R0)}},
2288 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R3), MATCH_OP_REG(R1)}},
2289 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R4), MATCH_OP_IMM(0x40000000)}},
2290 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM(0)}},
2291 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R1), MATCH_OP_REG(R4)}},
2292 {MATCH_INS(BL, 1), {MATCH_OP_IMM_ANY}},
2293 {ARM_INS_ENDING}
2294 };
2295 const insn_match_t* match2[]={ match2a, match2b };
2296
2297 if(!insn_match_find_next_seq(fw,is,15,match2[idx])) {
2298 return 0;
2299 }
2300 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2301 }
2302
2303 int sig_match_sqrt(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2304 {
2305 if(!init_disasm_sig_ref(fw,is,rule)) {
2306 return 0;
2307 }
2308
2309 if(!insn_match_find_nth(fw,is,12,3,match_bl_blximm)) {
2310 return 0;
2311 }
2312
2313 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
2314 if(!disasm_iter(fw,is)) {
2315 printf("sig_match_sqrt: disasm failed\n");
2316 return 0;
2317 }
2318 uint32_t j_tgt=get_direct_jump_target(fw,is);
2319
2320 if(j_tgt) {
2321
2322 disasm_iter_init(fw,is,j_tgt);
2323 if(!disasm_iter(fw,is)) {
2324 printf("sig_match_sqrt: disasm failed\n");
2325 return 0;
2326 }
2327 }
2328
2329 if(!insn_match_find_nth(fw,is,12,2,match_b_bl_blximm)) {
2330 return 0;
2331 }
2332 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2333 }
2334 int sig_match_get_drive_cluster_size(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2335 {
2336 if(!init_disasm_sig_ref(fw,is,rule)) {
2337 return 0;
2338 }
2339
2340 if(fw_search_insn(fw,is,search_disasm_str_ref,0,"A/OpLogErr.txt",(uint32_t)is->adr+260)) {
2341
2342 if(!insn_match_find_next(fw,is,3,match_bl_blximm)) {
2343
2344 return 0;
2345 }
2346
2347 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
2348
2349 if(!insn_match_find_nth(fw,is,13,2,match_bl_blximm)) {
2350
2351 return 0;
2352 }
2353
2354 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
2355 disasm_iter(fw,is);
2356 if (B_target(fw, is->insn))
2357 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
2358
2359 if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
2360
2361 return 0;
2362 }
2363 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2364 }
2365 return 0;
2366 }
2367
2368 int sig_match_mktime_ext(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2369 {
2370 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2371 if(!str_adr) {
2372 printf("sig_match_mktime_ext: failed to find ref %s\n",rule->ref_name);
2373 return 0;
2374 }
2375
2376 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
2377 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2378
2379 if(!find_next_sig_call(fw,is,12,"sscanf_FW")) {
2380
2381 return 0;
2382 }
2383
2384 if(!insn_match_find_next(fw,is,22,match_bl_blximm)) {
2385
2386 return 0;
2387 }
2388
2389 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
2390 if(!disasm_iter(fw,is)) {
2391 printf("sig_match_mktime_ext: disasm failed\n");
2392 return 0;
2393 }
2394 uint32_t j_tgt=get_direct_jump_target(fw,is);
2395
2396 if(j_tgt) {
2397
2398 disasm_iter_init(fw,is,j_tgt);
2399 if(!disasm_iter(fw,is)) {
2400 printf("sig_match_mktime_ext: disasm failed\n");
2401 return 0;
2402 }
2403 }
2404 const insn_match_t match_pop4[]={
2405 {MATCH_INS(POP, 4), {MATCH_OP_REST_ANY}},
2406 {MATCH_INS(POP, 6), {MATCH_OP_REST_ANY}},
2407 {ARM_INS_ENDING}
2408 };
2409
2410
2411 if(!insn_match_find_next(fw,is,54,match_pop4)) {
2412
2413 return 0;
2414 }
2415 if(!insn_match_find_next(fw,is,1,match_b)) {
2416
2417 return 0;
2418 }
2419 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2420 }
2421 return 0;
2422 }
2423
2424
2425 int sig_match_rec2pb(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2426 {
2427 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2428 if(!str_adr) {
2429 printf("sig_match_mktime_ext: failed to find ref %s\n",rule->ref_name);
2430 return 0;
2431 }
2432
2433 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
2434 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2435 const insn_match_t match_ldr_cbnz_r0[]={
2436 {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM_ANY}},
2437 {MATCH_INS(CBNZ, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM_ANY}},
2438 {ARM_INS_ENDING}
2439 };
2440 if(!insn_match_find_next_seq(fw,is,10,match_ldr_cbnz_r0)) {
2441
2442 continue;
2443 }
2444
2445 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
2446 if(!insn_match_find_next(fw,is,3,match_b_bl_blximm)) {
2447
2448
2449 return 0;
2450 }
2451 uint32_t adr = iter_state_adr(is);
2452
2453 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
2454 if(!find_next_sig_call(fw,is,16,"LogCameraEvent")) {
2455
2456 return 0;
2457 }
2458 uint32_t regs[4];
2459 if((get_call_const_args(fw,is,4,regs)&3)!=3) {
2460
2461 return 0;
2462 }
2463
2464 if(regs[0]==0x60 && adr2ptr(fw,regs[1]) && (strcmp((const char *)adr2ptr(fw,regs[1]),"AC:Rec2PB")==0)) {
2465 return save_sig_with_j(fw,rule->name,adr);
2466 } else {
2467
2468 return 0;
2469 }
2470 }
2471 return 0;
2472 }
2473
2474
2475 int sig_match_get_parameter_data(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2476 {
2477 if(!init_disasm_sig_ref(fw,is,rule)) {
2478 return 0;
2479 }
2480 const insn_match_t match_cmp_bhs[]={
2481 {MATCH_INS(CMP, 2), {MATCH_OP_REG_ANY, MATCH_OP_IMM_ANY}},
2482 {MATCH_INS_CC(B,HS,MATCH_OPCOUNT_IGNORE)},
2483 {ARM_INS_ENDING}
2484 };
2485 if(!insn_match_find_next_seq(fw,is,4,match_cmp_bhs)) {
2486
2487 return 0;
2488 }
2489
2490 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
2491 if(!insn_match_find_next(fw,is,1,match_b)) {
2492
2493 return 0;
2494 }
2495 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2496 }
2497
2498
2499
2500
2501 int sig_match_prepdir_x(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2502 {
2503 if(!init_disasm_sig_ref(fw,is,rule)) {
2504 return 0;
2505 }
2506 const insn_match_t match_mov_r1_1[]={
2507 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R1), MATCH_OP_IMM(1)}},
2508 #if CS_API_MAJOR < 4
2509 {MATCH_INS(MOVS, 2), {MATCH_OP_REG(R1), MATCH_OP_IMM(1)}},
2510 #endif
2511 {ARM_INS_ENDING}
2512 };
2513 if(!insn_match_find_next(fw,is,1,match_mov_r1_1)) {
2514
2515 return 0;
2516 }
2517 if(!insn_match_find_next(fw,is,1,match_b)) {
2518
2519 return 0;
2520 }
2521 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2522 }
2523
2524
2525
2526
2527 int sig_match_prepdir_1(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2528 {
2529 uint32_t call_adr = find_call_near_str(fw,is,rule);
2530 if(call_adr) {
2531 disasm_iter_init(fw,is,call_adr);
2532 disasm_iter(fw,is);
2533 disasm_iter(fw,is);
2534 if (!CBx_target(fw,is->insn))
2535 {
2536 rule->param = SIG_NEAR_BEFORE(20,5);
2537 call_adr = find_call_near_str(fw,is,rule);
2538 if(!call_adr) {
2539 return 0;
2540 }
2541 disasm_iter_init(fw,is,call_adr);
2542 disasm_iter(fw,is);
2543 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2544 }
2545 }
2546
2547 rule->param = SIG_NEAR_BEFORE(7,2);
2548 call_adr = find_call_near_str(fw,is,rule);
2549 if(!call_adr) {
2550 return 0;
2551 }
2552 return save_sig_match_call(fw, rule, call_adr);
2553 }
2554
2555 int sig_match_prepdir_0(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2556 {
2557 if(!init_disasm_sig_ref(fw,is,rule)) {
2558 return 0;
2559 }
2560 uint32_t ref_pdx=get_saved_sig_val("PrepareDirectory_x");
2561 if(!ref_pdx) {
2562 printf("sig_match_prepdir_0: missing PrepareDirectory_x\n");
2563 return 0;
2564 }
2565
2566 disasm_iter(fw,is);
2567 disasm_iter(fw,is);
2568
2569 uint32_t adr=(uint32_t)is->adr|is->thumb;
2570 const insn_match_t match_mov_r1_1[]={
2571 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R1), MATCH_OP_IMM(0)}},
2572 #if CS_API_MAJOR < 4
2573 {MATCH_INS(MOVS, 2), {MATCH_OP_REG(R1), MATCH_OP_IMM(0)}},
2574 #endif
2575 {ARM_INS_ENDING}
2576 };
2577 if(!insn_match_find_next(fw,is,1,match_mov_r1_1)) {
2578
2579 return 0;
2580 }
2581 if(!insn_match_find_next(fw,is,1,match_b)) {
2582
2583 return 0;
2584 }
2585 uint32_t pdx=get_branch_call_insn_target(fw,is);
2586 if(pdx != ref_pdx) {
2587
2588 return 0;
2589 }
2590 return save_sig_with_j(fw,rule->name,adr);
2591 }
2592 int sig_match_mkdir(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2593 {
2594 if(!init_disasm_sig_ref(fw,is,rule)) {
2595 return 0;
2596 }
2597 const insn_match_t match[]={
2598 {MATCH_INS(STRB,2), {MATCH_OP_REG_ANY, MATCH_OP_MEM_ANY}},
2599 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R0), MATCH_OP_REG(SP)}},
2600 {MATCH_INS(LDR, 2), {MATCH_OP_REG(R1), MATCH_OP_MEM_BASE(SP)}},
2601 {MATCH_INS(BL, MATCH_OPCOUNT_IGNORE)},
2602 {ARM_INS_ENDING}
2603 };
2604 if(insn_match_find_next_seq(fw,is,148,match)) {
2605 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2606 }
2607
2608 init_disasm_sig_ref(fw,is,rule);
2609 const insn_match_t match2[]={
2610 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R1), MATCH_OP_REG_ANY}},
2611 {MATCH_INS(STRB,2), {MATCH_OP_REG_ANY, MATCH_OP_MEM_ANY}},
2612 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R0), MATCH_OP_REG(SP)}},
2613 {MATCH_INS(BL, MATCH_OPCOUNT_IGNORE)},
2614 {ARM_INS_ENDING}
2615 };
2616 if(!insn_match_find_next_seq(fw,is,148,match2)) {
2617
2618 return 0;
2619 }
2620 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2621 }
2622
2623 int sig_match_add_ptp_handler(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2624 {
2625 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2626 if(!str_adr) {
2627 printf("sig_match_add_ptp_handler: failed to find ref %s\n",rule->ref_name);
2628 return 0;
2629 }
2630
2631 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
2632 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2633
2634 if(!find_next_sig_call(fw,is,8,"CreateTaskStrictly")) {
2635
2636 continue;
2637 }
2638
2639 if(!insn_match_find_nth(fw,is,13,3,match_bl_blximm)) {
2640
2641 return 0;
2642 }
2643
2644 uint32_t regs[4];
2645 if((get_call_const_args(fw,is,5,regs)&7)!=7) {
2646
2647 return 0;
2648 }
2649 if(regs[0] < 0x9000 || regs[0] > 0x10000 || !adr2ptr(fw,regs[1]) || regs[2] != 0) {
2650
2651 return 0;
2652 }
2653 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2654 }
2655 return 0;
2656 }
2657 int sig_match_qsort(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2658 {
2659 if(!init_disasm_sig_ref(fw,is,rule)) {
2660 return 0;
2661 }
2662 if(!find_next_sig_call(fw,is,90,"DebugAssert")) {
2663
2664 return 0;
2665 }
2666 if(!insn_match_find_nth(fw,is,38,3,match_bl_blximm)) {
2667
2668 return 0;
2669 }
2670
2671 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
2672
2673 if(insn_match_find_next(fw,is,4,match_bl_blximm)) {
2674 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
2675 }
2676 if(!insn_match_find_next(fw,is,14,match_bl_blximm)) {
2677
2678 return 0;
2679 }
2680
2681 uint32_t regs[4];
2682 if((get_call_const_args(fw,is,5,regs)&0xe)!=0xe) {
2683
2684 return 0;
2685 }
2686 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2687 }
2688
2689
2690
2691
2692
2693
2694
2695
2696 int sig_match_deletedirectory_fut(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2697 {
2698 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2699 if(!str_adr) {
2700 printf("sig_match_deletedirectory_fut: failed to find ref %s\n",rule->ref_name);
2701 return 0;
2702 }
2703
2704
2705 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - 2048) | fw->thumb_default);
2706 uint32_t end_adr = ADR_ALIGN4(str_adr) + 2048;
2707 while(find_next_sig_call(fw,is,end_adr - (uint32_t)is->adr,"DeleteFile_Fut")) {
2708 if(!insn_match_find_next(fw,is,6,match_bl_blximm)) {
2709
2710 continue;
2711 }
2712 if(!is_sig_call(fw,is,"strcpy")) {
2713
2714 continue;
2715 }
2716 if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
2717
2718 continue;
2719 }
2720 if(!is_sig_call(fw,is,"strrchr")) {
2721
2722 continue;
2723 }
2724
2725 uint32_t regs[4];
2726 if((get_call_const_args(fw,is,2,regs)&0x2)!=0x2) {
2727
2728 continue;
2729 }
2730 if(regs[1] != '/') {
2731
2732 continue;
2733 }
2734 if(!insn_match_find_next(fw,is,5,match_bl_blximm)) {
2735
2736 continue;
2737 }
2738 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2739 }
2740 return 0;
2741 }
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752 int sig_match_set_control_event(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2753 {
2754 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2755 if(!str_adr) {
2756
2757
2758 return 0;
2759 }
2760 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
2761 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2762 if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
2763
2764 continue;
2765 }
2766 if(!is_sig_call(fw,is,"LogCameraEvent")) {
2767
2768 continue;
2769 }
2770 const insn_match_t match_seq[]={
2771 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R0), MATCH_OP_REG_ANY,}},
2772 {MATCH_INS(BL, MATCH_OPCOUNT_IGNORE)},
2773 {MATCH_INS(BL, MATCH_OPCOUNT_IGNORE)},
2774 {ARM_INS_ENDING}
2775 };
2776 if(!insn_match_find_next_seq(fw,is,1,match_seq)) {
2777
2778 continue;
2779 }
2780 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2781 }
2782 return 0;
2783 }
2784
2785 int sig_match_displaybusyonscreen_52(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2786 {
2787 if (fw->dryos_ver != 52) {
2788 return 0;
2789 }
2790 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2791 if(!str_adr) {
2792 printf("sig_match_displaybusyonscreen: failed to find ref %s\n",rule->ref_name);
2793 return 0;
2794 }
2795 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
2796 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2797 if(!insn_match_find_next(fw,is,3,match_bl_blximm)) {
2798
2799 continue;
2800 }
2801 if(!is_sig_call(fw,is,"LogCameraEvent")) {
2802
2803 continue;
2804 }
2805 if(!find_next_sig_call(fw,is,4,"GUISrv_StartGUISystem_FW")) {
2806
2807 continue;
2808 }
2809 if(!insn_match_find_nth(fw,is,5,2,match_bl_blximm)) {
2810
2811 continue;
2812 }
2813 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2814 }
2815 return 0;
2816 }
2817
2818 int sig_match_undisplaybusyonscreen_52(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2819 {
2820 if (fw->dryos_ver != 52) {
2821 return 0;
2822 }
2823 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2824 if(!str_adr) {
2825 printf("sig_match_undisplaybusyonscreen: failed to find ref %s\n",rule->ref_name);
2826 return 0;
2827 }
2828 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
2829 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2830
2831 if(!find_next_sig_call(fw,is,24,"displaybusyonscreen")) {
2832
2833 continue;
2834 }
2835 if(!find_next_sig_call(fw,is,12,"GUISrv_StartGUISystem_FW")) {
2836
2837 continue;
2838 }
2839 if(!insn_match_find_nth(fw,is,6,3,match_bl_blximm)) {
2840
2841 continue;
2842 }
2843 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2844 }
2845 return 0;
2846 }
2847
2848 int sig_match_try_take_sem_dry_gt_58(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2849 {
2850 if(!init_disasm_sig_ref(fw,is,rule)) {
2851 return 0;
2852 }
2853 if(!find_next_sig_call(fw,is,24,"ReceiveMessageQueue")) {
2854 printf("sig_match_try_take_sem_dry_gt_58: failed to find ReceiveMessageQueue\n");
2855 return 0;
2856 }
2857 if(!find_next_sig_call(fw,is,60,"bzero")) {
2858 printf("sig_match_try_take_sem_dry_gt_58: failed to find bzero\n");
2859 return 0;
2860 }
2861 if(insn_match_find_next(fw,is,3,match_bl_blximm)) {
2862 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2863 }
2864 printf("sig_match_try_take_sem_dry_gt_58: no match\n");
2865 return 0;
2866 }
2867
2868 int sig_match_wait_all_eventflag_strict(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2869 {
2870 if(!init_disasm_sig_ref(fw,is,rule)) {
2871 return 0;
2872 }
2873 uint32_t str_adr = find_str_bytes_main_fw(fw,"EFTool.c");
2874 if(!str_adr) {
2875 printf("sig_match_wait_all_eventflag_strict: failed to find ref EFTool.c\n");
2876 return 0;
2877 }
2878 if(!find_next_sig_call(fw,is,60,"SleepTask")) {
2879 printf("sig_match_wait_all_eventflag_strict: failed to find SleepTask\n");
2880 return 0;
2881 }
2882
2883 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,is->adr + 60)) {
2884 if(!insn_match_find_next(fw,is,6,match_bl_blximm)) {
2885 printf("sig_match_wait_all_eventflag_strict: no match bl 0x%"PRIx64"\n",is->insn->address);
2886 return 0;
2887 }
2888 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2889 }
2890 return 0;
2891 }
2892
2893 int sig_match_get_num_posted_messages(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2894 {
2895 if(!init_disasm_sig_ref(fw,is,rule)) {
2896 return 0;
2897 }
2898 if(!find_next_sig_call(fw,is,50,"TakeSemaphore")) {
2899 printf("sig_match_get_num_posted_messages: failed to find TakeSemaphore\n");
2900 return 0;
2901 }
2902
2903 if(!insn_match_find_next(fw,is,5,match_bl_blximm)) {
2904 printf("sig_match_get_num_posted_messages: no match bl 0x%"PRIx64"\n",is->insn->address);
2905 return 0;
2906 }
2907 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2908 }
2909
2910 int sig_match_set_hp_timer_after_now(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2911 {
2912 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2913 if(!str_adr) {
2914 printf("sig_match_set_hp_timer_after_now: failed to find ref %s\n",rule->ref_name);
2915 return 0;
2916 }
2917 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
2918 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2919 if(!find_next_sig_call(fw,is,20,"ClearEventFlag")) {
2920
2921 continue;
2922 }
2923
2924 if(!insn_match_find_nth(fw,is,13,3,match_bl_blximm)) {
2925
2926 continue;
2927 }
2928
2929 uint32_t regs[4];
2930 uint32_t found_regs = get_call_const_args(fw,is,6,regs);
2931 if((found_regs&0x1)!=0x1) {
2932
2933
2934 if((found_regs & 0x8) && regs[3] == 4) {
2935 if((found_regs & 0x2 && regs[1] > fw->rom_code_search_min_adr)
2936 || (found_regs & 0x4 && regs[2] > fw->rom_code_search_min_adr)) {
2937 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2938 }
2939 }
2940
2941 continue;
2942 }
2943
2944 if(regs[0] != 70000) {
2945
2946 continue;
2947 }
2948 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2949 }
2950 return 0;
2951 }
2952 int sig_match_transfer_src_overlay(firmware *fw, iter_state_t *is, sig_rule_t *rule) {
2953 if(!init_disasm_sig_ref(fw,is,rule)) {
2954 return 0;
2955 }
2956
2957 if(!find_next_sig_call(fw,is,32,"DebugAssert")) {
2958 printf("sig_match_transfer_src_overlay: no match DebugAssert\n");
2959 return 0;
2960 }
2961 var_ldr_desc_t desc;
2962 if(!find_and_get_var_ldr(fw, is, 20,4, ARM_REG_R0, &desc)) {
2963 printf("sig_match_transfer_src_overlay: no match ldr\n");
2964 return 0;
2965 }
2966
2967 if(!insn_match_find_next(fw,is,1,match_bl_blximm)) {
2968 printf("sig_match_transfer_src_overlay: no match bl 0x%"PRIx64"\n",is->insn->address);
2969 return 0;
2970 }
2971
2972 uint32_t fadr = get_branch_call_insn_target(fw,is);
2973
2974
2975 save_misc_val("active_bitmap_buffer",desc.adr_adj,desc.off,(uint32_t)is->insn->address);
2976
2977
2978
2979
2980 const insn_match_t bm_buf_match[]={
2981 {MATCH_INS(LDR, 2), {MATCH_OP_REG_ANY, MATCH_OP_MEM_ANY}},
2982 {MATCH_INS(ADD, 3), {MATCH_OP_REG(R0), MATCH_OP_REG_ANY, MATCH_OP_IMM_ANY}},
2983 {ARM_INS_ENDING}
2984 };
2985 if(insn_match_find_next_seq(fw,is,1,bm_buf_match)) {
2986 if((arm_reg)is->insn->detail->arm.operands[1].reg == desc.reg_base) {
2987 save_misc_val("bitmap_buffer",desc.adr_adj,is->insn->detail->arm.operands[2].imm,(uint32_t)is->insn->address);
2988 }
2989
2990
2991
2992
2993
2994 }
2995
2996
2997
2998
2999
3000 return save_sig_with_j(fw,rule->name,fadr);
3001 }
3002
3003
3004 int sig_match_exmem_vars(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3005 {
3006 uint32_t adr[2], fnd[2];
3007 if(!init_disasm_sig_ref(fw,is,rule)) {
3008 printf("sig_match_exmem_vars: missing ref\n");
3009 return 0;
3010 }
3011
3012 if(!insn_match_find_next(fw,is,15,match_ldr_pc)) {
3013 printf("sig_match_exmem_vars: match LDR PC failed\n");
3014 return 0;
3015 }
3016 adr[0]=LDR_PC2val(fw,is->insn);
3017 fnd[0]=(uint32_t)is->insn->address;
3018 if(!insn_match_find_next(fw,is,5,match_ldr_pc)) {
3019 printf("sig_match_exmem_vars: 2nd match LDR PC failed\n");
3020 return 0;
3021 }
3022 adr[1]=LDR_PC2val(fw,is->insn);
3023 fnd[1]=(uint32_t)is->insn->address;
3024
3025 int n;
3026 for (n=0; n<2; n++) {
3027 if (adr[n] < fw->data_start+fw->data_len) {
3028 uint32_t ladr = adr[n]-fw->data_start+fw->data_init_start;
3029 save_misc_val("exmem_types_table",ladr,0,fnd[n]);
3030 int m;
3031 int exm_typ_cnt = 0;
3032 for (m=0; m<42; m++) {
3033 if ( (fw_u32(fw,ladr+m*4)!=0) && isASCIIstring(fw, fw_u32(fw,ladr+m*4)) )
3034 {
3035 char *extyp = (char*)adr2ptr(fw, fw_u32(fw,ladr+m*4));
3036 if ( strncmp(extyp,"EXMEM",5)==0 )
3037 {
3038 exm_typ_cnt++;
3039 }
3040 }
3041 else
3042 {
3043 break;
3044 }
3045 }
3046 save_misc_val("exmem_type_count",exm_typ_cnt,0,ladr);
3047 }
3048 else if (adr[n] < fw->memisostart) {
3049 save_misc_val("exmem_alloc_table",adr[n],0,fnd[n]);
3050 }
3051 }
3052 return 1;
3053 }
3054
3055
3056 int sig_match_zicokick_52(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3057 {
3058 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
3059 if(!str_adr) {
3060 printf("sig_match_zicokick_52: failed to find ref %s\n",rule->ref_name);
3061 return 0;
3062 }
3063 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
3064
3065
3066 if(!fw_search_insn(fw,is,search_disasm_str_ref,0,rule->ref_name,(uint32_t)is->adr+SEARCH_NEAR_REF_RANGE)) {
3067 printf("sig_match_zicokick_52: failed to find insn ref %s\n",rule->ref_name);
3068 return 0;
3069 }
3070
3071 if(!fw_disasm_iter_single(fw,adr_hist_get(&is->ah,1))) {
3072 printf("sig_match_zicokick_52: disasm failed\n");
3073 return 0;
3074 }
3075 if (!(isLDR_PC(fw->is->insn) && fw->is->insn->detail->arm.operands[0].reg == ARM_REG_R0)) {
3076 printf("sig_match_zicokick_52: match ldr r0 failed\n");
3077 return 0;
3078 }
3079
3080 uint32_t adr=(uint32_t)(fw->is->insn->address) | is->thumb;
3081
3082 if(!disasm_iter(fw,is)) {
3083 printf("sig_match_zicokick_52: disasm failed\n");
3084 return 0;
3085 }
3086 if (is->insn->id == ARM_INS_PUSH && is->insn->detail->arm.operands[0].reg == ARM_REG_R4) {
3087 return save_sig_with_j(fw,rule->name,adr);
3088 }
3089 return 0;
3090 }
3091
3092 int sig_match_zicokick_gt52(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3093 {
3094 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
3095 if(!str_adr) {
3096 printf("sig_match_zicokick_gt52: failed to find ref %s\n",rule->ref_name);
3097 return 0;
3098 }
3099 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
3100
3101
3102 if(!fw_search_insn(fw,is,search_disasm_str_ref,0,rule->ref_name,(uint32_t)is->adr+SEARCH_NEAR_REF_RANGE)) {
3103 printf("sig_match_zicokick_gt52: failed to find insn ref %s\n",rule->ref_name);
3104 return 0;
3105 }
3106 int i;
3107
3108
3109
3110 for(i=1; i<=8; i++) {
3111 if (!fw_disasm_iter_single(fw,adr_hist_get(&is->ah,i))) {
3112 printf("sig_match_zicokick_gt52: disasm failed\n");
3113 return 0;
3114 }
3115 if (fw->is->insn->id == ARM_INS_PUSH && fw->is->insn->detail->arm.operands[0].reg == ARM_REG_R4) {
3116 if (!fw_disasm_iter_single(fw,adr_hist_get(&is->ah,i+1))) {
3117 printf("sig_match_zicokick_gt52: disasm failed\n");
3118 return 0;
3119 }
3120 if (isLDR_PC(fw->is->insn) && fw->is->insn->detail->arm.operands[0].reg == ARM_REG_R0) {
3121 return save_sig_with_j(fw,rule->name,(uint32_t)(fw->is->insn->address) | is->thumb);
3122 }
3123 return 0;
3124 }
3125 }
3126 return 0;
3127 }
3128 int sig_match_zicokick_copy(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3129 {
3130 if(!init_disasm_sig_ref(fw,is,rule)) {
3131 return 0;
3132 }
3133
3134 const insn_match_t match_ldrs_bl[]={
3135 {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM_BASE(PC)}},
3136 {MATCH_INS(LDR, 2), {MATCH_OP_REG(R1), MATCH_OP_MEM_BASE(PC)}},
3137 {MATCH_INS(LDR, 2), {MATCH_OP_REG(R2), MATCH_OP_MEM_BASE(R0)}},
3138 {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM_BASE(PC)}},
3139 {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM_BASE(R0)}},
3140 {MATCH_INS(BL,MATCH_OPCOUNT_IGNORE)},
3141 {ARM_INS_ENDING}
3142 };
3143 if(!insn_match_find_next_seq(fw,is,30,match_ldrs_bl)) {
3144 printf("sig_match_zicokick_copy no match ldr\n");
3145 return 0;
3146 }
3147
3148 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3149 }
3150
3151 int sig_match_zicokick_values(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3152 {
3153 if(!init_disasm_sig_ref(fw,is,rule)) {
3154 return 0;
3155 }
3156
3157 #if 0
3158
3159 if(!find_next_sig_call(fw,is,64,"zicokick_copy")) {
3160 printf("sig_match_zicokick_values: no zicokick_copy 1\n");
3161 return 0;
3162 }
3163 while(1) {
3164 uint32_t regs[4];
3165 if((get_call_const_args(fw,is,7,regs)&0x7)==0x7) {
3166 printf("xtensa blob @ 0x%08x, loads to 0x%08x, size 0x%08x\n",regs[1],regs[0],regs[2]);
3167 } else {
3168 printf("sig_match_zicokick_values: failed to get regs\n");
3169 }
3170 if(!find_next_sig_call(fw,is,8,"zicokick_copy")) {
3171 break;
3172 }
3173 }
3174 return 1;
3175 #endif
3176 int i;
3177 uint32_t uv[3] = {0,0,0};
3178 int uvi = 0;
3179 misc_blob_t *blobs=malloc((MISC_BLOB_XTENSA_MAX + 1)*sizeof(misc_blob_t));
3180 int n_blobs = 0;
3181
3182 for(i=1; i<=64; i++) {
3183 if (!disasm_iter(fw,is)) {
3184 free(blobs);
3185 return 0;
3186 }
3187 if (is->insn->id == ARM_INS_LDR && is->insn->detail->arm.operands[1].type == ARM_OP_MEM) {
3188 uint32_t u = LDR_PC2val(fw,is->insn);
3189 if ((u<fw->base+fw->size8) && (u>fw->rom_code_search_max_adr)) {
3190
3191 if (uvi<3) {
3192 uv[uvi] = u;
3193 uvi++;
3194 }
3195 }
3196 }
3197 else if (is->insn->id == ARM_INS_BL) {
3198 if (uvi==3) {
3199
3200 uint32_t bsize, bloadedto, badr, u;
3201 int j;
3202 badr = MAX(MAX(uv[0],uv[1]),uv[2]);
3203 for (j=0; j<3; j++) {
3204 if (uv[j]!=badr) {
3205 u = fw_u32(fw, uv[j]);
3206 if (u<1024*1024*2) {
3207 bsize = u;
3208 }
3209 else {
3210 bloadedto = u;
3211 }
3212 }
3213 }
3214 if (bsize) {
3215 if(n_blobs == MISC_BLOB_XTENSA_MAX) {
3216 printf("sig_match_zicokick_values: ignoring xtensa blobs > %d\n",MISC_BLOB_XTENSA_MAX);
3217 blobs[n_blobs].type = MISC_BLOB_TYPE_NONE;
3218 break;
3219 }
3220
3221 blobs[n_blobs].type = MISC_BLOB_TYPE_XTENSA;
3222 blobs[n_blobs].rom_adr = badr;
3223 blobs[n_blobs].ram_adr = bloadedto;
3224 blobs[n_blobs].size = bsize;
3225 n_blobs++;
3226 }
3227 }
3228 uvi = 0;
3229 }
3230 else if (is->insn->id == ARM_INS_POP) {
3231 break;
3232 }
3233 }
3234 if(n_blobs > 0) {
3235 blobs[n_blobs].type = MISC_BLOB_TYPE_NONE;
3236 save_misc_val_blobs("zicokick_values",blobs,0);
3237 return 1;
3238 } else {
3239 free(blobs);
3240 return 0;
3241 }
3242 }
3243
3244 int sig_match_init_ex_drivers(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3245 {
3246 if(!init_disasm_sig_ref(fw,is,rule)) {
3247 return 0;
3248 }
3249 int i;
3250 int b_count;
3251
3252 for(i=0, b_count = 0; i < 32 && b_count < 14; i++) {
3253 if (!disasm_iter(fw,is)) {
3254 printf("sig_match_init_ex_drivers: disasm failed 1\n");
3255 return 0;
3256 }
3257 uint32_t b_tgt = get_branch_call_insn_target(fw,is);
3258 if(!b_tgt) {
3259 continue;
3260 }
3261 b_count++;
3262 uint64_t next_adr = is->adr | is->thumb;
3263 disasm_iter_init(fw,is,b_tgt);
3264 if (!disasm_iter(fw,is)) {
3265 printf("sig_match_init_ex_drivers: disasm failed 2\n");
3266 return 0;
3267 }
3268
3269 if(is->insn->id == ARM_INS_PUSH) {
3270 if(find_next_sig_call(fw,is,30,"DebugAssert")) {
3271 uint32_t regs[4];
3272 if((get_call_const_args(fw,is,5,regs)&0x2)==0x2) {
3273 const char *str=(char *)adr2ptr(fw,regs[1]);
3274 if(str && strcmp(str,"InitExDrivers.c") == 0) {
3275 return save_sig_with_j(fw,rule->name,b_tgt);
3276 }
3277 }
3278 }
3279 }
3280 disasm_iter_init(fw,is,next_adr);
3281 }
3282 return 0;
3283 }
3284
3285 int sig_match_omar_init(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3286 {
3287
3288 if (fw->arch_flags & FW_ARCH_FL_VMSA) {
3289 return 0;
3290 }
3291 if(!init_disasm_sig_ref(fw,is,rule)) {
3292 return 0;
3293 }
3294 uint32_t fadr = find_last_call_from_func(fw,is,20,42);
3295 if(!fadr) {
3296 printf("sig_match_omar_init: no match call\n");
3297 return 0;
3298 }
3299
3300 disasm_iter_init(fw,is,fadr);
3301 if(!find_next_sig_call(fw,is,44,"dry_memcpy")) {
3302 printf("sig_match_omar_init: no match dry_memcpy\n");
3303 return 0;
3304 }
3305 uint32_t regs[4];
3306
3307 if((get_call_const_args(fw,is,5,regs)&0x6)!=0x6) {
3308 printf("sig_match_omar_init: no match dry_memcpy args 1\n");
3309 return 0;
3310 }
3311 if(regs[2] != 0x18 || !adr2ptr(fw,regs[1])) {
3312 printf("sig_match_omar_init: no match dry_memcpy args 2\n");
3313 return 0;
3314 }
3315 uint32_t dadr = regs[1];
3316 save_misc_val("omar_init_data",dadr,0,(uint32_t)is->insn->address);
3317 misc_blob_t *blobs=malloc(3*sizeof(misc_blob_t));
3318 int i;
3319 for(i = 0; i<2; i++) {
3320 uint32_t dst = fw_u32(fw,dadr + i*12);
3321 uint32_t src = fw_u32(fw,dadr + i*12 + 4);
3322 uint32_t bsize = fw_u32(fw,dadr + i*12 + 8);
3323 if(src && dst && bsize) {
3324 blobs[i].type = MISC_BLOB_TYPE_OMAR;
3325 blobs[i].rom_adr = src;
3326 blobs[i].ram_adr = dst;
3327 blobs[i].size = bsize;
3328 } else {
3329 printf("sig_match_omar_init: invalid blobs\n");
3330 free(blobs);
3331 blobs = NULL;
3332 break;
3333 }
3334 }
3335 if(blobs) {
3336 blobs[2].type = MISC_BLOB_TYPE_NONE;
3337 save_misc_val_blobs("omar_init_values",blobs,0);
3338 }
3339
3340 return save_sig_with_j(fw,rule->name,fadr);
3341 }
3342
3343 int sig_match_enable_hdmi_power(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3344 {
3345 if(!init_disasm_sig_ref(fw,is,rule)) {
3346 return 0;
3347 }
3348 if(!find_next_sig_call(fw,is,14,"CreateEventFlagStrictly")) {
3349 printf("sig_match_enable_hdmi_power: no match CreateEventFlagStrictly\n");
3350 return 0;
3351 }
3352 const insn_match_t match_seq[]={
3353 {MATCH_INS(BL, MATCH_OPCOUNT_IGNORE)},
3354 {MATCH_INS(CBNZ, MATCH_OPCOUNT_IGNORE)},
3355 {ARM_INS_ENDING}
3356 };
3357 if(!insn_match_find_next_seq(fw,is,4,match_seq)) {
3358 printf("sig_match_enable_hdmi_power: no match bl seq cbnz 0x%"PRIx64"\n",is->insn->address);
3359 return 0;
3360 }
3361
3362 if (!disasm_iter(fw,is)) {
3363 return 0;
3364 }
3365 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3366 }
3367
3368 int sig_match_disable_hdmi_power(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3369 {
3370 if(!init_disasm_sig_ref(fw,is,rule)) {
3371 return 0;
3372 }
3373 if(!find_next_sig_call(fw,is,24,"EnableHDMIPower")) {
3374 printf("sig_match_disable_hdmi_power: no match EnableHDMIPower\n");
3375 return 0;
3376 }
3377 if(!find_next_sig_call(fw,is,22,"ClearEventFlag")) {
3378 printf("sig_match_disable_hdmi_power: no match ClearEventFlag\n");
3379 return 0;
3380 }
3381 const insn_match_t match_seq[]={
3382 {MATCH_INS(BL, MATCH_OPCOUNT_IGNORE)},
3383 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM(1)}},
3384 {MATCH_INS(POP, MATCH_OPCOUNT_IGNORE)},
3385 {ARM_INS_ENDING}
3386 };
3387 if(!insn_match_find_next_seq(fw,is,12,match_seq)) {
3388 printf("sig_match_disable_hdmi_power: no match seq bl movs pop 0x%"PRIx64"\n",is->insn->address);
3389 return 0;
3390 }
3391
3392 disasm_iter_init(fw,is,adr_hist_get(&is->ah,2));
3393 if (!disasm_iter(fw,is)) {
3394 return 0;
3395 }
3396 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3397 }
3398
3399 int sig_match_levent_table(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3400 {
3401 if(!init_disasm_sig_ref(fw,is,rule)) {
3402 return 0;
3403 }
3404 if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
3405
3406 return 0;
3407 }
3408
3409 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
3410
3411
3412 if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
3413
3414 return 0;
3415 }
3416
3417
3418 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
3419
3420
3421 disasm_iter(fw,is);
3422 uint32_t adr=LDR_PC2val(fw,is->insn);
3423 if(!adr) {
3424
3425 return 0;
3426 }
3427 uint32_t *p=(uint32_t *)adr2ptr(fw,adr);
3428 if(!p) {
3429 printf("sig_match_levent_table: 0x%08x not a ROM adr 0x%"PRIx64"\n",adr,is->insn->address);
3430 return 0;
3431 }
3432 if(*(p+1) != 0x800) {
3433 printf("sig_match_levent_table: expected 0x800 not 0x%x at 0x%08x ref 0x%"PRIx64"\n",*(p+1),adr,is->insn->address);
3434 return 0;
3435 }
3436
3437 save_misc_val(rule->name,adr,0,(uint32_t)is->insn->address);
3438 return 1;
3439 }
3440 int sig_match_flash_param_table(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3441 {
3442 if(!init_disasm_sig_ref(fw,is,rule)) {
3443 return 0;
3444 }
3445
3446 if(!insn_match_find_next(fw,is,14,match_bl_blximm)) {
3447
3448 return 0;
3449 }
3450 if(!is_sig_call(fw,is,"DebugAssert")) {
3451
3452 return 0;
3453 }
3454 if(!insn_match_find_next(fw,is,7,match_bl_blximm)) {
3455
3456 return 0;
3457 }
3458 if(!is_sig_call(fw,is,"DebugAssert")) {
3459
3460 return 0;
3461 }
3462 if(!insn_match_find_next(fw,is,8,match_bl_blximm)) {
3463
3464 return 0;
3465 }
3466 if(!is_sig_call(fw,is,"DebugAssert")) {
3467
3468 return 0;
3469 }
3470
3471 if(!insn_match_find_nth(fw,is,14,2,match_bl_blximm)) {
3472
3473 return 0;
3474 }
3475
3476 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
3477
3478
3479 if(!insn_match_find_next(fw,is,8,match_bl_blximm)) {
3480
3481 return 0;
3482 }
3483
3484
3485 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
3486
3487 disasm_iter(fw,is);
3488 uint32_t adr=LDR_PC2val(fw,is->insn);
3489 if(!adr) {
3490
3491 return 0;
3492 }
3493 save_misc_val(rule->name,adr,0,(uint32_t)is->insn->address);
3494 return 1;
3495 }
3496 int sig_match_jpeg_count_str(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3497 {
3498 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
3499 if(!str_adr) {
3500 printf("sig_match_jpeg_count_str: failed to find ref %s\n",rule->ref_name);
3501 return 0;
3502 }
3503
3504 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
3505 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
3506
3507 if(!insn_match_find_next(fw,is,3,match_bl_blximm)) {
3508
3509 continue;
3510 }
3511 if(!is_sig_call(fw,is,"sprintf_FW")) {
3512
3513 continue;
3514 }
3515
3516 uint32_t regs[4];
3517 if((get_call_const_args(fw,is,5,regs)&0x3)!=0x3) {
3518
3519 continue;
3520 }
3521 if(regs[1] != str_adr) {
3522
3523 return 0;
3524 }
3525 if(!adr_is_var(fw,regs[0])) {
3526
3527 return 0;
3528 }
3529 save_misc_val(rule->name,regs[0],0,(uint32_t)is->insn->address);
3530 return 1;
3531 }
3532 return 0;
3533 }
3534
3535
3536 int sig_match_misc_flag_named(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3537 {
3538 uint32_t ref=get_saved_sig_val(rule->ref_name);
3539 save_misc_val(rule->name,(ref)?1:0,0,ref);
3540 return 1;
3541 }
3542
3543 int sig_match_cam_has_iris_diaphragm(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3544 {
3545 uint32_t v;
3546 uint32_t ref=0;get_saved_sig_val(rule->ref_name);
3547
3548 if(get_misc_val_value("CAM_IS_ILC")) {
3549 v=1;
3550 } else {
3551 ref=get_saved_sig_val(rule->ref_name);
3552 v=(ref)?1:0;
3553 }
3554 save_misc_val(rule->name,v,0,ref);
3555 return 1;
3556 }
3557
3558 int sig_match_cam_uncached_bit(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3559 {
3560 if(!init_disasm_sig_ref(fw,is,rule)) {
3561 return 0;
3562 }
3563 const insn_match_t match_bic_r0[]={
3564 {MATCH_INS(BIC, 3), {MATCH_OP_REG(R0), MATCH_OP_REG(R0), MATCH_OP_IMM_ANY}},
3565 {ARM_INS_ENDING}
3566 };
3567 if(insn_match_find_next(fw,is,4,match_bic_r0)) {
3568 save_misc_val(rule->name,is->insn->detail->arm.operands[2].imm,0,(uint32_t)is->insn->address);
3569 return 1;
3570 }
3571 return 0;
3572 }
3573
3574 int sig_match_physw_event_table(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3575 {
3576 if(!init_disasm_sig_ref(fw,is,rule)) {
3577 return 0;
3578 }
3579
3580 if(!insn_match_find_next(fw,is,5,match_ldr_pc)) {
3581 printf("sig_match_physw_event_table: match LDR PC failed\n");
3582 return 0;
3583 }
3584 uint32_t adr=LDR_PC2val(fw,is->insn);
3585 if(!adr) {
3586 printf("sig_match_physw_event_table: no match LDR PC 0x%"PRIx64"\n",is->insn->address);
3587 return 0;
3588 }
3589 if(!adr2ptr(fw,adr)) {
3590 printf("sig_match_physw_event_table: adr not ROM 0x%08x at 0x%"PRIx64"\n",adr,is->insn->address);
3591 return 0;
3592 }
3593 save_misc_val(rule->name,adr,0,(uint32_t)is->insn->address);
3594 return 1;
3595 }
3596 int sig_match_uiprop_count(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3597 {
3598 if(!init_disasm_sig_ref(fw,is,rule)) {
3599 return 0;
3600 }
3601 if(!find_next_sig_call(fw,is,38,"DebugAssert")) {
3602
3603 return 0;
3604 }
3605 if(!find_next_sig_call(fw,is,14,"DebugAssert")) {
3606
3607 return 0;
3608 }
3609 const insn_match_t match_bic_cmp[]={
3610 {MATCH_INS(BIC, 3), {MATCH_OP_REG_ANY, MATCH_OP_REG_ANY, MATCH_OP_IMM(0x8000)}},
3611 {MATCH_INS(CMP, 2), {MATCH_OP_REG_ANY, MATCH_OP_ANY}},
3612 {ARM_INS_ENDING}
3613 };
3614 if(!insn_match_find_next_seq(fw,is,3,match_bic_cmp)) {
3615
3616 return 0;
3617 }
3618 save_misc_val(rule->name,is->insn->detail->arm.operands[1].imm,0,(uint32_t)is->insn->address);
3619 return 1;
3620 }
3621
3622 int sig_match_get_canon_mode_list(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3623 {
3624 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
3625 if(!str_adr) {
3626 printf("sig_match_get_canon_mode_list: failed to find ref %s\n",rule->ref_name);
3627 return 0;
3628 }
3629 uint32_t adr=0;
3630
3631 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
3632 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
3633
3634 if(!find_next_sig_call(fw,is,4,"LogCameraEvent")) {
3635
3636 continue;
3637 }
3638
3639 if(!disasm_iter(fw,is)) {
3640
3641 return 0;
3642 }
3643 const insn_match_t match_mov_r0_1[]={
3644 #if CS_API_MAJOR < 4
3645 {MATCH_INS(MOVS, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM(1)}},
3646 #endif
3647 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM(1)}},
3648 {ARM_INS_ENDING}
3649 };
3650 if(insn_match_any(is->insn,match_mov_r0_1)) {
3651 if(!insn_match_find_nth(fw,is,2,2,match_bl_blximm)) {
3652
3653 continue;
3654 }
3655 } else {
3656 if(!insn_match_any(is->insn,match_bl_blximm)) {
3657
3658 continue;
3659 }
3660 }
3661
3662 adr=get_branch_call_insn_target(fw,is);
3663 break;
3664 }
3665 if(!adr) {
3666 return 0;
3667 }
3668
3669 disasm_iter_init(fw,is,adr);
3670 if(!find_next_sig_call(fw,is,40,"TakeSemaphoreStrictly")) {
3671
3672 return 0;
3673 }
3674
3675 if(!insn_match_find_nth(fw,is,12,2,match_b_bl_blximm)) {
3676
3677 return 0;
3678 }
3679
3680 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
3681 const insn_match_t match_loop[]={
3682 {MATCH_INS(ADD, 3), {MATCH_OP_REG_ANY, MATCH_OP_REG_ANY, MATCH_OP_IMM(1)}},
3683 {MATCH_INS(UXTH, 2), {MATCH_OP_REG_ANY, MATCH_OP_REG_ANY}},
3684 {MATCH_INS(CMP, 2), {MATCH_OP_REG_ANY, MATCH_OP_IMM_ANY}},
3685 {MATCH_INS_CC(B,LO,MATCH_OPCOUNT_IGNORE)},
3686 {ARM_INS_ENDING}
3687 };
3688 if(!insn_match_find_next_seq(fw,is,64,match_loop)) {
3689
3690 return 0;
3691 }
3692 if(!insn_match_find_next(fw,is,2,match_bl_blximm)) {
3693
3694 return 0;
3695 }
3696
3697 adr=get_branch_call_insn_target(fw,is);
3698
3699 disasm_iter_init(fw,is,adr);
3700 const insn_match_t match_ldr_r0_ret[]={
3701 {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM_BASE(PC)}},
3702 {MATCH_INS(BX, 1), {MATCH_OP_REG(LR)}},
3703 {ARM_INS_ENDING}
3704 };
3705 if(!insn_match_find_next_seq(fw,is,1,match_ldr_r0_ret)) {
3706
3707 return 0;
3708 }
3709 return save_sig_with_j(fw,rule->name,adr);
3710 }
3711
3712 int sig_match_zoom_busy(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3713 {
3714 if(!init_disasm_sig_ref(fw,is,rule)) {
3715 return 0;
3716 }
3717
3718 if(!insn_match_find_next(fw,is,5,match_bl_blximm)) {
3719
3720 return 0;
3721 }
3722
3723 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
3724
3725 if(!insn_match_find_next(fw,is,5,match_ldr_pc)) {
3726
3727 return 0;
3728 }
3729 uint32_t base=LDR_PC2val(fw,is->insn);
3730 arm_reg rb=is->insn->detail->arm.operands[0].reg;
3731
3732
3733 if(!find_next_sig_call(fw,is,40,"TakeSemaphoreStrictly")) {
3734
3735 return 0;
3736 }
3737 if(!disasm_iter(fw,is)) {
3738
3739 return 0;
3740 }
3741
3742 if(is->insn->id != ARM_INS_LDR
3743 || is->insn->detail->arm.operands[0].reg != ARM_REG_R0
3744 || is->insn->detail->arm.operands[1].mem.base != rb) {
3745
3746 return 0;
3747 }
3748 save_misc_val(rule->name,base,is->insn->detail->arm.operands[1].mem.disp,(uint32_t)is->insn->address);
3749 return 1;
3750 }
3751
3752 int sig_match_focus_busy(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3753 {
3754 if(!init_disasm_sig_ref(fw,is,rule)) {
3755 return 0;
3756 }
3757
3758 if(!find_next_sig_call(fw,is,40,"TakeSemaphore")) {
3759
3760 return 0;
3761 }
3762
3763 if(!insn_match_find_next(fw,is,5,match_bl_blximm)) {
3764
3765 return 0;
3766 }
3767
3768 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
3769
3770 if(!insn_match_find_next(fw,is,5,match_ldr_pc)) {
3771
3772 return 0;
3773 }
3774 uint32_t base=LDR_PC2val(fw,is->insn);
3775 arm_reg rb=is->insn->detail->arm.operands[0].reg;
3776
3777
3778 if(!find_next_sig_call(fw,is,50,"TakeSemaphoreStrictly")) {
3779
3780 return 0;
3781 }
3782 const insn_match_t match_ldr[]={
3783 {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM_ANY}},
3784 {MATCH_INS(CBZ, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM_ANY}},
3785 {ARM_INS_ENDING}
3786 };
3787 if(!insn_match_find_next_seq(fw,is,10,match_ldr)) {
3788
3789 return 0;
3790 }
3791
3792 disasm_iter_init(fw,is,adr_hist_get(&is->ah,1));
3793 disasm_iter(fw,is);
3794
3795 if(is->insn->detail->arm.operands[1].mem.base != rb) {
3796
3797 return 0;
3798 }
3799 save_misc_val(rule->name,base,is->insn->detail->arm.operands[1].mem.disp,(uint32_t)is->insn->address);
3800 return 1;
3801 }
3802 int sig_match_aram_size(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3803 {
3804 if(!init_disasm_sig_ref(fw,is,rule)) {
3805 printf("sig_match_aram_size: missing ref\n");
3806 return 0;
3807 }
3808 const insn_match_t match_ldr_r0_sp_cmp[]={
3809 {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0),MATCH_OP_MEM(SP,INVALID,0xc)}},
3810 {MATCH_INS(CMP, 2), {MATCH_OP_REG(R0),MATCH_OP_IMM_ANY}},
3811 {ARM_INS_ENDING}
3812 };
3813 if(!insn_match_find_next_seq(fw,is,15,match_ldr_r0_sp_cmp)) {
3814 printf("sig_match_aram_size: no match LDR\n");
3815 return 0;
3816 }
3817 uint32_t val=is->insn->detail->arm.operands[1].imm;
3818 if(val != 0x22000 && val != 0x32000) {
3819 printf("sig_match_aram_size: unexpected ARAM size 0x%08x\n",val);
3820 }
3821 save_misc_val(rule->name,val,0,(uint32_t)is->insn->address);
3822 return 1;
3823 }
3824
3825 int sig_match_aram_size_gt58(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3826 {
3827 if(!init_disasm_sig_ref(fw,is,rule)) {
3828 printf("sig_match_aram_size: missing ref\n");
3829 return 0;
3830 }
3831 const insn_match_t match_ldrd_r0r1_mov[]={
3832 {MATCH_INS(LDRD, 3), {MATCH_OP_REG(R0),MATCH_OP_REG(R1),MATCH_OP_MEM(SP,INVALID,0x10)}},
3833 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R2),MATCH_OP_IMM_ANY}},
3834 {ARM_INS_ENDING}
3835 };
3836
3837 const insn_match_t match_ldrd_r2r1_mov[]={
3838 {MATCH_INS(LDRD, 3), {MATCH_OP_REG(R2),MATCH_OP_REG(R1),MATCH_OP_MEM(SP,INVALID,0x10)}},
3839 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R3),MATCH_OP_IMM_ANY}},
3840 {ARM_INS_ENDING}
3841 };
3842 if(!insn_match_find_next_seq(fw,is,15,match_ldrd_r0r1_mov)) {
3843 init_disasm_sig_ref(fw,is,rule);
3844 if(!insn_match_find_next_seq(fw,is,15,match_ldrd_r2r1_mov)) {
3845 printf("sig_match_aram_size: no match LDR\n");
3846 }
3847 return 0;
3848 }
3849 uint32_t val=is->insn->detail->arm.operands[1].imm;
3850 if(val != 0x22000 && val != 0x32000) {
3851 printf("sig_match_aram_size: unexpected ARAM size 0x%08x\n",val);
3852 }
3853 save_misc_val(rule->name,val,0,(uint32_t)is->insn->address);
3854 return 1;
3855 }
3856
3857 int sig_match_aram_start(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3858 {
3859 if(!init_disasm_sig_ref(fw,is,rule)) {
3860 printf("sig_match_aram_start: missing ref\n");
3861 return 0;
3862 }
3863 if(!find_next_sig_call(fw,is,50,"DebugAssert")) {
3864 printf("sig_aram_start: no match DebugAssert\n");
3865 return 0;
3866 }
3867 const insn_match_t match_cmp_bne_ldr[]={
3868 {MATCH_INS(CMP, 2), {MATCH_OP_REG(R1),MATCH_OP_IMM(0)}},
3869 {MATCH_INS_CC(B,NE,MATCH_OPCOUNT_IGNORE)},
3870 {MATCH_INS(LDR, 2), {MATCH_OP_REG_ANY,MATCH_OP_MEM_BASE(PC)}},
3871 {ARM_INS_ENDING}
3872 };
3873 if(!insn_match_find_next_seq(fw,is,15,match_cmp_bne_ldr)) {
3874 printf("sig_match_aram_start: no match CMP\n");
3875 return 0;
3876 }
3877 uint32_t adr=LDR_PC2val(fw,is->insn);
3878 if(!adr) {
3879 printf("sig_match_aram_start: no match LDR PC 0x%"PRIx64"\n",is->insn->address);
3880 return 0;
3881 }
3882
3883 save_misc_val(rule->name,adr,0,(uint32_t)is->insn->address);
3884 return 1;
3885 }
3886
3887 int sig_match_aram_start2(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3888 {
3889 if (get_misc_val_value("ARAM_HEAP_START"))
3890 return 0;
3891
3892 if(!init_disasm_sig_ref(fw,is,rule)) {
3893 printf("sig_match_aram_start: missing ref\n");
3894 return 0;
3895 }
3896 if(!find_next_sig_call(fw,is,60,"DebugAssert")) {
3897 printf("sig_aram_start2: no match DebugAssert\n");
3898 return 0;
3899 }
3900 const insn_match_t match_cmp_bne_ldr[]={
3901 {MATCH_INS(CMP, 2), {MATCH_OP_REG(R1),MATCH_OP_IMM(0)}},
3902 {MATCH_INS_CC(B,NE,MATCH_OPCOUNT_IGNORE)},
3903 {MATCH_INS(LDR, 2), {MATCH_OP_REG_ANY,MATCH_OP_MEM_BASE(SP)}},
3904 {MATCH_INS(LDR, 2), {MATCH_OP_REG_ANY,MATCH_OP_MEM_BASE(PC)}},
3905 {ARM_INS_ENDING}
3906 };
3907 if(!insn_match_find_next_seq(fw,is,15,match_cmp_bne_ldr)) {
3908 printf("sig_match_aram_start2: no match CMP\n");
3909 return 0;
3910 }
3911 uint32_t adr=LDR_PC2val(fw,is->insn);
3912 if(!adr) {
3913 printf("sig_match_aram_start2: no match LDR PC 0x%"PRIx64"\n",is->insn->address);
3914 return 0;
3915 }
3916
3917 save_misc_val(rule->name,adr,0,(uint32_t)is->insn->address);
3918 return 1;
3919 }
3920
3921 int sig_match__nrflag(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3922 {
3923 if(!init_disasm_sig_ref(fw,is,rule)) {
3924 return 0;
3925 }
3926 uint32_t fadr=is->adr;
3927
3928 const insn_match_t match_cmp_b[]={
3929 {MATCH_INS(CMP, 2), {MATCH_OP_REG(R0),MATCH_OP_IMM_ANY}},
3930 {MATCH_INS(B,MATCH_OPCOUNT_IGNORE)},
3931 {ARM_INS_ENDING}
3932 };
3933 if(!insn_match_find_next_seq(fw,is,4,match_cmp_b) || is->insn->detail->arm.cc == ARM_CC_AL) {
3934 printf("sig_match__nrflag: no match CMP\n");
3935 return 0;
3936 }
3937
3938 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
3939 if(!disasm_iter(fw,is)) {
3940 printf("sig_match__nrflag: disasm failed\n");
3941 return 0;
3942 }
3943
3944 uint32_t adr=LDR_PC2val(fw,is->insn);
3945 if(!adr) {
3946 printf("sig_match__nrflag: no match LDR PC 0x%"PRIx64"\n",is->insn->address);
3947 return 0;
3948 }
3949 arm_reg reg_base = is->insn->detail->arm.operands[0].reg;
3950 if(!disasm_iter(fw,is)) {
3951 printf("sig_match__nrflag: disasm failed\n");
3952 return 0;
3953 }
3954
3955 if(isADDx_imm(is->insn) || isSUBx_imm(is->insn)) {
3956 if((arm_reg)is->insn->detail->arm.operands[0].reg != reg_base) {
3957 printf("sig_match__nrflag: no match ADD/SUB\n");
3958 return 0;
3959 }
3960 if(isADDx_imm(is->insn)) {
3961 adr+=is->insn->detail->arm.operands[1].imm;
3962 } else {
3963 adr-=is->insn->detail->arm.operands[1].imm;
3964 }
3965 if(!disasm_iter(fw,is)) {
3966 printf("sig_match__nrflag: disasm failed\n");
3967 return 0;
3968 }
3969 }
3970 if(is->insn->id != ARM_INS_STR || (arm_reg)is->insn->detail->arm.operands[1].reg != reg_base) {
3971 printf("sig_match__nrflag: no match STR\n");
3972 return 0;
3973 }
3974 uint32_t disp = is->insn->detail->arm.operands[1].mem.disp;
3975 save_misc_val(rule->name,adr,disp,fadr);
3976 return 1;
3977 }
3978
3979
3980
3981
3982 int sig_match_var_struct_get(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3983 {
3984 if(!init_disasm_sig_ref(fw,is,rule)) {
3985 return 0;
3986 }
3987 uint32_t fadr=is->adr;
3988 var_ldr_desc_t desc;
3989 if(!find_and_get_var_ldr(fw, is, 1, 4, ARM_REG_R0, &desc)) {
3990 printf("sig_match_var_struct_get: no match ldr\n");
3991 return 0;
3992 }
3993 if(!disasm_iter(fw,is)) {
3994 printf("sig_match_var_struct_get: disasm failed\n");
3995 return 0;
3996 }
3997
3998 if(!insn_match(is->insn,match_bxlr)) {
3999 printf("sig_match_var_struct_get: no match BX LR\n");
4000 return 0;
4001 }
4002 save_misc_val(rule->name,desc.adr_adj,desc.off,fadr);
4003 return 1;
4004 }
4005
4006 int sig_match_av_over_sem(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4007 {
4008
4009 if(!get_misc_val_value("CAM_HAS_IRIS_DIAPHRAGM")) {
4010 return 0;
4011 }
4012
4013 if(!init_disasm_sig_ref(fw,is,rule)) {
4014 return 0;
4015 }
4016 if(!find_next_sig_call(fw,is,30,"TakeSemaphore")) {
4017 printf("sig_match_av_over_sem: no match TakeSemaphore at 0x%"PRIx64"\n",is->insn->address);
4018 return 0;
4019 }
4020
4021
4022 disasm_iter_init(fw,is,adr_hist_get(&is->ah,5));
4023 var_ldr_desc_t desc;
4024 if(!find_and_get_var_ldr(fw, is, 3, 4, ARM_REG_R0, &desc)) {
4025 printf("sig_match_av_over_sem: no match ldr at 0x%"PRIx64"\n",is->insn->address);
4026 return 0;
4027 }
4028
4029 save_misc_val(rule->name,desc.adr_adj,desc.off,(uint32_t)is->insn->address);
4030 return 1;
4031 }
4032
4033 int sig_match_canon_menu_active(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4034 {
4035 if(!init_disasm_sig_ref(fw,is,rule)) {
4036 return 0;
4037 }
4038 var_ldr_desc_t desc;
4039 if(!find_and_get_var_ldr(fw, is, 2, 4, ARM_REG_R0, &desc)) {
4040 printf("sig_match_canon_menu_active: no match ldr at 0x%"PRIx64"\n",is->insn->address);
4041 return 0;
4042 }
4043 if(!disasm_iter(fw,is)) {
4044 printf("sig_match_canon_menu_active: disasm failed\n");
4045 return 0;
4046 }
4047 if(is->insn->id != ARM_INS_CMP) {
4048 printf("sig_match_canon_menu_active: no match cmp at 0x%"PRIx64"\n",is->insn->address);
4049 return 0;
4050 }
4051 save_misc_val(rule->name,desc.adr_adj,desc.off,(uint32_t)is->insn->address);
4052 return 1;
4053 }
4054
4055 int sig_match_file_counter_init(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4056 {
4057 if(!init_disasm_sig_ref(fw,is,rule)) {
4058 return 0;
4059 }
4060
4061 if(!insn_match_find_next(fw,is,3,match_bl_blximm)) {
4062
4063 return 0;
4064 }
4065
4066 if(check_simple_func(fw,get_branch_call_insn_target(fw,is),MATCH_SIMPLE_FUNC_NULLSUB,NULL)) {
4067 if(!insn_match_find_next(fw,is,3,match_bl_blximm)) {
4068
4069 return 0;
4070 }
4071 }
4072
4073 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
4074 if(!insn_match_find_next(fw,is,3,match_bl_blximm)) {
4075
4076 return 0;
4077 }
4078 uint32_t fadr = get_branch_call_insn_target(fw,is);
4079
4080 disasm_iter_init(fw,is,fadr);
4081 if(!disasm_iter(fw,is)) {
4082
4083 return 0;
4084 }
4085
4086 if(!isLDR_PC(is->insn)) {
4087
4088 return 0;
4089 }
4090
4091 return save_sig_with_j(fw,rule->name,fadr);
4092 }
4093 int sig_match_file_counter_var(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4094 {
4095 if(!init_disasm_sig_ref(fw,is,rule)) {
4096 return 0;
4097 }
4098 uint32_t adr=LDR_PC2val(fw,is->insn);
4099 if(!adr) {
4100
4101 return 0;
4102 }
4103 if(is->insn->detail->arm.operands[0].reg != ARM_REG_R0) {
4104
4105 return 0;
4106 }
4107 if(!adr_is_var(fw,adr)) {
4108
4109 return 0;
4110 }
4111 save_misc_val(rule->name,adr,0,(uint32_t)is->insn->address);
4112 return 1;
4113 }
4114
4115 int sig_match_palette_vars(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4116 {
4117 if(!init_disasm_sig_ref(fw,is,rule)) {
4118 return 0;
4119 }
4120 if(!find_next_sig_call(fw,is,70,"transfer_src_overlay")) {
4121 printf("sig_match_palette_vars: no match transfer_src_overlay\n");
4122 return 0;
4123 }
4124 uint32_t fadr=0;
4125 int i;
4126
4127 for(i=1; i<=6; i++) {
4128 if(!fw_disasm_iter_single(fw,adr_hist_get(&is->ah,i))) {
4129 printf("sig_match_palette_vars: disasm failed\n");
4130 return 0;
4131 }
4132 fadr=get_branch_call_insn_target(fw,fw->is);
4133 if(fadr) {
4134 break;
4135 }
4136 }
4137 if(!fadr) {
4138 printf("sig_match_palette_vars: no match bl 1 0x%"PRIx64"\n",fw->is->insn->address);
4139 return 0;
4140 }
4141
4142 disasm_iter_init(fw,is,fadr);
4143
4144 if(!insn_match_find_next(fw,is,3,match_bl)) {
4145 printf("sig_match_palette_vars: no match bl 2 0x%"PRIx64"\n",is->insn->address);
4146 return 0;
4147 }
4148
4149 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
4150
4151 if(!insn_match_find_next(fw,is,3,match_ldr_pc)) {
4152 printf("sig_match_palette_vars: no match ldr pc 0x%"PRIx64"\n",is->insn->address);
4153 return 0;
4154 }
4155
4156 uint32_t pal_base=LDR_PC2val(fw,is->insn);
4157 if(!pal_base || !adr_is_var(fw,pal_base)) {
4158 printf("sig_match_palette_vars: bad LDR PC 0x%"PRIx64"\n",is->insn->address);
4159 return 0;
4160 }
4161
4162 arm_reg ptr_reg = is->insn->detail->arm.operands[0].reg;
4163
4164 save_misc_val(rule->name,pal_base,0,(uint32_t)is->insn->address);
4165
4166 int found=0;
4167
4168 for(i=0; i<3; i++) {
4169 if(!disasm_iter(fw,is)) {
4170 printf("sig_match_palette_vars: disasm failed\n");
4171 return 0;
4172 }
4173 if (is->insn->id == ARM_INS_LDR && is->insn->detail->arm.operands[1].mem.base == ptr_reg) {
4174 save_misc_val("active_palette_buffer",
4175 pal_base,
4176 is->insn->detail->arm.operands[1].mem.disp,
4177 (uint32_t)is->insn->address);
4178 found=1;
4179 break;
4180 }
4181 }
4182 if(!found) {
4183 printf("sig_match_palette_vars: no match active_palette_buffer 0x%"PRIx64"\n",is->insn->address);
4184 return 0;
4185 }
4186
4187 if(!find_next_sig_call(fw,is,20,"PTM_RestoreUIProperty_FW")) {
4188 printf("sig_match_palette_vars: no match PTM_RestoreUIProperty_FW\n");
4189 return 0;
4190 }
4191
4192 for(i=0; i<6; i++) {
4193 if(!disasm_iter(fw,is)) {
4194 printf("sig_match_palette_vars: disasm failed\n");
4195 return 0;
4196 }
4197 if (is->insn->id == ARM_INS_LDR && is->insn->detail->arm.operands[1].mem.base == ptr_reg) {
4198 save_misc_val("palette_buffer_ptr",
4199 pal_base,
4200 is->insn->detail->arm.operands[1].mem.disp,
4201 (uint32_t)is->insn->address);
4202 return 1;
4203 }
4204 }
4205 printf("sig_match_palette_vars: no match palette_buffer_ptr 0x%"PRIx64"\n",is->insn->address);
4206 return 0;
4207 }
4208
4209 int sig_match_rom_ptr_get(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4210 {
4211 if(!init_disasm_sig_ref(fw,is,rule)) {
4212 return 0;
4213 }
4214 uint32_t fadr=is->adr;
4215 if(!disasm_iter(fw,is)) {
4216 printf("sig_match_rom_ptr_get: disasm failed\n");
4217 return 0;
4218 }
4219 uint32_t adr=LDR_PC2val(fw,is->insn);
4220 if(!adr) {
4221 printf("sig_match_rom_ptr_get: no match LDR PC 0x%"PRIx64"\n",is->insn->address);
4222 return 0;
4223 }
4224 if(is->insn->detail->arm.operands[0].reg != ARM_REG_R0) {
4225 printf("sig_match_rom_ptr_get: not R0\n");
4226 return 0;
4227 }
4228 if(!disasm_iter(fw,is)) {
4229 printf("sig_match_rom_ptr_get: disasm failed\n");
4230 return 0;
4231 }
4232
4233 if(!insn_match(is->insn,match_bxlr)) {
4234 printf("sig_match_rom_ptr_get: no match BX LR\n");
4235 return 0;
4236 }
4237 save_misc_val(rule->name,adr,0,fadr);
4238 return 1;
4239 }
4240
4241
4242
4243
4244 uint32_t find_call_near_str(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4245 {
4246 uint32_t str_adr;
4247 if(rule->param & SIG_NEAR_INDIRECT) {
4248 str_adr = find_str_bytes(fw,rule->ref_name);
4249 } else {
4250 str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
4251 }
4252 if(!str_adr) {
4253 printf("find_call_near_str: %s failed to find ref %s\n",rule->name,rule->ref_name);
4254 return 0;
4255 }
4256 uint32_t search_adr = str_adr;
4257
4258
4259 if(rule->param & SIG_NEAR_INDIRECT) {
4260
4261 search_adr=find_u32_adr_range(fw,str_adr,fw->rom_code_search_min_adr,fw->rom_code_search_max_adr);
4262 if(!search_adr) {
4263 printf("find_call_near_str: %s failed to find indirect ref %s\n",rule->name,rule->ref_name);
4264 return 0;
4265 }
4266
4267 }
4268 const insn_match_t *insn_match;
4269 if(rule->param & SIG_NEAR_JMP_SUB) {
4270 insn_match = match_b_bl_blximm;
4271 } else {
4272 insn_match = match_bl_blximm;
4273 }
4274
4275 int max_insns=rule->param&SIG_NEAR_OFFSET_MASK;
4276 int n=(rule->param&SIG_NEAR_COUNT_MASK)>>SIG_NEAR_COUNT_SHIFT;
4277
4278
4279 disasm_iter_init(fw,is,(ADR_ALIGN4(search_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
4280 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,search_adr+SEARCH_NEAR_REF_RANGE)) {
4281
4282 if(rule->param & SIG_NEAR_REV) {
4283 int i;
4284 int n_calls=0;
4285 for(i=1; i<=max_insns; i++) {
4286 fw_disasm_iter_single(fw,adr_hist_get(&is->ah,i));
4287 if(insn_match_any(fw->is->insn,insn_match)) {
4288 n_calls++;
4289 }
4290 if(n_calls == n) {
4291 return iter_state_adr(fw->is);
4292 }
4293 }
4294 } else {
4295 if(insn_match_find_nth(fw,is,max_insns,n,insn_match)) {
4296 return iter_state_adr(is);
4297 }
4298 }
4299 }
4300 printf("find_call_near_str: no match %s\n",rule->name);
4301 return 0;
4302 }
4303
4304
4305 int sig_match_near_str(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4306 {
4307 if (!get_saved_sig_val(rule->name))
4308 {
4309 uint32_t call_adr = find_call_near_str(fw,is,rule);
4310 if(call_adr) {
4311 return save_sig_match_call(fw, rule, call_adr);
4312 }
4313 }
4314 return 0;
4315 }
4316
4317
4318 int sig_match_prop_string(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4319 {
4320 uint32_t call_adr = find_call_near_str(fw, is, rule);
4321
4322 if (call_adr == 0)
4323 return 0;
4324
4325
4326 disasm_iter_init(fw,is,call_adr);
4327 disasm_iter(fw,is);
4328
4329 uint32_t myreg;
4330
4331 if (is_sig_call(fw,is,"GetPropertyCase")) {
4332
4333 myreg = 0;
4334 }
4335 else {
4336
4337 myreg = 1;
4338 }
4339
4340
4341 const int hl = 8;
4342 disasm_iter_init(fw,is,call_adr - hl*4);
4343
4344 while (is->adr < call_adr) {
4345 if (!disasm_iter(fw,is))
4346 disasm_iter_init(fw,is,(is->adr | is->thumb)+2);
4347 }
4348 uint32_t regs[4];
4349
4350 if ((get_call_const_args(fw,is,hl,regs)&(1<<myreg))==(1<<myreg)) {
4351 add_prop_hit(rule->name,(int)regs[myreg]);
4352 return 1;
4353 }
4354 return 0;
4355 }
4356
4357
4358
4359 int is_immediate_ret_sub(firmware *fw,iter_state_t *is_init)
4360 {
4361 fw_disasm_iter_single(fw,is_init->adr | is_init->thumb);
4362 const insn_match_t match_mov_r0_imm[]={
4363 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM_ANY}},
4364 #if CS_API_MAJOR < 4
4365 {MATCH_INS(MOVS, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM_ANY}},
4366 #endif
4367 {ARM_INS_ENDING}
4368 };
4369
4370 if(insn_match_any(fw->is->insn,match_mov_r0_imm)) {
4371 fw_disasm_iter(fw);
4372 }
4373 if(isRETx(fw->is->insn)) {
4374 return 1;
4375 }
4376 return 0;
4377 }
4378
4379
4380
4381
4382
4383
4384
4385 #define SIG_NAMED_LAST_MAX_MASK 0x00000FFF
4386 #define SIG_NAMED_LAST_MIN_MASK 0x00FFF000
4387 #define SIG_NAMED_LAST_MIN_SHIFT 12
4388 #define SIG_NAMED_LAST_RANGE(min,max) ((SIG_NAMED_LAST_MIN_MASK&((min)<<SIG_NAMED_LAST_MIN_SHIFT)) \
4389 | (SIG_NAMED_LAST_MAX_MASK&(max)))
4390
4391 int sig_match_named_last(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4392 {
4393 uint32_t ref_adr = get_saved_sig_val(rule->ref_name);
4394 int min = (rule->param&SIG_NAMED_LAST_MIN_MASK)>>SIG_NAMED_LAST_MIN_SHIFT;
4395 int max = (rule->param&SIG_NAMED_LAST_MAX_MASK);
4396 if(!ref_adr) {
4397 printf("sig_match_named_last: %s missing %s\n",rule->name,rule->ref_name);
4398 return 0;
4399 }
4400 disasm_iter_init(fw,is,ref_adr);
4401 if(is_immediate_ret_sub(fw,is)) {
4402 printf("sig_match_named_last: immediate return %s\n",rule->name);
4403 return 0;
4404 }
4405 uint32_t fadr = find_last_call_from_func(fw,is,min,max);
4406 if(fadr) {
4407 return save_sig_with_j(fw,rule->name,fadr);
4408 }
4409 return 0;
4410 }
4411
4412
4413 #define SIG_NAMED_ASIS 0x00000000
4414
4415 #define SIG_NAMED_JMP_SUB 0x00000001
4416
4417 #define SIG_NAMED_SUB 0x00000002
4418
4419 #define SIG_NAMED_INSN 0x00000003
4420 #define SIG_NAMED_TYPE_MASK 0x0000000F
4421
4422 #define SIG_NAMED_CLEARTHUMB 0x00000010
4423 #define SIG_NAMED_FLAG_MASK 0x000000F0
4424
4425 #define SIG_NAMED_NTH_MASK 0x00000F00
4426 #define SIG_NAMED_NTH_SHIFT 8
4427
4428
4429
4430 #define SIG_NAMED_NTH_RANGE_MASK 0x0003F000
4431 #define SIG_NAMED_NTH_RANGE_SHIFT 12
4432
4433
4434 #define SIG_NAMED_NTH(n,type) ((SIG_NAMED_NTH_MASK&((n)<<SIG_NAMED_NTH_SHIFT)) | (SIG_NAMED_##type))
4435
4436 #define SIG_NAMED_NTH_RANGE(n) ((SIG_NAMED_NTH_RANGE_MASK&((n)<<SIG_NAMED_NTH_RANGE_SHIFT)))
4437
4438 void sig_match_named_save_sig(firmware *fw,const char *name, uint32_t adr, uint32_t flags)
4439 {
4440 if(flags & SIG_NAMED_CLEARTHUMB) {
4441 adr = ADR_CLEAR_THUMB(adr);
4442 }
4443 save_sig(fw,name,adr);
4444 }
4445
4446
4447
4448 int sig_match_named(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4449 {
4450 uint32_t ref_adr = get_saved_sig_val(rule->ref_name);
4451 if(!ref_adr) {
4452 printf("sig_match_named: missing %s\n",rule->ref_name);
4453 return 0;
4454 }
4455 uint32_t sig_type = rule->param & SIG_NAMED_TYPE_MASK;
4456 uint32_t sig_flags = rule->param & SIG_NAMED_FLAG_MASK;
4457 uint32_t sig_nth = (rule->param & SIG_NAMED_NTH_MASK)>>SIG_NAMED_NTH_SHIFT;
4458 uint32_t sig_nth_range = (rule->param & SIG_NAMED_NTH_RANGE_MASK)>>SIG_NAMED_NTH_RANGE_SHIFT;
4459 if(!sig_nth) {
4460 sig_nth=1;
4461 }
4462 if(!sig_nth_range) {
4463 sig_nth_range=5;
4464 }
4465
4466
4467 if(sig_type == SIG_NAMED_ASIS) {
4468 sig_match_named_save_sig(fw,rule->name,ref_adr,sig_flags);
4469 return 1;
4470 }
4471 const insn_match_t *insn_match;
4472 if(sig_type == SIG_NAMED_JMP_SUB) {
4473 insn_match = match_b_bl_blximm;
4474 } else if(sig_type == SIG_NAMED_SUB) {
4475 insn_match = match_bl_blximm;
4476 } else if(sig_type == SIG_NAMED_INSN) {
4477 insn_match = NULL;
4478 } else {
4479 printf("sig_match_named: %s invalid type %d\n",rule->ref_name,sig_type);
4480 return 0;
4481 }
4482
4483 disasm_iter_init(fw,is,ref_adr);
4484
4485 if(is_immediate_ret_sub(fw,is)) {
4486 printf("sig_match_named: immediate return %s\n",rule->name);
4487 return 0;
4488 }
4489 if(sig_type == SIG_NAMED_INSN) {
4490 uint32_t i;
4491
4492 for(i=0;i<=sig_nth;i++) {
4493 if(!disasm_iter(fw,is)) {
4494 printf("sig_match_named: disasm failed %s 0x%08x\n",rule->name,(uint32_t)is->insn->address);
4495 return 0;
4496 }
4497 }
4498 sig_match_named_save_sig(fw,rule->name,iter_state_adr(is),sig_flags);
4499 return 1;
4500 }
4501
4502
4503 if(insn_match_find_nth(fw,is,15 + sig_nth_range*sig_nth,sig_nth,insn_match)) {
4504 uint32_t adr = B_BL_BLXimm_target(fw,is->insn);
4505 if(adr) {
4506
4507 if(is->insn->id == ARM_INS_BLX) {
4508
4509 if(!is->thumb) {
4510 adr=ADR_SET_THUMB(adr);
4511 }
4512 } else {
4513
4514 adr |= is->thumb;
4515 }
4516 disasm_iter_set(fw,is,adr);
4517 if(disasm_iter(fw,is)) {
4518
4519 uint32_t j_adr=get_direct_jump_target(fw,is);
4520 if(j_adr) {
4521 char *buf=malloc(strlen(rule->name)+3);
4522
4523 sprintf(buf,"j_%s",rule->name);
4524 add_func_name(fw,buf,adr,NULL);
4525 adr=j_adr;
4526 }
4527 } else {
4528 printf("sig_match_named: disasm failed in j_ check at %s 0x%08x\n",rule->name,adr);
4529 }
4530 sig_match_named_save_sig(fw,rule->name,adr,sig_flags);
4531 return 1;
4532 } else {
4533 printf("sig_match_named: %s invalid branch target 0x%08x\n",rule->ref_name,adr);
4534 }
4535 } else {
4536 printf("sig_match_named: %s branch not found 0x%08x\n",rule->ref_name,ref_adr);
4537 }
4538 return 0;
4539 }
4540
4541 #define SIG_DRY_MIN(min_rel) (min_rel),0
4542 #define SIG_DRY_MAX(max_rel) 0,(max_rel)
4543 #define SIG_DRY_RANGE(min_rel,max_rel) (min_rel),(max_rel)
4544
4545
4546
4547 sig_rule_t sig_rules_initial[]={
4548
4549
4550 {sig_match_str_r0_call, "ExportToEventProcedure_FW","ExportToEventProcedure"},
4551 {sig_match_reg_evp, "RegisterEventProcedure",},
4552 {sig_match_reg_evp_table, "RegisterEventProcTable","DispDev_EnableEventProc"},
4553 {sig_match_reg_evp_alt2, "RegisterEventProcedure_alt2","EngApp.Delete"},
4554 {sig_match_unreg_evp_table,"UnRegisterEventProcTable","MechaUnRegisterEventProcedure"},
4555 {sig_match_evp_table_veneer,"RegisterEventProcTable_alt","RegisterEventProcTable"},
4556 {sig_match_evp_table_veneer,"UnRegisterEventProcTable_alt","UnRegisterEventProcTable"},
4557 {sig_match_str_r0_call,"CreateTaskStrictly", "LowConsole",},
4558 {sig_match_str_r0_call,"CreateTaskStrictly_alt","HdmiCecTask", 0, SIG_DRY_MIN(59)},
4559 {sig_match_str_r0_call,"CreateTask", "EvShel",},
4560 {sig_match_str_r0_call,"CreateTask_alt", "PhySw", 0, SIG_DRY_MIN(58)},
4561 {sig_match_named, "CreateTask_low", "CreateTask", (SIG_NAMED_NTH(2,SUB)|SIG_NAMED_NTH_RANGE(10)), SIG_DRY_MAX(52)},
4562 {sig_match_named, "CreateTask_low", "CreateTask", (SIG_NAMED_NTH(3,SUB)|SIG_NAMED_NTH_RANGE(10)), SIG_DRY_MIN(54)},
4563 {sig_match_near_str, "dry_memcpy", "EP Slot%d", SIG_NEAR_BEFORE(4,1)},
4564 {sig_match_add_ptp_handler,"add_ptp_handler", "PTPtoFAPI_EventProcTask_Try",},
4565 {NULL},
4566 };
4567
4568
4569
4570 sig_rule_t sig_rules_main[]={
4571
4572 {sig_match_named, "SetParameterData", "PTM_BackupUIProperty_FW", 0, SIG_DRY_MIN(58)},
4573 {sig_match_named, "ExitTask", "ExitTask_FW",},
4574 {sig_match_named, "EngDrvRead", "EngDrvRead_FW", SIG_NAMED_JMP_SUB},
4575 {sig_match_named, "CalcLog10", "CalcLog10_FW", SIG_NAMED_JMP_SUB},
4576 {sig_match_named, "CalcSqrt", "CalcSqrt_FW", SIG_NAMED_JMP_SUB},
4577 {sig_match_named, "Close", "Close_FW",},
4578 {sig_match_named, "close", "Close", SIG_NAMED_SUB, SIG_DRY_MAX(57)},
4579 {sig_match_named, "DoAELock", "SS.DoAELock_FW", SIG_NAMED_JMP_SUB},
4580 {sig_match_named, "DoAFLock", "SS.DoAFLock_FW", SIG_NAMED_JMP_SUB},
4581 {sig_match_named, "Fclose_Fut", "Fclose_Fut_FW",},
4582 {sig_match_named, "Fopen_Fut", "Fopen_Fut_FW",},
4583 {sig_match_named, "Fread_Fut", "Fread_Fut_FW",},
4584 {sig_match_named, "Fseek_Fut", "Fseek_Fut_FW",},
4585 {sig_match_named, "Fwrite_Fut", "Fwrite_Fut_FW",},
4586 {sig_match_named, "GetAdChValue", "GetAdChValue_FW",},
4587 {sig_match_named, "GetCurrentAvValue", "GetCurrentAvValue_FW",},
4588 {sig_match_named, "GetCurrentShutterSpeed", "GetCurrentShutterSpeed_FW",},
4589 {sig_match_named, "GetBatteryTemperature", "GetBatteryTemperature_FW",},
4590 {sig_match_named, "GetCCDTemperature", "GetCCDTemperature_FW",},
4591 {sig_match_named, "GetFocusLensSubjectDistance","GetFocusLensSubjectDistance_FW",SIG_NAMED_JMP_SUB},
4592 {sig_match_named, "GetOpticalTemperature", "GetOpticalTemperature_FW",},
4593 {sig_match_named, "GetPropertyCase", "GetPropertyCase_FW", SIG_NAMED_SUB},
4594 {sig_match_named, "GetSystemTime", "GetSystemTime_FW",},
4595 {sig_match_named, "GetUsableMaxAv", "GetUsableMaxAv_FW",},
4596 {sig_match_named, "GetUsableMinAv", "GetUsableMinAv_FW",},
4597
4598 {sig_match_named, "GetUsableAvRange", "GetUsableMinAv", SIG_NAMED_SUB},
4599 {sig_match_named, "GetVRAMHPixelsSize", "GetVRAMHPixelsSize_FW",},
4600 {sig_match_named, "GetVRAMVPixelsSize", "GetVRAMVPixelsSize_FW",},
4601 {sig_match_named, "GetZoomLensCurrentPoint", "GetZoomLensCurrentPoint_FW",},
4602 {sig_match_named, "GetZoomLensCurrentPosition","GetZoomLensCurrentPosition_FW",},
4603 {sig_match_named, "GiveSemaphore", "GiveSemaphore_FW",},
4604 {sig_match_named, "IsStrobeChargeCompleted", "EF.IsChargeFull_FW",},
4605 {sig_match_named, "Read", "Read_FW",},
4606 {sig_match_named, "LEDDrive", "LEDDrive_FW",},
4607 {sig_match_named, "LockMainPower", "LockMainPower_FW",},
4608 {sig_match_named, "MoveFocusLensToDistance", "MoveFocusLensToDistance_FW",},
4609 {sig_match_named, "MoveIrisWithAv", "MoveIrisWithAv_FW",},
4610 {sig_match_named, "MoveZoomLensWithPoint", "MoveZoomLensWithPoint_FW",},
4611 {sig_match_named, "Open", "Open_FW",},
4612 {sig_match_named, "PostLogicalEventForNotPowerType", "PostLogicalEventForNotPowerType_FW",},
4613 {sig_match_named, "PostLogicalEventToUI", "PostLogicalEventToUI_FW",},
4614 {sig_match_named, "PT_MFOn", "SS.MFOn_FW", SIG_NAMED_JMP_SUB},
4615 {sig_match_named, "PT_MFOff", "SS.MFOff_FW", SIG_NAMED_JMP_SUB},
4616 {sig_match_named, "PT_MoveDigitalZoomToWide", "SS.MoveDigitalZoomToWide_FW", SIG_NAMED_JMP_SUB},
4617 {sig_match_named, "PT_MoveOpticalZoomAt", "SS.MoveOpticalZoomAt_FW",},
4618 {sig_match_named, "PutInNdFilter", "PutInNdFilter_FW",},
4619 {sig_match_named, "PutOutNdFilter", "PutOutNdFilter_FW",},
4620 {sig_match_named, "SetAE_ShutterSpeed", "SetAE_ShutterSpeed_FW",},
4621 {sig_match_named, "SetAutoShutdownTime", "SetAutoShutdownTime_FW",},
4622 {sig_match_named, "SetCurrentCaptureModeType","SetCurrentCaptureModeType_FW",},
4623 {sig_match_named, "SetDate", "SetDate_FW",},
4624 {sig_match_named, "SetLogicalEventActive", "UiEvnt_SetLogicalEventActive_FW",},
4625 {sig_match_named, "SetScriptMode", "SetScriptMode_FW",},
4626 {sig_match_named, "SleepTask", "SleepTask_FW",},
4627 {sig_match_named, "SetPropertyCase", "SetPropertyCase_FW", SIG_NAMED_SUB},
4628 {sig_match_named, "TakeSemaphore", "TakeSemaphore_FW",},
4629 {sig_match_named, "TurnOnDisplay", "DispCon_TurnOnDisplay_FW",SIG_NAMED_SUB},
4630 {sig_match_named, "TurnOffDisplay", "DispCon_TurnOffDisplay_FW",SIG_NAMED_SUB},
4631 {sig_match_named, "TurnOnBackLight", "DispCon_TurnOnBackLight_FW",SIG_NAMED_SUB, SIG_DRY_MAX(57)},
4632 {sig_match_named, "TurnOffBackLight", "DispCon_TurnOffBackLight_FW",SIG_NAMED_SUB},
4633 {sig_match_named, "UIFS_WriteFirmInfoToFile", "UIFS_WriteFirmInfoToFile_FW",},
4634 {sig_match_named, "UnlockAE", "SS.UnlockAE_FW", SIG_NAMED_JMP_SUB},
4635 {sig_match_named, "UnlockAF", "SS.UnlockAF_FW", SIG_NAMED_JMP_SU