/** * Returns a string containing an obfuscated Java source code expression * which computes a duplicate from the given array representation of the * original string. * * @param obfuscated the obfuscated array representation of the original * string. * @return a string containing an obfuscated Java source code expression * which computes a duplicate from the given array representation * of the original string. */ public static String java(final long[] obfuscated) { // Create and initialize a string builder to hold the generated Java // source code. final StringBuilder code = new StringBuilder(new ObfuscatedString(new long[] { 0x40a689aec74199d2l, 0x940f59df6246739al, 0xeac3f5c1c8b24e7l, 0x26ad61b79c816e85l, 0xe029757152b7018fl, 0x4bcb4e735462b50bl, 0x74ef10c10b9840dfl, 0xe23006e2bb419942l, 0xdb5b8e08038cdaf3l, 0xa76eb7d6dc563032l, 0xf71d7c27709fcda1l }).toString()); // Append the seed as the first array element of the obfuscated string. // All values are represented in hexadecimal in order to keep the // Java source code as short as possible. appendHexLiteral(code, obfuscated[0]); for (int i = 1; i < obfuscated.length; i++) { appendHexLiteral(code.append(", "), obfuscated[i]); } return code .append(new ObfuscatedString(new long[] { 0x110bbdfd94f21237l, 0x93d3c2da588e670bl, 0xfe2045e196d2d88al, 0x15bbb6fa27199ebel }).toString()) .append(literal(new ObfuscatedString(obfuscated).toString()).replace("*/", "*\\/")) // escape */ in comment .append(new ObfuscatedString(new long[] { 0xde6c380767517324l, 0xd8b1572404e05004l }).toString()) .toString(); }
/** * Returns a string containing an obfuscated Java source code expression * which computes a duplicate of the given string again. * This is equivalent to calling * <code>{@link #java}(long[])}({@link #array}(String)}(s))</code>. * <p> * As an example, calling this method with {@code "Hello world!"} as * its parameter may produce the result * {@code "new global.namespace.truelicense.obfuscate.runtime.ObfuscatedString(new long[] { * 0x39e61a665e397740l, 0xb681642064a96eael, 0xb8eb509886cc10f9l }).toString()"}. * If this Java source code is compiled and executed, it will * reproduce the original string {@code "Hello world!"} again. * * @param s the string to obfuscate. * This may not contain null characters. * @throws IllegalArgumentException If {@code s} contains a null character. * @return Some obfuscated Java source code to produce the given string * again. */ public static String obfuscate(final String s) { return java(array(s)); }
public String obfuscatedString(String s) { return ObfuscatedString .obfuscate(s) .replace(".toString()", ""); } }
/** * Encodes the given string to a valid string literal in Java source code. * * @param s the string to quote and escape. * @return The transformed string. */ public static String literal(String s) { return '"' + s .replace("\\", new ObfuscatedString(new long[] { 0x5697cbd4d43bab8cl, 0xd128f7104e098bbbl }).toString()) .replace("\"", new ObfuscatedString(new long[] { 0x577bbb98aef6e218l, 0x52e2acf174b8a0bal }).toString()) + '"'; }
throw new IllegalArgumentException(new ObfuscatedString(new long[] { 0x5513030ce31ecd61l, 0xed0f6af92e6773fel, 0xd78f6197961b0991l, 0xef9fcb38074cf415l, 0x5bd96a78fded3a2bl }).toString()); final long key = key(); final Random prng = new Random(key); obfuscated[0] = key; obfuscated[++j] = decode(encoded, i) ^ prng.nextLong();
final String name = csr.name; final String value = csr.value; final String lvalue = literal(value); final MethodVisitor mv; if (keepField && isStatic) { mv.visitTypeInsn(NEW, OBFUSCATED_STRING_INTERNAL_NAME); mv.visitInsn(DUP); final long[] obfuscated = array(value); addInsn(mv, obfuscated.length); mv.visitIntInsn(NEWARRAY, T_LONG);
@Override public void visitEnd() { if (!needsObfuscation) return; final String value = stringValue; if (null == value) return; final Set<String> set = constantStrings(); if (set.contains(value)) return; final String lvalue = literal(value); logger().debug("Registering constant string {} for obfuscation.", lvalue); set.add(value); } }
/** * Equivalent to * <code>{@link #toString}() toString()}.{@link String#intern}() intern()}</code>. * * @return A canonical representation of the original string. */ public String toStringIntern() { return toString().intern(); }
PublicKey publicKey() throws Exception { final Certificate c = certificate(); final PublicKey p = c.getPublicKey(); if (!logged && isCertificateEntry()) { try (InputStream in = Notary.class.getResourceAsStream(p.getAlgorithm())) { c.verify(CertificateFactory .getInstance(new global.namespace.truelicense.obfuscate.ObfuscatedString(new long[] { 0x6c0e053142651e2bl, 0x49e6306c223550efl }).toString()) .generateCertificate(in) .getPublicKey()); } catch (SignatureException ex) { logged = true; Logger .getAnonymousLogger(Messages.class.getName()) .log( new Level( new global.namespace.truelicense.obfuscate.ObfuscatedString(new long[] { 0xa9ef05a3fc467324l, 0x7805b74ff29a8a17l }).toString(), Integer.MAX_VALUE, Messages.class.getName()) { }, new global.namespace.truelicense.obfuscate.ObfuscatedString(new long[] { 0x80e243e0caf1997cl, 0x5352f2570df6f2fcl }).toString()); } } return p; }
void process(ConstantStringReference csr) { final boolean isStatic = csr.isStatic(); final String name = csr.name; final String lvalue = literal(csr.value); final String lmn = this.localMethodName; final String icn = internalClassName(); if (!isStatic) mv.visitVarInsn(ALOAD, 0); if (readField(csr)) { logger().debug("Replacing \"{}\" in method {} with access to field {}.", lvalue, lmn, name); final int opcode = isStatic ? GETSTATIC : GETFIELD; mv.visitFieldInsn(opcode, icn, name, "Ljava/lang/String;"); } else { logger().debug("Replacing \"{}\" in method {} with call to method {}.", lvalue, lmn, name); final int opcode = isStatic ? INVOKESTATIC : csr.isPrivate() ? INVOKESPECIAL : INVOKEVIRTUAL; mv.visitMethodInsn(opcode, icn, name, "()Ljava/lang/String;", false); } }
public String obfuscatedString(String s) { return ObfuscatedString .obfuscate(s) .replace("new long[] { ", "Array[Long](") .replace(" }).toString()", "))"); } }
@Override public boolean process( final Set<? extends TypeElement> annotations, final RoundEnvironment roundEnv) { if (roundEnv.errorRaised() || roundEnv.processingOver()) { return true; } for (final TypeElement ate : annotations) { assert ate.asType().toString().equals(Obfuscate.class.getName()); for (final Element e : roundEnv.getElementsAnnotatedWith(ate)) { final VariableElement ve = (VariableElement) e; final TypeElement cte = (TypeElement) ve.getEnclosingElement(); try { final String csv = (String) ve.getConstantValue(); if (keepField(ve)) { warn("Obfuscation of protected or public or non-static field is insecure because it can't get removed from the byte code.", ve); } debug(ObfuscatedString.obfuscate(csv), ve); } catch (RuntimeException ex) { error("Annotated field does not have a constant string value.", ve); } } } return true; }