lundi 2 novembre 2009

Injection de code en Delphi

Introduction
Une méthode connue sous le nom de détour (par Microsoft) permet d'injecter un code de quelques bytes en assembleur devant les appels de fonctions.
Il s'agit en gros 5 bytes (1 byte pour le JMP et 4 bytes pour l'adresse) permettant de faire un saut vers un tremplin (un bout de code situé plus loin).
Ce dernier effectuant des opérations complémentaires (le code injecté) avant d'appeler la fonction initialement appelée (le saut de tremplin lui-même).
En agissant de la sorte, il est possible d'intercepter tous les appels (si l'on en connais l'adresse de la fonction).
Il est également possible de monitorer les API windows.

Pour en savoir plus:

Pour en apprendre plus, aller lire l'article "API Hooking with MS Detours" sur CodeProject.
Cet article traite également des méthodes DLL injection.
Faire une recherche google sur "Api Détour".

AsmProfiler
Il y a quelques temps André Mussche a développé en Delphi un profiler nommé AsmProfiler . AsmProfiler est librement disponible sur Google Code.

AsmProfiler utilise méthode spéciale détournant les appels de fonctions pour insérer du code de monitoring avant l'appel réel de la fonction (méthode appelé "Détour"). Il est ainsi possible d'intercepter n'importe quel appel si l'adresse de la fonction est connue.
Il est par exemple possible d'utiliser cette méthode pour monitorer les appels à l'API WriteProcessMemory et par conséquent d'identifier les processus modifiant le code applicatif à la volée (comme les virus informatiques par exemple).

Le procédé de "detouring" du projet AsmProfiler est implémenté dans la unit KOLDetours.pas.

DLL injection
Voici deux autres méthodes/exemples (issues du projet AsmProfiler) démontrant la méthode de  "DLL Injection".

XSL transformation - XML to CSV

Issu d'un article en allemand (dont j'ai perdu la trace), voici une méthode permettant de transformer du contenu XML en CSV par l'intermédiaire d'une stylesheet relativement simple.

Les données

<?xml version="1.0"?>
<daten>
<!-- test.xml Testdatei zum umformen nach csv mit xmltocsv -->
<name id="idausnamen" aber="keine Attribute">
    <name>1. Thomas</name>
    <wert-zwei>1b.</wert-zwei>
</name>
<ergebnis id="1">
    <wert>2.</wert>
    <nachname>Wenzlaff</nachname>
    <testtag>der 3. Tag</testtag>
</ergebnis>
<ergebnis id="2">
    <wert>3.</wert>
    <wert-drei>3b.</wert-drei>
</ergebnis>
<ergebnis id="3" aber="keine Attribute 22">
    <wert>4.</wert>
    <wert-drei>5.</wert-drei>
</ergebnis>
<ergebnis id="4">
    <wert>6.</wert>
</ergebnis>
</daten>

La stylesheet XSL
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="iso-8859-1"/>
<xsl:strip-space elements="*" />
<xsl:template match="/*/child::*">
<xsl:for-each select="child::*">
<xsl:if test="position() != last()">"<xsl:value-of select="normalize-space(.)"/>",</xsl:if>

<xsl:if test="position()  = last()">"<xsl:value-of select="normalize-space(.)"/>"<xsl:text>&#xD;</xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

Le résultat
"1. Thomas","1b."
"2.","Wenzlaff","der 3. Tag"
"3.","3b."
"4.","5."
"6."

Autre stylesheet

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="iso-8859-1"/>
<xsl:strip-space elements="*" />
<xsl:template match="/*/child::*">
<xsl:for-each select="child::*">
<xsl:if test="position() != last()"><xsl:value-of select="normalize-space(.)"/>;</xsl:if>
<xsl:if test="position() = last()"><xsl:value-of select="normalize-space(.)"/>;</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

avec cette fois le resultat:

1. Thomas;1b.;2.;Wenzlaff;der 3. Tag;3.;3b.;4.;5.;6.;

jeudi 29 octobre 2009

Traffic on Google Map

Moi aussi j'y avait pensé... mais peut être un an ou deux trop tard!

Regular expression en Python

Voici deux très bonnes références pour l'utilisation d'expression régulière en Python.
Utiliser des raw string avec les regular expression
Pour facilité l'écriture des regular expressions, il est préférable d'utiliser les raw string de Python.
Les raw strings sont précédées d'un r et informe le compilateur que le caractère  "\" dans la string n'initie pas une séquence d'échappement Python.
# avec raw string
if re.search(r'\tok', item)>0

# sans raw string
if re.search('\\tok', item)>0
Sans raw string, il est nécessaire de doubler le \ (ce qui donne \\) pour que Python interprète la séquence d'échappement \\ (soit \+\) comme un simple \ qu'il envoi alors au module d'expression régulière.
L'utilisation des raw strings dans les régulars expressions permet de s'émanciper d'une situation communément dénommée "The Back Slash Hell".

Plus d'information
Voir le site de documentation  docs.python.org
A voir également: la section string services de docs.python.org abordant les strings sous toutes leurs formes (StringIO, Codes, Regular expression, template, formattage, etc)

Lecture de fichier et streaming d'objets en Python

Voici quelques notes et exemples rudimentaires de lecture de fichier texte.

Lecture séquentielle
>>> def readFile( sFilename ):
    file = open( sFilename )
    while 1:
        line = file.readline()
        if not line:
            break
        print( line )
    file.close()
>>> readFile( 'c:\\dcu\\test.txt' )
***
Plus d'information sur la lecture de fichier dans cet article "Reading Text Files".

fichiers et séquences

Qui n'a pas un jour eu le besoin de charger le contenu d'un fichier dans une liste ou une séquence?
Voici un petit script permettant de charger le contenu d'un fichier dans une séquence en quelques lignes.
>>> filename = 'c:/Source/MySoft/fileset2'
>>> _file = open( filename, 'r' )
>>> fileset2 = _file.readlines()
>>> _file.close()
>>> fileset2 
['acl.pas\n', 'Action.pas\n', 'Address.pas\n', 'Check.pas\n', 'Template.pas\n', 'listStuff.pas\n', 'ruine.pas\n', 'Cassandre.pas\n', 'ptoleme.pas\n', 'Codes.pas\n', 'BCV.pas\n', 'DisplayModule.pas\n', 'DocumentTemplate.pas\n' ]

plus d'info sur la manipulation de fichier sur l'article "Introduction to Python: File I/O".

Pickling
Ou le "streaming d'objets" !
Apparemment, le pickling est une méthode permettant de transformer un object en sa représentation texte compacte afin d'en permettre facilement le transport (par reseau, fichier, etc).
Le module pickle contient la fonction "dumps" permettant de transformer un objet en sa représentation texte.
>>> pickled = pickle.dumps( Mike ) # Mike est un objet de type Student
>>> print( pickled )
Fournira le résultat suivant:
(i__main__
Student
p0
(dp1
S'school'
p2
S'UIUC'
p3
sS'year'
p4
S'Senior'
p5
sS'name'
p6
S'Mike'
p7
sS'gpa'
p8
F0.59999999999999998
sS'major'
p9
S'CS'
p10
sb.

La fonction loads du module pickle permet quant a elle de recréer une instance de la classe.
>>> # La création d'un nouvel objet depuis le pickle
>>> Mike2 = pickle.loads(pickled)

Le streaming
Il est également possible d'écrire l'état d'un objet dans un fichier... voir l'exemple suivant:
>>> f = open( 'c:/pickle.dat', 'w' )
>>> P = pickle.Pickler( f )
>>> P.dump( Mike ) # Mike est un objet de type Student
>>> f.close()

Plus d'info voir l'article "Introduction to Python: File I/O".

mercredi 28 octobre 2009

Embedded File System en Delphi

Les articles "Writing an embedded file system" et "GpStructuredStorage internals" de Primoz Gabrijelcic (créateur de GpTools et GpSynch) explique comment implémenter, à l'aide de Delphi, un système de fichier avec répertoires dans un seul fichier physique.
L'implémentation de  GpStructuredStorage tire encore une fois parti des avantages offerts par l'implémentation d'interface. Le code utilisant GpStructuredStorage est d'une grande lisibilité.

L'utilisation de cette technique permet par exemple:
  1. De maintenir les nombreuses données de configurations d'un logiciel dans un seul fichier physique.
  2. D'organiser des fichiers de données les plus variés au sein d'un seul fichier physique.
  3. Mettre en place une pseudo base de donnée (basée sur un système de fichier).

Télécharger les sources de GpStructuredStorage.

mardi 27 octobre 2009

Data Liberation: Exportez et Importez vos données Google

C'est un peu par hasard que je croise le chemin de l'initiative Data Liberation de Google.
Data Libération fut initié en 2007 par quelques ingénieurs de Google et visait à permettre l'exportation et l'importation de données personnelles depuis et vers les services de Google.
C'est ainsi qu'il est possible d'exporter ses e-mail GMail, ses contacts, ses documents Google Doc, ses articles de Blog, App Engine, etc.
Data Liberation centralise toutes les informations nécessaires à ces processus d'importation et exportation.

Comme résultat de cette initiative, il est maintenant possible de convertir, zipper et exporter toute une série de documents Google Doc.
Pour plus d'information, voir l'article Liberate Your Google Docs with convert, Zip and Download du blog officiel de Google et le blog de Data Liberation.