Created
July 1, 2014 20:47
-
-
Save jamesduncombe/b4732a4ffee6a8561dc0 to your computer and use it in GitHub Desktop.
JPEG Smash but in Ruby...
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
require 'optparse' | |
options = {} | |
# Markers | |
JPEG_START = 'ffda' | |
JPEG_END = 'ffd9' | |
OptionParser.new do |opts| | |
opts.banner = 'Usage: jpeg_crush.rb [options]' | |
opts.on('-f', '--file [FILE]', 'Use source file') do |v| | |
options[:file] = v | |
end | |
opts.on('-o', '--output-file [FILE]', 'Use output file') do |v| | |
options[:output_file] = v | |
end | |
opts.on('-m', '--message [MESSAGE]', 'Specify message to inject') do |v| | |
options[:message] = v.unpack("H*").first.scan(/.{2}/) | |
end | |
end.parse! | |
puts 'Opening source file...' | |
if File.exists? options[:file] | |
original = File.binread(options[:file]) | |
else | |
raise ArgumentError, 'Incorrect filename given' | |
end | |
puts 'Unpacking hex into pairs...' | |
ready = original.unpack('H*').first.scan(/.{2}/) # get hex pairs | |
def start_of_data(data) | |
data.each_with_index { |e,i| return i if e == 'ff' && data[i+1] == 'da' } | |
end | |
def end_of_data(data) | |
data.each_with_index { |e,i| return i if e == 'ff' && data[i+1] == 'd9' } | |
end | |
# remember these are split into 2's and there's 4 as delimeters (ffda and ffd9) hance | |
# the 2 offset forwards and back (we don't want to ovewrite the markers) | |
puts 'Getting offsets for JPEG markers...' | |
starts = start_of_data(ready) + 2 | |
ends = end_of_data(ready) - 2 | |
puts 'Get the length of my name, insert Hex randomly...' | |
options[:message].count.times do |t| | |
loc = rand(starts+2..ends-2) | |
ready[loc] = options[:message].shuffle.first | |
end | |
# re-assemble file for writing out to a JPEG file | |
ready = [ready.join].pack('H*') | |
f = File.open(options[:output_file], 'w+') | |
f.write ready | |
f.close | |
puts 'Done :)' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment