# this script patches libreadline to fix the input data discard # debian bug #498277, aka irb copy-paste bug # (c) Yoann Guillot, 09/2008, WTFPL # should work on all versions (tested on debian/libreadline5.2-3) # http://metasm.cr0.org/ require 'metasm' target = ARGV.shift || '/usr/lib/libreadline.so' puts "read ELF" elf = Metasm::ELF.decode_file target puts "disassemble" dasm = elf.disassemble 'rl_stuff_char', '_rl_insert_typein' puts "scan" # search for the faulty jmps in rl_stuff_char and rl_get_char patchaddr = [] dasm.each_instructionblock { |b| if b.list.last.instruction.opname == 'jle' and b.list.find { |ddi| ddi.to_s =~ /cmp .*, 1feh/ } patchaddr << b.list.last.address end } raise "#{patchaddr.length} patch location found, expected 2" if patchaddr.length != 2 def hexdump(str) str.unpack('C*').map { |c| '%02x' % c }.join end puts "patch" patchaddr.each { |addr| # assemble the replacement instructions ori = dasm.decoded[addr] sc = Metasm::Shellcode.new(elf.cpu) # we compute the jump offset numerically, to avoid encoding our offset on 4 bytes jmpoff = ori.instruction.args.first - addr jmpoff = jmpoff.bind(dasm.prog_binding).reduce sc.parse <