64
DANS LES ENTRAILLES DU LANGAGE C No#ons de bases pour comprendre les technique d’exploit en C

Dans les entrailles du langage C

Embed Size (px)

DESCRIPTION

Séance de Club Code à Télécom SudParis sur le langage C avec une initiation à GDB. Le code source des exercices est disponible en télégargement sur la page http://intlab.minet.net/?p=113

Citation preview

Page 1: Dans les entrailles du langage C

DANSLESENTRAILLESDULANGAGECNo#onsdebasespourcomprendrelestechniqued’exploitenC

Page 2: Dans les entrailles du langage C

ATTENTION!

Ce/eprésenta7ons'appuieengrandepar7esurl'excellentlivredeJonErickson"Hacking,theartofexploita7on".

LesprogrammesenCquiserontécritspuisétudiésnesontquele

prétexteàundécor7cageunpeupousséducode.Ce/eprésenta7onestuncoursintroduc7fàunesecondesession

depra7qued'exploitenCsurunvieuxnoyauLinux.

2

Page 3: Dans les entrailles du langage C

SOMMAIRE

  ConceptsdeCàtraverslescopedudeboggueur

  Backtothebasics

 Memorysegmenta#on

3

Page 4: Dans les entrailles du langage C

SOMMAIRE

Backtothebasics

 ProgrammessimplesenC LeGNUCompilerCollec7on(GCC) Leprocesseurx86(Intel)  Instruc7onsassembleurpourx86 Quelquescommandesu7lespourGDB

  ConceptsdeCàtraverslescopedudeboggueur

 Memorysegmenta#on

4

Page 5: Dans les entrailles du langage C

SOMMAIRE

Backtothebasics

 Chaînesdecaractères(strings) Signedness Pointeurs Typecas0ng Argumentsenlignedecommande Portéedesvariables

  ConceptsdeCàtraverslescopedudeboggueur

 Memorysegmenta#on

5

Page 6: Dans les entrailles du langage C

SOMMAIRE

Backtothebasics

 Segmentsdelamémoire No7ondestack(«pile»mémoire) No7ondeheap(«tas») Principesdestechniquesd’overflow

  ConceptsdeCàtraverslescopedudeboggueur

 Memorysegmenta#on

6

Laprochainefois!

Page 7: Dans les entrailles du langage C

BACKTOTHEBASICS

7

Page 8: Dans les entrailles du langage C

CODINGTIME!

EcrireunprogrammeenCpour  Afficher10foislachainedecaractères"HelloWord!"

  Alacompila7on:nepasoublierl'op7on–g(u7leultérieurementpourledebug)

8

Page 9: Dans les entrailles du langage C

BACKTOTHEBASICS

UnprogrammesimpleenC #include <stdio.h> int main(){

int i; for (i = 0; i < 10; i++){ printf("Hello world !\n"); } return 0;

}

Compilerleprogrammepourl'éxecuter

AvecleGNUCompilerCollec7on(GCC):#gcc‐gprog.c ‐>a.out*ou#gcc–gprog.c–oprog ‐>prog*

9

Page 10: Dans les entrailles du langage C

BACKTOTHEBASICS

Lerôleducompilateur C'estuntraducteurdecoded'unlangage(langagesource)versunautre(langagecible).Exemples:o  GCC:GNUCompilerCollec7onpourleC,C++essen7ellemento  Javac,compilateurJavao  ClangpourlangagesdelafamilleCo  GHCpourleHaskell

Encequinousconcerne,lelangagecibleestlelangagecompréhensibleparl'ordinateurpourqu'ilexécutenoscommandes.  Langageassembleur

10

Page 11: Dans les entrailles du langage C

BACKTOTHEBASICS

Op#misa#onducodeparlecompilateur

Lecompilateurvagénéralementchercheràop7miserlecodecible:  Améliora7ondelavitessed'exécu7on(ré‐ordonnancementdes

instruc7ons)  Réduc7ondel'occupa7onmémoireduprogramme

  Queditmangcc?Withoutanyop0miza0onop0on,thecompiler'sgoalistoreducethecostofcompila0onandtomakedebuggingproducetheexpectedresults.Turningonop0miza0onflagsmakesthecompilera@empttoimprovetheperformance and/or code size at the expense of compila0on 0me andpossiblytheabilitytodebugtheprogram.Op7ons:–O0(default)–O1–O2–O3...

11

Page 12: Dans les entrailles du langage C

BACKTOTHEBASICS

Compilateurvsinterpréteur

Certainslangagesnesontpascompilés.L'interpréteurlitetanalyseun"script"pourenexécuterlesinstruc7onsàlavolée.Exemples:o  basho  SQLEnUnix,leshellestuninterpréteurdelignedecommande.

12

Page 13: Dans les entrailles du langage C

BACKTOTHEBASICS

Lelangageassembleurpourx86

Surlaplupartdesordinateurs,leprocesseurquiexécutelesinstruc7onsappar7entàlafamillex86.Ils'agitdelafamilledeprocesseursIntelIA32bits,baséesurlepremiermicroprocesseurdecetyped'architecture:leIntel8086.Lelangageassembleurx86estunjeud'instruc7onscompa7blesaveclesprocesseursdelafamillex86.

13

Page 14: Dans les entrailles du langage C

DISASSEMBLINGTIME!

Surleprogrammeprécédent:  Visualiserlefichierexécutablesimple_progCommentafficherleprogrammeenlangageassembleur?  AvecGDB:

#gdbsimple_prog(gdb)list(gdb)disassemblemain

  Avecobjdump

#objdump–Mintel–Dsimple_prog

14

Page 15: Dans les entrailles du langage C

BACKTOTHEBASICS

Notreprogrammeenlangageassembleur(Linux2.6.40.3‐0.fc15.i686)

SyntaxeAT&T:0x080483b4<+0>: push%ebp0x080483b5<+1>: mov%esp,%ebp0x080483b7<+3>: and$0xfffffff0,%esp0x080483ba<+6>: sub$0x20,%esp0x080483bd<+9>: movl$0x0,0x1c(%esp)0x080483c5<+17>: jmp0x80483d8<main+36>0x080483c7<+19>: movl$0x80484d0,(%esp)0x080483ce<+26>: call0x80482f0<puts@plt>0x080483d3<+31>: addl$0x1,0x1c(%esp)0x080483d8<+36>: cmpl$0x9,0x1c(%esp)0x080483dd<+41>: jle0x80483c7<main+19>...

15

Page 16: Dans les entrailles du langage C

BACKTOTHEBASICS

Notreprogrammeenlangageassembleur(Linux2.6.40.3‐0.fc15.i686)

SyntaxeAT&T:0x080483b4<+0>: push%ebp0x080483b5<+1>: mov%esp,%ebp0x080483b7<+3>: and$0xfffffff0,%esp0x080483ba<+6>: sub$0x20,%esp0x080483bd<+9>: movl$0x0,0x1c(%esp)0x080483c5<+17>: jmp0x80483d8<main+36>0x080483c7<+19>: movl$0x80484d0,(%esp)0x080483ce<+26>: call0x80482f0<puts@plt>0x080483d3<+31>: addl$0x1,0x1c(%esp)0x080483d8<+36>: cmpl$0x9,0x1c(%esp)0x080483dd<+41>: jle0x80483c7<main+19>...

16

Page 17: Dans les entrailles du langage C

BACKTOTHEBASICS

Lesregistresdel'architecturex86

17

  (gdb)inforegistersEAX–AccumulatorregisterECX–CounterregisterEDX–DataregisterEBX–Baseregister

Engénéral,ilsstockenttemporairementdesvariablespourleCPU.

ESP–StackPointerEBP–BasePointerESI–SourceIndexEDI–Des7na7onIndexEIP–Instruc7onPointer

Enregistredesadresses32‐bitsPointeursu7lisésquanddesdonnéesdoiventêtreluesouécritesàunemplacementdonné.Pointeàl'instruc7oncourante(queleprocesseurestentraindelire)

Page 18: Dans les entrailles du langage C

