mirror of
https://github.com/radareorg/radare2
synced 2026-08-22 20:23:32 -04:00
698 lines
23 KiB
JavaScript
698 lines
23 KiB
JavaScript
/* Pebble libpebble.a stub resolver for radare2/r2js.
|
|
*
|
|
* Usage:
|
|
* r2 -i examples/pebble.r2.js hello-world/build/aplite/pebble-app.elf
|
|
*
|
|
* The per-API stubs linked from libpebble.a look like this in Thumb bytes:
|
|
* 0f b4 push {r0, r1, r2, r3}
|
|
* 01 49 ldr r1, [pc, #4]
|
|
* ff f7 ?? ?? b.w jump_to_pbl_function
|
|
* ?? ?? ?? ?? little-endian firmware jump-table byte offset
|
|
*
|
|
* Objdump prints the same pattern as halfwords:
|
|
* b40f 4901 f7ff ???? <offset32>
|
|
*
|
|
* The shared trampoline usually looks like this in file/memory bytes:
|
|
* 03 a3 18 68 08 44 02 68 94 46 0f bc 60 47 00 bf ?? ?? ?? ??
|
|
* where the last word is pbl_table_addr and is patched by the firmware loader.
|
|
*/
|
|
|
|
const STUB_PATTERN = "0fb40149fff7............";
|
|
const TRAMPOLINE_PATTERN = "03a318680844026894460fbc604700bf........";
|
|
|
|
const PEBBLE_API_BY_INDEX = {
|
|
0: "accel_data_service_subscribe__deprecated",
|
|
1: "accel_data_service_unsubscribe",
|
|
2: "accel_service_peek",
|
|
3: "accel_service_set_samples_per_update",
|
|
4: "accel_service_set_sampling_rate",
|
|
5: "accel_tap_service_subscribe",
|
|
6: "accel_tap_service_unsubscribe",
|
|
7: "action_bar_layer_legacy2_add_to_window",
|
|
8: "action_bar_layer_legacy2_clear_icon",
|
|
9: "action_bar_layer_legacy2_create",
|
|
10: "action_bar_layer_legacy2_destroy",
|
|
11: "action_bar_layer_legacy2_get_layer",
|
|
12: "action_bar_layer_legacy2_remove_from_window",
|
|
13: "action_bar_layer_legacy2_set_background_color_2bit",
|
|
14: "action_bar_layer_legacy2_set_click_config_provider",
|
|
15: "action_bar_layer_legacy2_set_context",
|
|
16: "action_bar_layer_legacy2_set_icon",
|
|
17: "animation_legacy2_create",
|
|
18: "animation_legacy2_destroy",
|
|
19: "animation_legacy2_get_context",
|
|
20: "animation_legacy2_is_scheduled",
|
|
21: "animation_legacy2_schedule",
|
|
22: "animation_legacy2_set_curve",
|
|
23: "animation_legacy2_set_delay",
|
|
24: "animation_legacy2_set_duration",
|
|
25: "animation_legacy2_set_handlers",
|
|
26: "animation_legacy2_set_implementation",
|
|
27: "animation_legacy2_unschedule",
|
|
28: "animation_legacy2_unschedule_all",
|
|
29: "app_comm_get_sniff_interval",
|
|
30: "app_comm_set_sniff_interval",
|
|
31: "app_event_loop",
|
|
34: "app_log",
|
|
35: "app_message_deregister_callbacks",
|
|
36: "app_message_open",
|
|
43: "app_sync_deinit",
|
|
44: "app_sync_get",
|
|
45: "app_sync_init",
|
|
46: "app_sync_set",
|
|
47: "app_timer_cancel",
|
|
48: "app_timer_register",
|
|
49: "app_timer_reschedule",
|
|
50: "atan2_lookup",
|
|
51: "atoi",
|
|
52: "atol",
|
|
53: "battery_state_service_peek",
|
|
54: "battery_state_service_subscribe",
|
|
55: "battery_state_service_unsubscribe",
|
|
56: "bitmap_layer_create",
|
|
57: "bitmap_layer_destroy",
|
|
58: "bitmap_layer_get_layer",
|
|
59: "bitmap_layer_set_alignment",
|
|
60: "bitmap_layer_set_background_color_2bit",
|
|
61: "bitmap_layer_set_bitmap",
|
|
62: "bitmap_layer_set_compositing_mode",
|
|
63: "bluetooth_connection_service_peek",
|
|
64: "bluetooth_connection_service_subscribe",
|
|
65: "bluetooth_connection_service_unsubscribe",
|
|
66: "click_number_of_clicks_counted",
|
|
67: "click_recognizer_get_button_id",
|
|
68: "clock_copy_time_string",
|
|
69: "clock_is_24h_style",
|
|
70: "cos_lookup",
|
|
71: "data_logging_create",
|
|
72: "data_logging_finish",
|
|
73: "data_logging_log",
|
|
74: "dict_calc_buffer_size",
|
|
75: "dict_calc_buffer_size_from_tuplets",
|
|
76: "dict_find",
|
|
77: "dict_merge",
|
|
78: "dict_read_begin_from_buffer",
|
|
79: "dict_read_first",
|
|
80: "dict_read_next",
|
|
81: "dict_serialize_tuplets",
|
|
82: "dict_serialize_tuplets_to_buffer__deprecated",
|
|
83: "dict_serialize_tuplets_to_buffer_with_iter",
|
|
84: "dict_write_begin",
|
|
85: "dict_write_cstring",
|
|
86: "dict_write_data",
|
|
87: "dict_write_end",
|
|
88: "dict_write_int",
|
|
89: "dict_write_int16",
|
|
90: "dict_write_int32",
|
|
91: "dict_write_int8",
|
|
92: "dict_write_tuplet",
|
|
93: "dict_write_uint16",
|
|
94: "dict_write_uint32",
|
|
95: "dict_write_uint8",
|
|
96: "fonts_get_system_font",
|
|
97: "fonts_load_custom_font",
|
|
98: "fonts_unload_custom_font",
|
|
99: "free",
|
|
100: "gbitmap_create_as_sub_bitmap",
|
|
101: "gbitmap_create_with_data",
|
|
102: "gbitmap_create_with_resource",
|
|
103: "gbitmap_destroy",
|
|
104: "gmtime",
|
|
105: "gpath_create",
|
|
106: "gpath_destroy",
|
|
107: "gpath_draw_filled_legacy",
|
|
108: "gpath_draw_outline",
|
|
109: "gpath_move_to",
|
|
110: "gpath_rotate_to",
|
|
111: "gpoint_equal",
|
|
112: "graphics_context_set_compositing_mode",
|
|
113: "graphics_context_set_fill_color_2bit",
|
|
114: "graphics_context_set_stroke_color_2bit",
|
|
115: "graphics_context_set_text_color_2bit",
|
|
116: "graphics_draw_bitmap_in_rect",
|
|
117: "graphics_draw_circle",
|
|
118: "graphics_draw_line",
|
|
119: "graphics_draw_pixel",
|
|
120: "graphics_draw_rect",
|
|
121: "graphics_draw_round_rect",
|
|
122: "graphics_fill_circle",
|
|
123: "graphics_fill_rect",
|
|
125: "graphics_text_layout_get_max_used_size",
|
|
126: "grect_align",
|
|
127: "grect_center_point",
|
|
128: "grect_clip",
|
|
129: "grect_contains_point",
|
|
130: "grect_crop",
|
|
131: "grect_equal",
|
|
132: "grect_is_empty",
|
|
133: "grect_standardize",
|
|
134: "gsize_equal",
|
|
135: "inverter_layer_create",
|
|
136: "inverter_layer_destroy",
|
|
137: "inverter_layer_get_layer",
|
|
138: "layer_add_child",
|
|
139: "layer_create",
|
|
140: "layer_create_with_data",
|
|
141: "layer_destroy",
|
|
142: "layer_get_bounds",
|
|
143: "layer_get_clips",
|
|
144: "layer_get_data",
|
|
145: "layer_get_frame",
|
|
146: "layer_get_hidden",
|
|
147: "layer_get_window",
|
|
148: "layer_insert_above_sibling",
|
|
149: "layer_insert_below_sibling",
|
|
150: "layer_mark_dirty",
|
|
151: "layer_remove_child_layers",
|
|
152: "layer_remove_from_parent",
|
|
153: "layer_set_bounds",
|
|
154: "layer_set_clips",
|
|
155: "layer_set_frame",
|
|
156: "layer_set_hidden",
|
|
157: "layer_set_update_proc",
|
|
158: "light_enable",
|
|
159: "light_enable_interaction",
|
|
160: "localtime__deprecated",
|
|
161: "malloc",
|
|
162: "memcpy",
|
|
163: "memmove",
|
|
164: "memset",
|
|
165: "menu_cell_basic_draw",
|
|
166: "menu_cell_basic_header_draw",
|
|
167: "menu_cell_title_draw",
|
|
168: "menu_index_compare",
|
|
169: "menu_layer_legacy2_create",
|
|
170: "menu_layer_destroy",
|
|
171: "menu_layer_get_layer",
|
|
172: "menu_layer_get_scroll_layer",
|
|
173: "menu_layer_get_selected_index",
|
|
174: "menu_layer_reload_data",
|
|
175: "menu_layer_legacy2_set_callbacks__deprecated",
|
|
176: "menu_layer_set_click_config_onto_window",
|
|
177: "menu_layer_set_selected_index",
|
|
178: "menu_layer_set_selected_next",
|
|
179: "number_window_create",
|
|
180: "number_window_destroy",
|
|
181: "number_window_get_value",
|
|
182: "number_window_set_label",
|
|
183: "number_window_set_max",
|
|
184: "number_window_set_min",
|
|
185: "number_window_set_step_size",
|
|
186: "number_window_set_value",
|
|
187: "persist_delete",
|
|
188: "persist_exists",
|
|
189: "persist_get_size",
|
|
190: "persist_read_bool",
|
|
191: "persist_read_data__deprecated",
|
|
192: "persist_read_int",
|
|
193: "persist_read_string__deprecated",
|
|
194: "persist_write_bool",
|
|
195: "persist_write_data__deprecated",
|
|
196: "persist_write_int",
|
|
197: "persist_write_string",
|
|
198: "property_animation_legacy2_create",
|
|
199: "property_animation_legacy2_create_layer_frame",
|
|
200: "property_animation_legacy2_destroy",
|
|
201: "property_animation_legacy2_update_gpoint",
|
|
202: "property_animation_legacy2_update_grect",
|
|
203: "property_animation_legacy2_update_int16",
|
|
204: "psleep",
|
|
205: "rand",
|
|
206: "resource_get_handle",
|
|
207: "resource_load",
|
|
208: "resource_load_byte_range",
|
|
209: "resource_size",
|
|
210: "rot_bitmap_layer_create",
|
|
211: "rot_bitmap_layer_destroy",
|
|
212: "rot_bitmap_layer_increment_angle",
|
|
213: "rot_bitmap_layer_set_angle",
|
|
214: "rot_bitmap_layer_set_corner_clip_color_2bit",
|
|
215: "rot_bitmap_set_compositing_mode",
|
|
216: "rot_bitmap_set_src_ic",
|
|
217: "scroll_layer_add_child",
|
|
218: "scroll_layer_create",
|
|
219: "scroll_layer_destroy",
|
|
220: "scroll_layer_get_content_offset",
|
|
221: "scroll_layer_get_content_size",
|
|
222: "scroll_layer_get_layer",
|
|
223: "scroll_layer_get_shadow_hidden",
|
|
224: "scroll_layer_scroll_down_click_handler",
|
|
225: "scroll_layer_scroll_up_click_handler",
|
|
226: "scroll_layer_set_callbacks",
|
|
227: "scroll_layer_set_click_config_onto_window",
|
|
228: "scroll_layer_set_content_offset",
|
|
229: "scroll_layer_set_content_size",
|
|
230: "scroll_layer_set_context",
|
|
231: "scroll_layer_set_frame",
|
|
232: "scroll_layer_set_shadow_hidden",
|
|
233: "simple_menu_layer_create",
|
|
234: "simple_menu_layer_destroy",
|
|
235: "simple_menu_layer_get_layer",
|
|
236: "simple_menu_layer_get_selected_index",
|
|
237: "simple_menu_layer_set_selected_index",
|
|
238: "sin_lookup",
|
|
239: "snprintf",
|
|
240: "srand",
|
|
241: "strcat",
|
|
242: "strcmp",
|
|
243: "strcpy",
|
|
244: "strftime",
|
|
245: "strlen",
|
|
246: "strncat",
|
|
247: "strncmp",
|
|
248: "strncpy",
|
|
249: "text_layer_legacy2_create",
|
|
250: "text_layer_legacy2_destroy",
|
|
251: "text_layer_legacy2_get_content_size",
|
|
252: "text_layer_legacy2_get_layer",
|
|
253: "text_layer_legacy2_get_text",
|
|
254: "text_layer_legacy2_set_background_color_2bit",
|
|
255: "text_layer_legacy2_set_font",
|
|
256: "text_layer_legacy2_set_overflow_mode",
|
|
257: "text_layer_legacy2_set_size",
|
|
258: "text_layer_legacy2_set_text",
|
|
259: "text_layer_legacy2_set_text_alignment",
|
|
260: "text_layer_legacy2_set_text_color_2bit",
|
|
262: "tick_timer_service_subscribe",
|
|
263: "tick_timer_service_unsubscribe",
|
|
264: "time__deprecated",
|
|
265: "time_ms_deprecated",
|
|
266: "vibes_cancel",
|
|
267: "vibes_double_pulse",
|
|
268: "vibes_enqueue_custom_pattern",
|
|
269: "vibes_long_pulse",
|
|
270: "vibes_short_pulse",
|
|
271: "window_create",
|
|
272: "window_destroy",
|
|
273: "window_get_click_config_provider",
|
|
274: "window_get_fullscreen",
|
|
275: "window_get_root_layer",
|
|
276: "window_is_loaded",
|
|
277: "window_set_background_color_2bit",
|
|
278: "window_set_click_config_provider",
|
|
279: "window_set_click_config_provider_with_context",
|
|
280: "window_set_fullscreen",
|
|
281: "window_set_status_bar_icon",
|
|
282: "window_set_window_handlers",
|
|
283: "window_stack_contains_window",
|
|
284: "window_stack_get_top_window",
|
|
285: "window_stack_pop",
|
|
286: "window_stack_pop_all",
|
|
287: "window_stack_push",
|
|
288: "window_stack_remove",
|
|
289: "app_focus_service_subscribe",
|
|
290: "app_focus_service_unsubscribe",
|
|
291: "window_get_user_data",
|
|
292: "window_set_user_data",
|
|
293: "app_message_get_context",
|
|
294: "app_message_inbox_size_maximum",
|
|
295: "app_message_outbox_begin",
|
|
296: "app_message_outbox_send",
|
|
297: "app_message_outbox_size_maximum",
|
|
298: "app_message_register_inbox_dropped",
|
|
299: "app_message_register_inbox_received",
|
|
300: "app_message_register_outbox_failed",
|
|
301: "app_message_register_outbox_sent",
|
|
302: "app_message_set_context",
|
|
303: "window_long_click_subscribe",
|
|
304: "window_multi_click_subscribe",
|
|
305: "window_raw_click_subscribe",
|
|
306: "window_set_click_context",
|
|
307: "window_single_click_subscribe",
|
|
308: "window_single_repeating_click_subscribe",
|
|
309: "graphics_draw_text",
|
|
310: "dict_serialize_tuplets_to_buffer",
|
|
311: "persist_read_data",
|
|
312: "persist_read_string",
|
|
313: "persist_write_data",
|
|
314: "dict_size",
|
|
315: "graphics_text_layout_get_content_size",
|
|
316: "simple_menu_layer_get_menu_layer",
|
|
317: "accel_data_service_subscribe",
|
|
318: "calloc",
|
|
319: "bitmap_layer_get_bitmap",
|
|
320: "menu_layer_legacy2_set_callbacks",
|
|
321: "window_get_click_config_context",
|
|
322: "number_window_get_window",
|
|
323: "realloc",
|
|
324: "gbitmap_create_blank_2bit",
|
|
325: "click_recognizer_is_repeating",
|
|
326: "accel_raw_data_service_subscribe",
|
|
327: "app_worker_is_running",
|
|
328: "app_worker_kill",
|
|
329: "app_worker_launch",
|
|
330: "app_worker_message_subscribe",
|
|
331: "app_worker_message_unsubscribe",
|
|
332: "app_worker_send_message",
|
|
333: "worker_event_loop",
|
|
334: "worker_launch_app",
|
|
335: "heap_bytes_free",
|
|
336: "heap_bytes_used",
|
|
337: "compass_service_peek",
|
|
338: "compass_service_set_heading_filter",
|
|
339: "compass_service_subscribe",
|
|
340: "compass_service_unsubscribe",
|
|
341: "uuid_equal",
|
|
342: "uuid_to_string",
|
|
343: "gpath_draw_filled",
|
|
344: "animation_legacy2_set_custom_curve",
|
|
345: "watch_info_get_color",
|
|
346: "watch_info_get_firmware_version",
|
|
347: "watch_info_get_model",
|
|
348: "graphics_capture_frame_buffer_2bit",
|
|
349: "graphics_frame_buffer_is_captured",
|
|
350: "graphics_release_frame_buffer",
|
|
351: "clock_to_timestamp",
|
|
352: "launch_reason",
|
|
353: "wakeup_cancel",
|
|
354: "wakeup_cancel_all",
|
|
355: "wakeup_get_launch_event",
|
|
356: "wakeup_query",
|
|
357: "wakeup_schedule",
|
|
358: "wakeup_service_subscribe",
|
|
359: "clock_is_timezone_set",
|
|
360: "i18n_get_system_locale",
|
|
361: "_localeconv_r",
|
|
362: "setlocale",
|
|
363: "mktime",
|
|
364: "gcolor_equal",
|
|
365: "__profiler_init",
|
|
366: "__profiler_print_stats",
|
|
367: "__profiler_start",
|
|
368: "__profiler_stop",
|
|
370: "bitmap_layer_set_background_color",
|
|
371: "graphics_context_set_fill_color",
|
|
372: "graphics_context_set_stroke_color",
|
|
373: "graphics_context_set_text_color",
|
|
374: "rot_bitmap_layer_set_corner_clip_color",
|
|
377: "window_set_background_color",
|
|
378: "clock_get_timezone",
|
|
379: "localtime",
|
|
380: "animation_create",
|
|
381: "animation_destroy",
|
|
382: "animation_get_context",
|
|
383: "animation_is_scheduled",
|
|
384: "animation_schedule",
|
|
385: "animation_set_curve",
|
|
386: "animation_set_custom_curve",
|
|
387: "animation_set_delay",
|
|
388: "animation_set_duration",
|
|
389: "animation_set_handlers",
|
|
390: "animation_set_implementation",
|
|
391: "animation_unschedule",
|
|
392: "animation_unschedule_all",
|
|
393: "gbitmap_create_blank",
|
|
394: "graphics_capture_frame_buffer",
|
|
395: "graphics_capture_frame_buffer_format",
|
|
396: "property_animation_create",
|
|
397: "property_animation_create_layer_frame",
|
|
398: "property_animation_destroy",
|
|
399: "property_animation_from",
|
|
400: "property_animation_get_animation",
|
|
401: "property_animation_subject",
|
|
402: "property_animation_to",
|
|
403: "property_animation_update_gpoint",
|
|
404: "property_animation_update_grect",
|
|
405: "property_animation_update_int16",
|
|
406: "gbitmap_create_blank_with_palette",
|
|
407: "gbitmap_get_bounds",
|
|
408: "gbitmap_get_bytes_per_row",
|
|
409: "gbitmap_get_data",
|
|
410: "gbitmap_get_format",
|
|
411: "gbitmap_get_palette",
|
|
412: "gbitmap_set_bounds",
|
|
413: "gbitmap_set_data",
|
|
414: "gbitmap_set_palette",
|
|
415: "gbitmap_sequence_create_with_resource",
|
|
416: "gbitmap_sequence_destroy",
|
|
417: "gbitmap_sequence_get_bitmap_size",
|
|
418: "gbitmap_sequence_get_current_frame_idx",
|
|
419: "gbitmap_sequence_get_total_num_frames",
|
|
420: "gbitmap_sequence_update_bitmap_next_frame",
|
|
421: "gbitmap_create_from_png_data",
|
|
422: "animation_clone",
|
|
423: "animation_get_delay",
|
|
424: "animation_get_duration",
|
|
425: "animation_get_play_count",
|
|
426: "animation_get_elapsed",
|
|
427: "animation_get_reverse",
|
|
428: "animation_sequence_create",
|
|
429: "animation_sequence_create_from_array",
|
|
430: "animation_set_play_count",
|
|
431: "animation_set_elapsed",
|
|
432: "animation_set_reverse",
|
|
433: "animation_spawn_create",
|
|
434: "animation_spawn_create_from_array",
|
|
435: "animation_get_curve",
|
|
436: "animation_get_custom_curve",
|
|
437: "animation_get_implementation",
|
|
438: "launch_get_args",
|
|
439: "menu_layer_create",
|
|
441: "gbitmap_sequence_get_play_count",
|
|
442: "gbitmap_sequence_restart",
|
|
443: "gbitmap_sequence_set_play_count",
|
|
444: "graphics_context_set_antialiased",
|
|
445: "graphics_context_set_stroke_width",
|
|
446: "action_bar_layer_add_to_window",
|
|
447: "action_bar_layer_clear_icon",
|
|
448: "action_bar_layer_create",
|
|
449: "action_bar_layer_destroy",
|
|
450: "action_bar_layer_get_layer",
|
|
451: "action_bar_layer_remove_from_window",
|
|
452: "action_bar_layer_set_background_color",
|
|
453: "action_bar_layer_set_click_config_provider",
|
|
454: "action_bar_layer_set_context",
|
|
455: "action_bar_layer_set_icon",
|
|
456: "action_bar_layer_set_icon_animated",
|
|
457: "gbitmap_sequence_update_bitmap_by_elapsed",
|
|
458: "gbitmap_create_palettized_from_1bit",
|
|
459: "menu_cell_layer_is_highlighted",
|
|
460: "graphics_draw_rotated_bitmap",
|
|
461: "action_bar_layer_set_icon_press_animation",
|
|
462: "text_layer_create",
|
|
463: "text_layer_destroy",
|
|
464: "text_layer_get_content_size",
|
|
465: "text_layer_get_layer",
|
|
466: "text_layer_get_text",
|
|
467: "text_layer_set_background_color",
|
|
468: "text_layer_set_font",
|
|
469: "text_layer_set_overflow_mode",
|
|
470: "text_layer_set_size",
|
|
471: "text_layer_set_text",
|
|
472: "text_layer_set_text_alignment",
|
|
473: "text_layer_set_text_color",
|
|
474: "gdraw_command_draw",
|
|
475: "gdraw_command_frame_draw",
|
|
476: "gdraw_command_frame_get_duration",
|
|
477: "gdraw_command_frame_set_duration",
|
|
478: "gdraw_command_get_fill_color",
|
|
479: "gdraw_command_get_hidden",
|
|
480: "gdraw_command_get_num_points",
|
|
481: "gdraw_command_get_path_open",
|
|
482: "gdraw_command_get_point",
|
|
483: "gdraw_command_get_radius",
|
|
484: "gdraw_command_get_stroke_color",
|
|
485: "gdraw_command_get_stroke_width",
|
|
486: "gdraw_command_get_type",
|
|
487: "gdraw_command_image_clone",
|
|
488: "gdraw_command_image_create_with_resource",
|
|
489: "gdraw_command_image_destroy",
|
|
490: "gdraw_command_image_draw",
|
|
491: "gdraw_command_image_get_bounds_size",
|
|
492: "gdraw_command_image_get_command_list",
|
|
493: "gdraw_command_image_set_bounds_size",
|
|
494: "gdraw_command_list_draw",
|
|
495: "gdraw_command_list_get_command",
|
|
496: "gdraw_command_list_get_num_commands",
|
|
497: "gdraw_command_list_iterate",
|
|
498: "gdraw_command_sequence_clone",
|
|
499: "gdraw_command_sequence_create_with_resource",
|
|
500: "gdraw_command_sequence_destroy",
|
|
501: "gdraw_command_sequence_get_bounds_size",
|
|
502: "gdraw_command_sequence_get_frame_by_elapsed",
|
|
503: "gdraw_command_sequence_get_frame_by_index",
|
|
504: "gdraw_command_sequence_get_num_frames",
|
|
505: "gdraw_command_sequence_get_play_count",
|
|
506: "gdraw_command_sequence_get_total_duration",
|
|
507: "gdraw_command_sequence_set_bounds_size",
|
|
508: "gdraw_command_sequence_set_play_count",
|
|
509: "gdraw_command_set_fill_color",
|
|
510: "gdraw_command_set_hidden",
|
|
511: "gdraw_command_set_path_open",
|
|
512: "gdraw_command_set_point",
|
|
513: "gdraw_command_set_radius",
|
|
514: "gdraw_command_set_stroke_color",
|
|
515: "gdraw_command_set_stroke_width",
|
|
516: "property_animation_create_bounds_origin",
|
|
517: "property_animation_update_uint32",
|
|
518: "gpath_draw_outline_open",
|
|
519: "time",
|
|
520: "menu_layer_set_highlight_colors",
|
|
521: "menu_layer_set_normal_colors",
|
|
522: "menu_layer_set_callbacks",
|
|
523: "menu_layer_pad_bottom_enable",
|
|
524: "status_bar_layer_create",
|
|
525: "status_bar_layer_destroy",
|
|
526: "status_bar_layer_get_background_color",
|
|
527: "status_bar_layer_get_foreground_color",
|
|
528: "status_bar_layer_get_layer",
|
|
529: "status_bar_layer_set_colors",
|
|
530: "status_bar_layer_set_separator_mode",
|
|
531: "difftime",
|
|
532: "time_ms",
|
|
533: "gcolor_legible_over",
|
|
534: "property_animation_update_gcolor8",
|
|
535: "app_focus_service_subscribe_handlers",
|
|
536: "action_menu_close",
|
|
537: "action_menu_freeze",
|
|
538: "action_menu_get_context",
|
|
539: "action_menu_get_root_level",
|
|
540: "action_menu_hierarchy_destroy",
|
|
541: "action_menu_item_get_action_data",
|
|
542: "action_menu_item_get_label",
|
|
543: "action_menu_level_add_action",
|
|
544: "action_menu_level_add_child",
|
|
545: "action_menu_level_create",
|
|
546: "action_menu_level_set_display_mode",
|
|
547: "action_menu_open",
|
|
548: "action_menu_set_result_window",
|
|
549: "action_menu_unfreeze",
|
|
550: "dictation_session_create",
|
|
551: "dictation_session_destroy",
|
|
552: "dictation_session_enable_confirmation",
|
|
553: "dictation_session_start",
|
|
554: "dictation_session_stop",
|
|
555: "smartstrap_attribute_begin_write",
|
|
556: "smartstrap_attribute_create",
|
|
557: "smartstrap_attribute_destroy",
|
|
558: "smartstrap_attribute_end_write",
|
|
559: "smartstrap_attribute_get_attribute_id",
|
|
560: "smartstrap_attribute_get_service_id",
|
|
561: "smartstrap_attribute_read",
|
|
562: "smartstrap_service_is_available",
|
|
563: "smartstrap_set_timeout",
|
|
564: "smartstrap_subscribe",
|
|
565: "smartstrap_unsubscribe",
|
|
566: "connection_service_peek_pebble_app_connection",
|
|
567: "connection_service_peek_pebblekit_connection",
|
|
568: "connection_service_subscribe",
|
|
569: "connection_service_unsubscribe",
|
|
570: "dictation_session_enable_error_dialogs",
|
|
571: "gbitmap_get_data_row_info",
|
|
572: "content_indicator_configure_direction",
|
|
573: "content_indicator_create",
|
|
574: "content_indicator_destroy",
|
|
575: "content_indicator_get_content_available",
|
|
576: "content_indicator_set_content_available",
|
|
577: "scroll_layer_get_content_indicator",
|
|
578: "menu_layer_get_center_focused",
|
|
579: "menu_layer_set_center_focused",
|
|
580: "grect_inset",
|
|
581: "gpoint_from_polar",
|
|
582: "graphics_draw_arc",
|
|
583: "graphics_fill_radial",
|
|
584: "grect_centered_from_polar",
|
|
585: "graphics_text_attributes_create",
|
|
586: "graphics_text_attributes_destroy",
|
|
587: "graphics_text_attributes_enable_paging",
|
|
588: "graphics_text_attributes_enable_screen_text_flow",
|
|
589: "graphics_text_attributes_restore_default_paging",
|
|
590: "graphics_text_attributes_restore_default_text_flow",
|
|
591: "graphics_text_layout_get_content_size_with_attributes",
|
|
592: "layer_convert_point_to_screen",
|
|
593: "layer_convert_rect_to_screen",
|
|
594: "scroll_layer_get_paging",
|
|
595: "scroll_layer_set_paging",
|
|
596: "text_layer_enable_screen_text_flow_and_paging",
|
|
597: "text_layer_restore_default_text_flow_and_paging",
|
|
598: "menu_layer_is_index_selected",
|
|
599: "health_service_activities_iterate",
|
|
600: "health_service_any_activity_accessible",
|
|
601: "health_service_events_subscribe",
|
|
602: "health_service_events_unsubscribe",
|
|
603: "health_service_get_minute_history",
|
|
604: "health_service_metric_accessible",
|
|
605: "health_service_peek_current_activities",
|
|
606: "health_service_sum",
|
|
607: "health_service_sum_today",
|
|
608: "time_start_of_today",
|
|
609: "health_service_metric_averaged_accessible",
|
|
610: "health_service_sum_averaged",
|
|
611: "health_service_get_measurement_system_for_display",
|
|
612: "gdraw_command_frame_get_command_list",
|
|
};
|
|
|
|
function hex(addr) {
|
|
return "0x" + (addr >>> 0).toString(16);
|
|
}
|
|
|
|
function cleanName(name) {
|
|
return name.replace(/[^A-Za-z0-9_]/g, "_");
|
|
}
|
|
|
|
function u32leFromHex(hexstr, byteOffset) {
|
|
const p = byteOffset * 2;
|
|
return parseInt(hexstr.slice(p + 6, p + 8) + hexstr.slice(p + 4, p + 6) + hexstr.slice(p + 2, p + 4) + hexstr.slice(p, p + 2), 16) >>> 0;
|
|
}
|
|
|
|
function searchJson(pattern) {
|
|
const out = r2.cmd("/xj " + pattern).trim();
|
|
if (!out) {
|
|
return [];
|
|
}
|
|
try {
|
|
return JSON.parse(out);
|
|
} catch (e) {
|
|
console.log("Cannot parse /xj output for " + pattern + ": " + e);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
function nameTrampoline() {
|
|
const hits = searchJson(TRAMPOLINE_PATTERN);
|
|
for (const hit of hits) {
|
|
const addr = hit.addr >>> 0;
|
|
r2.cmd("f sym.pebble.jump_to_pbl_function 16 @ " + hex(addr));
|
|
r2.cmd("f sym.pebble.pbl_table_addr 4 @ " + hex(addr + 16));
|
|
r2.cmd("CCu Pebble firmware API trampoline, pbl_table_addr is patched by loader @ " + hex(addr));
|
|
}
|
|
return hits.length;
|
|
}
|
|
|
|
function nameStubs() {
|
|
r2.cmd("e search.align=4");
|
|
const hits = searchJson(STUB_PATTERN);
|
|
let named = 0;
|
|
let unknown = 0;
|
|
for (const hit of hits) {
|
|
const addr = hit.addr >>> 0;
|
|
const data = (hit.data || "").replace(/[^0-9a-fA-F]/g, "").toLowerCase();
|
|
if (data.length < 24) {
|
|
continue;
|
|
}
|
|
const byteOffset = u32leFromHex(data, 8);
|
|
if ((byteOffset & 3) !== 0) {
|
|
continue;
|
|
}
|
|
const index = byteOffset >>> 2;
|
|
const apiName = PEBBLE_API_BY_INDEX[index] || ("unknown_" + index);
|
|
const flagName = "sym.pebble." + cleanName(apiName);
|
|
r2.cmd("f " + flagName + " 12 @ " + hex(addr));
|
|
r2.cmd("af @ " + hex(addr));
|
|
r2.cmd("afn " + flagName + " @ " + hex(addr));
|
|
r2.cmd("CCu Pebble API stub " + apiName + " index=" + index + " offset=0x" + byteOffset.toString(16) + " @ " + hex(addr));
|
|
if (PEBBLE_API_BY_INDEX[index]) {
|
|
named++;
|
|
} else {
|
|
unknown++;
|
|
}
|
|
}
|
|
console.log("Pebble stubs: named=" + named + " unknown=" + unknown + " total=" + hits.length);
|
|
return named;
|
|
}
|
|
|
|
r2.cmd("e search.align=4");
|
|
const trampolines = nameTrampoline();
|
|
const stubs = nameStubs();
|
|
console.log("Pebble trampoline hits: " + trampolines);
|
|
console.log("Pebble stub resolver complete: " + stubs + " named stubs");
|