Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android反编译、查看混淆、多渠道打包等 #6

Open
bingoogolapple opened this issue Sep 29, 2014 · 5 comments
Open

Android反编译、查看混淆、多渠道打包等 #6

bingoogolapple opened this issue Sep 29, 2014 · 5 comments
Labels

Comments

@bingoogolapple
Copy link
Owner

bingoogolapple commented Sep 29, 2014

直接用 jadx

Android反编译

下载apktool

下载地址已经迁移到 http://ibotpeaches.github.io/Apktool/
* 将apk文件和apktool.jar放在同一目录
* 在命令行跳转到a中所述目录,执行java -jar apktool.jar d xxx.apk
到此,已经获取到清单文件和资源文件,但是并没获取到xxx.dex文件

下载dex2jar

* 用压缩工具解压xxx.apk文件中的xxx.dex文件
* 将xxx.dex文件拷贝到dex2jar目录下
* 在命令行跳转到a中所述目录,执行dex2jar.bat xxx.dex(Windows)    ./dex2jar.sh xxx.dex(Ubuntu)
到此就得到了xxx.jar文件

下载jd-jui

运行jd-gui.exe就能查看java源码了

在线反编译工具

@bingoogolapple
Copy link
Owner Author

bingoogolapple commented Jul 14, 2016

proguard 语法

接下来的例子只列举 -keep 的情况,-keepxxxxxxxx 的情况参考下面这个的表格推导

  防止被移除或者被重命名 防止被重命名
类和指定的类成员都不会被混淆 -keep -keepnames
类名会被混淆,指定的类成员不会被混淆 -keepclassmembers -keepclassmembernames
如果拥有指定的所有成员,类和指定的类成员都不会被混淆
如果不拥有指定的某一个成员,类和类成员都会被混淆
-keepclasseswithmembers -keepclasseswithmembernames

keep 和 keepclasseswithmembers 区别在于:

  • keep 关键字看到 class * 就认为应该将所有类名进行保留,不关心 {} 中的参数
  • keepclasseswithmembers 的前提是 {} 中指定的成员必须存在,如果不存在则还是会混淆
  一颗 * 表示当前包 两颗 * 表示当前包及其子包
什么都不加时
类名不会被混淆
类里的内容会被混淆
-keep class cn.bga.proguardjar.one.*

包 cn.bga.proguardjar.one 下的类
* 类名不会被混淆
* 类里的内容会被混淆
包 cn.bga.proguardjar.one 的子包下的类
* 类名会被混淆
* 类里的内容会被混淆
-keep class cn.bgaf.proguardjar.one.**

包 cn.bga.proguardjar.one 下的类
* 类名不会被混淆
* 类里的内容会被混淆
包 cn.bga.proguardjar.one 的子包下的类
* 类名不会被混淆
* 类里的内容会被混淆
加 { *; } 时
类名不会被混淆
类里的内容也不会被混淆
-keep class cn.bga.proguardjar.one.* { *; }

包 cn.bga.proguardjar.one 下的类
* 类名不会被混淆
* 类里的内容不会被混淆
包 cn.bga.proguardjar.one 的子包下的类
* 类名会被混淆
* 类里的内容会被混淆
-keep class cn.bga.proguardjar.one.** { *; }

包 cn.bga.proguardjar.one 下的类
* 类名不会被混淆
* 类里的内容不会被混淆
包 cn.bga.proguardjar.one 的子包下的类
* 类名不会被混淆
* 类里的内容不会被混淆
  • 可以使用 Java 的基本规则来保护特定类不被混淆,比如 extends、implements 等。如下例子表示避免所有继承 cn.bga.proguardjar.one.One 的类名被混淆
-keep class * extends cn.bga.proguardjar.one.One
  • 保留一个类中的内部类不被混淆需要用 $ 符号,如下例子表示避免 cn.bga.proguardjar.Business 的内部类 MyInnerClass 被混淆
-keep class cn.bga.proguardjar.Business$MyInnerClass { *; }
  • 如果一个类中你不希望保持全部内容不被混淆,而只是希望保护类下的特定内容,就可以使用
-keep class * extends cn.bga.proguardjar.one.One {
    <init>();   #匹配构造方法
    <fields>;   #匹配所有属性
    <methods>;  #匹配所有方法
}
  • 可以在 class、 、 等的前面加上 private 、public 等来进一步指定不被混淆的内容
-keep public class * extends cn.bga.proguardjar.one.One {
    public <init>();
    public <fields>;
    public <methods>;
}
  • 可以给方法上加上参数「除基本类型外,必须是完整的全类名」
-keep class cn.bga.proguardjar.one.One {
    public void test2(int, java.lang.Integer, java.lang.String);
}
  • 方法名也可以用一颗星「*」来模糊匹配,还可以用「...」来匹配任意长度的任意参数类型
-keep class cn.bga.proguardjar.one.One {
    public void test1*(...);
}
  • 方法可以用三颗星「***」来模糊匹配任意传入或返回的参数类型
-keep class cn.bga.proguardjar.one.One {
    public *** test(***);
}

@bingoogolapple
Copy link
Owner Author

bingoogolapple commented Jul 15, 2016

通用配置

# 代码混淆压缩比,在0~7之间
-optimizationpasses 5
# 混合时不使用大小写混合,混合后的类名为小写
-dontusemixedcaseclassnames
# 指定不去忽略非公共库的类
-dontskipnonpubliclibraryclasses
# 不做预校验,preverify 是 proguard 的四个步骤之一,因为 Android 的 dex 并不像 Java 虚拟机需要 preverify,去掉这一步能够加快混淆速度
-dontpreverify
# 不分析和优化字节码,optimize 是 proguard 的四个步骤之一,因为 Android 的 dex 并不像 Java 虚拟机需要 optimize,去掉这一步能够加快混淆速度
-dontoptimize
# 混淆时记录日志
-verbose
# 混淆时所采用的算法。google 推荐算法
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
# 避免混淆 Annotation、内部类、泛型、匿名类
-keepattributes *Annotation*,InnerClasses,Signature,EnclosingMethod
# 重命名抛出异常时的文件名称
-renamesourcefileattribute SourceFile
# 抛出异常时保留代码行号
-keepattributes SourceFile,LineNumberTable
# 忽略警告
-ignorewarnings
# =========== 记录生成的日志数据 START ===========
# apk 包内所有 class 的内部结构
-dump class_files.txt
# 未混淆的类和成员
-printseeds seeds.txt
# 列出从 apk 中删除的代码
-printusage unused.txt
# 混淆前后的映射
-printmapping mapping.txt
# =========== 记录生成的日志数据 END ===========
-dontwarn **CompatHoneycomb,**CompatCreatorHoneycombMR2
# 处理support包
-dontnote android.support.**
-dontwarn android.support.**
# 保留四大组件,自定义的 Application 等这些类不被混淆
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Appliction
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.app.Fragment
-keep public class * extends android.support.v4.app.Fragment
# 保留 Keep 注解的类名和方法
-keep,allowobfuscation @interface android.support.annotation.Keep
-keep @android.support.annotation.Keep class *
-keepclassmembers class * {
    @android.support.annotation.Keep *;
}
# 保留 native 方法不被混淆
-keepclasseswithmembernames class * {
    native <methods>;
}
# 不混淆泛型
-keepattributes Signature
# 保留枚举类不被混淆
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}
# 保留 Serializable 序列化类不被混淆
-keepclassmembers class * implements java.io.Serializable {
    static final long serialVersionUID;
    private static final java.io.ObjectStreamField[] serialPersistentFields;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}
# 保留 Parcelable 序列化类不被混淆
-keep class * implements android.os.Parcelable {
    public static final android.os.Parcelable$Creator *;
}
# 不混淆资源类
-keepclassmembers class **.R$* {
    public static <fields>;
}
# WebView
-keepattributes JavascriptInterface
-keepclassmembers class * {
    @android.webkit.JavascriptInterface <methods>;
}
# View
-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers class * extends android.app.Activity {
    public void *(android.view.View);
}
-keep public class * extends android.view.View {
    public <init>(android.content.Context);
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(android.content.Context, android.util.AttributeSet, int);
    public void set*(...);
}

@bingoogolapple bingoogolapple changed the title Android反编译 Android反编译、查看混淆、多渠道打包等 Jul 15, 2016
@bingoogolapple
Copy link
Owner Author

bingoogolapple commented Dec 10, 2017

解码混淆过的堆栈跟踪信息(Decoding Obfuscated Stack Traces)

命令行

  • retrace.sh 脚本命令能把混淆后的堆栈调试信息转换为可以理解的文件
  • 它被放在 <sdk_root>/tools/proguard/bin 目录下
  • 运行 retrace 工具的命令语法是
retrace.bat|retrace.sh [-verbose] mapping.txt [<stacktrace_file>]
  • 如果你没有为 <stracktrace_file> 指定值,那么 retrace 工具从标准输入读取
    image

GUI 工具

  • <sdk_root>/tools/proguard/bin 下有个叫 proguardgui.sh 的工具

@bingoogolapple
Copy link
Owner Author

bingoogolapple commented Aug 26, 2019

public void crashNatively() {
        try {
            Class.forName("dalvik.system.VMDebug").getMethod("crash").invoke(null);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant