欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

python逆向之pyc反編譯的使用教程

 更新時(shí)間:2024年03月27日 09:52:40   作者:GalaxySpaceX  
python代碼的運(yùn)行是靠python解析器將源代碼轉(zhuǎn)換為字節(jié)碼,本文主要介紹了python逆向之pyc反編譯的使用教程,具有一定的參考價(jià)值,感興趣的可以了解一下

前言:

今天碰到個(gè)程序是用python編寫,然后編譯成exe程序,有點(diǎn)興趣就拿來研究了一下,下面記錄下分析的過程。

python代碼的運(yùn)行是靠python解析器將源代碼轉(zhuǎn)換為字節(jié)碼(.pyc),然后把編譯好的字節(jié)碼轉(zhuǎn)發(fā)到Python虛擬機(jī)(PVM)中進(jìn)行執(zhí)行,那么python程序是如何打包成為exe程序來執(zhí)行的那,這里面有二種方法可以將python轉(zhuǎn)換為exe程序執(zhí)行。

第一種就是將python程序轉(zhuǎn)換為c/c++代碼后,然后編譯成為exe程序,但是這種方法會(huì)有很多限制且容易出bug,并不好用;

第二種就是首先將python所需要的所有庫代碼編碼為pyd文件并拷貝到對(duì)應(yīng)的目錄中,然后按照PE格式制造一個(gè)可執(zhí)行文件,包含了windows自帶的運(yùn)行dll庫和PythonXX.dll(解析器庫),入口點(diǎn)為python解析器,就是將整個(gè)python所需要的全部壓縮進(jìn)了一個(gè)exe程序中來進(jìn)行執(zhí)行,需要的庫通過pyd調(diào)用。

python編譯:

為了兼容性或者代碼的保護(hù),我們會(huì)采用將python程序編碼為exe程序來進(jìn)行運(yùn)行,使用工具一般采用PyInstaller工具進(jìn)行轉(zhuǎn)換。這里先介紹PyInstaller是如何將python程序轉(zhuǎn)換為exe程序的:

安裝:

下載地址:
https://github.com/pyinstaller/pyinstaller
或者直接執(zhí)行命令:
pip install PyInstaller

支持版本為 Python version 3.7-3.11 ,并且支持PyQt5, PySide2, PyQt6, PySide6, wxPython, matplotlib and others out-of-the-box的捆綁:

注意:Python 3.10.0 包含一個(gè)錯(cuò)誤,使得 PyInstaller 不支持它。PyInstaller也無法與Python 3.12的beta版本一起使用

支持操作系統(tǒng)為win7以及以上版本。

打包:

首先看下PyInstaller的常用命令:

picture.ico為圖標(biāo):
PyInstaller -F -i picture.ico -n noPac.exe noPac.py

打包成獨(dú)立exe:
PyInstaller -F --version-file ver.txt noPac.py
# 多文件
pyinstaller -D noPac.py
# 單個(gè)可執(zhí)行文件
pyinstaller -F noPac.py

加密打包exe(加密只針對(duì)依賴庫):
但是要安裝tinyaes:pip install tinyaes
pyinstaller -F --key 123456 xxx.py

我這里使用一個(gè)連接mysql的python代碼進(jìn)行測(cè)試:

包含兩個(gè)py文件:demo.py和mysql_client_tools.py

執(zhí)行:PyInstaller -F -i icon.ico -n demo.exe demo.py

 執(zhí)行成功后會(huì)在dist目錄下生成exe文件,并在build目錄生成build文件

當(dāng)提示缺少庫的時(shí)候可以在PyCharm中查看:

然后使用命令:

pyinstaller -F -p D:\code\Work_Scan\venv\Lib\site-packages main.py

加密exe可以使用:pyinstaller -F --key 123456 demo.py

python逆向:

前期分析:

拿到一個(gè)程序我們首先要去分析這個(gè)程序到底是用什么語言寫的,然后才能對(duì)癥下藥,既然是exe程序,我們使用die進(jìn)行分析:

我這里測(cè)試的就是上面生成的加密后的exe,可以看到分析結(jié)果,使用的是PyInstaller進(jìn)行的打包,且語言為python。

解包:

之后我們要對(duì)exe進(jìn)行解包處理,這里我們要使用工具pyinstxtractor:

pyinstxtractor下載地址:
https://github.com/extremecoders-re/pyinstxtractor

執(zhí)行:

python pyinstxtractor.py demo_key.exe 

這里需要注意使用的什么版本的python編譯的exe,就要用什么版本的python進(jìn)行解包,不然會(huì)報(bào)錯(cuò)

解包完成后可以看到生成了demo_key.exe_extracted文件夾,里面就是解包后的文件,需要特別注意的幾個(gè)文件:

main.pyc   主函數(shù)

pyimod00_crypto_key.pyc  這里面保存有加密key

