关于反编译后添加资源回编译后资源ID的问题

向来不喜欢写文字,代码拿去

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());
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,529评论 5 475
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,015评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,409评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,385评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,387评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,466评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,880评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,528评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,727评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,528评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,602评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,302评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,873评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,890评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,132评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,777评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,310评论 2 342

推荐阅读更多精彩内容