Files
android_sdk_tools/src/com/qy/utils/CsjTools.java
2020-06-03 17:50:55 +08:00

385 lines
15 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package com.qy.utils;
import com.qy.Interfaces.SmaliApkToolsPath;
import com.qy.ui.EditToDalog;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class CsjTools {
private static String csj_res = "D:\\IdeaProjects\\android_sdk_tools\\demo_2.8.0.2\\res\\values";
private static String apk_res = "D:\\IdeaProjects\\android_sdk_tools\\app-release\\res\\values";
private static String apk_Path = "D:\\IdeaProjects\\android_sdk_tools\\app-release";
private static String csj_Path = "D:\\IdeaProjects\\android_sdk_tools\\demo_2.8.0.2";
private List<String> r_list;
private String packageName = null;
public CsjTools() {
}
public CsjTools(String apkFile, String csjFile, String packageName, String version, SmaliApkToolsPath toolsPath) {
setUserPackageName(false);
this.packageName = packageName;
build(csjFile, apkFile, new SmaliApkToolsPath() {
@Override
public void smaliPath(String path) {
System.out.println(path);
if (path.startsWith("已出包")) {
out(path.replace("已出包", ""),
new File("csj").getAbsolutePath() + File.separator + "csc",
Integer.parseInt(version));
toolsPath.smaliPath(new File("csj").getAbsolutePath() + File.separator + "csc");
}
}
});
}
public String loadXml(String path) {
File file = new File(path);
String xml = null;
try {
BufferedReader reader = new BufferedReader(new FileReader(file));
String tmp;
while ((tmp = reader.readLine()) != null) {
if (xml == null) {
xml = tmp + "\n";
} else {
xml += tmp + "\n";
}
}
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
return xml;
}
public long getId(String publicXml) {
long maxId = 0;
for (String xml : publicXml.split("\n")) {
String id = getXMLValue("id", xml.trim());
if (id != null) {
id = id.substring(2, 6);
if (maxId < Long.parseLong(id, 16)) {
maxId = Long.parseLong(id, 16);
}
}
}
return maxId;
}
public String getXMLValue(String name, String message) {
Pattern p = Pattern.compile(name + "=\"([^\"]+)\"");
Matcher m = p.matcher(message);
if (m.find()) {
String tmp = message.substring(m.start(), m.end()).split("=")[1];
return tmp.substring(1, tmp.length() - 1);
}
return null;
}
private boolean isAppPackageName = false;
public void setUserPackageName(boolean isAppPackageName) {
this.isAppPackageName = isAppPackageName;
}
private String getPackageName() {
try {
if (isAppPackageName) {
File apkManifest = new File(apk_Path + File.separator + "AndroidManifest.xml");
BufferedReader reader = new BufferedReader(new FileReader(apkManifest));
String tmp = reader.readLine();
reader.close();
return getXMLValue("package", tmp);
} else {
if (packageName == null) {
return Tools.loadConfig(new File("config.cfg")).getString("csjPackageName");
} else {
return packageName;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private void outManifest() {
try {
File apkManifest = new File(apk_Path + File.separator + "AndroidManifest.xml");
File demoManifest = new File(csj_Path + File.separator + "AndroidManifest.xml");
BufferedReader reader = new BufferedReader(new FileReader(apkManifest));
String tmp = reader.readLine();
reader.close();
String apkPackage = getXMLValue("package", tmp);
System.out.println(apkPackage);
_log.smaliPath("获取到APK包名" + apkPackage);
reader = new BufferedReader(new FileReader(demoManifest));
tmp = reader.readLine();
String manifest = tmp.replace(getXMLValue("package", tmp), apkPackage) + "\n";
while ((tmp = reader.readLine()) != null) {
manifest += tmp + "\n";
}
FileWriter writer = new FileWriter(demoManifest);
writer.write(manifest);
writer.flush();
writer.close();
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public void out(String srcFile, String encryptFile, int version) {
EncryptJar encryptJar = new EncryptJar();
encryptJar.encrypt(new File(srcFile), encryptFile, 13, version);
}
private void commandFile() {
JSONObject config = Tools.loadConfig(new File("config.cfg"));
if (config != null && config.getJSONObject("csjConfig") != null) {
JSONObject _config = config.getJSONObject("csjConfig");
JSONObject fileConfig = _config.getJSONObject("file");
JSONArray data = fileConfig.getJSONArray("data");
for (Object _item : data) {
JSONObject item = (JSONObject) _item;
String path = item.getString("name");
if (item.getString("command").equals("delete")) {
path = path.replace("${demoRoot}", csj_Path)
.replace("${apkRoot}", apk_Path)
.replace("/", File.separator);
File file = new File(path.replace("*", ""));
if (path.endsWith("*")) {
Tools.deleteFiles(file.getAbsolutePath());
} else {
file.delete();
}
}
}
_config = config.getJSONObject("csjConfig").getJSONObject("xml");
if (_config != null) {
data = _config.getJSONArray("data");
for (Object _item : data) {
JSONObject item = (JSONObject) _item;
if (item.getString("command").equals("remove")) {
String path = item.getString("name")
.replace("${demoRoot}", csj_Path)
.replace("${apkRoot}", apk_Path)
.replace("/", File.separator);
File file = new File(path);
commandXml(file, item);
}
}
}
}
}
private void commandXml(File file, JSONObject item) {
try {
String fileXml = loadXml(file.getAbsolutePath());
String newXml = "";
boolean remove = false;
for (String xml : fileXml.split("\n")) {
for (Object data : item.getJSONArray("data")) {
JSONObject _item = (JSONObject) data;
String value = getXMLValue(_item.getString("title"), xml.trim());
if (value != null && value.equals(_item.getString("value"))) {
remove = true;
}
}
if (remove) {
remove = false;
continue;
}
newXml += xml + "\n";
}
FileWriter writer = new FileWriter(file);
writer.write(newXml);
writer.flush();
writer.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private void start() {
_log.smaliPath("开始制作资源包");
commandFile();
String apkXML = loadXml(apk_res + File.separator + "public.xml");
String demoXML = loadXml(csj_res + File.separator + "public.xml");
long maxId = getId(apkXML);
int index = 0;
String message = "";
String oldType = "";
for (String xml : demoXML.split("\n")) {
String type = getXMLValue("type", xml.trim());
// String name = getXMLValue("name", xml.trim());
String oldId = getXMLValue("id", xml.trim());
if (type != null && !type.equals(oldType)) {
oldType = type;
maxId++;
index = 0;
}
if (type != null) {
String nextId = "0x" + Long.toHexString(maxId + 1) + String.format("%.3f", (index++) / 1000f).replace(".", "");
xml = xml.replace(oldId, nextId);
}
message += xml + "\n";
}
try {
FileWriter writer = new FileWriter(new File(csj_res + File.separator + "public.xml"));
writer.write(message);
writer.flush();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
outManifest();
File csjRes = new File("csj" + File.separator + "csc.apk");
if (!new File("csj").exists()) {
new File("csj").mkdirs();
}
SmaliUtils utils = new SmaliUtils();
_log.smaliPath("资源包制作完成开始打包为apk");
utils.bale(csj_Path, csjRes.getAbsolutePath(), new SmaliApkToolsPath() {
@Override
public void smaliPath(String path) {
_log.smaliPath("已出包" + csjRes.getAbsolutePath());
_log.smaliPath("耗时:" + (System.currentTimeMillis() - time) / 1000 + "");
System.gc();
}
});
}
private long time;
private boolean unPackageCSJ = false;
private SmaliApkToolsPath _log;
public void build(String csjPath, String apkPath, SmaliApkToolsPath log) {
time = System.currentTimeMillis();
_log = log;
unPackageCSJ = false;
File csjFile = new File(csjPath);
//由于改成动态SDK所以每个应用都要单独打包
/*if (new File(csjFile.getName().replace(".apk", "")).exists()) {
System.out.println(">?>>" + new File(csjFile.getName().replace(".apk", "")).getAbsolutePath());
unPackageCSJ = true;
csj_Path = new File(csjFile.getName().replace(".apk", "")).getAbsolutePath();
csj_res = csj_Path + File.separator + "res" + File.separator + "values";
}*/
SmaliUtils utils = new SmaliUtils();
Tools.deleteFiles(new File("").getAbsolutePath() + File.separator + new File(csjPath).getName().replace(".apk", File.separator));
Tools.deleteFiles(new File("").getAbsolutePath() + File.separator + new File(apkPath).getName().replace(".apk", File.separator));
new Thread(new Runnable() {
@Override
public void run() {
_log.smaliPath("开始反编译目标APK");
utils.unPack(apkPath, new SmaliApkToolsPath() {
@Override
public void smaliPath(String path) {
log.smaliPath("目标APK反编译完成:" + path);
apkUnPackage = true;
System.out.println(path);
apk_Path = path;
apk_res = apk_Path + File.separator + "res" + File.separator + "values";
runStart();
utils.clear();
}
});
if (unPackageCSJ) {
_log.smaliPath("穿山甲demo已存在不再反编译");
csjManifest = true;
runStart();
} else {
_log.smaliPath("开始反编译穿山甲Demo");
utils.unPack(csjPath, new SmaliApkToolsPath() {
@Override
public void smaliPath(String path) {
_log.smaliPath("穿山甲Demo反编译完成:" + path);
System.out.println(path);
csj_Path = path;
csj_res = csj_Path + File.separator + "res" + File.separator + "values";
_log.smaliPath("开始修改穿山甲");
utils.clear();
new Thread(new Runnable() {
@Override
public void run() {
new AutoRandomAdSDK().startNotUnPackage(path, getPackageName(), new SmaliApkToolsPath() {
@Override
public void smaliPath(String path) {
_log.smaliPath("穿山甲修改完成");
System.out.println("-------" + path);
csjManifest = true;
runStart();
}
});
}
}).start();
}
});
}
}
}).start();
}
boolean csjManifest = false;
boolean apkUnPackage = false;
private void runStart() {
if (apkUnPackage && csjManifest) {
start();
}
}
//还有最后一个问题穿山甲的Activity没改
public static void main(String[] args) {
CsjTools tools = new CsjTools();
tools.build("D:\\IdeaProjects\\android_sdk_tools\\demo_2.8.0.2.apk",
"D:\\IdeaProjects\\android_sdk_tools\\app-release.apk",
new SmaliApkToolsPath() {
@Override
public void smaliPath(String log) {
System.out.println(log);
if (log.startsWith("已出包")) {
System.out.println("打包完成");
new EditToDalog("成功", "打包完成,请输入版本号", "5600", new SmaliApkToolsPath() {
@Override
public void smaliPath(String path) {
System.out.println(">>" + path);
tools.out(log.replace("已出包", ""),
new File("csj").getAbsolutePath() + File.separator + "csc",
Integer.parseInt(path));
}
});
}
}
});
// tools.outManifest();
// tools.start();
}
}