Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Seeking Device Profile for WOOX Smart Plug Model R6080 #193

Closed
NielsPiersma opened this issue Nov 26, 2022 · 22 comments
Closed

Seeking Device Profile for WOOX Smart Plug Model R6080 #193

NielsPiersma opened this issue Nov 26, 2022 · 22 comments

Comments

@NielsPiersma
Copy link

Hi all,
I am new to Tuya (Cloudcutter) but have been using Tasmota for quite some time. This I my first attempt at getting a Tya chip converted into cloud-less.
I followed, as best as I possibly could, the instructions on https://www.elektroda.com/rtvforum/topic3906898.html, but I was unable to finish the process successfully. I was hoping you could help me out.

Flashing the chip with OpenBeken, was also not an issue, but I rather find a way where I can do OTA flashing. So that's why I liked this approach.

I was able to export / extract the original firmware using the bktools after desoldering the chip from the smart socket.

bk7231s_dump-2022-11-22-19- 0-14.zip

And extracting the information / decrypting was no problem.

./bk7231tools dissect_dump -e -O /home/niels/woox /home/niels/woox.bin
RBL containers:
0x118f0a: app - [encoding_algorithm=NONE, size=0xeb5c0]
extracted to /home/niels/woox
0x1fff9a: bootloader - [encoding_algorithm=NONE, size=0xdd20]
extracted to /home/niels/woox
Storage partition:
0x1dd000: 68 KiB - 7 keys
extracted all keys to /home/niels/woox/woox_storage.json

And I can get some profile / device information
python3 ../cloudcutter-bk7231-haxomatic/haxomatic.py woox_app_1.00_decrypted.bin
[!] Matched pattern for BK7231T version 2, payload version 1
[!] Searching for ty_cJSON_Parse
[+] Payload prep gadget (THUMB): 0x9d431
[!] Searching for mf_cmd_process
[+] Payload pwn gadget (THUMB): 0x90201
[+] Profile:
{
"chip": "BK7231T",
"payload": "eyJhdXprZXkiOiJBVVRIS0VZQUFBQUFBQUFBIiwidXVpZCI6IlVVSURBQUFBQUFBQSIsInBza0tleSI6IiIsInByb2RfdGVzdCI6ZmFsc2UsImFwX3NzaWQiOiJBIiwic3NpZCI6IkEiLCJ0b2tlbiI6IkFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQTHUCSJ9",
"authkey_template": "AUTHKEYAAAAAAAAA",
"uuid_template": "UUIDAAAAAAAA",
"datagram_padding": "QUFBQQECCQABAgkAAQIJAAECCQABAgkAAQIJAAECCQABAgkAAQIJAA=="
}

And then my trouble begins;
I am unable to decrypt the settings.

python3 ../decrypt_settings.py woox_app_1.00_decrypted.bin result.bin
Traceback (most recent call last):
File "/home/niels/woox/../decrypt_settings.py", line 40, in
key = merge_keys(INNER_FLASH_KEY, key)
File "/home/niels/woox/../decrypt_settings.py", line 15, in merge_keys
raise ValueError("Inner and outer key lengths must match")
ValueError: Inner and outer key lengths must match

And I am lost...
The extracted file.
woox. zip

I would sincerely appreciate any help in adding this device to the repository.

Kind regards
NIels

@kuba2k2
Copy link
Member

kuba2k2 commented Nov 26, 2022

You're trying to decrypt settings using a decrypted app file, which won't work. Bk7231tools has settings/storage decryption built-in now, so there's no need for separate scripts for that:

Storage partition:
0x1dd000: 68 KiB - 7 keys
extracted all keys to /home/niels/woox/woox_storage.json

@NielsPiersma
Copy link
Author

@kuba2k2 , Thanks for your swift response. I understand that the keys are stored in the woox_storage.json file. How would I get the "results" converted into a device profile? I am doing my best to connect the dots, and it looks like I am almost there, but just missing the last piece of knowledge getting there.

Once I've got it figured out I'll certainly add the device to the repository and do a nice write up from start to end on how to get these devices flashed.

If you could point me to the right place, I would certainly appreciate that.

Niels

@kuba2k2
Copy link
Member

kuba2k2 commented Nov 26, 2022

We're moving away from "classic" profiles (like the one haxomatic generated for you). Profiles (and "devices") are now in cloudcutter-data repo.

There's a WIP branch of haxomatic that @Cossid made, which generates profiles and devices in the new universal format (only 2 JSON files per device/firmware combination).
As it's still WIP, there's no usage guide, but you may be able to figure it out from the scripts' usage info:

d:\Dev\tuya\_cloudcutter\cloudcutter-bk7231-haxomatic (rework/universal-format -> origin)  λ parse_app.py
Usage: python parse_app.py <dercypted app file>

d:\Dev\tuya\_cloudcutter\cloudcutter-bk7231-haxomatic (rework/universal-format -> origin)  λ parse_storage.py
Usage: python parse_storage.py <storage.json file>

d:\Dev\tuya\_cloudcutter\cloudcutter-bk7231-haxomatic (rework/universal-format -> origin)  λ assemble_universal.py
Usage: python assemble_universal.py <device_folder_name>

d:\Dev\tuya\_cloudcutter\cloudcutter-bk7231-haxomatic (rework/universal-format -> origin)  λ haxomatic.py
Usage: python haxomatic.py <app code file>

d:\Dev\tuya\_cloudcutter\cloudcutter-bk7231-haxomatic (rework/universal-format -> origin)  λ

@kuba2k2
Copy link
Member

kuba2k2 commented Nov 26, 2022

I wrote a quick-and-dirty script to "automate" that:

bk7231tools dissect_dump -e -O %1 %1.bin
pushd %1
..\haxomatic.py %1_app_1.00_decrypted.bin
..\parse_storage.py %1_storage.json
..\parse_app.py %1_app_1.00_decrypted.bin
mkdir extracted
move *.txt extracted\
popd
assemble_universal.py %1

Works on Windows. Rename your full dump .bin to device-manufacturer_device-name.bin and run it like:

do_magic.bat device-manufacturer_device-name

Edited the script per response below

@Cossid
Copy link
Member

Cossid commented Nov 26, 2022

Ideally, parse_storage should be run before parse_app.
Still working on refactoring to handle bk7231tools portions and profile api stuff

@NielsPiersma
Copy link
Author

@kuba2k2 and @Cossid, again, thanks for the quick response; I'll give it a shot tomorrow and see how it works out. I am running Linux, but I don't see that as a con.

Cheers
Niels

@NielsPiersma
Copy link
Author

Well,
I am getting there;

parse_storage.py is is successful. It nicely generates the files expected.
python3 parse_storage.py woox_storage.json
========== woox ==========
uuid: 4b4956d24cb6c14b
auth_key: Xk8WLgchknJEzYTwDMxvjCWMFKhNA7eG
ap_ssid: Woox
swv: 1.1.2
bv: 40.00
key: keya4gvchmtapm8n

parse_app.py runs without errors;
python3 parse_app.py woox_app_1.00_decrypted.bin
========== woox ==========
[+] SDK: 1.0.2
[+] Device class: oem_bk7231s_rnd_switch

The files are created;
woox_ap_ssid.txt woox_device_class.txt woox_sdk.txt
woox_auth_key.txt woox_icon.txt woox_swv.txt
woox_bv.txt woox_key.txt woox_uuid.txt

after moving the *.txt to the extracted directory, assemble_universal.py fails:
Traceback (most recent call last):
File "/home/niels/cloudcutter-bk7231-haxomatic-rework-universal-format/assemble_universal.py", line 122, in
assemble()
File "/home/niels/cloudcutter-bk7231-haxomatic-rework-universal-format/assemble_universal.py", line 19, in assemble
name = base_name.split('_')[1].replace('-', ' ').replace(" ", "-")
IndexError: list index out of range

What ever directory I use, it keeps acting up. Any hints / help would be appreciated, though.

Niels

@NielsPiersma
Copy link
Author

Just for me to be sure, I do need to create these profiles BEFORE I can flash via OTA?
Niels

@kuba2k2
Copy link
Member

kuba2k2 commented Nov 26, 2022

See the script: the files have to be in a specifically named directory. It has to be manufacturer_product.

@Cossid Cossid added this to the Universal Profiles milestone Nov 27, 2022
@NielsPiersma
Copy link
Author

Well,
Did give it another try, but still not getting the desired result;

$ bk7231tools dissect_dump -e -O woox woox.bin
RBL containers:
0x118f0a: app - [encoding_algorithm=NONE, size=0xeb5c0]
extracted to woox
0x1fff9a: bootloader - [encoding_algorithm=NONE, size=0xdd20]
extracted to woox
Storage partition:
0x1dd000: 68 KiB - 7 keys
extracted all keys to woox/woox_storage.json

pushd woox
~/woox ~

~/woox$ python3 ../cloudcutter-bk7231-haxomatic/haxomatic.py woox_app_1.00_decrypted.bin
[!] Matched pattern for BK7231T version 2, payload version 1
[!] Searching for ty_cJSON_Parse
[+] Payload prep gadget (THUMB): 0x9d431
[!] Searching for mf_cmd_process
[+] Payload pwn gadget (THUMB): 0x90201
[+] Profile:
{
"chip": "BK7231T",
"payload": "eyJhdXprZXkiOiJBVVRIS0VZQUFBQUFBQUFBIiwidXVpZCI6IlVVSURBQUFBQUFBQSIsInBza0tleSI6IiIsInByb2RfdGVzdCI6ZmFsc2UsImFwX3NzaWQiOiJBIiwic3NpZCI6IkEiLCJ0b2tlbiI6IkFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQTHUCSJ9",
"authkey_template": "AUTHKEYAAAAAAAAA",
"uuid_template": "UUIDAAAAAAAA",
"datagram_padding": "QUFBQQECCQABAgkAAQIJAAECCQABAgkAAQIJAAECCQABAgkAAQIJAA=="
}
~/woox$ python3 ../cc/parse_storage.py woox_storage.json
========== woox ==========
uuid: 4b4956d24cb6c14b
auth_key: Xk8WLgchknJEzYTwDMxvjCWMFKhNA7eG
ap_ssid: Woox
swv: 1.1.2
bv: 40.00
key: keya4gvchmtapm8n

~/woox$ python3 ../cc/parse_app.py woox_app_1.00_decrypted.bin
========== woox ==========
[+] SDK: 1.0.2
[+] Device class: oem_bk7231s_rnd_switch
*~/woox$ mkdir extracted
~/woox$ mv .txt extracted/
~/woox$ popd

~
python3 cc/assemble_universal.py woox
Traceback (most recent call last):
File "/home/niels/cc/assemble_universal.py", line 122, in
assemble()
File "/home/niels/cc/assemble_universal.py", line 19, in assemble
name = base_name.split('_')[1].replace('-', ' ').replace(" ", "-")
IndexError: list index out of range

Can it be this will only run on Windows based python?

Having said that, anyone so kind as to create the profile so I can test Tuya Cloud cutter on the Woox R6080?

Niels

@kuba2k2
Copy link
Member

kuba2k2 commented Nov 27, 2022

You still didn't name the file as you should.

See the script: the files have to be in a specifically named directory. It has to be manufacturer_product.

On Linux, the script would look something like that:

bk7231tools dissect_dump -e -O $1 $1.bin
cd $1
python ../haxomatic.py $1_app_1.00_decrypted.bin
python ../parse_storage.py $1_storage.json
python ../parse_app.py $1_app_1.00_decrypted.bin
mkdir extracted
mv *.txt extracted/
cd ..
python assemble_universal.py $1

Name the .bin file woox_r6080.bin and run the script like ./script.sh woox_r6080.

@Cossid
Copy link
Member

Cossid commented Nov 27, 2022

The error is because assemble_universal expected a specific format for the folder of mfg-name_model-information where an underscore is required.

You don't need to worry about generating a universal profile, we have one ready for when we switch to universal format. Either way, your dump is missing schema information, so your attempt would be incomplete anyway.

@NielsPiersma
Copy link
Author

You still didn't name the file as you should.

See the script: the files have to be in a specifically named directory. It has to be manufacturer_product.

On Linux, the script would look something like that:

bk7231tools dissect_dump -e -O $1 $1.bin
cd $1
python ../haxomatic.py $1_app_1.00_decrypted.bin
python ../parse_storage.py $1_storage.json
python ../parse_app.py $1_app_1.00_decrypted.bin
mkdir extracted
mv *.txt extracted/
cd ..
python assemble_universal.py $1

Name the .bin file woox_r6080.bin and run the script like ./script.sh woox_r6080.

@kuba2k2
Sorry, I misunderstood the manufacturer/model part. My bad, now it is running successful.

[+] Dumping universal profile oem_bk7231s_rnd_switch-1.1.2-sdk-1.0.2-40.00
[+] Dumping device profile woox-r6080

@NielsPiersma
Copy link
Author

schema info

@Cossid
Thanks for clarifying, Now I have got the profile, which, when looking at the output I already got using the tools. I'll have a look now to find the schema information.

Niels

@Cossid
Copy link
Member

Cossid commented Nov 27, 2022

I'm working on refactoring the scripts to pull schema when storage information is present.

I'm refactoring all these scripts to work better together and leverage bk7231tools extraction as well. Changes will be coming soon, and probably moved into the official tuya-cloudcutter profile-building section.

@NielsPiersma
Copy link
Author

@Cossid , for now I'll put my WOOX R6080 on a bit of ice and give it some time :). Quite happy you are doing the hard work.
I'll upload the pictures of the breakdown of the WOOX R6080 and share them here.

@kuba2k2
Copy link
Member

kuba2k2 commented Nov 27, 2022

If you want, we have a Discord server with an "esphome-configs" channel, where people can post ready-to-use configs, as well as device disassembly photos/other info.

@NielsPiersma
Copy link
Author

If you want, we have a Discord server with an "esphome-configs" channel, where people can post ready-to-use configs, as well as device disassembly photos/other info.

Will check it out. For now discord.com seems to be down from my connection. I am still looking for a way how to get the schema. Maybe someone can direct me how to get it.

NIels

@Cossid
Copy link
Member

Cossid commented Nov 28, 2022

Here is a full profile that will work with the current iteration of CloudCutter. woox_r6080-smart-plug.zip We're working on migrating to universal profiles, in which it will be included by default there.

@NielsPiersma
Copy link
Author

@Cossid, this is excellent. We will try this later this evening and report the results, still have 7 devices left for testing ;)

NIels

@NielsPiersma
Copy link
Author

@Cossid , I would like to thank you. We got the R6080 unlocked and flashed in under 5 minutes apiece. I can confirm the complete profile export is working as expected. Later this week, I'll draft all the steps and the (now) unneeded disassembly of the R6080, which, in most cases, leads to a partially damaged unit. So the possibility for OTA flashing, without damaging the unit, is unbelievably helpful.
Niels

@Cossid
Copy link
Member

Cossid commented Nov 30, 2022

An update has been pushed that should include a profile for this device. Please update your repo and give it a try. Please see the instructions page ( https://github.com/tuya-cloudcutter/tuya-cloudcutter/blob/main/INSTRUCTIONS.md ) for any command or input changes.

If the new profile does not work, please re-open this ticket with details (including logs) of the failure.
Any feedback is appreciated.

@Cossid Cossid closed this as completed Nov 30, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants