綁定帳號登入

Android 台灣中文網

打印 上一主題 下一主題

[教程] android逆向分析之smali語法(二)

[複製連結] 查看: 2795|回覆: 2|好評: 0
跳轉到指定樓層
樓主
fam1001 | 收聽TA | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
發表於 2016-3-22 13:41

馬上加入Android 台灣中文網,立即免費下載應用遊戲。

您需要 登錄 才可以下載或查看,沒有帳號?註冊

x
六、for循環
  1. # virtual methods  
  2. .method public onClick(Landroid/view/View;)V  
  3. .locals 9  
  4. .parameter 「v」  
  5.   
  6. .prologue  
  7. .line 36  
  8. invoke-virtual {p1}, Landroid/view/View;->getId()I    # 非靜態方法參數中隱含的第一個參數p0為this指針, p1為第一個參數, 即View對像  
  9.   
  10. move-result v6     # 把上次的計算結果給第七個寄存器,v6=p1.getId(), v6中為View對象的id  
  11.   
  12. packed-switch v6, :pswitch_data_0    # switch(v6)  
  13.   
  14. # —————– 程式出口開始 ——————  
  15. .line 58  
  16. :goto_0         # for循環出口  
  17. return-void     # return;  
  18. # —————– 程式出口結束 ——————  
  19.   
  20. # —————– 獲取控件內容開始 ——————  
  21. .line 39  
  22. :pswitch_0  
  23. iget-object v6, p0, Lcom/sanwho/crackdemo/ForActivity$1;->this$0:Lcom/sanwho/crackdemo/ForActivity;  # v6保存this指針  
  24.   
  25. const v7, 0x7f080001   # v7 = txtValue1, 該id保存在public.xml中  
  26.   
  27. invoke-virtual {v6, v7}, Lcom/sanwho/crackdemo/ForActivity;->findViewById(I)Landroid/view/View; # findViewById(txtValue1)  
  28.   
  29. move-result-object v4  # v4為txtValue1對應的View對像  
  30.   
  31. check-cast v4, Landroid/widget/EditText;  # 將View對像轉換成EditText, 完成後v4中是txtValue1對像, 失敗會拋出ClassCastException異常  
  32.   
  33. .line 40  
  34. .local v4, txtValue1:Landroid/widget/EditText;  
  35. iget-object v6, p0, Lcom/sanwho/crackdemo/ForActivity$1;->this$0:Lcom/sanwho/crackdemo/ForActivity;  
  36.   
  37. const v7, 0x7f080003  # v7 = txtValue2  
  38.   
  39. invoke-virtual {v6, v7}, Lcom/sanwho/crackdemo/ForActivity;->findViewById(I)Landroid/view/View;  
  40.   
  41. move-result-object v5  # v5為txtValue2對應的View對像  
  42.   
  43. check-cast v5, Landroid/widget/EditText;  # 將View對像轉換成EditText, 完成後v5中是txtValue2對像  
  44.   
  45. .line 41  
  46. .local v5, txtValue2:Landroid/widget/EditText;  
  47. invoke-virtual {v4}, Landroid/widget/EditText;->getText()Landroid/text/Editable;    # 根據.line 39處可知,v4中為txtValue1對像  
  48.   
  49. move-result-object v6   # v6 = txtValue1.getText();  
  50.   
  51. invoke-interface {v6}, Landroid/text/Editable;->toString()Ljava/lang/String;  
  52.   
  53. move-result-object v6   # v6 = txtValue1.getText().toString();  
  54.   
  55. invoke-static {v6}, Ljava/lang/Integer;->parseInt(Ljava/lang/String;)I  
  56.   
  57. move-result v1    # v1 = Integer.parseInt(v6); 也就是起始數值  
  58.   
  59. .line 42  
  60. .local v1, from:I  
  61. invoke-virtual {v5}, Landroid/widget/EditText;->getText()Landroid/text/Editable;    # 根據.line 40處可知,v5中為txtValue2對像  
  62.   
  63. move-result-object v6  # v6 = txtValue2.getText();  
  64.   
  65. invoke-interface {v6}, Landroid/text/Editable;->toString()Ljava/lang/String;  
  66.   
  67. move-result-object v6  # v6 = txtValue2.getText().toString();  
  68.   
  69. invoke-static {v6}, Ljava/lang/Integer;->parseInt(Ljava/lang/String;)I  
  70.   
  71. move-result v0    # v0 = Integer.parseInt(v6); 也就是結束數值  
  72.   
  73. # —————– 獲取控件內容結束 ——————  
  74.   
  75. .line 43  
  76. .local v0, end:I  
  77. if-le v1, v0, :cond_0   # if v1 <= v0, 即起始數值 <= 結束數值, 則跳到cond_0  
  78.   
  79. # —————– 起始數值 > 結束數值時開始 ——————  
  80. .line 45  
  81. iget-object v6, p0, Lcom/sanwho/crackdemo/ForActivity$1;->this$0:Lcom/sanwho/crackdemo/ForActivity;  
  82.   
  83. const-string v7, 「u8d77u59cbu6570u503cu4e0du80fdu5927u4e8eu7ed3u675fu6570u503c!」  # 起始數值不能大於結束數值  
  84.   
  85. #calls: Lcom/sanwho/crackdemo/ForActivity;->MessageBox(Ljava/lang/String;)V  
  86. invoke-static {v6, v7}, Lcom/sanwho/crackdemo/ForActivity;->access$0(Lcom/sanwho/crackdemo/ForActivity;Ljava/lang/String;)V  
  87.   
  88. goto :goto_0  
  89.   
  90. # —————– 起始數值 > 結束數值時結束 ——————  
  91.   
  92. # —————– 起始數值 <= 結束數值時開始 —————–  
  93. .line 49  
  94. :cond_0  
  95. const/4 v3, 0x0   # v3 = 0, 即int sum = 0;  
  96.   
  97. .line 50  
  98. .local v3, sum:I  
  99. move v2, v1       # v2 = v1, v2即源碼中的i變量  
  100.   
  101. .local v2, i:I  
  102. :goto_1           # for循環主要入口  
  103. if-le v2, v0, :cond_1   # if 目前數值 <= 結束數值, 跳到cond_1;  否則循環結束, 顯示累加結果  
  104.   
  105. .line 54  
  106. iget-object v6, p0, Lcom/sanwho/crackdemo/ForActivity$1;->this$0:Lcom/sanwho/crackdemo/ForActivity;  # v6指向MessageBox方法  
  107.   
  108. new-instance v7, Ljava/lang/StringBuilder;    # v7為StringBuilder對像  
  109.   
  110. const-string v8, 「u7d2fu52a0u7ed3u679cuff1a」  # v8 = 「累加結果:」  
  111.   
  112. invoke-direct {v7, v8}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V  # 以v8為參數調用StringBuilder構造函數  
  113.   
  114. invoke-static {v3}, Ljava/lang/Integer;->toString(I)Ljava/lang/String; # 把int型的sum值轉成字符串  
  115.   
  116. move-result-object v8   # v8 = Integer.toString(v3); 此時v8中為sum的值  
  117.   
  118. invoke-virtual {v7, v8}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;   # 把累加結果和sum的值進行追加  
  119.   
  120. move-result-object v7  # v7 為 「累加結果:」 + Integer.toString(sum)的StringBuilder對像;  
  121.   
  122. invoke-virtual {v7}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;  # 將v7轉為字符串對像  
  123.   
  124. move-result-object v7   # v7 = 「累加結果:」 + Integer.toString(sum);  
  125.   
  126. #calls: Lcom/sanwho/crackdemo/ForActivity;->MessageBox(Ljava/lang/String;)V  
  127. invoke-static {v6, v7}, Lcom/sanwho/crackdemo/ForActivity;->access$0(Lcom/sanwho/crackdemo/ForActivity;Ljava/lang/String;)V  # 調用MessageBox顯示字符串  
  128.   
  129. goto :goto_0  # 跳到goto_0  
  130. # —————– 起始數值 <= 結束數值時結束 —————–  
  131.   
  132. .line 52  
  133. :cond_1           # 加1操作入口  
  134. add-int/2addr v3, v2   # v3 = v3 + v2, 即sum += i  
  135.   
  136. .line 50  
  137. add-int/lit8 v2, v2, 0x1  # v2 = v2 + 1, , 即i = i + 1  
  138.   
  139. goto :goto_1   # 跳到for循環入口繼續比對  
  140.   
  141. .line 36  
  142. nop  
  143.   
  144. :pswitch_data_0  
  145. .packed-switch 0x7f080004  
  146. :pswitch_0  
  147. .end packed-switch  
  148. .end method
複製代碼
源碼解釋
  1. Button.OnClickListener onClickListener = new Button.OnClickListener()  
  2. {  
  3.     @Override  
  4.     public void onClick(View v)  
  5.     {  
  6.         switch (v.getId())  
  7.         {  
  8.         case R.id.btnSubmit:  
  9.             EditText txtValue1 = (EditText) findViewById(R.id.txtValue1);  
  10.             EditText txtValue2 = (EditText) findViewById(R.id.txtValue2);  
  11.             int from = Integer.parseInt(txtValue1.getText().toString());  
  12.             int end = Integer.parseInt(txtValue2.getText().toString());  
  13.             if (from > end){  
  14.                 MessageBox("起始數值不能大於結束數值!");  
  15.             }  
  16.             else  
  17.             {  
  18.                  int sum = 0;  
  19.                  for (int i = from; i <= end; i++){  
  20.                      
  21.                 sum += i;  
  22.                    }  
  23.                   MessageBox("累加結果:" + Integer.toString(sum));  
  24.             }  
  25.             break;  
  26.         }  
  27.     }  
  28. };  
  29.   
  30. private void MessageBox(String str)  
  31. {         
  32.     Toast.makeText(this, str, Toast.LENGTH_LONG).show();  
  33. }
複製代碼

八、內部類

