Reversing Tools — méthode pratique avec x64dbg, Ghidra, WinDbg et Sysinternals

Salut ce forum est dédié à comprendre les entrailles de l'ordinateur au plus bas niveau bienvenue dans le monde du reverse et de l'assembleur

Moderator: Rick

Post Reply
Hydraxx
Site Admin
Posts: 114
Joined: Mon Jan 12, 2026 4:04 pm
Location: France
Contact:

Reversing Tools — méthode pratique avec x64dbg, Ghidra, WinDbg et Sysinternals

Post by Hydraxx »

Reversing Tools — méthode pratique avec x64dbg, Ghidra, WinDbg et Sysinternals

Objectif du cours

Ce chapitre présente les outils essentiels du reverse engineering, mais surtout comment les utiliser ensemble.

L'idée importante est :

Code: Select all

un seul outil ne suffit presque jamais
En pratique, on combine souvent :

Code: Select all

Ghidra        → comprendre la structure du programme
x64dbg        → observer l'exécution réelle
Process Monitor → voir fichiers / registre / processus
Process Explorer → modules / handles / threads
WinDbg        → user-mode avancé et kernel
DUMPBIN / PE viewer → structure du PE
Le but du cours n'est donc pas de connaître une liste d'outils par cœur.

Le but est de savoir :

Code: Select all

quel outil utiliser
pour quel problème
et dans quel ordre
1. Analyse statique et analyse dynamique

Il existe deux grandes manières d'analyser un programme.

Analyse statique

On analyse le binaire sans l'exécuter.

Outils typiques :

Code: Select all

Ghidra
IDA
DUMPBIN
PE viewers
strings
On cherche notamment :
  • les fonctions ;
  • les imports ;
  • les strings ;
  • les xrefs ;
  • les graphes ;
  • les sections ;
  • les structures du PE.
Analyse dynamique

On exécute le programme et on observe son comportement réel.

Outils :

Code: Select all

x64dbg
WinDbg
Process Monitor
Process Explorer
On observe :
  • les registres ;
  • la mémoire ;
  • les appels API ;
  • les fichiers ouverts ;
  • les accès registre ;
  • les threads ;
  • les modules chargés.
Réflexe

En pratique :

Code: Select all

statique = où regarder
dynamique = confirmer ce qui se passe réellement
Les deux sont complémentaires.

2. Post-mortem et live analysis

Post-mortem

On analyse après l'exécution :
  • dump mémoire ;
  • crash dump ;
  • fichier PE ;
  • logs ;
  • traces.
Live analysis

On observe le programme pendant qu'il tourne.

Exemple :

Code: Select all

breakpoint sur CreateFileW
↓
programme continue
↓
breakpoint déclenché
↓
inspection RCX
↓
chemin du fichier trouvé
Pour toi, le live reversing avec x64dbg est souvent le plus rentable.

3. Désassembleurs

Un désassembleur transforme le code machine en assembleur.

Exemple machine :

Code: Select all

48 8B 41 08
peut devenir :

Code: Select all

mov rax, [rcx+8]
Mais le désassembleur doit aussi déterminer :
  • où commence le code ;
  • où finissent les données ;
  • quelles adresses sont des fonctions ;
  • quels sauts sont liés ;
  • quelles zones sont réellement exécutables.
Un désassemblage automatique peut donc être imparfait.

Important

Un désassembleur ne "comprend" pas vraiment le programme comme un humain.

Il reconstruit une représentation.

4. Basic Blocks

Un basic block est un bloc d'instructions exécuté sans branchement interne.

Exemple :

Code: Select all

mov eax, [rcx]
cmp eax, 10
jle failed
Puis le flot se sépare.

Les graphes de contrôle affichent ces blocs sous forme de boîtes reliées.

C'est extrêmement utile pour comprendre :
  • if ;
  • else ;
  • boucles ;
  • switch ;
  • chemins de retour.
5. Ghidra : vue d'ensemble

Ghidra est particulièrement utile pour l'analyse statique.

Quand tu importes un PE :
  • Ghidra analyse les sections ;
  • détecte les fonctions ;
  • résout les imports ;
  • trouve les strings ;
  • construit les xrefs ;
  • génère du pseudo-code.
Les vues importantes :

Code: Select all

Listing
Decompiler
Functions
Symbol Tree
Strings
Defined Data
References
Function Graph
6. Functions dans Ghidra

Une fonction détectée peut apparaître comme :

Code: Select all

FUN_1400012A0
Au début, elle n'a aucun sens.

Mais après analyse, tu peux la renommer :

Code: Select all

FUN_1400012A0
↓
ReadConfig
ou :

Code: Select all

CheckSession
Ce renommage est très important.

Plus tu renommes :
  • fonctions ;
  • variables ;
  • paramètres ;
  • structures ;
plus le binaire devient lisible.

7. Strings dans Ghidra

Les strings sont souvent l'un des meilleurs points d'entrée.

Exemple :

Code: Select all

"Access denied"
"C:\\config.ini"
"Global\\MyMutex"
"Invalid password"
Tu peux :

Code: Select all

string
↓
Show References To
↓
fonction qui utilise la string
↓
analyse de la fonction
C'est beaucoup plus rapide que de partir de l'entry point.

8. Xrefs

Xref signifie :

Code: Select all

cross-reference
Une xref permet de savoir :

Code: Select all

qui utilise cette fonction ?
qui utilise cette variable ?
qui référence cette chaîne ?
Exemple :

Code: Select all

VirtualAlloc
↓
Xrefs
↓
3 fonctions l'appellent
Tu peux alors analyser directement ces trois fonctions.

Réflexe

Quand tu trouves quelque chose d'intéressant :

Code: Select all

fonction
string
global
import
cherche les xrefs.

9. Function Graph

Le graph view permet de visualiser les basic blocks.

Exemple logique :

Code: Select all

        cmp eax, 10
          |
      +---+---+
      |       |
    >10      <=10
      |       |
 success    failed
C'est très utile pour reconstruire du :

Code: Select all

if / else
ou des boucles.

10. Call Graph

Un call graph montre les relations entre fonctions.

Exemple :

Code: Select all

main
 ├── Init
 ├── LoadConfig
 ├── Connect
 │    └── ResolveHost
 └── Cleanup
Cela permet de comprendre l'architecture globale du programme.

Pour un gros binaire, c'est souvent plus utile que de lire toutes les instructions.

11. Décompilateurs

Un décompilateur tente de reconstruire du pseudo-code C/C++.

Exemple assembleur :

Code: Select all

mov eax, [rcx]
test eax, eax
je failed
add eax, 5
ret
Pseudo-code possible :

Code: Select all

if (*param_1 == 0)
    return 0;

return *param_1 + 5;
Le décompilateur est très utile, mais :

Code: Select all

pseudo-code != code source original
12. Limites du décompilateur

Le compilateur a pu :
  • optimiser ;
  • inliner ;
  • supprimer des variables ;
  • recalculer des constantes ;
  • réorganiser du code ;
  • fusionner des branches.
Exemple source :

Code: Select all

int x = 5;
return x * 2;
peut devenir :

Code: Select all

mov eax, 10
ret
Le décompilateur ne peut pas "deviner" que `x` existait.

Réflexe

Utilise le pseudo-code pour comprendre rapidement.

Vérifie l'assembleur si quelque chose paraît incohérent.

13. Reverse .NET

Pour .NET, le code est souvent beaucoup plus facile à reconstruire.

On analyse :

Code: Select all

CIL / MSIL
metadata
classes
methods
types


Aujourd'hui, on peut utiliser différents outils modernes.

Le point important :

Code: Select all

reverse .NET != reverse natif C/C++
En .NET, beaucoup de métadonnées survivent.

En natif, beaucoup d'informations disparaissent.

14. Debuggers

Un debugger permet de contrôler l'exécution.

Il peut :
  • arrêter le programme ;
  • continuer ;
  • exécuter instruction par instruction ;
  • afficher les registres ;
  • afficher la stack ;
  • inspecter la mémoire ;
  • poser des breakpoints ;
  • modifier certaines valeurs.
Pour toi, l'outil principal en user-mode est :

Code: Select all

x64dbg
15. Run, Pause, Step Into, Step Over, Step Out

Run

Continue jusqu'au prochain breakpoint ou événement.

Pause

Interrompt le programme.

Step Into

Exécute une instruction.

Si c'est un `call`, entre dans la fonction.

Step Over

Exécute le `call` sans entrer dedans.

Très utile pour éviter :

Code: Select all

std::cout
ucrtbase
KernelBase
ntdll
quand ce n'est pas ton objectif.

Step Out

Continue jusqu'au retour de la fonction courante.

16. Breakpoints logiciels

Un breakpoint logiciel modifie temporairement le code pour provoquer une interruption.

Typiquement avec une instruction :

Code: Select all

INT3
Le debugger restaure ensuite l'instruction originale au bon moment.

C'est le breakpoint classique.

Exemple :

Code: Select all

bp VirtualAlloc
Le programme s'arrête dès que `VirtualAlloc` est appelée.

17. Hardware Breakpoints

Les breakpoints matériels utilisent les registres de debug du CPU.

Ils sont utiles notamment pour surveiller :
  • exécution ;
  • lecture mémoire ;
  • écriture mémoire ;
  • accès mémoire.
Exemple pratique :

Tu as trouvé une variable en mémoire :

Code: Select all

000001F4A1002000
Tu veux savoir :

Code: Select all

qui modifie cette valeur ?
Pose un hardware breakpoint sur écriture.

Quand la valeur est modifiée :

Code: Select all

break
↓
RIP montre l'instruction responsable
C'est extrêmement puissant.

18. Breakpoint sur API

C'est probablement l'une des techniques les plus importantes pour ton reverse Windows.

Exemple :

Code: Select all

VirtualAlloc
Breakpoint.

Quand il se déclenche :

Code: Select all

RCX = lpAddress
RDX = size
R8  = flags
R9  = protection
Après le retour :

Code: Select all

RAX = adresse allouée
Tu reconstruis l'appel sans symboles du programme.

19. Registres importants sous Windows x64

Les registres les plus utiles :

Code: Select all

RAX → retour / calculs
RCX → argument 1
RDX → argument 2
R8  → argument 3
R9  → argument 4
RSP → stack pointer
RBP → base éventuelle de frame
RIP → instruction courante
Les autres comme :

Code: Select all

RBX
RSI
RDI
R12-R15
sont souvent utilisés pour conserver des valeurs plus longtemps.

20. Flags

Les flags déterminent souvent les sauts conditionnels.

Exemple :

Code: Select all

cmp eax, 10
je equal
`cmp` modifie les flags.

`je` examine notamment le Zero Flag.

Pour le reverse, retiens :

Code: Select all

cmp / test
↓
flags
↓
jcc
21. Stack dans x64dbg

La stack contient beaucoup d'informations utiles.

Tu peux y retrouver :
  • adresses de retour ;
  • arguments supplémentaires ;
  • variables locales ;
  • pointeurs ;
  • chaînes temporaires.
Sous Windows x64, les quatre premiers arguments passent par :

Code: Select all

RCX
RDX
R8
R9
Mais les arguments suivants sont sur la stack.

Exemple :

Code: Select all

CreateFileW
a plus de quatre paramètres.

Il faut donc examiner :

Code: Select all

RSP + offsets
pour les suivants.

22. Dump mémoire

Le dump permet d'afficher la mémoire brute.

Tu peux suivre :

Code: Select all

RCX
RAX
RSP
adresse
pointeur
et voir :
  • octets ;
  • ASCII ;
  • Unicode ;
  • pointeurs ;
  • structures.
Exemple :

Code: Select all

RCX = 000001F4A1003000
Tu suis RCX dans le dump.

Tu vois :

Code: Select all

43 00 3A 00 5C 00 ...
En Unicode :

Code: Select all

C:\...
Tu viens de retrouver une chaîne.

23. Suivre un pointeur

Si :

Code: Select all

RAX = 000001F4A1000000
et :

Code: Select all

[RAX] = 000001F4A2000000
alors `RAX` contient un pointeur vers une zone qui contient elle-même un autre pointeur.

Tu dois être à l'aise avec :

Code: Select all

registre
↓
adresse
↓
contenu
↓
nouvelle adresse éventuelle
24. Memory Map

La Memory Map de x64dbg est très utile.

Elle montre :
  • modules ;
  • stack ;
  • heap ;
  • private memory ;
  • mapped memory ;
  • protections.
Exemple :

Code: Select all

Base                 Size      Protection
000001F4A1000000     1000      RW
Si cette région vient juste d'être retournée par `VirtualAlloc`, tu sais exactement où regarder.

25. Modules

Un processus charge plusieurs modules.

Exemple :

Code: Select all

program.exe
ntdll.dll
kernel32.dll
KernelBase.dll
ucrtbase.dll
Dans x64dbg, la liste des modules permet de :
  • retrouver leur base ;
  • calculer des RVA ;
  • identifier les DLL ;
  • retrouver une fonction.
26. Threads

Le debugger montre les threads du processus.

Pour chaque thread, tu peux regarder :
  • RIP ;
  • stack ;
  • état ;
  • adresse de démarrage.
Si un programme fait beaucoup de multithreading, identifier le bon thread est important.

27. x64dbg : workflow minimal

Pour un petit programme inconnu :

1

Ouvre le programme.

2

Regarde :

Code: Select all

imports
strings
modules
memory map
3

Choisis une API intéressante.

4

Pose un breakpoint.

5

Lance le programme.

6

Quand ça casse :

Code: Select all

RCX
RDX
R8
R9
RSP
7

Suis les pointeurs.

8

Remonte vers l'appelant.

C'est souvent suffisant pour comprendre beaucoup de programmes.

28. Exercice x64dbg : VirtualAlloc

Programme :

Code: Select all

void* p = VirtualAlloc(
    nullptr,
    0x2000,
    MEM_RESERVE | MEM_COMMIT,
    PAGE_READWRITE
);
Tu poses :

Code: Select all

breakpoint VirtualAlloc
Au breakpoint :

Code: Select all

RCX = 0
RDX = 2000h
R8  = 3000h
R9  = 4
Tu reconstruis :

Code: Select all

VirtualAlloc(NULL, 0x2000, 0x3000, 0x4)
Puis Step Over.

Après retour :

Code: Select all

RAX = nouvelle adresse
Tu suis RAX dans la Memory Map ou le dump.

29. Exercice x64dbg : retrouver une chaîne

Supposons :

Code: Select all

lea rcx, [rip+1234h]
call SomeFunction
Tu suis l'adresse :

Code: Select all

RIP + 1234h
dans le dump.

Tu trouves :

Code: Select all

"config.ini"
Tu peux ensuite chercher :

Code: Select all

xrefs / références
pour savoir où cette chaîne est utilisée.

30. Exercice x64dbg : reconstruire un if

Tu vois :

Code: Select all

cmp eax, 5
jne failed

mov ebx, 1
jmp end

failed:
xor ebx, ebx

end:
Tu peux reconstruire :

Code: Select all

if (eax == 5)
    ebx = 1;
else
    ebx = 0;
Le nom réel des variables n'est pas important.

La structure logique l'est.

31. Exercice x64dbg : reconstruire une boucle

Tu vois :

Code: Select all

xor ecx, ecx

loop:
cmp ecx, 10
jge done

inc ecx
jmp loop

done:
Tu reconnais :

Code: Select all

for (int i = 0; i < 10; i++)
Le saut vers une adresse plus basse est un indice fort de boucle.

32. Ghidra + x64dbg ensemble

Le workflow le plus puissant pour toi :

Code: Select all

Ghidra
↓
trouver fonction intéressante
↓
noter RVA
↓
x64dbg
↓
module base + RVA
↓
breakpoint
↓
observer runtime
Exemple :

Dans Ghidra :

Code: Select all

fonction RVA = 0x2450
Dans x64dbg :

Code: Select all

base = 0x00007FF700000000
Adresse runtime :

Code: Select all

0x00007FF700000000 + 0x2450
=
0x00007FF700002450
Tu poses un breakpoint à cette adresse.

33. Attention à l'ASLR

Avec ASLR, la base du module peut changer.

Donc :

Code: Select all

adresse absolue Ghidra
n'est pas forcément identique à l'adresse runtime.

Le bon réflexe est :

Code: Select all

RVA = adresse - image base
Puis :

Code: Select all

runtime = base actuelle + RVA
34. WinDbg user-mode

WinDbg peut aussi debugger un processus user-mode.

Il est très utile pour :
  • symboles ;
  • exceptions ;
  • stacks ;
  • modules ;
  • structures Windows.
Pour du reverse interactif pur, x64dbg est souvent plus confortable.

