码迷,mamicode.com
首页 > 其他好文 > 详细

SWF代码分析与破解之路 (YueTai VIP视频信息获取工具) Socket续篇

时间:2015-08-12 06:44:26      阅读:501      评论:0      收藏:0      [点我收藏+]

标签:actionscript   mywife.cc   福利图   破解   air   

引言

上一篇 《Socket与网站保密应用 (隐藏链接的视频下载)》大大咧咧地从 WEB 讲 Socket,再到 TCP/IP 等协议,又再讲到 Wireshark 如何抓IP包分析,最还要复习一下路由与网络的知识,真的涉及面太广了,只能蜻蜓点水一一带过,不过将多领域的知识串烧也是不错的,可以起到一个归纳的作用。这篇针对 Flash 来进行,写作思路以解决问题的过程行为线索。依次展示如何使用 Flex Air 的 ServerSocket 和 Socket 实现简化版本的 HTTP 服务器,以及如何加载外部的 SWF 文件并进行操作。

在 mplayer.swf 内部,使用 FlasCC 集成 C 代码做保护。使用了 Hessian 做对象序列化,Hessian是一个由Caucho Technology开发的轻量级二进制RPC协议。Hessian 自称为 binary web service protocol
,看来加了个 protocol 的都不简单了,好几个平台的版本都出来了。FlasCC 的加密部分似乎和 cmodule.usemd5 包下的 FSM_encode 这个类有关,这里截一片代码出来,看有没人了解一二:

    this.i2 = mstate.ebp + -96;
    this.i2 = this.i2 + 24;
    this.i11 = this.i2 + this.i12;
    this.i14 = this.i8;
    this.i15 = this.i13;
    memcpy(this.i11, this.i14, this.i15);
    mstate.esp = mstate.esp - 8;
    mstate.esp = mstate.esp - 4;
    this.start();
    mstate.esp = mstate.esp + 8;
    this.i2 = this.i13 + 64;

由于没有完全掌握 FlasCC ,所以没有深入,这里路过一下了,还是从 SWF 载入流程出发。通过调试得到,mvplayer 的执行是从这里开始的 com.yinyuetai.mvplayer.player.InPlayer > Player。抓主线,理清了 videoId 是如何和视频信息关联的,主要代码贴一贴,有点长,但这部分是最小功能 F**K CODE 之前,来两张AOA福利滋润一下各位看官:)。

技术分享技术分享

//com.yinyuetai.mvplayer.player.player extends Sprite implements IPlayer
    public function loadByVideoId(id:String) : void
    {
        var key:String = null;
        var url:String = null;
        var req:GetRequest = null;
        var cLoader:* = new CLibInit();
        var cLib:* = cLoader.init();
        var stamp:String = UTCDateCreator.utcfiveminute();
        key = cLib.encode(":" + id + ":" + stamp + ":" + PlayerVersion.version);
        // cLib.encode(":2344403:4797398:1.8.2.2") => ee4fb9b09346bd933dd22e37fe978741 32Byte
        var reg:RegExp = /^(http:\/\/.*?)\/.*/;
        if (ServiceConfig.GET_VIDEOINFO_URL.indexOf("http") >= 0)
        {
            url = ServiceConfig.GET_VIDEOINFO_URL;
        }
        else
        {
            url = RootReference.stage.loaderInfo.url.replace(reg, "$1") + ServiceConfig.GET_VIDEOINFO_URL;
        }
        req = new GetRequest(url);
        req.addEventListener(RequestEvent.RESPONSE, this.onAfterGetVideoInfo);
        req.doRequest({videoId:id, sc:key, t:stamp, v:PlayerVersion.version});
        // http://www.yinyuetai.com/main/get-mv-info?
        // flex=true&sc=ee4fb9b09346bd933dd22e37fe978741&t=4797398&v=1.8.2.2&videoId=2344403
        // Content-Type:binary/hessian; charset=UTF-8
        // data["videoInfo"] as MvSiteVideoInfo;
        return;
    }

    private function onAfterGetVideoInfo(event:RequestEvent) : void
    {
        var videoInfo:MvSiteVideoInfo = null;
        var coreVInfo:CoreVideoInfo = null;
        var pe:PlayerEvent = null;
        var evInfo:ExVideoInfo = null;
        var listItem:PlaylistItem = null;
        var o:Object = event.responseData;
        var isNOK:Boolean = o["error"] as Boolean;
        var msg:String = o["message"] as String;
        if (!isNOK)
        {
            videoInfo = o["videoInfo"] as MvSiteVideoInfo;
            coreVInfo = videoInfo.coreVideoInfo;
            if (coreVInfo.error)
            {
                pe = new PlayerEvent(PlayerEvent.MVPLAYER_ERROR, coreVInfo.errorMsg);
                dispatchEvent(pe);
            }
            else
            {
                evInfo = new ExVideoInfo(videoInfo);
                this.config.exVideoInfo = evInfo;
                listItem = new PlaylistItem();
                listItem.init(coreVInfo);
                this.load(listItem);
                this.model.config.setConfig(coreVInfo);
            }
        }
        else
        {
            pe = new PlayerEvent(PlayerEvent.MVPLAYER_ERROR, msg);
            dispatchEvent(pe);
        }
        return;
    }


//com.yinyuetai.mvplayer.model.ExVideoInfo extends Object
    public var pageUrl:String;
    public var headImage:String;
    public var bigHeadImage:String;

    public function ExVideoInfo(o:Object)
    {
        var reg:RegExp = /^(http:\/\/.*?)\/.*/;
        var srvURL:String = ServiceConfig.REMOTE_SERVER_URL;
        if (o.hasOwnProperty("bigHeadImage") && o["bigHeadImage"])
        {
            if (o["bigHeadImage"].indexOf("http") < 0)
            {
                this.bigHeadImage = (srvURL.indexOf("http") < 0 ? 
                    (RootReference.stage.loaderInfo.url.replace(reg, "$1")) : ("")) + 
                    srvURL + StringUtil.trim(o["bigHeadImage"]);
            }
            else
            {
                this.bigHeadImage = StringUtil.trim(o["bigHeadImage"]);
            }
        }
        if (o.hasOwnProperty("pageUrl") && o["pageUrl"])
        {
            this.pageUrl = o["pageUrl"].indexOf("http") < 0 ? 
                (srvURL + StringUtil.trim(o["pageUrl"])) : (StringUtil.trim(o["pageUrl"]));
        }
        if (o.hasOwnProperty("headImage") && o["headImage"])
        {
            this.headImage = o["headImage"].indexOf("http") < 0 ? (srvURL + StringUtil.trim(o["headImage"])) : (StringUtil.trim(o["headImage"]));
        }
        if (o.hasOwnProperty("secretKeyUri") && o["secretKeyUri"])
        {
            ServiceConfig.secretKeyURL = o["secretKeyUri"];
        }
        return;
    }


//com.yinyuetai.flex.GetRequest extends RequestBase

    public function GetRequest(param1:String = null, param2:URLVariables = null, param3:IUpdatable = null, param4:IResponseDecoder = null) : void
    {
        super(URLRequestMethod.GET, param1, param2, param3, param4);
        return;
    }

