Getting the address of sys_call_table within an LKM (kernel version > 5.14.0)

MySprtlty·2023년 2월 16일
0

Kernel

목록 보기
1/10

🏷️Getting the address of sys_call_table within an LKM (kernel version > 5.14.0)

📌Check the static sys_call_table address

  • System.map에서 static address를 확인할 수 있다.
vi System.map-5.14.0

ffffffff82001680 D sys_call_table

📌Check the dynamic sys_call_table address

  • 하지만, running kernel의 sys_call_table의 address를 가져오려면 다른 방법을 사용해야 한다.
  • symbols of running kernel을 확인하려면 kallsyms에서 읽어야 한다.
cat /proc/kallsyms | grep sys_call_table
  • 커널 버전에 따라 커널 모듈에서 sys_call_table 주소를 읽는 방법이 다르다.
  • 🖇️cf. KASLR가 켜져있는 커널이라면, 부팅할 때마다 주소가 다르다. (일반적으로 켜져있다.)

📌Get the dynamic sys_call_table address within an LKM

  • kprobe를 통해 kallsyms_lookup_name함수의 주소를 가져온다.
    • 🖇️cf. kprobe
      • 커널에서 제공하는 도구로, 개발자가 커널의 실행 중인 특정 코드 위치에 동적으로 breakpoint를 설정할 수 있게 해준다.
      • 커널 함수의 실행을 가로채거나 특정 지점에서 추가적인 코드를 실행시킬 수 있다.
      • kprobe는 디버깅, 성능 분석, 시스템 모니터링 등 다양한 목적으로 사용될 수 있다.
  • 아래 코드는 5.14.0 kernel에서 동작된다.
/* get the address of sys_call_table */
static unsigned long int **acquire_sys_call_table(void)
{
	unsigned long int (*kallsyms_lookup_name)(const char *name);

	/* probe가 설치될 위치 지정 */
	struct kprobe kp = {
		.symbol_name = "kallsyms_lookup_name",
	};

	/* probe 등록 */
	if (register_kprobe(&kp) < 0){
		return NULL;
	}
    
    /* get the address of kallsyms_lookup_name */
	kallsyms_lookup_name = (unsigned long (*)(const char *name))kp.addr;
    
    /* probe 해제 */
	unregister_kprobe(&kp);

	/* sys_call_table의 주소를 얻어서 return */
	return (unsigned long int **)kallsyms_lookup_name("sys_call_table");
}
profile
2Co 4:7

0개의 댓글