模块加载失败unknown symbol: memset
内核日志: [26821.176645] [+] KP D load_module_path: /data/local/tmp/mod_main.kpm [26821.176674] [+] KP D load_module_path: module size: 8668 [26821.176714] [+] KP D loading module: [26821.176714] [+] KP D name: IO Redirect [26821.176715] [+] KP D version: 1.0.0 [26821.176716] [+] KP D license: (null) [26821.176716] [+] KP D author: yuuki [26821.176717] [+] KP D description: Prevent your phone from being maliciously formatted [26821.176730] [+] KP I alloc module size: 3935 [26821.176735] [+] KP D final section addresses: [26821.176735] [+] KP D .text ffffffe4ec1c3130 5e4 [26821.176736] [+] KP D .rodata.str1.8 ffffffe4ec1c4130 325 [26821.176737] [+] KP D .kpm.info ffffffe4ec1c4455 6c [26821.176738] [+] KP D .data ffffffe4ec1c5130 10 [26821.176738] [+] KP D .kpm.ctl0 ffffffe4ec1c5140 8 [26821.176739] [+] KP D .kpm.exit ffffffe4ec1c5148 8 [26821.176739] [+] KP D .kpm.init ffffffe4ec1c5150 8 [26821.176740] [+] KP D .bss ffffffe4ec1c5158 50 [26821.176740] [+] KP D .symtab ffffffe4ec1c6130 648 [26821.176741] [+] KP D .strtab ffffffe4ec1c6896 1cf [26821.176743] [-] KP E unknown symbol: memset
代码: #include "data_parse.h"
char *my_strdup(const char *src) { if (src == NULL) { return NULL; }
size_t len = strlen(src) + 1;
char *copy = (char*)kf_vmalloc(len);
if (copy == NULL) {
return NULL;
}
memcpy(copy, src, len);
return copy;
}
char *my_strtok(char *str, const char *delim) { static char *saved_str = NULL; char *start = NULL; char *end = NULL;
if (str != NULL) {
saved_str = str;
}
if (saved_str == NULL) {
return NULL;
}
start = saved_str;
while (*start && strchr(delim, *start) != NULL) {
start++;
}
if (*start == '\0') {
saved_str = NULL;
return NULL;
}
end = start;
while (*end && strchr(delim, *end) == NULL) {
end++;
}
if (*end != '\0') {
*end = '\0';
saved_str = end + 1;
} else {
saved_str = NULL;
}
return start;
}
void parsePaths(const char *input, char source_path[][PATH_MAX], char redirect_path[][PATH_MAX], int *line_count) { char *temp = my_strdup(input); char *line = my_strtok(temp, "\n"); *line_count = 0;
while (line != NULL) {
char *arrow = strstr(line, " -> ");
if (arrow != NULL) {
// 分隔符前后的路径
size_t path_len = arrow - line;
strncpy(source_path[*line_count], line, path_len);
source_path[*line_count][path_len] = '\0'; // 确保字符串以 '\0' 结尾
strncpy(redirect_path[*line_count], arrow + 4, PATH_MAX - 1);
redirect_path[*line_count][PATH_MAX - 1] = '\0'; // 确保字符串以 '\0' 结尾
(*line_count)++;
}
line = my_strtok(NULL, "\n");
}
kf_vfree(temp);
}
//static long mod_control0(const char *args, char *__user out_msg, int outlen) { pr_info("[yuuki] kpm hello control0, args: %s\n", args);
char source_paths[MAX_LINES][PATH_MAX] = {0};
char redirect_paths[MAX_LINES][PATH_MAX] = {0};
int line_count = 0;
// 解析输入
parsePaths(args, source_paths, redirect_paths, &line_count);
// 输出结果
for (int i = 0; i < line_count; i++) {
pr_info("[yuuki] source_path: %s redirect_path: %s\n", source_paths[i], redirect_paths[i]);
}
//control_internal(true);
return 0;
}
我都没有使用到memset这个函数,但是加载失败提示unknown symbol: memset 我尝试使用void *(*kf_memset)(void *s, int c, size_t count) = NULL; kf_memset = (typeof(kf_memset))kallsyms_lookup_name("memset");依然会报这个错误,请问大佬们这个问题如何解决
你自己编译器优化的问题
[ 7939.904376] [-] KP E unknown symbol: fp_wrap_syscalln [ 7939.904377] [-] KP E unknown symbol: fp_unwrap_syscalln [ 7939.904378] [-] KP E unknown symbol: inline_unwrap_syscalln [ 7939.904379] [-] KP E unknown symbol: inline_wrap_syscalln. 我遇到这几个函数找不到,为啥
我今天也遇到了这个问题,编译器优化会自动插入memcpy调用,无论你如何手动避免它。不幸的是我的内核符号表里memcpy的标识是W,并且我尝试使用编译选项禁用内置函数修改Makefile,为gcc添加-fno-builtin-memcpy选项但是仍然:
/mnt/e/KernelPatch-0.10.7/kpms/12345# aarch64-linux-gnu-nm show_vma_perm.kpm | grep memcpy
U memcpy
/mnt/e/KernelPatch-0.10.7/kpms/12345# aarch64-linux-gnu-objdump -d show_vma_perm.kpm | grep -A5 -B5 memcpy
5bc: f103fedf cmp x22, #0xff
5c0: d2801fe0 mov x0, #0xff // #255
5c4: 9a8092d6 csel x22, x22, x0, ls // ls = plast
5c8: aa1503e0 mov x0, x21
5cc: aa1603e2 mov x2, x22
5d0: 94000000 bl 0 <memcpy>
5d4: 38366abf strb wzr, [x21, x22]
5d8: 17ffff98 b 438 <my_show_map_vma+0x274>
5dc: 39400040 ldrb w0, [x2]
5e0: 7100281f cmp w0, #0xa
5e4: 54ffe680 b.eq 2b4 <my_show_map_vma+0xf0> // b.none
/mnt/e/KernelPatch-0.10.7/kpms/12345# aarch64-linux-gnu-readelf -s show_vma_perm.kpm | grep memcpy
31: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND memcpy
于是我最后决定直接在模块中提供memcpy的实现,幸运的是,最后成功了。
我今天也遇到了这个问题,编译器优化会自动插入memcpy调用,无论你如何手动避免它。不幸的是我的内核符号表里memcpy的标识是W,并且我尝试使用编译选项禁用内置函数修改Makefile,为gcc添加-fno-builtin-memcpy选项但是仍然:
/mnt/e/KernelPatch-0.10.7/kpms/12345# aarch64-linux-gnu-nm show_vma_perm.kpm | grep memcpy U memcpy /mnt/e/KernelPatch-0.10.7/kpms/12345# aarch64-linux-gnu-objdump -d show_vma_perm.kpm | grep -A5 -B5 memcpy 5bc: f103fedf cmp x22, #0xff 5c0: d2801fe0 mov x0, #0xff // #255 5c4: 9a8092d6 csel x22, x22, x0, ls // ls = plast 5c8: aa1503e0 mov x0, x21 5cc: aa1603e2 mov x2, x22 5d0: 94000000 bl 0 <memcpy> 5d4: 38366abf strb wzr, [x21, x22] 5d8: 17ffff98 b 438 <my_show_map_vma+0x274> 5dc: 39400040 ldrb w0, [x2] 5e0: 7100281f cmp w0, #0xa 5e4: 54ffe680 b.eq 2b4 <my_show_map_vma+0xf0> // b.none /mnt/e/KernelPatch-0.10.7/kpms/12345# aarch64-linux-gnu-readelf -s show_vma_perm.kpm | grep memcpy 31: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND memcpy于是我最后决定直接在模块中提供memcpy的实现,幸运的是,最后成功了。
我的似乎是数组初始化的问题,换个方式就好了
我今天也遇到了这个问题,编译器优化会自动插入memcpy调用,无论你如何手动避免它。不幸的是我的内核符号表里memcpy的标识是W,并且我尝试使用编译选项禁用内置函数修改Makefile,为gcc添加-fno-builtin-memcpy选项但是仍然:
/mnt/e/KernelPatch-0.10.7/kpms/12345# aarch64-linux-gnu-nm show_vma_perm.kpm | grep memcpy U memcpy /mnt/e/KernelPatch-0.10.7/kpms/12345# aarch64-linux-gnu-objdump -d show_vma_perm.kpm | grep -A5 -B5 memcpy 5bc: f103fedf cmp x22, #0xff 5c0: d2801fe0 mov x0, #0xff // #255 5c4: 9a8092d6 csel x22, x22, x0, ls // ls = plast 5c8: aa1503e0 mov x0, x21 5cc: aa1603e2 mov x2, x22 5d0: 94000000 bl 0 <memcpy> 5d4: 38366abf strb wzr, [x21, x22] 5d8: 17ffff98 b 438 <my_show_map_vma+0x274> 5dc: 39400040 ldrb w0, [x2] 5e0: 7100281f cmp w0, #0xa 5e4: 54ffe680 b.eq 2b4 <my_show_map_vma+0xf0> // b.none /mnt/e/KernelPatch-0.10.7/kpms/12345# aarch64-linux-gnu-readelf -s show_vma_perm.kpm | grep memcpy 31: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND memcpy于是我最后决定直接在模块中提供memcpy的实现,幸运的是,最后成功了。
我的似乎是数组初始化的问题,换个方式就好了
请问你是怎么build的? 我用的是arm-gnu-toolchain-14.2.rel1-x86_64-aarch64-none-elf.tar, 然后make
我今天也遇到了这个问题,编译器优化会自动插入memcpy调用,无论你如何手动避免它。不幸的是我的内核符号表里memcpy的标识是W,并且我尝试使用编译选项禁用内置函数修改Makefile,为gcc添加-fno-builtin-memcpy选项但是仍然:
/mnt/e/KernelPatch-0.10.7/kpms/12345# aarch64-linux-gnu-nm show_vma_perm.kpm | grep memcpy U memcpy /mnt/e/KernelPatch-0.10.7/kpms/12345# aarch64-linux-gnu-objdump -d show_vma_perm.kpm | grep -A5 -B5 memcpy 5bc: f103fedf cmp x22, #0xff 5c0: d2801fe0 mov x0, #0xff // #255 5c4: 9a8092d6 csel x22, x22, x0, ls // ls = plast 5c8: aa1503e0 mov x0, x21 5cc: aa1603e2 mov x2, x22 5d0: 94000000 bl 0 <memcpy> 5d4: 38366abf strb wzr, [x21, x22] 5d8: 17ffff98 b 438 <my_show_map_vma+0x274> 5dc: 39400040 ldrb w0, [x2] 5e0: 7100281f cmp w0, #0xa 5e4: 54ffe680 b.eq 2b4 <my_show_map_vma+0xf0> // b.none /mnt/e/KernelPatch-0.10.7/kpms/12345# aarch64-linux-gnu-readelf -s show_vma_perm.kpm | grep memcpy 31: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND memcpy于是我最后决定直接在模块中提供memcpy的实现,幸运的是,最后成功了。
我的似乎是数组初始化的问题,换个方式就好了
请问你是怎么build的? 我用的是arm-gnu-toolchain-14.2.rel1-x86_64-aarch64-none-elf.tar, 然后make
我也差不多, TARGET_COMPILE := E:\KernelPatch\arm-gnu-toolchain-14.2.rel1-mingw-w64-x86_64-aarch64-none-elf\bin\aarch64-none-elf- CC = $(TARGET_COMPILE)gcc LD = $(TARGET_COMPILE)ld 在终端里make即可
我今天也遇到了这个问题,编译器优化会自动插入memcpy调用,无论你如何手动避免它。不幸的是我的内核符号表里memcpy的标识是W,并且我尝试使用编译选项禁用内置函数修改Makefile,为gcc添加-fno-builtin-memcpy选项但是仍然:
/mnt/e/KernelPatch-0.10.7/kpms/12345# aarch64-linux-gnu-nm show_vma_perm.kpm | grep memcpy U memcpy /mnt/e/KernelPatch-0.10.7/kpms/12345# aarch64-linux-gnu-objdump -d show_vma_perm.kpm | grep -A5 -B5 memcpy 5bc: f103fedf cmp x22, #0xff 5c0: d2801fe0 mov x0, #0xff // #255 5c4: 9a8092d6 csel x22, x22, x0, ls // ls = plast 5c8: aa1503e0 mov x0, x21 5cc: aa1603e2 mov x2, x22 5d0: 94000000 bl 0 <memcpy> 5d4: 38366abf strb wzr, [x21, x22] 5d8: 17ffff98 b 438 <my_show_map_vma+0x274> 5dc: 39400040 ldrb w0, [x2] 5e0: 7100281f cmp w0, #0xa 5e4: 54ffe680 b.eq 2b4 <my_show_map_vma+0xf0> // b.none /mnt/e/KernelPatch-0.10.7/kpms/12345# aarch64-linux-gnu-readelf -s show_vma_perm.kpm | grep memcpy 31: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND memcpy于是我最后决定直接在模块中提供memcpy的实现,幸运的是,最后成功了。
我的似乎是数组初始化的问题,换个方式就好了
请问你是怎么build的? 我用的是arm-gnu-toolchain-14.2.rel1-x86_64-aarch64-none-elf.tar, 然后make
我看到了你的问题,具体的函数符号找不到可以这样: 首先查询你的手机的内核符号表,你可以:
$ su
# echo 0 > /proc/sys/kernel/kptr_restrict
# cat /proc/kallsyms > /sdcard/syms.txt
导出内核符号表,查询你用到的函数是否标识为T或者t,这样标识的函数可以使用kallsyms_lookup_name寻址并使用。 我目前的经验就是如果unknown symbol:可能是使用了内核符号表里没有或者标识为W的函数,或者没有使用但是编译器将其放进去了。
我今天也遇到了这个问题,编译器优化会自动插入memcpy调用,无论你如何手动避免它。不幸的是我的内核符号表里memcpy的标识是W,并且我尝试使用编译选项禁用内置函数修改Makefile,为gcc添加-fno-builtin-memcpy选项但是仍然:
/mnt/e/KernelPatch-0.10.7/kpms/12345# aarch64-linux-gnu-nm show_vma_perm.kpm | grep memcpy U memcpy /mnt/e/KernelPatch-0.10.7/kpms/12345# aarch64-linux-gnu-objdump -d show_vma_perm.kpm | grep -A5 -B5 memcpy 5bc: f103fedf cmp x22, #0xff 5c0: d2801fe0 mov x0, #0xff // #255 5c4: 9a8092d6 csel x22, x22, x0, ls // ls = plast 5c8: aa1503e0 mov x0, x21 5cc: aa1603e2 mov x2, x22 5d0: 94000000 bl 0 <memcpy> 5d4: 38366abf strb wzr, [x21, x22] 5d8: 17ffff98 b 438 <my_show_map_vma+0x274> 5dc: 39400040 ldrb w0, [x2] 5e0: 7100281f cmp w0, #0xa 5e4: 54ffe680 b.eq 2b4 <my_show_map_vma+0xf0> // b.none /mnt/e/KernelPatch-0.10.7/kpms/12345# aarch64-linux-gnu-readelf -s show_vma_perm.kpm | grep memcpy 31: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND memcpy于是我最后决定直接在模块中提供memcpy的实现,幸运的是,最后成功了。
我的似乎是数组初始化的问题,换个方式就好了
请问你是怎么build的? 我用的是arm-gnu-toolchain-14.2.rel1-x86_64-aarch64-none-elf.tar, 然后make
我看到了你的问题,具体的函数符号找不到可以这样: 首先查询你的手机的内核符号表,你可以:
$ su # echo 0 > /proc/sys/kernel/kptr_restrict # cat /proc/kallsyms > /sdcard/syms.txt导出内核符号表,查询你用到的函数是否标识为T或者t,这样标识的函数可以使用kallsyms_lookup_name寻址并使用。 我目前的经验就是如果unknown symbol:可能是使用了内核符号表里没有或者标识为W的函数,或者没有使用但是编译器将其放进去了。
我那几个符号都是 kernelpatch里面一个syscall.h里面的方法,不是内核导出符号。不知道是不是跟系统syscall.h重名了导致找不到符号,不是