赞
踩
目录
二.从stream.exe中提取stream.pyc和struct.pyc文件
1.方法一:使用pyinstxtractor.py提取(较为简单)
(2)将stream.exe和pyinstxtractor.py文件置于同一文件夹内,在该路径内打开cmd
2.方法二:使用PyInstaller自带的archive_viewer.py提取(相对复杂)
(4)将stream.pyc的magic head头信息补上去,同方法1
三.反编译stream.pyc文件获取stream.py源码
1.使用python3.11解释器调用dis解释出pyc文件的字节码
2.使用ChatGpt翻译字节码得到源码(看文档生啃也可以)
通过查壳可以发现这是python语言编写,使用PyInstaller打包的exe程序,但是并不确定python版本
下载地址: extremecoders-re/pyinstxtractor: PyInstaller Extractor (github.com)
点绿色的code,再点download zip即可下载
使用命令:
python pyinstxtractor.py stream.exe
则会在该路径下输出stream.exe_extracted文件夹,同时也可以看到pyinstaller和python的版本(python3.10)
注意:这里最好是让使用的python解释器版本和待解包程序python版本一致(建议使用Anaconda管理python版本),保证输出准确,否则可能会丢失部分文件
一般而言,使用pyinstxtractor解包会自动修复MagicHead,如果没有自动修复则手动修复
在文件夹内找到stream.pyc和struct.pyc文件,用winhex或者010editor打开,将struct文件的第一行(Magic head)复制到stream.pyc的最前面,保存更改
pip install pyinstaller -i https://pypi.douban.com/simple(也可指定为其他源)
使用where python找到python所在路径,
然后在python所在的文件夹内找Lib\site-packages\PyInstaller\utils\cliutils\archive_viewer.py
即: C:\Users\admin\AppData\Local\Programs\Python\Python310\Lib\site-packages\PyInstaller\utils\cliutils\archive_viewer.py
将archive_viewer.py复制到stream.exe所在文件夹内,在文件夹内打开cmd,使用命令
python archive_viewer.py stream.exe,这里也可以看到python版本等信息
继续使用命令即可输出stream.pyc和struct.pyc文件
选择pyc文件即可得到源码:
如果不想下载编译的话这里有我编译好的pycdc.exe,可以直接跳转到(4)反编译pyc文件
下载installer安装包版
安装时记得勾选添加到环境变量,其他选项默认即可
1. 使用命令行下载
- git clone https://github.com/zrax/pycdc.git #下载pycdc
-
- cd pycdc #进入pycdc目录
-
- cmake . #注意是cmake . 这个'.'点号
使用visual studio打开pycdc文件夹中的pycdc.sln文件
打开后选择x64 release模式编译运行
在pycdc/Release文件夹内可以找到pycdc.exe
也可以选则直接下载源码
2. 直接下载
项目地址:zrax/pycdc: C++ python bytecode disassembler and decompiler (github.com)
点击Code>Download Zip
解压后得到的文件夹用VisualStudio打开,然后找到pycdc.cpp文件,然后点击管理配置
点击绿色+号选择x64-release,然后ctrl+s保存json的设置就可以
选择x64-release模式编译
然后在生成里选择全部生成
最后就可以在~\pycdc-master\out\build\x64-Release目录下找到pycdc.exe了(可以将目录配置到环境变量方便使用)
将pycdc.exe和stream.pyc文件放于同一文件夹内(也可以将pycdc.exe所在文件夹路径添加到环境变量)
在文件夹内打开cmd,使用命令:pycdc stream.pyc
成功输出源码:
- #!/usr/bin/env python
- # visit https://tool.lu/pyc/ for more information
- # Version: Python 3.10
-
- import base64
-
- def gen(key):
- s = list(range(256))
- j = 0
- for i in range(256):
- j = (j + s[i] + ord(key[i % len(key)])) % 256
- tmp = s[i]
- s[i] = s[j]
- s[j] = tmp
- i = j = 0
- data = []
- for _ in range(50):
- i = (i + 1) % 256
- j = (j + s[i]) % 256
- tmp = s[i]
- s[i] = s[j]
- s[j] = tmp
- data.append(s[(s[i] + s[j]) % 256])
- return data
-
-
- def encrypt(text, key):
- result = ''
- for c, k in zip(text, gen(key)):
- result += chr(ord(c) ^ k)
- result = base64.b64encode(result.encode()).decode()
- return result
-
- text = input('Flag: ')
- key = 'As_we_do_as_you_know'
- enc = encrypt(text, key)
- if enc == 'wr3ClVcSw7nCmMOcHcKgacOtMkvDjxZ6asKWw4nChMK8IsK7KMOOasOrdgbDlx3DqcKqwr0hw701Ly57w63CtcOl':
- print('yes!')
- return None
- None('try again...')
- #!/usr/bin/env python
- # visit for more information
- # Version: Python 3.10
- # 反编译代码
- import base64
-
- def gen(key):
- s = list(range(256))#s=[0,1,...,255]
- j = 0
- for i in range(256):
- j = (j + s[i] + ord(key[i % len(key)])) % 256
- tmp = s[i]
- s[i] = s[j]
- s[j] = tmp
- i = j = 0
- data = []
- for _ in range(50):# _字符表示不指明循环变量,但是循环会进行50次
- i = (i + 1) % 256
- j = (j + s[i]) % 256
- tmp = s[i]
- s[i] = s[j]
- s[j] = tmp
- data.append(s[(s[i] + s[j]) % 256])
- return data
-
- def decrypt(enc , key):
- result=''
- enc = base64.b64decode(enc.encode()).decode()
- c = ""
- for i, k in zip(enc, gen(key)):
- c += chr((ord(i) ^ k))
- print(c)
-
- key = 'As_we_do_as_you_know'
- enc = "wr3ClVcSw7nCmMOcHcKgacOtMkvDjxZ6asKWw4nChMK8IsK7KMOOasOrdgbDlx3DqcKqwr0hw701Ly57w63CtcOl"
- decrypt(enc, key)
- #hgame{python_reverse_is_easy_with_internet}
-
-
-
-
得到flag:hgame{python_reverse_is_easy_with_internet}
2.[Python逆向] 逆向Pyinstaller打包的exe文件源码及保护
3.Pyinstaller打包的exe之一键反编译py脚本与防反编译
4.【Python教程】保姆版教使用Pyinstaller 打包python成exe文件
5.使用pydumpck反编译pyintaller生成的exe文件 python3.10
DASCTF2023 RE easyRE 这题使用python3.11解释器,由于版本过高,得到pyc字节码文件后无法反编译出python源码.
- import marshal
- import dis
- f=open(r'easyRE.pyc','rb')
- # 将pyc文件和该脚本放于同一文件夹内,或者自行指定绝对路径
- code=marshal.loads(f.read()[16:])
- print(dis.dis(code))
- f.close()
字节码:
ChatGpt翻译出的源码
- import random
-
- r = random.Random(322376503)
- pt = input('Enter your flag: ').encode()
- ct = b'\x8b\xcck\xd3\xed\x96\xffFb\x06r\x085\x82\xbc \xb2\xde)p\x88Q`\x1bf\x18\xb6QUSw\x10\xcd\xd9\x13A$\x86\xe5\xcd\xd9\xff'
- buf = []
-
- for b in pt:
- buf.append(b ^ r.randint(0, 255))
-
- if bytes(buf) == ct:
- print('Correct!')
- else:
- assert False
dis库打印时可能会有报错的情况,这时可以尝试这条命令
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。