Python逆向(三)—— Python编译运行及反汇编
一、前言
前期我們已經(jīng)對(duì)python的運(yùn)行原理以及運(yùn)行過(guò)程中產(chǎn)生的文件結(jié)構(gòu)有了了解。本節(jié),我們將結(jié)合具體的例子來(lái)實(shí)踐python運(yùn)行,編譯,反編譯的過(guò)程,并對(duì)前些章節(jié)中可能遺漏的具體細(xì)節(jié)進(jìn)行補(bǔ)充。
二、Python編譯
python在正常運(yùn)行時(shí),有時(shí)編譯生成pyc文件,有時(shí)候沒有pyc文件的生成。那么我們能不能手動(dòng)將python程序編譯成pyc文件呢?答案是可以的,不但可以編譯,還可以直接運(yùn)行pyc文件以實(shí)現(xiàn)程序運(yùn)行的效率。
2.1、pyc文件的生成
命令行模式:
python -m py_compile file.py # 生成單個(gè)pyc文件
python -m py_compile /dir/{file1,file2}.py # 生成多個(gè)pyc文件
python -m compileall /dir/ # 生成目錄下所有py文件對(duì)應(yīng)的pyc文件
交互shell模式:
>>> import py_compile # 相當(dāng)于命令行中的“-m py_compile”
>>> py_compile.compile('py file path')
>>> import compileall
>>> compileall.compile_dir("py files dir")
2.2、pyo文件生成
pyo文件是源代碼文件經(jīng)過(guò)優(yōu)化編譯后生成的文件,是pyc文件的優(yōu)化版本。編譯時(shí)需要使用-O和-OO選項(xiàng)來(lái)生成pyo文件。在Python3.5之后,不再使用.pyo文件名,而是生成文件名類似“test.opt-n.pyc的文件。
python -O -m py_compile file.py
python -O -m py_compile /dir/{file1,file2}.py
python -O -m compileall /dir/
2.3、直接運(yùn)行編譯好的pyc或者pyo文件
三、字節(jié)碼文件反編譯
經(jīng)過(guò)編譯的python文件可以提高程序的運(yùn)行速度,一定程度上也對(duì)源代碼起到了保護(hù)作用。然而如果我們只有編譯過(guò)的python字節(jié)碼文件,就給我們審查源碼造成了一定的困難,這就引出了python字節(jié)碼反編譯的需求。
上一節(jié)我們介紹過(guò)pyc文件的結(jié)構(gòu),其實(shí)就是pyc文件頭部加上PyCodeObject對(duì)象。文件頭部的信息在python2中只占用固定8字節(jié),用來(lái)攜帶一些版本類的信息,不是我們做反編譯的重點(diǎn),因此通過(guò)提取8字節(jié)之后的部門做反編譯處理就可以了。
PyCodeObjectData就是我們需要提取的數(shù)據(jù),根據(jù)python的編譯原理我們知道PyCodeObjectData是python源文件作為一個(gè)實(shí)例化的類,通過(guò)python內(nèi)置庫(kù)函數(shù)marshal.dumps生成的二進(jìn)制數(shù)據(jù)段,因此通過(guò)marshal.loads(PyCodeObjectData) ,我們可以得到PyCodeObjectData反序列化的對(duì)象。
可以看到PyObj對(duì)象包含了很多內(nèi)置方法和屬性,這些屬性在第二節(jié)中我們已經(jīng)有過(guò)介紹,各個(gè)字段的含義都已經(jīng)知道了。通過(guò)對(duì)這些方法的引用可以直接看到相關(guān)字段反序列后的具體值。
使用python內(nèi)置模塊dis可以對(duì)PyCodeObject進(jìn)行反編譯,從而獲取到python二進(jìn)制字節(jié)碼代碼段的“匯編形式”。這樣可以便于對(duì)字節(jié)碼進(jìn)行閱讀。dis模塊也可以單獨(dú)對(duì)PyCodeObject中的co_data模塊進(jìn)行反編譯,但是這樣得到的是單純的代碼段字節(jié)碼,缺少很多代碼段中涉及的變量名字。如上圖所示。
四、結(jié)語(yǔ)
本節(jié)我們對(duì)python源碼編譯生成字節(jié)碼文件和從字節(jié)碼文件反編譯生成字節(jié)碼代碼段(python的匯編形式)進(jìn)行介紹。下一章節(jié)我們將對(duì)dis模塊的源碼進(jìn)行解讀,以便于后續(xù)章節(jié)關(guān)于python代碼混淆技術(shù)的涉及。
總結(jié)
以上是生活随笔為你收集整理的Python逆向(三)—— Python编译运行及反汇编的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 18000字的SQL优化大全,收藏直接起
- 下一篇: 精选6种制作酷炫动图的方法,收藏!