最近搞了幾個apk的破解,主要是對smali代碼的修改,看上去挺簡單的,但是實際動手,卻不是那么回事了。
一開始是尋找關鍵位置,當然是采用加Log的辦法了,加入以下Log:
const-string v0, "SMS" invoke-static {v0, v1}, Landroid/util/Log;->v(Ljava/lang/String;Ljava/lang/String;)I
開啟DDMS查看,可是沒有發現任何帶有“SMS”標識的信息,以為沒有執行到位,在mainActivity的onCreate中添加后仍然沒有,奇怪了。於是乎,換了種方式,直接加入如下代碼:
//注意makeText的第一個參數是Context類型的。 const-string v0, "SMS Bindi" const/4 v2, 0x1 iget-object v1, p0, Lcom/chinamworld/mobile_bank/i;->a:Lcom/chinamworld/mobile_bank/BTCSMSBindDeviceActivity; invoke-static {v1, v0, v2}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast; move-result-object v0 invoke-virtual {v0}, Landroid/widget/Toast;->show()V
加入后程序啟動不起來了,查看logcat時發現context不對,原來我把makeText的第一個參數整錯了,修改后重打包運行一切OK,成功的找到關鍵位置 。
后來需要加入一段調用startActivity的代碼:
//在Lcom/newtime/KC2011的changeListener方法(即Lcom/newtime/KC2011$changeListener文件)中調用startActivity
//在Lcom/newtime/KC2011中聲明: .field protected mContext:Landroid/content/Context; //在本文件中聲明 .field final synthetic this$0:Lcom/newtime/KC2011; new-instance v0, Landroid/content/Intent; invoke-direct {v0}, Landroid/content/Intent;-><init>()V .line 300 .local v0, intent:Landroid/content/Intent; iget-object v2, p0, Lcom/newtime/KC2011$changeListener;->this$0:Lcom/newtime/KC2011; iget-object v2, v2, Lcom/newtime/KC2011;->mContext:Landroid/content/Context; const-class v3, Lcom/newtime/service/KcLoginActivity; invoke-virtual {v0, v2, v3}, Landroid/content/Intent;->setClass(Landroid/content/Context;Ljava/lang/Class;)Landroid/content/Intent; .line 301 iget-object v2, p0, Lcom/newtime/KC2011$changeListener;->this$0:Lcom/newtime/KC2011; iget-object v2, v2, Lcom/newtime/KC2011;->mContext:Landroid/content/Context; invoke-virtual {v2, v0}, Landroid/content/Context;->startActivity(Landroid/content/Intent;)V
發現程序又崩潰了,logcat提示不能訪問Lcom/newtime/KC2011的mContext,原來是在Lcom/newtime/KC2011中把mContext聲明為private了,改成如下之后一切運行正常:
.field protected mContext:Landroid/content/Context;
另外如果在重打包時出現如下錯誤:
[682,1] The register number must be less than v16
[684,4] All register args must fit in 4 bits
Exception in thread "main" brut.androlib.AndrolibException: Could not smali file: C:\Users\Tim\Desktop\ABC_Android_V1.1.0\smali\com\android\bankabc\FormAction.smali at brut.androlib.src.DexFileBuilder.addSmaliFile(DexFileBuilder.java:45) at brut.androlib.src.DexFileBuilder.addSmaliFile(DexFileBuilder.java:33) at brut.androlib.src.SmaliBuilder.buildFile(SmaliBuilder.java:66) at brut.androlib.src.SmaliBuilder.build(SmaliBuilder.java:50) at brut.androlib.src.SmaliBuilder.build(SmaliBuilder.java:37) at brut.androlib.Androlib.buildSourcesSmali(Androlib.java:257) at brut.androlib.Androlib.buildSources(Androlib.java:214) at brut.androlib.Androlib.build(Androlib.java:205) at brut.androlib.Androlib.build(Androlib.java:176) at brut.apktool.Main.cmdBuild(Main.java:228) at brut.apktool.Main.main(Main.java:79) ->編譯完成!
則是因為很多指令(如invoke-virtual等指令)不能夠使用大於15的寄存器,故應該加上“move-object/from16 v1, px”語句進行轉換。也可以用“invoke-virtual/range {p1 .. p1}”指令,但是這里要求變量名稱需要連續。
px registers are after vx ones, so if you have for example 17 vx registers, then p0 is v17. Most of instructions can't use registers above v15, so you have to move values to "lower" registers to use them.
補充:
后來通過加入類似如下的log,終於正常監控到log輸出了:
const-string v1, "sms" const-string v4, "send a message" invoke-static {v1, v4}, Landroid/util/Log;->i(Ljava/lang/String;Ljava/lang/String;)I