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

V2 Home Data api #155

Open
Lash-L opened this issue Nov 30, 2023 · 18 comments
Open

V2 Home Data api #155

Lash-L opened this issue Nov 30, 2023 · 18 comments

Comments

@Lash-L
Copy link
Collaborator

Lash-L commented Nov 30, 2023

Seemingly Roborock has rolled out a new api version for the /user/homes/{home_id} request. It is now /v2/user/homes/{home_id}

It uses the same hawk authentication method, butI have been getting invalid token error when I have been trying. I will continue to figure out why, but if you wanted to take a look as well @humbertogontijo, more eyes would be nice.

Basically we want this for 2 reasons:

  1. In case they depreciate v1 of the api

  2. Some of the newer non-robot vacuum devices are received from this api.

Let me know if you figure anything out

@humbertogontijo
Copy link
Owner

Hmm.. I wonder if the app is already using it

@Lash-L
Copy link
Collaborator Author

Lash-L commented Dec 1, 2023

Hmm.. I wonder if the app is already using it

The app is using it and I can see it with mitm. But I can't figure out what the difference is in terms of the request headers for the one we do now and v2. I tried adding a few of the additional requests, but nothing would accept.

The response seems to be the same as well, except that it also gives the new devices as well

@Lash-L
Copy link
Collaborator Author

Lash-L commented Dec 9, 2023

Next piece of the api that I have noticed that has changed:

/api/v1/login is now /api/v3/auth/email/login

And the request is

        params={
            "email": self._username,
            "password": password,
            "twoStep": 1,
            "version": 0
        },

Where password is some encrypted version of the password I have yet to figure out

I am trying to figure out if code login has changed as well, but it isn't ever asking me for a code for some reason

@Lash-L
Copy link
Collaborator Author

Lash-L commented Dec 9, 2023

I got home data working for v2 now - I hvae not figured out v3 login though

@Lash-L
Copy link
Collaborator Author

Lash-L commented Dec 10, 2023

If you're up for a challenge, I've been trying to RE the dyad vacuums, I was able to get the following set of bytes with the following local key: 'ELSYN0wTI4AUm7C4'

It's been so long since i've touched any of the decryption logic, I honestly forgot how a lot of it works, if you're up for it, i'd be interested to see if you would have more luck @humbertogontijo

I tried changing all of the version instances of 1.0 to A01, but that didn't make a difference

b'A01\x00\x00\x0e\xa6\x00\x00\x0e\xa6ev5X\x00f\x00@$\xc4\x08\x08\x9b\x87D\xe0\xc1\xf9F\xf2\xc7\x9d\xc3?\xb3E\x08\x96\x06\x8d7\xb0\x1c\xc0\x9d`\x0c\xf0\x830\x1a\x90\xe0Y\xc9\xc6\xa9T}\xe8\x92\xfa`\xc3\xc8\xa9\xc2 \xc5N(\xe5\xec\x05]j\xe7\xf2\x0f1\xa4\xdb\xe1\x8b\xc5\xf5'
b'A01\x00\x00\x0e\xaf\x00\x00\x0e\xafev7x\x00f\x000\x90`OY\xcc\x7f\xb4\xc8\x1b\x9a\x9e\xc5Xy\x1e\xf11\x00\xbb \x1d\x9a\x81\xfcs\xa8+\x0e{!:\xa4`>.\x9f\x1aGq\xa4\xfe\xf8\xb8\xa9F\x7f*\xe2\xfbq#\xd8'
b'A01\x00\x00\x0e\xb1\x00\x00\x0e\xb1ev7y\x00f\x01\xc0\xf5/\xd4P`\x1e.\xdde\xe7\x16\xcc\x054{g\x8d\xde\xe1_\xdc:\xdc(-\xa2\x85\\\x90\x01\x17p\x0bK\x08#"uUbZ\x8f\x92\xd99\xf4\xf9\x8e\x86p\xdb\xa8~\xa1\x8cF\xff\'\x08h\x9f\xac3\x18\x03\xc2\xbd\xcca\xf5TI\x87\x89\x00\x05\x80\x92\x8b\xce?\x86\x02\xf3\x04\x10-\x89S\xea\x9f[\x8d\xb7\x82Lo/\x9a\x1aC\xd3@&\xf2D\xe3\x19\x12B\x92k\xc2|\xef\x97\xd9<\xdf"\xc7\xee\x01\x1a\x9f\xc8\x8f\x8b\xba\x8b~\xe34\xfe?\x1e\x00x\x13\xee0\xee|\xf4\xd9\xf1\x8c^\\\x11~\xb6\xaa\r\xc7\xf6\x9e\xfec\xd3\xe4H@{\xa6;-\xce\xff\xcf\xab\xfbk\xf8\xc6<{lGM\xd7d\xc3\x14E\tX,\xc3\xca3\xeeG\xa6\xc4\xdb#\x9f7^32\xaa\x8d$\x18 2\xa9\x88n\x96q\xe34&$\xff)\x19\x8d\xce\xd7"\x9d\x90\x08n\x16\x8ab\xd2\xc6:5\nP\x17\xb9\xe3\xbed\x8bM0\xef\xa5d\xb4\x18\x0c$\xc1\xe0\xa4Kc\x12px\xfc\xe2"\xd5`\xb3.\xb5\x05y1\xf5O\r\xf4?c\x885\xba\x9a\x08\xd7\xb3\x06E\xcdEIbk\xe1\n\xe6\xbf\xa7(d\xb8!C?&+\xabj}1\xf9Va\x8fN\x17\xd0`\xca\xb9\xf5\x8a\xcak4\x85\xb1\xdf\xac\xf8\x93\xbc\xee\x07\x84\xe7JT\xdf\rx\\(u\x8a\xac\xee\xe7l\xb1@\xd8\xbc\xad\xd5\x14b\xe7\x83Wj\x9ezY\x12P:xQ\x81\x00\x04\xdb\xcc\xa3\x84Q\xc5\xb6\xc54\xc0e\x95\x85\xccR\x95\xaa\xea%\xb5\x8f\x99\xb7\xf5[\xa6NBk\xd0A\x96Q\x00c8pqD{(\x0f\xd6\x97\xec\t\xde\x90"\xb0d\xbe\x1bU\xb9\x17\x19\xdd\x07s\xe2\x1d\x16PQF\xd3K<H\x10|\xc76\xdb\x11J/s\xa7\xe6\x7f'
b'A01\x00\x00\x0e\xb3\x00\x00\x0e\xb3ev7y\x00f\x00\xf0\xfe\x0c\xed\xe4\xff\x91\x83\xce\xadz\xac\'\x04s\x80\xda\xbe@\xd1\x13\xb02\xe4{\x18a\xbf=\xa7\x85+\xcc\x8a\n\xb2\xfa\xbb\x06\x16\x8ed\xfa\xadT.\xe8|\xae=?\x00m\xc6iC\xb2\x07\xc2\x0b2Z\x05\xa6\xdc\xd1BhF\x147\x9c\xd3\x04Bx\x1b\x84XR\x8dpy\xe1L|\xd5]\x98\xba\x87\xc0\x17\xd8\xa5\x11H\xae}0\xac)\x02\xe5\x8c{A3v/?\xfa6o\xcfL\x8db\xb6\xde\xa4\xe9n\xcf\x13\xbf\xe1\xdf\x01r\xc9\xd3\'\xff\x8ePOE\x19.Bx\xe6s+C\xf9\xefil0\xf4\x9e\xca\x82 \xf6\xb9c+9z\xcd\xc6X\x0c\x80[\xf6\xdd\xc4\x99\x91&w\xad\x11\x9d\xae\xe7\xca\x80"\x91\xa9\xbb\xd2\xdb\xbd\xa7`\xcc\xdca\x1cq,\x90W.\x8cq*\xbe\xa9\x96H\xd4\x0e.s\xf2\x8d\x8f \xf7\x83\xdek\xeb\x7fHq\xa5\xeczF\xb2O^\xf4\xb6\xedVQ\x14W9]\xb8S=J4\x92'
b'A01\x00\x00\x0e\xb0\x00\x00\x0e\xb0ev7x\x00f\x00\x90\xb4\xb1\x8b\xd8\x91\xf42\x919\xee\xe8\x83&\xcb`\xc9\x89Hi\xce2h\x83\xe6\x95\xa3\xab\xfd)}v\x97\x9dh\xdd\x1e\xcf)\xba#\xb5\xacl\x9cT@|!d\x94!$V\x99$ \x1e{\\o\xbbQ&\xcd\xf1J\x079pk\xbb\x08\xbfPC4H\x16\xa7\xc3\x8bg\xfd\xb5\x83\x92G\xf9\x8c\x99\xde\xfe\x0c_\xa3\xc1\x94\xff$r\xbf\xcbO\xd6\x84"[d\x92\xb4\xednx\x1c\xc1S\xe4\xb7\x1e\x0fj\xe45\xac\x98\x9bz\xf5"T\x8c\x03\xfb\xb7_\xb9\x97F\xbf\xc6\x81Uj6\xf4S\xacH'
b"A01\x00\x00\x0e\xb2\x00\x00\x0e\xb2ev7y\x00f\x00`\xfc\xa7\x9f\xe8n\xf5\x07\x8a\xf7\xc5qy\x10\xda\x99R\xb2 \xe1\x1b>\xc1\x87^\xd4\xa5W|\xa6\xe9a\xebh+\xc8\xab\xe5\xc9\x1f\x8f\xee\x04I'\xe5\xc6\x85\xc1\x89=9{\x8bA\rlO\x1a\x07\xa3\xf4F\x8d\x0b~\xc9\xde\x8c<)\xf5{\xf6Q\xb8\xa4wA\xf9\xbb3`\xa6\xa5\x97\xa47\xb9\x1eX~\x8a\x07U\x87\xe00\x10Tb"
b'A01\x00\x00\x0e\xb4\x00\x00\x0e\xb4ev7y\x00f\x00\xc09\x06\xaeN\n\r\\\x13y\xa3%\x1e\re\xd8vD\xa4\x1e)x\xd8dY8S\xb6y\xe4R\xae\xe9\xf1\xefe\xac\x01\xf06\xaf`\xeaE\x1a\xa4\xe55[\xc1\xf7\xe3\xd7X\x81\xcf\x0c\x9a\xa1q\x95*\xb9\xe7v/\x16A\xb7\x01\x1f2\xfe\xe2\xe0Xs\x97S\x9e\xf0\xc0\xf1\xf4\x05\xe4z\xde\x97\xec!\xb1\xe3>\xf4\x98\xcf-\xee3+\xa2Q\xcb\x8a\x934l\x01B\xa8\xb9\xfb\x9a&\x10e\xc0\x8c"\xb4\xcb\x12S-\xcd\xbeNP\xf3\x13v\x9b2\n\x84\x996\'\xd2`\x1d\xdf\x89\x96rbT\xac\xa7\xa4\xc3R\xe6T\x92\xccI\xcf\xf3HQ\xf1U\xdar=\x85E\xc7\xf2e+\xa6\x06\xb7\xa9\xd2\x08\xc68y4\x9e\'\xb2\x01\x07\x83\xca\xe2\xc6\x17\xc5Hr\xc0'

