本文乃Siliphen原創(chuàng),轉(zhuǎn)載請(qǐng)注明出處:http://blog.csdn.net/stevenkylelee
本文針對(duì)的是cocos2d-x 3.4 版本進(jìn)行研究。
首先,加密解密應(yīng)當(dāng)是1個(gè)單獨(dú)的話題,1般不會(huì)觸及具體使用的引擎、框架和技術(shù)。
加密算法有Base64,DES等。
Base64的原理類似于凱撒密碼,啥是凱撒密碼呢,就是1個(gè)字符用另外一個(gè)字符來(lái)代替。
比如:a用i代替,b用k代替,以此類推。加密和解密的進(jìn)程就是1個(gè)相互映照的進(jìn)程。
DES是1種使用密鑰的加密算法。
DES和Base64這類無(wú)密鑰的算法在使用上的區(qū)分是:
DES算法本身是可以不保密的,只要保密密鑰便可,密鑰才是解密的關(guān)鍵。
Base64如果用于加密的話,算法本身就是密鑰。要保密算法。
MD5,SHA等是摘要算法。
Base64,DES都可以把密文還原出明文。
而MD5,SHA則不能對(duì)算法作用后的輸出還原出原始數(shù)據(jù)。
摘要算法1般做身份驗(yàn)證。
我們做資源加密是要選擇能把密文還原出明文的算法。
這屬于密碼學(xué)的內(nèi)容了,可深可淺。
可以鑒戒凱撒密碼的原理自己對(duì)每一個(gè)字節(jié)的內(nèi)容進(jìn)行映照來(lái)加密。
也能夠?qū)?字節(jié),2字節(jié),4字節(jié)的數(shù)據(jù),用某個(gè)數(shù)進(jìn)行異或運(yùn)算來(lái)加密。
異或的特性是,用數(shù)A對(duì)內(nèi)容B進(jìn)行異或得到內(nèi)容C,再用數(shù)A對(duì)內(nèi)容C異或可以得到內(nèi)容B。
這個(gè)特性可以被用來(lái)加密。同時(shí),數(shù)A的作用就是密鑰了。
設(shè)計(jì)的加密算法不同,加密算法的使用的接口也不同。
如果是用上面的2種思路做加密算法的話,加密算法的實(shí)現(xiàn)可以“in place”操作,
就是可以直接在密文所在的內(nèi)存進(jìn)行解密,不單獨(dú)分配內(nèi)存來(lái)保存解密后的數(shù)據(jù)。
如果加密算法很復(fù)雜,沒(méi)法“就地還原”,就需要新申請(qǐng)內(nèi)存來(lái)保存解密數(shù)據(jù)。
固然,履行速度1般是”就地還原“快。
我覺(jué)得,如果可以的話,最好是自己設(shè)計(jì)加密算法。
使用現(xiàn)成的DES之類的算法,密鑰是關(guān)鍵。
如果是自己設(shè)計(jì)1個(gè)用密鑰加密的算法,密鑰和算法本身都是不公然的。
破解者要獲得資源明文要經(jīng)過(guò)以下步驟:
1.在程序中找到密鑰的常量。
2.看懂反出來(lái)的匯編還原出算法,或想辦法利用加密算法的匯編代碼。
其中步驟2會(huì)加大解密者解密的難度,這是自己設(shè)計(jì)加密算法比用現(xiàn)成的DES之類著名算法的好處。
我見(jiàn)過(guò)有1些人加密是對(duì)字段內(nèi)容進(jìn)行加密。
比如,他用xml保存數(shù)據(jù),他只對(duì)保存的值進(jìn)行加密。
內(nèi)容類似這樣 <Entity Hp = "密文" AttackValue = "密文" >
這其實(shí)不是1種好的應(yīng)用加密的方式,由于這類方式會(huì):
1.流露程序的配置文件結(jié)構(gòu)。XML、json等。
2.流露了程序可能使用的數(shù)據(jù)結(jié)構(gòu)。看以上內(nèi)容可料想Entity實(shí)體類有2個(gè)字段,Hp(血量),AttackValue(攻擊力)
更完全的加密方式是,對(duì)全部xml、json等文件進(jìn)行加密。
這樣他人就不會(huì)知道關(guān)于你的數(shù)據(jù)的1丁點(diǎn)信息。
這類做法不是直接用數(shù)據(jù)解析庫(kù)封裝的類似LoadFile的函數(shù)直接讀取文件。
而是,先把加密文件用文件讀取方法讀入內(nèi)存,在內(nèi)存解密后,再把解密數(shù)據(jù)傳給解析庫(kù)的解析函數(shù)。
這類做法要求解析庫(kù)有對(duì)內(nèi)存進(jìn)行解析的接口。
比如,若用XML解析庫(kù),就會(huì)棄用LoadFile,要求有Parse方法。
有1種情況可能沒(méi)法對(duì)全部數(shù)據(jù)文件進(jìn)行加密。
就是使用sqlite等數(shù)據(jù)庫(kù)的時(shí)候,這時(shí)候候只能對(duì)字段進(jìn)行加密了。
有些人設(shè)計(jì)加密機(jī)制會(huì)要求配置程序本身。
比如:程序需要1個(gè)配置(1個(gè)開(kāi)關(guān)變量或條件編譯)來(lái)決定是不是對(duì)資源進(jìn)行解密。
發(fā)布時(shí),把資源都加密好,開(kāi)出發(fā)序?qū)Y源的解密。
開(kāi)發(fā)時(shí),資源沒(méi)必要加密,屏蔽程序?qū)Y源的解密。
這類做法需要來(lái)回設(shè)置解密開(kāi)關(guān),比較繁瑣。
有1種實(shí)現(xiàn)思路更有擴(kuò)大性、更靈活、使用更方便。
那就是自己設(shè)計(jì)文件頭。
熟習(xí)Win32編程的人可能會(huì)知道PE文件格式。
Windows運(yùn)行1個(gè)exe之前,會(huì)檢查PE文件頭,
獲得EXE文件的數(shù)據(jù)常量、代碼區(qū)塊等信息后,系統(tǒng)才能正確履行1個(gè)EXE。
我們可以設(shè)計(jì)1個(gè)加密文件頭,加密文件頭有1個(gè)字段標(biāo)識(shí)該文件是不是是被加密過(guò)的。
解密算法可以通過(guò)判斷加密頭的標(biāo)識(shí)符來(lái)決定是不是進(jìn)行解密、采取哪一種解密算法等。
這是1種數(shù)據(jù)驅(qū)動(dòng)式的解密機(jī)制,解密信息都保存在加密數(shù)據(jù)本身中。
對(duì)沒(méi)有被加密過(guò)的數(shù)據(jù),程序判斷沒(méi)有文件加密頭標(biāo)識(shí),就不履行解密。
這樣,程序可以同時(shí)讀取未加密的數(shù)據(jù)和已加密的數(shù)據(jù),而不需要對(duì)程序進(jìn)行任何修改。
注意:加密頭的標(biāo)識(shí)符應(yīng)當(dāng)足夠特殊,保證和未加密的數(shù)據(jù)不會(huì)產(chǎn)生沖突。
若未加密的數(shù)據(jù)恰好出現(xiàn)了加密頭的內(nèi)容,那末程序就會(huì)對(duì)未加密的數(shù)據(jù)進(jìn)行解密。
我的項(xiàng)目配置是用CSV文件。解析器,用的是我自己寫的CSV解析器:
《CSV文件格式解析器的實(shí)現(xiàn):從字符串Split到FSM》
在游戲中這部份的解密,比較容易實(shí)現(xiàn),就是對(duì)全部文件加密,
游戲啟動(dòng)時(shí)把加密文件讀入內(nèi)存進(jìn)行解密,然后把解密數(shù)據(jù)傳到解析器進(jìn)行解析。
1些由游戲產(chǎn)生的需要保存的數(shù)據(jù),我用XML進(jìn)行保存。加解密思路也如上。
但是,對(duì)圖片、動(dòng)畫,粒子、cocostudio1.6導(dǎo)出的UI 等數(shù)據(jù),加密就不那末簡(jiǎn)單了。
由于,像 Sprite::create 這樣的接口,并沒(méi)有提供1個(gè)從內(nèi)存獲得紋理數(shù)據(jù)來(lái)初始化精靈的方式,
而是直接從磁盤文件中讀。用戶在外部是沒(méi)法干預(yù)文件數(shù)據(jù)的讀取載入的。
游戲資源的加密要怎樣做?――只有修改引擎了。- -!
我覺(jué)得,修改引擎其實(shí)不是1個(gè)好的做法。
引擎應(yīng)當(dāng)由引擎提供商來(lái)保護(hù),而不是靠用戶自己來(lái)動(dòng)手。
用戶自己動(dòng)手會(huì)造成項(xiàng)目保護(hù)升級(jí)困難。
自己把引擎改得亂78糟,想升級(jí)引擎到新的版本會(huì)變成很麻煩。
就算是修改了1點(diǎn),升級(jí)引擎版本1次,就要做1次修改,這樣也很麻煩。
要修改引擎,首先要跟蹤調(diào)試,
以cocos2d-x 3.4 作為實(shí)驗(yàn)版本,從Sprite::create入口,1步步跟下去,
看看引擎是在哪里載入文件數(shù)據(jù)的。
經(jīng)過(guò)調(diào)試跟蹤,Sprite::create的調(diào)用堆棧以下:
getData
FileUtilsWin32::getDataFromFile
Image::initWithImageFile
TextureCache::addImage
Sprite::initWithFile
Sprite::create
在windows上,精靈載入圖片,是調(diào)用到了
CCFileUtils-win32.cpp 這個(gè)文件中的
static Data getData(const std::string& filename, bool forString) 函數(shù)。
這個(gè)函數(shù)是1個(gè)非類成員靜態(tài)函數(shù)。
再調(diào)試下其他的數(shù)據(jù)載入,cocostudio1.6做的動(dòng)畫的調(diào)用堆棧是:
cocos2d::FileUtilsWin32::getFileData
cocostudio::DataReaderHelper::addDataFromFile
cocostudio::ArmatureDataManager::addArmatureFileInfo
經(jīng)過(guò)了多種文件類型載入的跟蹤調(diào)試后,總結(jié),
基本上文件的載入函數(shù)有2個(gè),都在CCFileUtils-win32.cpp文件中,
1.FileUtilsWin32::getFileData
2.getData
要做解密的話,就是修改這2個(gè)函數(shù)了。
值得注意的1點(diǎn)是:getData函數(shù)的簽名是:
static Data getData(const std::string& filename, bool forString)
forString這個(gè)參數(shù),用于標(biāo)識(shí)讀入的文件是否是1個(gè)文本文件。
如果forString為真的話,buffer就要多分配1個(gè)字節(jié),用來(lái)放置C語(yǔ)言的字符串結(jié)束符 主站蜘蛛池模板: 日韩毛片免费视频一级特黄 | 欧美精品免费在线 | 在线观看黄a | 日本视频网址 | 日韩国产成人av | 激情综合五月天 | 欧美一区二区三区在线观看视频 | 91精品国产91久久综合 | 91精品国产综合久久福利软件 | 日本视频在线 | 午夜在线视频 | 亚洲精品乱码久久久久v最新版 | 久久91精品国产91久久跳 | 综合久久久久久久 | 日韩欧美一区二区三区免费观看 | 成人综合一区 | 97人人草| 久久wwww | 中国一级特黄毛片大片 | 成人午夜网 | 欧美日韩综合视频 | 99久久99久久 | 91直接看 | 久久久久国产精品人 | 国产三级一区二区三区 | 日日lu | a级片网站| 日韩亚洲精品在线 | 九九视频在线 | 国产二区三区 | 国产在线视频一区二区三区 | a级毛片观看 | 久久久久成人网 | 久久99精品久久久久久国产越南 | 国产精品五区 | 男女涩涩视频 | 欧美日韩综合一区 | av电影在线网址 | 欧美精品乱码久久久久久按摩 | 一区二区三区在线 | 国产精品99久久久久久大便 |