Exemplo n.º 1
0
Arquivo: ui.c Projeto: idl3r/rappel
static
void ui_read(
		const pid_t child_pid,
		const char *line)
{
	char *dupline = strdup(line);

	if (!dupline) {
		perror("strdup");
		return;
	}

	char *saveptr;

	const char *dotread = strtok_r(dupline, " ", &saveptr);

	if (!dotread || strcasecmp(dotread, ".read"))
		goto bail;

	const char *addr_str = strtok_r(NULL, " ", &saveptr);

	if (!addr_str)
		goto bail;

	errno = 0;
	const unsigned long addr = strtoul(addr_str, NULL, 0);

	if (addr == ULONG_MAX && errno) {
		perror("strtoul");
		goto bail;
	}

	const char *sz_str = strtok_r(NULL, " ", &saveptr);

	unsigned long sz = 0x10;

	if (sz_str && strlen(sz_str)) {
		errno = 0;
		sz = strtoul(sz_str, NULL, 0);

		if (sz == ULONG_MAX && errno) {
			perror("strtoul");
			goto bail;
		}
	}

	uint8_t *buf = xmalloc(sz);

	if (!ptrace_read(child_pid, (void *)addr, buf, sz))
		dump(buf, sz, addr);

	free(buf);

bail:
	free(dupline);
}
Exemplo n.º 2
0
int
print_sharelib_runtime (pid_t pid)
{
  struct link_map *lm = (struct link_map *) malloc (sizeof (struct link_map));
  char *str;

  printf ("-------- runtime process --------\n");
  printf ("PROCESS ID: [%d]\n", pid);

  lm = get_linkmap (pid);
  if (!lm)
    return -1;

#if 0
  str = ptrace_readstr (pid, (unsigned long) lm->l_name);
  printf ("[%s]\n", str);
  free (str);
#endif

  if (!lm->l_next)
    return -1;

  ptrace_read (pid, (unsigned long) lm->l_next, lm, sizeof (struct link_map));
  while (lm->l_next)
    {
      ptrace_read (pid, (unsigned long) lm->l_next, lm,
		   sizeof (struct link_map));

      str = ptrace_readstr (pid, (unsigned long) lm->l_name);
      printf ("[%s]\n", str);
      free (str);
    }

  printf ("------------ end ------------\n");
  return 0;
}
Exemplo n.º 3
0
dl_fl_t *ptrace_find_dlinfo(int pid) {
    Elf32_Sym sym;
    Elf32_Addr addr;
    struct soinfo lsi;
#define LIBDLSO "libdl.so"
    Elf32_Addr base_start = 0;
    Elf32_Addr base_end = 0;
    Elf32_Addr base = get_linker_base(pid, &base_start, &base_end);

    if (base == 0) {
        printf("no linker found\n");
        return NULL ;
    } else {
        printf("search libdl.so from %08u to %08u\n", base_start, base_end);
    }

    for (addr = base_start; addr < base_end; addr += 4) {
        char soname[strlen(LIBDLSO)];
        Elf32_Addr off = 0;

        ptrace_read(pid, addr, soname, strlen(LIBDLSO));
        if (strncmp(LIBDLSO, soname, strlen(LIBDLSO))) {
            continue;
        }

        printf("soinfo found at %08u\n", addr);
        printf("symtab: %p\n", lsi.symtab);
        ptrace_read(pid, addr, &lsi, sizeof(lsi));

        off = (Elf32_Addr)lsi.symtab;

        ptrace_read(pid, off, &sym, sizeof(sym));
        //just skip
        off += sizeof(sym);

        ptrace_read(pid, off, &sym, sizeof(sym));
        ldl.l_dlopen = sym.st_value;
        off += sizeof(sym);

        ptrace_read(pid, off, &sym, sizeof(sym));
        ldl.l_dlclose = sym.st_value;
        off += sizeof(sym);

        ptrace_read(pid, off, &sym, sizeof(sym));
        ldl.l_dlsym = sym.st_value;
        off += sizeof(sym);

        printf("dlopen addr %p\n", (void*) ldl.l_dlopen);
        printf("dlclose addr %p\n", (void*) ldl.l_dlclose);
        printf("dlsym addr %p\n", (void*) ldl.l_dlsym);
        return &ldl;

    }
    printf("%s not found!\n", LIBDLSO);
    return NULL ;
}
Exemplo n.º 4
0
int
main (int argc, char *argv[])
{
  int pid;
  struct link_map *map;
  char sym_name[256];
  unsigned long sym_addr;
  unsigned long new_addr, old_addr, rel_addr;

  pid = atoi (argv[1]);

  ptrace_attach (pid);

  map = get_linkmap (pid);

  sym_addr = find_symbol (pid, map, "_dl_open");
  printf ("found _dl_open at addr %p\n", sym_addr);
  call_dl_open (pid, sym_addr,
		"/home/joker/JustForFun/Injectso/passwd/so.so");

/* 找到我们的新函数newread的地址 */
  strcpy (sym_name, "newread");	/* intercept */
  sym_addr = find_symbol (pid, map, sym_name);
  printf ("%s addr\t %p\n", sym_name, sym_addr);

  /* 找到read的RELOCATION地址 */
  strcpy (sym_name, "read");
  rel_addr = find_sym_in_rel (pid, sym_name);
  printf ("%s rel addr\t %p\n", sym_name, rel_addr);

  /* 找到用于保存read地址的指针 */
  strcpy (sym_name, "oldread");
  old_addr = find_symbol (pid, map, sym_name);
  printf ("%s addr\t %p\n", sym_name, old_addr);

  /* 函数重定向 */
  puts ("intercept...");	/* intercept */
  ptrace_read (pid, rel_addr, &new_addr, sizeof (new_addr));
  ptrace_write (pid, old_addr, &new_addr, sizeof (new_addr));
  ptrace_write (pid, rel_addr, &sym_addr, sizeof (sym_addr));
  puts ("injectso ok");

  /* 脱离进程 */
  ptrace_detach (pid);

  exit (0);
}
Exemplo n.º 5
0
void call_shit(struct elf_info *einfo) {
    unsigned long addr2 = 0;
    unsigned long rel_addr = find_sym_in_rel(einfo, "math_shit");
    regs_t regs;
    ptrace_read(einfo->pid, rel_addr, &addr2, sizeof(long));
    printf("math_shit rel addr\t %lx\n", rel_addr);
    printf("addr2 is \t %lx\n", addr2);
    ptrace_readreg(einfo->pid, &regs);
    ptrace_dump_regs(&regs,"before call to call_shit\n");
#ifdef THUMB
    regs.ARM_lr = 1;
#else
    regs.ARM_lr = 0;
#endif
    regs.ARM_r0 = 5;
    regs.ARM_r1 = 6;
    regs.ARM_r2 = 7;
    regs.ARM_r3 = 8;
    {
        int a5 = 9;
        ptrace_push(einfo->pid, &regs, &a5, 4);
        ptrace_push(einfo->pid, &regs, &a5, 4);
        ptrace_push(einfo->pid, &regs, &a5, 4);
        ptrace_push(einfo->pid, &regs, &a5, 4);
        ptrace_push(einfo->pid, &regs, &a5, 4);
        ptrace_push(einfo->pid, &regs, &a5, 4);
        ptrace_push(einfo->pid, &regs, &a5, 4);
        ptrace_push(einfo->pid, &regs, &a5, 4);
        ptrace_push(einfo->pid, &regs, &a5, 4);
        a5 = 10;
        ptrace_push(einfo->pid, &regs, &a5, 4);
    }
    regs.ARM_pc = addr2;
    ptrace_writereg(einfo->pid, &regs);
    ptrace_cont(einfo->pid);
    printf("done %d\n",  ptrace_wait_for_signal(einfo->pid,SIGSEGV));
    ptrace_readreg(einfo->pid, &regs);
    ptrace_dump_regs(&regs,"before return call_shit\n");
}
Exemplo n.º 6
0
static struct link_map *
get_linkmap (pid_t pid)
{
  Elf32_Ehdr *ehdr = (Elf32_Ehdr *) malloc (sizeof (Elf32_Ehdr));
  Elf32_Phdr *phdr = (Elf32_Phdr *) malloc (sizeof (Elf32_Phdr));
  Elf32_Dyn *dyn = (Elf32_Dyn *) malloc (sizeof (Elf32_Dyn));
  Elf32_Word got;
  unsigned long phdr_addr, dyn_addr, map_addr;
  struct link_map *map =
    (struct link_map *) malloc (sizeof (struct link_map));
  int i = 0;

  ptrace_read (pid, IMAGE_ADDR, ehdr, sizeof (Elf32_Ehdr));
  phdr_addr = IMAGE_ADDR + ehdr->e_phoff;

  ptrace_read (pid, phdr_addr, phdr, sizeof (Elf32_Phdr));
  while (phdr->p_type != PT_DYNAMIC)
    ptrace_read (pid, phdr_addr +=
		 sizeof (Elf32_Phdr), phdr, sizeof (Elf32_Phdr));
  dyn_addr = phdr->p_vaddr;

  ptrace_read (pid, dyn_addr, dyn, sizeof (Elf32_Dyn));
  while (dyn->d_tag != DT_PLTGOT)
    {
      ptrace_read (pid, dyn_addr + i * sizeof (Elf32_Dyn), dyn,
		   sizeof (Elf32_Dyn));
      i++;
    }

  got = (Elf32_Word) dyn->d_un.d_ptr;
  got += 4;

  ptrace_read (pid, got, &map_addr, 4);
  ptrace_read (pid, map_addr, map, sizeof (struct link_map));

  free (ehdr);
  free (phdr);
  free (dyn);
  return map;
}
Exemplo n.º 7
0
void inject_restore_socketcall(struct tracedump *td, struct pid *sp)
{
	/* int 0x80, int3 */
	unsigned char code[4] = { 0xcd, 0x80, 0xcc, 0 };
	char backup[4];
	struct user_regs_struct regs2;

	/* backup */
	ptrace_read(sp, sp->regs.eip, backup, 4);

	/* exec */
	sp->regs.eax = sp->regs.orig_eax;
	ptrace_setregs(sp, &sp->regs);
	ptrace_write(sp, sp->regs.eip, code, 4);
	ptrace_cont(sp, 0, true);

	/* read the return code */
	ptrace_getregs(sp, &regs2);
	sp->regs.eax = regs2.eax;

	/* restore */
	ptrace_setregs(sp, &sp->regs);
	ptrace_write(sp, sp->regs.eip, backup, 4);
}
Exemplo n.º 8
0
int32_t inject_socketcall(struct tracedump *td, struct pid *sp, uint32_t sc_code, ...)
{
	/* int 0x80, int3 */
	unsigned char code[4] = { 0xcd, 0x80, 0xcc, 0 };
	char backup[4];
	struct user_regs_struct regs, regs2;
	int ss_vals, ss_mem, ss;
	va_list vl;
	enum arg_type type;
	uint32_t sv;
	void *ptr;
	uint8_t *stack, *stack_mem;
	uint32_t *stack32;
	int i, j;

	/*
	 * get the required amount of stack space
	 */
	ss_vals = 0;
	ss_mem = 0;
	va_start(vl, sc_code);
	do {
		type = va_arg(vl, enum arg_type);
		if (type == AT_LAST) break;
		sv  = va_arg(vl, uint32_t);

		/* each socketcall argument takes 4 bytes */
		ss_vals += 4;

		/* if its memory, it takes additional sv bytes */
		if (type == AT_MEM_IN || type == AT_MEM_INOUT) {
			ss_mem += sv;
			ptr = va_arg(vl, void *);
		}
	} while (true);
	va_end(vl);
	ss = ss_vals + ss_mem;

	/*
	 * backup
	 */
	ptrace_getregs(sp, &regs);
	memcpy(&regs2, &regs, sizeof regs);
	ptrace_read(sp, regs.eip, backup, sizeof backup);

	/*
	 * write the stack
	 */
	stack = mmatic_zalloc(td->mm, ss);
	stack32 = (uint32_t *) stack;
	stack_mem = stack + ss_vals;

	va_start(vl, sc_code);
	i = 0; j = 0;
	do {
		type = va_arg(vl, enum arg_type);
		if (type == AT_LAST) break;

		sv  = va_arg(vl, uint32_t);

		if (type == AT_VALUE) {
			stack32[i++] = sv;
		} else { /* i.e. its a memory arg */
			stack32[i++] = regs.esp - ss_mem + j;

			/* copy the memory */
			ptr = va_arg(vl, void *);
			memcpy(stack_mem + j, ptr, sv);
			j += sv;
		}
	} while (true);
	va_end(vl);

	ptrace_write(sp, regs.esp - ss, stack, ss);

	/*
	 * write the code and run
	 */
	regs2.eax = 102; // socketcall
	regs2.ebx = sc_code;
	regs2.ecx = regs.esp - ss;

	ptrace_write(sp, regs.eip, code, sizeof code);
	ptrace_setregs(sp, &regs2);
	ptrace_cont(sp, 0, true);

	/*
	 * read back
	 */
	ptrace_getregs(sp, &regs2);
	ptrace_read(sp, regs.esp - ss_mem, stack_mem, ss_mem);

	va_start(vl, sc_code);
	do {
		type = va_arg(vl, enum arg_type);
		if (type == AT_LAST) break;

		sv = va_arg(vl, uint32_t);
		if (type == AT_VALUE) continue;

		ptr = va_arg(vl, void *);
		if (type == AT_MEM_IN) continue;

		memcpy(ptr, stack_mem, sv);
		stack_mem += sv;
	} while (true);
	va_end(vl);

	/* restore */
	ptrace_write(sp, regs.eip, backup, sizeof backup);
	ptrace_setregs(sp, &regs);

	mmatic_free(stack);

	return regs2.eax;
}
Exemplo n.º 9
0
int32_t inject_socketcall(struct tracedump *td, struct pid *sp, uint32_t sc_code, ...)
{
	struct user_regs_struct regs, regs2;
	int ss_vals, ss_mem, ss;
	va_list vl;
	enum arg_type type;
	uint32_t sv;
	void *ptr;
	uint8_t *stack, *stack_mem;
	uint32_t *stack32;
	int i, j;

	/*
	 * get the required amount of stack space
	 */
	ss_vals = 0;  // stack space for immediate values
	ss_mem = 0;   // stack space for pointer values
	va_start(vl, sc_code);
	do {
		type = va_arg(vl, enum arg_type);
		if (type == AT_LAST) break;
		sv  = va_arg(vl, uint32_t);

		/* each socketcall argument takes 4 bytes */
		ss_vals += 4;

		/* if its memory, it takes additional sv bytes */
		if (type == AT_MEM_IN || type == AT_MEM_INOUT) {
			ss_mem += sv;
			ptr = va_arg(vl, void *);
		}
	} while (true);
	va_end(vl);
	ss = ss_vals + ss_mem;

	/*
	 * backup
	 */
	ptrace_getregs(sp, &regs);
	memcpy(&regs2, &regs, sizeof regs);

	/*
	 * write the stack
	 */
	stack = mmatic_zalloc(td->mm, ss); // stack area for immediate values
	stack32 = (uint32_t *) stack;
	stack_mem = stack + ss_vals;       // stack area for pointer values

	va_start(vl, sc_code);
	i = 0; j = 0;
	do {
		type = va_arg(vl, enum arg_type);
		if (type == AT_LAST) break;

		sv  = va_arg(vl, uint32_t);

		if (type == AT_VALUE) {
			stack32[i++] = sv;
		} else { /* i.e. its a memory arg */
			stack32[i++] = regs.esp - ss_mem + j;

			/* copy the memory */
			ptr = va_arg(vl, void *);
			memcpy(stack_mem + j, ptr, sv);
			j += sv;
		}
	} while (true);
	va_end(vl);

	ptrace_write(sp, regs.esp - ss, stack, ss);

	/*
	 * write the code and run
	 */
	_prepare(sp);

	regs2.eax = 102;            // socketcall
	regs2.ebx = sc_code;
	regs2.ecx = regs.esp - ss;
	regs2.eip = sp->vdso_addr;  // gateway to int3

	ptrace_setregs(sp, &regs2);
	ptrace_cont_syscall(sp, 0, true);   // enter...
	ptrace_cont_syscall(sp, 0, true);   // ...and exit

	/*
	 * read back
	 */
	ptrace_getregs(sp, &regs2);
	ptrace_read(sp, regs.esp - ss_mem, stack_mem, ss_mem);

	va_start(vl, sc_code);
	do {
		type = va_arg(vl, enum arg_type);
		if (type == AT_LAST) break;

		sv = va_arg(vl, uint32_t);
		if (type == AT_VALUE) continue;

		ptr = va_arg(vl, void *);
		if (type == AT_MEM_IN) continue;

		memcpy(ptr, stack_mem, sv);
		stack_mem += sv;
	} while (true);
	va_end(vl);

	/* restore */
	ptrace_setregs(sp, &regs);
	mmatic_free(stack);

	return regs2.eax;
}
Exemplo n.º 10
0
int ptrace_call(int pid, long proc, int argc, ptrace_arg *argv) {
    int i = 0;
#define ARGS_MAX 64
    regs_t regs;
    ptrace_readreg(pid, &regs);
    ptrace_dump_regs(&regs, "before ptrace_call\n");

    /*prepare stacks*/
    for (i = 0; i < argc; i++) {
        ptrace_arg *arg = &argv[i];
        if (arg->type == PAT_STR) {
            arg->_stackid = ptrace_push(pid, &regs, arg->s, strlen(arg->s) + 1);
        } else if (arg->type == PAT_MEM) {
            //LOGD("push data %p to stack[%d] :%d \n", arg->mem.addr, stackcnt, *((int*)arg->mem.addr));
            arg->_stackid = ptrace_push(pid, &regs, arg->mem.addr, arg->mem.size);
        }
    }
    for (i = 0; (i < 4) && (i < argc); i++) {
        ptrace_arg *arg = &argv[i];
        if (arg->type == PAT_INT) {
            regs.uregs[i] = arg->i;
        } else if (arg->type == PAT_STR) {
            regs.uregs[i] = arg->_stackid;
        } else if (arg->type == PAT_MEM) {
            regs.uregs[i] = arg->_stackid;
        } else {
            LOGD("unkonwn arg type\n");
        }
    }

    for (i = argc - 1; i >= 4; i--) {
        ptrace_arg *arg = &argv[i];
        if (arg->type == PAT_INT) {
            ptrace_push(pid, &regs, &arg->i, sizeof(int));
        } else if (arg->type == PAT_STR) {
            ptrace_push(pid, &regs, &arg->_stackid, sizeof(unsigned long));
        } else if (arg->type == PAT_MEM) {
            ptrace_push(pid, &regs, &arg->_stackid, sizeof(unsigned long));
        } else {
            LOGD("unkonwn arg type\n");
        }
    }
#ifdef THUMB
    regs.ARM_lr = 1;
#else
    regs.ARM_lr= 0;
#endif
    regs.ARM_pc= proc;
    ptrace_writereg(pid, &regs);
    ptrace_cont(pid);
    ptrace_wait_for_signal(pid, SIGSEGV);
    ptrace_readreg(pid, &regs);
    ptrace_dump_regs(&regs, "before return ptrace_call\n");

    //sync memory
    for (i = 0; i < argc; i++) {
        ptrace_arg *arg = &argv[i];
        if (arg->type == PAT_STR) {
        } else if (arg->type == PAT_MEM) {
            ptrace_read(pid, arg->_stackid, arg->mem.addr, arg->mem.size);
        }
    }

    return regs.ARM_r0;
}