//com.yinyuetai.flex.RequestBase extends EventDispatcher

    private var _method:String;
    private var _url:String;
    private var _params:URLVariables;
    private var _updatable:IUpdatable;
    private var _decoder:IResponseDecoder;
    private static var _addFlexParam:Boolean = true;

    public function RequestBase(m:String, url:String, data:URLVariables = null,
            up:IUpdatable = null, deco:IResponseDecoder = null) : void
    {
        this._method = m;
        this._url = url;
        this._params = data;
        this._updatable = up;
        this._decoder = deco;
    }

    protected function onComplete(event:Event) : void
    {
        var requestEvent:RequestEvent;
        var responseData:Object;
        var event:* = event;
        var stream:* = event.target as URLStream;
        var buffer:* = new ByteArray();
        var offset:uint;
        do
        {
            stream.readBytes(buffer, offset, stream.bytesAvailable);
            offset = offset + stream.bytesAvailable;
            var ba:int = stream.bytesAvailable;
        }while (ba > 0)
        stream.close();
        if (!this._decoder)
        {
            this._decoder = new HessianDecoder();
        }
        try
        {
            responseData = this._decoder.decode(buffer);
            if (this._updatable)
            {
                this._updatable.responseData = responseData;
            }
            requestEvent = new RequestEvent(RequestEvent.RESPONSE);
            requestEvent.responseData = responseData;
            dispatchEvent(requestEvent);
        }
        catch (ex:DecodeError)
        {
            requestEvent = new RequestEvent(RequestEvent.ERROR);
            requestEvent.errorMessage = ex.message;
            dispatchEvent(requestEvent);
            if (_updatable)
            {
                _updatable.error(ex.message);
            }
        }
        dispatchEvent(new RequestEvent(RequestEvent.END));
        if (this._updatable)
        {
            this._updatable.end();
        }
        return;
    }// end function


//com.yinyuetai.mvplayer.utils.UTCDateCreator extends Object
    public static function get utcfiveminute() : String
    {
        var r:int = null;
        var d:Date = new Date();
        r = int(d.getTime() / 300000).toString();
        return r;
    }

//?package com.yinyuetai.mvplayer.player.PlayerVersion extends Object
    static const VERSION:String = "1.8.2.2";


//com.yinyuetai.mvplayer.ServiceConfig extends Object
    public static const REMOTE_SERVER_URL:String = "http://www.yinyuetai.com";
    public static const GET_VIDEOINFO_URL:String = REMOTE_SERVER_URL + "/main/get-mv-info";
    public static var secretKeyURL:String;

//com.yinyuetai.mvplayer.pojos.MvSiteVideoInfo extends Object
    public var coreVideoInfo:CoreVideoInfo;
    public var secretKeyUri:String;
    public var pageUrl:String;

//com.yinyuetai.mvplayer.pojos.CoreVideoInfo extends Object
    public var artistIds:String = "";
    public var artistNames:String = "";
    public var headImage:String = "";
    public var bigHeadImage:String = "";
    public var duration:int = 0;
    public var error:Boolean = false;
    public var errorMsg:String = "";
    public var like:Boolean = false;
    public var threeD:Boolean = false;
    public var videoId:int = 0;
    public var videoName:String = "";
    public var videoUrlModels:Array = null;

//com.yinyuetai.mvplayer.pojos.VideoUrlModel extends Object
    public var qualityLevelName:String;
    public var videoUrl:String;
    public var bitrateType:int;
    public var bitrate:int;
    public var sha1:String;
    public var fileSize:int;
    public var md5:String;

以上代码通过追踪 loadByVideoId,可以发现 RequestBase 这个很关键的类,它使用了 IResponseDecoder 接口,实现了对象的逆序列化,这个过程是 hessian 类包实现的功能,主要是使用 Hessian2Input.readObject(), hessian-flash-4_0-snap.swc 就是应现在使用的版本,如果使用低版本会不认识MAGIC 0x48:

    Error: unknown code: 0x48 H
        at hessian.io::Hessian2Inpu。

有了这些后面会比较好办,稍为花点心思。先来用 Loader 将 mvplayer.swf 加载往来,然后调用它的 loadByVideoId,所以只需要提供一个 ID 就可以得到连接信息了,一条含有 get-mv-info 的数据请求,FlasCC 的逆向也免了。当然,使用这种方法也面临两个难题:

1. 沙箱安全约束。
2. 本地加载时,不允许使用 allowDomain() 方法,所以需要以服务端加载。

因为沙箱安全约束,即使用加载 mvplayer.swf 也不能使它读取到 yinyuetai.com 服务器的数据,因为改变了 mvplayer.swf 的位置后,原来的 yinyuetai.com 已经变成第三方网站了,所以要在它身上取数据,就要通过 crossDomain.xml 策略文件来授权。这个授权有点问题, 我试了一下本地做了一个 hack 版本:

<cross-domain-policy>
        <allow-access-from domain="*"/>
</cross-domain-policy>

上面这个策略文件就是一个完全开放许可,我需要做的就是把本地 hosts 文件修改一下,加入下面一行:

127.0.0.1   www.yinyuetai.com

再次调用 mvplayer.swf 时,它依然是从 www.yinyuetai.com 请求数据,只是这次它的请求被路由到了本地的环回接口,我只需做一个 HTTP 服务提供上面的策略文件即可以解决授权,当 mvpayer.swf 认为得到授权后,还需要它来获取数据,所以要再次修改 hosts 文件,去掉之前的修改内容,这样就麻烦是有点,不过它真的 WORKING 了!

退一步来考虑,可以不需要 mvplayer.swf 获取数据,只要得到它间接产生的数据链接即可以达到破解的目的了。于是,我做了一个通过 ServerSocket 实现的 HTTP 服务,mvplayer.swf 就从这个 HTTP 服务加载,然后就让它产生一个数据请求,我需要做的是捕捉这个即将产生异常的数据请求。可惜的是,通过全局异常捕捉可以处理文档类 Player 产生的异常,但进入到 RequestBase 类后,Flash UncaughtErrorEvents 全局异常处理就真的异常了,完全不工作。而且使用 AIR 运行时,根本连异常的警告窗都不弹出来,所以有用的数据连接完全处理不了:

=========================================================================
Error #2044: Unhandled SecurityErrorEvent:. text=Error #2048: Security sandbox violation: http://127.0.0.1/mvplayer.swf cannot load data from http://www.yinyuetai.com/main/get-mv-info?flex=true&sc=54e4b6daef63eb263d80e97ae4bb775a&t=4797652&v=1.8.2.2&videoId=2344403.
    at com.yinyuetai.flex::RequestBase/doRequest()
    at com.yinyuetai.mvplayer.player::Player/loadByVideoId()
    at Main/parseCMD()
    at Main/doKeyUp()
=========================================================================

到这里,问题似乎变得更复杂了,难道非要走上抓 IP 包的不归路?好吧,看 TCPViewr 这个小工具是怎么做的,看看如何自己写代码做一个 Tiny Sniffer,这只能先想想的法子,基本上也是一条不归路吧,以后有空再去搞。先要以简单的方法来解决问题,想想,想想,再想想!真的还是有的,而且极为便利,可以说随手拈来。那就是让 mvplayer.swf 请求数据时,去本地的服务器取数据了,本地服务器最多就是产生一条 404 回复,因此就不会产生不可以处理的异常了,太好了,就这样干了,使用 Hex Workshop 来找找 www.yinyuetai.com 来改掉:

=========================================================================
00033F40 74 74 70 3A 2F 2F 70 70 6C 73 69 73 2E 63 68 69 ttp://pplsis.chi
00033F50 6E 61 63 61 63 68 65 2E 6E 65 74 2F 66 69 6C 65 nacache.net/file
00033F60 11 52 45 4D 4F 54 45 5F 53 45 52 56 45 52 5F 55 .REMOTE_SERVER_U
00033F70 52 4C 18 68 74 74 70 3A 2F 2F 31 32 37 2E 31 30 RL.http://127.10
00033F80 30 2E 31 30 30 2E 31 30 3A 38 30 18 52 45 4D 4F 0.100.10:80.REMO
00033F90 54 45 5F 53 54 41 54 49 43 5F 53 45 52 56 45 52 TE_STATIC_SERVER
00033FA0 5F 55 52 4C 18 68 74 74 70 3A 2F 2F 73 2E 63 2E _URL.http://s.c.
=========================================================================
看上的服务器已经变成 127.100.100.10:80 了,处理后让 YueTai VIP 跑跑看,我的小工具叫“月台微挨披”,list 是命令,输入命令 list ID 就获取对应 ID 的视频数据:

技术分享

=========================================================================
list 2344403
Parsing command: list 2344403
Parse request: GET /main/get-mv-info?flex=true&sc=57dc2e7b639a3d74f87a295f22abc04a&t=4797738&v=1.8.2.2&videoId=2344403 HTTP/1.1

GET: /main/get-mv-info?flex=true&sc=57dc2e7b639a3d74f87a295f22abc04a&t=4797738&v=1.8.2.2&videoId=2344403

parseVideo Info: http://www.yinyuetai.com/main/get-mv-info?flex=true&sc=57dc2e7b639a3d74f87a295f22abc04a&t=4797738&v=1.8.2.2&videoId=2344403

Length: 1753
Video info: [object Object]
CoreVideoInfo: [object Object]
videoUrlModels: [object Object],[object Object],[object Object],[object Object]
=========================================================================

这个 ID 的节目是 AOA专访 - 王牌天使 怦然心动! 15/08/04。看到 videoUrlModels 成员对应出现了四个 Object,离成功就不远了,提取一个 VideoUrlModel 数据来观赏:

=========================================================================
qualityLevelName:String "流畅"
videoUrl:String         "http://hc.yinyuetai.com/uploads/videos/common/3132014EF85A8CE3ADF791CC5E279802.flv?sc=8600027e500abf9b&br=779&vid=2344403&aid=30971&area=ML&vst=6"
bitrateType:int         1
bitrate:int             779
sha1:String             "b83ad22372f9522e4803e7c0cd370fad08ffb3bd"
fileSize:int            53090582
md5:String              "82878eee0fc9a36d41beadc4557f533b"
=========================================================================
考虑到我的代码伤害性较大,就不全贴了,这里取一段展示如何使用傅 URLStream 加载 Hessian 序列化数据,并进行逆向序列,然后还有通过 ServerSocket 和 Socket 实现只支持 GET 动作的超简版本 HTTP 服务器。

    private function parseVideoInfo(msg:String, index:int):void
    {    
        //get-mv-info
        var gmi:String = YYT + msg.substr(index);
        log("parseVideo Info: " + gmi);
        var req:URLRequest = new URLRequest(gmi);
        var lod:URLStream = new URLStream();
        req.method = URLRequestMethod.GET;
        lod.addEventListener(Event.COMPLETE, doMVInfo);
        //lod.dataFormat = URLLoaderDataFormat.BINARY;
        lod.load(req);
    }

    private function doMVInfo(e:Event):void 
    {
        var lod:URLStream = URLStream(e.target);
        var buf:ByteArray = new ByteArray();
        log("Length: " + lod.bytesAvailable);
        var inf:Object = new Hessian2Input(lod).readObject();
        if ( inf.videoInfo && !inf.error) { // inf.logined
            var mvInfo:MvInfoModel = MvInfoModel(inf.videoInfo);
            var vInfo:MvInfo = mvInfo.coreVideoInfo;
            var vModels:Array = vInfo.videoUrlModels;
            log("Video info: " + vInfo.artistNames + " - " + vInfo.videoName);
            var i:String, mb:int = 1024*1024;
            for ( i in vModels) {
                var v:VideoUrlModel = vModels[i];
                log( v.qualityLevelName + " " +(v.fileSize / mb).toFixed(2) + "MB " + v.videoUrl);
            }
        }
    }

最后,下载器的功能就不做了,目标已经达成,就这样收工。程序输出效果如下:
======================================================================
list 2344403
Parsing command: list 2344403
 Close client <127.0.0.1:55585>.

connect to <127.0.0.1:55586>

Parse request: GET /main/get-mv-info?flex=true&sc=2019a249b4fc9065dba9a05a794571e2&t=4797752&v=1.8.2.2&videoId=2344403 HTTP/1.1

GET: /main/get-mv-info?flex=true&sc=2019a249b4fc9065dba9a05a794571e2&t=4797752&v=1.8.2.2&videoId=2344403

parseVideo Info: http://www.yinyuetai.com/main/get-mv-info?flex=true&sc=2019a249b4fc9065dba9a05a794571e2&t=4797752&v=1.8.2.2&videoId=2344403

Length: 1753
Video info: STAR!调查团,AOA - AOA专访 - 王牌天使 怦然心动! 15/08/04
流畅 50.63MB http://hc.yinyuetai.com/uploads/videos/common/3132014EF85A8CE3ADF791CC5E279802.flv?sc=5514cfbb95a8d0cd&br=779&vid=2344403&aid=30971&area=ML&vst=6
高清 71.40MB http://hd.yinyuetai.com/uploads/videos/common/757B014EF85F24E2341DCCA341D31C53.flv?sc=affff575aed9948a&br=1099&vid=2344403&aid=30971&area=ML&vst=6
超清 203.08MB http://he.yinyuetai.com/uploads/videos/common/1816014EF85F24DBDDA5B109E2710BA3.flv?sc=56451050f885c3c0&br=3125&vid=2344403&aid=30971&area=ML&vst=6
会员 397.74MB http://sh.yinyuetai.com/uploads/videos/common/EF43014EF85F24D5360F07B4721B30D6.mp4?sc=9ef45657ec52ff16&br=6122&vid=2344403&aid=30971&area=ML&vst=6
======================================================================

技术分享

微缩HTTP服务器实现

外部 SWF 文件加载,完成载入后 SWF成员就指向外部文件的文档类。

package
{
	import flash.display.*;
	import flash.events.*;
	import flash.net.URLRequest;
	import flash.display.Loader;
	import flash.system.LoaderContext;
	import flash.system.ApplicationDomain;
	
	/**
	 * ...
	 * @author Jimbowhy
	 */
	public class ContextAgent extends EventDispatcher
	{
		public static const ON_INIT:String = "oninit";
		
		public var SWF:Object; // This is the reference to the main class of swf file
		public var URL:String = "http://airdownload.adobe.com/air/browserapi/air.swf";
		// localhost version is ok "http://localhost/JSocketSrv/bin/air.swf");
		// local sanbox not allow use Security.allowDomain()
		// SecurityError: Error #3207: Application-sandbox content cannot access this feature.
		private var SWFLoader:Loader = new Loader(); // Used to load the SWF
		private var loaderContext:LoaderContext = new LoaderContext();
		private var doInit:Function;
		
		public function ContextAgent(url:String, fun:Function):void 
		{
			if ( fun!=null ) {
				addEventListener(ContextAgent.ON_INIT, fun);
				doInit = fun;
			}
			if( url ) load(url)
		}
		
		public function load(url:String):void 
		{
			URL = url || URL;
			// Used to set the application domain
			loaderContext.applicationDomain = ApplicationDomain.currentDomain;
			SWFLoader.contentLoaderInfo.addEventListener(Event.INIT, onInit);
			SWFLoader.load(new URLRequest(URL), loaderContext);
		}
		
		private function onInit(e:Event):void
		{
			SWF = e.target.content;
			dispatchEvent( new Event(ON_INIT) );
			if ( doInit!=null ) {
				removeEventListener(ContextAgent.ON_INIT, doInit);
				doInit = null;
			}
		}
	}

}
微版HTTP,实现 crossDomain.xml 分发,可以执行 HTTP GET 动作。

