### Author Topic: Steganography  (Read 2095 times)

#### Galileo

• Guest
##### Steganography
« on: February 25, 2018, 01:08:58 PM »
Small modifications to the program "Import/Export BMP files" to make a program that encodes/decodes hidden information within an image.

Code: [Select]
`// Yabasic 2.78, by Galileo, 02/2018// Code adopted from IMAGE.yab (author: Hermang Hialino Mansilla Mattos, hh_mm@yahoo.com)sub Encodegraphic(texto\$, bmpfile\$, dx, dy) local fp, tmp, row, col, blue, green, red, lbtxt, ptxt, btexto\$, b, cm, nblue fp = open(bmpfile\$,"rb") if fp < 1 then    print "File ", bmpfile\$, " Does not Exist"    return -1 end if btexto\$ = ConvertToBit\$(texto\$ + chr\$(127)) lbtxt = len(btexto\$)    seek #fp,18 : Width = peek(fp)+256*peek(fp) seek #fp,22 : Height = peek(fp)+256*peek(fp) seek #fp,28 : bpp = peek(fp) if bpp = 24 THEN  seek #fp,54  for row = 1 to Height    FOR col = 1 to Width        blue = peek(fp)        green = peek(fp)        red = peek(fp)        if ptxt < lbtxt then        b = val(mid\$(btexto\$, ptxt + 1, 1))        cm = mod(blue, 2)        if b <> cm then        nblue = blue + 1        if nblue > 255 nblue = blue - 1        blue = nblue        end if        ptxt = ptxt + 1        end if        color red, green, blue        dot dx + col, dy + Height + 1 - row    NEXT col      rem adjust extra bytes  c = Width * 3 while(mod(c,4))  tmp = peek(fp)  c = c + 1 wend  next row END IF close fpend sub// Code adapted from SmallBASIC (author: Keijo Koskinen, keijoko@csolve.net)// Ogirinal code: https://smallbasic.sourceforge.io/?q=node/40sub SaveToBMP(bmpfile\$, dx, dy, wid, hei) local fp, row, col, xh, xl, bmkk, bmk, ero, mbtot, bml, bmll, bmh, bmhh, p\$ fp = open(bmpfile\$,"wb") if fp < 1 then    print "File ", bmpfile\$, " Does not create"    return -1 end if poke #fp, dec("42") : poke #fp, dec("4D") // BM poke #fp, 54 : poke #fp, 3 : poke #fp, 0 : poke #fp, 0 // Tamaño del archivo poke #fp, 0 : poke #fp, 0 : poke #fp, 0 : poke #fp, 0   // Reservado poke #fp, 54 : poke #fp, 0 : poke #fp, 0 : poke #fp, 0  // Inicio de los datos de la imagen poke #fp, 40 : poke #fp, 0 : poke #fp, 0 : poke #fp, 0  // Tamaño de la cabecera del bitmap xh = int(wid / 256) xl = wid - xh * 256 poke #fp, xl : poke #fp, xh : poke #fp, 0 : poke #fp, 0 // Anchura xh = int(hei / 256) xl = hei - xh * 256 poke #fp, xl : poke #fp, xh : poke #fp, 0 : poke #fp, 0 // Altura poke #fp, 1 : poke #fp, 0 // Número de planos poke #fp, 24 : poke #fp, 0 // Tamaño de cada punto poke #fp, 0 : poke #fp, 0 : poke #fp, 0 : poke #fp, 0   // Compresión bmkk = wid * 3   // real line length    bmk = int(bmkk / 4 + .5)  // but it has to be 4-bit    bmk = bmk * 4        // total length (expanded by 0 :s )    ero = bmk - bmkk     //  how many 0:s on the end of each line    bmtot = (bmk * hei)  // +54    bml = Int(bmtot / 256)    bmll = bmtot - (bml * 256)    If bml > 256 Then        bmh = Int(bml / 256)        bml = bml - (bmh * 256)        If bmh > 256 Then            bmhh = Int(bmh / 256)            bmh = bmh - (bmh * 256)        End If    End If poke #fp, bmll : poke #fp, bml : poke #fp, bmh : poke #fp, bmhh // Tamaño de la imagen poke #fp, 0 : poke #fp, 0 : poke #fp, 0 : poke #fp, 0 // Resolución horizontal poke #fp, 0 : poke #fp, 0 : poke #fp, 0 : poke #fp, 0 // Resolución vertical poke #fp, 0 : poke #fp, 0 : poke #fp, 0 : poke #fp, 0 // Tamaño de la tabla de color poke #fp, 0 : poke #fp, 0 : poke #fp, 0 : poke #fp, 0 // Contador de colores importantes for col = hei to 1 step -1  for row = 1 to wid   xl = dy + row  xh = dx + col p\$ = right\$(getbit\$(xl, xh, xl, xh), 6) poke #fp, dec(right\$(p\$, 2)) // blue poke #fp, dec(mid\$(p\$, 3, 2)) // green poke #fp, dec(left\$(p\$, 2)) // red    next    If ero > 0 Then        // if 32bit (4-byte) boundary  for xl = 1 To ero  // does not match  poke #fp, 0    // rows have to be filled  with zeros next xl            // to macth boundary End If next close fpend subsub Decodegraphic(bmpfile\$, dx, dy) local fp, row, col, tmp, blue, green, red, btexto\$ fp = open(bmpfile\$,"rb") if fp < 1 then    print "File ", bmpfile\$, " Does not Exist"    return -1 end if seek #fp,18 : Width = peek(fp)+256*peek(fp) seek #fp,22 : Height = peek(fp)+256*peek(fp) seek #fp,28 : bpp = peek(fp) if bpp = 24 THEN  seek #fp,54  for row = 1 to Height    FOR col = 1 to Width        blue = peek(fp)        green = peek(fp)        red = peek(fp)        btexto\$ = btexto\$ + str\$(mod(blue, 2))        color red, green, blue        dot dx + col, dy + Height + 1 - row    NEXT col      rem adjust extra bytes  c = Width * 3 while(mod(c,4))  tmp = peek(fp)  c = c + 1 wend  next row  print ConvertToTxt\$(btexto\$) end if close fpend subsub ConvertToBit\$(texto\$) local btexto\$, n for n = 1 to len(texto\$) btexto\$ = btexto\$ + right\$("000000" + bin\$(asc(mid\$(texto\$, n, 1))), 8) next n return btexto\$end subsub ConvertToTxt\$(texto\$) local n, c, r\$ for n = 1 to len(texto\$) step 8 c = dec(mid\$(texto\$, n, 8), 2) if c = 127 break r\$ = r\$ + chr\$(c) next n return r\$end subopen window 800, 600backcolor 0, 0, 0clear windowEncodegraphic("This is a test of the steganographic encryption/decryption simple code.", "Flower.bmp", 100, 100 )SaveToBMP("prueba.bmp", 100, 100, 112, 112)clear windowDecodegraphic("prueba.bmp")`
See the original image and the codified image.
« Last Edit: February 26, 2018, 04:43:49 PM by Galileo »

#### Galileo

• Guest
##### Re: Steganography
« Reply #1 on: February 27, 2018, 06:52:29 PM »
This code is simpler and more generalist. It works reasonably well with uncompressed image and sound files.

Code: [Select]
`// Yabasic 2.78, by Galileo, 02/2018// Simple steganographic codeEOT\$ = "<END>"gap = 29700test\$ = "This is a test of the steganographic encryption/decryption simple code."sub Encode(texto\$, file\$) local fp, fc, filesize, lbtxt, ptxt, btexto\$, n, b, cm, byte, ini fp = open(file\$,"rb") if fp < 1 then    print "File ", file\$, " Does not Exist"    return -1 end if fc = open("cod-" + file\$,"wb") if fc < 1 then    print "Creation fail of ", "cod-", file\$, "."    return -1 end if btexto\$ = ConvertToBit\$(texto\$ + EOT\$) lbtxt = len(btexto\$)    seek #fp, 0, "end" filesize = tell(#fp) seek #fp, 0, "begin" ini = gap for n = 1 to filesize byte = peek(#fp) if n >= ini and mod(n, 100) then if ptxt < lbtxt then b = val(mid\$(btexto\$, ptxt + 1, 1)) cm = mod(byte, 2) if b <> cm then byte = byte + 1 if byte = 256 byte = 254 end if ptxt = ptxt + 1 end if end if poke #fc, byte next n close #fp close #fcend subsub Decode(file\$) local fp, btexto\$, filesize, ini, n, byte, eom\$, leom fp = open(file\$,"rb") if fp < 1 then    print "File ", bmpfile\$, " Does not Exist"    return -1 end if eom\$ = ConvertToBit\$(EOT\$) leom = len(eom\$) seek #fp, 0, "end" filesize = tell(#fp) seek #fp, 0, "begin" ini = gap for n = 1 to filesize byte = peek(#fp) if n >= ini and mod(n, 100) then        btexto\$ = btexto\$ + str\$(mod(byte, 2))        if right\$(btexto\$, leom) = eom\$ break        end if  next n  print ConvertToTxt\$(btexto\$) close fpend subsub ConvertToBit\$(texto\$) local btexto\$, n for n = 1 to len(texto\$) btexto\$ = btexto\$ + right\$("000000" + bin\$(asc(mid\$(texto\$, n, 1))), 8) next n return btexto\$end subsub ConvertToTxt\$(texto\$) local n, c, r\$ for n = 1 to len(texto\$) step 8 c = dec(mid\$(texto\$, n, 8), 2) if c = EOT break r\$ = r\$ + chr\$(c) next n return r\$end subEncode(test\$, "flower.bmp")Decode("cod-flower.bmp")Encode(test\$, "retroactive.mp3")Decode("cod-retroactive.mp3")`
« Last Edit: February 27, 2018, 08:23:24 PM by Galileo »

