find_sys_call_table和kallsysms_lookup_name的区别

2024-05-30 12:45:14 浏览数 (2)

find_sys_call_tablekallsyms_lookup_name 都可以用于查找内核符号,但它们的具体作用和使用场景有所不同。以下是两者的详细对比:

1. find_sys_call_table

作用

find_sys_call_table 是一种通过遍历内核内存或者其他方式来手动查找系统调用表地址的技术。这种方法通常在某些情况下使用,比如系统没有启用 kallsyms_lookup_name 或者内核版本不支持直接符号查找。

使用场景
  • 内核版本不支持 kallsyms_lookup_name:在某些老版本内核中,kallsyms_lookup_name 可能不可用或者被禁用。
  • 无符号信息的内核:某些内核可能没有编译符号信息,这时无法通过符号名直接查找地址。
  • 调试和分析工具:在某些情况下,调试工具可能需要手动查找系统调用表。
实现方法

find_sys_call_table 通常通过扫描内存中的特定模式来找到系统调用表。以下是一个简化的示例,展示了如何通过遍历内存来找到 sys_call_table

代码语言:javascript复制
unsigned long **find_sys_call_table(void) {
    unsigned long offset;
    unsigned long **sct;

    for (offset = PAGE_OFFSET; offset < ULLONG_MAX; offset  = sizeof(void *)) {
        sct = (unsigned long **)offset;

        if (sct[__NR_close] == (unsigned long *) sys_close) {
            return sct;
        }
    }
    return NULL;
}

这个示例通过遍历从 PAGE_OFFSET 开始的内核内存地址空间,查找包含 sys_close 函数地址的位置,来确定系统调用表的位置。

2. kallsyms_lookup_name

作用

kallsyms_lookup_name 是内核提供的一个函数,用于通过符号名称查找其地址。这在调试和开发内核模块时非常方便,能够直接获取符号(如函数、变量等)的地址。

使用场景
  • 内核开发和调试:在开发内核模块时,通过符号名称快速查找函数或变量的地址。
  • 符号查找:需要查找特定符号的地址时,如 sys_call_table 的地址。
使用方法

使用 kallsyms_lookup_name 需要确保内核配置启用了 CONFIG_KALLSYMSCONFIG_KALLSYMS_ALL,并且函数是GPL导出的。以下是一个示例代码:

代码语言:javascript复制
#include <linux/kallsyms.h>
#include <linux/module.h>

static int __init init_module_func(void) {
    unsigned long address;

    address = kallsyms_lookup_name("sys_call_table");
    if (address) {
        printk(KERN_INFO "sys_call_table address: %lxn", address);
    } else {
        printk(KERN_ERR "sys_call_table not foundn");
    }
    return 0;
}

static void __exit cleanup_module_func(void) {
    printk(KERN_INFO "Module exitingn");
}

module_init(init_module_func);
module_exit(cleanup_module_func);

MODULE_LICENSE("GPL");

总结

  • 查找方法find_sys_call_table 通过遍历内存查找特定模式找到系统调用表,而 kallsyms_lookup_name 通过符号名称直接查找地址。
  • 适用场景find_sys_call_table 适用于符号信息不可用或者不支持 kallsyms_lookup_name 的情况,而 kallsyms_lookup_name 适用于开发和调试,需要通过符号名称快速查找地址的情况。
  • 实现复杂度find_sys_call_table 通常实现较复杂,需要了解内核内存布局和系统调用表特征;kallsyms_lookup_name 使用方便,只需提供符号名称即可。

两者在使用场景和实现复杂度上有显著区别,应根据具体需求选择合适的方法。

0 人点赞