Clean up code

This commit is contained in:
s809
2025-01-26 17:52:30 +05:00
parent 4a72e02550
commit 23a1f0b025
3 changed files with 153 additions and 119 deletions
@@ -1,52 +1,21 @@
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
class RelocateNatives
class NativeRelocator
{
private static boolean prepared = false;
private static final Path rootDirectory = Path.of(System.getProperty("user.dir"), "relocate_natives");
private static final Path cacheRoot = rootDirectory.resolve("cache");
@SuppressWarnings({"ResultOfMethodCallIgnored", "BusyWait"})
private static CompletableFuture<Void> readOutputStreams(Process process)
NativeRelocator() throws Exception
{
return CompletableFuture.runAsync(() -> {
try
{
while (process.isAlive() || process.getInputStream().available() > 0 || process.getErrorStream().available() > 0)
{
if (process.getInputStream().available() > 0)
{
byte[] data = new byte[process.getInputStream().available()];
process.getInputStream().read(data);
System.out.write(data);
}
if (process.getErrorStream().available() > 0)
{
byte[] data = new byte[process.getErrorStream().available()];
process.getErrorStream().read(data);
System.err.write(data);
}
Thread.sleep(100);
}
}
catch (Exception ignored)
{
}
});
}
private static void ensurePrepared() throws Exception
{
if (prepared)
if (rootDirectory.resolve(".venv").toFile().exists())
{
return;
}
prepared = true;
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.directory(rootDirectory.toFile());
@@ -77,39 +46,40 @@ class RelocateNatives
}
}
public static byte[] updateUsingLief(Path outputFilePath, byte[] content) throws Exception
private static CompletableFuture<Void> readOutputStreams(Process process)
{
ensurePrepared();
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.directory(rootDirectory.toFile());
processBuilder.command(
rootDirectory.resolve(".venv/Scripts").toFile().exists()
? rootDirectory.resolve(".venv/Scripts/python.exe").toString()
: rootDirectory.resolve(".venv/bin/python").toString(),
"./process.py",
outputFilePath.toString()
);
Process process = processBuilder.start();
CompletableFuture<Void> outputFuture = readOutputStreams(process);
process.getOutputStream().write(content);
process.getOutputStream().close();
int exitCode = process.waitFor();
outputFuture.get();
if (exitCode != 0)
{
throw new Exception("Process failed: " + exitCode);
}
return Files.readAllBytes(outputFilePath);
return CompletableFuture.runAsync(() -> {
try
{
while (process.isAlive() || process.getInputStream().available() > 0 || process.getErrorStream().available() > 0)
{
if (process.getInputStream().available() > 0)
{
byte[] data = new byte[process.getInputStream().available()];
//noinspection ResultOfMethodCallIgnored
process.getInputStream().read(data);
System.out.write(data);
}
if (process.getErrorStream().available() > 0)
{
byte[] data = new byte[process.getErrorStream().available()];
//noinspection ResultOfMethodCallIgnored
process.getErrorStream().read(data);
System.err.write(data);
}
//noinspection BusyWait
Thread.sleep(100);
}
}
catch (Throwable ignored)
{
}
});
}
private static void replaceInByteArray(byte[] byteArray, String target, String replacement)
private void replaceInNullTerminatedStrings(byte[] byteArray, String target, String replacement)
{
if (target.length() < replacement.length())
{
@@ -147,9 +117,40 @@ class RelocateNatives
}
}
public static byte[] processNative(String path, byte[] content) throws Exception
public byte[] fixModifiedBinary(Path outputFilePath, byte[] content) throws Exception
{
Path outputFilePath = cacheRoot.resolve(path);
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.directory(rootDirectory.toFile());
processBuilder.command(
rootDirectory.resolve(".venv/Scripts").toFile().exists()
? rootDirectory.resolve(".venv/Scripts/python.exe").toString()
: rootDirectory.resolve(".venv/bin/python").toString(),
"./fix_modified_binary.py",
outputFilePath.toString()
);
Process process = processBuilder.start();
CompletableFuture<Void> outputFuture = readOutputStreams(process);
process.getOutputStream().write(content);
process.getOutputStream().close();
int exitCode = process.waitFor();
outputFuture.get();
if (exitCode != 0)
{
throw new Exception("Process failed: " + exitCode);
}
return Files.readAllBytes(outputFilePath);
}
public byte[] processBinary(String outputPath, byte[] content, Map<String, String> replacements) throws Exception
{
Path outputFilePath = cacheRoot.resolve(outputPath);
//noinspection ResultOfMethodCallIgnored
outputFilePath.getParent().toFile().mkdirs();
if (outputFilePath.toFile().exists())
@@ -157,9 +158,12 @@ class RelocateNatives
return Files.readAllBytes(outputFilePath);
}
replaceInByteArray(content, "org_sqlite", "dh_1sqlite");
replaceInByteArray(content, "org/sqlite", "dh_sqlite");
return updateUsingLief(outputFilePath, content);
for (Map.Entry<String, String> replacement : replacements.entrySet())
{
this.replaceInNullTerminatedStrings(content, replacement.getKey(), replacement.getValue());
}
return this.fixModifiedBinary(outputFilePath, content);
}
}