做淘宝优惠券的时候,搞了一套网站的源码,不过是加密的,现在来尝试解密来熟悉正则表达式
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2017/9/9
* Time: 23:07
*/
namespace app\admin\controller;
class Decode extends Controller
{
public function index()
{
$CommonVar = [
'$_SERVER' => [],
'$_GET' => [],
'$GLOBALS' => [],
];
foreach ($GLOBALS as $key => $value) {
$encode = mb_detect_encoding($key, array("ASCII"));
if ($encode !== 'ASCII') {
//$CommonVar['$GLOBALS'][$key] = $value;
}
}
foreach ($_GET as $key => $value) {
$encode = mb_detect_encoding($key, array("ASCII"));
if ($encode !== 'ASCII') {
//$CommonVar['$_GET'][$key] = $value;
}
}
foreach ($_SERVER as $key => $value) {
$encode = mb_detect_encoding($key, array("ASCII"));
if ($encode !== 'ASCII') {
//$CommonVar['$_SERVER'][$key] = $value;
}
}
//halt(get_defined_constants());
header('Content-type:text/html;Charset=utf-8');
$filePath = 'application/index/controller/Goods.php';
$output = file_get_contents($filePath);
//dump($output);
$allVar = [];
getphpCode($output, $allVar, $ErrString);
$pat_array = [];
$this->replace_all_isset_global($output, $CommonVar);
//最后的文本将$this->request->{'param'}类似的转化
$pattner = '/\{\'([a-zA-Z_]*?)\'\}/';
preg_match_all($pattner, $output, $pat_array);
foreach ($pat_array[0] as $key => $value) {
$output = str_replace($value, $pat_array[1][$key], $output);
}
//将最后的文本 defind(xx,xxx); 删掉
$pattner = '/define\([\s\S]*?\)\;/';
preg_match_all($pattner, $output, $pat_array);
foreach ($pat_array[0] as $key => $value) {
$output = str_replace($value, '', $output);
}
//将最后的文本中 return $this->success( -> $this->success(
//将最后的文本中 return $this->error( -> $this->error(
$output = str_replace('return $this->success(', '$this->success(', $output);
$output = str_replace('return $this->error(', '$this->error(', $output);
dump($pat_array);
dump($CommonVar);
dump($output);
put_stop($output);
die;
}
/** info:替换所有的已经定义的变量
* @param $output
* @param $CommonVar
*/
public function replace_all_isset_global(&$output,&$CommonVar){
//先匹配是否有$Ser[xxx] = explode(xxx)格式的,将如$CommonVar
//匹配是否有explode的数据
$pattern = '/(\$_SERVER|\$_GET|\$GLOBALS)(\{(.*?)\}|\[(.*?)\])[\s]?\=[\s]?explode\(\'(.*?)\',[\s]*([\s\S]*?)\)\;/';
$result = preg_match($pattern, $output, $pat_array);
if($result){
//explode\('([\s\S]*?)',[\s]*(gzinflate\(substr\('([\s\S]*?)',[\s\S]*?,[\s\S]*?\)\))\)\;
$pattern = '/(\$_SERVER|\$_GET|\$GLOBALS)(\{(.*?)\}|\[(.*?)\])[\s]?\=[\s]?(explode\(\'(.*?)\',[\s]?(gzinflate\(substr\(\'([\s\S]*?)\',[\s\S]*?,[\s\S]*?\)\))\))\;/';
$result = preg_match($pattern, $output, $pat_array_li);
if($result){
//匹配gzinflate 需要解压缩
$pat_array = $pat_array_li;
$explode_result = return_explode($pat_array[5]);
if(empty($explode_result[0])){
$explode_result = explode($pat_array[6],gzinflate_decode($pat_array[8]));
if(empty($explode_result[0])){
getphpCode($output, $allVar, $gzinflateStr);
dump('错误!');
halt($gzinflateStr);
}
}
dump('解析出数组');
dump($explode_result);
$variable_name = $pat_array[1];
if(!empty($pat_array[3])){
$key_name = $pat_array[3];
}else{
$key_name = $pat_array[4];
}
$CommonVar[$variable_name][$key_name] = $explode_result;
$str = PHP_EOL . $variable_name . '[' . $key_name . '] = ' . array_format_echo($explode_result) . ';' . PHP_EOL;
//如果匹配上了的话,将字符串格式话成数组拼接转化
$output = str_replace($pat_array[0], $str, $output);
$this->replace_all_global_variable($output,$CommonVar);
//put_stop($output);
//转换之后 删除第一次匹配
$output = str_replace($str, PHP_EOL, $output);
}else{
ob_clean();
//没有匹配到需要gzinflate解码的数据
//不需要解压缩,直接获得explode之后的数据
//$pattern = '/(\$_SERVER|\$_GET|\$GLOBALS)(\{([\s\S]*?)\}|\[([\s\S]*?)\])[\s]?\=[\s]?explode\(\'([\s\S]*?)\',[\s]?\'(.*?)\'\)\;/';
//注意: 由于正则表达式中 . 表示出换行符以外的所有单个字符,所以需要用到[\s\S]
$pattern = '/(\$_SERVER|\$_GET|\$GLOBALS)(\{(.*?)\}|\[(.*?)\])[\s]?\=[\s]?explode\(\'(.*?)\',[\s]?\'([\s\S]*?)\'\)\;/';
$result = preg_match($pattern, $output, $pat_array);
dump('66');
if($result){
$variable_name = $pat_array[1];
//如果匹配到第三个、第四个有一个OK
if(!empty($pat_array[3])){
$key_name = $pat_array[3];
}else{
$key_name = $pat_array[4];
}
//explode爆裂后的数据
$explode_result = explode($pat_array[5],stripcslashes($pat_array[6]));
if(count($explode_result)>1){
//加入全局数组
$CommonVar[$variable_name][$key_name] = $explode_result;
}else{
$explode_result = explode($pat_array[5],$pat_array[6]);
//加入全局数组
$CommonVar[$variable_name][$key_name] = $explode_result;
}
//将匹配到的explode格式话成数组格式
$str = PHP_EOL . $variable_name . '[' . $key_name . '] = ' . array_format_echo($explode_result) . ';' . PHP_EOL;
$output = str_replace($pat_array[0], $str, $output);
//替换所有变量
$this->replace_all_global_variable($output,$CommonVar);
//转换之后 删除第一次匹配
$output = str_replace($str, PHP_EOL, $output);
}
}
dump($output);
//替换文中引用全局变量的变量
$this->replace_yinyong_variables($output,$CommonVar);
dump($CommonVar);
//持续替换已定义的变量
$this->replace_all_isset_global($output,$CommonVar);
} else{
//ob_clean();
//halt($CommonVar);
//替换文中引用全局变量的变量
//$this->replace_yinyong_variables($output,$CommonVar);
//替换所有变量
$this->replace_all_global_variable($output,$CommonVar);
}
}
//替换所有的全局变量
public function replace_all_global_variable(&$output,&$CommonVar){
$End = 0;
foreach($CommonVar as $variable_name=>$variable_value){
$break = 0;
foreach($variable_value as $key=>$value){
$explode_result = $CommonVar[$variable_name][$key];
dump($variable_name);
dump($key);
$key = trim($key,'\'');
//四种 $variable_name[$value]
//四种 $variable_name['\''.$value.'\'']
//四种 $variable_name{$value}
//四种 $variable_name{'\''.$value.'\''}
$i=0;
$pattern[1] = '/'.preg_quote($variable_name.'['.$key.']').'(\{([^\{^\[]*?)\}|\[([^\[^\{]*?)\])/';
$pattern[2] = '/'.preg_quote($variable_name.'[\''.$key.'\']').'(\{([^\{^\[]*?)\}|\[([^\[^\{]*?)\])/';
$pattern[3] = '/'.preg_quote($variable_name.'{'.$key.'}').'(\{([^\{^\[]*?)\}|\[([^\[^\{]*?)\])/';
$pattern[4] = '/'.preg_quote($variable_name.'{\''.$key.'\'}').'(\{([^\{^\[]*?)\}|\[([^\[^\{]*?)\])/';
foreach($pattern as $k=>$v){
preg_match_all($v,$output,$pat_array);
dump($pat_array);
if(count($pat_array[0])>0){
$this->replace_global_variable($output,$pat_array,$explode_result);
}else{
$i++;
}
}
if($i==4){
//如果四种模式都没有匹配,父级foreach跳出
$break=1;
continue;
}
}
if($break==1){
$End = 1;
continue;
}
}
if($End !== 1){
$this->replace_all_global_variable($output,$CommonVar);
}
}
public function replace_global_variable(&$output, $pat_array, $explode_result)
{
foreach ($pat_array[0] as $key => $value) {
$index = $pat_array[2][$key];
if ($index !== '') {
//dump($index);
if (isset($explode_result[$index])) {
$relace_str = $explode_result[$index];
//dump('有-'.$relace_str);
if (!function_exists($relace_str)) {
$relace_str = array_format_echo($relace_str);
}
//dump($value);dump('=>');dump($relace_str);
$output = str_replace($value, $relace_str, $output);
}else{
//dump('没有');
}
}
}
//一个是字符串
foreach ($pat_array[0] as $key => $value) {
$index = $pat_array[3][$key];
if ($index !== '') {
if (isset($explode_result[$index])) {
$relace_str = $explode_result[$index];
//dump('有-'.$relace_str);
if (!function_exists($relace_str)) {
$relace_str = array_format_echo($relace_str);
}
//dump($value);dump('=>');dump($relace_str);
$output = str_replace($value, $relace_str, $output);
}else{
//dump('没有');
}
}
}
}
/** 匹配到 $var_xx = &$Goll[xx];
* @param $output
* @param $CommonVar
*/
public function replace_yinyong_variables(&$output,&$CommonVar){
$pattern = '/(\$var_[0-9]*?)+[\s]?\=[\s]?[\&]?[\s]?((\$_SERVER|\$_GET|\$GLOBALS)(\{([^\[^\{]+?)\}|\[([^\[^\{]+?)\]+?))\;/';
preg_match_all($pattern, $output, $pat_array);
//匹配所有经引用的变量
dump('匹配所有经引用的变量');
dump($pat_array);
if (count($pat_array[0])>0) {
foreach ($pat_array[5] as $key => $value) {
$replcae_var = $pat_array[1][$key];
$variable_name = $pat_array[3][$key];
$key_name = $value;
if(isset($CommonVar[$variable_name][$key_name])){
$decode_result = $CommonVar[$variable_name][$key_name];
}else{
$decode_result = $CommonVar[$variable_name]['\''.$key_name.'\''];
}
$CommonVar[$replcae_var] = $CommonVar[$variable_name];
if(!empty($decode_result)){
$pattern = '/' . preg_quote($replcae_var) . '(\{([^\[]+?)\}|\[([^\}]+?)\]+?)/';
preg_match_all($pattern, $output, $pat_array_li);
$this->replace_global_variable($output,$pat_array_li,$decode_result);
//清除无效的
$output = str_replace($pat_array[0][$key], PHP_EOL, $output);
}
}
//开始替换: 方法里面重新定义变量,引用了全局变量
}
}
}