正在使用哪些方法来保护此 Android APK:反射?加密?我如何对其进行逆向工程和分析? [英] What methods are being used to protect this Android APK: Reflection? Encryption? How do I reverse engineer it and analyze it?

查看:35
本文介绍了正在使用哪些方法来保护此 Android APK:反射?加密?我如何对其进行逆向工程和分析?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道 Java 编程的基础知识,但我是逆向工程 APK 的新手,所以解释会很好!

I know the basics to java programming, but I'm new to reverse engineering APKs, so explanations would be nice!

我有一个 APK 文件,但没有 Java 源.在线反编译APK后:

I have an APK file file, but not the Java source. After decompiling the APK online:

应用程序的大部分隐藏在

the bulk of the application is hidden under

资产> classes.dex.dat

assets > classes.dex.dat

我找到的唯一java文件是

the only java file I found is

com > ... > util > ProtectedUtils.java

com > ... > util > ProtectedUtils.java

我在下面有 ProtectedUtils.java:如果有人感兴趣,请链接到完整文件

I have ProtectedUtils.java below: Link to full file if anyone is interested

   import android.app.Application;
    import android.app.Instrumentation;
    import android.content.Context;
    import android.os.Build.VERSION;
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import java.util.List;

    public class ProtectedApplicationUtils extends Application {
        private static Application f0d;
        private static boolean f1d;
        private static transient Object[] f2d;
        private static Application dd;
        private static boolean gfgf;

        public ProtectedApplicationUtils() {
            dd = this;
        }

        private static final int attachBaseContext(int i, int i2) {
            int i3 = (i2 + i) >> 24;
            return (i >>> i2) | (i << (-i2));
        }

        public static Context attachBaseContext(Context context) {
            attachBaseContext();
            return context == dd ? f0d : context;
        }

        private static void attachBaseContext() {
            if (!f1d) {
                f1d = true;
                Class cls = Class.forName(m1d("\u50b3\uc849\ue145\ud010\udf4f\u45e5\u6b13\u36e0\u0e7b\ucae7\u774e\uc2b0\ub84a\udeeb\u9071\u3fd2\u3dd6\u3676\u95ca\u031b\udc13\ufaca\u3bf1\u0935\u75af\ud3d6"));
                Class[] clsArr = new Class[0];
                Object invoke = cls.getMethod(m1d("\u50b1\uc852\ue153\ud010\udf45\u45e2\u6b03\u368f\u0e79\ucae3\u7757\uc2e8\ub862\udefc\u907c\u3fef\u3dc8\u366d\u95db\u0303\udc23"), clsArr).invoke(null, new Object[0]);
                Field declaredField = cls.getDeclaredField(m1d("\u50bf\uc866\ue14d\ud00e\udf61\u45fc\u6b07\u36a2\u0e73\ucaf4\u775f\uc2ea\ub862\udee7\u906b\u3fc8"));
                declaredField.setAccessible(true);
                ((List) declaredField.get(invoke)).add(0, f0d);
                Field declaredField2 = cls.getDeclaredField(m1d("\u50bf\uc86e\ue14f\ud00b\udf54\u45e5\u6b16\u36a2\u0e5b\ucae7\u774e\uc2f2\ub862\udeeb\u9064\u3fcf\u3dc9\u3670\u95d0"));
                declaredField2.setAccessible(true);
                declaredField2.set(invoke, f0d);
                Field declaredField3 = cls.getDeclaredField(m1d("\u50bf\uc865\ue14e\ud017\udf4e\u45e8\u6b36\u36be\u0e6a\ucafb\u7757\uc2fd\ub86a\udefc\u906c\u3fd4\u3dce"));
                declaredField3.setAccessible(true);
                Object obj = declaredField3.get(invoke);
                Field declaredField4 = obj.getClass().getDeclaredField(m1d("\u50bb\uc849\ue147\ud00d"));
                declaredField4.setAccessible(true);
                Object obj2 = declaredField4.get(obj);
                Field declaredField5 = obj2.getClass().getDeclaredField(m1d("\u50bf\uc866\ue151\ud012\udf4c\u45e5\u6b14\u36af\u0e6e\ucafe\u7751\uc2f0"));
                declaredField5.setAccessible(true);
                declaredField5.set(obj2, f0d);
                Context baseContext = f0d.getBaseContext();
                Field declaredField6 = baseContext.getClass().getDeclaredField(m1d("\u50bf\uc868\ue154\ud016\udf45\u45fe\u6b34\u36a1\u0e74\ucae3\u775b\uc2e6\ub87f"));
                declaredField6.setAccessible(true);
                declaredField6.set(baseContext, f0d);
            }
        }

        private static final int m0d(byte[] bArr, int i) {
            Object obj = null;
            int i2 = bArr[14] << 16;
            Object obj2 = null;
            while (obj2 == null) {
                obj2 = 3;
                try {
                    return (bArr[(i >> 24) & 255] << 24) | (((bArr[i & 255] & 255) | ((bArr[(i >> 8) & 255] & 255) << 8)) | ((bArr[(i >> 16) & 255] & 255) << 16));
                } catch (Exception e) {
                }
            }
            while (obj == null) {
                obj = 2;
                try {
                    return bArr[i & 127] >> 8;
                } catch (Exception e2) {
                }
            }
            return i2;
        }

static final String m1d(String str) {
        if (f2d == null) {
            mark();
        }
        Object[] objArr = (Object[]) ((Method) f2d[8]).invoke(((Method) f2d[7]).invoke(null, null), null);
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(((Method) f2d[10]).invoke(objArr[((Integer) f2d[12]).intValue()], null));
        int hashCode = stringBuilder.append(((Method) f2d[11]).invoke(objArr[((Integer) f2d[12]).intValue()], null)).toString().hashCode();
        int[] iArr = (int[]) f2d[6];
        int i = hashCode ^ iArr[0];
        int i2 = hashCode ^ iArr[1];
        int i3 = hashCode ^ iArr[2];
        int i4 = hashCode ^ iArr[3];
        iArr = (int[]) f2d[5];
        int[] iArr2 = (int[]) f2d[1];
        int[] iArr3 = (int[]) f2d[2];
        int[] iArr4 = (int[]) f2d[3];
        int[] iArr5 = (int[]) f2d[4];
        byte[] bArr = (byte[]) f2d[0];
        char[] cArr = (char[]) ((Method) f2d[9]).invoke(str, null);
        int i5 = i3;
        i3 = i2;
        i2 = i;
        i = i4;
        Object obj = null;
        while (obj == null) {
            try {
                int length = cArr.length;
                for (int i6 = 0; i6 < length; i6++) {
                    if (i6 % 8 == 0) {
                        int i7;
                        int i8;
                        int i9;
                        int i10 = i2 ^ iArr[0];
                        int i11 = i3 ^ iArr[1];
                        int i12 = i5 ^ iArr[2];
                        i4 = iArr[3] ^ i;
                        int i13 = 4;
                        while (i13 < 36) {
                            i7 = (((iArr2[i10 & 255] ^ iArr3[(i11 >> 8) & 255]) ^ iArr4[(i12 >> 16) & 255]) ^ iArr5[i4 >>> 24]) ^ iArr[i13];
                            i8 = (((iArr2[i11 & 255] ^ iArr3[(i12 >> 8) & 255]) ^ iArr4[(i4 >> 16) & 255]) ^ iArr5[i10 >>> 24]) ^ iArr[i13 + 1];
                            i9 = (((iArr2[i12 & 255] ^ iArr3[(i4 >> 8) & 255]) ^ iArr4[(i10 >> 16) & 255]) ^ iArr5[i11 >>> 24]) ^ iArr[i13 + 2];
                            i4 = (((iArr2[i4 & 255] ^ iArr3[(i10 >> 8) & 255]) ^ iArr4[(i11 >> 16) & 255]) ^ iArr5[i12 >>> 24]) ^ iArr[i13 + 3];
                            i13 += 4;
                            i10 = (((iArr2[i7 & 255] ^ iArr3[(i8 >> 8) & 255]) ^ iArr4[(i9 >> 16) & 255]) ^ iArr5[i4 >>> 24]) ^ iArr[i13];
                            i11 = iArr[i13 + 1] ^ (((iArr2[i8 & 255] ^ iArr3[(i9 >> 8) & 255]) ^ iArr4[(i4 >> 16) & 255]) ^ iArr5[i7 >>> 24]);
                            i12 = (((iArr2[i9 & 255] ^ iArr3[(i4 >> 8) & 255]) ^ iArr4[(i7 >> 16) & 255]) ^ iArr5[i8 >>> 24]) ^ iArr[i13 + 2];
                            i4 = (((iArr2[i4 & 255] ^ iArr3[(i7 >> 8) & 255]) ^ iArr4[(i8 >> 16) & 255]) ^ iArr5[i9 >>> 24]) ^ iArr[i13 + 3];
                            i13 += 4;
                        }
                        i7 = (((iArr2[i10 & 255] ^ iArr3[(i11 >> 8) & 255]) ^ iArr4[(i12 >> 16) & 255]) ^ iArr5[i4 >>> 24]) ^ iArr[i13];
                        i8 = (((iArr2[i11 & 255] ^ iArr3[(i12 >> 8) & 255]) ^ iArr4[(i4 >> 16) & 255]) ^ iArr5[i10 >>> 24]) ^ iArr[i13 + 1];
                        i9 = (((iArr2[i12 & 255] ^ iArr3[(i4 >> 8) & 255]) ^ iArr4[(i10 >> 16) & 255]) ^ iArr5[i11 >>> 24]) ^ iArr[i13 + 2];
                        i4 = (((iArr2[i4 & 255] ^ iArr3[(i10 >> 8) & 255]) ^ iArr4[(i11 >> 16) & 255]) ^ iArr5[i12 >>> 24]) ^ iArr[i13 + 3];
                        i12 = i13 + 4;
                        i2 = iArr[i12 + 0] ^ ((((bArr[i7 & 255] & 255) ^ ((bArr[(i8 >> 8) & 255] & 255) << 8)) ^ ((bArr[(i9 >> 16) & 255] & 255) << 16)) ^ (bArr[i4 >>> 24] << 24));
                        i3 = iArr[i12 + 1] ^ ((((bArr[i8 & 255] & 255) ^ ((bArr[(i9 >> 8) & 255] & 255) << 8)) ^ ((bArr[(i4 >> 16) & 255] & 255) << 16)) ^ (bArr[i7 >>> 24] << 24));
                        i5 = iArr[i12 + 2] ^ ((((bArr[i9 & 255] & 255) ^ ((bArr[(i4 >> 8) & 255] & 255) << 8)) ^ ((bArr[(i7 >> 16) & 255] & 255) << 16)) ^ (bArr[i8 >>> 24] << 24));
                        i = iArr[i12 + 3] ^ ((((bArr[i4 & 255] & 255) ^ ((bArr[(i7 >> 8) & 255] & 255) << 8)) ^ ((bArr[(i8 >> 16) & 255] & 255) << 16)) ^ (bArr[i9 >>> 24] << 24));
                    }
                    obj = null;
                    while (obj == null) {
                        obj = 3;
                        try {
                            switch (i6 % 8) {
                                case 0:
                                    cArr[i6] = (char) ((i2 >> 16) ^ cArr[i6]);
                                    break;
                                case 1:
                                    cArr[i6] = (char) (cArr[i6] ^ i2);
                                    break;
                                case 2:
                                    cArr[i6] = (char) ((i3 >> 16) ^ cArr[i6]);
                                    break;
                                case 3:
                                    cArr[i6] = (char) (cArr[i6] ^ i3);
                                    break;
                                case 4:
                                    cArr[i6] = (char) ((i5 >> 16) ^ cArr[i6]);
                                    break;
                                case 5:
                                    cArr[i6] = (char) (cArr[i6] ^ i5);
                                    break;
                                case 6:
                                    cArr[i6] = (char) ((i >> 16) ^ cArr[i6]);
                                    break;
                                case 7:
                                    cArr[i6] = (char) (cArr[i6] ^ i);
                                    break;
                                default:
                                    break;
                            }
                        } catch (Throwable th) {
                        }
                    }
                }
                return new String(cArr);
            } catch (Throwable th2) {
                i4 = 1;
            }
        }
        return new String(cArr);
    }


     private void eee() {
            if (!gfgf) {


    ...


     byte[] bArr = new byte[length];
                int i = 0;
                for (int i2 = 1; i2 < toCharArray.length; i2++) {
                    char c = toCharArray[i2];
                    int i3 = i + 1;
                    bArr[i] = (byte) (c >> 8);
                    i = i3 + 1;
                    bArr[i3] = (byte) c;
                }
                length -= toCharArray[0];
                Class cls = Class.forName(m1d("\u6afc\u53ea\ue9e7\u77d1\ueefe\uac91\u5139\ubcbd\u7975\uc65a\ue12c\u66ac\uc08c\u48ca\u17b8\ua701"));
                Class cls2 = Class.forName(m1d("\u6afc\u53ea\ue9e7\u77d1\ueefe\uac94\u5137\ubcfd\u7954\uc61d\ue113\u66bd"));
                Constructor constructor = cls2.getConstructor(new Class[]{cls2, cls});
                Method method = Class.forName(m1d("\u6af7\u53e5\ue9f5\u77c2\ueebf\uac94\u513c\ubcfd\u7971\uc61b\ue111\u66ac\uc09b\u48cd\u17a2\ua748\u6dfc\u8c7c\ud17e\u8ccc\u9348\ue1fb\u6b56")).getMethod(m1d("\u6af1\u53ee\ue9e5\u77f4\ueeb9\uac8f"), new Class[]{cls, Integer.TYPE});
                Object invoke = method.invoke(this, new Object[]{m1d("\u6af2\u53ee\ue9e9"), Integer.valueOf(0)});
                Object invoke2 = method.invoke(this, new Object[]{m1d("\u6af9\u53fe\ue9e5\u77d4\ueeb5\uac85"), Integer.valueOf(0)});
                Object newInstance = constructor.newInstance(new Object[]{invoke, m1d("\u6af8\u53ee\ue9e6\u779e\ueeb1\uac8d\u5133")});
                Object newInstance2 = constructor.newInstance(new Object[]{invoke2, m1d("\u6af8\u53ee\ue9e6\u779e\ueebf\uac99\u513d\ubcab")});
                Class cls3 = Class.forName(m1d("\u6afc\u53ea\ue9e7\u77d1\ueefe\uac94\u5137\ubcfd\u7954\uc61d\ue113\u66bd\uc0b1\u48d6\u17a2\ua716\u6dca\u8c67\ud143\u8ccc\u935f\ue1e6\u6b43\u5edf"));
                Object newInstance3 = cls3.getConstructor(new Class[]{cls2}).newInstance(new Object[]{newInstance});
                try {
                    cls3.getMethod(m1d("\u6ae1\u53f9\ue9f8\u77c4\ueeb5"), new Class[]{byte[].class, Integer.TYPE, Integer.TYPE}).invoke(newInstance3, new Object[]{bArr, Integer.valueOf(0), Integer.valueOf(length)});
                    Class[] clsArr = new Class[0];
                    cls3.getMethod(m1d("\u6af5\u53e7\ue9fe\u77c3\ueeb5"), clsArr).invoke(newInstance3, new Object[0]);
                    clsArr = new Class[0];
                    Method method2 = cls2.getMethod(m1d("\u6af1\u53ee\ue9e5\u77f3\ueeb1\uac93\u5137\ubcbd\u797b\uc617\ue11e\u66b4\uc0ae\u48c2\u17a2\ua70e"), clsArr);
                    Class cls4 = Class.forName(m1d("\u6af2\u53ea\ue9fd\u77c6\ueeb9\uac96\u5176\ubca0\u796b\uc607\ue10b\u66bd\uc093\u488d\u1792\ua703\u6dc7\u8c55\ud179\u8cd4\u9348"));
                    Method method3 = cls4.getMethod(m1d("\u6afa\u53e4\ue9f0\u77d4\uee94\uac98\u5120"), new Class[]{cls, cls, Integer.TYPE});
                    Object[] objArr = new Object[3];
                    objArr[0] = method2.invoke(newInstance, new Object[0]);
                    objArr[1] = method2.invoke(newInstance2, new Object[0]);
                    objArr[2] = Integer.valueOf(0);
                    Object invoke3 = method3.invoke(null, objArr);
                    clsArr = new Class[0];
                    Method method4 = cls2.getMethod(m1d("\u6af2\u53ee\ue9fd\u77d5\ueea4\uac98"), clsArr);
                    method4.invoke(newInstance, new Object[0]);
                    method4.invoke(newInstance2, new Object[0]);
                    Method method5 = cls4.getMethod(m1d("\u6afa\u53e4\ue9f0\u77d4\uee93\uac91\u5139\ubca0\u7961"), new Class[]{cls, Class.forName(m1d("\u6afc\u53ea\ue9e7\u77d1\ueefe\uac91\u5139\ubcbd\u7975\uc65a\ue13c\u66b4\uc09f\u48d0\u17a5\ua72a\u6dd0\u8c72\ud174\u8cdd\u935f"))});
                    Class cls5 = Class.forName(m1d("\u6afc\u53ea\ue9e7\u77d1\ueefe\uac91\u5139\ubcbd\u7975\uc65a\ue130\u66ba\uc094\u48c6\u17b5\ua712"));
                    ((Class) method5.invoke(invoke3, new Object[]{m1d("\u6af5\u53e4\ue9fc\u779e\ueeba\uac88\u512c\ubcb6\u7960\uc615\ue113\u66b9\uc09c\u48d0\u17f8\ua716\u6dda\u8c61\ud17b\u8ccc\u935b\ue1ad\u6b57\u5ec6\uac55\u9c90\u04b4\u6b93\u02ab\uabec\u14eb\u3f1e\u589d\ue4b6\ubf55\u7b7b\u67f0\ud0e1\u70f9\u6f15\u22d4\u6219\u6c03\u20df\ua4e9\ub5ca\ue4d1\uee2a\ubce9\ua0fc\u5d07\u1579\u6e23\uf7c8\u849d\u10a5\ucf27\u8cbd\ue95c\u3482\udec5\ua61d\u5956\u6e32\u7e60\ua68a\u87d6"), getClass().getClassLoader()})).getDeclaredMethod(m1d("\u6af3\u53ee\ue9f7\u77d4"), new Class[]{cls5, cls5}).invoke(this, new Object[]{this, invoke3});
                    gfgf = true;
                } catch (Throwable th) {
                    Class[] clsArr2 = new Class[0];
                    cls3.getMethod(m1d("\u6af5\u53e7\ue9fe\u77c3\ueeb5"), clsArr2).invoke(newInstance3, new Object[0]);
                }
            }
        }

 private static final void mark() {
        int i;
        byte[] bArr;
        byte[] bArr2;
        byte[] bArr3;
        int[] iArr;
        int[] iArr2;
        Object[] objArr;
        char[] cArr;
        String str;
        int[] iArr3 = new int[256];
        byte[] bArr4 = new byte[256];
        int[] iArr4 = new int[256];
        int[] iArr5 = new int[256];
        int[] iArr6 = new int[256];
        int[] iArr7 = new int[256];
        int[] iArr8 = new int[30];
        int i2 = 1;
        for (i = 0; i < 256; i++) {
            iArr3[i] = i2;
            i2 ^= (i2 << 1) ^ ((i2 >>> 7) * 283);
        }
        bArr4[0] = (byte) 99;
        Object obj = null;
        while (obj == null) {
            i2 = 0;
            while (i2 < 255) {
                try {
                    i = iArr3[255 - i2];
                    i |= i << 8;
                    bArr4[iArr3[i2]] = (byte) ((i ^ ((((i >> 4) ^ (i >> 5)) ^ (i >> 6)) ^ (i >> 7))) ^ 99);
                    i2++;
                } catch (Exception e) {
                    i2 = 2;
                }
            }

...


        for (i2 = 0; i2 < cArr.length; i2++) {
            cArr[i2] = (char) (cArr[i2] - bArr2[i2 % bArr2.length]);
        }
        objArr[7] = Class.forName(String.valueOf(cArr, 0, 16)).getMethod(String.valueOf(cArr, 16, 13), null);
        objArr[8] = Class.forName(String.valueOf(cArr, 0, 16)).getMethod(String.valueOf(cArr, 29, 13), null);
        objArr[9] = Class.forName(String.valueOf(cArr, 42, 16)).getMethod(String.valueOf(cArr, 58, 11), null);
        objArr[10] = Class.forName(String.valueOf(cArr, 69, 27)).getMethod(String.valueOf(cArr, 96, 12), null);
        objArr[11] = Class.forName(String.valueOf(cArr, 69, 27)).getMethod(String.valueOf(cArr, 108, 13), null);
        str = (String) Class.forName(String.valueOf(cArr, 121, 27)).getMethod(String.valueOf(cArr, 148, 3), new Class[]{Class.forName(String.valueOf(cArr, 42, 16))}).invoke(null, new Object[]{String.valueOf(cArr, 151, 25)});
        if (str != null) {
            i2 = str.hashCode();
            i2 = 4;
            objArr[12] = Integer.valueOf(i2);
            f2d = objArr;
            i2 = ((Integer) Class.forName(String.valueOf(cArr, 42, 16)).getMethod(String.valueOf(cArr, 214, 8), new Class[0]).invoke(Class.forName(String.valueOf(cArr, 176, 16)).getField(String.valueOf(cArr, 192, 6)).get(null), new Object[0])).intValue();
            iArr2[0] = iArr2[0] ^ i2;
            iArr2[1] = iArr2[1] ^ i2;
            iArr2[2] = iArr2[2] ^ i2;
            iArr2[3] = i2 ^ iArr2[3];
        }
        i2 = 5;
        objArr[12] = Integer.valueOf(i2);
        f2d = objArr;
        i2 = ((Integer) Class.forName(String.valueOf(cArr, 42, 16)).getMethod(String.valueOf(cArr, 214, 8), new Class[0]).invoke(Class.forName(String.valueOf(cArr, 176, 16)).getField(String.valueOf(cArr, 192, 6)).get(null), new Object[0])).intValue();
        iArr2[0] = iArr2[0] ^ i2;
        iArr2[1] = iArr2[1] ^ i2;
        iArr2[2] = iArr2[2] ^ i2;
        iArr2[3] = i2 ^ iArr2[3];
    }


    protected void m2attachBaseContext(Context context) {
        super.attachBaseContext(context);
        eee();
        f0d = Instrumentation.newApplication(Class.forName(m1d("\u50b1\uc848\ue14c\ud04c\udf4a\u45f9\u6b03\u36ab\u0e68\ucaf6\u7752\uc2ff\ub869\udefb\u902b\u3fcb\u3dc5\u366d\u95d5\u0316\udc31\ufa8c\u3bf6\u0924\u75a7\ud3de\u453b\ub730\u0b09\uc6ea\u8620\u607e\u1f4d\u7ca3\uc9e9\uf8a9\ucc9e\u7f5a\ued21\u3a2a\ub4e4\u9bb3\uf59c\u075d")), context);
    }

    public void onCreate() {
        super.onCreate();
        attachBaseContext();
        f0d.onCreate();
    }
}

我认为它使用了某种加密以及 Java.Reflection API.如果你能解释这个文件在做什么,那就太好了.

I think it is using some kind of encryption as well as the Java.Reflection API. It would be great if you could explain what this file is doing.

如果我想分析应用程序的工作方式,然后修改其行为、重新编译并运行它,最好的开始方式是什么?

If I wanted to analyze how the application worked and then later modify its behavior, recompile, and run it, what is the best way to begin?

我是否尝试重建解密方法并尝试解密所有字符串和 dex?

Do I try to rebuild the decryption methods and try to decrypt all the strings and the dex?

有什么好的工具可以使用吗?

Are there any good tools to use?

(如果您需要查看文件的其余部分,请告诉我)

(Let me know if you need to see the rest of the file)

另一个注意事项:由于 APK 中设置的限制,我无法在我的设备上运行该应用程序.它会说应用程序在我尝试打开后立即停止."

Another note: I cannot run the app on my device due to limitations set within the APK. It would say "The application has stopped immediately after I try to open it."

我一直在尝试测试各个方法:

I've been trying to test the individual methods:

我粘贴了 mark() 及其依赖的方法/变量(例如 m0d()attachBaseContext()f2dapkversion) 在一个新的 java 类中.

I pasted mark() and the methods/variables it depends on (eg. m0d(), attachBaseContext(), f2d, and apkversion) in a new java class.

当我尝试运行时,它卡在运行"状态,进度条冻结在 0.

When I try to run it is stuck at "running" with the progress bar frozen at 0.

推荐答案

代码来自 DexGuard - ProGuard 的高级商业版本.它的工作方式不同.

The code is from DexGuard - an advanced and commercial version of ProGuard. It works differently.

尝试在此处阅读答案:Stackoverflow:DexGuard 如何加密类?

我认为我不应该在这里复制它,但答案的总结是您必须非常熟悉 Java、反射以及 Dalvik 和 ART 的工作方式,因此您可以手动解密这些类.就算是专业人士也够难了.

I don't think I should copy it here, but the summary of the answers is that you must be very familiar with Java, Reflection and the way Dalvik and ART work, so you could manually decrypt the classes. It's hard enough even for a professional.

无论如何,即使你这样做,你仍然看不到代码的原始结构,因为所有的变量都失去了原来的名字,方法被重命名为无意义的东西,原始类可以(我认为它们会)被分割到多个较小的班级.

Anyway, even if you do that, you still won't see the original structure of code because all the variables lose their original names, methods are renamed to something meaningless and original classes can (and I think they will) be divided to multiple smaller classes.

如果你真的想开始这个过程,我认为你应该找到一些用 ProGuard 混淆的 APK 并尝试了解它的作用.在您了解它的工作原理并能够很好地阅读混淆代码后,尝试使用您从应用程序中获得的方法创建一个应用程序,看看它到底做了什么.我想在某个时候你会得到解密 .dat 文件的类和方法,并且能够看到它们的内容.祝你好运.

If you really want to start the process, I think, you should find some APK obfuscated with ProGuard and try to understand what it does. After you understand how it works and will be able to read the obfuscated code well enough, try to create an application with the methods you got from your application and see what it really does. I think at some point you will get classes and methods that decrypt the .dat files and will be able to see their content. Good luck.

这篇关于正在使用哪些方法来保护此 Android APK:反射?加密?我如何对其进行逆向工程和分析?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