Saturday, February 19, 2011

Ruby for hackers code snippet 2, the bindump class

#!/usr/bin/env ruby
#Class file for ruby function and basic block importing from immunity dumps.
#I may add conversion of the vcg files to dot files and some basic block
#highlighting.

class Bindump
@organized = Array.new

def initialize(filename)
funclist = Array.new
funclist.push("Start address","End address","Content array")
afunc = Array.new
afunc.push("Start address block","End address","Content array")
abb = Array.new
som = "" #not implemented
sof = ""
eof = ""
sob = ""
eob = ""
eom = ""
newf = false
newbb = false

File.open(filename).each { |line|
line.chomp!
#parse for start of binary address
#not implemented

#parse for start of function
if ( line.index('sof')!=nil )
 temparray = line.split(':')
 sof = temparray[1]

#parse for end of function
elsif ( line.index('eof')!=nil )
 temparray = line.split(':')
 eof = temparray[1]
 newf = true

#parse for start of basic block
elsif ( line.index('BBS')!=nil )
 temparray = line.split(':')
 sob = temparray[1]

#parse for end of basic block
elsif ( line.index('BBE')!=nil )
 temparray = line.split(':')
 eob = temparray[1]
 newbb = true

#if we get here it's either junk or basic block instructions
#trailing junk is okay, leading junk is not
else
 abb.push(line)
end


#check if a basic block is ready
if (newbb == true)
  #add our blocks to the function
  afunc.push(sob, eob, abb)
  #clear the array
  abb = Array.new
  abb.push("Start address block","End address","Content array")
  #set new block
  newbb = false
  #add the basic block to the function
elsif (newf == true)
  #check if a func is ready
  funclist.push(sof, eof, afunc)
  #clear the array
  afunc = Array.new
  afunc.push("Start address block","End address","Content array")
  #set new func 
  newf = false
end
  }
#fileread just ended
#copy it out of private to instance
@organized = funclist

end
#init just ended

def getorganized
 return @organized
end

def funccount
 return ((@organized.length)/3-1)
end

def bbcount(funcnum)
  startadd, endadd, allblocks = funcbynum(1)
  return (allblocks.length/3-1)
end

def funcbynum(funcnum)
  funcnum = funcnum
  startadd = @organized[funcnum]
  endadd = @organized[funcnum+1]
  function = @organized[funcnum+2]
  return startadd, endadd, function
end

def bbgetbynum(funcnum, bbnum)
  bbnum = bbnum
  startadd, endadd, data = funcbynum(funcnum)

  startadd = data[bbnum]
  endaddadd = data[bbnum+1]
  assembly = data[bbnum+2]
  return startadd, endadd, assembly
end

end
#end of bindump class

#Start of on execute

begin
if __FILE__ == $0
test = Bindump.new('immdump.old')
puts "The assembled array looks like this"
p test.getorganized
puts "Number of functions is"
puts test.funccount
puts "We get a function like this funcbynum(1) which returns"
startadd, endadd, basicblocks = test.funcbynum(1)
puts "The start address: " + startadd
puts "The end address: " + endadd
puts "The entire function with extra data: "
puts basicblocks
puts "The first function has this many basic blocks"
puts test.bbcount(1)
puts "The contents of the first function's first basic block are"
startdadd, endadd, code = test.bbgetbynum(1,1)
puts code
puts "The start address is: " + startadd
puts "The end address is: " + endadd
puts "Okay, so does the example make sense?"
end
end

No comments:

Post a Comment