#include "us_inst.h"
#include <us_manager/us_manager.h>
- static int wrt_launcher_port = 0;
++static int wrt_launcher_port;
+
static int set_config(struct conf_data *conf)
{
int ret;
}
fi->addr = addr;
- fi->args = args;
- fi->ret_type = ret_type;
+
+ switch (type) {
+ case SWAP_RETPROBE:
+ if (get_retprobe(mb, &(fi->probe_i)) != 0)
+ goto free_func_inst;
+ break;
+ case SWAP_WEBPROBE:
+ if (get_webprobe(mb, &(fi->probe_i)) != 0)
+ goto free_func_inst;
+ break;
+ case SWAP_PRELOAD_PROBE:
+ if (get_preload_probe(mb, &(fi->probe_i)) != 0)
+ goto free_func_inst;
+ break;
+ case SWAP_GET_CALLER:
+ if (get_get_caller_probe(mb, &(fi->probe_i)) != 0)
+ goto free_func_inst;
+ break;
+ case SWAP_GET_CALL_TYPE:
+ if (get_get_call_type_probe(mb, &(fi->probe_i)) != 0)
+ goto free_func_inst;
+ break;
+ default:
- printk(KERN_WARNING "SWAP PARSER: Wrong probe type %d!\n", type);
++ printk(KERN_WARNING "SWAP PARSER: Wrong probe type %d!\n",
++ type);
+ goto free_func_inst;
+ }
return fi;
switch (mt) {
case MT_ADD:
- ret = pf_register_probe(pfg, dentry, func->addr, &func->probe_i);
- ret = pf_register_probe(pfg, dentry, func->addr, func->args,
- func->ret_type);
++ ret = pf_register_probe(pfg, dentry, func->addr,
++ &func->probe_i);
break;
case MT_DEL:
ret = pf_unregister_probe(pfg, dentry, func->addr);
return addr;
}
- printk("failed to dereference a pointer, ptr=%p\n", ptr);
+static inline void swap_put_uarg(struct pt_regs *regs, unsigned long n,
+ unsigned long val)
+{
+ u32 *ptr;
+
+ switch (n) {
+ case 0:
+ regs->ARM_r0 = val;
+ case 1:
+ regs->ARM_r1 = val;
+ case 2:
+ regs->ARM_r2 = val;
+ case 3:
+ regs->ARM_r3 = val;
+ }
+
+ ptr = (u32 *)regs->ARM_sp + n - 4;
+ if (put_user(val, ptr))
++ printk(KERN_INFO "failed to dereference a pointer, ptr=%p\n",
++ ptr);
+}
+
int swap_arch_init_uprobes(void);
void swap_arch_exit_uprobes(void);
return addr;
}
- unsigned long val)
+static inline void swap_put_uarg(struct pt_regs *regs, unsigned long n,
- printk("failed to dereference a pointer, ptr=%p\n", ptr);
++ unsigned long val)
+{
+ u32 *ptr;
+
+ /* 1 - return address saved on top of the stack */
+ ptr = (u32 *)regs->sp + n + 1;
+ if (put_user(val, ptr))
++ printk(KERN_INFO "failed to dereference a pointer, ptr=%p\n",
++ ptr);
+}
+
int swap_arch_init_uprobes(void);
void swap_arch_exit_uprobes(void);
*/
void add_uprobe_table(struct kprobe *p)
{
- hlist_add_head_rcu(&p->is_hlist, &uprobe_insn_slot_table[hash_ptr(p->ainsn.insn, UPROBE_HASH_BITS)]);
- INIT_HLIST_NODE(&p->is_hlist);
+ hlist_add_head_rcu(&p->is_hlist,
+ &uprobe_insn_slot_table[hash_ptr(p->ainsn.insn,
+ UPROBE_HASH_BITS)]);
}
/**
p->count = 0;
#endif
- // get the first item
+ /* get the first item */
old_p = get_ukprobe(p->addr, kp2up(p)->task->tgid);
if (old_p) {
- printk("uprobe on task[%u %u %s] vaddr=%p is there\n",
+ struct task_struct *task = up->task;
+
+ /* TODO: add support many uprobes on address */
++ printk(KERN_INFO "uprobe on task[%u %u %s] vaddr=%p is there\n",
+ task->tgid, task->pid, task->comm, p->addr);
+ ret = -EINVAL;
+ goto out;
#ifdef CONFIG_ARM
p->safe_arm = old_p->safe_arm;
p->safe_thumb = old_p->safe_thumb;
/* debug */
void img_ip_print(struct img_ip *ip)
{
- printk(KERN_INFO "### addr=8%lx, args=%s\n",
- ip->addr, ip->args);
+ if (ip->probe_i.probe_type == SWAP_RETPROBE)
- printk("### addr=8%lx, args=%s\n", ip->addr,
- ip->probe_i.rp_i.args);
++ printk(KERN_INFO "### addr=8%lx, args=%s\n",
++ ip->addr, ip->probe_i.rp_i.args);
}
/* debug */
file = create_img_file(dentry);
- ret = img_file_add_ip(file, addr, args, ret_type);
+ ret = img_file_add_ip(file, addr, probe_i);
if (ret) {
- printk("Cannot add ip to img file\n");
+ printk(KERN_INFO "Cannot add ip to img file\n");
free_img_file(file);
- }
- else
+ } else {
img_add_file_by_list(proc, file);
+ }
return ret;
}
void free_img_proc(struct img_proc *proc);
int img_proc_add_ip(struct img_proc *proc, struct dentry *dentry,
- unsigned long addr, const char *args, char ret_type);
+ unsigned long addr, struct probe_info *probe_i);
- int img_proc_del_ip(struct img_proc *proc, struct dentry *dentry, unsigned long addr);
+ int img_proc_del_ip(struct img_proc *proc,
+ struct dentry *dentry,
+ unsigned long addr);
/* debug */
void img_proc_print(struct img_proc *proc);
INIT_LIST_HEAD(&ip->list);
ip->offset = offset;
- ip->args = (char *)ip + sizeof(*ip);
- ip->ret_type = ret_type;
-
- /* copy args */
- memcpy(ip->args, args, len);
+ ip->page = page;
- /* retprobe */
- ip->retprobe.handler = ret_handler;
- ip->retprobe.entry_handler = entry_handler;
+ probe_info_copy(probe_i, &ip->probe_i);
+ probe_info_init(&ip->probe_i, ip);
} else {
- printk("Cannot kmalloc in create_ip function!\n");
+ printk(KERN_INFO "Cannot kmalloc in create_ip function!\n");
}
return ip;
static inline int sspt_register_usprobe(struct us_ip *ip)
{
int ret;
+ struct uprobe *up = NULL;
- /* for retuprobe */
- ip->retprobe.up.task = ip->page->file->proc->task;
- ip->retprobe.up.sm = ip->page->file->proc->sm;
+ up = probe_info_get_uprobe(&ip->probe_i, ip);
- ret = swap_register_uretprobe(&ip->retprobe);
+ if (!up) {
- printk("SWAP US_MANAGER: failed getting uprobe!\n");
++ printk(KERN_INFO "SWAP US_MANAGER: failed getting uprobe!\n");
+ return -EINVAL;
+ }
+
+ up->task = ip->page->file->proc->task;
+ up->sm = ip->page->file->proc->sm;
+
+ ret = probe_info_register(&ip->probe_i, ip);
if (ret) {
struct sspt_file *file = ip->page->file;
char *name = file->dentry->d_iname;
- unsigned long addr = (unsigned long)ip->retprobe.up.kp.addr;
+ unsigned long addr = (unsigned long)up->kp.addr;
unsigned long offset = addr - file->vm_start;
- printk("swap_register_uretprobe() failure %d (%s:%lx|%lx)\n",
- ret, name, offset, (unsigned long)ip->retprobe.up.kp.opcode);
+ printk(KERN_INFO "swap_register_uretprobe() failure %d "
+ "(%s:%lx|%lx)\n", ret, name, offset,
+ (unsigned long)ip->retprobe.up.kp.opcode);
}
return ret;
}
- static inline int sspt_unregister_usprobe(struct task_struct *task, struct us_ip *ip, enum US_FLAGS flag)
-static inline int do_unregister_usprobe(struct us_ip *ip, int disarm)
-{
- __swap_unregister_uretprobe(&ip->retprobe, disarm);
-
- return 0;
-}
-
+ static inline int sspt_unregister_usprobe(struct task_struct *task,
+ struct us_ip *ip,
+ enum US_FLAGS flag)
{
- int err = 0;
+ struct uprobe *up = NULL;
switch (flag) {
case US_UNREGS_PROBE:
static inline void print_ip(struct us_ip *ip, int i)
{
- printk(KERN_INFO "### addr[%2d]=%lx, R_addr=%lx\n",
- i, (unsigned long)ip->offset,
- (unsigned long)ip->retprobe.up.kp.addr);
- print_retprobe(&ip->retprobe);
+ if (ip->probe_i.probe_type == SWAP_RETPROBE) {
+ struct uretprobe *rp = &ip->retprobe;
+
- printk("### addr[%2d]=%lx, R_addr=%lx\n",
- i, (unsigned long)ip->offset,
- (unsigned long)rp->up.kp.addr);
++ printk(KERN_INFO "### addr[%2d]=%lx, R_addr=%lx\n",
++ i, (unsigned long)ip->offset,
++ (unsigned long)rp->up.kp.addr);
+ print_retprobe(rp);
+ }
}
static inline void print_page_probes(const struct sspt_page *page)
* @return Void
*/
void sspt_file_add_ip(struct sspt_file *file, unsigned long offset,
- const char *args, char ret_type)
+ struct probe_info *probe_i)
{
- struct sspt_page *page = sspt_find_page_or_new(file, offset & PAGE_MASK);
+ struct sspt_page *page =
+ sspt_find_page_or_new(file, offset & PAGE_MASK);
- // FIXME: delete ip
+ /* FIXME: delete ip */
- struct us_ip *ip = create_ip(offset, args, ret_type);
+ struct us_ip *ip = create_ip(offset, probe_i, page);
sspt_add_ip(page, ip);
}
struct sspt_page *sspt_find_page_mapped(struct sspt_file *file,
unsigned long page);
void sspt_file_add_ip(struct sspt_file *file, unsigned long offset,
- const char *args, char ret_type);
+ struct probe_info *probe_i);
- struct sspt_page *sspt_get_page(struct sspt_file *file, unsigned long offset_addr);
+ struct sspt_page *sspt_get_page(struct sspt_file *file,
+ unsigned long offset_addr);
void sspt_put_page(struct sspt_page *page);
int sspt_file_check_install_pages(struct sspt_file *file);
}
EXPORT_SYMBOL_GPL(custom_exit_event);
- void* m_buffer;
+
+
+
+
+/* ============================================================================
+ * = WEB APP EVENT =
+ * ============================================================================
+ */
+
+/* TODO: develop method for obtaining this data during build... */
+/* location: webkit2-efl-123997_0.11.113/Source/WTF/wtf/text/StringImpl.h:70 */
+struct MStringImpl {
+ unsigned m_refCount;
+ unsigned m_length;
+ union {
+ const unsigned char *m_data8;
+ const unsigned short *m_data16;
+ };
+ union {
++ void *m_buffer;
+ struct MStringImpl *m_substringBuffer;
+ unsigned short *m_copyData16;
+ };
+ unsigned m_hashAndFlags;
+};
+
+/* location: webkit2-efl-123997_0.11.113/Source/JavaScriptCore/profiler/
+ * CallIdentifier.h:36
+ */
+struct MCallIdentifier {
+ struct MStringImpl *m_name;
+ struct MStringImpl *m_url;
+ unsigned m_lineNumber;
+};
+
+int entry_web_event(unsigned long func_addr, struct pt_regs *regs)
+{
+ char *buf, *pl;
+ long t;
+ int ret = 0, n, lnum;
+ struct MCallIdentifier *callIdentifier;
+ struct {
+ const char *str;
+ int len;
+ } m_name, m_url;
+ struct task_struct *task = current;
+
+ if (!check_event(current))
+ return 0;
+
+ callIdentifier = (void *)swap_get_uarg(regs, 2);
+
+ if (get_user(t, (int *)&callIdentifier->m_name) ||
+ get_user(m_name.str, &((struct MStringImpl *)t)->m_data8) ||
+ get_user(m_name.len, &((struct MStringImpl *)t)->m_length) ||
+ get_user(t, (int *)&callIdentifier->m_url) ||
+ get_user(m_url.str, &((struct MStringImpl *)t)->m_data8) ||
+ get_user(m_url.len, &((struct MStringImpl *)t)->m_length) ||
+ get_user(lnum, (int *)&callIdentifier->m_lineNumber)) {
+ print_err("%s: cannot read user memory\n", __func__);
+ return 0;
+ }
+
+ buf = get_current_buf();
+ pl = pack_basic_msg_fmt(buf, MSG_WEB_FUNCTION_ENTRY);
+
+ /* Pack message */
+ /* PID */
+ *(u32 *)pl = task->tgid;
+ pl += sizeof(u32);
+ /* TID */
+ *(u32 *)pl = task->pid;
+ pl += sizeof(u32);
+ /* Line number (in source file) */
+ *(u32 *)pl = lnum;
+ pl += sizeof(u32);
+ /* Function name */
+ n = strncpy_from_user(pl, m_name.str, m_name.len);
+ if (n < 0) {
+ print_err("%s: cannot read user memory (function name)\n",
+ __func__);
+ goto put_current_buf_return;
+ } else {
+ pl[n] = '\0';
+ pl += n + 1;
+ }
+ /* URL (source file) */
+ n = strncpy_from_user(pl, m_url.str, m_url.len);
+ if (n < 0) {
+ print_err("%s: cannot read user memory (url)\n", __func__);
+ goto put_current_buf_return;
+ } else {
+ pl[n] = '\0';
+ pl += n + 1;
+ }
+
+ set_len_msg(buf, pl);
+ ret = write_to_buffer(buf);
+
+put_current_buf_return:
+ put_current_buf();
+ return ret;
+}
+EXPORT_SYMBOL_GPL(entry_web_event);
+
+int exit_web_event(unsigned long func_addr, struct pt_regs *regs)
+{
+ char *buf, *pl;
+ long t;
+ int ret = 0, n;
+ struct MCallIdentifier *callIdentifier;
+ struct {
+ const char *str;
+ int len;
+ } m_name;
+ struct task_struct *task = current;
+
+ if (!check_event(current))
+ return 0;
+
+ callIdentifier = (void *)swap_get_uarg(regs, 2);
+
+ if (get_user(t, (int *)&callIdentifier->m_name) ||
+ get_user(m_name.str, &((struct MStringImpl *)t)->m_data8) ||
+ get_user(m_name.len, &((struct MStringImpl *)t)->m_length)) {
+ print_err("%s: cannot read user memory\n", __func__);
+ return 0;
+ }
+
+ buf = get_current_buf();
+ pl = pack_basic_msg_fmt(buf, MSG_WEB_FUNCTION_EXIT);
+
+ /* Pack message */
+ /* PID */
+ *(u32 *)pl = task->tgid;
+ pl += sizeof(u32);
+ /* TID */
+ *(u32 *)pl = task->pid;
+ pl += sizeof(u32);
+ /* Function name */
+ n = strncpy_from_user(pl, m_name.str, m_name.len);
+ if (n < 0) {
+ print_err("%s: cannot read user memory (function name)\n",
+ __func__);
+ goto put_current_buf_return;
+ } else {
+ pl[n] = '\0';
+ pl += n + 1;
+ }
+
+ set_len_msg(buf, pl);
+ ret = write_to_buffer(buf);
+
+put_current_buf_return:
+ put_current_buf();
+ return ret;
+}
+EXPORT_SYMBOL_GPL(exit_web_event);
+
+
+
+
+
SWAP_LIGHT_INIT_MODULE(NULL, event_filter_init, event_filter_exit,
init_debugfs_writer, exit_debugfs_writer);