关于反编译后添加资源回编译后资源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());
    }
}
上一篇下一篇

猜你喜欢

热点阅读