package  
{
	import flash.events.*;
	import flash.events.*;
	import flash.filesystem.File;
	import flash.filesystem.FileMode;
	import flash.filesystem.FileStream;
	import flash.net.*;
	import flash.utils.ByteArray;
	import flash.utils.setInterval;
	
	/**
	 * ...
	 * @author Jimbowhy
	 */
	public class HttpAgent extends EventDispatcher
	{
		public static const ON_MESSAGE:String = "onMessage";
		
		public var message:String;
		
		private var sovsok:ServerSocket;
		private var sovsokSecu:ServerSocket;
		private var clients:Array = new Array();
		private var HOST:String = "127.0.0.1"
		private var PORT:int = 80;
		private var portSecu:int = 843;
		private var crossDomain:String = "<policy-file-request/>";
		private var crossDomainXML:String = 
			"<cross-domain-policy><allow-access-from domain=\"*\" to-ports=\"*\"/></cross-domain-policy>";
		
		public function HttpAgent(host:String = "127.0.0.1", port:int = 80):void 
		{
			HOST = host;
			PORT = port;
			log( "Do Invoke <host:port>".replace("host", HOST).replace("port", PORT) );
			//new ContextAgent("http://localhost/JSocketSrv/bin/air.swf");
			
			if ( !ServerSocket.isSupported ) 
			{
				log("ServerSocket is not supported.");
				return;
			}
			if ( sovsok ) clearAll();
			try{
				sovsokSecu = new ServerSocket();
				sovsokSecu.addEventListener(ServerSocketConnectEvent.CONNECT, doConnectSecurity);
				sovsokSecu.bind(portSecu, HOST);
				sovsokSecu.listen();
				log("Bound Security Server to <VA:VB>".replace("VA", HOST).replace("VB", portSecu));
				sovsok = new ServerSocket();
				sovsok.addEventListener(ServerSocketConnectEvent.CONNECT, doConnect);
				//sovsok.addEventListener(Event.CLOSE, doSocketClose);			
				sovsok.bind(PORT, HOST);
				log("Bound to <VA:VB>".replace("VA", HOST).replace("VB", PORT));
				sovsok.listen();
			}catch (e:Error) {
				log(e.getStackTrace());
			}
			if ( !sovsok || !sovsok.bound ) {
				log("Fail to bounding, check host address and port:"+PORT+","+portSecu);
			}
		}
		
		private function clearAll():void
		{
			if ( sovsok.bound ) sovsok.close();
			sovsok.removeEventListener(ServerSocketConnectEvent.CONNECT, doConnect);
			if ( sovsokSecu.bound ) sovsokSecu.close();
			sovsokSecu.removeEventListener(ServerSocketConnectEvent.CONNECT, doConnectSecurity);
			var i:int;
			for (i = 0; i < clients.length; i++) {
				var s:Socket = Socket(clients[i]);
				s.removeEventListener(ProgressEvent.SOCKET_DATA, doSocketClient);
				s.removeEventListener(Event.CLOSE, doSocketClose);
				s.removeEventListener(DataEvent.DATA, doSocketXML);
				s.close();
			}
			clients = new Array();
		}
		
		private function doSocketClose(e:Event):void 
		{
			var sok:Socket = Socket(e.target);
			var s:Socket ;
			var c:Array = new Array();
			while ( s = clients.shift() ) {
				if ( s != sok ) c.push(s);
				s.removeEventListener(ProgressEvent.SOCKET_DATA, doSocketClient);
				s.removeEventListener(DataEvent.DATA, doSocketXML);
				s.removeEventListener(Event.CLOSE, doSocketClose);
				log(" Close client <VA:VB>.".replace("VA", s.remoteAddress).replace("VB", s.remotePort) );
			}
		}
		
		private function doConnectSecurity(e:ServerSocketConnectEvent):void 
		{
			var policier:Socket = e.socket;
			policier.addEventListener(ProgressEvent.SOCKET_DATA, doSocketDataSecu);
			log( " Policier connected via port VA.".replace("VA", portSecu) );
		}
		
		private function doConnect(e:ServerSocketConnectEvent):void 
		{
			var client:Socket = e.socket;
			var msg:String = e.type + " to <VA:VB>";
			log( msg.replace("VA", client.remoteAddress).replace("VB", client.remotePort) );
			clients.push(client);
			client.addEventListener( ProgressEvent.SOCKET_DATA, doSocketClient );
			//client.addEventListener( DataEvent.DATA, doSocketXML );
			client.addEventListener( Event.CLOSE, doSocketClose );
		}
		
		private function bin2hex(bytes:ByteArray):String
		{
			bytes.position = 0;
			var r:String = "";
			var i:int;
			for (i = 0; i < 0x10; i++) r += "0x0" + i.toString(16)+" ";
			r += "\n";
			for (i = 0; i < bytes.length; i++) {
				var v:int = bytes.readByte();
				r += (v>0x0F? "0x":"0x0") + v.toString(16)+" ";
			}
			return r;
		}
		
		private function doSocketClient(e:ProgressEvent):void 
		{
			var sok:Socket = Socket(e.target);
			var buf:ByteArray = new ByteArray();
			var len:int = e.bytesLoaded;
			sok.readBytes(buf, 0, len);
			
			var txt:String = buf.readUTFBytes(len);
			while( txt.length<len){ // skip \0 between XMLSocket send
				txt += buf.readUTFBytes(buf.bytesAvailable);
				txt += "\n";
				buf.position = txt.length;
			}
			trace( "Bin2Hex:\n" + bin2hex(buf) );
			
			//if(txt.length>512) txt = "...";
			var msg:String = "Socket cient <VA:VB> " + txt.length + " " + e.bytesLoaded + "/" + e.bytesTotal + " :" + txt;
			//log( msg.replace("VA", sok.remoteAddress).replace("VB", sok.remotePort) );
			if ( txt == crossDomain ) {
				responsePolicier(sok);
				trace("Response with crossDomain.xml");
			}else {
				parseRequest(sok, txt);
			}
		}
		
		private function parseRequest(sok:Socket, req:String):void 
		{
			var ls:Array = req.split("\n");
			log("Parse request: " + ls[0]);
			
			var r:Array = HTTP1P1.RGET.exec(ls[0]);
			if ( r ) {
				log("GET: " + r[2]);
				http_get(sok, r[2], req);
			}else {
				log(HTTP1P1.HTTP501+": " + ls[0]);
				sok.writeUTFBytes(HTTP1P1.HTTP501);
				sok.writeUTFBytes(HTTP1P1.HEADSPLITER);
				sok.flush();
			}
		}
		
		private function http_get(sok:Socket, path:String, req:String):void 
		{
			path = File.applicationDirectory.resolvePath("./"+path).nativePath;
			var file:File = new File(path);
			if ( !file.exists ) {
				log( HTTP1P1.HTTP404 + path);
				HTTP1P1.setHttpStatus(sok, 404);
				HTTP1P1.setContentLength(sok, 0);
				HTTP1P1.setMime(sok, "html");
				HTTP1P1.setServerMark(sok);
				HTTP1P1.setHeaderFinish(sok);
			}else{
				var buff:ByteArray = new ByteArray();
				var stem:FileStream = new FileStream();
				log("HTTP GET: " + path);
				stem.open(file, FileMode.READ);
				stem.readBytes(buff);
				HTTP1P1.setHttpStatus(sok, 200);
				//HTTP1P1.setHeader(sok, "Content-Encoding", "gzip");
				HTTP1P1.setServerMark(sok);
				log( HTTP1P1.setMime(sok, file.extension) );
				HTTP1P1.setContentLength(sok, buff.length);
				HTTP1P1.setHeaderFinish(sok);
				sok.writeBytes(buff);
			}
			sok.flush();
		}
		
		private function doSocketXML(e:DataEvent):void 
		{
			var sok:Socket = Socket(e.target);
			var txt:String = sok.readUTFBytes(sok.bytesAvailable);
			var msg:String = "XMLSocket cient <VA:VB> " + sok.bytesAvailable +" :" + txt;
			log( msg.replace("VA", sok.remoteAddress).replace("VB", sok.remotePort) );
			if ( txt == crossDomain ) responsePolicier(sok);						
		}
		
		private function doSocketDataSecu(e:ProgressEvent):void 
		{
			var msg:String = "Security server receiving (VA)";
			trace(msg.replace("VA", e.bytesLoaded)); //e.bytesTotal alway 0 for Socket
			var policier:Socket = Socket( e.target );
			var req:String = policier.readUTFBytes(policier.bytesAvailable);
			trace("Policier request: " + req);
			if ( req == crossDomain ) responsePolicier(policier);
			policier.close();			
		}
		
		public function responsePolicier(policier:Socket):void
		{
			trace("Response: " + crossDomainXML);
			policier.writeUTFBytes( crossDomainXML );
			policier.writeByte(0); // \0 for XMLSocket policy
			policier.flush();
		}		
		
		private function log(msg:String):void
		{
			message = msg+("\n");
			var e:Event = new Event(HttpAgent.ON_MESSAGE);
			dispatchEvent(e);
		}
	}

}

HTTP1P1 类文件,保存HTTP状态常数,实现基础方法。