Pour du debug système avancé, WinDbg devient très puissant.

35. Debuggers kernel-mode

Un debugger kernel permet d'observer l'ensemble du système.

Il peut voir :
  • drivers ;
  • threads kernel ;
  • processus ;
  • objets ;
  • mémoire kernel ;
  • structures internes.
Mais il faut être beaucoup plus prudent.

Un mauvais état peut planter toute la machine cible.

36. WinDbg kernel

Le scénario recommandé :

Code: Select all

PC hôte
↓
WinDbg
↓
connexion debug
↓
VM Windows cible
La VM peut être :
  • arrêtée ;
  • debuggée ;
  • snapshotée ;
  • restaurée.
C'est beaucoup plus sûr que de tester directement sur ta machine principale.

37. Pourquoi utiliser une VM

Avantages :
  • isolation ;
  • snapshots ;
  • récupération rapide ;
  • crashes sans casser la machine principale ;
  • tests kernel plus sûrs.
Pour le reverse kernel :

Code: Select all

WinDbg + VM
est le workflow moderne logique.

38. System-Monitoring Tools

Le reverse ne se limite pas à l'assembleur.

On peut observer le comportement du programme depuis l'extérieur.

Exemples :
  • fichiers ouverts ;
  • clés registre ;
  • processus créés ;
  • DLL chargées ;
  • connexions réseau ;
  • handles.
C'est ce qu'on appelle souvent :

Code: Select all

system monitoring
39. Process Monitor

Process Monitor est l'un des outils les plus utiles.

Il permet de voir :
  • File System ;
  • Registry ;
  • Process / Thread ;
  • Image Load.
Exemple :

Tu lances un programme.

ProcMon montre :

Code: Select all

CreateFile
C:\ProgramData\App\config.dat
SUCCESS
Tu sais immédiatement quel fichier est important.

Ensuite :

Code: Select all

x64dbg
↓
breakpoint CreateFileW
↓
retrouver l'appel exact
40. Filtres Process Monitor

Sans filtres, ProcMon affiche énormément d'événements.

Exemple de filtre :

Code: Select all

Process Name is target.exe
Puis éventuellement :

Code: Select all

Operation is CreateFile
ou :

Code: Select all

Path contains config
Le but :

Code: Select all

réduire le bruit
41. Process Explorer

Process Explorer permet d'inspecter un processus.

Tu peux voir :
  • arbre de processus ;
  • PID ;
  • threads ;
  • DLL ;
  • handles ;
  • propriétés ;
  • consommation mémoire.
Très utile avant ou pendant un reverse.

Exemple :

Code: Select all

target.exe
↓
DLLs
↓
mylibrary.dll
Tu découvres qu'une DLL non évidente est chargée.

Tu peux ensuite l'analyser dans Ghidra.

42. Handles dans Process Explorer

Tu peux retrouver :

Code: Select all

File
Mutex
Section
Event
Key
Exemple :

Code: Select all

Mutant
\BaseNamedObjects\MyMutex
Tu sais que le programme utilise un mutex nommé.

Tu peux chercher la chaîne dans Ghidra.

43. TCPView

TCPView permet de voir :
  • connexions TCP ;
  • UDP ;
  • ports locaux ;
  • ports distants ;
  • processus associés.
Exemple :

Code: Select all

target.exe
TCP
192.168.1.5:52000
93.184.216.34:443
Tu sais alors que le programme communique en réseau.

Ensuite tu peux poser des breakpoints sur :

Code: Select all

connect
send
recv
WSASend
WSARecv
44. Choisir le bon outil

Question :

Code: Select all

je veux trouver une fonction
Réponse :

Code: Select all

Ghidra
Question :

Code: Select all

je veux savoir quelles valeurs passent dans une API
Réponse :

Code: Select all

x64dbg
Question :

Code: Select all

je veux savoir quel fichier est ouvert
Réponse :

Code: Select all

Process Monitor
Question :

Code: Select all

je veux voir les modules et handles
Réponse :

Code: Select all

Process Explorer
Question :

Code: Select all

je veux voir le kernel
Réponse :

Code: Select all

WinDbg
Question :

Code: Select all

je veux inspecter les headers PE
Réponse :

Code: Select all

DUMPBIN / PE viewer
45. Patching

Patcher signifie modifier le programme.

Exemple simple :

Code: Select all

jne failed
peut être remplacé temporairement par :

Code: Select all

je failed
ou :

Code: Select all

nop
nop
Le but est de modifier le comportement pour comprendre une branche ou tester une hypothèse.

Attention

Toujours conserver l'original.

46. Patching temporaire et permanent

Temporaire

Modification en mémoire pendant le debug.

Après fermeture du processus :

Code: Select all

patch perdu
Permanent

Modification enregistrée dans le fichier PE.

Le programme reste modifié au prochain lancement.

47. Exemple simple de patch

Code :

Code: Select all

cmp eax, 1
jne failed
Tu veux vérifier ce qui se passe si la condition réussit toujours.

Tu peux patcher temporairement :

Code: Select all

jne failed
en :

Code: Select all

nop
nop
Puis reprendre l'exécution.

Si le comportement change comme prévu, ton hypothèse était correcte.

48. Hex Editors

Un éditeur hexadécimal permet de voir les octets du fichier brut.

Exemple :

Code: Select all

75 05
peut représenter :

Code: Select all

jne +5
Mais attention :

Code: Select all

adresse runtime != offset fichier
Tu dois convertir correctement.

49. Executable Dumping

Dumper un exécutable consiste à récupérer une image ou des informations sur le PE.

Cela peut servir à examiner :
  • headers ;
  • sections ;
  • imports ;
  • exports ;
  • image mémoire.
Un dump mémoire peut être utile si le programme change son contenu à runtime.

50. DUMPBIN

DUMPBIN est fourni avec les outils Visual Studio.

Commandes utiles :

Code: Select all

dumpbin /headers program.exe
Affiche les headers.

Code: Select all

dumpbin /imports program.exe
Affiche les imports.

Code: Select all

dumpbin /exports library.dll
Affiche les exports.

Code: Select all

dumpbin /disasm program.exe
Produit du désassemblage.

51. PE Viewers

Un PE viewer permet d'examiner visuellement :
  • DOS header ;
  • NT headers ;
  • sections ;
  • imports ;
  • exports ;
  • resources ;
  • directories.


Aujourd'hui, tu peux utiliser un viewer PE moderne.

Le principe reste exactement le même.

52. Dump mémoire d'une région

Supposons qu'après `VirtualAlloc`, tu vois :

Code: Select all

RAX = 000001F4A1000000
Plus tard, cette zone contient des données.

Tu peux :

Code: Select all

suivre RAX
↓
observer la région
↓
sauvegarder / comparer le contenu
Cela permet de voir ce qui a été construit à runtime.

53. Workflow pratique complet

Pour un binaire inconnu :

Étape 1 — Process Monitor

Regarde ce que le programme fait :

Code: Select all

fichiers
registre
processus
Étape 2 — Process Explorer

Regarde :

Code: Select all

DLL
handles
threads
Étape 3 — Ghidra

Cherche :

Code: Select all

imports
strings
xrefs
fonctions
Étape 4 — x64dbg

Pose des breakpoints ciblés.

Regarde :

Code: Select all

RCX
RDX
R8
R9
RAX
stack
Étape 5

Reconstruis du pseudo-code.

Étape 6

Si nécessaire :

Code: Select all

patch
ou
WinDbg kernel
54. Mini défi : API + mémoire

Tu vois :

Code: Select all

xor ecx, ecx
mov edx, 1000h
mov r8d, 3000h
mov r9d, 4
call VirtualAlloc

mov rbx, rax
Question :

Que dois-tu faire ?

Réponse :

Code: Select all

1. reconnaître VirtualAlloc
2. décoder les arguments
3. Step Over
4. récupérer RAX
5. suivre RAX dans le dump
6. regarder qui écrit dans cette zone
55. Mini défi : fichier

Process Monitor montre :

Code: Select all

target.exe
CreateFile
C:\temp\data.bin
SUCCESS
Workflow :

Code: Select all

ProcMon
↓
information comportementale
↓
x64dbg
↓
breakpoint CreateFileW
↓
regarder RCX
↓
retrouver appelant
Puis tu peux suivre :

Code: Select all

ReadFile
WriteFile
pour voir ce que le programme fait du fichier.

