558 lines
21 KiB
Java
558 lines
21 KiB
Java
package com.qy.utils;
|
||
|
||
import java.awt.Desktop;
|
||
import java.io.BufferedReader;
|
||
import java.io.File;
|
||
import java.io.FileNotFoundException;
|
||
import java.io.FileReader;
|
||
import java.io.IOException;
|
||
import java.io.PrintWriter;
|
||
import java.sql.SQLOutput;
|
||
import java.util.ArrayList;
|
||
import java.util.HashMap;
|
||
import java.util.List;
|
||
import java.util.Map;
|
||
import java.util.Random;
|
||
|
||
import org.json.JSONArray;
|
||
import org.json.JSONObject;
|
||
|
||
import com.qy.Interfaces.DalogAbs;
|
||
/*
|
||
配置JSON格式:
|
||
{
|
||
"title": "趣赢SDK", //标题
|
||
"ltName": "qysdk.jar", //保存文件名
|
||
"manifest": [
|
||
//原始清单配置
|
||
],
|
||
"class": [ //希望变动的类
|
||
"com.qy.sdk.views.MyActivity",
|
||
],
|
||
"random": [//修改包名
|
||
"com",//固定包名
|
||
"[random]"//随机包名
|
||
],
|
||
"rename": {//修改类名
|
||
"MyActivity": "Activity",//指定类名
|
||
"TMProvider":"TProvider[notmover]",//指定类名,但不移动路径
|
||
"BannerView":"[random]"//随机类名(2~6)
|
||
"BannerView":"{+/activity}BannerView"//指定路径 [+表示在random的基础上]
|
||
},
|
||
"isAllPackage":true,//修改所有包名,false的话只修改class指定的包名
|
||
"isReName": true,//重命名类名
|
||
"isJarLib":true,//打出成jar包,false的话则会进行加密
|
||
"packagerlimit": 3,//修改包名长度,需小于或等于random数组
|
||
"isManual": false,//手动修改类文件
|
||
"manual": [
|
||
//需要手动修改的类
|
||
],
|
||
"dex2jar":"/media/yutou/_dde_data/反编译/dex2jar-2.0/_d2j-dex2jar.sh"//指定dex2jar的路径
|
||
}
|
||
*/
|
||
import com.qy.Interfaces.SmaliApkToolsPath;
|
||
import com.qy.ui.TextToDalog;
|
||
|
||
public class AutoRandomAdSDK {
|
||
private File sdk;
|
||
private JSONObject config;
|
||
private SmaliUtils smalitools;
|
||
private Map<String, File> adClass;
|
||
private Map<String, File> nowAdClass;
|
||
private Map<String, String> nowAdFile;
|
||
private String rootPath;
|
||
private String dxPath;
|
||
private String version;
|
||
private String sdktype;
|
||
private SmaliApkToolsPath inter;
|
||
private boolean isDev = false;
|
||
|
||
public static void main(String[] args) {
|
||
// TODO Auto-generated method stub
|
||
new AutoRandomAdSDK(new File("JooMobAdSDK_6.1.8.jar"), "5600", "5", 1, null);
|
||
// new AutoRandomAdSDK(new File("GDTSDK.unionNormal.4.100.970.jar"), 0, null);
|
||
}
|
||
|
||
public AutoRandomAdSDK() {
|
||
|
||
}
|
||
|
||
public AutoRandomAdSDK(File sdk, String version, String type, int cfgIndex, SmaliApkToolsPath inster) {
|
||
// TODO Auto-generated constructor stub
|
||
this.inter = inster;
|
||
this.version = version;
|
||
this.sdktype = type;
|
||
JSONObject cfg = Tools.loadConfig(new File("ad_config.cfg"));
|
||
if (cfg == null) {
|
||
throw new NullPointerException("没有广告配置文件");
|
||
}
|
||
this.sdk = sdk;
|
||
config = cfg.getJSONArray("array").getJSONObject(cfgIndex);
|
||
start();
|
||
}
|
||
|
||
public void start() {
|
||
adClass = new HashMap<String, File>();
|
||
nowAdClass = new HashMap<String, File>();
|
||
nowAdFile = new HashMap<String, String>();
|
||
smalitools = new SmaliUtils();
|
||
File tmpSdk = new File(sdk.getAbsolutePath().replace(sdk.getName(), "new_" + sdk.getName()));
|
||
if (isDev) {
|
||
dxPath = "/media/yutou/_dde_data/AndroidStudio_Data/buildTools/dx.jar";
|
||
sdktype = "3";
|
||
version = "1000";
|
||
} else {
|
||
JSONObject json = Tools.loadConfig(new File("config.cfg"));
|
||
dxPath = json.getString("dx");
|
||
}
|
||
JarToAJar.toAJar(dxPath, sdk.getAbsolutePath(),
|
||
tmpSdk.getAbsolutePath());
|
||
sdk = new File(tmpSdk.getAbsolutePath());
|
||
try {
|
||
Thread.sleep(2000);
|
||
} catch (InterruptedException e) {
|
||
// TODO Auto-generated catch block
|
||
e.printStackTrace();
|
||
}
|
||
smalitools.unPack(sdk.getAbsolutePath(), new SmaliApkToolsPath() {
|
||
|
||
@Override
|
||
public void smaliPath(String path) {
|
||
// TODO Auto-generated method stub
|
||
rootPath = path;
|
||
alter();
|
||
}
|
||
});
|
||
}
|
||
|
||
boolean isPackage = true;
|
||
|
||
public void startNotUnPackage(String path, SmaliApkToolsPath inster) {
|
||
this.inter = inster;
|
||
isPackage = false;
|
||
adClass = new HashMap<String, File>();
|
||
nowAdClass = new HashMap<String, File>();
|
||
nowAdFile = new HashMap<String, String>();
|
||
smalitools = new SmaliUtils();
|
||
JSONObject cfg = Tools.loadConfig(new File("ad_config.cfg"));
|
||
config = cfg.getJSONArray("array").getJSONObject(4);
|
||
rootPath = path;
|
||
sdktype = "13";
|
||
alter();
|
||
}
|
||
|
||
private void alter() {
|
||
JSONArray clazzs = config.getJSONArray("class");
|
||
for (int i = 0; i < clazzs.length(); i++) {
|
||
File clz = new File(rootPath + File.separator + "smali" + File.separator
|
||
+ clazzs.getString(i).replace(".", File.separator) + ".smali");
|
||
|
||
if (clz.exists()) {
|
||
adClass.put(clazzs.getString(i), clz);
|
||
}
|
||
}
|
||
for (String key : adClass.keySet()) {
|
||
System.out.println("注入的值:" + key);
|
||
}
|
||
mkdirs();
|
||
update();
|
||
change();
|
||
|
||
}
|
||
|
||
private void outManifest() {
|
||
if (!config.isNull("outManifest") && !config.getBoolean("outManifest")) {
|
||
return;
|
||
}
|
||
JSONArray array = new JSONArray();
|
||
for (String key : nowAdClass.keySet()) {
|
||
JSONArray manifest = config.getJSONArray("manifest");
|
||
for (int i = 0; i < manifest.length(); i++) {
|
||
if (manifest.getString(i).contains(key)) {
|
||
String path = nowAdClass.get(key).getAbsolutePath();
|
||
String newManifest = path
|
||
.replace(sdk.getAbsolutePath() + ".out" + File.separator + "smali" + File.separator, "");
|
||
try {
|
||
newManifest = newManifest.replace(File.separator, ".") + "." + adClass.get(key).getName();
|
||
array.put(manifest.getString(i).replace(key, newManifest.replace(".smali", "")));
|
||
} catch (Exception e) {
|
||
// TODO: handle exception
|
||
e.printStackTrace();
|
||
System.out.println("-------->" + adClass.size());
|
||
for (String keys : adClass.keySet()) {
|
||
System.out.println(keys + " " + adClass.get(keys));
|
||
}
|
||
}
|
||
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
File manifest = new File(sdk.getAbsolutePath() + ".out" + File.separator + "manifest.xml");
|
||
PrintWriter writer;
|
||
try {
|
||
writer = new PrintWriter(manifest);
|
||
for (int i = 0; i < array.length(); i++) {
|
||
writer.write(array.getString(i).toString() + "\n");
|
||
writer.flush();
|
||
}
|
||
writer.close();
|
||
} catch (FileNotFoundException e) {
|
||
// TODO Auto-generated catch block
|
||
e.printStackTrace();
|
||
}
|
||
}
|
||
|
||
private void change() {
|
||
File file;
|
||
if (sdk == null) {
|
||
smalitools.setPath(rootPath + File.separator + "smali");
|
||
file = new File(rootPath + File.separator + "smali");
|
||
} else {
|
||
smalitools.setPath(sdk.getAbsolutePath() + ".out" + File.separator + "smali");
|
||
file = new File(sdk.getAbsolutePath() + ".out" + File.separator + "smali");
|
||
}
|
||
System.out.println(smalitools.mainPath);
|
||
try {
|
||
Thread.sleep(200);
|
||
System.out.println(smalitools.mainPath);
|
||
|
||
|
||
if (file.exists()) {
|
||
JSONArray array = config.isNull("filter")?null:config.getJSONArray("filter");
|
||
if (array != null) {
|
||
List<String> list = new ArrayList<>();
|
||
for (int i = 0; i < array.length(); i++) {
|
||
list.add(array.getString(i));
|
||
}
|
||
smalitools.setFilter(list);
|
||
}
|
||
smalitools.start();
|
||
if (config.getBoolean("isManual")) {
|
||
manual();
|
||
} else {
|
||
out();
|
||
}
|
||
}
|
||
} catch (InterruptedException e) {
|
||
// TODO Auto-generated catch block
|
||
e.printStackTrace();
|
||
}
|
||
|
||
}
|
||
|
||
private void manual() {
|
||
JSONArray man = config.getJSONArray("manual");
|
||
for (int i = 0; i < man.length(); i++) {
|
||
JSONObject json = man.getJSONObject(i);
|
||
File file = new File(sdk.getAbsolutePath() + ".out" + File.separator + "smali" + File.separator
|
||
+ json.getString("class").replace(".", File.separator) + ".smali");
|
||
if (file.exists()) {
|
||
List<Integer> list = new ArrayList<Integer>();
|
||
try {
|
||
BufferedReader reader = new BufferedReader(new FileReader(file));
|
||
String tmp;
|
||
int index = 1;
|
||
while ((tmp = reader.readLine()) != null) {
|
||
if (tmp.contains(json.getString("find"))) {
|
||
list.add(index);
|
||
}
|
||
index++;
|
||
}
|
||
reader.close();
|
||
Desktop.getDesktop().open(file);
|
||
} catch (IOException e) {
|
||
// TODO Auto-generated catch block
|
||
e.printStackTrace();
|
||
System.out.println("请手动打开:" + file.getAbsolutePath() + " 文件");
|
||
}
|
||
String index = "";
|
||
for (Integer integer : list) {
|
||
System.out.println("请修改第:" + integer + " 行附近的代码");
|
||
index += integer + ",";
|
||
}
|
||
new TextToDalog("提示", "请修改第:" + index + " 行附近的代码,备注:" + json.getString("msg"), new DalogAbs() {
|
||
|
||
@Override
|
||
public void onSuccess() {
|
||
// TODO Auto-generated method stub
|
||
out();
|
||
}
|
||
});
|
||
|
||
}
|
||
}
|
||
}
|
||
private void show(File file){
|
||
for (File listFile : file.listFiles()) {
|
||
if(listFile.isDirectory()){
|
||
show(listFile);
|
||
}else{
|
||
System.out.println(">?"+listFile.getAbsolutePath());
|
||
}
|
||
|
||
}
|
||
}
|
||
private void out() {
|
||
if (!isPackage) {
|
||
if (inter != null) {
|
||
inter.smaliPath("not package");
|
||
return;
|
||
}
|
||
}
|
||
String path;
|
||
String name;
|
||
if (sdk == null) {
|
||
path = rootPath;
|
||
name = "tmp.zip";
|
||
} else {
|
||
path = sdk.getAbsolutePath() + ".out";
|
||
name = sdk.getName();
|
||
}
|
||
try {
|
||
Thread.sleep(2000);
|
||
} catch (InterruptedException e) {
|
||
e.printStackTrace();
|
||
}
|
||
smalitools.bale(path,
|
||
path + File.separator + name, new SmaliApkToolsPath() {
|
||
|
||
@Override
|
||
public void smaliPath(String path) {
|
||
// TODO Auto-generated method stub
|
||
try {
|
||
Thread.sleep(2000);
|
||
outManifest();
|
||
File lt;
|
||
File nLt = null;
|
||
try {
|
||
if (!config.getBoolean("isJarLib")) {
|
||
JarToAJar.toAJar(dxPath, sdk.getAbsolutePath() + ".out" + File.separator + sdk.getName(), sdk.getAbsolutePath() + ".out" + File.separator + sdk.getName() + "_dex.jar");
|
||
new EncryptJar().encrypt(new File(sdk.getAbsolutePath() + ".out" + File.separator + sdk.getName())
|
||
, sdk.getAbsolutePath() + ".out" + File.separator + "dexTmp.jar", sdktype, version);
|
||
lt = new File(sdk.getAbsolutePath() + ".out" + File.separator + "dexTmp.jar");
|
||
} else {
|
||
System.out.println(sdk.getAbsolutePath() + ".out" + File.separator + sdk.getName());
|
||
|
||
String exec=config.getString("dex2jar") + " " + sdk.getAbsolutePath() + ".out" + File.separator + sdk.getName();
|
||
System.out.println("exec:"+exec);
|
||
Process process = Runtime.getRuntime().exec(exec);
|
||
process.waitFor();
|
||
Thread.sleep(100);
|
||
process=Runtime.getRuntime().exec(exec);
|
||
process.waitFor();
|
||
lt = new File(sdk.getAbsolutePath().split(sdk.getName())[0], sdk.getName().replace(".jar", "-dex2jar.jar"));
|
||
}
|
||
System.out.println(">>>:" + lt.getAbsolutePath());
|
||
if (lt.exists()) {
|
||
nLt = new File(config.getString("ltName"));
|
||
if(nLt.exists()){
|
||
nLt.delete();
|
||
}
|
||
lt.renameTo(nLt);
|
||
|
||
}
|
||
} catch (Exception e) {
|
||
e.printStackTrace();
|
||
}
|
||
|
||
|
||
if (inter != null)
|
||
inter.smaliPath(nLt == null ? rootPath : nLt.getAbsolutePath());
|
||
} catch (Exception e) {
|
||
// TODO: handle exception
|
||
e.printStackTrace();
|
||
}
|
||
}
|
||
});
|
||
|
||
|
||
}
|
||
|
||
private void update() {
|
||
for (String key : adClass.keySet()) {
|
||
File file = adClass.get(key);
|
||
String fileName = file.getName().replace(".smali", "");
|
||
File filePath = new File(file.getAbsolutePath().replace(file.getName(), ""));
|
||
|
||
for (File fs : filePath.listFiles()) {
|
||
System.out.println(fs.getAbsolutePath().replace(new File("").getAbsolutePath(),""));
|
||
if(fs.isDirectory()){
|
||
continue;
|
||
}
|
||
if(!fs.getName().startsWith(fileName)){
|
||
continue;
|
||
}
|
||
String nName = getNewName(fs.getName());
|
||
if (fs.getName().startsWith(fileName + "$")) {
|
||
|
||
if (getNewName(fs.getName()).endsWith("[notmover]")) {
|
||
Tools.copyFileToName(fs.getAbsolutePath(), fs.getAbsolutePath(),
|
||
nName + "$" + fs.getName().split("\\$")[1], true);
|
||
} else {
|
||
moveFile(fs, key, nName + "$" + fs.getName().split("\\$")[1],false);
|
||
}
|
||
fs.delete();
|
||
}
|
||
}
|
||
if (getNewNameForSrc(file.getName()).endsWith("[notmover]")) {
|
||
nowAdFile.put(key, file.getAbsolutePath());
|
||
Tools.copyFileToName(file.getAbsolutePath(), file.getAbsolutePath().replace(file.getName(), ""),
|
||
getNewName(file.getName()) + ".smali", true);
|
||
} else {
|
||
moveFile(file, key, getNewName(file.getName()) + ".smali",true);
|
||
}
|
||
|
||
file.delete();
|
||
}
|
||
System.out.println("配置:"+config.getBoolean("isAllPackage"));
|
||
if (config.getBoolean("isAllPackage")) {
|
||
String tmp = nowAdClass.keySet().iterator().next();
|
||
File path = new File((nowAdClass.get(tmp)).getAbsolutePath());
|
||
String packge = path.getAbsolutePath().replace(rootPath + File.separator + "smali" + File.separator, "");
|
||
File root = new File(rootPath + File.separator + "smali");
|
||
allpackage(root, packge);
|
||
removeNullFile(root);
|
||
}
|
||
}
|
||
|
||
private void moveFile(File file, String key, String nName, boolean isAddFile) {
|
||
String path;
|
||
if (nName.startsWith("{>")) {
|
||
nName = nName.replace("{>", "");
|
||
String tmp = nName.split("}")[0];
|
||
nName = nName.split("}")[1];
|
||
tmp = tmp.replace("}", "");// +/activity
|
||
tmp = tmp.replace("/", File.separator);
|
||
String t = tmp.substring(0, 1);
|
||
if (t.equals("+")) {
|
||
path = nowAdClass.get(key).getAbsolutePath() + tmp.replace("+","");
|
||
} else {
|
||
path = rootPath + File.separator + "smali" + tmp;
|
||
}
|
||
} else {
|
||
path = nowAdClass.get(key).getAbsolutePath();
|
||
}
|
||
if (isAddFile)
|
||
nowAdFile.put(key, nowAdClass.get(key).getAbsolutePath());
|
||
Tools.copyFileToName(file.getAbsolutePath(), path,
|
||
nName, true);
|
||
}
|
||
|
||
private void allpackage(File file, String packge) {
|
||
for (File tmp : file.listFiles()) {
|
||
|
||
String pack = tmp.getAbsolutePath().replace(rootPath + File.separator + "smali" + File.separator, "");
|
||
if (!packge.contains(pack) && tmp.isDirectory()) {
|
||
movesdk(tmp, File.separator + "smali" + File.separator + packge);
|
||
}
|
||
if (tmp.isDirectory()) {
|
||
allpackage(tmp, packge);
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
private void movesdk(File path, String toPath) {
|
||
for (File file : path.listFiles()) {
|
||
if (file.getName().equals("BuildConfig.smali")) {
|
||
file.delete();
|
||
continue;
|
||
}
|
||
|
||
if (file.isDirectory()) {
|
||
String tmp = toPath + File.separator + file.getName();
|
||
//System.out.println("创建文件夹:"+tmp);
|
||
new File(rootPath + File.separator + tmp).mkdirs();
|
||
movesdk(file, tmp);
|
||
} else {
|
||
boolean data=file.renameTo(new File(rootPath + File.separator + toPath, file.getName()));
|
||
// System.out.println("移动文件:"+file.getAbsolutePath().replace(rootPath, "")+" 到"+(rootPath + File.separator + toPath)+" "+data);
|
||
}
|
||
}
|
||
}
|
||
|
||
private void removeNullFile(File root) {
|
||
for (File file : root.listFiles()) {
|
||
if (file.isDirectory()) {
|
||
if (file.listFiles().length == 0) {
|
||
file.delete();
|
||
} else {
|
||
removeNullFile(file);
|
||
if (file.listFiles().length == 0) {
|
||
file.delete();
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
private String getNewName(String name) {
|
||
String nName = getNewNameForSrc(name);
|
||
if (nName.endsWith("[notmover]")) {
|
||
nName = nName.replace("[notmover]", "");
|
||
}
|
||
|
||
return nName;
|
||
}
|
||
|
||
private String getNewNameForSrc(String name) {
|
||
// TODO Auto-generated method stub
|
||
if (!config.getBoolean("isReName")) {
|
||
return name;
|
||
}
|
||
String tmpName;
|
||
String wName = null;
|
||
name = name.replace(".smali", "");
|
||
if (name.contains("$")) {
|
||
tmpName = name.split("$")[0];
|
||
for (String t : name.split("$")) {
|
||
if (!t.equals(tmpName)) {
|
||
wName += t;
|
||
}
|
||
}
|
||
} else {
|
||
tmpName = name;
|
||
}
|
||
|
||
String nName = config.getJSONObject("rename")
|
||
.getString(tmpName.contains("$") ? tmpName.split("\\$")[0] : tmpName);
|
||
if (nName.contains("[random]")) {
|
||
String tName = Tools.getRandomString(new Random().nextInt(6) + 2);
|
||
nName = nName.replace("[random]", tName);
|
||
config.getJSONObject("rename").put(tmpName.contains("$") ? tmpName.split("\\$")[0] : tmpName, nName);
|
||
}
|
||
if (wName != null) {
|
||
nName += wName;
|
||
}
|
||
return nName;
|
||
}
|
||
|
||
private void mkdirs() {
|
||
JSONArray clazzs = config.getJSONArray("class");
|
||
JSONArray random = config.getJSONArray("random");
|
||
for (int i = 0; i < clazzs.length(); i++) {
|
||
File path = new File(rootPath + File.separator + "smali");
|
||
File mkdir = null;
|
||
for (int j = 0; j < config.getInt("packagerlimit"); j++) {
|
||
String packageName;
|
||
if (random.getString(j).equals("[random]")) {
|
||
packageName = Tools.getRandomString(3);
|
||
} else {
|
||
packageName = random.getString(j);
|
||
}
|
||
if (mkdir == null) {
|
||
mkdir = new File(path.getAbsolutePath() + File.separator + packageName);
|
||
} else {
|
||
mkdir = new File(mkdir.getAbsolutePath() + File.separator + packageName);
|
||
}
|
||
if (!mkdir.exists()) {
|
||
mkdir.mkdirs();
|
||
}
|
||
}
|
||
nowAdClass.put(clazzs.getString(i), mkdir);
|
||
}
|
||
}
|
||
}
|