atc1441 / DaFlasherFiles

Additional files for the DaFlasher App and the ATCwatch Firmware for the P8 Smartwatch
GNU General Public License v3.0
111 stars 20 forks source link

Restoring original firmware #7

Closed MarkMLl closed 3 years ago

MarkMLl commented 3 years ago

Noting that one can get a copy of the appropriate variant of the Mo Young ("MOY") firmware by giving the watch type (e.g. "TIN5"), current version number (e.g. "1.7.8") and MAC address (e.g. "12:34:56:78:9A:BC") to crrepa.com

http://api2.crrepa.com/upgrade/factory?mac=12:34:56:78:9A:BC&version=MOY-TIN5-1.7.8

which returns JSON with a binary name encoded, hence a .bin file like

-rw-r--r-- 1 markMLl markMLl 166460 Oct 1 17:40 d4d4015482a4f96d4472155a1a584fc6.bin

which looks like sensible watch firmware, is it possible to package this in an appropriately-formatted zipfile which daflash can send to the watch?

atc1441 commented 3 years ago

Hi. Yes that is the firmware and its possible to pack it into an nordic style update file to update thw watch with it.

Just to be clear when the custom bootlpader is flashed and then the stock firmware again it is not possible to flash anything else again as the update method is bricked then

MarkMLl commented 3 years ago

Thanks for that. Do you mean that neither DaFit nor DaFlash will ever work again, or that DaFlash is overwritten and would have to be reinstalled? If the latter, is that because the bootloader initialises via a vector in low Flash, or are you assuming that the stock firmware is sufficiently large (about 162K) to overwrite DaFlash?

Apologies for asking stupid questions, I'm an outsider to this architecture and am just trying to get a basic understanding of what's going on.

atc1441 commented 3 years ago

No problem.

It is because the stock bootloader is removed after a custom bootloader is flashed.

The stock firmware uses a different update method then the custom bootloader so its not really compatible you can not even flash a real update from DaFit ever again. Everything update related is broken when reflashing the stock firmware again after a custom bootloader is flashed

MarkMLl commented 3 years ago

OK, but it remains DaFlash compatible so you can upgrade like that? Of course, the stock firmware could check the integrity of its own loader before it accepted instructions from a 'phone...

I'll have a play. Do you have any pointers to instructions for bundling the .bin into a .zip?

atc1441 commented 3 years ago

No ypu can ot flash anything after flashing the stock back again.

Only by opening the watch and flashing it via SWD

Ypu can use nrfutil to convert the bin to a zip file

MarkMLl commented 3 years ago

OK, thanks for that.

MarkMLl commented 3 years ago

A late (post-close) observation in case there's anything useful, and my apologies if I'm reiterating anybody else's tinkering. Assuming a WiFi access point connected to a local server, then an Android 'phone etc. uses the server's DHCP and DNS for its network setup. That's distinct from something like Termux where it assumes a fixed 8.8.8.8 for its DNS.

The result of that is that while e.g. DaFit gets installed using some proprietary protocol connecting to Google's Play Store, once it's running it "phones home" using HTTP (not HTTPS) with local name resolution (which can be spoofed). Hence a local nameserver can be set up to redirect upgrade requests to a local copy of Apache etc.

A P8 watch sends an upgrade request with a MAC address (which is ignored) and a variant/version identifier (e.g. MOY-TIN5-1.7.8) for its current firmware. If the server decides that it has a more recent firmware version for that variant it will return the appropriate file's name.

The name comprises 32 hex digits, and I speculate that it is a 128-bit hash of a filename. This is followed by a .bin extension.

I've not been able to find a list that translates variant/version names to the actual binary filename, and I've put a very limited amount of time investigating what the server is prepared to return if given different variant/version info.

It might be possible to build custom firmware into the format expected by the DaFit loader, and load it without overwriting the original bootloader.

Again, my apologies if I'm stating the obvious.

atc1441 commented 3 years ago

Hey
Yes you are correct with your assumption.

This is what the HackedBootloader exactly is. So it uses the stock bootloader to write a new firmware in flash, only after the new firmware is executed the bootloader gets erased.

So it is exactly possible like you think, the big problem there is that you need a fully working firmware to be able to do any update as if the firmware wouldnt run anymore you can not flash a new firmware. The stock bootloader has no ble function, it will only copy the content from the external flash to the internal flash, the main update is hapening in the stock firmware

