==Phrack Inc.== Volume 0x0c, Issue 0x41, Phile #0x0b of 0x0f |=-------------------=[ Hacking the $49 Wifi Finder ]=-------------------=| |=-----------------------------------------------------------------------=| |=-------------------------=[ by openschemes ]=--------------------------=| |=-----------------------------------------------------------------------=| |=--------------=[ traduit par TboWan pour arsouyes.org ]=---------------=| --[ Contents 1.0 - Introduction 2.0 - Survol du périphérique 3.0 - Ouverture du périphérique 4.0 - L'intérieur et les recherches 5.0 - Accéder au chargeur d'ISP 6.0 - Possibilités du chargeur d'ISP 7.0 - Possibilités du booloader logiciel 8.0 - Insérer votre propre code 9.0 - Conclusion A.0 - Références B.0 - Note du traducteur --[ 1.0 - Introduction Noël est passé, et pendant ces semaines de froid, nous nous sommes déjà lassé des jouets que le Père Noël nous a laissé sous le sapin. Nous n'avons plus qu'une solution, les hacker ! Ce papier décrit notre attaque réussie sur un wifi finder [NDT : matériel pour trouver des réseaux wifi], et vous fournira la capacité d'utiliser ce périphérique d'une nouvelle manière intéressante. Vous n'êtes limités que par votre créativité ! Toute attaque réussie doit commencé par la mise à plat d'un but clair. En pensant de manière déterminée et créative, vous verrez les étapes nécessaire pour atteindre le but. Juste dire "j'aimerais hacker ce périphérique" est sans intérêt sans contexte, et vous donner un but inateignable ne fera que vous enliser dans une étape intermédiaire et vous fera probablement abandonner le projet. Nous vous recommandons donc de commencer chaque hack en vous donnant de petites étapes, et à chaque étape terminée, vous ouvrirez de nouvelles portes et de nouveaux chemins d'investigation et de développement. Dans le cas du wifi finder, notre pénultième [NDT : avant-dernier] but était d'exécuter notre propre code dans son micro-contrôleur interne. Nous avons atteint ce but et nous allons vous décrire les étapes que nous avons effectuées pour l'atteindre. Il est facile de voir qu'en atteignant ce but, nous avons ouvert plein de nouveaux chemin pour étendre les possibilités de ce périphérique. Certaines sont faciles, comme permettre au périphérique de chercher des SSID cachés et de parcourir les canaux wifi non autorisés aux USA. D'autres sont imposantes, comme le développement d'un périphérique d'"aircracking" portable. Certains de ces sujets seront couverts dans le futur, mais nous vous encourageons à vous poser avec le périphérique et les connaissances que vous en avez, et de planifier votre propre chemin. Nous nous excusons si vous trouvez ce texte long, comme une description qui divague de noter attaque, mais nous pensons que c'est la MÉTHODE, et non le résultat qui est le vrai hack. Donnez un hack à un homme, et il pourra programmer son wifi-finder. Apprenez à un homme à hacker, et il pourra programmer n'importe quoi ... Les outils utilisés dans cette attaque sont les suivants : - De côté matériel, nous avons utilisé un convertisseur USB vers RS232 modifié pour communiquer avec le port série sur le wifi-finder. Un alternative à cette solution serait de construire notre propre convertisseur RS232 3.3V en utilisant le MAX3232 IC. Des schémas pour tout ceci sont disponibles plus loin. - Du côté des logiciels, nous avons utilisé une combinaison de désassembleur IDA [1] et d'assembleur A51 de Keil [2]. Cet assembleur peut être utilisé en ligne de commande ou dans l'IDE µVision de Keil. Les étapes principales du projets sont les suivantes : A) Ouvrir et identifier le périphérique et ses possibilités B) Chercher après une backdoor dans le périphérique C) Construire une interface pour communiquer avec le périphérique D) Faire des recherches sur les opérations internes du périphérique E) Étendre et modifier les opérations du périphérique c'est juste un bref survol du schéma de haut niveau, et comme vous allez vite vous en rendre compte, ça demande un peu de hacking bas niveau pour effectuer les étapes les unes après les autres. Nous espérons que vous trouverez ce texte instructif pendant que nous raconterons l'attaque de ce petit périphérique intéressant. --[ 2.0 - Survol du périphérique Actuellement, il y a peu de gammes de wifi-finder sur le marché. Certains périphériques peu coûteux ne font que détecter les variations des micro-ondes. Ils détecterons le 802.11 mais aussi certains téléphones sans fils, les bébéphones, ou l'inclassable maman qui réchauffe sa soupe au four à micro-ondes dans la rue. Ce ne sont que du n'importe quoi, ça consiste simplement en un amplificateur et un filtre de bande. La gamme suivante peut détecter les accès points, mais ne donne aucune information que les quelques led qui vous disent si c'est loin ou proche. C'est aussi n'importe quoi. La plus haute gamme actuelle de wifi-finder coûte entre 25 et 65 euros [NDT-1] et consiste en une carte wifi usb autonome connectée à un microcontrôleur et un écran LCD pour afficher les SSID, les canaux et la force du signal. Ils contiennent une petite pile lithium-ion pour une utilisation portable, et se recharge lui-même dès qu'il est connecté en au port USB. Vous pouvez facilement identifier ce périphérique car c'est le seul avec écran LCD ! Ce marché a été piégé par un développeur qui a vendu sa conception à plein de compagnies, il y a donc pour l'instant qu'un seul vrai produit qui a été refait en différents modèles. Après nos recherches, nous pensons que tous ces périphériques sont identiques du point de vue de leur potentiel en hacking, et ils sont tous vulnérables à notre attaque. Voici une liste de ce que nous avons trouvé jusqu'à présent dans les magasins ou sur internet (i.e. Amazon.com) : Constructeur Modèle Référence ------------ --------- --------- Allnet ALL-0298 [3] ZyXel AG-225H [4] ConnecTec AG-225H None TrendNet TEW-429UB [5] Linksys WUSBF54G [6] Tous ce périphériques partagent un facteur commun : une clef USB avec un bouton on-off et deux boutons pour l'utiliser seul : "Seek" et "Next". Seek Next ______________==_____==______ | ___________ |___ | | | _ | | HackMe | LCD | _ | USB | |___________| ___| |_____________________________| \_/ Bouton On-Off Allumer le périphérique quand ilest déconnecté d'un ordinateur lui fera démarrer les procédures de recherche. En plus, appuyer sur "Seek" fera redémarrer les procédures de recherche la plupart du temps. Un fois qu'un hotspot a été trouvé, appuyer sur Next les lui fera parcours, nous montrant le SSID, le canal, le type de chiffrement et la force du signal. En laissant appuyé seek pendant l'allumage, le périphérique lance des procédures de tests de l'écran et de l'horloge interne. En appuyant sur next pendant l'allumage, le périphérique entre en mode de mise à jours du firmware pour télécharger le firmware via USB. C'est vraiment une fonctionnalité merveilleuse ! Mais ne pensez par que nous patchons simplement le code ennuyeux du vendeurs et qu'on appelle ça un hack : Pour la plupart des périphériques que nous avons trouvé, le mode de mise à jours du firmware a été rendu obsolète et n'est plus capable d'uploader vers le microcontrôleur. Nous devons trouver un autre chemin dans le micro, et ils n'ont pas rendu le chemin facile. --[ 3.0 - Ouverture du périphérique Le périphérique le plus facile à ouvrir est le Zyxel/Allnet, suivi du Linksys et ensuite du TrendNet. À force de "dégrader" la fabrication, ces vendeurs l'ont rendu, sans le faire exprès, difficile à ouvrir sans l'endommager. Mais on ne s'en fait pas pour si peux, et même un TrendNet avec son petit onglet endommagé peut être fermé et rendu au magasin sans problème. Ce n'est pas que vous le feriez bien spur.. c'est juste un exemple. Pour ouvrir le périphérique, vous devrez retirer le panneau DU BAS (pas celui qui contient le LCD). Commencez à appuyer très fort sur l'arrière du périphérique, l'arrière étant la partie SANS la connexion USB. En appuyant près des coins arrières, le Zyxel s'ouvre facilement. Un petit levier avec le verrou peut faire des merveilles et ne laisser aucunes traces. Le TrendNet est verrouillé avec 6 petits onglets en plastic pas cher qui se casseront facilement quand vous tenterez de l'ouvrir. Mais le Trend est le moins cher sur le marché, c'est donc celui-là que vous tenterez d'attaquer le plus probablement. Bien sûr, vous pourriez toujours essayer de l'ouvrir en faisant levier avec un tournevis si vous ne vous inquiétez pas de le retourner ensuite. Une fois que le périphérique est ouvert, vous allez voir qu'il consiste en deux cartes intégrées connectées par un connecteur à 10-pin. La première carte est attachée avec une petite visse près de l'arrière du périphérique. N'ayez pas peur de la retirer, ou la manger, ou autre. Elle n'est pas nécessaire. La carte wifi/USB contient une puce ZD1211 802.11 et le sous-système RF. En gros, c'est la même chose qu'un adaptateur USB 802.11 générique qu'on peut acheter chez le même fabricant. Une fois que la visse est enlevée, vous pouvez prendre le connecteur USB et tortiller cette carte, la libérant du connecteur 10-pin qui la connecte à la carte du bas. La carte du bas contiens la cible de notre attaque, le mystérieux micro-contrôleur WHFX30 qui semble être le "cerveau" de l'opération. Voici une vue de côté de la manière dont les cartes sont ensemble. Quand vous regarderez du dessus pendant le désassemblage, vous noterez que la carte wifi a ses composant sur le bas, et la carte du microcontrôleur a ses composant vers le haut. Déconnecter les cartes est nécessaire pour voir les composants intéressants. Vue de côté des cartes du wifi-finder RF (shielded) ZD1211 USB Carte du haut _____________________________________ _ __________ |______________| \________/ |_| |_____| ____________ _____ | | carte du bas |____________|--____/ \________|_|_ Pile WHFX30 connecteur 10-pin --[ 4.0 - L'intérieur et les recherches Comme on l'a déjà mentionné, la carte du haut complète peut être utilisée comme carte wifi USB autonome pour votre PC. Cette architecture utilisant le chipset ZD1211 est très largement rependue, et pour nous : ennuyeuse. Pour des informations sur la carte et le périphérique ZD1211, je vous renvoie à l'excellent travail de la communauté Linux dont le driver et le code source sont disponibles librement en [7]. Vous pouvez y parcourir le code source pour découvrir les parties USB, la configuration des registres du ZD1211, le promiscuous mode, les canaux et d'autres chouettes informations. Mais il n'y a nulle part des informations sur le périphérique "WHFX30"... c'est un fantôme, une IC [NDT : Circuit Intégré] semi-personnalité qui se trouve dans l'esprit du finder. Puisque l'outil de mise à jours du vendeur du firware est trop limitée, nous devons trouver une manière de pénétrer les mystère de cette puce et y insérer notre code. En faisant des recherches en ligne sur le périphérique, nous avons vu d'excellent poins d'entrée pour notre attaque dans les investigations de J. Maushammer du périphérique [8]. M. Maushammer a été le premier à tenter d'hacker le périphérique et détient une belle masse d'informations. Il a émis l'hypothèse que le WHFX30 contienne un microcontrôleur 805x, et en désassemblant l'une des mises à jours du firmware, ça y ressemblait bien. Il a aussi souligné quelques blocs de données dans le firware du WHFX30, nous montrant la table des caractères et les graphiques de démarrage mais il n'a pas été plus loin. Peut-être avait-il un but plus noble, ou s'est-il lassé dans une étape intermédiaire. Nous sommes résolus de garder notre but clair : pénétrer le WHFX30. En fouillant les fichiers de mise à jours du firware, on peut voir que seul 15k block de mémoire à partir de 0x4000 est du code 8051. Cependant, il ne contient aucun vecteur de jmp (qui se trouverait en 0x0000) ou de procédures de gestions d'interruptions, ce n'est donc pas entièrement un programme 8051. en plus, les chaines de textes pour l'auto-test et l'outil de mise à jour automatique n'est pas autorisé à toucher une petite portion du code du périphérique : Spécifiquement les procédures du finder. Il nous montre aussi que le périphérique WHFX30 contient probablement plus que 16K de code en mémoire, ce qui est une bonne chose pour étendre ses possibilités. Nous allons prendre l'opportunité d'emprunter le brochage du connecteur 10-pin de Maushammer. Nous pourrions utiliser nos propres mots, mais il serait mieux de commencer directement à faire un standart sur ce qu'on défini dans le périphérique. Notez que la vue du connecteur est fait par le bas de la carte (WHFX30). On-Off Switch -----/ \---------------- ----- | 1 | o o | 2 | 3 | o o | 4 | 5 | o o | 6 | 7 | o o | 8 | 9 | o o | 10 | ----- | ---\_/----------------- "Next" Pinout ------ J1) Inconnu (pour l'instant) J2) Scan J3) Début du scan J4) GND J5) GND J6) Données USB (obsolète ?) J7) données série (ZD1211 TxD, WHFX30 RxD) J8) données USB (obsolète ?) J9) données série (ZD1211 RxD, WHFX30 TxD) J10) Prise électrique USB pour se charger (une fois connecté au PC) Quand on se retrouve face à une puce avec laquelle on n'est pas familier, le mieux est de commencer par collecter le maximum d'informations et de classer jusqu'à avoir une identification positive. Je pense qu'en gros, tous les périphériques tomberont dans une des trois catégories suivantes : A) Puce de production - les informations sur ces puces seront libres ou facilement disponibles. B) Puce semi-personnalisée passée sur une puce de production. - Les informations PEUVENT être disponibles, en fonction du secret de l'application de la puce. Par exemple, les machines ATM utilisent des CPU génériques et sûr 8051 mais aucun ne va jamais l'admettre devant vous. C) Puce complètement personnalisée - Uniquement faisable pour des gros volumes d'exécution, comme des puces graphiques spéciales pour la nouvelle playstation. À moins de travailler chez Sony ou Nvidia, la probabilité de trouver une information tend vers 0. Notre périphérique n'est pas dans A, et ce petit jouet USB ne doit pas être dans les C, nous sommes donc bloqués dans B : Probablement un puce "prêt à porter" (mais remaniée) ou au moins basée dessus. Voici un exemple de puce du type B, un CPU tout propre que j'ai vu dans un distributeur japonnais. Il y avait beaucoup trop de broches pour être un CPU normal, mais les circuits autour étaient trop grossier pour pouvoir être autre chose. Qu'était-ce finalement ? Et bien, c'était un microcontrôleur 8032 générique avec une puce EEPROM dans le même paquet. C'était construit uniquement pour ce constructeur de machines Pchislo, mais à l'intérieur, ce n'était que du prêt à l'emploi. Je pense que la raison est que sans savoir ce que c'est, les utilisateurs et les concurrents ne sont pas capables d'y accéder ? FAUX ! L'obscurité ne fait pas la sécurité. Ce périphérique pouvait être lu et écrit avec un graveur d'EEPROM standard une fois le brochage connu. Mais revenons à notre wifi-finder. Nous pouvons tracer la localisation de la broche VDD (la source d'énergie) et GND, et nous savons qu'il y a un port RS232 sur le peu de broches qu'il reste. Avoir peu de broches est souvent suffisant pour découvrir un "B facile" - un périphérique standard qui est simplement marqué comme quelque chose d'autre. Mais dans notre cas, les gars, c'est pas bon. Il y a trop de dérivés 805x et trop de broches pour qu'on puisse faire une identification positive. Nous avons besoin d'informations supplémentaires. Nous pourrions tenter le Social Engineering, mais il semble que les vendeurs ne soient pas non plus au fait des détails internes du WHFX30 et la boite de conception originale est gardée confidentielle par le vendeur, on manque de chance sur cette voie. C'est à ce moment qu'un de nos membres a eu recours à une cochonnerie dans l'enquête du WHFX30. On appelle ça "Decap", et, en gros, quand un trou est fait sur le haut d'une puce avec un fort acide, vous pouvez voir l'intérieur de la puce. Nous ne vous recommandons pas de le tenter vous-même car c'est évidement dangereux et ça risque bien d'endommager la carte si vous ne faites pas attention ! Mais pour une petite somme de 20 à 65 euros [NDT-1], il y a des compagnies qui peuvent vous décaper vos puces, même si elles sont attachées à un circuit imprimé. Vous pouvez trouver ces compagnies faisant une recherche de termes comme "SEM" (scanning electron microscope),"FIB" (focused ion beam), "Decap", "IC Failure Analysis". Ils seront content de décaper vos puces pour un prix nominal, et rieront et blagueront avec vous si vous leur apportez un ipod ou d'autres trucs de grande valeur. J'ai trouvé qu'il ne riaient pas parce que vous leur apportez une puce propriétaire d'Apple, mais parce qu'ils l'ont déjà fait tellement de fois qu'ils vous dirons simplement ce qu'il y a à l'intérieur. Bande de malades ! Une fois le WHFX30 décapé, nous l'avons examiné au microscope pour trouver le logo du constructeur : Macronix. Les constructeurs mettent toujours un logo et une marque sur les puces, à moins qu'elle n'implique un énorme sécurité ou qu'elle soit vraiment pas chères (comme un de ces jouets clignotants). Une fois avec le nom du fabricant, ça a été facile de chercher dans les produits de Macronix jusqu'à trouver quelque chose correspondant au brochage et aux possibilités du WHFX30 : le MX10E8050A. Vous pouvez télécharger la fiche technique pour ce périphérique chez Keil, qui a fait une chouette suite de compilateur/débogueur appelée microvision (µVision) que vous utiliserez probablement plus tard. La fiche technique du MX108050A est disponible en [9]. Le MX10E8050A est un clone bas niveau du 8051 qui offre peu de ports GPIO, une UART, 2K de RAM internet, et une énorme EEPROM de 64K (divisée en 4 blocs de 16K) pour stocker le code. Rien que cette information nous a aidé à déchiffrer à quoi l'offset amusant 0x4000 des mises à jours du firmware pouvait bien servir : Vous ne pouvez écraser l'EEPROM que par blocs de 16K, et ne pouvez (devez ?) pas écraser un blog dans lequel vous êtes en train d'exécuter du code. Donc, pour avoir une "Mode de Mise à jour du Firmware", les concepteurs ont du mettre ces procédures avec le vecteur de jmp et les procédures de gestion des interruptions dans le premier bloc de l'EEPROM, entre 0x0000 et 0x3FFF. Ensuite viennent les procédures de recherches des hotspot entre 0x4000 et 0x7FFF, et les deux blocs suivants sont inutilisés. NOTE : en fait, il y a une mémoire bloc-note pour écrire le nouveau firmware avant de le flasher en 0x4000, mais ne nous en occupons pas. --[ 5.0 - Accéder au chargeur d'ISP À ce stade, les choses se dénouent rapidement. Nous avons atteint nos buts intermédiaires de recherche et d'identification de notre cible, et un petit parcours de la fiche technique du MX10 nous a montré qu'il y a un bootloader plus profond câblé dans la ROM de chaque périphérique. C'est souvent le cas dans les clones du 8051, et de grands sourires se sont formés sur nos visages quand nous avons appris à lui donner vie. Maintenant, nous sommes proches de notre but principal, et devrions avoir bientôt la possibilité de copier et écraser les 64K d'EEPROM avec une petite aide du chargeur d'ISP. Mais nous avons besoin d'une manière de communiquer avec le périphérique, ainsi qu'une manière d'exécuter une séquence particulière de démarrage, nécessaire pour activer ce chargeur de ROM du fabricant. Commençons par la séquence d'allumage. La fiche technique nous dit que si nous avons la broche !PSEN basse, les broches ALE et !EN hautes pendant qu'on relâche reset, nous entrerons dans le chargeur d'ISP. EA est tenu haut par la carte et ALE sera par défaut haut quand !PSEN sera forcé à être en bas, nous n'avons donc qu'à mettre !PSEN bas. Nous avons commencé par l'agresser avec une aiguille connectée à la terre, ce qui marche mais risque d'endommager les circuits d'E/S de la broche en question. En traçant un peu le PCB, nous avons vu que la broche J1 du connecteur 10-pin est utilisée pour mettre en bas !PSEN pendant un bref délai pendant l'allumage. C'est donc simple ! Nous avons juste mis J1 à la terre en le connectant à J4 et avons allumé le périphérique. Boom ! Nous avons touché le chargeur ! Quand le chargeur est actif, le port RS232 su WHFX30 est utilisé pour transmettre des commandes et les données de l'EEPROM. Cependant, c'est un signal logique 3.0v, 0v au lieu des signaux -12v, 12v utilisé par le port RS232 de vos PC. NE LE CONNECTEZ PAS à votre PC sans une interface adaptée ou vous allez souffler le WHFX30. Puisque le WHFX30 nécessite un niveau logique à 3v, vous pouvez utiliser la version 3v de la puce populaire MAX232, la MAX3232. Allez voir la fiche technique chez Maxim [A]. Vous allez avoir besoin d'un circuit 3232, 5 condensateurs 1uf et soit un câble RS232 coupé ou un connecteur RS232. Je vais décrire le circuit ici, avec un schéma ASCII, mais ça laisse toujours à désirer. Dans la description du circuit, quelques noms communs sont utilisés et sont expliqués ici. VCC et VDD, c'est pour la source d'énergie du périphérique, ici 3.0v ou 3.3v. GND, c'est pour la terre. RxD est l'entrée et TxD est la sortie. Le PC et le wifi finder ont chacun des lignes RxD et TxD, ce circuit imprimé est donc une interface pour connecter le TxD du finder au Rxd du PC et vice versa. Ça devrait vous aider à ne pas vous perdre en câblant la puce. Étapes de câblage : A) Connectez votre source 3v sur la broche 16. NOTE : Connectez un condensateur (C5) de VCC vers GND pour filtrer le bruit. B) Connectez le GND de la source d'énergie à la broche 15 NOTE : Connectez ce GND vers le GND du WHFX30 sur J4 du connecteur 10-pin. C) Connectez un "Pump Capacitor" C1 de la broche 1 vers la 3 D) Connectez un "Pump Capacitor" C2 de la broche 4 vers la 5 E) Connectez un "Reservoir Capacitor" C3 de la broche 2 vers GND F) connectez un "Reservoir Capacitor" C4 de la broche 6 vers GND NOTE : Le condensateur C4 a une polarité négative, la partie + est donc connectée à GND G) le RxD RS232 (broche 2 sur un RS232 9 broches) sur la broche 14 H) le TxD RS232 (broche 3 sur un RS232 9 broches) sur la broche 13 I) le RxD WHFXS30 (broche J7 du connecteur 10-pin) sur la broche 12 J) le TxD WHFXS30 (broche J9 du connecteur 10-pin) sur la broche 11 NDT : Pump Capacitor est un condensateur utilisé pour monter la tension, Reservoir capacitor est un condensateur utilisé pour baisser la tension... Il s'agit dans les deux cas du même composant (un condensateur), mais utilisé à des fins différentes. * http://en.wikipedia.org/wiki/Capacitor * http://en.wikipedia.org/wiki/Reservoir_capacitor MAX3232 Interface ___ ___ +-----)|--- C1+ -|1 U 16|- Vcc ---|(---GND | GND--)|-- V+ -|2 15|- GND --------GND +---------- C1- -|3 14|- T1out ---> RS232 RxD (RS232 p2) +---)|---- C2+ -|4 13|- R1in <--- RS232 TxD (RS232 p3) +--------- C2- -|5 12|- R1out ---> WHFX30 RxD (Header J7) GND--|(-- V- -|6 11|- T1in <--- WHFX30 TxD (Header J9) T2out -|7 10|- T2in R2in -|8 9|- R2out |_______| Comme alternative, vous pouvez aussi acheter un connecteur USB-RS232 pas cher et le mettre entre les broches 3v Txd et Rxd, vous évitant des problèmes en construisant le circuit MAX3232. --[ 6.0 - Possibilités du chargeur d'ISP Ok, vous avez construit et testé votre carte d'interface, et l'avez connecté au wifi finder. Vous avez fait un pont entre J1 et J4 pour activer le bootloader, et vous avez allumé le wifi finder, en ayant un hyperterminal qui tourne sur votre PC. Et maintenant ? Tout d'abord, le périphérique ne va rien vous envoyer, ou alors des caractères qui servent à rien. Il attend un "U" majuscule pour détecter et configurer le débit. Après avoir envoyé quelques "U" au périphérique, il va commencer à nous retourner des caractères. Vous pouvez alors parler au chargeur d'ISP. C'est à ce moment qu'on a noté une divergence avec la fiche technique. Peut-être que notre périphérique n'est pas exactement un MX10E8050A, ou peut-être qu'ils se sont merdés. La fiche technique dit qu'on peut envoyer soit du ASCII, soit du binaire. Nous avons trouvé qu'il ne répondait qu'au binaire (et donc, un hyperterminal est assez limité). Mais les commandes listées dans la fiche techniques sont les bonnes, vous n'avez qu'à les envoyer en format binaire, et pas en ASCII. Allez chercher un programme de communication sur le site openschemes donné à la fin de l'article. Les lignes que vous enverrez sont basées sur le format Intel Hex Record que vous avez du voir dans ces fichiers .HEX de votre compilateur. Mais ce périphérique utilise un ensemble étendu pour inclure des commandes. Le format est par contre le même. Les détails sur le format HEX sont disponibles dans les références [B] plus loin. Format générique d'une ligne hex : : nn aa aa rr dd ... dd cc Nombre Donnée Description ------ ------ ------------ 1) 0x3A (caractère ":") Début de la ligne 2) 0xnn Le nombres d'octets de données de la commande 3-4) 0xaa, 0xaa Adresse de l'endroit à accéder, ou sinon 00,00 5) 0xrr Type de ligne (ou type de commande) 6-n) 0xdd..... Paquet de données, de longueur donnée en #2 n+1) 0xcc complément du checksum en base 2. Somme (sauf les :), modulo FF, invert-1 Donc, à la réception d'une commande complète, le périphérique va commencer par répondre "." pour indiquer que le checksum est bon, ou un "X" sinon. La seule autre réponse serait un "R" si vous tentez d'écrire des données mais que ça n'a pas marché. Nous n'en avons jamais reçu à part quand nous avons tenté d'écrire avant que l'EEPROM soit effacée. Quelques chouettes commandes sont offertes dans la fiche technique, et nous nous en sommes sortis avec quelques autres. Nous allons les montrer comme des chaines hex, parce que la version ASCII ne ressemble à rien ! La séquence suivante pourrait être un ensemble typique de commande. --------------------------------------------------------------------------- 1) Copie de l'EEPROM. 0x3A, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xF9 Description: Lire l'EEPROM (0x04) depuis 0x0000 jusqu'en 0xFFFF, checksum 0xF9. Cette beauté copie le contenu complet de la mémoire du code du WHFX30 vers le port série. C'est la première commande que vous voudrez utiliser, pour avoir une copie propre des 64K d'EEPROM au cas où vous vous merdiez plus tard. --------------------------------------------------------------------------- 2) Écrasement complet de la puce 0x3A, 0x01, 0x00, 0x00, 0x03, 0x07, 0xF5 Description: supprime tous les blocks d'EEPROM (0x03) + octets de statu et vecteur de boot, checksum : 0xF5. Vous pourriez aussi faire un écrasement par block, mais cette commande va tout supprimer dans la puce, c'est notre méthode préférée. Veuillez noter que vous aurez besoin de ré-écrire le vecteur de boot après la suppression, sinon, la puce va rester bloquée dans le chargeur d'ISP. --------------------------------------------------------------------------- 3) Autoriser l'écriture sur le périphérique 0x3A, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0xFF, 0xFF, 0x01, 0xF8 Description: Blank check * (0x01) du périphérique de 0x0000 à 0xFFFF NDT : blank check, chèque blanc (chèque signé mais dont le montant est laissé vide pour qu'on puisse y mettre ce qu'on veut). C'est un peut l'idée ici, permettre l'écriture, sans savoir à l'avance ce qu'on veut y mettre). Vous pouvez réussir à programmer l'EEPROM avec des données dedans, vous aurez donc besoin de faire un blank check. Ça prend quelques secondes si ça va à son terme, mais si vous ratez, vos écritures raterons chaque fois que la puce trouvera des données. Cool ! --------------------------------------------------------------------------- 4) Données du programme 0x3A, 0x10, 0x00, 0xhh, 0xll, 0x00, 16 octets de donnée, Checksum Description : Programme l'EEPROM (0x00) à l'endroit 0xhhll avec les octets suivants. Le premier octet est la taille de la donnée. Nous utilisons ici 0x10 pour 16 octets, mais ça peut changer. Veuillez noter que vous devrez calculer le checksum à la volée, et que la somme du checksum n'inclus PAS le premier octet 0x3A. Si vous ne savez pas comment faire un checksum intel, voici comment ça marche : a) sommez les octets modulo 256 (ou sommez dans une variable de la taille d'un octets et vous ennuyez pas). b) Faites en le complément à 2. Si vous ne voulez pas entrer dans les détails, soustrayez votre somme à 256 (0x100) ou laissez 0x00 si votre somme faisait déjà 0x00. Pour ceux d'entre vous qui ne sont pas familier des compléments à 2, c'est le nombre nécessaire pour, quand on l'additionne, le résultat fasse 0x100. Donc, pour un total de 0x7E, notre checksum serait de 0x82. Puisqu'on fait des checksum sur un octet, un total de 0x17E ou 0x217E ferait de toutes façons 0x82, puisque seuls le dernier octet compte. Si le total fait un multiple de 0x100, alors le checksum fait 0x00. --------------------------------------------------------------------------- 5) Supprime le vecteur de boot et l'octet de statu 0x02, 0x00, 0x00, 0x03, 0x04, 0x00, 0xf7 Description: Supprime (0x03) l'octet BV/Status byte (0x04) après que la programmation soit faite, pour se préparer à restaurer les valeurs par défaut. Après la programmation, le périphérique va avoir son statu et BV [Boot Vector] de mis pour continuer le démarrage dans le chargeur d'ISP. Pour remettre la puce dans un mode normal (démarrer dans l'EEPROM), nous devons nettoyer et réécrire le BV manuellement. Veuillez notez qu'après avoir nettoyé ces octets, il est très important que vous arrivez à réécrire le BV vers sa valeur par défaut, ou vous DÉSACTIVERIEZ vraiment le chargeur d'ISP et vous ne pourriez plus revenir dedans. Si vous avez des problèmes en le réécrivant, faites simplement une suppression complète de la puce pour quitter ce cas dangereux. Mais n'éteignez JAMAIS si vous êtes bloqués dans cette étape 5. --------------------------------------------------------------------------- 6) Écrire le vecteur de boot 0x03, 0x00, 0x00, 0x03, 0x06, 0x01, 0xFC, 0xF7 Description: écrire (0x03) le vecteur de boot (0x01) avec la valeur 0xFC (pour 0xFC00), checksum: 0xF7. Ceci remet la valeur par défaut dans le vecteur de boot à 0xFC00. N'éteignez pas le périphérique entre les étapes 5 et 6, ou le vecteur de boot restera à 0x0000, démarrant toujours l'EEPROM vous empêchant à jamais d'atteindre le chargeur d'ISP. --------------------------------------------------------------------------- Nous admettrons à partir d'ici que vous avez copié entièrement les 64K d'EEPROM qui sont dans le périphérique. Un tout petit 16K correspond aux données qu'on trouve dans les fichiers de mises à jours du vendeur, ce qui nous laisse BEAUCOUP de données inconnues. N'ais pas peur, intrépide hacker - nous allons découper ces zones et fonctions de ce code d'EEPROM pour toi. Les 65K d'EEPROM sont divisés en quatre blocs logiques de 16K chacun. Cette partition est fournie par le constructeur pour permettre à la puce de s'écraser et reprogrammée elle-même de manière limitée. Dans tous les firmware fouillés, le partitionnement suit le schéma suivant : Partition Adresse logique Fonction --------- --------------- -------- 1 0000h-3FFFh Bootloader et procédures de test 2 4000h-7FFFh procédures de recherche d'hotspot 3 8000h-BFFFh Scratchpad 1 - Wifi Data?? pas encore sûr 4 C000h-FFFFh Scratchpad 2 - bloc note des mises à jours Comme c'est le cas avec la plupart des microcontroleurs 8051, l'exécution typique à partir du démarrage ou d'un reset commencent en 0x0000 dans la partition 1. Ici, le micro va d'abord vider la RAM et vérifier la mémoire avant de vérifier l'état des boutons. Si les boutons du mode self-test ou du bootloader sont abaissés, le micro va fonctionner exclusivement dans la partition 1. Dans le "Firmware Update Mode" qui s'y trouve, le micro peut supprimer et ré-écrire les autres blocs. Par exemple, quand une procédure du finder est mise à jours en mode de mise à jours du firmware, le micro commence par supprimer le bloc en C000, et y écrit les données. Si le checksum est bon, le bloc 4000 sera supprimé et la nouvelle procédure y sera écrite. La deuxième partition contient les procédures de recherche d'hotspot, c'est ce qu'on voit s'exécuter quand le périphérique est en train de chercher les hotspots. Si aucun bouton n'est appuyé pendant le démarrage, nous sauterons le bootloader et continuerons dans les procédures de ce bloc. La troisième partition est utilisée comme bloque note, mais sa fonction n'est pas déterminée à 100%. Nous la suspectons d'être utilisée pour écrire les données wifi, mais nos notes sur ce sujet ne sont pas vérifiées. La quatrième partition est utilisée comme bloque note pendant les mises à jours du firmware pour y écrire le nouveau firmware temporairement. Au début du mode de mise à jour du firmware, le bloc C000 est effacé. Quand un nouveau firmware est envoyé au périphérique, il y est d'abord écrit. Une fois la transmission réussie, le checksum est vérifié. S'il est valide, le bloc 4000 est alors supprimées et ces données écrites pour un usage permanent en tant que nouvelles procédures de recherche. Cette mise à jours simplifiée est un peu plus sûre car elle est téléchargée et le checksum vérifié avant que la mise à jour soit faite, ça sera donc le sujet de notre prochaine section. --[ 7.0 - Possibilités du bootloader logiciel Pour ceux qui se défient d'écraser et de chambouler l'EEPROM à bas niveau, on peut aussi communiquer avec le bootloader logiciel, aussi connu comme "Firmware Upgrade Mode". Il ne fonctionne que pour le bloc de 16K à partir de 0x4000 (les procédures de recherche), mais c'est quand même utile dans certains cas. C'est une bonne alternative pour ceux qui ne veulent pas risquer de corrompre la mémoire du périphérique ou le vecteur de boot. Je le considère très sûr, parce que le bootloader lui-même se trouve dans le bloc à 0x0000, séparé des suppressions et écritures qui ont lieu en 0x4000 et au dessus. Donc, vous ne perdrez en aucun cas la possibilité de revenir à l'EEPROM originale. Quand nous allumons le périphérique (sans sauter entre J1 et J4), et en appuyant sur le bouton "Next", le bootloader logiciel démarre comme on en a déjà parlé. Le port série est automatiquement configuré sur 115.2k, 8n1 et le périphérique commente à écrire des caractères. Il tente de parler avec le ZD1211, mais nous pouvons simplement y attacher notre interface RS232 et communiquer avec lui directement. Je n'entrerez pas dans les détails ici, mais nous avons du désassembler le bootloader lui-même pour trouver les commandes et la séquence de communication. Vous pouvez le faire aussi, si vous voulez. Ou, un petit programme est disponible en ligne pour lire et écrire le périphérique en utilisant le firmware upgrade mode. Un petit survol d'une partie désassemblée montre quelques détails que nous avons utilisé dans le développement de notre programme. À l'entrée du firmware upgrade mode, le périphérique envoie 8 octets 0x00 au port série pour montré qu'il est en vie, et ensuite, il envoie 8 octets 0xA6 pour prévenir qu'il va supprimer le bloc 0xC000. Après avoir vidé le bloc note, le périphérique envoie 8 octets 0xA7. Enfin, il envoie 8 octets 0x11, qui sont l'équivalent d'un "prompte de commande". Une bonne commande sera exécutée, et une mauvaise sera ignorée, et nous rendra une autre huitaine de 0x11. Bien que toutes les instructions ne soit pas montrées, vous pouvez voir les opérations de ces sections grâce à nos commentaires. Extrait 1 : Envoie les 0xA6, écrase le bloc 0xC000 et envoie les 0xA7. Note : les 8 transmissions des 0xA6 et 0xA7 ne sont pas montrées, mais vous pouvez vous faire une idée. 053A 7F A6 mov R7, #0xA6 ; Charge 0xA6 053C 12 28 A0 lcall SerialOut0 ; L'envoie au port série 053F 7F A6 mov R7, #0xA6 ; Charge 0xA6 0541 12 28 A0 lcall SerialOut0 ; L'envoie au port série 0544 7F C0 mov R7, #0xC0 ; Charge 0xC0 pour la suppression 0546 12 29 3C lcall Do_IAP_ERASE ; Fait un appel pour supprimer 0xC000 0549 7F A7 mov R7, #0xA7 ; Envoie 8x 0xA7 pour signifier ; la suppression du bloc 054B 12 28 A0 lcall SerialOut0 054E 7F A7 mov R7, #0xA7 0550 12 28 A0 lcall SerialOut0 0553 7F A7 mov R7, #0xA7 0555 12 28 A0 lcall SerialOut0 ... et ainsi de suite ... Extrait 2 : Envoi des derniers octets 0x11 du prompt, et inspection du "password" et des commande. 058F 7F 11 mov R7, #0x11 ; Charge 0x11 0591 12 28 A0 lcall SerialOut0 ; L'envoie sur le port série 0594 7F 11 mov R7, #0x11 ; Charge 0x11 0596 12 28 A0 lcall SerialOut0 ; L'envoie au port série 0599 12 29 A2 lcall SerIn_OneByte ; Récup. un octet 059C BF AA D2 cjne R7, #0xAA, L_571 ; Si != 0xAA, quitte 059F 12 29 A2 lcall SerIn_OneByte ; Récup. un autre octet 05A2 BF 77 CC cjne R7, #0x77, L_571 ; Si != 0x77, quitte 05A5 12 29 A2 lcall SerIn_OneByte ; Récup. un autre octet 05A8 8F 28 mov RAM_28, R7 ; Stocke à l'adresse 28 05AA E5 28 mov A, RAM_28 ; Stocke dans A aussi 05AC 64 A5 xrl A, #0xA5 ; XOR avec 0xA5 05AE 70 2B jnz L_5DB ; Si != 0xA5, continue de "supprimer" 05B0 7F A5 mov R7, #0xA5 ; Sinon, écrit un ack de 0xA5 05B2 12 28 A0 lcall SerialOut0 05B5 7F A5 mov R7, #0xA5 05B7 12 28 A0 lcall SerialOut0 On peut voir que le bootloader attend un "password" de 0xAA, 0x77 pour commencer l'interpréteur de commandes. Ensuite, il attend l'octet 0x45 pour commencer le téléchargement. Une fois qu'il a reçu un 0xA5, il va écrire 8 0xA5 et continuer sa procédure de "réception". Vous noterez que ces noms de fonctions sont les nôtres, et sont bien évidement pas incluses dans le firmware. N'ayez pas peur de mettre vos propres noms et commentaires dans le code si vous décidez de le désassembler vous-même. En plus, vous noterez que pour supprimer le bloc 0xC000, nous devons utiliser les appels ROM internes du périphérique. C'est une caractéristique intéressante fournie par le constructeur pour faciliter la programmation de l'EEPROM. Les détails des appels IAP rom sont listés dans la fiche technique et nous ne vous montrons ici qu'un petit extrait de l'appel Do_IAP_ERASE, juste par souci de clarté. 293C Do_IAP_ERASE: 293C 8F 2F mov RAM_2F, R7 ; Récup. l'adresse où supprimer 293E 75 F8 5A mov SFR_F8, #0x5A ; Écrit le ROM Security code 2941 43 A2 20 orl FIE, #0x20 ; Met ENBOOT pour autoriser IAP ROM 2944 79 01 mov R1, #1 ; Fonction 0x01 (ERASE EEPROM) 2946 8F 83 mov DPH, R7 ; Octet de poids fort dans DPH 2948 75 82 00 mov DPL, #0 ; Octet de poids faible dans DPL 294B 12 FF F0 lcall L_FFF0 ; Exécute l'appel 294E FF mov R7, A ; Stocke le résultat dans R7 294F 53 A2 DF anl FIE, #0xDF ; Libère le flag ENBOOT 2952 53 F8 00 anl SFR_F8, #0 ; Libère le ROM security code 2955 22 ret 2955 ; Fin de la fonction Do_IAP_ERASE C'est intéressant parce qu'il n'y a aucun code en FFF0, mais cette adresse a été remappée vers une fonction internet fournie par le constructeur de la carte. Nous activons ce remappage en écrivant le password et en mettant le bit ENBOOT. Comme il a été mentionné, les détails sont dans la fiche technique, mais c'est la procédure générale pour appeler les fonctions IAP avec la commande désirée dans le registre R1. Vous avez eu assez d'assembleur ? Continuons donc notre description ! Quand on utilise le firmware upgrade mode, les fichiers de 16k doivent passer un checksum interne où la valeur des octets en 0x0E et 0x0F (0x400E, 0x400F) est là pour que la somme 16bits du bloc entier fasse 0x000. C'est un calcul facile et notre programme pour communiquer avec le mode de mise à jour le calculera et le corrigera à la volée s'il y a besoin. Si vous codez le vôtre, gardez ceci à l'esprit : si le fichier entier est téléchargé mais que le checksum ne marche pas, le périphérique affichera BED CS: ???? sur le LCD, où les ?? seront remplacés par le checksum. L'EEPROM ne sera pas mise à jours en cas de checksum raté. Si le checksum est bon, le périphérique affiche "Erasing", "Upgrading" pendant un tout petit moment et vous affiche alors la nouvelle version du firmware avant d'attendre que vous le redémarriez. Veuillez noter que le bloc 0xC000 et peut-être le bloc 0x8000 sont utilisé comme bloc note quand un nouveau fichier BIN de 16K est téléchargé. Donc, si vous avez mis du code à ces endroit quand vous entrez en firmware upgrade mde, sachez que ces blocs seront automatiquement supprimés lors de l'entrée en mode de mise à jours. --[ 8.0 - Insérer votre propre code Nous admettrons que vous avez un compilateur, et la connaissance nécessaire pour écrire du code 8051. La prochaine étape est d'insérer des bouts de codes pour être exécutés. Il y a essentiellement deux manières de le faire : en patchant les procédures de recherche quand on utilise le mode de mise à jour du firmware; ou en patchant le bootloader quand on est en train d'écraser toute la mémoire via le chargeur d'ISP. La première est chouette, mais l'espace est limité aux procédures de recherche, ce qui fait en gros 1400 octets en 0x7A80. Néanmoins, nous allons la montrer ici. Le point d'entrée des procédures de recherches est en 0x4020, on y saute après que les vérifications du bootloader. Ici, nous libérons un peu de mémoire et sautons à la procédure principale en 0x71FE. En y insérant un saut ou un call juste après avoir libéré la RAM interne, on peut détourner l'exécution vers notre code, que nous admettrons se trouver en 0x7A80. Après que notre code se soit exécuté, nous pouvons continuer avec les procédures normales de recherche en sautant en 0x71FE. Ou vous pouvez insérez un appel juste après la libération de la RAM, et faire simplement un ret. Code original du point d'entrée org 0x4020 ;------------------------------------------- Finder_Entry: mov R0, #0x7F ; Charge l'adresse du haut de la RAM clr A ; Libère l'ACC Memclear_Loop: ; seg000_4023 mov @R0, A ; Met un 0 à l'adresse de R0 djnz R0, Memclear_Loop ; Décrémente R0, boucle si on a pas fini mov SP, #0xA1 ; Met le pointeur de pile à 0x41 ljmp Finder_Start ; Continue en 0x71FE Nous insérerions notre saut ou notre appel juste avant le ljmp. Après le ljmp, il y a une zone blanche jusqu'en 0x4070, c'est donc pas un problème d'y insérer quelques instructions. Par exemple : Code modifié du point d'entrée org 0x4020 ;------------------------------------------- Finder_Entry: mov R0, #0x7F ; Charge l'adresse du haut de la RAM clr A ; Libère l'ACC Memclear_Loop: ; seg000_4023 mov @R0, A ; Met un 0 à l'adresse de R0 djnz R0, Memclear_Loop ; Décrémente R0, boucle si on a pas fini mov SP, #0xA1 ; Met le pointeur de pile à 0x41 ljmp MyRoutine ; jump vers notre code org 0x7A80 ;------------------------------------------- MyRoutine: Instruction à compléter ;) ... ... ljmp Finder_Start ; Continue en 0x71FE À ce stade, nous n'avons pas montré qu'il y a beaucoup de données entre ces deux points. C'est mieux de compiler de votre programme, et ensuite le convertir de fichier .hex vers un fichier .bin (en utilisant HEX2BIN.exe - cherchez-le ou téléchargez-le à partir des références [C]). Finalement, insérez votre nouveau code en copiant/collant via un éditeur hexadécimal au bon endroit du fichier .bin original avant de l'uploader vers le périphérique. Pour les plus aventureux, c'est mieux de mettre à jour l'EEPROM entièrement en utilisant le chargeur d'ISP. Ensuite, on peut en gros s'emparer du bloc de 16K complet en 0x8000. Celui--ci n'est pas supprimé par des commandes quand on est en mode de mise à jours du firmware et est donc relativement sûr. Si vous utilisez le bloc d'EEPROM en 0xC000, vous ne pourrez plus entrer en mode de mise à jours du firmware sous peine qu'il l'efface immédiatement et que vous ayez à le reprogrammer pour que votre code retourne dans le périphérique. Au démarrage, le périphérique commence l'exécution en 0xC000; où nous ne pouvons mettre qu'une instruction, le reset jump vector. Vous pouvez toujours patcher cette instruction pour sauter vers votre code, et ensuite continuer avec sa valeur originale en sautant en 0x0100. Il est plus souhaitable de patcher en 0x109, après que le périphérique ait libéré la RAM internet et ait placé le pointeur de pile. Ce code en 0x0100 est presque identique au début des procédures de recherche que nous venons de regarder. Notre stratégie est identique et dans cet exemple, nous allons prendre le contrôle en 0x0109 et sauter vers notre code en 0x8000. Une fois que notre code a terminé, on peut poursuivre en sautant à l'étape suivante de la procédure originale (vérifier les boutons Next/Seek) avec un saut vers 0x26D2. Code original de démarrage. Atteint après un saut du vecteur en 0x0000. org 0x0100 ;------------------------------------------- Power-ON: mov R0, #0x7F ; Charge l'adresse du haut de la RAM clr A ; Libère l'ACC Memclear_Loop0: ; seg000_0103 mov @R0, A ; Met 0 à l'adresse pointée par R0 djnz R0, Memclear_Loop0 ; Décrémente R0, boucle si pas fini mov SP, #0xA1 ; Met le pointeur de pile à 0xA1 ljmp Boot_Check ; Continue en 0x26D2 Code modifié pour le démarrage org 0x0100 ;------------------------------------------- Power-ON: mov R0, #0x7F ; Charge l'adresse du haut de la RAM clr A ; Libère l'ACC Memclear_Loop0: ; seg000_0103 mov @R0, A ; Met 0 à l'adresse pointée par R0 djnz R0, Memclear_Loop0 ; Décrémente R0, boucle si pas fini mov SP, #0xA1 ; Met le pointeur de pile à 0xA1 ljmp MyRoutine ; Continue en 0x8000 (notre code) org 0x8000 ;-------------------------------------------- MyRoutine: Complétez avec vos instructions ... ... ljmp Boot_Check ; Continue en 0x26D2 Cette approche est un peut plus facile à éditer en hexa parce qu'il n'y a que quelques octets à modifier en 0x0109. Ensuite, on peut coller allègrement les 16K de code en 0x8000. Évidement, le meilleur hack n'utilise pas d'édition en hexa, mais re-créera le .ASM complet pour le reste de l'EEPROM. Soit nous, ou un autre groupe publiera ce .ASM - on est encore en pour parler - mais ça prendra du temps car on en est encore à l'étude du désassemblage. --[ 9.0 - Conclusion Nous n'avons fait qu'effleurer la surface dans cet article, pour vous donner les outils et les points d'entrée pour vos propres développements. Des techniques plus avancées, comme insérer deux interfaces RS232 entre les deux cartes, peuvent nous permettre de surveiller toutes les communications pendant les procédures de recherches ou le mode de mise à jours du firmware. Avec cette méthode, on peut facilement voir la séquence de commandes qui passe entre les deux puces. De plus, l'USB snooping est un super outil pour écouter les communications haut-niveau entre le PC et le finder n'importe quand. Ces commendant peuvent aussi être vue dans un désassemblage et une analyse du firmware complet, qui n'ont pas été inclus ici. Utiliser votre imagination et votre créativité, vous mènera à plein d'autres avancées auxquelles nous n'avons même pas pensé ! En conclusion, cet article s'est centré sur le hack matériel, nos idées sur le logiciel et les discussions sur notre outil logiciel personnalisé ont donc été omises. Pour une analyse plus profonde et en détail, ainsi qu'un accès aux outils logiciels décrit dans l'article, allez voir notre page, généreusement hébergée par le projet Openscheme en [D]. Bonne chance, et joyeux hack ! --[ A.0 - Références [1] - IDA Disassembler by DataRescue Corporation http://www.datarescue.com/ [2] - Keil uVision IDE http://www.keil.com/uvision/ [3] - Allnet Allspot ALL0298 http://www.allnet-usa.com/html/shop.php?kat=WiFi+54Mbit [4] - ZyXel AG-225H http://www.zyxel.com (Direct link too long to include) [5] - TrendNet TEW-429UB http://trendnet.com/products/proddetail.asp?prod=155_TEW-429UB [6] - Linksys WUSBF54G http://www.linksys.com (Direct link too long to include) [7] - ZD1211 Linux Driver Development http://zd1211.wiki.sourceforge.net [8] - ZyXEL AG-225H WiFi Finder Reverse Engineering http://www.maushammer.com/systems/wififinder/index.html [9] - Macronix MX108050A Datasheet http://www.keil.com/dd/docs/datashts/mxic/mx10e8050i.pdf [A] - Maxim MAX3232 Datasheet http://datasheets.maxim-ic.com/en/ds/MAX3222-MAX3241.pdf [B] - Intel Hex Record Format at Keil http://keil.com/support/docs/1584.htm [C] - HEX2BIN Download http://www.tech-tools.com/d_hx2bin.htm [D] - Wifi Finder Reverse Engineering at Openschemes http://wifi.openschemes.com. --[ B.0 - Note du traducteur NDT-1 : entre 40 et 100 dollars, au taux de change du 22 Mai, ça fait entre 25 et 65 euros.