Giter Site home page Giter Site logo

protyposis / yi-mirrorless-firmware-tools Goto Github PK

View Code? Open in Web Editor NEW
45.0 16.0 7.0 93 KB

Firmware tools / unpacker for the YI M1 mirrorless camera

License: GNU General Public License v3.0

JavaScript 100.00%
xiaomi yi mirrorless camera firmware region-change packer unpacker

yi-mirrorless-firmware-tools's Introduction

YI M1 Mirrorless Camera Firmware Tools

A firmware unpacker & repacker for YI M1 firmware files. Parses the section headers of a firmware file, extracts the sections into separate files, and splits and decompresses the firmware code section. It can also change the region of firmware files between Chinese (CN) to International (INT) to install the international firmware on Chinese models and vice versa.

Requirements: Node.js & npm (recommended: v8.10.0 LTS)

Usage:

  1. npm install
  2. Download firmware
  3. Run any of the supported commands
    • npm run unpack /path/to/firmware.bin to unpack the firmware file into separate (decompressed) files
    • npm run repack /path/to/firmware.bin repacks unpacked data into a flashable firmware file (needs the .unpack metadata file generated by the unpack command) (flashing of generated file not tested yet!!!)
    • npm run flipregion /path/to/firmware.bin to change the region between CN and INT

The output will be a number of files (usually 4) named firmware.bin.{sectionNumber}[.{sectionId}].

ATTENTION: the firmware decompression/compression is not yet 100% correct, do not attempt to flash a repacked firmware file or it may damage the camera!

Firmware analysis

Firmware files consist of 4 sections.

Section Number Section Id Size Description
0 none variable, ~7 MB Most probably the actual firmware code. Contains two sections with 0x1000 byte length each, followed by 3 LZSS-compressed data sections).
1 ND1 variable, ~4 MB Offset 0x1600000. Memory image that contains resources like bitmaps, fonts, and texts in different languages
2 IPL 128 kB, 0x20000 byte Bootloader (Initial Program Loader)
3 PTBL 4 kB, 0x1000 byte Partition table, unknown format

Section headers

The section headers inside the firmware file are simple strings with a length of 256 byte (0x100). Examples from FW 2.9.1-int:

LENGTH=7366656 C59Y1 VER=M1INT DVR=Ver1.37 SUM=937214718 ND1 IPL PTBL
ND1 LENGTH=4197888 C59Y1 VER=M1INT DVR=Ver1.37 SUM=299791776 OFFSET=23068672
IPL LENGTH=131072 C59Y1 VER=M1INT DVR=Ver1.37 SUM=5714438
PTBL LENGTH=4096  C59Y1 VER=M1INT SUM=5181

The LENGTH is the length in bytes of the following section body. SUM is a simple checksum calculated by summing all bytes. OFFSET seems to be an offset in the camera's memory space to which the section is written. The first header has the IDs of the following headers appended. All following headers start with their ID.

Hardware & Software Identification

Tons of interesting strings regarding the system can be found by runnings the Unix strings utility against the decompressed firmware. Some interesting strings regarding the hardware:

Section 0 / System

  • C:/XC_ODM/sdk/SDK_selfcheck/src/EV9x_DevEnv/btstack/bluesdk
  • BCM4343A1_001.002.009.0043.0178 -> Wifi radio?
  • BCM4343WA1 37.4MHz Murata Type-1FJ BT4.1 OTP-BD-0043 -> Bluetooth radio?
  • Copyright (c) 2009-2010 Tokyo Electron Device Ltd
  • Broadcom BCM.%s 802.11 Wireless Controller %s
  • il0macaddr=00:90:4c:c5:12:38 -> Epigram MAC (Broadcom)
  • bcm943430wlselgs_20150609__1FJ_lp2.txt
  • Copyright 2009 Murata Manufacturing Co.,Ltd

