Fixes #452. Solves a number of crashes caused by Regexp.new() on 1.9 without an explicit language specified

git-svn-id: file:///home/svn/framework3/trunk@7320 4d416f70-5f16-0410-b530-b9f4589650da
This commit is contained in:
HD Moore 2009-11-02 17:09:13 +00:00
parent c0a0507fdf
commit 176996fe61
12 changed files with 175 additions and 171 deletions

View File

@ -1,12 +1,12 @@
###
#
# This module provides methods for parseing and interacting
# with the PDF format.
# This module provides methods for parseing and interacting
# with the PDF format.
#
###
module Msf
module Exploit::PDF_Parse
@ -27,21 +27,21 @@ module Msf
end
def xref_trailer_parse(offset, stream)
a = offset
a = offset
b = stream.index(/>>/,a) + 2
return stream[a..b]
end
def trailer_parse(xref_trailer)
trailer = Hash.new()
trailer["Size"] = xref_trailer.match(/Size (\d+)/m)[1]
if match = xref_trailer.match(/Root (\d+ \d)/m)
trailer["Root"] = match[1]
end
if match = xref_trailer.match(/Info (\d+ \d)/m)
trailer["Info"] = match[1]
end
@ -49,36 +49,36 @@ module Msf
if match = xref_trailer.match(/ID(\[.+\])/m)
trailer["ID"] = match[1]
end
if match = xref_trailer.match(/Prev (\d+)/m)
trailer["Prev"] = match[1]
end
if match = xref_trailer.match(/XRefStm (\d+)/m)
trailer["XRefStm"] = match[1]
end
return trailer
end
def object_locate(xref_trailer,obj_name)
found = false
match = obj_name.match(/(\d+) (\d+)/)
match = obj_name.match(/(\d+) (\d+)/)
obj = match[1]
gen = match[2]
xrefs_end = xref_trailer.index(/trailer/) - 1
xrefs = xref_trailer[0..xrefs_end]
if gen.to_i != 0
else
len = xrefs.length
match = xrefs.match(/xref\r?\n?(\d+) (\d+)\r?\n?/m)
match = xrefs.match(/xref\r?\n?(\d+) (\d+)\r?\n?/m)
offset = 0
while offset < len
if match
@ -93,8 +93,8 @@ module Msf
jump = num_obj.to_i * 20
offset += jump
else
if obj.to_i <= ( start_obj.to_i + num_obj.to_i - 1)
if obj.to_i <= ( start_obj.to_i + num_obj.to_i - 1)
jump = (obj.to_i - start_obj.to_i) * 20
offset += jump
found = true
@ -104,34 +104,34 @@ module Msf
offset += jump
end
end
xrefs.index(/(\d+) (\d+)\r?\n?/m,offset)
match = Regexp.last_match
end
end
if found
offset_end = offset + 11
return xrefs[offset..offset_end].to_i
else
return nil
end
end
def parse_object(xref_trailers,obj_name,stream)
for xrefs in xref_trailers
offset = object_locate(xrefs,obj_name)
if offset
if offset
break
end
end
if offset
if offset
stream.index(/endobj/,offset)
object_end = Regexp.last_match.end(0)
return stream[offset..object_end]
@ -139,22 +139,22 @@ module Msf
return nil
end
end
def xref_create(stream,offset,num_obj)
xref = Array.new()
object = String.new()
case
when num_obj.to_s == "1"
obj = stream.index(/(\d+) \d obj/,offset)
if obj
num = obj.to_s
dif = 10 - num.length
out = String.new
while dif > 0
while dif > 0
out << "0"
dif -= 1
end
@ -162,13 +162,13 @@ module Msf
xref.push("#{out}")
object = "#{Regexp.last_match(1)}"
end
when num_obj.to_s == "*"
len = stream.length
n = offset
while n < len
obj = stream.index(/(\d+) \d obj/,n)
while n < len
obj = stream.index(/(\d+) \d obj/,n)
if obj != nil
num = obj.to_s
dif = 10 - num.length
@ -177,10 +177,10 @@ module Msf
out << "0"
dif -= 1
end
out << num
out << num
xref.push("#{out}")
n = Regexp.last_match.end(0)
n = Regexp.last_match.end(0)
if object.empty?
object = "#{Regexp.last_match(1)}"
end
@ -188,59 +188,59 @@ module Msf
break
end
end
end
output = String.new()
output << "#{object} #{xref.length}\r\n"
xref.each {|xref_| output << "#{xref_} 00000 n\r\n"}
return output
end
def parse_pdf(stream)
xref_array = Array.new()
startxrefs = Array.new()
startxref_offsets = Hash.new()
xref_trailers = Array.new()
xref_trailer = Hash.new()
trailers = Array.new()
trailer = Hash.new()
len = stream.length
n = 0
while n < len
obj = stream.index(/startxref\r?\n?/m,n)
while n < len
obj = stream.index(/startxref\r?\n?/m,n)
if obj != nil
n = Regexp.last_match.end(0)
n = Regexp.last_match.end(0)
stream.index(/\d+/,n)
startxref_offsets["#{Regexp.last_match}"] = "#{obj}"
startxrefs.push("#{Regexp.last_match}")
startxrefs.push("#{Regexp.last_match}")
else
break
end
end
xref_trailer = xref_trailer_parse(startxrefs.last.to_i,stream)
xref_trailers.push(xref_trailer)
trailer = trailer_parse(xref_trailer)
trailer = trailer_parse(xref_trailer)
trailers.push(trailer)
root_obj = trailers[0].fetch("Root")
while trailer["Prev"]
while trailer["Prev"]
xref_trailer = xref_trailer_parse(trailer.fetch("Prev").to_i,stream)
xref_trailers.push(xref_trailer)
trailer = trailer_parse(xref_trailer)
trailers.each {|check| if check.fetch("Prev") == trailer["Prev"] then trailer.delete("Prev") end}
if trailer.has_key?("Prev")
@ -250,7 +250,8 @@ module Msf
return xref_trailers, trailers, startxrefs, root_obj
end
end
end
end

View File

@ -904,7 +904,7 @@ class Core
end
begin
regex = Regexp.new(match, true)
regex = Regexp.new(match, true, 'n')
rescue RegexpError => e
print_error("Invalid regular expression: #{match} (hint: try .*)")
return

View File

@ -56,7 +56,7 @@ module Msf
# Perform the search
found = []
filter = Regexp.new(text, Regexp::IGNORECASE)
filter = Regexp.new(text, Regexp::IGNORECASE, 'n')
$gtk2driver.module_tree.refresh(filter)
$gtk2driver.module_tree.expand
@ -115,4 +115,4 @@ module Msf
end
end
end
end

View File

@ -74,7 +74,7 @@ module Net # :nodoc:
Net::DNS::RR::Classes.regexp +
"|CLASS\\d+)?\\s*(" +
Net::DNS::RR::Types.regexp +
"|TYPE\\d+)?\\s*(.*)$", Regexp::IGNORECASE)
"|TYPE\\d+)?\\s*(.*)$", Regexp::IGNORECASE, 'n')
# Dimension of the sum of class, type, TTL and rdlength fields in a
# RR portion of the packet, in bytes

View File

@ -1,4 +1,3 @@
#!/usr/bin/env ruby
# $Id$
@ -6,19 +5,19 @@ module Rex
module ElfScan
module Scanner
class Generic
attr_accessor :elf, :regex
def initialize(elf)
self.elf = elf
end
def config(param)
end
def scan(param)
config(param)
$stdout.puts "[#{param['file']}]"
elf.program_header.each do |program_header|
@ -33,7 +32,7 @@ class Generic
end
end
end
end
def scan_segment(program_header, param={})
[]
@ -44,7 +43,7 @@ class JmpRegScanner < Generic
def config(param)
regnums = param['args']
# build a list of the call bytes
calls = _build_byte_list(0xd0, regnums - [4]) # note call esp's don't work..
jmps = _build_byte_list(0xe0, regnums)
@ -58,7 +57,7 @@ class JmpRegScanner < Generic
regexstr += "\xff[#{jmps}]|([#{pushs1}]|\xff[#{pushs2}])(\xc3|\xc2..))"
self.regex = Regexp.new(regexstr)
self.regex = Regexp.new(regexstr, nil, 'n')
end
# build a list for regex of the possible bytes, based on a base
@ -119,7 +118,7 @@ class JmpRegScanner < Generic
else
raise "wtf"
end
else
else
regname = Rex::Arch::X86.reg_name32(byte1 & 0x7)
retsize = _ret_size(offset+1)
message = "push #{regname}; " + _parse_ret(elf.read(offset+1, retsize))
@ -137,7 +136,7 @@ class PopPopRetScanner < JmpRegScanner
def config(param)
pops = _build_byte_list(0x58, (0 .. 7).to_a - [4]) # we don't want pop esp's...
self.regex = Regexp.new("[#{pops}][#{pops}](\xc3|\xc2..)")
self.regex = Regexp.new("[#{pops}][#{pops}](\xc3|\xc2..)", nil, 'n')
end
def scan_segment(program_header, param={})
@ -172,7 +171,7 @@ end
class RegexScanner < JmpRegScanner
def config(param)
self.regex = Regexp.new(param['args'])
self.regex = Regexp.new(param['args'], nil, 'n')
end
def scan_segment(program_header, param={})
@ -186,12 +185,12 @@ class RegexScanner < JmpRegScanner
idx = offset
buf = ''
mat = nil
while (! (mat = buf.match(regex)))
buf << elf.read(idx, 1)
idx += 1
end
rva = elf.offset_to_rva(offset)
hits << [ rva, buf.unpack("H*") ]
@ -200,8 +199,9 @@ class RegexScanner < JmpRegScanner
return hits
end
end
end
end
end
end

View File

@ -41,7 +41,7 @@ class Generic
end
end
end
end
def scan_segment(segment, param={})
[]
@ -66,7 +66,7 @@ class JmpRegScanner < Generic
regexstr += "\xff[#{jmps}]|([#{pushs1}]|\xff[#{pushs2}])(\xc3|\xc2..))"
self.regex = Regexp.new(regexstr)
self.regex = Regexp.new(regexstr, nil, 'n')
end
# build a list for regex of the possible bytes, based on a base
@ -127,7 +127,7 @@ class JmpRegScanner < Generic
else
raise "wtf"
end
else
else
regname = Rex::Arch::X86.reg_name32(byte1 & 0x7)
retsize = _ret_size(offset+1)
message = "push #{regname}; " + _parse_ret(mach.read(offset+1, retsize))
@ -145,7 +145,7 @@ class PopPopRetScanner < JmpRegScanner
def config(param)
pops = _build_byte_list(0x58, (0 .. 7).to_a - [4]) # we don't want pop esp's...
self.regex = Regexp.new("[#{pops}][#{pops}](\xc3|\xc2..)")
self.regex = Regexp.new("[#{pops}][#{pops}](\xc3|\xc2..)", nil, 'n')
end
def scan_segment(segment, param={})
@ -181,7 +181,7 @@ end
class RegexScanner < JmpRegScanner
def config(param)
self.regex = Regexp.new(param['args'])
self.regex = Regexp.new(param['args'], nil, 'n')
end
def scan_segment(segment, param={})
@ -209,8 +209,9 @@ class RegexScanner < JmpRegScanner
end
return hits
end
end
end
end
end
end

View File

