Browse Source

Add decodeRecursive. Add ExplodeDelimiterWithApostropheException.

master
Ganlv 3 years ago
parent
commit
76cd4c7752
8 changed files with 132 additions and 72 deletions
  1. +12
    -2
      README.md
  2. +76
    -0
      bin/decodeRecursive.php
  3. +4
    -70
      docs/enphp_bugs.md
  4. +23
    -0
      src/KnownEnphpBugs/ExplodeDelimiterWithApostropheException.php
  5. +9
    -0
      src/KnownEnphpBugs/KnownEnphpBugsException.php
  6. +2
    -0
      src/NodeVisitors/FunctionGlobalStringNodeVisitor.php
  7. +2
    -0
      src/NodeVisitors/GlobalStringNodeVisitor.php
  8. +4
    -0
      tests/bug_samples/Rush.php

+ 12
- 2
README.md View File

@ -20,15 +20,25 @@ Download the `zip` file and unzip them into a folder. All dependencies have been
## Usage
### Decode One File
```bash
php bin/decode.php input.php output.php
```
Call `bin/decode.php` decode `input.php` and save it to `output.php`.
## About EnPHP Bugs
### Decode All Files in A Directory
```bash
php bin/decodeRecursive.php dir/
```
Call `bin/decodeRecursive.php` decode all php files in `dir/` recursively and save it to its original path.
**EnPHP is for php 5. There may be some problem is you use the obfuscated files on php 7.**
**CAUTION: This will OVERWRITE all php files! If any error happened with the decoder, your files MAY NOT BE RECOVERED! Please backup your files!**
## About EnPHP Bugs
See <docs/enphp_bugs.md>.


+ 76
- 0
bin/decodeRecursive.php View File

@ -0,0 +1,76 @@
<?php
/**
* EnPHP Decoder
*
* https://github.com/ganlvtech/php-enphp-decoder
*
* Copyright (C) 2019 Ganlv
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use Ganlv\EnphpDecoder\AutoDecoder;
use Ganlv\EnphpDecoder\KnownEnphpBugs\KnownEnphpBugsException;
error_reporting(E_ALL);
require __DIR__ . '/../vendor/autoload.php';
function endsWith($haystack, $needle)
{
$length = strlen($needle);
if ($length == 0) {
return true;
}
return (substr($haystack, -$length) === $needle);
}
function decodeRecursive($dir)
{
$files = scandir($dir);
foreach ($files as $key => $value) {
$path = realpath($dir . DIRECTORY_SEPARATOR . $value);
if (!is_dir($path)) {
if (endsWith($path, '.php')) {
echo $path;
$modified = false;
try {
$code = file_get_contents($path);
$ast = AutoDecoder::parseFile($code);
$decoder = new AutoDecoder($ast);
$modified = $decoder->autoDecode();
if ($modified) {
file_put_contents($path, $decoder->prettyPrintFile());
echo ' Decoded.';
}
} catch (KnownEnphpBugsException $e) {
echo ' Known EnPHP Bugs: ', $e->getMessage();
} catch (Throwable $e) {
echo ' Decode error.', PHP_EOL;
echo $e->getTraceAsString();
}
if (!$modified) {
echo ' Unchanged.';
}
echo PHP_EOL;
}
} else {
if ($value != '.' && $value != '..') {
decodeRecursive($path);
}
}
}
}
decodeRecursive($argv[1]);

+ 4
- 70
docs/enphp_bugs.md View File

@ -1,77 +1,11 @@
# About EnPHP Bugs
**EnPHP is for php 5. There may be some problem is you use the obfuscated files on php 7.**
## explode delimiter with apostrophe
**php 5.5 5.6 7.0 is no longer supported.** See [PHP: Supported Versions](http://php.net/supported-versions.php).
EnPHP has bugs. The obfuscated files cannot even run properly on php 7. You shouldn't ask a decoder to recover a broken file to a normal file.
See [PHP 5.x to 7.x: Changes to the handling of indirect variables, properties, and methods](http://php.net/manual/en/migration70.incompatible.php#migration70.incompatible.variable-handling.indirect).
Here are some known EnPHP bugs running on php 7. They **WON'T** be fixed.
## Class Static Call
```php
class Foo
{
public static function baz()
{
echo 'baz';
}
}
class Bar extends Foo
{
public function __construct()
{
parent::baz();
}
}
```
class Bar will be obfuscated like this
```php
class Bar extends Foo
{
public function __construct()
{
parent::$GLOBALS[GLOBAL_VAR_KEY][0x0]();
}
}
```
This means `(parent::$GLOBALS)[GLOBAL_VAR_KEY][0x0]();` instead of what we expected `parent::{$GLOBALS[GLOBAL_VAR_KEY][0x0]}();`.
## Class Method Call
```php
class Foo
{
public function bar()
{
echo 'bar';
}
public function __construct()
{
$this->bar();
}
}
```
The constructor will be encoded like this
tests/bug_samples/Rush.php
```php
class Foo
{
public function __construct()
{
$v0 = &$GLOBALS[GLOBAL_VAR_KEY];
$this->$v0[0x0]();
}
}
explode('|\'|%|\'', 'post.|\\\'|%|\\\'site_config|\\\'|%|\\\'设置成功|\\\'|%|\\\'API|\\\'|%|\\\'api_config|\\\'|%|\\\'taobao|\\\'|%|\\\'key|\\\'|%|\\\'taobaoAppkey|\\\'|%|\\\'site');
```
This means `($this->$v0)[0x0]()` instead of what we expected `$this->{$v0[0x0]}()`.
This is EnPHP's bug. Won't Fix!

+ 23
- 0
src/KnownEnphpBugs/ExplodeDelimiterWithApostropheException.php View File

@ -0,0 +1,23 @@
<?php
namespace Ganlv\EnphpDecoder\KnownEnphpBugs;
class ExplodeDelimiterWithApostropheException extends KnownEnphpBugsException
{
public $stringArray;
public $dim;
public function __construct($stringArray, $dim)
{
$this->stringArray = $stringArray;
$this->dim = $dim;
parent::__construct('explode delimiter with apostrophe.');
}
public static function test($stringArray, $dim)
{
if (!isset($stringArray[$dim]) && count($stringArray) === 1 && strpos($stringArray[0],'\\\'') !== false) {
throw new self($stringArray, $dim);
}
}
}

+ 9
- 0
src/KnownEnphpBugs/KnownEnphpBugsException.php View File

@ -0,0 +1,9 @@
<?php
namespace Ganlv\EnphpDecoder\KnownEnphpBugs;
use Exception;
abstract class KnownEnphpBugsException extends Exception
{
}

+ 2
- 0
src/NodeVisitors/FunctionGlobalStringNodeVisitor.php View File

@ -2,6 +2,7 @@
namespace Ganlv\EnphpDecoder\NodeVisitors;
use Ganlv\EnphpDecoder\KnownEnphpBugs\ExplodeDelimiterWithApostropheException;
use Ganlv\EnphpDecoder\PrettyPrinter\StandardPrettyPrinter;
use PhpParser\Node;
use PhpParser\NodeTraverser;
@ -37,6 +38,7 @@ class FunctionGlobalStringNodeVisitor extends NodeVisitorAbstract
&& $node->var instanceof Node\Expr\Variable
&& $node->var->name === $this->localVarName
&& $node->dim instanceof Node\Scalar\LNumber) {
ExplodeDelimiterWithApostropheException::test($this->stringArray, $node->dim->value);
return new Node\Scalar\String_($this->stringArray[$node->dim->value]);
}
return null;


+ 2
- 0
src/NodeVisitors/GlobalStringNodeVisitor.php View File

@ -2,6 +2,7 @@
namespace Ganlv\EnphpDecoder\NodeVisitors;
use Ganlv\EnphpDecoder\KnownEnphpBugs\ExplodeDelimiterWithApostropheException;
use Ganlv\EnphpDecoder\PrettyPrinter\StandardPrettyPrinter;
use PhpParser\Node;
use PhpParser\NodeVisitorAbstract;
@ -28,6 +29,7 @@ class GlobalStringNodeVisitor extends NodeVisitorAbstract
&& $node->var->dim !== null
&& StandardPrettyPrinter::prettyPrinter()->prettyPrintExpr($node->var->dim) === $this->globalVarKeyExpr
&& $node->dim instanceof Node\Scalar\LNumber) {
ExplodeDelimiterWithApostropheException::test($this->stringArray, $node->dim->value);
return new Node\Scalar\String_($this->stringArray[$node->dim->value]);
}
return null;


+ 4
- 0
tests/bug_samples/Rush.php View File

@ -0,0 +1,4 @@
<?php /* 遞句コ丈セ�CMS豺伜ョ晏ョ「邉サ扈� 遞句コ丈セ�迚域揀謇€譛� 謚€譛ッ隶コ蝮帶髪謖�: bbs.chengxuxia.com QQ: 573907419 豁」迚域肢譚�亟豁「蜃コ邇ー貍乗エ槫錘髣ィ
-- enphp : https://git.oschina.net/mz/mzphp2
*/
namespace app\admin\controller;error_reporting(E_ALL^E_NOTICE);define('コ佗', 'ナナツ');�湘ゥス�鎌゚苻荢ィ屎レ・靫€�チ菖�ア杦チイ�ェマ嘉ー汯ャfネ�瑙恩煜��ェ鼕匆ヒヒ�ハ�モコ。ツ佩ナ棊蛟�カ�シ、�ホリ�闃�ェキォ寥貍マ�虚椒墲ゥ鰈斷陳セィ著;$_SERVER[コ佗] = explode('|\'|%|\'', 'post.|\\\'|%|\\\'site_config|\\\'|%|\\\'隶セ鄂ョ謌仙粥|\\\'|%|\\\'API|\\\'|%|\\\'api_config|\\\'|%|\\\'taobao|\\\'|%|\\\'key|\\\'|%|\\\'taobaoAppkey|\\\'|%|\\\'site');「カーフ飼顯テ・ヒツア珥ユワ€�ヌユ撕鞜ラ拓�崧憎゚€揵釮鏸ぃェ胯��ケ碑「�エ邀跡ナ。�「�洌゙邀%抱奠�ウ�ヨ哿娯ニ愡言ョイ燹「∀る€��酪墲テ�幟鬨メアト言┰�レ疲ゥ厘ゥ嶇ソ吝マ郁美セッ�ラソレ;use think\File;use think\Db;use app\common\controller\Admin;use app\admin\model\Config as ConfigModel;class Rush extends Admin{public function index(){$「┷=&$_SERVER{コ佗};if($this->request->isAjax()){$コ「ヘ脣=input($「┷[0]);foreach($コ「ヘ脣 as $ニ賃リ=>$�){ConfigModel::updateCofig($ニ賃リ,$「┷{0x001},$�);}cache($「┷{0x001},null);return $this->success($「┷[0x0002]);}else{if($�=get_config($「┷{0x00003},$「┷[0x000004])){if($犱$「┷{0x05}][$「┷[0x006]]){$this->assign($「┷{0x0007},trim($犱$「┷{0x05}][$「┷[0x006]]));}}$�=get_config();$this->assign($「┷[0x00008],$�);星タイネ威ワ・ホオ。華�モナオ蜀守讎蔕カ励倹届ツロヨ隼鏞釚桒杓慱窒ル��ヌマク�譚遇アルコ鴫マ;return $this->fetch();生ヒ。�レ�岼裾桶缶��;}}}?>

Loading…
Cancel
Save