Перейти к содержанию
Введение
Обработчики исключений организованы в односвязный список, каждый элемент которого (т.е. каждый обработчик) связан с неким потоком. Как правило, для узлов списка выделяется место в стеке.
Начало списка ссылается указателем который размещен в начале TEB (Thread Environment Block - структура которая используется для хранения информации о потоках в текущем процессе, каждый поток имеет свой TEB), поэтому, если мы хотим добавить новый обработчик исключений, новый узел будет добавлен в начало списка и указатель в TEB будет ссылаться на новый узел. Каждый узел имеет тип _EXCEPTION_REGISTRATION_RECORD, который содержит в себе адрес обработчика и указатель на следующий узел в списке. Довольно странное поведение указателя на следующий элемент списка, он не указывает на NULL как в большинстве случаев а равен 0xffffffff.
Вот точное определение структуры:
К TEB мы можем получить доступ через селектор fs начиная с fs:[0], так что не удивляйтесь видя в коде следующее:Code:0:000> dt _EXCEPTION_REGISTRATION_RECORD ntdll!_EXCEPTION_REGISTRATION_RECORD +0x000 Next : Ptr32 _EXCEPTION_REGISTRATION_RECORD +0x004 Handler : Ptr32 _EXCEPTION_DISPOSITION
Компиляторы обычно регистрируют один глобальный обработчик который знает о том, какой участок памяти в данный момент исполняется (опираясь на глобальную переменную).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:
Теперь проверим ссылается ли fs на 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:18h содержит адрес 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
Вспомните что poi разыменовывает указатель, а «?» используется для вычисления выражения.Code:0:000> ? poi(fs:[18]) Evaluate expression: 2130563072 = 7efdd000
Давайте посмотрим какое имя у структуры на которую указывает ExceptionList :
Это значит то, что каждый узел это экземпляр _EXCEPTION_REGISTRATION_RECORD, как и было ранее упомянуто.Code:0:000> dt nt!_NT_TIB ExceptionList ntdll!_NT_TIB +0x000 ExceptionList : Ptr32 _EXCEPTION_REGISTRATION_RECORD
Для вывода всего списка используйте !slist:
Помните что $teb это адрес TEB.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
Простой способ вывести цепочку обработчиков исключений:
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)



Reply With Quote
Thanks
