成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

Swoole Compiler 加密 Drupal 產(chǎn)生的一些問(wèn)題

source / 2272人閱讀

摘要:第行通過(guò)類(lèi)提供的方法分別獲取本類(lèi)和父類(lèi)中的屬性,然后進(jìn)行對(duì)比剔除父類(lèi)的屬性,保留本類(lèi)的屬性,此方法返回的是一個(gè)類(lèi)對(duì)象。

前言

上個(gè)星期碰到個(gè)客戶(hù)使用Swoole Compiler加密Drupal導(dǎo)致Drupal項(xiàng)目無(wú)法運(yùn)行的問(wèn)題,逐步排查后總結(jié)問(wèn)題是Drupal中有部分代碼直接通過(guò)file_get_contents獲取PHP源碼導(dǎo)致的,因?yàn)轫?xiàng)目代碼是加密過(guò)后的,所以直接獲取PHP源碼解析是獲取不到想要的內(nèi)容的。
注:

Swoole Compiler:https://www.swoole-cloud.com/compiler.html

Drupal是使用PHP語(yǔ)言編寫(xiě)的開(kāi)源內(nèi)容管理框架(CMF),它由內(nèi)容管理系統(tǒng)(CMS)和PHP開(kāi)發(fā)框架(Framework)共同構(gòu)成。

加密后的影響Drupal運(yùn)行的主要代碼 代碼路徑

drupal/vendor/doctrine/common/lib/Doctrine/Common/Reflection/StaticReflectionParser.php:126

    //代碼內(nèi)容
    protected function parse()
    {
        if ($this->parsed || !$fileName = $this->finder->findFile($this->className)) {
            return;
        }
        $this->parsed = true;
        $contents = file_get_contents($fileName);
        if ($this->classAnnotationOptimize) {
            if (preg_match("/A.*^s*((abstract|final)s+)?classs+{$this->shortClassName}s+/sm", $contents, $matches)) {
                $contents = $matches[0];
            }
        }
        $tokenParser = new TokenParser($contents);
        ......
    }

其中部分代碼如上,通過(guò)class名獲取文件路徑,然后通過(guò)file_get_contents獲取PHP文件的內(nèi)容,其中TokenParser類(lèi)中構(gòu)造函數(shù)如下

    public function __construct($contents)
    {
         $this->tokens = token_get_all($contents);
         token_get_all("numTokens = count($this->tokens);
    }

傳入獲取到的源碼通過(guò)token_get_all進(jìn)行解析,然后后續(xù)分析代碼獲取PHP文件的類(lèi)、屬性、方法的注釋 ,父類(lèi)的命名空間 和class名 ,本類(lèi)的use信息等,因?yàn)槲募呀?jīng)加密,所以file_get_contents獲取到的內(nèi)容是加密后的內(nèi)容,token_get_all就解析不到正確的信息,從而導(dǎo)致程序無(wú)法運(yùn)行。

解決方案
本次使用的2.1.1版本的加密器,通過(guò)Swoole Compiler加密器加密的代碼,在配置文件中save_doc配置選項(xiàng)必須設(shè)置為1,如果設(shè)置為0則不會(huì)保存注釋?zhuān)⑶以?b>2.1.3版本swoole_loader.so擴(kuò)展中新增加的函數(shù)naloinwenraswwww也無(wú)法獲取到類(lèi)中use的相關(guān)信息,具體函數(shù)使用在后面會(huì)詳細(xì)說(shuō)明。
  1    $ref = new ReflectionClass($this->className);
  2
  3    $parent_ref = $ref->getParentClass();
  4
  5    ......
  6
  7    if (is_file($fileName)) {
  8        $php_file_info = unserialize(naloinwenraswwww(realpath($fileName)));
  9        foreach ($php_file_info as $key => $info) {
  10           if ($key == "swoole_namespaces" || $key == "swoole_class_name") {
  11               continue;
  12           }
  13           $this->useStatements[$key] = $info;
  14       }
  15   }
  16
  17   $this->parentClassName = $parent_ref->getName();
  18
  19   if (strpos($this->parentClassName, "")!==0) {
  20       $this->parentClassName = "".$this->parentClassName;
  21   }
  22
  23   $static_properties = [];
  24
  25   $properties = $ref->getProperties();
  26
  27   $parent_properties = $this->createNewArrKey($parent_ref->getProperties());
  28
  29   ......
  30
  31   $static_methods = [];
  32
  33   $methods = $ref->getMethods();
  34
  35   ......

第1行通過(guò)類(lèi)名來(lái)獲取反射類(lèi)ReflectionClass類(lèi)的對(duì)象。

