PHP 用zip函数操作crx文件和如何获取crx文件的唯一标识crx_id

PHP 用zip函数操作crx文件和如何获取crx文件的唯一标识crx_id

作者:admin |  时间:2014-04-27 |  浏览:1042 |  0 条评论

crx文件(浏览器扩展)是一种特殊的zip包,头部包含306个字节的特殊信息。用zip操作分析crx文件,需要将头部的306个字节去掉,将剩下的字节重新包窜到另一个zip文件中,接下来就可以用zip函数对其进行操作了。

<?php
$dir = dirname(__FILE__);
$fname1 = $dir."\piao_2.0.0.15.crx";
$stream = fopen($fname1, 'rb');
$content = stream_get_contents($stream, -1, 306);
$fname = $dir."\crx.zip";
file_put_contents($fname, $content);
$zip = zip_open($fname);
$dll_arr = array();
$manifest_arr = array();
if(is_resource($zip) ) {
     while($zip_entry = zip_read($zip)) {
          $entry_name = zip_entry_name( $zip_entry );
          if(preg_match('/\.dll$/', $entry_name)) {
             $dll_arr[] =  $entry_name;
          } else if(preg_match('/manifest\.json$/', $entry_name)) {
             $content = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
             $content_j = json_decode($content, true);
             if(!empty($content_j)) {
                $manifest_arr[] = $content_j;
             }
          }
     }
}
var_dump($dll_arr, $manifest_arr);
?>

如何获取crx文件的标识crx_id

<?php
class crx_parser_exception extends Exception {
    
}

/**
* Chrome crx 解析器,用于获取扩展、皮肤ID
*
*/
class crx_parser {
     const MAX_PUBLIC_KEY_SIZE = 65535;
     const MAX_SIGNATURE_SIZE  = 65535;
     const HEADER_MAGIC_PREFIX = 'Cr24';
     const CURRENT_VERSION     = 2;
    
     private $_crx_file = null;
     /**
     * 开始解析该 crx 文件
     */
     public function parse($crx_file) {
          if(substr($crx_file,0,'4') != 'http' && !file_exists($crx_file)) {
               throw new crx_parser_exception("parser init: crx file does not exisit");
          }
          $this->_crx_file = fopen($crx_file, 'r');
          $this->parse_header(); // 解析头部信息
          $this->parse_key();
          fclose($this->_crx_file);
          return $this->get_crx_id();
     }
     /**
     * crx 文件的头信息
     * @var unknown_type
     */
     private $_header = array();
     /**
     * 解析头部信息,并设置 $_header 数组
     * @throws crx_parser_exception 解析错误抛出异常
     */
     private function parse_header() {
          $data = fread($this->_crx_file, 16); // HEADER 头信息有16个字节
          if($data) {
               $data = @unpack('C4prefix/Vversion/Vkey_size/Vsig_size',$data);
          }else{
               throw new crx_parser_exception("header parse: error reading header");
          }
          // 前四个字节拼合 prefix
          $data['prefix'] = chr( $data['prefix1'] ).chr( $data['prefix2'] ).chr( $data['prefix3'] ).chr( $data['prefix4'] );
          unset($data['prefix1'],$data['prefix2'],$data['prefix3'],$data['prefix4']);
         
          if($data['prefix'] != self::HEADER_MAGIC_PREFIX) {
               throw new crx_parser_exception("header parse: illegal prefix");
          }
          if( $data['version'] != self::CURRENT_VERSION ) {
               throw new crx_parser_exception("header parse: illegal version");
          }
          if(
               empty($data['key_size']) || $data['key_size'] > self::MAX_PUBLIC_KEY_SIZE ||
               empty($data['sig_size']) || $data['sig_size'] > self::MAX_SIGNATURE_SIZE
          ){
               throw new crx_parser_exception("header parse: illegal public key size or signature size");
          }
          $this->_header = $data;
     }
     private function parse_key() {
          $key = fread($this->_crx_file,$this->_header['key_size']);
          if($key) {
               $this->_key = $key;
          }else{
               throw new crx_parser_exception("key parse: error reading key");
          }
     }
     private function get_crx_id() {
          $hash = hash('sha256',$this->_key);
          $hash = substr($hash,0,32);
         
          $length = strlen($hash);
          $ascii_0 = ord('0');
          $ascii_9 = ord('9');
          $ascii_a = ord('a');
          $data = '';
          for($i=0;$i<$length;$i++) {
               $c = ord($hash[$i]);
              
               if($c >= $ascii_0 && $c <= $ascii_9) {
                    $d = chr($ascii_a + $c - $ascii_0);
               } else if($c >= $ascii_a && $c < $ascii_a + 6) {
                    $d = chr($ascii_a + $c - $ascii_a + 10);
               } else {
                    $d = 'a';
               }
               $data .= $d;
          }
          return $data;
     }
}

发表评论

电子邮件地址不会被公开。

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>