Structured Exception Handling
By LuTiN NoIR
|
I_ Seh : Présentation et Utilité : Tout d'abord qu'est-ce qu'une exception. Et bien on peut représenter
cela comme une erreur dans un programme qui n'est pas prévue et qui en général bloque et quitte
le progrramme par une messagebox de windows, nous prévenant qu'une erreur c'est produit. Voici un premier exemple d'utilisation des exceptions handlers avec l'aide de l'API SetUnhandledExceptionFilter qui est assez évocatrice : elle permet de gérer ces exceptions : .386 .model flat,stdcall option casemap:none include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib .data TitleMsg db "Filter",0 GoodMsg db "Fichier créé",0 ErrorMsg db "Fichier non créé",0 Fichier db "test.dat" ;------------------------------------------------------- .code start: push offset NoProblem call SetUnhandledExceptionFilter invoke CreateFile,ADDR Fichier,\ GENERIC_READ or GENERIC_WRITE ,\ FILE_SHARE_READ or FILE_SHARE_WRITE,\ NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,\ NULL invoke MessageBox, 0, addr GoodMsg, addr TitleMsg, 0 invoke ExitProcess, NULL ;------------------------------------------------------ NoProblem PROC invoke MessageBox, 0, addr ErrorMsg, addr TitleMsg, 0 invoke ExitProcess, NULL NoProblem ENDP end start Sur ce petit exemple, si jamais lors de l'appel à CreateFile il y a une exception
qui se produit alors le programme affichera que le fichier n'est pas créer, sinon grace au seh il passe
à la routine NoProblem. Bien sur ce n'est qu'un exemple, et oui pour qu'il y est une exception lors de l'appel
à cette api ..... .386 .model flat,stdcall option casemap:none assume fs:nothing ; pour utiliser un seh avec masm include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib .data TitleMsg db "Filter",0 GoodMsg db "aucune exception n'a eu lieu",0 ErrorMsg db "une exception a eu lieu",0 Fichier db "test.dat" ;------------------------------------------------------- .code start: push offset NoProblem push FS:[0] mov FS:[0], esp invoke CreateFile,ADDR Fichier,\ GENERIC_READ or GENERIC_WRITE ,\ FILE_SHARE_READ or FILE_SHARE_WRITE,\ NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,\ NULL pop FS:[0] add esp,4h invoke MessageBox, 0, addr GoodMsg, addr TitleMsg, 0 invoke ExitProcess, NULL ;------------------------------------------------------ NoProblem PROC invoke MessageBox, 0, addr ErrorMsg, addr TitleMsg, 0 invoke ExitProcess, NULL NoProblem ENDP end start C'est le même principe que tout à l'heure sauf que là on met
un except handler avec (de même il y a peu de chance pour que l'appel à la fonction createfile créé
une exception): Et il faut également le retiré avec : Voilà c'est on ne peut plus simple. Bien sur ce n'est ici qu'un simple
exemple, ce n'est pas réelement intégré dans un programme. En effet dans les deux cas le programme
fait appel à l'api ExitProcess pour se terminé. Mais les seh peuvent être mieux utilisé
par exemple si une exception à lieu lors de l'éxécution d'une routine du programme alors si
on a utilisé un seh dans le code pour afficher une erreur, on verra un message d'erreur, et là on
est pas obligé de quitter le programme. En effet il est plus judicieux soit de gérer l'exception
qui a eu lieu soit de retourner dans le programme comme si de rien était en ayant pris soin de prevenir
l'utilisateur que la fonction appelée n'a pu être éxécutée. Voilà c'est fini pour la présentation des seh. Je le reconnait volontiers, c'est une présentation assez simpliste, je ne parle même pas de l'utilisation de la pile des exception handler par thread chainées... mais j'espère cependant que ce texte vous aura permis de comprendre l'utilité d'un seh dans un programme. Si vous désirez découvrir plus profondément l'utilisation
des seh dans un programmes ainsi que les exceptions je vous conseil de lire le magnifique document rédigé
par Jeremy Gordon, qui est disponible sur http://win32asm.cjb.net . II_ SEH: de la gestion des exceptions à la lutte anti-cracking : Avant d'attaquer cette partie, Christal vient juste de m'envoyer ce qu'il
a rédigé sur les seh, et par ailleurs c'est très bien foutu. Il explique en pleu plus en profondeur
ce qu'est un seh. Pour ce qui est des techniques anti-crack il analysé l'int 3 de blindwrite. Pour
ma part je suis actuellemnt sur Aspack2.1 qui est protégé par asprotect (je pense qu'il s'agit de
la version 1.0). J'orienterais cette partie vers un exemple de programmation. .386 .model flat,stdcall option casemap:none assume fs:nothing include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib .data TitleMsg db "Filter",0 GoodMsg db "utilisateur enregistré",0 ErrorMsg db "utilisateur non enregistré",0 Fichier db "keyfile.dat" .data? buffer db 512 dup(?) ;------------------------------------------------------- .code start: push offset NoProblem push FS:[0] mov FS:[0], esp invoke _lopen, addr Fichier, OF_READ .if (eax== -1) xor eax, eax mov eax, [eax] .endif pop FS:[0] add esp,4h invoke MessageBox, 0, addr GoodMsg, addr TitleMsg, 0 invoke ExitProcess, NULL ;------------------------------------------------------ NoProblem PROC invoke MessageBox, 0, addr ErrorMsg, addr TitleMsg, 0 invoke ExitProcess, NULL NoProblem ENDP end start Dans ce petit exemple si jamais le fichier keyfile.dat n'est pas présent,
et bien on créé une exception qui ferait afficher le message utilisateur non enregistré à
la du seh précédement installé. Bien sur au coeur d'un programme il faudrait mettre tout ceci
dans une routine et ne pas quitté le prog mais utilisé un ret. .386 .model flat,stdcall option casemap:none assume fs:nothing ; pour utiliser un seh avec masm include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib .data TitleMsg db "Filter",0 GoodMsg db "Softice non détecté",0 ErrorMsg db "Softice détecté",0 .data? buffer db 512 dup(?) ;------------------------------------------------------- .code start: push offset NoProblem1 push FS:[0] mov FS:[0], esp mov ebp,"BCHK" ;on met le mot magique dans ebp mov ax, 04h int 3 ;on crée une erreur ;à ce moment si sice est lancé on ne va rien voir et ;tout va se passer normalement, ;mais on n'atterrira pas dans l'except Handler... invoke MessageBox, 0, addr ErrorMsg, addr TitleMsg, 0 POP FS:[0] ADD ESP,4h ;on enlève l'except handler invoke ExitProcess, NULL ;------------------------------------------------------- NoProblem1 PROC push offset NoProblem2 push FS:[0] mov FS:[0], esp mov ebp,"BCHK" mov ax, 04h int 3 invoke MessageBox, 0, addr ErrorMsg, addr TitleMsg, 0 POP FS:[0] ADD ESP,4h invoke ExitProcess, NULL NoProblem1 ENDP ;------------------------------------------------------- NoProblem2 PROC push offset NoProblem3 push FS:[0] mov FS:[0], esp mov ebp,"BCHK" mov ax, 04h int 3 invoke MessageBox, 0, addr ErrorMsg, addr TitleMsg, 0 POP FS:[0] ADD ESP,4h invoke ExitProcess, NULL NoProblem2 ENDP ;------------------------------------------------------- NoProblem3 PROC push offset NoProblem4 push FS:[0] mov FS:[0], esp mov ebp,"BCHK" mov ax, 04h int 3 invoke MessageBox, 0, addr ErrorMsg, addr TitleMsg, 0 POP FS:[0] ADD ESP,4h invoke ExitProcess, NULL NoProblem3 ENDP ;------------------------------------------------------ NoProblem4 PROC invoke MessageBox, 0, addr TitleMsg, addr GoodMsg, 0 invoke ExitProcess, NULL NoProblem4 ENDP end start Là j'ai tout le temps utilisé le même anti-softice mais
rien n'empèche de changer, il suffit juste de générer ou pas une exception en fonction du
résultat si l'anti-si ne s'en charge pas lui même. |
Voilà, je n'ai fait que survoler le sujet pour vous donner une première approche de la question aussi bien au niveau de l'utilité d'un seh, que de son utilisation dans une protection logiciel. Je ne saurais trop vous conseillé de lire le texte de Jeremy Gordon sur les seh, disponible sur http://win32asm. Sur ce même site il y a également des exemples d'utilisations des seh dans des protections, nettement plus poussé.
En espérant que ce petit texte puisse servir à quelque chose.Amicalement
LuTiN NoIR