kprobe를 등록할 수 없습니다.

kprobe를 등록할 수 없습니다.

시스템 호출의 주소를 검색하기 위해 kprobe를 등록하려고 합니다. 하지만 내 모든 시도는 오류 코드로 -22를 반환하는 것 같습니다. 다음 예제 코드(완전하지는 않지만 관련 기능이 포함되어 있음)는 호출에 대한 커널 프로브를 등록하려고 시도합니다 sys_mkdir.

전처리기나 후처리기를 지정해도 문제가 되지 않는 것 같습니다. 단지 프로브를 등록하는 것만으로는 작동하지 않습니다.

kallsyms_lookup_name참고: 커널 5.7 이상에서는 더 이상 내보내지지 않는 내보내지 않은 대체품으로 kprobes를 사용해 보았습니다 .

unsigned long lookup_name(const char *name)  
{
        int ret;
        struct kprobe kp;
        unsigned long retval;
 
        kp.symbol_name = name;
        ret = register_kprobe(&kp);     
        if (ret < 0) {
                printk(KERN_DEBUG "register_kprobe failed for symbol %s, returned %d\n", name,
 ret);
                return 0;
        }
        retval = (unsigned long)kp.addr;
        unregister_kprobe(&kp);
        return retval;
}
                                                                                                  
static int __init mod_init(void)                                                              
{                                                                                                 
        int (*fn)(unsigned long param);

        fn = (void*)lookup_name("__x64_sys_mkdir");   
} 

답변1

구조체를 완전히 초기화 하지 않았 으므로 및 사이의 상호 배제 또는 요구 사항을 kprobe충족할 수 없습니다 (표의 3번 항목).symbol_nameaddrregister_kprobe선적 서류 비치): addr함수 시작 시 스택에 있는 모든 항목을 포함합니다. 이는 0이 아닐 가능성이 높으므로 두 symbol_name합계 모두 addr0이 아니며 register_kprobe(22)로 실패합니다.EINVAL

다음과 같이 이 문제를 해결할 수 있습니다.

        int ret;
        struct kprobe kp = {
                .symbol_name = name
        };
        unsigned long retval;

이렇게 하면 구조의 다른 멤버가 기본값으로 초기화됩니다.

관련 정보