首页
社区
课程
招聘
[转帖]pdf2ceb源代码vc2010版 32位&64位编译
发表于: 2016-2-22 11:39 5428

[转帖]pdf2ceb源代码vc2010版 32位&64位编译

2016-2-22 11:39
5428
/********************************************************************
	created:	2015/12/19
	created:	19:12:2015   9:59
	filename: 	D:\work\pdf2ceb\pdf2ceb\pdf2ceb.cpp
	file path:	D:\work\pdf2ceb\pdf2ceb
	file base:	pdf2ceb
	file ext:	cpp
	author:		ceb2pdf
	
	purpose:	
*********************************************************************/

#include "stdafx.h"
#include <iostream> 
#include <string>
#include <vector> 
using namespace std;

#pragma  pack (push,1)	// 单字节对齐  


#define IV_SIZE			8
// 索引类型
#define CEB_INDEXTYPE_PDFDATA				0x01				// 作为文件内核的PDF数据
#define CEB_INDEXTYPE_RC4KEY				0x03				// 对PDF数据进行RC4加密的密钥
#define CEB_INDEXTYPE_CSENCRYPTKEY			0x04				// 对PDF数据中的内容流进行加密的密钥
#define CEB_INDEXTYPE_CSENCRYPTALGORITHMID	0x05				// 对PDF数据中的内容流进行加密时采用的加密算法
#define CEB_INDEXTYPE_DOCINFO				0x10				// 文档相关信息


const char* DES_KEY		= 			"123456789012345678901234"; // 必须24字节
const char* RC4_KEY		=			"0123456789abcdef";			// 必须16字节


// ceb文件头结构
typedef struct __tagCEBFILEHEADER
{
	BYTE szHeaderInfo[16];					// 版权版本信息
	DWORD dwIndexTableLength;				// 索引表长度
	WORD wIndexCount;						// 索引个数
} CEBFILEHEADER;

// 索引结构
typedef struct __tagCEBINDEXITEM
{
	BYTE byIndexType;						// 索引类型
	BYTE byPlugInID[8];						// 插件ID
	DWORD dwOffsetPos;						// 字节偏移量
	DWORD dwDataBlockLength;				// 数据块长度
} CEBINDEXITEM;

typedef struct __tagCEBDOCINFOA
{
	WORD wVersion;
	CHAR szCreator[15];
	BYTE byCreateDate[8];
	CHAR szLastModifier[15];
	BYTE byLastModifyDate[8];
	CHAR szOS[20];
	WORD wLanguage;
} CEBDOCINFOA;

// rc4
typedef struct __tagRC4KEY
{      
	BYTE state[256];       
	BYTE x;        
	BYTE y;
} RC4KEY;
class CRC4CryptoEngine
{
public:
	CRC4CryptoEngine() {}
	virtual ~CRC4CryptoEngine() {}

protected:
	RC4KEY m_RC4Key; 	// RC4的加密/解密密钥



public:
	void InitialRC4Crypto(LPBYTE lpbyKey, BYTE byKeyLen)    // 初始化
	{
		// Create Seed
		BYTE pbySeed[256];

		for (BYTE i = 0; i < byKeyLen; i++)
		{
			pbySeed[i]  = lpbyKey[i];
			pbySeed[i] |= 0xAA;
		}

		// Prepare RC4 Key
		BYTE byT;
		BYTE byIndex1 = 0;
		BYTE byIndex2 = 0;
		BYTE byCounter;
		BYTE *pbyState;

		pbyState = &m_RC4Key.state[0];
		byCounter = 0;
		while (TRUE)
		{
			pbyState[byCounter] = byCounter;
			if (byCounter == 255) 
				break;
			else
				byCounter++;
		}                

		m_RC4Key.x = 0;
		m_RC4Key.y = 0;

		byCounter = 0;
		while (TRUE)
		{
			byIndex2 = (BYTE)(((int)pbySeed[byIndex1] + pbyState[byCounter] + byIndex2) % 256);

			byT = pbyState[byCounter];
			pbyState[byCounter] = pbyState[byIndex2];
			pbyState[byIndex2] = byT;

			byIndex1 = (BYTE)(((int)byIndex1 + 1) % byKeyLen);

			if (byCounter == 255) 
				break;
			else
				byCounter++;
		}
	}


	void RC4Crypto(LPBYTE lpbyCryptoText, DWORD dwTextLen)
	{
		BYTE byT, byX, byY;
		BYTE byXorIndex;

		BYTE *pbyState;

		byX = m_RC4Key.x;
		byY = m_RC4Key.y;

		pbyState = &m_RC4Key.state[0];
		for (DWORD dwCounter = 0; dwCounter < dwTextLen; dwCounter++)
		{
			byX = (BYTE)(((int)byX + 1) % 256);
			byY = (BYTE)(((int)pbyState[byX] + byY) % 256);

			byT = pbyState[byX];
			pbyState[byX] = pbyState[byY];
			pbyState[byY] = pbyState[byT];

			byXorIndex = (BYTE)(((int)pbyState[byX] + pbyState[byY]) % 256);
			lpbyCryptoText[dwCounter] ^= pbyState[byXorIndex];
		}               

		m_RC4Key.x = byX;
		m_RC4Key.y = byY;
	}
};
//////////////////////////////////////////////////////////////////////////



BOOL pdf2ceb(const char* szInFileName, const char* szOutFileName = NULL)
{

	BOOL bRet = FALSE;
	if(!szInFileName)
		return bRet;
//	const char* Encry1 = "/Encrypt 9999999 0 R\r";
//	const char* Encry2 = "9999999 0 obj<</Filter /EBX_FOUNDER/R 4/V 3/Length 128>>endobj\r";


	CFile pdfFile;
	if (!pdfFile.Open(szInFileName, CFile::modeRead | CFile::shareDenyWrite))
		return bRet;
	DWORD dwPDFDataLength = (DWORD)pdfFile.GetLength();

	// CreateFileMapping
	HANDLE hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE,
		0,
		PAGE_READWRITE,
		0,
		0x40000000,		// 创建个1G的内存映射文件
		NULL);
	if (hMapFile == NULL || hMapFile == INVALID_HANDLE_VALUE)
	{
		pdfFile.Close();
		return bRet;
	}

	LPVOID lpFile = (LPBYTE)MapViewOfFile(hMapFile,FILE_MAP_READ|FILE_MAP_WRITE,0,0,0);
	if (lpFile == NULL)
	{
		pdfFile.Close();
		CloseHandle(hMapFile);
		return bRet;
	}
	pdfFile.Read(lpFile, dwPDFDataLength);
	pdfFile.Close();

	LPBYTE pBuffer = (LPBYTE)lpFile ;


	// 判断是否pdf文件
	if (memcmp(pBuffer, "%PDF", 4) )
	{
		if (lpFile)
		{
			UnmapViewOfFile(lpFile);

		}
		if (hMapFile)
		{
			CloseHandle(hMapFile);

		}
		return bRet;
	}

	// 将整个pdf用RC4加密
	CRC4CryptoEngine objTmpRC4;
	objTmpRC4.InitialRC4Crypto((LPBYTE)RC4_KEY, strlen(RC4_KEY));
	CRC4CryptoEngine objRC4;
	DWORD dwLen = 0,dwPDFLen = dwPDFDataLength;
	int nCount = 0;
	while (dwPDFLen > 0)
	{
		dwLen = 65536;
		if (dwPDFLen < 65536)
		{
			dwLen = dwPDFLen;
		}
		memcpy(&objRC4, &objTmpRC4, sizeof(CRC4CryptoEngine));
		objRC4.RC4Crypto(pBuffer + nCount*65536, dwLen);
		if (dwPDFDataLength < 65536)
		{
			break;
		}
		dwPDFLen -= dwLen;
		nCount++;
	}
	// create CEB file
	CFile cebfile;
	CString strCEBFileName = szOutFileName;
	CString strPDFFileName = szInFileName;
	if (strCEBFileName.IsEmpty())
	{
		strCEBFileName = strPDFFileName.Left(strPDFFileName.GetLength() - 4);
		strCEBFileName += ".ceb";

	}
	DeleteFile(strCEBFileName);

	if (!cebfile.Open(strCEBFileName, 
		CFile::modeReadWrite|CFile::shareDenyWrite|CFile::modeCreate))
	{
		goto _Exit;
	}
	// 写ceb文件头和索引表
	CEBFILEHEADER cfh ;
	ZeroMemory(&cfh, sizeof(CEBFILEHEADER));
	memcpy(cfh.szHeaderInfo, "Founder CEB", 11);		// 版权信息
	cfh.szHeaderInfo[14]	= 3;
	cfh.szHeaderInfo[15]	= 99;

	cfh.wIndexCount			= 5;						// 索引表的个数为4
	cfh.dwIndexTableLength	= 5 * sizeof(CEBINDEXITEM);	// 索引表的长度
	cebfile.SeekToBegin();
	cebfile.Write((LPVOID)&cfh, sizeof(CEBFILEHEADER));



	CEBINDEXITEM cii_pdfdata;
	cii_pdfdata.byIndexType	= CEB_INDEXTYPE_PDFDATA;
	memset(cii_pdfdata.byPlugInID, 0, 8);
	cii_pdfdata.dwDataBlockLength	= dwPDFDataLength;
	cii_pdfdata.dwOffsetPos			= sizeof(CEBFILEHEADER) + cfh.dwIndexTableLength;
	cebfile.Write((LPVOID)&cii_pdfdata, sizeof(CEBINDEXITEM));

	CEBINDEXITEM cii_rc4key;
	cii_rc4key.byIndexType	= CEB_INDEXTYPE_RC4KEY;
	memset(cii_rc4key.byPlugInID, 0, 8);
	cii_rc4key.dwDataBlockLength	= 16;
	cii_rc4key.dwOffsetPos			= cii_pdfdata.dwDataBlockLength + cii_pdfdata.dwOffsetPos;
	cebfile.Write((LPVOID)&cii_rc4key, sizeof(CEBINDEXITEM));

	
	CEBINDEXITEM cii_csencryptalgorithmid;
	cii_csencryptalgorithmid.byIndexType	= CEB_INDEXTYPE_CSENCRYPTALGORITHMID;
	memset(cii_csencryptalgorithmid.byPlugInID, 0, 8);
	cii_csencryptalgorithmid.dwDataBlockLength	= 4;
	cii_csencryptalgorithmid.dwOffsetPos		= cii_rc4key.dwDataBlockLength + cii_rc4key.dwOffsetPos;
	cebfile.Write((LPVOID)&cii_csencryptalgorithmid, sizeof(CEBINDEXITEM));

	CEBINDEXITEM cii_csencryptkey;
	cii_csencryptkey.byIndexType	= CEB_INDEXTYPE_CSENCRYPTKEY;
	memset(cii_csencryptkey.byPlugInID, 0, 8);
	cii_csencryptkey.dwDataBlockLength	= 24;
	cii_csencryptkey.dwOffsetPos		= cii_csencryptalgorithmid.dwDataBlockLength + cii_csencryptalgorithmid.dwOffsetPos;
	cebfile.Write((LPVOID)&cii_csencryptkey, sizeof(CEBINDEXITEM));

	CEBINDEXITEM cii_docinfo;
	cii_docinfo.byIndexType	= CEB_INDEXTYPE_DOCINFO;
	memset(cii_docinfo.byPlugInID, 0, 8);
	cii_docinfo.dwDataBlockLength	= sizeof(CEBDOCINFOA);
	cii_docinfo.dwOffsetPos		= cii_csencryptkey.dwDataBlockLength + cii_csencryptkey.dwOffsetPos;
	cebfile.Write((LPVOID)&cii_docinfo, sizeof(CEBINDEXITEM));

	// 写处理后的pdf数据到ceb
	cebfile.Write(pBuffer, dwPDFDataLength);
	
	// 写rc4的key	
	cebfile.Write(RC4_KEY, 16);
	
	// 写加密类型
	DWORD dwCsencryptalgorithmid = 0;
	cebfile.Write(&dwCsencryptalgorithmid, sizeof(DWORD));
	
	// 写des的key
	cebfile.Write(DES_KEY, 24);
	
	// 写docinfo
	CEBDOCINFOA di;
	memset(&di, 0, sizeof(CEBDOCINFOA));
	memcpy_s(di.szCreator, 15, "pdf2ceb", 7);
	memcpy_s(di.szOS, 20, "WIN7_PRO_X64", 12);
	memcpy_s(di.szLastModifier, 15, "QQ694285177", 11);
	di.wVersion = 1;
	di.wLanguage = 1;
	cebfile.Write(&di, sizeof(CEBDOCINFOA));

	// 关闭文件
	cebfile.Close();
	bRet = TRUE;

	// 关闭pdf文件

