The video on Vimeo will be available at: http://vimeo.com/20256351 if the conversion goes properly. I'll edit to include my conversion options as the output file was TINY by comparison to other videos and still great resolution. We'll see...more to follow on that part.
Securitytube link goes here(when it's approved)
Note: I really appreciate securitytube linking to me. They are responsibly for most of my traffic at the moment.
The code is available at github. aking1012/bindiff-ruby
Thanks for reading. Hope you enjoy it.
Tuesday, February 22, 2011
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
#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
Ep1Pt1 Ruby4Hackers - An Immunity Debugger connector and binary dumper
It is a little fuzzy. I can still read the pertinent code sections. We don't need to see the immdbg window in this tutorial, so the very blurry on that one is okay. Original ogv is available if requested (1440x900 and really sharp).
Link to vimeo: http://vimeo.com/20135554
On SecurityTube: http://www.securitytube.net/Ruby-for-Hackers-Ep1-Pt1-Getting-ready-to-write-our-own-Binary-Diffing-Engine-video.aspx
The securitytube link has a high res download available it you want to see the code.
When all parts of this tutorial are complete code may be available for download or posted on RCE. Most of following along with this part is getting the environment set up so the broad strokes are sorted out and working. In the next video we will move on to the actual binary diffing and seeing code more sharply will be critical.
The upload should be at 1280x720, but the re-encode to mp4 degrades the quality(and vimeo chokes on gtkrecordmydesktop ogv files because of the swscaler stream). For this reason I have to use ffmpeg to re-encode as mp4 with different bearer streams. Then next part will be sharper, I was just REALLY tired.
Link to vimeo: http://vimeo.com/20135554
On SecurityTube: http://www.securitytube.net/Ruby-for-Hackers-Ep1-Pt1-Getting-ready-to-write-our-own-Binary-Diffing-Engine-video.aspx
The securitytube link has a high res download available it you want to see the code.
When all parts of this tutorial are complete code may be available for download or posted on RCE. Most of following along with this part is getting the environment set up so the broad strokes are sorted out and working. In the next video we will move on to the actual binary diffing and seeing code more sharply will be critical.
The upload should be at 1280x720, but the re-encode to mp4 degrades the quality(and vimeo chokes on gtkrecordmydesktop ogv files because of the swscaler stream). For this reason I have to use ffmpeg to re-encode as mp4 with different bearer streams. Then next part will be sharper, I was just REALLY tired.
Thursday, February 17, 2011
So over on questions.securitytube.net a user named me asked about ImmDbg binary diffing and wanted a cut and paste plug-in.
This is not a cut and paste plugin, but it does dump function locations and addresses...
# bindiff PyCommand - (c) Andrew King
# TODO:
# - a LOT
# liberated some code from other scripts built by immunity.
# this arrangement, however, is mine.
import immlib
import immutils
import libdatatype
import getopt
from immlib import *
__VERSION__ = '0.la'
DESC = "A start on bindiff for immdbg"
ProgName = 'bindiff'
ProgVers = __VERSION__
def usage(imm):
imm.log("%s v%s aking1012 -> team notATeam : response to a question on questions.securitytube.net" % (ProgName, ProgVers),focus=1, highlight=1)
imm.log("!%s Runs through all function calls and dumps the basic blocks for binary diff-ing" % (NAME))
imm.log("usage !bindiff -i modulename")
imm.log("%s v%s aking1012 -> team notATeam : response to a question on questions.securitytube.net" % (ProgName, ProgVers),focus=1, highlight=1)
def main(args):
imm = Debugger()
include_pattern = exclude_pattern = None
try:
opts, args = getopt.getopt(args, "i:")
except getopt.GetoptError:
usage(imm)
return "Incorrect arguments (Check log window)"
for o, a in opts:
if o == "-i":
image_name = a
else:
usage(imm)
return "Incorrect arguments (Check log window)"
imm.markBegin()
module = imm.getModule( image_name )
modadd = module.getBase()
func_list = imm.getAllFunctions( modadd )
i=0
for f in func_list:
i=1+i
function=imm.getFunction(f)
sof = imm.getFunctionBegin(f)
imm.log("Start of function: %x - end " % (sof))
basicblocks = function.getBasicBlocks(f)
for bb in basicblocks:
imm.log(" basicblock duration: %x - end %x" % (bb.start,bb.end))
inst_set=bb.getInstructions(imm)
for inst in inst_set:
imm.log(" assembly: %s" % inst.result)
totaltime=imm.markEnd()
imm.log("Used time: %d seconds" % totaltime)
return "[*] Got'em."
# bindiff PyCommand - (c) Andrew King
# TODO:
# - a LOT
# liberated some code from other scripts built by immunity.
# this arrangement, however, is mine.
import immlib
import immutils
import libdatatype
import getopt
from immlib import *
__VERSION__ = '0.la'
DESC = "A start on bindiff for immdbg"
ProgName = 'bindiff'
ProgVers = __VERSION__
def usage(imm):
imm.log("%s v%s aking1012 -> team notATeam : response to a question on questions.securitytube.net" % (ProgName, ProgVers),focus=1, highlight=1)
imm.log("!%s Runs through all function calls and dumps the basic blocks for binary diff-ing" % (NAME))
imm.log("usage !bindiff -i modulename")
imm.log("%s v%s aking1012 -> team notATeam : response to a question on questions.securitytube.net" % (ProgName, ProgVers),focus=1, highlight=1)
def main(args):
imm = Debugger()
include_pattern = exclude_pattern = None
try:
opts, args = getopt.getopt(args, "i:")
except getopt.GetoptError:
usage(imm)
return "Incorrect arguments (Check log window)"
for o, a in opts:
if o == "-i":
image_name = a
else:
usage(imm)
return "Incorrect arguments (Check log window)"
imm.markBegin()
module = imm.getModule( image_name )
modadd = module.getBase()
func_list = imm.getAllFunctions( modadd )
i=0
for f in func_list:
i=1+i
function=imm.getFunction(f)
sof = imm.getFunctionBegin(f)
imm.log("Start of function: %x - end " % (sof))
basicblocks = function.getBasicBlocks(f)
for bb in basicblocks:
imm.log(" basicblock duration: %x - end %x" % (bb.start,bb.end))
inst_set=bb.getInstructions(imm)
for inst in inst_set:
imm.log(" assembly: %s" % inst.result)
totaltime=imm.markEnd()
imm.log("Used time: %d seconds" % totaltime)
return "[*] Got'em."
Tuesday, February 15, 2011
New video on vimeo
Approved on Securitytube.
Here's the link: http://www.securitytube.net/Exploit-Research-Megaprimer-Part-9-Guest-Lecture-by-Andrew-King-video.aspx
Link to vimeo: http://vimeo.com/19971212
It's a SEH Exploitation Tutorial video I made to help out Vivek with his Exploitation Megaprimer. Happy bug hunting.
Here's the link: http://www.securitytube.net/Exploit-Research-Megaprimer-Part-9-Guest-Lecture-by-Andrew-King-video.aspx
Link to vimeo: http://vimeo.com/19971212
It's a SEH Exploitation Tutorial video I made to help out Vivek with his Exploitation Megaprimer. Happy bug hunting.
Tuesday, February 8, 2011
Working with binary in ruby...without bit-struct etc
test = String.new
File.open('../data/sourcefile').each do |line|
#combine the strings into one long string
test = test + line
end
#get hex and binary representations of the file...
#no I am not easy on memory
testa = test.unpack('H*')
testb = test.unpack('B*')
#this is so we get the strings and can do substring stuff.
testc = testa[0]
testd = testb[0]
teste = Array.new
testf = Array.new
#in here i was testing how to set a single bit
p testd
p testd[0..7]
testd[7] = '0'
p testd
teste[0] = testc
testf[0] = testd
#and reverse the transform
testg = teste.pack('H*')
testh = testf.pack('B*')
#i tested it...oddly enough it preserves newlines and nulls
#even though my conversion was...lacking finesse
#but it's the easiest way i could find
p testg
p testh
-------------
Thinking if I wanted to add a single bit to the end of a binary string I could to a pack on a single 1 and add the strings together...Hmm, anyway. Using this snippet in a targeted fuzzer I am trying to put together. Need to make some conversion classes and the like, but you get the idea. That's all for now.
File.open('../data/sourcefile').each do |line|
#combine the strings into one long string
test = test + line
end
#get hex and binary representations of the file...
#no I am not easy on memory
testa = test.unpack('H*')
testb = test.unpack('B*')
#this is so we get the strings and can do substring stuff.
testc = testa[0]
testd = testb[0]
teste = Array.new
testf = Array.new
#in here i was testing how to set a single bit
p testd
p testd[0..7]
testd[7] = '0'
p testd
teste[0] = testc
testf[0] = testd
#and reverse the transform
testg = teste.pack('H*')
testh = testf.pack('B*')
#i tested it...oddly enough it preserves newlines and nulls
#even though my conversion was...lacking finesse
#but it's the easiest way i could find
p testg
p testh
-------------
Thinking if I wanted to add a single bit to the end of a binary string I could to a pack on a single 1 and add the strings together...Hmm, anyway. Using this snippet in a targeted fuzzer I am trying to put together. Need to make some conversion classes and the like, but you get the idea. That's all for now.
Subscribe to:
Posts (Atom)