void open_pid(pid_t pid) { Process *proc; char *filename; if (trace_pid(pid) < 0) { fprintf(stderr, "Cannot attach to pid %u: %s\n", pid, strerror(errno)); return; } filename = pid2name(pid); if (!filename) { fprintf(stderr, "Cannot trace pid %u: %s\n", pid, strerror(errno)); return; } proc = open_program(filename, pid); continue_process(pid); proc->breakpoints_enabled = 1; //modify for android attach_child_thread(proc); }
//thread function with connections check loop static unsigned __stdcall checkthread(void *dummy) { #ifdef _DEBUG _OutputDebugString(_T("check thread started")); #endif while(1) { struct CONNECTION* conn=NULL,*connOld=first,*cur=NULL; #ifdef _DEBUG _OutputDebugString(_T("checking connections table...")); #endif if (WAIT_OBJECT_0 == WaitForSingleObject(killCheckThreadEvent,100)) { hConnectionCheckThread=NULL; return 0; } conn=GetConnectionsTable(); cur=conn; while(cur!=NULL) { if (searchConnection(first,cur->strIntIp,cur->strExtIp,cur->intIntPort,cur->intExtPort,cur->state)==NULL && (settingStatusMask & (1 << (cur->state-1)))) { #ifdef _DEBUG TCHAR msg[1024]; mir_sntprintf(msg,_countof(msg),_T("%s:%d\n%s:%d"),cur->strIntIp,cur->intIntPort,cur->strExtIp,cur->intExtPort); _OutputDebugString(_T("New connection: %s"),msg); #endif pid2name(cur->Pid, cur->PName, SIZEOF(cur->PName)); if ( WAIT_OBJECT_0 == WaitForSingleObject( hExceptionsMutex, 100 )) { if (checkFilter(connExceptions,cur)) { showMsg(cur->PName,cur->Pid,cur->strIntIp,cur->strExtIp,cur->intIntPort,cur->intExtPort,cur->state); SkinPlaySound(PLUGINNAME_NEWSOUND); } ReleaseMutex(hExceptionsMutex); } } cur=cur->next; } first=conn; deleteConnectionsTable(connOld); Sleep(settingInterval); } hConnectionCheckThread=NULL; return 1; }
int init_connection(state_t state, int pid) { int fd; if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { return -1; } char unix_path[128] = { 0 }; pid2name(pid, unix_path); struct sockaddr_un addr; bzero(&addr, sizeof(addr)); addr.sun_family = AF_UNIX; memcpy(addr.sun_path, unix_path, strlen(unix_path) + 1); if (connect(fd, (struct sockaddr *)&addr, strlen(unix_path) + 1 + sizeof(addr.sun_family)) == -1) { return -1; } return fd; }
int init_socket(state_t state) { struct sockaddr_un addr; int fd; if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { return -1; } char unix_path[128] = { 0 }; pid2name(state->myid.pid, unix_path); unlink(unix_path); bzero(&addr, sizeof(addr)); addr.sun_family = AF_UNIX; memcpy(addr.sun_path, unix_path, strlen(unix_path)+1); if (bind(fd, (struct sockaddr *)&addr, strlen(unix_path) + 1 + sizeof(addr.sun_family)) || listen(fd, 128) < 0) { return -1; } return fd; }
static void handle_exec(Event * event) { Process * proc = event->proc; pid_t saved_pid; debug(DEBUG_FUNCTION, "handle_exec(pid=%d)", proc->pid); if (proc->state == STATE_IGNORED) { untrace_pid(proc->pid); remove_process(proc); return; } output_line(proc, "--- Called exec() ---"); proc->mask_32bit = 0; proc->personality = 0; proc->arch_ptr = NULL; free(proc->filename); proc->filename = pid2name(proc->pid); saved_pid = proc->pid; proc->pid = 0; breakpoints_init(proc, 0); proc->pid = saved_pid; proc->callstack_depth = 0; continue_process(proc->pid); }
int process_clone(struct Process *retp, struct Process *proc, pid_t pid) { if (process_bare_init(retp, proc->filename, pid, 0) < 0) { fail1: fprintf(stderr, "failed to clone process %d->%d : %s\n", proc->pid, pid, strerror(errno)); return -1; } retp->tracesysgood = proc->tracesysgood; retp->e_machine = proc->e_machine; retp->e_class = proc->e_class; /* For non-leader processes, that's all we need to do. */ if (retp->leader != retp) return 0; /* Clone symbols first so that we can clone and relink * breakpoints. */ struct library *lib; struct library **nlibp = &retp->libraries; for (lib = proc->leader->libraries; lib != NULL; lib = lib->next) { *nlibp = malloc(sizeof(**nlibp)); if (*nlibp == NULL || library_clone(*nlibp, lib) < 0) { fail2: process_bare_destroy(retp, 0); /* Error when cloning. Unroll what was done. */ for (lib = retp->libraries; lib != NULL; ) { struct library *next = lib->next; library_destroy(lib); free(lib); lib = next; } goto fail1; } nlibp = &(*nlibp)->next; } /* Now clone breakpoints. Symbol relinking is done in * clone_single_bp. */ struct clone_single_bp_data data = { .old_proc = proc, .new_proc = retp, .error = 0, }; dict_apply_to_all(proc->leader->breakpoints, &clone_single_bp, &data); if (data.error < 0) goto fail2; /* And finally the call stack. */ /* XXX clearly the callstack handling should be moved to a * separate module and this whole business extracted to * callstack_clone, or callstack_element_clone. */ memcpy(retp->callstack, proc->callstack, sizeof(retp->callstack)); retp->callstack_depth = proc->callstack_depth; size_t i; for (i = 0; i < retp->callstack_depth; ++i) { struct callstack_element *elem = &retp->callstack[i]; struct fetch_context *ctx = elem->fetch_context; if (ctx != NULL) { struct fetch_context *nctx = fetch_arg_clone(retp, ctx); if (nctx == NULL) { size_t j; fail3: for (j = 0; j < i; ++j) { nctx = elem->fetch_context; fetch_arg_done(nctx); elem->fetch_context = NULL; } goto fail2; } elem->fetch_context = nctx; } struct value_dict *args = elem->arguments; if (args != NULL) { struct value_dict *nargs = malloc(sizeof(*nargs)); if (nargs == NULL || val_dict_clone(nargs, args) < 0) { size_t j; for (j = 0; j < i; ++j) { nargs = elem->arguments; val_dict_destroy(nargs); free(nargs); elem->arguments = NULL; } /* Pretend that this round went well, * so that fail3 frees I-th * fetch_context. */ ++i; goto fail3; } elem->arguments = nargs; } /* If it's not a syscall, we need to find the * corresponding library symbol in the cloned * library. */ if (!elem->is_syscall && elem->c_un.libfunc != NULL) { struct library_symbol *libfunc = elem->c_un.libfunc; int rc = proc_find_symbol(retp, libfunc, NULL, &elem->c_un.libfunc); assert(rc == 0); } } /* At this point, retp is fully initialized, except for OS and * arch parts, and we can call private_process_destroy. */ if (os_process_clone(retp, proc) < 0) { private_process_destroy(retp, 0); return -1; } if (arch_process_clone(retp, proc) < 0) { os_process_destroy(retp); private_process_destroy(retp, 0); return -1; } return 0; } static int open_one_pid(pid_t pid) { Process *proc; char *filename; debug(DEBUG_PROCESS, "open_one_pid(pid=%d)", pid); /* Get the filename first. Should the trace_pid fail, we can * easily free it, untracing is more work. */ if ((filename = pid2name(pid)) == NULL || trace_pid(pid) < 0) { fail: free(filename); return -1; } proc = open_program(filename, pid); if (proc == NULL) goto fail; free(filename); trace_set_options(proc); return 0; }
struct libref *elf_read_main_binary(struct task *task, int was_attached) { char fname[PATH_MAX]; int ret; char *filename; struct mt_elf mte = { }; unsigned long entry; unsigned long base; struct libref *libref; filename = pid2name(task->pid); if (!filename) return NULL; libref = libref_new(LIBTYPE_MAIN); if (libref == NULL) goto fail1; ret = readlink(filename, fname, sizeof(fname) - 1); if (ret == -1) goto fail2; fname[ret] = 0; free(filename); libref_set_filename(libref, fname); if (elf_read(&mte, task, fname) == -1) goto fail3; task->is_64bit = is_64bit(&mte); if (process_get_entry(task, &entry, &base) < 0) { fprintf(stderr, "Couldn't find process entry of %s\n", filename); goto fail3; } mte.bias = entry - mte.ehdr.e_entry - mte.vstart; mte.entry_addr = entry; if (elf_lib_init(&mte, task, libref)) goto fail3; close_elf(&mte); report_attach(task, was_attached); library_add(task, libref); if (!mte.interp) return libref; struct mt_elf mte_ld = { }; if (copy_str_from_proc(task, ARCH_ADDR_T(mte.bias + mte.interp - mte.vstart), fname, sizeof(fname)) == -1) { fprintf(stderr, "fatal error: cannot get loader name for pid=%d\n", task->pid); abort(); } if (!elf_read(&mte_ld, task, fname)) { struct libref *libref; libref = libref_new(LIBTYPE_LOADER); if (libref == NULL) goto fail4; libref_set_filename(libref, fname); mte_ld.bias = base; mte_ld.entry_addr = base + mte_ld.ehdr.e_entry - mte.vstart; ret = elf_lib_init(&mte_ld, task, libref); if (!ret) { library_add(task, libref); if (linkmap_init(task, ARCH_ADDR_T(mte.bias + mte.dyn - mte.vstart))) { arch_addr_t addr = find_solib_break(&mte_ld); if (!addr) addr = ARCH_ADDR_T(entry); struct entry_breakpoint *entry_bp = (void *)breakpoint_new_ext(task, addr, NULL, 0, sizeof(*entry_bp) - sizeof(entry_bp->breakpoint)); if (!entry_bp) fprintf(stderr, "Couldn't initialize entry breakpoint for PID %d.\n" "Tracing events may be missed.\n", task->pid ); else { entry_bp->breakpoint.on_hit = entry_breakpoint_on_hit; entry_bp->breakpoint.locked = 1; entry_bp->dyn_addr = ARCH_ADDR_T(mte.bias + mte.dyn - mte.vstart); breakpoint_enable(task, &entry_bp->breakpoint); } } } else { fprintf(stderr, "Couldn't read dynamic loader `%s` for PID %d.\n" "Tracing events may be missed.\n", fname, task->pid ); } fail4: close_elf(&mte_ld); } else { fprintf(stderr, "Couldn't open dynamic loader `%s` for PID %d.\n" "Tracing events may be missed.\n", fname, task->pid ); } return libref; fail3: close_elf(&mte); fail2: libref_delete(libref); fail1: free(filename); return libref; }