完善了穿山甲资源包生成的初始版本
This commit is contained in:
@@ -1,71 +1,90 @@
|
||||
package com.qy.utils;
|
||||
|
||||
import com.qy.Interfaces.SmaliApkToolsPath;
|
||||
import com.qy.ui.TextToDalog;
|
||||
import com.qy.ui.EditToDalog;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class CsjTools {
|
||||
private String csj_R_path="E:\\idea\\android_sdk_tools\\demo_2.8.0.1\\smali\\com\\bytedance\\sdk\\openadsdk";
|
||||
private String csj_demo_path="E:\\idea\\android_sdk_tools\\demo_2.8.0.1";
|
||||
private String apk_R_path="E:\\idea\\android_sdk_tools\\app-release-1\\smali\\com\\luckyboy\\mmxing";
|
||||
private List<String> r_list;
|
||||
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;
|
||||
|
||||
public CsjTools() {
|
||||
}
|
||||
public void setR() {
|
||||
r_list=new ArrayList<>();
|
||||
File apk_R=new File(csj_R_path+File.separator+"R.smali");
|
||||
if(!apk_R.exists()){
|
||||
new TextToDalog("找不到文件","穿山甲R文件不存在:"+apk_R);
|
||||
return;
|
||||
}
|
||||
|
||||
public String loadXml(String path) {
|
||||
File file = new File(path);
|
||||
String xml = null;
|
||||
try {
|
||||
BufferedReader reader=new BufferedReader(new FileReader(apk_R));
|
||||
BufferedReader reader = new BufferedReader(new FileReader(file));
|
||||
String tmp;
|
||||
while ((tmp=reader.readLine())!=null){
|
||||
if(tmp.contains("/R$")){
|
||||
r_list.add(tmp.split("/")[tmp.split("/").length-1].replace(";,","").replace(";",""));
|
||||
while ((tmp = reader.readLine()) != null) {
|
||||
if (xml == null) {
|
||||
xml = tmp + "\n";
|
||||
} else {
|
||||
xml += tmp + "\n";
|
||||
}
|
||||
}
|
||||
/*for (String fileName : r_list) {
|
||||
setRData(fileName);
|
||||
}*/
|
||||
reader.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return xml;
|
||||
}
|
||||
private void setRData(String fileName){
|
||||
File apkR=new File(apk_R_path+File.separator+fileName+".smali");
|
||||
|
||||
List<String> header=new ArrayList<>();
|
||||
List<String> end=new ArrayList<>();
|
||||
|
||||
boolean isHeader=true;
|
||||
long id=-1;
|
||||
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 void outManifest() {
|
||||
try {
|
||||
BufferedReader reader=new BufferedReader(new FileReader(apkR));
|
||||
String tmp;
|
||||
while ((tmp=reader.readLine())!=null){
|
||||
if(tmp.trim().equals("# direct methods")){
|
||||
isHeader=false;
|
||||
}
|
||||
if(isHeader){
|
||||
header.add(tmp);
|
||||
if(tmp.contains(":I = 0x")){
|
||||
id=Long.parseLong(tmp.split("0x")[1],16);
|
||||
}
|
||||
}else{
|
||||
end.add(tmp);
|
||||
}
|
||||
}
|
||||
header.addAll(getCSJR(fileName,id));
|
||||
header.addAll(end);
|
||||
FileWriter writer=new FileWriter(apkR);
|
||||
for (String str : header) {
|
||||
writer.write(str+"\n");
|
||||
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);
|
||||
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();
|
||||
|
||||
@@ -73,39 +92,224 @@ public class CsjTools {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
private List<String> getCSJR(String fileName,long id){
|
||||
File csjR=new File(csj_R_path+File.separator+fileName+".smali");
|
||||
List<String> csj=new ArrayList<>();
|
||||
try {
|
||||
BufferedReader reader=new BufferedReader(new FileReader(csjR));
|
||||
String tmp;
|
||||
long nextId=id;
|
||||
while ((tmp=reader.readLine())!=null){
|
||||
if(tmp.trim().startsWith(".field public")){
|
||||
csj.add(tmp.replace(".field public static",".field public static final")+" = 0x"+Long.toHexString(++nextId));
|
||||
|
||||
private 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
csj.add("\n");
|
||||
_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();
|
||||
}
|
||||
return csj;
|
||||
}
|
||||
private void copyFile(){
|
||||
setR();
|
||||
for (String s : r_list) {
|
||||
Tools.copyFile(apk_R_path+File.separator+s+".smali",csj_R_path+File.separator+s+".smali",true);
|
||||
|
||||
private void start(SmaliApkToolsPath toolsPath) {
|
||||
System.out.println("开始制作资源包");
|
||||
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();
|
||||
utils.bale(csj_Path, csjRes.getAbsolutePath(), new SmaliApkToolsPath() {
|
||||
@Override
|
||||
public void smaliPath(String path) {
|
||||
toolsPath.smaliPath("已出包" + csjRes.getAbsolutePath());
|
||||
System.out.println("耗时:"+(System.currentTimeMillis()-time)/1000+" 秒");
|
||||
}
|
||||
});
|
||||
}
|
||||
private long time;
|
||||
public void build(String csjPath, String apkPath, SmaliApkToolsPath log) {
|
||||
time=System.currentTimeMillis();
|
||||
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(log);
|
||||
}
|
||||
});
|
||||
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("开始修改穿山甲清单");
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
new AutoRandomAdSDK().startNotUnPackage(path, new SmaliApkToolsPath() {
|
||||
@Override
|
||||
public void smaliPath(String path) {
|
||||
System.out.println("-------" + path);
|
||||
csjManifest = true;
|
||||
runStart(log);
|
||||
}
|
||||
});
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
}).start();
|
||||
|
||||
}
|
||||
private void out(){
|
||||
EncryptJar encryptJar=new EncryptJar();
|
||||
encryptJar.encrypt(new File("E:\\idea\\android_sdk_tools\\csj.apk"),"E:\\idea\\android_sdk_tools\\csj_",13,5600);
|
||||
|
||||
boolean csjManifest = false;
|
||||
boolean apkUnPackage = false;
|
||||
|
||||
private void runStart(SmaliApkToolsPath log) {
|
||||
if (apkUnPackage && csjManifest) {
|
||||
start(log);
|
||||
}
|
||||
}
|
||||
|
||||
//还有最后一个问题,穿山甲的Activity没改
|
||||
public static void main(String[] args) {
|
||||
CsjTools tools=new CsjTools();
|
||||
tools.out();
|
||||
if (false) {
|
||||
new AutoRandomAdSDK().startNotUnPackage("D:\\IdeaProjects\\android_sdk_tools\\demo_2.8.0.2", new SmaliApkToolsPath() {
|
||||
@Override
|
||||
public void smaliPath(String path) {
|
||||
System.out.println("-------" + path);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
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();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user