티스토리 뷰

기존 커널에 대해 hooking하는 hooking.c와 그것을 테스트하는 파일 test.c를 컴파일한다.

hooking.c에서 현재 프로세스의 task_struct를 이용해 test.c 파일의 경로를 얻기 위한 과정에서 알게 된 것을 기록한다.

 

 

struct task_struct *t;
struct mm_struct *mm;
struct vm_area_struct *vm;

t = pid_task(find_vpid(pid), PIDTYPE_PID);
mm = get_task_mm(t);
vm = mm->mmap;

 

현재 프로세스에 해당하는 파일의 경로 출력

char* file_path;
struct file* exe_file;
	
down_read(&mm->mmap_sem);
exe_file = mm->exe_file;
if(exe_file) get_file(exe_file);
up_read(&mm->mmap_sem);
file_path = d_path(&(exe_file->f_path), file_path, 100*sizeof(char));

printk(KERN_INFO "%s\n", file_path);

test 파일이 위치한 경로가 출력된다.

char* file_path;
char buf[100];
struct file* file;

file = vm->vm_file;
file_path = d_path(&file->f_path, buf, 100);

printk(KERN_INFO "%s\n", file_path);

vm = vm->vm_next 로 넘겨가며 반복문으로 출력하면 test 파일과 .so 파일의 경로가 모두 출력할 수 있다.

 

현재 프로세스에 해당하는 파일의 이름 출력

struct fs_struct *f_fs;
struct path f_pwd;
struct dentry* f_dentry;
struct qstr f_dname;
    
f_fs = t->fs;
f_pwd = f_fs->pwd;
f_dentry = f_pwd.dentry;
f_dname = f_dentry->d_name;

printk(KERN_INFO "%s\n", f_dname.name);

1. task_struct* t -> files_struct* files -> path pwd -> dentry* dentry -> qstr d_name -> const unsigned char* name

2. task_struct* t -> mm_struct* mm -> vm_area_struct* vm -> file* vm_file -> path f_path -> dentry* dentry -> qstr d_name -> const unsigned char* name

3. task_struct* t -> files_struct* files -> file* fd_array[] -> path f_path -> dentry* dentry -> qstr d_name -> const unsigned char* name

4. task_struct* t -> files_struct* files -> fdtable* fdt -> file** fd -> path f_path -> dentry* dentry -> qstr d_name -> const unsigned char* name

3번, 4번은 안될 수도 있다.

커널 버전이 바뀌면서 멤버변수가 삭제되고 변경되어 안맞는 경우가 많다.

 

 

 

참고

m.blog.naver.com/PostView.nhn?blogId=hsmnim&logNo=30108957173&proxyReferer=https:%2F%2Fwww.google.com%2F

docs.huihoo.com/doxygen/linux/kernel/3.7/structfile.html

esos.hanyang.ac.kr/tc/david/i/entry/62

반응형

댓글