Трансформация классов после ProGuard (BuildHook API)

This commit is contained in:
Gravit 2018-09-23 18:25:02 +07:00
parent de69eb45a4
commit 5d2def1414
2 changed files with 55 additions and 4 deletions

View file

@ -5,10 +5,7 @@
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.HashMap;
import java.util.Map;
@ -24,6 +21,7 @@
import ru.gravit.launcher.Launcher;
import ru.gravit.launcher.LauncherAPI;
import ru.gravit.launcher.LauncherConfig;
import ru.gravit.launchserver.manangers.BuildHookManager;
import ru.gravit.utils.helper.IOHelper;
import ru.gravit.utils.helper.LogHelper;
import ru.gravit.utils.helper.SecurityHelper;
@ -110,6 +108,38 @@ public void build() throws IOException {
} catch (ParseException e1) {
e1.printStackTrace();
}
if(server.buildHookManager.isNeedPostProguardHook())
{
Path obfPath = Paths.get(server.config.binaryName + "-obf.jar");
Path tmpPath = Paths.get(server.config.binaryName + "-tmp.jar");
IOHelper.move(obfPath,tmpPath);
try (ZipOutputStream output = new ZipOutputStream(IOHelper.newOutput(obfPath)))
{
try (ZipInputStream input = new ZipInputStream(
IOHelper.newInput(tmpPath))) {
ZipEntry e = input.getNextEntry();
while (e != null) {
String filename = e.getName();
output.putNextEntry(e);
if (filename.endsWith(".class")) {
CharSequence classname = filename.replace('/', '.').subSequence(0,
filename.length() - ".class".length());
byte[] bytes;
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream(2048)) {
IOHelper.transfer(input, outputStream);
bytes = outputStream.toByteArray();
}
bytes = server.buildHookManager.proGuardClassTransform(bytes, classname);
try (ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes)) {
IOHelper.transfer(inputStream, output);
}
} else
IOHelper.transfer(input, output);
e = input.getNextEntry();
}
}
}
}
if (server.config.sign.enabled)
signBuild();
}
@ -123,6 +153,7 @@ private void signBuild() throws IOException {
while (e != null) {
output.addFileContents(e, input);
e = input.getNextEntry();
}
}
}

View file

@ -1,9 +1,11 @@
package ru.gravit.launchserver.manangers;
import java.io.InputStream;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.zip.ZipOutputStream;
import ru.gravit.launcher.AutogenConfig;
import ru.gravit.launcher.modules.TestClientModule;
@ -20,6 +22,10 @@ public interface PostBuildHook {
public interface PreBuildHook {
void build(BuildContext context);
}
@FunctionalInterface
public interface ProGuardTransformHook {
byte[] transform(byte[] input, CharSequence classname);
}
@FunctionalInterface
public interface Transformer {
@ -28,6 +34,7 @@ public interface Transformer {
private boolean BUILDRUNTIME;
private final Set<PostBuildHook> POST_HOOKS;
private final Set<ProGuardTransformHook> POST_PROGUARD_HOOKS;
private final Set<PreBuildHook> PRE_HOOKS;
private final Set<Transformer> CLASS_TRANSFORMER;
private final Set<String> CLASS_BLACKLIST;
@ -36,6 +43,7 @@ public interface Transformer {
public BuildHookManager() {
POST_HOOKS = new HashSet<>(4);
POST_PROGUARD_HOOKS = new HashSet<>(4);
PRE_HOOKS = new HashSet<>(4);
CLASS_BLACKLIST = new HashSet<>(4);
MODULE_CLASS = new HashSet<>(4);
@ -62,6 +70,11 @@ public byte[] classTransform(byte[] clazz, CharSequence classname) {
for (Transformer transformer : CLASS_TRANSFORMER) result = transformer.transform(result, classname);
return result;
}
public byte[] proGuardClassTransform(byte[] clazz, CharSequence classname) {
byte[] result = clazz;
for (Transformer transformer : CLASS_TRANSFORMER) result = transformer.transform(result, classname);
return result;
}
public void registerIncludeClass(String classname, byte[] classdata) {
INCLUDE_CLASS.put(classname, classdata);
@ -102,6 +115,13 @@ public void registerIgnoredClass(String clazz) {
public void registerPostHook(PostBuildHook hook) {
POST_HOOKS.add(hook);
}
public void registerProGuardHook(ProGuardTransformHook hook) {
POST_PROGUARD_HOOKS.add(hook);
}
public boolean isNeedPostProguardHook()
{
return !POST_PROGUARD_HOOKS.isEmpty();
}
public void registerPreHook(PreBuildHook hook) {
PRE_HOOKS.add(hook);