J2ME遊戲破解心得之二

來源:互聯網
上載者:User

      上一次一篇《J2ME遊戲破解心得暨反編譯位元組碼操作研究》記錄了我破解一款RPG遊戲的簡訊計費代碼,不出一個月,被許許多多的網站轉載,而且沒有註明出處。當然,這到不是最重要的,重要的是大家學會了破解的方法。
      最近在破解另一個深受大家喜愛的遊戲時(名字我還是不提了),遇到了和上次不同的問題,雖然都是傳送簡訊計費,但代碼的結構和邏輯發生了比較大的變化。上次破解時,關於傳送簡訊的判斷比較簡單,就是成功了就返回成功,失敗了捕捉異常返回失敗,破解點也就顯得簡單,只需把返回失敗的地方改成返回成功就行了。而這次是使用了一個匿名的線程類,發送時啟動一個線程去處理,外部通過一些發送的狀態變數值來判斷。該類對應的檔案是b.class,而匿名的線程類被編譯到b$1.class中。b$1.class檔案反編譯出的代碼如下:

 public void run()<br />{<br />try<br />{<br />b.if = true;<br />MessageConnection messageconnection = null;<br />String s = "sms://" + b.access$000(b.this);<br />System.out.println(s);<br />messageconnection = (MessageConnection)Connector.open(s);<br />TextMessage textmessage = (TextMessage)messageconnection.newMessage("text");<br />textmessage.setPayloadText(b.access$100(b.this));<br />messageconnection.send(textmessage);<br />messageconnection.close();<br />b.int[0]++;<br />b.this.do.setRecord(1, b.int, 0, 1);<br />if (b.int[0] < 2)<br />{<br />b.try = 3;<br />} else<br />{<br />g.j = 1;<br />a.do();<br />b.if = false;<br />b.try = 6;<br />}<br />}<br />catch (Exception exception)<br />{<br />b.try = -1;<br />exception.printStackTrace();<br />}<br />} 

可見要發送兩次簡訊進行計費(心太黑了),b.try就是外部用於判斷是否發送夠的標誌,發送夠之後還做了其他一些事情。可見,用上一次的更改true、false不行了。網上也有一個例子是sendOK和sendFalse兩個函數交換位置的,在這裡也行不通。

我嘗試了更改位元組碼,但發現在需要更改這樣較多的位元組碼時,很難做到不出錯。最後還是想到用javassist來處理,思路就是把messageconnection.send(textmessage);這一句“幹掉”,當然,你也可以把MessageConnection相關的都“幹掉”,那樣連提示傳送簡訊都沒有了。

經過多方尋找,找到了CtMethod的instrument方法,該方法可以對method內部的每一個運算式進行判斷、替換,下面就來看看“幹掉”send調用的代碼:

 public static void main(String[] args) throws Exception{</p><p>ClassPool pool = ClassPool.getDefault();<br />CtClass cc = pool.get("c.b$1");<br />System.out.println(cc.getName());</p><p>CtMethod cm = cc.getDeclaredMethod("run", new CtClass[0]);</p><p>cm.instrument(new ExprEditor() {</p><p>public void edit(MethodCall m) throws CannotCompileException {</p><p>if (m.getClassName().equals("javax.wireless.messaging.MessageConnection")</p><p> && m.getMethodName().equals("send"))</p><p> m.replace("{ }");</p><p> }<br />});</p><p>cc.writeFile();</p><p>}

這個ExprEditor的意思就是,當運算式是調用MessageConnection類的send方法時,對該調用進行替換,我這裡是替換成Null 字元串。

至此,該類替換完畢。反編譯替換後的b$1.class代碼變成以下:

 public void run()<br />{<br />try<br />{<br />b.if = true;<br />MessageConnection messageconnection = null;<br />String s = "sms://" + b.access$000(b.this);<br />System.out.println(s);<br />messageconnection = (MessageConnection)Connector.open(s);<br />TextMessage textmessage = (TextMessage)messageconnection.newMessage("text");<br />textmessage.setPayloadText(b.access$100(b.this));<br />TextMessage textmessage1 = textmessage;<br />MessageConnection messageconnection1 = messageconnection;<br />messageconnection.close();<br />b.int[0]++;<br />b.this.do.setRecord(1, b.int, 0, 1);<br />if (b.int[0] < 2)<br />{<br />b.try = 3;<br />} else<br />{<br />g.j = 1;<br />a.do();<br />b.if = false;<br />b.try = 6;<br />}<br />}<br />catch (Exception exception)<br />{<br />b.try = -1;<br />exception.printStackTrace();<br />}<br />}

send那一行代碼的確沒有了,但多了兩行這樣的代碼:

            TextMessage textmessage1 = textmessage;
            MessageConnection messageconnection1 = messageconnection;
不知道是為什麼,但明顯這兩行對整個方法沒有影響。

重新打包進jar,放在手機上測試,成功!

注意:

由於這是J2ME的程式,破解時最好建立一個J2ME的項目,儘管實際上就是一般的java控制台程式。因為我之前用java項目,class是改了,但是打進jar包運行要出錯,而在J2ME項目下,修改後的class打進jar包是成功運行了的。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.