因?yàn)榇朔瓷漕?lèi)包含了所有父類(lèi)中的屬性和方法,但源碼中只要獲取本類(lèi)中的屬性和方法,所以還要獲取父類(lèi)的反射類(lèi)然后通過(guò)對(duì)比來(lái)剔除父類(lèi)中的屬性和方法,第3行使用ReflectionClass類(lèi)提供的getParentClass方法獲取父類(lèi)的反射類(lèi),此方法返回父類(lèi)的ReflectionClass對(duì)象。

第25行通過(guò)ReflectionClass類(lèi)提供的getProperties方法分別獲取本類(lèi)和父類(lèi)中的屬性,然后進(jìn)行對(duì)比剔除父類(lèi)的屬性,保留本類(lèi)的屬性,此方法返回的是一個(gè)ReflectionProperty類(lèi)對(duì)象。

通過(guò)ReflectionProperty類(lèi)提供的getDocComment方法就可以拿到屬性的注釋。

同上第33行通過(guò)ReflectionClass類(lèi)提供的getMethods方法可以拿到本類(lèi)和父類(lèi)中的方法,然后進(jìn)行對(duì)比剔除父類(lèi)的方法,保留本類(lèi)的方法,此方法返回的是一個(gè)ReflectionMethod類(lèi)對(duì)象。

通過(guò)ReflectionMethod對(duì)象提供的getDocComment方法就可以拿到方法的注釋。

通過(guò)第17行ReflectionClass提供的getName方法可以拿到類(lèi)名。

因?yàn)榉瓷錈o(wú)法獲取use類(lèi)的信息,所以在2.1.3版本中的swoole_loader.so擴(kuò)展中添加函數(shù)naloinwenraswwww,此函數(shù)傳入一個(gè)PHP文件的絕對(duì)路徑,返回傳入文件的相關(guān)信息的序列化數(shù)組,反序列化后數(shù)組如下
    [
        "swoole_namespaces" => "DrupalCoreDatetimeElement",
        "swoole_class_name" => "DrupalCoreDatetimeElementDateElementBase",
        "nestedarray" => "DrupalComponentUtilityNestedArray",
        "drupaldatetime" => "DrupalCoreDatetimeDrupalDateTime",
        "formelement"=> "DrupalCoreRenderElementFormElement"
    ]

其中swoole_namespaces為文件的命名空間,swoole_class_name為文件的命名空間加類(lèi)名,其他為use信息,鍵為use類(lèi)的類(lèi)名小寫(xiě)字母,如存在別名則為別名的小寫(xiě)字母,值為use類(lèi)的命名空間加類(lèi)名,通過(guò)該函數(shù)和反射函數(shù)可以兼容StaticReflectionParser中加密后出現(xiàn)的無(wú)法獲取正確信息的問(wèn)題

在加密后的未影響Drupal運(yùn)行的潛在問(wèn)題:

代碼路徑:drupal/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/PhpParser.php:39

代碼路徑:drupal/vendor/symfony/class-loader/ClassMapGenerator.php:91

代碼路徑:drupal/vendor/symfony/routing/Loader/AnnotationFileLoader.php:90

Drupal中引入了Symfony框架,此框架中部分代碼也是通過(guò)file_get_contentstoken_get_all來(lái)獲取PHP文件的類(lèi)名,但目前未對(duì)Druapl運(yùn)行產(chǎn)生影響,可能并未用到其中方法
解決方案:

StaticReflectionParser類(lèi)的解決方案一樣通過(guò)2.1.3版本中的swoole_loader.so擴(kuò)展中添加函數(shù)naloinwenraswwww來(lái)獲取加密后文件的命名空間和類(lèi)名

尚未有更好方案的問(wèn)題:

代碼路徑:drupal/core/includes/install.inc:220

    function drupal_rewrite_settings($settings = [], $settings_file = NULL)
    {
        if (!isset($settings_file)) {
            $settings_file = Drupal::service("site.path") . "/settings.php";
        }
        // Build list of setting names and insert the values into the global namespace.
        $variable_names = [];
        $settings_settings = [];
        foreach ($settings as $setting => $data) {
            if ($setting != "settings") {
                _drupal_rewrite_settings_global($GLOBALS[$setting], $data);
            } else {
                _drupal_rewrite_settings_global($settings_settings, $data);
            }
            $variable_names["$" . $setting] = $setting;
        }
        $contents = file_get_contents($settings_file);
        if ($contents !== FALSE) {
            // Initialize the contents for the settings.php file if it is empty.
            if (trim($contents) === "") {
                $contents = " $setting) {
                $buffer .= _drupal_rewrite_settings_dump($setting, "$" . $name);
            }

            // Write the new settings file.
            if (file_put_contents($settings_file, $buffer) === FALSE) {
                throw new Exception(t("Failed to modify %settings. Verify the file permissions.", ["%settings" => $settings_file]));
            } else {
                // In case any $settings variables were written, import them into the
                // Settings singleton.
                if (!empty($settings_settings)) {
                    $old_settings = Settings::getAll();
                    new Settings($settings_settings + $old_settings);
                }
                // The existing settings.php file might have been included already. In
                // case an opcode cache is enabled, the rewritten contents of the file
                // will not be reflected in this process. Ensure to invalidate the file
                // in case an opcode cache is enabled.
                OpCodeCache::invalidate(DRUPAL_ROOT . "/" . $settings_file);
            }
        } else {
            throw new Exception(t("Failed to open %settings. Verify the file permissions.", ["%settings" => $settings_file]));
        }
    }

Drupal安裝過(guò)程中有個(gè)配置文件default.setting.php,里面存放了默認(rèn)配置數(shù)組,在安裝的過(guò)程中會(huì)讓用戶(hù)在安裝界面輸入一些配置比如Mysql的信息,輸入過(guò)后此方法通過(guò)file_get_contentstoken_get_all來(lái)獲取setting中的信息,然后合并用戶(hù)在頁(yè)面輸入的信息,重新存回文件,因?yàn)檎麄€(gè)過(guò)程涉及到讀取文件,更改文件信息,在存入文件,所以Swoole Compiler在此處暫時(shí)沒(méi)有更好的解決方案,需要在加密的時(shí)候選擇不加密setting文件。

代碼路徑:drupal/vendor/symfony/class-loader/ClassCollectionLoader.php:126
此類(lèi)中是Symfony讀取PHP文件然后作相應(yīng)處理后緩存到文件中,存在和上面代碼同樣的問(wèn)題,暫未找到更好的解決方案

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/31592.html

相關(guān)文章

  • swoole compiler加密drupal產(chǎn)生一些問(wèn)題

    摘要:通過(guò)類(lèi)提供的方法分別獲取本類(lèi)和父類(lèi)中的屬性,然后進(jìn)行對(duì)比剔除父類(lèi)的屬性,保留本類(lèi)的屬性,此方法返回的是一個(gè)類(lèi)對(duì)象。 問(wèn)題描述 上個(gè)星期碰到個(gè)客戶(hù)使用swoole compiler加密drupal導(dǎo)致drupal項(xiàng)目無(wú)法運(yùn)行的問(wèn)題,逐步排查后總結(jié)問(wèn)題是drupal中有部分代碼直接通過(guò)file_get_contents獲取php源碼導(dǎo)致的,因?yàn)轫?xiàng)目代碼是加密過(guò)后的,所以直接獲取php源碼解...

    frolc 評(píng)論0 收藏0
  • 4 個(gè)常用 HTTP 安全頭部

    摘要:偏巧的是重定向的過(guò)程會(huì)給黑客提供中間人攻擊。在上例的情況下,從發(fā)送頭部到得到響應(yīng),有效性可保持年。它認(rèn)為這個(gè)頭部可以預(yù)防偽造跨站請(qǐng)求??偨Y(jié)使用以上頭部可幫你快速容易地預(yù)防攻擊點(diǎn)擊挾持攻擊嗅探和中間人攻擊。請(qǐng)確保用戶(hù)的安全性。 它曾是世界性圖書(shū)館夢(mèng)的開(kāi)始,現(xiàn)在它是全球知識(shí)的聚集地,它是目前最流行的,人們將應(yīng)用都部署之上的萬(wàn)維網(wǎng)。 它是敏捷的代表,它不是單一的實(shí)體,它由客戶(hù)端和服務(wù)端組成...

    beita 評(píng)論0 收藏0
  • Swoole 源碼分析——Server模塊之OpenSSL (上)

    摘要:另一方比如小明得到公鑰之后,雙方就可以通信。然而,中間人還是可能截獲公鑰,然后自己弄一對(duì)秘鑰,然后告訴小明說(shuō)是小紅的公鑰。這樣,小亮在簽署小紅的身份證的時(shí)候,可以在小紅身份證后面附上自己的身份證。一般來(lái)說(shuō),自簽名的根身份證用于公司內(nèi)部使用。 前言 自從 Lets Encrypt 上線之后,HTTPS 網(wǎng)站數(shù)量占比越來(lái)越高,相信不久的未來(lái)就可以實(shí)現(xiàn)全網(wǎng) HTTPS,大部分主流瀏覽器也對(duì) ...

    ky0ncheng 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<