1 điểm bởi GN⁺ 2023-10-30 | 1 bình luận | Chia sẻ qua WhatsApp
  • Âm thanh hệ thống khi ghép đôi·kết nối·ngắt kết nối của tai nghe Tozo T6 quá lớn, nên đã giải quyết bằng cách trực tiếp giảm gain của các tệp âm thanh bên trong firmware
  • Chipset được suy đoán thuộc dòng Airoha AB1562, và thông qua ứng dụng AirReps156X đã xác nhận khả năng lấy thông tin chẩn đoán cũng như nạp firmware đã chỉnh sửa
  • Đã chặn lưu lượng kiểm tra cập nhật của ứng dụng Tozo bằng mitmproxy và lấy được liên kết nhị phân firmware của tai nghe từ phản hồi /api/v1/getOtaVersionV3
  • Firmware gồm 2 FotaPackage cho tai nghe trái/phải và 2 FileSystemImage, và trong image hệ thống tệp cần chỉnh sửa, các tệp mp3 được chứa nguyên trạng
  • Sau khi dùng mp3gain để chỉ giảm -19.5dB mà không tái mã hóa mp3 hay thay đổi độ dài, đã thay thế các byte bên trong image rồi flash; thiết bị vẫn hoạt động bình thường và âm thanh nhỏ hơn rất nhiều

Âm thanh hệ thống quá lớn và giả định ban đầu

  • Tai nghe Tozo T6 phát âm thanh mỗi khi ghép đôi, kết nối và ngắt kết nối, và âm lượng này lớn hơn nhiều so với mức người dùng mong muốn
  • Cách giảm vài dB trên toàn dải trong equalizer không giải quyết được vấn đề, và khi gửi email hỏi Tozo thì công ty trả lời rằng họ không thể làm gì
  • Mục tiêu là chỉnh sửa firmware đang chạy trên thiết bị để hạ âm lượng của các tệp âm thanh tương ứng
  • Ban đầu, tác giả tiếp cận với một số giả định
    • Có thể lấy nhị phân firmware của thiết bị trên mạng
    • Firmware có thể có cấu trúc nhị phân dễ hiểu như ELF
    • Các tệp âm thanh được nhúng trong firmware và nếu biết offset cùng độ dài thì có thể sửa
    • Âm thanh có thể ở định dạng đơn giản như PCM
    • Có thể flash firmware đã sửa bằng công cụ dành cho thiết bị hoặc chipset
  • Trên thực tế, nhiều giả định đã sai, và thời gian lại chủ yếu được dùng cho việc thiết lập hạ tầng phân tích như proxy và tìm các đường vòng hơn là reverse engineering thuần túy

Nhận diện thiết bị và chipset

  • Với thiết bị điện tử giá rẻ, thường có nhiều bên và nhiều tầng liên quan
    • Vendor bán sản phẩm dưới thương hiệu, trong trường hợp này là Tozo
    • Có chipset là phần cứng trung tâm chạy firmware
    • Chipset có thể dùng ISA phát sinh từ các công nghệ nền tảng như ARM hoặc MIPS
    • Có thể tích hợp thêm đồng xử lý hoặc chức năng cho các giao tiếp phần cứng
  • Khi disassemble ứng dụng Android của Tozo, tác giả phát hiện Airoha SDK, tham chiếu tới một số mẫu chip cụ thể và các chức năng cơ bản dùng để giao tiếp với thiết bị
  • Từ cộng đồng Reddit /r/airreps về các bản sao AirPods, tác giả tìm được thêm thông tin định hướng và biết tới ứng dụng AirReps156X
  • Ứng dụng AirReps156X dùng Airoha SDK và có thể cung cấp thông tin chẩn đoán cho thiết bị Airoha
  • Khi kết nối thiết bị với ứng dụng này, chuỗi chẩn đoán QW_1562U_SDK1.5.1 được hiển thị, từ đó tác giả xác định chipset của thiết bị thuộc dòng Airoha AB1562
  • AirReps156X cũng có chức năng flash firmware mới, đáp ứng điều kiện quan trọng để nạp firmware đã chỉnh sửa lên thiết bị

Tìm URL firmware từ lưu lượng của ứng dụng Tozo

  • Khi kết nối với tai nghe, ứng dụng Tozo hiển thị phiên bản firmware hiện tại và cho biết đã là bản mới nhất hay chưa
  • Tác giả suy luận rằng ứng dụng đang trao đổi với máy chủ để kiểm tra firmware mới nhất, nên quyết định tìm URL tệp firmware thực tế trong quá trình kiểm tra cập nhật
  • Thay vì đọc hết mã đã decompile theo kiểu phân tích tĩnh, tác giả chọn phân tích động bằng cách trực tiếp quan sát các yêu cầu mạng
  • Một proxy chặn bắt được dựng bằng NIC không dây, hostapdmitmproxy
  • Tozo APK được vá bằng apktooluber apk signer để tin cậy chứng chỉ TLS của mitmproxy trong kho CA người dùng
    • Ứng dụng Android thường mặc định chỉ nhìn kho CA hệ thống
    • Việc vá APK giúp ứng dụng dùng cả kho CA người dùng rồi được ký lại để có thể chạy trên Android
  • Cấu hình proxy bao gồm thiết lập AP, chuyển hướng lưu lượng 80/443 tới cổng mitmproxy bằng iptables, và cấu hình NAT
  • Khi ứng dụng hiển thị “current” cạnh phiên bản firmware, nó gửi yêu cầu tới endpoint /api/v1/getOtaVersionV3, và phản hồi chứa các liên kết file bin firmware cần thiết

Cấu trúc tệp firmware và phân tích

  • Firmware lấy được gồm tổng cộng 4 tệp
    • FotaPackage cho tai nghe trái và phải
    • FileSystemImage cho tai nghe trái và phải
  • Hai image hệ thống tệp là giống hệt nhau, nên các tệp thực sự khác biệt chỉ còn 3: 2 FotaPackage cho trái/phải và 1 image hệ thống tệp
  • Tác giả dùng file, strings, hexdump, binwalk để xác định định dạng và các tệp nhúng bên trong
  • Trong image hệ thống tệp có thấy một số chuỗi tên tệp, nhưng binwalk không tìm ra được các tệp mp3 như kỳ vọng
  • mp3 không có magic number hay footer rõ ràng, nên rất khó xác định chắc chắn offset và độ dài của nó trong một nhị phân tùy ý
    • Phần đầu có thể là 0xFFFF hoặc 0xFFFE
    • Nhưng cả hai đều không đủ đặc trưng để làm dấu hiệu nhận diện tệp
  • Tác giả chuyển hướng sang tìm hiểu định dạng image, với giả định rằng nếu hiểu cấu trúc hệ thống tệp thì sẽ biết được điểm bắt đầu và kết thúc của từng tệp

Phân tích entropy và ROFS

  • Phân tích entropy hữu ích để trực quan hóa phần nào của tệp giống hằng số, nhiễu ngẫu nhiên, văn bản ASCII và các điểm chuyển tiếp giữa chúng
  • Image hệ thống tệp trông có cấu trúc, còn các tệp FotaPackage thì có vẻ đã được nén hoặc mã hóa
  • FotaPackage trái/phải chỉ khác lác đác ở một phần header, phần thân gần như giống nhau, rồi hoàn toàn khác ở khoảng 7KB cuối tệp
  • Tác giả không xác định chính xác khác biệt này có ý nghĩa gì, nhưng kết luận rằng đã có một phép biến đổi không trong suốt được áp dụng, nên khó thu được thông tin hữu ích nếu không bỏ ra nhiều công sức
  • Image hệ thống tệp bắt đầu bằng chuỗi ASCII ROFS
  • Tác giả không tìm được tài liệu công khai hay thông tin định dạng khớp với ROFS, nhưng sau đó phát hiện trong Airoha SDK có triển khai giao diện để đọc image này
  • Có lúc tác giả thử đi theo hướng giải mã FotaPackage, nhưng chỉ xác nhận được rằng SDK không biến đổi firmware trước khi truyền đi, và không thu được kết quả nào thêm

Giảm âm lượng mp3 mà không tái mã hóa

  • Việc tệp âm thanh là mp3 ban đầu bị xem là một rủi ro
    • Trình mã hóa mp3 có rất nhiều tùy chọn, và một bộ giải mã không rõ nguồn gốc có thể không xử lý được một số tệp hợp lệ nhất định
    • Nếu âm thanh phát ngay sau khi kết nối gây lỗi, thiết bị có thể sập trước khi kịp kết nối lại, dẫn tới trạng thái không thể khôi phục
  • Nếu tái mã hóa mp3, độ dài tệp có thể thay đổi, và khi đó có thể phải chỉnh chính xác cả thông tin độ dài trong image hệ thống tệp
  • May mắn là có thể điều chỉnh gain của mp3 mà không cần tái mã hóa, đổi độ dài hay sửa metadata
  • Cách này gần giống như xoay JPEG mà không tái mã hóa, tức là chỉ sửa một phần trong cấu trúc dữ liệu bên trong

Manh mối quyết định từ SDK

  • Khi tìm theo tên chipset, tác giả tìm được một bản sao Airoha SDK, và trong đó có các tệp .mp3 giống hệt âm thanh nghe thấy trên thiết bị
  • Tác giả viết một chương trình Python đơn giản bincontains.py để kiểm tra xem tệp nào được chứa nguyên trạng trong một nhị phân khác
  • Đã xác minh rằng các tệp mp3 trong SDK được đưa vào image hệ thống tệp nguyên vẹn
    • Không bị nén
    • Không bị chia thành các khối
    • Vì vậy có thể tính được offset và độ dài của chúng trong image
  • Tác giả cũng xem sơ qua mã SDK liên quan tới ROFS và không thấy ký hiệu nào gợi ý mạnh về việc có checksum
  • Tới thời điểm này, các điều kiện cần để chỉnh sửa đã đầy đủ mà không cần reverse engineering thêm
    • Có tệp firmware và cách để flash
    • Biết vị trí và độ dài của các tệp mp3 trong image
    • Có thể chỉnh gain mp3 mà không đổi độ dài
    • Có thể giả định rằng chỉ thay đổi một dải byte trong tệp sẽ không làm hỏng metadata của hệ thống tệp

Chỉnh sửa image hệ thống tệp và flash

  • Một script Bash duyệt qua các tệp mp3 trong SDK để tìm các tệp được nhúng trong image hệ thống tệp
  • Sau đó sao chép mp3 được tìm thấy ra tệp tạm rồi dùng mp3gain để giảm gain
  • Mức điều chỉnh được dùng là -19.5dB
  • Sau khi xác nhận mp3 đã sửa có cùng kích thước với bản gốc, tác giả dùng dd để ghi đè các byte tại offset tương ứng trong image hệ thống tệp
  • Image firmware cuối cùng khi diff nhị phân chỉ khác vài byte đúng như dự kiến
  • Firmware đã sửa được flash lên thiết bị, thiết bị vẫn hoạt động bình thường và âm thanh hệ thống trở nên nhỏ hơn rất nhiều so với ban đầu

Kết quả và giới hạn

  • Không cần phải giải được mã hóa firmware hay hiểu đầy đủ định dạng hệ thống tệp ROFS
  • Trên thực tế, phần lớn thời gian reverse engineering lại được dùng cho những đường vòng không trực tiếp cần thiết cho lời giải cuối cùng
  • Nếu việc chỉnh âm lượng âm thanh hệ thống là một tính năng mặc định của thiết bị thì đã không cần tới kiểu chỉnh sửa này
  • Với một thiết bị phát âm thanh, sẽ hợp lý hơn nếu có điều khiển âm lượng ở cấp độ UI áp dụng cho mọi âm thanh mà thiết bị phát ra
  • Trong trường hợp này, việc chỉ giảm gain của các mp3 bên trong image firmware đã đủ để tạo ra một cách lách hiệu quả

1 bình luận

 
GN⁺ 2023-10-30
Ý kiến trên Hacker News
  • Ước gì cũng có ai sửa mặt nạ ngủ Bluetooth của tôi như vậy
    Nhìn chung nó khá ổn, nhưng khi pin yếu hoặc sắp tắt, nó báo điều đó ở âm lượng tối đa
    Ngay trên mặt nạ ngủ cơ đấy

    • Cái đó thật ra khá buồn cười. Có thể tưởng tượng lúc lần đầu biết chuyện thì hẳn đã tức điên thế nào
      Tôi từng dùng một chiếc đồng hồ báo thức bị lỗi tương tự, có tính năng đồng bộ thời gian vô tuyến MSF
      Nhưng mỗi lần nó đồng bộ lại với tín hiệu thời gian MSF, nó phát ra âm thanh giống báo thức trong 2–3 giây, và không thể tắt được
      Lúc nào cũng kêu vào một thời điểm kinh khủng kiểu khoảng 3 giờ sáng, nên cuối cùng tôi mở nó ra, cắt ăng-ten MSF, và ngủ ngon hơn dù biết đồng hồ luôn hơi sai giờ
    • Kẹp tai Bluetooth của tôi hoạt động thế này khi cảnh báo pin yếu: tắt âm thanh đang phát, tạo một khoảng lặng đầy kịch tính, nói “BATTERY LOW. PLEASE CHARGE NOW.”, rồi lại thêm một khoảng lặng đầy kịch tính nữa trước khi trở về hoạt động bình thường
      Trong lúc đó tôi cố bắt kịp xem người bên kia cuộc gọi đã nói gì trong vài giây ấy, nhưng thường không được
      Thông báo này còn tệ hơn nhiều so với không có gì. Trường hợp tệ nhất khi không có cảnh báo là âm thanh bị ngắt và bạn bỏ lỡ lời người kia, còn cái kẹp tai này cố tình tạo ra đúng hiệu ứng đó theo lịch trình nhanh hơn
      Không có lý do gì nó không thể trộn vào luồng âm thanh hiện có bằng một mẫu tiếng bíp không gây khó chịu chẳng hạn. Việc đó mất chưa tới 1 giây, và cũng không tự tạo ra chính vấn đề mà nó đang cố ngăn chặn
      Một hành vi Bluetooth tệ khó tưởng tượng khác là khi dùng chat thoại, toàn bộ âm thanh máy tính thông thường biến mất. Khi chat thoại dùng đầu vào micro, thiết bị Bluetooth chuyển sang chế độ “headset”, chế độ này đổi stereo thành mono và trở thành đầu ra duy nhất được phép trong lúc đầu vào âm thanh đang được cung cấp hoặc có khả năng được cung cấp
      Các ứng dụng không dùng đầu vào âm thanh thì vẫn tiếp tục cố phát ra thiết bị tai nghe Bluetooth không còn tồn tại nữa, nên tất cả đều không phát được tiếng
      Tôi không hiểu vì sao thiết bị phải có nhiều chế độ. Không có lý do gì tôi muốn mất tính năng chỉ vì tác dụng phụ của việc nói chuyện với gia đình. Tôi không hiểu việc phát đồng thời hai tín hiệu âm thanh khác nhau vào hai tai thì khó đến mức nào chỉ vì micro có khả năng đang bật. Thiết bị không dùng Bluetooth xử lý được chuyện này, thậm chí còn chẳng được xem là một tính năng đáng chú ý. Tại sao “tai nghe không tắt khi dùng micro” lại phải là điều đặc biệt?
    • Cuối cùng tôi dùng loa gối có cáp jack 3,5 mm. Tránh được những vấn đề kiểu này với Bluetooth
    • Đó là thiết bị làm gì vậy? Tôi tò mò vì sao khi đi ngủ lại cần kết nối Bluetooth
    • Làm tôi nhớ đến đồng hồ thành phố NNY trong Futurama. Trong cutscene nó hét ở âm lượng tối đa: “THE TIME IS FOUR AM”
  • Hay đấy! Tác giả gốc thật đáng nể vì đã làm đến cùng
    Nhân nói về tai nghe nhét tai quá to, có lẽ tôi gặp vấn đề ngược lại. Tôi dùng tai nghe nhét tai thể thao Bose trên máy chạy bộ ở mức mà tôi thấy là thoải mái và khá dè dặt, nhưng iPhone lại thông báo rằng âm lượng quá cao và tôi đang làm hỏng thính lực
    Điện thoại có đúng không? Nếu đúng thì tôi sẵn sàng hy sinh một chút niềm vui vì sức khỏe đôi tai. Nhưng cũng có giả thuyết khác nghe hợp lý: ở cùng mức âm lượng, chiếc tai nghe này có âm lượng vật lý thực tế thấp hơn rõ rệt so với các sản phẩm khác tôi từng dùng, nên mô hình lười biếng của Apple có thể tạo ra thông báo sai như tôi đang nhận
    Nếu Apple đã xây dựng cơ sở dữ liệu ánh xạ model sản phẩm và thiết lập âm lượng sang âm lượng vật lý thực tế thì tôi xin khen. Nhưng thông báo và mô tả tính năng hoàn toàn không có chi tiết nào nên tôi không tin tưởng, và tôi không muốn khiến việc tập luyện kém thú vị hơn chỉ vì Apple đưa một mô hình tầm bài tập đại học vào sản phẩm thật
    Có ai biết khoa học dữ liệu đứng sau thông báo này có đàng hoàng không?

    • Có đúng hai thứ của Android mà tôi nhớ khi dùng iOS, và cả hai đều liên quan đến việc Bluetooth hoạt động bớt tệ hơn
      Thứ nhất, trên iOS, âm lượng tối thiểu của tai nghe nhét tai Bluetooth của tôi quá lớn. Mọi tai nghe bên thứ ba tôi từng dùng đều vậy, và trên mạng người ta đã phàn nàn suốt 10 năm. EU thậm chí đã thông qua luật yêu cầu sửa, nhưng tiết lộ luôn: chẳng có tác dụng
      Làm ơn, âm lượng tối thiểu trên UI phải được ánh xạ tới số nguyên âm lượng phần cứng 1
      Thứ hai, ứng dụng bên thứ ba không thể đưa nhạc hoặc podcast ra menu duyệt media Bluetooth của ô tô. Trên Android thì được
      Vì vậy trên Android tôi có thể nghe podcast và stream Tidal bằng núm xoay của xe, còn trên iOS thì không
      Tôi còn các phàn nàn khác về Bluetooth. Tại sao Apple Watch của tôi lại đưa stereo ô tô vào danh sách đen? Bluetooth trên iOS phiên bản N và N-1 thật sự rất nhiều lỗi
    • Điện thoại của tôi cũng vậy, chạy Android 5 và nói thật là tôi hầu như không dùng nên chưa cần máy mới cho đến khi nó hỏng, mỗi lần kết nối Bluetooth với xe lần đầu sau khi khởi động lại là nó lại làm trò tương tự
      Đó rõ ràng là một tính năng ngu ngốc. Nếu root được thì hẳn tôi có thể tắt công tắc đó trong một file cấu hình nào đó, nhưng với Samsung Galaxy J1 (2016) thì tôi chưa từng thành công
    • Tôi nghĩ hệ điều hành không thể biết phía bên kia phát ra bao nhiêu dB
      Bose của tôi cũng hoạt động khác nhau tùy chipset Bluetooth. Trên Linux, muốn nghe rõ cái gì thì phải đặt âm lượng 150%
    • Ngay cả nếu Apple có tạo ánh xạ như vậy thì ngay khoảnh khắc phát hành nó đã trở thành dữ liệu lỗi thời
      Nhưng không có lý do gì để tin là họ đã làm việc đó. Nếu nhà sản xuất tai nghe báo cáo dải dB khi kết nối Bluetooth để cho phép tính năng như vậy thì sẽ thú vị, nhưng tôi chưa từng nghe nói có chuyện đó. Khác với jack 3,5 mm, Bluetooth đúng là một lĩnh vực có thể cho phép tính năng như vậy
    • Tai nghe/headphone chống ồn giải quyết được vấn đề này
      Dùng chống ồn thì có thể giữ âm lượng dưới 20% mà vẫn nghe thoải mái, không hành hạ đôi tai
      Trường hợp của tôi, vài năm trước tai bắt đầu đau sau các buổi tập dài, nên tôi nghĩ thông báo của Apple có lẽ đúng. Sau khi dùng chống ồn thì hết hẳn
  • Công việc kiểu này thật sự rất hay. Tự nhiên mẫu tai nghe này trở nên khá thú vị
    Nhân tiện, âm thanh hệ thống do thiết bị Bluetooth phát ra là một trong những yếu tố tạo khác biệt mạnh nhất giữa các sản phẩm. Có cái thì cực kỳ kinh khủng: https://youtu.be/J2wPsH64JEM
    Nhưng tôi chưa từng thấy bài đánh giá hay trang sản phẩm nào cho biết sản phẩm đó phát ra âm thanh như thế nào. Trong khi mỗi ngày phải nghe nhiều lần, lại còn không có cách tắt
    Chỉ riêng việc cho phép thay đổi những âm thanh này thôi cũng có vẻ là một cách khác biệt hóa khá dễ

    • Giá mà có thể giảm tiếng bíp phát/tạm dừng của AfterShokz của tôi
      Khi đeo nút tai trong xưởng ồn ào thì hoàn hảo, nhưng nếu ở văn phòng yên tĩnh, mở nhạc nhỏ để tập trung thì nó gây khó chịu và làm giật mình
      Tôi không hiểu vì sao âm thanh hệ thống lại không tuân theo thiết lập âm lượng
  • Giá mà điện thoại biết được headset đang kết nối là một bộ loa, in-ear monitor, hay tai nghe truyền âm qua xương, v.v.
    Khi dùng bộ loa thường và cố ý bật to để nghe được ở mọi nơi trong nhà, thông báo “âm lượng quá lớn” rất phiền
    Tai nghe truyền âm qua xương cần âm lượng khá lớn mới nghe rõ, nên còn phiền gấp đôi

  • May là đây là mục tiêu Airoha không có mã hóa firmware
    Nếu tò mò thì cũng có template 010 Editor cho định dạng firmware
    https://github.com/ramikg/airoha-firmware-parser

  • Tôi công nhận năng lực, nhưng thật đáng tiếc khi một việc cơ bản như chỉnh âm lượng phát của một tệp lại cần nhiều công sức đến thế
    Không nên phải vất vả đến mức này mới khiến công cụ hoạt động theo ý mình

  • Không phải là “có thể hiểu được”. Tôi đã trả tiền cho sản phẩm, và đây là vấn đề của sản phẩm cần được sửa

  • Đọc bài này xong tôi đã mua một chiếc Tozo T6 cũ, nhìn bề ngoài thì có vẻ được sản xuất khá gần đây, nhưng tôi không tái hiện được
    Ứng dụng Tozo chính thức thậm chí không nhận ra headset, và tôi cũng không xác minh được nó có dùng chipset Airoha, vốn được nhận diện qua hỗ trợ AAC, hay không. Cái của tôi chỉ hỗ trợ SBC
    Có lẽ tôi đã mua phải hàng giả, hoặc bên trong đã có thay đổi sau khi tác giả mua
    Một số tệp âm thanh nghe giống với những tệp có trong phần SDK Airoha không đầy đủ trên Internet, nhưng nó cũng phát các tệp giọng nói mới khác
    Nếu muốn kiểm chứng độc lập kết quả này hoặc vọc thử, AirPods giả có thể là hướng đi tốt hơn

  • Mong có nhiều người phàn nàn hơn về âm thanh hệ thống to và dở tệ

  • Sony WH-1000XM4 của tôi cũng gặp đúng vấn đề tương tự, nhưng có vẻ Sony mã hóa payload firmware rồi giải mã trên thiết bị
    Tôi suýt nữa đã tháo tung nó ra để dump toàn bộ và khám phá, nhưng tay tôi run nên khả năng làm hỏng là quá cao
    Tôi sẵn sàng trả khá nhiều tiền cho một chiếc headset chống ồn có thể hack được