11月23日:html
因爲Kindle界面使用的是Java,因此我一開始考慮自定字體時就是從Java入手的。(之前沒用過Kindle,KPW2算是個人第一臺電紙書)
反彙編 /opt/amazon/ebook/lib/kindlet-2.2.jar
文件,能夠看到UI字體配置選項java
/opt/amazon/ebook/lib/portability.jar
文件的 com.amazon.ebook.pl.service
包裏面的 FontService.class
定義了基本的字體配置工廠類。(Java Beans的一種寫法,通常在設計模式中叫作工廠模式。)git
/opt/amazon/ebook/lib/ReaderContentSDK.jar
裏面的 resource 的 FontPreferencesResources
定義了所有的字體列表,可是沒有圓體。由於圓體是經過更在外面添加的。查看 /usr/bin
下面的腳本很容易發現玄機。web
繼續搜索,在 /usr/java/lib
內發現文字鏡像 fonts.cramfs.img
和配置文件fontconfig.properties
。掛載鏡像後能夠看到Kindle自帶的所有字體,可是此處的字體引用須要在Java的程序中自行定義,修改量很大,天文數字般,要重打包,反彙編jar包,修改30多個類裏面的引用。所此處放棄直接的程序修改。設計模式
繼續查看Webkit部分發現自定義字體的更新代碼,查看 /usr/share/webkit-1.0/pillow/updating_content_package_fonts.html
文件代碼,發現其爲Kindle系統的顯示界面定義,放棄。緩存
找到配置文件 /usr/lib/font/manifests/manifest_zh-Hans
其定義了外置的字體文件和字體文件的Hash Code,找到可能的破解方法之一。服務器
{ "languages": "zh-Hans", "type": "font", "uniqueIdentifier": "zh-Hans", "files": "zh-Hans.font", "zh-Hans.font.md5": "37824a7650fc8f1fd952413fc5fad029", "STKaiMedium.ttf.md5": "0a3083d601f3c2fea59930ecfe664c2a", "STKaiBold.ttf.md5": "7e26a55e24fe35c98b2c89ceb7244cf3", "STYuanMedium.ttf.md5": "1cafad348452f68baccc1df5e80e1165", "version": 20130808, "fonts.zh-Hans": "stkai,styuan", "font.stkai.display": "\u6977\u4f53", "font.styuan.display": "\u5706\u4f53" }
在走了前面那麼多彎路後繼續回來看 system/fonts 文件夾下面的*.font文件。因爲我沒有日語字體的推送,因此打開一本日語的Kindle電子書,而後等待字體更新。可是一直沒有推送,因而我切換爲日語重啓後驚奇地發現有了更新的字體。因此咱們能夠猜想,其實字體的推送安裝只須要拷貝文件,而後重啓。(但後面的測試彷佛不是如此,須要聯網下載完畢後系統自動在未重啓前安裝更新,而非重啓,在重啓前其實就安裝完了,以後的重啓只是爲了更新字體緩存。)app
查看了字體的打包格式,cramfs打包的,這個工具源碼在Kindle的源碼包裏面是有的。編譯安裝後解包字體,自定義字體的廬山真面目出現了。框架
11月25號:函數
成功截取日語字體更新文件,ja.bin,一會解包分析。(bin文件的下載地址後面有給出)
奇怪的是,解包的字體和安裝成功後的字體文件類型不一致,目前更新包的字體沒法解包,查閱腳本,在 /usr/lib/contentpack/
下發現玄機。原來更新包內的字體實際上是封裝好的,而後在系統內進行轉碼爲cramfs格式的font鏡像,目前專心於解包更新包裏面的字體鏡像中……(在dalvik幫助下12月6日更正)
查看相關字體更新腳本,列表以下:/usr/lib/contentpack/csp_functions
/usr/sbin/csp-update-props
update font.properties using font manifests
此腳本首先調用 /etc/upstat/bundlefuncs 其內部定義更新方法,而後調用前面的那個csp_functions
腳本(其中的基本是更新中組件的共有方法)。
/usr/sbin/csp-instbundle
installs the bundle contents
usaage: csp-instbundle [path_to_bundle_1] [path_to_bundle_2] ...
if the bundle path is not specified, it scans the download directory
/usr/sbin/csp-unbundle
unbundles Content Support Pack bundle
/var/local/system/
下面的fontBundle.checksum的內容:ce369e7dc775c5a71c4005ebce93adfa,暫時不知道作什麼的。
查看腳本 csp_functions
找到安裝包裏面的字體解包方法 extract_bundle
,如今在查找字體的解包腳本,在 /etc/upstat/bundlefuncs 中找到具體的解包方法。
繼續查閱腳本,在bundlefuncs裏面331行找到解包腳本,坑爹的解包方法。決定另闢它徑,採用最麻煩的打包。(同時還在看LinkFont腳本)
12月1日:
找到字體鏡像安裝腳本 /usr/sbin/csp-instbundle
開始閱讀:
19~29 行引入基本的組件功能,Unix小既是美的設計。(坑爹的代碼查找)
24行 mount_directory
函數閱讀,函數有2個參數,第一個是將要掛載的文件,後面一個是掛載的目標目錄。
30~46行首先檢測掛載的目標目錄是否存在,若是存在的話,檢測此文件夾是否被掛載。若是被掛載,強制進行卸載,卸載成功後,將 _mounted
變量設爲0。
在卸載成功後48~72行進行掛載,50行調用csp_functions
腳本里面的 ensure_directory
代碼,經過3步判斷,保證,最後執行的時候是一個同名文件夾。
56行調用 /usr/sbin/get_free_loop_device
腳原本查看是否還能掛載鏡像,掛載地址0爲用戶文件,掛載地址1爲waveform,也就是EInk顯示屏文件,這一塊有興趣的本身看:
http://hi.baidu.com/black/item/c754a348fe0be50d6cc2f066
這是因爲Linux下面掛載鏡像的個數是有限的。我推測你們在切換官方更新的另外2種字體失敗的緣由也就是沒有空閒的loop device,而後字體鏡像掛載失敗的緣故。當達到最大掛載數時,按照 /etc/upstart/system.conf
裏面的定義,會自動加一。
63行開始掛載,此函數基本結束。
80~100行爲設置字體清單,首先按照題頭的註釋,意味將字體清單源文件夾 /usr/lib/font/manifests
的清單文件拷貝到工做時使用的清單文件夾 /var/local/font/manifests
。
85行獲取文字鏡像的名字不包括.font這個擴展名,86行將文字鏡像名前加上manifest_,而後分別在 /var/local/font/manifests
和 /usr/lib/font/manifests
上進行查找,直到找到同名文件,獲取路徑。
87~97行中,若是manifests的清單文件位於 /usr/lib/font/manifests
中的話,在簽名覈對正確的狀況下,將清單文件拷貝至 /var/local/font/manifests
文件夾。
102~115行計算文字鏡像的MD5值和Manifest裏面的是否相同。
117~139行對字體文件夾進行檢查,其中會檢查cache這個字體緩存文件夾,還有字體鏡像文件夾font
189~247行開始對字體進行掛載,首先經過manifest對字體鏡像文件覈對,而後添加至鏡像列表目錄。而後調用前面24行的方法將字體鏡像列表中的字體鏡像掛載至 /var/local/font/mnt/
鏡像名 _font 這樣子格式的目錄。
249~270行的代碼爲臨時掛載。
278行正式腳本代碼開始……
280~315,本人智商問題,看得只知其一;不知其二,能夠理解爲設備狀態檢測。只掛載模式調用前面的189行的掛載方法mount_only。
343~362行檢測已經掛載的字體的字體鏡像,若是鏡像掛載,文件卻沒了,就會自動卸載鏡像刪除。這也是前面測試的時候刪除ja.font文件後那個字體馬上沒有的緣由。
364~379行覈對字體清單,在缺失字體鏡像的狀況下會自動刪除清單。
目前進入死衚衕。
12月2日:
手動打包後字體不顯示,查看 /var/log/message
日誌記錄發現:csp-instbundle[3420]: Font manifest with name "zh-lth" exists, but the image is missing.查看對應腳本位置,尋求解決方法。發現本身打包的文件名寫錯了,坑爹啊 = =、修改文件名後從新掛載。
後面發現字體掛載後不顯示,結果發現,坑爹的XML配置腳本寫錯了一個地方,坑爹的馬大哈。修改從新打包,重啓,出現正在安裝字體的更新界面。可是依舊沒出現字體選擇菜單,查看字體conf腳本和實際的字體屬性,發現問題,坑爹的方正蘭亭黑,其粗體的屬性居然有問題(不是一個字族的)。
很奇怪,明明應該有字體掛載成功了,結果字體選擇菜單中沒有,查看後發現最關鍵的問題了, /var/local/java/prefs/master.manifest
中須要配置字體選擇目錄。
日語字體的更新文件下載地址爲:http://amzdigitaldownloads.edgesuite.net/eink/b07b507e8c6d1bc3ebb6ef0a11218410/ja.bin
中文字體的更新文件下載地址爲:http://amzdigitaldownloads.edgesuite.net/eink/7c5fc7918b6bb5afcd916bf210c552c8/zh-Hans.bin
成功發現字體配置屬性中的Indentify屬性值的由來,開始修改master.manifest從新配置打包。系統重啓中……失敗,實在是無力了,決定挺而走險修改zh-Hans.font
修改失敗,成功出現新增的字體選擇菜單,可是字體切換後無效果。(坑爹的fc-cache)
查閱腳本,找到 /etc/fonts/conf.d/70-lab126-altfonts.conf
彷佛和當年的USE_ALT_FONT方法相似,查閱相關歷史腳本中。
開始測試自定義字體方法,此文檔註釋詳細說明了是用於自定義字體,可是此方法其實已經失效,在此再也不累述。
12月6日:
在論壇dalvik的幫助下成功解包了font字體,發現了其實一切都是打包好的。因此判斷出主要的問題在於腳本中manifest文件的安裝上,其安裝步驟中向系統進行註冊。因此目前須要打包安裝鏡像自定義字體,目前研究解包打包中。
首先先解包原版更新鏡像zh-Hans.bin文件,日誌以下:
Bundle SP01 (Signing Envelope) Cert number 2 Cert file pubprodkey02.pem (Official 2K) Bundle FL01 (Language [lang]) Bundle Type OTA V2 Minimum OTA 1 Target OTA 2 Devices 1 Device Kindle 1 Critical 0 Padding Byte 36 (0x24) MD5 Hash b67f4424bc5d8f38fb55696c57e1d0a5 Metadata 0 x update-zh-Hans_font.dat x zh-Hans.font x manifest
使用Kindletool打包時參照上面的參數寫打包參數:kindletool create ota2 --device k1 --bundle FL01 --cert 2 zh-Tests.tar.gz update_a.bin
掛載Kindle,刪除/mnt/us/system/font/zh-Hans.font
重啓Kindle,已經沒有了中文裏面的另外2個字體。雖然文件校驗顯示打包後的字體和原版徹底不同,可是我依舊嘗試安裝,拷貝字體文件,強行重啓,字體的安裝主要是校驗Cert Key文件,結果失敗。因爲使用指定的Cert key打包的文件沒法解包,因而掛載UBSNET將Kindle下面的默認key文件拷貝出來做爲參數,可是依舊沒法打包,這致使全部的重打包字體若是想要安裝成功就必需要越獄。
新的打包示例:kindletool create ota2 --device k1 --bundle FL01 --tgtrev 2 zh-Hans/zh-Hans.tar.gz update_zh-Hans.bin
(後面測試成功)
拷貝過去重啓後奇怪的是字體沒有安裝,更新文件也沒有刪除,莫非字體更新鏡像須要系統手動下載更新?思考良久決定試試看,將字體文件上傳至本身的服務器,而後修改master.manifest中字體更新文件地址。
可是修改後忘了去除w權限,下載地址還原,第二次修改後去除了w了權限,目前暫未發現字體下載地址被修改。成功聯網下載了我從新打包的字體,系統重啓安裝更新中,卡在字體更新界面一會系統並未重啓,字體安裝成功(第一步解包打包成功,Yayness)。
第二步測試,核心的更新文件是3個:manifest、update-zh-Hans_font.dat、zh-Hans.font。能夠解包轉換的文件分別是:manifes、zh-Hans.font這兩個文件,將解包轉換後從新打包,此步驟嘗試成功後便有了打包更新文件的可能。
12月7日(二度解包打包):
首先開始zh-Hans.font的還原:kindletool convert -w zh-Hans.bin
(因爲kindletool參數問題將font改成bin):
Bundle SP01 (Signing Envelope) Cert number 2 Cert file pubprodkey02.pem (Official 2K)
解包出來的是zh-Hans.font,其屬性爲: Linux Compressed ROM File System data, little endian size 30789632 version #2 sorted_dirs CRC 0xfec5cf0b, edition 0, 11802 blocks, 9 files。文件指紋爲:37824a7650fc8f1fd952413fc5fad029
從新混淆:kindletool create sig --bundle SP01 --unsigned --userdata --cert 0 zh-Hans.tgz data.stgz
(無視最後的2個參數)
將混淆後的文件解包:`kindletool convert -w data.stgz
Bundle SP01 (Signing Envelope) Cert number 0 Cert file pubdevkey01.pem (Developer)
解包後的data_unwrapped.tgz和以前的zh-Hans.font 徹底一致。
其次是manifest的還原:kindletool convert -w manifest.bin
(坑爹的kindletool參數)
日誌以下:
Bundle SP01 (Signing Envelope) Cert number 2 Cert file pubprodkey02.pem (Official 2K)
按照解包日誌寫重打包參數:kindletool create sig --bundle SP01 --unsigned --userdata --cert 0 manifest.tgz data.stgz
(坑爹的輸入輸出參數)
實驗成功後我將zh-Hans.font用cramfsck解包,而後從新用mkcramfs打包。而後完整打包成一個鏡像,這時候這個文字更新包徹底不一樣了。修改好對應的坑爹的/usr/lib/font/manifest裏面的腳本的Hash值。修改好更新腳本里面的更新Hash值,使用第一步的方法打包。依舊是和6號同樣的更新方法上傳,依舊是安裝字體更新的界面,卡上1分鐘後更新成功。
以上的步驟說明了自定義字體的可行性,下面將要作的就是在原字體包上的修改,添加新字體了。
從新打包字體文件:
添加了方正準雅宋字體,刪除楷體的粗體版,修改image_manifest
和manifest_zh-Hans
文件,二者的卻別在於後者多了一個zh-Hans.font的校驗。
照着範例修改好字體的conf文件,字體的family屬性使用TTFEdit查看編輯。USBNET鏈接Kindle,在指定位置拷貝字體,fc-cache.sh生成須要的字體緩存文件。
打包zh-Hans.font鏡像,在字體的文件夾內執行mkcramfs . ../zh-Hans.tgz
混淆字體鏡像,kindletool create sig --bundle SP01 --unsigned --userdata --cert 0 zh-Hans.tgz data.stgz
。而後mv data.stgz zh-Hans.font
這樣子,字體打包就OK了,打包好配置文件,而後壓縮爲tar.gz文件,打包爲更新文件。
用自定義的manifest_zh-Hans腳本覆蓋默認文件 /usr/lib/font/manifest/manifest_zh-Hans
,等待推送更新。
更新開始,緩慢地卡着字體安裝界面,而後卡了字體框架,手動進入USBNET重啓。
12月8號,單獨的字體更新包測試:
還原原來的中文字體鏡像,掛載USBNET後拷貝master.manifest編輯,而後開始按照上面的規則打包鏡像,等待系統自動聯網下載更新,發現更新推送週期好久,若是想要馬上更新的方法就是刪除已經存在的中文字體重啓,而後重啓後聯網下看一看中文書,設置裏面檢查一下更新就開始推送字體了。
字體推送完畢,系統同時安裝2箇中文字體更新包(一個原版,一個個人修改版),卡了1分鐘,自動重啓。
字體未安裝成功,後臺顯示依舊在下載字體,提示更新後系統未自動重啓,字體選擇框內有了後面添加的字體,可是前面添加的2個官方的圓體、楷體卻沒有了。
強制重啓,依舊只有1個自定義準雅宋。沒法單獨的更新包打包麼,發愁中……仔細查看master.manifest腳本,同時查看了啓動日誌和更新日誌,發現問題。ContentPackages.preferences文件中,將zh-Zys當作locales,坑爹啊,知道問題了。從新編輯打包更新文件,修改了語言區域標識。
依舊更新安裝失敗,manifest沒法在系統中註冊。因爲一個語言只能安裝一個額外的文字更新包,因此很遺憾,我沒法建立出單獨的文字更新鏡像。
這樣子的結果很是糟糕,目前的自定義字體方法不適合絕大對數人,我已經將個人思路反饋給外國的大神,坐等他們的研究。
有技術,愛折騰的人能夠等待我後面的字體重打包教程,打包添加本身的字體。固然我也會提供一份打包鏡像給越獄事後的需求不是很高的用戶,我會添加3~4個最受歡迎的字體在裏面。
12月8日晚開始打包:
首選選擇即將打包的字體,在官方的2個字體基礎上增長了4個字體:信黑體、冬青黑體、方正準雅宋、方正準圓。
將字體拷貝進Kindle建立緩存的時候發現掛載的位置空間不夠,決定建立符號鏈接解決。成功創建字體緩存,開始打包。
發現 /var/local/java/prefs/master.manifest
文件老是被系統自動還原,後面發現還原緣由是手動刪除ContentPackages.preferences的緣由,這個時候系統會自動重置字體一塊,可是離線刪除後master.manifest卻不會還原,會在聯網後馬上還原。
備註: ln -s /mnt/us/fonts/* /var/local/font/mnt/zh-Hans_font/fonts/
字體緩存符號連接
掛載系統: mount -o rw,remount /
字體font鏡像打包: mkcramfs . ../zh-Hans.font
字體font鏡像混淆:
mv zh-Hans.font zh-Hans.tgz kindletool create sig --bundle SP01 --unsigned --userdata --cert 0 zh-Hans.tgz data.stgz mv data.stgz zh-Hans.font
manifest生成:
mv manifest_zh-Hans manifest.tgz kindletool create sig --bundle SP01 --unsigned --userdata --cert 0 manifest.tgz data.stgz mv data.stgz manifest