@humbertogontijo
Copy link
Owner

humbertogontijo commented Dec 10, 2023

I changed every 1.0 to A01 in protocol.py file. All info except payload looks correct.
Which means the key might be different from

Utils.md5(
    Utils.encode_timestamp(ctx.timestamp) + Utils.ensure_bytes(ctx.search("local_key")) + SALT
)

Could be a different salt

@Lash-L
Copy link
Collaborator Author

Lash-L commented Dec 11, 2023

How did you determine salt when you original reverse engineered it?

@Lash-L
Copy link
Collaborator Author

Lash-L commented Dec 11, 2023

For what it is worth, api seems to point towards rpc beeing a different code:

                {
                    "code": "rpc_req",
                    "desc": null,
                    "id": "10101",
                    "mode": "wo",
                    "name": "rpc req",
                    "property": null,
                    "type": "STRING"
                },
                {
                    "code": "rpc_resp",
                    "desc": null,
                    "id": "10102",
                    "mode": "ro",
                    "name": "rpc resp",
                    "property": null,
                    "type": "STRING"
                }

@humbertogontijo
Copy link
Owner

I got salt from decompiled android app

@Lash-L
Copy link
Collaborator Author

Lash-L commented Dec 11, 2023

I got salt from decompiled android app

oh it was just in plain text? Interesting, i'll go searching through and see if i can find another

@Lash-L
Copy link
Collaborator Author

Lash-L commented Dec 11, 2023

@humbertogontijo
Copy link
Owner

Previously that was some files that hold these constants like salt and broadcast token. But I couldn't find them in your decompiled version

@Lash-L
Copy link
Collaborator Author

Lash-L commented Dec 11, 2023

I used http://www.javadecompilers.com/apk
Did you use something different?

@humbertogontijo
Copy link
Owner

I don't think so. It was probably just an older version of the app.
I did it twice. On January this year and at the time we managed to get local integration working. Both times those variables were available as plain text

@Lash-L
Copy link
Collaborator Author

Lash-L commented Dec 11, 2023

@humbertogontijo
Copy link
Owner

@LukeSerne
Copy link

I remembered it. I got it from here
https://gist.github.com/rovo89/dff47ed19fca0dfdda77503e66c2b7c7#file-test-js-L28

Based on the comment in this file, I looked into librrcodec.so. I identified several relevant functions, but unfortunately, the code for the more complex functions is a bit hard to follow because control flow obfuscation was used. There are 2 authentication functions, and their behaviour seems very similar.

Before I spend more time looking into how both authentication methods work, I wanted to check if there is already some work done on this? Maybe someone already figured out how the new authentication works, or made significant progress. It'd be a shame to repeat work that has already been done. Is there a community where these things are discussed?

@Lash-L
Copy link
Collaborator Author

Lash-L commented Jan 27, 2024

I remembered it. I got it from here
gist.github.com/rovo89/dff47ed19fca0dfdda77503e66c2b7c7#file-test-js-L28

Based on the comment in this file, I looked into librrcodec.so. I identified several relevant functions, but unfortunately, the code for the more complex functions is a bit hard to follow because control flow obfuscation was used. There are 2 authentication functions, and their behaviour seems very similar.

Before I spend more time looking into how both authentication methods work, I wanted to check if there is already some work done on this? Maybe someone already figured out how the new authentication works, or made significant progress. It'd be a shame to repeat work that has already been done. Is there a community where these things are discussed?

Yes - we have fully Reverse engineered it, I have not taken the time to implement it into this library though. You can add me on discord @conway220

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants