1 #include <dbi_kprobes.h>
2 #include <dbi_kprobes_deps.h>
4 #include "us_proc_inst.h"
5 #include "us_slot_manager.h"
8 #include "filters/filters_core.h"
11 ******************************************************************************
13 ******************************************************************************
20 static int entry_handler_pf(struct kretprobe_instance *ri, struct pt_regs *regs)
22 struct pf_data *data = (struct pf_data *)ri->data;
25 data->addr = read_cr2();
27 data->addr = regs->ARM_r0;
29 #error this architecture is not supported
35 /* Detects when IPs are really loaded into phy mem and installs probes. */
36 static int ret_handler_pf(struct kretprobe_instance *ri, struct pt_regs *regs)
38 struct task_struct *task;
39 struct sspt_proc *proc;
42 * Because process threads have same address space
43 * we instrument only group_leader of all this threads
45 task = current->group_leader;
46 if (task->flags & PF_KTHREAD)
49 if (!is_us_instrumentation())
52 proc = sspt_proc_get_by_task(task);
56 task = check_task(task);
58 proc = sspt_proc_get_new(task);
65 if (proc->first_install) {
67 page = ((struct pf_data *)ri->data)->addr & PAGE_MASK;
68 sspt_proc_install_page(proc, page);
70 sspt_proc_install(proc);
76 static struct kretprobe pf_kretprobe = {
77 .entry_handler = entry_handler_pf,
78 .handler = ret_handler_pf,
79 .data_size = sizeof(struct pf_data)
85 ******************************************************************************
87 ******************************************************************************
90 static void recover_child(struct task_struct *child_task, struct sspt_proc *proc)
92 sspt_proc_uninstall(proc, child_task, US_DISARM);
93 dbi_disarm_urp_inst_for_task(current, child_task);
96 static void rm_uprobes_child(struct task_struct *task)
98 struct sspt_proc *proc = sspt_proc_get_by_task(current);
100 recover_child(task, proc);
104 /* Delete uprobs in children at fork */
105 static int ret_handler_cp(struct kretprobe_instance *ri, struct pt_regs *regs)
107 struct task_struct *task = (struct task_struct *)regs_return_value(regs);
109 if(!task || IS_ERR(task))
112 if(task->mm != current->mm) { /* check flags CLONE_VM */
113 rm_uprobes_child(task);
115 if (check_task(current)) {
116 struct sspt_proc *proc;
118 proc = sspt_proc_get_new(task);
119 sspt_proc_install(proc);
126 static struct kretprobe cp_kretprobe = {
127 .handler = ret_handler_cp,
133 ******************************************************************************
135 ******************************************************************************
138 /* Detects when target process removes IPs. */
139 static int mr_pre_handler(struct kprobe *p, struct pt_regs *regs)
141 struct sspt_proc *proc = NULL;
142 struct task_struct *task = (struct task_struct *)regs->ARM_r0; /* for ARM */
144 if (!is_us_instrumentation() || task->tgid != task->pid) {
148 proc = sspt_proc_get_by_task(task);
150 int ret = sspt_proc_uninstall(proc, task, US_UNREGS_PROBE);
152 printk("failed to uninstall IPs (%d)!\n", ret);
155 dbi_unregister_all_uprobes(task);
162 static struct kprobe mr_kprobe = {
163 .pre_handler = mr_pre_handler
169 ******************************************************************************
171 ******************************************************************************
174 static int remove_unmap_probes(struct task_struct *task, struct sspt_proc *proc, unsigned long start, size_t len)
176 struct mm_struct *mm = task->mm;
177 struct vm_area_struct *vma;
179 if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE - start) {
183 if ((len = PAGE_ALIGN(len)) == 0) {
187 vma = find_vma(mm, start);
188 if (vma && check_vma(vma)) {
189 struct sspt_file *file;
190 unsigned long end = start + len;
191 struct dentry *dentry = vma->vm_file->f_dentry;
193 file = sspt_proc_find_file(proc, dentry);
195 if (vma->vm_start == start || vma->vm_end == end) {
196 sspt_file_uninstall(file, task, US_UNREGS_PROBE);
199 unsigned long page_addr;
200 struct sspt_page *page;
202 for (page_addr = vma->vm_start; page_addr < vma->vm_end; page_addr += PAGE_SIZE) {
203 page = sspt_find_page_mapped(file, page_addr);
205 sspt_unregister_page(page, US_UNREGS_PROBE, task);
209 if (sspt_file_check_install_pages(file)) {
219 /* Detects when target removes IPs. */
220 static int unmap_pre_handler(struct kprobe *p, struct pt_regs *regs)
223 struct mm_struct *mm = (struct mm_struct *)regs->ARM_r0;
224 unsigned long start = regs->ARM_r1;
225 size_t len = (size_t)regs->ARM_r2;
227 struct sspt_proc *proc = NULL;
228 struct task_struct *task = current;
230 //if user-space instrumentation is not set
231 if (!is_us_instrumentation()) {
235 proc = sspt_proc_get_by_task(task);
237 if (remove_unmap_probes(task, proc, start, len)) {
238 printk("ERROR do_munmap: start=%lx, len=%x\n", start, len);
246 static struct kprobe unmap_kprobe = {
247 .pre_handler = unmap_pre_handler
252 int register_helper(void)
256 /* install kprobe on 'do_munmap' to detect when for remove user space probes */
257 ret = dbi_register_kprobe(&unmap_kprobe);
259 printk("dbi_register_kprobe(do_munmap) result=%d!\n", ret);
263 /* install kprobe on 'mm_release' to detect when for remove user space probes */
264 ret = dbi_register_kprobe(&mr_kprobe);
266 printk("dbi_register_kprobe(mm_release) result=%d!\n", ret);
267 goto unregister_unmap;
271 /* install kretprobe on 'copy_process' */
272 ret = dbi_register_kretprobe(&cp_kretprobe);
274 printk("dbi_register_kretprobe(copy_process) result=%d!\n", ret);
278 /* install kretprobe on 'do_page_fault' to detect when they will be loaded */
279 ret = dbi_register_kretprobe(&pf_kretprobe);
281 printk("dbi_register_kretprobe(do_page_fault) result=%d!\n", ret);
288 dbi_unregister_kretprobe(&cp_kretprobe);
291 dbi_unregister_kprobe(&mr_kprobe, NULL);
294 dbi_unregister_kprobe(&unmap_kprobe, NULL);
299 void unregister_helper(void)
301 /* uninstall kretprobe with 'do_page_fault' */
302 dbi_unregister_kretprobe(&pf_kretprobe);
304 /* uninstall kretprobe with 'copy_process' */
305 dbi_unregister_kretprobe(&cp_kretprobe);
307 /* uninstall kprobe with 'mm_release' */
308 dbi_unregister_kprobe(&mr_kprobe, NULL);
310 /* uninstall kprobe with 'do_munmap' */
311 dbi_unregister_kprobe(&unmap_kprobe, NULL);
314 int init_helper(void)
317 addr = swap_ksyms("do_page_fault");
319 printk("Cannot find address for page fault function!\n");
322 pf_kretprobe.kp.addr = (kprobe_opcode_t *)addr;
324 addr = swap_ksyms("copy_process");
326 printk("Cannot find address for copy_process function!\n");
329 cp_kretprobe.kp.addr = (kprobe_opcode_t *)addr;
331 addr = swap_ksyms("mm_release");
333 printk("Cannot find address for mm_release function!\n");
336 mr_kprobe.addr = (kprobe_opcode_t *)addr;
338 addr = swap_ksyms("do_munmap");
340 printk("Cannot find address for do_munmap function!\n");
343 unmap_kprobe.addr = (kprobe_opcode_t *)addr;
348 void uninit_helper(void)