sqlmap源码阅读(一)
本人菜鸟一枚,最近开始阅读sqlmap源码,如有错误,多多指教!
首先一点,在看源码的时候发现很多函数的函数体只有一个pass,有两种可能:
1、父类中声明函数,但不声明实现,由继承的子类进行实现,也就是说这就是一个空方法;
2、这个函数的具体实现不用Python编写,而是由例如C这种高效语法编写,在包中只用一个空方法占位,调用的时候是调用C语言实现的方法,这里定义的函数只是类似于一个接口。Python中有一些需要大量运算的内置函数是用C或者C++写的。
pass
- 先从sqlmap.py的main函数开始,这一章简单分析一些main函数开始的几个被调用函数
main.py
def main():
"""
Main function of sqlmap when running from command line.
"""
try:
dirtyPatches()
resolveCrossReferences()
checkEnvironment() #检测环境
setPaths(modulePath()) #为一些目录和文件设置了绝对路径
banner() #打印sqlmap banner信息
.....
.....
(这一章先分析以上几个函数,所以后面代码省略)
dirtyPatches()
patch.py:
def dirtyPatches():
"""
Place for "dirty" Python related patches
"""
# accept overly long result lines (e.g. SQLi results in HTTP header responses)
# 接受过长的结果行(例如HTTP头响应中的SQLi结果)
_http_client._MAXLINE = 1 * 1024 * 1024
# prevent double chunked encoding in case of sqlmap chunking (Note: Python3 does it automatically if 'Content-length' is missing)
# 在sqlmap分块的情况下防止双块编码(注意:如果缺少“Content-length”,Python3会自动执行)
if six.PY3:#在python3下运行返回true
if not hasattr(_http_client.HTTPConnection, "__send_output"):
_http_client.HTTPConnection.__send_output = _http_client.HTTPConnection._send_output
def _send_output(self, *args, **kwargs):
if conf.get("chunked") and "encode_chunked" in kwargs:
kwargs["encode_chunked"] = False
self.__send_output(*args, **kwargs)
_http_client.HTTPConnection._send_output = _send_output
# add support for inet_pton() on Windows OS
if IS_WIN:
from thirdparty.wininetpton import win_inet_pton
# Reference: https://github.com/nodejs/node/issues/12786#issuecomment-298652440
codecs.register(lambda name: codecs.lookup("utf-8") if name == "cp65001" else None)
# Reference: http://bugs.python.org/issue17849
if hasattr(_http_client, "LineAndFileWrapper"):
def _(self, *args):
return self._readline()
_http_client.LineAndFileWrapper._readline = _http_client.LineAndFileWrapper.readline
_http_client.LineAndFileWrapper.readline = _
# to prevent too much "guessing" in case of binary data retrieval
thirdparty.chardet.universaldetector.MINIMUM_THRESHOLD = 0.90
逐一分析这个函数
1. _http_client._MAXLINE = 1 * 1024 * 1024
_http_client是对http包里的client.py文件的别名
import http.client as _http_client
_MAXLINE是读取客户端http请求时的最大行长度限制,原本是65536,这里设置为1024*1024=1048576(为什么这多行?)
# maximal line length when calling readline().
#调用readline()时的最大行长度
_MAXLINE = 65536
检查版本是不是py3,是的话做相应设置,不是的话按py2执行
if six.PY3
检查HTTPConnection有没有叫做__send_output的属性,没有就设置一下
if not hasattr(_http_client.HTTPConnection, "__send_output"):
_http_client.HTTPConnection.__send_output = _http_client.HTTPConnection._send_output
分析hasattr函数和_send_output函数
builtins.py:
def hasattr(*args, **kwargs): # real signature unknown
"""
Return whether the object has an attribute with the given name.
返回对象是否具有具有给定名称的属性。
This is done by calling getattr(obj, name) and catching AttributeError.
这是通过调用getattr(obj, name)和捕获AttributeError来完成的。
"""
pass
client.py:
def _send_output(self, message_body=None, encode_chunked=False):
"""Send the currently buffered request and clear the buffer.
发送当前缓冲的请求并清除缓冲区。
Appends an extra \\r\\n to the buffer.
向缓冲区追加一个额外的\\r\ n
A message_body may be specified, to be appended to the request.
可以指定message_body,将其附加到请求中
"""
#给缓冲区添加一个元组
self._buffer.extend((b"", b""))
#拼接起来传给msg
msg = b"\r\n".join(self._buffer)
#清空缓冲区
del self._buffer[:]
#send方法是把msg发送给服务器
self.send(msg)
if message_body is not None:
.......(由于前面是无参调用,所以message_body=None,因此下面的代码我就省略了)
这里有个疑问,_send_output函数没有返回值,那他怎么会放在赋值语句_http_client.HTTPConnection.__send_output = _http_client.HTTPConnection._send_output的右边的?
解答:这里涉及到调用函数时带括号与不带括号的区别,带括号是调用函数体,需要执行这个函数,不带括号,只是调用这个函数对象,不需要执行。按上面的具体情况就是,把HTTPConnection的__send_output变成_send_output函数,执行前者就相当于执行后者。
回到dirtPatches:
def _send_output(self, *args, **kwargs):
if conf.get("chunked") and "encode_chunked" in kwargs:
kwargs["encode_chunked"] = False
self.__send_output(*args, **kwargs)
_http_client.HTTPConnection._send_output = _send_output
这里又把HTTPConnection的_send_output函数更新了,这就是当py版本是3而不是2时,对函数进行调整。
# 在Windows操作系统上添加对inet_pton()的支持
if IS_WIN:
from thirdparty.wininetpton import win_inet_pton
# Reference: https://github.com/nodejs/node/issues/12786#issuecomment-