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文本处理

MIT 许可证

250KB
5K SLoC

unfuck

如果你的 Python 2.7 字节码被篡改了?让我们来 unfuck 它。

概述

unfuck 是一个用于反混淆 Python 2.7 字节码的工具和库。它本质上是对 Python 虚拟机的重新实现,带有污点跟踪。unfuck 可以做到以下一些事情

  1. 移除不透明的谓词
  2. 死代码消除
  3. 恢复一些丢失的函数名
  4. 清理混淆的变量名

在尝试重建原始 Python 源代码时,#1 和 #2 是 Python 反编译器遇到的最大问题。

unfuck 使你的字节码从这样变成这样

Obfuscated code Deobfuscated code

或者从这样变成这样

Obfuscated vs deobfuscated code hex dump

是的,这些都是真实存在的

有用的 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