Sign natives for mac
This commit is contained in:
+2
-1
@@ -26,7 +26,8 @@ Merged/
|
|||||||
# Folder created by the buildAll scripts
|
# Folder created by the buildAll scripts
|
||||||
buildAllJars/
|
buildAllJars/
|
||||||
|
|
||||||
.venv
|
relocate_natives/.venv/
|
||||||
|
relocate_natives/apple-codesign/
|
||||||
relocate_natives/cache/
|
relocate_natives/cache/
|
||||||
|
|
||||||
# file from notepad++
|
# file from notepad++
|
||||||
|
|||||||
+6
-1
@@ -343,7 +343,12 @@ subprojects { p ->
|
|||||||
String path = context.path.replace("org/sqlite", "dh_sqlite")
|
String path = context.path.replace("org/sqlite", "dh_sqlite")
|
||||||
byte[] content = context.is.readAllBytes()
|
byte[] content = context.is.readAllBytes()
|
||||||
|
|
||||||
content = RelocateNatives.processNative(path, content)
|
try {
|
||||||
|
content = RelocateNatives.processNative(path, content)
|
||||||
|
}
|
||||||
|
catch (Throwable e) {
|
||||||
|
throw new GradleException("Failed to relocate", e)
|
||||||
|
}
|
||||||
rewrittenFiles.put(path, content)
|
rewrittenFiles.put(path, content)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import java.io.File;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
@@ -6,63 +5,16 @@ import java.util.concurrent.CompletableFuture;
|
|||||||
|
|
||||||
class RelocateNatives
|
class RelocateNatives
|
||||||
{
|
{
|
||||||
static boolean prepared = false;
|
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");
|
||||||
|
|
||||||
private static void ensurePrepared() throws Exception
|
|
||||||
{
|
|
||||||
if (prepared)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
prepared = true;
|
|
||||||
|
|
||||||
ProcessBuilder processBuilder = new ProcessBuilder();
|
|
||||||
processBuilder.directory(new File(System.getProperty("user.dir")));
|
|
||||||
|
|
||||||
String os = System.getProperty("os.name").toLowerCase();
|
|
||||||
if (os.contains("win"))
|
|
||||||
{
|
|
||||||
processBuilder.command("powershell", "./relocate_natives/prepare.ps1");
|
|
||||||
}
|
|
||||||
else if (os.contains("nix") || os.contains("nux") || os.contains("mac"))
|
|
||||||
{
|
|
||||||
processBuilder.command("./relocate_natives/prepare.sh");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new IllegalStateException("Unsupported operating system: " + os);
|
|
||||||
}
|
|
||||||
|
|
||||||
Process process = processBuilder.start();
|
|
||||||
process.getInputStream().transferTo(System.out);
|
|
||||||
process.getErrorStream().transferTo(System.err);
|
|
||||||
|
|
||||||
int exitCode = process.waitFor();
|
|
||||||
if (exitCode != 0)
|
|
||||||
{
|
|
||||||
throw new Exception("Prepare failed: " + exitCode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings({"ResultOfMethodCallIgnored", "BusyWait"})
|
@SuppressWarnings({"ResultOfMethodCallIgnored", "BusyWait"})
|
||||||
public static byte[] updateUsingLief(Path outputFilePath, byte[] content) throws Exception
|
private static CompletableFuture<Void> readOutputStreams(Process process)
|
||||||
{
|
{
|
||||||
ensurePrepared();
|
return CompletableFuture.runAsync(() -> {
|
||||||
|
|
||||||
ProcessBuilder processBuilder = new ProcessBuilder();
|
|
||||||
processBuilder.directory(new File(System.getProperty("user.dir")));
|
|
||||||
|
|
||||||
if (Path.of(System.getProperty("user.dir"), ".venv/Scripts").toFile().exists())
|
|
||||||
{
|
|
||||||
processBuilder.command("./.venv/Scripts/python", "./relocate_natives/process.py", outputFilePath.toString());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
processBuilder.command("./.venv/bin/python", "./relocate_natives/process.py", outputFilePath.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
Process process = processBuilder.start();
|
|
||||||
CompletableFuture<Void> outputFuture = CompletableFuture.runAsync(() -> {
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
while (process.isAlive() || process.getInputStream().available() > 0 || process.getErrorStream().available() > 0)
|
while (process.isAlive() || process.getInputStream().available() > 0 || process.getErrorStream().available() > 0)
|
||||||
@@ -86,6 +38,62 @@ class RelocateNatives
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ensurePrepared() throws Exception
|
||||||
|
{
|
||||||
|
if (prepared)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
prepared = true;
|
||||||
|
|
||||||
|
ProcessBuilder processBuilder = new ProcessBuilder();
|
||||||
|
processBuilder.directory(rootDirectory.toFile());
|
||||||
|
|
||||||
|
String os = System.getProperty("os.name").toLowerCase();
|
||||||
|
if (os.contains("win"))
|
||||||
|
{
|
||||||
|
processBuilder.command("powershell", "./prepare.ps1");
|
||||||
|
}
|
||||||
|
else if (os.contains("nix") || os.contains("nux") || os.contains("mac"))
|
||||||
|
{
|
||||||
|
processBuilder.command("./prepare.sh");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new IllegalStateException("Unsupported operating system: " + os);
|
||||||
|
}
|
||||||
|
|
||||||
|
Process process = processBuilder.start();
|
||||||
|
CompletableFuture<Void> outputFuture = readOutputStreams(process);
|
||||||
|
|
||||||
|
int exitCode = process.waitFor();
|
||||||
|
outputFuture.get();
|
||||||
|
|
||||||
|
if (exitCode != 0)
|
||||||
|
{
|
||||||
|
throw new Exception("Prepare failed: " + exitCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] updateUsingLief(Path outputFilePath, byte[] content) throws Exception
|
||||||
|
{
|
||||||
|
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().write(content);
|
||||||
process.getOutputStream().close();
|
process.getOutputStream().close();
|
||||||
@@ -141,7 +149,6 @@ class RelocateNatives
|
|||||||
|
|
||||||
public static byte[] processNative(String path, byte[] content) throws Exception
|
public static byte[] processNative(String path, byte[] content) throws Exception
|
||||||
{
|
{
|
||||||
Path cacheRoot = Path.of(System.getProperty("user.dir"), "relocate_natives/cache/");
|
|
||||||
Path outputFilePath = cacheRoot.resolve(path);
|
Path outputFilePath = cacheRoot.resolve(path);
|
||||||
outputFilePath.getParent().toFile().mkdirs();
|
outputFilePath.getParent().toFile().mkdirs();
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,110 @@
|
|||||||
|
import os
|
||||||
|
import platform
|
||||||
|
import requests
|
||||||
|
import tarfile
|
||||||
|
import zipfile
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
def get_platform_specific_filename():
|
||||||
|
system = platform.system()
|
||||||
|
machine = platform.machine()
|
||||||
|
|
||||||
|
if system == "Darwin":
|
||||||
|
if machine == "arm64":
|
||||||
|
return "apple-codesign-*-aarch64-apple-darwin.tar.gz"
|
||||||
|
else:
|
||||||
|
return "apple-codesign-*-x86_64-apple-darwin.tar.gz"
|
||||||
|
elif system == "Linux":
|
||||||
|
if machine == "aarch64":
|
||||||
|
return "apple-codesign-*-aarch64-unknown-linux-musl.tar.gz"
|
||||||
|
else:
|
||||||
|
return "apple-codesign-*-x86_64-unknown-linux-musl.tar.gz"
|
||||||
|
elif system == "Windows":
|
||||||
|
if machine.endswith("64"):
|
||||||
|
return "apple-codesign-*-x86_64-pc-windows-msvc.zip"
|
||||||
|
else:
|
||||||
|
return "apple-codesign-*-i686-pc-windows-msvc.zip"
|
||||||
|
else:
|
||||||
|
raise Exception(f"Unsupported platform: {system} {machine}")
|
||||||
|
|
||||||
|
|
||||||
|
def download_and_unpack():
|
||||||
|
dest_dir = Path("./apple-codesign")
|
||||||
|
|
||||||
|
repo_url = "https://api.github.com/repos/indygreg/apple-platform-rs/releases/latest"
|
||||||
|
dest_dir.mkdir(exist_ok=True)
|
||||||
|
|
||||||
|
# Fetch the latest release info from GitHub
|
||||||
|
print("Fetching latest release information...")
|
||||||
|
response = requests.get(repo_url)
|
||||||
|
response.raise_for_status()
|
||||||
|
release_data = response.json()
|
||||||
|
|
||||||
|
# Ensure release data has assets
|
||||||
|
if "assets" not in release_data:
|
||||||
|
raise Exception("Release data does not contain assets.")
|
||||||
|
|
||||||
|
# Determine the correct asset
|
||||||
|
platform_filename = get_platform_specific_filename()
|
||||||
|
asset = next((asset for asset in release_data["assets"] if asset["name"].startswith("apple-codesign-") and asset["name"].endswith(platform_filename.split("*")[-1])), None)
|
||||||
|
|
||||||
|
if not asset:
|
||||||
|
raise Exception(f"No matching asset found for platform: {platform_filename}")
|
||||||
|
|
||||||
|
# Download the archive
|
||||||
|
print(f"Downloading {asset['name']}...")
|
||||||
|
download_url = asset["browser_download_url"]
|
||||||
|
archive_path = dest_dir / asset["name"]
|
||||||
|
|
||||||
|
with requests.get(download_url, stream=True) as r:
|
||||||
|
r.raise_for_status()
|
||||||
|
with open(archive_path, "wb") as f:
|
||||||
|
for chunk in r.iter_content(chunk_size=8192):
|
||||||
|
f.write(chunk)
|
||||||
|
|
||||||
|
print(f"Downloaded to {archive_path}")
|
||||||
|
|
||||||
|
# Extract the archive
|
||||||
|
print("Extracting archive...")
|
||||||
|
temp_extract_dir = dest_dir / "temp_extract"
|
||||||
|
temp_extract_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
if archive_path.suffix == ".zip":
|
||||||
|
with zipfile.ZipFile(archive_path, "r") as zip_ref:
|
||||||
|
zip_ref.extractall(temp_extract_dir)
|
||||||
|
elif archive_path.suffixes[-2:] == [".tar", ".gz"]:
|
||||||
|
with tarfile.open(archive_path, "r:gz") as tar_ref:
|
||||||
|
tar_ref.extractall(temp_extract_dir)
|
||||||
|
else:
|
||||||
|
raise Exception(f"Unknown archive format: {archive_path}")
|
||||||
|
|
||||||
|
# Move contents of the root directory inside the archive to dest_dir
|
||||||
|
root_dir = next(temp_extract_dir.iterdir()) # Assuming only one root directory
|
||||||
|
for item in root_dir.iterdir():
|
||||||
|
target_path = dest_dir / item.name
|
||||||
|
if target_path.exists():
|
||||||
|
if target_path.is_dir():
|
||||||
|
os.rmdir(target_path)
|
||||||
|
else:
|
||||||
|
os.remove(target_path)
|
||||||
|
item.rename(target_path)
|
||||||
|
|
||||||
|
# Clean up temporary directories
|
||||||
|
for item in temp_extract_dir.iterdir():
|
||||||
|
if item.is_dir():
|
||||||
|
os.rmdir(item)
|
||||||
|
temp_extract_dir.rmdir()
|
||||||
|
|
||||||
|
print(f"Extracted to {dest_dir}")
|
||||||
|
|
||||||
|
# Clean up the archive
|
||||||
|
os.remove(archive_path)
|
||||||
|
print(f"Removed archive {archive_path}")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
download_and_unpack()
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error: {e}")
|
||||||
@@ -2,4 +2,4 @@ $ErrorActionPreference = "Stop"
|
|||||||
|
|
||||||
python -m venv .venv
|
python -m venv .venv
|
||||||
.\.venv\Scripts\activate
|
.\.venv\Scripts\activate
|
||||||
pip install lief
|
pip install -r requirements.txt
|
||||||
|
|||||||
@@ -4,4 +4,4 @@ set -e
|
|||||||
|
|
||||||
python -m venv .venv
|
python -m venv .venv
|
||||||
. ./.venv/bin/activate
|
. ./.venv/bin/activate
|
||||||
pip install lief
|
pip install -r requirements.txt
|
||||||
|
|||||||
@@ -1,8 +1,26 @@
|
|||||||
import sys
|
import sys
|
||||||
import lief
|
import lief
|
||||||
|
import subprocess
|
||||||
|
import download_codesign
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
# print("imported", file=sys.stderr)
|
output_path = sys.argv[1]
|
||||||
|
|
||||||
binary = lief.parse(sys.stdin.buffer.read())
|
binary = lief.parse(sys.stdin.buffer.read())
|
||||||
# print([func.name for func in binary.exported_functions], file=sys.stderr)
|
|
||||||
binary.write(sys.argv[1])
|
if binary is None:
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
if isinstance(binary, lief.MachO.Binary):
|
||||||
|
binary.remove_signature()
|
||||||
|
|
||||||
|
binary.write(output_path)
|
||||||
|
|
||||||
|
if isinstance(binary, lief.MachO.Binary):
|
||||||
|
print(f"Signing {output_path}...")
|
||||||
|
|
||||||
|
if not Path("./apple-codesign/COPYING").exists():
|
||||||
|
download_codesign.download_and_unpack()
|
||||||
|
|
||||||
|
sign_process = subprocess.Popen(["./apple-codesign/rcodesign", "sign", output_path], shell=False,
|
||||||
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
|
sign_process.wait()
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user