| 常見(jiàn)電子書(shū)格式及其反編譯思路 作者:馬健 主頁(yè):http://stronghorse.yeah.net 電郵:stronghorse@tom.com 版本:1.00 日期:2004.05.30 聲明: 本文可能夾雜大量技術(shù)術(shù)語(yǔ),如果您對此感到不快,請勿繼續閱讀。 本文僅僅討論一些思路,不會(huì )提供相關(guān)源代碼,最多也只提供源代碼網(wǎng)站的鏈接。如果您對此有所不滿(mǎn),請勿繼續閱讀。 本文僅僅從技術(shù)角度討論電子書(shū)反編譯問(wèn)題,請勿將之用于侵犯版權等等非法目的,或損害他人利益。如果您對此感到失望,請勿繼續閱讀。 本文版權歸作者所有,轉載前請先征得作者書(shū)面同意。 1. 前言 2. 常見(jiàn)電子書(shū)格式及其反編譯思路 2.1 PDF格式 2.2 基于IE內核的電子書(shū) 2.2.1 CHM格式 2.2.2 EXE格式 2.2.2.1 Web Compiler 1.67 2.2.2.2 Caislabs eBook Pack Express 1.6 2.2.2.3 通用反編譯思路 2.3 HLP格式 2.4 小說(shuō)網(wǎng)/小說(shuō)世界(ebx/XReader) 3. 結論 附錄 基于IE內核電子書(shū)的實(shí)現方式探討 1. 前言 本文所描述的電子書(shū),指的是將原始的、可編輯的HTML、TXT、RTF、圖像文件等,打包成一個(gè)獨立的EXE,或其它只有專(zhuān)用瀏覽器才能讀取的文件,打包后的文件通常不可用常規工具進(jìn)行編輯、全文檢索。 本文所描述的電子書(shū)反編譯,指的是將電子書(shū)中的內容提取出來(lái),還原或轉換成標準的、可編輯的HTML、TXT、RTF及圖像文件等。 就像世間其它事物一樣,電子書(shū)編譯器和反編譯器的出現也都不是偶然的,都有其必然性。 在電子書(shū)編譯器這一方來(lái)說(shuō),大概從有電子文檔那天開(kāi)始,就有人琢磨著(zhù)要對電子文檔打包了。我個(gè)人認為這主要是從以下幾個(gè)方面進(jìn)行考慮: 便于閱讀、管理。當年在DOS下閱讀文本文件,尤其是中文文件比較麻煩,因此出現了自帶中文字庫、自帶基本瀏覽(翻頁(yè)、滾動(dòng))功能的DOS電子書(shū);由于需要在不同OS平臺上獲得相同的閱讀效果,因此產(chǎn)生了跨平臺的PDF格式電子書(shū);隨著(zhù)互聯(lián)網(wǎng)絡(luò )的發(fā)展,大量信息以HTML格式出現,但是面對一大堆HTML文件,并不是每個(gè)人都知道該去雙擊index.htm或default.htm的,而且文件太多,管理也成問(wèn)題,因此出現了CHM格式和各種基于IE內核的EXE格式電子書(shū)。 便于保護知識產(chǎn)權、商業(yè)機密。這個(gè)問(wèn)題的重要性相信大家現在都能理解了,不要說(shuō)那些包含核心商業(yè)機密的東西,就算是區區一本小說(shuō),都會(huì )有些卑鄙小人把原始的HTML、TXT文件拿去加LOGO、打包,然后聲稱(chēng)是自己“辛苦掃校的成果”,再堂而皇之地收取所謂“VIP費用”。因此PDF一直將文檔安全性作為賣(mài)點(diǎn)之一,國內的各種獨門(mén)格式電子書(shū)也以防反編譯、防內容復制為首要目標。 而反對將通用格式打包成獨門(mén)格式的人,當然也有自己的道理: 便于全文檢索。如前所述,電子書(shū)一般不可用通常的檢索工具進(jìn)行全文檢索,這就為資料的有效利用設置了障礙。我個(gè)人認為,藏書(shū)量在幾十本、上百本的時(shí)候,手工建立摘要、索引可能還可以接受;再多以后,我想要的就只是一個(gè)快速的全文檢索工具,就好像在互聯(lián)網(wǎng)環(huán)境下,對google的依賴(lài)一樣。 便于修改。俗話(huà)說(shuō):“金無(wú)足赤,人無(wú)完人”,電子書(shū)也是人做的,有時(shí)難免會(huì )出點(diǎn)什么錯,或者因為資訊的發(fā)展,需要對原有內容加以修正、補充,這個(gè)時(shí)候如果面對的是一個(gè)不可編輯的EXE,您會(huì )有什么感想? 節省時(shí)間和耐心。Windows在顯示文件列表的時(shí)候,需要讀取文件信息,EXE文件還要讀取ICON等,如果裝有反病毒軟件,進(jìn)入文件夾的時(shí)候,反病毒軟件一般還會(huì )自動(dòng)對文件夾中的EXE文件進(jìn)行自動(dòng)檢查,而電子書(shū)大小一般都在MB級,因此打開(kāi)包含EXE格式電子書(shū)的時(shí)候,感覺(jué)速度巨慢,比較令人反感。 節省空間。一般EXE格式電子書(shū)的標準架構是:可執行體+內容+TOC??蓤绦畜w指的是電子書(shū)的執行代碼部分,包括程序代碼、插件代碼、界面資源等。內容指的是電子書(shū)中真正包含的文本、圖像內容,一般使用某種壓縮、加密算法進(jìn)行處理。TOC(Table Of Content)相當于目錄索引,作用是加速對內容的訪(fǎng)問(wèn)。因此相對于直接用WinZip、WinRAR對原始內容進(jìn)行壓縮,每一本EXE格式的電子書(shū)都會(huì )浪費一部分磁盤(pán)空間,以存儲執行體部分。電子書(shū)的軟件界面越花哨,這種浪費一般也越大,我見(jiàn)過(guò)最夸張的電子書(shū)比原始內容足足多出 1 MB多的東西。 避免垃圾。對于某些基于IE內核的電子書(shū)來(lái)說(shuō),由于實(shí)現技術(shù)的限制,可能會(huì )在注冊表和系統目錄下留下垃圾。 安全。如果說(shuō)如今的網(wǎng)絡(luò )社會(huì )是一個(gè)充滿(mǎn)惡意、毫無(wú)誠信的環(huán)境,可能有點(diǎn)夸張了,不過(guò)確實(shí)有人不知“做人要厚道”為何物。老實(shí)說(shuō),每次拿到一個(gè)來(lái)路不明的EXE格式的電子書(shū)的時(shí)候,我都在懷疑里面有沒(méi)有什么木馬、病毒,實(shí)在難受。 便于平臺轉換,包括轉換到手持設備。EXE格式的電子書(shū)看起來(lái)可能很爽,但是畢竟只能在Windows下看,如果想在其它系統下看,尤其是在手持設備上看,唯一的出路就是反編譯了它。 當然,在反編譯后,也必須尋找合適的替代品,以繼續滿(mǎn)足原先的需要: 打包工具。建議選擇Winzip或WinRAR,不僅使用方便,而且打包后文件也小,進(jìn)入目錄還快。 閱讀工具?,F在可以不解包就直接閱讀zip/rar文件內容的軟件不少,一搜一大把,我自己都做過(guò)一個(gè)MyReader,不僅可以直接從ZIP/RAR中讀取內容,還有自動(dòng)定位index.htm、書(shū)簽、現場(chǎng)保護、資源瀏覽器右鍵菜單擴展、zip/rar密碼自動(dòng)記憶等功能。 全文檢索工具??梢灾苯釉趜ip/rar中全文檢索的軟件也有不少,我自己也做過(guò)一個(gè)FindStr,支持加密zip/rar,這個(gè)工具還可以與MyReader集成,搜索結果可以直接用MyReader直接打開(kāi),不需解包。另外它還支持批量文本替換,所以也經(jīng)常被我用來(lái)整理下載到的或反編譯出來(lái)的小說(shuō),包括去除廣告鏈接、絕對URL改成相對URL等。 對勞動(dòng)成果的保護。這個(gè)直接用zip/rar的密碼保護就好。 2. 常見(jiàn)電子書(shū)格式及其反編譯思路 2.1 PDF格式 PDF格式是Adobe公司推出的一種跨平臺電子文檔格式,Adobe公司提供專(zhuān)用的文檔瀏覽器,使用戶(hù)可以在不同平臺下獲得相同的閱讀效果。 其實(shí)Adobe公司提供的PDF編輯工具--Adobe Acrobat本身,就已經(jīng)支持將PDF文件另存為RTF格式,因此我對PDF的反編譯研究不多。不過(guò)這個(gè)功能似乎受到“文檔安全性”的限制,好在我google了一下,破解PDF安全保護的軟件似乎不少。如果真的對批量轉換有興趣,在codeproject上也有一篇文章,提供將PDF轉換成純文本的源代碼。 從我使用的情況看,Adobe Acrobat本身輸出的RTF格式,對英文文檔來(lái)說(shuō)應該沒(méi)有什么太大的問(wèn)題,頂多是格式有點(diǎn)變化,但是在輸出中文文檔的時(shí)候,偶爾會(huì )因為字符集代碼錯誤,導致輸出的文件在Word、寫(xiě)字板中打開(kāi)的時(shí)候,只能看到一堆亂碼。對于這種情況,手工替換一下字符集編碼即可解決。 出現亂碼還有一種可能就是PDF文件中使用了自定義的字庫,導致轉換出來(lái)后的文件無(wú)法正常顯示,這個(gè)比較麻煩。PDF文件自帶字庫有兩種方式:自帶一種完整的字庫,稱(chēng)為font embedding;只自帶一種字庫中要用到的那幾個(gè)字符,稱(chēng)為font subsetting。在e類(lèi)出版物論壇的“圖書(shū)制作、閱讀工具區”對此有過(guò)討論,需要的可以自己去看。 不過(guò)有一次我試著(zhù)用過(guò)一個(gè)叫PDF2Html的軟件,這個(gè)軟件的思想是將PDF文件的每一頁(yè)轉換成一個(gè)JPG文件,然后將JPG文件封裝到HTML文件里,加上目錄、翻頁(yè)按鈕等,這樣在網(wǎng)絡(luò )瀏覽的時(shí)候,連客戶(hù)端的Acrobat Reader及客戶(hù)端字體支持都可以省了。這個(gè)軟件的HTML文件模板做得怎樣先不去說(shuō)它,最令我奇怪的是,轉換出來(lái)的圖像格式只能是JPG,不能是PNG。其實(shí)對于有大片白色背景的頁(yè)面來(lái)說(shuō),使用PNG格式不僅文件長(cháng)度比JPG小,而且不會(huì )象JPG格式一樣,在文字、圖像邊緣產(chǎn)生許多細小的碎片(高次雜波)。 2.2 基于IE內核的電子書(shū) 隨著(zhù)互聯(lián)網(wǎng)的發(fā)展,現在越來(lái)越多的網(wǎng)絡(luò )文檔內容是以HTML格式提供的,而微軟本身又以控件的形式提供了IE瀏覽器的內核,可以很方便地被幾乎所有Windows下的編程工具所調用,因此目前基于IE內核的電子書(shū)似乎占據了主流位置。 2.2.1 CHM格式 CHM(發(fā)音為“chum”)的原意是Compiled HTML help file,是微軟作為HLP格式(16位Windows下的標準幫助文件格式)的替代格式提出的,因此微軟自己不僅隨4.01以上版本的IE一起提供免費的瀏覽器,而且免費提供制作工具M(jìn)icrosoft HTML Help Workshop。 CHM文件內部使用ITS格式,這是一種非常優(yōu)秀的壓縮格式,感覺(jué)壓縮比要比zip、rar大。 由于ITS格式的開(kāi)放性,國外早就有人做出了CHM格式的獨立編譯、反編譯工具,并且公開(kāi)了全部源代碼,需要的人可以到這里看: http://bonedaddy.net/pabs3/hhm/ 這個(gè)網(wǎng)站除了提供CHM編譯、反編譯工具及其源代碼外,還提供CHM格式的詳細說(shuō)明,當然是英文的。我做的UnEBook在開(kāi)始的時(shí)候,就使用了其中chmdeco的源代碼,實(shí)現批量反編譯CHM的功能。如果這個(gè)網(wǎng)站不幸登錄不了,google一下chmdeco就好,有很多備份站點(diǎn)的。chmdeco內部使用的是chmlib的源代碼,這份源代碼很有名,除chmdeco外,chmtools用的也是它。 不過(guò)在使用了一段時(shí)間后,我發(fā)現這份代碼在反編譯某些CHM文件的時(shí)候,會(huì )出現數組越界錯誤。這種錯誤出現的概率雖然不大,但是出現后還是比較心煩,因此最終放棄了這份代碼。 現在UnEBook使用的CHM反編譯代碼是從這里改出來(lái)的: http://www.codeproject.com/winhelp/htmlhelp.asp 這份代碼使用了微軟未公開(kāi)的ITS文件訪(fǎng)問(wèn)接口,直接對文件進(jìn)行操作。由于使用的都是微軟的東西,不僅目標碼比較小,兼容性也好得多,目前還沒(méi)有遇到反編譯不出來(lái)的CHM文件(唯一的一次例外,是那個(gè)CHM文件本身就打不開(kāi)),內存漏洞什么的也沒(méi)有發(fā)現??磥?lái)微軟的東西還是要由微軟來(lái)對付,方為王道。 另外某些人制作CHM電子書(shū)的時(shí)候,為了省事,沒(méi)有制作index.htm,而是單純依賴(lài)左側的目錄樹(shù)進(jìn)行導航。對于這樣的電子書(shū),在反編譯后,一般還需要根據生成的hcc文件,自動(dòng)生成一個(gè)索引頁(yè),以免看的時(shí)候不方便。hcc文件結構大致如下: 多級目錄通過(guò)<UL>控制,見(jiàn)到<UL>的時(shí)候往下走一級目錄,</UL>往回走一級。 目錄項以<OBJECT type="text/sitemap">開(kāi)始,以</OBJECT>結束。以<PARAM NAME="Name" VALUE="xxx">存放項名稱(chēng),<PARAM NAME="Local" VALUE="xxx.html">存放項鏈接。 某些目錄項可能只有名稱(chēng),沒(méi)有鏈接。 在UnEbook中,不僅能夠根據hcc文件自動(dòng)生成索引頁(yè),還能自動(dòng)生成框架頁(yè),將索引頁(yè)和顯示頁(yè)嵌入框架中,以最大限度模仿CHM中的目錄效果。如果要完全模仿能夠動(dòng)態(tài)伸縮的樹(shù)形目錄效果,則需要增加圖片、js、css等文件,實(shí)在得不償失。 2.2.2 EXE格式 除了CHM格式外,大量基于IE內核的電子書(shū)是以EXE格式提供的。制作EXE格式的電子書(shū)工具現在似乎已成為一個(gè)產(chǎn)業(yè),養活了大批的程序員。雖然很多人認為這種格式的電子書(shū)很酷:一個(gè)文件就可以執行,界面也可以做得很漂亮,還可以帶密碼保護。但是我個(gè)人對這種格式的電子書(shū)是最最痛恨的:除了前面說(shuō)到的安全性、速度、空間、檢索等問(wèn)題外,我最心煩的一點(diǎn)是目前的EXE電子書(shū)都沒(méi)有好用的書(shū)簽功能,尤其是沒(méi)有能夠定位到頁(yè)面中任意位置的書(shū)簽功能,看長(cháng)文檔看到一半的時(shí)候被打斷會(huì )很麻煩,所以自從MyReader實(shí)現了書(shū)簽功能后,我就下定決心一定要解決反編譯問(wèn)題。 2.2.2.1 Web Compiler 1.67 這種格式的電子書(shū),因為其制作工具在國內出現得比較早,而且有非常徹底的漢化解密版,所以曾經(jīng)比較流行,E書(shū)時(shí)空提供的很多電子書(shū)都是這種格式。不過(guò)也正因為它的流行,導致想反編譯它的人也多,引出了各種反編譯工具,所以現在用的人似乎已經(jīng)不多了。 反編譯工具里,收費的就不去說(shuō)它了,國內RMH和Fbilo還聯(lián)合推出過(guò)免費的unwebcompiler,并且提供全套的Delphi源代碼,有需要的到google或百度搜索一下unwebcompiler就有了。不過(guò)可能?chē)鴥却蠖鄶弟浖W(wǎng)站的管理員都不是開(kāi)發(fā)人員出身,對源代碼不感興趣,所以收藏的都是212 KB的EXE,有源代碼的不多,需要仔細找一下。 在unwebcompiler的源代碼里,RMH和Fbilo對Web Compiler 1.67生成的電子書(shū)的文件格式進(jìn)行了詳細描述,在這里我就不做無(wú)聊的重復,有興趣就自己去看吧。我做的UnEBook也使用了他們提供的源代碼,實(shí)現對Web Compiler 1.67生成的電子書(shū)的批量反編譯,不過(guò)被我將代碼從Delphi改成了C,似乎長(cháng)度縮短了一些(原代碼中有一段在字符串和十六進(jìn)制數之間轉換來(lái)、轉換去,看起來(lái)比較怪異,被我省了),不過(guò)LHA解壓縮部分改起來(lái)實(shí)在太麻煩,我直接在網(wǎng)上找了一段現成的C代碼來(lái)用。 2.2.2.2 Caislabs eBook Pack Express 1.6 這個(gè)電子書(shū)制作工具也出過(guò)漢化版,所以在國內也有一定影響,不過(guò)這種影響似乎還沒(méi)有大到足以使反編譯工具滿(mǎn)天飛的程度,嘿嘿…… 在分析這種格式的電子書(shū)的時(shí)候,我沒(méi)有使用任何反匯編工具,用UltraEdit32和系統監視工具就猜出來(lái)了: 文件標識:以十六進(jìn)制串 00 F8 03 00 結尾。這個(gè)似乎是一種慣例,差不多所有EXE格式的電子書(shū)都有自己特殊的文件結尾。 目錄塊起始地址指針:0003F81C 目錄塊中目錄項結構:以0字符結尾的文件名+4字節起始地址,文件名起始字節為FF則目錄塊結束。 如果文件存放在子目錄里,則文件名首字符:02=../,01:第一個(gè)00變成/,直到遇到02。 文件內容實(shí)際起始地址:目錄項里的4字節起始地址+9 文件內容長(cháng)度:目錄項里4字節起始地址所指內容,DWORD。 在分析出目錄結構后,我曾經(jīng)想通過(guò)調試工具,分析文件加密算法,再反編譯出具體的文件內容,但是很快我就發(fā)現那樣干太累了,實(shí)在是得不償失。 不過(guò)在經(jīng)過(guò)幾次嘗試后,我還是找到了一個(gè)偷懶的辦法: 通過(guò)安裝hook的方法,往電子書(shū)的進(jìn)程空間注入一個(gè)DLL。 在這個(gè)DLL里,用Windows標準的API函數URLDownloadToFile,就可以下載到指定的文件。文件的URL可以按前面說(shuō)的方法,從目錄項得到相對路徑,再加上一個(gè)固定前綴("file://Z:\\com_caislabs_ebk\\")構成絕對路徑。 UnEbook在批量反編譯這種格式的電子書(shū)的時(shí)候,就是按照上面的分析結果實(shí)現的。 不過(guò)到了更高版本的Caislabs eBook Pack Express的時(shí)候,似乎Caislabs公司也開(kāi)始意識到文件內容保護的重要性,因此不僅對文件內容采用更強的加密算法,杜絕了可以用URLDownloadToFile下載的漏洞,連目錄塊的加密強度都強到足夠使我不想去分析了。幸好這個(gè)時(shí)候我已經(jīng)有了更好的反編譯思路--與具體文件格式無(wú)關(guān)的,專(zhuān)門(mén)針對使用IE內核的電子書(shū)的通用反編譯思想。 2.2.2.3 通用反編譯思路 在分析過(guò)幾種電子書(shū)格式后,我開(kāi)始領(lǐng)悟到一個(gè)真理:電子書(shū)內部文件結構的變化是無(wú)窮的,而我的時(shí)間和精力是有限的;把有限的時(shí)間和精力投入到對抗無(wú)窮的變數中去,早晚會(huì )有累死的一天。 有此認識后,我開(kāi)始思考有沒(méi)有什么通用的方法,可以解決大部分電子書(shū)的反編譯問(wèn)題(我還沒(méi)有幼稚到相信這世上會(huì )有萬(wàn)能藥的程度)。按照慣例(不可救藥的職業(yè)?。?,第一步當然是市場(chǎng)調查、產(chǎn)品定位,結論是目前大多數電子書(shū)都是基于IE內核的,但是根據我在開(kāi)發(fā)MyReader時(shí)對IE內核的了解,這里面明顯存在一個(gè)誤區:微軟以控件的形式提供IE內核,其目的就是希望通過(guò)控件接口的開(kāi)放性、方便性,吸引更多的人加入微軟的標準陣營(yíng),如果想在此基礎上添加加密、保護等等內容,恐怕與微軟的初衷不合(我說(shuō)的是當時(shí),以后微軟改主意了也說(shuō)不定)。因此我相信IE內核一定有后門(mén)可走!經(jīng)過(guò)一番努力,果然沒(méi)有令我失望。 1、基本原理 針對IE內核電子書(shū)的通用破解技術(shù)實(shí)現起來(lái)可能需要一些技術(shù)和技巧,但是原理卻很簡(jiǎn)單,幾句話(huà)就可以說(shuō)清楚:不論電子書(shū)在存儲的時(shí)候如何對內容進(jìn)行加密,在將內容傳遞給IE內核進(jìn)行顯示的時(shí)候,一定要將內容轉換成IE內核能夠識別的標準格式--HTML格式。而IE內核為了便于顯示、刷新,在對HTML代碼進(jìn)行解析后,并不是立刻就把這些HTML代碼拋棄,而是在內存里保存了一份備份。因此只要將這份備份從IE內核里搞出來(lái),就得到了解碼后的內容,也就是反編譯想得到的內容。 至于網(wǎng)頁(yè)中的其它內容,包括圖片、css、js、Flash文件等,就更簡(jiǎn)單了:模擬IE內核,直接找電子書(shū)要就好。如果電子書(shū)分辨不出請求是來(lái)自IE內核還是來(lái)自其它地方,自然會(huì )乖乖把我們需要的東西雙手奉上! 雖然反編譯的原理幾句話(huà)就可以說(shuō)清,但是要加以實(shí)現,還需要經(jīng)過(guò)艱苦的探索和試驗,我自己就經(jīng)過(guò)了長(cháng)期的努力,IE內核的源代碼都翻來(lái)覆去看了好幾遍(吹的,別當真?。?。而我思想的發(fā)展也大概經(jīng)歷了兩個(gè)階段:第一個(gè)階段是在得到某份傳說(shuō)中的源代碼(沒(méi)錯,就是那份展開(kāi)后近700MB,被國內主流媒體形容為噱頭、無(wú)足輕重、充滿(mǎn)無(wú)聊垃圾的東西)之前,完全立足于微軟公開(kāi)的IE內核接口。當時(shí)我考慮將電子書(shū)內容按照HTML、圖像等分類(lèi),分別解決獲取問(wèn)題。第二個(gè)階段是在得到那份源代碼之后,我突然發(fā)現其實(shí)對于所有文件,我都可以直接找電子書(shū)要,只要假裝是IE內核在要就行了。 由于某些東西比較敏感,因此下面敘述的主要是我第一個(gè)階段的想法,其中有些屬于基礎性的東西。第二個(gè)階段的實(shí)現恕我不便奉告。 2、獲取HTML源代碼的方法 從IE內核獲取HTML源代碼的方法不僅我一個(gè)人在想,從國內到國外,從CSDN(CSDN的VC/MFC區有一個(gè)欄目專(zhuān)門(mén)討論IE內核編程)到MSDN,早就有很多人討論過(guò)了,歸納起來(lái),一般認為可以通過(guò)下列步驟實(shí)現: 不管是通過(guò)鼠標點(diǎn)擊也好,通過(guò)EnumChildWindow也好,總之先找到IE內核的顯示窗口,也就是電子書(shū)顯示網(wǎng)頁(yè)內容的那個(gè)窗口。 通過(guò)這個(gè)窗口的句柄(HWND),取得這個(gè)窗口對應的IE內核文檔接口IHTMLDocument2的接口指針。取得的方法目前認為有兩種,我個(gè)人認為這兩種需要結合使用,否則總有一些電子書(shū)會(huì )搞不定:一個(gè)是通過(guò)MSAA,一個(gè)是通過(guò)WM_HTML_GETOBJECT消息。至于具體的實(shí)現代碼,在CSDN上都快被討論爛了,因此此處從略,有需要的自己到CSDN上找。不過(guò)這兩種方法都對平臺有要求:XP下是完全沒(méi)有問(wèn)題,2000下可能需要裝IE 6,98/Me/NT就不要想了。 在得到IHTMLDocument2接口指針后,按照這個(gè)接口提供的標準方法,即可獲得文檔的HTML代碼。具體實(shí)現代碼見(jiàn)CSDN中的例子。 除了上面這種方法外,我自己還嘗試過(guò)一種方法:使用MIME Filter。 對于搞過(guò)網(wǎng)頁(yè)在線(xiàn)翻譯、網(wǎng)頁(yè)內容過(guò)濾的人來(lái)說(shuō),MIME Filter可是吃飯的本錢(qián),它的作用和實(shí)現機理應該早就爛熟于心,但是對于其它人來(lái)說(shuō),可能還不是很熟,所以這里簡(jiǎn)單介紹一下:為了便于對IE內核的功能進(jìn)行擴展,微軟規定在IE內核顯示某種標準格式(HTML、TEXT等)的內容之前,會(huì )先將要顯示的內容傳遞給這種格式的過(guò)濾器,即MIME Filter,由它先對內容進(jìn)行預處理(如將英文翻譯成中文,將下流文字替換成星號等),然后再顯示。 按照這個(gè)原理,如果實(shí)現一個(gè)針對HTML格式的MIME Filter,即可攔截到最原汁原味的HTML代碼??上?,經(jīng)過(guò)我的嘗試,這招對IE本身是靈的,對某些電子書(shū)也有效,但是對另一些無(wú)效。再加上使用IHTMLDocument2接口指針的方法要比這種方法簡(jiǎn)單得多,也可靠得多,所以后來(lái)在我開(kāi)發(fā)的反編譯工具KillEBook、IECracker和CtrlN里就沒(méi)有使用這種方法。不過(guò)這種方法也有一個(gè)好處:與平臺無(wú)關(guān),我在98/Me/2000/XP下都試過(guò),當然都是在虛擬機下試的啦。 MIME Filter的作用機理、實(shí)現方法在MSDN里有詳細說(shuō)明,并提供了詳細的實(shí)例代碼,有需要的可以到MSDN上搜“MIME Filter”。 3、獲取圖像的方法 與HTML代碼相似,IE內核對圖像的處理也有一個(gè)“下載->解碼->顯示”的過(guò)程??紤]到顯示代碼的抽象性,原來(lái)各種各樣的圖像格式,包括JPG、GIF、PNG、TIFF等,在解碼后都被統一表示成位圖格式,而原有格式數據在解碼后即被從內存中釋放,只在IE的cache中留有文件備份。如果指定不允許保存本地cache,則連這個(gè)備份都沒(méi)有。在IE中通過(guò)右鍵菜單選“圖片另存為...”的時(shí)候,其實(shí)就是將cache中的文件備份拷貝一份出來(lái),如果cache中已經(jīng)沒(méi)有備份,就只能保存內存中的位圖(*.bmp)了?,F在明白為什么有些圖片明明是jpg格式,但是用IE卻只能保存為“無(wú)標題.bmp”了吧? 因此,獲取圖像文件要比獲取HTML文件難得多。而且在MSDN里說(shuō)得很清楚,用IHTMLDocument2接口只能得到圖像的鏈接,用MIME Filter也不能搞到網(wǎng)頁(yè)里的圖像數據,因此需要另想辦法。我想過(guò)、試過(guò)的包括: 先將圖像復制到剪貼板,再從剪貼板里獲取圖像數據,然后根據圖像文件擴展名(可以從圖像元素的URL里解析),編碼成原始圖像格式,包括jpg、png、gif、tiff等。這個(gè)方法實(shí)現比較簡(jiǎn)單,到MSDN KB里搜索Q293125,拷貝圖像到剪貼板的現成源代碼就有了,圖像編碼的源代碼則可以參考cximage,這個(gè)也是google一下就有的。不過(guò)這個(gè)方法遠非完美無(wú)缺:a). 對于png、gif等允許帶透明背景的格式,用這種方法處理后就不透明了。b). gif動(dòng)畫(huà)處理后就動(dòng)不起來(lái)了,只能顯示其中的某一幀。c). 對于jpg這樣的有損壓縮格式來(lái)說(shuō),每壓縮一次就損失一次,多壓縮幾次可能就沒(méi)法看了。d). 在電子書(shū)里,可以通過(guò)標準的Windows API函數,使剪貼板失效。 將IE內核導航到圖片,然后通過(guò)IViewObject接口獲取圖片的拷貝。這個(gè)方法與上面的方法基本相同,不過(guò)不通過(guò)剪貼板,可以防止因為剪貼板被封鎖而搞不到圖像。 使用IE圖像解碼插件。IE內核在下載到某種格式的圖像文件后,會(huì )調用對應的解碼器,對圖像進(jìn)行解碼(類(lèi)似于MIME Filter)。為了便于擴充,解碼器是做成插件形式的。如果自己做一個(gè)圖像解碼器插件,對解碼請求進(jìn)行攔截,即可獲得解碼前的原始圖像格式數據。解碼器的接口、實(shí)現方法在微軟公開(kāi)文檔中沒(méi)有任何蛛絲馬跡,但是在那份傳說(shuō)中的源代碼里,不僅有詳細的接口規范,而且有好幾個(gè)內嵌圖像解碼器的實(shí)現代碼,可供借鑒。奇怪的是,雖然在MSDN中找不到,但是我在google上搜的時(shí)候,卻發(fā)現有一個(gè)日本人在自己的個(gè)人網(wǎng)站上,早就給出了詳細的圖像解碼器插件實(shí)現方法,一步一步說(shuō)得很清楚,而且落款時(shí)間是2002年12月!看來(lái)這份源代碼的泄漏時(shí)間可能比想象的要早。當然這個(gè)日本人也可能本來(lái)就在微軟工作,或與微軟有合作關(guān)系,可以光明正大地查看解碼器源代碼也說(shuō)不定。 4、通用反編譯器的實(shí)現 在解決了HTML、頁(yè)面元素等的獲取方法后,通用反編譯器KillEBook的實(shí)現就很簡(jiǎn)單了,其算法可以描述如下: 打開(kāi)電子書(shū)。 定位電子書(shū)的顯示窗口。 獲取當前顯示頁(yè)面的HTML代碼。 解析頁(yè)面HTML代碼,得到其中的所有鏈接。 獲取頁(yè)面上的所有元素內容,包括圖片等。 引導IE內核依次加載HTML鏈接頁(yè)面。 重復步驟3~6,直到所有頁(yè)面及其中的元素都已獲取到。 5、進(jìn)一步討論 在完成KillEBook后,我發(fā)現其實(shí)對它擴展一下,就可以成為一種新的離線(xiàn)瀏覽器,解決傳統離線(xiàn)瀏覽器(Offline Explorer Pro、Webzip等)面臨的一個(gè)問(wèn)題:傳統離線(xiàn)瀏覽器多半與IE內核沒(méi)什么瓜葛,因此在抓靜態(tài)網(wǎng)頁(yè)的時(shí)候都沒(méi)有什么問(wèn)題,但是在抓用session維持的動(dòng)態(tài)網(wǎng)頁(yè)時(shí),都有點(diǎn)問(wèn)題,更不用說(shuō)抓需要PKI證書(shū)驗證的HTTPS網(wǎng)站。 因此我考慮可以實(shí)現這樣一個(gè)離線(xiàn)瀏覽器: 提供一個(gè)地址欄供用戶(hù)輸入起始URL。 內嵌一個(gè)微軟web browser控件(IE內核),供用戶(hù)交互,包括在網(wǎng)頁(yè)上輸入用戶(hù)名/密碼、從IE證書(shū)庫中選擇證書(shū)。 用戶(hù)登錄成功、進(jìn)入需要開(kāi)始抓取的網(wǎng)頁(yè)后,設定遞歸深度、URL過(guò)濾條件,點(diǎn)“開(kāi)始”按鈕開(kāi)始抓取。 離線(xiàn)瀏覽器自動(dòng)引導web browser進(jìn)入每個(gè)頁(yè)面,每進(jìn)入一個(gè)頁(yè)面,都通過(guò)web browser控件獲取客戶(hù)端HTML源代碼及頁(yè)面元素,包括圖片、css、js、flash等。 采用這種方法實(shí)現的離線(xiàn)瀏覽器,由于使用web browser控件,因此可以維持客戶(hù)端session,抓取到動(dòng)態(tài)網(wǎng)頁(yè)。雖然網(wǎng)頁(yè)抓取下來(lái)就成了靜態(tài)的,但是對離線(xiàn)瀏覽來(lái)說(shuō)應該不成問(wèn)題,對付收費的網(wǎng)上教育等網(wǎng)站正好合適。 2.3 HLP格式 這種格式出現得比較早,在16位Windows(Windows 95以前的各Windows版本)下曾是標準的幫助文件格式,因此大概也算是Windows下出現得最早的電子書(shū)格式之一了。 由于這種格式比較流行,國外研究的也比較多,不過(guò)公開(kāi)源代碼的我似乎只見(jiàn)過(guò)一個(gè)HELPDECO v2.1。這個(gè)軟件是一個(gè)控制臺程序,因此有人做了一個(gè)GUI外殼DuffOS對它進(jìn)行封裝。國內有人對HELPDECO進(jìn)行過(guò)漢化,到漢化新世紀搜索一下就可以找到,包括全部源代碼。 在UnEBook中使用了HELPDECO的源代碼,實(shí)現對HLP文件的批量反編譯。不過(guò)從我使用的情況看,原版HELPDECO有一個(gè)小小的不足:反編譯出來(lái)的RTF文件沒(méi)有指定字符集。這對英文RTF來(lái)說(shuō)沒(méi)有任何影響,但是對中文RTF來(lái)說(shuō),其影響足夠強到使您打開(kāi)RTF后看到的是一堆亂碼。它的修正方法有兩個(gè): 用文本編輯器打開(kāi)反編譯出來(lái)的RTF文件,手工指定中文字符集。這個(gè)是一種比較累的方法。 修改HELPDECO源代碼,加上字符集修正,這個(gè)是一勞永逸的辦法。但是不知道為什么,在漢化新世紀推出的漢化版上,我看到的還是原版的HELPDECO??磥?lái)漢化者只是用它反編譯過(guò)英文HLP,沒(méi)有反編譯過(guò)中文HLP。 另外這份源代碼還有一個(gè)不知道算不算是嚴重的問(wèn)題:變量沒(méi)有統一初始化、釋放,因此不僅在程序退出的時(shí)候,VC++會(huì )報告有內存漏洞,而且就象當年的DOS內核一樣,幾乎沒(méi)有可重入性。我曾經(jīng)試圖修復這個(gè)bug,但是在經(jīng)過(guò)一個(gè)下午的奮斗后,有兩處泄漏死活找不到。最后我還是決定向DuffOS學(xué)習:將HELPDECO代碼封裝成一個(gè)獨立的DLL,每反編譯一個(gè)HLP文件,都動(dòng)態(tài)加載、釋放一次DLL。這樣一方面可以利用Windows本身的DLL管理機制,彌補HELPDECO產(chǎn)生的內存漏洞,一方面解決不可重入問(wèn)題。收費的“耶書(shū)制造”軟件提供的HLP反編譯功能也是用DLL文件實(shí)現的,因此我嚴重懷疑它的作者可能也曾遇到過(guò)相同的煩惱,嘿嘿嘿…… 從HLP文件反編譯出來(lái)的RTF文件,一般包含大量書(shū)簽、分頁(yè)符等與實(shí)際文本內容無(wú)關(guān)的東西,有必要轉換成純文本格式。這個(gè)實(shí)現倒是比較簡(jiǎn)單: 創(chuàng )建一個(gè)Windows標準的RichEdit控件,當然沒(méi)有必要在用戶(hù)界面上顯示出來(lái)。 按SF_RTF格式,StreamIn原RTF文件內容。 按SF_TEXT格式,StreamOut文本內容。 UnEBook提供的從RTF到TXT的批量轉換功能,就是按照上面的方法實(shí)現的。 2.4 小說(shuō)網(wǎng)/小說(shuō)世界(ebx/XReader) 這兩家網(wǎng)站提供的電子書(shū)使用的是同一個(gè)閱讀器,只不過(guò)小說(shuō)網(wǎng)出現得比較早,提供的電子書(shū)多半不需要驗證碼,而小說(shuō)世界出現得比較晚,提供的電子書(shū)多半需要輸入驗證碼。 這種電子書(shū)分兩種:ebx和EXE格式。ebx格式的電子書(shū)需要用專(zhuān)用瀏覽器XReader才能瀏覽,EXE文件的內容其實(shí)就是XReader + ebx包構成。 國內Cyu曾經(jīng)推出過(guò)反編譯這種EXE格式的工具--xReader Unpacker。從我試用的情況來(lái)看,這個(gè)工具的實(shí)現應該是基于對EXE文件格式的辛苦分析,果然勤勞善良的中國人什么時(shí)候都有??!不過(guò)從我試用的結果看,這個(gè)工具也存在下列問(wèn)題: 一次只能反編譯一個(gè)文件,不能批量反編譯,使用起來(lái)略有不便。 反編譯出來(lái)的文件用左側目錄樹(shù)中對應的節點(diǎn)命名,完全失去了文件的先后順序。 在反編譯某些文件,如《血酬定律--中國歷史中的生存游戲》的時(shí)候,會(huì )出錯退出。我個(gè)人猜想可能是因為對書(shū)中多級目錄處理不當。 奇怪得很,只能對EXE文件進(jìn)行反編譯,不能對ebx文件反編譯,其實(shí)這兩種文件本是兩位一體的。 當然,我試用的只是最初版本的xReader Unpacker,后來(lái)聽(tīng)說(shuō)作者又進(jìn)行了更新,這些問(wèn)題都解決了也說(shuō)不定。 在考慮反編譯這種格式的電子書(shū)的時(shí)候,因為我已經(jīng)在思考針對IE內核的通用反編譯方法,因此從一開(kāi)始我就沒(méi)打算對文件格式進(jìn)行分析,而是打算從界面元素入手,看看有沒(méi)有什么后面可走: 先用IECracker抓一下窗口,發(fā)現根本就不是基于IE內核的東西。這個(gè)時(shí)候首先想到的就是:軟件作者會(huì )不會(huì )向起點(diǎn)中文網(wǎng)學(xué)習,將內容轉換成圖片,然后再顯示?但是很快就否定了這個(gè)可能,一方面是因為XReader提供了文字放大、縮小功能,另一方面是因為啟動(dòng)金山詞霸后,將光標往窗口上一放,詞霸顯示出了抓詞內容。這個(gè)時(shí)候腦袋里一閃念間,也曾出現過(guò)一個(gè)反編譯方案:干脆向金山詞霸學(xué)習,做一個(gè)API hook,抓它的顯示內容算了,哈哈…… 在確定XReader顯示的東西不是圖片后,我就啟動(dòng)SPY++,打算看看XReader的顯示窗口用的是什么東西。但是查看的結果令人驚奇:每啟動(dòng)一次XReader,顯示窗口的class name就會(huì )變化一次,是一個(gè)完全隨機的字符串,從上面根本看不出這個(gè)窗口使用了什么控件。 再多看幾本電子書(shū)后,我發(fā)現所有電子書(shū)都有一個(gè)特點(diǎn):完全沒(méi)有圖片,清一色都是純文本,但是鼠標放到窗口上的時(shí)候,光標不會(huì )變成通常文本窗口的插入光標(一條豎線(xiàn)),還是箭頭光標。到這個(gè)時(shí)候,我已經(jīng)開(kāi)始準備相信軟件作者完全繼承了國人勤勞善良的光榮傳統,自己寫(xiě)了一個(gè)文本輸出控件了?!衣?,為什么在打開(kāi)這個(gè)大文件的時(shí)候光標會(huì )閃一下,從豎線(xiàn)變成箭頭?再前后動(dòng)動(dòng)鼠標滾輪看看,每次不多不少,正好滾動(dòng)3行,這個(gè)不是RichEdit控件的特性之一嗎?! 立刻啟動(dòng)SPY++,這次不看class name了,改看消息流。果然每次點(diǎn)擊左側目錄樹(shù),都會(huì )向右側顯示窗口發(fā)送一堆RichEdit控件的消息:EM_SETBKGNDCOLOR(設置窗口背景色)、EM_SETCHARFORMAT(設置光標形狀)、EM_SETMARGINS(設置左右頁(yè)邊距)、EM_STREAMIN(導入顯示內容)。 既然已經(jīng)確定右側顯示區用的是一個(gè)標準的RichEdit控件,而左側目錄樹(shù)是一個(gè)標準的TreeCtrl控件,那么反編譯方案其實(shí)也就出來(lái)了:周游左側目錄樹(shù),依次選中每個(gè)節點(diǎn),然后攔截右側RichEdit控件的輸出,寫(xiě)入文件即可。 不過(guò)在搞清楚XReader的原理后,我也產(chǎn)生了一個(gè)疑問(wèn):RichEdit控件本身是可以同時(shí)顯示文本、圖片的(RTF格式),但是為什么XReader只顯示純文本,不顯示圖片呢?要知道這樣可是會(huì )使做出來(lái)的電子書(shū)增色不少。開(kāi)始我以為是為了保密,象我自己一開(kāi)始不也差點(diǎn)誤入歧途?如果不是偶然看到光標閃爍,再動(dòng)動(dòng)鼠標滾輪,可能我一時(shí)也想不起來(lái)他用的是標準RichEdit控件。后來(lái)在看到早期版本的XReader后,我想更大的可能是為了兼容:早期版本用WM_SETTEXT傳遞顯示信息,只能顯示純文本,后來(lái)才改用EM_STREAMIN的。 總結一下,XReader中采取了下列措施防拷貝、防反編譯: 隨機更改RichEdit控件的class name,防止被人識破。 對光標形狀進(jìn)行設置,一方面防止被人識破使用的是RichEdit,一方面避免用鼠標選擇、復制內容。 對WM_COPY、WM_GETTEXT、EM_STREAMOUT等等消息進(jìn)行了過(guò)濾,因此直接從窗口獲得文本內容就不要想了。 可惜,微軟提供的RichEdit控件是用于開(kāi)放環(huán)境的,一旦被識破,用微軟本身提供的接口就足以搞到所需的內容了。 后來(lái)看到小說(shuō)網(wǎng)早期放出來(lái)的EXE格式電子書(shū),才發(fā)現XReader這個(gè)軟件也是不斷發(fā)展的,而版本升級的目的主要就是為了加強安全性,ebx格式本身卻沒(méi)有什么變化,一直很穩定,新的ebx文件也可以用老的XReader打開(kāi): 早期版本的XReader支持用命令行參數的方式,傳入需要打開(kāi)的ebx文件路徑,這樣容易被人利用,實(shí)現文件自動(dòng)打開(kāi)。后來(lái)版本的XReader就只能通過(guò)菜單或工具條,點(diǎn)“打開(kāi)電子書(shū)”才能打開(kāi)文件。當然這個(gè)限制也不是不可以突破,不過(guò)畢竟沒(méi)有用命令行參數傳遞這么方便。 早期版本的XReader其實(shí)就使用WM_SETTEXT消息顯示文本。如果早點(diǎn)看到這個(gè)版本的電子書(shū),說(shuō)不定我還可以少費點(diǎn)周折。后來(lái)版本改用EM_STREAMIN,估計一方面是為了保密,另一方面是為了速度和性能:在顯示大文件的時(shí)候,EM_STREAMIN比WM_SETTEXT快得多;EM_STREAMIN可以顯示RTF文件,而WM_SETTEXT只能顯示文本文件;EM_STREAMIN可以顯示大型文件,而WM_SETTEXT支持的文件長(cháng)度是有限的。 3. 結論 就像信息安全中的攻與防一樣,電子書(shū)的編譯與反編譯之間的斗爭也將是一個(gè)永無(wú)止境的死循環(huán)。我相信不論電子書(shū)反編譯技術(shù)如何發(fā)展,都不會(huì )導致電子書(shū)的絕跡,畢竟有實(shí)際的需要。但是本文的發(fā)表,毫無(wú)疑問(wèn)將會(huì )刺激電子書(shū)制作軟件和制作技術(shù)的新一輪升級。那么我的文章和軟件會(huì )不會(huì )隨之升級呢?我自己是沒(méi)什么自信啦,畢竟我的自由時(shí)間越來(lái)越少,而如果沒(méi)有其他人愿意象我這樣研究反編譯技術(shù)和軟件(收費的免談),我想最終勝利的一定是有商業(yè)利益支撐的電子書(shū)制作軟件。 先分析電子書(shū)的詳細文件格式,再有針對性推出專(zhuān)用反編譯器的方法,在初期確實(shí)是一個(gè)不錯的方法,但是隨著(zhù)電子書(shū)格式的增多,如果每一種都要去分析一遍,早晚會(huì )累死。 電子書(shū)制作軟件其實(shí)也是人開(kāi)發(fā)的,開(kāi)發(fā)者當然也會(huì )有人類(lèi)的通病——懶!只要有現成的東西可用,很少有人會(huì )再花力氣去修練自己的獨門(mén)功夫。而目前Windows下的東西,開(kāi)放性的考慮要比安全性的考慮更多一些,如果能夠找到這些東西的突破口,即可突破同一類(lèi)使用這些東西的電子書(shū)。 利用現成控件的接口或漏洞,實(shí)現通用電子書(shū)反編譯,這其實(shí)也是程序員懶惰的一種體現。這種方法雖然比老老實(shí)實(shí)分析、跟蹤電子書(shū)簡(jiǎn)單許多,但是也有其天然缺陷:只能反編譯顯示到控件中的內容。通俗一點(diǎn)說(shuō),如果電子書(shū)是加密碼保護的,那么這種方法并不能在不知道密碼的情況下,反編譯出電子書(shū)的內容。 附錄 基于IE內核電子書(shū)的實(shí)現方式探討 電子書(shū)看多了,有時(shí)候我也會(huì )想,如果是我自己做一個(gè)電子書(shū)制作工具,我會(huì )采用什么樣的技術(shù)加以實(shí)現?考慮到現在HTML格式文檔的普遍性,在有人開(kāi)放出新的HTML render之前,我的想法還是只能?chē)@IE內核打轉。下面就是我想到的一些思路。 1、基于res協(xié)議 res協(xié)議是IE內核提供的一種非常簡(jiǎn)單的協(xié)議,允許將需要瀏覽的頁(yè)面存放在EXE或DLL的資源(resource)中,IE根據URL定位EXE或DLL,裝載其中的資源。下面這個(gè)URL就是這種協(xié)議的一個(gè)例子: res://C:\WINNT\system32\shdoclc.dll/http_404.htm 如果您在IE中要瀏覽的頁(yè)面不存在,IE就會(huì )通過(guò)這個(gè)URL,打開(kāi)C:\WINNT\system32\shdoclc.dll,查找其中名為http_404.htm的資源,找到后提取、顯示出來(lái),您看到的就是一個(gè)提示頁(yè)面不存在的網(wǎng)頁(yè)。 從上面這個(gè)頁(yè)面的源代碼可以看到,除HTML代碼外,res協(xié)議還允許在頁(yè)面中包含圖片等內容,如上面這個(gè)頁(yè)面就顯示了一個(gè)名為pagerror.gif的圖片,其絕對URL為res://C:\WINNT\system32\shdoclc.dll/pagerror.gif。 雖然res協(xié)議非常簡(jiǎn)單,基本上不需要額外的編程,但是我目前還沒(méi)有看到有人用它做電子書(shū),最多只看到有人用它顯示軟件的About信息。仔細想想,可能是因為這種協(xié)議太不保密了:隨便找一個(gè)資源編輯器,就可以直接獲取、替換資源內容了。 2、基于文件方式 這種方式的思路其實(shí)非常簡(jiǎn)單:需要顯示網(wǎng)頁(yè)的時(shí)候,先將網(wǎng)頁(yè)解壓縮到臨時(shí)目錄,然后用IE控件顯示,退出的時(shí)候刪除臨時(shí)文件。 這種方式我早就知道,但是因為它實(shí)在是太簡(jiǎn)單了,所以連我自己都不相信有人真的會(huì )用它做電子書(shū),直到我見(jiàn)到雄風(fēng)網(wǎng)的電子書(shū):這個(gè)網(wǎng)站早期發(fā)行的電子書(shū),雖然要求用戶(hù)輸入密碼進(jìn)行驗證,但是在密碼輸對以后,就會(huì )把全部?jì)热萁鈮嚎s到temp目錄下,然后用IE控件打開(kāi)文件進(jìn)行瀏覽。雖然temp目錄下的文件屬性被設置為隱藏,但是這點(diǎn)小伎倆實(shí)在不值一提,所以只要破解了認證密碼,電子書(shū)本身就已經(jīng)提供了完整的反編譯功能了。 該網(wǎng)站后來(lái)發(fā)行的電子書(shū)雖然經(jīng)過(guò)升級,但還是延續了這種模式,只不過(guò)在temp目錄里存放的是加過(guò)密的HTML文件,但是圖像文件卻是不加密的,因此我猜測他們可能改用MIME Filter技術(shù)了。 3、基于流或document.write方法 用流往IE控件中寫(xiě)入內容的方法,在MSDN和CSDN中都有詳細的討論,連源代碼都有。有需要的到MSDN搜索“Loading HTML content from a Stream”即可。 document.write在動(dòng)態(tài)網(wǎng)頁(yè)中比較常用,很多網(wǎng)頁(yè)加密工具都是使用這招來(lái)實(shí)現網(wǎng)頁(yè)源代碼的隱藏。對于VC、Delphi等來(lái)說(shuō),這招不過(guò)是換成了IHTMLDocument2::write,效果是一樣的。 使用這種方法做電子書(shū)的雖然不多,不過(guò)畢竟還是有的,我見(jiàn)過(guò)的就是讀寫(xiě)網(wǎng)。由于打開(kāi)這個(gè)網(wǎng)站的電子書(shū)后,IE主頁(yè)就會(huì )自動(dòng)設置為這個(gè)網(wǎng)站的URL,所以在這里就不給出這個(gè)網(wǎng)站的URL了,以免各位受到意外傷害。破解這種電子書(shū)的收費驗證的方法,已經(jīng)有人在紫宸殿網(wǎng)絡(luò )論壇的技術(shù)區貼出來(lái)過(guò),有興趣的可以去看看。 在MSDN中對這種基于流的方法的局限性說(shuō)得很清楚: 頁(yè)面不能太復雜,如果頁(yè)面包含的tag太多,顯示出來(lái)的就不是解析后生成的頁(yè)面,而是原始的HTML代碼。大概就是因為這個(gè)原因,所以讀寫(xiě)網(wǎng)放出來(lái)的電子書(shū)清一色都只有純文本,加背景色。 當前頁(yè)面的URL永遠不變(讀寫(xiě)網(wǎng)的永遠都是about:blank),因此IE內核沒(méi)有辦法從相對URL自動(dòng)構造出絕對URL。就是因為這個(gè)原因,讀寫(xiě)網(wǎng)早期的電子書(shū)在頁(yè)面中使用jpg文件作為背景,就只能將這個(gè)背景圖片寫(xiě)到temp目錄下,然后在網(wǎng)頁(yè)中使用絕對URL引用這個(gè)圖片。也正是因為這個(gè)原因,所以在頁(yè)面中不能包含“上一頁(yè)”、“下一頁(yè)”、“回目錄”等鏈接,只能自己在左側放一棵目錄樹(shù),讓用戶(hù)一頁(yè)、一頁(yè)去點(diǎn)。 由于這種電子書(shū)的頁(yè)面沒(méi)有自己的URL,因此不能用KillEBook進(jìn)行反編譯,只能用IECracker或CtrlN,一頁(yè)、一頁(yè)手工抓取。 4、采用MIME Filter 與基于流的方法相比,這種方法不僅支持包含眾多tag的復雜HTML頁(yè)面,而且可以從相對URL構造絕對URL,因此支持頁(yè)面之間的鏈接,實(shí)現也不復雜,MSDN上就有現成的例子可供參考。 不過(guò)這種方法的缺點(diǎn)也很明顯:不能對圖像等內容進(jìn)行加密處理。下面說(shuō)的協(xié)議插件方法就比這種方法強些。 5、基于web服務(wù)器 對于不懂行的人來(lái)說(shuō),“web服務(wù)器”聽(tīng)起來(lái)可能是一個(gè)很了不起的東東,但是對于懂行的人來(lái)說(shuō),實(shí)現其實(shí)很簡(jiǎn)單: 起一個(gè)監聽(tīng)線(xiàn)程,對本地80或任何一個(gè)指定的端口進(jìn)行監聽(tīng)。 每監聽(tīng)到一個(gè)連接請求,起一個(gè)服務(wù)線(xiàn)程,根據請求內容,按照HTTP協(xié)議,返回內容。 在codeguru和codeproject上,有很多現成的web server代碼,直接拿來(lái)用就好,自己只要考慮怎么填寫(xiě)返回內容即可。VC 6自帶的MSDN光盤(pán)上,也帶了一個(gè)名為HTTPSVR的例子,說(shuō)明如何用MFC和WinSock創(chuàng )建web server。 使用這種方法雖然簡(jiǎn)單、直截了當,而且只要愿意,差不多能夠模擬一個(gè)真正web server的功能(就算想實(shí)現app server也并非不可能,不過(guò)要花點(diǎn)功夫),但是也有問(wèn)題: 基本上沒(méi)有什么保密性可言,服務(wù)器起來(lái)后,本機其它進(jìn)程很輕松就能下載到需要的內容。 如果本機上其它進(jìn)程也提供TCP/IP服務(wù),可能會(huì )產(chǎn)生端口沖突。 6、協(xié)議插件(Asynchronous Pluggable Protocols) 這個(gè)是微軟專(zhuān)門(mén)為IE擴展的東西。 在互聯(lián)網(wǎng)上,常見(jiàn)的應用層協(xié)議包括http、FTP等。出于種種原因,微軟允許用戶(hù)在標準的應用層協(xié)議之外,擴展自己的協(xié)議,稱(chēng)為Asynchronous Pluggable Protocol。到MSDN、codeguru和codeproject上搜索這幾個(gè)關(guān)鍵字,從理論到源代碼都能找出一堆,在這里我就不羅嗦了。 Asynchronous Pluggable Protocol可以指定對所有進(jìn)程有效,這個(gè)在注冊表的HKEY_CLASSES_ROOT\PROTOCOLS\Handler下注冊一下就好;也可以指定只在某個(gè)進(jìn)程內有效,以增加保密性,不過(guò)這個(gè)時(shí)候微軟就不叫它Asynchronous Pluggable Protocol了,而是Pluggable Namespace Handler。 由于A(yíng)synchronous Pluggable Protocol具有一定的保密性,實(shí)現起來(lái)又有例子可參考,而且差不多與架設web server一樣,能夠對網(wǎng)頁(yè)顯示提供全面的支持,因此在電子書(shū)中得到了廣泛的應用,我見(jiàn)過(guò)的就有mk(chm)、ada99(eBook Workshop)、wc2p(Web Compiler 2000)、ic32pp(Web Compiler 2000—exe防反編譯格式)、e-book(E-Book Creator)、mec(E-ditor eBook Compiler)等。不過(guò)這種技術(shù)如果使用不好,可能會(huì )在注冊表中產(chǎn)生垃圾,或產(chǎn)生垃圾文件(插件本身是一個(gè)COM控件,一般用DLL實(shí)現,使用前必須在注冊表中注冊)。 7、最后一招 即使使用Asynchronous Pluggable Protocol,由于在IE內核中還存在可顯示的HTML源代碼,因此還是存在被導出的可能,這個(gè)就是上面正文里討論了半天的東西。 我想到的最后一招制作防反編譯的電子書(shū)的辦法就是:在制作的時(shí)候,將所有頁(yè)面內容全部轉換成圖片,然后再打包。將網(wǎng)頁(yè)轉換成圖片的源代碼參見(jiàn)這里: http://www.codeproject.com/internet/htmlimagecapture.asp 使用這種方法,在拿到一本制作好的電子書(shū)后,想得到原始文本信息的方法大概只有兩個(gè):OCR和key in。這個(gè)也可以用起點(diǎn)中文網(wǎng)的方法來(lái)對付:使用手寫(xiě)體,加水印,故意增加錯別字或替換標點(diǎn)符號等。據傳說(shuō),起點(diǎn)就是根據用戶(hù)ID,生成錯別字和錯誤標點(diǎn)的,因此如果是原樣key in或OCR,就可能被查出來(lái)。 但是回頭一想,如果哪個(gè)電子書(shū)制作工具真的走到了這一步,大概也就離消亡不遠了,用戶(hù)還不如直接去做PDF: 所有動(dòng)態(tài)效果全部沒(méi)有,頁(yè)面上的鏈接也全部失效,大概又只能靠在左側放一棵目錄樹(shù)才能導航了。 頁(yè)面大小、字符大小基本固定,顯示的時(shí)候很難放大、縮小,尤其是放大的時(shí)候,要么速度比較慢,要么必須忍受難看的鋸齒。 文件尺寸大增。對于以收藏為目的的電子書(shū)來(lái)說(shuō),這是一個(gè)必須以嚴肅的態(tài)度,認真地加以考慮的問(wèn)題。 |
聯(lián)系客服