|
Эксперт Hardware
|
||||||||
FASM WinDBG - отладчик ядерного уровня10.05.2019, 13:12. Показов 19946. Ответов 7
**************************************** *************** Часть 1. Введение (в заблуждение). Проблема отладки приложений уходит корнями в DOS, где в нашем распоряжении имелся широкий набор инструментов: Soft-ICE, Turbo-Debugger, AVPUtil, CUP386, AFD-Pro, etc. Но вот пришла Win и всё изменилось. Старый софт оказался не у дел, хотя некоторые экземпляры всё-ещё упорно цепляются за жизнь и на данном витке эволюции удовлетворяют потребностям студентов и узкого круга бородатых прогеров. Защищённый режим прийти-то пришёл, только забыл принести с собой средства отладки и это не удивительно - на то он и защищённый, со-всеми вытекающими. Тут за дело взялись энтузиасты одним из которых стал Олег Ющук и мир увидел его отладчик "OllyDbg". Оля в полной мере оправдывает наши надежды выворачивая наизнанку все/тайные закрома исполняемого РЕ-файла, и имеет кучу доп.плагинов расширяющих стандартные её возможности. А что ещё нам нужно? На первый взгляд вроде ничего, только есть одна проблема! Это юзер/модный отладчик, для которого вход на ядерный уровень - закрыт. Да, он может показать нам Win32-API, стек и многое/другое. Однако в ядре хранится куча служебных структур прикладной задачи - вот где кроются все секреты! К сожалению, создать универсальный инструмент увы не получится, т.к. Win-приложения не могут работать на обоих уровнях сразу. Причиной тому - разграничение памяти на User и Kernel (ring-0/3), за правами доступа к которой на аппаратном уровне пристально следит сам процессор. В какой-то мере заполнил свободную нишу мега-отладчик "Soft-ICE", но его поддержка давно прекращена и в последний раз окно этого монстра видели счастливые обладатели систем WinXP-SP1. Так, все кодокопатели ядра дружненько пересели на WinDbg. Это детише мелкософта бурно развивается и на данный момент уверенно себя чувствует на всех/современных платформах, вплоть до 64-битной Win10. Как-правило, миграция от Оли к WinDbg для программистов проходит болезненно, но её можно сравнить с переходом из юношества во-взрослую жизнь. Огромное кол-во команд даёт нам полную свободу, хотя и требует взамен особой внимательности. Поскольку это отладчик уровня ядра, то функции Win-API уходят тут на второй план, а им взамен приходит Kernel-API со-своими параметрами. Это по-истине увлекательное путешествие "к центру вселенной", которое советую совершить каждому. Часть 2. Обзор и настройка интерфейса WinDBG. WinDBG входит в состав множества продуктов: SDK, DDK, WDF, а так-же поставляется как самостоятельный пакет "Debugging Tools for Windows" весом ~20 Мб. Причём версия из пакета обычно самая/свежая, и содержит наибольшее кол-во полезных расширений. После установки отладчика, нас встречает скудный фейс, чем-то напоминающий наскальные рисунки недочеловеков. Но не делайте преждевременных выводов! Возможности WinDBG намного больше, чем это кажется на первый взгляд, просто до них через интерфейсные штучки не подобраться. Попробуем перекроить дефолтный вид под себя, или воспользоваться уже имеющимися заготовками - т.н. Workspace (рабочее пространство) из папки %WinDbg%\themes. Для этого нужно проделать следующие шаги:
Судя по всему, WinDbg задумывался как инструмент для отладки драйверов, а всё/остальное прицепили к нему позже. Отладчик способен работать в трёх режимах, а текущий указывается в заголовке ком-строки (см.рис.выше). Последние/введённые команды запоминаются в кольцевом буфере, поэтому их не нужно вводить повторно - после ввода, следующий раз просто жмём Enter. Заголовок ком-строки характеризует следующее:
Отладочные символы. (инструкция к метле) Чтобы достойно принять на борт пассажира, нам нужно скачать "отладочные символы". Эти символы с расширением *.pdb хранятся на сервере Microsoft и позволяют "по отпечатку кода" придавать осмысленные имена функциям, безчисленному кол-ву служебных структур и т.п. При отсутсвии символов, в ответ на большинство команд WinDBG будет обкладывать нас трёхэтажным матом, употребляя при этом приблизительно такой лексикон (аж 13 повторений слова "symbol"):
Для настройки символов, запустим WinDBG в Kernel-режиме [Ctrl+K] и в появившемся окне перейдём на вкладку 'Local'. Теперь в окне менюшки "File-->Symbol_File_Path" прошьём путь до локального хранилища, и через разделитель(*) укажем дополнительный сервер символов Microsoft. В конечном итоге, адрес должен иметь следующий формат: SRV*C:\Program Files\Debugging Tools for Windows (x86)\sym*http://msdl.microsoft.com/download/symbols Если на данном этапе вы находитесь в On-line, то после нажатия ОК отладчик начнёт скачивать в своё/локальное хранилище символы основных файлов ядра - это 'ntoskrnl.exe' и 'ntdll.dll'. Для начала этого набора символов будет достаточно, а остальные будут загружаться по мере необходимости, о которой WinDBG будет сам нас оповещать:
lm (Load_Module). Если-же нужно сфокусировать своё внимание на "личном деле" конкретного модуля из списка, то используем многообещающую команду !lmi (Load_Module_Info) с указанием имени пациента. Кроме прочего, в логе будет строка "Symbol Type" где и указано, есть-ли символы в локальном хранилище для этого модуля, или их там нет (PDB not found). После скачивания символов, вы можете уйти в Off-line и продолжать дебажить уже вне сети:
.hh. Перед тем-как рваться в бой, имеет смысл ознакомится с основными командами отладчика, на специально посвящённом ему ресурсе windbg.info
3
|
||||||||
| 10.05.2019, 13:12 | |
|
Ответы с готовыми решениями:
7
Отладчик WinDBG Температура 6 ядерного i7 4930K
|
|
Эксперт Hardware
|
|||
| 12.05.2019, 15:54 [ТС] | |||
|
Часть 3. Связываем WinDBG и VirtualBox.
Не удивительно, что для отладки ядра Windows нужны две машины, поскольку большинство ядерных процессов локальной системы уже находятся в памяти, и Win блокирует к ним доступ. Тем-более из прикладного уровня в который мы только-что заселили WinDBG. В локальном режиме отладчик может лишь добывать информацию о системных процессах, но не отлаживать их. В этом деле нет обходных путей, если только ..винда сама этого не захочет! Изначально, эту "хотелку" прогеры Microsoft точили исключительно под себя, как технические люки из ринга(0) на ринг(3). В процессе отладки своего продукта им приходилось скакать по уровням в обоих направлениях, в результате чего система обзавелась т.н. "отладочным портом". Ничего лучше для этих целей и придумать не возможно. В наш век использовать пару физических компьютеров уже не обязательно - для этого есть виртуальные машины любой "ориентации". Лично меня, во-всех отношениях устраивает "VirtualBox", примеры на которой я и буду приводить. Однако это не обязывает вас ни к чему, и вы можете использовать привычную для машину типа VM-Ware, QEMU, Virtual-PC и другие. Просто по личному опыту могу сказать, что процесс отладки на связке VBox+WinDBG происходит быстрее, и не грузит процессор по самые помидоры. Систему, в ядро которой хотим проникнуть, ставим на виртуальную машину и будем называть её "Target" (целевая). WinDBG у нас под капотом реальной машины, к которой будем обращаться как "Host". Значит запускаем VirtualBox и топаем в её настройки. После того-как в разделе "COM-порт" создадим транспортный канал "Pipe", настройки виртуальной машины закончатся, не успев и начаться. Просто задайте их как на скрине, и всё: После этого, необходимо настроить на отладку и саму (установленную на Target) операционную систему. Запускаем её! ..и в корне диска C: открываем для редактирования файл-конфигурации загрузки "boot.ini" (у меня хрюша, а для обладателей Win7+ конфиг задаётся через оснастку "bcdedit"). Нужно сказать, что именно здесь зарыта та-самая "кнопка", которая заставит винду открыть для нас ворота в свою святая/святых - исполнительное ядро! (модуль Executive в ntoskrnl.exe). Дело в том, что мастдай может загружаться в нескольких режимах, типа "безопасный" и прочие (клавиша F8 после процедуры POST). Если посмотреть на этот лист, то в списке обнаружим и режим отладки "Debug-mode". В этом режиме, активируется специальная функция ядра, которая будет посылать отладчику сообщения по установленному нами пайпу (канал-хоста, см.рис.выше). При этом отладчик может фильтровать поступающие пакеты, отсеивая тем-самым неинформативные из них. Режим отладки включается всего одним ключом /debug в файле "boot.ini". После этого ключа нужно указать номер и скорость информационного порта. Для редактирования, мы просто делаем дубликат первой записи, и добавляем отладочные ключи как на рисунке ниже (выделены красным). После этих манипуляций, при загрузке получим окно с выбором режима - система должна сама дополнить нашу запись текстом (с отладчиком):На этом с виртуальной машиной покончено, и остаётся только настроить отладчик на хосте. Для этого запускаем WinDBG и комбинацией [Ctrl+K] выбираем режим его работы "Kernel". Отладчик отзывается окном, в котором просит задать параметры принимающего сообщения COM-порта. Не трудно догадаться, что здесь нужно ввести те-же данные, что и в настройках виртуальной машины: После всех телодвижений можно считать, что наши подопытные связяны между собой крепкими узами, разорвать которые в силах только "фильтр пакетов" отладчика. Установка связи между оппонентами должна происходить по следующей схеме.. Сначала запускаем ось на виртуальной машине и следом сразу отладчик (если сделать наоборот, отладчик не найдёт указанный в его настройках pipe). При этом, в окне отладчика должна красоваться надпись, которая характеризует правильные настройки портов на приёмо/передающих узлах:
Обязательным условием является то, что оси таргет и хост должны быть одинаковы. Теперь, перезагрузив отладочные символы (.reload) можно получить список активных процессов клиента, подключится к любому из них и отлаживать, погружаясь всё глубже в нёдра кода и ядерных структур.
2
|
|||
|
Эксперт Hardware
|
|||||||||||
| 14.05.2019, 15:01 [ТС] | |||||||||||
|
Часть 4. Системные механизмы
Особенности работы Win в режиме отладки Чтобы понять принцип работы отладчиков режима ядра, нужно рассмотреть исполняющую систему оси "Executive". Она занимает львиную долю Kernel-пространства и содержит различные сервисы ядерной инфраструктуры. Помимо прочего, в эти сервисы включена и поддержка отладки ядра, реализованная внутри системных библиотек dbgeng.dll и dbghelp.dll. На первый взгляд может показаться, что эти либы попали в систему при установке WinDBG, но это не так - начиная с ХР они изначально присутствуют в ней (посмотрите в свойствах дату создания/изменения). Если вскрыть в дизассемблере W32Dasm таблицу-экспорта этих длл, можно обнаружить там API, имена которых WinDBG использует непосредственно как свои/консольные команды! В частности, это уже знакомые нам lm/lmi/dh/sym. Следовательно, сам WinDbg - это только оболочка для отладки, с помощью системного движка:Кликните здесь для просмотра всего текста
Но это только вершина айсберга! К судьбе движка небезучастна и сама исполняющая система, зарытая глубоко в файлах ntoskrnl.exe и ntdll.dll. Её разбор на техническом языке займёт много времени, поэтому поставим архитектуру NT на детские рельсы и посмотрим на неё с другой стороны. Как юзер так и кернел-пространства можно логически разделить на две части - получили бутерброд из четырёх частей, где юзер-мода находится сверху, а кернел снизу. • В первой части юзера располагаются пользовательские программы, опирающиеся на библиотеки "user/kernel32.dll", а вторую часть занимает системная библиотека "Ntdll.dll". • В свою очередь, в пространстве кернела первая часть отводится под исполняющую систему "Ntoskrnl.exe", а нижняя - это слой абстракции от реального железа "Hal.dll" (хотя есть ещё и драйверы, которые стоят особняком). Благодаря Ntdll.dll наши программы могут переходить рубикон из юзера в кернел, сразу-же попадая в поле зрения ядра ntoskrnl. Здесь нужно отметить, что тушка файла ntoskrnl.exe разбита на два самостоятельных модуля - это непосредственно "Микроядро" (или гибридное ядро, что одно и тоже), и исполняющая система ядра "Executive": Если говорить про либу Ntdll, то она находится в пространстве юзера и содержит подмножество вспомогательных функций ядра таких-как: загрузчики образов программ с диска (префикс Ldr), диспетчер динамической памяти (префикс Mem), функции обмена данными между процессами подсистемы Win32 (префикс Csr), общие библиотеки времени выполнения (префикс Rtl), поддержку юзерской отладки (префикс DbgUi) и отслеживания событий Win (префикс Etw, эвенты). Кроме того, именно в её окопах залегли диспетчер асинхронных вызовов процедур (АРС) и диспетчер исключений пользовательского режима (SEH). Объектно-ориентированный подход В ОС класса Win вселенная вращается вокруг объектов, которыми управляет их диспетчер (см.рис.выше). Он создаёт объекты только для разделяемых ресурсов операционной системы, и если ресурс используется в рамках одного процесса, то назначать его в виде объекта не имеет смысла. Объектный подход позволяет в будующем добавлять ещё системных ресурсов, не переписывая при этом код самого ядра. В своём пространстве, система имеет каталог объектов, с под/каталогами для каждого типа объектов. При первом запуске системы, каталог пуст и заполняется он динамически, по мере обращения системы к различным/своим ресурсам. В качестве ресурсов могут выступать: процессы, потоки, файлы, устройства, события и всё/остальное. Пользователь может запросить у диспетчера создания индивидуального объекта, если его чем-то не устраивают системные. При этом юзер будет иметь родительские права на данный объект. С понятием "объект" тесно связан "дескриптор объекта" - система возвращает его нам в ответ, например, открытия файла. Всякий объект имеет одинаковый для всех "заголовок", где прописаны исчерпывающие характеристики данного объекта (его пасспорт). В момент, когда мы открываем файл, система создаёт дубликат своего объекта типа "File", и оформив его в виде дескриптора, вручает нам. Процедура оформления состоит из сброса/установки определённых полей в заголовке-объекта, исходя из наших привилегий в системе. При каждом открытии объекта, диспетчер увеличивает на 1 поле "счётчика дескрипторов". Соответственно, при каждом закрытии - уменьшает его на 1. Обнуление счётчика дескрипторов и счётчика списка-процессов означает, что объект никем более не используется и его можно удалить. Он отправляется к праотцам, с последующим удалением его имени из каталога объектов. Такой подход позволяет содержать таблицу объектов в компактном виде, динамически корректируя её в процессе работы системы. "Квота" представляет собой "откат", взимаемый с процесса за открытие объекта. Например, если диспетчер установил цену для объекта "File" в 2 шекеля (не знаю в каких попугаях она измеряется), а процесс принадлежит к заданию (Job) у которого в портмоне всего 10 шекелей, то суммарно все процессы этого Job'a смогут открыть не более 5-ти файлов. Так для объектов каждого типа устанавливаются ограничения на ресурсы. Весь пул объектов под названием "Пространство имён" отсортирован по "типам". Это означает, что у каждого типа объектов есть общие (для данного типа) свойства. Информация о типе выведена в отдельную структуру, членами которой являются "имя" и прочие (см.рис). Каждый объект указывает на свой "объект-типа". И наконец поля "методов" хранят указатели на обработчики стандартных операций, например open/close. Для просмотра таблицы-объектов Руссинович написал утилиту "WinObj". Однако переплюнул его знаменитый хакер Four-F, который внёс огромный вклад в область программирования и разработки драйверов. Его аналог называется "WinObjEx" (Object_Explorer) и вытягивает из системы намного больше информации, чем утилита Руссиновича: Как видим, в этой синагоге находятся множество объектов типа, но в контексте темы-отладки нас будут интересовать только два из них - объект PORT, и объект Debug. Мы вернёмся к ним позже (никогда), а пока посмотрим на описание каталогов в пространстве имён:
2
|
|||||||||||
|
Эксперт Hardware
|
||||||||||||||||||||||||||
| 18.05.2019, 18:04 [ТС] | ||||||||||||||||||||||||||
|
Собираем информацию об объектах приложения
Посмотрим, какую инфу о системных объектах может предоставить нам WinDbg.. Как упоминалось выше, у каждого объекта есть заголовок и тело. Диспетчер объектов управляет заголовками, а телами занимается Executive. В каждом заголовке объекта содержится индекс на структуру "объект-типа" (Object_Type), которая и характеризует тип объекта. Одной из незаменимых команд является dt (Display_Type), с помощью которой можно просмотреть буквально все/системные структуры. На вооружение нужно взять тот факт, что в WinDbg имена структур должны начинаться с подчёркивания, поскольку в системе они зарегистрированы именно в таком виде. Например, чтобы ознакомиться с членами структуры PEB, нужно ввести dt _peb, предварив её имя подчёркиванием. Кроме того, в некоторых структурах могут присутствовать члены, которые сами указывают на принадлежащие к данной структуре, вложенные структуры. Для рекурсивного обхода таких структур, команда "dt" имеет ключик "-r" (рекурсия, нет в документации). Справку по этой и другим командам из окна отладчика можно вызвать так: .hh dt, где dt является аргументом.Перед тем-как дать команду на отображение "dt", мы должны знать имя интересующей нас структуры. Нужно сказать, что общее кол-во структур в системе может в несколько раз превышать числа растительности на голове у некоторых из нас - как найти нужную? Оказывается очень просто! Достаточно указать в каком именно модуле exe/dll мы хотим произвести поиск, и подставить в качестве аргумента, обрамлённую символами(*) маску для поиска. В данном случае модуль будет Ntoskrnl (кличка "nt"), а маска - "_object". Вот пример:
По именам структур можно догадаться об их назначении. К примеру, в наличии имеются уже знакомые нам "_OBJECT_HEADER" (заголовок объекта) и "_OBJECT_TYPE" (выведенный в отдельную структуру, описатель типа объекта). Обратите внимание, что заголовок находится в пространстве кернела (nt!), а тип - отфутболен уже в пространство юзера (ntdll!). Как упоминалось выше, завершающий команду ключ(-r) позволяет сходу просмотреть и вложенные структуры:
Хорошо.. А что если нужно узнать, какие из системных объектов использует наше приложение? Для этого напишем подопытного кролика "Hello Word!", который сбоксит мессагу и будет ждать нажатия буттона "ОК" в своём окне. Наша задача, загрузить кролика в память и подключиться к его процессу через "Attach-to-Process" отладчика (клавиша F6). На этот момент системный загрузчик образов уже полностью проинициализирует все модули нашего приложения, и нам останется только снять с них скальп. В арсенале WinDbg есть команда !handle, которая допускает сл.аргументы: !handle ‹индекс_описателя› ‹флаги› ‹ID_процесса›Из курса начинающих программистов мы помним, что "Handle" (описатель) - это и есть дескриптор, а дескриптор в свою очередь формируется из заголовка объекта. То есть мы на правильном пути.. Индекс в команде определяет элемент в таблице дескрипторов (0 = вывод всех). Индекс первого =4, второго =8, и т.д. Например, введя !bandle 4, вы увидите первый дескриптор в текущем процессе. Кроме того, мы можем фильтровать вывод битовыми флагами: • 001b (1) = вывести лишь информацию из элемента таблицы; • 010b (2) = показать не только используемые, но и свободные описатели; • 100b (4) = сообщить информацию об объекте, на который ссылается описатель; • 111b (7) = выдать полную информацию!
Во-первых тут нужно запросить у системы список всех/текущих процессов в памяти, среди которых должен быть и наш "Hello World" (если мы не закрыли его MessageBox() кнопкой ОК). Если таковой присутствует в памяти, то нам потребуется его Cid - Client_ID, который подставляем как третий аргумент в команду !handle:
..заполненные заголовки объектов и прочие структуры можно выводить на экран следующим способом. Здесь адреса являются указателями - их и ждёт команда DisplayType:
1
|
||||||||||||||||||||||||||
|
Эксперт Hardware
|
||||||||||||||||||||||||||||||||||||
| 22.05.2019, 21:25 [ТС] | ||||||||||||||||||||||||||||||||||||
|
Диспетчер системных сервисов и таблица SSDT
В пользовательском пространстве обитает множество системных служб. Некоторые экземпляры запускаются из автозагрузки, некоторые простаивают, а некоторые вообще отключены админом. Чтобы ознакомиться с полным списком и состоянием каждой из них, достаточно запустить одноимённую оснастку через Win+R-->services.msc. Как видно из названия команды, синонимом слова "служба" является английское "servis". Если проштудировать имена этих служб, то можно обнаружить, что вся/эта шайка представляет из-себя сборище сервисов подсистемы окружения Win32. Кроме перечисленных, в системе имеется ещё вагон и целая тележка, только они не для домохозяек, под которых собственно и заточена Windows всех мастей. Системный диспетчер служб SCM (Service_Control_Management) умышленно скрывает от юзера жизненно/важные свои сервисы, чтобы обезопасить себя от любопытных глаз. Возьмём к примеру вызов функций Win32-API.. Каждая из этих функций тоже представляет собой определённый сервис, но зачем конечному пользователю знать о его существовании? Для юзера главное чтобы пимпа была красивой, и чтобы на её нажатие что-то происходило (кроме зависания машины). Вывод - система от нас явно что-то скрывает, и мы обязательно должны выяснить, что. Рассмотрим в подробностях, как происходят вызовы программного интерфейса API.. Для начала, чтобы создать общую картину, взглянем на табличку ниже, где представлена организация критически-важных файлов Win. Это данные, которые я собрал со-своей XP, так-что за остальные оськи не ручаюсь. Судя по всему, сервисы подсистемы Win32 не сильно обременяют себя работой, лишь изредка прибегая к чьим-либо услугам. Причём сами что-то конкретное делать упорно не хотят, т.к. не имеют в своих тушках ни одной/экспортируемой функции. Это типичные доносчики, которые только и "стучат" ядру о происходящих в пространстве юзера событиях. Другое дело Ntdll - заслуженный труженик, который не импортирует ни одного тушканчика, зато выдаёт на экспорт аж 1316 функций. Вот если-бы все так пахали! Но у каждой/положительной, есть и отрицательная сторона. Если размазать функции по-всем библиотекам, то получим винегрет и проблему переносимости системы, за что лентяи/программисты из Microsoft так крепко держатся. Для каждой/последующей системы Win7,8,10 пришлось-бы переписывать все системные файлы, а так - только парочку. Что касается библиотек x32, то дела здесь обстоят лучше. Они выполняют рутину по обслуживанию прихотей юзера - всякие окошки, менюшки, иконки, и прочая лабуда. А вот чего они не смогут сделать, так это создавать/завершать процессы, потоки, работать с файлами, etc.. Другими словами, юзер не может сам создавать системные объекты - для этого есть Executive, к которой рано или поздно нужно будет обратиться за помощью. Вот тут-то и начинается самое/интересное.. Защищённая подсистема Win32 работает в режиме пользователя, вызывая системный сервис NT для выполнения привилегированных действий в режиме ядра. Когда наше приложение вызывает какую-либо API, диспетчер анализирует запрос и выполняет его либо обращаясь к ядру, либо перенаправляя запрос библиотекам окружения Win32 (если это работа с плюшечками/дрюшечками). После завершения процедуры, приложение вручается мандат с результатами. Мы рассмотрим только механизм обращения программы к ядру, не затрагивая тему локальной обработки в юзер-моде. Для этого напишем всего одну строчку кода, которая закроет объект "Process" текущего приложения по ExitProcess(). Теперь загрузим это чудо в WinDbg по и поставим бряк на эту функцию:
ZwTerminateProcess() это лишь прелюдия. Шоу дельфинов начинается когда номер запроса помещается в EAX и управления принимает инструкция sysenter. Именно эта инструкция позволяет коду пользовательского режима перейти на ядерный уровень - других путей в этом лесу нет! Однако WinDbg не показывает нам, что происходит за кулисами sysenter, если только не заставить его этого сделать. Открыв толмут Intel vol.4 с описанием MSR-регистров мы обнаруживаем, что регистры с номерами: 174h, 175h, 176h хранят явный указатель, куда передаёт управление sysenter. Запросим их содержимое, после чего можно дизассемблировать код по указателю EIP:
KiSystemService(). В прямом подчинении этого диспетчера имеются две таблицы SSDT - System_Service_Descriptor_Table, одна из которых затенённая (shadow) и недоступна никому, кроме самого Ntoskrnl. Вторая - открытая, куда так и норовят пролезть руткины, для перехвата Kernel-API. Каждую из этих таблиц описывают свои структуры, но поскольку Shadow-таблица в два раза больше чем открытая, то и характеризующая её структура тоже в два раза больше. В первой части затенённой таблицы хранится точная копия открытой, а во-второй её части - хранятся поддерживающие работу с графикой нативные функции из win32k.sys. По своей природе, таблицы SSDT напоминают таблицу прерываний MS-DOS. В них отсортированы по именам все/имеющиеся kernel-API с указанием их точек-входа в функцию. В примере выше с ExitProcess() мы наблюдали, что перед вызовом sysenter в EAX кладётся значение 101h - это и есть порядковый номер ZwTerminateProcess() в таблице SSDT. Формат этих структур представлен ниже (почему-то WinDbg их не отображает):
Кроме того, в ntddk можно найти ещё одну структуру, которая описывает уже расположения таблиц SSDT в памяти:
Команда WinDbg с громким названием x позволяет искать по-маске функции в модулях. Для наших целей маска "KeServiceDescriptorTable" как-раз то, что доктор прописал. В качестве модуля укажем Ntoskrnl под кличкой "nt!" - пробуем..
Напомню, чтобы получить кол-во параметров функции, нужно каждый байт разделить на 4. В данном случае, байт по смещению(0) равен 18h, значит фрейм именно такого размера понадобится первой API из списка SSDT. Разделив 18h на 4 получим число её параметров = 6. Чтобы вывести дамп в байтах, вскормим консоль командой "db":
Если вы не в танке, и понимаете о чём я тут "пою серенады", то возможно зададитесь вопросом: -"А как насчёт вызова натива не из юзера, а из самого кенела ..например драйверами. Тут-же идёт прямой вызов без Sysenter?" Это будет заслуживающий аплодисментов стоя вопрос! Ради интриги, оставим его открытым - кому интересно, сам найдёт инфу, например у Руссиновича или ресурсах по борьбе с руткитами.
1
|
||||||||||||||||||||||||||||||||||||
|
Эксперт Hardware
|
||
| 22.05.2019, 22:33 [ТС] | ||
Сообщение было отмечено Mikl___ как решение
Решение
..и ещё. Поскольку ядро Ntoskrnl доверять свою работу никому не может (ниже только плинтус),
то все точки-входа в его функции должны находиться в одной базе 80000000h. Если при анализе адресов мы обнаружим выход за эту границу, то можем с чистой совестью утверждать, что в ядре завелися блохи и от них срочно нужно избавляться. Все аверки проверяют на руткиты именно таким образом:
1
|
||
|
Эксперт Hardware
|
|||||||||||||||||||||||||||||||
| 28.05.2019, 20:15 [ТС] | |||||||||||||||||||||||||||||||
|
Debug API, или что под капотом отладчиков
Обычно первое знакомство с отладчиками типа "OllyDbg" вызывает бурю эмоций. Цветочно-букетный период проходит гладко и мы всё/больше восхищаемся их возможностями. В этом деле огромную роль играет продуманный интерфейс, чего у Оли не отнять. Но задумывались-ли вы, какие шестерёнки приводят в действие этот шагающий экскаватор? В принципе, всё-что требуется от желающего написать юзермодный отладчик, это расставить под "правильным углом" его форточки и определиться, что именно он хотел-бы видеть в окне своего творения. На данный этап уходит больше времени, чем на процесс оформления полезного кода. Для остального Win имеет мощный, и в тоже время, очень простой "движок отладки". Его начинку составляет группа функций под общим названием Debug-API, оптом предлагающие нам услуги следующего характера:
Теперь распишем в красках общую картину.. Step 1. Начальный этап отладки Работа отладчиков основана на модели клиент-сервер, где в роли сервера выступает отладчик. Он выбирает в качестве жертвы другую программу, которую будем называть "клиент". Суть в том, что из своей тушки, отладчик должен запустить процесс клиента присвоив ему флаг DEBUG_PROCESS - на это способна функция CreateProcess(). Связанные с отладкой флаги этой API (из директории "fasm\include\equates\kernel32.inc") представлены ниже:
Обнаружив комбинацию этих флагов, система сразу-же "заморозит" основной поток клиента как-только он загрузится в память (Soft-Ice). С этого момента, клиент будет полностью под контролем отладчика, а его процесс будет считаться "отлаживаемым". Через системный порт-отладки клиент будет посылать отладчику сообщения, о происходящих в своей тушке событиях "Event". Step 2. Отладчик ждёт событий клиента Мы выяснили, что когда запускаем клиента или подключаемся к нему через DebugActiveProcess(), клиент впадает в спячку - это хорошо. Однако наш отладчик-то не спит и продолжает работать! Значит нужно заморозить и его поток, иначе он мухой отработает весь/свой код и просто закроется. Для этого, в движке-отладки имеется функция WaitForDebugEvent(), которая жонглирует объектом синхронизации "Event". Данная функция блокиpует отладчик до тех пор, пока клиент не пошлёт ему сообщение о каком-нибудь отладочном событии. Посмотpим на её прототип:
Кликните здесь для просмотра всего текста
Теперь у нас есть пауза, чтобы обработать событие клиента, и отобразить необходимую информацию в форточках своего отладчика. Step 3. Собираем информацию об отладочном событии Как-правило событием является Step с исключением 0x80000004 (int-1), но чтобы узнать наверняка, нужно извлечь код-события из структуры DEBUG_EVENT. Если вы используете предпочитаемый мною FASM, то по-умолчанию в его штанах нет инклуд со-структурами отладки (у masm'a они зашиты в windows.inc). Поэтому я создал свой "debug.inc" для фасма, который прицепил в скрепке. Внутри него вы найдёте структуру "DEBUGSTRUCT", куда клиент сбрасывает расширенную информацию о своём событии. Отладчик, который не отображает регистры отлаживаемой программы, никому не нужен - именно в этом его предназначение. Встроим такую возможностью, прибегнув к функции GetThreadContext(). У неё всего два параметра, один из которых отправляем, а во-второй получаем ответ. Хендл возвращает CreateProcess(), когда мы только открываем клиента, а вот контекст - требует пояснений:
Step 4. Возврат управления клиенту Один цикл работы отладчика заканчивается тем, что нужно пробудить спящий поток клиента, пнув его функцией ContinueDebugEvent(). Эта функция заставит клиента сделать один стэп, после которого клиент опять отправится в царство Морфея, и весь цикл-отладки вернётся на круги свои:
Когда обычная программа генерит Exception, его перехватывает системный "Диспетчер исключений". У него свои планы на обработку возникшей ситуации, от которых ничего/хорошего ждать не приходится - в большинстве случаях он прибивает процесс и всё. Однако бит гуманности у диспетчера всё-же присутствует, и он сначала пробует передать бразды в юзерский SEH-обработчик, и если такового не обнаруживает, тогда пиши-пропало. Аналогичную ситуацию мы наблюдаем и здесь.. Если в ответ на событие клиента "EXCEPTION_DEBUG_EVENT" функция ContinueDebug() возвратит клиенту "NOT_HANDLED" (исключение не обработано), то притаившийся в кустах диспетчер посчитает это как знак свыше, и сразу-же примется за обслуживание сам. Поэтому со-статусом "NOT_HANDLED" нужно быть аккуратней, ато клиент может зависнуть на одном исключении, и будет генерить его снова-и-снова. Нужно всегда проверять ExceptionCode в структуре "DEBUG_EVENT" и исходя из него возвращать клиенту тот или иной свой/статус.Среди исключений есть "EXCEPTION_BREAKPOINT" с кодом 80000003h. Это первое, что получит отладчик после запуска клиента на исполнение. В ответ на данное событие, отладчик в первый раз обязательно должен вернуть статус "DBG_CONTINUE", иначе система откажется запускать пpоцесс клиента, обращая в прах все/наши усилия. Следуюший "EXCEPTION_BREAKPOINT" можно уже обрабатывать на своё усмотрение, возвращая HANDLED или NOT_HANDLED соответственно. Пользовательский отладчик на практике Сухая теория до добра не доводит, но и без неё никак. Попробуем написать демонстрационный отладчик, чтобы так-сказать пощупать это дело руками. Я не буду изворачиваться тут на изнанку, а просто открою клиента, соберу о нём информацию, и тупо сбоксю её в мессагу. Выбирать клиента буду через системное окно выбора-файла функцией GetOpenFileName(), а для сбора информации о нём воспользуюсь GetThreadContext():
2
|
|||||||||||||||||||||||||||||||
|
Эксперт Hardware
|
|||||||||||||||||||||
| 01.06.2019, 10:38 [ТС] | |||||||||||||||||||||
|
Kernel Debug-API (или логово тираноидов)
Механизмы отладки радикально изменились в Win-XP. В то время, большинство функций из Ntoskrnl перекочевали в Ntdll, в результате чего пришлось переписать большую часть ядра. Связано это с тем, что начиная именно с ХР была напрочь искорена подсистема окружения OS/2, а в Win8 отказались и от POSIX. На данный момент, полным монополистом является только подсистема Win32. Cистемная поддержка отладки разбита на три уровня, и каждый/последующий использует функции предыдущих. По сути, есть только один ядерный движок "альфа-самец", а остальное - это его шлюзы, через которые юзер может использовать функции ядра. • Первый уровень расположен в исполняющей системе Ntoskrnl. Его Native-API имеют префикс Dbgk (фреймворк, среда отладки). Данный модуль предоставляет нам внутренние функции ядра для прослушивания событий отладчика (объект Event), управления объектом отладки "DebugPort", и упаковки информации для отправки её юзермодному отладчику:Список функций Dbgk
• Второй модуль расположен в Ntdll.dll в составе API с префиксом DbgUi. Эти API оборачивают в свой кокон основные функции выше, и позволяют приложениям Win32 использовать отладочные средства ядерного уровня:Функции DbgUi, Dbg
• Третий модуль принадлежит уже библиотекам подсистемы Win32. Это функции из Kernel32.dll, которые обслуживают юзера - они без префикса: Список пользовательских функций
В этих списках, перед именем указана точка-входа в функцию. Воспользовавшись этим адресом, мы можем дизассемблировать функцию командой(u), или собрать о ней информацию командой .fnent - function environment. Обратите внимание, что все функции с префиксом "Dbgk" находятся в пространстве ядра (адрес выше 0х80000000), в то время-как остальные болтаются в пространстве юзера (нижняя половина):
NT поддерживает отладку со времён своего "подгузничества", а в последующих выпусках добавляются всё/больше доп.функций. В частности, начиная с XP добавлены ещё 4 полезных API-интерфейса:
Система ХР содержит и несколько изменений базовой реализации. В ней отказались от устаревшего метода обмена сообщениями через вызов локальных процедур LPC, в пользу порта отладки "DebugPort". Работой LPC заправляет сервис "csrss.exe", но поскольку теперь он не имеет отношения к отладке, то появилась возможность дебажить и сам "csrss.exe" (раньше такой возможности не было). Структуры и описания ядерных функций можно найти в скрепке..
2
|
|||||||||||||||||||||
| 01.06.2019, 10:38 | |
|
Помогаю со студенческими работами здесь
8
Запуск 22-х ядерного процессора на одном ядре
Неполная загрузка 4-ядерного процессора, Canopus Procoder3. Энергия πи-мезонов (кванты ядерного поля)
Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
| Опции темы | |
|
|
Новые блоги и статьи
|
|||
|
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд.
Даже если у вас. . .
|
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает
монорепозиторий в котором находятся все исходники.
При создании нового решения, мы просто добавляем нужные проекты
и имеем. . .
|
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение:
В этой книге («Подход, основанный на вариантах использования») Ивар утверждает,
что архитектура программного обеспечения — это
структуры,. . .
|
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога
Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
|
|
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога
Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip
На первой гифке отладочные линии отключены, а на второй включены:. . .
|
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога
Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем.
. . .
|
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
|
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
|