bundle {boot.img, vbmeta.img}

pull/31/head
cfig 6 years ago
parent bcf3c2e2b4
commit bf7defd434
No known key found for this signature in database
GPG Key ID: B104C307F0FDABB7

@ -44,22 +44,23 @@ class Signer {
partition_name = bootDesc.partition_name, partition_name = bootDesc.partition_name,
newAvbInfo = ObjectMapper().readValue(File(getJsonFileName(cfg.info.output)), AVBInfo::class.java)) newAvbInfo = ObjectMapper().readValue(File(getJsonFileName(cfg.info.output)), AVBInfo::class.java))
//original signer //original signer
File(cfg.info.output + ".clear").copyTo(File(cfg.info.output + ".signed2")) CommandLine.parse("$avbtool add_hash_footer").apply {
var cmdlineStr = "$avbtool add_hash_footer " + addArguments("--image ${cfg.info.output}.signed2")
"--image ${cfg.info.output}.signed2 " + addArguments("--partition_size ${info2.imageSize}")
"--partition_size ${info2.imageSize} " + addArguments("--salt ${Helper.toHexString(bootDesc.salt)}")
"--salt ${Helper.toHexString(bootDesc.salt)} " + addArguments("--partition_name ${bootDesc.partition_name}")
"--partition_name ${bootDesc.partition_name} " + addArguments("--hash_algorithm ${bootDesc.hash_algorithm}")
"--hash_algorithm ${bootDesc.hash_algorithm} " + addArguments("--algorithm ${alg!!.name}")
"--algorithm ${alg!!.name} " if (alg.defaultKey.isNotBlank()) {
if (alg.defaultKey.isNotBlank()) { addArguments("--key ${alg.defaultKey}")
cmdlineStr += "--key ${alg.defaultKey}" }
addArgument("--internal_release_string")
addArgument(ai.header!!.release_string, false)
log.warn(this.toString())
File(cfg.info.output + ".clear").copyTo(File(cfg.info.output + ".signed2"))
DefaultExecutor().execute(this)
} }
log.warn(cmdlineStr)
val cmdLine = CommandLine.parse(cmdlineStr)
cmdLine.addArgument("--internal_release_string")
cmdLine.addArgument(ai.header!!.release_string, false)
DefaultExecutor().execute(cmdLine)
Parser.verifyAVBIntegrity(cfg.info.output, avbtool) Parser.verifyAVBIntegrity(cfg.info.output, avbtool)
} }
} }

@ -141,7 +141,7 @@ class Avb {
} }
} }
fun parseVbMeta(image_file: String): AVBInfo { fun parseVbMeta(image_file: String, dumpFile: Boolean = true): AVBInfo {
log.info("parsing $image_file ...") log.info("parsing $image_file ...")
val jsonFile = getJsonFileName(image_file) val jsonFile = getJsonFileName(image_file)
var footer: Footer? = null var footer: Footer? = null
@ -257,8 +257,13 @@ class Avb {
} }
} }
ObjectMapper().writerWithDefaultPrettyPrinter().writeValue(File(jsonFile), ai) if (dumpFile) {
log.info("vbmeta info written to $jsonFile") ObjectMapper().writerWithDefaultPrettyPrinter().writeValue(File(jsonFile), ai)
log.info("vbmeta info of [$image_file] has been analyzed")
log.info("vbmeta info written to $jsonFile")
} else {
log.warn("vbmeta info of [$image_file] has been analyzed, no dummping")
}
return ai return ai
} }