BACKTOTHEBASICS

Notreprogrammeenlangageassembleur(Linux2.6.40.3‐0.fc15.i686)

18

Page 19: Dans les entrailles du langage C

BACKTOTHEBASICS

Notreprogrammeenlangageassembleur(Linux2.6.40.3‐0.fc15.i686)

SyntaxeAT&T:0x080483b4<+0>: push%ebp0x080483b5<+1>: mov%esp,%ebp0x080483b7<+3>: and$0xfffffff0,%esp0x080483ba<+6>: sub$0x20,%esp0x080483bd<+9>: movl$0x0,0x1c(%esp)0x080483c5<+17>: jmp0x80483d8<main+36>0x080483c7<+19>: movl$0x80484d0,(%esp)0x080483ce<+26>: call0x80482f0<puts@plt>  Syntaxe:opera#on<source>,<des+na+on>

mov%esp,%ebpcopielecontenudeesp(source)dansebp(des0na0on)

19

Page 20: Dans les entrailles du langage C

BACKTOTHEBASICS

Notreprogrammeenlangageassembleur(Linux2.6.40.3‐0.fc15.i686)

SyntaxeIntel: plusclaireàdéchiffrerdansunpremiertemps0x080483b4<+0>: pushebp0x080483b5<+1>: movebp,esp0x080483b7<+3>: andesp,0xfffffff00x080483ba<+6>: subesp,0x200x080483bd<+9>: movDWORDPTR[esp+0x1c],0x00x080483c5<+17>: jmp0x80483d8<main+36>0x080483c7<+19>: movDWORDPTR[esp],0x80484d00x080483ce<+26>: call0x80482f0<puts@plt>  Syntaxe:opera#on<des+na+on>,<source>

movebp,espcopielecontenudeesp(source)dansebp(des0na0on)

20

Page 21: Dans les entrailles du langage C

BACKTOTHEBASICS

ConfigurerGDBpouru#liserlasyntaxeIntel

  Achaquelancement:$gdb(gdb)setdisassembly‐flavorintel  Dans.gdbinit:$echo"setdisassembly‐flavorintel">~/.gdbinit

21

Page 22: Dans les entrailles du langage C

BACKTOTHEBASICS

Décomposonsunpe#tpeutoutça...(codeLinux)

(gdb) disass main Dump of assembler code for function main: 0x080483b4 <+0>: push ebp 0x080483b5 <+1>: mov ebp,esp 0x080483b7 <+3>: and esp,0xfffffff0 0x080483ba <+6>: sub esp,0x20 0x080483bd <+9>: mov DWORD PTR [esp+0x1c],0x0 0x080483c5 <+17>: jmp 0x80483d8 <main+36>

Onsauvelesinfos!

  Onsauvel'adressepointéeespdansebp.

  Ilfautsavoiroùrevenirunefoisfinileprogramme!

Enimage...

22

ebp

esp

Page 23: Dans les entrailles du langage C

BACKTOTHEBASICS

Décomposonsunpe#tpeutoutça...

(gdb) disass main Dump of assembler code for function main: 0x080483b4 <+0>: push ebp 0x080483b5 <+1>: mov ebp,esp 0x080483b7 <+3>: and esp,0xfffffff0 0x080483ba <+6>: sub esp,0x20 0x080483bd <+9>: mov DWORD PTR [esp+0x1c],0x0 0x080483c5 <+17>: jmp 0x80483d8 <main+36>

Alloca#ondemémoire

  Onsoustraire0x20àesp,etonenregistrelavaleurdansesp

  Onmetlavaleuresp+0x1cà0:déclara7ondelavariablei

  Onsauteàl'instruc7on<main+36>23+

+0x1ci

esp

Page 24: Dans les entrailles du langage C

BACKTOTHEBASICS

Décomposonsunpe#tpeutoutça...

0x080483bd <+9>: mov DWORD PTR [esp+0x1c],0x0 0x080483c5 <+17>: jmp 0x80483d8 <main+36> 0x080483c7 <+19>: mov DWORD PTR [esp],0x80484d0 0x080483ce <+26>: call 0x80482f0 <puts@plt> 0x080483d3 <+31>: add DWORD PTR [esp+0x1c],0x1 0x080483d8 <+36>: cmp DWORD PTR [esp+0x1c],0x9 0x080483dd <+41>: jle 0x80483c7 <main+19> 0x080483df <+43>: mov eax,0x0 0x080483e4 <+48>: leave

Labouclefor

  Comparaisondanslabouclefor

24

Page 25: Dans les entrailles du langage C

BACKTOTHEBASICS

Décomposonsunpe#tpeutoutça...

0x080483bd <+9>: mov DWORD PTR [esp+0x1c],0x0 0x080483c5 <+17>: jmp 0x80483d8 <main+36> 0x080483c7 <+19>: mov DWORD PTR [esp],0x80484d0 0x080483ce <+26>: call 0x80482f0 <puts@plt> 0x080483d3 <+31>: add DWORD PTR [esp+0x1c],0x1 0x080483d8 <+36>: cmp DWORD PTR [esp+0x1c],0x9 0x080483dd <+41>: jle 0x80483c7 <main+19> 0x080483df <+43>: mov eax,0x0 0x080483e4 <+48>: leave

Exécu#ondelabouclefor

  Appeldelafonc7onprin�()  Onincrémenteipourleprochain

tour.

25

Page 26: Dans les entrailles du langage C

BACKTOTHEBASICS

Décomposonsunpe#tpeutoutça...

0x080483c7 <+19>: mov DWORD PTR [esp],0x80484d0 0x080483ce <+26>: call 0x80482f0 <puts@plt> 0x080483d3 <+31>: add DWORD PTR [esp+0x1c],0x1 0x080483d8 <+36>: cmp DWORD PTR [esp+0x1c],0x9 0x080483dd <+41>: jle 0x80483c7 <main+19> 0x080483df <+43>: mov eax,0x0 0x080483e4 <+48>: leave 0x080483e5 <+49>: ret

Sor#eduprogramme

  leave:movesp,ebp  ret:"returnfromprocedure",à

uneadresseindiquéeenhautdelapile

26

Page 27: Dans les entrailles du langage C

GDBTIME!

Onvasuivreledéroulementpasàpasdesimple_prog  But:comprendrelerôledecertainsregistres

27

Page 28: Dans les entrailles du langage C

info

GDBTIME!

•  Listfonc+on:afficheleslignesdecodeduprogramme

•  breakn:poseunpointd'arrêtàlalignenouàlafonc7onn.•  run:exécuteleprogrammeenen7eroujusqu'auprochainbreak

•  step:exécutel'instruc7onsuivante(modepas‐à‐pas)nex#:exécutel'instruc7oncourante

•  inforouinforegister:affichel'étatdesregistresd'instruc7ons•  printexp:affichelavaleurdeexp•  infoaddrexp:affichel'addressedeexp

28

Page 29: Dans les entrailles du langage C

BACKTOTHEBASICS

Lacommandeexamine

  Intérêt:examinerl'étatdelamémoire  Syntaxedelacommande:x/formataddr

o  o:enoctalo  x:enhexadécimalo  u:unsigned(basedécimalstandard)o  t:enbinaire

29

Page 30: Dans les entrailles du langage C

BACKTOTHEBASICS

Suivrel'étatdelamémoiredeEIPavecx

  Le registre EIP (Instruc7on Pointer) con7ent les adresses mémoire qui

pointentverslesinstruc7onsduprogrammeencoursd'exécu7on.(gdb)ireip #raccourcipourinforegistereip(gdb)x/x$eip #$eipdésignel'adressecontenuedanseip  Onpeutafficherplusieurs"mots"(unmot=4octets):(gdb)x/2x$eip  L'op7onipermetd'afficherlamémoirecommeuneinstruc7ondelangage

assembleur:(gdb)x/i$eip

30

Page 31: Dans les entrailles du langage C

BACKTOTHEBASICS

Suivrel'étatdelamémoiredeEIPavecx

  Onpeutmodulerlatailledesunitésd'adressesaffichées(pardéfaut,un

mot):o  b:1octeto  h:2octets(undemi‐motouhalfwordoushort)o  w:1mot(word)o  g:8octets(giantword)

A/en7on!Unmotpeutaussidésigner2octets.UndoublewordouDWORDdésignealors4octets.(gdb)x/8xb$eip(gdb)x/8xw$eip

31

Page 32: Dans les entrailles du langage C

BACKTOTHEBASICS

Pe#tIndienouGrandIndien

(gdb)x/8xb$eip0x1fc3<main+13>:0xc70x450xf40x000x000x000x000xeb(gdb)x/xw$eip0x1fc3<main+13>:0x00f445c7   Sur les processeurs x86, les valeurs sont stockées en lible‐endian: les

octetsdepoidsfaiblesontstockésenpremier.(poidsfaible==depuissanceslespluspe7tesdanslabasedenota7on)/!\Surleréseau,c'estlecontraire:valeursstockéesenbig‐endian!

32

Page 33: Dans les entrailles du langage C

BACKTOTHEBASICS

Déclara#ondelavariablei

33

Page 34: Dans les entrailles du langage C

BACKTOTHEBASICS

ChaîneASCII

0x080483c7 <+19>: mov DWORD PTR [esp],0x80484d0 (gdb)x/8xb0x80484d0(gdb)x/6ub0x80484d0  TableASCII

34

Page 35: Dans les entrailles du langage C

BACKTOTHEBASICS

ChaîneASCII

35

Page 36: Dans les entrailles du langage C

BACKTOTHEBASICS

ChaîneASCII

0x080483c7 <+19>: mov DWORD PTR [esp],0x80484d0 (gdb)x/8xb0x80484d0(gdb)x/6ub0x80484d0  TableASCII

  DirectementavecGDB:

(gdb)x/6cb0x80484d0 #regardelacorrespondanceoctetparoctet(gdb)x/s0x80484d0 #affichedirectementlachaînedecaractères

36

Page 37: Dans les entrailles du langage C

BACKTOTHEBASICS

UnprogrammesimpleenC #include <stdio.h> int main(){

int i; for (i = 0; i < 10; i++){ printf("Hello world !\n"); } return 0;

} Lalibrairiestdio.h

StandartInput/Outputlibrary  /usr/include/stdio.hCon7entleprototypedelafonc7onprin�()

Accéderaucodedeprind()?

  Oùestlecodedeprin�()?  Commentyaccéder?

37

Page 38: Dans les entrailles du langage C

BACKTOTHEBASICS

Trouverlecodesourcedeprind()Lecodedeprin�()setrouvedansdespaquetsprécompilésdelalibc.  Ilfautallerregarderparexemplelessourcesdelaglibc.o  Téléchargerlessources:h/p://�p.gnu.org/gnu/glibc/o  $apt‐getsourceglibc‐devel

  Lecodedevientrapidementcomplexeetlong.

38

Page 39: Dans les entrailles du langage C

BACKTOTHEBASICS

Trouverlecodesourcedeprind()Lecodedeprin�()setrouvedansdespaquetsprécompilésdelalibc.  Ilfautallerregarderparexemplelessourcesdelaglibc.o  Téléchargerlessources:h/p://�p.gnu.org/gnu/glibc/o  $apt‐getsourceglibc‐devel

Lecodedevientrapidementcomplexeetlong.

  Unealterna7veestderegarderdanslecodedeladietlibc.o  h/p://dietlibc.sourcearchive.com/

39

Page 40: Dans les entrailles du langage C

BACKTOTHEBASICS

RetoursurquelquescommandesassembleurLejeud'instruc7onassembleurpourx86aévoluéavecletempsetlesarchitectures.Instruc7onsini7alespourles8086/8088:unecentained'instruc7on.not and or xor neg push pop mov jmp cmp jle add sub mul inc dec lea

40

Page 41: Dans les entrailles du langage C

CONCEPTSDECATRAVERSLESCOPEDUDEBOGGUEUR

41

Page 42: Dans les entrailles du langage C

info

