Open Lash-L opened 11 months ago
Hmm.. I wonder if the app is already using it
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
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
I got home data working for v2 now - I hvae not figured out v3 login though
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'
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
How did you determine salt when you original reverse engineered it?
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"
}
I got salt from decompiled android app
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
Looks like it is here: https://github.com/Lash-L/roborock_decompiled/blob/74802b6d018c2becdf8b7efe281937307ef10adf/sources/roborock/sawmill/common/msg/Msg%24LogRequest.java#L128 Mind taking a look and telling me what you think?
Previously that was some files that hold these constants like salt and broadcast token. But I couldn't find them in your decompiled version
I used http://www.javadecompilers.com/apk Did you use something different?
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
I see broadcast token here: https://github.com/Lash-L/roborock_decompiled/blob/b9a0741fae7f8e74152d3456e83155a2c2ccfbd2/resources/AndroidManifest.xml#L91
Here is it in a version from January:
I don't see anything about the salt though
I remembered it. I got it from here https://gist.github.com/rovo89/dff47ed19fca0dfdda77503e66c2b7c7#file-test-js-L28
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?
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
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