Thesis Document

159
STI College – Bacoor ADAPTIVE DIGITAL STEGANOGRAPHY FOR TRUE-COLOR BITMAPS A Thesis Presented to Systems Technology Institute Bacoor in Partial Fulfillment of the Requirements for the Degree of Bachelor of Science in Computer Science by: Gan, Mark David C. Mr. Gerry A. Villanueva Thesis Adviser March 2003

Transcript of Thesis Document

Page 1: Thesis Document

STI College – Bacoor

ADAPTIVE DIGITAL STEGANOGRAPHY FOR TRUE-COLOR BITMAPS

A Thesis Presented to Systems Technology Institute

Bacoor

in Partial Fulfillment of the Requirements for the Degree of

Bachelor of Science in Computer Science

by:

Gan, Mark David C.

Mr. Gerry A. Villanueva Thesis Adviser

March 2003

Page 2: Thesis Document

STI College – Bacoor

ADVISER’S RECOMMENDATION SHEET

This Thesis entitled

Adaptive Digital Steganography for True-Color Bitmaps

by:

Gan, Mark David C.

and submitted in partial fulfillment of the requirements of the Bachelor of Science in Computer Science degree has been examined

and is recommended for acceptance and approval

_________________________________ Mr. Gerry A. Villanueva

Thesis Adviser

March 2003

Page 3: Thesis Document

STI College – Bacoor

THESIS COORDINATOR AND DEAN’S ACCEPTANCE SHEET

This Thesis entitled

Adaptive Digital Steganography for True-Color Bitmaps

after having been recommended and approved is hereby accepted by the Information Technology Department of Systems Technology Institute - Bacoor

_________________________________ Mr. Angelo Magdangal A. Maderal

Thesis Coordinator

_________________________________ Ms. Minerva R. Almalvez

Assistant Dean

March 2003

Page 4: Thesis Document

STI College – Bacoor

PANEL’S APPROVAL SHEET

This Thesis entitled

Adaptive Digital Steganography for True-Color Bitmaps

developed by:

Gan, Mark David C.

after having been presented is hereby approved by the following members of the panel

_________________________________ Mr. Angelo Magdangal A. Maderal

Panelist March 2003

_________________________________ Mr. Ruben B. Muñoz

Panelist March 2003

_________________________________ Mr. Reynaldo P. Gozum

Lead Panelist March 2003

Page 5: Thesis Document

TABLE OF CONTENTS

Title Page

Adviser’s Recommendation Sheet

Thesis Coordinator and Dean’s Acceptance Sheet

Panel’s Approval Sheet

List of Appendices

List of Tables

List of Figures

Acknowledgement

Abstract

1.0 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-1

1.1 Background of the Study . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-1

1.2 Statement of the Problem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-4

1.3 Objectives of the Study . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-6

1.3.1 General Objective . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-6

1.3.2 Specific Objectives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-6

1.4 Significance of the Study . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-7

1.5 Scope and Limitation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-9

2.0 Methodology of the Study . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-1

3.0 Review of Related Literature and Studies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-1

4.0 Theoretical Framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-1

4.1 Parameters of Information Hiding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-1

4.2 Least Significant Bit Encoding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-4

4.3 Transform Embedding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-5

4.4 Masking and Filtering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-6

4.5 Bit-plane Steganalysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-6

4.6 Statistical Attacks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-8

4.7 Capacity Evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-10

Page 6: Thesis Document

4.8 Minimum-Error Replacement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-13

4.9 Error Diffusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-14

4.10 Pseudorandom Number Generators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-16

4.11 Hash Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-17

5.0 Data Gathering Procedures and Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-1

6.0 Documentation of Current System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-1

6.1 EyeMage IIE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-1

6.2 Invisible Secrets 2002 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-2

6.3 Steganos File Manager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-5

6.4 The Third Eye . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-6

7.0 Requirement Analysis Specification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-1

7.1 Performance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-1

7.2 Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-1

7.3 Usability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-2

7.4 Functionality . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-2

8.0 System Design Specification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-1

8.1 Stegosystem Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-1

8.1.1 Encoding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-2

8.1.2 Transmission . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-5

8.1.3 Decoding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-6

8.2 Stegosystem Pseudocode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-7

8.2.1 Capacity Evaluation Function . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-8

8.2.2 Minimum-Error Replacement Function . . . . . . . . . . . . . . . . . . . . 8-8

8.2.3 Error Diffusion Function . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-9

8.2.4 Encoding Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-9

8.2.5 Metadata Decoding Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-10

8.2.6 Data File Decoding Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-10

8.3 Image Formats . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-11

9.0 Systems Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-1

9.1 Programming Considerations, Issues and Tools . . . . . . . . . . . . . . . . . . . . 9-1

Page 7: Thesis Document

9.2 System Requirement Specification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-2

9.3 Testing Activities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-4

9.4 Installation Process . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-12

10.0 Conclusion and Justification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-1

11.0 Recommendation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-1

Appendices

Bibliography

Curriculum Vitae

Page 8: Thesis Document

LIST OF APPENDICES

Appendix A. Information Hiding Terminology

Appendix B. Mathematical Notations

Appendix C. Project Schedule

Appendix D. Cover Images Used in Performance Testing

Appendix E. Stego Images With Severe Distortions

Appendix F. Chameleon Help File

Appendix G. Chameleon Source Code

Page 9: Thesis Document

LIST OF TABLES

Table 9-1. Cover-Images Used in Performance Testing . . . . . . . . . . . . . . . . . . . . . 9-5

Table 9-2. Test Results for Cover Image “abandon.bmp” . . . . . . . . . . . . . . . . . . . . 9-6

Table 9-3. Test Results for Cover Image “antelope.bmp” . . . . . . . . . . . . . . . . . . . . 9-6

Table 9-4. Test Results for Cover Image “badwater.bmp” . . . . . . . . . . . . . . . . . . . 9-7

Table 9-5. Test Results for Cover Image “death.bmp” . . . . . . . . . . . . . . . . . . . . . . 9-7

Table 9-6. Test Results for Cover Image “gardens.bmp” . . . . . . . . . . . . . . . . . . . . 9-7

Table 9-7. Test Results for Cover Image “kiss.bmp” . . . . . . . . . . . . . . . . . . . . . . . . 9-8

Table 9-8. Test Results for Cover Image “nap.bmp” . . . . . . . . . . . . . . . . . . . . . . . . 9-8

Table 9-9. Test Results for Cover Image “passing.bmp” . . . . . . . . . . . . . . . . . . . . . 9-8

Table 9-10. Test Results for Cover Image “race.bmp” . . . . . . . . . . . . . . . . . . . . . . . 9-9

Table 9-11. Test Results for Cover Image “rain.bmp” . . . . . . . . . . . . . . . . . . . . . . . . 9-9

Table 9-12. Test Results for Cover Image “ruins.bmp” . . . . . . . . . . . . . . . . . . . . . . . 9-9

Table 9-13. Test Results for Cover Image “storm.bmp” . . . . . . . . . . . . . . . . . . . . . . 9-10

Table 9-14. Test Results for Cover Image “style.bmp” . . . . . . . . . . . . . . . . . . . . . . . 9-10

Table 9-15. Test Results for Cover Image “subtle.bmp” . . . . . . . . . . . . . . . . . . . . . . 9-10

Table 9-16. Test Results for Cover Image “sunrise.bmp” . . . . . . . . . . . . . . . . . . . . . 9-11

Page 10: Thesis Document

LIST OF FIGURES

Figure 2-1. Software Engineering Paradigm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-1

Figure 4-1. Data-Hiding Problem Space . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-3

Figure 4-2. A Grayscale STI College Logo and its Bit-planes . . . . . . . . . . . . . . . . 4-7

Figure 4-3. Neighbors of a Pixel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-9

Figure 6-1. A Noise Image Created by EyeMage IIE . . . . . . . . . . . . . . . . . . . . . . 6-1

Figure 6-2. Screenshot of EyeMage IIE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-2

Figure 6-3. Screenshot of Invisible Secrets 2002 . . . . . . . . . . . . . . . . . . . . . . . . . . 6-4

Figure 6-4. Screenshot of Steganos File Manager . . . . . . . . . . . . . . . . . . . . . . . . . 6-5

Figure 6-5. Screenshot of The Third Eye . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-7

Figure 8-1. Framework of the Proposed Stegosystem . . . . . . . . . . . . . . . . . . . . . . 8-1

Figure 8-2. HIPO Chart of the Encoding Module . . . . . . . . . . . . . . . . . . . . . . . . . . 8-2

Figure 8-3. HIPO Chart of the Decoding Module . . . . . . . . . . . . . . . . . . . . . . . . . 8-6

Figure D-1. abandon.bmp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D-1

Figure D-2. antelope.bmp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D-2

Figure D-3. badwater.bmp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D-3

Figure D-4. death.bmp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D-4

Figure D-5. gardens.bmp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D-5

Figure D-6. kiss.bmp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D-6

Figure D-7. nap.bmp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D-7

Figure D-8. passing.bmp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D-8

Figure D-9. race.bmp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D-9

Figure D-10. rain.bmp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D-10

Figure D-11. ruins.bmp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D-11

Figure D-12. storm.bmp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D-12

Figure D-13. style.bmp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D-13

Figure D-14. subtle.bmp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D-14

Figure D-15. sunrise.bmp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D-15

Figure E-1. e_abandon_data350k.bmp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . E-1

Page 11: Thesis Document

Figure E-2. e_gardens_data310k.bmp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . E-2

Figure E-3. e_rain_data170k.bmp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . E-3

Figure E-4. e_storm_data350k.bmp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . E-4

Figure E-5. e_style_data190k.bmp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . E-5

Figure E-6. e_sunrise_data360k.bmp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . E-6

Page 12: Thesis Document

ACKNOWLEDGEMENT

First of all, the author would like to thank his thesis adviser, Mr. Gerry

Villanueva, and the thesis coordinator, Mr. Angelo Magdangal Maderal. Their continued

efforts in supervising the development of this thesis is truly appreciated.

The author would also like to express his appreciation for the well-needed support

and guidance extended by the faculty and staff of STI College Bacoor.

Sincere gratitude also goes to Mr. Conrado Vidal who provided valuable

assistance in the preparation of this paper.

The author also gives out thanks to his friends and classmates who have helped in

various ways for the benefit of this project.

Lastly, the author extends out heartfelt appreciation to his parents and relatives

who have contributed a great deal of moral and material support not only for the

completion of this project but more importantly for the physical, mental, and spiritual

well-being of the author. This project would not have been possible without them.

Page 13: Thesis Document

ABSTRACT

Steganography is the science of hiding the existence of information for the

purpose or covert communications. Unlike cryptography which conceals the content of a

message, steganography conceals the very existence of a message.

In the electronic world, one of the most appropriate “hosts” for steganography are

digital images. Digital photographs are a commonly shared, sent, and exchanged

throughout the Internet in the form of email attachments or web postings. However,

current steganographic software available on the market have poor support for

high-capacity image steganography. Even worse, some steganographic software actually

distort or degrade the appearance of cover images and therefore exposes the

steganographic transformation the image has undergone.

In this study, a new image steganography software was presented to answer the

need for a software that makes optimum use of hiding space in an image without creating

any visible distortions. Along with a highly secure method for randomized encoding,

techniques for adaptive encoding were incorporated with the design of the software.

These techniques include capacity evaluation, minimum-error replacement, and error

diffusion.

The test results of comparing the performance of the presented software with

popular and currently-available steganography software showed that the presented

software is a major improvement especially in terms of providing high capacities for

hidden data while preserving the quality and appearance of the image.

Page 14: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 1-1

1.0 INTRODUCTION

1.1 Background of the Study

Cryptography has long been the cornerstone of information

security. With a history that can be traced back to the ancient Egyptians

some 4000 years ago, it still plays a crucial role in present-day diplomatic

and military services [MENE1996]. However, encryption of messages is

obviously useful only when there is an expected enemy that is monitoring

the channel of communications. Unfortunately, detection of encrypted

communications is likely to provoke an enemy to exert great efforts in

destroying the exposed signal. In an even worse scenario, an enemy may

have enough computing power to break the encryption and decipher the

message. In such situations, the secrecy of the message transmission can

be as vital as the secrecy of the message itself.

Such a case was introduced by G. J. Simmons in 1983 as the

Prisoners’ Problem [ANDE1998]. The problem is that of two prisoners

named Alice and Bob who want to devise an escape plan.

Communications between them pass through a warden named Willie, who

frustrates their plans by putting them into solitary confinement every time

an encrypted message is detected. To avoid detection, they must first find

a way to conceal not only the content of the message but also the message

transmission itself. The solution is an ancient craft called steganography.

Page 15: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 1-2

Steganography is the art and science of hiding the existence of

information. The term originated from Greek words (στεγανοζ and

γραφειν) that literally mean “covered writing” [HETZ2002]. The Greek

historian Herodotus recorded several accounts of steganography in the

ancient times [KAHN1996]. One of these stories was that of a man named

Histaieus who wanted to inform his allies when to revolt against the

Medes and the Persians. To avoid detection, the message was tattooed on

the shaved head of a trusted slave whose hair was later allowed to grow

before being dispatched to Persia. The message was successfully sent and

a victorious revolt soon followed.

Steganography played a key role in classical warfare and it

continued to do so even in modern times. In World War I, for example,

spies made extensive use of invisible inks in order for their mail to pass

through censorship bureaus [DAVE1995]. During World War II, microdot

technology allowed the Germans to photographically shrink documents

into the size of a printed period and avoid detection [KAHN1996]. At the

turn of the century, even the international terrorist leader Osama bin Laden

is believed be using steganography to “covertly distribute information to

his supporters and hide messages throughout the Internet” [SIEB2001].

Evidently, the practical use of steganography in covert communications

makes it one of the most significant subdisciplines in the field of

information hiding.

Page 16: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 1-3

Although considered as a relative of cryptography, steganography

presents an entirely different perspective in protecting data. Cryptography

conceals the content of a message; steganography conceals the very

existence of a message [ANDE1998]. Encrypted text is quite prone to

detection, primarily due to its enigmatic or scrambled appearance. For

instance, practically any person who sees a piece of text written like

“HQFUBSWHG PHVVDJH” would suspect that it is an encrypted

message, since the text is obviously meaningless in its present form. On

the contrary, steganography avoids exposure by hiding information within

common and seemingly harmless media. Instead of merely obscuring the

appearance of information, the observer is provided with a convincing

illusion. As a result, the act of communication itself is kept secret.

The introduction of computers to the modern world has provided

various forms of digital media that can be exploited by steganography to

secretly host vital information. Modern approaches include the use of text

documents, digital pictures and even music files as carriers of hidden data.

For digital images, the most basic method for steganography is called least

significant bit encoding (LSB encoding). The simple and logical concept

behind this method makes it effective in concealing relatively large

volumes of data within a single image.

Unfortunately, the transformation-sensitive nature of

LSB-embedded data makes LSB encoding inapplicable to some image

formats, including popular standards like JPEG and GIF. As a result, most

Page 17: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 1-4

researchers and developers focus their work on improving alternative

methods for image steganography; therefore leaving behind formats that

use LSB encoding like the standard Windows Bitmap (.bmp).

With the advent of these emerging steganographic technologies,

steganographic software applications are now becoming considerably

popular in the information security industry. Among the most popular and

highly acclaimed are Steganos File Manager, Invisible Secrets 2002,

EyeMage IIE and The Third Eye. All these four steganographic software

utilize safe hiding algorithms for standard Windows bitmaps. However,

most steganographic software available in the market are not always

suitable or sufficient for real-world applications of steganography because

of certain problems with respect to their design.

This study works on the problems of current steganographic

programs and presents a fully-operational software designed for real-world

application of steganography in covert communications and covert data

transfer.

1.2 Statement of the Problem

Generally, current steganographic software are adequate tools for

concealing information. However, most of the steganographic techniques

incorporated by these tools have certain weaknesses that may render the

software inapplicable in certain real-world situations that require the use

of steganography.

Page 18: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 1-5

Basically, these weaknesses include the following:

• Inefficient use of hiding space for bitmap images.

Current steganographic software uses standard LSB

encoding for bitmap images, which means the number of bits

used for data hiding is the same (fixed) for every pixel. To

minimize the possibility of making visual distortions in the

resulting image, only the first LSB of each color component of

each pixel is used as hiding space. Considering the relatively

larger file size of uncompressed bitmaps, keeping the size of

the hiding space to a fixed minimum results in inefficiency.

• Tendency to produce distortions in the image.

To maximize hiding capacity, an alternative method is to

use more bits in a pixel instead of just the least significant bits.

As embedding is performed on more-significant bits,

distortions or noticeable marks tend to appear on the image.

Moreover, with original high-resolution digital photographs,

distortions can appear even when embedding is performed only

on the least significant bits.

• Insecure hiding schemes.

Some steganographic software utilize insecure techniques

such as comment insertion for JPEG (Joint Photographic

Experts Group) and PNG (Portable Network Graphics) image

formats. As the name suggests, the algorithm works by merely

inserting data as comments in the header of the image file.

Although this method allows a virtually unlimited size of data

to be hidden, this is obviously insecure. Since the data is not

encoded within the pixels of the image but rather as header

information, the hidden data is readily visible and extractable

Page 19: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 1-6

in a file editor. Such hiding scheme hardly qualifies as real

steganography.

For a further discussion on the nature of these problems, the

concepts behind LSB encoding along with other topics on information

hiding are discussed in Chapter 4.

1.3 Objectives of the Study

1.3.1 General Objective

This study aims to develop a secure steganography

software that overcomes the weaknesses of current steganographic

software and that is suitable for real-world application in covert

communications before the end of the school year 2002-2003.

1.3.2 Specific Objectives

To accomplish this objective, this study aims to:

• Incorporate techniques that would eliminate the

possibility of creating human-perceptible distortions in

the image.

• Incorporate techniques that would maximize the use of

hiding space in the image.

• Incorporate techniques that encode the hidden data

within the pixels of the image in order to make them

more integrated with the image itself and not merely as

appended header information in the image file.

Page 20: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 1-7

• Establish security that is reliable even when an enemy

has knowledge of how the steganographic algorithm

works, i.e., unconditional security.

1.4 Significance of the Study

As a relative of cryptography in the spycraft family, steganography

is undeniably significant in the espionage industry. However, its use is

certainly not limited to illegal or malicious purposes. Steganography can

also be used to defeat espionage by concealing and securing the

transmission of sensitive information. Around the world, there are

growing concerns regarding diplomatic, industrial and even domestic

espionage. Nowadays, such attacks may come from a wide variety of

organizations that range from government intelligence agencies to

international terrorist networks.

In the fifth of July 2000, for instance, the European Parliament

decided to investigate claims that a global interception system, presumably

codenamed ECHELON, is “being used for purposes of industrial

espionage” under the control of the US National Security Agency (NSA)

and associate countries [SCHM2001]. Although no substantial evidence

proved that it has actually been used to gather competitive intelligence in

favor of American business firms, it was concluded that the satellite-based

interception system undoubtedly exists and is operational.

During the same year, the US Federal Bureau of Investigation

(FBI) also stirred up human rights issues with its Carnivore software

Page 21: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 1-8

[MCCU2000]. Like its reported predecessors, Carnivore is capable of

intercepting Web and email traffic as part of investigations on suspected

felons. The online article “How Carnivore Works” explains that the

software uses a technology called packet sniffing, which is a common

technology used by network administrators to monitor network traffic

[TYSO2001]. The unfortunate availability of this technology leads to

serious security concerns regarding Internet traffic.

Government intelligence agencies also have rising concerns

regarding the communications capabilities of extremist factions. Even

before the heightened security concerns brought about by the September

11, 2001 terrorist attack on the World Trade Center, Muslim extremist

groups that are linked to the attacks were already reported to be using

“Internet bulletin boards carrying pornographic and sports information” as

hosts for innocuous-looking pictures encoded with terrorist guerilla plots

[PLEM2001]. Clearly, such exploitations of Internet media pose a threat to

society and are unacceptable.

This paper provides useful information regarding both established

and experimental steganographic techniques. These techniques provide

formidable security for data transmission over public channels such as the

Internet. Companies and various institutions can also integrate

steganographic technology as a primary layer to their existing security

protocols. For example, those which use cryptography as their only

security layer may incorporate steganography as an additional first line of

Page 22: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 1-9

defense next to encryption. This way, transmitted messages need to be

detected, extracted and deciphered before its contents can be compromised

to unauthorized personnel.

In addition, understanding the concepts behind digital

steganography can help Web-based companies to develop precautionary

measures to protect their websites or message boards from being used as

hosts for covert criminal transactions such as terrorist plots. Similar

protocols may also be employed by business firms to prevent disloyal

employees from using steganography in secretly passing sensitive

information to rival companies through the company’s own website.

1.5 Scope and Limitation

This study centers its work on the application of digital image

steganography in covert communications. The techniques presented in this

study are not suitable for other areas of information hiding since different

applications focus on different features, as explained in Chapter 4.

Focusing on communications, the primary concerns of the proposed

steganographic software are imperceptibility and hiding capacity.

This study also limits its work on true-color bitmaps. True-color

bitmaps represent pixels as a combination of three 8-bit values

corresponding to the red, green, and blue color components of a pixel.

Despite of its relatively large file size as compared to grayscale images,

the true-color format offers a wider range of distinct colors. More colors in

Page 23: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 1-10

an image’s palette means less difference in color tone between each pair of

close colors. This allows for higher levels of modification to be made in

each pixel before the human eye is capable of noticing the changes in

color.

It is important to note that the presented algorithms are

inapplicable to image formats that use lossy compression. Lossy

compression refers to the type of compression wherein “some data is

deliberately discarded to achieve massive reductions in the size of the

compressed file” [PFAF1995]. An example of which is the Discrete

Cosine Transform (DCT) of the popular JPEG image format. This

transformation smoothens the random textures of an image, the same areas

of texture in which embedding is most appropriate. Such transformations

can therefore destroy the data embedded within an image.

Furthermore, although such transformations remove details that are

typically imperceptible to the human eye, repeated processing will

eventually result in a highly degraded image quality. On the other hand,

bitmaps that utilize lossless compression store color values in exact detail.

This means that unlike in JPEG images, bitmaps remain exactly the same

regardless of how many times they are saved or copied.

Page 24: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 2-1

2.0 METHODOLOGY

As an outline for the software development section of this study, the

author followed the generic software engineering paradigm presented by

Pressman [PRES1992]. However, Pressman’s generic paradigm is an outline for

company-based software systems. In contrast, the application software developed

in this study is not designed for any specific organization or individual. Its main

purpose is to demonstrate the proposed stegosystem and to test it effectiveness.

With this in mind, the generic paradigm was modified to suit the needs of the

project. The five phases of this modified paradigm is presented in Figure 2-1.

The analysis phase is concerned with defining the scope and functions of

the software being developed. In this phase, the specific attributes that need to be

incorporated to the stegosystem are assessed. Then follows the design phase,

where concepts and techniques are put together to form an abstract model of the

Figure 2-1.

Software Engineering Paradigm

Analysis

Design

Coding

Testing

Enhancement

Page 25: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 2-2

proposed stegosystem. In the coding phase, the model conceptualized in the

design phase is translated to computer code by construction of a software

prototype. After construction, next is the testing phase where the effectiveness of

the design is evaluated. Finally, in the enhancement phase, additional

optimizations or corrections are made to the algorithm as necessary.

Supplementary software features are also added in this phase, yielding a fully

engineered version of the application software.

It is important to note that since the software is not a company-based

software system, adaptive maintenance is inapplicable. The software is designed

for a specific use, not for a specific user. It is generic and does not need to adapt

to a specific organization or individual.

Furthermore, requirement analysis is very limited. No company-related

data gathering operations, like interviews and surveys, are needed in this study.

The requirements defined for the proposed stegosystem are based entirely on the

concepts of information hiding and of other fields in computer science.

Page 26: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 3-1

3.0 REVIEW OF RELATED LITERATURE AND STUDIES

Over the past few years, a growing interest in the field of information

hiding started to arise. In May of 1996, the “First International Workshop on

Information Hiding” was held in Cambridge, UK. From then on, several areas of

the new field, like steganography and digital watermarking, started to get

attention from the research community. INSPEC reported that by 1998, the

number of publications on digital watermarking alone increased to 103 from

merely 2 back in 1992 [PETI1999].

Following the trend, different research institutions published reports and

journal articles that advertised the developing field. The Institute of Electrical and

Electronics Engineers (IEEE) published many of these articles, especially those in

the area of steganography. Neil Johnson and Sushil Jajodia’s article in the IEEE’s

magazine Computer provided a good primer for understanding steganography

[JOHN1998]. The article discussed basic techniques for image steganography and

evaluated a few steganographic software. Ross Anderson and Fabien Petitcolas

discussed the limitations of steganography in a special issue of the IEEE Journal

of Selected Areas in Communications [ANDE1998]. Petitcolas and Anderson,

along with Markus Kuhn, also wrote a summary of different areas of information

hiding and discussed several practical applications in the July 1999 issue of

Proceedings of the IEEE [PETI1999].

In 1996, Walter Bender et al. wrote a comprehensive article entitled

“Techniques for Data Hiding” for the IBM Systems Journal [BEND1996]. This

renowned publication discussed watermarking techniques for digital images such

Page 27: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 3-2

as Texture Block Coding and the robust Patchwork algorithm. For digital audio,

the article also discussed low-bit coding, phase coding, echo data hiding, and

Direct Sequence Spread Spectrum (DSSS) encoding.

Bender et al. also explained semantic and syntactic methods for data

hiding in text. Syntactic methods manipulate punctuations such as commas in

order to encode a series of bits. Semantic methods, on the other hand, encode data

by replacing certain words with synonyms, where each synonym corresponds to a

certain binary value. Perhaps the simplest text-based steganographic techniques

presented in the article are the open space methods, otherwise known as white

space steganography. Bender presented such methods that encode data bits by

modulating the number of spaces between each pair of words. A simple approach

to such methods is to encode 0’s as single spaces and 1’s as double spaces.

A more efficient white space method is Matthew Kwan’s SNOW

algorithm, which stands for “Steganographic Nature of Whitespace”

[KWAN2001]. Unlike Bender’s example, SNOW encodes a set of three bits as a

set of spaces whose length is equal to the decimal value of the set of bits. Each set

of spaces is terminated with a tab character, which is also a white space. This

ensures that for each column of white spaces, exactly three bits of data are stored.

For example, the binary value 111 (decimal number 7) is encoded as a

combination of seven spaces and a tab. The binary value 011 (decimal number 3)

on the other hand, is encoded as a combination of three spaces and a tab.

Furthermore, these sets of white spaces are placed only at the end of every line of

text so as not to affect the appearance of the text.

Page 28: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 3-3

Bender’s article was later followed by the equally comprehensive

“Applications for Data Hiding” in 2000 [BEND2000]. This next article, also

written by Bender, discussed several applications of information hiding such as

anti-counterfeiting, tamper detection, and copyright marking.

Well noted for his works on digital watermarking, Bender also supervised

the Master’s degree thesis of Fernando Paiz entitled “Tartan Threads: A Method

for the Real-time Recognition of Secure Documents in Ink Jet Printers”

[PAIZ1999]. This impressive thesis for the Massachusetts Institute of Technology

(MIT) presented a robust watermarking technology that can be used to prevent

inkjet printers from printing copyrighted documents and even monetary bills.

Such technologies are truly valuable in fighting forgery and counterfeiting.

Recognizing its significance in covert communications, the US Military

also conducted studies on steganography. One of which was the project lead by

Lisa Marvel on Spread Spectrum Image Steganography (SSIS), which was

sponsored by the US Army Research Laboratory [MARV1999]. SSIS adopted

concepts from spread spectrum communications to maximize embedding capacity

and imperceptibility. The Air Force Research Laboratory, on the other hand,

sponsored the work of Jiri Fridrich et al. on steganalysis techniques for detecting

LSB encoding in color images [FRID2000]. The Office of Naval Research also

supported steganographic studies. Under the Naval Research Laboratory,

Moskowitz et al. wrote the article “A New Paradigm Hidden in Steganography”.

The article explained how the concepts of information theory are inapplicable in

steganography, unlike in the case of cryptography [MOSK2000].

Page 29: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 3-4

With the emergence of several studies on various steganographic

techniques, some researchers moved on to the study of steganalysis, i.e., the

process of detecting and defeating steganography. In 2002, Jessica Fridrich and

Miroslav Goljan wrote a paper entitled “Practical Steganalysis of Digital Images”

[FRID2002]. The paper is a compilation of current approaches to steganalysis and

included discussions on both visual attacks and statistical attacks. Visual attacks

rely on a human observer to “look for suspicious artifacts using simple visual

inspection”. The paper pointed out that despite the simplicity of visual attacks, “it

may be impossible to distinguish noisy images or highly textured images from

stego images using this technique”.

Statistical tests, the other hand, look for discrepancies in certain expected

properties of an image. Neils Provos and Peter Honeyman explains that “some

tests are independent of the data format and just measure the entropy of the

redundant data” [PROV2001a]. This means that images with hidden data are

expected to have “higher entropy” than those without. Images without hidden

data, for example, tend to have an LSB plane that is correlated to 1 or 0. Jiri

Fridrich’s paper on steganalysis for the Air Force Research Laboratory discusses

a technique that is based on evaluating the relative frequencies of close color pairs

[FRID2000].

With respect to statistical attacks, Neils Provos wrote a paper entitled

“Defending Against Statistical Steganalysis” which discusses certain

countermeasures that could help prevent the detection of hidden information.

These approaches “included preserving correlations to one and entropy measured

Page 30: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 3-5

by the Maurer test” [PROV2001]. These concepts were incorporated in Provos’

image steganography software called OutGuess which uses the JPEG format.

Another software designed to defeat statistical steganalysis is Andreas

Wesfeld’s software named F5 [WEST2001]. F5 uses a technique called matrix

encoding in order to maximize hiding capacity in JPEG images. As a result, F5

uses an average of 13% of the image file size, which means it is as space-efficient

as the standard fixed-size LSB encoding in lossless true-color bitmaps.

In 2002 however, Jessica Fridrich et al. wrote a paper entitled “Attacking

the OutGuess” which explains how stego images created with OutGuess, F5, and

other JPEG-based steganography software can be reliably detected and identified

[FRID2002a]. The results presented in the paper was verified by Provos himself

by developing a software called Stegdetect based on the presented steganalysis

techniques. The reliability of the techniques presented were acknowledged by

Provos in the OutGuess website, where Stegdetect is available for download

[PROV2002].

Other relevant publications on steganography are cited in Petitcolas and

Anderson’s “Information Hiding: An Annotated Bibliography” [ANDE1999].

This bibliography written for the Computer Laboratory of the University of

Cambridge is an excellent resource guide on practically every area of information

hiding.

Page 31: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 4-1

4.0 THEORETICAL FRAMEWORK

4.1 Parameters of Information Hiding

Depending on the application, different methods for information

hiding are inherently focused on different features or parameters. The

basic parameters of information hiding systems are imperceptibility,

hiding capacity, and robustness.

Imperceptibility, or perceptual transparency, is obviously an

inherent goal of every information hiding system. In order to conceal the

existence of hidden information, it is important that the embedding

process does not produce perceptible distortions to the cover-medium.

Bender et al. related this concept to the magician’s trick of misdirection,

which allows “something to be hidden while it remains in plain sight”

[BEND1996].

An extension to imperceptibility is undetectability. Instead of

exploiting the weaknesses of human perceptive capabilities, as in the case

of imperceptibility, undetectability focuses on defending steganography

against computer-based steganalysis by preserving certain statistical

characteristics of the cover-medium. Undetectability is therefore

concerned with the stego-medium’s consistency with the statistical

characteristics of the original cover-medium [FRID1998].

Hiding capacity, which is also referred to as embedding capacity,

bit-rate, and payload, was defined by Eugene Lin and Edward Delp as

Page 32: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 4-2

“the size of information that can be hidden relative to the size of the

cover” [LIN1999]. They further explained that a higher capacity rate

reduces the need for using larger cover-files. This in turn enhances

portability and transmission speed, which are both high priorities in covert

communications. Digital watermarking systems, on the other hand, embed

only small volumes of data like copyright information and thus capacity is

of minimal importance in such applications [BEND1996].

Robustness is the resistance against attempts to destroy the

embedded data by means of modifying the stego-medium. Bender et al.

stated that sources of such modifications range “from intentional and

intelligent attempts of removal to anticipated manipulations”

[BEND1996]. In image processing, these “anticipated manipulations”

include the inevitable consequences of certain image transformations. A

good example of which is the downgrading of image quality in the JPEG

format, as explained in Chapter 1.

Beyond accidental or intentional destruction of embedded data, an

even greater threat is tampering. An example of such malicious attack is a

pirate’s attempt to alter embedded copyright information. As with music

files, copyrighted images are common targets of piracy. Robustness and

tamper resistance are therefore primary concerns of digital watermarking

systems [LIN1999].

Marvel et al. stated that capacity and robustness is impossible to

maximize at the same time while adhering to high imperceptibility rates

Page 33: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 4-3

[MARV1999]. In an article for the IBM Systems Journal, Bender et al.

introduced this trade-off between capacity and robustness as the

data-hiding problem space [BEND1996]. The article explains that to

achieve robustness, redundant encoding of the embedded data on the

cover-medium must be performed, which in turn sacrifices capacity.

Figure 4-1 is based on Fridrich’s diagram for the data-hiding problem

space, which depicts the mutually competitive nature of these parameters

[FRID1998].

As the triangular shape of the diagram shows, the three opposing

parameters cannot be maximized all at the same time. In the case of covert

communications, for example, working on the midpoint between

imperceptibility and hiding capacity provides optimum balance between

the two parameters but at the expense of completely compromising

robustness. On the other hand, digital watermarking systems sacrifice

capacity in favor of robustness, as is required by the application.

Figure 4-1.

Data-Hiding Problem Space

Imperceptibility

Hiding Capacity Robustness

Digital Watermarking Steganography

Page 34: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 4-4

4.2 Least Significant Bit Encoding

The concept behind LSB encoding is to replace the least

significant bit (LSB) of each pixel in an image with the bits of the data to

be embedded [LIN1999]. In a grayscale image, for example, each pixel is

represented by an 8-bit value that corresponds to the pixel’s intensity. The

lower the value, the closer the pixel is to the color black. Since the least

significant bit has a place value of 1, modifying it would result in a

maximum difference of only 1. Because the human eye is not capable of

distinguishing minute changes in color, such modifications would

normally be imperceptible.

In true-color bitmaps, the three colors of light (red, green, and

blue) are combined in varying intensities to define the color of each pixel.

Each color component is represented by an 8-bit value that corresponds to

the component’s intensity, ranging from 0 to 255. Since there are three

LSB’s in each pixel, the hiding capacity in terms of bits is three times the

total number of pixels in the cover image. In a 300x300 bitmap, for

example, the hiding capacity is 270,000 bits (33,750 bytes).

In cases that require large volumes of data to be hidden,

embedding can be performed even up to the second or third LSB of each

color component of a pixel. However, using the more significant portions

of a color component will certainly cause drastic changes in the image.

These changes may exist in the form undesirable marks and artifacts or as

distortions in the contour of smooth areas in an image.

Page 35: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 4-5

LSB encoding, therefore, deals with two basic problems:

• If capacity is maximized, modifications become evident and

secrecy is compromised.

• If imperceptibility is maximized, lower volumes of data can be

hidden.

Furthermore, embedding in images with areas of very smooth

textures or solid patterns, such as computer-drawn images and graphs, is

likely to create visible distortions even if only the first LSB’s are

modified.

4.3 Transform Embedding

Because of the loss of data caused by the transformations

employed by many image file formats, standard LSB encoding is

inapplicable to many images. In such cases, instead of manipulating the

pixels or the spatial domain of an image, the coefficients of the transform

domain of a processed image is used [LIN1999]. The JPEG format, for

example, uses a lossy compression algorithm called the Discrete Cosine

Transform (DCT). The LSBs of the coefficients of this transform can then

be used as hiding space for data bits.

Although transform embedding techniques are typically more

robust as compared with standard LSB encoding, they also typically offer

less hiding capacity [LIN1999]. Furthermore, since such techniques are

format-dependent and embed data after the transformations have been

Page 36: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 4-6

made, the embedding process may alter certain statistical properties of the

image that are common or unique to that particular image format. This

makes transform embedding techniques susceptible to detection or

