• STATISTIQUES
  • Il y a eu un total de 0 membres et 30051 visiteurs sur le site dans les dernières 24h pour un total de 30 051 personnes!
    Membres: 2 605
    Discussions: 3 579
    Messages: 32 816
    Tutoriels: 78
    Téléchargements: 38
    Sites dans l'annuaire: 58


  • ANNUAIRE
  • [EN] Listbrain Version 3
    Site proposant 66 challenges présentés dans une liste mélangée.
    Challenges
    [EN] This is legal
    Basic: 10, Realistic: 5, Programming: 1, Bonus: 11, SQL: 2, Encryption: 6, Application: 4, User Contributed: 3
    Challenges
    [EN] Exploit-db
    Une base de données d'exploits triés par genre (GHDB, Remote, Local, Web, DOS, ShellCode) à ...
    Vulnérabilités
    [FR] Developpez.net
    Un forum communautaire qui se veut pour les développeurs en générale. Avec presque 500 000 membr...
    Programmation
    [EN] Bright Shadows
    JavaScript: 13, Exploit: 27, Crypto: 69, CrackIt: 52, Stegano: 67, Flash: 3, Programming: 16, Java-Applet: 10, Logic: 20...
    Challenges
    [FR] Comment ca marche
     Gratuit et accessible à tous, ce site de communauté permet de se dépanner, se faire aider ...
    Webmaster
    [FR] Forum-Webmaster
    Une communauté webmaster pour apporter / recevoir de l'aide en création de site internet. Webmaster...
    Webmaster

  • DONATION
  • Si vous avez trouvé ce site internet utile, nous vous invitons à nous faire un don du montant de votre choix via Paypal. Ce don servira à financer notre hébergement.

    MERCI!




Note de ce sujet :
  • Moyenne : 0 (0 vote(s))
  • 1
  • 2
  • 3
  • 4
  • 5
[ASM] Interruption 2d, détection d'un debugger
05-04-2014, 10h28 (Modification du message : 14-04-2014, 22h18 par Dobry.)
Message : #1
Dobry Hors ligne
Tueur de lamouz
*



Messages : 206
Sujets : 25
Points: 73
Inscription : Aug 2011
[ASM] Interruption 2d, détection d'un debugger
Depuis une petite semaine j'ai repris l'assembleur, avec MASM, voici un bref recap de ce que j'ai trouvé sur l'interruption 2d (qui lèvre une exception qui doit être gérée).
J'ai trouvé énormement de ressources dans la magnifique suite de tutorial de Dr Fu : http://fumalwareanalysis.blogspot.jp/p/m...verse.html
Voici mes observations (pas eu le temps de faire la mise en page, mais j'attend vos retours avec impatience avant de publier une version plus travaillée).

INT 02Dh, hum, vous avez dit debugger ?
Je me suis plongé un peu dans les différentes techniques de detection des debuggers, et souhaite faire partager le premier : l'interruption 2d.
Cette interruption provoque la levée d'une exception, si le debugger est présent il va capturer cette exception et le programme ne sera jamais capable de le récupérer, on imagine déjà que l'on pourrait effectuer des opérations qui doivent être executées uniquement si le debugger n'est pas présent dans cette exception, voyons voir comment ceci fonctionne.
Tout d'abord, pour le reste de cet article, nous utiliserons MASM et IMM Debugger, ainsi qu'un code assez simple (que je detaillerai à la fin de cet article car ce n'est pas le sujet de cet article) qui fait simplement apparaitre une fenêtre basique avec uniquement un titre. Afin d'avoir un retour visuel de nos différentes expériences, le but sera de modifier le titre de cette fenêtre.
Le code de base est le suivant:
Code ASM :

.386
.model flat, stdcall
option casemap:none

include windows.inc

include user32.inc
includelib user32.lib

include kernel32.inc
includelib kernel32.lib

WinMain proto WORD,WORD,WORD,WORD

.data
ClassName   BYTE    "SimpleWinClass", 0
NoDebugger  BYTE    "A great title",0
Debugger    BYTE    "Please close the debugger",0
Secret      BYTE    "This is a secret title",0

.data?
hInstance HINSTANCE ?
CommandLine LPSTR ?
AppName LPCTSTR ?

.code
start:
 invoke GetModuleHandle,NULL
 mov hInstance, eax
 
 invoke GetCommandLine
 mov CommandLine, eax
 
 invoke WinMain, hInstance, NULL, CommandLine, SW_SHOWDEFAULT
 invoke ExitProcess,eax
 
 WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShowWORD
 LOCAL wc:WNDCLASSEX
 LOCAL msg:MSG
 LOCAL hwnd:HWND
 
 mov wc.cbSize, SIZEOF WNDCLASSEX
 mov wc.style, CS_HREDRAW OR CS_VREDRAW
 mov wc.lpfnWndProc, OFFSET WndProc
 mov wc.cbClsExtra, NULL
 mov wc.cbWndExtra, NULL
 push hInstance
 pop wc.hInstance
 mov wc.hbrBackground, COLOR_WINDOW+1
 mov wc.lpszMenuName, NULL
 mov wc.lpszClassName, OFFSET ClassName
 invoke LoadIcon,NULL,IDI_APPLICATION
 mov wc.hIcon, eax
 mov wc.hIconSm, eax
 invoke LoadCursor,NULL,IDC_ARROW
 mov wc.hCursor, eax
 invoke RegisterClassEx, addr wc
 mov AppName, offset NoDebugger

 ; Partie importante, génère une interruption
 xor eax, eax
 int 02dh
 inc eax


 startWindow:
 invoke CreateWindowEx,NULL,\
                ADDR ClassName,\
                AppName,\
                WS_OVERLAPPEDWINDOW,\
                CW_USEDEFAULT,\
                CW_USEDEFAULT,\
                CW_USEDEFAULT,\
                CW_USEDEFAULT,\
                NULL,\
                NULL,\
                hInst,\
                NULL
 mov hwnd, eax
 invoke ShowWindow,hwnd,CmdShow
 invoke UpdateWindow, hwnd
 .WHILE TRUE
    invoke GetMessage, ADDR msg, NULL, 0, 0
    .BREAK .IF (!eax)
    invoke TranslateMessage, ADDR msg
    invoke DispatchMessage, ADDR msg
 .ENDW
 mov eax, msg.wParam
 invoke ExitProcess,eax
 ret
 WinMain ENDP
 
 WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
    .IF uMsg==WM_DESTROY
        invoke PostQuitMessage, NULL
    .ELSE
        invoke DefWindowProc, hWnd, uMsg, wParam, lParam
        ret
    .ENDIF
    xor eax, eax
    ret

 WndProc endp
end start
 

Ce code est largement inspiré du magnifique document de NoteWorthy : http://asm.developpez.com/cours/noteworthy/
Essayer de le compiler, une fenêtre blanche avec le titre "A great title".

Afin de connaitre le fonctionnement des exceptions sur Windows, je vous conseil fortement de lire (ou au moins d'y jetter un coup d'oeil) : http://www.microsoft.com/msj/0197/except...ption.aspx et http://technet.microsoft.com/en-us/libra...67887.aspx histoire de savoir un peut comment fonctionne la gestions des exceptions sur Windows.
Pour les parresseux, un petit récapitulatif: les exceptions sont envoyés à un gestionnaire d'exceptions, qui contient une liste de structure pouvant gérer ces exceptions, si la structure renvoit le code ExceptionContinueExecution (définit dans EXCPT.H) le système considère que l'exception a été gérée et elle n'est pas passée à la structure suivante (et l'execution du programme reprend).
La structure qui doit gérer l'exception possède une méthode de callback qui ressemble à :
Code C :

__cdecl _except_handler(
    struct _EXCEPTION_RECORD *ExceptionRecord,
    void * EstablisherFrame,
    struct _CONTEXT *ContextRecord,
    void * DispatcherContext
);
 

Nous devons maintenannt définir cette fonction qui sera se chargée de gérer l'exception levée par l'interruption, pour cela voici le code:
Code ASM :

PTExceptionHandler proc ExceptionRecordWORD, EstablisherFrameWORD, ContextRecordWORD, DispatcherContextWORD
    mov eax, 0
    ret
 

Avec MASM, le mot clé "proc" décrit une procédure (fonction) suivit de ses arguments, dans notre cas, ceux requis par une fonction de gestion d'exception, la signification de ces arguments n'est pas essentiel mais elle est tout de même detaillée dans les liens précedents.
L'instruction mov eax, 0 permet de renvoyer le signal décrit précedemment : ExceptionContinueExecution afin de dire au système que l'exception a été correctement gérée (elle ne sera donc pas envoyés aux autres structures).
Il ne manque plus qu'une étape afin que notre exception soit utilisée par le système, il nous faut l'ajouter à la liste des interruptions, de préférence au début, pour cela, il existe deux directives (code à placer en premier, juste après l'étiquette "start") :
Code ASM :

assume FS:NOTHING
push offset PTExceptionHandler
push FS:[0]
mov FS:[0], esp
 

La première ligne charge le gestionnaire d'exception, la seconde ajoute sur la pile l'addresse de notre fonction de callback chargée de gérer les interruptions la troisième sauvegarde l'addresse de la fonction de callback par défaut (afin de la restaurer à la fin du programme), et la dernière ligne charge notre fonction (ajoutée au sommet de la pile, et donc pointée par ESP) en tant que fonction de gestion d'exception par défaut.
Ce que nous voulons faire maintenant est afficher un titre différent en fonction de la présence ou non d'un debugger, si un debugger est présent, nous laisserons le titre par défaut "A great title" dans le cas contraire, nous afficherons le titre "This is a secret title".
Par défaut le titre est "A great title" et nous savons également que si un débugger est présent l'exception ne sera pas exécutée, il nous suffit donc de changer le titre dans ce code de gestion de l'exception, pour le changer en "This is a secret title", ce code se résume en une ligne à placer dans PTExceptionHandler en première ligne :
Code ASM :
mov AppName, offset Secret
.
Ce code résulte en un changement de l'addresse pointée par AppName en faveur de celle contenant le titre spécial.
Vous pouvez maintenant essayer, si le code est éxecuté depuis un debugger (IMM par exemple), le titre de la fenêtre est : "A great title", cependant s'il est éxecuté sans debugger, le titre de la fenêtre est changé en "This is a secret title", cela fonctionne bien et nous savons maintenant comment detecter la présence d'un debugger.

L'avantage de cette instruction (int 2d) c'est qu'elle nous permet de detecter d'une autre façon un debugger, en effet, lorsque qu'une exception est gérée par le système, le registre EIP (qui pointe la prochaine instruction qui doit être executée) est decrementé de un (et pointe de nouveau vers l'exception que l'on considère comme corrigée), dans le cas d'une interruption int 2d, le registre eip est incrementé de un, ce qui fait que EIP pointe vers l'instruction située juste apprès l'appel à EIP (execution normale du programme). Cependant, si l'exception est gérée par le debugger, EIP n'est pas decrementé de un, mais uniquement incrementé, ce qui engendre le "saut" d'un byte par le registre EIP, ainsi si un debugger est présent l'instruction située après int 2d sera soit tronqué (si elle tient sur plus d'un byte), soit sautée (si elle tient sur un byte).
Comment utiliser ceci pour detecter la présence d'un debugger ?
Pour cela il nous faut placer une instruction (sur un byte) à la suite de notre interruption afin de différencier les deux cas, si vous regarder le premier code, on remarque la présence de l'instruction
Code ASM :
inc eax
(opcode : 0x40), juste après notre interruption, ainsi si le programme est éxécuté normalement, le registre EAX sera incrementé, et vaudra 1, dans le cas contraire, sa valeur ne sera pas changée et restera 0.
Voici le code que nous allons utiliser par la suite, il est à mettre juste après l'instruction
Code ASM :
inc eax
:
Code ASM :

.IF eax == 1 ; Pas de débugger
    mov AppName, offset NoDebugger
.ELSE ; Présence d'un débugger
    mov AppName, offset Debugger
.ENDIF
 

Notez que les macros de MASM simplifient nettement le code, mais nous aurions très bien pu utiliser des instructions de jump avec des étiquettes pour effectuer le même test.
Les instructions conditionnelles précédente vont changer le titre de la fenêtre en fonction de la valeur du registre EAX (et donc de l'éxécution ou non de l'instruction inc eax).
A l'execution de ce code, la fenêtre affichera "Please close the debugger" si le debugger est présent, "A great title" dans le cas contraire. Cette méthode permet donc elle aussi de modifier l'execution du programme en fonction des conditions de lancement.
Cepedant, les techniques précédentes peuvent facilement être contrées facilement par la plupart des débugger. En effet en lui précisant qu'il faut passer cette exception au programme et ne pas la capturer. Par exemple, pour IMM, il suffit lors de l'execution de l'interruption, d'appuyer sur "MAJ+F9" au lieu de "F9" , en faisant ca, même depuis le debugger, le titre de la fenêtre est "This is a secret title", nous devons donc trouver quelque chose de plus puissant si nous voulons detecter de façon plus efficace la présence d'un debugger.

ex0ns, à votre service

Tous les fichiers (en fonction des étapes) sont disponible dans l'archive suivante : lien
Aestuārium Erudītiōnis

There are only two hard things in Computer Science: cache invalidation, naming things, and off-by-one errors.
+1 (5) -1 (0) Répondre
05-04-2014, 11h18 (Modification du message : 05-04-2014, 11h19 par supersnail.)
Message : #2
supersnail Hors ligne
Éleveur d'ornithorynques
*******



Messages : 1,609
Sujets : 71
Points: 465
Inscription : Jan 2012
RE: [ASM] Interruption 2d, détection d'un debugger
C'est malin, j'avais fait un tuto sur les SEH aussi: http://n-pn.fr/t/3487-les-structured-exception-handlers

Sinon, toujours sympa à lire Smile
Mon blog

Code :
push esp ; dec eax ; inc ebp ; and [edi+0x41],al ; dec ebp ; inc ebp

"VIM est merveilleux" © supersnail
+1 (0) -1 (0) Répondre
05-04-2014, 15h57
Message : #3
ark Hors ligne
Psyckomodo!
*****



Messages : 1,033
Sujets : 48
Points: 317
Inscription : Sep 2011
RE: [ASM] Interruption 2d, détection d'un debugger
Excellent dude =)

Je lirais ça plus en détail dans la semaine, mais ça a l'air vraiment sympa a lire =)
En tout cas, la syntaxe de MASM avec toutes ces macro, ça ressemble même plus a de l'assembleur! :p
+1 (0) -1 (0) Répondre
05-04-2014, 17h28
Message : #4
Dobry Hors ligne
Tueur de lamouz
*



Messages : 206
Sujets : 25
Points: 73
Inscription : Aug 2011
RE: [ASM] Interruption 2d, détection d'un debugger
(05-04-2014, 11h18)supersnail a écrit : C'est malin, j'avais fait un tuto sur les SEH aussi: http://n-pn.fr/t/3487-les-structured-exception-handlers

Sinon, toujours sympa à lire Smile
Yep je sais mais bon ca fait pas de mal de le redire !
Aestuārium Erudītiōnis

There are only two hard things in Computer Science: cache invalidation, naming things, and off-by-one errors.
+1 (0) -1 (0) Répondre
14-04-2014, 11h45 (Modification du message : 14-04-2014, 11h45 par ark.)
Message : #5
ark Hors ligne
Psyckomodo!
*****



Messages : 1,033
Sujets : 48
Points: 317
Inscription : Sep 2011
RE: [ASM] Interruption 2d, détection d'un debugger
J'ai finalement pris le temps de lire ton article correctement, c'est pas mal comme technique. Je c'est pas vraiment pareil, mais sur des systemes de type Linux, il existe un interruption qui est catchée par le débugger, il s'agit de: int 0x03. Cet interruption se comporte comme un breakpoint du coté débugger, et stop le programme s'il arrive jusque la sans debugger. Cependant, il s'agit d'un signal comme un autre, je pense qu'on doit pouvoir le catcher avec une fonction comme signal() ou sigaction().
Il existe un autre moyen de détecter la présence d'un débugger, il suffit de faire des appels a ptrace() et voir en fonction du retour de certaines de ces fonctions si on a un débugger présent ou non. Cela ce bypasse assez facilement puisqu'il suffit de modifier la condition, ou une des valeurs qui sont comparés. :)

Au passage, tu n'as toujours pas upload les fichiers ;)
+1 (0) -1 (0) Répondre
14-04-2014, 22h21
Message : #6
Dobry Hors ligne
Tueur de lamouz
*



Messages : 206
Sujets : 25
Points: 73
Inscription : Aug 2011
RE: [ASM] Interruption 2d, détection d'un debugger
Je dois dire que j'ai entendu parler de int 0x03 mais je me suis jamais demandé quel était la différence entre les deux, je vais aller voir (je doute que la différence soit grande), je vous tiens au courant.
Pour ptrace() je ne connaissais pas, merci Smile
Désolé, liens mis à jour dans le post !
Aestuārium Erudītiōnis

There are only two hard things in Computer Science: cache invalidation, naming things, and off-by-one errors.
+1 (0) -1 (0) Répondre


Sujets apparemment similaires…
Sujet Auteur Réponses Affichages Dernier message
  [C] Besoin d'aide pour débugger mon code Polo 4 368 22-03-2013, 01h08
Dernier message: Polo

Atteindre :


Utilisateur(s) parcourant ce sujet : 1 visiteur(s)
N-PN
Accueil | Challenges | Tutoriels | Téléchargements | Forum | Retourner en haut