安卓反编译笔记

反编译apk时整理了以下几点
一、jd-gui反编译 access$xxx类函数
使用jd-gui反编译后去掉注释 /* \d **/
此处略作修改:\/* \d **\/
去掉最后一行自动生成的注释 /* Location:[\S\s]+?(?=*/)*/$
转自:https://blog.csdn.net/fssf0079/article/details/7875901
二、access$ 反编译偶内部类调用外部类成员问题
很简单的一个测试类源码:

public class testOuter {
private int a;
private int b;
private void fun() {
    a += 1;
}

class testInner {
    int x = 0;
    testInner() {
        b = 1;
        a = 0;
        fun();
    }
}

编译生成的Class文件:

class testOuter$testInner {
    int x = 0;
    testOuter$testInner(testOuter paramtestOuter) {
        testOuter.access$002(paramtestOuter, 1);
        testOuter.access$102(paramtestOuter, 0);
        testOuter.access$200(paramtestOuter);
    }
}

可以看出,为了使内部类访问外部类的私有成员,编译器生成了形似 “外部类.access$XYZ”的函数。XYZ为数字。X是按照私有成员在内部类出现的顺序递增的。YZ为02的话,标明是基本变量成员;YZ为00的话标明是对象成员或者函数。

三、java关键字的错误显示
1、会把if ..esle 反编译成 if …while(true)结构.
反编译代码

if (paramBoolean){
        paramTextView.setTextColor(-16727809);
       while (true){
         return;
         paramTextView.setTextColor(-1315861);
       }
}

还原后

    if (paramBoolean)
        paramTextView.setTextColor(-16727809);
    else
        paramTextView.setTextColor(-1315861);

2、switch规则就是一个continue对应一个case.要注意是是要外层的continue才算数,在if里的continue不算
转自:
https://www.cnblogs.com/yaowen/p/5964618.html
反编译代码

   switch (this.mBand)
    {
     default:
     case 0:
     case 1:
     case 2:
    }
    while (true)
    {
      return;
      this.mBand.setText("FM1");
      continue;
      this.mBand.setText("FM2");
      continue;
      this.mBand.setText("AM");
    }

还原

switch (mBand)
    {
     case 0:
      mBand.setText("FM1");
      break;
     case 1:
       mBand.setText("FM2");
       break;
     case 2:
       mBand.setText("AM");
       break;
     default:
    }

以上两个问题在项目中的例子,Activity基类中有一个ShowToastTask线程类
反编译代码

   if (this.args != null){
       BaseActivity localBaseActivity = BaseActivity.this;
       int i = this.msg;
       Object[] arrayOfObject = new Object[1];
       arrayOfObject[0] = this.args;
       String str = localBaseActivity.getString(i, arrayOfObject);
       BaseActivity.access$102(BaseActivity.this, Toast.makeText(BaseActivity.this, str, 0));
   }
   while (true){
       BaseActivity.this.mToast.show();
       return;
       BaseActivity.access$102(BaseActivity.this, Toast.makeText(BaseActivity.this, this.msg, 0));
    }  

还原

  if (this.args != null) {
      BaseActivity localBaseActivity = BaseActivity.this;
      int i = this.msg;
      Object[] arrayOfObject = new Object[1];
      arrayOfObject[0] = this.args;
      String str = localBaseActivity.getString(i, arrayOfObject);
      mToast = Toast.makeText(BaseActivity.this, str, Toast.LENGTH_SHORT);
      mToast.show();
} else{
      mToast =  Toast.makeText(BaseActivity.this, this.msg, Toast.LENGTH_SHORT);
      mToast.show();
} 

四、静态常量的类型转换
反编译得到的代码

Iterator localIterator - context.getPackageManager().getAllPermissionGroups(128.iterator());

判断为使用迭代器获取所有的权限,将128转换为16进制是0x80,刚好对应PackageManager.GET_META_DATA这个常量

猜你喜欢

转载自blog.csdn.net/zhawenting/article/details/81455831