devloop :: blog

Aller au contenu | Aller au menu | Aller à la recherche

samedi 23 Août 2008

Google Street View à Orléans ?

Il y a quelques jours, alors que je marchais dans la rue, j'ai été dépassé par une voiture avec un dispositif étrange placé sur le toit. Une bloc carré sur une espèce de trépied.
J'ai assez rapidement pensé aux voitures Street View qui se chargent de prendre des photos à intégrer dans Google Maps. Bien que le dispositif ne ressemblait pas exactement à certaines photos trouvées sur Internet, je vois difficilement ce que ça pourrait être d'autre...

Dans ma mémoire, cela ressemblait plus à un trépied, avec des pieds en diagonale. La voiture utilisée avait un look bien européen, peut-être même une Renault ou une Citroën, berline, propablement 4 portes, couleur très fonçée mais pas noire. Elle roulait assez doucement sans doute pour éviter de balancer le dispositif.

Après vérification aujourd'hui, il semble que les voitures de Google circulent bien en France D'après des commentaires sur Zorgloob, d'autres personnes auraient croisé ces voitures un peu partout en France, et notamment sur Orléans à la mi-mai et la semaine dernière... comme quoi ce n'était pas une hallucination :p

Dans tous les cas j'ai vérifié sur Google Maps et aucune photo n'est présente pour le moment pour le lieu où j'ai croisé la famuse voiture :p
Ca pourrait aussi être une société concurrente ou un petit malin qui a décidé de reprendre le principe... rien n'est sûr.

mercredi 20 Août 2008

Anywhere.FM Python CLI Player

C'est après pas mal de recherches et de tests de code que je suis finalement parvenu à développer en Python un lecteur de ma musique présente sur le site Anywhere.FM :)

Le dernier bug rencontré était, comme expliqué dans un précédent, le décodage de certaines chaines de caractères qui ne respectaient pas le format UTF-8. Le responsable était finalement le site lui-même ou plutôt les utilisateurs qui envoit des données au serveur à l'aide d'un navigateur utilisant un autre encodage.

Ainsi dans mon cas, le décodage de mon profil échouait car dans les données retournées se trouvait entre autres le nom mal encodé Ted Gärdestad correspondant à l'un des artistes les plus écoutés par une personne dans ma liste d'amis (la fonctione RPC get_complete_profiles du site renvoie beaucoup d'infos superflues :-| )

Pour résoudre ce souci il fallait intervenir sur la méthode readString de la classe Decoder de PyAMF (module amf3).
Comme je ne voulais pas et d'ailleurs ne pouvais pas modifier le code de PyAMF (installé sous forme de egg sur mon système), j'ai plutôt imaginé une technique de Python API Hooking.
En fait il s'agit simplement de la redéfinition puis d'un écrasement d'une méthode d'une classe Python... mais avouez que dit comme ça, ça en jette beaucoup moins :p

La vérification ajoutée à la méthode readString consistait à lever une exception si le passage en unicode échouait et dans ce cas, à remplacer les mauvais caractères par des underscore. Ce qui donnait :
from pyamf.amf3 import Decoder
from string import maketrans

in_string="".join([chr(i) for i in range(126,256)])
out_string="_"*130
trans=maketrans(in_string,out_string)

def my_readString(object, use_references=True):
  def readLength():
      x = object.readUnsignedInteger()

      return (x >> 1, x & 1 == 0)

  length, is_reference = readLength()

  if use_references and is_reference:
      return object.context.getString(length)

  buf = object.stream.read(length)

  try:
    result = unicode(buf, "utf8")
  except UnicodeDecodeError:
    buf=buf.translate(trans)
    result = unicode(buf, "utf8")

  if len(result) != 0 and use_references:
      object.context.addString(result)

  return result

sav_readString=Decoder.readString
Decoder.readString=my_readString

L'opération de récupération et de correction de la liste de lecture Entire Library pouvant prendre un certain temps si la liste de lecture est importante, j'ai préféré diviser le programme en deux : le premier code récupère la liste de lecture et l'enregistre sous forme d'une liste Python dans un fichier ; le second est le lecteur qui charge la liste de lecture et va lire de façon aléatoire et unique un titre de la bibliothèque :)
Au final on gagne largement en charge réseau et en temps d'accès par rapport à l'utilisation du site Internet et on n'a pas à subir les utilisations mémoire et processeur gourmandes du plugin Flash :p

Vous avez donc get_library.py qui donne un résultat de ce style :
Connection on the server...
Connexion successfull!
user_id = 5418
Hooking the PyAMF Decoder
Getting the Entire Library playlist...
Library dumped!
qui génère un fichier library.py utilisé par le lecteur player.py qui joue les flux musicaux et donne un affichage dans ce genre :
Connecting on the server...
Connexion successfull
user_id = 5418
White America - Eminem ( The Eminem Show )
Troisième tour - Rapaces ( 2000 )
Les Poubelles du Coeur - Parabellum ( 1984-2004 )
Question de fun - Les Shériff ( La Saga Des Sheriff (disc 2) )
Alcohol - Dropkick Murphys ( Live On St. Patrick's Day )
Marilyn Moore - Sonic Youth ( Evol )
Come Back, Baby - Ramones ( The Chrysalis Years (disc 1) )
The Watcher - Dr. Dre ( 2001 )
...
La partie lecteur nécessite la présence de mplayer sur le système. Seul regret : on ne peut pas trop jouer sur l'interface de mplayer pour avoir quelque chose de moins verbeux et agréable... une simple barre de défilement de la lecture en cours (à l'instar de wget) m'aurait bien plu... mais c'est une autre histoire :)

lundi 18 Août 2008

Enregistrer les vidéos de M6Replay Béta sous Windows c'est possible

J'étais désespéremment à la recherche d'une spécification qui aurait pû m'en apprendre sur le protocole RTMPE utilisé par la Béta de M6Replay, en particulier sur la couche de cryptage, quand je suis finalement tombé sur un blog parlant d'un logiciel qui avait réussi à casser cette protection.

Ca m'a finalement amené à cette discussion sur le forum d'Adobe, puis au fameux logiciel ainsi qu'à un article sur le sujet sur Slashdot

Après essai de Replay Media Catcher, il s'avère que effectivement ça fonctionne, entre autres sur M6Replay Béta.
Bien sûr, aucune information n'est disponible sur le fonctionnement du logiciel mais il doit utiliser à priori une attaque de type MITM, se faisant passer auprès du plugin Flash comme le serveur de streaming avant de renvoyer le flux réencodé par ses soins vers le véritable serveur. Bref il doit agir comme un proxy.
Le logiciel ne se sert pas de modules Internet Explorer, ni de la librairie pcap. Il n'y a donc pas, à la différence des logiciels concurrents, de sniffing. Le protocole RTMPE n'est donc pas cassé, ce sont juste les développeurs de Replay Media Catcher qui ont trouvé puis implémenté la bonne astuce :)

Face à tout ça, Adobe a rajouté une clarification dans un document sur son Flash Media Server (pdf).

Et moi je n'ai trouvé aucune information intéressante sur le RTMPE... la magie des logiciels propriétaires :(

Télécharger les vidéos de M6Replay sous Windows avec Replay Media Catcher
Ci-dessus, le fameux logiciel en action.

dimanche 17 Août 2008

Lire directement la musique de Anywhere.FM : ça marche (presque)

Suite de ma précédente étude du fonctionnement de Anywhere.FM.

Je me suis lancé aujourd'hui dans la pratique en écrivant quelques lignes de code et les résultats sont pour le moins encourageants :)
Je me suis orienté naturellement vers les modules urllib2 et cookielib de Python que j'avais utilisé pour Wapiti.

Les premières étapes se sont réalisées sans problème (envoies de données par GET ou POST, utilisation d'une boîte à cookies :p )
Pour la seconde étape j'avais le choix entre utiliser les capacitées de PyAMF à effectuer les requêtes mais en devant injecter mes entêtes HTTP ou rester sur l'utilisation du module urllib2 et injecter les données encodées à l'aide de PyAMF.
J'ai finalement opté pour la seconde méthode, même s'il m'a fallu un peu de temps pour comprendre quels arguments passer à quelles fonctions. Pour résumer j'utilise seulement les fonctionnalitées de création d'objet (plus propre) et d'encodeur/décodeur de PyAMF et toute la partie communication est réalisée par urllib2.

J'ai d'abord implémenté les étapes que j'avais observé au complet puis j'ai ensuite commenté certaines étapes dont l'utilité était douteuse.
Au final les réponses aux questions précédentes sont :
  • _unique_request_id_ est aléatoire. On peut même le définir nous même au début. Reprendre la même valeur à chaque nouvelle session ne semble pas poser de problème, même sur des intervalles de temps rapprochés. Je n'ai pas vérifié si on pouvait se passer de l'incrémentation d'une requête à une autre
  • Les fameuses variabes __qca et __qcb définies par le biais du Javascript sur le serveur quantserve semblent totalement superflues. Ne pas les utiliser n'entrave en rien la communication avec Anywhere.FM. De toute évidence elles sont utilisées uniquement à des fins de tracking
  • tracker_id n'a pas d'utilité, malgré qu'il soit explicitement défini (une requête est générée uniquement à cet effet). Il pourrait s'agir d'une fonctionnalitée que les administrateurs n'ont pas encore pû implémenté mais à venir ?!
  • Certains arguments passés à get_songs_for_user_playlists restent un mystère, toutefois on n'a pas besoin d'en savoir plus pour accèder à la librairie complète d'un utilisateur
Le code que vous pourrez trouver ici : PyAnywhereFM.py et sur pastebin.com n'est pas totalement fonctionnel.
En effet si on parvient bien à ouvrir une session sur le site, à effectuer des requêtes AMF et obtenir les résultats, on ne parvientpas pour le moment à décoder les réponses AMF à cause d'erreurs de décodage UTF-8. A l'heure actuelle je ne saurais pas dire si le problème vient de Anywhere.FM, de PyAMF ou encore de Python...

Il est tout de même possible d'obtenir un jeton valide pour accèder à un titre dont on connait par avance le master_id et le song_ressource_id (paramêtres qui sont fixes).
Le code tente de se connecter avec les identifiants présents dans la source (à vous d'y insérer les votres) ou fonctionnera avec l'utilisateur par défaut (démo, id = 89 comme vu la dernière fois) si les identifiants sont invalides. Il va ensuite lire un titre dans ma librairie à l'aide de mplayer.

Vous pouvez utiliser un sniffeur comme Wireshark pour comprendre ce qui se passe en fond lors de l'utilisation du script. Il faut noter toutefois que l'utilisateur demo a une librairie vide, c'est pour cela qu'il est possible de décommenter une ligne fixant le user_id à 46 (correspondant au compte Free Music)

L'étape restante consiste donc à extraire les données des réponses AMF obtenues, ce qui ne devrait pas être trop difficile puisque le master_id et le song_ressource_id sont envoyés comme des chaines de caractères et non comme des entiers.
Tout cela montre qu'il est assez aisé (le code fait 129 lignes une fois les commentaires et les lignes vides retirées) de télécharger de la musique sur Anywhere.FM et malgré qu'il n'y ait pas de système permettant de rechercher un titre en particulier, il serait possible de générer une base de données des titres disponibles en récupérant les profils puis les listes de lecture des utilisateurs du site. Evidemment ça prendrait du temps, mais ce serait toujours plus rapide que de fouiller par le biais de l'interface web du site :p

samedi 16 Août 2008

Ecoutez votre musique aléatoirement pour pas un rond (ou presque) en mode console

L'astuce qui suit nécessite la présence d'un logiciel lisant le fichier qu'on lui passe en argument et quitte une fois arrivé à la fin du titre.

find /repertoire/vers/votre/musique/ -name "*.mp3" -print|sort -R|xargs -0 -d"\n" mplayer
La première commande fouille dans une arborescence les fichiers mp3 présents et génére une liste en affichant le chemon complet vers les fichiers.
La seconde commande va réorganiser cette liste de façon aléatoire :)
La dernière commande extrait chaque nom de fichier de la liste pour le passer en argument du lecteur audio (ici mplayer)

jeudi 7 Août 2008

Dissection de Anywhere.FM

Il y a presque un an maintenant j'avais testé Anywhere.FM, un site permettant d'uploader sa musique en ligne pour pouvoir ensuite la réécouter depuis n'importe quel poste connecté à Internet et disposant du plugin Flash d'Adobe.
C'est très pratique et agréable... quand cela fonctionne. Et malheureusement sous Linux, ça ne fonctionne pas souvent. Premièrement la fonction d'upload ne fonctionne pas sous Linux avec Flash9 (je n'ai pas testé avec la version béta 10), la faute à Adobe qui semble moins pressé quand il s'agit de systèmes libres. Deuxièmement la lecture des titres (et c'est quand même l'utilité principale du site) semble fonctionner uniquement quand ça lui chante... et de toute évidence depuis des mois le site a décidé qu'il ne voulait pas lire les musiques sous Linux. Ainsi l'animation Flash reste bloquée sur Loading... mais ne charge rien du tout.

Bref dans mon raz-le-bol général j'ai décidé d'analyser le fonctionnement du site et de voir s'il est possible de développer un petit quelque chose qui me permettrait de pouvoir lire ma musique en ligne directement sur les serveurs sans avoir à passer par l'interface pompeuse existante :p
A l'heure actuelle il n'y a pas encore de code, seulement mon analyse qui dévoile la grosse partie du fonctionnement du site.

Identification
Si vous rendez sur une des urls du site, vous serez redirigés automatiquement vers http://www.anywhere.fm/player/. Cette page est chargée dynamiquement et en fonction de la page que vous avez demandé en premier, différentes variables seront passées à l'animation Flash chargée dans le navigateur (par exemple pour indiquer qu'il faut aller chercher la librairie de tel utilisateur).
Durant ce premier contact avec le site, un identifiant de session PHP (variable PHPSESSID) vous sera attribué et vous n'en changerez normalement pas même si vous fermez/ouvrez une session sur le site.
Cette variable de session définie comme cookie est spécifique à l'hôte www du domaine anywhere.fm (d'autres hôtes entrent en jeu comme on le verra plus tard).

Tracking
La page chargée fait appel à différents scripts JavaScript dont un qui a sans doute un rôle de tracking (analyse pour étude commerciale etc) mais à l'heure de ces lignes je ne le jurerais pas.
Le script en question se situe à l'adresse http://edge.quantserve.com/quant.js et il déclare une variable nommée dc qui est générée aléatoirement par le serveur.
La fonction principale nommée quantserve() récupère différentes informations sur la configuration de l'internaute et construit une url vers un pixel traqueur qui est ensuite chargée par le client pour envoyer les données au serveur pixel.quantserve.com.

La partie qui nous intéresse dans ce script (mais qui est peut-être optionnelle) est la modification des cookies.
La variable dc qui était définie se retrouve dans les cookies sous le nom __qca.
Une autre variable, générée aléatoirement en JavaScript (code : Math.round(Math.random()*2147483647) ) est aussi ajoutée au cookie et se nomme __qcb.

Contrairement à PHPSESSID qui est propre à www, __qca et __qcb sont propres à l'ensemble du domaine.

Crossdomain
L'animation Flash étant chargée, elle a besoin de vérifier qu'elle a bien la permission de communiquer avec certains serveurs. Pour cela elle va demander pour chacun un fichier crossdomain.xml qui définie les règles d'accès.
Parmis les serveurs on trouve music, upload-XX (XX étant un nombre multiple de 5) et upload-full.

Authentification
L'animation ayant déterminée qu'elle pouvait dialoguer avec musique.anywhere.fm, elle effectue une requête GET sur la page /account/get_current_user?_unique_request_id_=XXXXXXXXXXXXXX.
L'argument _unique_request_id_ a pour valeur un nombre probablement aléatoire mais toujours très grand. Cet identifiant unique de requête est incrémenté à chaque communication avec le serveur music.

Le serveur music donne ses réponses sous le format XML. En l'absence de la saisie de vos identifiants, les données renvoyées sont celle de l'utilisateur par défaut (user_id = 89, login = demo, fullname = Lux)

La page en profite pour définir trois nouvelles variables de cookie :
  • auth_token et auth_session_id ont pour restriction l'hôte music
  • _HotPot_session_id est défini sur tout le domaine anywhere.fm
Ces trois variables sont typiques des variables de session : 32 caractères sous l'alphabet hexadécimal.
Malgré leur nom différents, auth_session_id et _HotPot_session_id ont la même valeur.

L'opération suivante est un POST à l'adresse /account/create_login_tracker?_unique_request_id_=XXXXXXXXXXXXXX.
Les variables vues précédemment et concernant l'hôte music ou tout le domaine sont bien sûr renvoyés à nouveau au serveur.
Les données passées dans le corps de la requêtes sont session_id (correspondant à auth_session_id de tout à l'heure) et user_id (correspondant à celui renvoyé par la requête précédente soit 89 ici).
Cela renvoit une information très courte de la forme : <tracker_id>XXXXXXXXXX</tracker_id>

Introduction à AMF
Débutent alors les communications AMF avec le serveur www. Action Message Format est un format de données créé à l'origine par Macromedia puis conservé par Adobe.
Il est utilisé principalement par Flash pour des communications RPC.
L'avantage par rapport à un formatage XML sont son format binaire (on n'est pas resteint à des caractères imprimables) et son gain de place. Il utilise notemment un système de références qui permet de ne pas avoir à redéfinir des données déjà envoyées (pour le moment je n'ai pas étudié en détails ce sujet).
On pourrait comparer ce format au bencodage de BitTorrent mais en réalité il est bien plus complexe, voire carrément prise de tête (rien que le codage d'entiers sur 29 bits donne un aperçu)
De plus deux versions existent : AMF0 et AMF3. Il peut possible d'intégrer des données AMF3 dans du AMF0 par le biais d'un type particulier (0x11)
Les requêtes HTTP transportant des données AMF ont l'entête Content-Type: application/x-amf

Ce format n'étant pas le sujet de l'article, je n'en dirais pas plus pour le moment.

Connexion
Passons pour l'instant sur les échanges RPC qui ont été faits, et rentrons nos identifiants de connexion sur le site.
Cela génère une requête POST sur /account/login?_unique_request_id_=XXXXXXXXXXXXXX sur le serveur music. L'identifiant de requête a (ne l'oublions pas) été incrémenté à plusieurs reprises et cela ne changera pas.
Les données envoyées sont :
  • dans le header Cookie : __qca, __qcb, auth_token, auth_session_id et _HotPot_session_id
  • dans le body : login et password
auth_session_id et _HotPot_session_id ont toujours la même valeur.
La réponse du serveur nous informe d'une nouvelle valeur pour auth_token (qui définie donc notre session utilisateur sur le serveur music)
Sur le serveur www, aucun changement n'est à prendre en compte, les données du cookies n'ont pas changées.

Les deux requêtes effectuées avant connexion sont répétées sauf que get_current_user renverra notre user_id et create_login_tracker renverra une nouvelle valeur.

RPC et Flex
Les échanges RPC sont effectués uniquement avec le serveur www et à destination de la page
/amfphp/gateway.php?_unique_request_id_=XXXXXXXXXXXXXX
Les requêtes RPC sont toujours groupées par deux et ont le même _unique_request_id_. Anywhere.FM utilise les librairies Flex dans ses échanges.
On trouve ainsi deux types de messages :
  • flex.messaging.messages.CommandMessage : permet de faire un ping du serveur. C'est toujours la première requête du groupe
  • flex.messaging.messages.RemotingMessage : permet d'appeler une fonction RPC sur le serveur. C'est toujours la seconde requête
Ces fonctions Flex se basent toujours sur les mêmes arguments.
Concernant les fonctions RPC, l'argument source sera toujours fixé à BlazingFast.DBQueries. L'argument operation contient le nom de la fonction à appeler sur le serveur et body est un tableau contenant les arguments à y passer.

Fonctions
Le premier argument de chacune des fonctions existante correspont au auth_session_id, permettant ainsi au serveur de vérifier les permissions d'accès aux données.

La première fonction qui nous intéresse est get_complete_profiles. Elle prend deux argument : le premier est (bien entendu) l'identifiant de session et le second est un tableau contenant une liste d'identifiants utilisateur.
Le résultat retourné est un tableau contenant des informations diverses sur les utilisateurs correspondant, notemment les liste de titres dont ils disposent.
Trois données importantes permettent de définir une playlist : playlist_type, playlist_id et playlist_name
Le type d'une playlist aura la valeur 200 s'il s'agit de la collection entière de l'utilisateur et 300 s'il s'agit d'une librairie personnalisée.

La fonction get_songs_for_user_playlists pourrait se définir de cette façon :
get_songs_for_user_playlists(session_id, user_id, bool, [playlist_id], [playlist_type], ['0','0'...])
Le rôle du booléen en troisième argument m'échappe pour le moment ainsi que le tableau de chaines de caractères définie à '0'.
Cette fonction retourne un tableau qui peut être imposant définissant chaque titre d'une liste de lecture. En dehors des données classiques (name, artist, album), on trouve les données master_id et song_ressource_id qui permettent de récupérer une adresse valide pour un titre donné.

C'est la fonction get_song_url qui nous donne le sésame. On pourrait la déclarer de cette façon :
get_song_url(session_id, user_id, master_id, song_ressource_id)
Elle retourne une chaine de caractères correspondant à une url HTTP vers le fichier MP3 :)
Cette url dispose d'une clé d'accès ainsi qu'un temps de validation. Par conséquent il ne doit pas être possible d'utiliser deux fois la même url.

Conlusion
Il reste de nombreux points à éclaircir qui doivent pouvoir être déterminés par expérimentation comme :
  • _unique_request_id_ est-il généré aléatoirement au début ?
  • Les variables définies par quantserve() ont-elle une utilité autre que le tracking ?
  • Quelle utilité a la valeur tracker_id
  • A quoi sert le booléen et le tableau de chaines passé à get_songs_for_user_playlists ?

Netographie
Open Source Flash documentation
PyAMF (les codes sources m'ont bien aidé)
Charles Web Debugging Proxy : Un proxy qui comprend l'AMF :) Malheureusement en shareware :(

Ping Flex
Pour terminer un petit exemple de code utilisant l'API PyAMF qui réalisé un ping en Flex (merci aux développeurs de l'API pour leur aide ;-) ) :
import pyamf
from pyamf.remoting import client
from pyamf.flex import messaging
from pyamf import remoting