_Exit:
	if (lpFile)
	{
		UnmapViewOfFile(lpFile);

	}
	if (hMapFile)
	{
		CloseHandle(hMapFile);

	}
	return bRet;
}
#pragma  pack (pop)  



void DoCmd(std::string& strCmd)
{
	if (strCmd == "help")
	{
		cout <<endl<< "用法:"<<endl<<endl<<"convert[c] pdffile cebfile" << endl<<endl;
		cout <<"1.输入输出文件名路径不能有空格!" << endl <<endl;
		cout <<"2.输出文件名可以忽略,默认生成同名ceb文件!" << endl <<endl;
		cout <<"3.convert命令可以用c代替!" << endl <<endl;
		return;
	}
	std::vector<std::string> str_list; // 存放分割后的字符串
	int comma_n = 0;
	do
	{
		std::string tmp_s = "";
		comma_n = strCmd.find( " " );
		if( -1 == comma_n )
		{
			tmp_s = strCmd.substr( 0, strCmd.length() );
			str_list.push_back( tmp_s );
			break;
		}
		tmp_s = strCmd.substr( 0, comma_n );
		strCmd.erase(0, comma_n+1);
		str_list.push_back( tmp_s );
	}
	while(true);

	int i = str_list.size();
	if ((str_list[0] == "convert" || str_list[0] == "c")&& i >= 2)
	{
		BOOL bRet = FALSE;
		if (i == 2)
		{
			bRet = pdf2ceb(str_list[1].data());
		}
		else
		{
			bRet = pdf2ceb(str_list[1].data(), str_list[2].data());
		}
		
		
		if (bRet)
		{
			cout<<endl<<"done!"<<endl<<endl;
		}
		else
		{
			cout<<endl<<"error!"<<endl<<endl;
		}
	}
	else
	{
		cout <<endl<< "Please type \"help\" to usag and type \"exit\" to exit." << endl<<endl;

	}
	return ;
}

int _tmain(int argc, _TCHAR* argv[])
{


#if 0
	printf("将要转换的pdf文件是%s\n\n",argv[1]);
	// system("PAUSE");
	//// 成功返回1,失败返回0
	BOOL bRet = pdf2ceb(argv[1]);
	printf("\n转换结果:	%d\n\n",bRet);
	//system("PAUSE");
	return 0;
#else
	string strCmd;
	char buf[1024] = {0};
	while ( strCmd != "quit" && strCmd!= "exit")
	{
		cout << "pdf2ceb>" ;
		gets_s(buf);
		strCmd = buf;
		DoCmd(strCmd);
	}
	return 0;
#endif
}


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 0
支持
分享
最新回复 (1)
雪    币: 220
活跃值: (248)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2

我按着代码编译成了exe文件,试着转了一个pdf,但没有ceb2pdf,没法验证是否正确,你帮忙看看行吗?

上传的附件:
2020-5-3 18:49
0
游客
登录 | 注册 方可回帖
返回
//