linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* ptrace and emulated mfspr/mtspr on DSCR
@ 2012-07-06  7:30 Alexey Kardashevskiy
  2012-07-06  8:12 ` Alexey Kardashevskiy
  0 siblings, 1 reply; 2+ messages in thread
From: Alexey Kardashevskiy @ 2012-07-06  7:30 UTC (permalink / raw)
  To: Linuxppc-dev

Hi!

I am trying to change DSCR's value of a specific process with pid=XXX. For this, I attach by ptrace() to XXX, inject a piece of code which does mfspr/mtspr, "continue" XXX and see how it is changing. So far so good.

The problem is with "continue". The XXX process does not wake up until I press a key (if XXX is waiting on something like scanf() or gets()) OR it exits from sleep() if I change it to run sleep() in a loop.

Not sure if it matters but mfspr/mtspr are privileged instructions and are emulated by the kernel.

How to wake XXX up?



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

void getdata(pid_t child, long addr, void *str)
{
	unsigned long *ptr = (unsigned long *) str;
	ptr[0] = ptrace(PTRACE_PEEKDATA, child, addr, NULL);
}

void putdata(pid_t child, long addr, void *str)
{
	unsigned long *ptr = (unsigned long *) str;
	ptrace(PTRACE_POKEDATA, child, addr, ptr[0]);
}

int main(int argc, char *argv[])
{
	pid_t traced_process;
	struct pt_regs regs, backup_regs;
	unsigned long dscr = -1;
/*.set_dscr:
* 7f d1 03 a6     mtspr   17,r30
  7d 82 10 08     twge    r2,r2     <- set breakpoint */
	unsigned int insert_set[] = { 0x7fd103a6, 0x7d821008 };
/*.get_dscr:
  7f d1 02 a6     mfspr   r30,17
  7d 82 10 08     twge    r2,r2     <- set breakpoint */
	unsigned int insert_get[] = { 0x7fd102a6, 0x7d821008 };
	char backup[8];
	int len = 8;

	if((argc < 2)||(sizeof(unsigned int)!=4)) {
		printf("Usage: %s <pid to be traced> [dscr value]\n", argv[0], argv[1]);
		exit(1);
	}
	if (argc > 2) {
		dscr = atoi(argv[2]);
	}

	traced_process = atoi(argv[1]);
	ptrace(PTRACE_ATTACH, traced_process, NULL, NULL);
	wait(NULL);

	printf("Attached to pid=%u\n", traced_process);
	ptrace(PTRACE_GETREGS, traced_process, NULL, &regs);
	backup_regs = regs;
	getdata(traced_process, regs.nip, backup);

	if (dscr != -1) {
		regs.gpr[30] = dscr;
		putdata(traced_process, regs.nip, insert_set);
		ptrace(PTRACE_SETREGS, traced_process, NULL, &regs);
		printf("Setting DSCR = %x to gpr0\n", regs.gpr[30]);
	} else {
		putdata(traced_process, regs.nip, insert_get);
		printf("Reading DSCR\n");
	}

	printf("Continued pid=%u\n", traced_process);
	ptrace(PTRACE_CONT, traced_process, NULL, SIGCONT);

	printf("waiting...\n");
	wait(NULL);      // <---------------- HERE IS THE PROBLEM

	if (dscr == -1) {
		printf("DSCR has been read\n");
		ptrace(PTRACE_GETREGS, traced_process, NULL, &regs);
		printf("Reading DSCR from gpr30 = %x\n", regs.gpr[30]);
	}

	printf("The process stopped, Putting back the original instructions\n");
	putdata(traced_process, backup_regs.nip, backup);
	ptrace(PTRACE_SETREGS, traced_process, NULL, &backup_regs);
	printf("Letting it continue with original flow\n");
	ptrace(PTRACE_DETACH, traced_process, NULL, NULL);

	return 0;
}

-- 
Alexey

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: ptrace and emulated mfspr/mtspr on DSCR
  2012-07-06  7:30 ptrace and emulated mfspr/mtspr on DSCR Alexey Kardashevskiy
@ 2012-07-06  8:12 ` Alexey Kardashevskiy
  0 siblings, 0 replies; 2+ messages in thread
From: Alexey Kardashevskiy @ 2012-07-06  8:12 UTC (permalink / raw)
  To: Linuxppc-dev


ha, forget it, it is all correct actually :)


