终于又到了一周一度的整理博客的时间了,博主平时课余时间看书,周末统一整理,坚持周更真是爱了爱了 ~
今天要说的是python面向对象这一部分的内容,今天这是基础篇的第二篇,也是最后一篇。
说来基础篇还真是少呢,第一篇说了一下函数部分比较难理解的闭包和装饰器
,今天说一下模块、包、对象、类
这部分。当然中途还有很多东西也很重要啊。
- 基础语法:尤其是字符串、列表和字典的操作,以及循环、判断的使用
- 文件处理:主要是文件的读写
- 异常处理:因为我们前期写的顶多就是些小脚本,辅助渗透用,没必要了解太多异常处理
这三部分,有一点编程基础的,网上找篇博客随便看看就能懂,不会的等遇到了直接百度,也比我现在写篇博客节省时间,所以就没写,但是我肯定都看了,哈哈。
因为平时渗透过程中,我们经常会用到别人写的脚本,或者使用渗透测试框架时也需要自己动手写POC/EXP之类的,甚至以后可能会自己写一些python脚本,所以python的函数、对象等等这部分内容是非常重要的。
我希望今天这部分结束后,我们至少可以做到能读懂别人的脚本,于是我就去随便下了一个dirmap
,等下在文章最后,大家和我一起读一下源码!
那废话不多说,开始今天的内容,包-> 模块-> 类-> 对象-> 方法,咦?为什么加个箭头呢?因为它们的关系确实如此:
- 模块:就是
.py
文件 - 包:就是一群
.py
文件所在的目录 - 类:狗就是一个类
- 对象:对象就是类的实例化,比如哈士奇、金毛、阿拉斯加
- 方法:实现具体逻辑的代码
包
如果一个目录下是一堆python文件,且其中有一个的话,那这个目录就是包,且目录名称就是包名。
我们可以使用import导入包/模块:
# 导入包import[包名1],[包名2]# 导入模块from[包名]import[模块名1],[模块名2]
模块
一个python文件就是一个模块,且文件名就是模块名。
我们可以使用import导入模块/函数
# 导入模块import[模块名1],[模块名2]# 导入函数from[模块名]import[函数名1],[函数名2]
类
从类开始,就是代码层面的了,类具体定义如果不知道的建议学一门面向对象的语言,这玩意解释起来太多了,网上文章也太多了,我不想写。
放一段最基本的python代码,先抛开面向对象编程的思想:声明一个类,里边有个方法,用来打印一句话
# 先声明一个Test类classTest():defprint_test(self,perm):print(perm)# 实例化一个test对象test=Test()# 调用print_test方法test.print_test('白帽子续命指南')
执行结果
对象
对象就是对类的实例化,具体语法格式如下:
方法
就是实现具体功能的代码
在类里边写它的主要逻辑,注意写的时候要加上self参数,这个必须加(除了类方法和静态方法,这两个不讨论)。语法格式为:
classTest():defprint_test(self,perm):print(perm)
创建一个实例对象之后,可以调用,调用格式:
# 对象名.方法名(参数)test.ptint_test('白帽子续命指南')
除此之外,方法也分很多种,比如带下划线的,还有类方法、静态方法等等,这里不细说,遇到了再去百度。简单说三种:
- 前边有两个下划线的:私有的,只有类自己可以访问,连子类都不能访问
- 前边有一个下划线的:保护变量,只有类和子类能访问,言外之意就是不能import
- 左右各两个下划线的:系统的
继承
继承就是子类和父类那一块的,语法格式为:
# 父类classCat():passclassAnimal():pass# 子类classKitty(Cat,Animal):pass
这样,Kitty这个类就继承了Cat和Animal这两个类的所有属性和方法(属性就是变量)。
重写
重写就是继承一个父类后,对父类中某个方法重新写一下。
语法上保证方法名和参数列表都一样,就OK了:
# 父类classCat():defprint_cat(self):print('喵~')classAnimal():defprint_live(self):print('活的')# 子类classKitty(Cat,Animal):defprint_live(self):print('死了')test=Kitty()test.print_live()
执行结果
读源码
项目地址: https:// gitee.com/c0ny10/dirmap
首先,下载好dirmap的源码后,进入到dirmap/中,看看都有什么。
.
├── LICENSE
├──
├──
├── data
│ ├──
│ ├──
│ ├── dictmult
│ │ ├──
│ │ ├──
│ │ └──
│ ├──
│ ├──
│ ├── fuzzmult
│ │ ├──
│ │ └──
│ └──
├──
├──
├── doc
│ ├──
│ ├──
│ ├──
│ ├──
│ ├──
│ ├──
│ └──
├── lib # 想这个lib/下面有,说明这个就是一个包啊
│ ├──
│ ├── controller # 这也是包
│ │ ├──
│ │ ├── bruter.py # 这就是所谓的模块
│ │ └──
│ ├── core
│ │ ├──
│ │ ├──
│ │ ├──
│ │ ├──
│ │ ├──
│ │ ├──
│ │ └──
│ ├── parse
│ │ ├──
│ │ └──
│ ├── plugins
│ │ ├──
│ │ └──
│ └── utils
│ ├──
│ ├──
│ └──
├──
└── thirdlib
├── IPy
│ ├── AUTHORS
│ ├── COPYING
│ ├── ChangeLog
│ ├──
│ ├──
│ ├── Makefile
│ ├── README
│ ├── example
│ │ ├── confbuilder
│ │ └──
│ ├──
│ ├── test
│ │ ├──
│ │ ├── test_
│ │ └──
│ └──
└── colorama
├──
├──
├──
├──
├──
└── winterm.py
15 directories, 61 files
看到有一个的文件,查看这个文件内容。
把代码复制过来,然后我给加上中文注释(我的注释,为了区分,前边用两个#):
c0ny100@dingzongdeMacBook-Airdirmap%vimdirmap.py## 以"#!"开头的,是用来指定python解释器的,这里是python3## 如果不指定你就不能用"./"来执行了#!/usr/bin/env python3# -*- coding: utf-8 -*-## 这里是作者信息,没什么好说的'''
@Author: xxlin
@LastEditors: xxlin
@Date: 2019-04-10 13:27:59
@LastEditTime: 2019-05-01 17:57:11
'''## 导入了两个模块importosimportsys## 这里的gevent是第三方库## 从gevent导入了一个monkey模块并调用了patch_all()方法fromgeventimportmonkeymonkey.patch_all()## 这里用了好几个点来导入,明显是文件路径## 我们知道python默认从当前目录开始搜,所以这个lib应该在的同级目录fromlib.controller.engineimportrunfromlib.core.commonimportbanner,outputscreen,setPathsfromlib.core.dataimportcmdLineOptions,conf,pathsfromlib.core.optionimportinitOptionsfromlib.parse.cmdlineimportcmdLineParser## 这个main函数就是用来调用刚刚导入进来的方法defmain():"""
main fuction of dirmap
"""# anyway output thr banner informationbanner()# set paths of project paths.ROOT_PATH=os.getcwd()setPaths()# received command >> cmdLineOptionscmdLineOptions.update(cmdLineParser().__dict__)# loader script,target,working way(threads? gevent?),output_file from cmdLineOptions# and send it to confinitOptions(cmdLineOptions)# run!run()## 然后最后执行一下main函数if__name__=="__main__":main()
那这篇文章就是熟悉一下python代码,至少我们现在应该能做到两点:
- 能看懂目录结构
- 能看懂python代码
至于里边代码怎么写,怎么用渗透框架,怎么写POC,怎么写EXP,怎么写脚本,那是我们后边的内容,大家不要着急~
最后,文章首发于公众号,觉得写的还不错不妨关注一手。