Java 語言允許在一個類的內部定義另一個類,這種在類中定義的類被稱為內部類(Inner Class)。內部類可分為成員內部類、靜態嵌套類、方法內部類、匿名內部類。前面我們曾經說過,baksmali 在反編譯dex 檔案的時候,會為每個類單獨生成了一個 smali 檔案,內部類作為一個獨立的類,它也擁有自己獨立的smali 檔案,只是內部類的檔案名形式為「[外部類]$[內部類].smali 」,例如下面的類。
class Outer {
   class Inner{}
}

baksmali 反編譯上述代碼後會在同一目錄生成兩個檔案:Outer.smali 與Outer$Inner.smali。
  1. public class MainActivity extends Activity {      
  2.     private Button btnAnno;  
  3.     private Button btnCheckSN;  
  4.     private EditText edtSN;   
  5.     @Override  
  6.     public void onCreate(Bundle savedInstanceState) {  
  7.         super.onCreate(savedInstanceState);  
  8.         setContentView(R.layout.activity_main);  
  9.         btnAnno = (Button) findViewById(R.id.btn_annotation);  
  10.         btnCheckSN = (Button) findViewById(R.id.btn_checksn);  
  11.         edtSN = (EditText) findViewById(R.id.edt_sn);  
  12.         btnAnno.setOnClickListener(new OnClickListener() {  
  13.            @Override  
  14.             public void onClick(View v) {  
  15.                 getAnnotations();                  
  16.             }  
  17.         });  
  18.          
  19.         btnCheckSN.setOnClickListener(new OnClickListener() {  
  20.             @Override  
  21.             public void onClick(View v) {  
  22.                 SNChecker checker = new SNChecker(edtSN.getText().toString());  
  23.                 String str = checker.isRegistered() ? "註冊碼正確" : "註冊碼錯誤";  
  24.                 Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show();  
  25.             }  
  26.         });  
  27.     }  
  28.       
  29.     private void getAnnotations() {  
  30.         try {  
  31.             Class<?> anno = Class.forName("com.droider.anno.MyAnno");  
  32.             if (anno.isAnnotationPresent(MyAnnoClass.class)) {  
  33.                 MyAnnoClass myAnno = anno.getAnnotation(MyAnnoClass.class);  
  34.                 Toast.makeText(this, myAnno.value(), Toast.LENGTH_SHORT).show();  
  35.             }  
  36.             Method method = anno.getMethod("outputInfo", (Class[])null);  
  37.             if (method.isAnnotationPresent(MyAnnoMethod.class)) {  
  38.                 MyAnnoMethod myMethod = method.getAnnotation(MyAnnoMethod.class);  
  39.                 String str = myMethod.name() + " is " + myMethod.age() + " years old.";  
  40.                 Toast.makeText(this, str, Toast.LENGTH_SHORT).show();  
  41.             }  
  42.             Field field = anno.getField("sayWhat");  
  43.             if (field.isAnnotationPresent(MyAnnoField.class)) {  
  44.                 MyAnnoField myField = field.getAnnotation(MyAnnoField.class);  
  45.                 Toast.makeText(this, myField.info(), Toast.LENGTH_SHORT).show();  
  46.             }  
  47.         } catch (Exception e) {  
  48.             e.printStackTrace();  
  49.         }  
  50.     }  
  51.   
  52.     @Override  
  53.     public boolean onCreateOptionsMenu(Menu menu) {  
  54.         getMenuInflater().inflate(R.menu.activity_main, menu);  
  55.         return true;  
  56.     }  
  57.       
  58.     public class SNChecker {  
  59.         private String sn;  
  60.         public SNChecker(String sn) {  
  61.             this.sn = sn;  
  62.         }  
  63.          
  64.         public boolean isRegistered() {  
  65.             boolean result = false;  
  66.             char ch = "\0";  
  67.             int sum = 0;  
  68.             if (sn == null || (sn.length() < 8)) return result;  
  69.             int len = sn.length();  
  70.             if (len == 8) {  
  71.                 ch = sn.charAt(0);  
  72.                 switch (ch) {  
  73.                     case "a":  
  74.                     case "f":  
  75.                         result = true;  
  76.                         break;  
  77.                     default:  
  78.                         result = false;  
  79.                         break;  
  80.                 }  
  81.                 if (result) {  
  82.                     ch = sn.charAt(3);  
  83.                     switch (ch) {  
  84.                         case "1":  
  85.                         case "2":  
  86.                         case "3":  
  87.                         case "4":  
  88.                         case "5":  
  89.                             result = true;  
  90.                             break;  
  91.                         default:  
  92.                             result = false;  
  93.                             break;  
  94.                     }  
  95.                 }  
  96.             } else if (len == 16) {  
  97.                 for (int i = 0; i < len; i++) {  
  98.                     char chPlus = sn.charAt(i);  
  99.                     sum += (int) chPlus;  
  100.                 }  
  101.                 result = ((sum % 6) == 0) ? true : false;  
  102.             }  
  103.             return result;  
  104.         }  
  105.     }  
  106. }
複製代碼


MainActivity$ SNChecker.smali 檔案,這個SNChecker 就是MainActivity的一個內部類。開啟這個檔案,代碼結構如下。

  1. .class public Lcom/droider/crackme0502/MainActivity$SNChecker;  
  2. .super Ljava/lang/Object;  
  3. .source "MainActivity.java"  
  4.   
  5.   
  6. # annotations  
  7. .annotation system Ldalvik/annotation/EnclosingClass;  
  8.     value = Lcom/droider/crackme0502/MainActivity;  
  9. .end annotation  
  10.   
  11. .annotation system Ldalvik/annotation/InnerClass;  
  12.     accessFlags = 0x1  
  13.     name = "SNChecker"  
  14. .end annotation  
  15.   
  16.   
  17. # instance fields  
  18. .field private sn:Ljava/lang/String;  
  19.   
  20. .field final synthetic this$0:Lcom/droider/crackme0502/MainActivity;  
  21.   
  22.   
  23. # direct methods  
  24. .method public constructor <init>(Lcom/droider/crackme0502/MainActivity;Ljava/lang/String;)V  
  25.     .locals 0  
  26.     .parameter  
  27.     .parameter "sn"  
  28.   
  29.     .prologue  
  30.     .line 83  
  31.     iput-object p1, p0, Lcom/droider/crackme0502/MainActivity$SNChecker;->this$0:Lcom/droider/crackme0502/MainActivity;  
  32.   
  33.     invoke-direct {p0}, Ljava/lang/Object;-><init>()V  
  34.   
  35.     .line 84  
  36.     iput-object p2, p0, Lcom/droider/crackme0502/MainActivity$SNChecker;->sn:Ljava/lang/String;  
  37.   
  38.     .line 85  
  39.     return-void  
  40. .end method  
  41.   
  42.   
  43. # virtual methods  
  44. .method public isRegistered()Z  
  45.     .locals 10  
  46.   
  47.     .prologue  
  48.     const/16 v9, 0X8  
  49.   
  50.     const/4 v7, 0x0  
  51.   
  52.     .line 88  
  53.     const/4 v4, 0x0  
  54.   
  55.     .line 89  
  56.     .local v4, result:Z  
  57.     const/4 v0, 0x0  
  58.   
  59.     .line 90  
  60.     .local v0, ch:C  
  61.     const/4 v6, 0x0  
  62.   
  63.     .line 91  
  64.     .local v6, sum:I  
  65.     iget-object v8, p0, Lcom/droider/crackme0502/MainActivity$SNChecker;->sn:Ljava/lang/String;  
  66.   
  67.     if-eqz v8, :cond_0  
  68.   
  69.     iget-object v8, p0, Lcom/droider/crackme0502/MainActivity$SNChecker;->sn:Ljava/lang/String;  
  70.   
  71.     invoke-virtual {v8}, Ljava/lang/String;->length()I  
  72.   
  73.     move-result v8  
  74.   
  75.     if-ge v8, v9, :cond_1  
  76.   
  77.     :cond_0  
  78.     move v5, v4  
  79.   
  80.     .line 126  
  81.     .end local v4           #result:Z  
  82.     .local v5, result:I  
  83.     :goto_0  
  84.     return v5  
  85.   
  86.     .line 92  
  87.     .end local v5           #result:I  
  88.     .restart local v4       #result:Z  
  89.     :cond_1  
  90.     iget-object v8, p0, Lcom/droider/crackme0502/MainActivity$SNChecker;->sn:Ljava/lang/String;  
  91.   
  92.     invoke-virtual {v8}, Ljava/lang/String;->length()I  
  93.   
  94.     move-result v3  
  95.   
  96.     .line 93  
  97.     .local v3, len:I  
  98.     if-ne v3, v9, :cond_3  
  99.   
  100.     .line 94  
  101.     iget-object v8, p0, Lcom/droider/crackme0502/MainActivity$SNChecker;->sn:Ljava/lang/String;  
  102.   
  103.     invoke-virtual {v8, v7}, Ljava/lang/String;->charAt(I)C  
  104.   
  105.     move-result v0  
  106.   
  107.     .line 95  
  108.     sparse-switch v0, :sswitch_data_0  
  109.   
  110.     .line 101  
  111.     const/4 v4, 0x0  
  112.   
  113.     .line 104  
  114.     :goto_1  
  115.     if-eqz v4, :cond_2  
  116.   
  117.     .line 105  
  118.     iget-object v7, p0, Lcom/droider/crackme0502/MainActivity$SNChecker;->sn:Ljava/lang/String;  
  119.   
  120.     const/4 v8, 0x3  
  121.   
  122.     invoke-virtual {v7, v8}, Ljava/lang/String;->charAt(I)C  
  123.   
  124.     move-result v0  
  125.   
  126.     .line 106  
  127.     packed-switch v0, :pswitch_data_0  
  128.   
  129.     .line 115  
  130.     const/4 v4, 0x0  
  131.   
  132.     :cond_2  
  133.     :goto_2  
  134.     move v5, v4  
  135.   
  136.     .line 126  
  137.     .restart local v5       #result:I  
  138.     goto :goto_0  
  139.   
  140.     .line 98  
  141.     .end local v5           #result:I  
  142.     :sswitch_0  
  143.     const/4 v4, 0x1  
  144.   
  145.     .line 99  
  146.     goto :goto_1  
  147.   
  148.     .line 112  
  149.     :pswitch_0  
  150.     const/4 v4, 0x1  
  151.   
  152.     .line 113  
  153.     goto :goto_2  
  154.   
  155.     .line 119  
  156.     :cond_3  
  157.     const/16 v8, 0x10  
  158.   
  159.     if-ne v3, v8, :cond_2  
  160.   
  161.     .line 120  
  162.     const/4 v2, 0x0  
  163.   
  164.     .local v2, i:I  
  165.     :goto_3  
  166.     if-lt v2, v3, :cond_4  
  167.   
  168.     .line 124  
  169.     rem-int/lit8 v8, v6, 0x6  
  170.   
  171.     if-nez v8, :cond_5  
  172.   
  173.     const/4 v4, 0x1  
  174.   
  175.     :goto_4  
  176.     goto :goto_2  
  177.   
  178.     .line 121  
  179.     :cond_4  
  180.     iget-object v8, p0, Lcom/droider/crackme0502/MainActivity$SNChecker;->sn:Ljava/lang/String;  
  181.   
  182.     invoke-virtual {v8, v2}, Ljava/lang/String;->charAt(I)C  
  183.   
  184.     move-result v1  
  185.   
  186.     .line 122  
  187.     .local v1, chPlus:C  
  188.     add-int/2addr v6, v1  
  189.   
  190.     .line 120  
  191.     add-int/lit8 v2, v2, 0x1  
  192.   
  193.     goto :goto_3  
  194.   
  195.     .end local v1           #chPlus:C  
  196.     :cond_5  
  197.     move v4, v7  
  198.   
  199.     .line 124  
  200.     goto :goto_4  
  201.   
  202.     .line 95  
  203.     :sswitch_data_0  
  204.     .sparse-switch  
  205.         0x61 -> :sswitch_0  
  206.         0x66 -> :sswitch_0  
  207.     .end sparse-switch  
  208.   
  209.     .line 106  
  210.     :pswitch_data_0  
  211.     .packed-switch 0x31  
  212.         :pswitch_0  
  213.         :pswitch_0  
  214.         :pswitch_0  
  215.         :pswitch_0  
  216.         :pswitch_0  
  217.     .end packed-switch  
  218. .end method
