是否可以使用PHP从SWF文件中删除actionScript?

问题描述:

结果应该是clean SWF文件。是否可以使用PHP从SWF文件中删除actionScript?

当然可能,但您必须阅读文件数据并了解文件的结构才能知道动作的存储位置。

你可以使用PHP自身的功能,如

  • 的fopen
  • fseak
  • FREAD
  • flcose

随着其他二进制工具,如

  • < <,|,>>,&和其他二进制操作工具

要处理的二进制数据,我建议你先从下面的链接了解复杂这个:

http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/swf/pdf/swf_file_format_spec_v10.pdf

这里是一个非常基本的T类帽子可以让你从一个SWF文件或压缩的SWF文件中读取数据:

/** 
* Base SWF class 
* 
* This class requires the File PEAR. 
* Read the SWF header informations and return an 
* associative array with the property of the SWF File, the result array 
* will contain framerate, framecount, background color, compression, filetype 
* version and movie size. 
* <code> 
* <?php 
* require_once "File/File_SWF.php"; 
* $file = "any_file.swf"; 
* 
* $swf = &new File_SWF($file); 
* if($swf->isValid){ 
* $result = $swf->stat(); 
* print_r($result); 
* } 
* <? 
* </code> 
* @author Alessandro Crugnola <[email protected]> 
* @access public 
* @version 0.2 
* @package File_SWF 
*/ 
class File_SWF 
{ 
    /** 
    * current unpacked binary string 
    * @var mixed 
    */ 
    var $current = ""; 
    /** 
    * internal pointer 
    * @var integer 
    */ 
    var $position = 0; 
    /** 
    * use zlib compression 
    * @var boolean 
    */ 
    var $compression = 0; 
    /** 
    * current position 
    * @var integer 
    */ 
    var $point = 0; 
    /** 
    * is a valid swf 
    * @var boolean 
    * @access private 
    */ 
    var $isValid = 0; 
    /** 
    * stirng file name to parse 
    * @var string 
    */ 
    var $file = ""; 
    /** 
    * determine if file is protected 
    * @var boolean 
    */ 
    var $protected = false; 
    /** 
    * password for protected files 
    * @var mixed 
    */ 
    var $password; 

    /** 
    * Deconstructor 
    * does anything right now 
    * @access public 
    */ 
    function _File_SWF() 
    { 
    } 

    /** 
    * Costructor 
    * creates a new SWF object 
    * reads the given file and parse it 
    * @param string $file file to parse 
    * @access public 
    */ 
    function File_SWF($file="") 
    { 
     $this->compression = 0; 
     $this->isValid = 0; 
     $this->point = 0; 
     $this->file = $file; 
     $head = File::read($this->file, 3); 
     if(PEAR::isError($head)){ 
      return $head; 
     } 
     File::rewind($this->file, "rb"); 
     if($head == "CWS"){ 
      $data = File::read($this->file, 8); 
      $_data = gzuncompress(File::read($this->file, filesize($this->file))); 
      $data = $data . $_data; 
      $this->data = $data; 
      $this->compression = 1; 
      $this->isValid = 1; 
     } else if ($head == "FWS"){ 
      $this->data = File::read($this->file, filesize($this->file)); 
      $this->isValid = 1; 
     } else { 
      /** 
      * invalid SWF file, or invalid head tag found 
      */ 
      $this->isValid = 0; 
     } 
     File::close($this->file, "rb"); 
    } 

    /** 
    * Is a valid SWF file 
    * @return boolean 
    * @access public 
    */ 
    function is_valid() 
    { 
     return $this->isValid; 
    } 

    /** 
    * Return if swf file is protected from import 
    * @return boolean 
    * @access public 
    */ 
    function getProtected() 
    { 
     if($this->getVersion() >= 8){ 
      $this->_seek(31); 
     } else { 
      $this->_seek(26); 
     } 
     $data = $this->_readTag(); 
     $tag = $data[0]; 
     $this->protected = $tag == 24; 
     return $this->protected; 
    } 

    /** 
    * Define import protection for the SWF 
    * @param boolean $protect define is file must be protected 
    * @access public 
    */ 
    function setProtected($protect) 
    { 
     if($protect and !$this->protected){ 
      if($this->getVersion() >= 8){ 
       $pre = substr($this->data, 0, 31); 
       $post = substr($this->data, 31); 
      } else { 
       $pre = substr($this->data, 0, 26); 
       $post = substr($this->data, 26); 
      } 
      $middle = pack("v", 1536); 
      $this->data = $pre . $middle . $post; 
      $this->password = 0; 
      $this->protected = true; 
     } else if(!$protect and $this->protected){ 
      if($this->getVersion() >= 8){ 
       $pos = 31; 
      } else { 
       $pos = 26; 
      } 
      $this->_seek($pos); 
      if($this->_readData()){ 
       $this->data = substr($this->data,0, $pos) . substr($this->data, $this->point - (is_string($this->password) == 1 ? 0 : 1)); 
      } 
     } 
    } 

    /** 
    * Return the current SWF frame rate 
    * @return mixed integer frame rate in fps or Error if invalid file 
    * @access public 
    */ 
    function getFrameRate() 
    { 
     if(!$this->is_valid()){ 
      return PEAR::raiseError("Invalid SWF head TAG found in " . $this->file, PEAR_SWF_ID_ERR); 
     } 
     if($this->getVersion() >= 8){ 
      $this->_seek(16); 
     } else { 
      $this->_seek(17); 
     } 
     $fps = unpack('vrate',$this->_read(2)); 
     return $fps['rate']/256; 
    } 

    /** 
    * Set the new Frame Rate 
    * @access public 
    */ 
    function setFrameRate($num) 
    { 
     if(!$this->is_valid()){ 
      return; 
     } 
     $num = intval($num); 
     if($num > 0 and $num <= 120){ 
      $fps = pack('v', $num*256); 
      if($this->getVersion() >= 8){ 
       $this->_seek(16); 
       $this->data = substr($this->data, 0, 16) . $fps . substr($this->data, 18); 
      } else { 
       $this->_seek(17); 
       $this->data = substr($this->data, 0, 17) . $fps . substr($this->data, 19); 
      } 
     } 
    } 

    /** 
    * Return the current number of frames 
    * @return mixed interger or error if invalid file format 
    * @access public 
    */ 
    function getFrameCount() 
    { 
     if(!$this->is_valid()){ 
      return PEAR::raiseError("Invalid SWF head TAG found in " . $this->file, PEAR_SWF_ID_ERR); 
     } 
     if($this->getVersion() >= 8){ 
      $this->_seek(18); 
     } else { 
      $this->_seek(19); 
     } 
     return $this->_readshort(); 
    } 

    /** 
    * Return the current movie size in pixel 
    * @return mixed array or error if invalid file format 
    * @access public 
    */ 
    function getMovieSize() 
    { 
     if(!$this->is_valid()){ 
      return PEAR::raiseError("Invalid SWF head TAG found in " . $this->file, PEAR_SWF_ID_ERR); 
     } 
     $this->_seek(8); 
     return $this->_readRect(); 
    } 

    /** 
    * Return the current file type (CWS, FWS) 
    * @return mixed string or error if invalid file format 
    * @access public 
    */ 
    function getFileType() 
    { 
     if(!$this->is_valid()){ 
      return PEAR::raiseError("Invalid SWF head TAG found in " . $this->file, PEAR_SWF_ID_ERR); 
     } 
     $this->_seek(0); 
     return $this->_read(3); 
    } 

    /** 
    * Return the current compression used 
    * @return mixed interger or error if invalid file format 
    * @access public 
    */ 
    function getCompression() 
    { 
     if(!$this->is_valid()){ 
      return PEAR::raiseError("Invalid SWF head TAG found in " . $this->file, PEAR_SWF_ID_ERR); 
     } 
     return $this->compression; 
    } 

    /** 
    * Set the compression 
    * @return string based on the compression used 
    * @param integer $mode compression on/off 
    * @access public 
    */ 
    function setCompression($mode = 0) 
    { 
     if(!$this->is_valid()){ 
      return; 
     } 
     $data = ""; 
     $real_size = pack("V", strlen($this->data)); 
     $this->data = substr($this->data, 0, 4) . $real_size . substr($this->data, 8, strlen($this->data)); 
     if($mode == 0){ 
      $this->compression = 0; 
      $this->data = "FWS" . substr($this->data, 3); 
      $_n1 = substr($this->data, 0, 8); 
      $_n2 = substr($this->data, 8, strlen($this->data)); 
      $data = $_n1 . $_n2; 
     } else if($mode == 1){ 
      $this->compression = 1; 
      $this->data = "CWS" . substr($this->data, 3); 
      $_n1 = substr($this->data, 0, 8); 
      $_n2 = substr($this->data, 8, strlen($this->data)); 
      $_n3 = gzcompress($_n2); 
      $data = $_n1 . $_n3; 
     } 
     return $data; 
    } 

