Minor enhancement to internal --profile function

This commit is contained in:
Bernardo Damele 2010-05-21 15:06:05 +00:00
parent 20d05cc404
commit 03fb84e29f
5 changed files with 2248 additions and 24 deletions

View File

@ -85,9 +85,12 @@ Kasper Fons <thefeds@mail.dk>
for reporting a few bugs for reporting a few bugs
Jose Fonseca <jose.r.fonseca@gmail.com> Jose Fonseca <jose.r.fonseca@gmail.com>
for his Gprof2Dot utility for converting profiler output for his Gprof2Dot utility for converting profiler output to dot
to dot graph(s) included in sqlmap tree inside extras, graph(s) and for his XDot utility to render nicely dot graph(s),
http://gprof2dot.jrfonseca.googlecode.com/hg/gprof2dot.py both included in sqlmap tree inside extra folder. These libraries
are used for sqlmap development purposes only
http://code.google.com/p/jrfonseca/wiki/Gprof2Dot
http://code.google.com/p/jrfonseca/wiki/XDot
Alan Franzoni <alan.franzoni@gmail.com> Alan Franzoni <alan.franzoni@gmail.com>
for helping me out with Python subprocess library for helping me out with Python subprocess library

19
extra/gprof2dot/__init__.py Executable file
View File

@ -0,0 +1,19 @@
#!/usr/bin/env python
#
# Copyright 2008-2009 Jose Fonseca
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
pass

19
extra/xdot/__init__.py Executable file
View File

@ -0,0 +1,19 @@
#!/usr/bin/env python
#
# Copyright 2008-2009 Jose Fonseca
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
pass

2159
extra/xdot/xdot.py Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1093,50 +1093,74 @@ def isBase64EncodedString(subject):
def isHexEncodedString(subject): def isHexEncodedString(subject):
return re.match(r"\A[0-9a-fA-F]+\Z", subject) is not None return re.match(r"\A[0-9a-fA-F]+\Z", subject) is not None
def profile(profileOutputFile=None, imageOutputFile=None): def profile(profileOutputFile=None, dotOutputFile=None, imageOutputFile=None):
try:
from extra.gprof2dot import gprof2dot
from extra.xdot import xdot
import gobject
import gtk
import pydot
except ImportError, e:
logger.error(e)
return
if profileOutputFile is None: if profileOutputFile is None:
profileOutputFile = os.path.join(paths.SQLMAP_OUTPUT_PATH, "sqlmap_profile.raw") profileOutputFile = os.path.join(paths.SQLMAP_OUTPUT_PATH, "sqlmap_profile.raw")
if dotOutputFile is None:
dotOutputFile = os.path.join(paths.SQLMAP_OUTPUT_PATH, "sqlmap_profile.dot")
if imageOutputFile is None: if imageOutputFile is None:
imageOutputFile = os.path.join(paths.SQLMAP_OUTPUT_PATH, "sqlmap_profile.png") imageOutputFile = os.path.join(paths.SQLMAP_OUTPUT_PATH, "sqlmap_profile.png")
if os.path.exists(profileOutputFile): if os.path.exists(profileOutputFile):
os.remove(profileOutputFile) os.remove(profileOutputFile)
if os.path.exists(dotOutputFile):
os.remove(dotOutputFile)
if os.path.exists(imageOutputFile): if os.path.exists(imageOutputFile):
os.remove(imageOutputFile) os.remove(imageOutputFile)
infoMsg = "profiling the execution into file %s" % profileOutputFile infoMsg = "profiling the execution into file %s" % profileOutputFile
logger.info(infoMsg) logger.info(infoMsg)
# Start sqlmap main function and generate a raw profile file
cProfile.run("start()", profileOutputFile) cProfile.run("start()", profileOutputFile)
infoMsg = "converting profile data into a graph image '%s'" % imageOutputFile infoMsg = "converting profile data into a dot file '%s'" % dotOutputFile
logger.info(infoMsg) logger.info(infoMsg)
graphScriptPath = os.path.join(paths.SQLMAP_EXTRAS_PATH, 'gprof2dot', 'gprof2dot.py') # Create dot file by using extra/gprof2dot/gprof2dot.py
# http://code.google.com/p/jrfonseca/wiki/Gprof2Dot
dotFilePointer = open(dotOutputFile, 'wt')
parser = gprof2dot.PstatsParser(profileOutputFile)
profile = parser.parse()
profile.prune(0.5/100.0, 0.1/100.0)
dot = gprof2dot.DotWriter(dotFilePointer)
dot.graph(profile, gprof2dot.TEMPERATURE_COLORMAP)
dotFilePointer.close()
# TODO: find the Windows version of Unix command 'dot' infoMsg = "converting dot file into a graph image '%s'" % imageOutputFile
process = execute('%s %s -f pstats %s | dot -Tpng -o %s' % (sys.executable, graphScriptPath, profileOutputFile, imageOutputFile), shell=True, stdout=None, stderr=PIPE) logger.info(infoMsg)
processStderr = process.communicate()[1]
if processStderr or not os.path.exists(imageOutputFile): # Create graph image (png) by using pydot (python-pydot)
errMsg = "there was an error while converting ('%s'), " % processStderr.strip() # http://code.google.com/p/pydot/
errMsg += "but you can still find raw profile data " pydotGraph = pydot.graph_from_dot_file(dotOutputFile)
errMsg += "inside file '%s'" % profileOutputFile pydotGraph.write_png(imageOutputFile)
logger.error(errMsg)
return infoMsg = "displaying interactive graph with xdot library"
logger.info(infoMsg)
# Display interactive Graphviz dot file by using extra/xdot/xdot.py
# http://code.google.com/p/jrfonseca/wiki/XDot
win = xdot.DotWindow()
win.connect('destroy', gtk.main_quit)
win.set_filter("dot")
win.open_file(dotOutputFile)
gobject.timeout_add(1000, win.update, dotOutputFile)
gtk.main()
try:
if PLATFORM == 'mac':
subprocess.call(('open', imageOutputFile))
elif PLATFORM == 'posix':
subprocess.call(('xdg-open', imageOutputFile))
elif PLATFORM == 'nt':
subprocess.call(('start', imageOutputFile))
except:
pass
def getConsoleWidth(default=80): def getConsoleWidth(default=80):
width = None width = None