複製代碼

發現它有兩個註解定義塊「Ldalvik/annotation/EnclosingClass;」與「Ldalvik/annotation/ InnerClass; 」、兩個實例字段sn 與this$0 、一個直接方法 init()、一個虛方法isRegistered() 。註解定義塊我們稍後進行講解。先看它的實例字段,sn 是字符串類型,this$0 是MainActivity類型,synthetic 關鍵字表明它是「合成」的,那 this$0 到底是個什麼東西呢?

其實this$0 是內部類自動保留的一個指向所在外部類的引用。左邊的 this 表示為父類的引用,右邊的數值0 表示引用的層數。我們看下面的類。

  1. public class Outer {        <span style="white-space:pre">    </span>    //this$0   
  2.      public class FirstInner {         <span style="white-space:pre"> </span>//this$1   
  3.              public class SecondInner {      //this$2   
  4.              public class ThirdInner {  
  5.             }   
  6.          }   
  7.     }  
  8. }  
複製代碼
每往裡一層右邊的數值就加一,如 ThirdInner類存取 FirstInner 類的引用為this$1 。在生成的反彙編代碼中,this$X 型字段都被指定了synthetic 屬性,表明它們是被編譯器合成的、虛構的,代碼的作者並沒有聲明該字段。

我們再看看MainActivity$SNChecker的構造函數,看它是如何初始化的。代碼如下。

  1. # direct methods  
  2. .method public constructor <init>(Lcom/droider/crackme0502/MainActivity;Ljava/lang/String;)V  
  3.     .locals 0  
  4.     .parameter       #第一個參數MainActivity引用  
  5.     .parameter "sn"  #第二個參數字符串sn  
  6.   
  7.     .prologue  
  8.     .line 83  
  9.     #將MainActivity引用賦值給this$0  
  10.     iput-object p1, p0, Lcom/droider/crackme0502/MainActivity$SNChecker;->this$0:Lcom/droider/crackme0502/MainActivity;  
  11.   
  12.     #調用預設的構造函數  
  13.     invoke-direct {p0}, Ljava/lang/Object;-><init>()V  
  14.   
  15.     .line 84  
  16.     #將sn字符串的值賦給sn字段  
  17.     iput-object p2, p0, Lcom/droider/crackme0502/MainActivity$SNChecker;->sn:Ljava/lang/String;  
  18.   
  19.     .line 85  
  20.     return-void  
  21. .end method
