├── .DS_Store
├── .classpath
├── .gitignore
├── .project
├── LICENSE
├── README.md
├── baffle.jar
├── libs
├── ant.jar
├── commons-cli-1.2.jar
├── commons-io-2.4.jar
├── commons-lang3-3.1.jar
└── luciad-webp-imageio.jar
├── libwebp-imageio.dylib
├── res
├── libwebp-imageio.dylib
├── mapping.map
├── out.rep
└── resguard.cfg
└── src
└── com
└── guye
└── baffle
├── ant
└── BaffleTask.java
├── config
├── BaffleConfig.java
├── ConfigReader.java
└── MappingWriter.java
├── decoder
├── ArscData.java
├── ArscFileGenerator.java
├── MakeCsc.java
└── StringBlock.java
├── exception
├── BaffleException.java
├── BaffleRuntimeException.java
└── UndefinedResObject.java
├── obfuscate
├── ApkBuilder.java
├── Main.java
├── NameFactory.java
├── ObfuscateHelper.java
└── Obfuscater.java
├── util
├── AntLogHandle.java
├── ApkFileUtils.java
├── ConsoleHandler.java
├── DataInputDelegate.java
├── Duo.java
├── ExtDataInput.java
├── LEDataInputStream.java
├── LEDataOutputStream.java
├── OS.java
└── ZipInfo.java
└── webp
└── WebpIO.java
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joker535/Baffle/0fcf542fd67b7e16ddccdd87b1c8818fa27853cd/.DS_Store
--------------------------------------------------------------------------------
/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Built application files
2 | *.apk
3 | *.ap_
4 |
5 | # Files for the Dalvik VM
6 | *.dex
7 |
8 | # Java class files
9 | *.class
10 |
11 | # Generated files
12 | bin/
13 | gen/
14 |
15 | # Gradle files
16 | .gradle/
17 | build/
18 | /*/build/
19 |
20 | # Local configuration file (sdk path, etc)
21 | local.properties
22 |
23 | # Proguard folder generated by Eclipse
24 | proguard/
25 |
26 | # Log Files
27 | *.log
28 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | baffle-github
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.jdt.core.javanature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 joker535
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Android apk包res 资源混淆工具
2 |
3 | 功能描述:
4 | 对编译后的APK 进行资源名称混淆。混淆之后apk对比如下图:
5 | 
6 |
7 | 目前支持命令行操作:
8 | java -jar baffle.jar [-c/--config filepaths list ][-o/--output filepath] ApkFile TargetApkFile
9 |
10 | -c/--config 可选项,支持keep和mapping配置文件。
11 | -o/--output 可选项,支持混淆后mapping文件输出。
12 |
13 | config文件格式见res目录,描述如下:
14 |
15 | \#这个开头的行是注释。
16 | \#key keep 段,比较关键。需要用名字取得资源需要keep,支持正则表达式。 key指的是R文件里的变量名。不是文件名,不包含后缀
17 | ----keep_key
18 |
19 | notificationsound
20 | newicon
21 | \#下面这个是,java的正则表达式。
22 | ^mini.*
23 |
24 | ----keep_key
25 |
26 | \#key 段的mapping
27 | ----map_key
28 |
29 | activity_login,bx
30 | imexaple,a
31 | icon,b
32 | activity_myinformation,ae
33 | ----map_key
34 | \#大概就是这个样子,暂时不支持include之类的操作。和keep规则冲突以mapping为准
35 |
36 |
37 | 具体原理可以参见我的博客:[Android apk文件资源混淆原理及实现](http://blog.csdn.net/joker535/article/details/48315257)
38 |
--------------------------------------------------------------------------------
/baffle.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joker535/Baffle/0fcf542fd67b7e16ddccdd87b1c8818fa27853cd/baffle.jar
--------------------------------------------------------------------------------
/libs/ant.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joker535/Baffle/0fcf542fd67b7e16ddccdd87b1c8818fa27853cd/libs/ant.jar
--------------------------------------------------------------------------------
/libs/commons-cli-1.2.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joker535/Baffle/0fcf542fd67b7e16ddccdd87b1c8818fa27853cd/libs/commons-cli-1.2.jar
--------------------------------------------------------------------------------
/libs/commons-io-2.4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joker535/Baffle/0fcf542fd67b7e16ddccdd87b1c8818fa27853cd/libs/commons-io-2.4.jar
--------------------------------------------------------------------------------
/libs/commons-lang3-3.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joker535/Baffle/0fcf542fd67b7e16ddccdd87b1c8818fa27853cd/libs/commons-lang3-3.1.jar
--------------------------------------------------------------------------------
/libs/luciad-webp-imageio.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joker535/Baffle/0fcf542fd67b7e16ddccdd87b1c8818fa27853cd/libs/luciad-webp-imageio.jar
--------------------------------------------------------------------------------
/libwebp-imageio.dylib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joker535/Baffle/0fcf542fd67b7e16ddccdd87b1c8818fa27853cd/libwebp-imageio.dylib
--------------------------------------------------------------------------------
/res/libwebp-imageio.dylib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joker535/Baffle/0fcf542fd67b7e16ddccdd87b1c8818fa27853cd/res/libwebp-imageio.dylib
--------------------------------------------------------------------------------
/res/mapping.map:
--------------------------------------------------------------------------------
1 | #mapping 文件,同样这个开头的是注释:)
2 |
3 | #key 段的mapping
4 | ----map_key
5 |
6 | activity_login_rb_admin,b444444
7 | imexaple,a
8 | icon,b
9 | activity_myinformation_tv_sex,a799999
10 |
11 |
12 |
13 | ----map_key
14 |
15 | #大概就是这个样子,暂时不支持include之类的操作。和keep规则冲突以mapping为准
--------------------------------------------------------------------------------
/res/resguard.cfg:
--------------------------------------------------------------------------------
1 | #这个开头的行是注释。
2 | #这个必须用utf—8编码。
3 |
4 | #key keep 段,比较关键。需要用名字取得资源需要keep,支持正则表达式。 key指的是R文件里的变量名。不是文件名,不包含后缀
5 | ----keep_key
6 |
7 | #notificationsound
8 | #newblogtoast
9 | #radar_scan
10 | #radar_pop
11 | #^activity_di_di_web.*
12 | #^didi_.*
13 | #^market_.*
14 | #^uxin_.*
15 | #^redbeans_.*
16 | #headlines_button_reward_selector
17 | #empty_answer
18 | #empty_trouble
19 | #list_background
20 | #qa_question_bg_color
21 | #yw_1222
22 | #
23 | #
24 | #^mini.*
25 | #^alipay.*
26 | #^key_.*
27 | #^keyboard_.*
28 | #^flybird_.*
29 | #nopwd_list
30 | #nopwd_limit
31 | #nopwd_limit_default
32 | #title_back_layout
33 | #setting_activity_channel
34 | #channel_list
35 | #text
36 |
37 | .*
38 |
39 | ----keep_key
--------------------------------------------------------------------------------
/src/com/guye/baffle/ant/BaffleTask.java:
--------------------------------------------------------------------------------
1 | package com.guye.baffle.ant;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 | import java.util.logging.Level;
6 | import java.util.logging.Logger;
7 | import org.apache.tools.ant.BuildException;
8 | import org.apache.tools.ant.Task;
9 | import com.guye.baffle.exception.BaffleException;
10 | import com.guye.baffle.obfuscate.Obfuscater;
11 | import com.guye.baffle.util.AntLogHandle;
12 |
13 | public class BaffleTask extends Task {
14 |
15 | private boolean mVerbose;
16 | private boolean mConfig;
17 | private boolean mHelp;
18 | private boolean mOutput;
19 | private String mConfigFilpaths;
20 | private String mOutputFilepath;
21 | private String mApkFilepath;
22 | private String mTargetFilepath;
23 | public static final String helper = "[--config(true/false) filepaths list] [--output(true/false) filepath] ApkFile TargetApkFile";
24 |
25 | public void setVerbose(boolean verbose) {
26 | this.mVerbose = verbose;
27 | }
28 |
29 | public void setConfig(boolean config) {
30 | this.mConfig = config;
31 | }
32 |
33 | public void setHelp(boolean help) {
34 | this.mHelp = help;
35 | }
36 |
37 | public void setOutput(boolean output) {
38 | this.mOutput = output;
39 | }
40 |
41 | public void setConfigFilepaths(String configfilepaths) {
42 | this.mConfigFilpaths = configfilepaths;
43 | }
44 |
45 | public void setOutputFilepath(String outputfilepath) {
46 | this.mOutputFilepath = outputfilepath;
47 | }
48 |
49 | public void setApkFilepath(String apkfilepath) {
50 | this.mApkFilepath = apkfilepath;
51 | }
52 |
53 | public void setTargetFilepath(String targetFilepath) {
54 | this.mTargetFilepath = targetFilepath;
55 | }
56 |
57 | @Override
58 | public void execute() throws BuildException {
59 |
60 | if (mVerbose) {
61 | Logger.getLogger(Obfuscater.LOG_NAME).setLevel(Level.CONFIG);
62 | } else {
63 | Logger.getLogger(Obfuscater.LOG_NAME).setLevel(Level.OFF);
64 | }
65 |
66 | Logger.getLogger(Obfuscater.LOG_NAME)
67 | .addHandler(new AntLogHandle(this));
68 |
69 | if (mApkFilepath == null || mTargetFilepath == null
70 | || mApkFilepath.equals("") || mTargetFilepath.equals("")) {
71 | Logger.getLogger(Obfuscater.LOG_NAME).log(Level.CONFIG,
72 | "not specify apk file or taget apk file");
73 | return;
74 | }
75 |
76 | if (mApkFilepath.equals(mTargetFilepath)) {
77 | Logger.getLogger(Obfuscater.LOG_NAME)
78 | .log(Level.CONFIG,
79 | "apk file can not rewrite , please specify new target file");
80 | return;
81 | }
82 |
83 | File mApkFile = new File(mApkFilepath);
84 | if (!mApkFile.exists()) {
85 | Logger.getLogger(Obfuscater.LOG_NAME).log(Level.CONFIG,
86 | "apk file not exists");
87 | return;
88 | }
89 |
90 | if (mHelp) {
91 | Logger.getLogger(Obfuscater.LOG_NAME).log(Level.CONFIG, helper);
92 | return;
93 | }
94 |
95 | File[] mConfigFiles = null;
96 | if (mConfig) {
97 | String[] fs = mConfigFilpaths.split(",");
98 | int len = fs.length;
99 | mConfigFiles = new File[fs.length];
100 | for (int i = 0; i < len; i++) {
101 | mConfigFiles[i] = new File(fs[i]);
102 | if (!mConfigFiles[i].exists()) {
103 | Logger.getLogger(Obfuscater.LOG_NAME).log(Level.CONFIG,
104 | "config file " + fs[i] + " not exists");
105 | return;
106 | }
107 | }
108 | } else {
109 | mConfigFiles = null;
110 | }
111 |
112 | File mappingfile = null;
113 | if (mOutput) {
114 | mappingfile = new File(mOutputFilepath);
115 | if (mappingfile.getParentFile() != null) {
116 | mappingfile.getParentFile().mkdirs();
117 | }
118 | } else {
119 | mappingfile = null;
120 | }
121 |
122 | Obfuscater obfuscater = new Obfuscater(mConfigFiles, mappingfile,null,
123 | mApkFile, mTargetFilepath);
124 |
125 | try {
126 | obfuscater.obfuscate();
127 | } catch (IOException e) {
128 | getProject().fireBuildFinished(e);
129 | } catch (BaffleException e) {
130 | getProject().fireBuildFinished(e);
131 | }
132 |
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/src/com/guye/baffle/config/BaffleConfig.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Baffle Project
3 | * The MIT License (MIT) Copyright (Baffle) 2015 guye
4 | *
5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
6 | * and associated documentation files (the "Software"), to deal in the Software
7 | * without restriction, including without limitation the rights to use, copy, modify,
8 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in all copies
12 | * or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
15 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
16 | * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
17 | * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
18 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 |
20 | * @author guye
21 | *
22 | **/
23 | package com.guye.baffle.config;
24 |
25 | import java.util.ArrayList;
26 | import java.util.Collections;
27 | import java.util.HashMap;
28 | import java.util.List;
29 | import java.util.Map;
30 | import java.util.regex.Matcher;
31 | import java.util.regex.Pattern;
32 |
33 | public class BaffleConfig {
34 |
35 | private Map mKeyMapping = new HashMap();
36 |
37 | private List