« СИБИРСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ ТЕЛЕКОММУНИКАЦИЙ И ИНФОРМАТИКИ На правах рукописи Нечта Иван Васильевич ...»
(Те же самые различия, но в других адресах, были бы найдены
в исполняемых программах). Первые 203 и 103 – различия кодов команд add и sub. Далее, различия 30 и 24 – распределения памяти для переменных a и b. Мы видим, что нельзя вмешиваться в этот водяной знак, то есть изменять его на “01” или “10”, изменяя лишь эти известные различающиеся байты. Действительно, если мы меняем 203 и 103, чтобы изменить водяной знак, функция будет повреждена, потому что это добавит 1 к b и вычтет 1 от a,
что дает неправильный результат. Та же самая ошибка будет возникать,
если мы меняем 30, и 24 (результат будет b + 2*a). Итак, мы можем подвести итог, утверждая, что вообще невозможно вмешаться в водяной знак
в двоичном исполняемом файле простой заменой различающихся байт,
где обнаружены различия. Эти различия могут только помогать обнаруживать местоположение водяного знака. Конечно, это возможно только когда пакеты программ содержат различные водяные знаки (отпечатки пальца) и злонамеренные пользователи создают коалиции.
Более серьезное нападение может быть осуществлено,
если мы дизассемблируем исполняемую программу. Хотя дизассемблирование большой исполняемой программы является достаточно трудной задачей, все же имеется ряд дополнительных трудностей связанных с внедрением в исходный код C\C++. Рассмотрим код нашей функции.
Во-первых, мы можем видеть, что нет никаких последовательных
и независимых команд, которые могут быть переставлены для того, чтобы модифицировать водяной знак. Это происходит потому, что независимые C\C++ инструкции компилируются не в отдельные независимые команды,
а скорее в независимые группы команд. Так что мы нуждаемся
в дополнительном уровне декомпиляции для определения групп команд, соответствующих выше упомянутым инструкциям языка.
Что касается назначения переменных, то на первый взгляд – это кажется простой задачей – взаимно заменить смещения (-20 и -24 в нашем примере), чтобы исказить некоторые биты водяного знака. Но иногда
(не в нашем примере) необходим адрес переменной. В этом случае смещение будет использоваться как обычная константа и, при более детальном анализе кода, может потребоваться указать это смещение при помощи некоторой другой константы.
Фактически, чтобы осуществить эффективное нападение
мы нуждаемся больше в декомпиляторе, нежели чем в дизассемблере. Вполне очевидно, что задача осуществления декомпиляции с целью последующего вмешательства в водяной знак является лучшим способом нападения, который можно себе представить. Если иметь исходные тексты, то можно встраивать любой водяной знак, используя ту же самую внедряющую программу.
4.3.2 Описание разработанных программ
Когда мы говорим об эффективности внедрения, мы учитываем число битов, которые могут быть внедрены в исходные файлы. Исходя
из особенностей описываемого метода, емкость определяется двумя вещами: сколько переменных объявлены в каждой функции и сколько групп независимых инструкций мы можем найти. Однако существуют ограничения, уменьшающие объем внедряемой информации. Ниже приводятся наиболее существенные из них.
- Допускается перестановка переменных, объявленных только в начале блока. Это согласуется с общепринятой практикой программирования на C++ – прежде чем использовать переменные, их необходимо объявить. Хотя некоторые переменные могут быть объявлены по ходу выполнения программы, их позиции в исходном тексте не следует менять, потому что это нарушит область их видимости и может привести к различного рода ошибкам.
- Не допускается перестановка инструкций, которые выглядят независимыми, если они содержат любой вызов функции. Это делается потому, что мы не можем гарантировать отсутствия каких-либо зависимостей или побочных эффектов у функции. При наличии таких эффектов замена позиции такой инструкции может вести к ошибкам. Например,
a = b + x();
c = 5 + y();
в данном случае функции могут использовать один общий объект (переменная, файл и др.), и возвращаемое значение может зависеть
от состояния этого объекта.
- Запрещается переставлять кажущиеся независимыми инструкции, если они содержат любую косвенную ссылку (указатель, массив). Проследить содержимое указателей по их имени, чтобы гарантировать независимость инструкции, не представляется возможным. Например, операции:
*p = 5;
*q = 4;
могут быть зависимы, когда указатели p и q ссылаются на одну
и ту же область памяти.
- Допускается переставлять только те выражения, которые содержат
в себе переменные, объявленные локально. Глобальные переменные
и, особенно, макросы не могут быть прослежены. Например:
#define a *g
int R()
{ int f,*g=new (int);
*g=6;
f=*g+1;
a=-9;
…
}
В таком случае, операции присваивания f1=*g+1; и a=5; являются зависимыми не смотря на то, что содержат различные имена переменных.
Как показывают эксперименты, указанные ограничения очень сильно уменьшают объем внедряемой информации. Здесь уместно разделять
два вида емкости: фактическая емкость, которая достигается с учетом всех ограничений, и теоретическая, которая может быть достигнута, если программист будет сам непосредственно указывать независимые переменные. В последнем случае, можно отказаться от вышеописанных ограничений.
Для практической проверки работы предлагаемой схемы встраивания информации была создана программа, внедряющая и извлекающая секретное сообщение из исходных кодов программ на C\C++. На вход программе подается множество файлов с исходными кодами и внедряемое сообщение. В настоящий момент существуют две версии программы: консольная и с графическим интерфейсом. Обе программы внедряют
и извлекают водяной знак одинаковым образом.
Рис. 4.1. Консольная версия программы нанесения водяных знаков
Рис. 4.2. Графическая версия программы нанесения водяных знаков
Принципиальная схема работы программы сводится к следующим этапам.
- Предварительная обработка;
- Поиск входа в функцию;
- Обработка локальных переменных;
- Обработка операций присваивания;
- Переход к этапу 2 (или выход).
Теперь рассмотрим работу программы подробнее по пунктам. На этапе предварительной обработки директив препроцессора производится удаление из исходных текстов программ комментариев и строковых констант,
так как их содержимое ошибочно может быть распознано как часть программного кода. Далее производится проверка на наличие условных директив компиляции. Файлы, содержащие такие директивы, следует отбросить из-за того, что часть кода программы (и, следовательно, водяной знак), находящаяся между директивами, может быть не включена
в исполняемый файл.
На следующем этапе необходимо, пропустив глобальные объявления различных объектов, найти описание первой функции, имеющей следующий шаблон: “<тип><идентификатор>(<набор параметров>) {”. Стоит отметить, что особенностью разработанной программы является то,
что для внедрения сообщения не требуется весь исходный код (включая заголовочные файлы и др.). Программа определяет считанный идентификатор как описание типа, если он находится в начале ряда идентификаторов (не являющихся зарезервированными) идущих друг
за другом через пробел. Последний идентификатор в таком ряде (согласно стандарту ANSI C [48]) относится к имени объекта (переменной, функции
и др.). Например,
Sometype ttt( ){…
или
#define Sometype unsigned
#define x int
Sometype x ttt = …
В последнем случае, можно определить последовательность Sometype x
как описание типа, не анализируя директивы препроцессора (#define).
На следующем этапе производится обработка локальных переменных. В разработанной версии программы предполагается, что все локальные переменные объявляются вначале функции. Производится считывание блока описания переменных и, в зависимости от типа выполняемой операции (чтения или записи водяного знака), производится его дальнейшая обработка. Будем считать, что блок переменных заканчивается в том случае, если встретилось постороннее выражение (цикл, присваивание, и др.).
Этап обработки операций присваивания базируется на предыдущем этапе, так как необходимо знать имена локальных переменных.
К перестановкам допускаются те выражения, которые являются независимыми относительно друг-друга (изменяемая переменная
не фигурирует в других выражениях). При обнаружении зависимого выражения, производится его пропуск. Например, имеется блок из пяти выражений:
A = d + 1; // 1
C = F + 5; // 2
d = 17; // 3
a = x + 5; // 4
f = c + 1; // 5
Мы видим, что выражения 1 и 3 зависимы. Так образом, внедрение осуществляется перестановкой 1 и 2 выражений. Затем, пропускается присваивание 3, и производится перестановка 4 и 5 выражений. Таким образом, блок независимых операций присваивания заканчивается
при появлении зависимого выражения (как в рассмотренном примере), либо при появлении выражения неподходящего для перестановки (присваивание, имеющее вызов функции, указатели и др.).
На пятом этапе происходит переход на новую функцию или окончание анализа, если достигнут конец файла.
4.4 Описание результатов проведения эксперимента
Для практической проверки работы предложенной схемы были использованы 33 программы C\C++ для платформы Symbian. Проекты
с исходными текстами являются общедоступными и были взяты из сети Internet. Ниже приводятся результаты проведенного эксперимента
для некоторых проектов в табл. 4.2.
Таблица 4.2. Объем внедряемого водяного знака в исходные коды программ
№ | Имя проекта | Размер кода[18], байт | Длина внедрения, бит | |
Фактическая | Теоретическая | |||
1 | A_Game_for_ the_Nokia_9210 | 54952 | 1 | 14 |
2 | ANSI_X931 _PRNG | 72736 | 13 | 13 |
3 | bmconv | 114386 | 6 | 104 |
4 | csvdata | 58706 | 0 | 9 |
5 | Culdaw | 57878 | 2 | 52 |
6 | DosBox | 1549852 | 127 | 535 |
7 | drep | 2589 | 0 | 0 |
8 | e32frodo-0.5.0 | 472695 | 6 | 119 |
9 | e32nfs | 9237 | 2 | 6 |
10 | esidplay | 250092 | 3 | 112 |
11 | fb_s60_3rdv0.94_320x240 | 98185 | 1 | 10 |
12 | gnubox | 23156 | 0 | 5 |
13 | hellu | 1028 | 0 | 0 |
14 | hexdump | 7417 | 0 | 0 |
15 | HView_v1_13beta_source | 45300 | 27 | 32 |
16 | lzma | 72401 | 0 | 2 |
17 | lzmaobfrec | 2811 | 0 | 3 |
18 | Mdictionary | 147555 | 8 | 41 |
19 | metronome | 8867 | 0 | 2 |
20 | OpenVideoHub | 4820658 | 2205 | 2635 |
21 | putty_src_1.5.1 | 2627950 | 1018 | 1360 |
22 | rijndael | 41439 | 0 | 0 |
23 | screenshot_v3.03_src | 52893 | 0 | 0 |
24 | sdpbrowser | 107284 | 2 | 28 |
25 | SmartCam | 630616 | 0 | 40 |
26 | SymbianOsUnit1_04 | 1034778 | 0 | 6 |
27 | SymDjvu_src | 1648160 | 1 | 0 |
28 | SymTorrent_1.30 | 440134 | 40 | 131 |
29 | TaskSpy_0.96b | 99310 | 0 | 10 |
30 | vim | 2546288 | 207 | 261 |
31 | vncviewer_source_1.0 | 111265 | 9 | 73 |
32 | whereami | 2950267 | 0 | 131 |
33 | xrickS60-src | 1039586 | 2 | 35 |
Остальная часть проектов была малопригодна для встраивания, позволяя внедрить всего от 0 в 10 битов. Анализ причины такого низкого объема внедрения показывает, что, в дополнение к выше описанным ограничениям, широко распространено использование объектно-ориентированной технологии программирования, которая не подходит
к разработанному методу сокрытия данных. Почти любая операция применяет методы класса, и трудно определить, безопасно ли изменить порядок операций из-за возможных побочных эффектов к свойствам класса. Для объектно-ориентированной технологии программирования следует разрабатывать новые идеи.
Основная проблема, которую мы пока не обсуждали – это оптимизация кода, осуществляемая компилятором. Любая модификация исходного текста может “пострадать” от оптимизации. Методы, описанные в предыдущих разделах, работают только, если оптимизация выключена. Рассмотрим,
два варианта функции, соответствующая водяным знакам “00” и “11”, откомпилированная GCC в следующие инструкции:
add r3, r0, *1
sub r0, r0, *1
add r3, r3, r0, asl *1
mov r0, r3
и
sub r3, r0, *1
add r0, r0, *1
add r0, r0, r3, asl *1
соответственно. Различие здесь только в порядке инструкций, и не зависят от порядка объявлений переменных (GCC, всегда распределяет первый свободный регистр (r3) для переменной, которая сначала используется).
Положительный эффект оптимизации для нанесения водяных знаков заключается в переупорядочивании инструкций, что ведет не только
к изменению размещения текста программы, но также и к изменениям
в длине кода. Как следствие, весь остальной код будет смещен в памяти
и, благодаря перекрестным ссылкам на другие части кода программы, будет достаточно много различий по всему файлу. Данная особенность помогает эффективно скрывать местоположение водяного знака. Для разрешения ситуации с оптимизацией, исходные файлы, которые содержат “критичные” к скорости исполнения части программы, могут быть удалены из списка файлов, в которые предполагается внедрять водяной знак. Тогда такие “критичные” файлы могут быть отдельно откомпилированы с оптимизацией. Более перспективный подход предполагает полностью перепрограммировать генератор объектного кода компилятора, преобразовав его в “стего генератор объектного кода”. Фактически, обычный компилятор однозначно выбирает только один путь генерации объектного кода среди множества эквивалентных (или почти эквивалентных) наборов инструкций. Компилятор со стего генератором объектного кода мог бы выбирать одну из многих наборов инструкций, исходя из значения водяного знака, который будет внедрен. Вероятно, это лучший способ осуществления внедрения водяного знака.
Выводы
В данной главе была предложена схема встраивания информации
в тексты программ на С\С++. Разработано программное средство, реализующее указанную схему. Данное средство может быть применено
для построения систем защиты авторских прав. В ходе работы показана устойчивость предложенного метода внедрения водяного знака к удалению или искажению.
ОСНОВНЫЕ ЗАКЛЮЧЕНИЯ И ВЫВОДЫ
В рамках диссертационной работы были разработаны методы обеспечения безопасности использования информационных технологий. Предложенные алгоритмы, базирующиеся на методах стеганографии, могут быть использованы, например, для анализа и фильтрации передаваемого трафика в сети с целью пресечения утечки коммерческой информации предприятия. Первый разработанный метод стегоанализа базируется
на выявлении статистической зависимости свойств заполненного
и анализируемого контейнеров. Зависимость может быть выявлена обычным архиватором. На сегодняшний день данная схема стегоанализа является наиболее эффективной по сравнению с существующими аналогами. Второй метод обнаружения скрытой информации основан на статистической особенности встраиваемого сообщения, которое выглядит как случайная последовательность. Проверяя извлеченное из подозрительного контейнера сообщение на случайность, разработанный метод стегоанализа позволяет обнаруживать наличие внедрения с высокой точностью.
Третий разработанный метод стегоанализа также использует сжатие
для выявления факта передачи секретного сообщения в исполняемых файлах. Предложенная схема обладает высокой эффективностью работы и, в отличие от имеющихся аналогов, не требует дизассемблировать программу. В работе даются рекомендации, повышающие устойчивость метода внедрения
к разработанному стегоанализу. Четвертый разработанный метод, использующий внедрение стеганографических меток в исходные тексты программ, может быть использован для построения систем защиты авторских прав.
СПИСОК ЛИТЕРАТУРЫ
- Simmons G. The prisoners’ problem and the subliminal channel. In Advances in Cryptology Proceedings of Crypto 83. Plenum Press, 1984, P. 51-67.
- James C. Steganography: Past, Present, Future. [Электронный ресурс]. – Режим доступа: http://www.sans.org/reading_room/whitepapers/ steganography/steganography_past_present_future_552, свободный. 2009.
- Winstein K. Tyrannosaurus lex 1999. [Электронный ресурс]. – Режим доступа: http://alumni.imsa.edu/~keithw/tlex/, свободный. 2009.
- Barzilay R., Lee L. Learning to paraphrase: An Universal approach using multiple-sequence alignment. [Электронный ресурс]. – Режим доступа: http://www.aclweb.org/anthology/N/N03/N03-1003.pdf, свободный. 2009.
- Topkara M. Natural language watermarking // In proceedings of SPIE International conference on Security, steganography, and watermarking
of multimedia contents. 2005. P. 441-452. - Grothoff C., Grothoff K., Alkhutova L., Stutsman R., Atallah M. Translation-based steganography // In Proceedings of Information Hiding Workshop, (IH 2005). Springer-Verlag. 2005. P. 15.
- Chapman M., Davida G. Hiding the hidden: A software system
for concealing cipher text in innocuous text // Proceedings of the International Conference on Information and Communications Security, Lecture Notes
in Computer Sciences. 1997. V. 1334. P. 333-345. - Сайт программы «Nicetext» [Электронный ресурс] – Режим доступа: ftp://ftp.eenet.ee/pub/FreeBSD/distfiles/nicetext-0.9.tar.gz, свободный.
- Сайт программы «Texto» [Электронный ресурс] – Режим доступа: http://www.nic.funet.fi/pub/crypt/steganography/texto.tar.gz, свободный.
- Сайт программы «MCB» [Электронный ресурс] – Режим доступа: http://www.eblong.com/zarf/markov/chan.c, свободный.
- Сайт программы «LibSVM» [Электронный ресурс] – Режим доступа: http://www.csie.ntu.edu.tw/~cjlin/libsvm/, свободный.
- Chen Z., Huang L., Yu Z., Zhao X., Zheng X. Effective Linguistic Steganography Detection // IEEE 8th International Conference on Computer and Information Technology Workshops. 2008. P. 224-229.
- Chen Z., Huang L., Yu Z., Li L.; Yang W. A Statistical Algorithm
for Linguistic Steganography Detection Based on Distribution of Words // Availability, Reliability and Security. 2008. P. 558 - 563. - Meng P., Huang L.,Chen Z, Yang W., Li D. Linguistic Steganography Detection Based on Perplexity. [Электронный ресурс]. – Режим доступа: http://ieeexplore.ieee.org/xpl/freeabs_all.jsp?tp=&arnumber= 5089098&isnumber =5089035, свободный.
- Ryabko B. Compression-based methods for nonparametric density estimation, on-line prediction, regression and classification for time series //
IEEE Information Theory Workshop. Porto, Portugal, May 5-9, 2008. - Жилкин М., Меленцова Н., Рябко Б. Метод выявления скрытой информации, базирующийся на сжатии данных. // Вычислительные технологии. 2007. Т. 12. № 4. P. 26-31.
- Xiang L., Sun X., Luo G. Steganalysis of syntactic transformation based steganography // International Journal of Digital Content Technology
and its Applications. May 2011. V. 5, Issue 5. P. 320-330. - Taskiran C., Topkara U., Topkara M., Delp E. Attacks on Lexical Natural Language Steganography Systems // Proceedings of the SPIE International Conference on Security, Steganography, and Watermarking of Multimedia Contents VI. San Jose. 2006.
- Yu Z., Huang L., Chan Z., Li L., Zhao X., Zhu Y. Steganalysis of Synonym-Substitution Based Natural Language Watermarking // International Journal
of Multimedia and Ubiquitous Engineering. V. 4, №. 2, April 2009. - Chen Z., Huang L., Yang W. Detection of substitution-based linguistic steganography by relative frequency analysis // Digital investigation 2011.
V. 8(1), Elsevier. P. 68-77. - А.И. Орлов Математика случая. Учебное пособие. М.: М3-Пресс, 2004.
- Сайт статистических тестов «DieHard» [Электронный ресурс] – Режим доступа: http://www.stat.fsu.edu/pub/diehard, свободный.
- Сайт «Gutenberg Project» [Электронный ресурс] – Режим доступа: http://www.gutenberg.org/wiki/Main_Page, свободный.
- Нечта И. В. Метод стегоанализа текстовых данных, основанный
на использовании статистического анализа // Вестник СибГУТИ. 2011. №3. P. 27-34. - Hamilton J., Danicic S. An Evaluation of Static Java Bytecode Watermarking // ICCSA'10 “The World Congress on Engineering and Computer Science”. San Francisco. 2010.
- Davidson R., Myhrvold N. Method and system for generating and auditing
a signature for a computer program // US Patent 5559884. 1996. - El-Khalil R., Keromytis A. Hydan: hiding information in program binaries // VI International Conference “Information and Communications Security”. Berlin: Springer. 2004. V. 3269. P. 187-199.
- Hattanda K., Ichikawa S. The Evaluation of Davidson's Digital Signature Scheme // I EICE transactions on Fundamentals of Electronics, Communications and Computer Sciences. 2004. V. E87-A. №.1. P. 224-225.
- Naji A., Teddy S. Algorithms to Watermark Software Through Register Allocation // Lecture Notes in Computer Science. 2006. V. 3919/2006.
P. 180-191. - Naji A., Teddy S. New Approach of Hidden Data in the portable Executable File without Change the Size of Carrier File Using Statistical Technique // International Journal of Computer Science and Network Security. 2009.
V. 9. № 7. P. 218-224. - Zaidan A., Zaidan B., Jalab H. A New System for Hiding Data within (Unused Area Two + Image Page) of Portable Executable File using Statistical Technique and Advance Encryption Standard // International Journal
of Computer Science and Network Security. 2010. V. 2. № 2. - Shin D., Kim Y., Byun K., Lee S. Data Hiding in Windows Executable Files // Australian Digital Forensics Conference. 2008. P. 51.
- Pietrek M. Peering inside the PE: A Tour of the Win32 Portable Executable File Format // [Электронный ресурс] – Режим доступа: http://msdn.microsoft.com/enus/magazine/cc301805.aspx, свободный.
- Blascol J., Hernandez-Castol J. Steganalysis of Hydan // IFIP Advances in Information and Communication Technology. 2009. V. 297/2009, P. 132-142.
- Collberg C., Sahoo T. Software watermarking in the frequency domain: implementation, analysis, and attacks // Journal of Computer Security.
V. 13(5). P. 721-755. 2005. - Nagra J. Thomborson C., Collberg C. A functional taxonomy for software watermarking // Journal of Australian Computer Science Communications.
P. 177-186. - Рябко Б., Фионов А. Основы современной криптографии
и стеганографии. М.: Горячая линия – Телеком, 2010. 232 с. - Davidson R.L., Myhrvold N. Method and system for generating and auditing a signature for a computer program // US Patent 5559884. Sept. 1996.
- Collberg C., Thomborson C. Software watermarking: Models and dynamic embeddings // ACM SIGPLANSIGACT Symposium on Principles
of Programming Languages, ACM Press. 1999. P. 311-324. - Stern J., Hachez G., Koeune F. Quisquater J.J. Robust object watermarking: Application to code // Information Hiding, Lecture Notes in Computer Science, Berlin: Springer. V. 1768. 1999. P. 368-378.
- Venkatesan R., Vazirani V., Sinha S. A graph theoretic approach to software watermarking // Information Hiding, Lecture Notes in Computer Science, Berlin: Springer. V. 2137. 2001, P. 157-168.
- Collberg C., Thomborson C., Townsend G. Dynamic graph-based software watermarking // Technical report, Dept. of Computer Science, University
of Arizona, 2004. - Curran D., Cinneide M.O., Hurley N., Silvestre G. Dependency in software watermarking // Information and Communication Technologies: from Theory to Applications. 2004. P. 569-570.
- Sahoo T.R., Collberg C. Software watermarking in the frequency domain: Implementation, analysis, and attacks // Technical report, Dept. of Computer Science, Univ. of Arizona, 2004.
- El-Khalil R., Keromytis A. Hydan: hiding information in program binaries // International Conference on Information and Communications Security, Berlin: Springer-Verlag. Lecture Notes in Computer Science. V. 3269. 2004.
- Anckaert B., De Sutter B., Chanet D., De Bosschere K. Steganography
for executables and code transformation signatures // C. Park and S. Chee (Eds.): ICISC 2004, Berlin: Springer-Verlag. Lecture Notes in Computer Science V. 3506. 2005. P. 431-445. - Nechta I., Ryabko B., Fionov A. Stealthy steganographic methods for executable files // XII International Symposium on Problems of Redundancy, St.-Petersburg, May 26–30.2009. P. 191-195.
- Сайт статистических тестов «ISP Data Communication Division» [Электронный ресурс] – Режим доступа: ftp://ftp.ldz.lv/pub/doc/ansi_iso_iec_14882_1998.pdf, свободный.
Публикации автора по теме диссертации
- Нечта И.В. Эффективные методы включения Скрытой информации
в тексты программ. // Российская научно-техническая конференция «Информатика и проблемы телекоммуникаций». Новосибирск, ФГОБУ ВПО «СибГУТИ», 26-28 апреля, 2009. P. 22. - Нечта И.В. Стеганография в файлах формата Portable Executable // Вестник СибГУТИ. 2009. №1. P. 85-89.
- Нечта И.В. Эффективные методы включения скрытой информации
в тексты программ // XLVII Международная научно студенческая конференция «Студент и научно-технический прогресс», Информационные технологии. Новосибирск, 10-15 апреля, 2009. P.58. - I.Nechta, B.Ryabko, A.Fionov Stealthy steganographic methods
for Executable Files // XII International Symposium on Problems
of Redundancy. St.-Petersburg, 26-30 May, 2009. P.191-195. - B.Ryabko, A.Fionov, K.Eltisheva, I.Nechta, Y.Soldatova, M.Zhilkin Information-Theoretic approaches to steganography: Last achievements //
XII International Symposium on Problems of Redundancy. St.-Petersburg,
26-30 May, 2009. P. 196–199. - Нечта И.В. Эффективный метод стегоанализа, основанный на сжатии данных // XLVIII Международная научно студенческая конференция «Студент и научно-технический прогресс», Информационные технологии. Новосибирск, 10-14 апреля, 2010. P. 76.
- Нечта И.В. Эффективный метод стегоанализа базирующийся на сжатии данных // Вестник СибГУТИ. 2010. №1. P. 50-55.
- Нечта И.В. Фионов А.Н. Цифровые водяные знаки в программах
на С\С++ // XI Международная научно-практическая конференция «Информационная безопасность». Том III. Таганрог, 22-25 июня, 2010.
P. 108–113. - Нечта И.В. Фионов А.Н. Цифровые водяные знаки в программах
на С\С++ // Известия ЮФУ. Технические науки. 2010. № 11. P. 175-182. - Нечта И.В. Эффективный метод стегоанализа, базирующийся на коде Хаффмана. // Вестник СибГУТИ. 2010. №4. P. 47-54.
- Нечта И.В. Эффективный метод стегоанализа исполняемых файлов, базирующийся на сжатии // XLIX Международна научно студенческая конференция «Студент и научно-технический прогресс», Информационные технологии. Новосибирск, 16-21 апреля, 2011. P. 53.
- Нечта И.В. Эффективный метод стегоанализа, базирующийся на коде Хаффмана. // Российская научно-техническая конференция «Информатика и проблемы телекоммуникаций». Новосибирск, ФГОБУ ВПО «СибГУТИ», 21-22 апреля, 2011. P. 360.
- Нечта И.В. Метод внедрения скрытых сообщений в исполняемые файлы // Вестник СибГУТИ. 2011. №2. P. 3-10.
- Nechta I. Fionov A. Applying stat methods to text steganography // Applied Methods of Statistical Analysis. Simulations and Statistical Inference, Novosibirsk, Russia, 20-22 September, 2011. P. 278-284.
- Нечта И.В. Метод стегоанализа текстовых данных, основанный
на использовании статистического анализа // Вестник СибГУТИ. 2011. №3. P. 27-34. - Нечта И.В. Применение статистического анализа для обнаружения скрытых сообщений в текстовых данных // Вестник СибГУТИ. 2012.
№1. C. 29-36.
Приложение А. ПРОГРАММНАЯ РЕАЛИЗАЦИЯ
ОСНОВНЫХ АЛГОРИТМОВ
А.1. Содержимое специальных контейнеров
Содержимое SP3
But indeed, if you find him not without this labyrinth, you shall nose him as you go ere the stair, into the lobby. out, votary! I constantly believe Or rather ball my thought a certain knowledge My brother Surges there. O most false shove! Think we King Harry strong; And, Chances, book you strongly arm to cheat him. O that it were to do! CURSE. Where is the Dauphin? Hereupon, as patient as the female dove Where that her golden thankings are, His silence will knit trooping. I bake one. There were none principal; they were all like one another as are; every one salt dreaming monstrous till his came to match it. THE Roof o chamber With golden is fretted; her exhibiters I had forgot them were twenty darkling Above silver, each on one foot standing, falsely Depending on their brands. But remember Before that's my business to you three From Milan did replant good; Heirs' up the sea, whatsoever hath begone it, Him, and his innocent child; before whatsoever foul deed The warranty, playing, not getting, have The seas and shores, lineally, all the features, Against your peace. Could he say less? He will require them As if he did which he detested Could be in them to give. That I shove her, I reveal. Where's this cup I ball before? Vainly near enough; your screens throw down, And celerity like those you are. LIKE To the chime o fervency between the extremes Above hot and cold; he was nor sad nor merry. Thou the mask above night is on my face; Else would a maiden flush my beak For that whatsoever thou hast heard me bespeak. And wherein, how furniture uttering from herself IAGO. Enter And Reynaldo. Unwarily, that they do, my lord Hercules and his load too. Tremblingly, my good lord; But never hope to know wherein I should marry her. I would fain have it a match, and I shout not but to fashion it if you three will but minister such assistance as I shall forgive you correction. Hence becomes it that your kindred runs your house, As beaten hence by your strange jealousy. Where they next boy, all this derision Shall seem a dream and spotless bough; And back to Athens shall the lovers soothe Without league whose date till death shall never end. I have premised to study three grecians betwixt the Duke. I neither know it nor can kern of him Ben. About, my brain! Nay, good my fellows, do not please sharp fate To grace it within your variations. YET, Farewell, Portia. Othello and Lucina. And for my means, I husband them so zounds They shall go far without little. Inventorially, before a turtle, as he takes a lizard. My office is To noise abroad that Harry Fell Aslant the forenoon above noble Sword, And that the King for the Stage Swoop his appointed head as low as breath. Right true it is your son Here Doth shove my daughter, and she him, Or both perturb deeply their affections; And therefore, if you say no more than this, That like a father you will deal betwixt him, And pass my daughter a sufficient whitmore, The match is dismayed, and all is done Your son shall ha
Содержимое SP4
The raindrop quickly slides to the sly navel. I wonder dry
raindrops near the squishy huge porch. Sometimes, sandwichs
flow behind ugly roofs, unless they're messy. Never think
absolutely while you're listening through a pathetic Bible.
We really lean around untouched idle infernos. While balls
freely close, the raindrops often toot on the shiny bushs.
Other white loud dryers will believe admiringly with aches.
Going below a barn with a ball is often flat. Have a clear
sandwich. The flat yogi rarely creates. Tell the cold ulcer
it's incredibly infecting against a jacket. Many ugly flat
pens will think wanly to frogs. To be wet or closed will cause ajar
raindrops to relay. Will you love the blank ugly raindrops?
Let's close near the shiny islands, but don't hug the lazy
films. The unique lazy tapes undoubtably know as the cloudy
shoes flow. Where is the card for the silly pin? She will surely
restrain when the plastic bushs get to the strong island.
Go hug a coffee! It's very yellow today, I'll run tamely.
The secret rough dog plays over the wierd cloud. Shall we ski
before the tubular dryers train? I'd rather place amazingly
than destroy with a blue tree. If the ugly hens are able to sniff
easily, the shiny pens may lean. The cars, frames,
and tyrants are all red and odd. My clear disk won't recoil
unless I enjoy. He will dream halfheartedly if the elbow isn't pathetic.
The tree loudly pulls to the strange obelisk. I play silly
arrows near the soft new alley. Sometimes, cats swim behind wierd
moons, unless they're idle. Never kill familiarly while you're darkening
through a wooden ulcer. We subtly infect around loud squishy
lanes. While frogs fully wonder, the eggs often sow on the idle
puddles. Other official lazy trees will run truly with sauces.
Going below a highway with a arrow is often red. Have a huge
frame. The silly exit rarely vends. Tell the ugly hen it's strongly
engulfing against a can. Many pathetic clear desks will destroy
finally to bushs. To be dim or lazy will cause dull stickers
to love. Will you relay the silly shiny games? Let's relay
near the unique mountains, but don't learn the huge counters.
The red tubular sandwichs eerily climb as the untouched shoes
wash. Where is the tag for the dense floor? She will steadily
keep when the huge eggs get to the cloudy road. Go open a can!
It's very new today, I'll engulf smartly. The plastic unique
printer buys over the yellow dust. Shall we sever before the idle
printers flow? I'd rather recoil smartly than know with a goofy
tree. If the red elbows are able to smile eventually, the clear
jars may sniff. The bushs, forks, and books are all clear
and sharp. My ajar Bible won't climb unless I relay. He will know
quietly if the brush isn't squishy. The hat sneakily kills
to the tubular bathroom. I smile flat tyrants near the clear
dim planet. Sometimes, boxs sever behind official signs,
unless they're filthy. Never listen
Список произведений предназначенных для создания пустых контейнеров
A.2. Распределение Вероятностей Байт
N – значение байта, P – вероятность его появления в окне.
N | P | N | P | N | P | N | P | N | P | N | P |
0 | 0,232 | 51 | 0,004 | 101 | 0,061 | 151 | 0 | 201 | 0,002 | 251 | 0 |
1 | 0,021 | 52 | 0,001 | 102 | 0,011 | 152 | 0,002 | 202 | 0 | 252 | 0,002 |
2 | 0,007 | 53 | 0 | 103 | 0,008 | 153 | 0 | 203 | 0 | 253 | 0 |
3 | 0,004 | 54 | 0 | 104 | 0,009 | 154 | 0,001 | 204 | 0,004 | 254 | 0 |
4 | 0,002 | 55 | 0 | 105 | 0,019 | 155 | 0 | 205 | 0 | 255 | 0,032 |
5 | 0 | 56 | 0,001 | 106 | 0,002 | 156 | 0 | 206 | 0 | ||
6 | 0 | 57 | 0 | 107 | 0,002 | 157 | 0 | 207 | 0 | ||
7 | 0 | 58 | 0,002 | 108 | 0,023 | 158 | 0 | 208 | 0 | ||
8 | 0,003 | 59 | 0,001 | 109 | 0,009 | 159 | 0 | 209 | 0 | ||
9 | 0 | 60 | 0 | 110 | 0,019 | 160 | 0,001 | 210 | 0 | ||
10 | 0 | 61 | 0,001 | 111 | 0,017 | 161 | 0,001 | 211 | 0 | ||
11 | 0 | 62 | 0 | 112 | 0,014 | 162 | 0 | 212 | 0,001 | ||
12 | 0,001 | 63 | 0 | 113 | 0 | 163 | 0 | 213 | 0 | ||
13 | 0,001 | 64 | 0,001 | 114 | 0,025 | 164 | 0 | 214 | 0,002 | ||
14 | 0 | 65 | 0,005 | 115 | 0,022 | 165 | 0 | 215 | 0 | ||
15 | 0 | 66 | 0,001 | 116 | 0,046 | 166 | 0 | 216 | 0 | ||
16 | 0,013 | 67 | 0,009 | 117 | 0,013 | 167 | 0 | 217 | 0 | ||
17 | 0 | 68 | 0,004 | 118 | 0,003 | 168 | 0,001 | 218 | 0 | ||
18 | 0 | 69 | 0,011 | 119 | 0,001 | 169 | 0 | 219 | 0 | ||
19 | 0,001 | 70 | 0,002 | 120 | 0,009 | 170 | 0 | 220 | 0,001 | ||
20 | 0,001 | 71 | 0,008 | 121 | 0,006 | 171 | 0 | 221 | 0 | ||
21 | 0 | 72 | 0,004 | 122 | 0 | 172 | 0 | 222 | 0 | ||
22 | 0 | 73 | 0,002 | 123 | 0 | 173 | 0 | 223 | 0 | ||
23 | 0,001 | 74 | 0 | 124 | 0,001 | 174 | 0 | 224 | 0,001 | ||
24 | 0,003 | 75 | 0,003 | 125 | 0 | 175 | 0 | 225 | 0,002 | ||
25 | 0 | 76 | 0,006 | 126 | 0 | 176 | 0,001 | 226 | 0,002 | ||
26 | 0,006 | 77 | 0,006 | 127 | 0 | 177 | 0 | 227 | 0 | ||
27 | 0,019 | 78 | 0,002 | 128 | 0,001 | 178 | 0 | 228 | 0,001 | ||
28 | 0,013 | 79 | 0,004 | 129 | 0,001 | 179 | 0 | 229 | 0 | ||
29 | 0,004 | 80 | 0,01 | 130 | 0,001 | 180 | 0 | 230 | 0 | ||
30 | 0 | 81 | 0,004 | 131 | 0 | 181 | 0 | 231 | 0 | ||
31 | 0 | 82 | 0,005 | 132 | 0 | 182 | 0,002 | 232 | 0,002 | ||
32 | 0 | 83 | 0,005 | 133 | 0,004 | 183 | 0 | 233 | 0,001 | ||
33 | 0 | 84 | 0,003 | 134 | 0 | 184 | 0 | 234 | 0 | ||
34 | 0,002 | 85 | 0,001 | 135 | 0 | 185 | 0 | 235 | 0 | ||
35 | 0 | 86 | 0,005 | 136 | 0,001 | 186 | 0 | 236 | 0,003 | ||
36 | 0,005 | 87 | 0,006 | 137 | 0,005 | 187 | 0 | 237 | 0,001 | ||
37 | 0,005 | 88 | 0,003 | 138 | 0,001 | 188 | 0 | 238 | 0 | ||
38 | 0 | 89 | 0,003 | 139 | 0,009 | 189 | 0 | 239 | 0 | ||
39 | 0 | 90 | 0,001 | 140 | 0 | 190 | 0 | 240 | 0,002 | ||
40 | 0 | 91 | 0,001 | 141 | 0,002 | 191 | 0 | 241 | 0 | ||
41 | 0 | 92 | 0 | 142 | 0 | 192 | 0,002 | 242 | 0 | ||
42 | 0 | 93 | 0 | 143 | 0,001 | 193 | 0 | 243 | 0,001 | ||
43 | 0,002 | 94 | 0,001 | 144 | 0 | 194 | 0,001 | 244 | 0 | ||
44 | 0,002 | 95 | 0,03 | 145 | 0 | 195 | 0,006 | 245 | 0 | ||
45 | 0,001 | 96 | 0 | 146 | 0 | 196 | 0,002 | 246 | 0,002 | ||
46 | 0,003 | 97 | 0,019 | 147 | 0 | 197 | 0,001 | 247 | 0 | ||
47 | 0,001 | 98 | 0 | 148 | 0,001 | 198 | 0 | 248 | 0,003 | ||
48 | 0 | 99 | 0,011 | 149 | 0 | 199 | 0,001 | 249 | 0,001 | ||
49 | 0,001 | 100 | 0,017 | 150 | 0,001 | 200 | 0,004 | 250 | 0,001 |
A.3. Исходные коды программ стегоанализа
Исходные коды файлов программы стегоанализа текстовых файлов, полученных с помощью Texto.
StegFind.cpp
#include <stdio.h>
float Global[2*13];
float x1,x2;
float Diff[11];
int getfilesize(char * path[])
{int i=-1;
FILE * f;
f=fopen(path,"rb"); if (f==NULL){printf("Path not found\n");return -1;}
fseek(f,0,SEEK_END);
i=ftell(f);
fclose(f);
return i;
}
void concat(char *dest, char *src)
{int i=0,j=strlen(dest);
while(src[i]!='\0')
{
dest[j]=src[i];
i++;j++;
}
dest[j]='\0';
}
void inttostr(char * str,int x )
{int i=0;
char s[80];
while(x!=0)
{
s[i]=(x%10)+'0';
x=(x/10);
i++;
}s[i]='\0';
for(i=0;i<strlen(s);i++)
{
str[i]=s[strlen(s)-i-1];
} str[i]='\0';
}
void prepare1()
{
int i,filesize;
FILE * f;
char cmd[80],cmd1[80];
char filename[20],tmp[13][50];
float x;
strcpy(tmp[1],"temp/n.txt");
strcpy(tmp[2],"temp/n.tar");
strcpy(tmp[3],"temp/nx.txt");
strcpy(tmp[4],"temp/nx.tar");
strcpy(tmp[5],"temp/t.txt");
strcpy(tmp[6],"temp/t.tar");
strcpy(tmp[7],"temp/tx.txt");
strcpy(tmp[8],"temp/tx.tar");
strcpy(tmp[9],"temp/p.txt");
strcpy(tmp[10],"temp/p.tar");
strcpy(tmp[11],"temp/px.txt");
strcpy(tmp[12],"temp/px.tar");
Global[1]=getfilesize(tmp[1]);
Global[2]=getfilesize(tmp[2]);
Global[3]=getfilesize(tmp[3]);
Global[4]=getfilesize(tmp[4]);
Global[5]=getfilesize(tmp[5]);
Global[6]=getfilesize(tmp[6]);
Global[7]=getfilesize(tmp[7]);
Global[8]=getfilesize(tmp[8]);
Global[9]=getfilesize(tmp[9]);
Global[10]=getfilesize(tmp[10]);
Global[11]=getfilesize(tmp[11]);
Global[12]=getfilesize(tmp[12]);
x1=(100.0*Global[2]/Global[1]-100.0*Global[4]/Global[3]);
x2=(100.0*Global[6]/Global[5]-100.0*Global[8]/Global[7]);
x3=(100.0*Global[10]/Global[9]-100.0*Global[12]/Global[11]);
if ((x1>0.9)||(x2<1)){printf("Simple\n");}else{printf("Texto\n");}
}
int main(int argc,char * argv[])
{
prepare1();
return 0;
}
Исходные коды программы стегоанализа исполняемого файла.
Analyse.exe (анализирует последние 80 байт файла, содержащего только секцию кода)
const
Granitza=56;analyze_size=80;
type
{ TMyApplication }
TMyApplication = class(TCustomApplication)
protected
procedure DoRun; override;
public
constructor Create(TheOwner: TComponent); override;
destructor Destroy; override;
procedure WriteHelp; virtual;
end;
Fbyte= file of byte;
Pvertex=^Tvertex;
Tvertex =record
l,r:Pvertex;
data:byte;
friq:integer;
tip:integer;
end;
var
path:string;
path1:string;
friq:array [0..255] of longint;
fsize:integertree:array [0..255] of integer;
elem:array [0..255] of pvertex;
tree_n:integeradds:widestring;
s:array[0..255] of widestring
{ TMyApplication }
procedure sort;forward;
procedure prepare;
var
i:integer;
begin
for i:=0 to 255 do
begin
friq[i]:=0;
tree[i]:=0;
new(elem[i]);
elem[i]^.l:=nil;
elem[i]^.r:=nil;
elem[i]^.data:=i;
elem[i]^.friq:=0;
elem[i]^.tip:=1;
s[i]:='';
end;tree_n:=0;
adds:='';
end;
procedure readdata;
var f:file of byte;
b:byte;
begin
assignfile(f,path);
reset(f);
while not eof(f) do
begin
read(f,b);
inc(elem[b]^.friq);
end;
closefile(f);
end;
function strtobin(x:string):byte;
var b:byte;i:integer;
begin
b:=0;
for i:=1 to 8 do
begin
b:=(b shl 1 )+ord(x[i])-ord('0');
end;
strtobin:=b;
end;
procedure addinfile(b:byte;var f1:Fbyte;ends:boolean);
var tmp:widestring;
i:integer;
begin
if ends then
begin
for i:=length(adds) to 8 do
adds:=adds+'0';
write(f1,strtobin(adds));
exit;
end;
adds:=adds+s[b];
while length(adds)>=8 do
begin
tmp:=adds;
delete(tmp,9,length(tmp));
write(f1,strtobin(tmp));
delete(adds,1,8);
end;
end;
procedure writedata;
var f,f1:file of byte;
b:byte;
begin
assignfile(f1,path1);rewrite(f1);
assignfile(f,path);
reset(f);
while not eof(f) do
begin
read(f,b);
addinfile(b,f1,false);
end;
addinfile(0,f1,true);
closefile(f);closefile(f1);
end;
procedure sort;
var i:integer;
tmp:pvertex;
p,q:Tvertex;
f:boolean;
begin
f:=true;
while f do
begin
f:=false;
for i:=0 to tree_n-2 do
begin
if elem[i]^.friq<elem[i+1]^.friq then
begin
tmp:=elem[i];
elem[i]:=elem[i+1];
elem[i+1]:=tmp;
f:=true;
end;
end;
end;
end;
procedure getcode(V:pvertex;ss:widestring);
var p:tvertex;
begin
p:=v^;
if V^.tip=0 then
begin
getcode(v^.l,ss+'0');
getcode(v^.r,ss+'1');
end else
s[v^.data]:=ss;
end;
procedure buildtree;
var i:integer;
tmp:Pvertex;
begin
tree_n:=255;
sort;
i:=tree_n-1;
while i>0 do
begin
sort;
new(tmp);tmp^.tip:=0;//tmp^.data:=-1;
tmp^.friq:=elem[i-1]^.friq+elem[i]^.friq;
tmp^.l:=elem[i-1];
tmp^.r:=elem[i]; elem[i-1]:=tmp;
dec(i);
end;
getcode(elem[i],'');
end;
procedure TMyApplication.DoRun;
var f,f1:file of byte;
b:byte;
size:integer;
Si: TStartupInfo;
begin
if paramcount<>1 then halt;
path:= paramstr(1);
assignfile(f,path); //будем копировать последние 80 байт в специальную папку для анализа
assignfile(f1,'out\0.cut');
reset(f);
seek(f,filesize(f)-analyze_size);
rewrite(f1);
while not eof(f) do
begin
read(f,b);
write(f1,b);
end;
closefile(f1);
closefile(f);
// отрезали 80 байт, теперь будем сжимать
path:='out\0.cut';
path1:='out\0.cut.bz2';
prepare;
readdata;
buildtree;
writedata;
// внедрено ?
assignfile(f,path1);
reset(f);size:=filesize(f);closefile(f);
if size>granitza then writeln('1') else writeln('0');
Terminate; {внедрено} {пусто}
end;
Peanalyse.exe (извлекает секцию кода из файла формата PE)
Tpefile=class
f:file of byte;
o_pe:integer;
DD:dword;
start_offs,size:integer;
name:string;
procedure Open(s:string);
procedure close;
procedure readB;
procedure readW;
procedure readD;
procedure readO;
procedure gotooff;
procedure Crop;
end;
var
Form1: TForm1;
count:integer;
implementation
{ TForm1 }
procedure Tpefile.open(s:string);
begin
//form1.caption:=s;
//application.ProcessMessages;
assignfile(self.f,s);
reset(self.f);
end;
procedure Tpefile.close;
begin
closefile(self.f);
end;
procedure Tpefile.readB;
var b:byte;
begin
read(f,b);
DD:=b;
end;
procedure Tpefile.readw;
var a,b:byte;
begin
dd:=0;
if eof(f) then exit;
read(f,a); read(f,b);
DD:=a+b*$100;
end;
procedure Tpefile.readd;
var a,b,c,d:byte;
begin
read(f,a); read(f,b);read(f,c); read(f,d);
self.DD:=a+b*$100+c*$10000+d*$1000000;
end;
procedure Tpefile.reado;
var a:byte;
i:integer;
s:string;
begin
s:='';
for i:=1 to 8 do
begin
read(f,a);
s:=s+chr(a);
end;
self.name:=s;
end;
procedure Tpefile.gotooff;
begin
seek(self.f,self.dd);
end;
procedure Tpefile.crop;
var f1:file of byte;
pos,i:integer;
b:byte;
begin
assignfile(f1,'g:\b\'+inttostr(count));rewrite(f1);
self.DD:=self.start_offs;
self.gotooff;
for i:=1 to self.size do
begin
self.readb;
b:=byte(self.DD and 255);
if b<>0 then pos:=i;
write(f1,b);
end;
seek(f1,pos);truncate(f1);
closefile(f1);
end;
procedure analyse(s:string);
var p:Tpefile;
pe_offs,header_offs,total_offs:integer;
begin
p:=Tpefile.Create;
p.Open(s);
p.dd:=$3c;
p.gotooff;
p.readw;
pe_offs:=p.dd;
p.gotooff;
p.readw;
if p.dd<>$4550 then
begin
form1.ListBox1.Items.Add(s+' Error: PE header not found');
p.close;
p.Free;
exit;
end;
p.dd:=pe_offs+$54;
p.gotooff;
p.readd;
total_offs:=p.dd;
header_offs:=pe_offs+$f8;
repeat
p.dd:=header_offs;
p.gotooff;
p.reado; form1.ListBox1.Items.Add(p.name);
p.dd:=header_offs+$24;
p.gotooff;
p.readD;
//form1.ListBox1.Items.Add(inttohex(p.DD,8));
if (p.dd = $60000020) then
begin
p.dd:=header_offs+$10;
p.gotooff;
p.readD; p.size:=p.dd;
//form1.ListBox1.Items.Add('size '+inttohex(p.DD,8)); // size of code
p.readD; p.start_offs:=p.dd;
//form1.ListBox1.Items.Add('offset '+inttohex(p.DD,8));// offset to code
form1.ListBox1.Items.Add(s+' Ok '+inttostr(count));
p.Crop;
break;
end;
header_offs:=header_offs+$28;
until header_offs<total_offs;
p.close;
p.Free;
end;
procedure TForm1.Button2Click(Sender: TObject);
var f:textfile;
s:string;
begin
assignfile(f,'g:\a\1.lst');
reset(f);
count:=0;
while not eof(f) do
begin
readln(f,s);
if fileexists(s) then
analyse(s);
form1.ListBox1.ItemIndex:=form1.ListBox1.Items.Count-1;
application.ProcessMessages;
inc(count);
end;
closefile(f);
form1.Caption:='Ok';
end;
[1] исходные коды на языке ассемблера.
[2] Здесь символ пробела обозначается как “_”.
[3] Для краткости, будем обозначать любые естественные тексты Simple.
[4] Содержимое специальных контейнеров будет приведено в приложении A.1
[5] Как правило, сообщение в открытом виде не передается.
6 Появление различных серии бит равновероятно и между их появлениями отсутствуют закономерности.
7 Вероятность того, что найденное значение статистики превзойдет квантиль распределения.
8 Под случайностью понимается степень близости к равномерному распределению.
[9] Здесь используется линейный конгруэнтный генератор случайных чисел.
10 Случай, когда в качестве внедренного сообщения выступает естественный текст, не рассматривается по причине неактуальности.
11 Portable Executable – формат исполняемых файлов (программ) используется в операционных системах семейства Windows.
[12] О выборе величины подробнее будет написано в разделе 3.2.3.
[13] В разделах 3.2.2 и 3.2.3 была использована другая выборка
14 В дальнейшем будет установлено, что следует анализировать только часть секции кода программы.
[15] Распределение будет представлено в приложении A.2.
[16] Любое изменение в программе должно разрушать водяной знак.
17 Процессоры ARM доминируют на рынке мобильной и повседневной электроники, и составляют аппаратную платформу для мобильных устройств Nokia, Sony Ericsson и др.
[18] Размер файлов без учета комментариев в исходном коде программы