200 lines
7.4 KiB
Nix
200 lines
7.4 KiB
Nix
{
|
|
description = "APKs demonstrating class shadowing.";
|
|
inputs = {
|
|
nixpkgs.url = github:nixos/nixpkgs/nixos-unstable;
|
|
flake-utils.url = github:numtide/flake-utils;
|
|
};
|
|
|
|
outputs = { self, nixpkgs, flake-utils }:
|
|
flake-utils.lib.eachDefaultSystem (system:
|
|
let
|
|
pkgs = import nixpkgs {
|
|
system = system;
|
|
config = {
|
|
android_sdk.accept_license = true;
|
|
allowUnfree = true;
|
|
};
|
|
};
|
|
jdk = pkgs.javaPackages.compiler.openjdk17;
|
|
android-env = pkgs.androidenv.composeAndroidPackages {
|
|
buildToolsVersions = [ "34.0.0" ];
|
|
platformVersions = [ "34" ];
|
|
};
|
|
platforms = "${builtins.head android-env.platforms}/libexec/android-sdk/platforms/android-34";
|
|
build-tools = "${builtins.head android-env.build-tools}/libexec/android-sdk/build-tools/34.0.0";
|
|
|
|
javaCompile = folder: pkgs.stdenvNoCC.mkDerivation {
|
|
name = "java-class-${folder}";
|
|
src = self;
|
|
buildInputs = [ jdk android-env.androidsdk ];
|
|
phases = ["unpackPhase" "buildPhase"];
|
|
buildPhase = ''
|
|
mkdir $out
|
|
javac -classpath ${platforms}/android.jar $(find ${folder} -type f -name '*.java') -d $out/
|
|
'';
|
|
};
|
|
java2dex = drv: pkgs.stdenvNoCC.mkDerivation {
|
|
name = "${drv}-classes.dex";
|
|
srcs = drv;
|
|
# jdk env needed for d8
|
|
buildInputs = [ jdk android-env.androidsdk ];
|
|
phases = ["unpackPhase" "buildPhase" "installPhase"];
|
|
buildPhase = ''
|
|
mkdir build
|
|
d8 --classpath ${platforms}/android.jar $(find . -name '*.class') --output build/
|
|
'';
|
|
installPhase = ''
|
|
mv build/classes.dex $out
|
|
'';
|
|
};
|
|
make-manifest = package : name: pkgs.stdenvNoCC.mkDerivation {
|
|
name = "AndroidManifest-${package}.xml";
|
|
srcs = self;
|
|
#buildInputs = [ ];
|
|
phases = ["unpackPhase" "buildPhase"];
|
|
buildPhase = ''
|
|
mkdir $out
|
|
cat AndroidManifest.xml | sed 's/PACKAGE/${package}/' | sed 's/NAME/${name}/' > $out/AndroidManifest.xml
|
|
'';
|
|
};
|
|
keypass = "P@ssw0rd!";
|
|
keystore = pkgs.stdenvNoCC.mkDerivation {
|
|
name = "shadowing.keystore";
|
|
buildInputs = [ jdk ];
|
|
phases = ["buildPhase"];
|
|
buildPhase = ''
|
|
keytool -genkeypair -validity 1000 -dname "CN=SomeKey,O=SomeOne,C=FR" -keystore $out -storepass '${keypass}' -keypass '${keypass}' -alias SignKey -keyalg RSA -v
|
|
'';
|
|
};
|
|
make-apk = {
|
|
package,
|
|
name,
|
|
classes,
|
|
} : let
|
|
manifest = make-manifest package name;
|
|
in pkgs.stdenvNoCC.mkDerivation {
|
|
name = "${package}";
|
|
buildInputs = [ jdk android-env.androidsdk ];
|
|
phases = ["buildPhase" "installPhase"];
|
|
buildPhase = ''
|
|
mkdir -p build/apk_files
|
|
|
|
${pkgs.lib.strings.concatMapStringsSep "\n" ( item:
|
|
"cp ${item.drv} build/apk_files/${item.name}"
|
|
) classes}
|
|
|
|
# link classes.dex not working?
|
|
# ${build-tools}/aapt2 link -v ---manifest ${manifest}/AndroidManifest.xml -I ${platforms}/android.jar -o build/app.apk build/apk_files/
|
|
|
|
${build-tools}/aapt package -v -f -M ${manifest}/AndroidManifest.xml -I ${platforms}/android.jar -F build/app.apk build/apk_files/
|
|
${build-tools}/zipalign -f 4 build/app.apk build/app.aligned.apk
|
|
${build-tools}/apksigner sign -ks ${keystore} --v2-signing-enabled true --in build/app.aligned.apk --out build/${package}.apk --ks-pass 'pass:${keypass}'
|
|
'';
|
|
installPhase = ''
|
|
mkdir $out
|
|
cp build/${package}.apk $out/
|
|
cp build/${package}.apk.idsig $out/
|
|
'';
|
|
};
|
|
|
|
java-classes-main = pkgs.stdenvNoCC.mkDerivation {
|
|
name = "java-class-main";
|
|
src = self;
|
|
buildInputs = [ jdk android-env.androidsdk ];
|
|
phases = ["unpackPhase" "buildPhase"];
|
|
buildPhase = ''
|
|
mkdir $out
|
|
javac -classpath ${platforms}/android.jar $(find java/main -type f -name '*.java') $(find java/actual -type f -name '*.java') -d $out/
|
|
find java/actual/ -type f -name '*.java' | while read f ; do
|
|
class_file=$(echo $f | sed "s#java/actual/##" | sed 's/.java/.class/')
|
|
rm $out/$class_file
|
|
done
|
|
'';
|
|
};
|
|
java-classes-actual = javaCompile "java/actual";
|
|
java-classes-dummy = javaCompile "java/dummy";
|
|
java-classes-empty = javaCompile "java/empty";
|
|
|
|
main-actual-classes-dex = java2dex (pkgs.symlinkJoin {
|
|
name = "classes-main-actual";
|
|
paths = [ java-classes-main java-classes-actual ];
|
|
});
|
|
main-dummy-classes-dex = java2dex (pkgs.symlinkJoin {
|
|
name = "classes-main-dummy";
|
|
paths = [ java-classes-main java-classes-dummy ];
|
|
});
|
|
main-classes-dex = java2dex java-classes-main;
|
|
actual-classes-dex = java2dex java-classes-actual;
|
|
dummy-classes-dex = java2dex java-classes-dummy;
|
|
empty-classes-dex = java2dex java-classes-empty;
|
|
|
|
in {
|
|
|
|
packages = rec {
|
|
control = make-apk {
|
|
package = "com.example.shadowing.control";
|
|
name = "Shadowing C";
|
|
classes = [
|
|
{ name = "classes.dex"; drv = main-actual-classes-dex; }
|
|
];
|
|
};
|
|
# classes.dex vs classes2.dex
|
|
shdw1 = make-apk {
|
|
package = "com.example.shadowing.one";
|
|
name = "Shadowing 1";
|
|
classes = [
|
|
{ name = "classes.dex"; drv = main-actual-classes-dex; }
|
|
{ name = "classes2.dex"; drv = dummy-classes-dex; }
|
|
];
|
|
};
|
|
# classes2.dex vs classes3.dex
|
|
shdw2 = make-apk {
|
|
package = "com.example.shadowing.two";
|
|
name = "Shadowing 2";
|
|
classes = [
|
|
{ name = "classes.dex"; drv = main-classes-dex; }
|
|
{ name = "classes2.dex"; drv = actual-classes-dex; }
|
|
{ name = "classes3.dex"; drv = dummy-classes-dex; }
|
|
];
|
|
};
|
|
# classes2.dex vs classes1.dex
|
|
shdw3 = make-apk {
|
|
package = "com.example.shadowing.three";
|
|
name = "Shadowing 3";
|
|
classes = [
|
|
{ name = "classes.dex"; drv = main-classes-dex; }
|
|
{ name = "classes1.dex"; drv = dummy-classes-dex; }
|
|
{ name = "classes2.dex"; drv = actual-classes-dex; }
|
|
];
|
|
};
|
|
# classes10.dex vs classes2.dex
|
|
shdw4 = make-apk {
|
|
package = "com.example.shadowing.four";
|
|
name = "Shadowing 4";
|
|
classes = [
|
|
{ name = "classes.dex"; drv = main-classes-dex; }
|
|
{ name = "classes2.dex"; drv = actual-classes-dex; }
|
|
{ name = "classes3.dex"; drv = empty-classes-dex; }
|
|
{ name = "classes4.dex"; drv = empty-classes-dex; }
|
|
{ name = "classes5.dex"; drv = empty-classes-dex; }
|
|
{ name = "classes6.dex"; drv = empty-classes-dex; }
|
|
{ name = "classes7.dex"; drv = empty-classes-dex; }
|
|
{ name = "classes8.dex"; drv = empty-classes-dex; }
|
|
{ name = "classes9.dex"; drv = empty-classes-dex; }
|
|
{ name = "classes10.dex"; drv = dummy-classes-dex; }
|
|
];
|
|
};
|
|
default = pkgs.symlinkJoin {
|
|
name = "all-shadowing-apks";
|
|
paths = [ control shdw1 shdw2 shdw3 shdw4];
|
|
};
|
|
};
|
|
|
|
devShells.default = pkgs.mkShellNoCC {
|
|
packages = [ jdk android-env.androidsdk ];
|
|
#shellHook = ''
|
|
#'';
|
|
};
|
|
})
|
|
;
|
|
}
|