Russian translation of the article published in phrack 65, phook - The PEB Hooker: http://phrack.org/issues.html?issue=65&id=10#article http://www.phrack.org/ Translation posted by Izg0y in CULT OF RUSSIAN UNDERGROUND - http://coru.in/ ==Phrack Inc.== Volume 0x0c, Issue 0x41, Phile #0x0a of 0x0f |=-----------------------------------------------------------------------=| |=---------------------=[ phook - The PEB Hooker ]=----------------------=| |=-----------------------------------------------------------------------=| |=-----------------------------------------------------------------------=| |=----------------=[ [Shearer] - eunimedesAThotmail.com ]=---------------=| |=----------------=[ Dreg - DregATfr33project.org ]=---------------=| |=-----------------------------------------------------------------------=| |=--=[ http://www.fr33project.org / Mirror: http://www.disidents.com ]=--=| |=-----------------------------------------------------------------------=| |=-------------------------=[ October 15 2007 ]=-------------------------=| |=-----------------------------------------------------------------------=| ------[ Index 0.- Предисловие 1.- Введение 2.- Предыдущие концепции 2.1 - Process Environment Block (PEB) 2.1.1 - LoaderData (загрузчик данных) 2.2 - Import Address Table (IAT) 2.2.1 - Загрузка из IAT 2.3 - Запуск процесса в приостановленном состоянии 2.4 - Инъекция DLL в процесс 2.5 - Перехват в ring3 2.5.1 - Проблемы 3.- Разработки 3.1 - Первый шаг к PEB HOOKING 3.2 - Обмен данными в загрузчике данных 3.3 - Динамическая загрузка модулей 3.4 - Восстановление IAT 3.5 - Начало выполнения 3.6 - API которые работают с модулями 3.7 - Новая разработка: DLL MINIFILTER 3.8 - Частые проблемы 4.- phook 4.1 - InjectorDLL 4.2 - Консоль управления 4.3 - CreateExp 4.3.1 - Forwarder DLL 4.4 - ph_ker32.dll 4.4.1 - Проблемы стэка 4.4.2 - Проблемы регистра 4.4.3 - JMP макрос 4.4.4 - Версии 4.5 - Использование phook 4.5.1 - DLL MINIFILTER 4.6 - Частые проблемы 5.- Что делаем 6.- Тестирование 7.- Преимущества и возможности 8.- Заключение 9.- Благодарности 10.- Похожие работ 11.- Ссылки 12.- Исходный код ------[ 0.- Предисловие Номенклатуры: .- [T.Index]: соответствующих работ (section 10). .- [R.Index]: ссылки (section 11). Индекс это идентификатор из номенклатуры. Для понимания документа требуются знания по win32: - Форматы исполняемых файлов: - PE32 [R.3]: DLLs, EXE... - Программирование: - Использование APIs [R.20]: LoadLibrary, GetModuleHandle ... - Hooks [R.10] [R.8] [...] - Win32 ASM [R.21]. 2 термины каторые часто используются в документе: 1.- DLL_FAKE: DLL которая будет подменять системную DLL (DLL_REAL). 2.- DLL_REAL: DLL которая будет подменяться DLL_FAKE. Если неуказанно иначе, hook/s будет всегда ссылаться на hook/s в win32. ------[ 1.- Введение Перехват в win32 обычно используются для обратного проектирования, обычно для анализа работы malware и пакеров, систем защиты программного обеспечения. Перехват также используются для наблюдения за действиями части программ: доступ к файлам, сокетам, модификацией реестра и т д... Большинство известных методов реализации перехвата под ring3 (см. пункт 2.5) имеют различные проблемы (см. пункт 2.5.1). Наиболее актуальная для нас заключается в том, что специальные программы могут обнаружить их... Некоторые защитные программы (фаерволы, антивирусы, антируткиты и т. д.), в состоянии приостановить поток, снять неизвестные ей перхваты и продолжить нормальное выполнение потока. Другая проблема возникает при попытке реализовать перехват в вирусе, который отслеживает API адреса в памяти, отключая такие типы перехвата, как IAT HOOKING (см. пункт 2.5). Есть так же защитное ПО использующие вирусные технологии и наоборот. Из-за этих проблем мы создали phook, который использует несколько документированных методов при реализации перехвата в ring3 и даже реализует некоторые вирусные технологи используя наш перехват. Этот документ объясняет как работает phook и PEB HOOKING [T.1]. phook - это инструмент, который использует PEB PEB HOOKING [T.1] для реализации перехвата в DLL, он также позволяет реализовать другие задачи в интерактивном режиме: - Показать список загружаемых модулей. - Загрузить DLL. - Скачать DLL. - ... PEB HOOKING [T.1] выполняет замену DLL_REAL в памяти на DLL_FAKE, поэтому все модули процесса, которые используют DLL_REAL теперь будут использовать DLL_FAKE. ------[ 2 - Предыдущая концепций Для понимания работы PEB HOOKING [T.1] метода и phook, необходимо четко понимать некоторые понятия. ------[ 2.1 - Process Environment Block Process Environment Block (PEB) это структура [R.1] расположенная в пользовательском пространстве, которая содержит данные окружающей среды процесса : [R.2]: - Переменные среды. - Список загруженных модулей. - Адреса в памяти Heap. - If the process is being depurated. - ... ------[ CODE typedef struct _PEB { BOOLEAN InheritedAddressSpace; BOOLEAN ReadImageFileExecOptions; BOOLEAN BeingDebugged; BOOLEAN Spare; HANDLE Mutant; PVOID ImageBaseAddress; PPEB_LDR_DATA LoaderData; PRTL_USER_PROCESS_PARAMETERS ProcessParameters; PVOID SubSystemData; PVOID ProcessHeap; PVOID FastPebLock; PPEBLOCKROUTINE FastPebLockRoutine; PPEBLOCKROUTINE FastPebUnlockRoutine; ... } PEB, *PPEB; ------[ END CODE Для реализации PEB HOOKING, нужно использовать поле LoaderData [T.1]. ------[ 2.1.1 - LoaderData Оно представляет собой структуру [R.1], в которой есть данные о модулях в процессе. Это двойной связанный список, и он может быть отсортированы по трём критериям [R.2]: 1.- Порядок загрузки 2.- Порядок в памяти 3.- Порядок инициализации ------[ CODE typedef struct _PEB_LDR_DATA { ULONG Length; BOOLEAN Initialized; PVOID SsHandle; LIST_ENTRY InLoadOrderModuleList; LIST_ENTRY InMemoryOrderModuleList; LIST_ENTRY InInitializationOrderModuleList; } PEB_LDR_DATA, *PPEB_LDR_DATA; ------[ END CODE Все flink и blink поля в LIST_ENTRY указывает на LDR_MODULE. ------[ CODE typedef struct _LIST_ENTRY { struct _LIST_ENTRY * Flink; struct _LIST_ENTRY * Blink; } LIST_ENTRY,*PLIST_ENTRY; ------[ END CODE Данные, которые нам понадобятся из LDR_MODULE, реализовывая PEB HOOKING это [T.1]: - BaseAddress: Адрес модуля в памяти.. - EntryPoint : Адрес где содержится первая инструкция для выполнения модуля. - SizeOfImage: Размер модуля в памяти. ------[ CODE typedef struct _LDR_MODULE { LIST_ENTRY InLoadOrderModuleList; LIST_ENTRY InMemoryOrderModuleList; LIST_ENTRY InInitializationOrderModuleList; PVOID BaseAddress; PVOID EntryPoint; ULONG SizeOfImage; UNICODE_STRING FullDllName; UNICODE_STRING BaseDllName; ULONG Flags; SHORT LoadCount; SHORT TlsIndex; LIST_ENTRY HashTableEntry; ULONG TimeDateStamp; } LDR_MODULE, *PLDR_MODULE; ------[ END CODE ------[ 2.2 - Import Address Table Import Address Table (IAT) это таблица где содержится PE32 [R.3], который заполняет win32 загрузчик, когда модуль[R.4] загружен и также на дальнейшей загрузке, используя stub в IAT. Внешние символы, в которых нуждается модуль, называются импортом, а символы, которые модуль предоставляет другим модулям, называются экспортом. В IAT [R.3] модуля есть адрес его импорта, это значит, что в IAT [R.3] модуля есть адрес экспорта используемых из других модулей. ------[ 2.2.1 - Загрузка из Import Address Table Для win32 загрузчика, который может получить экспорт, нужно узнать: модуль в котором он расположен, имя экспорта и/или ordinal [R.3]. В PE32 имеет структура IMAGE_IMPORT_DESCRIPTOR [R.5], где мы можем выделить 3 области: - Name : Имя модуля где находится экспорт. - OriginalFirstThunk : Адрес таблицы импорта - FirstThunk : Адрес таблицы, идентичной OriginalFirstThunk, куда win32 загрузчик помещает адреса импорта. ------[ CODE typedef struct _IMAGE_IMPORT_DESCRIPTOR { DWORD OriginalFirstThunk; DWORD TimeDateStamp; DWORD ForwarderChain; DWORD Name; DWORD FirstThunk; } IMAGE_IMPORT_DESCRIPTOR,*PIMAGE_IMPORT_DESCRIPTOR; ------[ END CODE Каждая запись в таблице FirstThunk и OriginalFirstThunk имеет 2 поля[R.3]: - Hint: если первые 31/63 bits составляют 0x80000000, то импорт будет произведён по ordinal, в противном случаи нет. Биты 15-0 это ordinal. - Name: Адрес, где хранятся имена экспорта. ------[ CODE typedef struct _IMAGE_IMPORT_BY_NAME { WORD Hint; BYTE Name[1]; } IMAGE_IMPORT_BY_NAME,*PIMAGE_IMPORT_BY_NAME; ------[ END CODE ------[ 2.3 - Запуск процесса в приостановленном состоянии Когда мы хотим создать процесс в приостановленном состоянии, то нам необходимо знать, какого типа он [R.6]: - Console - GUI Консольные тип процесса могут быть созданы с помощью API CreateProcess и флага CREATE_SUSPENDED. Если GUI процесс открывается с флагом CREATE_SUSPENDED, то он можеь работать не корректно, поэтому он должен быть создан с помощью API: 1.- CreateProcess : Процесс создаётся без флага CREATE_SUSPENDED. 2.- WaitForInputIdle: Дождаться корректной загрузки [R.6] процесса. 3.- SuspendThread : Приостановить главный поток. ------[ 2.4 - Инъекция DLL в процесс Существует много способов внедрения DLL в процесс [R.7], самый простой это использовать связку API: 1.- VirtualAllocEx : Зарезервировать память в процессе. 2.- WriteProcessMemory: Записать в зарезервированное место код который загрузит DLL. 3.- CreateRemoteThread: Создать поток в процессе каторый выполнит записанный код. 4.- VirtualFreeEx : Освободить зарезервированную память после подгрузки DLL. ------[ 2.5 - Hooks в ring3 Всегда существует куча форм для реализации перехвата в win32 как в ринг0 так и в ринг3. Проблема при работе в ring0 заключается в том, что если код работает не стабильно, то это отразиться на всей ОС. Самый стабильный метод для OS реализовать перехват из ring3. Самые известные методы: - IAT HOOKING: Запись IAT [R.3] изменяется, так чтоб загрузчик win32, указывал на другую область [R.8]. - PUSH + RET: В область кода PUSH DIRECTION и RET вставляется jump , чтоб передать управление своему коду, но приходится восстанавливать оригинальный код в определённый момент [R.9]. - SetWindowHook...: С помощью этих API, вызов своего кода может быть зарегистрирован для различных событий в системе. ------[ 2.5.1 - Проблемы Некоторые проблемы при реализации перехвата в ring3: +-------------------------------------------------------------------------+ | Метод | Проблема | +------------------------+------------------------------------------------+ | IAT HOOKING [R.8] | 1.- IAT [R.3] для всех загружаемых модулей | | | должен быть изменён. | | | 2.- Модулю не нужен IAT [R.3] для | | | использования символов экспортируемых | | | другими. | | | 3.- Это всем хорошо известно. | | | 4.- Легко восстановить. | | | 5.- Можно обнаружить. | | | 6.- Не даёт полный контроль сразу после старта.| |------------------------+------------------------------------------------| | PUSH + RET [R.9] | 1.- Метод не универсален. | | | 2.- Сложно в применении. | | | 3.- Легко восстановить. | | | 4.- Можно обнаружить. | | | 5.- Не даёт полный контроль сразу после старта.| |------------------------+------------------------------------------------| | Otros "hooks": | 1.- Не даёт полного контроля. | | SetWindowHook... [R.10]| 2.- Легко восстановить. | | | 3.- Можно обнаружить. | |------------------------+------------------------------------------------| | PEB HOOKING [T.1] | 1.- Сложно в применении. | | | 2.- Оригинальная DLL и внедрённая, должна | | | экспортировать теже символы в том же | | | объеме (как минимум). | | | 3.- Можно обнаружить. | | | 4.- Не даёт полный контроль сразу после старта.| +------------------------+------------------------------------------------+ Примечание: Эта таблица только мнение авторов. Вызовы из ring3 в ring0 используя SYSENTER не могут управляться только с помощью предыдущих методов. Системны вызов из ring3 могут быть реализованы SYSENTER [R.11] без каких либо других DLL, таких образом, предыдущие методы сделались непригодным для использования, это довольно редкая ситуация. Из-за предыдущих проблем, мы решили использовать PEB HOOKING [T.1], чтобы создать механизм, который делает больше чем хук : phook - The PEB Hooker. Примечание: Преимущества и недостатки PEB HOOKING [T.1] разъясняются в section 7. ------[ 3.- Разработка В этом разделе будет говориться о базовой концепции и реализации PEB HOOKING [T.1]. Реализация не сложная, но только тогда, когда понимаешь для чего и зачем применяется тот или иной код. Шаги: 1.- Загрузить DLL_FAKE и DLL_REAL. 2.- В списке, используемым загрузчиком вин32, в котором перечислены все загруженные в данный момент модули, нужно поменять поля между DLL_FAKE и DLL_REAL 3.- Необходимо чтобы IAT [R.3] всех загруженных модулей, кроме DLL_REAL и возможно DLL_FAKE указывали функциям, что DLL_FAKE экспорт. ------[ 3.1 - Первый шаг к PEB HOOKING Прежде чем что-то сделать, необходимо загрузить DLL_FAKE в память процесса, к которому это требуется что-бы использовать PEB HOOKING [T.1]. DLL_FAKE должен иметь по крайней мере тот же самый экспорт что и DLL_REAL. ------[ 3.2 - Обмен данными в LoaderData Необходимо найти в DLL_FAKE и DLL_REAL некоторые идентификаторы LDR_MODULE, после чего обменяться следующей информацией: - EntryPoint - BaseAddress - SizeOfImage (почти всегда) Поиск с использованием поля BaseDllName будет получать данные о "LDR_MODULE", относящиеся к DLL_FAKE. Некоторые вирусы, упаковщики и API используют эту форму поиска, чтобы найти BaseAddress или EntryPoint для модуля. Необходимо изменить поле SizeOfImage если DLL_FAKE и DLL_REAL, не имеют равный размера в памяти. Поиск BaseAddress из kernel32.dll без "PEB HOOKING": 0 +---------------------------------+ [ process ] ---------+ | Process Environment Block (PEB) | | |---------------------------------| | | InheritedAddressSpace | | | ReadImageFileExecOptions | | | BeingDebugged | | | Spare | | | Mutant | | | ImageBaseAddress | +->| LoaderData |--+ | ... | | +---------------------------------+ | 1 | | +--------------------------------------------------------------+ | +----------------------------+ +----------------------------+ | | LoaderData | | LDR_MODULE | | +----------------------------+ |----------------------------| flink | | Length | | InLoadOrderModList |-----+ | | Initialized | | InMemoryOrderModList | | | | SsHandle | | InInitOrderModList | | +->| InLoadOrderModList | 2 | ... | | | InMemoryOrderModList |---->| BaseDllName "ntdll.dll" |---+ | | InInitOrderModList - Flink | +----------------------------+ | | +----------------------------+ +------------------------------------+ | | +----------------------------+ | | | LDR_MODULE (DLL_REAL) | | | |----------------------------| | | | InLoadOrderModList | 6 | +---------------------+ 3 | | InMemoryOrderModList | | | ¿Es "kernel32.dll"? |<-------+ | InInitOrderModList | | +---------------------+ | BaseAddress 7C801000 | | 8 | |4 ^ 7 | ... | | Si <-+ +-> No +-------------| BaseDllName "kernel32.dll" |<----+ | | 5 | ... | 9 | v +----------------------------+ | NextLdrModule(); v kernel32.dll = 7C801000 Поиск BaseAddress из kernel32.dll с использованием PEB HOOKING [T.1]: 0 +---------------------------------+ [ process ] ---------+ | Process Environment Block (PEB) | | |---------------------------------| | | InheritedAddressSpace | | | ReadImageFileExecOptions | | | BeingDebugged | | | Spare | | | Mutant | | | ImageBaseAddress | +->| LoaderData |--+ | ... | | +---------------------------------+ | 1 | | +--------------------------------------------------------------+ | +----------------------------+ +----------------------------+ | | LoaderData | | LDR_MODULE | | +----------------------------+ |----------------------------| flink | | Length | | InLoadOrderModList |-----+ | | Initialized | | InMemoryOrderModList | | | | SsHandle | | InInitOrderModList | | +->| InLoadOrderModList | 2 | ... | | | InMemoryOrderModList |---->| BaseDllName "ntdll.dll" |---+ | | InInitOrderModList - Flink | +----------------------------+ | | +----------------------------+ +------------------------------------+ | | +----------------------------+ | | | LDR_MODULE (DLL_REAL) | | | |----------------------------| 6 | | | InLoadOrderModList | | +---------------------+ 3 | | InMemoryOrderModList |flink| | ¿Es "kernel32.dll"? |<-------+ | InInitOrderModList |--+ | +---------------------+ | BaseAddress 7C801000 | | | 12 | |4-8 ^ ^ 7 | ... | | | Si <-+ +-> No | +-------------| BaseDllName "old_k32.dll" |<-|--+ | 5-9 | +------------+ | ... | | 13 | v | +----------------------------+ | | NextLdrModule(); +-+ | v | +----------------------------+ | kernel32.dll = 005C5000 | | LDR_MODULE (DLL_FAKE) | | 10 | |----------------------------| | 11 | | InLoadOrderModList | | | | InMemoryOrderModList | | | | InInitOrderModList | | | | BaseAddress 005C5000 | | | | ... | | +-| BaseDllName "kernel32.dll" |<+ | ... | +----------------------------+ Результаты поиска: 1.- BaseAddress без использования PEB HOOKING [T.1]: 7C801000 (DLL_REAL) 2.- BaseAddress с использованием PEB HOOKING [T.1]: 005C5000 (DLL_FAKE) PD: В поиске по InLoadOrderModList, первое поле показывает, что LDR_MODULE соответствует основному модулю. В примере он был опущен для ясности. ------[ 3.3 - Динамическая загрузка модулей Кoгда процесс, PEB HOOKING [T.1] будет выполнен, динамически [R.12] загруженные модули будут иметь импорт DLL_REAL, его IAT [R.3] будет автоматически загружен с необходимым экспортом DLL_FAKE. ------[ 3.4 - Восстановление IAT Кроме модулей DLL_FAKE и DLL_REAL, все IAT [R.3] экспортирующие DLL_REAL, должны быть заменены DLL_FAKE. IAT [R.3] DLL_FAKE не должен изменяться в случаи если DLL_REAL необходимо использовать. Если IAT из DLL_FAKE модифицирована таким образом, что экспорты DLL_REAL совпадают с DLL_FAKE, вызов экспорта из DLL_REAL из такого же экспорта DLL_FAKE войдет в непрерывный бесконечный цикл, вызывающий переполнение стека. +--------------------------+ +--------------------------------+ | .text DLL_FAKE | | IAT | |--------------------------| |--------------------------------| | ... | | LocalAlloc 1 (Nr_LocalAlloc) | | PUSH EBP | +->| LoadLibrary 2 (Nr_LoadLibrary) |--+ | MOV EBP, ESP | | | .... | | | ... | | +--------------------------------+ | | LoadLibrary_FAKE: | | | +->| PUSH original_lib_name | | 0 | | | CALL IAT[Nr_LoadLibrary] |--+ | | | ... | | | | POP EBP | | | | RET | | | | ... | | | +--------------------------+ | | 1 | +-----------------------------------------------------------------------+ Реальную проблему составляет то, что мы обращаемся сами к себе или одной из других DLL. Это не должно восстанавливать IAT [R.3] любого другова модуля (DLL_ANY), когда DLL_FAKE вызывает экспорт DLL_ANY который в свою очередь обращается к экспорту DLL_FAKE, который снова обращается к экспорту DLL_ANY. Вызов RtlHeapAlloc, когда PEB HOOKING [T.1] выполнен через NTDLL.DLL и IAT kernel32.dll был изменён: Пример: [ proceso ] | | CALL RtlHeapAlloc CALL LoadLibrary +-------------------> [DLL_FAKE ntdll.dll] ------------------+ 0 ^ 1 | | CALL RtlInitUnicodeString v +--------------------------- [DLL_ANY kernel32.dll] 2 Вызов RtlHeapAlloc, когда PEB HOOKING [T.1] выполнен через NTDLL.DLL и IAT [R.3] kernel32.dll не был изменен: [ proceso ]<----------------+ | 4 | | CALL RtlHeapAlloc | CALL LoadLibrary +-------------------> [ DLL_FAKE ntdll.dll] ------------------+ 0 ^ 1 | +------------------+ | | 3 | | CALL RtlInitUnicodeString v [DLL_REAL old_nt.dll] <--------------------------- [DLL_ANY kernel32.dll] 2 Примечание: Схема была упрощенна, исключив другие вызовы DLL_FAKE. Нормальный вызов LoadLibrary из процесса (без PEB HOOKING [T.1]): CALL IAT[Nr_LoadLibrary] +--------------------------------+ [process] -------------------------+ | IAT | ^ 0 | |--------------------------------| | | | LocalAlloc 1 (Nr_LocalAlloc) | | +-----------------------+ +->| LoadLibrary 2 (Nr_LoadLibrary) |-+ | | DLL_REAL kernel32.dll | | .... | | | |-----------------------| +--------------------------------+ | | | ... | 1 | | | LoadLibrary: | <--------------------------------------+ | 2 | PUSH EBP | | | MOV EBP, ESP | | | ... | | | POP EBP | +----| RET | | ... | +-----------------------+ Вызов проходит нормально без захода в DLL_REAL. Вызов LoadLibrary в процессе с PEB HOOKING [T.1]: CALL IAT[Nr_LoadLibrary] +--------------------------------+ [process] -------------------------+ | IAT | ^ 0 | |--------------------------------| | | | LocalAlloc 1 (Nr_LocalAlloc) | | +-------------------------+ +->| LoadLibrary 2 (Nr_LoadLibrary) |-+ | | DLL_FAKE kernel32.dll | | .... | | | |-------------------------| +--------------------------------+ | 4 | | ... | 1 | | | Own_LoadLibrary: | <--------------------------------------+ | | PUSH EBP | | | MOV EBP, ESP | +-----------------------------+ | | // Own functions... | 2 | DLL_REAL old_k32.dll | | | CALL IAT[Nr_LoadLibrary]|----+ |-----------------------------| | | POP EBP |<-+ | | ... | +--| RET | | +->| LoadLibrary: | | ... | | | PUSH EBP | +-------------------------+ | | MOV EBP, ESP | | | ... | 3 | | POP EBP | | | RET |--+ | | ... | | | +-----------------------------+ | +-------------------------------------+ Рассмотрев схему можно увидеть, что вызов проходит сначало через DLL_FAKE. Затем DLL_FAKE вызывает оригинальную LoadLibrary (DLL_REAL). ------[ 3.5 - Начало выполнения Как только предыдущие шаги выполнены, настал момент для началa выполнения процесса и слежения за его работоспособностью. ------[ 3.6 - API для работы с модулями API - LoadLibrary, GetModuleHandle, EnumProcessModules [R.12] ... используют поле LoaderData из PEB [T.1]. Это означает, что каждый раз, они вызывают что-то из DLL_REAL, которая вызывает что-то из DLL_FAKE, например: PEB HOOKING [T.1] был выполнен для USER32.DLL: - DLL_FAKE - Name in memory: USER32.DLL - BaseAddress: 00435622 - DLL_REAL - Name in memory: OLD_U32.DLL - BaseAddress: 77D10000 Процесс пытается получить базу USER32.DLL: - HMODULE user32 = GetModuleHandle( "user32.dll" ); После выполнения GetModuleHandle [R.12] в переменной user32 будет: 00435622 (BaseAddress из DLL_FAKE). Если процесс выполнен позже GetProcAddress [R.12] на некоторые функции экспорта USER32.DLL, они получат функции из DLL_FAKE. Блогадоря PEB HOOKING [T.1] больше нет необходимости изменять API, которые работают с модулями, так чтоб они использовали DLL_FAKE. ------[ 3.7 - Новая разработка: DLL MINIFILTER DLL MINIFILTER это название, которые мы дали способности, вызывать экспорт проходя через несколько DLL_FAKE. Одной из самых важных особностей метода является, ограничение или расширение функциональных возможностей к запросу на экспорт. Когда PEB HOOKING [T.1] выполнен с DLL_FAKE, то термин DLL_REAL для новых DLL_FAKE становится предыдущий DLL_FAKE. Поток пойдёт по форме последней DLL_FAKE, над которым взял контроль PEB HOOKING [T.1] по отношению к DLL_REAL, в случаи если все DLL_FAKEs приводят к оригинальному экспорту. Поток запроса процесса, с PEB HOOKING [T.1], только с одним DLL_FAKE: 0 1 [proceso] --> [DLL_FAKE] --> [DLL_REAL] ^ | | 2 | +----------------------------+ Поток запроса процесса, с PEB HOOKING [T.1], с тремя DLL_FAKEs: 0 1 2 3 [proceso] --> [DLL_FAKE 3] --> [DLL_FAKE 2] --> [DLL_FAKE 1] --> [DLL_REAL] ^ | | 4 | +---------------------------------------------------------------+ В предыдущем примере все DLL_FAKEs получают контроль соответствующий DLL_REAL. ------[ 3.8 - Частые проблемы На данный момент при реализации PEB HOOKING [T.1] выявлены, следующие проблемы: +-------------------------------------------------------------------------+ | Проблема | Возможные решения | |-------------------------------+-----------------------------------------| | - PEB HOOKING [T.1] fails | - Проверьте, могут ли необходимые поля | | | PEB [T.1] обмениваться. | | | - Проверьте, есть ли доступ | | | для изменения в IATs [R.3] | |-------------------------------+-----------------------------------------| | - Выполнение процесса не | - Проверьте корректность PEB [R.1] | | происходит | - Проверьте значения IATs [R.3] | | | модуля во всех процессах | | | - Проверьте были ли восстановлены | | | изменения в памяти PEB HOOKING [T.1] | +-------------------------------------------------------------------------+ ------[ 4.- phook phook способен реализовать PEB HOOKING [T.1] (и кое что ещё). phook это проект из различных модулей: - InjectorDLL: Создаёт приостановленный процесс и внедряет в него DLL. - Console Control: Внедрённая DLL позволяет выполнит PEB HOOKING [T.1]. и другие задачи в интерактивном режиме посредством команд консоли через sockets. - CreateExp: Программа создающая из DLL_REAL код, нужный для DLL_FAKE. - ph_ker32.dll: DLL_FAKE из kernel32.dll. ph_ker32.dll смотрит за доступом к API: CreateFileA and CreateFileW [R.14]. ------[ 4.1 - InjectorDLL Программа создаёт приостановленный процесс и внедряет в него DLL. Для внедрения DLL C:\console.dll в процесс C:\poc.exe: - Тип процесса: - CONSOLE: - InjectorDLL.exe C:\console.dll -c C:\poc.exe - GUI: - InjectorDLL.exe C:\console.dll -g C:\poc.exe - Неизвестный тип: - InjectorDLL.exe C:\console.dll -u C:\poc.exe InjectorDLL, с параметром -u, пытается обнаружить GUI или Console чтобы знать как создавать приостановленный поток (см пунтк 2.3). Этот метод создаёт процесс при помощи API CreateProcess и флага CREATE_SUSPENDED [R.6]. Потом вызывает WaitForInputIdle, если это не приносит результата то это консольный процесс, иначе GUI. ------[ CODE CreateProcess ( program_name , NULL , NULL , NULL , FALSE , CREATE_SUSPENDED | CREATE_NEW_CONSOLE , NULL , NULL , pstart_inf , ppro_inf ) // Необходимо проверить тип созданного процесса if ( WaitForInputIdle( ppro_inf->hProcess, 0 ) == WAIT_FAILED ) // "Console процесс" else // "GUI процесс" ------[ END CODE Если известен тип процесса мы знаем как его правельно остановить (см. пункт 2.3). Примечание: метод не всегда работает, например если "Console процесс" будет опознан как "GUI процесс". Код который загружает DLL помещён в структуру под названием LOADER_DLL_s (см. пункт 2.3). LOADER_DLL_s состоит из команд на ассемблере и всеми необходимыми данными. В созданном процессе необходимо описать структуру LOADER_DLL_s и объявить CreateRemoteThread, как точку запуска структуры. Она будет выполняться в коде LOADER_DLL_s. Как только DLL загружена и поток приостановлен, LOADER_DLL_s начинает выполнение и устанавливает флаг для "опознания". ------[ CODE typedef struct LOADER_DLL_s { /* - CODE ------------------------------------------------------ */ PUSH_ASM_t push_name_dll; /* PUSH "DLL_INJECT.DLL"*/ CALL_ASM_t call_load_library; /* CALL LoadLibraryA */ CALL_ASM_t call_get_current_thread; /* CALL GetCurrentThread*/ INC_BYTE_MEM_t inc_flag; /* INC [FLAG] */ char PUSH_EAX; /* PUSH EAX */ CALL_ASM_t call_suspendthread; /* CALL SuspendThread */ /* - DATA ------------------------------------------------------ */ char name_dll[MAX_PATH]; /* DLL_INJECT.DLL'\0' */ char flag; /* [FLAG] */ } LOADER_DLL_t; ------[ END CODE ------[ 4.2 - Консоль управления Консолью управления является DLL, которая внедрена в процессе, в котором вы хотели бы реализовать PEB HOOKING [T.1]. Это позволяет сделать PEB HOOKING [T.1] и другие задачи в интерактивном режиме с помощью команд консоли через sockets. Через прослушиваемый порт, в файл C:\ph_listen_ports.log записывается, PID - PORT. Например процесс с PID 2456, прослушивать на 1234 порт: 2456 - 1234. На данный момент поддерживаются следующие команды: help - Показать справку exit - Закрыть и выгрузить консоль suspend - Приостановить выполнение программы resume - Возобновить выполнение программы showmodules - Показать список модулей load [param1] - Загрузить в память библиотеку указанную в [param1] unload [param1] - Выгрузить из памяти библиотеку указанную в [param1] pebhook [param1] [param2] - Реализовать PEB HOOKING [T.1] над dll [param1]: Имя оригинальной dll [param2]: путь до DLL_FAKE Эти команды легки для понимания, но мы обьясним как работают "showmodules", "pebhook" и "suspend". Команда "showmodules" выполняет поиск по PEB [R.1] из загружаемых модулей, без использования API. pebhook которая реализовывает весь процесс PEB HOOKING (см. пункт 3). Если требуется выполнить PEB HOOKING [T.1] для kernel32.dll , используйте DLL_FAKE "C:\phook\bin\windows_xp_sp2\ph_ker32.dll", для ОС Windows XP SP2, требуется только отправить команду: - pebhook kernel32.dll c:\phook\bin\windows_xp_sp2\ph_ker32.dll Команда "suspend" способна приостановить выполнение главного потока процесса. TID основного потока получен, просматривая THREADENTRY32 [R.13] этой системы, можно достигнуть первого из процесса: ------[ CODE BOOL GetMainThreadId( DWORD * thread_id ) { HANDLE hThreadSnap; THREADENTRY32 th32; BOOL return_function; DWORD process_id; process_id = GetCurrentProcessId(); hThreadSnap = INVALID_HANDLE_VALUE; return_function = FALSE; hThreadSnap = \ CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, process_id ); if( hThreadSnap == INVALID_HANDLE_VALUE ) { ShowGetLastErrorString ( " GetMainThreadId() - CreateToolhelp32Snapshot()" ); return FALSE; } th32.dwSize = sizeof( THREADENTRY32 ); if( !Thread32First( hThreadSnap, & th32 ) ) ShowGetLastErrorString( "GetMainThreadId() - Thread32First()"); do { if ( th32.th32OwnerProcessID == process_id ) { * thread_id = th32.th32ThreadID; return_function = TRUE; } } while ( Thread32Next( hThreadSnap, & th32 ) && return_function != TRUE ); CloseHandle( hThreadSnap ); return return_function; } ------[ END CODE ------[ 4.3 - CreateExp CreateExp это программа создает исходный код, необходимый для реализации DLL_FAKE из a DLL_REAL. На данный момент она способна создавать .c и .def, для использования с mingw. Для создания DLL_FAKE для kernel32.dll необходимо выполнить: - CreateExp C:\WINDOWS\SYSTEM32\KERNEL32.DLL C:\ph_ker32 После успешного выполнения создадутся C:\ph_ker32.c и C:\ph_ker32.def. ph_ker32.c содержит в себе экспорт из kernel32.dll и автоматически jumps для оригиналов. ph_ker32.def содержит псевдонимы и имена из экспорта kernel32.dll. По умолчанию экспорт из DLL_FAKE приведёт к экспорту из DLL_REAL. ------[ 4.3.1 - Forwarder DLL CreateExp преобразовывает Forwarder DLL [R.3] в экспорт PEB HOOKING таким образом функция Forwarder может быть создана. Пример: kernel32.dll имеет Forwarder HeapAlloc который идет в экспорте RtlAllocateHeap of NTDL.DLL. Когда модуль импортирует HeapAlloc из kernel32.dll, загрузчик win32 автоматически помещает адрес экспорта NTDLL.DLL и никогда не проходит через kernel32.dll: CALL HeapAlloc [proceso] ------------------> [NTDLL.DLL] ^ 0 | +-------------------------------+ 1 Если DLL_FAKE из kernel32.dll создается с CreateExp, то поток будет: CALL HeapAlloc (DLL_FAKE) [proceso] ------------------> [KERNEL32.DLL] --------> [NTDLL.DLL] ^ 0 1 | +-----------------------------------------------------+ 2 В такой форме мы можем осуществить хук HeapAlloc (kernel32.dll). ------[ 4.4 - ph_ker32.dll ph_ker32.dll была создана для реализации PEB HOOKING [T.1] из kernel32.dll; Наблюдает за APIs "CreateFileA" и "CreateFileW" [R.14], и когда их вызывают, их ( или любые другие ) перенапраляют на оригинальные. Чтобы ослаблять прыжок к API, бал создан макрос JMP, он должно передать название DLL и оригинальный экспорт (см. пункт 4.4.2). ph_ker32.c созданный с CreateExp (JMP макрос был пропущен): ------[ CODE #define FAKE_LIB "ph_ker32.dll" DLLEXPORT void _ActivateActCtx ( void ) { JMP( FAKE_LIB, 1 ); } DLLEXPORT void _AddAtomA ( void ) { JMP( FAKE_LIB, 2 ); } DLLEXPORT void _AddAtomW ( void ) { JMP( FAKE_LIB, 3 ); } DLLEXPORT void _AddConsoleAliasA ( void ) { JMP( FAKE_LIB, 4 ); } .... ------[ END CODE Необходимо помнить, что после выполнения PEB HOOKING [T.1], kernel32.dll будет называться ph_ker32.dll, поэтому ph_ker32.dll обозначен как константа FAKE_LIB. ph_ker32.def созданный с CreateExp: ------[ CODE LIBRARY default EXPORTS ActivateActCtx=_ActivateActCtx @ 1 AddAtomA=_AddAtomA @ 2 AddAtomW=_AddAtomW @ 3 ... ------[ END CODE Причинами ясности выполнение APIs CreateFileA и CreateFileW [R.14] были помещены в файл owns.c. Когда сделан запрос к CreateFileA, и к CreateFileW [R.14] то записывается параметр lpFileName в файле C:\CreateFile.log owns.c: ------[ CODE #define FILE_LOG C:\CreateFile.log DLLEXPORT HANDLE _stdcall _CreateFileW ( LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDistribution, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile ) { char asc_str[MAX_PATH]; if ( UnicodeToANSI( (WCHAR *) lpFileName, asc_str ) == 0 ) CreateFileLogger( asc_str ); return CreateFileW( lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDistribution, dwFlagsAndAttributes, hTemplateFile ); } DLLEXPORT HANDLE _stdcall _CreateFileA ( LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDistribution, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile ) { char asc_str[MAX_PATH]; CreateFileLogger( lpFileName ); return CreateFileA( lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDistribution, dwFlagsAndAttributes, hTemplateFile ); } static void CreateFileLogger( const char * file_to_log ) { HANDLE file; DWORD chars; file = \ CreateFileA ( FILE_LOG , GENERIC_WRITE | GENERIC_READ , 0 , NULL , OPEN_ALWAYS , 0 , NULL ); if ( file != INVALID_HANDLE_VALUE ) { if ( SetFilePointer( file, 0, NULL, FILE_END ) != -1 ) { WriteFile ( file, file_to_log, strlen( file_to_log ), &chars, NULL ); WriteFile( file, "\x0D\x0A", 2, &chars, NULL ); } CloseHandle( file ); } } ------[ END CODE ------[ 4.4.1 - Проблемы стэка Когда требуется непосредственно передать контроль к API, необходимо передать его неповрежденный стек оригиналу API. Нужно в mingw выбрать compilator-fomit-frame-pointer [R.15] и JMP (ASM) к оригиналу API. Функции, которые были осуществлены, должны быть помещены образец и должны иметь тип _stdcall. Функции типа _stdcall имеют различный синтаксис в файле .def: - Name_exportation=Alias@arguments * 4 @ Ordinal Пример файла .def с APIs типа _stdcall CreateFileA и CreateFileW [R.14] (оба имеют семь аргументов): ------[ CODE LIBRARY ph_ker32 EXPORTS ; Name Exp | Alias | No Args * 4 | Ordinal Windows XP SP2 CreateFileW=_CreateFileW@28 @ 83 CreateFileA=_CreateFileA@28 @ 80 ------[ END CODE Функции типа _stdcall не должны быть скомпилированы с опцией с-fomit-frame-pointer [R.15]. ------[ 4.4.2 - Проблемы регистра Не только необходимо передать стек с неповреждённым экспортом, экспортирование должно быть с целостностью регистраторов. Перед прохождением контроля к оригинальному экспортированию, необходимо чтобы регистры не были повреждены, это достигается использованием в коде инструкции PUSHAD и POPAD: [PUSHAD] [ CODE NEEDED TO JUMP TO THE EXPORTATION ] [POPAD] Пример экспортирования с использованием регистров _chkstk в NTDLL.DLL: _chkstk in NTDLL.DLL (WINDOWS XP SP2): ------[ CODE 7C911A09 >/$ 3D 00100000 CMP EAX,1000 7C911A0E |. 73 0E JNB SHORT ntdll.7C911A1E 7C911A10 |. F7D8 NEG EAX 7C911A12 |. 03C4 ADD EAX,ESP 7C911A14 |. 83C0 04 ADD EAX,4 7C911A17 |. 8500 TEST DWORD PTR DS:[EAX],EAX 7C911A19 |. 94 XCHG EAX,ESP 7C911A1A |. 8B00 MOV EAX,DWORD PTR DS:[EAX] 7C911A1C |. 50 PUSH EAX 7C911A1D |. C3 RETN 7C911A1E |> 51 PUSH ECX 7C911A1F |. 8D4C24 08 LEA ECX,DWORD PTR SS:[ESP+8] 7C911A23 |> 81E9 00100000 /SUB ECX,1000 7C911A29 |. 2D 00100000 |SUB EAX,1000 7C911A2E |. 8501 |TEST DWORD PTR DS:[ECX],EAX 7C911A30 |. 3D 00100000 |CMP EAX,1000 7C911A35 |.^73 EC \JNB SHORT ntdll.7C911A23 7C911A37 |. 2BC8 SUB ECX,EAX 7C911A39 |. 8BC4 MOV EAX,ESP 7C911A3B |. 8501 TEST DWORD PTR DS:[ECX],EAX 7C911A3D |. 8BE1 MOV ESP,ECX 7C911A3F |. 8B08 MOV ECX,DWORD PTR DS:[EAX] 7C911A41 |. 8B40 04 MOV EAX,DWORD PTR DS:[EAX+4] 7C911A44 |. 50 PUSH EAX 7C911A45 \. C3 RETN ------[ END CODE ------[ 4.4.3 - JMP макрос Макрос JMP необходим так, как не всегда весь DLL (файл .h) имеются в его header'e. С макросом JMP адрес экспорта получается с GetProcAddress [R.12] во времени выполнения. ------[ CODE unsigned long tmp; #define JMP( lib, func ) \ asm ( "pushad" ); \ asm \ ( \ " push edx \n" \ " push %1 \n" \ " call eax \n" \ " pop edx \n" \ " push %2 \n" \ " push eax \n" \ " call edx \n" \ " mov %4, eax \n" \ " popad \n" \ \ : : \ "a" (GetModuleHandle) , \ "g" (lib) , \ "g" (func) , \ "d" (GetProcAddress) , \ "g" (tmp) \ ); \ asm ( "jmp %0" : : "g" (tmp) ); ------[ END CODE Это код для mingw [R.16], компилировать с опцией -masm=intel. ------[ 4.4.4 - Версии Мы включили в phook различные версии ph_ker32 для систем: - Windows XP SP2 v5.1.2600 - Windows Server 2003 R2 v5.2.3790 - Windows Vista v6.0.6000 Исходный код в ph_ker32/SO и бинарники в bin/OS. ------[ 4.5 - Использование phook Далее рассмотрено что можно делать с PEB HOOKING [T.1] для kernel32.dll к ph_ker32.dll, программа poc.exe была выбрана для примера (лежит в папке bin\ of phook). Шаги для следования: 1.- Запустите InjectorDLL с указанием программы для инжекта DLL, для для этого введите в консоли: - InjectorDLL.exe console.dll -u poc.exe Процесс будет в приостановленном виде и будет возможность для прослушки порта, записанном в файле C:\ph_listen_ports.log C:\phook\bin>InjectorDll.exe console.dll -u poc.exe ________________________________________________________________ | InjectorDLL v1.0 | | | | Juan Carlos Montes eunimedes@hotmail.com | | David Reguera Garcia Dreg@fr33project.org / Dreg@7a69ezine.org | | -------------------------------------------------------------- | | http://www.fr33project.org | |________________________________________________________________| Showing injection data ..... Program to inject : poc.exe Library to inject: console.dll [OK] - CONSOLE. [OK] - Create process: [INFO] PID: 0x0960 [INFO] P. HANDLE: 0x000007B8 [INFO] TID: 0x0AE0 [INFO] T. HANDLE: 0x000007B0 [INFO] - Injecting DLL... [OK] - Allocate memory in the extern process. [INFO] - Address reserved on the other process: 0x00240000 [INFO] - Space requested: 306 [OK] - Creating structure for the dll load. [OK] - Writing structure for the dll load. [OK] - Creating remote thread. [INFO] - Thread created with TID: 0x0B28 [INFO] - Attempt: 1 [INFO] - Thread has entered suspension mode. [OK] - Injection thread ended. [OK] - Memory in remote thread freed. [OK] - DLL injected. [OK] - Injection ended. 2.- Необходимо соединиться с клиентом через netcat к открытому порту, в нашем случаи: 1234. C:\>nc 127.0.0.1 1234 ________________________________________________________________ | Phook Prompt v1.0 | | Juan Carlos Montes eunimedes@hotmail.com | | David Reguera Garcia Dreg@fr33project.org / Dreg@7a69ezine.org | | -------------------------------------------------------------- | | http://www.fr33project.org | |________________________________________________________________| ph > help _________________________________________________________________ | Phook Prompt v1.0 | | | | Command list: | | --------------------------------------------------------------- | | help - Shows this screen | | exit - Closes and unloads the console | | suspend - Pauses the programs execution | | resume - Resumes the programs execution | | showmodules - Shows the modules list | | load [param1] - Loads in memory the library | | especified in [param1] | | unload [param1] - Unloads a librery in memory | | especified in [param1] | | pebhook [param1] [param2] - Performs PEB Hook over a dll | | [param1]: Name of the original dll | | [param2]: Path to the DLL hook | |_________________________________________________________________| 3.- PEB HOOKING [T.1] для kernel32.dll осуществляется с ph_ker32.dll: ph > pebhook kernel32.dll C:\phook\bin\windows_xp_sp2\ph_ker32.dll 4.- Команда resume продолжает выполнение процесса. ph > resume ph > C:\phook\bin> 5.- poc.exe creates the files in C:\ - file - file2 - file3 6.- ph_ker32.dll регистрирует успешные API вызовы CreateFileA и CreateFileW [R.14] в файле C:\CreateFile.log 7.- C:\>more CreateFile.log C:\file1 C:\file2 C:\file3 ------[ 4.5.1 - DLL MINIFILTER phook позволяет также реализовать и DLL MINIFILTER (см. пункт 3.7). Он только должен выполнить PEB HOOKING [T.1], с помощью команды pebhook, с необходимым именем DLL_FAKE, тоесть той что была DLL_REAL. Предположим что у нас есть две DLL_FAKE: - ph_ker32_1.dll: Следит за доступом к API CreateFile [R.14]. - ph_ker32_2.dll: Следит за доступом к API ReadFile [R.17]. Выполнения DLL MINIFILTER очень просто: C:\>nc 127.0.0.1 1234 ________________________________________________________________ | Phook Prompt v1.0 | | Juan Carlos Montes eunimedes@hotmail.com | | David Reguera Garcia Dreg@fr33project.org / Dreg@7a69ezine.org | | -------------------------------------------------------------- | | http://www.fr33project.org | |________________________________________________________________| ph > pebhook kernel32.dll C:\phook\bin\windows_xp_sp2\ph_ker32_1.dll ph > pebhook kernel32.dll C:\phook\bin\windows_xp_sp2\ph_ker32_2.dll Поступает вызов от процесса к kernel32.dll: 0 1 2 [proceso] --> [ph_ker32_2.dll] --> [ph_ker32_2.dll] -> [kernel32.dll] ^ | | 3 | +------------------------------------------------------+ ------[ 4.6 - Частые проблемы Помимо проблем описанных в section 3.8, есть и другие: +------------------------------------------------------------------------+ | Problem | Possible/s Solution/s | |------------------------------+-----------------------------------------| | - DLL_FAKE ошибка компиляции | - Проверьте, что функции, которые | | | выходят непосредственно на DLL_REAL | | | не повторялись, и реализуются. | | | - Проверьте, что выполнены функций | | | (которые должны быть _stdcall типа) | | | хорошо определено в .def файле | | | (см. пункт 4.4.1). | |------------------------------+-----------------------------------------| | - Выполнение процесса | - Проверьте, что функции, которые | | не происходит | выходят непосредственно на DLL_REAL | | | были составлены с помощью опции | | | -fomit-frame-pointer (см. пункт | | | 4.4.1). | | | - Проверьте, что выполнены функции | | | имеют _stdcall типа. | | | - Проверьте, что DLL_FAKE были созданы | | | от DLL_REAL, а не от другой. | | | - Проверьте, если InjectorDLL правильно | | | обнаружен реальный тип процесса | | | (GUI или CONSOLE). | |------------------------------+-----------------------------------------| | - Не удалось подключиться | - Проверьте что порт 1234 открыт | | к консоли | перед вызовом PEB HOOKING [T.1]. | | | - Проверьте что фаервол не блокирует... | | | - Убедитесь в том, что полный путь | | | console.dll было указано | | | в InjectorDLL. | |------------------------------+-----------------------------------------| | - InjectorDLL не работает | - Проверьте что есть привилегии для | | | внедрения DLL (CreateRemoteThread..) | | | | | | - Проверьте не блокирует ли антивирус.. | |------------------------------+-----------------------------------------| | - CreateExp не работает |- Проверьте DLL_REAL на правильность | | | PE32 и EXPORT DIRECTORY [R.3]. | +------------------------------------------------------------------------+ Некоторые другие проблемы могут возникнуть из-за проектирования или других несвязанных с phook ошибок программиста. ------[ 5.- Что делаем На данный момент мы работаем над: - Реализацией PEB HOOKING [T.1] до выполнения: - TLS Table и DLLMain [R.3]. - Создать отладочные файлы конфигурации и для консоли. - Правила для восстановления IATs [R.4]. - Список прослушивающих портов. - ... - Улучшить InjectorDLL: - Автоматическое распознавание "GUI процессов" и "Console процессов". ------[ 6.- Тестирование Тестирование phook было произведено в различных версиях Windows и программах. Windows: - Windows XP SP2 v5.1.2600 - Windows Server 2003 R2 v5.2.3790 - Windows Vista v6.0.6000 Теоретически должно работать и в Windows 2000, но мы не можем подтвердить это. Программы: - Microsoft Word 10.0.2627.0 - Regedit 5.1.2600.2180 - Notepad 5.1.2600.2180 - Calc 5.1.2600.0 - CMD 5.1.2600.2180 - piathook 1.4 - pebtry Beta 5 - pe32analyzer Beta 2 ------[ 7.- Преимущества и возможности Главное преимущества PEB HOOKING перед другими в том что, он применяется только 1 раз.К моменту когда выполнен хук длл, любой загружаемый модуль автоматически получает в своей IAT экспорт DLL_FAKE. Остальные модули должны применять хук каждый раз когда модуль загружается. Другие преимущества PEB HOOKING [T.1]: - Поиск PEB (используя BaseDllName) чтоб найти DLL_REAL, будет находится в DLL_FAKE. - PEB HOOKING является более стабильным для ОС чем использование ring0. - Некоторые упаковщики не обнаруживают PEB HOOKING [T.1] так как это не документированный способ. - Нет необходимости менять поведение работы API с модулями. Когда модуль обращается к DLL_REAL, то он автоматически обращается к DLL_FAKE. - Возможность реализовать DLL MINIFILTER (см. пункт 3.7). - PEB HOOKING может экспортировать Forwarder [R.3] не делая PEB HOOKING к Forwarder DLL. Спектр возможностей PEB HOOKING [T.1] и phook достаточно большой, вот несколько примеров применения: - Мониторинг/виртуализация доступа процесса к реестру: - POC [R.18]: 1.- Запустите CreateExp (см. пункт 4.3) с "advapi32.dll". 2.- Взависимости от того, что вы хотите сделать необходимо наблюдать/виртуализовать следующие API: - RegCloseKey - RegCreateKeyA/RegCreateKeyW - RegCreateKeyExA/RegCreateKeyExW - RegDeleteKeyA/RegDeleteKeyW - RegLoadKeyA/RegLoadKeyW - RegOpenKeyA/RegOpenKeyW - RegOpenKeyExA/RegOpenKeyExW - RegQueryValueA/RegQueryValueW - RegQueryValueExA/RegQueryValueExW - RegReplaceKeyA/RegReplaceKeyW - RegRestoreKeyA/RegRestoreKeyW - RegSaveKeyA/RegSaveKeyW - RegSaveKeyExA/RegSaveKeyExW - RegSetValueA/RegSetValueW - RegSetValueExA/RegSetValueExW - RegUnLoadKeyA/RegUnLoadKeyW ... - Наблюдение/виртуализация подключений. - POC [R.20]: 1.- Запустите CreateExp (см. пункт 4.3) с "ws2_32.dll". 2.- Взависимости от того, что вы хотите сделать необходимо наблюдать/виртуализовать следующие API: - accept - bind - closesocket - connect - listen - recv - recvfrom - send - sendto - socket - WSAAccept - WSAConnect - WSARecv - WSARecvFrom - WSASend - WSASendTo - WSASocketA/W ... - Syscall Proxy of files: - POC [R.19]: 1.- Запустите CreateExp (см. пункт 4.3) с "kernel32.dll". 2.- Взависимоти от того, что вы хотите сделать необходимо перенаправлять следующие API: - CreateFileA/CreateFileW - CreateFileExA/CreateFileExW - ReadFile - ReadFileEx - WriteFile - WriteFileEx ... - ... и конечно ваши идеи ;-) ------[ 8.- Заключение Если необходимо выполнить hook на API/экспорта, можно использовать любые методы. Но если необходимо наблюдать или виртуализировать доступ к различным API/экспорту, то с phook это намного проще осуществить. Кроме того, это - метод, ориентируемый к обратному проектированию программного обеспечения и malware систем защиты, это как альтернативные методы поиска экспорта и устранения хуков. ------[ 9.- Благодарности Recommendations for the paper: - phrack staff - Tarako Translation to English of the chains of phook: - Southern - LogicMan - XENMAX Translations of the paper to English: - BETA : Ana Hijosa - BETA 2: delcoyote - ACTUAL: LogicMan Virii scene: - GriYo, zert, Slow, pluf, xezaw, sha0 ... Reversing scene: - pOpE, JKD, ilo, Ripe, int27h, at4r, uri, numitor, vikt0ry, kania, remains, S-P-A-R-K ... Other scene: - sync, ryden, xenmax, ozone/membrive, \^snake^\, topo, fixgrain, ia64, overdrive, success, scorpionn, oyzzo, simkin, !dSR ... ALL vx.7a69ezine.org and 7a69ezine.org people ;-) And specially thanks to YJesus - http://www.security-projects.com ------[ 10.- Похожие работ [T.1] .- Нам неизвестно о каких-то других работах с использованием phook, но есть статья с упоминанием PEB HOOKING написанная Deroko: "PEB DLL Hooking Novel method to Hook DLLs". Статья была опубликованна в ARTeam-Ezine выпуск 2. - http://www.arteam.accessroot.com/ezine/ … load1.php? file=ARTeam.eZine.Number2.rar ------[ 11.- Ссылки [R.1] .- Структура PEB:: - http://undocumented.ntinternals.net/ [R.2] .- Gaining important datas from PEB under NT boxes: - http://vx.netlux.org/29a/29a-6/29a-6.224 [R.3] .- Visual Studio, Microsoft Portable Executable and Common Object File Format Specification. Revision 8.0 - May 16, 2006: - http://www.microsoft.com/whdc/system/platform/firmware/ PECOFF.mspx [R.4] .- What Goes On Inside Windows 2000: Solving the Mysteries of the Loader: - http://msdn.microsoft.com/msdnmag/issues/02/03/Loader/ [R.5] .- winnt.h (DEV-CPP): - http://www.bloodshed.net/devcpp.html [R.6] - CreateProcess: - http://msdn2.microsoft.com/en-us/library/ms682425(vs.80).aspx [R.7] - Three Ways to Inject Your Code into Another Process: - http://www.codeproject.com/threads/winspy.asp [R.8] - Import address table hooks: - http://www.securityfocus.com/infocus/1850 [R.9] - Code overwriting: - http://www.codeproject.com/system/hooksys.asp [R.10] - Hooks: - http://msdn2.microsoft.com/en-us/library/ms632589.aspx [R.11] - System Call Optimization with the SYSENTER Instruction: - http://blog.donews.com/zwell/archive/2005/03/13/300440.aspx [R.12] - Run-Time Dynamic Linking - http://msdn2.microsoft.com/en-us/library/ms685090.aspx [R.13] - Thread Walking - http://msdn2.microsoft.com/en-us/library/ms686780.aspx [R.14] - CreateFile - http://msdn2.microsoft.com/en-us/library/aa363858.aspx [R.15] - MAN GCC (-fomit-frame-pointer): - http://www.astro.uni-bonn.de/~webstw/cm/gnu/gcc/gcc.1.html [R.16] - MINGW: - http://www.mingw.org/ [R.17] - ReadFile: - http://msdn2.microsoft.com/en-us/library/aa365467.aspx [R.18] - Registry Functions: - http://msdn2.microsoft.com/en-us/library/ms724875.aspx [R.19] - File Management Functions: - http://msdn2.microsoft.com/en-us/library/aa364232.aspx [R.20] - Winsock Functions: - http://msdn2.microsoft.com/en-us/library/ms741394.aspx [R.20] - MSDN LIBRARY: - http://msdn2.microsoft.com/en-us/library/ [R.21] - Iczelion's Win32 Assembly Homepage: - http://win32assembly.online.fr/ ------[ 12.- Исходный код Message-ID: MIME-Version: 1.0 Content-Description: "UU encode of phookt~1.gz by Wincode 2.7.3" Content-Type: application/X-gzip; name="phookt~1.gz" Content-Transfer-Encoding: X-uuencode Content-Disposition: attachment; filename="phookt~1.gz" begin 644 phookt~1.gz M'XL("-%*$T<``'!H;V]K+G1A<@#LW7M`5.6^-_#%@(J*@HJ&BCJ:%[PA=Q$0 M4!CO%^2BE5>$05`$9&8434M%2D+*KIIEBEI969IIW@OO6EIF:II66JDHE&9D M9"KO\_L^:WA^CK7//N_9^[SO'WN=/>WGG5_UEH#='+2L[.G]-#^K8/1 M:.S9LZ=1O(O!S^%='_'WZ^D7%!(4&!+24XP'^X>$&+5@[3_#OWN0^W]B1M:_ M\1CX;^S_8+\0/]K_/0,"_[/__S<&M?]3LK,LV9EFW]3,3.U?._RC_>\?'.`? M$!1BW_]!`7[^1C$2$!ADU/RT_PS_[F'H(XLU9_'N(E[5U9JV5<^CM?]ZF"M> M#=ML;ZAMJGNT[5:G(4?;)J9G6(PYN=F3>[V-.).F#7%RU>8-:-)?&U9;NR(6YKQ6NVU])T.HUEY? M$(-X>=#+OF!YF;!!+K<3EE\?-M3&R*41=31G>?1A.O&/_B[?U`F@:0OJ_..5 M3#=H__+!UVK.LXKW5Q_4%ZB]?274,$'\SSEOKFRT*,! M;53:,>+5Y;ZZ:-^)%@NY%#/XFU6F]C*H/7W;Y(B7JWB%_M5\S9G9*?HVFJNO M0_1]=7U]+=;DB=24B]A;BP5JB_?8>^L,KGJ=Q9J[PU!+TU:*&A?Q/LCIOCKM M/\._9$@JO#AJ9$)^A5O1'+?\:B?W!>^(L'!V>Y>BL1Y%0UT+Q[1W+71K7W:Q MD4@/B#*J>6&/?VG!3?<72@OV6$<7-=4FY&46'+>:BEIY")4W6,R'_'*77E_F M-B]R+BBU_EI]3%8CM)076SMJA9[MRY:*@]O_>"$^.NB"GJ',*K*":IN'O7E; M/_^;J+]>;*X1"KMIH6IVR*M_CT9DM-N]*Q MNKIZL5S(XNE:\_/E.R&2*]FBQ;*K0@97`L3Q38=TMZET*5]V1PQ\>'\*J?FI7OE M9$G;:NJWRWJJ%=/(^J%4OY=M7['_QEZ9)-;1/DZ3AAXTW:;&#IJJY%NE?+LN MWRKD6QF]%9GZG3_GMCZ544WU2S,UU1>T24R5A;'M/<3$XLU-S%F\N1:;RL2; MBS[)0M&XV!-H*5JU]"9KZ4D-\Z=IJ0DU;8$!TWK3M.EJVBEJVO)A17^U"$7W M+,(69]5,H6JF/6NFCH#<>#\>WHLM[DK5%.G5U*OK'WG11T[J(^I(Q18K,MVV M%^@?#!0?V#=E77W7E0>(92SVW(^FQ6<1!O99,_K,37Z6=%NTXNS22.S!(E,5 M:SD_+P*3E&&2CB(I2G(MBHYP.J;/2WU8E^90FE=H*A-;!$U0SV#4=_:>5OK. MKB@R>5+PO@Q07D'!C;O5U86F2C$QC?V(L>M%(DBZ7A3M&=[7T]J$ML5*M5$_ M]Z35JLS/\]1L;@=-Y[&#/Z#U&>M&I;2MJ(%HS+#46VP@Y_PY;JSX"5%AWQM) M8M8_BME8)A8EN0D6>\MM$R`_<>[K0;M97UAG++U8BL#[BJ^K8GU=3GG+XMA` MEV)Q#&CESQ>9O*C5>,]"#[$H<+S97C1XW5F[[4/W,*O*VGR/Z=IQE#ZK4 M27-.;9*=36B%3F/E.HG#AIV/(VJ*EK`B@R@J.^DI-HW8D',J]>+VJG@R*SYI MWZ!NV#77@0K:)*;SXM^B:*]PTVU;;01E]J!*#WZD0)/UX:;S5D/YD?PY99HU M(W_.CYHUI4A,$>U=:#I7E"0F_9'M5\2N[K9?_4"Y\::SXE M]S7:/S6*I<?% M\6K_I%(>*=CNQXK$_PBGQ=(7FDX<-!UQ4AVTR+#U*VUUQ`<\N7Y/HH6;3N@! M+=D1S3I#%N)@^Y-.PD/YB6(-+H5-YG6)3E3B3 M]Q2+QC27\G?TI9)7"%>'A;KH95\H=&%+U4*Y>5!O=;NFN_36\T=O55?;ST@W MO8NXTM()5\%\G[GWYLXBOZ=GOB[[9'4L7'??$ET[W%3A_O1&K%Q%X;'=YPU. MQ^S=EJU2935;H+(H-M`U/+:1Q_3@^S\=RZ:HV3AB"H.K/P1DZ$' M.I^_SYNZ4'Y_,VKK`E%1MJ>IV!P%/UZKKL9)O6NMT.WMY*VUZ(C<77CLUW=P M3OII=%M(>Z^LN!GZQ;+;SN*]X+28)'\7_5MMK8T]T$U,X.8A#T+74K%7J8$# M(]1]WLYFV/%7"@UB9+T'M;(5K="_FJUG$49IAZ_R0!]2).8B@PON,C!5TM@' M344#OM0%1!KDW9>H+RXHHV)3A9IJM!NMYGEJ75\L4:CW99A`KUO=5/_43WVJ MSVHAMM01>Q,%:U1C+F?%NJF9#6^`U$LV35M4'/N>Q9B"[I-HZ]@7@[:G?K.F M&MB%=?0N+#B'C4+_5MN:E=T43Y^]+XIM;JUWL&"EFKV'DWQWJQ8#&JV9<7XI M+KCV'6=%PY[W-LP:NW\9B_$9G;NRP7L7-.C^]C3>GMJ/+>1NR]^%CZQ]1#?A MC++NC<2..("M3&VK79$K-_V],[34HF/E/.9&_SK9&JD/#S2X9QX-10D6J-:5 M^N*N22W+L(;\$,II(C9,^6U1,,=^[^CSC^[T]9YH&ZY#UT6EWI5$BVN\^].7 M986SZ?;<4*.UOIV:S0]G1A=Q,R@O!JZT8OK=S-@FN`^-%GP9;UW_0GE&VMUU< MAZDA\<]ML8!TJ.D;:\!!TPG:!&D'3<>/N]#A5[OF\H,NPT!'WB`WVN9NN#FH M+"B=&E'P=?U]>4[D3_G1+7-FR:,%N7' M[2V\I5I`A:'\0_M'I]CZZLV]@FI7L:*1?[6B-]F*;FB$%=4G-,C9Z*M=/A.= MD79?9S38OKC7Q5U3M>TO9W*'S63P/3-97N^>F7CJ\1,R%L=RH>E(D>D(=O"\ MBH?D952L^/>T]U*T M_/;E=%BM4K&<'J*1LE\]])[OQ%TZQ>G?:O<%'^A3&ARFE%W,"7V^!S&M1WY5 MM=6JEJ:1!RTQS5]V9\=$;E]VO4JTI%IY%JUXWC\!S=B@S[B36%8UR3@YB0K& MRHN6^DH!V_$0'<(%J:)&OV42WU"(V[E"VC^CZXAO5B9,H,V8+@KL?3;=\.;4 MU0\E:V>^]?SBY5X.B5=[V>R.+5#>JUC,!JW4K`>?=&4+.2F-VR?=CDF]MM(Q M?%A\"[3XGD$^]][;*U(+<6+F>A_V1P.Z8;6UOOIU2L53G*B)#71 MOK^`9FN*YWDU>;58YG*/$OJ01MO(RY>]P1?U!C]6#4Z5#?;\NP;?N[?! M;QOP!LO[XVY-M=9&MN9'\1'52(8+CIY4.GK6V5NHHA;TAO`@CDWQNYHJ4$QU MSU4M/)I^+9ZK-9SOJ1_P^7_U4UP4#5V)6Y#LN_Z"^6XXB: MM"%;C@'BPHS-+2EE^,<>_4)%?P>'^ MH8J>SBNMX\1SD#SSJO)+VU,3K<6T8@,%%,D/](9+]=,\2LWK71'IWUA-$]VK M/&%CU>?%XG/,1\Z5YF8H?T)_>L37>'_9/ZI['MK196EUL;;4Y>:(MO'<+=[U M'?I07:PC6]`'Q,3ZAV==[=]TWM^L>UW[1M3/[,21-0M^@D[@4#['Q2-KYGC) MU7&.KVLU<\Q0<_0I<1F(MMM7%E5Y\Y3=`ZAY4;%_] M2F]S$Q,=HXDRZ<'%="+<5&ISI^\Q3,<*#6*V3O=-^[9]6JMK_IQ]3N)P/:1_ MWK]"TL\BT\_!>?7NDTZX8(V9R5U;(FTF<^ONPE#A^ZHD*<0922QWK ML#5C=;%E$;1=]O![#2]]"=5VI1_ZB$6J/B;Z'[&8-5/7%G>:A:9]8OG4'JON M4#DM+W/Q8DT?JCO\Z##NFGOO^&V'SZL?_U5[%#7`AR-%-'??H$L4=+%@;F9=+]<.>"TL*]UB:%-_6?GU5[+J>/!MMNBF,@ MNILX!MX6/X,9+3KJH@:+Q`?B)Y&'R^M%%WD6B#%JNK)\E_X#N(]Y^T;\:-`6 M@AGM<**=W$IDF&<'S--],?V\[_[YA?U7\]M]3_^ZS6,L_?RNW%,NA5CO(J?\ MW:Y.\^FW%N;]09_F7AVK[K=+YN+G?6.+!KA47RB\F;2=?K0M%MI]2VE^12KN M_9/6^I_5?P!8W31([-[M;43--B<-3U9BK>J4]W,Z/"BOX=S97=;VL576_52, MS;R1'QYAJU-X&E].;DL<(R:[2DT/D4\48O7FB6SK2O$/G9UESXG.:.L1,;;C M1]E9N=$/?\N_TG>4V!_JY\7S*H[0NC6@91<[W57_F>S>@Z:E?<10XB>:*;8M M/6AZE48/FE;26Z%I:TF0^$!\(RS3M3+=61**=)U,-\BTM"0"Z28YNJ\DFA;4 M=*@D%N]'2@;@_5C)$+R?<-]2*TXHK5`\+`>)[>0CMA.VH8O8NP6Q]'16$.Z$ M/C.".K\8L;JTW]T7/"S2VX4'BU"TS5U\*+Y'C'$I]<_+Q#8^&.,ZMWM>9DDT M_?C7F28N:AI+CO%!9Q'C6>(1+98AP:NHJ2>_[8U.AUWZ+%S098"88-#,R]B&A07I8JPD M",PDAH(YQ`C02HP&\XBQX&Q!?0O-U;?0`K6%%A87T%QP/'EB.U71=JJV]?4_ M+@[IUH7>[PE:TVXMC7%;GX-UU]6+Q;C\$"JO* M0D59K].%MVSOE[]?1H\NB]4PHO"".!MZT^U!KL>\*_2>7U?K3N_E5SKO%BX\ M7WBD2'P/[E)]ON9Z*'Y,<_^/;?5K?LEB6L#2:.KW[XK-RL=]:4^?$?\L5OWU M;(?^<:'#^*L.XVL MBAL>GVA,[--WB$D4RCHQI<6<:Z5*^KUC8_9TT5Z/4-? M;RW=G)FCY9@GTFZ_Y[@;9DX1FU!L:6.._0BC5;/8+#GFK%15%Y,]=6IR5JJ1 M?J4X.3,S>X:9CC^Q=6Q3S9HY+\/*VHP5.]"^/VF:E,QLB[!]T]!AE90UA?9R MBFQ5;DOC$+G/C=9L.ASDO,QB.5(RTC+$L>:#)?3OC./>7BP6)M>G[ M),0,'(B%]/?U$VV-_Q\.QGK&V<:_&>+0L\2)/BC':IS>P?(W9;.IB4&VY"QC M3'*N.#Z,0[.SK&:J-MNR,J::4\V6Z/1LZ]3DC$Q?<93\?1NQR=,S4HWQYDDV M*7X2>;4ZR^V;F3C#UDW#,YI)=Y5D:6F4+9 M1O?_T2#;N'](MUISPGKTF#%CAJ_#HOS-NHS_'PZSZ]7C_5N8,=F2,2DKF8X( M_2@TBN,N>6I&2C(=7FGB8*1^P3C1EI9FSJ7CXU]P;.#@^)\=&_J>_9\.U(B] MW\*5*\SXWQ_^!<>'/$#DIO[+H;LQ0735%J.5_GS#DI)K-F?]W9)03_MWC<2( MTTB<06)M]9Z#6C3;>UW6B-ZY_V4C<V(?W;Q-YK1@MN^*Q#HT,HF%^#?CG#S;5 MXXN6[IN3:D3?[#45]RQ)DKY+DC%_LYB_OE3_EB71+_4U)3H"QM(N-N>*4W^J MA:XAQ@'V^T"Q8.)/S_[I);$W'&;$128[C39MS1T>-?5/-Q*`VUMKNKA2H1%Q MX<+MZ;^N8Z2>4=T"TTQJ;ES#C!TLXK/^9NN09(L5)2)*%5$'\8K36?NK\M$=FC+")HV)@%NV;9%HTT4_2O=D]]=V'#.S;/R9F5&!`=].`[@'= M$P8-&=2]?^*`^.Y#Q4VZB$7-C,"`\9;TY%QS:HXUMWND)6.6V=B[MY'>L]-\ M1HE/30/&)PSH$V^*[:QUL(1UL(49T\1U5AQ4R1;Q?(!S=$('2R=Q0?#U[2'^ M-RDE!2_1E:1E3.J1$1@:TD/,I;N<2W?71*UVSQ6BA>B\5KI7BM%:]-XE4J7H=8_0GA\^)UG3+QW.`A7MW$*U2\ MAHC7&/'*%*^YXK54O-:*UT[Q.B9>Y\6K0KQNTW0V3?,2+Q_Q"A6O`>(U1KSL M0SJS57B!>"T6KZ7BM5*\UHG75O':)UY'Q.NT>/TH7M?%Z[9XN=)V%B_[8&3V MF_Z?[?//;!]W>E;%C8EINCG+JC6BB"&EI2)SF.XN`IE)N?DF%/I_B$3 MG_G19_'F%&HN2-IBMLI)8VA\5'*&M5]V[E!1GY&3*1L5VZT%?<8[=3%]&X?G MY@?M#^#X\T_Q-]CB-U0Z:"FTL/)Y'?-,MXK[)_&W\.*!P3H^67SCH/6R/[^+ M(4:SF&FZ`?9'?/P]K/AB@GK"/IK64^G^AN^XCQ1_1Q M7"-$.V.UO[FXB);7:_TRLO2&CVG]<)D82@_OD]"4=E+K)VX=]0=),7Z.]%VILL,DRD?P]#RU#/ M0'=<^C*(&D\Q+IXV:,&T.0;<%]:LZPY#@ME*&R(N.T,\^Z$'*C/%_?*V2E8T_!=#&9V2+/Y1M:DB>*+Y] MT=H:Z%DI.P7'HB$M+=-F22?W,J3EY(JE3A..,J31ZFFYAJDUM3,,XM9.S(Z< M!^?,),\B6^1Q\KBAI@GM>8.E9F2%02QJICR^WG/2]W#?[+P^:&NXV"KZ1J$A MYZ]?HQ("Q@<&X,9"\\SYYUZC$H;'#-8G\LG1_JVOP:;X8:8A8F;Z?^X@0F13 M+=-3%*"*=X^ISS'>3OOU_Z?#AZB3Z?SS6^HWS2_17ZK M_([ZG?.[X=?(OYO_1/],_^?\7_5O&3`BX)6`KP):!UJ"G@A^)_AT\,:0%CVC M>I:$AO1R"_<,OQ[>(ZIGU*PH^F5#^D45+S^CWQR_`K]K?D'^Y_U#`E("I@2\ M%E`6T"HP/G!NX'N!+D$/!H4&Q00E!5F#"H->"'HC:$_0F2#WX%[!UN!UP8>" M_P@."ID8\EA(YYXO]MSWE'A8;]E;8IV%]P^/# M)X;GAL\/?RY\5?C&\#WAQ\._#[\1;HAH'-$N(B"B?T1J1';$PHC5$>]&[(SX M)*(LXI>(VQ%->K?JW:UW6._XWI-[Y_2>W_O]WF6];_=VBG2/C(P<&9D=61#Y M2N3;D1LCMT?NB3P2>2:R153'J*YB[?I%#8\:%34Y*CMJ6=3K41NB=D0=B/HB MZES4CU$_1]&?8-!!Y.37SB_8K[>?R6^OWY=B&QK\&_NW\P_P[^L?+[9EKO]\ ML357^6_TW^-_W/][_QO^AH#&`>T"`@+Z!L0'3`S(#9@?\%S`JH"-`7L"C@=\ M'W`CP!#8.+!=8$!@7['=)@;.#UP4*/^8W@V=@7@MEO84VUN+<](\Z3XL_'R$ M3^^5O1,C/:.T"4Z:E\A6^GD$G@BN#!D3FAYJ#:7STPF_"%@5Y!)\I-?I7MI< M.>X3%!3T0MC*,&VQ$]H-\HOV$YT.VJT(.M$SHE=5V+GPVU%:M$'SIOL.OS$A MBT.7]GHA+#%\0T1LU(DH$<89,,^%?@/\U_J/"3X1[-73NU=E+^T_P_^7@Q/^ M/=%4_/<6L,]3Q>M8H[Q,)^:1U#_:O_\7K[FZGV%^B_DTLX>3\E#FUYBO,;

Q;R7^6OA^>+]4W'P7X3E8'!1;LV< MHCNK@5AF%VJG&_)M\.2:?;!*O/Z1/]/;N>WJK%W%M-\BOP-_!S>NI=R#N1_\ M@WP.@"_#4^`K<`'S,O@J_"Y<#N^!*^3S!OP3?)NY<6WRSW`'YE[P-7@DN0*^$VS.',(^K(;7BW?7XCO(-JY4CLGD?>$34[_[+[C'HII_>'Q<`"<"P?""^`@>`GS1C@8/L#\/1P" M_\[S,/AB?!T6#X`4< M!*^$!\$E\+B&\ES;+_ZC1(\*V\^+QW,GPO;C_F+S'>$[<=\$W?E MKL+VXS^:^2%WM2^RF9]T5_ME!?,V.$4>`\SEL'PT?Q[J.O%Q\P7X"FR/V1NU8B<*>?%G`A/A2J\6].GHE\-/,SS55-=`N<^W*;,[_:0M4, M;4DN1#Z=^:V6JJ:5-_H'Y`',([Q5S3/P\\BWL;Q]*_)2N2ZM5#ZN-?E]Y/-; MJWR)D7P$^0;XO3KD+YE_-JKZ;]N2/ZR#D7;*#S+W;Z?J2^#MR/U! MN!)Y)7/7+N3?X(%=6#W\)_)KS&V[JIHL^"[RIT`7[([\C3FIWU53=,>Y*;(@YC']F#' M/.R%?`?S%5;CYT?V1CZ,>3KS2WZJ?B_S*/"U0=F1.B5S9'[,S\T M1-6X#B/7JHOG,N;X8:JF^W!R`^1#F6;$7^&O-GK*9D//E%Y(>8_QC/^M)DG#O(-S-?358U^U+(.Y!?8FZP;D(YF?F*QJ7I]" MKET/VYFY?(JJ,661.R&?Q/Q\EJK9D4WV1WZ)N66.JED']T+^&?,M5A,WC1R% M?`;SVFFLC\TE#T`^E'EFKJJQ6,@)R%ULY`G(!S'/MJF:/7`J\C)F MK^FJ9BV>N9RB-FJIIO MX*>0N\U2-LU2-=OA9Y!?9&[Q*'DQ'/>HJN\\F[Q4YLSS9K-[W3GDE:KF M._B0W#[SE6/FL^<4^#/D5YG;Y+-K=P'Y6^1^S),*5,T#3Y`ORNW//.<)59/S M)/D:\B7,AYY4-5L7XGX>^7'FFPM537$AV5`?UQWFLX6J9MA3Y#K(KIK<#7G$T^RY]1ER*/+IS,\\ MHVH^?Y8Q&H2 M7B(O1S[C)95_N(3\)O*?F?V6LN?3E\D;D;_+?/5E=O^YC+P%^7YF[17V/0.\ M'?ECS-M8S>Q7R;N1;V2^\:JJB5V.:EKZD:EQ7D M(\ACF!>M4#7S5^)9'OE6YJJ5JB:LA/P5\G3FE26JYAOX(O(_F1]IW=;[]!]D`>PYS[ M!JMYDQR(O"]SSINJYN3;Y'CDMY@[OZ-JYKU'GH9\'?.%]U2-SP;RX\B',3^V M0=5W MD._*;1#7`;V!D.AEW@$7`M.!.N#>=O8_==UE^"79%7FN[RCO!=9&; M6)X)UT/^#,O?@^LC/\SRJ[`;\CH[V'$"-Y#MLWPJW!#YLRS?"+LC_YSEUV$/ MY`UVLN<1N!'R@2R?"GLB+V;Y1K@9\B]9?AM^`'G;7>3F<.0N53,>;H%\-LM+ MX);(][#\,NPM]^]'Y%:P\2-V#PRW1I[.\D*X#?*U+#\,&Y&7L;S>Q^2VR+M\ MK/+!<#ODDUF^"'X0^3J6'X7;(Z]@N4?`G>`"V`=>#G>& M-\-=X&_AKG`5W`UNN%NUGP$'('^<>07S%C@0_IY-&[F'W`MY$O-TYF?@,'C' M'C5M!1R)W'FO#/0\H]SS`OCN"!\F^ MB/D$JW$^2!X&MV`./ZAJ"N!X^1S$?)+5+#B$>S-X`_,E^!%YKWB8S?<3\F2X MPRVRN?!(RJ_#C\&-SPJ[;B/ M0H[*?71M;@,MX:B:=CG M5S4MOR2/E#GSN"]53_(H\!_E[S,?A MQ^!ZIU5]KS/DIY"G,B\[HVH:?XUG4N01S-.^5C6?P<\CKV3N<)8]D\(O(5_( MO(/5_`Z_C-QX3CGQ'.M+OR&7(`]F-G_#KBGP&N2'F&^Q&MNWY+>0KV`^\2W[ M/O\[\KO(NS+'?:=JWCY/WH7\(/.U\VQ>%W`_C_Q9YBW,)R^P[R5^()]&OH[Y MY`^LYB*Y0M8PG[RH:D9<(M]`/IWY=>8CEU3]IY?Q/(O\5^8.9:KF:]C9&==] MYC97E&.OL'O1J^0&R#LRQUU5-0^6DYO*G+FPG)W[%>2VR#U_4HYASOA)U1__ MF=P=^4WF#M>4!U]CURPX"+G[=>7(Z^RY'@Y%_@'+8WXA1R)/_X5=L^"^R']@ M^1,WR/V1O\W\]0UV+?B5/`3Y&N83O[+O@BK)<<@3*MEQ>Y,\$;D?\^B;K%_Z MG3P9>5]FV^_L9Y159`OR)QRBWT/_R=Y%?+WF$\Q__8G M.U_ND#9=]A5I/W(K1SV-^C_F+6JJ^0VWRE\BCF=-JJYJ;\#GD7G6434(^`]X%+,-O@4_P[P.ED,M-W(U\E;,T6ZJYBW8I1:N4\S7X19P4W?E M:.9D=]8.W!KY(>8;\(/P<`_E&1YJVB\:D?UE/7/KQJIF7#-R*O(\YN7,6YNI M^I]:D)<@K]-2N1MS_Y:J_C3\&O)*EL_Q)K^.?`GS+F]5T[\5>1WR%.:B5JIF M+[P!^=?,MUE-<6OR%N3KF$^U5C6F-C@'D8]G7L"\DGD7\QGFF\P>1N6NL!S6 MP?N1[V>^PNS25M6GM".?0CZ7>6T[5>/T(/DL\E;,L!G\@SQ.VJMISW0@7T/^)W/GCJIF4"?RG\@SF9=U4C5_2-?& M/:J/S9?<392O MJGD5]D.^G?D'9N<>RNU[J&F7PB'(-S)_Q6HZ^)'#D`]FGLV\AOFHGYIVMS^Y M'_*S_BH?$T@>B3R/>07SKD!5WR68G";W%_-4YJ)@5?]5"#D7^4UF8T_E/CU5 M_6.AY,>0+V<^R%P6JNKC>I'SD<]AWMQ+U3P>1EZ$_%7F?JN:!I'DMY#[,`^+5#6WX/>1>TPOQT%-O^\&:Y_9F-T\"99#9!_R3N1CF`OZJ)I?X3W(/?JJ M?!/\"?(OF>^PFL08\N?(;_JJFTP#R[[(O95XX0-695S`>8+S/7'U@.!2/(01WSL40U;;8&XU4-=/@!.3/,N]D-=&CR(\@SV!>SKR/N6*4FC;X(?(X M>7PR/\V\F?F;A]2T'1\F3T0^D'D&\S+FCQYFSQ2/D-.0=V9^Z!%5\Q8\&?GG M=F-GL'LJ.`OY%.8ES-N9OV73]AQ#SI7G"_,+8U3-;V/)^7(0\F7GQ>%5CG$!^#OD`YDQWR9N6Z& MPOP5J_>=YE3S-Q'#F6=/4S6'8"?Y?1ISXUS6YUO)#R`?S&QC?LFJZK=.)W=' M_A6STPSE=C-4_1HX"/E^EC?/(X?*[_28'V&>D M/8?=E\Y#'XA\%O,[S%_.4_7O%)"W(?^"V?"$"E?!!<5JVMJ+R4WD[Z(S)S'/7*SJ#<^3NR-OSSR" MV29<>H+*K\`]T9^A[G]B\I]7V1]"-P7^7'FNZQFVDOD M_LB?9=[U$KOW6$(>BCR3>=D25=-U*3D!^5#F1Y>JFLWP*.3'F']G-2DOD\<@ MG\_\[LOL>Z%EY&3D79D?6:9JGH7-R-0W MD9N9BYG7E;#OE%:1UR'W9TYF7KA*U7\);T!>R6Q?7R:6RAGD6\PIX#WP4W@O?AO?!OF^0]\,I\`%X*7P0W@8?@K^&#\/U MWR1_`D?`G\)9\!&Y#/!1>0S#G\':6O(K]8G-X%=A/^:1\')X&O,2YDWP:_!Q MYC^96[Y%+H&#F1]AG@&_";_(_!'SM_!:^`ZSS]ODM^"AS'.8U\!OPZ7,EYEK MO4-^!^[(G`"O@ZW,*YGWPN_"E^#W9)OKE/W@]?`(YL?@#;)-YJ.Z'7_>]\LZ M^?.^E,JF6L-WJ:8;]FF0L+W?'@O[PD_!/>#-L!_\(^P/-WE/6._;8^%`V?_# M0?!;<##\C;"]SZ^SGMP3#H%#Y?$,]X(7P&%R&>!PN0QPA%R&#<+Z=2$8CH1' MP5%P'AP-OPSW@0_#,_4#5IF\@3D!7?F1[:KFCOP2\B]=RCWWZ%J/H&7([_*\J2=>+9%GLN\;"?[ MSF07^@'9)K.%^:5=JK[=1^3WD?=CMC&_`N^0_?/'RE,^5OU_O5+E8.91S#-+ MU35B/2R'YW:3OT"^B?E[YEI[R*?AU^<]Y/OB;[)>;1^U7->K@2^2'FGUC-[P?@>GA>/JCL?83_7.$H.11[.G`[W M@E<>9=OD,_)`Y,>8[\"#X.#/5?U7<`+RWYC;'",GPHG'6%_T!7D,\F[,HYD? MAR?`9V$SW.S_P8\W+FCYB_8ZZ&Y;#F2W*6W)[,97`V['V"_"@<=E(Y MC;D0?A)^\Y3RE\PW3[%[XZ_(BY#/_$KEWJ?)+\AYG5;Y2OAEY+N9?V8UB6?( MKR&W,:\ZP[[7_9K\!O(DYGE?JYJF9W$O(?3;[#LRWR[LSCOE,U#UX@7T`^@'GF!?:=[??D=]KVJB M?L`Y+MMG+OQ!U=2Y**S_W5PGYH2+JN:+2V0/Y+\PM[JL:L;#GO(^D/E-5G,% M]D)>ITSEC\.MD:]B_H+Y-U8_]0JY/?+%S!]?8>MUE>R#O#WST*NJYC#<`_E% M9O=R93_FHS.U^4C67X?[(Z_^L'`[K MPS5RO%Q'YL1KJN:6<,W?"5Y7[L.;^*O`SY MY\Q5S%Y_J/JOX=7(;S%WN*7<_Y:JWWI+/:.=8JYF;O.GJM\%OX_\''/MVZIF M&[P=^4GF._`.>1[=4?4-[N+^"KDO\R/,<^ZJ^@OPI\B=JI6[,0^K9OV#9JCY M.\HBYDW,)V`Y-'QISFI&K.PA?D=F;N8%`U6^!?D9]AKN.L:I;!MY#O M9+[*:K)=R`8WW!\R[V:^""^`I]52?@W^S9V\G?E[YFKX)MRJMG)_YC3X=_@) MYHUP%7P2_@/^C=E81[DO?`N>R/PT_">\COD4?%NVR6QT)=^!HY@GPW?AIY@_ MA*OA,\RN=;&=/?!LR)S`;(.=X)>8]\(+X>^9&]0C%\+^NAV_0T@6^7PZ9D!F\'_X(/B"7 M`3X(.SN7B3\/Z=)" MU5?#;\$M6RKW::EJFGF3/X`#F!_R5C5E\':X7BOEGJU4S2%X-US.W+RUJGD/ M/@1_QOP'JWFZ#?ES6<]\IHVJ\3*2C\&1S-E&-B_X"_@$`?9@'^*B:77"PW'?,E?`"N'YG:<=EZ-99 M+D/G(;6T`9U5F]V[D(?!@YDM753-BUW)#\N^A;F\JZIITXT\1AY[W52>#8^' MBUENZ$Y.E>O+_'!W5?,9G"'7D;F#KZIY"\Z"OV+VZ,&.#=@"[V'^D]5X^9,? MD\^\S-/\V3D80"Z$-S-?#E`UCP22GY9]-?.N0%7C%T1^7EX7F)^'7Y#K#K\( MUPU6TTZ$7X87,F]C-8U#R,OA4.:,$%7S#/P:_`&\0O8G\$KX%[A$]H<]A?6C M*1Q>#>?"#W?LQ=:]E^J'YS"O9C5# MPU0_/(-Y71BK"5?]\`SF=7!C>;_$[!1!;B+[#=@3'@LWA?.9-\/-X`O,S7N3 M'X"CF*?!7O`K<'-X-]P"O@*WA)M$DKWOZV>B(N4YWF:/N$ZAIKE\)H5;R?,] MBMP./@YW@N.BR;ZRCX6#[NM#,OO(]L=L-&A/]E';8UF3HI1-2ZQZEAMRSP@5M4< M,9$WPY>8Z_53-8O@'?+YFN4C^N-^5?9US$OZJYHM`]1U]A1S]0!5 M9O88I&J2!I,KY'G'_/)@MKY#U+6O'?.@(:QF*)Z)9(WT??MZT%"YKQ.]Q.^' M#%73[H`WWU?_N5X_)LF@E:'F=]G'PE6P^S`\T\GC$);#L_!=>`/S:>8_6/VT MX<+Z?RMF,?,VYJ^'L_X_CMP`^0?,YYCOQ*EZTPAR(^2IS,7,[XU0]3>%[>=^ MTWCE2.;Q\:K^G7AUCA]@+F=V35#UB7`K^?S"_`+S^ZS^M42RCWRN8:Y@]DA2 M]=5P(/*V(Y6',D^#@^0S)AP,?P?WEMN0N<,H91,<*;<#W!22ZW;0U2S4/Z-.5P(CX.?@I^$B^"5\")X*RR'2P_C>H?\#G/K M1Y1#'V'7>G@5\EDLKX#?1%Y_M'(0<])H57\.?E?.E]EGC/)@^#TX#UX/+XB+S#6)4/A#]`/H7EB^%-R#^`-\-?P1_"M^$M<(MQY*UR M^X]C_?-X/-PCQIO*H/GX#G<>0/,\]C+A%6OYN-9Q/DSS/O8#Z;K.J7 M3"1_AWP3\UGF6Q-5_8!Y!_B7S+>;FJ:I^$WP-^3'FF\R>9G8_`_\JUY'Y M;>9/6?V2-/2'R#.%[7\OG\OREV`#\NTL/P\[(Z^=SIX7 M8!?DB7`M.`^N#:^`Z\`'85?X.EP7=L\@UX/#X?IP-NP&%\,-X+?@AO!^6`X; M)Y.;(S_.?(>YS115[Y9);H^\&_,HYIF9[-R92NZ*O#WS,.;LJ:K^3S@`>8LL MY=C_P]Y]@%=1K0L?GTD`$14!!4$14$&*E)2=9"_`P\@VJ MK!.$\[&.2W$1^0=Q,7Y+U/R(0^1/KE8>CI.PCL]Q&?F#PNW&6??!.G;C<>1/ M&&\=+SQ064%YHO(-Y*N$[Q-^!>M8.%EY'ODWA7\1/NE26[_W,N67R#>YW+J' M<`CKZ'NE\@;RHX5G"2_%.F9>Q;Q'?HGPU\(-IMCZK_"WNG^F6I\K/!SKZ'ZU M\E[R(X3O%EZ)=<1,4_Z#?)'P'.'WL8Z>UR@?)%\M_(SP3JSCC&N5(VHK9PO/ M$'X)Z]B':Y-O,]WZ(N&;L'_NX+KD]PL'K[,>A8_%M^)Z>!G647>&#\:1M]KMG(V'D$_'%^`Q>"B^0]1WOEVYC'Q?X4N$;\;E M>"76T>L.Y7'DAPE?)[P`C\*3PS5A'S"SEJ\CG"T\5?@3K MZ'>7\G3R9<+W"J_`.IK?K7PC^7.%1PO?C'5LQ#/)_R;W4[A'T7-H'N5'R`_2?A1K*/^?OH>+_R$^1S MA*<*/XYU])RCO(C\*.'9PJNP/S[G*K](OK=PI?"=6,>?>!GY%@]89PA?@G4L MQRO)[Q!N.,\Z'NN8AM>0?T1XH_"?HK[O@\IODA\C/%MX.=9QXGSEM\G'"%\L M/`WKV(X_(%_G(>MXK.,1_!'Y]<+[A5L_+.86O)7\+.'7A7\0]3T7*'].OE1X MCO`;6$?+1Y2_T,=4>)+P?*RCY%'E[\G/%%XM_`/6\=QCRGO)?R)<_W'K(-9Q M#_Z#_"KA?<)G+K3U+SZA?%P=Y<^$&SQI'<0ZZCZE_!+Y3L(7"E^-=5SPM/)J M\E.%GQ?>AG4L>49YO6Z/<*-GK;MB'4_C#\AO$C[V.>L8K&,*WD3^4>%/A&LM MLO53\5;R3PAO%ZZ_V-;?B'>07R*\2[CI\[9^.-Y%_D;A5X6_%O5]ERC_1+Y2 M>('P^UC'HR]PW,F_)USK1>O.6$?MI%UPE_ MAX?A>BNM`\+YN`A7"M\K_#(NQIN$]PN?NDHYA!.$"X0OQ\/Q;.%5PMOQ"!RQ MVKJ3B:N$YPNOPR7X3^'XUZQ'XE%XJO"CPFOP:/RU<.,UUHFX%%\@?!T> M@Y\4_E2X]NO*9;BM<)[P!%R.[Q%^7?@[/!8W6FO=4W@,O@3?+KQ&>#>NP$W> ML.XC?`FNQ/<(ORW\.Z["K=ZTSA&>C*OQ?.'-PI'KE,?A#L)#A>5[W6E>?HHZ MM[QK^!QJ=$2\I5R$6PJG81V=WU'6?\H0KL0ZSGU7>3J^6/@&K.,'?"-N\)YU M5ZSC%CP3/R[\KJ@Y]WWE._$%PE.PCI,W*"_`[87[8!U[\5.X\8?6YV$=R_%B MO$U8]FV]C;IOKSO.<<[:J&K:Z.W@L_'Y?DUE;(13Y;M%G/>L2LTX:A[&$_"+ M>")^&T_"W^/)N-XFY4MQ*WP9#N++<2:^`E^"K\0WXRE'[,M#Y"_`K^.A^#.L M(VFS\L5X*-:Q"!?C=W`(?R]J>GVD/`H78ATOXW*\6?@`'HO;?ZQ\"<['U?@Y M/!&?]HGMJYYX,@YA';OP5;C^%NLDK.,`GH';;[6^".MH^:GR;;BO\!7X;ESG M,^M$?`\NQK/Q'*SC3_P`;K7-YB_##^%Y^'W\J6=U%-<<'^'\*>K3/E=NAB_& M.E[`I^.MPL=MMS5]=BAWP$7"T_$Y>#'NB+_'T;ALI_6]6,L8 M_*7R>?@*X:>PCL5?*:?C3X2/^UJY+VZ+=W]>E^_;/><1CQC3WOIN(K=2W6D?BM\G4X5W@V)YK*_8JX_URGVNMH];OR&-Q= MN`3K6/"'G=/>%8[\T]:\B:_">X3;_65K"O#5>*KP,W@:WHBOP0?PM5CN;^O] M>G^??[:.D[)?U6PF/P9_A*_#'^.'\"=X!=Z"/\5;\7[\*6Y^0/DSW!5OPT.Q MC@L/VG$U67@^UG&O$^GY5[Q4>`?6,35"68^3N<)KL8Z1M91/)3]-^`FLHV-M MY5;D>PF/QIWPPW6LW\%)N%Y=ZUBLHV\]Y6SR)<*W81V/':\\G/P;PK]@?PX_ M07DT^2+AZ[".3_%8\K\+MZQO:QX_4?E*\F\*[\$ZKFRH?`OY.<)O8!TOG*3\ M$/D/A'_'.KYNK+R4?&03Z_:X\#5\F/%]XM:B/;*:\$Y\A MW$>X!.N8C;_`RX2_$VYPJJWO@;_$(>%;A9>(>K>Y\E[<0CA-N!CK>/)TY5JN M\CKAGX4;MK#U^:V43R=?(7RW\`M8QU]G*L>3;W:6=7?A`JSC59Q,?HMP9&OK M,[&.*;@[^3G":X2_$/6CVRCW)C]=^"GAM[&.O+.5,\E?(GR7\!*LXTN<1;Y. M6^LHX1RLXRJ<3?X!X77"WXOZ6>V4S]>?*_RY<&1[6_\$OIC\>N%]PLTZV/K8 M<*7R8\!^MXL:/R!/(?"4=VLFZ#=>3CB>3'"3\@O%K4[\&3R#?N;-U= MN!CKN!5/)O^L\%;A@Z*^4Q?E2\GW%YX@?`_VQS.^BGS+*.O^PA58QP9\C>YS MX3;1UGVQCJWX1O+[A=O%6/?%?CV^7=<+MXNU[HMU/(KO)O^&\![A)@%;7XWO M)W^'\'+A[:)^8)SR?/(3A1<(OX5U=(]7?HQ\D?!,X>>QCH^#RBOT_@J?DVB= MC754)2MO)C]+^#7A;[&.]EV5/R'?3WB"\+U81^UNRMO(MQ,>*#P9Z]B)OR!_ MS+G6<<)#L([CSU/>1;Z+\(7"4[".0'?E7\@/$IXF_!C6L07_2OZ`\#DIUEE8 MQ[5X'_EGA+\4;M1#W"_AW\A7"3\J_*&H?RY5N7:$\F?"37I:]\0ZUN'CR/\L MW#K-NG^:N+[@AGK[PO5Z67?$.N['IY!?)OR-\'&];?TXW)S\;.%UPC^+^@O[ M*)]!?HKPL\(?X??QK\(MTJW/Q1_@"X2G"C^(-^"5PKN$3^RK_"&.$;Y8^!J\ M$2\0_D!X']Z$F_6S[B4\"F_&UPH_)?P._@CO$CXYPSJ`/\:YPI<)WX\_P:\( M?R5(!P!=Z*;Q5^17@;_A1'9%IW$<[%G^%JX7G":_`V_+5PXRSK M1/PYOD!XNO!"O!U_*'QLMG4`[\"YPI<)WX]WXI7"/PG+>^Q3!NA[[/N>K>_$ M#5`U+`9NC>=B'?MP$)^08_.]A3<(-\JUGBR\73@AS[I> MOO5,X1L'*M?1SXSX&/PFUG'F(.NUPO7/5SXM0KDK;HY'X-/QW;@%7H);XF]P M*WS:8/H'=\-GXC)\%IZ-6^.UN`W^#9^-VPU1;HOS<3M\"6Z/;\0=\`OX'/P5 M[HA/OD"Y$SX/=\:EN`N^#T?AEW$T_A;'X/9#E6-Q`0[@VW$!BY13\%#<%]^&^^$5.`,?Q/UQIP+E07@,/A\_@0?C M'_`0''VQ\@7X$CP4/XTOQ%_C7X-ZX`H\2O@M7XN=Q%?X,5V-G MF/(XW`R/Q]WP!#P83\25>)+>/IZ,%^-+\7I\&?X17XZ/+U*^`I^-K\0I^"I\ M(9Z"Q^.I^#9\-7X:3\/K\#7X:WPMKE.L/!VWQ-?A5#P#7XP?QU.PCB7X5?+O M">\3-94AY;7D;\$;\$*LX_;A=JY^6GB3\%ZL8^((Y2_U-H6?PS_@-[".F)'* M>\D/%+X&Z_@*NY'*QY58)PE?C'4\@>N0?TOX5^%31MGZ;'P\^0KA.<*K1/TQ MHY4;D6\CG"E2_$FY<99V$=:S'5^KM"[>HMD[%U^(0GHZGX^OP0JRC^SCE6\F/ M%)XM_!K6,7B\\CWDKQ)>)/PI?@#7GJ`\#W?"#^*!6,=>O)#\:1.M,X2KL(Z3 M)BDO(I\H/$KX5OP27H)?QEOQ*[C69+O-$KR*_(W"KXB:,R]7WD*^M_`$K./3 M*Y5_(1]YE74`[\4C\:_X:;P?;\`'\!]8Q^0IRG5K*<\5?E=X']9QQ=7*+72] M\%O"N_$L?-8TY;MP(;X;S\'WX(UX-JYWC?*].!7?AZ_$]^-7\!P<<:WR7-P; M/X"GX7EX.7X0_XGGX]CIR@_A2OPP7H@7X!_P(SCJ.N5'\63\&%Z#'\>_X86X MPPSE)W`I?A(_B9_"V_#3N,GURL_@0?A9?!=^#F_&BW#3&Y07XX'X>7P]7H(7 MXA?P>OPB/H"7XL0;E5_"9?AE_"1^!6_`RW#MFY1?Q5WP@IK]]\KSO[&*?2 M]_KVWO7T%K6=^OJY8*:UW&;23%W?OR3"&4C-\>2GXA/PDV+=3_")^-A;E1O@ M;K@AGH@;X4?Q2?@+?#(^YS;EQO@"X4MP$[P`GX(_PTUQX]N5F^%!^%1\,SX- MK\/-<>T[E$_'W7`+7(5;XL=P*[P=GX$;W:E\)L[&9^&K<6N\$K?!=6X`VYWE_(Y>#CNB.?A3O@+W!EWOENY"QZ/H_`+.!K_CF-P MTCW*L7@B#N"E.$Z.#;TN^1A\PFSEBW![/`S?C(OPXUA'G7N51^`VPIEX-!Z) M2_$4/`8_BL8XWGE(^G?RWN`4^XVGEEK@'UG$O/HO\2MP: M?X;;X$;/V/J]N"/Y9L]:]\$ZWL31Y'_%,;C3<[:F&L>3GRWR:W`"^1TB7[1( MN1OY6X2781W[%ROW(]_Z>>L,K&,A?IG\FR(?LT1Y%?D!^$,\'F_$]^!-6)[7 M+R_1<_Z[4=ZUE9H)U#1\07DB[H=OP)7X@R.V\Y3*^W9?5.Z*3\$Z[L0]\-,B M7WNI1WWX+/QLR*_%W?`]5^R^;ZX,QXF\IMQ//Y!Y(M> MYKC@2=B?NUY13L$ML(X)N">^3>3=9`1^1]347ZX\&K?#I;@_UK$` M7X)7B'Q@A7(U[HMUW($GX"=%/F^U]?WX&OR*R!_$,W"+UVR^`-^$KQ#YE?A6 MO!W?AG\7-=^N47X(1[ZN_/`1U[LS7M?C<(ZWJ!LU.B[#S?`=PL^(FBYKE5OB M'*QC#FZ#EPE_+FI6O:'B&>*?+WW[;G6 M&NMX%1?CST2^_0?*);@']H\A+L,OB_S4#_!-XO\E(^4%^#[A%=A'<=^K+P0GX6? MP-VQCM,^47X>)PD781T_X66X[A9QC/!J?+O(1VQ5?@.?BG4LQNOQ.I$?]*GR M>[@,ZUB/-^!O1+[U9\J;<1+6,0YOP=>+_%J\#7\J\LVVV7NYSEA')?X:SQ#Y M]_$N_)W(QWZN_"/.P#INQWOP0I'_%?^&&VRW^6S\%QXE\B]HN\H;1;[5#N5: MY).PCFG8_RZBR&_%QY/?(_)==RHW()^'_?D?GTS^19&O]85R4_*ML(XQN#GY MZT7^(]R*_#Z13_A2N37Y'-P&WXS]TP6W)_^;R#O?*1>1;XG]>0^/(C]?Y)U= MRN6Z'NNX%5>2?T;DH[]7GJC;AG5\C*\@?^P/-E^]6WDF^4>QCJ8_3?Y]D3_K)^4'=+WP**QCUL_6._`\:B)^L6Z#=63M$<<4/ZCO=85WB)H3 M?[4>C>=36\7[\)#5G MNM;]L(Z.$=9E>"DUUPH_+&JVU[(^N[;R.]1T%[X8ZSCC&.LJ_!DU=PJ_(FJF MU+5^#7^KG]&$#V"_OI[U.OP'-5\+USO.UHP]P7H%;A#!?@G7K6]K3C_1>A@^ MG9K+A.\3-;D-K.?C=M2\)OR=J,EH9+T`)U"S7O@W4?/VR=8G-5;N0TUGX4RL M8^DIU@?P4&J:-K4.8AT-FUL7XTG47"/\A*@)MK">AJ^G9K[P6E$SJ)7U/#R; MFN7".T1-XIG6U^#'J'E(^`U1T[VU]?5X*36/"K\E:G:<;9W45GD]-1<)7XMU MK&]GW:B]\B?4=!+NCW5%S^BL?)":-.$R[)^/7:SC MHI3KZ]^C"5^.=82BK9_'IU&S27B_J'DCUKIE0+DC-:G"H[%_?..4`^2OP3K> MP8GD=PG7C[$O M1,V\KM8_XK'4-.AF'<`ZOCC7.OD\Y2NI*1"^%NOHUL/Z;GPG-HR1"NQ#H>[&V]#[]*S:E]K%.PCHATZSS\)C7C MA.\5-9_TM>[23WDS-3G"$[&.^`SKZ7@'-8\)ORMJZF5:C\(_47.;\')1(Y^7 MC\D6UQ1<@.\2^?=Q$=Z-[\:M!RC?<\0V!WGY*>J>VGL,J?+]P-6-G)NI[T;- MR_A<_!T^#Y^=H]P=#\MNX!]Z&4W&C7.6>N"=.PQ-P+[P0]\:?XCZX29YR M.AZ(^^*[<#_\-O;[*M_V3RNLXWI6,?M M^$Z\6.1/ND!Y-@Y@'45#E1_#4[&.[AA&/P>NSW\TCE>/+3L8Y. M)Y`/"!5C'D[@?^77">T1-\FCE+/(#A2_#.G[` M`\G7*[6.P3J:E"F/TGGA(5C'+CQ6;Z?0[8AVS M\-7DGQ/Y%A7*T\EWQ3JF5C(.R<\1?AWK:%;%W$4^4"7.ZVKE^>3/%$['.A:- M4UY(_CVL(WH"8Y5\)M9QUT3E%\DOPCJ:3E)>1KX;]N=YO)+\(\(;1$V+R@7^@9IMPK6N M$->[*ZW'X3_U+&INO-'Z M/3R&?1$WSVZU#>"8U4X3GBYJ?[K#N=:?RX]24 M",_$.G;.LDZ^R][;%PA/QSH&W6T]#[]&S7+A':+FE/NL0W@O-=.$'\5'WDM\ M?+_-MYZC/!\G8QT3\2/X5N'%HN:RN?9:,$OX%:RCP0/*S^,NPH/Q2W@N7GU$ M.[O.T_U/<,[W'/YNQBS<`+^-&^)C'E1NA)/Q2?@2?#)>@!OC;W`3?,9\ MY5-P/FZ*9^-FNAZ?BML_I'P:+L'-\1Q\.MZ$6^!C'U9NB;OA5O@RK&,S;HM_ M$?G^"Y0[XA+LZ!H<@QL]8O,5.`'/%/F&CRKWP)VPC@DX#=\KO`[WPCM%??)C MROUP/M:Q&@_`6X7=QY5S<$N?ABK.-S?`&NL]`Z'NNX"E^(YPBO$#6? M/J%\$=Z/=>0^J5R$QPG/P3J*G[)^%E?C]X1_%36-G[$>@Z?@6X5?$C6CGK-> MBN_''PL[BVS-=8NMW\=+\6[AAL_;FM.76@_'>_!4X8=$S6TO6?^`]3OPDU^V M/@_K^/H5Z^[+E)M2$Q*^">MHN]QZ!FZGK[G".T3-DRNM(UNN5%U#3 M3K@?]MOPMO++Y&=B'5OPMT[^P+Z' M'"0\`>O8N,&ZY8?*)T MGXGK?&3='NN8AL^6VSS"#WZDKRDYL=[U]QC'6>GGYPM_XUG5[*SE.,O8YC#W M\.U\(#[WJH^5;\=WX+[4/^99;:?GT'_]6A_OA%W`.?@?GXZ_P4'^`*A?`4W$( MQ^"1N!\NPT6X\F^/T:0MNM^^7.O54A\@?S^.P^MQ/-Z)=9RVU>YC,M8Q%??# M\X17B9HS/[77IA["I5C'EW@H/O$SZQ[8/Q^WVV?Y3<+U=]B:+_!T'+G3^ARL MXZ4OE._1VQ'>CW6<]+WRA[B=<&^LH\X/RI_A:+S[B#X?H_*^G\*9>(VPK/_" MR[?VCLN[#2>4[O,\UXEUZJI]V:U]O.>6OAN$YU".8]CQ3AWC!.<$XZ!SLG$B MHUX[B3->.YF1KGVN$V5\'B,:>^IMW,,98ISF##?NY8PW[L-1TDYW;C'N[]QK MG.>\;CS8^=CX0N=+XP*^":A]L=/$N,II:3R.&0)[+;C0>+(SW/A29XSGCKOU M./_KX,C!^US>6.C6WJ/M'5 M;NW[WMVU/-_@]#AI0NDBCMWU'%/=GALT\(WBV-WL-$-LA^/U-MN9XUQHMG._ MV,X<#3Q/;.+L39[R#V7$P[?R0=E;@ MC8R?&7B3LZN&]J?:]N-YM/^@<]K)X7G@=]J_E#[_@S[_`/_)/+`-_T4__X`/ MB/8?U,!U7=L/Q[K-C(]W.QB?X`:-&[B]C!NZ><9-W1'&S=RQQLW=2XU;N+., M6[KW&9_I/FK[RW)I\+?=KS[&XMKNSAF.1:,]?G/Q3+<\I;E[C\+'H[M:E_[6/5^OY M-G.R5P]PIFO'6)9[BO$`MYUQKMO9.,^U\^T@M[_Q8#?7>(AKY]N+W`KC`G>2 M<:%[I?$P]S;CX>X-1[C/&8]TEQI>X*XVKW+7&U>X'QA/KJ_>>Z+TQA7`W$OQM5PW)MQ-1'W85S- MP.F,JWMQ7W>;YR=P/W=+#>-MHAUO^"7&V[/N^B;A\;:0\?;>3\I/N/;MU/SC&O/_6?%.%PEQN$Z]PSCM]P8X[?=5.-WW73C]]RAQAOY5QI^X-QIO<>\PWNK.-M[F+C#>X3YMO--]T?A;]U7C[]PUQC^XZXUW MNYN-?W(_,_[9_=9XK_N3\9_NG\8'W`@W;#>BKG%D1#/C8R):&M>-L/-/O8C. MQ@TC$HU/BAALW#BBP+A-Q!7&;2.N->X0<;OQ.1&SS9AMR^R-AK1WXI8V\X^9?LYA?QR]Y$:QO!<.X;Q\)]K>4Z-&-,T/(;/C;!C^+R(XSU/^%FY M>T0#,VY[1-C[A-0(@-,CCC$>&!%E/"C"CM6A$7V,+XK(-KXXHL!X6,0XX^*( M&T3]3<8C(^Q8+8VPUZR)$:\97QJAQENLGA\BU%PQC?[I%;&GAO[9ZKNU[SOI MGT!DWV832A^C'V(CS779RP.<)/+=(IL8GQO9W+A[9#O;5Y&=C?M&!HPS(KL; MYT9F&N=%YMN^C2RU_1EYOW%AI)WGAT?6<<,>$5D?Z^V<;#PJTL[;HR//-BZ- M/,=X3&3`N#RRF_'8R%3/R^C/N$C5G_J>*C[R1W/M3HC$?Q8^)U)L4[A$^";A><*KA.O^HM\;C/)NUK^( MM.]8(FI9MQ`N\EUV@O?,XONONI'.@&.T#[3NY)1BXN_>X>`&]1SGHOK:KWD' M=N-J[=&U(YSX]=J[KSS!61SAXA!.XX(-+)::K]5@7_ M^_[X'N]T&]56>UFQ5]<>\[]U?MZYVBV]_RI-P?SO%_?MC_G?MWT'Z__MVOKG M8_YW1:>MP_Q;]/4V8O[M]/.5[;^1CEO$J7_C&O-O7#?X!O-O,J?[?M9;?L5> MS+_'VWH_YM^JC6@:JN\S"_;WKP(\__ MQGM"Y9VU]+N^E?_&NS[/O.MKQ%C5T=SW@IP()\FS^?MQN"U>(_R-<.T]MGX7 MCL''[+4^1S@=ZQCUJ_*Y^'KAYX4_PCI^WZ?<%S?[S3I5.(1UM/U=.1?W$BX7 MO@7[^_N'<@%^2_A7X:9_VOHA?RF/QA.%YPGSYS"$5ZD:WW'[E3-P7V%9/\++ M3T'Z_>1*__VDK!F_7UTK8YF3N49X)G#0J6^OC^*9-\7I8JS>2(6=Y@RPUT?G MXK"][+7&^Z`PSGN0L%.^^5H2M_F:S\52G M=D38TYSZQMT3V,$YRO=X?O M'X+.3L_/D4]TMGE^S?<6SV_C)&>SYX]PLK/!\[>^W_7\%^[JO.7YV`/*W9Q' M/+?"YSKS/7?R/7?WT>])3HW4;NT[^4`MSRN:ZSG'<^YVN+]VPK M-/!*\?YJE7C?NUJ\*\>-N9:/P.Y[;V!\X, MXP^=AXTW.F\9;_*JPMXBWNM^[OQJO-UI[MKVG&'\E7..9WV\5O(^K8C^7,5[ MVK%X-<=Z$G[-^;&&>[].]MX/7TT_[W&^:N'/)YX)O%_TYP'1GZY[DG&DV]6X MMEMD?*Q;;ES/M?USG'N+\?'N/.-&[F+CD]P/C1N[GQ@W<7<:-Q7O3TYS[?S0 MPCW.#;N5VR9LKS?MG'"6>`?2UBTR;N=>;=S!G1&VU_O/A.WUVJO&T>Y:XX"[ MT3C.W>)Y%L?B5X[+PW@?QV4Q_LW9[/EU_+NSP?-[^`_G_1J.W>?VV.&M'+M$ M=VVK":7?X%YOG"O>.>2Y?Q@/=!D_^'SW M7,^_T^8D=_.!@P?K'53N[F[PW`2GN.]Z9K^\MOU:PWYUM_N%S_36]>Z@=-)_ M'JE[IGTV:>`YSJO1_N?91#Z;K/SGV>2?9Y/_)<\FX7QSK)]-NAY4#?YG3@N; M9Z*5_\QO_\QO_Y_,;_*Y?AYS72SGN_Z]0`QSW?,'L7C&D<_X<>*>/%[8^_/!SI1QH.<5.,A3I;Q4&*3SH?%HYPOC,N<'X['B/<`EXMF_PFEK7.ET-A[GQ!E/<)*-)SN9 MQI^:V&>^/<".W6OGUYB;/#],/S?C]@T0]+-/!2T0\O MBWY8)OIAA>B'E:(?5HM^>$WTPUK1#V\ZDXW7.3<9ORW>F[WK/&;\GO.,V?<7 M:MSWY^V^X]/8]^W.W6=/*(WR/-?YG'WOKRWV?;L&_L(YQOA+\=[C*W$O](T3 M:_RMDR;RA<:[G)'&WSOE3OB]Q(X:Q_`$VWY<0/OW.PW;AH_=7^+[2/LU^*=!#? M%>GDVCDPQGW..""^MY/@OF8<=-7[GPJGMOI[ZQS?R['#=RIF8OU=G7E8?U?G M61SIUO3]J/=L?^*57OWA]Y;;V]I[RQ\]?^C5:/]S;QGV=J]/IJ!_[BW_N;?\ MWW]OR5@/GX/,L=&<[WJ.C1)S;+0&#ASR'>G3C?LX0>-^3E_C#"=?M<-5L07:.PDUX2;;Y;`]\OVCQ7_`[N`><, MXP>=@/%S3K7Q(F>Z\?/\[?DQM/,>VGD9GNUPO<#W.C5]K^8NVW[\(.U?[0QH M'^[S5;1_B9=7MO<)JS7P:V)?UCBQ8IMQ-5QKKFEOKS6W>%[M;5_[GVN-MCQG M_[F^_'-]^:]=7\2<___\6O,V/]GT#,5Y-L?,,WL/G9CKO>9][7(2:K_J+N3=3`P\4;1@DYM[S17LN$'_O8ZCX>PH7 M.+]\"CG4N-2YVKC,?;[$EZU?7:H%,^\U?2O]CC^ MM?73(U3_9#.W1^$!SEK/W7".L]IS+LYUEM?0A^M]MQ8N5O-E!_&]/L_%WG:T M_YF??01S+W/+'!S/]Q">Q@G.VG_S?C(\GP3/\?;K MG_B?%6-#PPI&EI>/[ESDI"9UZ5E>5#TF5%95V:JPK+A5;JBJJJ1L1&67E.(Q M)64EE545A<7E%5W2*HLJ2JK**TK*NXQ5JW9)+2^K+"\-%7@_JRK*2[LX(XJ* M8@J*RL>,+2D-%7=V2LJJDJK:176,;M^M@A_)G6*B`PF!8&Q\()ALF)#L%(TL MK*`TQBOE1W)4!F5X M?XI-"$?X8XY8.4ZO'/?OK'Q(0^/;=^M>&1](KE#VUHX6:\OM)(@X?(-';U)" M>,OX\'9%U[#!RI'E%55F&T&UC>AXMA'T^C(V)B$^F*S^.UQZY.+GWZ:I`#N<=D563!E>F5DI>3IG-_<&&^S(DMSU9!GRRP--X1QKG[$ZX4)ZF/MP@1_ MH;=&>J:_M6!X]S)L+C&BG9C*S,WCH;J[-^S\9Z MV^MI5XG3"_V6LJ98FJ"7JJ:F#LQ*][-!G?4[-=9KTVC_!,H09;'1X3)'[1(I M<^3S32I6I=A+F_.:JG[$T6)Z12R,]Q?6-`3+JFHZTRJ\FF_:R!G%7)$MD@&]`D-!+\P=HI?$Z\9Z&88VR1.MDH8E6V2#K6 MI&4V8+/L+LDXG8S7'\/>AC>>$%[DF%30I#+959*))IEADH$HD[2Y:%NH1J1. MZET(^/T=".C]9#?-BG%^C5K19N---L\.>=5H5B\0R6`XF<<434ZUFGHGVZLD M%Z<;'&&?/')GV M3\$$_U/C5*/D\J"_W,NGIO?4.:YJ'$*32_"O:FK]E,S>X6RTKHS6\YCZC\XS MO:D3GPN5S<>25[M\:+WN\`0UA;"Z5W#8FO&Z@OU@0TQ+8A/L"`NR#UN2Z*^J M)K],4L$HG8K1]RII*7Z:W:%YAZ1CS-U`+SNQQNI:+V>/7C#@]X>7Y?-)QI$\ M^OW8L,+*4%5E<>>1=&!LC+=&=(Q7&[[[DEG=C`#7ZG`NUE2*9"!=\Y2N8#K%C^92*G0IZDH"82;F)L^)*T@CRS7+QK#1"(7Q/M; MY)SQ*W(/J0CZJZJ]/G1)(DOTY8N2\/BPS8F-%A]\^+(8\]D;0O+]/`?:)`EJMEI./-NL=FH\Q MZS$P3=Y.9H>D`[8\)34U+3>WH']*;C\]%<2;F?6(1?8^OJ!WOC>_YJFDMRO> MVX6>A56%T4D<>OTXKA(Q*I'(\WAT/)E8/Q,(AC.!)+41;[\+*SPD>CNN?_[] MBQOOT3LA6=\N>A<;[_^]IWV:5*565KU$RYR-U&="D==GJ"7<]^JZPI24M,* M^J2E]$S+T7OA=71E(*4HE#=Q;"A)71Q4^X/)7J97:>&(2C\5U*G;*K=L6Z&NAOQ4LT4-);%^"7>$K",:FI&2TU\T-.Z_KZ%L MV;8B7K>"JT@-)0E^"6?=-29==R.@7_O1;K$TPV-VO8J%!1%:7,D&PSF$GW9'=D?`_KCMD>X_< MQ:"_BVKN^?M*?P;B]DNO<7UBD%)7FA,:55):4EXDK;^ZP2='BJNL5'7'5]9*AU/+JLJIPEOLI MM69,.,/]%&,]PV]1O-\B->/9;(*?99)CL6YG04[:P/3<]*S,@O3,7EDY_5/R M//N-9XX[K/'\TH4>K'%E/I!W-&S$_QSNX(_XC("^1-G]M)_@?7"/B56ARO2R M_$JZA?V72WI5A$*'707$)QW>(/^8!M0!XCU\NO<@E9LR,*T@)255Q3+)GDCJ:JZDJQL3U[A"'*R*6D5%>456<.'5X;8*<:LR>>&2KWA M6EZAEZAQ&KYQMFLP!J+"^U&N.."X9X[LDO\?HOS^TU->:E9F7EIY^?YG17O=59" M=+SJK-"$*GG>ZG971-ENXL_1MHOXMOJ$-ADK-Y\Y5B3B0_ZJ^96VH[5'S"A*E16'"H.CZA*W:$)APRG MN.AHQI-:+58]1":JF<0LB8NVM0X!6GG MIZ9EJ_/7FV52U6^4\E@4HV;4J+0)1:&Q5=Z')*#SBP0?>'E#UF4$RI2 MIRN;XYF0[3(L95E*<7%%J%+W1$)XD&96CQD6JL@NK"@<$Z*?[(B5ZZ:7#2^O M&%.HJ#_GT!,S.I!L!W8@&.5UX^&[Z_<(9Q_-<[)K*(GW2WB#74--@JT1'9N= ME>[U?DZNW[5!U;5'[:7PPZY_JHM%@43[6_OC0!\5.'%ZDWCGSDQ?D M?G5&S>4QIMPI\"[-O=,*U.+>ZG&7O'=@JX/523B@=BRC?+QWV`ZYQ/0I&3&2 M'&^LP_OA+?->*^@UX_Z#-0=4%Q:S3+_%U$>- MG]Q.^949O*DA'>>OKV87D?:[D1?PX>4%:GE!2J;WG[R\G/0>^7EI_CA/"'+/ MD5%=HH8P6]6-3JFJJB@95NW=61QV5W&T3>E/3O0_68WL&JO4&WU^,K3]\J-4 M>U?=G)3!_CHQ_CJQO[.SDD?F)Z1YO5[;IIW M&2>O+N,Q4=D5)>-*2D,CCKP1\V^&#CGVICI)-Y*^XG)PZ"?HIH1_K:H.V]&6 M!_WE_/K)+_06I^;GI.<-/N+X)49Q_,HR0F4CJD;*EI:.S0T557M/!!-[AM07 MW\:J.R96";=[F/_(T*>PK+B4"T>\/-7<4WQRS/^ MICX0KI=[F]X_VYODLC)3F/0RT@:F^<\2ZCUD*+Q_*67E91/'E%=7)D5U#.?2 MBT-E527#2XKT92?:+A@SUKM2E9?I?$Q'VTG>$=3)V([)SM\V0;?8/]%X$?EO ME"?XY4Q?>CW[*?Z5OR`O)R6UG[KQ[)_5,\U?49]60?7X]6_4QZA7D?SD!&-% MT:,#\E,RU,^L7EXN9V"Z>BJE.H9Q=.0PDOWEC;)QH5(]B'A$%9?!O(K"HM'> M-S+Z2TX<.]V_62<:&LLM*)2;I%WK7`6Y+L_%V[]-[$^GNCKOG_ MNCK@5W.>LYI]GY&7U2\MTZ\+3Y)TS6$'+3@?UN8J`MY#4J"_?)FQ'3O M'4Y>>J_TM!SO_45>GRS5>7K/>!T:/["PM#J4Q)]C#KV[30X_FP+,2V_>S"?88JJ3>+7TY.]H;ANIA*=55(\O5 MN+4(4I2=([QKN'@%W;+DH\[%)TZ$72M)(WC31,_5+,IJ-UFI>* M>CF[<>1%FJI8=2N2RR6:'6<,'GZ)MO>>1V['_U2_]WG+5V-1G"[B_5ZX.K?& MRRL5"?XJP<,[A0_EP_YV?7\`\Q;-WZ##^>J-\ZS\G/`D%/9MYW'65QP%_,"*8NW%9F MY9RL#+^QZE8B$,7?Q7B]D9V0K=7/_0\/V@HRT/^LNYW:#0[$[/M%XI^1EY!3W#K_!B`E%JGWJ& MAA=6EU;U+"S2$UIL>$#2@L-7K&)%QCL;<+)K+(KQB[AGH-JTI7=.5GYVKM^* M`"=Y[XKRZK%'W*"1K4SRAZ.7T<=9;L7_-,8Y6Z-)AR^.]Q=S'^W791RM,.@7 MVC&;-2A3/8N0Y;UAUOBR4(4X>>DK6S_ M8>_LNA/)F03-3]G+/7MJ=R!)DL2^PAA7,8T-8W!7U7OC@R%=9AJ#AX]R5?_Z MD1Y%2@&9:5?/SL>[9^>BNW!$2(H(A4*AT$=>=V^_.KYWY\7#L19MH,W.JPVF-V$D/3<\30A1I=ZVB= MFFOC"A+Q*@E>16B'%<1)PQ/7]K-OCFCZ=2R>QZZP,P:?:-1$E/QY&DZ>UU11 M5S/^A"J$4XV,!8DW@2I7(C/\8#(=]";"@W4HK>3?XE#Z/UZ66U#3)5Z39>&1 M4V&_P/&+2WDS]B.U2!+RYWKVO)SWGLS)]TR2OM8D%*[[?;9C$:W4'WO6%W(L,W;>8N M!"L2_R'35>3^4FZPZ2!./[%'!V_>9/>4_WV<+$WD:<$,H31K8^9A&I&7HKA>*_4934YNZ'K-MMC9< M-6)!F*3#Q>;'P(BW/VN(,-W#8KD?;U;+N7&PB6A@N_RV-"OX-KZU7,&N*_"E M*-J%TC?=Z[X=>Z)_4@;+A=6'](#\Y?09Y7]>;IYGIL%F_G=WM9SMSN+\S\_9 M:O7;>O.ZEF[(X3:!8'35G<]Q7$D.'ZR_SU8F=&_G@+OU'[;X69H#>IOGE\/> M<-0Q(FK&1:Y$Y&+Y4T2W!4UB0>C,"GDT[=X/!]>#:6Y_-A)I1N.9<=3CS68U M7#XO]V?N8*+,PC>;=06ZZ?SOS9IH6&J@6;VHYI&1JYM MY-$8BF[##V$[0X$(TU1'@C@ME!.^DP]7&S*5H,47=XB9A.Y^,#)^[DZ2_:#= M<0U[G,VLZ-U$Z:8?G<;E5%LYWLVR(S,';\L(_$QK6S")DO7.C`:%1T3?1`D! MF<$A@72%D;%[$MP1+&"=G]E8F-[F]&9CU^/.$X=;EH[L9D M??K&I__T^[1JNYIP2*]*KY8KEFPJPX3>%.J,RLO6D`TLA[W]*LZ<,/AX.*R- MWZ)LVBP9_S9RL0G?N^/^??^V:WT&6#;8\*!'*;'G;+%DVUBE?LYKJK1KH^G: M(`E50,:")/*#*F?@8]^LBDQ\VK\?=V_-6'>&"DW"&.[W>M(T$ZWU'UOG9QV8 M"9>M\O%LL3##T(&9FY[5J;;HNP'.BU=KX/=I4:(D2*:2[Z[I_.>@6NJM1I[MZLY?9 MG,21.+2Z\P5VFJ%S`.=>1*E0*^A4>5I'N(WQ=K//[&SM.[OCS+*:223CD#_, MHH6W:2.A)7RED-;">#09.#1';_X!1AP?3^\## MX>!BLX['EO#(NKZ")A$:%O<0YW*,;_M&:AG_I!-3[])_V0E()=(83HG*8.@$ M;3.$_(LG@B[G95+I""(YLV%5H&/H4\=P63;]H!'\77F4D5Z\-2VN8! M:I,_'O\%P\(!I%ZH@BW;I"C_,GXK:"*AL>.6'W[[\-A$97';M M=-([7JJ7C`#X]WSJ:AT++6&!85E.D@B)'97\\*.R=]OO3C&=J59W"JM!W=7, MZ@E+S0ZZ8JVOCG#"D*VFL_E0_F7L2@%C2-/H"=K(VDAZ,=ME MZE!-2.JOC$WC;2R%H!!"X\39*XDX`&@9A=K%79FV=\T5S3D&99AS5NM-0C$-CFZY$F627`Q'O=^<)*T&5FIF MML'B]!R)AVB',-W8L'I9.'E1T0ALM1CA-`;_U81-(8SAGQ(E_%]VIUUAO\4T M[LYZC1YQN3LMAT"@34[U#VLAF5O>CF,,ITQ[2%!)EPH=#ED*F%7?9*K-)R%? M=[5:KO^`,TY2\:/NV0ZX,*^I>O;@T"O%:N,"TNJ2"L@XW'P<]HN,6'<:W^06 M2J+7P?ULI4OJVG&'4-;&530HC6H-!V#S>TZ`4WL2RB0POJV?LY/EK&.G8]44 MN$ORXZK9"\-.'[3._N5`!N?XL'6>!M6-.][:.$>8J(U+T#)OM5F;"]W][71H M?*UQL;WNT"8=2?)<]B_N/CJ)VDU":IR5]@J]K5DG;+87YA""/8E@LBZ+[(?R M$I`L;8)\-,VY\=9#:^W#Y4XT%N7S-DOADI4- MYR/6%9'[Y&6VS1PGQT.G<0Y=R'U4*T;4*9;`O>IWB5,A9@Q1JD+WHO46<1'"M,HBP`VJU69GJM,"'6_Q MN.9\_D=M[]@,JTEO*I61HE(H7RIL\+!4.2Z2QJ6W`>*&+`)/NLOU)VZ9;JN- M2PEB(<`9"^7]:/*[B?J-5=CH128_S@,VXG3Q:K`9YFSM7P59B+1XO9[]\V8K M%,H:0"W7'A7L`=3%8;G2BL4>P(Q7L[T]-4V`H`QB]V=ORG&=C,R_#D7=9C13WHPG@RQ-$];HC.)CD%C?C/*:1@#$3\N(P M]YZ074!"_5?EEP%;?^8[4.O4J3VW]%1WH2:))5TT7=H-Z*N&1K%`5VS(JDX&.G\Y`*-[\VHW?JI.?5/?3SH;IAZ9UGU7 M>_C+C+,V*JP`OK/70SEV1S_^`7$<%D.\\>>I;I5&]K>#; M7`&EH@*-.CR'N,!7N=BJ(G&<*H0JD'H>C!S[V8/`6XU( MP>?$[<#C6,%-H)K#V[YA8^?;@$CJON'M;CL/+21Q72-"$TD[\HAL%PJTZ[YI M$\XI>-,WO5AN%3Q)%3S4G];K7GM6YZ%$V@PJWV9SA4AB+]WSRS/)-N!8FH*' M5CI1JE`O9NWDC;.N[2%T12<8V\+$>Q;I,$PEOLPV6VUF"X\))K<.V@(3[&[^ MH''N#J0N!0^""58W.^PWEA&/"E:WL`NA)0LA<$Q)&K=2@7P<%+'>[37_#,FZ MQB[,VF?MDX8V.SR3["XI3SJ)UJ*T@:CH1W#1VM M][]LZ6H'W&`>K5_/YD_+]7%&($]8R7+_.&7(BLNL*C*3'7U^.;[-LUFNS0B> M;B8_GQ\VJZDZNL8H"!6#WVF?2YIY]#CBSN!LQ1U_%=$P5=JS)<=230[B\'MV;A:_*THKVVS?[\;IS&8;;R MR>@0?A2V@.&N6)EKG`4%E<)@%5G'D44L*Z#W/(ZXW-@=^BZ&L&&[.(JO"_,K MD98PI`S+?.LZB@NS6D`''JQ-IFBV,K\7=N7I>S]0W*V7)S3: M"D25HT=R0AC4\11L4_NJ=:;@`/?UJ8.8QAE:Y/$4+*8=\GMZ&N98A4+IR1C- MN6U->TCGYVZ?/>M($GV@8Z/%=REQ!JY.&#W%XQ*HJ1R?I+[\Y/"P*VTCC7T= M%30V2-<)C48("4*_T7X("0+"#=7=<530>\I,.HK)0<4$OGW`%NZ&[N5J53&V M6PF4(XH;W9 M[?=9=[VPE4`0X@IKC9=+&P[8Y!$C,CJ>9UKG;OP3H MIHN%CC0-!;RKN!U=5[@+=TKZ_V=OX>`7^'+E+3Z^;-WZ2SN)G@!1W7$JJ7GN M?8;EQ)3GNMAI!L[W1T4GRK3`7OM[M#(W-)D;*!3FK]'$]S,T7&"+L[)UEPGX M5B]ZO@?F('2>0+8K7S!.06B5EM( M15%K9!X13`C$=JZW.RR(9;@R$@C]"D/;"AC"?6TN0-UR6QN,M+>S-D.#SC-` MN]MY(&[!46;?CO/_0%G0Z,&M[,&_8<(9?+$(@$WPER=+2`AFW\6HN`[*KD7W^Z?#^H]0&48`SBAIFST^_-RKIG`G:/!U9G?^ M9L%VZIZ)%VQ2X/FQ5V7<>B#@7#'RVKB"1'QJC$^%UH^5FRFD'*J"AE`[3B=& M:9RZ5(L!PDE9T,AZQ$`9WZ?+':9X<4KMCA_INCE8BR-AC9%>3M(4DACNH54A MP`G[=I>RG90P6J_D,V7,V'[34]D)$XDPT8+/GIA>OM M[#6$$S@>O2#66-1VC,WRPTD[%8YH"A->96O"31V9Z!A45Z&=CJ?056CW4UQ6 MZ_4.7:M[0@\03L[0(_1N)9E88@M+A#YT\-?KB]'0=:P[+I/>N`Y+[/F+B?TB MD>YIUZT!PC(<*MUKP\WZ6\D;,\!#V;3DV$#+M9`7T&%;HA>.3JLP;1S^T(AD_T,1V_`S7DS_=G[:KXF!2 M1[%!R:N_KK;I9E\VPN26PWS=E5520M]?'=:HVH'HZ)+QH*OR:'LJ)Q0OVD%W MNYU)4QQ3OER:A?X.8A?L:2/`!]A_I]^]?D)P`9$)*'#RKLH.ZO1VUJX?VYEW M4!23XKE=N1(<>RL>FJ@>[@WK-`?CGIR[A84%EW'-M.Z=035B4],LW!)71R`R@N[H:1[ M2?O/1&=T-3_PSJDC^$+.4A*QQ+29B^?G''O0MBAC&K^?T)4CG"5Y75VIYH+5 M%I7#:"5=(G0"T0