err4o4 / spotify-car-thing-reverse-engineering

411 stars 5 forks source link

Firmware images for the Car Thing #22

Open lmore377 opened 1 year ago

lmore377 commented 1 year ago

Firmware dumps, OTA updates and premodded images can be found here: https://mega.nz/folder/NxNXQCaT#-n1zkoXsJuw-5rQ-ZYzRJw

If you have any carthing related files you want to upload, upload them here then make a comment on this issue. You shouldn't need a mega account but if it's giving you issues let me know. It'll also be completely anonymous if that's something you care about.

aarondj122 commented 1 year ago

now that you have been able to get a factory FW, is it possible to edit part of the boot scrip and flash the new FW? I am trying to figure out how hard it would be to disable the premium check, so that we can use the regular spotify account. What would we need to do to accomplish that task? when a mobile device is synced with the car thing (for the first time) every new boot starts up at the media screen and then the "need premium account" splash screen takes over. However, the media (whether spotify or other) continues to play in the background. Any thoughts?

lmore377 commented 1 year ago

The webapp can be edited on versions that use chromium so we can probably bypass the premium screen like that but I'm not entirely sure if qt-superbird-webapp would respond to commands from it. I'll poke around with that a bit.

aarondj122 commented 1 year ago

That would be great to know if that will work, I appreciate the reply and for looking into it for me! With my limited knowledge and skill set - I know for a lot of us having a custom firmware we can flash with usb connection to PC with a file would be amazing! It sounds like we might be a ways off from flashing custom FW?

lmore377 commented 1 year ago

Just poking around with inspect element a bit, if you delete the overlay portion while connected to a device without premium it'll clear away the premium screen and tapping the controls on screen works but the physical buttons are still dead. Someone with more experience in javascript & css could probably get it working 100% image

Zip file containing the html. This won't run on it's own you'll need to have car thing connected with adb enabled so you can forward the websocket port to your computer. Use adb forward tcp:8890 tcp:8890

webapp.zip

aarondj122 commented 1 year ago

Thank you! It is all beyond my scope. I am sure someone will get there. I might try and play around with it a bit and see what I can find out. As for the FW dump and the second screen you are working on, are you working on anything specific either app wise or hacking? A few of us on r/carthinghax have been posting some updates (that I have not seen on GitHub) you should come and say Hi!

johnventions commented 1 year ago

I'm on my phone right now but there are 3 places in the main.js file that set a permission in the permissionStore. The lines look like this: this.canUseCarThing=t.can_use_superbird

In this context, t is a response from an interapp call.

If you replace that with: this.canUseCarThing=1

It should hard code it as allowed instead of requiring premium Spotify. The code is minified so it's not super easy to parse through, but can someone let me know if that works for them? Screenshot_20221102-220504

There is another setting there called canPlayOnDemand. It might be worth overriding that as well.

lmore377 commented 1 year ago

Hey that worked! The preset buttons still aren't working but everything else works as expected and even hey spotify listens now. I'll try the playondemand flag to see if that gets presets working

johnventions commented 1 year ago

Oh wow. Let me know if it does. I'll scan the code a bit more and see if I can find the cause for the preset buttons if that's not it

lmore377 commented 1 year ago

Didn't work but I just realized that just the canUseCarThing flag lets you pick the song you want to listen to on playlists that normally only allow shuffling Edit: UI gets very buggy at times (might just be because I'm using a fresh spotify account with no listening history) and shufflle is still forced on. Previous song button is also greyed out and scrubbing in a song is disabled too. Skip gets disabled when you reach the 6 per hour limit.

(sidenote, i'm finding some good music that my normal spotify account would never play unless i looked for it lmao)

johnventions commented 1 year ago

This method might control presets?

isPresetButtonsEnabled() {
    return (t => {
        const {
            viewStore: e,
            permissionsStore: n,
            remoteControlStore: o,
            sessionStateStore: i,
            overlayController: r
        } = t;
        return e.appView === ac.MAIN && i.isLoggedIn && o.interappConnected && !0 === n.canUseCarThing && !r.isShowing("phone_call") && !r.isShowing("promo")
    })
}

Looks like it says presets enabled when:

It's worth clearing out one or two of them at a time and seeing what happens

williamtcastro commented 1 year ago

I think if you delete de && !r.isShowing("promo") might do the trick if promo means the premium ad or something like that

is there any other functions that call this method ?

lmore377 commented 1 year ago

Real quick, do you know of any good ways to clean up js code? The main.js file is just massive and every website I tried just failed when trying to upload it. It even makes the default ubuntu text editor freak out a bit lmao

johnventions commented 1 year ago

You can put it into: https://beautifier.io/

That will format it better so it's easier to parse through. Its still going to be compiled in to minified code but at least it will have line breaks and spaces

lmore377 commented 1 year ago

That's the one I first tried but this just happens lol image

I'll try again on my PC

williamtcastro commented 1 year ago

I usually use vscode to clear the code, it works pretty well.

Can you upload the file you're trying to clean, I don't have access to a car thing as by now.

lmore377 commented 1 year ago

It's just main.js. If you want I can forward the websocket from my car thing over ngrok or something so you can play around with the webapp

williamtcastro commented 1 year ago

That would be great, if you don't mind, or if would be easier to you can send me the webapp folder

aarondj122 commented 1 year ago

Thank you both for working on this! I figured there would be 1 string of code that has a “true” variable for Spotify premium check. I realized that there are a few hard stops in place. 1 when the device is first booted to get to the tutorial (passed the phone connection) the other one is after the phone has already connected. An interesting finding is that once you have passed the initial connection, after restart it defaults to the media playback before the “need premium” error.

lmore377 commented 1 year ago

@williamtcastro The webapp.zip I linked a few comments above is the whole webapp. It just stays blank (and spams websocket connections to the point of crashing a chrome tab) until it connects to a daemon running on the car thing. Just give me a bit ngrok isn't sending my password reset email

aarondj122 commented 1 year ago

I don’t know if this is relevant (credit to nulld3v on Reddit) created a modified APK for android devices - I am using it on my tablet to connect to car thing works without premium. Here are his notes:

For future devs/modders, here are the modifications included in this APK if you want to update this patch for a newer version of Spotify or something: • Modified p.d7t so the constructor always sets m to true. You can tell from the toString implementation that m represents canUseSuperbird. Setting it to true will make the Spotify app think that your current user account has permission to setup and manage Car Things, without this you can't setup the Car Thing using the app. This class is obfuscated so expect the classname to change in future revisions of the app • Modified com.spotify.superbird.interappprotocol.permissions.mo del. PermissionsAppProtocol$Permissions so the constructor always sets canUseSuperbird to true. This will make the app tell the Car Thing that you have a premium account, without this, the Car Thing will complain that you don't have premium when it boots

lmore377 commented 1 year ago

@williamtcastro got it to work finally. In main.js just replace ws://127.0.0.1:8890 with ws://8.tcp.ngrok.io:10907 Do you have a discord or something we can message through instead?

williamtcastro commented 1 year ago

Got working here

lmore377 commented 1 year ago

For the preset keys its 1,2,3,4, for power/settings menu it's M, enter is select, esc is back and left/right arrows simulate turning the wheel left and right. Let me know if you want me to test hey spotify because that only uses the mics on the device itself

mogorman commented 1 year ago

thank you @lmore377 was able to get things going with your newer image.

williamtcastro commented 1 year ago

The connection is kinda slow but I've manage to clean the code and reading the functions

lmore377 commented 1 year ago

I'll heart some random playlists and stuff so that way there's a bit more to play around with. Feel free to play/pause and adjust the volume. The device it's connected to is muted anyways

williamtcastro commented 1 year ago

@lmore377 Apparently the connection died, I'll be trying to change but by now I'll read the code and see if there's any functions that validate the premium block

In the mean time here the clean version of the code (Change to .js after downloading) main.txt

lmore377 commented 1 year ago

I restarted the daemon on the car thing itself so you can try again. I'm honestly not surprised it died considering its being forwarded multiple times (adb then ngrok). Also I don't think the daemon likes having more than one connection at the same time lol

williamtcastro commented 1 year ago

I found this function when the app boots, using useEffect it call either or not the modal should be shown.

image

williamtcastro commented 1 year ago

I restarted the daemon on the car thing itself so you can try again. I'm honestly not surprised it died considering its being forwarded multiple times (adb then ngrok). Also I don't think the daemon likes having more than one connection at the same time lol

Yeah the connection is not working, I'll be heading off for today, but I'll receive my carthing by the next week, and I'll try to tinker with it asap.

lmore377 commented 1 year ago

Alright sounds good. I'll poke around a bit more in the js file now that my text editor can actually open it

ckosmic commented 1 year ago

I recommend reverse-sourcemap for un-minifying the webapp into multiple files and directories. It won't run since the paths are all messed up and it doesn't generate a package.json, tsconfig.json, etc., but it works nicely for readability

lmore377 commented 1 year ago

Looks like spotify might've originally planned to allow non premium users to use car thing. There's functions that check if there's an ad playing and disable playback controls if there is.

lmore377 commented 1 year ago

Got presets working! You just need to also delete !0 === n.canUseCarThing && completely. Easiest way to start using car thing without premium is to flash the updated image in the first post of this issue (its the second link), boot it up while connected to a PC then run these adb commands to override the main.js on the device:

adb shell mount -o remount,rw /
adb push main.txt /usr/share/qt-superbird-app/webapp/static/main.js
adb reboot

"Hey Spotify" will be disabled on every reboot but you can just turn it on in the options menu. Also just pair to it through your phone settings. That'll bypass the premium popup when trying to pair it thru the app settings

Merlin04 commented 1 year ago

You can also use browser devtools to look at the sourcemapped code and debug the app from the original source, with complete folder structure! image

aarondj122 commented 1 year ago

This is amazing! I am excited to get the new firmware flashed. I am using a Mac, is it possible to boot and run ADB using this? What tools/software do I need to get this running?

lmore377 commented 1 year ago

I think you should be able to do it on Mac as long as you have libusb installed. Use one of these to put the car thing into burn mode:

https://github.com/bishopdynamics/superbird-tool https://github.com/frederic/superbird-bulkcmd

Then just run undump.sh in the folder with the dump. There's also a text file in there with all the changes I've made

fonix232 commented 1 year ago

@lmore377 the original repository from frederic won't work - it's a binary compiled for Linux, and macOS, albeit *nix compliant, can't run that.

The superbird-tool repo however works perfectly on macOS!

johnventions commented 1 year ago

.... And what about windows? 😅

bishopdynamics commented 1 year ago

It works on windows too!

williamtcastro commented 1 year ago

Received mine yesterday and I'm already on track to try some new things. just got a few problems regarding the version, since mine is in 6.39, and trying to update it to the v8

williamtcastro commented 1 year ago

Manage to update to v8 using the provided latest firmware from @lmore377 and using @bishopdynamics toolkit in macOS

Steps:

williamtcastro commented 1 year ago

@lmore377 I've tried to replicate again the non-premium version and I've found out that is easier to change all the t.car_use_carthing property to true in the main.js file, and the result.can_use_carthing to true on the main.map.js.

I'll soon be creating a repo with a step-by-step process to a non-premium carthing version. Still need to fix some problems regarding the setup that still needs a premium account

williamtcastro commented 1 year ago

I've managed to by pass the setup process and create a nonpremium version already setup, I'll soon be posting it here.

williamtcastro commented 1 year ago

Finally I've created the repo with the installation process: https://github.com/williamtcastro/carthing-non-premium-spotify

FlyingThaCat commented 7 months ago

i wonder can we get the websocket binary things ?? maybe can i run it locally without car thing ?

FlyingThaCat commented 6 months ago

i try to run the binary but it seems to be broken ???

 # ./qemu-arm-static usr/bin/qt-superbird-app -platform linuxfb --headless-mode true  --no-sandbox 
2024-03-05T12:13:22.923Z [D] main.cpp:66 BOOTMARK: main(): 5ms
Could not convert: --phone-port = latform
Run with --help for more information.
2024-03-05T12:13:22.962Z [D] main.cpp:73 BOOTMARK: Config Parsed: 45ms
QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-root'
This plugin does not support createPlatformOpenGLContext!
2024-03-05T12:13:23.265Z [D] main.cpp:78 BOOTMARK: QApplication created: 348ms
Attribute Qt::AA_ShareOpenGLContexts must be set before QCoreApplication is created.
2024-03-05T12:13:23.550Z [V] Timer.h:97 Timer 1 (0x4c5470) with timeout 7000 ms created
2024-03-05T12:13:23.550Z [D] main.cpp:117 BOOTMARK: Splash screen rendered: 633ms
2024-03-05T12:13:23.554Z [I] main.cpp:127 Setting INFO logging because app is running on a release OS
2024-03-05T12:13:23.554Z [I] SuperbirdConfig.cpp:39 Spotify Superbird Application: HEAD-v0.24.107-gc424f0fa
2024-03-05T12:13:23.554Z [I] SuperbirdConfig.cpp:40 vSDK: v1.4-v1.4.0-g2006d779--dspc
2024-03-05T12:13:23.569Z [I] RemoteConfigManager.cpp:136 Config loaded {}
WebEngineContext used before QtWebEngine::initialize() or OpenGL context creation failed.
[0305/121323.671333:WARNING:resource_bundle_qt.cpp(116)] locale_file_path.empty() for locale 
[0305/121324.037720:WARNING:resource_bundle_qt.cpp(116)] locale_file_path.empty() for locale 
[5732:5732:0305/121324.047978:FATAL:thread_helpers.cc(41)] : No such file or directory (2)
qemu: uncaught target signal 5 (Trace/breakpoint trap) - core dumped
2024-03-05T12:13:25.269Z [I] vSDK:0 SendWakeword (1, 0)
2024-03-05T12:13:25.269Z [I] vSDK:0 SendWakeword [0]
2024-03-05T12:13:25.269Z [I] vSDK:0 SendWakeword (2, 0)
2024-03-05T12:13:25.269Z [I] vSDK:0 SendWakeword [0]
2024-03-05T12:13:25.269Z [I] vSDK:0 SetVoiceEncoding (1, 32000)
2024-03-05T12:13:25.270Z [I] vSDK:0 SetVoiceEncoding [0, 0, 0, 0, 0]
2024-03-05T12:13:25.270Z [I] vSDK:0 SetHPFFrequency (0)
2024-03-05T12:13:25.270Z [I] vSDK:0 SetHPFFrequency [1]
2024-03-05T12:13:25.270Z [I] vSDK:0 SetMuted (1)
2024-03-05T12:13:25.270Z [I] vSDK:0 SetMuted [0]
Cannot find a running Bluez. Please check the Bluez installation.
2024-03-05T12:13:25.326Z [I] BluetoothManagement.cpp:617 Advertising iAP2
qt.bluetooth.bluez: Device does not support Bluetooth or "00:00:00:00:00:00" is not a valid local adapter
2024-03-05T12:13:25.334Z [E] StorageClient.cpp:163 Could not open directory /var/lib/qt-superbird-app/settings/paired_devices/
2024-03-05T12:13:25.337Z [I] StorageClient.cpp:77 Could not open /var/lib/qt-superbird-app/settings/paired_devices/default
2024-03-05T12:13:25.339Z [I] CrashManager.cpp:83 Boot result timer started...
2024-03-05T12:13:25.341Z [W] ChainedEventBroker.cpp:15 Attempt to register the same component twice to EventBroker: TEST
terminate called after throwing an instance of 'std::system_error'
  what():  cannot open file /proc/5727/oom_score_adj: No such file or directory
qemu: uncaught target signal 6 (Aborted) - core dumped
^[[AAborted (core dumped)
/ # ./qemu-arm-static usr/bin/qt-superbird-app -platform linuxfb --headless-mode true  --no-sandbox 
2024-03-05T12:13:27.132Z [D] main.cpp:66 BOOTMARK: main(): 5ms
Could not convert: --phone-port = latform
Run with --help for more information.
2024-03-05T12:13:27.169Z [D] main.cpp:73 BOOTMARK: Config Parsed: 42ms
QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-root'
This plugin does not support createPlatformOpenGLContext!
2024-03-05T12:13:27.463Z [D] main.cpp:78 BOOTMARK: QApplication created: 336ms
Attribute Qt::AA_ShareOpenGLContexts must be set before QCoreApplication is created.
2024-03-05T12:13:27.719Z [V] Timer.h:97 Timer 1 (0x4c5520) with timeout 7000 ms created
2024-03-05T12:13:27.719Z [D] main.cpp:117 BOOTMARK: Splash screen rendered: 593ms
2024-03-05T12:13:27.723Z [I] main.cpp:127 Setting INFO logging because app is running on a release OS
2024-03-05T12:13:27.724Z [I] SuperbirdConfig.cpp:39 Spotify Superbird Application: HEAD-v0.24.107-gc424f0fa
2024-03-05T12:13:27.724Z [I] SuperbirdConfig.cpp:40 vSDK: v1.4-v1.4.0-g2006d779--dspc
2024-03-05T12:13:27.734Z [I] RemoteConfigManager.cpp:136 Config loaded {}
WebEngineContext used before QtWebEngine::initialize() or OpenGL context creation failed.
[0305/121327.827164:WARNING:resource_bundle_qt.cpp(116)] locale_file_path.empty() for locale 
[0305/121328.173929:WARNING:resource_bundle_qt.cpp(116)] locale_file_path.empty() for locale 
[5774:5774:0305/121328.184361:FATAL:thread_helpers.cc(41)] : No such file or directory (2)
qemu: uncaught target signal 5 (Trace/breakpoint trap) - core dumped
2024-03-05T12:13:29.432Z [I] vSDK:0 SendWakeword (1, 0)
2024-03-05T12:13:29.433Z [I] vSDK:0 SendWakeword [0]
2024-03-05T12:13:29.433Z [I] vSDK:0 SendWakeword (2, 0)
2024-03-05T12:13:29.433Z [I] vSDK:0 SendWakeword [0]
2024-03-05T12:13:29.433Z [I] vSDK:0 SetVoiceEncoding (1, 32000)
2024-03-05T12:13:29.433Z [I] vSDK:0 SetVoiceEncoding [0, 0, 0, 0, 0]
2024-03-05T12:13:29.434Z [I] vSDK:0 SetHPFFrequency (0)
2024-03-05T12:13:29.434Z [I] vSDK:0 SetHPFFrequency [1]
2024-03-05T12:13:29.434Z [I] vSDK:0 SetMuted (1)
2024-03-05T12:13:29.434Z [I] vSDK:0 SetMuted [0]
Cannot find a running Bluez. Please check the Bluez installation.
2024-03-05T12:13:29.493Z [I] BluetoothManagement.cpp:617 Advertising iAP2
qt.bluetooth.bluez: Device does not support Bluetooth or "00:00:00:00:00:00" is not a valid local adapter
2024-03-05T12:13:29.504Z [E] StorageClient.cpp:163 Could not open directory /var/lib/qt-superbird-app/settings/paired_devices/
2024-03-05T12:13:29.506Z [I] CrashManager.cpp:83 Boot result timer started...
2024-03-05T12:13:29.507Z [I] StorageClient.cpp:77 Could not open /var/lib/qt-superbird-app/settings/paired_devices/default
2024-03-05T12:13:29.512Z [W] ChainedEventBroker.cpp:15 Attempt to register the same component twice to EventBroker: TEST
2024-03-05T12:13:29.520Z [I] VsdkManager.cpp:793 VsdkManager::start created vsdk thread 29291380
terminate called after throwing an instance of 'std::system_error'
  what():  cannot open file /proc/5769/oom_score_adj: No such file or directory
2024-03-05T12:13:29.538Z [I] vSDK:0 Run ()
qemu: uncaught target signal 6 (Aborted) - core dumped
Aborted (core dumped)