Непонятки с информацией из статьи про SEH

Тема в разделе "WASM.ASSEMBLER", создана пользователем Nicholas_F, 5 май 2010.

  1. Nicholas_F

    Nicholas_F New Member

    Публикаций:
    0
    Регистрация:
    8 апр 2010
    Сообщения:
    29
    Привет.
    В статье "SEH изнутри" http://www.wasm.ru/article.php?article=Win32SEHPietrek1 на рис.3 приведен следующий листинг:

    Код (Text):
    1. DWORD handler = (DWORD)_except_handler;
    2.  
    3.     __asm{                          // Создаем структуру EXCEPTION_REGISTRATION:
    4.         push        handler        // Адрес функции обработчика исключений.
    5.         push        FS:[0]         // Адрес предыдущего EXECEPTION_REGISTRATION.
    6.         mov         FS:[0], ESP  // Добавляем в связанный список EXECEPTION_REGISTRATION.
    7.     }
    8.  
    9.     __asm{
    10.         mov         eax, 0      // Обнуляем значение регистра EAX.
    11.         mov         [eax], 1    // Чтобы преднамеренно вызвать исключение, делаем запись по нулевому адресу.
    12.     }
    13.  
    14.     printf("After writing!\n");
    15.  
    16.     __asm{                     // Удаляем из связанного списка EXECEPTION_REGISTRATION.
    17.         mov     eax, [ESP]   // Получаем указатель на предыдущий EXECEPTION_REGISTRATION.
    18.         mov     FS:[0], EAX // Устанавливаем в начале списка предыдущий EXECEPTION_REGISTRATION.
    19.         add     esp, 8         // Удаляем из стека структуру EXECEPTION_REGISTRATION.
    20.     }
    Я не могу понять следующее - где-то читал, что по адресу fs:[0] живет TIB, но в комментах сказано, что на этот адрес пишем адрес предыдущего EXECEPTION_REGISTRATION. И что значит "Добавляем в связанный список EXECEPTION_REGISTRATION" в следующем комменте, что такое вообще связный список?

    Тут скорее всего все просто, но я понятия не имею где искать ответ, поэтому решил спросить на форуме.
     
  2. lhc645

    lhc645 New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2009
    Сообщения:
    106
    В начале NT_TIB адрес EXCEPTION_REGISTRATION. Смотрим структуру NT_TIB

    http://www.nirsoft.net/kernel_struct/vista/NT_TIB.html
     
  3. Nicholas_F

    Nicholas_F New Member

    Публикаций:
    0
    Регистрация:
    8 апр 2010
    Сообщения:
    29
    т.е. по адресу fs:[0] сидит структура _NT_TIB, и мы в стек пихаем адрес PEXCEPTION_REGISTRATION_RECORD?
    А что делает mov FS:[0], ESP - что сейчас находится в ESP?
     
  4. Oleg_SK

    Oleg_SK Guest

    Публикаций:
    0
    Nicholas_F, не совсем понятно: что именно вам не понятно? Действительно, по адресу FS:[0] находится TIB. TIB является структурой, и выглядит (если память не изменяет) следующим образом:
    Код (Text):
    1. typedef struct _NT_TIB {
    2.     struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList;
    3.     PVOID StackBase;    //база стека
    4.     PVOID StackLimit;   //лимит стека
    5.     PVOID SubSystemTib;
    6.     union {
    7.         PVOID FiberData;
    8.         DWORD Version;
    9.     };
    10.     PVOID ArbitraryUserPointer;
    11.     struct _NT_TIB *Self;
    12. } NT_TIB;
    13. typedef NT_TIB *PNT_TIB;
    Как видите, первым элементом этой структуры является указатель на вершину связного списка ExceptionList. Каждый элемент этого списка содержит адрес обработчика исключений и адрес предыдущего элемента связанного списка ExceptionList. Таким образом на текущий обработчик исключений SEH указывает тот элемент списка ExceptionList, который находится на вершине связанного списка, адрес которого находится по адресу FS:[0]. Что касается связных списков, то они бывают нескольких видов, и в данном случае используется однонаправленный связный список. IMHO, проще всего представить себе этот список как массив, элементы которого хранятся в памяти не последовательно, а в разных местах. каждый элемент этого списка представляет собой структуру, в которой помимо прочего хранится адрес предыдущего элемента этого списка.
     
  5. Oleg_SK

    Oleg_SK Guest

    Публикаций:
    0
    Добавляет в связанный список новый элемент, помещая его на вершину этого списка.
     
  6. Oleg_SK

    Oleg_SK Guest

    Публикаций:
    0
    В ESP находится адрес нового элемента (являющегося структурой EXCEPTION_REGISTRATION_RECORD) добавляемого в связный список.
     
  7. Nicholas_F

    Nicholas_F New Member

    Публикаций:
    0
    Регистрация:
    8 апр 2010
    Сообщения:
    29
    Ага... понятно, но вот это не совсем ясно: ESP - по идее указывает на вершину стека... откуда там может быть адрес нового элемента являющегося структурой EXCEPTION_REGISTRATION_RECORD?
     
  8. Oleg_SK

    Oleg_SK Guest

    Публикаций:
    0
    Потаму что эта структура сформирована в стеке, и находится на его вершине (на которую указывает регистр ESP).
     
  9. Oleg_SK

    Oleg_SK Guest

    Публикаций:
    0
    Вообще, элементы связанного списка ExceptionList хранятся именно в стеке.
     
  10. Nicholas_F

    Nicholas_F New Member

    Публикаций:
    0
    Регистрация:
    8 апр 2010
    Сообщения:
    29
    Ааа точно! Спасибо большое :)
     
  11. Oleg_SK

    Oleg_SK Guest

    Публикаций:
    0
    Вот инструкции, которые формируют эту структуру в стеке:
    Код (Text):
    1.        push        handler        // Адрес функции обработчика исключений.
    2.         push        FS:[0]         // Адрес предыдущего EXECEPTION_REGISTRATION.
     
  12. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Нет, fs:[0] это не NT_TIB.
    Селектор fs указывает на сегмент, содержащий в себе Thread Environment Block, начинающийся с NT_TIB (Thread Information Block).
    fs:[0] - это уже поле в NT_TIB со смещением 0, то есть ExceptionList

    Называть fs:[0] адресом TIB некорректно.
     
  13. Nicholas_F

    Nicholas_F New Member

    Публикаций:
    0
    Регистрация:
    8 апр 2010
    Сообщения:
    29
    Вот такая непонятка еще, про одну из SEH структур: Iczelion в своих туториалах по PE формату использует следующую структуру для обработки исключения:
    Код (Text):
    1. SEH struct
    2.     PrevLink dd ?
    3.     CurrentHandler dd ?
    4.     SafeOffset dd ?
    5.     PrevEsp dd ?
    6.     PrevEbp dd ?
    7. SEH ends
    Как я понимаю, первые два поля - это структура EXEPTION_REGISTATION, а к чему относятся посление 3 поля? Эта структура фиксированной длины, значит она имеет свое описание? Как я понял, после возврата callback функции ExeptionContinueExecution выполнение кода продолжится со смещения SafeOffset и оно сохраняется в структуре CONTEXT. Но в этой же структуре сохраняются и значения регистров на момент исключения откуда они и могут быть восстановлены - зачем их сохранять еще и в нашей SEH struct?
     
  14. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Nicholas_F
    Для восстановления стековых фреймов. Исключение подразумевает не валидность контекста.
     
  15. Nicholas_F

    Nicholas_F New Member

    Публикаций:
    0
    Регистрация:
    8 апр 2010
    Сообщения:
    29
    Это понял.

    А про SEH struct? Как понимать эту структуру, включающую в себя EXEPTION_REGISTRATION и еще что-то...?
     
  16. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Nicholas_F
    Фрейм с параметрами для хэндлера.