/*
时间: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. 源代码加密软件选型分析

    1源代码加密软件需求背景: 目前很多企业都拥有自己的研发机构,其研发成果往往体现在源代码和技术文档方面,这些核心机密,如何防止研发参与人员泄密,如何防止核心成员把研究成果带走另立山头,或者提供给竞争对 ...

  2. jsencrypt代码分析——openssl的rsa加密解密在js的实现

    在js上做rsa,感觉jsencrypt这个是封装的比较好的,但用起来还是遇到了些坑,所以踩进代码里填填坑- 项目在这里 https://github.com/travist/jsencrypt [r ...

  3. MediaInfo源代码分析 5:JPEG解析代码分析

    ===================================================== MediaInfo源代码分析系列文章列表: MediaInfo源代码分析 1:整体结构 Me ...

  4. BT源代码学习心得(七):跟踪服务器(Tracker)的代码分析(HTTP协议处理对象) -- 转贴自 wolfenstein (NeverSayNever)

    BT源代码学习心得(七):跟踪服务器(Tracker)的代码分析(HTTP协议处理对象) author: wolfenstein (NeverSayNever) 上次我们分析了Tracker类初始化的 ...

  5. BT源代码学习心得(六):跟踪服务器(Tracker)的代码分析(初始化) -- 转贴自 wolfenstein (NeverSayNever)

    BT源代码学习心得(六):跟踪服务器(Tracker)的代码分析(初始化) author:wolfenstein Tracker在BT中是一个很重要的部分.这个名词我注意到以前的文章中都是直接引用,没 ...

  6. BT源代码学习心得(八):跟踪服务器(Tracker)的代码分析(用户请求的实际处理) - 转贴自 wolfenstein (NeverSayNever)

    BT源代码学习心得(八):跟踪服务器(Tracker)的代码分析(用户请求的实际处理) author: wolfenstein 通过上一次的分析,我们已经知道了Tracker采用http协议和客户端通 ...

  7. BT源代码学习心得(六):跟踪服务器(Tracker)的代码分析(初始化)

    BT源代码学习心得(六):跟踪服务器(Tracker)的代码分析(初始化) 发信人: wolfenstein (NeverSayNever), 个人文集 标  题: BT源代码学习心得(六):跟踪服务 ...

  8. 源代码加密软件类型分析

    随着计算机和网络技术的普及发展,公司和企业的办公方式和业务流发生了翻天覆地的变化. 全世界有60%的人主要从事与信息的生成.加工和存储以及相关技术的服务性工作.大量数据信息的创建.存储.传输以及共享方 ...

  9. 你绝对能看懂的Kafka源代码分析-KafkaConsumer类代码分析

    目录: <Kafka Producer设计分析> <KafkaProducer类代码分析> <RecordAccumulator类代码分析> <Sender类 ...

最新文章

  1. Redis 缓存穿透、雪崩、缓存数据库不一致、持久化方式、分布式锁、过期策略
  2. mac 查看端口_黑客克星养成记 系列二:MAC-Flooding原理及解决方案
  3. 每日一皮:唯一的编码思想!
  4. 美国计算机科学厉害的大学,求推荐美国综合排名40~70间计算机科学较好的大学...
  5. bzoj1452: [JSOI2009]Count
  6. 【TensorFlow】笔记3:MNIST数字识别问题
  7. 图像处理--线line 提取
  8. ppt演讲计时器_用演示文稿演讲的10个技巧
  9. ubuntu16.04 配置nginx支持redis
  10. 放松时刻——C#分割字符串
  11. android arcgis 绘制圆_arcgis for android 定位 圆
  12. powerbi使用说明_一起学微软Power BI系列-官方文档-入门指南(3)Power BI建模
  13. 计算机软件考研北京学校,软件考研考哪些学校
  14. 信息熵与老鼠试药、称球问题
  15. 国外最好用的WordPress主机推荐
  16. SqlServer 如何插入图片和导出图片数据
  17. php lumen timestamp,一次 lumen 调优的记录
  18. Arduino智能浇灌系统
  19. 新版火狐 拖 功能_Firefox 33的新功能
  20. Java 输入一个正整数的字符串,输出与它最接近的对称数字(不包括它自己)的字符串

热门文章

  1. oracle 等待的进程,Oracle 等待事件:ges generic event
  2. 恢复账套提示文件上的媒体簇结构不正确_用友U8软件用友固定资产(账套数据结构不正确)...
  3. electron+vue3全家桶+vite项目搭建【九】集成vite-plugin-mock-server 模拟后端请求
  4. 印度软件,告诉我们什么?(转)
  5. 发育中的小鼠大脑细胞与结构图谱
  6. CPU到计算机刷新速度,计算机CPU运算速度是多少
  7. next.js 初试
  8. Jmetal Problem和Problem Set的变量范围
  9. CH340晶体不起振
  10. 安卓端微信H5下载文件处理:让微信自动弹起跳转外部浏览器窗口