
시스템 호출의 주소를 검색하기 위해 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_name
addr
register_kprobe
선적 서류 비치): addr
함수 시작 시 스택에 있는 모든 항목을 포함합니다. 이는 0이 아닐 가능성이 높으므로 두 symbol_name
합계 모두 addr
0이 아니며 register_kprobe
(22)로 실패합니다.EINVAL
다음과 같이 이 문제를 해결할 수 있습니다.
int ret;
struct kprobe kp = {
.symbol_name = name
};
unsigned long retval;
이렇게 하면 구조의 다른 멤버가 기본값으로 초기화됩니다.