-
-
[转帖]pdf2ceb源代码vc2010版 32位&64位编译
-
发表于: 2016-2-22 11:39 5392
-
/******************************************************************** 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 }
赞赏
他的文章
看原图
赞赏
雪币:
留言: