• Nenhum resultado encontrado

Parsing

No documento Ricardo Silveira Moreira (páginas 41-46)

2.3 Ferramentas an´ alise est´ atica de c´ odigo

2.3.2 Parsing

Este processo serve para, recorrendo a tokens obtidos pela an´alise lexical (figura 2.7), transformar o c´odigo fonte numa parse tree.

A parse tree ´e constru´ıda a partir daquilo a que se chama uma gram´atica livre de contexto, tipicamente representada na nota¸c˜ao Backus-Naur Form (BNF). Esta forma de especificar gram´aticas ´e f´acil de ler, de expandir e de especificar qualquer

Figura 2.7: Rela¸c˜ao entre a an´alise lexical e o parser

linguagem.

Gram´aticas livres de contexto

Este formato ´e o que permite especificar a sintaxe de uma linguagem atrav´es daquilo a que se chamam produ¸c˜oes, que se constroem a partir de s´ımbolos terminais e n˜ao terminais.

S´ımbolos terminais s˜ao os tokens obtidos atrav´es do reconhecimento de express˜oes regulares pela an´alise lexical. N˜ao terminais s˜ao os s´ımbolos que permitem especi- ficar a hierarquia de uma linguagem e s˜ao uma combina¸c˜ao de s´ımbolos terminais e/ou n˜ao terminais. Produ¸c˜oes especificam o m´etodo como s´ımbolos terminais e n˜ao terminais, podem ser combinados para formar strings.

A melhor forma de perceber gram´aticas livres de contexto ´e representando a gram´atica de opera¸c˜oes aritm´eticas. Neste caso, a an´alise lexical vai devolver os

tokens ou s´ımbolos terminais id, +, −, ∗, /, (, ). Um id ´e qualquer n´umero de zero a nove. Neste caso o que a gram´atica deve representar ´e a sintaxe correcta de uma opera¸c˜ao matem´atica. Esta gram´atica est´a representada na tabela 2.2. Com esta

1a express˜ao express˜ao + termo

2a express˜ao → express˜ao - termo 3a express˜ao termo

4a termo termo * factor

5a termo termo / factor

6a termo → factor

7a factor ( express˜ao )

8a factor {id}

Tabela 2.2: Regras de produ¸c˜ao para opera¸c˜oes aritm´eticas

gram´atica ´e poss´ıvel especificar a estrutura que qualquer opera¸c˜ao aritm´etica tem de seguir.

Cap´ıtulo 2. Contexto e trabalho relacionado 25

Se tomarmos como exemplo a seguinte express˜ao (1 + 4) ∗ 5 + 3, esta express˜ao vai come¸car por aplicar a primeira regra, que vai resultar em express˜ao + termo.

Sendo a express˜ao igual a (1 + 4) ∗ 5 e o termo igual a 3. De seguida vai ser aplicada

a terceira regra a (1 + 4) ∗ 5, que vai resultar em termo, que por sua vez vai aplicar a quarta regra termo ∗ f actor. O termo ainda pode ser mais simplificado, o que vai resultar em f actor, que vai resultar em (express˜ao). Sobre esta podemos aplicar

a primeira express˜ao que vai resultar em express˜ao + termo. Estas depois v˜ao ser simplificadas at´e `a oitava regra, que vai ser traduzida no token id. Estas regras s˜ao aplicadas aos tokens seguintes. Isto mostra-nos que a express˜ao (1 + 4) ∗ 5 + 3 ´e uma express˜ao v´alida, porque pode ser derivada recorrendo ´as express˜oes da tabela 2.2 da seguinte forma

express˜ao → express˜ao + termo express˜ao + termo → termo + termo termo + termo → termo ∗ f actor + termo

termo ∗ f actor + termo → f actor ∗ f actor + termo f actor ∗ f actor + termo → (express˜ao) ∗ f actor + termo

(express˜ao) ∗ f actor + termo → (express˜ao + termo) ∗ f actor + termo

(express˜ao + termo) ∗ f actor + termo → (id + termo) ∗ f actor + termo

(id + termo) ∗ f actor + termo → (id + id) ∗ f actor + termo (id + id) ∗ f actor + termo → (id + id) ∗ id + termo

(id + id) ∗ id + termo → (id + id) ∗ id + id (id + id) ∗ id + id → (1 + 4) ∗ 5 + 3

A deriva¸c˜ao aqui feita ´e `a esquerda e existe ainda uma variante `a direita. Com estas deriva¸c˜oes ´e depois poss´ıvel fazer aquilo a que se chama ´arvores de parsing ou sint´actica, sobre as quais ´e poss´ıvel fazer an´alises. Existem tamb´em muitas vezes representa¸c˜oes directas do c´odigo tal como o programador escreveu.

A ´area de parsing dentro de compiladores ´e uma ´area muito vasta existem v´arios tipos de gram´aticas que especificam o m´etodo como ´e feito o parsing, se ´e da esquerda para a direita assim como o n´umero de lookaheads (s´ımbolos que s˜ao vistos antes de ser aplicada uma regra de produ¸c˜ao). Estas considera¸c˜oes contudo j´a n˜ao s˜ao relevantes para este projecto. No entanto, s˜ao retiradas algumas ideias como a cria¸c˜ao de uma gram´atica de regras que representam padr˜oes de c´odigo vulner´avel.

2.3.3

Arvore sint´´

actica

Uma ´arvore sint´actica ou de parsing ´e aquilo que permite representar sob a forma de ´

arvore, a estrutura de um c´odigo fonte escrita numa linguagem de programa¸c˜ao. A vantagem desta representa¸c˜ao ´e que permite perceber os v´arios caminhos que uma fun¸c˜ao pode tomar, de acordo com valores ou condi¸c˜oes diferentes. ´E sobre esta ´

arvore que s˜ao depois aplicadas as t´ecnicas de an´alise de controlo de fluxo, dados e a variante desta, i.e, taint analysis.

Para fazer a convers˜ao ´e necess´ario fazer a tradu¸c˜ao das v´arias regras de produ¸c˜ao que v˜ao especificar a cria¸c˜ao de n´os e de folhas na ´arvore. Neste contexto, um

n´o representa (se tiver folhas) um s´ımbolo n˜ao terminal e as folhas s˜ao s´ımbolos terminais.

Na tabela 2.3 est˜ao representadas as regras de constru¸c˜ao de uma ´arvore de

parsing.

Produ¸c˜ao Regras de semantica

express˜ao → express˜ao + termo express˜ao.node=new Node(’+’,express˜ao.node,termo.node) express˜ao → express˜ao - termo express˜ao.node=new Node(’-’,express˜ao.node,termo.node) express˜ao → termo express˜ao.node=termo.node

termo → termo * factor termo.node=new Node(’*’,termo.node,factor.node) termo → termo / factor termo.node=new Node(’/’,termo.node,factor.node)

termo → factor termo.node=factor.node

factor → ( expression ) factor.node = express˜ao.node

factor → id factor.node = new Leaf(id,id.entrada) Tabela 2.3: Tradu¸c˜ao de regras de produ¸c˜ao para regras de semantica

Esta tabela permite traduzir cada regra de produ¸c˜ao nos n´os e folhas. Se usarmos como exemplo a express˜ao (1 + 4) ∗ 5 + 3 obtermos a seguinte ´arvore 2.8

A grande vantagem deste tipo de estrutura de dados ´e que permite associar a cada n´o e folha informa¸c˜ao que vai facilitar a an´alise de vulnerabilidades, simular a execu¸c˜ao do c´odigo, perceber a forma como as v´arias opera¸c˜oes v˜ao afectar vari´aveis e perceber se estas chegam a Sensitive Sinks ou n˜ao. Esta fase n˜ao est´a contemplada na aplica¸c˜ao aqui apresentada

2.3.4

etodos de an´alise

As ferramentas de an´alise est´atica de c´odigo precisam sempre de fazer uma ou mais das t´ecnicas abaixo listadas, ou seja, para an´alisar c´odigo v˜ao todas precisar de extrair tokens atrav´es de an´alise lexical. Por essa raz˜ao ´e dif´ıcl dizer que uma t´ecnica emprega apenas um m´etodo, porque mesmo aquelas que fazem simplesmente an´alise lexical podem usar algumas t´ecnicas de parsing.

An´alise lexical

Este tipo de m´etodo muito simplesmente procura identificar fun¸c˜oes que s˜ao poten- cialmente vulner´aveis e lan¸ca alertas, como ´e o caso do [3], [9] entre outros. O grande problema deste tipo de m´etodo de an´alise ´e o grande n´umero de falsos positivos que pode lan¸car[22].

Pattern matching

Este m´etodo procura especificar regras de produ¸c˜ao que potencialmente v˜ao ser vul- ner´aveis e posteriormente vai procurar esses mesmos padr˜oes no c´odigo. Tal como o m´etodo anterior este pode gerar um grande n´umero de falsos positivos [22]. Con- tudo ´e um bom m´etodo para uma an´alise r´apida e que, juntamente com anota¸c˜oes

Cap´ıtulo 2. Contexto e trabalho relacionado 27

Figura 2.8: Arvore de parsing da express˜ao (1 + 4) ∗ 5 + 3

de utilizadores, permite detectar grande partes das vulnerabilidades. Este ´e o tipo de an´alise que a aplica¸c˜ao aqui desenvolvida efectua.

Controlo de fluxo

Ferramentas que utilizam este m´etodo procuram explorar os diferentes caminhos de execu¸c˜ao que uma aplica¸c˜ao tem. Para isto constroem aquilo a que se chama um grafo de controlo de fluxo por cima da ´arvore de parsing. Isto permite ter no¸c˜ao do comportamento do programa e perceber caminhos da fun¸c˜ao que s˜ao inacess´ıveis, com apoio de regras perceber o que ´e potencialmente perigoso e identificar caminhos que podem levar a vulnerabilidades.

Taint propagation

Este tipo de m´etodo ´e uma subcategoria da an´alise de fluxo de dados e procura identificar a que valores um atacante consegue ter acesso. Para isto ´e necess´ario saber os pontos de entrada do programa, tais como inputs, entradas de ficheiros entre outros. Este tipo de m´etodo procura perceber as altera¸c˜oes que vari´aveis v˜ao ter ao longo do c´odigo e detectar se chegam a Sensitive Sinks.

No documento Ricardo Silveira Moreira (páginas 41-46)

Documentos relacionados