Section 2 / IPL

  • PureNAND IPL ev9x-v1.8t.r1864 (Mimasaka) [DEBUG BUILD] (Feb 10 2016 10:30:54)
  • EV9XES1.0
  • EV9XES2.0
  • Warning: EV9X ES1.0 does not use 513MHz, it was changed to 400MHz
  • ARM926_1 -> armv5te architecture
  • ARM926_2
  • BCH2K124

Camera Software

Wifi / HTTP Server

When the YI Camera app is paired with the camera, the camera sets a Wifi password which is a 8 digit number. This password can be read from the Android app through logcat, and can then be used to connect a computer with the camera's wifi. The camera has a fixed IP 192.168.0.10, and you can then send commands to the camera via GET requests, e.g. http://192.168.0.10/?data={"command":"GetCameraStatus"} to get the camera status. The list of commands can be extracted from the decompressed firmware by extracting the strings with the strings utility. The camera wifi is started up by the app through Bluetooth, so you have to connect the app first. Seems like it does not support multiple clients (they can connect but only the first gets an IP address), so you need to turn off the phone's wifi to successfully connect another device.

Next steps

  • Identify partition table format and decode
  • Disassemble first section
  • Change something simple (e.g. the 500 shot limit in the beta firmware), repack FW file and upload to camera

Other Cameras

The Fujifilm X-A10 camera uses the same firmware format and can be unpacked with this tool as well. The compression scheme of the first section is also similar. In comparison to the M1 it contains an additional fifth section called "A9262" that contains additional code. Also interesting is that the model ID is very similar (M1: C59Y1, X-A10: C5932).

Other Fujifilm cameras, e.g. Finepix S800, seem to use a similar firmware format, but with shorter headers, so these cannot be unpacked with this tool.

FAQ

What's the purpose of this tool?

To lay the roots for a firmware hack. To help with firmware analysis. To change firmware regions.

What can a potential firmware hack do?

  • Increase video bitrates
  • Add 24p video modes
  • Decrease JPEG compression
  • Change focus peaking color
  • Fix UX issues
    • Disable full shutter button press during video recording which stops the recording while a half press triggers focus

How can I contribute?

Please open an issue, pull request, or drop me a mail at [email protected]

How dare you write this in JavaScript?

Times are changing, and messing with the string headers in C seemed too much of a hassle. JS with Node also runs on virtually every platform.

yi-mirrorless-firmware-tools's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

yi-mirrorless-firmware-tools's Issues

How do I use this program?

Hello I am not an expert with programming and I am currently attempting to change my M1 firmware from CN to INT. I am confused on the instructions in the readme section, where would I download the program?

I’ve submitted a request to YI technology

Hi all! I know that this repo is not doable with nothing in our hands.

I'm one of the many of us that bought the YI M1 but, i really don't use it because of many limitations.

I've requested today the sources to YI tech, hoping that they will release them, in order to have something to work! I'm not an "expert" dev, i mainly work in frontend, but the fact that i can't use this camera drives me crazy.

I really hope that YI respond!

firmware.bin not found

Hi,

i tryed to unpack the firmware.bin but the file is not found.

Software-Version: commit b90b96c

Issue
`npm run unpack firmware.bin

[email protected] unpack /home/markus/projekte/yi-Kamera/Firmware_Kamera/yi-mirrorless-firmware-tools
node index.js unpack 'firmware.bin'
{ Error: ENOENT: no such file or directory, open 'firmware.bin'
at Object.openSync (fs.js:450:3)
at readSections (/home/markus/projekte/yi-Kamera/Firmware_Kamera/yi-mirrorless-firmware-tools/firmware.js:120:19)
at Object.unpack (/home/markus/projekte/yi-Kamera/Firmware_Kamera/yi-mirrorless-firmware-tools/firmware.js:211:5)
at Object. (/home/markus/projekte/yi-Kamera/Firmware_Kamera/yi-mirrorless-firmware-tools/index.js:28:22)
at Module._compile (internal/modules/cjs/loader.js:721:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:732:10)
at Module.load (internal/modules/cjs/loader.js:620:32)
at tryModuleLoad (internal/modules/cjs/loader.js:560:12)
at Function.Module._load (internal/modules/cjs/loader.js:552:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:774:12)
errno: -2,
syscall: 'open',
code: 'ENOENT',
path: 'firmware.bin' }
`

