+ Reply to Thread
Results 1 to 1 of 1

Thread: Exploit Development Course Part 3: Structured Exception Handling (SEH) (Перевод: klaus)

  1. #1
    klaus's Avatar

    Default Exploit Development Course Part 3: Structured Exception Handling (SEH) (Перевод: klaus)

    Перейти к содержанию


    Введение

    Обработчики исключений организованы в односвязный список, каждый элемент которого (т.е. каждый обработчик) связан с неким потоком. Как правило, для узлов списка выделяется место в стеке.

    Начало списка ссылается указателем который размещен в начале TEB (Thread Environment Block - структура которая используется для хранения информации о потоках в текущем процессе, каждый поток имеет свой TEB), поэтому, если мы хотим добавить новый обработчик исключений, новый узел будет добавлен в начало списка и указатель в TEB будет ссылаться на новый узел. Каждый узел имеет тип _EXCEPTION_REGISTRATION_RECORD, который содержит в себе адрес обработчика и указатель на следующий узел в списке. Довольно странное поведение указателя на следующий элемент списка, он не указывает на NULL как в большинстве случаев а равен 0xffffffff.

    Вот точное определение структуры:
    Code:
    0:000> dt _EXCEPTION_REGISTRATION_RECORD
    ntdll!_EXCEPTION_REGISTRATION_RECORD
       +0x000 Next             : Ptr32 _EXCEPTION_REGISTRATION_RECORD
       +0x004 Handler          : Ptr32     _EXCEPTION_DISPOSITION
    К TEB мы можем получить доступ через селектор fs начиная с fs:[0], так что не удивляйтесь видя в коде следующее:
    Code:
    mov    eax, dword ptr fs:[00000000h]      ; получить начало списка
    push   eax                                ; сохранить старое начало списка
    lea    eax, [ebp-10h]
    mov    dword ptr fs:[00000000h], eax      ; установить новое начало списка
    .
    .
    .
    mov    ecx, dword ptr [ebp-10h]           ; получить старое начало списка (поле NEXT текущего начала списка)
    mov    dword ptr fs:[00000000h], ecx      ; восстановить старое начало списка
    Компиляторы обычно регистрируют один глобальный обработчик который знает о том, какой участок памяти в данный момент исполняется (опираясь на глобальную переменную).

    Поскольку каждый поток имеет свой TEB, операционная система гарантирует что сегмент выбранный регистром fs ссылается всегда на правильный TEB (т.е. одного текущего процесса). Что бы получить адрес TEB надо прочитать fs:[18h] который соответствует области Self структуры TEB.

    Давайте выведем TEB:
    Code:
    0:000> !teb
    TEB at 7efdd000
        ExceptionList:        003ef804          <-----------------------
        StackBase:            003f0000
        StackLimit:           003ed000
        SubSystemTib:         00000000
        FiberData:            00001e00
        ArbitraryUserPointer: 00000000
        Self:                 7efdd000
        EnvironmentPointer:   00000000
        ClientId:             00001644 . 00000914
        RpcHandle:            00000000
        Tls Storage:          7efdd02c
        PEB Address:          7efde000
        LastErrorValue:       2
        LastStatusValue:      c0000034
        Count Owned Locks:    0
        HardErrorMode:        0
    Теперь проверим ссылается ли fs на TEB:
    Code:
    0:000> dg fs
                                      P Si Gr Pr Lo
    Sel    Base     Limit     Type    l ze an es ng Flags
    ---- -------- -------- ---------- - -- -- -- -- --------
    0053 7efdd000 00000fff Data RW Ac 3 Bg By P  Nl 000004f3
    Как было сказано ранее, fs:18h содержит адрес TEB:
    Code:
    0:000> ? poi(fs:[18])
    Evaluate expression: 2130563072 = 7efdd000
    Вспомните что poi разыменовывает указатель, а «?» используется для вычисления выражения.

    Давайте посмотрим какое имя у структуры на которую указывает ExceptionList :

    Code:
    0:000> dt nt!_NT_TIB ExceptionList
    ntdll!_NT_TIB
       +0x000 ExceptionList : Ptr32 _EXCEPTION_REGISTRATION_RECORD
    Это значит то, что каждый узел это экземпляр _EXCEPTION_REGISTRATION_RECORD, как и было ранее упомянуто.

    Для вывода всего списка используйте !slist:
    Code:
    0:000> !slist $teb _EXCEPTION_REGISTRATION_RECORD
    SLIST HEADER:
       +0x000 Alignment          : 3f0000003ef804
       +0x000 Next               : 3ef804
       +0x004 Depth              : 0
       +0x006 Sequence           : 3f
    
    SLIST CONTENTS:
    003ef804
       +0x000 Next             : 0x003ef850 _EXCEPTION_REGISTRATION_RECORD
       +0x004 Handler          : 0x6d5da0d5     _EXCEPTION_DISPOSITION  MSVCR120!_except_handler4+0
    003ef850
       +0x000 Next             : 0x003ef89c _EXCEPTION_REGISTRATION_RECORD
       +0x004 Handler          : 0x00271709     _EXCEPTION_DISPOSITION  +0
    003ef89c
       +0x000 Next             : 0xffffffff _EXCEPTION_REGISTRATION_RECORD
       +0x004 Handler          : 0x77e21985     _EXCEPTION_DISPOSITION  ntdll!_except_handler4+0
    ffffffff
       +0x000 Next             : ???? 
       +0x004 Handler          : ???? 
    Can't read memory at ffffffff, error 0
    Помните что $teb это адрес TEB.

    Простой способ вывести цепочку обработчиков исключений:

    Code:
    0:000> !exchain
    003ef804: MSVCR120!_except_handler4+0 (6d5da0d5)
      CRT scope  0, func:   MSVCR120!doexit+116 (6d613b3b)
    003ef850: exploitme3+1709 (00271709)
    003ef89c: ntdll!_except_handler4+0 (77e21985)
      CRT scope  0, filter: ntdll!__RtlUserThreadStart+2e (77e21c78)
                    func:   ntdll!__RtlUserThreadStart+63 (77e238cb)
    
    Мы можем также изучить цепочку обработчиков исключений вручную:
    0:000> dt 003ef804 _EXCEPTION_REGISTRATION_RECORD
    MSVCR120!_EXCEPTION_REGISTRATION_RECORD
       +0x000 Next             : 0x003ef850 _EXCEPTION_REGISTRATION_RECORD
       +0x004 Handler          : 0x6d5da0d5     _EXCEPTION_DISPOSITION  MSVCR120!_except_handler4+0
    0:000> dt 0x003ef850 _EXCEPTION_REGISTRATION_RECORD
    MSVCR120!_EXCEPTION_REGISTRATION_RECORD
       +0x000 Next             : 0x003ef89c _EXCEPTION_REGISTRATION_RECORD
       +0x004 Handler          : 0x00271709     _EXCEPTION_DISPOSITION  +0
    0:000> dt 0x003ef89c _EXCEPTION_REGISTRATION_RECORD
    MSVCR120!_EXCEPTION_REGISTRATION_RECORD
       +0x000 Next             : 0xffffffff _EXCEPTION_REGISTRATION_RECORD
       +0x004 Handler          : 0x77e21985     _EXCEPTION_DISPOSITION  ntdll!_except_handler4+0
    © Translated by klaus (r0 Crew)
    Last edited by klaus; 26-06-2015 at 08:36.
    Do not follow the ancient masters, seek what they sought. (c) Matsuo Bashō

  2. 7 пользователя(ей) сказали cпасибо:
    Dark Koder (23-06-2015) Darwin (22-06-2015) Shizoid (01-07-2015) benedict (23-06-2015) dukeBarman (22-06-2015) root (25-06-2015) ximera (22-06-2015)
+ Reply to Thread

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
All times are GMT. The time now is 09:45
vBulletin® Copyright ©2000 - 2017
www.reverse4you.org