wifijammer源碼分析一

處于學(xué)習(xí)別人代碼風(fēng)格階段,github參考學(xué)習(xí)程序
程序開頭會有

#!/usr/bin/python
# -*- coding: utf-8 -*-

一是用來指定腳本語言為 Python,二是用來指定文件編碼為utf-8.

1、Python logging 模塊使用

最好學(xué)習(xí)資料還是官方文檔

(1)輸出等級

logging是一個實用的輔助工具,可以分等級地打印調(diào)試信息或錯誤信息屯断。分為五個等級:

Paste_Image.png

默認(rèn)是warning等級。設(shè)置等級后只有大于等于該等級的信息會打印出。不指定文件則打印在終端上殖演⊙趺兀可以通過以下方式指定輸出文件和輸出等級:
logging.basicConfig(filename='example.log',level=logging.DEBUG)
也可以在命令行通過 --log=INFO/DEBUG/ERROR等

(2)格式化顯示

可以根據(jù)自己的需要改變顯示信息的格式,如:

logging.warning('%s before you %s', 'Look', 'leap!')

import logging
logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.DEBUG)
logging.debug('This message should appear on the console')
logging.info('So should this')
logging.warning('And this, too')

打印出:

DEBUG:This message should appear on the console
INFO:So should this
WARNING:And this, too

即可以通過basicConfig改變輸出格式趴久,默認(rèn)為

WARNING:root:Look before you leap!

關(guān)于時間

import logging
logging.basicConfig(format='%(asctime)s %(message)s')
logging.warning('is when this event was logged.')

打印出:

2017-04-29 19:47:17,128 is when this event happened

也可以改變默認(rèn)的時間顯示格式(some problem):

logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
(3)深入學(xué)習(xí)

https://docs.python.org/2/howto/logging-cookbook.html#logging-cookbook
程序示例:

import logging

logging.basicConfig(level=logging.DEBUG,
                format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
                datefmt='%a, %d %b %Y %H:%M:%S',
                filename='myapp.log',
                filemode='w')

#################################################################################################
#定義一個StreamHandler丸相,將INFO級別或更高的日志信息打印到標(biāo)準(zhǔn)錯誤,并將其添加到當(dāng)前的日志處理對象#
console = logging.StreamHandler()
console.setLevel(logging.INFO)
formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
console.setFormatter(formatter)
logging.getLogger('').addHandler(console)
#################################################################################################

logging.debug('This is debug message')
logging.info('This is info message')
logging.warning('This is warning message')

當(dāng)沒有指定filename時彼棍,默認(rèn)為標(biāo)準(zhǔn)錯誤輸出灭忠,如上程序中的StreamHandler。

2座硕、scapy工具使用

scapy是一個強大的第三方庫弛作,用于網(wǎng)絡(luò)嗅探。能夠偽造或者解碼大量的網(wǎng)絡(luò)協(xié)議數(shù)據(jù)包华匾,能夠發(fā)送缆蝉、捕捉、匹配請求和回復(fù)包等等瘦真。它可以很容易地處理一些典型操作,比如端口掃描黍瞧,tracerouting诸尽,探測,單元 測試印颤,攻擊或網(wǎng)絡(luò)發(fā)現(xiàn)(可替代hping您机,NMAP,arpspoof年局,ARP-SK际看,arping,tcpdump矢否,tethereal仲闽,P0F等)。 最重要的他還有很多更優(yōu)秀的特性——發(fā)送無效數(shù)據(jù)幀僵朗、注入修改的802.11數(shù)據(jù)幀赖欣、在WEP上解碼加密通道(VOIP)、ARP緩存攻擊(VLAN) 等验庙,這也是其他工具無法處理完成的顶吮。

有以下兩種使用方式:

執(zhí)行sudo scapy命令進(jìn)入交互式數(shù)據(jù)包處理,或在Python代碼中使用from scapy.all import *引入scapy

慢慢學(xué)習(xí)別人,造輪子

3粪薛、threading模塊實現(xiàn)多線程

threading對thread(多線程底層支持模塊悴了,一般不建議使用)進(jìn)行了封裝,將一些線程的操作對象化
參考 http://www.cszhi.com/20130528/python-threading.html

import threading
 
def thread_fun(num):
    for n in range(0, int(num)):
        print " I come from %s, num: %s" %( threading.currentThread().getName(), n)
 
def main(thread_num):
    thread_list = list();
    # 先創(chuàng)建線程對象
    for i in range(0, thread_num):
        thread_name = "thread_%s" %i
        thread_list.append(threading.Thread(target = thread_fun, name = thread_name, args = (20,)))
 
    # 啟動所有線程
    for thread in thread_list:
        thread.start()
 
    # 主線程中等待所有子線程退出
    for thread in thread_list:
        thread.join()
 
if __name__ == "__main__":
    main(3)

列表的廣義化,列表可以是函數(shù)湃交、類的集合熟空。可以理解為存放的是地址巡揍。通過threading.Thread函數(shù)創(chuàng)建一個線程痛阻,指定target-回調(diào)函數(shù),線程名以及參數(shù)等腮敌。
thread.join()函數(shù)會依次檢測線程池中的線程是否結(jié)束阱当,沒有結(jié)束就阻塞直到線程結(jié)束,結(jié)束后會跳轉(zhuǎn)執(zhí)行下一個線程的join函數(shù)糜工。Python的join函數(shù)還可以設(shè)置超時時間弊添,Thread.join([timeout])。

上述是通過自定義創(chuàng)建函數(shù)捌木,并通過Thread運行油坝,也可以繼承Thread類進(jìn)行簡化編程。

import threading
 
class MyThread(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self);
 
    def run(self):
        print "I am %s" %self.name
 
if __name__ == "__main__":
    for thread in range(0, 5):
        t = MyThread()
        t.start()

通過自定義run函數(shù)重寫Thread中的run函數(shù)刨裆。

擴展:
(1)setdaemon函數(shù)

Python中得thread的一些機制和C/C++不同:在C/C++中澈圈,主線程結(jié)束后,其子線程會默認(rèn)被主線程kill掉帆啃。而在python中瞬女,主線程結(jié)束后,會默認(rèn)等待子線程結(jié)束后努潘,主線程才退出诽偷。
setDaemon:主線程A啟動了子線程B,調(diào)用b.setDaemaon(True)疯坤,則主線程結(jié)束時报慕,會把子線程B也殺死,與C/C++中得默認(rèn)效果是一樣的压怠。

#! /usr/bin/env python

import threading
import time

class myThread(threading.Thread):
   def __init__(self, threadname):
     threading.Thread.__init__(self, name=threadname)
     self.st = 2

   def run(self):
     time.sleep(self.st)
     print self.getName()
   def setSt(self, t):
     self.st = t

def fun1():
   t1.start()
   print "fun1 done"

def fun2():
   t2.start()
   print "fun2 done"

t1=myThread("t1")
t2=myThread("t2")
t2.setSt(10);
# t2.setDaemon(True)
fun1()
fun2()
print "now u will see me"

當(dāng) t2.setDaemon(True)沒有生效時眠冈,打印出

fun1 done
fun2 done
now u will see me
t1
t2

生效后,打印出

fun1 done
fun2 done
now u will see me
t1

t2.setDaemon(True)表示主進(jìn)程結(jié)束后立即結(jié)束子進(jìn)程菌瘫,不管子進(jìn)程有沒有運行完成洋闽。

(2)互斥鎖

多個線程訪問同一資源,由于先后順序不確定突梦,產(chǎn)生“線程不安全”诫舅,引入互斥鎖,使無序變有序宫患。

import threading
import time
 
counter = 0
mutex = threading.Lock()
 
class MyThread(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
 
    def run(self):
        global counter, mutex
        time.sleep(1);
        if mutex.acquire():
            counter += 1
            print "I am %s, set counter:%s" % (self.name, counter)
            mutex.release()
 
if __name__ == "__main__":
    for i in range(0, 100):
        my_thread = MyThread()
        my_thread.start()

當(dāng)一個線程調(diào)用Lock對象的acquire()方法獲得鎖時刊懈,這把鎖就進(jìn)入“l(fā)ocked”狀態(tài)。因為每次只有一個線程1可以獲得鎖,所以如果此時另一個線程2試圖獲得這個鎖虚汛,該線程2就會變?yōu)椤癰lock“同步阻塞狀態(tài)匾浪。直到擁有鎖的線程1調(diào)用鎖的release()方法釋放鎖之后,該鎖進(jìn)入“unlocked”狀態(tài)卷哩。線程調(diào)度程序從處于同步阻塞狀態(tài)的線程中選擇一個來獲得鎖蛋辈,并使得該線程進(jìn)入運行(running)狀態(tài)。

(3)避免死鎖
(4)進(jìn)程間通信
(5)管道pipe

4将谊、subprocess 模塊

官網(wǎng)參考資料
subprocess允許開啟一個新的進(jìn)程冷溶,并與之通信。
subprocess用來代替以下模塊:

  • os.system
  • os.spawn*
  • os.popen*
  • popen2.*
  • commands.*
(1)subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False)

運行參數(shù)中的命令尊浓,并返回 returncode,如:
subprocess.call(['ls','-al']) 在官方文檔中有以下注意

Note :Do not use stdout=PIPE or stderr=PIPE with this function as that can deadlock based on the child process output volume. Use Popen
with the communicate() method when you need pipes.

值得注意shell=False這個參數(shù)逞频,根據(jù)官網(wǎng)shell=False比shell=True更安全,假設(shè)運行以下

 cmd = "cat test.txt; rm test.txt"  
subprocess.call(cmd, shell=True)

shell=True參數(shù)會讓subprocess.call接受字符串類型的變量作為命令栋齿,并調(diào)用shell去執(zhí)行這個字符串苗胀,第一個測試中的分號被認(rèn)為是shell命令中的分隔符,執(zhí)行了cat和rm兩個命令瓦堵。
當(dāng)shell=False時基协,subprocess.call只接受數(shù)組變量作為命令,并將數(shù)組的第一個元素作為命令菇用,剩下的全部作為該命令的參數(shù)澜驮,因此第二個測試只執(zhí)行了cat命令,并試著打開了作為參數(shù)的”text.txt;”刨疼,”rm” , “text.txt”三個文件。

(2)subprocess.check_call (*popenargs , **kwargs )

執(zhí)行上面的call命令鹅龄,并檢查返回值揩慕,如果子進(jìn)程返回非0,則會拋出CalledProcessError異常扮休,這個異常會有個returncode
屬性迎卤,記錄子進(jìn)程的返回值。

(2)subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, universal_newlines=False)

和上個函數(shù)類似玷坠,主要不同在于將所有輸出保存為字符串蜗搔,而不直接打印到標(biāo)準(zhǔn)輸出。

>>> import subprocess
>>> str = subprocess.check_output(['echo','hello world'])
>>> str
'hello world\n'
>>> 
(3) class subprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)

是該模塊中最為重要的方法之一八堡,創(chuàng)建一個新進(jìn)程樟凄,類似于unix系統(tǒng)下的 os.execvp()
,windows下的 CreateProcess() 兄渺。

>>> import shlex, subprocess
>>> command_line = raw_input()
/bin/vikings -input eggs.txt -output "spam spam.txt" -cmd "echo '$MONEY'"
>>> args = shlex.split(command_line)
>>> print args
['/bin/vikings', '-input', 'eggs.txt', '-output', 'spam spam.txt', '-cmd', "echo '$MONEY'"]
>>> p = subprocess.Popen(args) # Success!

shelex是一個簡單的詞典分析模塊 ,shlex.split()
可以被用于序列化復(fù)雜的命令參數(shù)缝龄,比如:

>>> shlex.split('ls ps top grep pkill')
['ls', 'ps', 'top', 'grep', 'pkill']
args參數(shù):

可以是一個字符串,可以是一個包含程序參數(shù)的列表。要執(zhí)行的程序一般就是這個列表的第一項叔壤,或者是字符串本身瞎饲。
subprocess.Popen(["cat","test.txt"])
subprocess.Popen("cat test.txt")
這兩個之中,后者將不會工作炼绘。因為如果是一個字符串的話嗅战,必須是程序的路徑才可以。
但是下面的可以工作 subprocess.Popen("cat test.txt", shell=True)
這是因為它相當(dāng)于 subprocess.Popen(["/bin/sh", "-c", "cat test.txt"])
在*nix下俺亮,當(dāng)shell=False(默認(rèn))時驮捍,Popen使用os.execvp()來執(zhí)行子程序。args一般要是一個【列表】铅辞。如果args是個字符串的
話厌漂,會被當(dāng)做是可執(zhí)行文件的路徑,這樣就不能傳入任何參數(shù)了斟珊。

executable參數(shù) :

很少用到苇倡,用來指定要執(zhí)行的程序,一般程序可以用args參數(shù)指定囤踩。

preexec_fn參數(shù):

如果把preexec_fn設(shè)置為一個可調(diào)用的對象(比如函數(shù))旨椒,就會在子進(jìn)程被執(zhí)行前被調(diào)用。(僅限*nix)

close_fds參數(shù):

如果把close_fds設(shè)置成True堵漱,*nix下會在開子進(jìn)程前把除了0综慎、1、2以外的文件描述符都先關(guān)閉勤庐。在 Windows下也不會繼承其他文件描述符示惊。

shell參數(shù):

如果把shell設(shè)置成True,指定的命令會在shell里解釋執(zhí)行愉镰。

cwd參數(shù):

如果cwd不是None米罚,則會把cwd做為子程序的當(dāng)前目錄。注意丈探,并不會把該目錄做為可執(zhí)行文件的搜索目錄录择,所以不要把程序文件所在
目錄設(shè)置為cwd 。

env參數(shù):

如果env不是None碗降,則子程序的環(huán)境變量由env的值來設(shè)置隘竭,而不是默認(rèn)那樣繼承父進(jìn)程的環(huán)境變量。注意讼渊,即使你只在env里定義了
某一個環(huán)境變量的值动看,也會阻止子程序得到其他的父進(jìn)程的環(huán)境變量
后面幾個很少用到。

