欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android彻底去Log,反编译都看不到实现方法

程序员文章站 2022-09-02 23:19:45
android彻底去log,反编译都看不到实现方法。 当然是由于习惯太好,打了一堆中文log,其实只是想给测试看。然而如果包被反编译,看log基本都能理解流程了,有点尴尬。所以此文主要探究progu...

android彻底去log,反编译都看不到实现方法。
当然是由于习惯太好,打了一堆中文log,其实只是想给测试看。然而如果包被反编译,看log基本都能理解流程了,有点尴尬。所以此文主要探究proguard配置,以去除log。


以下过程示例,来自于这段代码。

public class mainactivity extends appcompatactivity {
 private static final string tag = "mainactivity";

 private string a = "a";
 private string b = "b";

 @override
 protected void oncreate(bundle savedinstancestate) {
  super.oncreate(savedinstancestate);
  setcontentview(r.layout.activity_main);

  log.d(tag, "this is" + a + b);
 }
}

啥都不配置的情况下,反编译的smali代码如下:

# virtual methods
.method public oncreate(landroid/os/bundle;)v
 .locals 2

 invoke-super {p0, p1}, landroid/support/v7/app/c;->oncreate(landroid/os/bundle;)v

 const p1, 0x7f09001b

 invoke-virtual {p0, p1}, lcom/rentee/logremove/mainactivity;->setcontentview(i)v

 const-string p1, "mainactivity"

 new-instance v0, ljava/lang/stringbuilder;

 const-string v1, "this is"

 invoke-direct {v0, v1}, ljava/lang/stringbuilder;->(ljava/lang/string;)v

 iget-object v1, p0, lcom/rentee/logremove/mainactivity;->m:ljava/lang/string;

 invoke-virtual {v0, v1}, ljava/lang/stringbuilder;->append(ljava/lang/string;)ljava/lang/stringbuilder;

 iget-object v1, p0, lcom/rentee/logremove/mainactivity;->n:ljava/lang/string;

 invoke-virtual {v0, v1}, ljava/lang/stringbuilder;->append(ljava/lang/string;)ljava/lang/stringbuilder;

 invoke-virtual {v0}, ljava/lang/stringbuilder;->tostring()ljava/lang/string;

 move-result-object v0

 invoke-static {p1, v0}, landroid/util/log;->d(ljava/lang/string;ljava/lang/string;)i

 return-void
.end method

很明显,整条字符串拼接过程是由stringbuilder完成的。


1.在build.gradle配置proguard-android-optimize.txt,因为默认的proguard-android.txt优化开关是关了的,而proguard的assumenosideeffects、assumenoexternalsideeffects配置是需要开启优化开关的。

 buildtypes {
  release {
minifyenabled true
proguardfiles getdefaultproguardfile('proguard-android-optimize.txt'), 'proguard-rules.pro'
  }
 }

在proguard-rules.pro文件中配置assumenosideeffects。这是网上的通用大解。

-assumenosideeffects class android.util.log {
 public static boolean isloggable(java.lang.string, int);
 public static int v(...);
 public static int i(...);
 public static int w(...);
 public static int d(...);
 public static int e(...);
}

不过也的确存在一个问题,就是去除不干净,反编译后,smail如下:

# virtual methods
.method public oncreate(landroid/os/bundle;)v
 .locals 1

 invoke-super {p0, p1}, landroid/support/v7/app/c;->oncreate(landroid/os/bundle;)v

 const p1, 0x7f09001b

 invoke-virtual {p0, p1}, lcom/rentee/logremove/mainactivity;->setcontentview(i)v

 new-instance p1, ljava/lang/stringbuilder;

 const-string v0, "this is"

 invoke-direct {p1, v0}, ljava/lang/stringbuilder;->(ljava/lang/string;)v

 iget-object v0, p0, lcom/rentee/logremove/mainactivity;->m:ljava/lang/string;

 invoke-virtual {p1, v0}, ljava/lang/stringbuilder;->append(ljava/lang/string;)ljava/lang/stringbuilder;

 iget-object v0, p0, lcom/rentee/logremove/mainactivity;->n:ljava/lang/string;

 invoke-virtual {p1, v0}, ljava/lang/stringbuilder;->append(ljava/lang/string;)ljava/lang/stringbuilder;

 return-void
.end method

log的相关代码没了,但是还是有stringbuilder的拼接过程在,这个从根本上解决不了问题。

2.进化版,proguard 6.0以上版本新增了assumenoexternalsideeffectsassumenoexternalreturnvalues,这两个属性6.0才引入,android自带proguard-gradle插件并没有这么新,所以要在工程项目根目录配置如下strategy,强制将progurad指定到6.0以上版本

buildscript {
 configurations.all {
  resolutionstrategy {
force "net.sf.proguard:proguard-gradle:6.0.3"
  }
 }
}

然后在progaurd-rules.txt文件中增加如下配置:

-assumenoexternalsideeffects class java.lang.stringbuilder {
 public java.lang.stringbuilder();
 public java.lang.stringbuilder(int);
 public java.lang.stringbuilder(java.lang.string);
 public java.lang.stringbuilder append(java.lang.object);
 public java.lang.stringbuilder append(java.lang.string);
 public java.lang.stringbuilder append(java.lang.stringbuffer);
 public java.lang.stringbuilder append(char[]);
 public java.lang.stringbuilder append(char[], int, int);
 public java.lang.stringbuilder append(boolean);
 public java.lang.stringbuilder append(char);
 public java.lang.stringbuilder append(int);
 public java.lang.stringbuilder append(long);
 public java.lang.stringbuilder append(float);
 public java.lang.stringbuilder append(double);
 public java.lang.string tostring();
}

-assumenoexternalreturnvalues public final class java.lang.stringbuilder {
 public java.lang.stringbuilder append(java.lang.object);
 public java.lang.stringbuilder append(java.lang.string);
 public java.lang.stringbuilder append(java.lang.stringbuffer);
 public java.lang.stringbuilder append(char[]);
 public java.lang.stringbuilder append(char[], int, int);
 public java.lang.stringbuilder append(boolean);
 public java.lang.stringbuilder append(char);
 public java.lang.stringbuilder append(int);
 public java.lang.stringbuilder append(long);
 public java.lang.stringbuilder append(float);
 public java.lang.stringbuilder append(double);
}

这段配置的作用是,去除返回值无用的stringbuilder的相关操作,由于在第2点配置后,log相关代码被去除,所以log中的字符串拼接也是无用的,会被去除。配置后smali代码是:

# virtual methods
.method public oncreate(landroid/os/bundle;)v
 .locals 0

 invoke-super {p0, p1}, landroid/support/v7/app/c;->oncreate(landroid/os/bundle;)v

 const p1, 0x7f09001b

 invoke-virtual {p0, p1}, lcom/rentee/logremove/mainactivity;->setcontentview(i)v

 return-void
.end method