0

Someone can help me to discover what type of algorithm is this?

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);
    }

}

If i call m5192a(1) passing any int index as parameter, the code returns a String. It's like some kind of hiding plain strings on the source code.

Someone have any idea of a possible reverse code? To transform plain string in to this? Is this a known technique with a name?

ruakh
  • 175,680
  • 26
  • 273
  • 307
  • 1
    A `hash function` typically converts a string to a number. That's the opposite from what you have, but maybe it can help you somehow... – peer Nov 27 '20 at 21:14
  • This looks like an algorithm to deterministically produce strings that look random from an int key. One reason you might ask this question about obviously decompiled code is trying to compute future keys of a service from a current one (where you have only the compiled Java) so that you can so something nefarious. You need to prove non-malicious intent. I.e. that you aren't trying to crowd source a hack. – Gene Nov 28 '20 at 04:10
  • I’m voting to close this question because it seems likely to be crowd sourcing a nefarious activity of some kind. – Gene Nov 28 '20 at 04:12

1 Answers1

0

I'm not sure about a "known technique with a name" - perhaps keywords like "inverse function" or "bidirectionalization" might help, e.g. In pure functional languages, is there an algorithm to get the inverse function?

For this particular function, luckily it seems pretty straightforward to invert as long as the f365xx string constants abide by some certain properties. Notice that cArr is filled one-by-one and each character is independent of each other. We can try to use both the characters and the length of the string to try to decode the input i. Specifically,

  • A single character will give us candidates for i10, which will give us candidates for charAt. Repeating over all the characters, hopefully only one candidate will work for every character, and that candidate will give us i7/i2 -> i2/i3 -> i if the strings are "benevolent".
  • If the strings are not benevolent, then the length of the string will give us candidates for charAt2 which, together with the candidates for charAt, will give us candidates for i8/i6. Hopefully there is only one candidate pair i6/i8 -> i5/i6 -> -> i4 -> i if the string constants are benevolent.

If the strings are still not benevolent, then it is unsolvable since the function is not one-to-one.

I'll outline the algorithm for the 2 bullet points now, but as a disclaimer, I haven't tested this and it's just pseudocode.

From a character

Let's say you start with the first character, cArr[0]. If we focus on the 3 lines inside the for loop,

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

Then we can get charAt3 by finding where cArr[0] appears in f3650a. For example,

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)

Note that we filter out indexCandidate >= 8192 and charAt3candidate >= 65536 due to modulo's and bitwise and's that make greater values impossible (x & 65535 == x % 65536 since 65536 = 2^16).

Do a similar process to find the candidates for i10 and subtract i9 to get candidates for charAt. If you have more than one candidate, repeat this process for every character in cArr and keep only the candidates of charAt which are valid for every character in cArr. Even after repeating for every character in cArr, you may still have many candidates.

For each candidate of charAt, use the right-half of the expression for charAt:

charAt % 65536 = (str.charAt(i7) & 65535)

combined with str = f3652c[i2] to try to find i2/i7 the same way we tried to find charAt3 and i10. Note that the left half of the expression, ((str.charAt(i7 + 1) & 65535) << 16), doesn't matter (for now). Hope and pray that this only gives you one possible choice of i2/i7. If so, use it to find i2/i3 -> i. If there's more than one option, then we have to try using the length of the string.

From the length of the string

The length of the string gives us charAt2, and we can use a similar process as before to find all the candidates for i8 and str2 (i5). Note in this process we have to try with every possible candidate for charAt. Hopefully there is only one candidate pair for i8/i5 remaining. If so, use it to find i5/i6 -> i4 -> i. If there are more than 1 candidate, then the function is not one-to-one and it's impossible to invert.

Good luck!

gchen
  • 126
  • 6
  • 1
    I'm not sure, but I think you've misinterpreted the question; when the OP writes "a possible reverse code? To transform plain string in to this?", you've taken that to mean "a method that's the inverse of m5192a, taking a string and converting it to an integer", but I *think* the OP means something more like "a method that takes a string that generates this obfuscated code". (But I could be wrong.) – ruakh Nov 27 '20 at 23:48
  • Oh indeed, I did misunderstand, thanks for pointing this out. To clarify, perhaps an example application would be: OP has a secret message that he wants to share with his friend - he shares the code publically, but tells only his friend the int `i` which will generate the secret message. I believe you added the keyword "obfuscation" to the question, which was very helpful. @PedroGaldino OP, could you clarify if this is the correct interpretation? – gchen Nov 29 '20 at 05:13
  • Perhaps just general cryptography methods such as public-private key (ie RSA) or symmetric (i.e. AES) would work for this. You can include the encrypted message and public key (if applicable) as a string constants, and then the code would simply be the decrypting function, where the input `i` is the private key. – gchen Nov 29 '20 at 05:14