Analisis estatico de programas

38
Análisis Estático de Programas Francisco Bavera

Transcript of Analisis estatico de programas

Análisis Estático de Programas

Francisco Bavera

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)

Confidencialidad e Confidencialidad e IntegridadIntegridad

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:

Un Ejemplo de Otras Un Ejemplo de Otras Representaciones de Representaciones de

ProgramasProgramas

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)