Skip to content

Commit

Permalink
lots of stuff
Browse files Browse the repository at this point in the history
 - extract helper for more projects
 - kotlin 1.4.31
 - gradle 6.8.3
 - vendor_boot flash/pull
 - fix comanion vbmeta update: boot.img, vendor_boot.img
 - refine libavb
  • Loading branch information
cfig committed Feb 28, 2021
1 parent 50273a9 commit 6c662a5
Show file tree
Hide file tree
Showing 53 changed files with 1,151 additions and 843 deletions.
8 changes: 4 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ addons:
- python-all
before_install:
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew update ; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew install lz4 dtc gradle; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew install lz4 dtc ; fi
before_script:
- ./gradlew check && ./gradlew clean
script:
- ./gradlew check
- ./gradlew clean
- ./integrationTest.py
- ./integrationTest.py
19 changes: 2 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Android_boot_image_editor
[![Build Status](https://travis-ci.org/cfig/Android_boot_image_editor.svg?branch=master)](https://travis-ci.org/cfig/Android_boot_image_editor)
[![Build Status](https://www.travis-ci.com/cfig/Android_boot_image_editor.svg?branch=master)](https://www.travis-ci.com/cfig/Android_boot_image_editor)
[![License](http://img.shields.io/:license-apache-blue.svg?style=flat-square)](http://www.apache.org/licenses/LICENSE-2.0.html)

A tool for reverse engineering Android ROM images.
Expand All @@ -10,7 +10,7 @@ A tool for reverse engineering Android ROM images.

Mac: `brew install lz4 xz`

Linux: `sudo apt install device-tree-compiler lz4 xz zlib1g-dev openjdk-11-jdk`
Linux: `sudo apt install git device-tree-compiler lz4 xz-utils zlib1g-dev openjdk-11-jdk gcc g++ python3`

Windows: Make sure you have `python3`, `JDK9+` and `openssl` properly installed.
An easy way is to install [Anaconda](https://www.anaconda.com/products/individual#windows) and [Oracle JDK 11](https://www.oracle.com/java/technologies/javase-jdk11-downloads.html), then run the program under anaconda PowerShell.
Expand Down Expand Up @@ -60,7 +60,6 @@ Well done you did it! The last step is to star this repo :smile
| boot images | boot.img, vendor_boot.img | |
| recovery images | recovery.img, recovery-two-step.img | |
| vbmeta images | vbmeta.img, vbmeta_system.img etc. | |
| sparse images | system.img, vendor.img etc. | |
| dtbo images | dtbo.img | |

Please note that the boot.img MUST follows AOSP verified boot flow, either [Boot image signature](https://source.android.com/security/verifiedboot/verified-boot#signature_format) in VBoot 1.0 or [AVB HASH footer](https://android.googlesource.com/platform/external/avb/+/master/README.md#The-VBMeta-struct) (a.k.a. AVB) in VBoot 2.0.
Expand Down Expand Up @@ -106,20 +105,6 @@ cp <your_vbmeta_image> vbmeta.img
```
Your boot.img.signed and vbmeta.img.signd will be updated together.

* sparse vendor.img

```bash
cp <your_vendor_image> vendor.img
./gradlew unpack
./gradlew pack
```

You get vendor.img.unsparse, then you can mount it.
```bash
mkdir mnt
sudo mount -o ro vendor.img mnt
```

## boot.img layout
Read [layout](doc/layout.md) of Android boot.img and vendor\_boot.img.

Expand Down
5 changes: 5 additions & 0 deletions aosp/avb/avbtool.v1.2.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import argparse
import binascii
import bisect
import binascii
import hashlib
import json
import math
Expand Down Expand Up @@ -577,6 +578,7 @@ def verify_vbmeta_signature(vbmeta_header, vbmeta_blob):
ha.update(header_blob)
ha.update(aux_blob)
computed_digest = ha.digest()
print("computed %s hash : %s" % (alg.hash_name, binascii.hexlify(computed_digest)))

if computed_digest != digest_blob:
return False
Expand All @@ -586,6 +588,7 @@ def verify_vbmeta_signature(vbmeta_header, vbmeta_blob):
(num_bits,) = struct.unpack('!I', pubkey_blob[0:4])
modulus_blob = pubkey_blob[8:8 + num_bits//8]
modulus = decode_long(modulus_blob)
print("modulus = %s" % modulus)
exponent = 65537

# We used to have this:
Expand Down Expand Up @@ -2528,6 +2531,8 @@ def verify_image(self, image_filename, key_path, expected_chain_partitions,
if not verify_vbmeta_signature(header, vbmeta_blob):
raise AvbError('Signature check failed for {} vbmeta struct {}'
.format(alg_name, image_filename))
else:
print("Sig check done")

if key_blob:
# The embedded public key is in the auxiliary block at an offset.
Expand Down
22 changes: 12 additions & 10 deletions aosp/build/tools/extract_kernel.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def dump_from_release(input_bytes, key):

value = get_from_release(input_bytes, idx, key)
if value:
return value
return value.encode()

idx += len(LINUX_BANNER_PREFIX)

Expand Down Expand Up @@ -176,16 +176,18 @@ def dump_to_file(f, dump_fn, input_bytes, desc):
if f is not None:
o = decompress_dump(dump_fn, input_bytes)
if o:
if isinstance(o, str):
f.write(o.encode())
else:
f.write(o)
f.write(o)
else:
sys.stderr.write(
"Cannot extract kernel {}".format(desc))
return False
return True

def to_bytes_io(b):
"""
Make b, which is either sys.stdout or sys.stdin, receive bytes as arguments.
"""
return b.buffer if sys.version_info.major == 3 else b

def main():
parser = argparse.ArgumentParser(
Expand All @@ -197,35 +199,35 @@ def main():
help='Input kernel image. If not specified, use stdin',
metavar='FILE',
type=argparse.FileType('rb'),
default=sys.stdin)
default=to_bytes_io(sys.stdin))
parser.add_argument('--output-configs',
help='If specified, write configs. Use stdout if no file '
'is specified.',
metavar='FILE',
nargs='?',
type=argparse.FileType('wb'),
const=sys.stdout)
const=to_bytes_io(sys.stdout))
parser.add_argument('--output-version',
help='If specified, write version. Use stdout if no file '
'is specified.',
metavar='FILE',
nargs='?',
type=argparse.FileType('wb'),
const=sys.stdout)
const=to_bytes_io(sys.stdout))
parser.add_argument('--output-release',
help='If specified, write kernel release. Use stdout if '
'no file is specified.',
metavar='FILE',
nargs='?',
type=argparse.FileType('wb'),
const=sys.stdout)
const=to_bytes_io(sys.stdout))
parser.add_argument('--output-compiler',
help='If specified, write the compiler information. Use stdout if no file '
'is specified.',
metavar='FILE',
nargs='?',
type=argparse.FileType('wb'),
const=sys.stdout)
const=to_bytes_io(sys.stdout))
parser.add_argument('--tools',
help='Decompression tools to use. If not specified, PATH '
'is searched.',
Expand Down
2 changes: 1 addition & 1 deletion avbImpl/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ model {

task v1(type:Exec) {
workingDir "."
environment preloads: "vbmeta boot", requests: "boot dtbo", suffix: ""
environment preloads: "vbmeta boot", requests: "boot dtbo vendor_boot", suffix: ""
commandLine "./build/exe/avbVerifier/avbVerifier"
}

Expand Down
30 changes: 26 additions & 4 deletions avbImpl/src/avbVerifier/cpp/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,9 @@ int main(int, char**) {
}
}

bool isDeviceLocked = true;
cfigOps.avb_ops_.read_is_device_unlocked(NULL, &isDeviceLocked);
if (isDeviceLocked) {
bool isDeviceUnlocked = false;
cfigOps.avb_ops_.read_is_device_unlocked(NULL, &isDeviceUnlocked);
if (isDeviceUnlocked) {
flags |= AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR;
}
std::cout << "[" << __FUNCTION__ << "]: flags: " << flags << std::endl;
Expand All @@ -94,6 +94,28 @@ int main(int, char**) {
std::cout << "Run:\n python -m json.tool " << outFile << std::endl;
}
if (slotData) { avb_slot_verify_data_free(slotData); }
std::cerr << "\n\tVerify Result: " << toString(result) << std::endl;
std::cout << "\n\tVerify Result: " << toString(result) << std::endl;
if (isDeviceUnlocked) {
switch (result) {
case AVB_SLOT_VERIFY_RESULT_OK:
std::cout << "\tVerify Flow: [orange] continue";
break;
case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION:
case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED:
case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX:
std::cout << "\tVerify Flow: [orange] allowed errors found: " << toString(result) << std::endl;
break;
default:
std::cout<< "\tVerify Flow: [orange] but fatal errors found" << std::endl;
}
} else {
switch (result) {
case AVB_SLOT_VERIFY_RESULT_OK:
std::cout << "\tVerify Flow: [green] continue";
break;
default:
std::cout << "\tVerify Flow: [?????] halt";
}
}
return 0;
}
31 changes: 20 additions & 11 deletions avbImpl/src/avbx/cpp/CfigAvbOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,10 @@ static AvbIOResult read_is_device_unlockedX(AvbOps *, bool *out_is_unlocked) {
std::string line = read_line(lockStatusFile);
if ("0" == line) {
*out_is_unlocked = true;
std::cout << "[" << __FUNCTION__ << "], device is unlocked" << std::endl;
} else {
*out_is_unlocked = false;
std::cout << "[" << __FUNCTION__ << "], device is locked" << std::endl;
}
std::cout << "[" << __FUNCTION__ << "], device is " << ((*out_is_unlocked) ? "unlocked" : "locked") << std::endl;

return AVB_IO_RESULT_OK;
}
Expand Down Expand Up @@ -152,16 +151,16 @@ static AvbIOResult get_size_of_partitionX(AvbOps *,
auto file_size = get_file_size(partitionFile.c_str());
if (-1 == file_size) {
std::cout << "[" << __FUNCTION__ << "(" << partition << ")]: ";
std::cout << ": error when accessing file [" << partitionFile << "]" << std::endl;
std::cout << "error when accessing file [" << partitionFile << "]" << std::endl;
return AVB_IO_RESULT_ERROR_IO;
} else {
std::cout << "[" << __FUNCTION__ << "(" << partition << ")]: ";
std::cout << ": partition " << partitionFile << " size: " << file_size << std::endl;
std::cout << "partition " << partitionFile << " size: " << file_size << std::endl;
if (out_size_num_bytes != nullptr) {
*out_size_num_bytes = file_size;
} else {
std::cerr << "[" << __FUNCTION__ << "(" << partition << ")]: ";
std::cerr << ": size is not passed back" << std::endl;
std::cerr << "size is not passed back" << std::endl;
}
}
return AVB_IO_RESULT_OK;
Expand Down Expand Up @@ -215,7 +214,7 @@ static AvbIOResult read_from_partitionX(AvbOps *,
return AVB_IO_RESULT_ERROR_IO;
}
ssize_t num_read = read(fd, buffer, num_bytes);
if (num_read < 0 || num_read != num_bytes) {
if (num_read < 0) {
fprintf(stderr,
"[%s()]: Error reading %zd bytes from pos %" PRId64 " in file %s: %s\n",
__FUNCTION__,
Expand All @@ -230,11 +229,21 @@ static AvbIOResult read_from_partitionX(AvbOps *,
if (out_num_read != nullptr) {
*out_num_read = num_read;
}
fprintf(stdout,
"[%s()]: Read %ld bytes from partition %s\n",
__FUNCTION__,
num_read,
partition);
if (num_read != num_bytes) {
fprintf(stderr,
"[%s()]: read fewer bytes from pos %" PRId64 " in file %s: exp=%zd, act=%zd\n",
__FUNCTION__,
offset,
partitionFile.c_str(),
num_bytes,
num_read);
} else {
fprintf(stdout,
"[%s()]: Read %ld bytes from partition %s\n",
__FUNCTION__,
num_read,
partition);
}
// cout << hexStr((unsigned char *) buffer, num_read) << endl;

return AVB_IO_RESULT_OK;
Expand Down
11 changes: 6 additions & 5 deletions bbootimg/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
kotlin("jvm") version "1.4.21"
kotlin("jvm") version "1.4.31"
application
}

Expand All @@ -12,19 +12,19 @@ repositories {
dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("org.jetbrains.kotlin:kotlin-reflect")

implementation("org.slf4j:slf4j-simple:1.7.30")
implementation("org.slf4j:slf4j-api:1.7.30")
implementation("com.fasterxml.jackson.core:jackson-annotations:2.11.3")
implementation("com.fasterxml.jackson.core:jackson-databind:2.11.3")
implementation("com.fasterxml.jackson.core:jackson-annotations:2.12.1")
implementation("com.fasterxml.jackson.core:jackson-databind:2.12.1")
implementation("com.google.guava:guava:18.0")
implementation("org.apache.commons:commons-exec:1.3")
implementation("org.apache.commons:commons-compress:1.20")
implementation("org.tukaani:xz:1.8")
implementation("commons-codec:commons-codec:1.15")
implementation("junit:junit:4.12")
implementation("org.bouncycastle:bcprov-jdk15on:1.57")
implementation("org.bouncycastle:bcprov-jdk15on:1.68")
implementation("de.vandermeer:asciitable:0.3.2")
implementation(project(":helper"))

testImplementation("org.jetbrains.kotlin:kotlin-test")
testImplementation("org.jetbrains.kotlin:kotlin-test-junit")
Expand All @@ -46,6 +46,7 @@ tasks {
}
from(configurations.runtimeClasspath.get().map({ if (it.isDirectory) it else zipTree(it) }))
excludes.addAll(mutableSetOf("META-INF/*.RSA", "META-INF/*.SF", "META-INF/*.DSA"))
dependsOn(":helper:jar")
}
test {
testLogging {
Expand Down
47 changes: 0 additions & 47 deletions bbootimg/src/main/kotlin/KeyUtil.kt

This file was deleted.

Loading

0 comments on commit 6c662a5

Please sign in to comment.