Skip to content

Instantly share code, notes, and snippets.

@jamesduncombe
Created July 1, 2014 20:47

Revisions

  1. jamesduncombe renamed this gist Jul 1, 2014. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  2. jamesduncombe created this gist Jul 1, 2014.
    62 changes: 62 additions & 0 deletions gistfile1.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,62 @@
    #!/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 :)'