4

I am trying to reverse engineer a Mickey Mouse toy just for fun but I am stuck. The toy has several buttons that play various phrases and songs. My aim was to see if I can read those songs from the eeprom as the other chip is encased in resin. I was able to read the 2mb bin file and I have tried various softwares for reverse engineering but I didn't find very useful information.

binwalk -A mickey.bin:

    DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
1581594       0x18221A        ARMEB instructions, function prologue

In imHex I was only able to identify this at the start of the file:

Date: 2009-11-09Version:     V06Author:    A\xAAUi\x96/\x00\xD0\xFF8#

In Ghidra I was only able to find this:

                             //
                         // ram 
                         // ram:00000000-ram:001fffff
                         //
                         **************************************************************
                         *                          FUNCTION                          *
                         **************************************************************
                         undefined Reset()
         undefined         r0:1           <RETURN>
                         Reset                                           XREF[1]:     Entry Point(*)  
    00000000 44 61 74 65     ldrbvs     r6,[r4,#-0x144]!
                         **************************************************************
                         *                          FUNCTION                          *
                         **************************************************************
                         undefined UndefinedInstruction()
         undefined         r0:1           <RETURN>
                         UndefinedInstruction                            XREF[1]:     Entry Point(*)  
    00000004 3a 20 32 30     eorccs     r2,r2,r10, lsr r0
                         SupervisorCall                                  XREF[1]:     Entry Point(*)  
    00000008 30              ??         30h    0
    00000009 39              ??         39h    9
    0000000a 2d              ??         2Dh    -
    0000000b 31              ??         31h    1
                         **************************************************************
                         *                          FUNCTION                          *
                         **************************************************************
                         undefined PrefetchAbort()
         undefined         r0:1           <RETURN>
                         PrefetchAbort                                   XREF[1]:     Entry Point(*)  
    0000000c 31 2d 30 39     ldmdbcc    r0!,{r0,r4,r5,r8,r10,r11,sp}
                         DataAbort                                       XREF[1]:     Entry Point(*)  
    00000010 56              ??         56h    V
    00000011 65              ??         65h    e
    00000012 72              ??         72h    r
    00000013 73              ??         73h    s
    00000014 69              ??         69h    i
    00000015 6f              ??         6Fh    o
    00000016 6e              ??         6Eh    n
    00000017 3a              ??         3Ah    :
                         **************************************************************
                         *                          FUNCTION                          *
                         **************************************************************
                         undefined IRQ()
         undefined         r0:1           <RETURN>
                         IRQ                                             XREF[1]:     Entry Point(*)  
    00000018 20 20 20 20     eorcs      r2,r0,r0, lsr #32
                         **************************************************************
                         *                          FUNCTION                          *
                         **************************************************************
                         undefined FIQ()
         undefined         r0:1           <RETURN>
                         FIQ                                             XREF[1]:     Entry Point(*)  
    0000001c 20 56 30 36     ldrtcc     r5,[r0],-r0,lsr #0xc
    00000020 41 75 74 68     ldmdavs    r4!,{r0,r6,r8,r10,r12,sp,lr}^
    00000024 6f 72 3a 20     eorcss     r7,r10,pc, ror #0x4
    00000028 20              ??         20h     

Since I am a beginer I might have not used the reverse engineering software properly.

Here is the bin file: https://easyupload.io/3yyq4x

  • 2
    What is the toy? What are the other chips on the toy? (If there is another chip for storage how do you know the EEPROM contains the songs?) – secfren Mar 12 '23 at 21:19
  • 1
    You're trying to disassemble ASCII, look at the values, that's the version string. look for other bytes – mumbel Mar 13 '23 at 05:56
  • @secfren The toy looks something similar to this link Apart from the eeprom there are just some passive componets and a a chip enclosed in a black blob. I was assuming the songs are in the eeprom since they are in Romanian, that implies that the toys were built in multiple languages. I supposed that the manufacturer used the eeprom for the songs but I'm not sure – George Farcas Mar 13 '23 at 07:08
  • @mumbel what other bytes do you suggest? – George Farcas Mar 13 '23 at 07:13
  • 1
    Inside? PCB? Model? What about the other chips? – secfren Mar 13 '23 at 07:13
  • 2
    Looks like data for me. there are sections with 00 6d db b6 and some more pattern between more varying sections. Assuming that each one of those varying sections is a audio clip. thats what i was able to spot from a quick check on the file. – masterX244 Mar 13 '23 at 08:39
  • Byte structure between 0x6C and 0x127 looks like some sort of index. 2 bytes that are always incrementing, a zero byte and a byte that changes between each "record". before that there is some weird "padding" and a single byte that doesnt seem to match up to anything... – masterX244 Mar 13 '23 at 16:44

1 Answers1

3

Got the file disassembled into the audio segments. Format is pretty simple.

(for further analysis the separated files: https://nplusc.de/mickey.bin-splitted.zip )

File has a index list at 0x6c of 0x29 uint32 offsets, at each offset there is a length field (uint32) and then the raw file.

File format as a 010editor binary template:

byte randomgarbage[0x6b];
local uint64 returnoffset = FTell();
uint32 sizes[0x29];

struct FILE{ uint32 file_size; byte content[file_size]; };

FSeek(returnoffset); local uint i = 0; for(i = 0; i<0x29;i++) { FSeek(sizes[i]); FILE file; }

Used this java program to split the file:

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;

public class MickeyBinSplitter { public static void main(String[] args) { try (RandomAccessFile file = new RandomAccessFile(args[0],"r")) { File out = new File(args[0]+"out"); out.mkdirs(); file.seek(0x6b); //guessed from file reading for(int i=0; i < 0x29;i++) { byte[] swapMe = new byte[4]; file.read(swapMe); ByteBuffer wrapped = ByteBuffer.wrap(new byte[]{swapMe[3],swapMe[2],swapMe[1],swapMe[0]}); // big-endian by default int offsetFile = wrapped.getInt(); System.out.println(offsetFile); long retval = file.getFilePointer();

            file.seek(offsetFile);

            file.read(swapMe);
            wrapped = ByteBuffer.wrap(new byte[]{swapMe[3],swapMe[2],swapMe[1],swapMe[0]}); // big-endian by default
            int lenFile = wrapped.getInt();
            System.out.println(lenFile);
            byte[] innerFile = new byte[lenFile];
            file.read(innerFile);
            file.seek(retval);
            try (RandomAccessFile outRandom = new RandomAccessFile(new File(out, i + &quot;.bin&quot;), &quot;rw&quot;)) {
                outRandom.write(innerFile);
            }
        }

    } catch (FileNotFoundException e) {
        throw new RuntimeException(e);
    } catch (IOException e) {
        throw new RuntimeException(e);
    }

}

}

masterX244
  • 228
  • 1
  • 9
  • Excelent find! I am trying to do the same in imHex for learning purposes. What was your thought process on doing this? What was the first thing you searched? – George Farcas Mar 14 '23 at 09:47
  • scrolling over the file. i got a slightly different wired brain and scrolling over a file often shows me patterns. knowing that it looked like a data flash and not a code flash (and a few similar formats that i twiddled apart) got me to look for stuff that looks like a index/offset table (those often show as a series of increasing values). rest was cross-referencing and guessworks. java program was quickly cobbled together after i had the binary template done (those are useful for quick verify if a guess fits). Nasty traps are when the tables are not really aligned. was off by one byte – masterX244 Mar 14 '23 at 12:16
  • first and that caused me to look at wrong values. the zero bytes in the table pointed me to the offset then – masterX244 Mar 14 '23 at 12:18