我有一些仅用于资源的dll,我想将它们转换为十六进制格式* .cpp文件。稍后从* .cpp文件获取资源。但是,我不知道该怎么做。

这是* .cpp格式(样本格式)?

unsigned long g_XXXResourceMap[172] =
{
    0x7725,0xa,0x0,0xd21,0x7726, 0xa,0xd21,0xf99,0x7727, 0xa,0x1cba,0xe15,0x7728, 0xa,0x2acf,0xd7f,
    0x7729,0xa,0x384e,0xcf2,0x772a, 0xa,0x4540,0xc75,0x772b, 0xa,0x51b5,0x128a,0x772c, 0xa,0x643f,0xda1,
    0x772d,0xa,0x71e0,0xf51,0x7744, 0xa,0x8131,0xda5,0x7745, 0xa,0x8ed6,0xcc2,0x7746, 0xa,0x9b98,0xe18,
};

unsigned char g_XXXResourceArray[55001] =
{
    0x78,0x9c,0x1,0x16,0xd,0xe9,0xf2,0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,
    0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x18,0x0,0x0,0x0,0x18,
    0x8,0x6,0x0,0x0,0x0,0xe0,0x77,0x3d,0xf8,0x0,0x0,0x0,0x9,0x70,0x48,0x59,
    0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,
};

最佳答案

看看这个,我花了几个小时来实现它。注意:该代码使用C ++ 11,STL和Lambda。我使用Visual Studio 2010进行编译。
代码如下:

#include "stdafx.h"
#include "function.h"

/*
0: type
1: name
2: Lang
*/
typedef std::tuple<VARIANT, VARIANT, DWORD> resInfoTuple;

// Declare callback functions.
BOOL EnumTypesFunc(
    HANDLE hModule,
    LPTSTR lpType,
    LONG lParam);

BOOL EnumNamesFunc(
    HANDLE hModule,
    LPCTSTR lpType,
    LPTSTR lpName,
    LONG lParam);

BOOL EnumLangsFunc(
    HANDLE hModule,
    LPCTSTR lpType,
    LPCTSTR lpName,
    WORD wLang,
    LONG lParam);

void rawData2Hex(
    CCodec_ModuleMgr*,
    HMODULE hRes,
    std::wofstream& wofs,
    const wchar_t* wsInxAryName,
    const wchar_t* wsDataAryName,
    std::vector<resInfoTuple>& vecResInfo
    );

namespace omg
{
    int res2C(
        const wchar_t* szFileName,
        const wchar_t* wsInxAryName,
        const wchar_t* wsDataAryName,
        const wchar_t* outFileName
        )
    {
        // Load the .EXE whose resources you want to list.
        auto hRes = LoadLibrary(szFileName);
        if (hRes == NULL)
        {
            // Add code to fail as securely as possible.
            return -1;
        }

        std::wofstream wofs;
        std::vector<resInfoTuple>vecResInfo;

        CCodec_ModuleMgr *  pCodecModuleMgr = nullptr;
        CPDF_Document*      pDoc = nullptr;
        CPDF_Parser*        pParser = nullptr;

        //initialization
        pCodecModuleMgr = CCodec_ModuleMgr::Create();
        CFX_GEModule::Create();
        CFX_GEModule::Get()->SetCodecModule(pCodecModuleMgr);
        CPDF_ModuleMgr::Create();
        CPDF_ModuleMgr* pModule = CPDF_ModuleMgr::Get();
        if (pModule)
        {
            pModule->SetCodecModule(pCodecModuleMgr);
            pModule->InitPageModule();
            pModule->InitRenderModule();
        }

        auto bRes = EnumResourceTypes(hRes,  // module handle
            (ENUMRESTYPEPROC)EnumTypesFunc,  // callback function
            (LONG_PTR)&vecResInfo);          // extra parameter
        if(!bRes) return -1;

        wofs.open(outFileName, std::ios_base::ate/* | std::ios_base::binary*/);
        rawData2Hex(pCodecModuleMgr, hRes, wofs, wsInxAryName, wsDataAryName, vecResInfo);

        // Unload the executable file whose resources were
        // enumerated and close the file created to contain
        // the resource information.
        FreeLibrary(hRes);

        wofs.close();

        pCodecModuleMgr->Destroy();
        CFX_GEModule::Destroy();
        CPDF_ModuleMgr::Destroy();

        return 0;
    }//--end res2C

}//--end namespace::omg