gw = client.RemotingService('http://127.0.0.1/',pyamf.AMF0,pyamf.ClientTypes.Flash9)
message = messaging.CommandMessage(body={},
    timestamp=0,
    destination='',
    clientId=None,
    headers={'DSId': u'nil'},
    timeToLive=0,
    messageId='7478D81C-65B4-EA4B-B52E-4689507A7241',
    operation=5,correlationId='',
    messageRefType='flex.messaging.messages.CommandMessage')
gw.addRequest('null', message)
gw.execute()

dimanche 3 Août 2008

J'ai testé le Live-CD de F-Secure

Un petit billet pour vous dire que j'ai testé F-Secure Rescue CD 3.00.
Comme vous le devinez, c'est un live-cd permettant de chercher des virus sur les systèmes installés sur la machine. L'avantage de pouvoir scanner un système off (qui n'est pas démarré) est que l'on peut détecter des malwares qui se rendent invisibles quand le système est en marche (rootkits...)
L'inconvénient est évidemment que l'on s'en remet uniquement à l'analyse par signature (qui comme tout n'est pas parfaite).

J'ai d'abord essayé de le faire fonctionner sur un PC avec clavier USB. Après lancement du kernel Linux utilisé par le CD, on arrive sur un écran qui nous invite à appuyer sur une touche pour continuer. Sans quoi après 15 secondes, le système installé va démarrer.
Malheureusement le kernel utilisé ne doit pas supporter les claviers USB puisque aucune touche ne semblait répondre alors que juste avant j'ai pû aller dans le BIOS avec le même clavier pour rajouter le lecteur CD dans les périphériques de boot :(
J'ai laissé un message à F-Secure par leur site, en espérant que ce soit corrigé.

Sur un autre système (sans clavier USB), le lancement s'est fait sans problème. L'interface est simple et épurée, il n'y a pas besoin d'être un habitué de Linux ou de la ligne de commande pour l'utiliser.
Une tentative de téléchargement de la dernière base antivirale est faite. Chez moi ça n'a pas fonctionné (à la fin su scan ça affichait mai 2008) mais difficile de déterminer pour qu'elles raisons (DHCP ? DNS ?)

Ensuite vient le scan en lui-même. L'antivirus vérifie le MBR ainsi que les différentes partitions. Les drivers NTFS-3G sont utilisés de cette façon l'antivirus peut agir sur le système de fichier de Windows. Je ne jugerais pas de la qualité de l'AV en lui-même, ce n'est pas le but de l'article. Les quelques virus qui étaient intentionnelement présents sur le disque ont été détectés, rien d'autre n'a été trouvé comme quoi le système devait être propre.
L'antivirus renomme les fichiers infectés en y ajoutant l'extension .virus. Avant de lancer le scan, un message nous prévient que le renommage des fichiers systèmes peut poser problème. Peut-être qu'il manque d'informations sur ce point pour les non-informaticiens qui pourraient se retrouver avec un système propre mais inutilisable.

Au final c'est très pratique, efficace et bon à avoir sous la main en cas de pépin même si quelques points mériteraient d'être améliorés.

samedi 2 Août 2008

Convertir des nombres en ligne de commande

Tout bidouilleur qui se respecte a forcément à portée de main (ou de quelques clics de souris) une table ascii et un logiciel pour convertir des chiffres d'une base à une autre (binaire, décimal, hexadécimal, octal).
En ce qui me concerne, pour la table ascii j'ai la même qui traine sur mon bureau depuis environ 8 ans :p Par contre le problème se pose pour la conversion des chiffres. J'ai plutôt tendance à utiliser la calculatrice de KDE3 (KCalc) mais ça m'oblige à passer par le menu KDE, choisir Applications, Utilitaires, Calculatrice... ce n'est pas très rapide surtout que si on ferme la calculatrice on est bon pour répéter le même cheminement la première fois :(

Bref ce serait tellement plus rapide d'avoir un outil de conversion de nombres en ligne de commande :)
Sous Linux on a bien bc qui permet de réaliser des conversions en utilisant les commandes ibase et obase.
> bc
obase=2
ibase=16
DEADC0DE
11011110101011011100000011011110
Ca marche bien seulement là encore on a plein de choses à taper, c'est interactif : on ne peut pas passer les arguments en ligne de commande et utiliser un echo+pipe ça ne me dit trop rien...

Après quelques recherches peu concluantes, j'ai finalement trouvé un petit outil sympathique sur SourceForge nommé Number Converter (numcv).

Pour le compiler on utilisera la commande gcc -o numcv numcv.c -lm.
La commande prend trois arguments. Le premier est la base d'origine du nombre qui tient sur un seul caractère : 'o' pour octal, 'd' pour décimal, 'h' pour hexadécimal et 'b' pour binaire.
Le second argument est le nombre à convertir et enfin le dernier argument est la base de sortie pour la conversion (les même caractères que précédemment).

Ce qui donne par exemple :
> numcv d 31337 x
0x7a69
> numcv x 29a d
666
> numcv o 56 b
101110
On peut en plus spécifier la base 'a' qui nous permet de connaître la valeur d'un caractère ascii :
> numcv a A x
0x41
Le seul inconvénient est que l'on ne peut convertir qu'un nombre/caractère à la fois. Et aussi une fonction usage() avec une option -h ne serait pas du luxe :p

Au final un outil sympathique en ligne de commande et qui s'avère vite indispensable :)

mardi 29 Juillet 2008

M6Replay Béta et Linux

Vous êtes peut-être au courant de l'existence d'une version béta de M6Replay qui permet aux utilisateurs de Linux et Mac de profiter des vidéos du site de M6.

Je m'étais déjà penché il y a quelques temps sur la version initiale (pour le moment toujours la version officielle) histoire de voir si il était possible de bricoler une zapette comme celle pour les émissions en clair de Canal+.
Après avoir pas mal fouillé, et trouvé assez facilement les urls des flux, il s'avérait que le protocole utilisait était du RTSP-over-HTTP (ou du moins quelque chose dans ces eaux là :D ), qu'on pouvait normalement le lire en bidouillant les options de VLC ou en passant un simple mms:// au lieu du protocole dit officiel.
On final on avait bien de l'image et du son mais pas vraiment ce qu'on désirait. J'ai quand même cru discerner durant un dixième de seconde une paire d'yeux au milieu d'un artistique nuage jaune fluo et de taches oranges... à moins que ce soit l'effet du hazard :p
En fait il semblerait qu'un codec propiétaire (DRM-powered) soit utilisé en plus, rendant impossible la lecture sur les systèmes libres :(

Avec la version béta les vidéos sont bien lisibles sous Linux, mais M6 s'est visiblement cresé la tête pour trouver une solution tout aussi imbuvable.
Ca fonctionne donc avec le lecteur Flash (qui rappelons le est propriétaire)... mais pas autre chose.

On a bien un flux XML dans lequel on retrouve des urls du style
mp4:production/live/DIFF_28072008/H264_UN_DINER_PRESQ__UN_DINER_PRESQ__280720080615__LIVE.mp4
et en observant le traffic réseau on sait que le flux vidéo est lu depuis le serveur fcds98.lon.llnw.net (le nom de machine n'est probablement pas fixe) mais à part ça difficile de retrouver un lien direct pour y pointer son lecteur multimédia préféré.

Après recherches le flux vidéo utiliserait le protocole RTMP (Real Time Messaging Protocol), un protocole (bien évidemment) propriétaire développé par Macromédia (avant rachat par Adobe).
Il existe différents outils closed-source pour capturer les vidéos des flux RTMP, la majorité se basant sur le même principe que cette source C++ à savoir utiliser la librairie pcap et surveiller tout ce qui communique avec le port TCP 1935.

Le protocole RTMP a aussi été analysé et est utilisé par le projet Open Source Flash par le biais du serveur Red5.
Comble du bonheur, les versions béta de VLC (>= 0.9.*) supportent le RTMP :)

Petit problème : M6Replay utilise à priori le RTMPE (RTMPE is a version of RTMP which is an 128-bit encrypted protocol), ce qui fait que ces outils se montrent inefficaces.

Bref pour le moment seulement le lecteur Flash peut lire ces vidéos sous Linux. Il reste à trouver les adresses exactes des flux et attendre que le RTMPE soit supporté par un logiciel libre pour pouvoir en profiter pleinement.

samedi 19 Juillet 2008

Un air de ressemblance

C'est complétement par hazard que je suis tombé sur une image où je retrouvais le logo de présent blog. A l'origine j'avais trouvé le smiley seul sur un autre site avant de le réutiliser, mais sur cette nouvelle image il était accompagné...
Après un bon temps passé sur Google et Yahoo!, j'ai finalement retrouvé l'image et l'auteur original. Il s'agissait d'un sympathique wallpaper :)

J'en profite pour faire un petit screenshot de mon environnement actuel (ça faisait longtemps) : KDE4 avec le thème Aya et un Widget qui m'affiche les strips de User-Friendly.
devloop screenshot