複製代碼

對於一個非靜態的方法而言,會隱含的使用p0寄存器當作類的this 引用。因此,這裡的確是使用了3 個寄存器:p0表示MainActivity$SNChecker自身的引用,p1表示MainActivity的引用,p2表示sn 字符串。另外,從 MainActivity$SNChecker的構造函數可以看出,內部類的初始化共有以下 3 個步驟:首先是保存外部類的引用到本類的一個 synthetic字段中,以便內部類的其它方法使用,然後是調用內部類的父類的構造函數來初始化父類,最後是對內部類自身進行初始化。
一個方法中指定的寄存器個
在一個方法(method)中有兩中方式指定有多少個可用的寄存器。指令.registers指令指定了在這個方法中有多少個可用的寄存器,指令.locals指明了在這個方法中非參(non-parameter)寄存器的數量。然而寄存器的總數也包括保存方法參數的寄存器。

參數是如何傳遞的?
當一個方法被調用時,該方法的參數被保存在最後N個寄存器中。如果一個方法有2個參數和5個寄存器(V0-V4),參數將被保存在最後的2個寄存器內V3和V4.

非靜態方法的第一個參數,總是被方法調用的對象。
例如,你寫了一個非靜態方法LMyObject;->callMe(II)V。這個方法有2個int參數,但在這兩個整型參數前面還有一個隱藏的參數LMyObject;所以這個方法總共有3個參數。

