Accueil Routeurs 4G
routeur4g.fr est financé par ses lecteurs. Quand vous achetez en passant par les liens du site, nous pouvons toucher une commission d’affiliation.

[TUTO] Modification d'un firmware FW

oga83oga83 Membre Messages: 1121
Modifié (avril 2019) dans Routeurs 4G
Le but de ce tutoriel est de montrer le principe pour extraire les fichiers d'un firmware, les modifier ou en ajouter.
Cela permet d'ajouter des fonctionnalités à son routeur 4G :)

Attention : Il est réservé à des utilisateurs qui maîtrisent parfaitement les techniques employées.
Ne vous lancez pas dans ce genre de manipulations si ce n'est pas le cas.


1- Objectifs

Nous allons partir du firmware original d'un routeur B715s-23c pour le modifier de la manière suivante :
- allongement de la durée de session de l'interface Web (5 minutes, c'est vraiment trop court !)
- modification du logo de l'interface Web
- ajout d'un serveur telnet
Ces modifications sont assez simples, mais elles donnent les bases pour allez plus loin ;)

Le firmware de départ est le B715-23c_UPDATE_11.197.01.00.965.bin (d'origine) mais le principe serait le même pour un autre modèle et/ou une autre version.


2- Outils utilisés

- balong_usbdload, pour installer un loader dans le routeur qui va permettre de flasher un firmware par USB;
- balongflash, pour extraire les sections du firmware (cela peut également être fait avec qhuaweiflash, mais je trouve cela moins pratique); Egalement utilisé pour flasher le firmware final;
- qhuaweiflash, pour remplacer les sections du firmware et générer le fichier .BIN final.

En théorie, qhuaweiflash permet d'ajouter, modifier et supprimer des fichiers dans le firmware, mais je n'ai pas réussi à faire fonctionner correctement la fonction d'ajout (les fichiers sont uniquement ajoutés dans la racine). D'autre part, il est plus facile d'avoir l'arborescence complète sur son disque : on peut facilement faire des recherches, décompresser des fichiers, ...

Ces outils ont été développés par Forth32 (merci à lui !) et je les ai traduits à partir du Russe. La version originale en Russe se trouve ici. La version traduite ici.
Note importante : qhuaweiflash ne fonctionne que sur Linux.

Pour compiler balong_usbdload :
<code>balong-usbdload<br>makegit clone https://github.com/Oga83/balong-usbdload<br>cd 

Pour compiler balongflash :
<code>balongflash<br>makegit clone https://github.com/Oga83/balongflash<br>cd 

Pour compiler qhuaweiflash
<code>qhuaweiflash<br>qmake
makehttps://github.com/Oga83/qhuaweiflash<br>cd


3- Extraction des sections

Une fois que nous avons le firmware original et les outils, on met le tout dans le répertoire de son choix (/tmp/huawei pour la suite de ce tuto) :



Pour extraire les sections du firmware, on utilise la commande suivante :
balong_flash -e B715-23c_UPDATE_11.197.01.00.965.bin


Et on obtient un fichier par section :


Les 2 sections qui nous intéressent sont System et WEBUI. Il s'agit d'archives 'cpio'.
On peut extraire le système de fichiers qu'elles contiennent dans un répertoire avec la commande 'cpio' :
mkdir System<br>cd System<br>cpio -ivm -F ../10-00590000-System.bin<br>hm103.jpg

et on obtient le contenu de cette section :


On procède de la même manière avec la section WEBUI :
cd ..<br>mkdir WEBUI<br>cd WEBUI<br>cpio -ivm -F ../12-005b0000-WEBUI.bin



4- Modifications

4a- Modification de la durée de session

Le timeout de session est défini dans le fichier WEBUI/WebApp/common/config/webserver/timeout.xml
Il suffit modifier la valeur. Je la passe à 1440 minutes (1 jour), en remplacement des 5 minutes d'origine :
nano WEBUI/WebApp/common/config/webserver/timeout.xml


4b- Modification du logo

Il suffit de modifier le fichier WEBUI/WebApp/common/res/euap-icon2.png
pinta WEBUI/WebApp/common/res/euap-icon2.png

4c- Ajout du serveur telnet

Le routeur est basé sur une distribution Linux qui utilise une vieille version de Busybox qui, de plus, est limitée (pas de serveur telnet).
Busybox est un programme qui regroupe tout un ensemble d'utilitaires linux. On l'appelle le couteau Suisse du Linux embarqué.
Nous allons ajouter au routeur une version plus récente de Busybox.
Les binaires, compilés (avec librairies statiques), peuvent être téléchargés ici.
Pour le B715, la version ARMv7-1.21 fera l'affaire. On va la télécharger dans System/bin :

cd System/bin<br>wget <code>https://busybox.net/downloads/binaries/1.21.1/busybox-armv7l


Pour que le serveur telnet fonctionne, il faut créer au moins 1 utilisateur.
On va donc créer le fichier System/etc/passwd (qui n'existe pas dans le firmware d'origine) avec la ligne suivante :
root::0:0:root:/tmp:/bin/sh
Soit vous le faites avec votre éditeur préféré, soit avec la commande suivante :
printf "root::0:0:root:/tmp:/bin/sh\n" > System/etc/passwd

Et pour terminer, il faut lancer le serveur telnet au démarrage (en utilisant le Busybox qu'on vient de télécharger).
Pour cela, on va ajouter une ligne à la fin du fichier System/etc/autorun.sh :
busybox-armv7l telnetd -l /bin/sh
Encore une fois, soit vous le faites avec votre éditeur préféré, soit avec la commande suivante :
printf "\nbusybox-armv7l telnetd -l /bin/sh\n" >>System/etc/autorun.sh
(notez bien qu'on utilise ">>" pour ajouter la ligne à la fin du fichier)



Voilà, nos modifications sont terminées !
Il faut maintenant les injecter dans le firmware.


5- Génération du firmware modifié

On procède à l'envers de l'extraction de fichiers.
Générer les archives cpio :
cd System<br>find . -print | cpio -ov -H newc -F ../10-00590000-System-mod.bin <br>cd ../WEBUI<br><div>find . -print | cpio -ov -H newc -F ../12-005b0000-WEBUI-mod.bin </div>


Pour réinjecter ces sections modifiées dans le firmware, on lance qhuaweiflash, et on ouvre le firmware d'origine :

Et pour chacune des 2 sections System et WEBUI, on utilise le menu "Section/Remplacer", en sélectionnant les fichiers crées juste avant (10-00590000-System-mod.bin et 12-005b0000-WEBUI-mod.bin) :

Une fois que c'est fait, il suffit d'enregistrer (menu "Fichier/Enregistrer sous"), et vous obtenez un .BIN qui contient vos modifications

Il ne reste plus qu'à le flasher !
Pour cela, on utilise balong_usbdload et balong_flash, mais c'est pour un autre tuto !

Une fois que c'est fait, on peut accéder au routeur avec telnet :)
telnet 192.168.0.1



Message edité par ludovick on
«1345

Réponses

  • NicolasNicolas Membre Messages: 569
    Excellent tuto, merci @oga83 !
    C'est indiqué au début, mais a répéter : ne pas s'y aventurer si vous ne maîtrisez pas les concepts et les environnements linux.
  • yyvon66yyvon66 Membre Messages: 929
    Modifié (avril 2019)
    bravo, je suis admiratif,
    ce qu'il me plairait de modifier, ce serait par rapport au firmware d'origine, de retrouver l'agrégation (B1, B3, B7) par exemple, ce que je n'ai plus maintenant,
    et en information système, je n'ai plus la bande utilisée,
    mais ce n'est peut être pas évident,
    mais bravo 
  • anglophoneanglophone Membre Messages: 76
    super excellent tutorial @oga83 bravo
  • oga83oga83 Membre Messages: 1121
    Modifié (avril 2019)
    Pour ceux qui veulent utiliser tcpdump directement sur le routeur, cette version binaire armv7 fonctionne très bien.
    Exemple avec telnet sur le routeur :


    Message edité par ludovick on
  • NicolasNicolas Membre Messages: 569
    Modifié (avril 2019)
    @oga83 : tu crois que c'est réalisable de faire tourner Huawei Monitor directement dans le firmware du routeur avec écriture sur une clef usb connecté dessus ?
    Ça permettrai de n'avoir que le routeur et de recuperer les stats via son pc pour analyse si necessaire :)

    Un firmware B715s signé Oga83 😎😉
  • oga83oga83 Membre Messages: 1121
    Modifié (avril 2019)
    Hehe, tu y as pensé aussi ? :)
  • NicolasNicolas Membre Messages: 569
    Techniquement ça doit passer, a voir si la charge va pas pénaliser le routeur :)
  • oga83oga83 Membre Messages: 1121
    La charge serait beaucoup plus faible sur le routeur car il n'y aurait pas besoin de faire les requêtes http
  • NicolasNicolas Membre Messages: 569
    😎 y'a plus qu'a ! mais ça demande a réécrire les requêtes du coup 🤔
  • MavrikMavrik Membre Messages: 1469
    Je propose d'ajouter une fonction / bouton pour pouvoir sauver et rappeller une configuration du modem.

  • oga83oga83 Membre Messages: 1121
    Modifié (avril 2019)
    Avoir TcpDump sur le routeur est assez pratique : ça permet de visualiser le trafic wan généré par le routeur (qui ne provient pas du lan), et qui est inaccessible côté lan :)
    C'est par exemple le cas quand le routeur vérifie si une mise à jour existe.
    Par exemple, on peut lancer la commande suivante pour sauvegarder le trafic wan sur une clef USB :
    ./tcpdump -w /mnt/sdcard/usb1_1/update.cap -i eth_x
    Pour visualiser le trafic qui correspond à une demande de mise à jour, il suffit d'utiliser la fonction "Mise à jour" dans l'interface Web du routeur. Et hop, c'est enregistré !
    Le plus pratique est ensuite de lire le fichier de capture avec WireShark (sur un partage samba de la clef usb sur le routeur) :


    On peut voir que les mises à jour sont demandées avec un post de données Json :
    {<br>&nbsp;&nbsp;&nbsp; "rules":<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "IMEI":&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "RSA:xxxx=",<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "IMSI":&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "RSA:xxxx=",<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "DeviceName":&nbsp;&nbsp;&nbsp;   "B715s-23c",<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "FirmWare":&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "11.197.01.00.965",<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "HardWare":&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "xxxx",<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "DashBoard":&nbsp;   &nbsp;&nbsp; "21.100.45.00.03",<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "Cver":&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "965"<br>&nbsp;&nbsp;&nbsp; }<br>}<br>
    L'IMEI et l'IMSI sont chiffrés mais ce n'est pas grave si on souhaite les informations de son propre routeur.
    Pour récupérer son firmware actuel, il suffit de remplacer les informations de version par celles d'un firmware plus ancien et de simuler la demande avec curl :)

    Si ce genre de post vous plait, n'oubliez pas de le promotionner pour que j'en fasse d'autres ! :)

  • oga83oga83 Membre Messages: 1121
    C'est marrant comme l'analyse du firmware peut être intéressante...
    L'analyse de certains exécutables révèle de nouvelles api :)
    La 1ère sur laquelle je suis tombé (pas la plus intéressante car on a l'info ailleurs) n'est pas du tout référencée par l'interface Web du B715 : /api/net/cell-info
    Mais il y en a d'autres qui semblent plus prometteuses !



  • MavrikMavrik Membre Messages: 1469
    Modifié (avril 2019)
    comme le TR069 pas dans l'interface web mais dans le FW qlq part.

    celle ci c'est le CID en HEX
  • oga83oga83 Membre Messages: 1121
    avec le LAC/TAC, qu'on a ailleurs également.
    LE TR069 est dans l'interface du firmware en .182
  • NicolasNicolas Membre Messages: 569
    Modifié (avril 2019)
    j'attends le firmware made in Oga83 "Huawei B715s Firmware MOGA83" 😎
    Incluant Huawei Monitor, Jeedom pour la domotique et Nagios pour surveiller son lan.

    Bon, juste HM serait déjà énorme 😁
  • oga83oga83 Membre Messages: 1121
    Modifié (avril 2019)
    Maintenant qu'on a accès au routeur avec telnet et qu'on peut partager des fichiers avec Samba, il est temps de passer aux choses sérieuses :)
    Nous allons compiler notre premier programme qui va fonctionner sur le routeur.

    1- Premier programme

    On va commencer par quelque chose de très simple :
    #include <stdio.h><br>void main(void)<br>{<br>&nbsp;&nbsp; &nbsp;printf("Hello world !\r\n");<br>}<br>
    Je compile ça sur un Raspberry B+ que j'ai sous la main (et qui utilise aussi un Armv7), en prenant la précaution de linker en static pour qu'il n'y ait aucune dépendances sur les librairies :
    <div>cc test.c -o test -static</div><div></div>
    On récupère l'exécutable sur le routeur et on le lance :

    ça marche !
    Super simple, non ?
    Bon, ok, vous allez me dire que ça ne sert à rien...

    2- Utilisation des librairies dynamiques du routeur

    Pour passer à l'étape suivante, nous allons utiliser les librairies installées sur le routeur. C'est elles qui sont intéressantes puisqu'elles vont nous permettre d'accéder à ses entrailles ...
    Pour cela, il faut utiliser un compilateur avec la même version EABI (qui soit capable de linker les librairies dynamiques du routeur).
    Nous allons donc installer la toolchain Android. En fait, elle est déjà sur mon PC (installée avec Visual Studio).
    Nous avons également besoin de connaitre la version du sdk Android utilisé pour générer les librairies du routeur. Pour cela, on lance la commande suivante sur le routeur :
    grep sdk /system/build.prop

    C'est la version 19. Cela va nous permettre d'utiliser les bons fichiers de démarrage crtbegin/crtend. Ils doivent correspondre à la libc dynamique utilisée.
    Pour utiliser les librairies du routeur (/app/lib et /system/lib), nous allons les recopier sur le PC, dans le répertoire ./lib_router
    Cela nous permet de préparer notre commande pour compiler le même programme :
    gcc -o test test.c %Lib%/crtbegin_static.o %Lib%/crtend_android.o -I %Inc% -nostdlib -Wl,--dynamic-linker=/system/bin/linker -Wl,-Bdynamic -L./lib_router -lc<br>
    avec %Lib% et %Inc% qui pointent vers les répertoires de la toolchain Android 19.
    Je ne vais pas rentrer dans les détails de cette commande mais, en résumé, elle permet de n'utiliser que les librairies indiquées (celles du routeur, libc dans cet exemple), et d'utiliser le bon loader sur le routeur.
    On compile, et le programme donne le même résultat !
    Alors, quelle différence me direz-vous ? A part utiliser une commande beaucoup plus compliquée...
    Et bien cette fois-ci, on utilise uniquement les librairies présentes sur le routeur :
    Notre première compilation (statique - tout était embarqué dans le programme) générait un programme de 582ko alors que le deuxième programme ne fait que 6ko !
    Le second intérêt, c'est que maintenant, on peut utiliser les librairies spécifiques au routeur pour accéder à différentes fonctions...

    3- Affichage CellId, RSSI, ...

    On complète donc notre programme pour afficher les informations relatices aux CellId, RSSI, RSRP, RSRQ et SINR :
    <code>	unsigned char Buffer[64]; <br>	printf("Hello world !");

    // Affichage CellId
    AT_Locinfo(Buffer);
    printf("CellId=%d", *(int *)(Buffer + 16));
    // Affichage Rssi
    printf("Rssi=%s dBm", Buffer);
    // Affichage Rsrp/Rsrq/Sinr
    AT_Rsrp(Buffer);
    printf("Rsrp=%s dBmRsrq=%s dB", Buffer, Buffer + 8);
    // Affichage Sinr
    AT_Hcsq(Buffer);
    printf("Sinr=%d dB", (int)(*(int *)(Buffer + 12)*0.2));
    }
    #include <stdio.h><br>#include <string.h><br><br>void main(void)<br>{<br>
    On ajoute les librairies correspondantes à la ligne de commande, on compile, on transfère, sur le router et on exécute :

    On peut comparer ces valeurs avec ce que donne Huawei Monitor :

    et on trouve pareil ! Enfin presque...
    On peut remarquer que les informations du RSSI et du SINR ne sont plus clampées (comme dans les API ou l'interface Web). On a ici les vrais valeurs de la baseboard :)
    Côté performance, notre programme n'a aucun impact sur le CPU. On peut faire des centaines de requêtes par secondes !

    4- Et après ?

    Quand j'aurai un peu de temps et de courage, j'écrirai un démon Huawei Monitor qui tournera sur le routeur pour enregistrer sa base de données sur une clef USB. Un partage Samba permettra de visualiser les données en même temps sur son PC :D
    Si ce genre de post vous plait, n'oubliez pas de le promotionner pour que j'en fasse d'autres !
  • NicolasNicolas Membre Messages: 569
    Une machine @oga83 ! Bien joué :)
  • MavrikMavrik Membre Messages: 1469
    Quand le maitre parle les disciples écoutent !
    ça parait si simple quand on maitrise comme toi
    Merci pour tes explications.
  • MavrikMavrik Membre Messages: 1469
    Modifié (avril 2019)
    Il va falloir qu'on discute, car du coup cela ouvre bcp de possibilités si on peut avoir d'autres infos que celles disponibles par les API, surtout si HM est "embedded"
  • oga83oga83 Membre Messages: 1121
    Mavrik a dit :
    ça parait si simple
    C'est simple une fois que c'est fait. Mais ça a quand même demandé pas mal d'essais...
  • oga83oga83 Membre Messages: 1121
    Petit teaser :)

  • oga83oga83 Membre Messages: 1121
    Modifié (avril 2019)
    Nicolas a dit :
    Techniquement ça doit passer, a voir si la charge va pas pénaliser le routeur :)
    Premier élément de réponse :)
    Le temps cpu sur le routeur est négligeable. %CPU à 0% et TickDuration à ~80ms (contre ~400ms en remote) :

    ça vient principalement du fait qu'on ne passe pas par le serveur web intégré mais directement par les api d'accès à la baseboard.
  • yyvon66yyvon66 Membre Messages: 929
    Modifié (avril 2019)
    Message edité par yyvon66 on
  • yyvon66yyvon66 Membre Messages: 929
    aprés relecture du post, si je comprends bien, ça ne fonctionne pas sous windows, pas même en ligne de commande
    pour compiler :smile:
    export QT_SELECT=qt5
    qmake
    make
    ça ne marche que sous linux ?? c'est cela

    on trouve 2 .exe en :
    firmware\balongflash-master\release\balong_flash.exe 
    et
    firmware\balong-usbdload-master\winbuild\Release\balong_usbdload.exe

    mais rien pour \firmware\qhuaweiflash-master, pas d'.exe

    à quoi servent ces 2 exe balong_flash et balong_usbload
  • MavrikMavrik Membre Messages: 1469
    c'est réservé aux personnes qui maitrisent le sujet, les lignes de commandes ET les modifs de FW (c'est du bas niveau), car tu peux totalement casser un modem avec un FW modifié ayant un bug / la moindre erreur.
    Ce n'est pas du tout juste utiliser les outils de flashage ici.
  • oga83oga83 Membre Messages: 1121
    Effectivement, qhuaweiflash ne fonctionne que sous Linux, comme indiqué dans le post initial (Point 2 - "Note importante : qhuaweiflash ne fonctionne que sur Linux").
    Pour balong_usbdload et balongflash, il y a une explication ici. Ils fonctionnent sous Windows et Linux.


  • oga83oga83 Membre Messages: 1121
    Modifié (mai 2019)
    J'ai préparé 2 firmwares pour le B715 :
    Les modifications apportées par rapport au firmwares d'origine sont les suivantes :
    - Modification du logo
    - Durée de session passée à 24h (au lieu de 5 minutes)
    - Ajout de l'utilitaire tcpdump
    - Possibilité de lancer le script /hme/autorun.sh sur une clef usb
    Cela permet de lancer le serveur telnet ou "Huawei Monitor Embedded" (en préparation).
    Pour lancer telnet, il faut ajouter le fichier autorun.sh dans le répertoire hme d'une clef USB avec le contenu suivant :
    <div>#!/system/bin/busybox sh<br>busybox-armv7l telnetd -p 24 -l /bin/sh<br></div>
    Quand on démarre le routeur avec ce fichier sur la clef USB, le serveur telnet est lancé.
    Sans ce fichier, ou sans clef, Telnet n'est pas lancé.
    Cela permet de choisir sans avoir à reflasher un firmware.
    Pour ceux qui veulent vérifier le contenu de ces firmware, il suffit d'utiliser qhuaweiflash (voir plus haut dans ce fil de discussion).


  • yyvon66yyvon66 Membre Messages: 929
    Modifié (mai 2019)
    merci de ton investissement,

    j'ai installé la version B715-23c_UPDATE_11.197.01.00.965-oga83 , ça marche nikel
    ce qui est bien, on retrouve bien ses réglages aprés flashage,

    qu'est-ce que donne de lancer le serveur telnet ? en ais-je l'utilité,
    bonne soirée, a+

    ps : est-ce mieux ce 965 qui est en 11.197 ou de mettre le 11.196.01.00.1217 ?
  • NicolasNicolas Membre Messages: 569
    a l'occaz je testerai pour après lancer Huawei Monitor :)
    good job !
  • oga83oga83 Membre Messages: 1121
    yyvon66 a dit :
    qu'est-ce que donne de lancer le serveur telnet ? en ais-je l'utilité,
    ça peut servir à sauvegarder sa nvram (nv.bin).
    Mais, à mon avis, l'application la plus intéressante est de pouvoir lancer tcpdump pour faire de l'analyse de trafic réseau côté WAN. Par exemple, pour surveiller les paquets entrants.
    Dans cet exemple, on écoute ce qui rentre côté WAN (pas les réponses à ce qui est sorti) en éliminant les paquets DNS destinés au routeur. Si une connexion ou un scan est fait sur notre IP WAN, on le verra. Normalement, on ne doit pas avoir grand chose. Dans mon cas, c'est juste le keepalive udp du VPN :

Connectez-vous ou Inscrivez-vous pour répondre.