steganalysis. Considering this, such techniques are ideal only for

applications like copyright marking and authentication.

4.4 Masking and Filtering

Another alternative method for data hiding in digital images are

masking and filtering techniques. Such techniques hide data by “marking

an image in a manner similar to paper watermarks”, thus they are designed

for application in digital watermarking [JOHN1998].

Digital watermarking techniques are more robust than traditional

steganographic techniques since watermarks are more integrated into the

image. The Patchwork watermarking algorithm, for example, embeds data

by manipulating the brightness or luminance of certain pairs of points in

an image [BEND1996].

4.5 Bit-plane Steganalysis

A bit-plane is the plane formed by the bits of the same bit position

in each pixel. Figure 4-2 shows a grayscale image of the STI College logo

along with its eight bit-planes. Black areas in the bit-planes represent a bit

value of 0 while white areas represent 1. Figure 4-2b is the most

significant bit-plane of the original image depicted as Figure 4-2a. Figure

Page 37: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 4-7

4-2i, on the other hand, is the least significant bit-plane of the original

image.

Yeuan-Kwen Lee and Ling-Hwei Chen made two important

observations regarding bit-planes that are relevant to information hiding

[LEE1999]. The first observation is that areas appearing as random texture

in a more significant bit-plane will also appear as random texture in less

significant bit-planes. The second observation is that randomness in the

texture of a specific area increases gradually from the most significant

bit-plane to the least significant bit-plane. These observations are evident

in Figure 4-2.

Random textures in a bit-plane are produced by transitions of

0-to-1 or 1-to-0 in the values of adjacent bits in a bit-plane. Considering

the observations on bit-planes, Lee and Chen concluded that transition

(b) (d) (c)

(a)

(e)

(g) (f) (h) (i)

Figure 4-2.

A Grayscale STI College Logo and its Bit-planes

Page 38: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 4-8

density is higher in less significant bit-planes compared to that of more

significant bit-planes [LEE1999].

Embedding in the more significant bits of an image is likely to

increase the transition densities of these bit-planes. The supposedly

gradual increase in transition density from more significant bit-planes to

less significant bit-planes would consequently be changed. Considering

this phenomenon, an attacker can therefore detect the presence of

embedded data by analyzing the transition densities of the bit-planes of an

image.

However, it is important to note that like most techniques for

steganalysis, bit-plane steganalysis is essentially based on statistical

observations and assumptions of distinct properties of the cover-medium.

The results of such methods for detection are not always reliable as they

may sometimes miss detecting hidden data or falsely identify a plain

image as a host for steganography. Moreover, Lee and Chen’s paper does

not provide details as to how bit-plane steganalysis may be automated

with the use of algorithms or software. Bit-plane steganalysis therefore

remains a visual attack and thus require a human observer to evaluate the

bit planes.

4.6 Statistical Attacks

Unlike visual attacks, statistical attacks are steganalytic methods

that can be automated through software. Statistical attacks operate by

Page 39: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 4-9

detecting discrepancies in certain expected properties of an image or

image format. Lossy-compressed image formats, like JPEG for example,

tend to have distinct statistical properties because of the transformations

involved. Jessica Fridrich and Miroslav Goljan’s paper on practical

steganalysis explains that after a JPEG image is embedded with data, “the

cover image will become incompatible with the JPEG format in the sense

that it may be possible to prove that a particular 8x8 block of pixels could

not have been produced by JPEG decompression” [FRID2002]. The JPEG

compatibility test can therefore “potentially detect messages as short as

one bit”. Such distinct properties therefore make JPEG images very

vulnerable to attacks.

On the other hand, lossless-compressed bitmaps do not undergo

transformations and are therefore unlikely to have distinct properties, since

any combination of pixels in any area of the image is possible. However,

Jiri Fridrich et al. wrote a paper entitled “Steganalysis of LSB Encoding in

Color Images” that describes a steganalysis technique that is expected to

detect statistical discrepancies even in lossless-compressed true-color

bitmaps [FRID2000]. This technique called the RQP method (Raw Quick

Pair method) “is based on analyzing close pairs of colors created by LSB

embedding” [FRID2002].

Fridrich et al. states that data embedding tends to increase the

number of close colors in an image’s palette [FRID2000]. If an image

already has been embedded with hidden data, the ratio between the

Page 40: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 4-10

number of all pairs of close colors and the number of all color pairs will

no longer increase if LSB encoding of random data is again performed on

the image.

A pair of colors is considered to be “close” if the difference

between the red-green-blue values of one color and the red-green-blue

values of the other color is less than or equal to 1. This expression can be

expressed as:

(|R1 – R2| ≤ 1) and (|G1 – G2| ≤ 1) and (|B1 – B2| ≤ 1)

This is expression is also equivalent to:

(R1 – R2)2 + (G1 – G2)

2 + (B1 – B2)2 ≤ 3

The RQP method is said to work “reasonably well as long as the

number of unique colors in the cover image is less than 30% of the

number of pixels” [FRID2002].

4.7 Capacity Evaluation

Instead of embedding on a fixed number of bits in every pixel, the

size of the hiding space in each pixel must be dependent on the color

variation of the adjacent pixels. This prevents the embedding process from

making drastic modifications in the smooth areas of an image, therefore

minimizing human-perceptible distortions. Such adaptive selection of

hiding space also protects the stego image from bit-plane steganalysis and

Page 41: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 4-11

other visual attacks since the significant bits of each pixel remain

unchanged.

Lee and Chen presented a simple method for evaluating the hiding

capacity of a pixel in a grayscale image [LEE1999]. For a particular pixel

P, the first step is to get the gray level variation in its top-left adjacent

pixels A, B, C, and D. The schematic layout of these pixels is depicted in

Figure 4-3. The gray level variation is defined as the difference between

the maximum and the minimum gray values among the four pixels. The

formula for the gray level variation V can be written as:

V = max {A, B, C, D} – min {A, B, C, D}

According to Lee and Chen, the number of bits that can be

modified in pixel P is the minimum number of bits needed to store the

Figure 4-3.

Neighbors of a Pixel

B (x-1,y-1)

A (x-1,y)

H (x-1,y+1)

C (x,y-1)

P (x,y)

G (x,y+1)

D (x+1,y-1)

E (x+1,y)

F (x+1,y+1)

Page 42: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 4-12

binary value of V minus 1. Mathematically, this can be expressed simply

as:

K = log2 V

It is important to note that with this technique, embedding can only

be performed in a top-to-bottom left-to-right orientation. Only the four

top-left adjacent pixels are considered in the evaluation because the

embedding function has already passed through these pixels. The other

four pixels on the bottom-right are still to undergo the embedding process,

which means their values may still change.

Lee and Chen also noted a distinct characteristic of the human

visual system (HVS) that is crucial to capacity evaluation. They stated that

for the human eye, “the greater the gray-scale is, the more change of the

gray-scale could be tolerated” [LEE2000]. Simply put, this means that the

closer a pixel is to the color white, the more tolerant it is to modifications.

Considering this, an upper boundary for the capacity of a pixel can be set

based on its intensity. Lee and Chen gives the following condition:

if P > 191 then U = 5, else U = 4

A threshold of 5 is set for U because the more significant bits of

the pixels must not be allowed to change so that the upper boundary may

still be calculated accurately in the decoding process. The succeeding

Page 43: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 4-13

topic will explain why the constants 191, 5, and 4 were chosen for the

condition for U.

Although not mentioned in Lee and Chen’s paper, such a technique

is, in theory, also applicable for true-color images. One possible

interpretation of the original algorithm is to use the capacity evaluation

function independently for each of the three color channels of a pixel.

Instead of evaluating grayscale values, the intensity of each color

component of a pixel may be considered. This approach will be

experimented in this study.

4.8 Minimum-Error Replacement

In order to minimize the changes made to a pixel as a result of

embedding, minimum-error replacement (MER) will also be incorporated

in the proposed stegosystem. The idea behind MER is to adjust the bit that

is immediately succeeding the modified LSB’s of a particular color value

in such a way that the change caused by the embedding operation is

minimal.

For example, if a binary number 1000 (decimal number 8) is

changed to 1111 (decimal number 15) because its three LSB’s were

replaced with embedded data, the difference from the original number is 7.

This difference in the original value of a color component is called the

embedding error. By adjusting the fourth bit from a value of 1 to a value

of 0, the binary number now becomes 0111 (decimal number 7) and the

Page 44: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 4-14

embedding error is reduced to 1 while at the same time preserving the

value of the three embedded bits.

For every K number of LSB’s used for embedding in a particular

color value, the maximum embedding error for that color value is 2K–1, or

the maximum value for a set of K bits. Since MER adjusts the bit next to

the modified LSB’s, the embedding error is restricted to a maximum value

of 2(K–1) [LEE1999].

Going back to the calculation of the upper boundary in capacity

evaluation, the constants 191, 5, and 4 were chosen with consideration to

how MER works. A threshold of 5 was selected since embedding five bits

into an 8-bit value (a byte) using MER would mean that the sixth LSB

may also change. Since the only remaining bits that are protected from

modification are the two most significant bits (MSB), the value of a byte

when only these two bits are set to 1 is 192, i.e., 27 + 26. Whatever the

value of the six LSBs, the value of the byte will always be greater than

191 as long as both of the two MSBs are set to 1.

4.9 Error Diffusion

Since the capacity-evaluation technique presented by Lee and

Chen analyzes only the four top-left adjacent pixels, distortions in the

contour of certain areas or shapes in an image can still be made. For an

image to adapt to the changes in color caused by embedding, an error

diffusion technique must also be employed.

Page 45: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 4-15

Lee and Chen presented an error diffusion technique called

Improved Gray-Scale Compensation (IGSC), which makes up for the

embedding error in the grayscale value of a pixel by spreading that error

evenly across the adjacent pixels [LEE2000]. This is done by adding ¼ of

the embedding error to the intensity or grayscale value of each of the four

bottom-right adjacent pixels. These pixels are depicted in Figure 4-3 as

pixels E, F, G, and H.

In simpler terms, when a pixel’s intensity increases, the intensities

of the four adjacent pixels on its bottom-right sides are decreased. Lee and

Chen did not discuss exactly how such an operation helps in preventing

distortions in the image. Nevertheless, it is conceivable that when a pixel’s

intensity increases, the capacity evaluation function is likely to allocate

higher capacities for the succeeding pixels than what it would have

originally allocated if the intensity of the current pixel had not increased,

and vice versa. This is because an increase or decrease in the intensity of

the current pixel affects the capacity evaluation for the succeeding pixels

that have not been processed yet. IGSC therefore compensates for the

change by maintaining balance between the intensities of adjacent pixels.

Moreover, performing such correcting operations allow the image to

preserve the average color intensity of the image as well as possible

correlations in the image’s bit-planes.

Although IGSC was presented as a technique for grayscale images,

Lee and Chen stated that it was based on an error-diffusion technique used

Page 46: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 4-16

when converting true-color images to 8-bit color formats [LEE2000]. It

may therefore be assumed that the concept behind IGSC is applicable to

color images.

4.10 Pseudorandom Number Generators

According to Menezes et al., the “security of many cryptographic

systems depends upon the generation of unpredictable quantities”

[MENE1996]. In digital cryptography, this is particularly true in the sense

that every computer-based cryptosystem utilizes what is generally known

as a pseudorandom number generator (PRNG). A PRNG is a device or

algorithm that outputs a seemingly-random sequence of numbers based on

a given numerical value called the seed. Unlike real random number

generators (RNG), PRNGs are deterministic, which means a particular

seed will generate the exact same sequence of numbers every time it is

used.

Before the use of computer-based PRNGs in cryptography, data is

encrypted with a keystream as long as the unencrypted data in order to

eliminate any detectable patterns in encryption process. With PRNGs,

instead of requiring the user to remember an extremely long keystream,

encryption algorithms can use as a keystream the long sequence of

numerical values generated by a PRNG that is seeded by the numeric

equivalent of a given password or encryption key. This way, encryption

keys can be relatively short while still maintaining high security.

Page 47: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 4-17

The same concept for key security can be used in steganography.

PRNGs can be used in steganography in randomizing the pattern of

embedding. With PRNGs, data bits may be scattered pseudorandomly

across the cover-medium. This makes the embedded data extremely

difficult, if not impossible, to extract without knowledge of the seed used

by the PRNG. In such a setup, the seed of the PRNG can be the hash value

of a user-given stego key.

4.11 Hash Functions

Like PRNGs, hash functions “play a fundamental role in modern

cryptography” [MENE1996]. Hash functions transform input values of

varying length or range into a fixed-length bit stream. Unlike

cryptographic functions, these functions are not reversible. Once a value

has been hashed, information about its original value has already been

lost.

This unique feature of hash functions makes them ideal for

password verification operations. For example, if a password-protected

operating system stores a list of valid passwords within the system for

login verification, a potential attacker or hacker may eventually find a way

to access the contents of such a list and break into the system.

A solution to this problem is to store the hash values of the

passwords instead of the original values. During login, entered passwords

are verified by calculating their hash values and comparing them with the

Page 48: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 4-18

hash values stored in the system. This way, even if a hacker gains access

to the password list, the only way to know the actual passwords is to

calculate the hash value every possible character combination within the

maximum length for passwords and find the ones that matches the hash

values in the list. This would be an extremely exhaustive operation for the

attacker.

The same concept can be used in steganography. For password

verification, a hash value of the original password may be embedded in an

image along with the hidden data bits.

Page 49: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 5-1

5.0 DATA GATHERING PROCEDURES AND OUTPUTS

The software being developed in this study is not a company-based system

but rather a general-purpose security software for use in covert communications.

Because of this, data gathering for this study is focused on the modern researches

and developments in the field of information hiding, particularly in

steganography. No interviews or surveys on companies and company personnel

are conducted during the course of this study, as they are not necessary.

The primary information resource used in this study is the Internet. As it is

with most subjects, the Internet is evidently the best source for up-to-date and

detailed information regarding steganographic research. Several research papers,

technical reports, and journal articles gathered from the Internet provided the

technical information required for the designing and development of this study’s

proposed steganography software.

Most of the papers referenced during the course of this study were

acquired from the CiteSeer Scientific Literature Digital Library, a comprehensive

archive of scientific documents sponsored by the NEC Research Institute.

CiteSeer currently indexes over 500,000 research documents on the web and

allows copies of these documents to be downloaded in PostScript and PDF

formats.

Copies of the IBM Systems Journal downloaded from the IBM Research

website were also referenced in this study. The two issues of this journal

referenced in this study provided useful background information on data hiding

Page 50: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 5-2

techniques. News articles referenced in this paper were acquired from Wired

News, TechTV.com, and CNN.com.

Other Internet searches were done in AlltheWeb, a “public search engine

and technology showcase” from Fast Search & Transfer, Inc. [FAST2002].

Originally set up as a test site for new and experimental search features,

AlltheWeb grew into a fast and comprehensive search engine ideal for students

and researchers. At present, it “indexes over 2.1 billion web pages, 118 million

multimedia files, 132 million FTP files, two million MP3s, 15 million PDF files

and supports 49 languages”.

Page 51: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 6-1

6.0 DOCUMENTATION OF CURRENT SYSTEM

6.1 EyeMage IIE

EyeMage IIE (In Image Encryption) is a free steganography

software from Proporta Ltd. It supports data hiding in Windows bitmaps

only but allows data to be embedded in more significant bit planes, not

just on the LSBs.

The unique feature of EyeMage is the ability to create a custom

noise image in which a selected data file may be embedded. However, as

the name suggests, noise images are made up of random colors and form

no meaningful picture. Because of this, using noise images as cover

images would hardly qualify as valid steganography since the media is

obviously cryptic and does not provide a convincing illusion. Figure 6-1

shows a sample of such an image created by EyeMage.

Figure 6-1.

A Noise Image Created by EyeMage IIE

Page 52: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 6-2

According to the included documentation, EyeMage also features

built-in encryption and compression capabilities. It also uses a technique

called password mangling which processes the user-given password with a

hash function repeatedly several times before it is actually used in the

encoding process. The user interface of EyeMage is quite simple and is

relatively easy to use. Figure 6-2 shows a screenshot of EyeMage.

6.2 Invisible Secrets 2002

Invisible Secrets 2002 is a commercial steganography software

from NeoByte Solutions [NEOB2002]. Version 3.2 supports

steganography in five different file formats:

Figure 6-2.

Screenshot of EyeMage IIE

Page 53: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 6-3

• Windows Bitmap (.bmp)

• JPEG File Interchange Format (.jpg)

• Portable Network Graphics (.png)

• Wave sound files (.wav)

• HTML documents (.html)

For Windows bitmaps, Invisible Secrets uses standard LSB

encoding to avoid creating distortions on the stego image. In the case of

JPEG and PNG images, however, a technique referred to as comment

insertion is used. As the name suggests, the hidden data file is encoded as

comment data in the header of the image. Although this provides an

unlimited hiding space and does not make any changes to the image itself,

such a technique is highly insecure. Since the data bits are not embedded

as integral parts of the image, the hidden data is readily extractable by

potential attackers. Moreover, inserting large files would greatly increase

the size of the stego image and may attract suspicion since JPEG and PNG

images often have very small file sizes.

Invisible Secrets may be considered as a general-purpose

“information security suite” because it can also be used exclusively for file

encryption or file shredding. The included encryption algorithms are

Blowfish, Twofish, RC4, Cast128, GOST, Rijndael (AES), Diamond 2, and

Sapphire II.

Invisible Secrets features a wizard-style user interface that makes it

very easy to use as compared with other software. Figure 6-3 shows a

Page 54: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 6-4

screenshot of this user interface. It has been observed in this study that

such interface designs are very effective in enhancing the usability of

steganographic software.

Invisible Secrets is designed and tested to run under the Windows

95, Windows 98, Windows 2000, Windows ME, Windows NT, and

Windows XP operating systems.

The NeoByte Solutions website does not provide any information

regarding the minimum system requirements of Invisible Secrets 2002.

Figure 6-3.

Screenshot of Invisible Secrets 2002

Page 55: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 6-5

Nevertheless, it is has been tested to run reasonably fast even on slow

computers during the course of this study.

6.3 Steganos File Manager

The Steganos File Manager is a steganography program

distributed as a part of the Steganos Security Suite, which includes several

security features such as file shredding, file encryption, disk encryption,

and Internet tracks erasing [STEG2002].

Although one of the most popular steganography software on the

Internet, Steganos supports embedding on standard Windows bitmaps

only. The encryption algorithms included with Steganos is Rijndael and

Blowfish.

Figure 6-4.

Screenshot of Steganos File Manager

Page 56: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 6-6

The user interface of the Steganos File Manager is quite similar to

that of the WinZip file compression software and is not as easy to use as

other steganographic software. A screenshot of this user interface is shown

in Figure 6-4.

The minimum system requirements of Steganos listed on its Help

file are as follows:

• Pentium processor

• 32 MB RAM

• 9 MB hard drive space

• screen resolution of 640x480 pixels at 256 colors.

• mouse or other pointing devices (since it does not provide full

keyboard support)

6.4 The Third Eye

The Third Eye is a freeware steganography program developed by

Satya Kiran [KIRA2002]. Version 1.0 supports steganography in three

image formats:

• Windows Bitmap (.bmp)

• Graphics Interchange Format (.gif)

• PC Paintbrush Format (.pcx)

The Third Eye also uses standard LSB encoding like Steganos and

Invisible Secrets. The user’s manual defines the following minimum

system requirements:

Page 57: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 6-7

• Intel 80386 processor

• Windows operating system

• 1.5 MB free hard disk space.

The Third Eye features a Multiple Document Interface (MDI) that

is also quite easy to use since very few controls and menu options are on

the main window. Figure 6-5 shows a screenshot of this user interface.

Figure 6-5.

Screenshot of The Third Eye

Page 58: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 6-8

The Third Eye does not include any encryption or compression

capabilities. It does however include a feature for binary comparison

between the pixels of two images.

Page 59: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 7-1

7.0 REQUIREMENTS ANALYSIS SPECIFICATION

This study is focused on developing a steganography software that is

suitable in real-world application for covert communication or covert data

transmission. In view of the software’s intended function, certain points should be

considered in designing the software.

7.1 Performance

• The steganographic process should not create distortions or artifacts in

the image which may expose the existence of hidden data.

• The steganographic algorithm should support high capacities for

embedded data without sacrificing imperceptibility.

• The software should be streamlined and compact.

• The software should be reasonably fast.

• The software should incorporate file compression to further increase

hiding capacity.

7.2 Security

• The software should provide password protection.

• The steganographic algorithm should generate a randomized pattern

for embedding.

• The software should incorporate file encryption to further enhance

data protection.

Page 60: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 7-2

7.3 Usability

• The user interface should be intuitive or easy to learn.

• The user interface should be able to guide the user step-by-step

throughout each steganographic process.

• The user interface should provide full keyboard support.

• The user interface should be fairly easy-to-use with the mouse.

7.4 Functionality

• The software should provide a means for viewing the final appearance

of processed stego-image.

• The software should provide a means for opening the extracted data

file from within the software itself.

• The software should display a progress indicator during processing.

Page 61: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 8-1

8.0 SYSTEM DESIGN SPECIFICATION

8.1 Stegosystem Model

The framework of the proposed stegosystem is based on the

generic model presented by Birgit Pfitzmann [PFIT1996]. The block

diagram of this framework is depicted in Figure 8-1.

A complete steganographic transaction essentially consists of three

separate processes: encoding, transmission, and decoding. Encoding

consists of all the tasks performed in embedding hidden data in an image.

Transmission refers to the transfer of the stego image from a sender to a

recipient. Decoding involves the extraction of the hidden data from the

stego image.

Figure 8-1.

Framework of the Proposed Stegosystem

Stego Key Data File

Cover Image

Decoding Module

Encoding Module

Stego Image

Stego Key

Stego Image

Data File

Transmission Channel

Page 62: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 8-2

8.1.1 Encoding

The encoding module takes in exactly three inputs (data

file, cover image, and stego key) and produces a single image (the

stego image) as the output of the entire process. As with some

other steganography software, the proposed software incorporates

compression and encryption to further enhance an already secure

algorithm. Unlike others, however, the proposed software utilizes a

rather complex variation of LSB encoding. The Hierarchical

Input-Process-Output (HIPO) chart shown in Figure 8-2 illustrates

Encoding

1.0

Process

1.2

Input

1.1

Output

1.3

Compress Data File

1.2.1

Perform Embedding

1.2.3

Encrypt Data File

1.2.2

Data File

1.1.1 Stego Key

1.1.3 Cover Image

1.1.2

Stego Image

1.3.1

Capacity Evaluation

1.2.3.2

Encode Metadata

1.2.3.5

Error Diffusion

1.2.3.4

Randomize Embedding

1.2.3.1 MER

1.2.3.3

Figure 8-2.

Hierarchical Input-Process-Output (HIPO) Chart of the Encoding Module

Page 63: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 8-3

this multipart process.

Before the actual embedding of the data bits, the 128-bit

MD5 hash-value of the user-given stego key is used to seed a

PRNG. During embedding, the numbers generated by this PRNG

determine the color channels on which each set of data bits is to be

embedded. This, in effect, randomizes the otherwise sequential

pattern of embedding and therefore protects the hidden data from

unauthorized extraction even after an attacker gains knowledge of

the hidden data’s existence.

The same PRNG mentioned above is also used to assign the

pseudorandom address of a bit stream of metadata that is also

embedded within the image. This metadata bit stream is composed

of five segments of information arranged in the following order:

1. 20-byte string representing the SHA-1 hash value of the

user-given stego key.

2. 255-byte string representing the filename of the hidden

data file.

3. 8-byte value representing the modify date and time that

the hidden data file was created or last modified.

4. 4-byte integer representing the size of the data file in

terms of bytes.

5. 16-byte string representing the MD5 checksum of the

hidden data file.

Page 64: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 8-4

The SHA-1 hash value of the stego key is included in the

metadata in order to support password verification in the decoding

process. The MD5 checksum, on the other hand, is used for data

integrity verification.

The algorithms for capacity evaluation, minimum-error

replacement (MER), and error diffusion described in Chapter 4 are

incorporated in the embedding process to maximize hiding

capacity and minimize distortions in the image. However, since

true-color images have three color channels and each one is being

evaluated separately, one color component of a pixel may increase

while another decreases. In such cases, the increase in total

embedding error may result to visible distortions. To compensate

for this, the original formula for gray level variation is replaced

with a formula for color intensity variation based on the texture

formed by pairs of adjacent pixels on the top and left sides of the

pixel being evaluated. This new formula may be expressed in the

form:

V = round [(|C–A| + |A–B| +|B–C| +|C–D|) / 4]

Although not explicitly stated in their paper, it is

understandable that Lee and Chen’s capacity evaluation function

calculates a pixel’s hiding capacity based on the range of color

intensities of surrounding pixels. By considering only the

Page 65: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 8-5

difference between the maximum and minimum color intensities,

the actual texture of the area being evaluated is not put into

consideration. In contrast, the formula presented in this paper

calculates hiding capacity based on the texture of the top-left sides

of a pixel. As a result, the new capacity evaluation function now

provides a more sensitive and more accurate estimate of a pixel’s

tolerance to modifications.

8.1.2 Transmission

As this is digital steganography, the transmission channel

must also be digital in nature. This may be in the form of the

Internet, a local area network (LAN), a disk, and other digital

media. In the case of the Internet, the stego image can be posted on

a web page or sent as an email attachment. Steganographic

transactions have long been suspected to take place in Internet

bulletin boards and other public web sites. The advantage of using

such media is the fact that web pages have no specified recipients

unlike emails. This makes it virtually impossible to track down the

intended recipient of the hidden message.

It is important to note that the proposed software does not

cover this part of the steganographic transaction. Since the general

objective of steganography is to make communication or file

transfer seem innocuous, common or traditional tools for data

Page 66: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 8-6

transfer such as popular web browsers must be used to enhance

that innocuous effect. Using the same steganography software for

file transfer is quite impractical.

8.1.3 Decoding

After transmission, the stego image is now ready for

decoding at the receiving end. The decoding module uses the stego

image and the stego key for input and performs a reverse operation

of the encoding process. This reversed process is illustrated in

Figure 8-3.

Hierarchical Input-Process-Output (HIPO) Chart of the Decoding Module

Decoding

1.0

Process

1.2

Input

1.1

Output

1.3

Perform Extraction

1.2.1

Decompress Data File

1.2.3

Decrypt Data File

1.2.2

Data File

1.3.1 Stego Key

1.1.2 Stego Image

1.1.1

Capacity Evaluation

1.2.1.3

Extract Metadata

1.2.1.1

Verify Stego Key

1.2.1.2

Extract Data Bits

1.2.1.4.

Page 67: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 8-7

Figure 8-3.

At the beginning of extraction, the Metadata is extracted

first in order to determine the data file size and verify the stego key

entered by the recipient. Capacity evaluation is still required in

order to determine how many bits are embedded in each pixel.

MER and error diffusion, on the other hand, is no longer required

since they are only functions for minimizing distortions during

embedding. If the stego key entered is correct, the data file will

properly extracted as final output. It is important to note, however,

that the original cover image cannot be regenerated out of the stego

image. That original information was already lost during

embedding.

8.2 Stegosystem Pseudocode

The following are abstract codes for the major components of the

proposed stegosystem. All functions are written in a format patterned on

the Visual Basic programming language.

It is important to note that the following pseudocodes depict only

the essential logic and fundamental structure of the actual program code.

These pseudocodes do not include variable declarations, input validation,

bounds checking, error handling, and other auxiliary code.

Page 68: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 8-8

8.2.1 Capacity Evaluation Function

Function ComputeCapacity() Dif1 = Abs(PixelC – PixelA) Dif2 = Abs(PixelA – PixelB) Dif3 = Abs(PixelD – PixelC) Dif4 = Abs(PixelC – PixelD) V = Round((Dif1 + Dif2 + Dif3 + Dif4) / 4) K = Int(Log(V) / Log(2)) If PixelP > 191 Then U = 5 Else U = 4 End If If K < U Then Capacity = K Else Capacity = U End If End Function

8.2.2 Minimum-Error Replacement Function

Function PerformMER() BitMask = Not ((2 ^ (Capacity + 1)) - 1) Value1 = (PixelP And BitMask) Or Bits Error1 = Value1 - PixelP Value2 = Value1 Or (2 ^ Capacity) Error2 = Value2 - PixelP If Abs(Error1) < Abs(Error2) Then PixelP = Value1 EmbeddingError = Error1 Else PixelP = Value2 EmbeddingError = Error2 End If End Function

Page 69: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 8-9

8.2.3 Error Diffusion Function

Function DiffuseError() ErrorFraction = EmbeddingError / 4 PixelE = PixelE – ErrorFraction PixelF = PixelF – ErrorFraction PixelG = PixelG – ErrorFraction PixelH = PixelH – ErrorFraction End Function

8.2.4 Encoding Function

Function Encode() InitializePRNGWith(StegoKeyMD5Hash) MetadataAddress = GetRandomNumber CurrentAddress = 0 DataFileCounter = 0 Do Until AllPixelsEncoded If CurrentAddress = MetadataAddress Then GetBitsFrom(Metadata) Else If DataFileCounter < DataFileSize Then GetBitsFrom(DataFile) DataFileCounter = DataFileCounter + 1 Else GetRandomBits End If End If ComputeCapacity PerformMER DiffuseError SelectRandomAddress Loop End Function

Page 70: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 8-10

8.2.5 Metadata Decoding Function

Function DecodeMetadata() InitializePRNGWith(StegoKeyMD5Hash) MetadataAddress = GetRandomNumber CurrentAddress = 0 MetadataCounter = 0 Do While MetadataCounter < MetadataSize If CurrentAddress = MetadataAddress Then ComputeCapacity Extracted = PixelP And ((2 ^ Capacity) - 1) AppendToMetadata(Extracted) DataFileCounter = MetadataCounter + 1 SelectNextAddress End If Loop End Function

8.2.6 Data File Decoding Function

Function DecodeDataFile() InitializePRNGWith(StegoKeyMD5Hash) MetadataAddress = GetRandomNumber CurrentAddress = 0 DataFileCounter = 0 Do While DataFileCounter < DataFileSize If CurrentAddress <> MetadataAddress Then ComputeCapacity Extracted = PixelP And ((2 ^ Capacity) - 1) AppendToDataFile(Extracted)

Page 71: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 8-11

DataFileCounter = DataFileCounter + 1 SelectRandomAddress End If Loop End Function

8.3 Image Formats

The algorithm used by the proposed software requires cover

images and stego images to be in the true-color format, i.e., composed of

red, green, and blue color channels. This allows for a randomized pattern

of embedding in three separate color channels. In essence, the presented

algorithm is applicable to other multiple-channel formats, such as the

32-bit CMYK (cyan-magenta-yellow-black) image standard. Nevertheless,

this study remains focused on 24-bit formats since 32-bit formats are

rarely used and generate even larger file sizes.

Furthermore, the stego image must also be saved in a lossless

image format so as not to lose any of the embedded data bits. This

automatically eliminates the popular JPEG and GIF images from the list of

supported stego image formats.

The proposed software, however, supports the five comparatively

popular image formats listed below.

Page 72: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 8-12

• BMP (Windows Bitmap)

The standard uncompressed 24-bit image format for the

Microsoft Windows operating system. BMP files use an

extension name of “.bmp”.

• PNG (Portable Network Graphics)

An image format originally designed as a replacement for

GIF. It uses a variation of the LZ77 compression algorithm,

which makes it the most lightweight standard image format

that does not use lossy compression. PNGs use an extension

name of “.png”.

• PPM (Portable Pixelmap)

The 24-bit implementation of the PNM image standard

defined by Jef Poskanzer. PPM files are uncompressed and use

an extension name of “.ppm”.

• TARGA (Truevision Advanced Raster Graphics Adapter)

A widely-used bitmap format developed by Truevision

Incorporated. It supports alpha channels and typically uses RLE

compression. TARGA files use an extension name of “.tga”

• TIFF (Tagged Image File Format)

One of the most complex standard image formats.

Designed to support more than 70 types of tags, it is also

compatible with multiple image compression algorithms.

Without tags, TIFFs are quite smaller than Windows bitmaps.

TIFF files use and extension name of “.tiff” or “.tif”.

Using lossless image formats also increases the security of the

steganographic algorithm. Unlike algorithms that use JPEG and GIF, the

Page 73: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 8-13

presented algorithm is not format dependent and is applicable to all bitmap

formats that do not apply transformations on the image. This means that

the encoding process does not leave any distinct signature on the created

stego image.

JPEG images, for example, have a certain characteristic structure

because of the Discrete Cosine Transform (DCT) that they undergo.

Because of this lossy transformation, embedding on JPEG images can only

be performed after it has undergone DCT. Embedding therefore, distorts

the characteristic structure of the JPEG image. Fridrich and Goljan explain

that when a JPEG image is embedded with data, “the cover image will

become (with high probability) incompatible with the JPEG format”

[FRID2002]. It is obviously quite suspicious and peculiar for a JPEG

image to be incompatible with the JPEG format. Such irony may therefore

be used as a proof that embedding has taken place.

In contrast, images that do not undergo any lossy transformation

do not have distinct characteristic structures since every color pattern and

every bit arrangement is valid and possible. Therefore, any statistical

assumption on the expected characteristics of an image for use in

steganalysis does not always apply.

Page 74: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 9-1

9.0 SYSTEMS IMPLEMENTATION

With respect to the adaptive nature of the algorithms incorporated in the

presented steganography software, the software was named “Chameleon”, after

the species of reptiles that have the ability to adapt the color of their skin with

their surroundings. From hereon, the software developed in this study will

continually be referred to as Chameleon.

9.1 Programming Considerations, Issues and Tools

To achieve rapid and flexible development, Microsoft Visual Basic

6.0 was used in building Chameleon. Visual Basic’s graphical integrated

development environment (IDE) provides ways for easier development of

ergonomic user interfaces. This, in effect, allowed the programming task

to be more focused on the internal workings of the software and not on

development of a working graphical interface.

Being concerned with image steganography, the first requirement

in the development of Chameleon is a means for manipulating images.

Unfortunately, Visual Basic provides very little support for image

processing. Furthermore, Visual Basic is only capable of opening images

saved in the Windows bitmap, JPEG and GIF formats.

To overcome these obstacles, the open-source graphics library

FreeImage written by Floris van den Berg was used for opening and

saving images. FreeImage is freely downloadable and distributable as a

C++-compiled DLL (dynamic link library) file. To utilize the FreeImage

Page 75: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 9-2

library in Visual Basic, a special Visual Basic wrapper class was written

for Chameleon. This wrapper class also made use or several Windows API

functions since FreeImage loads images into memory as device

independent bitmaps (DIB). In order to manipulate the contents of a DIB,

it must be converted into a device-dependent bitmap (DDB) that is

formatted as an array of red, green, and blue color components of each

pixel.

The open-source ActiveX control EzCryptoAPI written by Antonio

Ramirez Cobos is also used in encrypting data files with the very fast RC4

stream cipher. EzCryptoAPI also provided the MD5 and SHA-1 hash

functions required by the steganographic modules of the software. To

support data compression, the ZlibTool control of Mark Nelson is also

used. ZlibTool is a freeware ActiveX control based on the open-source

ZLib compression library.

A file wiping (also known as “file shredding”) feature is also

included in Chameleon. Wiping a file means permanently destroying its

contents before deleting it. Normally, when a file is deleted, it is simply

removed from the disk’s file system but its contents are left intact. This

allows file recovery programs to “undelete” the file. For this reason,

Chameleon features a file wipe option to allow users to wipe confidential

files such as secret messages hidden with Chameleon. Wiping original

data files when they are not needed in the computer further increases the

security provided by steganography software.

Page 76: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 9-3

9.2 System Requirement Specification

Chameleon was designed, built, and tested on a slow Intel

Pentium-II-powered computer running Microsoft Windows ME. This

means that Chameleon will execute perfectly even on reasonably old

machines. However, since Chameleon does perform a rather exhaustive

analysis of the image during embedding, it is advisable to use faster

computers on images with very high resolutions.

Below is a listing of the estimated minimum computer setup for

Chameleon:

• 233 MHz processor

• 64 MB RAM

• A video card that supports 1024x768 True-Color display

• 14-inch color monitor

• Microsoft Windows operating system

Chameleon would perform reasonably fast enough in such a setup.

However, for faster embedding in extremely large images, faster

processors are required.

Concerning cover-images, it is advisable to use original photos

taken from digital cameras. Using private and original photos instead of

widely-available images posted on the Internet or stored in commercial

photo CDs prevents potential attackers from comparing the stego-images

to their original unprocessed copies.

Page 77: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 9-4

9.3 Testing Activities

To test the performance of the proposed software, the efficiency of

Chameleon in terms of hiding capacity was compared to those of the four

popular steganography software described in Chapter 6.

In preparation for the tests, 50 test data files containing

pseudorandomly-generated bits were created with program written in

Visual Basic. The sizes of the data files range from 10 kilobytes to 500

kilobytes, in 10-kilobyte intervals.

The seed value used for Visual Basic’s built-in PRNG is the

hexadecimal value F0F0F0F0 (decimal number 4,042,322,160). The bits

written on the data files were random enough in such a way that none of

the data files can be compressed by standard compression algorithms,

even at maximum setting. This, in effect, provided a more accurate

measurement of the efficiency of each software’s embedding algorithm

since Steganos File Manager and The Third Eye does not include a data

compression feature like the ones integrated with Chameleon, Invisible

Secrets and EyeMage.

The 15 cover images used in the tests were downloaded from

fredmiranda.com, the online gallery of digital photographer Fred Miranda.

Table 9-1 is a list of these digital photographs. The actual photos are

shown in Appendix D.

Page 78: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 9-5

Table 9-1. Cover Images Used in Performance Testing

Filename Dimensions Size of LSB Plane File Size

abandon.bmp 750x494 pixels 138,937.50 bytes 1,087 KB

antelope.bmp 367x550 pixels 75,693.75 bytes 594 KB

badwater.bmp 700x461 pixels 121,012.50 bytes 946 KB

death.bmp 466x700 pixels 122,325.00 bytes 958 KB

gardens.bmp 700x466 pixels 122,325.00 bytes 956 KB

kiss.bmp 368x550 pixels 75,900.00 bytes 594 KB

nap.bmp 550x368 pixels 75,900.00 bytes 594 KB

passing.bmp 550x368 pixels 75,900.00 bytes 594 KB

race.bmp 700x459 pixels 120,487.50 bytes 942 KB

rain.bmp 337x550 pixels 69,506.25 bytes 544 KB

ruins.bmp 700x529 pixels 138,862.50 bytes 1,085 KB

storm.bmp 495x750 pixels 139,218.75 bytes 1,090 KB

style.bmp 367x550 pixels 79,693.75 bytes 594 KB

subtle.bmp 550x367 pixels 75,693.75 bytes 593 KB

sunrise.bmp 750x506 pixels 142,312.50 bytes 1,113 KB

All tests were conducted on a desktop PC with the following

specifications:

• Intel Pentium II 233 MHz processor

• 64 MB RAM

• Trident 3D Image 9750 video adapter

• 17-inch color monitor

• Microsoft Windows Millennium Edition operating system

Page 79: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 9-6

The succeeding tables show the test results for each cover image

under Chameleon, EyeMage IIE, Invisible Secrets 2002, Steganos File

Manager, and The Third Eye.

Table 9-2. Test Results for Cover Image “abandon.bmp”

Software Processing Time

Reported Capacity

Largest File Hidden Errors

Chameleon 28.59 sec 227,810 bytes 220 KB -

EyeMage IIE 5.35 sec 366,733 bytes 350 KB severe distortions

Invisible Secrets 2002 4.01 sec 138,937 bytes 130 KB -

Steganos File Manager 4.82 sec - 130 KB -

The Third Eye 1.31 sec 111,228 bytes 100 KB -

Table 9-3. Test Results for Cover Image “antelope.bmp”

Software Processing Time

Reported Capacity

Largest File Hidden Errors

Chameleon 17.42 sec 123,054 bytes 120 KB -

EyeMage IIE 2.95 sec 198,304 bytes 190 KB -

Invisible Secrets 2002 2.46 sec 75,693 bytes 70 KB -

Steganos File Manager 2.82 sec - 70 KB -

The Third Eye 0.83 sec 60,699 bytes 50 KB -

Page 80: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 9-7

Table 9-4. Test Results for Cover Image “badwater.bmp”

Software Processing Time

Reported Capacity

Largest File Hidden Errors

Chameleon 31.53 sec 288,503 bytes 280 KB -

EyeMage IIE 5.37 sec 318,604 bytes 310 KB slight distortions

Invisible Secrets 2002 3.27 sec 121,012 bytes 110 KB -

Steganos File Manager 3.84 sec - 110 KB -

The Third Eye 1.03 sec 96,789 bytes 90 KB failed to extract data

Table 9-5. Test Results for Cover Image “death.bmp”

Software Processing Time

Reported Capacity

Largest File Hidden Errors

Chameleon 35.78 sec 366,935 bytes 350 KB -

EyeMage IIE 4.81 sec 322,570 bytes 310 KB -

Invisible Secrets 2002 3.41 sec 122,325 bytes 110 KB -

Steganos File Manager 2.83 sec - 110 KB -

The Third Eye 1.08 sec 97,979 bytes 90 KB failed to extract data

Table 9-6.

Test Results for Cover Image “gardens.bmp”

Software Processing Time

Reported Capacity

Largest File Hidden Errors

Chameleon 19.89 sec 94,789 bytes 90 KB -

EyeMage IIE 5.04 sec 322,104 bytes 310 KB severe distortions

Invisible Secrets 2002 3.49 sec 122,325 bytes 110 KB -

Steganos File Manager 3.10 sec - 110 KB -

The Third Eye 1.01 sec 97,839 bytes 90 KB -

Page 81: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 9-8

Table 9-7. Test Results for Cover Image “kiss.bmp”

Software Processing Time

Reported Capacity

Largest File Hidden Errors

Chameleon 16.34 sec 95,824 bytes 90 KB -

EyeMage IIE 2.96 sec 198,304 bytes 190 KB slight distortions

Invisible Secrets 2002 2.53 sec 75,900 bytes 70 KB -

Steganos File Manager 3.03 sec - 70 KB -

The Third Eye 0.83 sec 60,699 bytes 50 KB -

Table 9-8. Test Results for Cover Image “nap.bmp”

Software Processing Time

Reported Capacity

Largest File Hidden Errors

Chameleon 20.58 sec 208,810 bytes 200 KB -

EyeMage IIE 2.91 sec 198,549 bytes 190 KB slight distortions

Invisible Secrets 2002 2.59 sec 75,900 bytes 70 KB -

Steganos File Manager 3.15 sec - 70 KB -

The Third Eye 0.63 sec 60,773 bytes 50 KB -

Table 9-9.

Test Results for Cover Image “passing.bmp”

Software Processing Time

Reported Capacity

Largest File Hidden Errors

Chameleon 17.14 sec 143,050 bytes 130 KB -

EyeMage IIE 3.11 sec 198,549 bytes 190 KB slight distortions

Invisible Secrets 2002 2.79 sec 75,900 bytes 70 KB -

Steganos File Manager 2.98 sec - 70 KB -

The Third Eye 0.72 sec 60,773 bytes 50 KB -

Page 82: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 9-9

Table 9-10. Test Results for Cover Image “race.bmp”

Software Processing Time

Reported Capacity

Largest File Hidden Errors

Chameleon 31.71 sec 302,416 bytes 290 KB -

EyeMage IIE 4.29 sec 317,204 bytes 300 KB slight distortions

Invisible Secrets 2002 3.29 sec 120,487 bytes 110 KB -

Steganos File Manager 4.17 sec - 110 KB -

The Third Eye 1.07 sec 96,369 bytes 90 KB -

Table 9-11. Test Results for Cover Image “rain.bmp”

Software Processing Time

Reported Capacity

Largest File Hidden Errors

Chameleon 10.85 sec 60,671 bytes 50 KB -

EyeMage IIE 2.79 sec 181,437 bytes 170 KB severe distortions

Invisible Secrets 2002 2.13 sec 69,506 bytes 60 KB -

Steganos File Manager 2.81 sec - 60 KB -

The Third Eye 0.86 sec 55,639 bytes 50 KB -

Table 9-12.

Test Results for Cover Image “ruins.bmp”

Software Processing Time

Reported Capacity

Largest File Hidden Errors

Chameleon 34.06 sec 348,720 bytes 340 KB -

EyeMage IIE 6.21 sec 366,204 bytes 350 KB slight distortions

Invisible Secrets 2002 4.03 sec 138,862 bytes 130 KB -

Steganos File Manager 5.66 sec - 130 KB -

The Third Eye 1.16 sec 111,069 bytes 100 KB failed to extract data

Page 83: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 9-10

Table 9-13. Test Results for Cover Image “storm.bmp”

Software Processing Time

Reported Capacity

Largest File Hidden Errors

Chameleon 18.02 sec 110,852 bytes 100 KB -

EyeMage IIE 5.90 sec 367,904 bytes 350 KB highly severe distortions

Invisible Secrets 2002 4.06 sec 139,218 bytes 130 KB -

Steganos File Manager 4.93 sec - 130 KB -

The Third Eye 1.65 sec 111,579 bytes 100 KB failed to extract data

Table 9-14. Test Results for Cover Image “style.bmp”

Software Processing Time

Reported Capacity

Largest File Hidden Errors

Chameleon 11.19 sec 75,534 bytes 70 KB -

EyeMage IIE 3.07 sec 198,304 bytes 190 KB highly severe distortions

Invisible Secrets 2002 2.52 sec 79,693 bytes 70 KB -

Steganos File Manager 3.03 sec - 70 KB -

The Third Eye 0.71 sec 60,699 bytes 50 KB -

Table 9-15.

Test Results for Cover Image “subtle.bmp”

Software Processing Time

Reported Capacity

Largest File Hidden Errors

Chameleon 15.06 sec 108,221 bytes 100 KB -

EyeMage IIE 3.10 sec 197,998 bytes 190 KB slight distortions

Invisible Secrets 2002 2.59 sec 75,693 bytes 70 KB -

Steganos File Manager 2.96 sec - 70 KB -

The Third Eye 0.79 sec 60,608 bytes 50 KB -

Page 84: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 9-11

Table 9-16. Test Results for Cover Image “sunrise.bmp”

Software Processing Time

Reported Capacity

Largest File Hidden Errors

Chameleon 12.64 sec 35,328 bytes 30 KB -

EyeMage IIE 5.46 sec 375,741 bytes 360 KB highly severe distortions

Invisible Secrets 2002 4.12 sec 142,312 bytes 130 KB -

Steganos File Manager 3.98 sec - 130 KB -

The Third Eye 1.34 sec 113,931 bytes 100 KB -

In all of the encoding tests, the password used was “test”. After

each encoding operation on an image, the created stego image was then

viewed to check for distortions or any visible differences from the cover

image. Finally, extraction is performed to verify that the data file has been

properly embedded and that no corruption of the data file occurred.

During extraction tests, four cases of extraction failures were

recorded on The Third Eye. In these four cases, The Third Eye displayed

error messages stating that no data is hidden within the stego images. The

messages were, of course, incorrect. This leads to the conclusion that

regardless of the fact that The Third Eye performed the fastest in all tests,

it is simply unreliable. No other software resulted in extraction failures.

Except for the tests on “death.bmp” and “nap.bmp”, EyeMage used

the largest hiding capacity for all cover images. However, as the results

show, EyeMage produced significant distortions on almost all images. In

three cases, the distortions were even highly severe.

Page 85: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 9-12

With Chameleon, on the other hand, absolutely no distortions were

created on all images, even in images where it used the largest hiding

capacities. This proves that using more bits for embedding requires careful

analysis of the image. Invisible Secrets and Steganos File Manager also

did not produce any visible distortions on the images since both software

used only the first LSB plane of each image for embedding.

All results show that Chameleon is highly reliable in allocating the

maximum possible size of hiding space without making any visible

changes to an image.

9.4 Installation Process

The Chameleon Image Steganography installation package is very

compact and easy to install. The installation package was created with

Setup Factory 6.0 and is a single 3.41 MB self-extracting setup file. The

user interface of the setup program created by Setup Factory is very easy

to use.

Except for the Visual Basic runtime files, there are only seven

program files required by Chameleon, as listed below.

• Chameleon.exe (Chameleon main program file)

• FreeImage.dll (FreeImage Graphics Library)

• ZlibTool.ocx (ZlibTool ActiveX Control)

• EzCryptoApi.ocx (EZCryptoAPI ActiveX Control)

Page 86: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 9-13

• MSCOMCTL.OCX (Windows Common Controls ActiveX

Control)

• COMDLG32.OCX (Common Dialog ActiveX Control)

• HHCTRL.OCX (Microsoft Help ActiveX Control)

Chameleon does not require any specialized training for a user to

be able to operate it. It features a very intuitive wizard-style user interface

that guides the user step-by-step along each steganographic task.

Command buttons in the interface are accentuated with descriptive 3D

icons to help the user easily understand the function of each button.

Moreover, a context-sensitive help system provides quick assistance for

first-time users by displaying the appropriate help topic at the press of the

“F1” key or the “More Help” button.

A separate program named Chameleon Decoder was also

constructed. The program is a smaller and more streamlined version of the

original software that can only perform decoding operations.

Page 87: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 10-1

10.0 CONCLUSION AND JUSTIFICATION

In the course of this study, all the major problems of current

steganography software listed in Chapter 1 have been solved. These problems and

their corresponding solutions are described below.

• Inefficient use of hiding space.

To make optimum use of hiding space, a special capacity

evaluation function was incorporated in the steganographic algorithm.

The capacity evaluation function used analyzes the capacity of each

pixel based on the texture formed by the varying color intensities of its

surrounding pixels.

• Tendency to produce distortions in the image.

To minimize distortions, techniques for minimum-error

replacement (MER) and error diffusion were incorporated in the

encoding process. Changes in color values are minimized and error

values are spread across surrounding pixels to compensate for such

changes.

• Insecure hiding schemes.

Pseudorandom number generators and hash functions were used to

embed the data in an unfixed non-sequential pattern based on the

user-given stego-key. Moreover, the data bits are embedded on the

image pixels themselves to make them integrated with the image.

Other improvements included in the developed steganographic software

include file encryption, file compression, file wiping, password verification, data

integrity verification, and support for five standard bitmap formats.

Page 88: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 10-2

All these incorporated solutions and improvements make the developed

software more suitable for real-world covert communications and covert data

transmission than currently available steganographic software in the market.

Page 89: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 11-1

11.0 RECOMMENDATION

The steganographic techniques presented in this study were found to be

very effective in making imperceptible modifications to images even at high

bit-rates. Nevertheless, these techniques are susceptible to image modifications

and are therefore inapplicable to other fields of information hiding such as digital

watermarking. Modifying the techniques into a robust algorithm for watermarking

applications would be a great challenge for other researchers.

In such a shift of applications, researchers may consider working on other

techniques such as those presented by Yeuan-Kuen Lee and Ling-Hwei Chen in

their paper “Object-Based Image Steganography Using Affine Transformation”

[LEE2002]. In this paper, the authors focused their work on the robustness of the

hidden data and worked on a data hiding technique based on transformations

applied to specific objects in an image.

On the subject of undetectability, further research on the concept of

Gaussian noise may prove to be beneficial for future steganographic systems. In

the embedding process, for example, steganographic systems may exploit the fact

that Gaussian noise is considered to be a natural occurrence in certain cameras

[FRID2002].

Regarding Chameleon, it is recommended that it be used for

communications purposes only, since Chameleon is designed only for such

applications. The software would certainly not surpass the performance of

commercially-available watermarking software.

Page 90: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps 11-2

As it is with all image steganography software, the recommended

cover-images or carriers are original photos taken from digital cameras. Also the

ideal mode of transmission is through web postings on public bulletin boards.

This generally prevents the recipient from being traced by potential attackers

monitoring the channel of communications. Nevertheless, sending stego-images

as seemingly-innocuous email attachments is still relatively secure.

Page 91: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps A-1

A. INFORMATION HIDING TERMINOLOGY

This paper conforms to the standard information hiding terminology that

was agreed upon in the First International Workshop on Information Hiding

[PFIT1996]. The author defines these terms as follows:

cover medium Also referred to as host or carrier, it is the input medium of the embedding

process that will host the embedded data. In image steganography, this

medium is called the cover-image.

embedded data The input data hidden within the cover-medium.

embedding The process of hiding data within a cover-medium. It may also be referred to

as encoding.

extraction The process of retrieving the embedded data from a stego-medium. It may

also be referred to as decoding.

steganalysis A deliberate and systematic attempt to detect the existence of hidden data in a

cover-medium through statistical or computer-based examinations. Broadly, it

is an attempt to defeat a stegosystem.

stego medium The output medium of the embedding process that hosts the embedded data.

In image steganography, this medium is called the stego-image.

Page 92: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps A-2

stego key The security key used in the embedding process, which is required in order to

successfully extract the embedded data from the stego-medium. It is the

equivalent of an encryption key in cryptography.

stegosystem A complete design for the implementation of steganography, which defines

all the stages involved in the steganographic process as well as their

underlying concepts and techniques.

Page 93: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps B-1

B. MATHEMATICAL NOTATIONS

This paper made use of certain mathematical notations in presenting

formulas and algebraic expressions. These notations are defined as follows:

| x |

The absolute value of x.

x

The highest integer less than or equal to x.

xy

The power of x raised to the exponent y.

logb x

The logarithm of x to the base b.

max {x, y, z}

The highest number between x, y, and z.

min {x, y, z}

The lowest number between x, y, and z.

round (x)

The value of x rounded to the nearest integer.

Page 94: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps C-1

C. PROJECT SCHEDULE AND WORK ASSIGNMENT

Activities Jun Jul Aug Sep Oct Nov Dec Jan

Analysis

Requirements Analysis

Design

Algorithm Design

Interface Design

Coding

Prototype

Main Program

Help System

Testing

Error Testing

Performance Testing

Enhancement

Speed Optimization

Interface Enhancement

Page 95: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps D-1

D. COVER IMAGES USED IN PERFORMANCE TESTING

Figure D-1. abandon.bmp

“Abandoned”

Copyright © 2002 Fred Miranda

Page 96: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps D-2

Figure D-2. antelope.bmp

“Antelope”

Copyright © 2002 Fred Miranda

Page 97: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps D-3

Figure D-3. badwater.bmp

“Badwater”

Copyright © 2002 Fred Miranda

Page 98: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps D-4

Figure D-4. death.bmp

“Death Valley”

Copyright © 2002 Fred Miranda

Page 99: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps D-5

Figure D-5. gardens.bmp

“Descanso Gardens”

Copyright © 2002 Fred Miranda

Page 100: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps D-6

Figure D-6. kiss.bmp

“French Kiss”

Copyright © 2002 Fred Miranda

Page 101: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps D-7

Figure D-7. nap.bmp

“Nap”

Copyright © 2002 Fred Miranda

Page 102: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps D-8

Figure D-8. passing.bmp

“Passing By”

Copyright © 2002 Fred Miranda

Page 103: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps D-9

Figure D-9. race.bmp

“Racetrack”

Copyright © 2002 Fred Miranda

Page 104: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps D-10

Figure D-10. rain.bmp

“Rain”

Copyright © 2002 Fred Miranda

Page 105: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps D-11

Figure D-11. ruins.bmp

“Old Ruins”

Copyright © 2002 Fred Miranda

Page 106: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps D-12

Figure D-12. storm.bmp

“After the Storm”

Copyright © 2002 Fred Miranda

Page 107: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps D-13

Figure D-13. style.bmp

“Style”

Copyright © 2002 Fred Miranda

Page 108: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps D-14

Figure D-14. subtle.bmp

“Subtle Light”

Copyright © 2002 Fred Miranda

Page 109: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps D-15

Figure D-15. sunrise.bmp

“Desert Sunrise”

Copyright © 2002 Fred Miranda

Page 110: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps E-1

E. STEGO IMAGES WITH SEVERE DISTORTIONS

Figure E-1. e_abandon_data350k.bmp

Stego Image of “abandon.bmp” containing a 350 KB Data File embedded

by EyeMage IIE

Page 111: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps E-2

Figure E-2. e_gardens_data310k.bmp

Stego Image of “gardens.bmp” containing a 310 KB Data File embedded

by EyeMage IIE

Page 112: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps E-3

Figure E-3. e_rain_data170k.bmp

Stego Image of “rain.bmp” containing a 170 KB Data File embedded by

EyeMage IIE

Page 113: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps E-4

Figure E-4. e_storm_data350k.bmp

Stego Image of “storm.bmp” containing a 350 KB Data File embedded by

EyeMage IIE

Page 114: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps E-5

Figure E-5. e_style_data190k.bmp

Stego Image of “style.bmp” containing a 190 KB Data File embedded by

EyeMage IIE

Page 115: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps E-6

Figure E-6. e_sunrise_data360k.bmp

Stego Image of “sunrise.bmp” containing a 360 KB Data File embedded

by EyeMage IIE

Page 116: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps F-1

F. CHAMELEON HELP FILE

About Steganography Steganography refers to the art and science of hiding the existence of information. The idea behind steganography is to hide information within coventional objects in order to allow covert transmission of messages and other forms of information. Classical examples of this include invisible inks and microdots, which were extensively used by spies in hiding secret messages within conventional letters and newspapers during World War II. The advantage of steganography over standard cryptography is that encryption only hides the meaning of information whereas steganography hides the existence of the information itself. Obviously, information that cannot be seen is better protected than information that cannot be understood. In computer-based steganography, one of the most suitable forms of media are digital images. Digital images are constantly being uploaded, downloaded, shared, and transmitted over the Internet and through other digital channels of communications. This characteristic of digital images makes them appropriate hosts for steganography. A digital picture can be used as a cover image or "carrier" by embedding the data bits of a file or message across the pixels of the picture. Accordingly, the resulting image wherein secret information is embedded is called a stego image. Information hiding in images is usually performed by replacing the least-significant-bit (LSB) of each of the three color components (red, green, blue) of a pixel with data bits. The idea behind this is that the human eye is not capable of distinguishing very minimal changes in color, such as those created by replacing the LSBs of an image. However, since only the very least significant bits are used, only a small capacity for hidden information is available. In some images, using more bits in the color values of pixels still doesn't cause visible changes and thus hiding capacity can be increased. Some images, on the other hand, are visibly degraded or even distorted if more bits are changed. In order to obtain optimum hiding capacities, a more space-efficient technique must be used.

About Chameleon

Chameleon is an image steganography software for true-color (24-bit) digital images.

It was developed by Mark David Gan as part of his Computer Science Thesis at the Systems Technology Institute for the school year of 2002-2003.

Page 117: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps F-2

Features Chameleon provides a more space-efficient solution to image steganography by using adaptive steganographic algorithms that analyze the optimum capacity of an image for hidden data. These algorithms are sensitive to the texture of every area in an image, thereby preventing Chameleon from degrading or distorting whatever image is used. Chameleon is also a highly-secure steganography software. It includes a password verification feature and uses the user-given password to randomize the data hiding sequence. Without the correct password, access to the hidden data is impossible even if an attacker has detailed knowledge of the steganographic algorithms used by Chameleon. Chameleon also features integrated encryption and compression algorithms to further enhance security and performance. Furthermore, a file wipe feature (also known as "file shredding") is also included to allow users to permanently destroy files that contain secret information. Secret message files extracted from stego images, for example, may be wiped off the disk after the contents have been read by the recipient.

Supported File Formats Chameleon can hide any type of file within an image and allows processed stego images to be converted into any true-color image format that do not use lossy compression or undergo image transformations. Chameleon can save images in five standard image formats:

• Windows Bitmap (*.bmp) • Portable Network Graphics (*.png) • Tagged Image File Format (*.tif) • TARGA (*.tga) • Portable Pixelmap (*.ppm)

In addition to these formats, Chameleon can also open images stored in the following formats:

• JPEG (*.jpg) • Kodak PhotoCD (*.pcd) • PC Paintbrush (*.pcx) • Adobe Photoshop (*.psd)

Main Window At start-up, Chameleon displays the Main Window which offers the user four basic options:

Page 118: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps F-3

• Hide

(shortcut key: Alt+H) Starts up a hiding task and opens the first page of the Hide Wizard.

• Extract (shortcut key: Alt+E) Starts up an extraction task and opens the first page of the Extract Wizard.

• Wipe (shortcut key: Alt+W) Wipes a file selected by the user from the Wipe Dialog.

• Help (shortcut key: F1) Opens up this help file.

Hide Wizard The Hide Wizard is designed to help the user perform hiding tasks quickly and easily. It guides the user step-by-step throughout the entire operation and features a context-sensitive help system that provides useful information for first-time users.

The four pages comprising this wizard is discussed below.

Page 1: Select Data File In this page, the user is asked to specify the data file to be hidden within an image. Only existing files may be specified in this page.

Page 119: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps F-4

Only existing files may be specified in this page.

Whenever asked to specify a file, the user may either type the complete address of a file in the File Path box or press the Open button (shown below) to select a file from a dialog window.

Before continuing to the next page, the selected file may first be previewed by clicking the Preview button (shown below). In previewing the file, Chameleon opens the file in the application program associated to it. Text files, for example, would normally be opened in "Notepad".

Page 2: Select Cover Image In this page, the user is asked to specify the image to use as cover for the data file. A copy of the selected image file will contain the actual hidden data and not the original image file itself, thus the original cover image will remain the same. Only existing image files may be specified in this page.

Page 120: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps F-5

The Preview button in this page displays the selected image in the center of a blank screen. Chameleon generates image previews by itself and no external programs are used.

Page 3: Enter Password In this page, the user is asked to specify the password to use for restricting access to the hidden data file. Without the correct password, extraction of the hidden data file would be impossible since the password defines the random pattern of encoding used in the hiding task.

To ensure that the desired password is specified correctly, the user is asked to re-enter the same password in the Password Confirmation box.

Page 121: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps F-6

enter the same password in the Password Confirmation box.

Page 4: Encode Stego Image In the last page, the user is provided with a summary of the selected input files to allow the user to verify that the selected files are correct before initiating the actual encoding. Pressing the Next button then signals the encoding process to start.

During encoding, a progress bar is displayed to indicate how much of the stego image has already been processed.

After encoding, a dialog window is displayed to ask the user for the filename and image format to use in saving the processed stego image.

Page 122: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps F-7

image format to use in saving the processed stego image.

Finally, a report of the encoding results is displayed. From here, the user may preview a comparison of the original cover image and the processed stego image by pressing the Preview button.

The user may also save the stego image multiple times in different filenames and image formats by pressing the Save button (shown below) which opens up again the previously-discussed dialog window.

Page 123: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps F-8

Pressing the Close button closes the wizard and opens up the Main Window.

Extract Wizard The Extract Wizard is designed to help the user perform extraction tasks quickly and easily. It guides the user step-by-step throughout the entire operation and features a context-sensitive help system that provides useful information for first-time users. The three pages comprising this wizard is discussed below.

Page 1: Select Stego Image In this page, the user is asked to specify the stego image from which to extract a hidden data file. Only existing image files may be specified in this page.

Whenever asked to specify a file, the user may either type the complete address of a file in the File Path box or press the Open button (shown below) to select a file from a dialog window.

Before continuing to the next page, the selected image may first be previewed by clicking the Preview button (shown below). In previewing the image, Chameleon displays the selected image in the center of a blank screen. Chameleon generates image previews by itself and no external programs are used.

Page 124: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps F-9

Page 2: Enter Password In this page, the user is asked to specify the password to use for extracting the hidden data file.

Pressing the Next button initiates password verification. The wizard will continually ask for the password until the correct one is given or when the Cancel button is pressed.

Page 125: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps F-10

It is important to note that there is no way of identifying a real stego image. If the image selected in the previous page does not contain a data file hidden with Chameleon, password verification will continually fail. In such cases, it is even possible for password verification to succeed but only meaningless data will be extracted since no data file is actually hidden inside the image.

Page 3: Decode Data File In the last page, the user is provided with information about the hidden data file to allow the user to verify that the correct stego image has been selected. Pressing the Next button then signals the decoding process to start.

During decoding, a progress bar is displayed to indicate how much of the data file has already been processed.

Page 126: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps F-11

After decoding, a dialog window is displayed to ask the user for the filename to use in saving the extracted data file.

Finally, a report of the decoding results is displayed. From here, the user may preview the extracted data file by pressing the Preview button. In previewing the file, Chameleon opens the file in the application program associated to it. Text files, for example, would normally be opened in "Notepad". For this reason, previewing is only possibly after the data file has been saved by the user.

Page 127: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps F-12

The user may also save the data file multiple times in different filenames by pressing the Save button (shown below) which opens up again the previously-discussed dialog window.

Pressing the Close button closes the wizard and opens up the Main Window.

Wipe Dialog

The Wipe Dialog asks the user to select a file to be wiped off the disk.

Wiping a file means permanently destroying the contents of a file and then deleting it from the disk. This prevents a file from ever being recovered from the disk after deletion. Such a feature is particularly useful in cases wherein a file containing secret information needs to be permanently removed from the computer without leaving any trace of its existence.

To wipe a file, Chameleon begins by renaming the file so as not to leave any trace of what the file contains. Next, Chameleon overwrites the file with a bit pattern of alternating 0's and 1's. Then, the file is overwritten again but this time with a bit pattern of alternating 1's and 0's. Finally, the file is overwritten with 0's and then deleted from the disk.

Page 128: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps F-13

Security Tips Chameleon is essentially designed to make it easy for the user to perform steganographic tasks without having to worry about a lot of things. Nevertheless, there are still certain steps that a user can take to further improve security and reliability:

• Use actual photos with complex textures instead of simple computer-generated images. Complex or highly-detailed images have higher hiding capacities than those with basic or solid textures.

• Use original photos taken from digital cameras and avoid scanned images. Scanned images are usually of low quality and may already appear degraded.

• Use unique passwords and avoid using dates or other personal information.

• After hiding a data file in an image, wipe the original cover image to prevent attackers from comparing the original cover image with the created stego image.

• After hiding a data file in an image, wipe the original data file from the computer to prevent unauthorized users from accessing its contents.

• After reading an extracted data file from an image, wipe the extracted data file from the computer to prevent unauthorized users from accessing its contents.

Page 129: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps G-1

G. CHAMELEON SOURCE CODE

'------------------------------------------------------------------------------' ' ' ' Chameleon Image Steganography v1.2 ' ' ' ' Cover Image Selection Form ' ' [frmCoverImage] ' ' ' '------------------------------------------------------------------------------' ' ' ' Copyright (C) 2003 Mark David Gan ' ' ' '------------------------------------------------------------------------------' Option Explicit '------------------------------------------------------------------------------' ' Public Procedures ' '------------------------------------------------------------------------------' Public Sub ResetControls() lblFileSize(1).Caption = vbNullString lblFileDate(1).Caption = vbNullString txtPath.Text = vbNullString End Sub '------------------------------------------------------------------------------' ' Event Handlers ' '------------------------------------------------------------------------------' Private Sub btnBack_Click() frmDataFile.Show frmDataFile.SetFocus End Sub Private Sub btnBrowse_Click() If Len(txtPath.Text) > 0 Then dlgBrowse.InitDir = txtPath.Text If FileExists(txtPath.Text) Then dlgBrowse.FileName = txtPath.Text End If On Error Resume Next dlgBrowse.ShowOpen If Err.Number = 0 Then txtPath.Text = dlgBrowse.FileName Call txtPath_LostFocus End If txtPath.SetFocus End Sub Private Sub btnCancel_Click() frmMainMenu.Show frmMainMenu.SetFocus End Sub Private Sub btnHelp_Click() DisplayHelpFile "hide_wizard.html#Page2" End Sub Private Sub btnNext_Click() On Error Resume Next Me.ValidateControls If ActiveControl Is btnNext Then frmPassword1.Show frmPassword1.SetFocus End If End Sub Private Sub btnView_Click() On Error Resume Next Me.ValidateControls If ActiveControl Is btnView Then If Not frmView.DisplayByFilename(, txtPath.Text) Then MsgBox "The specified file cannot be opened as an image." & vbCrLf & _ "Please select a valid image file.", vbExclamation End If End If End Sub Private Sub Form_Activate() On Error Resume Next txtPath.SetFocus End Sub Private Sub Form_Deactivate() If Screen.ActiveForm.MDIChild Then Me.Hide End Sub Private Sub Form_Load() Set imgPageIcon(1).Picture = imgPageIcon(0).Picture SetMargins txtPath, 1 dlgBrowse.Filter = "(All supported image formats)|" & _ "*.bmp;*.png;*.tif;*.tiff;*.tga;*.ppm;" & _ "*.jpg;*.jpeg;*.pcx;*.psd;*.ras|" & _ "Adobe Photoshop (*.psd)|*.psd|" & _ "JPEG File Interchange Format (*.jpg)" & _ "|*.jpg;*.jpeg|" & _ "PC Paintbrush (*.pcx)|*.pcx|" & _ "Portable Network Graphics (*.png)|*.png|" & _ "Portable Pixelmap (*.ppm)|*.ppm|" & _ "Tagged Image File Format (*.tif)|*.tif;*.tiff|" & _ "TARGA Bitmap (*.tga)|*.tga|" & _ "Sun Rasterfile (*.ras)|*.ras|" & _ "Windows Bitmap (*.bmp)|*.bmp|" dlgBrowse.FilterIndex = 1 dlgBrowse.Flags = cdlOFNHideReadOnly + cdlOFNLongNames + _ cdlOFNPathMustExist + cdlOFNFileMustExist dlgBrowse.InitDir = GetPrimaryDrive

End Sub Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer) If Shift = vbCtrlMask Then Select Case KeyCode Case vbKeyO: btnBrowse.Press Case vbKeyP: btnView.Press End Select ElseIf KeyCode = vbKeyF1 Then btnHelp.Press End If End Sub Private Sub txtPath_Change() If Screen.ActiveControl Is txtPath Then lblFileSize(1).Caption = vbNullString lblFileDate(1).Caption = vbNullString End If End Sub Private Sub txtPath_GotFocus() With txtPath If .Tag <> "MouseDown" Then .SelStart = 0 .SelLength = Len(.Text) End If End With End Sub Private Sub txtPath_KeyDown(KeyCode As Integer, Shift As Integer) If KeyCode = vbKeyReturn Then btnNext.SetFocus End Sub Private Sub txtPath_LostFocus() txtPath.Text = GetAbsolutePath(Trim$(txtPath.Text)) lblFileSize(1).Caption = GetFileSize(txtPath.Text) lblFileDate(1).Caption = GetFileDateTime(txtPath.Text) End Sub Private Sub txtPath_MouseDown(Button As Integer, Shift As Integer, _ X As Single, Y As Single) txtPath.Tag = "MouseDown" End Sub Private Sub txtPath_MouseUp(Button As Integer, Shift As Integer, _ X As Single, Y As Single) txtPath.Tag = "" End Sub Private Sub txtPath_Validate(Cancel As Boolean) If Len(txtPath.Text) = 0 Then MsgBox "No file has been specified." & vbCrLf & _ "Please specify an existing file.", vbExclamation Cancel = True ElseIf Not FileExists(txtPath.Text) Then MsgBox "The specified file cannot be found." & vbCrLf & _ "Please specify an existing file.", vbExclamation Cancel = True End If End Sub '------------------------------------------------------------------------------' ' ' ' Chameleon Image Steganography v1.2 ' ' ' ' Data File Selection Form ' ' [frmDataFile] ' ' ' '------------------------------------------------------------------------------' ' ' ' Copyright (C) 2003 Mark David Gan ' ' ' '------------------------------------------------------------------------------' Option Explicit '------------------------------------------------------------------------------' ' Public Procedures ' '------------------------------------------------------------------------------' Public Sub ResetControls() lblFileSize(1).Caption = vbNullString lblFileDate(1).Caption = vbNullString txtPath.Text = vbNullString End Sub '------------------------------------------------------------------------------' ' Event Handlers ' '------------------------------------------------------------------------------' Private Sub btnBack_Click() frmMainMenu.Show frmMainMenu.SetFocus End Sub Private Sub btnBrowse_Click() If Len(txtPath.Text) > 0 Then dlgBrowse.InitDir = txtPath.Text If FileExists(txtPath.Text) Then dlgBrowse.FileName = txtPath.Text

Page 130: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps G-2

End If On Error Resume Next dlgBrowse.ShowOpen If Err.Number = 0 Then txtPath.Text = dlgBrowse.FileName Call txtPath_LostFocus End If txtPath.SetFocus End Sub Private Sub btnCancel_Click() frmMainMenu.Show frmMainMenu.SetFocus End Sub Private Sub btnHelp_Click() DisplayHelpFile "hide_wizard.html" End Sub Private Sub btnNext_Click() On Error Resume Next Me.ValidateControls If ActiveControl Is btnNext Then frmCoverImage.Show frmCoverImage.SetFocus End If End Sub Private Sub btnView_Click() On Error Resume Next Me.ValidateControls If ActiveControl Is btnView Then OpenFile txtPath.Text End Sub Private Sub Form_Activate() On Error Resume Next txtPath.SetFocus End Sub Private Sub Form_Deactivate() If Screen.ActiveForm.MDIChild Then Me.Hide End Sub Private Sub Form_Load() Set imgPageIcon(1).Picture = imgPageIcon(0).Picture SetMargins txtPath, 1 dlgBrowse.Filter = "(All files)|*.*|" dlgBrowse.FilterIndex = 1 dlgBrowse.Flags = cdlOFNHideReadOnly + cdlOFNLongNames + _ cdlOFNPathMustExist + cdlOFNFileMustExist dlgBrowse.InitDir = GetPrimaryDrive End Sub Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer) If Shift = vbCtrlMask Then Select Case KeyCode Case vbKeyO: btnBrowse.Press Case vbKeyP: btnView.Press End Select ElseIf KeyCode = vbKeyF1 Then btnHelp.Press End If End Sub Private Sub txtPath_Change() If Screen.ActiveControl Is txtPath Then lblFileSize(1).Caption = vbNullString lblFileDate(1).Caption = vbNullString End If End Sub Private Sub txtPath_GotFocus() With txtPath If .Tag <> "MouseDown" Then .SelStart = 0 .SelLength = Len(.Text) End If End With End Sub Private Sub txtPath_KeyDown(KeyCode As Integer, Shift As Integer) If KeyCode = vbKeyReturn Then btnNext.SetFocus End Sub Private Sub txtPath_LostFocus() txtPath.Text = GetAbsolutePath(Trim$(txtPath.Text)) lblFileSize(1).Caption = GetFileSize(txtPath.Text) lblFileDate(1).Caption = GetFileDateTime(txtPath.Text) End Sub Private Sub txtPath_MouseDown(Button As Integer, Shift As Integer, _ X As Single, Y As Single) txtPath.Tag = "MouseDown" End Sub Private Sub txtPath_MouseUp(Button As Integer, Shift As Integer, _ X As Single, Y As Single) txtPath.Tag = "" End Sub Private Sub txtPath_Validate(Cancel As Boolean) If Len(txtPath.Text) = 0 Then MsgBox "No file has been specified." & vbCrLf & _

"Please specify an existing file.", vbExclamation Cancel = True ElseIf Not FileExists(txtPath.Text) Then MsgBox "The specified file cannot be found." & vbCrLf & _ "Please specify an existing file.", vbExclamation Cancel = True End If End Sub '------------------------------------------------------------------------------' ' ' ' Chameleon Image Steganography v1.2 ' ' ' ' Decoding Process Form ' ' [frmDecode] ' ' ' '------------------------------------------------------------------------------' ' ' ' Copyright (C) 2003 Mark David Gan ' ' ' '------------------------------------------------------------------------------' Option Explicit '------------------------------------------------------------------------------' ' Private Variables ' '------------------------------------------------------------------------------' '[ user-selected input file ]' Private m_StegoImagePath As String '[ temporary files ]' Private m_TemporaryFilePath As String Private m_TemporaryDataFilePath As String '[ user-selected output file ]' Private m_DataFilePath As String '[ user password ]' Private m_Password As String Private m_PasswordHashMD5 As String '[ cancel process flag ]' Private m_Cancel As Boolean '------------------------------------------------------------------------------' ' Private Procedures ' '------------------------------------------------------------------------------' Private Function PerformDecompression() As Boolean lblStatus(0).Caption = "Decompressing data file..." lblStatus(1).Caption = vbNullString prgStatus.Value = 0 On Error GoTo ZlibError With frmMainMenu.ZlibDecompressor .Level = Standard .InputFile = m_TemporaryFilePath .OutputFile = m_TemporaryDataFilePath .Decompress End With ZlibError: If UCase(frmMainMenu.ZlibDecompressor.Status) = "SUCCESS" Then PerformDecompression = True Else PerformDecompression = False End If End Function Private Sub PerformDecryption() lblStatus(0).Caption = "Decrypting data file..." lblStatus(1).Caption = vbNullString prgStatus.Value = 0 '--------------------------------------------------------------------------' ' ' ' Special Note: ' ' For some reason, the last hash function executed by EzCryptoApi ' ' affects the succeeding encryption/decryption operation. Because of ' ' this, it must be made sure that last hash function called before ' ' an decryption operation is the same as the last hash function called ' ' before its corresponding encryption operation. ' ' ' '--------------------------------------------------------------------------' GetHashValue m_Password, SHA On Error Resume Next With frmMainMenu.EzCrypto .EncryptionAlgorithm = RC4 .Speed = [1KB] .Password = m_Password .DecryptFile m_TemporaryFilePath End With End Sub Private Function PerformExtraction() As Boolean lblStatus(0).Caption = "Extracting data file..." lblStatus(1).Caption = vbNullString prgStatus.Value = 0 With frmMainMenu.StegoDecoder If .Decode(m_PasswordHashMD5) Then .SaveDataFile m_TemporaryFilePath PerformExtraction = True Else PerformExtraction = False End If End With End Function '------------------------------------------------------------------------------' ' Event Handlers ' '------------------------------------------------------------------------------' Private Sub btnBack_Click()

Page 131: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps G-3

frmPassword2.Show frmPassword2.SetFocus End Sub Private Sub btnCancel_Click() If Not btnNext.Visible Then If MsgBox("Do you wish to cancel the current task?", _ vbQuestion + vbYesNo) = vbYes Then m_Cancel = True frmMainMenu.ZlibDecompressor.Abort frmMainMenu.StegoDecoder.Abort frmMainMenu.Show frmMainMenu.SetFocus End If Else frmMainMenu.Show frmMainMenu.SetFocus End If End Sub Private Sub btnClose_Click() If fraSave.Visible Then If Len(m_DataFilePath) = 0 Then If MsgBox("Would you like to save the extracted data file first?", _ vbQuestion + vbYesNo) = vbYes Then btnSave.Press End If End If End If frmMainMenu.Show frmMainMenu.SetFocus End Sub Private Sub btnHelp_Click() DisplayHelpFile "extract_wizard.html#Page3" End Sub Private Sub btnNext_Click() Dim Extracted As Boolean Dim Msg As String m_Cancel = False fraStatus.Visible = True btnNext.Visible = False btnBack.Visible = False btnCancel.SetFocus lblHelp(0).Visible = False lblHelp(1).Visible = True '[ prepare timer ]' Dim Tmr As RealTimer Set Tmr = New RealTimer Extracted = PerformExtraction '[ perform tasks ]' If Extracted Then If m_Cancel Then Exit Sub '[ verify checksum ]' If frmMainMenu.StegoDecoder.DataFileChecksum = _ GetHashValueOfFile(m_TemporaryFilePath, MD5) Then Msg = vbNullString Else Msg = "The extracted data has an invalid checksum and is " & _ "possibly corrupted." & vbCrLf & _ "Do you still want to continue the decoding operation?" If MsgBox(Msg, vbQuestion + vbYesNo) = vbNo Then Extracted = False GoTo PostProcessing End If End If PerformDecryption If m_Cancel Then Exit Sub PerformDecompression If m_Cancel Then Exit Sub End If PostProcessing: '[ display elapsed time ]' Tmr.Mark lblStatus(1).Caption = "Processing Time: " & Tmr.ElapsedTimeInMinutes prgStatus.Value = prgStatus.Max fraProperties(1).Visible = True fraProperties(0).Visible = False fraHelp.Visible = False btnCancel.Visible = False btnClose.Visible = True btnClose.Refresh If m_Cancel Then Exit Sub If Extracted Then '[ indicate completion ]' lblStatus(0).Caption = "Decoding Complete." lblDataFileSize(1).Caption = FormatSize(FileLen(m_TemporaryDataFilePath)) fraSave.Visible = True fraView.Visible = True btnSave.Press Else '[ indicate failure ]' lblStatus(0).Caption = "Decoding Failed." lblDataFileName2(1).Caption = vbNullString lblDataFileSize(1).Caption = vbNullString If Msg = vbNullString Then MsgBox "The selected image does not contain valid hidden data." & _ vbCrLf & "Decoding cannot be completed.", vbExclamation Else MsgBox "The selected image is possibly corrupted." & _ vbCrLf & "Decoding has been canceled.", vbExclamation End If

End If btnClose.SetFocus End Sub Private Sub btnSave_Click() On Error Resume Next dlgBrowse.ShowSave If Err.Number = 0 Then m_DataFilePath = dlgBrowse.FileName FileCopy m_TemporaryDataFilePath, m_DataFilePath SetFileDate m_DataFilePath, frmMainMenu.StegoDecoder.DataFileDate btnView.SetFocus End If End Sub Private Sub btnView_Click() If Len(m_DataFilePath) = 0 Then MsgBox "The extracted data file has not been saved yet." & vbCrLf & _ "Please save the data file first.", _ vbExclamation btnSave.SetFocus Else OpenFile m_DataFilePath End If End Sub Private Sub Form_Activate() m_Cancel = False m_StegoImagePath = frmStegoImage.txtPath.Text m_TemporaryFilePath = GenerateTempFile m_TemporaryDataFilePath = GenerateTempFile m_DataFilePath = vbNullString lblDataFileName1(1).Caption = frmMainMenu.StegoDecoder.DataFileName lblDataFileName2(1).Caption = lblDataFileName1(1).Caption lblDataFileDate(1).Caption = FormatDate(frmMainMenu.StegoDecoder.DataFileDate) CompactCaptionWithEllipses lblDataFileName1(1) CompactCaptionWithEllipses lblDataFileName2(1) m_Password = frmPassword2.txtPassword.Text m_PasswordHashMD5 = GetHashValue(m_Password, MD5) dlgBrowse.FileName = frmMainMenu.StegoDecoder.DataFileName If Not ActiveControl Is btnNext Then btnNext.SetFocus End Sub Private Sub Form_Deactivate() If Screen.ActiveForm.MDIChild Then Me.Hide '[ reset controls ]' fraStatus.Visible = False fraProperties(0).Visible = True fraProperties(1).Visible = False fraHelp.Visible = True fraSave.Visible = False fraView.Visible = False lblStatus(0).Caption = lblStatus(0).Tag lblStatus(1).Caption = vbNullString lblDataFileName1(1).Caption = vbNullString lblDataFileName2(1).Caption = vbNullString lblDataFileDate(1).Caption = vbNullString lblDataFileSize(1).Caption = vbNullString lblHelp(0).Visible = True lblHelp(1).Visible = False prgStatus.Min = 0 prgStatus.Max = 100 prgStatus.Value = 0 btnNext.Visible = True btnBack.Visible = True btnCancel.Visible = True btnClose.Visible = False '[ cleanup temporary files ]' WipeFile m_TemporaryFilePath, False WipeFile m_TemporaryDataFilePath, False End If End Sub Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer) If Shift = vbCtrlMask Then Select Case KeyCode Case vbKeyS: btnSave.Press Case vbKeyP: btnView.Press End Select ElseIf KeyCode = vbKeyF1 Then btnHelp.Press End If End Sub Private Sub Form_Load() Set imgPageIcon(1).Picture = imgPageIcon(0).Picture dlgBrowse.Filter = "(All files)|*.*|" dlgBrowse.FilterIndex = 1 dlgBrowse.Flags = cdlOFNHideReadOnly + cdlOFNLongNames + _ cdlOFNPathMustExist + cdlOFNOverwritePrompt dlgBrowse.InitDir = GetPrimaryDrive End Sub Private Sub Form_Unload(Cancel As Integer) WipeFile m_TemporaryFilePath, False WipeFile m_TemporaryDataFilePath, False End Sub

Page 132: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps G-4

'------------------------------------------------------------------------------' ' ' ' Chameleon Image Steganography v1.2 ' ' ' ' Encoding Process Form ' ' [frmEncode] ' ' ' '------------------------------------------------------------------------------' ' ' ' Copyright (C) 2003 Mark David Gan ' ' ' '------------------------------------------------------------------------------' Option Explicit '------------------------------------------------------------------------------' ' Private Variables ' '------------------------------------------------------------------------------' '[ user-selected input files ]' Private m_CoverImagePath As String Private m_DataFilePath As String '[ temporary file ]' Private m_TemporaryFilePath As String '[ user-selected output file ]' Private m_StegoImagePath As String '[ user password ]' Private m_Password As String Private m_PasswordHashMD5 As String Private m_PasswordHashSHA As String '[ cancel process flag ]' Private m_Cancel As Boolean '------------------------------------------------------------------------------' ' Private Procedures ' '------------------------------------------------------------------------------' Private Function PerformCompression() As Boolean lblStatus(0).Caption = "Compressing data file..." lblStatus(1).Caption = vbNullString prgStatus.Value = 0 On Error GoTo ZlibError With frmMainMenu.ZlibCompressor .Level = Standard .InputFile = m_DataFilePath .OutputFile = m_TemporaryFilePath .Compress End With ZlibError: If UCase(frmMainMenu.ZlibCompressor.Status) = "SUCCESS" Then PerformCompression = True Else PerformCompression = False End If End Function Private Function PerformEmbedding() lblStatus(0).Caption = "Hiding data file..." lblStatus(1).Caption = vbNullString prgStatus.Value = 0 PerformEmbedding = False With frmMainMenu.StegoEncoder If .LoadDataFile(m_TemporaryFilePath, _ GetPathFileName(m_DataFilePath), _ FileDateTime(m_DataFilePath), _ GetHashValueOfFile(m_TemporaryFilePath, MD5)) Then If .LoadCoverImage(m_CoverImagePath) Then PerformEmbedding = .Encode(m_PasswordHashMD5, m_PasswordHashSHA) lblDataSize(1).Caption = FormatSize(.DataFileSize) lblCapacity(1).Caption = FormatSize(.ImageCapacity) Else m_Cancel = True MsgBox "The selected cover image cannot be loaded." & vbCrLf & _ "Please select a valid image file.", vbInformation frmCoverImage.Show frmCoverImage.SetFocus End If Else m_Cancel = True MsgBox "The selected data file cannot be loaded." & vbCrLf & _ "Please select a valid data file.", vbInformation frmDataFile.Show frmDataFile.SetFocus End If End With End Function Private Sub PerformEncryption() lblStatus(0).Caption = "Encrypting data file..." lblStatus(1).Caption = vbNullString prgStatus.Value = 0 '--------------------------------------------------------------------------' ' ' ' Special Note: ' ' For some reason, the last hash function executed by EzCryptoApi ' ' affects the succeeding encryption/decryption operation. Because of ' ' this, it must be made sure that last hash function called before ' ' a decryption operation is the same as the last hash function called ' ' before its corresponding encryption operation. ' ' ' '--------------------------------------------------------------------------' GetHashValue m_Password, SHA On Error Resume Next With frmMainMenu.EzCrypto .EncryptionAlgorithm = RC4 .Speed = [1KB] .Password = m_Password .EncryptFile m_TemporaryFilePath End With

End Sub '------------------------------------------------------------------------------' ' Event Handlers ' '------------------------------------------------------------------------------' Private Sub btnBack_Click() frmPassword1.Show frmPassword1.SetFocus End Sub Private Sub btnCancel_Click() If Not btnNext.Visible Then If MsgBox("Do you wish to cancel the current task?", _ vbQuestion + vbYesNo) = vbYes Then m_Cancel = True frmMainMenu.ZlibCompressor.Abort frmMainMenu.StegoEncoder.Abort frmMainMenu.Show frmMainMenu.SetFocus End If Else frmMainMenu.Show frmMainMenu.SetFocus End If End Sub Private Sub btnClose_Click() If fraSave.Visible Then If Len(m_StegoImagePath) = 0 Then If MsgBox("Would you like to save the created stego image first?", _ vbQuestion + vbYesNo) = vbYes Then btnSave.Press End If End If End If frmMainMenu.Show frmMainMenu.SetFocus End Sub Private Sub btnHelp_Click() DisplayHelpFile "hide_wizard.html#Page4" End Sub Private Sub btnNext_Click() Dim Completed As Boolean m_Cancel = False fraStatus.Visible = True btnNext.Visible = False btnBack.Visible = False lblHelp(0).Visible = False lblHelp(1).Visible = True '[ prepare timer ]' Dim Tmr As RealTimer Set Tmr = New RealTimer PerformCompression If m_Cancel Then Exit Sub PerformEncryption If m_Cancel Then Exit Sub Completed = PerformEmbedding If m_Cancel Then Exit Sub '[ display elapsed time ]' Tmr.Mark lblStatus(1).Caption = "Processing Time: " & Tmr.ElapsedTimeInMinutes fraProperties(1).Visible = True fraProperties(0).Visible = False fraHelp.Visible = False btnCancel.Visible = False btnClose.Visible = True btnClose.Refresh If Completed Then '[ indicate completion ]' lblStatus(0).Caption = "Encoding Complete." fraSave.Visible = True fraView.Visible = True btnSave.Press btnClose.SetFocus Else '[ indicate failure ]' lblStatus(0).Caption = "Encoding Failed." Dim Res As VbMsgBoxResult Res = MsgBox("There is not enough space on the selected image." & vbCrLf & _ "Would you like to select another cover image?", _ vbQuestion + vbYesNo) If Res = vbYes Then frmCoverImage.Show frmCoverImage.SetFocus Else MsgBox "Encoding Canceled.", vbExclamation btnClose.SetFocus End If End If End Sub Private Sub btnSave_Click() On Error Resume Next dlgBrowse.ShowSave If Err.Number = 0 Then '[ set stego image file format ]' Dim ImageFormat As FREE_IMAGE_FORMAT Select Case dlgBrowse.FilterIndex Case 1: ImageFormat = FIF_BMP Case 2: ImageFormat = FIF_PNG Case 3: ImageFormat = FIF_PPMRAW Case 4: ImageFormat = FIF_TIFF Case 5: ImageFormat = FIF_TARGA End Select

Page 133: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps G-5

'[ save stego image ]' m_StegoImagePath = dlgBrowse.FileName frmMainMenu.StegoEncoder.SaveStegoImage m_StegoImagePath, ImageFormat btnView.SetFocus End If End Sub Private Sub btnView_Click() With frmMainMenu.StegoEncoder If Not frmView.DisplayByDIB(.CoverImageDIB, .StegoImageDIB) Then MsgBox "The images cannot be displayed." & _ "The encoding process may have failed.", vbExclamation End If End With End Sub Private Sub Form_Activate() m_Cancel = False m_DataFilePath = frmDataFile.txtPath.Text m_CoverImagePath = frmCoverImage.txtPath.Text m_TemporaryFilePath = GenerateTempFile m_StegoImagePath = vbNullString lblDataFile(1).Caption = m_DataFilePath lblCoverImage(1).Caption = m_CoverImagePath CompactCaptionWithEllipses lblDataFile(1) CompactCaptionWithEllipses lblCoverImage(1) m_Password = frmPassword1.txtPassword(0).Text m_PasswordHashMD5 = GetHashValue(m_Password, MD5) m_PasswordHashSHA = GetHashValue(m_Password, SHA) If Not ActiveControl Is btnNext Then btnNext.SetFocus End Sub Private Sub Form_Deactivate() If Screen.ActiveForm.MDIChild Then Me.Hide '[ reset controls ]' fraStatus.Visible = False fraProperties(0).Visible = True fraProperties(1).Visible = False fraHelp.Visible = True fraSave.Visible = False fraView.Visible = False lblStatus(0).Caption = vbNullString lblStatus(1).Caption = vbNullString lblDataFile(1).Caption = vbNullString lblCoverImage(1).Caption = vbNullString lblDataSize(1).Caption = vbNullString lblCapacity(1).Caption = vbNullString lblHelp(0).Visible = True lblHelp(1).Visible = False prgStatus.Min = 0 prgStatus.Max = 100 prgStatus.Value = 0 btnNext.Visible = True btnBack.Visible = True btnCancel.Visible = True btnClose.Visible = False '[ cleanup temporary files ]' WipeFile m_TemporaryFilePath, False End If End Sub Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer) If Shift = vbCtrlMask Then Select Case KeyCode Case vbKeyS: btnSave.Press Case vbKeyP: btnView.Press End Select ElseIf KeyCode = vbKeyF1 Then btnHelp.Press End If End Sub Private Sub Form_Load() Set imgPageIcon(1).Picture = imgPageIcon(0).Picture dlgBrowse.Filter = "Windows Bitmap (*.bmp)|*.bmp|" & _ "Portable Network Graphics (*.png)|*.png|" & _ "Portable Pixelmap (*.ppm)|*.ppm|" & _ "Tagged Image File Format (*.tif)|*.tif;*.tiff|" & _ "TARGA Bitmap (*.tga)|*.tga|" dlgBrowse.FilterIndex = 1 dlgBrowse.Flags = cdlOFNHideReadOnly + cdlOFNLongNames + _ cdlOFNPathMustExist + cdlOFNOverwritePrompt dlgBrowse.InitDir = GetPrimaryDrive End Sub Private Sub Form_Unload(Cancel As Integer) WipeFile m_TemporaryFilePath, False End Sub '------------------------------------------------------------------------------' ' ' ' Chameleon Image Steganography v1.2 ' ' ' ' Main Menu Form ' ' [frmMainMenu] ' ' ' '------------------------------------------------------------------------------' ' ' ' Copyright (C) 2003 Mark David Gan '

' ' '------------------------------------------------------------------------------' Option Explicit '------------------------------------------------------------------------------' ' Windows API Function Declarations ' '------------------------------------------------------------------------------' Private Declare Function ReleaseCapture Lib "user32" () As Long Private Declare Function SetCapture Lib "user32" (ByVal hWnd As Long) As Long '------------------------------------------------------------------------------' ' Public Variables ' '------------------------------------------------------------------------------' '[ stegosystem objects ]' Public WithEvents StegoEncoder As StegosystemEncoder Public WithEvents StegoDecoder As StegosystemDecoder '------------------------------------------------------------------------------' ' Event Handlers ' '------------------------------------------------------------------------------' Private Sub btnExit_Click() Unload frmMDI End Sub Private Sub btnExtract_Click() CurrentTask = TASK_DECODE frmStegoImage.Show frmStegoImage.SetFocus End Sub Private Sub btnHelp_Click() DisplayHelpFile "index.html" End Sub Private Sub btnHide_Click() CurrentTask = TASK_ENCODE frmDataFile.Show frmDataFile.SetFocus End Sub Private Sub btnWipe_Click() Dim Msg As String On Error Resume Next dlgBrowse.ShowOpen Msg = "A file can no longer be recovered after being wiped." & vbCrLf & _ "Are you sure you wish to permanently remove the following file?" & _ vbCrLf & vbCrLf & _ dlgBrowse.FileName If Err.Number = 0 Then If MsgBox(Msg, vbQuestion + vbYesNo) = vbYes Then If WipeFile(dlgBrowse.FileName, True) Then MsgBox "The selected file has been successfully wiped." Else MsgBox "The selected file cannot be wiped." End If End If End If End Sub Private Sub EzCrypto_DecryptionFileStatus(ByVal lBytesProcessed As Long, _ ByVal lTotalBytes As Long) With frmDecode .prgStatus.Value = (lBytesProcessed * 100) \ lTotalBytes .lblStatus(1).Caption = .prgStatus.Value & "% complete" End With End Sub Private Sub EzCrypto_EncryptionFileStatus(ByVal lBytesProcessed As Long, _ ByVal lTotalBytes As Long) With frmEncode .prgStatus.Value = (lBytesProcessed * 100) \ lTotalBytes .lblStatus(1).Caption = .prgStatus.Value & "% complete" End With End Sub Private Sub Form_Activate() CurrentTask = TASK_NONE frmMDI.ResetChildFormControls End Sub Private Sub Form_Deactivate() If Screen.ActiveForm.MDIChild Then Me.Hide End Sub Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer) If KeyCode = vbKeyF1 Then btnHelp.Press End Sub Private Sub Form_Load() Set picHeader.Picture = imgTitle.Picture dlgBrowse.InitDir = GetPrimaryDrive dlgBrowse.Filter = "(All files)|*.*|" dlgBrowse.Flags = cdlOFNHideReadOnly + cdlOFNLongNames + _ cdlOFNPathMustExist + cdlOFNFileMustExist Set StegoEncoder = New StegosystemEncoder Set StegoDecoder = New StegosystemDecoder Me.Show End Sub Private Sub Form_Unload(Cancel As Integer) Set StegoEncoder = Nothing Set StegoDecoder = Nothing End Sub Private Sub picHeader_LostFocus()

Page 134: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps G-6

If picHeader.Picture <> imgTitle.Picture Then Set picHeader.Picture = imgTitle.Picture End If End Sub Private Sub picHeader_MouseDown(Button As Integer, Shift As Integer, _ X As Single, Y As Single) Set picHeader.Picture = imgAuthor.Picture End Sub Private Sub picHeader_MouseUp(Button As Integer, Shift As Integer, _ X As Single, Y As Single) If picHeader.Picture <> imgTitle.Picture Then Set picHeader.Picture = imgTitle.Picture End If End Sub Private Sub StegoDecoder_DataFileProgress(ByVal Processed As Long, _ ByVal Total As Long) With frmDecode .prgStatus.Value = (Processed * 100) \ Total .lblStatus(1).Caption = .prgStatus.Value & "% complete" End With End Sub Private Sub StegoDecoder_MetadataProgress(ByVal Processed As Long, _ ByVal Total As Long) With frmPassword2 .prgStatus.Value = (Processed * 100) \ Total .lblStatus(1).Caption = .prgStatus.Value & "% complete" End With End Sub Private Sub StegoEncoder_Progress(ByVal Processed As Long, ByVal Total As Long) With frmEncode .prgStatus.Value = (Processed * 100) \ Total .lblStatus(1).Caption = .prgStatus.Value & "% complete" End With End Sub Private Sub ZlibCompressor_Progress(ByVal percent_complete As Integer) With frmEncode .prgStatus.Value = percent_complete .lblStatus(1).Caption = percent_complete & "% complete" End With End Sub Private Sub ZlibDecompressor_Progress(ByVal percent_complete As Integer) With frmDecode .prgStatus.Value = percent_complete .lblStatus(1).Caption = percent_complete & "% complete" End With End Sub '------------------------------------------------------------------------------' ' ' ' Chameleon Image Steganography v1.2 ' ' ' ' Multiple Document Interface (MDI) Form ' ' [frmMDI] ' ' ' '------------------------------------------------------------------------------' ' ' ' Copyright (C) 2003 Mark David Gan ' ' ' '------------------------------------------------------------------------------' Option Explicit '------------------------------------------------------------------------------' ' Windows User Interface Constants ' '------------------------------------------------------------------------------' Private Const MF_BYCOMMAND = &H0& Private Const MF_BYPOSITION = &H400& Private Const SC_SIZE = &HF000& Private Const SC_MOVE = &HF010& Private Const SC_MINIMIZE = &HF020& Private Const SC_MAXIMIZE = &HF030& Private Const WS_CAPTION = &HC00000 Private Const WS_MAXIMIZEBOX = &H10000 Private Const WS_MINIMIZEBOX = &H20000 Private Const WS_SYSMENU = &H80000 Private Const WS_THICKFRAME = &H40000 Private Const GWL_STYLE = -16 '------------------------------------------------------------------------------' ' Windows User Interface Function Declarations ' '------------------------------------------------------------------------------' Private Declare Function GetSystemMenu _ Lib "user32" ( _ ByVal hWnd As Long, _ ByVal bRevert As Long _ ) As Long Private Declare Function RemoveMenu _ Lib "user32" ( _ ByVal hMenu As Long, _ ByVal nPosition As Long, _ ByVal wFlags As Long _ ) As Long Private Declare Function DrawMenuBar _ Lib "user32" ( _ ByVal hWnd As Long _ ) As Long Private Declare Function SetWindowLong _ Lib "user32" Alias "SetWindowLongA" ( _ ByVal hWnd As Long, _ ByVal nIndex As Long, _ ByVal dwNewLong As Long _ ) As Long Private Declare Function GetWindowLong _ Lib "user32" Alias "GetWindowLongA" ( _ ByVal hWnd As Long, _ ByVal nIndex As Long _

) As Long '------------------------------------------------------------------------------' ' Public Procedures ' '------------------------------------------------------------------------------' Public Sub FormatWindow() Dim Res As Long Dim Ctr As Long '[ remove maximize button from mdi form and disable resizing ]' Res = GetWindowLong(Me.hWnd, GWL_STYLE) SetWindowLong Me.hWnd, GWL_STYLE, Res And Not (WS_MAXIMIZEBOX + WS_THICKFRAME) '[ remove maximize menu item from system menu ]' Res = GetSystemMenu(Me.hWnd, 0) RemoveMenu Res, SC_MAXIMIZE, MF_BYCOMMAND DrawMenuBar Me.hWnd End Sub Public Sub ResetChildFormControls() On Error Resume Next Dim Frm As Form For Each Frm In VB.Forms If Frm.MDIChild Then Frm.ResetControls Next Frm End Sub '------------------------------------------------------------------------------' ' Event Handlers ' '------------------------------------------------------------------------------' Private Sub MDIForm_Load() '[ check for other instances of chameleon in memory ]' If App.PrevInstance Then MsgBox "Another instance of Chameleon is already open." & vbCrLf & _ "Only one instance of Chameleon may be opened.", vbCritical End End If FormatWindow Load frmView End Sub Private Sub MDIForm_QueryUnload(Cancel As Integer, UnloadMode As Integer) If (UnloadMode = vbAppTaskManager) Or (UnloadMode = vbFormControlMenu) Then If Not frmMDI.ActiveForm Is frmMainMenu Then If MsgBox("Do you wish to cancel the current task and exit Chameleon?", _ vbQuestion + vbYesNo) = vbNo Then Cancel = True Exit Sub End If End If End If Cancel = False '[ hide mdi form ]' frmMDI.WindowState = vbMinimized frmMDI.Hide CloseHelpFiles Unload frmView Unload frmMDI End Sub '------------------------------------------------------------------------------' ' ' ' Chameleon Image Steganography v1.2 ' ' ' ' Password Specification Form ' ' [frmPassword1] ' ' ' '------------------------------------------------------------------------------' ' ' ' Copyright (C) 2003 Mark David Gan ' ' ' '------------------------------------------------------------------------------' Option Explicit '------------------------------------------------------------------------------' ' Public Procedures ' '------------------------------------------------------------------------------' Public Sub ResetControls() txtPassword(0).Text = vbNullString txtPassword(1).Text = vbNullString End Sub '------------------------------------------------------------------------------' ' Event Handlers ' '------------------------------------------------------------------------------' Private Sub btnBack_Click() frmCoverImage.Show frmCoverImage.SetFocus End Sub Private Sub btnCancel_Click() frmMainMenu.Show frmMainMenu.SetFocus End Sub Private Sub btnHelp_Click() DisplayHelpFile "hide_wizard.html#Page3" End Sub Private Sub btnNext_Click() On Error Resume Next

Page 135: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps G-7

Me.ValidateControls If ActiveControl Is btnNext Then frmEncode.Show frmEncode.SetFocus End If End Sub Private Sub Form_Activate() On Error Resume Next txtPassword(0).SetFocus End Sub Private Sub Form_Deactivate() If Screen.ActiveForm.MDIChild Then Me.Hide End Sub Private Sub Form_Load() Set imgPageIcon(1).Picture = imgPageIcon(0).Picture SetMargins txtPassword(0), 1 SetMargins txtPassword(1), 1 End Sub Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer) If KeyCode = vbKeyF1 Then btnHelp.Press End Sub Private Sub txtPassword_GotFocus(Index As Integer) With txtPassword(Index) If .Tag <> "MouseDown" Then .SelStart = 0 .SelLength = Len(.Text) End If End With End Sub Private Sub txtPassword_KeyDown(Index As Integer, KeyCode As Integer, _ Shift As Integer) If KeyCode = vbKeyReturn Then Select Case Index Case 0: txtPassword(1).SetFocus Case 1: btnNext.SetFocus End Select End If End Sub Private Sub txtPassword_MouseDown(Index As Integer, Button As Integer, _ Shift As Integer, _ X As Single, Y As Single) txtPassword(Index).Tag = "MouseDown" End Sub Private Sub txtPassword_MouseUp(Index As Integer, Button As Integer, _ Shift As Integer, _ X As Single, Y As Single) txtPassword(Index).Tag = "" End Sub Private Sub txtPassword_Validate(Index As Integer, Cancel As Boolean) If Len(txtPassword(0).Text) = 0 Then MsgBox "No password has been specified." & vbCrLf & _ "Please specify a password.", vbExclamation Cancel = True ElseIf Len(txtPassword(1).Text) = 0 Then MsgBox "The password has not been confirmed." & vbCrLf & _ "Please confirm the password.", vbExclamation Cancel = True ElseIf txtPassword(0).Text <> txtPassword(1).Text Then MsgBox "The two passwords specified are different." & vbCrLf & _ "Please confirm the password carefully.", vbExclamation Cancel = True End If End Sub '------------------------------------------------------------------------------' ' ' ' Chameleon Image Steganography v1.2 ' ' ' ' Password Verification Form ' ' [frmPassword2] ' ' ' '------------------------------------------------------------------------------' ' ' ' Copyright (C) 2003 Mark David Gan ' ' ' '------------------------------------------------------------------------------' Option Explicit '------------------------------------------------------------------------------' ' Private Variables ' '------------------------------------------------------------------------------' '[ user-selected input file ]' Private m_StegoImagePath As String '[ cancel process flag ]' Private m_Cancel As Boolean '------------------------------------------------------------------------------' ' Public Procedures ' '------------------------------------------------------------------------------' Public Sub ResetControls() txtPassword.Text = vbNullString End Sub '------------------------------------------------------------------------------' ' Private Procedures ' '------------------------------------------------------------------------------'

Private Sub PerformVerification() Dim PasswordHashMD5 As String Dim PasswordHashSHA As String With frmMainMenu.StegoDecoder fraPage.Enabled = False If .LoadStegoImage(m_StegoImagePath) Then PasswordHashMD5 = GetHashValue(txtPassword.Text, MD5) PasswordHashSHA = GetHashValue(txtPassword.Text, SHA) lblStatus(0).Caption = "Verifying password..." fraStatus.Visible = True .DecodeMetadata PasswordHashMD5 lblStatus(0).Caption = vbNullString lblStatus(1).Caption = vbNullString If .StoredPassword = PasswordHashSHA Then If m_Cancel Then Exit Sub frmDecode.Show frmDecode.SetFocus Else If m_Cancel Then Exit Sub lblStatus(0).Caption = "Invalid Password." MsgBox "The specified password is invalid." & vbCrLf & _ "Please specify the correct password.", vbExclamation fraPage.Enabled = True txtPassword.SetFocus End If Else MsgBox "The selected image does not contain valid hidden data." & _ vbCrLf & "Please select a valid stego image.", vbExclamation frmStegoImage.Show frmStegoImage.SetFocus End If End With End Sub '------------------------------------------------------------------------------' ' Event Handlers ' '------------------------------------------------------------------------------' Private Sub btnBack_Click() frmStegoImage.Show frmStegoImage.SetFocus End Sub Private Sub btnCancel_Click() If Not btnNext.Visible Then If MsgBox("Do you wish to cancel the current task?", _ vbQuestion + vbYesNo) = vbYes Then m_Cancel = True frmMainMenu.StegoDecoder.Abort frmMainMenu.Show frmMainMenu.SetFocus End If Else frmMainMenu.Show frmMainMenu.SetFocus End If End Sub Private Sub btnHelp_Click() DisplayHelpFile "extract_wizard.html#Page2" End Sub Private Sub btnNext_Click() On Error Resume Next Me.ValidateControls If ActiveControl Is btnNext Then PerformVerification End Sub Private Sub Form_Activate() m_Cancel = False m_StegoImagePath = frmStegoImage.txtPath.Text On Error Resume Next txtPassword.SetFocus End Sub Private Sub Form_Deactivate() If Screen.ActiveForm.MDIChild Then Me.Hide '[ reset controls ]' fraPage.Enabled = True fraStatus.Visible = False lblStatus(0).Caption = vbNullString lblStatus(1).Caption = vbNullString prgStatus.Min = 0 prgStatus.Max = 100 prgStatus.Value = 0 End If End Sub Private Sub Form_Load() Set imgPageIcon(1).Picture = imgPageIcon(0).Picture SetMargins txtPassword, 1 End Sub Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer) If KeyCode = vbKeyF1 Then btnHelp.Press End Sub Private Sub txtPassword_GotFocus() With txtPassword

Page 136: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps G-8

If .Tag <> "MouseDown" Then .SelStart = 0 .SelLength = Len(.Text) End If End With End Sub Private Sub txtPassword_KeyDown(KeyCode As Integer, Shift As Integer) If KeyCode = vbKeyReturn Then btnNext.SetFocus End Sub Private Sub txtPassword_MouseDown(Button As Integer, Shift As Integer, _ X As Single, Y As Single) txtPassword.Tag = "MouseDown" End Sub Private Sub txtPassword_MouseUp(Button As Integer, Shift As Integer, _ X As Single, Y As Single) txtPassword.Tag = "" End Sub Private Sub txtPassword_Validate(Cancel As Boolean) If Len(txtPassword.Text) = 0 Then MsgBox "No password has been specified." & vbCrLf & _ "Please specify a password.", vbExclamation Cancel = True End If End Sub '------------------------------------------------------------------------------' ' ' ' Chameleon Image Steganography v1.2 ' ' ' ' Stego Image Selection Form ' ' [frmStegoImage] ' ' ' '------------------------------------------------------------------------------' ' ' ' Copyright (C) 2003 Mark David Gan ' ' ' '------------------------------------------------------------------------------' Option Explicit '------------------------------------------------------------------------------' ' Public Procedures ' '------------------------------------------------------------------------------' Public Sub ResetControls() lblFileSize(1).Caption = vbNullString lblFileDate(1).Caption = vbNullString txtPath.Text = vbNullString End Sub '------------------------------------------------------------------------------' ' Form Event Handlers ' '------------------------------------------------------------------------------' Private Sub btnBack_Click() frmMainMenu.Show frmMainMenu.SetFocus End Sub Private Sub btnBrowse_Click() If Len(txtPath.Text) > 0 Then dlgBrowse.InitDir = txtPath.Text If FileExists(txtPath.Text) Then dlgBrowse.FileName = txtPath.Text End If On Error Resume Next dlgBrowse.ShowOpen If Err.Number = 0 Then txtPath.Text = dlgBrowse.FileName Call txtPath_LostFocus End If txtPath.SetFocus End Sub Private Sub btnCancel_Click() frmMainMenu.Show frmMainMenu.SetFocus End Sub Private Sub btnHelp_Click() DisplayHelpFile "extract_wizard.html" End Sub Private Sub btnNext_Click() On Error Resume Next Me.ValidateControls If ActiveControl Is btnNext Then frmPassword2.Show frmPassword2.SetFocus End If End Sub Private Sub btnView_Click() On Error Resume Next Me.ValidateControls If ActiveControl Is btnView Then If Not frmView.DisplayByFilename(, txtPath.Text) Then MsgBox "The specified image cannot be loaded." & vbCrLf & _ "Please select a valid image.", vbExclamation End If End If End Sub

Private Sub Form_Activate() On Error Resume Next txtPath.SetFocus End Sub Private Sub Form_Deactivate() If Screen.ActiveForm.MDIChild Then Me.Hide End Sub Private Sub Form_Load() Set imgPageIcon(1).Picture = imgPageIcon(0).Picture SetMargins txtPath, 1 dlgBrowse.Filter = "(All supported image formats)|" & _ "*.bmp;*.png;*.tif;*.tiff;*.tga;*.ppm|" & _ "Windows Bitmap (*.bmp)|*.bmp|" & _ "Portable Network Graphics (*.png)|*.png|" & _ "Portable Pixelmap (*.ppm)|*.ppm|" & _ "Tagged Image File Format (*.tif)|*.tif;*.tiff|" & _ "TARGA Bitmap (*.tga)|*.tga|" dlgBrowse.FilterIndex = 1 dlgBrowse.Flags = cdlOFNHideReadOnly + cdlOFNLongNames + _ cdlOFNPathMustExist + cdlOFNFileMustExist dlgBrowse.InitDir = GetPrimaryDrive End Sub Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer) If Shift = vbCtrlMask Then Select Case KeyCode Case vbKeyO: btnBrowse.Press Case vbKeyP: btnView.Press End Select ElseIf KeyCode = vbKeyF1 Then btnHelp.Press End If End Sub Private Sub txtPath_Change() If Screen.ActiveControl Is txtPath Then lblFileSize(1).Caption = vbNullString lblFileDate(1).Caption = vbNullString End If End Sub Private Sub txtPath_GotFocus() With txtPath If .Tag <> "MouseDown" Then .SelStart = 0 .SelLength = Len(.Text) End If End With End Sub Private Sub txtPath_KeyDown(KeyCode As Integer, Shift As Integer) If KeyCode = vbKeyReturn Then btnNext.SetFocus End Sub Private Sub txtPath_LostFocus() txtPath.Text = GetAbsolutePath(Trim$(txtPath.Text)) lblFileSize(1).Caption = GetFileSize(txtPath.Text) lblFileDate(1).Caption = GetFileDateTime(txtPath.Text) End Sub Private Sub txtPath_MouseDown(Button As Integer, Shift As Integer, _ X As Single, Y As Single) txtPath.Tag = "MouseDown" End Sub Private Sub txtPath_MouseUp(Button As Integer, Shift As Integer, _ X As Single, Y As Single) txtPath.Tag = "" End Sub Private Sub txtPath_Validate(Cancel As Boolean) If Len(txtPath.Text) = 0 Then MsgBox "No file has been specified." & vbCrLf & _ "Please specify an existing file.", vbExclamation Cancel = True ElseIf Not FileExists(txtPath.Text) Then MsgBox "The specified file cannot be found." & vbCrLf & _ "Please specify an existing file.", vbExclamation Cancel = True End If End Sub '------------------------------------------------------------------------------' ' ' ' Chameleon Image Steganography v1.2 ' ' ' ' Image Preview Form ' ' [frmView] ' ' ' '------------------------------------------------------------------------------' ' ' ' Copyright (C) 2003 Mark David Gan ' ' ' '------------------------------------------------------------------------------' Option Explicit '------------------------------------------------------------------------------' ' Private Variables ' '------------------------------------------------------------------------------' '[ freeimage wrapper object ]' Private Imager As FreeImageWrapper

Page 137: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps G-9

'[ image dib handles ]' Private m_CoverImageDIB As Long Private m_StegoImageDIB As Long Private m_DIBsTemporary As Boolean '[ number of images to display ]' Private m_ImageCount As Long '[ mouse down coordinate ]' Private m_MouseX As Long Private m_MouseY As Long '[ size difference between image and container ]' Private m_DifX As Long Private m_DifY As Long '------------------------------------------------------------------------------' ' Public Procedures ' '------------------------------------------------------------------------------' Public Function DisplayByDIB( _ Optional ByVal CoverImage As Long = 0, _ Optional ByVal StegoImage As Long = 0 _ ) As Boolean DisplayByDIB = False m_ImageCount = 0 m_CoverImageDIB = CoverImage m_StegoImageDIB = StegoImage m_DIBsTemporary = False If PaintImage(picCoverImage(1)) Then m_ImageCount = m_ImageCount + 1 If PaintImage(picStegoImage(1)) Then m_ImageCount = m_ImageCount + 1 If m_ImageCount > 0 Then Call Form_Resize Me.Show DisplayByDIB = True End If End Function Public Function DisplayByFilename( _ Optional ByVal CoverImage As String = vbNullString, _ Optional ByVal StegoImage As String = vbNullString _ ) As Boolean DisplayByFilename = False m_ImageCount = 0 m_CoverImageDIB = Imager.LoadDIB(CoverImage) m_StegoImageDIB = Imager.LoadDIB(StegoImage) m_DIBsTemporary = True If PaintImage(picCoverImage(1)) Then m_ImageCount = m_ImageCount + 1 If PaintImage(picStegoImage(1)) Then m_ImageCount = m_ImageCount + 1 If m_ImageCount > 0 Then Call Form_Resize Me.Show DisplayByFilename = True End If End Function '------------------------------------------------------------------------------' ' Private Procedures ' '------------------------------------------------------------------------------' Private Function PaintImage(ByRef Picture1 As PictureBox) As Boolean Dim hDIB As Long Select Case Picture1.Name Case picCoverImage(1).Name: hDIB = m_CoverImageDIB Case picStegoImage(1).Name: hDIB = m_StegoImageDIB End Select If hDIB <> 0 Then Picture1.Width = Imager.GetWidth(hDIB) Picture1.Height = Imager.GetHeight(hDIB) If Imager.PaintDIB(hDIB, Picture1.hDC) Then PaintImage = True Select Case Picture1.Name Case picCoverImage(1).Name: picCoverImage(0).Visible = True Case picStegoImage(1).Name: picStegoImage(0).Visible = True End Select Else PaintImage = False End If End If End Function '------------------------------------------------------------------------------' ' Event Handlers ' '------------------------------------------------------------------------------' Private Sub Form_Deactivate() Me.Hide picCoverImage(0).Visible = False picStegoImage(0).Visible = False If m_DIBsTemporary Then On Error Resume Next Imager.UnloadDIB m_CoverImageDIB Imager.UnloadDIB m_StegoImageDIB End If End Sub Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer) Select Case KeyCode Case vbKeyRight: If picCoverImage(0).Visible Then Call picCoverImage_MouseDown(1, vbLeftButton, 0, 0, 0) Call picCoverImage_MouseMove(1, vbLeftButton, 0, -10, 0) Else Call picStegoImage_MouseDown(1, vbLeftButton, 0, 0, 0) Call picStegoImage_MouseMove(1, vbLeftButton, 0, -10, 0) End If Case vbKeyLeft:

If picCoverImage(0).Visible Then Call picCoverImage_MouseDown(1, vbLeftButton, 0, 0, 0) Call picCoverImage_MouseMove(1, vbLeftButton, 0, 10, 0) Else Call picStegoImage_MouseDown(1, vbLeftButton, 0, 0, 0) Call picStegoImage_MouseMove(1, vbLeftButton, 0, 10, 0) End If Case vbKeyDown: If picCoverImage(0).Visible Then Call picCoverImage_MouseDown(1, vbLeftButton, 0, 0, 0) Call picCoverImage_MouseMove(1, vbLeftButton, 0, 0, -10) Else Call picStegoImage_MouseDown(1, vbLeftButton, 0, 0, 0) Call picStegoImage_MouseMove(1, vbLeftButton, 0, 0, -10) End If Case vbKeyUp: If picCoverImage(0).Visible Then Call picCoverImage_MouseDown(1, vbLeftButton, 0, 0, 0) Call picCoverImage_MouseMove(1, vbLeftButton, 0, 0, 10) Else Call picStegoImage_MouseDown(1, vbLeftButton, 0, 0, 0) Call picStegoImage_MouseMove(1, vbLeftButton, 0, 0, 10) End If Case vbKeyEscape: Call mnuClose_Click Case 93: Call Form_MouseDown(vbRightButton, 0, 0, 0) End Select End Sub Private Sub Form_Load() Set Imager = New FreeImageWrapper End Sub Private Sub Form_MouseDown(Button As Integer, Shift As Integer, _ X As Single, Y As Single) If Button = vbRightButton Then PopupMenu mnuView End If End Sub Private Sub Form_Resize() Dim W As Long Dim H As Long Dim L As Long Dim T As Long Select Case m_ImageCount Case 1: W = Me.ScaleWidth H = Me.ScaleHeight If m_CoverImageDIB <> 0 Then m_DifX = W - picCoverImage(1).Width m_DifY = H - picCoverImage(1).Height picCoverImage(0).Move 0, 0 picCoverImage(0).Width = W picCoverImage(0).Height = H Else m_DifX = W - picStegoImage(1).Width m_DifY = H - picStegoImage(1).Height picStegoImage(0).Move 0, 0 picStegoImage(0).Width = W picStegoImage(0).Height = H End If Case 2: W = Me.ScaleWidth \ 2 H = Me.ScaleHeight m_DifX = W - picCoverImage(1).Width m_DifY = H - picCoverImage(1).Height picCoverImage(0).Move 0, 0 picCoverImage(0).Width = W - 1 picCoverImage(0).Height = H picStegoImage(0).Move W + 1, 0 picStegoImage(0).Width = W - 1 picStegoImage(0).Height = H End Select L = m_DifX \ 2 T = m_DifY \ 2 If m_CoverImageDIB <> 0 Then With picCoverImage(1) If L < 0 Then .Left = 0 .MousePointer = vbSizeAll Else .Left = L .MousePointer = vbDefault End If If T < 0 Then .top = 0 .MousePointer = vbSizeAll Else .top = T End If End With End If If m_StegoImageDIB <> 0 Then With picStegoImage(1) If L < 0 Then .Left = 0 .MousePointer = vbSizeAll Else .Left = L .MousePointer = vbDefault End If If T < 0 Then .top = 0 .MousePointer = vbSizeAll Else .top = T End If End With End If End Sub Private Sub Form_Unload(Cancel As Integer) Set Imager = Nothing End Sub Private Sub mnuClose_Click() Me.Hide

Page 138: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps G-10

End Sub Private Sub picCoverImage_MouseDown(Index As Integer, Button As Integer, _ Shift As Integer, X As Single, Y As Single) If Button = vbLeftButton Then m_MouseX = X m_MouseY = Y ElseIf Button = vbRightButton Then PopupMenu mnuView End If End Sub Private Sub picStegoImage_MouseDown(Index As Integer, Button As Integer, _ Shift As Integer, X As Single, Y As Single) If Button = vbLeftButton Then m_MouseX = X m_MouseY = Y ElseIf Button = vbRightButton Then PopupMenu mnuView End If End Sub Private Sub picCoverImage_MouseMove(Index As Integer, Button As Integer, _ Shift As Integer, X As Single, Y As Single) If (Index = 1) Then If (Button = vbLeftButton) Then Dim X2 As Long Dim Y2 As Long X2 = picCoverImage(1).Left Y2 = picCoverImage(1).top If (m_DifX < 0) Then X2 = X2 + (X - m_MouseX) If X2 > 0 Then X2 = 0 ElseIf X2 < m_DifX Then X2 = m_DifX End If End If If (m_DifY < 0) Then Y2 = Y2 + (Y - m_MouseY) If Y2 > 0 Then Y2 = 0 ElseIf Y2 < m_DifY Then Y2 = m_DifY End If End If If (X2 <> picCoverImage(1).Left) Or (Y2 <> picCoverImage(1).top) Then picCoverImage(1).Move X2, Y2 If picStegoImage(0).Visible Then picStegoImage(1).Move X2, Y2 Me.Refresh End If End If End If End Sub Private Sub picStegoImage_MouseMove(Index As Integer, Button As Integer, _ Shift As Integer, X As Single, Y As Single) If (Index = 1) Then If (Button = vbLeftButton) Then Dim X2 As Long Dim Y2 As Long X2 = picStegoImage(1).Left Y2 = picStegoImage(1).top If (m_DifX < 0) Then X2 = X2 + (X - m_MouseX) If X2 > 0 Then X2 = 0 ElseIf X2 < m_DifX Then X2 = m_DifX End If End If If (m_DifY < 0) Then Y2 = Y2 + (Y - m_MouseY) If Y2 > 0 Then Y2 = 0 ElseIf Y2 < m_DifY Then Y2 = m_DifY End If End If If (X2 <> picStegoImage(1).Left) Or (Y2 <> picStegoImage(1).top) Then picStegoImage(1).Move X2, Y2 If picCoverImage(0).Visible Then picCoverImage(1).Move X2, Y2 Me.Refresh End If End If End If End Sub '------------------------------------------------------------------------------' ' ' ' Chameleon Image Steganography v1.2 ' ' ' ' Miscellaneous Application Procedures Module ' ' [modApplication] ' ' ' '------------------------------------------------------------------------------' ' ' ' Copyright (C) 2003 Mark David Gan ' ' ' '------------------------------------------------------------------------------' Option Explicit '------------------------------------------------------------------------------' ' Public Enumerated Data Types ' '------------------------------------------------------------------------------' Public Enum appTaskConstants TASK_NONE = 0 TASK_ENCODE = 1 TASK_DECODE = 2 End Enum

'------------------------------------------------------------------------------' ' Windows API Structure Data Types ' '------------------------------------------------------------------------------' Public Type RECT Left As Long top As Long Right As Long Bottom As Long End Type '------------------------------------------------------------------------------' ' Windows API Constants ' '------------------------------------------------------------------------------' '[ constants for setting textbox margins with "SendMessageLong" function ]' Private Const EC_LEFTMARGIN As Long = &H1 Private Const EC_RIGHTMARGIN As Long = &H2 Private Const EM_SETMARGINS As Long = &HD3 '[ constants for "DrawText" function "uFormat" parameter ]' Private Const DT_CALCRECT As Long = &H400 Private Const DT_END_ELLIPSIS As Long = &H8000 Private Const DT_MODIFYSTRING As Long = &H10000 Private Const DT_NOPREFIX As Long = &H800 Private Const DT_PATH_ELLIPSIS As Long = &H4000 Private Const DT_WORD_ELLIPSIS As Long = &H40000 '[ constants for "ShellExecute" function return values ]' Private Const SE_ERR_ACCESSDENIED As Long = 5 Private Const SE_ERR_ASSOCINCOMPLETE As Long = 27 Private Const SE_ERR_DDEBUSY As Long = 30 Private Const SE_ERR_DDEFAIL As Long = 29 Private Const SE_ERR_DDETIMEOUT As Long = 28 Private Const SE_ERR_DLLNOTFOUND As Long = 32 Private Const SE_ERR_FNF As Long = 2 Private Const SE_ERR_NOASSOC As Long = 31 Private Const SE_ERR_OOM As Long = 8 Private Const SE_ERR_PNF As Long = 3 Private Const SE_ERR_SHARE As Long = 26 Private Const ERROR_BAD_FORMAT As Long = 11& '[ constants for "ShellExecute" function "nShowCmd" parameter ]' Private Const SW_SHOW As Long = 5 Private Const SW_SHOWDEFAULT As Long = 10 Private Const SW_SHOWMAXIMIZED As Long = 3 Private Const SW_SHOWMINIMIZED As Long = 2 Private Const SW_SHOWMINNOACTIVE As Long = 7 Private Const SW_SHOWNA As Long = 8 Private Const SW_SHOWNOACTIVATE As Long = 4 Private Const SW_SHOWNORMAL As Long = 1 '------------------------------------------------------------------------------' ' HTML Help Constants ' '------------------------------------------------------------------------------' Public Const HH_DISPLAY_TOPIC As Long = &H0 Public Const HH_SET_WIN_TYPE As Long = &H4 Public Const HH_GET_WIN_TYPE As Long = &H5 Public Const HH_GET_WIN_HANDLE As Long = &H6 Public Const HH_DISPLAY_TEXT_POPUP As Long = &HE Public Const HH_HELP_CONTEXT As Long = &HF Public Const HH_TP_HELP_CONTEXTMENU As Long = &H10 Public Const HH_TP_HELP_WM_HELP As Long = &H11 Public Const HH_CLOSE_ALL As Long = &H12 '------------------------------------------------------------------------------' ' Windows API Function Declarations ' '------------------------------------------------------------------------------' Private Declare Function DestroyWindow _ Lib "user32" (ByVal hWnd As Long) As Long Private Declare Function DrawText _ Lib "user32" Alias "DrawTextA" ( _ ByVal hDC As Long, _ ByVal lpString As String, _ ByVal nCount As Long, _ lpRect As RECT, _ ByVal uFormat As Long _ ) As Long Private Declare Function GetDesktopWindow Lib "user32" () As Long Private Declare Function SendMessageLong _ Lib "user32" Alias "SendMessageA" ( _ ByVal hWnd As Long, _ ByVal wMsg As Long, _ ByVal wParam As Long, _ ByVal lParam As Long _ ) As Long Private Declare Function ShellExecute _ Lib "shell32.dll" Alias "ShellExecuteA" ( _ ByVal hWnd As Long, _ ByVal lpOperation As String, _ ByVal lpFile As String, _ ByVal lpParameters As String, _ ByVal lpDirectory As String, _ ByVal nShowCmd As Long _ ) As Long '------------------------------------------------------------------------------' ' HTML Help Function Declarations ' '------------------------------------------------------------------------------' Private Declare Function HtmlHelp _ Lib "hhctrl.ocx" Alias "HtmlHelpA" ( _ ByVal hwndCaller As Long, _ ByVal pszFile As String, _ ByVal uCommand As Long, _ ByVal dwData As Long _ ) As Long '------------------------------------------------------------------------------' ' Public Variables ' '------------------------------------------------------------------------------' Public CurrentTask As appTaskConstants '------------------------------------------------------------------------------' ' Public Procedures ' '------------------------------------------------------------------------------' Public Sub CloseHelpFiles() Call HtmlHelp(0, "", HH_CLOSE_ALL, 0)

Page 139: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps G-11

End Sub Public Sub CompactCaptionWithEllipses(Label1 As Control) Dim Cap As String Dim RC As RECT With Label1 '[ compute boundary ]' RC.Right = frmView.ScaleX(.Width, vbTwips, vbPixels) RC.Bottom = frmView.ScaleY(.Height, vbTwips, vbPixels) Cap = .Caption Set frmMainMenu.Font = Label1.Font '[ use ellipses to compact the caption ]' Call DrawText(frmMainMenu.hDC, Cap, -1, RC, _ DT_CALCRECT + DT_MODIFYSTRING + DT_NOPREFIX + _ DT_PATH_ELLIPSIS) If .Caption = Cap Then .ToolTipText = vbNullString Else '[ set the tooltip to the original caption and display new caption ]' .ToolTipText = .Caption .Caption = Cap End If End With End Sub Public Sub DisplayHelpFile(ByVal TopicFile As String) Call HtmlHelp(GetDesktopWindow, App.Path & "\Chameleon.chm::/" & TopicFile & _ ">default", HH_DISPLAY_TOPIC, 0) End Sub Public Function FormatDate(ByVal DateTime As Date) As String FormatDate = Format$(DateTime, "mmmm d, yyyy" & vbCrLf & "dddd" & vbCrLf & _ "h:Nn AMPM") End Function Public Function FormatSize(ByVal Bytes As Long) As String FormatSize = Format$(Bytes, "#,##0") & IIf(Bytes = 1, " byte", " bytes") End Function Public Function GetHashValue(ByVal Data As String, _ ByVal Algorithm As EC_HASH_ALG_ID) As String With frmMainMenu.EzCrypto .HashAlgorithm = Algorithm .CreateHash .HashDigestData Data GetHashValue = .GetDigestedData(EC_HF_ASCII) .DestroyHash End With End Function Public Function GetHashValueOfFile(ByVal FileName As String, _ ByVal Algorithm As EC_HASH_ALG_ID) As String With frmMainMenu.EzCrypto .HashAlgorithm = Algorithm .CreateHash .HashDigestFile FileName GetHashValueOfFile = .GetDigestedData(EC_HF_ASCII) .DestroyHash End With End Function Public Function OpenFile(ByVal FileName As String) As Boolean Dim RV As Long On Error Resume Next OpenFile = (ShellExecute(0, "", FileName, "", "", SW_SHOW) > 32) If Not OpenFile Then RV = ShellExecute(0, "open", FileName, "", "", SW_SHOW) If RV > 32 Then OpenFile = True Else OpenFile = False Select Case RV Case SE_ERR_NOASSOC, SE_ERR_ASSOCINCOMPLETE: MsgBox "The file " & FileName & " cannot be opened." & vbCrLf & _ "The file may not be associated with any application.", _ vbExclamation Case Else: MsgBox "The file " & FileName & " cannot be opened." & vbCrLf & _ "An error occured while accessing the file.", vbExclamation End Select End If End If End Function Public Sub SetMargins(ByRef Text1 As TextBox, ByVal Margin As Long) SendMessageLong Text1.hWnd, EM_SETMARGINS, EC_LEFTMARGIN, Margin SendMessageLong Text1.hWnd, EM_SETMARGINS, EC_RIGHTMARGIN, Margin * &H10000 End Sub '------------------------------------------------------------------------------' ' ' ' Chameleon Image Steganography v1.2 ' ' ' ' Custom Button Subclassing Module ' ' [modCustomButton] ' ' ' '------------------------------------------------------------------------------' ' ' ' Copyright (C) 2003 Mark David Gan ' ' ' '------------------------------------------------------------------------------' Option Explicit

'------------------------------------------------------------------------------' ' Windows API Constants ' '------------------------------------------------------------------------------' '[ constants for "SetWindowLong" function "nIndex" parameter ]' Private Const GWL_WNDPROC As Long = (-4) '[ constants for "TRACTMOUSEEVENTTYPE" structure "dwFlags" member ]' Private Const TME_HOVER As Long = &H1 Private Const TME_LEAVE As Long = &H2 Private Const TME_QUERY As Long = &H40000000 Private Const TME_CANCEL As Long = &H80000000 '[ window messages ]' Private Const WM_LBUTTONDBLCLK As Long = &H203 Private Const WM_LBUTTONDOWN As Long = &H201 Private Const WM_LBUTTONUP As Long = &H202 Private Const WM_MOUSEACTIVATE As Long = &H21 Private Const WM_MOUSEHOVER As Long = &H2A1 Private Const WM_MOUSELEAVE As Long = &H2A3 Private Const WM_MOUSEMOVE As Long = &H200 Private Const WM_MOUSEWHEEL As Long = &H20A '------------------------------------------------------------------------------' ' Public Structure Data Types ' '------------------------------------------------------------------------------' Private Type TRACKMOUSEEVENTTYPE cbSize As Long dwFlags As Long hwndTrack As Long dwHoverTime As Long End Type '------------------------------------------------------------------------------' ' Windows API Function Declarations ' '------------------------------------------------------------------------------' Private Declare Function CallWindowProc _ Lib "user32" Alias "CallWindowProcA" ( _ ByVal lpPrevWndFunc As Long, _ ByVal hWnd As Long, _ ByVal Msg As Long, _ ByVal wParam As Long, _ ByVal lParam As Long _ ) As Long Private Declare Function SetWindowLong _ Lib "user32" Alias "SetWindowLongA" ( _ ByVal hWnd As Long, _ ByVal nIndex As Long, _ ByVal dwNewLong As Long _ ) As Long Private Declare Function TrackMouseEvent _ Lib "user32" ( _ lpEventTrack As TRACKMOUSEEVENTTYPE _ ) As Long '------------------------------------------------------------------------------' ' Private Variables ' '------------------------------------------------------------------------------' Private m_ButtonCollection As Collection '------------------------------------------------------------------------------' ' Public Procedures ' '------------------------------------------------------------------------------' Public Function NewWndProc(ByVal hWnd As Long, ByVal uMsg As Long, _ ByVal wParam As Long, ByVal lParam As Long) As Long Dim CButton1 As CustomButton On Error Resume Next If Not m_ButtonCollection Is Nothing Then Set CButton1 = m_ButtonCollection.Item("hWnd: " & hWnd) '[ test for mouse leave event ]' If CButton1.Enabled Then Select Case uMsg Case WM_MOUSELEAVE: CButton1.State = cbtnStateNormal CButton1.RaiseMouseLeaveEvent End Select End If '[ call original window procedure ]' NewWndProc = CallWindowProc(CButton1.OldWndProc, hWnd, uMsg, wParam, lParam) End If End Function Public Sub StartSubclassingButton(ByVal CButton1 As CustomButton) If CButton1.OldWndProc = 0 Then '[ create button collection ] ' If m_ButtonCollection Is Nothing Then Set m_ButtonCollection = New Collection End If '[ subclass button ]' m_ButtonCollection.Add CButton1, "hWnd: " & CButton1.hWnd CButton1.OldWndProc = SetWindowLong(CButton1.hWnd, GWL_WNDPROC, _ AddressOf NewWndProc) End If End Sub Public Sub StopSubclassingButton(ByVal CButton1 As CustomButton) '[ reconnect button to its original window procedure ]' If CButton1.OldWndProc <> 0 Then SetWindowLong CButton1.hWnd, GWL_WNDPROC, CButton1.OldWndProc CButton1.OldWndProc = 0 m_ButtonCollection.Remove "hWnd: " & CButton1.hWnd End If End Sub

Page 140: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps G-12

Public Sub TrackMouseLeaveEvent(ByVal CButton1 As CustomButton) Dim TMEvent As TRACKMOUSEEVENTTYPE With TMEvent .cbSize = Len(TMEvent) .hwndTrack = CButton1.hWnd .dwFlags = TME_LEAVE End With TrackMouseEvent TMEvent End Sub '------------------------------------------------------------------------------' ' ' ' Chameleon Image Steganography v1.2 ' ' ' ' File System Operations Module ' ' [modFileSystem] ' ' ' '------------------------------------------------------------------------------' ' ' ' Copyright (C) 2003 Mark David Gan ' ' ' '------------------------------------------------------------------------------' Option Explicit '------------------------------------------------------------------------------' ' Windows API Structure Data Types ' '------------------------------------------------------------------------------' '[ 64-bit time structure ]' Private Type FILETIME dwLowDateTime As Long dwHighDateTime As Long End Type '[ multiple-field time structure ]' Private Type SYSTEMTIME wYear As Integer wMonth As Integer wDayOfWeek As Integer wDay As Integer wHour As Integer wMinute As Integer wSecond As Integer wMilliseconds As Integer End Type '------------------------------------------------------------------------------' ' Windows API Constants ' '------------------------------------------------------------------------------' '[ constants for "CreateFile" function "dwDesiredAccess" parameter ]' Private Const GENERIC_READ As Long = &H80000000 Private Const GENERIC_WRITE As Long = &H40000000 '[ constants for "CreateFile" function "dwShareMode" parameter ]' Private Const FILE_SHARE_READ As Long = &H1 Private Const FILE_SHARE_WRITE As Long = &H2 '[ constants for "CreateFile" function "dwCreateDisposition" parameter ]' Private Const CREATE_ALWAYS As Long = 2 Private Const CREATE_NEW As Long = 1 Private Const OPEN_ALWAYS As Long = 4 Private Const OPEN_EXISTING As Long = 3 Private Const TRUNCATE_EXISTING As Long = 5 '[ constants for "CreateFile" function "dwFlagsAndAttributes" parameter ]' Private Const FILE_ATTRIBUTE_ARCHIVE As Long = &H20 Private Const FILE_ATTRIBUTE_HIDDEN As Long = &H2 Private Const FILE_ATTRIBUTE_NORMAL As Long = &H80 Private Const FILE_ATTRIBUTE_READONLY As Long = &H1 Private Const FILE_ATTRIBUTE_SYSTEM As Long = &H4 Private Const FILE_FLAG_DELETE_ON_CLOSE As Long = &H4000000 Private Const FILE_FLAG_NO_BUFFERING As Long = &H20000000 Private Const FILE_FLAG_OVERLAPPED As Long = &H40000000 Private Const FILE_FLAG_POSIX_SEMANTICS As Long = &H1000000 Private Const FILE_FLAG_RANDOM_ACCESS As Long = &H10000000 Private Const FILE_FLAG_SEQUENTIAL_SCAN As Long = &H8000000 Private Const FILE_FLAG_WRITE_THROUGH As Long = &H80000000 '[ constants for "SetFilePointer" function "dwMoveMethod" parameter ]' Private Const FILE_BEGIN As Long = 0 Private Const FILE_CURRENT As Long = 1 Private Const FILE_END As Long = 2 '------------------------------------------------------------------------------' ' FileSystemObject Constants ' '------------------------------------------------------------------------------' '[ constants for "GetSpecialFolder" function "folderspec" parameter ]' Private Const GSF_WINDOWSFOLDER As Long = 0 Private Const GSF_SYSTEMFOLDER As Long = 1 Private Const GSF_TEMPORARYFOLDER As Long = 2 '------------------------------------------------------------------------------' ' Windows API Function Declarations ' '------------------------------------------------------------------------------' Private Declare Function CloseHandle _ Lib "kernel32.dll" (ByVal hObject As Long) As Long Private Declare Function CreateFile _ Lib "kernel32.dll" Alias "CreateFileA" ( _ ByVal lpFileName As String, _ ByVal dwDesiredAccess As Long, _ ByVal dwShareMode As Long, _ ByVal lpSecurityAttributes As Long, _ ByVal dwCreationDisposition As Long, _ ByVal dwFlagsAndAttributes As Long, _ ByVal hTemplateFile As Long _ ) As Long Private Declare Function SetFilePointer _ Lib "kernel32.dll" ( _ ByVal iFileHandler As Long, _ ByVal lDistanceToMove As Long, _ ByRef lpDistanceToMoveHigh As Long, _ ByVal dwMoveMethod As Long _ ) As Long

Private Declare Function SetFileTime _ Lib "kernel32" ( _ ByVal hFile As Long, _ ByVal lpCreationTime As Long, _ ByRef lpLastAccessTime As FILETIME, _ ByRef lpLastWriteTime As FILETIME _ ) As Long Private Declare Function SystemTimeToFileTime _ Lib "kernel32" ( _ lpSystemTime As SYSTEMTIME, _ lpFileTime As FILETIME _ ) As Long Private Declare Function WriteFile _ Lib "kernel32.dll" ( _ ByVal iFileHandler As Long, _ ByRef lpBuffer As Any, _ ByVal nNumberOfBytesToWrite As Long, _ ByRef lpNumberOfBytesWritten As Long, _ ByVal lpOverlapped As Long _ ) As Long '------------------------------------------------------------------------------' ' Public Procedures ' '------------------------------------------------------------------------------' Public Sub CreateFolder(ByVal Path As String) Dim FSO As Object Set FSO = CreateObject("Scripting.FileSystemObject") If Len(FSO.GetParentFolderName(Path)) > 0 Then CreateFolder FSO.GetParentFolderName(Path) End If On Error Resume Next MkDir Path End Sub Public Function FileExists(ByVal Path As String) As Boolean Dim FSO As Object Set FSO = CreateObject("Scripting.FileSystemObject") FileExists = FSO.FileExists(Path) End Function Public Function FolderExists(ByVal Path As String) As Boolean Dim FSO As Object Set FSO = CreateObject("Scripting.FileSystemObject") FolderExists = FSO.FolderExists(Path) End Function Public Function GenerateTempFile() As String Dim FSO As Object Set FSO = CreateObject("Scripting.FileSystemObject") '[ set current drive to that of the windows folder ]' ChDir Left$(FSO.GetSpecialFolder(GSF_WINDOWSFOLDER), 2) & "\" '[ get path of temporary folder ]' GenerateTempFile = FSO.GetSpecialFolder(GSF_TEMPORARYFOLDER) & "\" & _ UCase$(FSO.GetTempName) End Function Public Function GetAbsolutePath(ByVal Path As String) As String If Len(Path) = 0 Then GetAbsolutePath = "" Exit Function End If Dim FSO As Object Set FSO = CreateObject("Scripting.FileSystemObject") '[ replace illegal characters ]' Path = Replace$(Path, ">", "") Path = Replace$(Path, "<", "") Path = Replace$(Path, "*", "") Path = Replace$(Path, "?", "") Path = Replace$(Path, "|", "") Path = Replace$(Path, Chr(34), "") '[ ensure that the colon character is in place ]' If InStr(1, Path, ":") = 2 Then Path = Left$(Path, 2) & Replace$(Path, ":", "", 3) Else Path = Replace$(Path, ":", "") End If '[ set current drive to that of the windows folder ]' ChDir Left$(FSO.GetSpecialFolder(GSF_WINDOWSFOLDER), 2) & "\" GetAbsolutePath = FSO.GetAbsolutePathName(Path) End Function Public Function GetFileDateTime(ByVal FileName As String) As String If FileExists(FileName) Then GetFileDateTime = FormatDate(FileDateTime(FileName)) Else GetFileDateTime = vbNullString End If End Function Public Function GetFileSize(ByVal FileName As String) As String If FileExists(FileName) Then GetFileSize = FormatSize(FileLen(FileName)) Else GetFileSize = vbNullString End If End Function Public Function GetPathFileName(ByVal Path As String) As String Dim FSO As Object Set FSO = CreateObject("Scripting.FileSystemObject") GetPathFileName = FSO.GetFileName(Path) End Function Public Function GetPathFolderName(ByVal Path As String) As String Dim FSO As Object Set FSO = CreateObject("Scripting.FileSystemObject") GetPathFolderName = FSO.GetParentFolderName(Path)

Page 141: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps G-13

End Function Public Function GetPrimaryDrive() As String Dim FSO As Object Set FSO = CreateObject("Scripting.FileSystemObject") GetPrimaryDrive = Left$(FSO.GetSpecialFolder(GSF_WINDOWSFOLDER), 2) & "\" End Function Public Function SetFileDate(ByVal FileName As String, _ ByVal FileDate As Date) As Boolean Dim STime As SYSTEMTIME Dim FTime As FILETIME Dim hFile As Long '[ get data file date and time ]' STime.wYear = Year(FileDate) STime.wMonth = Month(FileDate) STime.wDay = Day(FileDate) STime.wDayOfWeek = Weekday(FileDate) - 1 STime.wHour = Hour(FileDate) STime.wMinute = Minute(FileDate) STime.wSecond = Second(FileDate) STime.wMilliseconds = 0 SystemTimeToFileTime STime, FTime '[ set file attribute to normal ]' On Error Resume Next SetAttr FileName, vbNormal '[ open source file ]' hFile = CreateFile(FileName, GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0) '[ get file date and time ]' If hFile <> -1 Then SetFileTime hFile, 0, FTime, FTime CloseHandle hFile SetFileDate = True Else SetFileDate = False End If End Function Public Function WipeFile(ByVal FileName As String, ByVal Rename As Boolean) _ As Boolean Dim FileName2 As String Dim FileSize As Long Dim hFile As Long Dim Ctr As Long Dim Pattern() As Byte Dim BytesWritten As Long On Error Resume Next '[ set file attribute to normal and retrieve file size ]' SetAttr FileName, vbNormal FileSize = FileLen(FileName) '[ rename file and move to windows temporary folder ]' If Rename Then FileName2 = GenerateTempFile Kill FileName2 Name FileName As FileName2 Else FileName2 = FileName End If On Error GoTo FileError '[ open file with disk caching disabled ]' hFile = CreateFile(FileName2, GENERIC_WRITE, 0, 0, OPEN_EXISTING, _ FILE_FLAG_WRITE_THROUGH + FILE_FLAG_DELETE_ON_CLOSE + _ FILE_FLAG_SEQUENTIAL_SCAN, 0) '[ if file opened successfully, then wipe file ]' If hFile <> -1 Then ReDim Pattern(1 To FileSize, 1 To 3) '[ assign bit patterns ]' For Ctr = 1 To FileSize Pattern(Ctr, 1) = &H55 '[ bit pattern 01010101 ]' Pattern(Ctr, 2) = &HAA '[ bit pattern 10101010 ]' Pattern(Ctr, 3) = &H0 '[ bit pattern 00000000 ]' Next Ctr '[ write bit patterns to file ]' For Ctr = 1 To 3 SetFilePointer hFile, 0, 0, FILE_BEGIN WriteFile hFile, Pattern(1, Ctr), FileSize, BytesWritten, 0 Next Ctr '[ close and delete file ]' CloseHandle hFile WipeFile = True Exit Function End If FileError: WipeFile = False End Function '------------------------------------------------------------------------------' ' ' ' Chameleon Image Steganography v1.2 ' ' ' ' Bit Stream Class ' ' [BitStream] ' ' ' '------------------------------------------------------------------------------' ' ' ' Copyright (C) 2003 Mark David Gan ' ' ' '------------------------------------------------------------------------------' Option Explicit '------------------------------------------------------------------------------' ' Windows API Function Declarations ' '------------------------------------------------------------------------------' Private Declare Sub CopyMemory _ Lib "kernel32" Alias "RtlMoveMemory" ( _

pDst As Any, _ pSrc As Any, _ ByVal ByteLen As Long) '------------------------------------------------------------------------------' ' Private Variables ' '------------------------------------------------------------------------------' Private m_Stream() As Byte '[ bit stream array ]' Private m_Length As Long '[ bit stream length ]' '------------------------------------------------------------------------------' ' Public Procedures ' '------------------------------------------------------------------------------' Public Sub Clear() Erase m_Stream m_Length = 0 End Sub Public Function ExtractBits(ByVal BitCount As Long) As Long If BitCount > 32 Then BitCount = 32 If BitCount <= m_Length Then '[ decrement length ]' m_Length = m_Length - BitCount ExtractBits = 0 Dim Ctr As Long For Ctr = 1 To BitCount If Ctr < 32 Then '[ add bit value ]' If m_Stream(m_Length + Ctr) > 0 Then ExtractBits = ExtractBits + Int(2 ^ (Ctr - 1)) End If Else '[ if negative, compute two's complement ]' If m_Stream(m_Length + Ctr) > 0 Then ExtractBits = (Not ExtractBits) + 1 End If End If Next Ctr '[ resize stream ]' If m_Length > 0 Then ReDim Preserve m_Stream(1 To m_Length) Else Erase m_Stream End If End If End Function Public Function ExtractByte() As Byte If m_Length > 7 Then '[ decrement length ]' m_Length = m_Length - 8 '[ add bit values ]' ExtractByte = 0 If m_Stream(m_Length + 1) > 0 Then ExtractByte = ExtractByte + 1 If m_Stream(m_Length + 2) > 0 Then ExtractByte = ExtractByte + 2 If m_Stream(m_Length + 3) > 0 Then ExtractByte = ExtractByte + 4 If m_Stream(m_Length + 4) > 0 Then ExtractByte = ExtractByte + 8 If m_Stream(m_Length + 5) > 0 Then ExtractByte = ExtractByte + 16 If m_Stream(m_Length + 6) > 0 Then ExtractByte = ExtractByte + 32 If m_Stream(m_Length + 7) > 0 Then ExtractByte = ExtractByte + 64 If m_Stream(m_Length + 8) > 0 Then ExtractByte = ExtractByte + 128 '[ resize stream ]' If m_Length > 0 Then ReDim Preserve m_Stream(1 To m_Length) Else Erase m_Stream End If End If End Function Public Function ExtractString(ByVal CharCount As Long) As String Dim Ctr As Long ExtractString = vbNullString For Ctr = 1 To CharCount ExtractString = ExtractString & Chr(ExtractByte) Next Ctr End Function Public Sub InsertBitsAtEnd(ByVal Bits As Long, ByVal BitCount As Long) If BitCount > 32 Then BitCount = 32 '[ resize stream ]' ReDim Preserve m_Stream(1 To (m_Length + BitCount)) '[ shift bits towards the top ]' If m_Length > 0 Then CopyMemory ByVal VarPtr(m_Stream(BitCount + 1)), _ ByVal VarPtr(m_Stream(1)), _ m_Length End If '[ insert bits in the stream ]' Dim Ctr As Long For Ctr = 1 To BitCount If Ctr < 32 Then If (Bits And Int(2 ^ (Ctr - 1))) > 0 Then m_Stream(Ctr) = 1 Else m_Stream(Ctr) = 0 End If Else If Bits < 0 Then m_Stream(Ctr) = 1 Else m_Stream(Ctr) = 0 End If End If Next Ctr '[ increment length ]' m_Length = m_Length + BitCount

Page 142: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps G-14

End Sub Public Sub InsertBitsAtTop(ByVal Bits As Long, ByVal BitCount As Long) If BitCount > 32 Then BitCount = 32 '[ resize stream ]' ReDim Preserve m_Stream(1 To (m_Length + BitCount)) '[ insert bits in the stream ]' Dim Ctr As Long For Ctr = 1 To BitCount If Ctr < 32 Then If (Bits And Int(2 ^ (Ctr - 1))) > 0 Then m_Stream(m_Length + Ctr) = 1 Else m_Stream(m_Length + Ctr) = 0 End If Else If Bits < 0 Then m_Stream(m_Length + Ctr) = 1 Else m_Stream(m_Length + Ctr) = 0 End If End If Next Ctr '[ increment length ]' m_Length = m_Length + BitCount End Sub Public Sub InsertByteAtEnd(ByVal Bits As Byte) '[ resize stream ]' ReDim Preserve m_Stream(1 To (m_Length + 8)) '[ shift bits towards the top ]' If m_Length > 0 Then CopyMemory ByVal VarPtr(m_Stream(9)), ByVal VarPtr(m_Stream(1)), m_Length End If '[ insert bits in the stream ]' m_Stream(8) = (Bits And &H80) \ &H80 m_Stream(7) = (Bits And &H40) \ &H40 m_Stream(6) = (Bits And &H20) \ &H20 m_Stream(5) = (Bits And &H10) \ &H10 m_Stream(4) = (Bits And &H8) \ &H8 m_Stream(3) = (Bits And &H4) \ &H4 m_Stream(2) = (Bits And &H2) \ &H2 m_Stream(1) = Bits And &H1 '[ increment length ]' m_Length = m_Length + 8 End Sub Public Sub InsertByteAtTop(ByVal Bits As Byte) '[ resize stream ]' ReDim Preserve m_Stream(1 To (m_Length + 8)) '[ insert bits in the stream ]' m_Stream(m_Length + 8) = (Bits And &H80) \ &H80 m_Stream(m_Length + 7) = (Bits And &H40) \ &H40 m_Stream(m_Length + 6) = (Bits And &H20) \ &H20 m_Stream(m_Length + 5) = (Bits And &H10) \ &H10 m_Stream(m_Length + 4) = (Bits And &H8) \ &H8 m_Stream(m_Length + 3) = (Bits And &H4) \ &H4 m_Stream(m_Length + 2) = (Bits And &H2) \ &H2 m_Stream(m_Length + 1) = Bits And &H1 '[ increment length ]' m_Length = m_Length + 8 End Sub Public Sub InsertStringAtEnd(ByVal Bits As String) Dim Ctr As Long For Ctr = 1 To Len(Bits) InsertByteAtEnd Asc(Mid$(Bits, Ctr, 1)) Next Ctr End Sub Public Sub InsertStringAtTop(ByVal Bits As String) Dim Ctr As Long For Ctr = Len(Bits) To 1 Step -1 InsertByteAtTop Asc(Mid$(Bits, Ctr, 1)) Next Ctr End Sub '------------------------------------------------------------------------------' ' Public Properties ' '------------------------------------------------------------------------------' Public Property Get Length() As Long Length = m_Length End Property '------------------------------------------------------------------------------' ' Event Handlers ' '------------------------------------------------------------------------------' Private Sub Class_Initialize() Clear End Sub Private Sub Class_Terminate() Clear End Sub '------------------------------------------------------------------------------' ' ' ' Chameleon Image Steganography v1.2 ' ' ' ' FreeImage Library Wrapper Class ' ' [FreeImageWrapper] ' ' ' '------------------------------------------------------------------------------' ' ' ' Copyright (C) 2003 Mark David Gan ' ' ' '------------------------------------------------------------------------------'

'------------------------------------------------------------------------------' ' ' ' Requires: FreeImage.dll ' ' ' ' The FreeImage Library (FreeImage.dll) is written by Floris van den Berg. ' ' ' '------------------------------------------------------------------------------' Option Explicit '------------------------------------------------------------------------------' ' Windows API Structure Data Types ' '------------------------------------------------------------------------------' '[ rgb color components ]' Private Type RGBQUAD rgbBlue As Byte rgbGreen As Byte rgbRed As Byte rgbReserved As Byte End Type '[ dib dimensions and color format ]' Private Type BITMAPINFOHEADER biSize As Long biWidth As Long biHeight As Long biPlanes As Integer biBitCount As Integer biCompression As Long biSizeImage As Long biXPelsPerMeter As Long biYPelsPerMeter As Long biClrUsed As Long biClrImportant As Long End Type '[ dib information ]' Private Type BITMAPINFO bmiHeader As BITMAPINFOHEADER bmiColors() As RGBQUAD End Type '[ bitmap structure ]' Private Type BITMAP bmType As Long bmWidth As Long bmHeight As Long bmWidthBytes As Long bmPlanes As Integer bmBitsPixel As Integer bmBits As Long End Type '------------------------------------------------------------------------------' ' Windows API Constants ' '------------------------------------------------------------------------------' '[ constant for "CreateDIBitmap" function "BitFlags" parameter ]' Private Const CBM_INIT As Long = &H4 '[ color representation ]' Private Const DIB_RGB_COLORS As Long = 0 '[ colors as rgb components ]' Private Const DIB_PAL_COLORS As Long = 1 '[ colors as palette indexes ]' '------------------------------------------------------------------------------' ' FreeImage Constants ' '------------------------------------------------------------------------------' '[ default load/save flags ]' Private Const BMP_DEFAULT As Long = 0 Private Const CUT_DEFAULT As Long = 0 Private Const ICO_DEFAULT As Long = 0 Private Const IFF_DEFAULT As Long = 0 Private Const JPEG_DEFAULT As Long = 0 Private Const KOALA_DEFAULT As Long = 0 Private Const LBM_DEFAULT As Long = 0 Private Const MNG_DEFAULT As Long = 0 Private Const PCD_DEFAULT As Long = 0 Private Const PCX_DEFAULT As Long = 0 Private Const PNG_DEFAULT As Long = 0 Private Const PNM_DEFAULT As Long = 0 Private Const PSD_DEFAULT As Long = 0 Private Const RAS_DEFAULT As Long = 0 Private Const TARGA_DEFAULT As Long = 0 Private Const TIFF_DEFAULT As Long = 0 Private Const WBMP_DEFAULT As Long = 0 '[ special load flags ]' Private Const ICO_FIRST As Long = 0 Private Const ICO_SECOND As Long = 0 Private Const ICO_THIRD As Long = 0 Private Const JPEG_FAST As Long = 1 Private Const JPEG_ACCURATE As Long = 2 Private Const PCD_BASE As Long = 1 '[ PhotoCD, size 768 x 512 ]' Private Const PCD_BASEDIV4 As Long = 2 '[ PhotoCD, size 384 x 256 ]' Private Const PCD_BASEDIV16 As Long = 3 '[ PhotoCD, size 192 x 128 ]' Private Const PNG_IGNOREGAMMA As Long = 1 Private Const TARGA_LOAD_RGB888 As Long = 1 '[ special save flags ]' Private Const JPEG_QUALITYSUPERB As Long = &H80 Private Const JPEG_QUALITYGOOD As Long = &H100 Private Const JPEG_QUALITYNORMAL As Long = &H200 Private Const JPEG_QUALITYAVERAGE As Long = &H400 Private Const JPEG_QUALITYBAD As Long = &H800 Private Const PNM_SAVE_RAW As Long = 0 Private Const PNM_SAVE_ascii As Long = 1 '------------------------------------------------------------------------------' ' FreeImage Enumerated Data Types ' '------------------------------------------------------------------------------' '[ image file format ]' Public Enum FREE_IMAGE_FORMAT FIF_UNKNOWN = -1 '[ unidentified bitmap type ]' FIF_BMP = 0 '[ windows or OS/2 bitmap file (*.bmp) ]' FIF_ICO = 1 '[ windows icon (*.ico) ]' FIF_JPEG = 2 '[ independent jpeg froup (*.jpg) ]' FIF_JNG = 3 '[ jpeg network graphics (*.jng) ]' FIF_KOALA = 4 '[ commodore 64 koala format (*.koa) ]' FIF_IFF = 5 '[ amiga iff (*.iff, *.lbm) ]' FIF_MNG = 6 '[ multiple network graphics (*.mng) ]' FIF_PBM = 7 '[ portable bitmap (ascii) (*.pbm) ]' FIF_PBMRAW = 8 '[ portable bitmap (binary) (*.pbm) ]' FIF_PCD = 9 '[ kodak photocd (*.pcd) ]' FIF_PCX = 10 '[ pcx bitmap format (*.pcx) ]' FIF_PGM = 11 '[ portable graymap (ascii) (*.pgm) ]' FIF_PGMRAW = 12 '[ portable graymap (binary) (*.pgm) ]'

Page 143: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps G-15

FIF_PNG = 13 '[ portable network Graphics (*.PNG) ]' FIF_PPM = 14 '[ portable pixelmap (ascii) (*.PPM) ]' FIF_PPMRAW = 15 '[ portable pixelmap (binary) (*.PPM) ]' FIF_RAS = 16 '[ sun rasterfile (*.ras) ]' FIF_TARGA = 17 '[ targa files (*.tga) ]' FIF_TIFF = 18 '[ tagged image file format (*.tiff) ]' FIF_WBMP = 19 '[ wireless bitmap (*.wbmp) ]' FIF_PSD = 20 '[ photoshop (*.psd) ]' FIF_CUT = 21 '[ dr. halo (*.cut) ]' End Enum '------------------------------------------------------------------------------' ' Windows API Function Declarations ' '------------------------------------------------------------------------------' Private Declare Function CreateDIBitmap _ Lib "gdi32" ( _ ByVal hDC As Long, _ ByRef lpBITMAPINFOHEADER As Any, _ ByVal BitFlags As Long, _ ByRef BmpBits As Any, _ ByRef lpBitmapInfo As Any, _ ByVal fuUsage As Long _ ) As Long Private Declare Function DeleteObject _ Lib "gdi32" (ByVal hObject As Long) As Boolean Private Declare Function GetBitmapBits _ Lib "gdi32" ( _ ByVal hBitmap As Long, _ ByVal dwCount As Long, _ BmpBits As Any _ ) As Long Private Declare Function GetDC Lib "user32" (ByVal hWnd As Long) As Long Private Declare Function GetDesktopWindow Lib "user32" () As Long Private Declare Function GetDIBits _ Lib "gdi32" ( _ ByVal hDC As Long, _ ByVal hBitmap As Long, _ ByVal StartingScanLine As Long, _ ByVal ScanLineCount As Long, _ ByRef lpBits As Any, _ ByRef lpBitmapInfo As Any, _ ByVal ColorUsage As Long _ ) As Long Private Declare Function GetObject _ Lib "gdi32" Alias "GetObjectA" ( _ ByVal hObject As Long, _ ByVal nCount As Long, _ ByRef lpObject As Any _ ) As Long Private Declare Function ReleaseDC _ Lib "user32" ( _ ByVal hWnd As Long, _ ByVal hDC As Long _ ) As Long Private Declare Function SetBitmapBits _ Lib "gdi32" ( _ ByVal hBitmap As Long, _ ByVal dwCount As Long, _ ByRef BmpBits As Any _ ) As Long Private Declare Function SetDIBitsToDevice _ Lib "gdi32" ( _ ByVal Dest_hDC As Long, _ ByVal Dest_X As Long, _ ByVal Dest_Y As Long, _ ByVal Src_Width As Long, _ ByVal Src_Height As Long, _ ByVal Src_X As Long, _ ByVal Src_Y As Long, _ ByVal StartingScanLine As Long, _ ByVal ScanLineCount As Long, _ ByRef BmpBits As Any, ByRef BmpInfo As Any, _ ByVal ColorUse As Long _ ) As Long '------------------------------------------------------------------------------' ' FreeImage Library General Function Declarations ' '------------------------------------------------------------------------------' Private Declare Sub FreeImage_DeInitialise _ Lib "FreeImage" Alias "_FreeImage_DeInitialise@0" () Private Declare Sub FreeImage_Initialise _ Lib "FreeImage" Alias "_FreeImage_Initialise@4" ( _ Optional ByVal load_local_plugins_only As Boolean = False) '------------------------------------------------------------------------------' ' FreeImage Library Bitmap Management Function Declarations ' '------------------------------------------------------------------------------' Private Declare Function FreeImage_Allocate _ Lib "FreeImage" Alias "_FreeImage_Allocate@24" ( _ ByVal Width As Long, _ ByVal Height As Long, _ ByVal BitsPerPixel As Long, _ Optional ByVal Red_Mask As Long = 0, _ Optional ByVal Green_Mask As Long = 0, _ Optional ByVal Blue_Mask As Long = 0 _ ) As Long Private Declare Function FreeImage_Load _ Lib "FreeImage" Alias "_FreeImage_Load@12" ( _ ByVal FIF As FREE_IMAGE_FORMAT, _ ByVal FileName As String, _ Optional ByVal Flags As Long = 0 _ ) As Long Private Declare Function FreeImage_Save _ Lib "FreeImage" Alias "_FreeImage_Save@16" ( _ ByVal FIF As FREE_IMAGE_FORMAT, _ ByVal hDIB As Long, _ ByVal FileName As String, _ Optional ByVal Flags As Long = 0 _ ) As Boolean Private Declare Sub FreeImage_Unload _ Lib "FreeImage" Alias "_FreeImage_Unload@4" (ByVal hDIB As Long) '------------------------------------------------------------------------------' ' FreeImage Library Bitmap Information Function Declarations ' '------------------------------------------------------------------------------'

Private Declare Function FreeImage_GetBits _ Lib "FreeImage" Alias "_FreeImage_GetBits@4" ( _ ByVal hDIB As Long _ ) As Long Private Declare Function FreeImage_GetBPP _ Lib "FreeImage" Alias "_FreeImage_GetBPP@4" ( _ ByVal hDIB As Long _ ) As Long Private Declare Function FreeImage_GetHeight _ Lib "FreeImage" Alias "_FreeImage_GetHeight@4" ( _ ByVal hDIB As Long _ ) As Long Private Declare Function FreeImage_GetInfo _ Lib "FreeImage" Alias "_FreeImage_GetInfo@4" ( _ ByVal hDIB As Long _ ) As Long Private Declare Function FreeImage_GetInfoHeader _ Lib "FreeImage" Alias "_FreeImage_GetInfoHeader@4" ( _ ByVal hDIB As Long _ ) As Long Private Declare Function FreeImage_GetPitch _ Lib "FreeImage" Alias "_FreeImage_GetPitch@4" ( _ ByVal hDIB As Long _ ) As Long Private Declare Function FreeImage_GetWidth _ Lib "FreeImage" Alias "_FreeImage_GetWidth@4" ( _ ByVal hDIB As Long _ ) As Long '------------------------------------------------------------------------------' ' FreeImage Library Filetype Function Declarations ' '------------------------------------------------------------------------------' Private Declare Function FreeImage_GetFileType _ Lib "FreeImage" Alias "_FreeImage_GetFileType@8" ( _ ByVal FileName As String, _ Optional ByVal size As Long = 16 _ ) As FREE_IMAGE_FORMAT Private Declare Function FreeImage_GetFileTypeFromExt _ Lib "FreeImage" Alias "_FreeImage_GetFileTypeFromExt@4" ( _ ByVal FileName As String _ ) As FREE_IMAGE_FORMAT Private Declare Function FreeImage_GetFileTypeFromFormat _ Lib "FreeImage" Alias "_FreeImage_GetFileTypeFromFormat@4" ( _ ByVal FIF As FREE_IMAGE_FORMAT _ ) As String '------------------------------------------------------------------------------' ' Public Procedures ' '------------------------------------------------------------------------------' Public Function CreateBitmapFromDIB(ByVal hDIB As Long) As Long Dim BmpHead As Long Dim BmpInfo As Long Dim BmpBits As Long Dim hDeskDC As Long Dim hBmp As Long '[ get desktop dc ]' hDeskDC = GetDC(GetDesktopWindow) '[ get dib information ]' BmpHead = FreeImage_GetInfoHeader(hDIB) BmpInfo = FreeImage_GetInfo(hDIB) BmpBits = FreeImage_GetBits(hDIB) '[ create screen-compatible bitmap based on dib ]' hBmp = CreateDIBitmap(hDeskDC, ByVal BmpHead, CBM_INIT, ByVal BmpBits, _ ByVal BmpInfo, DIB_RGB_COLORS) '[ return bitmap handle ]' CreateBitmapFromDIB = hBmp '[ cleanup desktop dc ]' ReleaseDC GetDesktopWindow, hDeskDC End Function Public Function CreateDIBFromBitmap(ByVal hBmp As Long) As Long Dim BMP As BITMAP Dim W As Long Dim H As Long Dim BPP As Long Dim hDeskDC As Long Dim hTmpDIB As Long Dim BmpInfo As Long Dim BmpBits As Long Dim Res As Long CreateDIBFromBitmap = 0 '[ get bitmap information ]' If GetObject(hBmp, Len(BMP), BMP) <> 0 Then '[ get desktop dc ]' W = BMP.bmWidth H = BMP.bmHeight BPP = 24 '[ get desktop dc ]' hDeskDC = GetDC(GetDesktopWindow) '[ allocate new dib ]' hTmpDIB = FreeImage_Allocate(W, H, BPP) '[ get dib information ]' BmpInfo = FreeImage_GetInfo(hTmpDIB) BmpBits = FreeImage_GetBits(hTmpDIB) '[ set dib bits ]' Res = GetDIBits(hDeskDC, hBmp, 0, H, ByVal BmpBits, ByVal BmpInfo, _ DIB_RGB_COLORS) If False Then '[ cleanup dib ]' FreeImage_Unload hTmpDIB Else '[ return dib handle ]' CreateDIBFromBitmap = hTmpDIB End If '[ cleanup desktop dc ]' ReleaseDC GetDesktopWindow, hDeskDC

Page 144: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps G-16

End If End Function Public Function DeleteBitmap(ByVal hBmp As Long) As Boolean DeleteBitmap = DeleteObject(hBmp) End Function Public Sub GetBitmapPixels(ByVal hBmp As Long, PixelArray() As Byte) Dim BMP As BITMAP '[ get bitmap structure ]' GetObject hBmp, Len(BMP), BMP '[ resize bitmap array ]' ReDim PixelArray(0 To (BMP.bmWidthBytes \ BMP.bmWidth) - 1, _ 0 To BMP.bmWidth - 1, _ 0 To BMP.bmHeight - 1) As Byte '[ load bitmap bits to array ]' GetBitmapBits hBmp, BMP.bmWidthBytes * BMP.bmHeight, _ PixelArray(0, 0, 0) End Sub Public Function GetHeight(ByVal hDIB As Long) As Long GetHeight = FreeImage_GetHeight(hDIB) End Function Public Function GetWidth(ByVal hDIB As Long) As Long GetWidth = FreeImage_GetWidth(hDIB) End Function Public Function GetFileType(ByVal FileName As String) As FREE_IMAGE_FORMAT GetFileType = FreeImage_GetFileType(FileName) If GetFileType = FIF_UNKNOWN Then GetFileType = FreeImage_GetFileTypeFromExt(FileName) End If End Function Public Function GetFileTypeString(ByVal FIF As FREE_IMAGE_FORMAT) As String GetFileTypeString = FreeImage_GetFileTypeFromFormat$(FIF) End Function Public Function LoadDIB(ByVal FileName As String, _ Optional ByRef FIF As Long) As Long Dim Flg As Long '[ get format ]' FIF = GetFileType(FileName) '[ set load flags based on format ]' Select Case FIF Case FIF_JPEG: Flg = JPEG_ACCURATE Case FIF_PCD: Flg = PCD_BASE Case FIF_PNG: Flg = PNG_IGNOREGAMMA Case Else: Flg = 0 End Select '[ if format recognized, then load image ]' If FIF = FIF_UNKNOWN Then LoadDIB = 0 Else LoadDIB = FreeImage_Load(FIF, FileName, Flg) End If End Function Public Function PaintDIB(ByVal hDIB As Long, ByVal Dest_hDC As Long, _ Optional ByVal Dest_X As Long = 0, _ Optional ByVal Dest_Y As Long = 0, _ Optional ByVal Src_Width As Long = -1, _ Optional ByVal Src_Height As Long = -1) As Boolean Dim W As Long Dim H As Long Dim BmpBits As Long Dim BmpInfo As Long Dim Res As Long '[ get dimensions of dib ]' W = IIf(Src_Width > 0, Src_Width, FreeImage_GetWidth(hDIB)) H = IIf(Src_Height > 0, Src_Height, FreeImage_GetHeight(hDIB)) '[ get memory address of dib bits ]' BmpBits = FreeImage_GetBits(hDIB) '[ get memory address of dib bitmap information ]' BmpInfo = FreeImage_GetInfo(hDIB) '[ paint as bitmap ]' If (W > 0) And (H > 0) And (BmpBits) And (BmpInfo) Then Res = SetDIBitsToDevice(Dest_hDC, Dest_X, Dest_Y, W, H, 0, 0, 0, H, _ ByVal BmpBits, ByVal BmpInfo, DIB_RGB_COLORS) Else Res = 0 End If PaintDIB = (Res <> 0) End Function Public Function SaveDIB(ByVal hDIB As Long, ByVal FileName As String, _ ByVal FIF As FREE_IMAGE_FORMAT) As Long Dim Flg As Long '[ set save flags ]' Select Case FIF Case FIF_JPEG: Flg = JPEG_QUALITYSUPERB Case FIF_PBM: Flg = PNM_SAVE_RAW Case FIF_PGM: Flg = PNM_SAVE_RAW Case FIF_PPM: Flg = PNM_SAVE_RAW Case Else: Flg = 0 End Select SaveDIB = FreeImage_Save(FIF, hDIB, FileName, Flg) End Function Public Sub SetBitmapPixels(ByVal hBmp As Long, PixelArray() As Byte) Dim BMP As BITMAP

'[ get bitmap structure ]' GetObject hBmp, Len(BMP), BMP '[ resize bitmap array ]' ReDim Preserve PixelArray(0 To (BMP.bmWidthBytes \ BMP.bmWidth) - 1, _ 0 To BMP.bmWidth - 1, _ 0 To BMP.bmHeight - 1) As Byte '[ set bitmap bits from array ]' SetBitmapBits hBmp, BMP.bmWidthBytes * BMP.bmHeight, _ PixelArray(0, 0, 0) End Sub Public Sub UnloadDIB(hDIB As Long) FreeImage_Unload hDIB End Sub '------------------------------------------------------------------------------' ' Event Handlers ' '------------------------------------------------------------------------------' Private Sub Class_Initialize() ChDir App.Path FreeImage_Initialise End Sub Private Sub Class_Terminate() FreeImage_DeInitialise End Sub '------------------------------------------------------------------------------' ' ' ' Chameleon Image Steganography v1.2 ' ' ' ' High Frequency Timer Class ' ' [RealTimer] ' ' ' '------------------------------------------------------------------------------' ' ' ' Copyright (C) 2003 Mark David Gan ' ' ' '------------------------------------------------------------------------------' Option Explicit '------------------------------------------------------------------------------' ' Windows Timer Function Declarations ' '------------------------------------------------------------------------------' Private Declare Function QueryPerformanceCounter _ Lib "kernel32" (lpPerformanceCount As Currency) As Long Private Declare Function QueryPerformanceFrequency _ Lib "kernel32" (lpFrequency As Currency) As Long '------------------------------------------------------------------------------' ' Private Variables ' '------------------------------------------------------------------------------' Private m_Elapsed As Currency Private m_Frequency As Currency Private m_Start As Currency Private m_Stop As Currency Private m_Supported As Boolean '------------------------------------------------------------------------------' ' Public Properties ' '------------------------------------------------------------------------------' Public Property Get CounterSupported() As Boolean CounterSupported = m_Supported End Property Public Property Get Frequency() As Currency Frequency = m_Frequency End Property Public Property Get ElapsedTime() As Currency ElapsedTime = m_Elapsed End Property Public Property Get ElapsedTimeInHours() As String ElapsedTimeInHours = Format$((m_Elapsed \ 360000) Mod 100, "#00:") & _ Format$((m_Elapsed \ 60000) Mod 60, "00:") & _ Format$((m_Elapsed \ 1000) Mod 60, "00.") & _ Format$(m_Elapsed Mod 1000, "000") End Property Public Property Get ElapsedTimeInMinutes() As String ElapsedTimeInMinutes = Format$((m_Elapsed \ 60000) Mod 100, "#00:") & _ Format$((m_Elapsed \ 1000) Mod 60, "00.") & _ Format$(m_Elapsed Mod 1000, "000") End Property Public Property Get ElapsedTimeInSeconds() As String ElapsedTimeInSeconds = Format$((m_Elapsed \ 1000) Mod 100, "#00.") & _ Format$(m_Elapsed Mod 1000, "000") End Property '------------------------------------------------------------------------------' ' Public Procedures ' '------------------------------------------------------------------------------' Public Sub Reset() QueryPerformanceCounter m_Start End Sub Public Sub Mark() QueryPerformanceCounter m_Stop m_Elapsed = ((m_Stop - m_Start) / m_Frequency) * 1000 End Sub '------------------------------------------------------------------------------'

Page 145: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps G-17

' Event Handlers ' '------------------------------------------------------------------------------' Private Sub Class_Initialize() m_Supported = QueryPerformanceFrequency(m_Frequency) QueryPerformanceCounter m_Start End Sub '------------------------------------------------------------------------------' ' ' ' Chameleon Image Steganography v1.2 ' ' ' ' Stegosystem Decoder Class ' ' [StegosystemDecoder] ' ' ' '------------------------------------------------------------------------------' ' ' ' Copyright (C) 2003 Mark David Gan ' ' ' '------------------------------------------------------------------------------' '------------------------------------------------------------------------------' ' ' ' Requires: FreeImageWrapper.cls ' ' FreeImage.dll ' ' ' '------------------------------------------------------------------------------' '------------------------------------------------------------------------------' ' ' ' Metadata Format: ' ' Password SHA Hash Value - String - 20 Bytes ' ' Data File Name - String - 255 Bytes ' ' Data File Date & Time - FILETIME - 8 Bytes ' ' Data File Size - Long - 4 Bytes ' ' Data File MD5 Checksum - String - 16 Bytes ' ' ' '------------------------------------------------------------------------------' Option Explicit '------------------------------------------------------------------------------' ' Windows API Structure Data Types ' '------------------------------------------------------------------------------' '[ 64-bit time structure ]' Private Type FILETIME dwLowDateTime As Long dwHighDateTime As Long End Type '[ multiple-field time structure ]' Private Type SYSTEMTIME wYear As Integer wMonth As Integer wDayOfWeek As Integer wDay As Integer wHour As Integer wMinute As Integer wSecond As Integer wMilliseconds As Integer End Type '------------------------------------------------------------------------------' ' Private Constants ' '------------------------------------------------------------------------------' '[ metadata bit length constants ]' Private Const STOREDPASSWORD_BITS As Long = 160 Private Const FILENAME_BITS As Long = 2040 Private Const FILEDATEHIGH_BITS As Long = 32 Private Const FILEDATELOW_BITS As Long = 32 Private Const FILESIZE_BITS As Long = 32 Private Const FILECHECKSUM_BITS As Long = 128 Private Const METADATA_BITS As Long = STOREDPASSWORD_BITS + _ FILENAME_BITS + _ FILEDATEHIGH_BITS + _ FILEDATELOW_BITS + _ FILESIZE_BITS + _ FILECHECKSUM_BITS '[ metadata byte length constants ]' Private Const STOREDPASSWORD_BYTES As Long = 20 Private Const FILENAME_BYTES As Long = 255 Private Const FILEDATEHIGH_BYTES As Long = 4 Private Const FILEDATELOW_BYTES As Long = 4 Private Const FILESIZE_BYTES As Long = 4 Private Const FILECHECKSUM_BYTES As Long = 16 Private Const METADATA_BYTES As Long = STOREDPASSWORD_BYTES + _ FILENAME_BYTES + _ FILEDATEHIGH_BYTES + _ FILEDATELOW_BYTES + _ FILESIZE_BYTES + _ FILECHECKSUM_BYTES '[ metadata progress report interval ]' Private Const METADATA_INTERVAL As Long = METADATA_BITS \ 100 '------------------------------------------------------------------------------' ' Windows API Function Declarations ' '------------------------------------------------------------------------------' Private Declare Function FileTimeToSystemTime _ Lib "kernel32" ( _ ByRef lpFileTime As FILETIME, _ ByRef lpSystemTime As SYSTEMTIME _ ) As Long Private Declare Function GetInputState Lib "user32" () As Long '------------------------------------------------------------------------------' ' Public Events ' '------------------------------------------------------------------------------' Public Event DataFileProgress(ByVal Processed As Long, ByVal Total As Long) Public Event MetadataProgress(ByVal Processed As Long, ByVal Total As Long) '------------------------------------------------------------------------------' ' Private Variables ' '------------------------------------------------------------------------------'

