mailto: wangkai0351@gmail.com
【未經贊成禁止轉載】
strings工具獲得該固件編譯過程當中include 的一些c語言代碼文件的路徑和文件名以下api
esp-idf/components/esp32/./heap_alloc_caps.c esp-idf/components/esp32/./ipc.c esp-idf/components/esp32/./intr_alloc.c ieee80211_crypto.c ieee80211_hostap.c ieee80211_ht.c ieee80211_input.c ieee80211_ioctl.c ieee80211_output.c ieee80211_phy.c ieee80211_scan.c ieee80211_sta.c wl_chm.c wl_cnx.c ieee80211_action.c pm.c esp-idf/components/newlib/./locks.c esp-idf/components/nvs_flash/src/nvs_storage.cpp esp-idf/components/nvs_flash/src/nvs_item_hash_list.cpp esp-idf/components/nvs_flash/src/nvs_page.cpp esp-idf/components/nvs_flash/src/nvs_pagemanager.cpp esp-idf/components/spi_flash/./partition.c esp-idf/components/spi_flash/./flash_mmap.c esp-idf/components/tcpip_adapter/./tcpip_adapter_lwip.c esp-idf/components/vfs/./vfs.c esp-idf/components/vfs/./vfs_uart.c main/./bravo.c main/../embedded/dingtalk/base/dt_log.c main/../embedded/dingtalk/base/dt_string.c esp-idf/components/driver/./rtc_module.c esp-idf/components/esp32/./crosscore_int.c esp-idf/components/esp32/./phy_init.c components/fingerprint/./fingerprint.c components/fingerprint/./fingerprint_helper.c components/fingerprint/./userIdpool.c components/hardware/./alc5660.c components/hardware/./fd650b.c components/hardware/./gpio_helper..c components/hardware/./pcf8563.c components/logcache/./dt_log_fireeye.c components/logcache/./dt_log_flash.c components/ota/./ota.c components/ota/./ota_downloader.c components/root/./dt_device.c components/root/./dt_fingerprint.c components/root/./dt_root.c components/root/./dt_lightvoice.c components/root/./dt_login.c components/root/./dt_coredump_upload.c components/wifi/./wifi.c main/../embedded/dingtalk/attend/dt_atdevice_service.c main/../embedded/dingtalk/attend/dt_atdevice_statesync.c main/../embedded/dingtalk/attend/dt_atdevice_uploadcrash.c main/../embedded/dingtalk/attend/dt_atdevice_uploadresp.c main/../embedded/dingtalk/attend/dt_atdevice_usercheck.c main/../embedded/dingtalk/attend/dt_atdevice_usercontext.c main/../embedded/dingtalk/attend/dt_atdevice_userinfo.c main/../embedded/dingtalk/attend/dt_atdevice_userstampcontext.c main/../embedded/dingtalk/attend/dt_atdevice_usertimestamp.c main/../embedded/dingtalk/auth/dt_auth_service.c main/../embedded/dingtalk/base/dt_list.c main/../embedded/dingtalk/base/dt_queue.c main/../embedded/dingtalk/device/dt_device_environment.c main/../embedded/dingtalk/device/dt_device_service.c main/../embedded/dingtalk/lwp/dt_lwp_delivery_reg.c main/../embedded/dingtalk/lwp/dt_lwp_error.c main/../embedded/dingtalk/lwp/dt_lwp_header.c main/../embedded/dingtalk/lwp/dt_lwp_pushlistener.c main/../embedded/dingtalk/lwp/dt_lwp_response.c main/../embedded/dingtalk/lwp/dt_lwp_setting.c tls.dingtalk.com main/../embedded/dingtalk/lwp/dt_lwp_useragent.c main/../embedded/dingtalk/wukong/dt_wukong_noticelist.c main/../embedded/dingtalk/wukong/dt_wukong_service.c main/../embedded/dingtalk/net/dt_net_loop.c main/../embedded/dingtalk/file/dt_file_service.c main/../embedded/dingtalk/file/dt_file_upload_context.c main/../embedded/dingtalk/file/dt_file_upload_service.c main/../embedded/dingtalk/fireeye/dt_fireeye_service.c main/../embedded/dingtalk/fireeye/dt_fireeye_upload_mediaid.c main/../embedded/dingtalk/attend/dt_atdevice_atcmd.c main/../embedded/dingtalk/attend/dt_atdevice_checkresp.c main/../embedded/dingtalk/auth/dt_auth_login_result.c main/../embedded/dingtalk/auth/dt_auth_refresh_token_response.c main/../embedded/dingtalk/base/dt_asyncjob.c main/../embedded/dingtalk/base/dt_asyncqueue.c main/../embedded/dingtalk/base/dt_thread.c main/../embedded/dingtalk/base/dt_timer.c main/../embedded/dingtalk/lwp/dt_lwp_mid.c main/../embedded/dingtalk/lwp/dt_lwp_transaction.c main/../embedded/dingtalk/lwp/dt_lwp_transport.c main/../embedded/dingtalk/wukong/dt_wukong_kickout.c main/../embedded/dingtalk/wukong/dt_wukong_notice.c main/../embedded/dingtalk/fireeye/dt_fireeye_logupcmd.c main/../embedded/dingtalk/lwp/dt_lwp_ask.c main/../embedded/dingtalk/lwp/dt_lwp_connection.c main/../embedded/dingtalk/lwp/dt_lwp_parser.c main/../embedded/dingtalk/net/dt_net_connection.c main/../embedded/dingtalk/net/dt_net_openssl.c esp-idf/components/app_update/./esp_ota_ops.c components/ble/./dt_ble.c components/ble/./dt_npc.c esp-idf/components/bt/bluedroid/device/controller.c esp-idf/components/bt/bluedroid/hci/hci_layer.c esp-idf/components/bt/bluedroid/hci/hci_packet_factory.c esp-idf/components/bt/bluedroid/hci/hci_packet_parser.c esp-idf/components/bt/bluedroid/hci/packet_fragmenter.c esp-idf/components/bt/bluedroid/osi/fixed_queue.c esp-idf/components/bt/bluedroid/osi/future.c esp-idf/components/bt/bluedroid/osi/hash_map.c esp-idf/components/bt/bluedroid/osi/list.c esp-idf/components/bt/bluedroid/stack/btu/btu_task.c esp-idf/components/bt/bluedroid/stack/l2cap/l2c_api.c esp-idf/components/bt/bluedroid/stack/l2cap/l2c_fcr.c esp-idf/components/bt/bluedroid/bta/dm/bta_dm_pm.c esp-idf/components/bt/bluedroid/bta/sys/bta_sys_main.c esp-idf/components/bt/bluedroid/btcore/bdaddr.c esp-idf/components/bt/bluedroid/gki/gki_buffer.c esp-idf/components/bt/bluedroid/hci/hci_hal_h4.c esp-idf/components/bt/bluedroid/stack/btm/btm_ble_bgconn.c esp-idf/components/bt/bluedroid/device/interop.c arch_main.c ea.c ld_fm.c lld.c rwble.c rwbt.c vhci.c intc.c esp-idf/components/driver/./i2c.c esp-idf/components/driver/./i2s.c esp-idf/components/driver/./uart.c esp-idf/components/freertos/./heap_regions.c esp-idf/components/freertos/./queue.c esp-idf/components/freertos/./tasks.c esp-idf/components/freertos/./timers.c esp-idf/components/freertos/./ringbuf.c pp.c lmac.c wdev.c ieee80211_misc.c
從源文件命名來看,咱們從中挑出一些咱們最感興趣的源文件;好比esp-idf/components/路徑下的文件大多屬於官方SDK中的文件,源代碼是公開的,所以這部分代碼很難稱得上使咱們感興趣的。反而,main/../embedded/dingtalk/路徑的文件是釘釘本身開發的,確定是涉及到打卡器業務和服務器通訊的代碼,所以咱們着重從這些源文件匯中挑選咱們初探信息。服務器
好比,咱們挑選這樣一個源文件app
components/root/./dt_login.c
咱們就先用strings的結果來看這個源文件形成的信息泄露。async
on_connect_fail wifi is not connected! connect fail,times=%d device_not_exist! fp num:%d != enrollednum:%d get users version fail. status=%d, code=%.*s, reason=%.*s fingerprint_sync_timestamp, local: %d, remote:%d start full fp sync! dt_get_users_version is requesting, ignore atm_state_sync fail. status=%d, code=%.*s, reason=%.*s atm_state_sync timestamp=%d, code=%.*s, firmware=%.*s, system_key.fwversion:%s, md5=%.*s emit_ota_task {"maxUsers":1000,"maxFP":1000,"maxFA":0,"dev_mac_addr":"%s","dev_local_ip":"%s","router_name":"%s"} kaoqinji dt_update_machine_info do report request on_reg_success failed, invalid parameter, reg=%p reg success, timestamp=%lld (aka "%.*s"), get_rtc_timer: %ld, time(): %ld //ESP_LOGE connect fail long time, restart wifi login_task wifi is not connected! login_task device is not bind! 85A09F60A599F5E1867EAB915A8BB07F 9_%d dingboxM1 dingtalk /s/biz/atcmd /s/logup /push/kickout login_task call login_by_device device_key=%s,sn=%s,active_code=%s,secret=%s received logup cmd! begining to upload logs! atmGetUserInfo atmUploadUserInfo atmEnterFP atmESC atmStateSync atmUploadLog atmEnterMenu atmEnterFA atmEnterFPCancel atmOTA rollback datastr cJSON_Parse succeed, action: %d! recv atcmd, cmd=%.*s, data len=%d retry_login wifi is not connected! login long time fail, restart wifi retry login,times=%d device_not_exist device_secret_invalid login failed, status=%d, code=%.*s, reason=%.*s LOGIN FAIL. should not happen. login ok without login_result login success, uid=%lld dt_get_users_version is requesting, ignore 2 need_auth(), is_wifi_connected: %d parse_cmd on_async_atcmd_rsp on_async_atcmd_rsp on_logupcmd_rsp on_logupcmd_rsp on_async_kickout_rsp on_async_kickout_rsp login_task retry_login on_connect_fail on_discon nected on_disconnected on_connected need_auth set_systemtime_on_reg_success on_async_login_rsp on_async_login_rsp dt_update_machine_info on_atm_state_sync dt_get_users_version on_atm_get_users_version dt_on_device_not_exist upload coredump error!
咱們看到上面包含了一些debug打印信息的流出,所以咱們考慮這些debug信息應該是打印到串口的。咱們固然很是想看到這些debug信息了。tcp
上面這句話說的不許確,上述strings工具輸出的敏感信息字符串主要分爲幾類函數
1. esp32 SDK自己自帶的調試信息,有 #ifndef BOOTLOADER_BUILD #define ESP_LOGE //error錯誤 #define ESP_LOGW //warning警告 #define ESP_LOGI //info信息 #define ESP_LOGD //debug模式 #define ESP_LOGV // 這幾類 這些調試信息可能會由串口輸出,這類調試信息格式如 [0;32mI (%d) %s: SPI Speed : %s [0;32mI (%d) %s: SPI Mode : %s [0;32mI (%d) %s: SPI Flash Size : %s bravo_1.0.2-90-gcfa4912 [0;32mI (%d) %s: ESP-IDF %s 2nd stage bootloader 2. 釘釘本身開發日誌記錄功能,好比 device_key=%s,sn=%s,active_code=%s,secret=%s 這些日誌記錄是都要寫到flash中存儲起來,以便於在聯網的時候可以upload到服務器 3. 函數名 4. 斷言 5. 宏定義
ESP32 有 3 個 UART 接口,即 UART0、UART1 和 UART2。工具
查閱《ESP32 技術規格書》版本2.1可知oop
U0RXD 40 號引腳ui
U0TXD 41 號引腳debug
U1RXD 28 號引腳
U1TXD 29 號引腳
U2RXD 25 號引腳
U2TXD 27 號引腳
到PCB上看看,這三對引腳有沒有露出來,若是有任意一對引腳引到了PCB的焊盤上,那麼極可能就是這個PCB的串口調試端口。
下面,嘗試猜想復原一下ESP32(xtensa)+FreeRTOS的符號表(symbol table),我在固件的bin文件中發現瞭如下的感興趣段落。根據個人經驗,符號表就應該長成一個表格的樣子,規規矩矩,對齊工整,因此我猜想如下段落很像是符號表。
00000060 01 00 00 00 36 2b 0d 40 79 28 0d 40 7e 28 0d 40 |....6+.@y(.@~(.@| 00000070 d5 28 0d 40 07 2b 0d 40 05 2b 0d 40 b0 2a 0d 40 |.(.@.+.@.+.@.*.@| 00000080 d4 2a 0d 40 60 2c 0d 40 09 29 0d 40 4a 2c 0d 40 |.*.@`,.@.).@J,.@| 00000090 55 2c 0d 40 60 2c 0d 40 60 2c 0d 40 60 2c 0d 40 |U,.@`,.@`,.@`,.@| 000000a0 09 29 0d 40 09 29 0d 40 09 29 0d 40 09 29 0d 40 |.).@.).@.).@.).@| 000000b0 09 29 0d 40 09 29 0d 40 09 29 0d 40 55 2c 0d 40 |.).@.).@.).@U,.@| 000000c0 09 29 0d 40 09 29 0d 40 09 29 0d 40 3f 2c 0d 40 |.).@.).@.).@?,.@| 000000d0 09 29 0d 40 55 2c 0d 40 09 29 0d 40 09 29 0d 40 |.).@U,.@.).@.).@| 000000e0 ee 28 0d 40 09 29 0d 40 09 29 0d 40 09 29 0d 40 |.(.@.).@.).@.).@| 000000f0 09 29 0d 40 09 29 0d 40 09 29 0d 40 09 29 0d 40 |.).@.).@.).@.).@|
符號表能夠簡單理解爲函數的入口地址和函數名的存儲起始地址一一對應的關係,以下表
函數名起始地址1 | 函數地址1 |
---|---|
函數名起始地址2 | 函數地址2 |
函數名起始地址3 | 函數地址3 |
挑出了固件bin文件的一段
0002bf10 73 79 6e 63 5f 67 65 74 5f 61 6c 6c 5f 75 73 65 |sync_get_all_use| 0002bf20 72 69 6e 66 6f 5f 72 73 70 00 00 00 6f 6e 5f 61 |rinfo_rsp...on_a| 0002bf30 73 79 6e 63 5f 67 65 74 5f 61 6c 6c 5f 75 73 65 |sync_get_all_use| 0002bf40 72 69 6e 66 6f 5f 72 73 70 00 00 00 64 74 5f 72 |rinfo_rsp...dt_r| 0002bf50 65 73 79 6e 63 5f 66 61 69 6c 65 64 5f 75 73 65 |esync_failed_use| 0002bf60 72 73 00 00 64 74 5f 72 65 73 79 6e 63 5f 66 61 |rs..dt_resync_fa| 0002bf70 69 6c 65 64 5f 75 73 65 72 73 00 00 6f 6e 5f 61 |iled_users..on_a| 0002bf80 73 79 6e 63 5f 61 74 6d 5f 67 65 74 75 73 65 72 |sync_atm_getuser| 0002bf90 69 6e 66 6f 5f 61 63 74 69 6f 6e 00 6f 6e 5f 67 |info_action.on_g| 0002bfa0 65 74 5f 75 73 65 72 69 6e 66 6f 5f 62 79 5f 69 |et_userinfo_by_i| 0002bfb0 64 73 5f 72 73 70 00 00 64 74 5f 66 69 6e 67 65 |ds_rsp..dt_finge|
on_async_get_all_users
是一個函數名,它的起始存儲地址是0x0002bf20+c,固然該地址是在固件中的絕對地址(帶有偏移)。
dt_resync_failed_users
也是一個函數名,它的起始存儲地址是0x0002bf40+c。
on_async_atm_getuserinfo_action
也是一個函數名,它的起始存儲地址是0x0002bf70+c。
on_get_userinfo_by_ids_rsp
也是一個函數名,它的起始存儲地址是0x0002bf90+c。
從flash的絕對地址上能夠看出,
addr(dt_resync_failed_users
)-addr(on_async_get_all_users
)=0x20
addr(on_async_atm_getuserinfo_action
)-addr(dt_resync_failed_users
)=0x30
addr(on_get_userinfo_by_ids_rsp
)-addr(on_async_atm_getuserinfo_action
)=0x20
這樣相減,就減掉了它們都包含的偏移地址常數。
因此符號表中,
addr(函數名起始地址2)-addr(函數名起始地址1)=0x20 addr(函數名起始地址3)-addr(函數名起始地址2)=0x30 addr(函數名起始地址4)-addr(函數名起始地址3)=0x20
或者,咱們再來看一簇gpio配置相關的函數
00026ff0 6f 5f 6e 75 6d 3a 25 75 1b 5b 30 6d 0a 00 00 00 |o_num:%u.[0m....| 00027000 67 70 69 6f 5f 69 73 72 5f 72 65 67 69 73 74 65 |gpio_isr_registe| 00027010 72 00 00 00 67 70 69 6f 5f 69 6e 73 74 61 6c 6c |r...gpio_install| 00027020 5f 69 73 72 5f 73 65 72 76 69 63 65 00 00 00 00 |_isr_service....| 00027030 67 70 69 6f 5f 69 73 72 5f 68 61 6e 64 6c 65 72 |gpio_isr_handler| 00027040 5f 61 64 64 00 00 00 00 67 70 69 6f 5f 6f 75 74 |_add....gpio_out| 00027050 70 75 74 5f 64 69 73 61 62 6c 65 00 67 70 69 6f |put_disable.gpio| 00027060 5f 6f 75 74 70 75 74 5f 65 6e 61 62 6c 65 00 00 |_output_enable..| 00027070 67 70 69 6f 5f 73 65 74 5f 64 69 72 65 63 74 69 |gpio_set_directi| 00027080 6f 6e 00 00 67 70 69 6f 5f 73 65 74 5f 70 75 6c |on..gpio_set_pul| 00027090 6c 5f 6d 6f 64 65 00 00 67 70 69 6f 5f 73 65 74 |l_mode..gpio_set| 000270a0 5f 6c 65 76 65 6c 00 00 67 70 69 6f 5f 69 6e 74 |_level..gpio_int| 000270b0 72 5f 64 69 73 61 62 6c 65 00 00 00 67 70 69 6f |r_disable...gpio| 000270c0 5f 69 6e 74 72 5f 65 6e 61 62 6c 65 5f 6f 6e 5f |_intr_enable_on_| 000270d0 63 6f 72 65 00 00 00 00 67 70 69 6f 5f 73 65 74 |core....gpio_set| 000270e0 5f 69 6e 74 72 5f 74 79 70 65 00 00 67 70 69 6f |_intr_type..gpio| 000270f0 5f 70 75 6c 6c 64 6f 77 6e 5f 64 69 73 00 00 00 |_pulldown_dis...| 00027100 67 70 69 6f 5f 70 75 6c 6c 64 6f 77 6e 5f 65 6e |gpio_pulldown_en| 00027110 00 00 00 00 67 70 69 6f 5f 70 75 6c 6c 75 70 5f |....gpio_pullup_| 00027120 64 69 73 00 67 70 69 6f 5f 70 75 6c 6c 75 70 5f |dis.gpio_pullup_|
編號 | 函數名 | 函數名的起始存儲地址 | 和前一個函數名地址的偏移 |
---|---|---|---|
1 | gpio_isr_register | 0x00027000 | |
2 | gpio_install_isr_service | 0x00027010+4 | 0x14 |
3 | gpio_isr_handler_add | 0x00027030 | 0x1c |
4 | gpio_output_disable | 0x00027040+8 | 0x12 |
5 | gpio_output_enable | 0x00027050+c | 0x14 |
6 | gpio_set_direction | 0x00027070 | 0x14 |
這簇函數給了咱們5條證據來複原符號表,應該干擾更小了,結果更準確了。