這里主要總結(jié)一下單機(jī)手機(jī)游戲里一些保護(hù)措施朵诫。雖然看似簡(jiǎn)單,但效果也還可以薄扁,能讓試圖破解你游戲的人稍微費(fèi)點(diǎn)功夫剪返。當(dāng)然完全防止破解是不太現(xiàn)實(shí)的,這本身就是個(gè)成本問題泌辫,破解者全力以赴于破解随夸,開發(fā)者還是要全力以赴于游戲邏輯的。
內(nèi)存加密
我記得我十幾年前玩一些PC單機(jī)游戲的時(shí)候震放,使用過一個(gè)叫金山游俠的工具修改內(nèi)存,把游戲里的錢或者其他屬性改成我想要的驼修〉钏欤基本原理是,游戲運(yùn)行的時(shí)候里面的一些數(shù)值比如金錢乙各、生命值之類的都是存儲(chǔ)在內(nèi)存中的墨礁,修改器就通過搜索游戲進(jìn)程中中所有特定數(shù)值的內(nèi)存并返回,讓你可以修改耳峦。比如你在一個(gè)游戲里有22222金幣恩静,然后你用修改器搜索內(nèi)存,找到了一個(gè)地方存著這么個(gè)值蹲坷,那你就基本可以肯定這個(gè)地址就是游戲程序用來存放金幣的內(nèi)存地址驶乾,然后只要修改這個(gè)地址上的值,你游戲里的錢就也被改了循签;如果第一次搜索搜到多個(gè)結(jié)果级乐,可以玩一會(huì)兒游戲等數(shù)值變了再搜,多試幾次县匠,幾次的數(shù)值變動(dòng)情況都對(duì)應(yīng)到同一個(gè)地址也就能確認(rèn)位置了风科。
應(yīng)對(duì)這種作弊方式很簡(jiǎn)單撒轮,一種是加密存儲(chǔ)一些關(guān)鍵性數(shù)值,每次代碼中要讀取/賦值也都要走一遍加密/解密的步驟贼穆,內(nèi)存中永遠(yuǎn)存放的是密文题山。當(dāng)然這樣別人也很容易發(fā)現(xiàn),游戲中明明有的某個(gè)數(shù)值搜內(nèi)存竟然搜不到故痊,那他也許就會(huì)采取措施來定位你的密文然后試圖解密了臀蛛。所以最好還是在內(nèi)存中放一份明文的數(shù)值,讓玩家可以搜到崖蜜,當(dāng)然等他們改了你就能知道浊仆,因?yàn)楹兔芪膶?duì)比不一致,然后就能知道這個(gè)家伙是個(gè)作弊玩家了豫领。
至于檢測(cè)到作弊玩家后如何處理抡柿,這就取決于開發(fā)者的腦洞了〉瓤郑可以對(duì)設(shè)備封號(hào)洲劣,可以偷偷的把這個(gè)玩家游戲里需要花錢地方的數(shù)值調(diào)高,或者讓他的游戲變成另一個(gè)完全不同的樣子课蔬,甚至我們的策劃表示可以直接告訴作弊玩家“我們發(fā)現(xiàn)你是個(gè)作弊玩家囱稽,現(xiàn)在給你一個(gè)機(jī)會(huì),只要充值10塊錢二跋,立馬轉(zhuǎn)正成正版玩家”战惊。
存檔加密
由于是單機(jī)游戲,所以存檔都存儲(chǔ)在本地的文件系統(tǒng)上扎即。在Android和越獄的iOS上,是可以很容易得到這個(gè)存檔文件的各拷。如果直接使用某種文本格式來存儲(chǔ)游戲進(jìn)度,比如把存檔序列化成xml或者json之類,那簡(jiǎn)直就是不設(shè)防互例,隨便用一個(gè)文本編輯器打開稍微看一下就能知道怎么改腥光;稍微好一點(diǎn)的用二進(jìn)制來存放,但這也是可以很容易找到規(guī)律捉片,或者干脆用像修改內(nèi)存那樣的方式來修改存檔。
基于以上的情況莹规,游戲存檔最好加密進(jìn)行存儲(chǔ),而且最好使用密鑰加密的算法來做而不要把加密解密算法寫死。這樣以后哪天發(fā)現(xiàn)被破解了可以再更換密鑰患久。
存檔綁定
雖然存檔加密了,破解起來稍微費(fèi)點(diǎn)勁溉旋,但是還是可以拷貝存檔耙叵小!誰誰誰玩出一個(gè)很不錯(cuò)的存檔量淌,分享出存檔文件給大家呀枢。其實(shí)這是很破壞游戲樂趣的一件事裙秋,正常點(diǎn)的玩家都不太會(huì)去做摘刑。但如果你的單機(jī)游戲還是有點(diǎn)玩家間交互的紧唱,比如有排行榜蛹锰,看著那些作弊玩家占據(jù)著高名次铜犬,肯定覺得挺沒意思的纷宇,然后就刪游戲了吧。
其實(shí)處理這種情況很容易桩砰,讓存檔跟設(shè)備綁定就好了拓春,而且存檔肯定要加密,不然什么都白搭亚隅。具體做法分兩種硼莽,一種是在玩家第一次玩游戲存檔被創(chuàng)建的時(shí)候把這臺(tái)設(shè)備的device id也寫到存檔里,之后每次要讀存檔的時(shí)候都比較存檔里的device id和本機(jī)的device id是否一致煮纵,不一致則不讓進(jìn)游戲或者開啟新的存檔懂鸵;另一種方式是把本機(jī)的device id來作為加密存檔的密鑰來使用偏螺,這樣存檔被拷貝到別的機(jī)器上之后也是無法正常讀取的。
內(nèi)購(gòu)驗(yàn)證
如果一個(gè)游戲里可以花錢購(gòu)買金幣道具之類的矾瑰,作弊者就可以通過內(nèi)購(gòu)破解來不花錢就得到那些東西砖茸。內(nèi)購(gòu)破解是一件比較通用的事情,因?yàn)橥婕也皇峭ㄟ^直接破解你的游戲而是破解了AppStore或者GooglePlay的支付來達(dá)到的殴穴;一般是在越獄的iOS設(shè)備和root的Android設(shè)備上進(jìn)行的凉夯。
由于這種事情是在游戲以外的部分做了手腳,從游戲的層面上無法判斷采幌,在你游戲里你會(huì)收到正確的購(gòu)買成功回調(diào)劲够。不過好在AppStore和GooglePlay都提供了額外的協(xié)議允許你去驗(yàn)證訂單,所以你可以在客戶端的支付完成后再去蘋果或谷歌的服務(wù)器查證剛剛的那筆訂單的真實(shí)性休傍。這一步都是放在自己的服務(wù)器上來進(jìn)行的(我不確定手機(jī)端是否也能驗(yàn)證訂單征绎,不過即便可以放在手機(jī)端做也是不安全的),也就是你在手機(jī)端支付完成后再和自己的服務(wù)器通信把訂單的信息傳給自己服務(wù)器,自己的服務(wù)器再去跟蘋果或谷歌的服務(wù)器驗(yàn)證這筆訂單然后再告訴手機(jī)端這筆交易是不是有效。
這樣做的話首先自己需要架設(shè)服務(wù)器專門用于內(nèi)購(gòu)驗(yàn)證贡珊,這是額外的開銷;另外玩家在游戲中購(gòu)買一個(gè)東西的時(shí)間會(huì)變長(zhǎng)凫岖,稍微影響一些體驗(yàn)。當(dāng)然堵死了內(nèi)購(gòu)破解這條路并不意味著能賺到原本內(nèi)購(gòu)破解所損失的錢逢净,很多作弊玩家大不了就當(dāng)免費(fèi)玩家好了哥放,另外還有一些情商高不放棄的會(huì)繼續(xù)嘗試其他的方法。
強(qiáng)制更新
雖然是單機(jī)游戲爹土,一般感覺是不該做強(qiáng)制更新這種事的甥雕,當(dāng)然使用了熱更新技術(shù)的人也可以忽略這條。
這一步需要一個(gè)服務(wù)器胀茵,當(dāng)然一般的CDN服務(wù)器就可以了(這只需要錢社露,不需寫服務(wù)器代碼),把一些基本的配置信息放在上面琼娘,每次游戲開啟的時(shí)候都下載一下并存到本地(當(dāng)然不一定要每次都下載呵哨,可以先下載一個(gè)放版本號(hào)的小文本,只有配置文件的版本比本地新才下)轨奄。然后這種配置信息里面可以保存一個(gè)游戲最低版本號(hào)的字段,如果發(fā)現(xiàn)當(dāng)前運(yùn)行的游戲版本低于該版本就把游戲鎖定不讓玩并引導(dǎo)玩家去更新游戲版本就好了(這種配置文件最好好也加密)拒炎。
其實(shí)這么做的意義在安全方面就是可以把以前發(fā)布的有嚴(yán)重漏洞可以利用的那些版本給干掉挪拟。
改時(shí)間限制
這一條主要是針對(duì)那些對(duì)時(shí)間敏感的單機(jī)游戲,比如掛機(jī)游戲這種击你。如果只是取本地時(shí)間的話玉组,至少可以做成每次寫存檔都把當(dāng)前時(shí)間寫進(jìn)去谎柄,然后玩家改時(shí)間作弊通常是改到未來把未來該得到的東西都得到了然后再改回來,只要你發(fā)現(xiàn)時(shí)間倒退了就對(duì)玩家做出一定的懲罰或者怎么樣就可以了惯雳。
還有一種是聯(lián)機(jī)獲取網(wǎng)絡(luò)時(shí)間朝巫,不時(shí)的獲取網(wǎng)絡(luò)時(shí)間來跟本地時(shí)間進(jìn)行對(duì)比以判斷玩家是否在時(shí)間上作弊了,或者在某些比較重要的邏輯進(jìn)行的時(shí)候只使用網(wǎng)絡(luò)時(shí)間(比如每日登錄獎(jiǎng)勵(lì))石景。具體的做法可以是自己架設(shè)一個(gè)服務(wù)器來提供時(shí)間劈猿,當(dāng)然也可以從網(wǎng)絡(luò)上免費(fèi)的授時(shí)服務(wù)器來直接獲取時(shí)間。
不過使用授時(shí)服務(wù)器獲取網(wǎng)絡(luò)時(shí)間有一些問題潮孽,由于獲取時(shí)間使用的是NTP協(xié)議(參看RFC 1305)揪荣,而NTP是基于UDP報(bào)文進(jìn)行傳輸?shù)模云鋵?shí)不是那么穩(wěn)定往史,實(shí)測(cè)下來有的時(shí)候失敗率挺高的仗颈;還有一個(gè)就是發(fā)現(xiàn)國(guó)內(nèi)部分地區(qū)的運(yùn)營(yíng)商的網(wǎng)絡(luò)環(huán)境下一直無法獲取到時(shí)間,由于是玩家報(bào)告的椎例,所以無法得知究竟是那個(gè)地方連不到國(guó)家授時(shí)中心還是那個(gè)運(yùn)營(yíng)商封了NTP協(xié)議挨决。
遷存檔限制
之前我所做的單機(jī)游戲里有一個(gè)功能,遷存檔订歪。雖然做了防止存檔拷貝脖祈,但是為了讓玩家可以在換手機(jī)的時(shí)候繼續(xù)在新手機(jī)上沿著她(這里用“她”因?yàn)槟莻€(gè)游戲的大部分玩家是妹紙)的老存檔進(jìn)行我們的游戲,我們提供了官方的存檔遷移功能陌粹。
具體的做法就是先把存檔上傳到我們服務(wù)器撒犀,并返回給玩家一個(gè)隨機(jī)碼,然后客戶端鎖定上傳了存檔的游戲掏秩,讓玩家通過那個(gè)碼再?gòu)男略O(shè)備里把存檔下載下來或舞,只能下載一次。
這個(gè)功能給很多作弊者帶來了新的機(jī)遇蒙幻,他們紛紛在淘寶上開店映凳,通過遷移存檔的方式,遠(yuǎn)程收錢幫助其他玩家修改存檔邮破。當(dāng)時(shí)我們還沒有做內(nèi)購(gòu)驗(yàn)證诈豌,很多賣家先把其他玩家的存檔遷移到自己手機(jī)上然后用內(nèi)購(gòu)破解購(gòu)買了很多充值幣再把存檔返還給買家。當(dāng)然后來做了內(nèi)購(gòu)驗(yàn)證后一些只會(huì)內(nèi)購(gòu)破解的淘寶賣家被淘汰了抒和,但還是有人能繼續(xù)做這個(gè)生意矫渔,這充分了說明道高一尺,魔高一丈摧莽。
所以我覺得這種功能的使用應(yīng)該是要受到一定限制的庙洼,比如固定的次數(shù)限制或者玩滿多少個(gè)小時(shí)之后才有一次遷移的機(jī)會(huì)之類。
代碼混淆
這個(gè)大家基本都知道,其實(shí)就是在游戲的源代碼層面油够,在保持代碼功能不改變的情況下將代碼變的面目全非蚁袭。一般就是通過大量的替換原有標(biāo)識(shí)符的名字來達(dá)到這樣的目的,不過這肯定不是人工來做石咬,都是用代碼混淆器來自動(dòng)完成的揩悄。
當(dāng)然對(duì)于某些寫代碼自帶混淆的人來說,這一步其實(shí)沒什么意義鬼悠。(對(duì)吧删性,天王~)
游戲加殼
這個(gè)其實(shí)大家也都知道的,在游戲的包編譯出來之后進(jìn)行的厦章。iOS的ipa我不是很清楚镇匀,但是對(duì)Android的apk來說,這一步還是挺有必要的袜啃。不加殼的話汗侵,別人可以很輕易的反編譯你的包,加一點(diǎn)他自己的廣告(或替換掉原有的)后重新打包在別的應(yīng)用市場(chǎng)上發(fā)布群发;加殼的話晰韵,別人要稍微費(fèi)點(diǎn)事來破解你的包。熟妓。雪猪。
現(xiàn)在國(guó)內(nèi)的有些渠道甚至?xí)竽惆寻峤唤o他們之前先加個(gè)殼,不過不知道為什么一般是指定了用360加固寶起愈,其實(shí)也是有一些比較安全的加殼工具比如APK Protect這種只恨。
好了,暫時(shí)就想到這些抬虽。