    /** 
    * Return the current version of player used 
    * @return mixed interger or error if invalid file format 
    * @access public 
    */ 
    function getVersion() 
    { 
     if(!$this->is_valid()){ 
      return PEAR::raiseError("Invalid SWF head TAG found in " . $this->file, PEAR_SWF_ID_ERR); 
     } 
     $this->_seek(3); 
     return $this->_readbyte(); 
    } 

    /** 
    * Return the current SWF file size 
    * @return mixed interger or error if invalid file format 
    * @access public 
    */ 
    function filesize() 
    { 
     if(!$this->is_valid()){ 
      return PEAR::raiseError("Invalid SWF head TAG found in " . $this->file, PEAR_SWF_ID_ERR); 
     } 
     $this->_seek(4); 
     $real_size = unpack("Vnum", $this->_read(4)); 
     if($this->getCompression()){ 
      $n = $this->data; 
      $n = "CWS" . substr($n, 3, 8) . gzcompress(substr($n, 8, strlen($n))); 
      $file_size = strlen($n) -3; 
     } else { 
      $file_size = strlen($this->data)-3; 
     } 
     return array($file_size, $real_size['num'], "compressed" => $file_size, "real" => $real_size['num']); 
    } 

    /** 
    * Return the current background color 
    * @return mixed array or error if invalid file format 
    * @access public 
    */ 
    function getBackgroundColor() 
    { 
     if(!$this->is_valid()){ 
      return PEAR::raiseError("Invalid SWF head TAG found in " . $this->file, PEAR_SWF_ID_ERR); 
     } 
     if($this->getVersion() >= 8){ 
      $this->_seek(26); 
     } else { 
      $this->_seek(21); 
     } 
     return $this->_readData(); 
    } 

    /** 
    * Set the new background color 
    * @param integer $r (0,255) 
    * @param integer $g (0,255) 
    * @param integer $b (0,255) 
    * @access public 
    */ 
    function setBackgroundColor($r=0, $g=0, $b=0) 
    { 
     if(!$this->is_valid()){ 
      return; 
     } 
     $color = pack("C", $r); 
     $color .= pack("C", $g); 
     $color .= pack("C", $b); 

     if($this->getVersion() >= 8){ 
      $data = substr($this->data, 0, 28); 
      $data .= $color; 
      $this->data = $data . substr($this->data, 31, strlen($this->data)); 
     } else { 
      $data = substr($this->data, 0, 23); 
      $data .= $color; 
      $this->data = $data . substr($this->data, 26, strlen($this->data)); 
     } 
    } 

    /** 
    * Save current swf as a new file 
    * @param string $filename filename 
    * @param boolean $overwrite overwrite existing file 
    * @return boolean true if saved succesfully 
    * @access public 
    */ 
    function write($filename, $overwrite = 1) 
    { 
     if(!$this->is_valid()){ 
      return false; 
     } 
     if(is_writeable(dirname($filename))){ 
      if(is_file($filename)){ 
       if($overwrite == 0){ 
        return false; 
       } 
      } 
      $newdata = $this->setCompression($this->getCompression()); 
      File::write ($filename, $newdata, $mode = "wb"); 
      File::close($filename, "wb"); 
      return true; 
     } else { 
      return false; 
     } 
    } 

    /** 
    * reads the SWF header 
    * @return mixed associative array or error on fault 
    * @access private 
    */ 
    function stat() 
    { 
     if(!$this->is_valid()){ 
      return PEAR::raiseError("Invalid SWF head TAG found in " . $this->file, PEAR_SWF_ID_ERR); 
     } 
     $filetype = $this->getFileType(); 
     $version = $this->getVersion(); 
     $filelength = $this->filesize(); 
     $rect = $this->getMovieSize(); 
     $framerate = $this->getFrameRate(); 
     $framecount = $this->getFrameCount(); 
     $background = $this->getBackgroundColor(); 
     $protection = $this->getProtected(); 
     return array(
      "zlib-compression" => $this->getCompression(), 
      "fileType" => $filetype, 
      "version" => $version, 
      "fileSize" => $filelength, 
      "frameRate" => $framerate, 
      "frameCount" => $framecount, 
      "movieSize" => $rect, 
      "background" => $background, 
      "protected" => $protection, 
     ); 
    } 

    /** 
    * read tag type, tag length 
    * @return array 
    * @access private 
    */ 
    function _readTag() 
    { 
     $n = $this->_readshort(); 
     if($n == 0) 
     { 
      return false; 
     } 
     $tagn = $n>>6; 
     $length = $n&0x3F; 
     if($length == 0x3F) 
     { 
      $length = $this->_readlong(); 
     } 
     return array($tagn,$length); 
    } 

    /** 
    * read long 
    * @access private 
    */ 
    function _readlong(){ 
     $ret = unpack("Nnum", $this->_read(4)); 
     return $ret['num']; 
    } 

    /** 
    * read data of next tag 
    * @return array 
    * @access private 
    */ 
    function _readData() 
    { 
     $tag = $this->_readTag(); 
     $tagn = $tag[0]; 
     $length = $tag[1]; 
     if($tagn == 9) 
     { 
      $r = $this->_readbyte(); 
      $g = $this->_readbyte(); 
      $b = $this->_readbyte(); 
      $data = array($r,$g,$b, "hex" => sprintf("#%X%X%X", $r, $g, $b)); 
      return $data; 
     } else if($tagn == 24) 
     { 
      if($this->_readbyte() == 0x00){ 
       $this->_readbyte(); 
       $this->password = $this->_readstring(); 
      } else { 
       $this->password = 0; 
      } 
      return true; 
     } 
     return array(); 
    } 

    /** 
    * read a string 
    * @return string 
    * @access private 
    */ 
    function _readstring() 
    { 
     $s = ""; 
     while(true){ 
      $ch = $this->_read(1); 
      if($this->point > strlen($this->data)){ 
       break; 
      } 
      if($ch == "\x00"){ 
       break; 
      } 
      $s .= $ch; 
     } 
     return $s; 
    } 


    /** 
    * read internal data file 
    * @param integer $n number of byte to read 
    * @return array 
    * @access private 
    */ 
    function _read($n) 
    { 
     $ret = substr($this->data, $this->point, $n); 
     $this->point += $n; 
     return $ret; 
    } 

    /** 
    * move the internal pointer 
    * @param integer $num 
    * @access private 
    */ 
    function _seek($num){ 
     if($num < 0){ 
      $num = 0; 
     } else if($num > strlen($this->data)){ 
      $num = strlen($this->data); 
     } 
     $this->point = $num; 
    } 

    /** 
    * read short 
    * @return string 
    * @access private 
    */ 
    function _readshort(){ 
     $pack = unpack('vshort',$this->_read(2)); 
     return $pack['short']; 
    } 

    /** 
    * read single byte 
    * @return string 
    * @access private 
    */ 
    function _readByte(){ 
     $ret = unpack("Cbyte",$this->_read(1)); 
     return $ret['byte']; 
    } 
    /** 
    * read a rect type 
    * @return rect 
    * @access private 
    */ 
    function _readRect(){ 
     $this->_begin(); 
     $l = $this->_readbits(5); 
     $xmin = $this->_readbits($l)/20; 
     $xmax = $this->_readbits($l)/20; 
     $ymin = $this->_readbits($l)/20; 
     $ymax = $this->_readbits($l)/20; 
     $rect = array(
      $xmax, 
      $ymax, 
      "width" => $xmax, 
      "height" => $ymax 
     ); 
     return $rect; 
    } 

    /** 
    * read position internal to rect 
    * @access private 
    */ 
    function _incpos(){ 
     $this->position += 1; 
     if($this->position>8){ 
      $this->position = 1; 
      $this->current = $this->_readbyte(); 
     } 
    } 
    /** 
    * read bites 
    * @param integer $nbits number of bits to read 
    * @return string 
    * @access private 
    */ 
    function _readbits($nbits){ 
     $n = 0; 
     $r = 0; 
     while($n < $nbits){ 
      $r = ($r<<1) + $this->_getbits($this->position); 
      $this->_incpos(); 
      $n += 1; 
     } 
     return $r; 
    } 

    /** 
    * getbits 
    * @param integer $n 
    * @return long 
    * @access private 
    */ 
    function _getbits($n){ 
     return ($this->current>>(8-$n))&1; 
    } 

    /** 
    * begin reading of rect object 
    * @access private 
    */ 
    function _begin(){ 
     $this->current = $this->_readbyte(); 
     $this->position = 1; 
    } 
} 
?> 

来源:http://www.sephiroth.it/swfreader.php

+0

非常感谢!我会看看它。 – Zap 2011-05-06 12:31:20