I wrote these
Autoit3 code examples to illustrate some of
the ways that steganography (hiding data in other data, or as I like to call it
"hiding your stuff in other stuff so people can't find your stuff") can be done.
These sorts of techniques can be of great use in passing messages without others
knowing, in anti-forensics activities, or as covert command and control channels
for botnets (as I plan to study for my final project in the malware class I'm
enrolled in). There are probably better stego tools out there for these
tasks, I know steghide is a better option if you want to encode hidden data into
images. Still, these examples are fairly simple and should help students begin
to learn the concepts. The download contains two programs and their source code:

unisteg.exe: This tool lets you encode data using different
representations Unicode of characters. The hidden message can then be pasted
into Twitter or Facebook. On Twitter, I can only get 17 hidden characters
encoded into a 140 byte message, but for a command and control channel I'm
sure I can split it up across multiple posts. I'm hoping to get Robin Wood
to implement an encoding scheme similar to this one into his
KreiosC2 project.

lsbsteg.exe: This tool is a simple image editor that takes a message and
hides it as bits in a lossless image format (PNGs for example).

I plan to use some of these stego techniques in future projects. Looks at the comments at the
top of the source code for more details on the specifics of how each algorithm
works. Most of the real technical information is in those comments.

In Unicode there are multiple ways to encode characters that look more or less the same to the human eye, but have different numerical values (homoglyphs). I thought this would be a great way to try to hide data in user generated content. I did some searching around, but did not find any code. Antonio Alcorn had a demo page (link below), which he may put up code for later. I looked at what he did, but went a slightly different direction in how I do my encoding (his results looks better, mine hides more data). It seems the characters:

are represented in both the 0021-007E (Basic Latin) and the FF01-FF5E (Fullwidth Latin) ranges. This means I can use the lower range to represent 0s and the higher range to represent 1s. I have to do something special with spaces and encode them as Unicode number 8287 decimal. This means changing from one encoding to another is as easy as adding the decimal values 65248 to the lower range versions. With some effort, I should be able to encode more data or make the output look better by using other homoglyphs, but that will make the algorithm more complicated. Also, some sort of XOR based encryption to the payload would be an easy option to add. Since this first release is for learning, I’ve opted for simplicity of concept. Great thing about this code, you can hide your messages in Twitter or Facebook posts. :)

;This function just lets the use know what they can encodeFunc ShowInfo($CoverStr,$InputMessageStr)$TotalCoverChrs=StringLen($CoverStr);$CoverStrNoSpaces = StringReplace($CoverStr, " ", "");$EncodablePlaces = StringLen($CoverStrNoSpaces) / 8$EncodablePlaces=StringLen($CoverStr)/8$ChrToEncode=StringLen($InputMessageStr)$InfoMessage="You have "&$ChrToEncode&" characters to encode"&@CRLF$InfoMessage=$InfoMessage&"With the current cover text, you can only encode "&$EncodablePlaces&" characters"&@CRLF$InfoMessage=$InfoMessage&"You have "&$TotalCoverChrs&" total cover characters (140 is all Twitter will allow)"Return$InfoMessageEndFunc;==>ShowInfo

;Decodes the input string into the hidden textFunc UniDecodeString($InputStr)$BinTemp=""For$i=1ToStringLen($InputStr)$TheChr=StringMid($InputStr,$i,1)SelectCaseAscW($TheChr)<32;do nothing, it's a lower ASCII character, so we skip itCaseAscW($TheChr)>126$BinTemp=$BinTemp&"1"CaseElse$BinTemp=$BinTemp&"0"EndSelectNextReturn BinDecodeString($BinTemp)EndFunc;==>UniDecodeString

;Somethin I put here to help me debugFunc PrintDecodeString($arg)$results=""For$i=1ToStringLen($arg)$TheChr=StringMid($arg,$i,1)$results=$results&$TheChr&" "&AscW($TheChr)&@CRLFNextReturn$resultsEndFunc;==>PrintDecodeString

;Just a simple function to make the code easier to readFunc UnicodeReplace($arg)IfAscW($arg)=32ThenReturnChrW(8287);encode a space this way, since 32+65248 does not workElseReturnChrW(AscW($arg)+65248)EndIfEndFunc;==>UnicodeReplace

;Loops though the sting, turing the Binary to ASCIIFunc BinDecodeString($arg)$results=""For$i=1ToStringLen($arg)Step8$results=$results& Byte2Asc(StringMid($arg,$i,8))NextReturn$resultsEndFunc;==>BinDecodeString

;Loops though the sting, turing the ASCII to a series of 1s and 0sFunc BinEncodeString($arg)$results=""For$i=1ToStringLen($arg)$results=$results& Asc2Byte(StringMid($arg,$i,1))NextReturn$resultsEndFunc;==>BinEncodeString

