关于反编译后添加资源回编译后资源ID的问题
2017-07-13 本文已影响25人
小慕汐
向来不喜欢写文字,代码拿去
package com.lion.ccsdk.utils;
import com.lion.ccsdk.interfaces.OnDocumentListener;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
public class DocumentUtils {
public static final String WORK_PATH = "D:\\android\\trunk\\ccplay_2016\\CCPaySdk\\tools\\test_apk_build";
public static final String INTENT_FILTER = "intent-filter";
public static final String ACTION = "action";
public static final String CATEGORY = "category";
public static final String ANDROID_NAME = "android:name";
public static final String ANDROID_MAIN = "android.intent.action.MAIN";
public static final String ANDROID_LAUNCHER = "android.intent.category.LAUNCHER";
public static final String APPLICATION = "application";
public static final String ACTIVITY = "activity";
public static final String SERVICE = "service";
public static final String RECEIVER = "receiver";
public static final String MANIFEST_TAG = "manifest";
public static final String PACKAGE = "package";
public static final String RES = "res";
public static final String LIB = "lib";
public static final String SMALI = "smali";
public static final String VALUES = "values";
public static final String MANIFEST = "AndroidManifest.xml";
public static final String XML = ".xml";
public static final String PUBLIC = "public";
public static final String NAME = "name";
public static final String TYPE = "type";
public static final String ID = "id";
public static final String CC_SDK_RES = "lion_";
public static final String CC_SDK_JAVA = "com.lion.ccpay";
public static final String ALIPAY_SDK_ACTIVITY = "com.alipay.sdk.app.H5PayActivity";
public static final String UNIONPAY_SDK_ACTIVITY = "com.unionpay.uppay";
public static final String PNG_SUFFIX = ".png";
public static final String SPLASH = "splash";
public static final String OUT = "out";
public static final String SDK = "sdk";
public static final String APK = "apk";
public static final String WATER = "water";
public static void updateDocument(String fileUrl, OnDocumentListener listener) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new File(fileUrl));
document.normalize();
if (listener != null) {
listener.update(document);
}
DOMSource source = new DOMSource(document);
StreamResult result = new StreamResult(new File(fileUrl));
TransformerFactory.newInstance().newTransformer().transform(source, result);
}
public static void writeAppMain(Document document, Element element) {
element.appendChild(document.createElement(INTENT_FILTER));
element = (Element) element.getElementsByTagName(INTENT_FILTER).item(0);
Element childElement = document.createElement(ACTION);
childElement.setAttribute(ANDROID_NAME, ANDROID_MAIN);
element.appendChild(childElement);
childElement = document.createElement(CATEGORY);
childElement.setAttribute(ANDROID_NAME, ANDROID_LAUNCHER);
element.appendChild(childElement);
}
public static Document newDocument(String fileUrl) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.newDocument();
return document;
}
public static Document readDocument(String fileUrl) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new File(fileUrl));
document.normalize();
return document;
}
public static void writeDocument(Document document, String fileUrl) throws Exception {
DOMSource source = new DOMSource(document);
StreamResult result = new StreamResult(new File(fileUrl));
TransformerFactory.newInstance().newTransformer().transform(source, result);
}
}
package com.lion.ccsdk.utils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import java.io.File;
import java.io.FileOutputStream;
import java.util.HashMap;
import java.util.Set;
import static com.lion.ccsdk.utils.DocumentUtils.ID;
import static com.lion.ccsdk.utils.DocumentUtils.NAME;
import static com.lion.ccsdk.utils.DocumentUtils.PUBLIC;
import static com.lion.ccsdk.utils.DocumentUtils.RES;
import static com.lion.ccsdk.utils.DocumentUtils.TYPE;
import static com.lion.ccsdk.utils.DocumentUtils.VALUES;
import static com.lion.ccsdk.utils.DocumentUtils.XML;
public class RUtils {
private static final String SMALI_SUFFIX = ".smali";
private static final String SMALI = "smali";
private static final String R_SUB_PATH = "R$%s";
private static final String R = "R";
private static final String L_PATH = "L%s/%s;";
private static final String COMMA = ",";
private static final String R_TITLE = ".class public final L%s/%s;\n" +
".super Ljava/lang/Object;\n" +
".source \"R.java\"";
private static final String ENCLOSING_CLASS = "# annotations\n" +
" .annotation system Ldalvik/annotation/EnclosingClass;\n" +
" value = L%s/R;\n" +
" .end annotation";
private static final String INNER_CLASS = ".annotation system Ldalvik/annotation/InnerClass;\n" +
" accessFlags = 0x19\n" +
" name = \"%s\"\n" +
".end annotation";
private static final String STATIC = "# static fields";
private static final String ITEM = ".field public static final %s:I = %s";
private static final String CONSTRUCTOR = "# direct methods\n" +
".method public constructor <init>()V\n" +
" .locals 0\n" +
"\n" +
" .prologue\n" +
" .line 664\n" +
" invoke-direct {p0}, Ljava/lang/Object;-><init>()V\n" +
"\n" +
" return-void\n" +
".end method";
private static final String R_ANNOTATIONS_START = "# annotations\n" +
".annotation system Ldalvik/annotation/MemberClasses;\n" +
" value = {\n";
private static final String R_ANNOTATIONS_END = " }\n" +
".end annotation";
////处理R.smali
public static void buildR(String praiseDir, String packageName) {
File outSmaliFile = new File(praiseDir, SMALI);
String packagePath = packageName.replace(".", "/");
File pkgDir = new File(outSmaliFile, packagePath);
if (!pkgDir.exists()) {
pkgDir.mkdirs();
}
File resFile = new File(praiseDir, RES);
File valueFile = new File(resFile, VALUES);
File publicFile = new File(valueFile, PUBLIC + XML);
try {
Document document = DocumentUtils.readDocument(publicFile.getAbsolutePath());
NodeList nodeList = document.getElementsByTagName(PUBLIC);
HashMap<String, FileOutputStream> outputStreamHashMap = new HashMap<>();
for (int i = 0; i < nodeList.getLength(); i++) {
Element element = (Element) nodeList.item(i);
String nodeId = element.getAttribute(ID);
String type = element.getAttribute(TYPE);
String name = element.getAttribute(NAME);
FileOutputStream fos = outputStreamHashMap.get(type);
if (fos == null) {
File file = new File(pkgDir, String.format(R_SUB_PATH + SMALI_SUFFIX, type));
fos = new FileOutputStream(file);
outputStreamHashMap.put(type, fos);
writeString(fos, String.format(R_TITLE, packagePath, String.format(R_SUB_PATH, type)));
writeString(fos, String.format(ENCLOSING_CLASS, packagePath));
writeString(fos, String.format(INNER_CLASS, type));
writeString(fos, STATIC);
}
writeString(fos, String.format(ITEM, name, nodeId));
}
File file = new File(pkgDir, R + SMALI_SUFFIX);
FileOutputStream fos4R = new FileOutputStream(file);
writeString(fos4R, String.format(R_TITLE, packagePath, R));
writeString(fos4R, R_ANNOTATIONS_START);
Set<String> keys = outputStreamHashMap.keySet();
int index = 0;
for (String key : keys) {
index++;
if (index == keys.size()) {
writeString(fos4R, String.format(L_PATH, packagePath, String.format(R_SUB_PATH, key)));
} else {
writeString(fos4R, String.format(L_PATH + COMMA, packagePath, String.format(R_SUB_PATH, key)));
}
FileOutputStream fos = outputStreamHashMap.get(key);
if (fos != null) {
writeString(fos, CONSTRUCTOR);
fos.flush();
fos.close();
}
}
writeString(fos4R, R_ANNOTATIONS_END);
writeString(fos4R, CONSTRUCTOR);
outputStreamHashMap.clear();
} catch (Exception e) {
e.printStackTrace();
}
}
private static void writeString(FileOutputStream fos, String str) throws Exception {
fos.write(str.getBytes());
fos.write("\n".getBytes());
fos.write("\n".getBytes());
}
}