Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

模块加载失败unknown symbol: memset #144

Open
SoyBeanMilkx opened this issue Nov 18, 2024 · 8 comments
Open

模块加载失败unknown symbol: memset #144

SoyBeanMilkx opened this issue Nov 18, 2024 · 8 comments

Comments

@SoyBeanMilkx
Copy link

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

@pomelohan
Copy link
Contributor

你自己编译器优化的问题

@feng504x
Copy link

feng504x commented Feb 19, 2025

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

@yangyyyy15
Copy link

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

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

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

@feng504x
Copy link

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

@yangyyyy15
Copy link

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

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

@feng504x
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants