php解混淆加密:简单说明一下,具体是什么加密我也不知道,可能是phpjm2
本人php水平比较烂,由于在PU系干了多年二次开发导致水平很不行啊。也不会vscode+xdebug进行调试,纯粹是在网上找的。外加自己写的。代码比较烂,希望不要批评。昨天买了一套源码,发现商家加密了,想更改改不了。花了几块钱使用了网上破解平台,破解了7个文件,发现源码里还有好多加密文件,实在不想花钱了,穷,自己研究了一下。写的文档也不好,我已经不知道我写的是啥了,大家见谅。最后我写了一个解码文件。
———————————言归正传*手动分析过程—————————————
此加密方式我也不知道叫啥,有的php解密平台显示phpjm2、zym、新版phpjm我也不知道是那个,知道的可以评论我改一下标题。
加密文件里面有#!/usr/bin/php -q标识和一堆类似于base64代码,以及混淆的乱码变量。
加密文件如下图:
(install.php 加密前的完整源码文件)。
变量比较杂乱,手动分析,那里是换行,都不知道,不过在网上看到。
phpjm的函数变量命名都是 \$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]* 这个范围的。
来源:https://blog.csdn.net/sbdx/article/details/70677197提供的代码无法解密,不过我使用了他一小部分代码。
<?php
$filename='install'; //文件名,不要添加后缀
$str = file_get_contents("$filename.php");
preg_match_all('|[\w\x7f-\xff]*|', $str, $params) or die('err 1.');
$params = array_unique($params); // 去重复
$replace = array();
foreach ($params as $k=>$v){
if(preg_match('/+/',$v,$re)){//过滤掉正常的英文变量名
unset($params[$k]);
continue;
}
$replace[] = 'MD5_'.md5($v);
}
$str = str_replace($params, $replace, $str);
file_put_contents($filename."_2.php", $str);//新生成一个文件
echo 'Done.';
exit();
通过上述代码,把比较乱的混淆文件变成了新文件install_2.php,如下图一样。电脑显示器小,截图接不全面,尽量口述了
格式化一下源代码,手动调试就很方便了。
__FILE__ 改成最原始文件的路径,因为新文件发生改变偏移也改变了。
把eval的变量存储一个新的文件 install_3.php。
又获得一个新的混淆乱码文件install_3.php。
通过最上面的php代码把install_3.php这个混淆文件,在变成一个稍微正常点的新文件install_3_2.php。
继续php代码格式化一下,接着手动分析。
红框内都是判断,IP,域名,使用时间,是不是命令行调试php,如果相应信息不匹配,就会实行一个 @MD5_7e42a98c08b947087c388b9b3318d52b();不存在的方法,达到不显示错误且终止运行的目的。
把所有@MD5_7e42a98c08b947087c388b9b3318d52b(); 已@开头的方法,替换成NULL; 这样就不会影响下面获取最终源码了。
这个文件中有很多参数给,最终混淆源码文件用的,每一次混淆加密之间都有关联,有点恶心啊。
把eval的变量存储一个新的文件 install_4.php,需要install_2.php中的函数和变量依赖引用进来。
获得最终乱码文件install_4.php。
给install_4.php整整容,通过上面的源码,变成一个正常文件install_4_2.php。
这就是最终的内容,很多依赖都是上面的文件中的参数。手动通过上面解析出来的参数和方法替换一下,就是源文件了,有些变量不可逆的,但是不影响使用。
---------------------肯定不少人听我说的云里雾里*没办法叙述就是这样啊-------------------------------
最后我把我自己写的巨丑的解码文件,分享出来。写完我就要睡觉去了,农村父母睡觉早啊。
大佬通道:
<?php
$filename='FirstendAction.class';//文件名 不要后缀
$str = file_get_contents("$filename.php");
preg_match_all('|[\w\x7f-\xff]*|', $str, $params) or die('err 1.');
$params = array_unique($params); // 去重复
$replace = array();
foreach ($params as $k=>$v){
if(preg_match('/+/',$v,$re)){//过滤掉正常的英文变量名
unset($params[$k]);
continue;
}
$replace[] = 'MD5_'.md5($v);
}
$str = str_replace($params, $replace, $str);
$file_url = str_replace("\\", "/", dirname(__FILE__))."/$filename.php";
$str = str_replace('__FILE__',"'$file_url'", $str);
$str = str_replace('return(eval(',"\$aaa=((", $str);
$str = str_replace(' ?>','return $aaa; ?>', $str);
$str = str_replace('<?php ','', $str);
$str_array = explode(' ?>',$str);
//print_r($str_array);
$cc = eval($str_array);
preg_match_all('|[\w\x7f-\xff]*|', $cc, $params) or die('err 1.');
$params = array_unique($params); // 去重复
$replace2 = array();
foreach ($params as $k=>$v){
if(preg_match('/+/',$v,$re)){//过滤掉正常的英文变量名
unset($params[$k]);
continue;
}
$replace2[] = 'MD5_'.md5($v);
}
$str = str_replace($params, $replace2, $cc);
//$str = str_replace('{', '{/*', $str);
//$str = str_replace('}', '*/}', $str);
$str = str_replace('return(eval(',"\$bbb=((", $str);
$str = str_replace(' ?>','return $bbb;', $str);
preg_match_all('|\@MD5\_{32}\(\);|', $str, $params) or die('cccc');
$params = array_unique($params); // 去重复
$str = str_replace($params, 'NULL;', $str);
$dd = eval($str);
preg_match_all('|[\w\x7f-\xff]*|', $dd, $params) or die('err 1.');
$params = array_unique($params); // 去重复
$replace3 = array();
foreach ($params as $k=>$v){
if(preg_match('/+/',$v,$re)){//过滤掉正常的英文变量名
unset($params[$k]);
continue;
}
$replace3[] = 'MD5_'.md5($v);
}
$str = str_replace($params, $replace3, $dd);
$str = str_replace(';?><?php','<?php', $str);
preg_match_all('|MD5\_{32}\(\'.*?\',\'.*?\'\)|', $str, $params) or die('cccc');
$params1 = array_unique($params); // 去重复
$replace_a1 = array();
foreach ($params1 as $v){
eval("\$replace_a1[]=\"'\".".$v.".\"'\";");
}
$str = str_replace($params1, $replace_a1, $str);
//print_r($replace_a1);
//exit();
preg_match_all('|\$GLOBALS\[\'MD5\_{32}\'\]\[\'MD5\_{32}\'\]|', $str, $params) or die('cccc');
$params2 = array_unique($params); // 去重复
$replace_a2 = array();
foreach ($params2 as $v){
eval("\$replace_a2[]=".$v.";");
}
//print_r($replace_a2);
//exit();
$str = str_replace($params2, $replace_a2, $str);
//print_r($params2);
echo $str;
file_put_contents($filename.".de.php", $str);
echo 'Done.';
//print_r($GLOBALS);
//print_r($params);
//echo $str;
使用说明:
把上面代码保存一个文件,与需要解密的文件放在同一个目录。
修改$finame使用文件名,使用浏览器访问保存的这个解密文件,会生成一个 “文件名.de.php”的新文件。
$filename='FirstendAction.class';//文件名 不要后缀
————————————————————————
给大家看看,付费解密的和我手动解密的文件对比
付费平台解密的源文件
自己解密的源文件(没格式化)
思路就是把非正常字符集的变量名或方法名替换成可以勉强看明白的代码,再一层层的解 vistal 发表于 2020-6-24 10:31
哦哦好的谢谢大佬 这个您能解吗 我想解密 收F也行啊
不想解了,费事费力啊。
你可以把下面的这个代码,把变量转换成可识别的。
<?php
$filename='install'; //文件名,不要添加后缀
$str = file_get_contents("$filename.php");
preg_match_all('|[\w\x7f-\xff]*|', $str, $params) or die('err 1.');
$params = array_unique($params); // 去重复
$replace = array();
foreach ($params as $k=>$v){
if(preg_match('/+/',$v,$re)){//过滤掉正常的英文变量名
unset($params[$k]);
continue;
}
$replace[] = 'MD5_'.md5($v);
}
$str = str_replace($params, $replace, $str);
file_put_contents($filename."_2.php", $str);//新生成一个文件
echo 'Done.';
exit();
然后一定一点的手动分析
大佬,要的是解密思路啊.... 大佬,厉害! 厉害,不过一开始就格式化一下会不会好处理? 本帖最后由 涛之雨 于 2020-6-23 06:19 编辑
哈哈,
楼主辛苦了。
巧了,最近在杠jsjiami,v6的。。。
这玩意能把三句话给“加密”到25k。。。
手动拆开一看,注入的定时器,cookie,正则表达式(防止一键格式化,需要手动格式化。。。),花指令,方法抽取,多层嵌套{:301_1008:}
解密这玩意是真的费劲
楼主这写的调试过程再详细一点,再多配几张图应该会精华帖吧{:301_1008:}
过程有点省略的太多了{:301_1001:} kingwl 发表于 2020-6-23 00:17
厉害,不过一开始就格式化一下会不会好处理?
最开始格式化会乱啊,我用两个编辑器显示的乱码字符串 涛之雨 发表于 2020-6-23 06:16
哈哈,
楼主辛苦了。
巧了,最近在杠jsjiami,v6的。。。
不行啊电脑截图不全,太费事了,大家就凑合看吧,最后分享的解密文件,如果看的懂,就是我解密的思路了,其实把最开始混淆的文件变成正常的变量文件,自己手动解就快很多了 Cyntec 发表于 2020-6-22 22:46
大佬,要的是解密思路啊....
不想在改这文档了,好费事写文档好久,就是把混淆文件改成正常文件,一步一步手动解密的,可以直接下载我最后共享的文件,那个就是我手动解密的思路。 saobee 发表于 2020-6-22 22:57
思路就是把非正常字符集的变量名或方法名替换成可以勉强看明白的代码,再一层层的解
少侠,就是这样把比较乱的变量文件替换成正常的,然后手动解密,之所以用md5命名,就是上下加密文档有依赖,直接搜索md5值就找到了