是否有可能从SWF文件中使用PHP内部取出动作? [英] Is it possible to remove actionScript from inside of SWF file using PHP?

查看:266
本文介绍了是否有可能从SWF文件中使用PHP内部取出动作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

结果应该是洁净的SWF文件。

The result should be clean SWF file.

推荐答案

当然,其可能的,但你必须要读取的文件数据,并了解文件的结构,知道哪里有动作的存储。

Of course its possible, but you would have to read the file data and understand the structure of the file to know where the actionscript's are stored.

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

you can use PHP native functions such as

  • 的fopen
  • fseak
  • FREAD
  • flcose

随着其他二进制工具,如

Along with other binary tools such as

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

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

To manipulate binary data, I suggest you start with the link below to understand the complexity of this:

<一个href="http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/swf/pdf/swf_file_format_spec_v10.pdf" rel="nofollow">http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/swf/pdf/swf_file_format_spec_v10.pdf

下面是一个pretty的基本类,它可以让你从一个SWF读取数据或COM pressed SWF文件:

Here's a pretty basic class that allows you to read data from a SWF or Compressed SWF File:

/**
* 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 <alessandro@sephiroth.it>
* @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

这篇关于是否有可能从SWF文件中使用PHP内部取出动作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