6 个版本 (3 个重大更新)
0.4.0 | 2023年11月9日 |
---|---|
0.3.0 | 2022年5月26日 |
0.2.2 | 2021年8月12日 |
0.1.0 | 2021年8月10日 |
#527 在 文本处理
250KB
5K SLoC
unfuck
如果你的 Python 2.7 字节码被篡改了?让我们来 unfuck
它。
概述
unfuck 是一个用于反混淆 Python 2.7 字节码的工具和库。它本质上是对 Python 虚拟机的重新实现,带有污点跟踪。unfuck 可以做到以下一些事情
- 移除不透明的谓词
- 死代码消除
- 恢复一些丢失的函数名
- 清理混淆的变量名
在尝试重建原始 Python 源代码时,#1 和 #2 是 Python 反编译器遇到的最大问题。
unfuck 使你的字节码从这样变成这样
或者从这样变成这样
是的,这些都是真实存在的
有用的 Wiki 资源
使用方法
unfuck 可以作为库或命令行工具使用。
unfuck 0.2.0
USAGE:
unfuck [FLAGS] [OPTIONS] <input-obfuscated-file> <output-path> [graphs-dir] [SUBCOMMAND]
FLAGS:
--dry Dry run only -- do not write any files
-g Enable outputting code graphs to dot format
-h, --help Prints help information
-q Disable all logging
-V, --version Prints version information
-v Enable verbose logging
OPTIONS:
--decompiler <decompiler> Your favorite Python 2.7 bytecode decompiler. This program assumes the decompiler's
first positional argument is the file to decompile, and it prints the decompiled
output to stdout [env: UNFUCK_DECOMPILER=] [default: uncompyle6]
ARGS:
<input-obfuscated-file> Input obfuscated file
<output-path> Output file name or directory name. If this path is a directory, a file will be
created with the same name as the input. When the `strings-only` subcommand is
applied, this will be where the output strings file is placed
<graphs-dir> An optional directory for graphs to be written to [default: .]
SUBCOMMANDS:
help Prints this message or the help of the given subcommand(s)
strings-only
解密单个文件
# deobfuscated.pyc can also be a directory
unfuck obfuscated.pyc deobfuscated.pyc
您还可以提供额外的标志以将字符串输出到文件,或将 dot
图形输出,以便在 graphviz 中查看
# -g is for printing graphs
unfuck -g obfuscated.pyc deobfuscated.pyc
# use the strings-only subcommand for dumping just dumping strings -- no deobfuscation is performed
unfuck deobfuscated.pyc ./strings.csv strings-only
构建
unfuck 需要 Python 2.7 在您的系统 PATH
中。在确保其存在后,您只需执行 cargo build
即可。如果由于某些原因找不到正确的解释器,请尝试设置 PYTHON_SYS_EXECUTABLE
环境变量到您的 Python 2.7 解释器路径。
安装
cargoinstall --forceunfuck
库使用
注意:unfuck 最初并不是为了库使用而设计的,因此它自带了多线程平台(在这种情况下,是 Rayon)。
使用方法很简单
use std::convert::TryInto;
use std::fs::File;
let mut pyc_contents = vec![];
let pyc_file = File::open("obfuscated.pyc")?;
pyc_file.read_to_end(&mut pyc_contents)?;
// magic/moddate are specific to the PYC header and are required to be
// a valid PYC file
let magic = u32::from_le_bytes(pyc_contents[0..4].try_into().unwrap());
let moddate = u32::from_le_bytes(pyc_contents[4..8].try_into().unwrap());
let pyc_contents = &pyc_contents[8..];
// Use a standard Python 2.7 opcode table
let deobfuscator = unfuck::Deobfuscator::<pydis::opcode::py27::Standard>::new(pyc_contents);
let deobfuscator = if enable_graphs {
deobfuscator.enable_graphs()
} else {
deobfuscator
};
let deobfuscated_code = deobfuscator.deobfuscate()?;
let mut deobfuscated_file = File::create("deobfuscated.pyc")?;
deobfuscated_file.write_all(&magic.to_le_bytes()[..])?;
deobfuscated_file.write_all(&moddate.to_le_bytes()[..])?;
deobfuscated_file.write_all(deobfuscated_code.data.as_slice())?;
greetz
gabe_k, yrp, lpcvoid, WD 磁盘组的人,squif, ian, pie doom, saruhan
依赖项
~10–20MB
~247K SLoC