Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 29 Mar 2012 09:44:11 -0400
From:      John Baldwin <jhb@freebsd.org>
To:        Maninya M <maninya@gmail.com>
Cc:        freebsd-hackers@freebsd.org
Subject:   Re: __NR_mmap2 in FreeBSD
Message-ID:  <201203290944.11446.jhb@freebsd.org>
In-Reply-To: <CAC46K3kvymco4bDu0RJND64ejpWyPth8qFCOEx=gY9BbPGYSLg@mail.gmail.com>
References:  <CAC46K3kjQyqQ0VvjP%2BUwQkSooqbT1HR=SVYUpz8KQ1CcYovaEA@mail.gmail.com> <201203270753.21534.jhb@freebsd.org> <CAC46K3kvymco4bDu0RJND64ejpWyPth8qFCOEx=gY9BbPGYSLg@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
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@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@freebsd.org mailing list
> > > http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
> > > To unsubscribe, send any mail to "
> > freebsd-hackers-unsubscribe@freebsd.org"
> > >
> >
> > --
> > John Baldwin
> >
> 
> 
> 
> -- 
> Maninya
> 

-- 
John Baldwin



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201203290944.11446.jhb>