Graphe de dépendances

publicité
Graphe de dépendances
Petit Poucet style
M. Blanc, F. Desclaux, C. Leman, C. Mougey, A. Vincent
Direction des applications militaires
3 juin 2016
Problématique
Analyse de flot de données : data slicing
Problème initial : quelles sont les opérations du programme qui participent à la
valeur d’une variable donnée ?
Utilisation
Analyse de malware
Recherche de vulnérabilités
Analyse de code
Contexte
CEA/DAM | 3 juin 2016 | PAGE 2/55
Exemple simplifié
main
MOV
ECX, 0x1
MOV
EDX, 0x2
JMP
loop
Qui participe à la valeur finale d’EAX ?
loop
INC
EDI
MOV
EBX, ECX
MOV
ECX, EDX
CMP
EDI, 0x10
JNZ
loop
Ça s’appelle le slicing / backward data
tainting / whatever-ing…
…et ça commence à avoir 20 ans [Weiser,
père et fils]
end
MOV
EAX, EBX
RET
Contexte
CEA/DAM | 3 juin 2016 | PAGE 3/55
Exemple simplifié
main
A = 1
B = 2
JMP loop
Qui participe à la valeur finale de X ?
loop
COUNT++
C = A
A = B
COUNT == 10
JNZ loop
Ça s’appelle le slicing / backward data
tainting / whatever-ing…
…et ça commence à avoir 20 ans [Weiser,
père et fils]
end
X = C
RET
Contexte
CEA/DAM | 3 juin 2016 | PAGE 4/55
Slicing
Tel le petit poucet, nous allons devoir
retrouver notre chemin en déposant et en
retrouvant nos cailloux
Contexte
CEA/DAM | 3 juin 2016 | PAGE 5/55
Analyse manuelle sous IDA
Méthode du baroudeur de binaire
Expert
Sélection de la cible (slicing
criterion)
Remonter à la dernière
affectation
Surlignage en jaune
oui
Contexte
Peut-on
encore
scroller
↑?
non
Travail terminé
CEA/DAM | 3 juin 2016 | PAGE 6/55
Exemple : analyse de code
Retrouver la source de la taille d’un memcpy
Fonction 0x401691, recherche des sources de EDI depuis 0x4016F6
Contexte
CEA/DAM | 3 juin 2016 | PAGE 7/55
Analyse manuelle
Inconvénients
Passage à l’échelle difficile
Sujet à l’erreur
Chronophage
Contexte
CEA/DAM | 3 juin 2016 | PAGE 8/55
Plan
Limitations
Demo
État
de
l’art
Contexte
Algorithme
CEA/DAM | 3 juin 2016 | PAGE 9/55
Angr
Angr : angr.io
“Framework for analyzing binaries”
Loader de binaire (ELF, PE)
Multi architecture (ARM / AArch64, x86 32/64, Mips 32/64, PPC 32/64)
Moteur d’exécution symbolique
Méthodes d’analyse statique
Use-define
CEA/DAM | 3 juin 2016 | PAGE 10/55
Use-define chains
Use-define chains
“BackwardSlice”
Statique, sans distinction de chemin d’exécution
Efficace (de l’ordre de O(n + e))
project = angr.Project(filename,
load_options={’auto_load_libs’:False})
cfg = project.analyses.CFG(context_sensitivity_level=2, keep_state=True)
cdg = project.analyses.CDG(cfg)
ddg = project.analyses.DDG(cfg)
target_node = cfg.get_any_node(addr)
bs = project.analyses.BackwardSlice(cfg, cdg=cdg, ddg=ddg,
targets=[(target_node, statement)])
Use-define
CEA/DAM | 3 juin 2016 | PAGE 11/55
Use-define chains : Graphe de dépendances
main
A = 1
B = 2
JMP loop
loop
COUNT++
C = A
X
A = B
COUNT == 10
JNZ loop
end
X = C
RET
Use-define
CEA/DAM | 3 juin 2016 | PAGE 12/55
Use-define chains : Graphe de dépendances
main
A = 1
B = 2
JMP loop
loop
COUNT++
Xend
C = A
A = B
COUNT == 10
define
X
JNZ loop
end
X = C
RET
Use-define
CEA/DAM | 3 juin 2016 | PAGE 12/55
Use-define chains : Graphe de dépendances
main
A = 1
B = 2
JMP loop
loop
COUNT++
C = A
C
use
Xend
A = B
COUNT == 10
JNZ loop
define
X
end
X = C
RET
Use-define
CEA/DAM | 3 juin 2016 | PAGE 12/55
Use-define chains : Graphe de dépendances
main
A = 1
B = 2
JMP loop
Cloop
define
loop
COUNT++
C = A
A = B
COUNT == 10
C
use
Xend
define
JNZ loop
X
end
X = C
RET
Use-define
CEA/DAM | 3 juin 2016 | PAGE 12/55
Use-define chains : Graphe de dépendances
main
A = 1
B = 2
JMP loop
A
use
loop
Cloop
define
COUNT++
C = A
A = B
COUNT == 10
JNZ loop
C
use
Xend
define
X
end
X = C
RET
Use-define
CEA/DAM | 3 juin 2016 | PAGE 12/55
Use-define chains : Graphe de dépendances
main
A = 1
B = 2
JMP loop
Aloop
Amain
define
define
A
loop
COUNT++
use
Cloop
C = A
A = B
COUNT == 10
JNZ loop
define
C
use
Xend
define
end
X = C
X
RET
Use-define
CEA/DAM | 3 juin 2016 | PAGE 12/55
Use-define chains : Graphe de dépendances
main
1
A = 1
use
B = 2
JMP loop
Aloop
Amain
define
loop
define
A
use
COUNT++
C = A
Cloop
A = B
COUNT == 10
JNZ loop
define
C
use
Xend
end
define
X = C
RET
Use-define
X
CEA/DAM | 3 juin 2016 | PAGE 12/55
Use-define chains : Graphe de dépendances
main
1
A = 1
B = 2
JMP loop
B
use
use
Aloop
Amain
define
loop
define
A
use
COUNT++
C = A
Cloop
A = B
COUNT == 10
JNZ loop
define
C
use
Xend
end
define
X = C
RET
Use-define
X
CEA/DAM | 3 juin 2016 | PAGE 12/55
Use-define chains : Graphe de dépendances
Bmain
main
define
A = 1
1
B = 2
B
use
use
JMP loop
Aloop
Amain
loop
COUNT++
define
define
A
use
C = A
A = B
COUNT == 10
Cloop
define
JNZ loop
C
use
end
X = C
Xend
define
RET
X
Use-define
CEA/DAM | 3 juin 2016 | PAGE 12/55
Use-define chains : Graphe de dépendances
2
use
main
Bmain
A = 1
define
B = 2
1
JMP loop
B
use
use
loop
COUNT++
C = A
Aloop
Amain
define
define
A
A = B
COUNT == 10
JNZ loop
use
Cloop
define
end
X = C
RET
C
use
Xend
define
X
Use-define
CEA/DAM | 3 juin 2016 | PAGE 12/55
Angr
Inconvénient : sur-ensemble des solutions
0x22
0x1
use
lbl2
lbl1
a = 0x22
a = 0x1
b = 0x23
b = 0x2
0x23
albl2
albl1
lbl3
use
blbl2
blbl1
definedefine
define
define
a
r = (a+b)
0x2
use
use
b
use
rlbl3
use
define
r
Use-define
CEA/DAM | 3 juin 2016 | PAGE 13/55
Angr
Inconvénient : sur-ensemble des solutions
0x22
0x1
use
1
a
2
a
: 0x1, b : 0x2
3
: 0x22, b : 0x23
a : 0x1, b : 0x23
4
a
: 0x22, b : 0x2
0x23
albl2
0x2
use
use
albl1
use
blbl2
blbl1
definedefine
define
define
a
b
use
rlbl3
use
define
r
Use-define
CEA/DAM | 3 juin 2016 | PAGE 13/55
Angr : Path-sensitive
Path-sensitive
Exécution symbolique
Branchement → contrainte
“PathGroup”
Magie noire pour les boucles
state = project.factory.blank_state(addr=0x401000)
# Activating veritesting results in a crash
path_group = project.factory.path_group(state, veritesting=False)
path_group = path_group.explore(find=(addr,))
# Display results
founds = path_group.found
for i, found in enumerate(founds):
print i, found.state.regs.eax
Path-sensitive
CEA/DAM | 3 juin 2016 | PAGE 14/55
Angr Path-sensitive
main
A = 1
B = 2
JMP loop
loop
$ python angr_pathgroup.py
COUNT++
C = A
A = B
COUNT == 10
- COUNT = 9
- C = 1
JNZ loop
end
X = C
RET
Path-sensitive
CEA/DAM | 3 juin 2016 | PAGE 15/55
Path-sensitive
Cas d’utilisations
Recherche de vulnérabilités, crackme, …
Participation au “Cyber Grand Challenge” (équipe Shellphish)
Inconvénients
Nécessité d’une heuristique …
…quitte à oublier des solutions
- COUNT != 9
- C = 2
Très lourd
Quid des boucles inutiles ?
Path-sensitive
CEA/DAM | 3 juin 2016 | PAGE 16/55
Trouver un compromis
Marchand de cailloux
Solutions sur étagère disponibles :
Contenant trop peu d’information (sac de sable)
Trop lourde à utiliser (sac de menhirs)
Caractéristiques désirées
Plus précis que l’algorithme des use-define chains
Mais sans avoir peur des boucles
Path-sensitive
CEA/DAM | 3 juin 2016 | PAGE 17/55
Trouver un compromis
Marchand de cailloux
Solutions sur étagère disponibles :
Contenant trop peu d’information (sac de sable)
Trop lourde à utiliser (sac de menhirs)
Caractéristiques désirées
Plus précis que l’algorithme des use-define chains
Mais sans avoir peur des boucles
Path-sensitive
CEA/DAM | 3 juin 2016 | PAGE 17/55
Metasm : BackTracking
Metasm : metasm.cr0.org
“Cross-architecture assembler, disassembler, compiler, linker and debugger”
Loader (PE, ELF, Mach-O)
Multi-architecture (arc, arm, arm64, …, st20, x86 64, z80)
BackTracking
Méthode : un seul passage dans chaque boucle
pe = PE.decode_file(filename)
dasm = pe.disassemble_fast_deep ’entrypoint’
reg = reg.to_sym
# Run backtrace
log = []
dasm.debug_backtrace = 1
ret = dasm.backtrace(reg, offset, :log => log)
Ruby style
CEA/DAM | 3 juin 2016 | PAGE 18/55
Metasm
Metasm
“use-define chains”
“path-sensitive”
Analyse très rapide
Trouve la solution X = 1
Indique qu’il a potentiellement manqué des solutions
Raffinement de la solution
On pense pouvoir obtenir mieux pour pas beaucoup plus cher.
Ruby style
CEA/DAM | 3 juin 2016 | PAGE 19/55
I have a dream
Avantages de l’algorithme présenté (vue du commercial)
Distinguer les chemins d’exécutions
Éviter les chemins “équivalents en dépendance”
Dérouler les boucles seulement le nombre de fois nécessaire
→ un sac de pocket-cailloux !
Algorithme
CEA/DAM | 3 juin 2016 | PAGE 20/55
Algorithme
Étapes
Algorithme
1
L’algorithme suit les dépendances dans le basic block courant
2
On poursuit l’analyse dans chaque bloc parent
3
Sauf ceux qu’on a déjà parcouru avec des dépendances identiques
4
L’algorithme s’arrête si on atteint la racine du graphe, ou que toutes les
dépendances sont résolues.
CEA/DAM | 3 juin 2016 | PAGE 21/55
Algorithme
Étapes
L’algorithme suit les dépendances dans le basic block courant
main
A = 1
B = 2
JMP loop
loop
COUNT++
C = A
X dépend de C
A = B
COUNT == 10
JNZ loop
end
X = C
RET
Algorithme
CEA/DAM | 3 juin 2016 | PAGE 22/55
Algorithme
Étapes
On poursuit l’analyse dans chaque bloc parent
main
A = 1
B = 2
JMP loop
loop
COUNT++
C = A
De qui dépend C dans loop ?
A = B
COUNT == 10
JNZ loop
end
X = C
RET
Algorithme
CEA/DAM | 3 juin 2016 | PAGE 23/55
Algorithme
Étapes
L’algorithme suit les dépendances dans le basic block courant
main
A = 1
B = 2
JMP loop
loop
COUNT++
C = A
C dépend de A
A = B
COUNT == 10
JNZ loop
end
X = C
RET
Algorithme
CEA/DAM | 3 juin 2016 | PAGE 24/55
Algorithme
Étapes
On poursuit l’analyse dans chaque bloc parent
main
A = 1
B = 2
JMP loop
loop
COUNT++
C = A
De qui dépend A dans main ?
A = B
COUNT == 10
JNZ loop
end
X = C
RET
Algorithme
CEA/DAM | 3 juin 2016 | PAGE 25/55
Algorithme
Étapes
L’algorithme suit les dépendances dans le basic block courant
main
A = 1
B = 2
JMP loop
loop
COUNT++
C = A
A dépend de la constante 1
A = B
COUNT == 10
JNZ loop
end
X = C
RET
Algorithme
CEA/DAM | 3 juin 2016 | PAGE 26/55
Algorithme
Étapes
L’algorithme s’arrête si toutes les dépendances sont résolues.
main
A = 1
B = 2
JMP loop
Solution 1 :
loop
COUNT++
2
← Cdebut end
Cfin loop ← Adebut loop
3
Afin main
1
C = A
A = B
COUNT == 10
JNZ loop
Xfin end
←1
end
X = C
RET
Algorithme
CEA/DAM | 3 juin 2016 | PAGE 27/55
Algorithme
Étapes
On poursuit l’analyse dans chaque bloc parent
main
A = 1
B = 2
JMP loop
loop
COUNT++
C = A
De qui dépend A dans loop ?
A = B
COUNT == 10
JNZ loop
end
X = C
RET
Algorithme
CEA/DAM | 3 juin 2016 | PAGE 28/55
Algorithme
Étapes
L’algorithme suit les dépendances dans le basic block courant
main
A = 1
B = 2
JMP loop
loop
COUNT++
C = A
A dépend de B
A = B
COUNT == 10
JNZ loop
end
X = C
RET
Algorithme
CEA/DAM | 3 juin 2016 | PAGE 29/55
Algorithme
Étapes
On poursuit l’analyse dans chaque bloc parent
main
A = 1
B = 2
JMP loop
loop
COUNT++
C = A
De qui dépend B dans main ?
A = B
COUNT == 10
JNZ loop
end
X = C
RET
Algorithme
CEA/DAM | 3 juin 2016 | PAGE 30/55
Algorithme
Étapes
L’algorithme suit les dépendances dans le basic block courant
main
A = 1
B = 2
JMP loop
loop
COUNT++
C = A
B dépend de la constante 2
A = B
COUNT == 10
JNZ loop
end
X = C
RET
Algorithme
CEA/DAM | 3 juin 2016 | PAGE 31/55
Algorithme
Étapes
L’algorithme s’arrête si toutes les dépendances sont résolues.
main
A = 1
B = 2
JMP loop
Solution 2 :
loop
2
← Cdebut end
Cfin loop ← Adebut loop
3
Afin loop
4
Bfin main
1
COUNT++
C = A
A = B
COUNT == 10
JNZ loop
Xfin end
← Bdebut loop
←2
end
X = C
RET
Algorithme
CEA/DAM | 3 juin 2016 | PAGE 32/55
Algorithme
Étapes
On poursuit l’analyse dans chaque bloc parent
main
A = 1
B = 2
JMP loop
loop
COUNT++
C = A
De qui dépend B dans loop ?
A = B
COUNT == 10
JNZ loop
end
X = C
RET
Algorithme
CEA/DAM | 3 juin 2016 | PAGE 33/55
Algorithme
Étapes
L’algorithme suit les dépendances dans le basic block courant
main
A = 1
B = 2
JMP loop
loop
COUNT++
C = A
B n’est pas modifié
A = B
COUNT == 10
JNZ loop
end
X = C
RET
Algorithme
CEA/DAM | 3 juin 2016 | PAGE 34/55
Algorithme
Étapes
Sauf les parents qu’on a déjà parcourus avec des dépendances identiques
main
A = 1
B = 2
JMP loop
loop
COUNT++
C = A
On arrête cette branche de recherche
A = B
COUNT == 10
JNZ loop
end
X = C
RET
Algorithme
CEA/DAM | 3 juin 2016 | PAGE 35/55
Algorithme
Étapes
Sauf les parents qu’on a déjà parcourus avec des dépendances identiques
main
A = 1
B = 2
JMP loop
loop
COUNT++
C = A
On arrête cette branche de recherche
A = B
COUNT == 10
JNZ loop
end
X = C
RET
Algorithme
CEA/DAM | 3 juin 2016 | PAGE 36/55
Algorithme
Étapes
L’algorithme s’arrête si on atteint la racine du graphe, ou que toutes les
dépendances sont résolues.
Fin de l’algorithme
Il n’y a plus de dépendances à résoudre. Deux solutions ont été trouvées :
X = 1 avec un seul passage dans loop
X = 2 avec plus d’un passage dans loop
Algorithme
CEA/DAM | 3 juin 2016 | PAGE 37/55
Résultat
lbl0
c = 0x1
lbl1
b = c
Solution
1 a ← blbl2
2
blbl2
3
clbl1
← clbl1
← 0x1lbl0
lbl2
a = b
Exemples
CEA/DAM | 3 juin 2016 | PAGE 38/55
Résultat
lbl0
c = 0x1
lbl1
b = 0x2
Solution
1 a ← blbl2 , clbl2
2
blbl2
3
clbl2
← 0x2lbl1
← 0x1lbl0
lbl2
a = (b+c)
Exemples
CEA/DAM | 3 juin 2016 | PAGE 39/55
Résultat
lbl0
c = 0x1
lbl2
lbl1
b = 0x3
b = 0x2
Solutions
1 a ← blbl3 , clbl3
2
blbl3
3
clbl3
← 0x2lbl1
← 0x1lbl0
1
2
3
← blbl3 , clbl3
blbl3 ← 0x3lbl2
clbl3 ← 0x1lbl0
a
lbl3
a = (b+c)
Exemples
CEA/DAM | 3 juin 2016 | PAGE 40/55
Résultat
lbl0
c = 0x1
lbl1
c = (c+0x2)
pc = c?(lbl2,lbl1)
Solution
1 a ← blbl2
2
blbl2
← bhead
lbl2
a = b
Exemples
CEA/DAM | 3 juin 2016 | PAGE 41/55
Résultat
lbl0
b = 0x1
Solutions
lbl1
b = (b+0x2)
pc = b?(lbl2,lbl1)
1
2
3
lbl2
← blbl2
blbl2 ← blbl1
blbl1 ← 0x1lbl0
← blbl2
1
a
2
blbl2
3
blbl1
4
blbl1
a
← blbl1
← blbl1
← 0x1lbl0
a = b
Exemples
CEA/DAM | 3 juin 2016 | PAGE 42/55
Partie formelle
Terminaison de l’algorithme
Voir les actes. Spoiler : il termine
Complexité
La complexité s’obtient directement en connaissant le nombre de solutions …
qui s’obtient en travaillant sur un “algorithme adapté” …
qui se base sur un “CFG adapté” …
qui est détaillé dans les actes
→ 2|V|
2
+|X|
+ |V|.2|V|
2
Majorant du nombre de solution
16 blocs : nombre d’atomes dans l’univers
32 blocs : personnel de l’ANSSI
Complexité
CEA/DAM | 3 juin 2016 | PAGE 43/55
Partie formelle
Terminaison de l’algorithme
Voir les actes. Spoiler : il termine
Complexité
La complexité s’obtient directement en connaissant le nombre de solutions …
qui s’obtient en travaillant sur un “algorithme adapté” …
qui se base sur un “CFG adapté” …
qui est détaillé dans les actes
→ 2|V|
2
+|X|
+ |V|.2|V|
2
Majorant du nombre de solution
16 blocs : nombre d’atomes dans l’univers
32 blocs : personnel de l’ANSSI
Complexité
CEA/DAM | 3 juin 2016 | PAGE 43/55
Partie formelle
Terminaison de l’algorithme
Voir les actes. Spoiler : il termine
Complexité
La complexité s’obtient directement en connaissant le nombre de solutions …
qui s’obtient en travaillant sur un “algorithme adapté” …
qui se base sur un “CFG adapté” …
qui est détaillé dans les actes
→ 2|V|
2
+|X|
+ |V|.2|V|
2
Majorant du nombre de solution
16 blocs : nombre d’atomes dans l’univers
32 blocs : personnel de l’ANSSI
Complexité
CEA/DAM | 3 juin 2016 | PAGE 43/55
Résultat : analyse du Memcpy
2 solutions:
Possible value: @32[@32[ESP_init+0x4]+0x10] - @32[ESP_init+0x8]
Possible value: @32[ESP_init+0xC]
Démo
CEA/DAM | 3 juin 2016 | PAGE 44/55
Résultat : analyse du duqu2
Recherche de la source des arguments
Fonction : 0x10003925
Sample :
52fe506928b0262f10de31e783af8540b6a0b232b15749d647847488acd0e17a
DISAMS
INFO : generating IR... 10003959
Function: 0x10003925L Reference: 0x10003959L
Solution: 0 has_loop: False Arguments
Function: 0x10003925L Reference: 0x10003968L
Solution: 0 has_loop: False Arguments
Function: 0x10003925L Reference: 0x1000397fL
Solution: 0 has_loop: False Arguments
Function: 0x10003925L Reference: 0x1000398eL
Solution: 0 has_loop: False Arguments
Function: 0x10003925L Reference: 0x1000399dL
...
Démo
values: [’0x10032324’, ’0xC9052BB8’]
values: [’0x10032324’, ’0xEAF3865C’]
values: [’0x10032324’, ’0xAF32FB74’]
values: [’0x10032324’, ’0xC9EE1C94’]
CEA/DAM | 3 juin 2016 | PAGE 45/55
Limitations : résolution des alias
mov @32[B], 0x6
mov @32[C], 0x18
mov A, @32[B]
Cas possibles
Les cases mémoire [B] et [C] sont disjointes, A
B et C ont la même valeur, A
= 0x6
= 0x18
Les cases mémoire se recouvrent partiellement, A aura une autre valeur
Limitations
CEA/DAM | 3 juin 2016 | PAGE 46/55
Limitations : pointeur de pile non résolu
Limitations
Langage natif
Langage intermédiaire
push
edx
ESP = ESP - 0x4
@32[ESP] = EDX
push
[ebp+arg_4]
ESP = ESP - 0x4
@32[ESP] = @32[EBP + 0xC]
call
0x10028BA2
ESP = ESP - 0x4
EIP = 0x10028BA2
@32[ESP] = 0x10028B84
IRDst = lbl_gen_00000000
CEA/DAM | 3 juin 2016 | PAGE 47/55
Limitations : pointeur de pile non résolu
Limitations
Langage natif
Langage modifié
push
edx
ESP = ESP_init - 0xC
@32[ESP_init - 0xC] = EDX
push
[ebp+arg_4]
ESP = ESP_init - 0x10
@32[ESP_init - 0x10] = @32[EBP + 0xC]
call
0x10028BA2
ESP = ESP_init - 0x14
EIP = 0x10028BA2
@32[ESP_init - 0x14] = 0x10028B84
IRDst = lbl_gen_00000000
CEA/DAM | 3 juin 2016 | PAGE 48/55
Si on ne suit pas les bonnes dépendances …
Limitations
CEA/DAM | 3 juin 2016 | PAGE 49/55
Limitations : chemins non satisfaisables
lbl0
R0 = 0x1
IRDst = zf?(lbl1,lbl_gen_0)
lbl_gen_0
if (COND)
R0 = 1;
else
R0 = 0x11223344;
R0 = 0x3344
IRDst = lbl1
lbl1
IRDst = zf?(lbl2,lbl_gen_1)
lbl_gen_1
MOV
MOVNE
MOVTNE
R0, 0x1
R0, 0x3344
R0, 0x1122
R0 = (R0|(0x1122 << 0x10))
IRDst = lbl2
lbl2
PC = @32[(SP+0x0)]
SP = (SP+0x4)
IRDst = @32[(SP+0x0)]
Limitations
CEA/DAM | 3 juin 2016 | PAGE 50/55
Le Petit Poucet se dote du DepGraph
Limitations
CEA/DAM | 3 juin 2016 | PAGE 51/55
Conclusion : Miasm, l’ami des tout petits
Veni, Vidi, Vidi
Mix entre les deux familles d’analyses
Limitations contournables en pratique
Explicite/Implicite
Conclusion
CEA/DAM | 3 juin 2016 | PAGE 52/55
Merci !
http://www.miasm.re/blog
@MiasmRE
Conclusion
CEA/DAM | 3 juin 2016 | PAGE 53/55
Commissariat à l’énergie atomique et aux énergies alternatives
Centre de Bruyères-le-Châtel | 91297 Arpajon Cedex
T. +33 (0)1 69 26 40 00 | F. +33 (0)1 69 26 40 00
Établissement public à caractère industriel et commercial
RCS Paris B 775 685 019
CEA/DAM
Partie formelle
Une famille de CFG ayant de nombreuses solutions
2|V|log(|V|) < solutions < 2|V|
2
+|X|
+ |V|.2|V|
2
x := x + b
x := x + d
x := x + c
x := x + a
Conclusion
CEA/DAM | 3 juin 2016 | PAGE 55/55
Téléchargement