CODINGTIME–Chaînesdecaractères

Ecrireunprogrammequicrééunechaînedecaractèreetquil'imprimeàl'écran.

  Ce/echaînedevraêtreconstruitecaractèreparcaractère.

PuisavecGDB,désassemblezlecode.

42

Page 43: Dans les entrailles du langage C

info

CODINGTIME–Chaînesdecaractères

Ecrireunprogrammequicrééunechaînedecaractèreetquil'imprimeàl'écran.

  Ce/echaînedevraêtreconstruitecaractèreparcaractère.

PuisavecGDB,désassemblezlecode.  Fairedemêmeenu7lisantstrcpy().

43

Page 44: Dans les entrailles du langage C

CONCEPTSDECATRAVERSLESCO

PEDUDEBOGGU

EUR

Taillesdecertainstypesdevariables  Signedint:en7ersposi7fsetnéga7fs  Unsignedint:seulementdesen7ersposi7fs

Surunprocesseurx86_32bits,ilya2^32combinaisonspossiblespourununsignedint(4294967295possibilités).Pourunsignedint:entre‐2147483648à2147483647.  Latailled'untypedépenddutyped'architecture.

44

Page 45: Dans les entrailles du langage C

CONCEPTSDECATRAVERSLESCO

PEDUDEBOGGU

EUR

Lespointeurs

  EIP,l'Instruc7onPointer,estunpointeurquipointeversl'instruc7onen

courscarilcon7entsonadressemémoire.

  Onnepeutpasbouger"réellement"desadressesdemémoiresphysiques.

Ondoitdonccopierl'informa7onstockéeàcetemplacementmémoire.C'estcoûteux:groschunksdemémoireàallouer/copier.

45

data

data

data

Page 46: Dans les entrailles du langage C

CONCEPTSDECATRAVERSLESCO

PEDUDEBOGGU

EUR

Lespointeurs

Lasolu7on:lespointeurs.  Aulieudecopierdesgrosmorceauxdemémoire,onu7lisel'adressedu

débutdublocdemémoireenques7on.

46

datadata

PointeurversaddrDébut

addrDébut addrDébut

Page 47: Dans les entrailles du langage C

CONCEPTSDECATRAVERSLESCO

PEDUDEBOGGU

EUR

Lespointeurs

Unpointeurestdéfinicommequelquechosequipointeversunedonnéed'uncertaintype:int*ptr; #ptrpointeversunedonnéedetypeint.

47

Page 48: Dans les entrailles du langage C

CONCEPTSDECATRAVERSLESCO

PEDUDEBOGGU

EUR

Lespointeurs

Unpointeurestdéfinicommequelquechosequipointeversunedonnéed'uncertaintype:int*ptr; #ptrpointeversunedonnéedetypeint.Commentvoirlesdonnéesquisontenregistréesdanslepointeurlui‐même?  opérateur&(gdb)printpointer #printlavaleurdupointeur(uneadresse)(gdb)print&pointer #printl'adressedupointeur  déréférencement*(gdb)print*pointer #printlavaleurdesdonnéesprésentes

àl'adressecontenuedanslepointeur.

48

Page 49: Dans les entrailles du langage C

CONCEPTSDECATRAVERSLESCO

PEDUDEBOGGU

EUR

Typecas#ng

Typecas7ng:changementtemporairedutyped'unevariable,quelquesoitletypeaveclequelaétédéfinice/evariable.Syntaxe:(typecast_data_type)variable

49

Page 50: Dans les entrailles du langage C

CODINGTIME!

EcrireenCunprogrammequi:  Définit2tableauxde5chiffreset5le/res;  Affichelecontenudesdeuxtableaux(ondéfiniraunpointeur

pourafficherlecontenudansunebouclefor).

50

Page 51: Dans les entrailles du langage C

GDBTIME!

Afficherl'adressedupremierélémentdechacundestableaux.Devinerlesadressesdesélémentssuivants?VérifierlerésultatavecGDB.

51

Page 52: Dans les entrailles du langage C

CONCEPTSDECATRAVERSLESCO

PEDUDEBOGGU

