> For the complete documentation index, see [llms.txt](https://sansong.gitbook.io/cyber/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://sansong.gitbook.io/cyber/rev/anti-debugging/ptrace.md).

# ptrace

process trace

<mark style="color:green;">`ptrace`</mark> permet à un processus d'en tracer un autre. Le processus traceur intercepte les appels systèmes du processus tracé.

```c
#include <sys/ptrace.h>

long ptrace(enum __ptrace_request request, 
            pid_t pid,
            void *addr, 
            void *data);
```

{% hint style="success" %}
D'après la doc SunOS: *ptrace est unique et mystérieux*
{% endhint %}

|                                                                                                    Requête                                                                                                   |                       Description                      |
| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------: |
|    <p><mark style="color:green;"><code>PTRACE\_TRACEME</code></mark><br><mark style="color:green;"><code>PTRACE\_ATTACH</code></mark><br><mark style="color:green;"><code>PTRACE\_DETACH</code></mark></p>   |               Attachement à un processus               |
| <p><mark style="color:green;"><code>PTRACE\_PEEKTEXT</code></mark><br><mark style="color:green;"><code>PTRACE\_PEEKDATA</code></mark><br><mark style="color:green;"><code>PTRACE\_PEEKUSER</code></mark></p> |                     Lecture mémoire                    |
| <p><mark style="color:green;"><code>PTRACE\_POKETEXT</code></mark><br><mark style="color:green;"><code>PTRACE\_POKEDATA</code></mark><br><mark style="color:green;"><code>PTRACE\_POKEUSER</code></mark></p> |                    Écriture mémoire                    |
|                                    <p><mark style="color:green;"><code>PTRACE\_GETREGS</code></mark><br><mark style="color:green;"><code>PTRACE\_SETREGS</code></mark></p>                                   | <p>Lecture des registres<br>Écriture des registres</p> |

### Anti-debug

Un processus ne peut être tracé que **par un seul processus à la fois**. Pour empêcher le debug d'un programme, un attaquant peut appeler <mark style="color:green;">`ptrace`</mark> avec la request <mark style="color:green;">`PTRACE_TRACEME`</mark> pour qu'il trace son propre processus.

Si un debugger essaye de s'attacher au processus avec <mark style="color:green;">`ptrace`</mark> la fonction renvoie une erreur car le processus est déjà tracée grâce à l'appel de <mark style="color:green;">`ptrace`</mark> dans le programme !

```c
/* gcc ptrace.c -o ptrace */

#include <stdio.h>
#include <sys/ptrace.h>

int main() {

    if (ptrace(PTRACE_TRACEME, 0, 0, 0) == -1) {
        printf("debugger détecté!\n");
        return 1;
    }
    
    printf("exécution normale\n");
    
    return 0;
}
```

**Si on l'exécute normalement tout se passe bien.**

```bash
$ ./ptrace
exécution normale

```

**Si on utilise un debugger, problème.**

```sh
$ gdb ./ptrace
gef➤  r
Starting program: /home/sam/Documents/anti-debug/ptrace 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
debugger détecté!
[Inferior 1 (process 15851) exited with code 01]

```

### **Bypass ptrace**

#### **LD\_PRELOAD**

On redéfinit le code de la fonction.

```c
/* gcc ptrace-so.c -fPIE -shared -o ptrace.so */

long ptrace(int request, int pid,
            void *addr, void *data) {
	return 0;
}
```

On le compile en tant que librairie partagée.

```bash
$ gcc ptrace-so.c -fPIE -shared -o ptrace.so
$ file ptrace.so
ptrace.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=bc408e29b4f3c7268a42e3f9d390cab0747b902c, not stripped
```

On met le path de la librairie dans `LD_PRELOAD`.

```bash
export LD_PRELOAD=/chemin/vers/ptrace.so
```

Si on utilise un debugger notre `ptrace` est utilisé au lieu du vrai code et ça marche !

```sh
$ gdb ./ptrace
gef➤  r
Starting program: /home/sam/Documents/anti-debug/ptrace 
exécution normale
During startup program exited normally.

```

#### **NOP**

On peut modifier le binaire pour remplacer l'appel à <mark style="color:green;">`ptrace`</mark> par des instructions NOP.

Avec IDA:

* afficher les opcodes: <mark style="color:green;">`Options > Général > Number of opcodes bytes > 6`</mark>
* cliquer sur l'opcode correspondant
* <mark style="color:green;">`Edit > Patch program > Change byte`</mark>
* remplacer par 90 (opcode de NOP)
* <mark style="color:green;">`Edit > Patch program > Apply patches to input file`</mark>

**Modifier à l'exécution**

Si le programme vérifie la valeur de retour et agit en fonction on peux juste mettre un breakpoint sur la vérification et modifier la valeur du registre concerné ou changer l'instruction JUMP avec un qui évite le bloc qui stop l'exécution.

{% hint style="danger" %}
Réponse des attaquants à ces méthodes:

* création de 2 processus qui se tracent mutuellement et communiquent pour s'assurer de la survie de l'autre

-> voir [Nanomites](/cyber/rev/anti-debugging/nanomites.md)
{% endhint %}