@ -1,20 +1,34 @@
package cfig.packable package cfig.packable
import avb.AVBInfo
import cfig.* import cfig.*
import cfig.bootimg.BootImgInfo import cfig.bootimg.BootImgInfo
import com.fasterxml.jackson.databind.ObjectMapper
import de.vandermeer.asciitable.AsciiTable import de.vandermeer.asciitable.AsciiTable
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import java.io.File import java.io.File
import java.lang.IllegalArgumentException import java.lang.IllegalArgumentException
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
class BootImgParser : IPackable { class BootImgParser() : IPackable {
override val loopNo: Int
get() = 0
private val log = LoggerFactory.getLogger(BootImgParser::class.java) private val log = LoggerFactory.getLogger(BootImgParser::class.java)
override fun capabilities(): List<String> { override fun capabilities(): List<String> {
return listOf("^boot\\.img$", "^recovery\\.img$", "^recovery-two-step\\.img$") return listOf("^boot\\.img$", "^recovery\\.img$", "^recovery-two-step\\.img$")
} }
private fun unpackVBMeta(): Boolean {
if (File("vbmeta.img").exists()) {
log.warn("Found vbmeta.img, parsing ...")
VBMetaParser().unpack("vbmeta.img")
return true
} else {
return false
}
}
override fun unpack(fileName: String) { override fun unpack(fileName: String) {
if (File(UnifiedConfig.workDir).exists()) File(UnifiedConfig.workDir).deleteRecursively() if (File(UnifiedConfig.workDir).exists()) File(UnifiedConfig.workDir).deleteRecursively()
File(UnifiedConfig.workDir).mkdirs() File(UnifiedConfig.workDir).mkdirs()
@ -29,6 +43,7 @@ class BootImgParser : IPackable {
InfoTable.instance.addRow("AVB info", Avb.getJsonFileName(fileName)) InfoTable.instance.addRow("AVB info", Avb.getJsonFileName(fileName))
} }
Parser().extractBootImg(fileName, info2 = info) Parser().extractBootImg(fileName, info2 = info)
val unpackedVbmeta = unpackVBMeta()
InfoTable.instance.addRule() InfoTable.instance.addRule()
val tableHeader = AsciiTable().apply { val tableHeader = AsciiTable().apply {
@ -37,6 +52,14 @@ class BootImgParser : IPackable {
addRule() addRule()
} }
log.info("\n\t\t\tUnpack Summary of $fileName\n{}\n{}", tableHeader.render(), InfoTable.instance.render()) log.info("\n\t\t\tUnpack Summary of $fileName\n{}\n{}", tableHeader.render(), InfoTable.instance.render())
if (unpackedVbmeta) {
val tableFooter = AsciiTable().apply {
addRule()
addRow("vbmeta.img", Avb.getJsonFileName("vbmeta.img"))
addRule()
}
LoggerFactory.getLogger("vbmeta").info("\n" + tableFooter.render())
}
log.info("Following components are not present: ${InfoTable.missingParts}") log.info("Following components are not present: ${InfoTable.missingParts}")
} catch (e: IllegalArgumentException) { } catch (e: IllegalArgumentException) {
log.error(e.message) log.error(e.message)
@ -47,6 +70,28 @@ class BootImgParser : IPackable {
override fun pack(fileName: String) { override fun pack(fileName: String) {
Packer().pack(mkbootfsBin = "./aosp/mkbootfs/build/exe/mkbootfs/mkbootfs") Packer().pack(mkbootfsBin = "./aosp/mkbootfs/build/exe/mkbootfs/mkbootfs")
Signer.sign(avbtool = "avb/avbtool", bootSigner = "aosp/boot_signer/build/libs/boot_signer.jar") Signer.sign(avbtool = "avb/avbtool", bootSigner = "aosp/boot_signer/build/libs/boot_signer.jar")
if (File("vbmeta.img").exists()) {
val partitionName = ObjectMapper().readValue(File(Avb.getJsonFileName(fileName)), AVBInfo::class.java).let {
it.auxBlob!!.hashDescriptors.get(0).partition_name
}
val newHashDesc = Avb().parseVbMeta("$fileName.signed", dumpFile = false)
assert(newHashDesc.auxBlob!!.hashDescriptors.size == 1)
val mainVBMeta = ObjectMapper().readValue(File(Avb.getJsonFileName("vbmeta.img")), AVBInfo::class.java).apply {
val itr = this.auxBlob!!.hashDescriptors.iterator()
var seq = 0
while (itr.hasNext()) {
val itrValue = itr.next()
if (itrValue.partition_name == partitionName) {
seq = itrValue.sequence
itr.remove()
break
}
}
val hd = newHashDesc.auxBlob!!.hashDescriptors.get(0).apply { this.sequence = seq }
this.auxBlob!!.hashDescriptors.add(hd)
}
Avb().packVbMetaWithPadding("vbmeta.img", mainVBMeta)
}
} }
override fun flash(fileName: String, deviceName: String) { override fun flash(fileName: String, deviceName: String) {

@ -12,6 +12,9 @@ import java.util.*
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
class DtboParser(val workDir: File) : IPackable { class DtboParser(val workDir: File) : IPackable {
override val loopNo: Int
get() = 0
constructor() : this(File(".")) constructor() : this(File("."))
private val log = LoggerFactory.getLogger(DtboParser::class.java) private val log = LoggerFactory.getLogger(DtboParser::class.java)

@ -6,6 +6,7 @@ import org.slf4j.Logger
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
interface IPackable { interface IPackable {
val loopNo: Int
fun capabilities(): List<String> { fun capabilities(): List<String> {
return listOf("^dtbo\\.img$") return listOf("^dtbo\\.img$")
} }

@ -25,16 +25,33 @@ fun main(args: Array<String>) {
var targetHandler: KClass<IPackable>? = null var targetHandler: KClass<IPackable>? = null
run found@{ run found@{
File(".").listFiles().forEach { file -> File(".").listFiles().forEach { file ->
packablePool.forEach { p -> packablePool
for (item in p.key) { .filter { it.value.createInstance().loopNo == 0 }
if (Pattern.compile(item).matcher(file.name).matches()) { .forEach { p ->
log.debug("Found: " + file.name + ", " + item) for (item in p.key) {
targetFile = file.name if (Pattern.compile(item).matcher(file.name).matches()) {
targetHandler = p.value log.debug("Found: " + file.name + ", " + item)
return@found targetFile = file.name
targetHandler = p.value
return@found
}
}
}
}
File(".").listFiles().forEach { file ->
packablePool
.filter { it.value.createInstance().loopNo != 0 }
.forEach { p ->
for (item in p.key) {
if (Pattern.compile(item).matcher(file.name).matches()) {
log.debug("Found: " + file.name + ", " + item)
targetFile = file.name
targetHandler = p.value
return@found
}
}
} }
}
}
} }
} }

@ -4,6 +4,9 @@ import cfig.Avb
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
class VBMetaParser: IPackable { class VBMetaParser: IPackable {
override val loopNo: Int
get() = 1
override fun capabilities(): List<String> { override fun capabilities(): List<String> {
return listOf("^vbmeta\\.img$", "^vbmeta\\_[a-z]+.img$") return listOf("^vbmeta\\.img$", "^vbmeta\\_[a-z]+.img$")
} }

@ -7,6 +7,8 @@ import cfig.Helper.Companion.check_call
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
class SparseImg : IPackable { class SparseImg : IPackable {
override val loopNo: Int
get() = 0
private val log = LoggerFactory.getLogger(SparseImg::class.java) private val log = LoggerFactory.getLogger(SparseImg::class.java)
private val simg2imgBin: String private val simg2imgBin: String
private val img2simgBin: String private val img2simgBin: String

@ -1 +1 @@
Subproject commit 9c8f314279c08d9d06720b5be86b5894f872682c Subproject commit 2b95308b91c2c0a564451b744354b2ef1428311d
Loading…
Cancel
Save