package 
{
	import flash.net.Socket;
	
	/**
	 * ...
	 * @author Jimbowhy
	 */
	public class HTTP1P1 
	{
		public static const HTTP200:String = "HTTP/1.1 200 OK\r\n";
		public static const HTTP201:String = "HTTP/1.1 201 Created\r\n";
		public static const HTTP202:String = "HTTP/1.1 202 Accepted\r\n";
		public static const HTTP203:String = "HTTP/1.1 203 Non-Authoritative Information\r\n";
		public static const HTTP204:String = "HTTP/1.1 204 No Content\r\n";
		public static const HTTP205:String = "HTTP/1.1 205 Reset Content\r\n";
		public static const HTTP206:String = "HTTP/1.1 206 Partial Content\r\n";
		
		public static const HTTP300:String = "HTTP/1.1 300 Multiple Choices\r\n";
		public static const HTTP301:String = "HTTP/1.1 301 Moved Permanently\r\n";
		public static const HTTP302:String = "HTTP/1.1 302 Found\r\n";
		public static const HTTP303:String = "HTTP/1.1 303 See Other\r\n";
		public static const HTTP304:String = "HTTP/1.1 304 Not Modified\r\n";
		public static const HTTP305:String = "HTTP/1.1 305 Use Proxy\r\n";
		public static const HTTP306:String = "HTTP/1.1 306 (Unused)\r\n";
		public static const HTTP307:String = "HTTP/1.1 307 Temporary Redirect\r\n";
		
		public static const HTTP400:String = "HTTP/1.1 400 Bad Request\r\n";
		public static const HTTP401:String = "HTTP/1.1 401 Unauthorized\r\n";
		public static const HTTP402:String = "HTTP/1.1 402 Payment Required\r\n";
		public static const HTTP403:String = "HTTP/1.1 403 Forbidden\r\n";
		public static const HTTP404:String = "HTTP/1.1 404 Not Found\r\n";
		public static const HTTP405:String = "HTTP/1.1 405 Method Not Allowed\r\n";
		public static const HTTP406:String = "HTTP/1.1 406 Not Acceptable\r\n";
		public static const HTTP407:String = "HTTP/1.1 407 Proxy Authentication Required\r\n";
		public static const HTTP408:String = "HTTP/1.1 408 Request Timeout\r\n";
		public static const HTTP409:String = "HTTP/1.1 409 Conflict\r\n";
		public static const HTTP410:String = "HTTP/1.1 410 Gone\r\n";
		public static const HTTP411:String = "HTTP/1.1 411 Length Required\r\n";
		public static const HTTP412:String = "HTTP/1.1 412 Precondition Failed\r\n";
		public static const HTTP413:String = "HTTP/1.1 413 Request Entity Too Large\r\n";
		public static const HTTP414:String = "HTTP/1.1 414 Request-URI Too Long\r\n";
		public static const HTTP415:String = "HTTP/1.1 415 Unsupported Media Type\r\n";
		public static const HTTP416:String = "HTTP/1.1 416 Requested Range Not Satisfiable\r\n";
		public static const HTTP417:String = "HTTP/1.1 417 Expectation Failed\r\n";
		
		public static const HTTP500:String = "HTTP/1.1 500 Internal Server Error\r\n";
		public static const HTTP501:String = "HTTP/1.1 501 Not Implemented\r\n";
		public static const HTTP502:String = "HTTP/1.1 502 Bad Gateway\r\n";
		public static const HTTP503:String = "HTTP/1.1 503 Service Unavailable\r\n";
		public static const HTTP504:String = "HTTP/1.1 504 Gateway Timeout\r\n";
		public static const HTTP505:String = "HTTP/1.1 505 HTTP Version Not Supported\r\n";
		
		public static const HTTP520:String = "HTTP/1.1 520 Error setHttpStatus VA\r\n";
		
		public static const ContentLength:String = "Content-Length: VA\r\n";
		
		public static const HEADSPLITER:String = "\r\n";
		public static const RGET:RegExp = /^(GET) (.+) (HTTP\/1.1)$/;
		
		public static const SERVER:String = "Server: ServerSocket by Jimbowhy\r\n";
		
		public static function setHeader(sok:Socket, name:String, value:String):void 
		{
			sok.writeUTFBytes(name + ": " + value + "\r\n");
		}
		public static function setHttpStatus(sok:Socket, statusCode:int):void 
		{
			var s:String = HTTP1P1["HTTP" + statusCode];
			if ( s == null) {
				sok.writeUTFBytes( HTTP520.replace("VA", statusCode) );
				return;
			}
			sok.writeUTFBytes( s );
		}
		
		public static function setServerMark(sok:Socket):void 
		{
			sok.writeUTFBytes(SERVER);
		}
		
		public static function setMime(sok:Socket, ext:String):String 
		{
			var ex:String = ext.split(".").pop();
			var m:String = Mime["M_" + ex.toLowerCase()];
			if ( m == null ) m = Mime.M_BIN;
			sok.writeUTFBytes("Content-Type: "+m);
			return m;
		}
		
		public static function setContentLength(sok:Socket, len:int):void
		{
			sok.writeUTFBytes(ContentLength.replace("VA", len));
		}
		
		public static function setHeaderFinish(sok:Socket):void 
		{
			sok.writeUTFBytes(HEADSPLITER);
		}
	}
	
}
Mime 类,记录文件相关的 MIME信息
package  
{
	/**
	 * ...
	 * @author Jimbowhy
	 */
	public class Mime 
	{
		public static const M_001:String = "application/x-001\r\n";
		public static const M_301:String = "application/x-301\r\n";
		public static const M_323:String = "text/h323\r\n";
		public static const M_906:String = "application/x-906\r\n";
		public static const M_907:String = "drawing/907\r\n";
		public static const M_BIN:String = "application/octet-stream\r\n";
		public static const M_IVF:String = "video/x-ivf\r\n";
		public static const M_a11:String = "application/x-a11\r\n";
		public static const M_acp:String = "audio/x-mei-aac\r\n";
		public static const M_ai:String = "application/postscript\r\n";
		public static const M_aif:String = "audio/aiff\r\n";
		public static const M_aifc:String = "audio/aiff\r\n";
		public static const M_aiff:String = "audio/aiff\r\n";
		public static const M_anv:String = "application/x-anv\r\n";
		public static const M_apk:String = "application/vnd.android.package-archive\r\n";
		public static const M_asa:String = "text/asa\r\n";
		public static const M_asf:String = "video/x-ms-asf\r\n";
		public static const M_asp:String = "text/asp\r\n";
		public static const M_asx:String = "video/x-ms-asf\r\n";
		public static const M_au:String = "audio/basic\r\n";
		public static const M_avi:String = "video/avi\r\n";
		public static const M_awf:String = "application/vnd.adobe.workflow\r\n";
		public static const M_biz:String = "text/xml\r\n";
		public static const M_bmp:String = "application/x-bmp\r\n";
		public static const M_bot:String = "application/x-bot\r\n";
		public static const M_c4t:String = "application/x-c4t\r\n";
		public static const M_c90:String = "application/x-c90\r\n";
		public static const M_cal:String = "application/x-cals\r\n";
		public static const M_cat:String = "application/vnd.ms-pki.seccat\r\n";
		public static const M_cdf:String = "application/x-netcdf\r\n";
		public static const M_cdr:String = "application/x-cdr\r\n";
		public static const M_cel:String = "application/x-cel\r\n";
		public static const M_cer:String = "application/x-x509-ca-cert\r\n";
		public static const M_cg4:String = "application/x-g4\r\n";
		public static const M_cgm:String = "application/x-cgm\r\n";
		public static const M_cit:String = "application/x-cit\r\n";
		public static const M_class:String = "java/*\r\n";
		public static const M_cml:String = "text/xml\r\n";
		public static const M_cmp:String = "application/x-cmp\r\n";
		public static const M_cmx:String = "application/x-cmx\r\n";
		public static const M_cot:String = "application/x-cot\r\n";
		public static const M_crl:String = "application/pkix-crl\r\n";
		public static const M_crt:String = "application/x-x509-ca-cert\r\n";
		public static const M_csi:String = "application/x-csi\r\n";
		public static const M_css:String = "text/css\r\n";
		public static const M_cut:String = "application/x-cut\r\n";
		public static const M_dbf:String = "application/x-dbf\r\n";
		public static const M_dbm:String = "application/x-dbm\r\n";
		public static const M_dbx:String = "application/x-dbx\r\n";
		public static const M_dcd:String = "text/xml\r\n";
		public static const M_dcx:String = "application/x-dcx\r\n";
		public static const M_der:String = "application/x-x509-ca-cert\r\n";
		public static const M_dgn:String = "application/x-dgn\r\n";
		public static const M_dib:String = "application/x-dib\r\n";
		public static const M_dll:String = "application/x-msdownload\r\n";
		public static const M_doc:String = "application/msword\r\n";
		public static const M_dot:String = "application/msword\r\n";
		public static const M_drw:String = "application/x-drw\r\n";
		public static const M_dtd:String = "text/xml\r\n";
		//public static const M_dwf:String = "Model/vnd.dwf\r\n";
		public static const M_dwf:String = "application/x-dwf\r\n";
		public static const M_dwg:String = "application/x-dwg\r\n";
		public static const M_dxb:String = "application/x-dxb\r\n";
		public static const M_dxf:String = "application/x-dxf\r\n";
		public static const M_edn:String = "application/vnd.adobe.edn\r\n";
		public static const M_emf:String = "application/x-emf\r\n";
		public static const M_eml:String = "message/rfc822\r\n";
		public static const M_ent:String = "text/xml\r\n";
		public static const M_epi:String = "application/x-epi\r\n";
		public static const M_eps:String = "application/postscript\r\n";
		public static const M_etd:String = "application/x-ebx\r\n";
		public static const M_exe:String = "application/x-msdownload\r\n";
		public static const M_fax:String = "image/fax\r\n";
		public static const M_fdf:String = "application/vnd.fdf\r\n";
		public static const M_fif:String = "application/fractals\r\n";
		public static const M_fo:String = "text/xml\r\n";
		public static const M_frm:String = "application/x-frm\r\n";
		public static const M_g4:String = "application/x-g4\r\n";
		public static const M_gbr:String = "application/x-gbr\r\n";
		public static const M_gif:String = "image/gif\r\n";
		public static const M_gl2:String = "application/x-gl2\r\n";
		public static const M_gp4:String = "application/x-gp4\r\n";
		public static const M_hgl:String = "application/x-hgl\r\n";
		public static const M_hmr:String = "application/x-hmr\r\n";
		public static const M_hpg:String = "application/x-hpgl\r\n";
		public static const M_hpl:String = "application/x-hpl\r\n";
		public static const M_hqx:String = "application/mac-binhex40\r\n";
		public static const M_hrf:String = "application/x-hrf\r\n";
		public static const M_hta:String = "application/hta\r\n";
		public static const M_htc:String = "text/x-component\r\n";
		public static const M_htm:String = "text/html\r\n";
		public static const M_html:String = "text/html\r\n";
		public static const M_htt:String = "text/webviewhtml\r\n";
		public static const M_htx:String = "text/html\r\n";
		public static const M_icb:String = "application/x-icb\r\n";
		public static const M_ico:String = "application/x-ico\r\n";
		//public static const M_ico:String = "image/x-icon\r\n";
		public static const M_iff:String = "application/x-iff\r\n";
		public static const M_ig4:String = "application/x-g4\r\n";
		public static const M_igs:String = "application/x-igs\r\n";
		public static const M_iii:String = "application/x-iphone\r\n";
		public static const M_img:String = "application/x-img\r\n";
		public static const M_ins:String = "application/x-internet-signup\r\n";
		public static const M_ipa:String = "application/vnd.iphone\r\n";		
		public static const M_isp:String = "application/x-internet-signup\r\n";
		public static const M_java:String = "java/*\r\n";
		public static const M_jfif:String = "image/jpeg\r\n";
		//public static const M_jpe:String = "application/x-jpe\r\n";
		public static const M_jpe:String = "image/jpeg\r\n";
		public static const M_jpeg:String = "image/jpeg\r\n";
		//public static const M_jpg:String = "application/x-jpg\r\n";
		public static const M_jpg:String = "image/jpeg\r\n";
		public static const M_js:String = "application/x-javascript\r\n";
		public static const M_jsp:String = "text/html\r\n";
		public static const M_la1:String = "audio/x-liquid-file\r\n";
		public static const M_lar:String = "application/x-laplayer-reg\r\n";
		public static const M_latex:String = "application/x-latex\r\n";
		public static const M_lavs:String = "audio/x-liquid-secure\r\n";
		public static const M_lbm:String = "application/x-lbm\r\n";
		public static const M_lmsff:String = "audio/x-la-lms\r\n";
		public static const M_ls:String = "application/x-javascript\r\n";
		public static const M_ltr:String = "application/x-ltr\r\n";
		public static const M_m1v:String = "video/x-mpeg\r\n";
		public static const M_m2v:String = "video/x-mpeg\r\n";
		public static const M_m3u:String = "audio/mpegurl\r\n";
		public static const M_m4e:String = "video/mpeg4\r\n";
		public static const M_mac:String = "application/x-mac\r\n";
		public static const M_man:String = "application/x-troff-man\r\n";
		public static const M_math:String = "text/xml\r\n";
		//public static const M_mdb:String = "application/msaccess\r\n";
		public static const M_mdb:String = "application/x-mdb\r\n";
		public static const M_mfp:String = "application/x-shockwave-flash\r\n";
		public static const M_mht:String = "message/rfc822\r\n";
		public static const M_mhtml:String = "message/rfc822\r\n";
		public static const M_mi:String = "application/x-mi\r\n";
		public static const M_mid:String = "audio/mid\r\n";
		public static const M_midi:String = "audio/mid\r\n";
		public static const M_mil:String = "application/x-mil\r\n";
		public static const M_mml:String = "text/xml\r\n";
		public static const M_mnd:String = "audio/x-musicnet-download\r\n";
		public static const M_mns:String = "audio/x-musicnet-stream\r\n";
		public static const M_mocha:String = "application/x-javascript\r\n";
		public static const M_movie:String = "video/x-sgi-movie\r\n";
		public static const M_mp1:String = "audio/mp1\r\n";
		public static const M_mp2:String = "audio/mp2\r\n";
		public static const M_mp2v:String = "video/mpeg\r\n";
		public static const M_mp3:String = "audio/mp3\r\n";
		public static const M_mp4:String = "video/mpeg4\r\n";
		public static const M_mpa:String = "video/x-mpg\r\n";
		public static const M_mpd:String = "application/vnd.ms-project\r\n";
		public static const M_mpe:String = "video/x-mpeg\r\n";
		public static const M_mpeg:String = "video/mpg\r\n";
		public static const M_mpg:String = "video/mpg\r\n";
		public static const M_mpga:String = "audio/rn-mpeg\r\n";
		public static const M_mpp:String = "application/vnd.ms-project\r\n";
		public static const M_mps:String = "video/x-mpeg\r\n";
		public static const M_mpt:String = "application/vnd.ms-project\r\n";
		public static const M_mpv2:String = "video/mpeg\r\n";
		public static const M_mpv:String = "video/mpg\r\n";
		public static const M_mpw:String = "application/vnd.ms-project\r\n";
		public static const M_mpx:String = "application/vnd.ms-project\r\n";
		public static const M_mtx:String = "text/xml\r\n";
		public static const M_mxp:String = "application/x-mmxp\r\n";
		public static const M_net:String = "image/pnetvue\r\n";
		public static const M_nrf:String = "application/x-nrf\r\n";
		public static const M_nws:String = "message/rfc822\r\n";
		public static const M_odc:String = "text/x-ms-odc\r\n";
		public static const M_out:String = "application/x-out\r\n";
		public static const M_p10:String = "application/pkcs10\r\n";
		public static const M_p12:String = "application/x-pkcs12\r\n";
		public static const M_p7b:String = "application/x-pkcs7-certificates\r\n";
		public static const M_p7c:String = "application/pkcs7-mime\r\n";
		public static const M_p7m:String = "application/pkcs7-mime\r\n";
		public static const M_p7r:String = "application/x-pkcs7-certreqresp\r\n";
		public static const M_p7s:String = "application/pkcs7-signature\r\n";
		public static const M_pc5:String = "application/x-pc5\r\n";
		public static const M_pci:String = "application/x-pci\r\n";
		public static const M_pcl:String = "application/x-pcl\r\n";
		public static const M_pcx:String = "application/x-pcx\r\n";
		public static const M_pdf:String = "application/pdf\r\n";
		public static const M_pdx:String = "application/vnd.adobe.pdx\r\n";
		public static const M_pfx:String = "application/x-pkcs12\r\n";
		public static const M_pgl:String = "application/x-pgl\r\n";
		public static const M_pic:String = "application/x-pic\r\n";
		public static const M_pko:String = "application/vnd.ms-pki.pko\r\n";
		public static const M_pl:String = "application/x-perl\r\n";
		public static const M_plg:String = "text/html\r\n";
		public static const M_pls:String = "audio/scpls\r\n";
		public static const M_plt:String = "application/x-plt\r\n";
		//public static const M_png:String = "application/x-png\r\n";
		public static const M_png:String = "image/png\r\n";
		public static const M_pot:String = "application/vnd.ms-powerpoint\r\n";
		public static const M_ppa:String = "application/vnd.ms-powerpoint\r\n";
		public static const M_ppm:String = "application/x-ppm\r\n";
		public static const M_pps:String = "application/vnd.ms-powerpoint\r\n";
		//public static const M_ppt:String = "application/vnd.ms-powerpoint\r\n";
		public static const M_ppt:String = "application/x-ppt\r\n";
		public static const M_pr:String = "application/x-pr\r\n";
		public static const M_prf:String = "application/pics-rules\r\n";
		public static const M_prn:String = "application/x-prn\r\n";
		public static const M_prt:String = "application/x-prt\r\n";
		public static const M_ps:String = "application/x-ps\r\n";
		public static const M_ptn:String = "application/x-ptn\r\n";
		public static const M_pwz:String = "application/vnd.ms-powerpoint\r\n";
		public static const M_r3t:String = "text/vnd.rn-realtext3d\r\n";
		public static const M_ra:String = "audio/vnd.rn-realaudio\r\n";
		public static const M_ram:String = "audio/x-pn-realaudio\r\n";
		public static const M_ras:String = "application/x-ras\r\n";
		public static const M_rat:String = "application/rat-file\r\n";
		public static const M_rdf:String = "text/xml\r\n";
		public static const M_rec:String = "application/vnd.rn-recording\r\n";
		public static const M_red:String = "application/x-red\r\n";
		public static const M_rgb:String = "application/x-rgb\r\n";
		public static const M_rjs:String = "application/vnd.rn-realsystem-rjs\r\n";
		public static const M_rjt:String = "application/vnd.rn-realsystem-rjt\r\n";
		public static const M_rlc:String = "application/x-rlc\r\n";
		public static const M_rle:String = "application/x-rle\r\n";
		public static const M_rm:String = "application/vnd.rn-realmedia\r\n";
		public static const M_rmf:String = "application/vnd.adobe.rmf\r\n";
		public static const M_rmi:String = "audio/mid\r\n";
		public static const M_rmj:String = "application/vnd.rn-realsystem-rmj\r\n";
		public static const M_rmm:String = "audio/x-pn-realaudio\r\n";
		public static const M_rmp:String = "application/vnd.rn-rn_music_package\r\n";
		public static const M_rms:String = "application/vnd.rn-realmedia-secure\r\n";
		public static const M_rmvb:String = "application/vnd.rn-realmedia-vbr\r\n";
		public static const M_rmx:String = "application/vnd.rn-realsystem-rmx\r\n";
		public static const M_rnx:String = "application/vnd.rn-realplayer\r\n";
		public static const M_rp:String = "image/vnd.rn-realpix\r\n";
		public static const M_rpm:String = "audio/x-pn-realaudio-plugin\r\n";
		public static const M_rsml:String = "application/vnd.rn-rsml\r\n";
		public static const M_rt:String = "text/vnd.rn-realtext\r\n";
		//public static const M_rtf:String = "application/msword\r\n";
		public static const M_rtf:String = "application/x-rtf\r\n";
		public static const M_rv:String = "video/vnd.rn-realvideo\r\n";
		public static const M_sam:String = "application/x-sam\r\n";
		public static const M_sat:String = "application/x-sat\r\n";
		public static const M_sdp:String = "application/sdp\r\n";
		public static const M_sdw:String = "application/x-sdw\r\n";
		public static const M_sis:String = "application/vnd.symbian.install\r\n";
		public static const M_sisx:String = "application/vnd.symbian.install\r\n";
		public static const M_sit:String = "application/x-stuffit\r\n";
		public static const M_slb:String = "application/x-slb\r\n";
		public static const M_sld:String = "application/x-sld\r\n";
		public static const M_slk:String = "drawing/x-slk\r\n";
		public static const M_smi:String = "application/smil\r\n";
		public static const M_smil:String = "application/smil\r\n";
		public static const M_smk:String = "application/x-smk\r\n";
		public static const M_snd:String = "audio/basic\r\n";
		public static const M_sol:String = "text/plain\r\n";
		public static const M_sor:String = "text/plain\r\n";
		public static const M_spc:String = "application/x-pkcs7-certificates\r\n";
		public static const M_spl:String = "application/futuresplash\r\n";
		public static const M_spp:String = "text/xml\r\n";
		public static const M_ssm:String = "application/streamingmedia\r\n";
		public static const M_sst:String = "application/vnd.ms-pki.certstore\r\n";
		public static const M_stl:String = "application/vnd.ms-pki.stl\r\n";
		public static const M_stm:String = "text/html\r\n";
		public static const M_sty:String = "application/x-sty\r\n";
		public static const M_svg:String = "text/xml\r\n";
		public static const M_swf:String = "application/x-shockwave-flash\r\n";
		public static const M_tdf:String = "application/x-tdf\r\n";
		public static const M_tg4:String = "application/x-tg4\r\n";
		public static const M_tga:String = "application/x-tga\r\n";
		//public static const M_tif:String = "application/x-tif\r\n";
		public static const M_tif:String = "image/tiff\r\n";
		public static const M_tiff:String = "image/tiff\r\n";
		public static const M_tld:String = "text/xml\r\n";
		public static const M_top:String = "drawing/x-top\r\n";
		public static const M_torrent:String = "application/x-bittorrent\r\n";
		public static const M_tsd:String = "text/xml\r\n";
		public static const M_txt:String = "text/plain\r\n";
		public static const M_uin:String = "application/x-icq\r\n";
		public static const M_uls:String = "text/iuls\r\n";
		public static const M_vcf:String = "text/x-vcard\r\n";
		public static const M_vda:String = "application/x-vda\r\n";
		public static const M_vdx:String = "application/vnd.visio\r\n";
		public static const M_vml:String = "text/xml\r\n";
		public static const M_vpg:String = "application/x-vpeg005\r\n";
		public static const M_vsd:String = "application/vnd.visio\r\n";
		//public static const M_vsd:String = "application/x-vsd\r\n";
		public static const M_vss:String = "application/vnd.visio\r\n";
		//public static const M_vst:String = "application/vnd.visio\r\n";
		public static const M_vst:String = "application/x-vst\r\n";
		public static const M_vsw:String = "application/vnd.visio\r\n";
		public static const M_vsx:String = "application/vnd.visio\r\n";
		public static const M_vtx:String = "application/vnd.visio\r\n";
		public static const M_vxml:String = "text/xml\r\n";
		public static const M_wav:String = "audio/wav\r\n";
		public static const M_wax:String = "audio/x-ms-wax\r\n";
		public static const M_wb1:String = "application/x-wb1\r\n";
		public static const M_wb2:String = "application/x-wb2\r\n";
		public static const M_wb3:String = "application/x-wb3\r\n";
		public static const M_wbmp:String = "image/vnd.wap.wbmp\r\n";
		public static const M_wiz:String = "application/msword\r\n";
		public static const M_wk3:String = "application/x-wk3\r\n";
		public static const M_wk4:String = "application/x-wk4\r\n";
		public static const M_wkq:String = "application/x-wkq\r\n";
		public static const M_wks:String = "application/x-wks\r\n";
		public static const M_wm:String = "video/x-ms-wm\r\n";
		public static const M_wma:String = "audio/x-ms-wma\r\n";
		public static const M_wmd:String = "application/x-ms-wmd\r\n";
		public static const M_wmf:String = "application/x-wmf\r\n";
		public static const M_wml:String = "text/vnd.wap.wml\r\n";
		public static const M_wmv:String = "video/x-ms-wmv\r\n";
		public static const M_wmx:String = "video/x-ms-wmx\r\n";
		public static const M_wmz:String = "application/x-ms-wmz\r\n";
		public static const M_wp6:String = "application/x-wp6\r\n";
		public static const M_wpd:String = "application/x-wpd\r\n";
		public static const M_wpg:String = "application/x-wpg\r\n";
		public static const M_wpl:String = "application/vnd.ms-wpl\r\n";
		public static const M_wq1:String = "application/x-wq1\r\n";
		public static const M_wr1:String = "application/x-wr1\r\n";
		public static const M_wri:String = "application/x-wri\r\n";
		public static const M_wrk:String = "application/x-wrk\r\n";
		public static const M_ws2:String = "application/x-ws\r\n";
		public static const M_ws:String = "application/x-ws\r\n";
		public static const M_wsc:String = "text/scriptlet\r\n";
		public static const M_wsdl:String = "text/xml\r\n";
		public static const M_wvx:String = "video/x-ms-wvx\r\n";
		public static const M_x_b:String = "application/x-x_b\r\n";
		public static const M_x_t:String = "application/x-x_t\r\n";
		public static const M_xap:String = "application/x-silverlight-app\r\n";
		public static const M_xdp:String = "application/vnd.adobe.xdp\r\n";
		public static const M_xdr:String = "text/xml\r\n";
		public static const M_xfd:String = "application/vnd.adobe.xfd\r\n";
		public static const M_xfdf:String = "application/vnd.adobe.xfdf\r\n";
		public static const M_xhtml:String = "text/html\r\n";
		//public static const M_xls:String = "application/vnd.ms-excel\r\n";
		public static const M_xls:String = "application/x-xls\r\n";
		public static const M_xlw:String = "application/x-xlw\r\n";
		public static const M_xml:String = "text/xml\r\n";
		public static const M_xpl:String = "audio/scpls\r\n";
		public static const M_xq:String = "text/xml\r\n";
		public static const M_xql:String = "text/xml\r\n";
		public static const M_xquery:String = "text/xml\r\n";
		public static const M_xsd:String = "text/xml\r\n";
		public static const M_xsl:String = "text/xml\r\n";
		public static const M_xslt:String = "text/xml\r\n";
		public static const M_xwd:String = "application/x-xwd\r\n";
		public static const M_zip:String = "application/x-zip-compressed\r\n";
		
		public function Mime() 
		{
			
		}
		
	}

}


视频链接

======================================================================
所有 get-mv-info 前缀为: http://www.yinyuetai.com/main/

AKB48 - 真夏のSounds good !
get-mv-info?flex=true&sc=bacd04f73c560b6432c43e5e3c5c3eb9&t=4797407&v=1.8.2.2&videoId=398619
流畅 40MB http://hc.yinyuetai.com/uploads/videos/common/F466013AB6C9120E52E98349C292DE47.flv
高清 56MB http://hd.yinyuetai.com/uploads/videos/common/2C65013AD50F006FD35FE181C9551007.flv

AOA专访 - 王牌天使 怦然心动! 
get-mv-info?flex=true&sc=ee4fb9b09346bd933dd22e37fe978741&t=4797398&v=1.8.2.2&videoId=2344403
LT    50MB http://hc.yinyuetai.com/uploads/videos/common/3132014EF85A8CE3ADF791CC5E279802.flv
SD   71MB http://hd.yinyuetai.com/uploads/videos/common/757B014EF85F24E2341DCCA341D31C53.flv
HD  203MB http://he.yinyuetai.com/uploads/videos/common/1816014EF85F24DBDDA5B109E2710BA3.flv
VIP 398MB http://sh.yinyuetai.com/uploads/videos/common/EF43014EF85F24D5360F07B4721B30D6.mp4

AOA - 胸キュン 完整版
get-mv-info?flex=true&sc=02cdd2a81d89ce0fea835e1dd678bfdb&t=4797686&v=1.8.2.2&videoId=2340250
LT  http://hc.yinyuetai.com/uploads/videos/common/31E2014EDD026BFBF62BA8B5D17C5A76.flv
HD  http://hd.yinyuetai.com/uploads/videos/common/63EB014EDD6964447B14EE32E183CEEF.fl
FHD http://he.yinyuetai.com/uploads/videos/common/DD24014EDD69643E5090A131A6E2037B.flv
VIP http://sh.yinyuetai.com/uploads/videos/common/E761014EDD6964382D7A2B5F9C5FBEC9.mp4

少女时代 - Party - MBC 音乐中心 现场版 
get-mv-info?flex=true&sc=0295650498d599e87d08606efdc81e3a&t=4797689&v=1.8.2.2&videoId=2342124
http://hc.yinyuetai.com/uploads/videos/common/15B2014EEC958C659D81B6494BEF2229.flv
http://hd.yinyuetai.com/uploads/videos/common/BCF3014EECD1ADE87ACA388D99255D62.flv
http://he.yinyuetai.com/uploads/videos/common/D6CC014EECD1ADE1352C8903233358E6.flv
http://sh.yinyuetai.com/uploads/videos/common/7A7F014EECD1ADDA3FE62CEC444FE149.mp4

爱してる-- 高铃:
LT 26MB http://hc.yinyuetai.com/32A00127BA9B8DBB4FA3B950FEC648DF.flv

其它链接:
get-mv-info?flex=true&sc=f16935827aa59a8c6da702c0d0942c1b&t=4797690&v=1.8.2.2&videoId=121753
Visual Dreams-- 少女时代
get-mv-info?flex=true&sc=4ec07f9e6d21d1ee77c4b60fe4369ca0&t=4797691&v=1.8.2.2&videoId=2291949
君の第二章-- AKB48

这里是VIP展览,感受一下AOA的1080的超高清:

技术分享


参考资料

======================================================================
Network Sniffer and Connection Analyzer
http://www.codeproject.com/Articles/8254/Network-Sniffer-and-Connection-Analyzer
SharpPcap A Packet Capture Framework for NET
http://www.codeproject.com/Articles/12458/SharpPcap-A-Packet-Capture-Framework-for-NET
Getting the active TCP/UDP connections using the GetExtendedTcpTable function
http://www.codeproject.com/Articles/14423/Getting-the-active-TCP-UDP-connections-using-the-G
Getting active TCP/UDP connections on a box
http://www.codeproject.com/Articles/4298/Getting-active-TCP-UDP-connections-on-a-box
《【原创】Sysinternal出品工具TcpView的驱动逆向源代码》 vxasm
http://bbs.pediy.com/showthread.php?t=69543
Hessian Flash-only (不需要Flex框架支持):
http://hessian.caucho.com/download/hessian-flash-3_1-snap.swc
http://hessian.caucho.com/download/hessian-flex-3_1-snap-src.jar
其它相关工具下载
http://www.bizon.org/ilya/sniffer80.htm
https://github.com/PcapDotNet/Pcap.Net
http://sourceforge.net/projects/sharppcap/
http://hessian.caucho.com/#FlashFlex

版权声明:Jimbowhy原创文章,不得断根转载。

SWF代码分析与破解之路 (YueTai VIP视频信息获取工具) Socket续篇

标签:actionscript   mywife.cc   福利图   破解   air   

原文地址:http://blog.csdn.net/winsenjiansbomber/article/details/47436965

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!