Attaching to a process and calling a kernel function

jjore on 2010-01-09T01:30:33

I figured out last night that I could use allocate memory within another process for the purposes of using more complicated APIs. In the below example, I attached to one of my shells and queried the groups out of it.

In this snippet, the target shell tells me its process id is 40728.

Last login: Fri Jan  8 16:51:00 on ttys000
w3m211a:~ jjore$ echo $$
40728


I'm calling the (int)getgroups( int, int* ) kernel function. I start by getting the size of an integer because I'm going to allocate some multiple of this.

w3m211a:~ jjore$ gdb -p 40728

(gdb) print sizeof(int) $1 = 4


Call (int)getgroups(int,int*) once to get the number of groups I'm a member of.

(gdb) print (int)getgroups(0,0)
$2 = 16


Allocate 64 bytes of memory to hold my groups[16] array.

(gdb) print (void*)malloc(64)
$3 = (void *) 0x10010fca0


Call (int)getgroups(int,int*) again but this time the kernel will write to my memory with the group ids.

(gdb) print (int)getgroups($2,$3)
$4 = 16


Print the 16 decimal numbers out of memory

(gdb) x/16d $3
0x10010fca0:	2042662593	401	1612991420	1178352327
0x10010fcb0:	102	800006232	204	100
0x10010fcc0:	98	81	80	79
0x10010fcd0:	62	12	155049148	2133303823


Clean up

(gdb) print (void)free($3)
$5 = void


fun!

awwaiid on 2010-01-11T17:19:24

My favorite sort of fun! Crazyness :)

Re:fun!

jjore on 2010-01-11T18:15:10

I made it into a shell script so I'd have a working groups program since Mac OS X 10.6.2 has a "wrong" version. The shell script is dumb and just assumes it's ok to read 32 ints.

#!/bin/bash
 
cat >/tmp/groups.gdb <<EOF
  print \$ngroups = (int)getgroups(0,0)
  set \$groups = (int*)malloc(4092)
  set \$ngroups = (int)getgroups(\$ngroups,\$groups)
  x/32d \$groups
  call (void)free(\$groups)
  detach
  quit
EOF
 
gdb -x /tmp/groups.gdb -p $1