KernelPatch icon indicating copy to clipboard operation
KernelPatch copied to clipboard

模块加载失败unknown symbol: memset

Open SoyBeanMilkx opened this issue 1 year ago • 8 comments

内核日志: [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");依然会报这个错误,请问大佬们这个问题如何解决

SoyBeanMilkx avatar Nov 18 '24 06:11 SoyBeanMilkx

你自己编译器优化的问题

pomelohan avatar Nov 29 '24 14:11 pomelohan

[ 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. 我遇到这几个函数找不到,为啥

feng504x avatar Feb 19 '25 06:02 feng504x

我今天也遇到了这个问题,编译器优化会自动插入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的实现,幸运的是,最后成功了。

yangyyyy15 avatar Feb 20 '25 03:02 yangyyyy15

我今天也遇到了这个问题,编译器优化会自动插入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的实现,幸运的是,最后成功了。

我的似乎是数组初始化的问题,换个方式就好了

SoyBeanMilkx avatar Feb 20 '25 03:02 SoyBeanMilkx

我今天也遇到了这个问题,编译器优化会自动插入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

feng504x avatar Feb 20 '25 03:02 feng504x

我今天也遇到了这个问题,编译器优化会自动插入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即可

yangyyyy15 avatar Feb 20 '25 03:02 yangyyyy15

我今天也遇到了这个问题,编译器优化会自动插入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的函数,或者没有使用但是编译器将其放进去了。

yangyyyy15 avatar Feb 20 '25 03:02 yangyyyy15

我今天也遇到了这个问题,编译器优化会自动插入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重名了导致找不到符号,不是

feng504x avatar Feb 20 '25 12:02 feng504x