Nouveaux concepts : Utilisation du mappage de fichier pour augmenter la taille d'un fichier Nouvelles fonctions API : lstrcpy
|
Dans ce tutoriel, nous allons développer le code du dernier tutoriel pour ajouter une nouvelle section à un fichier PE. Cela illustrera des techniques de codage plus avancées et je vous recommande vivement de lire d'abord mon tutoriel sur les fichiers PE. Ajouter une section est une technique utile à connaître dans les cas où vous souhaitez injecter beaucoup de code dans un fichier où il n'y a pas suffisamment d'espace existant. Si vous souhaitez créer un outil de reconstruction d'importation personnalisé pour contourner un packer particulier, la solution la plus simple est d'avoir les nouvelles tables d'importation dans une nouvelle section. C'est exactement ce que fait ImpREC - il ajoute une nouvelle section appelée MackT après l'auteur. Le plan global est le suivant : 1. Sélectionner un fichier et vérifier s'il s'agit d'un fichier PE valide Notes spécifiques : 1. Le mappage du fichier avec une valeur de taille supérieure à la taille réelle ajoute un remplissage de 00 à la fin de la vue du fichier lorsqu'il est mappé. C'est ainsi que nous créons de l'espace pour notre nouvelle section à la fin du fichier. Lorsque la vue est désappariée, les modifications sont écrites directement sur le fichier sur le disque. Consultez le chapitre sur le correcteur de recherche et de remplacement pour plus de détails. 2. La table des sections contient une liste de headers de section, chacun d'une longueur de 40 octets, un pour chaque section du fichier PE. Après le dernier header de section, la première section commence. Les sections sont alignées en fonction de la valeur d'alignement du fichier (généralement sur des frontières de 200h octets) avec un remplissage de 00 entre elles. Par conséquent, il y aura un remplissage variable entre la fin de la table des sections et le début de la première section. Cet espace doit être suffisamment grand (40 octets ou plus) pour accueillir un nouveau header de section. S'il n'y a pas suffisamment d'espace, nous en informerons l'utilisateur et nous arrêterons. L'espace peut être agrandi s'il est insuffisant, mais cela ajoute une énorme complexité qui dépasse le cadre de ce tutoriel. 3. S'il y a suffisamment d'espace, nous pouvons superposer notre structure IMAGE_SECTION_HEADER sur cette partie de la mémoire pour écrire des données dans les champs corrects. La structure ISH est la suivante : Les champs que nous devons remplir sont Misc.VirtualSize, VirtualAddress, SizeOfRawData, PointerToRawData et Characteristics. Name1 est facultatif et les autres peuvent être laissés NULL. Notez que pour adresser correctement VirtualSize, vous devez le spécifier en tant que membre de Misc. L'alignement de ces sections est essentiel pour un fichier valide. - Name1 a une longueur maximale de 8 octets et accepte des caractères sans zéro terminal. 4. Après avoir écrit notre nouveau header de section, nous devons mettre à jour 2 champs dans le PE header pour garantir que le loader Windows chargera le fichier en tant qu'exécutable valide. Le champ NumberOfSections doit clairement être augmenté de 1 et le champ SizeOfImage doit être augmenté de la taille de notre nouvelle section. Pour fonctionner de manière fiable, cela doit également être aligné sur SectionAlignment.
|
Ouvrez WinAsm et collez les codes (addsection.asm et addsection.rc inclus). Etant donné que vous êtes à présent de grands garçons et grandes filles et acquis de l'expérience, je ne ferai pas une analyse approfondie du code, mais j'ai tout de même commenté le code source, car c'est ce que vous verrez dans les extraits de code des autres et d'internet. Le script de ressource est essentiellement le même que dans le dernier tutoriel : La partie principale de l'application devrait ressembler à cela : La procédure de dialogue est presque identique à celle du dernier tutoriel : La procédure de validation a légèrement changé pour renvoyer un code d'erreur à l'appelant : Et enfin, la procédure AddSection c'est la plus longue : Il serait assez facile de pousser ce code plus loin pour créer un outil d'ajout de section permettant à l'utilisateur de saisir les informations de section requises. Le rapport d'erreurs est très succinct et SEH pourrait être implémenté pour l'améliorer. Enfin, le code pourrait être réduit au strict minimum pour un outil de compression ou de décompression. Il est important de réaliser qu'il existe de nombreuses façons de faire la même chose, qui varieront en termes d'efficacité ou de "bugginess". Par exemple, nous aurions pu définir une structure PEInfo pour contenir toutes les informations requises de notre fichier cible pour une récupération facile. Nous aurions également pu définir une variable de structure IMAGE_SECTION_HEADER et la remplir avec les valeurs calculées au fur et à mesure pour l'écrire dans le fichier en une seule fois. De temps en temps, vous serez confronté à un binaire cible dans lequel il n'y a pas assez d'espace à la fin de la table des sections pour ajouter un nouveau header de section. Dans ce cas, il est possible d'agrandir le binaire et de créer de l'espace entre la fin de la table des sections et le début de la première section pour un nouveau header. Cependant, cela est complexe et implique, entre autres choses, de mettre à jour les positions de toutes les sections existantes dans la table des sections. Il est également possible d'agrandir la dernière section d'un exécutable pour créer de l'espace pour un nouveau code. C'est relativement facile, mais cela est compliqué par le fait que le header de la dernière section n'est pas toujours la dernière entrée dans la table des sections, de sorte que l'ensemble de la table des sections doit être parcouru et examiné pour trouver celle avec la plus grande valeur de PointerToRawData avant que les champs appropriés puissent être modifiés.
|
Copyright (C)- xtx Team (2021)