MFC —— 资源文件释放(为了程序更简洁)

应用场景:

  病毒木马会广泛常用资源文件释放技术。程序会将一些DLL文件、文本文件、图片文件或其它的音/视频文件作为资源插入到程序里,等到程序运行后,使用资源文件释放技术将它们释放到本地上,这样编译出来的程序只有一个exe文件,而不需要附带其它文件,因而程序变得简洁,降低了被发现的风险。

资源插入的步骤:

  介绍资源文件释放技术之前,先要了解如何向程序中插入资源。毕竟没有资源,你释放光和热吗?资源插入不需要编码操作,只需要手动设置VS开发环境即可完成。操作如下:   

     (1).解决方案中,选择 “添加”,选中 “资源”

       

   (2).在弹出对话框中选择 “自定义(C)...”按钮,如下图所示:

  

   (3).在 “新建自定义资源” 对话框中,输入 “资源类型” ,建议输入有意思的类型名,如 “MYRES"(我的资源),然后点击确定。

  

   (4).通过上面步骤设置好自定义资源的类型后,接着回到 ”添加资源“对话框,选中刚新建的自定义资源类型 ”MYRES",然后单击右侧的 ”导入(M)...”按钮来选中导入文件

  

 资源文件释放实现原理:

  (1).通过FindResource定位程序里的资源,获取资源信息块的句柄。主要是根据 “资源类型” 和 “资源名称” 进行定位。

  (2).根据上面获取的资源信息块的句柄,使用SizeOfResource获取资源的大小

  (3).根据 (1) 步获得的资源信息块的句柄,使用LoadResource把资源加载到程序内存中

  (4).根据上一步返回的数据资源句柄,使用LockResource锁定加载到内存中的资源,防止程序中的其它操作影响这块内存,返回值就是资源在进程内存中的起始地址

  (5).最后根据第二步获得的资源大小以及第四步获得的资源在进程内存中的起始地址,使用文件写函数fwrite将资源读取出来并保存为本地文件

  注意:在资源释放过程中,必须明确资源所在的模块,要指明资源所在模块句柄并且统一。因为文件可以以资源的形式插入到dll中,所以当dll加载到其它进程时,资源所在的模块仍是该dll模块。要想成功释放资源,需要先通过GetModuleHandle函数获取该DLL模块的句柄。否则,资源释放会因为指定了错误模块而失败。

   

代码实现:

//************************************
// 函数名:  CBasicsDlg::FreeMyResource
// 返回类型:   BOOL
// 功能:释放资源将资源保存为文件
// 参数1: 资源名
// 参数2: 资源类型
// 参数3: 文件名
//************************************

BOOL CBasicsDlg::FreeMyResource(UINT uiResourceName, char* lpszResourceType, char* lpszSaveFileName)
{
    //获取指定模块里的资源
    HRSRC hRsrc = FindResource(GetModuleHandle(NULL), MAKEINTRESOURCE(uiResourceName), (LPCWSTR)lpszResourceType);
    if (NULL == hRsrc)
    {
        m_FreeResTipMsg += _T("获取资源")+ CString(lpszSaveFileName)+_T("失败
");
        return FALSE;
    }
    else
    {
        m_FreeResTipMsg += _T("获取资源") + CString(lpszSaveFileName) + _T("成功
");
    }
    //获取资源大小
    DWORD dwSize = SizeofResource(NULL, hRsrc);
    if (dwSize <= 0)
    {
        m_FreeResTipMsg += _T("获取") + CString(lpszSaveFileName) + _T("资源大小失败
");
        return FALSE;
    }
    else
    {
        m_FreeResTipMsg += _T("获取") + CString(lpszSaveFileName) + _T("资源大小成功
");
    }
    //将资源加载到内存里
    HGLOBAL hGlobal = LoadResource(NULL, hRsrc);
    if (NULL == hGlobal)
    {
        m_FreeResTipMsg += _T("资源") + CString(lpszSaveFileName) + _T("加载到内存失败
");
        return FALSE;
    }
    else
    {
        m_FreeResTipMsg += _T("资源") + CString(lpszSaveFileName) + _T("加载到内存成功
");
    }
    //锁定资源
    LPVOID lpVoid = LockResource(hGlobal);
    if (NULL == lpVoid)
    {
        m_FreeResTipMsg += _T("资源") + CString(lpszSaveFileName) + _T("锁定失败
");
        return FALSE;
    }
    else
    {
        m_FreeResTipMsg += _T("资源") + CString(lpszSaveFileName) + _T("锁定成功
");
    }
    //保存资源为文件
    FILE* fp = NULL;
    fopen_s(&fp, lpszSaveFileName,"wb+");
    if (NULL == fp)
    {
        m_FreeResTipMsg += _T("创建文件") + CString(lpszSaveFileName) + _T("失败
");
        return FALSE;
    }
    DWORD res = fwrite(lpVoid, sizeof(char), dwSize, fp);
    if (res != dwSize)
    {
        m_FreeResTipMsg += _T("资源") + CString(lpszSaveFileName) + _T("保存为文件时有数据丢失
");
        fclose(fp);
        return FALSE;
    }
    else
    {
        m_FreeResTipMsg += _T("资源") + CString(lpszSaveFileName) + _T("成功保存为文件
");
        fclose(fp);
        return TRUE;
    }

}
原文地址:https://www.cnblogs.com/ndyxb/p/12881373.html