MarkMLl commented 3 years ago

Thanks for the confirmation, that was just the result of a bit of tinkering looking at how the update actually worked.

I might take a bit of a look at some point seeing if I can reverse-engineer the filenames... the overall level of security suggests that they probably aren't salting the name.

atc1441 commented 3 years ago

The hash is an MD5 hash of the update file nothing more, it is only checked by dafit but not by the watch, You can use DaFlasher as it accept the stock firmware files without the need of hashing

MarkMLl commented 3 years ago

My apologies for asking questions that I'm sure are covered somewhere in previous discussion or in your sources.

So since the name is an MD5 of the file content (rather than of the variant/version name as I hoped) it can't be used to predict the names of and build up a complete archive of the recovery files. Pity.

From what you're saying it's not possible to merge custom functionality with the bootloader in the .bin, so that the DaFit updater can be used multiple times.

atc1441 commented 3 years ago

No problem,

you did misunderstand it, the bootloader can be used multible times, but it is needed to prepare the new firmware you want to flash on the external flash of the watch in the main firmware. so the new custom firmware needs to be able to write into the external flash to then start the bootloader so it can write the new firmware to the nrf internal flash

MarkMLl commented 3 years ago

OK, I think I've got that.

luzemario commented 2 years ago

No problem,

you did misunderstand it, the bootloader can be used multible times, but it is needed to prepare the new firmware you want to flash on the external flash of the watch in the main firmware. so the new custom firmware needs to be able to write into the external flash to then start the bootloader so it can write the new firmware to the nrf internal flash

There is any chance the stock bootloader be the same (or similar) across many DaFit watches?

stefan123t commented 2 years ago

@MarkMLl maybe the REST-API of the upgrade/factory got changed or enhanced ? I received the following when checking for my new P8b MOY-TON5-1.8.4 device.

$ curl http://api2.crrepa.com/upgrade/factory?mac\=12:34:56:78:9A:BC\&version\=MOY-TON5-1.8.4 | jq .
{
  "code": 0,
  "mcu": 3,
  "message": "发现新版本",
  "type": 0,
  "version": "MOY-TON5-2.0.3",
  "path": "http://api2.crrepa.com/uploads/files/c6e5f86b857daa6953f9b8145c8df820.bin",
  "url": "http://api2.crrepa.com/uploads/files/c6e5f86b857daa6953f9b8145c8df820.bin",
  "md5": "d50941558822cab61bc8bb7bce3a345e",
  "log": "优化升级",
  "log_en": "Optimization and upgrade",
  "size": 65696
}

So everything you wanted is there, md5 checksum, version number and english changelog entry. Someone may write a small scraper to get the current firmware version URLs for those models given in the earlier model list

MarkMLl commented 2 years ago

So everything you wanted is there, md5 checksum, version number and english changelog entry. Someone may write a small scraper to get the current firmware version URLs for those models given in the earlier model list

Remember that you can't force an HTTP server to return a directory listing if it prefers not to. So getting the true name of each file hence a full list or potential URLs might be a problem.

stefan123t commented 2 years ago

Yeah it is more like the problem is to get the valid / matching version numbers to the model name. But it will give us the latest possible version anyway, i.e. there is no choice for intermediate versions if it is not required.

Actually the example above mentions version MOY-TON5-2.0.3 both in version string and in the firmware binary. Though the DaFit app will upgrade twice, i.e. I have it now on version MOY-TON5-2.0.4 in the about dialog.

$ curl http://api2.crrepa.com/upgrade/factory?mac\=12:34:56:78:9A:BC\&version\=MOY-TON5-2.0.3 | jq .
{
  "code": 0,
  "mcu": 3,
  "message": "发现新版本",
  "type": 2,
  "version": "MOY-TON5-2.0.4",
  "path": "http://api2.crrepa.com/uploads/files/13227867923c42fb784e4504aa0c2048.bin",
  "url": "http://api2.crrepa.com/uploads/files/13227867923c42fb784e4504aa0c2048.bin",
  "md5": "a831b204cfaf1c8c123e5d6453d1a63e",
  "log": "优化升级",
  "log_en": "Optimization and upgrade",
  "size": 177172
}

As noted on the Discord channel the 2.0.3 is fairly minimal with only 65k in size vs. the 2.0.4 with 177k.