-
-
[转帖]pdf2ceb源代码vc2010版 32位&64位编译
-
发表于: 2016-2-22 11:39 5704
-
/********************************************************************
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
}

赞赏
他的文章
赞赏
雪币:
留言: