Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions kernel/base/hook.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,18 +58,18 @@ typedef uint32_t inst_mask_t;
#define MASK_HINT 0xFFFFF01F
#define MASK_IGNORE 0x0

static inst_mask_t masks[] = {
static const inst_mask_t masks[] = {
MASK_B, MASK_BC, MASK_BL, MASK_ADR, MASK_ADRP, MASK_LDR_32,
MASK_LDR_64, MASK_LDRSW_LIT, MASK_PRFM_LIT, MASK_LDR_SIMD_32, MASK_LDR_SIMD_64, MASK_LDR_SIMD_128,
MASK_CBZ, MASK_CBNZ, MASK_TBZ, MASK_TBNZ, MASK_IGNORE,
};
static inst_type_t types[] = {
static const inst_type_t types[] = {
INST_B, INST_BC, INST_BL, INST_ADR, INST_ADRP, INST_LDR_32,
INST_LDR_64, INST_LDRSW_LIT, INST_PRFM_LIT, INST_LDR_SIMD_32, INST_LDR_SIMD_64, INST_LDR_SIMD_128,
INST_CBZ, INST_CBNZ, INST_TBZ, INST_TBNZ, INST_IGNORE,
};

static int32_t relo_len[] = { 6, 8, 8, 4, 4, 6, 6, 6, 8, 8, 8, 8, 6, 6, 6, 6, 2 };
static const int32_t relo_len[] = { 6, 8, 8, 4, 4, 6, 6, 6, 8, 8, 8, 8, 6, 6, 6, 6, 2 };

// static uint64_t sign_extend(uint64_t x, uint32_t len)
// {
Expand Down
26 changes: 1 addition & 25 deletions kernel/include/preset.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,30 +197,6 @@ _Static_assert(sizeof(patch_extra_item_t) == PATCH_EXTRA_ITEM_LEN, "sizeof patch

#ifndef __ASSEMBLY__

// TODO: remove
typedef struct
{
version_t kernel_version;
int32_t _;
int64_t kimg_size; // must aligned
int64_t kpimg_size; // must aligned
int64_t kernel_size; // must aligned
int64_t page_shift;
int64_t setup_offset; // must aligned
int64_t start_offset; // must aligned
int64_t extra_size; // must aligned
int64_t map_offset; // must aligned MAP_ALIGN
int64_t map_max_size;
int64_t kallsyms_lookup_name_offset;
int64_t paging_init_offset;
int64_t printk_offset;
map_symbol_t map_symbol;
uint8_t header_backup[HDR_BACKUP_SIZE];
uint8_t superkey[SUPER_KEY_LEN];
patch_config_t patch_config;
char additional[ADDITIONAL_LEN];
} setup_preset_be_000a04_t;

typedef struct _setup_preset_t
{
version_t kernel_version;
Expand Down Expand Up @@ -275,4 +251,4 @@ typedef struct
} preset_t;
#endif

#endif // _KP_PRESET_H_
#endif // _KP_PRESET_H_
32 changes: 28 additions & 4 deletions tools/kallsym.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,21 @@ static void *memmem(const void *haystack, size_t haystack_len, const void *const
}
#endif

static void record_linux_banner_offset(kallsym_t *info, int32_t offset)
{
const int32_t max = (int32_t)ARRAY_SIZE(info->linux_banner_offset);

if (info->banner_num < max) {
info->linux_banner_offset[info->banner_num++] = offset;
return;
}

for (int32_t i = 1; i < max; i++) {
info->linux_banner_offset[i - 1] = info->linux_banner_offset[i];
}
info->linux_banner_offset[max - 1] = offset;
}

static int find_linux_banner(kallsym_t *info, char *img, int32_t imglen)
{
/*
Expand All @@ -59,12 +74,18 @@ static int find_linux_banner(kallsym_t *info, char *img, int32_t imglen)
char *banner = (char *)img;
info->banner_num = 0;
while ((banner = (char *)memmem(banner + 1, imgend - banner - 1, linux_banner_prefix, prefix_len)) != NULL) {
if (isdigit(*(banner + prefix_len)) && *(banner + prefix_len + 1) == '.') {
info->linux_banner_offset[info->banner_num++] = (int32_t)(banner - img);
size_t remaining = (size_t)(imgend - banner);
if (remaining <= prefix_len + 1) continue;
if (isdigit((unsigned char)banner[prefix_len]) && banner[prefix_len + 1] == '.') {
record_linux_banner_offset(info, (int32_t)(banner - img));
tools_logi("linux_banner %d: %s", info->banner_num, banner);
tools_logi("linux_banner offset: 0x%lx\n", banner - img);
}
}
if (info->banner_num <= 0) {
tools_loge("can't find linux banner\n");
return -1;
}
banner = img + info->linux_banner_offset[info->banner_num - 1];

char *uts_release_start = banner + prefix_len;
Expand Down Expand Up @@ -94,10 +115,13 @@ int kernel_if_need_patch(kallsym_t *info, char *img, int32_t imglen)
char *banner = (char *)img;
info->banner_num = 0;
while ((banner = (char *)memmem(banner + 1, imgend - banner - 1, linux_banner_prefix, prefix_len)) != NULL) {
if (isdigit(*(banner + prefix_len)) && *(banner + prefix_len + 1) == '.') {
info->linux_banner_offset[info->banner_num++] = (int32_t)(banner - img);
size_t remaining = (size_t)(imgend - banner);
if (remaining <= prefix_len + 1) continue;
if (isdigit((unsigned char)banner[prefix_len]) && banner[prefix_len + 1] == '.') {
record_linux_banner_offset(info, (int32_t)(banner - img));
}
}
if (info->banner_num <= 0) tools_loge_exit("can't find linux banner\n");
banner = img + info->linux_banner_offset[info->banner_num - 1];

char *uts_release_start = banner + prefix_len;
Expand Down
48 changes: 28 additions & 20 deletions tools/patch.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,13 @@ uint32_t get_kpimg_version(const char *kpimg_path)
int kpimg_len = 0;
read_file(kpimg_path, &kpimg, &kpimg_len);
preset_t *preset = get_preset(kpimg, kpimg_len);
if (!preset) tools_loge_exit("not patched kernel image\n");
if (!preset) {
free(kpimg);
tools_loge_exit("not patched kernel image\n");
}
version_t ver = preset->header.kp_version;
uint32_t version = (ver.major << 16) + (ver.minor << 8) + ver.patch;
free(kpimg);
return version;
}

Expand Down Expand Up @@ -125,11 +129,16 @@ const char *extra_type_str(extra_item_type extra_type)

static char *bytes_to_hexstr(const unsigned char *data, int len)
{
char *buf = (char *)malloc(2 * len + 1);
buf[2 * len] = '\0';
enum { HEX_CHARS_PER_BYTE = 2 };
static const char hex_digits[] = "0123456789abcdef";

char *buf = (char *)malloc((size_t)len * HEX_CHARS_PER_BYTE + 1);
for (int i = 0; i < len; i++) {
sprintf(&buf[2 * i], "%02x", data[i]);
unsigned char byte = data[i];
buf[i * HEX_CHARS_PER_BYTE] = hex_digits[byte >> 4];
buf[i * HEX_CHARS_PER_BYTE + 1] = hex_digits[byte & 0x0F];
}
buf[len * HEX_CHARS_PER_BYTE] = '\0';
return buf;
}

Expand All @@ -148,19 +157,12 @@ void print_preset_info(preset_t *preset)
fprintf(stdout, "config=%s,%s\n", is_android ? "android" : "linux", is_debug ? "debug" : "release");
fprintf(stdout, "superkey=%s\n", setup->superkey);

// todo: remove compat version
if (ver_num > 0xa04) {
char *hexstr = bytes_to_hexstr(setup->root_superkey, ROOT_SUPER_KEY_HASH_LEN);
fprintf(stdout, "root_superkey=%s\n", hexstr);
free(hexstr);
}
char *hexstr = bytes_to_hexstr(setup->root_superkey, ROOT_SUPER_KEY_HASH_LEN);
fprintf(stdout, "root_superkey=%s\n", hexstr);
free(hexstr);

fprintf(stdout, INFO_ADDITIONAL_SESSION "\n");
char *addition = setup->additional;
// todo: remove compat version
if (ver_num <= 0xa04) {
addition -= (ROOT_SUPER_KEY_HASH_LEN + SETUP_PRESERVE_LEN);
}
char *pos = addition;
while (pos < addition + ADDITIONAL_LEN) {
int len = *pos;
Expand All @@ -177,7 +179,7 @@ void print_preset_info(preset_t *preset)
int print_kp_image_info_path(const char *kpimg_path)
{
int rc = 0;
char *kpimg;
char *kpimg = NULL;
int len = 0;
read_file(kpimg_path, &kpimg, &len);
preset_t *preset = (preset_t *)kpimg;
Expand All @@ -186,8 +188,8 @@ int print_kp_image_info_path(const char *kpimg_path)
} else {
print_preset_info(preset);
fprintf(stdout, "\n");
free(kpimg);
}
free(kpimg);
return rc;
}

Expand All @@ -204,12 +206,18 @@ int parse_image_patch_info(const char *kimg, int kimg_len, patched_kimg_t *pimg)
char linux_banner_prefix[] = "Linux version ";
size_t prefix_len = strlen(linux_banner_prefix);
const char *imgend = pimg->kimg + pimg->kimg_len;
const char *banner = (char *)pimg->kimg;
while ((banner = (char *)memmem(banner + 1, imgend - banner, linux_banner_prefix, prefix_len)) != NULL) {
if (isdigit(*(banner + prefix_len)) && *(banner + prefix_len + 1) == '.') {
const char *search = pimg->kimg;
if (search < imgend) search++;
while (search < imgend) {
size_t search_len = (size_t)(imgend - search);
const char *banner = (const char *)memmem(search, search_len, linux_banner_prefix, prefix_len);
if (!banner) break;
size_t remaining = (size_t)(imgend - banner);
if (remaining > prefix_len + 1 && isdigit((unsigned char)banner[prefix_len]) && banner[prefix_len + 1] == '.') {
pimg->banner = banner;
break;
}
search = banner + 1;
}
if (!pimg->banner) tools_loge_exit("can't find linux banner\n");

Expand Down Expand Up @@ -771,4 +779,4 @@ int dump_ikconfig(const char *kimg_path)
set_log_enable(false);
free_kernel_file(&kernel_file);
return 0;
}
}