コード例 #1
0
oc::result<void> AndroidFormatWriter::finish_entry(File &file)
{
    OUTCOME_TRYV(m_seg->finish_entry(file, m_writer));

    auto swentry = m_seg->entry();

    // Update SHA1 hash
    uint32_t le32_size = mb_htole32(*swentry->size);

    // Include size for everything except empty DT images
    if ((swentry->type != ENTRY_TYPE_DEVICE_TREE || *swentry->size > 0)
            && !SHA1_Update(&m_sha_ctx, &le32_size, sizeof(le32_size))) {
        m_writer.set_fatal();
        return AndroidError::Sha1UpdateError;
    }

    switch (swentry->type) {
    case ENTRY_TYPE_KERNEL:
        m_hdr.kernel_size = *swentry->size;
        break;
    case ENTRY_TYPE_RAMDISK:
        m_hdr.ramdisk_size = *swentry->size;
        break;
    case ENTRY_TYPE_SECONDBOOT:
        m_hdr.second_size = *swentry->size;
        break;
    case ENTRY_TYPE_DEVICE_TREE:
        m_hdr.dt_size = *swentry->size;
        break;
    }

    return oc::success();
}
コード例 #2
0
static oc::result<void>
_mtk_header_update_size(Writer &writer, File &file,
                        uint64_t offset, uint32_t size)
{
    uint32_t le32_size = mb_htole32(size);

    if (offset > SIZE_MAX - offsetof(MtkHeader, size)) {
        writer.set_fatal();
        return MtkError::MtkHeaderOffsetTooLarge;
    }

    auto seek_ret = file.seek(
            static_cast<int64_t>(offset + offsetof(MtkHeader, size)), SEEK_SET);
    if (!seek_ret) {
        if (file.is_fatal()) { writer.set_fatal(); }
        return seek_ret.as_failure();
    }

    auto ret = file_write_exact(file, &le32_size, sizeof(le32_size));
    if (!ret) {
        if (file.is_fatal()) { writer.set_fatal(); }
        return ret.as_failure();
    }

    return oc::success();
}
コード例 #3
0
ファイル: loki.cpp プロジェクト: Caio99BR/DualBootPatcher
MB_BEGIN_C_DECLS

static bool _patch_shellcode(uint32_t header, uint32_t ramdisk,
                             unsigned char patch[LOKI_SHELLCODE_SIZE])
{
    bool found_header = false;
    bool found_ramdisk = false;
    uint32_t *ptr;

    for (size_t i = 0; i < LOKI_SHELLCODE_SIZE - sizeof(uint32_t); ++i) {
        // Safe with little and big endian
        ptr = reinterpret_cast<uint32_t *>(&patch[i]);
        if (*ptr == 0xffffffff) {
            *ptr = mb_htole32(header);
            found_header = true;
        } else if (*ptr == 0xeeeeeeee) {
            *ptr = mb_htole32(ramdisk);
            found_ramdisk = true;
        }
    }

    return found_header && found_ramdisk;
}
コード例 #4
0
static oc::result<void>
_mtk_compute_sha1(Writer &writer, SegmentWriter &seg,
                  File &file, unsigned char digest[SHA_DIGEST_LENGTH])
{
    SHA_CTX sha_ctx;
    char buf[10240];

    uint32_t kernel_mtkhdr_size = 0;
    uint32_t ramdisk_mtkhdr_size = 0;

    if (!SHA1_Init(&sha_ctx)) {
        return android::AndroidError::Sha1InitError;
    }

    for (auto const &entry : seg.entries()) {
        uint64_t remain = *entry.size;

        auto seek_ret = file.seek(static_cast<int64_t>(entry.offset),
                                  SEEK_SET);
        if (!seek_ret) {
            if (file.is_fatal()) { writer.set_fatal(); }
            return seek_ret.as_failure();
        }

        // Update checksum with data
        while (remain > 0) {
            auto to_read = std::min<uint64_t>(remain, sizeof(buf));

            auto ret = file_read_exact(file, buf, static_cast<size_t>(to_read));
            if (!ret) {
                if (writer.is_fatal()) { writer.set_fatal(); }
                return ret.as_failure();
            }

            if (!SHA1_Update(&sha_ctx, buf, static_cast<size_t>(to_read))) {
                return android::AndroidError::Sha1UpdateError;
            }

            remain -= to_read;
        }

        uint32_t le32_size;

        // Update checksum with size
        switch (entry.type) {
        case ENTRY_TYPE_MTK_KERNEL_HEADER:
            kernel_mtkhdr_size = *entry.size;
            continue;
        case ENTRY_TYPE_MTK_RAMDISK_HEADER:
            ramdisk_mtkhdr_size = *entry.size;
            continue;
        case ENTRY_TYPE_KERNEL:
            le32_size = mb_htole32(*entry.size + kernel_mtkhdr_size);
            break;
        case ENTRY_TYPE_RAMDISK:
            le32_size = mb_htole32(*entry.size + ramdisk_mtkhdr_size);
            break;
        case ENTRY_TYPE_SECONDBOOT:
            le32_size = mb_htole32(*entry.size);
            break;
        case ENTRY_TYPE_DEVICE_TREE:
            if (*entry.size == 0) {
                continue;
            }
            le32_size = mb_htole32(*entry.size);
            break;
        default:
            continue;
        }

        if (!SHA1_Update(&sha_ctx, &le32_size, sizeof(le32_size))) {
            return android::AndroidError::Sha1UpdateError;
        }
    }

    if (!SHA1_Final(digest, &sha_ctx)) {
        return android::AndroidError::Sha1UpdateError;
    }

    return oc::success();
}