I have pulled the Firmware binary from a PPC and have it loaded into IDA. Now I'm trying to determine what operating system it contains but don't know where to start.
4 Answers
NB: Problem is that such an endeavor is very specific to the file one is looking at. So a lot of common sense and presumably experience is required to deviate from the path outlined here when necessary.
Okay, you have numerous options, and all of us probably have kind of a recipe for this.
- I for one would start with
file
(Windows version here). - Assuming that fails, I would search the web for the hex values of the first 8 to 16 bytes to see what comes up. In addition I would throw in search terms that fit my scenario.
- That not yielding anything, I would proceed to see whether I can convince the tool
strings
to show me anything useful (there is a Windows version of strings at Sysinternals). This may be sufficient already. - However, if the file contains compressed or encrypted blobs, I would now bring in firmware-mod-kit. It'll build straight from SVN (tested it only a few days ago), comes with
binwalk
included and allows to also unpack someinitrd
s which cannot be unpacked by the vanillabinwalk
. Alternatively you can tryfind-firmware.pl
(or in general the set of scripts of which it is part) - Failing all that, I would open the file in a hex editor that supports some kind of binary templates (e.g. 010 Editor or freeware Neo).
... from there I would look for patterns. And that's where it gets really hard to describe how I tick, it's a visual thing. Basically I would be looking for offsets, but the patterns of 00
and non-00
would also tip me off in some cases. Additionally I might use the histogram functionality, provided the hex editor has one, to see whether a particular blob of data is likely to be encrypted or compressed (which both makes for a relatively even distribution of the byte values). Knowing that the platform (PPC) is Big Endian, I would assume that the offsets will also be Big Endian. So that setting would be switched on and then I'll see whether I can decode the meaning of something like a file header. If I can, then I'll check all of the blobs that I find and see whether I can discern some kind of information from them, such as a compression algorithm. For example gzip
has specific lead bytes, whereas raw deflate
doesn't unless the programmer chose to use them. Failing all of that, I would have to assume this is some other compression format for the time being and would use the LZMA SDK as a reference to come up with a working theory which one (usually the binwalk
step from before is responsible to do exactly that). Looking for fingerprints of these I would hopefully be able to extract the blobs that are files in their own right and can be handled by external tools.
If all of those previous methods would fail, I would set out to find a piece of software that is supposed to know the file format to some extent, such as a firmware flasher program which takes the firmware file as input.
NB: If your firmware blob comes from a driver, e.g. in Linux, you would of course start by looking into that driver for clues.
Original answer (before it was clear that this is a firmware binary)
I would start with the file
command (Windows version here, thanks to amccormack - see his comment). It will usually tell you for the well-known executable formats for which OS (and kernel etc) it was built.
Example:
# On an AIX 5.3 machine
$ file python
python: executable (RISC System/6000) or object module not stripped
# Debian 6 on PPC64
$ file python
python: ELF 32-bit MSB executable, PowerPC or cisco 4500, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, with unknown capability 0x41000000 = 0x13676e75, with unknown capability 0x10000 = 0xb0401, stripped
# Ubuntu 10.04, x64
$ file python
python: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped
# Windows
>file C:\Python27\python.exe
C:\Python27\python.exe; PE32 executable for MS Windows (console) Intel 80386 32-bit
-
2See this site if you want to run
file
from windows. It is installed natively on most linux installations. Commented Apr 16, 2013 at 15:45 -
No luck finding it, this is assembly though so I'm not sure it would fall out that easy. I have found dev/tty and dev/lp which seem to point to Unix– gigawattCommented Apr 16, 2013 at 16:00
-
Sorry for the confusion. I have the raw bits that gets loaded into the PowerPC. This isn't a executable at all, just a memory grab from the attached flash. I've put that into Ida Pro which has converted it back into assembly. This is a far as I have made it. I told you I was a Newb. :)– gigawattCommented Apr 16, 2013 at 16:14
-
Yes, this is firmware. Binwalk has been used with no luck and am not familiar with firmware-mod-kit at all.– gigawattCommented Apr 16, 2013 at 16:24
-
Sorry, I see the confusion in my wording, hopefully the edit helped.– gigawattCommented Apr 16, 2013 at 18:27
As 0xC0000022L already stated, strings is really the first step. Since this is a dump you obtained directly from the flash chip, there should be some readable strings (such as those from the bootloader for example), unless it is encrypted.
You mentioned it's a PPC based device, so you can also search for common PPC opcodes (binwalk can do this, specify the -A option); you should see at least some opcodes pop out.
Another thing to check is the entropy of the binary data (binwalk's -E option can do this, as can many other tools). It is typical for firmware to have certain sections (such as the kernel and file system) compressed, and this will show up as separate, very high entropy sections inside the firmware image. Strings and code have a medium-ish entropy. Encrypted data has very high entropy.
The hardware of the device can give you a bit of a clue as well. Devices with very little flash storage (say, 2MB or less) are unlikely to be running a large OS such as Linux for example; they are probably running a smaller RTOS of some kind.
Another thing to take into account is how you dumped the flash, what type of flash chip it is, and the flash chip's data bus. Parallel flash chips operating in 16-bit mode on little-endian systems for example have every two bytes flipped. So the string "ABCD" would be read out as "BADC" if you did a raw read of the chip in 16-bit mode. This would obviously mess up any signature-based analysis and cause strings to look oddly familiar yet simultaneously unreadable.
-
Yeah, I've dug around the strings (in the correct endianness) but haven't seen anything that screams the OS. I'm not sure how the OPcodes will help but I have them all translated thanks to IdaPro.– gigawattCommented Apr 18, 2013 at 17:40
-
Well if there are valid opcodes, at least part of it isn't compressed/encrypted. That code is probably a boot loader or decompressor stub, which may or may not have any information (or even knowledge) of the OS type. I'd look for strings/functionality that might indicate what else is in the firmware.– devttys0Commented Apr 19, 2013 at 3:46
-
Sorry, I'm so new at this I don't know what strings would be of interest. I've mentioned that I've found a /dev/tty and a /dev/lp along with stdin, stdout, and stderr. I just don't know the significance of them.– gigawattCommented Apr 19, 2013 at 11:58
-
As an example, if you see strings that read something like
Decompressing the main image
orDecompressing kernel
would indicate that the code is at least responsible for decompressing other data in the firmware image. It might also reference the specific compression algorithm used, such asLZMA
orGZIP
.– devttys0Commented Apr 20, 2013 at 1:04
It isn't rocket science. IDA is not the tool to use for making this simple determination. Check the strings found in the firmware image. If you can't find any, it may be encrypted and/or compressed in its entirety. In either case, try Binwalk for additional assistance. The type of file system used in the firmware can also be a clue.
Also, there aren't but so many possible choices. Some are (most common in bold):
- Linux (various branches, uLinux, OpenWrt, ...)
- VxWorks
- BSD (various branches, iOS would be one)
- LynxOS
- QNE
- QNX
- Windows CE
- Windows NT embedded
To poster, since you say it may be VxWorks, here's one possible header data structure, as used in the WR54G(S)v5, as documented here.
////////////////////////////////////////////////////////////////
// Linksys VxWorks based firmware image format
#pragma pack(1)
typedef struct _VxFileDescriptor
{
DWORD nFileId_BigEnd; // file type (see below)
DWORD nFileSize_BigEnd;
} VxFileDescriptor, *pVxFileDescriptor;
typedef struct _VxLinksysHeader
{
DWORD nCodePattern;
BYTE cUnknown_4[4];
BYTE cYear;
BYTE cMonth;
BYTE cDay;
BYTE nProductVersion_0;
BYTE nMinorVersion_0;
BYTE cZUnknown_0D;
BYTE cImageFormatVersion[4];
BYTE cZUnknown_12[238];
//
// offset 0x100 -- begining of an secondary header?
//
// After this point, all integers are stored big endian
// and should be read by endian neutral code
// (that is, read as big endian).
//
BYTE nProductVersion_1;
BYTE nMinorVersion_1;
WORD nMajorVersion_1;
BYTE cZUnknown_104[2];
WORD nHeaderSizeBigEnd;
DWORD nChecksumBigEnd;
BYTE cZUnknown_10B[2];
WORD nUnknown_10D;
BYTE cZUnknown_110[0x30];
BYTE cModelName[0x20];
BYTE cVendorName[0x20];
VxFileDescriptor TrailingFiles[8];
// parts of file that follow primary file descriptors
VxFileDescriptor FileDescriptors[8];
// primary file descriptors, immediately follow header
} VxLinksysHeader, *pVxLinksysHeader;
-
1Basically all of the BSDs are also possible choices, actually - probably most notably NetBSD. +1– 0xC0000022L ♦Commented Apr 16, 2013 at 20:33
-
1True! Speaking of BSD derivatives, I was considering listing iOS, Android, and other mobile platforms, as they can be used for embedded systems, and a phone is almost classified as such anyway.– dyastaCommented Apr 17, 2013 at 0:49
-
I'm starting to believe that this is VxWorks but don't know what I'm looking for to definitely say that this VxWorks.– gigawattCommented Apr 18, 2013 at 17:46
-
You'd normally see a Wind River copyright somewhere. If you don't see any plaintext, then you gotta get that image to its plain state for analysis. When I worked on the VxWorks edition of the WRT54G(S), I reversed the VxWorks header format. Perhaps it will be the same or similar, who knows. I updated the answer. Link is here: bitsum.com/openwiking/owbase/WRT54G5_CFE– dyastaCommented Apr 19, 2013 at 4:16
Most operating Systems have some kind of string in it that identifies the os and version. So by looking at the file with a hex editor you can often identify the os. Else you'll need to search for known signatures/footprints.
-
-
1He means a set of bytes, or marker, that are used to identify the image type, or identify data structures within the image. These are often the first field in a data structure definition, though don't have to be.– dyastaCommented Apr 19, 2013 at 4:27