Активная инфильтрация в ботнет при помощи автоматического обратного инжиниринга командного протокола

АННОТАЦИЯ

Автоматический обратный инжиниринг протокола важен для многих приложений в сфере IT-безопасности, в том числе, для анализа ботнетов и борьбы с ними. Понимание командного протокола, используемого ботнетом, критически важно, как для противодействия его вредоносной деятельности, так и для активной инфильтрации в него. Зачастую аналитикам необходимо переписать сообщения, полученные или отправленные ботом для того чтобы воспрепятствовать вредоносной деятельности, а у ботмастера создать иллюзию, что его бот успешно выполнил задание. Для того чтобы такое переписывание сообщений было возможно, нам требуется подробная информация о назначении и структуре сообщений, следующих в обоих направлениях несмотря на тот факт, что обычно в нашем распоряжении имеется реализация только одной стороны диалога, а именно исполняемый двоичный файл бота. Существующие техники не дают возможности переписывать сообщения таким образом. В этой публикации мы предлагаем техники для воссоздания формата сообщений протокола, отправленных приложением. Техники эти позволяют воссоздать спецификацию протокола и сделать выводы о семантике полей для сообщений, как отправленных, так и полученных приложением. Наши техники делают возможным переписывание сообщений командного протокола с целью активной инфильтрации в ботнет. Мы реализовали наши техники в Dispatcher, инструментальном средстве для воссоздания формата и семантики полей, как полученных, так и отправленных сообщений. Мы используем Dispatcher для анализа ботнета MegaD, широко распространенного спамового ботнета, использующего собственный недокументированный командный протокол, и показываем, что извлеченная при помощи Dispatcher информация позволяет переписывать сообщения командного протокола этого ботнета.

*Этот материал основан на работе, частично поддерживаемой Национальным Научным Фондом по грантам No. 0311808, No. 0448452, No. 0627511, и CCF-0424422, Офисом ВВС по научным исследованиям, по гранту MURI Grant No. 22178970-4170, Офисом Исследований Армии, по гранту Cyber-TA Research Grant No. W911NF-06-1-0316, и программой CyLab в университете Карнеги Меллон по гранту DAAD19-02-1-0389 от офиса исследований Армии. Любые мнения, данные и выводы или рекомендации в этом материале относятся к авторам и необязательно отражают точку зрения Национального Научного Фонда, Офиса ВВС по научным исследованиям или Офиса Исследований Армии.

Разрешение делать цифровые или твердые копии этого документа целиком или частями для личного или коллективного использования предоставляется бесплатно при условии, что копии не используются для получения коммерческой прибыли и что данное примечание на них присутствует без сокращений на первой странице. Для копирования на других условиях, для републикации или рассылки требуется предварительное разрешение и/или оплата.

CCS'09, 9-13 ноября 2009, Чикаго, Иллинойс, США. Copyright 2009 ACM 978-1-60558-352-5/09/11 ...$10.00.


Категории и тематические дескрипторы

C.2.2 [Организация компьютерных систем]: Сетевые протоколы; D.4.6 [Операционные системы]: Безопасность и защита

Общие термины

Безопасность

Ключевые слова

Обратный инжиниринг протокола, инфильтрация в ботнет, двоичный анализ

1.   ВВЕДЕНИЕ

Техника автоматического обратного инжиниринга протокола позволяет получить спецификацию протокола для неизвестных или недокументированных протоколов, имея реализацию протокола на уровне приложения [18,22,25,26,35,36,38,49]. Наличие подробной спецификации протокола может быть полезным в таких приложениях безопасности, как фаззинг (fuzzing) [22], идентификация приложений [17], глубокий анализ пакетов (deep packet inspection) [29] или сигнатурная фильтрация [27].

Одним из важных приложений автоматического обратного инжиниринга протокола является анализ ботнетов и инфильтрация в них. Ботнеты, большие сети инфицированных компьютеров, в наши дни стали одной из серьезнейших угроз в Internet. С их помощью осуществляются многие виды вредоносной или преступной деятельности, такие, как рассылка спама, фишинг, "накрутка" переходов по ссылкам и распределенные DoS-атаки (атаки типа "отказ в обслуживании") [10, 28, 32]. Сердцем ботнета является его командный протокол, при помощи которого боты находят в сети координаты для связи и при помощи которого ботмастер организует и направляет работу своего "стада". Автоматический обратный инжиниринг здесь поможет понять работу командного протокола ботнета и получить много полезных сведений о возможностях ботов и целях ботнета.

Вдобавок к пониманию работы командного протокола, аналитик получит возможность напрямую взаимодействовать с ботнетом в исследовательских целях. В исследовании [33] экономическая подоплека ботнета Storm анализировалась при помощи подмены команд, посылаемых ботам. В других случаях аналитику может потребоваться подменить сообщения ботов, отсылаемые ими своему командному центру. Например, аналитику может потребоваться обмануть командный центр относительно возможностей некоторого конкретного бота, заставить ботмастера поверить, что бот в состоянии отсылать сообщения e-mail (притом, что на самом деле все исходящие SMTP-соединения бота заблокированы) или что бот располагает высокоскоростным соединением с Internet (в то время как на самом деле его трафик ограничивается и фильтруется).

Для того чтобы успешно подделать сообщение бота, аналитик должен понимать назначение сообщения, структуру его полей и знать смысл каждого поля

В то время как старые ботнеты основывали свой командный протокол на сервисах IRC, многие из новых ботнетов реализуют свои собственные недокументированные протоколы. [20,31,43].

Анализ такого командного протокола представляет собой трудную задачу. Обратный инжиниринг, выполняемый вручную,  здесь требует много времени и чреват многими ошибками. С другой стороны, имевшиеся ранее техники автоматического обратного инжиниринга страдали различными ограничениями, не позволяющими создавать с их помощью поддельные сообщения. Техники, использующие сетевой трафик в качестве входных данных [25,26,35,36], оказываются бессильны при использовании ботнетом шифрования или специально запутанного текста. У техник, которые основываются на наблюдении за реакциями на входные данные участников обмена (клиента или сервера) [18, 22, 38,49] есть два серьезных ограничения. Во-первых, в реальных условиях они могут наблюдать только за одной стороной диалога, например, видят только полученные сообщения. Для полного понимания протокола им необходимо иметь доступ к обеим сторонам диалога. К сожалению, при изучении ботнета аналитик зачастую имеет в своем распоряжении только бота. То же самое относится и к анализу других, вполне легальных систем, например систем обмена мгновенными сообщениями, когда аналитику доступна только клиентская часть системы. Во-вторых, техники, основывающиеся на анализе потока двоичных данных, никак не учитывают семантического аспекта анализируемого протокола. А семантика сообщения имеет фундаментальное значение для понимания смысла и целей сообщения, что, в свою очередь, необходимо для того чтобы идентифицировать нужную часть диалога, переписать и подменить ее. Семантическая информация необходима для анализа любого типа протоколов, как текстовых, так и двоичных. Хотя в случае текстовых протоколов аналитик может иногда сделать какие-то выводы из контекста, зачастую и это оказывается невозможным. Например, целое число в кодировке ASCII может обозначать, среди прочего, размер данных, номер порта, задержку таймера или контрольную сумму.

В этом документе мы представляем новую технику восстановления формата сообщений по сообщениям, отправленным программой. Она позволяет воссоздать формат сообщений протокола, наблюдая только одну из сторон обмена сообщениями. Новые техники нужны нам по той причине, что имеющиеся сейчас техники анализа формата сообщений по полученным сообщениям основываются на том, что «метят» входные данные программы и следят за их дальнейшим движением. Однако при этом большая часть данных в отсылаемых сообщениях не связана с «мечеными» данными в полученных сообщениях. Мы вместо этого используем следующую идею: программы хранят значения полей в буферах в памяти и конструируют сообщение для последующей его отправки, составляя его как, комбинацию буферов. Таким образом, структура буфера сообщения в памяти является инверсией структуры этого сообщения. Мы также представляем новую технику для вывода заключений о значении полей в сообщениях, полученных и отправленных приложением. Наша техника основывается на анализе типов данных и значительно расширяет ту семантическую информацию, которая уже доступна в программе через посредство наблюдения за использованием данных из принятых сообщений в местах, смысл которых уже известен, и за тем, как данные с уже известным смыслом используются для конструирования отправляемых сообщений. Кроме того, мы предлагаем расширения для недавно предложенной техники идентификации буферов, содержащих незашифрованное полученное сообщение [48]. Наши расширения распространяют сферу действия этой техники на случай приложения, где нет четкой границы между дешифрованием и дальнейшей обработкой данных, а также на случай идентификации буфера, содержащего незашифрованное отправленное сообщение.

Мы реализовали наши техники в Dispatcher, инструментальном средстве для восстановления формата сообщения и значений его полей по полученным и отправленным сообщениям. Мы применяем Dispatcher для анализа командного протокола, используемого MegaD, одного из самых распространенных спамовых ботнетов, действующих сегодня [7,32]. Насколько нам известно, ботнет MegaD использует собственный, зашифрованный двоичный  командный протокол, который нигде еще не был задокументирован, и тем самым представляет собой идеальный образец для испытания нашей системы. Мы покажем, что информация о протоколе, извлеченная при помощи Dispatcher, может использоваться для подделки сообщений  командного протокола MegaD. Кроме того, мы используем четыре открытых протокола (HTTP, FTP, ICQ и DNS) для того чтобы сравнить формат сообщений, автоматически восстановленный при помощи Dispatcher с форматом, который восстанавливает Wireshark [12], известный и распространенный в наши дни анализатор протоколов, содержащий написанные вручную грамматики протоколов.

В целом, наш вклад состоит в следующем:

    Мы предлагаем новую технику для восстановления формата сообщений протокола по сообщениям, отправленным приложением. Ранее это можно было сделать только в отношении принятых сообщений. Наша техника позволяет восстановить полный формат протокола даже в случае, когда доступна только одна из сторон, участвующих в обмене.

    Мы представляем технику, позволяющую раскрыть семантику полей сообщения, отправленных или полученных приложением. Наша техника основывается на анализе типов данных и значительно расширяет ту семантическую информацию, которая уже доступна в программе.

    Мы разрабатываем и совершенствуем Dispatcher, инструментальное средство, которое реализует наши техники и автоматически воссоздает формат сообщений, и смысл его полей для обеих сторон обмена по протоколу на основе наблюдения только за одной стороной. Мы используем Dispatcher для анализа MegaD, распространенного спамового ботнета, который использует собственный шифрованный двоичный командный протокол, ранее публично не документированный.

    Мы показываем, что информация, извлекаемая при помощи Dispatcher, позволяет подделывать сообщения MegaD, делая возможной инфильтрацию в этот ботнет.

 

...

 

3. ВЫВОДЫ О СЕМАНТИКЕ ПОЛЕЙ

В этом разделе мы представляем нашу технику определения значения полей, как полученных, так и отправленных сообщений. 4.

Идея нашего подхода, основанного на типах используемых программой данных, состоит в следующем: многие функции и инструкции, используемые программой, содержат в себе семантическую информацию. Мы можем распространить эту информацию  на более широкую сферу, если назначения полей в данном конкретном контексте уже известны, или если отправляемые в сеть данные были получены из данных с известным уже смыслом.  Такие выводы носят общий характер и могут использоваться для идентификации широкого спектра семантики полей, включая такие назначения, например, как метки времени, имена машин, номера портов и адреса IP, и так далее.

4Наши техники семантических выводов были впервые опубликованы в октябре 2007 в виде технического отчета [16]. Они носят более общий характер, чем одновременно обнародованные техники, использующие файлы «cookies» и имена файлов из трассировки выполнения программы [49], а также другие подобные работы [27].

Семантическая информация об этих функциях и инструкциях публично доступна в описаниях их прототипов, которые определяют их общее назначение,  а также смысл входных и выходных данных. Прототипы функций можно найти, например,  в документации MSDN для разработчиков [8] или в стандартной документации библиотек C [5]. В отношении назначения инструкций можно обратиться к документации производителя системы. [1,4].

 

Техника. Для каждого полученного сообщения, Dispatcher отслеживает распространение каждой последовательности байт от полученного сообщения до входных параметров функций и процедур. Последовательность байт во входящем сообщении можно ассоциировать с семантикой параметров функции, проводя аналогию с ее прототипом. Например, когда программа обращается к функции connect, Dispatcher использует прототип этой функции для того чтобы проверить, являются ли какие-либо из параметров функции в стеке «мечеными» данными. Прототип функции говорит нам, что первый параметр является дескриптором сокета, второй – адресом структуры данных с IP-адресом и номером порта машины, а третий представляет собой размер этой структуры. Если указанная параметром область памяти содержит IP-адрес машины, который был «помечен» по входных данных, то Dispatcher может сделать вывод, что эти четыре байта во входящем сообщении (идентифицированные по смещению) представляют собой поле с IP-адресом. Аналогичным образом, если данные в памяти соответствуют номеру порта и совпадают с двумя байтами во входящем сообщении, то можно сделать понятный вывод о назначении поля этого сообщения.

Для отправленных сообщений, Dispatcher «метит» выходные данные функции при помощи уникального идентификатора и значения смещения. Для каждой такой «меченой» последовательности байт в буфере исходящего сообщения Dispatcher определяет, из какого «меченого» источника данных они происходят. Семантика источника «меченых» данных определяется на основе прототипа функции или инструкции. Например, если программа использует инструкцию rdtsc, мы можем сделать вывод, что входные данные ей не требуются, а выходные данные представляют собой 64-битовое значение, соответствующее метке времени процессора, находящейся в регистре EDX:EAX [4]. Таким образом, если в период выполнения программа использует инструкцию rdtsc, то Dispatcher пометит содержимое регистров EDX и EAX при помощи уникального идентификатора и смещения. Этим однозначно идентифицируется происхождение значений, используемых инструкцией rdtsc, а смещение определяется для  каждого из байтов в данных инструкции rdtsc (смещения от 0 до 7 при первом обращении).

Специальным случаем этой техники является логика выводов о строках «cookie». Строки «cookie» представляют собой данные из принятого сообщения, которые в неизменном виде передаются в буфер исходящего сообщения (напр., идентификатор сеанса). Таким образом, строки «cookie» одновременно идентифицируются во входящих и исходящих сообщениях.

Реализация. Для определения семантики полей Dispatcher использует набор прототипов для функций и инструкций, обрабатывающих  входные данные. По умолчанию, Dispatcher включает в себя сведения о более чем сотне функций и о ряде инструкций, которые мы уже включили в список прототипов на основании наших исследований. Для того чтобы выяснить семантику нового поля, мы исследуем внешние функции, вызываемые программой при его обработке согласно трассировке. В таблице 1 описаны выводы относительно семантики поля, которые Dispatcher может сделать на основе анализа входящих и исходящих сообщений с учетом списка предопределенных функций. Мы отсылаем читателя к приложению B, где приведены примеры функций и инструкций, используемых для идентификации семантики полей, описанных в таблице 1.

 

 

...

 

4.2   Реконструкция буфера

Реконструкция буфера – это рекурсивный процесс. В каждой итерации этой рекурсии заданный буфер в памяти разбивается на более мелкие буферы, из которых он составлен. Процесс начинается с выходного буфера и рекурсивно повторяется до тех пор, пока необработанных буферов не остается. Процесс состоит из двух частей. Вначале, для каждого байта в заданном буфере мы строим цепочку зависимостей. Затем, при помощи этой цепочки и информации, собранной на предварительном этапе, мы определяем структуру буфера. Входными данными для каждой такой итерации являются начальный адрес буфера в памяти, его длина и номер инструкции в трассировке, где в этот буфер последний раз производилась запись. Начальный адрес и длину выходного буфера мы получаем из параметров функции, которая отсылает данные в сеть (или функции, выполняющей шифрование). Номером инструкции выбирается номер первой инструкции в функции, передающей данные в сеть или в шифрующей функции. В остальной части этого раздела мы познакомим вас с понятием цепочек зависимостей и цепочек локализации и объясним, как они используются для реконструкции выходного буфера.

Локализация в программе. Мы определяем понятие локализации в программе, как однобайтовую единицу хранения в состоянии программы. Мы различаем четыре типа локализации: локализация в памяти, локализация в регистрах, непосредственная локализация и константная локализация. Мы концентрируемся, скорее, на адресах этих локализаций, чем на их содержимом. Каждый байт в памяти локализуется по его адресу. Каждый байт в регистрах локализуется при помощи имен регистров, например, в EAX имеется четыре локализации EAX: EAX(0) или AL, EAX(1) или AH, EAX(2) и EAX(3). Непосредственной локализации соответствует байт непосредственно в коде программы, такая локализация определяется при помощи смещения относительно начала модуля кода. Под константной локализацией понимается выходной байт некоторых инструкций, в которых он предопределен. Например, инструкции, выполняющие операцию XOR регистра с самим собой очищают регистр (напр., xor %eax, %eax). Dispatcher распознает ряд таких инструкций и рассматривает каждый байт их результата, как константную локализацию