PYZ-00.pyz_extracted  文件夾里面為依賴庫

 如果PYZ-00.pyz_extracted里面的文件是pyc.encrypted,則證明為加密文件,如果不是則為加密。

解密:

當(dāng)發(fā)現(xiàn)存在pyc.encrypted,則進(jìn)行解密,如果不是則跳過這一步:

使用010editor打開pyimod00_crypto_key.pyc,注意看我們解包的python的dll版本,這里就要注意header頭的版本一定要一致,不然會(huì)報(bào)錯(cuò)

這里列出各個(gè)版本的python頭:

Python 2.7: \x03\xf3\x0d\x0a\0\0\0\0

Python 3.0: \x3b\x0c\x0d\x0a\0\0\0\0

Python 3.1: \x4f\x0c\x0d\x0a\0\0\0\0

Python 3.2: \x6c\x0c\x0d\x0a\0\0\0\0

Python 3.3: \x9e\x0c\x0d\x0a\0\0\0\0\0\0\0\0

Python 3.4: \xee\x0c\x0d\x0a\0\0\0\0\0\0\0\0

Python 3.5: \x17\x0d\x0d\x0a\0\0\0\0\0\0\0\0

Python 3.6: \x33\x0d\x0d\x0a\0\0\0\0\0\0\0\0

Python 3.7: \x42\x0d\x0d\x0a\0\0\0\0\0\0\0\0\0\0\0\0

Python 3.8: \x55\x0d\x0d\x0a\0\0\0\0\0\0\0\0\0\0\0\0

Python 3.9: \x61\x0d\x0d\x0a\0\0\0\0\0\0\0\0\0\0\0\0

Python 3.10: \x6f\x0d\x0d\x0a\0\0\0\0\0\0\0\0\0\0\0\0

使用uncompyle6反編譯:

pip install uncompyle6
注意uncompyle6有版本限制為1.4, 2.1-2.7, and 3.0-3.8

執(zhí)行如下命令:

uncompyle6 -o pyimod00_crypto_key.py pyimod00_crypto_key.pyc
uncompyle6 -o demo.py demo.pyc
cat pyimod00_crypto_key.py 

可以看到解密出來的key為0000000000123456

 因?yàn)槭褂玫氖茿ES加密,使用如下代碼進(jìn)行解密,這里要注意看PyInstaller用的是什么版本,如果是>=4.0使用的是tinyaes,而且使用的算法也不一樣

Pyinstaller < 4.0 => PyCrypto and CFB

Pyinstaller >= 4.0 => tinyaes and CTR

當(dāng)pyinstaller < 4.0 使用如下:

# For pyinstaller < 4.0
import glob
import zlib
from Crypto.Cipher import AES
from pathlib import Path

CRYPT_BLOCK_SIZE = 16

# key obtained from pyimod00_crypto_key
key = bytes('MySup3rS3cr3tK3y', 'utf-8')

for p in Path("PYZ-00.pyz_extracted").glob("**/*.pyc.encrypted"):
	inf = open(p, 'rb') # encrypted file input
	outf = open(p.with_name(p.stem), 'wb') # output file 

	# Initialization vector
	iv = inf.read(CRYPT_BLOCK_SIZE)

	cipher = AES.new(key, AES.MODE_CFB, iv)

	# Decrypt and decompress
	plaintext = zlib.decompress(cipher.decrypt(inf.read()))

	# Write pyc header
	# The header below is for Python 3.8
	outf.write(b'\x55\x0d\x0d\x0a\0\0\0\0\0\0\0\0\0\0\0\0')

	# Write decrypted data
	outf.write(plaintext)

	inf.close()
	outf.close()

	# Delete .pyc.encrypted file
	p.unlink()

當(dāng)使用版本>= 4.0使用如下代碼:

# For pyinstaller >=4.0
import glob
import zlib
import tinyaes
from pathlib import Path

CRYPT_BLOCK_SIZE = 16

# key obtained from pyimod00_crypto_key
key = bytes('MySup3rS3cr3tK3y', 'utf-8')

for p in Path("PYZ-00.pyz_extracted").glob("**/*.pyc.encrypted"):
	inf = open(p, 'rb') # encrypted file input
	outf = open(p.with_name(p.stem), 'wb') # output file 

	# Initialization vector
	iv = inf.read(CRYPT_BLOCK_SIZE)

	cipher = tinyaes.AES(key, iv)

	# Decrypt and decompress
	plaintext = zlib.decompress(cipher.CTR_xcrypt_buffer(inf.read()))

	# Write pyc header
	# The header below is for Python 3.8
	outf.write(b'\x55\x0d\x0d\x0a\0\0\0\0\0\0\0\0\0\0\0\0')

	# Write decrypted data
	outf.write(plaintext)

	inf.close()
	outf.close()

	# Delete .pyc.encrypted file
	p.unlink()

但是要如何判單使用的是什么版本,我們可以反編譯 pyimod01_archive.pyc,看里面是否引用了tinyaes,這里可以看到,引用了tinyaes

則使用下面的版本。 

反編譯:

其實(shí)上面也講過了,使用uncompyle6進(jìn)行反編譯,這里可以使用我上面的腳本進(jìn)行批量的反編譯,但是當(dāng)反匯編的為公共庫的時(shí)候會(huì)失敗,所以也可以選擇uncompyle6進(jìn)行指定反匯編:

我這里直接全部反編譯,可以看到可以將源代碼反編譯出來

但是可以看看其他反編譯的文件可以看到有些沒成功會(huì)報(bào)錯(cuò)比如如下的

 這就是加了混淆,具體的怎么解混淆就要看情況了,后面有時(shí)間在寫

總結(jié):

過程其實(shí)很簡(jiǎn)單,主要使用pyinstxtractor.py和uncompyle6兩個(gè)工具,一個(gè)是解包,一個(gè)是反編譯,中間有當(dāng)文件加密,可以使用解密工具進(jìn)行解密,之后使用uncompyle6反編譯,過程不難,用這樣的方法可以很簡(jiǎn)單的反編譯出源代碼,所以為了對(duì)抗破解,會(huì)進(jìn)行混淆等操作,這個(gè)后續(xù)進(jìn)行介紹。

到此這篇關(guān)于python逆向之pyc反編譯的使用教程的文章就介紹到這了,更多相關(guān)python pyc反編譯內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python numpy 點(diǎn)數(shù)組去重的實(shí)例

    Python numpy 點(diǎn)數(shù)組去重的實(shí)例

    下面小編就為大家分享一篇Python numpy 點(diǎn)數(shù)組去重的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-04-04
  • pytorch如何定義新的自動(dòng)求導(dǎo)函數(shù)

    pytorch如何定義新的自動(dòng)求導(dǎo)函數(shù)

    這篇文章主要介紹了pytorch如何定義新的自動(dòng)求導(dǎo)函數(shù)問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
    2022-12-12
  • python結(jié)束程序運(yùn)行的四種方法

    python結(jié)束程序運(yùn)行的四種方法

    大家好,小編為大家解答python結(jié)束程序的代碼用什么符號(hào)的問題,很多人還不知道python如何結(jié)束程序運(yùn)行,文中通過代碼示例和圖文結(jié)合的方式介紹的非常詳細(xì),現(xiàn)在讓我們一起來看看吧
    2024-07-07
  • python生成器generator:深度學(xué)習(xí)讀取batch圖片的操作

    python生成器generator:深度學(xué)習(xí)讀取batch圖片的操作

    這篇文章主要介紹了python生成器generator:深度學(xué)習(xí)讀取batch圖片的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-05-05
  • 簡(jiǎn)單了解django索引的相關(guān)知識(shí)

    簡(jiǎn)單了解django索引的相關(guān)知識(shí)

    這篇文章主要介紹了簡(jiǎn)單了解django索引的相關(guān)知識(shí),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-07-07
  • linux centos 7.x 安裝 python3.x 替換 python2.x的過程解析

    linux centos 7.x 安裝 python3.x 替換 python2.x的過程解析

    這篇文章主要介紹了linux centos 7.x 安裝 python3.x 替換 python2.x的過程解析,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12
  • Python:format格式化字符串詳解

    Python:format格式化字符串詳解

    這篇文章主要介紹了Python中用format函數(shù)格式化字符串的用法,格式化字符串是Python學(xué)習(xí)當(dāng)中的基礎(chǔ)知識(shí),本文主要針對(duì)Python2.7.x版本,需要的朋友可以參考下
    2021-09-09
  • Python函數(shù)的作用域及內(nèi)置函數(shù)詳解

    Python函數(shù)的作用域及內(nèi)置函數(shù)詳解

    這篇文章主要介紹了python函數(shù)的作用域及內(nèi)置函數(shù)詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2021-09-09
  • flask之郵件發(fā)送的實(shí)現(xiàn)示例

    flask之郵件發(fā)送的實(shí)現(xiàn)示例

    Flask-Mail是一個(gè)處理電子郵件發(fā)送的擴(kuò)展,它提供了簡(jiǎn)單且易于使用的API,可以方便地發(fā)送電子郵件,本文就來介紹一下flask之郵件發(fā)送的實(shí)現(xiàn)示例,感興趣的可以了解一下
    2023-12-12
  • 通過python調(diào)用adb命令對(duì)App進(jìn)行性能測(cè)試方式

    通過python調(diào)用adb命令對(duì)App進(jìn)行性能測(cè)試方式

    這篇文章主要介紹了通過python調(diào)用adb命令對(duì)App進(jìn)行性能測(cè)試方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-04-04

最新評(píng)論