EnPHP 是 mzphp2 框架内置的 PHP 源码加密工具,主打变量 / 函数名混淆 + 多层编码 + gzinflate 压缩 + 动态执行的组合防护。本文将系统解析 EnPHP 加密原理,提供完整逆向脚本与实战指南,适用于学习研究与合法授权场景。
一、EnPHP 加密核心原理
EnPHP 采用多层防护机制,主要包括:
表格
| 加密层 | 技术实现 | 防护目的 |
|---|---|---|
| 代码混淆 | 变量名 / 函数名替换为乱码或随机字母组合 | 降低可读性,增加静态分析难度 |
| 字符串编码 | base64、rot13、str_rot13 多层混合编码 | 隐藏关键字符串与执行逻辑 |
| 代码压缩 | gzinflate 压缩核心代码 | 减小体积,增加逆向复杂度 |
| 动态执行 | eval、preg_replace (‘/./e’)、call_user_func 等 | 延迟代码执行,避免静态提取 |
| 垃圾代码 | 随机插入无效代码与空操作 | 干扰代码分析,增加逆向时间成本 |
二、逆向准备:环境与工具
1. 必备环境
- PHP 5.3+(推荐 7.4,兼容 EnPHP 全版本加密)
- 扩展:mbstring、zlib(处理 gzinflate)
- 隔离环境:虚拟机 / 容器(避免恶意代码执行风险)
2. 核心工具
- 静态分析:Notepad++(语法高亮)、正则表达式(提取编码字符串)
- 动态调试:Xdebug(单步跟踪)、phpdbg(PHP 调试器)
- 辅助工具:CyberChef(在线编码转换)、unphp.net(在线反混淆)
三、完整逆向脚本:静态 + 动态双方案
方案 1:静态逆向脚本(针对 Base64+gzinflate+eval)
适用于 EnPHP 基础加密模式,可直接提取并解码核心代码:
php
运行
<?php
/**
* EnPHP静态逆向脚本(基础版)
* 适用:eval(gzinflate(base64_decode(...))) 类型加密
* 作者:逆向工程师
* 日期:2026-06-05
*/
error_reporting(E_ALL);
ini_set('display_errors', 1);
// 配置区
$encrypted_file = 'encrypted.php'; // 待解密文件
$output_file = 'decoded_static.php'; // 输出文件
$max_depth = 10; // 最大解码层数(防止无限循环)
/**
* 核心解码函数:处理base64+gzinflate组合
*/
function decode_enphp($code, $depth = 0) {
if ($depth >= $max_depth) {
return $code; // 达到最大深度,停止解码
}
// 模式1: eval(gzinflate(base64_decode('...')))
if (preg_match('/eval\s*\s*gzinflate\s*\s*base64_decode\s*\s*([\'"])(.*?)\1\s*\s*\s*\s*/is', $code, $matches)) {
echo "[+] 发现模式1: eval+gzinflate+base64_decode (深度: $depth)\n";
$encoded = $matches[2];
try {
$decoded = base64_decode($encoded);
$uncompressed = gzinflate($decoded);
echo "[+] 解码成功,继续递归处理...\n";
return decode_enphp($uncompressed, $depth + 1);
} catch (Exception $e) {
echo "[!] 解码失败: " . $e->getMessage() . "\n";
return $code;
}
}
// 模式2: preg_replace('/./e', 'eval(gzinflate(base64_decode("...")))', '...')
if (preg_match('/preg_replace\s*\s*\'\/\.\/e\'\s*,\s*\'eval\s*\s*gzinflate\s*\s*base64_decode\s*\s*([\'"])(.*?)\1\s*\s*\s*\s*\'\s*,\s*\'[^\']+\'/is', $code, $matches)) {
echo "[+] 发现模式2: preg_replace/e+eval+gzinflate+base64_decode (深度: $depth)\n";
$encoded = $matches[2];
try {
$decoded = base64_decode($encoded);
$uncompressed = gzinflate($decoded);
echo "[+] 解码成功,继续递归处理...\n";
return decode_enphp($uncompressed, $depth + 1);
} catch (Exception $e) {
echo "[!] 解码失败: " . $e->getMessage() . "\n";
return $code;
}
}
// 模式3: 直接提取base64编码的gzip数据
if (preg_match('/base64_decode\s*\s*([\'"])([A-Za-z0-9+\/=]{50,})\1\s*/is', $code, $matches)) {
echo "[+] 发现模式3: 独立base64编码字符串 (深度: $depth)\n";
$encoded = $matches[2];
try {
$decoded = base64_decode($encoded);
if (@gzinflate($decoded) !== false) {
$uncompressed = gzinflate($decoded);
echo "[+] 检测到gzip压缩,解压成功\n";
return decode_enphp($uncompressed, $depth + 1);
}
} catch (Exception $e) {
echo "[!] 解码失败: " . $e->getMessage() . "\n";
}
}
echo "[+] 解码完成(深度: $depth)\n";
return $code;
}
// 执行逆向流程
echo "===== EnPHP静态逆向脚本开始 =====\n";
echo "[*] 读取加密文件: $encrypted_file\n";
if (!file_exists($encrypted_file)) {
die("[!] 文件不存在: $encrypted_file\n");
}
$encrypted_code = file_get_contents($encrypted_file);
$decoded_code = decode_enphp($encrypted_code);
echo "[*] 保存解码结果到: $output_file\n";
file_put_contents($output_file, $decoded_code);
echo "===== 逆向完成!=====\n";
echo "提示:静态解码后可能仍存在变量混淆,需进一步人工还原或使用动态调试方案。\n";
?>
方案 2:动态调试脚本(针对高度混淆 + 多层加密)
通过劫持eval函数,在代码执行时捕获解密后的原始代码,适用于复杂加密场景:
php
运行
<?php
/**
* EnPHP动态逆向脚本(高级版)
* 适用:高度混淆、多层加密、变量替换严重的EnPHP代码
* 原理:劫持eval函数,记录执行前的明文代码
* 作者:逆向工程师
* 日期:2026-06-05
*/
error_reporting(E_ALL);
ini_set('display_errors', 1);
ini_set('log_errors', 0);
// 配置区
$encrypted_file = 'encrypted.php'; // 待解密文件
$log_file = 'enphp_decoded.log'; // 日志文件(保存解密后的代码)
$capture_count = 0; // 捕获计数器
/**
* 劫持eval函数:记录所有eval执行的代码
*/
function hijack_eval($code) {
global $log_file, $capture_count;
$capture_count++;
// 过滤无效代码
$code = trim($code);
if (empty($code) || strlen($code) < 20) {
return eval($code); // 执行原始代码
}
// 保存解密后的代码到日志
$log_content = "===== 捕获到第 $capture_count 段代码 =====\n";
$log_content .= "时间: " . date('Y-m-d H:i:s') . "\n";
$log_content .= "代码长度: " . strlen($code) . " 字节\n";
$log_content .= "-----------------------------------------\n";
$log_content .= $code . "\n\n";
file_put_contents($log_file, $log_content, FILE_APPEND);
echo "[+] 已捕获第 $capture_count 段代码(保存到 $log_file)\n";
// 执行原始代码(保持程序正常运行)
return eval($code);
}
// 替换内置eval函数
rename_function('eval', 'original_eval');
override_function('eval', '$code', 'return hijack_eval($code);');
echo "===== EnPHP动态逆向脚本开始 =====\n";
echo "[*] 劫持eval函数成功\n";
echo "[*] 日志文件: $log_file\n";
echo "[*] 正在执行加密文件: $encrypted_file\n\n";
// 执行加密文件(触发解密流程)
try {
include $encrypted_file;
echo "\n[*] 执行完成,共捕获 $capture_count 段代码\n";
echo "提示:请查看日志文件获取解密后的完整代码\n";
} catch (Exception $e) {
echo "[!] 执行过程中出错: " . $e->getMessage() . "\n";
echo "[!] 已捕获 $capture_count 段代码\n";
}
echo "===== 动态逆向完成!=====\n";
/**
* 辅助函数:还原变量名(简单模式)
* 适用于EnPHP字母混淆模式(encode_var=1)
*/
function restore_variables($code) {
// 匹配EnPHP字母混淆变量(如 $a1b2c3)
$pattern = '/\$([a-zA-Z][a-zA-Z0-9]{2,})/';
$variables = [];
preg_match_all($pattern, $code, $matches);
foreach ($matches[1] as $var) {
if (!isset($variables[$var])) {
$variables[$var] = '$var_' . count($variables);
}
}
// 替换变量名
foreach ($variables as $old => $new) {
$code = str_replace('$' . $old, $new, $code);
}
return $code;
}
?>
四、逆向实战步骤
1. 静态分析流程
- 识别加密特征:打开加密文件,查找
eval、gzinflate、base64_decode、preg_replace('/./e')等关键词 - 提取编码字符串:使用正则表达式提取被加密的核心字符串
- 逐层解码:先 base64 解码,再 gzinflate 解压,重复直到获取可读代码
- 去混淆:手动或用脚本还原变量名和函数名
2. 动态调试流程
- 准备环境:在隔离环境中部署脚本和加密文件
- 运行动态脚本:执行
php enphp_dynamic_decrypt.php - 分析日志:查看
enphp_decoded.log获取完整解密代码 - 后处理:使用
restore_variables函数或手动还原混淆变量
3. 复杂加密处理技巧
表格
| 加密类型 | 处理方法 | 工具推荐 |
|---|---|---|
| 乱码变量混淆 | 动态调试捕获执行时代码,再用代码格式化工具 | PhpStorm、VS Code(代码格式化) |
| 多层嵌套加密 | 递归解码,设置最大深度防止无限循环 | 本文静态脚本(max_depth 参数) |
| 函数调用混淆 | 查找函数映射关系,批量替换真实函数名 | 正则表达式、批量替换工具 |
| 垃圾代码干扰 | 静态分析剔除无效代码,保留核心执行逻辑 | Notepad++(正则替换) |
五、逆向注意事项与法律声明
- 法律合规:逆向仅用于合法授权的代码(如自己加密的代码、开源项目、授权商业软件),严禁用于破解他人版权作品
- 安全防护:在隔离环境中执行逆向操作,避免恶意代码执行风险
- 效果评估:
- EnPHP 基础加密(仅 base64+gzinflate):100% 可还原
- 高度混淆(乱码变量 + 多层编码 + 垃圾代码):可还原核心逻辑,但变量名可能无法完全恢复原始状态
- 商业级加密(如 IonCube、Zend Guard):本文脚本不适用,需专业工具
六、逆向脚本使用示例
- 静态逆向: bash运行
# 保存脚本为 enphp_static_decrypt.php # 执行 php enphp_static_decrypt.php - 动态逆向: bash运行
# 保存脚本为 enphp_dynamic_decrypt.php # 执行 php enphp_dynamic_decrypt.php # 查看结果 cat enphp_decoded.log
七、总结
EnPHP 作为国产 PHP 加密工具,其防护机制主要基于混淆 + 编码 + 压缩 + 动态执行的组合。本文提供的两套逆向脚本可有效应对大多数 EnPHP 加密场景,静态脚本适合基础加密,动态脚本适合复杂加密。
逆向技术是一把双刃剑,应始终遵守法律法规,仅用于合法授权的场景。对于商业软件,建议通过官方渠道获取授权,而非逆向破解。
正文完
可以使用微信扫码关注公众号(ID:xzluomor)