安全类工具制作第002篇:U盘防火墙的制作

一、前言

我在上一篇文章中讨论了如何制作AutoRun.inf免疫程序,虽然这个免疫程序可以对所有的盘符有效,但是其实主要还是针对于U盘来进行防护的。由于目前新版的操作系统已经基本不支持AutoRun.inf,因此一般来说我们无需特别地关注这个问题。作为对U盘防御研究的收尾,这次我所讨论的是制作一个U盘防火墙。通过这个防火墙,当检测到有U盘插入时,则会产生提示,并且自动检查U盘中是否有AutoRun.inf文件,进行解析再进行删除操作,通过这个防火墙就可以安全地打开U盘。

其实现在很多杀毒软件都集成了这样的功能,当用户插入U盘后,杀软就会检测U盘的盘符,然后自动进行病毒木马的扫描,如下图所示:

图1 杀毒软件对U盘进行检测

我所制作的U盘防火墙虽然没有商业软件这么漂亮,功能也没有那么齐全,但是所运用的原理是相似的。而且随着讨论的深入,我的这些安全工具也会不断地进化,相信在不久的将来,其功能也能够基本达到专业软件的效果。

二、界面的制作

这个程序我依旧使用MFC制作,只需要在界面中添加一个按钮控件即可,如下图所示:

图2 界面的制作

盘符直接用一个对话框显示,无需在程序界面中画出来。只要在界面中设置一个“安全打开U盘”的按钮控件即可。为方便之后的操作,还需为按钮控件创建一个类型为“Control”,名称为“m_SafeOpen”的变量。

三、编写显示U盘盘符的代码

由于程序是在MFC下进行开发的,因此可以使用OnDeviceChange()这个消息响应函数。这里先来简单讲一下“映射机制”:

MFC使用一种消息映射机制来处理消息,在应用程序框架中的表现就是一个消息与消息处理函数一一对应的消息映射表,以及消息处理函数的声明和实现等代码。当窗口接收到消息时,会到消息映射表中查找该消息对应的消息处理函数,然后由消息处理函数进行相应的处理。SDK编程时需要在窗口过程中一一判断消息值进行相应的处理,相比之下MFC的消息映射机制要方便好用的多。

那么我们的第一步就是先在文件UFirewallDlg.cpp中添加一个消息映射:

BEGIN_MESSAGE_MAP(CUFireWallDlg, CDialog)
        //{{AFX_MSG_MAP(CUFireWallDlg)
        ON_WM_SYSCOMMAND()
        ON_WM_PAINT()
        ON_WM_QUERYDRAGICON()
        ON_BN_CLICKED(IDC_BTN_SAFEOPEN, OnBtnSafeopen)
        ON_MESSAGE(WM_DEVICECHANGE, OnDeviceChange)
        //}}AFX_MSG_MAP
END_MESSAGE_MAP()

接下来在头文件UFirewallDlg.h中的protected下,添加消息响应函数的定义:

// Generated message map functions
        //{{AFX_MSG(CUFireWallDlg)
        virtual BOOL OnInitDialog();
        afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
        afx_msg void OnPaint();
        afx_msg HCURSOR OnQueryDragIcon();
        afx_msg BOOL OnDeviceChange(UINT nEventType, DWORD dwData);
        afx_msg void OnBtnSafeopen();
        //}}AFX_MSG

之后添加获取盘符的代码:

void CUFireWallDlg::GetDriverName(DWORD dwData)
{
        PDEV_BROADCAST_HDR pDevHdr = (PDEV_BROADCAST_HDR)dwData;
        //如果设备类型为DBT_DEVTYP_VOLUME,则把当前结构体转换为
        //DBT_DEVTYP_VOLUME类型的结构体
        if ( pDevHdr->dbch_devicetype == DBT_DEVTYP_VOLUME )
        {
                //结构体转换
                PDEV_BROADCAST_VOLUME pDevVolume = (PDEV_BROADCAST_VOLUME)pDevHdr;
                //如果pDevVolume->dbcv_flags为0表示为可移动磁盘
                if ( pDevVolume->dbcv_flags == 0 )
                {
                        //通过将pDevVolume->dbcv_unitmask移位来判断逻辑盘符,
                        //第0位表示A盘,第1位表示B盘,依此类推。
                        DWORD dwUnitmask = pDevVolume->dbcv_unitmask;
                        //最多循环移动26位,因为至多有26位
                        for (i = 0; i < 26; ++i)
                        {
                                //因为新插入的可移动设备一定会是最后一个盘符的后一个,
                                //所以这里寻找dwUnitmask中的最低位数值为0x1的位。
                                if ( dwUnitmask & 0x1)
                                {
                                        //找到则跳出循环
                                        break;
                                }
                                //没找到则继续移位寻找
                                dwUnitmask = dwUnitmask >> 1;
                        }
                        //如果循环完26位依旧没找到,则返回
                        if ( i >= 26 )
                        {
                                return ;
                        }
                        //格式操作转化为字符串
                        DriverName.Format("%c:", i + 'A');
                }
        }
}

最后在头文件UFirewallDlg.h中的public下添加:

void GetDriverName(DWORD dwData);
CString DriverName;

需要说明的是,由于程序中使用了DBT_DEVTYP_VOLUME这样以DBT_开头的宏,所以一定要包含头文件“Dbt.h”。再定义一个字符型全局变量i用于保存可移动磁盘的盘符。至此,判断盘符的程序已经完成。编写完以上程序后,程序还不能运行的,因为我们还需完善OnDeviceChange()函数。

四、检测U盘中的AutoRun.inf文件

这里不再进行讲解,我已经在代码中添加了足够的注释:

BOOL CUFireWallDlg::OnDeviceChange( UINT nEventType, //An event type.
                                    DWORD dwData     //The address of a structure that contains event-specific data.
								  )
{
        //The system broadcasts the DBT_DEVICEARRIVAL device event when
        //a device or piece of media has been inserted and becomes available.
        if ( nEventType == DBT_DEVICEARRIVAL )
        {
                //获取盘符名称
                GetDriverName(dwData);
                //显示可移动磁盘的盘符,由于这里不是为了调试而显示,所以不使用AfxMessageBox()函数
                CString TmpFile;
                TmpFile.Format("检测到可移动磁盘为:%c", i + 'A');
                MessageBox(TmpFile);
                //如果成功获取盘符,则继续执行
                if ( DriverName != "" )
                {
                        //令"安全打开U盘"按钮可用
                        m_SafeOpen.EnableWindow(TRUE);
                        //创建CString类型的File,令其保存AutoRun.inf的完整路径
                        CString File = DriverName;
                        File += "\\AutoRun.inf";

                        char szBuff[MAX_PATH] = { 0 };
                        //判断可移动磁盘中的AutoRun.inf文件是否存在,不存在则令"安全打开U盘"按钮不可用
                        if ( GetFileAttributes(File.GetBuffer(0)) == -1 )
                        {
                                m_SafeOpen.EnableWindow(FALSE);
                                return FALSE;
                        }

                        //获取AutoRun.inf文件中open后面的内容,即所要自动打开的可疑文件
                        GetPrivateProfileString(
                                "AutoRun",              //The name of the section containing the key name.
                                "shell\\auto\\command", //The name of the key whose associated string is to be retrieved.
                                NULL,                   //A default string.
                                szBuff,                 //A pointer to the buffer that receives the retrieved string.
                                MAX_PATH,//The size of the buffer pointed to by the lpReturnedString parameter, in characters.
                                File.GetBuffer(0)       //The name of the initialization file.
                                );
                        //保存由AutoRun.inf启动的程序的路径
                        CString DelFile = DriverName;
                        DelFile += szBuff;

                        CString str;
                        str = "请选择是否删除可疑文件:";
                        str += szBuff;

                        if ( MessageBox(str, NULL, MB_YESNO) == IDYES )
                        {
                                //删除可移动磁盘中的AutoRun.inf以及由之启动的文件
                                DeleteFile(File);
                                DeleteFile(DelFile);
                        }
                }
        }
        //The system broadcasts the DBT_DEVICEREMOVECOMPLETE device event
        //when a device or piece of media has been physically removed.
        else if ( nEventType == DBT_DEVICEREMOVECOMPLETE )
        {
                //当U盘被拔出时,令"安全打开U盘"按钮不可用
                m_SafeOpen.EnableWindow(FALSE);
        }

        return TRUE;
}

程序可以检测U盘中是否存在AutoRun.inf文件,如果存在,则对其进行解析,找到其中所包含的欲运行的可疑程序,询问用户是否删除,若用户同意,则将二者删除。

五、编写按钮控件代码

由于使用了按钮控件的特殊效果,因此这里需要给按钮控件添加声明。找到文件UFirewallDlg.cpp,在BOOL CUFirewallDlg::OnInitDialog()中添加:

// TODO: Add extra initialization here
m_SafeOpen.EnableWindow(FALSE);

最后添加按钮控件代码:

void CUFireWallDlg::OnBtnSafeopen()
{
        // TODO: Add your control notification handler code here
        ShellExecute( NULL,                     //指定父窗口句柄
                      "open",                   //指定动作, 譬如: open、print、edit、explore、find
                      DriverName.GetBuffer(0),  //指定要打开的文件或程序
                      NULL,                     //给要打开的程序指定参数; 如果打开的是文件这里应该是NULL
                      NULL,                     //缺省目录
                      SW_SHOW                   //打开选项
                    );
}

至此所有代码编写完毕,接下来就是进行测试。

六、软件运行测试

为了测试我们的程序,这里我首先在U盘中编写一个AutoRun.inf程序:

[autorun]
shell\auto\command=Hacked.exe

然后放入我之前用于模拟病毒的对话框程序(详见《反病毒攻防研究》系列,或者建立一个空文件,命名为“Hacked.exe”也可)。之后运行U盘防火墙程序,再插入U盘,程序就能够检测到盘符:

图3 程序检测到盘符

单击“确定”按钮后,由于程序检测到了U盘中包含有“AutoRun.inf”程序,于是解析该程序中欲启动文件的文件名,之后弹出对话框,询问用户是否删除可疑文件:

图4 询问是否删除可疑文件

这里点击“是(Y)”以后,程序就会删除掉U盘中的AutoRun.inf文件以及欲由之运行的恶意程序。最后可以单击“安全打开U盘”按钮,来安全地打开U盘。

七、小结

由以上的分析可见,微软为我们提供了非常丰富的API函数以实现各种各样的功能。我们在实际的编程中,奉行的其实就是“拿来主义”,所以平时就需要多多积累。有一点需要说明的是,对于AutoRun.inf来说,为了实现恶意程序的启动,可能会使用“open”指令,如果这样,只要稍加改动上述程序即可。我也希望上述程序能够起到抛砖引玉的效果。

时间: 2024-10-14 06:09:01

安全类工具制作第002篇:U盘防火墙的制作的相关文章

安全类工具制作第001篇:制作AutoRun.inf免疫程序

一.前言 我曾经在<反病毒攻防研究第006篇:利用WinRAR与AutoRun.inf实现自启动>那篇文章中讨论过AutoRun.inf的原理与应对方法,作为对这个问题的收尾,我打算在此讨论一下如何利用MFC开发一个简单的免疫程序.尽管如今我们应该已经不会再受到AutoRun.inf的肆虐,但是这其中包含的很多思想依旧值得探讨.需要强调的是,这篇文章的重点在于预防,也就是在还没有受到AutoRun.inf的威胁时该如何给自己的计算机打预防针.如果计算机中了AutoRun.inf的破坏,可参考反

装机员U盘启动PE制作工具V5.0(UEFI+UD+首发自动安装MSDN版系统)

软件名称: 装机员U盘启动PE制作工具V5.0(UEFI+UD) 软件语言: 简体中文 软件大小: 288 大小: MB 发布日期: 2016-10-02 文件名称: ZhuangJiYuanPESetup_V5.0.exe M D 5: E8EBB32CB08E914F3C5E0B8BC1A4ACAB 软件封面: 迅雷下载: thunder://QUFodHRwOi8vZG93bi56aHVhbmdqaXl1YW4uY29tOjk1My9aaHVhbmdKaVl1YW5QRVNldHVwX1Y

中小企业openstack私有云布署实践【16.3 Windows Server2008 R2 只有C盘分区镜像制作】

之所以要只有C盘分区镜像,是因为在创建VM或者调整云主机的硬盘大小时,它能自动扩容.无需人工介入 参考http://www.iyunv.com/thread-45149-1-1.html的灵感 在原来的物理机10.40.41.1的CentOS 6.7上制作镜像. 宿主机坱要安装KVM相关软件: yum groupinstall Virtualization "Virtualization Client" -y yum install libvirt libguestfs-tools q

制作U-boot ---AT91SAM9260篇

制作U-boot ---AT91SAM9260篇 0.制作交叉编译链请看<ARM交叉编译工具制作V2> ---------------------------------------------------转载请注明:xiaobin_hlj80---- 1.烧写boot-uboot 查看AT91SAM9260芯片文档,关于内存部分 P19– 6221s.pdf(http://www.atmel.com/zh/cn/devices/SAM9260.aspx?tab=documents) 起始地址

如何制作Ubuntu SDK Live USB盘

对于一些想开发Ubuntu手机应用或Scope的开发者来说,不想重新买一个电脑安装Ubuntu操作系统或在自己的硬盘上重新安装一个Ubuntu系统,那么可以考虑制作一个Ubuntu系统的Live USB盘.这个USB包括如下的部分: Ubuntu Kylin 14.10操作系统 Ubuntu SDK (包括已经安装好的SDK,模拟器及编译环境) 使用这个Live USB盘,开发者就不用安装任何的东西,直接插入电脑的USB口中.在电脑启动的过程中,选择我们制作好的USB启动盘进行启动(在电脑启动的

纯windows下制作变色龙引导安装U盘教程

原创教程:纯windows下制作变色龙引导安装U盘教程 支持Mavericks和Yosemite 支持白苹果 目标:windows下制作带 Chamelon变色龙引导的黑苹果安装U盘,支持PC机引导安装,经测试同样支持真苹果安装. 制作工具:1.bootice1.32.windows版变色龙 wowpc.iso 2391支持 10.10引导(可以随时更新)3.懒人版安装镜像 Mavericks_Install_10.9.4.cdr(可以选择其它版本)硬件需要:大于或等于8G U盘一个.标注:以最

谁说NTFS不支持UEFI启动的?启动U盘放不了超过4G的文件怎么办?Server2016 Win10 U盘UEFI启动制作方法

大家都知道,我们平时做启动盘,用得最多的就是UltraISO(软碟通)这个工具了.用它我们可以很简单快速的把一个空白的普通U盘制作成一个PE启动U盘或系统U盘,然后用它来安装系统非常的方便,受到了广大用户的喜爱. Fat32不支持4G以上文件 但是用它制作的启动盘都是Fat32格式的,而我们都知道Fat32格式是不支持4G以上的文件的,现在我们使用的64位win10系统就超过了4G,还有合集版等系统也是超过4G的.如果我们要使用安装这些系统怎么办呢? 今天,我们教大家另外一种制作方法,只需换一个

【翻译】圣斗士星矢:圣域传说 制作介绍 场景篇

背景布置 这里是背景舞台布置的制作介绍. 圣斗士的发源地[圣域],来看看成为黄金十二宫标准的狮子宫, 以及相对的最异端的存在的巨蟹宫的制作工程吧. 从Pre-production到正式制作 包含破坏模型 140个布景的制作 本作的背景制作是2011年末开始的.到2013年1月由约10名制作了总计140多个的场景(包含丢弃场景总数250多).Concept Work的开始是从2011年中旬,由从OVA[鸦 KARAS](2005? 2007)开始就负责很多さとうけいいち監督作品美术的佐藤肇氏来做美

【翻译】圣斗士CG动画电影制作介绍 角色篇

日本独自的CG动画新方案 圣斗士星矢 LEGEND of SANCTUARY 传说的超人气作品在时隔10年后完全新作的剧场长篇中复苏.这次,关于本作和主流动画CG的有明显区别的,独特的画面制作方法,由さとうけいいち监督(译注:没查出汉字)和核心工作人员毫无保留的讲述的了. 角色的开发 因全CG的剧场动画作品而引发很大话题的本作,关于担当制作的东映动画数字影响部分的具体的制作方法. 首先是因为3DCG而变化的青铜圣斗士们的Modeling和Setup以及Gimmick的表现. 角色设计 主要角色设