Cette semaine j'ai mis le nez dans le code de UPX 3.03, un packer connu pour être très facile à unpacker (ce qui se comprend puisque ce n'est pas pour ça qu'il a été conçu). Mais comme pour FSG, mon but n'était pas de faire de l'unpacking mais plutôt de comprendre comment le loader (le "stub" dans la terminologie UPX) fonctionne et réalise son unpacking. Ces stubs sont programmés en ASM et les commentaires sont plutôt laconiques, donc ça vaut le coup de sortir son débuggeur préféré pour comprendre à la main :-)
Ca ma permit de découvrir une "feature" assez marrante @Microsoft : quand on compile avec Visual Studio C++ un programme qui fait des opérations flottantes, le programme va vérifier dans le header PE que les sections de la mémoire qui ne doivent pas être "écrivables" (typiquement .text et .rdata) le sont bien. Sinon il déclenche un joli message "R6002: floating point not loaded error" et votre programme plante lamentablement. Le "side-effect" c'est que quand un packer lambda (comme FSG) décompresse son exécutable dans une zone mémoire (donc avec les droits d'écritures) il laisse les droits et donc le programme plante.
UPX résoud le problème en changeant les droits juste avant de jumper sur l'OEP mais ça implique un appel à VirtualProtect() pour pouvoir modifier le PE header (+ 1 pour remettre les anciens droits) et d'écrire dans la mémoire, donc une perte de temps.
Voir le post de kpnc sur le sujet.
Ayant une expérience très restreinte je ne sais pas comment les autres packers s'en sortent. Do you have any idea ?
Sur ce, voici le bouzin.
Ca ma permit de découvrir une "feature" assez marrante @Microsoft : quand on compile avec Visual Studio C++ un programme qui fait des opérations flottantes, le programme va vérifier dans le header PE que les sections de la mémoire qui ne doivent pas être "écrivables" (typiquement .text et .rdata) le sont bien. Sinon il déclenche un joli message "R6002: floating point not loaded error" et votre programme plante lamentablement. Le "side-effect" c'est que quand un packer lambda (comme FSG) décompresse son exécutable dans une zone mémoire (donc avec les droits d'écritures) il laisse les droits et donc le programme plante.
UPX résoud le problème en changeant les droits juste avant de jumper sur l'OEP mais ça implique un appel à VirtualProtect() pour pouvoir modifier le PE header (+ 1 pour remettre les anciens droits) et d'écrire dans la mémoire, donc une perte de temps.
Voir le post de kpnc sur le sujet.
Ayant une expérience très restreinte je ne sais pas comment les autres packers s'en sortent. Do you have any idea ?
Sur ce, voici le bouzin.