'[ freeimage wrapper object ]' Private Imager As FreeImageWrapper '[ dib handles ]' Private m_StegoImageDIB As Long '[ image properties ]' Private m_ImageBits() As Byte Private m_ImageWidth As Long Private m_ImageHeight As Long Private m_ImagePixels As Long '[ data file properties ]' Private m_DataFileName As String Private m_DataFileDate As Date Private m_DataFileTime As FILETIME Private m_DataFileSize As Long Private m_DataFileChecksum As String Private m_DataFileBits() As Byte '[ password hash value stored with metadata ]' Private m_StoredPassword As String '[ highest suitable address for metadata ]' Private m_MetadataMaxPosX As Long Private m_MetadataMaxPosY As Long '[ starting address for metadata (color channel, horizontal, vertical) ]' Private m_MetadataPosC As Long Private m_MetadataPosX As Long Private m_MetadataPosY As Long '[ current pixel position pointers (color channel, horizontal, vertical) ]' Private m_PosC As Long Private m_PosX(0 To 2) As Long Private m_PosY(0 To 2) As Long '[ abort process flag ]' Private m_Abort As Boolean '------------------------------------------------------------------------------' ' Public Properties ' '------------------------------------------------------------------------------' Public Property Get DataFileChecksum() As String DataFileChecksum = m_DataFileChecksum End Property Public Property Get DataFileDate() As Date DataFileDate = m_DataFileDate End Property Public Property Get DataFileName() As String DataFileName = m_DataFileName End Property Public Property Get DataFileSize() As Long DataFileSize = m_DataFileSize End Property Public Property Get StegoImageDIB() As Long StegoImageDIB = m_StegoImageDIB End Property Public Property Get StoredPassword() As String StoredPassword = m_StoredPassword End Property '------------------------------------------------------------------------------' ' Private Properties ' '------------------------------------------------------------------------------' Private Property Get Pixel0() As Long '[ color value of current pixel ]' Pixel0 = m_ImageBits(m_PosC, m_PosX(m_PosC), m_PosY(m_PosC)) End Property Private Property Get Pixel1() As Long '[ color value of middle-left pixel ]' Pixel1 = m_ImageBits(m_PosC, m_PosX(m_PosC) - 1, m_PosY(m_PosC)) End Property Private Property Get Pixel2() As Long '[ color value of top-left pixel ]' Pixel2 = m_ImageBits(m_PosC, m_PosX(m_PosC) - 1, m_PosY(m_PosC) - 1) End Property Private Property Get Pixel3() As Long '[ color value of top-middle pixel ]' Pixel3 = m_ImageBits(m_PosC, m_PosX(m_PosC), m_PosY(m_PosC) - 1) End Property Private Property Get Pixel4() As Long '[ color value of top-right pixel ]' Pixel4 = m_ImageBits(m_PosC, m_PosX(m_PosC) + 1, m_PosY(m_PosC) - 1) End Property '------------------------------------------------------------------------------' ' Public Procedures ' '------------------------------------------------------------------------------' Public Function Abort() m_Abort = True End Function Public Function Decode(ByVal PasswordHashMD5 As String) As Boolean Dim hBmp As Long '[ temporary bitmap handle ]' Dim Bits As Long '[ numeric value of bits extracted from pixel ]' Dim C As Long '[ pixel capacity ]' Dim MetadataCtr As Long '[ number of extracted metadata bits ]' Dim WriteCtr As Long '[ number of bits written on the data array ]' Dim Interval As Long '[ progress event interval ]' Dim Buffer As BitStream '[ buffer for extracted bits ]' '[ compute highest address in image where metadata can fit ]' m_MetadataMaxPosX = m_ImageWidth - METADATA_BITS m_MetadataMaxPosY = m_ImageHeight - 1 Do While (m_MetadataMaxPosX < 0)

Page 146: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps G-18

m_MetadataMaxPosX = m_ImageWidth + m_MetadataMaxPosX m_MetadataMaxPosY = m_MetadataMaxPosY - 1 Loop '[ set progress event interval ]' If m_DataFileSize < 200 Then Interval = 1 Else Interval = m_DataFileSize \ 100 End If '[ create temporary bitmap from the stego image dib ]' hBmp = Imager.CreateBitmapFromDIB(m_StegoImageDIB) '[ copy bitmap bits to pixel array ]' Imager.GetBitmapPixels hBmp, m_ImageBits '[ initialize prng with MD5 hash of password ]' InitializePRNG PasswordHashMD5 '[ select starting address for the metadata bits ]' m_MetadataPosC = Int(Rnd * 3) m_MetadataPosX = Int(Rnd * (m_MetadataMaxPosX + 1)) m_MetadataPosY = Int(Rnd * (m_MetadataMaxPosY + 1)) '[ initialize bit buffer ]' Set Buffer = New BitStream '[ clear and resize data array ]' ReDim m_DataFileBits(1 To m_DataFileSize) '[ reset counters ]' MetadataCtr = 0 WriteCtr = 0 ResetPixelPosition '[ start extraction ]' Do While WriteCtr < m_DataFileSize If m_Abort Then m_Abort = False GoTo Cleanup End If '[ if no metadata is in the buffer ]' If MetadataCtr < 1 Then '[ select a random color channel ]' SelectPixelChannel '[ initialize countdown variable for metadata ]' If (m_PosC = m_MetadataPosC) And _ (m_PosY(m_PosC) = m_MetadataPosY) And _ (m_PosX(m_PosC) = m_MetadataPosX) Then MetadataCtr = METADATA_BITS End If End If '[ get capacity ]' PerformCapacityEvaluation C If C > 0 Then '[ store extracted bits in the bit buffer ]' Bits = Pixel0 And ((2 ^ C) - 1) If MetadataCtr > 0 Then MetadataCtr = MetadataCtr - C If MetadataCtr < 0 Then C = Abs(MetadataCtr) Buffer.InsertBitsAtEnd (Bits And ((2 ^ C) - 1)), C MetadataCtr = 0 End If Else Buffer.InsertBitsAtEnd Bits, C End If Do While Buffer.Length > 7 WriteCtr = WriteCtr + 1 m_DataFileBits(WriteCtr) = CByte(Buffer.ExtractByte) Loop End If SelectPixelCoordinate If (WriteCtr Mod Interval) = 0 Then '[ signal progress ]' RaiseEvent DataFileProgress(WriteCtr, m_DataFileSize) DoEvents ElseIf GetInputState() Then '[ allow other processes to execute ]' DoEvents End If Loop '[ signal completion ]' If (WriteCtr Mod Interval) > 0 Then RaiseEvent DataFileProgress(WriteCtr, m_DataFileSize) End If '[ return whether all bits have been extracted ]' Decode = (WriteCtr >= m_DataFileSize) Cleanup: '[ cleanup temporary bitmap ]' Imager.DeleteBitmap hBmp Erase m_ImageBits End Function Public Sub DecodeMetadata(ByVal PasswordHashMD5 As String) Dim hBmp As Long '[ temporary bitmap handle ]' Dim Bits As Long '[ numeric value of bits extracted from pixel ]' Dim C As Long '[ pixel capacity ]' Dim Buffer As BitStream '[ buffer for extracted bits ]' Dim SysTime As SYSTEMTIME '[ temporary variable for file date and time ]' Dim MetadataCtr As Long '[ number of extracted metadata bits ]' '[ compute highest address in image where metadata can fit ]' m_MetadataMaxPosX = m_ImageWidth - METADATA_BITS m_MetadataMaxPosY = m_ImageHeight - 1 Do While (m_MetadataMaxPosX < 0) m_MetadataMaxPosX = m_ImageWidth + m_MetadataMaxPosX m_MetadataMaxPosY = m_MetadataMaxPosY - 1 Loop '[ create temporary bitmap from the stego image dib ]' hBmp = Imager.CreateBitmapFromDIB(m_StegoImageDIB) '[ copy bitmap bits to pixel array ]'

Imager.GetBitmapPixels hBmp, m_ImageBits '[ initialize prng with MD5 hash of password ]' InitializePRNG PasswordHashMD5 '[ select starting address for the metadata bits ]' m_MetadataPosC = Int(Rnd * 3) m_MetadataPosX = Int(Rnd * (m_MetadataMaxPosX + 1)) m_MetadataPosY = Int(Rnd * (m_MetadataMaxPosY + 1)) '[ initialize bit buffer ]' Set Buffer = New BitStream '[ reset counters ]' MetadataCtr = 0 '[ set pixel position to starting address of metadata bits ]' m_PosC = m_MetadataPosC m_PosX(m_PosC) = m_MetadataPosX m_PosY(m_PosC) = m_MetadataPosY '[ extract metadata bits From the stego image ]' Do While MetadataCtr < METADATA_BITS If m_Abort Then m_Abort = False GoTo Cleanup End If '[ get capacity ]' PerformCapacityEvaluation C If C > 0 Then '[ store extracted metadata bits in the bit buffer ]' Bits = Pixel0 And ((2 ^ C) - 1) Buffer.InsertBitsAtEnd Bits, C MetadataCtr = MetadataCtr + C If MetadataCtr > METADATA_BITS Then MetadataCtr = METADATA_BITS If (MetadataCtr Mod METADATA_INTERVAL) = 0 Then '[ report progress ]' RaiseEvent MetadataProgress(MetadataCtr, METADATA_BITS) DoEvents ElseIf GetInputState() Then '[ allow other processes to execute ]' DoEvents End If End If SelectPixelCoordinate Loop '[ report completion ]' If (MetadataCtr Mod METADATA_INTERVAL) > 0 Then RaiseEvent MetadataProgress(MetadataCtr, METADATA_BITS) End If On Error Resume Next '[ get information from metadata ]' m_StoredPassword = Buffer.ExtractString(STOREDPASSWORD_BYTES) m_DataFileName = Trim$(Buffer.ExtractString(FILENAME_BYTES)) m_DataFileTime.dwHighDateTime = Buffer.ExtractBits(FILEDATEHIGH_BITS) m_DataFileTime.dwLowDateTime = Buffer.ExtractBits(FILEDATELOW_BITS) FileTimeToSystemTime m_DataFileTime, SysTime m_DataFileDate = DateSerial(SysTime.wYear, SysTime.wMonth, SysTime.wDay) + _ TimeSerial(SysTime.wHour, SysTime.wMinute, SysTime.wSecond) m_DataFileSize = Buffer.ExtractBits(FILESIZE_BITS) m_DataFileChecksum = Buffer.ExtractString(FILECHECKSUM_BYTES) Cleanup: '[ cleanup temporary bitmap ]' Imager.DeleteBitmap hBmp Erase m_ImageBits End Sub Public Function LoadStegoImage(ByVal FileName As String) As Boolean '[ create new dib for stego image ]' m_StegoImageDIB = Imager.LoadDIB(FileName) If m_StegoImageDIB = 0 Then LoadStegoImage = False Else '[ get stego image dimensions ]' m_ImageWidth = Imager.GetWidth(m_StegoImageDIB) m_ImageHeight = Imager.GetHeight(m_StegoImageDIB) m_ImagePixels = m_ImageWidth * m_ImageHeight * 3 LoadStegoImage = (m_ImagePixels > METADATA_BITS) End If End Function Public Function SaveDataFile(ByVal FileName As String) As Boolean Dim FileIdx As Long On Error GoTo FileError '[ open data file ]' FileIdx = FreeFile Open FileName For Binary Access Write As FileIdx '[ copy data file bits from data array ]' Put FileIdx, , m_DataFileBits '[ close data file ]' Close FileIdx SaveDataFile = True Exit Function FileError: SaveDataFile = False End Function '------------------------------------------------------------------------------' ' Private Procedures ' '------------------------------------------------------------------------------' Private Sub InitializePRNG(ByVal Seed As String) Dim Ctr As Long Dim Tmp As Single Rnd -1 Randomize AscB(Left$(Seed, 1)) For Ctr = 2 To Len(Seed)

Page 147: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps G-19

Tmp = Rnd Rnd -1 Randomize Int(AscB(Mid$(Seed, Ctr, 1)) * Tmp) Next Ctr End Sub Private Sub PerformCapacityEvaluation(ByRef Capacity As Long) '[ if current pixel is not at topmost row, then compute capacity ]' If (m_PosY(m_PosC) > 0) Then Dim Dif1 As Long Dim Dif2 As Long Dim Dif3 As Long Dim Dif4 As Long Dim Avg As Long '[ get difference of adjacent pairs formed by pixel1, pixel2, & pixel3 ]' If m_PosX(m_PosC) > 0 Then Dif1 = Abs(Pixel3 - Pixel1) Dif2 = Abs(Pixel1 - Pixel2) Dif3 = Abs(Pixel2 - Pixel3) Else Dif1 = 0 Dif2 = 0 Dif3 = 0 End If '[ get difference of pixel3 and pixel4 ]' If m_PosX(m_PosC) < (m_ImageWidth - 1) Then Dif4 = Abs(Pixel3 - Pixel4) Else Dif4 = 0 End If '[ compute average difference in color intensity ]' Avg = Round((Dif1 + Dif2 + Dif3 + Dif4) / 4) '[ if c would not be equal to 0, compute hiding capacity of pixel ]' If Avg > 1 Then Dim C As Long Dim U As Long '[ compute capacity (base-2 logarithm of average difference) ]' C = Int(Log(Avg) / Log(2)) If C > 4 Then '[ compute upper boundary ]' If Pixel0 > 191 Then U = 5 Else U = 4 End If '[ limit capacity by the upper boundary ]' If C < U Then Capacity = C Else Capacity = U End If Else Capacity = C End If '[ if pixel in color channel of reserved area for metadata ]' ElseIf m_PosC = m_MetadataPosC Then If m_PosY(m_PosC) > m_MetadataMaxPosY Then Capacity = 1 ElseIf (m_PosY(m_PosC) = m_MetadataMaxPosY) And _ (m_PosX(m_PosC) >= m_MetadataMaxPosX) Then Capacity = 1 Else Capacity = 0 End If Else Capacity = 0 End If '[ if current pixel is at topmost row ]' Else '[ if pixel in color channel of reserved area for metadata ]' If m_PosC = m_MetadataPosC Then If m_PosY(m_PosC) > m_MetadataMaxPosY Then Capacity = 1 ElseIf (m_PosY(m_PosC) = m_MetadataMaxPosY) And _ (m_PosX(m_PosC) >= m_MetadataMaxPosX) Then Capacity = 1 Else Capacity = 0 End If Else Capacity = 0 End If End If End Sub Private Sub ResetPixelPosition() m_PosC = 0 Erase m_PosX Erase m_PosY End Sub Private Sub SelectPixelChannel() '[ select random color channel ]' m_PosC = Int(Rnd * 3) '[ if selected color channel is full, then select next ]' If m_PosY(m_PosC) >= m_ImageHeight Then m_PosC = (m_PosC + 1) Mod 3 If m_PosY(m_PosC) >= m_ImageHeight Then m_PosC = (m_PosC + 1) Mod 3 End If End If End Sub Private Sub SelectPixelCoordinate()

'[ increment horizontal position ]' m_PosX(m_PosC) = m_PosX(m_PosC) + 1 '[ increment vertical position ]' If m_PosX(m_PosC) >= m_ImageWidth Then m_PosX(m_PosC) = 0 m_PosY(m_PosC) = m_PosY(m_PosC) + 1 End If End Sub '------------------------------------------------------------------------------' ' Event Handlers ' '------------------------------------------------------------------------------' Private Sub Class_Initialize() Set Imager = New FreeImageWrapper m_StegoImageDIB = 0 m_Abort = False End Sub Private Sub Class_Terminate() On Error Resume Next Imager.UnloadDIB m_StegoImageDIB Set Imager = Nothing End Sub '------------------------------------------------------------------------------' ' ' ' Chameleon Image Steganography v1.2 ' ' ' ' Stegosystem Encoder Class ' ' [StegosystemEncoder] ' ' ' '------------------------------------------------------------------------------' ' ' ' Copyright (C) 2003 Mark David Gan ' ' ' '------------------------------------------------------------------------------' '------------------------------------------------------------------------------' ' ' ' Requires: FreeImageWrapper.cls ' ' FreeImage.dll ' ' ' '------------------------------------------------------------------------------' '------------------------------------------------------------------------------' ' ' ' Metadata Format: ' ' Password SHA Hash Value - String - 20 Bytes ' ' Data File Name - String - 255 Bytes ' ' Data File Date & Time - FILETIME - 8 Bytes ' ' Data File Size - Long - 4 Bytes ' ' Data File MD5 Checksum - String - 16 Bytes ' ' ' '------------------------------------------------------------------------------' Option Explicit '------------------------------------------------------------------------------' ' Windows API Structure Data Types ' '------------------------------------------------------------------------------' '[ 64-bit time structure ]' Private Type FILETIME dwLowDateTime As Long dwHighDateTime As Long End Type '[ multiple-field time structure ]' Private Type SYSTEMTIME wYear As Integer wMonth As Integer wDayOfWeek As Integer wDay As Integer wHour As Integer wMinute As Integer wSecond As Integer wMilliseconds As Integer End Type '------------------------------------------------------------------------------' ' Private Constants ' '------------------------------------------------------------------------------' '[ metadata bit length constants ]' Private Const STOREDPASSWORD_BITS As Long = 160 Private Const FILENAME_BITS As Long = 2040 Private Const FILEDATEHIGH_BITS As Long = 32 Private Const FILEDATELOW_BITS As Long = 32 Private Const FILESIZE_BITS As Long = 32 Private Const FILECHECKSUM_BITS As Long = 128 Private Const METADATA_BITS As Long = STOREDPASSWORD_BITS + _ FILENAME_BITS + _ FILEDATEHIGH_BITS + _ FILEDATELOW_BITS + _ FILESIZE_BITS + _ FILECHECKSUM_BITS '------------------------------------------------------------------------------' ' Windows API Function Declarations ' '------------------------------------------------------------------------------' Private Declare Function GetInputState Lib "user32" () As Long Private Declare Function SystemTimeToFileTime _ Lib "kernel32" ( _ lpSystemTime As SYSTEMTIME, _ lpFileTime As FILETIME _ ) As Long '------------------------------------------------------------------------------' ' Public Events ' '------------------------------------------------------------------------------' Public Event Progress(ByVal Processed As Long, ByVal Total As Long)

Page 148: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps G-20

'------------------------------------------------------------------------------' ' Private Variables ' '------------------------------------------------------------------------------' '[ freeimage wrapper object ]' Private Imager As FreeImageWrapper '[ dib handles ]' Private m_CoverImageDIB As Long Private m_StegoImageDIB As Long '[ image properties ]' Private m_ImageBits() As Byte Private m_ImageWidth As Long Private m_ImageHeight As Long Private m_ImagePixels As Long Private m_ImageCapacity As Long '[ data file properties ]' Private m_DataFileName As String Private m_DataFileDate As Date Private m_DataFileTime As FILETIME Private m_DataFileSize As Long Private m_DataFileChecksum As String Private m_DataFileBits() As Byte '[ highest suitable address for metadata ]' Private m_MetadataMaxPosX As Long Private m_MetadataMaxPosY As Long '[ starting address for metadata (color channel, horizontal, vertical) ]' Private m_MetadataPosC As Long Private m_MetadataPosX As Long Private m_MetadataPosY As Long '[ current pixel position pointers (color channel, horizontal, vertical) ]' Private m_PosC As Long Private m_PosX(0 To 2) As Long Private m_PosY(0 To 2) As Long '[ abort process flag ]' Private m_Abort As Boolean '------------------------------------------------------------------------------' ' Public Properties ' '------------------------------------------------------------------------------' Public Property Get CoverImageDIB() As Long CoverImageDIB = m_CoverImageDIB End Property Public Property Get DataFileDate() As Date DataFileDate = m_DataFileDate End Property Public Property Get DataFileName() As String DataFileName = m_DataFileName End Property Public Property Get DataFileSize() As Long DataFileSize = m_DataFileSize End Property Public Property Get ImageCapacity() As Long ImageCapacity = m_ImageCapacity End Property Public Property Get StegoImageDIB() As Long StegoImageDIB = m_StegoImageDIB End Property '------------------------------------------------------------------------------' ' Private Properties ' '------------------------------------------------------------------------------' Private Property Get Pixel0() As Long '[ color value of current pixel ]' Pixel0 = m_ImageBits(m_PosC, m_PosX(m_PosC), m_PosY(m_PosC)) End Property Private Property Let Pixel0(New_Pixel0 As Long) '[ color value of current pixel ]' m_ImageBits(m_PosC, m_PosX(m_PosC), m_PosY(m_PosC)) = New_Pixel0 End Property Private Property Get Pixel1() As Long '[ color value of middle-left pixel ]' Pixel1 = m_ImageBits(m_PosC, m_PosX(m_PosC) - 1, m_PosY(m_PosC)) End Property Private Property Get Pixel2() As Long '[ color value of top-left pixel ]' Pixel2 = m_ImageBits(m_PosC, m_PosX(m_PosC) - 1, m_PosY(m_PosC) - 1) End Property Private Property Get Pixel3() As Long '[ color value of top-middle pixel ]' Pixel3 = m_ImageBits(m_PosC, m_PosX(m_PosC), m_PosY(m_PosC) - 1) End Property Private Property Get Pixel4() As Long '[ color value of top-right pixel ]' Pixel4 = m_ImageBits(m_PosC, m_PosX(m_PosC) + 1, m_PosY(m_PosC) - 1) End Property Private Property Get Pixel5() As Long '[ color value of middle-right pixel ]' Pixel5 = m_ImageBits(m_PosC, m_PosX(m_PosC) + 1, m_PosY(m_PosC)) End Property Private Property Let Pixel5(New_Pixel5 As Long) '[ color value of middle-right pixel ]' If New_Pixel5 > 255 Then m_ImageBits(m_PosC, m_PosX(m_PosC) + 1, m_PosY(m_PosC)) = 255 ElseIf New_Pixel5 < 0 Then m_ImageBits(m_PosC, m_PosX(m_PosC) + 1, m_PosY(m_PosC)) = 0 Else m_ImageBits(m_PosC, m_PosX(m_PosC) + 1, m_PosY(m_PosC)) = New_Pixel5 End If End Property

Private Property Get Pixel6() As Long '[ color value of current bottom-right pixel ]' Pixel6 = m_ImageBits(m_PosC, m_PosX(m_PosC) + 1, m_PosY(m_PosC) + 1) End Property Private Property Let Pixel6(New_Pixel6 As Long) '[ color value of current bottom-right pixel ]' If New_Pixel6 > 255 Then m_ImageBits(m_PosC, m_PosX(m_PosC) + 1, m_PosY(m_PosC) + 1) = 255 ElseIf New_Pixel6 < 0 Then m_ImageBits(m_PosC, m_PosX(m_PosC) + 1, m_PosY(m_PosC) + 1) = 0 Else m_ImageBits(m_PosC, m_PosX(m_PosC) + 1, m_PosY(m_PosC) + 1) = New_Pixel6 End If End Property Private Property Get Pixel7() As Long '[ color value of bottom-middle pixel ]' Pixel7 = m_ImageBits(m_PosC, m_PosX(m_PosC), m_PosY(m_PosC) + 1) End Property Private Property Let Pixel7(New_Pixel7 As Long) '[ color value of bottom-middle pixel ]' If New_Pixel7 > 255 Then m_ImageBits(m_PosC, m_PosX(m_PosC), m_PosY(m_PosC) + 1) = 255 ElseIf New_Pixel7 < 0 Then m_ImageBits(m_PosC, m_PosX(m_PosC), m_PosY(m_PosC) + 1) = 0 Else m_ImageBits(m_PosC, m_PosX(m_PosC), m_PosY(m_PosC) + 1) = New_Pixel7 End If End Property Private Property Get Pixel8() As Long '[ color value of bottom-left pixel ]' Pixel8 = m_ImageBits(m_PosC, m_PosX(m_PosC) - 1, m_PosY(m_PosC) + 1) End Property Private Property Let Pixel8(New_Pixel8 As Long) '[ color value of bottom-left pixel ]' If New_Pixel8 > 255 Then m_ImageBits(m_PosC, m_PosX(m_PosC) - 1, m_PosY(m_PosC) + 1) = 255 ElseIf New_Pixel8 < 0 Then m_ImageBits(m_PosC, m_PosX(m_PosC) - 1, m_PosY(m_PosC) + 1) = 0 Else m_ImageBits(m_PosC, m_PosX(m_PosC) - 1, m_PosY(m_PosC) + 1) = New_Pixel8 End If End Property '------------------------------------------------------------------------------' ' Public Procedures ' '------------------------------------------------------------------------------' Public Function Abort() m_Abort = True End Function Public Function Encode(ByVal PasswordHashMD5 As String, _ ByVal PasswordHashSHA As String) As Boolean Dim hBmp As Long '[ temporary bitmap handle ]' Dim Bits As Long '[ numeric value of bits to be embedded ]' Dim C As Long '[ pixel capacity ]' Dim E As Long '[ embedding error ]' Dim MetadataCtr As Long '[ number of metadata bits in the buffer ]' Dim ReadCtr As Long '[ number of bytes read from the data file ]' Dim EmbedCtr As Long '[ number of bits embedded in the image ]' Dim PixelCtr As Long '[ number of pixels processed ]' Dim Interval As Long '[ progress event interval ]' Dim Buffer As BitStream '[ buffer for bits to be embedded ]' '[ compute highest address in image where metadata can fit ]' m_MetadataMaxPosX = m_ImageWidth - METADATA_BITS m_MetadataMaxPosY = m_ImageHeight - 1 Do While (m_MetadataMaxPosX < 0) m_MetadataMaxPosX = m_ImageWidth + m_MetadataMaxPosX m_MetadataMaxPosY = m_MetadataMaxPosY - 1 Loop '[ set progress event interval ]' If m_ImagePixels < 200 Then Interval = 1 Else Interval = m_ImagePixels \ 100 End If '[ create temporary bitmap from the cover image dib ]' hBmp = Imager.CreateBitmapFromDIB(m_CoverImageDIB) '[ copy bitmap bits to pixel array ]' Imager.GetBitmapPixels hBmp, m_ImageBits '[ initialize prng with MD5 hash of password ]' InitializePRNG PasswordHashMD5 '[ select starting address for the metadata bits ]' m_MetadataPosC = Int(Rnd * 3) m_MetadataPosX = Int(Rnd * (m_MetadataMaxPosX + 1)) m_MetadataPosY = Int(Rnd * (m_MetadataMaxPosY + 1)) '[ initialize bit buffer ]' Set Buffer = New BitStream '[ reset counters ]' MetadataCtr = 0 ReadCtr = 0 EmbedCtr = 0 PixelCtr = 0 ResetPixelPosition '[ start embedding ]' For PixelCtr = 1 To m_ImagePixels If m_Abort Then m_Abort = False GoTo Cleanup End If '[ if no metadata is in the buffer ]' If MetadataCtr < 1 Then '[ select a random color channel ]' SelectPixelChannel '[ insert metadata bits at the start of the bit buffer ]' If (m_PosC = m_MetadataPosC) And _ (m_PosY(m_PosC) = m_MetadataPosY) And _ (m_PosX(m_PosC) = m_MetadataPosX) Then

Page 149: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps G-21

MetadataCtr = METADATA_BITS Buffer.InsertStringAtTop m_DataFileChecksum Buffer.InsertBitsAtTop m_DataFileSize, FILESIZE_BITS Buffer.InsertBitsAtTop m_DataFileTime.dwLowDateTime, FILEDATELOW_BITS Buffer.InsertBitsAtTop m_DataFileTime.dwHighDateTime, FILEDATEHIGH_BITS Buffer.InsertStringAtTop m_DataFileName Buffer.InsertStringAtTop PasswordHashSHA End If End If '[ get capacity ]' PerformCapacityEvaluation C If C > 0 Then If Buffer.Length < C Then If ReadCtr < m_DataFileSize Then '[ insert data bits at the end of the bit buffer ]' ReadCtr = ReadCtr + 1 Buffer.InsertByteAtEnd m_DataFileBits(ReadCtr) Else '[ insert random bits at the end of the bit buffer ]' Buffer.InsertByteAtEnd Int(Rnd * 256) End If End If '[ select bits to embed ] ' Bits = Buffer.ExtractBits(C) '[ embed with minimum error ] ' E = PerformMinimumErrorReplacement(Bits, C) '[ diffuse embedding error ] ' PerformErrorDiffusion E '[ increment embedded bits counter ] ' EmbedCtr = EmbedCtr + C '[ decrement metadata counter ] ' If MetadataCtr > 0 Then MetadataCtr = MetadataCtr - C End If SelectPixelCoordinate If (PixelCtr Mod Interval) = 0 Then '[ report progress ]' RaiseEvent Progress(PixelCtr, m_ImagePixels) DoEvents ElseIf GetInputState() Then '[ allow other processes to execute ]' DoEvents End If Next PixelCtr '[ report completion ]' If (PixelCtr Mod Interval) > 0 Then RaiseEvent Progress(PixelCtr, m_ImagePixels) End If '[ update temporary bitmap with contents of pixel array ]' Imager.SetBitmapPixels hBmp, m_ImageBits '[ create stego dib from temporary bitmap ]' m_StegoImageDIB = Imager.CreateDIBFromBitmap(hBmp) '[ compute net image capacity in bytes ]' m_ImageCapacity = (EmbedCtr - METADATA_BITS) \ 8 '[ return whether all data file bits have been embedded ]' Encode = (m_ImageCapacity >= m_DataFileSize) Cleanup: '[ unload temporary bitmap ]' Imager.DeleteBitmap hBmp Erase m_ImageBits End Function Public Function LoadCoverImage(ByVal FileName As String) As Boolean '[ create new dib for cover image ]' m_CoverImageDIB = Imager.LoadDIB(FileName) If m_CoverImageDIB = 0 Then LoadCoverImage = False Else '[ get cover image dimensions ]' m_ImageWidth = Imager.GetWidth(m_CoverImageDIB) m_ImageHeight = Imager.GetHeight(m_CoverImageDIB) m_ImagePixels = m_ImageWidth * m_ImageHeight * 3 LoadCoverImage = (m_ImagePixels > METADATA_BITS) End If m_ImageCapacity = 0 End Function Public Function LoadDataFile(ByVal FileName As String, _ ByVal StoredFileName As String, _ ByVal StoredFileDate As Date, _ ByVal Checksum As String) Dim FileIdx As Long Dim SysTime As SYSTEMTIME '[ get data file stored file name ]' m_DataFileName = Format$(StoredFileName, "!" & String$(255, "@")) '[ get data file date and time ]' m_DataFileDate = StoredFileDate SysTime.wYear = Year(m_DataFileDate) SysTime.wMonth = Month(m_DataFileDate) SysTime.wDay = Day(m_DataFileDate) SysTime.wDayOfWeek = Weekday(m_DataFileDate) - 1 SysTime.wHour = Hour(m_DataFileDate) SysTime.wMinute = Minute(m_DataFileDate) SysTime.wSecond = Second(m_DataFileDate) SysTime.wMilliseconds = 0 SystemTimeToFileTime SysTime, m_DataFileTime '[ get data file checksum ]' m_DataFileChecksum = Checksum '[ open data file ]' FileIdx = FreeFile On Error GoTo FileError Open FileName For Binary Access Read As FileIdx '[ get data file size ]' m_DataFileSize = LOF(FileIdx)

'[ copy data file bits to data array ]' ReDim m_DataFileBits(1 To m_DataFileSize) Get FileIdx, , m_DataFileBits '[ close data file ]' Close FileIdx LoadDataFile = True Exit Function FileError: LoadDataFile = False End Function Public Function SaveStegoImage(ByVal FileName As String, _ ByVal Format As FREE_IMAGE_FORMAT) As Boolean SaveStegoImage = Imager.SaveDIB(m_StegoImageDIB, FileName, Format) End Function '------------------------------------------------------------------------------' ' Private Procedures ' '------------------------------------------------------------------------------' Private Sub InitializePRNG(ByVal Seed As String) Dim Ctr As Long Dim Tmp As Single Rnd -1 Randomize AscB(Left$(Seed, 1)) For Ctr = 2 To Len(Seed) Tmp = Rnd Rnd -1 Randomize Int(AscB(Mid$(Seed, Ctr, 1)) * Tmp) Next Ctr End Sub Private Sub PerformCapacityEvaluation(ByRef Capacity As Long) '[ if current pixel is not at topmost row, then compute capacity ]' If (m_PosY(m_PosC) > 0) Then Dim Dif1 As Long Dim Dif2 As Long Dim Dif3 As Long Dim Dif4 As Long Dim Avg As Long '[ get difference of adjacent pairs formed by pixel1, pixel2, & pixel3 ]' If m_PosX(m_PosC) > 0 Then Dif1 = Abs(Pixel3 - Pixel1) Dif2 = Abs(Pixel1 - Pixel2) Dif3 = Abs(Pixel2 - Pixel3) Else Dif1 = 0 Dif2 = 0 Dif3 = 0 End If '[ get difference of pixel3 and pixel4 ]' If m_PosX(m_PosC) < (m_ImageWidth - 1) Then Dif4 = Abs(Pixel3 - Pixel4) Else Dif4 = 0 End If '[ compute average difference in color intensity ]' Avg = Round((Dif1 + Dif2 + Dif3 + Dif4) / 4) '[ if c would not be equal to 0, compute hiding capacity of pixel ]' If Avg > 1 Then Dim C As Long Dim U As Long '[ compute capacity (base-2 logarithm of average difference) ]' C = Int(Log(Avg) / Log(2)) If C > 4 Then '[ compute upper boundary ]' If Pixel0 > 191 Then U = 5 Else U = 4 End If '[ limit capacity by the upper boundary ]' If C < U Then Capacity = C Else Capacity = U End If Else Capacity = C End If '[ if pixel in color channel of reserved area for metadata ]' ElseIf m_PosC = m_MetadataPosC Then If m_PosY(m_PosC) > m_MetadataMaxPosY Then Capacity = 1 ElseIf (m_PosY(m_PosC) = m_MetadataMaxPosY) And _ (m_PosX(m_PosC) >= m_MetadataMaxPosX) Then Capacity = 1 Else Capacity = 0 End If Else Capacity = 0 End If '[ if current pixel is at topmost row ]' Else '[ if pixel in color channel of reserved area for metadata ]' If m_PosC = m_MetadataPosC Then If m_PosY(m_PosC) > m_MetadataMaxPosY Then Capacity = 1 ElseIf (m_PosY(m_PosC) = m_MetadataMaxPosY) And _ (m_PosX(m_PosC) >= m_MetadataMaxPosX) Then Capacity = 1 Else Capacity = 0 End If

Page 150: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps G-22

Else Capacity = 0 End If End If End Sub Private Sub PerformErrorDiffusion(ByVal EmbeddingError As Long) If EmbeddingError > 3 Then Dim E As Long '[ get fraction of embedding error ]' E = EmbeddingError \ 4 '[ distribute embedding error among neighboring pixels ]' If m_PosY(m_PosC) < (m_ImageHeight - 1) Then If m_PosX(m_PosC) < (m_ImageWidth - 1) Then Pixel5 = Pixel5 - E Pixel6 = Pixel6 - E End If Pixel7 = Pixel7 - E If m_PosX(m_PosC) > 0 Then Pixel8 = Pixel8 - E End If ElseIf m_PosX(m_PosC) < (m_ImageWidth - 1) Then Pixel5 = Pixel5 - E End If End If End Sub Private Function PerformMinimumErrorReplacement(ByVal Bits As Long, _ ByVal Capacity As Long) Dim Mask As Long Dim Value0 As Long Dim Value1 As Long Dim Value2 As Long Dim Error1 As Long Dim Error2 As Long Value0 = Pixel0 '[ compute new color value with rightmost Unreplaced bit set to 0 ]' Mask = Not ((2 ^ (Capacity + 1)) - 1) Value1 = (Value0 And Mask) Or Bits Error1 = Value1 - Value0 '[ compute new color value with rightmost Unreplaced bit set to 1 ]' Value2 = Value1 Or (2 ^ Capacity) Error2 = Value2 - Value0 '[ select color value with less embedding Error ]' If Abs(Error1) < Abs(Error2) Then Pixel0 = Value1 PerformMinimumErrorReplacement = Error1 Else Pixel0 = Value2 PerformMinimumErrorReplacement = Error2 End If End Function Private Sub ResetPixelPosition() m_PosC = 0 Erase m_PosX Erase m_PosY End Sub Private Sub SelectPixelChannel() '[ select random color channel ]' m_PosC = Int(Rnd * 3) '[ if selected color channel is full, then select next ]' If m_PosY(m_PosC) >= m_ImageHeight Then m_PosC = (m_PosC + 1) Mod 3 If m_PosY(m_PosC) >= m_ImageHeight Then m_PosC = (m_PosC + 1) Mod 3 End If End If End Sub Private Sub SelectPixelCoordinate() '[ increment horizontal position ]' m_PosX(m_PosC) = m_PosX(m_PosC) + 1 '[ if x exceeds width, then increment vertical position and reset x ]' If m_PosX(m_PosC) >= m_ImageWidth Then m_PosX(m_PosC) = 0 m_PosY(m_PosC) = m_PosY(m_PosC) + 1 End If End Sub '------------------------------------------------------------------------------' ' Event Handlers ' '------------------------------------------------------------------------------' Private Sub Class_Initialize() Set Imager = New FreeImageWrapper m_CoverImageDIB = 0 m_StegoImageDIB = 0 m_ImageCapacity = 0 m_DataFileSize = 0 m_Abort = False End Sub Private Sub Class_Terminate() On Error Resume Next Imager.UnloadDIB m_CoverImageDIB Imager.UnloadDIB m_StegoImageDIB Set Imager = Nothing End Sub