56. Mini défi : fonction sans symbole

Dans Ghidra :

Code: Select all

FUN_140002340
contient :

Code: Select all

VirtualAlloc
memcpy
VirtualProtect
Tu suspects une routine de préparation mémoire.

Workflow :

Code: Select all

1. noter RVA
2. calculer adresse runtime
3. breakpoint x64dbg
4. observer arguments
5. suivre buffers
6. renommer fonction
Même si tu n'as pas le nom original, tu peux l'appeler :

Code: Select all

PrepareBuffer
si c'est ce qu'elle semble faire.

57. Mini défi : hardware breakpoint

Tu trouves :

Code: Select all

player.hp = 100
dans la mémoire.

Mais tu ne sais pas quelle fonction le modifie.

Tu poses :

Code: Select all

hardware breakpoint
on write
sur l'adresse de `hp`.

Plus tard :

Code: Select all

break
RIP pointe vers :

Code: Select all

sub dword ptr [rcx], eax
Tu viens de trouver la fonction qui modifie les HP.

58. Mini défi : patch

Tu vois :

Code: Select all

cmp eax, 0
je failed
Tu veux confirmer que cette branche contrôle l'échec.

Patch temporaire :

Code: Select all

je failed

Code: Select all

nop
nop
Tu continues.

Si la branche failed n'est plus prise et que le comportement change, tu as confirmé la logique.

59. Erreurs classiques

Erreur 1

Vouloir lire tout le programme depuis l'entry point.

Mieux :

Code: Select all

imports / strings / xrefs / API
Erreur 2

Entrer dans toutes les fonctions système.

Tu peux perdre énormément de temps.

Utilise souvent :

Code: Select all

Step Over
Erreur 3

Faire confiance aveuglément au décompilateur.

Toujours vérifier l'assembleur si nécessaire.

Erreur 4

Oublier l'ASLR.

Travaille avec les RVA.

Erreur 5

Confondre adresse, RVA et offset fichier.

Ce sont trois notions différentes.

Erreur 6

Utiliser un seul outil.

Le reverse devient beaucoup plus facile en combinant les outils.

60. Méthode à retenir

Ta méthode pratique peut être :

Code: Select all

1. comportement externe
   → Process Monitor / Process Explorer

2. structure
   → Ghidra

3. point intéressant
   → string / import / xref

4. confirmation runtime
   → x64dbg

5. arguments
   → RCX RDX R8 R9 + stack

6. valeurs de retour
   → RAX

7. données
   → dump / memory map

8. origine
   → remonter vers l'appelant

9. comprendre
   → pseudo-code

10. si besoin
   → patch / WinDbg
61. Ce qu'il faut retenir

Les outils ont chacun un rôle.

Code: Select all

Ghidra
= structure du programme

Code: Select all

x64dbg
= comportement réel instruction par instruction

Code: Select all

Process Monitor
= fichiers / registre / événements système

Code: Select all

Process Explorer
= processus / modules / handles / threads

Code: Select all

WinDbg
= debugging avancé Windows et kernel

Code: Select all

DUMPBIN / PE viewer
= structure du PE
Le point le plus important est :

Code: Select all

ne choisis pas un outil parce que tu l'aimes
choisis-le parce qu'il répond à la question que tu te poses
Conclusion

Un bon reverse engineer ne passe pas son temps à lire des milliers d'instructions.

Il cherche des points d'entrée pertinents.

Exemple :

Code: Select all

"quel fichier est utilisé ?"
→ Process Monitor

"quelle fonction utilise cette string ?"
→ Ghidra

"quels arguments passent dans VirtualAlloc ?"
→ x64dbg

"quel objet est ouvert ?"
→ Process Explorer

"que fait ce driver ?"
→ WinDbg + VM
La combinaison des outils permet de réduire énormément le travail.

Le workflow moderne recommandé est donc :

Code: Select all

Process Monitor / Process Explorer
        ↓
      Ghidra
        ↓
      x64dbg
        ↓
WinDbg si nécessaire
À partir de là, le reverse n'est plus seulement :

Code: Select all

lire de l'assembleur
mais :

Code: Select all

collecter des indices
les relier
tester des hypothèses
et reconstruire le fonctionnement réel du programme

Who is online

Users browsing this forum: No registered users and 1 guest