ToxicScorpius, Lances un D20.
J’ajoute un bonus de +2 pour ce lancer, la personne en face n’étant pas immunisée contre les morsures et elle ne peut ni parer, ni esquiver.
Ouais c’est assez terrible. J’ai pas creusé dans les détails le fonctionnement du bousin, mais à l’époque je pensais à des techniques pour obfusquer du code genre :
Tu vois facilement les 0x90 qui correspondent à des NOP (on pourrait y compacter d’autres micro-instructions plus grandes évidemment) et le 04eb exprimé en petit boutiste (little endian en anglais) et qui en fait correspond à eb 04 soit un jmp 4 octets plus loin… Soit jusqu’à la tétrachiée de 0x909090 suivants.
J’ai pas testé, c’est juste que je me souviens avoir vu ce genre de code dans un crackme. C’est un coup à complètement faire chier non seulement un algorithme de désassemblage type linear sweep (gdb) mais aussi un peu plus poussé genre recursive traversal (sous IDA par exemple).
Ouais c’est assez terrible. J’ai pas creusé dans les détails le fonctionnement du bousin, mais à l’époque je pensais à des techniques pour obfusquer du code genre :
Le principe est expliqué dans un PDF sur le dépôt GitHub et part du remplacement des comparaisons par une simple suite d’instructions mov. Pour le cas de l’égalité, par exemple entre la valeur du registre rax et du registre rbx, il utilise leur valeur comme une adresse et y place respectivement 0 et 1.
1
2
3
movq$0,(%rax)movq$1,(%rbx)movq(%rax),%rcx; On récupère le résultat
Si la valeur « référencée » par rax est 1, alors c’est que la valeur de rbx est identique (puisqu’il aura écrasé la valeur précédente), sinon c’est qu’ils sont différents. Une fois que l’on a le résultat, on peut employer d’autres stratagèmes pour obtenir le même effet qu’un embranchement.
Par exemple, pour traduire if (x == y) x = 100, il est possible d’employer un tableau de deux pointeurs, l’un pointant vers x, l’autres vers une zone quelconque. Ce qui donne quelque chose comme ceci en C.
1
2
3
4
5
intx=1;inty=1;int*tab={&osef,&x};tab[x==y]=100;
Bon, après, cela reste assez théorique ici et il faut voir comment c’est effectivement mis en oeuvre, mais je trouve cela sacrément ingénieux.
Tu vois facilement les 0x90 qui correspondent à des NOP (on pourrait y compacter d’autres micro-instructions plus grandes évidemment) et le 04eb exprimé en petit boutiste (little endian en anglais) et qui en fait correspond à eb 04 soit un jmp 4 octets plus loin… Soit jusqu’à la tétrachiée de 0x909090 suivants.
C’était pour démontrer que tu pouvais compacter des instructions les unes dans les autres. Mais si tu veux, on va imaginer quelque chose de plus concret : mettre le registre rcx à 0.
Une instruction pour y parvenir serait :
xor rcx, rcx
Ce qui, assemblé en opcodes intel x64, donne 48 31 c9.
Maintenant assemble ce code :
1
2
jmp $+4
mov rax, 0x9090c93148909090
Ici, on voit pas vraiment que le registre rcx sera mis à 0. Le listing avec les opcodes donne ceci :
tu vois bien les 48 31 c9. Tu vois même un eb 02 qui, une fois désassemblé, donne jmp $+4. En gros tu sautes 4 octets plus loin à partir de l’adresse mémoire courante.
Et ton xor rcx, rcx, ne fût-il pas désassemblé, est bel et bien exécuté.
Ma pauvre tante vient de m’envoyer un mail. Elle semble avoir des problèmes. De graves douleurs aux intestins, elle est à l’hôpital. On va lui faire une coloscopie pour vérifier ce que c’est, mais le cancer est à craindre. Elle a un besoin urgent d’argent. Il faut que je lui fasse un prêt par carte bleu rechargeable et que je lui envoie les codes ; c’est urgent.
Ma pauvre tante s’est faite pirater sa boite mail.
Connectez-vous pour pouvoir poster un message.
Connexion
Pas encore membre ?
Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte