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

Contribuez Assembleur Discussion :

Exemple de code auto-modifiant


Sujet :

Contribuez Assembleur

  1. #1
    Membre averti
    Exemple de code auto-modifiant
    Bonjour tlm.

    Ce topique est en lien avec celui-ci:
    http://www.developpez.net/forums/d13...icateur-texte/

    Mais j'ai préféré créé un nouveau topique étant donné que ça traite d'un sujet à part entière.

    Le code est auto-modifiant, c'est à dire qu'il change sa forme puis la remet à son état d'origine, et pourrait le faire indéfiniment si il le faudrait.
    Dans la lancée, j'ai essayé d'implémenter du code-automodifiant également pour la partie des modificateurs à base de "rol reg 8/16", mais sans conviction, car je me doutais car ce serait beaucoup plus difficile à faire et je n'ai pas réussi à le faire comme je l'aurais voulu, c'est à dire beaucoup plus dynamique qu'il ne l'est actuellement.
    Quelqu'un de bon en math pourrait peut être trouver un algo efficace pour cette partie du code ^

    [edit: A regarder au debugger de préférence]
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
     
    format PE console 5.0
    include 'include/windows/win32a.inc'
     
    ;--------------------------------------------------
    section '.text' code readable writeable executable
    ;--------------------------------------------------
     
    entry $
     
    	mov	edi,texte
    	call	strlen
    	mov	[texte_len],ecx
      begin:
    	mov	esi,mod_addr
    	mov	ebp,mod_addr_len
    	xor	dl,dl
    	not	dl
         @@:
    	inc	dl
    	inc	ebp
    	add	esi,4
    	cmp	bl,dl
    	jnz	@b
     
    	mov	esi,[esi]
    	mov	edi,y1
    	xor	ecx,ecx
    	mov	cl,12			;Padding de la zone afin d'éviter
    	mov	al,0x90			;des bytes restant de précédantes
    	repnz	stosb			;instructions.
    	sub	edi,12
    	mov	cl,byte [ebp]
    	repnz	movsb			;Injection d'un des "mod(nbr)".
     
    	mov	esi,texte
    	mov	edi,txtbuf
    	mov	ecx,[texte_len]
        @re:
    	mov	dl,4
         @@:
    	mov	al,[esi]
    	inc	esi
    	ror	eax,8
    	dec	dl
    	jnz	@b
         y1:
    	rd 3				;Zone d'injection des "mod(nbr)".
    	mov	[edi],eax
    	add	edi,4
    	sub	ecx,4
    	jnz	@re
     
    	push	ebx
    	cinvoke	printf,forms,txtbuf
    	cinvoke	puts,crlf
    	invoke	Sleep,1000
    	pop	ebx
         z1:				;Gestion de la fonction:
    	inc	bl			;"modifier db 0,1,2,3,4,5,4,3,2,1,0"
         z2:				;par un "inc/dec bl" automodifiant.
    	cmp	bl,5
    	jnz	z3
    	mov	edi,z1
    	mov	ax,0xCBFE		;"dec bl" opcode.
    	cmp	bl,5
    	jz	@f
    	sub	ah,8			;Modificateur d'opcode en "inc bl".
         @@:
    	stosw				;Storage de l'opcode à "z1".
    	mov	esi,z2
    	mov	ax,0xFB80		;"cmp bl" opcode.
    	stosw				;Storage de l'opcode à "z2".
    	xor	al,al			;"0" opcode suite.
    	cmp	bl,5
    	jz	@f
    	add	al,5			;"5" opcode suite.
         @@:
    	stosb				;Storage à "z2" de la suite de
         z3:				;l'opcode "cmp bl" donc 5 ou 0.
    	dec	[nbrloop]
    	jnz	begin
     
    	invoke	ExitProcess,0
     
     
     strlen:
    	xor	ecx,ecx
    	xor	al,al
         @@:
    	inc	edi
    	inc	ecx
    	cmp	byte [edi],al
    	jnz	@b
    	ret
     
    ;-[Data]------------------------------------------------------------------
     
    txtbuf rb 1024
     
    texte db 'A table is a form of furniture with a flat horizontal upper surface used to support objects of interest, for storage, show, and/or manipulation. The surface must be held stable; for reasons of simplicity, this is usually done by support from below by either a column, a "base", or at least three columnar "stands". In special situations, table surfaces may be supported from a nearby wall, or suspended from above. wikipedia',0
     
    texte_len dd 0
     
    mod_addr dd 0,0,mod1,mod2,mod3,mod4,mod5	;adresse opcode
    mod_addr_len db 0,0,4,4,8,8,12			;longueur opcode
     
    mod1 dd 0x08C0C166				;rol ax,8
    mod2 dd 0x9010C0C1				;rol eax,16
    mod3 dd 0x08C0C166,0x9010C0C1			;mix
    mod4 dd 0x9010C0C1,0x08C0C166			;mix
    mod5 dd 0x08C0C166,0x9010C0C1,0x08C0C166	;mix
     
    nbrloop db 11
    crlf db 13,10,0
     
    forms db '%s',10,0
     
    ;-[Import]----------------------------------------------------------------
     
    data import
     
    library kernel32,'kernel32.dll',\
    	msvcrt,'msvcrt.dll',\
    	user32,'user32.dll',\
    	wsock32,'ws2_32.dll'
     
    include 'include/windows/api/kernel32.inc'
    include 'include/windows/api/user32.inc'
    include	'include/windows/api/wsock32.inc'
     
    import msvcrt,\
    printf,'printf',\
    puts,'puts'
     
    end data

  2. #2
    Membre chevronné
    euh... j'ai pas compris grand chose à tes deux derniers topics

    Ici tu parles de code polymorphe, mais je ne vois pas bien ce qui se polymorphise là dedans

  3. #3
    Membre averti
    Regarde le au debugger.
    Sinon c'est sur qu'à lire comme ça c'est pas évident.

    Il y a la partie des "rol reg 8/16" qui sont injecté directement à "y1".
    Et il y a le "inc bl", qui se change en "dec bl", pour la gestion de la fonction 0,1,2,3,4,5,4,3,2,1,0.

    Je vais rajouter des commentaires dans le code.

    edit:
    Voilà j'ai rajouté des commentaires.
    Mais il faut le regarder au debugger quand même de préférence.
    (à moins de s'appeler Néo et de voir la matrice directement) ^

    edit2:
    J'ai rajouté un "push/pop ebx" entre les appels de fonctions externes (printf,puts et sleep), juste au cas où il y aurait un problème sur d'autres OS. Mais sous WIndows XP, pas de problème donc je n'ai pas eu à préserver la valeur de "bl" des appels de fonctions externes.
    Et j'ai du passer le "cinvoke" de "Sleep" en "invoke" car apparemment la fonction remet déjà la pile en place d'elle-même.

  4. #4
    Membre chevronné
    ok, mais du code polymorphe, c'est pas plutôt du code différent
    pour un résultat identique ?

    Dans ton exemple, c'est plutôt de la modification du code par le code

    quand j'étais jeune ( à l'époque ma plus grosse machine était un 386 à 16MHz )
    J'avais réalisé une démo avec une loupe en temps réel sur un graphisme
    en 320x200 VGA.

    pour faire cette loupe, je calculais les coordonnées des nouveaux points à l'aide d'une table de Sinus/cosinus et le programme écrivait directement le code
    genre :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
     
    mov al,ds: [di+truc]
    mov es: [si+machin],al

    J'affichais une fois l'image depuis une zone mémoire, puis j'affichais ma loupe par dessus.
    le contour de ma loupe remettait les pixels à leurs places, si bien qu'en se déplaçant , l'image avait l'air de revenir à la normale.
    le résultat était très fluide, et le code généré occupait presque 30Ko
    (que je n'avais pas eu à taper avec mes petits doigts )

  5. #5
    Membre averti
    Citation Envoyé par Forthman Voir le message
    ok, mais du code polymorphisme, c'est pas plutôt du code différent
    pour un résultat identique ?
    Ché pas en faite ^
    Mais oué, dans un sens c'est peut être plutôt ça.
    Voilà ce qu'en dit le wiki, mais j'ai pas le courage de tout lire:
    http://fr.wikipedia.org/wiki/Polymor...nformatique%29
    http://fr.wikipedia.org/wiki/Virus_polymorphe

    En faite j'ai déjà vu beaucoup de trucs différents.
    Tout dépend de l'ampleur de la modification.
    Il y en a qui vont jusqu'à modifier toute la page.

    Citation Envoyé par Forthman Voir le message
    ok, mais du code polymorphisme, c'est pas plutôt du code différent
    Dans ton exemple, c'est plutôt de la modification du code par le code
    Yep, code automodifiant. C'est plutôt ça en faite.
    edit:
    J'ai changé le nom du topique et éditer les "polymorphique/phisme" en "auto-modfiant" dans les deux topiques, histoire que ça ne porte pas à confusion.

    Citation Envoyé par Forthman Voir le message

    quand j'étais jeune ( à l'époque ma plus grosse machine était un 386 à 16MHz)
    Le premier pc que j'ai eu dans mes mains étant gosse c'était un proc "quelquechose"DX2.
    486DX2 je crois ^

    Citation Envoyé par Forthman Voir le message

    J'affichais une fois l'image depuis une zone mémoire, puis j'affichais ma loupe par dessus.
    le contour de ma loupe remettait les pixels à leurs places, si bien qu'en se déplaçant , l'image avait l'air de revenir à la normale.
    le résultat était très fluide, et le code généré occupait presque 30Ko
    (que je n'avais pas eu à taper avec mes petits doigts )
    Yep ça le fait. Perso je trouve ça passionnant ce style de coding. Y-a pas de limite en faite.
    Par exemple, on peut faire des codes automodifiants créés par des codes eux-même automod, qui sont gérés par d'autres codes automod, lol !

  6. #6
    Membre averti
    Pas simple quand même de construire un opcode sans faire d'accès mémoire et sans utiliser la pile.

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    	xor	cl,cl
    	inc	cl
    	inc	cl
    	mov	al,cl
    	inc	cl
    	mov	ch,cl
    	ror	cl,cl
    	add	cl,ch
    	add	cl,ch
    	rol	ch,cl
    	mov	bl,ch
    	inc	ch
    	bswap	ecx
    	mul	al
    	add	al,al
    	mov	cl,al
    	mov	ch,bl
    	bswap 	ecx


    Y-a peut être moyen de faire plus court mais perso je n'ai pas réussi.
    Ca m'a donné l'impression d'être dans l'émission "des chiffres et des lettres", quand ils disent "le compte est bon" lol !

    0x08C0C166 en 18 lignes ^

  7. #7
    Membre averti
    J'ai une question.
    Je vais la poster ici plutôt que d'ouvrir un topique juste pour ça étant donné que ça concerne le même thème.
    Au pire si il faut le mettre ailleurs vous le faite ou vous me prévenez et je le ferais.

    Je me demandais quel est le status des codes auto-modifiant.
    J'imagine que si je voudrais publier un code de ce genre pour Linux, il serait refusé ?
    De part la faille de sécurité qu'il représente. Du moins pour le type de code que j'ai donné en exemple qui met en permanence le droit écriture sur la page d'execution.

    Là je code gzip, et faire un code-automod est une évidence.
    Ca me permettrait de virer un gros bloc de code dès le début.
    J'ai réfléchie sur le code pas mal de temps, et je ne vois aucune solution en dehors de l'automod.
    C'est deux proc quasie identique, mais avec de légère variation du genre:
    mov al,byte [esi] / mov ax, word [esi]
    inc esi / add esi,2

    Ce genre de variations..
    Bien sur pour le pointage, j'ai pensé à la solution "mov al,byte [esi+ecx]"
    Mais c'est vraiment la seule ligne pour laquelle il y a une autre solution.

    Ex. pour la 1ère ligne, je ne peux mettre "mov ax,word [esi]" en remplacement de "al", car après il y a un contrôle de "al"...

    Donc voilà j'aimerais avoir votre avis sur ça.
    Est-ce que si je pars dans de l'automod, mon code risquerait d'être refusé pour une publication ?
    Si oui, est-ce que ce serait réfusé également en faisait une modification des droits de la page on-the-fly ?

  8. #8
    Modérateur

    Hello,

    Citation Envoyé par n5Rzn1D9dC Voir le message
    Je me demandais quel est le status des codes auto-modifiant. J'imagine que si je voudrais publier un code de ce genre pour Linux, il serait refusé ? De part la faille de sécurité qu'il représente. Du moins pour le type de code que j'ai donné en exemple qui met en permanence le droit écriture sur la page d'execution.
    Autant que je sache, il n'y a pas de « statut » défini permettant d'indiquer qu'un exécutable est par nature auto-modifiant et qu'il doit donc posséder les droits pour le faire (si c'est bien cela que tu veux dire).

    D'une part parce que, effectivement, ça pose pas mal de problèmes de sécurité mais également parce que, par tradition, cela ne se fait presque jamais sur PC, surtout depuis la prédominance des langages de plus haut niveau. En plus, par définition, ça ne pourrait pas fonctionner en ROM (mais là, pour le coup, ça ne concerne vraiment pas le PC).

    C'est bien dommage parce que j'ai examiné plusieurs programmes de ce type sur mon 8-bit à l'époque et que ça permettait plusieurs optimisations bien pratiques. Par contre, ça risque de pourrir les performances des processeurs modernes qui utilisent des lignes de cache, des pipelines et des exécutions randomisées.

    Il y a aussi que le x86 se présente comme une architecture Harvard. En réalité, ce n'est pas vrai : la séparation n'est concrétisée que par des flags de protection d'accès. Il en reste que sur le plan purement théorique, un code auto-modifiant n'est pas censé être possible dans une architecture Harvard.

    Là je code gzip, et faire un code-automod est une évidence. Ca me permettrait de virer un gros bloc de code dès le début. J'ai réfléchie sur le code pas mal de temps, et je ne vois aucune solution en dehors de l'automod. C'est deux proc quasie identique, mais avec de légère variation du genre:

    mov al,byte [esi] / mov ax, word [esi]
    inc esi / add esi,2

    Ce genre de variations..
    Bien sur pour le pointage, j'ai pensé à la solution "mov al,byte [esi+ecx]"
    Mais c'est vraiment la seule ligne pour laquelle il y a une autre solution.
    En fait, tu te retrouves confronté à du code générique avec de légères variations. L'auto-modif, c'est pratique mais ça t'implique à utiliser des codes qui font tous la même taille (sauf à combler avec des NOP) et, par nature, ce n'est pas thread-safe. Par contre, tu peux faire des sauts rapides vers des sous-procédures. Un « call eax » te permettrait d'utiliser des pointeurs de fonctions à peu de frais. Bon, il y a quand même le coût du CALL et du RET, mais c'est à mettre en balance avec le coût de modification du code lui-même.


    Est-ce que si je pars dans de l'automod, mon code risquerait d'être refusé pour une publication ?
    Probable. Malheureusement, c'est comme les goto et les variables globales. Il y a bien des cas où ils restent le plus efficace au bout du compte, mais le simple fait de les utiliser te discrédite, ce qui t'oblige à faire du code plus académique même si on pourrait faire d'avantageux raccourcis. C'est la vie.

    Si oui, est-ce que ce serait réfusé également en faisait une modification des droits de la page on-the-fly ?
    Pour pouvoir le faire, il te faudrait les droits root et le faire à l'insu du système. Donc ça risque de ne pas plaire à tout le monde non plus.

  9. #9
    Membre averti
    Ok merci pour ces info pertinantes.
    Un registre en pointeur, c'est vrais que ça pourrait être correct niveau perf.
    Je testerais ça, mais sinon au pire tant pis, je laisserais le code tel quel.
    De toute façon ça restera infiniment plus petit qu'un code C.

###raw>template_hook.ano_emploi###