From 0e26919cec6b3720a86b32ff6e2367ffe803e677 Mon Sep 17 00:00:00 2001 From: Nico Mexis Date: Tue, 29 Mar 2022 16:54:23 +0200 Subject: [PATCH] Improve handling of large arrays --- .../java/com/googlecode/d2j/dex/Dex2Asm.java | 36 ++++++++++++------ .../src/{test => main}/java/res/Hex.java | 13 +++++-- .../main/resources/d2j_hex_decode_stub.data | Bin 2278 -> 0 bytes 3 files changed, 34 insertions(+), 15 deletions(-) rename dex-translator/src/{test => main}/java/res/Hex.java (91%) delete mode 100644 dex-translator/src/main/resources/d2j_hex_decode_stub.data diff --git a/dex-translator/src/main/java/com/googlecode/d2j/dex/Dex2Asm.java b/dex-translator/src/main/java/com/googlecode/d2j/dex/Dex2Asm.java index 8973058b3..ac37f0fee 100644 --- a/dex-translator/src/main/java/com/googlecode/d2j/dex/Dex2Asm.java +++ b/dex-translator/src/main/java/com/googlecode/d2j/dex/Dex2Asm.java @@ -31,7 +31,7 @@ import com.googlecode.dex2jar.ir.ts.VoidInvokeTransformer; import com.googlecode.dex2jar.ir.ts.ZeroTransformer; import com.googlecode.dex2jar.ir.ts.array.FillArrayTransformer; -import java.io.IOException; +import com.googlecode.dex2jar.tools.Constants; import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; @@ -549,32 +549,44 @@ public void convertClass(int dexVersion, DexClassNode classNode, ClassVisitorFac convertMethod(classNode, methodNode, cv, clzCtx); } if (clzCtx.hexDecodeMethodNamePrefix != null) { - addHexDecodeMethod(cv, clzCtx.hexDecodeMethodNamePrefix); + addHexDecodeMethod(cv, classNode.className.replaceFirst("^L", "").replaceAll(";$", ""), + clzCtx.hexDecodeMethodNamePrefix); } } cv.visitEnd(); } - private void addHexDecodeMethod(ClassVisitor outCV, String hexDecodeMethodNameBase) { + private static final Set HEX_DECODE_METHODS = + new HashSet<>(Arrays.asList("decode_J", "decode_I", "decode_S", "decode_B")); + + private void addHexDecodeMethod(ClassVisitor outCV, String className, String hexDecodeMethodNameBase) { // the .data is a class-file compiled from res.Hex - try (InputStream is = Dex2Asm.class.getResourceAsStream("/d2j_hex_decode_stub.data")) { + try (InputStream is = Dex2Asm.class.getResourceAsStream("/res/Hex.class")) { ClassReader cr = new ClassReader(is); - cr.accept(new ClassVisitor(Opcodes.ASM5) { + cr.accept(new ClassVisitor(Constants.ASM_VERSION) { @Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { - if (name.startsWith("decode")) { - return outCV.visitMethod(Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC, - hexDecodeMethodNameBase + "$" + name, - desc, signature, exceptions - ); + if (HEX_DECODE_METHODS.contains(name)) { + return new MethodVisitor(Constants.ASM_VERSION, + outCV.visitMethod(Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC, + hexDecodeMethodNameBase + "$" + name, + desc, signature, exceptions + )) { + @Override + public void visitMethodInsn(int opcode, String owner, String name, String descriptor, + boolean isInterface) { + super.visitMethodInsn(opcode, owner.equals("res/Hex") ? className : owner, name, + descriptor, isInterface); + } + }; } else { return super.visitMethod(access, name, desc, signature, exceptions); } } }, ClassReader.EXPAND_FRAMES); - } catch (IOException e) { - throw new RuntimeException("fail to add hex.decode", e); + } catch (Throwable t) { + throw new RuntimeException("Failed to add Hex.decode_*", t); } } diff --git a/dex-translator/src/test/java/res/Hex.java b/dex-translator/src/main/java/res/Hex.java similarity index 91% rename from dex-translator/src/test/java/res/Hex.java rename to dex-translator/src/main/java/res/Hex.java index b53eac2f3..d6a3010b1 100644 --- a/dex-translator/src/test/java/res/Hex.java +++ b/dex-translator/src/main/java/res/Hex.java @@ -1,8 +1,13 @@ package res; -import java.nio.*; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.IntBuffer; +import java.nio.LongBuffer; +import java.nio.ShortBuffer; public class Hex { + public static long[] decode_J(String src) { byte[] d = decode_B(src); ByteBuffer b = ByteBuffer.wrap(d); @@ -12,6 +17,7 @@ public static long[] decode_J(String src) { s.get(data); return data; } + public static int[] decode_I(String src) { byte[] d = decode_B(src); ByteBuffer b = ByteBuffer.wrap(d); @@ -38,7 +44,7 @@ public static byte[] decode_B(String src) { for (int i = 0; i < ret.length; i++) { char h = d[2 * i]; char l = d[2 * i + 1]; - int hh = 0; + int hh; if (h >= '0' && h <= '9') { hh = h - '0'; } else if (h >= 'a' && h <= 'f') { @@ -48,7 +54,7 @@ public static byte[] decode_B(String src) { } else { throw new RuntimeException(); } - int ll = 0; + int ll; if (l >= '0' && l <= '9') { ll = h - '0'; } else if (l >= 'a' && l <= 'f') { @@ -62,4 +68,5 @@ public static byte[] decode_B(String src) { } return ret; } + } diff --git a/dex-translator/src/main/resources/d2j_hex_decode_stub.data b/dex-translator/src/main/resources/d2j_hex_decode_stub.data deleted file mode 100644 index 7cd3159c1fde83ff914d68010a3b803f2e1d128f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2278 zcmb7FT~ixX7=BKY&4y*6DUedq0##ecR|{HkjCf5D+XXE)?ygc+U8o^#%>=Y7umzPtHp z`^gr75!}$QA7dK)IIrPVBw8?z33<98mq`s%cuk%zYDnUeJiV?Vg=r0=n32n@iZ?X0 zV@$=HD&_>dXA7l5WlX>w3NH$HCdye;U|*_GGG{h!teDnq9d&W@FDCLIcD^{VD8x5yvaIae#iTE$8 zfXE8C(&Id=2m~CDQlUIFey3uNZ>+AG7IO&ZY_O%urCiPC$r=?yVldARm*ietXy~fv zNR}!!7+0FMo%s2^;-#S;Kc6pKjR>^vAn-!FS3}-3&u4;9k+kztU}{&9k|@ZF(B!tv zia^_Z#mHQrHg4M0R}ojyr-E6u`SOO9F{cW$Q9kzJgsiNN4s_}`juR>tbX>-wiX|Oy z;fjv8k=Ah)@2GfJ$1<+zFtDN`BZaIE6RRq6QpoElU`@w$kWaAQu(^#=rEtTXyqz&` zRtn{kfLfga0e{_Xc4f`Xka~m483ch&+pD>^oWEO^aZ{itlpYV)E8Eolj;6p_D{ES; zO)9ytkeXbcoVk!p%rv!C2HReo9Hs2IN2{Z`lisoKl~Fg=>oX?M9cpl_8wg*&Q(evO z@VN<-X*)J7gb ze8qzc0j^$0i32?A)pIuvQffgDg4D?1PwB02k3=5Bm5M%wdpht6W#Lr zikq!xJjZ*eRF`@@U((yj&ieQox_Rw> z7HELKfn(8cZaeY8m_8}~jyf+yo1y1A|1hhIurzjjTU1}G#P)0AUM?3h}= zMf;UU*!R6Vt_BnbSZM%OC9vWEE6u<(4bWr*EB+>6nrgt&-hfxV9Z)~`C4uONy9VwmN}{VGeg#`ozKUc~!2i4Qp)ALC_w zhB&^U=QlWoA8;B!^UwcRoWmbPd5ZIPo90;JUi`@DVU~LU-w|V&S;KgOmx$#hnnApi zd|~|fji@KdkWHyg-k*$*vt{l0ow@or_NQo%LEDC3#c361#5RV75W%4OH-d6|Mku$6 OQO8VgfwNp)IQI{H3d(!{