This source file includes following definitions.
- bprintf
- add_blankline
- write_output
- add_prop_hit
- get_misc_val
- get_misc_val_value
- save_misc_val
- save_misc_val_blobs
- find_saved_sig_index
- find_saved_sig
- get_saved_sig_val
- find_saved_sig_index_by_adr
- find_saved_sig_by_val
- save_sig
- add_func_name
- save_sig_veneers
- save_sig_with_j
- find_next_sig_call
- is_sig_call
- init_disasm_sig_ref
- sig_match_str_r0_call
- sig_match_reg_evp
- sig_match_reg_evp_table
- sig_match_reg_evp_alt2
- sig_match_unreg_evp_table
- sig_match_evp_table_veneer
- sig_match_createtaskstrictly_alt
- sig_match_createtask_alt
- sig_match_get_nd_value
- sig_match_get_current_exp
- sig_match_get_current_nd_value
- sig_match_get_current_deltasv
- sig_match_imager_active_callback
- sig_match_imager_active
- sig_match_screenlock_helper
- sig_match_fclose_low
- sig_match_screenunlock
- sig_match_log_camera_event
- sig_match_physw_misc
- sig_match_kbd_read_keys
- sig_match_get_kbd_state
- sig_match_get_dial_hw_position
- sig_match_create_jumptable
- sig_match_take_semaphore_strict
- sig_match_get_semaphore_value
- sig_match_stat
- sig_match_open
- sig_match_umalloc
- sig_match_ufree
- sig_match_deletefile_fut
- sig_match_closedir
- save_sig_match_call
- sig_match_readfastdir
- sig_match_strrchr
- sig_match_time
- sig_match_strncpy
- sig_match_strncmp
- sig_match_strtolx
- sig_match_exec_evp
- sig_match_fgets_fut
- sig_match_log
- sig_match_pow_dry_52
- sig_match_pow_dry_gt_52
- sig_match_sqrt
- sig_match_get_drive_cluster_size
- sig_match_mktime_ext
- sig_match_rec2pb
- sig_match_get_parameter_data
- sig_match_prepdir_x
- sig_match_prepdir_1
- sig_match_prepdir_0
- sig_match_mkdir
- sig_match_add_ptp_handler
- sig_match_qsort
- sig_match_deletedirectory_fut
- sig_match_set_control_event
- sig_match_displaybusyonscreen_52
- sig_match_undisplaybusyonscreen_52
- sig_match_try_take_sem_dry_gt_57
- sig_match_wait_all_eventflag_strict
- sig_match_get_num_posted_messages
- sig_match_set_hp_timer_after_now
- sig_match_transfer_src_overlay
- sig_match_exmem_vars
- sig_match_zicokick_52
- sig_match_zicokick_gt52
- sig_match_zicokick_copy
- sig_match_zicokick_values
- sig_match_init_ex_drivers
- sig_match_omar_init
- sig_match_init_error_handlers
- sig_match_default_assert_handler
- sig_match_default_exception_handler
- sig_match_default_panic_handler
- sig_match_get_task_properties
- sig_match_enable_hdmi_power
- sig_match_disable_hdmi_power
- sig_match_levent_table
- sig_match_flash_param_table
- sig_match_jpeg_count_str
- sig_match_misc_flag_named
- sig_match_dry_memset
- sig_match_dry_memzero
- sig_match_dry_memzero
- sig_match_dry_memcpy_bytes
- sig_match_cam_has_iris_diaphragm
- sig_match_cam_uncached_bit
- sig_match_umalloc_strictly
- sig_match_dcache_clean_flush_and_disable
- sig_match_get_rom_id
- sig_match_dcache_flush_and_enable
- sig_match_physw_event_table
- sig_match_uiprop_count
- sig_match_get_canon_mode_list
- sig_match_zoom_busy
- sig_match_focus_busy
- sig_match_aram_size
- sig_match_aram_size_gt58
- sig_match_aram_start
- sig_match_aram_start2
- sig_match_icache_flush_range
- sig_match__nrflag
- sig_match_var_struct_get
- sig_match_ui_mem_func_ptr
- sig_match_func_ptr_val
- sig_match_av_over_sem
- sig_match_canon_menu_active
- sig_match_file_counter_init
- sig_match_file_counter_var
- sig_match_palette_vars
- sig_match_live_free_cluster_count
- sig_match_rom_ptr_get
- find_call_near_str
- sig_match_near_str
- find_str_arg_call
- sig_match_str_arg_call
- sig_match_prop_string
- is_immediate_ret_sub
- sig_match_named_last
- sig_match_named_save_sig
- sig_match_named
- sig_rule_applies
- run_sig_rules
- add_event_proc
- process_reg_eventproc_call
- process_eventproc_table_call
- process_createtask_call
- save_ptp_handler_func
- process_add_ptp_handler_call
- add_generic_func_match
- add_generic_sig_match
- find_exception_handlers
- find_generic_funcs
- find_ctypes
- print_misc_val_makefile
- output_firmware_vals
- print_platform_misc_val_undef
- output_platform_vals
- output_propcases
- output_exmem_types
- print_misc_val_comment
- get_physw_table_entry
- find_physw_table_entry
- find_physw_table_max
- write_physw_event_table_dump
- print_kval
- add_kinfo
- add_kmval
- kinfo_compare
- print_kmvals
- do_km_vals
- output_physw_vals
- output_modemap
- compare_sig_names
- compare_func_addresses
- write_funcs
- write_func_lists
- print_other_stubs_min
- print_stubs_min_def
- find_other_stubs_min
- print_results
- write_stubs
- main
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <stdint.h>
4 #include <string.h>
5 #include <time.h>
6 #include <stdarg.h>
7
8 #include <inttypes.h>
9
10 #include <capstone.h>
11
12
13 #include "stubs_load.h"
14 #include "firmware_load_ng.h"
15 #include "ptp_op_names.h"
16
17
18
19 #define SEARCH_NEAR_REF_RANGE 1024
20
21 #define SIG_NEAR_OFFSET_MASK 0x00FF
22 #define SIG_NEAR_COUNT_MASK 0xFF00
23 #define SIG_NEAR_COUNT_SHIFT 8
24 #define SIG_NEAR_REV 0x10000
25 #define SIG_NEAR_INDIRECT 0x20000
26 #define SIG_NEAR_JMP_SUB 0x40000
27 #define SIG_NEAR_AFTER(max_insns,n) (((max_insns)&SIG_NEAR_OFFSET_MASK) \
28 | (((n)<<SIG_NEAR_COUNT_SHIFT)&SIG_NEAR_COUNT_MASK))
29 #define SIG_NEAR_BEFORE(max_insns,n) (SIG_NEAR_AFTER(max_insns,n)|SIG_NEAR_REV)
30
31 #define SIG_STRCALL_ARG_MASK 0x3
32 #define SIG_STRCALL_ARG(arg_num) (arg_num)
33
34
35 char out_buf[32*1024] = "";
36 int out_len = 0;
37 char hdr_buf[32*1024] = "";
38 int hdr_len = 0;
39 int out_hdr = 1;
40
41 FILE *out_fp;
42
43 void bprintf(char *fmt, ...)
44 {
45 va_list argp;
46 va_start(argp, fmt);
47
48 if (out_hdr)
49 hdr_len += vsprintf(hdr_buf+hdr_len,fmt,argp);
50 else
51 out_len += vsprintf(out_buf+out_len,fmt,argp);
52
53 va_end(argp);
54 }
55
56 void add_blankline()
57 {
58 if (strcmp(hdr_buf+hdr_len-2,"\n\n") != 0)
59 {
60 hdr_buf[hdr_len++] = '\n';
61 hdr_buf[hdr_len] = 0;
62 }
63 }
64
65 void write_output()
66 {
67 add_blankline();
68 if (out_fp)
69 {
70 fprintf(out_fp,"%s",hdr_buf);
71 fprintf(out_fp,"%s",out_buf);
72 }
73 }
74
75
76
77 #define DONT_EXPORT 0x01
78 #define OPTIONAL 0x02
79 #define UNUSED 0x04
80 #define BAD_MATCH 0x08
81 #define EV_MATCH 0x10
82 #define LIST_ALWAYS 0x20
83
84 #define ARM_STUB 0x80
85 #define DONT_EXPORT_ILC 0x100
86
87 typedef struct {
88 char *name;
89 int flags;
90 uint32_t val;
91 } sig_entry_t;
92
93 int next_sig_entry = 0;
94
95 #define MAX_SIG_ENTRY 5000
96
97 sig_entry_t sig_names[MAX_SIG_ENTRY] =
98 {
99
100 { "ExportToEventProcedure_FW", UNUSED|DONT_EXPORT },
101 { "RegisterEventProcedure", UNUSED|DONT_EXPORT },
102 { "RegisterEventProcedure_alt1", UNUSED|DONT_EXPORT },
103 { "RegisterEventProcedure_alt2", UNUSED|DONT_EXPORT },
104 { "RegisterEventProcTable", UNUSED|DONT_EXPORT },
105 { "UnRegisterEventProcTable", UNUSED|DONT_EXPORT },
106 { "UnRegisterEventProcedure", UNUSED|DONT_EXPORT },
107 { "PrepareDirectory_1", UNUSED|DONT_EXPORT },
108 { "PrepareDirectory_x", UNUSED|DONT_EXPORT },
109 { "PrepareDirectory_0", UNUSED|DONT_EXPORT },
110 { "CreateTaskStrictly", UNUSED|DONT_EXPORT },
111 { "CreateTaskStrictly_alt", UNUSED|DONT_EXPORT },
112 { "CreateTask_alt", UNUSED|DONT_EXPORT },
113 { "CreateTask_low", UNUSED | OPTIONAL },
114 { "CreateJumptable", UNUSED },
115 { "_uartr_req", UNUSED },
116 { "StartRecModeMenu", UNUSED },
117 { "LogCameraEvent", UNUSED|DONT_EXPORT },
118 { "getImageDirName", UNUSED|DONT_EXPORT },
119
120 { "AllocateMemory", UNUSED|LIST_ALWAYS },
121 { "AllocateUncacheableMemory" },
122 { "Close" },
123 { "CreateBinarySemaphore" },
124 { "CreateCountingSemaphore", UNUSED|LIST_ALWAYS },
125 { "CreateTask" },
126 { "DebugAssert", OPTIONAL|LIST_ALWAYS },
127 { "DeleteDirectory_Fut" },
128 { "DeleteFile_Fut" },
129 { "DeleteSemaphore", },
130 { "DoAELock" },
131 { "DoAFLock" },
132 { "EnterToCompensationEVF" },
133 { "ExecuteEventProcedure", ARM_STUB },
134 { "ExitFromCompensationEVF" },
135 { "ExitTask" },
136 { "ExpCtrlTool_StartContiAE" },
137 { "ExpCtrlTool_StopContiAE" },
138 { "Fclose_Fut" },
139 { "Feof_Fut" },
140 { "Fflush_Fut" },
141 { "Fgets_Fut" },
142 { "Fopen_Fut" },
143 { "Fread_Fut" },
144 { "FreeMemory", UNUSED|LIST_ALWAYS },
145 { "FreeUncacheableMemory" },
146 { "Fseek_Fut" },
147 { "Fwrite_Fut" },
148 { "GetBatteryTemperature" },
149 { "GetCCDTemperature" },
150
151 { "GetCurrentAvValue" },
152 { "GetCurrentShutterSpeed" },
153 { "GetUsableMaxAv", OPTIONAL },
154 { "GetUsableMinAv", OPTIONAL },
155 { "GetUsableAvRange", UNUSED |OPTIONAL },
156 { "get_nd_value", OPTIONAL },
157 { "get_current_exp", UNUSED | OPTIONAL },
158 { "get_current_nd_value", OPTIONAL },
159 { "get_current_deltasv", },
160 { "GetCurrentDriveBaseSvValue", },
161 { "GetDrive_ClusterSize" },
162 { "GetDrive_FreeClusters", UNUSED },
163 { "GetDrive_TotalClusters" },
164 { "GetFocusLensSubjectDistance" },
165 { "GetFocusLensSubjectDistanceFromLens" },
166 { "GetImageFolder", OPTIONAL },
167 { "GetKbdState" },
168 { "GetMemInfo" },
169 { "GetOpticalTemperature" },
170 { "GetParameterData" },
171 { "GetPropertyCase" },
172 { "GetSystemTime" },
173 { "GetVRAMHPixelsSize" },
174 { "GetVRAMVPixelsSize" },
175 { "GetZoomLensCurrentPoint" },
176 { "GetZoomLensCurrentPosition" },
177 { "GiveSemaphore", OPTIONAL|LIST_ALWAYS },
178 { "IsStrobeChargeCompleted" },
179 { "LEDDrive", OPTIONAL },
180 { "LocalTime" },
181 { "LockMainPower" },
182 { "Lseek", UNUSED|LIST_ALWAYS },
183 { "MakeDirectory_Fut" },
184 { "MakeSDCardBootable", OPTIONAL },
185 { "MoveFocusLensToDistance" },
186 { "MoveIrisWithAv", OPTIONAL },
187 { "MoveZoomLensWithPoint", DONT_EXPORT_ILC},
188 { "NewTaskShell", UNUSED },
189 { "Open" },
190 { "PB2Rec" },
191 { "PT_MoveDigitalZoomToWide", OPTIONAL | DONT_EXPORT_ILC},
192 { "PT_MoveOpticalZoomAt", OPTIONAL | DONT_EXPORT_ILC },
193 { "MoveOpticalZoomAt", OPTIONAL | DONT_EXPORT_ILC },
194 { "PT_PlaySound" },
195 { "PostLogicalEventForNotPowerType" },
196 { "PostLogicalEventToUI" },
197 { "PutInNdFilter", OPTIONAL },
198 { "PutOutNdFilter", OPTIONAL },
199 { "Read" },
200 { "ReadFastDir" },
201 { "Rec2PB" },
202 { "Remove", OPTIONAL|UNUSED },
203 { "RenameFile_Fut" },
204 { "Restart" },
205 { "screenlock_helper", UNUSED|DONT_EXPORT },
206 { "ScreenLock" },
207 { "ScreenUnlock" },
208 { "SetAE_ShutterSpeed" },
209 { "SetAutoShutdownTime" },
210 { "SetCurrentCaptureModeType" },
211 { "SetDate" },
212 { "SetFileAttributes" },
213 { "SetFileTimeStamp" },
214 { "SetLogicalEventActive" },
215 { "SetParameterData" },
216 { "SetPropertyCase" },
217 { "SetScriptMode" },
218 { "SleepTask" },
219 { "TakeSemaphore" },
220 { "TurnOffBackLight" },
221 { "TurnOnBackLight" },
222 { "TurnOnDisplay" },
223 { "TurnOffDisplay" },
224 { "UIFS_WriteFirmInfoToFile", OPTIONAL|UNUSED},
225 { "UnlockAE" },
226 { "UnlockAF" },
227 { "UnlockMainPower" },
228 { "UnsetZoomForMovie", OPTIONAL | DONT_EXPORT_ILC },
229
230 { "VbattGet" },
231 { "Write" },
232 { "WriteSDCard" },
233
234 { "_log" },
235 { "_log10" },
236 { "_pow" },
237 { "_sqrt" },
238 { "add_ptp_handler" },
239 { "apex2us" },
240 { "close" },
241 { "displaybusyonscreen", OPTIONAL },
242 { "err_init_task", OPTIONAL },
243 { "exmem_alloc", OPTIONAL },
244 { "exmem_free", OPTIONAL|UNUSED },
245 { "exmem_ualloc" },
246 { "exmem_ufree" },
247 { "free" },
248
249 { "kbd_p1_f" },
250 { "kbd_p1_f_cont" },
251 { "kbd_p2_f" },
252 { "kbd_read_keys" },
253 { "kbd_read_keys_r2" },
254
255 { "kbd_pwr_off", OPTIONAL },
256 { "kbd_pwr_on", OPTIONAL },
257 { "lseek" },
258 { "malloc" },
259 { "memcmp" },
260 { "memcpy" },
261 { "memset" },
262
263
264 { "mktime_ext" },
265 { "open" },
266 { "OpenFastDir" },
267 { "closedir" },
268 { "get_fstype", OPTIONAL|LIST_ALWAYS },
269 { "qsort" },
270 { "rand" },
271 { "read", UNUSED|OPTIONAL },
272 { "realloc", OPTIONAL|LIST_ALWAYS },
273 { "reboot_fw_update" },
274 { "set_control_event" },
275 { "srand" },
276 { "stat" },
277 { "strcat" },
278 { "strchr" },
279 { "strcmp" },
280 { "strcpy" },
281 { "strftime" },
282 { "strlen" },
283 { "strncmp" },
284 { "strncpy" },
285 { "strrchr" },
286 { "strtol" },
287 { "strtolx" },
288 { "strstr", UNUSED|OPTIONAL},
289
290 { "task_CaptSeq" },
291 { "task_DvlpSeqTask", OPTIONAL },
292 { "task_ExpDrv" },
293 { "task_FileWrite", OPTIONAL },
294 { "task_InitFileModules" },
295 { "task_MovieRecord" },
296 { "task_PhySw", OPTIONAL },
297 { "task_RotaryEncoder", OPTIONAL },
298 { "task_TouchPanel", OPTIONAL },
299 { "task_TricInitTask", OPTIONAL },
300
301 { "hook_CreateTask" },
302 { "hook_CreateTask_low", UNUSED},
303
304 { "time" },
305 { "vsprintf" },
306 { "write", UNUSED|OPTIONAL },
307 { "undisplaybusyonscreen", OPTIONAL },
308
309 { "EngDrvIn", OPTIONAL|UNUSED|LIST_ALWAYS },
310 { "EngDrvOut", OPTIONAL|UNUSED|LIST_ALWAYS },
311 { "EngDrvRead" },
312 { "EngDrvBits", OPTIONAL|UNUSED|LIST_ALWAYS },
313
314 { "PTM_GetCurrentItem" },
315 { "PTM_SetCurrentItem", UNUSED|LIST_ALWAYS },
316 { "PTM_NextItem", OPTIONAL|UNUSED|LIST_ALWAYS },
317 { "PTM_PrevItem", OPTIONAL|UNUSED|LIST_ALWAYS },
318 { "PTM_SetPropertyEnable", OPTIONAL|UNUSED|LIST_ALWAYS },
319
320 { "DisableISDriveError", OPTIONAL },
321
322
323 { "_GetSystemTime", OPTIONAL|UNUSED|LIST_ALWAYS },
324 { "SetTimerAfter", OPTIONAL|UNUSED|LIST_ALWAYS },
325 { "SetTimerWhen", OPTIONAL|UNUSED|LIST_ALWAYS },
326 { "CancelTimer", OPTIONAL|UNUSED|LIST_ALWAYS },
327 { "CancelHPTimer" },
328 { "SetHPTimerAfterTimeout", OPTIONAL|UNUSED|LIST_ALWAYS },
329 { "SetHPTimerAfterNow" },
330 { "CreateTaskStrictly", OPTIONAL|UNUSED|LIST_ALWAYS },
331 { "CreateMessageQueue", OPTIONAL|UNUSED|LIST_ALWAYS },
332 { "CreateRecursiveLock", OPTIONAL|UNUSED|LIST_ALWAYS },
333 { "GetSemaphoreValue", OPTIONAL|UNUSED|LIST_ALWAYS },
334 { "TryTakeSemaphore", OPTIONAL|UNUSED|LIST_ALWAYS },
335 { "CreateMessageQueueStrictly", OPTIONAL|UNUSED|LIST_ALWAYS },
336 { "CreateEventFlagStrictly", OPTIONAL|UNUSED|LIST_ALWAYS },
337 { "CreateBinarySemaphoreStrictly", OPTIONAL|UNUSED|LIST_ALWAYS },
338 { "CreateCountingSemaphoreStrictly", OPTIONAL|UNUSED|LIST_ALWAYS },
339 { "CreateRecursiveLockStrictly", OPTIONAL|UNUSED|LIST_ALWAYS },
340 { "TakeSemaphoreStrictly", OPTIONAL|UNUSED|LIST_ALWAYS },
341 { "ReceiveMessageQueueStrictly", OPTIONAL|UNUSED|LIST_ALWAYS },
342 { "PostMessageQueueStrictly", OPTIONAL|UNUSED|LIST_ALWAYS },
343 { "WaitForAnyEventFlagStrictly", OPTIONAL|UNUSED|LIST_ALWAYS },
344 { "WaitForAllEventFlagStrictly", OPTIONAL|UNUSED|LIST_ALWAYS },
345 { "AcquireRecursiveLockStrictly", OPTIONAL|UNUSED|LIST_ALWAYS },
346 { "DeleteMessageQueue", OPTIONAL|UNUSED|LIST_ALWAYS },
347 { "PostMessageQueue", OPTIONAL|UNUSED|LIST_ALWAYS },
348 { "ReceiveMessageQueue", OPTIONAL|UNUSED|LIST_ALWAYS },
349 { "TryReceiveMessageQueue", OPTIONAL|UNUSED|LIST_ALWAYS },
350 { "TryPostMessageQueue", OPTIONAL|UNUSED|LIST_ALWAYS },
351 { "GetNumberOfPostedMessages", OPTIONAL|UNUSED|LIST_ALWAYS },
352 { "DeleteRecursiveLock", OPTIONAL|UNUSED|LIST_ALWAYS },
353 { "AcquireRecursiveLock", OPTIONAL|UNUSED|LIST_ALWAYS },
354 { "ReleaseRecursiveLock", OPTIONAL|UNUSED|LIST_ALWAYS },
355 { "WaitForAnyEventFlag", OPTIONAL|UNUSED|LIST_ALWAYS },
356 { "WaitForAllEventFlag", OPTIONAL|UNUSED|LIST_ALWAYS },
357 { "ClearEventFlag", OPTIONAL|UNUSED|LIST_ALWAYS },
358 { "SetEventFlag", OPTIONAL|LIST_ALWAYS },
359 { "GetEventFlagValue", OPTIONAL|UNUSED|LIST_ALWAYS },
360 { "CreateEventFlag", OPTIONAL|UNUSED|LIST_ALWAYS },
361 { "DeleteEventFlag", OPTIONAL|UNUSED|LIST_ALWAYS },
362 { "CheckAnyEventFlag", OPTIONAL|UNUSED|LIST_ALWAYS },
363 { "CheckAllEventFlag", OPTIONAL|UNUSED|LIST_ALWAYS },
364 { "RegisterInterruptHandler", OPTIONAL|UNUSED|LIST_ALWAYS },
365 { "UnregisterInterruptHandler", OPTIONAL|UNUSED|LIST_ALWAYS },
366 { "GetSRAndDisableInterrupt", OPTIONAL|UNUSED|LIST_ALWAYS },
367 { "SetSR", OPTIONAL|UNUSED|LIST_ALWAYS },
368 { "EnableInterrupt", OPTIONAL|UNUSED|LIST_ALWAYS },
369 { "_divmod_signed_int", OPTIONAL|UNUSED|LIST_ALWAYS},
370 { "_divmod_unsigned_int", OPTIONAL|UNUSED|LIST_ALWAYS},
371 { "_dflt", OPTIONAL|UNUSED|LIST_ALWAYS},
372 { "_dfltu", OPTIONAL|UNUSED|LIST_ALWAYS},
373 { "_dfix", OPTIONAL|UNUSED|LIST_ALWAYS},
374 { "_dfixu", OPTIONAL|UNUSED|LIST_ALWAYS},
375 { "_dmul", OPTIONAL|UNUSED|LIST_ALWAYS},
376 { "_ddiv", OPTIONAL|UNUSED|LIST_ALWAYS},
377 { "_dadd", OPTIONAL|UNUSED|LIST_ALWAYS},
378 { "_dsub", OPTIONAL|UNUSED|LIST_ALWAYS},
379 { "_drsb", OPTIONAL|UNUSED|LIST_ALWAYS},
380 { "_dcmp", OPTIONAL|UNUSED|LIST_ALWAYS},
381 { "_dcmp_reverse", OPTIONAL|UNUSED|LIST_ALWAYS},
382 { "_safe_sqrt", OPTIONAL|UNUSED|LIST_ALWAYS},
383 { "_scalbn", OPTIONAL|UNUSED|LIST_ALWAYS},
384 { "_fflt", OPTIONAL|UNUSED|LIST_ALWAYS},
385 { "_ffltu", OPTIONAL|UNUSED|LIST_ALWAYS},
386 { "_ffix", OPTIONAL|UNUSED|LIST_ALWAYS},
387 { "_ffixu", OPTIONAL|UNUSED|LIST_ALWAYS},
388 { "_fmul", OPTIONAL|UNUSED|LIST_ALWAYS},
389 { "_fdiv", OPTIONAL|UNUSED|LIST_ALWAYS},
390 { "_f2d", OPTIONAL|UNUSED|LIST_ALWAYS},
391 { "DisplayBusyOnScreen", OPTIONAL|UNUSED|LIST_ALWAYS},
392 { "UndisplayBusyOnScreen", OPTIONAL|UNUSED|LIST_ALWAYS},
393 { "CreateDialogBox", OPTIONAL|UNUSED|LIST_ALWAYS},
394 { "DisplayDialogBox", OPTIONAL|UNUSED|LIST_ALWAYS},
395 { "add_ui_to_dialog", OPTIONAL|UNUSED|LIST_ALWAYS},
396 { "get_string_by_id", OPTIONAL|UNUSED|LIST_ALWAYS},
397 { "malloc_strictly", OPTIONAL|UNUSED|LIST_ALWAYS },
398 { "GetCurrentMachineTime", OPTIONAL|UNUSED|LIST_ALWAYS },
399 { "HwOcReadICAPCounter", OPTIONAL|UNUSED|LIST_ALWAYS },
400 { "transfer_src_overlay_helper",UNUSED},
401 { "transfer_src_overlay" },
402 { "GraphicSystemCoreFinish_helper", OPTIONAL|UNUSED },
403 { "GraphicSystemCoreFinish", OPTIONAL|UNUSED },
404 { "mzrm_createmsg", OPTIONAL|UNUSED },
405 { "mzrm_sendmsg", OPTIONAL|UNUSED },
406 { "zicokick_start", OPTIONAL|UNUSED },
407 { "zicokick_copy", OPTIONAL|UNUSED },
408 { "init_ex_drivers", OPTIONAL|UNUSED },
409 { "omar_init", OPTIONAL|UNUSED },
410 { "init_error_handlers", OPTIONAL|UNUSED },
411 { "set_assert_handler", OPTIONAL|UNUSED },
412 { "set_exception_handler", OPTIONAL|UNUSED },
413 { "set_panic_handler", OPTIONAL|UNUSED },
414 { "default_assert_handler", OPTIONAL|UNUSED },
415 { "default_exception_handler", OPTIONAL|UNUSED },
416 { "default_panic_handler", OPTIONAL|UNUSED },
417 { "get_self_task_errno_pointer", OPTIONAL|UNUSED },
418 { "get_self_task_id", OPTIONAL|UNUSED },
419 { "get_task_properties", OPTIONAL|UNUSED },
420 { "dry_error_printf", OPTIONAL|UNUSED },
421 { "heap_alloc", OPTIONAL|UNUSED },
422 { "heap_free", OPTIONAL|UNUSED },
423 { "umalloc_strictly", OPTIONAL|UNUSED },
424 { "GetRomID", OPTIONAL|UNUSED },
425 { "init_task_error", OPTIONAL|UNUSED },
426 { "dry_panic", OPTIONAL|UNUSED },
427 { "dry_panic_low", OPTIONAL|UNUSED },
428 { "dry_con_printf", OPTIONAL|UNUSED },
429 { "cameracon_set_state", UNUSED },
430 { "cameracon_get_state", UNUSED },
431
432 { "createsemaphore_low", OPTIONAL|UNUSED },
433
434 { "givesemaphore_low", OPTIONAL|UNUSED},
435 { "takesemaphore_low", OPTIONAL|UNUSED },
436 { "bzero" },
437 { "memset32" },
438 { "dry_memset", OPTIONAL|UNUSED },
439 { "dry_memzero", OPTIONAL|UNUSED },
440 { "dry_memcpy_bytes", OPTIONAL|UNUSED },
441 { "dry_memmove_bytes", OPTIONAL|UNUSED },
442 { "get_dial_hw_position", OPTIONAL },
443
444
445
446 { "dcache_flush_and_enable", OPTIONAL|UNUSED },
447 { "dcache_clean_flush_and_disable", OPTIONAL|UNUSED },
448 { "dcache_flush_range", OPTIONAL|UNUSED },
449 { "dcache_clean_range", OPTIONAL|UNUSED },
450
451 { "icache_flush_range", OPTIONAL|UNUSED },
452 { "data_synchronization_barrier", OPTIONAL|UNUSED },
453
454
455 { "GetSDProtect", UNUSED },
456 { "DispCon_ShowBitmapColorBar", UNUSED },
457 { "ResetZoomLens", OPTIONAL|UNUSED },
458 { "ResetFocusLens", OPTIONAL|UNUSED },
459 { "NR_GetDarkSubType", OPTIONAL|UNUSED },
460 { "NR_SetDarkSubType", OPTIONAL|UNUSED },
461 { "SavePaletteData", OPTIONAL|UNUSED },
462 { "GUISrv_StartGUISystem", OPTIONAL|UNUSED|LIST_ALWAYS },
463 { "get_resource_pointer", OPTIONAL|UNUSED|LIST_ALWAYS },
464 { "CalcLog10", OPTIONAL|UNUSED|LIST_ALWAYS },
465 { "CalcSqrt", OPTIONAL|UNUSED },
466 { "dry_memcpy", OPTIONAL|UNUSED },
467 { "get_playrec_mode", OPTIONAL|UNUSED },
468 { "DebugAssert2", OPTIONAL|UNUSED },
469 { "get_canon_mode_list", OPTIONAL|UNUSED },
470 { "taskcreate_LowConsole", OPTIONAL|UNUSED },
471 { "ImagerActivate", OPTIONAL|UNUSED },
472 { "imager_active_callback", OPTIONAL|UNUSED },
473 { "file_counter_var_init", OPTIONAL|UNUSED },
474 { "get_displaytype", OPTIONAL|UNUSED },
475
476 { "Close_low", OPTIONAL|UNUSED },
477 { "Open_low", OPTIONAL|UNUSED },
478
479
480 { "fclose_low", OPTIONAL|UNUSED },
481
482
483 { "fgets_low", OPTIONAL|UNUSED },
484 { "fopen_low", OPTIONAL|UNUSED },
485 { "fut_prepare", OPTIONAL|UNUSED },
486 { "fut_finish", OPTIONAL|UNUSED },
487 { "fut_flush", OPTIONAL|UNUSED },
488 { "fread_low", OPTIONAL|UNUSED },
489 { "fseek_low", OPTIONAL|UNUSED },
490 { "fwrite_low", OPTIONAL|UNUSED },
491
492 { "MFOn", OPTIONAL },
493 { "MFOff", OPTIONAL },
494 { "PT_MFOn", OPTIONAL },
495 { "PT_MFOff", OPTIONAL },
496 { "SS_MFOn", OPTIONAL },
497 { "SS_MFOff", OPTIONAL },
498
499 { "GetAdChValue", OPTIONAL },
500
501
502 { "EnableHDMIPower", OPTIONAL },
503 { "DisableHDMIPower", OPTIONAL },
504
505 { "SetVideoOutType", OPTIONAL },
506 { "GetVideoOutType", OPTIONAL },
507
508 { "is_movie_recording", OPTIONAL|UNUSED },
509 { "IsWirelessConnect", OPTIONAL },
510
511 { "ui_malloc", OPTIONAL|UNUSED },
512 { "ui_malloc_default", OPTIONAL|UNUSED },
513 { "ui_free", OPTIONAL|UNUSED },
514 { "ui_free_default", OPTIONAL|UNUSED },
515
516
517 { "pvm_get_largest_free_block_size_ptr", OPTIONAL|UNUSED },
518 { "pvm_get_largest_free_block_size", OPTIONAL|UNUSED },
519 { "pvm_malloc", OPTIONAL|UNUSED },
520 { "pvm_free", OPTIONAL|UNUSED },
521 { "pvm_init_pool", OPTIONAL|UNUSED },
522
523 {0,0,0},
524 };
525
526 typedef struct {
527 char* name;
528 int id;
529 int use;
530
531 int id_ps6;
532 int id_ps7;
533 int id_ps8;
534 int id_ps9;
535 int id_ps10;
536 int id_ps11;
537 int id_ps12;
538 int id_ps13;
539 } known_prop_t;
540
541 #define KNOWN_PROPSET_COUNT (13-5)
542
543 known_prop_t knownprops[] =
544 {
545 {"PROPCASE_AFSTEP" , -1, 2, 13, 13, 13, 13, 13, 13, 13, 13},
546 {"PROPCASE_FOCUS_STATE" , -1, 1, 18, 18, 18, 18, 18, 18, 18, 18},
547 {"PROPCASE_AV" , -1, 1, 23, 23, 23, 23, 23, 23, 23, 23},
548 {"PROPCASE_BV" , -1, 1, 34, 38, 35, 38, 40, 40, 40, 40},
549 {"PROPCASE_DELTA_DIGITALGAIN" , -1, 2, 77, 82, 79, 82, 84, 85, 85, 84},
550 {"PROPCASE_DELTA_SV" , -1, 1, 79, 84, 81, 84, 86, 87, 87, 86},
551 {"PROPCASE_DELTA_ND" , -1, 2, 80, 85, 82, 85, 87, 88, 88, 87},
552 {"PROPCASE_FELOCK" , -1, 2,114,120,117,120, 122, 123, 123, 122},
553 {"PROPCASE_FLASH_ADJUST_MODE" , -1, 1,121,127,124,127, 129, 130, 130, 129},
554 {"PROPCASE_FLASH_FIRE" , -1, 1,122,128,125,128, 130, 131, 131, 130},
555 {"PROPCASE_HSCAPTURE" , -1, 2,138,144,141,144, 146, 147, 147, 146},
556 {"PROPCASE_EV_CORRECTION_2" , -1, 1,210,216,213,216, 218, 219, 220, 218},
557 {"PROPCASE_ORIENTATION_SENSOR" , -1, 1,222,228,225,228, 230, 231, 232, 230},
558 {"PROPCASE_SV_MARKET" , -1, 1,249,255,252,255, 257, 259, 260, 258},
559 {"PROPCASE_SVFIX" , -1, 0, 0, 0, 0, 0, 0, 0, 0, 259},
560 {"PROPCASE_TV" , -1, 1,265,272,269,272, 274, 276, 277, 275},
561 {0,}
562 };
563
564 void add_prop_hit(char *name, int id)
565 {
566 int n = 0;
567 while (knownprops[n].name) {
568 if (strcmp(knownprops[n].name,name) == 0) {
569 knownprops[n].id = id;
570 break;
571 }
572 n++;
573 }
574 }
575
576 #define MISC_BLOB_XTENSA_MAX 5
577 #define MISC_BLOB_TYPE_NONE 0
578 #define MISC_BLOB_TYPE_XTENSA 1
579 #define MISC_BLOB_TYPE_OMAR 2
580 typedef struct {
581 int type;
582 uint32_t rom_adr;
583 uint32_t ram_adr;
584 uint32_t size;
585 } misc_blob_t;
586
587
588 #define MISC_VAL_NO_STUB 1
589
590 #define MISC_VAL_DEF_CONST 2
591 #define MISC_VAL_OPTIONAL 4
592
593 typedef struct {
594 char *name;
595 int flags;
596 uint32_t val;
597
598 uint32_t base;
599 uint32_t offset;
600 uint32_t ref_adr;
601 misc_blob_t *blobs;
602 } misc_val_t;
603
604 misc_val_t misc_vals[]={
605
606 { "ctypes", },
607 { "physw_run", },
608 { "physw_sleep_delay", },
609 { "physw_status", },
610 { "fileio_semaphore", },
611 { "levent_table", },
612 { "FlashParamsTable", },
613 { "playrec_mode", },
614 { "jpeg_count_str", },
615 { "zoom_busy", },
616 { "focus_busy", },
617 { "imager_active", },
618 { "canon_menu_active", },
619 { "file_counter_var", },
620 { "cameracon_state", },
621 { "_nrflag", MISC_VAL_OPTIONAL},
622 { "av_override_semaphore",MISC_VAL_OPTIONAL},
623 { "active_bitmap_buffer",MISC_VAL_OPTIONAL},
624 { "displaytype", MISC_VAL_OPTIONAL},
625 { "bitmap_buffer", MISC_VAL_OPTIONAL},
626 { "palette_control", MISC_VAL_OPTIONAL},
627 { "palette_buffer_ptr", MISC_VAL_OPTIONAL},
628 { "active_palette_buffer",MISC_VAL_OPTIONAL},
629 { "live_free_cluster_count",MISC_VAL_OPTIONAL},
630 { "CAM_UNCACHED_BIT", MISC_VAL_NO_STUB},
631 { "physw_event_table", MISC_VAL_NO_STUB},
632 { "uiprop_count", MISC_VAL_DEF_CONST},
633 { "canon_mode_list", MISC_VAL_NO_STUB},
634 { "ARAM_HEAP_START", MISC_VAL_NO_STUB},
635 { "ARAM_HEAP_SIZE", MISC_VAL_NO_STUB},
636 { "zicokick_values", MISC_VAL_NO_STUB},
637 { "omar_init_data", MISC_VAL_NO_STUB},
638 { "omar_init_values", MISC_VAL_NO_STUB},
639 { "CAM_HAS_ND_FILTER", MISC_VAL_NO_STUB},
640 { "CAM_IS_ILC", MISC_VAL_NO_STUB},
641 { "CAM_HAS_IRIS_DIAPHRAGM",MISC_VAL_NO_STUB},
642 { "CAM_HAS_WIFI", MISC_VAL_NO_STUB},
643 { "exmem_alloc_table", },
644 { "exmem_types_table", },
645 { "exmem_type_count", MISC_VAL_DEF_CONST},
646 { "ui_malloc_ptr", MISC_VAL_NO_STUB},
647 { "ui_free_ptr", MISC_VAL_NO_STUB},
648
649 {0,0,0},
650 };
651
652 misc_val_t *get_misc_val(const char *name)
653 {
654 misc_val_t *p=misc_vals;
655 while(p->name) {
656 if(strcmp(name,p->name) == 0) {
657 return p;
658 }
659 p++;
660 }
661 return NULL;
662 }
663
664
665 uint32_t get_misc_val_value(const char *name)
666 {
667 misc_val_t *p=get_misc_val(name);
668 if(!p) {
669 printf("get_misc_val_value: invalid name %s\n",name);
670 return 0;
671 }
672 return p->val;
673 }
674 void save_misc_val(const char *name, uint32_t base, uint32_t offset, uint32_t ref_adr)
675 {
676 misc_val_t *p=get_misc_val(name);
677 if(!p) {
678 printf("save_misc_val: invalid name %s\n",name);
679 return;
680 }
681 p->val = base + offset;
682 p->base = base;
683 p->offset = offset;
684 p->ref_adr = ref_adr;
685 p->blobs = NULL;
686 }
687 void save_misc_val_blobs(const char *name, misc_blob_t *blobs, uint32_t ref_adr)
688 {
689 misc_val_t *p=get_misc_val(name);
690 if(!p) {
691 printf("save_misc_val: invalid name %s\n",name);
692 return;
693 }
694 p->val = p->base = p->offset = 0;
695 p->ref_adr = ref_adr;
696 p->blobs = blobs;
697 }
698
699
700 #if 0
701 int find_saved_sig_index(const char *name)
702 {
703 int i;
704 for (i=0; sig_names[i].name != 0; i++)
705 {
706 if (strcmp(name,sig_names[i].name) == 0)
707 {
708 return i;
709 }
710 }
711 return -1;
712 }
713 #endif
714
715 sig_entry_t * find_saved_sig(const char *name)
716 {
717 int i;
718 for (i=0; sig_names[i].name != 0; i++)
719 {
720 if (strcmp(name,sig_names[i].name) == 0)
721 {
722 return &sig_names[i];
723 }
724 }
725 return NULL;
726 }
727
728
729 uint32_t get_saved_sig_val(const char *name)
730 {
731 sig_entry_t *sig=find_saved_sig(name);
732 if(!sig) {
733
734 return 0;
735 }
736 return sig->val;
737 }
738
739
740
741 #if 0
742 int find_saved_sig_index_by_adr(uint32_t adr)
743 {
744 if(!adr) {
745 return -1;
746 }
747 int i;
748 for (i=0; sig_names[i].name != 0; i++)
749 {
750 if (sig_names[i].val == adr)
751 {
752 return i;
753 }
754 }
755 return -1;
756 }
757 #endif
758 #if 0
759 sig_entry_t* find_saved_sig_by_val(uint32_t val)
760 {
761 if(!val) {
762 return NULL;
763 }
764 int i;
765 for (i=0; sig_names[i].name != 0; i++)
766 {
767 if (sig_names[i].val == val)
768 {
769 return &sig_names[i];
770 }
771 }
772 return NULL;
773 }
774 #endif
775
776
777 void save_sig(firmware *fw, const char *name, uint32_t val)
778 {
779 sig_entry_t *sig = find_saved_sig(name);
780 if (!sig)
781 {
782 printf("save_sig: refusing to save unknown name %s\n",name);
783 return;
784 }
785
786 if(!adr_is_main_fw_code(fw,val)) {
787 printf("save_sig: refusing to save %s with out of range address 0x%08x\n",name,val);
788 return;
789 }
790 if(sig->val && sig->val != val) {
791 printf("save_sig: duplicate name %s existing 0x%08x != new 0x%08x\n",name,sig->val,val);
792 }
793 sig->val = val;
794 }
795
796 void add_func_name(firmware *fw, char *n, uint32_t eadr, char *suffix)
797 {
798 int k;
799
800 char *s = n;
801 int mallocd = 0;
802 if (suffix != 0)
803 {
804 s = malloc(strlen(n) + strlen(suffix) + 1);
805 sprintf(s, "%s%s", n, suffix);
806 mallocd = 1;
807 }
808
809
810 if(!adr_is_main_fw_code(fw,eadr)) {
811 printf("save_sig: refusing to save %s with out of range address 0x%08x\n",s,eadr);
812 if(mallocd) {
813 free(s);
814 }
815 return;
816 }
817
818 for (k=0; sig_names[k].name != 0; k++)
819 {
820 if (strcmp(sig_names[k].name, s) == 0)
821 {
822 if (sig_names[k].val == 0)
823 {
824 sig_names[k].val = eadr;
825 sig_names[k].flags |= EV_MATCH;
826 if (mallocd)
827 free(s);
828 return;
829 }
830 else if (sig_names[k].val == eadr)
831 {
832 if (mallocd)
833 free(s);
834 return;
835 }
836 else
837 {
838 printf("add_func_name: duplicate name %s existing 0x%08x != new 0x%08x\n",s, sig_names[k].val, eadr);
839 }
840 }
841 }
842
843 sig_names[next_sig_entry].name = s;
844 sig_names[next_sig_entry].flags = OPTIONAL|UNUSED;
845 sig_names[next_sig_entry].val = eadr;
846 next_sig_entry++;
847 sig_names[next_sig_entry].name = 0;
848 }
849
850
851 uint32_t save_sig_veneers(firmware *fw, const char *name, uint32_t adr)
852 {
853
854 if(!fw_disasm_iter_single(fw,adr)) {
855 printf("save_sig_veneers: %s disassembly failed at 0x%08x\n",name,adr);
856 return 0;
857 }
858
859
860 uint32_t b_adr;
861 int v_cnt;
862 for(v_cnt = 0, b_adr = get_direct_jump_target(fw,fw->is);
863 v_cnt < 10 && b_adr;
864 v_cnt++,b_adr = get_direct_jump_target(fw,fw->is)) {
865 char *buf=malloc(strlen(name)+7);
866 if(v_cnt) {
867 sprintf(buf,"j%d_%s",v_cnt,name);
868 } else {
869
870 sprintf(buf,"j_%s",name);
871 }
872 add_func_name(fw,buf,adr,NULL);
873 adr=b_adr;
874 if(!fw_disasm_iter_single(fw,adr)) {
875 printf("save_sig_veneers: %s disassembly failed at 0x%08x\n",name,adr);
876 return 0;
877 }
878 }
879 return adr;
880 }
881
882
883 int save_sig_with_j(firmware *fw, char *name, uint32_t adr)
884 {
885 if(!adr) {
886 printf("save_sig_with_j: %s null adr\n",name);
887 return 0;
888 }
889 adr = save_sig_veneers(fw, name, adr);
890 if(adr) {
891 save_sig(fw,name,adr);
892 return 1;
893 }
894 return 0;
895 }
896
897
898
899 int find_next_sig_call(firmware *fw, iter_state_t *is, uint32_t max_offset, const char *name)
900 {
901 uint32_t adr=get_saved_sig_val(name);
902
903 if(!adr) {
904 printf("find_next_sig_call: missing %s\n",name);
905 return 0;
906 }
907
908 search_calls_multi_data_t match_fns[12];
909
910 match_fns[0].adr=adr;
911 match_fns[0].fn=search_calls_multi_end;
912 char veneer[128];
913 int i;
914 for(i = 1; i<11; i++) {
915
916 if(i>1) {
917 sprintf(veneer,"j%d_%s",i-1,name);
918 } else {
919 sprintf(veneer,"j_%s",name);
920 }
921 adr=get_saved_sig_val(veneer);
922 if(!adr) {
923 break;
924 } else {
925 match_fns[i].adr=adr;
926 match_fns[i].fn=search_calls_multi_end;
927 }
928 }
929 match_fns[i].adr=0;
930 return fw_search_insn(fw,is,search_disasm_calls_veneer_multi,0,match_fns,is->adr + max_offset);
931 }
932
933
934 int is_sig_call(firmware *fw, iter_state_t *is, const char *name)
935 {
936 uint32_t adr=get_branch_call_insn_target(fw,is);
937
938
939 if(!adr) {
940 return 0;
941 }
942 uint32_t sig_adr=get_saved_sig_val(name);
943 osig* ostub2 = find_sig(fw->sv->stubs,name);
944 if (ostub2 && ostub2->val)
945 sig_adr = ostub2->val;
946 if(!sig_adr) {
947 printf("is_sig_call: missing %s\n",name);
948 return 0;
949 }
950 if(adr == sig_adr) {
951 return 1;
952 }
953 char veneer[128];
954 sprintf(veneer,"j_%s",name);
955 sig_adr=get_saved_sig_val(veneer);
956 if(!sig_adr) {
957 return 0;
958 }
959 return (adr == sig_adr);
960 }
961
962
963 #define SIG_DRY_MIN(min_rel) (min_rel)*FW_DRYOS_VER_MUL,0
964 #define SIG_DRY_MAX(max_rel) 0,(max_rel)*FW_DRYOS_VER_MUL+(FW_DRYOS_VER_MUL-1)
965 #define SIG_DRY_RANGE(min_rel,max_rel) (min_rel)*FW_DRYOS_VER_MUL,\
966 (max_rel)*FW_DRYOS_VER_MUL+(FW_DRYOS_VER_MUL-1)
967
968 #define SIG_DRY_MINP(min_rel,min_patch) (min_rel)*FW_DRYOS_VER_MUL + (min_patch),0
969 #define SIG_DRY_MAXP(max_rel,max_patch) 0,(max_rel)*FW_DRYOS_VER_MUL + (max_patch)
970 #define SIG_DRY_RANGEP(min_rel,min_patch,max_rel,max_patch) \
971 (min_rel)*FW_DRYOS_VER_MUL + (min_patch), \
972 (max_rel)*FW_DRYOS_VER_MUL + (max_patch)
973
974 #define SIG_DRY_ANY 0,0
975
976
977 #define SIG_NO_D6 1
978 #define SIG_NO_D7 2
979
980 typedef struct sig_rule_s sig_rule_t;
981 typedef int (*sig_match_fn)(firmware *fw, iter_state_t *is, sig_rule_t *rule);
982
983 struct sig_rule_s {
984 sig_match_fn match_fn;
985 char *name;
986 char *ref_name;
987 int param;
988 int dryos_min;
989 int dryos_max;
990 unsigned flags;
991 };
992
993
994 int init_disasm_sig_ref(firmware *fw, iter_state_t *is, sig_rule_t *rule)
995 {
996 if(!rule->ref_name) {
997 printf("init_disasm_sig_ref: %s missing ref_name\n",rule->name);
998 return 0;
999 }
1000 uint32_t adr=get_saved_sig_val(rule->ref_name);
1001 if(!adr) {
1002 printf("init_disasm_sig_ref: %s missing %s\n",rule->name,rule->ref_name);
1003 return 0;
1004 }
1005 if(!disasm_iter_init(fw,is,adr)) {
1006 printf("init_disasm_sig_ref: %s bad address 0x%08x for %s\n",rule->name,adr,rule->ref_name);
1007 return 0;
1008 }
1009 return 1;
1010 }
1011
1012 int sig_match_near_str(firmware *fw, iter_state_t *is, sig_rule_t *rule);
1013
1014
1015
1016
1017
1018 int sig_match_str_r0_call(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1019 {
1020 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
1021 if(!str_adr) {
1022 printf("sig_match_str_r0_call: %s failed to find ref %s\n",rule->name,rule->ref_name);
1023 return 0;
1024 }
1025
1026
1027
1028
1029 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
1030 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
1031 if(is->insn->detail->arm.operands[0].reg == ARM_REG_R0) {
1032
1033
1034 if(insn_match_find_next(fw,is,4,match_b_bl_blximm)) {
1035 uint32_t adr=get_branch_call_insn_target(fw,is);
1036
1037 return save_sig_with_j(fw,rule->name,adr);
1038 }
1039 }
1040 }
1041 return 0;
1042 }
1043
1044
1045 int sig_match_reg_evp(firmware *fw, iter_state_t *is, __attribute__ ((unused))sig_rule_t *rule)
1046 {
1047 const insn_match_t reg_evp_match[]={
1048 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R2), MATCH_OP_REG(R1)}},
1049 {MATCH_INS(LDR, 2), {MATCH_OP_REG(R1), MATCH_OP_MEM_ANY}},
1050 {MATCH_INS(B, MATCH_OPCOUNT_IGNORE)},
1051 {ARM_INS_ENDING}
1052 };
1053
1054 uint32_t e_to_evp=get_saved_sig_val("ExportToEventProcedure_FW");
1055 if(!e_to_evp) {
1056 printf("sig_match_reg_evp: failed to find ExportToEventProcedure, giving up\n");
1057 return 0;
1058 }
1059
1060
1061 uint32_t reg_evp=0;
1062
1063 disasm_iter_init(fw,is,e_to_evp);
1064 if(insn_match_seq(fw,is,reg_evp_match)) {
1065 reg_evp=ADR_SET_THUMB(is->insn->detail->arm.operands[0].imm);
1066
1067 save_sig(fw,"RegisterEventProcedure",reg_evp);
1068 }
1069 return (reg_evp != 0);
1070 }
1071
1072
1073
1074 int sig_match_reg_evp_table(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1075 {
1076
1077 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
1078 if(!str_adr) {
1079 printf("sig_match_reg_evp_table: failed to find %s\n",rule->ref_name);
1080 return 0;
1081 }
1082
1083 uint32_t reg_evp_alt1=0;
1084 uint32_t reg_evp_tbl=0;
1085 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
1086 uint32_t dd_enable_p=0;
1087 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
1088 if(is->insn->detail->arm.operands[0].reg != ARM_REG_R0) {
1089 continue;
1090 }
1091 if(!insn_match_find_next(fw,is,2,match_b_bl)) {
1092 continue;
1093 }
1094 reg_evp_alt1=ADR_SET_THUMB(is->insn->detail->arm.operands[0].imm);
1095
1096 save_sig(fw,"RegisterEventProcedure_alt1",reg_evp_alt1);
1097
1098 uint32_t regs[4];
1099
1100
1101 if((get_call_const_args(fw,is,4,regs)&3)==3) {
1102
1103 if(regs[0]==str_adr) {
1104 dd_enable_p=regs[1];
1105
1106 add_func_name(fw,"DispDev_EnableEventProc",dd_enable_p,NULL);
1107 break;
1108 }
1109 }
1110 }
1111
1112 if(dd_enable_p) {
1113 disasm_iter_init(fw,is,dd_enable_p);
1114 if(insn_match_find_next(fw,is,4,match_b_bl)) {
1115
1116 uint32_t regs[4];
1117 if(get_call_const_args(fw,is,4,regs)&1) {
1118 reg_evp_tbl=ADR_SET_THUMB(is->insn->detail->arm.operands[0].imm);
1119
1120 save_sig(fw,"RegisterEventProcTable",reg_evp_tbl);
1121 }
1122 }
1123 }
1124 return (reg_evp_tbl != 0);
1125 }
1126
1127
1128 int sig_match_reg_evp_alt2(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1129 {
1130 uint32_t reg_evp_alt2=0;
1131
1132 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
1133 if(!str_adr) {
1134 printf("sig_match_reg_evp_alt2: failed to find %s\n",rule->ref_name);
1135 return 0;
1136 }
1137
1138 uint32_t reg_evp_alt1=get_saved_sig_val("RegisterEventProcedure_alt1");
1139
1140 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
1141 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
1142 if(is->insn->detail->arm.operands[0].reg != ARM_REG_R0) {
1143 continue;
1144 }
1145 if(!insn_match_find_next(fw,is,3,match_b_bl)) {
1146 continue;
1147 }
1148 uint32_t regs[4];
1149
1150 if((get_call_const_args(fw,is,4,regs)&3)==3) {
1151 if(regs[0]==str_adr) {
1152 reg_evp_alt2=ADR_SET_THUMB(is->insn->detail->arm.operands[0].imm);
1153
1154 if(reg_evp_alt2 == reg_evp_alt1) {
1155 printf("RegisterEventProcedure_alt2 == _alt1 at %"PRIx64"\n",is->insn->address);
1156 reg_evp_alt2=0;
1157 } else {
1158 save_sig(fw,"RegisterEventProcedure_alt2",reg_evp_alt2);
1159
1160
1161 }
1162 break;
1163 }
1164 }
1165 }
1166 return (reg_evp_alt2 != 0);
1167 }
1168
1169
1170 int sig_match_unreg_evp_table(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1171 {
1172 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
1173 if(!str_adr) {
1174 printf("sig_match_unreg_evp_table: failed to find %s\n",rule->ref_name);
1175 return 0;
1176 }
1177
1178 uint32_t reg_evp_alt1=get_saved_sig_val("RegisterEventProcedure_alt1");
1179 uint32_t reg_evp_alt2=get_saved_sig_val("RegisterEventProcedure_alt2");
1180
1181 uint32_t mecha_unreg=0;
1182 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
1183 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
1184
1185 if(is->insn->detail->arm.operands[0].reg != ARM_REG_R0) {
1186 continue;
1187 }
1188 if(!insn_match_find_next(fw,is,3,match_b_bl)) {
1189 continue;
1190 }
1191 uint32_t reg_call=get_branch_call_insn_target(fw,is);
1192
1193
1194 if(!reg_call || (reg_call != reg_evp_alt1 && reg_call != reg_evp_alt2)) {
1195 continue;
1196 }
1197 uint32_t regs[4];
1198 if((get_call_const_args(fw,is,4,regs)&3)==3) {
1199
1200 if(regs[0]==str_adr) {
1201 mecha_unreg=ADR_SET_THUMB(regs[1]);
1202 break;
1203 }
1204 }
1205 }
1206 if(!mecha_unreg) {
1207 return 0;
1208 }
1209
1210 disasm_iter_init(fw,is,mecha_unreg);
1211
1212 if(!insn_match_find_next(fw,is,7,match_b_bl)) {
1213 return 0;
1214 }
1215
1216 const insn_match_t match_ldr_r0[]={
1217 {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM_BASE(PC)}},
1218 {ARM_INS_ENDING}
1219 };
1220 if(!insn_match_find_next(fw,is,18,match_ldr_r0)) {
1221 return 0;
1222 }
1223 uint32_t tbl=LDR_PC2val(fw,is->insn);
1224 if(!tbl) {
1225 return 0;
1226 }
1227 if(!disasm_iter(fw,is)) {
1228 printf("sig_match_unreg_evp_table: disasm failed\n");
1229 return 0;
1230 }
1231 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1232 }
1233
1234
1235
1236 int sig_match_evp_table_veneer(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1237 {
1238 uint32_t ref_adr = get_saved_sig_val(rule->ref_name);
1239 int prevb = 0;
1240 uint32_t cadr;
1241
1242
1243 disasm_iter_init(fw,is,ref_adr);
1244 while (is->adr < (ref_adr+0x800)) {
1245 cadr = is->adr;
1246 if (!disasm_iter(fw,is)) {
1247 disasm_iter_set(fw,is,(is->adr+2) | fw->thumb_default);
1248 }
1249 else {
1250 if (is->insn->id == ARM_INS_B) {
1251 uint32_t b_adr = get_branch_call_insn_target(fw,is);
1252 if (prevb && (b_adr == ref_adr)) {
1253
1254 add_func_name(fw,rule->name,cadr | is->thumb,NULL);
1255 return 1;
1256 }
1257 prevb = 1;
1258 }
1259 }
1260 }
1261 return 0;
1262 }
1263
1264
1265 int sig_match_createtaskstrictly_alt(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1266 {
1267 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
1268 if(!str_adr) {
1269 printf("sig_match_createtaskstrictly_alt: %s failed to find ref %s\n",rule->name,rule->ref_name);
1270 return 0;
1271 }
1272
1273 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
1274 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
1275 if(is->insn->detail->arm.operands[0].reg == ARM_REG_R0) {
1276
1277
1278 if(insn_match_find_next(fw,is,4,match_b_bl_blximm)) {
1279 uint32_t adr=get_branch_call_insn_target(fw,is);
1280 uint32_t adr2 = get_saved_sig_val("CreateTaskStrictly");
1281
1282 if(adr == adr2) {
1283
1284 return 0;
1285 }
1286 adr2 = get_saved_sig_val("j_CreateTaskStrictly");
1287 if(adr == adr2) {
1288
1289 return 0;
1290 }
1291 return save_sig_with_j(fw,rule->name,adr);
1292 }
1293 }
1294 }
1295 return 0;
1296 }
1297
1298
1299 int sig_match_createtask_alt(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1300 {
1301
1302 if(!get_saved_sig_val(rule->ref_name)) {
1303 return 0;
1304 }
1305
1306 if(!init_disasm_sig_ref(fw,is,rule)) {
1307 return 0;
1308 }
1309 if(!insn_match_find_next(fw,is,6,match_bl_blximm)) {
1310 printf("sig_match_createtask_alt: bl match failed\n");
1311 return 0;
1312 }
1313 uint32_t adr = get_branch_call_insn_target(fw,is);
1314 uint32_t adr2 = get_saved_sig_val("CreateTask");
1315
1316 if(adr == adr2) {
1317
1318 return 0;
1319 }
1320 adr2 = get_saved_sig_val("j_CreateTask");
1321 if(adr == adr2) {
1322
1323 return 0;
1324 }
1325 return save_sig_with_j(fw,rule->name,adr);
1326 }
1327
1328
1329 int sig_match_get_nd_value(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1330 {
1331
1332 if(!get_misc_val_value("CAM_HAS_ND_FILTER") || !get_misc_val_value("CAM_HAS_IRIS_DIAPHRAGM")) {
1333 return 0;
1334 }
1335
1336 if(!init_disasm_sig_ref(fw,is,rule)) {
1337 return 0;
1338 }
1339 if(!find_next_sig_call(fw,is,16,"ClearEventFlag")) {
1340 printf("sig_match_get_nd_value: no match ClearEventFlag\n");
1341 return 0;
1342 }
1343 if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
1344 printf("sig_match_get_nd_value: bl match 1 failed\n");
1345 return 0;
1346 }
1347
1348 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
1349 disasm_iter(fw,is);
1350 if (B_target(fw,is->insn))
1351 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
1352
1353 if(!insn_match_find_next(fw,is,5,match_bl_blximm)) {
1354 printf("sig_match_get_nd_value: bl match 2 failed\n");
1355 return 0;
1356 }
1357 uint32_t addr=get_branch_call_insn_target(fw,is);
1358 if(addr == get_saved_sig_val("GetUsableAvRange")) {
1359 printf("sig_match_get_nd_value: found GetUsableAvRange, iris or ND only?\n");
1360 return 0;
1361 }
1362 return save_sig_with_j(fw,rule->name,addr);
1363 }
1364
1365 int sig_match_get_current_exp(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1366 {
1367 if(!init_disasm_sig_ref(fw,is,rule)) {
1368 return 0;
1369 }
1370 if(!insn_match_find_next(fw,is,2,match_bl_blximm)) {
1371 printf("sig_match_get_current_exp: bl match 1 failed\n");
1372 return 0;
1373 }
1374
1375 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
1376 if(!insn_match_find_next(fw,is,6,match_bl_blximm)) {
1377 printf("sig_match_get_current_exp: bl match 2 failed\n");
1378 return 0;
1379 }
1380
1381 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
1382 if(!insn_match_find_next(fw,is,6,match_bl_blximm)) {
1383 printf("sig_match_get_current_exp: bl match 3 failed\n");
1384 return 0;
1385 }
1386 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1387 }
1388
1389 int sig_match_get_current_nd_value(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1390 {
1391
1392 if(!get_misc_val_value("CAM_HAS_ND_FILTER") || !get_misc_val_value("CAM_HAS_IRIS_DIAPHRAGM")) {
1393 return 0;
1394 }
1395 if(!init_disasm_sig_ref(fw,is,rule)) {
1396 return 0;
1397 }
1398 if(!find_next_sig_call(fw,is,36,"GetCurrentShutterSpeed_FW")) {
1399 printf("sig_match_get_current_nd_value: no match GetCurrentShutterSpeed_FW\n");
1400 return 0;
1401 }
1402
1403
1404 const insn_match_t match_bl_strh[]={
1405 {MATCH_INS(BL,MATCH_OPCOUNT_IGNORE)},
1406 {MATCH_INS(STRH,2), {MATCH_OP_REG(R0), MATCH_OP_MEM(INVALID,INVALID,0x8)}},
1407 {ARM_INS_ENDING}
1408 };
1409 if(!insn_match_find_next_seq(fw,is,10,match_bl_strh)) {
1410 printf("sig_match_get_current_nd_value: match failed\n");
1411 return 0;
1412 }
1413
1414 disasm_iter_init(fw,is,adr_hist_get(&is->ah,1));
1415 disasm_iter(fw,is);
1416 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1417 }
1418
1419 int sig_match_get_current_deltasv(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1420 {
1421 if(!init_disasm_sig_ref(fw,is,rule)) {
1422 return 0;
1423 }
1424 if(!find_next_sig_call(fw,is,36,"GetCurrentShutterSpeed_FW")) {
1425 printf("sig_match_get_current_deltasv: no match GetCurrentShutterSpeed_FW\n");
1426 return 0;
1427 }
1428
1429
1430 const insn_match_t match_bl_strh[]={
1431 {MATCH_INS(BL,MATCH_OPCOUNT_IGNORE)},
1432 {MATCH_INS(STRH,2), {MATCH_OP_REG(R0), MATCH_OP_MEM(INVALID,INVALID,0x4)}},
1433 {ARM_INS_ENDING}
1434 };
1435 if(!insn_match_find_next_seq(fw,is,8,match_bl_strh)) {
1436 printf("sig_match_get_current_deltasv: match failed\n");
1437 return 0;
1438 }
1439
1440 disasm_iter_init(fw,is,adr_hist_get(&is->ah,1));
1441 disasm_iter(fw,is);
1442 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1443 }
1444
1445
1446 int sig_match_imager_active_callback(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1447 {
1448 if(!init_disasm_sig_ref(fw,is,rule)) {
1449 return 0;
1450 }
1451 const insn_match_t match_ldr_bl_mov_pop[]={
1452 {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM_BASE(PC)}},
1453 {MATCH_INS(BL, MATCH_OPCOUNT_IGNORE)},
1454 {MATCH_INS(MOV,2), {MATCH_OP_REG(R0), MATCH_OP_IMM(0)}},
1455 {MATCH_INS(POP, MATCH_OPCOUNT_IGNORE)},
1456 {ARM_INS_ENDING}
1457 };
1458
1459 if(!insn_match_find_next_seq(fw,is,28,match_ldr_bl_mov_pop)) {
1460 printf("sig_match_imager_active_callback: match failed\n");
1461 return 0;
1462 }
1463
1464 disasm_iter_init(fw,is,adr_hist_get(&is->ah,3));
1465
1466 disasm_iter(fw,is);
1467 uint32_t f1=LDR_PC2val(fw,is->insn);
1468
1469
1470 return save_sig_with_j(fw,rule->name,f1);
1471 }
1472 int sig_match_imager_active(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1473 {
1474 if(!init_disasm_sig_ref(fw,is,rule)) {
1475 return 0;
1476 }
1477
1478 const insn_match_t match_ldr_mov_str_pop[]={
1479 {MATCH_INS(LDR, 2), {MATCH_OP_REG_ANY, MATCH_OP_MEM_BASE(PC)}},
1480 {MATCH_INS(MOV,2), {MATCH_OP_REG_ANY, MATCH_OP_IMM(1)}},
1481 {MATCH_INS(STR, 2), {MATCH_OP_REG_ANY, MATCH_OP_MEM_ANY}},
1482 {MATCH_INS(POP, MATCH_OPCOUNT_IGNORE)},
1483 {ARM_INS_ENDING}
1484 };
1485
1486 int backtrack=3;
1487 if(!insn_match_find_next_seq(fw,is,10,match_ldr_mov_str_pop)) {
1488
1489 init_disasm_sig_ref(fw,is,rule);
1490 const insn_match_t match_mov_ldr_str_pop[]={
1491 {MATCH_INS(MOV,2), {MATCH_OP_REG_ANY, MATCH_OP_IMM(1)}},
1492 {MATCH_INS(LDR, 2), {MATCH_OP_REG_ANY, MATCH_OP_MEM_BASE(PC)}},
1493 {MATCH_INS(STR, 2), {MATCH_OP_REG_ANY, MATCH_OP_MEM_ANY}},
1494 {MATCH_INS(POP, MATCH_OPCOUNT_IGNORE)},
1495 {ARM_INS_ENDING}
1496 };
1497 if(!insn_match_find_next_seq(fw,is,10,match_mov_ldr_str_pop)) {
1498 printf("sig_match_imager_active: match failed\n");
1499 return 0;
1500 }
1501 backtrack=2;
1502 }
1503
1504 disasm_iter_init(fw,is,adr_hist_get(&is->ah,backtrack));
1505 disasm_iter(fw,is);
1506 uint32_t base=LDR_PC2val(fw,is->insn);
1507 uint32_t reg=is->insn->detail->arm.operands[0].reg;
1508
1509
1510 if(backtrack == 3) {
1511 disasm_iter(fw,is);
1512 }
1513 disasm_iter(fw,is);
1514
1515 if(is->insn->detail->arm.operands[1].mem.base != reg) {
1516 printf("sig_match_imager_active: reg mismatch\n");
1517 return 0;
1518 }
1519 uint32_t off=is->insn->detail->arm.operands[1].mem.disp;
1520
1521 save_misc_val("imager_active",base,off,(uint32_t)is->insn->address);
1522 return 1;
1523 }
1524
1525 int sig_match_screenlock_helper(firmware *fw, iter_state_t *is, sig_rule_t *rule) {
1526 if(!init_disasm_sig_ref(fw,is,rule)) {
1527 return 0;
1528 }
1529 uint32_t init_adr = (uint32_t)is->adr | is->thumb;
1530
1531
1532 const insn_match_t match_cmp_bne_bl[]={
1533 {MATCH_INS(CMP, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM(0)}},
1534 {MATCH_INS_CC(B,NE,MATCH_OPCOUNT_IGNORE)},
1535 {MATCH_INS(BL,MATCH_OPCOUNT_IGNORE)},
1536 {ARM_INS_ENDING}
1537 };
1538 const insn_match_t match_ldrpc_mov_b[]={
1539 {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM_BASE(PC)}},
1540 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R1), MATCH_OP_IMM(0)}},
1541 {MATCH_INS_CC(B,AL,MATCH_OPCOUNT_IGNORE)},
1542 {ARM_INS_ENDING}
1543 };
1544
1545 if(insn_match_find_next_seq(fw,is,6,match_cmp_bne_bl)) {
1546 return save_sig_with_j(fw,rule->name,init_adr);
1547
1548 }
1549
1550
1551
1552 disasm_iter_init(fw,is,init_adr);
1553 if(!insn_match_find_next_seq(fw,is,1,match_ldrpc_mov_b)) {
1554 printf("sig_match_screenlock_helper: match 2 failed 0x%"PRIx64"\n",is->insn->address);
1555 return 0;
1556 }
1557 disasm_iter_init(fw,is,init_adr);
1558 disasm_iter(fw,is);
1559 uint32_t adr = LDR_PC2val(fw,is->insn);
1560 if(!adr) {
1561 printf("sig_match_screenlock_helper: no match LDR PC 0x%"PRIx64"\n",is->insn->address);
1562 return 0;
1563 }
1564 disasm_iter_init(fw,is,adr);
1565
1566 if(!insn_match_find_next_seq(fw,is,6,match_cmp_bne_bl)) {
1567 printf("sig_match_screenlock_helper: match failed 0x%8x\n",init_adr);
1568 return 0;
1569 }
1570 return save_sig_with_j(fw,rule->name,adr);
1571 }
1572
1573 int sig_match_fclose_low(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1574 {
1575 if(!init_disasm_sig_ref(fw,is,rule)) {
1576
1577 return 0;
1578 }
1579 if(!find_next_sig_call(fw,is,24,"strlen")) {
1580
1581 return 0;
1582 }
1583 if(!find_next_sig_call(fw,is,26,"malloc")) {
1584
1585 return 0;
1586 }
1587 if(!find_next_sig_call(fw,is,14,"strcpy")) {
1588
1589 return 0;
1590 }
1591
1592 if(!insn_match_find_nth(fw,is,12,3,match_bl_blximm)) {
1593
1594 return 0;
1595 }
1596 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1597 }
1598
1599 int sig_match_screenunlock(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1600 {
1601 if(!init_disasm_sig_ref(fw,is,rule)) {
1602 return 0;
1603 }
1604
1605 if(!find_next_sig_call(fw,is,14,"ScreenLock")) {
1606
1607 return 0;
1608 }
1609
1610
1611 const insn_match_t match_end[]={
1612 {MATCH_INS(POP, MATCH_OPCOUNT_IGNORE)},
1613 {MATCH_INS_CC(B,AL,MATCH_OPCOUNT_IGNORE)},
1614 {ARM_INS_ENDING}
1615 };
1616 if(!insn_match_find_next_seq(fw,is,38,match_end)) {
1617
1618 return 0;
1619 }
1620
1621 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1622 }
1623
1624
1625 int sig_match_log_camera_event(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1626 {
1627 if(!init_disasm_sig_ref(fw,is,rule)) {
1628 return 0;
1629 }
1630 if(!insn_match_find_next(fw,is,6,match_bl_blximm)) {
1631
1632 return 0;
1633 }
1634 uint32_t regs[4];
1635 if((get_call_const_args(fw,is,4,regs)&3)!=3) {
1636
1637 return 0;
1638 }
1639 if(regs[0] != 0x60) {
1640
1641 return 0;
1642 }
1643 const char *str=(char *)adr2ptr(fw,regs[1]);
1644 if(!str || strcmp(str,"_SImage") != 0) {
1645
1646 return 0;
1647 }
1648 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1649 }
1650
1651
1652 int sig_match_physw_misc(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1653 {
1654 if(!init_disasm_sig_ref(fw,is,rule)) {
1655 osig* ostub2 = find_sig(fw->sv->stubs,rule->ref_name);
1656 if (ostub2 && ostub2->val)
1657 {
1658 disasm_iter_init(fw,is,ostub2->val);
1659 }
1660 else
1661 {
1662 return 0;
1663 }
1664 }
1665 int i;
1666 uint32_t physw_run=0;
1667 for(i=0; i<3; i++) {
1668 if(!disasm_iter(fw,is)) {
1669 printf("sig_match_physw_misc: disasm failed\n");
1670 return 0;
1671 }
1672 physw_run=LDR_PC2val(fw,is->insn);
1673 if(physw_run) {
1674 if(adr_is_var(fw,physw_run)) {
1675 save_misc_val("physw_run",physw_run,0,(uint32_t)is->insn->address);
1676 break;
1677 } else {
1678 printf("sig_match_physw_misc: adr not data? 0x%08x\n",physw_run);
1679 return 0;
1680 }
1681 }
1682 }
1683 if(!physw_run) {
1684 return 0;
1685 }
1686
1687
1688 if(!insn_match_find_next(fw,is,7,match_bl_blximm)) {
1689 return 0;
1690 }
1691 uint32_t sleeptask=get_saved_sig_val("SleepTask");
1692 if(!sleeptask) {
1693 printf("sig_match_physw_misc: missing SleepTask\n");
1694 return 0;
1695 }
1696 uint32_t f=get_branch_call_insn_target(fw,is);
1697
1698
1699 if(f != sleeptask) {
1700 fw_disasm_iter_single(fw,f);
1701 uint32_t f2=get_direct_jump_target(fw,fw->is);
1702 if(f2 != sleeptask) {
1703 return 0;
1704 }
1705
1706
1707 save_sig_with_j(fw,"SleepTask",f);
1708 }
1709
1710 disasm_iter_init(fw,is,adr_hist_get(&is->ah,1));
1711 if(!disasm_iter(fw,is)) {
1712 printf("sig_match_physw_misc: disasm failed\n");
1713 return 0;
1714 }
1715
1716 if(is->insn->id != ARM_INS_LDR
1717 || is->insn->detail->arm.operands[0].reg != ARM_REG_R0) {
1718 return 0;
1719 }
1720 save_misc_val("physw_sleep_delay",physw_run,is->insn->detail->arm.operands[1].mem.disp,(uint32_t)is->insn->address);
1721
1722 if(!disasm_iter(fw,is)) {
1723 printf("sig_match_physw_misc: disasm failed\n");
1724 return 0;
1725 }
1726
1727
1728 if(!insn_match_find_next(fw,is,2,match_bl_blximm)) {
1729 return 0;
1730 }
1731 save_sig(fw,"kbd_p1_f",get_branch_call_insn_target(fw,is));
1732
1733
1734 if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
1735 return 0;
1736 }
1737 save_sig(fw,"kbd_p2_f",get_branch_call_insn_target(fw,is));
1738 return 1;
1739 }
1740
1741 int sig_match_kbd_read_keys(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1742 {
1743 if(!init_disasm_sig_ref(fw,is,rule)) {
1744 return 0;
1745 }
1746
1747 if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
1748 return 0;
1749 }
1750 save_sig(fw,"kbd_read_keys",get_branch_call_insn_target(fw,is));
1751 if(!disasm_iter(fw,is)) {
1752 printf("sig_match_kbd_read_keys: disasm failed\n");
1753 return 0;
1754 }
1755 uint32_t physw_status=LDR_PC2val(fw,is->insn);
1756 if(physw_status) {
1757 save_misc_val("physw_status",physw_status,0,(uint32_t)is->insn->address);
1758 save_sig(fw,"kbd_p1_f_cont",(uint32_t)(is->insn->address) | is->thumb);
1759 return 1;
1760 }
1761 return 0;
1762 }
1763
1764
1765 int sig_match_get_kbd_state(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1766 {
1767 if(!init_disasm_sig_ref(fw,is,rule)) {
1768 return 0;
1769 }
1770
1771 insn_match_t match[]={
1772 {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM_BASE(PC)}},
1773 {MATCH_INS(BL, MATCH_OPCOUNT_IGNORE)},
1774 {ARM_INS_ENDING}
1775 };
1776
1777 if(!insn_match_find_next_seq(fw,is,11,match)) {
1778 return 0;
1779 }
1780 save_sig_with_j(fw,"GetKbdState",get_branch_call_insn_target(fw,is));
1781
1782 if(!insn_match_find_next(fw,is,5,match_b_bl_blximm)) {
1783 return 0;
1784 }
1785 save_sig_with_j(fw,"kbd_read_keys_r2",get_branch_call_insn_target(fw,is));
1786 return 1;
1787 }
1788
1789 int sig_match_get_dial_hw_position(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1790 {
1791 if(!init_disasm_sig_ref(fw,is,rule)) {
1792 return 0;
1793 }
1794 uint32_t adr = find_last_call_from_func(fw,is,18,50);
1795 if(!adr) {
1796
1797 return 0;
1798 }
1799
1800 disasm_iter_init(fw,is,adr);
1801 adr = find_last_call_from_func(fw,is,16,32);
1802 if(!adr) {
1803
1804 return 0;
1805 }
1806
1807 disasm_iter_init(fw,is,adr);
1808
1809 if(!insn_match_find_next(fw,is,30,match_bl_blximm)) {
1810
1811 return 0;
1812 }
1813 uint32_t fadr = get_branch_call_insn_target(fw,is);
1814
1815 disasm_iter_init(fw,is,adr_hist_get(&is->ah,4));
1816 const insn_match_t match_hw_dial_call[]={
1817 {MATCH_INS(ADD,MATCH_OPCOUNT_ANY), {MATCH_OP_REG(R0)}},
1818 {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0),MATCH_OP_MEM_BASE(PC)}},
1819 {MATCH_INS(BL,MATCH_OPCOUNT_IGNORE)},
1820 {ARM_INS_ENDING}
1821 };
1822 if(!insn_match_find_next(fw,is,4,match_hw_dial_call)) {
1823
1824 return 0;
1825 }
1826 return save_sig_with_j(fw,rule->name,fadr);
1827 }
1828
1829 int sig_match_create_jumptable(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1830 {
1831 if(!init_disasm_sig_ref(fw,is,rule)) {
1832 return 0;
1833 }
1834
1835 if(!insn_match_find_nth(fw,is,20,2,match_bl_blximm)) {
1836 return 0;
1837 }
1838
1839 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
1840 if(!insn_match_find_next(fw,is,15,match_bl_blximm)) {
1841 return 0;
1842 }
1843
1844 save_sig(fw,"CreateJumptable",get_branch_call_insn_target(fw,is));
1845 return 1;
1846 }
1847
1848
1849 int sig_match_take_semaphore_strict(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1850 {
1851 if(!init_disasm_sig_ref(fw,is,rule)) {
1852 return 0;
1853 }
1854
1855 if(!insn_match_find_next(fw,is,6,match_bl_blximm)) {
1856 return 0;
1857 }
1858
1859 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
1860
1861 if(!insn_match_find_nth(fw,is,10,2,match_bl_blximm)) {
1862 return 0;
1863 }
1864
1865 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
1866
1867 if(!insn_match_find_nth(fw,is,20,3,match_bl_blximm)) {
1868 return 0;
1869 }
1870 save_sig_with_j(fw,"DebugAssert",get_branch_call_insn_target(fw,is));
1871
1872
1873 if(!insn_match_find_next(fw,is,7,match_bl_blximm)) {
1874 return 0;
1875 }
1876 save_sig_with_j(fw,"TakeSemaphoreStrictly",get_branch_call_insn_target(fw,is));
1877 arm_reg ptr_reg = ARM_REG_INVALID;
1878 uint32_t sem_adr=0;
1879 int i;
1880
1881 for(i=1; i<7; i++) {
1882 fw_disasm_iter_single(fw,adr_hist_get(&is->ah,i));
1883 cs_insn *insn=fw->is->insn;
1884 if(insn->id != ARM_INS_LDR) {
1885 continue;
1886 }
1887 if(ptr_reg == ARM_REG_INVALID
1888 && insn->detail->arm.operands[0].reg == ARM_REG_R0
1889 && insn->detail->arm.operands[1].mem.base != ARM_REG_PC) {
1890 ptr_reg = insn->detail->arm.operands[1].mem.base;
1891 continue;
1892 }
1893 if(ptr_reg == ARM_REG_INVALID || !isLDR_PC(insn) || (arm_reg)insn->detail->arm.operands[0].reg != ptr_reg) {
1894 continue;
1895 }
1896 sem_adr=LDR_PC2val(fw,insn);
1897 if(sem_adr) {
1898 break;
1899 }
1900 }
1901 if(!sem_adr) {
1902 return 0;
1903 }
1904 save_misc_val("fileio_semaphore",sem_adr,0,(uint32_t)is->insn->address);
1905
1906 if(!insn_match_find_next(fw,is,10,match_bl_blximm)) {
1907 return 0;
1908 }
1909 return save_sig_with_j(fw,"GetDrive_FreeClusters",get_branch_call_insn_target(fw,is));
1910 }
1911
1912 int sig_match_get_semaphore_value(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1913 {
1914 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
1915 if(!str_adr) {
1916 printf("sig_get_semaphore_value: failed to find ref %s\n",rule->ref_name);
1917 return 0;
1918 }
1919
1920 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
1921
1922 if(!fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
1923
1924 return 0;
1925 }
1926
1927 uint32_t fadr=0;
1928 int i;
1929 for(i=1; i<=5; i++) {
1930 if(!fw_disasm_iter_single(fw,adr_hist_get(&is->ah,i))) {
1931
1932 return 0;
1933 }
1934 if(insn_match_any(fw->is->insn,match_bl_blximm)){
1935 fadr=get_branch_call_insn_target(fw,fw->is);
1936 break;
1937 }
1938 }
1939 if(!fadr) {
1940
1941 return 0;
1942 }
1943
1944 disasm_iter_init(fw,is,fadr);
1945
1946 if(!insn_match_find_next(fw,is,9,match_bl_blximm)) {
1947
1948 return 0;
1949 }
1950 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1951 }
1952
1953 int sig_match_stat(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1954 {
1955 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
1956 if(!str_adr) {
1957 printf("sig_match_stat: %s failed to find ref %s\n",rule->name,rule->ref_name);
1958 return 0;
1959 }
1960
1961
1962 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
1963 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
1964 if(is->insn->detail->arm.operands[0].reg == ARM_REG_R0) {
1965 if(insn_match_find_next(fw,is,2,match_bl_blximm)) {
1966 uint32_t adr=get_branch_call_insn_target(fw,is);
1967
1968 if(is_sig_call(fw,is,"Fopen_Fut_FW")) {
1969 continue;
1970 }
1971
1972 return save_sig_with_j(fw,rule->name,adr);
1973 }
1974 }
1975 }
1976 return 0;
1977 }
1978 static const insn_match_t match_open_mov_call[]={
1979
1980 {MATCH_INS(MOV, 2), {MATCH_OP_REG_ANY, MATCH_OP_REG_ANY}},
1981 {MATCH_INS(MOV, 2), {MATCH_OP_REG_ANY, MATCH_OP_REG_ANY}},
1982 {MATCH_INS(MOV, 2), {MATCH_OP_REG_ANY, MATCH_OP_REG_ANY}},
1983 {MATCH_INS(BL, MATCH_OPCOUNT_IGNORE)},
1984 {ARM_INS_ENDING}
1985 };
1986
1987
1988
1989 int sig_match_open(firmware *fw, iter_state_t *is, sig_rule_t *rule)
1990 {
1991 if(!init_disasm_sig_ref(fw,is,rule)) {
1992 return 0;
1993 }
1994 if(!insn_match_find_next_seq(fw,is,48,match_open_mov_call)) {
1995 return 0;
1996 }
1997 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
1998 }
1999
2000
2001 int sig_match_umalloc(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2002 {
2003 if(!init_disasm_sig_ref(fw,is,rule)) {
2004 return 0;
2005 }
2006
2007 if(!insn_match_find_nth(fw,is,15,3,match_bl_blximm)) {
2008 return 0;
2009 }
2010
2011 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
2012
2013 if(!insn_match_find_nth(fw,is,14,3,match_bl_blximm)) {
2014 return 0;
2015 }
2016 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2017 }
2018
2019
2020 int sig_match_ufree(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2021 {
2022 if(!init_disasm_sig_ref(fw,is,rule)) {
2023 return 0;
2024 }
2025
2026 if(!find_next_sig_call(fw,is,60,"strcpy_FW")) {
2027 return 0;
2028 }
2029
2030 if(!insn_match_find_nth(fw,is,12,3,match_bl_blximm)) {
2031 return 0;
2032 }
2033
2034 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
2035
2036 if(!find_next_sig_call(fw,is,40,"Close_FW")) {
2037 return 0;
2038 }
2039
2040 if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
2041 return 0;
2042 }
2043 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2044 }
2045
2046 int sig_match_deletefile_fut(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2047 {
2048 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2049 if(!str_adr) {
2050 printf("sig_match_deletefile_fut: %s failed to find ref %s\n",rule->name,rule->ref_name);
2051 return 0;
2052 }
2053
2054 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
2055 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2056
2057 if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
2058 continue;
2059 }
2060
2061 uint32_t adr=get_branch_call_insn_target(fw,is);
2062 if(!fw_disasm_iter_single(fw,adr)) {
2063 printf("sig_match_deletefile_fut: disasm failed\n");
2064 return 0;
2065 }
2066 const insn_match_t match_mov_r1[]={
2067 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R1), MATCH_OP_IMM_ANY}},
2068 #if CS_API_MAJOR < 4
2069 {MATCH_INS(MOVS, 2), {MATCH_OP_REG(R1), MATCH_OP_IMM_ANY}},
2070 #endif
2071 {ARM_INS_ENDING}
2072 };
2073
2074 if(!insn_match_any(fw->is->insn,match_mov_r1)){
2075 continue;
2076 }
2077 return save_sig_with_j(fw,rule->name,adr);
2078 }
2079 return 0;
2080 }
2081
2082 uint32_t find_call_near_str(firmware *fw, iter_state_t *is, sig_rule_t *rule);
2083
2084 int sig_match_closedir(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2085 {
2086 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2087 if(!str_adr) {
2088 printf("sig_match_closedir: %s failed to find ref %s\n",rule->name,rule->ref_name);
2089 return 0;
2090 }
2091
2092 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
2093 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2094 if(!find_next_sig_call(fw,is,60,"sprintf_FW")) {
2095 continue;
2096 }
2097 if(insn_match_find_nth(fw,is,7,2,match_bl_blximm)) {
2098 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2099 }
2100 }
2101
2102 uint32_t call_adr = find_call_near_str(fw,is,rule);
2103 if(call_adr) {
2104 disasm_iter_init(fw,is,call_adr);
2105 const insn_match_t match_closedir[]={
2106 {MATCH_INS(BL,MATCH_OPCOUNT_IGNORE)},
2107 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R0), MATCH_OP_REG_ANY}},
2108 {MATCH_INS(BL,MATCH_OPCOUNT_IGNORE)},
2109 {ARM_INS_ENDING}
2110 };
2111 if(insn_match_seq(fw,is,match_closedir)){
2112 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2113 }
2114 }
2115
2116 return 0;
2117 }
2118
2119
2120 int save_sig_match_call(firmware* fw, sig_rule_t *rule, uint32_t call_adr)
2121 {
2122 disasm_iter_init(fw,fw->is,call_adr);
2123 disasm_iter(fw,fw->is);
2124 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,fw->is));
2125 }
2126
2127 int sig_match_readfastdir(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2128 {
2129 uint32_t str_adr;
2130 str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2131 if(!str_adr) {
2132 printf("sig_match_readfastdir: %s failed to find ref %s\n",rule->name,rule->ref_name);
2133 return 0;
2134 }
2135 const insn_match_t match_cbnz_r0[]={
2136 {MATCH_INS(CBNZ, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM_ANY}},
2137 {ARM_INS_ENDING}
2138 };
2139 const insn_match_t match_cbz_r0[]={
2140 {MATCH_INS(CBZ, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM_ANY}},
2141 {ARM_INS_ENDING}
2142 };
2143 int max_insns=rule->param&SIG_NEAR_OFFSET_MASK;
2144 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
2145 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2146 uint32_t ref_adr = iter_state_adr(is);
2147
2148 fw_disasm_iter_single(fw,adr_hist_get(&is->ah,2));
2149 if(insn_match_any(fw->is->insn,match_bl_blximm)) {
2150 uint32_t call_adr = iter_state_adr(fw->is);
2151 fw_disasm_iter_single(fw,adr_hist_get(&is->ah,1));
2152 if(insn_match_any(fw->is->insn,match_cbnz_r0)) {
2153 return save_sig_match_call(fw, rule, call_adr);
2154 }
2155 }
2156 int i;
2157 for(i=3; i<=max_insns; i++) {
2158
2159 fw_disasm_iter_single(fw,adr_hist_get(&is->ah,i));
2160 if(insn_match_any(fw->is->insn,match_bl_blximm)) {
2161 uint32_t call_adr = iter_state_adr(fw->is);
2162 fw_disasm_iter_single(fw,adr_hist_get(&is->ah,i-1));
2163 if(insn_match_any(fw->is->insn,match_cbz_r0)) {
2164 uint32_t b_adr = get_branch_call_insn_target(fw,fw->is);
2165 if (ref_adr == b_adr) {
2166 return save_sig_match_call(fw, rule, call_adr);
2167 }
2168 }
2169 }
2170 }
2171 }
2172 printf("sig_match_readfastdir: no match %s\n",rule->name);
2173 return 0;
2174 }
2175
2176 int sig_match_strrchr(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2177 {
2178 uint32_t sig_adr=get_saved_sig_val(rule->name);
2179 if (sig_adr == 0)
2180 {
2181 uint32_t call_adr = find_call_near_str(fw,is,rule);
2182 if(call_adr) {
2183 disasm_iter_init(fw,is,call_adr-4);
2184 const insn_match_t match_mov_r1_imm[]={
2185 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R1), MATCH_OP_IMM_ANY}},
2186 {ARM_INS_ENDING}
2187 };
2188 if(insn_match_find_next(fw,is,2,match_mov_r1_imm)){
2189 return save_sig_match_call(fw, rule, call_adr);
2190 }
2191 }
2192 }
2193 return 0;
2194 }
2195
2196 int sig_match_time(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2197 {
2198 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2199 if(!str_adr) {
2200 printf("sig_match_time: %s failed to find ref %s\n",rule->name,rule->ref_name);
2201 return 0;
2202 }
2203 uint32_t fadr=0;
2204
2205 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
2206 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2207
2208 if(insn_match_find_nth(fw,is,6,2,match_bl_blximm)) {
2209 fadr=get_branch_call_insn_target(fw,is);
2210 break;
2211 }
2212 }
2213 if(!fadr) {
2214 return 0;
2215 }
2216
2217 disasm_iter_init(fw,is,fadr);
2218
2219 if(insn_match_find_nth(fw,is,11,2,match_bl_blximm)) {
2220 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2221 }
2222 return 0;
2223 }
2224
2225 int sig_match_strncpy(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2226 {
2227 if(!init_disasm_sig_ref(fw,is,rule)) {
2228 return 0;
2229 }
2230 if(!find_next_sig_call(fw,is,60,"strcpy_FW")) {
2231 return 0;
2232 }
2233 if(!insn_match_find_next(fw,is,6,match_bl_blximm)) {
2234 return 0;
2235 }
2236 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2237 }
2238
2239 int sig_match_strncmp(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2240 {
2241 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2242 if(!str_adr) {
2243 printf("sig_match_strncmp: failed to find ref %s\n",rule->ref_name);
2244 return 0;
2245 }
2246
2247 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
2248 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2249 if(!insn_match_find_next(fw,is,3,match_bl_blximm)) {
2250 continue;
2251 }
2252 uint32_t regs[4];
2253 if((get_call_const_args(fw,is,4,regs)&6)==6) {
2254
2255 if(regs[1]==str_adr && regs[2] == strlen(rule->ref_name)) {
2256 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2257 }
2258 }
2259 }
2260 return 0;
2261 }
2262
2263 int sig_match_strtolx(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2264 {
2265 if(!init_disasm_sig_ref(fw,is,rule)) {
2266 return 0;
2267 }
2268 if(!find_next_sig_call(fw,is,130,"strncpy")) {
2269 return 0;
2270 }
2271
2272 if(!insn_match_find_next(fw,is,6,match_bl_blximm)) {
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 if(!disasm_iter(fw,is)) {
2282 printf("sig_match_strtolx: disasm failed\n");
2283 return 0;
2284 }
2285
2286
2287
2288 const insn_match_t match_mov_r3_imm[]={
2289 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R3), MATCH_OP_IMM_ANY}},
2290 {ARM_INS_ENDING}
2291 };
2292 if(!insn_match(is->insn,match_mov_r3_imm)){
2293 return 0;
2294 }
2295 if(!disasm_iter(fw,is)) {
2296 printf("sig_match_strtolx: disasm failed\n");
2297 return 0;
2298 }
2299 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2300 }
2301
2302
2303 int sig_match_exec_evp(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2304 {
2305 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2306 if(!str_adr) {
2307 printf("sig_match_exec_evp: failed to find ref %s\n",rule->ref_name);
2308 return 0;
2309 }
2310
2311 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
2312 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2313
2314 int i;
2315 for(i=1; i<=18; i++) {
2316 if(!fw_disasm_iter_single(fw,adr_hist_get(&is->ah,i))) {
2317 break;
2318 }
2319 if(fw->is->insn->id == ARM_INS_PUSH && fw->is->insn->detail->arm.operands[0].reg == ARM_REG_R0) {
2320
2321 uint32_t adr=(uint32_t)(fw->is->insn->address) | is->thumb;
2322
2323 if(find_next_sig_call(fw,is,28,"DebugAssert")) {
2324 break;
2325 }
2326 return save_sig_with_j(fw,rule->name,adr);
2327 }
2328 }
2329 }
2330 return 0;
2331 }
2332
2333 int sig_match_fgets_fut(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2334 {
2335 if(!init_disasm_sig_ref(fw,is,rule)) {
2336 return 0;
2337 }
2338 if(!find_next_sig_call(fw,is,16,"Fopen_Fut_FW")) {
2339 return 0;
2340 }
2341 disasm_iter(fw,is);
2342 disasm_iter(fw,is);
2343 if (B_target(fw,is->insn) && (is->insn->detail->arm.cc == ARM_CC_NE)) {
2344 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
2345 } else {
2346 if (B_target(fw,is->insn) && (is->insn->detail->arm.cc == ARM_CC_NE)) {
2347 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
2348 }
2349 }
2350 if(!insn_match_find_nth(fw,is,20,1,match_bl_blximm)) {
2351 return 0;
2352 }
2353 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2354 }
2355
2356 int sig_match_log(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2357 {
2358 if(!init_disasm_sig_ref(fw,is,rule)) {
2359 return 0;
2360 }
2361 const insn_match_t match_pop6[]={
2362 {MATCH_INS(POP, 6), {MATCH_OP_REST_ANY}},
2363 {ARM_INS_ENDING}
2364 };
2365
2366 if(!insn_match_find_nth(fw,is,38,3,match_pop6)) {
2367 return 0;
2368 }
2369
2370 if(!insn_match_find_nth(fw,is,24,3,match_bl_blximm)) {
2371 return 0;
2372 }
2373 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2374 }
2375
2376
2377 int sig_match_pow_dry_52(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2378 {
2379 if (fw->dryos_ver != 52) {
2380 return 0;
2381 }
2382 if(!init_disasm_sig_ref(fw,is,rule)) {
2383 return 0;
2384 }
2385 const insn_match_t match_ldrd_r0_r1[]={
2386 {MATCH_INS(LDRD, 3), {MATCH_OP_REG(R0), MATCH_OP_REG(R1), MATCH_OP_ANY}},
2387 {ARM_INS_ENDING}
2388 };
2389
2390 if(!insn_match_find_next(fw,is,50,match_ldrd_r0_r1)) {
2391 return 0;
2392 }
2393
2394 if(is->insn->detail->arm.operands[2].mem.base == ARM_REG_SP) {
2395 return 0;
2396 }
2397 if(!disasm_iter(fw,is)) {
2398 printf("sig_match_pow: disasm failed\n");
2399 return 0;
2400 }
2401 uint32_t adr=get_branch_call_insn_target(fw,is);
2402 if(!adr) {
2403 return 0;
2404 }
2405 return save_sig_with_j(fw,rule->name,adr);
2406 }
2407
2408
2409 int sig_match_pow_dry_gt_52(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2410 {
2411 if (fw->dryos_ver <= 52) {
2412 return 0;
2413 }
2414 if(!init_disasm_sig_ref(fw,is,rule)) {
2415 return 0;
2416 }
2417 const insn_match_t match1a[]={
2418 {MATCH_INS(LDRSH, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM(SP,INVALID,0x12)}},
2419 {MATCH_INS(LDRD, 3), {MATCH_OP_REG(R2), MATCH_OP_REG(R3), MATCH_OP_MEM(SP,INVALID,0x20)}},
2420 {MATCH_INS(STR, 2), {MATCH_OP_REG_ANY, MATCH_OP_MEM(SP,INVALID,0)}},
2421 {MATCH_INS(BL, MATCH_OPCOUNT_IGNORE)},
2422 {ARM_INS_ENDING}
2423 };
2424 const insn_match_t match1b[]={
2425 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R2), MATCH_OP_REG(R7)}},
2426 {MATCH_INS(LDRSH, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM(SP,INVALID,0x12)}},
2427 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R3), MATCH_OP_REG(R6)}},
2428 {MATCH_INS(STR, 2), {MATCH_OP_REG_ANY, MATCH_OP_MEM(SP,INVALID,0)}},
2429 {MATCH_INS(BL, MATCH_OPCOUNT_IGNORE)},
2430 {ARM_INS_ENDING}
2431 };
2432 const insn_match_t* match1[]={ match1a, match1b };
2433 int idx;
2434 for (idx = 0; idx < 2; idx += 1)
2435 {
2436
2437 if(insn_match_find_next_seq(fw,is,50,match1[idx]))
2438 break;
2439 init_disasm_sig_ref(fw,is,rule);
2440 }
2441
2442 if (idx >= 2)
2443 return 0;
2444
2445 uint32_t adr=get_branch_call_insn_target(fw,is);
2446 if(!adr) {
2447 return 0;
2448 }
2449
2450 disasm_iter_init(fw,is,adr);
2451 const insn_match_t match2a[]={
2452 {MATCH_INS(LDRD,3), {MATCH_OP_REG(R0), MATCH_OP_REG(R1), MATCH_OP_MEM_ANY}},
2453 {MATCH_INS(BLX, 1), {MATCH_OP_IMM_ANY}},
2454 {ARM_INS_ENDING}
2455 };
2456 const insn_match_t match2b[]={
2457 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R2), MATCH_OP_REG(R0)}},
2458 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R3), MATCH_OP_REG(R1)}},
2459 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R4), MATCH_OP_IMM(0x40000000)}},
2460 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM(0)}},
2461 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R1), MATCH_OP_REG(R4)}},
2462 {MATCH_INS(BL, 1), {MATCH_OP_IMM_ANY}},
2463 {ARM_INS_ENDING}
2464 };
2465 const insn_match_t* match2[]={ match2a, match2b };
2466
2467 if(!insn_match_find_next_seq(fw,is,15,match2[idx])) {
2468 return 0;
2469 }
2470 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2471 }
2472
2473 int sig_match_sqrt(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2474 {
2475 if(!init_disasm_sig_ref(fw,is,rule)) {
2476 return 0;
2477 }
2478
2479 if(!insn_match_find_nth(fw,is,12,3,match_bl_blximm)) {
2480 return 0;
2481 }
2482
2483 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
2484 if(!disasm_iter(fw,is)) {
2485 printf("sig_match_sqrt: disasm failed\n");
2486 return 0;
2487 }
2488 uint32_t j_tgt=get_direct_jump_target(fw,is);
2489
2490 if(j_tgt) {
2491
2492 disasm_iter_init(fw,is,j_tgt);
2493 if(!disasm_iter(fw,is)) {
2494 printf("sig_match_sqrt: disasm failed\n");
2495 return 0;
2496 }
2497 }
2498
2499 if(!insn_match_find_nth(fw,is,12,2,match_b_bl_blximm)) {
2500 return 0;
2501 }
2502 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2503 }
2504 int sig_match_get_drive_cluster_size(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2505 {
2506 if(!init_disasm_sig_ref(fw,is,rule)) {
2507 return 0;
2508 }
2509
2510 if(fw_search_insn(fw,is,search_disasm_str_ref,0,"A/OpLogErr.txt",(uint32_t)is->adr+260)) {
2511
2512 if(!insn_match_find_next(fw,is,3,match_bl_blximm)) {
2513
2514 return 0;
2515 }
2516
2517 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
2518
2519 if(!insn_match_find_nth(fw,is,13,2,match_bl_blximm)) {
2520
2521 return 0;
2522 }
2523
2524 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
2525 disasm_iter(fw,is);
2526 if (B_target(fw, is->insn))
2527 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
2528
2529 if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
2530
2531 return 0;
2532 }
2533 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2534 }
2535 return 0;
2536 }
2537
2538 int sig_match_mktime_ext(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2539 {
2540 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2541 if(!str_adr) {
2542 printf("sig_match_mktime_ext: failed to find ref %s\n",rule->ref_name);
2543 return 0;
2544 }
2545
2546 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
2547 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2548
2549 if(!find_next_sig_call(fw,is,12,"sscanf_FW")) {
2550
2551 return 0;
2552 }
2553
2554 if(!insn_match_find_next(fw,is,22,match_bl_blximm)) {
2555
2556 return 0;
2557 }
2558
2559 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
2560 if(!disasm_iter(fw,is)) {
2561 printf("sig_match_mktime_ext: disasm failed\n");
2562 return 0;
2563 }
2564 uint32_t j_tgt=get_direct_jump_target(fw,is);
2565
2566 if(j_tgt) {
2567
2568 disasm_iter_init(fw,is,j_tgt);
2569 if(!disasm_iter(fw,is)) {
2570 printf("sig_match_mktime_ext: disasm failed\n");
2571 return 0;
2572 }
2573 }
2574 const insn_match_t match_pop4[]={
2575 {MATCH_INS(POP, 4), {MATCH_OP_REST_ANY}},
2576 {MATCH_INS(POP, 6), {MATCH_OP_REST_ANY}},
2577 {ARM_INS_ENDING}
2578 };
2579
2580
2581 if(!insn_match_find_next(fw,is,54,match_pop4)) {
2582
2583 return 0;
2584 }
2585 if(!insn_match_find_next(fw,is,1,match_b)) {
2586
2587 return 0;
2588 }
2589 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2590 }
2591 return 0;
2592 }
2593
2594
2595 int sig_match_rec2pb(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2596 {
2597 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2598 if(!str_adr) {
2599 printf("sig_match_mktime_ext: failed to find ref %s\n",rule->ref_name);
2600 return 0;
2601 }
2602
2603 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
2604 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2605 const insn_match_t match_ldr_cbnz_r0[]={
2606 {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM_ANY}},
2607 {MATCH_INS(CBNZ, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM_ANY}},
2608 {ARM_INS_ENDING}
2609 };
2610 if(!insn_match_find_next_seq(fw,is,10,match_ldr_cbnz_r0)) {
2611
2612 continue;
2613 }
2614
2615 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
2616 if(!insn_match_find_next(fw,is,3,match_b_bl_blximm)) {
2617
2618
2619 return 0;
2620 }
2621 uint32_t adr = iter_state_adr(is);
2622
2623 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
2624 if(!find_next_sig_call(fw,is,16,"LogCameraEvent")) {
2625
2626 return 0;
2627 }
2628 uint32_t regs[4];
2629 if((get_call_const_args(fw,is,4,regs)&3)!=3) {
2630
2631 return 0;
2632 }
2633
2634 if(regs[0]==0x60 && adr2ptr(fw,regs[1]) && (strcmp((const char *)adr2ptr(fw,regs[1]),"AC:Rec2PB")==0)) {
2635 return save_sig_with_j(fw,rule->name,adr);
2636 } else {
2637
2638 return 0;
2639 }
2640 }
2641 return 0;
2642 }
2643
2644
2645 int sig_match_get_parameter_data(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2646 {
2647 if(!init_disasm_sig_ref(fw,is,rule)) {
2648 return 0;
2649 }
2650 const insn_match_t match_cmp_bhs[]={
2651 {MATCH_INS(CMP, 2), {MATCH_OP_REG_ANY, MATCH_OP_IMM_ANY}},
2652 {MATCH_INS_CC(B,HS,MATCH_OPCOUNT_IGNORE)},
2653 {ARM_INS_ENDING}
2654 };
2655 if(!insn_match_find_next_seq(fw,is,4,match_cmp_bhs)) {
2656
2657 return 0;
2658 }
2659
2660 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
2661 if(!insn_match_find_next(fw,is,1,match_b)) {
2662
2663 return 0;
2664 }
2665 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2666 }
2667
2668
2669
2670
2671 int sig_match_prepdir_x(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2672 {
2673 if(!init_disasm_sig_ref(fw,is,rule)) {
2674 return 0;
2675 }
2676 const insn_match_t match_mov_r1_1[]={
2677 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R1), MATCH_OP_IMM(1)}},
2678 #if CS_API_MAJOR < 4
2679 {MATCH_INS(MOVS, 2), {MATCH_OP_REG(R1), MATCH_OP_IMM(1)}},
2680 #endif
2681 {ARM_INS_ENDING}
2682 };
2683 if(!insn_match_find_next(fw,is,1,match_mov_r1_1)) {
2684
2685 return 0;
2686 }
2687 if(!insn_match_find_next(fw,is,1,match_b)) {
2688
2689 return 0;
2690 }
2691 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2692 }
2693
2694
2695
2696
2697 int sig_match_prepdir_1(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2698 {
2699 uint32_t call_adr = find_call_near_str(fw,is,rule);
2700 if(call_adr) {
2701 disasm_iter_init(fw,is,call_adr);
2702 disasm_iter(fw,is);
2703 disasm_iter(fw,is);
2704 if (!CBx_target(fw,is->insn))
2705 {
2706 rule->param = SIG_NEAR_BEFORE(20,5);
2707 call_adr = find_call_near_str(fw,is,rule);
2708 if(!call_adr) {
2709 return 0;
2710 }
2711 disasm_iter_init(fw,is,call_adr);
2712 disasm_iter(fw,is);
2713 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2714 }
2715 }
2716
2717 rule->param = SIG_NEAR_BEFORE(7,2);
2718 call_adr = find_call_near_str(fw,is,rule);
2719 if(!call_adr) {
2720 return 0;
2721 }
2722 return save_sig_match_call(fw, rule, call_adr);
2723 }
2724
2725 int sig_match_prepdir_0(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2726 {
2727 if(!init_disasm_sig_ref(fw,is,rule)) {
2728 return 0;
2729 }
2730 uint32_t ref_pdx=get_saved_sig_val("PrepareDirectory_x");
2731 if(!ref_pdx) {
2732 printf("sig_match_prepdir_0: missing PrepareDirectory_x\n");
2733 return 0;
2734 }
2735
2736 disasm_iter(fw,is);
2737 disasm_iter(fw,is);
2738
2739 uint32_t adr=(uint32_t)is->adr|is->thumb;
2740 const insn_match_t match_mov_r1_1[]={
2741 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R1), MATCH_OP_IMM(0)}},
2742 #if CS_API_MAJOR < 4
2743 {MATCH_INS(MOVS, 2), {MATCH_OP_REG(R1), MATCH_OP_IMM(0)}},
2744 #endif
2745 {ARM_INS_ENDING}
2746 };
2747 if(!insn_match_find_next(fw,is,1,match_mov_r1_1)) {
2748
2749 return 0;
2750 }
2751 if(!insn_match_find_next(fw,is,1,match_b)) {
2752
2753 return 0;
2754 }
2755 uint32_t pdx=get_branch_call_insn_target(fw,is);
2756 if(pdx != ref_pdx) {
2757
2758 return 0;
2759 }
2760 return save_sig_with_j(fw,rule->name,adr);
2761 }
2762 int sig_match_mkdir(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2763 {
2764 if(!init_disasm_sig_ref(fw,is,rule)) {
2765 return 0;
2766 }
2767 const insn_match_t match[]={
2768 {MATCH_INS(STRB,2), {MATCH_OP_REG_ANY, MATCH_OP_MEM_ANY}},
2769 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R0), MATCH_OP_REG(SP)}},
2770 {MATCH_INS(LDR, 2), {MATCH_OP_REG(R1), MATCH_OP_MEM_BASE(SP)}},
2771 {MATCH_INS(BL, MATCH_OPCOUNT_IGNORE)},
2772 {ARM_INS_ENDING}
2773 };
2774 if(insn_match_find_next_seq(fw,is,148,match)) {
2775 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2776 }
2777
2778 init_disasm_sig_ref(fw,is,rule);
2779 const insn_match_t match2[]={
2780 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R1), MATCH_OP_REG_ANY}},
2781 {MATCH_INS(STRB,2), {MATCH_OP_REG_ANY, MATCH_OP_MEM_ANY}},
2782 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R0), MATCH_OP_REG(SP)}},
2783 {MATCH_INS(BL, MATCH_OPCOUNT_IGNORE)},
2784 {ARM_INS_ENDING}
2785 };
2786 if(!insn_match_find_next_seq(fw,is,148,match2)) {
2787
2788 return 0;
2789 }
2790 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2791 }
2792
2793 int sig_match_add_ptp_handler(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2794 {
2795 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2796 if(!str_adr) {
2797 printf("sig_match_add_ptp_handler: failed to find ref %s\n",rule->ref_name);
2798 return 0;
2799 }
2800
2801 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
2802 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2803
2804 if(!find_next_sig_call(fw,is,8,"CreateTaskStrictly")) {
2805
2806 continue;
2807 }
2808
2809 if(!insn_match_find_nth(fw,is,13,3,match_bl_blximm)) {
2810
2811 return 0;
2812 }
2813
2814 uint32_t regs[4];
2815 if((get_call_const_args(fw,is,5,regs)&7)!=7) {
2816
2817 return 0;
2818 }
2819 if(regs[0] < 0x9000 || regs[0] > 0x10000 || !adr2ptr(fw,regs[1]) || regs[2] != 0) {
2820
2821 return 0;
2822 }
2823 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2824 }
2825 return 0;
2826 }
2827 int sig_match_qsort(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2828 {
2829 if(!init_disasm_sig_ref(fw,is,rule)) {
2830 return 0;
2831 }
2832 if(!find_next_sig_call(fw,is,90,"DebugAssert")) {
2833
2834 return 0;
2835 }
2836 if(!insn_match_find_nth(fw,is,38,3,match_bl_blximm)) {
2837
2838 return 0;
2839 }
2840
2841 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
2842
2843 if(insn_match_find_next(fw,is,4,match_bl_blximm)) {
2844 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
2845 }
2846 if(!insn_match_find_next(fw,is,14,match_bl_blximm)) {
2847
2848 return 0;
2849 }
2850
2851 uint32_t regs[4];
2852 if((get_call_const_args(fw,is,5,regs)&0xe)!=0xe) {
2853
2854 return 0;
2855 }
2856 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2857 }
2858
2859
2860
2861
2862
2863
2864
2865
2866 int sig_match_deletedirectory_fut(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2867 {
2868 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2869 if(!str_adr) {
2870 printf("sig_match_deletedirectory_fut: failed to find ref %s\n",rule->ref_name);
2871 return 0;
2872 }
2873
2874
2875 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - 2048) | fw->thumb_default);
2876 uint32_t end_adr = ADR_ALIGN4(str_adr) + 2048;
2877 while(find_next_sig_call(fw,is,end_adr - (uint32_t)is->adr,"DeleteFile_Fut")) {
2878 if(!insn_match_find_next(fw,is,6,match_bl_blximm)) {
2879
2880 continue;
2881 }
2882 if(!is_sig_call(fw,is,"strcpy")) {
2883
2884 continue;
2885 }
2886 if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
2887
2888 continue;
2889 }
2890 if(!is_sig_call(fw,is,"strrchr")) {
2891
2892 continue;
2893 }
2894
2895 uint32_t regs[4];
2896 if((get_call_const_args(fw,is,2,regs)&0x2)!=0x2) {
2897
2898 continue;
2899 }
2900 if(regs[1] != '/') {
2901
2902 continue;
2903 }
2904 if(!insn_match_find_next(fw,is,5,match_bl_blximm)) {
2905
2906 continue;
2907 }
2908 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2909 }
2910 return 0;
2911 }
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922 int sig_match_set_control_event(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2923 {
2924 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2925 if(!str_adr) {
2926
2927
2928 return 0;
2929 }
2930 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
2931 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2932 if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
2933
2934 continue;
2935 }
2936 if(!is_sig_call(fw,is,"LogCameraEvent")) {
2937
2938 continue;
2939 }
2940 const insn_match_t match_seq[]={
2941 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R0), MATCH_OP_REG_ANY,}},
2942 {MATCH_INS(BL, MATCH_OPCOUNT_IGNORE)},
2943 {MATCH_INS(BL, MATCH_OPCOUNT_IGNORE)},
2944 {ARM_INS_ENDING}
2945 };
2946 if(!insn_match_find_next_seq(fw,is,1,match_seq)) {
2947
2948 continue;
2949 }
2950 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2951 }
2952 return 0;
2953 }
2954
2955 int sig_match_displaybusyonscreen_52(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2956 {
2957 if (fw->dryos_ver != 52) {
2958 return 0;
2959 }
2960 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2961 if(!str_adr) {
2962 printf("sig_match_displaybusyonscreen: failed to find ref %s\n",rule->ref_name);
2963 return 0;
2964 }
2965 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
2966 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
2967 if(!insn_match_find_next(fw,is,3,match_bl_blximm)) {
2968
2969 continue;
2970 }
2971 if(!is_sig_call(fw,is,"LogCameraEvent")) {
2972
2973 continue;
2974 }
2975 if(!find_next_sig_call(fw,is,4,"GUISrv_StartGUISystem_FW")) {
2976
2977 continue;
2978 }
2979 if(!insn_match_find_nth(fw,is,5,2,match_bl_blximm)) {
2980
2981 continue;
2982 }
2983 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
2984 }
2985 return 0;
2986 }
2987
2988 int sig_match_undisplaybusyonscreen_52(firmware *fw, iter_state_t *is, sig_rule_t *rule)
2989 {
2990 if (fw->dryos_ver != 52) {
2991 return 0;
2992 }
2993 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
2994 if(!str_adr) {
2995 printf("sig_match_undisplaybusyonscreen: failed to find ref %s\n",rule->ref_name);
2996 return 0;
2997 }
2998 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
2999 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
3000
3001 if(!find_next_sig_call(fw,is,24,"displaybusyonscreen")) {
3002
3003 continue;
3004 }
3005 if(!find_next_sig_call(fw,is,12,"GUISrv_StartGUISystem_FW")) {
3006
3007 continue;
3008 }
3009 if(!insn_match_find_nth(fw,is,6,3,match_bl_blximm)) {
3010
3011 continue;
3012 }
3013 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3014 }
3015 return 0;
3016 }
3017
3018 int sig_match_try_take_sem_dry_gt_57(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3019 {
3020 if(!init_disasm_sig_ref(fw,is,rule)) {
3021 return 0;
3022 }
3023 if(!find_next_sig_call(fw,is,24,"ReceiveMessageQueue")) {
3024 printf("sig_match_try_take_sem_dry_gt_57: failed to find ReceiveMessageQueue\n");
3025 return 0;
3026 }
3027 if(!find_next_sig_call(fw,is,60,"bzero")) {
3028 printf("sig_match_try_take_sem_dry_gt_57: failed to find bzero\n");
3029 return 0;
3030 }
3031 if(insn_match_find_next(fw,is,3,match_bl_blximm)) {
3032 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3033 }
3034 printf("sig_match_try_take_sem_dry_gt_57: no match\n");
3035 return 0;
3036 }
3037
3038 int sig_match_wait_all_eventflag_strict(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3039 {
3040 if(!init_disasm_sig_ref(fw,is,rule)) {
3041 return 0;
3042 }
3043 uint32_t str_adr = find_str_bytes_main_fw(fw,"EFTool.c");
3044 if(!str_adr) {
3045 printf("sig_match_wait_all_eventflag_strict: failed to find ref EFTool.c\n");
3046 return 0;
3047 }
3048 if(!find_next_sig_call(fw,is,60,"SleepTask")) {
3049 printf("sig_match_wait_all_eventflag_strict: failed to find SleepTask\n");
3050 return 0;
3051 }
3052
3053 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,is->adr + 60)) {
3054 if(!insn_match_find_next(fw,is,6,match_bl_blximm)) {
3055 printf("sig_match_wait_all_eventflag_strict: no match bl 0x%"PRIx64"\n",is->insn->address);
3056 return 0;
3057 }
3058 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3059 }
3060 return 0;
3061 }
3062
3063 int sig_match_get_num_posted_messages(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3064 {
3065 if(!init_disasm_sig_ref(fw,is,rule)) {
3066 return 0;
3067 }
3068 if(!find_next_sig_call(fw,is,50,"TakeSemaphore")) {
3069 printf("sig_match_get_num_posted_messages: failed to find TakeSemaphore\n");
3070 return 0;
3071 }
3072
3073 if(!insn_match_find_next(fw,is,5,match_bl_blximm)) {
3074 printf("sig_match_get_num_posted_messages: no match bl 0x%"PRIx64"\n",is->insn->address);
3075 return 0;
3076 }
3077 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3078 }
3079
3080 int sig_match_set_hp_timer_after_now(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3081 {
3082 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
3083 if(!str_adr) {
3084 printf("sig_match_set_hp_timer_after_now: failed to find ref %s\n",rule->ref_name);
3085 return 0;
3086 }
3087 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
3088 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
3089 if(!find_next_sig_call(fw,is,20,"ClearEventFlag")) {
3090
3091 continue;
3092 }
3093
3094 if(!insn_match_find_nth(fw,is,13,3,match_bl_blximm)) {
3095
3096 continue;
3097 }
3098
3099 uint32_t regs[4];
3100 uint32_t found_regs = get_call_const_args(fw,is,6,regs);
3101 if((found_regs&0x1)!=0x1) {
3102
3103
3104 if((found_regs & 0x8) && regs[3] == 4) {
3105 if((found_regs & 0x2 && regs[1] > fw->rom_code_search_min_adr)
3106 || (found_regs & 0x4 && regs[2] > fw->rom_code_search_min_adr)) {
3107 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3108 }
3109 }
3110
3111 continue;
3112 }
3113
3114 if(regs[0] != 70000) {
3115
3116 continue;
3117 }
3118 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3119 }
3120 return 0;
3121 }
3122 int sig_match_transfer_src_overlay(firmware *fw, iter_state_t *is, sig_rule_t *rule) {
3123 if(!init_disasm_sig_ref(fw,is,rule)) {
3124 return 0;
3125 }
3126
3127 if(!find_next_sig_call(fw,is,32,"DebugAssert")) {
3128 printf("sig_match_transfer_src_overlay: no match DebugAssert\n");
3129 return 0;
3130 }
3131 var_ldr_desc_t desc;
3132 if(!find_and_get_var_ldr(fw, is, 20,4, ARM_REG_R0, &desc)) {
3133 printf("sig_match_transfer_src_overlay: no match ldr\n");
3134 return 0;
3135 }
3136
3137 if(!insn_match_find_next(fw,is,1,match_bl_blximm)) {
3138 printf("sig_match_transfer_src_overlay: no match bl 0x%"PRIx64"\n",is->insn->address);
3139 return 0;
3140 }
3141
3142 uint32_t fadr = get_branch_call_insn_target(fw,is);
3143
3144
3145 save_misc_val("active_bitmap_buffer",desc.adr_adj,desc.off,(uint32_t)is->insn->address);
3146
3147
3148
3149
3150 const insn_match_t bm_buf_match[]={
3151 {MATCH_INS(LDR, 2), {MATCH_OP_REG_ANY, MATCH_OP_MEM_ANY}},
3152 {MATCH_INS(ADD, 3), {MATCH_OP_REG(R0), MATCH_OP_REG_ANY, MATCH_OP_IMM_ANY}},
3153 {ARM_INS_ENDING}
3154 };
3155 if(insn_match_find_next_seq(fw,is,1,bm_buf_match)) {
3156 if((arm_reg)is->insn->detail->arm.operands[1].reg == desc.reg_base) {
3157 save_misc_val("bitmap_buffer",desc.adr_adj,is->insn->detail->arm.operands[2].imm,(uint32_t)is->insn->address);
3158 }
3159
3160
3161
3162
3163
3164 }
3165
3166
3167
3168
3169
3170 return save_sig_with_j(fw,rule->name,fadr);
3171 }
3172
3173
3174 int sig_match_exmem_vars(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3175 {
3176 uint32_t adr[2], fnd[2];
3177 if(!init_disasm_sig_ref(fw,is,rule)) {
3178 printf("sig_match_exmem_vars: missing ref\n");
3179 return 0;
3180 }
3181
3182 if(!insn_match_find_next(fw,is,15,match_ldr_pc)) {
3183 printf("sig_match_exmem_vars: match LDR PC failed\n");
3184 return 0;
3185 }
3186 adr[0]=LDR_PC2val(fw,is->insn);
3187 fnd[0]=(uint32_t)is->insn->address;
3188 if(!insn_match_find_next(fw,is,5,match_ldr_pc)) {
3189 printf("sig_match_exmem_vars: 2nd match LDR PC failed\n");
3190 return 0;
3191 }
3192 adr[1]=LDR_PC2val(fw,is->insn);
3193 fnd[1]=(uint32_t)is->insn->address;
3194
3195 int n;
3196 for (n=0; n<2; n++) {
3197 if (adr[n] < fw->data_start+fw->data_len) {
3198 uint32_t ladr = adr[n]-fw->data_start+fw->data_init_start;
3199 save_misc_val("exmem_types_table",ladr,0,fnd[n]);
3200 int m;
3201 int exm_typ_cnt = 0;
3202 for (m=0; m<42; m++) {
3203 if ( (fw_u32(fw,ladr+m*4)!=0) && isASCIIstring(fw, fw_u32(fw,ladr+m*4)) )
3204 {
3205 char *extyp = (char*)adr2ptr(fw, fw_u32(fw,ladr+m*4));
3206 if ( strncmp(extyp,"EXMEM",5)==0 )
3207 {
3208 exm_typ_cnt++;
3209 }
3210 }
3211 else
3212 {
3213 break;
3214 }
3215 }
3216 save_misc_val("exmem_type_count",exm_typ_cnt,0,ladr);
3217 }
3218 else if (adr[n] < fw->memisostart) {
3219 save_misc_val("exmem_alloc_table",adr[n],0,fnd[n]);
3220 }
3221 }
3222 return 1;
3223 }
3224
3225
3226 int sig_match_zicokick_52(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3227 {
3228 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
3229 if(!str_adr) {
3230 printf("sig_match_zicokick_52: failed to find ref %s\n",rule->ref_name);
3231 return 0;
3232 }
3233 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
3234
3235
3236 if(!fw_search_insn(fw,is,search_disasm_str_ref,0,rule->ref_name,(uint32_t)is->adr+SEARCH_NEAR_REF_RANGE)) {
3237 printf("sig_match_zicokick_52: failed to find insn ref %s\n",rule->ref_name);
3238 return 0;
3239 }
3240
3241 if(!fw_disasm_iter_single(fw,adr_hist_get(&is->ah,1))) {
3242 printf("sig_match_zicokick_52: disasm failed\n");
3243 return 0;
3244 }
3245 if (!(isLDR_PC(fw->is->insn) && fw->is->insn->detail->arm.operands[0].reg == ARM_REG_R0)) {
3246 printf("sig_match_zicokick_52: match ldr r0 failed\n");
3247 return 0;
3248 }
3249
3250 uint32_t adr=(uint32_t)(fw->is->insn->address) | is->thumb;
3251
3252 if(!disasm_iter(fw,is)) {
3253 printf("sig_match_zicokick_52: disasm failed\n");
3254 return 0;
3255 }
3256 if (is->insn->id == ARM_INS_PUSH && is->insn->detail->arm.operands[0].reg == ARM_REG_R4) {
3257 return save_sig_with_j(fw,rule->name,adr);
3258 }
3259 return 0;
3260 }
3261
3262 int sig_match_zicokick_gt52(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3263 {
3264 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
3265 if(!str_adr) {
3266 printf("sig_match_zicokick_gt52: failed to find ref %s\n",rule->ref_name);
3267 return 0;
3268 }
3269 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
3270
3271
3272 if(!fw_search_insn(fw,is,search_disasm_str_ref,0,rule->ref_name,(uint32_t)is->adr+SEARCH_NEAR_REF_RANGE)) {
3273 printf("sig_match_zicokick_gt52: failed to find insn ref %s\n",rule->ref_name);
3274 return 0;
3275 }
3276 int i;
3277
3278
3279
3280 for(i=1; i<=8; i++) {
3281 if (!fw_disasm_iter_single(fw,adr_hist_get(&is->ah,i))) {
3282 printf("sig_match_zicokick_gt52: disasm failed\n");
3283 return 0;
3284 }
3285 if (fw->is->insn->id == ARM_INS_PUSH && fw->is->insn->detail->arm.operands[0].reg == ARM_REG_R4) {
3286 if (!fw_disasm_iter_single(fw,adr_hist_get(&is->ah,i+1))) {
3287 printf("sig_match_zicokick_gt52: disasm failed\n");
3288 return 0;
3289 }
3290 if (isLDR_PC(fw->is->insn) && fw->is->insn->detail->arm.operands[0].reg == ARM_REG_R0) {
3291 return save_sig_with_j(fw,rule->name,(uint32_t)(fw->is->insn->address) | is->thumb);
3292 }
3293 return 0;
3294 }
3295 }
3296 return 0;
3297 }
3298 int sig_match_zicokick_copy(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3299 {
3300 if(!init_disasm_sig_ref(fw,is,rule)) {
3301 return 0;
3302 }
3303
3304 const insn_match_t match_ldrs_bl[]={
3305 {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM_BASE(PC)}},
3306 {MATCH_INS(LDR, 2), {MATCH_OP_REG(R1), MATCH_OP_MEM_BASE(PC)}},
3307 {MATCH_INS(LDR, 2), {MATCH_OP_REG(R2), MATCH_OP_MEM_BASE(R0)}},
3308 {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM_BASE(PC)}},
3309 {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM_BASE(R0)}},
3310 {MATCH_INS(BL,MATCH_OPCOUNT_IGNORE)},
3311 {ARM_INS_ENDING}
3312 };
3313 if(!insn_match_find_next_seq(fw,is,30,match_ldrs_bl)) {
3314 printf("sig_match_zicokick_copy no match ldr\n");
3315 return 0;
3316 }
3317
3318 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3319 }
3320
3321 int sig_match_zicokick_values(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3322 {
3323 if(!init_disasm_sig_ref(fw,is,rule)) {
3324 return 0;
3325 }
3326
3327 #if 0
3328
3329 if(!find_next_sig_call(fw,is,64,"zicokick_copy")) {
3330 printf("sig_match_zicokick_values: no zicokick_copy 1\n");
3331 return 0;
3332 }
3333 while(1) {
3334 uint32_t regs[4];
3335 if((get_call_const_args(fw,is,7,regs)&0x7)==0x7) {
3336 printf("xtensa blob @ 0x%08x, loads to 0x%08x, size 0x%08x\n",regs[1],regs[0],regs[2]);
3337 } else {
3338 printf("sig_match_zicokick_values: failed to get regs\n");
3339 }
3340 if(!find_next_sig_call(fw,is,8,"zicokick_copy")) {
3341 break;
3342 }
3343 }
3344 return 1;
3345 #endif
3346 int i;
3347 uint32_t uv[3] = {0,0,0};
3348 int uvi = 0;
3349 misc_blob_t *blobs=malloc((MISC_BLOB_XTENSA_MAX + 1)*sizeof(misc_blob_t));
3350 int n_blobs = 0;
3351
3352 for(i=1; i<=64; i++) {
3353 if (!disasm_iter(fw,is)) {
3354 free(blobs);
3355 return 0;
3356 }
3357 if (is->insn->id == ARM_INS_LDR && is->insn->detail->arm.operands[1].type == ARM_OP_MEM) {
3358 uint32_t u = LDR_PC2val(fw,is->insn);
3359 if ((u<fw->base+fw->size8) && (u>fw->rom_code_search_max_adr)) {
3360
3361 if (uvi<3) {
3362 uv[uvi] = u;
3363 uvi++;
3364 }
3365 }
3366 }
3367 else if (is->insn->id == ARM_INS_BL) {
3368 if (uvi==3) {
3369
3370 uint32_t bsize, bloadedto, badr, u;
3371 int j;
3372 badr = MAX(MAX(uv[0],uv[1]),uv[2]);
3373 for (j=0; j<3; j++) {
3374 if (uv[j]!=badr) {
3375 u = fw_u32(fw, uv[j]);
3376 if (u<1024*1024*2) {
3377 bsize = u;
3378 }
3379 else {
3380 bloadedto = u;
3381 }
3382 }
3383 }
3384 if (bsize) {
3385 if(n_blobs == MISC_BLOB_XTENSA_MAX) {
3386 printf("sig_match_zicokick_values: ignoring xtensa blobs > %d\n",MISC_BLOB_XTENSA_MAX);
3387 blobs[n_blobs].type = MISC_BLOB_TYPE_NONE;
3388 break;
3389 }
3390
3391 blobs[n_blobs].type = MISC_BLOB_TYPE_XTENSA;
3392 blobs[n_blobs].rom_adr = badr;
3393 blobs[n_blobs].ram_adr = bloadedto;
3394 blobs[n_blobs].size = bsize;
3395 n_blobs++;
3396 }
3397 }
3398 uvi = 0;
3399 }
3400 else if (is->insn->id == ARM_INS_POP) {
3401 break;
3402 }
3403 }
3404 if(n_blobs > 0) {
3405 blobs[n_blobs].type = MISC_BLOB_TYPE_NONE;
3406 save_misc_val_blobs("zicokick_values",blobs,0);
3407 return 1;
3408 } else {
3409 free(blobs);
3410 return 0;
3411 }
3412 }
3413
3414 int sig_match_init_ex_drivers(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3415 {
3416 if(!init_disasm_sig_ref(fw,is,rule)) {
3417 return 0;
3418 }
3419 int i;
3420 int b_count;
3421
3422 for(i=0, b_count = 0; i < 32 && b_count < 14; i++) {
3423 if (!disasm_iter(fw,is)) {
3424 printf("sig_match_init_ex_drivers: disasm failed 1\n");
3425 return 0;
3426 }
3427 uint32_t b_tgt = get_branch_call_insn_target(fw,is);
3428 if(!b_tgt) {
3429 continue;
3430 }
3431 b_count++;
3432 uint64_t next_adr = is->adr | is->thumb;
3433 disasm_iter_init(fw,is,b_tgt);
3434 if (!disasm_iter(fw,is)) {
3435 printf("sig_match_init_ex_drivers: disasm failed 2\n");
3436 return 0;
3437 }
3438
3439 if(is->insn->id == ARM_INS_PUSH) {
3440 if(find_next_sig_call(fw,is,30,"DebugAssert")) {
3441 uint32_t regs[4];
3442 if((get_call_const_args(fw,is,5,regs)&0x2)==0x2) {
3443 const char *str=(char *)adr2ptr(fw,regs[1]);
3444 if(str && strcmp(str,"InitExDrivers.c") == 0) {
3445 return save_sig_with_j(fw,rule->name,b_tgt);
3446 }
3447 }
3448 }
3449 }
3450 disasm_iter_init(fw,is,next_adr);
3451 }
3452 return 0;
3453 }
3454
3455 int sig_match_omar_init(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3456 {
3457 if(!init_disasm_sig_ref(fw,is,rule)) {
3458 return 0;
3459 }
3460 uint32_t fadr = find_last_call_from_func(fw,is,20,42);
3461 if(!fadr) {
3462 printf("sig_match_omar_init: no match call\n");
3463 return 0;
3464 }
3465
3466 disasm_iter_init(fw,is,fadr);
3467 if(!find_next_sig_call(fw,is,44,"dry_memcpy")) {
3468 printf("sig_match_omar_init: no match dry_memcpy\n");
3469 return 0;
3470 }
3471 uint32_t regs[4];
3472
3473 if((get_call_const_args(fw,is,5,regs)&0x6)!=0x6) {
3474 printf("sig_match_omar_init: no match dry_memcpy args 1\n");
3475 return 0;
3476 }
3477 if(regs[2] != 0x18 || !adr2ptr(fw,regs[1])) {
3478 printf("sig_match_omar_init: no match dry_memcpy args 2\n");
3479 return 0;
3480 }
3481 uint32_t dadr = regs[1];
3482 save_misc_val("omar_init_data",dadr,0,(uint32_t)is->insn->address);
3483 misc_blob_t *blobs=malloc(3*sizeof(misc_blob_t));
3484 int i;
3485 for(i = 0; i<2; i++) {
3486 uint32_t dst = fw_u32(fw,dadr + i*12);
3487 uint32_t src = fw_u32(fw,dadr + i*12 + 4);
3488 uint32_t bsize = fw_u32(fw,dadr + i*12 + 8);
3489 if(src && dst && bsize) {
3490 blobs[i].type = MISC_BLOB_TYPE_OMAR;
3491 blobs[i].rom_adr = src;
3492 blobs[i].ram_adr = dst;
3493 blobs[i].size = bsize;
3494 } else {
3495 printf("sig_match_omar_init: invalid blobs\n");
3496 free(blobs);
3497 blobs = NULL;
3498 break;
3499 }
3500 }
3501 if(blobs) {
3502 blobs[2].type = MISC_BLOB_TYPE_NONE;
3503 save_misc_val_blobs("omar_init_values",blobs,0);
3504 }
3505
3506 return save_sig_with_j(fw,rule->name,fadr);
3507 }
3508
3509 int sig_match_init_error_handlers(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3510 {
3511 if(!init_disasm_sig_ref(fw,is,rule)) {
3512 return 0;
3513 }
3514 if(!find_next_sig_call(fw,is,64,"init_ex_drivers")) {
3515 printf("sig_match_init_error_handlers: no match init_ex_drivers\n");
3516 return 0;
3517 }
3518 if(!insn_match_find_nth(fw,is,4,2,match_bl_blximm)) {
3519 printf("sig_match_init_error_handlers: no match bl\n");
3520 return 0;
3521 }
3522 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3523 }
3524
3525 int sig_match_default_assert_handler(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3526 {
3527 if(!init_disasm_sig_ref(fw,is,rule)) {
3528 return 0;
3529 }
3530 if(!find_next_sig_call(fw,is,14,"set_assert_handler")) {
3531 printf("sig_match_default_assert_handler: no match set_assert_handler\n");
3532 return 0;
3533 }
3534
3535 uint32_t regs[4];
3536 if((get_call_const_args(fw,is,1,regs)&0x1)!=0x1) {
3537 printf("sig_match_default_assert_handler: no match arg\n");
3538 return 0;
3539 }
3540 return save_sig_with_j(fw,rule->name,regs[0]);
3541 }
3542
3543 int sig_match_default_exception_handler(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3544 {
3545 if(!init_disasm_sig_ref(fw,is,rule)) {
3546 return 0;
3547 }
3548 if(!find_next_sig_call(fw,is,20,"set_exception_handler")) {
3549 printf("sig_match_default_exception_handler: no match set_exception_handler\n");
3550 return 0;
3551 }
3552
3553 uint32_t regs[4];
3554 if((get_call_const_args(fw,is,1,regs)&0x1)!=0x1) {
3555 printf("sig_match_default_exception_handler: no match arg\n");
3556 return 0;
3557 }
3558 return save_sig_with_j(fw,rule->name,regs[0]);
3559 }
3560
3561 int sig_match_default_panic_handler(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3562 {
3563 if(!init_disasm_sig_ref(fw,is,rule)) {
3564 return 0;
3565 }
3566 if(!find_next_sig_call(fw,is,28,"set_panic_handler")) {
3567 printf("sig_match_default_panic_handler: no match set_panic_handler\n");
3568 return 0;
3569 }
3570
3571 uint32_t regs[4];
3572 if((get_call_const_args(fw,is,1,regs)&0x1)!=0x1) {
3573 printf("sig_match_default_panic_handler: no match arg\n");
3574 return 0;
3575 }
3576 return save_sig_with_j(fw,rule->name,regs[0]);
3577 }
3578
3579 int sig_match_get_task_properties(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3580 {
3581 if(!init_disasm_sig_ref(fw,is,rule)) {
3582 return 0;
3583 }
3584 if(fw_search_insn(fw,is,search_disasm_str_ref,0,"Occured Time %s\n",(uint32_t)is->adr+170)) {
3585
3586 if(!find_next_sig_call(fw,is,16,"dry_error_printf")) {
3587 printf("get_task_properties: no match dry_error_printf 0x%"PRIx64"\n",is->insn->address);
3588 return 0;
3589 }
3590 if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
3591 printf("sig_match_get_task_properties: no match bl 0x%"PRIx64"\n",is->insn->address);
3592 return 0;
3593 }
3594 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3595 }
3596 printf("sig_match_get_task_properties: no match 'Occured Time' 0x%"PRIx64"\n",is->insn->address);
3597 return 0;
3598 }
3599
3600 int sig_match_enable_hdmi_power(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3601 {
3602 if(!init_disasm_sig_ref(fw,is,rule)) {
3603 return 0;
3604 }
3605 if(!find_next_sig_call(fw,is,14,"CreateEventFlagStrictly")) {
3606 printf("sig_match_enable_hdmi_power: no match CreateEventFlagStrictly\n");
3607 return 0;
3608 }
3609 const insn_match_t match_seq[]={
3610 {MATCH_INS(BL, MATCH_OPCOUNT_IGNORE)},
3611 {MATCH_INS(CBNZ, MATCH_OPCOUNT_IGNORE)},
3612 {ARM_INS_ENDING}
3613 };
3614 if(!insn_match_find_next_seq(fw,is,4,match_seq)) {
3615 printf("sig_match_enable_hdmi_power: no match bl seq cbnz 0x%"PRIx64"\n",is->insn->address);
3616 return 0;
3617 }
3618
3619 if (!disasm_iter(fw,is)) {
3620 return 0;
3621 }
3622 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3623 }
3624
3625 int sig_match_disable_hdmi_power(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3626 {
3627 if(!init_disasm_sig_ref(fw,is,rule)) {
3628 return 0;
3629 }
3630 if(!find_next_sig_call(fw,is,24,"EnableHDMIPower")) {
3631 printf("sig_match_disable_hdmi_power: no match EnableHDMIPower\n");
3632 return 0;
3633 }
3634 if(!find_next_sig_call(fw,is,22,"ClearEventFlag")) {
3635 printf("sig_match_disable_hdmi_power: no match ClearEventFlag\n");
3636 return 0;
3637 }
3638 const insn_match_t match_seq[]={
3639 {MATCH_INS(BL, MATCH_OPCOUNT_IGNORE)},
3640 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM(1)}},
3641 {MATCH_INS(POP, MATCH_OPCOUNT_IGNORE)},
3642 {ARM_INS_ENDING}
3643 };
3644 if(!insn_match_find_next_seq(fw,is,12,match_seq)) {
3645 printf("sig_match_disable_hdmi_power: no match seq bl movs pop 0x%"PRIx64"\n",is->insn->address);
3646 return 0;
3647 }
3648
3649 disasm_iter_init(fw,is,adr_hist_get(&is->ah,2));
3650 if (!disasm_iter(fw,is)) {
3651 return 0;
3652 }
3653 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3654 }
3655
3656 int sig_match_levent_table(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3657 {
3658 if(!init_disasm_sig_ref(fw,is,rule)) {
3659 return 0;
3660 }
3661 if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
3662
3663 return 0;
3664 }
3665
3666 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
3667
3668
3669 if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
3670
3671 return 0;
3672 }
3673
3674
3675 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
3676
3677
3678 disasm_iter(fw,is);
3679 uint32_t adr=LDR_PC2val(fw,is->insn);
3680 if(!adr) {
3681
3682 return 0;
3683 }
3684 uint32_t *p=(uint32_t *)adr2ptr(fw,adr);
3685 if(!p) {
3686 printf("sig_match_levent_table: 0x%08x not a ROM adr 0x%"PRIx64"\n",adr,is->insn->address);
3687 return 0;
3688 }
3689 if(*(p+1) != 0x800) {
3690 printf("sig_match_levent_table: expected 0x800 not 0x%x at 0x%08x ref 0x%"PRIx64"\n",*(p+1),adr,is->insn->address);
3691 return 0;
3692 }
3693
3694 save_misc_val(rule->name,adr,0,(uint32_t)is->insn->address);
3695 return 1;
3696 }
3697 int sig_match_flash_param_table(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3698 {
3699 if(!init_disasm_sig_ref(fw,is,rule)) {
3700 return 0;
3701 }
3702
3703 if(!insn_match_find_next(fw,is,14,match_bl_blximm)) {
3704
3705 return 0;
3706 }
3707 if(!is_sig_call(fw,is,"DebugAssert")) {
3708
3709 return 0;
3710 }
3711 if(!insn_match_find_next(fw,is,7,match_bl_blximm)) {
3712
3713 return 0;
3714 }
3715 if(!is_sig_call(fw,is,"DebugAssert")) {
3716
3717 return 0;
3718 }
3719 if(!insn_match_find_next(fw,is,8,match_bl_blximm)) {
3720
3721 return 0;
3722 }
3723 if(!is_sig_call(fw,is,"DebugAssert")) {
3724
3725 return 0;
3726 }
3727
3728 if(!insn_match_find_nth(fw,is,14,2,match_bl_blximm)) {
3729
3730 return 0;
3731 }
3732
3733 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
3734
3735
3736 if(!insn_match_find_next(fw,is,8,match_bl_blximm)) {
3737
3738 return 0;
3739 }
3740
3741
3742 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
3743
3744 disasm_iter(fw,is);
3745 uint32_t adr=LDR_PC2val(fw,is->insn);
3746 if(!adr) {
3747
3748 return 0;
3749 }
3750 save_misc_val(rule->name,adr,0,(uint32_t)is->insn->address);
3751 return 1;
3752 }
3753 int sig_match_jpeg_count_str(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3754 {
3755 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
3756 if(!str_adr) {
3757 printf("sig_match_jpeg_count_str: failed to find ref %s\n",rule->ref_name);
3758 return 0;
3759 }
3760
3761 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
3762 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
3763
3764 if(!insn_match_find_next(fw,is,3,match_bl_blximm)) {
3765
3766 continue;
3767 }
3768 if(!is_sig_call(fw,is,"sprintf_FW")) {
3769
3770 continue;
3771 }
3772
3773 uint32_t regs[4];
3774 if((get_call_const_args(fw,is,5,regs)&0x3)!=0x3) {
3775
3776 continue;
3777 }
3778 if(regs[1] != str_adr) {
3779
3780 return 0;
3781 }
3782 if(!adr_is_var(fw,regs[0])) {
3783
3784 return 0;
3785 }
3786 save_misc_val(rule->name,regs[0],0,(uint32_t)is->insn->address);
3787 return 1;
3788 }
3789 return 0;
3790 }
3791
3792
3793 int sig_match_misc_flag_named(__attribute__ ((unused))firmware *fw, __attribute__ ((unused))iter_state_t *is, sig_rule_t *rule)
3794 {
3795 uint32_t ref=get_saved_sig_val(rule->ref_name);
3796 save_misc_val(rule->name,(ref)?1:0,0,ref);
3797 return 1;
3798 }
3799
3800 int sig_match_dry_memset(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3801 {
3802 if(!init_disasm_sig_ref(fw,is,rule)) {
3803 return 0;
3804 }
3805 if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
3806 printf("sig_match_dry_memset: no bl 1\n");
3807 return 0;
3808 }
3809
3810 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
3811 if(!insn_match_find_nth(fw,is,12,3,match_bl_blximm)) {
3812 printf("sig_match_dry_memset: no match bl 2\n");
3813 return 0;
3814 }
3815 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3816 }
3817
3818 int sig_match_dry_memzero(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3819 {
3820 if(!init_disasm_sig_ref(fw,is,rule)) {
3821 return 0;
3822 }
3823 if(!insn_match_find_next(fw,is,3,match_bl_blximm)) {
3824 printf("sig_match_dry_memset: no bl 1\n");
3825 return 0;
3826 }
3827
3828 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
3829 if(!insn_match_find_next(fw,is,7,match_bl_blximm)) {
3830 printf("sig_match_dry_memset: no match bl 2\n");
3831 return 0;
3832 }
3833 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3834 }
3835
3836 #if 0
3837
3838 int sig_match_dry_memzero(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3839 {
3840 if(!init_disasm_sig_ref(fw,is,rule)) {
3841 return 0;
3842 }
3843 const insn_match_t match_start[]={
3844 {MATCH_INS(AND, 3), {MATCH_OP_REG(R3), MATCH_OP_REG(R2), MATCH_OP_IMM(0xff)}},
3845 {MATCH_INS(ORR, 3), {MATCH_OP_REG(R2), MATCH_OP_REG(R3), MATCH_OP_REG(R3)}},
3846 {MATCH_INS(ORR, 3), {MATCH_OP_REG(R2), MATCH_OP_REG(R2), MATCH_OP_REG(R2)}},
3847 {MATCH_INS(B, 1), {MATCH_OP_IMM_ANY}},
3848 {ARM_INS_ENDING}
3849 };
3850 if(!insn_match_find_next_seq(fw,is,1,match_start)) {
3851 printf("sig_match_dry_memzero: no match start\n");
3852 return 0;
3853 }
3854
3855 uint32_t adr = get_branch_call_insn_target(fw,is) - 4;
3856 disasm_iter_init(fw,is,adr);
3857 const insn_match_t match_mov_r2_0[]={
3858 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R2), MATCH_OP_IMM(0x0)}},
3859 {ARM_INS_ENDING}
3860 };
3861 if(!insn_match_find_next(fw,is,1,match_mov_r2_0)) {
3862 printf("sig_match_dry_memzero: no match mov\n");
3863 return 0;
3864 }
3865 return save_sig_with_j(fw,rule->name,adr);
3866 }
3867 #endif
3868
3869 int sig_match_dry_memcpy_bytes(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3870 {
3871 if(!init_disasm_sig_ref(fw,is,rule)) {
3872 return 0;
3873 }
3874 if(!insn_match_find_next(fw,is,7,match_bl_blximm)) {
3875 printf("sig_match_dry_memcpy_bytes: no bl 1\n");
3876 return 0;
3877 }
3878
3879 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
3880
3881 const insn_match_t match_end[]={
3882 {MATCH_INS(POP, MATCH_OPCOUNT_IGNORE)},
3883 {MATCH_INS_CC(B,AL,MATCH_OPCOUNT_IGNORE)},
3884 {ARM_INS_ENDING}
3885 };
3886
3887 if(!insn_match_find_next_seq(fw,is,20,match_end)) {
3888 printf("sig_match_dry_memcpy_bytes: no match end\n");
3889 return 0;
3890 }
3891 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3892 }
3893
3894
3895 int sig_match_cam_has_iris_diaphragm(__attribute__ ((unused))firmware *fw, __attribute__ ((unused))iter_state_t *is, sig_rule_t *rule)
3896 {
3897 uint32_t v;
3898 uint32_t ref=0;get_saved_sig_val(rule->ref_name);
3899
3900 if(get_misc_val_value("CAM_IS_ILC")) {
3901 v=1;
3902 } else {
3903 ref=get_saved_sig_val(rule->ref_name);
3904 v=(ref)?1:0;
3905 }
3906 save_misc_val(rule->name,v,0,ref);
3907 return 1;
3908 }
3909
3910 int sig_match_cam_uncached_bit(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3911 {
3912 if(!init_disasm_sig_ref(fw,is,rule)) {
3913 return 0;
3914 }
3915 const insn_match_t match_bic_r0[]={
3916 {MATCH_INS(BIC, 3), {MATCH_OP_REG(R0), MATCH_OP_REG(R0), MATCH_OP_IMM_ANY}},
3917 {ARM_INS_ENDING}
3918 };
3919 if(insn_match_find_next(fw,is,4,match_bic_r0)) {
3920 save_misc_val(rule->name,is->insn->detail->arm.operands[2].imm,0,(uint32_t)is->insn->address);
3921 return 1;
3922 }
3923 return 0;
3924 }
3925
3926 int sig_match_umalloc_strictly(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3927 {
3928 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
3929 if(!str_adr) {
3930 printf("sig_umalloc_strictly: %s failed to find ref %s\n",rule->name,rule->ref_name);
3931 return 0;
3932 }
3933
3934 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
3935 if(!fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
3936 printf("sig_match_umalloc_strictly: faild to find ref insn\n");
3937 return 0;
3938 }
3939 if(is->insn->detail->arm.operands[0].reg != ARM_REG_R0) {
3940 printf("sig_match_umalloc_strictly: reg mismatch\n");
3941 return 0;
3942 }
3943 if(!insn_match_find_next(fw,is,4,match_bl_blximm)) {
3944 printf("sig_match_umalloc_strictly: no bl 1\n");
3945 return 0;
3946 }
3947 if(!is_sig_call(fw,is,"CreateTaskStrictly")) {
3948 printf("sig_match_umalloc_strictly: no CreateTaskStrictly\n");
3949 return 0;
3950 }
3951
3952 if(!insn_match_find_next(fw,is,6,match_b_bl_blximm)) {
3953 printf("sig_match_umalloc_strictly: no bl 1\n");
3954 return 0;
3955 }
3956
3957 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
3958 if(!insn_match_find_next(fw,is,10,match_bl_blximm)) {
3959 printf("sig_match_umalloc_strictly: no bl 2\n");
3960 return 0;
3961 }
3962 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3963 }
3964
3965 int sig_match_dcache_clean_flush_and_disable(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3966 {
3967 if(!init_disasm_sig_ref(fw,is,rule)) {
3968 return 0;
3969 }
3970 if(!find_next_sig_call(fw,is,44,"GetSRAndDisableInterrupt")) {
3971 printf("sig_match_dcache_clean_flush_and_disable: no GetSRAndDisableInterrupt\n");
3972 return 0;
3973 }
3974 if(!insn_match_find_next(fw,is,2,match_bl_blximm)) {
3975 printf("sig_match_dcache_clean_flush_and_disable: no bl\n");
3976 return 0;
3977 }
3978 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
3979 }
3980
3981 int sig_match_get_rom_id(firmware *fw, iter_state_t *is, sig_rule_t *rule)
3982 {
3983 if(!init_disasm_sig_ref(fw,is,rule)) {
3984 return 0;
3985 }
3986
3987 if(!disasm_iter(fw,is)) {
3988 printf("sig_match_get_rom_id: disasm failed\n");
3989 return 0;
3990 }
3991 if(is->insn->id == ARM_INS_MOV) {
3992 if(!disasm_iter(fw,is)) {
3993 printf("sig_match_get_rom_id: disasm failed\n");
3994 return 0;
3995 }
3996 if(is->insn->id != ARM_INS_B) {
3997 printf("sig_match_get_rom_id: no b\n");
3998 return 0;
3999 }
4000 } else if(is->insn->id == ARM_INS_PUSH) {
4001 const insn_match_t match_seq[]={
4002 {MATCH_INS(MOV, 2), {MATCH_OP_REG_ANY, MATCH_OP_REG_ANY}},
4003 {MATCH_INS(BL, 1), {MATCH_OP_IMM_ANY}},
4004 {MATCH_INS(MOV, 2), {MATCH_OP_REG_ANY, MATCH_OP_REG_ANY}},
4005 {MATCH_INS(POP, MATCH_OPCOUNT_IGNORE)},
4006 {MATCH_INS(B, MATCH_OPCOUNT_IGNORE)},
4007 {ARM_INS_ENDING}
4008 };
4009 if(!insn_match_find_next_seq(fw,is,1,match_seq)) {
4010 printf("sig_match_get_rom_id: no seq\n");
4011 return 0;
4012 }
4013 } else {
4014 printf("sig_match_get_rom_id: no match first insn\n");
4015 return 0;
4016 }
4017 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
4018 }
4019
4020 int sig_match_dcache_flush_and_enable(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4021 {
4022 if(!init_disasm_sig_ref(fw,is,rule)) {
4023 return 0;
4024 }
4025 if(!find_next_sig_call(fw,is,12,"GetSRAndDisableInterrupt")) {
4026 printf("sig_match_dcache_flush_and_enable: no GetSRAndDisableInterrupt\n");
4027 return 0;
4028 }
4029 if(!find_next_sig_call(fw,is,8,"dcache_clean_flush_and_disable")) {
4030 printf("sig_match_dcache_flush_and_enable: no dcache_clean_flush_and_disable\n");
4031 return 0;
4032 }
4033
4034
4035 if(!find_next_sig_call(fw,is,112,"SetSR")) {
4036 printf("sig_match_dcache_flush_and_enable: no SetSR\n");
4037 return 0;
4038 }
4039
4040 disasm_iter_init(fw,is,adr_hist_get(&is->ah,2));
4041 disasm_iter(fw,is);
4042 uint32_t adr = get_branch_call_insn_target(fw,is);
4043 if(!adr) {
4044 printf("sig_match_dcache_flush_and_enable: no match call\n");
4045 return 0;
4046 }
4047 return save_sig_with_j(fw,rule->name,adr);
4048 }
4049
4050
4051 int sig_match_physw_event_table(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4052 {
4053 if(!init_disasm_sig_ref(fw,is,rule)) {
4054 return 0;
4055 }
4056
4057 if(!insn_match_find_next(fw,is,5,match_ldr_pc)) {
4058 printf("sig_match_physw_event_table: match LDR PC failed\n");
4059 return 0;
4060 }
4061 uint32_t adr=LDR_PC2val(fw,is->insn);
4062 if(!adr) {
4063 printf("sig_match_physw_event_table: no match LDR PC 0x%"PRIx64"\n",is->insn->address);
4064 return 0;
4065 }
4066 if(!adr2ptr(fw,adr)) {
4067 printf("sig_match_physw_event_table: adr not ROM 0x%08x at 0x%"PRIx64"\n",adr,is->insn->address);
4068 return 0;
4069 }
4070 save_misc_val(rule->name,adr,0,(uint32_t)is->insn->address);
4071 return 1;
4072 }
4073 int sig_match_uiprop_count(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4074 {
4075 if(!init_disasm_sig_ref(fw,is,rule)) {
4076 return 0;
4077 }
4078 if(!find_next_sig_call(fw,is,38,"DebugAssert")) {
4079
4080 return 0;
4081 }
4082 if(!find_next_sig_call(fw,is,14,"DebugAssert")) {
4083
4084 return 0;
4085 }
4086 const insn_match_t match_bic_cmp[]={
4087 {MATCH_INS(BIC, 3), {MATCH_OP_REG_ANY, MATCH_OP_REG_ANY, MATCH_OP_IMM(0x8000)}},
4088 {MATCH_INS(CMP, 2), {MATCH_OP_REG_ANY, MATCH_OP_ANY}},
4089 {ARM_INS_ENDING}
4090 };
4091 if(!insn_match_find_next_seq(fw,is,3,match_bic_cmp)) {
4092
4093 return 0;
4094 }
4095 save_misc_val(rule->name,is->insn->detail->arm.operands[1].imm,0,(uint32_t)is->insn->address);
4096 return 1;
4097 }
4098
4099 int sig_match_get_canon_mode_list(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4100 {
4101 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
4102 if(!str_adr) {
4103 printf("sig_match_get_canon_mode_list: failed to find ref %s\n",rule->ref_name);
4104 return 0;
4105 }
4106 uint32_t adr=0;
4107
4108 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
4109 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,str_adr+SEARCH_NEAR_REF_RANGE)) {
4110
4111 if(!find_next_sig_call(fw,is,4,"LogCameraEvent")) {
4112
4113 continue;
4114 }
4115
4116 if(!disasm_iter(fw,is)) {
4117
4118 return 0;
4119 }
4120 const insn_match_t match_mov_r0_1[]={
4121 #if CS_API_MAJOR < 4
4122 {MATCH_INS(MOVS, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM(1)}},
4123 #endif
4124 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM(1)}},
4125 {ARM_INS_ENDING}
4126 };
4127 if(insn_match_any(is->insn,match_mov_r0_1)) {
4128 if(!insn_match_find_nth(fw,is,2,2,match_bl_blximm)) {
4129
4130 continue;
4131 }
4132 } else {
4133 if(!insn_match_any(is->insn,match_bl_blximm)) {
4134
4135 continue;
4136 }
4137 }
4138
4139 adr=get_branch_call_insn_target(fw,is);
4140 break;
4141 }
4142 if(!adr) {
4143 return 0;
4144 }
4145
4146 disasm_iter_init(fw,is,adr);
4147 if(!find_next_sig_call(fw,is,40,"TakeSemaphoreStrictly")) {
4148
4149 return 0;
4150 }
4151
4152 if(!insn_match_find_nth(fw,is,12,2,match_b_bl_blximm)) {
4153
4154 return 0;
4155 }
4156
4157 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
4158 const insn_match_t match_loop[]={
4159 {MATCH_INS(ADD, 3), {MATCH_OP_REG_ANY, MATCH_OP_REG_ANY, MATCH_OP_IMM(1)}},
4160 {MATCH_INS(UXTH, 2), {MATCH_OP_REG_ANY, MATCH_OP_REG_ANY}},
4161 {MATCH_INS(CMP, 2), {MATCH_OP_REG_ANY, MATCH_OP_IMM_ANY}},
4162 {MATCH_INS_CC(B,LO,MATCH_OPCOUNT_IGNORE)},
4163 {ARM_INS_ENDING}
4164 };
4165 if(!insn_match_find_next_seq(fw,is,64,match_loop)) {
4166
4167 return 0;
4168 }
4169 if(!insn_match_find_next(fw,is,2,match_bl_blximm)) {
4170
4171 return 0;
4172 }
4173
4174 adr=get_branch_call_insn_target(fw,is);
4175
4176 disasm_iter_init(fw,is,adr);
4177 const insn_match_t match_ldr_r0_ret[]={
4178 {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM_BASE(PC)}},
4179 {MATCH_INS(BX, 1), {MATCH_OP_REG(LR)}},
4180 {ARM_INS_ENDING}
4181 };
4182 if(!insn_match_find_next_seq(fw,is,1,match_ldr_r0_ret)) {
4183
4184 return 0;
4185 }
4186 return save_sig_with_j(fw,rule->name,adr);
4187 }
4188
4189 int sig_match_zoom_busy(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4190 {
4191 if(!init_disasm_sig_ref(fw,is,rule)) {
4192 return 0;
4193 }
4194
4195 if(!insn_match_find_next(fw,is,5,match_bl_blximm)) {
4196
4197 return 0;
4198 }
4199
4200 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
4201
4202 if(!insn_match_find_next(fw,is,5,match_ldr_pc)) {
4203
4204 return 0;
4205 }
4206 uint32_t base=LDR_PC2val(fw,is->insn);
4207 arm_reg rb=is->insn->detail->arm.operands[0].reg;
4208
4209
4210 if(!find_next_sig_call(fw,is,40,"TakeSemaphoreStrictly")) {
4211
4212 return 0;
4213 }
4214 if(!disasm_iter(fw,is)) {
4215
4216 return 0;
4217 }
4218
4219 if(is->insn->id != ARM_INS_LDR
4220 || is->insn->detail->arm.operands[0].reg != ARM_REG_R0
4221 || is->insn->detail->arm.operands[1].mem.base != rb) {
4222
4223 return 0;
4224 }
4225 save_misc_val(rule->name,base,is->insn->detail->arm.operands[1].mem.disp,(uint32_t)is->insn->address);
4226 return 1;
4227 }
4228
4229 int sig_match_focus_busy(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4230 {
4231 if(!init_disasm_sig_ref(fw,is,rule)) {
4232 return 0;
4233 }
4234
4235 if(!find_next_sig_call(fw,is,40,"TakeSemaphore")) {
4236
4237 return 0;
4238 }
4239
4240 if(!insn_match_find_next(fw,is,5,match_bl_blximm)) {
4241
4242 return 0;
4243 }
4244
4245 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
4246
4247 if(!insn_match_find_next(fw,is,5,match_ldr_pc)) {
4248
4249 return 0;
4250 }
4251 uint32_t base=LDR_PC2val(fw,is->insn);
4252 arm_reg rb=is->insn->detail->arm.operands[0].reg;
4253
4254
4255 if(!find_next_sig_call(fw,is,50,"TakeSemaphoreStrictly")) {
4256
4257 return 0;
4258 }
4259 const insn_match_t match_ldr[]={
4260 {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0), MATCH_OP_MEM_ANY}},
4261 {MATCH_INS(CBZ, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM_ANY}},
4262 {ARM_INS_ENDING}
4263 };
4264 if(!insn_match_find_next_seq(fw,is,10,match_ldr)) {
4265
4266 return 0;
4267 }
4268
4269 disasm_iter_init(fw,is,adr_hist_get(&is->ah,1));
4270 disasm_iter(fw,is);
4271
4272 if(is->insn->detail->arm.operands[1].mem.base != rb) {
4273
4274 return 0;
4275 }
4276 save_misc_val(rule->name,base,is->insn->detail->arm.operands[1].mem.disp,(uint32_t)is->insn->address);
4277 return 1;
4278 }
4279 int sig_match_aram_size(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4280 {
4281 if(!init_disasm_sig_ref(fw,is,rule)) {
4282 printf("sig_match_aram_size: missing ref\n");
4283 return 0;
4284 }
4285 const insn_match_t match_ldr_r0_sp_cmp[]={
4286 {MATCH_INS(LDR, 2), {MATCH_OP_REG(R0),MATCH_OP_MEM(SP,INVALID,0xc)}},
4287 {MATCH_INS(CMP, 2), {MATCH_OP_REG(R0),MATCH_OP_IMM_ANY}},
4288 {ARM_INS_ENDING}
4289 };
4290 if(!insn_match_find_next_seq(fw,is,15,match_ldr_r0_sp_cmp)) {
4291 printf("sig_match_aram_size: no match LDR\n");
4292 return 0;
4293 }
4294 uint32_t val=is->insn->detail->arm.operands[1].imm;
4295 if(val != 0x22000 && val != 0x32000) {
4296 printf("sig_match_aram_size: unexpected ARAM size 0x%08x\n",val);
4297 }
4298 save_misc_val(rule->name,val,0,(uint32_t)is->insn->address);
4299 return 1;
4300 }
4301
4302 int sig_match_aram_size_gt58(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4303 {
4304 if(!init_disasm_sig_ref(fw,is,rule)) {
4305 printf("sig_match_aram_size: missing ref\n");
4306 return 0;
4307 }
4308 const insn_match_t match_ldrd_r0r1_mov[]={
4309 {MATCH_INS(LDRD, 3), {MATCH_OP_REG(R0),MATCH_OP_REG(R1),MATCH_OP_MEM(SP,INVALID,0x10)}},
4310 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R2),MATCH_OP_IMM_ANY}},
4311 {ARM_INS_ENDING}
4312 };
4313
4314 const insn_match_t match_ldrd_r2r1_mov[]={
4315 {MATCH_INS(LDRD, 3), {MATCH_OP_REG(R2),MATCH_OP_REG(R1),MATCH_OP_MEM(SP,INVALID,0x10)}},
4316 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R3),MATCH_OP_IMM_ANY}},
4317 {ARM_INS_ENDING}
4318 };
4319 if(!insn_match_find_next_seq(fw,is,15,match_ldrd_r0r1_mov)) {
4320 init_disasm_sig_ref(fw,is,rule);
4321 if(!insn_match_find_next_seq(fw,is,15,match_ldrd_r2r1_mov)) {
4322 printf("sig_match_aram_size: no match LDR\n");
4323 }
4324 return 0;
4325 }
4326 uint32_t val=is->insn->detail->arm.operands[1].imm;
4327 if(val != 0x22000 && val != 0x32000) {
4328 printf("sig_match_aram_size: unexpected ARAM size 0x%08x\n",val);
4329 }
4330 save_misc_val(rule->name,val,0,(uint32_t)is->insn->address);
4331 return 1;
4332 }
4333
4334 int sig_match_aram_start(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4335 {
4336 if(!init_disasm_sig_ref(fw,is,rule)) {
4337 printf("sig_match_aram_start: missing ref\n");
4338 return 0;
4339 }
4340 if(!find_next_sig_call(fw,is,50,"DebugAssert")) {
4341 printf("sig_aram_start: no match DebugAssert\n");
4342 return 0;
4343 }
4344 const insn_match_t match_cmp_bne_ldr[]={
4345 {MATCH_INS(CMP, 2), {MATCH_OP_REG(R1),MATCH_OP_IMM(0)}},
4346 {MATCH_INS_CC(B,NE,MATCH_OPCOUNT_IGNORE)},
4347 {MATCH_INS(LDR, 2), {MATCH_OP_REG_ANY,MATCH_OP_MEM_BASE(PC)}},
4348 {ARM_INS_ENDING}
4349 };
4350 if(!insn_match_find_next_seq(fw,is,15,match_cmp_bne_ldr)) {
4351 printf("sig_match_aram_start: no match CMP\n");
4352 return 0;
4353 }
4354 uint32_t adr=LDR_PC2val(fw,is->insn);
4355 if(!adr) {
4356 printf("sig_match_aram_start: no match LDR PC 0x%"PRIx64"\n",is->insn->address);
4357 return 0;
4358 }
4359
4360 save_misc_val(rule->name,adr,0,(uint32_t)is->insn->address);
4361 return 1;
4362 }
4363
4364 int sig_match_aram_start2(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4365 {
4366 if (get_misc_val_value("ARAM_HEAP_START"))
4367 return 0;
4368
4369 if(!init_disasm_sig_ref(fw,is,rule)) {
4370 printf("sig_match_aram_start: missing ref\n");
4371 return 0;
4372 }
4373 if(!find_next_sig_call(fw,is,60,"DebugAssert")) {
4374 printf("sig_aram_start2: no match DebugAssert\n");
4375 return 0;
4376 }
4377 const insn_match_t match_cmp_bne_ldr[]={
4378 {MATCH_INS(CMP, 2), {MATCH_OP_REG(R1),MATCH_OP_IMM(0)}},
4379 {MATCH_INS_CC(B,NE,MATCH_OPCOUNT_IGNORE)},
4380 {MATCH_INS(LDR, 2), {MATCH_OP_REG_ANY,MATCH_OP_MEM_BASE(SP)}},
4381 {MATCH_INS(LDR, 2), {MATCH_OP_REG_ANY,MATCH_OP_MEM_BASE(PC)}},
4382 {ARM_INS_ENDING}
4383 };
4384 if(!insn_match_find_next_seq(fw,is,15,match_cmp_bne_ldr)) {
4385 printf("sig_match_aram_start2: no match CMP\n");
4386 return 0;
4387 }
4388 uint32_t adr=LDR_PC2val(fw,is->insn);
4389 if(!adr) {
4390 printf("sig_match_aram_start2: no match LDR PC 0x%"PRIx64"\n",is->insn->address);
4391 return 0;
4392 }
4393
4394 save_misc_val(rule->name,adr,0,(uint32_t)is->insn->address);
4395 return 1;
4396 }
4397
4398 int sig_match_icache_flush_range(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4399 {
4400 if(!init_disasm_sig_ref(fw,is,rule)) {
4401 printf("sig_match_icache_flush_range: missing ref\n");
4402 return 0;
4403 }
4404 if(!find_next_sig_call(fw,is,60,"DebugAssert")) {
4405 printf("sig_icache_flush_range: no match DebugAssert\n");
4406 return 0;
4407 }
4408 if(!find_next_sig_call(fw,is,44,"dcache_flush_range")) {
4409 printf("sig_icache_flush_range: no match DebugAssert\n");
4410 return 0;
4411 }
4412 if(!insn_match_find_next(fw,is,5,match_bl_blximm)) {
4413 printf("sig_icache_flush_range: bl match failed at 0x%"PRIx64"\n",is->insn->address);
4414 return 0;
4415 }
4416 return save_sig_with_j(fw,rule->name,get_branch_call_insn_target(fw,is));
4417 }
4418
4419 int sig_match__nrflag(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4420 {
4421 if(!init_disasm_sig_ref(fw,is,rule)) {
4422 return 0;
4423 }
4424 uint32_t fadr=is->adr;
4425
4426 const insn_match_t match_cmp_b[]={
4427 {MATCH_INS(CMP, 2), {MATCH_OP_REG(R0),MATCH_OP_IMM_ANY}},
4428 {MATCH_INS(B,MATCH_OPCOUNT_IGNORE)},
4429 {ARM_INS_ENDING}
4430 };
4431 if(!insn_match_find_next_seq(fw,is,4,match_cmp_b) || is->insn->detail->arm.cc == ARM_CC_AL) {
4432 printf("sig_match__nrflag: no match CMP\n");
4433 return 0;
4434 }
4435
4436 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
4437 if(!disasm_iter(fw,is)) {
4438 printf("sig_match__nrflag: disasm failed\n");
4439 return 0;
4440 }
4441
4442 uint32_t adr=LDR_PC2val(fw,is->insn);
4443 if(!adr) {
4444 printf("sig_match__nrflag: no match LDR PC 0x%"PRIx64"\n",is->insn->address);
4445 return 0;
4446 }
4447 arm_reg reg_base = is->insn->detail->arm.operands[0].reg;
4448 if(!disasm_iter(fw,is)) {
4449 printf("sig_match__nrflag: disasm failed\n");
4450 return 0;
4451 }
4452
4453 if(isADDx_imm(is->insn) || isSUBx_imm(is->insn)) {
4454 if((arm_reg)is->insn->detail->arm.operands[0].reg != reg_base) {
4455 printf("sig_match__nrflag: no match ADD/SUB\n");
4456 return 0;
4457 }
4458 if(isADDx_imm(is->insn)) {
4459 adr+=is->insn->detail->arm.operands[1].imm;
4460 } else {
4461 adr-=is->insn->detail->arm.operands[1].imm;
4462 }
4463 if(!disasm_iter(fw,is)) {
4464 printf("sig_match__nrflag: disasm failed\n");
4465 return 0;
4466 }
4467 }
4468 if(is->insn->id != ARM_INS_STR || (arm_reg)is->insn->detail->arm.operands[1].reg != reg_base) {
4469 printf("sig_match__nrflag: no match STR\n");
4470 return 0;
4471 }
4472 uint32_t disp = is->insn->detail->arm.operands[1].mem.disp;
4473 save_misc_val(rule->name,adr,disp,fadr);
4474 return 1;
4475 }
4476
4477
4478
4479
4480 int sig_match_var_struct_get(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4481 {
4482 if(!init_disasm_sig_ref(fw,is,rule)) {
4483 return 0;
4484 }
4485 uint32_t fadr=is->adr;
4486 var_ldr_desc_t desc;
4487 if(!find_and_get_var_ldr(fw, is, 1, 4, ARM_REG_R0, &desc)) {
4488 printf("sig_match_var_struct_get: no match ldr\n");
4489 return 0;
4490 }
4491 if(!disasm_iter(fw,is)) {
4492 printf("sig_match_var_struct_get: disasm failed\n");
4493 return 0;
4494 }
4495
4496 if(!insn_match(is->insn,match_bxlr)) {
4497 printf("sig_match_var_struct_get: no match BX LR\n");
4498 return 0;
4499 }
4500 save_misc_val(rule->name,desc.adr_adj,desc.off,fadr);
4501 return 1;
4502 }
4503
4504
4505
4506
4507
4508 int sig_match_ui_mem_func_ptr(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4509 {
4510 if(!init_disasm_sig_ref(fw,is,rule)) {
4511 return 0;
4512 }
4513 uint32_t fadr=is->adr;
4514 var_ldr_desc_t desc;
4515 if(!find_and_get_var_ldr(fw, is, 1, 4, ARM_REG_R1, &desc)) {
4516 printf("sig_match_var_struct_get: no match ldr\n");
4517 return 0;
4518 }
4519 if(!disasm_iter(fw,is)) {
4520 printf("sig_match_var_struct_get: disasm failed\n");
4521 return 0;
4522 }
4523 const insn_match_t match_bx_r1[]={
4524 {MATCH_INS(BX, 1), {MATCH_OP_REG(R1),}},
4525 {ARM_INS_ENDING}
4526 };
4527
4528
4529 if(!insn_match(is->insn,match_bx_r1)) {
4530 printf("sig_match_var_struct_get: no match BX R1\n");
4531 return 0;
4532 }
4533 save_misc_val(rule->name,desc.adr_adj,desc.off,fadr);
4534 return 1;
4535 }
4536
4537
4538 int sig_match_func_ptr_val(firmware *fw, __attribute__ ((unused))iter_state_t *is, sig_rule_t *rule)
4539 {
4540 uint32_t adr = get_misc_val_value(rule->ref_name);
4541 if(!adr) {
4542 return 0;
4543 }
4544 uint32_t *vp = (uint32_t *)adr2ptr_with_data(fw,adr);
4545 if(!vp) {
4546 return 0;
4547 }
4548 return save_sig_with_j(fw,rule->name,*vp);
4549 }
4550
4551
4552 int sig_match_av_over_sem(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4553 {
4554
4555 if(!get_misc_val_value("CAM_HAS_IRIS_DIAPHRAGM")) {
4556 return 0;
4557 }
4558
4559 if(!init_disasm_sig_ref(fw,is,rule)) {
4560 return 0;
4561 }
4562 if(!find_next_sig_call(fw,is,30,"TakeSemaphore")) {
4563 printf("sig_match_av_over_sem: no match TakeSemaphore at 0x%"PRIx64"\n",is->insn->address);
4564 return 0;
4565 }
4566
4567
4568 disasm_iter_init(fw,is,adr_hist_get(&is->ah,5));
4569 var_ldr_desc_t desc;
4570 if(!find_and_get_var_ldr(fw, is, 3, 4, ARM_REG_R0, &desc)) {
4571 printf("sig_match_av_over_sem: no match ldr at 0x%"PRIx64"\n",is->insn->address);
4572 return 0;
4573 }
4574
4575 save_misc_val(rule->name,desc.adr_adj,desc.off,(uint32_t)is->insn->address);
4576 return 1;
4577 }
4578
4579 int sig_match_canon_menu_active(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4580 {
4581 if(!init_disasm_sig_ref(fw,is,rule)) {
4582 return 0;
4583 }
4584 var_ldr_desc_t desc;
4585 if(!find_and_get_var_ldr(fw, is, 2, 4, ARM_REG_R0, &desc)) {
4586 printf("sig_match_canon_menu_active: no match ldr at 0x%"PRIx64"\n",is->insn->address);
4587 return 0;
4588 }
4589 if(!disasm_iter(fw,is)) {
4590 printf("sig_match_canon_menu_active: disasm failed\n");
4591 return 0;
4592 }
4593 if(is->insn->id != ARM_INS_CMP) {
4594 printf("sig_match_canon_menu_active: no match cmp at 0x%"PRIx64"\n",is->insn->address);
4595 return 0;
4596 }
4597 save_misc_val(rule->name,desc.adr_adj,desc.off,(uint32_t)is->insn->address);
4598 return 1;
4599 }
4600
4601 int sig_match_file_counter_init(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4602 {
4603 if(!init_disasm_sig_ref(fw,is,rule)) {
4604 return 0;
4605 }
4606
4607 if(!insn_match_find_next(fw,is,3,match_bl_blximm)) {
4608
4609 return 0;
4610 }
4611
4612 if(check_simple_func(fw,get_branch_call_insn_target(fw,is),MATCH_SIMPLE_FUNC_NULLSUB,NULL)) {
4613 if(!insn_match_find_next(fw,is,3,match_bl_blximm)) {
4614
4615 return 0;
4616 }
4617 }
4618
4619 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
4620 if(!insn_match_find_next(fw,is,3,match_bl_blximm)) {
4621
4622 return 0;
4623 }
4624 uint32_t fadr = get_branch_call_insn_target(fw,is);
4625
4626 disasm_iter_init(fw,is,fadr);
4627 if(!disasm_iter(fw,is)) {
4628
4629 return 0;
4630 }
4631
4632 if(!isLDR_PC(is->insn)) {
4633
4634 return 0;
4635 }
4636
4637 return save_sig_with_j(fw,rule->name,fadr);
4638 }
4639 int sig_match_file_counter_var(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4640 {
4641 if(!init_disasm_sig_ref(fw,is,rule)) {
4642 return 0;
4643 }
4644 uint32_t adr=LDR_PC2val(fw,is->insn);
4645 if(!adr) {
4646
4647 return 0;
4648 }
4649 if(is->insn->detail->arm.operands[0].reg != ARM_REG_R0) {
4650
4651 return 0;
4652 }
4653 if(!adr_is_var(fw,adr)) {
4654
4655 return 0;
4656 }
4657 save_misc_val(rule->name,adr,0,(uint32_t)is->insn->address);
4658 return 1;
4659 }
4660
4661 int sig_match_palette_vars(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4662 {
4663 if(!init_disasm_sig_ref(fw,is,rule)) {
4664 return 0;
4665 }
4666 if(!find_next_sig_call(fw,is,70,"transfer_src_overlay")) {
4667 printf("sig_match_palette_vars: no match transfer_src_overlay\n");
4668 return 0;
4669 }
4670 uint32_t fadr=0;
4671 int i;
4672
4673 for(i=1; i<=6; i++) {
4674 if(!fw_disasm_iter_single(fw,adr_hist_get(&is->ah,i))) {
4675 printf("sig_match_palette_vars: disasm failed\n");
4676 return 0;
4677 }
4678 fadr=get_branch_call_insn_target(fw,fw->is);
4679 if(fadr) {
4680 break;
4681 }
4682 }
4683 if(!fadr) {
4684 printf("sig_match_palette_vars: no match bl 1 0x%"PRIx64"\n",fw->is->insn->address);
4685 return 0;
4686 }
4687
4688 disasm_iter_init(fw,is,fadr);
4689
4690 if(!insn_match_find_next(fw,is,3,match_bl)) {
4691 printf("sig_match_palette_vars: no match bl 2 0x%"PRIx64"\n",is->insn->address);
4692 return 0;
4693 }
4694
4695 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
4696
4697 if(!insn_match_find_next(fw,is,3,match_ldr_pc)) {
4698 printf("sig_match_palette_vars: no match ldr pc 0x%"PRIx64"\n",is->insn->address);
4699 return 0;
4700 }
4701
4702 uint32_t pal_base=LDR_PC2val(fw,is->insn);
4703 if(!pal_base || !adr_is_var(fw,pal_base)) {
4704 printf("sig_match_palette_vars: bad LDR PC 0x%"PRIx64"\n",is->insn->address);
4705 return 0;
4706 }
4707
4708 arm_reg ptr_reg = is->insn->detail->arm.operands[0].reg;
4709
4710 save_misc_val(rule->name,pal_base,0,(uint32_t)is->insn->address);
4711
4712 int found=0;
4713
4714 for(i=0; i<3; i++) {
4715 if(!disasm_iter(fw,is)) {
4716 printf("sig_match_palette_vars: disasm failed\n");
4717 return 0;
4718 }
4719 if (is->insn->id == ARM_INS_LDR && is->insn->detail->arm.operands[1].mem.base == ptr_reg) {
4720 save_misc_val("active_palette_buffer",
4721 pal_base,
4722 is->insn->detail->arm.operands[1].mem.disp,
4723 (uint32_t)is->insn->address);
4724 found=1;
4725 break;
4726 }
4727 }
4728 if(!found) {
4729 printf("sig_match_palette_vars: no match active_palette_buffer 0x%"PRIx64"\n",is->insn->address);
4730 return 0;
4731 }
4732
4733 if(!find_next_sig_call(fw,is,20,"PTM_RestoreUIProperty_FW")) {
4734 printf("sig_match_palette_vars: no match PTM_RestoreUIProperty_FW\n");
4735 return 0;
4736 }
4737
4738 for(i=0; i<6; i++) {
4739 if(!disasm_iter(fw,is)) {
4740 printf("sig_match_palette_vars: disasm failed\n");
4741 return 0;
4742 }
4743 if (is->insn->id == ARM_INS_LDR && is->insn->detail->arm.operands[1].mem.base == ptr_reg) {
4744 save_misc_val("palette_buffer_ptr",
4745 pal_base,
4746 is->insn->detail->arm.operands[1].mem.disp,
4747 (uint32_t)is->insn->address);
4748 return 1;
4749 }
4750 }
4751 printf("sig_match_palette_vars: no match palette_buffer_ptr 0x%"PRIx64"\n",is->insn->address);
4752 return 0;
4753 }
4754
4755 int sig_match_live_free_cluster_count(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4756 {
4757 if(!init_disasm_sig_ref(fw,is,rule)) {
4758 return 0;
4759 }
4760
4761
4762 if(!insn_match_find_nth(fw,is,22,3,match_bl_blximm)) {
4763 printf("sig_match_live_free_cluster_count: no match bl1 0x%"PRIx64"\n",is->insn->address);
4764 return 0;
4765 }
4766
4767 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
4768
4769 if(!find_next_sig_call(fw,is,20,"get_fstype")) {
4770 printf("sig_match_live_free_cluster_count: no get_fstype 0x%"PRIx64"\n",is->insn->address);
4771 return 0;
4772 }
4773
4774
4775 if(!insn_match_find_nth(fw,is,12,2,match_bl_blximm)) {
4776 printf("sig_match_live_free_cluster_count: no match bl2 0x%"PRIx64"\n",is->insn->address);
4777 return 0;
4778 }
4779
4780
4781 disasm_iter_init(fw,is,get_branch_call_insn_target(fw,is));
4782
4783
4784 if(!insn_match_find_next(fw,is,3,match_ldr_pc)) {
4785 printf("sig_match_live_free_cluster_count: no match ldr1 0x%"PRIx64"\n",is->insn->address);
4786 return 0;
4787 }
4788
4789 if(!insn_match_find_next(fw,is,3,match_ldr_pc)) {
4790 printf("sig_match_live_free_cluster_count: no match ldr2 0x%"PRIx64"\n",is->insn->address);
4791 return 0;
4792 }
4793 uint32_t base = LDR_PC2val(fw,is->insn);
4794
4795 if(!find_next_sig_call(fw,is,16,"takesemaphore_low")) {
4796 printf("sig_match_live_free_cluster_count: no takesemaphore_low 0x%"PRIx64"\n",is->insn->address);
4797 return 0;
4798 }
4799 const insn_match_t match_ldr_ldrd[]={
4800 {MATCH_INS(LDR, 2), {MATCH_OP_REG_ANY, MATCH_OP_ANY}},
4801 {MATCH_INS(LDRD, 3), {MATCH_OP_REG_ANY, MATCH_OP_REG_ANY, MATCH_OP_ANY}},
4802 {ARM_INS_ENDING}
4803 };
4804
4805 if(!insn_match_find_next_seq(fw,is,50,match_ldr_ldrd)) {
4806 printf("sig_match_live_free_cluster_count: no match ldrd 0x%"PRIx64"\n",is->insn->address);
4807 return 0;
4808 }
4809
4810 save_misc_val(rule->name,base,is->insn->detail->arm.operands[2].mem.disp + 4,(uint32_t)is->insn->address);
4811 return 1;
4812
4813 }
4814
4815 int sig_match_rom_ptr_get(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4816 {
4817 if(!init_disasm_sig_ref(fw,is,rule)) {
4818 return 0;
4819 }
4820 uint32_t fadr=is->adr;
4821 if(!disasm_iter(fw,is)) {
4822 printf("sig_match_rom_ptr_get: disasm failed\n");
4823 return 0;
4824 }
4825 uint32_t adr=LDR_PC2val(fw,is->insn);
4826 if(!adr) {
4827 printf("sig_match_rom_ptr_get: no match LDR PC 0x%"PRIx64"\n",is->insn->address);
4828 return 0;
4829 }
4830 if(is->insn->detail->arm.operands[0].reg != ARM_REG_R0) {
4831 printf("sig_match_rom_ptr_get: not R0\n");
4832 return 0;
4833 }
4834 if(!disasm_iter(fw,is)) {
4835 printf("sig_match_rom_ptr_get: disasm failed\n");
4836 return 0;
4837 }
4838
4839 if(!insn_match(is->insn,match_bxlr)) {
4840 printf("sig_match_rom_ptr_get: no match BX LR\n");
4841 return 0;
4842 }
4843 save_misc_val(rule->name,adr,0,fadr);
4844 return 1;
4845 }
4846
4847
4848
4849
4850 uint32_t find_call_near_str(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4851 {
4852 uint32_t str_adr;
4853 if(rule->param & SIG_NEAR_INDIRECT) {
4854 str_adr = find_str_bytes(fw,rule->ref_name);
4855 } else {
4856 str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
4857 }
4858 if(!str_adr) {
4859 printf("find_call_near_str: %s failed to find ref %s\n",rule->name,rule->ref_name);
4860 return 0;
4861 }
4862 uint32_t search_adr = str_adr;
4863
4864
4865 if(rule->param & SIG_NEAR_INDIRECT) {
4866
4867 search_adr=find_u32_adr_range(fw,str_adr,fw->rom_code_search_min_adr,fw->rom_code_search_max_adr);
4868 if(!search_adr) {
4869 printf("find_call_near_str: %s failed to find indirect ref %s\n",rule->name,rule->ref_name);
4870 return 0;
4871 }
4872
4873 }
4874 const insn_match_t *insn_match;
4875 if(rule->param & SIG_NEAR_JMP_SUB) {
4876 insn_match = match_b_bl_blximm;
4877 } else {
4878 insn_match = match_bl_blximm;
4879 }
4880
4881 int max_insns=rule->param&SIG_NEAR_OFFSET_MASK;
4882 int n=(rule->param&SIG_NEAR_COUNT_MASK)>>SIG_NEAR_COUNT_SHIFT;
4883
4884
4885 disasm_iter_init(fw,is,(ADR_ALIGN4(search_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
4886 while(fw_search_insn(fw,is,search_disasm_const_ref,str_adr,NULL,search_adr+SEARCH_NEAR_REF_RANGE)) {
4887
4888 if(rule->param & SIG_NEAR_REV) {
4889 int i;
4890 int n_calls=0;
4891 for(i=1; i<=max_insns; i++) {
4892 fw_disasm_iter_single(fw,adr_hist_get(&is->ah,i));
4893 if(insn_match_any(fw->is->insn,insn_match)) {
4894 n_calls++;
4895 }
4896 if(n_calls == n) {
4897 return iter_state_adr(fw->is);
4898 }
4899 }
4900 } else {
4901 if(insn_match_find_nth(fw,is,max_insns,n,insn_match)) {
4902 return iter_state_adr(is);
4903 }
4904 }
4905 }
4906 printf("find_call_near_str: no match %s\n",rule->name);
4907 return 0;
4908 }
4909
4910
4911 int sig_match_near_str(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4912 {
4913 if (!get_saved_sig_val(rule->name))
4914 {
4915 uint32_t call_adr = find_call_near_str(fw,is,rule);
4916 if(call_adr) {
4917 return save_sig_match_call(fw, rule, call_adr);
4918 }
4919 }
4920 return 0;
4921 }
4922
4923
4924
4925
4926
4927
4928 uint32_t find_str_arg_call(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4929 {
4930 arm_reg reg = ARM_REG_R0 + (rule->param & SIG_STRCALL_ARG_MASK);
4931 uint32_t str_adr = find_str_bytes_main_fw(fw,rule->ref_name);
4932 if(!str_adr) {
4933 printf("find_str_arg_call: %s failed to find ref %s\n",rule->name,rule->ref_name);
4934 return 0;
4935 }
4936
4937 do {
4938 disasm_iter_init(fw,is,(ADR_ALIGN4(str_adr) - SEARCH_NEAR_REF_RANGE) | fw->thumb_default);
4939 uint32_t call_adr = find_const_ref_call(fw, is, SEARCH_NEAR_REF_RANGE*2, 8, reg, str_adr);
4940 if(call_adr) {
4941 return call_adr;
4942 }
4943 str_adr = find_next_str_bytes_main_fw(fw,rule->ref_name, str_adr+strlen(rule->ref_name));
4944 } while (str_adr);
4945 printf("find_str_arg_call: no match %s\n",rule->name);
4946 return 0;
4947 }
4948
4949 int sig_match_str_arg_call(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4950 {
4951 uint32_t call_adr = find_str_arg_call(fw,is,rule);
4952 if(call_adr) {
4953 return save_sig_match_call(fw, rule, call_adr);
4954 }
4955 return 0;
4956 }
4957
4958 int sig_match_prop_string(firmware *fw, iter_state_t *is, sig_rule_t *rule)
4959 {
4960 uint32_t call_adr = find_call_near_str(fw, is, rule);
4961
4962 if (call_adr == 0)
4963 return 0;
4964
4965
4966 disasm_iter_init(fw,is,call_adr);
4967 disasm_iter(fw,is);
4968
4969 uint32_t myreg;
4970
4971 if (is_sig_call(fw,is,"GetPropertyCase")) {
4972
4973 myreg = 0;
4974 }
4975 else {
4976
4977 myreg = 1;
4978 }
4979
4980
4981 const int hl = 8;
4982 disasm_iter_init(fw,is,call_adr - hl*4);
4983
4984 while (is->adr < call_adr) {
4985 if (!disasm_iter(fw,is))
4986 disasm_iter_init(fw,is,(is->adr | is->thumb)+2);
4987 }
4988 uint32_t regs[4];
4989
4990 if ((get_call_const_args(fw,is,hl,regs)&(1<<myreg))==(1<<myreg)) {
4991 add_prop_hit(rule->name,(int)regs[myreg]);
4992 return 1;
4993 }
4994 return 0;
4995 }
4996
4997
4998
4999 int is_immediate_ret_sub(firmware *fw,iter_state_t *is_init)
5000 {
5001 fw_disasm_iter_single(fw,is_init->adr | is_init->thumb);
5002 const insn_match_t match_mov_r0_imm[]={
5003 {MATCH_INS(MOV, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM_ANY}},
5004 #if CS_API_MAJOR < 4
5005 {MATCH_INS(MOVS, 2), {MATCH_OP_REG(R0), MATCH_OP_IMM_ANY}},
5006 #endif
5007 {ARM_INS_ENDING}
5008 };
5009
5010 if(insn_match_any(fw->is->insn,match_mov_r0_imm)) {
5011 fw_disasm_iter(fw);
5012 }
5013 if(isRETx(fw->is->insn)) {
5014 return 1;
5015 }
5016 return 0;
5017 }
5018
5019
5020
5021
5022
5023
5024 #define SIG_NAMED_LAST_MAX_MASK 0x00000FFF
5025 #define SIG_NAMED_LAST_MIN_MASK 0x00FFF000
5026 #define SIG_NAMED_LAST_MIN_SHIFT 12
5027 #define SIG_NAMED_LAST_RANGE(min,max) ((SIG_NAMED_LAST_MIN_MASK&((min)<<SIG_NAMED_LAST_MIN_SHIFT)) \
5028 | (SIG_NAMED_LAST_MAX_MASK&(max)))
5029
5030 int sig_match_named_last(firmware *fw, iter_state_t *is, sig_rule_t *rule)
5031 {
5032 uint32_t ref_adr = get_saved_sig_val(rule->ref_name);
5033 int min = (rule->param&SIG_NAMED_LAST_MIN_MASK)>>SIG_NAMED_LAST_MIN_SHIFT;
5034 int max = (rule->param&SIG_NAMED_LAST_MAX_MASK);
5035 if(!ref_adr) {
5036 printf("sig_match_named_last: %s missing %s\n",rule->name,rule->ref_name);
5037 return 0;
5038 }
5039 disasm_iter_init(fw,is,ref_adr);
5040 if(is_immediate_ret_sub(fw,is)) {
5041 printf("sig_match_named_last: immediate return %s\n",rule->name);
5042 return 0;
5043 }
5044 uint32_t fadr = find_last_call_from_func(fw,is,min,max);
5045 if(fadr) {
5046 return save_sig_with_j(fw,rule->name,fadr);
5047 }
5048 return 0;
5049 }
5050
5051
5052 #define SIG_NAMED_ASIS 0x00000000
5053
5054 #define SIG_NAMED_JMP_SUB 0x00000001
5055
5056 #define SIG_NAMED_SUB 0x00000002
5057
5058 #define SIG_NAMED_INSN 0x00000003
5059 #define SIG_NAMED_TYPE_MASK 0x0000000F
5060
5061 #define SIG_NAMED_CLEARTHUMB 0x00000010
5062 #define SIG_NAMED_FLAG_MASK 0x000000F0
5063
5064 #define SIG_NAMED_NTH_MASK 0x00000F00
5065 #define SIG_NAMED_NTH_SHIFT 8
5066
5067
5068
5069 #define SIG_NAMED_NTH_RANGE_MASK 0x0003F000
5070 #define SIG_NAMED_NTH_RANGE_SHIFT 12
5071
5072
5073 #define SIG_NAMED_NTH(n,type) ((SIG_NAMED_NTH_MASK&((n)<<SIG_NAMED_NTH_SHIFT)) | (SIG_NAMED_##type))
5074
5075 #define SIG_NAMED_NTH_RANGE(n) ((SIG_NAMED_NTH_RANGE_MASK&((n)<<SIG_NAMED_NTH_RANGE_SHIFT)))
5076
5077 int sig_match_named_save_sig(firmware *fw,const char *name, uint32_t adr, uint32_t flags)
5078 {
5079 adr = save_sig_veneers(fw, name, adr);
5080 if(adr) {
5081 if(flags & SIG_NAMED_CLEARTHUMB) {
5082 adr = ADR_CLEAR_THUMB(adr);
5083 }
5084 save_sig(fw,name,adr);
5085 return 1;
5086 }
5087 return 0;
5088 }
5089
5090
5091
5092 int sig_match_named(firmware *fw, iter_state_t *is, sig_rule_t *rule)
5093 {
5094 uint32_t ref_adr = get_saved_sig_val(rule->ref_name);
5095 if(!ref_adr) {
5096 printf("sig_match_named: missing %s\n",rule->ref_name);
5097 return 0;
5098 }
5099 uint32_t sig_type = rule->param & SIG_NAMED_TYPE_MASK;
5100 uint32_t sig_flags = rule->param & SIG_NAMED_FLAG_MASK;
5101 uint32_t sig_nth = (rule->param & SIG_NAMED_NTH_MASK)>>SIG_NAMED_NTH_SHIFT;
5102 uint32_t sig_nth_range = (rule->param & SIG_NAMED_NTH_RANGE_MASK)>>SIG_NAMED_NTH_RANGE_SHIFT;
5103 if(!sig_nth) {
5104 sig_nth=1;
5105 }
5106 if(!sig_nth_range) {
5107 sig_nth_range=5;
5108 }
5109
5110
5111 if(sig_type == SIG_NAMED_ASIS) {
5112 return sig_match_named_save_sig(fw,rule->name,ref_adr,sig_flags);
5113 }
5114 const insn_match_t *insn_match;
5115 if(sig_type == SIG_NAMED_JMP_SUB) {
5116 insn_match = match_b_bl_blximm;
5117 } else if(sig_type == SIG_NAMED_SUB) {
5118 insn_match = match_bl_blximm;
5119 } else if(sig_type == SIG_NAMED_INSN) {
5120 insn_match = NULL;
5121 } else {
5122 printf("sig_match_named: %s invalid type %d\n",rule->ref_name,sig_type);
5123 return 0;
5124 }
5125
5126 disasm_iter_init(fw,is,ref_adr);
5127
5128 if(is_immediate_ret_sub(fw,is)) {
5129 printf("sig_match_named: immediate return %s\n",rule->name);
5130 return 0;
5131 }
5132 if(sig_type == SIG_NAMED_INSN) {
5133 uint32_t i;
5134
5135 for(i=0;i<=sig_nth;i++) {
5136 if(!disasm_iter(fw,is)) {
5137 printf("sig_match_named: disasm failed %s 0x%08x\n",rule->name,(uint32_t)is->insn->address);
5138 return 0;
5139 }
5140 }
5141 return sig_match_named_save_sig(fw,rule->name,iter_state_adr(is),sig_flags);
5142 }
5143
5144
5145 if(insn_match_find_nth(fw,is,15 + sig_nth_range*sig_nth,sig_nth,insn_match)) {
5146 uint32_t adr = B_BL_BLXimm_target(fw,is->insn);
5147 if(adr) {
5148
5149 if(is->insn->id == ARM_INS_BLX) {
5150
5151 if(!is->thumb) {
5152 adr=ADR_SET_THUMB(adr);
5153 }
5154 } else {
5155
5156 adr |= is->thumb;
5157 }
5158 return sig_match_named_save_sig(fw,rule->name,adr,sig_flags);
5159 } else {
5160 printf("sig_match_named: %s invalid branch target 0x%08x\n",rule->ref_name,adr);
5161 }
5162 } else {
5163 printf("sig_match_named: %s branch not found 0x%08x\n",rule->ref_name,ref_adr);
5164 }
5165 return 0;
5166 }
5167
5168
5169
5170
5171 sig_rule_t sig_rules_initial[]={
5172
5173
5174 {sig_match_str_r0_call, "ExportToEventProcedure_FW","ExportToEventProcedure"},
5175 {sig_match_reg_evp, "RegisterEventProcedure",},
5176 {sig_match_reg_evp_table, "RegisterEventProcTable","DispDev_EnableEventProc"},
5177 {sig_match_reg_evp_alt2, "RegisterEventProcedure_alt2","EngApp.Delete"},
5178 {sig_match_unreg_evp_table,"UnRegisterEventProcTable","MechaUnRegisterEventProcedure"},
5179 {sig_match_evp_table_veneer,"RegisterEventProcTable_alt","RegisterEventProcTable"},
5180 {sig_match_evp_table_veneer,"UnRegisterEventProcTable_alt","UnRegisterEventProcTable"},
5181 {sig_match_str_r0_call,"CreateTaskStrictly", "LowConsole",},
5182 {sig_match_str_r0_call,"CreateTask", "EvShel",},
5183 {sig_match_named, "CreateTask_low", "CreateTask", (SIG_NAMED_NTH(2,SUB)|SIG_NAMED_NTH_RANGE(10)), SIG_DRY_MAX(52)},
5184 {sig_match_named, "CreateTask_low", "CreateTask", (SIG_NAMED_NTH(3,SUB)|SIG_NAMED_NTH_RANGE(10)), SIG_DRY_MIN(54)},
5185 {sig_match_createtaskstrictly_alt,"CreateTaskStrictly_alt","HdmiCecTask",0, SIG_DRY_MIN(58)},
5186 {sig_match_createtask_alt,"CreateTask_alt", "CreateTaskStrictly_alt",0, SIG_DRY_MIN(58)},
5187 {sig_match_near_str, "dry_memcpy", "EP Slot%d", SIG_NEAR_BEFORE(4,1)},
5188 {sig_match_add_ptp_handler,"add_ptp_handler", "PTPtoFAPI_EventProcTask_Try",},
5189 {NULL},
5190 };
5191
5192
5193
5194
5195 sig_rule_t sig_rules_main[]={
5196
5197 {sig_match_named, "SetParameterData", "PTM_BackupUIProperty_FW", 0, SIG_DRY_MIN(58)},
5198 {sig_match_named, "ExitTask", "ExitTask_FW",},
5199 {sig_match_named, "EngDrvRead", "EngDrvRead_FW", SIG_NAMED_JMP_SUB},
5200 {sig_match_named, "CalcLog10", "CalcLog10_FW", SIG_NAMED_JMP_SUB},
5201 {sig_match_named, "CalcSqrt", "CalcSqrt_FW", SIG_NAMED_JMP_SUB},
5202 {sig_match_named, "Close", "Close_FW",},
5203 {sig_match_named, "Close_low", "Close", SIG_NAMED_NTH(3,SUB),SIG_DRY_MIN(58)},
5204 {sig_match_named, "close", "Close", SIG_NAMED_SUB, SIG_DRY_MAX(57)},
5205 {sig_match_named, "close", "Close_low", SIG_NAMED_SUB, SIG_DRY_MIN(58)},
5206 {sig_match_named, "DoAELock", "SS.DoAELock_FW", SIG_NAMED_JMP_SUB},
5207 {sig_match_named, "DoAFLock", "SS.DoAFLock_FW", SIG_NAMED_JMP_SUB},
5208 {sig_match_named, "Fclose_Fut", "Fclose_Fut_FW",},
5209 {sig_match_named, "Fopen_Fut", "Fopen_Fut_FW",},
5210 {sig_match_named, "Fread_Fut", "Fread_Fut_FW",},
5211 {sig_match_named, "Fseek_Fut", "Fseek_Fut_FW",},
5212 {sig_match_named, "Fwrite_Fut", "Fwrite_Fut_FW",},
5213 {sig_match_named, "fopen_low", "Fopen_Fut", SIG_NAMED_NTH(3,SUB)},
5214 {sig_match_named, "fut_prepare", "Fopen_Fut", SIG_NAMED_NTH(1,SUB)},
5215 {sig_match_named, "fut_finish", "Fopen_Fut", SIG_NAMED_NTH(4,SUB)},
5216
5217
5218
5219 {sig_match_named, "fread_low", "Fread_Fut", SIG_NAMED_NTH(2,SUB)},
5220 {sig_match_named, "fseek_low", "Fseek_Fut", SIG_NAMED_NTH(2,SUB)},
5221 {sig_match_named, "fwrite_low", "Fwrite_Fut", SIG_NAMED_NTH(2,SUB)},
5222
5223 {sig_match_named, "GetAdChValue", "GetAdChValue_FW",},
5224 {sig_match_named, "GetCurrentAvValue", "GetCurrentAvValue_FW",},
5225 {sig_match_named, "GetCurrentShutterSpeed", "GetCurrentShutterSpeed_FW",},
5226 {sig_match_named, "GetBatteryTemperature", "GetBatteryTemperature_FW",},
5227 {sig_match_named, "GetCCDTemperature", "GetCCDTemperature_FW",},
5228 {sig_match_named, "GetFocusLensSubjectDistance","GetFocusLensSubjectDistance_FW",SIG_NAMED_JMP_SUB},
5229 {sig_match_named, "GetOpticalTemperature", "GetOpticalTemperature_FW",},
5230 {sig_match_named, "GetPropertyCase", "GetPropertyCase_FW", SIG_NAMED_SUB},
5231 {sig_match_named, "GetSystemTime", "GetSystemTime_FW",},
5232 {sig_match_named, "_GetSystemTime", "GetSystemTime", SIG_NAMED_SUB},
5233
5234 {sig_match_named, "GetSRAndDisableInterrupt", "_GetSystemTime", SIG_NAMED_SUB, SIG_DRY_ANY, SIG_NO_D7},
5235 {sig_match_named, "GetSRAndDisableInterrupt", "_GetSystemTime", SIG_NAMED_NTH(2,SUB),SIG_DRY_ANY, SIG_NO_D6},
5236 {sig_match_named, "SetSR", "_GetSystemTime", SIG_NAMED_NTH(2,SUB),SIG_DRY_ANY, SIG_NO_D7},
5237 {sig_match_named, "SetSR", "_GetSystemTime", SIG_NAMED_NTH(3,SUB),SIG_DRY_ANY, SIG_NO_D6},
5238 {sig_match_named, "GetUsableMaxAv", "GetUsableMaxAv_FW",},
5239 {sig_match_named, "GetUsableMinAv", "GetUsableMinAv_FW",},
5240
5241 {sig_match_named, "GetUsableAvRange", "GetUsableMinAv", SIG_NAMED_SUB},
5242 {sig_match_named, "GetVRAMHPixelsSize", "GetVRAMHPixelsSize_FW",},
5243 {sig_match_named, "GetVRAMVPixelsSize", "GetVRAMVPixelsSize_FW",},
5244 {sig_match_named, "GetZoomLensCurrentPoint", "GetZoomLensCurrentPoint_FW",},
5245 {sig_match_named, "GetZoomLensCurrentPosition","GetZoomLensCurrentPosition_FW",},
5246 {sig_match_named, "GiveSemaphore", "GiveSemaphore_FW",},
5247 {sig_match_named, "IsStrobeChargeCompleted", "EF.IsChargeFull_FW",},
5248 {sig_match_named, "Read", "Read_FW",},
5249 {sig_match_named, "LEDDrive", "LEDDrive_FW",},
5250 {sig_match_named, "LockMainPower", "LockMainPower_FW",},
5251 {sig_match_named, "MoveFocusLensToDistance", "MoveFocusLensToDistance_FW",},
5252 {sig_match_named, "MoveIrisWithAv", "MoveIrisWithAv_FW",},
5253 {sig_match_named, "MoveZoomLensWithPoint", "MoveZoomLensWithPoint_FW",},
5254 {sig_match_named, "Open", "Open_FW",},
5255 {sig_match_named, "Open_low", "Open", SIG_NAMED_NTH(3,SUB),SIG_DRY_MIN(58)},
5256 {sig_match_named, "PostLogicalEventForNotPowerType", "PostLogicalEventForNotPowerType_FW",},
5257 {sig_match_named, "PostLogicalEventToUI", "PostLogicalEventToUI_FW",},
5258 {sig_match_named, "PT_MFOn", "SS.MFOn_FW", SIG_NAMED_JMP_SUB},
5259 {sig_match_named, "PT_MFOff", "SS.MFOff_FW", SIG_NAMED_JMP_SUB},
5260 {sig_match_named, "PT_MoveDigitalZoomToWide", "SS.MoveDigitalZoomToWide_FW", SIG_NAMED_JMP_SUB},
5261 {sig_match_named, "PT_MoveOpticalZoomAt", "SS.MoveOpticalZoomAt_FW",},
5262 {sig_match_named, "PutInNdFilter", "PutInNdFilter_FW",},
5263 {sig_match_named, "PutOutNdFilter", "PutOutNdFilter_FW",},
5264 {sig_match_named, "SetAE_ShutterSpeed", "SetAE_ShutterSpeed_FW",},
5265 {sig_match_named, "SetAutoShutdownTime", "SetAutoShutdownTime_FW",},
5266 {sig_match_named, "SetCurrentCaptureModeType","SetCurrentCaptureModeType_FW",},
5267 {sig_match_named, "SetDate", "SetDate_FW",},
5268 {sig_match_named, "SetLogicalEventActive", "UiEvnt_SetLogicalEventActive_FW",},
5269 {sig_match_named, "SetScriptMode", "SetScriptMode_FW",},
5270 {sig_match_named, "SleepTask", "SleepTask_FW",},
5271 {sig_match_named, "SetPropertyCase", "SetPropertyCase_FW", SIG_NAMED_SUB},
5272 {sig_match_named, "TakeSemaphore", "TakeSemaphore_FW",},
5273 {sig_match_named, "TurnOnDisplay", "DispCon_TurnOnDisplay_FW",SIG_NAMED_SUB},
5274 {sig_match_named, "TurnOffDisplay", "DispCon_TurnOffDisplay_FW",SIG_NAMED_SUB},
5275 {sig_match_named, "TurnOnBackLight", "DispCon_TurnOnBackLight_FW",SIG_NAMED_SUB, SIG_DRY_MAX(57)},
5276 {sig_match_named, "TurnOffBackLight", "DispCon_TurnOffBackLight_FW",SIG_NAMED_SUB,SIG_DRY_MAX(57)},
5277 {sig_match_named, "UIFS_WriteFirmInfoToFile", "UIFS_WriteFirmInfoToFile_FW",},
5278 {sig_match_named, "UnlockAE", "SS.UnlockAE_FW", SIG_NAMED_JMP_SUB},
5279 {sig_match_named, "UnlockAF", "SS.UnlockAF_FW", SIG_NAMED_JMP_SUB},
5280 {sig_match_named, "UnlockMainPower", "UnlockMainPower_FW",},
5281 {sig_match_named, "UnRegisterEventProcedure", "UnRegisterEventProcTable", SIG_NAMED_SUB},
5282
5283 {sig_match_named, "VbattGet", "VbattGet_FW",},
5284 {sig_match_named, "Write", "Write_FW",},
5285 {sig_match_named, "bzero", "exec_FW", SIG_NAMED_SUB},
5286 {sig_match_named, "exmem_free", "ExMem.FreeCacheable_FW",SIG_NAMED_JMP_SUB, SIG_DRY_MAX(58)},
5287 {sig_match_named, "exmem_alloc", "ExMem.AllocCacheable_FW",SIG_NAMED_JMP_SUB,SIG_DRY_MAX(58)},
5288 {sig_match_named, "exmem_ufree", "ExMem.FreeUncacheable_FW",SIG_NAMED_JMP_SUB, SIG_DRY_MAX(58)},
5289 {sig_match_named, "exmem_ualloc", "ExMem.AllocUncacheable_FW",SIG_NAMED_JMP_SUB,SIG_DRY_MAX(58)},
5290 {sig_match_named, "free", "FreeMemory_FW", SIG_NAMED_JMP_SUB},
5291 {sig_match_named, "heap_free", "free", SIG_NAMED_NTH(2,SUB)},
5292 {sig_match_named, "lseek", "Lseek_FW",},
5293 {sig_match_named, "_log10", "CalcLog10", SIG_NAMED_NTH(2,SUB)},
5294 {sig_match_named, "malloc", "AllocateMemory_FW", SIG_NAMED_JMP_SUB},
5295 {sig_match_named, "heap_alloc", "malloc", SIG_NAMED_NTH(2,SUB)},
5296 {sig_match_named, "memcmp", "memcmp_FW",},
5297 {sig_match_named, "memcpy", "memcpy_FW",},
5298 {sig_match_named, "memset", "memset_FW",},
5299 {sig_match_named, "strcmp", "strcmp_FW",},
5300 {sig_match_named, "strcpy", "strcpy_FW",},
5301 {sig_match_named, "strlen", "strlen_FW",},
5302 {sig_match_named, "task_CaptSeq", "task_CaptSeqTask",},
5303 {sig_match_named, "task_ExpDrv", "task_ExpDrvTask",},
5304 {sig_match_named, "task_FileWrite", "task_FileWriteTask",},
5305
5306
5307 {sig_match_named, "vsprintf", "sprintf_FW", SIG_NAMED_SUB},
5308 {sig_match_named, "PTM_GetCurrentItem", "PTM_GetCurrentItem_FW",},
5309 {sig_match_named, "DisableISDriveError", "DisableISDriveError_FW",},
5310 {sig_match_named, "hook_CreateTask", "CreateTask", SIG_NAMED_CLEARTHUMB},
5311
5312 {sig_match_named, "hook_CreateTask_low", "CreateTask_low", SIG_NAMED_CLEARTHUMB},
5313 {sig_match_named, "malloc_strictly", "task_EvShel", SIG_NAMED_NTH(2,SUB)},
5314 {sig_match_named, "DebugAssert2", "malloc_strictly", SIG_NAMED_NTH(3,SUB)},
5315
5316
5317 {sig_match_named, "AcquireRecursiveLockStrictly","PTM_AllReset_FW", SIG_NAMED_SUB},
5318 {sig_match_named, "CheckAllEventFlag", "ChargeStrobeForFA_FW", SIG_NAMED_SUB},
5319 {sig_match_named, "ClearEventFlag", "GetAEIntegralValueWithFix_FW",SIG_NAMED_SUB},
5320 {sig_match_named, "CheckAnyEventFlag", "task_SynchTask", SIG_NAMED_NTH(2,SUB)},
5321 {sig_match_named, "taskcreate_LowConsole", "task_EvShel", SIG_NAMED_SUB},
5322 {sig_match_named, "CreateMessageQueueStrictly","taskcreate_LowConsole",SIG_NAMED_SUB},
5323 {sig_match_named, "CreateBinarySemaphoreStrictly","taskcreate_LowConsole",SIG_NAMED_NTH(2,SUB)},
5324 {sig_match_named, "PostMessageQueue", "GetCh_FW", SIG_NAMED_NTH(2,SUB)},
5325 {sig_match_named, "CreateEventFlagStrictly", "InitializeDigicon_FW", SIG_NAMED_SUB},
5326 {sig_match_named, "WaitForAnyEventFlag", "task_DPOFTask", SIG_NAMED_SUB},
5327 {sig_match_named, "GetEventFlagValue", "task_DPOFTask", SIG_NAMED_NTH(2,SUB)},
5328 {sig_match_named, "CreateBinarySemaphore", "task_UartLog", SIG_NAMED_SUB},
5329 {sig_match_named, "PostMessageQueueStrictly", "EF.IsChargeFull_FW", SIG_NAMED_SUB},
5330 {sig_match_named, "SetEventFlag", "StopStrobeChargeForFA_FW",SIG_NAMED_SUB},
5331 {sig_match_named, "TryReceiveMessageQueue", "task_DvlpSeqTask", SIG_NAMED_NTH(3,SUB)},
5332
5333 {sig_match_named, "TakeSemaphore", "task_Bye", SIG_NAMED_SUB},
5334 {sig_match_named_last,"GiveSemaphore", "TurnOnVideoOutMode_FW",SIG_NAMED_LAST_RANGE(10,24)},
5335
5336 {sig_match_named, "givesemaphore_low", "GiveSemaphore", SIG_NAMED_SUB, SIG_DRY_MAX(52)},
5337 {sig_match_named, "givesemaphore_low", "GiveSemaphore", SIG_NAMED_NTH(2,SUB),SIG_DRY_MIN(53)},
5338
5339
5340 {sig_match_named, "ReleaseRecursiveLock", "StartWDT_FW", SIG_NAMED_NTH(2,SUB)},
5341 {sig_match_named, "MoveOpticalZoomAt", "SS.MoveOpticalZoomAt_FW",SIG_NAMED_SUB},
5342 {sig_match_named, "SetVideoOutType", "SetVideoOutType_FW", SIG_NAMED_SUB},
5343 {sig_match_named, "GetVideoOutType", "GetVideoOutType_FW"},
5344 {sig_match_named, "is_movie_recording", "UIFS_StopMovieRecord_FW",SIG_NAMED_SUB},
5345 {sig_match_named, "dry_con_printf", "ShowCameraLogInfo_FW", SIG_NAMED_SUB},
5346 {sig_match_named, "ui_malloc", "CreateController_FW", SIG_NAMED_SUB},
5347 {sig_match_ui_mem_func_ptr,"ui_malloc_ptr", "ui_malloc", },
5348 {sig_match_func_ptr_val, "ui_malloc_default", "ui_malloc_ptr", },
5349 {sig_match_named, "pvm_malloc", "ui_malloc_default", SIG_NAMED_NTH(2,SUB)},
5350 {sig_match_named, "pvm_get_largest_free_block_size_ptr","ui_malloc_default",SIG_NAMED_NTH(3,SUB)},
5351 {sig_match_named, "pvm_get_largest_free_block_size","pvm_get_largest_free_block_size_ptr",SIG_NAMED_SUB},
5352 {sig_match_named, "ui_free", "CreateController_FW", SIG_NAMED_NTH(3,SUB)},
5353 {sig_match_ui_mem_func_ptr,"ui_free_ptr", "ui_free",},
5354 {sig_match_func_ptr_val, "ui_free_default", "ui_free_ptr", },
5355 {sig_match_named_last,"pvm_free", "ui_free_default", SIG_NAMED_LAST_RANGE(11,16)},
5356 {sig_match_near_str,"pvm_init_pool", "\n%ld-byte from heap\n",SIG_NEAR_BEFORE(14,3)},
5357
5358 {sig_match_near_str,"cameracon_set_state", "AC:ChkCom2PB", SIG_NEAR_BEFORE(4,1),},
5359 {sig_match_near_str,"cameracon_get_state", "DlvrUSBCnct", SIG_NEAR_AFTER(5,2)},
5360 {sig_match_near_str,"IsWirelessConnect", "WiFiDisconnect", SIG_NEAR_BEFORE(6,1),SIG_DRY_MAX(52)},
5361 {sig_match_near_str,"IsWirelessConnect", "USBDisconnect", SIG_NEAR_BEFORE(6,1),SIG_DRY_MIN(54)},
5362 {sig_match_var_struct_get,"cameracon_state", "cameracon_get_state",},
5363 {sig_match_str_arg_call,"strstr", "AUTPLAY", SIG_STRCALL_ARG(1)},
5364 {sig_match_named_last,"strchr", "strstr", SIG_NAMED_LAST_RANGE(14,22)},
5365 {sig_match_near_str,"init_task_error", "USER_MEM size checking",SIG_NEAR_AFTER(3,1)},
5366 {sig_match_named_last,"dry_panic", "init_task_error", SIG_NAMED_LAST_RANGE(4,12)},
5367 {sig_match_named, "dry_panic_low", "dry_panic", SIG_NAMED_NTH(3,SUB),SIG_DRY_ANY, SIG_NO_D6},
5368
5369 {sig_match_near_str,"data_synchronization_barrier","ER DlphCntInv", SIG_NEAR_AFTER(3,2),SIG_DRY_MAXP(58,8), SIG_NO_D7},
5370
5371 {sig_match_near_str,"bzero", "Canon Degital Camera",SIG_NEAR_AFTER(8,2)|SIG_NEAR_INDIRECT},
5372
5373
5374 {sig_match_named, "GetCurrentDriveBaseSvValue","GetCurrentDriveBaseSvValue_FW",SIG_NAMED_NTH(1,SUB)},
5375 {sig_match_near_str,"GetCurrentDriveBaseSvValue","IsExecutePreConti", SIG_NEAR_AFTER(7,2)},
5376 {sig_match_named, "memset32", "bzero", SIG_NAMED_NTH(1,INSN)},
5377 {sig_match_dry_memset,"dry_memset", "ClearDefectTurnTable_FW",0, SIG_DRY_MIN(53)},
5378 {sig_match_near_str,"dry_memset", "[xWiSE] generateRandom Err.\n",SIG_NEAR_BEFORE(8,2),SIG_DRY_MAX(52)},
5379 {sig_match_dry_memzero,"dry_memzero", "SetDefaultRecParameter_FW"},
5380 {sig_match_dry_memcpy_bytes,"dry_memcpy_bytes", "SaveDefectAdjTable_FW",},
5381 {sig_match_near_str,"dry_memmove_bytes", "NoOperation BulkOut!Remain.Length = %lu",SIG_NEAR_AFTER(18,3)},
5382 {sig_match_misc_flag_named,"CAM_IS_ILC", "task_EFLensComTask",},
5383 {sig_match_misc_flag_named,"CAM_HAS_ND_FILTER", "task_Nd",},
5384 {sig_match_misc_flag_named,"CAM_HAS_WIFI", "task_ComWireless",},
5385 {sig_match_cam_has_iris_diaphragm,"CAM_HAS_IRIS_DIAPHRAGM","task_IrisEvent",},
5386 {sig_match_near_str,"ImagerActivate", "Fail ImagerActivate(ErrorCode:%x)\r",SIG_NEAR_BEFORE(6,1)},
5387 {sig_match_screenlock_helper,"screenlock_helper","UIFS_DisplayFirmUpdateView_FW"},
5388 {sig_match_named, "ScreenLock", "screenlock_helper",SIG_NAMED_SUB},
5389 {sig_match_fclose_low,"fclose_low", "Fclose_Fut"},
5390 {sig_match_named, "fut_flush", "fclose_low", SIG_NAMED_NTH(1,SUB)},
5391
5392 {sig_match_screenunlock,"ScreenUnlock", "screenlock_helper", 0,SIG_DRY_MAX(55)},
5393 {sig_match_near_str,"ScreenUnlock", "PB._ErrorRef", SIG_NEAR_AFTER(8,2)|SIG_NEAR_JMP_SUB,SIG_DRY_RANGE(57,58)},
5394 {sig_match_near_str,"ScreenUnlock", "PB._ErrorRef:SI", SIG_NEAR_AFTER(8,2)|SIG_NEAR_JMP_SUB,SIG_DRY_MIN(59)},
5395 {sig_match_log_camera_event,"LogCameraEvent", "task_StartupImage",},
5396 {sig_match_physw_misc, "physw_misc", "task_PhySw"},
5397 {sig_match_kbd_read_keys, "kbd_read_keys", "kbd_p1_f"},
5398 {sig_match_get_kbd_state, "GetKbdState", "kbd_read_keys"},
5399 {sig_match_create_jumptable, "CreateJumptable", "InitializeAdjustmentSystem_FW"},
5400
5401 {sig_match_take_semaphore_strict, "TakeSemaphoreStrictly","Fopen_Fut"},
5402 {sig_match_near_str,"dry_error_printf", "\nSystem Panic: Module = %d, Panic = %d\n",SIG_NEAR_AFTER(2,1)},
5403
5404 {sig_match_get_semaphore_value,"GetSemaphoreValue","\tRaw[%i]", 0, SIG_DRY_MAXP(58,8)},
5405 {sig_match_get_semaphore_value,"GetSemaphoreValue","BlankRaw(%d)", 0, SIG_DRY_MINP(58,9)},
5406 {sig_match_stat, "stat", "A/uartr.req"},
5407 {sig_match_open, "open", "Open_FW", 0, SIG_DRY_MAX(57)},
5408 {sig_match_open, "open", "Open_low", 0, SIG_DRY_MIN(58)},
5409 {sig_match_named, "get_self_task_errno_pointer","open", SIG_NAMED_NTH(2,SUB)},
5410 {sig_match_named, "get_self_task_id", "get_self_task_errno_pointer",SIG_NAMED_SUB},
5411 {sig_match_umalloc, "AllocateUncacheableMemory","Fopen_Fut_FW"},
5412 {sig_match_named, "dcache_flush_range", "AllocateUncacheableMemory",SIG_NAMED_NTH(2,SUB)},
5413 {sig_match_ufree, "FreeUncacheableMemory", "Fclose_Fut_FW"},
5414 {sig_match_cam_uncached_bit,"CAM_UNCACHED_BIT", "FreeUncacheableMemory"},
5415 {sig_match_umalloc_strictly,"umalloc_strictly", "DPOFTask"},
5416 {sig_match_dcache_clean_flush_and_disable,"dcache_clean_flush_and_disable", "MemoryChecker_FW"},
5417 {sig_match_get_rom_id,"GetRomID", "GetRomID_FW",},
5418 {sig_match_dcache_flush_and_enable,"dcache_flush_and_enable", "GetRomID",0, SIG_DRY_ANY, SIG_NO_D7},
5419 {sig_match_deletefile_fut,"DeleteFile_Fut", "Get Err TempPath"},
5420 {sig_match_near_str,"createsemaphore_low", "termLock", SIG_NEAR_AFTER(3,1)},
5421
5422
5423 {sig_match_named,"takesemaphore_low", "malloc", SIG_NAMED_SUB},
5424
5425 {sig_match_near_str,"AcquireRecursiveLock", "not executed\n",SIG_NEAR_BEFORE(20,3),SIG_DRY_ANY, SIG_NO_D7},
5426 {sig_match_near_str,"AcquireRecursiveLock", "COCOA: ERR: QIF AcquireRecursiveLock QifPushmqif failure!!",SIG_NEAR_BEFORE(10,1),SIG_DRY_ANY, SIG_NO_D6},
5427 {sig_match_near_str,"CreateCountingSemaphoreStrictly","DvlpSeqTask", SIG_NEAR_BEFORE(18,3)},
5428 {sig_match_near_str,"CreateMessageQueue", "CreateMessageQueue:%ld",SIG_NEAR_BEFORE(7,1)},
5429 {sig_match_near_str,"CreateEventFlag", "CreateEventFlag:%ld", SIG_NEAR_BEFORE(7,1),SIG_DRY_MAX(57)},
5430 {sig_match_near_str,"CreateEventFlag", "CreateEventFlag:%ld", SIG_NEAR_BEFORE(9,1),SIG_DRY_MIN(58)},
5431 {sig_match_near_str,"CreateRecursiveLock", "WdtInt", SIG_NEAR_BEFORE(9,1)},
5432 {sig_match_near_str,"CreateRecursiveLockStrictly","LoadedScript", SIG_NEAR_AFTER(6,2)},
5433 {sig_match_near_str,"DeleteMessageQueue", "DeleteMessageQueue(%d) is FAILURE",SIG_NEAR_BEFORE(10,1)},
5434 {sig_match_near_str,"DeleteEventFlag", "DeleteEventFlag(%d) is FAILURE",SIG_NEAR_BEFORE(10,1)},
5435 {sig_match_near_str,"ReceiveMessageQueue", "ReceiveMessageQue:%d", SIG_NEAR_BEFORE(9,1)},
5436 {sig_match_near_str,"RegisterInterruptHandler", "WdtInt", SIG_NEAR_AFTER(3,1)},
5437 {sig_match_near_str,"TryPostMessageQueue", "TryPostMessageQueue(%d)\n",SIG_NEAR_BEFORE(9,1),SIG_DRY_MAX(52)},
5438
5439 {sig_match_near_str,"TryPostMessageQueue", "[CWS]TryPostMessageQueue(%d) Failed\n",SIG_NEAR_BEFORE(9,1)},
5440 {sig_match_near_str,"TryTakeSemaphore", "FileScheduleTask", SIG_NEAR_AFTER(10,2),SIG_DRY_MAX(57)},
5441 {sig_match_try_take_sem_dry_gt_57,"TryTakeSemaphore","task_ImageStoreTask",0,SIG_DRY_MIN(58)},
5442
5443 {sig_match_named, "takesemaphore_low", "TryTakeSemaphore", SIG_NAMED_SUB},
5444 {sig_match_near_str,"WaitForAllEventFlag", "Error WaitEvent PREPARE_TESTREC_EXECUTED.", SIG_NEAR_BEFORE(5,1)},
5445 {sig_match_near_str,"WaitForAnyEventFlagStrictly","_imageSensorTask", SIG_NEAR_AFTER(10,2)},
5446 {sig_match_wait_all_eventflag_strict,"WaitForAllEventFlagStrictly","EF.StartInternalMainFlash_FW"},
5447 {sig_match_near_str,"DeleteSemaphore", "DeleteSemaphore passed",SIG_NEAR_BEFORE(3,1)},
5448 {sig_match_get_num_posted_messages,"GetNumberOfPostedMessages","task_CtgTotalTask"},
5449 {sig_match_near_str,"LocalTime", "%Y-%m-%dT%H:%M:%S", SIG_NEAR_BEFORE(5,1),SIG_DRY_MAX(58)},
5450 {sig_match_near_str,"LocalTime", "%Y.%m.%d %H:%M:%S", SIG_NEAR_BEFORE(5,1)},
5451 {sig_match_near_str,"strftime", "%Y/%m/%d %H:%M:%S", SIG_NEAR_AFTER(3,1)},
5452 {sig_match_near_str,"OpenFastDir", "OpenFastDir_ERROR\n", SIG_NEAR_BEFORE(5,1)},
5453 {sig_match_readfastdir,"ReadFastDir", "ReadFast_ERROR\n", SIG_NEAR_BEFORE(24,1)},
5454 {sig_match_near_str,"PT_PlaySound", "BufAccBeep", SIG_NEAR_AFTER(7,2)|SIG_NEAR_JMP_SUB,SIG_DRY_MAX(58)},
5455
5456 {sig_match_near_str,"PT_PlaySound", "PB._PMenuCBR", SIG_NEAR_BEFORE(7,3),SIG_DRY_MIN(59)},
5457 {sig_match_closedir,"closedir", "ReadFast_ERROR\n", SIG_NEAR_AFTER(1,1)},
5458 {sig_match_strrchr,"strrchr", "ReadFast_ERROR\n", SIG_NEAR_AFTER(9,2)},
5459 {sig_match_strrchr,"strrchr", "ReadFast_ERROR\n", SIG_NEAR_BEFORE(18,4)},
5460 {sig_match_time, "time", "<UseAreaSize> DataWidth : %d , DataHeight : %d\r\n",},
5461 {sig_match_near_str,"strcat", "String can't be displayed; no more space in buffer",SIG_NEAR_AFTER(5,2),SIG_DRY_MAX(52)},
5462 {sig_match_near_str,"strcat", "/api/getimagelist", SIG_NEAR_AFTER(4,1),SIG_DRY_MIN(53)},
5463
5464 {sig_match_strncpy, "strncpy", "UnRegisterEventProcedure",},
5465 {sig_match_strncmp, "strncmp", "EXFAT ",},
5466 {sig_match_strtolx, "strtolx", "CheckSumAll_FW",},
5467 {sig_match_near_str,"strtol", "prio <task ID> <priority>\n",SIG_NEAR_AFTER(7,1)},
5468 {sig_match_exec_evp,"ExecuteEventProcedure", "Can not Execute "},
5469 {sig_match_fgets_fut,"Fgets_Fut", "CheckSumAll_FW",},
5470 {sig_match_named, "fgets_low", "Fgets_Fut", SIG_NAMED_NTH(2,SUB)},
5471 {sig_match_log, "_log", "_log10",},
5472 {sig_match_pow_dry_52,"_pow", "GetDefectTvAdj_FW", 0, SIG_DRY_MAX(52)},
5473 {sig_match_pow_dry_gt_52,"_pow", "GetDefectTvAdj_FW", 0, SIG_DRY_RANGEP(53,0,59,3)},
5474 {sig_match_sqrt, "_sqrt", "CalcSqrt",},
5475 {sig_match_named, "get_fstype", "OpenFastDir", SIG_NAMED_NTH(2,SUB)},
5476 {sig_match_near_str,"GetMemInfo", " -- refusing to print malloc information.\n",SIG_NEAR_AFTER(7,2)},
5477 {sig_match_get_drive_cluster_size,"GetDrive_ClusterSize","OpLog.WriteToSD_FW",},
5478 {sig_match_mktime_ext,"mktime_ext", "%04d%02d%02dT%02d%02d%02d.%01d",},
5479 {sig_match_near_str,"PB2Rec", "AC:ActionP2R Fail", SIG_NEAR_BEFORE(6,1)},
5480 {sig_match_rec2pb, "Rec2PB", "_EnrySRec",},
5481
5482 {sig_match_get_parameter_data,"GetParameterData","PTM_RestoreUIProperty_FW",},
5483 {sig_match_prepdir_1,"PrepareDirectory_1", "<OpenFileWithDir> PrepareDirectory NG\r\n",SIG_NEAR_BEFORE(7,1)},
5484 {sig_match_prepdir_x,"PrepareDirectory_x", "PrepareDirectory_1",},
5485 {sig_match_prepdir_0,"PrepareDirectory_0", "PrepareDirectory_1",},
5486 {sig_match_mkdir, "MakeDirectory_Fut", "PrepareDirectory_x",},
5487
5488
5489 {sig_match_qsort, "qsort", "task_MetaCtg",},
5490 {sig_match_deletedirectory_fut,"DeleteDirectory_Fut","RedEyeController.c",},
5491 {sig_match_set_control_event,"set_control_event","LogicalEvent:0x%04x:adr:%p,Para:%ld",},
5492
5493 {sig_match_set_control_event,"set_control_event","LogicalEvent:0x%08x:adr:%p,Para:%ld",},
5494 {sig_match_displaybusyonscreen_52,"displaybusyonscreen","_PBBusyScrn", 0, SIG_DRY_MAX(52)},
5495 {sig_match_undisplaybusyonscreen_52,"undisplaybusyonscreen","_PBBusyScrn",0, SIG_DRY_MAX(52)},
5496 {sig_match_near_str,"srand", "Canon Degital Camera",SIG_NEAR_AFTER(14,4)|SIG_NEAR_INDIRECT},
5497 {sig_match_near_str,"rand", "Canon Degital Camera",SIG_NEAR_AFTER(15,5)|SIG_NEAR_INDIRECT},
5498 {sig_match_set_hp_timer_after_now,"SetHPTimerAfterNow","MechaNC.c",},
5499 {sig_match_levent_table,"levent_table", "ShowLogicalEventName_FW",},
5500 {sig_match_flash_param_table,"FlashParamsTable","GetParameterData",},
5501 {sig_match_named, "get_playrec_mode", "task_SsStartupTask", SIG_NAMED_SUB},
5502 {sig_match_var_struct_get,"playrec_mode", "get_playrec_mode",},
5503 {sig_match_jpeg_count_str,"jpeg_count_str", "9999",},
5504 {sig_match_physw_event_table,"physw_event_table","kbd_read_keys_r2",},
5505 {sig_match_uiprop_count,"uiprop_count", "PTM_SetCurrentItem_FW",},
5506 {sig_match_get_canon_mode_list,"get_canon_mode_list","AC:PTM_Init",},
5507 {sig_match_rom_ptr_get,"canon_mode_list", "get_canon_mode_list",},
5508 {sig_match_zoom_busy,"zoom_busy", "ResetZoomLens_FW",},
5509 {sig_match_focus_busy,"focus_busy", "MoveFocusLensToTerminate_FW",},
5510 {sig_match_aram_size,"ARAM_HEAP_SIZE", "AdditionAgentRAM_FW", 0, SIG_DRY_MAX(58)},
5511 {sig_match_aram_size_gt58,"ARAM_HEAP_SIZE", "AdditionAgentRAM_FW", 0, SIG_DRY_MIN(59)},
5512 {sig_match_aram_start,"ARAM_HEAP_START", "AdditionAgentRAM_FW",},
5513 {sig_match_aram_start2,"ARAM_HEAP_START", "AdditionAgentRAM_FW",},
5514 {sig_match_icache_flush_range,"icache_flush_range","AdditionAgentRAM_FW",},
5515 {sig_match__nrflag,"_nrflag", "NRTBL.SetDarkSubType_FW",},
5516 {sig_match_near_str,"transfer_src_overlay_helper","Window_EmergencyRefreshPhysicalScreen",SIG_NEAR_BEFORE(6,1)},
5517 {sig_match_transfer_src_overlay,"transfer_src_overlay","transfer_src_overlay_helper",},
5518 {sig_match_named,"GraphicSystemCoreFinish_helper","transfer_src_overlay",SIG_NAMED_NTH(3,SUB),SIG_DRY_MAX(52)},
5519 {sig_match_named,"GraphicSystemCoreFinish_helper","transfer_src_overlay",SIG_NAMED_NTH(4,SUB),SIG_DRY_RANGE(53,57)},
5520 {sig_match_named,"GraphicSystemCoreFinish_helper","transfer_src_overlay",SIG_NAMED_NTH(5,SUB),SIG_DRY_MIN(58)},
5521
5522
5523 {sig_match_named,"GraphicSystemCoreFinish","GraphicSystemCoreFinish_helper",SIG_NAMED_SUB},
5524 {sig_match_named,"mzrm_createmsg","GraphicSystemCoreFinish",SIG_NAMED_SUB},
5525 {sig_match_named_last,"mzrm_sendmsg","GraphicSystemCoreFinish",SIG_NAMED_LAST_RANGE(10,16)},
5526 {sig_match_zicokick_52,"zicokick_start", "ZicoKick Start\n",0,SIG_DRY_MAX(52)},
5527 {sig_match_zicokick_gt52,"zicokick_start", "ZicoKick Start\n",0,SIG_DRY_MIN(53)},
5528 {sig_match_zicokick_copy,"zicokick_copy", "zicokick_start"},
5529 {sig_match_zicokick_values,"zicokick_values", "zicokick_start"},
5530 {sig_match_named_last,"dcache_clean_range", "zicokick_start", SIG_NAMED_LAST_RANGE(40,58)},
5531 {sig_match_init_ex_drivers,"init_ex_drivers", "task_Startup"},
5532 {sig_match_omar_init,"omar_init", "init_ex_drivers", 0, SIG_DRY_ANY, SIG_NO_D7},
5533 {sig_match_init_error_handlers,"init_error_handlers","task_Startup"},
5534 {sig_match_named, "set_assert_handler", "init_error_handlers", SIG_NAMED_NTH(2,SUB)},
5535 {sig_match_named, "set_exception_handler", "init_error_handlers", SIG_NAMED_NTH(3,SUB)},
5536 {sig_match_named, "set_panic_handler", "init_error_handlers", SIG_NAMED_NTH(4,JMP_SUB)},
5537 {sig_match_default_assert_handler,"default_assert_handler","init_error_handlers"},
5538 {sig_match_default_exception_handler,"default_exception_handler","init_error_handlers"},
5539 {sig_match_default_panic_handler,"default_panic_handler","init_error_handlers"},
5540 {sig_match_get_task_properties,"get_task_properties","default_assert_handler"},
5541 {sig_match_enable_hdmi_power,"EnableHDMIPower", "HecHdmiCecPhysicalCheckForScript_FW"},
5542 {sig_match_disable_hdmi_power,"DisableHDMIPower","HecHdmiCecPhysicalCheckForScript_FW"},
5543 {sig_match_get_nd_value,"get_nd_value", "PutInNdFilter",},
5544 {sig_match_get_current_exp,"get_current_exp","ShowCurrentExp_FW",},
5545 {sig_match_get_current_nd_value,"get_current_nd_value","get_current_exp",},
5546 {sig_match_get_current_deltasv,"get_current_deltasv","get_current_exp",},
5547 {sig_match_imager_active_callback,"imager_active_callback","ImagerActivate",},
5548 {sig_match_imager_active,"imager_active","imager_active_callback",},
5549 {sig_match_get_dial_hw_position,"get_dial_hw_position","kbd_p1_f",},
5550 {sig_match_near_str,"get_displaytype","DisplayType : %d\r\n",SIG_NEAR_BEFORE(5,1)},
5551 {sig_match_prop_string,"PROPCASE_AFSTEP", "\n\rError : GetAFStepResult",SIG_NEAR_BEFORE(7,1)},
5552 {sig_match_prop_string,"PROPCASE_FOCUS_STATE", "\n\rError : GetAFResult",SIG_NEAR_BEFORE(7,1)},
5553 {sig_match_prop_string,"PROPCASE_AV", "\n\rError : GetAvResult",SIG_NEAR_BEFORE(7,1)},
5554 {sig_match_prop_string,"PROPCASE_BV", "\n\rError : GetBvResult",SIG_NEAR_BEFORE(7,1)},
5555 {sig_match_prop_string,"PROPCASE_DELTA_DIGITALGAIN", "\n\rError : GetDeltaDigitalResult",SIG_NEAR_BEFORE(7,1)},
5556 {sig_match_prop_string,"PROPCASE_DELTA_SV", "\n\rError : GetDeltaGainResult",SIG_NEAR_BEFORE(7,1)},
5557 {sig_match_prop_string,"PROPCASE_DELTA_ND", "\n\rError : GetDeltaNdResult",SIG_NEAR_BEFORE(7,1)},
5558 {sig_match_prop_string,"PROPCASE_EV_CORRECTION_2", "\n\rError : GetRealExposureCompensationResult",SIG_NEAR_BEFORE(7,1)},
5559 {sig_match_prop_string,"PROPCASE_ORIENTATION_SENSOR", "\n\rError : GetRotationAngleResult",SIG_NEAR_BEFORE(7,1)},
5560 {sig_match_prop_string,"PROPCASE_SV_MARKET", "\n\rError : GetSvResult",SIG_NEAR_BEFORE(7,1)},
5561 {sig_match_prop_string,"PROPCASE_SVFIX", "\n\rError : GetSvFixResult",SIG_NEAR_BEFORE(7,1)},
5562 {sig_match_prop_string,"PROPCASE_TV", "\n\rError : GetTvResult",SIG_NEAR_BEFORE(7,1)},
5563 {sig_match_prop_string,"PROPCASE_HSCAPTURE", "GetPropertyFromCase Error [HSCapture]",SIG_NEAR_BEFORE(7,1)},
5564 {sig_match_prop_string,"PROPCASE_FLASH_FIRE", "FlashDecision",SIG_NEAR_BEFORE(7,1)},
5565 {sig_match_prop_string,"PROPCASE_FELOCK", "GetPropertyFromCurrentCase Error [FELock]",SIG_NEAR_BEFORE(7,1)},
5566 {sig_match_prop_string,"PROPCASE_FLASH_ADJUST_MODE", "GetPropertyFromCurrentCase Error [FlashAdjust]",SIG_NEAR_BEFORE(7,1)},
5567 {sig_match_exmem_vars,"exmem_types_table", "ExMem.View_FW"},
5568 {sig_match_av_over_sem,"av_override_semaphore", "MoveIrisWithAv_FW"},
5569 {sig_match_canon_menu_active,"canon_menu_active", "StartRecModeMenu_FW"},
5570 {sig_match_file_counter_init,"file_counter_var_init","task_InitFileModules",},
5571 {sig_match_file_counter_var,"file_counter_var","file_counter_var_init",},
5572 {sig_match_var_struct_get,"displaytype", "get_displaytype",},
5573 {sig_match_palette_vars,"palette_control", "transfer_src_overlay_helper",0, SIG_DRY_MAX(58)},
5574 {sig_match_live_free_cluster_count,"live_free_cluster_count","Close",0, SIG_DRY_MAX(57)},
5575 {sig_match_live_free_cluster_count,"live_free_cluster_count","Close_low",0, SIG_DRY_MIN(58)},
5576 {NULL},
5577 };
5578
5579 int sig_rule_applies(firmware *fw, sig_rule_t *rule)
5580 {
5581
5582 if((rule->dryos_min && fw->dryos_ver_full < rule->dryos_min) || (rule->dryos_max && fw->dryos_ver_full > rule->dryos_max)) {
5583 return 0;
5584 }
5585
5586 if(!rule->flags) {
5587 return 1;
5588 }
5589
5590 if((rule->flags & SIG_NO_D7) && (fw->arch_flags & FW_ARCH_FL_VMSA)) {
5591 return 0;
5592 }
5593
5594 if((rule->flags & SIG_NO_D6) && !(fw->arch_flags & FW_ARCH_FL_VMSA)) {
5595 return 0;
5596 }
5597 return 1;
5598 }
5599
5600 void run_sig_rules(firmware *fw, sig_rule_t *sig_rules)
5601 {
5602 sig_rule_t *rule=sig_rules;
5603
5604 iter_state_t *is=disasm_iter_new(fw,0);
5605 while(rule->match_fn) {
5606 if(!sig_rule_applies(fw,rule)) {
5607 rule++;
5608 continue;
5609 }
5610
5611
5612 rule->match_fn(fw,is,rule);
5613
5614 rule++;
5615 }
5616 disasm_iter_free(is);
5617 }
5618
5619 void add_event_proc(firmware *fw, char *name, uint32_t adr)
5620 {
5621
5622 if(!ADR_IS_THUMB(adr)) {
5623 printf("add_event_proc: %s is ARM 0x%08x\n",name,adr);
5624 }
5625
5626 if(!fw_disasm_iter_single(fw,adr)) {
5627 printf("add_event_proc: %s disassembly failed at 0x%08x\n",name,adr);
5628 return;
5629 }
5630
5631
5632
5633 uint32_t b_adr=get_direct_jump_target(fw,fw->is);
5634 if(b_adr) {
5635 char *buf=malloc(strlen(name)+6);
5636 sprintf(buf,"j_%s_FW",name);
5637 add_func_name(fw,buf,adr,NULL);
5638
5639 adr=b_adr;
5640 }
5641 add_func_name(fw,name,adr,"_FW");
5642 }
5643
5644
5645 int process_reg_eventproc_call(firmware *fw, iter_state_t *is, __attribute__ ((unused))uint32_t unused) {
5646 uint32_t regs[4];
5647
5648 if((get_call_const_args(fw,is,4,regs)&3)==3) {
5649
5650 if(isASCIIstring(fw,regs[0])) {
5651 char *nm=(char *)adr2ptr(fw,regs[0]);
5652 add_event_proc(fw,nm,regs[1]);
5653
5654
5655 } else {
5656 printf("eventproc name not string at 0x%"PRIx64"\n",is->insn->address);
5657 }
5658 } else {
5659
5660
5661
5662
5663 uint64_t adr = is->insn->address;
5664 uint32_t adr_thumb = is->thumb;
5665 uint32_t tbla = 0;
5666 int ar = -1;
5667 int found = 0;
5668
5669 disasm_iter_init(fw,is,adr_hist_get(&is->ah,10));
5670
5671 while(1) {
5672 if (!disasm_iter(fw,is)) break;
5673 if (is->insn->address >= adr) break;
5674 if (is->insn->id == ARM_INS_LDR && is->insn->detail->arm.operands[1].type == ARM_OP_MEM) {
5675 uint32_t u = LDR_PC2val(fw,is->insn);
5676 if ((u<fw->base+fw->size8) && (u>adr) && (!isASCIIstring(fw,u))) {
5677 ar = is->insn->detail->arm.operands[0].reg;
5678 tbla = u;
5679 break;
5680 }
5681 }
5682 }
5683
5684 while(ar >= 0) {
5685 if (!disasm_iter(fw,is)) break;
5686 if (is->insn->address >= adr) break;
5687 if (is->insn->id == ARM_INS_ADD && is->insn->detail->arm.operands[1].reg == ar) {
5688 found = 1;
5689
5690 break;
5691 }
5692 }
5693 if (found) {
5694
5695 uint32_t *p=(uint32_t*)adr2ptr_with_data(fw,tbla);
5696 if(p) {
5697 while(*p) {
5698 uint32_t nm_adr=*p;
5699
5700 if (!nm_adr) break;
5701 if(!isASCIIstring(fw,nm_adr)) {
5702 printf("eventproc name not string tbl2 0x%08x 0x%08x\n",tbla,nm_adr);
5703 break;
5704 }
5705 char *nm=(char *)adr2ptr(fw,nm_adr);
5706 p++;
5707 uint32_t fn=*p;
5708 p++;
5709 add_event_proc(fw,nm,fn);
5710 }
5711 } else {
5712 printf("eventproc tbl2 not table 0x%08x\n",tbla);
5713 }
5714 }
5715 else {
5716 printf("failed to get export/register eventproc args at 0x%"PRIx64"\n",adr);
5717 }
5718
5719 disasm_iter_init(fw,is,adr | adr_thumb);
5720 disasm_iter(fw,is);
5721 }
5722 return 0;
5723 }
5724
5725
5726 int process_eventproc_table_call(firmware *fw, iter_state_t *is, __attribute__ ((unused))uint32_t unused) {
5727 uint32_t regs[4];
5728 int foundr0 = 0;
5729
5730 foundr0 = get_call_const_args(fw,is,4,regs) & 1;
5731 if (!foundr0) {
5732
5733 uint32_t ca = iter_state_adr(is);
5734 uint32_t sa = adr_hist_get(&is->ah,2);
5735 uint32_t ta = adr_hist_get(&is->ah,8);
5736 disasm_iter_set(fw,is,ta);
5737 int n = 0;
5738 while(++n<=(8-2))
5739 {
5740 disasm_iter(fw,is);
5741 }
5742 fw_disasm_iter_single(fw,sa);
5743 uint32_t adr1 = get_saved_sig_val("j_dry_memcpy");
5744 uint32_t adr2 = get_branch_call_insn_target(fw,fw->is);
5745 if (fw->is->insn->id == ARM_INS_BLX && adr1 == adr2) {
5746 foundr0 = get_call_const_args(fw,is,8-2,regs) & 2;
5747 if (foundr0) {
5748 regs[0] = regs[1];
5749
5750 }
5751 }
5752
5753 disasm_iter_init(fw,is,ca);
5754 disasm_iter(fw,is);
5755 }
5756 if(foundr0) {
5757
5758 uint32_t *p=(uint32_t*)adr2ptr_with_data(fw,regs[0]);
5759
5760
5761 if(p) {
5762 while(*p) {
5763 uint32_t nm_adr=*p;
5764 if(!isASCIIstring(fw,nm_adr)) {
5765 printf("eventproc name not string tbl 0x%08x 0x%08x\n",regs[0],nm_adr);
5766 break;
5767 }
5768 char *nm=(char *)adr2ptr(fw,nm_adr);
5769 p++;
5770 uint32_t fn=*p;
5771 p++;
5772
5773 add_event_proc(fw,nm,fn);
5774
5775 }
5776 } else {
5777 printf("failed to get *EventProcTable arg 0x%08x at 0x%"PRIx64"\n",regs[0],is->insn->address);
5778 }
5779 } else {
5780 printf("failed to get *EventProcTable r0 at 0x%"PRIx64"\n",is->insn->address);
5781 }
5782 return 0;
5783 }
5784
5785 int process_createtask_call(firmware *fw, iter_state_t *is, __attribute__ ((unused))uint32_t unused) {
5786
5787 uint32_t regs[4];
5788
5789 if((get_call_const_args(fw,is,10,regs)&9)==9) {
5790 if(isASCIIstring(fw,regs[0])) {
5791
5792 char *buf=malloc(64);
5793 char *nm=(char *)adr2ptr(fw,regs[0]);
5794 sprintf(buf,"task_%s",nm);
5795
5796 add_func_name(fw,buf,regs[3],NULL);
5797 } else {
5798 printf("task name name not string at 0x%"PRIx64"\n",is->insn->address);
5799 }
5800 } else {
5801 printf("failed to get CreateTask args at 0x%"PRIx64"\n",is->insn->address);
5802 }
5803 return 0;
5804 }
5805
5806 int save_ptp_handler_func(firmware *fw,uint32_t op,uint32_t handler) {
5807 if((op >= 0x9000 && op < 0x10000) || (op >= 0x1000 && op < 0x2000)) {
5808 char *buf=malloc(64);
5809 const char *nm=get_ptp_op_name(op);
5810 if(nm) {
5811 sprintf(buf,"handle_%s",nm);
5812 } else {
5813 sprintf(buf,"handle_PTP_OC_0x%04x",op);
5814 }
5815
5816 add_func_name(fw,buf,handler,NULL);
5817 } else {
5818 return 0;
5819 }
5820 return 1;
5821 }
5822 int process_add_ptp_handler_call(firmware *fw, iter_state_t *is, __attribute__ ((unused))uint32_t unused) {
5823 uint32_t regs[4];
5824
5825 if((get_call_const_args(fw,is,8,regs)&3)==3) {
5826
5827 if(!save_ptp_handler_func(fw,regs[0],regs[1])) {
5828 printf("add_ptp_handler op 0x%08x out of range 0x%"PRIx64"\n",regs[0],is->insn->address);
5829 }
5830 return 0;
5831 } else {
5832
5833 arm_reg ptr_reg = ARM_REG_INVALID;
5834 int i;
5835
5836 for(i=1; i<6; i++) {
5837 fw_disasm_iter_single(fw,adr_hist_get(&is->ah,i));
5838 cs_insn *insn=fw->is->insn;
5839 if(insn->id != ARM_INS_LDRH) {
5840 continue;
5841 }
5842 if(insn->detail->arm.operands[0].reg != ARM_REG_R0
5843 || insn->detail->arm.operands[1].mem.base == ARM_REG_PC
5844
5845 ) {
5846 continue;
5847 }
5848 ptr_reg = insn->detail->arm.operands[1].mem.base;
5849
5850 break;
5851 }
5852
5853 if(ptr_reg == ARM_REG_INVALID) {
5854 printf("failed to get add_ptp_handler args at 0x%"PRIx64"\n",is->insn->address);
5855 return 0;
5856 }
5857 uint32_t op_table=0;
5858
5859
5860 for(; i<20; i++) {
5861 fw_disasm_iter_single(fw,adr_hist_get(&is->ah,i));
5862 cs_insn *insn=fw->is->insn;
5863 if(!isLDR_PC(insn)) {
5864 continue;
5865 }
5866 if((arm_reg)insn->detail->arm.operands[0].reg != ptr_reg) {
5867 continue;
5868 }
5869
5870 uint32_t adr=LDR_PC2val(fw,insn);
5871
5872 if(fw_u32(fw,adr) == 0x1004) {
5873 op_table=adr;
5874 }
5875 break;
5876 }
5877 if(!op_table) {
5878 printf("failed to get ptp handler table adr at 0x%"PRIx64"\n",is->insn->address);
5879 return 0;
5880 }
5881
5882
5883 for(i=0; i<64; i++) {
5884 uint32_t op=fw_u32(fw,op_table+i*8);
5885 uint32_t handler=fw_u32(fw,op_table+i*8+4);
5886
5887 if(!save_ptp_handler_func(fw,op,handler)) {
5888 break;
5889 }
5890 }
5891 return 0;
5892 }
5893 }
5894
5895 int add_generic_func_match(search_calls_multi_data_t *match_fns,
5896 int *match_fn_count,
5897 int max_funcs,
5898 search_calls_multi_fn fn,
5899 uint32_t adr)
5900 {
5901 if(*match_fn_count >= max_funcs-1) {
5902 printf("add_generic_func_match: ERROR max_funcs %d reached\n",max_funcs);
5903 match_fns[max_funcs-1].adr=0;
5904 match_fns[max_funcs-1].fn=NULL;
5905 return 0;
5906 }
5907 match_fns[*match_fn_count].adr=adr;
5908 match_fns[*match_fn_count].fn=fn;
5909 (*match_fn_count)++;
5910 match_fns[*match_fn_count].adr=0;
5911 match_fns[*match_fn_count].fn=NULL;
5912 return 1;
5913 }
5914 #define MAX_GENERIC_FUNCS 16
5915 void add_generic_sig_match(search_calls_multi_data_t *match_fns,
5916 int *match_fn_count,
5917 search_calls_multi_fn fn,
5918 const char *name)
5919 {
5920 uint32_t adr=get_saved_sig_val(name);
5921 if(!adr) {
5922 printf("add_generic_sig_match: missing %s\n",name);
5923 return;
5924 }
5925 add_generic_func_match(match_fns,match_fn_count,MAX_GENERIC_FUNCS,fn,adr);
5926 char veneer[128];
5927 sprintf(veneer,"j_%s",name);
5928 adr=get_saved_sig_val(veneer);
5929 if(adr) {
5930 add_generic_func_match(match_fns,match_fn_count,MAX_GENERIC_FUNCS,fn,adr);
5931 }
5932 }
5933
5934 void find_exception_handlers(firmware *fw, iter_state_t *is)
5935 {
5936 uint32_t ex_vec = 0;
5937
5938 if (fw->arch_flags & FW_ARCH_FL_VMSA) {
5939 const insn_match_t match_mcr_vbar[]={
5940
5941 {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)}},
5942 {ARM_INS_ENDING}
5943 };
5944
5945 disasm_iter_init(fw, is, fw->base + fw->main_offs + 12 + fw->thumb_default);
5946 if(!insn_match_find_next(fw,is,4,match_mcr_vbar)) {
5947 return;
5948 }
5949
5950 disasm_iter_init(fw, is, adr_hist_get(&is->ah,1));
5951 disasm_iter(fw, is);
5952
5953 ex_vec = LDR_PC2val(fw,is->insn);
5954 if(!ex_vec || adr_get_range_type(fw,ex_vec) != ADR_RANGE_ROM) {
5955 return;
5956 }
5957 }
5958
5959
5960
5961 disasm_iter_init(fw, is, ex_vec);
5962 disasm_iter(fw, is);
5963
5964 char *names[]={
5965 "exception_handler_Reset",
5966 "exception_handler_UndefinedInstruction",
5967 "exception_handler_SupervisorCall",
5968 "exception_handler_PrefetchAbort",
5969 "exception_handler_DataAbort",
5970 "exception_handler_NotUsed",
5971 "exception_handler_IRQ",
5972 "exception_handler_FIQ",
5973 };
5974
5975 uint32_t addr=LDR_PC2val(fw,is->insn);
5976 if(!addr && is->insn->id == ARM_INS_B) {
5977 addr=get_branch_call_insn_target(fw,is);
5978 }
5979
5980 if(addr) {
5981 add_func_name(fw,names[0],addr,NULL);
5982 }
5983 disasm_iter_init(fw, is, ADR_SET_THUMB(ex_vec + 4));
5984 int i;
5985 for(i=1; i<8; i++) {
5986 disasm_iter(fw, is);
5987
5988
5989 addr=LDR_PC2val(fw,is->insn);
5990 if(addr) {
5991 add_func_name(fw,names[i],addr,NULL);
5992 }
5993 }
5994 }
5995
5996
5997
5998
5999
6000 void find_generic_funcs(firmware *fw) {
6001 search_calls_multi_data_t match_fns[MAX_GENERIC_FUNCS];
6002
6003 int match_fn_count=0;
6004
6005 add_generic_sig_match(match_fns,&match_fn_count,process_reg_eventproc_call,"ExportToEventProcedure_FW");
6006 add_generic_sig_match(match_fns,&match_fn_count,process_reg_eventproc_call,"RegisterEventProcedure_alt1");
6007 add_generic_sig_match(match_fns,&match_fn_count,process_reg_eventproc_call,"RegisterEventProcedure_alt2");
6008 add_generic_sig_match(match_fns,&match_fn_count,process_eventproc_table_call,"RegisterEventProcTable");
6009 add_generic_sig_match(match_fns,&match_fn_count,process_eventproc_table_call,"UnRegisterEventProcTable");
6010 add_generic_sig_match(match_fns,&match_fn_count,process_createtask_call,"CreateTaskStrictly");
6011 if(get_saved_sig_val("CreateTaskStrictly_alt")) {
6012 add_generic_sig_match(match_fns,&match_fn_count,process_createtask_call,"CreateTaskStrictly_alt");
6013 }
6014 add_generic_sig_match(match_fns,&match_fn_count,process_createtask_call,"CreateTask");
6015 if(get_saved_sig_val("CreateTask_alt")) {
6016 add_generic_sig_match(match_fns,&match_fn_count,process_createtask_call,"CreateTask_alt");
6017 }
6018 add_generic_sig_match(match_fns,&match_fn_count,process_eventproc_table_call,"RegisterEventProcTable_alt");
6019 add_generic_sig_match(match_fns,&match_fn_count,process_eventproc_table_call,"UnRegisterEventProcTable_alt");
6020 add_generic_sig_match(match_fns,&match_fn_count,process_add_ptp_handler_call,"add_ptp_handler");
6021
6022 iter_state_t *is=disasm_iter_new(fw,0);
6023 disasm_iter_init(fw,is,fw->rom_code_search_min_adr | fw->thumb_default);
6024 fw_search_insn(fw,is,search_disasm_calls_multi,0,match_fns,0);
6025
6026 int i;
6027 for(i=0;i<fw->adr_range_count;i++) {
6028 if(fw->adr_ranges[i].type != ADR_RANGE_RAM_CODE) {
6029 continue;
6030 }
6031 disasm_iter_init(fw,is,fw->adr_ranges[i].start | fw->thumb_default);
6032
6033 fw_search_insn(fw,is,search_disasm_calls_veneer_multi,0,match_fns,0);
6034 }
6035
6036 find_exception_handlers(fw,is);
6037
6038 disasm_iter_free(is);
6039 }
6040
6041 void find_ctypes(firmware *fw)
6042 {
6043 static unsigned char ctypes[] =
6044 {
6045 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x60, 0x60, 0x60, 0x60, 0x20, 0x20,
6046 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
6047 0x48, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
6048 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
6049 0x10, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 1, 1, 1, 1, 1, 1, 1, 1, 1,
6050 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0x10, 0x10, 0x10, 0x10, 0x10,
6051 0x10, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 2, 2, 2, 2, 2, 2, 2, 2, 2,
6052 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0x10, 0x10, 0x10, 0x10, 0x20
6053 };
6054
6055 uint32_t ctypes_matches[10];
6056 int match_count = find_bytes_all(fw,ctypes,sizeof(ctypes),fw->base,ctypes_matches,10);
6057 if(!match_count) {
6058 return;
6059 }
6060 if(match_count == 10) {
6061 fprintf(stderr,"WARNING found 10+ ctypes!\n");
6062 }
6063 int i;
6064 int match_i;
6065 uint32_t min_adr = 0xFFFFFFFF;
6066 for(i = 0; i< match_count; i++) {
6067
6068 uint32_t maxadr = (fw->rom_code_search_max_adr > fw->base + 0x400000)?fw->base + 0x100000:fw->rom_code_search_max_adr;
6069 uint32_t adr = find_u32_adr_range(fw,ctypes_matches[i],fw->rom_code_search_min_adr,maxadr);
6070 if(adr && adr < min_adr) {
6071 min_adr = adr;
6072 match_i = i;
6073 }
6074 }
6075 if(min_adr == 0xFFFFFFFF) {
6076 fprintf(stderr,"WARNING cytpes pointer not found, defaulting to first\n");
6077 match_i = 0;
6078 }
6079 save_misc_val("ctypes",ctypes_matches[match_i],0,min_adr);
6080 }
6081
6082 void print_misc_val_makefile(const char *name)
6083 {
6084 misc_val_t *mv=get_misc_val(name);
6085 if(!mv) {
6086 return;
6087 }
6088
6089 if(!mv->val) {
6090 bprintf("// %s not found\n",name);
6091 return;
6092 }
6093 bprintf("// %s = 0x%08x# ",name,mv->val);
6094 if(mv->offset) {
6095 bprintf(" (0x%x+0x%x)",mv->base,mv->offset);
6096 }
6097 if(mv->ref_adr) {
6098 bprintf(" Found @0x%08x",mv->ref_adr);
6099 }
6100 bprintf("\n");
6101 }
6102
6103
6104 void output_firmware_vals(firmware *fw)
6105 {
6106 bprintf("// Camera info:\n");
6107 bprintf("// Main firmware start: 0x%08x\n",fw->base+fw->main_offs);
6108 if (fw->dryos_ver == 0)
6109 {
6110 bprintf("// Can't find DRYOS version !!!\n\n");
6111 } else {
6112 bprintf("// DRYOS R%d (%s) @ 0x%08x ref @ 0x%08x\n",
6113 fw->dryos_ver,
6114 fw->dryos_ver_str,
6115 fw->dryos_ver_adr,
6116 fw->dryos_ver_ref_adr);
6117 }
6118 if (fw->firmware_ver_str == 0)
6119 {
6120 bprintf("// Can't find firmware version !!!\n\n");
6121 }
6122 else
6123 {
6124 char *c = strrchr(fw->firmware_ver_str,' ') + 1;
6125 uint32_t j = ptr2adr(fw,(uint8_t *)fw->firmware_ver_str);
6126 uint32_t k = j + c - fw->firmware_ver_str;
6127 if ( (k>=j) && (k<j+32) )
6128 {
6129 bprintf("// %s // Found @ 0x%08x, \"%s\" @ 0x%08x\n",fw->firmware_ver_str,j,c,k);
6130 }
6131 else
6132 {
6133
6134 bprintf("// %s // Found @ 0x%08x, \"%s\" @ 0x%08x\n",fw->firmware_ver_str,j,fw->firmware_ver_str,j);
6135 }
6136 }
6137 if (fw->arch_flags & FW_ARCH_FL_VMSA) {
6138 bprintf("// VMSA detected, probably digic >= 7\n");
6139 }
6140
6141 bprintf("\n// Values for makefile.inc\n");
6142 bprintf("// PLATFORMOSVER = %d\n",fw->dryos_ver);
6143 if (fw->arch_flags & FW_ARCH_FL_VMSA) {
6144 bprintf("// DIGIC = 70\n");
6145 } else {
6146
6147 bprintf("// DIGIC = 60\n");
6148 }
6149
6150 if (fw->memisostart) {
6151 bprintf("// MEMISOSTART = 0x%x\n",fw->memisostart);
6152 } else {
6153 bprintf("// MEMISOSTART not found !!!\n");
6154 }
6155 if (fw->data_init_start)
6156 {
6157 bprintf("// MEMBASEADDR = 0x%x\n",fw->data_start);
6158 }
6159 print_misc_val_makefile("ARAM_HEAP_START");
6160 print_misc_val_makefile("ARAM_HEAP_SIZE");
6161
6162 bprintf("\n// Detected address ranges:\n");
6163 int i;
6164 for(i=0; i<fw->adr_range_count; i++) {
6165 if(fw->adr_ranges[i].type == ADR_RANGE_ROM) {
6166 bprintf("// %-8s 0x%08x - 0x%08x (%7d bytes)\n",
6167 adr_range_desc_str(&fw->adr_ranges[i]),
6168 fw->adr_ranges[i].start,
6169 fw->adr_ranges[i].start+fw->adr_ranges[i].bytes,
6170 fw->adr_ranges[i].bytes);
6171 } else {
6172 bprintf("// %-8s 0x%08x - 0x%08x copied from 0x%08x (%7d bytes)\n",
6173 adr_range_desc_str(&fw->adr_ranges[i]),
6174 fw->adr_ranges[i].start,
6175 fw->adr_ranges[i].start+fw->adr_ranges[i].bytes,
6176 fw->adr_ranges[i].src_start,
6177 fw->adr_ranges[i].bytes);
6178 }
6179 }
6180 misc_val_t *mv=get_misc_val("zicokick_values");
6181 if(mv->blobs) {
6182 bprintf("\n// Zico Xtensa blobs:\n");
6183 for(i=0;mv->blobs[i].type != MISC_BLOB_TYPE_NONE;i++) {
6184 bprintf("// zico_%d 0x%08x - 0x%08x copied from 0x%08x (%7d bytes)\n",
6185 i,
6186 mv->blobs[i].ram_adr,
6187 mv->blobs[i].ram_adr+mv->blobs[i].size,
6188 mv->blobs[i].rom_adr,
6189 mv->blobs[i].size);
6190 }
6191
6192 }
6193 mv=get_misc_val("omar_init_values");
6194 if(mv->blobs) {
6195 bprintf("\n// Omar ARM blobs:\n");
6196 for(i=0;mv->blobs[i].type != MISC_BLOB_TYPE_NONE;i++) {
6197 bprintf("// omar_%d 0x%08x - 0x%08x copied from 0x%08x (%7d bytes)\n",
6198 i,
6199 mv->blobs[i].ram_adr,
6200 mv->blobs[i].ram_adr+mv->blobs[i].size,
6201 mv->blobs[i].rom_adr,
6202 mv->blobs[i].size);
6203 }
6204 }
6205 if(fw->dryos_ver_count) {
6206 bprintf("\n// Found DryOS versions:\n");
6207 for(i=0;i<(int)fw->dryos_ver_count;i++) {
6208 bprintf("// 0x%08x %s \"%s\"\n",
6209 fw->dryos_ver_list[i], (fw->dryos_ver_list[i] == fw->dryos_ver_adr) ? "main ":"other",
6210 (char *)adr2ptr(fw,fw->dryos_ver_list[i]));
6211 }
6212 add_blankline();
6213 }
6214 add_blankline();
6215
6216
6217 sig_entry_t * ct = find_saved_sig("hook_CreateTask");
6218 if(ct && adr_get_range_type(fw,ct->val) != ADR_RANGE_RAM_CODE) {
6219 bprintf("// CreateTask is not in RAM code\n");
6220 ct->flags |= UNUSED;
6221 sig_entry_t * ctl = find_saved_sig("CreateTask_low");
6222 if(ctl && adr_get_range_type(fw,ctl->val) == ADR_RANGE_RAM_CODE) {
6223 bprintf("// use hook_CreateTask_low instead\n");
6224 ctl->flags &= ~UNUSED;
6225 sig_entry_t * hctl = find_saved_sig("hook_CreateTask_low");
6226 hctl->flags &= ~UNUSED;
6227 }
6228 add_blankline();
6229 }
6230 }
6231
6232
6233 void print_platform_misc_val_undef(const char *name, uint32_t def)
6234 {
6235 misc_val_t *mv=get_misc_val(name);
6236 if(mv && mv->val && mv->val != def) {
6237 bprintf("//#undef %s\n",name);
6238 bprintf("//#define %s 0x%08x // Found @0x%08x\n",name,mv->val,mv->ref_adr);
6239 }
6240 }
6241
6242 void output_platform_vals(firmware *fw) {
6243 bprintf("// Values below go in 'platform_camera.h':\n");
6244 bprintf("//#define CAM_DRYOS 1\n");
6245 if (fw->dryos_ver >= 39)
6246 bprintf("//#define CAM_DRYOS_2_3_R39 1 // Defined for cameras with DryOS version R39 or higher\n");
6247 if (fw->dryos_ver >= 47)
6248 bprintf("//#define CAM_DRYOS_2_3_R47 1 // Defined for cameras with DryOS version R47 or higher\n");
6249 if (fw->dryos_ver >= 59)
6250 bprintf("//#define CAM_DRYOS_2_3_R59 1 // Defined for cameras with DryOS version R59 or higher\n");
6251
6252 if(get_misc_val_value("CAM_IS_ILC")) {
6253 bprintf("//#define CAM_ILC 1 // Camera is interchangeable lens\n");
6254 }
6255
6256 if(get_misc_val_value("CAM_HAS_WIFI")) {
6257 bprintf("//#define CAM_HAS_WIFI 1 // Firmware has wifi support (only define if camera has hardware)\n");
6258 }
6259
6260
6261 print_platform_misc_val_undef("CAM_UNCACHED_BIT",0x10000000);
6262
6263 if(get_misc_val_value("CAM_HAS_ND_FILTER")) {
6264 bprintf("//#define CAM_HAS_ND_FILTER 1 // Camera has ND filter\n");
6265 } else {
6266 bprintf("//#undef CAM_HAS_ND_FILTER // Camera does not have an ND filter\n");
6267 }
6268 if(get_misc_val_value("CAM_HAS_IRIS_DIAPHRAGM")) {
6269 bprintf("// Camera has an iris (CAM_HAS_IRIS_DIAPHRAGM default)\n");
6270 } else {
6271 bprintf("//#undef CAM_HAS_IRIS_DIAPHRAGM // Camera does not have an iris\n");
6272 }
6273
6274 add_blankline();
6275 }
6276
6277 void output_propcases(firmware *fw) {
6278
6279 uint32_t used=0;
6280 uint32_t hits[KNOWN_PROPSET_COUNT];
6281 const uint32_t ps_offset = 6;
6282
6283 memset(hits, 0, KNOWN_PROPSET_COUNT*sizeof(uint32_t));
6284
6285 bprintf("// Known propcases\n");
6286
6287 int n = 0;
6288 while (knownprops[n].name) {
6289 used += knownprops[n].use>0?1:0;
6290 if (knownprops[n].id >= 0)
6291 {
6292 if (knownprops[n].use)
6293 {
6294 if (knownprops[n].id == knownprops[n].id_ps6) hits[6-ps_offset] += 1;
6295 if (knownprops[n].id == knownprops[n].id_ps7) hits[7-ps_offset] += 1;
6296 if (knownprops[n].id == knownprops[n].id_ps8) hits[8-ps_offset] += 1;
6297 if (knownprops[n].id == knownprops[n].id_ps9) hits[9-ps_offset] += 1;
6298 if (knownprops[n].id == knownprops[n].id_ps10) hits[10-ps_offset] += 1;
6299 if (knownprops[n].id == knownprops[n].id_ps11) hits[11-ps_offset] += 1;
6300 if (knownprops[n].id == knownprops[n].id_ps12) hits[12-ps_offset] += 1;
6301 if (knownprops[n].id == knownprops[n].id_ps13) hits[13-ps_offset] += 1;
6302 }
6303 if (knownprops[n].use == 1)
6304 {
6305 bprintf("// #define %s %i\n", knownprops[n].name, knownprops[n].id);
6306 }
6307 else
6308 {
6309
6310 bprintf("// // %s %i\n", knownprops[n].name, knownprops[n].id);
6311 }
6312 }
6313 else
6314 {
6315 bprintf("// %s not found\n", knownprops[n].name);
6316 }
6317 n++;
6318 }
6319
6320 bprintf("// Guessed propset: ");
6321 int m = 0;
6322 uint32_t fmax = 0;
6323 int okay = 0;
6324 for (n=0; n<KNOWN_PROPSET_COUNT; n++)
6325 {
6326 if (hits[n] == used)
6327 {
6328 if (m) bprintf(", ");
6329 bprintf("%i", n+ps_offset);
6330 if (fw->sv->propset == n+ps_offset) okay = 1;
6331 m += 1;
6332 }
6333 if (hits[n] > fmax) fmax = hits[n];
6334 }
6335 if (m == 0)
6336 {
6337 bprintf("uncertain (%i of %u match), closest to ",fmax,used);
6338 for (n=0; n<KNOWN_PROPSET_COUNT; n++)
6339 {
6340 if (hits[n] == fmax)
6341 {
6342 if (m) bprintf(", ");
6343 bprintf("%i", n+ps_offset);
6344 if (fw->sv->propset == n+ps_offset) okay = 1;
6345 m += 1;
6346 }
6347 }
6348 }
6349 bprintf("\n");
6350 if (!okay && fw->sv->propset>0)
6351 {
6352
6353 bprintf("// Port's propset (%i) may be set incorrectly\n", fw->sv->propset);
6354 }
6355
6356 add_blankline();
6357 }
6358
6359 void output_exmem_types(firmware *fw)
6360 {
6361
6362 misc_val_t *ett=get_misc_val("exmem_types_table");
6363 misc_val_t *etc=get_misc_val("exmem_type_count");
6364 if (ett->val == 0 || etc->val == 0) {
6365 return;
6366 }
6367 bprintf("// EXMEM types:\n");
6368 uint32_t n;
6369 for (n=0; n<etc->val; n++) {
6370 char *extyp = (char*)adr2ptr(fw, fw_u32(fw,ett->val+n*4));
6371 bprintf("// %s %i\n", extyp, n);
6372 }
6373 add_blankline();
6374 }
6375
6376 void print_misc_val_comment(const char *name)
6377 {
6378 misc_val_t *mv=get_misc_val(name);
6379 if(!mv) {
6380 return;
6381 }
6382
6383 if(!mv->val) {
6384 bprintf("// %s not found\n",name);
6385 return;
6386 }
6387 bprintf("// %s 0x%08x",name,mv->val);
6388 if(mv->offset) {
6389 bprintf(" (0x%x+0x%x)",mv->base,mv->offset);
6390 }
6391 if(mv->ref_adr) {
6392 bprintf(" Found @0x%08x",mv->ref_adr);
6393 }
6394 bprintf("\n");
6395 }
6396
6397 typedef struct {
6398 int reg;
6399 uint32_t bit;
6400 uint32_t ev;
6401 uint32_t raw_info;
6402 int no_invert;
6403 } physw_table_entry_t;
6404
6405 void get_physw_table_entry(firmware *fw, uint32_t adr, physw_table_entry_t *vals)
6406 {
6407 uint32_t info=fw_u32(fw,adr);
6408 vals->raw_info=info;
6409 vals->ev=fw_u32(fw,adr+4);
6410
6411 vals->reg=(info >>5) & 7;
6412 vals->bit=(1 << (info & 0x1f));
6413
6414 vals->no_invert=((info&0xff0000)==0x10000)?1:0;
6415 }
6416 uint32_t find_physw_table_entry(firmware *fw, uint32_t tadr, int tcount, uint32_t ev)
6417 {
6418 int i;
6419 for(i=0; i<tcount; i++,tadr += 8) {
6420 if(fw_u32(fw,tadr+4) == ev) {
6421 return tadr;
6422 }
6423 }
6424 return 0;
6425 }
6426
6427 uint32_t find_physw_table_max(firmware *fw, uint32_t tadr, int max_count)
6428 {
6429 int i;
6430 for(i=0; i<max_count; i++,tadr += 8) {
6431 physw_table_entry_t v;
6432 get_physw_table_entry(fw,tadr,&v);
6433 if(v.raw_info == 0 || v.raw_info == 0xFFFFFFFF || v.reg > 2) {
6434 return i;
6435 }
6436
6437 }
6438 return max_count;
6439 }
6440 void write_physw_event_table_dump(firmware *fw, uint32_t tadr, int tcount)
6441 {
6442 FILE *f=fopen("physw_bits.txt","w");
6443 if(!f) {
6444 return;
6445 }
6446 fprintf(f,"physw_event_table dump (%d entries printed, may not all be valid)\n",tcount);
6447 fprintf(f,"address info event index bit non-inverted\n");
6448 int i;
6449 physw_table_entry_t v;
6450
6451 for(i=0; i<tcount; i++,tadr += 8) {
6452 get_physw_table_entry(fw,tadr,&v);
6453 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);
6454 }
6455 fclose(f);
6456 }
6457 void print_kval(firmware *fw, uint32_t tadr, int tcount, uint32_t ev, const char *name, const char *sfx)
6458 {
6459 uint32_t adr=find_physw_table_entry(fw,tadr,tcount,ev);
6460 if(!adr) {
6461 return;
6462 }
6463 physw_table_entry_t v;
6464 get_physw_table_entry(fw,adr,&v);
6465
6466 char fn[100], rn[100];
6467 strcpy(fn,name); strcat(fn,sfx);
6468 strcpy(rn,name); strcat(rn,"_IDX");
6469
6470 bprintf("//#define %-20s0x%08x // Found @0x%08x, levent 0x%x%s\n",fn,v.bit,adr,v.ev,v.no_invert?" (non-inverted logic)":"");
6471 bprintf("//#define %-20s%d\n",rn,v.reg);
6472
6473 }
6474
6475
6476 typedef struct {
6477 int reg;
6478 uint32_t bits;
6479 char nm[32];
6480 uint32_t fadr;
6481 uint32_t ev;
6482 int inv;
6483 } kinfo;
6484
6485 int kmask[3];
6486 kinfo key_info[100];
6487 int kcount = 0;
6488 uint32_t kshutter_min_bits = 0xFFFFFFFF;
6489
6490 void add_kinfo(int r, uint32_t b, const char *nm, uint32_t adr, uint32_t ev, int inv)
6491 {
6492 key_info[kcount].reg = r;
6493 key_info[kcount].bits = b;
6494 strcpy(key_info[kcount].nm, nm);
6495 key_info[kcount].fadr = adr;
6496 key_info[kcount].ev = ev;
6497 key_info[kcount].inv = inv;
6498 kcount++;
6499 kmask[r] |= b;
6500 if ((ev <= 1) && (b < kshutter_min_bits)) kshutter_min_bits = b;
6501 }
6502
6503 uint32_t add_kmval(firmware *fw, uint32_t tadr, __attribute__ ((unused))int tsiz, int tlen, uint32_t ev, const char *name, uint32_t xtra)
6504 {
6505 uint32_t adr=find_physw_table_entry(fw,tadr,tlen,ev);
6506 if(!adr) {
6507 return 0;
6508 }
6509 physw_table_entry_t v;
6510 get_physw_table_entry(fw,adr,&v);
6511
6512 add_kinfo(v.reg,v.bit|xtra,name,adr,v.ev,(v.no_invert)?0:1);
6513 return v.bit;
6514 }
6515
6516 int kinfo_compare(const kinfo *p1, const kinfo *p2)
6517 {
6518 if (p1->reg > p2->reg)
6519 {
6520 return 1;
6521 }
6522 else if (p1->reg < p2->reg)
6523 {
6524 return -1;
6525 }
6526 if ((p1->ev <= 1) && (p2->ev <= 1))
6527 {
6528 if (p1->bits > p2->bits)
6529 {
6530 return -1;
6531 }
6532 else if (p1->bits < p2->bits)
6533 {
6534 return 1;
6535 }
6536 }
6537
6538 if (p1->ev <= 1)
6539 {
6540 if (kshutter_min_bits > p2->bits)
6541 {
6542 return 1;
6543 }
6544 else if (kshutter_min_bits < p2->bits)
6545 {
6546 return -1;
6547 }
6548 }
6549 if (p2->ev <= 1)
6550 {
6551 if (p1->bits > kshutter_min_bits)
6552 {
6553 return 1;
6554 }
6555 else if (p1->bits < kshutter_min_bits)
6556 {
6557 return -1;
6558 }
6559 }
6560 if (p1->bits > p2->bits)
6561 {
6562 return 1;
6563 }
6564 else if (p1->bits < p2->bits)
6565 {
6566 return -1;
6567 }
6568
6569 return 0;
6570 }
6571
6572 void print_kmvals()
6573 {
6574 qsort(key_info, kcount, sizeof(kinfo), (void*)kinfo_compare);
6575
6576 bprintf("//KeyMap keymap[] = {\n");
6577
6578 int k;
6579 for (k=0; k<kcount; k++)
6580 {
6581 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)");
6582 }
6583
6584 bprintf("// { 0, 0, 0 }\n//};\n");
6585 }
6586
6587 void do_km_vals(firmware *fw, uint32_t tadr,int tsiz,int tlen)
6588 {
6589 uint32_t key_half = add_kmval(fw,tadr,tsiz,tlen,0,"KEY_SHOOT_HALF",0);
6590 add_kmval(fw,tadr,tsiz,tlen,1,"KEY_SHOOT_FULL",key_half);
6591 add_kmval(fw,tadr,tsiz,tlen,1,"KEY_SHOOT_FULL_ONLY",0);
6592
6593 add_kmval(fw,tadr,tsiz,tlen,0x101,"KEY_PLAYBACK",0);
6594 add_kmval(fw,tadr,tsiz,tlen,0x100,"KEY_POWER",0);
6595
6596
6597 if (fw->dryos_ver == 52)
6598 {
6599 add_kmval(fw,tadr,tsiz,tlen,3,"KEY_ZOOM_IN",0);
6600 add_kmval(fw,tadr,tsiz,tlen,4,"KEY_ZOOM_OUT",0);
6601 add_kmval(fw,tadr,tsiz,tlen,6,"KEY_UP",0);
6602 add_kmval(fw,tadr,tsiz,tlen,7,"KEY_DOWN",0);
6603 add_kmval(fw,tadr,tsiz,tlen,8,"KEY_LEFT",0);
6604 add_kmval(fw,tadr,tsiz,tlen,9,"KEY_RIGHT",0);
6605 add_kmval(fw,tadr,tsiz,tlen,0xA,"KEY_SET",0);
6606 add_kmval(fw,tadr,tsiz,tlen,0xB,"KEY_MENU",0);
6607 add_kmval(fw,tadr,tsiz,tlen,0xC,"KEY_DISPLAY",0);
6608 add_kmval(fw,tadr,tsiz,tlen,0x12,"KEY_HELP",0);
6609 add_kmval(fw,tadr,tsiz,tlen,0x19,"KEY_ERASE",0);
6610 add_kmval(fw,tadr,tsiz,tlen,2,"KEY_VIDEO",0);
6611
6612 }
6613 else if (fw->dryos_ver < 54)
6614 {
6615 add_kmval(fw,tadr,tsiz,tlen,2,"KEY_ZOOM_IN",0);
6616 add_kmval(fw,tadr,tsiz,tlen,3,"KEY_ZOOM_OUT",0);
6617 add_kmval(fw,tadr,tsiz,tlen,4,"KEY_UP",0);
6618 add_kmval(fw,tadr,tsiz,tlen,5,"KEY_DOWN",0);
6619 add_kmval(fw,tadr,tsiz,tlen,6,"KEY_LEFT",0);
6620 add_kmval(fw,tadr,tsiz,tlen,7,"KEY_RIGHT",0);
6621 add_kmval(fw,tadr,tsiz,tlen,8,"KEY_SET",0);
6622 add_kmval(fw,tadr,tsiz,tlen,9,"KEY_MENU",0);
6623 add_kmval(fw,tadr,tsiz,tlen,0xA,"KEY_DISPLAY",0);
6624 }
6625 else if (fw->dryos_ver < 55)
6626 {
6627 add_kmval(fw,tadr,tsiz,tlen,3,"KEY_ZOOM_IN",0);
6628 add_kmval(fw,tadr,tsiz,tlen,4,"KEY_ZOOM_OUT",0);
6629 add_kmval(fw,tadr,tsiz,tlen,6,"KEY_UP",0);
6630 add_kmval(fw,tadr,tsiz,tlen,7,"KEY_DOWN",0);
6631 add_kmval(fw,tadr,tsiz,tlen,8,"KEY_LEFT",0);
6632 add_kmval(fw,tadr,tsiz,tlen,9,"KEY_RIGHT",0);
6633 add_kmval(fw,tadr,tsiz,tlen,0xA,"KEY_SET",0);
6634 add_kmval(fw,tadr,tsiz,tlen,0xE,"KEY_MENU",0);
6635 add_kmval(fw,tadr,tsiz,tlen,2,"KEY_VIDEO",0);
6636 add_kmval(fw,tadr,tsiz,tlen,0xD,"KEY_DISPLAY",0);
6637 add_kmval(fw,tadr,tsiz,tlen,0x103,"KEY_WIFI",0);
6638
6639
6640 }
6641 else if (fw->dryos_ver < 59)
6642 {
6643 add_kmval(fw,tadr,tsiz,tlen,3,"KEY_ZOOM_IN",0);
6644 add_kmval(fw,tadr,tsiz,tlen,4,"KEY_ZOOM_OUT",0);
6645 add_kmval(fw,tadr,tsiz,tlen,6,"KEY_UP",0);
6646 add_kmval(fw,tadr,tsiz,tlen,7,"KEY_DOWN",0);
6647 add_kmval(fw,tadr,tsiz,tlen,8,"KEY_LEFT",0);
6648 add_kmval(fw,tadr,tsiz,tlen,9,"KEY_RIGHT",0);
6649 add_kmval(fw,tadr,tsiz,tlen,0xA,"KEY_SET",0);
6650 add_kmval(fw,tadr,tsiz,tlen,0x14,"KEY_MENU",0);
6651 add_kmval(fw,tadr,tsiz,tlen,2,"KEY_VIDEO",0);
6652 add_kmval(fw,tadr,tsiz,tlen,0xD,"KEY_DISPLAY",0);
6653 add_kmval(fw,tadr,tsiz,tlen,0x103,"KEY_WIFI",0);
6654
6655
6656 }
6657 else
6658 {
6659 add_kmval(fw,tadr,tsiz,tlen,3,"KEY_ZOOM_IN",0);
6660 add_kmval(fw,tadr,tsiz,tlen,4,"KEY_ZOOM_OUT",0);
6661 add_kmval(fw,tadr,tsiz,tlen,6,"KEY_UP",0);
6662 add_kmval(fw,tadr,tsiz,tlen,7,"KEY_DOWN",0);
6663 add_kmval(fw,tadr,tsiz,tlen,8,"KEY_LEFT",0);
6664 add_kmval(fw,tadr,tsiz,tlen,9,"KEY_RIGHT",0);
6665 add_kmval(fw,tadr,tsiz,tlen,0xA,"KEY_SET",0);
6666 add_kmval(fw,tadr,tsiz,tlen,0x15,"KEY_MENU",0);
6667 add_kmval(fw,tadr,tsiz,tlen,2,"KEY_VIDEO",0);
6668 add_kmval(fw,tadr,tsiz,tlen,0xB,"KEY_ERASE",0);
6669 add_kmval(fw,tadr,tsiz,tlen,0x103,"KEY_WIFI",0);
6670 }
6671
6672 bprintf("\n// Keymap values for kbd.c. Additional keys may be present, only common values included here.\n");
6673 bprintf("// WARNING: Key name / function may vary! Values for unknown DryOS versions should not be trusted!\n");
6674 print_kmvals();
6675 }
6676 void output_physw_vals(firmware *fw) {
6677 print_misc_val_comment("physw_event_table");
6678 uint32_t physw_tbl=get_misc_val_value("physw_event_table");
6679 if(!physw_tbl) {
6680 return;
6681 }
6682 int physw_tbl_len=find_physw_table_max(fw,physw_tbl,50);
6683 write_physw_event_table_dump(fw,physw_tbl,physw_tbl_len);
6684
6685 bprintf("// Values below go in 'platform_kbd.h':\n");
6686 if (fw->dryos_ver >= 58)
6687 {
6688
6689 print_kval(fw,physw_tbl,physw_tbl_len,0x30A,"SD_READONLY","_FLAG");
6690 print_kval(fw,physw_tbl,physw_tbl_len,0x302,"USB","_MASK");
6691 print_kval(fw,physw_tbl,physw_tbl_len,0x305,"BATTCOVER","_FLAG");
6692 print_kval(fw,physw_tbl,physw_tbl_len,0x304,"HOTSHOE","_FLAG");
6693 print_kval(fw,physw_tbl,physw_tbl_len,0x300,"ANALOG_AV","_FLAG");
6694 }
6695 else
6696 {
6697 print_kval(fw,physw_tbl,physw_tbl_len,0x20A,"SD_READONLY","_FLAG");
6698 print_kval(fw,physw_tbl,physw_tbl_len,0x202,"USB","_MASK");
6699 print_kval(fw,physw_tbl,physw_tbl_len,0x205,"BATTCOVER","_FLAG");
6700 print_kval(fw,physw_tbl,physw_tbl_len,0x204,"HOTSHOE","_FLAG");
6701 print_kval(fw,physw_tbl,physw_tbl_len,0x200,"ANALOG_AV","_FLAG");
6702 }
6703 do_km_vals(fw,physw_tbl,2,physw_tbl_len);
6704
6705 add_blankline();
6706 }
6707
6708
6709
6710
6711
6712
6713
6714
6715
6716
6717
6718
6719
6720
6721
6722
6723
6724
6725
6726
6727
6728
6729
6730
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742 void output_modemap(firmware *fw) {
6743 print_misc_val_comment("canon_mode_list");
6744 bprintf("// Check modemap values from 'platform/CAMERA/shooting.c':\n");
6745 misc_val_t *mv=get_misc_val("canon_mode_list");
6746 if(!mv) {
6747 add_blankline();
6748 return;
6749 }
6750 int i;
6751 uint32_t adr=mv->val;
6752 int bad=0;
6753 for(i=0; i<50; i++,adr+=2) {
6754 uint16_t *pv=(uint16_t*)adr2ptr(fw,adr);
6755 if(!pv) {
6756 break;
6757 }
6758 if(*pv==0xFFFF) {
6759 break;
6760 }
6761 osig *m = find_sig_val(fw->sv->modemap, *pv);
6762 if (!m) {
6763 bprintf("// %5hu 0x%04hx In firmware but not in current modemap",*pv,*pv);
6764
6765
6766
6767
6768
6769
6770 bprintf("\n");
6771 bad++;
6772 } else {
6773
6774 m->pct = 100;
6775 }
6776 }
6777 osig *m = fw->sv->modemap;
6778 while (m)
6779 {
6780 if (m->pct != 100)
6781 {
6782 bprintf("// Current modemap entry not found in firmware - %-24s %5d\n",m->nm,m->val);
6783 bad++;
6784 }
6785 m = m->nxt;
6786 }
6787 if (bad == 0)
6788 {
6789 bprintf("// No problems found with modemap table.\n");
6790 }
6791
6792 add_blankline();
6793 }
6794
6795
6796 int compare_sig_names(const sig_entry_t **p1, const sig_entry_t **p2)
6797 {
6798 int rv = strcasecmp((*p1)->name, (*p2)->name);
6799 if (rv != 0)
6800 return rv;
6801 rv = strcmp((*p1)->name, (*p2)->name);
6802 if (rv != 0)
6803 return rv;
6804 if ((*p1)->val < (*p2)->val)
6805 return -1;
6806 else if ((*p1)->val > (*p2)->val)
6807 return 1;
6808 return 0;
6809 }
6810
6811 int compare_func_addresses(const sig_entry_t **p1, const sig_entry_t **p2)
6812 {
6813 if ((*p1)->val < (*p2)->val)
6814 return -1;
6815 else if ((*p1)->val > (*p2)->val)
6816 return 1;
6817 return compare_sig_names(p1,p2);
6818 }
6819
6820 void write_funcs(firmware *fw, char *filename, sig_entry_t *fns[], int (*compare)(const sig_entry_t **p1, const sig_entry_t **p2))
6821 {
6822 int k;
6823
6824 qsort(fns, next_sig_entry, sizeof(sig_entry_t*), (void*)compare);
6825
6826 FILE *out_fp = fopen(filename, "w");
6827 for (k=0; k<next_sig_entry; k++)
6828 {
6829 if (strncmp(fns[k]->name,"hook_",5) == 0) {
6830 continue;
6831 }
6832 if (fns[k]->val != 0)
6833 {
6834 if (fns[k]->flags & BAD_MATCH)
6835 {
6836 osig* ostub2 = find_sig(fw->sv->stubs,fns[k]->name);
6837 if (ostub2 && ostub2->val)
6838 fprintf(out_fp, "0x%08x,%s,(stubs_entry_2.s)\n", ostub2->val, fns[k]->name);
6839 }
6840 else
6841 fprintf(out_fp, "0x%08x,%s\n", fns[k]->val, fns[k]->name);
6842 }
6843 #ifdef LIST_IMPORTANT_FUNCTIONS
6844 else if (fns[k]->flags & LIST_ALWAYS)
6845 {
6846
6847 fprintf(out_fp, "0,%s,(NOT FOUND)\n", fns[k]->name);
6848 }
6849 #endif
6850 }
6851 fclose(out_fp);
6852 }
6853
6854 void write_func_lists(firmware *fw) {
6855 sig_entry_t *fns[MAX_SIG_ENTRY];
6856 int k;
6857 for (k=0; k<next_sig_entry; k++)
6858 fns[k] = &sig_names[k];
6859
6860 write_funcs(fw, "funcs_by_name.csv", fns, compare_sig_names);
6861 write_funcs(fw, "funcs_by_address.csv", fns, compare_func_addresses);
6862 }
6863
6864 void print_other_stubs_min(firmware *fw, const char *name, uint32_t fadr, uint32_t atadr)
6865 {
6866 osig *o = find_sig(fw->sv->stubs_min,name);
6867 if (o)
6868 {
6869 bprintf("//DEF(%-40s,0x%08x) // Found @0x%08x",name,fadr,atadr);
6870 if (fadr != o->val)
6871 {
6872 bprintf(", ** != ** stubs_min = 0x%08x (%s)",o->val,o->sval);
6873 }
6874 else
6875 {
6876 bprintf(", stubs_min = 0x%08x (%s)",o->val,o->sval);
6877 }
6878 }
6879 else
6880 {
6881 bprintf("DEF(%-40s,0x%08x) // Found @0x%08x",name,fadr,atadr);
6882 }
6883 bprintf("\n");
6884 }
6885
6886 void print_stubs_min_def(firmware *fw, misc_val_t *sig)
6887 {
6888 if(sig->flags & MISC_VAL_NO_STUB) {
6889 return;
6890 }
6891
6892 osig* ostub2=find_sig(fw->sv->stubs_min,sig->name);
6893
6894 const char *macro = "DEF";
6895 if(sig->flags & MISC_VAL_DEF_CONST) {
6896 macro="DEF_CONST";
6897 }
6898
6899 if (ostub2)
6900 {
6901 bprintf("//%s(%-34s,0x%08x)",macro,sig->name,sig->val);
6902 if (sig->val != ostub2->val)
6903 {
6904 bprintf(", ** != ** stubs_min = 0x%08x (%s)",ostub2->val,ostub2->sval);
6905 }
6906 else
6907 {
6908 bprintf(", stubs_min = 0x%08x (%s)",ostub2->val,ostub2->sval);
6909 }
6910 }
6911 else if(sig->base || sig->offset)
6912 {
6913 bprintf("%s(%-34s,0x%08x)",macro,sig->name,sig->val);
6914 if(sig->offset || sig->ref_adr) {
6915 bprintf(" //");
6916 if(sig->offset) {
6917 bprintf(" (0x%x+0x%x)",sig->base,sig->offset);
6918 }
6919 if(sig->ref_adr) {
6920 bprintf(" Found @0x%08x",sig->ref_adr);
6921 }
6922 }
6923 }
6924 else
6925 {
6926 if (sig->flags & MISC_VAL_OPTIONAL) return;
6927 bprintf("// %s not found",sig->name);
6928 }
6929 bprintf("\n");
6930 }
6931
6932
6933 void find_other_stubs_min(firmware *fw)
6934 {
6935 int k,k1;
6936
6937 out_hdr = 1;
6938
6939
6940 if (fw->sv->min_focus_len != 0)
6941 {
6942 int found = 0, pos = 0, len = 0, size = 0;
6943 for (k=0; k<fw->size32; k++)
6944 {
6945 if (fw->buf32[k] == fw->sv->min_focus_len)
6946 {
6947 int mul = 1;
6948 if ((fw->buf32[k+1] == 100) && (fw->buf32[k+2] == 0)) mul = 3;
6949 if ((fw->buf32[k+1] == 100) && (fw->buf32[k+2] != 0)) mul = 2;
6950 if ((fw->buf32[k+1] == 0) && (fw->buf32[k+2] != 0)) mul = 2;
6951 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) ;
6952 if (fw->buf32[k1] == fw->sv->max_focus_len)
6953 {
6954 if ((found == 0) || ((size < mul) && (len < ((k1 - k) / mul) + 1)))
6955 {
6956 found = 1;
6957 pos = k;
6958 len = ((k1 - k) / mul) + 1;
6959 size = mul;
6960 }
6961 }
6962 }
6963 }
6964 if (found == 1)
6965 {
6966 uint32_t adr = fw->base + (pos << 2);
6967 bprintf("// focus_len_table contains zoom focus lengths for use in 'get_focal_length' (main.c).\n");
6968 if (size == 1)
6969 bprintf("// each entry contains 1 int value, which is the the zoom focus length.\n",size);
6970 else
6971 bprintf("// each entry contains %d int value(s), the first is the zoom focus length.\n",size);
6972 bprintf("// there are %d entries in the table - set NUM_FL to %d\n",len,len);
6973 print_other_stubs_min(fw,"focus_len_table",adr,adr);
6974 }
6975 }
6976 }
6977
6978
6979
6980 void print_results(firmware *fw, sig_entry_t *sig)
6981 {
6982 int i;
6983 int err = 0;
6984 char line[500] = "";
6985
6986 if (sig->flags & DONT_EXPORT) {
6987 return;
6988 }
6989
6990 if ((sig->flags & DONT_EXPORT_ILC) && get_misc_val_value("CAM_IS_ILC")) {
6991 return;
6992 }
6993
6994
6995 osig* ostub2 = find_sig(fw->sv->stubs,sig->name);
6996
6997 if (ostub2 && (sig->val != ostub2->val))
6998 {
6999 if (ostub2->type != TYPE_IGNORE)
7000 {
7001 err = 1;
7002 sig->flags |= BAD_MATCH;
7003 }
7004 }
7005 else
7006 {
7007 if (sig->flags & UNUSED) return;
7008 }
7009
7010
7011 out_hdr = err;
7012
7013 char *macro = "NHSTUB";
7014 if (sig->flags & ARM_STUB) {
7015 macro = "NHSTUB2";
7016 }
7017 if (strncmp(sig->name,"task_",5) == 0 ||
7018 strncmp(sig->name,"hook_",5) == 0) macro = " DEF";
7019
7020 if (!sig->val && !ostub2)
7021 {
7022 if (sig->flags & OPTIONAL) return;
7023 char fmt[51] = "";
7024 sprintf(fmt, "// ERROR: %%s is not found. %%%ds//--- --- ", (int)(34-strlen(sig->name)));
7025 sprintf(line+strlen(line), fmt, sig->name, "");
7026 }
7027 else
7028 {
7029 if (ostub2 || (sig->flags & UNUSED))
7030 sprintf(line+strlen(line),"//%s(%-37s,0x%08x) //%3d ", macro, sig->name, sig->val, 0);
7031 else
7032 sprintf(line+strlen(line),"%s(%-39s,0x%08x) //%3d ", macro, sig->name, sig->val, 0);
7033
7034
7035
7036
7037
7038
7039 sprintf(line+strlen(line)," ");
7040 }
7041
7042 if (ostub2)
7043 {
7044 if (ostub2->type == TYPE_IGNORE)
7045 sprintf(line+strlen(line)," Overridden");
7046 else if (sig->val == ostub2->val)
7047 sprintf(line+strlen(line)," == 0x%08x ",ostub2->val);
7048 else {
7049
7050 if(sig->val && ostub2->val) {
7051 fw_disasm_iter_single(fw,ostub2->val);
7052 if(get_direct_jump_target(fw,fw->is) == sig->val) {
7053 sprintf(line+strlen(line)," <-veneer 0x%08x ",ostub2->val);
7054 } else {
7055 fw_disasm_iter_single(fw,sig->val);
7056 if(get_direct_jump_target(fw,fw->is) == ostub2->val) {
7057 sprintf(line+strlen(line)," veneer-> 0x%08x ",ostub2->val);
7058 } else {
7059 sprintf(line+strlen(line)," *** != 0x%08x ",ostub2->val);
7060 }
7061 }
7062 } else {
7063 sprintf(line+strlen(line)," *** != 0x%08x ",ostub2->val);
7064 }
7065 }
7066 }
7067 else
7068 sprintf(line+strlen(line)," ");
7069
7070 for (i=strlen(line)-1; i>=0 && line[i]==' '; i--) line[i] = 0;
7071 bprintf("%s\n",line);
7072
7073
7074
7075
7076
7077
7078
7079
7080
7081
7082 }
7083
7084 void write_stubs(firmware *fw,int max_find_func) {
7085 int k;
7086 bprintf("// Values below can be overridden in 'stubs_min.S':\n");
7087 misc_val_t *stub_min=misc_vals;
7088 while(stub_min->name) {
7089 print_stubs_min_def(fw,stub_min);
7090 stub_min++;
7091 }
7092
7093 find_other_stubs_min(fw);
7094
7095 add_blankline();
7096
7097 for (k = 0; k < max_find_func; k++)
7098 {
7099 print_results(fw,&sig_names[k]);
7100 }
7101 }
7102
7103 int main(int argc, char **argv)
7104 {
7105 clock_t t1 = clock();
7106
7107 firmware fw;
7108 memset(&fw,0,sizeof(firmware));
7109 if (argc < 4) {
7110 fprintf(stderr,"finsig_thumb2 <primary> <base> <outputfilename>\n");
7111 exit(1);
7112 }
7113
7114 for (next_sig_entry = 0; sig_names[next_sig_entry].name != 0; next_sig_entry++);
7115 int max_find_sig = next_sig_entry;
7116
7117 fw.sv = new_stub_values();
7118 load_stubs(fw.sv, "stubs_entry_2.S", 1);
7119 load_stubs_min(fw.sv);
7120 load_modemap(fw.sv);
7121 load_platform(fw.sv);
7122
7123 bprintf("// !!! THIS FILE IS GENERATED. DO NOT EDIT. !!!\n");
7124 bprintf("#include \"stubs_asm.h\"\n\n");
7125
7126 firmware_load(&fw,argv[1],strtoul(argv[2], NULL, 0),FW_ARCH_ARMv7);
7127 if(!firmware_init_capstone(&fw)) {
7128 exit(1);
7129 }
7130 firmware_init_data_ranges(&fw);
7131
7132 out_fp = fopen(argv[3],"w");
7133 if (out_fp == NULL) {
7134 fprintf(stderr,"Error opening output file %s\n",argv[3]);
7135 exit(1);
7136 }
7137
7138
7139
7140 find_ctypes(&fw);
7141
7142 run_sig_rules(&fw,sig_rules_initial);
7143 find_generic_funcs(&fw);
7144 run_sig_rules(&fw,sig_rules_main);
7145
7146 output_firmware_vals(&fw);
7147
7148 output_platform_vals(&fw);
7149 output_physw_vals(&fw);
7150 output_modemap(&fw);
7151
7152 output_propcases(&fw);
7153 output_exmem_types(&fw);
7154
7155 write_stubs(&fw,max_find_sig);
7156
7157 write_output();
7158 fclose(out_fp);
7159
7160 write_func_lists(&fw);
7161
7162 firmware_unload(&fw);
7163
7164 clock_t t2 = clock();
7165
7166 printf("Time to generate stubs %.2f seconds\n",(double)(t2-t1)/(double)CLOCKS_PER_SEC);
7167
7168 return 0;
7169 }