lib/bisc/elf_assembler.rb
require 'rex/elfparsey'
require 'rex/elfscan'
require 'bisc/assembler'
require 'bisc/elf/executable'
module BISC
class ELFAssembler < Assembler
PF_X = (1 << 0)
PF_W = (1 << 1)
PT_LOAD = Rex::ElfParsey::ElfBase::PT_LOAD
#
# Add and ELF module for to be scanned for usable instructions
#
def add_module(path)
elf = BISC::ELF::Executable.new(path)
elfname = File.basename(path)
@modules[elfname] = elf
if elf.header.e_type == Rex::ElfParsey::ElfBase::ET_DYN
raise(Error,"#{path} is ASLR enabled...")
end
scanner = Rex::ElfScan::Scanner::RegexScanner.new(elf.elf)
elf.segments.each do |header|
next unless header.p_type == PT_LOAD && header.p_flags & PF_X == PF_X
PATTERNS.keys.each do |pattern|
re = Regexp.new("#{pattern}(\\xC3)", nil, 'n')
scanner.regex = re
hits = scanner.scan_segment(header)
hits.each do |hit|
address = hit[0]
bytes = hit[1][0]
matchdata = re.match([bytes].pack('H*'))
if matchdata
sym = PATTERNS[pattern].call(matchdata)
if @instructions[sym] == nil
@instructions[sym] = []
end
@instructions[sym].push(address)
end
end
end
end
# Add slack space
elf.segments.each do |header|
next unless header.p_type == PT_LOAD && header.p_flags & PF_W == PF_W
slack_begin = header.p_vaddr + header.p_memsz;
slack_end = (slack_begin + header.p_align) & ~(header.p_align - 1)
@slack_space.push([slack_begin, slack_begin, slack_end])
end
end
def get_iat_pointer(fn_name)
@modules.values.each do |mod|
return mod.imports[fn_name] if mod.imports.include? fn_name
end
end
end
end