Elenco delle figure
fig. 2.1: Struttura di una Contact Card 15
fig. 2.2: Comunicazione tra host e Java (Smart) Cards 17
fig. 2.3: Conversione dei file class e Java Card installer 18
fig. 2.4: Smart Card runtime environment 20
fig. 3.1: Grafo e possibili sequenze di esecuzione del bytecode 25
fig. 3.2: Esempio di grafo con nodi virtuali START e END 26
fig. 3.3: Esempio di grafo che ha un target con 4 archi entranti. 26
fig. 3.4.1: Esempio di grafo nodi (12 e 14) che non raggiungono
il nodo END 27
fig. 3.4.2: Esempio di grafo in cui tutti i nodi raggiungono il nodo END 27
fig. 3.5: Blocchi di un grafo di flusso 28
fig. 3.6: Esempio di salto condizionato aperto / chiuso 29
fig. 3.4: Esempio di grafo che ha un target con 4 archi entranti. 31
fig. 3.7: Regole dei salti condizionati 30
fig. 3.8: Regole dell’ipd 32
fig. 3.9: switch a 12 vie 33
INDICE
fig. 3.10: Regola branch∉ 34
fig. 3.11: Dizionario e contesto durante l’esecuzione dello switch 34
fig. 3.12: Regola ipd=0 35
fig. 3.13: L’in-frame di un target può cambiare durante la data-flow
analysis 36
fig.3.14: Struttura dei nodi del grafo (InstrContext) e loro relazione
con le istruzioni del bytecode 42
fig. 3.15: Worklist durante una esecuzione simbolica delle istruzioni 45
fig. 4.1: Il bytecode non è strutturato: quali sono le istruzioni della
subroutine? La nop fa parte della subroutine? 58 fig. 4.2: Bytecode corretto che nessun compilatore “standard” produce a partire da un sorgente java. Questo codice supera la verifica effettuata dal verificatore della Sun, è invece rigettato dal JustIce
59
fig. 4.3: Grafo di codice non valido, due subroutines tentano il “merge”
su unica istruzione di ret 62
fig. 4.4: Grafo di una parte di codice in cui è presente una subroutine, nel calcolo dell’ipd i successori della ret sono tutti i possibili successori
70
fig. 4.5: Grafo di una parte di codice in cui è presente una subroutine, all’interno della subroutine sono ci sono dei salti condizionati con ipd pari al nodo ret
73
fig. 4.6: Grafo di una parte di codice in cui è presente una subroutine, all’interno della subroutine sono ci sono dei salti condizionati con ipd pari al nodo END
76
fig. 4.7: Grafo di una parte di codice in cui è presente una subroutine la cui chiamata è interna ad un salto condizionato, l’ipd del salto è il nodo 70
78
fig. 4.8: Grafo di una parte di codice in cui è presente una subroutine, l’ipd del salto è l’istruzione jsr alla posizione 18 79
INDICE
fig. 4.9: ECFG di una parte di codice in cui è presente una subroutine, tale caso ha richiesto la modifica dell’algoritmo nel calcolo dell’ipd
80
fig. 4.10: Regola branch∉ 81
fig. 4.11: Regola ipd≠0 , si fa il merge del frame con il frame nel
dizionario e si rimanda l’esecuzione, con questa operazione si perderà la polivarianza.
82
fig. 4.12: Si carica il nuovo frame nel frame corrente per il target del
salto 83
fig. 4.13: Si raggiunge nella verifica il nodo 33, perdendo le
informazioni relative al nodo 23 e ai suoi successori
84
fig. 4.14: ECFG dell’esempio 4.6 in cui vengono modificati gli ipd dei salti appartenenti alla subroutine 86 fig. 4.15: ECFG dell’esempio 4.9 in cui l’ipd è diventato il nodo END 88
fig. 4.16: Regola branch∉ 89
fig. 4.17 Nella verifica del nodo 50 si va a modificare l’ipd del salto
aperto associandogli il nodo END 90
fig. 4.18: Si carica nel frame corrente il frame relativo al target 91
fig. 4.19: Si procede nella verifica, questa volta non “dimenticando”
parti di codice 92
fig. 4.20: Grafo di un esempio di bytecode in cui l’ipd del salto viene
spostato dal nodo 60 al nodo 130 93
fig. 6.1: Tabella dei risultati ottenuti 116