Workaround

you need to run the command from the tools folder NOT from a subfolder there the Firmware file is.

PTBL format -- PEI

PEI (Pre-Efi Initialization phase). (section starts with magic @Pei.
This configures the entire platform and then loads and boots the DXE.

Probably don't need to dig into this section.

Can't run on linux

I'm new to JS, so may be you would be able to help with this issue.
npm run unpack ./firmware.bin
fails with this message : "const [key, value] = part.split('=');"

debug log from npm if it would help
npm-debug.log

How do we get this project moving again?

Just picked up an M1 and love that you have made some progress towards getting some custom firmware implemented! I would love to help where I can. I have development experience but not specifically with camera firmware, but I am always looking to learn new things. I have experience with Node, Javascript, Arduino Dev, Linux Dev (mostly scripts), and general front/back-end web dev.

My goals would be:

  • Add clean HDMI video output, ideally while also recording but if it's not powerful enough to encode and output over HDMI at the same time I would settle for just a clean HDMI output while not recording.
  • Increased bitrate to at least 100Mb/s from the default 75.
  • Ability to adjust custom color profiles would be great too, but I have no knowledge of how this is done in camera. I do have experience creating and implementing LUT's though.
  • The last one is a long shot because it doesn't seem to be the same or similar chip as the action cameras, but adding external microphone via USB port would be fantastic. Otherwise, I will work on a hardware hack to add a 3.5mm port (probably easier than firmware).

What do you think about feasibility for any of these? If they are available in the chipset I imagine it's not impossible with firmware. But not knowing what chip it uses its hard to tell what options might be available.

Let me know if this is still interesting to you and how I can help :)

Modding firmware

What would be the next steps to get a working firmware mod for increased bitrate or something like that?
Would I just have to go through the files and look for where a bitrate variable is and change that? Or is it more complex?
Thanks

Recompression output (input -> decompress -> compress -> output) is different from input

There seems to be an issue somewhere in the decompression and/or compression algorithms, because unmodified recompressed firmware data is different from the original firmware data. As long as this issue isn't solved, I do not recommend anyone to try and flash a recompressed/repacked firmware, it will most likely fail and possibly damage the camera.

This can be tested using the npm run test <firmwarefile> command, which will unpack and decompress the firmware sections, recompress them, and compare differences. It will output differences like this:

// lookup index data decompression vs. compression
// left: compressed input byte index, decompressed output byte index, lookup index, lookup length, lookup buffer size
// right:  compressed output byte index, decompressed input byte index, lookup index, lookup length, lookup buffer size
lookup mismatch: 363,427,137,3,409 <-> 363,427,199,3,409
lookup mismatch: 373,438,136,3,420 <-> 373,438,198,3,420
lookup mismatch: 588,864,138,3,846 <-> 588,864,200,3,846

Some information about how the compression algorithm works can be found here and in a reverse engineering SE question. The first line tells that the original firmware file has a lookup encoded with 3 bytes length at lookup buffer index 137, whereas the recompression selected lookup buffer index 199. Inspecting the lookup buffer shows that the 3 bytes can be found at both locations (actually it can be found in even more locations), but the recompression selects 199 because it's nearest to the tail of the circular lookup buffer where the reverse lookup search begins.

In most cases taking the nearest lookup index from the tail of the lookup buffer yields the correct lookup index, it's just in a few rare cases where it is wrong. This probably means that

  • either there is a bug in the decompression algorithm and the first decompression is wrong, and the lookup data in the case above should not be located at index 199 but only at 137 which the compression algorithm would then select correctly
  • or there's some weird deliberate optimization or undeliberate lookup index picking strategy implemented in the original algorithm that I cannot figure out

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.