<?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-3359491729754373146</id><updated>2012-02-20T02:38:31.345-08:00</updated><category term='C++'/><category term='setup'/><category term='ndis'/><category term='synthetic symbols'/><category term='debugEvent'/><category term='boost::python'/><category term='howto'/><category term='windbg extensions'/><category term='kernel'/><category term='qt'/><category term='release'/><category term='pyside'/><category term='API'/><category term='samples'/><title type='text'>Python windbg extension</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://pykd.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://pykd.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Pykd Maintainer</name><uri>http://www.blogger.com/profile/17452890529873583715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>24</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3359491729754373146.post-3206998400493263334</id><published>2012-02-06T00:24:00.000-08:00</published><updated>2012-02-06T00:24:37.570-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='boost::python'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>Обработка исключений в Boost.Python</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Мы в нашем проекте стараемся использовать исключения для сигнализации об ошибках. Почему? Причин несколько: удобно при отладке - если что-то пошло не так, мы сразу видим где и что произошло и можем перейти непосредственно к исправлению ошибки не теряя времени на отладку; пользователю приходится быть более дисциплинированным - ведь исключение нельзя проигнорировать, в отличие от проверки возвращаемого значения; удобно при разработке - вместо прокидывания кода ошибки через все функции, мы просто кидаем исключение, которое к тому же может быть гораздо информативнее. В результате, мы верим, что весь комплекс pykd + скрипт становится надежным инструментом.&lt;br /&gt;&lt;br /&gt;Но разберемся, как же исключения попадают из С++ кода, написанного с помощью Boost::Python в виртуальную машину Python? Будем двигаться итеративно.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Итерация 0: Генерируем python исключение&lt;/h3&gt;Сгенерировать исключение в ВМ python просто. Для этого служит функция &lt;b&gt;&lt;i&gt;PyErr_SetString&lt;/i&gt;&lt;/b&gt;. В нее нужно передать указатель на тип исключения и сторку с описанием ошибки. Например так:&lt;br /&gt;&lt;pre style="background: #ffffff; color: black;"&gt;PyErr_SetString&lt;span style="color: #808030;"&gt;(&lt;/span&gt; PyExc_IndexError&lt;span style="color: #808030;"&gt;,&lt;/span&gt; &lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;Index out of range&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;Не очень то удобно использовать эту конструкцию внтури С++ кода. Хотелось бы кидать С++ исключение и чтобы оно волшебным образом превращалось в python исключение. К счастью, boost::python предоставляет эту возможность.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Итерация 1: транслируем исключение из C++ в python&lt;/h3&gt;В общем все довольно просто. Любое исключение, возникшее во время выполнения python программы внутри модуля, использующего boost::python отлавливается. Существует механизм, с помощью которого можно поучаствовать в обработке такого исключения. Для этого необходимо зарегистрировать функцию-транслятор с помощью вызова register_exception_translator. Вот как это делается:&lt;br /&gt;&lt;br /&gt;&lt;pre style="background: #ffffff; color: black;"&gt;&lt;span style="color: dimgrey;"&gt;// класс исключения, для использования в C++ коде&lt;/span&gt;&lt;br /&gt;class PyException &lt;span style="color: purple;"&gt;:&lt;/span&gt; public std&lt;span style="color: purple;"&gt;::&lt;/span&gt;exception&lt;br /&gt;&lt;span style="color: purple;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #e34adc;"&gt;public:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    PyException&lt;span style="color: #808030;"&gt;(&lt;/span&gt; PyObject&lt;span style="color: #808030;"&gt;*&lt;/span&gt;  pyObj&lt;span style="color: #808030;"&gt;,&lt;/span&gt; &lt;span style="color: maroon; font-weight: bold;"&gt;const&lt;/span&gt; std&lt;span style="color: purple;"&gt;::&lt;/span&gt;string &lt;span style="color: #808030;"&gt;&amp;amp;&lt;/span&gt;desc &lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;span style="color: purple;"&gt;:&lt;/span&gt;&lt;br /&gt;        std&lt;span style="color: purple;"&gt;::&lt;/span&gt;exception&lt;span style="color: #808030;"&gt;(&lt;/span&gt; desc&lt;span style="color: #808030;"&gt;.&lt;/span&gt;c_str&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt;&lt;br /&gt;        m_typeObj&lt;span style="color: #808030;"&gt;(&lt;/span&gt; pyObj &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: purple;"&gt;{&lt;/span&gt;&lt;span style="color: purple;"&gt;}&lt;/span&gt;    &lt;br /&gt;&lt;br /&gt;    &lt;span style="color: maroon; font-weight: bold;"&gt;static&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: maroon; font-weight: bold;"&gt;void&lt;/span&gt;&lt;br /&gt;    exceptionTranslate&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;const&lt;/span&gt; PyException &lt;span style="color: #808030;"&gt;&amp;amp;&lt;/span&gt;e &lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;span style="color: purple;"&gt;{&lt;/span&gt;&lt;br /&gt;        PyErr_SetString&lt;span style="color: #808030;"&gt;(&lt;/span&gt; e&lt;span style="color: #808030;"&gt;.&lt;/span&gt;m_typeObj&lt;span style="color: #808030;"&gt;,&lt;/span&gt; e&lt;span style="color: #808030;"&gt;.&lt;/span&gt;what&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: purple;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #e34adc;"&gt;private:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    PyObject&lt;span style="color: #808030;"&gt;*&lt;/span&gt;       m_typeObj&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple;"&gt;}&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;void&lt;/span&gt; myFunc&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;span style="color: purple;"&gt;{&lt;/span&gt;&lt;br /&gt;    throw PyException&lt;span style="color: #808030;"&gt;(&lt;/span&gt; PyExc_IndexError&lt;span style="color: #808030;"&gt;,&lt;/span&gt; &lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;Index out of range&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;BOOST_PYTHON_MODULE&lt;span style="color: #808030;"&gt;(&lt;/span&gt; my_module &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple;"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: dimgrey;"&gt;// регистрируем транслятор&lt;/span&gt;&lt;br /&gt;    boost&lt;span style="color: purple;"&gt;::&lt;/span&gt;python&lt;span style="color: purple;"&gt;::&lt;/span&gt;register_exception_translator&lt;span style="color: #808030;"&gt;&amp;lt;&lt;/span&gt;PyException&lt;span style="color: #808030;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #808030;"&gt;(&lt;/span&gt; &lt;span style="color: #808030;"&gt;&amp;amp;&lt;/span&gt;PyException&lt;span style="color: purple;"&gt;::&lt;/span&gt;exceptionTranslate &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: dimgrey;"&gt;// функция, вызываемая из python программы&lt;/span&gt;&lt;br /&gt;    boost&lt;span style="color: purple;"&gt;::&lt;/span&gt;python&lt;span style="color: purple;"&gt;::&lt;/span&gt;def&lt;span style="color: #808030;"&gt;(&lt;/span&gt; &lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;myFunc&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt; &lt;span style="color: #808030;"&gt;&amp;amp;&lt;/span&gt;myFunc &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Прекрасно, генерировать исключения python теперь удобно. Но я хочу использовать собственный тип исключений. Возможно ли это? В общем да...&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Итерация 2: Использование собственного типа исключений.&lt;/h3&gt;&lt;br /&gt;Идея простая. Boost::python дает возможность импортировать типы в python программу. Наш план таков: импортируем тип в python, регистрируем функцию-транслятор С++ исключения и в коде функции-трансялтора используем наш тип исключения, который мы ранее импортировали ( и запомнили! ) в python. &lt;br /&gt;&lt;pre style="background: #ffffff; color: black;"&gt;&lt;span style="color: dimgrey;"&gt;// класс исключения, для использования в C++ коде&lt;/span&gt;&lt;br /&gt;class MyException &lt;span style="color: purple;"&gt;:&lt;/span&gt; public std&lt;span style="color: purple;"&gt;::&lt;/span&gt;exception&lt;br /&gt;&lt;span style="color: purple;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #e34adc;"&gt;public:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    MyException &lt;span style="color: #808030;"&gt;(&lt;/span&gt; &lt;span style="color: maroon; font-weight: bold;"&gt;const&lt;/span&gt; std&lt;span style="color: purple;"&gt;::&lt;/span&gt;string &lt;span style="color: #808030;"&gt;&amp;amp;&lt;/span&gt;desc &lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;span style="color: purple;"&gt;:&lt;/span&gt;&lt;br /&gt;        std&lt;span style="color: purple;"&gt;::&lt;/span&gt;exception&lt;span style="color: #808030;"&gt;(&lt;/span&gt; desc&lt;span style="color: #808030;"&gt;.&lt;/span&gt;c_str&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: purple;"&gt;{&lt;/span&gt;&lt;span style="color: purple;"&gt;}&lt;/span&gt;    &lt;br /&gt;&lt;br /&gt;    &lt;span style="color: maroon; font-weight: bold;"&gt;static&lt;/span&gt; &lt;span style="color: maroon; font-weight: bold;"&gt;void&lt;/span&gt; setTypeObject&lt;span style="color: #808030;"&gt;(&lt;/span&gt;PyObject &lt;span style="color: #808030;"&gt;*&lt;/span&gt;p&lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;span style="color: purple;"&gt;{&lt;/span&gt;&lt;br /&gt;        exceptTypeObject &lt;span style="color: #808030;"&gt;=&lt;/span&gt; p&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;        python&lt;span style="color: purple;"&gt;::&lt;/span&gt;register_exception_translator&lt;span style="color: #808030;"&gt;&amp;lt;&lt;/span&gt;MyException&lt;span style="color: #808030;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #808030;"&gt;(&lt;/span&gt; &lt;span style="color: #808030;"&gt;&amp;amp;&lt;/span&gt;exceptionTranslate &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: purple;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #e34adc;"&gt;private:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;   &lt;span style="color: maroon; font-weight: bold;"&gt;static&lt;/span&gt; PyObject  &lt;span style="color: #808030;"&gt;*&lt;/span&gt;exceptTypeObject&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: maroon; font-weight: bold;"&gt;static&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: maroon; font-weight: bold;"&gt;void&lt;/span&gt;&lt;br /&gt;    exceptionTranslate&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;const&lt;/span&gt; MyException &lt;span style="color: #808030;"&gt;&amp;amp;&lt;/span&gt;e &lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;span style="color: purple;"&gt;{&lt;/span&gt;&lt;br /&gt;        boost&lt;span style="color: purple;"&gt;::&lt;/span&gt;python&lt;span style="color: purple;"&gt;::&lt;/span&gt;object  pyExcept&lt;span style="color: #808030;"&gt;(&lt;/span&gt;e&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;        PyErr_SetObject&lt;span style="color: #808030;"&gt;(&lt;/span&gt; exceptTypeObject &lt;span style="color: #808030;"&gt;,&lt;/span&gt; pyExcept&lt;span style="color: #808030;"&gt;.&lt;/span&gt;ptr&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: purple;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple;"&gt;}&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;void&lt;/span&gt; myFunc&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;span style="color: purple;"&gt;{&lt;/span&gt;&lt;br /&gt;    throw MyException&lt;span style="color: #808030;"&gt;(&lt;/span&gt; &lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;Something's wrong&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;BOOST_PYTHON_MODULE&lt;span style="color: #808030;"&gt;(&lt;/span&gt; my_module &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple;"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: dimgrey;"&gt;// функция, вызываемая из python программы&lt;/span&gt;&lt;br /&gt;    boost&lt;span style="color: purple;"&gt;::&lt;/span&gt;python&lt;span style="color: purple;"&gt;::&lt;/span&gt;def&lt;span style="color: #808030;"&gt;(&lt;/span&gt; &lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;myFunc&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt; &lt;span style="color: #808030;"&gt;&amp;amp;&lt;/span&gt;myFunc &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: dimgrey;"&gt;// регистрирем тип исключения и его транслятор&lt;/span&gt;&lt;br /&gt;    MyException&lt;span style="color: purple;"&gt;::&lt;/span&gt;setTypeObject&lt;span style="color: #808030;"&gt;(&lt;/span&gt; &lt;br /&gt;        boost&lt;span style="color: purple;"&gt;::&lt;/span&gt;python&lt;span style="color: purple;"&gt;::&lt;/span&gt;class_&lt;span style="color: #808030;"&gt;&amp;lt;&lt;/span&gt;MyException&lt;span style="color: #808030;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #808030;"&gt;(&lt;/span&gt; &lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;MyException&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt; &lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;MyException error&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;ptr&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Вот на этом мы могли бы остановиться. Могли бы, если бы мир был совершенен. На самом деле, после чуть более тщательного тестирования, мы приходим к заключению, что работают наши исключения не совсем верно. А именно:&lt;br /&gt;не работает инструкция raise MyException - вместо генерации исключения обозначенного типа генерирует питоновское исключение, общий смысл которого в двух словах сводится к тому, что тип MyException не пригоден для генерации исключений. Вторая проблема заключается в том, что при попытке сделать иерархию исключений мы сталкиваемся с тем, что неверно работает фильтрация исключений, а именно: инструкция except BaseException не ловит исключения дочерних типов. Короче говоря, имплементация наших исключений весьма далека не только от идеала, но и просто от обычных python исключений. Будем разбираться.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Итерация 3: разбираемся&lt;/h3&gt;Изучив внимательно текст ошибки при попытке возбудить исключение raise MyExceptionException. Кроме того, тут надо сделать небольшой ( самостоятельный ;) ) экскурс в анатомию питонов и изучить вопрос о типах и метатипах. Если в двух словах, то тип в питоне - это такой же объект и ,соответственно, может быть динамически создан вызовом конструктора у некого типа. Вот этот "некий" тип и является метатипом. Покопавшись внутрях boost::python можно придти к заключению, что все типы, которые он импортирует, создаются через один и тот же метаттип. В итоге наш MyException имеет метатип такой же, как и другие типы, импортированные из boost::python. И он не имеет родственных связей с типами питоновских исключений. А это негативно влияет на обработку исключений питоном. Наш дальнейший план каким-то образом унаследовать MyException от питоновского типа Exception. Как же это сделать то????&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Итерация 4: Как же это сделать то????&lt;/h3&gt;Делать то нечего, приходится отказаться от регистрации типов исключений через бустовый class_. Подсмотрев в его исходники, находим место, где создается новый питоновский тип и переписываем его примерно так:&lt;br /&gt;&lt;br /&gt;&lt;pre style="background: #ffffff; color: black;"&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;using&lt;/span&gt; boost&lt;span style="color: purple;"&gt;::&lt;/span&gt;python&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: dimgrey;"&gt;// Базовым типом у нас будет PyExc_Exception&lt;/span&gt;&lt;br /&gt;handle&lt;span style="color: purple;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: purple;"&gt;&amp;gt;&lt;/span&gt;   basedtype &lt;span style="color: #808030;"&gt;=&lt;/span&gt; handle&lt;span style="color: purple;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: purple;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #808030;"&gt;(&lt;/span&gt;PyExc_Exception&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: dimgrey;"&gt;// Всякий объект в питоне имеет свой список свойств&lt;/span&gt;&lt;br /&gt;dict       ob_dict&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;ob_dict&lt;span style="color: #808030;"&gt;[&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;__doc__&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: #808030;"&gt;]&lt;/span&gt; &lt;span style="color: #808030;"&gt;=&lt;/span&gt; &lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;MyException&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: dimgrey;"&gt;// Объект в питоне кстате может иметь много пап. Но у нас будет один - самый лучший! &lt;/span&gt;&lt;br /&gt;tuple      ob_bases &lt;span style="color: #808030;"&gt;=&lt;/span&gt; make_tuple&lt;span style="color: #808030;"&gt;(&lt;/span&gt; basedtype &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: dimgrey;"&gt;// Вот тут весь оргазм: &lt;/span&gt;&lt;br /&gt;&lt;span style="color: dimgrey;"&gt;// Py_TYPE(basedtype.get()) - вернет нам тип от объекта PyExc_Exception. Тип типа - это метатип, мы это выясняли&lt;/span&gt;&lt;br /&gt;&lt;span style="color: dimgrey;"&gt;// object( boost::python::handle&amp;lt;&amp;gt;(Py_TYPE(basedtype.get()) ) ) - это будет у нас объект меаттипа&lt;/span&gt;&lt;br /&gt;&lt;span style="color: dimgrey;"&gt;// Что такоей вызов SomeType( a, b, c) ? - это конструирование объекта этого типа&lt;/span&gt;&lt;br /&gt;&lt;span style="color: dimgrey;"&gt;// Теперь собираем пазл во-едино: мы создаем новый тип, который имеет такой же метатип как и PyExc_Exception&lt;/span&gt;&lt;br /&gt;&lt;span style="color: dimgrey;"&gt;// и является наследником PyExc_Exception&lt;/span&gt;&lt;br /&gt;object     ob &lt;span style="color: #808030;"&gt;=&lt;/span&gt; object&lt;span style="color: #808030;"&gt;(&lt;/span&gt; boost&lt;span style="color: purple;"&gt;::&lt;/span&gt;python&lt;span style="color: purple;"&gt;::&lt;/span&gt;handle&lt;span style="color: purple;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: purple;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #808030;"&gt;(&lt;/span&gt;Py_TYPE&lt;span style="color: #808030;"&gt;(&lt;/span&gt;basedtype&lt;span style="color: #808030;"&gt;.&lt;/span&gt;get&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;(&lt;/span&gt; &lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;MyException&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt; ob_bases&lt;span style="color: #808030;"&gt;,&lt;/span&gt; ob_dict &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: dimgrey;"&gt;// остается пристроить новорожденного в приличное место, а именно в скоуп модуля&lt;/span&gt;&lt;br /&gt;scope&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;attr&lt;span style="color: #808030;"&gt;(&lt;/span&gt; &lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;MyException&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;span style="color: #808030;"&gt;=&lt;/span&gt; ob&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Теперь остается привести все в божеский вид.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Итерация 5: божеский вид&lt;/h3&gt;Для приведения в божеский вид нам надо написать какой то шаблон, по своим функциям хоть чуть-чуть напоминающий class_. Как минимум, хочется наследования, пусть даже не множественного. В результате, родился такой вот шаблон. Он далек от изящества к сожалению, но у него доброе сердце )).&lt;br /&gt;&lt;br /&gt;&lt;pre style="background: #ffffff; color: black;"&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;template&lt;/span&gt;&lt;span style="color: purple;"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color: maroon; font-weight: bold;"&gt;class&lt;/span&gt; TExcept &lt;span style="color: purple;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;struct&lt;/span&gt; exceptPyType&lt;span style="color: purple;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;     &lt;span style="color: maroon; font-weight: bold;"&gt;static&lt;/span&gt; python&lt;span style="color: purple;"&gt;::&lt;/span&gt;handle&lt;span style="color: purple;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: purple;"&gt;&amp;gt;&lt;/span&gt;     pyExceptType&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: purple;"&gt;}&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;template&lt;/span&gt;&lt;span style="color: purple;"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color: maroon; font-weight: bold;"&gt;class&lt;/span&gt; TExcept&lt;span style="color: #808030;"&gt;,&lt;/span&gt; &lt;span style="color: maroon; font-weight: bold;"&gt;class&lt;/span&gt; TBaseExcept &lt;span style="color: #808030;"&gt;=&lt;/span&gt; python&lt;span style="color: purple;"&gt;::&lt;/span&gt;detail&lt;span style="color: purple;"&gt;::&lt;/span&gt;not_specified &lt;span style="color: purple;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;class&lt;/span&gt; &lt;span style="color: #603000;"&gt;exception&lt;/span&gt;  &lt;span style="color: purple;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;public&lt;/span&gt;&lt;span style="color: #e34adc;"&gt;:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #603000;"&gt;exception&lt;/span&gt;&lt;span style="color: #808030;"&gt;(&lt;/span&gt; &lt;span style="color: maroon; font-weight: bold;"&gt;const&lt;/span&gt; &lt;span style="color: #666616;"&gt;std&lt;/span&gt;&lt;span style="color: purple;"&gt;::&lt;/span&gt;&lt;span style="color: #603000;"&gt;string&lt;/span&gt;&lt;span style="color: #808030;"&gt;&amp;amp;&lt;/span&gt; className&lt;span style="color: #808030;"&gt;,&lt;/span&gt; &lt;span style="color: maroon; font-weight: bold;"&gt;const&lt;/span&gt; &lt;span style="color: #666616;"&gt;std&lt;/span&gt;&lt;span style="color: purple;"&gt;::&lt;/span&gt;&lt;span style="color: #603000;"&gt;string&lt;/span&gt;&lt;span style="color: #808030;"&gt;&amp;amp;&lt;/span&gt; classDesc &lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;br /&gt;    &lt;span style="color: purple;"&gt;{&lt;/span&gt;&lt;br /&gt;        python&lt;span style="color: purple;"&gt;::&lt;/span&gt;handle&lt;span style="color: purple;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: purple;"&gt;&amp;gt;&lt;/span&gt;   basedtype&lt;span style="color: purple;"&gt;;&lt;/span&gt;      &lt;br /&gt;&lt;br /&gt;        &lt;span style="color: maroon; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #808030;"&gt;(&lt;/span&gt; boost&lt;span style="color: purple;"&gt;::&lt;/span&gt;is_same&lt;span style="color: purple;"&gt;&amp;lt;&lt;/span&gt;TBaseExcept&lt;span style="color: #808030;"&gt;,&lt;/span&gt; python&lt;span style="color: purple;"&gt;::&lt;/span&gt;detail&lt;span style="color: purple;"&gt;::&lt;/span&gt;not_specified&lt;span style="color: purple;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: purple;"&gt;::&lt;/span&gt;value &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: purple;"&gt;{&lt;/span&gt;&lt;br /&gt;            basedtype &lt;span style="color: #808030;"&gt;=&lt;/span&gt; python&lt;span style="color: purple;"&gt;::&lt;/span&gt;handle&lt;span style="color: purple;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: purple;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #808030;"&gt;(&lt;/span&gt;PyExc_Exception&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: purple;"&gt;}&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: maroon; font-weight: bold;"&gt;else&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: purple;"&gt;{&lt;/span&gt;&lt;br /&gt;            basedtype &lt;span style="color: #808030;"&gt;=&lt;/span&gt; exceptPyType&lt;span style="color: purple;"&gt;&amp;lt;&lt;/span&gt;TBaseExcept&lt;span style="color: purple;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: purple;"&gt;::&lt;/span&gt;pyExceptType&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: purple;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        python&lt;span style="color: purple;"&gt;::&lt;/span&gt;dict       ob_dict&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;       &lt;br /&gt;        ob_dict&lt;span style="color: #808030;"&gt;[&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;__doc__&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: #808030;"&gt;]&lt;/span&gt; &lt;span style="color: #808030;"&gt;=&lt;/span&gt; classDesc&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        python&lt;span style="color: purple;"&gt;::&lt;/span&gt;tuple      ob_bases &lt;span style="color: #808030;"&gt;=&lt;/span&gt; python&lt;span style="color: purple;"&gt;::&lt;/span&gt;make_tuple&lt;span style="color: #808030;"&gt;(&lt;/span&gt; basedtype &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        python&lt;span style="color: purple;"&gt;::&lt;/span&gt;object     ob &lt;span style="color: #808030;"&gt;=&lt;/span&gt; python&lt;span style="color: purple;"&gt;::&lt;/span&gt;object&lt;span style="color: #808030;"&gt;(&lt;/span&gt; python&lt;span style="color: purple;"&gt;::&lt;/span&gt;handle&lt;span style="color: purple;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: purple;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #808030;"&gt;(&lt;/span&gt;Py_TYPE&lt;span style="color: #808030;"&gt;(&lt;/span&gt;basedtype&lt;span style="color: #808030;"&gt;.&lt;/span&gt;get&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;(&lt;/span&gt; className&lt;span style="color: #808030;"&gt;,&lt;/span&gt; ob_bases&lt;span style="color: #808030;"&gt;,&lt;/span&gt; ob_dict &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        python&lt;span style="color: purple;"&gt;::&lt;/span&gt;scope&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;attr&lt;span style="color: #808030;"&gt;(&lt;/span&gt; className&lt;span style="color: #808030;"&gt;.&lt;/span&gt;c_str&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;span style="color: #808030;"&gt;=&lt;/span&gt; ob&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        exceptPyType&lt;span style="color: purple;"&gt;&amp;lt;&lt;/span&gt;TExcept&lt;span style="color: purple;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: purple;"&gt;::&lt;/span&gt;pyExceptType &lt;span style="color: #808030;"&gt;=&lt;/span&gt; python&lt;span style="color: purple;"&gt;::&lt;/span&gt;handle&lt;span style="color: purple;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: purple;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #808030;"&gt;(&lt;/span&gt; ob&lt;span style="color: #808030;"&gt;.&lt;/span&gt;ptr&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        python&lt;span style="color: purple;"&gt;::&lt;/span&gt;register_exception_translator&lt;span style="color: purple;"&gt;&amp;lt;&lt;/span&gt;TExcept&lt;span style="color: purple;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #808030;"&gt;(&lt;/span&gt; &lt;span style="color: #808030;"&gt;&amp;amp;&lt;/span&gt;exceptionTranslate &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: purple;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: maroon; font-weight: bold;"&gt;static&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: maroon; font-weight: bold;"&gt;void&lt;/span&gt;&lt;br /&gt;    exceptionTranslate&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;const&lt;/span&gt; TExcept &lt;span style="color: #808030;"&gt;&amp;amp;&lt;/span&gt;e &lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;span style="color: purple;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        python&lt;span style="color: purple;"&gt;::&lt;/span&gt;object      exceptObj &lt;span style="color: #808030;"&gt;=&lt;/span&gt; python&lt;span style="color: purple;"&gt;::&lt;/span&gt;object&lt;span style="color: #808030;"&gt;(&lt;/span&gt; exceptPyType&lt;span style="color: purple;"&gt;&amp;lt;&lt;/span&gt;TExcept&lt;span style="color: purple;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: purple;"&gt;::&lt;/span&gt;pyExceptType &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;(&lt;/span&gt; e&lt;span style="color: #808030;"&gt;.&lt;/span&gt;what&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        PyErr_SetObject&lt;span style="color: #808030;"&gt;(&lt;/span&gt; exceptPyType&lt;span style="color: purple;"&gt;&amp;lt;&lt;/span&gt;TExcept&lt;span style="color: purple;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: purple;"&gt;::&lt;/span&gt;pyExceptType&lt;span style="color: #808030;"&gt;.&lt;/span&gt;get&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt; exceptObj&lt;span style="color: #808030;"&gt;.&lt;/span&gt;ptr&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: purple;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: purple;"&gt;}&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Но со стороны описания модуля выглядит все не так уж и плохо:&lt;br /&gt;&lt;br /&gt;&lt;pre style="background: #ffffff; color: black;"&gt;BOOST_PYTHON_MODULE&lt;span style="color: #808030;"&gt;(&lt;/span&gt; mymodule &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple;"&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: #603000;"&gt;exception&lt;/span&gt;&lt;span style="color: purple;"&gt;&amp;lt;&lt;/span&gt;MyException&lt;span style="color: purple;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #808030;"&gt;(&lt;/span&gt; &lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;MyException&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt; &lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;description&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: #603000;"&gt;exception&lt;/span&gt;&lt;span style="color: purple;"&gt;&amp;lt;&lt;/span&gt;MyExceptionEx&lt;span style="color: #808030;"&gt;,&lt;/span&gt;MyException&lt;span style="color: purple;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #808030;"&gt;(&lt;/span&gt; &lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;MyExceptionEx&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt; &lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;description&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h3&gt;Заключение&lt;/h3&gt;Почему же нам пришлось прибегать к таким извращениям? Очевидно, что boost::python далек от совершенства )). Чего же в нем не хватает? Было бы классно, если бы существовала форма функции class_, позволяющая задать базовый класс через указатель на питоноский тип. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&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/3359491729754373146-3206998400493263334?l=pykd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pykd.blogspot.com/feeds/3206998400493263334/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://pykd.blogspot.com/2012/02/boostpython.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/3206998400493263334'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/3206998400493263334'/><link rel='alternate' type='text/html' href='http://pykd.blogspot.com/2012/02/boostpython.html' title='Обработка исключений в Boost.Python'/><author><name>Pykd Maintainer</name><uri>http://www.blogger.com/profile/17452890529873583715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3359491729754373146.post-4863066490681770535</id><published>2011-12-16T05:06:00.000-08:00</published><updated>2011-12-16T06:15:17.027-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='release'/><title type='text'>Новая линейка Pykd 0.1.x доступна для тестирования</title><content type='html'>Хочу представить вам новую, кардинально переработанную версию pykd.&lt;br /&gt;&lt;br /&gt;Страница для закачки: &lt;a href="http://pykd.codeplex.com/releases/view/78902"&gt;download&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Сейчас ветка 0.1.x находится в статусе альфа и имеет ряд недоделок, которые будут постепенно устраняться. Мы очень надеемся, чтои вы найдете время протестировать новую версию и сообщить нам свое мнение о новом функционале и найденных ошибках. Это позволит быстрее довести продукт до стабильного состояния.&lt;br /&gt;&lt;br /&gt;Основные фичи новой ветки:&lt;br /&gt;1) Работа с символами через библиотеку MS DIA. Это позволило реализовать доступ к битовым полям, типам-энумераторам, работать с многомерными массивами и указателями на массивы&lt;br /&gt;2) Доступ к DIA выведен в интерфейс для Python. Так что можно работать с отладочной информацией самостоятельно&lt;br /&gt;3) Поддерживается работа с несколькими клиентами одновременно, т.е. можно из одного скрипта управлять отладкой нескольких приложений или систем.&lt;br /&gt;4) Несколько изменен API&lt;br /&gt;5) Для windbg команда !pycmd предоставляет теперь полноценную консоль python, идентичную стандартной. Для команды !py улучшен вывод информации об ошибках, в том числе синтаксических&lt;br /&gt;&lt;br /&gt;Повторю еще раз, нам очень нужены ваши отзывы, в первую очередь по API. Так как мы отказались от полной обратной совместимости с предыдущей версией, мы сейчас имеем возможность исправить API и сделать его более понятным и удобным. &lt;br /&gt;&lt;br /&gt;Дальнейший план развития такой:&lt;br /&gt;Ветка 0.0.x больше развиваться не будет, будем только фиксить баги и, возможно, что-то потом интегрируем из 0.1.x. &lt;br /&gt;&lt;br /&gt;Спасибо, что используете наш продукт :).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3359491729754373146-4863066490681770535?l=pykd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pykd.blogspot.com/feeds/4863066490681770535/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://pykd.blogspot.com/2011/12/pykd-01x.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/4863066490681770535'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/4863066490681770535'/><link rel='alternate' type='text/html' href='http://pykd.blogspot.com/2011/12/pykd-01x.html' title='Новая линейка Pykd 0.1.x доступна для тестирования'/><author><name>Pykd Maintainer</name><uri>http://www.blogger.com/profile/17452890529873583715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3359491729754373146.post-2593039509095230881</id><published>2011-10-10T01:06:00.000-07:00</published><updated>2011-10-10T01:56:56.339-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='samples'/><category scheme='http://www.blogger.com/atom/ns#' term='debugEvent'/><category scheme='http://www.blogger.com/atom/ns#' term='howto'/><title type='text'>Обработка исключений и точек останова</title><content type='html'>В &lt;a href="http://pykd.blogspot.com/2011/10/release-0020.html"&gt;&lt;span style="font-weight:bold;"&gt;pykd&lt;/span&gt; v. 0.0.20&lt;/a&gt; появился новый полезный функционал: обработка исключений и точек останова. Возможность обработки этих событий реализована новыми методами класса &lt;a href="http://pykd.codeplex.com/wikipage?title=pykd_api_eng&amp;referringTitle=Documentation#debugEvent"&gt;debugEvent&lt;/a&gt;: &lt;span style="font-weight:bold;"&gt;onBreakpoint&lt;/span&gt; и &lt;span style="font-weight:bold;"&gt;onException&lt;/span&gt;. Для использования этого функционала, как и в случае &lt;a href="http://pykd.blogspot.com/2011/05/blog-post.html"&gt;с событиями загрузки/выгрузки модулей&lt;/a&gt;, необходимо реализовать свои вышеописанные обработчики. Сведения о произошедшем событии передаются в эти методы словарями, ключи и типы значений которых указаны в документации. Следует отметить, что для события срабатывания точки останова количество сформированных пар, может быть меньше, чем описано: если точка останова не обладает каким-либо свойством, данные не заносятся в словарь. А состав словаря, передаваемого в обработчик исключения, более стабилен: варьируется только список параметров исключения. Но даже, если у исключения нет параметров, то в словаре все равно окажется список, который будет пуст.&lt;br /&gt;&lt;br /&gt;У &lt;span style="font-weight:bold;"&gt;pykd&lt;/span&gt; уже был класс &lt;a href="http://pykd.codeplex.com/wikipage?title=pykd_api_eng&amp;referringTitle=Documentation#bp"&gt;bp&lt;/a&gt;, который позволяет ставить/снимать точку останова и назначать собственный обработчик. Этот класс так остался, так как имеет более простой интерфейс, но он был расширен новым конструктором, в который передается только целевой адрес. При установке такой точки, вместо вызова обработчика просто возвращается статус &lt;span style="font-weight:bold;"&gt;DEBUG_STATUS_BREAK&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Новый функционал debugEvent::&lt;span style="font-weight:bold;"&gt;onBreakpoint&lt;/span&gt; реализован не как замена, а как альтернатива существующему механизму. То есть в одном и том же скрипте можно использовать как механизм bp, так и переопределение метода debugEvent::onBreakpoint. Это было сделано для того, что бы можно было управлять исключениями и точками останова из одного класса - debugEvent.&lt;br /&gt;&lt;br /&gt;Мы достаточно мало освещаем тот факт, что pykd не только расширение к WinDbg, но и полноценный модуль для языка python, который позволяет получить доступ к API Debug Engine. Поэтому пример использования обработки исключений будет нацелен именно на такой подход: &lt;a href="https://pykd.svn.codeplex.com/svn/samples/watchDog.py"&gt;samples\watchDog.py&lt;/a&gt;. В начале скрипт, если переданы аргументы командной строки, стартует указанный отлаживаемый процесс. Затем он ставит обработчик исключения и ожидает возникновения исключения. Но это так же полноценный скрипт для &lt;span style="font-weight:bold;"&gt;pykd&lt;/span&gt;, функционирующего как расширение WinDbg. Например, при вызове из WinDbg можно не указывать параметров, тогда скрипт будет следить за исключениями на отлаживаемом объекте.&lt;br /&gt;&lt;br /&gt;Важной особенностью логики скрипта является пропуск исключений, для которых FirstChance == True. Это необходимо для того, что бы пропускать исключения, которые возможно будут обработаны самим отлаживаемым объектом, например если исключение произошло в блоке SEH'а.&lt;br /&gt;&lt;br /&gt;Теперь запускаем скрипт командной строкой "python watchDog.py test.exe". Тем самым pykd от лица процесса python.exe создаст отлаживаемый процесс test.exe, который запустится на исполнение с предварительно установленным обработчиком исключений. В test.exe специально был включен следующий код:&lt;br /&gt;&lt;br /&gt;&lt;pre style='color:#000000;background:#ffffff;'&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;__try&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt; &lt;span style='color:#808030; '&gt;*&lt;/span&gt;&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;char&lt;/span&gt; &lt;span style='color:#808030; '&gt;*&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#008c00; '&gt;0&lt;/span&gt; &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#008c00; '&gt;1&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt; &lt;span style='color:#800080; '&gt;}&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;__except&lt;/span&gt;&lt;span style='color:#808030; '&gt;(&lt;/span&gt;EXCEPTION_EXECUTE_HANDLER&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#808030; '&gt;*&lt;/span&gt;&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;char&lt;/span&gt; &lt;span style='color:#808030; '&gt;*&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#008c00; '&gt;3&lt;/span&gt; &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#008c00; '&gt;1&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Результат исполнения скрипта следующий:&lt;br /&gt;&lt;br /&gt;*** shit happens&lt;br /&gt;Exception code : EXCEPTION_ACCESS_VIOLATION&lt;br /&gt;Exception flags : 0&lt;br /&gt;Exception record : 0x0&lt;br /&gt;Exception address : 0x40122C(00401010) test!main+0x21c | (00401250) test!Define_the_symbol__ATL_MIXED::Thank_you::Thank_you&lt;br /&gt;&lt;br /&gt;Parameters :&lt;br /&gt; 0x1&lt;br /&gt; 0x3&lt;br /&gt;&lt;br /&gt;eax=00000000 ebx=0018fa64 ecx=00000000 edx=00000000 esi=00401222 edi=00000000eip=774c15ee esp=0018fa50 ebp=0018ff40 iopl=0 nv up ei pl zr na pe nccs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246ntdll!ZwRaiseException+0x12:774c15ee 83c404 add esp,4&lt;br /&gt;&lt;br /&gt;ChildEBP RetAddr Args to Child&lt;br /&gt;0018ff40 004017f3 00000001 00302330 00302370 ntdll!ZwRaiseException+0x120018ff88&lt;br /&gt;76ae339a 7efde000 0018ffd4 774d9ed2 test!__tmainCRTStartup+0xfb0018ff94&lt;br /&gt;774d9ed2 7efde000 62b6a849 00000000 kernel32!BaseThreadInitThunk+0x120018ffd4&lt;br /&gt;774d9ea5 0040184a 7efde000 ffffffff ntdll!RtlInitializeExceptionChain+0x630018ffec&lt;br /&gt;00000000 0040184a 7efde000 00000000 ntdll!RtlInitializeExceptionChain+0x36&lt;br /&gt;&lt;br /&gt;Как видно по второму параметру исключения (адрес памяти - 0x3) скрипт поймал именно необрабатываемое исключение: использования неверного указателя *(char *)3 = 1. Если включить дополнительную трассировку (например, вывод в консоль) для FirstChance == True, то можно увидеть, что onException срабатывает 3-а раза, первые 2-а из которых игнорируются, так как могут быть обработаны отлаживаемым объектом.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3359491729754373146-2593039509095230881?l=pykd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pykd.blogspot.com/feeds/2593039509095230881/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://pykd.blogspot.com/2011/10/debug-engine-handling-exceptions-and.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/2593039509095230881'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/2593039509095230881'/><link rel='alternate' type='text/html' href='http://pykd.blogspot.com/2011/10/debug-engine-handling-exceptions-and.html' title='Обработка исключений и точек останова'/><author><name>Alexey R. aka EreTIk</name><uri>http://www.blogger.com/profile/15766287755602837701</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-80Zoj-o50bI/TmEmoHunebI/AAAAAAAAAAk/pPu-sdWg0U8/s220/X-COM-128.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3359491729754373146.post-7660199647367186018</id><published>2011-10-09T22:39:00.000-07:00</published><updated>2011-10-09T22:39:23.068-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='release'/><title type='text'>Release 0.0.20</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Всем доброго дня! Спешу представить очередной релиз &lt;b&gt;pykd&lt;/b&gt; - версия 0.0.20.&lt;br /&gt;&lt;br /&gt;Для тех, кто предпочитает словам дела, страница &lt;a href="http://pykd.codeplex.com/releases/view/73451"&gt;загрузки&lt;/a&gt; и удачи в использовании! Я же хотел кратко пробежаться по составу релиза:&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Управление отладчиком:&lt;/h3&gt;&lt;br /&gt;Добавлены следующие функции: &lt;i&gt;breakin&lt;/i&gt;, &lt;i&gt;attachProcess&lt;/i&gt;, &lt;i&gt;attachKernel&lt;/i&gt;, &lt;i&gt;debuggerPath&lt;/i&gt;&lt;br /&gt;Наличие функции &lt;i&gt;breakin&lt;/i&gt; позволяет написать с помощью &lt;b&gt;pykd&lt;/b&gt; свой отладчик. А функции &lt;i&gt;attachProcess&lt;/i&gt; и &lt;i&gt;attachKernel&lt;/i&gt; в этом помогут ( напомню, что ранее уже были реализованы функции &lt;i&gt;loadDump&lt;/i&gt; и &lt;i&gt;createProcess&lt;/i&gt; ).&lt;br /&gt;&lt;br /&gt;Функция &lt;i&gt;debuggerPath&lt;/i&gt; возвращает полный путь к исполняемому модулю программы, использующей &lt;b&gt;pykd&lt;/b&gt;. Если вы, к примеру, захотите модифицировать файл symsrv.ini - она может быть полезна.&lt;br /&gt;&lt;br /&gt;В ближайшее время мы опубликуем тутор по разработке отладчика на PySide. Следите за блогом!&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;класс cpuReg &lt;/h3&gt;&lt;br /&gt;Дополнен такой казалось бы малозначительной деталью, как конструктор с параметром "индекс регистра". Это позволяет реализовать перечисление всех регистров CPU:&lt;br /&gt;&lt;pre style="background: #ffffff; color: black;"&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;def&lt;/span&gt; getRegisterSet&lt;span style="color: #808030;"&gt;(&lt;/span&gt;self&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;:&lt;/span&gt;&lt;br /&gt;    regSet&lt;span style="color: #808030;"&gt;=&lt;/span&gt;&lt;span style="color: #808030;"&gt;[&lt;/span&gt;&lt;span style="color: #808030;"&gt;]&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: maroon; font-weight: bold;"&gt;try&lt;/span&gt;&lt;span style="color: #808030;"&gt;:&lt;/span&gt;&lt;br /&gt;        i &lt;span style="color: #808030;"&gt;=&lt;/span&gt; &lt;span style="color: #008c00;"&gt;0&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: maroon; font-weight: bold;"&gt;while&lt;/span&gt; &lt;span style="color: #e34adc;"&gt;True&lt;/span&gt;&lt;span style="color: #808030;"&gt;:&lt;/span&gt;&lt;br /&gt;            reg &lt;span style="color: #808030;"&gt;=&lt;/span&gt; pykd&lt;span style="color: #808030;"&gt;.&lt;/span&gt;cpuReg&lt;span style="color: #808030;"&gt;(&lt;/span&gt;i&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;            regSet&lt;span style="color: #808030;"&gt;.&lt;/span&gt;append&lt;span style="color: #808030;"&gt;(&lt;/span&gt;reg&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;            i &lt;span style="color: #808030;"&gt;+&lt;/span&gt;&lt;span style="color: #808030;"&gt;=&lt;/span&gt; &lt;span style="color: #008c00;"&gt;1&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: maroon; font-weight: bold;"&gt;except&lt;/span&gt; pykd&lt;span style="color: #808030;"&gt;.&lt;/span&gt;BaseException&lt;span style="color: #808030;"&gt;:&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: maroon; font-weight: bold;"&gt;pass&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: maroon; font-weight: bold;"&gt;return&lt;/span&gt; regSet&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h3&gt;класс typedVar&lt;/h3&gt;&lt;br /&gt;Добавлен конструктор, принимающий имя переменной нужного типа. При этом сам тип указывать не надо, он будет взят из отладочной информации. Т.е достаточно написать:&lt;br /&gt;var = typedVar( myModule.myVar )&lt;br /&gt;&lt;br /&gt;Это особенно удобно при работе с переменными, тип которых заранее не известен. Например, с шаблонами С++. &lt;br /&gt;&lt;br /&gt;&lt;h3&gt;класс disasm&lt;/h3&gt;&lt;br /&gt;Добавлен метод &lt;i&gt;assembly&lt;/i&gt;, позволяющий изменять код по укзанному ( по умолчанию: по текущему ) смещению:&lt;br /&gt;&lt;pre style="background: #ffffff; color: black;"&gt;nt &lt;span style="color: #808030;"&gt;=&lt;/span&gt; loadModule&lt;span style="color: #808030;"&gt;(&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"nt"&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;dasm &lt;span style="color: #808030;"&gt;=&lt;/span&gt; disasm&lt;span style="color: #808030;"&gt;(&lt;/span&gt; nt&lt;span style="color: #808030;"&gt;.&lt;/span&gt;NtCreateFile &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;dasm&lt;span style="color: #808030;"&gt;.&lt;/span&gt;assembly&lt;span style="color: #808030;"&gt;(&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"int 3"&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h3&gt;getProcessorType&lt;/h3&gt;&lt;br /&gt;Возвращает тип процессора. Функция вернет строку, описывающую тип физического процессора. Сравните с &lt;i&gt;getProcessorMode&lt;/i&gt;, которая возвращает текущий режим. Вот так, к примеру, можно было бы реализовать команду !sw из стандартного расширения wow64ext:&lt;br /&gt;&lt;pre style="background: #ffffff; color: black;"&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;if&lt;/span&gt; getProcessorType&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;span style="color: #808030;"&gt;=&lt;/span&gt;&lt;span style="color: #808030;"&gt;=&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"X64"&lt;/span&gt;&lt;span style="color: #808030;"&gt;:&lt;/span&gt;&lt;br /&gt;  setProcessorMode&lt;span style="color: #808030;"&gt;(&lt;/span&gt; &lt;span style="color: purple;"&gt;{&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"X64"&lt;/span&gt;&lt;span style="color: #808030;"&gt;:&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"X86"&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"X86"&lt;/span&gt;&lt;span style="color: #808030;"&gt;:&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"X64"&lt;/span&gt;&lt;span style="color: purple;"&gt;}&lt;/span&gt;&lt;span style="color: #808030;"&gt;[&lt;/span&gt; getProcessorMode&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;span style="color: #808030;"&gt;]&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h3&gt;багфикс&lt;/h3&gt;&lt;br /&gt;&lt;strike&gt;9219&lt;/strike&gt;: улучшена поддержка многопоточности. Функции, которые могут надолго заблокировать исполнение python программы ( такие как go() и dbgCommand() ) сохраняют состояние потока, что позволяет планировщику python выполнять код в других потоках&lt;br /&gt;&lt;br /&gt;&lt;strike&gt;9518&lt;/strike&gt;: Исправлен баг с выводом текста через команду dprint(ln). До этого текст, содержащий символ '%' выводился неправильно ( обычно, обрезался ).&lt;br /&gt;&lt;br /&gt;&lt;strike&gt;9555&lt;/strike&gt;: Метод name() класса dbgModuleClass возвращал строку, содержащую нулевой символ. В итоге при использовании данного метода вывод мог повреждаться ( обрезаться )&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3359491729754373146-7660199647367186018?l=pykd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pykd.blogspot.com/feeds/7660199647367186018/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://pykd.blogspot.com/2011/10/release-0020.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/7660199647367186018'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/7660199647367186018'/><link rel='alternate' type='text/html' href='http://pykd.blogspot.com/2011/10/release-0020.html' title='Release 0.0.20'/><author><name>Pykd Maintainer</name><uri>http://www.blogger.com/profile/17452890529873583715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3359491729754373146.post-4076586124903105186</id><published>2011-07-29T00:03:00.000-07:00</published><updated>2011-07-29T00:43:31.886-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='release'/><title type='text'>Release 0.0.19</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Представляем ( не без затаенной гордости конечно ) очередной&lt;a href="http://pykd.codeplex.com/releases/view/70821"&gt; релиз pykd 0.0.19&lt;/a&gt;. Мы немного запоздали по срокам выпуска, надеемся на ваше понимание. И так, что новенького:&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Доработан интерфейс для windbg&lt;/h4&gt;&lt;br /&gt;!pycmd теперь поддерживает многострочный ввод. Пробуем:&lt;br /&gt;&lt;pre&gt;kd&amp;gt;!pycmd&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt;def hello():&lt;br /&gt;...    print "hello"&lt;br /&gt;...&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt;hello()&lt;br /&gt;hello&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;!py и !pycmd выводят теперь traceback при возникновении исключения при исполнении. Надеемся, это сделает отладку скриптов чуть-чуть удобнее.&lt;br /&gt;&lt;br /&gt;Кстати, про исключения. В предыдущем релизе ( 0.0.18 ) был реализован механизм трансляции ошибок pykd в исключения python. В этом релизе мы провели рефакторинг некоторых модулей. Будьте готовы, что функции ранее возвращавшие 0, None или "" будут кидать исключение и некоторые скрипты перестанут работать. Возможно, вас утешит, что обработка ошибок через обработку исключений сделает код в итоге более надежным и понятным ( положа руку на сердце, это конечно спорный момент или, как минимум, обсуждаемый ). &lt;br /&gt;&lt;br /&gt;&lt;h4&gt;class disasm&lt;/h4&gt;&lt;br /&gt;Это дизассемблер. Конечно не полноценный, он не разбирает инструкции на операнды. Тем не менее, простые задачи ему вполне по силам. Пользоваться просто:&lt;br /&gt;&lt;pre&gt;kd&amp;gt;!pycmd&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt;nt = loadModule("nt")&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt;da = disasm( nt.ZwCreateFile )&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt;print da.next()&lt;br /&gt;804fd55d 8d542404        lea     edx,[esp+4]&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt;print da.next()&lt;br /&gt;804fd561 9c              pushfd&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt;print da.next()&lt;br /&gt;804fd562 6a08            push    8&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt;print da.next()&lt;br /&gt;804fd564 e8e8f00300      call    nt!KiSystemService (8053c651)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h4&gt;Прочее:&lt;/h4&gt;&lt;br /&gt;&lt;b&gt;setMSR&lt;/b&gt; - функция меняет значение MSR регистра.&lt;br /&gt;&lt;br /&gt;классу &lt;b&gt;typedVar&lt;/b&gt; добавили метод &lt;b&gt;data&lt;/b&gt;, возвращающий данные в виде питоновской строки. Такую строку можно обработать например с помощью ctypes или записать в файл&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Фиксы:&lt;/h4&gt;&lt;br /&gt;&lt;i&gt;issue 8655&lt;/i&gt; &lt;br /&gt;Игнорировались поля безымянных структур и объединений. Теперь - не игнорируются.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;issue 8927&lt;/i&gt;&lt;br /&gt;Если поле структуры имеет перечисляемый тип, то узнать его числовое значение нельзя. Т.е конечно можно с помощью такого трика:&lt;br /&gt;val = ptrDword( structVar.enumField.getAddress() )&lt;br /&gt;Хорошая новость, теперь можно писать:&lt;br /&gt;val = structVar.enumField&lt;br /&gt;Плохая новость: предыдущий трик перестал работать, потому что у типа long нет метода getAddress().&lt;br /&gt;Но не все уж так плохо: в настоящий релиз вошел класс intBase, позволяющий включать его в операции с целыми числами. В следующей версии мы планируем переделать класс typedVar и хранить атрибуты, представляющие целые числа и указатели, в объектах-наследниках типа intBase. Это, к примеру позволит обращаться не только к членам структуры, но также и к данным, доступным по указателям. Короче говоря, планов много, будем стараться их осуществить.&lt;br /&gt;&lt;br /&gt;В заключение хотел напомнить: Друзья, у вас все еще есть блестящая возможность поучаствовать в разработке pykd. Очень нужны: С++ кодер - для работы с ядром pykd, python кодер - для разработки тестов ( у нас есть тесты! целых два!!! ), python кодер - для разработки библиотеки, русско-англо-xxx-язычный технический писатель. &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3359491729754373146-4076586124903105186?l=pykd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pykd.blogspot.com/feeds/4076586124903105186/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://pykd.blogspot.com/2011/07/release-0019.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/4076586124903105186'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/4076586124903105186'/><link rel='alternate' type='text/html' href='http://pykd.blogspot.com/2011/07/release-0019.html' title='Release 0.0.19'/><author><name>Pykd Maintainer</name><uri>http://www.blogger.com/profile/17452890529873583715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3359491729754373146.post-2081540250340580066</id><published>2011-06-22T06:18:00.000-07:00</published><updated>2011-06-22T06:18:55.964-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><title type='text'>Qt: "A QApplication instance already exists"</title><content type='html'>Не так давно мы &lt;a href="http://pykd.blogspot.com/2011/03/pysidepykd-qt-windbg.html"&gt;публиковали&lt;/a&gt; пример графического плагина на основе связки Qt и PySide. Использование графического интерфейса предоставляет широчайшие возможности. К сожалению, приведенный код содержал один существенный недостаток: при повторном запуске скрипта появлялось сообщение: "A QApplication instance already exists". &lt;br /&gt;&lt;br /&gt;Чтобы избежать этого, нужно совсем чуть-чуть переработать процедуру инициализации Qt. А именно: проверить существование синглтона QApplication c помощью вызова QCoreApplication::instance()&lt;br /&gt;&lt;br /&gt;Таким образом, прототип расширения для windbg c графическим интерфейсом мог бы выглядеть примерно так:&lt;br /&gt;&lt;br /&gt;&lt;pre style='color:#000000;background:#ffffff;'&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;from&lt;/span&gt; PySide&lt;span style='color:#808030; '&gt;.&lt;/span&gt;QtCore &lt;span style='color:#800000; font-weight:bold; '&gt;import&lt;/span&gt; &lt;span style='color:#808030; '&gt;*&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;from&lt;/span&gt; PySide&lt;span style='color:#808030; '&gt;.&lt;/span&gt;QtGui &lt;span style='color:#800000; font-weight:bold; '&gt;import&lt;/span&gt; &lt;span style='color:#808030; '&gt;*&lt;/span&gt;              &lt;br /&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;class&lt;/span&gt; MainForm&lt;span style='color:#808030; '&gt;(&lt;/span&gt; QDialog &lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;:&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span style='color:#800000; font-weight:bold; '&gt;def&lt;/span&gt; &lt;span style='color:#e34adc; '&gt;__init__&lt;/span&gt;&lt;span style='color:#808030; '&gt;(&lt;/span&gt; self &lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;:&lt;/span&gt;&lt;br /&gt;        QDialog&lt;span style='color:#808030; '&gt;.&lt;/span&gt;&lt;span style='color:#e34adc; '&gt;__init__&lt;/span&gt;&lt;span style='color:#808030; '&gt;(&lt;/span&gt; self&lt;span style='color:#808030; '&gt;,&lt;/span&gt; &lt;span style='color:#e34adc; '&gt;None&lt;/span&gt; &lt;span style='color:#808030; '&gt;)&lt;/span&gt;            &lt;br /&gt;        self&lt;span style='color:#808030; '&gt;.&lt;/span&gt;setWindowTitle&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;"Hello"&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;      &lt;br /&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;def&lt;/span&gt; main&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;:&lt;/span&gt;      &lt;br /&gt;&lt;br /&gt;    app &lt;span style='color:#808030; '&gt;=&lt;/span&gt; QCoreApplication&lt;span style='color:#808030; '&gt;.&lt;/span&gt;instance&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style='color:#800000; font-weight:bold; '&gt;if&lt;/span&gt; app &lt;span style='color:#808030; '&gt;=&lt;/span&gt;&lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#e34adc; '&gt;None&lt;/span&gt;&lt;span style='color:#808030; '&gt;:&lt;/span&gt;&lt;br /&gt;        app &lt;span style='color:#808030; '&gt;=&lt;/span&gt; QApplication&lt;span style='color:#808030; '&gt;(&lt;/span&gt; &lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt; &lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    mainForm &lt;span style='color:#808030; '&gt;=&lt;/span&gt; MainForm&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;br /&gt;    mainForm&lt;span style='color:#808030; '&gt;.&lt;/span&gt;show&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;br /&gt;    exitres &lt;span style='color:#808030; '&gt;=&lt;/span&gt; app&lt;span style='color:#808030; '&gt;.&lt;/span&gt;exec_&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;if&lt;/span&gt; &lt;span style='color:#e34adc; '&gt;__name__&lt;/span&gt; &lt;span style='color:#808030; '&gt;=&lt;/span&gt;&lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#0000e6; '&gt;"__main__"&lt;/span&gt;&lt;span style='color:#808030; '&gt;:&lt;/span&gt;&lt;br /&gt;    main&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&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/3359491729754373146-2081540250340580066?l=pykd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pykd.blogspot.com/feeds/2081540250340580066/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://pykd.blogspot.com/2011/06/qt-qapplication-instance-already-exists.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/2081540250340580066'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/2081540250340580066'/><link rel='alternate' type='text/html' href='http://pykd.blogspot.com/2011/06/qt-qapplication-instance-already-exists.html' title='Qt: &quot;A QApplication instance already exists&quot;'/><author><name>Pykd Maintainer</name><uri>http://www.blogger.com/profile/17452890529873583715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3359491729754373146.post-5938682362773428428</id><published>2011-05-26T06:08:00.000-07:00</published><updated>2011-09-05T05:22:58.595-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='debugEvent'/><category scheme='http://www.blogger.com/atom/ns#' term='API'/><category scheme='http://www.blogger.com/atom/ns#' term='howto'/><title type='text'>Обработка событий загрузки и выгрузки модулей отлаживаемой системы</title><content type='html'>&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;Одно из нововведений релиза &lt;strong&gt;pykd 0.0.18&lt;/strong&gt; это базовый класс для обработки событий от Debug Engine. В текущей версии реализованы только события загрузки и выгрузки модулей. Об этом было рассказано в &lt;a href="http://pykd.blogspot.com/2011/05/release-0018.html"&gt;обзоре релиза&lt;/a&gt;.&lt;br /&gt;Реализация сделана через базовый класс &lt;a href="http://pykd.codeplex.com/wikipage?title=pykd_api_eng&amp;amp;referringTitle=Documentation#debugEvent"&gt;debugEvent&lt;/a&gt;, реализация которого расположена в модуле pykd. Для обработки соответствующего события необходимо написать свой класс, в котором переопределить методы onLoadModule(...) или onUnloadModule(...), в зависимости от того, какие события необходимо обрабатывать. Входным параметром для этих методов выступает экземпляр класса загруженного модуля &lt;a href="http://pykd.codeplex.com/wikipage?title=pykd_api_eng&amp;amp;referringTitle=Documentation#dbgModuleClass"&gt;dbgModuleClass&lt;/a&gt;.&lt;br /&gt;В качестве демонстрации этого функционала рассмотрим  часть скрипта &lt;a href="https://pykd.svn.codeplex.com/svn/samples/goLoad.py"&gt;samples\goLoad.py&lt;/a&gt;:&lt;/div&gt;&lt;pre style="background: rgb(255, 255, 255); color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;from&lt;/span&gt; pykd &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48);"&gt;*&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;import&lt;/span&gt; fnmatch&lt;br /&gt;&lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;import&lt;/span&gt; sys&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;class&lt;/span&gt; loadHandler&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;debugEvent&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;  def&lt;/span&gt; &lt;span style="color: rgb(227, 74, 220);"&gt;__init__&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;self&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; mask&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;:&lt;/span&gt;&lt;br /&gt;  debugEvent&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;&lt;span style="color: rgb(227, 74, 220);"&gt;__init__&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;self&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;   &lt;/span&gt;self&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;mask &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; mask&lt;/pre&gt;&lt;pre style="background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(255, 255, 255); background-position: initial initial; background-repeat: initial initial; "&gt;&lt;span class="Apple-style-span" style="font-size: 16px; "&gt;&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0); font-weight: bold; "&gt;def&lt;/span&gt; onLoadModule&lt;span style="color: rgb(128, 128, 48); "&gt;(&lt;/span&gt;self&lt;span style="color: rgb(128, 128, 48); "&gt;,&lt;/span&gt; module&lt;span style="color: rgb(128, 128, 48); "&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48); "&gt;:&lt;/span&gt;&lt;br /&gt;&lt;span&gt;    &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0); font-weight: bold; "&gt;if&lt;/span&gt; fnmatch&lt;span style="color: rgb(128, 128, 48); "&gt;.&lt;/span&gt;fnmatch&lt;span style="color: rgb(128, 128, 48); "&gt;(&lt;/span&gt; module&lt;span style="color: rgb(128, 128, 48); "&gt;.&lt;/span&gt;name&lt;span style="color: rgb(128, 128, 48); "&gt;(&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48); "&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48); "&gt;,&lt;/span&gt; self&lt;span style="color: rgb(128, 128, 48); "&gt;.&lt;/span&gt;mask &lt;span style="color: rgb(128, 128, 48); "&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48); "&gt;:&lt;/span&gt;&lt;br /&gt;&lt;span&gt;      &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0); font-weight: bold; "&gt;return&lt;/span&gt; DEBUG_STATUS_BREAK&lt;br /&gt;&lt;span&gt;    &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0); font-weight: bold; "&gt;return&lt;/span&gt; DEBUG_STATUS_NO_CHANGE&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(128, 0, 0); font-weight: bold; "&gt;if&lt;/span&gt; &lt;span style="color: rgb(227, 74, 220); "&gt;__name__&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48); "&gt;=&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48); "&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230); "&gt;"__main__"&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48); "&gt;:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(128, 0, 0); font-weight: bold; "&gt;  if&lt;/span&gt; &lt;span style="color: rgb(227, 74, 220); "&gt;len&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48); "&gt;(&lt;/span&gt;sys&lt;span style="color: rgb(128, 128, 48); "&gt;.&lt;/span&gt;argv&lt;span style="color: rgb(128, 128, 48); "&gt;)&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48); "&gt;=&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48); "&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 140, 0); "&gt;2&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48); "&gt;:&lt;/span&gt;&lt;br /&gt;  loadHandler &lt;span style="color: rgb(128, 128, 48); "&gt;=&lt;/span&gt; loadHandler&lt;span style="color: rgb(128, 128, 48); "&gt;(&lt;/span&gt; sys&lt;span style="color: rgb(128, 128, 48); "&gt;.&lt;/span&gt;argv&lt;span style="color: rgb(128, 128, 48); "&gt;[&lt;/span&gt;&lt;span style="color: rgb(0, 140, 0); "&gt;1&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48); "&gt;]&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48); "&gt;)&lt;/span&gt;&lt;br /&gt;  go&lt;span style="color: rgb(128, 128, 48); "&gt;(&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48); "&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;Фактически, скрипт продолжает исполнение целевой системы, пока не будет загружен модуль, имя которого будет совпадать с указанной маской (передается первым параметром в скрипт). Передаваемая маска имени модуля может содержать wildcard'ы: символы &lt;span&gt;* и ?&lt;/span&gt;. То есть, например, что бы при старте системы дождаться загрузки модуля beep.sys в память, нужно выполнять команду: "&lt;strong&gt;!py goLoad *beep*&lt;/strong&gt;". Это может быть полезно, когда нужно, что бы отладчик остановился перед вызовом точки входа целевого модуля, но уже при загруженном целевом модуле. В этот момент можно расставлять точки останова в загруженном модуле или, например, дождаться исполнения точки входа в драйвер командой "&lt;strong&gt;g beep!DriverEntry&lt;/strong&gt;"&lt;/div&gt;&lt;div&gt;&lt;br /&gt;P.S. Сейчас в планах развивать функционал фильтрации отладочных событий. Хотелось бы услышать мнение конечных пользователей о том, какие событий представляют наибольший интерес (соответственно, реализация этих событий будет более приоритетной задачи). В число событий, для которых в pykd планируется реализовать механизмы фильтрации, входят:&lt;br /&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;Создание и уничтожение процесса&lt;/li&gt;&lt;li&gt;Возникновение исключения&lt;/li&gt;&lt;li&gt;Создание и уничтожение нити (thread)&lt;/li&gt;&lt;li&gt;Изменение состояния отлаживаемой сесии&lt;/li&gt;&lt;li&gt;Срабатывание точки останова. pykd уже предоставляет класс &lt;a href="http://pykd.codeplex.com/wikipage?title=pykd_api_eng&amp;amp;referringTitle=Documentation#bp"&gt;bp&lt;/a&gt;. Но планируется так же продублировать функционал в debugEvent, что бы была возможность написать единый диспетчер событий Debug Engine.&lt;/li&gt;&lt;/ul&gt;&lt;/div&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/3359491729754373146-5938682362773428428?l=pykd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pykd.blogspot.com/feeds/5938682362773428428/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://pykd.blogspot.com/2011/05/blog-post.html#comment-form' title='Комментарии: 4'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/5938682362773428428'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/5938682362773428428'/><link rel='alternate' type='text/html' href='http://pykd.blogspot.com/2011/05/blog-post.html' title='Обработка событий загрузки и выгрузки модулей отлаживаемой системы'/><author><name>Alexey R. aka EreTIk</name><uri>http://www.blogger.com/profile/15766287755602837701</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-80Zoj-o50bI/TmEmoHunebI/AAAAAAAAAAk/pPu-sdWg0U8/s220/X-COM-128.JPG'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3359491729754373146.post-4653341334597949094</id><published>2011-05-25T23:57:00.000-07:00</published><updated>2011-05-25T23:57:30.720-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='release'/><title type='text'>Release 0.0.18</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Хочу представить очередной релиз &lt;b&gt;pykd&lt;/b&gt;. Хотя список изменений может показаться не впечатляющим, но за этими изменениями стоит напряженная работа. Были серьезно переработаны ключевые части проекта. Но сначала приведем формальный список изменений:&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Новые функции:&lt;/h4&gt;&lt;i&gt;loadWChars&lt;/i&gt; - юникодная версия существующей loadChars&lt;br /&gt;&lt;i&gt;rdmsr&lt;/i&gt; - возвращает значение MSR регистра&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Поддержка исключений:&lt;/h4&gt;&lt;i&gt;BaseException&lt;/i&gt; - базовый класс для всех исключений&lt;br /&gt;&lt;i&gt;MemoryException&lt;/i&gt; - класс исключений для ошибок чтения памяти&lt;br /&gt;&lt;i&gt;TypeException&lt;/i&gt; - класс исключений при работе с типами&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Новые классы:&lt;/h4&gt;&lt;i&gt;typedVar&lt;/i&gt; - переработанная версия класса &lt;b&gt;typedVarClass&lt;/b&gt;&lt;br /&gt;&lt;i&gt;typeInfo&lt;/i&gt; - переработанная версия класса &lt;b&gt;typeClass&lt;/b&gt;&lt;br /&gt;&lt;i&gt;debugEvent&lt;/i&gt; - базовый класс для создания обработчиков событий отладчика&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Bugs fixed:&lt;/h4&gt;&lt;strike&gt;&lt;a href="http://pykd.codeplex.com/workitem/8669"&gt;8669&lt;/a&gt;&lt;/strike&gt; - функция typedVar (теперь это класс ) создает объект для несуществующего типа&lt;br /&gt;&lt;strike&gt;&lt;a href="http://pykd.codeplex.com/workitem/8655"&gt;8655&lt;/a&gt;&lt;/strike&gt; - не поддерживается работа с неименованными членами структур&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Прочее:&lt;/h4&gt;Добавили мелкую, но очень удобную фичу для команды &lt;i&gt;pycmd&lt;/i&gt;: теперь модуль pykd импортируется при старте расширения автоматически. Иными словами, не надо писать &lt;i&gt;from pykd import *&lt;/i&gt;. &lt;br /&gt;&lt;br /&gt;Теперь подробнее о ключевых моментах. Их три:&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Исключения&lt;/h4&gt;Начиная с этого релиза мы переходим к концепции возвращения ошибок через исключения. По нашему мнению, это упрощает и делает более стройным и логичным как код скриптов на питоне, так и внутреннюю реализацию на С++. В текущем релизе исключения возвращают все функции работы с типами ( через классы typeInfo и typedVar ) и все функции работы с памятью. Предлагаю попробовать выполнить в интерпретаторе python следующие команды:&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; typeInfo( "nt", "AAAAAAA" )&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; typedVar( "nt", "AAAAAA", 0xDEADBEEF )&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; typedVar( "nt", "_EPROCESS", 0xDEADBEEF )&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; loadWChars( 0xDEADBEEF, 100 )&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Динамическое определение типов&lt;/h4&gt;Теперь создать типизированную переменную можно, даже если нет соответствующей символьной информации. Для этого у класса typeInfo предусмотрен метод append. Работать с ним не сложно:&lt;br /&gt;&lt;pre&gt;&amp;gt;&amp;gt;&amp;gt;a = typeInfo()&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt;a.append( ushort_t, "ShortField")&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt;a.append( uchar_t, "CharArray", 10 )&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt;print a&lt;br /&gt;unnamed   size = 12(0xc)&lt;br /&gt; +0  unsigned short   ShortField&lt;br /&gt; +2  unsigned char[]   CharArray&lt;br /&gt;&lt;/pre&gt;Хочу обратить внимание на переменные uchar_t и ushort_t. Откуда они взялись? Для базовых типов в модуль pykd добавлены глобальные переменные с типом &lt;i&gt;typeInfo&lt;/i&gt;. Вот их полный список:&lt;br /&gt;char_t&lt;br /&gt;uchar_t&lt;br /&gt;short_t&lt;br /&gt;ushort_t&lt;br /&gt;long_t&lt;br /&gt;ulong_t&lt;br /&gt;int_t&lt;br /&gt;uint_t&lt;br /&gt;ptr_t&lt;br /&gt;double_t&lt;br /&gt;longlong_t&lt;br /&gt;ulonglong_t&lt;br /&gt;&lt;br /&gt;Кроме того, говоря про класс &lt;i&gt;typeInfo&lt;/i&gt;, хотелось бы отметить, что доступ полям описания типа возможен не только по имени, но и по индексу, в том числе с использованием нотации слайсов. Это может понадобится, если вы решите написать свою питоновскую версию команды отладчика &lt;i&gt;dt&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Обработка событий отладчика&lt;/h4&gt;Если вы планируете с помощью pykd написать автоотладочное средство, а может даже и полноценный отладчик, скорее всего вам понадобится получать и обрабатывать различные события: загрузку и выгрузку модулей, старт процессов и так далее. Для этого мы разработали класс &lt;i&gt;debugEvent&lt;/i&gt;. Он содержит виртуальные функции-обработчики событий. Если вы хотите реализовать собственную обработку того или иного события, вам достаточно создать класс-наследник debugEvent и переопределить нужные вам методы-обработчики. Текущая реализация содержит только два обработчика: onLoadModule и onUnloadModule. &lt;br /&gt;&lt;br /&gt;Проиллюстрирую-ка я все это примером, а то слишком много слов и мало дела:&lt;br /&gt;&lt;pre style="background: #ffffff; color: black;"&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;class&lt;/span&gt; ModuleEventMgr&lt;span style="color: #808030;"&gt;(&lt;/span&gt; debugEvent &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;:&lt;/span&gt;&lt;br /&gt; &lt;br /&gt;    &lt;span style="color: maroon; font-weight: bold;"&gt;def&lt;/span&gt; onLoadModule&lt;span style="color: #808030;"&gt;(&lt;/span&gt; self&lt;span style="color: #808030;"&gt;,&lt;/span&gt; module &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;:&lt;/span&gt;&lt;br /&gt;        dprintln&lt;span style="color: #808030;"&gt;(&lt;/span&gt; module&lt;span style="color: #808030;"&gt;.&lt;/span&gt;name&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: maroon; font-weight: bold;"&gt;return&lt;/span&gt; DEBUG_STATUS_GO_HANDLED  &lt;br /&gt;&lt;br /&gt;evnetMgr &lt;span style="color: #808030;"&gt;=&lt;/span&gt; ModuleEvent&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Данный код будет выводить имена загружаемых модулей на экран. Все просто.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;На этом хотелось бы закончить обзор релиза 0.0.18. Спасибо вам за то, что внимательно прочли. Как всегда, ждем от вас вопросов, предложений, благодарности и/или кусочки ненависти - все сгодится :).&lt;br /&gt;&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/3359491729754373146-4653341334597949094?l=pykd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pykd.blogspot.com/feeds/4653341334597949094/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://pykd.blogspot.com/2011/05/release-0018.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/4653341334597949094'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/4653341334597949094'/><link rel='alternate' type='text/html' href='http://pykd.blogspot.com/2011/05/release-0018.html' title='Release 0.0.18'/><author><name>Pykd Maintainer</name><uri>http://www.blogger.com/profile/17452890529873583715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3359491729754373146.post-546587218923850675</id><published>2011-04-24T06:10:00.000-07:00</published><updated>2011-04-24T06:55:03.169-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='windbg extensions'/><category scheme='http://www.blogger.com/atom/ns#' term='ndis'/><title type='text'>Анализ сетевых пакетов в Vista/Windows 7</title><content type='html'>Сетевые пакеты в Vista/Windows 7 описываются структурой NET_BUFFER и списками NET_BUFFER_LIST. Мы написали скрипт, который анализирует содержимое пакетов с учетом сетевых протоколов. Сам скрипт можно взять здесь: &lt;a href="https://pykd.svn.codeplex.com/svn/snippets/nbl.py"&gt;nbl.py&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Использовать его просто. Установим брейкпойнт:&lt;br /&gt;bp ndis!NdisFIndicateReceiveNetBufferLists&lt;br /&gt;&lt;br /&gt;При его срабатывании (а это при наличии сетевого подключения случится очень быстро ) выполним команду:&lt;br /&gt;!py nbl @rdx ( для amd64 в rdx лежит указатель на NET_BUFFER_LIST )&lt;br /&gt;&lt;br /&gt;В результате получим что то вроде:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;Length: 92 bytes&lt;br /&gt;Ethernet header: OK&lt;br /&gt;    Dest MAC: ff-ff-ff-ff-ff-ff&lt;br /&gt;    Src MAC: 20-cf-30-70-25-e2&lt;br /&gt;    Type: IPv4&lt;br /&gt;IPv4 header: OK&lt;br /&gt;    version: 4&lt;br /&gt;    header length: 20 bytes&lt;br /&gt;    total length: 78 bytes&lt;br /&gt;    protocol: UDP&lt;br /&gt;    TTL: 128&lt;br /&gt;    Src addr: 10.244.0.50&lt;br /&gt;    Dest addr: 10.244.7.255&lt;br /&gt;UDP header: OK&lt;br /&gt;    Src port: 137&lt;br /&gt;    Dest port: 137&lt;br /&gt;    Length: 58&lt;br /&gt;    Checksum: 0xec8a&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Поодерживается разбор заголовков Ethernet, IPv4, UDP, TCP. В будущем, возможно, добавим поддержку и других протоколов. Если кому то скрипт окажется полезен - пишите, и это будущее может стать настоящим :).&lt;br /&gt;&lt;br /&gt;UPD1: &lt;br /&gt;Eще у нас есть скрипт, отображающий внтуренние структуры NDIS ( минпорты, протоколы и.т.д ) и их взаимосвязь: &lt;a href="https://pykd.svn.codeplex.com/svn/snippets/ndis.py"&gt;ndis.py&lt;/a&gt;, иногда бывает полезно, надеемся, будет и вам.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3359491729754373146-546587218923850675?l=pykd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pykd.blogspot.com/feeds/546587218923850675/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://pykd.blogspot.com/2011/04/vistawindows-7.html#comment-form' title='Комментарии: 2'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/546587218923850675'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/546587218923850675'/><link rel='alternate' type='text/html' href='http://pykd.blogspot.com/2011/04/vistawindows-7.html' title='Анализ сетевых пакетов в Vista/Windows 7'/><author><name>Pykd Maintainer</name><uri>http://www.blogger.com/profile/17452890529873583715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3359491729754373146.post-1047773917054312787</id><published>2011-04-22T00:47:00.000-07:00</published><updated>2011-04-22T00:48:55.876-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='API'/><title type='text'>Работа с памятью</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Все данные лежат в памяти, это очевидно. Ранее, мы уже рассмотрели (&lt;a href="http://pykd.blogspot.com/2011/01/typedvar.html"&gt;ссылка&lt;/a&gt;), как с помощью фцнкции &lt;i&gt;&lt;b&gt;typedVar&lt;/b&gt;&lt;/i&gt; получить доступ к содержимому переменной с учетом ее типа. Но бывают ситуации, когда мы не знаем тип, или содержимое памяти представляет собой сырой нетипизированный массив. Для работы с такими массивами предназначены следующие функции:&lt;br /&gt;&lt;i&gt;&lt;b&gt;loadBytes&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;loadWords&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;loadDWords &lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;loadQWords&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;- эти функции возвращают списки ( list ) беззнаковых целых соответствующей разрядности;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;loadSignBytes&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;loadSignWords&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;loadSignDWords &lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;loadSignQWords&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;- эти функции возвращают списки целых чисел со знаком.&lt;br /&gt;&lt;br /&gt;Все функции имеют одинаковый прототип:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;list&amp;nbsp; loadIntegerType( address, number, phyAddr = False )&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;address &lt;/i&gt;- адрес, по которому расположен массив&lt;br /&gt;&lt;i&gt;number &lt;/i&gt;- количество элементов массива&lt;br /&gt;&lt;i&gt;phyAddr &lt;/i&gt;- является ли адрес физическим ( не виртуальным ).&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Остается привести какой-нибудь разумный пример:&lt;br /&gt;&lt;pre style='color:#000000;background:#ffffff;'&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;from&lt;/span&gt; pykd &lt;span style='color:#800000; font-weight:bold; '&gt;import&lt;/span&gt; &lt;span style='color:#808030; '&gt;*&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;def&lt;/span&gt; dd&lt;span style='color:#808030; '&gt;(&lt;/span&gt; addr &lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;:&lt;/span&gt;&lt;br /&gt;    buf &lt;span style='color:#808030; '&gt;=&lt;/span&gt; loadDWords&lt;span style='color:#808030; '&gt;(&lt;/span&gt; addr&lt;span style='color:#808030; '&gt;,&lt;/span&gt; &lt;span style='color:#008c00; '&gt;16&lt;/span&gt; &lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800000; font-weight:bold; '&gt;for&lt;/span&gt; i &lt;span style='color:#800000; font-weight:bold; '&gt;in&lt;/span&gt; &lt;span style='color:#e34adc; '&gt;xrange&lt;/span&gt;&lt;span style='color:#808030; '&gt;(&lt;/span&gt; &lt;span style='color:#e34adc; '&gt;len&lt;/span&gt;&lt;span style='color:#808030; '&gt;(&lt;/span&gt;buf&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;:&lt;/span&gt;&lt;br /&gt;        dprint&lt;span style='color:#808030; '&gt;(&lt;/span&gt; &lt;span style='color:#0000e6; '&gt;"%08x"&lt;/span&gt; &lt;span style='color:#808030; '&gt;%&lt;/span&gt; buf&lt;span style='color:#808030; '&gt;[&lt;/span&gt;i&lt;span style='color:#808030; '&gt;]&lt;/span&gt; &lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;br /&gt;        dprint&lt;span style='color:#808030; '&gt;(&lt;/span&gt; &lt;span style='color:#808030; '&gt;(&lt;/span&gt;i &lt;span style='color:#808030; '&gt;%&lt;/span&gt; &lt;span style='color:#008c00; '&gt;4&lt;/span&gt; &lt;span style='color:#808030; '&gt;&amp;lt;&lt;/span&gt; &lt;span style='color:#008c00; '&gt;3&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;and&lt;/span&gt; &lt;span style='color:#0000e6; '&gt;"  "&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;or&lt;/span&gt; &lt;span style='color:#0000e6; '&gt;"\n"&lt;/span&gt; &lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;Данный код выводит на экран дамп 4 байтных чисел. Можно доработать данный код и получить полный аналог команды отладчика dd.&lt;br /&gt;&lt;br /&gt;Для обработки сырых буферов средставами станадртных или сторонних библиотек, добавлена функция &lt;i&gt;&lt;b&gt;loadChars&lt;/b&gt;&lt;/i&gt;. Она работает также как и &lt;b&gt;&lt;i&gt;loadBytes&lt;/i&gt;&lt;/b&gt;, но возвращает не список, а строку ( string ). К примеру, разбирать данные можно с помощью стандартного модуля struct:&lt;br /&gt;&lt;pre style="background: #ffffff; color: black;"&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;from&lt;/span&gt; struct &lt;span style="color: maroon; font-weight: bold;"&gt;import&lt;/span&gt; unpack&lt;br /&gt;shortField1&lt;span style="color: #808030;"&gt;,&lt;/span&gt; shortField2&lt;span style="color: #808030;"&gt;,&lt;/span&gt; longField &lt;span style="color: #808030;"&gt;=&lt;/span&gt; unpack&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;'hhl'&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt; loadChars&lt;span style="color: #808030;"&gt;(&lt;/span&gt; addr&lt;span style="color: #808030;"&gt;,&lt;/span&gt; &lt;span style="color: #008c00;"&gt;8&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;От функции &lt;b&gt;&lt;i&gt;loadChars&lt;/i&gt;&lt;/b&gt; плавно перейдем к функциям работы со строками: &lt;i&gt;&lt;b&gt;loadCStr&lt;/b&gt;&lt;/i&gt; и &lt;i&gt;&lt;b&gt;loadWStr&lt;/b&gt;&lt;/i&gt;. Эту функции предназначены для работы с 0-терминированными строками. Первая для работы с ANSI-строками, вторая - с UNICODE. На правах КО обращу внимание, что работа с этими функциями небезопасна в том смысле, что наличие терминирующего нуля никем не гарантируется. &lt;br /&gt;&lt;br /&gt;Для горячо любимых нами разработчиков системного ПО для Windows есть еще две полезных функции: &lt;b&gt;&lt;i&gt;loadUnicodeString&lt;/i&gt;&lt;/b&gt; и &lt;b&gt;&lt;i&gt;loadAnsiString&lt;/i&gt;&lt;/b&gt;. Они трактуют переданный адрес как указатель на структуру &lt;i&gt;ANSI_STRING&lt;/i&gt; или &lt;i&gt;UNICODE_STRING&lt;/i&gt; и, соответственно, избавляют от необходимости в ручную разбирать эти стуркутры для получения строки.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3359491729754373146-1047773917054312787?l=pykd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pykd.blogspot.com/feeds/1047773917054312787/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://pykd.blogspot.com/2011/04/blog-post.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/1047773917054312787'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/1047773917054312787'/><link rel='alternate' type='text/html' href='http://pykd.blogspot.com/2011/04/blog-post.html' title='Работа с памятью'/><author><name>Pykd Maintainer</name><uri>http://www.blogger.com/profile/17452890529873583715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3359491729754373146.post-5701035936610364837</id><published>2011-04-18T00:04:00.000-07:00</published><updated>2011-04-18T00:04:07.075-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='release'/><title type='text'>Release 0.0.17</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Представляем очередной релиз &lt;b&gt;pykd&lt;/b&gt;: 0.0.17. И так что нового:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Документация&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Прежде всего, мы сделали нечеловеческое усилие над собой и добавили документацию для всех функций и классов. Правда документация пока очень-очень-очень скупая, но мы обещаем над этим поработать. А чтобы продемонстрировать, как это работает, мы написали скрипт help.py ( его можно взять &lt;a href="https://pykd.svn.codeplex.com/svn/snippets/help.py"&gt;тут&lt;/a&gt; ) выводящий интерактивный хелп в windbg. Пробуем:&lt;br /&gt;0. загружаем плагин .load pykd.pyd&lt;br /&gt;1. нажимаем ctrl+N&lt;br /&gt;2. в строке ввода набираем !py help&lt;br /&gt;4. наслаждаемся.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Добавили в API несколько функций:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;bool isDumpAnalyzing()&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;Позволяет определить, анализируется ли в данным момент дамп или производится отладка живой системы. Если в скрипте используются функции управления отладчиком ( &lt;i&gt;go&lt;/i&gt;, управления точками останова и.т.д ), имеет смысл вставить данный вызов и уберечь пользователя от неизбежных ошибок при попытке исполнения скрипта во время анализа дампа&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;bool isWindbgExt()&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;Позволяет определить, исполняется ли скрипт внутри WinDbg или вызван процессом интерпретатором python. Ранее для этого использовался неявный метод и вызов &lt;i&gt;isSesionStart&lt;/i&gt;. Теперь &lt;i&gt;isSessionStart&lt;/i&gt; удалена, этот вызов следует заменить в коде на &lt;i&gt;isWindbgExt&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;string loadChars(address, number)&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;В стандартной библиотеке python существует ряд средств для работы с массивами "сырых" данных. Все они для представления буфера данных используют класс string. Для того, чтобы не заниматься преобразованием списка байт, которые возвращает функция &lt;i&gt;loadBytes&lt;/i&gt; мы добавили функцию &lt;i&gt;loadChars&lt;/i&gt;.&lt;br /&gt;Ее удобно использовать, например, вместе с модулем &lt;b&gt;struct&lt;/b&gt;:&lt;br /&gt;&lt;pre style="background: #ffffff; color: black;"&gt;&lt;span style="color: #808030;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #808030;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #808030;"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: maroon; font-weight: bold;"&gt;from&lt;/span&gt; struct &lt;span style="color: maroon; font-weight: bold;"&gt;import&lt;/span&gt; unpack&lt;br /&gt;&lt;span style="color: #808030;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #808030;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #808030;"&gt;&amp;gt;&lt;/span&gt; shortField1&lt;span style="color: #808030;"&gt;,&lt;/span&gt; shortField2&lt;span style="color: #808030;"&gt;,&lt;/span&gt; longField &lt;span style="color: #808030;"&gt;=&lt;/span&gt; unpack&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;'hhl'&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt; loadChars&lt;span style="color: #808030;"&gt;(&lt;/span&gt; addr&lt;span style="color: #808030;"&gt;,&lt;/span&gt; &lt;span style="color: #008c00;"&gt;8&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;&lt;i&gt;Методы checksum() and timestamp() класса dbgModuleClass&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;Из названия методов должно быть ясно, их назначение. Если Вам придет в голову написать собственный загрузчик символов ( почему бы и нет? ), то они вам могут пригодится.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;callbacks for bp class ( breakpoint )&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;Это, можно сказать, изюминка данного релиза. До сих пор, пользоваться точками останова ( breakpoint ) из &lt;b&gt;pykd&lt;/b&gt; было не слишком удобно. Теперь при создании новой точки останова можно задать функцию обратного вызова и обрабатывать из в событийно-ориентированном стиле.&lt;br /&gt;&lt;br /&gt;Пример:&lt;br /&gt;&lt;pre style="background: #ffffff; color: black;"&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;from&lt;/span&gt; pykd &lt;span style="color: maroon; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #808030;"&gt;*&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;def&lt;/span&gt; bpCallback&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: maroon; font-weight: bold;"&gt;if&lt;/span&gt; is64bitSystem&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;:&lt;/span&gt;&lt;br /&gt;        objAttr &lt;span style="color: #808030;"&gt;=&lt;/span&gt; typedVar&lt;span style="color: #808030;"&gt;(&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"ntdll"&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"_OBJECT_ATTRIBUTES"&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt; reg&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"r8"&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;br /&gt;    &lt;span style="color: maroon; font-weight: bold;"&gt;else&lt;/span&gt;&lt;span style="color: #808030;"&gt;:&lt;/span&gt;&lt;br /&gt;        objAttr &lt;span style="color: #808030;"&gt;=&lt;/span&gt; typedVar&lt;span style="color: #808030;"&gt;(&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"ntdll"&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"_OBJECT_ATTRIBUTES"&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt; ptrPtr&lt;span style="color: #808030;"&gt;(&lt;/span&gt;reg&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"esp"&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;span style="color: #808030;"&gt;+&lt;/span&gt; &lt;span style="color: green;"&gt;0xC&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt;  &lt;br /&gt;&lt;br /&gt;    name &lt;span style="color: #808030;"&gt;=&lt;/span&gt; loadUnicodeString&lt;span style="color: #808030;"&gt;(&lt;/span&gt; objAttr&lt;span style="color: #808030;"&gt;.&lt;/span&gt;ObjectName &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    dprintln&lt;span style="color: #808030;"&gt;(&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"NtCreateFile: "&lt;/span&gt; &lt;span style="color: #808030;"&gt;+&lt;/span&gt; name &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: maroon; font-weight: bold;"&gt;return&lt;/span&gt; DEBUG_STATUS_GO_HANDLED&lt;br /&gt;&lt;br /&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: maroon; font-weight: bold;"&gt;not&lt;/span&gt; isWindbgExt&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;:&lt;/span&gt;&lt;br /&gt;    startProcess&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"notepad.exe"&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: maroon; font-weight: bold;"&gt;not&lt;/span&gt; isDumpAnalyzing&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;span style="color: maroon; font-weight: bold;"&gt;and&lt;/span&gt; &lt;span style="color: maroon; font-weight: bold;"&gt;not&lt;/span&gt; isKernelDebugging&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;:&lt;/span&gt;        &lt;br /&gt;    nt &lt;span style="color: #808030;"&gt;=&lt;/span&gt; loadModule&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"ntdll"&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;    b1 &lt;span style="color: #808030;"&gt;=&lt;/span&gt; bp&lt;span style="color: #808030;"&gt;(&lt;/span&gt; nt&lt;span style="color: #808030;"&gt;.&lt;/span&gt;NtCreateFile&lt;span style="color: #808030;"&gt;,&lt;/span&gt; bpCallback &lt;span style="color: #808030;"&gt;)&lt;/span&gt;   &lt;br /&gt;    &lt;span style="color: dimgrey;"&gt;# wait for user break, exceptions or process exit&lt;/span&gt;&lt;br /&gt;    go&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;    dprintln&lt;span style="color: #808030;"&gt;(&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"stopped"&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt;    &lt;br /&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;else&lt;/span&gt;&lt;span style="color: #808030;"&gt;:&lt;/span&gt;&lt;br /&gt;    dprintln&lt;span style="color: #808030;"&gt;(&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"The debugger must be connected to live usermode process"&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;&lt;i&gt;typedVarList&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;При работе со связанными списками в (ядре) Windows часто используется структура &lt;i&gt;LIST_ENTRY&lt;/i&gt;. Изначально функция &lt;i&gt;typedVarList&lt;/i&gt; была ориентирована на такие списки. Однако, гораздо чаще используется другой подход для создания связанных списков: когда структура содержит указатель ( Next ) на начало следующей структуры. Теперь, &lt;i&gt;typedVarList&lt;/i&gt; поддерживает оба случая. Какой вариант связного списка использовать, определяется по типу поля-указателя на следующий элемент.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Новый инсталлятор&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;К релизу 0.0.17 мы существенно переработали инсталятор:&lt;br /&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;Новый дизайн&lt;/li&gt;&lt;li&gt;Добавили деинсталлятор ( вдруг кому-нибудь понадобится? )&lt;/li&gt;&lt;li&gt;Добавили примеры в комплект иснталлятора&lt;/li&gt;&lt;li&gt;Выбор дополнительных компонентов по желанию пользователя ( VCRedist, python, примеры )&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;b&gt;Bug fixed&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;strike&gt;&lt;a href="http://pykd.codeplex.com/workitem/8470"&gt;8470&lt;/a&gt;&lt;/strike&gt; ( python.exe crashes after first pykd call )&lt;br /&gt;&lt;strike&gt;&lt;a href="http://pykd.codeplex.com/workitem/8614"&gt;8614&lt;/a&gt;&lt;/strike&gt; ( go() works incorrectly while process is terminating )&lt;br /&gt;&lt;strike&gt;&lt;a href="http://pykd.codeplex.com/workitem/8499"&gt;8499&lt;/a&gt;&lt;/strike&gt; ( !py command crashs with wrong script's path )&lt;br /&gt;&lt;strike&gt;&lt;a href="http://pykd.codeplex.com/workitem/8578"&gt;8578&lt;/a&gt;&lt;/strike&gt; ( findModule returns None for WOW64 process )&lt;br /&gt;&lt;strike&gt;&lt;a href="http://pykd.codeplex.com/workitem/8493"&gt;8493&lt;/a&gt;&lt;/strike&gt; ( loadPtrs returns dict instead list )&lt;br /&gt;&lt;strike&gt;&lt;a href="http://pykd.codeplex.com/workitem/8469"&gt;8469&lt;/a&gt;&lt;/strike&gt; ( dprintln does not work in console mode ) &lt;/div&gt;&lt;br /&gt;Надеемся, релиз 0.0.17 сделает вашу работу с &lt;b&gt;pykd&lt;/b&gt; более приятной и плодотворной!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3359491729754373146-5701035936610364837?l=pykd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pykd.blogspot.com/feeds/5701035936610364837/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://pykd.blogspot.com/2011/04/release-0017.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/5701035936610364837'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/5701035936610364837'/><link rel='alternate' type='text/html' href='http://pykd.blogspot.com/2011/04/release-0017.html' title='Release 0.0.17'/><author><name>Pykd Maintainer</name><uri>http://www.blogger.com/profile/17452890529873583715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3359491729754373146.post-4018859786941299799</id><published>2011-04-03T23:47:00.000-07:00</published><updated>2011-04-04T00:29:10.247-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='samples'/><category scheme='http://www.blogger.com/atom/ns#' term='howto'/><title type='text'>HOWTO</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;b&gt;1. Как получить указатель на PEB ?&lt;/b&gt;&lt;br /&gt;&lt;pre color="black" style="background: none repeat scroll 0% 0% rgb(255, 255, 255);"&gt;peb &lt;span style="color: #808030;"&gt;=&lt;/span&gt; typedVar&lt;span style="color: #808030;"&gt;(&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"ntdll"&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"_PEB"&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt; getCurrentProcess&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;/pre&gt;&lt;pre color="black" style="background: none repeat scroll 0% 0% rgb(255, 255, 255);"&gt;&lt;/pre&gt;&lt;b&gt;2. Какому модулю принадлежит адрес?&lt;/b&gt;&lt;br /&gt;&lt;pre color="black" style="background: none repeat scroll 0% 0% rgb(255, 255, 255);"&gt;module &lt;span style="color: #808030;"&gt;=&lt;/span&gt; findModule&lt;span style="color: #808030;"&gt;(&lt;/span&gt; addr &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;pre color="black" style="background: none repeat scroll 0% 0% rgb(255, 255, 255);"&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;print&lt;/span&gt; module&lt;span style="color: #808030;"&gt;=&lt;/span&gt;&lt;span style="color: #808030;"&gt;=&lt;/span&gt;&lt;span style="color: #e34adc;"&gt;None&lt;/span&gt; &lt;span style="color: maroon; font-weight: bold;"&gt;and&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"module not found"&lt;/span&gt; &lt;span style="color: maroon; font-weight: bold;"&gt;or&lt;/span&gt; module&lt;span style="color: #808030;"&gt;.&lt;/span&gt;name&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;/pre&gt;&lt;pre color="black" style="background: none repeat scroll 0% 0% rgb(255, 255, 255);"&gt;&lt;/pre&gt;&lt;b&gt;3. Как вывести текст с DML разметкой?&lt;/b&gt;&lt;br /&gt;&lt;pre color="black" style="background: none repeat scroll 0% 0% rgb(255, 255, 255);"&gt;dprintln&lt;span style="color: #808030;"&gt;(&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"&amp;lt;u&amp;gt;Hello &amp;lt;b&amp;gt;World&amp;lt;/b&amp;gt;&amp;lt;/u&amp;gt;"&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt; &lt;span style="color: #e34adc;"&gt;True&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;b&gt;4. Как передать в скрипт значение регистра?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Также, как и в любую команду windbg:&lt;br /&gt;!py myscript @eax&lt;br /&gt;Чтобы это работало, в скрипте нужно предусмотреть вычисление выражений:&lt;br /&gt;&lt;pre style="background: none repeat scroll 0% 0% rgb(255, 255, 255); color: black;"&gt;param1 &lt;span style="color: #808030;"&gt;=&lt;/span&gt; expr&lt;span style="color: #808030;"&gt;(&lt;/span&gt; sys&lt;span style="color: #808030;"&gt;.&lt;/span&gt;argv&lt;span style="color: #808030;"&gt;[&lt;/span&gt;&lt;span style="color: #008c00;"&gt;1&lt;/span&gt;&lt;span style="color: #808030;"&gt;]&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;/pre&gt;&lt;pre style="background: none repeat scroll 0% 0% rgb(255, 255, 255); color: black;"&gt;&lt;/pre&gt;&lt;b&gt;5. Как выполнить команду отладчика и получить ее результат?&lt;/b&gt;&lt;br /&gt;&lt;pre style="background: none repeat scroll 0% 0% rgb(255, 255, 255); color: black;"&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;print&lt;/span&gt; dbgCommand&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"!for_each_module"&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;/pre&gt;Результат команды можно обработать к примеру с помощью RE.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;6. Как получить размер структуры?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Проще всего так:&lt;br /&gt;&lt;pre style="background: #ffffff; color: black;"&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;print&lt;/span&gt; &lt;span style="color: #e34adc;"&gt;hex&lt;/span&gt;&lt;span style="color: #808030;"&gt;(&lt;/span&gt; sizeof&lt;span style="color: #808030;"&gt;(&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"nt"&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"_ERESOURCE"&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="background: none repeat scroll 0% 0% rgb(255, 255, 255); color: black;"&gt;&lt;/pre&gt;Можно с через класс, предсталяющий информацию о типе ( &lt;i&gt;&lt;b&gt;typeClass&lt;/b&gt;&lt;/i&gt;):&lt;br /&gt;&lt;pre style="background: none repeat scroll 0% 0% rgb(255, 255, 255); color: black;"&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;print&lt;/span&gt; &lt;span style="color: #e34adc;"&gt;hex&lt;/span&gt;&lt;span style="color: #808030;"&gt;(&lt;/span&gt;getTypeClass&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"nt"&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"_ERESOURCE"&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;sizeof&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;Справедливо и для объектов дочернего класса &lt;span style="font-style: italic; font-weight: bold;"&gt;typedVarClass&lt;/span&gt;, например:&lt;br /&gt;&lt;pre style="background: none repeat scroll 0% 0% rgb(255, 255, 255); color: black;"&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;print&lt;/span&gt; &lt;span style="color: #e34adc;"&gt;hex&lt;/span&gt;&lt;span style="color: #808030;"&gt;(&lt;/span&gt;typedVar&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"nt"&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"_ERESOURCE"&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt; getOffset&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"nt"&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"CmpRegistryLock"&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;sizeof&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;7. Как получить смещение поля структры?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Через класс, предсталяющий информацию о типе ( &lt;i&gt;&lt;b&gt;typeClass&lt;/b&gt;&lt;/i&gt;):&lt;br /&gt;&lt;pre style="background: none repeat scroll 0% 0% rgb(255, 255, 255); color: black;"&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;print&lt;/span&gt; &lt;span style="color: #e34adc;"&gt;hex&lt;/span&gt;&lt;span style="color: #808030;"&gt;(&lt;/span&gt;getTypeClass&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"nt"&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"_ETHREAD"&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;Tcb&lt;span style="color: #808030;"&gt;.&lt;/span&gt;ThreadListEntry&lt;span style="color: #808030;"&gt;.&lt;/span&gt;offset&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;Справедливо и для объектов дочернего класса &lt;span style="font-style: italic; font-weight: bold;"&gt;typedVarClass&lt;/span&gt;, например:&lt;br /&gt;&lt;pre style="background: none repeat scroll 0% 0% rgb(255, 255, 255); color: black;"&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;print&lt;/span&gt; &lt;span style="color: #e34adc;"&gt;hex&lt;/span&gt;&lt;span style="color: #808030;"&gt;(&lt;/span&gt;typedVar&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"nt"&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"_ETHREAD"&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt; getImplicitThread&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;Tcb&lt;span style="color: #808030;"&gt;.&lt;/span&gt;ThreadListEntry&lt;span style="color: #808030;"&gt;.&lt;/span&gt;offset&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;) &lt;/span&gt;&lt;/pre&gt;Но сравните результат выполнения двух команд:&lt;br /&gt;&lt;pre style="background: none repeat scroll 0% 0% rgb(255, 255, 255); color: black;"&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;print&lt;/span&gt; &lt;span style="color: #e34adc;"&gt;hex&lt;/span&gt;&lt;span style="color: #808030;"&gt;(&lt;/span&gt;getTypeClass&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"nt"&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"_ETHREAD"&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;Tcb&lt;span style="color: #808030;"&gt;.&lt;/span&gt;ThreadListEntry&lt;span style="color: #808030;"&gt;.&lt;/span&gt;Flink.offset&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: none repeat scroll 0% 0% rgb(255, 255, 255); color: black;"&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;print&lt;/span&gt; &lt;span style="color: #e34adc;"&gt;hex&lt;/span&gt;&lt;span style="color: #808030;"&gt;(&lt;/span&gt;typedVar&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"nt"&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"_ETHREAD"&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt; getImplicitThread&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;Tcb&lt;span style="color: #808030;"&gt;.&lt;/span&gt;ThreadListEntry&lt;span style="color: #808030;"&gt;.&lt;/span&gt;Flink&lt;span style="color: #808030;"&gt;.&lt;/span&gt;&lt;br /&gt;offset&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt; &lt;/span&gt;&lt;/pre&gt;Первая выводит ожидаемое значение, вторая - возвращает ошибку. Дело в том, что аттрибут 'Flink' в объекте &lt;span style="font-style: italic; font-weight: bold;"&gt;typedVarClass &lt;/span&gt;имеет встроенный тип python-а long и, соответственно, не имеет метода offset ( а также, getAddress() )&lt;br /&gt;&lt;br /&gt;&lt;b&gt;8. Есть ли в pykd команда help или другой способ получить справку?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;В &lt;b&gt;pykd&lt;/b&gt; - нет. Но такая возможность встроена в сам python! Пробуем:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;gt;!pycmd&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; help()&lt;br /&gt;help&amp;gt;pykd.typedVar&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;b&gt;9. Как отлаживать скрипт?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Небольшие скрипты можно отладить прямо в windbg ( или в консоле ). Для этого используем встроенный отладчик pdb:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;&amp;gt;!py pdb my_script.py&lt;br /&gt;(pdb) s&lt;br /&gt;-&amp;gt; import pykd&lt;br /&gt;(pdb)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;В более сложных случаях можно использовать любой отладчик python кода. Например, eсlipse или Visual Studio 2010 с плагином &lt;a href="http://pytools.codeplex.com/"&gt;pytools&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;10. Как сравнивать адреса?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Вопрос не так прост. DbgEng и все функции &lt;b&gt;pykd&lt;/b&gt; возращают адреса в 64 битном формате, даже для x86 платформы. Адреса, находящиеся в верхней половине адресного пространства, расширяются:&lt;br /&gt;0x804f8925 -&amp;gt; 0xFFFFFFFF'804f8925&lt;br /&gt;В следствии этого, в коде могут возникнуть непрогнозируемые ошибки. Рассмотрим пример:&lt;br /&gt;&lt;pre style="background: #ffffff; color: black;"&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;if&lt;/span&gt; reg&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"eax"&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;==&lt;/span&gt;getOffset&lt;span style="color: #808030;"&gt;(&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"nt"&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"NtCreateFile"&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: maroon; font-weight: bold;"&gt;print&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"eax point to NtCreateFile"&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;На x86 платформе данный код будет работать неправильно. Переменная &lt;b&gt;&lt;i&gt;a&lt;/i&gt;&lt;/b&gt; будет трактоваться как 32 битное целое, а функция getOffset вернет адрес, расширенный до 64 бит. И даже если регистр eax действительно указывает на NtCreateFile, проверка на равенство не сработает. Чтобы избежать этого, скастим значение регистра к указателю с помощью функции &lt;i&gt;&lt;b&gt;addr64&lt;/b&gt;&lt;/i&gt;:&lt;br /&gt;&lt;pre style="background: none repeat scroll 0% 0% rgb(255, 255, 255); color: black;"&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;if&lt;/span&gt; addr64&lt;span style="color: #808030;"&gt;(&lt;/span&gt;reg&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"eax"&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;=&lt;/span&gt;&lt;span style="color: #808030;"&gt;=&lt;/span&gt;getOffset&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"nt"&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"NtCreateFile"&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: maroon; font-weight: bold;"&gt;print&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"eax point to NtCReateFile" &lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: none repeat scroll 0% 0% rgb(255, 255, 255); color: black;"&gt;&lt;span style="color: #0000e6;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;Надеюсь, эта информация поможет начать работу с &lt;i&gt;pykd&lt;b&gt;&lt;/b&gt;&lt;/i&gt;. На все вопросы мы с удовольствием ответим в этом блоге или по электронной почте: &lt;a href="mailto:pykd@hotmail.com"&gt;pykd@hotmail.com&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/3359491729754373146-4018859786941299799?l=pykd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pykd.blogspot.com/feeds/4018859786941299799/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://pykd.blogspot.com/2011/04/howto.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/4018859786941299799'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/4018859786941299799'/><link rel='alternate' type='text/html' href='http://pykd.blogspot.com/2011/04/howto.html' title='HOWTO'/><author><name>Pykd Maintainer</name><uri>http://www.blogger.com/profile/17452890529873583715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3359491729754373146.post-7306993563475052205</id><published>2011-03-21T00:55:00.000-07:00</published><updated>2011-03-21T04:17:11.439-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='setup'/><title type='text'>Автоматическая установка pykd</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Установить pykd вручную не сложно. Однако есть как минимум один подводный камень: нужно также установить дистрибутив vcredist нужной версии. Но все заботы может взять на себя автоматический инсталлятор. Он найдет python нужной версии, а если его нет - скачает, установит рантайм библиотеки и, конечно, сэкономит вам время. &lt;br /&gt;&lt;br /&gt;&lt;a href="http://perfect-coding.blogspot.com/2011/03/pykd-python-windbg-extension.html"&gt;http://perfect-coding.blogspot.com/2011/03/pykd-python-windbg-extension.html&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/3359491729754373146-7306993563475052205?l=pykd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pykd.blogspot.com/feeds/7306993563475052205/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://pykd.blogspot.com/2011/03/pykd.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/7306993563475052205'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/7306993563475052205'/><link rel='alternate' type='text/html' href='http://pykd.blogspot.com/2011/03/pykd.html' title='Автоматическая установка pykd'/><author><name>Pykd Maintainer</name><uri>http://www.blogger.com/profile/17452890529873583715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3359491729754373146.post-2290663757302885892</id><published>2011-03-18T07:52:00.000-07:00</published><updated>2011-03-18T08:48:42.021-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='samples'/><category scheme='http://www.blogger.com/atom/ns#' term='pyside'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><title type='text'>PySide+pykd: используем Qt в питоновских скриптах к WinDbg</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;pykd&lt;/b&gt;, как расширении к WinDbg, дает не только возможность использования мощного и гибкого языка Python, но и уже готовых сторонних проектов. Далее пойдет речь о &lt;a href="http://www.pyside.org/"&gt;PySide&lt;/a&gt; - библиотеке интеграции инструментария &lt;b&gt;Qt&lt;/b&gt; в Python. Возьмем простой пример: нужно просмотреть статистику о процессах системы, в частноти размер виртуального адресного пространства и счетчики операций ввода/вывода. Не буду рассказывать об установке PySide, так как на официальной &lt;a href="http://developer.qt.nokia.com/wiki/PySide_Binaries_Windows"&gt;странице загрузок для Windows&lt;/a&gt; можно скачать инсталлятор. Набросаем небольшой скрипт, который средствами &lt;span style="font-weight: bold;"&gt;pykd&lt;/span&gt; получает и анализирует список процессов, а затем использует &lt;span style="font-weight: bold;"&gt;PySide&lt;/span&gt; для визуализации собранных данных в виде таблицы в GUI-окне:&lt;br /&gt;&lt;pre style="color: rgb(0, 0, 0); background: none repeat scroll 0% 0% rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;import&lt;/span&gt; sys&lt;br /&gt;&lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;from&lt;/span&gt; pykd &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48);"&gt;*&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;from&lt;/span&gt; PySide &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;import&lt;/span&gt; QtCore&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; QtGui&lt;br /&gt;&lt;br /&gt;COL_PID &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 140, 0);"&gt;0&lt;/span&gt;&lt;br /&gt;COL_PRC_NAME &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 140, 0);"&gt;1&lt;/span&gt;&lt;br /&gt;COL_VSIZE &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 140, 0);"&gt;2&lt;/span&gt;&lt;br /&gt;COL_READ &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 140, 0);"&gt;3&lt;/span&gt;&lt;br /&gt;COL_WRITE &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 140, 0);"&gt;4&lt;/span&gt;&lt;br /&gt;COL_OTHER &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 140, 0);"&gt;5&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: rgb(227, 74, 220);"&gt;__name__&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'__main__'&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; app &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; QtGui&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;QApplication&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;sys&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;argv&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; nt &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; loadModule&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;"nt"&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt; lstProcesses &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; typedVarList&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;nt&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;PsActiveProcessHead&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;"nt"&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;"_EPROCESS"&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;"ActiveProcessLinks"&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; countOfProcesses &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(227, 74, 220);"&gt;len&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;lstProcesses&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;countOfProcesses &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 140, 0);"&gt;0&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;:&lt;/span&gt;&lt;br /&gt;   &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;print&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;"Build process list failed"&lt;/span&gt;&lt;br /&gt;   sys&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;&lt;span style="color: rgb(227, 74, 220);"&gt;exit&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; model &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; QtGui&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;QStandardItemModel&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;countOfProcesses&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; COL_OTHER&lt;span style="color: rgb(128, 128, 48);"&gt;+&lt;/span&gt;&lt;span style="color: rgb(0, 140, 0);"&gt;1&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt; model&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;setHeaderData&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;COL_PID&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; QtCore&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;Qt&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;Horizontal&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;"PID"&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt; model&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;setHeaderData&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;COL_PRC_NAME&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; QtCore&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;Qt&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;Horizontal&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;"Image"&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt; model&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;setHeaderData&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;COL_VSIZE&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; QtCore&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;Qt&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;Horizontal&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;"VirtualSize"&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt; model&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;setHeaderData&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;COL_READ&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; QtCore&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;Qt&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;Horizontal&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;"Read"&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt; model&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;setHeaderData&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;COL_WRITE&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; QtCore&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;Qt&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;Horizontal&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;"Write"&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt; model&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;setHeaderData&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;COL_OTHER&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; QtCore&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;Qt&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;Horizontal&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;"Other"&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; tableView &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; QtGui&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;QTableView&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt; tableView&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;setModel&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;model&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;for&lt;/span&gt; row &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;in&lt;/span&gt; &lt;span style="color: rgb(227, 74, 220);"&gt;range&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;countOfProcesses&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;:&lt;/span&gt;&lt;br /&gt;   process &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; lstProcesses&lt;span style="color: rgb(128, 128, 48);"&gt;[&lt;/span&gt;row&lt;span style="color: rgb(128, 128, 48);"&gt;]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;   index_ &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; model&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;index&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;row&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; COL_PID&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; QtCore&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;QModelIndex&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt;   model&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;setData&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;index_&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; process&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;UniqueProcessId&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;   index_ &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; model&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;index&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;row&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; COL_PRC_NAME&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; QtCore&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;QModelIndex&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt;   model&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;setData&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;index_&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;""&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;join&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;[&lt;/span&gt;&lt;span style="color: rgb(227, 74, 220);"&gt;chr&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;i&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt; &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;for&lt;/span&gt; i &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;in&lt;/span&gt; process&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;ImageFileName&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;values&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;]&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;   index_ &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; model&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;index&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;row&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; COL_VSIZE&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; QtCore&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;QModelIndex&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt;   model&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;setData&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;index_&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; process&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;VirtualSize&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;   index_ &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; model&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;index&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;row&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; COL_READ&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; QtCore&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;QModelIndex&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt;   model&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;setData&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;index_&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; process&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;ReadOperationCount&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;QuadPart&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;   index_ &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; model&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;index&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;row&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; COL_WRITE&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; QtCore&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;QModelIndex&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt;   model&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;setData&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;index_&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; process&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;WriteOperationCount&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;QuadPart&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;   index_ &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; model&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;index&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;row&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; COL_OTHER&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; QtCore&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;QModelIndex&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt;   model&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;setData&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;index_&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; process&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;OtherOperationCount&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;QuadPart&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; tableView&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;resizeColumnsToContents&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; widthWidget &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 140, 0);"&gt;0&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;for&lt;/span&gt; col &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;in&lt;/span&gt; &lt;span style="color: rgb(227, 74, 220);"&gt;range&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;COL_OTHER&lt;span style="color: rgb(128, 128, 48);"&gt;+&lt;/span&gt;&lt;span style="color: rgb(0, 140, 0);"&gt;1&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;:&lt;/span&gt; widthWidget &lt;span style="color: rgb(128, 128, 48);"&gt;+&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; tableView&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;columnWidth&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;col&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt; widthWidget &lt;span style="color: rgb(128, 128, 48);"&gt;+&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 140, 0);"&gt;50&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; tableView&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;setSortingEnabled&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(227, 74, 220);"&gt;True&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt; tableView&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;setWindowTitle&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 230);"&gt;"Processes table:"&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt; tableView&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;resize&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;widthWidget&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 140, 0);"&gt;500&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt; tableView&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;show&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; app&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;exec_&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;span style="font-size:small;"&gt;Теперь исполним его в WinDbg. После того, как скрипт построит список процессов, мы увидим окно результатов. Оно не является модальным по отношению к основному окну WinDbg, но отладчик терпеливо ждет завершения работы скрипта (в нашем случае - закрытия окна):&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://1.bp.blogspot.com/-AjR8vUHLc-o/TYJd68IxWYI/AAAAAAAAAAU/V5SIkbo9T9U/s1600/ps_screenshot_7.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;br /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://1.bp.blogspot.com/-AjR8vUHLc-o/TYJd68IxWYI/AAAAAAAAAAU/V5SIkbo9T9U/s1600/ps_screenshot_7.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" id="BLOGGER_PHOTO_ID_5585129755049548162" src="http://1.bp.blogspot.com/-AjR8vUHLc-o/TYJd68IxWYI/AAAAAAAAAAU/V5SIkbo9T9U/s400/ps_screenshot_7.png" style="display: block; height: 400px; margin: 0px auto 10px; text-align: center; width: 357px;" border="0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;Конечно, можно было бы выдать эту информацию в текстовой форме. Но GUI таблица, например, позволяет одним кликом поменять колонку сортировки и можно наблюдать какой процесс активно более активно читает, а какой пишет.&lt;br /&gt;Еще один приятный момент использования &lt;b&gt;PySide&lt;/b&gt; - лицензия LGPL, позволяющая использовать и распространять библиотеку в любых проектах, включая коммерческие.&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/3359491729754373146-2290663757302885892?l=pykd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pykd.blogspot.com/feeds/2290663757302885892/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://pykd.blogspot.com/2011/03/pysidepykd-qt-windbg.html#comment-form' title='Комментарии: 3'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/2290663757302885892'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/2290663757302885892'/><link rel='alternate' type='text/html' href='http://pykd.blogspot.com/2011/03/pysidepykd-qt-windbg.html' title='PySide+pykd: используем Qt в питоновских скриптах к WinDbg'/><author><name>Alexey R. aka EreTIk</name><uri>http://www.blogger.com/profile/15766287755602837701</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-80Zoj-o50bI/TmEmoHunebI/AAAAAAAAAAk/pPu-sdWg0U8/s220/X-COM-128.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-AjR8vUHLc-o/TYJd68IxWYI/AAAAAAAAAAU/V5SIkbo9T9U/s72-c/ps_screenshot_7.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3359491729754373146.post-5041543838847667951</id><published>2011-03-16T07:39:00.000-07:00</published><updated>2011-03-16T07:39:33.877-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='samples'/><category scheme='http://www.blogger.com/atom/ns#' term='kernel'/><title type='text'>Исследуем ASLR</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Сегодня неожиданно возник вопрос: одинаков ли адрес загрузки ntdll.dll во всех процессах. Поспорив немного, вопрос  разбили на два: влияет ли ASLR на ntdll.dll и как, собственно, работает ASLR: отличаются ли адреса загрузки системных dll в разных процессах. Поскольку практика - мерило истинности, быстренько написали скрипт на питоне и все выяснили. Сам скрипт был написан очень быстро ( по сути, скопипастили пример proclist.py  и слегка его модифицировали ). Вот быстрота написания скрипта и сподвигла меня написать этот пост. А заодно хочется продемонстрировать некоторые приемы работы с pykd.&lt;br /&gt;&lt;br /&gt;Вот сам код:&lt;/div&gt;&lt;br /&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;import&lt;/span&gt; sys&lt;br /&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;from&lt;/span&gt; pykd &lt;span style="color: maroon; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #808030;"&gt;*&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;def&lt;/span&gt; moduleBase&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="padding-left: 25px;"&gt;nt &lt;span style="color: #808030;"&gt;=&lt;/span&gt; loadModule&lt;span style="color: #808030;"&gt;(&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"nt"&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;processList &lt;span style="color: #808030;"&gt;=&lt;/span&gt; typedVarList&lt;span style="color: #808030;"&gt;(&lt;/span&gt; nt&lt;span style="color: #808030;"&gt;.&lt;/span&gt;PsActiveProcessHead&lt;span style="color: #808030;"&gt;,&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"nt"&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"_EPROCESS"&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"ActiveProcessLinks"&lt;/span&gt;  &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;for&lt;/span&gt; process &lt;span style="color: maroon; font-weight: bold;"&gt;in&lt;/span&gt; processList&lt;span style="color: #808030;"&gt;:&lt;/span&gt;&lt;br /&gt;&lt;div style="padding-left: 50px;"&gt;&lt;br /&gt;dbgCommand&lt;span style="color: #808030;"&gt;(&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;".process /p %x"&lt;/span&gt; &lt;span style="color: #808030;"&gt;%&lt;/span&gt; process&lt;span style="color: #808030;"&gt;.&lt;/span&gt;getAddress&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;dbgCommand&lt;span style="color: #808030;"&gt;(&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;".reload /user"&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;print&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"process %x  "&lt;/span&gt; &lt;span style="color: #808030;"&gt;%&lt;/span&gt; process&lt;span style="color: #808030;"&gt;.&lt;/span&gt;getAddress&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;""&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;join&lt;span style="color: #808030;"&gt;(&lt;/span&gt; &lt;span style="color: #808030;"&gt;[&lt;/span&gt; &lt;span style="color: #e34adc;"&gt;chr&lt;/span&gt;&lt;span style="color: #808030;"&gt;(&lt;/span&gt;i&lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;span style="color: maroon; font-weight: bold;"&gt;for&lt;/span&gt; i &lt;span style="color: maroon; font-weight: bold;"&gt;in&lt;/span&gt; process&lt;span style="color: #808030;"&gt;.&lt;/span&gt;ImageFileName&lt;span style="color: #808030;"&gt;.&lt;/span&gt;values&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt; &lt;span style="color: #808030;"&gt;]&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;ntdll &lt;span style="color: #808030;"&gt;=&lt;/span&gt; loadModule&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"ntdll"&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;if&lt;/span&gt; ntdll &lt;span style="color: #808030;"&gt;!&lt;/span&gt;&lt;span style="color: #808030;"&gt;=&lt;/span&gt; &lt;span style="color: #e34adc;"&gt;None&lt;/span&gt;&lt;span style="color: #808030;"&gt;:&lt;/span&gt;             &lt;span style="color: maroon; font-weight: bold;"&gt;print&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"\tntdll: %x"&lt;/span&gt; &lt;span style="color: #808030;"&gt;%&lt;/span&gt; ntdll&lt;span style="color: #808030;"&gt;.&lt;/span&gt;begin&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;kernel32 &lt;span style="color: #808030;"&gt;=&lt;/span&gt; loadModule&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"kernel32"&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;if&lt;/span&gt; kernel32 &lt;span style="color: #808030;"&gt;!&lt;/span&gt;&lt;span style="color: #808030;"&gt;=&lt;/span&gt; &lt;span style="color: #e34adc;"&gt;None&lt;/span&gt;&lt;span style="color: #808030;"&gt;:&lt;/span&gt;              &lt;span style="color: maroon; font-weight: bold;"&gt;print&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"\tkernel32: %x"&lt;/span&gt; &lt;span style="color: #808030;"&gt;%&lt;/span&gt; kernel32&lt;span style="color: #808030;"&gt;.&lt;/span&gt;begin&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #e34adc;"&gt;__name__&lt;/span&gt; &lt;span style="color: #808030;"&gt;=&lt;/span&gt;&lt;span style="color: #808030;"&gt;=&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"__main__"&lt;/span&gt;&lt;span style="color: #808030;"&gt;:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="padding-left: 25px;"&gt;moduleBase&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;Запустив данный скрипт в отладчике ядра, мы получим что-то вроде:&lt;br /&gt;&lt;pre&gt;process ffffffff859fbbb0   System&lt;br /&gt;process ffffffff8bbf5460   smss.exe&lt;br /&gt;    ntdll: 77d50000&lt;br /&gt;    kernel32: 76b40000&lt;br /&gt;process ffffffff81f6f6a8   csrss.exe&lt;br /&gt;    ntdll: 77d50000&lt;br /&gt;    kernel32: 76b40000&lt;br /&gt;process ffffffff892435a8   wininit.exe&lt;br /&gt;    ntdll: 77d50000&lt;br /&gt;    kernel32: 76b40000&lt;br /&gt;process ffffffff89269b98   csrss.exe&lt;br /&gt;    ntdll: 77d50000&lt;br /&gt;    kernel32: 76b40000&lt;br /&gt;.......&lt;br /&gt;&lt;/pre&gt;и ответы на свои вопросы. Но не совсем сразу. Перезапустим систему и выполним скрипт еще раз - значения будет другие. Вот теперь уже все ясно. ASLR меняет адреса загрузки при каждом ребуте, в пределах одной загрузки адреса во всех процессах одинаковы.&lt;br /&gt;&lt;br /&gt;Хочу обратить внимание на использование функции &lt;i&gt;dbgCommand&lt;/i&gt;. Она позволяет выполнять обычные команды windbg. И если какой-то функционал не реализован в &lt;b&gt;pykd&lt;/b&gt;, его можно "позаимствовать".&lt;br /&gt;&lt;br /&gt;В данном случае, мы позаимстовали  команду &lt;i&gt;.process&lt;/i&gt; c ключиком /p.  Без этого ключика можно было бы использовать функцию &lt;i&gt;setCurrentProcess&lt;/i&gt;. Но к сожалению, данная функция не включает неявную трансляцию адресов. В результате, мы не можем получить актуальный список модулей пользовательского режима для каждого процесса. Тут то нам на помощь и&amp;nbsp; пришла спасительная&amp;nbsp; функция &lt;i&gt;dbgCommand&lt;/i&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/3359491729754373146-5041543838847667951?l=pykd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pykd.blogspot.com/feeds/5041543838847667951/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://pykd.blogspot.com/2011/03/aslr.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/5041543838847667951'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/5041543838847667951'/><link rel='alternate' type='text/html' href='http://pykd.blogspot.com/2011/03/aslr.html' title='Исследуем ASLR'/><author><name>Pykd Maintainer</name><uri>http://www.blogger.com/profile/17452890529873583715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3359491729754373146.post-8796158463836869359</id><published>2011-03-04T23:49:00.000-08:00</published><updated>2011-03-04T23:49:24.138-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='release'/><title type='text'>Release 0.0.16</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Хочу представить очередной релиз проекта &lt;b&gt;pykd&lt;/b&gt;. Он примечателен тем, что над ним активно работало несколько участников и результат: количество внесенных нововведений, исправлений и улучшений значительно увеличилось. Хочу поблагодарить всех участников проекта и выразить надежду, что далее их работа в команде будет не менее плодотворной. И так, что же мы наделали:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Исправили ряд багов:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;#8336: &lt;/b&gt;в некоторых ( довольно редких ) случаях функция typedVar возвращала переменную не того типа. Баг был в системе кеширования символьной информации, сделанной для ускорения работы с типизированными переменными&lt;br /&gt;&lt;br /&gt;&lt;b&gt; #8458: &lt;/b&gt;после завершения отладочной сессии и открытии новой весь вывод в консоль windbg удваивался.&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;#8467&lt;/b&gt;: при отладке х86 платформы функция typedVarList входила в бесконечный цикл при определенных значениях адреса начала списка.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Внесли ряд изменений в API:&lt;/b&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;семейство функций loadBytes, loadDWords и.т.д&lt;/i&gt;&lt;br /&gt;Ранее, эта функции возвращали инфорамцию в виде питоновского dictinory: {0 : val1, 1 : val2, ...}.&lt;br /&gt;Учитывая, что в данном случае ключ - это просто индекс в массиве, dictionary заменили на list. &lt;br /&gt;&lt;br /&gt;&lt;i&gt;typedVar &lt;/i&gt;&lt;br /&gt;Если в функцию передать не корректный адрес ( в том числе 0x0 ), она вернет &lt;i&gt;None&lt;/i&gt;. Это удобно при отладке.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;loadDump&lt;/i&gt;&lt;br /&gt;Функция возвращает теперь булевское значение. True - дамп загружен успешно, False - произошла ошибка.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;createSession&lt;/i&gt;&lt;br /&gt;Функция объявлена устаревшей и не желательной к использованию. Теперь функция loadDump ( и новая функция startProcess ), сами создадут сессию при необходимости ( когда скрипт исполняется в отдельном процессе python, а не в windbg ).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;И наконец, что же нового:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;isValid( addr )&lt;/i&gt;&lt;br /&gt;Функция&lt;i&gt; &lt;/i&gt;проверяет валидность адреса.&lt;br /&gt;&lt;br /&gt;dbgModuleClass.image() и dbgModuleClass.pdb() &lt;br /&gt;Метода класса возвращают пути к бинарному файлу и файлу с символьной информацией ( если они есть ) в локальном хранилище символов. Хочу отметить, что метод image() вернет &lt;b&gt;полный&lt;/b&gt; путь, его можно использовать для открытия файла.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;класс typeClass&lt;/i&gt; &lt;br /&gt;Содержит информацию о типе без загрузки значения. Его удобно использовать, к примеру, если нужно определить смещение определенного поля и при этом нет нужды загружать переменную из памяти, а возможно, и адрес то этой переменной не известен&lt;br /&gt;&lt;br /&gt;&lt;i&gt;getTypeClass( moduleName, symbolName )&lt;/i&gt;&lt;br /&gt;Возвращает объект типа &lt;i&gt;typeClass&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;addSynSymbol( addr, size, name )&lt;br /&gt;delAllSynSymbols()&lt;/i&gt;&lt;br /&gt;&lt;i&gt;delSynSymbols( addr )&lt;/i&gt;&lt;br /&gt;&lt;i&gt;delSyntheticSymbolsMask( moduleName, symbolName )&lt;/i&gt;&lt;br /&gt;Функции для работы с т.н синтетическими символами - т.е символами объявленными пользователем динамически во время работы. О работе с синтетическими символами мы уже писали &lt;a href="http://pykd.blogspot.com/2011/02/windbg.html"&gt;ранее&lt;/a&gt;. Хочу отметить, что pykd сохраняет установленные символы даже если пользователь сделал .reload для модуля.&lt;br /&gt;&lt;br /&gt;Добавлен метод __str__&amp;nbsp; для всех классов, экспортируемых в python. В результате, работа с ними будет удобнее: можно написать print и получить более полезную информацию, чем просто адрес объекта.&lt;br /&gt;&lt;br /&gt;startProcess( commandLine )&lt;br /&gt;Позволяет начать отладку пользовательского процесса ( аналог команды отладчика .create ). Теперь можно из питона отлаживать программы, примерно так:&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; startProcess( "myProgram.exe" )&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; myProgram = loadModule( "myProgram")&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; b1 = bp( myProgram.myFaultRoutine )&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; go()&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; trace()&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; print reg("eax")&lt;br /&gt;Конечно, пока о реальной отладке кода речь не идет. Но, возможно, в будущем на базе &lt;b&gt;pykd&lt;/b&gt; можно будет сделать неплохую альтернативу windbg.&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/3359491729754373146-8796158463836869359?l=pykd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pykd.blogspot.com/feeds/8796158463836869359/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://pykd.blogspot.com/2011/03/release-0016.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/8796158463836869359'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/8796158463836869359'/><link rel='alternate' type='text/html' href='http://pykd.blogspot.com/2011/03/release-0016.html' title='Release 0.0.16'/><author><name>Pykd Maintainer</name><uri>http://www.blogger.com/profile/17452890529873583715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3359491729754373146.post-4893257099576848818</id><published>2011-02-28T02:25:00.000-08:00</published><updated>2011-02-28T02:53:16.763-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='synthetic symbols'/><title type='text'>Синтетические символы: делаем дизассемблер WinDbg дружелюбнее</title><content type='html'>Многие не любят использовать WinDbg для отладки "чужих" модулей, (т.е. тех, к которым нет символов) из-за его не самого дружелюбного дизассемблера. Простой пример это отображение импортов. Например, имеем небольшую функцию:&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;0:000&gt; uf 00401090&lt;br /&gt;00401090 51              push    ecx&lt;br /&gt;00401091 56              push    esi&lt;br /&gt;00401092 8b742410        mov     esi,dword ptr [esp+10h]&lt;br /&gt;00401096 6a00            push    0&lt;br /&gt;00401098 6a00            push    0&lt;br /&gt;0040109a 8d44240c        lea     eax,[esp+0Ch]&lt;br /&gt;0040109e 50              push    eax&lt;br /&gt;0040109f 6800040000      push    400h&lt;br /&gt;004010a4 56              push    esi&lt;br /&gt;004010a5 6a00            push    0&lt;br /&gt;004010a7 6800110000      push    1100h&lt;br /&gt;004010ac ff1510c04000    call    dword ptr [&lt;span style="font-weight: bold;"&gt;image+0xc010&lt;/span&gt; (0040c010)]&lt;br /&gt;004010b2 8b4c2404        mov     ecx,dword ptr [esp+4]&lt;br /&gt;004010b6 8b54240c        mov     edx,dword ptr [esp+0Ch]&lt;br /&gt;004010ba 51              push    ecx&lt;br /&gt;004010bb 56              push    esi&lt;br /&gt;004010bc 52              push    edx&lt;br /&gt;004010bd 6824c24000      push    offset image+0xc224 (0040c224)&lt;br /&gt;004010c2 6a10            push    10h&lt;br /&gt;004010c4 68fcc14000      push    offset image+0xc1fc (0040c1fc)&lt;br /&gt;004010c9 e832ffffff      call    image+0x1000 (00401000)&lt;br /&gt;004010ce 8b44241c        mov     eax,dword ptr [esp+1Ch]&lt;br /&gt;004010d2 83c418          add     esp,18h&lt;br /&gt;004010d5 50              push    eax&lt;br /&gt;004010d6 ff1514c04000    call    dword ptr [&lt;span style="font-weight: bold;"&gt;image+0xc014&lt;/span&gt; (0040c014)]&lt;br /&gt;004010dc 5e              pop     esi&lt;br /&gt;004010dd 59              pop     ecx&lt;br /&gt;004010de c3              ret&lt;/span&gt;&lt;br /&gt;Так мы ее видим в статике дизассемблера WinDbg. Но стоит дойти до адреса 004010ac, как WinDbg вычислит значение по адресу 0040c010 и выведет следующую строку:&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;call    dword ptr [image+0xc010 (0040c010) ds:0023:0040c010={kernel32!FormatMessageW (77e4f831)]&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;На самом деле, по адресу 0040c010 расположен элемент IAT (директория импортов PE). При этом логика WinDbg ясна: значение по адресу 0040c010 может измениться, поэтому он и не вычисляет значение содержимого IAT при статическом дизассемблировании. Но если мы уверены, что содержимое таблицы импорта уже сформировано, то было бы неплохо добавить символы на обращения по этим адресам.&lt;br /&gt;Для подобного рода задач в &lt;span style="font-weight: bold;"&gt;Debugger Engine&lt;/span&gt; расширений WinDbg введено понятие синтетических символов (&lt;a href="http://msdn.microsoft.com/en-us/library/ff560150%28VS.85%29.aspx#synthetic_symbols"&gt;Synthetic Symbols&lt;/a&gt;). Фактически, это символ, добавленный пользователем по заданному виртуальному адресу. Синтетический символ, как и любой другой символ модуля, имеет атрибуты имени и размера. Смысл атрибута имени очевиден, а размер символа нужен для формирования символов вида: module!SymName+33. Важная особенность: при перезагрузке символов для модуля (reload), все добавленные синтетические символы удаляются.&lt;br /&gt;Для добавления синтетического имени в расширении pykd есть 2-а пути:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Функция &lt;span style="font-weight: bold;"&gt;addSynSymbol&lt;/span&gt;(адрес_символа, размер_символа, имя_символа)&lt;/li&gt;&lt;li&gt;Метод &lt;span style="font-weight: bold;"&gt;addSynSymbol&lt;/span&gt;(смещение_символа, размер_символа, имя_символа) класса &lt;span style="font-weight: bold;"&gt;dbgModuleClass&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt; Добавление синтетического символа через метод &lt;span style="font-weight: bold;"&gt;addSynSymbol &lt;/span&gt;касса &lt;span style="font-weight: bold;"&gt;dbgModuleClass&lt;/span&gt; отличается только тем, что в качестве адреса необходимо передать смещение относительно начала модуля.&lt;br /&gt;А теперь вернемся к примеру функции, дизассемблерный листинг которой был приведен ранее. Для демонстрации работы запустим &lt;a href="http://pykd.codeplex.com/SourceControl/changeset/view/61770#1410952"&gt;скрипт ~\samples\synimp.py&lt;/a&gt;, который принимает на вход адрес внутри модуля. Скрипт, для указанного модуля, добавляет импорты, как синтетические символы с префиксом "&lt;span style="font-weight: bold; font-style: italic;"&gt;_imp_&lt;/span&gt;". После работы скрипта функция выглядит намного понятнее и о ее назначении можно догадаться без трассировки:&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;0:000&gt; uf 00401090&lt;br /&gt;00401090 51              push    ecx&lt;br /&gt;00401091 56              push    esi&lt;br /&gt;00401092 8b742410        mov     esi,dword ptr [esp+10h]&lt;br /&gt;00401096 6a00            push    0&lt;br /&gt;00401098 6a00            push    0&lt;br /&gt;0040109a 8d44240c        lea     eax,[esp+0Ch]&lt;br /&gt;0040109e 50              push    eax&lt;br /&gt;0040109f 6800040000      push    400h&lt;br /&gt;004010a4 56              push    esi&lt;br /&gt;004010a5 6a00            push    0&lt;br /&gt;004010a7 6800110000      push    1100h&lt;br /&gt;004010ac ff1510c04000    call    dword ptr [&lt;span style="font-weight: bold;"&gt;image!_imp_kernel32!FormatMessageW&lt;/span&gt; (0040c010)]&lt;br /&gt;004010b2 8b4c2404        mov     ecx,dword ptr [esp+4]&lt;br /&gt;004010b6 8b54240c        mov     edx,dword ptr [esp+0Ch]&lt;br /&gt;004010ba 51              push    ecx&lt;br /&gt;004010bb 56              push    esi&lt;br /&gt;004010bc 52              push    edx&lt;br /&gt;004010bd 6824c24000      push    offset image+0xc224 (0040c224)&lt;br /&gt;004010c2 6a10            push    10h&lt;br /&gt;004010c4 68fcc14000      push    offset image+0xc1fc (0040c1fc)&lt;br /&gt;004010c9 e832ffffff      call    image+0x1000 (00401000)&lt;br /&gt;004010ce 8b44241c        mov     eax,dword ptr [esp+1Ch]&lt;br /&gt;004010d2 83c418          add     esp,18h&lt;br /&gt;004010d5 50              push    eax&lt;br /&gt;004010d6 ff1514c04000    call    dword ptr [&lt;span style="font-weight: bold;"&gt;image!_imp_kernel32!LocalFree&lt;/span&gt; (0040c014)]&lt;br /&gt;004010dc 5e              pop     esi&lt;br /&gt;004010dd 59              pop     ecx&lt;br /&gt;004010de c3              ret&lt;/span&gt;&lt;br /&gt;Стоит обратить внимание, что функционал синтетических символов будет включен в сборку &lt;span style="font-weight: bold;"&gt;pykd&lt;/span&gt; с версии 0.0.16&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3359491729754373146-4893257099576848818?l=pykd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pykd.blogspot.com/feeds/4893257099576848818/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://pykd.blogspot.com/2011/02/windbg.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/4893257099576848818'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/4893257099576848818'/><link rel='alternate' type='text/html' href='http://pykd.blogspot.com/2011/02/windbg.html' title='Синтетические символы: делаем дизассемблер WinDbg дружелюбнее'/><author><name>Alexey R. aka EreTIk</name><uri>http://www.blogger.com/profile/15766287755602837701</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-80Zoj-o50bI/TmEmoHunebI/AAAAAAAAAAk/pPu-sdWg0U8/s220/X-COM-128.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3359491729754373146.post-4792527502129699365</id><published>2011-02-06T22:51:00.000-08:00</published><updated>2011-02-06T22:51:45.462-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='release'/><title type='text'>Release 0.0.15</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Вышел очередной релиз &lt;b&gt;pykd&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Исправили ряд мелких и не очень багов:&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;#8229&lt;/b&gt; - При вызове функции loadModule для модулей отличных от nt появлялось сообщение об ошибке. Теперь - все работает четко.&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;#8236&lt;/b&gt; - Функции вывода текста ( dprint/dprintln ) не работали с UNICODE. В результате, приходилось писать:&lt;br /&gt;dprint( str( loadUnicodeString( strAddr ) )&lt;br /&gt;Теперь str - можно ( и нужно ) опустить.&lt;br /&gt;&lt;b&gt;#8239&lt;/b&gt; - ф. &lt;span class="CodePlexPageHeader" id="TitleLabel"&gt;ptrSignByte возвращала строку, а не число со знаком, что естсетвенно приводило к неправильной работе скриптов.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Добавили следующие функции:&lt;/b&gt;&lt;br /&gt;&lt;pre&gt;&lt;i&gt;&lt;b&gt;locals()&lt;/b&gt;&lt;/i&gt;&lt;/pre&gt;Возвращает коллекцию локальных переменных в текущей области видимости. Применять можно при отладке, например так:&lt;/div&gt;a &lt;span style="color: #808030;"&gt;=&lt;/span&gt; &lt;span style="color: #e34adc;"&gt;locals&lt;/span&gt;&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;a&lt;br /&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;while&lt;/span&gt; a &lt;span style="color: #808030;"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #008c00;"&gt;10&lt;/span&gt;&lt;span style="color: #808030;"&gt;:&lt;/span&gt;&lt;br /&gt;&lt;span style="padding: 0px 20px;"&gt;trace&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="padding: 0px 20px;"&gt;a &lt;span style="color: #808030;"&gt;=&lt;/span&gt; &lt;span style="color: #e34adc;"&gt;locals&lt;/span&gt;&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;a&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Также, локальные переменные можно посмотреть для любого фрейма в коллекции, которую возвращает функция &lt;i&gt;getCurrentStack&lt;/i&gt;. Примерно так:&lt;br /&gt;&lt;pre style="background: none repeat scroll 0% 0% rgb(255, 255, 255); color: black;"&gt;frames &lt;span style="color: #808030;"&gt;=&lt;/span&gt; getCurrentStack&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;for&lt;/span&gt; f &lt;span style="color: maroon; font-weight: bold;"&gt;in&lt;/span&gt; frames&lt;span style="color: #808030;"&gt;:&lt;/span&gt; dprintln&lt;span style="color: #808030;"&gt;(&lt;/span&gt; f&lt;span style="color: #808030;"&gt;.&lt;/span&gt;&lt;span style="color: #e34adc;"&gt;locals&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&amp;nbsp;&amp;nbsp;&lt;/pre&gt;&lt;pre style="background: none repeat scroll 0% 0% rgb(255, 255, 255); color: black;"&gt;&lt;/pre&gt;&lt;pre style="background: none repeat scroll 0% 0% rgb(255, 255, 255); color: black;"&gt;&lt;b&gt;&lt;i&gt;typedVarArray( offset, moduleName, symbolName, arraySize )&lt;/i&gt;&lt;/b&gt;&lt;/pre&gt;Возвращает коллекцию элементов типа &lt;i&gt;moduleName!symbolName&lt;/i&gt;, которые располагались в памяти в виде массива размерностью &lt;i&gt;arraySize&lt;/i&gt;. Использовать можно примерно так:&lt;br /&gt;&lt;br /&gt;&lt;pre style="background: none repeat scroll 0% 0% rgb(255, 255, 255); color: black;"&gt;nt &lt;span style="color: #808030;"&gt;=&lt;/span&gt; loadModule&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"nt"&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;poolVector &lt;span style="color: #808030;"&gt;=&lt;/span&gt; typedVarArray&lt;span style="color: #808030;"&gt;(&lt;/span&gt; nt&lt;span style="color: #808030;"&gt;.&lt;/span&gt;PoolVector&lt;span style="color: #808030;"&gt;,&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"nt"&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"_POOL_DESCRIPTOR*"&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt; &lt;span style="color: #008c00;"&gt;2&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;dprintln&lt;span style="color: #808030;"&gt;(&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"non paged pool: %x"&lt;/span&gt; &lt;span style="color: #808030;"&gt;%&lt;/span&gt; poolVector&lt;span style="color: #808030;"&gt;[&lt;/span&gt;&lt;span style="color: #008c00;"&gt;0&lt;/span&gt;&lt;span style="color: #808030;"&gt;]&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;dprintln&lt;span style="color: #808030;"&gt;(&lt;/span&gt; &lt;span style="color: #0000e6;"&gt;"paged pool: %x"&lt;/span&gt; &lt;span style="color: #808030;"&gt;%&lt;/span&gt; poolVector&lt;span style="color: #808030;"&gt;[&lt;/span&gt;&lt;span style="color: #008c00;"&gt;1&lt;/span&gt;&lt;span style="color: #808030;"&gt;]&lt;/span&gt; &lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&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/3359491729754373146-4792527502129699365?l=pykd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pykd.blogspot.com/feeds/4792527502129699365/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://pykd.blogspot.com/2011/02/release-0015.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/4792527502129699365'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/4792527502129699365'/><link rel='alternate' type='text/html' href='http://pykd.blogspot.com/2011/02/release-0015.html' title='Release 0.0.15'/><author><name>Pykd Maintainer</name><uri>http://www.blogger.com/profile/17452890529873583715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3359491729754373146.post-3998771288030161572</id><published>2011-02-03T01:03:00.000-08:00</published><updated>2011-02-03T01:03:04.586-08:00</updated><title type='text'>Сборка pykd вручную.</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Без лишней воды, по пунктам:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;1. Забираем исходники&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;2. Настраиваем boost::python&amp;nbsp;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;2.1 Переменная окружения BOOST_ROOT &lt;/b&gt;&lt;br /&gt;Должна указывать соответственно на каталог, где лежит используемая версия boost.&lt;br /&gt;У меня это:&amp;nbsp; С:\lib\boost_1_40_0&lt;br /&gt;&lt;b&gt;2.2 Сборка boost::python&lt;/b&gt;&lt;br /&gt;В настройках проекта забиты следующие пути к собранным библиотекам:&lt;br /&gt;&lt;i&gt;$(BOOST_ROOT)\stage - &lt;/i&gt;для х86 сборки&lt;br /&gt;&lt;i&gt;$(BOOST_ROOT)\stage64 - &lt;/i&gt;для х64 сборки &lt;i&gt;&lt;br /&gt;&lt;/i&gt;Чтобы собрать соответствующие библиотеки, нужно выполнить следующие команды, установив текущую директорию в &lt;i&gt;$(BOOST_ROOT)&lt;/i&gt;&lt;br /&gt;Для&amp;nbsp; x86:&lt;br /&gt;bjam --stagedir=stage --with-python stage &lt;br /&gt;&amp;nbsp;И для x64:&lt;br /&gt;bjam address-model=64 --stagedir=stage64 --with-python stage&lt;br /&gt;Возможно, вам понадобится сначала установить bjam&amp;nbsp; ( &lt;a href="http://www.boost.org/users/download/"&gt;ссылка&lt;/a&gt; )&lt;br /&gt;&lt;b&gt;2.3 Указание версии python&lt;/b&gt;&lt;br /&gt;Если у вас на машине есть несколько версий python и вы хотите явно указать, какую использовать, необходимо отредактировать файл user-config.jam и добавить в него строчки, к примеру, такие:&lt;br /&gt;using python : 2.6 ;&lt;br /&gt;using python : 2.7 ;&lt;br /&gt;Теперь можно собрать библиотеки явно указав версию python&lt;br /&gt;Для&amp;nbsp; x86:&lt;br /&gt;bjam --stagedir=stage --with-python stage python=2.7&lt;br /&gt;И для x64:&lt;br /&gt;bjam address-model=64 --stagedir=stage64 --with-python stage python=2.7&lt;br /&gt;Тут можно подробнее почитать:&lt;br /&gt;&lt;a href="http://www.boost.org/doc/libs/1_45_0/libs/python/doc/building.html"&gt;http://www.boost.org/doc/libs/1_45_0/libs/python/doc/building.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;3. Настройка путей к python&lt;/b&gt;&lt;br /&gt;Для сборки понадобятся заголовочные файлы и библиотека экспорта от соответствующей версии python. Для указания путей используется переменная окружения &lt;b&gt;PYTHON_ROOT&lt;/b&gt;, которая должна указывать на каталог установки Python. Если при сборки boost::python была задана конкртная версия python, то перемнная &lt;b&gt;PYTHON_ROOT&lt;/b&gt; должна ссылаться на инсталляцию python соответствующей версии.&lt;br /&gt;К примеру, у меня на машине переменная &lt;b&gt;PYTHON_ROOT &lt;/b&gt;= C:\Python26.&amp;nbsp; И установлены две версии ( x86 и x64) python:&lt;br /&gt;C:\Python26\x86\&amp;nbsp; &lt;br /&gt;C:\Python26\x64\ &lt;br /&gt;&lt;br /&gt;&lt;b&gt;4. Настройка путей к DBG SDK&lt;/b&gt;&lt;br /&gt;Пути к DBG SDK&amp;nbsp; задаются через переменную окружения&amp;nbsp;&lt;b&gt; DBG_SDK_ROOT. &lt;/b&gt;Сам DBG SDK находится в каталоге установки windbg&lt;b&gt;. &lt;/b&gt;&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/3359491729754373146-3998771288030161572?l=pykd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pykd.blogspot.com/feeds/3998771288030161572/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://pykd.blogspot.com/2011/02/pykd.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/3998771288030161572'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/3998771288030161572'/><link rel='alternate' type='text/html' href='http://pykd.blogspot.com/2011/02/pykd.html' title='Сборка pykd вручную.'/><author><name>Pykd Maintainer</name><uri>http://www.blogger.com/profile/17452890529873583715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3359491729754373146.post-8599193569730320898</id><published>2011-01-26T00:18:00.000-08:00</published><updated>2011-01-26T00:43:45.529-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='windbg extensions'/><title type='text'>Скрипты для windbg</title><content type='html'>Целью проекта &lt;b&gt;pykd&lt;/b&gt; является интеграция python в windbg. А целью интеграции python в windbg - замена стандартного скриптового движка на более удобный. А удобный скриптовый движок нам нужен, чтобы быстро и легко автоматизировать свои действия. По-моему, так?&lt;br /&gt;&lt;br /&gt;В данном посте я хочу предствить ряд скриптов, написанных с помощью &lt;b&gt;pykd&lt;/b&gt;, которые могут пригодится в повседневной работе многим. Описание их работы есть в wiki на сайте проекта ( &lt;a href="http://pykd.codeplex.com/wikipage?title=snippets_rus"&gt;ссылка&lt;/a&gt; ) и я не буду репостить текст. Допустим вы уже прочитали статью с wiki и уже хотите попробовать. Где взять сами скрипты? Через дистрибутив они не распространяются, единственный способ - скачать из репозитория исходного кода ( &lt;a href="http://pykd.codeplex.com/SourceControl/changeset/view/60688"&gt;ссылка&lt;/a&gt; ). В каталоге &lt;b&gt;&lt;i&gt;samples&lt;/i&gt;&lt;/b&gt; лежат, как не трудно догадаться, разные демонстрационный примеры. А в каталоге &lt;b&gt;&lt;i&gt;snippets&lt;/i&gt;&lt;/b&gt; - как раз то, что мы ищем. Допустим вы скачали исходный код, куда теперь распаковать каталоги со скриптами? Это не важно - в любой каталог, куда есть доступ. Для удобства использования настоятельно рекомендуется добавить этот путь в переменную окружения &lt;b&gt;$PYTHONPATH&lt;/b&gt;. В этом случае, для вызова скрипта не нужно указывать  полный путь, даже расширение можно опустить, примерно так:&lt;br /&gt;&lt;i&gt;!py export nt Zw*SetInformation*&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Если вы написали полезный скрпит и хотите поделится им - присылайте ссылки на опубликованный код или исходный код и мы опубликуем его на сайте проекта под действующий лицензией.&lt;br /&gt;&lt;br /&gt;Почта: &lt;a href="mailto:pykd.codeplex@hotmail.com"&gt;pykd.codeplex@hotmail.com&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3359491729754373146-8599193569730320898?l=pykd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pykd.blogspot.com/feeds/8599193569730320898/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://pykd.blogspot.com/2011/01/windbg.html#comment-form' title='Комментарии: 3'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/8599193569730320898'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/8599193569730320898'/><link rel='alternate' type='text/html' href='http://pykd.blogspot.com/2011/01/windbg.html' title='Скрипты для windbg'/><author><name>Pykd Maintainer</name><uri>http://www.blogger.com/profile/17452890529873583715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3359491729754373146.post-1783975894789848666</id><published>2011-01-20T23:59:00.000-08:00</published><updated>2011-04-22T00:47:51.907-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='API'/><title type='text'>typedVar</title><content type='html'>При разработке &lt;b&gt;pykd&lt;/b&gt; мы старались не трансиловать механически функционал из Debug Engine, а реализвать API, удобный при повседневной работе в windbg. А что делает пользователь в отладчике чаще всего? Конечно, просматривает значение переменных! Соответственно, для автоматизации его работу в первую очередь нужна функция для удобной и быстрой работы с переменными. Для этого мы реализовали функцию typedVar. &lt;br /&gt;&lt;br /&gt;Вот ее прототип:&lt;/br&gt;&lt;font size=+1&gt;&lt;br /&gt;&lt;b&gt;typedVar&lt;/b&gt;( string &lt;i&gt;moduleName&lt;/i&gt;, string &lt;i&gt;typeName&lt;/i&gt;, long &lt;i&gt;address &lt;/i&gt;)&lt;/font&gt;&lt;/br&gt;&lt;br /&gt;&lt;i&gt;moduleName &lt;/i&gt; - имя модуля, содержащего тип&lt;br /&gt;&lt;i&gt;typeName&lt;/i&gt; - имя типа переменной&lt;br /&gt;&lt;i&gt;address&lt;/i&gt; - виртуальный адрес переменной&lt;br /&gt;&lt;br /&gt;Функция создает объект типа &lt;i&gt;typedVarClass&lt;/i&gt; и динамически добавляет ему аттрибуты, с именами соответствующими именам полей структуры заданного типа. Если поле является сложным типом - операция повторяется рекурсивно. В результате, мы в python е получаем объект, с которым можем работать в той же манере, как и в Си:&lt;br /&gt;&lt;p&gt;p &lt;span style='color:#808030; '&gt;=&lt;/span&gt; typedVar&lt;span style='color:#808030; '&gt;(&lt;/span&gt; &lt;span style='color:#0000e6; '&gt;"nt"&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; &lt;span style='color:#0000e6; '&gt;"_ETHREAD"&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt;  threadAddr &lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;print&lt;/span&gt; &lt;span style='color:#0000e6; '&gt;"Wait time:  %d"&lt;/span&gt; &lt;span style='color:#808030; '&gt;%&lt;/span&gt; p&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Tcb&lt;span style='color:#808030; '&gt;.&lt;/span&gt;WaitTime&lt;br /&gt;&lt;/p&gt;Данный код выведет значение счетчика ожидания потока, адрес которого задан в переменной threadAddr. Массивы тоже будут корректно обработаны. Обращаться к элементу массива можно также в стиле Си:&lt;br /&gt;&lt;p&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;print&lt;/span&gt; p&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Tcb&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Alerted&lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#008c00; '&gt;1&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;В работе часто приходится иметь дело с связанными списками структур. Конечно, можно в цикле вызвать ф. typedVar для получения значений списка. В &lt;b&gt;pykd&lt;/b&gt; для этого реализована специальная функция: typedVarList.&lt;br /&gt;&lt;br /&gt;Вот ее прототип:&lt;/br&gt;&lt;font size=+1&gt;&lt;br /&gt;&lt;b&gt;typedVarList&lt;/b&gt;( long &lt;i&gt;head_address&lt;/i&gt;, string &lt;i&gt;moduleName&lt;/i&gt;, string &lt;i&gt;typeName&lt;/i&gt;, &lt;i&gt;fieldName&lt;/i&gt;)&lt;/font&gt;&lt;/br&gt;&lt;br /&gt;&lt;i&gt;head_address&lt;/i&gt; - адрес головы списка&lt;br /&gt;&lt;i&gt;moduleName &lt;/i&gt; - имя модуля, содержащего тип элемента списка&lt;br /&gt;&lt;i&gt;typeName&lt;/i&gt; - имя типа элемента списка&lt;br /&gt;&lt;i&gt;fieldName&lt;/i&gt; - имя поля, содержащего указатель на следующий элемент списка.&lt;br /&gt;&lt;br /&gt;Функция возвращает питоновский лист, каждый элемент которого имеет тип  &lt;i&gt;typedVarClass&lt;/i&gt;. Соответственно, для элементов этого списка справедливо все, что сказано выше. Проиллюстрируем на примере, как это работает:&lt;br /&gt;&lt;p&gt;nt &lt;span style='color:#808030; '&gt;=&lt;/span&gt; loadModule&lt;span style='color:#808030; '&gt;(&lt;/span&gt; &lt;span style='color:#0000e6; '&gt;"nt"&lt;/span&gt; &lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;br /&gt;processList &lt;span style='color:#808030; '&gt;=&lt;/span&gt; typedVarList&lt;span style='color:#808030; '&gt;(&lt;/span&gt; nt&lt;span style='color:#808030; '&gt;.&lt;/span&gt;PsActiveProcessHead&lt;span style='color:#808030; '&gt;,&lt;/span&gt; &lt;span style='color:#0000e6; '&gt;"nt"&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; &lt;span style='color:#0000e6; '&gt;"_EPROCESS"&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; &lt;span style='color:#0000e6; '&gt;"ActiveProcessLinks"&lt;/span&gt;  &lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;for&lt;/span&gt; process &lt;span style='color:#800000; font-weight:bold; '&gt;in&lt;/span&gt; processList&lt;span style='color:#808030; '&gt;:&lt;/span&gt;&lt;br /&gt;&lt;span style="padding:0px 20px;"&gt;dprintln&lt;span style='color:#808030; '&gt;(&lt;/span&gt; &lt;span style='color:#0000e6; '&gt;""&lt;/span&gt;&lt;span style='color:#808030; '&gt;.&lt;/span&gt;join&lt;span style='color:#808030; '&gt;(&lt;/span&gt; &lt;span style='color:#808030; '&gt;[&lt;/span&gt; &lt;span style='color:#e34adc; '&gt;chr&lt;/span&gt;&lt;span style='color:#808030; '&gt;(&lt;/span&gt;i&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;for&lt;/span&gt; i &lt;span style='color:#800000; font-weight:bold; '&gt;in&lt;/span&gt; process&lt;span style='color:#808030; '&gt;.&lt;/span&gt;ImageFileName&lt;span style='color:#808030; '&gt;.&lt;/span&gt;values&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#808030; '&gt;]&lt;/span&gt; &lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;Данный код выведет на экран список процессов&lt;br /&gt;&lt;br /&gt;Третья полезная функция для работы с переменными: &lt;i&gt;containingRecord&lt;/i&gt;. Это аналог макроса CONTAINING_RECORD. &lt;br /&gt;&lt;br /&gt;Вот ее прототип:&lt;/br&gt;&lt;font size=+1&gt;&lt;br /&gt;&lt;b&gt;containingRecord&lt;/b&gt;( long &lt;i&gt;field_address&lt;/i&gt;, string &lt;i&gt;moduleName&lt;/i&gt;, string &lt;i&gt;typeName&lt;/i&gt;, &lt;i&gt;fieldName&lt;/i&gt;)&lt;/font&gt;&lt;/br&gt;&lt;br /&gt;&lt;i&gt;field_address&lt;/i&gt; - адрес поля структуры.&lt;br /&gt;&lt;i&gt;moduleName &lt;/i&gt; - имя модуля, содержащего тип &lt;br /&gt;&lt;i&gt;typeName&lt;/i&gt; - имя типа элемента списка&lt;br /&gt;&lt;i&gt;fieldName&lt;/i&gt; - имя поля, адрес которого задан переменной field_address&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Битовые поля&lt;/h3&gt;Функция &lt;i&gt;typedVar&lt;/i&gt; не поддерживает работу с битовымии полями в полном объеме. Если в структуре объявлено битовое поле:&lt;br /&gt;&lt;p&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;struct&lt;/span&gt; A &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="padding:0px 20px;"&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;int&lt;/span&gt;   a &lt;span style='color:#800080; '&gt;:&lt;/span&gt; &lt;span style='color:#008c00; '&gt;10&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="padding:0px 20px;"&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;int&lt;/span&gt;   b &lt;span style='color:#800080; '&gt;:&lt;/span&gt; &lt;span style='color:#008c00; '&gt;20&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800080; '&gt;};&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;Мы в питоне получим, что obj.a = obj.b. Т.е структура битового поля не сохраняется и придется дополнительно накладывать битовые маски. Интересно, что команда &lt;b&gt;dt&lt;/b&gt; в windbg правильно отображает битовые поля. Так что тут есть над чем поработать!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3359491729754373146-1783975894789848666?l=pykd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pykd.blogspot.com/feeds/1783975894789848666/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://pykd.blogspot.com/2011/01/typedvar.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/1783975894789848666'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/1783975894789848666'/><link rel='alternate' type='text/html' href='http://pykd.blogspot.com/2011/01/typedvar.html' title='typedVar'/><author><name>Pykd Maintainer</name><uri>http://www.blogger.com/profile/17452890529873583715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3359491729754373146.post-695986193325253080</id><published>2011-01-18T23:58:00.000-08:00</published><updated>2011-01-19T01:52:54.324-08:00</updated><title type='text'>PYKD: Getting Started</title><content type='html'>Логично в самом начале жизни блога написать о том, как начать работу с PYKD. &lt;br /&gt;Основная задача pykd - подружить windbg и python. А поэтому разумным кажется требование иметь на машине предустановленные версии этих продуктов. Если вы еще читаете это, я уверен, что у вас уже установлен windbg или по крайней мере, вы знаете о чем идет речь. На установке python остановимся чуть подробнее. Какую версию выбрать? 1) Разрядность ( 32 или 64 бита ) должна совпадать с разрядностью windbg 2) Версия python должна поддерживаться pykd. В настоящее время поддерживается только 2.6.х ( для других версий 2.x можно собрать самостоятельно ). Таким образом, мы однозначно определяем, какой именно пакет скачать с &lt;a href="http://www.python.org/"&gt;www.python.org&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;Переходим к установке pykd. К сожалению, в настоящее время автоматический инсталлятор отсутствует и придется все делать вручную. Загружаем архив с последней версией: &lt;a href="http://pykd.codeplex.com/releases"&gt;ссылка&lt;/a&gt;.  В архиве два каталога - x64 и x86, в которых лежат сборки pykd.pyd соответствующей разрядности. Выбираем нужную версию и копируем ее. Только вот куда? В принципе, можно в любой каталог, из которого возможнен запуск исполняемых файлов. Наиболее удобным является подкаталог winext, расположенный в каталоге установки windbg. При выборе этого каталога при последующей загрузке расширения в windbg достаточно будет просто указать имя. В других случаях придется указывать полный путь.&lt;br /&gt;&lt;br /&gt;Можно начинать работу? Не совсем. Для работы pykd необходимо, чтобы на машине был установлен Microsoft Visual C++ 2005 SP1 Redistributable Package нужной версии и разрядности.  Загрузить его можно с сайта Microsoft или со страницы загрузки: &lt;a href="http://pykd.codeplex.com/releases"&gt;ссылка&lt;/a&gt;, файл vcredist_x86 или vcredist_x64. С выбором нужного, надеюсь, понятно. Вот теперь - можно начинать!&lt;br /&gt;&lt;br /&gt;Запускаем отладчик windbg и открываем любую отладочную сессию: начинаем отладку пользоватеьского процесса, загружаем креш-дамп или подключаемся к отладчику ядра удаленной машины. Далее необходимо загрузить расширение. Если вы установили его по рекомендованному пути, сделать это просто:&lt;br /&gt;.load pykd.pyd&lt;br /&gt;Проверим, что все заработало, вводим команду !pycmd для перехода в режим интерпретатора python&lt;br /&gt;1&gt;!pycmd&lt;br /&gt;&gt;&gt;&gt; print "hello world!"&lt;br /&gt;hello world!&lt;br /&gt;&gt;&gt;&gt;&lt;br /&gt;Для выхода из режима интерпретатора просто вводим пустую строку. Если у вас получилось вывести на экран приветственную строку, значит с установкой и настройкой все получилось. Теперь пора подумать, какую из этого можно извлечь пользу. Сам по себе интерпретатор python кончено очень занимательная штука, но нам он нужен для управления отладчиком. Поскольку pykd.pyd является не только расширением для windbg, но и модулем python, он нам в этом и поможет:&lt;br /&gt;1&gt;!pycmd&lt;br /&gt;&gt;&gt;&gt; from pykd import *&lt;br /&gt;&gt;&gt;&gt; eax = reg("eax")&lt;br /&gt;&gt;&gt;&gt; print eax&lt;br /&gt;125&lt;br /&gt;&gt;&gt;&gt;&lt;br /&gt;Мы использовали функцию reg, реализованную в модуле pykd. Полный список API приведен &lt;a href="http://pykd.codeplex.com/wikipage?title=doc_api_rus"&gt;здесь&lt;/a&gt;.&lt;br /&gt;Сессия интерпретатора питона длится, пока pykd не будет выгружен. Поэтому можно много позже сделать&lt;br /&gt;1&gt;!pycmd&lt;br /&gt;&gt;&gt;&gt; print eax&lt;br /&gt;125&lt;br /&gt;и получить сохраненное в контексте python значение. &lt;br /&gt;&lt;br /&gt;Кроме глобальной сессии интерпретора python есть возможность выполнить скрипт в изолированной среде:&lt;br /&gt;1&gt;!py myscript.py "hello script"&lt;br /&gt;hello from script&lt;br /&gt;На сайте проекта приведены как небольшие демонстрационные примеры таких скриптов, так и скрипты, которые вы можете использовать в своей работе. &lt;a href="http://pykd.codeplex.com/wikipage?title=snippets_rus"&gt;Здесь&lt;/a&gt; можно получить подробную информацию.&lt;br /&gt;&lt;br /&gt;И так, вы попробовали и:&lt;br /&gt;1) вам понравилось. Тогда помогите проекту: примите участие в разработке, написании документации, пришлите свой полезный скрипт, киньте ссылку коллеге - он то наверняка сидит без дела целыми днями в инете. Да просто напишите нам свое мнение - для нас это будет очень ценно.&lt;br /&gt;2) не понравилось. Очень вам просим, напишите, что именно! Это очень важно для нас.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3359491729754373146-695986193325253080?l=pykd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pykd.blogspot.com/feeds/695986193325253080/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://pykd.blogspot.com/2011/01/pykd-getting-started.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/695986193325253080'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/695986193325253080'/><link rel='alternate' type='text/html' href='http://pykd.blogspot.com/2011/01/pykd-getting-started.html' title='PYKD: Getting Started'/><author><name>Pykd Maintainer</name><uri>http://www.blogger.com/profile/17452890529873583715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3359491729754373146.post-174014501719064084</id><published>2011-01-17T09:28:00.000-08:00</published><updated>2011-01-17T09:28:35.598-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='release'/><title type='text'>Release 0.0.14</title><content type='html'>&lt;p&gt;В релизе 0.0.14 исправлен один серьезный &lt;a href="http://pykd.codeplex.com/workitem/8103"&gt;баг&lt;/a&gt;, заключавшийся в нарушении изоляции выполнений скриптов через расширение отладчика !py. В результате, все скрипты исполнялись в контексте одного интерпретатора и появлялись некоторые странные артефакты. К примеру, если код импортированных модулей изменялся, это не отражалось на выполнение скрипта, импортирующего модуль.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;В класс typedVarClass добавлен метод получения аттрибутов __getattr__. Получение аттрибута трактуется как вычисление адреса переменной(функции) модуля.&lt;br /&gt;Сравните два фрагмента кода. В старой редакции для получения адреса переменной необходимо было явно вызывать функцию getOffset:&lt;br /&gt;&lt;br /&gt;&lt;span style='color:#696969; '&gt;# Old version&lt;/span&gt;&lt;br /&gt;nt &lt;span style='color:#808030; '&gt;=&lt;/span&gt; loadModule&lt;span style='color:#808030; '&gt;(&lt;/span&gt; &lt;span style='color:#0000e6; '&gt;"nt"&lt;/span&gt; &lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;br /&gt;nt&lt;span style='color:#808030; '&gt;.&lt;/span&gt;PsActiveProcessHead &lt;span style='color:#808030; '&gt;=&lt;/span&gt; getOffset&lt;span style='color:#808030; '&gt;(&lt;/span&gt; &lt;span style='color:#0000e6; '&gt;"nt"&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; &lt;span style='color:#0000e6; '&gt;"PsActiveProcessHead"&lt;/span&gt; &lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;br /&gt;processList &lt;span style='color:#808030; '&gt;=&lt;/span&gt; typedVarList&lt;span style='color:#808030; '&gt;(&lt;/span&gt; nt&lt;span style='color:#808030; '&gt;.&lt;/span&gt;PsActiveProcessHead&lt;span style='color:#808030; '&gt;,&lt;/span&gt; &lt;span style='color:#0000e6; '&gt;"nt"&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; &lt;span style='color:#0000e6; '&gt;"_EPROCESS"&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; &lt;span style='color:#0000e6; '&gt;"ActiveProcessLinks"&lt;/span&gt;  &lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Теперь в этом нет нужды, при обращении к аттрибуту экземпляра класса модуля, эта функция будет вызвана автоматически&lt;br /&gt;&lt;br /&gt;&lt;span style='color:#696969; '&gt;# New version&lt;/span&gt;&lt;br /&gt;nt &lt;span style='color:#808030; '&gt;=&lt;/span&gt; loadModule&lt;span style='color:#808030; '&gt;(&lt;/span&gt; &lt;span style='color:#0000e6; '&gt;"nt"&lt;/span&gt; &lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#696969; '&gt;#nt.PsActiveProcessHead = getOffset( "nt", "PsActiveProcessHead" )&lt;/span&gt;&lt;br /&gt;processList &lt;span style='color:#808030; '&gt;=&lt;/span&gt; typedVarList&lt;span style='color:#808030; '&gt;(&lt;/span&gt; nt&lt;span style='color:#808030; '&gt;.&lt;/span&gt;PsActiveProcessHead&lt;span style='color:#808030; '&gt;,&lt;/span&gt; &lt;span style='color:#0000e6; '&gt;"nt"&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; &lt;span style='color:#0000e6; '&gt;"_EPROCESS"&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; &lt;span style='color:#0000e6; '&gt;"ActiveProcessLinks"&lt;/span&gt;  &lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;br /&gt;&lt;p&gt;При использовании команды !pycmd часто возникает желание распечатать содержимое переменной, полученной через вызов typedVar. До этого единственным способом было явное обращение к аттрибутам ( соответствующим полям стурктуры ). Оператор print - не работал. Поэтому в класс typedVarClass был добавлен метод __str__, возвращающий текстовое представление класса:&lt;br /&gt;&lt;br /&gt;p &lt;span style='color:#808030; '&gt;=&lt;/span&gt; typedVarList&lt;span style='color:#808030; '&gt;(&lt;/span&gt; &lt;span style='color:#0000e6; '&gt;"nt"&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; &lt;span style='color:#0000e6; '&gt;"_EPROCESS"&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; processAddr  &lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;print&lt;/span&gt; p&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3359491729754373146-174014501719064084?l=pykd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pykd.blogspot.com/feeds/174014501719064084/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://pykd.blogspot.com/2011/01/release-0014.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/174014501719064084'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/174014501719064084'/><link rel='alternate' type='text/html' href='http://pykd.blogspot.com/2011/01/release-0014.html' title='Release 0.0.14'/><author><name>Pykd Maintainer</name><uri>http://www.blogger.com/profile/17452890529873583715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3359491729754373146.post-6665203821535859503</id><published>2011-01-01T00:00:00.000-08:00</published><updated>2011-07-04T00:31:33.272-07:00</updated><title type='text'>Оставить отзыв</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Если у вас есть любые предложения, жалобы или слова благодарности, оставьте комментарий к этому сообщению.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3359491729754373146-6665203821535859503?l=pykd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pykd.blogspot.com/feeds/6665203821535859503/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://pykd.blogspot.com/2011/01/blog-post.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/6665203821535859503'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3359491729754373146/posts/default/6665203821535859503'/><link rel='alternate' type='text/html' href='http://pykd.blogspot.com/2011/01/blog-post.html' title='Оставить отзыв'/><author><name>Pykd Maintainer</name><uri>http://www.blogger.com/profile/17452890529873583715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
