apex: ApexBuildInfo.pb ApexManifest.pb

pull/140/head
cfig 2 years ago
parent 82ff5215b7
commit d558c77755
No known key found for this signature in database
GPG Key ID: B104C307F0FDABB7

@ -0,0 +1,63 @@
package com.android.apex
import com.android.apex.ApexBuildInfoOuterClass.ApexBuildInfo
import com.google.protobuf.ByteString
import java.nio.charset.Charset
/*
string apexer_command_line = 1;
bytes file_contexts = 2;
bytes canned_fs_config = 3;
bytes android_manifest = 4;
string min_sdk_version = 5;
string target_sdk_version = 6;
bool no_hashtree = 7;
string override_apk_package_name = 8;
string logging_parent = 9;
string payload_fs_type = 10;
}
*/
data class ApexBuildInfoDataClass(
var apexer_command_line: String = "", //string
var file_contexts: String = "", //bytes
var canned_fs_config: String = "",//bytes
var android_manifest: String = "",//bytes
var min_sdk_version: String = "",//string
var target_sdk_version: String = "",//string
var no_hashtree: Boolean = false,
var override_apk_package_name: String = "",//string
var logging_parent: String = "",//string
var payload_fs_type: String = "",//string
) {
fun toPb(): ApexBuildInfo {
return ApexBuildInfo.newBuilder()
.setApexerCommandLine(this.apexer_command_line)
.setFileContexts(ByteString.copyFrom(this.file_contexts, Charset.defaultCharset()))
.setCannedFsConfig(ByteString.copyFrom(this.canned_fs_config, Charset.defaultCharset()))
.setAndroidManifest(ByteString.copyFrom(this.android_manifest, Charset.defaultCharset()))
.setMinSdkVersion(this.min_sdk_version)
.setTargetSdkVersion(this.target_sdk_version)
.setNoHashtree(this.no_hashtree)
.setOverrideApkPackageName(this.override_apk_package_name)
.setLoggingParent(this.logging_parent)
.setPayloadFsType(this.payload_fs_type)
.build()
}
companion object {
fun fromOuterClass(pb: ApexBuildInfoOuterClass.ApexBuildInfo): ApexBuildInfoDataClass? {
return ApexBuildInfoDataClass(
pb.apexerCommandLine,
pb.fileContexts.toStringUtf8(),
pb.cannedFsConfig.toStringUtf8(),
pb.androidManifest.toStringUtf8(),
pb.minSdkVersion,
pb.targetSdkVersion,
pb.noHashtree,
pb.overrideApkPackageName,
pb.loggingParent,
pb.payloadFsType
)
}
}
}

@ -0,0 +1,108 @@
package com.android.apex
import org.slf4j.LoggerFactory
/*
message ApexManifest {
string name = 1;
int64 version = 2;
string preInstallHook = 3;
string postInstallHook = 4;
string versionName = 5;
bool noCode = 6;
repeated string provideNativeLibs = 7;
repeated string requireNativeLibs = 8;
repeated string jniLibs = 9;
repeated string requireSharedApexLibs = 10;
bool provideSharedApexLibs = 11;
message CompressedApexMetadata {
string originalApexDigest = 1;
}
CompressedApexMetadata capexMetadata = 12;
bool supportsRebootlessUpdate = 13;
}
*/
data class ApexManifestDataClass(
/* 1 */ var name: String = "",
/* 2 */ var version: Long = 0,
/* 3 */ var preInstallHook: String = "",
/* 4 */ var postInstallHook: String = "",
/* 5 */ var versionName: String = "",
/* 6 */ var noCode: Boolean = false,
/* 7 */ var provideNativeLibs: MutableList<String> = mutableListOf(),
/* 8 */ var requireNativeLibs: MutableList<String> = mutableListOf(),
/* 9 */ var jniLibs: MutableList<String> = mutableListOf(),
/* 10 */ var requireSharedApexLibs: MutableList<String> = mutableListOf(),
/* 11 */ var provideSharedApexLibs: Boolean = false,
/* 12 */ var capexMetadata: CompressedApexMetadata = CompressedApexMetadata(),
/* 13 */ var supportsRebootlessUpdate: Boolean = false,
) {
data class CompressedApexMetadata(var originalApexDigest: String = "") {
fun toPb(): ApexManifestOuterClass.ApexManifest.CompressedApexMetadata {
return ApexManifestOuterClass.ApexManifest.CompressedApexMetadata.newBuilder()
.setOriginalApexDigest(this.originalApexDigest)
.build()
}
companion object {
fun fromOuterClass(pb: ApexManifestOuterClass.ApexManifest.CompressedApexMetadata): CompressedApexMetadata {
return CompressedApexMetadata(pb.originalApexDigest)
}
}
}
fun toPb(): ApexManifestOuterClass.ApexManifest {
return ApexManifestOuterClass.ApexManifest.newBuilder()
.setName(this.name)
.setVersion(this.version)
.setPreInstallHook(this.preInstallHook)
.setPostInstallHook(this.postInstallHook)
.setVersionName(this.versionName)
.setNoCode(this.noCode)
.setProvideSharedApexLibs(this.provideSharedApexLibs)
.setCapexMetadata(this.capexMetadata.toPb())
.setSupportsRebootlessUpdate(this.supportsRebootlessUpdate)
.also {
this.provideNativeLibs.forEachIndexed { _, s ->
it.addProvideNativeLibs(s)
}
}
.also {
this.requireNativeLibs.forEachIndexed { _, s ->
it.addRequireNativeLibs(s)
}
}
.also {
this.jniLibs.forEachIndexed { _, s ->
it.addJniLibs(s)
}
}
.also {
this.requireSharedApexLibs.forEachIndexed { _, s ->
it.addRequireSharedApexLibs(s)
}
}
.build()
}
companion object {
private val log = LoggerFactory.getLogger(ApexManifestDataClass::class.java)
fun fromOuterClass(pb: ApexManifestOuterClass.ApexManifest): ApexManifestDataClass? {
return ApexManifestDataClass(
pb.name,
pb.version,
pb.preInstallHook,
pb.postInstallHook,
pb.versionName,
pb.noCode,
pb.provideNativeLibsList,
pb.requireNativeLibsList,
pb.jniLibsList,
pb.requireSharedApexLibsList,
pb.provideSharedApexLibs,
CompressedApexMetadata.fromOuterClass(pb.capexMetadata),
pb.supportsRebootlessUpdate
)
}
}
}

