BEEWi: SiMPLY WiRELESS : Bluetooth App Reversing
Auteur : Xartrick
Zine : Rafale #19
Beewi, simplement sans fils, voilà ce qu'ils nous envoient comme slogan. Et
oui, j'ai été séduit par une de leurs conneries. Une Mini Cooper S qui
fonctionne sans fil, comme promit, et qui peut être contrôlée par un
smartphone. Elle est contrôlée par une application développée par l'entreprise
afin de contrôler les appareils qu'ils ont créé. Cette application est
disponible sur la majorité des systèmes d'exploitations des smartphones: iOS,
Android, Windows Phone et sûrement d'autres.
Caractéristiques
----------------
Puce Bluetooth : Bluetooth 2.0+EDR, CSR BC4
Portée du Bluetooth : minimum 10 mètres, jusqu'à 15 mètres (Classe 2)
Profils Bluetooth : Wireless iAp
Alimentation : 3 Piles AA (non fournies)
Autonomie : Jusqu'à 3 heures
Contrôles : Avant / Arrière et contrôle du volant
Dimensions : 179 mm x 98 mm x 74 mm
Poids : 205 g
Echelle : 1:20
Je suis (tristement) propriètaire d'un téléphone sous iOS, et donc, la honte
est sur moi. Bref! J'installe leur appli', je met ma voiture en position ON, et
je démarre l'application.
Fuck It! Aucune voiture n'a été détectée. Alors, je pense à un simple défaut
sur le produit, ou une merde dans le genre. Je fais donc toute une batterie de
tests (allant même jusqu'à tester si les composants était bien sous tension,
mais tout est OK, pas de soucis). Alors je décide de prendre un second
téléphone, sous Android cette fois. Et là, ho magie, ça marche du feu de Dieu !
Bon, c'est bien que ça marche, mais cela n'est pas mon téléphone, alors, faut
une autre solution.
Qu'est-ce que j'utilise le plus à part mon téléphone ? Mon ordinateur, bien
sûr. Y'a pas 36 milles solutions, faut que je reverse l'application pour savoir
comment marche la voiture, donc, cable USB, mode developpeur et à l'aide de
ADB, on va aller chercher notre application et la récupérer sur notre PC afin
de lancer l'analyse. Pour ça, il vous faut le SDK Android installé correctement
(rien de compliqué, je vous assure, même moi je l'ai fait). Lancez un shell là
où se trouve ADB et là, on va commencer à explorer le téléphone. Pour pouvoir
récupérer l'application, il faut d'abord savoir où elle se trouve. Déjà, on met
notre Android en mode developpeur puis on lance ADB et vérifiant si notre
téléphone est trouvé :
> adb devices
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
List of devices attached
5700a9****** device
OK, ça c'est bon, notre device est bien là, on peut maitenant trouver la liste
des applications installées avec une commande :
pm list packages -f
Donc on lance ça avec une petit grep sur le nom du machin pour pas se manger
une liste avec des dizaines d'applications :
> adb shell "pm list packages -f | grep remotecontrol"
package:/data/app/com.baracoda.android.bluetoothcar.remotecontrol.apk=
com.baracoda.android.bluetoothcar.remotecontrol
Maintenant qu'on sait où elle se trouve, on la récupère :
>adb pull /data/app/com.baracoda.android.bluetoothcar.remoteco
ntrol.apk
1450 KB/s (842916 bytes in 0.567s)
Et voilà, elle se trouve dans le répertoire courrant, plus qu'à la décompiler
et voir ce qu'elle cache. Comme vous le savez peut-être, le format APK est
simplement un ZIP avec une structure particulière. Il contient un fichier au
format DEX, qui lui contient le code de notre application. Les programmes sous
Android sont écrits en JAVA, et il existe un outil pour convertir ces fichiers
en DEX vers un fichier JAR. Je vous présente donc, dextojar (original n'est-ce
pas ?).
https://code.google.com/p/dex2jar/
Donc, on lance ce logiciel et on se retrouve avec un fichier JAR.
>d2j-dex2jar.bat classes.dex
dex2jar classes.dex -> classes-dex2jar.jar
Au début, j'étais parti pour décompiler l'application avec JD-GUI, mais
il n'arrive pas à la décompiler complètement.
Je me suis donc tourné vers autre chose, JAD.
http://varaneckas.com/jad/
Tout comme le format APK, le format JAR est également une archive ZIP. Pour
vous éviter les recherches, le code intéressant se trouve dans la classe
CarController qui se trouve dans:
.\com\baracoda\android\bluetoothcar\remotecontrol\
On extrait donc le fichier CarController.class et on le décompile avec JAD.
>jad CarController.class
On se retrouve avec des erreurs, mais c'est pas important, cela ne nous gènera
pas pendant le reverse.
Dans cette classe, on voit un code intéressant:
private void sendMoveForward(byte byte0) throws Exception {
if (connectionHelper != null) {
vibrate();
if (!lastPaused) {
connectionHelper.write(MOVE_FORWARD);
lastSendCommand = 1;
}
updateControllerImageViewMoveState(MoveDirection.Forward);
}
}
connectionHelper est ce qui nous permet de faire la passerelle entre le
téléphone et la voiture (via le Bluetooth). La méthode write envoit une suite
de bytes à la voiture. Ici, c'est MOVE_FORWARD.
private static final byte MOVE_FORWARD[] = {
1
};
Donc, si on envoit un octet avec comme valeur 1, on fait avancer la voiture,
intéressant non ? Et ça marche, vraiment...
Pour le reste c'est la même chose. Il faut savoir que chaque direction a deux
commandes, la commande d'action, et la commande d'arrêt. Le stop est la valeur
du mouvement moins un. Donc pour arrêter d'avancer en avant, on envoit 0.
Avancé: 1 Stop: 0
Reculé: 3 Stop: 2
Gauche: 5 Stop: 4
Droite: 7 Stop: 6
On a pas besoin d'en savoir plus, on connait déjà le protocol. On envoit un seul
octet par mouvement, simpliste comme protocol hein?
Pour commencer, on va mettre notre périphérique Bluetooth sur un port série
(port COM), ça je vous laisse faire, j'ai choisi le port COM9.
Allez, on va coder un peu, et comme personne aime le .NET, on va le faire en
Python, comme ça la plus part du monde sera content :D
Pour cela, on va utiliser pyserial:
http://pyserial.sourceforge.net/
Donc, on commence déjà par ouvrir notre port...
import serial
port = serial.Serial(8) ' Le port COM1 correspond a 0
port.close()
Voilà, on a notre base, ça suffit amplement. Maintenant, on va mettre en place
les mouvements:
def move(movement, sec=0.5):
global port
port.write(chr(movement))
time.sleep(sec)
port.write(chr(movement - 1))
Et voilà, on a notre fonction pour bouger (on oublie pas d'importer time hein).
On pose donc nos constantes:
MOVE_FORWARD = 1
MOVE_BACKWARD = 3
MOVE_LEFT = 5
MOVE_RIGHT = 7
Et c'est déjà fini, libre à vous après de faire votre programme qui réagit
selon les touches qu'on presse, d'intégrer un joystick et tout ce que vous
voulez d'autre !
import serial
import time
def move(movement, sec=0.5):
global port
port.write(chr(movement))
time.sleep(sec)
port.write(chr(movement - 1))
port = serial.Serial(8)
move(MOVE_FORWARD)
port.close()
Xartrick.
|