Analisis estatico de programas
-
Upload
independent -
Category
Documents
-
view
0 -
download
0
Transcript of Analisis estatico de programas
Qué es el análisis de programas?• Técnicas para predecir propiedades de los programas antes de ejecutarlos (o sea, saber de antemano cosas que pasarán al ejecutarlos)
• Algunas propiedades que interesan: Variables “vivas”
int noSoyOptimo(int n){ x = n; {n} acum = n; {acum} i = 0; {acum, i} while(i< 10) {acum, i} { k = i + 1; {acum, k} acum = acum + 1; {acum, k} i = k; {acum, i} } return acum; { acum }}
• Una variable está viva en una posición del programa si es USADA en alguna posición a partir de ese punto SIN SER REASIGNADA• Una variable ASIGANDA pero no viva, puede ser eliminada junto con sus ASIGNACIONES
Qué es el análisis de programas?• Técnicas para predecir propiedades de los programas antes de ejecutarlos (o sea, saber de antemano cosas que pasarán al ejecutarlos)
• Algunas propiedades que interesan: Variables “vivas” Expresiones usadas frecuentemente
int noSoyOptimo(int n, int[] a){ acum = 0; for(int i=0; i< 10; i++) { a[2*n+i]=a[2*n+i]+1; acum = acum + a[2*n+i]; } return m;}
• Una expresión es usada frecuentemente si aparece varias veces en un programa y el valor que representa es siempre el mismo.
Qué es el análisis de programas?• Técnicas para predecir propiedades de los programas antes de ejecutarlos (o sea, saber de antemano cosas que pasarán al ejecutarlos)
• Algunas propiedades que interesan: Variables “vivas” Expresiones usadas frecuentemente Invariantes Accesos correctos a Arrays, a referencias (punteros)
Código alcanzable Tiempo de ejecución Y muchas más!
int noSoyOptimo(int n){ { true } acum = n; { acum = n } for(int i=0; i< 10; i++) { {0≤ i<10 acum=n+i } acum = acum + 1; {0≤ i<10 acum=n+i+1 } } { i = 10 acum=n+10 } return acum; }
Invariante en un punto: Invariante en un punto: Relación entre Relación entre variables que se variables que se mantiene mantiene para cualquier para cualquier ejecución ejecución de un de un programaprograma
Tipos de Análisis
• Dos enfoques Estático: Se analiza el programa sin ejecutarlo. Se deduce el comportamiento a partir del TEXTO del código.
Dinámico: Se ejecuta el programa (varias veces)Se deduce el comportamiento a partir de datos obtenidos de las ejecuciones.
El TESTING es un tipo análisis dinámico
Vamos a hablar de Análisis Estático
MotivaciónPor qué analizar programas?• Generación de Código
Compilación Optimización Transformación
Verificación Contra especificaciones Bugs en código Generación de casos de Test
Comprensión Obtención de invariantes Obtención de modelos a partir de código
Seguridad Buffer overflows Confidencialidad Referencia a null Objetos no inicializados
Por qué analizar programas?Generación de Código
• Compilar: Traducir un programa en un lenguaje que nosotros “entendemos” por algo que entiende la máquina
int ordenar(int[] A){ for(int i=0;i< a.size; i++) { swap(i, min(A,i) ); }}
ordenar Mov cx,0 L1: call minimo Mov bx, data[ax] Mov ex, data[cx] Mov data[cx], bx Mov data[ax], ex Inc cx; cmp cx,data[size] jnz L1
Estructura de un Compilador
Analizador Léxico Parse
rAnalizador Semántico Optimizador
independientedel procesador
Generador de código
Optimizadorespecifico
para el procesador
Cadena de Tokens
Síntaxis Abstracta
Representación
Intermedia
Representación
IntermediaOptimizadaCódigo
para una máquina
especifica
Código=Texto
Código optimizadopara una máquina
específica
Por qué analizar programas?Optimizar
Optimizar: Hacer algo más Optimizar: Hacer algo más eficiente según algún criterioeficiente según algún criterioint noSoyOptimo(int x){ int n = x; int h = 10; int m; for(int i=0; i< 1000; i++) { m = max(n,h); } return m;}
int soyOptimo(int x){ return max(x,10);}
•Espacio!•N° de instrucciones ejecutadas!•Velocidad!
Optimizaciones Típicas
• Evitar cómputos redundantes Reusar resultados disponibles Sacar de los “loops” los resultados que no varían en ellos
Evitar cómputos superfluos Resultados no necesarios Resultados calculables en tiempo de compilación (ej.:constantes)
Reusar resultados disponibles
int noSoyOptimo(int n, int[] a){ acum = 0; for(int i=0; i< 10; i++) { a[2*n+i]=a[2*n+i]+1; acum = acum + a[2*n+i]; } return m;}
int soyMasOptimo(int n, int[] a){ acum = 0; for(int i=0; i< 10; i++) { tmp = 2*n+i; a[tmp]=a[tmp]+1; acum = acum + a[tmp]; } return m;}
Primer cálculo
Cálculos repetidos
Otros análisis
int noSoyOptimo(int x){ int n = x; int h = 10; int m; for(int i=0; i<1000; i++) { m = max(n,h); } return m;} No depende del
Loop
int noSoyOptimo(int x){ int n = x; int h = 10; int m; m = max(n,h);return m;}
h es constanten es siempre x
int noSoyOptimo(int x){ int n = x; { x } int h = 10; { x } int m; {x} m = max(x,10); {m}return m; {} } n, h no
están vivas!!
Resultados no Resultados no necesariosnecesarios
Resultados calculables Resultados calculables en tiempo de en tiempo de compilaciòncompilaciòn
Instrucciones que no Instrucciones que no dependen del loopdependen del loop
int casiOptimo(int x){ int m; m = max(x,10); return m;}
Por qué analizar programas? Verificar
• Dos enfoques 1) Ver si el programa cumple con lo especificado. Testing… (dinámico) Descubrir invariantes y comparar (estática o dinámicamente)
2) Evitar la mayor cantidad errores en tiempo de ejecuciónchequeo de accesos indebidos a arrays,
A[i] con i mayor a la dimensión del array o negativo!
punteros nulos, variables no inicializadas…
Verificación Ejemplos• PolySpace aplica técnicas análisis estático para la verificación de programas “críticos”
• Verificó una aplicación de sincronización de los trenes de alta velocidad TGV (Francia)
• 15.000 líneas de código• Descubrió (sin ejecutar) los siguientes tipos de errores:
Acceso a variables no inicializadas Divisiones por cero Acceso fuera de límites de Arrays Acceso concurrente a variables compartidas sin sincronizar
POTENCIALES ERRORES EN EJECUCION!!!!!!CHOQUES!!!!!!
Limites del Análisis
Lamentablemente muchos problemas no son computables. Ejemplos:
Decidir si un punto del programa es alcanzable por alguna ejecución o no (código muerto)
Calcular (exactamente) cuanta memoria necesita un programa para ejecutarse
Saber si dos variables refieren al mismo objeto (aliasing)
Aproximaciones• No dar el resultado exacto (ya vimos que a veces es imposible)
• Dar una aproximación conservativa Tener en cuenta para que vamos a usar el resultado del análisis
Tiene que ofrecer datos SEGUROS según la transformación que hagamos
Copiar Constantes
Variables Vivas
= Espacio aproximado= Espacio de soluciones exacto
Que estamos haciendo?Nos interesan propiedades de Nos interesan propiedades de confidencialidad e integridad de la confidencialidad e integridad de la información.información.
Nos interesa traducir los programas a Nos interesa traducir los programas a otras representacionesotras representaciones
Nos interesan tanto programas en Nos interesan tanto programas en lenguajes de alto nivel (Java, C, etc) lenguajes de alto nivel (Java, C, etc) como de bajo nivel (Bytecode, como de bajo nivel (Bytecode, Assembly)Assembly)
Information-flow Information-flow • Descarga de un planificador financiero:Descarga de un planificador financiero:
• Control de acceso insuficienteControl de acceso insuficiente• Encriptación necesario, pero no es Encriptación necesario, pero no es prácticopráctico
Control de AccesoControl de AccesoControl de AccesoControl de Acceso
Permisos de acceso a archivosPermisos de acceso a archivos Permisos de acceso a sistemasPermisos de acceso a sistemas Variantes Modernas: stack Variantes Modernas: stack
inspectioninspection• Desventaja:Desventaja:
– No regula la propagación de la No regula la propagación de la información después de que el información después de que el permiso fue otorgadopermiso fue otorgado
CriptografíaCriptografía• Esencial paraEsencial para
– Proteger confidencialidad e Proteger confidencialidad e integridad de los datos integridad de los datos trasmitidos por medios trasmitidos por medios insegurosinseguros
– Autenticación de protocolosAutenticación de protocolos• Desventaja:Desventaja:
– No es práctico computar datos No es práctico computar datos encriptados!encriptados!
– No previene la propagación d No previene la propagación d ela información de datos ela información de datos desencriptadosdesencriptados
RequerimientosRequerimientos• Se necesita poder distinguir Se necesita poder distinguir información información confidentialconfidential de información de información públicapública
• Se necesita registrar el Se necesita registrar el flujo de la flujo de la información información (como fluyen los datos a (como fluyen los datos a traves del programa)traves del programa)– Cuando un secreto se liberaWhen is a Cuando un secreto se liberaWhen is a secret leaked?secret leaked?
• Se necesita un mecanísmo seguro y Se necesita un mecanísmo seguro y eficiente para garantizar que s eficiente para garantizar que s ecumple la política de seguridadecumple la política de seguridad
Una idea: tagsUna idea: tags
• Incluir un “tag” a cada datoIncluir un “tag” a cada dato– Tags: Tags: hihi (secreto) o (secreto) o lowlow (publico)(publico)
• Modifica las instrucciones del Modifica las instrucciones del programa para propagar los programa para propagar los tags.tags.– e.g.: (1:e.g.: (1:hihi) + (2:) + (2:lowlow) ) (3: (3:hihi))
Análisis EstáticoAnálisis Estático• Usar análisis estático (por ejemplo, Usar análisis estático (por ejemplo, sistemas de tipos o análisis de sistemas de tipos o análisis de dependencias) dependencias)
• Ventajas:Ventajas:– Ningún costo en tiempo de ejecuciónNingún costo en tiempo de ejecución– Tiene acceso al grafo de flujo de Tiene acceso al grafo de flujo de control, entonces puede aproximar todas control, entonces puede aproximar todas las corridas del programalas corridas del programa
– Determina la seguridad del programa antes Determina la seguridad del programa antes de ejecutarlode ejecutarlo
• Desventajas:Desventajas:– Ninguna información en tiempo de Ninguna información en tiempo de ejecución significa aproximaciónejecución significa aproximación
No InterferenciaNo Interferencia
• Datos privados no interfieren con Datos privados no interfieren con las comunicaciones en la redlas comunicaciones en la red
• Punto de partida para una Punto de partida para una política de confidencialidadpolítica de confidencialidad
]
No InterferenciaNo Interferencia
– Relaciones lógicasRelaciones lógicas– Técnicas de simulaciónTécnicas de simulación– Sistemas de tiposSistemas de tipos– Grafos de control de Grafos de control de flujoflujo
Se utilizan Se utilizan distintos distintos enfoques:enfoques:
Control Flow GraphControl Flow Graph
Enter
sum = 0 i = 1 while(i < 11) printf(sum) printf(i)
sum = sum + i i = i + i
int main() {int sum = 0;int i = 1;while (i < 11) {
sum = sum + i;i = i + 1;
}printf(“%d\n”,sum);printf(“%d\n”,i);
}
q is reached from pif condition p istrue (T), not otherwise.
Control Control DependenceDependence Graph GraphControl dependence
p qT
p qFSimilar for false (F).
Enter
sum = 0 i = 1 while(i < 11) printf(sum) printf(i)
sum = sum + i i = i + i
T T
T T TT
TT
int main() {int sum = 0;int i = 1;while (i < 11) {
sum = sum + i;i = i + 1;
}printf(“%d\n”,sum);printf(“%d\n”,i);
}
Flow Flow DependenceDependence Graph Graphint main() {
int sum = 0;int i = 1;while (i < 11) {
sum = sum + i;i = i + 1;
}printf(“%d\n”,sum);printf(“%d\n”,i);
} Enter
sum = 0 printf(sum) printf(i)
sum = sum + i i = i + i
Flow dependencep qValue of variable
assigned at p may beused at q.
i = 1 while(i < 11)
Program Dependence Graph Program Dependence Graph (PDG)(PDG)int main() {
int sum = 0;int i = 1;while (i < 11) {
sum = sum + i;i = i + 1;
}printf(“%d\n”,sum);printf(“%d\n”,i);
} Enter
sum = 0 i = 1 while(i < 11) printf(sum) printf(i)
sum = sum + i i = i + i
T
T T TT
Control dependenceFlow dependence
TT
T
Program Dependence Graph Program Dependence Graph (PDG)(PDG)int main() {
int i = 1;int sum = 0;while (i < 11) {
sum = sum + i;i = i + 1;
}printf(“%d\n”,sum);printf(“%d\n”,i);
} Enter
sum = 0 i = 1 while(i < 11) printf(sum) printf(i)
sum = sum + i i = i + i
T
T T TT
TT
T
Orden Opuesto
Mismo PDG
Otro Análisis: Backward Otro Análisis: Backward SliceSlice
int main() {int sum = 0;int i = 1;while (i < 11) {
sum = sum + i;i = i + 1;
}printf(“%d\n”,sum);printf(“%d\n”,i);
} Enter
sum = 0 i = 1 while(i < 11) printf(sum) printf(i)
sum = sum + i i = i + i
T
T T TT
TT
T
Backward Slice (2)Backward Slice (2)int main() {
int sum = 0;int i = 1;while (i < 11) {
sum = sum + i;i = i + 1;
}printf(“%d\n”,sum);printf(“%d\n”,i);
} Enter
sum = 0 i = 1 while(i < 11) printf(sum) printf(i)
sum = sum + i i = i + i
T
T T TT
TT
T
Backward Slice (3)Backward Slice (3)int main() {
int sum = 0;int i = 1;while (i < 11) {
sum = sum + i;i = i + 1;
}printf(“%d\n”,sum);printf(“%d\n”,i);
} Enter
sum = 0 i = 1 while(i < 11) printf(sum) printf(i)
sum = sum + i i = i + i
T
T T TT
TT
T
Backward Slice (4)Backward Slice (4)int main() {
int sum = 0;int i = 1;while (i < 11) {
sum = sum + i;i = i + 1;
}printf(“%d\n”,sum);printf(“%d\n”,i);
} Enter
sum = 0 i = 1 while(i < 11) printf(sum) printf(i)
sum = sum + i i = i + i
T T
T T TTTT
Extracción del Program Extracción del Program Slice Slice
int main() {
int i = 1;while (i < 11) {
i = i + 1;}
printf(“%d\n”,i);} Enter
i = 1 while(i < 11) printf(i)
i = i + iT
TTTT
Que hacemos?• Analizamos estáticamente programas• Nos enfocamos principalmente en propiedades de seguridad: especialmente en confidencialidad e integridad
• Sistemas de tipos para bytecode• Análisis de dependencias• Program Slicing
• Traducimos programas a distintas representaciones
– Grafos – Lenguajes de bajo nivel tipados
• Queremos incursionar en técnicas mixtas (estático-dinámico)