int module_init_notifier(struct notifier_block *self, unsigned long event, void *arg) { struct module *mod = (struct module *)arg; unsigned int name_offset; unsigned int lsc; lsc = get_sample_count(); name_offset = 0; if (event == MODULE_STATE_COMING) { if (mod->init_size > 0) { module_load_notif((char *)mod->name, name_offset, 0, (__u32)mod->module_init, mod->init_size, MODULE_FLAG_GLOBAL, lsc); } if (mod->core_size > 0) { module_load_notif((char*)mod->name, name_offset, 0, (__u32)mod->module_core, mod->core_size, MODULE_FLAG_GLOBAL, lsc); } } return 0; }
/* * enumerate all modules for process * pid: process id * lsc: load sample count */ static void enum_modules_for_process(pid_t pid, unsigned long lsc) { bool find = false; char *pname; unsigned long name_offset; unsigned int options; struct task_struct *task; struct vm_area_struct *mmap; struct mm_struct *mm; task = px_find_task_by_pid(pid); if (task == NULL) return; mm = get_task_mm(task); if (mm != NULL) { down_read(&mm->mmap_sem); for (mmap = mm->mmap; mmap; mmap = mmap->vm_next) { if (is_valid_module(mmap)) { memset(name, 0, (PATH_MAX) * sizeof(char)); pname = px_d_path(mmap->vm_file, name, PATH_MAX); if (pname != NULL) { options = 0; if (find == false) { options |= MODULE_FLAG_1ST; find = true; } name_offset = get_filename_offset(pname); module_load_notif(pname, name_offset, pid, mmap->vm_start, mmap->vm_end - mmap->vm_start, options, lsc); } } } up_read(&mm->mmap_sem); mmput(mm); } if (find == false) { module_load_notif(task->comm, 0, pid, LINUX_APP_BASE_LOW, 0,//mmap->vm_end - mmap->vm_start, MODULE_FLAG_1ST, lsc); } return; }
/* * static enumeration kernel modules */ static void static_enum_kernel_modules(void) { module_load_notif("swapper", 0, 0, LINUX_APP_BASE_LOW, 0, MODULE_FLAG_1ST, 0); /* * PAGE_OFFSET is the load address of kernel * * 0x8000 is the offset to the text section of kernel * which is defined as TEXT_OFFSET in arch/arm/Makefile */ module_load_notif("vmlinux", 0, 0, PAGE_OFFSET + 0x8000, 4096 * 2 * 1024, MODULE_FLAG_GLOBAL, 0); }
asmlinkage int px_sys_mmap2( unsigned long addr, unsigned long len, unsigned long prot, unsigned long flgs, unsigned long fd, unsigned long pgoff /* unsigned long lRegSP*/ ) { int ret = 0; int saved_r5; unsigned long lsc; struct file *file; INIT_STACK_FRAME; // here we must save r5 since it will be used by the OS sys_mmap2 code __asm__("str r5, %0\n\t":"=m"(saved_r5):); APPEND_STACK_FRAME; lsc = get_sample_count(); // restore r5 __asm__("ldr r5, %0\n\t"::"m"(saved_r5):"r5"); ret = px_original_sys_mmap2( addr, len, prot, flgs, fd, pgoff); CUTTAIL_STACK_FRAME; if (gb_enable_os_hooks && !IS_ERR((void *)ret) && (prot & PROT_EXEC) && !(flgs & MAP_ANONYMOUS)) { //rcu_read_lock(); if ((file = fcheck(fd))!= NULL) { char *pname; memset(name, 0, PATH_MAX * sizeof(char)); pname = px_d_path(file, name, PATH_MAX); if (pname) { unsigned long name_offset; name_offset = get_filename_offset(pname); module_load_notif(pname, name_offset, current->tgid, ret, len, 0, lsc); } } //rcu_read_unlock(); } return ret; }
asmlinkage int px_sys_mmap(struct mmap_arg_struct *arg) { int ret = 0; struct mmap_arg_struct tmp; struct file *file; unsigned long long lsc; char * name = NULL; lsc = get_sample_count(); if (copy_from_user(&tmp, arg, sizeof(tmp)) != 0) { return -EFAULT; } ret = px_original_sys_mmap(arg); if (gb_enable_os_hooks && (!IS_ERR((void*)ret)) && (tmp.prot & PROT_EXEC) && !(tmp.flags & MAP_ANONYMOUS)) { //rcu_read_lock(); if ((file = fcheck(tmp.fd)) != NULL) { char *filename; //memset(name, 0, PATH_MAX * sizeof(char)); name = kzalloc(PATH_MAX, GFP_ATOMIC); if (name == NULL) { return ret; } filename = px_d_path(file, name, PATH_MAX); if (filename) { unsigned long name_offset; name_offset = get_filename_offset(filename); module_load_notif(filename, name_offset, current->tgid, ret, tmp.len, 0, lsc); } kfree(name); } //rcu_read_unlock(); } return ret; }
/* * static enumeration kernel modules */ static void static_enum_kernel_modules(void) { unsigned int text_offset; #ifdef CONFIG_TEXT_OFFSET text_offset = CONFIG_TEXT_OFFSET; #else /* * PAGE_OFFSET is the load address of kernel * * 0x8000 is the offset to the text section of kernel * which is defined as TEXT_OFFSET in arch/arm/Makefile */ text_offset = 0x8000; #endif module_load_notif("swapper", 0, 0, LINUX_APP_BASE_LOW, 0, MODULE_FLAG_1ST, 0); module_load_notif("vmlinux", 0, 0, PAGE_OFFSET + text_offset, 4096 * 2 * 1024, MODULE_FLAG_GLOBAL, 0); }
/* * enumerate all modules for process * pid: process id * lsc: load sample count */ static void enum_modules_for_process(pid_t pid, unsigned long long lsc, const char * proc_name) { bool find = false; char *filename; unsigned long name_offset; unsigned int options; struct task_struct *task; struct vm_area_struct *mmap; struct mm_struct *mm; char * name = NULL; char * buffer = NULL; task = px_find_task_by_pid(pid); if (task == NULL) goto ret; name = kzalloc(PATH_MAX, GFP_ATOMIC); if (name == NULL) goto ret; buffer = kzalloc(PATH_MAX, GFP_ATOMIC); if (buffer == NULL) goto ret; mm = get_task_mm(task); if (mm != NULL) { down_read(&mm->mmap_sem); for (mmap = mm->mmap; mmap; mmap = mmap->vm_next) { if (is_valid_module(mmap)) { memset(name, 0, (PATH_MAX) * sizeof(char)); filename = px_d_path(mmap->vm_file, name, PATH_MAX); if (filename != NULL) { options = 0; if (find == false) { options |= MODULE_FLAG_1ST; find = true; if (proc_name != NULL) { /* for the first module (the executable image), if the process name is specified, use the specified one */ strcpy(buffer, proc_name); } else { /* * for the first module (the executable image), we need to get the process name again * because it may be modified by changing the argv[0] */ if (get_proc_name(task, buffer) == 0) { /* failed to get the process name, use the orignal module name */ strcpy(buffer, filename); } } /* save the orignal process name for checking if it will be updated later */ notify_new_loaded_process(task, buffer); } else { memset(buffer, 0, sizeof(PATH_MAX)); strcpy(buffer, filename); } name_offset = get_filename_offset(buffer); module_load_notif(buffer, name_offset, pid, mmap->vm_start, mmap->vm_end - mmap->vm_start, options, lsc); } } } up_read(&mm->mmap_sem); mmput(mm); } if (find == false) { module_load_notif(task->comm, 0, pid, LINUX_APP_BASE_LOW, 0,//mmap->vm_end - mmap->vm_start, MODULE_FLAG_1ST, lsc); } ret: if (name != NULL) kfree(name); if (buffer != NULL) kfree(buffer); return; }