Vous avez dit "BPX HMEMCPY" ?!


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 ;)