背景
项目中经常碰到下载版本时遇到错误ERROR:STATUS_SEC_VIOLATE_ANTI_ROLLBACK(0xC002002D),无法下载的情况,此时如果有一个工具可以直接查询到版本的antirollback值多好,那就可以明确看到问题点了,这就是这个exe小工具的原动力 ^_^
错误提示:
exe 工具可以去这里直接下载:https://download.csdn.net/download/jimbo_lee/89393012?spm=1001.2014.3001.5501
ReadRollbackIndex.exe 获取
调查avbVBMeta结构体
typedef struct AvbVBMetaImageHeader {
/* 0: Four bytes equal to "AVB0" (AVB_MAGIC). */
uint8_t magic[AVB_MAGIC_LEN];
/* 4: The major version of libavb required for this header. */
uint32_t required_libavb_version_major;
/* 8: The minor version of libavb required for this header. */
uint32_t required_libavb_version_minor;
/* 12: The size of the signature block. */
uint64_t authentication_data_block_size;
/* 20: The size of the auxiliary data block. */
uint64_t auxiliary_data_block_size;
/* 28: The verification algorithm used, see |AvbAlgorithmType| enum. */
uint32_t algorithm_type;
/* 32: Offset into the "Authentication data" block of hash data. */
uint64_t hash_offset;
/* 40: Length of the hash data. */
uint64_t hash_size;
/* 48: Offset into the "Authentication data" block of signature data. */
uint64_t signature_offset;
/* 56: Length of the signature data. */
uint64_t signature_size;
/* 64: Offset into the "Auxiliary data" block of public key data. */
uint64_t public_key_offset;
/* 72: Length of the public key data. */
uint64_t public_key_size;
/* 80: Offset into the "Auxiliary data" block of public key metadata. */
uint64_t public_key_metadata_offset;
/* 88: Length of the public key metadata. Must be set to zero if there
* is no public key metadata.
*/
uint64_t public_key_metadata_size;
/* 96: Offset into the "Auxiliary data" block of descriptor data. */
uint64_t descriptors_offset;
/* 104: Length of descriptor data. */
uint64_t descriptors_size;
/* 112: The rollback index which can be used to prevent rollback to
* older versions.
*/
uint64_t rollback_index;
/* 120: Flags from the AvbVBMetaImageFlags enumeration. This must be
* set to zero if the vbmeta image is not a top-level image.
*/
uint32_t flags;
/* 124: The location of the rollback index defined in this header.
* Only valid for the main vbmeta. For chained partitions, the rollback
* index location must be specified in the AvbChainPartitionDescriptor
* and this value must be set to 0.
*/
uint32_t rollback_index_location;
/* 128: The release string from avbtool, e.g. "avbtool 1.0.0" or
* "avbtool 1.0.0 xyz_board Git-234abde89". Is guaranteed to be NUL
* terminated. Applications must not make assumptions about how this
* string is formatted.
*/
uint8_t release_string[AVB_RELEASE_STRING_SIZE];
/* 176: Padding to ensure struct is size AVB_VBMETA_IMAGE_HEADER_SIZE
* bytes. This must be set to zeroes.
*/
uint8_t reserved[80];
} AVB_ATTR_PACKED AvbVBMetaImageHeader;
发现antirollback 值保存位置在vbmeata.img offset 是112~119
故可以做一个exe文件读取vbmeta.img文件rollback index值,代码如下:
// ReadRollbackIndex.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "stdio.h"
#include "stdlib.h"
#include <direct.h>
#include "Windows.h"
#define MAX_PATH_LEN 1024
//0x77 <==> 119
#define ROLLBAK_INDEX_OFFSET 0x77
void TcharToChar(const TCHAR * tchar, char * _char)
{
int iLength;
//获取字节长度
iLength = WideCharToMultiByte(CP_ACP, 0, tchar, -1, NULL, 0, NULL, NULL);
//将tchar值赋给_char
WideCharToMultiByte(CP_ACP, 0, tchar, -1, _char, iLength, NULL, NULL);
}
int _tmain(int argc, _TCHAR* argv[])
{
char currPath[MAX_PATH_LEN] = "\0";
char fileName[MAX_PATH_LEN] = "\0";
if(argc > 1)
{
TcharToChar(argv[1], fileName);
printf("transfer filename: %s \n", fileName);
}
// get current path
if (getcwd(currPath, sizeof(currPath)) == NULL){
printf("getcwd() error");
};
//printf(" currPath = %s \n", currPath);
char vbmetaFileName[MAX_PATH_LEN] = "\0";
//if(strlen(fileName) > 0){
if(argc > 1)
sprintf(vbmetaFileName, "%s\\%s", currPath, fileName);
}else{
sprintf(vbmetaFileName, "%s\\vbmeta.img", currPath);
}
printf("vbmeta.img file path: %s \n", vbmetaFileName);
// open and read file
FILE* pVbmetaFile = fopen(vbmetaFileName, "rb");
if (pVbmetaFile == NULL)
{
printf("open %s failed.", vbmetaFileName);
return -1;
}
//文件指针偏移 SEEK_SET初始位置开始偏移
if(!fseek(pVbmetaFile, ROLLBAK_INDEX_OFFSET, SEEK_SET)){
int rollbackIndex = fgetc(pVbmetaFile);
printf("Rollback Index: %d\n", rollbackIndex);
}
// release file handle
fclose(pVbmetaFile);
return 0;
}
此段代码经 vs2010 编译验证ok,程序运行结果:
代码中获取
antirollback 获取:
pl阶段获取 pl/lk的version。 需要在校验完LK img后可以呼叫获取:
获取pl ver api:seclib_get_pl_ver
获取LK ver api:get_img_ver
LK阶段获取modem 的img ver:
api: get_img_ver
MTK:
/vendor/mediatek/proprietary/bootable/bootloader/lk/platform/common/avb/libavb/avb_slot_verify.c
io_ret = ops->read_rollback_index(ops, rollback_index_location, &stored_rollback_index);
这里会根据rollback_index_location来读anti-rollback值
/vendor/mediatek/proprietary/bootable/bootloader/lk/platform/common/boot/avb20/load_vfy_boot.c
int load_vfy_boot(uint32_t bootimg_type, uint32_t addr)函数
ret = record_avb_version(slot_data);
这里会在验证AVB结束后更新anti-rollback ver。
set_avb_otp_ver(AVB_GROUP, (uint32_t)min_ver);
#define AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS 32
qcom:
LINUX/android/external/u-boot/common/avb_verify.c
virtual AvbIOResult read_rollback_index(AvbOps* ops,
size_t rollback_index_slot,
uint64_t* out_rollback_index) = 0;
virtual AvbIOResult write_rollback_index(AvbOps* ops,
size_t rollback_index_slot,
uint64_t rollback_index) = 0;
memset(param, 0, sizeof(param));
param[0].attr = TEE_PARAM_ATTR_TYPE_VALUE_INPUT;
param[0].u.value.a = rollback_index_slot;
param[1].attr = TEE_PARAM_ATTR_TYPE_VALUE_INPUT;
param[1].u.value.a = (u32)(rollback_index >> 32);
param[1].u.value.b = (u32)rollback_index;
return invoke_func(ops->user_data, TA_AVB_CMD_WRITE_ROLLBACK_INDEX,
ARRAY_SIZE(param), param);