From 5beb1d8b0d25d64be2cb1cd1d381980141606bb6 Mon Sep 17 00:00:00 2001 From: bmax Date: Sun, 17 Mar 2024 23:14:05 +0800 Subject: [PATCH 1/3] 1. fix kallsym: find kallsyms_marker error, newest oneplus12 (not noly oneplus12) is ok now, 2. try to fix module install os error 22 or 5, I'm not sure --- kernel/patch/android/userd.c | 2 +- tools/kallsym.c | 44 +++++++++++++++++++++++++++++++++++- tools/patch.c | 3 ++- version | 2 +- 4 files changed, 47 insertions(+), 4 deletions(-) diff --git a/kernel/patch/android/userd.c b/kernel/patch/android/userd.c index c9bd8fe8..1a47bea5 100644 --- a/kernel/patch/android/userd.c +++ b/kernel/patch/android/userd.c @@ -251,7 +251,7 @@ static void after_execveat(hook_fargs5_t *args, void *udata) handle_after_execve(&args->local); } -#define ORIGIN_RC_FILE "/init.environ.rc" +#define ORIGIN_RC_FILE "/system/etc/init/atrace.rc" #define REPLACE_RC_FILE "/dev/anduser.rc" static const char user_rc_data[] = { // diff --git a/tools/kallsym.c b/tools/kallsym.c index cfecb7ac..c8ca6581 100644 --- a/tools/kallsym.c +++ b/tools/kallsym.c @@ -445,7 +445,7 @@ static int find_num_syms(kallsym_t *info, char *img, int32_t imglen) return 0; } -static int find_markers(kallsym_t *info, char *img, int32_t imglen) +static int find_markers_1(kallsym_t *info, char *img, int32_t imglen) { int32_t elem_size = get_markers_elem_size(info); int32_t cand = info->kallsyms_token_table_offset - elem_size; @@ -472,6 +472,48 @@ static int find_markers(kallsym_t *info, char *img, int32_t imglen) return 0; } +static int find_markers_2(kallsym_t *info, char *img, int32_t imglen) +{ + int32_t elem_size = get_markers_elem_size(info); + int32_t cand = info->kallsyms_token_table_offset - KSYM_MIN_MARKER * elem_size; + + int64_t marker, last_marker = 0x7fffffff; + int count = 0; + while (cand > 0x1000) { + marker = int_unpack(img + cand, elem_size, info->is_be); + if (last_marker > marker) { + count++; + if (!marker && count > KSYM_MIN_MARKER) break; + } else { + count = 0; + last_marker = 0x7fffffff; + } + + last_marker = marker; + cand -= elem_size; + } + + if (count < KSYM_MIN_MARKER) { + tools_logw("find kallsyms_markers error\n"); + return -1; + } + + int32_t marker_end = cand + count * elem_size + elem_size; + info->kallsyms_markers_offset = cand; + info->_marker_num = count; + + tools_logi("kallsyms_markers range: [0x%08x, 0x%08x), count: 0x%08x\n", cand, marker_end, count); + return 0; +} + +static inline int find_markers(kallsym_t *info, char *img, int32_t imglen) +{ + // todo: remove one + int rc = find_markers_1(info, img, imglen); + if (!rc) return rc; + return find_markers_2(info, img, imglen); +} + static int decompress_symbol_name(kallsym_t *info, char *img, int32_t *pos_to_next, char *out_type, char *out_symbol) { int32_t pos = *pos_to_next; diff --git a/tools/patch.c b/tools/patch.c index 21599100..0e1c01e9 100644 --- a/tools/patch.c +++ b/tools/patch.c @@ -207,11 +207,12 @@ int print_image_patch_info(patched_kimg_t *pimg) if (pimg->banner[strlen(pimg->banner) - 1] != '\n') fprintf(stdout, "\n"); fprintf(stdout, "patched=%s\n", preset ? "true" : "false"); - fprintf(stdout, "extra_num=%d\n", pimg->embed_item_num); if (preset) { print_preset_info(preset); + fprintf(stdout, "extra_num=%d\n", pimg->embed_item_num); + fprintf(stdout, INFO_EXTRA_SESSION "\n"); fprintf(stdout, "num=%d\n", pimg->embed_item_num); diff --git a/version b/version index 20b53d0c..3daf75d1 100644 --- a/version +++ b/version @@ -1,3 +1,3 @@ #define MAJOR 0 #define MINOR 10 -#define PATCH 3 +#define PATCH 4 From 5d2f2a761be3034b230f85caf7f3c0c83454fbb8 Mon Sep 17 00:00:00 2001 From: 4qwerty7 <4qwerty7@163.com> Date: Thu, 21 Mar 2024 11:32:36 +0800 Subject: [PATCH 2/3] Fix the logic for processing the "UNCOMPRESSED_IMG" header(fix #72) (#73) * fix incorrect uncompressed img header process logic * fix some error in previous commit * seal all uncomrpessed_img logic * clean code --- tools/image.c | 15 ++--- tools/image.h | 1 - tools/kallsym.c | 17 ------ tools/kallsym.h | 2 - tools/patch.c | 149 ++++++++++++++++++++++++++++++++---------------- tools/patch.h | 13 +++++ 6 files changed, 116 insertions(+), 81 deletions(-) diff --git a/tools/image.c b/tools/image.c index 6428377f..1d76c4f4 100644 --- a/tools/image.c +++ b/tools/image.c @@ -56,16 +56,9 @@ typedef struct int32_t get_kernel_info(kernel_info_t *kinfo, const char *img, int32_t imglen) { - kinfo->img_offset = 0; - - if (!strncmp("UNCOMPRESSED_IMG", img, strlen("UNCOMPRESSED_IMG"))) { - kinfo->img_offset = 0x14; - tools_logw("kernel image with UNCOMPRESSED_IMG header\n"); - } - kinfo->is_be = 0; - arm64_hdr_t *khdr = (arm64_hdr_t *)(img + kinfo->img_offset); + arm64_hdr_t *khdr = (arm64_hdr_t *)img; if (strncmp(khdr->magic, KERNEL_MAGIC, strlen(KERNEL_MAGIC))) { tools_loge_exit("kernel image magic error: %s\n", khdr->magic); } @@ -76,10 +69,10 @@ int32_t get_kernel_info(kernel_info_t *kinfo, const char *img, int32_t imglen) uint32_t b_stext_insn_offset; if (kinfo->uefi) { b_primary_entry_insn = khdr->hdr.efi.b_insn; - b_stext_insn_offset = 4 + kinfo->img_offset; + b_stext_insn_offset = 4; } else { b_primary_entry_insn = khdr->hdr.nefi.b_insn; - b_stext_insn_offset = 0 + kinfo->img_offset; + b_stext_insn_offset = 0; } kinfo->b_stext_insn_offset = b_stext_insn_offset; @@ -122,7 +115,7 @@ int32_t get_kernel_info(kernel_info_t *kinfo, const char *img, int32_t imglen) int32_t kernel_resize(kernel_info_t *kinfo, char *img, int32_t size) { - arm64_hdr_t *khdr = (arm64_hdr_t *)(img + kinfo->img_offset); + arm64_hdr_t *khdr = (arm64_hdr_t *)img; uint64_t ksize = size; if (is_be() ^ kinfo->is_be) ksize = u64swp(size); khdr->kernel_size_le = ksize; diff --git a/tools/image.h b/tools/image.h index 2a3106b6..ebb81dbb 100644 --- a/tools/image.h +++ b/tools/image.h @@ -14,7 +14,6 @@ typedef struct { int8_t is_be; // 0: little, 1: big int8_t uefi; // - int32_t img_offset; int32_t load_offset; int32_t kernel_size; int32_t page_shift; diff --git a/tools/kallsym.c b/tools/kallsym.c index c8ca6581..82fd6c62 100644 --- a/tools/kallsym.c +++ b/tools/kallsym.c @@ -816,13 +816,6 @@ int analyze_kallsym_info(kallsym_t *info, char *img, int32_t imglen, enum arch_t if (arch == ARM64) info->try_relo = 1; if (is_64) info->asm_PTR_size = 8; - info->img_offset = 0; - if (!strncmp("UNCOMPRESSED_IMG", img, strlen("UNCOMPRESSED_IMG"))) { - info->img_offset = 0x14; - } - img += info->img_offset; - imglen -= info->img_offset; - int rc = -1; static int32_t (*base_funcs[])(kallsym_t *, char *, int32_t) = { find_linux_banner, @@ -856,8 +849,6 @@ int analyze_kallsym_info(kallsym_t *info, char *img, int32_t imglen, enum arch_t int32_t get_symbol_index_offset(kallsym_t *info, char *img, int32_t index) { - img = img + info->img_offset; - int32_t elem_size; int32_t pos; if (info->has_relative_base) { @@ -874,8 +865,6 @@ int32_t get_symbol_index_offset(kallsym_t *info, char *img, int32_t index) int get_symbol_offset_and_size(kallsym_t *info, char *img, char *symbol, int32_t *size) { - img = img + info->img_offset; - char decomp[KSYM_SYMBOL_LEN] = { '\0' }; char type = 0; *size = 0; @@ -904,8 +893,6 @@ int get_symbol_offset_and_size(kallsym_t *info, char *img, char *symbol, int32_t int get_symbol_offset(kallsym_t *info, char *img, char *symbol) { - img = img + info->img_offset; - char decomp[KSYM_SYMBOL_LEN] = { '\0' }; char type = 0; char **tokens = info->kallsyms_token_table; @@ -925,8 +912,6 @@ int get_symbol_offset(kallsym_t *info, char *img, char *symbol) int dump_all_symbols(kallsym_t *info, char *img) { - img = img + info->img_offset; - char symbol[KSYM_SYMBOL_LEN] = { '\0' }; char type = 0; char **tokens = info->kallsyms_token_table; @@ -943,8 +928,6 @@ int dump_all_symbols(kallsym_t *info, char *img) int on_each_symbol(kallsym_t *info, char *img, void *userdata, int32_t (*fn)(int32_t index, char type, const char *symbol, int32_t offset, void *userdata)) { - img = img + info->img_offset; - char symbol[KSYM_SYMBOL_LEN] = { '\0' }; char type = 0; char **tokens = info->kallsyms_token_table; diff --git a/tools/kallsym.h b/tools/kallsym.h index 82ffb310..4643b162 100644 --- a/tools/kallsym.h +++ b/tools/kallsym.h @@ -63,8 +63,6 @@ typedef struct int32_t is_64; int32_t is_be; - int32_t img_offset; - struct { uint8_t _; diff --git a/tools/patch.c b/tools/patch.c index 0e1c01e9..8019845c 100644 --- a/tools/patch.c +++ b/tools/patch.c @@ -23,6 +23,50 @@ #include "symbol.h" #include "kpm.h" +void read_kernel_file(const char *path, kernel_file_t *kernel_file) +{ + int img_offset = 0; + read_file(path, &kernel_file->kfile, &kernel_file->kfile_len); + kernel_file->is_uncompressed_img = kernel_file->kfile_len >= 20 && !strncmp("UNCOMPRESSED_IMG", kernel_file->kfile, 16); + if (kernel_file->is_uncompressed_img) img_offset = 20; + kernel_file->kimg = kernel_file->kfile + img_offset; + kernel_file->kimg_len = kernel_file->kfile_len - img_offset; +} + +void update_kernel_file_img_len(kernel_file_t *kernel_file, int kimg_len, bool is_different_endian) +{ + kernel_file->kimg_len = kimg_len; + if (kernel_file->is_uncompressed_img) { + *(uint32_t *)(kernel_file->kfile + 16) = (uint32_t)(is_different_endian ? i32swp(kimg_len) : kimg_len); + kernel_file->kfile_len = kimg_len + 20; + } else { + kernel_file->kfile_len = kimg_len; + } +} + +void new_kernel_file(kernel_file_t *kernel_file, kernel_file_t *old, int kimg_len, bool is_different_endian) +{ + int prefix_len = old->kimg - old->kfile; + int new_len = kimg_len + prefix_len; + kernel_file->kfile = (char *)malloc(new_len); + kernel_file->kimg = kernel_file->kfile + prefix_len; + memcpy(kernel_file->kfile, old->kfile, prefix_len); + kernel_file->is_uncompressed_img = old->is_uncompressed_img; + update_kernel_file_img_len(kernel_file, kimg_len, is_different_endian); +} + +void write_kernel_file(kernel_file_t *kernel_file, const char *path) +{ + write_file(path, kernel_file->kfile, kernel_file->kfile_len, false); +} + +void free_kernel_file(kernel_file_t *kernel_file) +{ + free(kernel_file->kfile); + kernel_file->kfile = NULL; + kernel_file->kimg = NULL; +} + preset_t *get_preset(const char *kimg, int kimg_len) { char magic[MAGIC_LEN] = KP_MAGIC; @@ -188,11 +232,10 @@ int parse_image_patch_info_path(const char *kimg_path, patched_kimg_t *pimg) { if (!kimg_path) tools_loge_exit("empty kernel image\n"); - char *kimg; - int kimg_len; - read_file(kimg_path, &kimg, &kimg_len); - int rc = parse_image_patch_info(kimg, kimg_len, pimg); - free(kimg); + kernel_file_t kernel_file; + read_kernel_file(kimg_path, &kernel_file); + int rc = parse_image_patch_info(kernel_file.kimg, kernel_file.kimg_len, pimg); + free_kernel_file(&kernel_file); return rc; } @@ -247,12 +290,11 @@ int print_image_patch_info(patched_kimg_t *pimg) int print_image_patch_info_path(const char *kimg_path) { patched_kimg_t pimg = { 0 }; - char *kimg; - int kimg_len; - read_file(kimg_path, &kimg, &kimg_len); - int rc = parse_image_patch_info(kimg, kimg_len, &pimg); + kernel_file_t kernel_file; + read_kernel_file(kimg_path, &kernel_file); + int rc = parse_image_patch_info(kernel_file.kimg, kernel_file.kimg_len, &pimg); print_image_patch_info(&pimg); - free(kimg); + free_kernel_file(&kernel_file); return rc; } @@ -263,6 +305,12 @@ static int extra_compare(const void *a, const void *b) return -(pa->priority - pb->priority); } +static void extra_append(char *kimg, const void *data, int len, int *offset) +{ + memcpy(kimg + *offset, data, len); + *offset += len; +} + int patch_update_img(const char *kimg_path, const char *kpimg_path, const char *out_path, const char *superkey, const char **additional, const char *kpatch_path, extra_config_t *extra_configs, int extra_config_num) @@ -274,10 +322,11 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * if (!superkey) tools_loge_exit("empty superkey\n"); patched_kimg_t pimg = { 0 }; - char *kimg; - int kimg_len; - read_file(kimg_path, &kimg, &kimg_len); - int rc = parse_image_patch_info(kimg, kimg_len, &pimg); + kernel_file_t kernel_file; + read_kernel_file(kimg_path, &kernel_file); + if (kernel_file.is_uncompressed_img) tools_logw("kernel image with UNCOMPRESSED_IMG header\n"); + + int rc = parse_image_patch_info(kernel_file.kimg, kernel_file.kimg_len, &pimg); if (rc) tools_loge_exit("parse kernel image error\n"); // print_image_patch_info(&pimg); @@ -404,13 +453,14 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * tools_logi("layout kimg: 0x0-0x%x, kpimg: 0x%x,0x%x, extra: 0x%x,0x%x, end: 0x%x, start: 0x%x\n", ori_kimg_len, align_kimg_len, kpimg_len, out_img_len, extra_size, out_all_len, start_offset); - char *out_img = (char *)malloc(out_img_len); - memcpy(out_img, pimg.kimg, ori_kimg_len); - memset(out_img + ori_kimg_len, 0, align_kimg_len - ori_kimg_len); - memcpy(out_img + align_kimg_len, kpimg, kpimg_len); + kernel_file_t out_kernel_file; + new_kernel_file(&out_kernel_file, &kernel_file, out_all_len, (bool)(is_be() ^ kinfo->is_be)); + memcpy(out_kernel_file.kimg, pimg.kimg, ori_kimg_len); + memset(out_kernel_file.kimg + ori_kimg_len, 0, align_kimg_len - ori_kimg_len); + memcpy(out_kernel_file.kimg + align_kimg_len, kpimg, kpimg_len); // set preset - preset_t *preset = (preset_t *)(out_img + align_kimg_len); + preset_t *preset = (preset_t *)(out_kernel_file.kimg + align_kimg_len); setup_header_t *header = &preset->header; version_t ver = header->kp_version; @@ -479,7 +529,7 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * int paging_init_offset = get_symbol_offset_exit(&kallsym, kallsym_kimg, "paging_init"); setup->paging_init_offset = relo_branch_func(kallsym_kimg, paging_init_offset); int text_offset = align_kimg_len + SZ_4K; - b((uint32_t *)(out_img + kinfo->b_stext_insn_offset), kinfo->b_stext_insn_offset, text_offset); + b((uint32_t *)(out_kernel_file.kimg + kinfo->b_stext_insn_offset), kinfo->b_stext_insn_offset, text_offset); // additional [len key=value] set char *addition_pos = setup->additional; @@ -500,10 +550,8 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * addition_pos += kvlen; } - // write out - write_file(out_path, out_img, out_img_len, false); - - // write extra + // append extra + int current_offset = out_img_len; for (int i = 0; i < extra_config_num; i++) { extra_config_t *config = extra_configs + i; patch_extra_item_t *item = config->item; @@ -522,20 +570,22 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * item->args_size = i32swp(item->args_size); } - write_file(out_path, (void *)item, sizeof(*item), true); - if (args_len > 0) write_file(out_path, (void *)config->set_args, args_len, true); - write_file(out_path, (void *)config->data, con_len, true); + extra_append(out_kernel_file.kimg, (void *)item, sizeof(*item), ¤t_offset); + if (args_len > 0) extra_append(out_kernel_file.kimg, (void *)config->set_args, args_len, ¤t_offset); + extra_append(out_kernel_file.kimg, (void *)config->data, con_len, ¤t_offset); } // guard extra patch_extra_item_t empty_item = { 0 }; - write_file(out_path, (void *)&empty_item, sizeof(empty_item), true); + extra_append(out_kernel_file.kimg, (void *)&empty_item, sizeof(empty_item), ¤t_offset); + + write_kernel_file(&out_kernel_file, out_path); // free free(kallsym_kimg); free(kpimg); - free(out_img); - free(kimg); + free_kernel_file(&out_kernel_file); + free_kernel_file(&kernel_file); tools_logi("patch done: %s\n", out_path); @@ -548,18 +598,19 @@ int unpatch_img(const char *kimg_path, const char *out_path) if (!kimg_path) tools_loge_exit("empty kernel image\n"); if (!out_path) tools_loge_exit("empty out image path\n"); - char *kimg = NULL; - int kimg_len = 0; - read_file(kimg_path, &kimg, &kimg_len); + kernel_file_t kernel_file; + read_kernel_file(kimg_path, &kernel_file); - preset_t *preset = get_preset(kimg, kimg_len); + preset_t *preset = get_preset(kernel_file.kimg, kernel_file.kimg_len); if (!preset) tools_loge_exit("not patched kernel image\n"); - memcpy(kimg, preset->setup.header_backup, sizeof(preset->setup.header_backup)); - int kimg_size = preset->setup.kimg_size ?: ((char *)preset - kimg); + // todo: check whether the endian is different or not + memcpy(kernel_file.kimg, preset->setup.header_backup, sizeof(preset->setup.header_backup)); + int kimg_size = preset->setup.kimg_size ?: ((char *)preset - kernel_file.kimg); + update_kernel_file_img_len(&kernel_file, kimg_size, false); - write_file(out_path, kimg, kimg_size, false); - free(kimg); + write_kernel_file(&kernel_file, out_path); + free_kernel_file(&kernel_file); return 0; } @@ -572,21 +623,20 @@ int reset_key(const char *kimg_path, const char *out_path, const char *superkey) if (strlen(superkey) <= 0) tools_loge_exit("empty superkey\n"); if (strlen(superkey) >= SUPER_KEY_LEN) tools_loge_exit("too long superkey\n"); - char *kimg = NULL; - int kimg_len = 0; - read_file(kimg_path, &kimg, &kimg_len); + kernel_file_t kernel_file; + read_kernel_file(kimg_path, &kernel_file); - preset_t *preset = get_preset(kimg, kimg_len); + preset_t *preset = get_preset(kernel_file.kimg, kernel_file.kimg_len); if (!preset) tools_loge_exit("not patched kernel image\n"); char *origin_key = strdup((char *)preset->setup.superkey); strcpy((char *)preset->setup.superkey, superkey); tools_logi("reset superkey: %s -> %s\n", origin_key, preset->setup.superkey); - write_file(out_path, kimg, kimg_len, false); + write_kernel_file(&kernel_file, out_path); free(origin_key); - free(kimg); + free_kernel_file(&kernel_file); return 0; } @@ -596,17 +646,16 @@ int dump_kallsym(const char *kimg_path) if (!kimg_path) tools_loge_exit("empty kernel image\n"); set_log_enable(true); // read image files - char *kimg = NULL; - int kimg_len = 0; - read_file(kimg_path, &kimg, &kimg_len); + kernel_file_t kernel_file; + read_kernel_file(kimg_path, &kernel_file); kallsym_t kallsym; - if (analyze_kallsym_info(&kallsym, kimg, kimg_len, ARM64, 1)) { + if (analyze_kallsym_info(&kallsym, kernel_file.kimg, kernel_file.kimg_len, ARM64, 1)) { fprintf(stdout, "analyze_kallsym_info error\n"); return -1; } - dump_all_symbols(&kallsym, kimg); + dump_all_symbols(&kallsym, kernel_file.kimg); set_log_enable(false); - free(kimg); + free_kernel_file(&kernel_file); return 0; } \ No newline at end of file diff --git a/tools/patch.h b/tools/patch.h index d0a0a009..fb1f73b8 100644 --- a/tools/patch.h +++ b/tools/patch.h @@ -50,6 +50,19 @@ typedef struct patch_extra_item_t *item; } extra_config_t; +typedef struct +{ + char *kfile, *kimg; + int kfile_len, kimg_len; + bool is_uncompressed_img; +} kernel_file_t; + +void read_kernel_file(const char *path, kernel_file_t *kernel_file); +void new_kernel_file(kernel_file_t *kernel_file, kernel_file_t *old, int kimg_len, bool is_different_endian); +void update_kernel_file_img_len(kernel_file_t *kernel_file, int kimg_len, bool is_different_endian); +void write_kernel_file(kernel_file_t *kernel_file, const char *path); +void free_kernel_file(kernel_file_t *kernel_file); + preset_t *get_preset(const char *kimg, int kimg_len); uint32_t get_kpimg_version(const char *kpimg_path); From 4ab1c3aa8fbb4e1490807822c70daa601b83bcad Mon Sep 17 00:00:00 2001 From: SK <33929605+sekaiacg@users.noreply.github.com> Date: Mon, 25 Mar 2024 19:48:27 +0800 Subject: [PATCH 3/3] kptools: Skip relocation when trying again (#76) Signed-off-by: sekaiacg --- tools/kallsym.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/tools/kallsym.c b/tools/kallsym.c index 82fd6c62..8cb459fd 100644 --- a/tools/kallsym.c +++ b/tools/kallsym.c @@ -254,6 +254,7 @@ static int try_find_arm64_relo_table(kallsym_t *info, char *img, int32_t imglen) tools_logi("find arm64 relocation table range: [0x%08x, 0x%08x), count: 0x%08x\n", cand_start, cand_end, rela_num); // apply relocations + int32_t max_offset = imglen - 8; int32_t apply_num = 0; for (cand = cand_start; cand < cand_end; cand += 24) { uint64_t r_offset = uint_unpack(img + cand, 8, info->is_be); @@ -264,11 +265,14 @@ static int try_find_arm64_relo_table(kallsym_t *info, char *img, int32_t imglen) // tools_logw("warn ignore arm64 relocation r_offset: 0x%08lx at 0x%08x\n", r_offset, cand); continue; } + int32_t offset = r_offset - kernel_va; - if (offset >= imglen) { - // tools_logw("apply relocations error\n"); - continue; + if (offset < 0 || offset >= max_offset) { + tools_logw("bad rela offset: 0x%08lx\n", r_offset); + info->try_relo = 0; + return -1; } + uint64_t value = uint_unpack(img + offset, 8, info->is_be); if (value == r_addend) continue; *(uint64_t *)(img + offset) = value + r_addend; @@ -834,11 +838,17 @@ int analyze_kallsym_info(kallsym_t *info, char *img, int32_t imglen, enum arch_t if (!rc) goto out; // 2nd + if (!info->try_relo) { + memcpy(copied_img, img, imglen); + rc = retry_relo_retry(info, copied_img, imglen); + if (!rc) goto out; + } + + // 3rd if (info->elf64_kernel_base != ELF64_KERNEL_MIN_VA) { info->elf64_kernel_base = ELF64_KERNEL_MIN_VA; memcpy(copied_img, img, imglen); rc = retry_relo_retry(info, copied_img, imglen); - if (!rc) goto out; } out: