All of lore.kernel.org
 help / color / mirror / Atom feed
From: Daniel Souza <thehazard@gmail.com>
To: linux-c-programming@vger.kernel.org
Subject: Re: monitoring code while executing.
Date: Mon, 22 Nov 2004 19:17:56 -0200	[thread overview]
Message-ID: <e1e1d5f4041122131733b07e62@mail.gmail.com> (raw)
In-Reply-To: <20041122193533.GP26791@lug-owl.de>

you can either use ptrace to attach to the process pid and use
PTRACE_SINGLESTEP to "walk" through instructions. After every
PTRACE_SINGLESTEP, the process get stopped by a signal and waits for
the next PTRACE_SINGLESTEP 'delivered' by your monitoring application
.  Before you call PTRACE_SINGLESTEP again, you can do things with the
attached process like read words or write to its memory, view CPU
registers, etc. I wrote a little code (i dont remember if its the last
version, anyways, you can got the "ideia"), with some adaptations to
fit your needs. (it uses 2 ways to read the registers values, one is
fetching the word at the exact offset, other is filling up a "struct
user" that holds the values.

/*
 * procinfo.c
 * 2004 daniel souza <thehazard@gmail.com>
 *
 * small utility to dump registers from a running process
 *
 */
  
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/user.h>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <linux/ptrace.h>

#define WORD_LEN sizeof(long)
#define S_USER_LEN sizeof(struct user)
	
extern int errno;

void fatalmsg(char *caller)
{
	fprintf(stderr, "[-] %s: %s\n", caller, strerror(errno));
	exit(-1);
}

void usage(char *progname)
{	
	fprintf(stderr, "procinfo.c - shows information about a running process\n");
	fprintf(stderr, "USAGE: %s <pid>\n", progname);
	exit(-1);
}

int show_task_info(pid_t process_pid)
{
	u_long ptracex = 0;
	u_long user_offset = 0;
	u_long got_user_data;
	u_int process_user_len;
	int child_status, user_idx, i;
	struct user process_user_data;
	struct user *buff;

	fprintf(stdout, "[+] dumping data from pid: %d\n", process_pid);
	fprintf(stdout, "[+] attaching to process...\n");
	if ((ptracex = ptrace( PTRACE_ATTACH, process_pid, NULL, NULL)) != 0)
		fatalmsg("ptrace");
	fprintf(stdout, "[+] atacched.\n");
	fprintf(stdout, "[+] S_USER_LEN = %d\n", S_USER_LEN);
	fprintf(stdout, "[+] WORD_LEN = %d\n", WORD_LEN);	
	fprintf(stdout, "[!] waiting for child...\n");

	waitpid( process_pid, &child_status, 0 );
	if (WIFSTOPPED(child_status))
	{
		fprintf(stdout, "[!] process got signal %d\n", WSTOPSIG(child_status));
		/* fetch the user structure */
		fprintf(stdout, "[+] fetching user structure. errno=%d\n", errno);			
		printf( "[+] [EAX=%d] regs.eax = [0x%08x]\n", EAX, ptrace(
PTRACE_PEEKUSR, process_pid, 4*EAX, NULL ) );
		printf( "[+] [EBX=%d] regs.ebx = [0x%08x]\n", EBX, ptrace(
PTRACE_PEEKUSR, process_pid, 4*EBX, NULL ) );
		printf( "[+] [ECX=%d] regs.ecx = [0x%08x]\n", ECX, ptrace(
PTRACE_PEEKUSR, process_pid, 4*ECX, NULL ) );
		printf( "[+] [EDX=%d] regs.edx = [0x%08x]\n", EDX, ptrace(
PTRACE_PEEKUSR, process_pid, 4*EDX, NULL ) );
		
		buff = &process_user_data;
		memset(buff, 0x41, sizeof(process_user_data));		
		//for (user_offset = 0; user_offset <= S_USER_LEN-WORD_LEN;
user_offset += WORD_LEN)
		for (user_idx = 0; user_idx <= (S_USER_LEN/WORD_LEN)-1; user_idx++)
		{
			printf("[!] process_user_data=[%08x], buff=[%08x]\n",
&process_user_data, &process_user_data+(user_idx*WORD_LEN));
			buff = &process_user_data+(user_idx*WORD_LEN);
			got_user_data = ptrace( PTRACE_PEEKUSR, process_pid,
user_idx*WORD_LEN, NULL );
			memcpy(&buff, &got_user_data, 4);
			printf("[!] IDX: %d = [0x%08x], at %p, errno=[%s]\n", user_idx,
got_user_data, &buff, strerror(errno));
		
			//*(u_long *)(((buff)+(user_idx*WORD_LEN))) = got_user_data;
			//*((u_long *) buff+(user_idx*WORD_LEN)) = got_user_data;			
			
		}
		//memcpy( &process_user_data, buff, S_USER_LEN );
		//free(buff);

		printf("[!] process_user_data at %p\n", &process_user_data);
		sleep(10);

		printf( "[+] regs.eax = [0x%08x]\n", process_user_data.regs.eax );
		printf( "[+] regs.ebx = [0x%08x]\n", process_user_data.regs.ebx );
		printf( "[+] regs.ecx = [0x%08x]\n", process_user_data.regs.ecx );
		printf( "[+] regs.edx = [0x%08x]\n", process_user_data.regs.edx );
		printf( "[+] magic=[0x%08x] u_comm=[%s]\n", process_user_data.magic,
process_user_data.u_comm );
		
		

	}



	/* unstop process */
	ptrace( PTRACE_CONT, process_pid, NULL, NULL );	
	
	/* detaches from process */
	ptrace( PTRACE_DETACH, process_pid, NULL, NULL );
	fprintf(stdout, "[+] detached.\n");
}

int main(int argc, char **argv)
{
	pid_t process_pid = 0;	
	
	if ((argc < 2) || !(process_pid = atol(argv[1])))
		usage(argv[0]);		
	
	show_task_info(process_pid);
}

  reply	other threads:[~2004-11-22 21:17 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-11-22 18:24 monitoring code while executing A M
2004-11-22 19:35 ` Jan-Benedict Glaw
2004-11-22 21:17   ` Daniel Souza [this message]
  -- strict thread matches above, loose matches on Subject: below --
2004-11-22 21:15 A M
2004-11-23  5:50 ` Jan-Benedict Glaw

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=e1e1d5f4041122131733b07e62@mail.gmail.com \
    --to=thehazard@gmail.com \
    --cc=linux-c-programming@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.