用户
搜索
  • TA的每日心情
    郁闷
    2017-5-15 13:44
  • 签到天数: 21 天

    连续签到: 1 天

    [LV.4]偶尔看看III

    i春秋签约作家

    蜂巢网络安全

    Rank: 7Rank: 7Rank: 7

    9

    主题

    129

    帖子

    76

    魔法币
    收听
    1
    粉丝
    2
    注册时间
    2016-6-2

    i春秋签约作者

    发表于 2017-8-4 12:53:54 102328
                         模糊测试之AVI文件分析
    AVI的基本概念
    1. 什么是AVI
    AVI是音频视频交错(Audio Video Interleaved)的英文缩写,它是Microsoft公司开发的一种符合RIFF文件规范的数字音频与视频文件格式,原先用于Microsoft Video for Windows (简称VFW)环境,现在已被Windows 95/98、OS/2等多数操作系统直接支持。
    2. AVI格式的优缺点
    图像质量好、可跨平台使用、体积庞大、压缩标准不统一。
    3. AVI的文件结构
    AVI是符合RIFF文件规范的数字音频与视频文件格式,在介绍AVI文件前,我们要先来看看RIFF文件结构。AVI文件采用的是RIFF文件结构方式,RIFF(Resource Interchange File Format,资源互换文件格式)是微软公司定义的一种用于管理windows环境中多媒体数据的文件格式,波形音频wave,MIDI和数字视频AVI 都采用这种格式存储。构造RIFF文件的基本单元叫做数据块(Chunk),每个数据块包含3个部分:4字节的数据块标记(或者叫做数据块的ID)、数据块的大小、数据。整个RIFF文件可以看成一个数据块,其数据块ID为RIFF,称为RIFF块。
    一个RIFF文件中只允许存在一个RIFF块。RIFF块中包含一系列的子块,其中有一种字块的ID为"LIST",称为LIST,LIST块中可以再包含一系列的子块,但除了LIST块外的其他所有的子块都不能再包含子块。RIFF和LIST块分别比普通的数据块多一个被称为形式类型(Form Type)和列表类型(List Type)的数据域,其组成为: 4字节的数据块标记(Chunk ID)、数据块的大小、4字节的形式类型或者列表类型、数据。
    下面我们看看AVI文件的结构。AVI文件是目前使用的最复杂的RIFF文件,它能同时存储同步表现的音频视频数据。AVI的RIFF块的形式类型是AVI,它包含3个子块,如下所述:
    (1)信息块,一个ID为"hdrl"的LIST块,定义AVI文件的数据格式。
    (2)数据块,一个ID为 "movi"的LIST块,包含AVI的音视频序列数据。
    (3)索引块,ID为 "idxl"的子块,定义 "movi"LIST块的索引数据,是可选块。
    AVI文件的结构如下图所示,下面将具体介绍AVI文件的各子块构造。                                                   图片1.png
    AVIBMP的关系       一个AVI文件是由多个BMP文件构成。如下图:
                 2.png
    VI视频序列中的“帧”即为位图。
    AVI视频序列中的“帧”的数量和位图数量是对应的。


    三.分析analysis目录里AVI操作函数的写法
    目录 “Easy_BMP2AVI”   
    在此目录下运行如下:
           图片3.png
    上图的一些命令是用来合成avi的,在一下函数的调用:
    cvLoadImage:从文件中读取图像 。
    cvCreateVideoWriter:创建视频文件写入器 。
    cvWriteFrame:写入一帧到一个视频文件中。
    cvGetCaptureProperty:获得视频获取结构的属性,如视频序列的帧数等。
    cvCaptureFromFile 为从文件中读取而打开文件
    cvQueryFrame从摄像头或者文件中抓取并返回一帧
    可以很方便的把BMP合成AVI。一下是合成的过程:
           图片4.png

    最终可以打开结果看一下:
           图片5.png
    OpenCV 及MFC实现AVI的合成和分解
    1. 创建一个MFC对话框应用程序(Dialog-based Application),在名称栏输入创建项目的名称,点击“确定”。
    2. 在出现的“MFC应用程序向导”对话框内,选择“基于对话框”,并取消“使用Unicode库(N)”其他选项不做修改,单击“下一步”如下图
           图片6.png
    3.一直点击“下一步”到“生成的类”对话框,选择基类为“CDialog”单击完成即可创建一个MFC对话框。如下图 :
           7.png
    4.删除“TODO:在此放置对话框控件。”、“确定”和“取消”控件。然后点击“工具”中的“Button”添加以下五个控件并改名。结果如下下图:
          8.png
    5. 接着点击属性栏中的“控制事件“按钮 ,弹出如下对话框:
          9.png
    选择 10.png 分别添加
    OnBnClickedButton1()•••OnBnClickedButton5()
    6. 在工具箱中点击 11.png 在图中添加后如下图:
        12.png
    7. 在工具箱中点击“Group Box” ,从左上角往右下角拖拉到 “开始分解”止,同时修改其属性栏里的 的“静态”为“AVI的合成”,完成后如图:
        13.png
    同理可得完成下一部分:
           14.png
    8. 依次右击“示例编辑框”按钮分别添加变量,如图:
          15.png
    变量名分别为m_1, m_2, m_3, m_4。

    9.在“解决方案资源管理器下”打开“BY_MFC_YJCDlg.h”,在“#pragma one”下面添加:
    [HTML] 纯文本查看 复制代码
    #include "cv.h"
    #include "highgui.h"
    #include "cxcore.h"
    #include <stdio.h>
    #include "shlwapi.h"
    #include <direct.h>
    #include <io.h>
    #include <vector>
    using namespace std;
    #define UM_PROGRESS WM_USER+1
    10.在最后的“}”内添加:
     afx_msg LRESULT Onrogress(WPARAM, LPARAM);
    public:
            char* choisebmppath(HWND hWnd,CHAR *szTitle, CHAR *szPath);
    public:
            int bmptoavi();
    public:
            afx_msg void OnBnClickedButton10();
    
            void GetFile(CString sPath, vector<CString> *filePaths);
            CString getFileExt(CString filePath);
            BOOL __cdecl isSameType (char *Ext,const char *format, ...);
    
    11.打开源文件“BY_MFC_YJCDlg.cpp”,在“#ifdef_DEBUG”上添加:
    
    #include <stdlib.h>
    
    在 “#endif”下添加:
    CString bmp_path1;
    CString bmp_path;//bmp路径(hecheng)
    CString AviFileName;//AVIL路径
    CString AVI_path;
    int i = 1;
    //int bmptoavi(LPVOID lpParameter);//shengming
    CEdit dlg;
    
    12.在“END_MESSAGE-MAP()”的上面和 
    下面添加:
    ON_MESSAGE(UM_PROGRESS,Onrogress)
    13.在下面添加:
     char* COPENCV_AVI_BMPDlg::choisebmppath(HWND hWnd,CHAR *szTitle, CHAR *szPath)//获得文件夹
    {
            BROWSEINFO bi;
            LPCITEMIDLIST pItemIDList;
            bi.hwndOwner = AfxGetMainWnd()->GetSafeHwnd();
            bi.pidlRoot = NULL;
            bi.pszDisplayName = szPath;
            bi.lpszTitle = szTitle;
            bi.ulFlags = BIF_RETURNONLYFSDIRS;
            bi.lpfn = NULL;
            bi.iImage = 0;
            pItemIDList = SHBrowseForFolder(&bi);
            if(NULL == SHGetPathFromIDList(pItemIDList, szPath) )
            {
              AfxMessageBox("路径为获取");
            }
            return (char*)szPath;
    }
    
    14.在OnBnClickedButton2()下添加:
     if (0 == m_1.GetWindowTextLength())
            {
                    AfxMessageBox("please CHOISE bmp_filename!");
                    exit(1);
            }
            if (0 == m_1.GetWindowTextLength())
            {
                    AfxMessageBox("please INPUT bmp_filename!");
                    exit(1);
            }
        //AfxBeginThread((AFX_THREADPROC)bmptoavi, (void*)this);
            PostMessage(UM_PROGRESS);
            bmptoavi();
    }
    
    int COPENCV_AVI_BMPDlg::bmptoavi()
    {
            CString FileName;
        CvVideoWriter *writer;
        IplImage *frame;
            vector<CString> imgFilePaths;
    
            GetDlgItemText(IDC_EDIT1,bmp_path);//BMP的文件路径
    
            GetFile(bmp_path, &imgFilePaths);
    
            for (int i=0 ;i< imgFilePaths.size();++i)
            {        
                    frame = cvLoadImage(imgFilePaths.at(i).GetBuffer());
                    if(i == 0)
                    {
                            int AviForamt = -1;//设置压缩格式
                            int FPS = 25;
                            int AviColor = 1;
                            writer=cvCreateVideoWriter(AviFileName,-1,FPS,cvGetSize(frame),AviColor);
                    }
                    cvWriteFrame(writer,frame);
                    cvWaitKey(1);
    
                    cvReleaseImage(&frame);
            }
            cvReleaseVideoWriter(&writer);        
            return 0;
    }
    
    /*
    * 功能:获取文件夹下的所有图片文件
    */
    void COPENCV_AVI_BMPDlg::GetFile(CString sPath, vector<CString> *filePaths)
    {
            if (sPath.IsEmpty())
            {
                    return;
            }
            CFileFind   ff;
            CString                szDir = sPath;
            CString                Ext;
    
            if(szDir.Right(1) != "\\")
                    szDir += "\\";
    
            szDir += "*.*";
    
            BOOL res = ff.FindFile(szDir);
            while( res )
            {
                    res = ff.FindNextFile();
    
                    CString sFileName;
                    if (ff.IsDirectory() && !ff.IsDots())//文件夹
                    {
                            CString sFilePath = ff.GetFilePath();
                            sFileName = ff.GetFileTitle();
                            GetFile(sFilePath, filePaths);
                    }
                    else if (!ff.IsDirectory() && !ff.IsDots())//文件
                    {
                            CString   strFilePath = ff.GetFilePath();
                            Ext = getFileExt(ff.GetFilePath());
                            if (isSameType(Ext.GetBuffer(),"ss","bmp","jpg"))
                            {
                                    filePaths->push_back(strFilePath);
                            }
                    }
            }
    
            ff.Close(); 
    }
    
    CString COPENCV_AVI_BMPDlg::getFileExt(CString filePath)
    {
            filePath.ReleaseBuffer();
            int pos = filePath.ReverseFind('.');
            if (pos >= 0)
            {
                    return filePath.Right(filePath.GetLength() - pos -1);
            }
    }
    BOOL __cdecl COPENCV_AVI_BMPDlg::isSameType (char *Ext,const char *format, ...) 
    { 
            va_list ap; 
    
            int                buffing; 
            int                retval;
            char        ch;
    
            char        *ext;
    
            va_start(ap, format);
            _ASSERTE(format != NULL);
    
            ext = strlwr(Ext);
    
            while(ch = *(format++))
            {
                    switch(ch)
                    {
                    case 's':
                            {
                                    char *p = va_arg(ap, char *);
                                    if (0 == strcmp(Ext,p))
                                    {
                                            return 1;
                                    }
                                    break;
                            }
                    default:
                            {
                                    printf("input parameter is error \n");
                                    return -1;
                            }
                            break;
                    }
            }
            return(0);
    
    15.在OnBnClickedButton1()下添加:
     
    char path[MAX_PATH];
            choisebmppath(m_hWnd,"bmp文件夹",path);
        bmp_path = path;
            SetDlgItemText(IDC_EDIT1,bmp_path);
            AviFileName = "E:\\avi.avi";
            SetDlgItemText(IDC_EDIT2,"E:\\avi.avi");
    16.在OnBnClickedButton3()下添加:
     
    CFileDialog dlg(true,NULL,NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,NULL,NULL,0);
            if(!dlg.DoModal())
            {
                    AfxMessageBox("创建失败");
                    exit(1);
            }
            AVI_path = dlg.GetPathName();
            SetDlgItemText(IDC_EDIT3,AVI_path);
    }
    
    LRESULT  COPENCV_AVI_BMPDlg::Onrogress(WPARAM, LPARAM)
    {
            pgctrl.OffsetPos(2);
            pgctrl.SetStep(1);//设置步长
            pgctrl.SetRange32(1,1000);
            pgctrl.SetPos(i);
            pgctrl.SetBkColor(RGB(255, 0, 0));
            pgctrl.StepIt();//让进度条动起来
            return 1;
    
    17.在OnBnClickedButton4()下添加:
    
    if (m_3.GetWindowTextLength() == 0)
        {
            AfxMessageBox("AVI文件出错");
            exit(1);
        }
        CvCapture *capture;
        IplImage *frame;
        capture = cvCaptureFromAVI(AVI_path);
        CString FileName;
        CString strtemp;
        CString newFileName;
        int i=1;
    
        UpdateData(FALSE);
        for (i = 1;i<101;i++)
        {
            FileName.Format("Frame-%03d.bmp", i);
    
            if (i==1)
            {
                GetDlgItemText(IDC_EDIT4,strtemp);
            }
    
            newFileName = strtemp + FileName;
    
            frame = cvQueryFrame(capture);
    
            if (!cvSaveImage( newFileName,frame))
            {
                AfxMessageBox("提取失败");
            }
    
            cvWaitKey(1);
    }
    }

    然后修改相应位置的所有“COPENCV-AVI-BMPDlg”为“C(工程名)Dlg”。并且在“项目属性”的“附加依赖项”添加 “cv.lib highgui.lib cvaux.lib cxcore.lib运行 得:
           16.png
    五.实验心得与总结
    本次试验主要是针对AVI的处理,了解AVI的基本概念,并且掌握AVI文件常用的程序读写方法。
       知道AVI视频文件的帧的读取方法,以及了解BMP和AVI的基本关系。

    由于试验目的需要对一些代码的理解,对C++有更深度的认识,建议各位同学多看一些有关C++的内容。以更深一步的理解Opencv的机制与功能,将Opencv透彻的系统学习,加深对其的理解。

    蜂巢网安团队招人,招收对象:各大src排行榜,安全领域安全研究成员。QQ群:613097965.


    本帖被以下淘专辑推荐:

    阿甫哥哥 管理员 i春秋最帅男神-阿甫大哥哥 楚 核心白帽 i春秋签约作者 白帽传说 春秋游侠 秦 燕 魏
    来自 11#
    发表于 昨天 22:23
    文章奖励介绍及评分标准:http://bbs.ichunqiu.com/thread-7869-1-1.html,如有疑问请加QQ:286894635!
    奖金
    点评
    50
    技术理论性很强,感谢分享

    Time will give me the answer
    使用道具 举报 回复
    six six six six six six six six
    使用道具 举报 回复
    发表于 2017-8-4 13:51:20
    AVI的格式和mp4的码流不同,所以用一些东西渲染出来的avi文件会达到G的级别,另一方面,一些电影的录制的时候  出来的就是 avi文件,而且其中的分辨率,音频保真度都是比较好的 ,最典型的例子就是,岛国的小视频,那叫一个逼真啊,
    ——蜂巢网安-屌丝绅士
    做自己的自己 和平年代的炮灰,战争年代的爆破鬼才
    使用道具 举报 回复
    天天表哥666
    使用道具 举报 回复
    发表于 2017-8-4 13:53:27

    天天表哥666
    使用道具 举报 回复
    发表于 2017-8-4 13:54:14
    使用道具 举报 回复
    发表于 2017-8-5 18:52:36
    天天了解的面真广
    xss  交流群602221356  接收XSS爱好者
    使用道具 举报 回复
    发表于 2017-8-5 19:06:35
    天天表哥666
    使用道具 举报 回复
    发表于 2017-8-9 09:46:34
    很棒的fuzz文章精彩支持
    使用道具 举报 回复
    发表于 2017-8-10 10:12:31
    表哥66                     
    使用道具 举报 回复
    发新帖
    您需要登录后才可以回帖 登录 | 立即注册