On 06/07/12 17:30, Alexey Kardashevskiy wrote:
> Hi!
> 
> I am trying to change DSCR's value of a specific process with pid=XXX. For this, I attach by ptrace() to XXX, inject a piece of code which does mfspr/mtspr, "continue" XXX and see how it is changing. So far so good.
> 
> The problem is with "continue". The XXX process does not wake up until I press a key (if XXX is waiting on something like scanf() or gets()) OR it exits from sleep() if I change it to run sleep() in a loop.
> 
> Not sure if it matters but mfspr/mtspr are privileged instructions and are emulated by the kernel.
> 
> How to wake XXX up?
> 
> 
> 
> #include <sys/ptrace.h>
> #include <sys/types.h>
> #include <sys/wait.h>
> #include <string.h>
> #include <unistd.h>
> #include <sys/user.h>
> #include <stdio.h>
> #include <stdlib.h>
> 
> void getdata(pid_t child, long addr, void *str)
> {
> 	unsigned long *ptr = (unsigned long *) str;
> 	ptr[0] = ptrace(PTRACE_PEEKDATA, child, addr, NULL);
> }
> 
> void putdata(pid_t child, long addr, void *str)
> {
> 	unsigned long *ptr = (unsigned long *) str;
> 	ptrace(PTRACE_POKEDATA, child, addr, ptr[0]);
> }
> 
> int main(int argc, char *argv[])
> {
> 	pid_t traced_process;
> 	struct pt_regs regs, backup_regs;
> 	unsigned long dscr = -1;
> /*.set_dscr:
> * 7f d1 03 a6     mtspr   17,r30
>   7d 82 10 08     twge    r2,r2     <- set breakpoint */
> 	unsigned int insert_set[] = { 0x7fd103a6, 0x7d821008 };
> /*.get_dscr:
>   7f d1 02 a6     mfspr   r30,17
>   7d 82 10 08     twge    r2,r2     <- set breakpoint */
> 	unsigned int insert_get[] = { 0x7fd102a6, 0x7d821008 };
> 	char backup[8];
> 	int len = 8;
> 
> 	if((argc < 2)||(sizeof(unsigned int)!=4)) {
> 		printf("Usage: %s <pid to be traced> [dscr value]\n", argv[0], argv[1]);
> 		exit(1);
> 	}
> 	if (argc > 2) {
> 		dscr = atoi(argv[2]);
> 	}
> 
> 	traced_process = atoi(argv[1]);
> 	ptrace(PTRACE_ATTACH, traced_process, NULL, NULL);
> 	wait(NULL);
> 
> 	printf("Attached to pid=%u\n", traced_process);
> 	ptrace(PTRACE_GETREGS, traced_process, NULL, &regs);
> 	backup_regs = regs;
> 	getdata(traced_process, regs.nip, backup);
> 
> 	if (dscr != -1) {
> 		regs.gpr[30] = dscr;
> 		putdata(traced_process, regs.nip, insert_set);
> 		ptrace(PTRACE_SETREGS, traced_process, NULL, &regs);
> 		printf("Setting DSCR = %x to gpr0\n", regs.gpr[30]);
> 	} else {
> 		putdata(traced_process, regs.nip, insert_get);
> 		printf("Reading DSCR\n");
> 	}
> 
> 	printf("Continued pid=%u\n", traced_process);
> 	ptrace(PTRACE_CONT, traced_process, NULL, SIGCONT);
> 
> 	printf("waiting...\n");
> 	wait(NULL);      // <---------------- HERE IS THE PROBLEM
> 
> 	if (dscr == -1) {
> 		printf("DSCR has been read\n");
> 		ptrace(PTRACE_GETREGS, traced_process, NULL, &regs);
> 		printf("Reading DSCR from gpr30 = %x\n", regs.gpr[30]);
> 	}
> 
> 	printf("The process stopped, Putting back the original instructions\n");
> 	putdata(traced_process, backup_regs.nip, backup);
> 	ptrace(PTRACE_SETREGS, traced_process, NULL, &backup_regs);
> 	printf("Letting it continue with original flow\n");
> 	ptrace(PTRACE_DETACH, traced_process, NULL, NULL);
> 
> 	return 0;
> }
> 


-- 
Alexey

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2012-07-06  8:12 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-07-06  7:30 ptrace and emulated mfspr/mtspr on DSCR Alexey Kardashevskiy
2012-07-06  8:12 ` Alexey Kardashevskiy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).