Цепочки зависимостей. Цепочкой зависимостей для некоторой локализации в программе является последовательность операций записи, которая привела к тому значению, которое содержится в локализации в рассматриваемый момент. Под операцией записи понимается номер инструкции, которой была произведена запись локализация места назначения (то есть место, куда осуществлена запись), локализация источника (то есть место, откуда было взято значение для записи) и смещение локализации-получателя относительно начала выходного буфера. На рисунке 3 показана цепочка зависимостей для буфера B2 (того, который содержит шифрованные данные на рисунке 2). Здесь каждый блок представляет операцию записи, а каждый вертикальный ряд блоков представляет цепочку зависимостей для одной из локализаций в буфере.

Цепочка зависимостей вычисляется обратным проходом от номера заданной инструкции. Мы прекращаем построение цепочки, когда для очередной операции записи локализацией источника оказывается 1) непосредственная локализация, 2) константная локализация, 3) локализация в памяти, или 4) неизвестная локализация.

Если локализация источника является частью кода или предопределенным результатом инструкции, то зависимостей больше нет и цепочка зависимостей завершена.

Так обстоит дело для первых четырех байт B2 на рисунке 3. Причина остановки на моменте, когда источником данных является локализация в памяти, состоит в том, мы хотим выяснить, каким образом буфер в памяти конструируется из других буферов в памяти. После того, как структура заданного буфера выяснена,  Dispatcher рекурсивно продолжает процесс для составляющих его буферов. Например, на рисунке 3, цепочки зависимостей для локализаций от Mem(A+4) до Mem(A+11) состоят лишь из одной операции записи, поскольку локализацией-источником является другая локализация в памяти. Затем Dispatcher строит новую цепочку зависимостей для буферов от Mem(B) до Mem(B+7). При построении цепочки Dispatcher принимает во внимание то небольшое подмножество машинных инструкций x86, которые просто перемещают данные, не изменяя их. В это подмножество входят инструкции пересылок «move» (mov,movs), инструкции пересылок с нулевым расширением (movz), стековые инструкции типа «push» и «pop», инструкции записи строк (stos), и инструкции, используемые для преобразования порядка данных, такие, как инструкции обмена (xchg), инструкции обмена местами байтов в слове (bswap), или сдвиг вправо на целое число байт (напр., shr $0x8,%eax). Когда операция записи производится при помощи любых других инструкций, локализация источника рассматривается, как неизвестная, и построение цепочки прекращается. Зачастую оказывается достаточным остановить построение цепочки на таких инструкциях, поскольку в этом месте программа выполняет какую-то операцию над содержимым поля (например, арифметическую операцию). Поскольку программа совершает операции над содержимым  концевых узлов дерева полей, то в этом месте цепочки мы уже дошли до содержимого концевого узла («листа») нашего дерева. Например, на рисунке 3 цепочка зависимостей для последних двух байтов останавливается по достижении инструкции add. Здесь локализации обоих источников неизвестны. Обратите внимание на то, что эти локализации соответствуют полю длины на рисунке 1. Тот факт, что программа увеличивает значение длины, означает, что цепочка зависимостей достигла «листа» дерева полей.

 

Восстановление структуры буфера. Локализацию источника в последней операции записи в цепочке зависимостей мы называем источником буфера. Мы говорим, что две локализации-источника принадлежат к одному и тому же буферу, если они составляют вместе непрерывную область памяти (в восходящем или нисходящем порядке) и при этом они обе актуальны, то есть ни одна из этих локализаций не освобождалась в промежутке между соответствующими операциями записи. Если локализации источников не относятся к памяти (напр., это локализации в регистре, непосредственные, константные или неизвестные локализации), они принадлежат к одному и тому же буферу в случае, когда они были записаны одной и той же инструкцией.

Для того чтобы воссоздать структуру заданного буфера, Dispatcher циклически просматривает локализации данных буфера от начала до конца буфера. Для каждой очередной локализации Dispatcher проверяет, принадлежит ли ее источник к тому же буферу-источнику, что и источник предыдущей просмотренной локализации.

Атрибут

Значение

Field Range (диапазон поля)

Field Boundary

(границы поля)

Field Semantics

(семантика поля)

Field Keywords

(ключевые слова)

Смещение поля от начала сообщения и его длина

Фиксированное, длина, ограничитель

 

Значение из таблицы 1

 

Список ключевых слов в поле

Таблица 2: Атрибуты поля, используемые в дереве полей сообщения.

Если это не так, значит, найдена граница в структуре буфера. Структура заданного буфера выдается в форме последовательности диапазонов, его составляющих, при этом для каждого диапазона определяется, соответствует ли ему какой-либо буфер-источник в памяти, или нет.

Например, на рисунке 3 локализации источников для Mem(A+4) и Mem(A+5) представляют собой непрерывную область Mem(B) и Mem(B+l), а вот локализации источников для Mem(A+11) и Mem(A+12) непрерывную область не представляют. Таким образом, Dispatcher помечает локализацию Mem(A+12), как начало нового диапазона. Dispatcher обнаруживает 6 диапазонов в буфере B2 Первые четыре изображены на рисунке 3 и помечены надписями вверху. Поскольку лишь третий диапазон имеет своим источником другой буфер в памяти, только его Dispatcher подвергает дальнейшему анализу. Два последних диапазона соответствуют полям «Host Info» (информация о машине) и «Padding» (заполнение) на рисунке 1, и на рисунке 3 не отображены.

Восстановив структуру буфера, Dispatcher использует соответствия между буферами и полями в анализируемом сообщении для того чтобы добавить по одному полю в дерево полей сообщения на каждый диапазон в буфере. На рисунке 3 добавляются четыре новых поля, которые соответствуют блокам Version (версия), Type (тип), bot ID (идентификатор бота) и Length (длина) на рисунке 1.

 

...

 

5.   ОБРАБОТКА ЗАШИФРОВАННЫХ СООБЩЕНИЙ

Аналогично предыдущей работе, наша техника обратного инжиниринга протокола работает с незашифрованными данными. Таким образом, для случая шифрованного протокола необходимо решить две проблемы. Первая состоит в том, что для полученных сообщений нам необходимо идентифицировать буферы, где содержатся расшифрованные данные в тот момент, когда дешифрование только что закончилось, поскольку расшифрованные данные могут оставаться в буфере очень короткое время. Вторая проблема заключается в том, что для отправленных сообщений необходимо идентифицировать буферы с незашифрованными данными в момент, предшествующий шифрованию. Если буферы с незашифрованными данными идентифицированы, к ним применима та же техника обратного инжиниринга протокола, каковую нельзя применить к уже зашифрованным отправляемым и еще не дешифрованным полученным сообщениям.

В недавней работе была рассмотрена проблема обратного инжиниринга формата полученных шифрованных сообщений [39,48]. Поскольку приложению необходимо дешифровать данные, прежде чем ими воспользоваться, можно отслеживать работу приложения над зашифрованным сообщением, пытаясь найти буфер с уже дешифрованными данными в момент, когда дешифрование только что завершилось. Но в этих подходах не рассматривается проблема нахождения буфера с незашифрованными данными в момент, предшествующий их шифрованию, а этот вариант в нашем случае также требуется.

В этой работе мы представляем два расширения техники, представленной в ReFormat [48]. Во-первых, ReFormat может работать только с приложениями, где существует четкая и единственная граница между дешифрованием и собственно обработкой данных. Однако подобных границ может быть несколько. Как показано на рисунке 1, сообщения MegaD включают в себя два байта, содержащих значение длины сообщения, и зашифрованную часть с собственно данными. Прочитав значение длины, бот MegaD дешифрует 8 байт из зашифрованной части, обработает их, а затем дешифрует следующий 8 байт, и так далее. Кроме того, в некоторых сообщениях MegaD также используется сжатие, и операции распаковки и дешифрования чередуются друг с другом. Таким образом, здесь нет единственной точки в работе программы, где все данные из сообщения были бы распакованы и дешифрованы. Вследствие этого, мы расширяем технику таким образом, чтобы идентифицировать каждый случай шифрования, хеширования, сжатия и обфускации, что мы определим общим термином функции кодирования. Во-вторых, в ReFormat не предусмотрен механизм идентификации буферов с не кодированными (не шифрованными) данными в момент перед началом кодирования (шифрования). Таким образом, мы расширяем технику также и на этот случай. Далее мы представляем обобщенную технику.

Идентификация кодирующих функций. Для того чтобы идентифицировать каждый экземпляр кодирующей функции, мы упростили использованный в ReFormat процесс, удалив кумулятивные метрики, использование «меченых» данных и концепцию «листьевых» функций. В расширенной технике используется идея из ReFormat, состоящая в том, что процесс дешифрования характеризуется большой интенсивностью арифметических и битовых операций. Работает это следующим образом.

...

 

 

 

 

 

Hosted by uCoz