@ -3,22 +3,22 @@ module PeScan
module Analyze
require "rex/ui/text/table"
class Fingerprint
attr_accessor :pe
def initialize(pe)
self.pe = pe
end
def config(param)
@sigs = {}
name = nil
regx = ''
epon = 0
sidx = 0
fd = File.open(param['database'], 'rb')
fd.each_line do |line|
case line
@ -42,35 +42,35 @@ module Analyze
epon = ($1 =~ /^T/i) ? 1 : 0
end
end
if (name and ! @sigs[name])
@sigs[ name ] = [regx, epon]
end
fd.close
end
def scan(param)
config(param)
epa = pe.hdr.opt.AddressOfEntryPoint
buf = pe.read_rva(epa, 256)
@sigs.each_pair do |name, data|
begin
if (buf.match(Regexp.new('^' + data[0])))
if (buf.match(Regexp.new('^' + data[0], nil, 'n')))
$stdout.puts param['file'] + ": " + name
end
rescue RegexpError
$stderr.puts "Invalid signature: #{name} #{data[0]}"
end
end
end
end
end
class Information
attr_accessor :pe
def initialize(pe)
self.pe = pe
end
@ -86,9 +86,9 @@ module Analyze
end
def scan(param)
$stdout.puts "\n\n"
tbl = table("Image Headers", ['Name', 'Value'])
add_fields(tbl, pe.hdr.file, %W{
Characteristics
@ -137,7 +137,7 @@ module Analyze
$stdout.puts tbl.to_s
$stdout.puts "\n\n"
if (pe.exports)
if (pe.exports)
tbl = table("Exported Functions", ['Ordinal', 'Name', 'Address'])
pe.exports.entries.each do |ent|
tbl << [ent.ordinal, ent.name, "0x%.8x" % pe.rva_to_vma(ent.rva)]
@ -145,7 +145,7 @@ module Analyze
$stdout.puts tbl.to_s
$stdout.puts "\n\n"
end
if (pe.imports)
tbl = table("Imported Functions", ['Library', 'Ordinal', 'Name'])
pe.imports.each do |lib|
@ -156,10 +156,10 @@ module Analyze
$stdout.puts tbl.to_s
$stdout.puts "\n\n"
end
if(pe.config)
tbl = table("Configuration Header", ['Name', 'Value'])
add_fields(tbl, pe.config, %W{
add_fields(tbl, pe.config, %W{
Size
TimeDateStamp
MajorVersion
@ -195,16 +195,16 @@ module Analyze
$stdout.puts tbl.to_s
$stdout.puts "\n\n"
end
tbl = table("Section Header", ["Name", "VirtualAddress", "SizeOfRawData", "Characteristics"])
pe.sections.each do |sec|
tbl << [ sec.name, *[sec.vma, sec.raw_size, sec.flags].map{|x| "0x%.8x" % x} ]
tbl << [ sec.name, *[sec.vma, sec.raw_size, sec.flags].map{|x| "0x%.8x" % x} ]
end
$stdout.puts tbl.to_s
$stdout.puts "\n\n"
end
$stdout.puts "\n\n"
end
def table(name, cols)
Rex::Ui::Text::Table.new(
'Header' => name,
@ -215,70 +215,70 @@ module Analyze
class Ripper
require "fileutils"
attr_accessor :pe
def initialize(pe)
self.pe = pe
end
def scan(param)
dest = param['dir']
if (param['file'])
dest = File.join(dest, File.basename(param['file']))
end
::FileUtils.mkdir_p(dest)
pe.resources.keys.sort.each do |rkey|
res = pe.resources[rkey]
path = File.join(dest, rkey.split('/')[1] + '_' + res.file)
fd = File.new(path, 'w')
fd = File.new(path, 'wb')
fd.write(res.data)
fd.close
end
end
end
end
class ContextMapDumper
attr_accessor :pe
def initialize(pe)
self.pe = pe
end
def scan(param)
dest = param['dir']
path = ''
::FileUtils.mkdir_p(dest)
if(not (param['dir'] and param['file']))
$stderr.puts "No directory or file specified"
return
end
if (param['file'])
path = File.join(dest, File.basename(param['file']) + ".map")
end
fd = File.new(path, "w")
fd = File.new(path, "wb")
pe.all_sections.each do |section|
# Skip over known bad sections
next if section.name == ".data"
next if section.name == ".reloc"
offset = 0
while offset < section.size
byte = section.read(offset, 1)[0]
if byte != 0
chunkbase = pe.rva_to_vma( section.base_rva) + offset
chunkbase = pe.rva_to_vma(section.base_rva) + offset
data = ''
while byte != 0
data << byte
@ -288,21 +288,22 @@ module Analyze
end
buff = nil
buff = [ 0x01, chunkbase, data.length, data].pack("CNNA*") if data.length > 0
fd.write(buff) if buff
end
offset += 1
end
end
fd.close
end
end
# EOC
end
end
end

View File

@ -3,48 +3,48 @@ module PeScan
module Scanner
class Generic
attr_accessor :pe, :regex
def initialize(pe)
self.pe = pe
end
def config(param)
end
def scan(param)
config(param)
$stdout.puts "[#{param['file']}]"
pe.all_sections.each do |section|
hits = scan_section(section, param)
hits.each do |hit|
vma = pe.rva_to_vma(hit[0])
next if (param['filteraddr'] and [vma].pack("V").reverse !~ /#{param['filteraddr']}/)
msg = hit[1].is_a?(Array) ? hit[1].join(" ") : hit[1]
$stdout.puts pe.ptr_s(vma) + " " + msg
if(param['disasm'])
::Rex::Assembly::Nasm.disassemble([msg].pack("H*")).split("\n").each do |line|
$stdout.puts "\t#{line.strip}"
end
end
end
end
end
end
end
def scan_section(section, param={})
[]
end
end
class JmpRegScanner < Generic
def config(param)
regnums = param['args']
# build a list of the call bytes
calls = _build_byte_list(0xd0, regnums - [4]) # note call esp's don't work..
jmps = _build_byte_list(0xe0, regnums)
@ -58,7 +58,7 @@ module Scanner
regexstr += "\xff[#{jmps}]|([#{pushs1}]|\xff[#{pushs2}])(\xc3|\xc2..))"
self.regex = Regexp.new(regexstr)
self.regex = Regexp.new(regexstr, nil, 'n')
end
# build a list for regex of the possible bytes, based on a base
@ -119,7 +119,7 @@ module Scanner
else
raise "wtf"
end
else
else
regname = Rex::Arch::X86.reg_name32(byte1 & 0x7)
retsize = _ret_size(section, index+1)
message = "push #{regname}; " + _parse_ret(section.read(index+1, retsize))
@ -132,12 +132,12 @@ module Scanner
return hits
end
end
class PopPopRetScanner < JmpRegScanner
def config(param)
pops = _build_byte_list(0x58, (0 .. 7).to_a - [4]) # we don't want pop esp's...
self.regex = Regexp.new("[#{pops}][#{pops}](\xc3|\xc2..)")
self.regex = Regexp.new("[#{pops}][#{pops}](\xc3|\xc2..)", nil, 'n')
end
def scan_section(section, param={})
@ -169,9 +169,9 @@ module Scanner
end
class RegexScanner < JmpRegScanner
def config(param)
self.regex = Regexp.new(param['args'])
self.regex = Regexp.new(param['args'], nil, 'n')
end
def scan_section(section, param={})
@ -184,12 +184,12 @@ module Scanner
idx = index
buf = ''
mat = nil
while (! (mat = buf.match(regex)))
buf << section.read(idx, 1)
idx += 1
end
rva = section.offset_to_rva(index)
hits << [ rva, buf.unpack("H*") ]
@ -198,8 +198,9 @@ module Scanner
return hits
end
end
end
end
end
end

View File

@ -24,7 +24,7 @@ class Handle
uuid_re = '[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}'
rev_re = '\d+.\d+'
proto_re = '(?:' + @@protocols.join('|') + ')'
re = Regexp.new("(#{uuid_re}):(#{rev_re})\@(#{proto_re}):(.*?)\\[(.*)\\]$")
re = Regexp.new("(#{uuid_re}):(#{rev_re})\@(#{proto_re}):(.*?)\\[(.*)\\]$", true, 'n')
match = re.match(handle)
raise ArgumentError if !match
@ -44,4 +44,4 @@ class Handle
end
end
end
end
end

View File

@ -168,7 +168,7 @@ module Text
# the regex the first time it is used and never check again. Since we
# want to know how many to capture on every instance, we do it this
# way.
return str.unpack('H*')[0].gsub(Regexp.new(".{#{count * 2}}")) { |s| prefix + s }
return str.unpack('H*')[0].gsub(Regexp.new(".{#{count * 2}}", nil, 'n')) { |s| prefix + s }
end
#

View File

@ -465,7 +465,7 @@ module Zip
end
path = @file.expand_path(aDirectoryName).ensure_end("/")
subDirEntriesRegex = Regexp.new("^#{path}([^/]+)$")
subDirEntriesRegex = Regexp.new("^#{path}([^/]+)$", nil, 'n')
@mappedZip.each {
|fileName|
match = subDirEntriesRegex.match(fileName)
@ -606,4 +606,4 @@ end
# Copyright (C) 2002, 2003 Thomas Sondergaard
# rubyzip is free software; you can redistribute it and/or
# modify it under the terms of the ruby license.
# modify it under the terms of the ruby license.

View File

@ -76,7 +76,7 @@ module Kernel #:nodoc:all
end
def already_loaded?(moduleName)
moduleRE = Regexp.new("^"+moduleName+"(\.rb|\.so|\.dll|\.o)?$")
moduleRE = Regexp.new("^"+moduleName+"(\.rb|\.so|\.dll|\.o)?$", nil, 'n')
$".detect { |e| e =~ moduleRE } != nil
end
@ -87,4 +87,4 @@ end
# Copyright (C) 2002 Thomas Sondergaard
# rubyzip is free software; you can redistribute it and/or
# modify it under the terms of the ruby license.
# modify it under the terms of the ruby license.