IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

x86 32-bits / 64-bits Assembleur Discussion :

[OllyDbg] Exe de cryptage désassemblé


Sujet :

x86 32-bits / 64-bits Assembleur

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    182
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 182
    Points : 103
    Points
    103
    Par défaut [OllyDbg] Exe de cryptage désassemblé
    Bonjour,

    J'ai désassemblé un petit exécutable destiné à crypter (de façon simple me semble-t-il...)des fichiers textes à l'aide d'ollydbg (à priori écrit en C).

    Mes (maigres...) notions en assembleur m'ont permis de comprendre la structure générale du code mais je bloque sur la partie principale de celui-ci qui permet de crypter les caractères de ma chaine d'origine.

    Pour info j'ai fait un test en lançant l'exécutable de cryptage sur la chaine "fontaine". La partie de code ci-dessous correspond au cryptage de la lettre "f".

    Au début de cette partie du code le registre EAX contient 00000066 (ascii "f") et le registre edx 00000000. A la sortie de ce bout de code eax contient la valeur crypté de "f" soit 0000002B (ascii "+"). Ce que je ne comprend pas c'est comment le "f" est transformé en "+" (en tout cas en partie...).

    ci-dessous le code avec ce que j'en ai compris en commentaire... si quelqu'un pouvait m'expliquer les parties que je n'ai pas commenté il serait bien aimable, merci d'avance...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    movsx eax,byte ptr ds:[edx] ;premiere lettre de "fontaine" placee dans eax
     
    mov ecx,dword ptr ds:[403158] ;l'adresse 403158 contient 00000000 je suppose donc que cela correspond a l'initialisation à 0 de ecx...
     
    mov edx,dword ptr ss:[ebp-8] ;apres cette instruction edx contient 00000000
     
    and edx,dword ptr ds:[ecx*4+403140];la c'est plutot obscur...
     
    mov ecx,dword ptr ds:[403148] ; le contenu de l'adresse 403148 est place dans ecx (en l'occurence 0040301C)
     
    movsx edx,byte ptr ds:[ecx+edx] ; le contenu de l'adresse ecx+edx est place dans edx d'où edx = 4D
     
    xor eax,edx ; eax xor edx place dans eax soit 2B (ascii "+")
    Je ne comprend pas comment le registre edx passe de 00000000 à 0000004D...

    J'espère etre clair dans mes explication...

    Merci de votre aide

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    182
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 182
    Points : 103
    Points
    103
    Par défaut
    je ne sais toujours pas à quoi peut bien correspondre cette ligne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    and edx,dword ptr ds:[ecx*4+403140]
    Mais dans tous les cas j'ai résolu le problème.
    Il semblerait qu'il y ait au préalable une initialisation de plusieurs constante, le cryptage semble se faire par un xor de ces constante et de chacun des caractere de la chaine a crypter... le 0000004D est une de ces constantes.

    Je pense donc être tout près du but... Je n'ai donc plus besoins de votre aide... jusqu'à la prochaine fois

  3. #3
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 369
    Points : 23 623
    Points
    23 623
    Par défaut
    Bonjour,

    Il y a plusieurs notions mais, en tout état de cause, je pense que le morceau de programme que tu nous présentes est insuffisant pour tirer une conclusion définitive.

    L'avantage du OU exclusif (XOR) est qu'il est réversible. Cette opération inverse dans le premier registre l'état des bits marqués à un dans l'autre. Cela suffit à rendre une chaîne de caractères illisible à l'œil nu si tu choisis bien ta clé, et il suffit de repasser une seconde fois la clé par dessus pour retrouver la chaîne initiale. C'est extrêmement connu − le programmeur débutant qui découvre cette opération y pense immédiatement − mais cela ne résiste pas quinze minutes à une analyse cryptographique.

    Ici, le principe de ton hack est d'utiliser une clé dynamique qui soit fonction de certains paramètres. Après, le reste relève de l'algorithmique. Je ne sais pas a priori s'il s'agit d'une formule connue style CRC ou apparentée, ou bien si c'est un codage unique inventé à la volée par le programmeur. Je commenterai donc ton programme sur la forme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
            movsx           eax,  byte ptr ds:[edx]                 ;premiere lettre de "fontaine" placee dans eax
     
            mov             ecx, dword ptr ds:[403158]              ;l'adresse 403158 contient 00000000 je suppose donc que cela correspond a l'initialisation à 0 de ecx...
            mov             edx, dword ptr ss:[ebp-8]               ;apres cette instruction edx contient 00000000
            and             edx, dword ptr ds:[ecx*4+403140]        ;la c'est plutot obscur.
    • ECX est chargé avec une valeur sur 32 bits se trouvant à l'adresse fixe 403158. Il y a donc neuf chances sur dix qu'il s'agisse d'une variable globale (c'est mal). À en voir ce qui suit, il s'agit vraissemblablement d'un index ;
    • EDX est chargée avec une valeur 32 bits se trouvant dans le segment de pile, 8 octets avant l'endroit pointée par EBP. Typique d'une variable locale, stockée dans le cadre de pile ou d'un paramètre. Le fait que l'on remonte de huit octets me laisse penser qu'il y a deux variables de 32 bits et qu'on utilise la seconde ;
    • On multiplie la valeur de ECX par 4 pour la faire correspondre à des adresses multiples de 32 bits et on y ajoute une adresse fixe. → Indexation d'un tableau global.
    • On fait un AND avec la variable locale chargée juste avant, ce qui veut dire qu'il s'agit d'un masque.


    Ensuite :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
            mov             ecx, dword ptr ds:[403148]              ; le contenu de l'adresse 403148 est place dans ecx (en l'occurence 0040301C)
            movsx           edx,  byte ptr ds:[ecx+edx]             ; le contenu de l'adresse ecx+edx est place dans edx d'où edx = 4D
     
            xor             eax, edx                                ; eax xor edx place dans eax soit 2B (ascii "+")
    On charge dans ECX le contenu d'un pointeur global qui référence la clé de cryptage, et on se sert d'EDX (que l'on vient de calculer) comme offset dans cette chaîne. Le C correspond à tout ça doit donc ressembler à ceci :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    /* Variables globales */
    char * clefs;
    int offset_clef [TAILLE];
    int numero_cle;
     
    /* Fonctions */
    char crypte (char * chaine, int masque)
    {
        char c;
     
        c = *chaine ^ clefs[offset_cle[numero_cle] & masque];
    }

    En bref : plusieurs clés stockées consécutivement dans une même chaîne, elle-même référencée par un pointeur global, un tableau des emplacements des différentes clés dans cette chaîne, toujours global, et le numéro de la clé en cours d'utilisation (servant à indexer le tableau), global là aussi.

    Le paramètre « masque » peut alors avoir de l'utilité pour resteindre le codage à la ou aux premières clés, à condition qu'elles aient une longueur qui soit une puissance de deux.

  4. #4
    Membre actif

    Inscrit en
    Février 2009
    Messages
    200
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 200
    Points : 235
    Points
    235
    Par défaut
    Le code que tu soumets est très partiel et l'utilisation d'un tableau tiers ne simplifie pas la lisibilité...

    Cependant, la méthode utilisée fait appel à des mécanismes relativement connus, clé publique / clé privée et un simple xor d'encodage (après apparemment une génération de clé codée en dur).

    Désolé d'enfoncer les portes ouvertes, mais une des propriétés de cet opérateur (xor donc) est de pouvoir inverser certains bits sources selon une ou plusieurs clés, utilisées comme masques de flags.

    Xor est employé, par exemple, pour échanger sur place deux variables ou créer des tables liées.

    xor ContenuSource clé -> ContenuChiffré
    xor ContenuChiffré clé -> ContenuSource

    Il est possible aussi, d'utiliser des filtres adaptatifs (traitement du signal)dans lesquels on injecte du bruit pour encoder/décoder un flux quelconque (pourquoi pas "fontaine"). C'est en fait la suite des réglages de chaque cellule de filtrage qui constitue la clé (le signal encodé peut donc contenir une suite de clés dynamiques).

    Tu peux aussi utiliser cette méthode avec xor, quelques checksum.. et tu obtiens un encodeur/décodeur à clés dynamiques qui s'auto protège.
    Le plus sûr étant d'avoir une hiérarchie de clés publiques et privées générées à chaque nouvelle transmission et variant tout le long de celle-ci.

    [édition] désolé d'écrire en même temps que la foule

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    182
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 182
    Points : 103
    Points
    103
    Par défaut
    Merci à vous deux c'est beaucoup plus clair maintenant !

    Par contre j'ai encore un petit problème avec l'instruction MOVSX et plus précisément cette ligne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    movsx           edx,  byte ptr ds:[ecx+edx]
    Afin d'essayer de vous fournir tous les éléments voici les 4 premier elements de la cle de cryptage et leurs adresses mémoire :

    adresse cle
    0040301C 4D
    0040301D 0A
    0040301E D3
    0040301F AE

    La chaine a crypter est toujours "fontaine".
    ci-dessous les valeurs des registres pour le cryptage des 3 premières lettres avant et après le MOVSX (c'est le "n" qui me pose problème).

    Pour rappel :
    ECX contient un pointeur référençant la cle de cryptage.
    EDX correspond à l'offset.

    lettre "f":
    avant le MOVSX :
    ECX : 0040301C
    EDX : 00000000 (0 car c'est la premiere lettre de la chaîne)

    après le MOVSX :
    EDX : 0000004D (ce qui correspond bien a la valeur référencé par ECX + EDX soit 0040301C (4D)

    lettre "o" :
    avant le MOVSX :
    ECX : 0040301C
    EDX : 00000001 (1 car c'est la seconde lettre de la chaîne)

    après le MOVSX :
    EDX : 0000000A (ce qui correspond bien à la valeur référencée par ECX + EDX soit 0040301D (0A)

    lettre "n" (ca se corse...) :
    avant le MOVSX :
    ECX : 0040301C
    EDX : 00000002 (2 car c'est la troisième lettre de la chaîne)

    après le MOVSX :
    EDX : FFFFFFD3 (la je suis largué...)

    Comment se fait-il que EDX contienne FFFFFFD3 et non 000000D3 ? (ce qui pour moi parait logique si je me réfère au cryptage du "f" et du "o"...). Pour moi 0040301C + 2 = 0040301E. L'adresse 0040301E contient bien 000000D3 et non pas FFFFFFD3...

    J'ai exactement le même problème avec le "t", après le MOVSX EDX contient FFFFFFAE et non 000000AE...

    Merci

  6. #6
    Membre actif

    Inscrit en
    Février 2009
    Messages
    200
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 200
    Points : 235
    Points
    235
    Par défaut
    movsx est un mov qui copie un byte dans un word ou un dword ou word dans un dword.
    x ou extend et s pour signe. vu qu'il fait une extension avec signe, cela sous-entend que tous les bits sont pris en compte dans leur état courant contrairement à movzx (z pour zéro) qui place des bits à zéro dans les bits manquants pour l'extension.

    Donc, un ASCII étant codé sur un byte, si tu en fais un copie exented avec signe il est normal d'avoir un résultat équivalent à movzx (des zero au delàs de FF/255). Le "problème" viendrait plutôt du xor qui inverse tous les bits à zéro selon l'état de la clé. Si tu faisais tes essais en mode pas à pas en affichant tes contenus de registres au format binaire, plutôt qu'hexadécimal, tu pourrais suivre plus facilement une algèbre qui se lit en binaire, enfin... d'habitude...

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    182
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 182
    Points : 103
    Points
    103
    Par défaut
    Citation Envoyé par Rémi Coquet Voir le message
    Si tu faisais tes essais en mode pas à pas en affichant tes contenus de registres au format binaire, plutôt qu'hexadécimal, tu pourrais suivre plus facilement une algèbre qui se lit en binaire, enfin... d'habitude...
    Je ne savais pas qu'on pouvais afficher le contenu des registres en binaire avec olydbg mais je testerai ça ce week end car c'est vrai que ce serait largement plus pratique car je "m'amusai" à faire les conversions à chaque fois lorsque j'avais un doute... Je ne pense pas avoir mal suivi le contenu des registres dans ce cas précis mais je jetterai un oeil.

  8. #8
    Membre actif

    Inscrit en
    Février 2009
    Messages
    200
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 200
    Points : 235
    Points
    235
    Par défaut
    A mon avis, c'est le meilleur moyen pour comprendre les mécanismes de base de l'assembleur.
    Les API n'aiment pas toutes que tu leur farfouilles les entrailles mais si ton débuggeur est bien fichu cela devrait normalement correctement se passer.

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    182
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 182
    Points : 103
    Points
    103
    Par défaut
    Je n'ai pas trouvé comment afficher le contenu des registres en binaire dans ollydbg, cela dit j'avoue que j'ai regardé ca rapidement car j'ai peu de temps de libre en semaine. Je regarderai mieux ça ce week end, au pire j'utiliserai IDA qui est semble-t-il plus complet.

    Par contre j'ai vérifier en mode pas à pas si j'avais bien suivi le contenu des registres et c'est bien le cas... je ne comprends donc toujours pas d'ou sortent les F dans FFFFFFD3, effectivement cela corespondrait plutot au xor mais lorsque je fais mon pas à pas cette modification ce fait au niveau du movsx...

    Ci-dessous deux screenshots, qui correspondent au passage du pas a pas sur le movsx. Sur le premier screenshot c'est le cas "normal" qui correspond au passage du registre EDX à 0000000A décrit dans mon post précédent. Sur le deuxieme screenshot c'est le cas que je ne comprend pas... le registre passant de 00000002 à FFFFFFD3 sur le movsx (décrit également dans mon post précédent). Je n'ai pas beaucoup eu le temps de me pencher sur le problème cette semaine mais je ne comprend toujours pas d'ou sort cette valeur FFFFFFD3...



  10. #10
    Membre actif

    Inscrit en
    Février 2009
    Messages
    200
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 200
    Points : 235
    Points
    235
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    xor eax eax    histoire de vider eax et montrer le problème
    mov al 7F      eax (al) contient donc un byte (127) UNSIGNED
    movsx edx al   edx contient 7F (127) UNSIGNED
     
    xor eax eax
    mov al 80      eax (al) contient un byte (128) SIGNED et oui...
    movsx edx al   edx contient FFFFFF80...
    Il me semble que tu as ce qu'il faut pour terminer

    PS: Quelle horreur ce debug

  11. #11
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    182
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 182
    Points : 103
    Points
    103
    Par défaut
    Merci Rémi.
    J'ai enfin terminé. Les F venaient effectivement du fait que le nombre était signé. Je vérifie donc si celui-ci est supérieur à 127, si c'est le cas j'ajoute FFFFFF00.

    J'ai réécris le code pour le cryptage en C#. Ca fonctionne parfaitement, il me reste juste à faire la fonction de décryptage, c'est juste une formalité étant donné que j'ai terminé la fonction de cryptage.

    Donc merci à vous deux pour votre aide au combien précieuse

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Décompiler/Désassembler un .msi ou .exe
    Par Erazion dans le forum Framework .NET
    Réponses: 8
    Dernier message: 26/07/2011, 13h34
  2. Cryptage de fichier
    Par :GREG: dans le forum Composants VCL
    Réponses: 6
    Dernier message: 18/12/2008, 09h43
  3. Format d'un exe pour DOS et pour Windows
    Par Alfhiger dans le forum Assembleur
    Réponses: 4
    Dernier message: 12/06/2002, 11h57
  4. Cryptage en C selon la méthode de césat
    Par shenron dans le forum C
    Réponses: 2
    Dernier message: 31/05/2002, 08h22
  5. Quel désassembleur/assembleur pour un exe Windows ?
    Par Anonymous dans le forum x86 32-bits / 64-bits
    Réponses: 6
    Dernier message: 17/04/2002, 10h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo