Skip to content

Instantly share code, notes, and snippets.

@b1nary
Created January 27, 2012 20:35
Show Gist options
  • Save b1nary/1690788 to your computer and use it in GitHub Desktop.
Save b1nary/1690788 to your computer and use it in GitHub Desktop.
HideMage in development ;) It can save Text to images and get it back.

HideMage

What i try in this projekt is to make an simple but effective tool to hide information in Images. Text or in Binary should not matter. Also it should give some functions like decodeing it, or encrypting it (AES, ...)

Todo

  • Encryption (Aes, ...) use OpenSSL Api ^^
  • May add Twofish Encryption
  • Write Binary data to images
  • Execute Scripts hidden in Images (also width password)
#----------------------------------------------------------------#
# HideMage - Write some Infos into an Image
# by Roman Pramberger
#
# Ruby converts text to Ascii int values up to 126
# We use a numbersystem of 6. Because we just change the last
# number of an 257 RGB value.
# For example "x" in Ascii is 320
# Lets guess the Pixel comes as: red[144], green[178], blue[214]
# So we take the 320 and do: red[143], green[172], blue[210]
# And we put 1 Char into 1 Pixel!
#----------------------------------------------------------------#
require 'optparse'
begin
require 'RMagick'
include Magick
rescue
puts "RMagick not deteced! Do you want to install? (y/n)"
answer = gets.chomp()
if answer == "y"
system("sudo gem install rmagick")
end
exit
end
options = {}
optparse = OptionParser.new do|opts|
opts.banner = "Usage: ruby hidemage.rb [options] IMG-FILE.png"
options[:debug] = false
opts.on( '-d', '--debug', "Output MUCH information\n\n" ) do
options[:debug] = true
end
options[:write] = false
opts.on( '-w', '--write', 'Write to Image' ) do |string|
options[:write] = true
end
options[:string] = nil
opts.on( '-s', '--string "STRING"', '* String to hide' ) do |string|
options[:string] = string
end
options[:file] = nil
opts.on( '-f', '--file FILE', "* Read String from file\n\n" ) do|file|
options[:file] = file
end
options[:read] = nil
opts.on( '-r', '--read', "Read from Image\n\n" ) do|file|
options[:read] = file
end
options[:install] = false
opts.on( '-i', '--install', 'Copy this Script to /usr/bin' ) do|file|
options[:install] = true
end
opts.on( '-h', '--help', 'Display this screen' ) do
puts opts
exit
end
end
optparse.parse!
if ARGV[0].nil? or ARGV[0] == "" or (options[:write] and (options[:file].nil? and options[:string].nil?))
puts "ERROR: No image given..." if ARGV[0].nil? or ARGV[0] == ""
puts "try: ruby hidemage.rb -h"
exit
end
if !File.exist?(ARGV[0])
puts "ERROR: Image not found..."
exit
end
if !options[:file].nil?
if File.exist?(options[:file])
string = File.open(options[:file]).read
end
end
if !options[:string].nil?
puts "!! If you define a file and a string. It will just use the string... " if !options[:file].nil?
string = options[:string]
end
DEBUG = options[:debug]
@escape = ["1","3","5","1","3","5","1","3","5"]
puts "
####################################
# < HideMage > #
# Hide Secret Messages in Images #
####################################
"
if options[:write]
print ":: Reading image to rmagick... "
#img = ImageList.new(ARGV[0])
img = Magick::Image.read(ARGV[0]).first
#pixels = inimg.dispatch(0,0,inimg.columns, inimg.rows, "RGB")
#img = Magick::Image.constitute(inimg.columns, inimg.rows, "RGB", pixels)
puts "done"
puts img.inspect if DEBUG
## get Ascii values
print ":: Cutting String into Ascii values... "
$chars = Array.new
string.each_byte do |c|
if c.to_s.split("").size == 2
puts "Char is only 2 big. expand to 3" if DEBUG
$chars << "0"
elsif c.to_s.split("").size == 1
puts "Char is only 1 big. expand to 3" if DEBUG
$chars << "0"
$chars << "0"
end
c.to_s.each_char do |c2|
$chars << c2
end
end
puts "done"
print "#{$chars}\n" if DEBUG
$chars += @escape # add escape sequence "135135135"
puts ":: Created #{$chars.size} numbers"
def getNewColorValue(color)
if color.to_i < 250 and color.to_i > 9
print "Left Values: #{$chars}\n" if DEBUG
color = color.to_i
color -= color.to_s.split("").last.to_i
color += $chars.first.to_i
$chars.delete_at(0)
end
return color
end
print ":: Write to Image..."
puts "" if DEBUG # just some cosmetic :3
img.each_pixel { |p,c,r|
if $chars.size > 0
red = getNewColorValue(p.red/257)
green = getNewColorValue(p.green/257)
blue = getNewColorValue(p.blue/257)
color = "rgb(#{red},#{green},#{blue}) #{c}/#{r}"
#color = "##{red.to_s(16)}#{green.to_s(16)}#{blue.to_s(16)}"
#puts color
img.pixel_color(c,r,color)
img.store_pixels(c,r,1,1,[Pixel.new(red*257, green*257, blue*257, 0)])
else
break
end
#rgb(r,g,b)
}
puts "done"
print ":: Saving image..."
img.write(ARGV[0])
puts " done"
img = nil
end
sleep 0.4
if options[:read]
print ":: Reading image to rmagick... "
img = ImageList.new(ARGV[0])
puts "done"
puts img.inspect if DEBUG
def checkWork()
if @work.size == 3
@out << @work.join("")
print @work if DEBUG
@work.clear
end
end
def genColor(color)
if color.to_i < 250 and color.to_i > 9
yut = color.to_s.split("").last.to_i
yut = 9 if yut == -1
@work << yut
checkWork()
end
end
print ":: Reading Image... "
@work = Array.new
@out = Array.new
img.each_pixel { |p,c,r|
genColor(p.red/257)
genColor(p.green/257)
genColor(p.blue/257)
break if @out[@out.size-1] == "135" and @out[@out.size-2] == "135" and @out[@out.size-3] == "135"
break if @out.size == 20
}
puts "done"
puts "<-----[Hidden Message]----->"
@out.each do |o|
begin
print o.to_i.chr if o.to_i != 135
rescue
end
end
puts "\r\n\r\n"
img = nil
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment