逆向工程-这段代码中的算法是什么?

7dl7o3gd  于 2021-07-08  发布在  Java
关注(0)|答案(1)|浏览(259)

有人能帮我找出这是什么类型的算法吗?

public class hf1 {

    public static final String[] f3650a = {"0sFU@W>Ao*BT64?[L5aONSK.'"...};

    public static final String[] f3651b = {" \bB\u0017\u001e)YBN\u001eT/\u001e4V\u0001ZT/6VV"...};

    public static final String[] f3652c = {"\u0000\u0000\u0013\u00006\u0000\\\u0000\u0000¢\u0000¹\u0000¿\u0000"...};

    public static String m5192a(int i) {
        int i2 = i / 4096;
        int i3 = i % 4096;
        int i4 = i + 1;
        int i5 = i4 / 4096;
        int i6 = i4 % 4096;
        String[] strArr = f3652c;
        String str = strArr[i2];
        String str2 = strArr[i5];

        int i7 = i3 * 2;
        int charAt = ((str.charAt(i7 + 1) & 65535) << 16) | (str.charAt(i7) & 65535);
        int i8 = i6 * 2;
        int charAt2 = ((str2.charAt(i8 + 1) << 16) | str2.charAt(i8)) - charAt;
        char[] cArr = new char[charAt2];
        for (int i9 = 0; i9 < charAt2; i9++) {
            int i10 = charAt + i9;
            int charAt3 = f3651b[i10 / 8192].charAt(i10 % 8192) & 65535;
            cArr[i9] = f3650a[charAt3 / 8192].charAt(charAt3 % 8192);
        }
        return new String(cArr);
    }

}

如果调用m5192a(1)并将任何int索引作为参数传递,代码将返回一个字符串。就像在源代码中隐藏普通字符串一样。
有人知道可能的反码吗?把普通字符串转换成这个?这是一种已知的有名字的技术吗?

7rfyedvj

7rfyedvj1#

我不确定“已知的有名称的技术”——也许像“逆函数”或“双向化”这样的关键词可能会有所帮助,例如,在纯函数语言中,是否有一种算法来获得逆函数?
对于这个特定函数,幸运的是,只要 f365xx 字符串常量遵循某些属性。注意 cArr 一个接一个地填充,每个字符相互独立。我们可以尝试使用字符和字符串长度来解码输入 i . 明确地,
一个字符就可以让我们成为 i10 ,这将为我们提供 charAt . 重复所有的角色,希望只有一个候选人将工作的每一个字符,候选人将给我们 i7 / i2 -> i2 / i3 -> i 如果弦是“仁慈的”。
如果字符串不仁慈,那么字符串的长度将给我们的候选人 charAt2 再加上 charAt ,将为我们提供 i8 / i6 . 希望只有一对候选人 i6 / i8 -> i5 / i6 -> -> i4 -> i 如果字符串常量是仁慈的。
如果字符串仍然不仁慈,那么它是无法解决的,因为函数不是一对一的。
我现在将概述这两个要点的算法,但作为免责声明,我还没有测试过这一点,它只是伪代码。

从一个角色

假设你从第一个角色开始, cArr[0] . 如果我们关注for循环中的3行,

int i10 = charAt + i9;
int charAt3 = f3651b[i10 / 8192].charAt(i10 % 8192) & 65535;
cArr[i9] = f3650a[charAt3 / 8192].charAt(charAt3 % 8192);

然后我们就可以 charAt3 找到了哪里 cArr[0] 出现在 f3650a . 例如,

charAt3candidates = []
for i = 0 to length(f3650a)-1:
  indexCandidates = f3650[i].indexOf(cArr[0])
  for indexCandidate in indexCandidates:
    charAt3candidate = i * 8192 + indexCandidate
    if indexCandidate >= 8192 or charAt3candidate >= 65536:
      continue
    charAt3candidates.append(charAt3candidate)

注意我们过滤掉了 indexCandidate >= 8192 以及 charAt3candidate >= 65536 由于模和位and使得更大的值变得不可能( x & 65535 == x % 65536 因为65536=2^16)。
做一个类似的过程来寻找候选人 i10 和减法 i9 让候选人 charAt . 如果您有多个候选角色,请对中的每个角色重复此过程 cArr 只保留 charAt 对中的每个字符都有效 cArr . 即使在每一个字符重复 cArr ,你可能还有很多候选人。
每一位候选人 charAt ,使用表达式的右半部分 charAt : charAt % 65536 = (str.charAt(i7) & 65535) 结合 str = f3652c[i2] 试图找到 i2 / i7 和我们想找的一样 charAt3 以及 i10 . 注意表达式的左半部分, ((str.charAt(i7 + 1) & 65535) << 16) ,无所谓(目前)。希望并祈祷这只给你一个可能的选择 i2 / i7 . 如果是,用它来找到 i2 / i3 -> i . 如果有多个选项,那么我们必须尝试使用字符串的长度。

从绳子的长度

绳子的长度给了我们 charAt2 ,我们可以使用与以前类似的过程来查找 i8 以及 str2 ( i5 ). 注意:在这个过程中,我们必须尝试每一个可能的候选人 charAt . 希望只有一对候选 i8 / i5 剩下的。如果是,用它来找到 i5 / i6 -> i4 -> i . 如果有多个候选函数,那么函数不是一对一的,不可能反转。
祝你好运!

相关问题