• 342 days later .... Magics of Kaitai Struct

    dan ksz10/10/2019 at 13:12 0 comments

    Due to some personal circumstances and then to the COVID-19 confinement, I didn't find the time to work effectively on Tsukuyomi and also to update the project logs. 

    Nevertheless in the past log I've reached a good milestone in understanding the Lunii image format, which lead me to: "I have to create python script to parse the Lunii images contents".

    Then thanks to a HAM Radio Project I discovered the Holy Graal of binary parsing: Kaitai Struct.

    Before starting this log It worth noting that thanks to a message in the Public Chat I came a cross an other project https://github.com/marian-m12l/studio that build a complete and advanced application written in JAVA to update Lunii through the USB. Unfortunately I didn't succeed yet to use it but the project seems to contains valuable information about the format of Lunii Image, things that I'm intending to take off if I'm blocked somewhere. 

    1. Falling in Love with Kaitai Struct

    Kaitai Struct basically defines a declarative language to describe binary data structures within a .ksy file and then compile it into source files of your preferred programming languages. 

    $ ksc --target python kaitai-struct/lunii.ksv

    So after playing with Kaitai Struct in this powerful online IDE using some small portions of Lunii image dumps and also locally with Kaitai Struct Compiler (KSC) and Kaitai Struct Vsualizer  (KSV) by using the whole Lunii image dump, I construct iteratively a first description of Lunii image format in Kaitai Struct Language lunii.ksy , that consist of 3 principal structures: content_struct, story_struct and node_struct. It also import Kaitai Struct definitions of Bitmap and Wav files that I copied from Kaitai Struct Formats Library repository that host a wonderful amount of format description in Kaitai Struct Language.

    a. content_struct

    In Lunii image I found out that the content from 0 up the offset 0x030D_4000 contains no useful information beside the version and some system medias (Battery, Error, USB ...)  So I decided to ignore it and just call it Header. 

    meta:
      id: lunii
      file-extension: lunii
      endian: be
      imports:
        - bmp
        - wav
    seq:
       - id: header
         size: fileoffset
       - id: contents
         type: content_struct
    instances:
       fileoffset:
         value: 0x30D4000

    Starting from 0x030D_4000 address useful things start: the definition of the content especially the value of number of stories and stories information (start_address and size).

    content_struct:
        seq:
          - id: nbr_stories
            type: u2
          - id: stories
            type: story_struct
            repeat: expr
            repeat-expr: nbr_stories

    b. story_struct

    Stories information contains the start address and size values in Sector unit (512 Bytes) next to value that I have to figure out but I called it unknown

    In order to calculate more easily a precise address of the story fields (needed more further), I had to reference the absolute location of the start address in special variable called abs_start_address.

      story_struct:
        seq:
          - id: start_address
            type: u4
          - id: size
            type: u4
          - id: unknown
            type: u4
        instances:
          abs_start_address:
            value: _root.fileoffset + (start_address * 0x200)
          story_info:
            pos: abs_start_address
            type: story_info_struct

    So the story_info_struct define a story by a number of nodes, a boolean (that I believe refers to factory_disabled), a uint16_t for the version of the story., and after some zeros story nodes start.

    A node is a story media storage unit, that contains the data for the Bitmap and/or the Audio Wav. 

      story_info_struct:
        seq:
          - id: nbr_nodes
            type: u2
          - id: factory_disabled
            type: u1
          - id: version
            type: u2
          - id: padding
            size: 0x200 - 5 #TODO this must be reworked
          - id: nodes
            type: node_struct
            repeat: expr
            repeat-expr: nbr_nodes

    c. node_struct

    The node struct contains the start addresses and sizes of the media in addition to a structure that I called navigation_struct which I believe it holds information...

    Read more »

  • Days 3,4,5: Eureka, sound and images found!

    dan ksz10/04/2019 at 09:49 1 comment

    1. Toolchain not found

    After stepping away few days far from my PC for family reason, I resumed my activities on the Tsykuyomi project.
    So I started by reading the https://github.com/WHhkwong/SIPI_Bear_playback code and looking for a SNC7001A Toolchain/SDK to build it. But unfortunately the only website that propose it for download is login/password protected.

    So I turned to the SDCard dump meanwhile finding a way to get the toolchain.

    2. Uninteresting hidden fat12 partition

    I started by opening the dump with 'testdisk' utility to look for a hidden partition or disk structure. so I found only one "fat12" partition at address 0xD920 0000 :

    D920 0000: EB 3C 90 4D 53 44 4F 53  35 2E 30 00 02 08 08 00  .<.MSDOS 5.0.....  
    D920 0010: 02 00 02 00 50 F8 08 00  3F 00 FF 00 00 00 00 00  ....P... ?.......  
    D920 0020: 00 00 00 00 80 01 29 22  8E 62 BC 4E 4F 20 4E 41  ......)" .b.NO NA  
    D920 0030: 4D 45 20 20 20 20 46 41  54 31 32 20 20 20 33 C9  ME    FA T12   3.  
    D920 0040: 8E D1 BC F0 7B 8E D9 B8  00 20 8E C0 FC BD 00 7C  ....{... . .....|  

    And more further I found the content of uninteresting files (pdf, link, ...) which appears anyway in the virtual storage media disk when I connect Lunii to the PC.

    3. Comparing the dumps

    So by analyzing the dumps of the sdcard before and after adding a new "Story" to Lunii -Thanks to vbindiff- , I found out very interesting things:

    1. Bitmap Image files with "BM8" or "BM6" magic at specific addresses

     $ hexdump -C disk-dump-0| grep -e BM6 -e BM8
    00000600  42 4d 38 84 03 00 00 00  00 00 36 00 00 00 28 00  |BM8.......6...(.|
    00038c00  42 4d 38 84 03 00 00 00  00 00 36 00 00 00 28 00  |BM8.......6...(.|
    00071200  42 4d 36 84 03 00 00 00  00 00 36 00 00 00 28 00  |BM6.......6...(.|
    000a9800  42 4d 38 84 03 00 00 00  00 00 36 00 00 00 28 00  |BM8.......6...(.|
    030ee000  42 4d 38 84 03 00 00 00  00 00 36 00 00 00 28 00  |BM8.......6...(.|
    03126600  42 4d 38 84 03 00 00 00  00 00 36 00 00 00 28 00  |BM8.......6...(.|
    0315ec00  42 4d 38 84 03 00 00 00  00 00 36 00 00 00 28 00  |BM8.......6...(.|
    03197200  42 4d 38 84 03 00 00 00  00 00 36 00 00 00 28 00  |BM8.......6...(.|
    031cf800  42 4d 38 84 03 00 00 00  00 00 36 00 00 00 28 00  |BM8.......6...(.|
    03207e00  42 4d 38 84 03 00 00 00  00 00 36 00 00 00 28 00  |BM8.......6...(.|
    03240400  42 4d 38 84 03 00 00 00  00 00 36 00 00 00 28 00  |BM8.......6...(.|
    03278a00  42 4d 38 84 03 00 00 00  00 00 36 00 00 00 28 00  |BM8.......6...(.|
    032b1000  42 4d 38 84 03 00 00 00  00 00 36 00 00 00 28 00  |BM8.......6...(.|
    032e9600  42 4d 38 84 03 00 00 00  00 00 36 00 00 00 28 00  |BM8.......6...(.|
    03321c00  42 4d 38 84 03 00 00 00  00 00 36 00 00 00 28 00  |BM8.......6...(.|
    0335a200  42 4d 38 84 03 00 00 00  00 00 36 00 00 00 28 00  |BM8.......6...(.|
    03392800  42 4d 38 84 03 00 00 00  00 00 36 00 00 00 28 00  |BM8.......6...(. 
    ...

    2. WAV files with "RIFF" magic

    $ hexdump -C disk-dump-0 | grep RIFF
    03a9e800  52 49 46 46 6e dd 02 00  57 41 56 45 66 6d 74 20  |RIFFn...WAVEfmt |
    03acc600  52 49 46 46 6c e5 03 00  57 41 56 45 66 6d 74 20  |RIFFl...WAVEfmt |
    03b0ac00  52 49 46 46 7c 0b 03 00  57 41 56 45 66 6d 74 20  |RIFF|...WAVEfmt |
    03b3b800  52 49 46 46 46 51 02 00  57 41 56 45 66 6d 74 20  |RIFFFQ..WAVEfmt |
    03b60a00  52 49 46 46 a6 19 02 00  57 41 56 45 66 6d 74 20  |RIFF....WAVEfmt |
    03b82400  52 49 46 46 b4 2c 02 00  57 41 56 45 66 6d 74 20  |RIFF.,..WAVEfmt |
    03ba5200  52 49 46 46 82 09 02 00  57 41 56 45 66 6d 74 20  |RIFF....WAVEfmt |
    03bc5c00  52 49 46 46 20 10 01 00  57 41 56 45 66 6d 74 20  |RIFF ...WAVEfmt |
    03bd6e00  52 49 46 46 26 5e 01 00  57 41 56 45 66 6d 74 20  |RIFF&^..WAVEfmt |
    03bece00  52 49 46 46 c2 98 01 00  57 41 56 45 66 6d 74 20  |RIFF....WAVEfmt |
    03c06800  52 49 46 46 26 90 01 00  57 41 56 45 66 6d 74 20  |RIFF&...WAVEfmt |
    03c1fa00  52 49 46 46 26 13 01 00  57 41 56 45 66 6d 74 20  |RIFF&...WAVEfmt |
    03c30e00  52 49 46 46 ce 28 b0 00  57 41 56 45 66 6d 74 20  |RIFF.(..WAVEfmt |
    04733800  52 49 46 46 8c 27 be 00  57 41 56 45 66 6d 74 20  |RIFF.'..WAVEfmt |
    05316000  52 49 46 46 a6 1f 01 00  57 41 56 45 66 6d 74 20  |RIFF....WAVEfmt...
    Read more »

  • Day2: more exploration ...

    dan ksz09/24/2019 at 17:23 0 comments

    1. Datasheet.

    So thanks to the datasheet, we know now that Lunii chipset is based on a 16bit DSP core and I also found out that the 10 pts connector is belonging to ICE-Debug (very known in the arduino/avr world) and not for UART or SWD.

    Unfortunately I don't have an ICE-Debug probe. Maybe I have to consider to buy one if I'm stuck.

    On the other hand according to the chip pinout, the UART seems to be on p4.10 and p4.11 lines which I have to trace to see if I can still hook through a Logic Analyzer.

    2. Googling

    Some googling about the chip name lead me to an interesting paper about reverse engineering a toy called "Teddy Ruxpin" which it is based on the same Sonix chip SNC7001A.

    The paper contains useful information about the proprietary audio format "AU".

    @Frederic Renet who just joined the project point me also to an interesting code in github that contains code which we believe it for the SNC7001A firmware. But we don't know how we can build/flash it.

    3. SDCard Dump

    I successfully dumped the SDCard (I will upload the dump somewhere tomorrow). The size of the dump is 8G. but I found useful raw data only starting from address 0x03ad2000

    $ hexdump -C lunii.dump
    
    03ad2000  05 00 07 00 0a 00 04 00  fb ff f4 ff 00 00 03 00  |................|
    03ad2010  ff ff 09 00 08 00 03 00  0c 00 04 00 fe ff fc ff  |................|
    03ad2020  ff ff 11 00 06 00 01 00  fd ff 00 00 01 00 0a 00  |................|
    03ad2030  18 00 0b 00 11 00 12 00  12 00 05 00 ff ff f7 ff  |................|
    03ad2040  17 00 0f 00 13 00 13 00  06 00 03 00 16 00 21 00  |..............!.|
    03ad2050  24 00 11 00 f9 ff 0f 00  f4 ff ec ff 18 00 03 00  |$...............|
    03ad2060  ed ff df ff 2c 00 29 00  00 00 09 00 02 00 e8 ff  |....,.).........
    

    =====

    Next Steps

    1. Looking for SNC7001A Toolchain/SDK.

    2. Try to find the UART.

    3. Try to buy a ICE-Debug.

    4. Learn more about Sonix proprietary audio format.

    5. Analyze more deeply the sdcard dump.

  • Day1: exploring ...

    dan ksz09/23/2019 at 15:48 3 comments

    I started the project by just exploring the Lunii box physically and connect it to a Linux workstation. so I noticed the following:

    1. When the box usb is plugged into a linux system, lsusb and dmesg gives :

    $ lsusb
    ...
    Bus 001 Device 016: ID 0c45:6820 Microdia
    ...

    And a media storage is also appearing:

    $ dmesg | tail -30

    $ dmesg | tail -30
    ...
    667105.143680] usb 1-2: new high-speed USB device number 17 using xhci_hcd
    [667105.616668] usb 1-2: New USB device found, idVendor=0c45, idProduct=6820
    [667105.616671] usb 1-2: New USB device strings: Mfr=0, Product=1, SerialNumber=1
    [667105.616674] usb 1-2: Product: USB2.0 DSP
    [667105.616676] usb 1-2: SerialNumber: USB2.0 DSP
    [667105.618045] usb-storage 1-2:1.0: USB Mass Storage device detected
    [667105.618551] scsi host4: usb-storage 1-2:1.0
    [667106.628045] scsi 4:0:0:0: Direct-Access     SONiX    SNC7001A USBDisk 0.01 PQ: 0 ANSI: 0 CCS
    [667106.628239] sd 4:0:0:0: Attached scsi generic sg3 type 0
    [667106.628770] sd 4:0:0:0: [sdd] 20480 512-byte logical blocks: (10.5 MB/10.0 MiB)
    [667106.629015] sd 4:0:0:0: [sdd] Write Protect is off
    [667106.629016] sd 4:0:0:0: [sdd] Mode Sense: 03 00 00 00
    [667106.629268] sd 4:0:0:0: [sdd] No Caching mode page found
    [667106.629270] sd 4:0:0:0: [sdd] Assuming drive cache: write through
    [667106.634987]  sdd:
    [667106.636788] sd 4:0:0:0: [sdd] Attached SCSI removable disk
    

    2. After unboxing Lunii, the chipset/SoC appears to be an obscure Chinese chip called Sonix. But unfortunately the exact part number cannot be read. It was maybe intentionally obfuscated.



    Thanks to dmesg (see above) we know that the SoC is a Sonix SNC7001A. And a datasheet can be found here: here

    3. In the PCB we can identify an SDCard (surrounded in red in picture below). But it seems to be soldered to the PCB, because it's not eject-able.

    We can also identify a 10pts connector (surrounded in green in picture below) that I hope it can handle signals to UART and SWD.


    ====
    Next Steps

    1. Extract the SDCARD and analyze its content
    2. Hook a digital analyzer on the 10pts connector to probe UART.
    3. Read the datasheet.