@ -0,0 +1,25 @@
package com.android.apex
import cfig.helper.CryptoHelper
import com.fasterxml.jackson.databind.ObjectMapper
import org.junit.Test
import org.slf4j.LoggerFactory
import kotlin.test.assertTrue
class ApexBuildInfoDataClassTest {
private val log = LoggerFactory.getLogger(ApexBuildInfoOuterClass::class.java)
@Test
fun parseAndPack() {
val raw = ApexBuildInfoDataClassTest::class.java.classLoader.getResourceAsStream("apex_build_info.pb")!!.readBytes()
val originalHash = CryptoHelper.Hasher.sha256(raw)
//parse
val abiPb = ApexBuildInfoOuterClass.ApexBuildInfo.parseFrom(raw)
log.info(abiPb.toString())
val abiJava = ApexBuildInfoDataClass.fromOuterClass(abiPb)
log.info(ObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(abiJava))
//pack
val convertedHash = CryptoHelper.Hasher.sha256(abiJava!!.toPb().toByteArray())
//check
assertTrue(originalHash.contentEquals(convertedHash))
}
}

@ -0,0 +1,25 @@
package com.android.apex
import cfig.helper.CryptoHelper
import com.fasterxml.jackson.databind.ObjectMapper
import org.junit.Assert.*
import org.junit.Test
import org.slf4j.LoggerFactory
class ApexManifestDataClassTest {
private val log = LoggerFactory.getLogger(ApexManifestDataClassTest::class.java)
@Test
fun parseAndPack() {
val raw = ApexManifestDataClassTest::class.java.classLoader.getResourceAsStream("apex_manifest.pb")!!.readBytes()
val originalHash = CryptoHelper.Hasher.sha256(raw)
//parse
val pb = ApexManifestOuterClass.ApexManifest.parseFrom(raw)
log.info(pb.toString())
val manifest = ApexManifestDataClass.fromOuterClass(pb)
log.info(ObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(manifest))
//pack
val convertedHash = CryptoHelper.Hasher.sha256(manifest!!.toPb().toByteArray())
//check
assertTrue(originalHash.contentEquals(convertedHash))
}
}

@ -0,0 +1,16 @@
s(/.*)? u:object_r:adbd_exec:s0
/apex_manifest\.pb u:object_r:system_file:s0
/ u:object_r:system_file:s0
/ 1000 1000 0755
/apex_manifest.json 1000 1000 0644
/apex_manifest.pb 1000 1000 0644
/bin 0 2000 0755
/bin/lazybox 0 2000 0755
"<22><?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cc.cfig.lazybox" android:versionCode="2">
<!-- APEX does not have classes.dex -->
<application android:hasCode="false" />
</manifest>
*31231Rext4

@ -0,0 +1,3 @@
cc.cfig.lazyboxB:vndkBlibc.soBlibdl.soB liblog.soBlibm.sobB
@2667842c6a7971ff1c8ee4c746d25ee93fa4cb588307a422739886d88dc0a980
Loading…
Cancel
Save