Gestionnaire SEH avec fs:[0] qui ne marche pas en C++

Résolu
bluehartt Messages postés 4 Date d'inscription mercredi 22 juillet 2009 Statut Membre Dernière intervention 26 juillet 2009 - 22 juil. 2009 à 20:12
bluehartt Messages postés 4 Date d'inscription mercredi 22 juillet 2009 Statut Membre Dernière intervention 26 juillet 2009 - 26 juil. 2009 à 16:02
Bonjour,

J'ai codé en ASM un petit shellcode qui :

1/ patch l'adresse du SEH handler dans la stack
2/ créé une exception div par 0
3/ gère l'exeption et modifie le registre EIP pour sauter après le div
4/ recharge le context pour que l'execution du prog continue après le div tranquillement

Quand je compile le shellocode sous MASM32, il marche très bien (vérifié sous olly).

Parcontre quand je le compile avec VisualStudio 2008 dans une dll en cpp, il bloque sur l'exception. Pourtant le SEH handler est bien patché dans la stack.

/!\ Je ne veux pas utiliser try et catch en cpp !
Je veux juste comprendre pourquoi je n'arrive pas à gérer mon exception quand c'est compilé avec VisualStudio.

Quelqu'un peut m'éclairer s.v.p ? C'est important. Merci d'avance

Voici mon shellcode en hexa :
EB185E64A10000000083C00489306633C066F7F0E80C000000C3E8E3FFFFFF8B4C240CEBEF5E89B1B800000033C0C3


Shellcode en ASM :
jmp short _seh_handler
_code:
   pop esi
   mov eax ,dword ptr  fs:[0]
   add eax, 4
   mov [eax], esi                                     ; patch le SEH handler
   
   xor  ax, ax                                          ; créé une exeption div par 0
   div ax
   
_new_eip:
   call _eip
   jmp _end
 
_seh_handler:
   call _code
 
   mov ecx, [esp+0Ch]                             ; ecx = adresse de la structure CONTEXT
   jmp short _new_eip
_eip:
   pop esi
   mov dword ptr [ecx+0B8h], esi               ; on va donc modifier eip pour sauter par dessus l'exception
   xor eax, eax                                        ; recharge le context
   retn
_end:


Mes options de compilation dans VisualStudio :
/O2 /Os /GL /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_USRDLL" /D "MaLib_EXPORTS" /D "_WINDLL" /D "_MBCS" /FD /EHa /MT /GS- /Zc:wchar_t- /Zc:forScope- /GR- /Fo"Release\" /Fd"Release\vc90.pdb" /W3 /nologo /c /Gd /TP /errorReport:prompt


Et du Linker:
/OUT:"C:\MaLib.dll" /INCREMENTAL:NO /NOLOGO /DLL /MANIFEST:NO /DEF:"exports.def" /SUBSYSTEM:WINDOWS /OPT:REF /OPT:ICF /ENTRY:"DllMain" /DYNAMICBASE:NO /MACHINE:X86 /ERRORREPORTROMPT ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib

5 réponses

bluehartt Messages postés 4 Date d'inscription mercredi 22 juillet 2009 Statut Membre Dernière intervention 26 juillet 2009
26 juil. 2009 à 16:02
Problème résolu ;)
/SAFESEH:NO dans le linker
3
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
23 juil. 2009 à 13:11
Bonjour,

Houlà !
On saute sur _seh_handler
_seh_handler appelle _code
_code met l'adresse de retour comme exception handler (Je suppose).
_code fait une division par zéro, donc c'est le code suivant l'appel à _code dans _seh_handler qui est exécuté.
Ce code met un argument dans ecx et appelle _new_eip, qui appelle _eip.
_eip écrase probablement une adresse de retour avec l'adresse de jmp _end.
Puis elle fait un retn. Sachant l'adresse de retour dans _new_eip a été dépilée... Donc l'appelant de _new_eip c'est... un jmp dans _seh_handler. Mais on était arrivé par là à cause de l'appel de l'exception.

Intérêt du code ?
Pourquoi faire quinze allez et retour pour exécuter ce qui est à _end ? Pourquoi ne pas simplement mettre le code de _end à la place de jmp short _seh_handler ?

Il y a un flag /EH dans les options de compile. Je sais pas si ça peut aider.
0
bluehartt Messages postés 4 Date d'inscription mercredi 22 juillet 2009 Statut Membre Dernière intervention 26 juillet 2009
23 juil. 2009 à 18:25
Je vais t'expliquer pourquoi je fais des jmp short + call + pop esi... C'est tout simplement pour frabriquer un shellcode

C'est un trick pour ne pas avoir les adresses en dur.

Au final j'obtiens un shellcode hexadécimal qui peut marcher dans tout les binaires.

L'intérêt du code ? Simplement pour tester le gestionnaire SEH avec une exception de type division par zéro. Je ne voulais pas faire un gestionnaire de fou pour expliquer mon problème lol.

Et j'ai essayé tout les flags possible /EH :p

Merci quand même pour ta réponse :)
0
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
24 juil. 2009 à 09:37
Ah ok, compris, c'est pour récupérer un eip sur ton code, eip dont tu as besoin pour le mettre comme gestionnaire d'exception.
Maintenant ce que je comprend plus, c'est pourquoi veux-tu remplacer le gestionnaire d'exception...

Mais je vais essayer de voir ça ce week end. Je me suis toujours dit qu'il faudrait que je regarde comment ça marche les exceptions.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
bluehartt Messages postés 4 Date d'inscription mercredi 22 juillet 2009 Statut Membre Dernière intervention 26 juillet 2009
24 juil. 2009 à 20:36
J'ai besoin d'installer mon propre gestionnaire pour détecté si on est sur une virtual machine.
+ d'infos ici : http://www.codeproject.com/KB/system/VmDetect.aspx

Mon shellcode est déja codé.
Je le copie sous olly après l'entry point et il marche très bien sur des binaires compilés avec MASM.
Mais sur des binaires compilés en C++ avec VisualStudio, ça ne marche pas :/
0
Rejoignez-nous