//    FUNCTION: EnumTypesFunc(HANDLE, LPSTR, LONG)
//
//    PURPOSE:  Resource type callback
BOOL EnumTypesFunc(
    HANDLE hModule,   // module handle
    LPTSTR lpType,    // address of resource type
    LONG lParam)      // extra parameter, could be
    // used for error checking
{
    // Find the names of all resources of type lpType.
    EnumResourceNames((HMODULE)hModule,
        lpType,
        (ENUMRESNAMEPROC)EnumNamesFunc,
        lParam);

    return TRUE;
}

//    FUNCTION: EnumNamesFunc(HANDLE, LPSTR, LPSTR, LONG)
//
//    PURPOSE:  Resource name callback
BOOL EnumNamesFunc(
    HANDLE hModule,   // module handle
    LPCTSTR lpType,   // address of resource type
    LPTSTR lpName,    // address of resource name
    LONG lParam)      // extra parameter, could be
    // used for error checking
{
    // Find the languages of all resources of type
    // lpType and name lpName.
    EnumResourceLanguages((HMODULE)hModule,
        lpType,
        lpName,
        (ENUMRESLANGPROC)EnumLangsFunc,
        lParam);

    return TRUE;
}

//    FUNCTION: EnumLangsFunc(HANDLE, LPSTR, LPSTR, WORD, LONG)
//
//    PURPOSE:  Resource language callback
BOOL EnumLangsFunc(
    HANDLE hModule,  // module handle
    LPCTSTR lpType,  // address of resource type
    LPCTSTR lpName,  // address of resource name
    WORD wLang,      // resource language
    LONG lParam)     // extra parameter, could be
    // used for error checking
{
    std::vector<resInfoTuple>& vecResInfo = *(std::vector<resInfoTuple>*)lParam;
    HANDLE hResInfo;
    size_t cbString = 0;

    hResInfo = FindResourceEx((HMODULE)hModule, lpType, lpName, wLang);

    VARIANT varType = {0};
    VARIANT varName = {0};
    if ((ULONG)lpType & 0xFFFF0000)
    {
        varType.vt = VT_BSTR;
        varType.bstrVal = _bstr_t(lpType);
    }
    else
    {
        varType.vt = VT_UI2;
        varType.uiVal = (USHORT)lpType;
    }

    if ((ULONG)lpName & 0xFFFF0000)
    {
        varName.vt = VT_BSTR;
        varName.bstrVal = _bstr_t(lpName);
    }
    else
    {
        varName.vt = VT_UI2;
        varName.uiVal = (USHORT)lpName;
    }
    vecResInfo.push_back(std::make_tuple(varType, varName, wLang));

    return TRUE;
}

void rawData2Hex(
    CCodec_ModuleMgr* pCodecModuleMgr,
    HMODULE hRes,
    std::wofstream& wofs,
    const wchar_t* wsInxAryName,
    const wchar_t* wsDataAryName,
    std::vector<resInfoTuple>& vecResInfo)
{
    using namespace std;
    unsigned __int64  offset = 0;
    size_t lineFeedFlag = 1;

    wstringstream wss;
    wss << endl;
    std::vector<FX_BYTE> vecBytes;
    wss << L"unsigned long " << wsInxAryName << L"["
        //<< vecResInfo.size() * 4
        << "] = " << endl << "{" << endl;

    auto inxAry2Hex =
    [pCodecModuleMgr, &wss, &vecBytes, &hRes, &lineFeedFlag, &offset]
    (resInfoTuple& param, const wchar_t* format) mutable -> void
    {
        auto varType = std::get<0>(param);
        auto varName = std::get<1>(param);
        auto wLang = std::get<2>(param);

        bool bRawData = (VT_BSTR == varType.vt);
        HRSRC hResInfo = nullptr;
        hResInfo = FindResourceEx((HMODULE)hRes,
            bRawData ? (LPCTSTR)varType.bstrVal : (LPCTSTR)varType.uiVal,
            (VT_BSTR == varName.vt) ? (LPCTSTR)varName.bstrVal : (LPCTSTR)varName.uiVal, wLang);

        CString strOut;
        auto srcSize = SizeofResource(hRes, hResInfo);
        auto hData = LoadResource((HMODULE)hRes, hResInfo);
        auto pSrcData = (unsigned char*)LockResource(hData);

        FX_LPBYTE pDestBuf = nullptr;
        FX_DWORD destSize = 0;
        if(2 != varType.uiVal)
            FlateEncode(pSrcData, srcSize, pDestBuf, destSize);
        else
        {
            auto pBasicModule = pCodecModuleMgr->GetBasicModule();
            ASSERT(nullptr != pBasicModule);
            pBasicModule->RunLengthEncode(pSrcData, srcSize, pDestBuf, destSize);
        }

        vecBytes.insert(vecBytes.end(), pDestBuf, pDestBuf + destSize);

        UnlockResource(pSrcData);
        FreeResource(hData);

        /*name / id, type, offset, size*/
        strOut.Format(format, varName.uiVal, bRawData ? 10 : varType.uiVal, offset, destSize);
        if(1 == lineFeedFlag)
            wss << '\t';
        wss << strOut.GetBuffer();
        if(0 == lineFeedFlag % 2)
        {
            lineFeedFlag = 1;
            wss << std::endl;
        }else
            ++lineFeedFlag;

        offset += destSize;
    };
    if(vecResInfo.size() > 0)
    {
        auto& param = *vecResInfo.begin();
        inxAry2Hex(param, _T("0x%08x, 0x%08x, 0x%08llx, 0x%08x"));
    }

    for(auto iter = vecResInfo.begin() + 1; iter != vecResInfo.end(); ++iter)
    {
        auto& param = *iter;
        inxAry2Hex(param, _T(", 0x%08x, 0x%08x, 0x%08llx, 0x%08x"));
    }//--end for each(auto& param in vecResInfo)
    wss << endl << L"};" << endl << endl;

    lineFeedFlag = 1;
    wss << L"unsigned char " << wsDataAryName << L"["
        //<< vecBytes.size()
        << "] = " << endl << "{" << endl;

    if(vecBytes.size() > 0)
    {
        FX_BYTE param = *vecBytes.begin();
        CString strOut;
        strOut.Format(_T("0x%02x"), param);

        wss << '\t' << strOut.GetBuffer();

        ++lineFeedFlag;
    }
    for_each(vecBytes.begin() + 1, vecBytes.end(),
        [lineFeedFlag, &wss](FX_BYTE param) mutable
    {
        CString strOut;
        strOut.Format(_T(", 0x%02x"), param);
        if(1 == lineFeedFlag)
            wss << '\t';
        wss << strOut.GetBuffer();
        if(0 == lineFeedFlag % 21)
        {
            lineFeedFlag = 1;
            wss << std::endl;
        }else
            ++lineFeedFlag;
    }
    );//--end for_each

    wss << endl << L"};";

    wofs << L"extern const size_t " << wsInxAryName << L"Cnt = "
        << vecResInfo.size() * 4 << L";" << endl;

    wofs << L"extern const size_t " << wsDataAryName << L"Cnt = "
        << vecBytes.size() << L";" << endl;

    wofs << wss.str();
}

关于c++ - 如何将仅资源dll转换为十六进制格式* .cpp文件?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14119538/

10-09 07:14
查看更多