#### Galileo

• Guest
##### Re: Steganography
« Reply #2 on: February 27, 2018, 07:30:00 PM »
Tested o.k. with

audio: .MP3, .OGG, .WAV
image: .TIF, .TGA, .BMP
video: .MP4, .FLV

Note: modify value of GAP variable for test with other file formats.
« Last Edit: February 27, 2018, 07:53:03 PM by Galileo »

#### Galileo

• Guest
##### Re: Steganography
« Reply #3 on: February 28, 2018, 06:19:08 PM »
This is the version to generate an executable program. Included is a compressed file with this code, the executable for Windows, and three files for testing.

Code: [Select]
`#!/usr/bin/yabasic // for Linux// Yabasic 2.78, by Galileo, 02/2018// Simple steganographic codedocu Mode of use for encoding: stegano.exe <carrierfile> <messagefile>docu Example: stegano.exe flower.bmp message.txtdocu Mode of use for decoding: stegano.exe <carrierfile>docu Example: stegano.exe cod-flower.bmpEOT\$ = "<END>"gap = 29700sub Encode(file\$, texto\$) local fp, fc, ft, filesize, lbtxt, ptxt, btexto\$, n, b, cm, byte, ini, a\$ fp = open(file\$,"rb") if fp < 1 then    print "File ", file\$, " Does not Exist"    return -1 end if fc = open("cod-" + file\$,"wb") if fc < 1 then    print "Creation fail of ", "cod-", file\$, "."    return -1 end if ft = open(texto\$, "r") if ft < 1 then    print "File ", texto\$, " Does no Exist"    return -1 end if texto\$ = "" while(not eof(ft))   line input #ft a\$  texto\$ = texto\$ + a\$ + chr\$(10) + chr\$(13) wend close #ft btexto\$ = ConvertToBit\$(texto\$ + EOT\$) lbtxt = len(btexto\$)    seek #fp, 0, "end" filesize = tell(#fp) seek #fp, 0, "begin" ini = gap for n = 1 to filesize byte = peek(#fp) if n >= ini and mod(n, 100) then if ptxt < lbtxt then b = val(mid\$(btexto\$, ptxt + 1, 1)) cm = mod(byte, 2) if b <> cm then byte = byte + 1 if byte = 256 byte = 254 end if ptxt = ptxt + 1 end if end if poke #fc, byte next n close #fp close #fcend subsub Decode(file\$) local fp, btexto\$, filesize, ini, n, byte, eom\$, leom fp = open(file\$,"rb") if fp < 1 then    print "File ", bmpfile\$, " Does not Exist"    return -1 end if eom\$ = ConvertToBit\$(EOT\$) leom = len(eom\$) seek #fp, 0, "end" filesize = tell(#fp) seek #fp, 0, "begin" ini = gap for n = 1 to filesize byte = peek(#fp) if n >= ini and mod(n, 100) then        btexto\$ = btexto\$ + str\$(mod(byte, 2))        if right\$(btexto\$, leom) = eom\$ break        end if  next n  print ConvertToTxt\$(btexto\$) close fpend subsub ConvertToBit\$(texto\$) local btexto\$, n for n = 1 to len(texto\$) btexto\$ = btexto\$ + right\$("000000" + bin\$(asc(mid\$(texto\$, n, 1))), 8) next n return btexto\$end subsub ConvertToTxt\$(texto\$) local n, c, r\$ for n = 1 to len(texto\$) step 8 c = dec(mid\$(texto\$, n, 8), 2) if c = EOT break r\$ = r\$ + chr\$(c) next n return r\$end subarg = peek("arguments")if arg = 1 then Decode(peek\$("argument"))elseif arg = 2 then Encode(peek\$("argument"), peek\$("argument"))else print "Error in calling the program."end ifif !peek("isbound") bind "stegano.exe"`
« Last Edit: February 28, 2018, 06:56:06 PM by Galileo »

#### jj2007

• Guest
##### Re: Steganography
« Reply #4 on: March 01, 2018, 12:05:31 AM »
Nice! For a serious implementation, one should use a lossless compression format, though, like PNG. Nobody sends uncompressed BMP files as attachments...

#### Galileo

• Guest
##### Re: Steganography
« Reply #5 on: March 01, 2018, 04:46:51 PM »
My intention at first was to explore a simple algorithm for encoding information into audio, video and image files. Of course, this is only a design concept, which, however, is already useful. Now I'm working on refining the program a little more, because I find it very fun to do so.