EUR

Lestypesaveclespointeurs

  Leformat%destéquivalentà0x%08xpourafficherdesadressesmémoire.(doncpra7quepourafficherlesvaleursdepointeurs)On va jouer un peu avec les types de pointeurs: exécuter le programmepointer_types2.cCorrigerleprogramme!

52

Page 53: Dans les entrailles du langage C

CONCEPTSDECATRAVERSLESCO

PEDUDEBOGGU

EUR

Lestypesaveclespointeurs

  Leformat%destéquivalentà0x%08xpourafficherdesadressesmémoire.(doncpra7quepourafficherlesvaleursdepointeurs)On va jouer un peu avec les types de pointeurs: exécuter le programmepointer_types2.cCorrigerleprogramme!2autresexmplesavecpointer_types4.cetpointer_types5.c

53

Page 54: Dans les entrailles du langage C

CONCEPTSDECATRAVERSLESCO

PEDUDEBOGGU

EUR

Passezdesargumentsenlignedecommande

  Leformat%destéquivalentà0x%08xpourafficherdesadressesmémoire.(doncpra7quepourafficherlesvaleursdepointeurs)On va jouer un peu avec les types de pointeurs: exécuter le programmepointer_types2.cCorrigerleprogramme!2autresexmplesavecpointer_types4.cetpointer_types5.c

54

Page 55: Dans les entrailles du langage C

info

GDBTIME!

Onacrééunprogrammebuggué:debug.c  Butdujeu:trouveroùestlebugavecGDBetuniquementavec

GDB.NEPASUTILISERLIST!Onnedoitpasvoirlecodedu

programme!

55

Page 56: Dans les entrailles du langage C

info

GDBTIME!

•  displayexp:équivautàunprintexpeffectuéchaquefoisqueleprogrammestoppe.

•  deletedisplaydnums:annulel'affichagedesvariablesdenumérodnums.

•  showvaluesn:afficherlesndernièresvaleursaffichées

•  wha#sexp:donneletyped'unevariable•  infoaddressexp:donnel'adressedeexp

56

Page 57: Dans les entrailles du langage C

MEMORYSEGMENTATION

57

Page 58: Dans les entrailles du langage C

BACKTOTHEBASICS

Notreprogrammeenlangageassembleur(DarwinKernelVersion9.8.0)

SyntaxeAT&T:0x00001�6<main+0>: push%ebp0x00001�7<main+1>: mov%esp,%ebp0x00001�9<main+3>: push%ebx0x00001�a<main+4>: sub$0x24,%esp0x00001�d<main+7>: call0x1fc2<main+12>0x00001fc2<main+12>: pop%ebx0x00001fc3<main+13>: movl$0x0,‐0xc(%ebp)0x00001fca<main+20>: jmp0x1fdf<main+41>0x00001fcc<main+22>: lea0x2e(%ebx),%eax0x00001fd2<main+28>: mov%eax,(%esp)0x00001fd5<main+31>: call0x3005<dyld_stub_puts>...

58

Page 59: Dans les entrailles du langage C

BACKTOTHEBASICS

Avecuncompilateur/processeurdifférent:

(gdb) disass main Dump of assembler code for function main: 0x00001fb6 <main+0>: push %ebp 0x00001fb7 <main+1>: mov %esp,%ebp 0x00001fb9 <main+3>: push %ebx 0x00001fba <main+4>: sub $0x24,%esp 0x00001fbd <main+7>: call 0x1fc2 <main+12> 0x00001fc2 <main+12>: pop %ebx 0x00001fc3 <main+13>: movl $0x0,-0xc(%ebp) Onsauvelesinfos!

  Onsauvel'adressepointéeparebpdanslastack.

  Ilfautsavoiroùrevenirunefoisfinileprogramme!

Enimage...

59

ebp

esp

ebx

ebp

esp

Page 60: Dans les entrailles du langage C

BACKTOTHEBASICS

Décomposonsunpe#tpeutoutça...

(gdb) disass main Dump of assembler code for function main: 0x00001fb6 <main+0>: push %ebp 0x00001fb7 <main+1>: mov %esp,%ebp 0x00001fb9 <main+3>: push %ebx 0x00001fba <main+4>: sub $0x24,%esp 0x00001fbd <main+7>: call 0x1fc2 <main+12> 0x00001fc2 <main+12>: pop %ebx 0x00001fc3 <main+13>: movl $0x0,-0xc(%ebp) Alloca#ondemémoire

  Onallouedelamémoire  Onappellel'instruc7on<main+12>  Onpopebx.

Remarques

60

  Ici,onfaitintervenirunregistreebx.Apriori,difficiledevoiràquoicelasert.

  $exp:valeurexp  %reg:adresseduregistrereg

Page 61: Dans les entrailles du langage C

BACKTOTHEBASICS

Décomposonsunpe#tpeutoutça...

0x00001fc3 <main+13>: movl $0x0,-0xc(%ebp) 0x00001fca <main+20>: jmp 0x1fdf <main+41> 0x00001fcc <main+22>: lea 0x2e(%ebx),%eax 0x00001fd2 <main+28>: mov %eax,(%esp) 0x00001fd5 <main+31>: call 0x3005 <dyld_stub_puts> 0x00001fda <main+36>: lea -0xc(%ebp),%eax 0x00001fdd <main+39>: incl (%eax) 0x00001fdf <main+41>: cmpl $0x9,-0xc(%ebp) 0x00001fe3 <main+45>: jle 0x1fcc <main+22>

Déclara#ondelavariablei

  Onmet4octetsà0,12casesmémoireaudessusdeebp

Ques#on!

Qu'est‐ceque‐0xc(%ebp)?

61

Page 62: Dans les entrailles du langage C

BACKTOTHEBASICS

Décomposonsunpe#tpeutoutça...

0x00001fc3 <main+13>: movl $0x0,-0xc(%ebp) 0x00001fca <main+20>: jmp 0x1fdf <main+41> 0x00001fcc <main+22>: lea 0x2e(%ebx),%eax 0x00001fd2 <main+28>: mov %eax,(%esp) 0x00001fd5 <main+31>: call 0x3005 <dyld_stub_puts> 0x00001fda <main+36>: lea -0xc(%ebp),%eax 0x00001fdd <main+39>: incl (%eax) 0x00001fdf <main+41>: cmpl $0x9,-0xc(%ebp) 0x00001fe3 <main+45>: jle 0x1fcc <main+22>

Labouclefor

  Comparaisondanslabouclefor

Remarque

62

Onu7liseeaxouebpaulieudustackpointer.

Page 63: Dans les entrailles du langage C

BACKTOTHEBASICS

Décomposonsunpe#tpeutoutça...

0x00001fc3 <main+13>: movl $0x0,-0xc(%ebp) 0x00001fca <main+20>: jmp 0x1fdf <main+41> 0x00001fcc <main+22>: lea 0x2e(%ebx),%eax 0x00001fd2 <main+28>: mov %eax,(%esp) 0x00001fd5 <main+31>: call 0x3005 <dyld_stub_puts> 0x00001fda <main+36>: lea -0xc(%ebp),%eax 0x00001fdd <main+39>: incl (%eax) 0x00001fdf <main+41>: cmpl $0x9,-0xc(%ebp) 0x00001fe3 <main+45>: jle 0x1fcc <main+22>

Exécu#ondelabouclefor

  String"helloworld!\n"contenueàl'adresse0x2e(%ebx)

  Appeldelafonc7onprin�()  Onincrémenteipourleprochain

tour.

Remarque

63

Page 64: Dans les entrailles du langage C

BACKTOTHEBASICS

Décomposonsunpe#tpeutoutça...

0x00001fe5 <main+47>: mov $0x0,%eax 0x00001fea <main+52>: add $0x24,%esp 0x00001fed <main+55>: pop %ebx 0x00001fee <main+56>: leave 0x00001fef <main+57>: ret

Finetsoriteduprogramme

Onreplacelestackpointeràsaposi7onini7ale.Onréini7aliseeaxà0.

Remarque

64