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_SUB},
4636 {sig_match_named, "UnlockMainPower", "UnlockMainPower_FW",},
4637 {sig_match_named, "UnRegisterEventProcedure", "UnRegisterEventProcTable", SIG_NAMED_SUB},
4638
4639 {sig_match_named, "VbattGet", "VbattGet_FW",},
4640 {sig_match_named, "Write", "Write_FW",},
4641 {sig_match_named, "bzero", "exec_FW", SIG_NAMED_SUB},
4642 {sig_match_named, "exmem_free", "ExMem.FreeCacheable_FW",SIG_NAMED_JMP_SUB},
4643 {sig_match_named, "exmem_alloc", "ExMem.AllocCacheable_FW",SIG_NAMED_JMP_SUB},
4644 {sig_match_named, "exmem_ufree", "ExMem.FreeUncacheable_FW",SIG_NAMED_JMP_SUB},
4645 {sig_match_named, "exmem_ualloc", "ExMem.AllocUncacheable_FW",SIG_NAMED_JMP_SUB},
4646 {sig_match_named, "free", "FreeMemory_FW", SIG_NAMED_JMP_SUB},
4647 {sig_match_named, "lseek", "Lseek_FW",},
4648 {sig_match_named, "_log10", "CalcLog10", SIG_NAMED_NTH(2,SUB)},
4649 {sig_match_named, "malloc", "AllocateMemory_FW", SIG_NAMED_JMP_SUB},
4650 {sig_match_named, "memcmp", "memcmp_FW",},
4651 {sig_match_named, "memcpy", "memcpy_FW",},
4652 {sig_match_named, "memset", "memset_FW",},
4653 {sig_match_named, "strcmp", "strcmp_FW",},
4654 {sig_match_named, "strcpy", "strcpy_FW",},
4655 {sig_match_named, "strlen", "strlen_FW",},
4656 {sig_match_named, "task_CaptSeq", "task_CaptSeqTask",},
4657 {sig_match_named, "task_ExpDrv", "task_ExpDrvTask",},
4658 {sig_match_named, "task_FileWrite", "task_FileWriteTask",},
4659
4660
4661 {sig_match_named, "vsprintf", "sprintf_FW", SIG_NAMED_SUB},
4662 {sig_match_named, "PTM_GetCurrentItem", "PTM_GetCurrentItem_FW",},
4663 {sig_match_named, "DisableISDriveError", "DisableISDriveError_FW",},
4664 {sig_match_named, "hook_CreateTask", "CreateTask", SIG_NAMED_CLEARTHUMB},
4665
4666 {sig_match_named, "hook_CreateTask_low", "CreateTask_low", SIG_NAMED_CLEARTHUMB},
4667 {sig_match_named, "malloc_strictly", "task_EvShel", SIG_NAMED_NTH(2,SUB)},
4668 {sig_match_named, "DebugAssert2", "malloc_strictly", SIG_NAMED_NTH(3,SUB)},
4669 {sig_match_named, "AcquireRecursiveLockStrictly","StartWDT_FW", SIG_NAMED_NTH(1,SUB)},
4670 {sig_match_named, "CheckAllEventFlag", "ChargeStrobeForFA_FW", SIG_NAMED_SUB},
4671 {sig_match_named, "ClearEventFlag", "GetAEIntegralValueWithFix_FW",SIG_NAMED_SUB},
4672 {sig_match_named, "CheckAnyEventFlag", "task_SynchTask", SIG_NAMED_NTH(2,SUB)},
4673 {sig_match_named, "taskcreate_LowConsole", "task_EvShel", SIG_NAMED_SUB},
4674 {sig_match_named, "CreateMessageQueueStrictly","taskcreate_LowConsole",SIG_NAMED_SUB},
4675 {sig_match_named, "CreateBinarySemaphoreStrictly","taskcreate_LowConsole",SIG_NAMED_NTH(2,SUB)},
4676 {sig_match_named, "PostMessageQueue", "GetCh_FW", SIG_NAMED_NTH(2,SUB)},
4677 {sig_match_named, "CreateEventFlagStrictly", "InitializeDigicon_FW", SIG_NAMED_SUB},
4678 {sig_match_named, "WaitForAnyEventFlag", "task_DPOFTask", SIG_NAMED_SUB},
4679 {sig_match_named, "GetEventFlagValue", "task_DPOFTask", SIG_NAMED_NTH(2,SUB)},
4680 {sig_match_named, "CreateBinarySemaphore", "task_UartLog", SIG_NAMED_SUB},
4681 {sig_match_named, "PostMessageQueueStrictly", "EF.IsChargeFull_FW", SIG_NAMED_SUB},
4682 {sig_match_named, "SetEventFlag", "StopStrobeChargeForFA_FW",SIG_NAMED_SUB},
4683 {sig_match_named, "TryReceiveMessageQueue", "task_DvlpSeqTask", SIG_NAMED_NTH(3,SUB)},
4684
4685 {sig_match_named, "TakeSemaphore", "task_Bye", SIG_NAMED_SUB},
4686 {sig_match_named_last,"GiveSemaphore", "TurnOnVideoOutMode_FW",SIG_NAMED_LAST_RANGE(10,24)},
4687
4688 {sig_match_named, "givesemaphore_low", "GiveSemaphore", SIG_NAMED_SUB, SIG_DRY_MAX(52)},
4689 {sig_match_named, "givesemaphore_low", "GiveSemaphore", SIG_NAMED_NTH(2,SUB),SIG_DRY_MIN(53)},
4690
4691
4692 {sig_match_named, "ReleaseRecursiveLock", "StartWDT_FW", SIG_NAMED_NTH(2,SUB)},
4693 {sig_match_named, "MoveOpticalZoomAt", "SS.MoveOpticalZoomAt_FW",SIG_NAMED_SUB},
4694 {sig_match_named, "SetVideoOutType", "SetVideoOutType_FW",SIG_NAMED_SUB},
4695 {sig_match_named, "GetVideoOutType", "GetVideoOutType_FW"},
4696
4697 {sig_match_near_str,"bzero", "Canon Degital Camera",SIG_NEAR_AFTER(8,2)|SIG_NEAR_INDIRECT},
4698
4699 {sig_match_named, "memset32", "bzero", SIG_NAMED_NTH(1,INSN)},
4700 {sig_match_misc_flag_named,"CAM_IS_ILC", "task_EFLensComTask",},
4701 {sig_match_misc_flag_named,"CAM_HAS_ND_FILTER", "task_Nd",},
4702 {sig_match_cam_has_iris_diaphragm,"CAM_HAS_IRIS_DIAPHRAGM","task_IrisEvent",},
4703 {sig_match_near_str,"ImagerActivate", "Fail ImagerActivate(ErrorCode:%x)\r",SIG_NEAR_BEFORE(6,1)},
4704 {sig_match_screenlock_helper,"screenlock_helper","UIFS_DisplayFirmUpdateView_FW"},
4705 {sig_match_named, "ScreenLock", "screenlock_helper",SIG_NAMED_SUB},
4706
4707 {sig_match_screenunlock,"ScreenUnlock", "screenlock_helper", 0,SIG_DRY_MAX(55)},
4708 {sig_match_near_str,"ScreenUnlock", "PB._ErrorRef", SIG_NEAR_AFTER(8,2)|SIG_NEAR_JMP_SUB,SIG_DRY_RANGE(57,58)},
4709 {sig_match_near_str,"ScreenUnlock", "PB._ErrorRef:SI", SIG_NEAR_AFTER(8,2)|SIG_NEAR_JMP_SUB,SIG_DRY_MIN(59)},
4710 {sig_match_log_camera_event,"LogCameraEvent", "task_StartupImage",},
4711 {sig_match_physw_misc, "physw_misc", "task_PhySw"},
4712 {sig_match_kbd_read_keys, "kbd_read_keys", "kbd_p1_f"},
4713 {sig_match_get_kbd_state, "GetKbdState", "kbd_read_keys"},
4714 {sig_match_create_jumptable, "CreateJumptable", "InitializeAdjustmentSystem_FW"},
4715 {sig_match_take_semaphore_strict, "TakeSemaphoreStrictly","Fopen_Fut"},
4716 {sig_match_get_semaphore_value,"GetSemaphoreValue","\tRaw[%i]"},
4717 {sig_match_stat, "stat", "A/uartr.req"},
4718 {sig_match_open, "open", "Open_FW", 0, SIG_DRY_MAX(57)},
4719 {sig_match_open_gt_57,"open", "Open_FW", 0, SIG_DRY_MIN(58)},
4720
4721 {sig_match_close_gt_57,"close", "Close_FW", 0, SIG_DRY_MIN(58)},
4722 {sig_match_umalloc, "AllocateUncacheableMemory","Fopen_Fut_FW"},
4723 {sig_match_ufree, "FreeUncacheableMemory", "Fclose_Fut_FW"},
4724 {sig_match_cam_uncached_bit,"CAM_UNCACHED_BIT", "FreeUncacheableMemory"},
4725 {sig_match_deletefile_fut,"DeleteFile_Fut", "Get Err TempPath"},
4726 {sig_match_near_str,"createsemaphore_low", "intr_sem", SIG_NEAR_AFTER(3,1)},
4727
4728 {sig_match_near_str,"takesemaphore_low", "sem_test_callback", SIG_NEAR_AFTER(12,2)},
4729
4730 {sig_match_near_str,"AcquireRecursiveLock", "not executed\n",SIG_NEAR_BEFORE(20,3)},
4731 {sig_match_near_str,"CreateCountingSemaphoreStrictly","DvlpSeqTask", SIG_NEAR_BEFORE(18,3)},
4732 {sig_match_near_str,"CreateMessageQueue", "CreateMessageQueue:%ld",SIG_NEAR_BEFORE(7,1)},
4733 {sig_match_near_str,"CreateEventFlag", "CreateEventFlag:%ld", SIG_NEAR_BEFORE(7,1),SIG_DRY_MAX(57)},
4734 {sig_match_near_str,"CreateEventFlag", "CreateEventFlag:%ld", SIG_NEAR_BEFORE(9,1),SIG_DRY_MIN(58)},
4735 {sig_match_near_str,"CreateRecursiveLock", "WdtInt", SIG_NEAR_BEFORE(9,1)},
4736 {sig_match_near_str,"CreateRecursiveLockStrictly","LoadedScript", SIG_NEAR_AFTER(6,2)},
4737 {sig_match_near_str,"DeleteMessageQueue", "DeleteMessageQueue(%d) is FAILURE",SIG_NEAR_BEFORE(10,1)},
4738 {sig_match_near_str,"DeleteEventFlag", "DeleteEventFlag(%d) is FAILURE",SIG_NEAR_BEFORE(10,1)},
4739 {sig_match_near_str,"ReceiveMessageQueue", "ReceiveMessageQue:%d", SIG_NEAR_BEFORE(9,1)},
4740 {sig_match_near_str,"RegisterInterruptHandler", "WdtInt", SIG_NEAR_AFTER(3,1)},
4741 {sig_match_near_str,"TryPostMessageQueue", "TryPostMessageQueue(%d)\n",SIG_NEAR_BEFORE(9,1),SIG_DRY_MAX(52)},
4742
4743 {sig_match_near_str,"TryPostMessageQueue", "[CWS]TryPostMessageQueue(%d) Failed\n",SIG_NEAR_BEFORE(9,1)},
4744 {sig_match_near_str,"TryTakeSemaphore", "FileScheduleTask", SIG_NEAR_AFTER(10,2),SIG_DRY_MAX(58)},
4745 {sig_match_try_take_sem_dry_gt_58,"TryTakeSemaphore","task_ImageStoreTask",0,SIG_DRY_MIN(59)},
4746
4747 {sig_match_named, "takesemaphore_low", "TryTakeSemaphore", SIG_NAMED_SUB},
4748 {sig_match_near_str,"WaitForAllEventFlag", "Error WaitEvent PREPARE_TESTREC_EXECUTED.", SIG_NEAR_BEFORE(5,1)},
4749 {sig_match_near_str,"WaitForAnyEventFlagStrictly","_imageSensorTask", SIG_NEAR_AFTER(10,2)},
4750 {sig_match_wait_all_eventflag_strict,"WaitForAllEventFlagStrictly","EF.StartInternalMainFlash_FW"},
4751 {sig_match_near_str,"DeleteSemaphore", "DeleteSemaphore passed",SIG_NEAR_BEFORE(3,1)},
4752 {sig_match_get_num_posted_messages,"GetNumberOfPostedMessages","task_CtgTotalTask"},
4753 {sig_match_near_str,"LocalTime", "%Y-%m-%dT%H:%M:%S", SIG_NEAR_BEFORE(5,1),SIG_DRY_MAX(58)},
4754 {sig_match_near_str,"LocalTime", "%Y.%m.%d %H:%M:%S", SIG_NEAR_BEFORE(5,1)},
4755 {sig_match_near_str,"strftime", "%Y/%m/%d %H:%M:%S", SIG_NEAR_AFTER(3,1)},
4756 {sig_match_near_str,"OpenFastDir", "OpenFastDir_ERROR\n", SIG_NEAR_BEFORE(5,1)},
4757 {sig_match_readfastdir,"ReadFastDir", "ReadFast_ERROR\n", SIG_NEAR_BEFORE(24,1)},
4758 {sig_match_near_str,"PT_PlaySound", "BufAccBeep", SIG_NEAR_AFTER(7,2)|SIG_NEAR_JMP_SUB,SIG_DRY_MAX(58)},
4759
4760 {sig_match_near_str,"PT_PlaySound", "PB._PMenuCBR", SIG_NEAR_BEFORE(7,3),SIG_DRY_MIN(59)},
4761 {sig_match_closedir,"closedir", "ReadFast_ERROR\n", SIG_NEAR_AFTER(1,1)},
4762 {sig_match_strrchr,"strrchr", "ReadFast_ERROR\n", SIG_NEAR_AFTER(9,2)},
4763 {sig_match_strrchr,"strrchr", "ReadFast_ERROR\n", SIG_NEAR_BEFORE(18,4)},
4764 {sig_match_time, "time", "<UseAreaSize> DataWidth : %d , DataHeight : %d\r\n",},
4765 {sig_match_near_str,"strcat", "String can't be displayed; no more space in buffer",SIG_NEAR_AFTER(5,2)},
4766 {sig_match_near_str,"strchr", "-._~",SIG_NEAR_AFTER(4,1)},
4767 {sig_match_strncpy, "strncpy", "UnRegisterEventProcedure",},
4768 {sig_match_strncmp, "strncmp", "EXFAT ",},
4769 {sig_match_strtolx, "strtolx", "CheckSumAll_FW",},
4770 {sig_match_near_str,"strtol", "prio <task ID> <priority>\n",SIG_NEAR_AFTER(7,1)},
4771 {sig_match_exec_evp,"ExecuteEventProcedure", "Can not Execute "},
4772 {sig_match_fgets_fut,"Fgets_Fut", "CheckSumAll_FW",},
4773 {sig_match_log, "_log", "_log10",},
4774 {sig_match_pow_dry_52,"_pow", "GetDefectTvAdj_FW", 0, SIG_DRY_MAX(52)},
4775 {sig_match_pow_dry_gt_52,"_pow", "GetDefectTvAdj_FW", 0, SIG_DRY_MIN(53)},
4776 {sig_match_sqrt, "_sqrt", "CalcSqrt",},
4777 {sig_match_named, "get_fstype", "OpenFastDir", SIG_NAMED_NTH(2,SUB)},
4778 {sig_match_near_str,"GetMemInfo", " -- refusing to print malloc information.\n",SIG_NEAR_AFTER(7,2)},
4779 {sig_match_get_drive_cluster_size,"GetDrive_ClusterSize","OpLog.WriteToSD_FW",},
4780 {sig_match_mktime_ext,"mktime_ext", "%04d%02d%02dT%02d%02d%02d.%01d",},
4781 {sig_match_near_str,"PB2Rec", "AC:ActionP2R Fail", SIG_NEAR_BEFORE(6,1)},
4782 {sig_match_rec2pb, "Rec2PB", "_EnrySRec",},
4783
4784 {sig_match_get_parameter_data,"GetParameterData","PTM_RestoreUIProperty_FW",},
4785 {sig_match_prepdir_1,"PrepareDirectory_1", "<OpenFileWithDir> PrepareDirectory NG\r\n",SIG_NEAR_BEFORE(7,1)},
4786 {sig_match_prepdir_x,"PrepareDirectory_x", "PrepareDirectory_1",},
4787 {sig_match_prepdir_0,"PrepareDirectory_0", "PrepareDirectory_1",},
4788 {sig_match_mkdir, "MakeDirectory_Fut", "PrepareDirectory_x",},
4789
4790
4791 {sig_match_qsort, "qsort", "task_MetaCtg",},
4792 {sig_match_deletedirectory_fut,"DeleteDirectory_Fut","RedEyeController.c",},
4793 {sig_match_set_control_event,"set_control_event","LogicalEvent:0x%04x:adr:%p,Para:%ld",},
4794
4795 {sig_match_set_control_event,"set_control_event","LogicalEvent:0x%08x:adr:%p,Para:%ld",},
4796 {sig_match_displaybusyonscreen_52,"displaybusyonscreen","_PBBusyScrn", 0, SIG_DRY_MAX(52)},
4797 {sig_match_undisplaybusyonscreen_52,"undisplaybusyonscreen","_PBBusyScrn",0, SIG_DRY_MAX(52)},
4798 {sig_match_near_str,"srand", "Canon Degital Camera",SIG_NEAR_AFTER(14,4)|SIG_NEAR_INDIRECT},
4799 {sig_match_near_str,"rand", "Canon Degital Camera",SIG_NEAR_AFTER(15,5)|SIG_NEAR_INDIRECT},
4800 {sig_match_set_hp_timer_after_now,"SetHPTimerAfterNow","MechaNC.c",},
4801 {sig_match_levent_table,"levent_table", "ShowLogicalEventName_FW",},
4802 {sig_match_flash_param_table,"FlashParamsTable","GetParameterData",},
4803 {sig_match_named, "get_playrec_mode", "task_SsStartupTask", SIG_NAMED_SUB},
4804 {sig_match_var_struct_get,"playrec_mode", "get_playrec_mode",},
4805 {sig_match_jpeg_count_str,"jpeg_count_str", "9999",},
4806 {sig_match_physw_event_table,"physw_event_table","kbd_read_keys_r2",},
4807 {sig_match_uiprop_count,"uiprop_count", "PTM_SetCurrentItem_FW",},
4808 {sig_match_get_canon_mode_list,"get_canon_mode_list","AC:PTM_Init",},
4809 {sig_match_rom_ptr_get,"canon_mode_list", "get_canon_mode_list",},
4810 {sig_match_zoom_busy,"zoom_busy", "ResetZoomLens_FW",},
4811 {sig_match_focus_busy,"focus_busy", "MoveFocusLensToTerminate_FW",},
4812 {sig_match_aram_size,"ARAM_HEAP_SIZE", "AdditionAgentRAM_FW", 0, SIG_DRY_MAX(58)},
4813 {sig_match_aram_size_gt58,"ARAM_HEAP_SIZE", "AdditionAgentRAM_FW", 0, SIG_DRY_MIN(59)},
4814 {sig_match_aram_start,"ARAM_HEAP_START", "AdditionAgentRAM_FW",},
4815 {sig_match_aram_start2,"ARAM_HEAP_START", "AdditionAgentRAM_FW",},
4816 {sig_match__nrflag,"_nrflag", "NRTBL.SetDarkSubType_FW",},
4817 {sig_match_near_str,"transfer_src_overlay_helper","Window_EmergencyRefreshPhysicalScreen",SIG_NEAR_BEFORE(6,1)},
4818 {sig_match_transfer_src_overlay,"transfer_src_overlay","transfer_src_overlay_helper",},
4819 {sig_match_named,"GraphicSystemCoreFinish_helper","transfer_src_overlay",SIG_NAMED_NTH(3,SUB),SIG_DRY_MAX(52)},
4820 {sig_match_named,"GraphicSystemCoreFinish_helper","transfer_src_overlay",SIG_NAMED_NTH(4,SUB),SIG_DRY_RANGE(53,57)},
4821 {sig_match_named,"GraphicSystemCoreFinish_helper","transfer_src_overlay",SIG_NAMED_NTH(5,SUB),SIG_DRY_MIN(58)},
4822
4823
4824 {sig_match_named,"GraphicSystemCoreFinish","GraphicSystemCoreFinish_helper",SIG_NAMED_SUB},
4825 {sig_match_named,"mzrm_createmsg","GraphicSystemCoreFinish",SIG_NAMED_SUB},
4826 {sig_match_named_last,"mzrm_sendmsg","GraphicSystemCoreFinish",SIG_NAMED_LAST_RANGE(10,16)},
4827 {sig_match_zicokick_52,"zicokick_start", "ZicoKick Start\n",0,SIG_DRY_MAX(52)},
4828 {sig_match_zicokick_gt52,"zicokick_start", "ZicoKick Start\n",0,SIG_DRY_MIN(53)},
4829 {sig_match_zicokick_copy,"zicokick_copy", "zicokick_start"},
4830 {sig_match_zicokick_values,"zicokick_values", "zicokick_start"},
4831 {sig_match_init_ex_drivers,"init_ex_drivers", "task_Startup"},
4832 {sig_match_omar_init,"omar_init", "init_ex_drivers"},
4833 {sig_match_enable_hdmi_power,"EnableHDMIPower", "HecHdmiCecPhysicalCheckForScript_FW"},
4834 {sig_match_disable_hdmi_power,"DisableHDMIPower","HecHdmiCecPhysicalCheckForScript_FW"},
4835 {sig_match_get_nd_value,"get_nd_value", "PutInNdFilter",},
4836 {sig_match_get_current_exp,"get_current_exp","ShowCurrentExp_FW",},
4837 {sig_match_get_current_nd_value,"get_current_nd_value","get_current_exp",},
4838 {sig_match_imager_active_callback,"imager_active_callback","ImagerActivate",},
4839 {sig_match_imager_active,"imager_active","imager_active_callback",},
4840 {sig_match_get_dial_hw_position,"get_dial_hw_position","kbd_p1_f",},
4841 {sig_match_near_str,"get_displaytype","DisplayType : %d\r\n",SIG_NEAR_BEFORE(5,1)},
4842 {sig_match_prop_string,"PROPCASE_AFSTEP", "\n\rError : GetAFStepResult",SIG_NEAR_BEFORE(7,1)},
4843 {sig_match_prop_string,"PROPCASE_FOCUS_STATE", "\n\rError : GetAFResult",SIG_NEAR_BEFORE(7,1)},
4844 {sig_match_prop_string,"PROPCASE_AV", "\n\rError : GetAvResult",SIG_NEAR_BEFORE(7,1)},
4845 {sig_match_prop_string,"PROPCASE_BV", "\n\rError : GetBvResult",SIG_NEAR_BEFORE(7,1)},
4846 {sig_match_prop_string,"PROPCASE_DELTA_DIGITALGAIN", "\n\rError : GetDeltaDigitalResult",SIG_NEAR_BEFORE(7,1)},
4847 {sig_match_prop_string,"PROPCASE_DELTA_SV", "\n\rError : GetDeltaGainResult",SIG_NEAR_BEFORE(7,1)},
4848 {sig_match_prop_string,"PROPCASE_DELTA_ND", "\n\rError : GetDeltaNdResult",SIG_NEAR_BEFORE(7,1)},
4849 {sig_match_prop_string,"PROPCASE_EV_CORRECTION_2", "\n\rError : GetRealExposureCompensationResult",SIG_NEAR_BEFORE(7,1)},
4850 {sig_match_prop_string,"PROPCASE_ORIENTATION_SENSOR", "\n\rError : GetRotationAngleResult",SIG_NEAR_BEFORE(7,1)},
4851 {sig_match_prop_string,"PROPCASE_SV_MARKET", "\n\rError : GetSvResult",SIG_NEAR_BEFORE(7,1)},
4852 {sig_match_prop_string,"PROPCASE_SVFIX", "\n\rError : GetSvFixResult",SIG_NEAR_BEFORE(7,1)},
4853 {sig_match_prop_string,"PROPCASE_TV", "\n\rError : GetTvResult",SIG_NEAR_BEFORE(7,1)},
4854 {sig_match_prop_string,"PROPCASE_HSCAPTURE", "GetPropertyFromCase Error [HSCapture]",SIG_NEAR_BEFORE(7,1)},
4855 {sig_match_prop_string,"PROPCASE_FLASH_FIRE", "FlashDecision",SIG_NEAR_BEFORE(7,1)},
4856 {sig_match_prop_string,"PROPCASE_FELOCK", "GetPropertyFromCurrentCase Error [FELock]",SIG_NEAR_BEFORE(7,1)},
4857 {sig_match_prop_string,"PROPCASE_FLASH_ADJUST_MODE", "GetPropertyFromCurrentCase Error [FlashAdjust]",SIG_NEAR_BEFORE(7,1)},
4858 {sig_match_exmem_vars,"exmem_types_table", "ExMem.View_FW"},
4859 {sig_match_av_over_sem,"av_override_semaphore", "MoveIrisWithAv_FW"},
4860 {sig_match_canon_menu_active,"canon_menu_active", "StartRecModeMenu_FW"},
4861 {sig_match_file_counter_init,"file_counter_var_init","task_InitFileModules",},
4862 {sig_match_file_counter_var,"file_counter_var","file_counter_var_init",},
4863 {sig_match_var_struct_get,"displaytype", "get_displaytype",},
4864 {sig_match_palette_vars,"palette_control", "transfer_src_overlay_helper",0,SIG_DRY_MAX(58)},
4865 {NULL},
4866 };
4867
4868 void run_sig_rules(firmware *fw, sig_rule_t *sig_rules)
4869 {
4870 sig_rule_t *rule=sig_rules;
4871
4872 iter_state_t *is=disasm_iter_new(fw,0);
4873 while(rule->match_fn) {
4874 if((rule->dryos_min && fw->dryos_ver < rule->dryos_min)
4875 || (rule->dryos_max && fw->dryos_ver > rule->dryos_max)) {
4876 rule++;
4877 continue;
4878 }
4879
4880
4881 rule->match_fn(fw,is,rule);
4882
4883 rule++;
4884 }
4885 disasm_iter_free(is);
4886 }
4887
4888 void add_event_proc(firmware *fw, char *name, uint32_t adr)
4889 {
4890
4891 if(!ADR_IS_THUMB(adr)) {
4892 printf("add_event_proc: %s is ARM 0x%08x\n",name,adr);
4893 }
4894
4895 if(!fw_disasm_iter_single(fw,adr)) {
4896 printf("add_event_proc: %s disassembly failed at 0x%08x\n",name,adr);
4897 return;
4898 }
4899
4900
4901
4902 uint32_t b_adr=get_direct_jump_target(fw,fw->is);
4903 if(b_adr) {
4904 char *buf=malloc(strlen(name)+6);
4905 sprintf(buf,"j_%s_FW",name);
4906 add_func_name(fw,buf,adr,NULL);
4907
4908 adr=b_adr;
4909 }
4910 add_func_name(fw,name,adr,"_FW");
4911 }
4912
4913
4914 int process_reg_eventproc_call(firmware *fw, iter_state_t *is,uint32_t unused) {
4915 uint32_t regs[4];
4916
4917 if((get_call_const_args(fw,is,4,regs)&3)==3) {
4918
4919 if(isASCIIstring(fw,regs[0])) {
4920 char *nm=(char *)adr2ptr(fw,regs[0]);
4921 add_event_proc(fw,nm,regs[1]);
4922
4923
4924 } else {
4925 printf("eventproc name not string at 0x%"PRIx64"\n",is->insn->address);
4926 }
4927 } else {
4928
4929
4930
4931
4932 uint64_t adr = is->insn->address;
4933 uint32_t adr_thumb = is->thumb;
4934 uint32_t tbla = 0;
4935 int ar = -1;
4936 int found = 0;
4937
4938 disasm_iter_init(fw,is,adr_hist_get(&is->ah,10));
4939
4940 while(1) {
4941 if (!disasm_iter(fw,is)) break;
4942 if (is->insn->address >= adr) break;
4943 if (is->insn->id == ARM_INS_LDR && is->insn->detail->arm.operands[1].type == ARM_OP_MEM) {
4944 uint32_t u = LDR_PC2val(fw,is->insn);
4945 if ((u<fw->base+fw->size8) && (u>adr) && (!isASCIIstring(fw,u))) {
4946 ar = is->insn->detail->arm.operands[0].reg;
4947 tbla = u;
4948 break;
4949 }
4950 }
4951 }
4952
4953 while(ar >= 0) {
4954 if (!disasm_iter(fw,is)) break;
4955 if (is->insn->address >= adr) break;
4956 if (is->insn->id == ARM_INS_ADD && is->insn->detail->arm.operands[1].reg == ar) {
4957 found = 1;
4958
4959 break;
4960 }
4961 }
4962 if (found) {
4963
4964 uint32_t *p=(uint32_t*)adr2ptr_with_data(fw,tbla);
4965 if(p) {
4966 while(*p) {
4967 uint32_t nm_adr=*p;
4968
4969 if (!nm_adr) break;
4970 if(!isASCIIstring(fw,nm_adr)) {
4971 printf("eventproc name not string tbl2 0x%08x 0x%08x\n",tbla,nm_adr);
4972 break;
4973 }
4974 char *nm=(char *)adr2ptr(fw,nm_adr);
4975 p++;
4976 uint32_t fn=*p;
4977 p++;
4978 add_event_proc(fw,nm,fn);
4979 }
4980 } else {
4981 printf("eventproc tbl2 not table 0x%08x\n",tbla);
4982 }
4983 }
4984 else {
4985 printf("failed to get export/register eventproc args at 0x%"PRIx64"\n",adr);
4986 }
4987
4988 disasm_iter_init(fw,is,adr | adr_thumb);
4989 disasm_iter(fw,is);
4990 }
4991 return 0;
4992 }
4993
4994
4995 int process_eventproc_table_call(firmware *fw, iter_state_t *is,uint32_t unused) {
4996 uint32_t regs[4];
4997 int foundr0 = 0;
4998
4999 foundr0 = get_call_const_args(fw,is,4,regs) & 1;
5000 if (!foundr0) {
5001
5002 uint32_t ca = iter_state_adr(is);
5003 uint32_t sa = adr_hist_get(&is->ah,2);
5004 uint32_t ta = adr_hist_get(&is->ah,8);
5005 disasm_iter_set(fw,is,ta);
5006 int n = 0;
5007 while(++n<=(8-2))
5008 {
5009 disasm_iter(fw,is);
5010 }
5011 fw_disasm_iter_single(fw,sa);
5012 uint32_t adr1 = get_saved_sig_val("j_dry_memcpy");
5013 uint32_t adr2 = get_branch_call_insn_target(fw,fw->is);
5014 if (fw->is->insn->id == ARM_INS_BLX && adr1 == adr2) {
5015 foundr0 = get_call_const_args(fw,is,8-2,regs) & 2;
5016 if (foundr0) {
5017 regs[0] = regs[1];
5018
5019 }
5020 }
5021
5022 disasm_iter_init(fw,is,ca);
5023 disasm_iter(fw,is);
5024 }
5025 if(foundr0) {
5026
5027 uint32_t *p=(uint32_t*)adr2ptr_with_data(fw,regs[0]);
5028
5029
5030 if(p) {
5031 while(*p) {
5032 uint32_t nm_adr=*p;
5033 if(!isASCIIstring(fw,nm_adr)) {
5034 printf("eventproc name not string tbl 0x%08x 0x%08x\n",regs[0],nm_adr);
5035 break;
5036 }
5037 char *nm=(char *)adr2ptr(fw,nm_adr);
5038 p++;
5039 uint32_t fn=*p;
5040 p++;
5041
5042 add_event_proc(fw,nm,fn);
5043
5044 }
5045 } else {
5046 printf("failed to get *EventProcTable arg 0x%08x at 0x%"PRIx64"\n",regs[0],is->insn->address);
5047 }
5048 } else {
5049 printf("failed to get *EventProcTable r0 at 0x%"PRIx64"\n",is->insn->address);
5050 }
5051 return 0;
5052 }
5053
5054 int process_createtask_call(firmware *fw, iter_state_t *is,uint32_t unused) {
5055
5056 uint32_t regs[4];
5057
5058 if((get_call_const_args(fw,is,10,regs)&9)==9) {
5059 if(isASCIIstring(fw,regs[0])) {
5060
5061 char *buf=malloc(64);
5062 char *nm=(char *)adr2ptr(fw,regs[0]);
5063 sprintf(buf,"task_%s",nm);
5064
5065 add_func_name(fw,buf,regs[3],NULL);
5066 } else {
5067 printf("task name name not string at 0x%"PRIx64"\n",is->insn->address);
5068 }
5069 } else {
5070 printf("failed to get CreateTask args at 0x%"PRIx64"\n",is->insn->address);
5071 }
5072 return 0;
5073 }
5074
5075 int save_ptp_handler_func(firmware *fw,uint32_t op,uint32_t handler) {
5076 if((op >= 0x9000 && op < 0x10000) || (op >= 0x1000 && op < 0x2000)) {
5077 char *buf=malloc(64);
5078 const char *nm=get_ptp_op_name(op);
5079 if(nm) {
5080 sprintf(buf,"handle_%s",nm);
5081 } else {
5082 sprintf(buf,"handle_PTP_OC_0x%04x",op);
5083 }
5084
5085 add_func_name(fw,buf,handler,NULL);
5086 } else {
5087 return 0;
5088 }
5089 return 1;
5090 }
5091 int process_add_ptp_handler_call(firmware *fw, iter_state_t *is,uint32_t unused) {
5092 uint32_t regs[4];
5093
5094 if((get_call_const_args(fw,is,8,regs)&3)==3) {
5095
5096 if(!save_ptp_handler_func(fw,regs[0],regs[1])) {
5097 printf("add_ptp_handler op 0x%08x out of range 0x%"PRIx64"\n",regs[0],is->insn->address);
5098 }
5099 return 0;
5100 } else {
5101
5102 arm_reg ptr_reg = ARM_REG_INVALID;
5103 int i;
5104
5105 for(i=1; i<6; i++) {
5106 fw_disasm_iter_single(fw,adr_hist_get(&is->ah,i));
5107 cs_insn *insn=fw->is->insn;
5108 if(insn->id != ARM_INS_LDRH) {
5109 continue;
5110 }
5111 if(insn->detail->arm.operands[0].reg != ARM_REG_R0
5112 || insn->detail->arm.operands[1].mem.base == ARM_REG_PC
5113
5114 ) {
5115 continue;
5116 }
5117 ptr_reg = insn->detail->arm.operands[1].mem.base;
5118
5119 break;
5120 }
5121
5122 if(ptr_reg == ARM_REG_INVALID) {
5123 printf("failed to get add_ptp_handler args at 0x%"PRIx64"\n",is->insn->address);
5124 return 0;
5125 }
5126 uint32_t op_table=0;
5127
5128
5129 for(; i<20; i++) {
5130 fw_disasm_iter_single(fw,adr_hist_get(&is->ah,i));
5131 cs_insn *insn=fw->is->insn;
5132 if(!isLDR_PC(insn)) {
5133 continue;
5134 }
5135 if((arm_reg)insn->detail->arm.operands[0].reg != ptr_reg) {
5136 continue;
5137 }
5138
5139 uint32_t adr=LDR_PC2val(fw,insn);
5140
5141 if(fw_u32(fw,adr) == 0x1004) {
5142 op_table=adr;
5143 }
5144 break;
5145 }
5146 if(!op_table) {
5147 printf("failed to get ptp handler table adr at 0x%"PRIx64"\n",is->insn->address);
5148 return 0;
5149 }
5150
5151
5152 for(i=0; i<64; i++) {
5153 uint32_t op=fw_u32(fw,op_table+i*8);
5154 uint32_t handler=fw_u32(fw,op_table+i*8+4);
5155
5156 if(!save_ptp_handler_func(fw,op,handler)) {
5157 break;
5158 }
5159 }
5160 return 0;
5161 }
5162 }
5163
5164 int add_generic_func_match(search_calls_multi_data_t *match_fns,
5165 int *match_fn_count,
5166 int max_funcs,
5167 search_calls_multi_fn fn,
5168 uint32_t adr)
5169 {
5170 if(*match_fn_count >= max_funcs-1) {
5171 printf("add_generic_func_match: ERROR max_funcs %d reached\n",max_funcs);
5172 match_fns[max_funcs-1].adr=0;
5173 match_fns[max_funcs-1].fn=NULL;
5174 return 0;
5175 }
5176 match_fns[*match_fn_count].adr=adr;
5177 match_fns[*match_fn_count].fn=fn;
5178 (*match_fn_count)++;
5179 match_fns[*match_fn_count].adr=0;
5180 match_fns[*match_fn_count].fn=NULL;
5181 return 1;
5182 }
5183 #define MAX_GENERIC_FUNCS 16
5184 void add_generic_sig_match(search_calls_multi_data_t *match_fns,
5185 int *match_fn_count,
5186 search_calls_multi_fn fn,
5187 const char *name)
5188 {
5189 uint32_t adr=get_saved_sig_val(name);
5190 if(!adr) {
5191 printf("add_generic_sig_match: missing %s\n",name);
5192 return;
5193 }
5194 add_generic_func_match(match_fns,match_fn_count,MAX_GENERIC_FUNCS,fn,adr);
5195 char veneer[128];
5196 sprintf(veneer,"j_%s",name);
5197 adr=get_saved_sig_val(veneer);
5198 if(adr) {
5199 add_generic_func_match(match_fns,match_fn_count,MAX_GENERIC_FUNCS,fn,adr);
5200 }
5201 }
5202
5203 void find_exception_handlers(firmware *fw, iter_state_t *is)
5204 {
5205 uint32_t ex_vec = 0;
5206
5207 if (fw->arch_flags & FW_ARCH_FL_VMSA) {
5208 const insn_match_t match_mcr_vbar[]={
5209
5210 {MATCH_INS(MCR, 6), {MATCH_OP_PIMM(15),MATCH_OP_IMM(0),MATCH_OP_REG_ANY,MATCH_OP_CIMM(12),MATCH_OP_CIMM(0),MATCH_OP_IMM(0)}},
5211 {ARM_INS_ENDING}
5212 };
5213
5214 disasm_iter_init(fw, is, fw->base + fw->main_offs + 12 + fw->thumb_default);
5215 if(!insn_match_find_next(fw,is,4,match_mcr_vbar)) {
5216 return;
5217 }
5218
5219 disasm_iter_init(fw, is, adr_hist_get(&is->ah,1));
5220 disasm_iter(fw, is);
5221
5222 ex_vec = LDR_PC2val(fw,is->insn);
5223 if(!ex_vec || adr_get_range_type(fw,ex_vec) != ADR_RANGE_ROM) {
5224 return;
5225 }
5226 }
5227
5228
5229
5230 disasm_iter_init(fw, is, ex_vec);
5231 disasm_iter(fw, is);
5232
5233 char *names[]={
5234 "exception_handler_Reset",
5235 "exception_handler_UndefinedInstruction",
5236 "exception_handler_SupervisorCall",
5237 "exception_handler_PrefetchAbort",
5238 "exception_handler_DataAbort",
5239 "exception_handler_NotUsed",
5240 "exception_handler_IRQ",
5241 "exception_handler_FIQ",
5242 };
5243
5244 uint32_t addr=LDR_PC2val(fw,is->insn);
5245 if(!addr && is->insn->id == ARM_INS_B) {
5246 addr=get_branch_call_insn_target(fw,is);
5247 }
5248
5249 if(addr) {
5250 add_func_name(fw,names[0],addr,NULL);
5251 }
5252 disasm_iter_init(fw, is, ADR_SET_THUMB(ex_vec + 4));
5253 int i;
5254 for(i=1; i<8; i++) {
5255 disasm_iter(fw, is);
5256
5257
5258 addr=LDR_PC2val(fw,is->insn);
5259 if(addr) {
5260 add_func_name(fw,names[i],addr,NULL);
5261 }
5262 }
5263 }
5264
5265
5266
5267
5268
5269 void find_generic_funcs(firmware *fw) {
5270 search_calls_multi_data_t match_fns[MAX_GENERIC_FUNCS];
5271
5272 int match_fn_count=0;
5273
5274 add_generic_sig_match(match_fns,&match_fn_count,process_reg_eventproc_call,"ExportToEventProcedure_FW");
5275 add_generic_sig_match(match_fns,&match_fn_count,process_reg_eventproc_call,"RegisterEventProcedure_alt1");
5276 add_generic_sig_match(match_fns,&match_fn_count,process_reg_eventproc_call,"RegisterEventProcedure_alt2");
5277 add_generic_sig_match(match_fns,&match_fn_count,process_eventproc_table_call,"RegisterEventProcTable");
5278 add_generic_sig_match(match_fns,&match_fn_count,process_eventproc_table_call,"UnRegisterEventProcTable");
5279 add_generic_sig_match(match_fns,&match_fn_count,process_createtask_call,"CreateTaskStrictly");
5280 if(get_saved_sig_val("CreateTaskStrictly_alt")) {
5281 add_generic_sig_match(match_fns,&match_fn_count,process_createtask_call,"CreateTaskStrictly_alt");
5282 }
5283 add_generic_sig_match(match_fns,&match_fn_count,process_createtask_call,"CreateTask");
5284 if(get_saved_sig_val("CreateTask_alt")) {
5285 add_generic_sig_match(match_fns,&match_fn_count,process_createtask_call,"CreateTask_alt");
5286 }
5287 add_generic_sig_match(match_fns,&match_fn_count,process_eventproc_table_call,"RegisterEventProcTable_alt");
5288 add_generic_sig_match(match_fns,&match_fn_count,process_eventproc_table_call,"UnRegisterEventProcTable_alt");
5289 add_generic_sig_match(match_fns,&match_fn_count,process_add_ptp_handler_call,"add_ptp_handler");
5290
5291 iter_state_t *is=disasm_iter_new(fw,0);
5292 disasm_iter_init(fw,is,fw->rom_code_search_min_adr | fw->thumb_default);
5293 fw_search_insn(fw,is,search_disasm_calls_multi,0,match_fns,0);
5294
5295
5296 int i;
5297 for(i=0;i<fw->adr_range_count;i++) {
5298 if(fw->adr_ranges[i].type != ADR_RANGE_RAM_CODE) {
5299 continue;
5300 }
5301 disasm_iter_init(fw,is,fw->adr_ranges[i].start | fw->thumb_default);
5302 fw_search_insn(fw,is,search_disasm_calls_multi,0,match_fns,0);
5303 }
5304
5305 find_exception_handlers(fw,is);
5306
5307 disasm_iter_free(is);
5308 }
5309
5310 void find_ctypes(firmware *fw)
5311 {
5312 static unsigned char ctypes[] =
5313 {
5314 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x60, 0x60, 0x60, 0x60, 0x20, 0x20,
5315 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
5316 0x48, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
5317 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
5318 0x10, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5319 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0x10, 0x10, 0x10, 0x10, 0x10,
5320 0x10, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 2, 2, 2, 2, 2, 2, 2, 2, 2,
5321 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0x10, 0x10, 0x10, 0x10, 0x20
5322 };
5323
5324 uint32_t ctypes_matches[10];
5325 int match_count = find_bytes_all(fw,ctypes,sizeof(ctypes),fw->base,ctypes_matches,10);
5326 if(!match_count) {
5327 return;
5328 }
5329 if(match_count == 10) {
5330 fprintf(stderr,"WARNING found 10+ ctypes!\n");
5331 }
5332 int i;
5333 int match_i;
5334 uint32_t min_adr = 0xFFFFFFFF;
5335 for(i = 0; i< match_count; i++) {
5336
5337 uint32_t maxadr = (fw->rom_code_search_max_adr > fw->base + 0x400000)?fw->base + 0x100000:fw->rom_code_search_max_adr;
5338 uint32_t adr = find_u32_adr_range(fw,ctypes_matches[i],fw->rom_code_search_min_adr,maxadr);
5339 if(adr && adr < min_adr) {
5340 min_adr = adr;
5341 match_i = i;
5342 }
5343 }
5344 if(min_adr == 0xFFFFFFFF) {
5345 fprintf(stderr,"WARNING cytpes pointer not found, defaulting to first\n");
5346 match_i = 0;
5347 }
5348 save_misc_val("ctypes",ctypes_matches[match_i],0,min_adr);
5349 }
5350
5351 void print_misc_val_makefile(const char *name)
5352 {
5353 misc_val_t *mv=get_misc_val(name);
5354 if(!mv) {
5355 return;
5356 }
5357
5358 if(!mv->val) {
5359 bprintf("// %s not found\n",name);
5360 return;
5361 }
5362 bprintf("// %s = 0x%08x# ",name,mv->val);
5363 if(mv->offset) {
5364 bprintf(" (0x%x+0x%x)",mv->base,mv->offset);
5365 }
5366 if(mv->ref_adr) {
5367 bprintf(" Found @0x%08x",mv->ref_adr);
5368 }
5369 bprintf("\n");
5370 }
5371
5372
5373 void output_firmware_vals(firmware *fw)
5374 {
5375 bprintf("// Camera info:\n");
5376 bprintf("// Main firmware start: 0x%08x\n",fw->base+fw->main_offs);
5377 if (fw->dryos_ver == 0)
5378 {
5379 bprintf("// Can't find DRYOS version !!!\n\n");
5380 } else {
5381 bprintf("// DRYOS R%d (%s) @ 0x%08x ref @ 0x%08x\n",
5382 fw->dryos_ver,
5383 fw->dryos_ver_str,
5384 fw->dryos_ver_adr,
5385 fw->dryos_ver_ref_adr);
5386 }
5387 if (fw->firmware_ver_str == 0)
5388 {
5389 bprintf("// Can't find firmware version !!!\n\n");
5390 }
5391 else
5392 {
5393 char *c = strrchr(fw->firmware_ver_str,' ') + 1;
5394 uint32_t j = ptr2adr(fw,(uint8_t *)fw->firmware_ver_str);
5395 uint32_t k = j + c - fw->firmware_ver_str;
5396 if ( (k>=j) && (k<j+32) )
5397 {
5398 bprintf("// %s // Found @ 0x%08x, \"%s\" @ 0x%08x\n",fw->firmware_ver_str,j,c,k);
5399 }
5400 else
5401 {
5402
5403 bprintf("// %s // Found @ 0x%08x, \"%s\" @ 0x%08x\n",fw->firmware_ver_str,j,fw->firmware_ver_str,j);
5404 }
5405 }
5406 if (fw->arch_flags & FW_ARCH_FL_VMSA) {
5407 bprintf("// VMSA detected, probably digic >= 7\n");
5408 }
5409
5410 bprintf("\n// Values for makefile.inc\n");
5411 bprintf("// PLATFORMOSVER = %d\n",fw->dryos_ver);
5412 if (fw->arch_flags & FW_ARCH_FL_VMSA) {
5413 bprintf("// DIGIC = 70\n");
5414 } else {
5415
5416 bprintf("// DIGIC = 60\n");
5417 }
5418
5419 if (fw->memisostart) {
5420 bprintf("// MEMISOSTART = 0x%x\n",fw->memisostart);
5421 } else {
5422 bprintf("// MEMISOSTART not found !!!\n");
5423 }
5424 if (fw->data_init_start)
5425 {
5426 bprintf("// MEMBASEADDR = 0x%x\n",fw->data_start);
5427 }
5428 print_misc_val_makefile("ARAM_HEAP_START");
5429 print_misc_val_makefile("ARAM_HEAP_SIZE");
5430
5431 bprintf("\n// Detected address ranges:\n");
5432 int i;
5433 for(i=0; i<fw->adr_range_count; i++) {
5434 if(fw->adr_ranges[i].type == ADR_RANGE_ROM) {
5435 bprintf("// %-8s 0x%08x - 0x%08x (%7d bytes)\n",
5436 adr_range_desc_str(&fw->adr_ranges[i]),
5437 fw->adr_ranges[i].start,
5438 fw->adr_ranges[i].start+fw->adr_ranges[i].bytes,
5439 fw->adr_ranges[i].bytes);
5440 } else {
5441 bprintf("// %-8s 0x%08x - 0x%08x copied from 0x%08x (%7d bytes)\n",
5442 adr_range_desc_str(&fw->adr_ranges[i]),
5443 fw->adr_ranges[i].start,
5444 fw->adr_ranges[i].start+fw->adr_ranges[i].bytes,
5445 fw->adr_ranges[i].src_start,
5446 fw->adr_ranges[i].bytes);
5447 }
5448 }
5449 misc_val_t *mv=get_misc_val("zicokick_values");
5450 if(mv->blobs) {
5451 bprintf("\n// Zico Xtensa blobs:\n");
5452 for(i=0;mv->blobs[i].type != MISC_BLOB_TYPE_NONE;i++) {
5453 bprintf("// zico_%d 0x%08x - 0x%08x copied from 0x%08x (%7d bytes)\n",
5454 i,
5455 mv->blobs[i].ram_adr,
5456 mv->blobs[i].ram_adr+mv->blobs[i].size,
5457 mv->blobs[i].rom_adr,
5458 mv->blobs[i].size);
5459 }
5460
5461 }
5462 mv=get_misc_val("omar_init_values");
5463 if(mv->blobs) {
5464 bprintf("\n// Omar ARM blobs:\n");
5465 for(i=0;mv->blobs[i].type != MISC_BLOB_TYPE_NONE;i++) {
5466 bprintf("// omar_%d 0x%08x - 0x%08x copied from 0x%08x (%7d bytes)\n",
5467 i,
5468 mv->blobs[i].ram_adr,
5469 mv->blobs[i].ram_adr+mv->blobs[i].size,
5470 mv->blobs[i].rom_adr,
5471 mv->blobs[i].size);
5472 }
5473 }
5474 if(fw->dryos_ver_count) {
5475 bprintf("\n// Found DryOS versions:\n");
5476 for(i=0;i<(int)fw->dryos_ver_count;i++) {
5477 bprintf("// 0x%08x %s \"%s\"\n",
5478 fw->dryos_ver_list[i], (fw->dryos_ver_list[i] == fw->dryos_ver_adr) ? "main ":"other",
5479 (char *)adr2ptr(fw,fw->dryos_ver_list[i]));
5480 }
5481 add_blankline();
5482 }
5483 add_blankline();
5484
5485
5486 sig_entry_t * ct = find_saved_sig("hook_CreateTask");
5487 if(ct && adr_get_range_type(fw,ct->val) != ADR_RANGE_RAM_CODE) {
5488 bprintf("// CreateTask is not in RAM code\n");
5489 ct->flags |= UNUSED;
5490 sig_entry_t * ctl = find_saved_sig("CreateTask_low");
5491 if(ctl && adr_get_range_type(fw,ctl->val) == ADR_RANGE_RAM_CODE) {
5492 bprintf("// use hook_CreateTask_low instead\n");
5493 ctl->flags &= ~UNUSED;
5494 sig_entry_t * hctl = find_saved_sig("hook_CreateTask_low");
5495 hctl->flags &= ~UNUSED;
5496 }
5497 add_blankline();
5498 }
5499 }
5500
5501
5502 void print_platform_misc_val_undef(const char *name, uint32_t def)
5503 {
5504 misc_val_t *mv=get_misc_val(name);
5505 if(mv && mv->val && mv->val != def) {
5506 bprintf("//#undef %s\n",name);
5507 bprintf("//#define %s 0x%08x // Found @0x%08x\n",name,mv->val,mv->ref_adr);
5508 }
5509 }
5510
5511 void output_platform_vals(firmware *fw) {
5512 bprintf("// Values below go in 'platform_camera.h':\n");
5513 bprintf("//#define CAM_DRYOS 1\n");
5514 if (fw->dryos_ver >= 39)
5515 bprintf("//#define CAM_DRYOS_2_3_R39 1 // Defined for cameras with DryOS version R39 or higher\n");
5516 if (fw->dryos_ver >= 47)
5517 bprintf("//#define CAM_DRYOS_2_3_R47 1 // Defined for cameras with DryOS version R47 or higher\n");
5518 if (fw->dryos_ver >= 59)
5519 bprintf("//#define CAM_DRYOS_2_3_R59 1 // Defined for cameras with DryOS version R59 or higher\n");
5520
5521 if(get_misc_val_value("CAM_IS_ILC")) {
5522 bprintf("//#define CAM_ILC 1 // Camera is interchangeable lens\n");
5523 }
5524
5525
5526 print_platform_misc_val_undef("CAM_UNCACHED_BIT",0x10000000);
5527
5528 if(get_misc_val_value("CAM_HAS_ND_FILTER")) {
5529 bprintf("//#define CAM_HAS_ND_FILTER 1 // Camera has ND filter\n");
5530 } else {
5531 bprintf("//#undef CAM_HAS_ND_FILTER // Camera does not have an ND filter\n");
5532 }
5533 if(get_misc_val_value("CAM_HAS_IRIS_DIAPHRAGM")) {
5534 bprintf("// Camera has an iris (CAM_HAS_IRIS_DIAPHRAGM default)\n");
5535 } else {
5536 bprintf("//#undef CAM_HAS_IRIS_DIAPHRAGM // Camera does not have an iris\n");
5537 }
5538
5539 add_blankline();
5540 }
5541
5542 void output_propcases(firmware *fw) {
5543
5544 uint32_t used=0;
5545 uint32_t hits[KNOWN_PROPSET_COUNT];
5546 const uint32_t ps_offset = 6;
5547
5548 memset(hits, 0, KNOWN_PROPSET_COUNT*sizeof(uint32_t));
5549
5550 bprintf("// Known propcases\n");
5551
5552 int n = 0;
5553 while (knownprops[n].name) {
5554 used += knownprops[n].use>0?1:0;
5555 if (knownprops[n].id >= 0)
5556 {
5557 if (knownprops[n].use)
5558 {
5559 if (knownprops[n].id == knownprops[n].id_ps6) hits[6-ps_offset] += 1;
5560 if (knownprops[n].id == knownprops[n].id_ps7) hits[7-ps_offset] += 1;
5561 if (knownprops[n].id == knownprops[n].id_ps8) hits[8-ps_offset] += 1;
5562 if (knownprops[n].id == knownprops[n].id_ps9) hits[9-ps_offset] += 1;
5563 if (knownprops[n].id == knownprops[n].id_ps10) hits[10-ps_offset] += 1;
5564 if (knownprops[n].id == knownprops[n].id_ps11) hits[11-ps_offset] += 1;
5565 if (knownprops[n].id == knownprops[n].id_ps12) hits[12-ps_offset] += 1;
5566 if (knownprops[n].id == knownprops[n].id_ps13) hits[13-ps_offset] += 1;
5567 }
5568 if (knownprops[n].use == 1)
5569 {
5570 bprintf("// #define %s %i\n", knownprops[n].name, knownprops[n].id);
5571 }
5572 else
5573 {
5574
5575 bprintf("// // %s %i\n", knownprops[n].name, knownprops[n].id);
5576 }
5577 }
5578 else
5579 {
5580 bprintf("// %s not found\n", knownprops[n].name);
5581 }
5582 n++;
5583 }
5584
5585 bprintf("// Guessed propset: ");
5586 int m = 0;
5587 uint32_t fmax = 0;
5588 int okay = 0;
5589 for (n=0; n<KNOWN_PROPSET_COUNT; n++)
5590 {
5591 if (hits[n] == used)
5592 {
5593 if (m) bprintf(", ");
5594 bprintf("%i", n+ps_offset);
5595 if (fw->sv->propset == n+ps_offset) okay = 1;
5596 m += 1;
5597 }
5598 if (hits[n] > fmax) fmax = hits[n];
5599 }
5600 if (m == 0)
5601 {
5602 bprintf("uncertain (%i of %u match), closest to ",fmax,used);
5603 for (n=0; n<KNOWN_PROPSET_COUNT; n++)
5604 {
5605 if (hits[n] == fmax)
5606 {
5607 if (m) bprintf(", ");
5608 bprintf("%i", n+ps_offset);
5609 if (fw->sv->propset == n+ps_offset) okay = 1;
5610 m += 1;
5611 }
5612 }
5613 }
5614 bprintf("\n");
5615 if (!okay && fw->sv->propset>0)
5616 {
5617
5618 bprintf("// Port's propset (%i) may be set incorrectly\n", fw->sv->propset);
5619 }
5620
5621 add_blankline();
5622 }
5623
5624 void output_exmem_types(firmware *fw)
5625 {
5626
5627 misc_val_t *ett=get_misc_val("exmem_types_table");
5628 misc_val_t *etc=get_misc_val("exmem_type_count");
5629 if (ett->val == 0 || etc->val == 0) {
5630 return;
5631 }
5632 bprintf("// EXMEM types:\n");
5633 uint32_t n;
5634 for (n=0; n<etc->val; n++) {
5635 char *extyp = (char*)adr2ptr(fw, fw_u32(fw,ett->val+n*4));
5636 bprintf("// %s %i\n", extyp, n);
5637 }
5638 add_blankline();
5639 }
5640
5641 void print_misc_val_comment(const char *name)
5642 {
5643 misc_val_t *mv=get_misc_val(name);
5644 if(!mv) {
5645 return;
5646 }
5647
5648 if(!mv->val) {
5649 bprintf("// %s not found\n",name);
5650 return;
5651 }
5652 bprintf("// %s 0x%08x",name,mv->val);
5653 if(mv->offset) {
5654 bprintf(" (0x%x+0x%x)",mv->base,mv->offset);
5655 }
5656 if(mv->ref_adr) {
5657 bprintf(" Found @0x%08x",mv->ref_adr);
5658 }
5659 bprintf("\n");
5660 }
5661
5662 typedef struct {
5663 int reg;
5664 uint32_t bit;
5665 uint32_t ev;
5666 uint32_t raw_info;
5667 int no_invert;
5668 } physw_table_entry_t;
5669
5670 void get_physw_table_entry(firmware *fw, uint32_t adr, physw_table_entry_t *vals)
5671 {
5672 uint32_t info=fw_u32(fw,adr);
5673 vals->raw_info=info;
5674 vals->ev=fw_u32(fw,adr+4);
5675
5676 vals->reg=(info >>5) & 7;
5677 vals->bit=(1 << (info & 0x1f));
5678
5679 vals->no_invert=((info&0xff0000)==0x10000)?1:0;
5680 }
5681 uint32_t find_physw_table_entry(firmware *fw, uint32_t tadr, int tcount, uint32_t ev)
5682 {
5683 int i;
5684 for(i=0; i<tcount; i++,tadr += 8) {
5685 if(fw_u32(fw,tadr+4) == ev) {
5686 return tadr;
5687 }
5688 }
5689 return 0;
5690 }
5691
5692 uint32_t find_physw_table_max(firmware *fw, uint32_t tadr, int max_count)
5693 {
5694 int i;
5695 for(i=0; i<max_count; i++,tadr += 8) {
5696 physw_table_entry_t v;
5697 get_physw_table_entry(fw,tadr,&v);
5698 if(v.raw_info == 0 || v.raw_info == 0xFFFFFFFF || v.reg > 2) {
5699 return i;
5700 }
5701
5702 }
5703 return max_count;
5704 }
5705 void write_physw_event_table_dump(firmware *fw, uint32_t tadr, int tcount)
5706 {
5707 FILE *f=fopen("physw_bits.txt","w");
5708 if(!f) {
5709 return;
5710 }
5711 fprintf(f,"physw_event_table dump (%d entries printed, may not all be valid)\n",tcount);
5712 fprintf(f,"address info event index bit non-inverted\n");
5713 int i;
5714 physw_table_entry_t v;
5715
5716 for(i=0; i<tcount; i++,tadr += 8) {
5717 get_physw_table_entry(fw,tadr,&v);
5718 fprintf(f,"0x%08x 0x%08x 0x%08x %-5d 0x%08x %d\n",tadr,v.raw_info,v.ev,v.reg,v.bit,v.no_invert);
5719 }
5720 fclose(f);
5721 }
5722 void print_kval(firmware *fw, uint32_t tadr, int tcount, uint32_t ev, const char *name, const char *sfx)
5723 {
5724 uint32_t adr=find_physw_table_entry(fw,tadr,tcount,ev);
5725 if(!adr) {
5726 return;
5727 }
5728 physw_table_entry_t v;
5729 get_physw_table_entry(fw,adr,&v);
5730
5731 char fn[100], rn[100];
5732 strcpy(fn,name); strcat(fn,sfx);
5733 strcpy(rn,name); strcat(rn,"_IDX");
5734
5735 bprintf("//#define %-20s0x%08x // Found @0x%08x, levent 0x%x%s\n",fn,v.bit,adr,v.ev,v.no_invert?" (non-inverted logic)":"");
5736 bprintf("//#define %-20s%d\n",rn,v.reg);
5737
5738 }
5739
5740
5741 typedef struct {
5742 int reg;
5743 uint32_t bits;
5744 char nm[32];
5745 uint32_t fadr;
5746 uint32_t ev;
5747 int inv;
5748 } kinfo;
5749
5750 int kmask[3];
5751 kinfo key_info[100];
5752 int kcount = 0;
5753 uint32_t kshutter_min_bits = 0xFFFFFFFF;
5754
5755 void add_kinfo(int r, uint32_t b, const char *nm, uint32_t adr, uint32_t ev, int inv)
5756 {
5757 key_info[kcount].reg = r;
5758 key_info[kcount].bits = b;
5759 strcpy(key_info[kcount].nm, nm);
5760 key_info[kcount].fadr = adr;
5761 key_info[kcount].ev = ev;
5762 key_info[kcount].inv = inv;
5763 kcount++;
5764 kmask[r] |= b;
5765 if ((ev <= 1) && (b < kshutter_min_bits)) kshutter_min_bits = b;
5766 }
5767
5768 uint32_t add_kmval(firmware *fw, uint32_t tadr, int tsiz, int tlen, uint32_t ev, const char *name, uint32_t xtra)
5769 {
5770 uint32_t adr=find_physw_table_entry(fw,tadr,tlen,ev);
5771 if(!adr) {
5772 return 0;
5773 }
5774 physw_table_entry_t v;
5775 get_physw_table_entry(fw,adr,&v);
5776
5777 add_kinfo(v.reg,v.bit|xtra,name,adr,v.ev,(v.no_invert)?0:1);
5778 return v.bit;
5779 }
5780
5781 int kinfo_compare(const kinfo *p1, const kinfo *p2)
5782 {
5783 if (p1->reg > p2->reg)
5784 {
5785 return 1;
5786 }
5787 else if (p1->reg < p2->reg)
5788 {
5789 return -1;
5790 }
5791 if ((p1->ev <= 1) && (p2->ev <= 1))
5792 {
5793 if (p1->bits > p2->bits)
5794 {
5795 return -1;
5796 }
5797 else if (p1->bits < p2->bits)
5798 {
5799 return 1;
5800 }
5801 }
5802
5803 if (p1->ev <= 1)
5804 {
5805 if (kshutter_min_bits > p2->bits)
5806 {
5807 return 1;
5808 }
5809 else if (kshutter_min_bits < p2->bits)
5810 {
5811 return -1;
5812 }
5813 }
5814 if (p2->ev <= 1)
5815 {
5816 if (p1->bits > kshutter_min_bits)
5817 {
5818 return 1;
5819 }
5820 else if (p1->bits < kshutter_min_bits)
5821 {
5822 return -1;
5823 }
5824 }
5825 if (p1->bits > p2->bits)
5826 {
5827 return 1;
5828 }
5829 else if (p1->bits < p2->bits)
5830 {
5831 return -1;
5832 }
5833
5834 return 0;
5835 }
5836
5837 void print_kmvals()
5838 {
5839 qsort(key_info, kcount, sizeof(kinfo), (void*)kinfo_compare);
5840
5841 bprintf("//KeyMap keymap[] = {\n");
5842
5843 int k;
5844 for (k=0; k<kcount; k++)
5845 {
5846 bprintf("// { %d, %-20s,0x%08x }, // Found @0x%08x, levent 0x%02x%s\n",key_info[k].reg,key_info[k].nm,key_info[k].bits,key_info[k].fadr,key_info[k].ev,(key_info[k].inv==0)?"":" (uses inverted logic in physw_status)");
5847 }
5848
5849 bprintf("// { 0, 0, 0 }\n//};\n");
5850 }
5851
5852 void do_km_vals(firmware *fw, uint32_t tadr,int tsiz,int tlen)
5853 {
5854 uint32_t key_half = add_kmval(fw,tadr,tsiz,tlen,0,"KEY_SHOOT_HALF",0);
5855 add_kmval(fw,tadr,tsiz,tlen,1,"KEY_SHOOT_FULL",key_half);
5856 add_kmval(fw,tadr,tsiz,tlen,1,"KEY_SHOOT_FULL_ONLY",0);
5857
5858 add_kmval(fw,tadr,tsiz,tlen,0x101,"KEY_PLAYBACK",0);
5859 add_kmval(fw,tadr,tsiz,tlen,0x100,"KEY_POWER",0);
5860
5861
5862 if (fw->dryos_ver == 52)
5863 {
5864 add_kmval(fw,tadr,tsiz,tlen,3,"KEY_ZOOM_IN",0);
5865 add_kmval(fw,tadr,tsiz,tlen,4,"KEY_ZOOM_OUT",0);
5866 add_kmval(fw,tadr,tsiz,tlen,6,"KEY_UP",0);
5867 add_kmval(fw,tadr,tsiz,tlen,7,"KEY_DOWN",0);
5868 add_kmval(fw,tadr,tsiz,tlen,8,"KEY_LEFT",0);
5869 add_kmval(fw,tadr,tsiz,tlen,9,"KEY_RIGHT",0);
5870 add_kmval(fw,tadr,tsiz,tlen,0xA,"KEY_SET",0);
5871 add_kmval(fw,tadr,tsiz,tlen,0xB,"KEY_MENU",0);
5872 add_kmval(fw,tadr,tsiz,tlen,0xC,"KEY_DISPLAY",0);
5873 add_kmval(fw,tadr,tsiz,tlen,0x12,"KEY_HELP",0);
5874 add_kmval(fw,tadr,tsiz,tlen,0x19,"KEY_ERASE",0);
5875 add_kmval(fw,tadr,tsiz,tlen,2,"KEY_VIDEO",0);
5876
5877 }
5878 else if (fw->dryos_ver < 54)
5879 {
5880 add_kmval(fw,tadr,tsiz,tlen,2,"KEY_ZOOM_IN",0);
5881 add_kmval(fw,tadr,tsiz,tlen,3,"KEY_ZOOM_OUT",0);
5882 add_kmval(fw,tadr,tsiz,tlen,4,"KEY_UP",0);
5883 add_kmval(fw,tadr,tsiz,tlen,5,"KEY_DOWN",0);
5884 add_kmval(fw,tadr,tsiz,tlen,6,"KEY_LEFT",0);
5885 add_kmval(fw,tadr,tsiz,tlen,7,"KEY_RIGHT",0);
5886 add_kmval(fw,tadr,tsiz,tlen,8,"KEY_SET",0);
5887 add_kmval(fw,tadr,tsiz,tlen,9,"KEY_MENU",0);
5888 add_kmval(fw,tadr,tsiz,tlen,0xA,"KEY_DISPLAY",0);
5889 }
5890 else if (fw->dryos_ver < 55)
5891 {
5892 add_kmval(fw,tadr,tsiz,tlen,3,"KEY_ZOOM_IN",0);
5893 add_kmval(fw,tadr,tsiz,tlen,4,"KEY_ZOOM_OUT",0);
5894 add_kmval(fw,tadr,tsiz,tlen,6,"KEY_UP",0);
5895 add_kmval(fw,tadr,tsiz,tlen,7,"KEY_DOWN",0);
5896 add_kmval(fw,tadr,tsiz,tlen,8,"KEY_LEFT",0);
5897 add_kmval(fw,tadr,tsiz,tlen,9,"KEY_RIGHT",0);
5898 add_kmval(fw,tadr,tsiz,tlen,0xA,"KEY_SET",0);
5899 add_kmval(fw,tadr,tsiz,tlen,0xE,"KEY_MENU",0);
5900 add_kmval(fw,tadr,tsiz,tlen,2,"KEY_VIDEO",0);
5901 add_kmval(fw,tadr,tsiz,tlen,0xD,"KEY_DISPLAY",0);
5902 add_kmval(fw,tadr,tsiz,tlen,0x103,"KEY_WIFI",0);
5903
5904
5905 }
5906 else if (fw->dryos_ver < 59)
5907 {
5908 add_kmval(fw,tadr,tsiz,tlen,3,"KEY_ZOOM_IN",0);
5909 add_kmval(fw,tadr,tsiz,tlen,4,"KEY_ZOOM_OUT",0);
5910 add_kmval(fw,tadr,tsiz,tlen,6,"KEY_UP",0);
5911 add_kmval(fw,tadr,tsiz,tlen,7,"KEY_DOWN",0);
5912 add_kmval(fw,tadr,tsiz,tlen,8,"KEY_LEFT",0);
5913 add_kmval(fw,tadr,tsiz,tlen,9,"KEY_RIGHT",0);
5914 add_kmval(fw,tadr,tsiz,tlen,0xA,"KEY_SET",0);
5915 add_kmval(fw,tadr,tsiz,tlen,0x14,"KEY_MENU",0);
5916 add_kmval(fw,tadr,tsiz,tlen,2,"KEY_VIDEO",0);
5917 add_kmval(fw,tadr,tsiz,tlen,0xD,"KEY_DISPLAY",0);
5918 add_kmval(fw,tadr,tsiz,tlen,0x103,"KEY_WIFI",0);
5919
5920
5921 }
5922 else
5923 {
5924 add_kmval(fw,tadr,tsiz,tlen,3,"KEY_ZOOM_IN",0);
5925 add_kmval(fw,tadr,tsiz,tlen,4,"KEY_ZOOM_OUT",0);
5926 add_kmval(fw,tadr,tsiz,tlen,6,"KEY_UP",0);
5927 add_kmval(fw,tadr,tsiz,tlen,7,"KEY_DOWN",0);
5928 add_kmval(fw,tadr,tsiz,tlen,8,"KEY_LEFT",0);
5929 add_kmval(fw,tadr,tsiz,tlen,9,"KEY_RIGHT",0);
5930 add_kmval(fw,tadr,tsiz,tlen,0xA,"KEY_SET",0);
5931 add_kmval(fw,tadr,tsiz,tlen,0x15,"KEY_MENU",0);
5932 add_kmval(fw,tadr,tsiz,tlen,2,"KEY_VIDEO",0);
5933 add_kmval(fw,tadr,tsiz,tlen,0xB,"KEY_ERASE",0);
5934 add_kmval(fw,tadr,tsiz,tlen,0x103,"KEY_WIFI",0);
5935 }
5936
5937 bprintf("\n// Keymap values for kbd.c. Additional keys may be present, only common values included here.\n");
5938 bprintf("// WARNING: Key name / function may vary! Values for unknown DryOS versions should not be trusted!\n");
5939 print_kmvals();
5940 }
5941 void output_physw_vals(firmware *fw) {
5942 print_misc_val_comment("physw_event_table");
5943 uint32_t physw_tbl=get_misc_val_value("physw_event_table");
5944 if(!physw_tbl) {
5945 return;
5946 }
5947 int physw_tbl_len=find_physw_table_max(fw,physw_tbl,50);
5948 write_physw_event_table_dump(fw,physw_tbl,physw_tbl_len);
5949
5950 bprintf("// Values below go in 'platform_kbd.h':\n");
5951 if (fw->dryos_ver >= 58)
5952 {
5953
5954 print_kval(fw,physw_tbl,physw_tbl_len,0x30A,"SD_READONLY","_FLAG");
5955 print_kval(fw,physw_tbl,physw_tbl_len,0x302,"USB","_MASK");
5956 print_kval(fw,physw_tbl,physw_tbl_len,0x305,"BATTCOVER","_FLAG");
5957 print_kval(fw,physw_tbl,physw_tbl_len,0x304,"HOTSHOE","_FLAG");
5958 print_kval(fw,physw_tbl,physw_tbl_len,0x300,"ANALOG_AV","_FLAG");
5959 }
5960 else
5961 {
5962 print_kval(fw,physw_tbl,physw_tbl_len,0x20A,"SD_READONLY","_FLAG");
5963 print_kval(fw,physw_tbl,physw_tbl_len,0x202,"USB","_MASK");
5964 print_kval(fw,physw_tbl,physw_tbl_len,0x205,"BATTCOVER","_FLAG");
5965 print_kval(fw,physw_tbl,physw_tbl_len,0x204,"HOTSHOE","_FLAG");
5966 print_kval(fw,physw_tbl,physw_tbl_len,0x200,"ANALOG_AV","_FLAG");
5967 }
5968 do_km_vals(fw,physw_tbl,2,physw_tbl_len);
5969
5970 add_blankline();
5971 }
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007 void output_modemap(firmware *fw) {
6008 print_misc_val_comment("canon_mode_list");
6009 bprintf("// Check modemap values from 'platform/CAMERA/shooting.c':\n");
6010 misc_val_t *mv=get_misc_val("canon_mode_list");
6011 if(!mv) {
6012 add_blankline();
6013 return;
6014 }
6015 int i;
6016 uint32_t adr=mv->val;
6017 int bad=0;
6018 for(i=0; i<50; i++,adr+=2) {
6019 uint16_t *pv=(uint16_t*)adr2ptr(fw,adr);
6020 if(!pv) {
6021 break;
6022 }
6023 if(*pv==0xFFFF) {
6024 break;
6025 }
6026 osig *m = find_sig_val(fw->sv->modemap, *pv);
6027 if (!m) {
6028 bprintf("// %5hu 0x%04hx In firmware but not in current modemap",*pv,*pv);
6029
6030
6031
6032
6033
6034
6035 bprintf("\n");
6036 bad++;
6037 } else {
6038
6039 m->pct = 100;
6040 }
6041 }
6042 osig *m = fw->sv->modemap;
6043 while (m)
6044 {
6045 if (m->pct != 100)
6046 {
6047 bprintf("// Current modemap entry not found in firmware - %-24s %5d\n",m->nm,m->val);
6048 bad++;
6049 }
6050 m = m->nxt;
6051 }
6052 if (bad == 0)
6053 {
6054 bprintf("// No problems found with modemap table.\n");
6055 }
6056
6057 add_blankline();
6058 }
6059
6060
6061 int compare_sig_names(const sig_entry_t **p1, const sig_entry_t **p2)
6062 {
6063 int rv = strcasecmp((*p1)->name, (*p2)->name);
6064 if (rv != 0)
6065 return rv;
6066 rv = strcmp((*p1)->name, (*p2)->name);
6067 if (rv != 0)
6068 return rv;
6069 if ((*p1)->val < (*p2)->val)
6070 return -1;
6071 else if ((*p1)->val > (*p2)->val)
6072 return 1;
6073 return 0;
6074 }
6075
6076 int compare_func_addresses(const sig_entry_t **p1, const sig_entry_t **p2)
6077 {
6078 if ((*p1)->val < (*p2)->val)
6079 return -1;
6080 else if ((*p1)->val > (*p2)->val)
6081 return 1;
6082 return compare_sig_names(p1,p2);
6083 }
6084
6085 void write_funcs(firmware *fw, char *filename, sig_entry_t *fns[], int (*compare)(const sig_entry_t **p1, const sig_entry_t **p2))
6086 {
6087 int k;
6088
6089 qsort(fns, next_sig_entry, sizeof(sig_entry_t*), (void*)compare);
6090
6091 FILE *out_fp = fopen(filename, "w");
6092 for (k=0; k<next_sig_entry; k++)
6093 {
6094 if (strncmp(fns[k]->name,"hook_",5) == 0) {
6095 continue;
6096 }
6097 if (fns[k]->val != 0)
6098 {
6099 if (fns[k]->flags & BAD_MATCH)
6100 {
6101 osig* ostub2 = find_sig(fw->sv->stubs,fns[k]->name);
6102 if (ostub2 && ostub2->val)
6103 fprintf(out_fp, "0x%08x,%s,(stubs_entry_2.s)\n", ostub2->val, fns[k]->name);
6104 }
6105 else
6106 fprintf(out_fp, "0x%08x,%s\n", fns[k]->val, fns[k]->name);
6107 }
6108 #ifdef LIST_IMPORTANT_FUNCTIONS
6109 else if (fns[k]->flags & LIST_ALWAYS)
6110 {
6111
6112 fprintf(out_fp, "0,%s,(NOT FOUND)\n", fns[k]->name);
6113 }
6114 #endif
6115 }
6116 fclose(out_fp);
6117 }
6118
6119 void write_func_lists(firmware *fw) {
6120 sig_entry_t *fns[MAX_SIG_ENTRY];
6121 int k;
6122 for (k=0; k<next_sig_entry; k++)
6123 fns[k] = &sig_names[k];
6124
6125 write_funcs(fw, "funcs_by_name.csv", fns, compare_sig_names);
6126 write_funcs(fw, "funcs_by_address.csv", fns, compare_func_addresses);
6127 }
6128
6129 void print_other_stubs_min(firmware *fw, const char *name, uint32_t fadr, uint32_t atadr)
6130 {
6131 osig *o = find_sig(fw->sv->stubs_min,name);
6132 if (o)
6133 {
6134 bprintf("//DEF(%-40s,0x%08x) // Found @0x%08x",name,fadr,atadr);
6135 if (fadr != o->val)
6136 {
6137 bprintf(", ** != ** stubs_min = 0x%08x (%s)",o->val,o->sval);
6138 }
6139 else
6140 {
6141 bprintf(", stubs_min = 0x%08x (%s)",o->val,o->sval);
6142 }
6143 }
6144 else
6145 {
6146 bprintf("DEF(%-40s,0x%08x) // Found @0x%08x",name,fadr,atadr);
6147 }
6148 bprintf("\n");
6149 }
6150
6151 void print_stubs_min_def(firmware *fw, misc_val_t *sig)
6152 {
6153 if(sig->flags & MISC_VAL_NO_STUB) {
6154 return;
6155 }
6156
6157 osig* ostub2=find_sig(fw->sv->stubs_min,sig->name);
6158
6159 const char *macro = "DEF";
6160 if(sig->flags & MISC_VAL_DEF_CONST) {
6161 macro="DEF_CONST";
6162 }
6163
6164 if (ostub2)
6165 {
6166 bprintf("//%s(%-34s,0x%08x)",macro,sig->name,sig->val);
6167 if (sig->val != ostub2->val)
6168 {
6169 bprintf(", ** != ** stubs_min = 0x%08x (%s)",ostub2->val,ostub2->sval);
6170 }
6171 else
6172 {
6173 bprintf(", stubs_min = 0x%08x (%s)",ostub2->val,ostub2->sval);
6174 }
6175 }
6176 else if(sig->base || sig->offset)
6177 {
6178 bprintf("%s(%-34s,0x%08x)",macro,sig->name,sig->val);
6179 if(sig->offset || sig->ref_adr) {
6180 bprintf(" //");
6181 if(sig->offset) {
6182 bprintf(" (0x%x+0x%x)",sig->base,sig->offset);
6183 }
6184 if(sig->ref_adr) {
6185 bprintf(" Found @0x%08x",sig->ref_adr);
6186 }
6187 }
6188 }
6189 else
6190 {
6191 if (sig->flags & MISC_VAL_OPTIONAL) return;
6192 bprintf("// %s not found",sig->name);
6193 }
6194 bprintf("\n");
6195 }
6196
6197
6198 void find_other_stubs_min(firmware *fw)
6199 {
6200 int k,k1;
6201
6202 out_hdr = 1;
6203
6204
6205 if (fw->sv->min_focus_len != 0)
6206 {
6207 int found = 0, pos = 0, len = 0, size = 0;
6208 for (k=0; k<fw->size32; k++)
6209 {
6210 if (fw->buf32[k] == fw->sv->min_focus_len)
6211 {
6212 int mul = 1;
6213 if ((fw->buf32[k+1] == 100) && (fw->buf32[k+2] == 0)) mul = 3;
6214 if ((fw->buf32[k+1] == 100) && (fw->buf32[k+2] != 0)) mul = 2;
6215 if ((fw->buf32[k+1] == 0) && (fw->buf32[k+2] != 0)) mul = 2;
6216 for (k1 = k + mul; (k1 < fw->size32) && (fw->buf32[k1] > fw->buf32[k1-mul]) && (fw->buf32[k1] > fw->sv->min_focus_len) && (fw->buf32[k1] < fw->sv->max_focus_len); k1 += mul) ;
6217 if (fw->buf32[k1] == fw->sv->max_focus_len)
6218 {
6219 if ((found == 0) || ((size < mul) && (len < ((k1 - k) / mul) + 1)))
6220 {
6221 found = 1;
6222 pos = k;
6223 len = ((k1 - k) / mul) + 1;
6224 size = mul;
6225 }
6226 }
6227 }
6228 }
6229 if (found == 1)
6230 {
6231 uint32_t adr = fw->base + (pos << 2);
6232 bprintf("// focus_len_table contains zoom focus lengths for use in 'get_focal_length' (main.c).\n");
6233 if (size == 1)
6234 bprintf("// each entry contains 1 int value, which is the the zoom focus length.\n",size);
6235 else
6236 bprintf("// each entry contains %d int value(s), the first is the zoom focus length.\n",size);
6237 bprintf("// there are %d entries in the table - set NUM_FL to %d\n",len,len);
6238 print_other_stubs_min(fw,"focus_len_table",adr,adr);
6239 }
6240 }
6241 }
6242
6243
6244
6245 void print_results(firmware *fw, sig_entry_t *sig)
6246 {
6247 int i;
6248 int err = 0;
6249 char line[500] = "";
6250
6251 if (sig->flags & DONT_EXPORT) {
6252 return;
6253 }
6254
6255 if ((sig->flags & DONT_EXPORT_ILC) && get_misc_val_value("CAM_IS_ILC")) {
6256 return;
6257 }
6258
6259
6260 osig* ostub2 = find_sig(fw->sv->stubs,sig->name);
6261
6262 if (ostub2 && (sig->val != ostub2->val))
6263 {
6264 if (ostub2->type != TYPE_IGNORE)
6265 {
6266 err = 1;
6267 sig->flags |= BAD_MATCH;
6268 }
6269 }
6270 else
6271 {
6272 if (sig->flags & UNUSED) return;
6273 }
6274
6275
6276 out_hdr = err;
6277
6278 char *macro = "NHSTUB";
6279 if (sig->flags & ARM_STUB) {
6280 macro = "NHSTUB2";
6281 }
6282 if (strncmp(sig->name,"task_",5) == 0 ||
6283 strncmp(sig->name,"hook_",5) == 0) macro = " DEF";
6284
6285 if (!sig->val && !ostub2)
6286 {
6287 if (sig->flags & OPTIONAL) return;
6288 char fmt[51] = "";
6289 sprintf(fmt, "// ERROR: %%s is not found. %%%ds//--- --- ", (int)(34-strlen(sig->name)));
6290 sprintf(line+strlen(line), fmt, sig->name, "");
6291 }
6292 else
6293 {
6294 if (ostub2 || (sig->flags & UNUSED))
6295 sprintf(line+strlen(line),"//%s(%-37s,0x%08x) //%3d ", macro, sig->name, sig->val, 0);
6296 else
6297 sprintf(line+strlen(line),"%s(%-39s,0x%08x) //%3d ", macro, sig->name, sig->val, 0);
6298
6299
6300
6301
6302
6303
6304 sprintf(line+strlen(line)," ");
6305 }
6306
6307 if (ostub2)
6308 {
6309 if (ostub2->type == TYPE_IGNORE)
6310 sprintf(line+strlen(line)," Overridden");
6311 else if (sig->val == ostub2->val)
6312 sprintf(line+strlen(line)," == 0x%08x ",ostub2->val);
6313 else {
6314
6315 if(sig->val && ostub2->val) {
6316 fw_disasm_iter_single(fw,ostub2->val);
6317 if(get_direct_jump_target(fw,fw->is) == sig->val) {
6318 sprintf(line+strlen(line)," <-veneer 0x%08x ",ostub2->val);
6319 } else {
6320 fw_disasm_iter_single(fw,sig->val);
6321 if(get_direct_jump_target(fw,fw->is) == ostub2->val) {
6322 sprintf(line+strlen(line)," veneer-> 0x%08x ",ostub2->val);
6323 } else {
6324 sprintf(line+strlen(line)," *** != 0x%08x ",ostub2->val);
6325 }
6326 }
6327 } else {
6328 sprintf(line+strlen(line)," *** != 0x%08x ",ostub2->val);
6329 }
6330 }
6331 }
6332 else
6333 sprintf(line+strlen(line)," ");
6334
6335 for (i=strlen(line)-1; i>=0 && line[i]==' '; i--) line[i] = 0;
6336 bprintf("%s\n",line);
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347 }
6348
6349 void write_stubs(firmware *fw,int max_find_func) {
6350 int k;
6351 bprintf("// Values below can be overridden in 'stubs_min.S':\n");
6352 misc_val_t *stub_min=misc_vals;
6353 while(stub_min->name) {
6354 print_stubs_min_def(fw,stub_min);
6355 stub_min++;
6356 }
6357
6358 find_other_stubs_min(fw);
6359
6360 add_blankline();
6361
6362 for (k = 0; k < max_find_func; k++)
6363 {
6364 print_results(fw,&sig_names[k]);
6365 }
6366 }
6367
6368 int main(int argc, char **argv)
6369 {
6370 clock_t t1 = clock();
6371
6372 firmware fw;
6373 memset(&fw,0,sizeof(firmware));
6374 if (argc < 4) {
6375 fprintf(stderr,"finsig_thumb2 <primary> <base> <outputfilename>\n");
6376 exit(1);
6377 }
6378
6379 for (next_sig_entry = 0; sig_names[next_sig_entry].name != 0; next_sig_entry++);
6380 int max_find_sig = next_sig_entry;
6381
6382 fw.sv = new_stub_values();
6383 load_stubs(fw.sv, "stubs_entry_2.S", 1);
6384 load_stubs_min(fw.sv);
6385 load_modemap(fw.sv);
6386 load_platform(fw.sv);
6387
6388 bprintf("// !!! THIS FILE IS GENERATED. DO NOT EDIT. !!!\n");
6389 bprintf("#include \"stubs_asm.h\"\n\n");
6390
6391 firmware_load(&fw,argv[1],strtoul(argv[2], NULL, 0),FW_ARCH_ARMv7);
6392 if(!firmware_init_capstone(&fw)) {
6393 exit(1);
6394 }
6395 firmware_init_data_ranges(&fw);
6396
6397 out_fp = fopen(argv[3],"w");
6398 if (out_fp == NULL) {
6399 fprintf(stderr,"Error opening output file %s\n",argv[3]);
6400 exit(1);
6401 }
6402
6403
6404
6405 find_ctypes(&fw);
6406
6407 run_sig_rules(&fw,sig_rules_initial);
6408 find_generic_funcs(&fw);
6409 run_sig_rules(&fw,sig_rules_main);
6410
6411 output_firmware_vals(&fw);
6412
6413 output_platform_vals(&fw);
6414 output_physw_vals(&fw);
6415 output_modemap(&fw);
6416
6417 output_propcases(&fw);
6418 output_exmem_types(&fw);
6419
6420 write_stubs(&fw,max_find_sig);
6421
6422 write_output();
6423 fclose(out_fp);
6424
6425 write_func_lists(&fw);
6426
6427 firmware_unload(&fw);
6428
6429 clock_t t2 = clock();
6430
6431 printf("Time to generate stubs %.2f seconds\n",(double)(t2-t1)/(double)CLOCKS_PER_SEC);
6432
6433 return 0;
6434 }