#### Galileo

• Guest
##### Re: Steganography
« Reply #6 on: March 01, 2018, 07:08:08 PM »
Well, as I was saying, here are the modifications and improvements. I'd like to know if anyone has tried it under Linux and how it works.

Code: [Select]
`#!/usr/bin/yabasic// Yabasic 2.78, by Galileo, 02/2018// Simple steganographic code, v. 1.5 03/2018docu Mode of use for encoding: stegano.exe <carrierfile> <messagefile>docu Example: stegano.exe flower.bmp message.txtdocu Mode of use for decoding: stegano.exe <carrierfile>docu Example: stegano.exe cod-flower.bmpif !peek("isbound") bind "stegano.exe"EOT\$ = "<END>"IOT\$ = "<INI>"sub Encode(file\$, texto\$) local fp, fc, ft, filesize, lbtxt, ptxt, btexto\$, n, b, cm, byte, ini, a\$ fp = open(file\$,"rb") if fp < 1 then    print "File ", file\$, " Does not Exist"    return -1 end if fc = open("cod-" + file\$,"wb") if fc < 1 then    print "Creation fail of ", "cod-", file\$, "."    return -1 end if ft = open(texto\$, "r") if ft < 1 then    print "File ", texto\$, " Does no Exist"    return -1 end if texto\$ = "" while(not eof(ft))   line input #ft a\$  texto\$ = texto\$ + a\$ + nl\$ wend close #ft btexto\$ = ConvertToBit\$(IOT\$ + texto\$ + EOT\$) lbtxt = len(btexto\$)    seek #fp, 0, "end" filesize = tell(#fp) seek #fp, 0, "begin" ini = gap for n = 1 to filesize byte = peek(#fp) if n >= ini and mod(n, stp) then if ptxt < lbtxt then b = val(mid\$(btexto\$, ptxt + 1, 1)) cm = mod(byte, 2) if b <> cm then byte = byte + 1 if byte = 256 byte = 254 end if ptxt = ptxt + 1 end if end if poke #fc, byte next n close #fp close #fcend subsub Decode(file\$) local fp, btexto\$, filesize, ini, n, byte, eom\$, leom, iom\$, liom, sw fp = open(file\$,"rb") if fp < 1 then    print "File ", bmpfile\$, " Does not Exist"    return -1 end if iom\$ = ConvertToBit\$(IOT\$) liom = len(iom\$) eom\$ = ConvertToBit\$(EOT\$) leom = len(eom\$) seek #fp, 0, "end" filesize = tell(#fp) seek #fp, 0, "begin" ini = gap for n = 1 to filesize byte = peek(#fp) if n >= ini and mod(n, stp) then        btexto\$ = btexto\$ + str\$(mod(byte, 2))        if not sw then // Checks if the message start mark exists        if len(btexto\$) = liom then        if btexto\$ <> iom\$ then print "There is no message."        return -1        else        sw = true        end if        end if        end if        if right\$(btexto\$, leom) = eom\$ break // Checks if the message end mark exists        end if  next n  print ConvertToTxt\$(btexto\$) close fpend subsub ConvertToBit\$(texto\$) local btexto\$, n for n = 1 to len(texto\$) btexto\$ = btexto\$ + right\$("000000" + bin\$(asc(mid\$(texto\$, n, 1))), 8) next n return btexto\$end subsub ConvertToTxt\$(texto\$) local n, c, r\$ for n = 1 to len(texto\$) step 8 c = dec(mid\$(texto\$, n, 8), 2) if c = EOT break r\$ = r\$ + chr\$(c) next n return r\$end subnl\$ = chr\$(10)//if peek\$("os") = "windows" nl\$ = chr\$(13) + nl\$arg = peek("arguments")if arg then arg\$ = peek\$("argument")else print "Error: no parameter found." endend ifext\$ = upper\$(right\$(arg\$, len(arg\$) - rinstr(arg\$, ".")))switch ext\$ case "TIF": case "TGA": case "BMP": gap = 55 : stp = 3 : break case "OGG": case "MP3": gap = 100 : stp = 100 : break case "FLV": gap = 15000 : stp = 100 : break case "MP4": gap = 29700 : stp = 100 : break case "MPEG": gap = 1000000 : stp = 1000 : break case "OGV": gap = 100000 : stp = 1000 : break case "AVI": gap = 100000000 : stp = 100000000 : break default: gap = 100000 : stp = 100 : breakend switchif arg = 1 then Decode(arg\$)elseif arg = 2 then Encode(arg\$, peek\$("argument"))else print "Error: extra parameter found."end if`
Yabasic is not particularly fast, so care should be taken to avoid large files.
« Last Edit: March 01, 2018, 09:27:21 PM by Galileo »