初识PHP-Parser

title: 初识PHP-Parser
date: 2020-9-13 03:11:21
categories:

  • PHP-Parser
    tags:
  • PHP-Parser
  • web
  • php
    toc: true

PHP-Parser 用于代码混淆的代码

learn from

http://j0k3r.top/2020/03/24/php-Deobfuscator/#0x01-php-parser

https://github.com/nikic/PHP-Parser/tree/master/doc

下载

curl -s http://getcomposer.org/installer | php

遇到权限问题时,可以输入一下命令

sudo chown -R 'user-name' /home/'user-name'/.composer

之后再在所需项目中php composer.phar require nikic/php-parser

为了更方便调用composer,可以输入一下命令

mv composer.phar /usr/local/bin/composer

如果composer require nikic/php-parse遇到长时间卡住,可以尝试更新源

composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/

项目: https://github.com/nikic/PHP-Parser

runoob 再次好用

生成AST

首先介绍一下PHP-Parser中定义的一些节点类型:

(1)PhpParser\Node\Stmt是语句节点,不带任何返回信息(return)的结构,如赋值语句”$a = $b” ;

(2)PhpParser\Node\Expr是表达式节点,可以返回一个值的语言结构,如$var和func()。

(3)PhpParser\Node\Scalar是常量节点,可以用来表示任何常量值。如’string’,0,以及常量表达式。

(4)还有一些节点没有包括进去,如参数节点(PhpParser\Node\Arg)。

一些节点类的名称使用了下划线,这是为了避免和PHP关键字冲突。

PHP-parser的test.php下,该代码片段会生成AST

<?php
use PhpParser\Error;
use PhpParser\ParserFactory;
require dirname(__FILE__).'/vendor/autoload.php';  #composer require nikic/php-parse 成功后会生成这个文件,当然还有其他的文件
$code = <<<'CODE'
<?php

echo 'Hello PHP';
CODE;

$parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);// 优先解析 PHP7 代码

try {
    $stmts = $parser->parse($code);//使用 ParserFactory 的 parse 方法解析代码,得到一个 statement 节点数组
    var_dump($stmts);
} catch (Error $e) {
    echo 'Parse Error: ', $e->getMessage();//语法错误可以通过 PhpParser\Error 来捕获
}

output:

/home/fe1w0/babyshop/ttt.php:15:
array(1) {
  [0] =>
  class PhpParser\Node\Stmt\Echo_#1131 (2) {
    public $exprs =>
    array(1) {
      [0] =>
      class PhpParser\Node\Scalar\String_#1130 (2) {
        ...
      }
    }
    protected $attributes =>
    array(2) {
      'startLine' =>
      int(3)
      'endLine' =>
      int(3)
    }
  }
}

使用 NodeDumper来查看

<?php
use PhpParser\Error;
use PhpParser\ParserFactory;
use PhpParser\NodeDumper;
require dirname(__FILE__).'/vendor/autoload.php';  #composer require nikic/php-parse 成功后会生成这个文件,当然还有其他的文件
$code = <<<'CODE'
<?php

echo 'Hello PHP';
CODE;

$parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);// 优先解析 PHP7 代码

try {
    $stmts = $parser->parse($code);//使用 ParserFactory 的 parse 方法解析代码,得到一个 statement 节点数组
    $nodeDumper = new NodeDumper;
    echo $nodeDumper->dump($stmts), "\n";
    #var_dump($stmts);
} catch (Error $e) {
    echo 'Parse Error: ', $e->getMessage();//语法错误可以通过 PhpParser\Error 来捕获
}

output:

array(
    0: Stmt_Echo(
        exprs: array(
            0: Scalar_String(
                value: Hello PHP
            )
        )
    )
)

修改节点值 将Hello PHP改为Hello world

<?php
use PhpParser\Error;
use PhpParser\ParserFactory;
use PhpParser\NodeDumper;
use PhpParser\NodeTraverser;
use PhpParser\Node;
use PhpParser\NodeVisitorAbstract;
use PhpParser\PrettyPrinter;

require dirname(__FILE__).'/vendor/autoload.php';

$code = <<<'CODE'
<?php

echo 'Hello PHP';

CODE;

class MyNodeVisitor extends NodeVisitorAbstract
{
    public function leaveNode(Node $node) {
        if ($node instanceof Node\Scalar\String_) {
            $node->value = 'Hello Word';
        }
    }
}

class PrintNodeVisitor extends NodeVisitorAbstract
{
    public function leaveNode(Node $node) {
        if ($node instanceof Node\Stmt\Echo_) {
            return new PhpParser\Node\Stmt\Expression( new Node\Expr\Print_(new Node\Scalar\String_(($node->exprs)[0]->value)) );
        }
    }
}

$parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);

try {
    $stmts = $parser->parse($code);
    $traverser = new NodeTraverser;
    // 添加 node visitors
    $traverser->addVisitor(new MyNodeVisitor);
    $traverser->addVisitor(new PrintNodeVisitor);
    // 遍历 AST
    $new_stmts = $traverser->traverse($stmts);
    // 将 AST 转为 PHP 代码
    $prettyPrinter = new PrettyPrinter\Standard;
    $new_code = $prettyPrinter->prettyPrintFile($new_stmts);
    echo $code.PHP_EOL;
    echo "--After parser:--\n\n".$new_code;

} catch (Error $e) {
    echo 'Parse Error: ', $e->getMessage();
}

解混淆[缺失ing]

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