一个检测二进制文件内容的工具

// incorporate.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "assert.h"
#include "stdio.h"
#include<windows.h>
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
#include "jtzCompress.h"
#include "jtcCompress.h"

static bool checkContext(const char * fileName, const char * szCheck);
static bool checkIfDataHasStr(const char * fileName, const char * szCheck, Byte * pData, UInt32 nFileLen);

//单字节、双字节互转
static char * wstrTostr(const wchar_t * lpcwszStr){
    DWORD dwNum = WideCharToMultiByte(CP_OEMCP,NULL,lpcwszStr,-1,NULL,0,NULL,FALSE);
    char *psText = NULL;
    psText = new char[dwNum*sizeof(char)];
    if(!psText)
    {
        delete(psText);
        psText = NULL;
        return psText;
    }
    WideCharToMultiByte(CP_OEMCP,NULL,lpcwszStr,-1,psText,dwNum,NULL,FALSE);
    return psText;
}

static wchar_t * strToWstr(const char * lpcwszStr){
    DWORD dwNum = MultiByteToWideChar (CP_ACP, 0, lpcwszStr, -1, NULL, 0);
    wchar_t *psText = NULL;
    psText = new wchar_t[dwNum];;
    if(!psText)
    {
        delete(psText);
        psText = NULL;
        return psText;
    }
    MultiByteToWideChar (CP_ACP, 0, lpcwszStr, -1, psText, dwNum);  
    return psText;
}

ostream & green(ostream & s)
{
    HANDLE hstdhadle = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(hstdhadle, FOREGROUND_GREEN|FOREGROUND_INTENSITY);
    return s;
}

ostream & white(ostream & s)
{
    HANDLE hstdhadle = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(hstdhadle, FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY);
    return s;
}


class CFile{
private:
    fstream m_fout;

public:
    CFile(){
        m_fout.open("out.txt", ios::out | ios::binary);
    }

    //检查要测试文件的路径
    void checkFolder(const char* lpPath, const char * szCheck, bool bNeedCheckAllFile){
        assert(lpPath);

        char szFind[1024];
        char szFile[1024];
        WIN32_FIND_DATA FindFileData;
        strcpy_s(szFind,lpPath);
        strcat_s(szFind,"*.*");
        wchar_t * wszFind = strToWstr(szFind);
        HANDLE hFind=FindFirstFile(wszFind,&FindFileData);
        delete wszFind;
        if (INVALID_HANDLE_VALUE == hFind)
            return;

        bool bHasFileFinded = false;//如果有文件已经找到匹配了,不用全部文件遍历
        while(true)
        {
            if (FindFileData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
            {
                if (FindFileData.cFileName[0]!='.')
                {
                    strcpy_s(szFile,lpPath);
                    char * pFileName = wstrTostr(FindFileData.cFileName);
                    strcat_s(szFile,pFileName);
                    strcat_s(szFile,"\\");
                    delete pFileName;
                    checkFolder(szFile, szCheck, bNeedCheckAllFile);
                }
            }
            else if(bHasFileFinded == false || bNeedCheckAllFile == true)
            {
                char * pFileName = wstrTostr(FindFileData.cFileName);
                char pFilePath[1024] = {0};
                strcpy_s(pFilePath,lpPath);
                strcat_s(pFilePath,pFileName);
                bHasFileFinded = checkContext(pFilePath, szCheck);
                delete pFileName;
            }
            if (!FindNextFile(hFind,&FindFileData))
                break;
        }
        FindClose(hFind);

    }

    bool checkContext(const char * fileName, const char * szCheck)
    {
        fstream fin;
        bool bRet = false;
        if(ifFileTypeEqual(fileName, "jtz"))
        {
            Byte* fileContext = NULL;
            UInt32 nFileLen = 0;

            wchar_t * pFileName = strToWstr(fileName);
            fin.open(pFileName, ios::in | ios::binary);//防止有中文名

            fin.seekg(0, ios::end);
            nFileLen = fin.tellg();
            fileContext = new Byte[nFileLen];
            fin.seekg(0, ios::beg);
            fin.read((char*)fileContext, nFileLen);
            fin.close();

            Byte* unzipMem = NULL;
            UInt32 unzipSize = 0;
            Unzip(&unzipMem, &unzipSize, fileContext, nFileLen);
            delete fileContext;

            //检测
            bRet = checkIfDataHasStr(fileName, szCheck, unzipMem, unzipSize);
            delete unzipMem;
            delete pFileName;
            return bRet;
        }
        if(ifFileTypeEqual(fileName, "jtc"))
        {
            Byte* unzipMem = NULL;
            UInt32 unzipSize = 0;
            CJtcCompress * jtcInstance = new CJtcCompress(fileName);
            unzipMem = jtcInstance->Decode(unzipSize);
            delete jtcInstance;

            wchar_t * pFileName = strToWstr(fileName);

            //检测
            bRet = checkIfDataHasStr(fileName, szCheck, unzipMem, unzipSize);
            delete unzipMem;
            delete pFileName;
            return bRet;
        }
        //其他文件格式,直接用strstr即可
        if(ifFileTypeEqual(fileName, "ini")
            || ifFileTypeEqual(fileName, "cfg")
            || ifFileTypeEqual(fileName, "txt")
            || ifFileTypeEqual(fileName, "mod"))
        {
            Byte* unzipMem = NULL;
            UInt32 unzipSize = 0;

            wchar_t * pFileName = strToWstr(fileName);
            fin.open(pFileName, ios::in | ios::binary);//防止有中文名

            assert(fin);
            fin.seekg(0, ios::end);
            unzipSize = fin.tellg();
            unzipMem = new Byte[unzipSize];
            fin.seekg(0, ios::beg);
            fin.read((char*)unzipMem, unzipSize);
            fin.close();

            //检测
            bRet = checkIfDataHasStr(fileName, szCheck, unzipMem, unzipSize);
            delete unzipMem;
            delete pFileName;
            return bRet;
        }
        if(ifFileTypeEqual(fileName, "bar"))
        {
            char copyLocalCmd[512];
            char delLocalCmd[512];
            char brewrcCmd[512];
            const wchar_t * wszBarName = L"demo.bar";
            const wchar_t * wszBrxName = L"demo.brx";
            const char * szBarName = "demo.bar";

            wchar_t * pFileName = strToWstr(fileName);
            copyFileToOtherPath(pFileName, wszBarName);

            sprintf_s(brewrcCmd, 512, "brewrc.exe -d %s > 1.txt", szBarName);
            system(brewrcCmd);//执行Brew反解析工具

            DeleteFile(wszBarName);

            Byte* unzipMem = NULL;
            UInt32 unzipSize = 0;

            fin.open(wszBrxName, ios::in | ios::binary);//防止有中文名
            fin.seekg(0, ios::end);
            unzipSize = fin.tellg();
            unzipMem = new Byte[unzipSize];
            fin.seekg(0, ios::beg);
            fin.read((char*)unzipMem, unzipSize);
            fin.close();

            //检测
            bRet = checkIfDataHasStr(fileName, szCheck, unzipMem, unzipSize);
            delete unzipMem;
            delete pFileName;
            return bRet;
        }
        return bRet;
    }


    //判定文件后缀是否匹配
    bool ifFileTypeEqual(const char * fullName, const char * szCompare){
        assert(fullName && szCompare);

        bool bRet = false;
        string * str = new string(fullName);
        int nLen = str->find_last_of('.');
        if (nLen <= 0)
            bRet = false;
        else
        {
            const char * sz = fullName + nLen + 1;
            if(strcmp(sz, szCompare) == 0)
                bRet = true;
        }

        delete str;
        return bRet;
    }

    //判定文件后缀是否匹配
    const char * getBrxName(const char * fullName){
        assert(fullName);

        char * szRet = NULL;
        string * str = new string(fullName);
        int nLen = str->find_last_of('.');
        if (nLen > 0)
        {
            szRet = strdup(fullName);
            nLen++;
            szRet[nLen] = 'b';
            nLen++;
            szRet[nLen] = 'r';
            nLen++;
            szRet[nLen] = 'x';
        }

        delete str;
        return szRet;
    }


    void copyFileToOtherPath(const wchar_t * wszSrc, const wchar_t * wszDes)
    {
        assert(wszDes && wszSrc);
        fstream fin, fout;
        fin.open(wszSrc, ios::in | ios::binary);
        if(fin.is_open())
        {
            Byte * buf = NULL;
            UInt32 nFileLen = 0;

            fin.seekg(0, ios::end);
            nFileLen = fin.tellg();

            buf = new Byte[nFileLen];
            fin.seekg(0, ios::beg);
            fin.read((char *)buf, nFileLen);
            fin.close();

            fout.open(wszDes, ios::out | ios::binary);
            if (fout.is_open())
            {
                fout.write((char *)buf, nFileLen);
                fout.close();
            }
        }
    }


    bool checkIfDataHasStr(const char * fileName, const char * szCheck, Byte * pData, UInt32 nFileLen)
    {
        assert(pData && fileName && szCheck);

        bool bRet = false;

        UInt32 nCheckLen = strlen(szCheck);
        UInt32 nCheckOffest = 0;
        UInt32 nOffest = 0;

        while (nOffest < nFileLen){
            while(nOffest < nFileLen && pData[nOffest++] == szCheck[nCheckOffest++])
            {
                if(nCheckOffest == nCheckLen)
                {
                    const char * c_file = "文件:";
                    const char * c_have = "";
                    const char * c_changeline = "\r\n";

                    m_fout.write(c_file, strlen(c_file));
                    m_fout.write(fileName, strlen(fileName));
                    m_fout.write(c_have, strlen(c_have));
                    m_fout.write(szCheck, strlen(szCheck));
                    m_fout.write(c_changeline, strlen(c_changeline));
                    return true;
                }
            }
            nCheckOffest = 0;
        }

        cout << white << "检测文件:" << green << fileName << white << endl;

        return bRet;
    }


    ~CFile(){
        if(m_fout)
            m_fout.close();
    }
};

int main(int argc, char* argv[]/* f */)
{
    //说明
    if(argc >= 2 && strcmp(argv[1], "/?") == 0)
    {
        cout << "参数1:要检查的目录,以‘/’结束,如“Res/”" << endl;
        cout << "参数2:要检查的字符串" << endl;
        cout << "参数3(Y/N):是否检测到一个文件存在要查字符串,就不再查这个目录下的其他文件" << endl;
        cout << "目前会查的文件有:bar、jtz、jtc、mod、cfg、ini、txt" << endl;
        return 0;
    }

    CFile * pFile = new CFile();
    if(argc > 3)
    {
        if (toupper(*argv[3]) == 'Y')
            pFile->checkFolder(argv[1], argv[2], true);
        else
            pFile->checkFolder(argv[1], argv[2], false);
    }
    else
        pFile->checkFolder("res\\", "base_url", false);

    delete pFile;
    getchar();
    return 0;
}

 

posted @ 2012-12-05 12:48  何卫  阅读(505)  评论(0编辑  收藏  举报