Kprobes 사용하기 [2] : 시스템콜에 probe 삽입하기
Kprobe 를 이용하려면 모듈로 작성하여야 함.
System call 중 sys_open( ) 이 호출되는 것을 로그로 감지하는 probe를 삽입해 보겠다.
우선 커널에서 sys_open( )의 심볼 주소를 얻어야 한다.
적어도 다음과 같은 3가지 방법이 있다.
/proc/kallsyms 파일 항목을 사용한다.
위 명령을 사용하면 심볼 주소를 알 수 있다.
c1169ba0 T sys_open 과 같이 결과가 뱉어진다.
나는 c1169ba0 임을 알 수 있었다.
kprobe의 addr에 넣어주면 된다.
다음 소스코드를 c 파일로 작성한다.
나는 kprobe_sys_open.c 로 저장하였다.
#include <linux/module.h>
#include <linux/kprobes.h>
struct kprobe kpb;
int handler_pre_sys_open(struct kprobe* p, struct pt_regs* regs) {
printk("sys_open_pre_handler: p->addr=0x%p\n", p->addr);
return 0;
}
void handler_post_sys_open(struct kprobe* p, struct pt_regs* regs, unsigned long flags) {
printk("post_handler_sys_open: p->addr=0x%p\n", p->addr);
}
int handler_fault_sys_open(struct kprobe* p, struct pt_regs* regs, int trapnr) {
printk("handler_fault_sys_open: p->addr=0x%p\n", p->addr);
return 0;
}
int init_module(void)
{
kpb.fault_handler = handler_fault_sys_open;
kpb.pre_handler = handler_pre_sys_open;
kpb.post_handler = handler_post_sys_open;
kpb.addr = (kprobe_opcode_t *) 0xc1169ba0; // 이 부분이 심볼 주소
register_kprobe(&kpb);
printk("register kprobe \n");
return 0;
}
void cleanup_module(void)
{
unregister_kprobe(&kpb);
printk("unregister kprobe\n");
}
MODULE_LICENSE("GPL");
모듈로 만들어 주기 위한 Makefile 을 작성했다.
vi Makefile
위 명령으로 Makefile을 만든 뒤 아래 내용을 넣어주고 저장한다.
obj-m += kprobe_sys_open.o
vi 에디터에서 빠져 나온 뒤 make 명령을 해주면, module 파일이 생성된다
다음과 같이 해준다.
make -C /usr/src/linux SUBDIRS=$PWD modules
몇개의 생성되는 파일이 있는데, .ko 확장자를 갖는 파일이 모듈 파일이다.
모듈의 삽입과 제거는 다음과 같이 수행한다.
insmod kprobe_sys_open.ko (모듈 삽입)
rmmod kprobe_sys_open.ko (모듈 제거)
모듈 삽입 후 커널의 로그 메세지를 보면, kprobe의 핸들러에서 printk 를 통해 출력하는 메세지들이 기록되는 것을 볼 수 있다. 로그가 기록되는 시점은 sys_open 시스템 콜이 불려질 때마다 전 (pre), 후 (post) 핸들러가 실행되어 로그를 기록한다.
로그 확인 뒤 모듈 제거를 하도록 한다.
커널 로그의 확인은 리눅스 배포판 마다 다른 듯 하다.
Ubuntu 12.04 에서는 다음과 같이 확인한다.
cat /proc/kmsg
여러 다른 로그가 쌓이는 중, kprobe가 기록하는 메세지도 함께 쌓이는 것을 확인 가능하다.
'개발자의 기록 노트 > Linux' 카테고리의 다른 글
man page와 section number (0) | 2012.10.06 |
---|---|
[Ubuntu 12.04] GRUB : 부트로더 환경설정 (1) | 2012.10.02 |
[우분투] Ubuntu 12.04 에 JDK7 설치하기 (0) | 2012.09.15 |
Kprobes 사용하기 [1] : Ubuntu 12.04 (0) | 2012.09.11 |
[리눅스/Vi]Vim, Vi, GVim 에서 '작업 취소(Undo)' / '다시 하기(Redo)' 방법 (0) | 2012.04.18 |
[우분투] Ubuntu에 Mysql 설치 (1) | 2011.12.28 |