Popen類的method
Popen.poll()

Check if child process has terminated. Set and return returncode attribute.

Popen.wait()

Wait for child process to terminate. Set and return returncode attribute.

Popen.communicate(input=None)

Interact with process: Send data to stdin. Read data from stdout and stderr, until end-of-file is reached. Wait for process to terminate. The optional input argument should be a string to be sent to the child process, or None, if no data should be sent to the child.

Popen.send_signal(signal)
Popen.terminate()

停止一個子進(jìn)程爪幻,在linux下發(fā)送SIGTERM信號給子進(jìn)程

Popen.kill()

殺死一個子進(jìn)程弧圆,在linux下發(fā)送SIGKILL給子進(jìn)程赋兵。

常用的一些屬性
  • Popen.returncode
  • Popen.pid
  • Popen.stderr
  • Popen.stdout
  • Popen.stdin
    對于Popen.stdin,如果stdin是PIPE搔预,則這個屬性返回的是為子進(jìn)程提供輸入的文件對象霹期。
    同理,If the stdout argument was PIPE
    , Popen.stdout is a file object that provides output from the child process. Otherwise, it is None
    示例:
    output= dmesg | grep hda
    等價于
p1 = Popen(["dmesg"], stdout=PIPE)
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
p1.stdout.close()  # Allow p1 to receive a SIGPIPE if p2 exits.
output = p2.communicate()[0]

注意以下幾點:
communicate函數(shù)返回一個元祖 (stdoutdata, stderrdata)
當(dāng)Popen函數(shù)中stdout=PIPE時拯田,表示輸出到一個管道中历造,要獲取該管道,Popen.stdout會返回該句柄船庇,可以通過讀文件方法讀出該管道中數(shù)據(jù)吭产。

pipe = os.popen("cmd", 'r', bufsize)
==>
pipe = Popen("cmd", shell=True, bufsize=bufsize, stdout=PIPE).stdout
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市鸭轮,隨后出現(xiàn)的幾起案子臣淤,更是在濱河造成了極大的恐慌,老刑警劉巖窃爷,帶你破解...
    沈念sama閱讀 218,640評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件邑蒋,死亡現(xiàn)場離奇詭異,居然都是意外死亡按厘,警方通過查閱死者的電腦和手機医吊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,254評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來逮京,“玉大人卿堂,你說我怎么就攤上這事±撩蓿” “怎么了草描?”我有些...
    開封第一講書人閱讀 165,011評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長策严。 經(jīng)常有香客問我穗慕,道長,這世上最難降的妖魔是什么享钞? 我笑而不...
    開封第一講書人閱讀 58,755評論 1 294
  • 正文 為了忘掉前任揍诽,我火速辦了婚禮诀蓉,結(jié)果婚禮上栗竖,老公的妹妹穿的比我還像新娘。我一直安慰自己渠啤,他們只是感情好狐肢,可當(dāng)我...
    茶點故事閱讀 67,774評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著沥曹,像睡著了一般份名。 火紅的嫁衣襯著肌膚如雪碟联。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,610評論 1 305
  • 那天僵腺,我揣著相機與錄音鲤孵,去河邊找鬼。 笑死辰如,一個胖子當(dāng)著我的面吹牛普监,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播琉兜,決...
    沈念sama閱讀 40,352評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼凯正,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了豌蟋?” 一聲冷哼從身側(cè)響起廊散,我...
    開封第一講書人閱讀 39,257評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎梧疲,沒想到半個月后允睹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,717評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡往声,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,894評論 3 336
  • 正文 我和宋清朗相戀三年擂找,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片浩销。...
    茶點故事閱讀 40,021評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡贯涎,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出慢洋,到底是詐尸還是另有隱情塘雳,我是刑警寧澤,帶...
    沈念sama閱讀 35,735評論 5 346
  • 正文 年R本政府宣布普筹,位于F島的核電站败明,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏太防。R本人自食惡果不足惜妻顶,卻給世界環(huán)境...
    茶點故事閱讀 41,354評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蜒车。 院中可真熱鬧讳嘱,春花似錦、人聲如沸酿愧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,936評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嬉挡。三九已至钝鸽,卻和暖如春汇恤,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背拔恰。 一陣腳步聲響...
    開封第一講書人閱讀 33,054評論 1 270
  • 我被黑心中介騙來泰國打工因谎, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人颜懊。 一個月前我還...
    沈念sama閱讀 48,224評論 3 371
  • 正文 我出身青樓蓝角,卻偏偏與公主長得像,于是被迫代替她去往敵國和親饭冬。 傳聞我的和親對象是個殘疾皇子使鹅,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,974評論 2 355

推薦閱讀更多精彩內(nèi)容