2016-11-02 4 views
0

J'ai suivi quelques instructions sur l'utilisation de ptrace que l'on trouve here. Je suis sur Ubuntu 14.04, x64, et j'ai modifié les bits de l'exemple de code pour travailler avec ma machine x64, comme eax à rax, et en changeant 4s à 8s le cas échéant. Le quatrième exemple est supposé inverser la sortie de ls, mais ce n'est pas le cas. Je reçois ceci:L'utilisation de ptrace pour annuler la lecture de ls ne semble pas fonctionner

bin  Debugger.depend dummy1.s  main_tut2.cpp main_tut4.cpp obj 
Debugger.cbp Debugger.layout main_tut1.cpp main_tut3.cpp main_tut5.cpp 
bin  Debugger.depend dummy1.s  main_tut2.cpp main_tut4.cpp obj 
Debugger.cbp Debugger.layout main_tut1.cpp main_tut3.cpp main_tut5.cpp 

Et je crois que je devrais obtenir il renversé si mon code fonctionne correctement, quelque chose comme ceci:

jbo ppc.4tut_niam ppc.2tut_niam s.1ymmud dneped.reggubeD nib 
ppc.5tut_niam ppc.3tut_niam ppc.1tut_niam tuoyal.reggubeD pbc.reggubeD 
jbo ppc.4tut_niam ppc.2tut_niam s.1ymmud dneped.reggubeD nib 
ppc.5tut_niam ppc.3tut_niam ppc.1tut_niam tuoyal.reggubeD pbc.reggubeD 

J'ai trouvé une erreur dans le code imprimé dans la page I lié ci-dessus (here) qui est de 20 lignes à partir du bas dans mon code, mais je pense que j'ai corrigé cela. C'est la ligne incorrecte:

   str = (char *)calloc((params[2] + 1) * sizeof(char)); 

Il a un argument mais a besoin de deux. Je crois qu'il devrait être:

   str = (char *)calloc(params[2] + 1, (params[2] + 1) * sizeof(char)); 

Mais si j'ai tort, je serais heureux d'être corrigé. J'ai essayé aussi:

   str = (char *)calloc(1, (params[2] + 1) * sizeof(char)); 

Je ne suis toujours pas sûr qui serait correct, si l'une ...

Est-ce la raison pour laquelle il ne fonctionne pas? Ou est-ce autre chose, peut-être un autre problème lié à être sur x64 que je n'ai pas pris en compte? Des points bonus pour tous ceux qui peuvent me dire ce que calloc fait dans ce cas et pourquoi le second argument est tel qu'il est.

EDIT:

Je viens de l'impression essayé str avant et après le renversement ... il est juste un tas de points d'interrogation. Quand je débogue, il semble que tout le contenu de str est -1s. Cela suggère en outre que quelque chose ne va pas avec mon appel à calloc() ...

Quoi qu'il en soit, voici ma version du code:

#include <iostream> 
#include <sys/ptrace.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <unistd.h>   // For fork() 
//#include <linux/user.h> // For constants ORIG_EAX for 32bit etc 
#include <sys/user.h>  // For constants ORIG_RAX for 64bit etc 
#include <sys/reg.h> 
#include <sys/syscall.h> // For SYS_write etc 
#include <cstring>   // For strlen() 

/** ptrace(enum __ptrace_request, // behaviour of ptrace 
      pid_t pid,    // Process ID 
      void *addr,    // Address to read in user area 
      void *data);    // 
**/ 

/** 
PTRACE_TRACEME, PTRACE_PEEKTEXT, PTRACE_PEEKDATA, PTRACE_PEEKUSER, PTRACE_POKETEXT, 
PTRACE_POKEDATA, PTRACE_POKEUSER, PTRACE_GETREGS, PTRACE_GETFPREGS, PTRACE_SETREGS, 
PTRACE_SETFPREGS, PTRACE_CONT,  PTRACE_SYSCALL, PTRACE_SINGLESTEP, PTRACE_DETACH 
**/ 

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, 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, 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++; 
     laddr += long_size; 
    } 

    j = len % long_size; 

    if (j != 0) { 
     memcpy(data.chars, laddr, j); 
     ptrace(PTRACE_POKEDATA, child, addr + i * 8, data.val); 
    } 
} 

int main() 
{ 
    pid_t child; 
    child = fork(); 

    if (child == 0) { 

     ptrace(PTRACE_TRACEME, 0, NULL, NULL); 
     execl("/bin/ls", "ls", NULL); 

    } else { 

     long orig_rax; 
     long params[3]; 
     int status; 
     char *str, *laddr; 
     int toggle = 0; 

     while(1) { 

      wait(&status); 
      if (WIFEXITED(status)) 
       break; 

      orig_rax = ptrace(PTRACE_PEEKUSER, child, 8 * ORIG_RAX, NULL); 

      if (orig_rax == SYS_write) { 

       if (toggle == 0) { 

        toggle = 1; 
        params[0] = ptrace(PTRACE_PEEKUSER, child, 8 * RBX, NULL); 
        params[1] = ptrace(PTRACE_PEEKUSER, child, 8 * RCX, NULL); 
        params[2] = ptrace(PTRACE_PEEKUSER, child, 8 * RDX, NULL); 
        str = (char *)calloc(params[2] + 1, (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); 
     } 
    } 

    execl("/bin/ls", "ls", NULL); 

    return 0; 
} 

Toute aide serait grandement appréciée!

+1

Si quelque chose, 'str = calloc (params [2] + 1, sizeof (char));' mais 'sizeof (char)' est toujours 1 afin que vous puissiez en ligne. – melpomene

+1

Copie possible de [ptrace avec PTRACE_PEEKDATA dans Ubuntu] (http://stackoverflow.com/questions/40355632/ptrace-with-ptrace-peekdata-in-ubuntu) –

+0

@melpomene oui oui!Cela aurait plus de sens. Je vais laisser le sizeof() là, peut-être avec un commentaire sur la valeur de la valeur dans certaines circonstances, car c'est mon fichier tutoriel. –

Répondre

0

Merci à @melpmene et @MarkPlotnick pour les réponses. J'ai eu du mal à comprendre certaines des autres réponses couvrant le même sujet, et une autre ressource que j'ai trouvé qui suggérait comment convertir le code x32 en code x64 n'était pas tout à fait exacte (au moins pour mon système), alors voici ce que je nécessaire pour le faire:

1)

str = (char *)calloc(params[2] + 1 * sizeof (char)) 

devrait être

str = (char *)calloc(params[2] + 1, sizeof (char)) 

2)

EBX, ECX et EDX devraient être remplacés par RDI, RSI et RDX