您的位置:首页 > 其它

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

2012-12-05 12:48 295 查看
// 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