[英]Reverse Engineering - What's Kind of Algorithm In This Code?
有人可以帮我发现这是什么类型的算法吗?
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 索引作为参数,代码将返回一个字符串。 这就像在源代码上隐藏了某种纯字符串。
有人知道可能的反向代码吗? 将普通字符串转换成这个? 这是一种有名字的已知技术吗?
我不确定“具有名称的已知技术” - 也许像“反函数”或“双向化”这样的关键字可能会有所帮助,例如在纯函数式语言中,是否有一种算法来获得反函数?
对于这个特定的函数,幸运的是,只要f365xx
字符串常量遵守某些特定属性,就可以很容易地进行反转。 请注意, cArr
是一一填充的,并且每个字符彼此独立。 我们可以尝试使用字符串的字符和长度来尝试解码输入i
。 具体来说,
i10
候选者,这将为我们提供charAt
候选者。 重复所有的字符,希望每个字符只有一个候选者可以工作,如果字符串是“仁慈的”,那个候选者会给我们i7
/ i2
-> i2
/ i3
-> i
。charAt2
的候选者,与charAt
的候选者一起,将为我们提供i8
/ i6
候选者。 希望只有一个候选对i6
/ i8
-> i5
/ i6
-> -> i4
-> i
如果字符串常量是仁慈的。如果字符串仍然不是仁慈的,那么它是不可解的,因为函数不是一对一的。
我现在将概述 2 个要点的算法,但作为免责声明,我尚未对此进行测试,它只是伪代码。
假设您从第一个字符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
因为模数和按位和使更大的值变得不可能( x & 65535 == x % 65536
因为 65536 = 2^16)。
执行类似的过程以找到i10
的候选者并减去i9
以获得charAt
候选者。 如果您有多个候选项,请对cArr
中的每个字符重复此过程,并仅保留对cArr
中的每个字符都有效的charAt
候cArr
。 即使在对cArr
每个字符重复之后,您可能仍然有很多候选者。
对于charAt
每个候选者,使用charAt
表达式的右半部分:
charAt % 65536 = (str.charAt(i7) & 65535)
结合str = f3652c[i2]
尝试以与我们尝试找到charAt3
和i10
相同的方式找到i2
/ i7
。 请注意,表达式的左半部分((str.charAt(i7 + 1) & 65535) << 16)
无关紧要(目前)。 希望并祈祷这只会为您提供i2
/ i7
一种可能选择。 如果是这样,请使用它来查找i2
/ i3
-> i
。 如果有多个选项,那么我们必须尝试使用字符串的长度。
字符串的长度为我们提供了charAt2
,我们可以使用与之前类似的过程来查找i8
和str2
( i5
) 的所有候选对象。 请注意,在此过程中,我们必须尝试使用每个可能的charAt
候选者。 希望i8
/ i5
只剩下一对候选。 如果是这样,请使用它来查找i5
/ i6
-> i4
-> i
。 如果有超过 1 个候选,则该函数不是一对一的,并且不可能反转。
祝你好运!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.