Dragon863 / EchoCLI

A python command line tool for rooting your Amazon Echo dot 2nd generation
101 stars 13 forks source link

Interfacing with mixer, read-only fs and/or killing the mixer until the next reboot. #18

Open samsieber opened 1 year ago

samsieber commented 1 year ago

Hey, thanks for all your work on this so far. I've successfully rooted a device and I've been poking at it a little to see if I can use it as a home assistant voice interface. I saw your comment on hackaday (https://hackaday.com/2023/07/22/root-on-an-amazon-echo-dot/) about the mixer process that owns audio and such:

I did have a look at the audio mixer, it looks like routing through aux should be possible. It seems to be using tinyalsa, a stripped down version of alsa, to manager audio. The main problem is that there is a process which restarts itself after being killed that uses the microphone, and on android to edit init scripts you have to unpack and repack the boot image. The led ring seems like it should be pretty useful too

My apologies if you've come up with this and discarded it for other practicality reasons, but it's possible to kill the mixer until the next device reboot for stable microphone access. It seems like overwriting the mixer process at startup with an empty file via a bound mount prevents it from starting, as the init script just finds an empty file! So this is what I did locally to prevent the mixer process from coming back.

adb shell touch /data/local/tmp/fake-mixer
adb shell mount --bind /data/local/tmp/fake-mixer /system/bin/mixer
adb shell killall mixer

Of course it'll come back at startup, but it did get me thinking about what it's possible to do with bind mounts.

Dragon863 commented 1 year ago

Hello! I never did find a solution for this, so thank you so much for sharing your findings! I'm sure there will be a way to use this, and in theory it would also be a good way to start a process on boot if we directed it to a different executable. Just curious, what prevents this from tripping DM-verity? Anyway, the static noise you mentioned has been an issue for me too, but it seems that a hacky workaround is to play a blank wav file with tinyplay, but as you say it would be great to implement the original mixer somehow.

Regarding blocking OTAs, that should be entirely possible, if I recall correctly there's a process called "otad" in the system/bin directory that handles updates (although I can't remember if this method is still used on newer versions), so your method should apply there too.

I'm glad to see that there's other people wanting to use this hardware for home assistant, it would be great especially considering the low cost of these dots. Again, thanks for the amazing work, and I'll definitely investigate this more when I have time!

samsieber commented 1 year ago

I'm glad to hear it's useful.

Just curious, what prevents this from tripping DM-verity

IIUC, the main issue you've had is that the file system is read-only, and so you have to modify the files before boot, and the DM-verity checks the file system during boot. I side-stepped that entirely by only making changes after the device was booted, and only in memory until the next reboot. Using a bind mount tells the OS that the file /system/bin/mixer should actually be read from /data/local/tmp/fake-mixer, but it doesn't actually touch the original file, and it doesn't persist between reboots. While linux does have support for persisting new mounts between reboots, that requires updating a file listing those mounts, which is probably in that same read-only files system; so the bind mount is only a between reboots solution to DM-verity. Which also means it's not a good solution for running things on boot (or at least not any better than using ADB). Though it does provide a good way to plug into the OS and have it manage a custom script with autostart; e.g. replace mixer with your own script, and if the script dies the OS will restart it...

With that said, I have some ideas of where to go from here that doesn't actually require killing the mixer; I've found a few articles about installing custom certificate files to enable MITM proxying https traffic. So my next steps will probably be:

The two big unknowns are whether I can get the proxy to work, and whether audio goes over https in a simple-to-use format. I'll keep you posted.

Dragon863 commented 1 year ago

That's really interesting about how it works, thanks for the explanation (I've been using linux for a few years but some of the things like mounts I've never fully got my head around!) Good luck with the project, sounds like a good approach, and please do keep me posted :)

samsieber commented 1 year ago

A few updates:

Next steps:

Dragon863 commented 1 year ago

I found the executable on a separate repo (I can't remember which one), it was a generic arm statically compiled binary. I think where possible static is the way to go, but unfortunately lots of programs don't support it. If you want to write things yourself, I think the android ndk is the best way to go. Also regarding the first point, I've also found that power is often an issue, if you have a powered USB hub it might be worth a try

ericlewis commented 3 months ago

@samsieber did you ever figure out audio output for this?