比如說,在方法中指定有5個寄存器(V0-V4),只用.register指令指定5個,或者使用.locals指令指定2個(2個local寄存器+3個參數寄存器)。該方法被調用的時候,調用方法的對象(即this引用)會保存在V2中,第一個參數在V3中,第二個參數在v4中。

除了不包含this隱藏參數,對於靜態方法都是相同的。

寄存器名稱
有兩種寄存器的命名方式,對於參數寄存器有普通的V命名方式和P命名方式。在方法(method)中第一個參數寄存器,是使用P方式命名的第一個寄存器,讓我們回到前面的例子中,有三個參數和5個寄存器,下面的這個表顯示了對每個寄存器的普通V命名方式,後面是P方式命名的參數寄存器。
「用Android 就來APK.TW」,快來加入粉絲吧!
Android 台灣中文網(APK.TW)

評分

參與人數 3碎鑽 +2 幫助 +3 收起 理由
liwil + 1 + 1 非常讃
球-球 + 1 好內容,老衲來為這篇文章開開光.
lulala123 + 1 + 1 非常讃

查看全部評分

收藏收藏3 分享分享 分享專題
用Android 就來Android 台灣中文網(https://apk.tw)
回覆

使用道具 舉報

沙發
lulala123 | 收聽TA | 只看該作者
發表於 2016-3-23 09:50
我也好想改 smali, 但是光環境就讓我快放棄了

我試著用 Line 5.1.1 APK 反編(我最想看的)
https://apkpure.com/line-free-calls-messages/jp.naver.line.android
去做,卻得到一大堆看不懂的錯誤,不知道妳是用什麼環境(版本)作逆向,有的 APK 又

可以反編成功,如
https://apkpure.com/splayer/com.sally.splayer
真是好困擾哦!!!謝謝

jdk1.7.0_80 32bit
Android SDK 1.16
改之理少月版3.3.2 / 3.3.1 反編譯/編譯 Line 5.11 的錯誤訊息

反編譯
> Decompiling Apk...  - OK!
> Dex2jaring...  - Failed:FileStream will not open Win32 devices such

as disk partitions and tape drives. Avoid use of "\." in the path.
> .smali Output:D:ApkIDE3.3.2Workjp.naver.line.android
> .class Output:D:ApkIDE3.3.2Worksrcjp.naver.line.android

編譯

> Compiling Apk...  -
  - Failed:
Exception in thread "main" com.rover12421.shaka.b.l: W: D:

ApkIDE3.3.2Workjp.naver.line.android
esvalues-v23styles.xml:5:

error: Error retrieving parent for item: No resource found that matches

the given name "@android:style/WindowTitle".
W:
W: D:ApkIDE3.3.2Workjp.naver.line.android
esvalues-

v23styles.xml:6: error: Error retrieving parent for item: No resource

found that matches the given name

"@android:style/WindowTitleBackground".
W:

        at b.a.e.a.a(Unknown Source)
        at b.a.e.a.a(Unknown Source)
        at b.a.a.a(Unknown Source)
        at b.a.a.a(Unknown Source)
        at b.a.a.e(Unknown Source)
        at b.a.a.a(Unknown Source)
        at b.b.a.b(Unknown Source)
        at b.b.a.a(Unknown Source)
        at com.rover12421.shaka.cli.Main.main(Unknown Source)
Caused by: b.a.D: b.c.a: could not exec (exit code = 1): [C:Users

Hawk_SunShakaApktoolwindows-x86inaapt.exe, p, --forced-package-

id, 127, --min-sdk-version, 15, --target-sdk-version, 19, --version-

code, 15051100, --version-name, 5.11.0, -F, C:eaTEMP

APKTOOL4651760530029879683.tmp, -0, arsc, -I, C:UsersHawk_Sun

apktoolframework1.apk, -S, D:ApkIDE3.3.2Work

jp.naver.line.android
es, -M, D:ApkIDE3.3.2Work

jp.naver.line.androidAndroidManifest.xml]
        at b.a.e.a.a(Unknown Source)
        ... 9 more
Caused by: b.c.a: could not exec (exit code = 1): [C:UsersHawk_Sun

ShakaApktoolwindows-x86inaapt.exe, p, --forced-package-id, 127,

--min-sdk-version, 15, --target-sdk-version, 19, --version-code,

15051100, --version-name, 5.11.0, -F, C:eaTEMP

APKTOOL4651760530029879683.tmp, -0, arsc, -I, C:UsersHawk_Sun

apktoolframework1.apk, -S, D:ApkIDE3.3.2Work

jp.naver.line.android
es, -M, D:ApkIDE3.3.2Work

jp.naver.line.androidAndroidManifest.xml]
        at b.e.i.a(Unknown Source)
        ... 10 more

  - Failed!Please check your code and retry.
用Android 就來Android 台灣中文網(https://apk.tw)
回覆 支持 反對

使用道具 舉報

板凳
liwil | 收聽TA | 只看該作者
發表於 2016-8-25 15:24
用Android 就來Android 台灣中文網(https://apk.tw)
回覆 支持 反對

使用道具 舉報

您需要登錄後才可以回帖 登錄 | 註冊

本版積分規則