Vous êtes sur la page 1sur 10

Chargement d’un firmware sous IDA PRO - II

1. Introduction
Dans la dernière version, nous avons selon le firmware :

 Créer les bons segments


 Transférer le firmware dans la FLASH
 Créer le point d’entrée
 Créer la routine BootStrap
 Transférer le LOADER en RAM
 Détecter la routine qui démarre le boot en RAM : RamBoot

Dans le cas des firmwares type C, D et B-PVR comme ils utilisent les instructions ASE16 que
IDA PRO gère très mal, la routine RamBoot est mal détectée :

Ce qui est faux et cela est du à l’instruction jalx que IDA confond avec un JUMP vers une
adresse locale, c’est pour ça que vous avez le « FUNCTION CHUNK » qui vous dit qu’un
autre morceau de la routine se trouve là-bas, allons-y :

Et vous pouvez voir que cela ne correspond à rien, en effet, dés qu’on voit des instructions
bizarres, des trucs qui utilisent le coprocesseur 2, ou des machins comme $v12[0], dites-vous
qu’il s’agit d’instructions 16 bits !

1
Donc j’ai ajouté au script T@LIS, la bonne détection de la première routine :

Cela est correct mais comme vous voyez IDA PRO, continue de penser qu’il y a un morceau
de fonction autre part !

Maintenant, pour continuer le désassemblage, il faut jouer avec la valeur du segment et le


faire manuellement car rapidement, vous allez obtenir de mauvais désassemblage et il faudra
recalculer les offsets et le script va commencer à devenir trop lourd et vraiment trop lent !

Mais comme le maincode en C semble être en MIPS32 classique, nous pourrons donc peut
être utiliser les routines utilisées pour le B Old !

Donc à la fin du script pour le C, vous aurez ceci :

Start of T@LiS 0.2.0

Segments already prepared!


No Maincode loaded!
Map register already loaded!
Loader already in RAM!
Ramboot already created at RAM:8068DB10
End of function at RAM:8068DB40
No more disassembling for firmware type C, it will be made in D@LI!
Delete local script variables..
Thanks to have used my script, PRC-600 from S@tGate Team

2
2. Terminer le désassemblage
Revenons, donc vers notre firmware type B Old, le système va donc maintenant créer une
structure d’appel hiérarchique de façon à ce que vous pouviez rapidement voir les différentes
routines et leur ordre d’appel !

Avant tout, il va vous proposez d’effacer les anciens noms de fonctions si nécessaires :

Ne vous inquiétez pas les procédures de bases sont gardées !

Répondons « yes » et les routines déjà détectées sont renommées :

Et si vous allez voir dans l’onglet Names :

3
On voit qu’un certains nombres de routines ont été renommées, ce qui facilite la tache !

Il a également fait la même chose pour le boot_loader

Mais remarquez dans la fenêtre de message :

Start of T@LiS 0.2.0

Segments already prepared!


Maincode already loaded!
Map register already loaded!
Loader already in RAM!
Create RamBoot at RAM:8030E760RAM:803065B4: Can't find name (hint: use manual
arg)

Cached Sub Call : 0:8FC009DC


Cached Sub Call Calculated: RAM:803009DC
Delete local script variables..
Thanks to have used my script, PRC-600 from S@tGate Team

IDA PRO nous indique qu’il a rencontré un problème, allons voir à cette adresse :

Que voyons-nous, il a détecté un problème car on appelle une adresse qui n’existe pas, en
réalité elle indique au processeur qu’il doit utiliser une adresse qui n’utilise pas le cache, le
script à recalculer la bonne adresse !

Mais pour nous aider, ceci ne va pas arriver car le script va modifier le code pour réaliser
directement l’opération et vous aurez ceci :

Ainsi, nous avons quelque chose de rapidement exploitable !

4
Jusque ici, vous voyez que l’on trouvé une petite « centaine » (90) routines, or il y en a encore
des centaines pour le bootloader et des milliers pour le maincode !

Donc, le script va continuer et va tenter de trouver les autres routines en analysant le code
entre deux routines (en effet gcc, a tendance à rassembler les routines et mettre les données
séparées, pas en ASE16 malheureusement où il place les variables locales et les pointeurs
juste après) :

Voici, ce que nous obtenons :

On a déjà trouvez plus de 200 routines supplémentaires en moins d’une seconde !!! A la main
cela prend des heures…

Ici, on est encore uniquement dans le loader ! On pourra faire la même chose pour le
maincode plus tard !

Mes nous sommes parfois confrontés à un autre problème, certaines fonctions ne sont pas
correctement désassemblées, elles sont trouées :

5
Si vous poursuivez cette routine vous voyez que le code continue :

Qu’est-ce que cela ? Il s’agit d’une technique fortement employée, il s’agit d’une table de
saut, cela permet de prendre des actions selon la valeur d’un indice, regardez le code
supérieure vous voyez qu’on place l’adresse d’un emplacement après le CODE, il est même
indiqué par l’indication Off_xxxxx, on prend donc cette valeur et on multiplie $v1 * 4 et on
l’ajoute à cette adresse et ensuite on charge le contenu de cette adresse dans $v0 et on saute à
cette adresse !

Allons voir ce tableau d’adresse :

On voit que la valeur retourne vers la fonction, avec le script les « trous » vont être
désassemblés et si il y un « jal utilisant une adresse sans cache », il sera mis à jour en même
temps !

Et nous obtiendrons ceci :

Ceci aussi demande beaucoup de temps à faire mais va être réalisé rapidement (quelques
secondes pour le loader).

Nous avons désassemblé quasi tout le code du loader, il nous reste à voir les données, fournie
avec celui-ci, elle commence « normalement » après le RamBoot mais il est possible que
quelques routines existent après !

6
3. L’analyse des données
Bien, un autre affreux est de mettre en forme les données manuellement, en effet, il y a des
structures partout, des chaînes non trouvées,…

Nous allons donc essayer de déjà mâcher le travail !

Nous allons d’abord repérer dans la zone de donnée, toutes les valeurs qui pointe vers la zone
de code ou de données, ainsi nous allons déjà voir que certaines routines orphelines vont
trouver une référence d’appel !

Par exemple :

Plus sympa que de passer des heures à faire « d » pour transformer les .bytes en .word, un bon
gain de temps !

On voit maintenant comment son appeler les morceaux de code internes :

Et surtout, des trucs comme ceci :

7
Car on a trouvé des pointeurs vers des chaînes de caractères que l’on mis en forme et en
même temps les sous-routines associées et la routine qui utilise cette structure (Ramboot_2_6
dans notre cas).

Imaginez un petit « tpscrypt » qui traîne et hop, on remonte vers sa routine 

Maintenant tout n’est pas fini car on voit également ceci :

On voit bien que c’est une chaîne (ps : elle indique souvent le début de la zone de donnée ),
nous pouvons directement la transformé en texte mais nous n’avons aucune référence croisée,
donc elle nous sera peu utile sauf si au hasard du code vous trouvez son adresse créée par le
code :

8
Nous voyons que via les instructions $v5 = 0x8031E920, ce qui correspond à l’adresse de
notre chaîne, donc nous pouvons supposer qu’il suffit en général de chercher la partie basse
de l’adresse en automatique et bien le script le fait pour vous !

Donc, il va nous trouver les chaînes restantes et vous donnez dans le bas les chaînes qui ont
été trouvées mais qui ne semble pas avoir de référence, j’ai ajouté un petit algorithme pour ne
pas mettre n’importe quoi comme chaîne comme le fait la fenêtre string mais il a ses limites
également!

Et on obtient ceci :

Et comme on a les références croisées, on va pouvoir travailler plus à l’aise et dans la fenêtre
du bas, on peut voir :

Start of T@LiS 0.2.0

Segments already prepared!


Maincode already loaded!
Map register already loaded!
Loader already in RAM!
Ramboot already created at RAM:8030E760
Start of subroutines search............
Fail to create function at RAM:803090E4.................

Address of first subroutine found: RAM:8030094C


Check functions code...
Find Data...
Data begins at RAM:8030E914
Search pointers to internal area...
Search non detected ASCII Strings...
String at RAM:8030E920 : bug in vform: bad base referenced at RAM:80302060,
String at RAM:8030E938 : 0123456789ABCDEF referenced at RAM:80302100,
String at RAM:8030E94C : 0123456789abcdef referenced at RAM:80302108,
String at RAM:8030EAC4 : 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ referenced at
RAM:80302358,
String at RAM:8030EAEC : 0123456789abcdefghijklmnopqrstuvwxyz referenced at
RAM:8030236C,
String at RAM:8030EE58 : bad gzip magic numbers referenced at RAM:80305134,

9
String at RAM:8030EED4 : invalid compressed format (err=1) referenced at
RAM:8030546C,
String at RAM:8030EEF8 : invalid compressed format (other) referenced at
RAM:80305484,
String at RAM:8030EF1C : invalid compressed format (err=2) referenced at
RAM:80305474,
String at RAM:8030EF40 : out of memory referenced at RAM:8030547C,
String at RAM:8030EF50 : crc error referenced at
String at RAM:8030EF5C : length error referenced at
String at RAM:8030F008 : p1P1q referenced at
String at RAM:8030F338 : (null) referenced at RAM:80301F30,
String at RAM:8030F3B8 : on referenced at RAM:8030B770,
String at RAM:8030F470 : r503 referenced at RAM:8030C94C,
Delete local script variables..
Thanks to have used my script, PRC-600 from S@tGate Team

10

Vous aimerez peut-être aussi