Pour les Softiciens, vous avez sûrement du déjà
utiliser ce bpx ultra-indispensable dans vos investigations. :) Ce tutz
rassemble en une espèce de "F.A.Q" l'histoire et les caractéristiques
de Hmemcpy, afin d'avoir plus d'informations sur les coulisses de ce breakpoint
magique!
Qu'est ce que c'est ?
--------------------------
Hmemcpy est une fonction API du kernel32
utilisée par Windows (c'est à dire qu'elle se trouve dans
la dll kernel32.dll) pour tout ce qui est
gestion des chaines de caractères dans un programme. Tout d'abord,
quelques définitions :
- API
Acronyme de Application Programming Interface.
Une
API définie la manière dont le programmeur doit utiliser
une fonction particulière. Dans notre cas, ca veut simplement dire
que Hmemcpy (comme les autres fonctions API) a des variables d'entrée
et de sortie.
- Dll
Les dll sont des dynamic link libraries
(bibliothèques de fonctions dynamiques), ce sont des fichiers qui
contiennent une ou plusieurs fonctions et qui sont compilés, reliés
et stockés séparément du processus (software en execution)
qui les utilise (en général, dans le répertoire C:\Windows\System).
Windows utilise énormément cette fonction dès qu'il
s'agit de manipuler ces chaines et de les comparer. Etant donné
que les opérateurs logiques (=,<>,...) ne supportent pas la comparaison
de variables définies par l'utilisateur/le programmeur (à
ce moment-là, vous obtenez une erreur "Type mismatch"), ces variables
sont converties en chaines, et ce sont ces chaines qui sont comparées.
Cette conversion est également possible à l'aide de la fonction
hmemcpy.
Qu'est ce que ca veut dire ?
-----------------------------------
Hmemcpy signifie Huge Memory Copy. Huge
signifie que cette fonction peut manipuler une énorme mémoire
(supérieur à 64K bytes), bien que les programmes standards
atteignent rarement cette capacité. Enfin, ca c'était comme
la place avec les diques durs au début, on n'en avait soi-disant
jamais besoin de tonnes...
La signification complète est donc : "Copie Enorme en Mémoire".
Origine ?
------------
Hmemcpy est une fonction API de Windows qui a été introduite
dans la version 3.1 de Windows (ach! ca remonte à un baille ca ;)
). Par conséquant, cette fonction ne peut être invoquée
que pour la version 3.1 ou bien une version ultérieure de Windows.
Selon Kro$oft, la function hmemcpy est très aimée des
programmeurs experimentés d'API de base (ben voui, nous aussi !!!
Pas vrai les gars ;)) ).
Comment ca marche?
----------------------------
Sous Softice, on pose un bpx hmemcpy. Cela signifie que l'on
demande a Softice d'arrêter l'execution (le 'x' de
bpx) du programme quand celui-ci va appeler la fonction hmemcpy dans le
kernel32.dll pour traiter une ou plusieurs chaine(s) de caractères.
L'exemple qui nous concerne le plus directement est bien sûr
celui où l'on rentre un "Name" et un "Sérial" dans une fenêtre
pour s'enregistrer. Afin de mettre ces deux données (nom + sérial)
en mémoire, le soft va utiliser (pas toujours!) notre cht'ite fonction.
Concrètement, il copie les bits de données d'une mémoire
tampon source (celle où vous entrez les données au clavier)
vers une mémoire tampon de destination (celle où la donnée
va être traitée, généralement un registre...).
Visual basic
----------------
Dans les programmes et crackmes en VB, vous avez du remarquer que les
techniques habituelles de cracking marchent moins bien, voir pas du tout.
Cela vient de la structure même de programmatione du Visual Basic.
Heuresement, hmemcpy nous sort souvent de la cambrouille. Dans le cas
du VB, cette fonction aussi est utilisée pour copier les données
que l'on a saisi, de la mémoire tampon (la RAM) vers l'espace mémoire
de la ou des dll VB (alors que dans le cas d'un soft non VB, on part dans
le kernel32.dll). Voila pourquoi hmemcpy marche si bien avec le VB!
Une petite précision au niveau des dll VB (à partir du
VB4), celles-ci convertissent toujours les chaines de caractères
saisies au format WideChar avant de les traiter. Donc si le bpx
sur hmemcpy ne donne rien, vous pouvez toujours essayer un bpx MultiByteToWideChar.
Hmemcpy
-------------
L'exemple VB ci-dessous illustre la manière de comparer des
variables définies par l'utilisateur en les convertissant d'abord
en chaines, et en comparant ensuite ces chaines à l'aide d'opérateurs
logiques.
************************************************ Début *********************************************
1. Démarrez VB et ouvrez un nouveau projet. La feuiile Form1 est créée par défaut.
2. Entrez le code suivant dans le module global :
Type myType
f1 As String * 2
f2 As Single
End Type
' Entrez
la déclaration suivante en une seule ligne :
Declare
Sub hmemcpy Lib "kernel" (hpvDest As Any, hpvSource As Any, ByVal cbCopy
As Long)
3. Entrez le code suivant dans la section général des déclarations dans la feuille Form1 :
' type2str
convertit un type de variable définie par l'utilisateur en une chaine.
Function
type2str (t As myType) As String
Dim s As String
s = Space$(Len(t))
Call hmemcpy(ByVal s, t, Len(t))
type2str = s
End Function
4. Entrez le code suivant dans la feuille Form1. Cliquez la procédure d'évènement :
Sub Form_Click
()
Dim x As myType
Dim y As myType
x.f1 = "ab"
x.f2 = 2
y = x
If type2str(x) = type2str(y) Then
Print "x = y"
Else
Print "x <> y"
End If
y.f1 = "ba"
If type2str(x) > type2str(y) Then
Print "x > y"
Else
Print "x <= y"
End If
End Sub
5. Appuyez sur F5 pour lancer le programme.
Le program affiche "x = y" et "x <= y" sur la feuille Form1.
********************************************* Fin****************************************************
Quand (pourquoi) l'utiliser ?
-------------------------------------
Hmemcpy est utilisée pour la saisie des chaînes de caractères
au clavier (comme le nom et le numéro de série) afin de permettre
leur manipulation, leur comparaison... Dans certains cas également,
il n'y a pas de bouton "OK" pour valider la chaine saisie. Cela signifie
que le programme srcute chaque entrée de notre clavier via la fonction
hmemcpy.
Enfin, elle nous sert à convertir des variables définies
par l'utilisateur en chaines.
Utilisation de la fonction (poser
le bpx)
---------------------------------------------------
Tout d'abord, vous renseignez le ou les champs de données demandé(s)
par le programme (nom, sérial, société...). Vous rentrez
donc dans Softice par Ctrl+D, et vous posez un bpx hmemcpy dans
la fenêtre de lignes de commandes. Vous quittez la bête (Softice
:) ) par F5, et vous appuyez sur le bouton "OK" (ou équivalent)
de la fenêtre de saisie du logiciel (s'il n'y a pas de bouton "OK"
comme cité dans le cas plus haut, continuez d'entrer des données
au clavier).
Dans le cas où hmemcpy est utilisée par le soft, Softice apparaitra immédiatement. Etant donné que hmemcpy est une fonction du kernel32, nous atterrirons toujours (pour les softs non VB) au beau milieu de la kernel32.dll. Le premier break effectué par Softice correspond à la copie en mémoire de la première chaine (par exemple le Name). Faites F5 pour sortir de Softice et continuer l'execution du programme, et vous aurez Softice qui réapparait tout de suite pour le traitement de la deuxième chaine (par exemple le Serial). Vous avez ainsi un break par chaine de saisie. Ensuite, il nous faudra resortir du listing assembleur du kernel32 (avec les Bozo et compagnie! - un gag de Kro$oft) avec F12 pour revenir dans le programme lui-même (le nom est affiché sur la ligne qui sépare la fenêtre du code asm et de la fenêtre de saisie des commandes) et scruter le traitement du sérial.
Enfin, si vous n'aviez pas enlevé le commentaire devant les kernel32.dll, user32.dll, gdi32.dll lors de l'installation/configuration de Softice,vous n'auriez pas pu avoir de break sur un bpx hmemcpy!
Quant au cas du VB, c'est à peu près la même chose,
seulement on passe par les dll VB. Hmemcpy va lire les chaines de caractères
qui sont dans la mémoire des dll (abus de langage : en fait ce sont
les dll VB qui sont chargées en mémoire et qui font le boulot
à la place de kernel32).
L'aprés 'hmemcpy' (Remplacement
de la fonction hmemcpy)
-------------------------------------------------------------------------------
Avec l'énorme évolution de la technique, les capacités
des mémoires, disques durs et autres ont explosé. Tout est
devenu énorme, et une distinction de 100 Méga commence à
devenir "négligeable". Qui se soucie d'un DVD de 5,4 Go ou de 5,3
Go ? Ou bien d'un processeur de 1,1 GHz et un autre de 1,2 GHz ? Alors
qu'à l'époque des 286, 386, 486 quand on rajoutait 20 Mo
de RAM ou que l'on passait d'un 60 MHz à un 160 MHz par exemple,
c'était le bout du monde!
Cette constatation illustre la "modernisation" de la fonction hmemcpy.
Dans ce tutz, vous avez vu que le "h" de hmemcpy signifie "huge" (énorme).
Et bien, comme tout est énorme de nos jours, la fonction hmemcopy
est appelée a disparaitre et ne sera plus disponible dans les systèmes
de développement 32-bits de Windows.
Cette fonction va être remplacé par CopyMememory. On
note la disparition du "h" car toute mémoire est considérée
comme énorme en mode 32-bits. Pourtant, si vous regardez la documentation
de Win32, vous n'aurez aucun indice comme quoi cette fonction va devenir
obsolète.
Par contre, si vous regardez bien, vous rencontrerez certainement la fonction CopyMemory. Cette fonction possède les même arguments et a la même tête que sa prédécesseur. Et si vous déclarez CopyMemory dans votre programmation en définissant kernel32.dll comme dll, vous aurez une belle erreur vous disant que cette fonction n'existe pas. En fait, vous ne trouverez aucune trace de CopyMemory! Mais si vous regardez attentivement les fichiers include en C de Win32, vous trouverez dans Winbase.h :
#define CopyMemory RtlCopyMemory
#define MoveMemory RtlMoveMemory
#define ZeroMemory RtlZeroMemory
Je vous dis donc à très bien tôt pour une 'bpx copymemory' party sous Softice ;)
Greetz : Tous les membres de la Shmeitcorp, les programmeurs de Softice (vous faites du super boulot les gars!), et hmemcpy ;)