#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/reg.h> //#include <linux/user.h>
#include <sys/syscall.h>
const int long_size = sizeof(long);
void reverse(char *str)
{
int i, j;
char temp;
for(i = 0, j = strlen(str) - 2;
i <= j; ++i, --j) {
temp = str[i];
str[i] = str[j];
str[j] = temp;
}
}
void getdata(pid_t child, long addr,
char *str, int len)
{
char *laddr;
int i, j;
union u {
long val;
char chars[long_size];
}data;
i = 0;
j = len / long_size;
laddr = str;
while(i < j) {
data.val = ptrace(PTRACE_PEEKDATA,
child, addr + i * 8, //i * 4
NULL);
memcpy(laddr, data.chars, long_size);
++i;
laddr += long_size;
}
j = len % long_size;
if(j != 0) {
data.val = ptrace(PTRACE_PEEKDATA,
child, addr + i * 8, //i * 4
NULL);
memcpy(laddr, data.chars, j);
}
str[len] = '\0';
}
void putdata(pid_t child, long addr,
char *str, int len)
{
char *laddr;
int i, j;
union u {
long val;
char chars[long_size];
}data;
i = 0;
j = len / long_size;
laddr = str;
while(i < j) {
memcpy(data.chars, laddr, long_size);
ptrace(PTRACE_POKEDATA, child,
addr + i * 8, data.val); //i * 4
++i;
laddr += long_size;
}
j = len % long_size;
if(j != 0) {
memcpy(data.chars, laddr, j);
ptrace(PTRACE_POKEDATA, child,
addr + i * 8, data.val); //i * 4
}
}
int main()
{
pid_t child;
child = fork();
if(child == 0) {
ptrace(PTRACE_TRACEME, 0, NULL, NULL);
execl("/bin/ls", "ls", NULL);
}
else {
long orig_eax;
long params[3];
int status;
char *str, *laddr;
int toggle = 0;
while(1) {
wait(&status);
if(WIFEXITED(status))
break;
orig_eax = ptrace(PTRACE_PEEKUSER,
child, 8 * ORIG_RAX, //4 * ORIG_EAX
NULL);
if(orig_eax == SYS_write) {
if(toggle == 0) {
toggle = 1;
params[0] = ptrace(PTRACE_PEEKUSER,
child, 8 * RDI, //4 * EBX
NULL);
params[1] = ptrace(PTRACE_PEEKUSER,
child, 8 * RSI, //4 * ECX
NULL);
params[2] = ptrace(PTRACE_PEEKUSER,
child, 8 * RDX, //4 * EDX
NULL);
str = (char *)calloc((params[2]+1) //
, sizeof(char));
getdata(child, params[1], str,
params[2]);
reverse(str);
putdata(child, params[1], str,
params[2]);
}
else {
toggle = 0;
}
}
ptrace(PTRACE_SYSCALL, child, NULL, NULL);
}
}
return 0;
}
注释部分是对原代码的修改,测试环境ubuntu 14。
代码2:
/*****************************
*ptrace testing by lasvegas
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/ptrace.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/user.h>
#include <string.h>
void getdata(pid_t child, char* const addr, unsigned long getlen, char* const rbuf);
void setdata(pid_t child, void* const addr, unsigned long setlen, char* const sbuf);
int main(int argc, char** argv)
{
unsigned long lrmt =0x31;
char rmt[] ="\xEB\x1D\x5B\x48\xC7\xC0\x01\x00\x00\x00\x48\xC7\xC7\x01\x00\x00\x00\x48\x89\xDE\x48\xC7\xC2\x0D\x00\x00\x00\x0F\x05\xEB\x13\xE8\xDE\xFF\xFF\xFF\x48\x65\x6C\x6C\x6F\x20\x57\x6F\x72\x6C\x64\x21\x0A";
char back[lrmt];
pid_t child =0;
struct user_regs_struct reg;
if(argc !=2)
{
printf("Usage: %s <target executable file>\n", argv[0]);
exit(1);
}
child =fork();
if(child ==0)
{
ptrace(PTRACE_TRACEME, 0, NULL, 0);
if(execlp(argv[1], argv[1], NULL) <0)
{
printf("Damn for executable execlp(%s,...)\n", argv[1]);
exit(2);
}
}
else
{
printf("Trace on %d...\n", child);
int status;
ptrace(PTRACE_ATTACH, child, NULL, NULL);
wait(&status);
if(WIFEXITED(status))
{
exit(0);
}
ptrace(PTRACE_GETREGS, child, NULL, ®);
getdata(child, (void*)reg.rip, lrmt, back);
setdata(child, (void*)reg.rip, lrmt, rmt);
ptrace(PTRACE_SETREGS, child, NULL, ®);
ptrace(PTRACE_CONT, child, NULL, NULL);
wait(NULL);
//restore
setdata(child, (void*)reg.rip, lrmt, back);
ptrace(PTRACE_SETREGS, child, NULL, ®);
//
ptrace(PTRACE_DETACH, child, NULL, NULL);
}
return 0;
}
/*
typedef union _mem_byte
{
long inst;
char insts[sizeof(long)];
}mem_byte;
*/
void getdata(pid_t child, char* const addr, unsigned long getlen, char* const rbuf)
{
int i =0, j =0;
char *laddr =NULL;
char *lbuf =NULL;
long mb;
laddr =addr;
lbuf =rbuf;
j =getlen/sizeof(long);
for(i =0; i <j; i++)
{
memset(&mb, 0, sizeof(long));
mb =ptrace(PTRACE_PEEKDATA, child, laddr, NULL);
memcpy(lbuf, &mb, sizeof(long));
lbuf +=sizeof(long);
laddr +=sizeof(long);
}
if(getlen %sizeof(long) !=0)
{
memset(&mb, 0, sizeof(long));
mb =ptrace(PTRACE_PEEKDATA, child, laddr, NULL);
memcpy(lbuf, &mb, getlen %sizeof(long));
}
return;
}
void setdata(pid_t child, void* const addr,unsigned long setlen, char* const sbuf)
{
int i =0, j=0;
char *laddr =NULL;
char *lbuf =NULL;
long mb;
laddr =addr;
lbuf =sbuf;
j =setlen/sizeof(long);
for(i =0; i <j; i++)
{
memset(&mb, 0, sizeof(long));
memcpy(&mb, lbuf, sizeof(long));
ptrace(PTRACE_POKETEXT, child, laddr, mb);
laddr +=sizeof(long);
lbuf +=sizeof(long);
}
if(setlen %sizeof(long) !=0)
{
memset(&mb, 0, sizeof(long));
memcpy(&mb, lbuf, setlen%sizeof(long));
ptrace(PTRACE_POKETEXT, child, laddr, mb);
}
return;
}