Obstacles
One of the difficulties associated with analyzing firmware is that firmware binaries do not usually have a standard format and do not segregate code and data in a standard manner like ELF or PE binaries do. The absence of clearly identifiable partitions within firmware binaries that allow for fast and accurate identification and differentiation between code and data is problematic for disassembly, since a disassembler such as Capstone (which is used to identify to identify the CPU architecture by binwalk
when the --disasm
argument is used) or Radare2 will disassemble data (such as ASCII strings) as opcodes and operands.
It appears that this is the case with UBLDM350.BIN
. If binwalk -A
is executed, we see that ARM code is detected fairly uniformly from offset 0x130 to offset 0x4224, a range of 16628 bytes:
$ binwalk -A UBLDM350.BIN
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
304 0x130 ARM instructions, function prologue
792 0x318 ARM instructions, function prologue
1396 0x574 ARM instructions, function prologue
8008 0x1F48 ARM instructions, function prologue
9380 0x24A4 ARM instructions, function prologue
9880 0x2698 ARM instructions, function prologue
9908 0x26B4 ARM instructions, function prologue
10024 0x2728 ARM instructions, function prologue
10320 0x2850 ARM instructions, function prologue
13036 0x32EC ARM instructions, function prologue
13080 0x3318 ARM instructions, function prologue
13196 0x338C ARM instructions, function prologue
13548 0x34EC ARM instructions, function prologue
15912 0x3E28 ARM instructions, function prologue
16872 0x41E8 ARM instructions, function prologue
16932 0x4224 ARM instructions, function prologue
However, when binwalk --disasm --verbose
is run to print the disassembled instructions, the memory address range of the disassembled code is much less than this (0x00
to 0xF5C
= 3932 bytes):
$ binwalk --disasm --verbose UBLDM350.BIN
Scan Time: 2017-05-07 10:56:43
Target File: /home/c/firmware/Philips/10FF2cme_pictureframe/PHILIPS.10FF2M/UBLDM350/UBLDM350.BIN
MD5 Checksum: 15b2dac3ce98d3308d9c6cf47e74eba7
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 ARM executable code, 32-bit, little endian, at least 984 valid instructions
0 0x0 ldr r0, [pc, #0x124]
4 0x4 mcr p15, #0, r0, c9, c1, #0
8 0x8 mov r0, r0
12 0xC mrs r0, apsr
16 0x10 bic r0, r0, #0x1f
20 0x14 orr r0, r0, #0x11
24 0x18 msr cpsr_fc, r0
28 0x1C ldr sp, [pc, #0xf4]
32 0x20 ldr r0, [pc, #0xf4]
36 0x24 add sp, sp, r0
40 0x28 mrs r0, apsr
< snip >
3888 0xF30 lsl ip, ip, #0x16
3892 0xF34 lsr ip, ip, #0x16
3896 0xF38 strh ip, [sp, #0x16]
3900 0xF3C ldrh ip, [sp, #0x14]
3904 0xF40 ldr r0, [sp, #4]
3908 0xF44 ldrb r1, [ip, r0]
3912 0xF48 ldrb r2, [sp, #0x16]
3916 0xF4C eor r1, r2, r1
3920 0xF50 strb r1, [ip, r0]
3924 0xF54 mov r0, #0
3928 0xF58 add sp, sp, #0x1c
3932 0xF5C bx lr
Why is this? A broken instruction causes Capstone to cease disassembly following offset 0xF5C
:
By default, Capstone stops disassembling when it encounters a broken instruction. Most of the time, the reason is that this is data mixed inside the input, and it is understandable that Capstone does not understand this "weird" code.
Typically, you are recommended to dertermine yourself where the next code is, and then continue disassembling from that place.1

Above we see that there are indeed invalid instructions following the instruction at offset 0xF5C
.
Some of the following data is disassembled as code:
00001ba0 bf f9 0a 1c 02 e0 d3 17 02 f0 92 fc 19 1c 10 1c |................|
00001bb0 70 bc 04 bc 10 47 c0 46 30 31 32 33 34 35 36 37 |p....G.F01234567|
00001bc0 38 39 61 62 63 64 65 66 30 31 32 33 34 35 36 37 |89abcdef01234567|
00001bd0 38 39 41 42 43 44 45 46 00 00 00 00 04 d0 4d e2 |89ABCDEF......M.|
00001be0 00 c0 a0 e3 00 c0 8d e5 00 c0 9d e5 2a 00 5c e3 |............*.\.|

Direct execution of the binary likely fails due to the fact that there is no header that provides the kernel program loader the information required to create a process image in memory, such as the entry point and binary layout information.
Options
1. Unicorn
An option for further investigation could be using the Unicorn engine to dynamically analyze successfully disassembled code. See this Q&A for more information:
Unicorn and QEMU: Example use cases to understand the differences
2. Device processor identification
If you have direct access to the hardware, it may prove useful to identify the exact processor/microcontroller, since this will allow you to locate the technical reference manual and datasheet, which will describe in detail the memory layout and instruction set architecture of the device. Knowledge of memory layout will aid in the analysis of the firmware binary.
3. Hex dump analysis
Analysis of a hex dump may allow you to manually identify non-code portions of the firmware. Portions with code only can be sliced out and disassembled by Capstone, r2, or some other disassembler.
4. Visualization
Visualization of the firmware binary using binwalk -E
can give an insight into the overall structure of the binary. An entropy plot allows for fast identification of compressed or regions of contiguous null bytes. binvis.io is a useful source for binary visualization as well.
See also:
Approach to extract useful information from binary file
1. SKIPDATA mode