안녕하세요! 호서대학교 석사(과정) 이우영 입니다.


오늘은 kprobes 에 대해서 알아 보도록 하겠습니다.


kprobes


 

kprobes 는 kernel 2.6.8 버전 부터 x86을 지원했습니다.


arm은 2.6.25 버전부터 지원을 시작했습니다.


kprobes는 kprobe, jprobe, kretprobe 3가지 기능을 제공 합니다.


기본적으로 kprobe를 기반으로 추가된 기능을 제공합니다.


kprobe는 코드상의 특정위치(커널함수호출)를 지정하고 함수가 호출될때 함수 실행 전, 실행 후에


실행되는 pre/post handler를 등록 합니다.


위치를 지정하는 방법은 2가지가 있습니다. 꼭 2가지 중 1가지 방법으로 해야합니다.


심볼의 이름으로 등록하는 방법과 메모리 주소를 통해 등록하는 방법이 있습니다.


jprobe는 함수가 호출될 때 사용자가 작성한 함수로 잠시 바꿔서 실행을 합니다.


kprobe에 대한 설명은 다음 시간에 더하고 일단 간단한 jprobe 작성 및 사용법을 알아 보도록 하겠습니다.


jprobe 모듈 작성


 

ez-s3c6410 보드를 통해서 작업을 하도록 하겠습니다.


필요한 자료는 http://forum.falinux.com/zbxe/?mid=EZS3C6410 에서 


Toolchain 과 kernel을 받으시면 됩니다.


먼저 하셔야 하는일은 kernel 을 보드에 맞게 수정 하셔야 합니다.


위에서 받은 kernel은 linux-2.6.29-ez-s3c6410 이라는 폴더로 압축이 풀립니다.


폴더로 들어가 다음과 같은 명령어를 해줘야 합니다.


make distclean

make ezs3c6410_android_defconfig       <- 안드로이드 버전이 별다른 설정이 필요 없습니다, ㅎㅎ

make menuconfig

make zImage


그럼 코드를 작성해 보겠습니다. 코드는 http://www.buggymind.com/113 를 참고하였습니다.


06_test_jprobe.c


#include <linux/kernel.h>

#include <linux/module.h>

#include <linux/init.h>

#include <linux/kprobes.h>

MODULE_LICENSE("GPL");


//잠시 바꿔치기할 함수입니다.

static void my_udp_sendmsg( struct kiocb* iocb, struct sock* sk, struct msghdr* msg, size_t len)

{

printk("i`m jprobe\n");


jprobe_return();

}


// jprobe 생성

static struct jprobe my_probe() 

{

.entry = (kprobe_opcode_t *)my_udp_sendmsg  //바꿔치기할 함수 주소등록

};


int module_start()

{

my_probe.kp.symbol_name = "udp_sendmsg"; //확인 할 함수를 이름


do{

if( register_jprobe(&my_probe) < 0 )  //jprobe 등록

{

printk("oop`s!\n");

}

}while( 0 );


return 0;

}


void module_end()

{

unregister_jprobe(&my_probe); //jprbe 해제

}


module_init(module_start);

module_exit(module_end);



Makefile


cc := arm-generic-linux-gnueabi-gcc-4.3.2


obj-m := 06_test_jprobe.c


KDIR := /home/woo/linux-2.6.29-ez-s3c6410


all:

make -C $(KDIR) SUBDIRS=$(PWD) modules

clean:

rm -rf *.o *.ko *.mod.* .*.cmd


Makefile은 크로스컴파일러 버전과 커널만 변했을 뿐입니다 ㅎㅎ


컴파일 후 insmod를 통해서 올려 주시면 됩니다.


jprobe_udp_senmeg.png


현재 nfs 서버에 마운트 중인 상태에서 ls 명령어를 치면 서버에서 파일 목록을 받아옵니다


그 과정 중 udp통신을 사용해서 위와같이 메시지를 출력 했습니다.


보시는거와 같이 jprobe를 이용하면 손쉽게 커널 내부의 동작들을 확인이 가능합니다.


오늘은 여기까지!


다음 시간에도 kprobe를 해보도록 하겠습니다.


http://ms-osek.org/ <- 쫌더 빨리 보고 싶으신분은 여기로 오세요~