__NR_mmap2 in FreeBSD

Maninya M maninya at gmail.com
Thu Apr 19 14:59:39 UTC 2012


Hello :)

After a long time trying different combinations of setting register values,
I was finally able to allocate memory to the process.
It doesn't seem to work for processes that use malloc(), so that's why I
was getting a problem.
Thank you very much John Baldwin and Julian Elischer, and to all the other
FreeBSD hackers on this amazing forum. Your patient replies to all my
questions helped a lot! :)




On 3 April 2012 02:12, John Baldwin <jhb at freebsd.org> wrote:

> On Saturday, March 31, 2012 5:40:50 pm Maninya M wrote:
> > Thanks.
> >
> > I've tried this. Still getting some allocation problems.
> >
> > if (temp_regs.r_eax != addr)
> >     warn("Wanted space at address 0x%.8x, mmap2 system call returned
> > 0x%.8x. This could be a problem.",addr,temp_regs.r_eax);
> >
> > What can I do? Please help.
>
> Hmm, can you capture a ktrace of the target process during this so you can
> see
> if the kernel sees the mmap request properly?
>
> >
> > void map_memory(unsigned long addr, unsigned long size, int flags)
> > {
> >   int status;
> >   struct reg regs,temp_regs;
> >   unsigned long int_instr = 0x000080cd; /* INT 0x80 */
> >   printf("%x\n",addr);
> >   //addr=addr&0xffff0000;
> >   if (ptrace(PT_GETREGS,exec_pid,(caddr_t)&regs,0) < 0)
> >     die_perror("ptrace(PTRACE_GETREGS,%d,(caddr_t)&regs,0)",exec_pid);
> >
> >   /* mmap2 system call seems to take arguments as follows:
> >    * eax = __NR_mmap2
> >    * ebx = (unsigned long) page aligned address
> >    * ecx = (unsigned long) page aligned file size
> >    * edx = protection
> >    * esi = flags
> >    * Other arguments (fd and pgoff) are not required for anonymous
> mapping
> >    */
> >   temp_regs = regs;
> >
> > //printf("temp=%u,
> \teip=%u\tregs=%u\teip=%u\n",&temp_regs,temp_regs.r_eip,&regs,regs.r_eip);
> >  // temp_regs.r_eax = __NR_mmap2;
> >  temp_regs.r_eax=71;
> >   /*temp_regs.r_ebx = addr;
> >   temp_regs.r_ecx = size;
> >   temp_regs.r_edx = flags;
> >   temp_regs.r_esi = MAP_PRIVATE | MAP_ANONYMOUS;*/
> >   //push size
> >
> >  //temp_regs.r_eip = temp_regs.r_esp - 4;
> >
> > //printf("temp=%u,
> \teip=%u\tregs=%u\teip=%u\n",&temp_regs,temp_regs.r_eip,&regs,regs.r_eip);
> >
> > if (ptrace(PT_WRITE_D,exec_pid,(void *)(temp_regs.r_esp-4),addr) < 0)
> >     die_perror("ptrace(PT_WRITE,%d,0x%.8x,0x%.8x) failed
> > ADDER",exec_pid,temp_regs.r_esp,addr);
> >
> > if (ptrace(PT_WRITE_D,exec_pid,(void *)(temp_regs.r_esp-8),size) < 0)
> >     die_perror("ptrace(PT_WRITE,%d,0x%.8x,INT 0x80) failed
> > size",exec_pid,temp_regs.r_esp);
> >
> > if (ptrace(PT_WRITE_D,exec_pid,(void *)(temp_regs.r_esp-12),flags) < 0)
> >     die_perror("ptrace(PT_WRITE,%d,0x%.8x,INT 0x80) failed
> > protections",exec_pid,temp_regs.r_esp);
> >
> > if (ptrace(PT_WRITE_D,exec_pid,(void
> > *)(temp_regs.r_esp-16),MAP_PRIVATE|MAP_ANON|MAP_FIXED) < 0)
> >     die_perror("ptrace(PT_WRITE,%d,0x%.8x,INT 0x80) failed
> > flags",exec_pid,temp_regs.r_esp);
> >
> > if (ptrace(PT_WRITE_D,exec_pid,(void *)(temp_regs.r_esp-20),-1) < 0)
> >     die_perror("ptrace(PT_WRITE,%d,0x%.8x,0x%.8x) failed
> > ADDER",exec_pid,temp_regs.r_esp,addr);
> >
> > if (ptrace(PT_WRITE_D,exec_pid,(void *)(temp_regs.r_esp-24),0) < 0)
> >     die_perror("ptrace(PT_WRITE,%d,0x%.8x,0x%.8x) failed
> > offset1",exec_pid,temp_regs.r_esp,addr);
> > if (ptrace(PT_WRITE_D,exec_pid,(void *)(temp_regs.r_esp-28),0) < 0)
> >     die_perror("ptrace(PT_WRITE,%d,0x%.8x,0x%.8x) failed
> > offset1",exec_pid,temp_regs.r_esp,addr);
> >
> >
> > /*
> > if (ptrace(PT_WRITE_I,exec_pid,(void *)(temp_regs.r_eip),0x000080cd) < 0)
> >     die_perror("ptrace(PT_WRITE,%d,0x%.8x,INT 0x80) failed while
> allocating
> > memory",exec_pid,temp_regs.r_eip);
> > */
> >   if (ptrace(PT_WRITE_I,exec_pid,(void *)(temp_regs.r_eip),0x000080cd) <
> 0)
> >     die_perror("ptrace(PT_WRITE,%d,0x%.8x,INT 0x80) failed while
> allocating
> > memory",exec_pid,temp_regs.r_eip);
> >
> > //temp_regs.r_eip = temp_regs.r_esp - 32;
> > temp_regs.r_esp = temp_regs.r_esp - 28;
> >
> >   if (ptrace(PT_SETREGS,exec_pid,(caddr_t)&temp_regs,0) < 0) {
> >     die_perror("ptrace(PT_SETREGS,%d,...) failed while allocating
> > memory",exec_pid);
> >   }
> >   if (ptrace(PT_STEP,exec_pid,NULL,0) < 0)
> >     die_perror("ptrace(PT_STEP,...) failed while executing mmap2");
> >
> >   wait(&status);
> >   if (WIFEXITED(status))
> >     die("Restarted process abrubtly (exited with value %d). Aborting
> > Restart.",WEXITSTATUS(status));
> >   else if (WIFSIGNALED(status))
> >     die("Restarted process abrubtly exited because of uncaught signal
> (%d).
> > Aborting Restart.",WTERMSIG(status));
> >
> >   if (ptrace(PT_GETREGS,exec_pid,(caddr_t)&temp_regs,0) < 0) {
> >     die_perror("ptrace(PT_GETREGS,...) failed after executing mmap2
> system
> > call");
> >   }
> > //fprintf(stdout,"hello iam here \n");
> >   if (temp_regs.r_eax != addr)
> >     warn("Wanted space at address 0x%.8x, mmap2 system call returned
> > 0x%.8x. This could be a problem.",addr,temp_regs.r_eax);
> >   else if (cr_options.verbose)
> >
> >     fprintf(stdout,"Successfully allocated [0x%.8lx -
> > 0x%.8lx]\n",addr,addr+size);
> >
> >   /* Restore original registers */
> >   if (ptrace(PT_SETREGS,exec_pid,(caddr_t)&temp_regs,0) < 0) {
> >     die_perror("ptrace(PT_SETREGS,...) when restoring registering after
> > allocating memory (mmap2)");
> >
> >   }
> > }
> >
> >
> >
> >
> > On 29 March 2012 19:14, John Baldwin <jhb at freebsd.org> wrote:
> >
> > > On Thursday, March 29, 2012 9:15:43 am Maninya M wrote:
> > > > Thanks a lot for replying!
> > > > Ok I've tried this to push arguments onto stack.
> > > > Is it right?
> > > > I get an error at this line:
> > > >
> > > >    die_perror("ptrace(PT_WRITE,%d,0x%.8x,INT 0x80) failed while
> > > > dasfallocating memory",exec_pid,temp_regs.r_eip);
> > > >
> > > >
> > > > Please tell me what to do.
> > > >
> > > >
> > > >
> > > >
> > > >
> > > > void map_memory(unsigned long addr, unsigned long size, int flags)
> > > > {
> > > >   int status;
> > > >   struct reg regs,temp_regs;
> > > >   unsigned long int_instr = 0x000080cd; /* INT 0x80 */
> > > >
> > > >   if (ptrace(PT_GETREGS,exec_pid,(caddr_t)&regs,0) < 0)
> > > >
> die_perror("ptrace(PTRACE_GETREGS,%d,(caddr_t)&regs,0)",exec_pid);
> > > >
> > > >   /* mmap2 system call seems to take arguments as follows:
> > > >    * eax = __NR_mmap2
> > > >    * ebx = (unsigned long) page aligned address
> > > >    * ecx = (unsigned long) page aligned file size
> > > >    * edx = protection
> > > >    * esi = flags
> > > >    * Other arguments (fd and pgoff) are not required for anonymous
> > > mapping
> > > >    */
> > > >   temp_regs = regs;
> > > >
> > > > //printf("temp=%u,
> > >
> \teip=%u\tregs=%u\teip=%u\n",&temp_regs,temp_regs.r_eip,&regs,regs.r_eip);
> > > >  // temp_regs.r_eax = __NR_mmap2;
> > > >  temp_regs.r_eax=71;
> > > >   /*temp_regs.r_ebx = addr;
> > > >   temp_regs.r_ecx = size;
> > > >   temp_regs.r_edx = flags;
> > > >   temp_regs.r_esi = MAP_PRIVATE | MAP_ANONYMOUS;*/
> > > >   //push size
> > > >
> > > >  //temp_regs.r_eip = temp_regs.r_esp - 4;
> > >
> > > You still want this, it is putting the instruction on the stack.
>  However,
> > > your stack layout is wrong I think.  You actually want it to be
> something
> > > like
> > > this:
> > >
> > > r_esp - 4:       <addr>
> > > r_esp - 8:       <len (in bytes)>
> > > r_esp - 12:      <flags (protection)>
> > > r_esp - 16:      <MAP_PRIVATE | MAP_ANON>  (MAP_FIXED?)
> > > r_esp - 20:      <fd>
> > > r_esp - 24:      <offset (64 bit!)>
> > > r_esp - 28:      <upper 32 bits of offset>
> > > r_esp - 32:      <int 0x80 instruction>
> > >
> > > Then you want to set:
> > >
> > > r_eip = r_esp - 32;
> > > r_esp -= 28;
> > >
> > > I think you want MAP_FIXED since it complains if the returned address
> > > doesn't
> > > match 'addr' at the end of your routine.  However, it might be best if
> you
> > > just compiled a program that called mmap() and then looked at the
> > > disassembly
> > > and to make sure the stack layout is correct.
> > >
> > > > //printf("temp=%u,
> > >
> \teip=%u\tregs=%u\teip=%u\n",&temp_regs,temp_regs.r_eip,&regs,regs.r_eip);
> > > > if (ptrace(PT_WRITE_D,exec_pid,(void
> *)(temp_regs.r_esp-4),MAP_PRIVATE |
> > > > MAP_ANONYMOUS) < 0)
> > > >     die_perror("ptrace(PT_WRITE,%d,0x%.8x,INT 0x80) failed while
> > > allocating
> > > > memory",exec_pid,temp_regs.r_eip);
> > > >
> > > > if (ptrace(PT_WRITE_D,exec_pid,(void *)(temp_regs.r_esp-8),flags) <
> 0)
> > > >     die_perror("ptrace(PT_WRITE,%d,0x%.8x,INT 0x80) failed while
> > > allocating
> > > > memory",exec_pid,temp_regs.r_eip);
> > > >
> > > > if (ptrace(PT_WRITE_D,exec_pid,(void *)(temp_regs.r_esp-12),size) <
> 0)
> > > >     die_perror("ptrace(PT_WRITE,%d,0x%.8x,INT 0x80) failed while
> > > allocating
> > > > memory",exec_pid,temp_regs.r_eip);
> > > >
> > > > if (ptrace(PT_WRITE_D,exec_pid,(void *)(temp_regs.r_esp-16), addr) <
> 0);
> > > >     die_perror("ptrace(PT_WRITE,%d,0x%.8x,INT 0x80) failed while
> > > > dasfallocating memory",exec_pid,temp_regs.r_eip);
> > > > /*
> > > > if (ptrace(PT_WRITE_I,exec_pid,(void *)(temp_regs.r_eip),0x000080cd)
> <
> 0)
> > > >     die_perror("ptrace(PT_WRITE,%d,0x%.8x,INT 0x80) failed while
> > > allocating
> > > > memory",exec_pid,temp_regs.r_eip);
> > > > */
> > > >   if (ptrace(PT_WRITE_I,exec_pid,(void
> *)(temp_regs.r_eip),0x000080cd) <
> > > 0)
> > > >     die_perror("ptrace(PT_WRITE,%d,0x%.8x,INT 0x80) failed while
> > > allocating
> > > > memory",exec_pid,temp_regs.r_eip);
> > > >   if (ptrace(PT_SETREGS,exec_pid,(caddr_t)&temp_regs,0) < 0) {
> > > >     die_perror("ptrace(PT_SETREGS,%d,...) failed while allocating
> > > > memory",exec_pid);
> > > >   }
> > > >   if (ptrace(PT_STEP,exec_pid,NULL,0) < 0)
> > > >     die_perror("ptrace(PT_STEP,...) failed while executing mmap2");
> > > >
> > > >   wait(&status);
> > > >   if (WIFEXITED(status))
> > > >     die("Restarted process abrubtly (exited with value %d). Aborting
> > > > Restart.",WEXITSTATUS(status));
> > > >   else if (WIFSIGNALED(status))
> > > >     die("Restarted process abrubtly exited because of uncaught signal
> > > (%d).
> > > > Aborting Restart.",WTERMSIG(status));
> > > >
> > > >   if (ptrace(PT_GETREGS,exec_pid,(caddr_t)&temp_regs,0) < 0) {
> > > >     die_perror("ptrace(PT_GETREGS,...) failed after executing mmap2
> > > system
> > > > call");
> > > >   }
> > > > //fprintf(stdout,"hello iam here \n");
> > > >   if (temp_regs.r_eax != addr)
> > > >     warn("Wanted space at address 0x%.8x, mmap2 system call returned
> > > > 0x%.8x. This could be a problem.",addr,temp_regs.r_eax);
> > > >   else if (cr_options.verbose)
> > > >
> > > >     fprintf(stdout,"Successfully allocated [0x%.8lx -
> > > > 0x%.8lx]\n",addr,addr+size);
> > > >
> > > >   /* Restore original registers */
> > > >   if (ptrace(PT_SETREGS,exec_pid,(caddr_t)&temp_regs,0) < 0) {
> > > >     die_perror("ptrace(PT_SETREGS,...) when restoring registering
> after
> > > > allocating memory (mmap2)");
> > > >
> > > >   }
> > > > }
> > > >
> > > >
> > > >
> > > >
> > > >
> > > >
> > > > On 27 March 2012 17:23, John Baldwin <jhb at freebsd.org> wrote:
> > > >
> > > > > On Monday, March 26, 2012 1:56:08 pm Maninya M wrote:
> > > > > > I am trying to convert a function written for Linux to FreeBSD.
> > > > > > What is the equivalent of the __NR_mmap2 system call in FreeBSD?
> > > > > >
> > > > > > I keep getting the error because of this exception:
> > > > > > warn("Wanted space at address 0x%.8x, mmap2 system call returned
> > > 0x%.8x.
> > > > > > This could be a problem.",addr,temp_regs.eax);
> > > > >
> > > > > I think you could just use plain mmap() for this?
> > > > >
> > > > > However, it seems that this is injecting a call into an existing
> > > binary,
> > > > > not calling mmap() directly.  A few things will need to change.
> First,
> > > > > FreeBSD system calls on i386 put their arguments on the stack, not
> in
> > > > > registers, so you will need to do a bit more work to push the
> arguments
> > > > > onto
> > > > > the stack rather than just setting registers.
> > > > >
> > > > > > I changed
> > > > > > temp_regs.eax = __NR_mmap2;
> > > > > > to
> > > > > > temp_regs.eax = 192;
> > > > > >
> > > > > > but it didn't work. I suppose I couldn't understand this
> function.
> > > Please
> > > > > > help.
> > > > > >
> > > > > > This is the function:
> > > > > >
> > > > > > void map_memory(unsigned long addr, unsigned long size, int
> flags)
> > > > > > {
> > > > > >   int status;
> > > > > >   struct user_regs_struct regs,temp_regs;
> > > > > >   unsigned long int_instr = 0x000080cd; /* INT 0x80 */
> > > > > >
> > > > > >   if (ptrace(PTRACE_GETREGS,exec_pid,NULL,&regs) < 0)
> > > > > >     die_perror("ptrace(PTRACE_GETREGS,%d,NULL,&regs)",exec_pid);
> > > > > >
> > > > > >   /* mmap2 system call seems to take arguments as follows:
> > > > > >    * eax = __NR_mmap2
> > > > > >    * ebx = (unsigned long) page aligned address
> > > > > >    * ecx = (unsigned long) page aligned file size
> > > > > >    * edx = protection
> > > > > >    * esi = flags
> > > > > >    * Other arguments (fd and pgoff) are not required for
> anonymous
> > > > > mapping
> > > > > >    */
> > > > > >   temp_regs = regs;
> > > > > >   temp_regs.eax = __NR_mmap2;
> > > > > >   temp_regs.ebx = addr;
> > > > > >   temp_regs.ecx = size;
> > > > > >   temp_regs.edx = flags;
> > > > > >   temp_regs.esi = MAP_PRIVATE | MAP_ANONYMOUS;
> > > > > >   temp_regs.eip = temp_regs.esp - 4;
> > > > > >
> > > > > >   if (ptrace(PTRACE_POKETEXT,exec_pid,(void
> > > > > > *)(temp_regs.eip),(void*)int_instr) < 0)
> > > > > >     die_perror("ptrace(PTRACE_POKETEXT,%d,0x%.8x,INT 0x80) failed
> > > while
> > > > > > allocating memory",exec_pid,temp_regs.eip);
> > > > > >   if (ptrace(PTRACE_SETREGS,exec_pid,NULL,&temp_regs) < 0) {
> > > > > >     die_perror("ptrace(PTRACE_SETREGS,%d,...) failed while
> allocating
> > > > > > memory",exec_pid);
> > > > > >   }
> > > > > >   if (ptrace(PTRACE_SINGLESTEP,exec_pid,NULL,NULL) < 0)
> > > > > >     die_perror("ptrace(PTRACE_SINGLESTEP,...) failed while
> executing
> > > > > > mmap2");
> > > > > >
> > > > > >   wait(&status);
> > > > > >   if (WIFEXITED(status))
> > > > > >     die("Restarted process abrubtly (exited with value %d).
> Aborting
> > > > > > Restart.",WEXITSTATUS(status));
> > > > > >   else if (WIFSIGNALED(status))
> > > > > >     die("Restarted process abrubtly exited because of uncaught
> signal
> > > > > (%d).
> > > > > > Aborting Restart.",WTERMSIG(status));
> > > > > >
> > > > > >   if (ptrace(PTRACE_GETREGS,exec_pid,NULL,&temp_regs) < 0) {
> > > > > >     die_perror("ptrace(PTRACE_GETREGS,...) failed after executing
> > > mmap2
> > > > > > system call");
> > > > > >   }
> > > > > >
> > > > > >   if (temp_regs.eax != addr)
> > > > > >     warn("Wanted space at address 0x%.8x, mmap2 system call
> returned
> > > > > > 0x%.8x. This could be a problem.",addr,temp_regs.eax);
> > > > > >   else if (cr_options.verbose)
> > > > > >     fprintf(stdout,"Successfully allocated [0x%.8lx -
> > > > > > 0x%.8lx]\n",addr,addr+size);
> > > > > >
> > > > > >   /* Restore original registers */
> > > > > >   if (ptrace(PTRACE_SETREGS,exec_pid,NULL,&regs) < 0) {
> > > > > >     die_perror("ptrace(PTRACE_SETREGS,...) when restoring
> registering
> > > > > after
> > > > > > allocating memory (mmap2)");
> > > > > >   }
> > > > > > }
> > > > > >
> > > > > > --
> > > > > > Maninya
> > > > > > _______________________________________________
> > > > > > freebsd-hackers at freebsd.org mailing list
> > > > > > http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
> > > > > > To unsubscribe, send any mail to "
> > > > > freebsd-hackers-unsubscribe at freebsd.org"
> > > > > >
> > > > >
> > > > > --
> > > > > John Baldwin
> > > > >
> > > >
> > > >
> > > >
> > > > --
> > > > Maninya
> > > >
> > >
> > > --
> > > John Baldwin
> > >
> >
> >
> >
> > --
> > Maninya
> >
>
> --
> John Baldwin
>



-- 
Maninya


More information about the freebsd-hackers mailing list