'------------------------------------------------------------------------------' ' ' ' Chameleon Image Steganography v1.2 ' ' ' ' Custom Button User Control ' ' [CustomButton] ' ' ' '------------------------------------------------------------------------------' ' ' ' Copyright (C) 2003 Mark David Gan ' ' ' '------------------------------------------------------------------------------' '------------------------------------------------------------------------------' ' ' ' Requires: modCustomButton.bas ' ' ' '------------------------------------------------------------------------------' Option Explicit '------------------------------------------------------------------------------' ' Windows API Structure Data Types ' '------------------------------------------------------------------------------' '[ pixel coordinates structure ]' Private Type POINTAPI X As Long Y As Long End Type '[ rectangular coordinates structure ]' Private Type RECT Left As Long top As Long Right As Long Bottom As Long End Type '[ font layout information ]' Private Type TEXTMETRIC tmHeight As Long tmAscent As Long tmDescent As Long tmInternalLeading As Long tmExternalLeading As Long tmAveCharWidth As Long tmMaxCharWidth As Long tmWeight As Long tmOverhang As Long tmDigitizedAspectX As Long tmDigitizedAspectY As Long tmFirstChar As Byte tmLastChar As Byte tmDefaultChar As Byte tmBreakChar As Byte tmItalic As Byte tmUnderlined As Byte tmStruckOut As Byte tmPitchAndFamily As Byte tmCharSet As Byte End Type '------------------------------------------------------------------------------' ' Public Enumerated Data Types ' '------------------------------------------------------------------------------' '[ mask style enumeration ]' Public Enum cbtnMaskStyleConstants cbtnMaskStyleNone = 0 cbtnMaskStyleAuto = 1 cbtnMaskStyleCustom = 2 End Enum '[ Button State Enumeration ]' Public Enum cbtnStateConstants cbtnStateNormal = 0 cbtnStateHover = 1 cbtnStatePressed = 2 End Enum '------------------------------------------------------------------------------' ' Windows API Constants ' '------------------------------------------------------------------------------' '[ constants for "DrawEdge" function "edge" parameter ]' Private Const BDR_INNER As Long = &HC Private Const BDR_OUTER As Long = &H3 Private Const BDR_RAISED As Long = &H5 Private Const BDR_RAISEDINNER As Long = &H4 Private Const BDR_RAISEDOUTER As Long = &H1 Private Const BDR_SUNKEN As Long = &HA Private Const BDR_SUNKENINNER As Long = &H8 Private Const BDR_SUNKENOUTER As Long = &H2 '[ constants for "DrawEdge" function "edge" parameter ]' Private Const EDGE_BUMP As Long = (BDR_RAISEDOUTER + BDR_SUNKENINNER) Private Const EDGE_ETCHED As Long = (BDR_SUNKENOUTER + BDR_RAISEDINNER) Private Const EDGE_RAISED As Long = (BDR_RAISEDOUTER + BDR_RAISEDINNER) Private Const EDGE_SUNKEN As Long = (BDR_SUNKENOUTER + BDR_SUNKENINNER) '[ constants for "DrawEdge" function "grfFlags" parameter ]' Private Const BF_LEFT As Long = &H1 Private Const BF_BOTTOM As Long = &H8 Private Const BF_RIGHT As Long = &H4 Private Const BF_TOP As Long = &H2 Private Const BF_RECT As Long = (BF_LEFT + BF_TOP + BF_RIGHT + BF_BOTTOM) '[ constants for "DrawStatePic" function "flags" parameter ]' '[ constants for "DrawStateTxt" function "flags" parameter ]' Private Const DSS_NORMAL As Long = &H0 Private Const DSS_DISABLED As Long = &H20 '[ constants for "DrawStatePic" function "flags" parameter ]' '[ constants for "DrawStateTxt" function "flags" parameter ]' Private Const DST_PREFIXTEXT As Long = &H2 Private Const DST_ICON As Long = &H3 Private Const DST_BITMAP As Long = &H4 '[ constants for "SetBkMode" function "nBkMode" parameter ]' Private Const BACKMODE_OPAQUE As Long = 0 Private Const BACKMODE_TRANSPARENT As Long = 1 '------------------------------------------------------------------------------' ' Windows API Function Declarations '

Page 151: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps G-23

'------------------------------------------------------------------------------' Private Declare Function BitBlt _ Lib "gdi32" ( _ ByVal hDestDC As Long, _ ByVal X As Long, _ ByVal Y As Long, _ ByVal nWidth As Long, _ ByVal nHeight As Long, _ ByVal hSrcDC As Long, _ ByVal xSrc As Long, _ ByVal ySrc As Long, _ ByVal dwRop As Long _ ) As Long Private Declare Function CreateCompatibleBitmap _ Lib "gdi32" ( _ ByVal hDC As Long, _ ByVal nWidth As Long, _ ByVal nHeight As Long _ ) As Long Private Declare Function CreateCompatibleDC _ Lib "gdi32" (ByVal hDC As Long) As Long Private Declare Function CreateFont _ Lib "gdi32" Alias "CreateFontA" ( _ ByVal nHeight As Long, _ ByVal nWidth As Long, _ ByVal nEscapement As Long, _ ByVal nOrientation As Long, _ ByVal fnWeight As Long, _ ByVal fdwItalic As Long, _ ByVal fdwUnderline As Long, _ ByVal fdwStrikeOut As Long, _ ByVal fdwCharSet As Long, _ ByVal fdwOutputPrecision As Long, _ ByVal fdwClipPrecision As Long, _ ByVal fdwQuality As Long, _ ByVal fdwPitchAndFamily As Long, _ ByVal lpszFace As String _ ) As Long Private Declare Function CreateSolidBrush _ Lib "gdi32" (ByVal crColor As Long) As Long Private Declare Function DeleteDC Lib "gdi32" (ByVal hDC As Long) As Long Private Declare Function DeleteObject _ Lib "gdi32" (ByVal hObject As Long) As Long Private Declare Function DrawEdge _ Lib "user32" ( _ ByVal hDC As Long, _ ByRef qrc As RECT, _ ByVal edge As Long, _ ByVal grfFlags As Long _ ) As Long Private Declare Function DrawFocusRect _ Lib "user32" ( _ ByVal hDC As Long, _ lpRect As RECT _ ) As Long Private Declare Function DrawStatePic _ Lib "user32" Alias "DrawStateA" ( _ ByVal hDC As Long, _ ByVal hBrush As Long, _ ByVal lpDrawStateProc As Long, _ ByVal lParam As Long, _ ByVal wParam As Long, _ ByVal X As Long, _ ByVal Y As Long, _ ByVal cx As Long, _ ByVal cy As Long, _ ByVal Flags As Long _ ) As Long Private Declare Function DrawStateTxt _ Lib "user32" Alias "DrawStateA" ( _ ByVal hDC As Long, _ ByVal hBrush As Long, _ ByVal lpDrawStateProc As Long, _ ByVal lString As String, _ ByVal wParam As Long, _ ByVal X As Long, _ ByVal Y As Long, _ ByVal cx As Long, _ ByVal cy As Long, _ ByVal Flags As Long _ ) As Long Private Declare Function FillRect _ Lib "user32" ( _ ByVal hDC As Long, _ lpRect As RECT, _ ByVal hBrush As Long _ ) As Long Private Declare Function GetPixel _ Lib "gdi32" ( _ ByVal hDC As Long, _ ByVal X As Long, _ ByVal Y As Long _ ) As Long Private Declare Function GetTextMetrics _ Lib "gdi32" Alias "GetTextMetricsA" ( _ ByVal hDC As Long, _ lpMetrics As TEXTMETRIC _ ) As Long Private Declare Sub OleTranslateColor _ Lib "oleaut32.dll" ( _ ByVal clr As Long, _ ByVal hpal As Long, _ ByRef lpcolorref As Long) Private Declare Function SelectObject _ Lib "gdi32" ( _ ByVal hDC As Long, _ ByVal hObject As Long _ ) As Long Private Declare Function SetBkColor _ Lib "gdi32" ( _ ByVal hDC As Long, _ ByVal crColor As Long _ ) As Long Private Declare Function SetBkMode _ Lib "gdi32" ( _ ByVal hDC As Long, _ ByVal nBkMode As Long _ ) As Long Private Declare Function SetPixel _

Lib "gdi32" ( _ ByVal hDC As Long, _ ByVal X As Long, _ ByVal Y As Long, _ ByVal crColor As Long _ ) As Long Private Declare Function SetTextColor _ Lib "gdi32" ( _ ByVal hDC As Long, _ ByVal crColor As Long _ ) As Long '------------------------------------------------------------------------------' ' Public Events ' '------------------------------------------------------------------------------' Public Event Click() Public Event KeyDown(KeyCode As Integer, Shift As Integer) Public Event KeyUp(KeyCode As Integer, Shift As Integer) Public Event MouseDown(Button As Integer, Shift As Integer, X As Single, _ Y As Single) Public Event MouseHover() Public Event MouseLeave() Public Event MouseMove(Button As Integer, Shift As Integer, X As Single, _ Y As Single) Public Event MouseUp(Button As Integer, Shift As Integer, X As Single, _ Y As Single) '------------------------------------------------------------------------------' ' Private Variables ' '------------------------------------------------------------------------------' Private m_Alignment As AlignmentConstants Private m_Caption As String Private m_GotFocus As Boolean Private m_MaskStyle As cbtnMaskStyleConstants Private m_OldWndProc As Long Private m_Padding As Long Private m_Picture As StdPicture Private m_PictureOffset As Long Private m_State As cbtnStateConstants '------------------------------------------------------------------------------' ' Public Properties ' '------------------------------------------------------------------------------' Public Property Get AccessKeys() As String AccessKeys = UserControl.AccessKeys End Property Public Property Let AccessKeys(New_AccessKeys As String) If UserControl.AccessKeys <> New_AccessKeys Then UserControl.AccessKeys = New_AccessKeys PropertyChanged "AccessKeys" PaintControl End If End Property Public Property Get Alignment() As AlignmentConstants Alignment = m_Alignment End Property Public Property Let Alignment(New_Alignment As AlignmentConstants) If m_Alignment <> New_Alignment Then m_Alignment = New_Alignment PropertyChanged "Alignment" PaintControl End If End Property Public Property Get BackColor() As OLE_COLOR BackColor = UserControl.BackColor End Property Public Property Let BackColor(New_BackColor As OLE_COLOR) If UserControl.BackColor <> New_BackColor Then UserControl.BackColor = New_BackColor PropertyChanged "BackColor" PaintControl End If End Property Public Property Get Caption() As String Caption = m_Caption End Property Public Property Let Caption(New_Caption As String) If m_Caption <> New_Caption Then m_Caption = New_Caption PropertyChanged "Caption" PaintControl End If End Property Public Property Get Enabled() As Boolean Enabled = UserControl.Enabled End Property Public Property Let Enabled(New_Enabled As Boolean) If UserControl.Enabled <> New_Enabled Then UserControl.Enabled = New_Enabled PropertyChanged "Enabled" PaintControl End If End Property Public Property Get Font() As StdFont Set Font = UserControl.Font End Property Public Property Set Font(New_Font As StdFont) Set UserControl.Font = New_Font PropertyChanged "Font" PaintControl End Property Public Property Get ForeColor() As OLE_COLOR ForeColor = UserControl.ForeColor End Property

Page 152: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps G-24

Public Property Let ForeColor(New_ForeColor As OLE_COLOR) If UserControl.ForeColor <> New_ForeColor Then UserControl.ForeColor = New_ForeColor PropertyChanged "ForeColor" PaintControl End If End Property Public Property Get hWnd() As Long hWnd = UserControl.hWnd End Property Public Property Get MaskColor() As OLE_COLOR MaskColor = UserControl.MaskColor End Property Public Property Let MaskColor(New_MaskColor As OLE_COLOR) If UserControl.MaskColor <> New_MaskColor Then UserControl.MaskColor = New_MaskColor PropertyChanged "MaskColor" PaintControl End If End Property Public Property Get MaskStyle() As cbtnMaskStyleConstants MaskStyle = m_MaskStyle End Property Public Property Let MaskStyle(New_MaskStyle As cbtnMaskStyleConstants) If m_MaskStyle <> New_MaskStyle Then m_MaskStyle = New_MaskStyle PropertyChanged "MaskStyle" PaintControl End If End Property Public Property Get Picture() As StdPicture Set Picture = m_Picture End Property Public Property Set Picture(New_Picture As StdPicture) Set m_Picture = New_Picture PropertyChanged "Picture" PaintControl End Property Public Property Get Padding() As Long Padding = m_Padding End Property Public Property Let Padding(New_Padding As Long) If m_Padding <> New_Padding Then m_Padding = New_Padding PropertyChanged "Padding" PaintControl End If End Property Public Property Get PictureOffset() As Long PictureOffset = m_PictureOffset End Property Public Property Let PictureOffset(New_PictureOffset As Long) If m_PictureOffset <> New_PictureOffset Then m_PictureOffset = New_PictureOffset PropertyChanged "PictureOffset" PaintControl End If End Property '------------------------------------------------------------------------------' ' Friend Properties ' '------------------------------------------------------------------------------' Friend Property Get OldWndProc() As Long OldWndProc = m_OldWndProc End Property Friend Property Let OldWndProc(ByVal New_OldWndProc As Long) m_OldWndProc = New_OldWndProc End Property Friend Property Get State() As cbtnStateConstants State = m_State End Property Friend Property Let State(ByVal New_State As cbtnStateConstants) If m_State <> New_State Then m_State = New_State PaintControl End If End Property '------------------------------------------------------------------------------' ' Public Procedures ' '------------------------------------------------------------------------------' Public Sub Press() On Error Resume Next If Extender.Visible Then If UserControl.Enabled Then UserControl.SetFocus DoEvents Call UserControl_Click End If End If End Sub Public Sub Refresh() PaintControl End Sub '------------------------------------------------------------------------------' ' Friend Procedures ' '------------------------------------------------------------------------------'

Friend Sub RaiseMouseLeaveEvent() RaiseEvent MouseLeave End Sub '------------------------------------------------------------------------------' ' Private Procedures ' '------------------------------------------------------------------------------' Private Sub DrawBorder(ByVal hDC As Long, ByRef tRect As RECT) Dim tRect2 As RECT tRect2.Left = tRect.Left + 1 tRect2.top = tRect.top + 1 tRect2.Right = tRect.Right - 1 tRect2.Bottom = tRect.Bottom - 1 Select Case m_State Case cbtnStateNormal: DrawEdge hDC, tRect, EDGE_ETCHED, BF_RECT Case cbtnStateHover: DrawEdge hDC, tRect2, BDR_RAISEDINNER, BF_RECT Case cbtnStatePressed: DrawEdge hDC, tRect2, BDR_SUNKENOUTER, BF_RECT End Select End Sub Private Sub DrawCaption(ByVal hDC As Long) If Len(Trim$(m_Caption)) = 0 Then Exit Sub Dim CapStr As String Dim CapWidth As Long Dim X As Long Dim Y As Long Dim Txt As TEXTMETRIC Dim hNewFont As Long Dim hOldFont As Long '[ get caption width without mnemonic character ]' CapStr = Replace(m_Caption, "&&", Chr$(254)) CapStr = Replace(CapStr, "&", vbNullString) CapStr = Replace(CapStr, Chr$(0), "&&") CapWidth = TextWidth(CapStr) '[ compute vertical position ]' Y = (UserControl.ScaleHeight - TextHeight(m_Caption)) \ 2 '[ compute horizontal position ]' If m_Alignment = vbLeftJustify Then If m_Picture Is Nothing Then X = m_Padding Else X = m_Padding + m_PictureOffset + _ ScaleX(m_Picture.Width, vbHimetric, vbPixels) End If ElseIf m_Alignment = vbRightJustify Then X = UserControl.ScaleWidth - CapWidth - m_Padding ElseIf m_Alignment = vbCenter Then If m_Picture Is Nothing Then X = (UserControl.ScaleWidth - CapWidth) \ 2 Else X = (UserControl.ScaleWidth - CapWidth + m_PictureOffset + _ ScaleX(m_Picture.Width, vbHimetric, vbPixels)) \ 2 End If End If '[ adjust text position according to state ]' If m_State = cbtnStatePressed Then X = X + 1 Y = Y + 1 End If '[ set font ]' GetTextMetrics UserControl.hDC, Txt hNewFont = CreateFont(Txt.tmHeight, 0, 0, 0, Txt.tmWeight, Txt.tmItalic, _ Txt.tmUnderlined, Txt.tmStruckOut, 0, 0, 16, 0, 0, _ UserControl.Font.Name) hOldFont = SelectObject(ByVal hDC, hNewFont) '[ set text color and background ]' SetTextColor hDC, TranslateColor(UserControl.ForeColor) SetBkMode hDC, BACKMODE_TRANSPARENT '[ paint Caption ]' If UserControl.Enabled Then DrawStateTxt hDC, 0, 0, m_Caption, Len(m_Caption), X, Y, 0, 0, _ DST_PREFIXTEXT Or DSS_NORMAL Else DrawStateTxt hDC, 0, 0, m_Caption, Len(m_Caption), X, Y, 0, 0, _ DST_PREFIXTEXT Or DSS_DISABLED End If '[ restore original font ]' SelectObject hDC, hOldFont DeleteObject hNewFont End Sub Private Sub DrawFocusRectangle(ByVal hDC As Long, ByRef tRect As RECT) Dim tRect2 As RECT tRect2.Left = tRect.Left + 3 tRect2.top = tRect.top + 3 tRect2.Right = tRect.Right - 4 tRect2.Bottom = tRect.Bottom - 4 SetTextColor hDC, vbBlack DrawFocusRect hDC, tRect2 End Sub Private Sub DrawPicture(ByVal hDC As Long) If m_Picture Is Nothing Then Exit Sub Dim CapStr As String Dim CapWidth As Long Dim offset As Long Dim X As Long Dim Y As Long Dim PicWidth As Long Dim PicHeight As Long Dim hDCTmp As Long Dim MaskClr As Long Dim BackClr As Long Dim Ctr1 As Long Dim Ctr2 As Long '[ get caption width and offset ]' If Len(Trim$(m_Caption)) = 0 Then CapWidth = 0 offset = 0 Else '[ remove mnemonic characters from total width ]'

Page 153: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps G-25

CapStr = Replace(m_Caption, "&&", Chr$(254)) CapStr = Replace(CapStr, "&", vbNullString) CapStr = Replace(CapStr, Chr$(0), "&&") CapWidth = TextWidth(CapStr) offset = m_PictureOffset End If '[ get picture dimensions ]' PicWidth = UserControl.ScaleX(m_Picture.Width, vbHimetric, vbPixels) PicHeight = UserControl.ScaleY(m_Picture.Height, vbHimetric, vbPixels) '[ compute vertical position ]' Y = (UserControl.ScaleHeight - PicHeight) \ 2 '[ compute horizontal position ]' If m_Alignment = vbLeftJustify Then X = m_Padding ElseIf m_Alignment = vbRightJustify Then X = UserControl.ScaleWidth - m_Padding - CapWidth - PicWidth - offset ElseIf m_Alignment = vbCenter Then X = (UserControl.ScaleWidth - CapWidth - PicWidth - offset) \ 2 End If '[ adjust picture position according to state ]' If m_State = cbtnStatePressed Then X = X + 1 Y = Y + 1 End If '[ if icon ]' If m_Picture.Type = vbPicTypeIcon Then If UserControl.Enabled Then DrawStatePic hDC, 0, 0, m_Picture.Handle, 0, X, Y, 0, 0, _ DST_ICON Or DSS_NORMAL Else DrawStatePic hDC, 0, 0, m_Picture.Handle, 0, X, Y, 0, 0, _ DST_ICON Or DSS_DISABLED End If '[ else if bitmap ]' Else '[ create temporary dc for picture ]' hDCTmp = CreateCompatibleDC(ByVal hDC) DeleteObject SelectObject(ByVal hDCTmp, m_Picture.Handle) '[ if mask enabled ]' If m_MaskStyle <> cbtnMaskStyleNone Then '[ get mask color ]' If m_MaskStyle = cbtnMaskStyleAuto Then MaskClr = GetPixel(ByVal hDCTmp, 0, 0) Else MaskClr = TranslateColor(UserControl.MaskColor) End If BackClr = TranslateColor(UserControl.BackColor) '[ clear transparent pixels of picture ]' For Ctr2 = 0 To PicHeight For Ctr1 = 0 To PicWidth If GetPixel(ByVal hDCTmp, Ctr1, Ctr2) = MaskClr Then SetPixel hDCTmp, Ctr1, Ctr2, BackClr End If Next Ctr1 Next Ctr2 End If '[ paint picture ]' BitBlt hDC, X, Y, PicWidth, PicHeight, hDCTmp, 0, 0, vbSrcCopy '[ cleanup temporary dc ]' DeleteDC hDCTmp End If End Sub Private Sub PaintControl() Dim tRect As RECT Dim hDC As Long Dim hBmp As Long Dim hBrush As Long '[ compute control dimensions ]' tRect.Left = 0 tRect.top = 0 tRect.Right = UserControl.ScaleWidth tRect.Bottom = UserControl.ScaleHeight '[ create back buffer ]' hDC = CreateCompatibleDC(UserControl.hDC) hBmp = CreateCompatibleBitmap(UserControl.hDC, tRect.Right, tRect.Bottom) DeleteObject SelectObject(ByVal hDC, hBmp) '[ fill back buffer with background color ]' hBrush = CreateSolidBrush(TranslateColor(UserControl.BackColor)) FillRect hDC, tRect, hBrush DeleteObject hBrush '[ paint control on back buffer ]' DrawPicture hDC DrawCaption hDC DrawBorder hDC, tRect If m_GotFocus Then DrawFocusRectangle hDC, tRect End If '[ copy back buffer contents to Control ]' BitBlt UserControl.hDC, tRect.Left, tRect.top, tRect.Right, tRect.Bottom, _ hDC, 0, 0, vbSrcCopy '[ update display ]' DoEvents UserControl.Refresh '[ cleanup temporary resources ]' DeleteDC hDC DeleteObject hBmp End Sub Private Function TranslateColor(OLEColor As OLE_COLOR) As Long OleTranslateColor OLEColor, UserControl.Palette, TranslateColor End Function '------------------------------------------------------------------------------' ' Control Event Handlers ' '------------------------------------------------------------------------------' Private Sub UserControl_AccessKeyPress(KeyAscii As Integer)

Call UserControl_Click End Sub Private Sub UserControl_AmbientChanged(PropertyName As String) PaintControl End Sub Private Sub UserControl_Click() RaiseEvent Click End Sub Private Sub UserControl_GotFocus() m_GotFocus = True PaintControl End Sub Private Sub UserControl_Hide() modCustomButton.StopSubclassingButton Me End Sub Private Sub UserControl_Initialize() m_GotFocus = False m_State = cbtnStateNormal m_OldWndProc = 0 End Sub Private Sub UserControl_InitProperties() m_Alignment = vbCenter m_Caption = Replace(Extender.Name, UserControl.Name, "Button") m_MaskStyle = cbtnMaskStyleAuto m_Padding = 10 Set m_Picture = Nothing m_PictureOffset = 10 UserControl.AccessKeys = vbNullString UserControl.BackColor = vbButtonFace UserControl.Enabled = True Set UserControl.Font = Ambient.Font UserControl.ForeColor = vbButtonText UserControl.MaskColor = vbWhite End Sub Private Sub UserControl_KeyDown(KeyCode As Integer, Shift As Integer) If (KeyCode = vbKeyReturn) Then '[ simulate click ]' RaiseEvent Click ElseIf (KeyCode = vbKeySpace) And (m_State <> cbtnStatePressed) Then '[ simulate mouse down ]' m_State = cbtnStatePressed PaintControl ElseIf (KeyCode = vbKeyDown) Or (KeyCode = vbKeyRight) Then '[ select next control ]' SendKeys "{TAB}", True ElseIf (KeyCode = vbKeyUp) Or (KeyCode = vbKeyLeft) Then '[ select previous control ]' SendKeys "+{TAB}", True End If RaiseEvent KeyDown(KeyCode, Shift) End Sub Private Sub UserControl_KeyUp(KeyCode As Integer, Shift As Integer) If (KeyCode = vbKeySpace) And (m_State = cbtnStatePressed) Then '[ simulate click ]' m_State = cbtnStateNormal PaintControl RaiseEvent Click End If RaiseEvent KeyUp(KeyCode, Shift) End Sub Private Sub UserControl_LostFocus() m_GotFocus = False PaintControl End Sub Private Sub UserControl_MouseDown(Button As Integer, Shift As Integer, _ X As Single, Y As Single) If Button = vbLeftButton Then m_State = cbtnStatePressed PaintControl End If RaiseEvent MouseDown(Button, Shift, X, Y) End Sub Private Sub UserControl_MouseMove(Button As Integer, Shift As Integer, _ X As Single, Y As Single) If Ambient.UserMode Then RaiseEvent MouseMove(Button, Shift, X, Y) If (m_State <> cbtnStateHover) And (Button <> vbLeftButton) Then modCustomButton.TrackMouseLeaveEvent Me m_State = cbtnStateHover PaintControl RaiseEvent MouseHover End If End If End Sub Private Sub UserControl_MouseUp(Button As Integer, Shift As Integer, _ X As Single, Y As Single) m_State = cbtnStateNormal PaintControl RaiseEvent MouseUp(Button, Shift, X, Y) End Sub Private Sub UserControl_ReadProperties(PropBag As PropertyBag) With PropBag m_Alignment = .ReadProperty("Alignment", vbCenter) m_Caption = .ReadProperty("Caption", vbNullString) m_MaskStyle = .ReadProperty("MaskStyle", cbtnMaskStyleAuto)

Page 154: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps G-26

m_Padding = .ReadProperty("Padding", 10) Set m_Picture = .ReadProperty("Picture", Nothing) m_PictureOffset = .ReadProperty("PictureOffset", 6) UserControl.AccessKeys = .ReadProperty("AccessKeys", vbNullString) UserControl.BackColor = .ReadProperty("BackColor", vbButtonFace) UserControl.Enabled = .ReadProperty("Enabled", True) Set UserControl.Font = .ReadProperty("Font", Ambient.Font) UserControl.ForeColor = .ReadProperty("ForeColor", vbButtonText) UserControl.MaskColor = .ReadProperty("MaskColor", vbWhite) End With End Sub Private Sub UserControl_Resize() PaintControl End Sub Private Sub UserControl_Show() m_State = cbtnStateNormal PaintControl modCustomButton.StartSubclassingButton Me End Sub Private Sub UserControl_WriteProperties(PropBag As PropertyBag) With PropBag .WriteProperty "AccessKeys", UserControl.AccessKeys, vbNullString .WriteProperty "Alignment", m_Alignment, vbCenter .WriteProperty "BackColor", UserControl.BackColor, vbButtonFace .WriteProperty "Caption", m_Caption, vbNullString .WriteProperty "Enabled", UserControl.Enabled, True .WriteProperty "Font", UserControl.Font, Ambient.Font .WriteProperty "ForeColor", UserControl.ForeColor, vbButtonText .WriteProperty "MaskColor", UserControl.MaskColor, vbWhite .WriteProperty "MaskStyle", m_MaskStyle, cbtnMaskStyleAuto .WriteProperty "Padding", m_Padding, 10 .WriteProperty "Picture", m_Picture, Nothing .WriteProperty "PictureOffset", m_PictureOffset, 6 End With End Sub

Page 155: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps Bibliography

BIBLIOGRAPHY

[ANDE1998] R J Anderson & F A P Petitcolas (1998). ‘On The Limits of Steganography’, Special Issue on Copyright & Privacy Protection, IEEE Journal of Selected Areas in Communications, 16(4), pp 474-482.

[ANDE1999] R J Anderson & F A P Petitcolas (1999). ‘Information Hiding: An Annotated Bibliography’, Computer Laboratory, University of Cambridge, UK.

[BEND1996] W Bender et al (1996). ‘Techniques for Data Hiding’, IBM Systems Journal, 35(3&4), pp 313-336.

[BEND2000] W Bender et al (2000). ‘Applications for Data Hiding’, IBM Systems Journal, 39(3&4), pp 547-568.

[DAVE1995] P Davern (1995). ‘Steganography: Its History and Its Application to Computer Based Data Files’, Working Paper: CA-0795, School of Computer Applications, Dublin City University.

[FAST2002] Fast Search & Transfer, Inc. (2002). ‘About Us’, AlltheWeb. http://www.alltheweb.com/about/index.html.

[FRID1998] Jiri Fridrich (1998). Applications of Data Hiding in Digital Images, Tutorial for the ISPACS’98 Conference in Melbourne, Australia.

[FRID2000] Jiri Fridrich, R Du & M Long (2000). ‘Steganalysis of LSB Encoding in Color Images’, Air Force Research Laboratory, Air Force Material Command, USAF.

[FRID2002] Jessica Fridrich & M Goljan (2002). ‘Practical Steganalysis of Digital Images – State of the Art’, Air Force Research Laboratory, Air Force Material Command, USAF.

[FRID2002a] Jessica Fridrich, M Goljan & D Hogea (2002). ‘Attacking the OutGuess’, Air Force Research Laboratory, Air Force Material Command, USAF.

[HETZ2002] S Hetzl (2002). ‘A Survey of Steganography’.

Page 156: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps Bibliography

[JOHN1998] N F Johnson & S Jajodia (1998). ‘Exploring Steganography: Seeing the Unseen’, IEEE Computer, 31(2), pp 26-34.

[KAHN1996] D Kahn (1996). ‘The History of Steganography’, In: Information Hiding: First International Workshop (R Anderson, ed), Lecture Notes in Computer Science 1174, pp 1-5, Berlin: Springer-Verlag.

[KIRA2002] P S Kiran (2002). ‘Project Third Eye’, Webkclub.com. http://www.webkclub.com/tte/.

[KWAN2001] M Kwan (2001). ‘How SNOW Works’, The SNOW Home Page. http://www.darkside.com.au/snow/description.html.

[LEE1999] Y K Lee & L H Chen (1999). ‘An Adaptive Image Steganographic Model Based on Minimum-Error LSB Replacement’, Department of Computer and Information Science, National Chiao Tung University, Taiwan, ROC.

[LEE2000] Y K Lee & L H Chen (2000). ‘High Capacity Image Steganographic Model’, Department of Computer and Information Science, National Chiao Tung University, Taiwan, ROC.

[LEE2002] Y K Lee & L H Chen (2002). ‘Object-Based Image Steganography Using Affine Transformation’, Department of Computer and Information Science, National Chiao Tung University, Taiwan, ROC.

[LIN1999] E Lin & E Delp (1999). ‘A Review of Data Hiding in Digital Images’, Video and Image Processing Laboratory, School of Electrical and Computer Engineering, Purdue University.

[MARV1999] L M Marvel, C G Boncelet Jr & C T Retter (1999). ‘Spread Spectrum Image Steganography’, IEEE Transactions on Image Processing, 8(8), pp 1075-1083.

[MCCU2000] D McCullagh (2000). ‘Carnivore to Continue Munching’, Wired News. http://www.wired.com/news/print/0,1294,38618,00.html.

[MENE1996] A J Menezes, P C van Oorschot & S A Vanstone (1996). Handbook of Applied Cryptography, Boca Raton: CRC Press.

Page 157: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps Bibliography

[MOSK2000] I S Moskowitz, G E Longdon & L W Chang (2000). ‘A New Paradigm Hidden in Steganography’, Center for High Assurance Computer Systems, Naval Research Laboratory, Washington DC.

[NEOB2002] NeoByte Solutions (2002). ‘Invisible Secrets 2002’, NeoByte Solutions Website. http://www.neobytesolutions.com/invsecr/.

[PAIZ1999] F J Paiz (1999). ‘Tartan Threads: A Method for the Real-time Digital Recognition of Secure Documents in Ink Jet Printers’, Department of Electrical Engineering and Computer Science, MIT.

[PETI1999] F A P Petitcolas, R J Anderson & M G Kuhn (1999). ‘Information Hiding–A Survey’, Proceedings of the IEEE, 87(7), pp 1062-1078.

[PFAF1995] B Pfaffenberger & D Wall (1995). Que’s Computer and Internet Dictionary, 6th ed, Indianapolis: Que Corporation.

[PFIT1996] B Pfitzmann (1996). ‘Information Hiding Terminology’, In: Information Hiding: First International Workshop (R Anderson, ed), Lecture Notes in Computer Science 1174, pp 347-350, Berlin: Springer-Verlag.

[PLEM2001] S Pleming (2001). ‘Muslim Extremists Utilize Web Encryption’, TechTV. http://www.techtv.com/news/print/0,23102,3310112,00.html.

[PRES1992] R S Pressman (1992). Software Engineering: A Practitioner’s Approach, 3rd ed, International ed, Singapore: McGraw-Hill.

[PROV2001] N Provos (2001). ‘Defending Against Statistical Steganalysis’, 10th USENIX Security Symposium, Washington, DC.

[PROV2001a] N Provos & P Honeyman (2001). ‘Detecting Steganographic Content on the Internet’, CITI Technical Report 01-11, Center for Information Technology Integration, University of Michigan.

[PROV2002] N Provos (2002). OutGuess Website. http://www.outguess.org.

[SCHM2001] G Schmid (2001). Report on the Existence of a Global System for the Interception of Private and Commercial Communications, Session Document: A5-0264/2001-Par1, Temporary Committee on the ECHELON Interception System, European Parliament.

Page 158: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps Bibliography

[SIEB2001] D Sieberg (2001). ‘Bin Laden exploits technology to suit his needs’, CNN.com. http://www.cnn.com/2001/US/09/20/inv.terrorist.search/.

[STEG2002] Steganos GmbH (2002). ‘Steganos Security Suite 4’, Steganos GmbH Home. http://www.steganos.com/en/sss/index.htm.

[TYSO2001] J Tyson (2001). ‘How Carnivore Works’, Howstuffworks. http://www.howstuffworks.com/carnivore.htm/printable.

[WEST2001] Andreas Westfeld (2001). ‘F5–A Steganographic Algorithm’, Presentation slides for the 4th Intenational Workshop on Information Hiding, Technische Universität Dresden.

Page 159: Thesis Document

Adaptive Digital Steganography for True-Color Bitmaps Curriculum Vitae

791 G. Del Pilar Street, Caridad, Cavite City Philippines 4100

Home: (046) 431-0034 Mobile: (919) 635-6479 E-mail: [email protected]

Mark David C. Gan

Education 2001 up to present STI College Bacoor

Bachelor of Science in Computer Science • Became the first Vice President for Internal Affairs of STI BITS (STI Bacoor

Information Technology Society) in 2001 • Computerized the 2002 Officer Elections of STI BITS • Organized and facilitated the 2003 STI Bacoor Programming Competition • Consistent Dean’s Honor List qualifier

1999–2001 STI College Bacoor

Associate in Computer Technology • Graduated With Honors • Student of the Year for the Batch of 2001 • Guaranteed Hire Program (GHP) qualifier • Consistent Dean’s Honor List qualifier

Awards 2002

ACM Asia Programming Contest - Manila Site • Twentieth Place

2002

STI “INTO Programming” - Senior Level Computer Programming Contest • Third Place in National Competition

2001

STI “Tagisan ng Talino” - Senior Level Computer Quiz and Computer Programming Contest • Third Place in National Competition

1999 and 2000

STI “Tagisan ng Talino” - Junior Level Computer Quiz and Computer Programming Contest • National Champion