关于“给PHP源代码加密“的代码分析
/*
时间:2022-1-9
作者:aweii
内容:关于"给PHP源代码加密"的代码分析[原创]
*/
网上看到一则"给PHP源代码加密"的代码,饶有兴趣研究了下(https://www.jb51.net/article/134506.htm)。代码如下:
<?phpfunction RandAbc($length = "") { // 返回随机字符串 $str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; return str_shuffle($str); } $filename = 'index.php'; //要加密的文件 $T_k1 = RandAbc(); //随机密匙1 $T_k2 = RandAbc(); //随机密匙2 $vstr = file_get_contents($filename); $v1 = base64_encode($vstr); $c = strtr($v1, $T_k1, $T_k2); //根据密匙替换对应字符。 $c = $T_k1.$T_k2.$c; $q1 = "O00O0O"; $q2 = "O0O000"; $q3 = "O0OO00"; $q4 = "OO0O00"; $q5 = "OO0000"; $q6 = "O00OO0"; $s = '$'.$q6.'=urldecode("%6E1%7A%62%2F%6D%615%5C%76%740%6928%2D%70%78%75%71%79%2A6%6C%72%6B%64%679%5F%65%68%63%73%77%6F4%2B%6637%6A");$'.$q1.'=$'.$q6.'{3}.$'.$q6.'{6}.$'.$q6.'{33}.$'.$q6.'{30};$'.$q3.'=$'.$q6.'{33}.$'.$q6.'{10}.$'.$q6.'{24}.$'.$q6.'{10}.$'.$q6.'{24};$'.$q4.'=$'.$q3.'{0}.$'.$q6.'{18}.$'.$q6.'{3}.$'.$q3.'{0}.$'.$q3.'{1}.$'.$q6.'{24};$'.$q5.'=$'.$q6.'{7}.$'.$q6.'{13};$'.$q1.'.=$'.$q6.'{22}.$'.$q6.'{36}.$'.$q6.'{29}.$'.$q6.'{26}.$'.$q6.'{30}.$'.$q6.'{32}.$'.$q6.'{35}.$'.$q6.'{26}.$'.$q6.'{30};eval($'.$q1.'("'.base64_encode('$'.$q2.'="'.$c.'";eval(\'?>\'.$'.$q1.'($'.$q3.'($'.$q4.'($'.$q2.',$'.$q5.'*2),$'.$q4.'($'.$q2.',$'.$q5.',$'.$q5.'),$'.$q4.'($'.$q2.',0,$'.$q5.'))));').'"));'; $s = '<?php '."\n".$s."\n".' ?>'; //echo $s; // 生成 加密后的PHP文件 $fpp1 = fopen('temp_'.$filename, 'w'); fwrite($fpp1, $s) or die('写文件错误'); ?>
以上代码极尽代码加密、混淆之能事,目的只有一个,让阅读者云里雾里,从而无法窥见真实的源码。但其实,对php程序员而言,根据上述算法,
是可以还原出源码的,就是稍费些功夫而已。下面,就一步步分析还原上述代码的逻辑。
$filename中存放源码文件名,'temp_'.$filename是目标文件名存放加密后的代码。首先生成$T_k1、$T_k2两个随机密钥,
源码读入变量$vstr中,对源码先进行base64_encode编码,然后用密钥做加密后放入$c变量(简单的凯撒密码,就是用密码本做字符替换的那种,不过这个密码本是随机生成的而已)。最后的$c还要在首部把两个密钥加上,后续运行时解密要用到。
$q1~$6存放6个临时变量名,这在加密文件运行过程中使用。最后把解密代码、加密字符串$c合成处理后(存放于临时变量$s中)放入目标文件。
那么奥秘主要在于$s中的内容及运行时的解密步骤了。
下面是$s的内容,是不是看着眼花,莫急,待我慢慢道来。
$s = '$'.$q6.'=urldecode("%6E1%7A%62%2F%6D%615%5C%76%740%6928%2D%70%78%75%71%79%2A6%6C%72%6B%64%679%5F%65%68%63%73%77%6F4%2B%6637%6A");$'.$q1.'=$'.$q6.'{3}.$'.$q6.'{6}.$'.$q6.'{33}.$'.$q6.'{30};$'.$q3.'=$'.$q6.'{33}.$'.$q6.'{10}.$'.$q6.'{24}.$'.$q6.'{10}.$'.$q6.'{24};$'.$q4.'=$'.$q3.'{0}.$'.$q6.'{18}.$'.$q6.'{3}.$'.$q3.'{0}.$'.$q3.'{1}.$'.$q6.'{24};$'.$q5.'=$'.$q6.'{7}.$'.$q6.'{13};$'.$q1.'.=$'.$q6.'{22}.$'.$q6.'{36}.$'.$q6.'{29}.$'.$q6.'{26}.$'.$q6.'{30}.$'.$q6.'{32}.$'.$q6.'{35}.$'.$q6.'{26}.$'.$q6.'{30};eval($'.$q1.'("'.base64_encode('$'.$q2.'="'.$c.'";eval(\'?>\'.$'.$q1.'($'.$q3.'($'.$q4.'($'.$q2.',$'.$q5.'*2),$'.$q4.'($'.$q2.',$'.$q5.',$'.$q5.'),$'.$q4.'($'.$q2.',0,$'.$q5.'))));').'"));';
首先,echo $s; 看看到底最后是什么东东。原始代码都在一行,为便于阅读,我加了回车。
以第一个eval为界可分两部分来看,前半部分代入变量值为:
$O00OO0=urldecode("%6E1%7A%62%2F%6D%615%5C%76%740%6928%2D%70%78%75%71%79%2A6%6C%72%6B%64%679%5F%65%68%63%73%77%6F4%2B%6637%6A");
$O00O0O=$O00OO0{3}.$O00OO0{6}.$O00OO0{33}.$O00OO0{30};
$O0OO00=$O00OO0{33}.$O00OO0{10}.$O00OO0{24}.$O00OO0{10}.$O00OO0{24};
$OO0O00=$O0OO00{0}.$O00OO0{18}.$O00OO0{3}.$O0OO00{0}.$O0OO00{1}.$O00OO0{24};
$OO0000=$O00OO0{7}.$O00OO0{13};
$O00O0O.=$O00OO0{22}.$O00OO0{36}.$O00OO0{29}.$O00OO0{26}.$O00OO0{30}.$O00OO0{32}.$O00OO0{35}.$O00OO0{26}.$O00OO0{30};
后半部分为:
'eval($'.$q1.'("'.base64_encode('$'.$q2.'="'.$c.'";eval(\'?>\'.$'.$q1.'($'.$q3.'($'.$q4.'($'.$q2.',$'.$q5.'*2),$'.$q4.'($'.$q2.',$'.$q5.',$'.$q5.'),$'.$q4.'($'.$q2.',0,$'.$q5.'))));').'"))';
变量代入后($c是加密的代码,没做替换)得到
eval($O00O0O(base64_encode('$O0O000="'.$c.'";eval(\'?>\'$O00O0O($O0OO00($OO0O00($O0O000,$OO0000*2),$OO0O00($O0O000,$OO0000,$OO0000),$OO0O00($O0O000,0,$OO0000))));')));
上面代码依然不直观,通过echo 可以进一步得到各变量的值,本质上是下面的结果:
$O00OO0="n1zb/ma5\vt0i28-pxuqy*6lrkdg9_ehcswo4+f37j";
$O00O0O="base";
$O0OO00="strtr";
$OO0O00="substr";
$OO0000="52";
$O00O0O.="64_decode"; //$O00O0O="base64_decode";
所以后半部分为:化为:
eval(base64_decode(
base64_encode('$O0O000="'.$c.'";eval(\'?>\'.base64_decode(strtr(substr($O0O000,52*2), //去掉$T_k1.$T_k2后的$csubstr($O0O000,52,52), //$T_k2substr($O0O000,0,52) //$T_k1)));')));
首先,$O0O000赋值为加密代码$c,然后再执行内嵌的eval,上述代码等价于
eval('eval(\'?>\'.base64_decode(
strtr(substr(加密代码串,52*2),substr(加密代码串,52,52),substr(加密代码串,0,52))
);');
这相当于在php环境中运行
eval('?>'.base64_decode(strtr(substr($c,52*2),substr($c,52,52),substr($c,0,52))));//$c代表加密代码串
注意,外层eval负责base64_decode、strtr、substr函数的执行(解密、解码过程)以及执行内嵌eval函数,
内嵌eval执行的是解密、解码后的原始代码。这里边引号的使用极见技巧,决定着代码是由外层eval还是内层eval执行。
strtr(……)这部分是上述加密的逆过程,因为是字符还原过程,所以两个密钥参数$T_k1,$T_k2调换了位置,解密后再用base64_decode解码
就得到了源代码。用'?>'和解密解码后的源代码串连接是因为源代码都是<?php开始的,所以要先结束上段php代码,再开始另一段php代码,
如果不这么处理,运行时会出现"eval()’d code"错误。
以下为补充:
其中base64_decode(strtr(substr($c,52*2),substr($c,52,52),substr($c,0,52)))是上述加密的逆过程(解密),再回顾下上述加密过程:
$v1 = base64_encode($vstr); $c = strtr($v1, $T_k1, $T_k2); //根据密匙替换对应字符。 $c = $T_k1.$T_k2.$c;
所以最后就是
eval('?>'.你的原始代码);
比如你的代码:
<?php
echo "Hello world!\n";
?>
运行加密后,再运行加密的文件,进行上述解密转换,最后运行的代码为:
eval('?>'."<?php
echo "Hello world!\n";
?>");
关于“给PHP源代码加密“的代码分析相关推荐
- 源代码加密软件选型分析
1源代码加密软件需求背景: 目前很多企业都拥有自己的研发机构,其研发成果往往体现在源代码和技术文档方面,这些核心机密,如何防止研发参与人员泄密,如何防止核心成员把研究成果带走另立山头,或者提供给竞争对 ...
- jsencrypt代码分析——openssl的rsa加密解密在js的实现
在js上做rsa,感觉jsencrypt这个是封装的比较好的,但用起来还是遇到了些坑,所以踩进代码里填填坑- 项目在这里 https://github.com/travist/jsencrypt [r ...
- MediaInfo源代码分析 5:JPEG解析代码分析
===================================================== MediaInfo源代码分析系列文章列表: MediaInfo源代码分析 1:整体结构 Me ...
- BT源代码学习心得(七):跟踪服务器(Tracker)的代码分析(HTTP协议处理对象) -- 转贴自 wolfenstein (NeverSayNever)
BT源代码学习心得(七):跟踪服务器(Tracker)的代码分析(HTTP协议处理对象) author: wolfenstein (NeverSayNever) 上次我们分析了Tracker类初始化的 ...
- BT源代码学习心得(六):跟踪服务器(Tracker)的代码分析(初始化) -- 转贴自 wolfenstein (NeverSayNever)
BT源代码学习心得(六):跟踪服务器(Tracker)的代码分析(初始化) author:wolfenstein Tracker在BT中是一个很重要的部分.这个名词我注意到以前的文章中都是直接引用,没 ...
- BT源代码学习心得(八):跟踪服务器(Tracker)的代码分析(用户请求的实际处理) - 转贴自 wolfenstein (NeverSayNever)
BT源代码学习心得(八):跟踪服务器(Tracker)的代码分析(用户请求的实际处理) author: wolfenstein 通过上一次的分析,我们已经知道了Tracker采用http协议和客户端通 ...
- BT源代码学习心得(六):跟踪服务器(Tracker)的代码分析(初始化)
BT源代码学习心得(六):跟踪服务器(Tracker)的代码分析(初始化) 发信人: wolfenstein (NeverSayNever), 个人文集 标 题: BT源代码学习心得(六):跟踪服务 ...
- 源代码加密软件类型分析
随着计算机和网络技术的普及发展,公司和企业的办公方式和业务流发生了翻天覆地的变化. 全世界有60%的人主要从事与信息的生成.加工和存储以及相关技术的服务性工作.大量数据信息的创建.存储.传输以及共享方 ...
- 你绝对能看懂的Kafka源代码分析-KafkaConsumer类代码分析
目录: <Kafka Producer设计分析> <KafkaProducer类代码分析> <RecordAccumulator类代码分析> <Sender类 ...
最新文章
- Redis 缓存穿透、雪崩、缓存数据库不一致、持久化方式、分布式锁、过期策略
- mac 查看端口_黑客克星养成记 系列二:MAC-Flooding原理及解决方案
- 每日一皮:唯一的编码思想!
- 美国计算机科学厉害的大学,求推荐美国综合排名40~70间计算机科学较好的大学...
- bzoj1452: [JSOI2009]Count
- 【TensorFlow】笔记3:MNIST数字识别问题
- 图像处理--线line 提取
- ppt演讲计时器_用演示文稿演讲的10个技巧
- ubuntu16.04 配置nginx支持redis
- 放松时刻——C#分割字符串
- android arcgis 绘制圆_arcgis for android 定位 圆
- powerbi使用说明_一起学微软Power BI系列-官方文档-入门指南(3)Power BI建模
- 计算机软件考研北京学校,软件考研考哪些学校
- 信息熵与老鼠试药、称球问题
- 国外最好用的WordPress主机推荐
- SqlServer 如何插入图片和导出图片数据
- php lumen timestamp,一次 lumen 调优的记录
- Arduino智能浇灌系统
- 新版火狐 拖 功能_Firefox 33的新功能
- Java 输入一个正整数的字符串,输出与它最接近的对称数字(不包括它自己)的字符串
热门文章
- oracle 等待的进程,Oracle 等待事件:ges generic event
- 恢复账套提示文件上的媒体簇结构不正确_用友U8软件用友固定资产(账套数据结构不正确)...
- electron+vue3全家桶+vite项目搭建【九】集成vite-plugin-mock-server 模拟后端请求
- 印度软件,告诉我们什么?(转)
- 发育中的小鼠大脑细胞与结构图谱
- CPU到计算机刷新速度,计算机CPU运算速度是多少
- next.js 初试
- Jmetal Problem和Problem Set的变量范围
- CH340晶体不起振
- 安卓端微信H5下载文件处理:让微信自动弹起跳转外部浏览器窗口