Func Asc2Byte($arg)$tempasc=Asc($arg)Local$result=""While($tempasc>=1)$tempasc/=2IfStringIsDigit($tempasc)Then$result&=0Else$split=StringSplit($tempasc,".")$tempasc=$split[1]$result&=1EndIfWEnd$result=_StringReverse($result)WhileStringLen($result)<8$result="0"&$resultWEndReturn$resultEndFunc;==>Asc2Byte;based on a post from Mpro

This simple sample code shows using “Least Significant Bit” encoding on a lossless image file format. We can modify the LSB to hide data if we wish. The human eye would have a hard time telling the difference between the RGB color value FF9999 (light red) and FF9899 (which encodes the binary value 101 on the least significant bit of Red Green and Blue), but a computer has no problem. Using a lossy algorithm would make this tougher so this educational code only used PNGs(For JPGs, look up “StegHide”). Also, some sort of XOR based encryption to the payload would be an easy option to add. Since this first release is for learning, I’ve opted for simplicity of concept.

;Main code begins$choice=MsgBox(3,"Irongeek's LSB Stego 1.1: Decode or Encode?","Yes=Encode"&@CRLF&"No=Decode"&@CRLF&"Cancel=Exit")SelectCase$choice=6$TextToEncode=FileOpenDialog("What text should I encode?",@ScriptDir,"Text (*.txt)")$InputImage=FileOpenDialog("What image should I use as cover?",@ScriptDir,"PNGs (*.png)")$OutputImage=FileSaveDialog("Where should I save the output image?",@ScriptDir,"PNGs (*.png)")$DataToEncode=FileRead($TextToEncode);msgbox(0,"",$DataToEncode) EncodeImage($DataToEncode,$InputImage,$OutputImage)Case$choice=7$ImageToDecode=FileOpenDialog("What should I decode?",@ScriptDir,"PNGs (*.png)")$DecodedImageData= BinDecodeString(DecodeImage($ImageToDecode))$TextFileToSaveTo=FileSaveDialog("Where should I save the output?",@ScriptDir,"Text (*.txt)")FileWrite($TextFileToSaveTo,$DecodedImageData)Case$choice=2ExitEndSelect;Main code ends

;Setsu the valus of the least significant bitFunc SetLSB($arg,$bit)If$bit="1"Then$results=BitOR($arg,1); 1 as LSBElse$results=BitAND($arg,254); 0 as LSBEndIfReturn$resultsEndFunc;==>SetLSB

;Gives you the value of the least significant bitFunc GetLSB($arg);msgbox(0,"",$arg)$results=_MathCheckDiv($arg,2)If$results=2Or$results=-1Then$results=0;msgbox(0,"",$results)Return$resultsEndFunc;==>GetLSB

;Had to use this to implement a stack, it made the code logic easierFunc PopBinValue(ByRef$arg)$results=StringLeft($arg,1)$arg=StringRight($arg,StringLen($arg)-1)Return$resultsEndFunc;==>PopBinValue

;Just get the color of a pixelFunc _GDIPlus_BitmapGetPixel($hBitmap,$iX,$iY)Local$tArgb,$pArgb,$aRet$tArgb=DllStructCreate("dword Argb")$pArgb=DllStructGetPtr($tArgb)$aRet=DllCall($ghGDIPDll,"int","GdipBitmapGetPixel","hwnd",$hBitmap,"int",$iX,"int",$iY,"ptr",$pArgb)ReturnHex(DllStructGetData($tArgb,"Argb"),6)EndFunc;==>_GDIPlus_BitmapGetPixel; Vossen

;Just set the color of a pixelFunc _GDIPlus_BitmapSetPixel($hBitmap,$iX,$iY,$iArgb)Local$aRet$iArgb="0xFF"&$iArgb$aRet=DllCall($ghGDIPDll,"int","GdipBitmapSetPixel","hwnd",$hBitmap,"int",$iX,"int",$iY,"dword",$iArgb)ReturnEndFunc;==>_GDIPlus_BitmapSetPixel;based on a post from Malkey

;Loops though the sting, turing the Binary to ASCIIFunc BinDecodeString($arg)$results=""For$i=1ToStringLen($arg)Step8$results=$results& Byte2Asc(StringMid($arg,$i,8))NextReturn$resultsEndFunc;==>BinDecodeString

;Loops though the sting, turing the ASCII to a series of 1s and 0sFunc BinEncodeString($arg)$results=""For$i=1ToStringLen($arg)$results=$results& Asc2Byte(StringMid($arg,$i,1))NextReturn$resultsEndFunc;==>BinEncodeStringFunc Asc2Byte($arg)$tempasc=Asc($arg)Local$result=""While($tempasc>=1)$tempasc/=2IfStringIsDigit($tempasc)Then$result&=0Else$split=StringSplit($tempasc,".")$tempasc=$split[1]$result&=1EndIfWEnd$result=_StringReverse($result)WhileStringLen($result)<8$result="0"&$resultWEndReturn$resultEndFunc;==>Asc2Byte;based on a post from Mpro